aicodeman 1.41.1 → 1.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -24
- package/dist/claude-session-title.d.ts +6 -4
- package/dist/claude-session-title.d.ts.map +1 -1
- package/dist/claude-session-title.js +6 -4
- package/dist/claude-session-title.js.map +1 -1
- package/dist/cli-agent.js +1 -1
- package/dist/cli-agent.js.map +1 -1
- package/dist/config/cli-registry/patterns.d.ts +1 -1
- package/dist/config/cli-registry/patterns.d.ts.map +1 -1
- package/dist/config/cli-registry/patterns.js +3 -0
- package/dist/config/cli-registry/patterns.js.map +1 -1
- package/dist/config/cli-registry/schema.d.ts +3 -0
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +19 -3
- package/dist/config/cli-registry/schema.js.map +1 -1
- package/dist/config/cli-registry/stock.d.ts.map +1 -1
- package/dist/config/cli-registry/stock.js +302 -7
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +37 -3
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/git-worktrees.d.ts +292 -0
- package/dist/git-worktrees.d.ts.map +1 -0
- package/dist/git-worktrees.js +791 -0
- package/dist/git-worktrees.js.map +1 -0
- package/dist/hooks-config.d.ts +9 -0
- package/dist/hooks-config.d.ts.map +1 -1
- package/dist/hooks-config.js +12 -0
- package/dist/hooks-config.js.map +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +2 -1
- package/dist/mcp-server.js.map +1 -1
- package/dist/mcp-sync-targets.d.ts +6 -3
- package/dist/mcp-sync-targets.d.ts.map +1 -1
- package/dist/mcp-sync-targets.js +6 -3
- package/dist/mcp-sync-targets.js.map +1 -1
- package/dist/mux-interface.d.ts +7 -3
- package/dist/mux-interface.d.ts.map +1 -1
- package/dist/services/unified-session-service.d.ts +8 -0
- package/dist/services/unified-session-service.d.ts.map +1 -1
- package/dist/services/unified-session-service.js +21 -0
- package/dist/services/unified-session-service.js.map +1 -1
- package/dist/session-activity.d.ts +51 -0
- package/dist/session-activity.d.ts.map +1 -1
- package/dist/session-activity.js +62 -0
- package/dist/session-activity.js.map +1 -1
- package/dist/session-cli-registry-bridge.d.ts +2 -1
- package/dist/session-cli-registry-bridge.d.ts.map +1 -1
- package/dist/session-cli-registry-bridge.js.map +1 -1
- package/dist/session-submit-verifier.js +1 -1
- package/dist/session.d.ts +84 -9
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +232 -18
- package/dist/session.js.map +1 -1
- package/dist/tmux-manager.d.ts +62 -7
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +98 -20
- package/dist/tmux-manager.js.map +1 -1
- package/dist/types/session.d.ts +32 -4
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js +2 -1
- package/dist/types/session.js.map +1 -1
- package/dist/utils/cli-installed-probes.d.ts +1 -1
- package/dist/utils/cli-installed-probes.d.ts.map +1 -1
- package/dist/utils/cli-installed-probes.js +4 -2
- package/dist/utils/cli-installed-probes.js.map +1 -1
- package/dist/utils/copilot-cli-resolver.d.ts +48 -0
- package/dist/utils/copilot-cli-resolver.d.ts.map +1 -0
- package/dist/utils/copilot-cli-resolver.js +112 -0
- package/dist/utils/copilot-cli-resolver.js.map +1 -0
- package/dist/utils/deepseek-cli-resolver.d.ts.map +1 -1
- package/dist/utils/deepseek-cli-resolver.js +1 -1
- package/dist/utils/deepseek-cli-resolver.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/web/approval-inbox.d.ts +12 -2
- package/dist/web/approval-inbox.d.ts.map +1 -1
- package/dist/web/approval-inbox.js +7 -2
- package/dist/web/approval-inbox.js.map +1 -1
- package/dist/web/case-path.d.ts +4 -2
- package/dist/web/case-path.d.ts.map +1 -1
- package/dist/web/case-path.js +13 -4
- package/dist/web/case-path.js.map +1 -1
- package/dist/web/public/admin-ui.js.gz +0 -0
- package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
- package/dist/web/public/app.ae50029a.js +43 -0
- package/dist/web/public/app.ae50029a.js.br +0 -0
- package/dist/web/public/app.ae50029a.js.gz +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/{constants.17d77b65.js → constants.e5e588db.js} +156 -2
- package/dist/web/public/constants.e5e588db.js.br +0 -0
- package/dist/web/public/constants.e5e588db.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/git-status-ui.js.gz +0 -0
- package/dist/web/public/home-sessions.js.gz +0 -0
- package/dist/web/public/host-wake-ui.js.gz +0 -0
- package/dist/web/public/i18n.8f291f06.js +2 -0
- package/dist/web/public/i18n.8f291f06.js.br +0 -0
- package/dist/web/public/i18n.8f291f06.js.gz +0 -0
- package/dist/web/public/{image-input.9ed1d0d2.js → image-input.941386e7.js} +41 -22
- package/dist/web/public/image-input.941386e7.js.br +0 -0
- package/dist/web/public/image-input.941386e7.js.gz +0 -0
- package/dist/web/public/index.html +88 -16
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.8bc46081.js.gz +0 -0
- package/dist/web/public/{keyboard-accessory.c458eea8.js → keyboard-accessory.c283e827.js} +40 -29
- package/dist/web/public/keyboard-accessory.c283e827.js.br +0 -0
- package/dist/web/public/keyboard-accessory.c283e827.js.gz +0 -0
- package/dist/web/public/mobile-handlers.0ef9c311.js.gz +0 -0
- package/dist/web/public/mobile-ime-preview.2dbaf262.js.gz +0 -0
- package/dist/web/public/mobile-overview.js +1 -0
- package/dist/web/public/mobile-overview.js.br +0 -0
- package/dist/web/public/mobile-overview.js.gz +0 -0
- package/dist/web/public/mobile.13514863.css +1 -0
- package/dist/web/public/mobile.13514863.css.br +0 -0
- package/dist/web/public/mobile.13514863.css.gz +0 -0
- package/dist/web/public/notification-manager.feb82c04.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/{panels-ui.73ec0137.js → panels-ui.b7bfb9da.js} +6 -6
- package/dist/web/public/panels-ui.b7bfb9da.js.br +0 -0
- package/dist/web/public/panels-ui.b7bfb9da.js.gz +0 -0
- package/dist/web/public/ralph-panel.b350e2ef.js.gz +0 -0
- package/dist/web/public/ralph-wizard.b6c0dd19.js.gz +0 -0
- package/dist/web/public/readmymind-ui.js.gz +0 -0
- package/dist/web/public/reboot-restore-ui.js.gz +0 -0
- package/dist/web/public/{respawn-ui.ff0dae4c.js → respawn-ui.d7adcf6a.js} +1 -1
- package/dist/web/public/respawn-ui.d7adcf6a.js.br +0 -0
- package/dist/web/public/respawn-ui.d7adcf6a.js.gz +0 -0
- package/dist/web/public/sanitize-html.e7147e76.js.gz +0 -0
- package/dist/web/public/security-notices.json +21 -0
- package/dist/web/public/session-lineage.js.gz +0 -0
- package/dist/web/public/session-ui.be076c88.js +100 -0
- package/dist/web/public/session-ui.be076c88.js.br +0 -0
- package/dist/web/public/session-ui.be076c88.js.gz +0 -0
- package/dist/web/public/settings-ui.fc4cc50a.js +97 -0
- package/dist/web/public/settings-ui.fc4cc50a.js.br +0 -0
- package/dist/web/public/settings-ui.fc4cc50a.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview-worker.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview.75c751de.js.gz +0 -0
- package/dist/web/public/spreadsheet-xlsx-core.js.gz +0 -0
- package/dist/web/public/styles.dcfa907f.css +1 -0
- package/dist/web/public/styles.dcfa907f.css.br +0 -0
- package/dist/web/public/styles.dcfa907f.css.gz +0 -0
- package/dist/web/public/subagent-windows.07277a58.js.gz +0 -0
- package/dist/web/public/sw.js +2 -2
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/tab-layout-browser.2d6189f7.js.gz +0 -0
- package/dist/web/public/tab-rail-resize.7157e0bd.js.gz +0 -0
- package/dist/web/public/terminal-keycode229-recovery.af09f99a.js.gz +0 -0
- package/dist/web/public/terminal-split.js.gz +0 -0
- package/dist/web/public/terminal-tile.js +1 -0
- package/dist/web/public/terminal-tile.js.br +0 -0
- package/dist/web/public/terminal-tile.js.gz +0 -0
- package/dist/web/public/terminal-ui.ae01a7d1.js +2 -0
- package/dist/web/public/terminal-ui.ae01a7d1.js.br +0 -0
- package/dist/web/public/terminal-ui.ae01a7d1.js.gz +0 -0
- package/dist/web/public/tile-grid.js +3 -6
- package/dist/web/public/tile-grid.js.br +0 -0
- package/dist/web/public/tile-grid.js.gz +0 -0
- package/dist/web/public/ultracode-panel.js.gz +0 -0
- package/dist/web/public/ultracode-windows.js.gz +0 -0
- package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
- package/dist/web/public/vendor/exceljs.min.js.gz +0 -0
- package/dist/web/public/vendor/fflate.min.js.gz +0 -0
- package/dist/web/public/vendor/marked.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-predictive-echo.ae5e3d5d.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.0b69623c.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/public/voice-input.2342c37b.js.gz +0 -0
- package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
- package/dist/web/public/webview-tabs.js.gz +0 -0
- package/dist/web/public/whats-new.json +13 -0
- package/dist/web/response-viewer-transcript.d.ts +6 -0
- package/dist/web/response-viewer-transcript.d.ts.map +1 -1
- package/dist/web/response-viewer-transcript.js +134 -1
- package/dist/web/response-viewer-transcript.js.map +1 -1
- package/dist/web/routes/approval-routes.d.ts.map +1 -1
- package/dist/web/routes/approval-routes.js +12 -8
- package/dist/web/routes/approval-routes.js.map +1 -1
- package/dist/web/routes/case-routes.d.ts.map +1 -1
- package/dist/web/routes/case-routes.js +9 -2
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/index.d.ts +1 -0
- package/dist/web/routes/index.d.ts.map +1 -1
- package/dist/web/routes/index.js +1 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/mcp-sync-routes.d.ts +4 -4
- package/dist/web/routes/mcp-sync-routes.js +4 -4
- package/dist/web/routes/ralph-routes.d.ts.map +1 -1
- package/dist/web/routes/ralph-routes.js +19 -14
- package/dist/web/routes/ralph-routes.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts +19 -7
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +227 -66
- package/dist/web/routes/session-routes.js.map +1 -1
- package/dist/web/routes/status-telemetry-routes.d.ts.map +1 -1
- package/dist/web/routes/status-telemetry-routes.js +9 -5
- package/dist/web/routes/status-telemetry-routes.js.map +1 -1
- package/dist/web/routes/system-routes.d.ts +9 -0
- package/dist/web/routes/system-routes.d.ts.map +1 -1
- package/dist/web/routes/system-routes.js +102 -12
- package/dist/web/routes/system-routes.js.map +1 -1
- package/dist/web/routes/worktree-routes.d.ts +52 -0
- package/dist/web/routes/worktree-routes.d.ts.map +1 -0
- package/dist/web/routes/worktree-routes.js +220 -0
- package/dist/web/routes/worktree-routes.js.map +1 -0
- package/dist/web/schemas.d.ts +30 -1
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +74 -3
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/screen-blocked.d.ts +80 -0
- package/dist/web/screen-blocked.d.ts.map +1 -0
- package/dist/web/screen-blocked.js +106 -0
- package/dist/web/screen-blocked.js.map +1 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +23 -2
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-listener-wiring.d.ts +1 -0
- package/dist/web/session-listener-wiring.d.ts.map +1 -1
- package/dist/web/session-listener-wiring.js +20 -0
- package/dist/web/session-listener-wiring.js.map +1 -1
- package/dist/web/session-wait-registry.d.ts +27 -9
- package/dist/web/session-wait-registry.d.ts.map +1 -1
- package/dist/web/session-wait-registry.js +36 -13
- package/dist/web/session-wait-registry.js.map +1 -1
- package/dist/web/sse-events.d.ts +7 -2
- package/dist/web/sse-events.d.ts.map +1 -1
- package/dist/web/sse-events.js +7 -2
- package/dist/web/sse-events.js.map +1 -1
- package/package.json +2 -2
- package/skills/codeman/SKILL.md +21 -17
- package/skills/codeman/preamble.sh +14 -11
- package/skills/codeman/reference/endpoints.md +8 -8
- package/skills/codeman/reference/messaging.md +5 -5
- package/skills/codeman/reference/recipes.md +13 -10
- package/skills/codeman/reference/verbs.md +7 -5
- package/dist/web/public/app.24689381.js +0 -43
- package/dist/web/public/app.24689381.js.br +0 -0
- package/dist/web/public/app.24689381.js.gz +0 -0
- package/dist/web/public/constants.17d77b65.js.br +0 -0
- package/dist/web/public/constants.17d77b65.js.gz +0 -0
- package/dist/web/public/i18n.9afd8e4d.js +0 -2
- package/dist/web/public/i18n.9afd8e4d.js.br +0 -0
- package/dist/web/public/i18n.9afd8e4d.js.gz +0 -0
- package/dist/web/public/image-input.9ed1d0d2.js.br +0 -0
- package/dist/web/public/image-input.9ed1d0d2.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.c458eea8.js.br +0 -0
- package/dist/web/public/keyboard-accessory.c458eea8.js.gz +0 -0
- package/dist/web/public/mobile.2dff1580.css +0 -1
- package/dist/web/public/mobile.2dff1580.css.br +0 -0
- package/dist/web/public/mobile.2dff1580.css.gz +0 -0
- package/dist/web/public/panels-ui.73ec0137.js.br +0 -0
- package/dist/web/public/panels-ui.73ec0137.js.gz +0 -0
- package/dist/web/public/respawn-ui.ff0dae4c.js.br +0 -0
- package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
- package/dist/web/public/session-ui.dbc6819b.js +0 -100
- package/dist/web/public/session-ui.dbc6819b.js.br +0 -0
- package/dist/web/public/session-ui.dbc6819b.js.gz +0 -0
- package/dist/web/public/settings-ui.81ac264e.js +0 -97
- package/dist/web/public/settings-ui.81ac264e.js.br +0 -0
- package/dist/web/public/settings-ui.81ac264e.js.gz +0 -0
- package/dist/web/public/styles.900a28e4.css +0 -1
- package/dist/web/public/styles.900a28e4.css.br +0 -0
- package/dist/web/public/styles.900a28e4.css.gz +0 -0
- package/dist/web/public/terminal-ui.858f5da5.js +0 -2
- package/dist/web/public/terminal-ui.858f5da5.js.br +0 -0
- package/dist/web/public/terminal-ui.858f5da5.js.gz +0 -0
package/dist/session.js
CHANGED
|
@@ -42,7 +42,7 @@ import { TaskTracker } from './task-tracker.js';
|
|
|
42
42
|
import { RalphTracker } from './ralph-tracker.js';
|
|
43
43
|
import { BashToolParser } from './bash-tool-parser.js';
|
|
44
44
|
import { isTrustDialogScreen, trustDialogNextKey, TRUST_KEY_CONFIRM, TRUST_DIALOG_WINDOW_MS, TRUST_DIALOG_RETRY_MS, TRUST_DIALOG_MAX_ATTEMPTS, TRUST_DIALOG_SCAN_BYTES, } from './session-trust-dialog.js';
|
|
45
|
-
import { trackActivityStreak, isSustainedActivity, isPaneQuiet, watchingLabel, isAwaitingWorkers, WATCHING_TAIL_LINES, IDLE_RECHECK_MS, PANE_PROBE_MIN_INTERVAL_MS, PANE_PROBE_RECHECK_MS, } from './session-activity.js';
|
|
45
|
+
import { trackActivityStreak, isSustainedActivity, isPaneQuiet, watchingLabel, isAwaitingWorkers, isBlockedScreen, WATCHING_TAIL_LINES, BLOCKED_TAIL_LINES, BLOCKED_RECHECK_MS, BLOCKED_QUIET_RECHECK_MS, BLOCKED_CLEAR_READS, IDLE_RECHECK_MS, PANE_PROBE_MIN_INTERVAL_MS, PANE_PROBE_RECHECK_MS, } from './session-activity.js';
|
|
46
46
|
import { BufferAccumulator, ANSI_ESCAPE_PATTERN_FULL, TOKEN_PATTERN, SPINNER_PATTERN, CLAUDE_WORKING_LINE_PATTERN, MAX_SESSION_TOKENS, execPattern, getClaudeCliVersion, getClaudeBinaryPath, spawnPtyWithHelperRepair, resolveLocalShell, waitForProcessesExit, } from './utils/index.js';
|
|
47
47
|
import { MAX_TERMINAL_BUFFER_SIZE, TRIM_TERMINAL_TO as TERMINAL_BUFFER_TRIM_SIZE, MAX_TEXT_OUTPUT_SIZE, TRIM_TEXT_TO as TEXT_OUTPUT_TRIM_SIZE, MAX_MESSAGES, MAX_LINE_BUFFER_SIZE, } from './config/buffer-limits.js';
|
|
48
48
|
import { DEFAULT_TMUX_HISTORY_LIMIT } from './config/terminal-history.js';
|
|
@@ -341,6 +341,8 @@ export class Session extends EventEmitter {
|
|
|
341
341
|
_taskCache = new SessionTaskCache();
|
|
342
342
|
_name;
|
|
343
343
|
_nameSource;
|
|
344
|
+
/** `pinCliSessionName` as of the last spawn (see {@link _refreshCliNamePin}). */
|
|
345
|
+
_pinEveryCliName = false;
|
|
344
346
|
/**
|
|
345
347
|
* Reconstructs the composer draft from USER keystrokes so the first real
|
|
346
348
|
* prompt can name the tab. Fed only when a write says `fromUser`, and never
|
|
@@ -408,6 +410,7 @@ export class Session extends EventEmitter {
|
|
|
408
410
|
_activityStreak = null; // Unbroken run of PTY repaints (working detection)
|
|
409
411
|
_lastPaneProbeAt = 0; // Throttle for the tmux screen probe
|
|
410
412
|
_lastPaneProbeWorking = null; // Its last verdict (null = could not read)
|
|
413
|
+
_lastPaneProbeTrustDialog = false; // Same capture showed the workspace-trust dialog (see _confirmIdle)
|
|
411
414
|
/**
|
|
412
415
|
* Background work the pane's own footer reports, e.g. `1 monitor`; null for none.
|
|
413
416
|
*
|
|
@@ -441,6 +444,23 @@ export class Session extends EventEmitter {
|
|
|
441
444
|
_watchingWindow = WATCHING_TAIL_LINES;
|
|
442
445
|
/** Lazily compiled `capabilities.workDetect.awaitingLine`. See _awaitingLinePattern(). */
|
|
443
446
|
_awaitingLineRe = undefined;
|
|
447
|
+
/** Lazily compiled `capabilities.workDetect.blockedLine`. See _blockedLinePattern(). */
|
|
448
|
+
_blockedLineRe = undefined;
|
|
449
|
+
/** Resolved with the pattern above: how many rows at the foot of the screen it sees. */
|
|
450
|
+
_blockedWindow = BLOCKED_TAIL_LINES;
|
|
451
|
+
/**
|
|
452
|
+
* The pane is showing a dialog the CLI blocks on, read off the screen with
|
|
453
|
+
* `capabilities.workDetect.blockedLine` (codex: an approval, a question, the trust
|
|
454
|
+
* prompt). Live state, not persisted: a restarted server re-reads it from the attach
|
|
455
|
+
* repaint the same way the watching label comes back. See `_noteBlockedReading()`.
|
|
456
|
+
*/
|
|
457
|
+
_screenBlocked = false;
|
|
458
|
+
/** Consecutive readable captures without the dialog (cleared at BLOCKED_CLEAR_READS). */
|
|
459
|
+
_blockedGoneReads = 0;
|
|
460
|
+
/** When the last reading that SAW the dialog was taken. See `_armBlockedRecheck()`. */
|
|
461
|
+
_blockedSeenAt = 0;
|
|
462
|
+
/** Re-reads the screen while a dialog is up, so the alert clears with it. */
|
|
463
|
+
_blockedRecheckTimer = null;
|
|
444
464
|
/**
|
|
445
465
|
* The newest model the running CLI reported for itself (its statusline, or its own
|
|
446
466
|
* footer read off the probe's capture), or null when none has. Feeds `displayModel`
|
|
@@ -555,6 +575,8 @@ export class Session extends EventEmitter {
|
|
|
555
575
|
_piConfig;
|
|
556
576
|
// Grok configuration (only for mode === 'grok')
|
|
557
577
|
_grokConfig;
|
|
578
|
+
// GitHub Copilot configuration (only for mode === 'copilot')
|
|
579
|
+
_copilotConfig;
|
|
558
580
|
// DeepSeek Harness configuration (only for mode === 'deepseek')
|
|
559
581
|
_deepSeekConfig;
|
|
560
582
|
// OMP configuration (only for mode === 'omp')
|
|
@@ -723,6 +745,10 @@ export class Session extends EventEmitter {
|
|
|
723
745
|
if (config.grokConfig) {
|
|
724
746
|
this._grokConfig = config.grokConfig;
|
|
725
747
|
}
|
|
748
|
+
// Apply GitHub Copilot configuration
|
|
749
|
+
if (config.copilotConfig) {
|
|
750
|
+
this._copilotConfig = config.copilotConfig;
|
|
751
|
+
}
|
|
726
752
|
// Apply env overrides (exported at spawn, not persisted to disk).
|
|
727
753
|
// Legacy migration: pre-0.7.2 carried effort as the CLAUDE_CODE_EFFORT_LEVEL env var,
|
|
728
754
|
// which hard-locks /effort switching. Extract it into _effort (--settings soft default)
|
|
@@ -1104,6 +1130,15 @@ export class Session extends EventEmitter {
|
|
|
1104
1130
|
get watching() {
|
|
1105
1131
|
return this._watching;
|
|
1106
1132
|
}
|
|
1133
|
+
/**
|
|
1134
|
+
* True while the pane shows a dialog its CLI is blocked on, as read off the screen
|
|
1135
|
+
* (`capabilities.workDetect.blockedLine`). Always false for a CLI that declares none,
|
|
1136
|
+
* Claude included: its dialogs arrive as hook events instead. The `blocked` wait reads
|
|
1137
|
+
* it so a caller that asks after the dialog appeared is answered at once.
|
|
1138
|
+
*/
|
|
1139
|
+
get screenBlocked() {
|
|
1140
|
+
return this._screenBlocked;
|
|
1141
|
+
}
|
|
1107
1142
|
/**
|
|
1108
1143
|
* Prompt-cache state of the main conversation as Claude Code last reported it on the
|
|
1109
1144
|
* statusline (v2.1.251+), fed by `POST /api/status-telemetry`. Null until the first
|
|
@@ -1407,16 +1442,31 @@ export class Session extends EventEmitter {
|
|
|
1407
1442
|
return this._nameSource;
|
|
1408
1443
|
}
|
|
1409
1444
|
/**
|
|
1410
|
-
* The name to pin on the Claude CLI as `--name`, or undefined to let Claude
|
|
1411
|
-
*
|
|
1412
|
-
*
|
|
1413
|
-
*
|
|
1414
|
-
*
|
|
1415
|
-
* in a case the same `/resume` entry
|
|
1416
|
-
* prompt, which Claude's
|
|
1445
|
+
* The name to pin on the Claude CLI as `--name`, or undefined to let Claude title the
|
|
1446
|
+
* conversation itself. `--name` is the prompt-box label, the `/resume` picker entry and the
|
|
1447
|
+
* terminal title all at once, and a pinned title stops Claude generating its own.
|
|
1448
|
+
*
|
|
1449
|
+
* By default only a name the user chose is pinned. Pinning the `w1-myapp` placeholder gave
|
|
1450
|
+
* every conversation in a case the same `/resume` entry (the tab number restarts once a
|
|
1451
|
+
* case's tabs are closed), and an auto name is a cut of the first prompt, which Claude's
|
|
1452
|
+
* own generated title already beats.
|
|
1453
|
+
*
|
|
1454
|
+
* With the opt-in `pinCliSessionName` setting every non-blank tab name is pinned, so the
|
|
1455
|
+
* CLI's labels read the same as the tabs, at the cost of those generated titles. A rename
|
|
1456
|
+
* in Codeman then holds only until the next turn: a process started with `--name`
|
|
1457
|
+
* re-appends its in-memory title (see claude-session-title.ts). The setting is re-read
|
|
1458
|
+
* at each spawn and respawn by {@link _refreshCliNamePin}.
|
|
1417
1459
|
*/
|
|
1418
1460
|
get cliPinnedName() {
|
|
1419
|
-
|
|
1461
|
+
if (!this._pinEveryCliName)
|
|
1462
|
+
return this._nameSource === 'manual' ? this._name : undefined;
|
|
1463
|
+
return this._name.trim() ? this._name : undefined;
|
|
1464
|
+
}
|
|
1465
|
+
/** Re-read `pinCliSessionName` so `cliPinnedName` decides per launch, with no server restart. */
|
|
1466
|
+
async _refreshCliNamePin() {
|
|
1467
|
+
// Dynamic: hooks-config -> route-helpers imports Session, so a static import would be a cycle.
|
|
1468
|
+
const { readPinCliSessionNameEnabled } = await import('./hooks-config.js');
|
|
1469
|
+
this._pinEveryCliName = await readPinCliSessionNameEnabled();
|
|
1420
1470
|
}
|
|
1421
1471
|
setAutoClear(enabled, threshold) {
|
|
1422
1472
|
this._autoOps.setAutoClear(enabled, threshold);
|
|
@@ -1585,6 +1635,7 @@ export class Session extends EventEmitter {
|
|
|
1585
1635
|
antigravityConfig: this._antigravityConfig,
|
|
1586
1636
|
piConfig: this._piConfig,
|
|
1587
1637
|
grokConfig: this._grokConfig,
|
|
1638
|
+
copilotConfig: this._copilotConfig,
|
|
1588
1639
|
deepSeekConfig: this._deepSeekConfig,
|
|
1589
1640
|
ompConfig: this._ompConfig,
|
|
1590
1641
|
resumeSessionId: this._resumeSessionId,
|
|
@@ -1936,6 +1987,7 @@ export class Session extends EventEmitter {
|
|
|
1936
1987
|
antigravityConfig: this._antigravityConfig,
|
|
1937
1988
|
piConfig: this._piConfig,
|
|
1938
1989
|
grokConfig: this._grokConfig,
|
|
1990
|
+
copilotConfig: this._copilotConfig,
|
|
1939
1991
|
deepSeekConfig: this._deepSeekConfig,
|
|
1940
1992
|
// OMP resolution/pinning does NOT happen here. This object is built
|
|
1941
1993
|
// EAGERLY — including on every boot-recovery reattach, before anyone
|
|
@@ -2029,6 +2081,7 @@ export class Session extends EventEmitter {
|
|
|
2029
2081
|
* still inside it and renders no local `--session-id` to collide.
|
|
2030
2082
|
*/
|
|
2031
2083
|
async _buildRespawnPaneOptionsWithResumePin() {
|
|
2084
|
+
await this._refreshCliNamePin();
|
|
2032
2085
|
const options = this._buildRespawnPaneOptions();
|
|
2033
2086
|
if (this._remote || this._docker)
|
|
2034
2087
|
return options;
|
|
@@ -2293,11 +2346,13 @@ export class Session extends EventEmitter {
|
|
|
2293
2346
|
if (this._closing) {
|
|
2294
2347
|
throw new Error('Session is being closed');
|
|
2295
2348
|
}
|
|
2349
|
+
await this._refreshCliNamePin();
|
|
2296
2350
|
// Bounds the workspace-trust scan (see _maybeAcceptTrustDialog). Stamped here
|
|
2297
2351
|
// rather than at PTY spawn so a slow mux attach still counts as startup.
|
|
2298
2352
|
this._interactiveStartedAt = Date.now();
|
|
2299
2353
|
this._trustDialogAttempts = 0;
|
|
2300
2354
|
this._lastTrustDialogScanAt = 0;
|
|
2355
|
+
this._lastPaneProbeTrustDialog = false; // the last pane's verdict, not this one's
|
|
2301
2356
|
if (this._trustDialogTimer) {
|
|
2302
2357
|
clearTimeout(this._trustDialogTimer);
|
|
2303
2358
|
this._trustDialogTimer = null;
|
|
@@ -2411,6 +2466,7 @@ export class Session extends EventEmitter {
|
|
|
2411
2466
|
antigravityConfig: this._antigravityConfig,
|
|
2412
2467
|
piConfig: this._piConfig,
|
|
2413
2468
|
grokConfig: this._grokConfig,
|
|
2469
|
+
copilotConfig: this._copilotConfig,
|
|
2414
2470
|
deepSeekConfig: this._deepSeekConfig,
|
|
2415
2471
|
ompConfig: this._ompConfig,
|
|
2416
2472
|
resumeSessionId: this._resumeSessionId,
|
|
@@ -2644,6 +2700,10 @@ export class Session extends EventEmitter {
|
|
|
2644
2700
|
this._expensiveProcessTimer = null;
|
|
2645
2701
|
}
|
|
2646
2702
|
this._pendingCleanData = '';
|
|
2703
|
+
// Nothing reads this pane any more, so a dialog on it can no longer be seen to
|
|
2704
|
+
// close: drop the state (and its timer) while the listeners are still attached.
|
|
2705
|
+
// A re-attach re-reads the screen and raises it again if the dialog is still up.
|
|
2706
|
+
this._clearScreenBlocked();
|
|
2647
2707
|
// If using mux, mark the session as detached but don't kill it
|
|
2648
2708
|
if (this._muxSession && this._mux) {
|
|
2649
2709
|
this._mux.setAttached(this.id, false);
|
|
@@ -2701,15 +2761,26 @@ export class Session extends EventEmitter {
|
|
|
2701
2761
|
* a two-marker match (isTrustDialogScreen), and an attempt cap.
|
|
2702
2762
|
*/
|
|
2703
2763
|
_maybeAcceptTrustDialog() {
|
|
2704
|
-
|
|
2764
|
+
// Stopped: the kill itself produces PTY output, and the buffer tail still holds the
|
|
2765
|
+
// dialog, so without this a deleted session kept "answering" it for several seconds.
|
|
2766
|
+
if (this._trustDialogAccepted || this._isStopped)
|
|
2705
2767
|
return;
|
|
2706
2768
|
const now = Date.now();
|
|
2707
2769
|
if (now - this._interactiveStartedAt > TRUST_DIALOG_WINDOW_MS) {
|
|
2708
2770
|
this._trustDialogAccepted = true; // window closed; anything matching now is not the dialog
|
|
2709
2771
|
return;
|
|
2710
2772
|
}
|
|
2711
|
-
|
|
2773
|
+
const sinceScan = now - this._lastTrustDialogScanAt;
|
|
2774
|
+
if (sinceScan < TRUST_DIALOG_RETRY_MS) {
|
|
2775
|
+
// ⚠️ Defer a throttled read, never drop it. The dialog's own paint is usually the
|
|
2776
|
+
// last output a launching pane produces, and it tends to land inside the throttle
|
|
2777
|
+
// of the read the blank screen before it triggered: dropped, nothing re-read the
|
|
2778
|
+
// screen and the session sat on the dialog for good (2 of 12 fresh launches on
|
|
2779
|
+
// Claude Code 2.1.294). A read already scheduled covers this one.
|
|
2780
|
+
if (!this._trustDialogTimer)
|
|
2781
|
+
this._rescanTrustDialogIn(TRUST_DIALOG_RETRY_MS - sinceScan + 100);
|
|
2712
2782
|
return;
|
|
2783
|
+
}
|
|
2713
2784
|
this._lastTrustDialogScanAt = now;
|
|
2714
2785
|
// Prefer the pane; fall back to the buffer tail on a direct-PTY session,
|
|
2715
2786
|
// where there is no screen to read.
|
|
@@ -2739,15 +2810,17 @@ export class Session extends EventEmitter {
|
|
|
2739
2810
|
// on a live 2.1.252 spawn: cursor moved at 6 s, then nothing). The timer is
|
|
2740
2811
|
// one-shot and self-rearming through this same path, and every exit route
|
|
2741
2812
|
// goes through _clearAllTimers().
|
|
2742
|
-
// The +100ms puts the re-entry OUTSIDE the scan throttle above
|
|
2743
|
-
|
|
2744
|
-
|
|
2813
|
+
// The +100ms puts the re-entry OUTSIDE the scan throttle above.
|
|
2814
|
+
this._rescanTrustDialogIn(TRUST_DIALOG_RETRY_MS + 100);
|
|
2815
|
+
}
|
|
2816
|
+
/** Re-run the trust-dialog scan after `delayMs`, replacing any read already scheduled. */
|
|
2817
|
+
_rescanTrustDialogIn(delayMs) {
|
|
2745
2818
|
if (this._trustDialogTimer)
|
|
2746
2819
|
clearTimeout(this._trustDialogTimer);
|
|
2747
2820
|
this._trustDialogTimer = setTimeout(() => {
|
|
2748
2821
|
this._trustDialogTimer = null;
|
|
2749
2822
|
this._maybeAcceptTrustDialog();
|
|
2750
|
-
},
|
|
2823
|
+
}, delayMs);
|
|
2751
2824
|
}
|
|
2752
2825
|
/**
|
|
2753
2826
|
* Per-chunk working/idle detection for an interactive pane. Split out of the
|
|
@@ -2821,10 +2894,29 @@ export class Session extends EventEmitter {
|
|
|
2821
2894
|
return this._lastPaneProbeWorking;
|
|
2822
2895
|
this._lastPaneProbeAt = now;
|
|
2823
2896
|
const text = this._mux.capturePaneText?.(this._muxSession.muxName) ?? null;
|
|
2897
|
+
// A dialog the CLI is blocked on is not work, whatever else is on screen: codex's
|
|
2898
|
+
// question dialog carries `esc to interrupt` in its own key hints, which is codex's
|
|
2899
|
+
// working line, so without this a session waiting on the user's answer read as busy.
|
|
2900
|
+
// Decided from THIS capture, never from `_screenBlocked`, which lags a vanished dialog
|
|
2901
|
+
// by design (see `_noteBlockedReading`) and would otherwise call a resumed turn idle.
|
|
2902
|
+
const blockedOnScreen = text === null ? null : this._paneShowsBlocked(text);
|
|
2903
|
+
this._noteBlockedReading(blockedOnScreen, text);
|
|
2824
2904
|
// A turn that ended by handing off to workers the CLI waits for is work too: the
|
|
2825
2905
|
// composer is up and the pane is quiet, but the next turn starts without the user.
|
|
2826
2906
|
this._lastPaneProbeWorking =
|
|
2827
|
-
text === null
|
|
2907
|
+
text === null
|
|
2908
|
+
? null
|
|
2909
|
+
: !blockedOnScreen && (this._workingLinePattern().test(text) || this._paneAwaitsWorkers(text));
|
|
2910
|
+
// A capture that failed proves nothing either way, so it keeps the last answer.
|
|
2911
|
+
if (text !== null) {
|
|
2912
|
+
const trustDialog = isTrustDialogScreen(text);
|
|
2913
|
+
if (trustDialog &&
|
|
2914
|
+
!this._lastPaneProbeTrustDialog &&
|
|
2915
|
+
now - this._interactiveStartedAt <= TRUST_DIALOG_WINDOW_MS) {
|
|
2916
|
+
console.log(`[Session] Holding idle while the workspace trust dialog is on screen: ${this.id}`);
|
|
2917
|
+
}
|
|
2918
|
+
this._lastPaneProbeTrustDialog = trustDialog;
|
|
2919
|
+
}
|
|
2828
2920
|
this._readWatching(text);
|
|
2829
2921
|
this._readScreenModel(text);
|
|
2830
2922
|
return this._lastPaneProbeWorking;
|
|
@@ -2913,6 +3005,7 @@ export class Session extends EventEmitter {
|
|
|
2913
3005
|
antigravityConfig: this._antigravityConfig,
|
|
2914
3006
|
piConfig: this._piConfig,
|
|
2915
3007
|
grokConfig: this._grokConfig,
|
|
3008
|
+
copilotConfig: this._copilotConfig,
|
|
2916
3009
|
deepSeekConfig: this._deepSeekConfig,
|
|
2917
3010
|
ompConfig: this._ompConfig,
|
|
2918
3011
|
};
|
|
@@ -3016,6 +3109,109 @@ export class Session extends EventEmitter {
|
|
|
3016
3109
|
const glyph = getCli(this.mode)?.capabilities.workDetect?.promptGlyph ?? '❯';
|
|
3017
3110
|
return isAwaitingWorkers(paneText, this._awaitingLineRe, glyph);
|
|
3018
3111
|
}
|
|
3112
|
+
/**
|
|
3113
|
+
* The regex matching the dialog this CLI blocks on, or null for a CLI whose registry
|
|
3114
|
+
* entry declares none (every CLI but codex today, Claude included: its dialogs arrive
|
|
3115
|
+
* as hook events). Compiled once per session through `compileVersionRegex()`, the same
|
|
3116
|
+
* guard the schema applies, so a pattern it refuses yields null rather than a throw.
|
|
3117
|
+
*/
|
|
3118
|
+
_blockedLinePattern() {
|
|
3119
|
+
if (this._blockedLineRe === undefined) {
|
|
3120
|
+
const detect = getCli(this.mode)?.capabilities.workDetect;
|
|
3121
|
+
this._blockedLineRe = detect?.blockedLine ? compileVersionRegex(detect.blockedLine) : null;
|
|
3122
|
+
this._blockedWindow = detect?.blockedLines ?? BLOCKED_TAIL_LINES;
|
|
3123
|
+
}
|
|
3124
|
+
return this._blockedLineRe;
|
|
3125
|
+
}
|
|
3126
|
+
/** Whether this capture shows a dialog the CLI is blocked on. See `isBlockedScreen()`. */
|
|
3127
|
+
_paneShowsBlocked(paneText) {
|
|
3128
|
+
const pattern = this._blockedLinePattern();
|
|
3129
|
+
return pattern ? isBlockedScreen(paneText, pattern, this._blockedWindow) : false;
|
|
3130
|
+
}
|
|
3131
|
+
/**
|
|
3132
|
+
* Fold one screen reading into the blocked state, announcing each transition with
|
|
3133
|
+
* `blockedChanged` (the web server turns it into the alert and the `blocked` signal).
|
|
3134
|
+
*
|
|
3135
|
+
* The two directions are deliberately unequal:
|
|
3136
|
+
* - RAISE on one reading. A match needs the dialog's own footer at the foot of the
|
|
3137
|
+
* screen, which is only there when the dialog is fully drawn.
|
|
3138
|
+
* - CLEAR on BLOCKED_CLEAR_READS readings in a row. A single capture can land inside a
|
|
3139
|
+
* full-frame repaint, and clearing on it would re-raise a moment later and send the
|
|
3140
|
+
* alert, push and webhook twice for one dialog.
|
|
3141
|
+
* A capture that could not be read (`null`) is no evidence either way and changes
|
|
3142
|
+
* nothing, so a tmux hiccup can neither raise nor drop an alert. That is the opposite
|
|
3143
|
+
* of `_readWatching`, and for the same reason: each degrades toward the alert.
|
|
3144
|
+
*
|
|
3145
|
+
* While blocked, `_blockedRecheckTimer` keeps reading, since answering resumes the turn
|
|
3146
|
+
* and a busy pane never reaches the settle path that raised it.
|
|
3147
|
+
*
|
|
3148
|
+
* @param frame the capture the reading came from; rides the raise as the alert's context
|
|
3149
|
+
*/
|
|
3150
|
+
_noteBlockedReading(onScreen, frame) {
|
|
3151
|
+
if (onScreen === null || !this._blockedLinePattern())
|
|
3152
|
+
return;
|
|
3153
|
+
if (onScreen) {
|
|
3154
|
+
this._blockedGoneReads = 0;
|
|
3155
|
+
// Stamped after the capture returned: output processed later is newer than it.
|
|
3156
|
+
this._blockedSeenAt = Date.now();
|
|
3157
|
+
if (!this._screenBlocked) {
|
|
3158
|
+
this._screenBlocked = true;
|
|
3159
|
+
this.emit('blockedChanged', true, frame);
|
|
3160
|
+
}
|
|
3161
|
+
this._armBlockedRecheck();
|
|
3162
|
+
return;
|
|
3163
|
+
}
|
|
3164
|
+
if (!this._screenBlocked)
|
|
3165
|
+
return;
|
|
3166
|
+
if (++this._blockedGoneReads < BLOCKED_CLEAR_READS) {
|
|
3167
|
+
this._armBlockedRecheck();
|
|
3168
|
+
return;
|
|
3169
|
+
}
|
|
3170
|
+
this._clearScreenBlocked();
|
|
3171
|
+
}
|
|
3172
|
+
/** (Re)arm the while-blocked screen read. One-shot and self-rearming, like the trust scan. */
|
|
3173
|
+
_armBlockedRecheck() {
|
|
3174
|
+
if (this._blockedRecheckTimer)
|
|
3175
|
+
clearTimeout(this._blockedRecheckTimer);
|
|
3176
|
+
this._blockedRecheckTimer = setTimeout(() => {
|
|
3177
|
+
this._blockedRecheckTimer = null;
|
|
3178
|
+
// No pane left to read (detached): nothing can change until a re-attach, whose
|
|
3179
|
+
// `_resetBuffers()` clears the state and whose repaint reads the screen afresh.
|
|
3180
|
+
if (this._isStopped || !this._screenBlocked || !this._mux?.capturePaneText || !this._muxSession)
|
|
3181
|
+
return;
|
|
3182
|
+
// A dialog leaves the screen only through a repaint, and tmux sends every repaint
|
|
3183
|
+
// to this client as PTY output (`_markActivity`). So while the last reading saw
|
|
3184
|
+
// the dialog and nothing has been drawn since, it is still up: skip the capture
|
|
3185
|
+
// (synchronous, see BLOCKED_QUIET_RECHECK_MS) and look again next interval. Never
|
|
3186
|
+
// once a reading has missed it: the confirming read must happen on a quiet pane
|
|
3187
|
+
// too, or the clear would wait for output that may never come.
|
|
3188
|
+
if (this._blockedGoneReads === 0 &&
|
|
3189
|
+
this._lastActivityAt < this._blockedSeenAt &&
|
|
3190
|
+
Date.now() - this._blockedSeenAt < BLOCKED_QUIET_RECHECK_MS) {
|
|
3191
|
+
this._armBlockedRecheck();
|
|
3192
|
+
return;
|
|
3193
|
+
}
|
|
3194
|
+
const text = this._mux.capturePaneText(this._muxSession.muxName) ?? null;
|
|
3195
|
+
// Unreadable this time: keep the state, keep looking (_noteBlockedReading ignores a null).
|
|
3196
|
+
if (text === null) {
|
|
3197
|
+
this._armBlockedRecheck();
|
|
3198
|
+
return;
|
|
3199
|
+
}
|
|
3200
|
+
this._noteBlockedReading(this._paneShowsBlocked(text), text);
|
|
3201
|
+
}, BLOCKED_RECHECK_MS);
|
|
3202
|
+
}
|
|
3203
|
+
/** Drop the blocked state (and its timer), announcing it when it was set. */
|
|
3204
|
+
_clearScreenBlocked() {
|
|
3205
|
+
this._blockedGoneReads = 0;
|
|
3206
|
+
if (this._blockedRecheckTimer) {
|
|
3207
|
+
clearTimeout(this._blockedRecheckTimer);
|
|
3208
|
+
this._blockedRecheckTimer = null;
|
|
3209
|
+
}
|
|
3210
|
+
if (!this._screenBlocked)
|
|
3211
|
+
return;
|
|
3212
|
+
this._screenBlocked = false;
|
|
3213
|
+
this.emit('blockedChanged', false, null);
|
|
3214
|
+
}
|
|
3019
3215
|
/**
|
|
3020
3216
|
* The regex matching this CLI's "a turn is running" status line.
|
|
3021
3217
|
*
|
|
@@ -3076,6 +3272,16 @@ export class Session extends EventEmitter {
|
|
|
3076
3272
|
this.activityTimeout = setTimeout(() => this._confirmIdle(), PANE_PROBE_RECHECK_MS);
|
|
3077
3273
|
return;
|
|
3078
3274
|
}
|
|
3275
|
+
// ⚠️ The workspace-trust dialog is not a composer, although its `❯` (on "No, exit")
|
|
3276
|
+
// arms this check and the dialog sits quiet. Calling it idle let an agent that waited
|
|
3277
|
+
// for idle send its prompt into the dialog, and the prompt's Enter answered *exit*.
|
|
3278
|
+
// Not working either, so the status stays where it is until the dialog is gone.
|
|
3279
|
+
// Bounded by the auto-accept's own startup window: later on, a screen that merely
|
|
3280
|
+
// quotes the dialog (an agent reading session-trust-dialog.ts) must not hold idle off.
|
|
3281
|
+
if (this._lastPaneProbeTrustDialog && Date.now() - this._interactiveStartedAt <= TRUST_DIALOG_WINDOW_MS) {
|
|
3282
|
+
this.activityTimeout = setTimeout(() => this._confirmIdle(), PANE_PROBE_RECHECK_MS);
|
|
3283
|
+
return;
|
|
3284
|
+
}
|
|
3079
3285
|
this._awaitingIdleConfirmation = false;
|
|
3080
3286
|
this.activityTimeout = null;
|
|
3081
3287
|
// Emit idle if either:
|
|
@@ -3515,6 +3721,9 @@ export class Session extends EventEmitter {
|
|
|
3515
3721
|
// into a program that never enabled tracking.
|
|
3516
3722
|
this._cliMouseModes.clear();
|
|
3517
3723
|
this._syncCliMouseTracking();
|
|
3724
|
+
// Nor does it start inside a dialog. Announced, so a pending alert for the old
|
|
3725
|
+
// pane's dialog is resolved rather than left behind it.
|
|
3726
|
+
this._clearScreenBlocked();
|
|
3518
3727
|
this._markActivity(true);
|
|
3519
3728
|
}
|
|
3520
3729
|
_clearAllTimers() {
|
|
@@ -3526,6 +3735,11 @@ export class Session extends EventEmitter {
|
|
|
3526
3735
|
clearTimeout(this._trustDialogTimer);
|
|
3527
3736
|
this._trustDialogTimer = null;
|
|
3528
3737
|
}
|
|
3738
|
+
// Clear the while-blocked screen read (the state itself is left to its owner)
|
|
3739
|
+
if (this._blockedRecheckTimer) {
|
|
3740
|
+
clearTimeout(this._blockedRecheckTimer);
|
|
3741
|
+
this._blockedRecheckTimer = null;
|
|
3742
|
+
}
|
|
3529
3743
|
// Clear activity timeout to prevent memory leak
|
|
3530
3744
|
if (this.activityTimeout) {
|
|
3531
3745
|
clearTimeout(this.activityTimeout);
|
|
@@ -3981,7 +4195,7 @@ export class Session extends EventEmitter {
|
|
|
3981
4195
|
*
|
|
3982
4196
|
* More reliable than direct PTY write for programmatic input, especially
|
|
3983
4197
|
* with Claude CLI which uses Ink (React for terminals).
|
|
3984
|
-
* Uses tmux
|
|
4198
|
+
* Uses tmux to inject the text (one bracketed paste) + Enter.
|
|
3985
4199
|
*
|
|
3986
4200
|
* @param data - Input data with optional `\r` for Enter
|
|
3987
4201
|
* @returns true if input was sent, false if no mux session or PTY
|
|
@@ -4037,7 +4251,7 @@ export class Session extends EventEmitter {
|
|
|
4037
4251
|
: this._mux.capturePaneText?.(this._muxSession.muxName),
|
|
4038
4252
|
sendEnter: () => this._mux?.sendInput(this.id, '\r'),
|
|
4039
4253
|
// ⚠ NO fallback glyph here, unlike the screen-reading probe elsewhere in this file.
|
|
4040
|
-
// Only claude, codex, pi, opencode, omp and
|
|
4254
|
+
// Only claude, codex, pi, opencode, omp, gemini and antigravity declare a promptGlyph; the other modes would fall back
|
|
4041
4255
|
// to claude's `❯`, which is ALSO starship's default shell prompt (and pure's, and
|
|
4042
4256
|
// spaceship's, and p10k lean's). On a shell session the line `❯ npm run build` sits
|
|
4043
4257
|
// on screen for as long as the command runs, promptStillInComposer() reads that as
|