diff --git a/docs/architecture-invariants.md b/docs/architecture-invariants.md index d58d3655..679a32af 100644 --- a/docs/architecture-invariants.md +++ b/docs/architecture-invariants.md @@ -1339,7 +1339,7 @@ Tests: `test/mobile-prompt-composer.test.ts` (in the CI gate, deliberately not u ### Z-index layers -**Z-index layers**: subagent windows (1000), split picker menu (1000, `.split-picker-menu`), Tiles count menu (1000, `.tile-count-menu`), the closing grid's still copy (`.tile-grid-ghosts`, z-index 3 inside `.main`, over the single view coming back; hidden under `.main.webview-active`), plan agents (1100), mobile/tablet fixed header (1200, `mobile.css`), modals on ≤768px (1300 — must beat the fixed header or the modal close button is buried), log viewers (2000), connection-loss overlay (2500, above the fixed header and modals), image popups (3000), response viewer (5000, backdrop 4999), folder grid (5090, `#folderGridOverlay` — above the response viewer a folder link opens it from, below the file preview its tiles open, so a tile's preview and its ←/→ paging sit on top of the grid), file-preview overlay (5100 — must outrank the response viewer, which can launch it; at its old 2000 a path clicked in the chat opened BEHIND the chat), toasts/path picker (10000+, deliberately above the preview), the custom-model center-status banner (10001, `.center-status-banner` — `[hidden]` must re-assert `display: none` over its own `display: flex`, same trap as `.home-sessions[hidden]`, or `dismiss()` leaves an invisible click-blocker dead centre on screen), the swap-confirm and context-warning modals (10010, `#customModelSwapConfirmModal`/`#customModelContextWarningModal` — must clear both the plain `.modal` z-index of 1000 and the center-status banner it can appear over), terminal touch-selection bar (900 — above terminal content and the local-echo overlay, deliberately BELOW floating agent windows so it can never cover their controls), local echo overlay (7), iOS IME composition preview (EFFECTIVE layer depends on its home: with local echo on it is part of the local echo overlay at 7, drawn by `setComposition()` as an underlined tail after the pending text; with local echo off it is a span at z-index 6 inside `.xterm-helpers`, but `.xterm-helpers` is its own z-index 5 stacking context, so the span's effective layer is 5. That is below the overlay's 7, which is why the span cannot be used while the overlay holds text: typed text never reaches the PTY before Enter, the PTY cursor that places the span stays at the prompt start, and the overlay's opaque line div covers it). +**Z-index layers**: subagent windows (1000), split picker menu (1000, `.split-picker-menu`), Tiles count menu (1000, `.tile-count-menu`), the closing grid's still copy (`.tile-grid-ghosts`, z-index 3 inside `.main`, over the single view coming back; hidden under `.main.webview-active`), mobile/tablet fixed header (1200, `mobile.css`), modals on ≤768px (1300 — must beat the fixed header or the modal close button is buried), log viewers (2000), connection-loss overlay (2500, above the fixed header and modals), image popups (3000), response viewer (5000, backdrop 4999), folder grid (5090, `#folderGridOverlay` — above the response viewer a folder link opens it from, below the file preview its tiles open, so a tile's preview and its ←/→ paging sit on top of the grid), file-preview overlay (5100 — must outrank the response viewer, which can launch it; at its old 2000 a path clicked in the chat opened BEHIND the chat), toasts/path picker (10000+, deliberately above the preview), the custom-model center-status banner (10001, `.center-status-banner` — `[hidden]` must re-assert `display: none` over its own `display: flex`, same trap as `.home-sessions[hidden]`, or `dismiss()` leaves an invisible click-blocker dead centre on screen), the swap-confirm and context-warning modals (10010, `#customModelSwapConfirmModal`/`#customModelContextWarningModal` — must clear both the plain `.modal` z-index of 1000 and the center-status banner it can appear over), terminal touch-selection bar (900 — above terminal content and the local-echo overlay, deliberately BELOW floating agent windows so it can never cover their controls), local echo overlay (7), iOS IME composition preview (EFFECTIVE layer depends on its home: with local echo on it is part of the local echo overlay at 7, drawn by `setComposition()` as an underlined tail after the pending text; with local echo off it is a span at z-index 6 inside `.xterm-helpers`, but `.xterm-helpers` is its own z-index 5 stacking context, so the span's effective layer is 5. That is below the overlay's 7, which is why the span cannot be used while the overlay holds text: typed text never reaches the PTY before Enter, the PTY cursor that places the span stays at the prompt start, and the overlay's opaque line div covers it). ## Security layers diff --git a/scripts/build.mjs b/scripts/build.mjs index d949fcad..f095fbc0 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -157,7 +157,6 @@ console.log('\n[build] content-hash cache busting'); 'settings-ui.js', 'panels-ui.js', 'session-ui.js', - 'ralph-wizard.js', 'api-client.js', 'subagent-windows.js', 'image-input.js', diff --git a/src/web/CLAUDE.md b/src/web/CLAUDE.md index 5cc46b70..e4825913 100644 --- a/src/web/CLAUDE.md +++ b/src/web/CLAUDE.md @@ -94,6 +94,6 @@ Frontend JS modules have `@fileoverview` with `@dependency`/`@loadorder` tags. L **SSE staleness watchdog** (`computeSseStale()` in constants.js, `_checkSseStale()` + a 5s interval in app.js): an `EventSource` can stop delivering without erroring, so the client forces a reconnect when nothing arrives. ⚠️ The server keepalive must stay the named `sse:heartbeat` event (`cleanupDeadClients()`, sse-stream-manager.ts), never an SSE comment, which `EventSource` cannot observe; its no-op client listener must stay registered. ⚠️ Judge staleness only while `connected` and online (the loop breaker). ⚠️ The liveness stamp lives inside `addListener`. ⚠️ Clear the interval only at the top of `connectSSE()`, or intervals stack. ⚠️ The watchdog cannot see an attempt that never OPENS (no response headers: no `open`, no `error`, never `connected`), so each attempt is bounded by `SSE_CONNECT_TIMEOUT_MS` (15s, `CodemanSseStale.CONNECT_TIMEOUT_MS`) and then retried through `_handleSseConnectionFailure()`, the same backoff `onerror` uses. Its timer is cleared at the top of `connectSSE()` BEFORE the offline early return, on `open`, and in `_handleSseConnectionFailure()`; the timer and the handler both ignore an `EventSource` that has been replaced. The window `offline` handler leaves it running on purpose (`navigator.onLine` can report offline on a working network). Tests: `test/sse-connect-timeout.test.ts`. → [architecture-invariants#sse-staleness-watchdog](../../docs/architecture-invariants.md#sse-staleness-watchdog) -**Z-index layers** (keep new overlays consistent with this stack): local echo overlay (7; with local echo on it also draws the iOS IME composition preview, as an underlined tail after its pending text via `setComposition`), iOS IME composition preview span when local echo is off (6 inside `.xterm-helpers`, whose own z-index 5 is its EFFECTIVE layer, so it sits UNDER the overlay and must never be used while the overlay shows text), terminal touch-selection bar (900, below floating agent windows), subagent windows + split picker menu + Tiles count menu (1000), plan agents (1100), mobile/tablet fixed header (1200), modals on ≤768px (1300, must beat the fixed header), log viewers (2000), connection-loss overlay (2500), image popups (3000), response viewer (5000, backdrop 4999), folder grid (5090, above the response viewer it opens from, below the file preview its tiles open), file-preview overlay (5100, must outrank the response viewer that launches it), toasts/path picker (10000+), custom-model center-status banner (10001; its `[hidden]` must re-assert `display: none` or `dismiss()` leaves an invisible click-blocker), custom-model swap-confirm/context-warning modals (10010). → [architecture-invariants#z-index-layers](../../docs/architecture-invariants.md#z-index-layers) +**Z-index layers** (keep new overlays consistent with this stack): local echo overlay (7; with local echo on it also draws the iOS IME composition preview, as an underlined tail after its pending text via `setComposition`), iOS IME composition preview span when local echo is off (6 inside `.xterm-helpers`, whose own z-index 5 is its EFFECTIVE layer, so it sits UNDER the overlay and must never be used while the overlay shows text), terminal touch-selection bar (900, below floating agent windows), subagent windows + split picker menu + Tiles count menu (1000), mobile/tablet fixed header (1200), modals on ≤768px (1300, must beat the fixed header), log viewers (2000), connection-loss overlay (2500), image popups (3000), response viewer (5000, backdrop 4999), folder grid (5090, above the response viewer it opens from, below the file preview its tiles open), file-preview overlay (5100, must outrank the response viewer that launches it), toasts/path picker (10000+), custom-model center-status banner (10001; its `[hidden]` must re-assert `display: none` or `dismiss()` leaves an invisible click-blocker), custom-model swap-confirm/context-warning modals (10010). → [architecture-invariants#z-index-layers](../../docs/architecture-invariants.md#z-index-layers) **Keyboard shortcuts**: Escape (close), Ctrl+? (shortcut overlay), Ctrl/Cmd/Alt+K (session palette), Ctrl+Tab (next), Alt+[/] (prev/next tab), Alt+1-9 (switch tab), Ctrl+Shift+{/} (move tab left/right), Shift+Enter or Ctrl+Enter (newline), Ctrl+C (copy selection, else interrupt) / Ctrl+Shift+C (copy, never interrupts), Ctrl+L (clear), Ctrl+Shift+R (restore size), Ctrl+Shift+V (voice input), Ctrl/Cmd +/- (font), Shift+Wheel (local scrollback when mouse passthrough is active), Shift+drag (start a selection in a stripped-DECSET pane, where xterm's own Shift branch is unreachable and a Shift+drag used to select nothing; `_installShiftDragSelection`), right-click (copy the selection, the mintty/PuTTY convention, since xterm paints into a canvas and the native menu has no Copy for it; with nothing selected the native menu is left alone). Rebindable via the registry. ⚠️ **Ctrl+W is deliberately NOT bound** (owner decision): it is delete-word in every shell and agent CLI, and as Close Session it killed sessions with no confirm; `close-session` keeps `bindings: []` and stays bindable (`test/ctrl-w-never-closes.test.ts`). diff --git a/src/web/public/api-client.js b/src/web/public/api-client.js index fea0d2b5..0e14c5e8 100644 --- a/src/web/public/api-client.js +++ b/src/web/public/api-client.js @@ -7,7 +7,7 @@ * * @mixin Extends CodemanApp.prototype via Object.assign * @dependency app.js (CodemanApp class must be defined) - * @loadorder 14 of 15 — loaded after ralph-wizard.js + * @loadorder 14 of 15 — loaded after session-ui.js */ // Codeman — Centralized API fetch helpers for CodemanApp diff --git a/src/web/public/app.js b/src/web/public/app.js index 5633aa21..8e58b9fd 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -11,7 +11,6 @@ * panels-ui.js — Subagent panel, agent teams, project insights, file browser, log viewer, * image popups, monitor, token stats, toast, system stats * session-ui.js — Quick start, session options modal, case settings, mobile case picker - * ralph-wizard.js — Ralph Loop wizard modal * api-client.js — API helper methods (fetch wrappers) * subagent-windows.js — Floating subagent terminal windows * @@ -299,13 +298,6 @@ const _SSE_HANDLER_MAP = [ [SSE_EVENTS.TUNNEL_QR_REGENERATED, '_onTunnelQrRegenerated'], [SSE_EVENTS.TUNNEL_QR_AUTH_USED, '_onTunnelQrAuthUsed'], - // Plan orchestration - [SSE_EVENTS.PLAN_SUBAGENT, '_onPlanSubagent'], - [SSE_EVENTS.PLAN_PROGRESS, '_onPlanProgress'], - [SSE_EVENTS.PLAN_STARTED, '_onPlanStarted'], - [SSE_EVENTS.PLAN_CANCELLED, '_onPlanCancelled'], - [SSE_EVENTS.PLAN_COMPLETED, '_onPlanCompleted'], - // Orchestrator loop [SSE_EVENTS.ORCHESTRATOR_STATE_CHANGED, '_onOrchestratorStateChanged'], [SSE_EVENTS.ORCHESTRATOR_PLAN_PROGRESS, '_onOrchestratorPlanProgress'], @@ -872,17 +864,6 @@ class CodemanApp { this.ralphStatePanelCollapsed = true; // Default to collapsed this.ralphClosedSessions = new Set(); // Sessions where user explicitly closed Ralph panel - // Plan subagent windows (visible agents during plan generation) - this.planSubagents = new Map(); // Map - this.planSubagentWindowZIndex = ZINDEX_PLAN_SUBAGENT_BASE; - this.planGenerationStopped = false; // Flag to ignore SSE events after Stop - this.planAgentsMinimized = false; // Whether agent windows are minimized to tab - - // Wizard dragging state - this.wizardDragState = null; // { startX, startY, startLeft, startTop, isDragging } - this.wizardDragListeners = null; // { move, up } for cleanup - this.wizardPosition = null; // { left, top } - null means centered - // Project Insights tracking (active Bash tools with clickable file paths) this.projectInsights = new Map(); // Map this.logViewerWindows = new Map(); // Map @@ -5058,10 +5039,6 @@ class CodemanApp { // wrapping) clipped xterm's bottom rows behind the toolbar until a tab // switch or a window resize. // Clear any other orphaned timers - if (this.planLoadingTimer) { - clearInterval(this.planLoadingTimer); - this.planLoadingTimer = null; - } if (this.timerCountdownInterval) { clearInterval(this.timerCountdownInterval); this.timerCountdownInterval = null; @@ -11140,28 +11117,6 @@ class CodemanApp { this.renderRalphStatePanel(); } - // ═══════════════════════════════════════════════════════════════ - // Ralph Loop Wizard (methods in ralph-wizard.js) - // ═══════════════════════════════════════════════════════════════ - - // Wizard state (initialized here, methods loaded from ralph-wizard.js) - ralphWizardStep = 1; - ralphWizardConfig = { - taskDescription: '', - completionPhrase: 'COMPLETE', - maxIterations: 10, - caseName: 'testcase', - enableRespawn: false, - generatedPlan: null, - planGenerated: false, - skipPlanGeneration: false, - planDetailLevel: 'detailed', - existingPlan: null, - useExistingPlan: false, - }; - planLoadingTimer = null; - planLoadingStartTime = null; - // ═══════════════════════════════════════════════════════════════ // Kill Sessions // ═══════════════════════════════════════════════════════════════ diff --git a/src/web/public/constants.js b/src/web/public/constants.js index f3f2b2ae..7421e1c7 100644 --- a/src/web/public/constants.js +++ b/src/web/public/constants.js @@ -16,7 +16,7 @@ * @dependency None (first in load order) * @loadorder 1 of 15 — constants.js → mobile-handlers.js → voice-input.js → notification-manager.js * → keyboard-accessory.js → input-cjk.js → app.js → terminal-ui.js → respawn-ui.js - * → ralph-panel.js → settings-ui.js → panels-ui.js → session-ui.js → ralph-wizard.js + * → ralph-panel.js → settings-ui.js → panels-ui.js → session-ui.js * → api-client.js → subagent-windows.js */ @@ -135,7 +135,6 @@ const TUI_REDRAW_SETTLE_MS = 400; // Grace for a TUI to redraw after a // Z-index base values for layered floating windows const ZINDEX_SUBAGENT_BASE = 1000; -const ZINDEX_PLAN_SUBAGENT_BASE = 1100; const ZINDEX_LOG_VIEWER_BASE = 2000; const ZINDEX_IMAGE_POPUP_BASE = 3000; @@ -1964,7 +1963,7 @@ function getEventCoords(e) { return { clientX: e.clientX, clientY: e.clientY }; } -// HTML escape utility (shared by NotificationManager, CodemanApp, and ralph-wizard.js) +// HTML escape utility (shared by NotificationManager and the CodemanApp mixins) const _htmlEscapeMap = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; const _htmlEscapePattern = /[&<>"']/g; function escapeHtml(text) { diff --git a/src/web/public/entrance-animations.js b/src/web/public/entrance-animations.js index a7068e0a..76fa99d2 100644 --- a/src/web/public/entrance-animations.js +++ b/src/web/public/entrance-animations.js @@ -58,7 +58,7 @@ * @dependency app.js (tab render pipeline), subagent-windows.js (window + line hooks), * tile-grid.js (tile mount, reveal and still-copy hooks) * @dependency constants.js (escapeHtml) - * @loadorder 12.6 of 16, after webview-tabs.js, before ralph-wizard.js + * @loadorder 12.6 of 16, after webview-tabs.js, before api-client.js */ /** Tab entrance styles. `key` doubles as the `data-tab-anim` value. */ diff --git a/src/web/public/index.html b/src/web/public/index.html index 9d1a3248..7d1d1430 100644 --- a/src/web/public/index.html +++ b/src/web/public/index.html @@ -1280,16 +1280,6 @@
No mux sessions
-
Background Agents @@ -4217,189 +4207,6 @@
- - - -