mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 15:09:42 +02:00
chore: bump version to 0.1550
This commit is contained in:
@@ -4384,11 +4384,6 @@ class ClaudemanApp {
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy toggle for backwards compat
|
||||
toggleSubagentDropdown(badgeEl) {
|
||||
this.pinSubagentDropdown(badgeEl);
|
||||
}
|
||||
|
||||
// Permanently close a minimized subagent (remove from DOM and minimized set)
|
||||
permanentlyCloseMinimizedSubagent(agentId, sessionId) {
|
||||
// Remove from minimized set
|
||||
@@ -7307,27 +7302,6 @@ class ClaudemanApp {
|
||||
}
|
||||
}
|
||||
|
||||
skipPlanGeneration() {
|
||||
// Stop any running timers
|
||||
if (this.planLoadingTimer) {
|
||||
clearInterval(this.planLoadingTimer);
|
||||
this.planLoadingTimer = null;
|
||||
}
|
||||
if (this.planPhaseTimer) {
|
||||
clearInterval(this.planPhaseTimer);
|
||||
this.planPhaseTimer = null;
|
||||
}
|
||||
|
||||
this.ralphWizardConfig.skipPlanGeneration = true;
|
||||
this.ralphWizardConfig.planGenerated = false;
|
||||
this.ralphWizardConfig.generatedPlan = null;
|
||||
|
||||
// Generate preview and go to step 3
|
||||
this.updateRalphPromptPreview();
|
||||
this.ralphWizardStep = 3;
|
||||
this.updateRalphWizardUI();
|
||||
}
|
||||
|
||||
regeneratePlan() {
|
||||
this.ralphWizardConfig.generatedPlan = null;
|
||||
this.ralphWizardConfig.planGenerated = false;
|
||||
|
||||
@@ -39,9 +39,6 @@
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
/* Utility classes */
|
||||
.mt-sm { margin-top: 0.5rem; }
|
||||
|
||||
/* ========== Accessibility: Focus Styles ========== */
|
||||
|
||||
/* Skip link for keyboard users */
|
||||
@@ -1319,22 +1316,7 @@ body {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Legacy classes for backward compatibility */
|
||||
.ralph-progress-section {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Large Progress Ring */
|
||||
.ralph-ring {
|
||||
position: relative;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.ralph-ring-svg-large {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -1378,66 +1360,6 @@ body {
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
|
||||
/* Meta Info */
|
||||
.ralph-meta {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.ralph-meta-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.ralph-meta-label {
|
||||
font-size: 0.65rem;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.ralph-meta code {
|
||||
background: var(--bg-input);
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
font-family: 'SF Mono', Monaco, monospace;
|
||||
font-size: 0.75rem;
|
||||
color: var(--accent);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.ralph-meta-row {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.ralph-meta-item span:not(.ralph-meta-label) {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
/* Task Cards Section */
|
||||
.ralph-tasks-section {
|
||||
background: var(--bg-card);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ralph-tasks-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: var(--bg-input);
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.ralph-tasks-count {
|
||||
color: var(--text-dim);
|
||||
font-weight: 400;
|
||||
@@ -1886,13 +1808,6 @@ body {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.toolbar-divider {
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
background: var(--border);
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
.btn-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -2339,15 +2254,6 @@ body {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
.btn-danger-sm {
|
||||
color: #ff6b6b;
|
||||
}
|
||||
|
||||
.btn-danger-sm:hover {
|
||||
color: #fff;
|
||||
background: #dc3545;
|
||||
}
|
||||
|
||||
.settings-section {
|
||||
margin-bottom: 1.25rem;
|
||||
padding-bottom: 1rem;
|
||||
@@ -2360,15 +2266,6 @@ body {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.settings-section-title {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin-bottom: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
@@ -2403,17 +2300,6 @@ body {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.form-row-inline {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-row-inline input[type="text"] {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-col {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -2447,43 +2333,6 @@ body {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.15s;
|
||||
}
|
||||
|
||||
.checkbox-label:hover {
|
||||
border-color: var(--border-light);
|
||||
}
|
||||
|
||||
.checkbox-label input[type="checkbox"] {
|
||||
accent-color: var(--accent);
|
||||
}
|
||||
|
||||
.checkbox-label span:first-of-type {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.checkbox-hint {
|
||||
font-size: 0.7rem;
|
||||
color: var(--text-muted);
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.form-hint {
|
||||
display: block;
|
||||
font-size: 0.65rem;
|
||||
@@ -2667,10 +2516,6 @@ body {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.settings-item-full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.settings-item-label {
|
||||
color: var(--text);
|
||||
white-space: nowrap;
|
||||
@@ -2726,26 +2571,6 @@ body {
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
/* CPU limit status indicator */
|
||||
.cpu-limit-status {
|
||||
font-size: 0.7rem;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-dim);
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.cpu-limit-status.available {
|
||||
background: rgba(34, 197, 94, 0.2);
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
.cpu-limit-status.unavailable {
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
/* Event Type Notification Grid */
|
||||
.event-type-grid {
|
||||
display: grid;
|
||||
@@ -2824,24 +2649,6 @@ body {
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.form-actions-stack {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.form-actions-stack button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background: var(--yellow);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.btn-warning:hover {
|
||||
background: #d4a107;
|
||||
}
|
||||
|
||||
/* Modal */
|
||||
.modal {
|
||||
display: none;
|
||||
@@ -3251,13 +3058,6 @@ body {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.modal-footer-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.auto-refresh-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -3297,32 +3097,6 @@ body {
|
||||
font-family: 'SF Mono', Monaco, monospace;
|
||||
}
|
||||
|
||||
#runSummaryModal .modal-footer-actions {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
#runSummaryModal .modal-footer-actions .btn-toolbar {
|
||||
font-size: 0.7rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
/* Tab summary icon */
|
||||
.tab-summary {
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
font-size: 0.85rem;
|
||||
transition: opacity 0.15s;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
.session-tab:hover .tab-summary {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.session-tab:hover .tab-summary:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.modal-warning-text {
|
||||
color: var(--text-dim);
|
||||
font-size: 0.85rem;
|
||||
@@ -3399,35 +3173,12 @@ body {
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.session-dir-display {
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
color: var(--text-dim);
|
||||
font-size: 0.8rem;
|
||||
font-family: 'SF Mono', Monaco, monospace;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Session respawn section in options modal */
|
||||
.session-respawn-section {
|
||||
padding-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.section-divider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
color: var(--text-dim);
|
||||
}
|
||||
|
||||
.session-respawn-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -3459,11 +3210,6 @@ body {
|
||||
}
|
||||
|
||||
/* Inline checkbox group */
|
||||
.checkbox-group-inline {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.checkbox-inline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -3481,13 +3227,6 @@ body {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
/* Auto-clear row */
|
||||
.auto-clear-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.input-suffix-sm {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -3583,11 +3322,6 @@ body {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.session-respawn-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* Modal Tabs */
|
||||
.modal-tabs {
|
||||
display: flex;
|
||||
@@ -4349,59 +4083,6 @@ kbd {
|
||||
transition: opacity 0.1s, color 0.1s;
|
||||
}
|
||||
|
||||
/* Task Panel */
|
||||
.task-panel {
|
||||
position: fixed;
|
||||
bottom: var(--toolbar-height);
|
||||
right: 0.5rem;
|
||||
width: 350px;
|
||||
max-width: calc(100vw - 1rem);
|
||||
/* Performance: GPU-accelerated transforms and isolated paint */
|
||||
contain: layout style;
|
||||
will-change: transform;
|
||||
max-height: 50vh;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-bottom: none;
|
||||
border-radius: 8px 8px 0 0;
|
||||
box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.4);
|
||||
z-index: 100;
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.2s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.task-panel.open {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.task-panel-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.6rem 1rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.task-panel-stats {
|
||||
margin-left: auto;
|
||||
font-size: 0.7rem;
|
||||
color: var(--text-dim);
|
||||
padding: 0.2rem 0.5rem;
|
||||
background: var(--bg-input);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.task-panel-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.task-empty {
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
@@ -4522,53 +4203,6 @@ kbd {
|
||||
background: var(--border-light);
|
||||
}
|
||||
|
||||
/* Process Monitor Panel */
|
||||
.process-panel {
|
||||
position: fixed;
|
||||
bottom: var(--toolbar-height);
|
||||
left: 0.5rem;
|
||||
width: 400px;
|
||||
max-width: calc(100vw - 1rem);
|
||||
max-height: 50vh;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-bottom: none;
|
||||
border-radius: 8px 8px 0 0;
|
||||
box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.4);
|
||||
z-index: 100;
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.2s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.process-panel.open {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.process-panel-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.6rem 1rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.process-panel-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.process-panel-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.process-empty {
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
@@ -4714,55 +4348,6 @@ kbd {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.monitor-tabs {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.monitor-tab {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-muted);
|
||||
padding: 0.3rem 0.6rem;
|
||||
font-size: 0.75rem;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.monitor-tab:hover {
|
||||
color: var(--text);
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
.monitor-tab.active {
|
||||
color: white;
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.monitor-tab-badge {
|
||||
display: inline-block;
|
||||
background: var(--success);
|
||||
color: white;
|
||||
font-size: 0.6rem;
|
||||
padding: 0.1rem 0.35rem;
|
||||
border-radius: 8px;
|
||||
margin-left: 0.25rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.monitor-tab-badge:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monitor-tab-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monitor-tab-content.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monitor-panel-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -4864,47 +4449,6 @@ kbd {
|
||||
|
||||
/* ========== Subagent Panel (Claude Code Background Agents) ========== */
|
||||
|
||||
/* Toolbar button for subagents tab */
|
||||
.toolbar-btn-subagents {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
background: var(--bg-hover);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text-dim);
|
||||
font-size: 0.75rem;
|
||||
padding: 0.4rem 0.75rem;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.toolbar-btn-subagents:hover {
|
||||
background: var(--bg-card);
|
||||
border-color: var(--accent);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.toolbar-btn-subagents.active {
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.toolbar-badge {
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
font-size: 0.65rem;
|
||||
padding: 0.1rem 0.4rem;
|
||||
border-radius: 8px;
|
||||
min-width: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toolbar-badge:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ========== Separate Subagents Panel ========== */
|
||||
.subagents-panel {
|
||||
position: fixed;
|
||||
@@ -6312,25 +5856,6 @@ kbd {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Custom tooltip for file links */
|
||||
.file-link-tooltip {
|
||||
position: fixed;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--accent);
|
||||
border-radius: 4px;
|
||||
padding: 0.3rem 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
color: var(--text);
|
||||
z-index: 10000;
|
||||
pointer-events: none;
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.file-link-tooltip::before {
|
||||
content: "📄 Click to stream: ";
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* ========== Ralph Loop Wizard ========== */
|
||||
|
||||
/* Wizard Progress Indicator */
|
||||
@@ -6767,28 +6292,11 @@ kbd {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
|
||||
.plan-skip-btn {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.plan-skip-btn:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.plan-error-msg {
|
||||
color: var(--red);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Plan Options (detail level, model) */
|
||||
.plan-options {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
margin-bottom: 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.plan-option-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -6987,10 +6495,6 @@ kbd {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.plan-actions-single {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.plan-skip-hint {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-muted);
|
||||
@@ -7446,11 +6950,6 @@ kbd {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.mode-changed {
|
||||
color: var(--accent);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Plan warnings and gaps display */
|
||||
#planWarnings {
|
||||
margin-bottom: 0.75rem;
|
||||
@@ -7762,55 +7261,6 @@ kbd {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
/* Verification criteria tooltip expansion */
|
||||
.plan-item-verify-expanded {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: calc(100% + 4px);
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
padding: 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
color: var(--text);
|
||||
z-index: 10;
|
||||
box-shadow: 0 -2px 8px rgba(0,0,0,0.2);
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.plan-item-verify-expanded::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border: 5px solid transparent;
|
||||
border-top-color: var(--border);
|
||||
}
|
||||
|
||||
/* Plan toolbar improvements */
|
||||
.plan-editor-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.plan-toolbar-left {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.plan-toolbar-right {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Plan item inline actions */
|
||||
.plan-item-actions {
|
||||
display: flex;
|
||||
@@ -7909,36 +7359,6 @@ kbd {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
/* Plan version indicator */
|
||||
.plan-version-indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-muted);
|
||||
padding: 0.25rem 0.5rem;
|
||||
background: var(--bg-input);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.plan-version-badge {
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
padding: 0.1rem 0.3rem;
|
||||
border-radius: 3px;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.plan-version-history {
|
||||
cursor: pointer;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.plan-version-history:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Plan history dropdown */
|
||||
.plan-history-dropdown {
|
||||
position: absolute;
|
||||
@@ -8061,27 +7481,6 @@ kbd {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
/* Phrase Input Group */
|
||||
.phrase-input-group {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.phrase-input-group input {
|
||||
width: 100%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
color: var(--text);
|
||||
font-size: 0.85rem;
|
||||
font-family: 'SF Mono', Monaco, 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.phrase-input-group input:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
/* Iteration Presets */
|
||||
.iteration-presets {
|
||||
display: flex;
|
||||
|
||||
+1
-12
@@ -8,12 +8,10 @@
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
import { SAFE_PATH_PATTERN } from '../utils/regex-patterns.js';
|
||||
|
||||
// ========== Path Validation ==========
|
||||
|
||||
/** Regex to validate working directory paths (no shell metacharacters) — matches tmux-manager.ts */
|
||||
const SAFE_PATH_PATTERN = /^[a-zA-Z0-9_\/\-. ~]+$/;
|
||||
|
||||
/** Validate a path string: no shell metacharacters, no traversal, must be absolute */
|
||||
export function isValidWorkingDir(p: string): boolean {
|
||||
if (!p || !p.startsWith('/')) return false;
|
||||
@@ -80,15 +78,6 @@ export const RunPromptSchema = z.object({
|
||||
prompt: z.string().min(1).max(100000),
|
||||
});
|
||||
|
||||
/**
|
||||
* Schema for POST /api/sessions/:id/input
|
||||
* Sends input to an interactive session.
|
||||
*/
|
||||
export const SessionInputSchema = z.object({
|
||||
input: z.string(),
|
||||
useMux: z.boolean().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Schema for POST /api/sessions/:id/resize
|
||||
* Resizes a session's terminal.
|
||||
|
||||
+11
-11
@@ -13,7 +13,7 @@
|
||||
import Fastify, { FastifyInstance, FastifyReply } from 'fastify';
|
||||
import fastifyCompress from '@fastify/compress';
|
||||
import fastifyStatic from '@fastify/static';
|
||||
import path, { join, dirname, resolve, relative, isAbsolute } from 'node:path';
|
||||
import { join, dirname, resolve, relative, isAbsolute } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { existsSync, statSync, mkdirSync, writeFileSync, readdirSync, readFileSync, rmSync } from 'node:fs';
|
||||
import fs from 'node:fs/promises';
|
||||
@@ -89,6 +89,7 @@ import {
|
||||
RespawnEnableSchema,
|
||||
} from './schemas.js';
|
||||
import { StaleExpirationMap } from '../utils/index.js';
|
||||
import { MAX_CONCURRENT_SESSIONS } from '../config/map-limits.js';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@@ -127,8 +128,6 @@ const SESSIONS_LIST_CACHE_TTL = 1000;
|
||||
const SCHEDULED_CLEANUP_INTERVAL = 5 * 60 * 1000;
|
||||
// Completed scheduled runs max age (1 hour)
|
||||
const SCHEDULED_RUN_MAX_AGE = 60 * 60 * 1000;
|
||||
// Maximum concurrent sessions to prevent resource exhaustion
|
||||
const MAX_CONCURRENT_SESSIONS = 50;
|
||||
// SSE client health check interval (every 30 seconds)
|
||||
const SSE_HEALTH_CHECK_INTERVAL = 30 * 1000;
|
||||
// Maximum allowed input length for session write (64KB)
|
||||
@@ -1461,7 +1460,7 @@ export class WebServer extends EventEmitter {
|
||||
}
|
||||
|
||||
const content = session.ralphTracker.generateFixPlanMarkdown();
|
||||
const filePath = path.join(workingDir, '@fix_plan.md');
|
||||
const filePath = join(workingDir, '@fix_plan.md');
|
||||
|
||||
try {
|
||||
await fs.writeFile(filePath, content, 'utf-8');
|
||||
@@ -1491,7 +1490,7 @@ export class WebServer extends EventEmitter {
|
||||
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Session has no working directory');
|
||||
}
|
||||
|
||||
const filePath = path.join(workingDir, '@fix_plan.md');
|
||||
const filePath = join(workingDir, '@fix_plan.md');
|
||||
|
||||
try {
|
||||
const content = await fs.readFile(filePath, 'utf-8');
|
||||
@@ -1534,7 +1533,7 @@ export class WebServer extends EventEmitter {
|
||||
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Session has no working directory');
|
||||
}
|
||||
|
||||
const filePath = path.join(workingDir, '@ralph_prompt.md');
|
||||
const filePath = join(workingDir, '@ralph_prompt.md');
|
||||
|
||||
try {
|
||||
await fs.writeFile(filePath, content, 'utf-8');
|
||||
@@ -5335,12 +5334,13 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
|
||||
|
||||
// Start stats collection for mux sessions
|
||||
this.mux.startStatsCollection(STATS_COLLECTION_INTERVAL_MS);
|
||||
}
|
||||
|
||||
// Start mouse mode sync (tmux only) — toggles mouse on/off based on pane count.
|
||||
// Mouse off = native xterm.js selection; mouse on = tmux pane clicking (split layouts).
|
||||
if ('startMouseModeSync' in this.mux) {
|
||||
(this.mux as { startMouseModeSync: (ms?: number) => void }).startMouseModeSync();
|
||||
}
|
||||
// Start mouse mode sync (tmux only) — toggles mouse on/off based on pane count.
|
||||
// Mouse off = native xterm.js selection; mouse on = tmux pane clicking (split layouts).
|
||||
// Always start, even with no sessions — new sessions may be created later.
|
||||
if ('startMouseModeSync' in this.mux) {
|
||||
(this.mux as { startMouseModeSync: (ms?: number) => void }).startMouseModeSync();
|
||||
}
|
||||
|
||||
if (dead.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user