@ai-devkit/agent-manager 0.32.0 → 0.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AgentManager.d.ts +13 -4
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +116 -84
- package/dist/AgentManager.js.map +1 -1
- package/dist/__tests__/AgentManager.test.js +623 -391
- 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/GrokCliAdapter.test.js +114 -114
- package/dist/__tests__/adapters/GrokCliAdapter.test.js.map +1 -1
- package/dist/__tests__/adapters/OpenCodeAdapter.test.js +170 -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/copilot/CopilotAdapter.test.js +641 -0
- package/dist/__tests__/providers/copilot/CopilotAdapter.test.js.map +1 -0
- package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js +1398 -0
- package/dist/__tests__/providers/gemini/GeminiCliAdapter.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/HerdrAgentDiscovery.test.js +164 -0
- package/dist/__tests__/runtime/HerdrAgentDiscovery.test.js.map +1 -0
- package/dist/__tests__/runtime/HerdrAgentRuntime.test.js +488 -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 +343 -218
- 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/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 +2 -1
- package/dist/adapters/OpenCodeAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenCodeAdapter.js +41 -37
- 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 +48 -43
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -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/{adapters → providers/copilot}/CopilotAdapter.d.ts +11 -25
- package/dist/providers/copilot/CopilotAdapter.d.ts.map +1 -0
- package/dist/providers/copilot/CopilotAdapter.js +108 -0
- package/dist/providers/copilot/CopilotAdapter.js.map +1 -0
- package/dist/providers/copilot/CopilotAgentMapper.d.ts +9 -0
- package/dist/providers/copilot/CopilotAgentMapper.d.ts.map +1 -0
- package/dist/providers/copilot/CopilotAgentMapper.js +37 -0
- package/dist/providers/copilot/CopilotAgentMapper.js.map +1 -0
- package/dist/providers/copilot/CopilotSessionLocator.d.ts +19 -0
- package/dist/providers/copilot/CopilotSessionLocator.d.ts.map +1 -0
- package/dist/providers/copilot/CopilotSessionLocator.js +41 -0
- package/dist/providers/copilot/CopilotSessionLocator.js.map +1 -0
- package/dist/providers/copilot/CopilotSessionParser.d.ts +30 -0
- package/dist/providers/copilot/CopilotSessionParser.d.ts.map +1 -0
- package/dist/providers/copilot/CopilotSessionParser.js +181 -0
- package/dist/providers/copilot/CopilotSessionParser.js.map +1 -0
- package/dist/providers/gemini/GeminiAgentMapper.d.ts +9 -0
- package/dist/providers/gemini/GeminiAgentMapper.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiAgentMapper.js +37 -0
- package/dist/providers/gemini/GeminiAgentMapper.js.map +1 -0
- package/dist/providers/gemini/GeminiCliAdapter.d.ts +52 -0
- package/dist/providers/gemini/GeminiCliAdapter.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiCliAdapter.js +188 -0
- package/dist/providers/gemini/GeminiCliAdapter.js.map +1 -0
- package/dist/providers/gemini/GeminiSessionLocator.d.ts +30 -0
- package/dist/providers/gemini/GeminiSessionLocator.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiSessionLocator.js +142 -0
- package/dist/providers/gemini/GeminiSessionLocator.js.map +1 -0
- package/dist/providers/gemini/GeminiSessionParser.d.ts +94 -0
- package/dist/providers/gemini/GeminiSessionParser.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiSessionParser.js +166 -0
- package/dist/providers/gemini/GeminiSessionParser.js.map +1 -0
- 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/HerdrAgentDiscovery.d.ts +18 -0
- package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrAgentDiscovery.js +183 -0
- package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.d.ts +36 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.js +202 -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 +16 -0
- package/dist/runtime/herdr/HerdrResponseParsers.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrResponseParsers.js +107 -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 +59 -26
- 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 +338 -274
- package/src/__tests__/AgentManager.test.ts +1143 -907
- package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +1657 -1368
- package/src/__tests__/adapters/CodexAdapter.test.ts +365 -1698
- package/src/__tests__/adapters/GrokCliAdapter.test.ts +325 -272
- package/src/__tests__/adapters/OpenCodeAdapter.test.ts +511 -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/copilot/CopilotAdapter.test.ts +602 -0
- package/src/__tests__/providers/gemini/GeminiCliAdapter.test.ts +1299 -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/HerdrAgentDiscovery.test.ts +131 -0
- package/src/__tests__/runtime/HerdrAgentRuntime.test.ts +377 -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 +516 -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/GrokCliAdapter.ts +353 -342
- package/src/adapters/OpenCodeAdapter.ts +289 -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 +151 -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/copilot/CopilotAdapter.ts +145 -0
- package/src/providers/copilot/CopilotAgentMapper.ts +36 -0
- package/src/providers/copilot/CopilotSessionLocator.ts +57 -0
- package/src/providers/copilot/CopilotSessionParser.ts +289 -0
- package/src/providers/gemini/GeminiAgentMapper.ts +36 -0
- package/src/providers/gemini/GeminiCliAdapter.ts +266 -0
- package/src/providers/gemini/GeminiSessionLocator.ts +183 -0
- package/src/providers/gemini/GeminiSessionParser.ts +271 -0
- 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/HerdrAgentDiscovery.ts +178 -0
- package/src/runtime/herdr/HerdrAgentRuntime.ts +216 -0
- package/src/runtime/herdr/HerdrCliClient.ts +78 -0
- package/src/runtime/herdr/HerdrErrors.ts +9 -0
- package/src/runtime/herdr/HerdrResponseParsers.ts +86 -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 +301 -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/CopilotAdapter.test.js +0 -630
- package/dist/__tests__/adapters/CopilotAdapter.test.js.map +0 -1
- package/dist/__tests__/adapters/GeminiCliAdapter.test.js +0 -1384
- package/dist/__tests__/adapters/GeminiCliAdapter.test.js.map +0 -1
- 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/CopilotAdapter.d.ts.map +0 -1
- package/dist/adapters/CopilotAdapter.js +0 -329
- package/dist/adapters/CopilotAdapter.js.map +0 -1
- package/dist/adapters/GeminiCliAdapter.d.ts +0 -98
- package/dist/adapters/GeminiCliAdapter.d.ts.map +0 -1
- package/dist/adapters/GeminiCliAdapter.js +0 -513
- package/dist/adapters/GeminiCliAdapter.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/CopilotAdapter.test.ts +0 -510
- package/src/__tests__/adapters/GeminiCliAdapter.test.ts +0 -1259
- 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/CopilotAdapter.ts +0 -473
- package/src/adapters/GeminiCliAdapter.ts +0 -701
- package/src/adapters/PiAdapter.ts +0 -598
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
import os from
|
|
2
|
-
import path from
|
|
3
|
-
import { DatabaseConnection, resolveAgentRegistryDbPath } from
|
|
1
|
+
import os from "os";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { DatabaseConnection, resolveAgentRegistryDbPath } from "../database/index.js";
|
|
4
|
+
import { parseTmuxRuntimeRef } from "../runtime/tmux/TmuxRuntimeRef.js";
|
|
4
5
|
export class RenameNotFoundError extends Error {
|
|
5
6
|
agentName;
|
|
6
7
|
constructor(agentName){
|
|
7
8
|
super(`Agent "${agentName}" not found in registry.`), this.agentName = agentName;
|
|
8
|
-
this.name =
|
|
9
|
+
this.name = "RenameNotFoundError";
|
|
9
10
|
}
|
|
10
11
|
}
|
|
11
12
|
export class RenameConflictError extends Error {
|
|
12
13
|
agentName;
|
|
13
14
|
constructor(agentName){
|
|
14
15
|
super(`Agent "${agentName}" is already in use.`), this.agentName = agentName;
|
|
15
|
-
this.name =
|
|
16
|
+
this.name = "RenameConflictError";
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
|
-
const
|
|
19
|
+
export const AGENT_RUNTIME_PROVIDERS = [
|
|
20
|
+
"tmux",
|
|
21
|
+
"herdr"
|
|
22
|
+
];
|
|
23
|
+
const DEFAULT_REGISTRY_PATH = path.join(os.homedir(), ".ai-devkit", "agents.json");
|
|
19
24
|
const DEFAULT_PRUNE_INTERVAL_MS = 30_000;
|
|
20
25
|
let defaultInstance = null;
|
|
21
26
|
export class AgentRegistry {
|
|
@@ -41,11 +46,13 @@ export class AgentRegistry {
|
|
|
41
46
|
return defaultInstance;
|
|
42
47
|
}
|
|
43
48
|
rowToEntry(row) {
|
|
49
|
+
const runtime = this.parseRuntime(row.runtime);
|
|
44
50
|
return {
|
|
45
51
|
name: row.name,
|
|
46
52
|
type: row.type,
|
|
47
53
|
pid: row.pid,
|
|
48
|
-
|
|
54
|
+
runtime,
|
|
55
|
+
runtimeRef: this.parseRuntimeRef(runtime, row.runtime_ref, row.tmux_session),
|
|
49
56
|
cwd: row.cwd,
|
|
50
57
|
startedAt: row.started_at,
|
|
51
58
|
sessionId: row.session_id,
|
|
@@ -54,47 +61,66 @@ export class AgentRegistry {
|
|
|
54
61
|
updatedAt: row.updated_at
|
|
55
62
|
};
|
|
56
63
|
}
|
|
64
|
+
parseRuntime(value) {
|
|
65
|
+
return value === "herdr" ? "herdr" : "tmux";
|
|
66
|
+
}
|
|
67
|
+
parseRuntimeRef(runtime, raw, legacyTmuxSession) {
|
|
68
|
+
if (raw) {
|
|
69
|
+
try {
|
|
70
|
+
return JSON.parse(raw);
|
|
71
|
+
} catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (runtime === "tmux" && legacyTmuxSession) {
|
|
76
|
+
return {
|
|
77
|
+
session: legacyTmuxSession
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
57
82
|
mergeEntry(incoming, existing) {
|
|
58
83
|
if (!existing) return incoming;
|
|
59
|
-
const
|
|
84
|
+
const keepExistingRuntime = existing.runtime === "herdr" || Boolean(parseTmuxRuntimeRef(existing.runtimeRef)) || incoming.runtime !== "herdr";
|
|
60
85
|
return {
|
|
61
86
|
...existing,
|
|
62
|
-
name:
|
|
63
|
-
|
|
64
|
-
|
|
87
|
+
name: existing.name,
|
|
88
|
+
runtime: keepExistingRuntime ? existing.runtime : incoming.runtime,
|
|
89
|
+
runtimeRef: keepExistingRuntime ? existing.runtimeRef : incoming.runtimeRef,
|
|
90
|
+
cwd: existing.cwd || incoming.cwd,
|
|
65
91
|
startedAt: existing.startedAt || incoming.startedAt,
|
|
66
92
|
sessionId: incoming.sessionId || existing.sessionId,
|
|
67
93
|
sessionFilePath: incoming.sessionFilePath || existing.sessionFilePath
|
|
68
94
|
};
|
|
69
95
|
}
|
|
70
96
|
findByIdentity(type, pid) {
|
|
71
|
-
const row = this.db.queryOne(
|
|
97
|
+
const row = this.db.queryOne("SELECT * FROM agents WHERE type = ? AND pid = ?", [
|
|
72
98
|
type,
|
|
73
99
|
pid
|
|
74
100
|
]);
|
|
75
101
|
return row ? this.rowToEntry(row) : undefined;
|
|
76
102
|
}
|
|
77
103
|
findByName(name) {
|
|
78
|
-
const row = this.db.queryOne(
|
|
104
|
+
const row = this.db.queryOne("SELECT * FROM agents WHERE name = ?", [
|
|
79
105
|
name
|
|
80
106
|
]);
|
|
81
107
|
return row ? this.rowToEntry(row) : undefined;
|
|
82
108
|
}
|
|
83
109
|
findPidConflicts(type, pid) {
|
|
84
|
-
return this.db.query(
|
|
110
|
+
return this.db.query("SELECT * FROM agents WHERE pid = ? AND type <> ?", [
|
|
85
111
|
pid,
|
|
86
112
|
type
|
|
87
113
|
]).map((row)=>this.rowToEntry(row));
|
|
88
114
|
}
|
|
89
115
|
entriesEqual(left, right) {
|
|
90
|
-
return left.name === right.name && left.type === right.type && left.pid === right.pid && left.
|
|
116
|
+
return left.name === right.name && left.type === right.type && left.pid === right.pid && left.runtime === right.runtime && JSON.stringify(left.runtimeRef ?? null) === JSON.stringify(right.runtimeRef ?? null) && left.cwd === right.cwd && left.startedAt === right.startedAt && left.sessionId === right.sessionId && left.sessionFilePath === right.sessionFilePath;
|
|
91
117
|
}
|
|
92
118
|
deleteNameConflict(name, type, pid) {
|
|
93
119
|
const conflict = this.findByName(name);
|
|
94
120
|
if (!conflict) return;
|
|
95
121
|
if (conflict.type === type && conflict.pid === pid) return;
|
|
96
122
|
if (!this.isAlive(conflict)) {
|
|
97
|
-
this.db.execute(
|
|
123
|
+
this.db.execute("DELETE FROM agents WHERE type = ? AND pid = ?", [
|
|
98
124
|
conflict.type,
|
|
99
125
|
conflict.pid
|
|
100
126
|
]);
|
|
@@ -104,13 +130,17 @@ export class AgentRegistry {
|
|
|
104
130
|
this.db.instance.prepare(`
|
|
105
131
|
INSERT INTO agents (
|
|
106
132
|
type, pid, name, tmux_session, cwd, started_at, session_id, session_file_path, updated_at
|
|
133
|
+
, runtime, runtime_ref
|
|
107
134
|
)
|
|
108
135
|
VALUES (
|
|
109
|
-
@type, @pid, @name, @
|
|
136
|
+
@type, @pid, @name, @legacyTmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt
|
|
137
|
+
, @runtime, @runtimeRefJson
|
|
110
138
|
)
|
|
111
139
|
ON CONFLICT(type, pid) DO UPDATE SET
|
|
112
140
|
name = excluded.name,
|
|
113
141
|
tmux_session = excluded.tmux_session,
|
|
142
|
+
runtime = excluded.runtime,
|
|
143
|
+
runtime_ref = excluded.runtime_ref,
|
|
114
144
|
cwd = excluded.cwd,
|
|
115
145
|
started_at = agents.started_at,
|
|
116
146
|
session_id = excluded.session_id,
|
|
@@ -118,6 +148,8 @@ export class AgentRegistry {
|
|
|
118
148
|
updated_at = excluded.updated_at
|
|
119
149
|
`).run({
|
|
120
150
|
...entry,
|
|
151
|
+
legacyTmuxSession: parseTmuxRuntimeRef(entry.runtimeRef)?.session ?? "",
|
|
152
|
+
runtimeRefJson: JSON.stringify(entry.runtimeRef ?? null),
|
|
121
153
|
updatedAt: this.now().toISOString()
|
|
122
154
|
});
|
|
123
155
|
}
|
|
@@ -132,7 +164,7 @@ export class AgentRegistry {
|
|
|
132
164
|
const pidConflicts = this.findPidConflicts(incoming.type, incoming.pid);
|
|
133
165
|
if (existing && this.entriesEqual(merged, existing) && pidConflicts.length === 0) return;
|
|
134
166
|
for (const conflict of pidConflicts){
|
|
135
|
-
this.db.execute(
|
|
167
|
+
this.db.execute("DELETE FROM agents WHERE type = ? AND pid = ?", [
|
|
136
168
|
conflict.type,
|
|
137
169
|
conflict.pid
|
|
138
170
|
]);
|
|
@@ -146,8 +178,8 @@ export class AgentRegistry {
|
|
|
146
178
|
process.kill(entry.pid, 0);
|
|
147
179
|
return true;
|
|
148
180
|
} catch (error) {
|
|
149
|
-
const code = error && typeof error ===
|
|
150
|
-
return code !==
|
|
181
|
+
const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
|
|
182
|
+
return code !== "ESRCH";
|
|
151
183
|
}
|
|
152
184
|
}
|
|
153
185
|
pruneAt(nowMs) {
|
|
@@ -156,7 +188,7 @@ export class AgentRegistry {
|
|
|
156
188
|
if (stale.length > 0) {
|
|
157
189
|
this.db.transaction(()=>{
|
|
158
190
|
for (const entry of stale){
|
|
159
|
-
this.db.execute(
|
|
191
|
+
this.db.execute("DELETE FROM agents WHERE type = ? AND pid = ?", [
|
|
160
192
|
entry.type,
|
|
161
193
|
entry.pid
|
|
162
194
|
]);
|
|
@@ -199,12 +231,12 @@ export class AgentRegistry {
|
|
|
199
231
|
}
|
|
200
232
|
this.db.transaction(()=>{
|
|
201
233
|
if (conflict) {
|
|
202
|
-
this.db.execute(
|
|
234
|
+
this.db.execute("DELETE FROM agents WHERE type = ? AND pid = ?", [
|
|
203
235
|
conflict.type,
|
|
204
236
|
conflict.pid
|
|
205
237
|
]);
|
|
206
238
|
}
|
|
207
|
-
this.db.execute(
|
|
239
|
+
this.db.execute("UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?", [
|
|
208
240
|
newName,
|
|
209
241
|
this.now().toISOString(),
|
|
210
242
|
existing.type,
|
|
@@ -214,9 +246,9 @@ export class AgentRegistry {
|
|
|
214
246
|
}
|
|
215
247
|
togglePin(type, pid) {
|
|
216
248
|
if (this.readonly) {
|
|
217
|
-
throw new Error(
|
|
249
|
+
throw new Error("Agent registry is readonly; cannot toggle pin.");
|
|
218
250
|
}
|
|
219
|
-
const result = this.db.execute(
|
|
251
|
+
const result = this.db.execute("UPDATE agents SET pinned = NOT pinned, updated_at = ? WHERE type = ? AND pid = ?", [
|
|
220
252
|
this.now().toISOString(),
|
|
221
253
|
type,
|
|
222
254
|
pid
|
|
@@ -228,9 +260,10 @@ export class AgentRegistry {
|
|
|
228
260
|
return this.findByName(name) ?? null;
|
|
229
261
|
}
|
|
230
262
|
list() {
|
|
231
|
-
const rows = this.db.query(
|
|
263
|
+
const rows = this.db.query("SELECT * FROM agents ORDER BY started_at ASC, name ASC");
|
|
232
264
|
return rows.map((row)=>this.rowToEntry(row));
|
|
233
265
|
}
|
|
234
266
|
}
|
|
267
|
+
export { parseTmuxRuntimeRef };
|
|
235
268
|
|
|
236
269
|
//# sourceMappingURL=AgentRegistry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/AgentRegistry.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport type { AgentType } from '../adapters/AgentAdapter.js';\nimport {\n DatabaseConnection,\n resolveAgentRegistryDbPath,\n} from '../database/index.js';\n\nexport class RenameNotFoundError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" not found in registry.`);\n this.name = 'RenameNotFoundError';\n }\n}\n\nexport class RenameConflictError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" is already in use.`);\n this.name = 'RenameConflictError';\n }\n}\n\nexport interface RegistryEntry {\n name: string;\n type: AgentType;\n pid: number;\n tmuxSession: string;\n cwd: string;\n startedAt: string; // ISO 8601\n sessionId: string;\n sessionFilePath: string;\n pinned: boolean;\n updatedAt?: string;\n}\n\ninterface RegistryRow {\n name: string;\n type: AgentType;\n pid: number;\n tmux_session: string;\n cwd: string;\n started_at: string;\n session_id: string;\n session_file_path: string;\n updated_at: string;\n pinned: number;\n}\n\nconst DEFAULT_REGISTRY_PATH = path.join(os.homedir(), '.ai-devkit', 'agents.json');\nconst DEFAULT_PRUNE_INTERVAL_MS = 30_000;\n\nlet defaultInstance: AgentRegistry | null = null;\n\nexport interface AgentRegistryOptions {\n now?: () => Date;\n pruneIntervalMs?: number;\n onDatabaseOperation?: (sql: string) => void;\n readonly?: boolean;\n}\n\nexport class AgentRegistry {\n private db: DatabaseConnection;\n private readonly now: () => Date;\n private readonly pruneIntervalMs: number;\n private readonly readonly: boolean;\n private lastPrunedAt: number | undefined;\n\n constructor(filePath: string = DEFAULT_REGISTRY_PATH, options: AgentRegistryOptions = {}) {\n this.now = options.now ?? (() => new Date());\n this.pruneIntervalMs = options.pruneIntervalMs ?? DEFAULT_PRUNE_INTERVAL_MS;\n this.readonly = options.readonly ?? false;\n this.db = new DatabaseConnection({\n dbPath: resolveAgentRegistryDbPath(filePath),\n verbose: options.onDatabaseOperation,\n readonly: this.readonly,\n });\n }\n\n static default(): AgentRegistry {\n if (!defaultInstance) {\n defaultInstance = new AgentRegistry();\n }\n return defaultInstance;\n }\n\n private rowToEntry(row: RegistryRow): RegistryEntry {\n return {\n name: row.name,\n type: row.type,\n pid: row.pid,\n tmuxSession: row.tmux_session,\n cwd: row.cwd,\n startedAt: row.started_at,\n sessionId: row.session_id,\n sessionFilePath: row.session_file_path,\n pinned: row.pinned !== 0,\n updatedAt: row.updated_at,\n };\n }\n\n private mergeEntry(incoming: RegistryEntry, existing: RegistryEntry | undefined): RegistryEntry {\n if (!existing) return incoming;\n const incomingIsManaged = Boolean(incoming.tmuxSession);\n return {\n ...existing,\n name: incomingIsManaged ? incoming.name : existing.name,\n tmuxSession: incoming.tmuxSession || existing.tmuxSession,\n cwd: incoming.cwd || existing.cwd,\n startedAt: existing.startedAt || incoming.startedAt,\n sessionId: incoming.sessionId || existing.sessionId,\n sessionFilePath: incoming.sessionFilePath || existing.sessionFilePath,\n };\n }\n\n private findByIdentity(type: AgentType, pid: number): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>(\n 'SELECT * FROM agents WHERE type = ? AND pid = ?',\n [type, pid],\n );\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findByName(name: string): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>('SELECT * FROM agents WHERE name = ?', [name]);\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findPidConflicts(type: AgentType, pid: number): RegistryEntry[] {\n return this.db.query<RegistryRow>(\n 'SELECT * FROM agents WHERE pid = ? AND type <> ?',\n [pid, type],\n ).map((row) => this.rowToEntry(row));\n }\n\n private entriesEqual(left: RegistryEntry, right: RegistryEntry): boolean {\n return left.name === right.name\n && left.type === right.type\n && left.pid === right.pid\n && left.tmuxSession === right.tmuxSession\n && left.cwd === right.cwd\n && left.startedAt === right.startedAt\n && left.sessionId === right.sessionId\n && left.sessionFilePath === right.sessionFilePath;\n }\n\n private deleteNameConflict(name: string, type: AgentType, pid: number): void {\n const conflict = this.findByName(name);\n if (!conflict) return;\n if (conflict.type === type && conflict.pid === pid) return;\n if (!this.isAlive(conflict)) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n }\n\n private insertOrUpdate(entry: RegistryEntry): void {\n this.db.instance.prepare(`\n INSERT INTO agents (\n type, pid, name, tmux_session, cwd, started_at, session_id, session_file_path, updated_at\n )\n VALUES (\n @type, @pid, @name, @tmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt\n )\n ON CONFLICT(type, pid) DO UPDATE SET\n name = excluded.name,\n tmux_session = excluded.tmux_session,\n cwd = excluded.cwd,\n started_at = agents.started_at,\n session_id = excluded.session_id,\n session_file_path = excluded.session_file_path,\n updated_at = excluded.updated_at\n `).run({ ...entry, updatedAt: this.now().toISOString() });\n }\n\n private needsWrite(incoming: RegistryEntry): boolean {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n return !existing\n || !this.entriesEqual(merged, existing)\n || this.findPidConflicts(incoming.type, incoming.pid).length > 0;\n }\n\n private save(incoming: RegistryEntry): void {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n const pidConflicts = this.findPidConflicts(incoming.type, incoming.pid);\n if (existing && this.entriesEqual(merged, existing) && pidConflicts.length === 0) return;\n\n for (const conflict of pidConflicts) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n if (existing && this.entriesEqual(merged, existing)) return;\n\n this.deleteNameConflict(merged.name, merged.type, merged.pid);\n this.insertOrUpdate(merged);\n }\n\n isAlive(entry: RegistryEntry): boolean {\n try {\n process.kill(entry.pid, 0);\n return true;\n } catch (error) {\n const code = error && typeof error === 'object' && 'code' in error\n ? error.code\n : undefined;\n return code !== 'ESRCH';\n }\n }\n\n private pruneAt(nowMs: number): void {\n const entries = this.list();\n const stale = entries.filter((e) => !this.isAlive(e));\n if (stale.length > 0) {\n this.db.transaction(() => {\n for (const entry of stale) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [entry.type, entry.pid]);\n }\n });\n }\n this.lastPrunedAt = nowMs;\n }\n\n prune(): void {\n this.pruneAt(this.now().getTime());\n }\n\n pruneIfDue(): void {\n const nowMs = this.now().getTime();\n const elapsed = this.lastPrunedAt === undefined ? undefined : nowMs - this.lastPrunedAt;\n if (elapsed !== undefined && elapsed >= 0 && elapsed < this.pruneIntervalMs) return;\n this.pruneAt(nowMs);\n }\n\n register(entry: RegistryEntry): void {\n this.registerBatch([entry]);\n }\n\n registerBatch(entries: RegistryEntry[]): void {\n if (entries.length === 0) return;\n if (!entries.some((entry) => this.needsWrite(entry))) return;\n this.db.transaction(() => {\n for (const incoming of entries) {\n this.save(incoming);\n }\n });\n }\n\n rename(currentName: string, newName: string): void {\n const existing = this.findByName(currentName);\n if (!existing) {\n throw new RenameNotFoundError(currentName);\n }\n const conflict = this.findByName(newName);\n if (conflict && this.isAlive(conflict)) {\n throw new RenameConflictError(newName);\n }\n\n this.db.transaction(() => {\n if (conflict) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n this.db.execute(\n 'UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?',\n [newName, this.now().toISOString(), existing.type, existing.pid],\n );\n });\n }\n\n togglePin(type: AgentType, pid: number): boolean | null {\n if (this.readonly) {\n throw new Error('Agent registry is readonly; cannot toggle pin.');\n }\n const result = this.db.execute(\n 'UPDATE agents SET pinned = NOT pinned, updated_at = ? WHERE type = ? AND pid = ?',\n [this.now().toISOString(), type, pid],\n );\n if (result.changes === 0) return null;\n return this.findByIdentity(type, pid)?.pinned ?? null;\n }\n\n lookup(name: string): RegistryEntry | null {\n return this.findByName(name) ?? null;\n }\n\n list(): RegistryEntry[] {\n const rows = this.db.query<RegistryRow>('SELECT * FROM agents ORDER BY started_at ASC, name ASC');\n return rows.map((row) => this.rowToEntry(row));\n }\n}\n"],"names":["os","path","DatabaseConnection","resolveAgentRegistryDbPath","RenameNotFoundError","Error","agentName","name","RenameConflictError","DEFAULT_REGISTRY_PATH","join","homedir","DEFAULT_PRUNE_INTERVAL_MS","defaultInstance","AgentRegistry","db","now","pruneIntervalMs","readonly","lastPrunedAt","filePath","options","Date","dbPath","verbose","onDatabaseOperation","default","rowToEntry","row","type","pid","tmuxSession","tmux_session","cwd","startedAt","started_at","sessionId","session_id","sessionFilePath","session_file_path","pinned","updatedAt","updated_at","mergeEntry","incoming","existing","incomingIsManaged","Boolean","findByIdentity","queryOne","undefined","findByName","findPidConflicts","query","map","entriesEqual","left","right","deleteNameConflict","conflict","isAlive","execute","insertOrUpdate","entry","instance","prepare","run","toISOString","needsWrite","merged","length","save","pidConflicts","process","kill","error","code","pruneAt","nowMs","entries","list","stale","filter","e","transaction","prune","getTime","pruneIfDue","elapsed","register","registerBatch","some","rename","currentName","newName","togglePin","result","changes","lookup","rows"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/AgentRegistry.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\nimport type { AgentType } from \"../adapters/AgentAdapter.js\";\nimport { DatabaseConnection, resolveAgentRegistryDbPath } from \"../database/index.js\";\nimport { parseTmuxRuntimeRef, type TmuxRuntimeRef } from \"../runtime/tmux/TmuxRuntimeRef.js\";\n\nexport class RenameNotFoundError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" not found in registry.`);\n this.name = \"RenameNotFoundError\";\n }\n}\n\nexport class RenameConflictError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" is already in use.`);\n this.name = \"RenameConflictError\";\n }\n}\n\nexport interface RegistryEntry {\n name: string;\n type: AgentType;\n pid: number;\n runtime: AgentRuntimeProvider;\n runtimeRef: unknown | null;\n cwd: string;\n startedAt: string; // ISO 8601\n sessionId: string;\n sessionFilePath: string;\n pinned: boolean;\n updatedAt?: string;\n}\n\ninterface RegistryRow {\n name: string;\n type: AgentType;\n pid: number;\n tmux_session: string;\n runtime?: string;\n runtime_ref?: string;\n cwd: string;\n started_at: string;\n session_id: string;\n session_file_path: string;\n updated_at: string;\n pinned: number;\n}\n\nexport const AGENT_RUNTIME_PROVIDERS = [\"tmux\", \"herdr\"] as const;\nexport type AgentRuntimeProvider = (typeof AGENT_RUNTIME_PROVIDERS)[number];\n\nconst DEFAULT_REGISTRY_PATH = path.join(os.homedir(), \".ai-devkit\", \"agents.json\");\nconst DEFAULT_PRUNE_INTERVAL_MS = 30_000;\n\nlet defaultInstance: AgentRegistry | null = null;\n\nexport interface AgentRegistryOptions {\n now?: () => Date;\n pruneIntervalMs?: number;\n onDatabaseOperation?: (sql: string) => void;\n readonly?: boolean;\n}\n\nexport class AgentRegistry {\n private db: DatabaseConnection;\n private readonly now: () => Date;\n private readonly pruneIntervalMs: number;\n private readonly readonly: boolean;\n private lastPrunedAt: number | undefined;\n\n constructor(filePath: string = DEFAULT_REGISTRY_PATH, options: AgentRegistryOptions = {}) {\n this.now = options.now ?? (() => new Date());\n this.pruneIntervalMs = options.pruneIntervalMs ?? DEFAULT_PRUNE_INTERVAL_MS;\n this.readonly = options.readonly ?? false;\n this.db = new DatabaseConnection({\n dbPath: resolveAgentRegistryDbPath(filePath),\n verbose: options.onDatabaseOperation,\n readonly: this.readonly,\n });\n }\n\n static default(): AgentRegistry {\n if (!defaultInstance) {\n defaultInstance = new AgentRegistry();\n }\n return defaultInstance;\n }\n\n private rowToEntry(row: RegistryRow): RegistryEntry {\n const runtime = this.parseRuntime(row.runtime);\n return {\n name: row.name,\n type: row.type,\n pid: row.pid,\n runtime,\n runtimeRef: this.parseRuntimeRef(runtime, row.runtime_ref, row.tmux_session),\n cwd: row.cwd,\n startedAt: row.started_at,\n sessionId: row.session_id,\n sessionFilePath: row.session_file_path,\n pinned: row.pinned !== 0,\n updatedAt: row.updated_at,\n };\n }\n\n private parseRuntime(value: string | undefined): AgentRuntimeProvider {\n return value === \"herdr\" ? \"herdr\" : \"tmux\";\n }\n\n private parseRuntimeRef(\n runtime: AgentRuntimeProvider,\n raw: string | undefined,\n legacyTmuxSession: string,\n ): unknown | null {\n if (raw) {\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return null;\n }\n }\n\n if (runtime === \"tmux\" && legacyTmuxSession) {\n return { session: legacyTmuxSession };\n }\n\n return null;\n }\n\n private mergeEntry(incoming: RegistryEntry, existing: RegistryEntry | undefined): RegistryEntry {\n if (!existing) return incoming;\n const keepExistingRuntime =\n existing.runtime === \"herdr\" ||\n Boolean(parseTmuxRuntimeRef(existing.runtimeRef)) ||\n incoming.runtime !== \"herdr\";\n return {\n ...existing,\n name: existing.name,\n runtime: keepExistingRuntime ? existing.runtime : incoming.runtime,\n runtimeRef: keepExistingRuntime ? existing.runtimeRef : incoming.runtimeRef,\n cwd: existing.cwd || incoming.cwd,\n startedAt: existing.startedAt || incoming.startedAt,\n sessionId: incoming.sessionId || existing.sessionId,\n sessionFilePath: incoming.sessionFilePath || existing.sessionFilePath,\n };\n }\n\n private findByIdentity(type: AgentType, pid: number): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>(\"SELECT * FROM agents WHERE type = ? AND pid = ?\", [\n type,\n pid,\n ]);\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findByName(name: string): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>(\"SELECT * FROM agents WHERE name = ?\", [name]);\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findPidConflicts(type: AgentType, pid: number): RegistryEntry[] {\n return this.db\n .query<RegistryRow>(\"SELECT * FROM agents WHERE pid = ? AND type <> ?\", [pid, type])\n .map((row) => this.rowToEntry(row));\n }\n\n private entriesEqual(left: RegistryEntry, right: RegistryEntry): boolean {\n return (\n left.name === right.name &&\n left.type === right.type &&\n left.pid === right.pid &&\n left.runtime === right.runtime &&\n JSON.stringify(left.runtimeRef ?? null) === JSON.stringify(right.runtimeRef ?? null) &&\n left.cwd === right.cwd &&\n left.startedAt === right.startedAt &&\n left.sessionId === right.sessionId &&\n left.sessionFilePath === right.sessionFilePath\n );\n }\n\n private deleteNameConflict(name: string, type: AgentType, pid: number): void {\n const conflict = this.findByName(name);\n if (!conflict) return;\n if (conflict.type === type && conflict.pid === pid) return;\n if (!this.isAlive(conflict)) {\n this.db.execute(\"DELETE FROM agents WHERE type = ? AND pid = ?\", [\n conflict.type,\n conflict.pid,\n ]);\n }\n }\n\n private insertOrUpdate(entry: RegistryEntry): void {\n this.db.instance\n .prepare(`\n INSERT INTO agents (\n type, pid, name, tmux_session, cwd, started_at, session_id, session_file_path, updated_at\n , runtime, runtime_ref\n )\n VALUES (\n @type, @pid, @name, @legacyTmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt\n , @runtime, @runtimeRefJson\n )\n ON CONFLICT(type, pid) DO UPDATE SET\n name = excluded.name,\n tmux_session = excluded.tmux_session,\n runtime = excluded.runtime,\n runtime_ref = excluded.runtime_ref,\n cwd = excluded.cwd,\n started_at = agents.started_at,\n session_id = excluded.session_id,\n session_file_path = excluded.session_file_path,\n updated_at = excluded.updated_at\n `)\n .run({\n ...entry,\n legacyTmuxSession: parseTmuxRuntimeRef(entry.runtimeRef)?.session ?? \"\",\n runtimeRefJson: JSON.stringify(entry.runtimeRef ?? null),\n updatedAt: this.now().toISOString(),\n });\n }\n\n private needsWrite(incoming: RegistryEntry): boolean {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n return (\n !existing ||\n !this.entriesEqual(merged, existing) ||\n this.findPidConflicts(incoming.type, incoming.pid).length > 0\n );\n }\n\n private save(incoming: RegistryEntry): void {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n const pidConflicts = this.findPidConflicts(incoming.type, incoming.pid);\n if (existing && this.entriesEqual(merged, existing) && pidConflicts.length === 0) return;\n\n for (const conflict of pidConflicts) {\n this.db.execute(\"DELETE FROM agents WHERE type = ? AND pid = ?\", [\n conflict.type,\n conflict.pid,\n ]);\n }\n if (existing && this.entriesEqual(merged, existing)) return;\n\n this.deleteNameConflict(merged.name, merged.type, merged.pid);\n this.insertOrUpdate(merged);\n }\n\n isAlive(entry: RegistryEntry): boolean {\n try {\n process.kill(entry.pid, 0);\n return true;\n } catch (error) {\n const code = error && typeof error === \"object\" && \"code\" in error ? error.code : undefined;\n return code !== \"ESRCH\";\n }\n }\n\n private pruneAt(nowMs: number): void {\n const entries = this.list();\n const stale = entries.filter((e) => !this.isAlive(e));\n if (stale.length > 0) {\n this.db.transaction(() => {\n for (const entry of stale) {\n this.db.execute(\"DELETE FROM agents WHERE type = ? AND pid = ?\", [entry.type, entry.pid]);\n }\n });\n }\n this.lastPrunedAt = nowMs;\n }\n\n prune(): void {\n this.pruneAt(this.now().getTime());\n }\n\n pruneIfDue(): void {\n const nowMs = this.now().getTime();\n const elapsed = this.lastPrunedAt === undefined ? undefined : nowMs - this.lastPrunedAt;\n if (elapsed !== undefined && elapsed >= 0 && elapsed < this.pruneIntervalMs) return;\n this.pruneAt(nowMs);\n }\n\n register(entry: RegistryEntry): void {\n this.registerBatch([entry]);\n }\n\n registerBatch(entries: RegistryEntry[]): void {\n if (entries.length === 0) return;\n if (!entries.some((entry) => this.needsWrite(entry))) return;\n this.db.transaction(() => {\n for (const incoming of entries) {\n this.save(incoming);\n }\n });\n }\n\n rename(currentName: string, newName: string): void {\n const existing = this.findByName(currentName);\n if (!existing) {\n throw new RenameNotFoundError(currentName);\n }\n const conflict = this.findByName(newName);\n if (conflict && this.isAlive(conflict)) {\n throw new RenameConflictError(newName);\n }\n\n this.db.transaction(() => {\n if (conflict) {\n this.db.execute(\"DELETE FROM agents WHERE type = ? AND pid = ?\", [\n conflict.type,\n conflict.pid,\n ]);\n }\n this.db.execute(\"UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?\", [\n newName,\n this.now().toISOString(),\n existing.type,\n existing.pid,\n ]);\n });\n }\n\n togglePin(type: AgentType, pid: number): boolean | null {\n if (this.readonly) {\n throw new Error(\"Agent registry is readonly; cannot toggle pin.\");\n }\n const result = this.db.execute(\n \"UPDATE agents SET pinned = NOT pinned, updated_at = ? WHERE type = ? AND pid = ?\",\n [this.now().toISOString(), type, pid],\n );\n if (result.changes === 0) return null;\n return this.findByIdentity(type, pid)?.pinned ?? null;\n }\n\n lookup(name: string): RegistryEntry | null {\n return this.findByName(name) ?? null;\n }\n\n list(): RegistryEntry[] {\n const rows = this.db.query<RegistryRow>(\n \"SELECT * FROM agents ORDER BY started_at ASC, name ASC\",\n );\n return rows.map((row) => this.rowToEntry(row));\n }\n}\n\nexport { parseTmuxRuntimeRef };\nexport type { TmuxRuntimeRef };\n"],"names":["os","path","DatabaseConnection","resolveAgentRegistryDbPath","parseTmuxRuntimeRef","RenameNotFoundError","Error","agentName","name","RenameConflictError","AGENT_RUNTIME_PROVIDERS","DEFAULT_REGISTRY_PATH","join","homedir","DEFAULT_PRUNE_INTERVAL_MS","defaultInstance","AgentRegistry","db","now","pruneIntervalMs","readonly","lastPrunedAt","filePath","options","Date","dbPath","verbose","onDatabaseOperation","default","rowToEntry","row","runtime","parseRuntime","type","pid","runtimeRef","parseRuntimeRef","runtime_ref","tmux_session","cwd","startedAt","started_at","sessionId","session_id","sessionFilePath","session_file_path","pinned","updatedAt","updated_at","value","raw","legacyTmuxSession","JSON","parse","session","mergeEntry","incoming","existing","keepExistingRuntime","Boolean","findByIdentity","queryOne","undefined","findByName","findPidConflicts","query","map","entriesEqual","left","right","stringify","deleteNameConflict","conflict","isAlive","execute","insertOrUpdate","entry","instance","prepare","run","runtimeRefJson","toISOString","needsWrite","merged","length","save","pidConflicts","process","kill","error","code","pruneAt","nowMs","entries","list","stale","filter","e","transaction","prune","getTime","pruneIfDue","elapsed","register","registerBatch","some","rename","currentName","newName","togglePin","result","changes","lookup","rows"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-requests.d.ts","sourceRoot":"","sources":["../../src/utils/agent-requests.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;
|
|
1
|
+
{"version":3,"file":"agent-requests.d.ts","sourceRoot":"","sources":["../../src/utils/agent-requests.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAO9F;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAI5E"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import * as fs from
|
|
2
|
-
import * as path from
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
3
|
export function getAgentRequestPath(homeDir, sessionId) {
|
|
4
|
-
return path.join(homeDir,
|
|
4
|
+
return path.join(homeDir, ".ai-devkit", "agent-requests", `${sessionId}.json`);
|
|
5
5
|
}
|
|
6
6
|
export function readLatestAgentRequest(homeDir, sessionId) {
|
|
7
7
|
try {
|
|
8
|
-
const raw = fs.readFileSync(getAgentRequestPath(homeDir, sessionId),
|
|
8
|
+
const raw = fs.readFileSync(getAgentRequestPath(homeDir, sessionId), "utf-8");
|
|
9
9
|
return JSON.parse(raw);
|
|
10
10
|
} catch {
|
|
11
11
|
return null;
|
|
@@ -16,7 +16,7 @@ export function writeAgentRequest(homeDir, entry) {
|
|
|
16
16
|
fs.mkdirSync(path.dirname(filePath), {
|
|
17
17
|
recursive: true
|
|
18
18
|
});
|
|
19
|
-
fs.writeFileSync(filePath, JSON.stringify(entry, null, 2),
|
|
19
|
+
fs.writeFileSync(filePath, JSON.stringify(entry, null, 2), "utf-8");
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
//# sourceMappingURL=agent-requests.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/agent-requests.ts"],"sourcesContent":["import * as fs from
|
|
1
|
+
{"version":3,"sources":["../../src/utils/agent-requests.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\n\nexport interface AgentRequest {\n sessionId: string;\n toolName: string;\n toolInput: Record<string, unknown>;\n timestamp: string;\n}\n\nexport function getAgentRequestPath(homeDir: string, sessionId: string): string {\n return path.join(homeDir, \".ai-devkit\", \"agent-requests\", `${sessionId}.json`);\n}\n\nexport function readLatestAgentRequest(homeDir: string, sessionId: string): AgentRequest | null {\n try {\n const raw = fs.readFileSync(getAgentRequestPath(homeDir, sessionId), \"utf-8\");\n return JSON.parse(raw) as AgentRequest;\n } catch {\n return null;\n }\n}\n\nexport function writeAgentRequest(homeDir: string, entry: AgentRequest): void {\n const filePath = getAgentRequestPath(homeDir, entry.sessionId);\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, JSON.stringify(entry, null, 2), \"utf-8\");\n}\n"],"names":["fs","path","getAgentRequestPath","homeDir","sessionId","join","readLatestAgentRequest","raw","readFileSync","JSON","parse","writeAgentRequest","entry","filePath","mkdirSync","dirname","recursive","writeFileSync","stringify"],"mappings":"AAAA,YAAYA,QAAQ,KAAK;AACzB,YAAYC,UAAU,OAAO;AAS7B,OAAO,SAASC,oBAAoBC,OAAe,EAAEC,SAAiB;IACpE,OAAOH,KAAKI,IAAI,CAACF,SAAS,cAAc,kBAAkB,GAAGC,UAAU,KAAK,CAAC;AAC/E;AAEA,OAAO,SAASE,uBAAuBH,OAAe,EAAEC,SAAiB;IACvE,IAAI;QACF,MAAMG,MAAMP,GAAGQ,YAAY,CAACN,oBAAoBC,SAASC,YAAY;QACrE,OAAOK,KAAKC,KAAK,CAACH;IACpB,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,OAAO,SAASI,kBAAkBR,OAAe,EAAES,KAAmB;IACpE,MAAMC,WAAWX,oBAAoBC,SAASS,MAAMR,SAAS;IAC7DJ,GAAGc,SAAS,CAACb,KAAKc,OAAO,CAACF,WAAW;QAAEG,WAAW;IAAK;IACvDhB,GAAGiB,aAAa,CAACJ,UAAUJ,KAAKS,SAAS,CAACN,OAAO,MAAM,IAAI;AAC7D"}
|
package/dist/utils/agents.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AgentType } from
|
|
2
|
-
export type StartableAgentType = Extract<AgentType,
|
|
1
|
+
import type { AgentType } from "../adapters/AgentAdapter.js";
|
|
2
|
+
export type StartableAgentType = Extract<AgentType, "claude" | "codex" | "copilot" | "gemini_cli" | "grok_cli" | "opencode" | "pi">;
|
|
3
3
|
export interface AgentConfig {
|
|
4
4
|
/** Shell command to launch the agent (sent to tmux via `send-keys`). */
|
|
5
5
|
command: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/utils/agents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/utils/agents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,SAAS,EACT,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,IAAI,CAC/E,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CACzC;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAQ1D,CAAC"}
|
package/dist/utils/agents.js
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import path from
|
|
1
|
+
import path from "path";
|
|
2
2
|
/**
|
|
3
3
|
* Per-agent configuration: launch command plus a matcher that recognizes the
|
|
4
4
|
* agent's process in `ps` output. Each matcher knows that agent's distribution
|
|
5
5
|
* quirks (e.g. gemini ships as a Node script so its real binary is in argv[1..]).
|
|
6
6
|
*/ export const AGENTS = {
|
|
7
7
|
claude: {
|
|
8
|
-
command:
|
|
9
|
-
matches: matchArgv0(
|
|
8
|
+
command: "claude",
|
|
9
|
+
matches: matchArgv0("claude")
|
|
10
10
|
},
|
|
11
11
|
codex: {
|
|
12
|
-
command:
|
|
13
|
-
matches: matchArgv0(
|
|
12
|
+
command: "codex",
|
|
13
|
+
matches: matchArgv0("codex")
|
|
14
14
|
},
|
|
15
15
|
copilot: {
|
|
16
|
-
command:
|
|
17
|
-
matches: matchArgv0Name(
|
|
16
|
+
command: "copilot",
|
|
17
|
+
matches: matchArgv0Name("copilot-cli")
|
|
18
18
|
},
|
|
19
19
|
gemini_cli: {
|
|
20
|
-
command:
|
|
21
|
-
matches: matchAnyToken(
|
|
20
|
+
command: "gemini",
|
|
21
|
+
matches: matchAnyToken("gemini")
|
|
22
22
|
},
|
|
23
23
|
grok_cli: {
|
|
24
|
-
command:
|
|
25
|
-
matches: matchArgv0(
|
|
24
|
+
command: "grok",
|
|
25
|
+
matches: matchArgv0("grok")
|
|
26
26
|
},
|
|
27
27
|
opencode: {
|
|
28
|
-
command:
|
|
29
|
-
matches: matchArgv0(
|
|
28
|
+
command: "opencode",
|
|
29
|
+
matches: matchArgv0("opencode")
|
|
30
30
|
},
|
|
31
31
|
pi: {
|
|
32
|
-
command:
|
|
32
|
+
command: "pi",
|
|
33
33
|
matches: matchAnyBasename([
|
|
34
|
-
|
|
34
|
+
"pi"
|
|
35
35
|
])
|
|
36
36
|
}
|
|
37
37
|
};
|
package/dist/utils/agents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/agents.ts"],"sourcesContent":["import path from
|
|
1
|
+
{"version":3,"sources":["../../src/utils/agents.ts"],"sourcesContent":["import path from \"path\";\nimport type { AgentType } from \"../adapters/AgentAdapter.js\";\n\nexport type StartableAgentType = Extract<\n AgentType,\n \"claude\" | \"codex\" | \"copilot\" | \"gemini_cli\" | \"grok_cli\" | \"opencode\" | \"pi\"\n>;\n\nexport interface AgentConfig {\n /** Shell command to launch the agent (sent to tmux via `send-keys`). */\n command: string;\n /** Returns true if the given `ps` command line belongs to this agent. */\n matches: (psCommand: string) => boolean;\n}\n\n/**\n * Per-agent configuration: launch command plus a matcher that recognizes the\n * agent's process in `ps` output. Each matcher knows that agent's distribution\n * quirks (e.g. gemini ships as a Node script so its real binary is in argv[1..]).\n */\nexport const AGENTS: Record<StartableAgentType, AgentConfig> = {\n claude: { command: \"claude\", matches: matchArgv0(\"claude\") },\n codex: { command: \"codex\", matches: matchArgv0(\"codex\") },\n copilot: { command: \"copilot\", matches: matchArgv0Name(\"copilot-cli\") },\n gemini_cli: { command: \"gemini\", matches: matchAnyToken(\"gemini\") },\n grok_cli: { command: \"grok\", matches: matchArgv0(\"grok\") },\n opencode: { command: \"opencode\", matches: matchArgv0(\"opencode\") },\n pi: { command: \"pi\", matches: matchAnyBasename([\"pi\"]) },\n};\n\nfunction matchArgv0(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n const token = psCommand.trim().split(/\\s+/)[0];\n return token ? path.basename(token).toLowerCase() === lower : false;\n };\n}\n\nfunction matchArgv0Name(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n const token = psCommand.trim().split(/\\s+/)[0];\n return token ? token.toLowerCase().includes(lower) : false;\n };\n}\n\nfunction matchAnyToken(name: string): (psCommand: string) => boolean {\n const lower = name.toLowerCase();\n return (psCommand) => {\n for (const token of psCommand.trim().split(/\\s+/)) {\n if (path.basename(token).toLowerCase() === lower) return true;\n }\n return false;\n };\n}\n\nfunction matchAnyBasename(names: string[]): (psCommand: string) => boolean {\n const lowers = new Set(names.map((name) => name.toLowerCase()));\n return (psCommand) => {\n for (const token of psCommand.trim().split(/\\s+/)) {\n if (lowers.has(path.basename(token).toLowerCase())) return true;\n }\n return false;\n };\n}\n"],"names":["path","AGENTS","claude","command","matches","matchArgv0","codex","copilot","matchArgv0Name","gemini_cli","matchAnyToken","grok_cli","opencode","pi","matchAnyBasename","name","lower","toLowerCase","psCommand","token","trim","split","basename","includes","names","lowers","Set","map","has"],"mappings":"AAAA,OAAOA,UAAU,OAAO;AAexB;;;;CAIC,GACD,OAAO,MAAMC,SAAkD;IAC7DC,QAAQ;QAAEC,SAAS;QAAUC,SAASC,WAAW;IAAU;IAC3DC,OAAO;QAAEH,SAAS;QAASC,SAASC,WAAW;IAAS;IACxDE,SAAS;QAAEJ,SAAS;QAAWC,SAASI,eAAe;IAAe;IACtEC,YAAY;QAAEN,SAAS;QAAUC,SAASM,cAAc;IAAU;IAClEC,UAAU;QAAER,SAAS;QAAQC,SAASC,WAAW;IAAQ;IACzDO,UAAU;QAAET,SAAS;QAAYC,SAASC,WAAW;IAAY;IACjEQ,IAAI;QAAEV,SAAS;QAAMC,SAASU,iBAAiB;YAAC;SAAK;IAAE;AACzD,EAAE;AAEF,SAAST,WAAWU,IAAY;IAC9B,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACN,MAAMC,QAAQD,UAAUE,IAAI,GAAGC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC9C,OAAOF,QAAQnB,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,OAAOD,QAAQ;IAChE;AACF;AAEA,SAASR,eAAeO,IAAY;IAClC,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACN,MAAMC,QAAQD,UAAUE,IAAI,GAAGC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC9C,OAAOF,QAAQA,MAAMF,WAAW,GAAGM,QAAQ,CAACP,SAAS;IACvD;AACF;AAEA,SAASN,cAAcK,IAAY;IACjC,MAAMC,QAAQD,KAAKE,WAAW;IAC9B,OAAO,CAACC;QACN,KAAK,MAAMC,SAASD,UAAUE,IAAI,GAAGC,KAAK,CAAC,OAAQ;YACjD,IAAIrB,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,OAAOD,OAAO,OAAO;QAC3D;QACA,OAAO;IACT;AACF;AAEA,SAASF,iBAAiBU,KAAe;IACvC,MAAMC,SAAS,IAAIC,IAAIF,MAAMG,GAAG,CAAC,CAACZ,OAASA,KAAKE,WAAW;IAC3D,OAAO,CAACC;QACN,KAAK,MAAMC,SAASD,UAAUE,IAAI,GAAGC,KAAK,CAAC,OAAQ;YACjD,IAAII,OAAOG,GAAG,CAAC5B,KAAKsB,QAAQ,CAACH,OAAOF,WAAW,KAAK,OAAO;QAC7D;QACA,OAAO;IACT;AACF"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Escape a string for safe use inside an AppleScript double-quoted string.
|
|
3
3
|
* Backslashes, double quotes, and newlines must be escaped.
|
|
4
4
|
*/ export function escapeAppleScript(text) {
|
|
5
|
-
return text.replace(/\\/g,
|
|
5
|
+
return text.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r\n|\r|\n/g, "\\n");
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
//# sourceMappingURL=applescript.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/applescript.ts"],"sourcesContent":["/**\n * Escape a string for safe use inside an AppleScript double-quoted string.\n * Backslashes, double quotes, and newlines must be escaped.\n */\nexport function escapeAppleScript(text: string): string {\n
|
|
1
|
+
{"version":3,"sources":["../../src/utils/applescript.ts"],"sourcesContent":["/**\n * Escape a string for safe use inside an AppleScript double-quoted string.\n * Backslashes, double quotes, and newlines must be escaped.\n */\nexport function escapeAppleScript(text: string): string {\n return text\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\r\\n|\\r|\\n/g, \"\\\\n\");\n}\n"],"names":["escapeAppleScript","text","replace"],"mappings":"AAAA;;;CAGC,GACD,OAAO,SAASA,kBAAkBC,IAAY;IAC5C,OAAOA,KACJC,OAAO,CAAC,OAAO,QACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,eAAe;AAC5B"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from
|
|
2
|
-
export { getProcessTty } from
|
|
3
|
-
export { batchGetSessionFileBirthtimes } from
|
|
4
|
-
export type { SessionFile } from
|
|
5
|
-
export { matchProcessesToSessions, generateAgentName } from
|
|
6
|
-
export type { MatchResult } from
|
|
1
|
+
export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot, } from "./process.js";
|
|
2
|
+
export { getProcessTty } from "./process.js";
|
|
3
|
+
export { batchGetSessionFileBirthtimes } from "./session.js";
|
|
4
|
+
export type { SessionFile } from "./session.js";
|
|
5
|
+
export { matchProcessesToSessions, generateAgentName } from "./matching.js";
|
|
6
|
+
export type { MatchResult } from "./matching.js";
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,eAAe,EACf,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/utils/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from
|
|
2
|
-
export { getProcessTty } from
|
|
3
|
-
export { batchGetSessionFileBirthtimes } from
|
|
4
|
-
export { matchProcessesToSessions, generateAgentName } from
|
|
1
|
+
export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from "./process.js";
|
|
2
|
+
export { getProcessTty } from "./process.js";
|
|
3
|
+
export { batchGetSessionFileBirthtimes } from "./session.js";
|
|
4
|
+
export { matchProcessesToSessions, generateAgentName } from "./matching.js";
|
|
5
5
|
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export {
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export {\n listAgentProcesses,\n batchGetProcessCwds,\n batchGetProcessStartTimes,\n enrichProcesses,\n captureProcessSnapshot,\n} from \"./process.js\";\nexport { getProcessTty } from \"./process.js\";\nexport { batchGetSessionFileBirthtimes } from \"./session.js\";\nexport type { SessionFile } from \"./session.js\";\nexport { matchProcessesToSessions, generateAgentName } from \"./matching.js\";\nexport type { MatchResult } from \"./matching.js\";\n"],"names":["listAgentProcesses","batchGetProcessCwds","batchGetProcessStartTimes","enrichProcesses","captureProcessSnapshot","getProcessTty","batchGetSessionFileBirthtimes","matchProcessesToSessions","generateAgentName"],"mappings":"AAAA,SACEA,kBAAkB,EAClBC,mBAAmB,EACnBC,yBAAyB,EACzBC,eAAe,EACfC,sBAAsB,QACjB,eAAe;AACtB,SAASC,aAAa,QAAQ,eAAe;AAC7C,SAASC,6BAA6B,QAAQ,eAAe;AAE7D,SAASC,wBAAwB,EAAEC,iBAAiB,QAAQ,gBAAgB"}
|
package/dist/utils/matching.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Shared 1:1 greedy matching algorithm that pairs running processes with session files
|
|
5
5
|
* based on CWD and birth-time proximity to process start time.
|
|
6
6
|
*/
|
|
7
|
-
import type { ProcessInfo } from
|
|
8
|
-
import type { SessionFile } from
|
|
7
|
+
import type { ProcessInfo } from "../adapters/AgentAdapter.js";
|
|
8
|
+
import type { SessionFile } from "./session.js";
|
|
9
9
|
/**
|
|
10
10
|
* Result of matching a process to a session file.
|
|
11
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD;;GAEG;AACH,MAAM,WAAW,WAAW;
|
|
1
|
+
{"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,OAAO,EAAE,WAAW,CAAC;IAErB,+BAA+B;IAC/B,OAAO,EAAE,WAAW,CAAC;IAErB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,WAAW,EAAE,EACxB,QAAQ,EAAE,WAAW,EAAE,GACtB,WAAW,EAAE,CAsCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlE"}
|
package/dist/utils/matching.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Shared 1:1 greedy matching algorithm that pairs running processes with session files
|
|
5
5
|
* based on CWD and birth-time proximity to process start time.
|
|
6
|
-
*/ import * as path from
|
|
6
|
+
*/ import * as path from "path";
|
|
7
7
|
/** Maximum allowed delta between process start time and session file birth time. */ const TOLERANCE_MS = 3 * 60 * 1000; // 3 minutes
|
|
8
8
|
/**
|
|
9
9
|
* Match processes to session files using 1:1 greedy assignment.
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
*
|
|
55
55
|
* Format: "folder-name-pid" (lowercase kebab-case)
|
|
56
56
|
*/ export function generateAgentName(cwd, pid) {
|
|
57
|
-
const folderName = path.basename(cwd) ||
|
|
58
|
-
const kebab = folderName.toLowerCase().replace(/[^a-z0-9]+/g,
|
|
59
|
-
return `${kebab ||
|
|
57
|
+
const folderName = path.basename(cwd) || "unknown";
|
|
58
|
+
const kebab = folderName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
59
|
+
return `${kebab || "unknown"}-${pid}`;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
//# sourceMappingURL=matching.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/matching.ts"],"sourcesContent":["/**\n * Session Matching Utilities\n *\n * Shared 1:1 greedy matching algorithm that pairs running processes with session files\n * based on CWD and birth-time proximity to process start time.\n */\n\nimport * as path from
|
|
1
|
+
{"version":3,"sources":["../../src/utils/matching.ts"],"sourcesContent":["/**\n * Session Matching Utilities\n *\n * Shared 1:1 greedy matching algorithm that pairs running processes with session files\n * based on CWD and birth-time proximity to process start time.\n */\n\nimport * as path from \"path\";\nimport type { ProcessInfo } from \"../adapters/AgentAdapter.js\";\nimport type { SessionFile } from \"./session.js\";\n\n/** Maximum allowed delta between process start time and session file birth time. */\nconst TOLERANCE_MS = 3 * 60 * 1000; // 3 minutes\n\n/**\n * Result of matching a process to a session file.\n */\nexport interface MatchResult {\n /** The matched process */\n process: ProcessInfo;\n\n /** The matched session file */\n session: SessionFile;\n\n /** Absolute time delta in ms between process start and session birth time */\n deltaMs: number;\n}\n\n/**\n * Match processes to session files using 1:1 greedy assignment.\n *\n * Algorithm:\n * 1. Exclude processes without startTime (they become process-only fallback).\n * 2. Build candidate pairs where process.cwd === session.resolvedCwd\n * and |process.startTime - session.birthtimeMs| <= 3 minutes.\n * 3. Sort candidates by deltaMs ascending (best matches first).\n * 4. Greedily assign: once a process or session is matched, skip it.\n *\n * Adapters must set session.resolvedCwd before calling this function.\n */\nexport function matchProcessesToSessions(\n processes: ProcessInfo[],\n sessions: SessionFile[],\n): MatchResult[] {\n // Build all candidate pairs\n const candidates: Array<{ process: ProcessInfo; session: SessionFile; deltaMs: number }> = [];\n\n for (const proc of processes) {\n if (!proc.startTime || !proc.cwd) continue;\n\n const processStartMs = proc.startTime.getTime();\n\n for (const session of sessions) {\n if (!session.resolvedCwd) continue;\n if (proc.cwd !== session.resolvedCwd) continue;\n\n const deltaMs = Math.abs(processStartMs - session.birthtimeMs);\n if (deltaMs > TOLERANCE_MS) continue;\n\n candidates.push({ process: proc, session, deltaMs });\n }\n }\n\n // Sort by smallest delta first\n candidates.sort((a, b) => a.deltaMs - b.deltaMs);\n\n // Greedy 1:1 assignment\n const matchedPids = new Set<number>();\n const matchedSessionIds = new Set<string>();\n const results: MatchResult[] = [];\n\n for (const candidate of candidates) {\n if (matchedPids.has(candidate.process.pid)) continue;\n if (matchedSessionIds.has(candidate.session.sessionId)) continue;\n\n matchedPids.add(candidate.process.pid);\n matchedSessionIds.add(candidate.session.sessionId);\n results.push(candidate);\n }\n\n return results;\n}\n\n/**\n * Generate a deterministic agent name from CWD and PID.\n *\n * Format: \"folder-name-pid\" (lowercase kebab-case)\n */\nexport function generateAgentName(cwd: string, pid: number): string {\n const folderName = path.basename(cwd) || \"unknown\";\n const kebab = folderName\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return `${kebab || \"unknown\"}-${pid}`;\n}\n"],"names":["path","TOLERANCE_MS","matchProcessesToSessions","processes","sessions","candidates","proc","startTime","cwd","processStartMs","getTime","session","resolvedCwd","deltaMs","Math","abs","birthtimeMs","push","process","sort","a","b","matchedPids","Set","matchedSessionIds","results","candidate","has","pid","sessionId","add","generateAgentName","folderName","basename","kebab","toLowerCase","replace"],"mappings":"AAAA;;;;;CAKC,GAED,YAAYA,UAAU,OAAO;AAI7B,kFAAkF,GAClF,MAAMC,eAAe,IAAI,KAAK,MAAM,YAAY;AAgBhD;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,yBACdC,SAAwB,EACxBC,QAAuB;IAEvB,4BAA4B;IAC5B,MAAMC,aAAqF,EAAE;IAE7F,KAAK,MAAMC,QAAQH,UAAW;QAC5B,IAAI,CAACG,KAAKC,SAAS,IAAI,CAACD,KAAKE,GAAG,EAAE;QAElC,MAAMC,iBAAiBH,KAAKC,SAAS,CAACG,OAAO;QAE7C,KAAK,MAAMC,WAAWP,SAAU;YAC9B,IAAI,CAACO,QAAQC,WAAW,EAAE;YAC1B,IAAIN,KAAKE,GAAG,KAAKG,QAAQC,WAAW,EAAE;YAEtC,MAAMC,UAAUC,KAAKC,GAAG,CAACN,iBAAiBE,QAAQK,WAAW;YAC7D,IAAIH,UAAUZ,cAAc;YAE5BI,WAAWY,IAAI,CAAC;gBAAEC,SAASZ;gBAAMK;gBAASE;YAAQ;QACpD;IACF;IAEA,+BAA+B;IAC/BR,WAAWc,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEP,OAAO,GAAGQ,EAAER,OAAO;IAE/C,wBAAwB;IACxB,MAAMS,cAAc,IAAIC;IACxB,MAAMC,oBAAoB,IAAID;IAC9B,MAAME,UAAyB,EAAE;IAEjC,KAAK,MAAMC,aAAarB,WAAY;QAClC,IAAIiB,YAAYK,GAAG,CAACD,UAAUR,OAAO,CAACU,GAAG,GAAG;QAC5C,IAAIJ,kBAAkBG,GAAG,CAACD,UAAUf,OAAO,CAACkB,SAAS,GAAG;QAExDP,YAAYQ,GAAG,CAACJ,UAAUR,OAAO,CAACU,GAAG;QACrCJ,kBAAkBM,GAAG,CAACJ,UAAUf,OAAO,CAACkB,SAAS;QACjDJ,QAAQR,IAAI,CAACS;IACf;IAEA,OAAOD;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASM,kBAAkBvB,GAAW,EAAEoB,GAAW;IACxD,MAAMI,aAAahC,KAAKiC,QAAQ,CAACzB,QAAQ;IACzC,MAAM0B,QAAQF,WACXG,WAAW,GACXC,OAAO,CAAC,eAAe,KACvBA,OAAO,CAAC,YAAY;IACvB,OAAO,GAAGF,SAAS,UAAU,CAAC,EAAEN,KAAK;AACvC"}
|
package/dist/utils/process.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Built-in refresh discovery uses captureProcessSnapshot(); synchronous helpers
|
|
6
6
|
* remain exported for compatibility with existing consumers.
|
|
7
7
|
*/
|
|
8
|
-
import type { ProcessInfo } from
|
|
8
|
+
import type { ProcessInfo } from "../adapters/AgentAdapter.js";
|
|
9
9
|
export declare function executableBasename(command: string): string;
|
|
10
10
|
export declare function filterByProcessNames(processes: readonly ProcessInfo[], namePatterns: readonly string[]): ProcessInfo[];
|
|
11
11
|
/**
|