@ai-devkit/agent-manager 0.36.0 → 0.38.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 -8
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +23 -4
- 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/anthropic.test.js +115 -0
- package/dist/__tests__/capacity/anthropic.test.js.map +1 -0
- package/dist/__tests__/capacity/boundaries.test.js +45 -0
- package/dist/__tests__/capacity/boundaries.test.js.map +1 -0
- package/dist/__tests__/capacity/claude.test.js +3 -3
- package/dist/__tests__/capacity/claude.test.js.map +1 -1
- package/dist/__tests__/capacity/codex.test.js +3 -1
- package/dist/__tests__/capacity/codex.test.js.map +1 -1
- package/dist/__tests__/capacity/openai.test.js +32 -25
- package/dist/__tests__/capacity/openai.test.js.map +1 -1
- package/dist/__tests__/capacity/wham.test.js +1 -1
- package/dist/__tests__/capacity/wham.test.js.map +1 -1
- package/dist/__tests__/capacity/zai.test.js +7 -8
- package/dist/__tests__/capacity/zai.test.js.map +1 -1
- 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__/harnesses/claude/ClaudeAgentMapper.test.js +79 -0
- package/dist/__tests__/harnesses/claude/ClaudeAgentMapper.test.js.map +1 -0
- package/dist/__tests__/harnesses/claude/ClaudeCodeAdapter.test.js +1881 -0
- package/dist/__tests__/harnesses/claude/ClaudeCodeAdapter.test.js.map +1 -0
- package/dist/__tests__/harnesses/claude/ClaudeSessionLocator.test.js +425 -0
- package/dist/__tests__/harnesses/claude/ClaudeSessionLocator.test.js.map +1 -0
- package/dist/__tests__/harnesses/claude/ClaudeSessionParser.test.js +314 -0
- package/dist/__tests__/harnesses/claude/ClaudeSessionParser.test.js.map +1 -0
- package/dist/__tests__/harnesses/claude/durable/ClaudeCliProbe.test.js +49 -0
- package/dist/__tests__/harnesses/claude/durable/ClaudeCliProbe.test.js.map +1 -0
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js +76 -0
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -0
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgentService.test.js +173 -0
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgentService.test.js.map +1 -0
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js +181 -0
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -0
- package/dist/__tests__/harnesses/codex/CodexAdapter.test.js +685 -0
- 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__/harnesses/codex/CodexSessionMapping.test.js +86 -0
- package/dist/__tests__/harnesses/codex/CodexSessionMapping.test.js.map +1 -0
- package/dist/__tests__/harnesses/codex/CodexSessionParser.test.js +254 -0
- package/dist/__tests__/harnesses/codex/CodexSessionParser.test.js.map +1 -0
- package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js +121 -0
- package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -0
- package/dist/__tests__/harnesses/codex/durable/CodexDurableAgentRepository.test.js +84 -0
- package/dist/__tests__/harnesses/codex/durable/CodexDurableAgentRepository.test.js.map +1 -0
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js +128 -0
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -0
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js +246 -0
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -0
- package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js +384 -0
- package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -0
- package/dist/__tests__/harnesses/copilot/CopilotAdapter.test.js +659 -0
- package/dist/__tests__/harnesses/copilot/CopilotAdapter.test.js.map +1 -0
- package/dist/__tests__/harnesses/copilot/CopilotRefreshIO.test.js +290 -0
- package/dist/__tests__/harnesses/copilot/CopilotRefreshIO.test.js.map +1 -0
- package/dist/__tests__/harnesses/gemini/GeminiCliAdapter.test.js +1443 -0
- 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__/harnesses/grok/GrokAgentMapper.test.js +56 -0
- package/dist/__tests__/harnesses/grok/GrokAgentMapper.test.js.map +1 -0
- package/dist/__tests__/harnesses/grok/GrokCliAdapter.test.js +421 -0
- package/dist/__tests__/harnesses/grok/GrokCliAdapter.test.js.map +1 -0
- package/dist/__tests__/harnesses/grok/GrokIncrementalRefresh.test.js +167 -0
- package/dist/__tests__/harnesses/grok/GrokIncrementalRefresh.test.js.map +1 -0
- package/dist/__tests__/harnesses/grok/GrokSessionLocator.test.js +133 -0
- package/dist/__tests__/harnesses/grok/GrokSessionLocator.test.js.map +1 -0
- 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__/harnesses/opencode/OpenCodeAdapter.test.js +213 -0
- package/dist/__tests__/harnesses/opencode/OpenCodeAdapter.test.js.map +1 -0
- package/dist/__tests__/harnesses/opencode/OpenCodeAgentMapper.test.js +89 -0
- package/dist/__tests__/harnesses/opencode/OpenCodeAgentMapper.test.js.map +1 -0
- package/dist/__tests__/harnesses/opencode/OpenCodeSessionLocator.test.js +94 -0
- package/dist/__tests__/harnesses/opencode/OpenCodeSessionLocator.test.js.map +1 -0
- package/dist/__tests__/harnesses/opencode/OpenCodeSessionParser.test.js +147 -0
- package/dist/__tests__/harnesses/opencode/OpenCodeSessionParser.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/PiAdapter.test.js +367 -0
- package/dist/__tests__/harnesses/pi/PiAdapter.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/PiDiscoveryIO.test.js +382 -0
- package/dist/__tests__/harnesses/pi/PiDiscoveryIO.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/PiSessionParser.test.js +416 -0
- package/dist/__tests__/harnesses/pi/PiSessionParser.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/PiSessionTracker.test.js +108 -0
- package/dist/__tests__/harnesses/pi/PiSessionTracker.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js +70 -0
- package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/durable/PiDurableAgentRepository.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js +192 -0
- package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/durable/PiPrintProtocol.test.js +119 -0
- package/dist/__tests__/harnesses/pi/durable/PiPrintProtocol.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js +382 -0
- package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js.map +1 -0
- package/dist/__tests__/harnesses/pi/durable/PiStreamParser.test.js +34 -0
- package/dist/__tests__/harnesses/pi/durable/PiStreamParser.test.js.map +1 -0
- package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js +342 -0
- package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js.map +1 -0
- package/dist/__tests__/harnesses/runtimeProfiles.test.js +89 -0
- package/dist/__tests__/harnesses/runtimeProfiles.test.js.map +1 -0
- package/dist/__tests__/print/DurableAgent.test.js +4 -6
- package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
- package/dist/__tests__/print/DurableAgentRepository.test.js +1 -12
- package/dist/__tests__/print/DurableAgentRepository.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__/terminal/TmuxManager.test.js +1 -1
- package/dist/__tests__/terminal/TmuxManager.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/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/index.d.ts +9 -19
- package/dist/capacity/index.d.ts.map +1 -1
- package/dist/capacity/index.js +11 -4
- package/dist/capacity/index.js.map +1 -1
- package/dist/capacity/providers/anthropic.d.ts +9 -0
- package/dist/capacity/providers/anthropic.d.ts.map +1 -0
- package/dist/capacity/providers/anthropic.js +153 -0
- package/dist/capacity/providers/anthropic.js.map +1 -0
- package/dist/capacity/providers/openai-platform.d.ts +14 -0
- package/dist/capacity/providers/openai-platform.d.ts.map +1 -0
- package/dist/capacity/providers/openai-platform.js +120 -0
- package/dist/capacity/providers/openai-platform.js.map +1 -0
- package/dist/capacity/providers/openai-subscription.d.ts +20 -0
- package/dist/capacity/providers/openai-subscription.d.ts.map +1 -0
- package/dist/capacity/providers/openai-subscription.js +129 -0
- package/dist/capacity/providers/openai-subscription.js.map +1 -0
- package/dist/capacity/providers/zai.d.ts +8 -0
- package/dist/capacity/providers/zai.d.ts.map +1 -0
- package/dist/capacity/providers/zai.js +158 -0
- package/dist/capacity/providers/zai.js.map +1 -0
- package/dist/capacity/sources/claude.d.ts +9 -0
- package/dist/capacity/sources/claude.d.ts.map +1 -0
- package/dist/capacity/sources/claude.js +17 -0
- package/dist/capacity/sources/claude.js.map +1 -0
- package/dist/capacity/sources/codex.d.ts +32 -0
- package/dist/capacity/sources/codex.d.ts.map +1 -0
- package/dist/capacity/sources/codex.js +227 -0
- package/dist/capacity/sources/codex.js.map +1 -0
- package/dist/capacity/sources/pi.d.ts +30 -0
- package/dist/capacity/sources/pi.d.ts.map +1 -0
- package/dist/capacity/sources/pi.js +81 -0
- package/dist/capacity/sources/pi.js.map +1 -0
- package/dist/capacity/types.d.ts +2 -0
- package/dist/capacity/types.d.ts.map +1 -1
- package/dist/capacity/types.js +1 -1
- package/dist/capacity/types.js.map +1 -1
- 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/harnesses/claude/ClaudeAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/claude/ClaudeAgentMapper.js +36 -0
- package/dist/harnesses/claude/ClaudeAgentMapper.js.map +1 -0
- package/dist/harnesses/claude/ClaudeCodeAdapter.d.ts +30 -0
- package/dist/harnesses/claude/ClaudeCodeAdapter.d.ts.map +1 -0
- package/dist/harnesses/claude/ClaudeCodeAdapter.js +134 -0
- package/dist/harnesses/claude/ClaudeCodeAdapter.js.map +1 -0
- package/dist/harnesses/claude/ClaudeSessionLocator.d.ts.map +1 -0
- package/dist/harnesses/claude/ClaudeSessionLocator.js +260 -0
- package/dist/harnesses/claude/ClaudeSessionLocator.js.map +1 -0
- package/dist/harnesses/claude/ClaudeSessionParser.d.ts +148 -0
- package/dist/harnesses/claude/ClaudeSessionParser.d.ts.map +1 -0
- package/dist/harnesses/claude/ClaudeSessionParser.js +365 -0
- package/dist/harnesses/claude/ClaudeSessionParser.js.map +1 -0
- package/dist/harnesses/claude/credentials.d.ts +10 -0
- package/dist/harnesses/claude/credentials.d.ts.map +1 -0
- package/dist/harnesses/claude/credentials.js +112 -0
- package/dist/harnesses/claude/credentials.js.map +1 -0
- package/dist/harnesses/claude/durable/ClaudeCliProbe.d.ts.map +1 -0
- package/dist/harnesses/claude/durable/ClaudeCliProbe.js.map +1 -0
- package/dist/harnesses/claude/durable/ClaudePrintAgentService.d.ts.map +1 -0
- package/dist/harnesses/claude/durable/ClaudePrintAgentService.js.map +1 -0
- package/dist/harnesses/claude/durable/ClaudePrintRunner.d.ts.map +1 -0
- package/dist/harnesses/claude/durable/ClaudePrintRunner.js.map +1 -0
- package/dist/harnesses/claude/durable/ClaudeStreamParser.d.ts.map +1 -0
- package/dist/harnesses/claude/durable/ClaudeStreamParser.js.map +1 -0
- package/dist/harnesses/claude/readiness.d.ts +3 -0
- package/dist/harnesses/claude/readiness.d.ts.map +1 -0
- package/dist/harnesses/claude/readiness.js +63 -0
- package/dist/harnesses/claude/readiness.js.map +1 -0
- package/dist/harnesses/codex/CodexAdapter.d.ts +29 -0
- package/dist/harnesses/codex/CodexAdapter.d.ts.map +1 -0
- package/dist/harnesses/codex/CodexAdapter.js +290 -0
- package/dist/harnesses/codex/CodexAdapter.js.map +1 -0
- package/dist/harnesses/codex/CodexAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/codex/CodexAgentMapper.js +28 -0
- 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/harnesses/codex/CodexSessionMapping.d.ts.map +1 -0
- package/dist/harnesses/codex/CodexSessionMapping.js +68 -0
- 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/harnesses/codex/CodexSessionParser.js +308 -0
- package/dist/harnesses/codex/CodexSessionParser.js.map +1 -0
- package/dist/harnesses/codex/credentials.d.ts +15 -0
- package/dist/harnesses/codex/credentials.d.ts.map +1 -0
- package/dist/harnesses/codex/credentials.js +58 -0
- package/dist/harnesses/codex/credentials.js.map +1 -0
- package/dist/harnesses/codex/durable/CodexCliProbe.d.ts.map +1 -0
- package/dist/harnesses/codex/durable/CodexCliProbe.js.map +1 -0
- package/dist/harnesses/codex/durable/CodexPrintAgentService.d.ts.map +1 -0
- package/dist/harnesses/codex/durable/CodexPrintAgentService.js.map +1 -0
- package/dist/harnesses/codex/durable/CodexPrintRunner.d.ts.map +1 -0
- package/dist/harnesses/codex/durable/CodexPrintRunner.js.map +1 -0
- package/dist/harnesses/codex/durable/CodexStreamParser.d.ts.map +1 -0
- package/dist/harnesses/codex/durable/CodexStreamParser.js.map +1 -0
- package/dist/harnesses/codex/readiness.d.ts +3 -0
- package/dist/harnesses/codex/readiness.d.ts.map +1 -0
- package/dist/harnesses/codex/readiness.js +60 -0
- package/dist/harnesses/codex/readiness.js.map +1 -0
- package/dist/harnesses/copilot/CopilotAdapter.d.ts +36 -0
- package/dist/harnesses/copilot/CopilotAdapter.d.ts.map +1 -0
- package/dist/harnesses/copilot/CopilotAdapter.js +128 -0
- package/dist/harnesses/copilot/CopilotAdapter.js.map +1 -0
- package/dist/harnesses/copilot/CopilotAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/copilot/CopilotAgentMapper.js +30 -0
- 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/harnesses/copilot/readiness.d.ts +3 -0
- package/dist/harnesses/copilot/readiness.d.ts.map +1 -0
- package/dist/harnesses/copilot/readiness.js +39 -0
- package/dist/harnesses/copilot/readiness.js.map +1 -0
- package/dist/harnesses/gemini/GeminiAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/gemini/GeminiAgentMapper.js +30 -0
- package/dist/harnesses/gemini/GeminiAgentMapper.js.map +1 -0
- package/dist/harnesses/gemini/GeminiCliAdapter.d.ts +52 -0
- package/dist/harnesses/gemini/GeminiCliAdapter.d.ts.map +1 -0
- package/dist/harnesses/gemini/GeminiCliAdapter.js +196 -0
- 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/harnesses/gemini/GeminiSessionParser.d.ts +121 -0
- 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/harnesses/grok/GrokAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/grok/GrokAgentMapper.js +30 -0
- package/dist/harnesses/grok/GrokAgentMapper.js.map +1 -0
- package/dist/harnesses/grok/GrokCliAdapter.d.ts +36 -0
- package/dist/harnesses/grok/GrokCliAdapter.d.ts.map +1 -0
- package/dist/harnesses/grok/GrokCliAdapter.js +102 -0
- package/dist/harnesses/grok/GrokCliAdapter.js.map +1 -0
- package/dist/harnesses/grok/GrokSessionLocator.d.ts.map +1 -0
- package/dist/harnesses/grok/GrokSessionLocator.js +140 -0
- 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/harnesses/opencode/OpenCodeAdapter.d.ts +29 -0
- package/dist/harnesses/opencode/OpenCodeAdapter.d.ts.map +1 -0
- package/dist/harnesses/opencode/OpenCodeAdapter.js +86 -0
- package/dist/harnesses/opencode/OpenCodeAdapter.js.map +1 -0
- package/dist/harnesses/opencode/OpenCodeAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/opencode/OpenCodeAgentMapper.js +42 -0
- package/dist/harnesses/opencode/OpenCodeAgentMapper.js.map +1 -0
- package/dist/harnesses/opencode/OpenCodeSessionLocator.d.ts.map +1 -0
- package/dist/harnesses/opencode/OpenCodeSessionLocator.js +118 -0
- package/dist/harnesses/opencode/OpenCodeSessionLocator.js.map +1 -0
- package/dist/harnesses/opencode/OpenCodeSessionParser.d.ts +16 -0
- package/dist/harnesses/opencode/OpenCodeSessionParser.d.ts.map +1 -0
- package/dist/harnesses/opencode/OpenCodeSessionParser.js +105 -0
- package/dist/harnesses/opencode/OpenCodeSessionParser.js.map +1 -0
- package/dist/harnesses/opencode/readiness.d.ts +3 -0
- package/dist/harnesses/opencode/readiness.d.ts.map +1 -0
- package/dist/harnesses/opencode/readiness.js +50 -0
- package/dist/harnesses/opencode/readiness.js.map +1 -0
- package/dist/harnesses/pi/PiAdapter.d.ts +30 -0
- package/dist/harnesses/pi/PiAdapter.d.ts.map +1 -0
- package/dist/harnesses/pi/PiAdapter.js +167 -0
- package/dist/harnesses/pi/PiAdapter.js.map +1 -0
- package/dist/harnesses/pi/PiAgentMapper.d.ts.map +1 -0
- package/dist/harnesses/pi/PiAgentMapper.js +30 -0
- 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/harnesses/pi/PiSessionTracker.d.ts.map +1 -0
- package/dist/harnesses/pi/PiSessionTracker.js +69 -0
- package/dist/harnesses/pi/PiSessionTracker.js.map +1 -0
- package/dist/harnesses/pi/credentials.d.ts +22 -0
- package/dist/harnesses/pi/credentials.d.ts.map +1 -0
- package/dist/harnesses/pi/credentials.js +98 -0
- package/dist/harnesses/pi/credentials.js.map +1 -0
- package/dist/harnesses/pi/durable/PiCliProbe.d.ts.map +1 -0
- package/dist/harnesses/pi/durable/PiCliProbe.js.map +1 -0
- package/dist/harnesses/pi/durable/PiPrintAgentService.d.ts.map +1 -0
- package/dist/harnesses/pi/durable/PiPrintAgentService.js.map +1 -0
- package/dist/harnesses/pi/durable/PiPrintProtocol.d.ts.map +1 -0
- package/dist/harnesses/pi/durable/PiPrintProtocol.js.map +1 -0
- package/dist/harnesses/pi/durable/PiPrintRunner.d.ts.map +1 -0
- package/dist/harnesses/pi/durable/PiPrintRunner.js.map +1 -0
- package/dist/harnesses/pi/durable/PiStreamParser.d.ts.map +1 -0
- package/dist/harnesses/pi/durable/PiStreamParser.js.map +1 -0
- package/dist/harnesses/pi/readiness.d.ts +3 -0
- package/dist/harnesses/pi/readiness.d.ts.map +1 -0
- package/dist/harnesses/pi/readiness.js +96 -0
- package/dist/harnesses/pi/readiness.js.map +1 -0
- package/dist/harnesses/readiness/AgentReadiness.d.ts +6 -0
- package/dist/harnesses/readiness/AgentReadiness.d.ts.map +1 -0
- package/dist/harnesses/readiness/AgentReadiness.js +68 -0
- package/dist/harnesses/readiness/AgentReadiness.js.map +1 -0
- package/dist/harnesses/readiness/checks.d.ts +31 -0
- package/dist/harnesses/readiness/checks.d.ts.map +1 -0
- package/dist/harnesses/readiness/checks.js +270 -0
- package/dist/harnesses/readiness/checks.js.map +1 -0
- package/dist/harnesses/readiness/types.d.ts +76 -0
- package/dist/harnesses/readiness/types.d.ts.map +1 -0
- package/dist/harnesses/readiness/types.js +4 -0
- package/dist/harnesses/readiness/types.js.map +1 -0
- package/dist/harnesses/runtimeProfiles.d.ts +11 -0
- package/dist/harnesses/runtimeProfiles.d.ts.map +1 -0
- package/dist/harnesses/runtimeProfiles.js +99 -0
- package/dist/harnesses/runtimeProfiles.js.map +1 -0
- 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 +21 -46
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -27
- package/dist/index.js.map +1 -1
- package/dist/runtime/ManagedAgentRuntime.d.ts +3 -3
- package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -1
- package/dist/runtime/ManagedAgentRuntime.js +6 -20
- package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
- package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -1
- package/dist/runtime/herdr/HerdrAgentDiscovery.js +2 -43
- package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
- package/dist/runtime/tmux/PidPolling.d.ts +1 -1
- package/dist/runtime/tmux/PidPolling.d.ts.map +1 -1
- package/dist/runtime/tmux/PidPolling.js.map +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.js +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -1
- package/dist/runtime/tmux/TmuxManager.d.ts +12 -0
- package/dist/runtime/tmux/TmuxManager.d.ts.map +1 -0
- package/dist/runtime/tmux/TmuxManager.js +116 -0
- package/dist/runtime/tmux/TmuxManager.js.map +1 -0
- package/dist/runtime/types.d.ts +1 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/terminal/TerminalFocusManager.d.ts +4 -32
- package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
- package/dist/terminal/TerminalFocusManager.js +17 -267
- package/dist/terminal/TerminalFocusManager.js.map +1 -1
- package/dist/terminal/TtyWriter.d.ts +1 -44
- package/dist/terminal/TtyWriter.d.ts.map +1 -1
- package/dist/terminal/TtyWriter.js +11 -347
- package/dist/terminal/TtyWriter.js.map +1 -1
- package/dist/terminal/backends/index.d.ts +5 -0
- package/dist/terminal/backends/index.d.ts.map +1 -0
- package/dist/terminal/backends/index.js +19 -0
- package/dist/terminal/backends/index.js.map +1 -0
- package/dist/terminal/backends/iterm2.d.ts +3 -0
- package/dist/terminal/backends/iterm2.d.ts.map +1 -0
- package/dist/terminal/backends/iterm2.js +135 -0
- package/dist/terminal/backends/iterm2.js.map +1 -0
- package/dist/terminal/backends/shared.d.ts +7 -0
- package/dist/terminal/backends/shared.d.ts.map +1 -0
- package/dist/terminal/backends/shared.js +35 -0
- package/dist/terminal/backends/shared.js.map +1 -0
- package/dist/terminal/backends/terminal-app.d.ts +3 -0
- package/dist/terminal/backends/terminal-app.d.ts.map +1 -0
- package/dist/terminal/backends/terminal-app.js +129 -0
- package/dist/terminal/backends/terminal-app.js.map +1 -0
- package/dist/terminal/backends/tmux.d.ts +3 -0
- package/dist/terminal/backends/tmux.d.ts.map +1 -0
- package/dist/terminal/backends/tmux.js +76 -0
- package/dist/terminal/backends/tmux.js.map +1 -0
- package/dist/terminal/backends/wezterm.d.ts +3 -0
- package/dist/terminal/backends/wezterm.d.ts.map +1 -0
- package/dist/terminal/backends/wezterm.js +71 -0
- package/dist/terminal/backends/wezterm.js.map +1 -0
- package/dist/terminal/types.d.ts +21 -0
- package/dist/terminal/types.d.ts.map +1 -0
- package/dist/terminal/types.js +10 -0
- package/dist/terminal/types.js.map +1 -0
- 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/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 +27 -6
- 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/anthropic.test.ts +105 -0
- package/src/__tests__/capacity/boundaries.test.ts +36 -0
- package/src/__tests__/capacity/claude.test.ts +3 -8
- package/src/__tests__/capacity/codex.test.ts +12 -35
- package/src/__tests__/capacity/fixtures/openai-codex-auth.json +1 -1
- package/src/__tests__/capacity/openai.test.ts +20 -30
- package/src/__tests__/capacity/wham.test.ts +1 -1
- package/src/__tests__/capacity/zai.test.ts +27 -62
- 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__/harnesses/claude/ClaudeAgentMapper.test.ts +84 -0
- package/src/__tests__/harnesses/claude/ClaudeCodeAdapter.test.ts +1793 -0
- package/src/__tests__/harnesses/claude/ClaudeSessionLocator.test.ts +423 -0
- package/src/__tests__/harnesses/claude/ClaudeSessionParser.test.ts +300 -0
- package/src/__tests__/harnesses/claude/durable/ClaudeCliProbe.test.ts +34 -0
- package/src/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.ts +61 -0
- package/src/__tests__/harnesses/claude/durable/ClaudePrintAgentService.test.ts +129 -0
- package/src/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.ts +152 -0
- package/src/__tests__/harnesses/codex/CodexAdapter.test.ts +652 -0
- package/src/__tests__/harnesses/codex/CodexSessionLocator.test.ts +419 -0
- package/src/__tests__/harnesses/codex/CodexSessionMapping.test.ts +63 -0
- package/src/__tests__/harnesses/codex/CodexSessionParser.test.ts +192 -0
- package/src/__tests__/harnesses/codex/durable/CodexCliProbe.test.ts +80 -0
- package/src/__tests__/harnesses/codex/durable/CodexDurableAgentRepository.test.ts +65 -0
- package/src/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.ts +104 -0
- package/src/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.ts +201 -0
- package/src/__tests__/harnesses/codex/durable/CodexPrintRunner.test.ts +299 -0
- package/src/__tests__/harnesses/copilot/CopilotAdapter.test.ts +614 -0
- package/src/__tests__/harnesses/copilot/CopilotRefreshIO.test.ts +270 -0
- package/src/__tests__/harnesses/gemini/GeminiCliAdapter.test.ts +1324 -0
- package/src/__tests__/harnesses/gemini/GeminiSessionJsonl.test.ts +402 -0
- package/src/__tests__/harnesses/gemini/GeminiSessionLocator.test.ts +396 -0
- package/src/__tests__/harnesses/grok/GrokAgentMapper.test.ts +57 -0
- package/src/__tests__/harnesses/grok/GrokCliAdapter.test.ts +376 -0
- package/src/__tests__/harnesses/grok/GrokIncrementalRefresh.test.ts +170 -0
- package/src/__tests__/harnesses/grok/GrokSessionLocator.test.ts +106 -0
- package/src/__tests__/harnesses/grok/GrokSessionParser.test.ts +230 -0
- package/src/__tests__/harnesses/kiro/KiroAdapter.test.ts +552 -0
- package/src/__tests__/harnesses/opencode/OpenCodeAdapter.test.ts +215 -0
- package/src/__tests__/harnesses/opencode/OpenCodeAgentMapper.test.ts +83 -0
- package/src/__tests__/harnesses/opencode/OpenCodeSessionLocator.test.ts +84 -0
- package/src/__tests__/harnesses/opencode/OpenCodeSessionParser.test.ts +148 -0
- package/src/__tests__/harnesses/pi/PiAdapter.test.ts +325 -0
- package/src/__tests__/harnesses/pi/PiDiscoveryIO.test.ts +337 -0
- package/src/__tests__/harnesses/pi/PiSessionParser.test.ts +280 -0
- package/src/__tests__/harnesses/pi/PiSessionTracker.test.ts +79 -0
- package/src/__tests__/harnesses/pi/durable/PiCliProbe.test.ts +50 -0
- package/src/__tests__/harnesses/pi/durable/PiPrintAgentService.test.ts +138 -0
- package/src/__tests__/harnesses/pi/durable/PiPrintProtocol.test.ts +71 -0
- package/src/__tests__/harnesses/pi/durable/PiPrintRunner.test.ts +252 -0
- package/src/__tests__/harnesses/pi/durable/PiStreamParser.test.ts +26 -0
- package/src/__tests__/harnesses/readiness/AgentReadiness.test.ts +285 -0
- package/src/__tests__/harnesses/runtimeProfiles.test.ts +110 -0
- package/src/__tests__/print/DurableAgent.test.ts +4 -13
- package/src/__tests__/print/DurableAgentRepository.test.ts +1 -13
- package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +31 -1
- package/src/__tests__/terminal/TmuxManager.test.ts +1 -1
- package/src/__tests__/utils/IncrementalJsonlSummary.test.ts +414 -0
- 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 -14
- package/src/capacity/index.ts +29 -23
- package/src/capacity/providers/anthropic.ts +198 -0
- package/src/capacity/providers/openai-platform.ts +150 -0
- package/src/capacity/providers/openai-subscription.ts +162 -0
- package/src/capacity/providers/zai.ts +155 -0
- package/src/capacity/sources/claude.ts +30 -0
- package/src/capacity/sources/codex.ts +262 -0
- package/src/capacity/sources/pi.ts +131 -0
- package/src/capacity/types.ts +3 -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/harnesses/claude/ClaudeAgentMapper.ts +55 -0
- package/src/harnesses/claude/ClaudeCodeAdapter.ts +175 -0
- package/src/harnesses/claude/ClaudeSessionLocator.ts +358 -0
- package/src/harnesses/claude/ClaudeSessionParser.ts +524 -0
- package/src/harnesses/claude/credentials.ts +122 -0
- package/src/harnesses/claude/readiness.ts +69 -0
- package/src/harnesses/codex/CodexAdapter.ts +337 -0
- package/src/harnesses/codex/CodexAgentMapper.ts +26 -0
- package/src/harnesses/codex/CodexSessionLocator.ts +509 -0
- package/src/harnesses/codex/CodexSessionMapping.ts +89 -0
- package/src/harnesses/codex/CodexSessionParser.ts +462 -0
- package/src/harnesses/codex/credentials.ts +81 -0
- package/src/harnesses/codex/readiness.ts +72 -0
- package/src/harnesses/copilot/CopilotAdapter.ts +161 -0
- package/src/harnesses/copilot/CopilotAgentMapper.ts +27 -0
- package/src/harnesses/copilot/CopilotSessionLocator.ts +161 -0
- package/src/harnesses/copilot/CopilotSessionParser.ts +380 -0
- package/src/harnesses/copilot/readiness.ts +33 -0
- package/src/harnesses/gemini/GeminiAgentMapper.ts +27 -0
- package/src/harnesses/gemini/GeminiCliAdapter.ts +272 -0
- package/src/harnesses/gemini/GeminiSessionLocator.ts +394 -0
- package/src/harnesses/gemini/GeminiSessionParser.ts +395 -0
- package/src/harnesses/gemini/fileSignature.ts +10 -0
- package/src/harnesses/grok/GrokAgentMapper.ts +32 -0
- package/src/harnesses/grok/GrokCliAdapter.ts +126 -0
- package/src/harnesses/grok/GrokSessionLocator.ts +179 -0
- 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/harnesses/opencode/OpenCodeAdapter.ts +110 -0
- package/src/harnesses/opencode/OpenCodeAgentMapper.ts +51 -0
- package/src/harnesses/opencode/OpenCodeSessionLocator.ts +151 -0
- package/src/harnesses/opencode/OpenCodeSessionParser.ts +146 -0
- package/src/harnesses/opencode/readiness.ts +48 -0
- package/src/harnesses/pi/PiAdapter.ts +197 -0
- package/src/harnesses/pi/PiAgentMapper.ts +27 -0
- package/src/harnesses/pi/PiSessionLocator.ts +288 -0
- package/src/harnesses/pi/PiSessionParser.ts +488 -0
- package/src/harnesses/pi/PiSessionTracker.ts +87 -0
- package/src/harnesses/pi/credentials.ts +129 -0
- package/src/harnesses/pi/readiness.ts +104 -0
- package/src/harnesses/readiness/AgentReadiness.ts +87 -0
- package/src/harnesses/readiness/checks.ts +336 -0
- package/src/harnesses/readiness/types.ts +90 -0
- package/src/harnesses/runtimeProfiles.ts +103 -0
- package/src/harnesses/shared.ts +119 -0
- package/src/index.ts +20 -131
- package/src/runtime/ManagedAgentRuntime.ts +7 -22
- package/src/runtime/herdr/HerdrAgentDiscovery.ts +3 -19
- package/src/runtime/tmux/PidPolling.ts +1 -1
- package/src/runtime/tmux/TmuxAgentRuntime.ts +1 -1
- package/src/runtime/tmux/TmuxManager.ts +102 -0
- package/src/runtime/types.ts +1 -1
- package/src/terminal/TerminalFocusManager.ts +19 -292
- package/src/terminal/TtyWriter.ts +16 -336
- package/src/terminal/backends/index.ts +21 -0
- package/src/terminal/backends/iterm2.ts +126 -0
- package/src/terminal/backends/shared.ts +42 -0
- package/src/terminal/backends/terminal-app.ts +122 -0
- package/src/terminal/backends/tmux.ts +62 -0
- package/src/terminal/backends/wezterm.ts +65 -0
- package/src/terminal/types.ts +22 -0
- package/src/utils/IncrementalJsonlSummary.ts +306 -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/AntigravityCliAdapter.test.js +0 -381
- package/dist/__tests__/adapters/AntigravityCliAdapter.test.js.map +0 -1
- package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js +0 -1853
- package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +0 -1
- package/dist/__tests__/adapters/CodexAdapter.test.js +0 -391
- package/dist/__tests__/adapters/CodexAdapter.test.js.map +0 -1
- package/dist/__tests__/adapters/KiroAdapter.test.js +0 -607
- package/dist/__tests__/adapters/KiroAdapter.test.js.map +0 -1
- package/dist/__tests__/durable/CodexCliProbe.test.js +0 -129
- package/dist/__tests__/durable/CodexCliProbe.test.js.map +0 -1
- package/dist/__tests__/durable/CodexDurableAgentRepository.test.js +0 -84
- package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +0 -1
- package/dist/__tests__/durable/CodexPrintAgent.integration.test.js +0 -126
- package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +0 -1
- package/dist/__tests__/durable/CodexPrintAgentService.test.js +0 -271
- package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +0 -1
- package/dist/__tests__/durable/CodexPrintRunner.test.js +0 -393
- package/dist/__tests__/durable/CodexPrintRunner.test.js.map +0 -1
- package/dist/__tests__/print/ClaudeCliProbe.test.js +0 -49
- package/dist/__tests__/print/ClaudeCliProbe.test.js.map +0 -1
- package/dist/__tests__/print/ClaudePrintAgent.integration.test.js +0 -75
- package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +0 -1
- package/dist/__tests__/print/ClaudePrintAgentService.test.js +0 -173
- package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +0 -1
- package/dist/__tests__/print/ClaudePrintRunner.test.js +0 -181
- package/dist/__tests__/print/ClaudePrintRunner.test.js.map +0 -1
- package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js +0 -79
- package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +0 -1
- package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js +0 -436
- package/dist/__tests__/providers/claude/ClaudeSessionLocator.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/codex/CodexSessionMapping.test.js +0 -86
- package/dist/__tests__/providers/codex/CodexSessionMapping.test.js.map +0 -1
- package/dist/__tests__/providers/codex/CodexSessionParser.test.js +0 -254
- package/dist/__tests__/providers/codex/CodexSessionParser.test.js.map +0 -1
- package/dist/__tests__/providers/copilot/CopilotAdapter.test.js +0 -659
- package/dist/__tests__/providers/copilot/CopilotAdapter.test.js.map +0 -1
- package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js +0 -1434
- package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js.map +0 -1
- package/dist/__tests__/providers/grok/GrokAgentMapper.test.js +0 -56
- package/dist/__tests__/providers/grok/GrokAgentMapper.test.js.map +0 -1
- package/dist/__tests__/providers/grok/GrokCliAdapter.test.js +0 -421
- package/dist/__tests__/providers/grok/GrokCliAdapter.test.js.map +0 -1
- package/dist/__tests__/providers/grok/GrokSessionLocator.test.js +0 -133
- package/dist/__tests__/providers/grok/GrokSessionLocator.test.js.map +0 -1
- package/dist/__tests__/providers/opencode/OpenCodeAdapter.test.js +0 -213
- package/dist/__tests__/providers/opencode/OpenCodeAdapter.test.js.map +0 -1
- package/dist/__tests__/providers/opencode/OpenCodeAgentMapper.test.js +0 -89
- package/dist/__tests__/providers/opencode/OpenCodeAgentMapper.test.js.map +0 -1
- package/dist/__tests__/providers/opencode/OpenCodeSessionLocator.test.js +0 -94
- package/dist/__tests__/providers/opencode/OpenCodeSessionLocator.test.js.map +0 -1
- package/dist/__tests__/providers/opencode/OpenCodeSessionParser.test.js +0 -147
- package/dist/__tests__/providers/opencode/OpenCodeSessionParser.test.js.map +0 -1
- package/dist/__tests__/providers/pi/PiAdapter.test.js +0 -367
- package/dist/__tests__/providers/pi/PiAdapter.test.js.map +0 -1
- package/dist/__tests__/providers/pi/PiSessionParser.test.js +0 -246
- package/dist/__tests__/providers/pi/PiSessionParser.test.js.map +0 -1
- package/dist/__tests__/providers/pi/PiSessionTracker.test.js +0 -108
- package/dist/__tests__/providers/pi/PiSessionTracker.test.js.map +0 -1
- package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js +0 -76
- package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js.map +0 -1
- package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js.map +0 -1
- package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js +0 -202
- package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js.map +0 -1
- package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js +0 -119
- package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js.map +0 -1
- package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js +0 -386
- package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js.map +0 -1
- package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js +0 -34
- package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js.map +0 -1
- package/dist/__tests__/readiness/AgentReadiness.test.js +0 -301
- package/dist/__tests__/readiness/AgentReadiness.test.js.map +0 -1
- package/dist/__tests__/utils/ClaudeSessionParser.test.js +0 -314
- package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +0 -1
- package/dist/__tests__/utils/agents.test.js +0 -29
- package/dist/__tests__/utils/agents.test.js.map +0 -1
- package/dist/adapters/AntigravityCliAdapter.d.ts +0 -57
- package/dist/adapters/AntigravityCliAdapter.d.ts.map +0 -1
- package/dist/adapters/AntigravityCliAdapter.js +0 -273
- package/dist/adapters/AntigravityCliAdapter.js.map +0 -1
- package/dist/adapters/KiroAdapter.d.ts +0 -46
- package/dist/adapters/KiroAdapter.d.ts.map +0 -1
- package/dist/adapters/KiroAdapter.js +0 -344
- package/dist/adapters/KiroAdapter.js.map +0 -1
- package/dist/adapters/index.d.ts +0 -12
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js +0 -12
- package/dist/adapters/index.js.map +0 -1
- package/dist/capacity/claude.d.ts +0 -17
- package/dist/capacity/claude.d.ts.map +0 -1
- package/dist/capacity/claude.js +0 -271
- package/dist/capacity/claude.js.map +0 -1
- package/dist/capacity/codex.d.ts +0 -36
- package/dist/capacity/codex.d.ts.map +0 -1
- package/dist/capacity/codex.js +0 -280
- package/dist/capacity/codex.js.map +0 -1
- package/dist/capacity/openai.d.ts +0 -48
- package/dist/capacity/openai.d.ts.map +0 -1
- package/dist/capacity/openai.js +0 -312
- package/dist/capacity/openai.js.map +0 -1
- package/dist/capacity/wham.d.ts +0 -16
- package/dist/capacity/wham.d.ts.map +0 -1
- package/dist/capacity/wham.js +0 -66
- package/dist/capacity/wham.js.map +0 -1
- package/dist/capacity/zai.d.ts +0 -14
- package/dist/capacity/zai.d.ts.map +0 -1
- package/dist/capacity/zai.js +0 -203
- package/dist/capacity/zai.js.map +0 -1
- package/dist/providers/claude/ClaudeAgentMapper.d.ts.map +0 -1
- package/dist/providers/claude/ClaudeAgentMapper.js +0 -42
- package/dist/providers/claude/ClaudeAgentMapper.js.map +0 -1
- package/dist/providers/claude/ClaudeCodeAdapter.d.ts +0 -31
- package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +0 -1
- package/dist/providers/claude/ClaudeCodeAdapter.js +0 -132
- package/dist/providers/claude/ClaudeCodeAdapter.js.map +0 -1
- package/dist/providers/claude/ClaudeSessionLocator.d.ts.map +0 -1
- package/dist/providers/claude/ClaudeSessionLocator.js +0 -260
- package/dist/providers/claude/ClaudeSessionLocator.js.map +0 -1
- package/dist/providers/claude/ClaudeSessionParser.d.ts +0 -114
- package/dist/providers/claude/ClaudeSessionParser.d.ts.map +0 -1
- package/dist/providers/claude/ClaudeSessionParser.js +0 -309
- package/dist/providers/claude/ClaudeSessionParser.js.map +0 -1
- package/dist/providers/claude/durable/ClaudeCliProbe.d.ts.map +0 -1
- package/dist/providers/claude/durable/ClaudeCliProbe.js.map +0 -1
- package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts.map +0 -1
- package/dist/providers/claude/durable/ClaudePrintAgentService.js.map +0 -1
- package/dist/providers/claude/durable/ClaudePrintRunner.d.ts.map +0 -1
- package/dist/providers/claude/durable/ClaudePrintRunner.js.map +0 -1
- package/dist/providers/claude/durable/ClaudeStreamParser.d.ts.map +0 -1
- package/dist/providers/claude/durable/ClaudeStreamParser.js.map +0 -1
- package/dist/providers/codex/CodexAdapter.d.ts +0 -28
- package/dist/providers/codex/CodexAdapter.d.ts.map +0 -1
- package/dist/providers/codex/CodexAdapter.js +0 -170
- package/dist/providers/codex/CodexAdapter.js.map +0 -1
- package/dist/providers/codex/CodexAgentMapper.d.ts.map +0 -1
- package/dist/providers/codex/CodexAgentMapper.js +0 -35
- 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.d.ts.map +0 -1
- package/dist/providers/codex/CodexSessionMapping.js +0 -68
- 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 +0 -262
- package/dist/providers/codex/CodexSessionParser.js.map +0 -1
- package/dist/providers/codex/durable/CodexCliProbe.d.ts.map +0 -1
- package/dist/providers/codex/durable/CodexCliProbe.js.map +0 -1
- package/dist/providers/codex/durable/CodexPrintAgentService.d.ts.map +0 -1
- package/dist/providers/codex/durable/CodexPrintAgentService.js.map +0 -1
- package/dist/providers/codex/durable/CodexPrintRunner.d.ts.map +0 -1
- package/dist/providers/codex/durable/CodexPrintRunner.js.map +0 -1
- package/dist/providers/codex/durable/CodexStreamParser.d.ts.map +0 -1
- package/dist/providers/codex/durable/CodexStreamParser.js.map +0 -1
- package/dist/providers/copilot/CopilotAdapter.d.ts +0 -35
- package/dist/providers/copilot/CopilotAdapter.d.ts.map +0 -1
- package/dist/providers/copilot/CopilotAdapter.js +0 -123
- package/dist/providers/copilot/CopilotAdapter.js.map +0 -1
- package/dist/providers/copilot/CopilotAgentMapper.d.ts.map +0 -1
- package/dist/providers/copilot/CopilotAgentMapper.js +0 -37
- 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.d.ts.map +0 -1
- package/dist/providers/gemini/GeminiAgentMapper.js +0 -37
- package/dist/providers/gemini/GeminiAgentMapper.js.map +0 -1
- package/dist/providers/gemini/GeminiCliAdapter.d.ts +0 -53
- package/dist/providers/gemini/GeminiCliAdapter.d.ts.map +0 -1
- package/dist/providers/gemini/GeminiCliAdapter.js +0 -197
- 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 +0 -94
- 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.d.ts.map +0 -1
- package/dist/providers/grok/GrokAgentMapper.js +0 -36
- package/dist/providers/grok/GrokAgentMapper.js.map +0 -1
- package/dist/providers/grok/GrokCliAdapter.d.ts +0 -36
- package/dist/providers/grok/GrokCliAdapter.d.ts.map +0 -1
- package/dist/providers/grok/GrokCliAdapter.js +0 -98
- package/dist/providers/grok/GrokCliAdapter.js.map +0 -1
- package/dist/providers/grok/GrokSessionLocator.d.ts.map +0 -1
- package/dist/providers/grok/GrokSessionLocator.js +0 -140
- 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 +0 -31
- package/dist/providers/opencode/OpenCodeAdapter.d.ts.map +0 -1
- package/dist/providers/opencode/OpenCodeAdapter.js +0 -89
- package/dist/providers/opencode/OpenCodeAdapter.js.map +0 -1
- package/dist/providers/opencode/OpenCodeAgentMapper.d.ts.map +0 -1
- package/dist/providers/opencode/OpenCodeAgentMapper.js +0 -50
- package/dist/providers/opencode/OpenCodeAgentMapper.js.map +0 -1
- package/dist/providers/opencode/OpenCodeSessionLocator.d.ts.map +0 -1
- package/dist/providers/opencode/OpenCodeSessionLocator.js +0 -118
- package/dist/providers/opencode/OpenCodeSessionLocator.js.map +0 -1
- package/dist/providers/opencode/OpenCodeSessionParser.d.ts +0 -18
- package/dist/providers/opencode/OpenCodeSessionParser.d.ts.map +0 -1
- package/dist/providers/opencode/OpenCodeSessionParser.js +0 -104
- package/dist/providers/opencode/OpenCodeSessionParser.js.map +0 -1
- package/dist/providers/pi/PiAdapter.d.ts +0 -29
- package/dist/providers/pi/PiAdapter.d.ts.map +0 -1
- package/dist/providers/pi/PiAdapter.js +0 -163
- package/dist/providers/pi/PiAdapter.js.map +0 -1
- package/dist/providers/pi/PiAgentMapper.d.ts.map +0 -1
- package/dist/providers/pi/PiAgentMapper.js +0 -37
- 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.d.ts.map +0 -1
- package/dist/providers/pi/PiSessionTracker.js +0 -69
- package/dist/providers/pi/PiSessionTracker.js.map +0 -1
- package/dist/providers/pi/durable/PiCliProbe.d.ts.map +0 -1
- package/dist/providers/pi/durable/PiCliProbe.js.map +0 -1
- package/dist/providers/pi/durable/PiPrintAgentService.d.ts.map +0 -1
- package/dist/providers/pi/durable/PiPrintAgentService.js.map +0 -1
- package/dist/providers/pi/durable/PiPrintProtocol.d.ts.map +0 -1
- package/dist/providers/pi/durable/PiPrintProtocol.js.map +0 -1
- package/dist/providers/pi/durable/PiPrintRunner.d.ts.map +0 -1
- package/dist/providers/pi/durable/PiPrintRunner.js.map +0 -1
- package/dist/providers/pi/durable/PiStreamParser.d.ts.map +0 -1
- package/dist/providers/pi/durable/PiStreamParser.js.map +0 -1
- package/dist/readiness/AgentReadiness.d.ts +0 -67
- package/dist/readiness/AgentReadiness.d.ts.map +0 -1
- package/dist/readiness/AgentReadiness.js +0 -614
- package/dist/readiness/AgentReadiness.js.map +0 -1
- package/dist/terminal/TmuxManager.d.ts +0 -28
- package/dist/terminal/TmuxManager.d.ts.map +0 -1
- package/dist/terminal/TmuxManager.js +0 -135
- package/dist/terminal/TmuxManager.js.map +0 -1
- package/dist/terminal/index.d.ts +0 -5
- package/dist/terminal/index.d.ts.map +0 -1
- package/dist/terminal/index.js +0 -5
- package/dist/terminal/index.js.map +0 -1
- package/dist/utils/agents.d.ts +0 -15
- package/dist/utils/agents.d.ts.map +0 -1
- package/dist/utils/agents.js +0 -82
- package/dist/utils/agents.js.map +0 -1
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -6
- package/dist/utils/index.js.map +0 -1
- package/src/__tests__/adapters/AntigravityCliAdapter.test.ts +0 -324
- package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +0 -1763
- package/src/__tests__/adapters/CodexAdapter.test.ts +0 -387
- package/src/__tests__/adapters/KiroAdapter.test.ts +0 -534
- package/src/__tests__/durable/CodexCliProbe.test.ts +0 -85
- package/src/__tests__/durable/CodexDurableAgentRepository.test.ts +0 -65
- package/src/__tests__/durable/CodexPrintAgent.integration.test.ts +0 -104
- package/src/__tests__/durable/CodexPrintAgentService.test.ts +0 -217
- package/src/__tests__/durable/CodexPrintRunner.test.ts +0 -309
- package/src/__tests__/fixtures/fake-claude.cjs +0 -31
- package/src/__tests__/fixtures/fake-codex.cjs +0 -56
- package/src/__tests__/print/ClaudeCliProbe.test.ts +0 -34
- package/src/__tests__/print/ClaudePrintAgent.integration.test.ts +0 -61
- package/src/__tests__/print/ClaudePrintAgentService.test.ts +0 -129
- package/src/__tests__/print/ClaudePrintRunner.test.ts +0 -152
- package/src/__tests__/providers/claude/ClaudeAgentMapper.test.ts +0 -84
- package/src/__tests__/providers/claude/ClaudeSessionLocator.test.ts +0 -434
- package/src/__tests__/providers/codex/CodexSessionLocator.test.ts +0 -182
- package/src/__tests__/providers/codex/CodexSessionMapping.test.ts +0 -63
- package/src/__tests__/providers/codex/CodexSessionParser.test.ts +0 -192
- package/src/__tests__/providers/copilot/CopilotAdapter.test.ts +0 -614
- package/src/__tests__/providers/gemini/GeminiCliAdapter.test.ts +0 -1320
- package/src/__tests__/providers/grok/GrokAgentMapper.test.ts +0 -57
- package/src/__tests__/providers/grok/GrokCliAdapter.test.ts +0 -376
- package/src/__tests__/providers/grok/GrokSessionLocator.test.ts +0 -106
- package/src/__tests__/providers/opencode/OpenCodeAdapter.test.ts +0 -215
- package/src/__tests__/providers/opencode/OpenCodeAgentMapper.test.ts +0 -83
- package/src/__tests__/providers/opencode/OpenCodeSessionLocator.test.ts +0 -84
- package/src/__tests__/providers/opencode/OpenCodeSessionParser.test.ts +0 -148
- package/src/__tests__/providers/pi/PiAdapter.test.ts +0 -325
- package/src/__tests__/providers/pi/PiSessionParser.test.ts +0 -190
- package/src/__tests__/providers/pi/PiSessionTracker.test.ts +0 -79
- package/src/__tests__/providers/pi/durable/PiCliProbe.test.ts +0 -54
- package/src/__tests__/providers/pi/durable/PiPrintAgentService.test.ts +0 -141
- package/src/__tests__/providers/pi/durable/PiPrintProtocol.test.ts +0 -71
- package/src/__tests__/providers/pi/durable/PiPrintRunner.test.ts +0 -253
- package/src/__tests__/providers/pi/durable/PiStreamParser.test.ts +0 -26
- package/src/__tests__/readiness/AgentReadiness.test.ts +0 -242
- package/src/__tests__/utils/ClaudeSessionParser.test.ts +0 -300
- package/src/__tests__/utils/agents.test.ts +0 -31
- package/src/adapters/AntigravityCliAdapter.ts +0 -356
- package/src/adapters/KiroAdapter.ts +0 -456
- package/src/adapters/index.ts +0 -17
- package/src/capacity/claude.ts +0 -313
- package/src/capacity/codex.ts +0 -332
- package/src/capacity/openai.ts +0 -361
- package/src/capacity/wham.ts +0 -84
- package/src/capacity/zai.ts +0 -237
- package/src/providers/claude/ClaudeAgentMapper.ts +0 -63
- package/src/providers/claude/ClaudeCodeAdapter.ts +0 -173
- package/src/providers/claude/ClaudeSessionLocator.ts +0 -358
- package/src/providers/claude/ClaudeSessionParser.ts +0 -432
- package/src/providers/codex/CodexAdapter.ts +0 -213
- package/src/providers/codex/CodexAgentMapper.ts +0 -35
- package/src/providers/codex/CodexSessionLocator.ts +0 -279
- package/src/providers/codex/CodexSessionMapping.ts +0 -89
- package/src/providers/codex/CodexSessionParser.ts +0 -385
- package/src/providers/copilot/CopilotAdapter.ts +0 -161
- package/src/providers/copilot/CopilotAgentMapper.ts +0 -36
- package/src/providers/copilot/CopilotSessionLocator.ts +0 -63
- package/src/providers/copilot/CopilotSessionParser.ts +0 -289
- package/src/providers/gemini/GeminiAgentMapper.ts +0 -36
- package/src/providers/gemini/GeminiCliAdapter.ts +0 -274
- package/src/providers/gemini/GeminiSessionLocator.ts +0 -183
- package/src/providers/gemini/GeminiSessionParser.ts +0 -271
- package/src/providers/grok/GrokAgentMapper.ts +0 -41
- package/src/providers/grok/GrokCliAdapter.ts +0 -125
- package/src/providers/grok/GrokSessionLocator.ts +0 -179
- package/src/providers/grok/GrokSessionParser.ts +0 -166
- package/src/providers/opencode/OpenCodeAdapter.ts +0 -116
- package/src/providers/opencode/OpenCodeAgentMapper.ts +0 -61
- package/src/providers/opencode/OpenCodeSessionLocator.ts +0 -151
- package/src/providers/opencode/OpenCodeSessionParser.ts +0 -145
- package/src/providers/pi/PiAdapter.ts +0 -195
- package/src/providers/pi/PiAgentMapper.ts +0 -36
- package/src/providers/pi/PiSessionLocator.ts +0 -110
- package/src/providers/pi/PiSessionParser.ts +0 -284
- package/src/providers/pi/PiSessionTracker.ts +0 -87
- package/src/readiness/AgentReadiness.ts +0 -730
- package/src/terminal/TmuxManager.ts +0 -123
- package/src/terminal/index.ts +0 -4
- package/src/utils/agents.ts +0 -75
- package/src/utils/index.ts +0 -12
- /package/dist/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.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/PiDurableAgentRepository.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,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental JSONL Summary
|
|
3
|
+
*
|
|
4
|
+
* Keeps a small per-file summary of append-only JSONL transcripts so repeated
|
|
5
|
+
* refreshes only parse bytes that were appended since the previous read.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```ts
|
|
9
|
+
* const summaries = new IncrementalJsonlSummary<MyState>({
|
|
10
|
+
* initial: () => ({ lastType: undefined }),
|
|
11
|
+
* reduce: (state, entry) => ({ ...state, lastType: (entry as any)?.type }),
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* const result = summaries.read(filePath); // { state, size, mtime, skippedBytes } | null
|
|
15
|
+
* summaries.prune(); // once per refresh: evict paths not read since the last prune
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Read rules, keyed by file path:
|
|
19
|
+
* - dev, ino, size and mtimeMs unchanged → cached state, 0 bytes read.
|
|
20
|
+
* - same dev/ino and size grew → read only the bytes after the last complete line.
|
|
21
|
+
* - anything else (first read, shrink, rotation, in-place rewrite) → rebuild.
|
|
22
|
+
*
|
|
23
|
+
* A rebuild of a file larger than `headBytes + tailBytes` (default 1 MiB +
|
|
24
|
+
* 4 MiB) is a bounded cold start rather than a full parse: it folds the
|
|
25
|
+
* complete lines in `[0, headBytes)`, calls `reducer.skip(state)`, then folds
|
|
26
|
+
* the lines that start inside `[size - tailBytes, size)`, including a line
|
|
27
|
+
* that starts exactly at `size - tailBytes` (one extra byte before the window
|
|
28
|
+
* is read to tell). Lines straddling a window edge are dropped. A field whose
|
|
29
|
+
* entries all sit in the skipped middle keeps whatever `skip` leaves; there is
|
|
30
|
+
* never a hidden full scan. The result's `skippedBytes` reports the unread
|
|
31
|
+
* middle, and the cache is seeded at end of file so later appends stay
|
|
32
|
+
* incremental.
|
|
33
|
+
*
|
|
34
|
+
* An unterminated last line is never folded into the committed state. If it
|
|
35
|
+
* already parses as JSON it is applied to the returned state only, and it is
|
|
36
|
+
* re-read (from its start offset) once more bytes arrive.
|
|
37
|
+
*/ import * as fs from "fs";
|
|
38
|
+
export const DEFAULT_HEAD_BYTES = 1024 * 1024;
|
|
39
|
+
export const DEFAULT_TAIL_BYTES = 4 * 1024 * 1024;
|
|
40
|
+
const DEFAULT_CHUNK_SIZE = 1024 * 1024;
|
|
41
|
+
const NEWLINE = 0x0a;
|
|
42
|
+
/** Fold a whole JSONL string with a reducer (one-shot, uncached). */ export function reduceJsonlContent(reducer, content) {
|
|
43
|
+
let state = reducer.initial();
|
|
44
|
+
for (const line of content.split("\n")){
|
|
45
|
+
state = reduceLine(reducer, state, line);
|
|
46
|
+
}
|
|
47
|
+
return state;
|
|
48
|
+
}
|
|
49
|
+
export class IncrementalJsonlSummary {
|
|
50
|
+
reducer;
|
|
51
|
+
entries = new Map();
|
|
52
|
+
chunkSize;
|
|
53
|
+
bounds;
|
|
54
|
+
generation = 0;
|
|
55
|
+
constructor(reducer, options = {}){
|
|
56
|
+
this.reducer = reducer;
|
|
57
|
+
this.chunkSize = options.chunkSize ?? DEFAULT_CHUNK_SIZE;
|
|
58
|
+
this.bounds = options.bounds ?? {
|
|
59
|
+
headBytes: DEFAULT_HEAD_BYTES,
|
|
60
|
+
tailBytes: DEFAULT_TAIL_BYTES
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Number of cached files. */ get size() {
|
|
64
|
+
return this.entries.size;
|
|
65
|
+
}
|
|
66
|
+
/** Return the summary of `filePath`, reading only what changed. Null if unreadable. */ read(filePath) {
|
|
67
|
+
let stat;
|
|
68
|
+
try {
|
|
69
|
+
stat = fs.statSync(filePath);
|
|
70
|
+
} catch {
|
|
71
|
+
this.entries.delete(filePath);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const cached = this.entries.get(filePath);
|
|
75
|
+
const sameFile = cached !== undefined && cached.dev === stat.dev && cached.ino === stat.ino;
|
|
76
|
+
if (sameFile && cached.size === stat.size && cached.mtimeMs === stat.mtimeMs) {
|
|
77
|
+
cached.seen = this.generation;
|
|
78
|
+
return toResult(cached);
|
|
79
|
+
}
|
|
80
|
+
const appended = sameFile && stat.size > cached.size;
|
|
81
|
+
const entry = appended ? {
|
|
82
|
+
...cached
|
|
83
|
+
} : {
|
|
84
|
+
dev: stat.dev,
|
|
85
|
+
ino: stat.ino,
|
|
86
|
+
size: 0,
|
|
87
|
+
mtimeMs: 0,
|
|
88
|
+
mtime: stat.mtime,
|
|
89
|
+
offset: 0,
|
|
90
|
+
discarding: false,
|
|
91
|
+
committed: this.reducer.initial(),
|
|
92
|
+
state: this.reducer.initial(),
|
|
93
|
+
skippedBytes: 0,
|
|
94
|
+
seen: this.generation
|
|
95
|
+
};
|
|
96
|
+
try {
|
|
97
|
+
const fd = fs.openSync(filePath, "r");
|
|
98
|
+
try {
|
|
99
|
+
const bounds = this.bounds;
|
|
100
|
+
if (!appended && bounds && stat.size > bounds.headBytes + bounds.tailBytes) {
|
|
101
|
+
this.readBounded(fd, entry, stat.size, bounds);
|
|
102
|
+
} else {
|
|
103
|
+
this.readRange(fd, entry, stat.size);
|
|
104
|
+
}
|
|
105
|
+
} finally{
|
|
106
|
+
fs.closeSync(fd);
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
this.entries.delete(filePath);
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
entry.mtimeMs = stat.mtimeMs;
|
|
113
|
+
entry.mtime = stat.mtime;
|
|
114
|
+
entry.seen = this.generation;
|
|
115
|
+
this.entries.set(filePath, entry);
|
|
116
|
+
return toResult(entry);
|
|
117
|
+
}
|
|
118
|
+
/** Evict entries not read since the previous `prune()` call. Call once per refresh. */ prune() {
|
|
119
|
+
for (const [filePath, entry] of this.entries){
|
|
120
|
+
if (entry.seen !== this.generation) {
|
|
121
|
+
this.entries.delete(filePath);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
this.generation++;
|
|
125
|
+
}
|
|
126
|
+
/** Cold start: fold the head lines, `skip`, then the lines starting in the tail window. */ readBounded(fd, entry, size, { headBytes, tailBytes }) {
|
|
127
|
+
this.readRange(fd, entry, headBytes);
|
|
128
|
+
const tailStart = size - tailBytes;
|
|
129
|
+
const head = entry.committed;
|
|
130
|
+
entry.committed = this.reducer.skip ? this.reducer.skip(head) : head;
|
|
131
|
+
// Lines are only folded from their first byte, and tailStart may fall
|
|
132
|
+
// mid-line. Discard from one byte earlier (tailStart > headBytes >= 0): if
|
|
133
|
+
// that byte is the newline ending the previous line, discarding stops there
|
|
134
|
+
// and the line starting at tailStart is folded; otherwise the partial line
|
|
135
|
+
// is dropped up to its newline.
|
|
136
|
+
entry.offset = tailStart - 1;
|
|
137
|
+
entry.discarding = true;
|
|
138
|
+
entry.skippedBytes = tailStart - headBytes;
|
|
139
|
+
this.readRange(fd, entry, size);
|
|
140
|
+
}
|
|
141
|
+
/** Fold complete lines in `[entry.offset, end)` into `entry`. */ readRange(fd, entry, end) {
|
|
142
|
+
const chunk = Buffer.allocUnsafe(Math.min(this.chunkSize, Math.max(end - entry.offset, 1)));
|
|
143
|
+
let position = entry.offset;
|
|
144
|
+
let carry;
|
|
145
|
+
let committed = entry.committed;
|
|
146
|
+
let discarding = entry.discarding;
|
|
147
|
+
while(position < end){
|
|
148
|
+
const bytesRead = fs.readSync(fd, chunk, 0, Math.min(chunk.length, end - position), position);
|
|
149
|
+
if (bytesRead === 0) break;
|
|
150
|
+
position += bytesRead;
|
|
151
|
+
let lineStart = 0;
|
|
152
|
+
let newline = chunk.indexOf(NEWLINE, 0);
|
|
153
|
+
while(newline !== -1 && newline < bytesRead){
|
|
154
|
+
if (discarding) {
|
|
155
|
+
discarding = false;
|
|
156
|
+
} else {
|
|
157
|
+
const lineBytes = carry ? Buffer.concat([
|
|
158
|
+
carry,
|
|
159
|
+
chunk.subarray(lineStart, newline)
|
|
160
|
+
]) : chunk.subarray(lineStart, newline);
|
|
161
|
+
committed = reduceLine(this.reducer, committed, lineBytes.toString("utf8"));
|
|
162
|
+
}
|
|
163
|
+
carry = undefined;
|
|
164
|
+
lineStart = newline + 1;
|
|
165
|
+
newline = chunk.indexOf(NEWLINE, lineStart);
|
|
166
|
+
}
|
|
167
|
+
if (lineStart < bytesRead && !discarding) {
|
|
168
|
+
const rest = Buffer.from(chunk.subarray(lineStart, bytesRead));
|
|
169
|
+
carry = carry ? Buffer.concat([
|
|
170
|
+
carry,
|
|
171
|
+
rest
|
|
172
|
+
]) : rest;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
entry.committed = committed;
|
|
176
|
+
entry.discarding = discarding;
|
|
177
|
+
entry.offset = position - (carry?.length ?? 0);
|
|
178
|
+
entry.size = position;
|
|
179
|
+
entry.state = carry ? reduceTentative(this.reducer, committed, carry.toString("utf8")) : committed;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function toResult(entry) {
|
|
183
|
+
return {
|
|
184
|
+
state: entry.state,
|
|
185
|
+
size: entry.size,
|
|
186
|
+
mtime: entry.mtime,
|
|
187
|
+
skippedBytes: entry.skippedBytes
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function reduceLine(reducer, state, line) {
|
|
191
|
+
if (!/\S/.test(line)) return state;
|
|
192
|
+
let entry;
|
|
193
|
+
try {
|
|
194
|
+
entry = JSON.parse(line);
|
|
195
|
+
} catch {
|
|
196
|
+
entry = undefined;
|
|
197
|
+
}
|
|
198
|
+
return reducer.reduce(state, entry);
|
|
199
|
+
}
|
|
200
|
+
/** Apply an unterminated line only if it is already valid JSON (i.e. fully written). */ function reduceTentative(reducer, state, line) {
|
|
201
|
+
if (!/\S/.test(line)) return state;
|
|
202
|
+
try {
|
|
203
|
+
return reducer.reduce(state, JSON.parse(line));
|
|
204
|
+
} catch {
|
|
205
|
+
return state;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
//# sourceMappingURL=IncrementalJsonlSummary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/IncrementalJsonlSummary.ts"],"sourcesContent":["/**\n * Incremental JSONL Summary\n *\n * Keeps a small per-file summary of append-only JSONL transcripts so repeated\n * refreshes only parse bytes that were appended since the previous read.\n *\n * Usage:\n * ```ts\n * const summaries = new IncrementalJsonlSummary<MyState>({\n * initial: () => ({ lastType: undefined }),\n * reduce: (state, entry) => ({ ...state, lastType: (entry as any)?.type }),\n * });\n *\n * const result = summaries.read(filePath); // { state, size, mtime, skippedBytes } | null\n * summaries.prune(); // once per refresh: evict paths not read since the last prune\n * ```\n *\n * Read rules, keyed by file path:\n * - dev, ino, size and mtimeMs unchanged → cached state, 0 bytes read.\n * - same dev/ino and size grew → read only the bytes after the last complete line.\n * - anything else (first read, shrink, rotation, in-place rewrite) → rebuild.\n *\n * A rebuild of a file larger than `headBytes + tailBytes` (default 1 MiB +\n * 4 MiB) is a bounded cold start rather than a full parse: it folds the\n * complete lines in `[0, headBytes)`, calls `reducer.skip(state)`, then folds\n * the lines that start inside `[size - tailBytes, size)`, including a line\n * that starts exactly at `size - tailBytes` (one extra byte before the window\n * is read to tell). Lines straddling a window edge are dropped. A field whose\n * entries all sit in the skipped middle keeps whatever `skip` leaves; there is\n * never a hidden full scan. The result's `skippedBytes` reports the unread\n * middle, and the cache is seeded at end of file so later appends stay\n * incremental.\n *\n * An unterminated last line is never folded into the committed state. If it\n * already parses as JSON it is applied to the returned state only, and it is\n * re-read (from its start offset) once more bytes arrive.\n */\n\nimport * as fs from \"fs\";\n\n/**\n * Pure fold over the entries of a JSONL file.\n *\n * `reduce` receives each non-blank line in file order: the parsed JSON value,\n * or `undefined` when the line is not valid JSON. It must return a new state\n * rather than mutate `state`, and the state should stay O(1) in file size\n * (no entry arrays or raw file contents).\n *\n * `skip` is called once when a bounded cold start skips the middle of a file,\n * between the head lines and the tail lines. It returns the state the tail\n * lines fold onto: keep what the head established (e.g. the first entry) and\n * reset fields that track the latest entry, so those come only from lines\n * actually read. Without `skip`, tail lines fold straight onto the head state.\n */\nexport interface JsonlSummaryReducer<S> {\n initial(): S;\n reduce(state: S, entry: unknown): S;\n skip?(state: S): S;\n}\n\nexport interface JsonlSummaryResult<S> {\n state: S;\n /** File size in bytes when the state was computed. */\n size: number;\n /** File mtime (`fs.Stats.mtime`) when the state was computed. */\n mtime: Date;\n /** Bytes the bounded cold start did not read; 0 when the whole file was parsed. */\n skippedBytes: number;\n}\n\nexport interface JsonlSummaryBounds {\n /** Bytes scanned from the start of the file on a cold start. */\n headBytes: number;\n /** Bytes scanned at the end of the file on a cold start. */\n tailBytes: number;\n}\n\nexport interface IncrementalJsonlSummaryOptions {\n /** Bytes read per `fs.readSync` call. */\n chunkSize?: number;\n /** Cold-start scan bounds; `false` parses rebuilt files from byte 0. */\n bounds?: JsonlSummaryBounds | false;\n}\n\ninterface CacheEntry<S> {\n dev: number;\n ino: number;\n size: number;\n mtimeMs: number;\n mtime: Date;\n /** Byte offset just past the last newline folded into `committed`. */\n offset: number;\n /** `offset` is mid-line: drop bytes up to and including the next newline. */\n discarding: boolean;\n /** State after every newline-terminated line. */\n committed: S;\n /** `committed` plus the unterminated last line, when it parses as JSON. */\n state: S;\n /** Bytes the cold start did not read. */\n skippedBytes: number;\n /** Prune generation in which this entry was last read. */\n seen: number;\n}\n\nexport const DEFAULT_HEAD_BYTES = 1024 * 1024;\nexport const DEFAULT_TAIL_BYTES = 4 * 1024 * 1024;\nconst DEFAULT_CHUNK_SIZE = 1024 * 1024;\nconst NEWLINE = 0x0a;\n\n/** Fold a whole JSONL string with a reducer (one-shot, uncached). */\nexport function reduceJsonlContent<S>(reducer: JsonlSummaryReducer<S>, content: string): S {\n let state = reducer.initial();\n for (const line of content.split(\"\\n\")) {\n state = reduceLine(reducer, state, line);\n }\n return state;\n}\n\nexport class IncrementalJsonlSummary<S> {\n private readonly entries = new Map<string, CacheEntry<S>>();\n private readonly chunkSize: number;\n private readonly bounds: JsonlSummaryBounds | false;\n private generation = 0;\n\n constructor(\n private readonly reducer: JsonlSummaryReducer<S>,\n options: IncrementalJsonlSummaryOptions = {},\n ) {\n this.chunkSize = options.chunkSize ?? DEFAULT_CHUNK_SIZE;\n this.bounds = options.bounds ?? {\n headBytes: DEFAULT_HEAD_BYTES,\n tailBytes: DEFAULT_TAIL_BYTES,\n };\n }\n\n /** Number of cached files. */\n get size(): number {\n return this.entries.size;\n }\n\n /** Return the summary of `filePath`, reading only what changed. Null if unreadable. */\n read(filePath: string): JsonlSummaryResult<S> | null {\n let stat: fs.Stats;\n try {\n stat = fs.statSync(filePath);\n } catch {\n this.entries.delete(filePath);\n return null;\n }\n\n const cached = this.entries.get(filePath);\n const sameFile = cached !== undefined && cached.dev === stat.dev && cached.ino === stat.ino;\n\n if (sameFile && cached.size === stat.size && cached.mtimeMs === stat.mtimeMs) {\n cached.seen = this.generation;\n return toResult(cached);\n }\n\n const appended = sameFile && stat.size > cached.size;\n const entry: CacheEntry<S> = appended\n ? { ...cached }\n : {\n dev: stat.dev,\n ino: stat.ino,\n size: 0,\n mtimeMs: 0,\n mtime: stat.mtime,\n offset: 0,\n discarding: false,\n committed: this.reducer.initial(),\n state: this.reducer.initial(),\n skippedBytes: 0,\n seen: this.generation,\n };\n\n try {\n const fd = fs.openSync(filePath, \"r\");\n try {\n const bounds = this.bounds;\n if (!appended && bounds && stat.size > bounds.headBytes + bounds.tailBytes) {\n this.readBounded(fd, entry, stat.size, bounds);\n } else {\n this.readRange(fd, entry, stat.size);\n }\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n this.entries.delete(filePath);\n return null;\n }\n\n entry.mtimeMs = stat.mtimeMs;\n entry.mtime = stat.mtime;\n entry.seen = this.generation;\n this.entries.set(filePath, entry);\n return toResult(entry);\n }\n\n /** Evict entries not read since the previous `prune()` call. Call once per refresh. */\n prune(): void {\n for (const [filePath, entry] of this.entries) {\n if (entry.seen !== this.generation) {\n this.entries.delete(filePath);\n }\n }\n this.generation++;\n }\n\n /** Cold start: fold the head lines, `skip`, then the lines starting in the tail window. */\n private readBounded(\n fd: number,\n entry: CacheEntry<S>,\n size: number,\n { headBytes, tailBytes }: JsonlSummaryBounds,\n ): void {\n this.readRange(fd, entry, headBytes);\n\n const tailStart = size - tailBytes;\n const head = entry.committed;\n entry.committed = this.reducer.skip ? this.reducer.skip(head) : head;\n // Lines are only folded from their first byte, and tailStart may fall\n // mid-line. Discard from one byte earlier (tailStart > headBytes >= 0): if\n // that byte is the newline ending the previous line, discarding stops there\n // and the line starting at tailStart is folded; otherwise the partial line\n // is dropped up to its newline.\n entry.offset = tailStart - 1;\n entry.discarding = true;\n entry.skippedBytes = tailStart - headBytes;\n this.readRange(fd, entry, size);\n }\n\n /** Fold complete lines in `[entry.offset, end)` into `entry`. */\n private readRange(fd: number, entry: CacheEntry<S>, end: number): void {\n const chunk = Buffer.allocUnsafe(Math.min(this.chunkSize, Math.max(end - entry.offset, 1)));\n let position = entry.offset;\n let carry: Buffer | undefined;\n let committed = entry.committed;\n let discarding = entry.discarding;\n\n while (position < end) {\n const bytesRead = fs.readSync(fd, chunk, 0, Math.min(chunk.length, end - position), position);\n if (bytesRead === 0) break;\n position += bytesRead;\n\n let lineStart = 0;\n let newline = chunk.indexOf(NEWLINE, 0);\n while (newline !== -1 && newline < bytesRead) {\n if (discarding) {\n discarding = false;\n } else {\n const lineBytes = carry\n ? Buffer.concat([carry, chunk.subarray(lineStart, newline)])\n : chunk.subarray(lineStart, newline);\n committed = reduceLine(this.reducer, committed, lineBytes.toString(\"utf8\"));\n }\n carry = undefined;\n lineStart = newline + 1;\n newline = chunk.indexOf(NEWLINE, lineStart);\n }\n\n if (lineStart < bytesRead && !discarding) {\n const rest = Buffer.from(chunk.subarray(lineStart, bytesRead));\n carry = carry ? Buffer.concat([carry, rest]) : rest;\n }\n }\n\n entry.committed = committed;\n entry.discarding = discarding;\n entry.offset = position - (carry?.length ?? 0);\n entry.size = position;\n entry.state = carry\n ? reduceTentative(this.reducer, committed, carry.toString(\"utf8\"))\n : committed;\n }\n}\n\nfunction toResult<S>(entry: CacheEntry<S>): JsonlSummaryResult<S> {\n return {\n state: entry.state,\n size: entry.size,\n mtime: entry.mtime,\n skippedBytes: entry.skippedBytes,\n };\n}\n\nfunction reduceLine<S>(reducer: JsonlSummaryReducer<S>, state: S, line: string): S {\n if (!/\\S/.test(line)) return state;\n let entry: unknown;\n try {\n entry = JSON.parse(line);\n } catch {\n entry = undefined;\n }\n return reducer.reduce(state, entry);\n}\n\n/** Apply an unterminated line only if it is already valid JSON (i.e. fully written). */\nfunction reduceTentative<S>(reducer: JsonlSummaryReducer<S>, state: S, line: string): S {\n if (!/\\S/.test(line)) return state;\n try {\n return reducer.reduce(state, JSON.parse(line));\n } catch {\n return state;\n }\n}\n"],"names":["fs","DEFAULT_HEAD_BYTES","DEFAULT_TAIL_BYTES","DEFAULT_CHUNK_SIZE","NEWLINE","reduceJsonlContent","reducer","content","state","initial","line","split","reduceLine","IncrementalJsonlSummary","entries","Map","chunkSize","bounds","generation","options","headBytes","tailBytes","size","read","filePath","stat","statSync","delete","cached","get","sameFile","undefined","dev","ino","mtimeMs","seen","toResult","appended","entry","mtime","offset","discarding","committed","skippedBytes","fd","openSync","readBounded","readRange","closeSync","set","prune","tailStart","head","skip","end","chunk","Buffer","allocUnsafe","Math","min","max","position","carry","bytesRead","readSync","length","lineStart","newline","indexOf","lineBytes","concat","subarray","toString","rest","from","reduceTentative","test","JSON","parse","reduce"],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tail reader for append-only JSONL transcripts.
|
|
3
|
+
*
|
|
4
|
+
* Reading the last N conversation messages from a large transcript should not
|
|
5
|
+
* require reading (and JSON-parsing) the whole file. This reader:
|
|
6
|
+
*
|
|
7
|
+
* 1. On the first call for a file, reads backward from the end in fixed-size
|
|
8
|
+
* chunks until enough messages are collected (or the start is reached).
|
|
9
|
+
* 2. Remembers `{dev, ino, offset}` plus a small window of parsed items, and
|
|
10
|
+
* on later calls parses only bytes appended since `offset`.
|
|
11
|
+
* 3. Resets (re-reads from the end) when the file is truncated or replaced by
|
|
12
|
+
* a different inode.
|
|
13
|
+
*
|
|
14
|
+
* Each adapter supplies a {@link JsonlTailSource}: `parseLine` maps one raw
|
|
15
|
+
* line to a candidate item (or null) and the optional `finalize` turns a
|
|
16
|
+
* contiguous window of items into messages. `finalize` exists for formats
|
|
17
|
+
* where one line's visibility depends on other lines (e.g. Codex drops an
|
|
18
|
+
* `event_msg` mirrored by a `response_item`); line-independent formats can
|
|
19
|
+
* omit it and return a {@link ConversationMessage} directly from `parseLine`.
|
|
20
|
+
*/
|
|
21
|
+
import type { ConversationMessage } from "../adapters/AgentAdapter.js";
|
|
22
|
+
/**
|
|
23
|
+
* Normalize a `tail` option: a positive integer, or undefined for "full
|
|
24
|
+
* conversation" (the pre-existing behaviour).
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizeTail(tail: number | undefined): number | undefined;
|
|
27
|
+
/** Keep the last `tail` messages of an already fully-parsed conversation. */
|
|
28
|
+
export declare function sliceTail<T>(messages: T[], tail: number | undefined): T[];
|
|
29
|
+
export declare const DEFAULT_TAIL_CHUNK_SIZE: number;
|
|
30
|
+
export interface JsonlTailSource<Item> {
|
|
31
|
+
/** Map one raw JSONL line (no trailing newline) to an item, or null to skip it. */
|
|
32
|
+
parseLine(line: string): Item | null;
|
|
33
|
+
/**
|
|
34
|
+
* Convert a contiguous window of items (oldest first) into messages. Must
|
|
35
|
+
* behave like the adapter's full parse restricted to that window. Defaults
|
|
36
|
+
* to treating every item as a {@link ConversationMessage}.
|
|
37
|
+
*/
|
|
38
|
+
finalize?(items: Item[]): ConversationMessage[];
|
|
39
|
+
}
|
|
40
|
+
export interface JsonlTailReaderOptions {
|
|
41
|
+
/** Bytes read per backward step. Defaults to 64 KiB. */
|
|
42
|
+
chunkSize?: number;
|
|
43
|
+
/** Number of (file, variant, tail) windows kept in the LRU cache. */
|
|
44
|
+
maxFiles?: number;
|
|
45
|
+
}
|
|
46
|
+
export declare class JsonlTailReader {
|
|
47
|
+
private readonly chunkSize;
|
|
48
|
+
private readonly maxFiles;
|
|
49
|
+
private readonly cache;
|
|
50
|
+
constructor(options?: JsonlTailReaderOptions);
|
|
51
|
+
/**
|
|
52
|
+
* Return the last `tail` messages of `filePath`.
|
|
53
|
+
*
|
|
54
|
+
* @param variant Cache discriminator for sources whose output differs by
|
|
55
|
+
* option (e.g. verbose vs. non-verbose).
|
|
56
|
+
* @param overscan Extra messages collected beyond `tail` before trimming,
|
|
57
|
+
* for sources whose `finalize` looks at neighbouring lines.
|
|
58
|
+
*/
|
|
59
|
+
read<Item>(filePath: string, tail: number, source: JsonlTailSource<Item>, variant?: string, overscan?: number): ConversationMessage[];
|
|
60
|
+
/** Forget all cached windows. */
|
|
61
|
+
clear(): void;
|
|
62
|
+
private readBackward;
|
|
63
|
+
/**
|
|
64
|
+
* Parse bytes appended since the cached offset. Returns null when the
|
|
65
|
+
* bytes before the offset no longer match (file rewritten in place).
|
|
66
|
+
*/
|
|
67
|
+
private readAppended;
|
|
68
|
+
private parse;
|
|
69
|
+
private countMessages;
|
|
70
|
+
private finish;
|
|
71
|
+
private touch;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=jsonlTail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonlTail.d.ts","sourceRoot":"","sources":["../../src/utils/jsonlTail.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,CAAC,EAAE,CAGzE;AAED,eAAO,MAAM,uBAAuB,QAAY,CAAC;AAKjD,MAAM,WAAW,eAAe,CAAC,IAAI;IACnC,mFAAmF;IACnF,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,mBAAmB,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,sBAAsB;IACrC,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAoBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;gBAE1C,OAAO,GAAE,sBAA2B;IAKhD;;;;;;;OAOG;IACH,IAAI,CAAC,IAAI,EACP,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,CAAC,IAAI,CAAC,EAC7B,OAAO,SAAK,EACZ,QAAQ,SAAI,GACX,mBAAmB,EAAE;IAuDxB,iCAAiC;IACjC,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,YAAY;IAkEpB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAoDpB,OAAO,CAAC,KAAK;IAMb,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,KAAK;CASd"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tail reader for append-only JSONL transcripts.
|
|
3
|
+
*
|
|
4
|
+
* Reading the last N conversation messages from a large transcript should not
|
|
5
|
+
* require reading (and JSON-parsing) the whole file. This reader:
|
|
6
|
+
*
|
|
7
|
+
* 1. On the first call for a file, reads backward from the end in fixed-size
|
|
8
|
+
* chunks until enough messages are collected (or the start is reached).
|
|
9
|
+
* 2. Remembers `{dev, ino, offset}` plus a small window of parsed items, and
|
|
10
|
+
* on later calls parses only bytes appended since `offset`.
|
|
11
|
+
* 3. Resets (re-reads from the end) when the file is truncated or replaced by
|
|
12
|
+
* a different inode.
|
|
13
|
+
*
|
|
14
|
+
* Each adapter supplies a {@link JsonlTailSource}: `parseLine` maps one raw
|
|
15
|
+
* line to a candidate item (or null) and the optional `finalize` turns a
|
|
16
|
+
* contiguous window of items into messages. `finalize` exists for formats
|
|
17
|
+
* where one line's visibility depends on other lines (e.g. Codex drops an
|
|
18
|
+
* `event_msg` mirrored by a `response_item`); line-independent formats can
|
|
19
|
+
* omit it and return a {@link ConversationMessage} directly from `parseLine`.
|
|
20
|
+
*/ import * as fs from "fs";
|
|
21
|
+
/**
|
|
22
|
+
* Normalize a `tail` option: a positive integer, or undefined for "full
|
|
23
|
+
* conversation" (the pre-existing behaviour).
|
|
24
|
+
*/ export function normalizeTail(tail) {
|
|
25
|
+
if (tail === undefined || !Number.isFinite(tail)) return undefined;
|
|
26
|
+
const n = Math.floor(tail);
|
|
27
|
+
return n > 0 ? n : undefined;
|
|
28
|
+
}
|
|
29
|
+
/** Keep the last `tail` messages of an already fully-parsed conversation. */ export function sliceTail(messages, tail) {
|
|
30
|
+
const n = normalizeTail(tail);
|
|
31
|
+
return n !== undefined && messages.length > n ? messages.slice(-n) : messages;
|
|
32
|
+
}
|
|
33
|
+
export const DEFAULT_TAIL_CHUNK_SIZE = 64 * 1024;
|
|
34
|
+
const DEFAULT_MAX_FILES = 16;
|
|
35
|
+
const NEWLINE = 0x0a;
|
|
36
|
+
const ANCHOR_BYTES = 32;
|
|
37
|
+
export class JsonlTailReader {
|
|
38
|
+
chunkSize;
|
|
39
|
+
maxFiles;
|
|
40
|
+
cache = new Map();
|
|
41
|
+
constructor(options = {}){
|
|
42
|
+
this.chunkSize = Math.max(1, options.chunkSize ?? DEFAULT_TAIL_CHUNK_SIZE);
|
|
43
|
+
this.maxFiles = Math.max(1, options.maxFiles ?? DEFAULT_MAX_FILES);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Return the last `tail` messages of `filePath`.
|
|
47
|
+
*
|
|
48
|
+
* @param variant Cache discriminator for sources whose output differs by
|
|
49
|
+
* option (e.g. verbose vs. non-verbose).
|
|
50
|
+
* @param overscan Extra messages collected beyond `tail` before trimming,
|
|
51
|
+
* for sources whose `finalize` looks at neighbouring lines.
|
|
52
|
+
*/ read(filePath, tail, source, variant = "", overscan = 0) {
|
|
53
|
+
const key = `${variant}\0${tail}\0${filePath}`;
|
|
54
|
+
const threshold = tail + Math.max(0, overscan);
|
|
55
|
+
let stat;
|
|
56
|
+
try {
|
|
57
|
+
stat = fs.statSync(filePath);
|
|
58
|
+
} catch {
|
|
59
|
+
this.cache.delete(key);
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
const cached = this.cache.get(key);
|
|
63
|
+
if (cached && cached.dev === stat.dev && cached.ino === stat.ino && cached.size === stat.size && cached.mtimeMs === stat.mtimeMs) {
|
|
64
|
+
this.touch(key, cached);
|
|
65
|
+
return cached.result.slice();
|
|
66
|
+
}
|
|
67
|
+
let fd;
|
|
68
|
+
try {
|
|
69
|
+
fd = fs.openSync(filePath, "r");
|
|
70
|
+
} catch {
|
|
71
|
+
this.cache.delete(key);
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const current = fs.fstatSync(fd);
|
|
76
|
+
const canAppend = cached !== undefined && cached.dev === current.dev && cached.ino === current.ino && current.size >= cached.offset && // A very large append is cheaper to re-read from the end.
|
|
77
|
+
current.size - cached.offset <= Math.max(this.chunkSize * 16, 1024 * 1024);
|
|
78
|
+
const state = canAppend && this.readAppended(fd, current, cached, tail, threshold, source) || this.readBackward(fd, current, tail, threshold, source);
|
|
79
|
+
this.touch(key, state);
|
|
80
|
+
return state.result.slice();
|
|
81
|
+
} catch {
|
|
82
|
+
this.cache.delete(key);
|
|
83
|
+
return [];
|
|
84
|
+
} finally{
|
|
85
|
+
fs.closeSync(fd);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Forget all cached windows. */ clear() {
|
|
89
|
+
this.cache.clear();
|
|
90
|
+
}
|
|
91
|
+
readBackward(fd, stat, tail, threshold, source) {
|
|
92
|
+
const reversed = [];
|
|
93
|
+
let partial = null;
|
|
94
|
+
let offset = 0;
|
|
95
|
+
let sawNewline = false;
|
|
96
|
+
// Pieces of the line currently being assembled, in file order.
|
|
97
|
+
let pending = [];
|
|
98
|
+
let pos = stat.size;
|
|
99
|
+
const takeLine = (piece)=>{
|
|
100
|
+
const lineBuf = pending.length === 0 ? piece : Buffer.concat([
|
|
101
|
+
piece,
|
|
102
|
+
...pending
|
|
103
|
+
]);
|
|
104
|
+
pending = [];
|
|
105
|
+
if (!sawNewline) {
|
|
106
|
+
// Bytes after the file's last newline: an unterminated (possibly
|
|
107
|
+
// still being written) line. Parsed tentatively, never cached.
|
|
108
|
+
sawNewline = true;
|
|
109
|
+
partial = this.parse(lineBuf, source);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const item = this.parse(lineBuf, source);
|
|
113
|
+
if (item !== null) reversed.push(item);
|
|
114
|
+
};
|
|
115
|
+
while(pos > 0){
|
|
116
|
+
const len = Math.min(this.chunkSize, pos);
|
|
117
|
+
pos -= len;
|
|
118
|
+
const buf = readExactly(fd, pos, len);
|
|
119
|
+
let end = len;
|
|
120
|
+
let nl = end > 0 ? buf.lastIndexOf(NEWLINE, end - 1) : -1;
|
|
121
|
+
while(nl !== -1){
|
|
122
|
+
if (!sawNewline) offset = pos + nl + 1;
|
|
123
|
+
takeLine(buf.subarray(nl + 1, end));
|
|
124
|
+
end = nl;
|
|
125
|
+
nl = end > 0 ? buf.lastIndexOf(NEWLINE, end - 1) : -1;
|
|
126
|
+
}
|
|
127
|
+
if (end > 0) pending.unshift(buf.subarray(0, end));
|
|
128
|
+
if (this.countMessages(reversed, partial, source, threshold) >= threshold) break;
|
|
129
|
+
}
|
|
130
|
+
if (pos === 0 && pending.length > 0) {
|
|
131
|
+
// The first line of the file (no newline before it).
|
|
132
|
+
const first = pending.shift();
|
|
133
|
+
takeLine(first);
|
|
134
|
+
}
|
|
135
|
+
const items = reversed.reverse();
|
|
136
|
+
return {
|
|
137
|
+
dev: stat.dev,
|
|
138
|
+
ino: stat.ino,
|
|
139
|
+
size: stat.size,
|
|
140
|
+
mtimeMs: stat.mtimeMs,
|
|
141
|
+
offset,
|
|
142
|
+
anchor: readAnchor(fd, offset),
|
|
143
|
+
items,
|
|
144
|
+
result: this.finish(items, partial, source, tail)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Parse bytes appended since the cached offset. Returns null when the
|
|
149
|
+
* bytes before the offset no longer match (file rewritten in place).
|
|
150
|
+
*/ readAppended(fd, stat, cached, tail, threshold, source) {
|
|
151
|
+
let items = cached.items;
|
|
152
|
+
let offset = cached.offset;
|
|
153
|
+
let partial = null;
|
|
154
|
+
const anchorLength = cached.anchor.length;
|
|
155
|
+
const raw = readExactly(fd, cached.offset - anchorLength, stat.size - offset + anchorLength);
|
|
156
|
+
if (!raw.subarray(0, anchorLength).equals(cached.anchor)) return null;
|
|
157
|
+
const buf = raw.subarray(anchorLength);
|
|
158
|
+
let anchor = cached.anchor;
|
|
159
|
+
if (buf.length > 0) {
|
|
160
|
+
const added = [];
|
|
161
|
+
let start = 0;
|
|
162
|
+
let nl = buf.indexOf(NEWLINE, start);
|
|
163
|
+
while(nl !== -1){
|
|
164
|
+
const item = this.parse(buf.subarray(start, nl), source);
|
|
165
|
+
if (item !== null) added.push(item);
|
|
166
|
+
start = nl + 1;
|
|
167
|
+
nl = buf.indexOf(NEWLINE, start);
|
|
168
|
+
}
|
|
169
|
+
offset = cached.offset + start;
|
|
170
|
+
if (start > 0) anchor = tailBytes(raw.subarray(0, anchorLength + start));
|
|
171
|
+
if (start < buf.length) partial = this.parse(buf.subarray(start), source);
|
|
172
|
+
if (added.length > 0) {
|
|
173
|
+
items = items.concat(added);
|
|
174
|
+
// Bound the retained window; keep a generous margin so sources whose
|
|
175
|
+
// finalize() drops items (e.g. de-duplication) still cover `tail`.
|
|
176
|
+
if (items.length > threshold * 4) items = items.slice(-threshold * 2);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
dev: stat.dev,
|
|
181
|
+
ino: stat.ino,
|
|
182
|
+
size: stat.size,
|
|
183
|
+
mtimeMs: stat.mtimeMs,
|
|
184
|
+
offset,
|
|
185
|
+
anchor,
|
|
186
|
+
items,
|
|
187
|
+
result: this.finish(items, partial, source, tail)
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
parse(lineBuf, source) {
|
|
191
|
+
const line = lineBuf.toString("utf-8");
|
|
192
|
+
if (line.trim().length === 0) return null;
|
|
193
|
+
return source.parseLine(line);
|
|
194
|
+
}
|
|
195
|
+
countMessages(reversed, partial, source, threshold) {
|
|
196
|
+
const available = reversed.length + (partial === null ? 0 : 1);
|
|
197
|
+
if (!source.finalize || available < threshold) return available;
|
|
198
|
+
const window = reversed.slice().reverse();
|
|
199
|
+
if (partial !== null) window.push(partial);
|
|
200
|
+
return source.finalize(window).length;
|
|
201
|
+
}
|
|
202
|
+
finish(items, partial, source, tail) {
|
|
203
|
+
const window = partial === null ? items : [
|
|
204
|
+
...items,
|
|
205
|
+
partial
|
|
206
|
+
];
|
|
207
|
+
const messages = source.finalize ? source.finalize(window) : window.slice();
|
|
208
|
+
return messages.length > tail ? messages.slice(-tail) : messages;
|
|
209
|
+
}
|
|
210
|
+
touch(key, state) {
|
|
211
|
+
this.cache.delete(key);
|
|
212
|
+
this.cache.set(key, state);
|
|
213
|
+
while(this.cache.size > this.maxFiles){
|
|
214
|
+
const oldest = this.cache.keys().next().value;
|
|
215
|
+
if (oldest === undefined) break;
|
|
216
|
+
this.cache.delete(oldest);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function readExactly(fd, position, length) {
|
|
221
|
+
const buf = Buffer.allocUnsafe(length);
|
|
222
|
+
let filled = 0;
|
|
223
|
+
while(filled < length){
|
|
224
|
+
const n = fs.readSync(fd, buf, filled, length - filled, position + filled);
|
|
225
|
+
if (n === 0) break;
|
|
226
|
+
filled += n;
|
|
227
|
+
}
|
|
228
|
+
return filled === length ? buf : buf.subarray(0, filled);
|
|
229
|
+
}
|
|
230
|
+
function readAnchor(fd, offset) {
|
|
231
|
+
const start = Math.max(0, offset - ANCHOR_BYTES);
|
|
232
|
+
return Buffer.from(readExactly(fd, start, offset - start));
|
|
233
|
+
}
|
|
234
|
+
function tailBytes(buf) {
|
|
235
|
+
return Buffer.from(buf.subarray(Math.max(0, buf.length - ANCHOR_BYTES)));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
//# sourceMappingURL=jsonlTail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/jsonlTail.ts"],"sourcesContent":["/**\n * Tail reader for append-only JSONL transcripts.\n *\n * Reading the last N conversation messages from a large transcript should not\n * require reading (and JSON-parsing) the whole file. This reader:\n *\n * 1. On the first call for a file, reads backward from the end in fixed-size\n * chunks until enough messages are collected (or the start is reached).\n * 2. Remembers `{dev, ino, offset}` plus a small window of parsed items, and\n * on later calls parses only bytes appended since `offset`.\n * 3. Resets (re-reads from the end) when the file is truncated or replaced by\n * a different inode.\n *\n * Each adapter supplies a {@link JsonlTailSource}: `parseLine` maps one raw\n * line to a candidate item (or null) and the optional `finalize` turns a\n * contiguous window of items into messages. `finalize` exists for formats\n * where one line's visibility depends on other lines (e.g. Codex drops an\n * `event_msg` mirrored by a `response_item`); line-independent formats can\n * omit it and return a {@link ConversationMessage} directly from `parseLine`.\n */\n\nimport * as fs from \"fs\";\nimport type { ConversationMessage } from \"../adapters/AgentAdapter.js\";\n\n/**\n * Normalize a `tail` option: a positive integer, or undefined for \"full\n * conversation\" (the pre-existing behaviour).\n */\nexport function normalizeTail(tail: number | undefined): number | undefined {\n if (tail === undefined || !Number.isFinite(tail)) return undefined;\n const n = Math.floor(tail);\n return n > 0 ? n : undefined;\n}\n\n/** Keep the last `tail` messages of an already fully-parsed conversation. */\nexport function sliceTail<T>(messages: T[], tail: number | undefined): T[] {\n const n = normalizeTail(tail);\n return n !== undefined && messages.length > n ? messages.slice(-n) : messages;\n}\n\nexport const DEFAULT_TAIL_CHUNK_SIZE = 64 * 1024;\nconst DEFAULT_MAX_FILES = 16;\nconst NEWLINE = 0x0a;\nconst ANCHOR_BYTES = 32;\n\nexport interface JsonlTailSource<Item> {\n /** Map one raw JSONL line (no trailing newline) to an item, or null to skip it. */\n parseLine(line: string): Item | null;\n /**\n * Convert a contiguous window of items (oldest first) into messages. Must\n * behave like the adapter's full parse restricted to that window. Defaults\n * to treating every item as a {@link ConversationMessage}.\n */\n finalize?(items: Item[]): ConversationMessage[];\n}\n\nexport interface JsonlTailReaderOptions {\n /** Bytes read per backward step. Defaults to 64 KiB. */\n chunkSize?: number;\n /** Number of (file, variant, tail) windows kept in the LRU cache. */\n maxFiles?: number;\n}\n\ninterface TailState {\n dev: number;\n ino: number;\n size: number;\n mtimeMs: number;\n /** Byte offset just past the last newline consumed; appends are read from here. */\n offset: number;\n /**\n * Up to {@link ANCHOR_BYTES} bytes ending at `offset`. Re-checked before an\n * incremental read so a same-inode truncate-and-regrow is detected.\n */\n anchor: Buffer;\n /** Parsed items from complete (newline-terminated) lines, oldest first. */\n items: unknown[];\n /** Last computed result, returned as-is while the file is unchanged. */\n result: ConversationMessage[];\n}\n\nexport class JsonlTailReader {\n private readonly chunkSize: number;\n private readonly maxFiles: number;\n private readonly cache = new Map<string, TailState>();\n\n constructor(options: JsonlTailReaderOptions = {}) {\n this.chunkSize = Math.max(1, options.chunkSize ?? DEFAULT_TAIL_CHUNK_SIZE);\n this.maxFiles = Math.max(1, options.maxFiles ?? DEFAULT_MAX_FILES);\n }\n\n /**\n * Return the last `tail` messages of `filePath`.\n *\n * @param variant Cache discriminator for sources whose output differs by\n * option (e.g. verbose vs. non-verbose).\n * @param overscan Extra messages collected beyond `tail` before trimming,\n * for sources whose `finalize` looks at neighbouring lines.\n */\n read<Item>(\n filePath: string,\n tail: number,\n source: JsonlTailSource<Item>,\n variant = \"\",\n overscan = 0,\n ): ConversationMessage[] {\n const key = `${variant}\\0${tail}\\0${filePath}`;\n const threshold = tail + Math.max(0, overscan);\n\n let stat: fs.Stats;\n try {\n stat = fs.statSync(filePath);\n } catch {\n this.cache.delete(key);\n return [];\n }\n\n const cached = this.cache.get(key);\n if (\n cached &&\n cached.dev === stat.dev &&\n cached.ino === stat.ino &&\n cached.size === stat.size &&\n cached.mtimeMs === stat.mtimeMs\n ) {\n this.touch(key, cached);\n return cached.result.slice();\n }\n\n let fd: number;\n try {\n fd = fs.openSync(filePath, \"r\");\n } catch {\n this.cache.delete(key);\n return [];\n }\n\n try {\n const current = fs.fstatSync(fd);\n const canAppend =\n cached !== undefined &&\n cached.dev === current.dev &&\n cached.ino === current.ino &&\n current.size >= cached.offset &&\n // A very large append is cheaper to re-read from the end.\n current.size - cached.offset <= Math.max(this.chunkSize * 16, 1024 * 1024);\n\n const state =\n (canAppend && this.readAppended(fd, current, cached, tail, threshold, source)) ||\n this.readBackward(fd, current, tail, threshold, source);\n this.touch(key, state);\n return state.result.slice();\n } catch {\n this.cache.delete(key);\n return [];\n } finally {\n fs.closeSync(fd);\n }\n }\n\n /** Forget all cached windows. */\n clear(): void {\n this.cache.clear();\n }\n\n private readBackward<Item>(\n fd: number,\n stat: fs.Stats,\n tail: number,\n threshold: number,\n source: JsonlTailSource<Item>,\n ): TailState {\n const reversed: Item[] = [];\n let partial: Item | null = null;\n let offset = 0;\n let sawNewline = false;\n // Pieces of the line currently being assembled, in file order.\n let pending: Buffer[] = [];\n let pos = stat.size;\n\n const takeLine = (piece: Buffer): void => {\n const lineBuf = pending.length === 0 ? piece : Buffer.concat([piece, ...pending]);\n pending = [];\n if (!sawNewline) {\n // Bytes after the file's last newline: an unterminated (possibly\n // still being written) line. Parsed tentatively, never cached.\n sawNewline = true;\n partial = this.parse(lineBuf, source);\n return;\n }\n const item = this.parse(lineBuf, source);\n if (item !== null) reversed.push(item);\n };\n\n while (pos > 0) {\n const len = Math.min(this.chunkSize, pos);\n pos -= len;\n const buf = readExactly(fd, pos, len);\n\n let end = len;\n let nl = end > 0 ? buf.lastIndexOf(NEWLINE, end - 1) : -1;\n while (nl !== -1) {\n if (!sawNewline) offset = pos + nl + 1;\n takeLine(buf.subarray(nl + 1, end));\n end = nl;\n nl = end > 0 ? buf.lastIndexOf(NEWLINE, end - 1) : -1;\n }\n if (end > 0) pending.unshift(buf.subarray(0, end));\n\n if (this.countMessages(reversed, partial, source, threshold) >= threshold) break;\n }\n\n if (pos === 0 && pending.length > 0) {\n // The first line of the file (no newline before it).\n const first = pending.shift()!;\n takeLine(first);\n }\n\n const items = reversed.reverse();\n return {\n dev: stat.dev,\n ino: stat.ino,\n size: stat.size,\n mtimeMs: stat.mtimeMs,\n offset,\n anchor: readAnchor(fd, offset),\n items,\n result: this.finish(items, partial, source, tail),\n };\n }\n\n /**\n * Parse bytes appended since the cached offset. Returns null when the\n * bytes before the offset no longer match (file rewritten in place).\n */\n private readAppended<Item>(\n fd: number,\n stat: fs.Stats,\n cached: TailState,\n tail: number,\n threshold: number,\n source: JsonlTailSource<Item>,\n ): TailState | null {\n let items = cached.items as Item[];\n let offset = cached.offset;\n let partial: Item | null = null;\n\n const anchorLength = cached.anchor.length;\n const raw = readExactly(fd, cached.offset - anchorLength, stat.size - offset + anchorLength);\n if (!raw.subarray(0, anchorLength).equals(cached.anchor)) return null;\n const buf = raw.subarray(anchorLength);\n let anchor = cached.anchor;\n\n if (buf.length > 0) {\n const added: Item[] = [];\n let start = 0;\n let nl = buf.indexOf(NEWLINE, start);\n while (nl !== -1) {\n const item = this.parse(buf.subarray(start, nl), source);\n if (item !== null) added.push(item);\n start = nl + 1;\n nl = buf.indexOf(NEWLINE, start);\n }\n offset = cached.offset + start;\n if (start > 0) anchor = tailBytes(raw.subarray(0, anchorLength + start));\n if (start < buf.length) partial = this.parse(buf.subarray(start), source);\n\n if (added.length > 0) {\n items = items.concat(added);\n // Bound the retained window; keep a generous margin so sources whose\n // finalize() drops items (e.g. de-duplication) still cover `tail`.\n if (items.length > threshold * 4) items = items.slice(-threshold * 2);\n }\n }\n\n return {\n dev: stat.dev,\n ino: stat.ino,\n size: stat.size,\n mtimeMs: stat.mtimeMs,\n offset,\n anchor,\n items,\n result: this.finish(items, partial, source, tail),\n };\n }\n\n private parse<Item>(lineBuf: Buffer, source: JsonlTailSource<Item>): Item | null {\n const line = lineBuf.toString(\"utf-8\");\n if (line.trim().length === 0) return null;\n return source.parseLine(line);\n }\n\n private countMessages<Item>(\n reversed: Item[],\n partial: Item | null,\n source: JsonlTailSource<Item>,\n threshold: number,\n ): number {\n const available = reversed.length + (partial === null ? 0 : 1);\n if (!source.finalize || available < threshold) return available;\n const window = reversed.slice().reverse();\n if (partial !== null) window.push(partial);\n return source.finalize(window).length;\n }\n\n private finish<Item>(\n items: Item[],\n partial: Item | null,\n source: JsonlTailSource<Item>,\n tail: number,\n ): ConversationMessage[] {\n const window = partial === null ? items : [...items, partial];\n const messages = source.finalize\n ? source.finalize(window)\n : (window as unknown as ConversationMessage[]).slice();\n return messages.length > tail ? messages.slice(-tail) : messages;\n }\n\n private touch(key: string, state: TailState): void {\n this.cache.delete(key);\n this.cache.set(key, state);\n while (this.cache.size > this.maxFiles) {\n const oldest = this.cache.keys().next().value;\n if (oldest === undefined) break;\n this.cache.delete(oldest);\n }\n }\n}\n\nfunction readExactly(fd: number, position: number, length: number): Buffer {\n const buf = Buffer.allocUnsafe(length);\n let filled = 0;\n while (filled < length) {\n const n = fs.readSync(fd, buf, filled, length - filled, position + filled);\n if (n === 0) break;\n filled += n;\n }\n return filled === length ? buf : buf.subarray(0, filled);\n}\n\nfunction readAnchor(fd: number, offset: number): Buffer {\n const start = Math.max(0, offset - ANCHOR_BYTES);\n return Buffer.from(readExactly(fd, start, offset - start));\n}\n\nfunction tailBytes(buf: Buffer): Buffer {\n return Buffer.from(buf.subarray(Math.max(0, buf.length - ANCHOR_BYTES)));\n}\n"],"names":["fs","normalizeTail","tail","undefined","Number","isFinite","n","Math","floor","sliceTail","messages","length","slice","DEFAULT_TAIL_CHUNK_SIZE","DEFAULT_MAX_FILES","NEWLINE","ANCHOR_BYTES","JsonlTailReader","chunkSize","maxFiles","cache","Map","options","max","read","filePath","source","variant","overscan","key","threshold","stat","statSync","delete","cached","get","dev","ino","size","mtimeMs","touch","result","fd","openSync","current","fstatSync","canAppend","offset","state","readAppended","readBackward","closeSync","clear","reversed","partial","sawNewline","pending","pos","takeLine","piece","lineBuf","Buffer","concat","parse","item","push","len","min","buf","readExactly","end","nl","lastIndexOf","subarray","unshift","countMessages","first","shift","items","reverse","anchor","readAnchor","finish","anchorLength","raw","equals","added","start","indexOf","tailBytes","line","toString","trim","parseLine","available","finalize","window","set","oldest","keys","next","value","position","allocUnsafe","filled","readSync","from"],"mappings":"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"}
|
package/dist/utils/matching.d.ts
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* based on CWD and birth-time proximity to process start time.
|
|
6
6
|
*/
|
|
7
7
|
import type { ProcessInfo } from "../adapters/AgentAdapter.js";
|
|
8
|
+
import { MATCH_TOLERANCE_MS } from "./matchingConstants.js";
|
|
8
9
|
import type { SessionFile } from "./session.js";
|
|
10
|
+
export { MATCH_TOLERANCE_MS };
|
|
9
11
|
/**
|
|
10
12
|
* Result of matching a process to a session file.
|
|
11
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,OAAO,EAAE,WAAW,CAAC;IAErB,+BAA+B;IAC/B,OAAO,EAAE,WAAW,CAAC;IAErB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,WAAW,EAAE,EACxB,QAAQ,EAAE,WAAW,EAAE,GACtB,WAAW,EAAE,CAsCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlE"}
|
package/dist/utils/matching.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Shared 1:1 greedy matching algorithm that pairs running processes with session files
|
|
5
5
|
* based on CWD and birth-time proximity to process start time.
|
|
6
6
|
*/ import * as path from "path";
|
|
7
|
-
|
|
7
|
+
import { MATCH_TOLERANCE_MS } from "./matchingConstants.js";
|
|
8
|
+
export { MATCH_TOLERANCE_MS };
|
|
8
9
|
/**
|
|
9
10
|
* Match processes to session files using 1:1 greedy assignment.
|
|
10
11
|
*
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
if (!session.resolvedCwd) continue;
|
|
27
28
|
if (proc.cwd !== session.resolvedCwd) continue;
|
|
28
29
|
const deltaMs = Math.abs(processStartMs - session.birthtimeMs);
|
|
29
|
-
if (deltaMs >
|
|
30
|
+
if (deltaMs > MATCH_TOLERANCE_MS) continue;
|
|
30
31
|
candidates.push({
|
|
31
32
|
process: proc,
|
|
32
33
|
session,
|