@loompad/cli 0.1.0 → 1.1.2
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/ARCHITECTURE.md +96 -11
- package/CHANGELOG.md +1054 -0
- package/README.md +1473 -44
- package/THIRD_PARTY_NOTICES.md +275 -0
- package/dist/adapters/antigravity-cli.d.ts +62 -0
- package/dist/adapters/antigravity-cli.js +258 -0
- package/dist/adapters/antigravity-cli.js.map +1 -0
- package/dist/adapters/base.d.ts +61 -9
- package/dist/adapters/base.js +266 -15
- package/dist/adapters/base.js.map +1 -1
- package/dist/adapters/bridges/antigravity.d.ts +9 -12
- package/dist/adapters/bridges/antigravity.js +9 -12
- package/dist/adapters/bridges/antigravity.js.map +1 -1
- package/dist/adapters/echo.d.ts +1 -0
- package/dist/adapters/echo.js +59 -3
- package/dist/adapters/echo.js.map +1 -1
- package/dist/adapters/grok.d.ts +7 -0
- package/dist/adapters/grok.js +20 -10
- package/dist/adapters/grok.js.map +1 -1
- package/dist/adapters/index.d.ts +5 -1
- package/dist/adapters/index.js +53 -7
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/model.d.ts +137 -0
- package/dist/adapters/model.js +527 -0
- package/dist/adapters/model.js.map +1 -0
- package/dist/adapters/opencode.d.ts +101 -1
- package/dist/adapters/opencode.js +874 -98
- package/dist/adapters/opencode.js.map +1 -1
- package/dist/cli/doctor.d.ts +32 -0
- package/dist/cli/doctor.js +89 -4
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.js +2651 -87
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/tui-model.js +3 -1
- package/dist/cli/tui-model.js.map +1 -1
- package/dist/cli/tui.js +44 -1
- package/dist/cli/tui.js.map +1 -1
- package/dist/cli/ui.d.ts +2 -0
- package/dist/cli/ui.js +13 -0
- package/dist/cli/ui.js.map +1 -1
- package/dist/core/ades.d.ts +32 -16
- package/dist/core/ades.js +57 -20
- package/dist/core/ades.js.map +1 -1
- package/dist/core/agent-state.d.ts +14 -0
- package/dist/core/agent-state.js +32 -0
- package/dist/core/agent-state.js.map +1 -0
- package/dist/core/approvals.d.ts +33 -0
- package/dist/core/approvals.js +29 -0
- package/dist/core/approvals.js.map +1 -0
- package/dist/core/backup.d.ts +19 -0
- package/dist/core/backup.js +86 -0
- package/dist/core/backup.js.map +1 -0
- package/dist/core/baton.d.ts +2 -2
- package/dist/core/baton.js.map +1 -1
- package/dist/core/brain-extract.d.ts +17 -0
- package/dist/core/brain-extract.js +28 -2
- package/dist/core/brain-extract.js.map +1 -1
- package/dist/core/brain-index.d.ts +71 -0
- package/dist/core/brain-index.js +204 -5
- package/dist/core/brain-index.js.map +1 -1
- package/dist/core/brain.d.ts +58 -2
- package/dist/core/brain.js +79 -1
- package/dist/core/brain.js.map +1 -1
- package/dist/core/chat-import.d.ts +71 -0
- package/dist/core/chat-import.js +419 -0
- package/dist/core/chat-import.js.map +1 -0
- package/dist/core/checkpoint.d.ts +107 -0
- package/dist/core/checkpoint.js +259 -0
- package/dist/core/checkpoint.js.map +1 -0
- package/dist/core/claude-cli.js +1 -1
- package/dist/core/claude-cli.js.map +1 -1
- package/dist/core/continuity/artifacts.d.ts +14 -0
- package/dist/core/continuity/artifacts.js +118 -0
- package/dist/core/continuity/artifacts.js.map +1 -0
- package/dist/core/continuity/capabilities.d.ts +65 -0
- package/dist/core/continuity/capabilities.js +129 -0
- package/dist/core/continuity/capabilities.js.map +1 -0
- package/dist/core/continuity/contracts.d.ts +352 -0
- package/dist/core/continuity/contracts.js +117 -0
- package/dist/core/continuity/contracts.js.map +1 -0
- package/dist/core/continuity/engine.d.ts +55 -0
- package/dist/core/continuity/engine.js +504 -0
- package/dist/core/continuity/engine.js.map +1 -0
- package/dist/core/continuity/store.d.ts +73 -0
- package/dist/core/continuity/store.js +438 -0
- package/dist/core/continuity/store.js.map +1 -0
- package/dist/core/conversations.d.ts +19 -0
- package/dist/core/conversations.js +87 -0
- package/dist/core/conversations.js.map +1 -0
- package/dist/core/crew-coordination.d.ts +6 -0
- package/dist/core/crew-coordination.js +24 -0
- package/dist/core/crew-coordination.js.map +1 -0
- package/dist/core/crew-policy.d.ts +18 -0
- package/dist/core/crew-policy.js +40 -0
- package/dist/core/crew-policy.js.map +1 -0
- package/dist/core/crew-protocol.d.ts +64 -0
- package/dist/core/crew-protocol.js +146 -0
- package/dist/core/crew-protocol.js.map +1 -0
- package/dist/core/crew-requests.d.ts +14 -0
- package/dist/core/crew-requests.js +22 -0
- package/dist/core/crew-requests.js.map +1 -0
- package/dist/core/crew.d.ts +395 -0
- package/dist/core/crew.js +1857 -0
- package/dist/core/crew.js.map +1 -0
- package/dist/core/digest.d.ts +40 -0
- package/dist/core/digest.js +94 -0
- package/dist/core/digest.js.map +1 -0
- package/dist/core/distill.js +3 -5
- package/dist/core/distill.js.map +1 -1
- package/dist/core/eventlog.d.ts +27 -25
- package/dist/core/eventlog.js +97 -150
- package/dist/core/eventlog.js.map +1 -1
- package/dist/core/events/contracts.d.ts +51 -0
- package/dist/core/events/contracts.js +2 -0
- package/dist/core/events/contracts.js.map +1 -0
- package/dist/core/events/jsonl-store.d.ts +23 -0
- package/dist/core/events/jsonl-store.js +90 -0
- package/dist/core/events/jsonl-store.js.map +1 -0
- package/dist/core/events/sqlite-store.d.ts +37 -0
- package/dist/core/events/sqlite-store.js +215 -0
- package/dist/core/events/sqlite-store.js.map +1 -0
- package/dist/core/forecast.d.ts +44 -0
- package/dist/core/forecast.js +46 -0
- package/dist/core/forecast.js.map +1 -0
- package/dist/core/free-pool.d.ts +65 -0
- package/dist/core/free-pool.js +171 -0
- package/dist/core/free-pool.js.map +1 -0
- package/dist/core/git.d.ts +30 -0
- package/dist/core/git.js +50 -2
- package/dist/core/git.js.map +1 -1
- package/dist/core/github-events.d.ts +53 -0
- package/dist/core/github-events.js +227 -0
- package/dist/core/github-events.js.map +1 -0
- package/dist/core/goal-lanes.d.ts +53 -0
- package/dist/core/goal-lanes.js +99 -0
- package/dist/core/goal-lanes.js.map +1 -0
- package/dist/core/hosted.d.ts +27 -0
- package/dist/core/hosted.js +50 -0
- package/dist/core/hosted.js.map +1 -0
- package/dist/core/http-server.d.ts +5 -0
- package/dist/core/http-server.js +8 -0
- package/dist/core/http-server.js.map +1 -0
- package/dist/core/invite-link.d.ts +31 -0
- package/dist/core/invite-link.js +45 -0
- package/dist/core/invite-link.js.map +1 -0
- package/dist/core/loops.d.ts +37 -0
- package/dist/core/loops.js +81 -0
- package/dist/core/loops.js.map +1 -0
- package/dist/core/mcp-catalog.d.ts +182 -0
- package/dist/core/mcp-catalog.js +431 -0
- package/dist/core/mcp-catalog.js.map +1 -0
- package/dist/core/mcp.d.ts +87 -0
- package/dist/core/mcp.js +181 -0
- package/dist/core/mcp.js.map +1 -0
- package/dist/core/memory.d.ts +1 -0
- package/dist/core/memory.js +5 -2
- package/dist/core/memory.js.map +1 -1
- package/dist/core/model-tools.d.ts +97 -0
- package/dist/core/model-tools.js +388 -0
- package/dist/core/model-tools.js.map +1 -0
- package/dist/core/notify.js +19 -1
- package/dist/core/notify.js.map +1 -1
- package/dist/core/orchestra.d.ts +635 -0
- package/dist/core/orchestra.js +2120 -0
- package/dist/core/orchestra.js.map +1 -0
- package/dist/core/permissions.d.ts +56 -0
- package/dist/core/permissions.js +122 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/preview-proxy.d.ts +70 -0
- package/dist/core/preview-proxy.js +563 -0
- package/dist/core/preview-proxy.js.map +1 -0
- package/dist/core/preview-shot.d.ts +46 -0
- package/dist/core/preview-shot.js +109 -0
- package/dist/core/preview-shot.js.map +1 -0
- package/dist/core/process.d.ts +36 -0
- package/dist/core/process.js +168 -0
- package/dist/core/process.js.map +1 -0
- package/dist/core/prompt-queue.d.ts +136 -0
- package/dist/core/prompt-queue.js +269 -0
- package/dist/core/prompt-queue.js.map +1 -0
- package/dist/core/prompts.d.ts +53 -0
- package/dist/core/prompts.js +127 -0
- package/dist/core/prompts.js.map +1 -0
- package/dist/core/proof.d.ts +82 -0
- package/dist/core/proof.js +216 -0
- package/dist/core/proof.js.map +1 -0
- package/dist/core/provider-text.d.ts +23 -0
- package/dist/core/provider-text.js +66 -0
- package/dist/core/provider-text.js.map +1 -0
- package/dist/core/providers.d.ts +152 -0
- package/dist/core/providers.js +343 -0
- package/dist/core/providers.js.map +1 -0
- package/dist/core/quota.d.ts +33 -0
- package/dist/core/quota.js +74 -0
- package/dist/core/quota.js.map +1 -0
- package/dist/core/recipes.d.ts +50 -0
- package/dist/core/recipes.js +99 -0
- package/dist/core/recipes.js.map +1 -0
- package/dist/core/registry.d.ts +54 -0
- package/dist/core/registry.js +62 -5
- package/dist/core/registry.js.map +1 -1
- package/dist/core/relay-client.d.ts +67 -0
- package/dist/core/relay-client.js +184 -0
- package/dist/core/relay-client.js.map +1 -0
- package/dist/core/relay-protocol.d.ts +140 -0
- package/dist/core/relay-protocol.js +189 -0
- package/dist/core/relay-protocol.js.map +1 -0
- package/dist/core/replay.d.ts +18 -0
- package/dist/core/replay.js +191 -0
- package/dist/core/replay.js.map +1 -0
- package/dist/core/review-triage.d.ts +41 -0
- package/dist/core/review-triage.js +124 -0
- package/dist/core/review-triage.js.map +1 -0
- package/dist/core/router.js +2 -2
- package/dist/core/router.js.map +1 -1
- package/dist/core/routes.d.ts +39 -3
- package/dist/core/routes.js +137 -4
- package/dist/core/routes.js.map +1 -1
- package/dist/core/run-command.d.ts +14 -0
- package/dist/core/run-command.js +45 -0
- package/dist/core/run-command.js.map +1 -0
- package/dist/core/runner-setup.d.ts +36 -0
- package/dist/core/runner-setup.js +114 -0
- package/dist/core/runner-setup.js.map +1 -0
- package/dist/core/search.js +0 -0
- package/dist/core/search.js.map +1 -1
- package/dist/core/semantic.d.ts +92 -0
- package/dist/core/semantic.js +227 -0
- package/dist/core/semantic.js.map +1 -0
- package/dist/core/servers.d.ts +115 -0
- package/dist/core/servers.js +305 -0
- package/dist/core/servers.js.map +1 -0
- package/dist/core/setup.js +64 -6
- package/dist/core/setup.js.map +1 -1
- package/dist/core/shield.d.ts +17 -0
- package/dist/core/shield.js +81 -0
- package/dist/core/shield.js.map +1 -0
- package/dist/core/shift.d.ts +69 -0
- package/dist/core/shift.js +120 -0
- package/dist/core/shift.js.map +1 -0
- package/dist/core/skill-install.d.ts +125 -0
- package/dist/core/skill-install.js +328 -0
- package/dist/core/skill-install.js.map +1 -0
- package/dist/core/skills.d.ts +116 -0
- package/dist/core/skills.js +223 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/step-conditions.d.ts +65 -0
- package/dist/core/step-conditions.js +102 -0
- package/dist/core/step-conditions.js.map +1 -0
- package/dist/core/subagents.d.ts +45 -0
- package/dist/core/subagents.js +90 -0
- package/dist/core/subagents.js.map +1 -0
- package/dist/core/team-canon.d.ts +42 -0
- package/dist/core/team-canon.js +121 -0
- package/dist/core/team-canon.js.map +1 -0
- package/dist/core/team-crypto.d.ts +97 -0
- package/dist/core/team-crypto.js +175 -0
- package/dist/core/team-crypto.js.map +1 -0
- package/dist/core/team-hub.d.ts +514 -0
- package/dist/core/team-hub.js +964 -0
- package/dist/core/team-hub.js.map +1 -0
- package/dist/core/team-landing.d.ts +239 -0
- package/dist/core/team-landing.js +504 -0
- package/dist/core/team-landing.js.map +1 -0
- package/dist/core/team-leases.d.ts +44 -0
- package/dist/core/team-leases.js +145 -0
- package/dist/core/team-leases.js.map +1 -0
- package/dist/core/team-memory.d.ts +42 -0
- package/dist/core/team-memory.js +84 -0
- package/dist/core/team-memory.js.map +1 -0
- package/dist/core/team-policy.d.ts +85 -0
- package/dist/core/team-policy.js +191 -0
- package/dist/core/team-policy.js.map +1 -0
- package/dist/core/thread-md.d.ts +6 -0
- package/dist/core/thread-md.js +42 -0
- package/dist/core/thread-md.js.map +1 -0
- package/dist/core/turn-stats.d.ts +61 -0
- package/dist/core/turn-stats.js +124 -0
- package/dist/core/turn-stats.js.map +1 -0
- package/dist/core/updater.d.ts +73 -0
- package/dist/core/updater.js +153 -0
- package/dist/core/updater.js.map +1 -0
- package/dist/core/usage.d.ts +75 -0
- package/dist/core/usage.js +163 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/core/windows-jobs.d.ts +15 -0
- package/dist/core/windows-jobs.js +170 -0
- package/dist/core/windows-jobs.js.map +1 -0
- package/dist/core/worktree-merge.d.ts +57 -0
- package/dist/core/worktree-merge.js +123 -0
- package/dist/core/worktree-merge.js.map +1 -0
- package/dist/core/worktree.d.ts +5 -0
- package/dist/core/worktree.js +45 -5
- package/dist/core/worktree.js.map +1 -1
- package/dist/core/worktrees.d.ts +6 -0
- package/dist/core/worktrees.js +21 -0
- package/dist/core/worktrees.js.map +1 -0
- package/dist/daemon/app-page.d.ts +0 -17
- package/dist/daemon/app-page.js +10 -6346
- package/dist/daemon/app-page.js.map +1 -1
- package/dist/daemon/auth.d.ts +24 -3
- package/dist/daemon/auth.js +66 -7
- package/dist/daemon/auth.js.map +1 -1
- package/dist/daemon/board.d.ts +7 -0
- package/dist/daemon/board.js +12 -1
- package/dist/daemon/board.js.map +1 -1
- package/dist/daemon/brand-icons.d.ts +6 -1
- package/dist/daemon/brand-icons.js +11 -3
- package/dist/daemon/brand-icons.js.map +1 -1
- package/dist/daemon/client.d.ts +665 -1
- package/dist/daemon/client.js +381 -3
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/delivery.d.ts +34 -0
- package/dist/daemon/delivery.js +63 -0
- package/dist/daemon/delivery.js.map +1 -0
- package/dist/daemon/deploys.d.ts +62 -0
- package/dist/daemon/deploys.js +159 -0
- package/dist/daemon/deploys.js.map +1 -0
- package/dist/daemon/landing.d.ts +192 -0
- package/dist/daemon/landing.js +992 -0
- package/dist/daemon/landing.js.map +1 -0
- package/dist/daemon/onboard.d.ts +150 -0
- package/dist/daemon/onboard.js +390 -0
- package/dist/daemon/onboard.js.map +1 -0
- package/dist/daemon/proof.d.ts +70 -0
- package/dist/daemon/proof.js +172 -0
- package/dist/daemon/proof.js.map +1 -0
- package/dist/daemon/push.d.ts +19 -1
- package/dist/daemon/push.js +90 -3
- package/dist/daemon/push.js.map +1 -1
- package/dist/daemon/relay.d.ts +82 -0
- package/dist/daemon/relay.js +351 -0
- package/dist/daemon/relay.js.map +1 -0
- package/dist/daemon/routes/agent-discovery.d.ts +4 -0
- package/dist/daemon/routes/agent-discovery.js +29 -0
- package/dist/daemon/routes/agent-discovery.js.map +1 -0
- package/dist/daemon/routes/agent-settings.d.ts +4 -0
- package/dist/daemon/routes/agent-settings.js +94 -0
- package/dist/daemon/routes/agent-settings.js.map +1 -0
- package/dist/daemon/routes/agents.d.ts +4 -0
- package/dist/daemon/routes/agents.js +105 -0
- package/dist/daemon/routes/agents.js.map +1 -0
- package/dist/daemon/routes/alerts.d.ts +4 -0
- package/dist/daemon/routes/alerts.js +137 -0
- package/dist/daemon/routes/alerts.js.map +1 -0
- package/dist/daemon/routes/approvals.d.ts +4 -0
- package/dist/daemon/routes/approvals.js +40 -0
- package/dist/daemon/routes/approvals.js.map +1 -0
- package/dist/daemon/routes/assets.d.ts +3 -0
- package/dist/daemon/routes/assets.js +64 -0
- package/dist/daemon/routes/assets.js.map +1 -0
- package/dist/daemon/routes/board.d.ts +4 -0
- package/dist/daemon/routes/board.js +147 -0
- package/dist/daemon/routes/board.js.map +1 -0
- package/dist/daemon/routes/brain.d.ts +4 -0
- package/dist/daemon/routes/brain.js +270 -0
- package/dist/daemon/routes/brain.js.map +1 -0
- package/dist/daemon/routes/chats.d.ts +4 -0
- package/dist/daemon/routes/chats.js +249 -0
- package/dist/daemon/routes/chats.js.map +1 -0
- package/dist/daemon/routes/clients.d.ts +4 -0
- package/dist/daemon/routes/clients.js +49 -0
- package/dist/daemon/routes/clients.js.map +1 -0
- package/dist/daemon/routes/cloud.d.ts +4 -0
- package/dist/daemon/routes/cloud.js +46 -0
- package/dist/daemon/routes/cloud.js.map +1 -0
- package/dist/daemon/routes/config.d.ts +4 -0
- package/dist/daemon/routes/config.js +35 -0
- package/dist/daemon/routes/config.js.map +1 -0
- package/dist/daemon/routes/context.d.ts +51 -0
- package/dist/daemon/routes/context.js +2 -0
- package/dist/daemon/routes/context.js.map +1 -0
- package/dist/daemon/routes/crews.d.ts +4 -0
- package/dist/daemon/routes/crews.js +149 -0
- package/dist/daemon/routes/crews.js.map +1 -0
- package/dist/daemon/routes/files.d.ts +3 -0
- package/dist/daemon/routes/files.js +253 -0
- package/dist/daemon/routes/files.js.map +1 -0
- package/dist/daemon/routes/git.d.ts +4 -0
- package/dist/daemon/routes/git.js +96 -0
- package/dist/daemon/routes/git.js.map +1 -0
- package/dist/daemon/routes/history.d.ts +4 -0
- package/dist/daemon/routes/history.js +101 -0
- package/dist/daemon/routes/history.js.map +1 -0
- package/dist/daemon/routes/integrations-project.d.ts +3 -0
- package/dist/daemon/routes/integrations-project.js +103 -0
- package/dist/daemon/routes/integrations-project.js.map +1 -0
- package/dist/daemon/routes/integrations.d.ts +3 -0
- package/dist/daemon/routes/integrations.js +111 -0
- package/dist/daemon/routes/integrations.js.map +1 -0
- package/dist/daemon/routes/logs.d.ts +3 -0
- package/dist/daemon/routes/logs.js +40 -0
- package/dist/daemon/routes/logs.js.map +1 -0
- package/dist/daemon/routes/messages.d.ts +4 -0
- package/dist/daemon/routes/messages.js +60 -0
- package/dist/daemon/routes/messages.js.map +1 -0
- package/dist/daemon/routes/observability.d.ts +4 -0
- package/dist/daemon/routes/observability.js +247 -0
- package/dist/daemon/routes/observability.js.map +1 -0
- package/dist/daemon/routes/onboard.d.ts +12 -0
- package/dist/daemon/routes/onboard.js +67 -0
- package/dist/daemon/routes/onboard.js.map +1 -0
- package/dist/daemon/routes/orchestra.d.ts +4 -0
- package/dist/daemon/routes/orchestra.js +110 -0
- package/dist/daemon/routes/orchestra.js.map +1 -0
- package/dist/daemon/routes/pairing.d.ts +4 -0
- package/dist/daemon/routes/pairing.js +155 -0
- package/dist/daemon/routes/pairing.js.map +1 -0
- package/dist/daemon/routes/preview.d.ts +24 -0
- package/dist/daemon/routes/preview.js +122 -0
- package/dist/daemon/routes/preview.js.map +1 -0
- package/dist/daemon/routes/project-actions.d.ts +4 -0
- package/dist/daemon/routes/project-actions.js +53 -0
- package/dist/daemon/routes/project-actions.js.map +1 -0
- package/dist/daemon/routes/project-team.d.ts +4 -0
- package/dist/daemon/routes/project-team.js +201 -0
- package/dist/daemon/routes/project-team.js.map +1 -0
- package/dist/daemon/routes/projects.d.ts +14 -0
- package/dist/daemon/routes/projects.js +138 -0
- package/dist/daemon/routes/projects.js.map +1 -0
- package/dist/daemon/routes/prompts.d.ts +4 -0
- package/dist/daemon/routes/prompts.js +44 -0
- package/dist/daemon/routes/prompts.js.map +1 -0
- package/dist/daemon/routes/proof.d.ts +4 -0
- package/dist/daemon/routes/proof.js +22 -0
- package/dist/daemon/routes/proof.js.map +1 -0
- package/dist/daemon/routes/providers.d.ts +3 -0
- package/dist/daemon/routes/providers.js +60 -0
- package/dist/daemon/routes/providers.js.map +1 -0
- package/dist/daemon/routes/public.d.ts +4 -0
- package/dist/daemon/routes/public.js +64 -0
- package/dist/daemon/routes/public.js.map +1 -0
- package/dist/daemon/routes/queue.d.ts +4 -0
- package/dist/daemon/routes/queue.js +140 -0
- package/dist/daemon/routes/queue.js.map +1 -0
- package/dist/daemon/routes/routing.d.ts +4 -0
- package/dist/daemon/routes/routing.js +61 -0
- package/dist/daemon/routes/routing.js.map +1 -0
- package/dist/daemon/routes/runtime-handler.d.ts +2 -0
- package/dist/daemon/routes/runtime-handler.js +63 -0
- package/dist/daemon/routes/runtime-handler.js.map +1 -0
- package/dist/daemon/routes/search.d.ts +4 -0
- package/dist/daemon/routes/search.js +17 -0
- package/dist/daemon/routes/search.js.map +1 -0
- package/dist/daemon/routes/servers.d.ts +4 -0
- package/dist/daemon/routes/servers.js +133 -0
- package/dist/daemon/routes/servers.js.map +1 -0
- package/dist/daemon/routes/setup.d.ts +3 -0
- package/dist/daemon/routes/setup.js +50 -0
- package/dist/daemon/routes/setup.js.map +1 -0
- package/dist/daemon/routes/shift.d.ts +4 -0
- package/dist/daemon/routes/shift.js +30 -0
- package/dist/daemon/routes/shift.js.map +1 -0
- package/dist/daemon/routes/specs.d.ts +4 -0
- package/dist/daemon/routes/specs.js +57 -0
- package/dist/daemon/routes/specs.js.map +1 -0
- package/dist/daemon/routes/task-delivery.d.ts +4 -0
- package/dist/daemon/routes/task-delivery.js +38 -0
- package/dist/daemon/routes/task-delivery.js.map +1 -0
- package/dist/daemon/routes/team.d.ts +4 -0
- package/dist/daemon/routes/team.js +193 -0
- package/dist/daemon/routes/team.js.map +1 -0
- package/dist/daemon/routes/terminals.d.ts +4 -0
- package/dist/daemon/routes/terminals.js +87 -0
- package/dist/daemon/routes/terminals.js.map +1 -0
- package/dist/daemon/routes/tools.d.ts +4 -0
- package/dist/daemon/routes/tools.js +180 -0
- package/dist/daemon/routes/tools.js.map +1 -0
- package/dist/daemon/routes/updates.d.ts +4 -0
- package/dist/daemon/routes/updates.js +89 -0
- package/dist/daemon/routes/updates.js.map +1 -0
- package/dist/daemon/routes/voice.d.ts +4 -0
- package/dist/daemon/routes/voice.js +53 -0
- package/dist/daemon/routes/voice.js.map +1 -0
- package/dist/daemon/runner.d.ts +186 -0
- package/dist/daemon/runner.js +612 -0
- package/dist/daemon/runner.js.map +1 -0
- package/dist/daemon/runtime/accounting.d.ts +130 -0
- package/dist/daemon/runtime/accounting.js +303 -0
- package/dist/daemon/runtime/accounting.js.map +1 -0
- package/dist/daemon/runtime/agents.d.ts +16 -0
- package/dist/daemon/runtime/agents.js +71 -0
- package/dist/daemon/runtime/agents.js.map +1 -0
- package/dist/daemon/runtime/briefings.d.ts +134 -0
- package/dist/daemon/runtime/briefings.js +329 -0
- package/dist/daemon/runtime/briefings.js.map +1 -0
- package/dist/daemon/runtime/native-usage.d.ts +21 -0
- package/dist/daemon/runtime/native-usage.js +71 -0
- package/dist/daemon/runtime/native-usage.js.map +1 -0
- package/dist/daemon/runtime/queue.d.ts +94 -0
- package/dist/daemon/runtime/queue.js +222 -0
- package/dist/daemon/runtime/queue.js.map +1 -0
- package/dist/daemon/runtime/relay.d.ts +93 -0
- package/dist/daemon/runtime/relay.js +240 -0
- package/dist/daemon/runtime/relay.js.map +1 -0
- package/dist/daemon/runtime/turns.d.ts +202 -0
- package/dist/daemon/runtime/turns.js +663 -0
- package/dist/daemon/runtime/turns.js.map +1 -0
- package/dist/daemon/runtime-support.d.ts +76 -0
- package/dist/daemon/runtime-support.js +134 -0
- package/dist/daemon/runtime-support.js.map +1 -0
- package/dist/daemon/runtime.d.ts +739 -70
- package/dist/daemon/runtime.js +2751 -470
- package/dist/daemon/runtime.js.map +1 -1
- package/dist/daemon/server.d.ts +82 -55
- package/dist/daemon/server.js +674 -1435
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/shift.d.ts +70 -0
- package/dist/daemon/shift.js +170 -0
- package/dist/daemon/shift.js.map +1 -0
- package/dist/daemon/specs.d.ts +92 -0
- package/dist/daemon/specs.js +285 -0
- package/dist/daemon/specs.js.map +1 -0
- package/dist/daemon/system.d.ts +208 -0
- package/dist/daemon/system.js +557 -0
- package/dist/daemon/system.js.map +1 -0
- package/dist/daemon/tasks.js +1 -1
- package/dist/daemon/team-brain.d.ts +136 -0
- package/dist/daemon/team-brain.js +659 -0
- package/dist/daemon/team-brain.js.map +1 -0
- package/dist/daemon/team-coordinator.d.ts +78 -0
- package/dist/daemon/team-coordinator.js +408 -0
- package/dist/daemon/team-coordinator.js.map +1 -0
- package/dist/daemon/team.d.ts +339 -0
- package/dist/daemon/team.js +1433 -0
- package/dist/daemon/team.js.map +1 -0
- package/dist/daemon/terminals.d.ts +22 -3
- package/dist/daemon/terminals.js +236 -16
- package/dist/daemon/terminals.js.map +1 -1
- package/dist/hub/client.d.ts +120 -0
- package/dist/hub/client.js +228 -0
- package/dist/hub/client.js.map +1 -0
- package/dist/hub/server.d.ts +32 -0
- package/dist/hub/server.js +180 -0
- package/dist/hub/server.js.map +1 -0
- package/dist/hub/supabase-client.d.ts +220 -0
- package/dist/hub/supabase-client.js +843 -0
- package/dist/hub/supabase-client.js.map +1 -0
- package/dist/observability/ask.d.ts +91 -0
- package/dist/observability/ask.js +179 -0
- package/dist/observability/ask.js.map +1 -0
- package/dist/observability/clickhouse.d.ts +33 -0
- package/dist/observability/clickhouse.js +48 -0
- package/dist/observability/clickhouse.js.map +1 -0
- package/dist/observability/decisions.d.ts +176 -0
- package/dist/observability/decisions.js +377 -0
- package/dist/observability/decisions.js.map +1 -0
- package/dist/observability/index.d.ts +89 -0
- package/dist/observability/index.js +348 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/insights.d.ts +151 -0
- package/dist/observability/insights.js +319 -0
- package/dist/observability/insights.js.map +1 -0
- package/dist/observability/logs-query.d.ts +82 -0
- package/dist/observability/logs-query.js +102 -0
- package/dist/observability/logs-query.js.map +1 -0
- package/dist/observability/logs.d.ts +72 -0
- package/dist/observability/logs.js +295 -0
- package/dist/observability/logs.js.map +1 -0
- package/dist/observability/metrics.d.ts +86 -0
- package/dist/observability/metrics.js +303 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/otlp.d.ts +127 -0
- package/dist/observability/otlp.js +242 -0
- package/dist/observability/otlp.js.map +1 -0
- package/dist/observability/snapshots.d.ts +43 -0
- package/dist/observability/snapshots.js +129 -0
- package/dist/observability/snapshots.js.map +1 -0
- package/dist/observability/triage.d.ts +49 -0
- package/dist/observability/triage.js +284 -0
- package/dist/observability/triage.js.map +1 -0
- package/dist/providers/adapter.d.ts +50 -0
- package/dist/providers/adapter.js +38 -0
- package/dist/providers/adapter.js.map +1 -0
- package/dist/providers/agent.d.ts +110 -0
- package/dist/providers/agent.js +487 -0
- package/dist/providers/agent.js.map +1 -0
- package/dist/providers/approvals.d.ts +24 -0
- package/dist/providers/approvals.js +78 -0
- package/dist/providers/approvals.js.map +1 -0
- package/dist/providers/attachments.d.ts +20 -0
- package/dist/providers/attachments.js +51 -0
- package/dist/providers/attachments.js.map +1 -0
- package/dist/providers/claude/adapter.d.ts +99 -0
- package/dist/providers/claude/adapter.js +790 -0
- package/dist/providers/claude/adapter.js.map +1 -0
- package/dist/providers/codex/adapter.d.ts +113 -0
- package/dist/providers/codex/adapter.js +881 -0
- package/dist/providers/codex/adapter.js.map +1 -0
- package/dist/providers/codex/instructions.d.ts +11 -0
- package/dist/providers/codex/instructions.js +154 -0
- package/dist/providers/codex/instructions.js.map +1 -0
- package/dist/providers/codex/rpc.d.ts +36 -0
- package/dist/providers/codex/rpc.js +104 -0
- package/dist/providers/codex/rpc.js.map +1 -0
- package/dist/providers/contracts.d.ts +339 -0
- package/dist/providers/contracts.js +19 -0
- package/dist/providers/contracts.js.map +1 -0
- package/dist/providers/directory.d.ts +70 -0
- package/dist/providers/directory.js +95 -0
- package/dist/providers/directory.js.map +1 -0
- package/dist/providers/errors.d.ts +47 -0
- package/dist/providers/errors.js +24 -0
- package/dist/providers/errors.js.map +1 -0
- package/dist/providers/index.d.ts +18 -0
- package/dist/providers/index.js +19 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/ingestion.d.ts +80 -0
- package/dist/providers/ingestion.js +330 -0
- package/dist/providers/ingestion.js.map +1 -0
- package/dist/providers/live.d.ts +22 -0
- package/dist/providers/live.js +56 -0
- package/dist/providers/live.js.map +1 -0
- package/dist/providers/process.d.ts +29 -0
- package/dist/providers/process.js +71 -0
- package/dist/providers/process.js.map +1 -0
- package/dist/providers/reaper.d.ts +33 -0
- package/dist/providers/reaper.js +65 -0
- package/dist/providers/reaper.js.map +1 -0
- package/dist/providers/service.d.ts +87 -0
- package/dist/providers/service.js +256 -0
- package/dist/providers/service.js.map +1 -0
- package/dist/sdk.d.ts +1 -1
- package/dist/sdk.js +1 -1
- package/dist/sdk.js.map +1 -1
- package/dist/types.d.ts +385 -6
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +7 -0
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -0
- package/dist/web/app.css +4646 -0
- package/dist/web/app.js +22640 -0
- package/dist/web/app.js.map +7 -0
- package/dist/web/shell.html +39 -0
- package/docs/README.md +21 -0
- package/docs/SETUP.md +10 -0
- package/docs/adapters.md +21 -8
- package/docs/brain-continuity.md +186 -0
- package/docs/cloud.md +108 -0
- package/docs/crews.md +62 -0
- package/docs/design-system.md +31 -2
- package/docs/integration-notes.md +128 -20
- package/docs/loompad.md +105 -0
- package/docs/observability.md +220 -0
- package/docs/play-store.md +123 -0
- package/docs/proposals/agent-teams.md +249 -0
- package/docs/proposals/brain-continuity-implementation.md +468 -0
- package/docs/proposals/brain-session-continuity.md +623 -0
- package/docs/proposals/t3code-port.md +81 -0
- package/docs/proposals/t3code-reference.md +95 -0
- package/docs/refactoring/AGENT-TEAMS-PROGRESS.md +88 -0
- package/docs/refactoring/BOUNDARIES.md +120 -0
- package/docs/refactoring/BRAIN-AUDIT.md +176 -0
- package/docs/refactoring/BRAIN-NOTES.md +390 -0
- package/docs/refactoring/BRAIN-TODO.md +214 -0
- package/docs/refactoring/NOTES.md +129 -0
- package/docs/refactoring/T3-PORT-NOTES.md +165 -0
- package/docs/refactoring/T3-PORT-TODO.md +123 -0
- package/docs/refactoring/TODO.md +46 -0
- package/docs/refactoring/brain-benchmark-2026-09-28.json +48 -0
- package/docs/refactoring/brain-benchmark-audit-2026-09-28.json +48 -0
- package/docs/release-notes/v0.2.0.md +35 -0
- package/docs/release-notes/v0.2.1.md +59 -0
- package/docs/release-notes/v0.2.3.md +77 -0
- package/docs/release-notes/v0.2.4.md +128 -0
- package/docs/release-notes/v0.2.5.md +153 -0
- package/docs/release-notes/v0.2.6.md +62 -0
- package/docs/release-notes/v1.0.0.md +120 -0
- package/docs/release-notes/v1.0.1.md +77 -0
- package/docs/release-notes/v1.1.0.md +71 -0
- package/docs/release-notes/v1.1.1.md +38 -0
- package/docs/release-notes/v1.1.2.md +21 -0
- package/docs/teams-architecture.md +697 -0
- package/docs/teams.md +171 -0
- package/docs/windows.md +85 -0
- package/package.json +22 -9
- package/dist/adapters/claude-code.d.ts +0 -26
- package/dist/adapters/claude-code.js +0 -209
- package/dist/adapters/claude-code.js.map +0 -1
- package/dist/adapters/codex.d.ts +0 -51
- package/dist/adapters/codex.js +0 -291
- package/dist/adapters/codex.js.map +0 -1
- package/docs/img/board-linear.png +0 -0
- package/docs/img/board-projects.png +0 -0
- package/docs/img/brain.png +0 -0
- package/docs/img/settings.png +0 -0
- package/docs/img/workspace.png +0 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoints: a point you can put the files back to.
|
|
3
|
+
*
|
|
4
|
+
* An agent turn can touch forty files, and the honest answer to "undo that"
|
|
5
|
+
* used to be "read the diff and retype it". `turn_diff` looks like the answer
|
|
6
|
+
* and isn't: its patch is truncated at 12KB, it records an untracked file as
|
|
7
|
+
* the line `?? new file: <path>` with no content in it, and it carries no ref
|
|
8
|
+
* to apply against. It is a thing to look at, not a thing to reverse.
|
|
9
|
+
*
|
|
10
|
+
* So this doesn't reverse anything. Before a turn runs, it writes down what
|
|
11
|
+
* the working tree *was*, and rewinding puts that back.
|
|
12
|
+
*
|
|
13
|
+
* ## Why a commit on a hidden ref
|
|
14
|
+
*
|
|
15
|
+
* The capture has to include untracked files (an agent's first act is often to
|
|
16
|
+
* create one), survive a daemon restart, and cost nothing in the common case
|
|
17
|
+
* where nobody ever rewinds. It also must not touch anything the human can
|
|
18
|
+
* see: not HEAD, not the current branch, not the index, not the stash stack —
|
|
19
|
+
* a checkpoint that rewrote `git status` under someone mid-review would be
|
|
20
|
+
* worse than no checkpoint.
|
|
21
|
+
*
|
|
22
|
+
* A tree written through a *temporary index* satisfies all of it. `git add -A`
|
|
23
|
+
* against `GIT_INDEX_FILE=<tmp>` stages tracked and untracked alike without
|
|
24
|
+
* going near the real index; `write-tree` turns that into a tree object;
|
|
25
|
+
* `commit-tree` parents it on HEAD so the object survives gc; and the commit
|
|
26
|
+
* is kept under `refs/loom/checkpoints/<id>`, which no branch listing shows.
|
|
27
|
+
* This is what `git stash create` does internally, minus the stash stack that
|
|
28
|
+
* belongs to the human.
|
|
29
|
+
*
|
|
30
|
+
* ## What is deliberately not captured
|
|
31
|
+
*
|
|
32
|
+
* Ignored files. `git add -A` honours `.gitignore`, so `node_modules`, build
|
|
33
|
+
* output and — the one that matters — `.env` are never read, never written
|
|
34
|
+
* into an object, and never restored. `.loom/` is ignored too, which is the
|
|
35
|
+
* reason a rewind cannot eat the event log: history is what happened, and a
|
|
36
|
+
* rewind that edited it would be a lie with a timestamp.
|
|
37
|
+
*
|
|
38
|
+
* ## Why restoring takes a checkpoint first
|
|
39
|
+
*
|
|
40
|
+
* Rewinding is destructive by definition — it is asking for work to go away.
|
|
41
|
+
* The work it removes is nearly always work you wanted gone, and occasionally
|
|
42
|
+
* it is four files you forgot you had open. So a restore captures the current
|
|
43
|
+
* tree before it touches anything, and says where that landed. Rewind is
|
|
44
|
+
* itself rewindable, or it is a trap.
|
|
45
|
+
*/
|
|
46
|
+
import { execFile } from "./process.js";
|
|
47
|
+
import fs from "node:fs";
|
|
48
|
+
import { GitError } from "./git.js";
|
|
49
|
+
/** Where checkpoints live. Not under refs/heads, so nothing lists them. */
|
|
50
|
+
const REF_PREFIX = "refs/loom/checkpoints";
|
|
51
|
+
/** How many to keep. Older ones are unreferenced and git collects them. */
|
|
52
|
+
export const KEEP_CHECKPOINTS = 60;
|
|
53
|
+
function run(args, cwd, env) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
execFile("git", args, { cwd, maxBuffer: 64 * 1024 * 1024, ...(env ? { env: { ...process.env, ...env } } : {}) }, (err, stdout, stderr) => {
|
|
56
|
+
if (err) {
|
|
57
|
+
const detail = String(stderr || err.message).trim();
|
|
58
|
+
reject(new GitError(detail.split("\n").find((l) => l.trim())?.trim() || `git ${args[0]} failed`, detail));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
resolve(String(stdout));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async function quiet(args, cwd) {
|
|
66
|
+
try {
|
|
67
|
+
return (await run(args, cwd)).trim();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return "";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** A temporary index path for this capture. Never the repository's own. */
|
|
74
|
+
function tmpIndex(dir, id) {
|
|
75
|
+
return `${dir.replace(/\/+$/, "")}/.git/loom-checkpoint-${id}.index`;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Ids are minted from the clock and have to survive two captures in the same
|
|
79
|
+
* millisecond — a restore takes its undo checkpoint immediately before the
|
|
80
|
+
* one it is restoring, and on a fast machine those are the same tick.
|
|
81
|
+
*/
|
|
82
|
+
let lastStamp = 0;
|
|
83
|
+
function newId() {
|
|
84
|
+
const now = Math.max(Date.now(), lastStamp + 1);
|
|
85
|
+
lastStamp = now;
|
|
86
|
+
return `c${now.toString(36)}`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Write down what the working tree is right now.
|
|
90
|
+
*
|
|
91
|
+
* Returns null when there is nothing a checkpoint could mean: no repository,
|
|
92
|
+
* or a repository with no commits, where there is no HEAD to parent on and
|
|
93
|
+
* nothing to go back to.
|
|
94
|
+
*/
|
|
95
|
+
export async function capture(dir, label) {
|
|
96
|
+
if ((await quiet(["rev-parse", "--is-inside-work-tree"], dir)) !== "true")
|
|
97
|
+
return null;
|
|
98
|
+
const head = await quiet(["rev-parse", "HEAD"], dir);
|
|
99
|
+
if (!head)
|
|
100
|
+
return null;
|
|
101
|
+
const id = newId();
|
|
102
|
+
const index = tmpIndex(dir, id);
|
|
103
|
+
const env = { GIT_INDEX_FILE: index };
|
|
104
|
+
try {
|
|
105
|
+
// Start from HEAD so the tree is HEAD-plus-your-changes rather than
|
|
106
|
+
// whatever happens to be staged, then take everything: modifications,
|
|
107
|
+
// deletions and new files alike. .gitignore still applies, which is what
|
|
108
|
+
// keeps .env and node_modules out of the object store.
|
|
109
|
+
await run(["read-tree", "HEAD"], dir, env);
|
|
110
|
+
await run(["add", "-A", "--", "."], dir, env);
|
|
111
|
+
const tree = (await run(["write-tree"], dir, env)).trim();
|
|
112
|
+
const commit = (await run([
|
|
113
|
+
"-c",
|
|
114
|
+
"user.name=Loom",
|
|
115
|
+
"-c",
|
|
116
|
+
"user.email=loom@loom.local",
|
|
117
|
+
"commit-tree",
|
|
118
|
+
tree,
|
|
119
|
+
"-p",
|
|
120
|
+
head,
|
|
121
|
+
"-m",
|
|
122
|
+
`loom checkpoint: ${label.replace(/\s+/g, " ").trim().slice(0, 120) || "unlabelled"}`,
|
|
123
|
+
], dir)).trim();
|
|
124
|
+
await run(["update-ref", `${REF_PREFIX}/${id}`, commit], dir);
|
|
125
|
+
const dirty = (await quiet(["diff", "--name-only", `${head}..${commit}`], dir)).split("\n").filter(Boolean).length;
|
|
126
|
+
const branch = (await quiet(["rev-parse", "--abbrev-ref", "HEAD"], dir)) || null;
|
|
127
|
+
const cp = {
|
|
128
|
+
id,
|
|
129
|
+
label: label.trim().slice(0, 200),
|
|
130
|
+
commit,
|
|
131
|
+
at: Date.now(),
|
|
132
|
+
branch: branch === "HEAD" ? null : branch,
|
|
133
|
+
dirty,
|
|
134
|
+
};
|
|
135
|
+
await prune(dir, KEEP_CHECKPOINTS);
|
|
136
|
+
return cp;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// A checkpoint is a courtesy taken on a hot path. It must never be the
|
|
140
|
+
// reason a turn doesn't run.
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
// The temporary index is scratch; leaving one behind would be litter, not
|
|
145
|
+
// a failure, so this never throws.
|
|
146
|
+
try {
|
|
147
|
+
fs.rmSync(index, { force: true });
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
/* disposable */
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** Every checkpoint this project holds, newest first. */
|
|
155
|
+
export async function list(dir) {
|
|
156
|
+
const out = await quiet(["for-each-ref", "--format=%(refname:short)%09%(objectname)%09%(subject)%09%(committerdate:unix)", REF_PREFIX], dir);
|
|
157
|
+
if (!out)
|
|
158
|
+
return [];
|
|
159
|
+
const rows = [];
|
|
160
|
+
for (const line of out.split("\n")) {
|
|
161
|
+
const [ref, commit, subject, when] = line.split("\t");
|
|
162
|
+
if (!ref || !commit)
|
|
163
|
+
continue;
|
|
164
|
+
const id = ref.slice(ref.lastIndexOf("/") + 1);
|
|
165
|
+
rows.push({
|
|
166
|
+
id,
|
|
167
|
+
label: (subject ?? "").replace(/^loom checkpoint: /, ""),
|
|
168
|
+
commit,
|
|
169
|
+
at: Number(when) * 1000 || 0,
|
|
170
|
+
branch: null,
|
|
171
|
+
dirty: 0,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// Ids are base36 milliseconds, so lexical order is chronological order.
|
|
175
|
+
return rows.sort((a, b) => (a.id < b.id ? 1 : a.id > b.id ? -1 : 0));
|
|
176
|
+
}
|
|
177
|
+
export async function find(dir, id) {
|
|
178
|
+
if (!/^c[a-z0-9]+$/.test(id))
|
|
179
|
+
return null;
|
|
180
|
+
return (await list(dir)).find((c) => c.id === id) ?? null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Put the working tree back to a checkpoint.
|
|
184
|
+
*
|
|
185
|
+
* Two commands do the work. `read-tree -u --reset` makes the index and the
|
|
186
|
+
* working tree agree with the captured tree — restoring what changed and
|
|
187
|
+
* deleting what the checkpoint didn't have. `clean -fd` then removes the
|
|
188
|
+
* directories git leaves behind. Neither is given `-x`, so ignored files are
|
|
189
|
+
* not touched: your `node_modules` survives, and so does your `.env`.
|
|
190
|
+
*
|
|
191
|
+
* HEAD does not move. A checkpoint is a working tree, not a history, and
|
|
192
|
+
* rewinding your files should not rewrite your commits.
|
|
193
|
+
*/
|
|
194
|
+
export async function restore(dir, id) {
|
|
195
|
+
const target = await find(dir, id);
|
|
196
|
+
if (!target)
|
|
197
|
+
throw new GitError(`no checkpoint "${id}" in this project`, "");
|
|
198
|
+
// Before anything is lost: a checkpoint of what is about to be replaced.
|
|
199
|
+
// Without this, rewind is a one-way door, and the one time it matters is
|
|
200
|
+
// the time someone rewinds past work they meant to keep.
|
|
201
|
+
const undo = await capture(dir, `before rewinding to ${target.label.slice(0, 80)}`);
|
|
202
|
+
if (!undo)
|
|
203
|
+
throw new GitError("couldn't save the current files before rewinding — nothing was changed", "");
|
|
204
|
+
// What this rewind will actually do, from the two captured trees rather
|
|
205
|
+
// than from `git diff`, which cannot see an untracked file — and an
|
|
206
|
+
// untracked file is precisely what a rewind deletes.
|
|
207
|
+
const changed = (await quiet(["diff", "--name-only", `${undo.commit}..${target.commit}`], dir))
|
|
208
|
+
.split("\n")
|
|
209
|
+
.filter(Boolean);
|
|
210
|
+
await run(["read-tree", "-u", "--reset", target.commit], dir);
|
|
211
|
+
await run(["clean", "-f", "-d", "--", "."], dir);
|
|
212
|
+
// read-tree moved the index to the checkpoint's tree as well as the files,
|
|
213
|
+
// which would leave every restored change reading as *staged* — a rewind
|
|
214
|
+
// that silently runs `git add` on your behalf. Putting the index back to
|
|
215
|
+
// HEAD leaves `git status` saying what it would say if you had made those
|
|
216
|
+
// edits by hand: modified, and untracked. --mixed touches the index only.
|
|
217
|
+
await quiet(["reset", "-q", "--mixed", "HEAD"], dir);
|
|
218
|
+
return { restored: target, undo, changed };
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Put one file back the way a checkpoint had it — or remove it, when the
|
|
222
|
+
* checkpoint didn't have it (the turn created it). Everything else is left
|
|
223
|
+
* alone. Like a full rewind, it takes an undo checkpoint first.
|
|
224
|
+
*/
|
|
225
|
+
export async function restoreFile(dir, id, file) {
|
|
226
|
+
const target = await find(dir, id);
|
|
227
|
+
if (!target)
|
|
228
|
+
throw new GitError(`no checkpoint "${id}" in this project`, "");
|
|
229
|
+
const rel = file.replace(/^\.?\/+/, "");
|
|
230
|
+
if (!rel || rel.split("/").includes(".."))
|
|
231
|
+
throw new GitError(`"${file}" isn't a path inside this project`, "");
|
|
232
|
+
const undo = await capture(dir, `before putting back ${rel.slice(0, 80)}`);
|
|
233
|
+
if (!undo)
|
|
234
|
+
throw new GitError("couldn't save the current files first — nothing was changed", "");
|
|
235
|
+
const existed = (await quiet(["cat-file", "-t", `${target.commit}:${rel}`], dir)) === "blob";
|
|
236
|
+
if (existed) {
|
|
237
|
+
await run(["checkout", target.commit, "--", rel], dir);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
await quiet(["rm", "-q", "--cached", "--ignore-unmatch", "--", rel], dir);
|
|
241
|
+
await fs.promises.rm(`${dir.replace(/\/+$/, "")}/${rel}`, { force: true });
|
|
242
|
+
}
|
|
243
|
+
// checkout staged it; leave it reading as a plain edit, like a rewind does
|
|
244
|
+
await quiet(["reset", "-q", "HEAD", "--", rel], dir);
|
|
245
|
+
return { restored: target, undo, path: rel, removed: !existed };
|
|
246
|
+
}
|
|
247
|
+
/** Drop all but the newest `keep`. The commits become unreferenced. */
|
|
248
|
+
export async function prune(dir, keep = KEEP_CHECKPOINTS) {
|
|
249
|
+
const all = await list(dir);
|
|
250
|
+
const drop = all.slice(Math.max(0, keep));
|
|
251
|
+
for (const c of drop)
|
|
252
|
+
await quiet(["update-ref", "-d", `${REF_PREFIX}/${c.id}`], dir);
|
|
253
|
+
return drop.length;
|
|
254
|
+
}
|
|
255
|
+
/** Remove every checkpoint. For `loom rewind --forget`. */
|
|
256
|
+
export async function forgetAll(dir) {
|
|
257
|
+
return prune(dir, 0);
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/core/checkpoint.ts"],"names":[],"mappings":"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"}
|
package/dist/core/claude-cli.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* internal reasoning jobs, never user-facing turns (those go through the
|
|
5
5
|
* claude-code adapter with sessions and streaming).
|
|
6
6
|
*/
|
|
7
|
-
import { spawn } from "
|
|
7
|
+
import { spawn } from "./process.js";
|
|
8
8
|
import { agentEnv } from "../adapters/base.js";
|
|
9
9
|
export function claudeText(prompt, opts = {}) {
|
|
10
10
|
return new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-cli.js","sourceRoot":"","sources":["../../src/core/claude-cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"claude-cli.js","sourceRoot":"","sources":["../../src/core/claude-cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAQ/C,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,OAAyB,EAAE;IACpE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CACjB,QAAQ,EACR;YACE,IAAI;YACJ,MAAM;YACN,iBAAiB;YACjB,MAAM;YACN,SAAS;YACT,IAAI,CAAC,KAAK,IAAI,OAAO;YACrB,0BAA0B;SAC3B,EACD,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,CACzD,CAAC;QACF,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAC7C,CAAC,EAAE,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;QAC7B,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC9D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC;YAClE,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4C,CAAC;gBAC3E,IAAI,OAAO,CAAC,QAAQ;oBAAE,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;gBAClF,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Immutable local retrieval evidence, finalized before its packet is stored.
|
|
2
|
+
* No model-selected path, credentials, SQLite write access or daemon dependency. */
|
|
3
|
+
export declare class ContextArtifacts {
|
|
4
|
+
private readonly root;
|
|
5
|
+
private readonly workspace;
|
|
6
|
+
constructor(workspace: string);
|
|
7
|
+
put(text: string): {
|
|
8
|
+
hash: string;
|
|
9
|
+
relativePath: string;
|
|
10
|
+
bytes: number;
|
|
11
|
+
};
|
|
12
|
+
read(hash: string): string;
|
|
13
|
+
private assertRoot;
|
|
14
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { ContinuityError, digest } from "./contracts.js";
|
|
5
|
+
/** Immutable local retrieval evidence, finalized before its packet is stored.
|
|
6
|
+
* No model-selected path, credentials, SQLite write access or daemon dependency. */
|
|
7
|
+
export class ContextArtifacts {
|
|
8
|
+
root;
|
|
9
|
+
workspace;
|
|
10
|
+
constructor(workspace) {
|
|
11
|
+
const canonical = fs.realpathSync(workspace);
|
|
12
|
+
this.workspace = canonical;
|
|
13
|
+
this.root = path.join(canonical, ".loom", "brain", "artifacts");
|
|
14
|
+
for (const part of [".loom", ".loom/brain", ".loom/brain/artifacts"]) {
|
|
15
|
+
const dir = path.join(canonical, part);
|
|
16
|
+
if (fs.existsSync(dir) && (fs.lstatSync(dir).isSymbolicLink() || !fs.statSync(dir).isDirectory()))
|
|
17
|
+
throw new ContinuityError("invalid", "Brain artifact directory must be a local directory, not a symlink");
|
|
18
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
put(text) {
|
|
22
|
+
this.assertRoot();
|
|
23
|
+
const bytes = Buffer.byteLength(text);
|
|
24
|
+
if (bytes > 32_000_000)
|
|
25
|
+
throw new ContinuityError("overflow", "source retrieval artifact exceeds 32 MB; narrow reviewed checkpoint sources");
|
|
26
|
+
const hash = digest(text), relativePath = `.loom/brain/artifacts/${hash}.json`, file = path.join(this.root, `${hash}.json`);
|
|
27
|
+
if (fs.existsSync(file)) {
|
|
28
|
+
this.read(hash);
|
|
29
|
+
return { hash, relativePath, bytes };
|
|
30
|
+
}
|
|
31
|
+
const temporary = path.join(this.root, `.pending-${randomUUID()}`);
|
|
32
|
+
const fd = fs.openSync(temporary, "wx", 0o600);
|
|
33
|
+
try {
|
|
34
|
+
try {
|
|
35
|
+
fs.writeFileSync(fd, text);
|
|
36
|
+
fs.fchmodSync(fd, 0o400);
|
|
37
|
+
fs.fsyncSync(fd);
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
fs.closeSync(fd);
|
|
41
|
+
}
|
|
42
|
+
this.assertRoot();
|
|
43
|
+
// Exclusive publication: never replace an existing immutable artifact.
|
|
44
|
+
try {
|
|
45
|
+
fs.linkSync(temporary, file);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (error.code !== "EEXIST")
|
|
49
|
+
throw error;
|
|
50
|
+
this.read(hash);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
fs.unlinkSync(temporary);
|
|
55
|
+
}
|
|
56
|
+
// macOS/Linux support fsync on a directory; Windows may reject it. The
|
|
57
|
+
// file has still been flushed; never treat a rejected directory fsync as
|
|
58
|
+
// acknowledgement of a durable packet.
|
|
59
|
+
let directory;
|
|
60
|
+
try {
|
|
61
|
+
directory = fs.openSync(this.root, "r");
|
|
62
|
+
fs.fsyncSync(directory);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (process.platform !== "win32")
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
if (directory !== undefined)
|
|
70
|
+
fs.closeSync(directory);
|
|
71
|
+
}
|
|
72
|
+
return { hash, relativePath, bytes };
|
|
73
|
+
}
|
|
74
|
+
read(hash) {
|
|
75
|
+
this.assertRoot();
|
|
76
|
+
if (!/^[a-f0-9]{64}$/.test(hash))
|
|
77
|
+
throw new ContinuityError("invalid", "invalid artifact hash");
|
|
78
|
+
const file = path.join(this.root, `${hash}.json`);
|
|
79
|
+
// O_NOFOLLOW is unavailable on Windows. Reject reparse-point symlinks
|
|
80
|
+
// explicitly there as well, before following any artifact path.
|
|
81
|
+
if (fs.lstatSync(file).isSymbolicLink())
|
|
82
|
+
throw new ContinuityError("invalid", "unsafe retrieval artifact symlink");
|
|
83
|
+
let fd;
|
|
84
|
+
try {
|
|
85
|
+
fd = fs.openSync(file, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (error.code === "ELOOP")
|
|
89
|
+
throw new ContinuityError("invalid", "unsafe retrieval artifact symlink");
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
let text;
|
|
93
|
+
try {
|
|
94
|
+
const stat = fs.fstatSync(fd);
|
|
95
|
+
if (!stat.isFile() || stat.size > 32_000_000)
|
|
96
|
+
throw new ContinuityError("invalid", "unsafe or oversized retrieval artifact");
|
|
97
|
+
text = fs.readFileSync(fd, "utf8");
|
|
98
|
+
this.assertRoot();
|
|
99
|
+
const current = fs.lstatSync(file);
|
|
100
|
+
if (current.isSymbolicLink() || current.ino !== stat.ino || current.dev !== stat.dev)
|
|
101
|
+
throw new ContinuityError("invalid", "unsafe retrieval artifact changed while reading");
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
fs.closeSync(fd);
|
|
105
|
+
}
|
|
106
|
+
if (digest(text) !== hash)
|
|
107
|
+
throw new ContinuityError("invalid", "retrieval artifact integrity mismatch");
|
|
108
|
+
return text;
|
|
109
|
+
}
|
|
110
|
+
assertRoot() {
|
|
111
|
+
for (const part of [".loom", ".loom/brain", ".loom/brain/artifacts"]) {
|
|
112
|
+
const dir = path.join(this.workspace, part);
|
|
113
|
+
if (fs.lstatSync(dir).isSymbolicLink() || fs.realpathSync(dir) !== dir)
|
|
114
|
+
throw new ContinuityError("invalid", "Brain artifact directory changed or became a symlink");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../../src/core/continuity/artifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** Protocol each adapter speaks. Any installed version may run; drift in the
|
|
2
|
+
* event stream shows up as missing acceptance evidence, never as success. */
|
|
3
|
+
export declare const NATIVE_PROTOCOLS: {
|
|
4
|
+
readonly codex: {
|
|
5
|
+
readonly protocol: "codex-app-server-v2";
|
|
6
|
+
readonly acceptance: "turn/start response or turn/started";
|
|
7
|
+
readonly compaction: "contextCompaction item";
|
|
8
|
+
readonly tested: readonly ["0.153.4"];
|
|
9
|
+
};
|
|
10
|
+
readonly "claude-code": {
|
|
11
|
+
readonly protocol: "claude-agent-sdk-stream-json-v1";
|
|
12
|
+
readonly acceptance: "status requesting or assistant/result output";
|
|
13
|
+
readonly compaction: "status compacting + compact_boundary";
|
|
14
|
+
readonly tested: readonly ["2.1.278"];
|
|
15
|
+
};
|
|
16
|
+
readonly opencode: {
|
|
17
|
+
readonly protocol: "opencode-serve-api-v2";
|
|
18
|
+
readonly acceptance: "prompt admitted (/api/session/{id}/prompt or /session/{id}/prompt_async 204)";
|
|
19
|
+
readonly compaction: "session.next.compaction.ended or session.compacted";
|
|
20
|
+
readonly tested: readonly ["1.18.31", "1.19.0"];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export type NativeKind = keyof typeof NATIVE_PROTOCOLS;
|
|
24
|
+
/** The harnesses native continuity speaks to, in one place. */
|
|
25
|
+
export declare const NATIVE_KINDS: NativeKind[];
|
|
26
|
+
export declare const isNativeKind: (kind: string) => kind is NativeKind;
|
|
27
|
+
export interface HarnessHealth {
|
|
28
|
+
kind: string;
|
|
29
|
+
available: boolean;
|
|
30
|
+
version: string | null;
|
|
31
|
+
/** Fixtures in this repo exercised this exact version. Informational only. */
|
|
32
|
+
tested: boolean;
|
|
33
|
+
binary: string | null;
|
|
34
|
+
fingerprint: string | null;
|
|
35
|
+
error?: string;
|
|
36
|
+
checkedAt: number;
|
|
37
|
+
}
|
|
38
|
+
/** A bounded `--version` probe. Never throws; an unreachable CLI is reported. */
|
|
39
|
+
export declare function probeHarness(kind: string, options: Record<string, unknown>): Promise<HarnessHealth>;
|
|
40
|
+
export interface HarnessTarget {
|
|
41
|
+
id: string;
|
|
42
|
+
kind: string;
|
|
43
|
+
options: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Keeps each native harness's reachability current: a probe every interval,
|
|
47
|
+
* and on demand before dispatch when the last result is older than that.
|
|
48
|
+
*/
|
|
49
|
+
export declare class HarnessMonitor {
|
|
50
|
+
private readonly targets;
|
|
51
|
+
private readonly onChange;
|
|
52
|
+
readonly intervalMs: number;
|
|
53
|
+
private readonly health;
|
|
54
|
+
private readonly inflight;
|
|
55
|
+
private timer;
|
|
56
|
+
constructor(targets: () => HarnessTarget[], onChange?: (id: string, next: HarnessHealth, previous: HarnessHealth | undefined) => void, intervalMs?: number);
|
|
57
|
+
start(): void;
|
|
58
|
+
stop(): void;
|
|
59
|
+
get(id: string): HarnessHealth | undefined;
|
|
60
|
+
report(): Record<string, HarnessHealth>;
|
|
61
|
+
pollAll(): Promise<void>;
|
|
62
|
+
/** A result no older than the poll interval; probes now when stale. */
|
|
63
|
+
ensure(id: string): Promise<HarnessHealth>;
|
|
64
|
+
private poll;
|
|
65
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { execFile } from "../process.js";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { codexBin } from "../../providers/codex/adapter.js";
|
|
5
|
+
import { claudeBin } from "../../providers/claude/adapter.js";
|
|
6
|
+
import { digest } from "./contracts.js";
|
|
7
|
+
import { probeWindowsJobs } from "../windows-jobs.js";
|
|
8
|
+
const exec = promisify(execFile);
|
|
9
|
+
/** Protocol each adapter speaks. Any installed version may run; drift in the
|
|
10
|
+
* event stream shows up as missing acceptance evidence, never as success. */
|
|
11
|
+
export const NATIVE_PROTOCOLS = {
|
|
12
|
+
codex: { protocol: "codex-app-server-v2", acceptance: "turn/start response or turn/started", compaction: "contextCompaction item", tested: ["0.153.4"] },
|
|
13
|
+
"claude-code": { protocol: "claude-agent-sdk-stream-json-v1", acceptance: "status requesting or assistant/result output", compaction: "status compacting + compact_boundary", tested: ["2.1.278"] },
|
|
14
|
+
opencode: { protocol: "opencode-serve-api-v2", acceptance: "prompt admitted (/api/session/{id}/prompt or /session/{id}/prompt_async 204)", compaction: "session.next.compaction.ended or session.compacted", tested: ["1.18.31", "1.19.0"] },
|
|
15
|
+
};
|
|
16
|
+
/** The harnesses native continuity speaks to, in one place. */
|
|
17
|
+
export const NATIVE_KINDS = Object.keys(NATIVE_PROTOCOLS);
|
|
18
|
+
export const isNativeKind = (kind) => NATIVE_KINDS.includes(kind);
|
|
19
|
+
/** A bounded `--version` probe. Never throws; an unreachable CLI is reported. */
|
|
20
|
+
export async function probeHarness(kind, options) {
|
|
21
|
+
const checkedAt = Date.now();
|
|
22
|
+
const down = (error, binary = null) => ({ kind, available: false, version: null, tested: false, binary, fingerprint: null, error, checkedAt });
|
|
23
|
+
if (process.platform === "win32") {
|
|
24
|
+
try {
|
|
25
|
+
await probeWindowsJobs();
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return down(`Windows Job Object containment is unavailable: ${error.message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (!isNativeKind(kind))
|
|
32
|
+
return down(`no native continuity protocol for ${kind}`);
|
|
33
|
+
const override = typeof options.bin === "string" ? options.bin : undefined;
|
|
34
|
+
// An opencode agent pointed at a running server is as reachable as that server.
|
|
35
|
+
if (kind === "opencode" && typeof options.baseUrl === "string" && options.baseUrl) {
|
|
36
|
+
try {
|
|
37
|
+
const url = options.baseUrl.replace(/\/$/, "");
|
|
38
|
+
let res = await fetch(`${url}/api/health`, { signal: AbortSignal.timeout(5000) });
|
|
39
|
+
if (!res.ok || !res.headers.get("content-type")?.includes("application/json"))
|
|
40
|
+
res = await fetch(`${url}/global/health`, { signal: AbortSignal.timeout(5000) });
|
|
41
|
+
if (!res.ok || !(await res.json()).healthy)
|
|
42
|
+
return down(`opencode server at ${options.baseUrl} did not report healthy`);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return down(`opencode server at ${options.baseUrl} is not reachable: ${error instanceof Error ? error.message.slice(0, 200) : String(error)}`);
|
|
46
|
+
}
|
|
47
|
+
return { kind, available: true, version: null, tested: false, binary: null,
|
|
48
|
+
fingerprint: digest(JSON.stringify([options.baseUrl, NATIVE_PROTOCOLS.opencode.protocol])), checkedAt };
|
|
49
|
+
}
|
|
50
|
+
const bin = kind === "codex" ? codexBin(override) : kind === "claude-code" ? claudeBin(override) : override ?? "opencode";
|
|
51
|
+
if (!bin)
|
|
52
|
+
return down(`${kind} CLI was not found`);
|
|
53
|
+
let version;
|
|
54
|
+
try {
|
|
55
|
+
const { stdout } = await exec(bin, ["--version"], { timeout: 5000, maxBuffer: 4096 });
|
|
56
|
+
version = stdout.match(/\b\d+\.\d+\.\d+\b/)?.[0] ?? null;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return down(`${kind} did not answer a version probe: ${error instanceof Error ? error.message.slice(0, 200) : String(error)}`, bin);
|
|
60
|
+
}
|
|
61
|
+
const profile = NATIVE_PROTOCOLS[kind];
|
|
62
|
+
const identity = fs.existsSync(bin) ? [fs.realpathSync(bin), fs.statSync(bin).size] : [bin];
|
|
63
|
+
return { kind, available: true, version, tested: version !== null && profile.tested.includes(version),
|
|
64
|
+
binary: bin, fingerprint: digest(JSON.stringify([identity, version, profile.protocol])), checkedAt };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Keeps each native harness's reachability current: a probe every interval,
|
|
68
|
+
* and on demand before dispatch when the last result is older than that.
|
|
69
|
+
*/
|
|
70
|
+
export class HarnessMonitor {
|
|
71
|
+
targets;
|
|
72
|
+
onChange;
|
|
73
|
+
intervalMs;
|
|
74
|
+
health = new Map();
|
|
75
|
+
inflight = new Map();
|
|
76
|
+
timer = null;
|
|
77
|
+
constructor(targets, onChange = () => { }, intervalMs = 20_000) {
|
|
78
|
+
this.targets = targets;
|
|
79
|
+
this.onChange = onChange;
|
|
80
|
+
this.intervalMs = intervalMs;
|
|
81
|
+
}
|
|
82
|
+
start() {
|
|
83
|
+
if (this.timer)
|
|
84
|
+
return;
|
|
85
|
+
void this.pollAll();
|
|
86
|
+
this.timer = setInterval(() => void this.pollAll(), this.intervalMs);
|
|
87
|
+
this.timer.unref?.();
|
|
88
|
+
}
|
|
89
|
+
stop() {
|
|
90
|
+
if (this.timer)
|
|
91
|
+
clearInterval(this.timer);
|
|
92
|
+
this.timer = null;
|
|
93
|
+
}
|
|
94
|
+
get(id) { return this.health.get(id); }
|
|
95
|
+
report() { return Object.fromEntries(this.health); }
|
|
96
|
+
async pollAll() {
|
|
97
|
+
const targets = this.targets().filter(t => isNativeKind(t.kind));
|
|
98
|
+
const ids = new Set(targets.map(t => t.id));
|
|
99
|
+
for (const id of [...this.health.keys()])
|
|
100
|
+
if (!ids.has(id))
|
|
101
|
+
this.health.delete(id);
|
|
102
|
+
await Promise.all(targets.map(t => this.poll(t)));
|
|
103
|
+
}
|
|
104
|
+
/** A result no older than the poll interval; probes now when stale. */
|
|
105
|
+
async ensure(id) {
|
|
106
|
+
const cached = this.health.get(id);
|
|
107
|
+
if (cached && Date.now() - cached.checkedAt < this.intervalMs)
|
|
108
|
+
return cached;
|
|
109
|
+
const target = this.targets().find(t => t.id === id);
|
|
110
|
+
if (!target)
|
|
111
|
+
return { kind: "unknown", available: false, version: null, tested: false, binary: null, fingerprint: null, error: `no agent "${id}"`, checkedAt: Date.now() };
|
|
112
|
+
return this.poll(target);
|
|
113
|
+
}
|
|
114
|
+
poll(target) {
|
|
115
|
+
const pending = this.inflight.get(target.id);
|
|
116
|
+
if (pending)
|
|
117
|
+
return pending;
|
|
118
|
+
const probe = probeHarness(target.kind, target.options).then(next => {
|
|
119
|
+
const previous = this.health.get(target.id);
|
|
120
|
+
this.health.set(target.id, next);
|
|
121
|
+
if (!previous || previous.available !== next.available || previous.version !== next.version)
|
|
122
|
+
this.onChange(target.id, next, previous);
|
|
123
|
+
return next;
|
|
124
|
+
}).finally(() => this.inflight.delete(target.id));
|
|
125
|
+
this.inflight.set(target.id, probe);
|
|
126
|
+
return probe;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/core/continuity/capabilities.ts"],"names":[],"mappings":"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"}
|