@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,130 +1,176 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import { randomUUID } from
|
|
3
|
-
import { DatabaseConnection, DEFAULT_AGENT_REGISTRY_DB_PATH } from
|
|
4
|
-
import { AGENT_MODES, CodexPrintError, type DurableActiveRun, type DurableAgent, type DurableProvider, type ProcessIdentity, type DurableRunStatus, type DurableSessionHealth } from './DurableAgent.js';
|
|
5
|
-
import { LocalProcessInspector, type ProcessInspector } from './process.js';
|
|
6
|
-
import { isUuid } from './utils.js';
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import { randomUUID } from "crypto";
|
|
3
|
+
import { DatabaseConnection, DEFAULT_AGENT_REGISTRY_DB_PATH } from "../database/index.js";
|
|
7
4
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
AGENT_MODES,
|
|
6
|
+
CodexPrintError,
|
|
7
|
+
type DurableActiveRun,
|
|
8
|
+
type DurableAgent,
|
|
9
|
+
type DurableProvider,
|
|
10
|
+
type ProcessIdentity,
|
|
11
|
+
type DurableRunStatus,
|
|
12
|
+
type DurableSessionHealth,
|
|
13
|
+
} from "./DurableAgent.js";
|
|
14
|
+
import { LocalProcessInspector, type ProcessInspector } from "./process.js";
|
|
15
|
+
import { isUuid } from "./utils.js";
|
|
16
|
+
import {
|
|
17
|
+
DurableAgentBusyError,
|
|
18
|
+
DurableAgentNameConflictError,
|
|
19
|
+
DurableAgentNotFoundError,
|
|
20
|
+
DurableAgentRepositoryError,
|
|
21
|
+
} from "./DurableAgent.js";
|
|
13
22
|
|
|
14
23
|
interface DurableAgentRow {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
provider: DurableProvider;
|
|
27
|
+
mode: typeof AGENT_MODES.DURABLE;
|
|
28
|
+
cwd: string;
|
|
29
|
+
provider_session_id: string | null;
|
|
30
|
+
state: DurableAgent["state"];
|
|
31
|
+
session_health: DurableSessionHealth;
|
|
32
|
+
created_at: string;
|
|
33
|
+
updated_at: string;
|
|
34
|
+
last_active_at: string | null;
|
|
35
|
+
last_result_status: DurableRunStatus | null;
|
|
36
|
+
last_result_completed_at: string | null;
|
|
37
|
+
last_result_exit_code: number | null;
|
|
38
|
+
last_result_summary: string | null;
|
|
39
|
+
active_run_token: string | null;
|
|
40
|
+
active_owner_pid: number | null;
|
|
41
|
+
active_owner_started_at: string | null;
|
|
42
|
+
active_provider_pid: number | null;
|
|
43
|
+
active_provider_started_at: string | null;
|
|
44
|
+
active_run_started_at: string | null;
|
|
21
45
|
}
|
|
22
46
|
|
|
23
|
-
export interface CreateDurableAgentInput {
|
|
47
|
+
export interface CreateDurableAgentInput {
|
|
48
|
+
name: string;
|
|
49
|
+
cwd: string;
|
|
50
|
+
provider?: DurableProvider;
|
|
51
|
+
}
|
|
24
52
|
|
|
25
53
|
export interface DurableAgentRepositoryOptions {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
54
|
+
dbPath?: string;
|
|
55
|
+
readonly?: boolean;
|
|
56
|
+
/** @deprecated SQLite busy_timeout replaces filesystem lock polling. */
|
|
57
|
+
lockTimeoutMs?: number;
|
|
58
|
+
now?: () => Date;
|
|
59
|
+
processInspector?: ProcessInspector;
|
|
60
|
+
/** @deprecated Active ownership is committed atomically. */
|
|
61
|
+
incompleteLockGraceMs?: number;
|
|
62
|
+
/** @deprecated SQLite transactions replace mutation lock directories. */
|
|
63
|
+
mutationLockStaleMs?: number;
|
|
36
64
|
}
|
|
37
65
|
|
|
38
|
-
export { LocalProcessInspector } from
|
|
39
|
-
export type { ProcessInspector } from
|
|
66
|
+
export { LocalProcessInspector } from "./process.js";
|
|
67
|
+
export type { ProcessInspector } from "./process.js";
|
|
40
68
|
export interface DurableRunCompletion {
|
|
41
|
-
|
|
69
|
+
status: DurableRunStatus;
|
|
70
|
+
exitCode: number | null;
|
|
71
|
+
summary: string;
|
|
72
|
+
sessionHealth: DurableSessionHealth;
|
|
42
73
|
}
|
|
43
74
|
|
|
44
75
|
export class DurableAgentRepository {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
76
|
+
readonly dbPath: string;
|
|
77
|
+
private readonly now: () => Date;
|
|
78
|
+
private readonly processInspector: ProcessInspector;
|
|
79
|
+
private readonly readonly: boolean;
|
|
80
|
+
private readonly db: DatabaseConnection;
|
|
50
81
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
82
|
+
constructor(options: DurableAgentRepositoryOptions = {}) {
|
|
83
|
+
this.dbPath = options.dbPath ?? DEFAULT_AGENT_REGISTRY_DB_PATH;
|
|
84
|
+
this.now = options.now ?? (() => new Date());
|
|
85
|
+
this.processInspector = options.processInspector ?? new LocalProcessInspector();
|
|
86
|
+
this.readonly = options.readonly ?? false;
|
|
87
|
+
try {
|
|
88
|
+
this.db = new DatabaseConnection({ dbPath: this.dbPath, readonly: this.readonly });
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (error instanceof DurableAgentRepositoryError) throw error;
|
|
91
|
+
throw new DurableAgentRepositoryError(
|
|
92
|
+
`Cannot open durable-agent database: ${(error as Error).message}`,
|
|
93
|
+
);
|
|
62
94
|
}
|
|
95
|
+
}
|
|
63
96
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
97
|
+
async create(input: CreateDurableAgentInput): Promise<DurableAgent> {
|
|
98
|
+
this.assertWritable();
|
|
99
|
+
const cwd = this.canonicalDirectory(input.cwd);
|
|
100
|
+
const timestamp = this.now().toISOString();
|
|
101
|
+
const id = randomUUID();
|
|
102
|
+
const provider = input.provider ?? "claude";
|
|
103
|
+
let providerSessionId = provider === "codex" ? null : randomUUID();
|
|
104
|
+
while (providerSessionId === id) providerSessionId = randomUUID();
|
|
105
|
+
try {
|
|
106
|
+
this.db.execute(
|
|
107
|
+
`INSERT INTO durable_agents (
|
|
74
108
|
id, name, provider, mode, cwd, provider_session_id, state, session_health, created_at, updated_at
|
|
75
109
|
) VALUES (?, ?, ?, ?, ?, ?, 'ready', 'uninitialized', ?, ?)`,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
110
|
+
[
|
|
111
|
+
id,
|
|
112
|
+
input.name,
|
|
113
|
+
provider,
|
|
114
|
+
AGENT_MODES.DURABLE,
|
|
115
|
+
cwd,
|
|
116
|
+
providerSessionId,
|
|
117
|
+
timestamp,
|
|
118
|
+
timestamp,
|
|
119
|
+
],
|
|
120
|
+
);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (/UNIQUE constraint failed: durable_agents\.name/i.test((error as Error).message)) {
|
|
123
|
+
throw new DurableAgentNameConflictError(input.name);
|
|
124
|
+
}
|
|
125
|
+
throw this.storageError("Failed to create durable agent", error);
|
|
84
126
|
}
|
|
127
|
+
return this.requireById(id);
|
|
128
|
+
}
|
|
85
129
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
130
|
+
async list(): Promise<DurableAgent[]> {
|
|
131
|
+
if (!this.readonly) await this.reconcile();
|
|
132
|
+
return this.listRaw();
|
|
133
|
+
}
|
|
90
134
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
135
|
+
async getById(id: string): Promise<DurableAgent | null> {
|
|
136
|
+
if (!this.readonly) await this.reconcile();
|
|
137
|
+
return this.findById(id);
|
|
138
|
+
}
|
|
95
139
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
140
|
+
async resolve(reference: string): Promise<DurableAgent | DurableAgent[] | null> {
|
|
141
|
+
const agents = await this.list();
|
|
142
|
+
const byId = agents.find((agent) => agent.id === reference);
|
|
143
|
+
if (byId) return byId;
|
|
144
|
+
const matches = agents.filter((agent) => agent.name.toLowerCase() === reference.toLowerCase());
|
|
145
|
+
return matches.length === 0 ? null : matches.length === 1 ? matches[0]! : matches;
|
|
146
|
+
}
|
|
103
147
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
148
|
+
async acquireRun(id: string): Promise<{ agent: DurableAgent; token: string }> {
|
|
149
|
+
this.assertWritable();
|
|
150
|
+
const snapshot = this.findById(id);
|
|
151
|
+
if (!snapshot) throw new DurableAgentNotFoundError(id);
|
|
152
|
+
this.validateBoundCwd(snapshot.cwd);
|
|
153
|
+
const observed = snapshot.activeRun;
|
|
154
|
+
const observedLive = observed ? this.isActive(observed) : false;
|
|
155
|
+
if (observedLive) throw new DurableAgentBusyError(id, snapshot.name);
|
|
156
|
+
const owner = this.processInspector.getIdentity(process.pid);
|
|
157
|
+
if (!owner)
|
|
158
|
+
throw new DurableAgentRepositoryError("Cannot determine the current process identity.");
|
|
159
|
+
const token = randomUUID();
|
|
160
|
+
const startedAt = this.now().toISOString();
|
|
161
|
+
let recovered = false;
|
|
162
|
+
try {
|
|
163
|
+
this.immediate(() => {
|
|
164
|
+
const current = this.findById(id);
|
|
165
|
+
if (!current) throw new DurableAgentNotFoundError(id);
|
|
166
|
+
if (current.state === "running") {
|
|
167
|
+
if (!observed || current.activeRun?.token !== observed.token || observedLive) {
|
|
168
|
+
throw new DurableAgentBusyError(id, current.name);
|
|
169
|
+
}
|
|
170
|
+
recovered = true;
|
|
171
|
+
}
|
|
172
|
+
const changed = this.db.execute(
|
|
173
|
+
`UPDATE durable_agents SET
|
|
128
174
|
state = 'running', active_run_token = ?, active_owner_pid = ?, active_owner_started_at = ?,
|
|
129
175
|
active_provider_pid = NULL, active_provider_started_at = NULL, active_run_started_at = ?, updated_at = ?,
|
|
130
176
|
session_health = CASE WHEN state = 'running' THEN 'unknown' ELSE session_health END,
|
|
@@ -135,202 +181,305 @@ export class DurableAgentRepository {
|
|
|
135
181
|
WHERE id = ? AND (state <> 'running' OR (
|
|
136
182
|
active_run_token = ? AND active_owner_started_at = ? AND active_run_started_at = ?
|
|
137
183
|
))
|
|
138
|
-
`,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
184
|
+
`,
|
|
185
|
+
[
|
|
186
|
+
token,
|
|
187
|
+
owner.pid,
|
|
188
|
+
owner.startedAt,
|
|
189
|
+
startedAt,
|
|
190
|
+
startedAt,
|
|
191
|
+
startedAt,
|
|
192
|
+
id,
|
|
193
|
+
observed?.token ?? null,
|
|
194
|
+
observed?.owner.startedAt ?? null,
|
|
195
|
+
observed?.startedAt ?? null,
|
|
196
|
+
],
|
|
197
|
+
);
|
|
198
|
+
if (changed.changes !== 1) throw new DurableAgentBusyError(id, current.name);
|
|
199
|
+
});
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (error instanceof DurableAgentBusyError || error instanceof DurableAgentNotFoundError)
|
|
202
|
+
throw error;
|
|
203
|
+
if (/busy|locked/i.test((error as Error).message))
|
|
204
|
+
throw new DurableAgentBusyError(id, snapshot.name);
|
|
205
|
+
throw this.storageError("Failed to acquire durable-agent run", error);
|
|
152
206
|
}
|
|
207
|
+
const agent = this.requireById(id);
|
|
208
|
+
if (recovered && agent.lastResult?.status !== "interrupted") {
|
|
209
|
+
throw new DurableAgentRepositoryError("Failed to record interrupted print run.");
|
|
210
|
+
}
|
|
211
|
+
return { agent, token };
|
|
212
|
+
}
|
|
153
213
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
214
|
+
async recordProviderProcess(id: string, token: string, identity: ProcessIdentity): Promise<void> {
|
|
215
|
+
this.assertWritable();
|
|
216
|
+
const changed = this.db.execute(
|
|
217
|
+
`UPDATE durable_agents SET
|
|
157
218
|
active_provider_pid = ?, active_provider_started_at = ?, updated_at = ?
|
|
158
219
|
WHERE id = ? AND state = 'running' AND active_run_token = ?`,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
220
|
+
[identity.pid, identity.startedAt, this.now().toISOString(), id, token],
|
|
221
|
+
);
|
|
222
|
+
if (changed.changes !== 1)
|
|
223
|
+
throw new DurableAgentRepositoryError("Print run ownership changed.");
|
|
224
|
+
}
|
|
162
225
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
226
|
+
async bindProviderSession(
|
|
227
|
+
id: string,
|
|
228
|
+
token: string,
|
|
229
|
+
providerSessionId: string,
|
|
230
|
+
): Promise<DurableAgent> {
|
|
231
|
+
this.assertWritable();
|
|
232
|
+
if (!isUuid(providerSessionId)) {
|
|
233
|
+
throw new DurableAgentRepositoryError("Invalid provider session id.");
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
this.immediate(() => {
|
|
237
|
+
const agent = this.findById(id);
|
|
238
|
+
if (!agent) throw new DurableAgentNotFoundError(id);
|
|
239
|
+
if (agent.provider !== "codex") {
|
|
240
|
+
throw new DurableAgentRepositoryError(
|
|
241
|
+
"Only Codex durable sessions can be bound after creation.",
|
|
242
|
+
);
|
|
167
243
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
if (agent.providerSessionId === providerSessionId) return;
|
|
182
|
-
const changed = this.db.execute(`UPDATE durable_agents SET provider_session_id = ?, updated_at = ?
|
|
244
|
+
if (agent.activeRun?.token !== token) {
|
|
245
|
+
throw new DurableAgentRepositoryError("Print run ownership changed.");
|
|
246
|
+
}
|
|
247
|
+
if (agent.providerSessionId !== null && agent.providerSessionId !== providerSessionId) {
|
|
248
|
+
throw new CodexPrintError(
|
|
249
|
+
"Durable agent provider session identity does not match.",
|
|
250
|
+
"CODEX_SESSION_MISMATCH",
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
if (agent.providerSessionId === providerSessionId) return;
|
|
254
|
+
const changed = this.db.execute(
|
|
255
|
+
`UPDATE durable_agents SET provider_session_id = ?, updated_at = ?
|
|
183
256
|
WHERE id = ? AND provider = 'codex' AND state = 'running' AND active_run_token = ?
|
|
184
257
|
AND provider_session_id IS NULL`,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
258
|
+
[providerSessionId, this.now().toISOString(), id, token],
|
|
259
|
+
);
|
|
260
|
+
if (changed.changes !== 1)
|
|
261
|
+
throw new DurableAgentRepositoryError("Print run ownership changed.");
|
|
262
|
+
});
|
|
263
|
+
} catch (error) {
|
|
264
|
+
if (
|
|
265
|
+
error instanceof DurableAgentRepositoryError ||
|
|
266
|
+
error instanceof DurableAgentNotFoundError ||
|
|
267
|
+
error instanceof CodexPrintError
|
|
268
|
+
)
|
|
269
|
+
throw error;
|
|
270
|
+
if (
|
|
271
|
+
/UNIQUE constraint failed: durable_agents\.provider_session_id/i.test(
|
|
272
|
+
(error as Error).message,
|
|
273
|
+
)
|
|
274
|
+
) {
|
|
275
|
+
throw new CodexPrintError(
|
|
276
|
+
"Provider session is already bound to another durable agent.",
|
|
277
|
+
"CODEX_SESSION_MISMATCH",
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
throw this.storageError("Failed to bind durable-agent provider session", error);
|
|
197
281
|
}
|
|
282
|
+
return this.requireById(id);
|
|
283
|
+
}
|
|
198
284
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
285
|
+
async completeRun(
|
|
286
|
+
id: string,
|
|
287
|
+
token: string,
|
|
288
|
+
result: DurableRunCompletion,
|
|
289
|
+
): Promise<DurableAgent> {
|
|
290
|
+
this.assertWritable();
|
|
291
|
+
const completedAt = this.now().toISOString();
|
|
292
|
+
const changed = this.db.execute(
|
|
293
|
+
`UPDATE durable_agents SET
|
|
203
294
|
state = ?, session_health = ?, active_run_token = NULL, active_owner_pid = NULL,
|
|
204
295
|
active_owner_started_at = NULL, active_provider_pid = NULL, active_provider_started_at = NULL,
|
|
205
296
|
active_run_started_at = NULL, last_active_at = ?, updated_at = ?, last_result_status = ?,
|
|
206
297
|
last_result_completed_at = ?, last_result_exit_code = ?, last_result_summary = ?
|
|
207
|
-
WHERE id = ? AND state = 'running' AND active_run_token = ?`,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
298
|
+
WHERE id = ? AND state = 'running' AND active_run_token = ?`,
|
|
299
|
+
[
|
|
300
|
+
result.status === "succeeded" ? "ready" : "degraded",
|
|
301
|
+
result.sessionHealth,
|
|
302
|
+
completedAt,
|
|
303
|
+
completedAt,
|
|
304
|
+
result.status,
|
|
305
|
+
completedAt,
|
|
306
|
+
result.exitCode,
|
|
307
|
+
result.summary.slice(0, 4096),
|
|
308
|
+
id,
|
|
309
|
+
token,
|
|
310
|
+
],
|
|
311
|
+
);
|
|
312
|
+
if (changed.changes !== 1)
|
|
313
|
+
throw new DurableAgentRepositoryError("Print run ownership changed.");
|
|
314
|
+
return this.requireById(id);
|
|
315
|
+
}
|
|
214
316
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
317
|
+
async reconcile(): Promise<void> {
|
|
318
|
+
this.assertWritable();
|
|
319
|
+
const running = this.listRaw().filter((agent) => agent.state === "running" && agent.activeRun);
|
|
320
|
+
for (const snapshot of running) {
|
|
321
|
+
if (this.isActive(snapshot.activeRun!)) continue;
|
|
322
|
+
const completedAt = this.now().toISOString();
|
|
323
|
+
this.db.execute(
|
|
324
|
+
`UPDATE durable_agents SET
|
|
222
325
|
state = 'degraded', session_health = 'unknown', active_run_token = NULL,
|
|
223
326
|
active_owner_pid = NULL, active_owner_started_at = NULL, active_provider_pid = NULL,
|
|
224
327
|
active_provider_started_at = NULL, active_run_started_at = NULL, updated_at = ?, last_active_at = ?,
|
|
225
328
|
last_result_status = 'interrupted', last_result_completed_at = ?, last_result_exit_code = NULL,
|
|
226
329
|
last_result_summary = 'Previous print run was interrupted.'
|
|
227
330
|
WHERE id = ? AND state = 'running' AND active_run_token = ?
|
|
228
|
-
AND active_owner_started_at = ? AND active_run_started_at = ?`,
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
331
|
+
AND active_owner_started_at = ? AND active_run_started_at = ?`,
|
|
332
|
+
[
|
|
333
|
+
completedAt,
|
|
334
|
+
completedAt,
|
|
335
|
+
completedAt,
|
|
336
|
+
snapshot.id,
|
|
337
|
+
snapshot.activeRun!.token,
|
|
338
|
+
snapshot.activeRun!.owner.startedAt,
|
|
339
|
+
snapshot.activeRun!.startedAt,
|
|
340
|
+
],
|
|
341
|
+
);
|
|
233
342
|
}
|
|
343
|
+
}
|
|
234
344
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
345
|
+
private immediate<T>(operation: () => T): T {
|
|
346
|
+
this.db.instance.exec("BEGIN IMMEDIATE");
|
|
347
|
+
try {
|
|
348
|
+
const result = operation();
|
|
349
|
+
this.db.instance.exec("COMMIT");
|
|
350
|
+
return result;
|
|
351
|
+
} catch (error) {
|
|
352
|
+
try {
|
|
353
|
+
this.db.instance.exec("ROLLBACK");
|
|
354
|
+
} catch {
|
|
355
|
+
/* retain original failure */
|
|
356
|
+
}
|
|
357
|
+
throw error;
|
|
245
358
|
}
|
|
359
|
+
}
|
|
246
360
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
361
|
+
private listRaw(): DurableAgent[] {
|
|
362
|
+
try {
|
|
363
|
+
return this.db
|
|
364
|
+
.query<DurableAgentRow>(
|
|
365
|
+
"SELECT * FROM durable_agents ORDER BY updated_at DESC, name COLLATE NOCASE",
|
|
366
|
+
)
|
|
367
|
+
.map((row) => this.fromRow(row));
|
|
368
|
+
} catch (error) {
|
|
369
|
+
throw this.storageError("Failed to read durable-agent database", error);
|
|
255
370
|
}
|
|
371
|
+
}
|
|
256
372
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
373
|
+
private findById(id: string): DurableAgent | null {
|
|
374
|
+
const row = this.db.queryOne<DurableAgentRow>("SELECT * FROM durable_agents WHERE id = ?", [
|
|
375
|
+
id,
|
|
376
|
+
]);
|
|
377
|
+
return row ? this.fromRow(row) : null;
|
|
378
|
+
}
|
|
261
379
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
380
|
+
private requireById(id: string): DurableAgent {
|
|
381
|
+
const agent = this.findById(id);
|
|
382
|
+
if (!agent) throw new DurableAgentNotFoundError(id);
|
|
383
|
+
return agent;
|
|
384
|
+
}
|
|
267
385
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
386
|
+
private fromRow(row: DurableAgentRow): DurableAgent {
|
|
387
|
+
if (
|
|
388
|
+
!["claude", "codex", "pi"].includes(row.provider) ||
|
|
389
|
+
(row.provider !== "codex" && row.provider_session_id === null)
|
|
390
|
+
) {
|
|
391
|
+
throw new DurableAgentRepositoryError(`Invalid durable-agent provider record: ${row.id}`);
|
|
392
|
+
}
|
|
393
|
+
const activeRun: DurableActiveRun | null =
|
|
394
|
+
row.active_run_token === null
|
|
395
|
+
? null
|
|
396
|
+
: {
|
|
274
397
|
token: row.active_run_token,
|
|
275
398
|
owner: { pid: row.active_owner_pid!, startedAt: row.active_owner_started_at! },
|
|
276
|
-
provider:
|
|
277
|
-
|
|
278
|
-
|
|
399
|
+
provider:
|
|
400
|
+
row.active_provider_pid === null
|
|
401
|
+
? null
|
|
402
|
+
: {
|
|
403
|
+
pid: row.active_provider_pid,
|
|
404
|
+
startedAt: row.active_provider_started_at!,
|
|
405
|
+
},
|
|
279
406
|
startedAt: row.active_run_started_at!,
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
407
|
+
};
|
|
408
|
+
const base = {
|
|
409
|
+
id: row.id,
|
|
410
|
+
name: row.name,
|
|
411
|
+
provider: row.provider,
|
|
412
|
+
mode: row.mode,
|
|
413
|
+
cwd: row.cwd,
|
|
414
|
+
state: row.state,
|
|
415
|
+
sessionHealth: row.session_health,
|
|
416
|
+
createdAt: row.created_at,
|
|
417
|
+
updatedAt: row.updated_at,
|
|
418
|
+
lastActiveAt: row.last_active_at,
|
|
419
|
+
lastResult:
|
|
420
|
+
row.last_result_status === null
|
|
421
|
+
? null
|
|
422
|
+
: {
|
|
423
|
+
status: row.last_result_status,
|
|
424
|
+
completedAt: row.last_result_completed_at!,
|
|
425
|
+
exitCode: row.last_result_exit_code,
|
|
426
|
+
summary: row.last_result_summary ?? "",
|
|
288
427
|
},
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
if (row.provider === 'pi') {
|
|
295
|
-
return { ...base, provider: 'pi', providerSessionId: row.provider_session_id! };
|
|
296
|
-
}
|
|
297
|
-
return { ...base, provider: 'codex', providerSessionId: row.provider_session_id };
|
|
428
|
+
activeRun,
|
|
429
|
+
};
|
|
430
|
+
if (row.provider === "claude") {
|
|
431
|
+
return { ...base, provider: "claude", providerSessionId: row.provider_session_id! };
|
|
298
432
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
try {
|
|
302
|
-
const resolved = fs.realpathSync(input);
|
|
303
|
-
if (!fs.statSync(resolved).isDirectory()) throw new Error('not a directory');
|
|
304
|
-
return resolved;
|
|
305
|
-
} catch {
|
|
306
|
-
throw new DurableAgentRepositoryError(`Durable agent cwd is not an existing directory: ${input}`);
|
|
307
|
-
}
|
|
433
|
+
if (row.provider === "pi") {
|
|
434
|
+
return { ...base, provider: "pi", providerSessionId: row.provider_session_id! };
|
|
308
435
|
}
|
|
436
|
+
return { ...base, provider: "codex", providerSessionId: row.provider_session_id };
|
|
437
|
+
}
|
|
309
438
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
439
|
+
private canonicalDirectory(input: string): string {
|
|
440
|
+
try {
|
|
441
|
+
const resolved = fs.realpathSync(input);
|
|
442
|
+
if (!fs.statSync(resolved).isDirectory()) throw new Error("not a directory");
|
|
443
|
+
return resolved;
|
|
444
|
+
} catch {
|
|
445
|
+
throw new DurableAgentRepositoryError(
|
|
446
|
+
`Durable agent cwd is not an existing directory: ${input}`,
|
|
447
|
+
);
|
|
317
448
|
}
|
|
449
|
+
}
|
|
318
450
|
|
|
319
|
-
|
|
320
|
-
|
|
451
|
+
private validateBoundCwd(bound: string): void {
|
|
452
|
+
try {
|
|
453
|
+
const stat = fs.lstatSync(bound);
|
|
454
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || fs.realpathSync(bound) !== bound)
|
|
455
|
+
throw new Error("binding changed");
|
|
456
|
+
} catch {
|
|
457
|
+
throw new DurableAgentRepositoryError(
|
|
458
|
+
`Durable agent cwd binding is no longer safe: ${bound}`,
|
|
459
|
+
);
|
|
321
460
|
}
|
|
461
|
+
}
|
|
322
462
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
463
|
+
private isActive(metadata: DurableActiveRun): boolean {
|
|
464
|
+
return (
|
|
465
|
+
this.sameProcess(metadata.owner) ||
|
|
466
|
+
(metadata.provider !== null && this.sameProcess(metadata.provider))
|
|
467
|
+
);
|
|
468
|
+
}
|
|
327
469
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
470
|
+
private sameProcess(expected: ProcessIdentity): boolean {
|
|
471
|
+
const actual = this.processInspector.getIdentity(expected.pid);
|
|
472
|
+
return actual !== null && actual.startedAt === expected.startedAt;
|
|
473
|
+
}
|
|
331
474
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
475
|
+
private assertWritable(): void {
|
|
476
|
+
if (this.readonly)
|
|
477
|
+
throw new DurableAgentRepositoryError("Durable-agent repository is readonly.");
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
private storageError(prefix: string, error: unknown): DurableAgentRepositoryError {
|
|
481
|
+
return error instanceof DurableAgentRepositoryError
|
|
482
|
+
? error
|
|
483
|
+
: new DurableAgentRepositoryError(`${prefix}: ${(error as Error).message}`);
|
|
484
|
+
}
|
|
336
485
|
}
|