@loompad/cli 0.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +96 -11
- package/CHANGELOG.md +1042 -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 +4643 -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/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,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Loom observability layer: folds LoomEvents into OpenTelemetry signals
|
|
3
|
+
* and ships them over OTLP. One process-wide config, three exporters.
|
|
4
|
+
*
|
|
5
|
+
* Mapping (LoomEvent → span, GenAI semantic conventions where they apply):
|
|
6
|
+
* run_complete → gen_ai.agent.turn (duration, cost, tokens, model)
|
|
7
|
+
* tool_call → gen_ai.tool.call
|
|
8
|
+
* handoff → loom.baton.handoff
|
|
9
|
+
* route_* → loom.route.<phase>
|
|
10
|
+
* memory_add/update/forget→ loom.memory.<op>
|
|
11
|
+
* error → span with ERROR status
|
|
12
|
+
*
|
|
13
|
+
* Metrics (LoomEvent → datapoint, see ./metrics.ts for names and temporality):
|
|
14
|
+
* run_complete → gen_ai.client.token.usage, gen_ai.client.operation.duration,
|
|
15
|
+
* loom.turns, loom.cost.usd (only if reported)
|
|
16
|
+
* status turn_started → loom.agents.active
|
|
17
|
+
* handoff → loom.handoffs
|
|
18
|
+
*
|
|
19
|
+
* Logs (LoomEvent → log record, see ./logs.ts): the event stream itself,
|
|
20
|
+
* correlated to the turn's trace so a span links to what the agent said.
|
|
21
|
+
*
|
|
22
|
+
* One event can produce all three. Callers still only call recordAgentEvent().
|
|
23
|
+
*/
|
|
24
|
+
import { LoomTelemetry, newTraceId, resolveTelemetryConfig } from "./otlp.js";
|
|
25
|
+
import { LoomMetrics } from "./metrics.js";
|
|
26
|
+
import { LoomLogs, eventToLogRecord } from "./logs.js";
|
|
27
|
+
let singleton = null;
|
|
28
|
+
let metricsSingleton = null;
|
|
29
|
+
let logsSingleton = null;
|
|
30
|
+
let sharedConfig = null;
|
|
31
|
+
// One trace per agent turn: minted when a turn starts, reused by every span in
|
|
32
|
+
// that turn (tool calls, the completion), cleared when it ends — so the backend
|
|
33
|
+
// shows a real span tree per turn instead of one orphan span per event.
|
|
34
|
+
const turnTrace = new Map();
|
|
35
|
+
/**
|
|
36
|
+
* The trace of the turn that most recently CLOSED, per agent. The decision
|
|
37
|
+
* miner runs off `run_complete` — i.e. after the turn's trace has been retired
|
|
38
|
+
* — and still needs the id to link each decision to the spans it came out of.
|
|
39
|
+
* One entry per agent, so this is bounded by the roster, not by history.
|
|
40
|
+
*/
|
|
41
|
+
const lastTurnTrace = new Map();
|
|
42
|
+
/**
|
|
43
|
+
* The trace id a span belongs to, advancing the per-agent turn as it goes.
|
|
44
|
+
*
|
|
45
|
+
* Also reports the turn boundary it just crossed, because the trace map is
|
|
46
|
+
* already the one place that knows where an agent's turn begins and ends.
|
|
47
|
+
* `opened` is true on the event that started a turn, `closed` on the one that
|
|
48
|
+
* ended it — which is what the active-agents gauge counts.
|
|
49
|
+
*/
|
|
50
|
+
function traceIdFor(event) {
|
|
51
|
+
const agent = event.agentId ?? "";
|
|
52
|
+
const isTurnStart = event.kind === "status" && event.payload?.state === "turn_started";
|
|
53
|
+
const opened = isTurnStart || !turnTrace.has(agent);
|
|
54
|
+
if (opened)
|
|
55
|
+
turnTrace.set(agent, newTraceId());
|
|
56
|
+
const traceId = turnTrace.get(agent);
|
|
57
|
+
// A turn ends when it completes — or when it dies. An adapter that throws
|
|
58
|
+
// emits `error` and may never reach run_complete; treating only the happy
|
|
59
|
+
// path as an ending would leave the trace (and the gauge) open forever.
|
|
60
|
+
const closed = event.kind === "run_complete" || event.kind === "error";
|
|
61
|
+
if (closed) {
|
|
62
|
+
lastTurnTrace.set(agent, traceId);
|
|
63
|
+
turnTrace.delete(agent); // this span closes the turn
|
|
64
|
+
}
|
|
65
|
+
return { traceId, opened, closed };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The trace id of an agent's in-flight turn, or the one that just finished.
|
|
69
|
+
*
|
|
70
|
+
* Undefined when telemetry is off, because then no trace was ever minted and
|
|
71
|
+
* there is nothing in the backend to link to. Callers must leave the field out
|
|
72
|
+
* rather than substituting "" — an empty trace id renders as a link that opens
|
|
73
|
+
* a search for nothing, which reads as a broken feature rather than an absent
|
|
74
|
+
* one.
|
|
75
|
+
*/
|
|
76
|
+
export function turnTraceId(agentId) {
|
|
77
|
+
return turnTrace.get(agentId) ?? lastTurnTrace.get(agentId);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* One resolved config for all three signals.
|
|
81
|
+
*
|
|
82
|
+
* Resolved once and shared so traces, metrics and logs can never disagree about
|
|
83
|
+
* the endpoint or the service name — a metric filed under a different
|
|
84
|
+
* service.name than its trace is invisible in the backend's service view, and
|
|
85
|
+
* that failure is silent.
|
|
86
|
+
*/
|
|
87
|
+
function config() {
|
|
88
|
+
if (!sharedConfig)
|
|
89
|
+
sharedConfig = resolveTelemetryConfig();
|
|
90
|
+
return sharedConfig;
|
|
91
|
+
}
|
|
92
|
+
export function telemetry() {
|
|
93
|
+
if (!singleton)
|
|
94
|
+
singleton = new LoomTelemetry(config());
|
|
95
|
+
return singleton;
|
|
96
|
+
}
|
|
97
|
+
export function metrics() {
|
|
98
|
+
if (!metricsSingleton)
|
|
99
|
+
metricsSingleton = new LoomMetrics(config());
|
|
100
|
+
return metricsSingleton;
|
|
101
|
+
}
|
|
102
|
+
export function logs() {
|
|
103
|
+
if (!logsSingleton)
|
|
104
|
+
logsSingleton = new LoomLogs(config());
|
|
105
|
+
return logsSingleton;
|
|
106
|
+
}
|
|
107
|
+
/** Push every buffered signal now — for shutdown, and for tests that assert. */
|
|
108
|
+
export function flushTelemetry() {
|
|
109
|
+
singleton?.flush();
|
|
110
|
+
metricsSingleton?.flush();
|
|
111
|
+
logsSingleton?.flush();
|
|
112
|
+
}
|
|
113
|
+
const MS_TO_NS = 1000000n;
|
|
114
|
+
function nsWindow(endMs, durationMs) {
|
|
115
|
+
const end = BigInt(Math.max(0, Math.round(endMs)));
|
|
116
|
+
const dur = BigInt(Math.max(0, Math.round(durationMs)));
|
|
117
|
+
return { startNs: (end - dur) * MS_TO_NS, endNs: end * MS_TO_NS };
|
|
118
|
+
}
|
|
119
|
+
function num(v) {
|
|
120
|
+
const n = Number(v);
|
|
121
|
+
return Number.isFinite(n) ? n : undefined;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Pure mapper: a LoomEvent → the span it should emit, or null for kinds that
|
|
125
|
+
* aren't telemetry-worthy. Exported so the mapping is unit-testable without a
|
|
126
|
+
* live exporter or collector.
|
|
127
|
+
*/
|
|
128
|
+
export function eventToSpan(event, ctx = {}) {
|
|
129
|
+
const p = event.payload ?? {};
|
|
130
|
+
const base = {
|
|
131
|
+
"loom.project": ctx.project,
|
|
132
|
+
"loom.chat": event.chat,
|
|
133
|
+
"loom.event.kind": event.kind,
|
|
134
|
+
"gen_ai.agent.id": event.agentId,
|
|
135
|
+
};
|
|
136
|
+
switch (event.kind) {
|
|
137
|
+
case "run_complete": {
|
|
138
|
+
const durationMs = num(p.durationMs) ?? 0;
|
|
139
|
+
return {
|
|
140
|
+
name: "gen_ai.agent.turn",
|
|
141
|
+
...nsWindow(event.ts, durationMs),
|
|
142
|
+
attributes: {
|
|
143
|
+
...base,
|
|
144
|
+
"gen_ai.system": str(p.adapter) || str(p.system) || "loom",
|
|
145
|
+
"gen_ai.operation.name": "chat",
|
|
146
|
+
"gen_ai.request.model": str(p.model) || undefined,
|
|
147
|
+
"gen_ai.usage.input_tokens": num(p.tokensIn) ?? num(p.inputTokens),
|
|
148
|
+
"gen_ai.usage.output_tokens": num(p.tokensOut) ?? num(p.outputTokens),
|
|
149
|
+
"gen_ai.usage.cost_usd": num(p.costUsd),
|
|
150
|
+
"loom.turn.duration_ms": durationMs,
|
|
151
|
+
},
|
|
152
|
+
error: p.error ? str(p.error) : undefined,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
case "tool_call":
|
|
156
|
+
return {
|
|
157
|
+
name: "gen_ai.tool.call",
|
|
158
|
+
...nsWindow(event.ts, num(p.durationMs) ?? 0),
|
|
159
|
+
attributes: { ...base, "gen_ai.tool.name": str(p.tool) || str(p.name) || "tool" },
|
|
160
|
+
};
|
|
161
|
+
case "handoff":
|
|
162
|
+
return {
|
|
163
|
+
name: "loom.baton.handoff",
|
|
164
|
+
...nsWindow(event.ts, 0),
|
|
165
|
+
attributes: {
|
|
166
|
+
...base,
|
|
167
|
+
"loom.handoff.to": str(p.to) || str(p.agent),
|
|
168
|
+
"loom.handoff.from": str(p.from) || event.agentId,
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
case "route_started":
|
|
172
|
+
case "route_step":
|
|
173
|
+
case "route_paused":
|
|
174
|
+
case "route_resumed":
|
|
175
|
+
case "route_completed":
|
|
176
|
+
case "route_failed":
|
|
177
|
+
return {
|
|
178
|
+
name: `loom.route.${event.kind.slice("route_".length)}`,
|
|
179
|
+
...nsWindow(event.ts, num(p.durationMs) ?? 0),
|
|
180
|
+
attributes: { ...base, "loom.route.id": str(p.routeId) || str(p.id) },
|
|
181
|
+
error: event.kind === "route_failed" ? str(p.error) || "route failed" : undefined,
|
|
182
|
+
};
|
|
183
|
+
case "memory_add":
|
|
184
|
+
case "memory_update":
|
|
185
|
+
case "memory_forget":
|
|
186
|
+
return {
|
|
187
|
+
name: `loom.memory.${event.kind.slice("memory_".length)}`,
|
|
188
|
+
...nsWindow(event.ts, 0),
|
|
189
|
+
attributes: {
|
|
190
|
+
...base,
|
|
191
|
+
"loom.memory.kind": str(p.kind) || str(p.type),
|
|
192
|
+
"loom.memory.scope": str(p.scope),
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
case "error":
|
|
196
|
+
return { name: "loom.error", ...nsWindow(event.ts, 0), attributes: base, error: str(p.message) || "error" };
|
|
197
|
+
default:
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Pure mapper: a LoomEvent → the datapoints it should produce.
|
|
203
|
+
*
|
|
204
|
+
* The rule that governs every branch: a number goes out only if the event
|
|
205
|
+
* carried it. An adapter that reports tokens but no cost produces token
|
|
206
|
+
* datapoints and no cost datapoint — not a cost datapoint of 0. Codex is
|
|
207
|
+
* exactly this case, and the reasoning is written out at the top of
|
|
208
|
+
* src/adapters/codex.ts: a fake $0.001 presented as fact is worse than a blank.
|
|
209
|
+
* On a counter it is worse still, because zeros are indistinguishable from real
|
|
210
|
+
* cheap turns once summed, and the total then reads as authoritative.
|
|
211
|
+
*/
|
|
212
|
+
export function eventToMetrics(event) {
|
|
213
|
+
const p = event.payload ?? {};
|
|
214
|
+
const ops = [];
|
|
215
|
+
if (event.kind === "run_complete") {
|
|
216
|
+
const agent = event.agentId;
|
|
217
|
+
const model = str(p.model) || undefined;
|
|
218
|
+
const system = str(p.adapter) || str(p.system) || undefined;
|
|
219
|
+
// The GenAI convention's dimensions. `gen_ai.operation.name` is "chat"
|
|
220
|
+
// because that is what an agent turn is under the convention's vocabulary.
|
|
221
|
+
const genai = {
|
|
222
|
+
"gen_ai.agent.id": agent,
|
|
223
|
+
"gen_ai.request.model": model,
|
|
224
|
+
"gen_ai.system": system,
|
|
225
|
+
"gen_ai.operation.name": "chat",
|
|
226
|
+
};
|
|
227
|
+
const tokensIn = num(p.tokensIn) ?? num(p.inputTokens);
|
|
228
|
+
const tokensOut = num(p.tokensOut) ?? num(p.outputTokens);
|
|
229
|
+
// > 0 rather than != null: adapters that don't track usage write a literal
|
|
230
|
+
// 0 into these fields (see runtime.trackCost), and a 0-token turn is not a
|
|
231
|
+
// thing that happens. Counting those would report a busy agent as free.
|
|
232
|
+
if (tokensIn !== undefined && tokensIn > 0) {
|
|
233
|
+
ops.push({ op: "count", name: "gen_ai.client.token.usage", value: tokensIn, isInt: true, attributes: { ...genai, "gen_ai.token.type": "input" } });
|
|
234
|
+
}
|
|
235
|
+
if (tokensOut !== undefined && tokensOut > 0) {
|
|
236
|
+
ops.push({ op: "count", name: "gen_ai.client.token.usage", value: tokensOut, isInt: true, attributes: { ...genai, "gen_ai.token.type": "output" } });
|
|
237
|
+
}
|
|
238
|
+
const durationMs = num(p.durationMs);
|
|
239
|
+
if (durationMs !== undefined && durationMs >= 0) {
|
|
240
|
+
// The convention specifies seconds, not milliseconds. Loom measures in
|
|
241
|
+
// ms everywhere else; convert here rather than shipping a metric that
|
|
242
|
+
// says "s" and holds ms.
|
|
243
|
+
ops.push({ op: "histogram", name: "gen_ai.client.operation.duration", value: durationMs / 1000, attributes: genai });
|
|
244
|
+
}
|
|
245
|
+
ops.push({
|
|
246
|
+
op: "count",
|
|
247
|
+
name: "loom.turns",
|
|
248
|
+
value: 1,
|
|
249
|
+
isInt: true,
|
|
250
|
+
attributes: { "gen_ai.agent.id": agent, "gen_ai.request.model": model, "gen_ai.system": system, status: p.error ? "error" : "ok" },
|
|
251
|
+
});
|
|
252
|
+
const costUsd = num(p.costUsd);
|
|
253
|
+
// Present, finite and positive — the three things that make it a real
|
|
254
|
+
// reported spend rather than a placeholder. Anything else emits nothing.
|
|
255
|
+
if (costUsd !== undefined && costUsd > 0) {
|
|
256
|
+
ops.push({ op: "count", name: "loom.cost.usd", value: costUsd, isInt: false, attributes: { "gen_ai.agent.id": agent, "gen_ai.request.model": model, "gen_ai.system": system } });
|
|
257
|
+
}
|
|
258
|
+
return ops;
|
|
259
|
+
}
|
|
260
|
+
if (event.kind === "handoff") {
|
|
261
|
+
ops.push({
|
|
262
|
+
op: "count",
|
|
263
|
+
name: "loom.handoffs",
|
|
264
|
+
value: 1,
|
|
265
|
+
isInt: true,
|
|
266
|
+
attributes: {
|
|
267
|
+
"loom.handoff.from": str(p.from) || event.agentId || undefined,
|
|
268
|
+
"loom.handoff.to": str(p.to) || str(p.agent) || undefined,
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return ops;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Agents with a turn in flight.
|
|
276
|
+
*
|
|
277
|
+
* Driven by the turn boundaries `traceIdFor` already computes, NOT by the
|
|
278
|
+
* `turn_started` status event. Only some adapters emit that status — codex,
|
|
279
|
+
* grok, claude-code and the antigravity bridge do; echo, opencode and the
|
|
280
|
+
* antigravity CLI never do — so a gauge keyed on it would read zero for half
|
|
281
|
+
* the roster while those agents were demonstrably working. A turn's trace
|
|
282
|
+
* opening is the one signal that holds for every adapter, because it is
|
|
283
|
+
* derived from the events rather than announced by them.
|
|
284
|
+
*
|
|
285
|
+
* Held here rather than asked of the daemon because this module must not reach
|
|
286
|
+
* into the runtime, and because the answer has to be derived from events for
|
|
287
|
+
* the same reason every other number is.
|
|
288
|
+
*/
|
|
289
|
+
const activeAgents = new Set();
|
|
290
|
+
/** Maintain the active set, returning true when it actually moved. */
|
|
291
|
+
function trackActive(agent, opened, closed) {
|
|
292
|
+
if (!agent)
|
|
293
|
+
return false; // human and system events are nobody's turn
|
|
294
|
+
if (closed)
|
|
295
|
+
return activeAgents.delete(agent);
|
|
296
|
+
if (opened && !activeAgents.has(agent)) {
|
|
297
|
+
activeAgents.add(agent);
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Record one live agent event, fanning it out to every enabled signal.
|
|
304
|
+
*
|
|
305
|
+
* Best-effort and non-throwing: observability must never break the agent loop.
|
|
306
|
+
* The three signals are independent — logs off still means traces and metrics —
|
|
307
|
+
* so each checks its own switch, and the shared trace id is minted once so a
|
|
308
|
+
* log record can point at the span covering the same event.
|
|
309
|
+
*/
|
|
310
|
+
export function recordAgentEvent(event, ctx = {}) {
|
|
311
|
+
try {
|
|
312
|
+
const t = telemetry();
|
|
313
|
+
const m = metrics();
|
|
314
|
+
const l = logs();
|
|
315
|
+
if (!t.enabled && !m.enabled && !l.enabled)
|
|
316
|
+
return;
|
|
317
|
+
// Advance the per-agent turn trace for every event, whatever is enabled —
|
|
318
|
+
// it is the id logs correlate on, not just a trace-exporter detail.
|
|
319
|
+
const { traceId, opened, closed } = traceIdFor(event);
|
|
320
|
+
const span = eventToSpan(event, ctx);
|
|
321
|
+
const spanId = span ? t.span({ ...span, traceId }) : undefined;
|
|
322
|
+
if (l.enabled) {
|
|
323
|
+
const record = eventToLogRecord(event, ctx);
|
|
324
|
+
// traceId always; spanId only when this event really produced that span.
|
|
325
|
+
// Pointing a log at a span id we invented would be a link to nothing.
|
|
326
|
+
if (record)
|
|
327
|
+
l.log({ ...record, traceId, ...(spanId ? { spanId } : {}) });
|
|
328
|
+
}
|
|
329
|
+
if (m.enabled) {
|
|
330
|
+
for (const op of eventToMetrics(event)) {
|
|
331
|
+
if (op.op === "count")
|
|
332
|
+
m.addCount(op.name, op.value, { ...op.attributes, "loom.project": ctx.project }, op.isInt);
|
|
333
|
+
else
|
|
334
|
+
m.record(op.name, op.value, { ...op.attributes, "loom.project": ctx.project });
|
|
335
|
+
}
|
|
336
|
+
if (trackActive(event.agentId, opened, closed)) {
|
|
337
|
+
m.setGauge("loom.agents.active", activeAgents.size, { "loom.project": ctx.project });
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
/* never let telemetry throw into the agent loop */
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function str(v) {
|
|
346
|
+
return typeof v === "string" ? v : v == null ? "" : String(v);
|
|
347
|
+
}
|
|
348
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observatory insights, read back from the backend's ClickHouse store: the spans
|
|
3
|
+
* behind the Span Replay viewer and the Trace Waterfall, the per-agent burn-rate
|
|
4
|
+
* series, and a deterministic 0–100 Agent Health Score. All of it is derived from
|
|
5
|
+
* the same real gen_ai spans Loom exports — nothing here is synthetic.
|
|
6
|
+
*
|
|
7
|
+
* The scoring (`healthScore`) is a pure function so it is unit-tested without a
|
|
8
|
+
* live ClickHouse, and it is the same math the UI badges render.
|
|
9
|
+
*/
|
|
10
|
+
import type { LoomEvent } from "../types.js";
|
|
11
|
+
export type InsightSpan = {
|
|
12
|
+
traceId: string;
|
|
13
|
+
spanId: string;
|
|
14
|
+
ts: number;
|
|
15
|
+
name: string;
|
|
16
|
+
ms: number;
|
|
17
|
+
code: number;
|
|
18
|
+
msg: string;
|
|
19
|
+
agent: string;
|
|
20
|
+
ade: string;
|
|
21
|
+
model: string;
|
|
22
|
+
tin: number;
|
|
23
|
+
tout: number;
|
|
24
|
+
cost: number;
|
|
25
|
+
handoffFrom: string;
|
|
26
|
+
handoffTo: string;
|
|
27
|
+
};
|
|
28
|
+
/** Recent spans for a project (optionally one agent), newest first. */
|
|
29
|
+
export declare function fetchSpans(project: string, opts?: {
|
|
30
|
+
agent?: string;
|
|
31
|
+
limit?: number;
|
|
32
|
+
}): Promise<InsightSpan[]>;
|
|
33
|
+
/** How many error spans an agent has emitted since `sinceMs` — the self-heal recheck signal. */
|
|
34
|
+
export declare function recentAgentErrors(project: string, agent: string, sinceMs: number): Promise<number>;
|
|
35
|
+
/** Every span in one trace, oldest first — the waterfall's rows. */
|
|
36
|
+
export declare function traceSpans(traceId: string): Promise<InsightSpan[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Fallback: derive InsightSpans from the local event log — the same data the
|
|
39
|
+
* backend gets — so the Observatory's replay/health/waterfall still work when
|
|
40
|
+
* ClickHouse is down or the agent hasn't exported anything yet.
|
|
41
|
+
*/
|
|
42
|
+
export declare function insightSpansFromLog(events: LoomEvent[], agent?: string): InsightSpan[];
|
|
43
|
+
export type BurnBucket = {
|
|
44
|
+
t: number;
|
|
45
|
+
byAgent: Record<string, number>;
|
|
46
|
+
total: number;
|
|
47
|
+
};
|
|
48
|
+
export type BurnSeries = {
|
|
49
|
+
hours: number;
|
|
50
|
+
buckets: BurnBucket[];
|
|
51
|
+
totalUsd: number;
|
|
52
|
+
/** USD/hour over the covered window, and the linear projection for 24h. */
|
|
53
|
+
ratePerHour: number;
|
|
54
|
+
projected24h: number;
|
|
55
|
+
};
|
|
56
|
+
/** Per-agent cost over time, bucketed — the burn-rate sparkline's data + a linear projection. */
|
|
57
|
+
export declare function burnSeries(project: string, opts?: {
|
|
58
|
+
hours?: number;
|
|
59
|
+
buckets?: number;
|
|
60
|
+
}): Promise<BurnSeries>;
|
|
61
|
+
/**
|
|
62
|
+
* The metric tables the collector writes into. Defaults are that layout;
|
|
63
|
+
* both are overridable for a backend that stores its metrics elsewhere.
|
|
64
|
+
*/
|
|
65
|
+
export declare const METRIC_SAMPLES_TABLE: string;
|
|
66
|
+
export declare const METRIC_SERIES_TABLE: string;
|
|
67
|
+
/** Expand each requested name to itself plus its histogram parts, deduped. */
|
|
68
|
+
export declare function expandMetricNames(names: string[]): string[];
|
|
69
|
+
export type MetricPoint = {
|
|
70
|
+
/** Bucket start, epoch ms. */
|
|
71
|
+
t: number;
|
|
72
|
+
/**
|
|
73
|
+
* Sum of the samples in the bucket. Loom's counters arrive as small
|
|
74
|
+
* per-export deltas (verified on the live stack: loom.turns reports 1/2/3,
|
|
75
|
+
* never a running total), so summing is the honest "how much happened in this
|
|
76
|
+
* window" number for a Sum-typed metric.
|
|
77
|
+
*/
|
|
78
|
+
sum: number;
|
|
79
|
+
/** Mean of the samples in the bucket — the right read for a Gauge like loom.agents.active. */
|
|
80
|
+
avg: number;
|
|
81
|
+
max: number;
|
|
82
|
+
/** How many raw samples went into the bucket, so the UI can tell thin data from zero. */
|
|
83
|
+
n: number;
|
|
84
|
+
};
|
|
85
|
+
export type MetricSeries = {
|
|
86
|
+
metric: string;
|
|
87
|
+
/** The backend's type column: "Sum" | "Gauge" | "Histogram" | "". */
|
|
88
|
+
type: string;
|
|
89
|
+
unit: string;
|
|
90
|
+
temporality: string;
|
|
91
|
+
/** The series' label set (agent id, model, project, …), internal `__*` keys stripped. */
|
|
92
|
+
labels: Record<string, string>;
|
|
93
|
+
/** ClickHouse fingerprint as a string — UInt64 overflows a JS number. */
|
|
94
|
+
fingerprint: string;
|
|
95
|
+
/** Which of sum/avg the UI should plot by default, chosen from `type`. */
|
|
96
|
+
prefer: "sum" | "avg";
|
|
97
|
+
points: MetricPoint[];
|
|
98
|
+
};
|
|
99
|
+
export type MetricQueryOpts = {
|
|
100
|
+
project: string;
|
|
101
|
+
sinceMs?: number;
|
|
102
|
+
stepMs?: number;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Build the SQL for a metric series query — split out so the join, the project
|
|
106
|
+
* filter and the bucketing are testable without a live ClickHouse.
|
|
107
|
+
*
|
|
108
|
+
* Note what the inner subquery does *not* do: filter time_series_v4 by
|
|
109
|
+
* unix_milli. That column is floored to the hour there, so a naive
|
|
110
|
+
* `>= sinceMs` would drop the metadata row for a series whose hour started
|
|
111
|
+
* before the window and take the whole series with it. The metric_name +
|
|
112
|
+
* project filters already narrow it to a handful of fingerprints, so the time
|
|
113
|
+
* filter belongs on the samples side only, where it is exact.
|
|
114
|
+
*
|
|
115
|
+
* The GROUP BY inside the subquery collapses the one-row-per-hour duplication;
|
|
116
|
+
* without it the join would multiply every sample by the number of hours the
|
|
117
|
+
* series has existed.
|
|
118
|
+
*/
|
|
119
|
+
export declare function buildMetricQuery(names: string[], opts: MetricQueryOpts): string;
|
|
120
|
+
/** Fold the flat (series, bucket) rows into one entry per series, points ordered. */
|
|
121
|
+
export declare function rowsToSeries(rows: Record<string, unknown>[]): MetricSeries[];
|
|
122
|
+
/**
|
|
123
|
+
* Read named metrics back for one project, one entry per distinct label set.
|
|
124
|
+
* Throws if ClickHouse is unreachable — like logs, there is no local substitute
|
|
125
|
+
* for a metric the backend never received, and the route reports that honestly.
|
|
126
|
+
*/
|
|
127
|
+
export declare function fetchMetricSeries(names: string[], opts: MetricQueryOpts): Promise<MetricSeries[]>;
|
|
128
|
+
/** The metrics Loom actually emits — the default set when a caller names none. */
|
|
129
|
+
export declare const LOOM_METRIC_NAMES: string[];
|
|
130
|
+
export type Health = {
|
|
131
|
+
score: number;
|
|
132
|
+
grade: "healthy" | "degraded" | "unhealthy";
|
|
133
|
+
turns: number;
|
|
134
|
+
errorCount: number;
|
|
135
|
+
buckets: {
|
|
136
|
+
errorRate: number;
|
|
137
|
+
latency: number;
|
|
138
|
+
tokenBloat: number;
|
|
139
|
+
recency: number;
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* A deterministic 0–100 health score from an agent's own spans. Four penalty
|
|
144
|
+
* buckets subtract from 100:
|
|
145
|
+
* errorRate (≤40) — share of spans that errored
|
|
146
|
+
* latency (≤25) — share of turns slower than 30s
|
|
147
|
+
* tokenBloat(≤20) — average input tokens above an 80k comfort line
|
|
148
|
+
* recency (≤15) — how recently the last error fired (fades over 30 min)
|
|
149
|
+
* Pure: same input, same score — this is what the UI badge shows.
|
|
150
|
+
*/
|
|
151
|
+
export declare function healthScore(spans: InsightSpan[], now?: number): Health;
|