@ai-devkit/agent-manager 0.35.0 → 0.37.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 +9 -4
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +21 -2
- package/dist/AgentManager.js.map +1 -1
- package/dist/__tests__/AgentManager.test.js +151 -3
- package/dist/__tests__/AgentManager.test.js.map +1 -1
- package/dist/__tests__/adapters/IncrementalSessionRefresh.test.js +486 -0
- package/dist/__tests__/adapters/IncrementalSessionRefresh.test.js.map +1 -0
- package/dist/__tests__/adapters/adapterProcessImports.test.js +52 -0
- package/dist/__tests__/adapters/adapterProcessImports.test.js.map +1 -0
- package/dist/__tests__/adapters/adapterSnapshotCandidates.test.js +247 -0
- package/dist/__tests__/adapters/adapterSnapshotCandidates.test.js.map +1 -0
- package/dist/__tests__/capacity/claude.test.js +485 -0
- package/dist/__tests__/capacity/claude.test.js.map +1 -0
- package/dist/__tests__/capacity/openai.test.js +670 -0
- package/dist/__tests__/capacity/openai.test.js.map +1 -0
- package/dist/__tests__/capacity/wham.test.js +144 -0
- package/dist/__tests__/capacity/wham.test.js.map +1 -0
- package/dist/__tests__/harnesses/BoundedSummarySkip.test.js +568 -0
- package/dist/__tests__/harnesses/BoundedSummarySkip.test.js.map +1 -0
- package/dist/__tests__/harnesses/SessionSummaryEquivalence.test.js +1089 -0
- package/dist/__tests__/harnesses/SessionSummaryEquivalence.test.js.map +1 -0
- package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.js +143 -0
- package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.js.map +1 -0
- package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.js +462 -0
- package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.js.map +1 -0
- package/dist/__tests__/harnesses/builtinAdapters.test.js +33 -0
- package/dist/__tests__/harnesses/builtinAdapters.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/claude/ClaudeAgentMapper.test.js +4 -4
- package/dist/__tests__/harnesses/claude/ClaudeAgentMapper.test.js.map +1 -0
- package/dist/__tests__/{adapters → harnesses/claude}/ClaudeCodeAdapter.test.js +47 -19
- package/dist/__tests__/harnesses/claude/ClaudeCodeAdapter.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/claude/ClaudeSessionLocator.test.js +1 -12
- package/dist/__tests__/{providers → harnesses}/claude/ClaudeSessionLocator.test.js.map +1 -1
- package/dist/__tests__/{utils → harnesses/claude}/ClaudeSessionParser.test.js +2 -2
- package/dist/__tests__/harnesses/claude/ClaudeSessionParser.test.js.map +1 -0
- package/dist/__tests__/{print → harnesses/claude/durable}/ClaudeCliProbe.test.js +1 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudeCliProbe.test.js.map +1 -0
- package/dist/__tests__/{print → harnesses/claude/durable}/ClaudePrintAgent.integration.test.js +1 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -0
- package/dist/__tests__/{print → harnesses/claude/durable}/ClaudePrintAgentService.test.js +4 -4
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgentService.test.js.map +1 -0
- package/dist/__tests__/{print → harnesses/claude/durable}/ClaudePrintRunner.test.js +1 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -0
- package/dist/__tests__/{adapters → harnesses/codex}/CodexAdapter.test.js +304 -10
- package/dist/__tests__/harnesses/codex/CodexAdapter.test.js.map +1 -0
- package/dist/__tests__/harnesses/codex/CodexSessionLocator.test.js +463 -0
- package/dist/__tests__/harnesses/codex/CodexSessionLocator.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/codex/CodexSessionMapping.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/codex/CodexSessionMapping.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/codex/CodexSessionParser.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/codex/CodexSessionParser.test.js.map +1 -1
- package/dist/__tests__/{durable → harnesses/codex/durable}/CodexCliProbe.test.js +4 -4
- package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -0
- package/dist/__tests__/{durable → harnesses/codex/durable}/CodexDurableAgentRepository.test.js +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexDurableAgentRepository.test.js.map +1 -0
- package/dist/__tests__/{durable → harnesses/codex/durable}/CodexPrintAgent.integration.test.js +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -0
- package/dist/__tests__/{durable → harnesses/codex/durable}/CodexPrintAgentService.test.js +8 -18
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -0
- package/dist/__tests__/{durable → harnesses/codex/durable}/CodexPrintRunner.test.js +2 -7
- package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/copilot/CopilotAdapter.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/copilot/CopilotAdapter.test.js.map +1 -1
- package/dist/__tests__/harnesses/copilot/CopilotRefreshIO.test.js +290 -0
- package/dist/__tests__/harnesses/copilot/CopilotRefreshIO.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/gemini/GeminiCliAdapter.test.js +34 -25
- package/dist/__tests__/harnesses/gemini/GeminiCliAdapter.test.js.map +1 -0
- package/dist/__tests__/harnesses/gemini/GeminiSessionJsonl.test.js +491 -0
- package/dist/__tests__/harnesses/gemini/GeminiSessionJsonl.test.js.map +1 -0
- package/dist/__tests__/harnesses/gemini/GeminiSessionLocator.test.js +399 -0
- package/dist/__tests__/harnesses/gemini/GeminiSessionLocator.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/grok/GrokAgentMapper.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/grok/GrokAgentMapper.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/grok/GrokCliAdapter.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/grok/GrokCliAdapter.test.js.map +1 -1
- package/dist/__tests__/harnesses/grok/GrokIncrementalRefresh.test.js +167 -0
- package/dist/__tests__/harnesses/grok/GrokIncrementalRefresh.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/grok/GrokSessionLocator.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/grok/GrokSessionLocator.test.js.map +1 -1
- package/dist/__tests__/harnesses/grok/GrokSessionParser.test.js +301 -0
- package/dist/__tests__/harnesses/grok/GrokSessionParser.test.js.map +1 -0
- package/dist/__tests__/harnesses/kiro/KiroAdapter.test.js +662 -0
- package/dist/__tests__/harnesses/kiro/KiroAdapter.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeAdapter.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeAdapter.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeAgentMapper.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeAgentMapper.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeSessionLocator.test.js +2 -2
- package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeSessionLocator.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeSessionParser.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeSessionParser.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/PiAdapter.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/PiAdapter.test.js.map +1 -1
- package/dist/__tests__/harnesses/pi/PiDiscoveryIO.test.js +382 -0
- package/dist/__tests__/harnesses/pi/PiDiscoveryIO.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/pi/PiSessionParser.test.js +171 -1
- package/dist/__tests__/harnesses/pi/PiSessionParser.test.js.map +1 -0
- package/dist/__tests__/{providers → harnesses}/pi/PiSessionTracker.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/PiSessionTracker.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/durable/PiCliProbe.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintAgentService.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintProtocol.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintProtocol.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintRunner.test.js.map +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/durable/PiStreamParser.test.js +1 -1
- package/dist/__tests__/{providers → harnesses}/pi/durable/PiStreamParser.test.js.map +1 -1
- package/dist/__tests__/readiness/AgentReadiness.test.js +20 -0
- package/dist/__tests__/readiness/AgentReadiness.test.js.map +1 -1
- package/dist/__tests__/runtime/ManagedAgentRuntime.test.js +49 -0
- package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
- package/dist/__tests__/utils/IncrementalJsonlSummary.test.js +650 -0
- package/dist/__tests__/utils/IncrementalJsonlSummary.test.js.map +1 -0
- package/dist/__tests__/utils/agents.test.js +72 -2
- package/dist/__tests__/utils/agents.test.js.map +1 -1
- package/dist/__tests__/utils/conversationTail.bench.test.js +258 -0
- package/dist/__tests__/utils/conversationTail.bench.test.js.map +1 -0
- package/dist/__tests__/utils/conversationTailParity.test.js +588 -0
- package/dist/__tests__/utils/conversationTailParity.test.js.map +1 -0
- package/dist/__tests__/utils/jsonlTail.test.js +360 -0
- package/dist/__tests__/utils/jsonlTail.test.js.map +1 -0
- package/dist/__tests__/utils/matchingConstants.test.js +35 -0
- package/dist/__tests__/utils/matchingConstants.test.js.map +1 -0
- package/dist/__tests__/utils/process.test.js +436 -2
- package/dist/__tests__/utils/process.test.js.map +1 -1
- package/dist/adapters/AgentAdapter.d.ts +25 -6
- package/dist/adapters/AgentAdapter.d.ts.map +1 -1
- package/dist/adapters/AgentAdapter.js +12 -3
- package/dist/adapters/AgentAdapter.js.map +1 -1
- package/dist/capacity/claude.d.ts +17 -0
- package/dist/capacity/claude.d.ts.map +1 -0
- package/dist/capacity/claude.js +271 -0
- package/dist/capacity/claude.js.map +1 -0
- package/dist/capacity/codex.d.ts +1 -2
- package/dist/capacity/codex.d.ts.map +1 -1
- package/dist/capacity/codex.js +5 -47
- package/dist/capacity/codex.js.map +1 -1
- package/dist/capacity/index.d.ts +11 -0
- package/dist/capacity/index.d.ts.map +1 -1
- package/dist/capacity/index.js +17 -0
- package/dist/capacity/index.js.map +1 -1
- package/dist/capacity/openai.d.ts +47 -0
- package/dist/capacity/openai.d.ts.map +1 -0
- package/dist/capacity/openai.js +307 -0
- package/dist/capacity/openai.js.map +1 -0
- package/dist/capacity/wham.d.ts +16 -0
- package/dist/capacity/wham.d.ts.map +1 -0
- package/dist/capacity/wham.js +66 -0
- package/dist/capacity/wham.js.map +1 -0
- package/dist/harnesses/antigravity/AntigravityAgentMapper.d.ts +13 -0
- package/dist/harnesses/antigravity/AntigravityAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/antigravity/AntigravityAgentMapper.js +30 -0
- package/dist/harnesses/antigravity/AntigravityAgentMapper.js.map +1 -0
- package/dist/harnesses/antigravity/AntigravityCliAdapter.d.ts +32 -0
- package/dist/harnesses/antigravity/AntigravityCliAdapter.d.ts.map +1 -0
- package/dist/harnesses/antigravity/AntigravityCliAdapter.js +97 -0
- package/dist/harnesses/antigravity/AntigravityCliAdapter.js.map +1 -0
- package/dist/harnesses/antigravity/AntigravitySessionLocator.d.ts +30 -0
- package/dist/harnesses/antigravity/AntigravitySessionLocator.d.ts.map +1 -0
- package/dist/harnesses/antigravity/AntigravitySessionLocator.js +56 -0
- package/dist/harnesses/antigravity/AntigravitySessionLocator.js.map +1 -0
- package/dist/harnesses/antigravity/AntigravitySessionParser.d.ts +75 -0
- package/dist/harnesses/antigravity/AntigravitySessionParser.d.ts.map +1 -0
- package/dist/harnesses/antigravity/AntigravitySessionParser.js +174 -0
- package/dist/harnesses/antigravity/AntigravitySessionParser.js.map +1 -0
- package/dist/{providers → harnesses}/claude/ClaudeAgentMapper.d.ts.map +1 -1
- package/dist/{providers → harnesses}/claude/ClaudeAgentMapper.js +4 -10
- package/dist/harnesses/claude/ClaudeAgentMapper.js.map +1 -0
- package/dist/{providers → harnesses}/claude/ClaudeCodeAdapter.d.ts +5 -6
- package/dist/harnesses/claude/ClaudeCodeAdapter.d.ts.map +1 -0
- package/dist/{providers → harnesses}/claude/ClaudeCodeAdapter.js +17 -15
- package/dist/harnesses/claude/ClaudeCodeAdapter.js.map +1 -0
- package/dist/{providers → harnesses}/claude/ClaudeSessionLocator.d.ts.map +1 -1
- package/dist/{providers → harnesses}/claude/ClaudeSessionLocator.js +3 -3
- package/dist/harnesses/claude/ClaudeSessionLocator.js.map +1 -0
- package/dist/{providers → harnesses}/claude/ClaudeSessionParser.d.ts +40 -6
- package/dist/harnesses/claude/ClaudeSessionParser.d.ts.map +1 -0
- package/dist/{providers → harnesses}/claude/ClaudeSessionParser.js +141 -85
- package/dist/harnesses/claude/ClaudeSessionParser.js.map +1 -0
- package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.d.ts.map +1 -1
- package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.js.map +1 -1
- package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.d.ts.map +1 -1
- package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.js.map +1 -1
- package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.d.ts.map +1 -1
- package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.js.map +1 -1
- package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.d.ts.map +1 -1
- package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.js.map +1 -1
- package/dist/{providers → harnesses}/codex/CodexAdapter.d.ts +5 -4
- package/dist/harnesses/codex/CodexAdapter.d.ts.map +1 -0
- package/dist/{providers → harnesses}/codex/CodexAdapter.js +139 -19
- package/dist/harnesses/codex/CodexAdapter.js.map +1 -0
- package/dist/{providers → harnesses}/codex/CodexAgentMapper.d.ts.map +1 -1
- package/dist/{providers → harnesses}/codex/CodexAgentMapper.js +4 -11
- package/dist/harnesses/codex/CodexAgentMapper.js.map +1 -0
- package/dist/harnesses/codex/CodexSessionLocator.d.ts +74 -0
- package/dist/harnesses/codex/CodexSessionLocator.d.ts.map +1 -0
- package/dist/harnesses/codex/CodexSessionLocator.js +359 -0
- package/dist/harnesses/codex/CodexSessionLocator.js.map +1 -0
- package/dist/{providers → harnesses}/codex/CodexSessionMapping.d.ts.map +1 -1
- package/dist/{providers → harnesses}/codex/CodexSessionMapping.js +3 -3
- package/dist/harnesses/codex/CodexSessionMapping.js.map +1 -0
- package/dist/harnesses/codex/CodexSessionParser.d.ts +89 -0
- package/dist/harnesses/codex/CodexSessionParser.d.ts.map +1 -0
- package/dist/{providers → harnesses}/codex/CodexSessionParser.js +124 -78
- package/dist/harnesses/codex/CodexSessionParser.js.map +1 -0
- package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.d.ts.map +1 -1
- package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.js.map +1 -1
- package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.d.ts.map +1 -1
- package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.js.map +1 -1
- package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.d.ts.map +1 -1
- package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.js.map +1 -1
- package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.d.ts.map +1 -1
- package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.js.map +1 -1
- package/dist/{providers → harnesses}/copilot/CopilotAdapter.d.ts +7 -6
- package/dist/harnesses/copilot/CopilotAdapter.d.ts.map +1 -0
- package/dist/{providers → harnesses}/copilot/CopilotAdapter.js +19 -14
- package/dist/harnesses/copilot/CopilotAdapter.js.map +1 -0
- package/dist/{providers → harnesses}/copilot/CopilotAgentMapper.d.ts.map +1 -1
- package/dist/{providers → harnesses}/copilot/CopilotAgentMapper.js +4 -11
- package/dist/harnesses/copilot/CopilotAgentMapper.js.map +1 -0
- package/dist/harnesses/copilot/CopilotSessionLocator.d.ts +42 -0
- package/dist/harnesses/copilot/CopilotSessionLocator.d.ts.map +1 -0
- package/dist/harnesses/copilot/CopilotSessionLocator.js +126 -0
- package/dist/harnesses/copilot/CopilotSessionLocator.js.map +1 -0
- package/dist/harnesses/copilot/CopilotSessionParser.d.ts +62 -0
- package/dist/harnesses/copilot/CopilotSessionParser.d.ts.map +1 -0
- package/dist/harnesses/copilot/CopilotSessionParser.js +236 -0
- package/dist/harnesses/copilot/CopilotSessionParser.js.map +1 -0
- package/dist/{providers → harnesses}/gemini/GeminiAgentMapper.d.ts.map +1 -1
- package/dist/{providers → harnesses}/gemini/GeminiAgentMapper.js +4 -11
- package/dist/harnesses/gemini/GeminiAgentMapper.js.map +1 -0
- package/dist/{providers → harnesses}/gemini/GeminiCliAdapter.d.ts +4 -5
- package/dist/harnesses/gemini/GeminiCliAdapter.d.ts.map +1 -0
- package/dist/{providers → harnesses}/gemini/GeminiCliAdapter.js +6 -7
- package/dist/harnesses/gemini/GeminiCliAdapter.js.map +1 -0
- package/dist/harnesses/gemini/GeminiSessionLocator.d.ts +72 -0
- package/dist/harnesses/gemini/GeminiSessionLocator.d.ts.map +1 -0
- package/dist/harnesses/gemini/GeminiSessionLocator.js +300 -0
- package/dist/harnesses/gemini/GeminiSessionLocator.js.map +1 -0
- package/dist/{providers → harnesses}/gemini/GeminiSessionParser.d.ts +34 -7
- package/dist/harnesses/gemini/GeminiSessionParser.d.ts.map +1 -0
- package/dist/harnesses/gemini/GeminiSessionParser.js +272 -0
- package/dist/harnesses/gemini/GeminiSessionParser.js.map +1 -0
- package/dist/harnesses/gemini/fileSignature.d.ts +8 -0
- package/dist/harnesses/gemini/fileSignature.d.ts.map +1 -0
- package/dist/harnesses/gemini/fileSignature.js +9 -0
- package/dist/harnesses/gemini/fileSignature.js.map +1 -0
- package/dist/{providers → harnesses}/grok/GrokAgentMapper.d.ts.map +1 -1
- package/dist/{providers → harnesses}/grok/GrokAgentMapper.js +4 -10
- package/dist/harnesses/grok/GrokAgentMapper.js.map +1 -0
- package/dist/{providers → harnesses}/grok/GrokCliAdapter.d.ts +5 -5
- package/dist/harnesses/grok/GrokCliAdapter.d.ts.map +1 -0
- package/dist/{providers → harnesses}/grok/GrokCliAdapter.js +14 -10
- package/dist/harnesses/grok/GrokCliAdapter.js.map +1 -0
- package/dist/{providers → harnesses}/grok/GrokSessionLocator.d.ts.map +1 -1
- package/dist/{providers → harnesses}/grok/GrokSessionLocator.js +2 -2
- package/dist/harnesses/grok/GrokSessionLocator.js.map +1 -0
- package/dist/harnesses/grok/GrokSessionParser.d.ts +87 -0
- package/dist/harnesses/grok/GrokSessionParser.d.ts.map +1 -0
- package/dist/harnesses/grok/GrokSessionParser.js +185 -0
- package/dist/harnesses/grok/GrokSessionParser.js.map +1 -0
- package/dist/harnesses/index.d.ts +7 -0
- package/dist/harnesses/index.d.ts.map +1 -0
- package/dist/harnesses/index.js +27 -0
- package/dist/harnesses/index.js.map +1 -0
- package/dist/harnesses/kiro/KiroAdapter.d.ts +31 -0
- package/dist/harnesses/kiro/KiroAdapter.d.ts.map +1 -0
- package/dist/harnesses/kiro/KiroAdapter.js +125 -0
- package/dist/harnesses/kiro/KiroAdapter.js.map +1 -0
- package/dist/harnesses/kiro/KiroAgentMapper.d.ts +13 -0
- package/dist/harnesses/kiro/KiroAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/kiro/KiroAgentMapper.js +29 -0
- package/dist/harnesses/kiro/KiroAgentMapper.js.map +1 -0
- package/dist/harnesses/kiro/KiroSessionLocator.d.ts +38 -0
- package/dist/harnesses/kiro/KiroSessionLocator.d.ts.map +1 -0
- package/dist/harnesses/kiro/KiroSessionLocator.js +95 -0
- package/dist/harnesses/kiro/KiroSessionLocator.js.map +1 -0
- package/dist/harnesses/kiro/KiroSessionParser.d.ts +81 -0
- package/dist/harnesses/kiro/KiroSessionParser.d.ts.map +1 -0
- package/dist/harnesses/kiro/KiroSessionParser.js +251 -0
- package/dist/harnesses/kiro/KiroSessionParser.js.map +1 -0
- package/dist/{providers → harnesses}/opencode/OpenCodeAdapter.d.ts +2 -4
- package/dist/harnesses/opencode/OpenCodeAdapter.d.ts.map +1 -0
- package/dist/{providers → harnesses}/opencode/OpenCodeAdapter.js +4 -7
- package/dist/harnesses/opencode/OpenCodeAdapter.js.map +1 -0
- package/dist/{providers → harnesses}/opencode/OpenCodeAgentMapper.d.ts.map +1 -1
- package/dist/{providers → harnesses}/opencode/OpenCodeAgentMapper.js +5 -13
- package/dist/harnesses/opencode/OpenCodeAgentMapper.js.map +1 -0
- package/dist/{providers → harnesses}/opencode/OpenCodeSessionLocator.d.ts.map +1 -1
- package/dist/{providers → harnesses}/opencode/OpenCodeSessionLocator.js +2 -2
- package/dist/harnesses/opencode/OpenCodeSessionLocator.js.map +1 -0
- package/dist/{providers → harnesses}/opencode/OpenCodeSessionParser.d.ts +2 -4
- package/dist/harnesses/opencode/OpenCodeSessionParser.d.ts.map +1 -0
- package/dist/{providers → harnesses}/opencode/OpenCodeSessionParser.js +2 -1
- package/dist/harnesses/opencode/OpenCodeSessionParser.js.map +1 -0
- package/dist/{providers → harnesses}/pi/PiAdapter.d.ts +5 -4
- package/dist/harnesses/pi/PiAdapter.d.ts.map +1 -0
- package/dist/{providers → harnesses}/pi/PiAdapter.js +16 -12
- package/dist/harnesses/pi/PiAdapter.js.map +1 -0
- package/dist/{providers → harnesses}/pi/PiAgentMapper.d.ts.map +1 -1
- package/dist/{providers → harnesses}/pi/PiAgentMapper.js +4 -11
- package/dist/harnesses/pi/PiAgentMapper.js.map +1 -0
- package/dist/harnesses/pi/PiSessionLocator.d.ts +61 -0
- package/dist/harnesses/pi/PiSessionLocator.d.ts.map +1 -0
- package/dist/harnesses/pi/PiSessionLocator.js +212 -0
- package/dist/harnesses/pi/PiSessionLocator.js.map +1 -0
- package/dist/harnesses/pi/PiSessionParser.d.ts +88 -0
- package/dist/harnesses/pi/PiSessionParser.d.ts.map +1 -0
- package/dist/harnesses/pi/PiSessionParser.js +318 -0
- package/dist/harnesses/pi/PiSessionParser.js.map +1 -0
- package/dist/{providers → harnesses}/pi/PiSessionTracker.d.ts.map +1 -1
- package/dist/{providers → harnesses}/pi/PiSessionTracker.js +2 -2
- package/dist/harnesses/pi/PiSessionTracker.js.map +1 -0
- package/dist/{providers → harnesses}/pi/durable/PiCliProbe.d.ts.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiCliProbe.js.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.d.ts.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.js.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.d.ts.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.js.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.d.ts.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.js.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiStreamParser.d.ts.map +1 -1
- package/dist/{providers → harnesses}/pi/durable/PiStreamParser.js.map +1 -1
- package/dist/harnesses/shared.d.ts +41 -0
- package/dist/harnesses/shared.d.ts.map +1 -0
- package/dist/harnesses/shared.js +71 -0
- package/dist/harnesses/shared.js.map +1 -0
- package/dist/index.d.ts +28 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -16
- package/dist/index.js.map +1 -1
- package/dist/readiness/AgentReadiness.d.ts +1 -1
- package/dist/readiness/AgentReadiness.d.ts.map +1 -1
- package/dist/readiness/AgentReadiness.js.map +1 -1
- package/dist/runtime/ManagedAgentRuntime.js +3 -1
- package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
- package/dist/runtime/herdr/HerdrAgentDiscovery.js +10 -0
- package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
- package/dist/utils/IncrementalJsonlSummary.d.ts +100 -0
- package/dist/utils/IncrementalJsonlSummary.d.ts.map +1 -0
- package/dist/utils/IncrementalJsonlSummary.js +209 -0
- package/dist/utils/IncrementalJsonlSummary.js.map +1 -0
- package/dist/utils/agents.d.ts +3 -2
- package/dist/utils/agents.d.ts.map +1 -1
- package/dist/utils/agents.js +61 -15
- package/dist/utils/agents.js.map +1 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/jsonlTail.d.ts +73 -0
- package/dist/utils/jsonlTail.d.ts.map +1 -0
- package/dist/utils/jsonlTail.js +238 -0
- package/dist/utils/jsonlTail.js.map +1 -0
- package/dist/utils/matching.d.ts +2 -0
- package/dist/utils/matching.d.ts.map +1 -1
- package/dist/utils/matching.js +3 -2
- package/dist/utils/matching.js.map +1 -1
- package/dist/utils/matchingConstants.d.ts +15 -0
- package/dist/utils/matchingConstants.d.ts.map +1 -0
- package/dist/utils/matchingConstants.js +14 -0
- package/dist/utils/matchingConstants.js.map +1 -0
- package/dist/utils/process.d.ts +38 -2
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +131 -43
- package/dist/utils/process.js.map +1 -1
- package/package.json +2 -1
- package/scripts/benchmark-cold-start.mjs +350 -0
- package/src/AgentManager.ts +26 -5
- package/src/__tests__/AgentManager.test.ts +141 -3
- package/src/__tests__/adapters/IncrementalSessionRefresh.test.ts +437 -0
- package/src/__tests__/adapters/adapterProcessImports.test.ts +58 -0
- package/src/__tests__/adapters/adapterSnapshotCandidates.test.ts +243 -0
- package/src/__tests__/capacity/claude.test.ts +467 -0
- package/src/__tests__/capacity/fixtures/claude-credentials.json +7 -0
- package/src/__tests__/capacity/fixtures/claude-usage-malformed.json +1 -0
- package/src/__tests__/capacity/fixtures/claude-usage-partial.json +15 -0
- package/src/__tests__/capacity/fixtures/claude-usage.json +63 -0
- package/src/__tests__/capacity/fixtures/openai-auth.json +6 -0
- package/src/__tests__/capacity/fixtures/openai-codex-auth.json +9 -0
- package/src/__tests__/capacity/fixtures/openai-usage-completions.json +67 -0
- package/src/__tests__/capacity/fixtures/openai-usage-responses.json +20 -0
- package/src/__tests__/capacity/fixtures/wham-usage.json +32 -0
- package/src/__tests__/capacity/openai.test.ts +560 -0
- package/src/__tests__/capacity/wham.test.ts +104 -0
- package/src/__tests__/harnesses/BoundedSummarySkip.test.ts +496 -0
- package/src/__tests__/harnesses/SessionSummaryEquivalence.test.ts +726 -0
- package/src/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.ts +133 -0
- package/src/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.ts +396 -0
- package/src/__tests__/harnesses/builtinAdapters.test.ts +33 -0
- package/src/__tests__/{providers → harnesses}/claude/ClaudeAgentMapper.test.ts +5 -5
- package/src/__tests__/{adapters → harnesses/claude}/ClaudeCodeAdapter.test.ts +54 -24
- package/src/__tests__/{providers → harnesses}/claude/ClaudeSessionLocator.test.ts +1 -12
- package/src/__tests__/{utils → harnesses/claude}/ClaudeSessionParser.test.ts +2 -2
- package/src/__tests__/{print → harnesses/claude/durable}/ClaudeCliProbe.test.ts +1 -1
- package/src/__tests__/{print → harnesses/claude/durable}/ClaudePrintAgent.integration.test.ts +1 -1
- package/src/__tests__/{print → harnesses/claude/durable}/ClaudePrintAgentService.test.ts +4 -4
- package/src/__tests__/{print → harnesses/claude/durable}/ClaudePrintRunner.test.ts +2 -2
- package/src/__tests__/{adapters → harnesses/codex}/CodexAdapter.test.ts +277 -12
- package/src/__tests__/harnesses/codex/CodexSessionLocator.test.ts +419 -0
- package/src/__tests__/{providers → harnesses}/codex/CodexSessionMapping.test.ts +1 -1
- package/src/__tests__/{providers → harnesses}/codex/CodexSessionParser.test.ts +1 -1
- package/src/__tests__/{durable → harnesses/codex/durable}/CodexCliProbe.test.ts +4 -4
- package/src/__tests__/{durable → harnesses/codex/durable}/CodexDurableAgentRepository.test.ts +1 -1
- package/src/__tests__/{durable → harnesses/codex/durable}/CodexPrintAgent.integration.test.ts +1 -1
- package/src/__tests__/{durable → harnesses/codex/durable}/CodexPrintAgentService.test.ts +8 -18
- package/src/__tests__/{durable → harnesses/codex/durable}/CodexPrintRunner.test.ts +3 -9
- package/src/__tests__/{providers → harnesses}/copilot/CopilotAdapter.test.ts +1 -1
- package/src/__tests__/harnesses/copilot/CopilotRefreshIO.test.ts +270 -0
- package/src/__tests__/{providers → harnesses}/gemini/GeminiCliAdapter.test.ts +27 -23
- package/src/__tests__/harnesses/gemini/GeminiSessionJsonl.test.ts +402 -0
- package/src/__tests__/harnesses/gemini/GeminiSessionLocator.test.ts +396 -0
- package/src/__tests__/{providers → harnesses}/grok/GrokAgentMapper.test.ts +2 -2
- package/src/__tests__/{providers → harnesses}/grok/GrokCliAdapter.test.ts +1 -1
- package/src/__tests__/harnesses/grok/GrokIncrementalRefresh.test.ts +170 -0
- package/src/__tests__/{providers → harnesses}/grok/GrokSessionLocator.test.ts +1 -1
- package/src/__tests__/harnesses/grok/GrokSessionParser.test.ts +230 -0
- package/src/__tests__/harnesses/kiro/KiroAdapter.test.ts +552 -0
- package/src/__tests__/{providers → harnesses}/opencode/OpenCodeAdapter.test.ts +1 -1
- package/src/__tests__/{providers → harnesses}/opencode/OpenCodeAgentMapper.test.ts +1 -1
- package/src/__tests__/{providers → harnesses}/opencode/OpenCodeSessionLocator.test.ts +2 -2
- package/src/__tests__/{providers → harnesses}/opencode/OpenCodeSessionParser.test.ts +1 -1
- package/src/__tests__/{providers → harnesses}/pi/PiAdapter.test.ts +1 -1
- package/src/__tests__/harnesses/pi/PiDiscoveryIO.test.ts +337 -0
- package/src/__tests__/{providers → harnesses}/pi/PiSessionParser.test.ts +91 -1
- package/src/__tests__/{providers → harnesses}/pi/PiSessionTracker.test.ts +1 -1
- package/src/__tests__/{providers → harnesses}/pi/durable/PiPrintProtocol.test.ts +1 -1
- package/src/__tests__/{providers → harnesses}/pi/durable/PiStreamParser.test.ts +1 -1
- package/src/__tests__/readiness/AgentReadiness.test.ts +16 -0
- package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +30 -0
- package/src/__tests__/utils/IncrementalJsonlSummary.test.ts +414 -0
- package/src/__tests__/utils/agents.test.ts +83 -2
- package/src/__tests__/utils/conversationTail.bench.test.ts +193 -0
- package/src/__tests__/utils/conversationTailParity.test.ts +365 -0
- package/src/__tests__/utils/jsonlTail.test.ts +317 -0
- package/src/__tests__/utils/matchingConstants.test.ts +40 -0
- package/src/__tests__/utils/process.test.ts +254 -0
- package/src/adapters/AgentAdapter.ts +37 -12
- package/src/capacity/claude.ts +313 -0
- package/src/capacity/codex.ts +25 -134
- package/src/capacity/index.ts +33 -4
- package/src/capacity/openai.ts +355 -0
- package/src/capacity/wham.ts +84 -0
- package/src/harnesses/antigravity/AntigravityAgentMapper.ts +34 -0
- package/src/harnesses/antigravity/AntigravityCliAdapter.ts +126 -0
- package/src/harnesses/antigravity/AntigravitySessionLocator.ts +75 -0
- package/src/harnesses/antigravity/AntigravitySessionParser.ts +252 -0
- package/src/{providers → harnesses}/claude/ClaudeAgentMapper.ts +2 -10
- package/src/{providers → harnesses}/claude/ClaudeCodeAdapter.ts +22 -20
- package/src/{providers → harnesses}/claude/ClaudeSessionLocator.ts +3 -3
- package/src/{providers → harnesses}/claude/ClaudeSessionParser.ts +189 -97
- package/src/{providers → harnesses}/codex/CodexAdapter.ts +153 -29
- package/src/{providers → harnesses}/codex/CodexAgentMapper.ts +2 -11
- package/src/harnesses/codex/CodexSessionLocator.ts +509 -0
- package/src/{providers → harnesses}/codex/CodexSessionMapping.ts +3 -3
- package/src/{providers → harnesses}/codex/CodexSessionParser.ts +169 -92
- package/src/{providers → harnesses}/copilot/CopilotAdapter.ts +22 -22
- package/src/{providers → harnesses}/copilot/CopilotAgentMapper.ts +2 -11
- package/src/harnesses/copilot/CopilotSessionLocator.ts +161 -0
- package/src/harnesses/copilot/CopilotSessionParser.ts +380 -0
- package/src/{providers → harnesses}/gemini/GeminiAgentMapper.ts +2 -11
- package/src/{providers → harnesses}/gemini/GeminiCliAdapter.ts +7 -9
- package/src/harnesses/gemini/GeminiSessionLocator.ts +394 -0
- package/src/{providers → harnesses}/gemini/GeminiSessionParser.ts +155 -31
- package/src/harnesses/gemini/fileSignature.ts +10 -0
- package/src/{providers → harnesses}/grok/GrokAgentMapper.ts +2 -11
- package/src/{providers → harnesses}/grok/GrokCliAdapter.ts +16 -15
- package/src/{providers → harnesses}/grok/GrokSessionLocator.ts +2 -2
- package/src/harnesses/grok/GrokSessionParser.ts +251 -0
- package/src/harnesses/index.ts +28 -0
- package/src/harnesses/kiro/KiroAdapter.ts +143 -0
- package/src/harnesses/kiro/KiroAgentMapper.ts +34 -0
- package/src/harnesses/kiro/KiroSessionLocator.ts +143 -0
- package/src/harnesses/kiro/KiroSessionParser.ts +376 -0
- package/src/{providers → harnesses}/opencode/OpenCodeAdapter.ts +5 -11
- package/src/{providers → harnesses}/opencode/OpenCodeAgentMapper.ts +3 -13
- package/src/{providers → harnesses}/opencode/OpenCodeSessionLocator.ts +2 -2
- package/src/{providers → harnesses}/opencode/OpenCodeSessionParser.ts +4 -3
- package/src/{providers → harnesses}/pi/PiAdapter.ts +20 -18
- package/src/{providers → harnesses}/pi/PiAgentMapper.ts +2 -11
- package/src/harnesses/pi/PiSessionLocator.ts +288 -0
- package/src/harnesses/pi/PiSessionParser.ts +488 -0
- package/src/{providers → harnesses}/pi/PiSessionTracker.ts +2 -2
- package/src/harnesses/shared.ts +119 -0
- package/src/index.ts +34 -23
- package/src/readiness/AgentReadiness.ts +4 -1
- package/src/runtime/ManagedAgentRuntime.ts +2 -0
- package/src/runtime/herdr/HerdrAgentDiscovery.ts +5 -1
- package/src/utils/IncrementalJsonlSummary.ts +306 -0
- package/src/utils/agents.ts +62 -20
- package/src/utils/index.ts +2 -0
- package/src/utils/jsonlTail.ts +349 -0
- package/src/utils/matching.ts +3 -3
- package/src/utils/matchingConstants.ts +15 -0
- package/src/utils/process.ts +189 -45
- package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +0 -1
- package/dist/__tests__/adapters/CodexAdapter.test.js.map +0 -1
- package/dist/__tests__/durable/CodexCliProbe.test.js.map +0 -1
- package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +0 -1
- package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +0 -1
- package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +0 -1
- package/dist/__tests__/durable/CodexPrintRunner.test.js.map +0 -1
- package/dist/__tests__/print/ClaudeCliProbe.test.js.map +0 -1
- package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +0 -1
- package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +0 -1
- package/dist/__tests__/print/ClaudePrintRunner.test.js.map +0 -1
- package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +0 -1
- package/dist/__tests__/providers/codex/CodexSessionLocator.test.js +0 -194
- package/dist/__tests__/providers/codex/CodexSessionLocator.test.js.map +0 -1
- package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js.map +0 -1
- package/dist/__tests__/providers/pi/PiSessionParser.test.js.map +0 -1
- package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +0 -1
- package/dist/adapters/index.d.ts +0 -10
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js +0 -10
- package/dist/adapters/index.js.map +0 -1
- package/dist/providers/claude/ClaudeAgentMapper.js.map +0 -1
- package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +0 -1
- package/dist/providers/claude/ClaudeCodeAdapter.js.map +0 -1
- package/dist/providers/claude/ClaudeSessionLocator.js.map +0 -1
- package/dist/providers/claude/ClaudeSessionParser.d.ts.map +0 -1
- package/dist/providers/claude/ClaudeSessionParser.js.map +0 -1
- package/dist/providers/codex/CodexAdapter.d.ts.map +0 -1
- package/dist/providers/codex/CodexAdapter.js.map +0 -1
- package/dist/providers/codex/CodexAgentMapper.js.map +0 -1
- package/dist/providers/codex/CodexSessionLocator.d.ts +0 -44
- package/dist/providers/codex/CodexSessionLocator.d.ts.map +0 -1
- package/dist/providers/codex/CodexSessionLocator.js +0 -207
- package/dist/providers/codex/CodexSessionLocator.js.map +0 -1
- package/dist/providers/codex/CodexSessionMapping.js.map +0 -1
- package/dist/providers/codex/CodexSessionParser.d.ts +0 -58
- package/dist/providers/codex/CodexSessionParser.d.ts.map +0 -1
- package/dist/providers/codex/CodexSessionParser.js.map +0 -1
- package/dist/providers/copilot/CopilotAdapter.d.ts.map +0 -1
- package/dist/providers/copilot/CopilotAdapter.js.map +0 -1
- package/dist/providers/copilot/CopilotAgentMapper.js.map +0 -1
- package/dist/providers/copilot/CopilotSessionLocator.d.ts +0 -20
- package/dist/providers/copilot/CopilotSessionLocator.d.ts.map +0 -1
- package/dist/providers/copilot/CopilotSessionLocator.js +0 -49
- package/dist/providers/copilot/CopilotSessionLocator.js.map +0 -1
- package/dist/providers/copilot/CopilotSessionParser.d.ts +0 -30
- package/dist/providers/copilot/CopilotSessionParser.d.ts.map +0 -1
- package/dist/providers/copilot/CopilotSessionParser.js +0 -181
- package/dist/providers/copilot/CopilotSessionParser.js.map +0 -1
- package/dist/providers/gemini/GeminiAgentMapper.js.map +0 -1
- package/dist/providers/gemini/GeminiCliAdapter.d.ts.map +0 -1
- package/dist/providers/gemini/GeminiCliAdapter.js.map +0 -1
- package/dist/providers/gemini/GeminiSessionLocator.d.ts +0 -30
- package/dist/providers/gemini/GeminiSessionLocator.d.ts.map +0 -1
- package/dist/providers/gemini/GeminiSessionLocator.js +0 -142
- package/dist/providers/gemini/GeminiSessionLocator.js.map +0 -1
- package/dist/providers/gemini/GeminiSessionParser.d.ts.map +0 -1
- package/dist/providers/gemini/GeminiSessionParser.js +0 -166
- package/dist/providers/gemini/GeminiSessionParser.js.map +0 -1
- package/dist/providers/grok/GrokAgentMapper.js.map +0 -1
- package/dist/providers/grok/GrokCliAdapter.d.ts.map +0 -1
- package/dist/providers/grok/GrokCliAdapter.js.map +0 -1
- package/dist/providers/grok/GrokSessionLocator.js.map +0 -1
- package/dist/providers/grok/GrokSessionParser.d.ts +0 -54
- package/dist/providers/grok/GrokSessionParser.d.ts.map +0 -1
- package/dist/providers/grok/GrokSessionParser.js +0 -122
- package/dist/providers/grok/GrokSessionParser.js.map +0 -1
- package/dist/providers/opencode/OpenCodeAdapter.d.ts.map +0 -1
- package/dist/providers/opencode/OpenCodeAdapter.js.map +0 -1
- package/dist/providers/opencode/OpenCodeAgentMapper.js.map +0 -1
- package/dist/providers/opencode/OpenCodeSessionLocator.js.map +0 -1
- package/dist/providers/opencode/OpenCodeSessionParser.d.ts.map +0 -1
- package/dist/providers/opencode/OpenCodeSessionParser.js.map +0 -1
- package/dist/providers/pi/PiAdapter.d.ts.map +0 -1
- package/dist/providers/pi/PiAdapter.js.map +0 -1
- package/dist/providers/pi/PiAgentMapper.js.map +0 -1
- package/dist/providers/pi/PiSessionLocator.d.ts +0 -24
- package/dist/providers/pi/PiSessionLocator.d.ts.map +0 -1
- package/dist/providers/pi/PiSessionLocator.js +0 -86
- package/dist/providers/pi/PiSessionLocator.js.map +0 -1
- package/dist/providers/pi/PiSessionParser.d.ts +0 -36
- package/dist/providers/pi/PiSessionParser.d.ts.map +0 -1
- package/dist/providers/pi/PiSessionParser.js +0 -191
- package/dist/providers/pi/PiSessionParser.js.map +0 -1
- package/dist/providers/pi/PiSessionTracker.js.map +0 -1
- package/src/__tests__/fixtures/fake-claude.cjs +0 -31
- package/src/__tests__/fixtures/fake-codex.cjs +0 -56
- package/src/__tests__/providers/codex/CodexSessionLocator.test.ts +0 -182
- package/src/adapters/index.ts +0 -15
- package/src/providers/codex/CodexSessionLocator.ts +0 -279
- package/src/providers/copilot/CopilotSessionLocator.ts +0 -63
- package/src/providers/copilot/CopilotSessionParser.ts +0 -289
- package/src/providers/gemini/GeminiSessionLocator.ts +0 -183
- package/src/providers/grok/GrokSessionParser.ts +0 -166
- package/src/providers/pi/PiSessionLocator.ts +0 -110
- package/src/providers/pi/PiSessionParser.ts +0 -284
- /package/dist/__tests__/{providers → harnesses}/pi/durable/PiCliProbe.test.js +0 -0
- /package/dist/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.test.js +0 -0
- /package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintAgentService.test.js +0 -0
- /package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintRunner.test.js +0 -0
- /package/dist/{providers → harnesses}/claude/ClaudeAgentMapper.d.ts +0 -0
- /package/dist/{providers → harnesses}/claude/ClaudeSessionLocator.d.ts +0 -0
- /package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.d.ts +0 -0
- /package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.js +0 -0
- /package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.d.ts +0 -0
- /package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.js +0 -0
- /package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.d.ts +0 -0
- /package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.js +0 -0
- /package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.d.ts +0 -0
- /package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.js +0 -0
- /package/dist/{providers → harnesses}/codex/CodexAgentMapper.d.ts +0 -0
- /package/dist/{providers → harnesses}/codex/CodexSessionMapping.d.ts +0 -0
- /package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.d.ts +0 -0
- /package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.js +0 -0
- /package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.d.ts +0 -0
- /package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.js +0 -0
- /package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.d.ts +0 -0
- /package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.js +0 -0
- /package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.d.ts +0 -0
- /package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.js +0 -0
- /package/dist/{providers → harnesses}/copilot/CopilotAgentMapper.d.ts +0 -0
- /package/dist/{providers → harnesses}/gemini/GeminiAgentMapper.d.ts +0 -0
- /package/dist/{providers → harnesses}/grok/GrokAgentMapper.d.ts +0 -0
- /package/dist/{providers → harnesses}/grok/GrokSessionLocator.d.ts +0 -0
- /package/dist/{providers → harnesses}/opencode/OpenCodeAgentMapper.d.ts +0 -0
- /package/dist/{providers → harnesses}/opencode/OpenCodeSessionLocator.d.ts +0 -0
- /package/dist/{providers → harnesses}/pi/PiAgentMapper.d.ts +0 -0
- /package/dist/{providers → harnesses}/pi/PiSessionTracker.d.ts +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiCliProbe.d.ts +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiCliProbe.js +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.d.ts +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.js +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.d.ts +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.js +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.d.ts +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.js +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiStreamParser.d.ts +0 -0
- /package/dist/{providers → harnesses}/pi/durable/PiStreamParser.js +0 -0
- /package/src/__tests__/{providers → harnesses}/pi/durable/PiCliProbe.test.ts +0 -0
- /package/src/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.test.ts +0 -0
- /package/src/__tests__/{providers → harnesses}/pi/durable/PiPrintAgentService.test.ts +0 -0
- /package/src/__tests__/{providers → harnesses}/pi/durable/PiPrintRunner.test.ts +0 -0
- /package/src/{providers → harnesses}/claude/durable/ClaudeCliProbe.ts +0 -0
- /package/src/{providers → harnesses}/claude/durable/ClaudePrintAgentService.ts +0 -0
- /package/src/{providers → harnesses}/claude/durable/ClaudePrintRunner.ts +0 -0
- /package/src/{providers → harnesses}/claude/durable/ClaudeStreamParser.ts +0 -0
- /package/src/{providers → harnesses}/codex/durable/CodexCliProbe.ts +0 -0
- /package/src/{providers → harnesses}/codex/durable/CodexPrintAgentService.ts +0 -0
- /package/src/{providers → harnesses}/codex/durable/CodexPrintRunner.ts +0 -0
- /package/src/{providers → harnesses}/codex/durable/CodexStreamParser.ts +0 -0
- /package/src/{providers → harnesses}/pi/durable/PiCliProbe.ts +0 -0
- /package/src/{providers → harnesses}/pi/durable/PiPrintAgentService.ts +0 -0
- /package/src/{providers → harnesses}/pi/durable/PiPrintProtocol.ts +0 -0
- /package/src/{providers → harnesses}/pi/durable/PiPrintRunner.ts +0 -0
- /package/src/{providers → harnesses}/pi/durable/PiStreamParser.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KiroSessionLocator.d.ts","sourceRoot":"","sources":["../../../src/harnesses/kiro/KiroSessionLocator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AASlE,OAAO,EAAY,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAEzE,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,OAAO,GAAE,yBAA8B;IAInD;;;;;;;OAOG;IACH,qBAAqB,CACnB,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,aAAa,EAAE,SAAS,WAAW,EAAE,EACrC,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,GACxC,gBAAgB,EAAE;IAarB,8DAA8D;IAC9D,YAAY,IAAI,gBAAgB,EAAE;IAQlC,+DAA+D;IAC/D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAMvD,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,mBAAmB;IAqB3B,+EAA+E;IAC/E,OAAO,CAAC,gBAAgB;IAiBxB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CAQ9B"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as path from "path";
|
|
2
|
+
import { isDirectory, isSafePathSegment, safeReadFile, safeReaddir, safeStat } from "../../utils/session.js";
|
|
3
|
+
import { homeDir } from "../shared.js";
|
|
4
|
+
import { asRecord } from "./KiroSessionParser.js";
|
|
5
|
+
export class KiroSessionLocator {
|
|
6
|
+
sessionsDir;
|
|
7
|
+
constructor(options = {}){
|
|
8
|
+
this.sessionsDir = options.sessionsDir ?? path.join(homeDir(), ".kiro", "sessions", "cli");
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Pair `<session-id>.lock` files with running Kiro processes.
|
|
12
|
+
*
|
|
13
|
+
* @param snapshot every process collected for Kiro's process names, used to
|
|
14
|
+
* walk up from the lock's PID (often a `kiro-cli-chat acp` helper)
|
|
15
|
+
* @param kiroProcesses the top-level Kiro processes that become agents
|
|
16
|
+
* @param isKiro whether a process is a top-level Kiro process
|
|
17
|
+
*/ matchRunningProcesses(snapshot, kiroProcesses, isKiro) {
|
|
18
|
+
const byPid = new Map(snapshot.map((proc)=>[
|
|
19
|
+
proc.pid,
|
|
20
|
+
proc
|
|
21
|
+
]));
|
|
22
|
+
const matches = [];
|
|
23
|
+
for (const lock of this.discoverActiveLocks()){
|
|
24
|
+
const proc = this.findKiroAncestor(lock.pid, byPid, isKiro) ?? this.matchSoleProcessOnTty(byPid.get(lock.pid)?.tty, kiroProcesses);
|
|
25
|
+
if (proc) matches.push({
|
|
26
|
+
process: proc,
|
|
27
|
+
session: this.sessionPaths(lock.sessionId)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return matches;
|
|
31
|
+
}
|
|
32
|
+
/** Every session with a transcript under the sessions dir. */ listSessions() {
|
|
33
|
+
if (!isDirectory(this.sessionsDir)) return [];
|
|
34
|
+
return safeReaddir(this.sessionsDir).filter((entry)=>entry.endsWith(".jsonl")).map((entry)=>this.sessionPaths(entry.slice(0, -".jsonl".length)));
|
|
35
|
+
}
|
|
36
|
+
/** The session stored as `<sessionId>.jsonl`, if it exists. */ findSession(sessionId) {
|
|
37
|
+
if (!isSafePathSegment(sessionId)) return null;
|
|
38
|
+
const paths = this.sessionPaths(sessionId);
|
|
39
|
+
return safeStat(paths.transcriptPath)?.isFile() ? paths : null;
|
|
40
|
+
}
|
|
41
|
+
sessionPaths(sessionId) {
|
|
42
|
+
return {
|
|
43
|
+
sessionId,
|
|
44
|
+
transcriptPath: path.join(this.sessionsDir, `${sessionId}.jsonl`),
|
|
45
|
+
metadataPath: path.join(this.sessionsDir, `${sessionId}.json`)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
discoverActiveLocks() {
|
|
49
|
+
if (!isDirectory(this.sessionsDir)) return [];
|
|
50
|
+
const locks = [];
|
|
51
|
+
for (const entry of safeReaddir(this.sessionsDir)){
|
|
52
|
+
if (!entry.endsWith(".lock")) continue;
|
|
53
|
+
const content = safeReadFile(path.join(this.sessionsDir, entry));
|
|
54
|
+
if (content === undefined) continue;
|
|
55
|
+
let pid;
|
|
56
|
+
try {
|
|
57
|
+
pid = toPid(asRecord(JSON.parse(content))?.pid);
|
|
58
|
+
} catch {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (pid !== null) locks.push({
|
|
62
|
+
sessionId: entry.slice(0, -".lock".length),
|
|
63
|
+
pid
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return locks;
|
|
67
|
+
}
|
|
68
|
+
/** The outermost Kiro process on the lock PID's parent chain, if collected. */ findKiroAncestor(lockPid, byPid, isKiro) {
|
|
69
|
+
let current = byPid.get(lockPid);
|
|
70
|
+
const seen = new Set();
|
|
71
|
+
let resolved = null;
|
|
72
|
+
while(current && !seen.has(current.pid)){
|
|
73
|
+
seen.add(current.pid);
|
|
74
|
+
if (isKiro(current)) resolved = current;
|
|
75
|
+
current = current.ppid === undefined ? undefined : byPid.get(current.ppid);
|
|
76
|
+
}
|
|
77
|
+
return resolved;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Fallback when the chain is broken (an uncollected intermediate process):
|
|
81
|
+
* attach to the only Kiro process on the lock holder's terminal.
|
|
82
|
+
*/ matchSoleProcessOnTty(tty, kiroProcesses) {
|
|
83
|
+
if (!tty || tty === "??" || tty === "?") return null;
|
|
84
|
+
const matches = kiroProcesses.filter((proc)=>proc.tty === tty);
|
|
85
|
+
return matches.length === 1 ? matches[0] : null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function toPid(value) {
|
|
89
|
+
if (typeof value === "number" && Number.isSafeInteger(value) && value > 0) return value;
|
|
90
|
+
if (typeof value !== "string" || !/^\d+$/.test(value)) return null;
|
|
91
|
+
const parsed = Number(value);
|
|
92
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=KiroSessionLocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/harnesses/kiro/KiroSessionLocator.ts"],"sourcesContent":["import * as path from \"path\";\nimport type { ProcessInfo } from \"../../adapters/AgentAdapter.js\";\nimport {\n isDirectory,\n isSafePathSegment,\n safeReadFile,\n safeReaddir,\n safeStat,\n} from \"../../utils/session.js\";\nimport { homeDir } from \"../shared.js\";\nimport { asRecord, type KiroSessionPaths } from \"./KiroSessionParser.js\";\n\n/** A live Kiro process and the session whose lock it holds. */\nexport interface KiroProcessMatch {\n process: ProcessInfo;\n session: KiroSessionPaths;\n}\n\nexport interface KiroSessionLocatorOptions {\n /** Overrides ~/.kiro/sessions/cli. */\n sessionsDir?: string;\n}\n\ninterface KiroLock {\n sessionId: string;\n pid: number;\n}\n\nexport class KiroSessionLocator {\n private readonly sessionsDir: string;\n\n constructor(options: KiroSessionLocatorOptions = {}) {\n this.sessionsDir = options.sessionsDir ?? path.join(homeDir(), \".kiro\", \"sessions\", \"cli\");\n }\n\n /**\n * Pair `<session-id>.lock` files with running Kiro processes.\n *\n * @param snapshot every process collected for Kiro's process names, used to\n * walk up from the lock's PID (often a `kiro-cli-chat acp` helper)\n * @param kiroProcesses the top-level Kiro processes that become agents\n * @param isKiro whether a process is a top-level Kiro process\n */\n matchRunningProcesses(\n snapshot: readonly ProcessInfo[],\n kiroProcesses: readonly ProcessInfo[],\n isKiro: (process: ProcessInfo) => boolean,\n ): KiroProcessMatch[] {\n const byPid = new Map(snapshot.map((proc) => [proc.pid, proc]));\n const matches: KiroProcessMatch[] = [];\n\n for (const lock of this.discoverActiveLocks()) {\n const proc =\n this.findKiroAncestor(lock.pid, byPid, isKiro) ??\n this.matchSoleProcessOnTty(byPid.get(lock.pid)?.tty, kiroProcesses);\n if (proc) matches.push({ process: proc, session: this.sessionPaths(lock.sessionId) });\n }\n return matches;\n }\n\n /** Every session with a transcript under the sessions dir. */\n listSessions(): KiroSessionPaths[] {\n if (!isDirectory(this.sessionsDir)) return [];\n\n return safeReaddir(this.sessionsDir)\n .filter((entry) => entry.endsWith(\".jsonl\"))\n .map((entry) => this.sessionPaths(entry.slice(0, -\".jsonl\".length)));\n }\n\n /** The session stored as `<sessionId>.jsonl`, if it exists. */\n findSession(sessionId: string): KiroSessionPaths | null {\n if (!isSafePathSegment(sessionId)) return null;\n const paths = this.sessionPaths(sessionId);\n return safeStat(paths.transcriptPath)?.isFile() ? paths : null;\n }\n\n private sessionPaths(sessionId: string): KiroSessionPaths {\n return {\n sessionId,\n transcriptPath: path.join(this.sessionsDir, `${sessionId}.jsonl`),\n metadataPath: path.join(this.sessionsDir, `${sessionId}.json`),\n };\n }\n\n private discoverActiveLocks(): KiroLock[] {\n if (!isDirectory(this.sessionsDir)) return [];\n\n const locks: KiroLock[] = [];\n for (const entry of safeReaddir(this.sessionsDir)) {\n if (!entry.endsWith(\".lock\")) continue;\n\n const content = safeReadFile(path.join(this.sessionsDir, entry));\n if (content === undefined) continue;\n\n let pid: number | null;\n try {\n pid = toPid(asRecord(JSON.parse(content))?.pid);\n } catch {\n continue;\n }\n if (pid !== null) locks.push({ sessionId: entry.slice(0, -\".lock\".length), pid });\n }\n return locks;\n }\n\n /** The outermost Kiro process on the lock PID's parent chain, if collected. */\n private findKiroAncestor(\n lockPid: number,\n byPid: Map<number, ProcessInfo>,\n isKiro: (process: ProcessInfo) => boolean,\n ): ProcessInfo | null {\n let current = byPid.get(lockPid);\n const seen = new Set<number>();\n let resolved: ProcessInfo | null = null;\n\n while (current && !seen.has(current.pid)) {\n seen.add(current.pid);\n if (isKiro(current)) resolved = current;\n current = current.ppid === undefined ? undefined : byPid.get(current.ppid);\n }\n return resolved;\n }\n\n /**\n * Fallback when the chain is broken (an uncollected intermediate process):\n * attach to the only Kiro process on the lock holder's terminal.\n */\n private matchSoleProcessOnTty(\n tty: string | undefined,\n kiroProcesses: readonly ProcessInfo[],\n ): ProcessInfo | null {\n if (!tty || tty === \"??\" || tty === \"?\") return null;\n const matches = kiroProcesses.filter((proc) => proc.tty === tty);\n return matches.length === 1 ? matches[0] : null;\n }\n}\n\nfunction toPid(value: unknown): number | null {\n if (typeof value === \"number\" && Number.isSafeInteger(value) && value > 0) return value;\n if (typeof value !== \"string\" || !/^\\d+$/.test(value)) return null;\n const parsed = Number(value);\n return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;\n}\n"],"names":["path","isDirectory","isSafePathSegment","safeReadFile","safeReaddir","safeStat","homeDir","asRecord","KiroSessionLocator","sessionsDir","options","join","matchRunningProcesses","snapshot","kiroProcesses","isKiro","byPid","Map","map","proc","pid","matches","lock","discoverActiveLocks","findKiroAncestor","matchSoleProcessOnTty","get","tty","push","process","session","sessionPaths","sessionId","listSessions","filter","entry","endsWith","slice","length","findSession","paths","transcriptPath","isFile","metadataPath","locks","content","undefined","toPid","JSON","parse","lockPid","current","seen","Set","resolved","has","add","ppid","value","Number","isSafeInteger","test","parsed"],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ConversationMessage, ConversationOptions } from "../../adapters/AgentAdapter.js";
|
|
2
|
+
import { AgentStatus } from "../../adapters/AgentAdapter.js";
|
|
3
|
+
import { type JsonlSummaryBounds } from "../../utils/IncrementalJsonlSummary.js";
|
|
4
|
+
type KiroRecord = Record<string, unknown>;
|
|
5
|
+
export interface KiroSessionParserOptions {
|
|
6
|
+
/** Cold-start scan bounds for `readSessionIncremental` (see IncrementalJsonlSummary). */
|
|
7
|
+
summaryBounds?: JsonlSummaryBounds | false;
|
|
8
|
+
}
|
|
9
|
+
export interface KiroSessionPaths {
|
|
10
|
+
sessionId: string;
|
|
11
|
+
transcriptPath: string;
|
|
12
|
+
metadataPath: string;
|
|
13
|
+
}
|
|
14
|
+
export interface KiroSession {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
projectPath: string;
|
|
17
|
+
sessionFilePath: string;
|
|
18
|
+
title: string;
|
|
19
|
+
firstUserMessage: string;
|
|
20
|
+
lastUserMessage?: string;
|
|
21
|
+
sessionStart: Date;
|
|
22
|
+
lastActive: Date;
|
|
23
|
+
lastEventKind?: string;
|
|
24
|
+
lastAssistantHasToolUse: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare class KiroSessionParser {
|
|
27
|
+
/** Incremental reader backing `getConversation({ tail })`. */
|
|
28
|
+
private readonly tailReader;
|
|
29
|
+
private readonly sessionCache;
|
|
30
|
+
constructor(options?: KiroSessionParserOptions);
|
|
31
|
+
/**
|
|
32
|
+
* Parse a session from its transcript and metadata. Metadata wins for the
|
|
33
|
+
* session id, cwd and timestamps; `fallbackCwd` is used when it has no cwd.
|
|
34
|
+
* Returns null when the transcript is missing.
|
|
35
|
+
*/
|
|
36
|
+
readSession(paths: KiroSessionPaths, fallbackCwd?: string): KiroSession | null;
|
|
37
|
+
/**
|
|
38
|
+
* Same result as `readSession`, but the transcript summary is backed by a
|
|
39
|
+
* per-instance incremental cache, so repeated refreshes only parse bytes
|
|
40
|
+
* appended since the last call. The small metadata file is still read each
|
|
41
|
+
* time. Call `pruneSessionCache()` once per refresh.
|
|
42
|
+
*/
|
|
43
|
+
readSessionIncremental(paths: KiroSessionPaths, fallbackCwd?: string): KiroSession | null;
|
|
44
|
+
/** Evict cached summaries for files not read since the previous prune. */
|
|
45
|
+
pruneSessionCache(): void;
|
|
46
|
+
getConversation(transcriptPath: string, options?: ConversationOptions): ConversationMessage[];
|
|
47
|
+
/**
|
|
48
|
+
* - past the idle threshold → IDLE
|
|
49
|
+
* - last event is an assistant reply without a tool call → WAITING
|
|
50
|
+
* - otherwise (user prompt, tool call or tool result) → RUNNING
|
|
51
|
+
*/
|
|
52
|
+
determineStatus(session: KiroSession): AgentStatus;
|
|
53
|
+
/**
|
|
54
|
+
* Fold one transcript line into the O(1) summary. Uses the same entry rules
|
|
55
|
+
* as `getConversation` (see `entryToMessage`); non-object lines are ignored.
|
|
56
|
+
*
|
|
57
|
+
* `skip` (bounded cold start) keeps the head's first prompt and timestamp and
|
|
58
|
+
* resets the latest fields, so those come from the tail only.
|
|
59
|
+
*/
|
|
60
|
+
private readonly summaryReducer;
|
|
61
|
+
private toSession;
|
|
62
|
+
private readMetadata;
|
|
63
|
+
private readJsonl;
|
|
64
|
+
private parseJsonlLine;
|
|
65
|
+
private entriesToMessages;
|
|
66
|
+
/**
|
|
67
|
+
* Prompt → user, AssistantMessage → assistant (tool calls appended in
|
|
68
|
+
* verbose mode), ToolResults → system (verbose only).
|
|
69
|
+
*/
|
|
70
|
+
private entryToMessage;
|
|
71
|
+
private textContent;
|
|
72
|
+
private toolUseContent;
|
|
73
|
+
private toolResultContent;
|
|
74
|
+
private contentBlocks;
|
|
75
|
+
private hasContentKind;
|
|
76
|
+
/** The line's own timestamp, else `data.meta.timestamp` (epoch seconds/ms or ISO). */
|
|
77
|
+
private entryTimestamp;
|
|
78
|
+
}
|
|
79
|
+
export declare function asRecord(value: unknown): KiroRecord | null;
|
|
80
|
+
export {};
|
|
81
|
+
//# sourceMappingURL=KiroSessionParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KiroSessionParser.d.ts","sourceRoot":"","sources":["../../../src/harnesses/kiro/KiroSessionParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,wCAAwC,CAAC;AAKhD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA+B1C,MAAM,WAAW,wBAAwB;IACvC,yFAAyF;IACzF,aAAa,CAAC,EAAE,kBAAkB,GAAG,KAAK,CAAC;CAC5C;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,qBAAa,iBAAiB;IAC5B,8DAA8D;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IAEpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA4C;gBAE7D,OAAO,GAAE,wBAA6B;IAMlD;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,WAAW,SAAK,GAAG,WAAW,GAAG,IAAI;IAS1E;;;;;OAKG;IACH,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,EAAE,WAAW,SAAK,GAAG,WAAW,GAAG,IAAI;IASrF,0EAA0E;IAC1E,iBAAiB,IAAI,IAAI;IAIzB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE;IAoB7F;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW;IAQlD;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAmC7B;IAEF,OAAO,CAAC,SAAS;IA0BjB,OAAO,CAAC,YAAY;IA4BpB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,iBAAiB;IASzB;;;OAGG;IACH,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,cAAc;IAItB,sFAAsF;IACtF,OAAO,CAAC,cAAc;CAOvB;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAG1D"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { AgentStatus } from "../../adapters/AgentAdapter.js";
|
|
2
|
+
import { IncrementalJsonlSummary, reduceJsonlContent } from "../../utils/IncrementalJsonlSummary.js";
|
|
3
|
+
import { JsonlTailReader, normalizeTail } from "../../utils/jsonlTail.js";
|
|
4
|
+
import { safeReadFile, safeStat } from "../../utils/session.js";
|
|
5
|
+
import { isIdle, parseTimestamp } from "../shared.js";
|
|
6
|
+
export class KiroSessionParser {
|
|
7
|
+
/** Incremental reader backing `getConversation({ tail })`. */ tailReader = new JsonlTailReader();
|
|
8
|
+
sessionCache;
|
|
9
|
+
constructor(options = {}){
|
|
10
|
+
this.sessionCache = new IncrementalJsonlSummary(this.summaryReducer, {
|
|
11
|
+
bounds: options.summaryBounds
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Parse a session from its transcript and metadata. Metadata wins for the
|
|
16
|
+
* session id, cwd and timestamps; `fallbackCwd` is used when it has no cwd.
|
|
17
|
+
* Returns null when the transcript is missing.
|
|
18
|
+
*/ readSession(paths, fallbackCwd = "") {
|
|
19
|
+
const stat = safeStat(paths.transcriptPath);
|
|
20
|
+
if (!stat?.isFile()) return null;
|
|
21
|
+
const content = safeReadFile(paths.transcriptPath);
|
|
22
|
+
const state = content === undefined ? {} : reduceJsonlContent(this.summaryReducer, content);
|
|
23
|
+
return this.toSession(paths, fallbackCwd, stat, state);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Same result as `readSession`, but the transcript summary is backed by a
|
|
27
|
+
* per-instance incremental cache, so repeated refreshes only parse bytes
|
|
28
|
+
* appended since the last call. The small metadata file is still read each
|
|
29
|
+
* time. Call `pruneSessionCache()` once per refresh.
|
|
30
|
+
*/ readSessionIncremental(paths, fallbackCwd = "") {
|
|
31
|
+
const stat = safeStat(paths.transcriptPath);
|
|
32
|
+
if (!stat?.isFile()) return null;
|
|
33
|
+
// Present but unreadable: surface the session without a summary, like readSession.
|
|
34
|
+
const state = this.sessionCache.read(paths.transcriptPath)?.state ?? {};
|
|
35
|
+
return this.toSession(paths, fallbackCwd, stat, state);
|
|
36
|
+
}
|
|
37
|
+
/** Evict cached summaries for files not read since the previous prune. */ pruneSessionCache() {
|
|
38
|
+
this.sessionCache.prune();
|
|
39
|
+
}
|
|
40
|
+
getConversation(transcriptPath, options) {
|
|
41
|
+
const verbose = options?.verbose ?? false;
|
|
42
|
+
const tail = normalizeTail(options?.tail);
|
|
43
|
+
if (tail === undefined) {
|
|
44
|
+
return this.entriesToMessages(this.readJsonl(transcriptPath), verbose);
|
|
45
|
+
}
|
|
46
|
+
return this.tailReader.read(transcriptPath, tail, {
|
|
47
|
+
parseLine: (line)=>{
|
|
48
|
+
const entry = this.parseJsonlLine(line);
|
|
49
|
+
return entry ? this.entryToMessage(entry, verbose) : null;
|
|
50
|
+
}
|
|
51
|
+
}, String(verbose));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* - past the idle threshold → IDLE
|
|
55
|
+
* - last event is an assistant reply without a tool call → WAITING
|
|
56
|
+
* - otherwise (user prompt, tool call or tool result) → RUNNING
|
|
57
|
+
*/ determineStatus(session) {
|
|
58
|
+
if (isIdle(session.lastActive)) return AgentStatus.IDLE;
|
|
59
|
+
if (session.lastEventKind === "AssistantMessage" && !session.lastAssistantHasToolUse) {
|
|
60
|
+
return AgentStatus.WAITING;
|
|
61
|
+
}
|
|
62
|
+
return AgentStatus.RUNNING;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Fold one transcript line into the O(1) summary. Uses the same entry rules
|
|
66
|
+
* as `getConversation` (see `entryToMessage`); non-object lines are ignored.
|
|
67
|
+
*
|
|
68
|
+
* `skip` (bounded cold start) keeps the head's first prompt and timestamp and
|
|
69
|
+
* resets the latest fields, so those come from the tail only.
|
|
70
|
+
*/ summaryReducer = {
|
|
71
|
+
initial: ()=>({}),
|
|
72
|
+
reduce: (state, value)=>{
|
|
73
|
+
const entry = asRecord(value);
|
|
74
|
+
if (!entry) return state;
|
|
75
|
+
const next = {
|
|
76
|
+
...state,
|
|
77
|
+
lastEventKind: entry.kind,
|
|
78
|
+
lastAssistantHasToolUse: entry.kind === "AssistantMessage" && this.hasContentKind(entry, "toolUse")
|
|
79
|
+
};
|
|
80
|
+
const timestampMs = parseTimestamp(this.entryTimestamp(entry))?.getTime();
|
|
81
|
+
if (timestampMs !== undefined) {
|
|
82
|
+
next.lastTimestampMs = timestampMs;
|
|
83
|
+
if (next.firstTimestampMs === undefined && !next.pastHead) {
|
|
84
|
+
next.firstTimestampMs = timestampMs;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const message = this.entryToMessage(entry, false);
|
|
88
|
+
if (message?.role === "user") {
|
|
89
|
+
next.lastUserMessage = message.content;
|
|
90
|
+
if (next.firstUserMessage === undefined && !next.pastHead) {
|
|
91
|
+
next.firstUserMessage = message.content;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return next;
|
|
95
|
+
},
|
|
96
|
+
skip: (state)=>({
|
|
97
|
+
pastHead: true,
|
|
98
|
+
firstUserMessage: state.firstUserMessage,
|
|
99
|
+
firstTimestampMs: state.firstTimestampMs
|
|
100
|
+
})
|
|
101
|
+
};
|
|
102
|
+
toSession(paths, fallbackCwd, stat, state) {
|
|
103
|
+
const metadata = this.readMetadata(paths);
|
|
104
|
+
const firstTimestamp = state.firstTimestampMs === undefined ? undefined : new Date(state.firstTimestampMs);
|
|
105
|
+
const lastTimestamp = state.lastTimestampMs === undefined ? undefined : new Date(state.lastTimestampMs);
|
|
106
|
+
return {
|
|
107
|
+
sessionId: metadata.sessionId,
|
|
108
|
+
projectPath: metadata.cwd || fallbackCwd,
|
|
109
|
+
sessionFilePath: paths.transcriptPath,
|
|
110
|
+
title: metadata.title,
|
|
111
|
+
firstUserMessage: state.firstUserMessage ?? "",
|
|
112
|
+
lastUserMessage: state.lastUserMessage,
|
|
113
|
+
sessionStart: metadata.createdAt ?? firstTimestamp ?? stat.birthtime,
|
|
114
|
+
lastActive: metadata.updatedAt ?? lastTimestamp ?? stat.mtime,
|
|
115
|
+
lastEventKind: state.lastEventKind,
|
|
116
|
+
lastAssistantHasToolUse: state.lastAssistantHasToolUse ?? false
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
readMetadata({ sessionId, metadataPath }) {
|
|
120
|
+
const empty = {
|
|
121
|
+
sessionId,
|
|
122
|
+
cwd: "",
|
|
123
|
+
title: "",
|
|
124
|
+
createdAt: null,
|
|
125
|
+
updatedAt: null
|
|
126
|
+
};
|
|
127
|
+
const content = safeReadFile(metadataPath);
|
|
128
|
+
if (content === undefined) return empty;
|
|
129
|
+
let parsed;
|
|
130
|
+
try {
|
|
131
|
+
parsed = asRecord(JSON.parse(content));
|
|
132
|
+
} catch {
|
|
133
|
+
return empty;
|
|
134
|
+
}
|
|
135
|
+
if (!parsed) return empty;
|
|
136
|
+
return {
|
|
137
|
+
sessionId: firstString(parsed.session_id, parsed.sessionId) ?? sessionId,
|
|
138
|
+
cwd: firstString(parsed.cwd) ?? "",
|
|
139
|
+
title: firstString(parsed.title) ?? "",
|
|
140
|
+
createdAt: parseTimestamp(parsed.created_at ?? parsed.createdAt),
|
|
141
|
+
updatedAt: parseTimestamp(parsed.updated_at ?? parsed.updatedAt)
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
readJsonl(filePath) {
|
|
145
|
+
const content = safeReadFile(filePath);
|
|
146
|
+
if (content === undefined) return [];
|
|
147
|
+
const entries = [];
|
|
148
|
+
for (const line of content.split(/\r?\n/)){
|
|
149
|
+
const entry = this.parseJsonlLine(line);
|
|
150
|
+
if (entry) entries.push(entry);
|
|
151
|
+
}
|
|
152
|
+
return entries;
|
|
153
|
+
}
|
|
154
|
+
parseJsonlLine(line) {
|
|
155
|
+
const trimmed = line.trim();
|
|
156
|
+
if (!trimmed) return null;
|
|
157
|
+
try {
|
|
158
|
+
return asRecord(JSON.parse(trimmed));
|
|
159
|
+
} catch {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
entriesToMessages(entries, verbose) {
|
|
164
|
+
const messages = [];
|
|
165
|
+
for (const entry of entries){
|
|
166
|
+
const message = this.entryToMessage(entry, verbose);
|
|
167
|
+
if (message) messages.push(message);
|
|
168
|
+
}
|
|
169
|
+
return messages;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Prompt → user, AssistantMessage → assistant (tool calls appended in
|
|
173
|
+
* verbose mode), ToolResults → system (verbose only).
|
|
174
|
+
*/ entryToMessage(entry, verbose) {
|
|
175
|
+
let role;
|
|
176
|
+
let content;
|
|
177
|
+
if (entry.kind === "Prompt") {
|
|
178
|
+
role = "user";
|
|
179
|
+
content = this.textContent(entry);
|
|
180
|
+
} else if (entry.kind === "AssistantMessage") {
|
|
181
|
+
role = "assistant";
|
|
182
|
+
const parts = [
|
|
183
|
+
this.textContent(entry)
|
|
184
|
+
];
|
|
185
|
+
if (verbose) parts.push(...this.toolUseContent(entry));
|
|
186
|
+
content = parts.filter(Boolean).join("\n");
|
|
187
|
+
} else if (entry.kind === "ToolResults" && verbose) {
|
|
188
|
+
role = "system";
|
|
189
|
+
content = this.toolResultContent(entry).join("\n");
|
|
190
|
+
} else {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
if (!content) return null;
|
|
194
|
+
return {
|
|
195
|
+
role,
|
|
196
|
+
content,
|
|
197
|
+
timestamp: this.entryTimestamp(entry)
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
textContent(entry) {
|
|
201
|
+
return this.contentBlocks(entry).filter((block)=>block.kind === "text").map((block)=>typeof block.data === "string" ? block.data : "").filter(Boolean).join("");
|
|
202
|
+
}
|
|
203
|
+
toolUseContent(entry) {
|
|
204
|
+
return this.contentBlocks(entry).filter((block)=>block.kind === "toolUse").map((block)=>{
|
|
205
|
+
const data = asRecord(block.data);
|
|
206
|
+
const name = firstString(data?.name) ?? "unknown";
|
|
207
|
+
const input = formatValue(data?.input);
|
|
208
|
+
return `[Tool: ${name}]${input ? ` ${input}` : ""}`;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
toolResultContent(entry) {
|
|
212
|
+
return this.contentBlocks(entry).filter((block)=>block.kind === "toolResult").map((block)=>{
|
|
213
|
+
const data = asRecord(block.data);
|
|
214
|
+
const prefix = data?.status === "error" ? "[Tool Error]" : "[Tool Result]";
|
|
215
|
+
const result = formatValue(data?.result ?? data?.results ?? data?.content);
|
|
216
|
+
return `${prefix}${result ? ` ${result}` : ""}`;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
contentBlocks(entry) {
|
|
220
|
+
const content = entry.data?.content;
|
|
221
|
+
if (!Array.isArray(content)) return [];
|
|
222
|
+
return content.map((block)=>asRecord(block)).filter((block)=>block !== null);
|
|
223
|
+
}
|
|
224
|
+
hasContentKind(entry, kind) {
|
|
225
|
+
return this.contentBlocks(entry).some((block)=>block.kind === kind);
|
|
226
|
+
}
|
|
227
|
+
/** The line's own timestamp, else `data.meta.timestamp` (epoch seconds/ms or ISO). */ entryTimestamp(entry) {
|
|
228
|
+
const direct = firstString(entry.timestamp);
|
|
229
|
+
if (direct) return direct;
|
|
230
|
+
const meta = asRecord(entry.data?.meta);
|
|
231
|
+
return parseTimestamp(meta?.timestamp)?.toISOString();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
export function asRecord(value) {
|
|
235
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
236
|
+
return value;
|
|
237
|
+
}
|
|
238
|
+
function firstString(...values) {
|
|
239
|
+
return values.find((value)=>typeof value === "string" && value.length > 0);
|
|
240
|
+
}
|
|
241
|
+
function formatValue(value) {
|
|
242
|
+
if (typeof value === "string") return value;
|
|
243
|
+
if (value === undefined || value === null) return "";
|
|
244
|
+
try {
|
|
245
|
+
return JSON.stringify(value);
|
|
246
|
+
} catch {
|
|
247
|
+
return "";
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
//# sourceMappingURL=KiroSessionParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/harnesses/kiro/KiroSessionParser.ts"],"sourcesContent":["import type { ConversationMessage, ConversationOptions } from \"../../adapters/AgentAdapter.js\";\nimport { AgentStatus } from \"../../adapters/AgentAdapter.js\";\nimport {\n IncrementalJsonlSummary,\n reduceJsonlContent,\n type JsonlSummaryBounds,\n type JsonlSummaryReducer,\n} from \"../../utils/IncrementalJsonlSummary.js\";\nimport { JsonlTailReader, normalizeTail } from \"../../utils/jsonlTail.js\";\nimport { safeReadFile, safeStat } from \"../../utils/session.js\";\nimport { isIdle, parseTimestamp } from \"../shared.js\";\n\ntype KiroRecord = Record<string, unknown>;\n\n/** One line of <session-id>.jsonl. */\ninterface KiroLine {\n kind?: string;\n timestamp?: string;\n data?: KiroRecord;\n}\n\n/** The sibling <session-id>.json metadata file. */\ninterface KiroMetadata {\n sessionId: string;\n cwd: string;\n title: string;\n createdAt: Date | null;\n updatedAt: Date | null;\n}\n\n/** O(1) running summary folded from transcript lines, never the entries themselves. */\ninterface KiroSummaryState {\n /** A bounded cold start skipped the middle: later lines are not the session's first. */\n pastHead?: boolean;\n firstUserMessage?: string;\n lastUserMessage?: string;\n /** First and last entry timestamps in file order, in epoch ms. */\n firstTimestampMs?: number;\n lastTimestampMs?: number;\n lastEventKind?: string;\n lastAssistantHasToolUse?: boolean;\n}\n\nexport interface KiroSessionParserOptions {\n /** Cold-start scan bounds for `readSessionIncremental` (see IncrementalJsonlSummary). */\n summaryBounds?: JsonlSummaryBounds | false;\n}\n\nexport interface KiroSessionPaths {\n sessionId: string;\n transcriptPath: string;\n metadataPath: string;\n}\n\nexport interface KiroSession {\n sessionId: string;\n projectPath: string;\n sessionFilePath: string;\n title: string;\n firstUserMessage: string;\n lastUserMessage?: string;\n sessionStart: Date;\n lastActive: Date;\n lastEventKind?: string;\n lastAssistantHasToolUse: boolean;\n}\n\nexport class KiroSessionParser {\n /** Incremental reader backing `getConversation({ tail })`. */\n private readonly tailReader = new JsonlTailReader();\n\n private readonly sessionCache: IncrementalJsonlSummary<KiroSummaryState>;\n\n constructor(options: KiroSessionParserOptions = {}) {\n this.sessionCache = new IncrementalJsonlSummary(this.summaryReducer, {\n bounds: options.summaryBounds,\n });\n }\n\n /**\n * Parse a session from its transcript and metadata. Metadata wins for the\n * session id, cwd and timestamps; `fallbackCwd` is used when it has no cwd.\n * Returns null when the transcript is missing.\n */\n readSession(paths: KiroSessionPaths, fallbackCwd = \"\"): KiroSession | null {\n const stat = safeStat(paths.transcriptPath);\n if (!stat?.isFile()) return null;\n\n const content = safeReadFile(paths.transcriptPath);\n const state = content === undefined ? {} : reduceJsonlContent(this.summaryReducer, content);\n return this.toSession(paths, fallbackCwd, stat, state);\n }\n\n /**\n * Same result as `readSession`, but the transcript summary is backed by a\n * per-instance incremental cache, so repeated refreshes only parse bytes\n * appended since the last call. The small metadata file is still read each\n * time. Call `pruneSessionCache()` once per refresh.\n */\n readSessionIncremental(paths: KiroSessionPaths, fallbackCwd = \"\"): KiroSession | null {\n const stat = safeStat(paths.transcriptPath);\n if (!stat?.isFile()) return null;\n\n // Present but unreadable: surface the session without a summary, like readSession.\n const state = this.sessionCache.read(paths.transcriptPath)?.state ?? {};\n return this.toSession(paths, fallbackCwd, stat, state);\n }\n\n /** Evict cached summaries for files not read since the previous prune. */\n pruneSessionCache(): void {\n this.sessionCache.prune();\n }\n\n getConversation(transcriptPath: string, options?: ConversationOptions): ConversationMessage[] {\n const verbose = options?.verbose ?? false;\n const tail = normalizeTail(options?.tail);\n if (tail === undefined) {\n return this.entriesToMessages(this.readJsonl(transcriptPath), verbose);\n }\n\n return this.tailReader.read(\n transcriptPath,\n tail,\n {\n parseLine: (line) => {\n const entry = this.parseJsonlLine(line);\n return entry ? this.entryToMessage(entry, verbose) : null;\n },\n },\n String(verbose),\n );\n }\n\n /**\n * - past the idle threshold → IDLE\n * - last event is an assistant reply without a tool call → WAITING\n * - otherwise (user prompt, tool call or tool result) → RUNNING\n */\n determineStatus(session: KiroSession): AgentStatus {\n if (isIdle(session.lastActive)) return AgentStatus.IDLE;\n if (session.lastEventKind === \"AssistantMessage\" && !session.lastAssistantHasToolUse) {\n return AgentStatus.WAITING;\n }\n return AgentStatus.RUNNING;\n }\n\n /**\n * Fold one transcript line into the O(1) summary. Uses the same entry rules\n * as `getConversation` (see `entryToMessage`); non-object lines are ignored.\n *\n * `skip` (bounded cold start) keeps the head's first prompt and timestamp and\n * resets the latest fields, so those come from the tail only.\n */\n private readonly summaryReducer: JsonlSummaryReducer<KiroSummaryState> = {\n initial: () => ({}),\n reduce: (state, value) => {\n const entry = asRecord(value) as KiroLine | null;\n if (!entry) return state;\n\n const next: KiroSummaryState = {\n ...state,\n lastEventKind: entry.kind,\n lastAssistantHasToolUse:\n entry.kind === \"AssistantMessage\" && this.hasContentKind(entry, \"toolUse\"),\n };\n\n const timestampMs = parseTimestamp(this.entryTimestamp(entry))?.getTime();\n if (timestampMs !== undefined) {\n next.lastTimestampMs = timestampMs;\n if (next.firstTimestampMs === undefined && !next.pastHead) {\n next.firstTimestampMs = timestampMs;\n }\n }\n\n const message = this.entryToMessage(entry, false);\n if (message?.role === \"user\") {\n next.lastUserMessage = message.content;\n if (next.firstUserMessage === undefined && !next.pastHead) {\n next.firstUserMessage = message.content;\n }\n }\n return next;\n },\n skip: (state) => ({\n pastHead: true,\n firstUserMessage: state.firstUserMessage,\n firstTimestampMs: state.firstTimestampMs,\n }),\n };\n\n private toSession(\n paths: KiroSessionPaths,\n fallbackCwd: string,\n stat: { birthtime: Date; mtime: Date },\n state: KiroSummaryState,\n ): KiroSession {\n const metadata = this.readMetadata(paths);\n const firstTimestamp =\n state.firstTimestampMs === undefined ? undefined : new Date(state.firstTimestampMs);\n const lastTimestamp =\n state.lastTimestampMs === undefined ? undefined : new Date(state.lastTimestampMs);\n\n return {\n sessionId: metadata.sessionId,\n projectPath: metadata.cwd || fallbackCwd,\n sessionFilePath: paths.transcriptPath,\n title: metadata.title,\n firstUserMessage: state.firstUserMessage ?? \"\",\n lastUserMessage: state.lastUserMessage,\n sessionStart: metadata.createdAt ?? firstTimestamp ?? stat.birthtime,\n lastActive: metadata.updatedAt ?? lastTimestamp ?? stat.mtime,\n lastEventKind: state.lastEventKind,\n lastAssistantHasToolUse: state.lastAssistantHasToolUse ?? false,\n };\n }\n\n private readMetadata({ sessionId, metadataPath }: KiroSessionPaths): KiroMetadata {\n const empty: KiroMetadata = {\n sessionId,\n cwd: \"\",\n title: \"\",\n createdAt: null,\n updatedAt: null,\n };\n const content = safeReadFile(metadataPath);\n if (content === undefined) return empty;\n\n let parsed: KiroRecord | null;\n try {\n parsed = asRecord(JSON.parse(content));\n } catch {\n return empty;\n }\n if (!parsed) return empty;\n\n return {\n sessionId: firstString(parsed.session_id, parsed.sessionId) ?? sessionId,\n cwd: firstString(parsed.cwd) ?? \"\",\n title: firstString(parsed.title) ?? \"\",\n createdAt: parseTimestamp(parsed.created_at ?? parsed.createdAt),\n updatedAt: parseTimestamp(parsed.updated_at ?? parsed.updatedAt),\n };\n }\n\n private readJsonl(filePath: string): KiroLine[] {\n const content = safeReadFile(filePath);\n if (content === undefined) return [];\n\n const entries: KiroLine[] = [];\n for (const line of content.split(/\\r?\\n/)) {\n const entry = this.parseJsonlLine(line);\n if (entry) entries.push(entry);\n }\n return entries;\n }\n\n private parseJsonlLine(line: string): KiroLine | null {\n const trimmed = line.trim();\n if (!trimmed) return null;\n try {\n return asRecord(JSON.parse(trimmed)) as KiroLine | null;\n } catch {\n return null;\n }\n }\n\n private entriesToMessages(entries: KiroLine[], verbose: boolean): ConversationMessage[] {\n const messages: ConversationMessage[] = [];\n for (const entry of entries) {\n const message = this.entryToMessage(entry, verbose);\n if (message) messages.push(message);\n }\n return messages;\n }\n\n /**\n * Prompt → user, AssistantMessage → assistant (tool calls appended in\n * verbose mode), ToolResults → system (verbose only).\n */\n private entryToMessage(entry: KiroLine, verbose: boolean): ConversationMessage | null {\n let role: ConversationMessage[\"role\"];\n let content: string;\n\n if (entry.kind === \"Prompt\") {\n role = \"user\";\n content = this.textContent(entry);\n } else if (entry.kind === \"AssistantMessage\") {\n role = \"assistant\";\n const parts = [this.textContent(entry)];\n if (verbose) parts.push(...this.toolUseContent(entry));\n content = parts.filter(Boolean).join(\"\\n\");\n } else if (entry.kind === \"ToolResults\" && verbose) {\n role = \"system\";\n content = this.toolResultContent(entry).join(\"\\n\");\n } else {\n return null;\n }\n\n if (!content) return null;\n return {\n role,\n content,\n timestamp: this.entryTimestamp(entry),\n };\n }\n\n private textContent(entry: KiroLine): string {\n return this.contentBlocks(entry)\n .filter((block) => block.kind === \"text\")\n .map((block) => (typeof block.data === \"string\" ? block.data : \"\"))\n .filter(Boolean)\n .join(\"\");\n }\n\n private toolUseContent(entry: KiroLine): string[] {\n return this.contentBlocks(entry)\n .filter((block) => block.kind === \"toolUse\")\n .map((block) => {\n const data = asRecord(block.data);\n const name = firstString(data?.name) ?? \"unknown\";\n const input = formatValue(data?.input);\n return `[Tool: ${name}]${input ? ` ${input}` : \"\"}`;\n });\n }\n\n private toolResultContent(entry: KiroLine): string[] {\n return this.contentBlocks(entry)\n .filter((block) => block.kind === \"toolResult\")\n .map((block) => {\n const data = asRecord(block.data);\n const prefix = data?.status === \"error\" ? \"[Tool Error]\" : \"[Tool Result]\";\n const result = formatValue(data?.result ?? data?.results ?? data?.content);\n return `${prefix}${result ? ` ${result}` : \"\"}`;\n });\n }\n\n private contentBlocks(entry: KiroLine): Array<{ kind?: string; data?: unknown }> {\n const content = entry.data?.content;\n if (!Array.isArray(content)) return [];\n return content\n .map((block) => asRecord(block))\n .filter((block): block is KiroRecord => block !== null);\n }\n\n private hasContentKind(entry: KiroLine, kind: string): boolean {\n return this.contentBlocks(entry).some((block) => block.kind === kind);\n }\n\n /** The line's own timestamp, else `data.meta.timestamp` (epoch seconds/ms or ISO). */\n private entryTimestamp(entry: KiroLine): string | undefined {\n const direct = firstString(entry.timestamp);\n if (direct) return direct;\n\n const meta = asRecord(entry.data?.meta);\n return parseTimestamp(meta?.timestamp)?.toISOString();\n }\n}\n\nexport function asRecord(value: unknown): KiroRecord | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n return value as KiroRecord;\n}\n\nfunction firstString(...values: unknown[]): string | undefined {\n return values.find((value): value is string => typeof value === \"string\" && value.length > 0);\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (value === undefined || value === null) return \"\";\n try {\n return JSON.stringify(value);\n } catch {\n return \"\";\n }\n}\n"],"names":["AgentStatus","IncrementalJsonlSummary","reduceJsonlContent","JsonlTailReader","normalizeTail","safeReadFile","safeStat","isIdle","parseTimestamp","KiroSessionParser","tailReader","sessionCache","options","summaryReducer","bounds","summaryBounds","readSession","paths","fallbackCwd","stat","transcriptPath","isFile","content","state","undefined","toSession","readSessionIncremental","read","pruneSessionCache","prune","getConversation","verbose","tail","entriesToMessages","readJsonl","parseLine","line","entry","parseJsonlLine","entryToMessage","String","determineStatus","session","lastActive","IDLE","lastEventKind","lastAssistantHasToolUse","WAITING","RUNNING","initial","reduce","value","asRecord","next","kind","hasContentKind","timestampMs","entryTimestamp","getTime","lastTimestampMs","firstTimestampMs","pastHead","message","role","lastUserMessage","firstUserMessage","skip","metadata","readMetadata","firstTimestamp","Date","lastTimestamp","sessionId","projectPath","cwd","sessionFilePath","title","sessionStart","createdAt","birthtime","updatedAt","mtime","metadataPath","empty","parsed","JSON","parse","firstString","session_id","created_at","updated_at","filePath","entries","split","push","trimmed","trim","messages","textContent","parts","toolUseContent","filter","Boolean","join","toolResultContent","timestamp","contentBlocks","block","map","data","name","input","formatValue","prefix","status","result","results","Array","isArray","some","direct","meta","toISOString","values","find","length","stringify"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* sessionFilePath encodes "<dbPath>::<sessionId>" so getConversation() can open the right
|
|
11
11
|
* DB row without extending the AgentAdapter interface.
|
|
12
12
|
*/
|
|
13
|
-
import type { AgentAdapter, AgentInfo, ProcessInfo, ConversationMessage, SessionSummary, ListSessionsOptions, AgentDetectionContext } from "../../adapters/AgentAdapter.js";
|
|
13
|
+
import type { AgentAdapter, AgentInfo, ProcessInfo, ConversationMessage, ConversationOptions, SessionSummary, ListSessionsOptions, AgentDetectionContext } from "../../adapters/AgentAdapter.js";
|
|
14
14
|
export declare class OpenCodeAdapter implements AgentAdapter {
|
|
15
15
|
readonly type: "opencode";
|
|
16
16
|
readonly processNames: readonly ["opencode"];
|
|
@@ -22,9 +22,7 @@ export declare class OpenCodeAdapter implements AgentAdapter {
|
|
|
22
22
|
close(): void;
|
|
23
23
|
canHandle(processInfo: ProcessInfo): boolean;
|
|
24
24
|
detectAgents(context?: AgentDetectionContext): Promise<AgentInfo[]>;
|
|
25
|
-
getConversation(sessionFilePath: string, options?:
|
|
26
|
-
verbose?: boolean;
|
|
27
|
-
}): ConversationMessage[];
|
|
25
|
+
getConversation(sessionFilePath: string, options?: ConversationOptions): ConversationMessage[];
|
|
28
26
|
listSessions(opts?: ListSessionsOptions): Promise<SessionSummary[]>;
|
|
29
27
|
findSessionsById(sessionId: string): Promise<SessionSummary[]>;
|
|
30
28
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenCodeAdapter.d.ts","sourceRoot":"","sources":["../../../src/harnesses/opencode/OpenCodeAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,gCAAgC,CAAC;AAcxC,qBAAa,eAAgB,YAAW,YAAY;IAClD,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IACpC,QAAQ,CAAC,YAAY,wBAAyB;IAE9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;gBAExC,MAAM,CAAC,EAAE,MAAM;IAS3B,KAAK,IAAI,IAAI;IAOb,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO;IAItC,YAAY,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IA2BzE,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE;IAUxF,YAAY,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAInE,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAGrE"}
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
*
|
|
10
10
|
* sessionFilePath encodes "<dbPath>::<sessionId>" so getConversation() can open the right
|
|
11
11
|
* DB row without extending the AgentAdapter interface.
|
|
12
|
-
*/ import {
|
|
13
|
-
import { OpenCodeAgentMapper } from "./OpenCodeAgentMapper.js";
|
|
12
|
+
*/ import { OpenCodeAgentMapper } from "./OpenCodeAgentMapper.js";
|
|
14
13
|
import { OpenCodeSessionLocator } from "./OpenCodeSessionLocator.js";
|
|
15
14
|
import { OpenCodeSessionParser } from "./OpenCodeSessionParser.js";
|
|
15
|
+
import { findHarnessProcesses, matchesExecutable } from "../shared.js";
|
|
16
16
|
const SESSION_REF_SEP = "::";
|
|
17
17
|
function decodeSessionRef(ref) {
|
|
18
18
|
const idx = ref.lastIndexOf(SESSION_REF_SEP);
|
|
@@ -45,13 +45,10 @@ export class OpenCodeAdapter {
|
|
|
45
45
|
this.locator.close();
|
|
46
46
|
}
|
|
47
47
|
canHandle(processInfo) {
|
|
48
|
-
|
|
49
|
-
return base === "opencode" || base === "opencode.exe";
|
|
48
|
+
return matchesExecutable(processInfo.command, "opencode");
|
|
50
49
|
}
|
|
51
50
|
async detectAgents(context) {
|
|
52
|
-
const
|
|
53
|
-
const relevant = filterByProcessNames(snapshot, this.processNames);
|
|
54
|
-
const processes = relevant.filter((process1)=>this.canHandle(process1));
|
|
51
|
+
const { processes } = await findHarnessProcesses(this, context);
|
|
55
52
|
if (processes.length === 0) return [];
|
|
56
53
|
const db = this.locator.openDb();
|
|
57
54
|
if (!db) return processes.map((process1)=>this.mapper.mapProcessOnlyAgent(process1));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/harnesses/opencode/OpenCodeAdapter.ts"],"sourcesContent":["/**\n * OpenCode Adapter\n *\n * Detects running OpenCode agents by:\n * 1. Filtering OpenCode processes from a shared asynchronous process snapshot\n * 2. Using snapshot CWD and start-time enrichment\n * 3. Querying OpenCode's SQLite DB (~/.local/share/opencode/opencode.db) to\n * find the session matching each process's CWD and read status from message.time.completed\n *\n * sessionFilePath encodes \"<dbPath>::<sessionId>\" so getConversation() can open the right\n * DB row without extending the AgentAdapter interface.\n */\n\nimport type {\n AgentAdapter,\n AgentInfo,\n ProcessInfo,\n ConversationMessage,\n ConversationOptions,\n SessionSummary,\n ListSessionsOptions,\n AgentDetectionContext,\n} from \"../../adapters/AgentAdapter.js\";\nimport { OpenCodeAgentMapper } from \"./OpenCodeAgentMapper.js\";\nimport { OpenCodeSessionLocator } from \"./OpenCodeSessionLocator.js\";\nimport { OpenCodeSessionParser } from \"./OpenCodeSessionParser.js\";\nimport { findHarnessProcesses, matchesExecutable } from \"../shared.js\";\n\nconst SESSION_REF_SEP = \"::\";\n\nfunction decodeSessionRef(ref: string): { sessionId: string } | null {\n const idx = ref.lastIndexOf(SESSION_REF_SEP);\n if (idx === -1) return null;\n return { sessionId: ref.slice(idx + SESSION_REF_SEP.length) };\n}\n\nexport class OpenCodeAdapter implements AgentAdapter {\n readonly type = \"opencode\" as const;\n readonly processNames = [\"opencode\"] as const;\n\n private readonly parser: OpenCodeSessionParser;\n private readonly locator: OpenCodeSessionLocator;\n private readonly mapper: OpenCodeAgentMapper;\n private readonly cleanup = (): void => this.close();\n\n constructor(dbPath?: string) {\n this.parser = new OpenCodeSessionParser();\n this.locator = new OpenCodeSessionLocator(dbPath, this.parser);\n this.mapper = new OpenCodeAgentMapper(this.locator.dbFilePath);\n process.once(\"exit\", this.cleanup);\n process.once(\"SIGINT\", this.cleanup);\n process.once(\"SIGTERM\", this.cleanup);\n }\n\n close(): void {\n process.off(\"exit\", this.cleanup);\n process.off(\"SIGINT\", this.cleanup);\n process.off(\"SIGTERM\", this.cleanup);\n this.locator.close();\n }\n\n canHandle(processInfo: ProcessInfo): boolean {\n return matchesExecutable(processInfo.command, \"opencode\");\n }\n\n async detectAgents(context?: AgentDetectionContext): Promise<AgentInfo[]> {\n const { processes } = await findHarnessProcesses(this, context);\n if (processes.length === 0) return [];\n\n const db = this.locator.openDb();\n if (!db) return processes.map((process) => this.mapper.mapProcessOnlyAgent(process));\n\n const agents: AgentInfo[] = [];\n for (const proc of processes) {\n if (!proc.cwd) {\n agents.push(this.mapper.mapProcessOnlyAgent(proc));\n continue;\n }\n\n const session = this.locator.findSessionForDirectory(db, proc.cwd);\n if (!session) {\n agents.push(this.mapper.mapProcessOnlyAgent(proc));\n continue;\n }\n\n const stats = this.parser.getSessionStats(db, session.sessionId);\n agents.push(this.mapper.mapSessionToAgent(session, stats, proc));\n }\n\n return agents;\n }\n\n getConversation(sessionFilePath: string, options?: ConversationOptions): ConversationMessage[] {\n const ref = decodeSessionRef(sessionFilePath);\n if (!ref) return [];\n\n const db = this.locator.openDb();\n if (!db) return [];\n\n return this.parser.getConversation(db, ref.sessionId, options);\n }\n\n async listSessions(opts?: ListSessionsOptions): Promise<SessionSummary[]> {\n return this.locator.listSessions(opts);\n }\n\n async findSessionsById(sessionId: string): Promise<SessionSummary[]> {\n return this.locator.findSessionsById(sessionId);\n }\n}\n"],"names":["OpenCodeAgentMapper","OpenCodeSessionLocator","OpenCodeSessionParser","findHarnessProcesses","matchesExecutable","SESSION_REF_SEP","decodeSessionRef","ref","idx","lastIndexOf","sessionId","slice","length","OpenCodeAdapter","type","processNames","parser","locator","mapper","cleanup","close","dbPath","dbFilePath","process","once","off","canHandle","processInfo","command","detectAgents","context","processes","db","openDb","map","mapProcessOnlyAgent","agents","proc","cwd","push","session","findSessionForDirectory","stats","getSessionStats","mapSessionToAgent","getConversation","sessionFilePath","options","listSessions","opts","findSessionsById"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenCodeAgentMapper.d.ts","sourceRoot":"","sources":["../../../src/
|
|
1
|
+
{"version":3,"file":"OpenCodeAgentMapper.d.ts","sourceRoot":"","sources":["../../../src/harnesses/opencode/OpenCodeAgentMapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAG7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AASvE,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAE3C,iBAAiB,CACf,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,WAAW,GAChB,SAAS;IAiBZ,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS;IAIjD,OAAO,CAAC,eAAe;CASxB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AgentStatus } from "../../adapters/AgentAdapter.js";
|
|
2
2
|
import { generateAgentName } from "../../utils/matching.js";
|
|
3
|
+
import { isIdle, processOnlyAgent } from "../shared.js";
|
|
3
4
|
const SESSION_REF_SEP = "::";
|
|
4
|
-
const IDLE_THRESHOLD_MINUTES = 5;
|
|
5
5
|
function encodeSessionRef(dbPath, sessionId) {
|
|
6
6
|
return `${dbPath}${SESSION_REF_SEP}${sessionId}`;
|
|
7
7
|
}
|
|
@@ -25,20 +25,12 @@ export class OpenCodeAgentMapper {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
mapProcessOnlyAgent(proc) {
|
|
28
|
-
return {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
status: AgentStatus.RUNNING,
|
|
32
|
-
summary: "OpenCode process running",
|
|
33
|
-
pid: proc.pid,
|
|
34
|
-
projectPath: proc.cwd || "",
|
|
35
|
-
sessionId: `pid-${proc.pid}`,
|
|
36
|
-
lastActive: new Date()
|
|
37
|
-
};
|
|
28
|
+
return processOnlyAgent("opencode", proc, {
|
|
29
|
+
summary: "OpenCode process running"
|
|
30
|
+
});
|
|
38
31
|
}
|
|
39
32
|
determineStatus(stats, lastActive) {
|
|
40
|
-
|
|
41
|
-
if (ageMin > IDLE_THRESHOLD_MINUTES) return AgentStatus.IDLE;
|
|
33
|
+
if (isIdle(lastActive)) return AgentStatus.IDLE;
|
|
42
34
|
if (stats.lastRole === "assistant" && !stats.lastAssistantCompleted) {
|
|
43
35
|
return AgentStatus.RUNNING;
|
|
44
36
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/harnesses/opencode/OpenCodeAgentMapper.ts"],"sourcesContent":["import type { AgentInfo, ProcessInfo } from \"../../adapters/AgentAdapter.js\";\nimport { AgentStatus } from \"../../adapters/AgentAdapter.js\";\nimport { generateAgentName } from \"../../utils/matching.js\";\nimport type { OpenCodeSession } from \"./OpenCodeSessionLocator.js\";\nimport type { OpenCodeSessionStats } from \"./OpenCodeSessionParser.js\";\nimport { isIdle, processOnlyAgent } from \"../shared.js\";\n\nconst SESSION_REF_SEP = \"::\";\n\nfunction encodeSessionRef(dbPath: string, sessionId: string): string {\n return `${dbPath}${SESSION_REF_SEP}${sessionId}`;\n}\n\nexport class OpenCodeAgentMapper {\n constructor(private readonly dbPath: string) {}\n\n mapSessionToAgent(\n session: OpenCodeSession,\n stats: OpenCodeSessionStats,\n proc: ProcessInfo,\n ): AgentInfo {\n const lastActive =\n stats.lastTimeUpdated > 0 ? new Date(stats.lastTimeUpdated) : new Date(session.timeCreated);\n\n return {\n name: generateAgentName(session.directory || proc.cwd || \"\", proc.pid),\n type: \"opencode\",\n status: this.determineStatus(stats, lastActive),\n summary: stats.summary || \"OpenCode session active\",\n pid: proc.pid,\n projectPath: session.directory || proc.cwd || \"\",\n sessionId: session.sessionId,\n lastActive,\n sessionFilePath: encodeSessionRef(this.dbPath, session.sessionId),\n };\n }\n\n mapProcessOnlyAgent(proc: ProcessInfo): AgentInfo {\n return processOnlyAgent(\"opencode\", proc, { summary: \"OpenCode process running\" });\n }\n\n private determineStatus(stats: OpenCodeSessionStats, lastActive: Date): AgentStatus {\n if (isIdle(lastActive)) return AgentStatus.IDLE;\n\n if (stats.lastRole === \"assistant\" && !stats.lastAssistantCompleted) {\n return AgentStatus.RUNNING;\n }\n if (stats.lastRole === \"assistant\") return AgentStatus.WAITING;\n return AgentStatus.RUNNING;\n }\n}\n"],"names":["AgentStatus","generateAgentName","isIdle","processOnlyAgent","SESSION_REF_SEP","encodeSessionRef","dbPath","sessionId","OpenCodeAgentMapper","mapSessionToAgent","session","stats","proc","lastActive","lastTimeUpdated","Date","timeCreated","name","directory","cwd","pid","type","status","determineStatus","summary","projectPath","sessionFilePath","mapProcessOnlyAgent","IDLE","lastRole","lastAssistantCompleted","RUNNING","WAITING"],"mappings":"AACA,SAASA,WAAW,QAAQ,iCAAiC;AAC7D,SAASC,iBAAiB,QAAQ,0BAA0B;AAG5D,SAASC,MAAM,EAAEC,gBAAgB,QAAQ,eAAe;AAExD,MAAMC,kBAAkB;AAExB,SAASC,iBAAiBC,MAAc,EAAEC,SAAiB;IACzD,OAAO,GAAGD,SAASF,kBAAkBG,WAAW;AAClD;AAEA,OAAO,MAAMC;;IACX,YAAY,AAAiBF,MAAc,CAAE;aAAhBA,SAAAA;IAAiB;IAE9CG,kBACEC,OAAwB,EACxBC,KAA2B,EAC3BC,IAAiB,EACN;QACX,MAAMC,aACJF,MAAMG,eAAe,GAAG,IAAI,IAAIC,KAAKJ,MAAMG,eAAe,IAAI,IAAIC,KAAKL,QAAQM,WAAW;QAE5F,OAAO;YACLC,MAAMhB,kBAAkBS,QAAQQ,SAAS,IAAIN,KAAKO,GAAG,IAAI,IAAIP,KAAKQ,GAAG;YACrEC,MAAM;YACNC,QAAQ,IAAI,CAACC,eAAe,CAACZ,OAAOE;YACpCW,SAASb,MAAMa,OAAO,IAAI;YAC1BJ,KAAKR,KAAKQ,GAAG;YACbK,aAAaf,QAAQQ,SAAS,IAAIN,KAAKO,GAAG,IAAI;YAC9CZ,WAAWG,QAAQH,SAAS;YAC5BM;YACAa,iBAAiBrB,iBAAiB,IAAI,CAACC,MAAM,EAAEI,QAAQH,SAAS;QAClE;IACF;IAEAoB,oBAAoBf,IAAiB,EAAa;QAChD,OAAOT,iBAAiB,YAAYS,MAAM;YAAEY,SAAS;QAA2B;IAClF;IAEQD,gBAAgBZ,KAA2B,EAAEE,UAAgB,EAAe;QAClF,IAAIX,OAAOW,aAAa,OAAOb,YAAY4B,IAAI;QAE/C,IAAIjB,MAAMkB,QAAQ,KAAK,eAAe,CAAClB,MAAMmB,sBAAsB,EAAE;YACnE,OAAO9B,YAAY+B,OAAO;QAC5B;QACA,IAAIpB,MAAMkB,QAAQ,KAAK,aAAa,OAAO7B,YAAYgC,OAAO;QAC9D,OAAOhC,YAAY+B,OAAO;IAC5B;AACF"}
|