@ai-devkit/agent-manager 0.32.0 → 0.33.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/dist/AgentManager.d.ts +3 -3
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +80 -79
- package/dist/AgentManager.js.map +1 -1
- package/dist/__tests__/AgentManager.test.js +413 -388
- package/dist/__tests__/AgentManager.test.js.map +1 -1
- package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js +642 -642
- package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +1 -1
- package/dist/__tests__/adapters/CodexAdapter.test.js +322 -2321
- package/dist/__tests__/adapters/CodexAdapter.test.js.map +1 -1
- package/dist/__tests__/adapters/CopilotAdapter.test.js +254 -248
- package/dist/__tests__/adapters/CopilotAdapter.test.js.map +1 -1
- package/dist/__tests__/adapters/GeminiCliAdapter.test.js +564 -558
- package/dist/__tests__/adapters/GeminiCliAdapter.test.js.map +1 -1
- package/dist/__tests__/adapters/GrokCliAdapter.test.js +114 -114
- package/dist/__tests__/adapters/GrokCliAdapter.test.js.map +1 -1
- package/dist/__tests__/adapters/OpenCodeAdapter.test.js +169 -169
- package/dist/__tests__/adapters/OpenCodeAdapter.test.js.map +1 -1
- package/dist/__tests__/capacity/codex.test.js +93 -93
- package/dist/__tests__/capacity/codex.test.js.map +1 -1
- package/dist/__tests__/capacity/index.test.js +17 -17
- package/dist/__tests__/capacity/index.test.js.map +1 -1
- package/dist/__tests__/durable/CodexCliProbe.test.js +60 -60
- package/dist/__tests__/durable/CodexCliProbe.test.js.map +1 -1
- package/dist/__tests__/durable/CodexDurableAgentRepository.test.js +28 -28
- package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +1 -1
- package/dist/__tests__/durable/CodexPrintAgent.integration.test.js +30 -30
- package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +1 -1
- package/dist/__tests__/durable/CodexPrintAgentService.test.js +71 -71
- package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +1 -1
- package/dist/__tests__/durable/CodexPrintRunner.test.js +125 -125
- package/dist/__tests__/durable/CodexPrintRunner.test.js.map +1 -1
- package/dist/__tests__/print/ClaudeCliProbe.test.js +20 -20
- package/dist/__tests__/print/ClaudeCliProbe.test.js.map +1 -1
- package/dist/__tests__/print/ClaudePrintAgent.integration.test.js +20 -20
- package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +1 -1
- package/dist/__tests__/print/ClaudePrintAgentService.test.js +58 -58
- package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +1 -1
- package/dist/__tests__/print/ClaudePrintRunner.test.js +55 -55
- package/dist/__tests__/print/ClaudePrintRunner.test.js.map +1 -1
- package/dist/__tests__/print/DurableAgent.test.js +9 -9
- package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
- package/dist/__tests__/print/DurableAgentRepository.sqlite.test.js +40 -40
- package/dist/__tests__/print/DurableAgentRepository.sqlite.test.js.map +1 -1
- package/dist/__tests__/print/DurableAgentRepository.test.js +66 -66
- package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
- package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js +34 -34
- package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +1 -1
- package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js +132 -132
- package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js.map +1 -1
- package/dist/__tests__/providers/codex/CodexSessionLocator.test.js +194 -0
- package/dist/__tests__/providers/codex/CodexSessionLocator.test.js.map +1 -0
- package/dist/__tests__/providers/codex/CodexSessionMapping.test.js +86 -0
- package/dist/__tests__/providers/codex/CodexSessionMapping.test.js.map +1 -0
- package/dist/__tests__/providers/codex/CodexSessionParser.test.js +254 -0
- package/dist/__tests__/providers/codex/CodexSessionParser.test.js.map +1 -0
- package/dist/__tests__/providers/pi/PiAdapter.test.js +337 -0
- package/dist/__tests__/providers/pi/PiAdapter.test.js.map +1 -0
- package/dist/__tests__/providers/pi/PiSessionParser.test.js +246 -0
- package/dist/__tests__/providers/pi/PiSessionParser.test.js.map +1 -0
- package/dist/__tests__/providers/pi/PiSessionTracker.test.js +108 -0
- package/dist/__tests__/providers/pi/PiSessionTracker.test.js.map +1 -0
- package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js +33 -33
- package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js.map +1 -1
- package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js +16 -16
- package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js.map +1 -1
- package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js +52 -52
- package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js.map +1 -1
- package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js +44 -44
- package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js.map +1 -1
- package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js +126 -126
- package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js.map +1 -1
- package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js +14 -14
- package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js.map +1 -1
- package/dist/__tests__/readiness/AgentReadiness.test.js +134 -134
- package/dist/__tests__/readiness/AgentReadiness.test.js.map +1 -1
- package/dist/__tests__/runtime/AgentRuntime.test.js +13 -0
- package/dist/__tests__/runtime/AgentRuntime.test.js.map +1 -0
- package/dist/__tests__/runtime/HerdrAgentRuntime.test.js +452 -0
- package/dist/__tests__/runtime/HerdrAgentRuntime.test.js.map +1 -0
- package/dist/__tests__/runtime/ManagedAgentRuntime.test.js +588 -0
- package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -0
- package/dist/__tests__/terminal/TerminalFocusManager.test.js +100 -100
- package/dist/__tests__/terminal/TerminalFocusManager.test.js.map +1 -1
- package/dist/__tests__/terminal/TmuxManager.test.js +101 -101
- package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
- package/dist/__tests__/terminal/TtyWriter.test.js +185 -185
- package/dist/__tests__/terminal/TtyWriter.test.js.map +1 -1
- package/dist/__tests__/utils/AgentRegistry.test.js +335 -217
- package/dist/__tests__/utils/AgentRegistry.test.js.map +1 -1
- package/dist/__tests__/utils/ClaudeSessionParser.test.js +103 -101
- package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +1 -1
- package/dist/__tests__/utils/agent-requests.test.js +43 -43
- package/dist/__tests__/utils/agent-requests.test.js.map +1 -1
- package/dist/__tests__/utils/agents.test.js +17 -17
- package/dist/__tests__/utils/agents.test.js.map +1 -1
- package/dist/__tests__/utils/matching.test.js +92 -92
- package/dist/__tests__/utils/matching.test.js.map +1 -1
- package/dist/__tests__/utils/process.test.js +108 -108
- package/dist/__tests__/utils/process.test.js.map +1 -1
- package/dist/__tests__/utils/session.test.js +53 -53
- package/dist/__tests__/utils/session.test.js.map +1 -1
- package/dist/adapters/AgentAdapter.d.ts +2 -2
- package/dist/adapters/AgentAdapter.d.ts.map +1 -1
- package/dist/adapters/AgentAdapter.js +1 -1
- package/dist/adapters/AgentAdapter.js.map +1 -1
- package/dist/adapters/CopilotAdapter.d.ts +2 -2
- package/dist/adapters/CopilotAdapter.d.ts.map +1 -1
- package/dist/adapters/CopilotAdapter.js +51 -51
- package/dist/adapters/CopilotAdapter.js.map +1 -1
- package/dist/adapters/GeminiCliAdapter.d.ts +2 -2
- package/dist/adapters/GeminiCliAdapter.d.ts.map +1 -1
- package/dist/adapters/GeminiCliAdapter.js +86 -86
- package/dist/adapters/GeminiCliAdapter.js.map +1 -1
- package/dist/adapters/GrokCliAdapter.d.ts +1 -1
- package/dist/adapters/GrokCliAdapter.d.ts.map +1 -1
- package/dist/adapters/GrokCliAdapter.js +80 -80
- package/dist/adapters/GrokCliAdapter.js.map +1 -1
- package/dist/adapters/OpenCodeAdapter.d.ts +1 -1
- package/dist/adapters/OpenCodeAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenCodeAdapter.js +37 -36
- package/dist/adapters/OpenCodeAdapter.js.map +1 -1
- package/dist/adapters/index.d.ts +9 -9
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +8 -8
- package/dist/adapters/index.js.map +1 -1
- package/dist/capacity/codex.d.ts +3 -3
- package/dist/capacity/codex.d.ts.map +1 -1
- package/dist/capacity/codex.js +57 -57
- package/dist/capacity/codex.js.map +1 -1
- package/dist/capacity/index.d.ts +3 -3
- package/dist/capacity/index.d.ts.map +1 -1
- package/dist/capacity/index.js +8 -8
- package/dist/capacity/index.js.map +1 -1
- package/dist/capacity/types.d.ts +1 -1
- package/dist/capacity/types.js.map +1 -1
- package/dist/database/connection.d.ts +1 -1
- package/dist/database/connection.d.ts.map +1 -1
- package/dist/database/connection.js +15 -15
- package/dist/database/connection.js.map +1 -1
- package/dist/database/index.d.ts +3 -3
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +2 -2
- package/dist/database/index.js.map +1 -1
- package/dist/database/migrations/005_agent_runtime.sql +2 -0
- package/dist/database/schema.d.ts +1 -1
- package/dist/database/schema.d.ts.map +1 -1
- package/dist/database/schema.js +7 -7
- package/dist/database/schema.js.map +1 -1
- package/dist/durable/DurableAgent.d.ts +9 -9
- package/dist/durable/DurableAgent.d.ts.map +1 -1
- package/dist/durable/DurableAgent.js +16 -16
- package/dist/durable/DurableAgent.js.map +1 -1
- package/dist/durable/DurableAgentRepository.d.ts +4 -4
- package/dist/durable/DurableAgentRepository.d.ts.map +1 -1
- package/dist/durable/DurableAgentRepository.js +49 -48
- package/dist/durable/DurableAgentRepository.js.map +1 -1
- package/dist/durable/process.d.ts +1 -1
- package/dist/durable/process.d.ts.map +1 -1
- package/dist/durable/process.js +14 -14
- package/dist/durable/process.js.map +1 -1
- package/dist/durable/run.d.ts +2 -2
- package/dist/durable/run.d.ts.map +1 -1
- package/dist/durable/run.js +6 -6
- package/dist/durable/run.js.map +1 -1
- package/dist/durable/utils.d.ts +1 -1
- package/dist/durable/utils.d.ts.map +1 -1
- package/dist/durable/utils.js +4 -4
- package/dist/durable/utils.js.map +1 -1
- package/dist/index.d.ts +46 -43
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -26
- package/dist/index.js.map +1 -1
- package/dist/providers/claude/ClaudeAgentMapper.d.ts +4 -4
- package/dist/providers/claude/ClaudeAgentMapper.d.ts.map +1 -1
- package/dist/providers/claude/ClaudeAgentMapper.js +10 -10
- package/dist/providers/claude/ClaudeAgentMapper.js.map +1 -1
- package/dist/providers/claude/ClaudeCodeAdapter.d.ts +1 -1
- package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +1 -1
- package/dist/providers/claude/ClaudeCodeAdapter.js +14 -14
- package/dist/providers/claude/ClaudeCodeAdapter.js.map +1 -1
- package/dist/providers/claude/ClaudeSessionLocator.d.ts +4 -4
- package/dist/providers/claude/ClaudeSessionLocator.d.ts.map +1 -1
- package/dist/providers/claude/ClaudeSessionLocator.js +79 -79
- package/dist/providers/claude/ClaudeSessionLocator.js.map +1 -1
- package/dist/providers/claude/ClaudeSessionParser.d.ts +2 -2
- package/dist/providers/claude/ClaudeSessionParser.d.ts.map +1 -1
- package/dist/providers/claude/ClaudeSessionParser.js +99 -99
- package/dist/providers/claude/ClaudeSessionParser.js.map +1 -1
- package/dist/providers/claude/durable/ClaudeCliProbe.d.ts.map +1 -1
- package/dist/providers/claude/durable/ClaudeCliProbe.js +16 -16
- package/dist/providers/claude/durable/ClaudeCliProbe.js.map +1 -1
- package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts +5 -5
- package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts.map +1 -1
- package/dist/providers/claude/durable/ClaudePrintAgentService.js +10 -10
- package/dist/providers/claude/durable/ClaudePrintAgentService.js.map +1 -1
- package/dist/providers/claude/durable/ClaudePrintRunner.d.ts +4 -4
- package/dist/providers/claude/durable/ClaudePrintRunner.d.ts.map +1 -1
- package/dist/providers/claude/durable/ClaudePrintRunner.js +18 -18
- package/dist/providers/claude/durable/ClaudePrintRunner.js.map +1 -1
- package/dist/providers/claude/durable/ClaudeStreamParser.d.ts +2 -2
- package/dist/providers/claude/durable/ClaudeStreamParser.d.ts.map +1 -1
- package/dist/providers/claude/durable/ClaudeStreamParser.js +17 -17
- package/dist/providers/claude/durable/ClaudeStreamParser.js.map +1 -1
- package/dist/providers/codex/CodexAdapter.d.ts +27 -0
- package/dist/providers/codex/CodexAdapter.d.ts.map +1 -0
- package/dist/providers/codex/CodexAdapter.js +162 -0
- package/dist/providers/codex/CodexAdapter.js.map +1 -0
- package/dist/providers/codex/CodexAgentMapper.d.ts +9 -0
- package/dist/providers/codex/CodexAgentMapper.d.ts.map +1 -0
- package/dist/providers/codex/CodexAgentMapper.js +35 -0
- package/dist/providers/codex/CodexAgentMapper.js.map +1 -0
- package/dist/providers/codex/CodexSessionLocator.d.ts +44 -0
- package/dist/providers/codex/CodexSessionLocator.d.ts.map +1 -0
- package/dist/providers/codex/CodexSessionLocator.js +207 -0
- package/dist/providers/codex/CodexSessionLocator.js.map +1 -0
- package/dist/providers/codex/CodexSessionMapping.d.ts +23 -0
- package/dist/providers/codex/CodexSessionMapping.d.ts.map +1 -0
- package/dist/providers/codex/CodexSessionMapping.js +68 -0
- package/dist/providers/codex/CodexSessionMapping.js.map +1 -0
- package/dist/providers/codex/CodexSessionParser.d.ts +58 -0
- package/dist/providers/codex/CodexSessionParser.d.ts.map +1 -0
- package/dist/providers/codex/CodexSessionParser.js +262 -0
- package/dist/providers/codex/CodexSessionParser.js.map +1 -0
- package/dist/providers/codex/durable/CodexCliProbe.d.ts.map +1 -1
- package/dist/providers/codex/durable/CodexCliProbe.js +22 -22
- package/dist/providers/codex/durable/CodexCliProbe.js.map +1 -1
- package/dist/providers/codex/durable/CodexPrintAgentService.d.ts +6 -6
- package/dist/providers/codex/durable/CodexPrintAgentService.d.ts.map +1 -1
- package/dist/providers/codex/durable/CodexPrintAgentService.js +10 -10
- package/dist/providers/codex/durable/CodexPrintAgentService.js.map +1 -1
- package/dist/providers/codex/durable/CodexPrintRunner.d.ts +4 -4
- package/dist/providers/codex/durable/CodexPrintRunner.d.ts.map +1 -1
- package/dist/providers/codex/durable/CodexPrintRunner.js +20 -20
- package/dist/providers/codex/durable/CodexPrintRunner.js.map +1 -1
- package/dist/providers/codex/durable/CodexStreamParser.d.ts +2 -2
- package/dist/providers/codex/durable/CodexStreamParser.d.ts.map +1 -1
- package/dist/providers/codex/durable/CodexStreamParser.js +21 -21
- package/dist/providers/codex/durable/CodexStreamParser.js.map +1 -1
- package/dist/providers/pi/PiAdapter.d.ts +28 -0
- package/dist/providers/pi/PiAdapter.d.ts.map +1 -0
- package/dist/providers/pi/PiAdapter.js +153 -0
- package/dist/providers/pi/PiAdapter.js.map +1 -0
- package/dist/providers/pi/PiAgentMapper.d.ts +9 -0
- package/dist/providers/pi/PiAgentMapper.d.ts.map +1 -0
- package/dist/providers/pi/PiAgentMapper.js +37 -0
- package/dist/providers/pi/PiAgentMapper.js.map +1 -0
- package/dist/providers/pi/PiSessionLocator.d.ts +23 -0
- package/dist/providers/pi/PiSessionLocator.d.ts.map +1 -0
- package/dist/providers/pi/PiSessionLocator.js +79 -0
- package/dist/providers/pi/PiSessionLocator.js.map +1 -0
- package/dist/providers/pi/PiSessionParser.d.ts +36 -0
- package/dist/providers/pi/PiSessionParser.d.ts.map +1 -0
- package/dist/providers/pi/PiSessionParser.js +191 -0
- package/dist/providers/pi/PiSessionParser.js.map +1 -0
- package/dist/providers/pi/PiSessionTracker.d.ts +23 -0
- package/dist/providers/pi/PiSessionTracker.d.ts.map +1 -0
- package/dist/providers/pi/PiSessionTracker.js +69 -0
- package/dist/providers/pi/PiSessionTracker.js.map +1 -0
- package/dist/providers/pi/durable/PiCliProbe.d.ts.map +1 -1
- package/dist/providers/pi/durable/PiCliProbe.js +15 -15
- package/dist/providers/pi/durable/PiCliProbe.js.map +1 -1
- package/dist/providers/pi/durable/PiPrintAgentService.d.ts +6 -6
- package/dist/providers/pi/durable/PiPrintAgentService.d.ts.map +1 -1
- package/dist/providers/pi/durable/PiPrintAgentService.js +10 -10
- package/dist/providers/pi/durable/PiPrintAgentService.js.map +1 -1
- package/dist/providers/pi/durable/PiPrintProtocol.d.ts.map +1 -1
- package/dist/providers/pi/durable/PiPrintProtocol.js +18 -18
- package/dist/providers/pi/durable/PiPrintProtocol.js.map +1 -1
- package/dist/providers/pi/durable/PiPrintRunner.d.ts +4 -4
- package/dist/providers/pi/durable/PiPrintRunner.d.ts.map +1 -1
- package/dist/providers/pi/durable/PiPrintRunner.js +15 -15
- package/dist/providers/pi/durable/PiPrintRunner.js.map +1 -1
- package/dist/providers/pi/durable/PiStreamParser.d.ts +1 -1
- package/dist/providers/pi/durable/PiStreamParser.d.ts.map +1 -1
- package/dist/providers/pi/durable/PiStreamParser.js +16 -16
- package/dist/providers/pi/durable/PiStreamParser.js.map +1 -1
- package/dist/readiness/AgentReadiness.d.ts +6 -6
- package/dist/readiness/AgentReadiness.d.ts.map +1 -1
- package/dist/readiness/AgentReadiness.js +130 -130
- package/dist/readiness/AgentReadiness.js.map +1 -1
- package/dist/runtime/ManagedAgentRuntime.d.ts +69 -0
- package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -0
- package/dist/runtime/ManagedAgentRuntime.js +156 -0
- package/dist/runtime/ManagedAgentRuntime.js.map +1 -0
- package/dist/runtime/RuntimeFactory.d.ts +4 -0
- package/dist/runtime/RuntimeFactory.d.ts.map +1 -0
- package/dist/runtime/RuntimeFactory.js +11 -0
- package/dist/runtime/RuntimeFactory.js.map +1 -0
- package/dist/runtime/errors.d.ts +27 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/errors.js +42 -0
- package/dist/runtime/errors.js.map +1 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.d.ts +31 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.js +184 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.js.map +1 -0
- package/dist/runtime/herdr/HerdrCliClient.d.ts +13 -0
- package/dist/runtime/herdr/HerdrCliClient.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrCliClient.js +60 -0
- package/dist/runtime/herdr/HerdrCliClient.js.map +1 -0
- package/dist/runtime/herdr/HerdrErrors.d.ts +7 -0
- package/dist/runtime/herdr/HerdrErrors.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrErrors.js +10 -0
- package/dist/runtime/herdr/HerdrErrors.js.map +1 -0
- package/dist/runtime/herdr/HerdrResponseParsers.d.ts +14 -0
- package/dist/runtime/herdr/HerdrResponseParsers.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrResponseParsers.js +96 -0
- package/dist/runtime/herdr/HerdrResponseParsers.js.map +1 -0
- package/dist/runtime/herdr/HerdrRuntimeRef.d.ts +9 -0
- package/dist/runtime/herdr/HerdrRuntimeRef.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrRuntimeRef.js +33 -0
- package/dist/runtime/herdr/HerdrRuntimeRef.js.map +1 -0
- package/dist/runtime/tmux/PidPolling.d.ts +5 -0
- package/dist/runtime/tmux/PidPolling.d.ts.map +1 -0
- package/dist/runtime/tmux/PidPolling.js +24 -0
- package/dist/runtime/tmux/PidPolling.js.map +1 -0
- package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +17 -0
- package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -0
- package/dist/runtime/tmux/TmuxAgentRuntime.js +80 -0
- package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -0
- package/dist/runtime/tmux/TmuxRuntimeRef.d.ts +5 -0
- package/dist/runtime/tmux/TmuxRuntimeRef.d.ts.map +1 -0
- package/dist/runtime/tmux/TmuxRuntimeRef.js +9 -0
- package/dist/runtime/tmux/TmuxRuntimeRef.js.map +1 -0
- package/dist/runtime/types.d.ts +54 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +3 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
- package/dist/terminal/TerminalFocusManager.js +50 -50
- package/dist/terminal/TerminalFocusManager.js.map +1 -1
- package/dist/terminal/TmuxManager.d.ts.map +1 -1
- package/dist/terminal/TmuxManager.js +47 -47
- package/dist/terminal/TmuxManager.js.map +1 -1
- package/dist/terminal/TtyWriter.d.ts +1 -1
- package/dist/terminal/TtyWriter.d.ts.map +1 -1
- package/dist/terminal/TtyWriter.js +89 -89
- package/dist/terminal/TtyWriter.js.map +1 -1
- package/dist/terminal/index.d.ts +4 -4
- package/dist/terminal/index.js +3 -3
- package/dist/terminal/index.js.map +1 -1
- package/dist/utils/AgentRegistry.d.ts +10 -2
- package/dist/utils/AgentRegistry.d.ts.map +1 -1
- package/dist/utils/AgentRegistry.js +57 -24
- package/dist/utils/AgentRegistry.js.map +1 -1
- package/dist/utils/agent-requests.d.ts.map +1 -1
- package/dist/utils/agent-requests.js +5 -5
- package/dist/utils/agent-requests.js.map +1 -1
- package/dist/utils/agents.d.ts +2 -2
- package/dist/utils/agents.d.ts.map +1 -1
- package/dist/utils/agents.js +15 -15
- package/dist/utils/agents.js.map +1 -1
- package/dist/utils/applescript.js +1 -1
- package/dist/utils/applescript.js.map +1 -1
- package/dist/utils/index.d.ts +6 -6
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -4
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/matching.d.ts +2 -2
- package/dist/utils/matching.d.ts.map +1 -1
- package/dist/utils/matching.js +4 -4
- package/dist/utils/matching.js.map +1 -1
- package/dist/utils/process.d.ts +1 -1
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +74 -74
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/session.d.ts +1 -1
- package/dist/utils/session.d.ts.map +1 -1
- package/dist/utils/session.js +7 -7
- package/dist/utils/session.js.map +1 -1
- package/dist/utils/sortAgents.d.ts +2 -2
- package/dist/utils/sortAgents.d.ts.map +1 -1
- package/dist/utils/sortAgents.js +5 -5
- package/dist/utils/sortAgents.js.map +1 -1
- package/package.json +18 -19
- package/src/AgentManager.ts +283 -281
- package/src/__tests__/AgentManager.test.ts +917 -907
- package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +1657 -1368
- package/src/__tests__/adapters/CodexAdapter.test.ts +365 -1698
- package/src/__tests__/adapters/CopilotAdapter.test.ts +576 -481
- package/src/__tests__/adapters/GeminiCliAdapter.test.ts +1189 -1157
- package/src/__tests__/adapters/GrokCliAdapter.test.ts +325 -272
- package/src/__tests__/adapters/OpenCodeAdapter.test.ts +510 -455
- package/src/__tests__/capacity/codex.test.ts +178 -91
- package/src/__tests__/capacity/index.test.ts +27 -18
- package/src/__tests__/durable/CodexCliProbe.test.ts +75 -53
- package/src/__tests__/durable/CodexDurableAgentRepository.test.ts +51 -40
- package/src/__tests__/durable/CodexPrintAgent.integration.test.ts +89 -64
- package/src/__tests__/durable/CodexPrintAgentService.test.ts +196 -118
- package/src/__tests__/durable/CodexPrintRunner.test.ts +282 -162
- package/src/__tests__/fixtures/fake-claude.cjs +20 -13
- package/src/__tests__/fixtures/fake-codex.cjs +41 -30
- package/src/__tests__/print/ClaudeCliProbe.test.ts +27 -21
- package/src/__tests__/print/ClaudePrintAgent.integration.test.ts +48 -40
- package/src/__tests__/print/ClaudePrintAgentService.test.ts +118 -67
- package/src/__tests__/print/ClaudePrintRunner.test.ts +136 -83
- package/src/__tests__/print/DurableAgent.test.ts +19 -16
- package/src/__tests__/print/DurableAgentRepository.sqlite.test.ts +109 -86
- package/src/__tests__/print/DurableAgentRepository.test.ts +170 -137
- package/src/__tests__/providers/claude/ClaudeAgentMapper.test.ts +65 -65
- package/src/__tests__/providers/claude/ClaudeSessionLocator.test.ts +400 -377
- package/src/__tests__/providers/codex/CodexSessionLocator.test.ts +182 -0
- package/src/__tests__/providers/codex/CodexSessionMapping.test.ts +63 -0
- package/src/__tests__/providers/codex/CodexSessionParser.test.ts +192 -0
- package/src/__tests__/providers/pi/PiAdapter.test.ts +310 -0
- package/src/__tests__/providers/pi/PiSessionParser.test.ts +190 -0
- package/src/__tests__/providers/pi/PiSessionTracker.test.ts +79 -0
- package/src/__tests__/providers/pi/durable/PiCliProbe.test.ts +48 -32
- package/src/__tests__/providers/pi/durable/PiDurableAgentRepository.test.ts +24 -23
- package/src/__tests__/providers/pi/durable/PiPrintAgentService.test.ts +131 -59
- package/src/__tests__/providers/pi/durable/PiPrintProtocol.test.ts +66 -28
- package/src/__tests__/providers/pi/durable/PiPrintRunner.test.ts +236 -90
- package/src/__tests__/providers/pi/durable/PiStreamParser.test.ts +20 -18
- package/src/__tests__/readiness/AgentReadiness.test.ts +217 -169
- package/src/__tests__/runtime/AgentRuntime.test.ts +8 -0
- package/src/__tests__/runtime/HerdrAgentRuntime.test.ts +358 -0
- package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +555 -0
- package/src/__tests__/terminal/TerminalFocusManager.test.ts +254 -253
- package/src/__tests__/terminal/TmuxManager.test.ts +157 -157
- package/src/__tests__/terminal/TtyWriter.test.ts +423 -419
- package/src/__tests__/utils/AgentRegistry.test.ts +506 -402
- package/src/__tests__/utils/ClaudeSessionParser.test.ts +276 -242
- package/src/__tests__/utils/agent-requests.test.ts +76 -56
- package/src/__tests__/utils/agents.test.ts +20 -20
- package/src/__tests__/utils/matching.test.ts +206 -171
- package/src/__tests__/utils/process.test.ts +276 -262
- package/src/__tests__/utils/session.test.ts +133 -139
- package/src/adapters/AgentAdapter.ts +134 -126
- package/src/adapters/CopilotAdapter.ts +405 -395
- package/src/adapters/GeminiCliAdapter.ts +598 -600
- package/src/adapters/GrokCliAdapter.ts +353 -342
- package/src/adapters/OpenCodeAdapter.ts +285 -259
- package/src/adapters/index.ts +15 -9
- package/src/capacity/codex.ts +137 -84
- package/src/capacity/index.ts +18 -13
- package/src/capacity/types.ts +1 -1
- package/src/database/connection.ts +73 -68
- package/src/database/index.ts +6 -6
- package/src/database/migrations/005_agent_runtime.sql +2 -0
- package/src/database/schema.ts +40 -38
- package/src/durable/DurableAgent.ts +85 -85
- package/src/durable/DurableAgentRepository.ts +409 -260
- package/src/durable/process.ts +22 -21
- package/src/durable/run.ts +61 -51
- package/src/durable/utils.ts +46 -41
- package/src/index.ts +144 -103
- package/src/providers/claude/ClaudeAgentMapper.ts +51 -50
- package/src/providers/claude/ClaudeCodeAdapter.ts +144 -136
- package/src/providers/claude/ClaudeSessionLocator.ts +291 -293
- package/src/providers/claude/ClaudeSessionParser.ts +322 -338
- package/src/providers/claude/durable/ClaudeCliProbe.ts +42 -37
- package/src/providers/claude/durable/ClaudePrintAgentService.ts +63 -50
- package/src/providers/claude/durable/ClaudePrintRunner.ts +79 -69
- package/src/providers/claude/durable/ClaudeStreamParser.ts +91 -62
- package/src/providers/codex/CodexAdapter.ts +205 -0
- package/src/providers/codex/CodexAgentMapper.ts +35 -0
- package/src/providers/codex/CodexSessionLocator.ts +279 -0
- package/src/providers/codex/CodexSessionMapping.ts +89 -0
- package/src/providers/codex/CodexSessionParser.ts +385 -0
- package/src/providers/codex/durable/CodexCliProbe.ts +50 -42
- package/src/providers/codex/durable/CodexPrintAgentService.ts +63 -49
- package/src/providers/codex/durable/CodexPrintRunner.ts +79 -69
- package/src/providers/codex/durable/CodexStreamParser.ts +97 -84
- package/src/providers/pi/PiAdapter.ts +183 -0
- package/src/providers/pi/PiAgentMapper.ts +36 -0
- package/src/providers/pi/PiSessionLocator.ts +95 -0
- package/src/providers/pi/PiSessionParser.ts +284 -0
- package/src/providers/pi/PiSessionTracker.ts +87 -0
- package/src/providers/pi/durable/PiCliProbe.ts +42 -34
- package/src/providers/pi/durable/PiPrintAgentService.ts +61 -53
- package/src/providers/pi/durable/PiPrintProtocol.ts +31 -29
- package/src/providers/pi/durable/PiPrintRunner.ts +75 -68
- package/src/providers/pi/durable/PiStreamParser.ts +82 -72
- package/src/readiness/AgentReadiness.ts +585 -513
- package/src/runtime/ManagedAgentRuntime.ts +266 -0
- package/src/runtime/RuntimeFactory.ts +13 -0
- package/src/runtime/errors.ts +50 -0
- package/src/runtime/herdr/HerdrAgentRuntime.ts +190 -0
- package/src/runtime/herdr/HerdrCliClient.ts +78 -0
- package/src/runtime/herdr/HerdrErrors.ts +9 -0
- package/src/runtime/herdr/HerdrResponseParsers.ts +76 -0
- package/src/runtime/herdr/HerdrRuntimeRef.ts +41 -0
- package/src/runtime/tmux/PidPolling.ts +34 -0
- package/src/runtime/tmux/TmuxAgentRuntime.ts +113 -0
- package/src/runtime/tmux/TmuxRuntimeRef.ts +9 -0
- package/src/runtime/types.ts +56 -0
- package/src/terminal/TerminalFocusManager.ts +215 -212
- package/src/terminal/TmuxManager.ts +99 -92
- package/src/terminal/TtyWriter.ts +203 -194
- package/src/terminal/index.ts +4 -4
- package/src/utils/AgentRegistry.ts +299 -238
- package/src/utils/agent-requests.ts +16 -16
- package/src/utils/agents.ts +41 -38
- package/src/utils/applescript.ts +4 -4
- package/src/utils/index.ts +12 -6
- package/src/utils/matching.ts +43 -43
- package/src/utils/process.ts +261 -258
- package/src/utils/session.ts +66 -66
- package/src/utils/sortAgents.ts +35 -33
- package/tsconfig.json +2 -8
- package/vitest.config.ts +16 -16
- package/.eslintrc.json +0 -31
- package/dist/__tests__/adapters/PiAdapter.test.js +0 -618
- package/dist/__tests__/adapters/PiAdapter.test.js.map +0 -1
- package/dist/__tests__/database/DurableAgentsDatabase.test.js +0 -128
- package/dist/__tests__/database/DurableAgentsDatabase.test.js.map +0 -1
- package/dist/adapters/CodexAdapter.d.ts +0 -109
- package/dist/adapters/CodexAdapter.d.ts.map +0 -1
- package/dist/adapters/CodexAdapter.js +0 -710
- package/dist/adapters/CodexAdapter.js.map +0 -1
- package/dist/adapters/PiAdapter.d.ts +0 -63
- package/dist/adapters/PiAdapter.d.ts.map +0 -1
- package/dist/adapters/PiAdapter.js +0 -453
- package/dist/adapters/PiAdapter.js.map +0 -1
- package/src/__tests__/adapters/PiAdapter.test.ts +0 -458
- package/src/__tests__/database/DurableAgentsDatabase.test.ts +0 -102
- package/src/adapters/CodexAdapter.ts +0 -923
- package/src/adapters/PiAdapter.ts +0 -598
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import * as fs from
|
|
2
|
-
import * as path from
|
|
3
|
-
import type { ConversationMessage } from
|
|
4
|
-
import { AgentStatus } from
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import type { ConversationMessage } from "../../adapters/AgentAdapter.js";
|
|
4
|
+
import { AgentStatus } from "../../adapters/AgentAdapter.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Content block within a Claude Code JSONL message entry.
|
|
8
8
|
* Handles text, tool_use, and tool_result block types.
|
|
9
9
|
*/
|
|
10
10
|
export interface ContentBlock {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
type?: string;
|
|
12
|
+
text?: string;
|
|
13
|
+
content?: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
input?: Record<string, unknown>;
|
|
16
|
+
tool_use_id?: string;
|
|
17
|
+
is_error?: boolean;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -26,12 +26,12 @@ export interface ContentBlock {
|
|
|
26
26
|
* - "last-prompt" / "file-history-snapshot" — metadata (not conversation state)
|
|
27
27
|
*/
|
|
28
28
|
export interface SessionEntry {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
type?: string;
|
|
30
|
+
timestamp?: string;
|
|
31
|
+
cwd?: string;
|
|
32
|
+
message?: {
|
|
33
|
+
content?: string | ContentBlock[];
|
|
34
|
+
};
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
@@ -39,16 +39,16 @@ export interface SessionEntry {
|
|
|
39
39
|
* Aggregates data from all entries into a single summary.
|
|
40
40
|
*/
|
|
41
41
|
export interface ClaudeSession {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
sessionId: string;
|
|
43
|
+
projectPath: string;
|
|
44
|
+
lastCwd?: string;
|
|
45
|
+
sessionStart: Date;
|
|
46
|
+
lastActive: Date;
|
|
47
|
+
lastEntryType?: string;
|
|
48
|
+
isInterrupted: boolean;
|
|
49
|
+
lastUserMessage?: string;
|
|
50
|
+
/** First meaningful user prompt in the session (post noise filter) */
|
|
51
|
+
firstUserMessage?: string;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
@@ -61,13 +61,7 @@ export interface ClaudeSession {
|
|
|
61
61
|
* last conversation turn — otherwise polling between writes lands on a
|
|
62
62
|
* UI-state entry and `determineStatus` falls through to UNKNOWN.
|
|
63
63
|
*/
|
|
64
|
-
const CONVERSATION_ENTRY_TYPES = new Set([
|
|
65
|
-
'user',
|
|
66
|
-
'assistant',
|
|
67
|
-
'system',
|
|
68
|
-
'progress',
|
|
69
|
-
'thinking',
|
|
70
|
-
]);
|
|
64
|
+
const CONVERSATION_ENTRY_TYPES = new Set(["user", "assistant", "system", "progress", "thinking"]);
|
|
71
65
|
|
|
72
66
|
/**
|
|
73
67
|
* Parses Claude Code session JSONL files into structured data.
|
|
@@ -77,314 +71,307 @@ const CONVERSATION_ENTRY_TYPES = new Set([
|
|
|
77
71
|
* event (user turn, assistant response, tool call, etc.).
|
|
78
72
|
*/
|
|
79
73
|
export class ClaudeSessionParser {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const allLines = content.trim().split('\n');
|
|
100
|
-
if (allLines.length === 0) {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const sessionStart = this.parseSessionStart(allLines[0]);
|
|
105
|
-
|
|
106
|
-
let lastEntryType: string | undefined;
|
|
107
|
-
let lastActive: Date | undefined;
|
|
108
|
-
let lastCwd: string | undefined;
|
|
109
|
-
let isInterrupted = false;
|
|
110
|
-
let lastUserMessage: string | undefined;
|
|
111
|
-
let firstUserMessage: string | undefined;
|
|
112
|
-
|
|
113
|
-
for (const line of allLines) {
|
|
114
|
-
try {
|
|
115
|
-
const entry: SessionEntry = JSON.parse(line);
|
|
116
|
-
|
|
117
|
-
if (entry.timestamp) {
|
|
118
|
-
const ts = new Date(entry.timestamp);
|
|
119
|
-
if (!Number.isNaN(ts.getTime())) {
|
|
120
|
-
lastActive = ts;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (typeof entry.cwd === 'string' && entry.cwd.trim().length > 0) {
|
|
125
|
-
lastCwd = entry.cwd;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (entry.type && CONVERSATION_ENTRY_TYPES.has(entry.type)) {
|
|
129
|
-
lastEntryType = entry.type;
|
|
130
|
-
|
|
131
|
-
if (entry.type === 'user') {
|
|
132
|
-
const msgContent = entry.message?.content;
|
|
133
|
-
isInterrupted =
|
|
134
|
-
Array.isArray(msgContent) &&
|
|
135
|
-
msgContent.some(
|
|
136
|
-
(c) =>
|
|
137
|
-
(c.type === 'text' &&
|
|
138
|
-
c.text?.includes('[Request interrupted')) ||
|
|
139
|
-
(c.type === 'tool_result' &&
|
|
140
|
-
c.content?.includes('[Request interrupted')),
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
const text = this.extractUserMessageText(msgContent);
|
|
144
|
-
if (text) {
|
|
145
|
-
lastUserMessage = text;
|
|
146
|
-
if (!firstUserMessage) {
|
|
147
|
-
firstUserMessage = text;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
} else {
|
|
151
|
-
isInterrupted = false;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
} catch {
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
74
|
+
/**
|
|
75
|
+
* Parse a session JSONL file into a ClaudeSession summary.
|
|
76
|
+
*
|
|
77
|
+
* Iterates all lines to extract: session start time (from first entry),
|
|
78
|
+
* last activity timestamp, last entry type (for status), whether the
|
|
79
|
+
* session was interrupted, and the last meaningful user message.
|
|
80
|
+
*
|
|
81
|
+
* Returns null if the file is unreadable or empty.
|
|
82
|
+
*/
|
|
83
|
+
readSession(filePath: string, projectPath: string): ClaudeSession | null {
|
|
84
|
+
const sessionId = path.basename(filePath, ".jsonl");
|
|
85
|
+
|
|
86
|
+
let content: string;
|
|
87
|
+
try {
|
|
88
|
+
content = fs.readFileSync(filePath, "utf-8");
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
158
92
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
lastCwd,
|
|
163
|
-
sessionStart: sessionStart || lastActive || new Date(),
|
|
164
|
-
lastActive: lastActive || new Date(),
|
|
165
|
-
lastEntryType,
|
|
166
|
-
isInterrupted,
|
|
167
|
-
lastUserMessage,
|
|
168
|
-
firstUserMessage,
|
|
169
|
-
};
|
|
93
|
+
const allLines = content.trim().split("\n");
|
|
94
|
+
if (allLines.length === 0) {
|
|
95
|
+
return null;
|
|
170
96
|
}
|
|
171
97
|
|
|
172
|
-
|
|
173
|
-
* Determine agent status from parsed session state.
|
|
174
|
-
*
|
|
175
|
-
* Status mapping:
|
|
176
|
-
* - "user" + interrupted → WAITING (agent finished, awaiting new input)
|
|
177
|
-
* - "user" + not interrupted → RUNNING (agent is processing)
|
|
178
|
-
* - "progress" / "thinking" → RUNNING
|
|
179
|
-
* - "assistant" → WAITING (agent responded, awaiting user)
|
|
180
|
-
* - "system" → IDLE
|
|
181
|
-
*/
|
|
182
|
-
determineStatus(session: ClaudeSession): AgentStatus {
|
|
183
|
-
if (!session.lastEntryType) {
|
|
184
|
-
return AgentStatus.UNKNOWN;
|
|
185
|
-
}
|
|
98
|
+
const sessionStart = this.parseSessionStart(allLines[0]);
|
|
186
99
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
100
|
+
let lastEntryType: string | undefined;
|
|
101
|
+
let lastActive: Date | undefined;
|
|
102
|
+
let lastCwd: string | undefined;
|
|
103
|
+
let isInterrupted = false;
|
|
104
|
+
let lastUserMessage: string | undefined;
|
|
105
|
+
let firstUserMessage: string | undefined;
|
|
192
106
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
) {
|
|
197
|
-
return AgentStatus.RUNNING;
|
|
198
|
-
}
|
|
107
|
+
for (const line of allLines) {
|
|
108
|
+
try {
|
|
109
|
+
const entry: SessionEntry = JSON.parse(line);
|
|
199
110
|
|
|
200
|
-
if (
|
|
201
|
-
|
|
111
|
+
if (entry.timestamp) {
|
|
112
|
+
const ts = new Date(entry.timestamp);
|
|
113
|
+
if (!Number.isNaN(ts.getTime())) {
|
|
114
|
+
lastActive = ts;
|
|
115
|
+
}
|
|
202
116
|
}
|
|
203
117
|
|
|
204
|
-
if (
|
|
205
|
-
|
|
118
|
+
if (typeof entry.cwd === "string" && entry.cwd.trim().length > 0) {
|
|
119
|
+
lastCwd = entry.cwd;
|
|
206
120
|
}
|
|
207
121
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const lines = content.trim().split('\n');
|
|
228
|
-
const messages: ConversationMessage[] = [];
|
|
229
|
-
|
|
230
|
-
for (const line of lines) {
|
|
231
|
-
let entry: SessionEntry;
|
|
232
|
-
try {
|
|
233
|
-
entry = JSON.parse(line);
|
|
234
|
-
} catch {
|
|
235
|
-
continue;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
let role: ConversationMessage['role'];
|
|
239
|
-
if (entry.type === 'user') {
|
|
240
|
-
role = 'user';
|
|
241
|
-
} else if (entry.type === 'assistant') {
|
|
242
|
-
role = 'assistant';
|
|
243
|
-
} else if (entry.type === 'system') {
|
|
244
|
-
role = 'system';
|
|
245
|
-
} else {
|
|
246
|
-
continue;
|
|
122
|
+
if (entry.type && CONVERSATION_ENTRY_TYPES.has(entry.type)) {
|
|
123
|
+
lastEntryType = entry.type;
|
|
124
|
+
|
|
125
|
+
if (entry.type === "user") {
|
|
126
|
+
const msgContent = entry.message?.content;
|
|
127
|
+
isInterrupted =
|
|
128
|
+
Array.isArray(msgContent) &&
|
|
129
|
+
msgContent.some(
|
|
130
|
+
(c) =>
|
|
131
|
+
(c.type === "text" && c.text?.includes("[Request interrupted")) ||
|
|
132
|
+
(c.type === "tool_result" && c.content?.includes("[Request interrupted")),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const text = this.extractUserMessageText(msgContent);
|
|
136
|
+
if (text) {
|
|
137
|
+
lastUserMessage = text;
|
|
138
|
+
if (!firstUserMessage) {
|
|
139
|
+
firstUserMessage = text;
|
|
140
|
+
}
|
|
247
141
|
}
|
|
142
|
+
} else {
|
|
143
|
+
isInterrupted = false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
248
150
|
|
|
249
|
-
|
|
250
|
-
|
|
151
|
+
return {
|
|
152
|
+
sessionId,
|
|
153
|
+
projectPath: projectPath || lastCwd || "",
|
|
154
|
+
lastCwd,
|
|
155
|
+
sessionStart: sessionStart || lastActive || new Date(),
|
|
156
|
+
lastActive: lastActive || new Date(),
|
|
157
|
+
lastEntryType,
|
|
158
|
+
isInterrupted,
|
|
159
|
+
lastUserMessage,
|
|
160
|
+
firstUserMessage,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Determine agent status from parsed session state.
|
|
166
|
+
*
|
|
167
|
+
* Status mapping:
|
|
168
|
+
* - "user" + interrupted → WAITING (agent finished, awaiting new input)
|
|
169
|
+
* - "user" + not interrupted → RUNNING (agent is processing)
|
|
170
|
+
* - "progress" / "thinking" → RUNNING
|
|
171
|
+
* - "assistant" → WAITING (agent responded, awaiting user)
|
|
172
|
+
* - "system" → IDLE
|
|
173
|
+
*/
|
|
174
|
+
determineStatus(session: ClaudeSession): AgentStatus {
|
|
175
|
+
if (!session.lastEntryType) {
|
|
176
|
+
return AgentStatus.UNKNOWN;
|
|
177
|
+
}
|
|
251
178
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
timestamp: entry.timestamp,
|
|
256
|
-
});
|
|
257
|
-
}
|
|
179
|
+
if (session.lastEntryType === "user") {
|
|
180
|
+
return session.isInterrupted ? AgentStatus.WAITING : AgentStatus.RUNNING;
|
|
181
|
+
}
|
|
258
182
|
|
|
259
|
-
|
|
183
|
+
if (session.lastEntryType === "progress" || session.lastEntryType === "thinking") {
|
|
184
|
+
return AgentStatus.RUNNING;
|
|
260
185
|
}
|
|
261
186
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
*
|
|
265
|
-
* Claude Code may emit a "file-history-snapshot" as the first entry,
|
|
266
|
-
* which stores its timestamp inside "snapshot.timestamp" rather than
|
|
267
|
-
* at the root level.
|
|
268
|
-
*/
|
|
269
|
-
private parseSessionStart(firstLine: string): Date | null {
|
|
270
|
-
try {
|
|
271
|
-
const firstEntry = JSON.parse(firstLine);
|
|
272
|
-
const rawTs: string | undefined =
|
|
273
|
-
firstEntry.timestamp || firstEntry.snapshot?.timestamp;
|
|
274
|
-
if (rawTs) {
|
|
275
|
-
const ts = new Date(rawTs);
|
|
276
|
-
if (!Number.isNaN(ts.getTime())) {
|
|
277
|
-
return ts;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
} catch {
|
|
281
|
-
/* malformed first line */
|
|
282
|
-
}
|
|
283
|
-
return null;
|
|
187
|
+
if (session.lastEntryType === "assistant") {
|
|
188
|
+
return AgentStatus.WAITING;
|
|
284
189
|
}
|
|
285
190
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
* Handles multiple formats:
|
|
290
|
-
* - Plain string content
|
|
291
|
-
* - Array of content blocks (extracts first text block)
|
|
292
|
-
* - Skill slash-commands (<command-message> tags)
|
|
293
|
-
* - Expanded skill content (extracts ARGUMENTS line)
|
|
294
|
-
* - Filters noise messages (interruptions, tool loaded, session continued)
|
|
295
|
-
*/
|
|
296
|
-
private extractUserMessageText(
|
|
297
|
-
content: string | Array<{ type?: string; text?: string }> | undefined,
|
|
298
|
-
): string | undefined {
|
|
299
|
-
if (!content) {
|
|
300
|
-
return undefined;
|
|
301
|
-
}
|
|
191
|
+
if (session.lastEntryType === "system") {
|
|
192
|
+
return AgentStatus.IDLE;
|
|
193
|
+
}
|
|
302
194
|
|
|
303
|
-
|
|
195
|
+
return AgentStatus.UNKNOWN;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Read the full conversation from a session JSONL file.
|
|
200
|
+
*
|
|
201
|
+
* Default mode returns only text content from user/assistant/system messages.
|
|
202
|
+
* Verbose mode also includes tool_use and tool_result blocks.
|
|
203
|
+
*/
|
|
204
|
+
getConversation(sessionFilePath: string, options?: { verbose?: boolean }): ConversationMessage[] {
|
|
205
|
+
const verbose = options?.verbose ?? false;
|
|
206
|
+
|
|
207
|
+
let content: string;
|
|
208
|
+
try {
|
|
209
|
+
content = fs.readFileSync(sessionFilePath, "utf-8");
|
|
210
|
+
} catch {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
304
213
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
214
|
+
const lines = content.trim().split("\n");
|
|
215
|
+
const messages: ConversationMessage[] = [];
|
|
216
|
+
|
|
217
|
+
for (const line of lines) {
|
|
218
|
+
let entry: SessionEntry;
|
|
219
|
+
try {
|
|
220
|
+
entry = JSON.parse(line);
|
|
221
|
+
} catch {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
let role: ConversationMessage["role"];
|
|
226
|
+
if (entry.type === "user") {
|
|
227
|
+
role = "user";
|
|
228
|
+
} else if (entry.type === "assistant") {
|
|
229
|
+
role = "assistant";
|
|
230
|
+
} else if (entry.type === "system") {
|
|
231
|
+
role = "system";
|
|
232
|
+
} else {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const text = this.extractConversationContent(entry.message?.content, role, verbose);
|
|
237
|
+
if (!text) continue;
|
|
238
|
+
|
|
239
|
+
messages.push({
|
|
240
|
+
role,
|
|
241
|
+
content: text,
|
|
242
|
+
timestamp: entry.timestamp,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
315
245
|
|
|
316
|
-
|
|
317
|
-
|
|
246
|
+
return messages;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Parse session start time from the first JSONL line.
|
|
251
|
+
*
|
|
252
|
+
* Claude Code may emit a "file-history-snapshot" as the first entry,
|
|
253
|
+
* which stores its timestamp inside "snapshot.timestamp" rather than
|
|
254
|
+
* at the root level.
|
|
255
|
+
*/
|
|
256
|
+
private parseSessionStart(firstLine: string): Date | null {
|
|
257
|
+
try {
|
|
258
|
+
const firstEntry = JSON.parse(firstLine);
|
|
259
|
+
const rawTs: string | undefined = firstEntry.timestamp || firstEntry.snapshot?.timestamp;
|
|
260
|
+
if (rawTs) {
|
|
261
|
+
const ts = new Date(rawTs);
|
|
262
|
+
if (!Number.isNaN(ts.getTime())) {
|
|
263
|
+
return ts;
|
|
318
264
|
}
|
|
265
|
+
}
|
|
266
|
+
} catch {
|
|
267
|
+
/* malformed first line */
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Extract meaningful text from a user message content field.
|
|
274
|
+
*
|
|
275
|
+
* Handles multiple formats:
|
|
276
|
+
* - Plain string content
|
|
277
|
+
* - Array of content blocks (extracts first text block)
|
|
278
|
+
* - Skill slash-commands (<command-message> tags)
|
|
279
|
+
* - Expanded skill content (extracts ARGUMENTS line)
|
|
280
|
+
* - Filters noise messages (interruptions, tool loaded, session continued)
|
|
281
|
+
*/
|
|
282
|
+
private extractUserMessageText(
|
|
283
|
+
content: string | Array<{ type?: string; text?: string }> | undefined,
|
|
284
|
+
): string | undefined {
|
|
285
|
+
if (!content) {
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
319
288
|
|
|
320
|
-
|
|
321
|
-
return this.parseCommandMessage(raw);
|
|
322
|
-
}
|
|
289
|
+
let raw: string | undefined;
|
|
323
290
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
291
|
+
if (typeof content === "string") {
|
|
292
|
+
raw = content.trim();
|
|
293
|
+
} else if (Array.isArray(content)) {
|
|
294
|
+
for (const block of content) {
|
|
295
|
+
if (block.type === "text" && block.text?.trim()) {
|
|
296
|
+
raw = block.text.trim();
|
|
297
|
+
break;
|
|
327
298
|
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
328
301
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
302
|
+
if (!raw) {
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
332
305
|
|
|
333
|
-
|
|
306
|
+
if (raw.startsWith("<command-message>")) {
|
|
307
|
+
return this.parseCommandMessage(raw);
|
|
334
308
|
}
|
|
335
309
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
private parseCommandMessage(raw: string): string | undefined {
|
|
340
|
-
const nameMatch = raw.match(/<command-name>([^<]+)<\/command-name>/);
|
|
341
|
-
const argsMatch = raw.match(/<command-args>([^<]+)<\/command-args>/);
|
|
342
|
-
const name = nameMatch?.[1]?.trim();
|
|
343
|
-
if (!name) {
|
|
344
|
-
return undefined;
|
|
345
|
-
}
|
|
346
|
-
const args = argsMatch?.[1]?.trim();
|
|
347
|
-
return args ? `${name} ${args}` : name;
|
|
310
|
+
if (raw.startsWith("Base directory for this skill:")) {
|
|
311
|
+
const argsMatch = raw.match(/\nARGUMENTS:\s*(.+)/);
|
|
312
|
+
return argsMatch?.[1]?.trim() || undefined;
|
|
348
313
|
}
|
|
349
314
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
private extractConversationContent(
|
|
354
|
-
content: string | ContentBlock[] | undefined,
|
|
355
|
-
role: ConversationMessage['role'],
|
|
356
|
-
verbose: boolean,
|
|
357
|
-
): string | undefined {
|
|
358
|
-
if (!content) return undefined;
|
|
359
|
-
|
|
360
|
-
if (typeof content === 'string') {
|
|
361
|
-
const cleaned = stripHarnessTags(content);
|
|
362
|
-
if (role === 'user' && isNoiseMessage(cleaned)) return undefined;
|
|
363
|
-
return cleaned || undefined;
|
|
364
|
-
}
|
|
315
|
+
if (isNoiseMessage(raw)) {
|
|
316
|
+
return undefined;
|
|
317
|
+
}
|
|
365
318
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
319
|
+
return raw;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Parse a <command-message> string into "/command args" format.
|
|
324
|
+
*/
|
|
325
|
+
private parseCommandMessage(raw: string): string | undefined {
|
|
326
|
+
const nameMatch = raw.match(/<command-name>([^<]+)<\/command-name>/);
|
|
327
|
+
const argsMatch = raw.match(/<command-args>([^<]+)<\/command-args>/);
|
|
328
|
+
const name = nameMatch?.[1]?.trim();
|
|
329
|
+
if (!name) {
|
|
330
|
+
return undefined;
|
|
331
|
+
}
|
|
332
|
+
const args = argsMatch?.[1]?.trim();
|
|
333
|
+
return args ? `${name} ${args}` : name;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Extract displayable content from a message content field for conversation output.
|
|
338
|
+
*/
|
|
339
|
+
private extractConversationContent(
|
|
340
|
+
content: string | ContentBlock[] | undefined,
|
|
341
|
+
role: ConversationMessage["role"],
|
|
342
|
+
verbose: boolean,
|
|
343
|
+
): string | undefined {
|
|
344
|
+
if (!content) return undefined;
|
|
345
|
+
|
|
346
|
+
if (typeof content === "string") {
|
|
347
|
+
const cleaned = stripHarnessTags(content);
|
|
348
|
+
if (role === "user" && isNoiseMessage(cleaned)) return undefined;
|
|
349
|
+
return cleaned || undefined;
|
|
350
|
+
}
|
|
385
351
|
|
|
386
|
-
|
|
352
|
+
if (!Array.isArray(content)) return undefined;
|
|
353
|
+
|
|
354
|
+
const parts: string[] = [];
|
|
355
|
+
|
|
356
|
+
for (const block of content) {
|
|
357
|
+
if (block.type === "text" && block.text?.trim()) {
|
|
358
|
+
const cleaned = stripHarnessTags(block.text);
|
|
359
|
+
if (!cleaned) continue;
|
|
360
|
+
if (role === "user" && isNoiseMessage(cleaned)) continue;
|
|
361
|
+
parts.push(cleaned);
|
|
362
|
+
} else if (block.type === "tool_use" && verbose) {
|
|
363
|
+
const inputSummary =
|
|
364
|
+
block.input?.file_path || block.input?.pattern || block.input?.command || "";
|
|
365
|
+
parts.push(`[Tool: ${block.name}]${inputSummary ? " " + inputSummary : ""}`);
|
|
366
|
+
} else if (block.type === "tool_result" && verbose) {
|
|
367
|
+
const truncated = truncateToolResult(block.content || "");
|
|
368
|
+
const prefix = block.is_error ? "[Tool Error]" : "[Tool Result]";
|
|
369
|
+
parts.push(`${prefix} ${truncated}`);
|
|
370
|
+
}
|
|
387
371
|
}
|
|
372
|
+
|
|
373
|
+
return parts.length > 0 ? parts.join("\n") : undefined;
|
|
374
|
+
}
|
|
388
375
|
}
|
|
389
376
|
|
|
390
377
|
/**
|
|
@@ -393,25 +380,22 @@ export class ClaudeSessionParser {
|
|
|
393
380
|
* stdout), not meaningful conversation content.
|
|
394
381
|
*/
|
|
395
382
|
const HARNESS_DROP_TAGS = [
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
383
|
+
"system-reminder",
|
|
384
|
+
"local-command-stdout",
|
|
385
|
+
"local-command-stderr",
|
|
386
|
+
"user-prompt-submit-hook",
|
|
387
|
+
"command-stdout",
|
|
388
|
+
"command-stderr",
|
|
389
|
+
"bash-input",
|
|
390
|
+
"bash-stdout",
|
|
391
|
+
"bash-stderr",
|
|
392
|
+
"command-message",
|
|
406
393
|
] as const;
|
|
407
394
|
|
|
408
|
-
const HARNESS_DROP_RE = new RegExp(
|
|
409
|
-
`<(${HARNESS_DROP_TAGS.join('|')})>[\\s\\S]*?</\\1>`,
|
|
410
|
-
'g',
|
|
411
|
-
);
|
|
395
|
+
const HARNESS_DROP_RE = new RegExp(`<(${HARNESS_DROP_TAGS.join("|")})>[\\s\\S]*?</\\1>`, "g");
|
|
412
396
|
|
|
413
397
|
const COMMAND_INVOCATION_RE =
|
|
414
|
-
|
|
398
|
+
/<command-name>([^<]+)<\/command-name>(?:\s*<command-args>([\s\S]*?)<\/command-args>)?/g;
|
|
415
399
|
|
|
416
400
|
/**
|
|
417
401
|
* Remove harness-injected XML blocks from message text and collapse
|
|
@@ -421,28 +405,28 @@ const COMMAND_INVOCATION_RE =
|
|
|
421
405
|
* survives stripping.
|
|
422
406
|
*/
|
|
423
407
|
function stripHarnessTags(text: string): string {
|
|
424
|
-
|
|
408
|
+
let out = text.replace(HARNESS_DROP_RE, "");
|
|
425
409
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
410
|
+
out = out.replace(COMMAND_INVOCATION_RE, (_match, rawName: string, rawArgs?: string) => {
|
|
411
|
+
const name = rawName.trim();
|
|
412
|
+
const args = rawArgs?.trim();
|
|
413
|
+
return args ? `${name} ${args}` : name;
|
|
414
|
+
});
|
|
431
415
|
|
|
432
|
-
|
|
416
|
+
return out.replace(/\n{3,}/g, "\n\n").trim();
|
|
433
417
|
}
|
|
434
418
|
|
|
435
419
|
/** Check if a message is noise (not a meaningful user intent). */
|
|
436
420
|
function isNoiseMessage(text: string): boolean {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
421
|
+
return (
|
|
422
|
+
text.startsWith("[Request interrupted") ||
|
|
423
|
+
text === "Tool loaded." ||
|
|
424
|
+
text.startsWith("This session is being continued")
|
|
425
|
+
);
|
|
442
426
|
}
|
|
443
427
|
|
|
444
428
|
function truncateToolResult(content: string, maxLength = 200): string {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
429
|
+
const firstLine = content.split("\n")[0] || "";
|
|
430
|
+
if (firstLine.length <= maxLength) return firstLine;
|
|
431
|
+
return firstLine.slice(0, maxLength - 3) + "...";
|
|
448
432
|
}
|