aicodeman 0.2.9 → 0.3.1
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 +118 -4
- package/dist/ai-idle-checker.d.ts.map +1 -1
- package/dist/ai-idle-checker.js +3 -2
- package/dist/ai-idle-checker.js.map +1 -1
- package/dist/ai-plan-checker.d.ts.map +1 -1
- package/dist/ai-plan-checker.js +3 -2
- package/dist/ai-plan-checker.js.map +1 -1
- package/dist/bash-tool-parser.d.ts +2 -3
- package/dist/bash-tool-parser.d.ts.map +1 -1
- package/dist/bash-tool-parser.js +14 -31
- package/dist/bash-tool-parser.js.map +1 -1
- package/dist/config/ai-defaults.d.ts +16 -0
- package/dist/config/ai-defaults.d.ts.map +1 -0
- package/dist/config/ai-defaults.js +16 -0
- package/dist/config/ai-defaults.js.map +1 -0
- package/dist/config/auth-config.d.ts +19 -0
- package/dist/config/auth-config.d.ts.map +1 -0
- package/dist/config/auth-config.js +28 -0
- package/dist/config/auth-config.js.map +1 -0
- package/dist/config/exec-timeout.d.ts +10 -0
- package/dist/config/exec-timeout.d.ts.map +1 -0
- package/dist/config/exec-timeout.js +10 -0
- package/dist/config/exec-timeout.js.map +1 -0
- package/dist/config/map-limits.d.ts +4 -0
- package/dist/config/map-limits.d.ts.map +1 -1
- package/dist/config/map-limits.js +7 -0
- package/dist/config/map-limits.js.map +1 -1
- package/dist/config/server-timing.d.ts +42 -0
- package/dist/config/server-timing.d.ts.map +1 -0
- package/dist/config/server-timing.js +57 -0
- package/dist/config/server-timing.js.map +1 -0
- package/dist/config/team-config.d.ts +16 -0
- package/dist/config/team-config.d.ts.map +1 -0
- package/dist/config/team-config.js +16 -0
- package/dist/config/team-config.js.map +1 -0
- package/dist/config/terminal-limits.d.ts +18 -0
- package/dist/config/terminal-limits.d.ts.map +1 -0
- package/dist/config/terminal-limits.js +18 -0
- package/dist/config/terminal-limits.js.map +1 -0
- package/dist/config/tunnel-config.d.ts +27 -0
- package/dist/config/tunnel-config.d.ts.map +1 -0
- package/dist/config/tunnel-config.js +36 -0
- package/dist/config/tunnel-config.js.map +1 -0
- package/dist/hooks-config.d.ts +21 -6
- package/dist/hooks-config.d.ts.map +1 -1
- package/dist/hooks-config.js +28 -12
- package/dist/hooks-config.js.map +1 -1
- package/dist/image-watcher.d.ts +4 -4
- package/dist/image-watcher.d.ts.map +1 -1
- package/dist/image-watcher.js +17 -30
- package/dist/image-watcher.js.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/plan-orchestrator.d.ts +2 -24
- package/dist/plan-orchestrator.d.ts.map +1 -1
- package/dist/plan-orchestrator.js.map +1 -1
- package/dist/prompts/planner.d.ts +7 -8
- package/dist/prompts/planner.d.ts.map +1 -1
- package/dist/prompts/planner.js +7 -8
- package/dist/prompts/planner.js.map +1 -1
- package/dist/prompts/research-agent.d.ts +6 -4
- package/dist/prompts/research-agent.d.ts.map +1 -1
- package/dist/prompts/research-agent.js +6 -4
- package/dist/prompts/research-agent.js.map +1 -1
- package/dist/push-store.d.ts +1 -1
- package/dist/push-store.d.ts.map +1 -1
- package/dist/push-store.js +4 -12
- package/dist/push-store.js.map +1 -1
- package/dist/ralph-fix-plan-watcher.d.ts +91 -0
- package/dist/ralph-fix-plan-watcher.d.ts.map +1 -0
- package/dist/ralph-fix-plan-watcher.js +326 -0
- package/dist/ralph-fix-plan-watcher.js.map +1 -0
- package/dist/ralph-loop.d.ts +14 -4
- package/dist/ralph-loop.d.ts.map +1 -1
- package/dist/ralph-loop.js +14 -4
- package/dist/ralph-loop.js.map +1 -1
- package/dist/ralph-plan-tracker.d.ts +201 -0
- package/dist/ralph-plan-tracker.d.ts.map +1 -0
- package/dist/ralph-plan-tracker.js +325 -0
- package/dist/ralph-plan-tracker.js.map +1 -0
- package/dist/ralph-stall-detector.d.ts +84 -0
- package/dist/ralph-stall-detector.d.ts.map +1 -0
- package/dist/ralph-stall-detector.js +139 -0
- package/dist/ralph-stall-detector.js.map +1 -0
- package/dist/ralph-status-parser.d.ts +141 -0
- package/dist/ralph-status-parser.d.ts.map +1 -0
- package/dist/ralph-status-parser.js +478 -0
- package/dist/ralph-status-parser.js.map +1 -0
- package/dist/ralph-tracker.d.ts +218 -692
- package/dist/ralph-tracker.d.ts.map +1 -1
- package/dist/ralph-tracker.js +389 -1723
- package/dist/ralph-tracker.js.map +1 -1
- package/dist/respawn-adaptive-timing.d.ts +61 -0
- package/dist/respawn-adaptive-timing.d.ts.map +1 -0
- package/dist/respawn-adaptive-timing.js +105 -0
- package/dist/respawn-adaptive-timing.js.map +1 -0
- package/dist/respawn-controller.d.ts +35 -115
- package/dist/respawn-controller.d.ts.map +1 -1
- package/dist/respawn-controller.js +167 -607
- package/dist/respawn-controller.js.map +1 -1
- package/dist/respawn-health.d.ts +54 -0
- package/dist/respawn-health.d.ts.map +1 -0
- package/dist/respawn-health.js +183 -0
- package/dist/respawn-health.js.map +1 -0
- package/dist/respawn-metrics.d.ts +81 -0
- package/dist/respawn-metrics.d.ts.map +1 -0
- package/dist/respawn-metrics.js +198 -0
- package/dist/respawn-metrics.js.map +1 -0
- package/dist/respawn-patterns.d.ts +45 -0
- package/dist/respawn-patterns.d.ts.map +1 -0
- package/dist/respawn-patterns.js +125 -0
- package/dist/respawn-patterns.js.map +1 -0
- package/dist/session-auto-ops.d.ts +89 -0
- package/dist/session-auto-ops.d.ts.map +1 -0
- package/dist/session-auto-ops.js +224 -0
- package/dist/session-auto-ops.js.map +1 -0
- package/dist/session-cli-builder.d.ts +62 -0
- package/dist/session-cli-builder.d.ts.map +1 -0
- package/dist/session-cli-builder.js +121 -0
- package/dist/session-cli-builder.js.map +1 -0
- package/dist/session-manager.d.ts +17 -5
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +17 -5
- package/dist/session-manager.js.map +1 -1
- package/dist/session-task-cache.d.ts +52 -0
- package/dist/session-task-cache.d.ts.map +1 -0
- package/dist/session-task-cache.js +90 -0
- package/dist/session-task-cache.js.map +1 -0
- package/dist/session.d.ts +23 -41
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +79 -317
- package/dist/session.js.map +1 -1
- package/dist/state-store.d.ts +19 -9
- package/dist/state-store.d.ts.map +1 -1
- package/dist/state-store.js +29 -30
- package/dist/state-store.js.map +1 -1
- package/dist/subagent-watcher.d.ts +26 -7
- package/dist/subagent-watcher.d.ts.map +1 -1
- package/dist/subagent-watcher.js +47 -64
- package/dist/subagent-watcher.js.map +1 -1
- package/dist/team-watcher.d.ts.map +1 -1
- package/dist/team-watcher.js +2 -5
- package/dist/team-watcher.js.map +1 -1
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +1 -2
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tunnel-manager.d.ts +26 -0
- package/dist/tunnel-manager.d.ts.map +1 -1
- package/dist/tunnel-manager.js +126 -7
- package/dist/tunnel-manager.js.map +1 -1
- package/dist/types/api.d.ts +108 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +98 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/app-state.d.ts +117 -0
- package/dist/types/app-state.d.ts.map +1 -0
- package/dist/types/app-state.js +76 -0
- package/dist/types/app-state.js.map +1 -0
- package/dist/types/common.d.ts +79 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +17 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/index.d.ts +66 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +66 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lifecycle.d.ts +28 -0
- package/dist/types/lifecycle.d.ts.map +1 -0
- package/dist/types/lifecycle.js +16 -0
- package/dist/types/lifecycle.js.map +1 -0
- package/dist/types/plan.d.ts +45 -0
- package/dist/types/plan.d.ts.map +1 -0
- package/dist/types/plan.js +18 -0
- package/dist/types/plan.js.map +1 -0
- package/dist/types/push.d.ts +36 -0
- package/dist/types/push.d.ts.map +1 -0
- package/dist/types/push.js +18 -0
- package/dist/types/push.js.map +1 -0
- package/dist/types/ralph.d.ts +262 -0
- package/dist/types/ralph.d.ts.map +1 -0
- package/dist/types/ralph.js +70 -0
- package/dist/types/ralph.js.map +1 -0
- package/dist/types/respawn.d.ts +271 -0
- package/dist/types/respawn.d.ts.map +1 -0
- package/dist/types/respawn.js +26 -0
- package/dist/types/respawn.js.map +1 -0
- package/dist/types/run-summary.d.ts +96 -0
- package/dist/types/run-summary.d.ts.map +1 -0
- package/dist/types/run-summary.js +37 -0
- package/dist/types/run-summary.js.map +1 -0
- package/dist/types/session.d.ts +152 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +27 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/task.d.ts +72 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +19 -0
- package/dist/types/task.js.map +1 -0
- package/dist/types/teams.d.ts +73 -0
- package/dist/types/teams.d.ts.map +1 -0
- package/dist/types/teams.js +23 -0
- package/dist/types/teams.js.map +1 -0
- package/dist/types/tools.d.ts +61 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +20 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types.d.ts +8 -1134
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -210
- package/dist/types.js.map +1 -1
- package/dist/utils/claude-cli-resolver.d.ts.map +1 -1
- package/dist/utils/claude-cli-resolver.js +1 -2
- package/dist/utils/claude-cli-resolver.js.map +1 -1
- package/dist/utils/debouncer.d.ts +111 -0
- package/dist/utils/debouncer.d.ts.map +1 -0
- package/dist/utils/debouncer.js +162 -0
- package/dist/utils/debouncer.js.map +1 -0
- package/dist/utils/index.d.ts +3 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/opencode-cli-resolver.d.ts.map +1 -1
- package/dist/utils/opencode-cli-resolver.js +1 -2
- package/dist/utils/opencode-cli-resolver.js.map +1 -1
- package/dist/utils/string-similarity.d.ts +0 -57
- package/dist/utils/string-similarity.d.ts.map +1 -1
- package/dist/utils/string-similarity.js +3 -18
- package/dist/utils/string-similarity.js.map +1 -1
- package/dist/web/middleware/auth.d.ts +31 -0
- package/dist/web/middleware/auth.d.ts.map +1 -0
- package/dist/web/middleware/auth.js +154 -0
- package/dist/web/middleware/auth.js.map +1 -0
- package/dist/web/ports/auth-port.d.ts +18 -0
- package/dist/web/ports/auth-port.d.ts.map +1 -0
- package/dist/web/ports/auth-port.js +6 -0
- package/dist/web/ports/auth-port.js.map +1 -0
- package/dist/web/ports/config-port.d.ts +28 -0
- package/dist/web/ports/config-port.d.ts.map +1 -0
- package/dist/web/ports/config-port.js +6 -0
- package/dist/web/ports/config-port.js.map +1 -0
- package/dist/web/ports/event-port.d.ts +13 -0
- package/dist/web/ports/event-port.d.ts.map +1 -0
- package/dist/web/ports/event-port.js +6 -0
- package/dist/web/ports/event-port.js.map +1 -0
- package/dist/web/ports/index.d.ts +14 -0
- package/dist/web/ports/index.d.ts.map +1 -0
- package/dist/web/ports/index.js +9 -0
- package/dist/web/ports/index.js.map +1 -0
- package/dist/web/ports/infra-port.d.ts +36 -0
- package/dist/web/ports/infra-port.d.ts.map +1 -0
- package/dist/web/ports/infra-port.js +6 -0
- package/dist/web/ports/infra-port.js.map +1 -0
- package/dist/web/ports/respawn-port.d.ts +20 -0
- package/dist/web/ports/respawn-port.d.ts.map +1 -0
- package/dist/web/ports/respawn-port.js +6 -0
- package/dist/web/ports/respawn-port.js.map +1 -0
- package/dist/web/ports/session-port.d.ts +15 -0
- package/dist/web/ports/session-port.d.ts.map +1 -0
- package/dist/web/ports/session-port.js +6 -0
- package/dist/web/ports/session-port.js.map +1 -0
- package/dist/web/public/api-client.js +82 -0
- package/dist/web/public/api-client.js.br +0 -0
- package/dist/web/public/api-client.js.gz +0 -0
- package/dist/web/public/app.js +117 -201
- package/dist/web/public/app.js.br +0 -0
- package/dist/web/public/app.js.gz +0 -0
- package/dist/web/public/constants.js +365 -0
- package/dist/web/public/constants.js.br +0 -0
- package/dist/web/public/constants.js.gz +0 -0
- package/dist/web/public/index.html +15 -3
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/keyboard-accessory.js +302 -0
- package/dist/web/public/keyboard-accessory.js.br +0 -0
- package/dist/web/public/keyboard-accessory.js.gz +0 -0
- package/dist/web/public/mobile-handlers.js +491 -0
- package/dist/web/public/mobile-handlers.js.br +0 -0
- package/dist/web/public/mobile-handlers.js.gz +0 -0
- package/dist/web/public/mobile.css.gz +0 -0
- package/dist/web/public/notification-manager.js +472 -0
- package/dist/web/public/notification-manager.js.br +0 -0
- package/dist/web/public/notification-manager.js.gz +0 -0
- package/dist/web/public/ralph-wizard.js +33 -9
- package/dist/web/public/ralph-wizard.js.br +0 -0
- package/dist/web/public/ralph-wizard.js.gz +0 -0
- package/dist/web/public/styles.css.gz +0 -0
- package/dist/web/public/subagent-windows.js +1149 -0
- package/dist/web/public/subagent-windows.js.br +0 -0
- package/dist/web/public/subagent-windows.js.gz +0 -0
- package/dist/web/public/sw.js +15 -0
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.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-zerolag-input.js +4 -0
- package/dist/web/public/vendor/xterm-zerolag-input.js.br +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.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.js +882 -0
- package/dist/web/public/voice-input.js.br +0 -0
- package/dist/web/public/voice-input.js.gz +0 -0
- package/dist/web/route-helpers.d.ts +38 -0
- package/dist/web/route-helpers.d.ts.map +1 -0
- package/dist/web/route-helpers.js +144 -0
- package/dist/web/route-helpers.js.map +1 -0
- package/dist/web/routes/case-routes.d.ts +9 -0
- package/dist/web/routes/case-routes.d.ts.map +1 -0
- package/dist/web/routes/case-routes.js +426 -0
- package/dist/web/routes/case-routes.js.map +1 -0
- package/dist/web/routes/file-routes.d.ts +8 -0
- package/dist/web/routes/file-routes.d.ts.map +1 -0
- package/dist/web/routes/file-routes.js +337 -0
- package/dist/web/routes/file-routes.js.map +1 -0
- package/dist/web/routes/hook-event-routes.d.ts +9 -0
- package/dist/web/routes/hook-event-routes.d.ts.map +1 -0
- package/dist/web/routes/hook-event-routes.js +57 -0
- package/dist/web/routes/hook-event-routes.js.map +1 -0
- package/dist/web/routes/index.d.ts +16 -0
- package/dist/web/routes/index.d.ts.map +1 -0
- package/dist/web/routes/index.js +16 -0
- package/dist/web/routes/index.js.map +1 -0
- package/dist/web/routes/mux-routes.d.ts +8 -0
- package/dist/web/routes/mux-routes.d.ts.map +1 -0
- package/dist/web/routes/mux-routes.js +32 -0
- package/dist/web/routes/mux-routes.js.map +1 -0
- package/dist/web/routes/plan-routes.d.ts +9 -0
- package/dist/web/routes/plan-routes.d.ts.map +1 -0
- package/dist/web/routes/plan-routes.js +385 -0
- package/dist/web/routes/plan-routes.js.map +1 -0
- package/dist/web/routes/push-routes.d.ts +8 -0
- package/dist/web/routes/push-routes.d.ts.map +1 -0
- package/dist/web/routes/push-routes.js +49 -0
- package/dist/web/routes/push-routes.js.map +1 -0
- package/dist/web/routes/ralph-routes.d.ts +9 -0
- package/dist/web/routes/ralph-routes.d.ts.map +1 -0
- package/dist/web/routes/ralph-routes.js +485 -0
- package/dist/web/routes/ralph-routes.js.map +1 -0
- package/dist/web/routes/respawn-routes.d.ts +8 -0
- package/dist/web/routes/respawn-routes.d.ts.map +1 -0
- package/dist/web/routes/respawn-routes.js +270 -0
- package/dist/web/routes/respawn-routes.js.map +1 -0
- package/dist/web/routes/scheduled-routes.d.ts +8 -0
- package/dist/web/routes/scheduled-routes.d.ts.map +1 -0
- package/dist/web/routes/scheduled-routes.js +51 -0
- package/dist/web/routes/scheduled-routes.js.map +1 -0
- package/dist/web/routes/session-routes.d.ts +9 -0
- package/dist/web/routes/session-routes.d.ts.map +1 -0
- package/dist/web/routes/session-routes.js +751 -0
- package/dist/web/routes/session-routes.js.map +1 -0
- package/dist/web/routes/system-routes.d.ts +9 -0
- package/dist/web/routes/system-routes.d.ts.map +1 -0
- package/dist/web/routes/system-routes.js +699 -0
- package/dist/web/routes/system-routes.js.map +1 -0
- package/dist/web/routes/team-routes.d.ts +8 -0
- package/dist/web/routes/team-routes.d.ts.map +1 -0
- package/dist/web/routes/team-routes.js +14 -0
- package/dist/web/routes/team-routes.js.map +1 -0
- package/dist/web/schemas.d.ts +43 -3
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +6 -2
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/server.d.ts +35 -15
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +563 -3971
- package/dist/web/server.js.map +1 -1
- package/dist/web/sse-events.d.ts +361 -0
- package/dist/web/sse-events.d.ts.map +1 -0
- package/dist/web/sse-events.js +396 -0
- package/dist/web/sse-events.js.map +1 -0
- package/package.json +2 -1
- package/scripts/postinstall.js +58 -0
package/dist/session.js
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Core PTY session wrapper for Claude CLI interactions.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Manages a PTY (pseudo-terminal) process running Claude CLI or OpenCode CLI.
|
|
5
|
+
* Three operation modes:
|
|
6
|
+
* 1. **One-shot** (`runPrompt`): Single prompt → JSON response
|
|
7
|
+
* 2. **Interactive** (`startInteractive`): Persistent interactive session
|
|
8
|
+
* 3. **Shell** (`startShell`): Plain bash shell for debugging
|
|
6
9
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* 3. **Shell mode**: Run a plain bash shell for debugging/testing
|
|
10
|
+
* Optionally wraps in a tmux session for persistence across disconnects.
|
|
11
|
+
* Tracks tokens, costs, background tasks, and auto-compact/clear.
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* Key exports:
|
|
14
|
+
* - `Session` class — main entity, extends EventEmitter
|
|
15
|
+
* - `ClaudeMessage` interface — parsed JSON messages from Claude output
|
|
16
|
+
* - `SessionEvents` interface — typed event map
|
|
17
|
+
*
|
|
18
|
+
* Key methods: `runPrompt()`, `startInteractive()`, `startShell()`,
|
|
19
|
+
* `writeViaMux()`, `toState()`, `stop()`, `resize()`, `isIdle()`,
|
|
20
|
+
* `setAutoCompact()`, `findTaskDescriptionNear()`, `getTerminalBuffer()`
|
|
21
|
+
*
|
|
22
|
+
* @dependencies session-cli-builder (args/env), session-auto-ops (auto-compact/clear),
|
|
23
|
+
* ralph-tracker (todo/completion parsing), bash-tool-parser (tool invocation tracking),
|
|
24
|
+
* task-tracker (background tasks), mux-interface (tmux abstraction)
|
|
25
|
+
* @consumedby session-manager, web/server, respawn-controller
|
|
26
|
+
* @emits session:terminal, session:idle, session:working, session:completion, session:exit
|
|
14
27
|
*
|
|
15
28
|
* @module session
|
|
16
29
|
*/
|
|
@@ -22,9 +35,11 @@ import { TaskTracker } from './task-tracker.js';
|
|
|
22
35
|
import { RalphTracker } from './ralph-tracker.js';
|
|
23
36
|
import { BashToolParser } from './bash-tool-parser.js';
|
|
24
37
|
import { BufferAccumulator } from './utils/buffer-accumulator.js';
|
|
25
|
-
import { LRUMap } from './utils/lru-map.js';
|
|
26
38
|
import { ANSI_ESCAPE_PATTERN_FULL, TOKEN_PATTERN, SPINNER_PATTERN, MAX_SESSION_TOKENS } from './utils/index.js';
|
|
27
39
|
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';
|
|
40
|
+
import { buildInteractiveArgs, buildPromptArgs, buildClaudeEnv, buildMuxAttachEnv, buildShellEnv, } from './session-cli-builder.js';
|
|
41
|
+
import { SessionAutoOps } from './session-auto-ops.js';
|
|
42
|
+
import { SessionTaskCache } from './session-task-cache.js';
|
|
28
43
|
/** Line buffer flush interval (100ms) - forces processing of partial lines */
|
|
29
44
|
const LINE_BUFFER_FLUSH_INTERVAL = 100;
|
|
30
45
|
// ============================================================================
|
|
@@ -34,10 +49,7 @@ const LINE_BUFFER_FLUSH_INTERVAL = 100;
|
|
|
34
49
|
const MUX_STARTUP_DELAY_MS = 300;
|
|
35
50
|
/** Delay before declaring session idle after last output (2 seconds) */
|
|
36
51
|
const IDLE_DETECTION_DELAY_MS = 2000;
|
|
37
|
-
|
|
38
|
-
const AUTO_RETRY_DELAY_MS = 2000;
|
|
39
|
-
/** Delay for auto-compact/clear initial check (1 second) */
|
|
40
|
-
const AUTO_INITIAL_DELAY_MS = 1000;
|
|
52
|
+
// Note: Auto-compact/clear timing constants moved to session-auto-ops.ts
|
|
41
53
|
/** Graceful shutdown delay when stopping session (100ms) */
|
|
42
54
|
const GRACEFUL_SHUTDOWN_DELAY_MS = 100;
|
|
43
55
|
// Filter out terminal focus escape sequences (focus in/out reports)
|
|
@@ -58,8 +70,6 @@ const LEADING_ANSI_WHITESPACE_PATTERN = /^(\x1b\[\??[\d;]*[A-Za-z]|[\s\r\n])+/;
|
|
|
58
70
|
const CTRL_L_PATTERN = /\x0c/g;
|
|
59
71
|
/** Pattern to split by newlines (CR or LF) */
|
|
60
72
|
const NEWLINE_SPLIT_PATTERN = /\r?\n/;
|
|
61
|
-
// Claude CLI PATH resolution — shared utility
|
|
62
|
-
import { getAugmentedPath } from './utils/claude-cli-resolver.js';
|
|
63
73
|
/**
|
|
64
74
|
* Core session class that wraps a PTY process running Claude CLI or a shell.
|
|
65
75
|
*
|
|
@@ -96,9 +106,8 @@ export class Session extends EventEmitter {
|
|
|
96
106
|
workingDir;
|
|
97
107
|
createdAt;
|
|
98
108
|
mode;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
static TASK_DESCRIPTION_MAX_AGE_MS = 30000; // Keep descriptions for 30 seconds
|
|
109
|
+
// Task description cache (extracted to SessionTaskCache)
|
|
110
|
+
_taskCache = new SessionTaskCache();
|
|
102
111
|
_name;
|
|
103
112
|
ptyProcess = null;
|
|
104
113
|
_pid = null;
|
|
@@ -125,14 +134,8 @@ export class Session extends EventEmitter {
|
|
|
125
134
|
// Token tracking for auto-clear
|
|
126
135
|
_totalInputTokens = 0;
|
|
127
136
|
_totalOutputTokens = 0;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
_isClearing = false; // Prevent recursive clearing
|
|
131
|
-
// Auto-compact settings
|
|
132
|
-
_autoCompactThreshold = 110000; // Default 110k tokens (lower than clear)
|
|
133
|
-
_autoCompactEnabled = false;
|
|
134
|
-
_autoCompactPrompt = ''; // Optional prompt for compact
|
|
135
|
-
_isCompacting = false; // Prevent recursive compacting
|
|
137
|
+
// Auto-compact/auto-clear automation (extracted to SessionAutoOps)
|
|
138
|
+
_autoOps;
|
|
136
139
|
// Image watcher setting (per-session toggle)
|
|
137
140
|
_imageWatcherEnabled = false;
|
|
138
141
|
// Flicker filter setting (per-session toggle, applied on frontend)
|
|
@@ -144,8 +147,6 @@ export class Session extends EventEmitter {
|
|
|
144
147
|
_cliLatestVersion = '';
|
|
145
148
|
_cliInfoParsed = false; // Only parse once per session
|
|
146
149
|
// Timer tracking for cleanup (prevents memory leaks)
|
|
147
|
-
_autoCompactTimer = null;
|
|
148
|
-
_autoClearTimer = null;
|
|
149
150
|
_promptCheckInterval = null;
|
|
150
151
|
_promptCheckTimeout = null;
|
|
151
152
|
_shellIdleTimer = null;
|
|
@@ -177,12 +178,7 @@ export class Session extends EventEmitter {
|
|
|
177
178
|
// Bash tool tracking (file paths for live log viewing)
|
|
178
179
|
_bashToolParser;
|
|
179
180
|
_bashToolHandlers = null;
|
|
180
|
-
// Task descriptions parsed from terminal output
|
|
181
|
-
// Used to correlate with SubagentWatcher discoveries for better window titles
|
|
182
|
-
// Uses LRUMap for automatic eviction at MAX_TASK_DESCRIPTIONS limit
|
|
183
|
-
_recentTaskDescriptions = new LRUMap({
|
|
184
|
-
maxSize: Session.MAX_TASK_DESCRIPTIONS,
|
|
185
|
-
});
|
|
181
|
+
// Task descriptions parsed from terminal output — delegated to SessionTaskCache
|
|
186
182
|
// Throttle expensive PTY processing (Ralph, bash parser, task descriptions)
|
|
187
183
|
// Accumulates clean data between processing windows to avoid running regex on every chunk
|
|
188
184
|
_lastExpensiveProcessTime = 0;
|
|
@@ -268,6 +264,21 @@ export class Session extends EventEmitter {
|
|
|
268
264
|
this._bashToolParser.on('toolStart', this._bashToolHandlers.toolStart);
|
|
269
265
|
this._bashToolParser.on('toolEnd', this._bashToolHandlers.toolEnd);
|
|
270
266
|
this._bashToolParser.on('toolsUpdate', this._bashToolHandlers.toolsUpdate);
|
|
267
|
+
// Initialize auto-compact/auto-clear automation and forward events
|
|
268
|
+
this._autoOps = new SessionAutoOps({
|
|
269
|
+
writeCommand: (cmd) => this.writeViaMux(cmd),
|
|
270
|
+
isWorking: () => this._isWorking,
|
|
271
|
+
isStopped: () => this._isStopped,
|
|
272
|
+
getTotalTokens: () => this._totalInputTokens + this._totalOutputTokens,
|
|
273
|
+
getSessionId: () => this.id,
|
|
274
|
+
});
|
|
275
|
+
this._autoOps.on('autoCompact', (data) => this.emit('autoCompact', data));
|
|
276
|
+
this._autoOps.on('autoClear', (data) => {
|
|
277
|
+
// Reset token counts on clear
|
|
278
|
+
this._totalInputTokens = 0;
|
|
279
|
+
this._totalOutputTokens = 0;
|
|
280
|
+
this.emit('autoClear', data);
|
|
281
|
+
});
|
|
271
282
|
}
|
|
272
283
|
get status() {
|
|
273
284
|
return this._status;
|
|
@@ -371,25 +382,7 @@ export class Session extends EventEmitter {
|
|
|
371
382
|
get allowedTools() {
|
|
372
383
|
return this._allowedTools;
|
|
373
384
|
}
|
|
374
|
-
|
|
375
|
-
* Build Claude CLI permission flags based on the configured mode.
|
|
376
|
-
* Returns an array of args to pass to the CLI.
|
|
377
|
-
*/
|
|
378
|
-
_buildPermissionArgs() {
|
|
379
|
-
switch (this._claudeMode) {
|
|
380
|
-
case 'dangerously-skip-permissions':
|
|
381
|
-
return ['--dangerously-skip-permissions'];
|
|
382
|
-
case 'allowedTools':
|
|
383
|
-
if (this._allowedTools) {
|
|
384
|
-
return ['--allowedTools', this._allowedTools];
|
|
385
|
-
}
|
|
386
|
-
// Fall back to normal mode if no tools specified
|
|
387
|
-
return [];
|
|
388
|
-
case 'normal':
|
|
389
|
-
default:
|
|
390
|
-
return [];
|
|
391
|
-
}
|
|
392
|
-
}
|
|
385
|
+
// Note: _buildPermissionArgs removed — now using buildInteractiveArgs from session-cli-builder.ts
|
|
393
386
|
/**
|
|
394
387
|
* Set CPU priority configuration.
|
|
395
388
|
* Note: This only affects new sessions; existing running processes won't be changed.
|
|
@@ -448,10 +441,10 @@ export class Session extends EventEmitter {
|
|
|
448
441
|
this._totalCost = totalCost;
|
|
449
442
|
}
|
|
450
443
|
get autoClearThreshold() {
|
|
451
|
-
return this.
|
|
444
|
+
return this._autoOps.autoClearThreshold;
|
|
452
445
|
}
|
|
453
446
|
get autoClearEnabled() {
|
|
454
|
-
return this.
|
|
447
|
+
return this._autoOps.autoClearEnabled;
|
|
455
448
|
}
|
|
456
449
|
get name() {
|
|
457
450
|
return this._name;
|
|
@@ -459,51 +452,20 @@ export class Session extends EventEmitter {
|
|
|
459
452
|
set name(value) {
|
|
460
453
|
this._name = value;
|
|
461
454
|
}
|
|
462
|
-
/** Minimum valid threshold for auto-clear/compact (1000 tokens) */
|
|
463
|
-
static MIN_AUTO_THRESHOLD = 1000;
|
|
464
|
-
/** Maximum valid threshold for auto-clear/compact (500k tokens) */
|
|
465
|
-
static MAX_AUTO_THRESHOLD = 500_000;
|
|
466
|
-
/** Default auto-clear threshold when invalid value provided */
|
|
467
|
-
static DEFAULT_AUTO_CLEAR_THRESHOLD = 140_000;
|
|
468
|
-
/** Default auto-compact threshold when invalid value provided */
|
|
469
|
-
static DEFAULT_AUTO_COMPACT_THRESHOLD = 110_000;
|
|
470
455
|
setAutoClear(enabled, threshold) {
|
|
471
|
-
this.
|
|
472
|
-
if (threshold !== undefined) {
|
|
473
|
-
// Validate threshold bounds
|
|
474
|
-
if (threshold < Session.MIN_AUTO_THRESHOLD || threshold > Session.MAX_AUTO_THRESHOLD) {
|
|
475
|
-
console.warn(`[Session ${this.id}] Invalid autoClear threshold ${threshold}, must be between ${Session.MIN_AUTO_THRESHOLD} and ${Session.MAX_AUTO_THRESHOLD}. Using default ${Session.DEFAULT_AUTO_CLEAR_THRESHOLD}.`);
|
|
476
|
-
this._autoClearThreshold = Session.DEFAULT_AUTO_CLEAR_THRESHOLD;
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
479
|
-
this._autoClearThreshold = threshold;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
456
|
+
this._autoOps.setAutoClear(enabled, threshold);
|
|
482
457
|
}
|
|
483
458
|
get autoCompactThreshold() {
|
|
484
|
-
return this.
|
|
459
|
+
return this._autoOps.autoCompactThreshold;
|
|
485
460
|
}
|
|
486
461
|
get autoCompactEnabled() {
|
|
487
|
-
return this.
|
|
462
|
+
return this._autoOps.autoCompactEnabled;
|
|
488
463
|
}
|
|
489
464
|
get autoCompactPrompt() {
|
|
490
|
-
return this.
|
|
465
|
+
return this._autoOps.autoCompactPrompt;
|
|
491
466
|
}
|
|
492
467
|
setAutoCompact(enabled, threshold, prompt) {
|
|
493
|
-
this.
|
|
494
|
-
if (threshold !== undefined) {
|
|
495
|
-
// Validate threshold bounds
|
|
496
|
-
if (threshold < Session.MIN_AUTO_THRESHOLD || threshold > Session.MAX_AUTO_THRESHOLD) {
|
|
497
|
-
console.warn(`[Session ${this.id}] Invalid autoCompact threshold ${threshold}, must be between ${Session.MIN_AUTO_THRESHOLD} and ${Session.MAX_AUTO_THRESHOLD}. Using default ${Session.DEFAULT_AUTO_COMPACT_THRESHOLD}.`);
|
|
498
|
-
this._autoCompactThreshold = Session.DEFAULT_AUTO_COMPACT_THRESHOLD;
|
|
499
|
-
}
|
|
500
|
-
else {
|
|
501
|
-
this._autoCompactThreshold = threshold;
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
if (prompt !== undefined) {
|
|
505
|
-
this._autoCompactPrompt = prompt;
|
|
506
|
-
}
|
|
468
|
+
this._autoOps.setAutoCompact(enabled, threshold, prompt);
|
|
507
469
|
}
|
|
508
470
|
get imageWatcherEnabled() {
|
|
509
471
|
return this._imageWatcherEnabled;
|
|
@@ -537,11 +499,11 @@ export class Session extends EventEmitter {
|
|
|
537
499
|
lastActivityAt: this._lastActivityAt,
|
|
538
500
|
name: this._name,
|
|
539
501
|
mode: this.mode,
|
|
540
|
-
autoClearEnabled: this.
|
|
541
|
-
autoClearThreshold: this.
|
|
542
|
-
autoCompactEnabled: this.
|
|
543
|
-
autoCompactThreshold: this.
|
|
544
|
-
autoCompactPrompt: this.
|
|
502
|
+
autoClearEnabled: this._autoOps.autoClearEnabled,
|
|
503
|
+
autoClearThreshold: this._autoOps.autoClearThreshold,
|
|
504
|
+
autoCompactEnabled: this._autoOps.autoCompactEnabled,
|
|
505
|
+
autoCompactThreshold: this._autoOps.autoCompactThreshold,
|
|
506
|
+
autoCompactPrompt: this._autoOps.autoCompactPrompt,
|
|
545
507
|
imageWatcherEnabled: this._imageWatcherEnabled,
|
|
546
508
|
totalCost: this._totalCost,
|
|
547
509
|
inputTokens: this._totalInputTokens,
|
|
@@ -603,8 +565,8 @@ export class Session extends EventEmitter {
|
|
|
603
565
|
total: this._totalInputTokens + this._totalOutputTokens,
|
|
604
566
|
},
|
|
605
567
|
autoClear: {
|
|
606
|
-
enabled: this.
|
|
607
|
-
threshold: this.
|
|
568
|
+
enabled: this._autoOps.autoClearEnabled,
|
|
569
|
+
threshold: this._autoOps.autoClearThreshold,
|
|
608
570
|
},
|
|
609
571
|
// CPU priority configuration
|
|
610
572
|
nice: {
|
|
@@ -707,14 +669,7 @@ export class Session extends EventEmitter {
|
|
|
707
669
|
cols: 120,
|
|
708
670
|
rows: 40,
|
|
709
671
|
cwd: this.workingDir,
|
|
710
|
-
env:
|
|
711
|
-
...process.env,
|
|
712
|
-
LANG: 'en_US.UTF-8',
|
|
713
|
-
LC_ALL: 'en_US.UTF-8',
|
|
714
|
-
TERM: 'xterm-256color',
|
|
715
|
-
COLORTERM: undefined,
|
|
716
|
-
CLAUDECODE: undefined,
|
|
717
|
-
},
|
|
672
|
+
env: buildMuxAttachEnv(),
|
|
718
673
|
});
|
|
719
674
|
// Set claudeSessionId immediately since we passed --session-id to Claude
|
|
720
675
|
// The mux manager passes --session-id ${sessionId} to Claude
|
|
@@ -789,27 +744,13 @@ export class Session extends EventEmitter {
|
|
|
789
744
|
try {
|
|
790
745
|
// Pass --session-id to use the SAME ID as the Codeman session
|
|
791
746
|
// This ensures subagents can be directly matched to the correct tab
|
|
792
|
-
const args =
|
|
793
|
-
if (this._model)
|
|
794
|
-
args.push('--model', this._model);
|
|
747
|
+
const args = buildInteractiveArgs(this.id, this._claudeMode, this._model, this._allowedTools);
|
|
795
748
|
this.ptyProcess = pty.spawn('claude', args, {
|
|
796
749
|
name: 'xterm-256color',
|
|
797
750
|
cols: 120,
|
|
798
751
|
rows: 40,
|
|
799
752
|
cwd: this.workingDir,
|
|
800
|
-
env:
|
|
801
|
-
...process.env,
|
|
802
|
-
LANG: 'en_US.UTF-8',
|
|
803
|
-
LC_ALL: 'en_US.UTF-8',
|
|
804
|
-
PATH: getAugmentedPath(),
|
|
805
|
-
TERM: 'xterm-256color',
|
|
806
|
-
COLORTERM: undefined,
|
|
807
|
-
CLAUDECODE: undefined,
|
|
808
|
-
// Inform Claude it's running within Codeman (helps prevent self-termination)
|
|
809
|
-
CODEMAN_MUX: '1',
|
|
810
|
-
CODEMAN_SESSION_ID: this.id,
|
|
811
|
-
CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
|
|
812
|
-
},
|
|
753
|
+
env: buildClaudeEnv(this.id),
|
|
813
754
|
});
|
|
814
755
|
}
|
|
815
756
|
catch (spawnErr) {
|
|
@@ -1078,14 +1019,7 @@ export class Session extends EventEmitter {
|
|
|
1078
1019
|
cols: 120,
|
|
1079
1020
|
rows: 40,
|
|
1080
1021
|
cwd: this.workingDir,
|
|
1081
|
-
env:
|
|
1082
|
-
...process.env,
|
|
1083
|
-
LANG: 'en_US.UTF-8',
|
|
1084
|
-
LC_ALL: 'en_US.UTF-8',
|
|
1085
|
-
TERM: 'xterm-256color',
|
|
1086
|
-
COLORTERM: undefined,
|
|
1087
|
-
CLAUDECODE: undefined,
|
|
1088
|
-
},
|
|
1022
|
+
env: buildMuxAttachEnv(),
|
|
1089
1023
|
});
|
|
1090
1024
|
}
|
|
1091
1025
|
catch (spawnErr) {
|
|
@@ -1118,15 +1052,7 @@ export class Session extends EventEmitter {
|
|
|
1118
1052
|
cols: 120,
|
|
1119
1053
|
rows: 40,
|
|
1120
1054
|
cwd: this.workingDir,
|
|
1121
|
-
env:
|
|
1122
|
-
...process.env,
|
|
1123
|
-
LANG: 'en_US.UTF-8',
|
|
1124
|
-
LC_ALL: 'en_US.UTF-8',
|
|
1125
|
-
TERM: 'xterm-256color',
|
|
1126
|
-
CODEMAN_MUX: '1',
|
|
1127
|
-
CODEMAN_SESSION_ID: this.id,
|
|
1128
|
-
CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
|
|
1129
|
-
},
|
|
1055
|
+
env: buildShellEnv(this.id),
|
|
1130
1056
|
});
|
|
1131
1057
|
}
|
|
1132
1058
|
catch (spawnErr) {
|
|
@@ -1219,30 +1145,14 @@ export class Session extends EventEmitter {
|
|
|
1219
1145
|
// Spawn claude in a real PTY
|
|
1220
1146
|
const model = options?.model;
|
|
1221
1147
|
console.log('[Session] Spawning PTY for claude with prompt:', prompt.substring(0, 50), model ? `(model: ${model})` : '');
|
|
1222
|
-
const args =
|
|
1223
|
-
if (model) {
|
|
1224
|
-
args.push('--model', model);
|
|
1225
|
-
}
|
|
1226
|
-
args.push(prompt);
|
|
1148
|
+
const args = buildPromptArgs(prompt, model);
|
|
1227
1149
|
try {
|
|
1228
1150
|
this.ptyProcess = pty.spawn('claude', args, {
|
|
1229
1151
|
name: 'xterm-256color',
|
|
1230
1152
|
cols: 120,
|
|
1231
1153
|
rows: 40,
|
|
1232
1154
|
cwd: this.workingDir,
|
|
1233
|
-
env:
|
|
1234
|
-
...process.env,
|
|
1235
|
-
LANG: 'en_US.UTF-8',
|
|
1236
|
-
LC_ALL: 'en_US.UTF-8',
|
|
1237
|
-
PATH: getAugmentedPath(),
|
|
1238
|
-
TERM: 'xterm-256color',
|
|
1239
|
-
COLORTERM: undefined,
|
|
1240
|
-
CLAUDECODE: undefined,
|
|
1241
|
-
// Inform Claude it's running within Codeman
|
|
1242
|
-
CODEMAN_MUX: '1',
|
|
1243
|
-
CODEMAN_SESSION_ID: this.id,
|
|
1244
|
-
CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
|
|
1245
|
-
},
|
|
1155
|
+
env: buildClaudeEnv(this.id),
|
|
1246
1156
|
});
|
|
1247
1157
|
}
|
|
1248
1158
|
catch (spawnErr) {
|
|
@@ -1390,8 +1300,8 @@ export class Session extends EventEmitter {
|
|
|
1390
1300
|
this._totalOutputTokens += outputDelta;
|
|
1391
1301
|
}
|
|
1392
1302
|
// Check if we should auto-compact or auto-clear
|
|
1393
|
-
this.checkAutoCompact();
|
|
1394
|
-
this.checkAutoClear();
|
|
1303
|
+
this._autoOps.checkAutoCompact();
|
|
1304
|
+
this._autoOps.checkAutoClear();
|
|
1395
1305
|
}
|
|
1396
1306
|
}
|
|
1397
1307
|
if (msg.type === 'result' && msg.total_cost_usd) {
|
|
@@ -1443,29 +1353,7 @@ export class Session extends EventEmitter {
|
|
|
1443
1353
|
while ((match = TASK_TOOL_PATTERN.exec(cleanLine)) !== null) {
|
|
1444
1354
|
const description = match[2].trim();
|
|
1445
1355
|
if (description && description.length > 0) {
|
|
1446
|
-
|
|
1447
|
-
this._recentTaskDescriptions.set(now, description);
|
|
1448
|
-
// Cleanup old entries
|
|
1449
|
-
this.cleanupOldTaskDescriptions();
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
|
-
/**
|
|
1454
|
-
* Remove task descriptions older than TASK_DESCRIPTION_MAX_AGE_MS.
|
|
1455
|
-
* Size limit is handled automatically by LRUMap eviction on set().
|
|
1456
|
-
*/
|
|
1457
|
-
cleanupOldTaskDescriptions() {
|
|
1458
|
-
const cutoff = Date.now() - Session.TASK_DESCRIPTION_MAX_AGE_MS;
|
|
1459
|
-
// Keys are timestamps - iterate and delete expired entries
|
|
1460
|
-
// LRUMap maintains insertion order, so we can break early once we find a non-expired entry
|
|
1461
|
-
for (const timestamp of this._recentTaskDescriptions.keysInOrder()) {
|
|
1462
|
-
if (timestamp < cutoff) {
|
|
1463
|
-
this._recentTaskDescriptions.delete(timestamp);
|
|
1464
|
-
}
|
|
1465
|
-
else {
|
|
1466
|
-
// Keys are ordered by insertion time (which is the timestamp)
|
|
1467
|
-
// Once we find a non-expired one, all subsequent are also non-expired
|
|
1468
|
-
break;
|
|
1356
|
+
this._taskCache.add(Date.now(), description);
|
|
1469
1357
|
}
|
|
1470
1358
|
}
|
|
1471
1359
|
}
|
|
@@ -1474,12 +1362,7 @@ export class Session extends EventEmitter {
|
|
|
1474
1362
|
* Returns descriptions sorted by timestamp (most recent first).
|
|
1475
1363
|
*/
|
|
1476
1364
|
getRecentTaskDescriptions() {
|
|
1477
|
-
this.
|
|
1478
|
-
const results = [];
|
|
1479
|
-
for (const [timestamp, description] of this._recentTaskDescriptions) {
|
|
1480
|
-
results.push({ timestamp, description });
|
|
1481
|
-
}
|
|
1482
|
-
return results.sort((a, b) => b.timestamp - a.timestamp);
|
|
1365
|
+
return this._taskCache.getAll();
|
|
1483
1366
|
}
|
|
1484
1367
|
/**
|
|
1485
1368
|
* Find a task description that was parsed close to a given timestamp.
|
|
@@ -1490,18 +1373,7 @@ export class Session extends EventEmitter {
|
|
|
1490
1373
|
* @returns The matching description or undefined
|
|
1491
1374
|
*/
|
|
1492
1375
|
findTaskDescriptionNear(subagentStartTime, maxAgeMs = 10000) {
|
|
1493
|
-
this.
|
|
1494
|
-
// Find the most recent description that was parsed before or around the subagent start time
|
|
1495
|
-
let bestMatch;
|
|
1496
|
-
let bestDiff = Infinity;
|
|
1497
|
-
for (const [timestamp, description] of this._recentTaskDescriptions) {
|
|
1498
|
-
const diff = Math.abs(subagentStartTime - timestamp);
|
|
1499
|
-
if (diff < maxAgeMs && diff < bestDiff) {
|
|
1500
|
-
bestMatch = { timestamp, description };
|
|
1501
|
-
bestDiff = diff;
|
|
1502
|
-
}
|
|
1503
|
-
}
|
|
1504
|
-
return bestMatch?.description;
|
|
1376
|
+
return this._taskCache.findNear(subagentStartTime, maxAgeMs);
|
|
1505
1377
|
}
|
|
1506
1378
|
// Parse token count from Claude's status line in interactive mode
|
|
1507
1379
|
// Matches patterns like "123.4k tokens", "5234 tokens", "1.2M tokens"
|
|
@@ -1555,8 +1427,8 @@ export class Session extends EventEmitter {
|
|
|
1555
1427
|
this._totalInputTokens += Math.round(delta * 0.6);
|
|
1556
1428
|
this._totalOutputTokens += Math.round(delta * 0.4);
|
|
1557
1429
|
// Check if we should auto-compact or auto-clear
|
|
1558
|
-
this.checkAutoCompact();
|
|
1559
|
-
this.checkAutoClear();
|
|
1430
|
+
this._autoOps.checkAutoCompact();
|
|
1431
|
+
this._autoOps.checkAutoClear();
|
|
1560
1432
|
}
|
|
1561
1433
|
}
|
|
1562
1434
|
}
|
|
@@ -1629,108 +1501,7 @@ export class Session extends EventEmitter {
|
|
|
1629
1501
|
});
|
|
1630
1502
|
}
|
|
1631
1503
|
}
|
|
1632
|
-
//
|
|
1633
|
-
checkAutoCompact() {
|
|
1634
|
-
if (this._isStopped)
|
|
1635
|
-
return; // Early exit check
|
|
1636
|
-
if (!this._autoCompactEnabled || this._isCompacting || this._isClearing)
|
|
1637
|
-
return;
|
|
1638
|
-
const totalTokens = this._totalInputTokens + this._totalOutputTokens;
|
|
1639
|
-
if (totalTokens >= this._autoCompactThreshold) {
|
|
1640
|
-
this._isCompacting = true;
|
|
1641
|
-
console.log(`[Session] Auto-compact triggered: ${totalTokens} tokens >= ${this._autoCompactThreshold} threshold`);
|
|
1642
|
-
// Wait for Claude to be idle before compacting
|
|
1643
|
-
const checkAndCompact = async () => {
|
|
1644
|
-
// Check if session is still valid (not stopped) - must be first check
|
|
1645
|
-
if (this._isStopped)
|
|
1646
|
-
return;
|
|
1647
|
-
if (!this._isCompacting)
|
|
1648
|
-
return;
|
|
1649
|
-
if (!this._isWorking) {
|
|
1650
|
-
// Re-check stopped state after async operation might have completed
|
|
1651
|
-
if (this._isStopped)
|
|
1652
|
-
return;
|
|
1653
|
-
// Send /compact command with optional prompt
|
|
1654
|
-
const compactCmd = this._autoCompactPrompt ? `/compact ${this._autoCompactPrompt}\r` : '/compact\r';
|
|
1655
|
-
await this.writeViaMux(compactCmd);
|
|
1656
|
-
this.emit('autoCompact', {
|
|
1657
|
-
tokens: totalTokens,
|
|
1658
|
-
threshold: this._autoCompactThreshold,
|
|
1659
|
-
prompt: this._autoCompactPrompt || undefined,
|
|
1660
|
-
});
|
|
1661
|
-
// Wait a moment then re-enable (longer than clear since compact takes time)
|
|
1662
|
-
if (!this._isStopped) {
|
|
1663
|
-
this._autoCompactTimer = setTimeout(() => {
|
|
1664
|
-
if (this._isStopped)
|
|
1665
|
-
return; // Check at callback start
|
|
1666
|
-
this._autoCompactTimer = null;
|
|
1667
|
-
this._isCompacting = false;
|
|
1668
|
-
}, 10000);
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
else {
|
|
1672
|
-
// Check again after delay
|
|
1673
|
-
if (!this._isStopped) {
|
|
1674
|
-
this._autoCompactTimer = setTimeout(checkAndCompact, AUTO_RETRY_DELAY_MS);
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
};
|
|
1678
|
-
// Start checking after a short delay
|
|
1679
|
-
if (!this._isStopped) {
|
|
1680
|
-
this._autoCompactTimer = setTimeout(checkAndCompact, AUTO_INITIAL_DELAY_MS);
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
// Check if we should auto-clear based on token threshold
|
|
1685
|
-
checkAutoClear() {
|
|
1686
|
-
if (this._isStopped)
|
|
1687
|
-
return; // Early exit check
|
|
1688
|
-
if (!this._autoClearEnabled || this._isClearing || this._isCompacting)
|
|
1689
|
-
return;
|
|
1690
|
-
const totalTokens = this._totalInputTokens + this._totalOutputTokens;
|
|
1691
|
-
if (totalTokens >= this._autoClearThreshold) {
|
|
1692
|
-
this._isClearing = true;
|
|
1693
|
-
console.log(`[Session] Auto-clear triggered: ${totalTokens} tokens >= ${this._autoClearThreshold} threshold`);
|
|
1694
|
-
// Wait for Claude to be idle before clearing
|
|
1695
|
-
const checkAndClear = async () => {
|
|
1696
|
-
// Check if session is still valid (not stopped) - must be first check
|
|
1697
|
-
if (this._isStopped)
|
|
1698
|
-
return;
|
|
1699
|
-
if (!this._isClearing)
|
|
1700
|
-
return;
|
|
1701
|
-
if (!this._isWorking) {
|
|
1702
|
-
// Re-check stopped state after async operation might have completed
|
|
1703
|
-
if (this._isStopped)
|
|
1704
|
-
return;
|
|
1705
|
-
// Send /clear command
|
|
1706
|
-
await this.writeViaMux('/clear\r');
|
|
1707
|
-
// Reset token counts
|
|
1708
|
-
this._totalInputTokens = 0;
|
|
1709
|
-
this._totalOutputTokens = 0;
|
|
1710
|
-
this.emit('autoClear', { tokens: totalTokens, threshold: this._autoClearThreshold });
|
|
1711
|
-
// Wait a moment then re-enable
|
|
1712
|
-
if (!this._isStopped) {
|
|
1713
|
-
this._autoClearTimer = setTimeout(() => {
|
|
1714
|
-
if (this._isStopped)
|
|
1715
|
-
return; // Check at callback start
|
|
1716
|
-
this._autoClearTimer = null;
|
|
1717
|
-
this._isClearing = false;
|
|
1718
|
-
}, 5000);
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
else {
|
|
1722
|
-
// Check again after delay
|
|
1723
|
-
if (!this._isStopped) {
|
|
1724
|
-
this._autoClearTimer = setTimeout(checkAndClear, AUTO_RETRY_DELAY_MS);
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
};
|
|
1728
|
-
// Start checking after a short delay
|
|
1729
|
-
if (!this._isStopped) {
|
|
1730
|
-
this._autoClearTimer = setTimeout(checkAndClear, AUTO_INITIAL_DELAY_MS);
|
|
1731
|
-
}
|
|
1732
|
-
}
|
|
1733
|
-
}
|
|
1504
|
+
// Note: checkAutoCompact/checkAutoClear moved to SessionAutoOps (this._autoOps)
|
|
1734
1505
|
/**
|
|
1735
1506
|
* Sends input directly to the PTY process.
|
|
1736
1507
|
*
|
|
@@ -1885,17 +1656,8 @@ export class Session extends EventEmitter {
|
|
|
1885
1656
|
clearTimeout(this._lineBufferFlushTimer);
|
|
1886
1657
|
this._lineBufferFlushTimer = null;
|
|
1887
1658
|
}
|
|
1888
|
-
//
|
|
1889
|
-
|
|
1890
|
-
clearTimeout(this._autoCompactTimer);
|
|
1891
|
-
this._autoCompactTimer = null;
|
|
1892
|
-
}
|
|
1893
|
-
this._isCompacting = false;
|
|
1894
|
-
if (this._autoClearTimer) {
|
|
1895
|
-
clearTimeout(this._autoClearTimer);
|
|
1896
|
-
this._autoClearTimer = null;
|
|
1897
|
-
}
|
|
1898
|
-
this._isClearing = false;
|
|
1659
|
+
// Destroy auto-compact/auto-clear automation (clears its timers)
|
|
1660
|
+
this._autoOps.destroy();
|
|
1899
1661
|
// Clear prompt check timers
|
|
1900
1662
|
if (this._promptCheckInterval) {
|
|
1901
1663
|
clearInterval(this._promptCheckInterval);
|
|
@@ -1968,7 +1730,7 @@ export class Session extends EventEmitter {
|
|
|
1968
1730
|
this._status = killMux ? 'stopped' : 'idle';
|
|
1969
1731
|
this._currentTaskId = null;
|
|
1970
1732
|
// Clear task description cache and agent tree to prevent memory leak
|
|
1971
|
-
this.
|
|
1733
|
+
this._taskCache.clear();
|
|
1972
1734
|
this._childAgentIds = [];
|
|
1973
1735
|
// Kill the associated mux session if requested
|
|
1974
1736
|
if (killMux && this._mux) {
|
|
@@ -2019,7 +1781,7 @@ export class Session extends EventEmitter {
|
|
|
2019
1781
|
this._messages = [];
|
|
2020
1782
|
this._taskTracker.clear();
|
|
2021
1783
|
this._ralphTracker.clear();
|
|
2022
|
-
this.
|
|
1784
|
+
this._taskCache.clear();
|
|
2023
1785
|
}
|
|
2024
1786
|
}
|
|
2025
1787
|
//# sourceMappingURL=session.js.map
|