@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,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every agent working for an orchestrator, in one list: the tasks of an
|
|
3
|
+
* Orchestra run, the entrants of a race, the teammates of a crew. The desktop
|
|
4
|
+
* opens it as a "Subagents" tab when a goal starts, and the phone shows the
|
|
5
|
+
* same list — who is working right now, who has finished, and a way into each
|
|
6
|
+
* one's own thread.
|
|
7
|
+
*/
|
|
8
|
+
/** A report as one plain line: markdown marks and runs of whitespace gone. */
|
|
9
|
+
function oneLine(md) {
|
|
10
|
+
return md.replace(/```[\s\S]*?```/g, " ").replace(/[*_`#>]+/g, "").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\s+/g, " ").trim().slice(0, 160);
|
|
11
|
+
}
|
|
12
|
+
const ACTIVE = new Set(["running", "asks", "pending"]);
|
|
13
|
+
function taskStatus(s) {
|
|
14
|
+
if (s === "running")
|
|
15
|
+
return "running";
|
|
16
|
+
if (s === "needs_input")
|
|
17
|
+
return "asks";
|
|
18
|
+
if (s === "pending")
|
|
19
|
+
return "pending";
|
|
20
|
+
if (s === "done")
|
|
21
|
+
return "done";
|
|
22
|
+
if (s === "cancelled")
|
|
23
|
+
return "cancelled";
|
|
24
|
+
return "failed"; // failed, conflict
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @param lastActivity chat id → latest event time, so a teammate's "when" is
|
|
28
|
+
* its last word rather than when the goal began.
|
|
29
|
+
* @param recentRuns how many Orchestra runs back to include (newest first).
|
|
30
|
+
*/
|
|
31
|
+
export function subagents(runs, crews, lastActivity, opts = {}) {
|
|
32
|
+
const out = [];
|
|
33
|
+
const recent = [...runs].sort((a, b) => (b.updatedAt ?? b.createdAt) - (a.updatedAt ?? a.createdAt)).slice(0, opts.recentRuns ?? 5);
|
|
34
|
+
for (const run of recent) {
|
|
35
|
+
const live = run.status !== "completed" && run.status !== "failed" && run.status !== "aborted" && run.status !== "moved";
|
|
36
|
+
for (const t of run.tasks) {
|
|
37
|
+
// a task the run never started, in a run that's over, isn't a subagent anyone met
|
|
38
|
+
if (!live && t.status === "pending")
|
|
39
|
+
continue;
|
|
40
|
+
out.push({
|
|
41
|
+
id: `o:${run.id}:${t.id}`,
|
|
42
|
+
name: run.race ? `${t.agent}'s take` : t.title,
|
|
43
|
+
agentId: t.agent,
|
|
44
|
+
kind: t.kind,
|
|
45
|
+
status: taskStatus(t.status),
|
|
46
|
+
chat: t.chat,
|
|
47
|
+
source: run.race ? "race" : "orchestra",
|
|
48
|
+
goal: run.goal,
|
|
49
|
+
goalId: run.id,
|
|
50
|
+
at: Math.max(t.finishedAt ?? 0, t.startedAt ?? 0, lastActivity.get(t.chat) ?? 0, run.createdAt),
|
|
51
|
+
...(t.costUsd ? { costUsd: t.costUsd } : {}),
|
|
52
|
+
...(t.error ? { note: t.error.slice(0, 160) } : t.result ? { note: oneLine(t.result) } : {}),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const crew of crews) {
|
|
57
|
+
const goal = crew.state.goal;
|
|
58
|
+
if (!goal)
|
|
59
|
+
continue;
|
|
60
|
+
const running = goal.status === "running" || goal.status === "planning" || goal.status === "awaiting_approval" || goal.status === "waiting_human";
|
|
61
|
+
for (const tm of crew.teammates) {
|
|
62
|
+
const chat = crew.state.threads[tm.id];
|
|
63
|
+
const onIt = running && goal.current?.teammate === tm.id;
|
|
64
|
+
const asked = running && goal.question?.teammate === tm.id;
|
|
65
|
+
const card = onIt && goal.current?.card ? goal.cards.find((c) => c.id === goal.current.card) : undefined;
|
|
66
|
+
// a teammate that never spoke on a finished goal had no part in it
|
|
67
|
+
if (!running && !(chat && lastActivity.has(chat)))
|
|
68
|
+
continue;
|
|
69
|
+
out.push({
|
|
70
|
+
id: `c:${crew.id}:${tm.id}`,
|
|
71
|
+
name: `${crew.name} · ${tm.id}`,
|
|
72
|
+
agentId: tm.agent,
|
|
73
|
+
kind: opts.kindOf?.(tm.agent) ?? tm.agent,
|
|
74
|
+
status: asked ? "asks" : onIt ? "running" : running ? "pending" : goal.status === "failed" ? "failed" : goal.status === "stopped" || goal.status === "interrupted" ? "cancelled" : "done",
|
|
75
|
+
...(chat ? { chat } : {}),
|
|
76
|
+
source: "crew",
|
|
77
|
+
goal: goal.text,
|
|
78
|
+
goalId: goal.id,
|
|
79
|
+
at: Math.max((chat && lastActivity.get(chat)) || 0, goal.startedAt),
|
|
80
|
+
...(asked ? { note: goal.question.text.slice(0, 160) } : card ? { note: `${goal.current.step} · ${card.title}`.slice(0, 160) } : {}),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const newest = (a, b) => b.at - a.at;
|
|
85
|
+
return {
|
|
86
|
+
active: out.filter((s) => ACTIVE.has(s.status)).sort(newest),
|
|
87
|
+
done: out.filter((s) => !ACTIVE.has(s.status)).sort(newest).slice(0, 60),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=subagents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagents.js","sourceRoot":"","sources":["../../src/core/subagents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loom Teams, Phase 3 — canon: the memories every agent on the team treats as
|
|
3
|
+
* law, living in the repo where people review them.
|
|
4
|
+
*
|
|
5
|
+
* D44: the source of truth is a Loom-managed section of AGENTS.md on the
|
|
6
|
+
* default branch. Each line carries a hidden `<!-- loom:m:<id> -->` marker so
|
|
7
|
+
* it round-trips through Loom; a human editing or deleting a line in any PR is
|
|
8
|
+
* a real canon change, and a line a human adds by hand (no marker) is canon
|
|
9
|
+
* too. AGENTS.md is the cross-vendor convention, so agents outside Loom —
|
|
10
|
+
* Codex, Cursor, Jules, Copilot — read the same canon. D46: CLAUDE.md gets an
|
|
11
|
+
* `@AGENTS.md` import so Claude Code does as well.
|
|
12
|
+
*
|
|
13
|
+
* Pure text in, text out — the daemon does the git.
|
|
14
|
+
*/
|
|
15
|
+
import type { MemoryKind } from "./brain.js";
|
|
16
|
+
export declare const CANON_START = "<!-- loom:canon";
|
|
17
|
+
export declare const CANON_END = "<!-- /loom:canon -->";
|
|
18
|
+
export interface CanonEntry {
|
|
19
|
+
id: string;
|
|
20
|
+
kind: MemoryKind;
|
|
21
|
+
text: string;
|
|
22
|
+
}
|
|
23
|
+
/** A stable id for a line a human added without a marker. */
|
|
24
|
+
export declare function handEntryId(text: string): string;
|
|
25
|
+
/** The managed section's bounds in a document, or null when there isn't one. */
|
|
26
|
+
export declare function findSection(doc: string): {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
} | null;
|
|
30
|
+
/** Canon entries from an AGENTS.md (empty when it has no managed section). */
|
|
31
|
+
export declare function parseCanon(doc: string): CanonEntry[];
|
|
32
|
+
/** The managed section for a set of entries, grouped by kind. */
|
|
33
|
+
export declare function renderCanon(entries: CanonEntry[]): string;
|
|
34
|
+
/**
|
|
35
|
+
* Put the section into a document: replace the existing one, or append it at
|
|
36
|
+
* the end — never touching anything a human wrote outside the markers.
|
|
37
|
+
*/
|
|
38
|
+
export declare function upsertCanon(doc: string, entries: CanonEntry[]): string;
|
|
39
|
+
/** Everything a human wrote: the document with the managed section cut out. */
|
|
40
|
+
export declare function withoutCanon(doc: string): string;
|
|
41
|
+
/** D46: the CLAUDE.md line that makes Claude Code read AGENTS.md. Null when nothing to change. */
|
|
42
|
+
export declare function withClaudeImport(claudeMd: string): string | null;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loom Teams, Phase 3 — canon: the memories every agent on the team treats as
|
|
3
|
+
* law, living in the repo where people review them.
|
|
4
|
+
*
|
|
5
|
+
* D44: the source of truth is a Loom-managed section of AGENTS.md on the
|
|
6
|
+
* default branch. Each line carries a hidden `<!-- loom:m:<id> -->` marker so
|
|
7
|
+
* it round-trips through Loom; a human editing or deleting a line in any PR is
|
|
8
|
+
* a real canon change, and a line a human adds by hand (no marker) is canon
|
|
9
|
+
* too. AGENTS.md is the cross-vendor convention, so agents outside Loom —
|
|
10
|
+
* Codex, Cursor, Jules, Copilot — read the same canon. D46: CLAUDE.md gets an
|
|
11
|
+
* `@AGENTS.md` import so Claude Code does as well.
|
|
12
|
+
*
|
|
13
|
+
* Pure text in, text out — the daemon does the git.
|
|
14
|
+
*/
|
|
15
|
+
import crypto from "node:crypto";
|
|
16
|
+
export const CANON_START = "<!-- loom:canon";
|
|
17
|
+
export const CANON_END = "<!-- /loom:canon -->";
|
|
18
|
+
const HEADINGS = [
|
|
19
|
+
["constraint", "Constraints"],
|
|
20
|
+
["failure", "Known failures — don't repeat these"],
|
|
21
|
+
["decision", "Decisions"],
|
|
22
|
+
["convention", "Conventions"],
|
|
23
|
+
["fact", "Facts"],
|
|
24
|
+
];
|
|
25
|
+
function kindOfHeading(h) {
|
|
26
|
+
const t = h.toLowerCase();
|
|
27
|
+
if (t.startsWith("constraint"))
|
|
28
|
+
return "constraint";
|
|
29
|
+
if (t.startsWith("known failure") || t.startsWith("failure"))
|
|
30
|
+
return "failure";
|
|
31
|
+
if (t.startsWith("decision"))
|
|
32
|
+
return "decision";
|
|
33
|
+
if (t.startsWith("convention"))
|
|
34
|
+
return "convention";
|
|
35
|
+
return "fact";
|
|
36
|
+
}
|
|
37
|
+
/** A stable id for a line a human added without a marker. */
|
|
38
|
+
export function handEntryId(text) {
|
|
39
|
+
return "h" + crypto.createHash("sha256").update(text.trim().toLowerCase()).digest("hex").slice(0, 15);
|
|
40
|
+
}
|
|
41
|
+
/** The managed section's bounds in a document, or null when there isn't one. */
|
|
42
|
+
export function findSection(doc) {
|
|
43
|
+
const start = doc.indexOf(CANON_START);
|
|
44
|
+
if (start < 0)
|
|
45
|
+
return null;
|
|
46
|
+
const endMarker = doc.indexOf(CANON_END, start);
|
|
47
|
+
if (endMarker < 0)
|
|
48
|
+
return null;
|
|
49
|
+
return { start, end: endMarker + CANON_END.length };
|
|
50
|
+
}
|
|
51
|
+
/** Canon entries from an AGENTS.md (empty when it has no managed section). */
|
|
52
|
+
export function parseCanon(doc) {
|
|
53
|
+
const sec = findSection(doc);
|
|
54
|
+
if (!sec)
|
|
55
|
+
return [];
|
|
56
|
+
const out = [];
|
|
57
|
+
let kind = "fact";
|
|
58
|
+
for (const raw of doc.slice(sec.start, sec.end).split("\n")) {
|
|
59
|
+
const line = raw.trim();
|
|
60
|
+
const h = /^#{2,4}\s+(.+)$/.exec(line);
|
|
61
|
+
if (h) {
|
|
62
|
+
if (!/team canon/i.test(h[1]))
|
|
63
|
+
kind = kindOfHeading(h[1]);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const item = /^[-*]\s+(.+)$/.exec(line);
|
|
67
|
+
if (!item)
|
|
68
|
+
continue;
|
|
69
|
+
const marker = /<!--\s*loom:m:([A-Za-z0-9_-]{1,40})\s*-->/.exec(item[1]);
|
|
70
|
+
const text = item[1].replace(/<!--[\s\S]*?-->/g, "").trim();
|
|
71
|
+
if (!text)
|
|
72
|
+
continue;
|
|
73
|
+
out.push({ id: marker?.[1] ?? handEntryId(text), kind, text });
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
/** The managed section for a set of entries, grouped by kind. */
|
|
78
|
+
export function renderCanon(entries) {
|
|
79
|
+
const lines = [
|
|
80
|
+
`${CANON_START} — team canon, managed by Loom. Change it through a PR; each line is one thing every agent treats as settled. -->`,
|
|
81
|
+
"## Team canon",
|
|
82
|
+
"",
|
|
83
|
+
];
|
|
84
|
+
for (const [kind, heading] of HEADINGS) {
|
|
85
|
+
const items = entries.filter((e) => e.kind === kind || (kind === "fact" && e.kind === "task"));
|
|
86
|
+
if (!items.length)
|
|
87
|
+
continue;
|
|
88
|
+
lines.push(`### ${heading}`, "");
|
|
89
|
+
for (const e of items)
|
|
90
|
+
lines.push(`- ${e.text.replace(/\s+/g, " ").trim()} <!-- loom:m:${e.id} -->`);
|
|
91
|
+
lines.push("");
|
|
92
|
+
}
|
|
93
|
+
lines.push(CANON_END);
|
|
94
|
+
return lines.join("\n");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Put the section into a document: replace the existing one, or append it at
|
|
98
|
+
* the end — never touching anything a human wrote outside the markers.
|
|
99
|
+
*/
|
|
100
|
+
export function upsertCanon(doc, entries) {
|
|
101
|
+
const body = renderCanon(entries);
|
|
102
|
+
const sec = findSection(doc);
|
|
103
|
+
if (sec)
|
|
104
|
+
return doc.slice(0, sec.start) + body + doc.slice(sec.end);
|
|
105
|
+
const base = doc.replace(/\s+$/, "");
|
|
106
|
+
return (base ? `${base}\n\n` : "") + body + "\n";
|
|
107
|
+
}
|
|
108
|
+
/** Everything a human wrote: the document with the managed section cut out. */
|
|
109
|
+
export function withoutCanon(doc) {
|
|
110
|
+
const sec = findSection(doc);
|
|
111
|
+
if (!sec)
|
|
112
|
+
return doc;
|
|
113
|
+
return (doc.slice(0, sec.start) + doc.slice(sec.end)).replace(/\n{3,}/g, "\n\n").trim();
|
|
114
|
+
}
|
|
115
|
+
/** D46: the CLAUDE.md line that makes Claude Code read AGENTS.md. Null when nothing to change. */
|
|
116
|
+
export function withClaudeImport(claudeMd) {
|
|
117
|
+
if (/^\s*@AGENTS\.md\s*$/m.test(claudeMd))
|
|
118
|
+
return null;
|
|
119
|
+
return `${claudeMd.replace(/\s+$/, "")}\n\n@AGENTS.md\n`;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=team-canon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-canon.js","sourceRoot":"","sources":["../../src/core/team-canon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loom Teams — the cryptography, all of it in one small file.
|
|
3
|
+
*
|
|
4
|
+
* Decisions this implements (docs/teams-architecture.md §1a):
|
|
5
|
+
* D2 content is end-to-end encrypted to the team; metadata stays plain
|
|
6
|
+
* D5 the team key rides the invite link's #fragment
|
|
7
|
+
* D6 leaving rotates the key forward, sealed to each remaining device
|
|
8
|
+
*
|
|
9
|
+
* Primitives, all audited pure-JS (@noble/*), so the phone runs the same code:
|
|
10
|
+
* - team key: 32 random bytes, versioned; content is XChaCha20-Poly1305
|
|
11
|
+
* (the relay's seal/open), bound to the team + key version as AAD-by-prefix
|
|
12
|
+
* - device keys: X25519 (sealing) + Ed25519 (signing), generated per device
|
|
13
|
+
* - sealed box: ephemeral X25519 → HKDF-SHA256 → XChaCha20-Poly1305, so a
|
|
14
|
+
* new team key can be handed to a device knowing only its public key
|
|
15
|
+
* - signatures: Ed25519 over the canonical JSON of what a daemon publishes
|
|
16
|
+
*/
|
|
17
|
+
export interface TeamKey {
|
|
18
|
+
version: number;
|
|
19
|
+
key: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function newTeamKey(version?: number): TeamKey;
|
|
22
|
+
/** A sealed value as stored on the hub: which key version, and the ciphertext. */
|
|
23
|
+
export interface Sealed {
|
|
24
|
+
v: number;
|
|
25
|
+
c: string;
|
|
26
|
+
}
|
|
27
|
+
/** Encrypt any JSON value to the team. The hub stores this and can't read it. */
|
|
28
|
+
export declare function sealForTeam(key: TeamKey, value: unknown): Sealed;
|
|
29
|
+
/** Decrypt with whichever key version sealed it; null if unknown or tampered. */
|
|
30
|
+
export declare function openFromTeam<T = unknown>(keys: TeamKey[], sealed: Sealed | null | undefined): T | null;
|
|
31
|
+
export interface DeviceKeys {
|
|
32
|
+
/** X25519 — others seal team keys to this. */
|
|
33
|
+
sealPub: string;
|
|
34
|
+
sealPriv: string;
|
|
35
|
+
/** Ed25519 — this device signs what it publishes. */
|
|
36
|
+
signPub: string;
|
|
37
|
+
signPriv: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function newDeviceKeys(): DeviceKeys;
|
|
40
|
+
/** Seal bytes to a device's X25519 public key. Only that device can open it. */
|
|
41
|
+
export declare function sealTo(recipientSealPub: string, plaintext: Uint8Array): string;
|
|
42
|
+
export declare function openSealed(device: Pick<DeviceKeys, "sealPriv" | "sealPub">, box: string): Uint8Array | null;
|
|
43
|
+
/** Seal a team key to a device — the envelope the hub stores per device. */
|
|
44
|
+
export declare function sealTeamKey(recipientSealPub: string, key: TeamKey): string;
|
|
45
|
+
export declare function openTeamKey(device: Pick<DeviceKeys, "sealPriv" | "sealPub">, envelope: string): TeamKey | null;
|
|
46
|
+
/** Deterministic JSON: sorted keys, so signer and verifier hash the same bytes. */
|
|
47
|
+
export declare function canonicalJson(v: unknown): string;
|
|
48
|
+
export declare function signPayload(device: Pick<DeviceKeys, "signPriv">, payload: unknown): string;
|
|
49
|
+
export declare function verifyPayload(signPub: string, payload: unknown, sig: string): boolean;
|
|
50
|
+
/** What an invite link's #fragment carries: the invite token and the team key. */
|
|
51
|
+
export interface InviteFragment {
|
|
52
|
+
invite: string;
|
|
53
|
+
key: TeamKey;
|
|
54
|
+
hub: string;
|
|
55
|
+
/**
|
|
56
|
+
* One-link onboarding (daemon/onboard.ts): what the link sets up besides
|
|
57
|
+
* team membership. All optional — a bare team invite is still an invite.
|
|
58
|
+
*/
|
|
59
|
+
teamId?: string;
|
|
60
|
+
team?: string;
|
|
61
|
+
/** The GitHub repo ("owner/name") to clone and open as a project. */
|
|
62
|
+
repo?: string;
|
|
63
|
+
/** The inviter's GitHub login, for "invited by". */
|
|
64
|
+
from?: string;
|
|
65
|
+
/** The inviter's project name, used as the joiner's when it clones. */
|
|
66
|
+
project?: string;
|
|
67
|
+
/** Crews to set up on the joiner's side, filled from the joiner's own agents. */
|
|
68
|
+
crews?: Array<{
|
|
69
|
+
name: string;
|
|
70
|
+
planApproval?: boolean;
|
|
71
|
+
teammates: Array<{
|
|
72
|
+
id: string;
|
|
73
|
+
role: string;
|
|
74
|
+
kind?: string;
|
|
75
|
+
charter?: string;
|
|
76
|
+
}>;
|
|
77
|
+
}>;
|
|
78
|
+
/**
|
|
79
|
+
* The inviter's device signature over everything above but the key (and
|
|
80
|
+
* which device signed). Anyone holding the link holds the key, so only a
|
|
81
|
+
* device signature — checked against the inviter's registered device after
|
|
82
|
+
* joining — proves the repo and crews are what the inviter put there.
|
|
83
|
+
*/
|
|
84
|
+
sig?: string;
|
|
85
|
+
dev?: string;
|
|
86
|
+
}
|
|
87
|
+
/** What an invite's signature covers. */
|
|
88
|
+
export declare function inviteSigned(f: InviteFragment): Record<string, unknown>;
|
|
89
|
+
export declare function packInvite(f: InviteFragment): string;
|
|
90
|
+
export declare function unpackInvite(s: string): InviteFragment | null;
|
|
91
|
+
/**
|
|
92
|
+
* A team memory's dedupe key: HMAC-SHA256 of its normalized text under the
|
|
93
|
+
* team key. The hub merges exact duplicates by comparing these without ever
|
|
94
|
+
* reading the text. Prefixed with the key version — after a rotation, a
|
|
95
|
+
* memory only merges with others hashed under the same key.
|
|
96
|
+
*/
|
|
97
|
+
export declare function memoryHmac(key: TeamKey, text: string): string;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loom Teams — the cryptography, all of it in one small file.
|
|
3
|
+
*
|
|
4
|
+
* Decisions this implements (docs/teams-architecture.md §1a):
|
|
5
|
+
* D2 content is end-to-end encrypted to the team; metadata stays plain
|
|
6
|
+
* D5 the team key rides the invite link's #fragment
|
|
7
|
+
* D6 leaving rotates the key forward, sealed to each remaining device
|
|
8
|
+
*
|
|
9
|
+
* Primitives, all audited pure-JS (@noble/*), so the phone runs the same code:
|
|
10
|
+
* - team key: 32 random bytes, versioned; content is XChaCha20-Poly1305
|
|
11
|
+
* (the relay's seal/open), bound to the team + key version as AAD-by-prefix
|
|
12
|
+
* - device keys: X25519 (sealing) + Ed25519 (signing), generated per device
|
|
13
|
+
* - sealed box: ephemeral X25519 → HKDF-SHA256 → XChaCha20-Poly1305, so a
|
|
14
|
+
* new team key can be handed to a device knowing only its public key
|
|
15
|
+
* - signatures: Ed25519 over the canonical JSON of what a daemon publishes
|
|
16
|
+
*/
|
|
17
|
+
import { xchacha20poly1305 } from "@noble/ciphers/chacha.js";
|
|
18
|
+
import { randomBytes } from "@noble/ciphers/utils.js";
|
|
19
|
+
import { ed25519, x25519 } from "@noble/curves/ed25519.js";
|
|
20
|
+
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
21
|
+
import { hmac } from "@noble/hashes/hmac.js";
|
|
22
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
23
|
+
import { fromB64, toB64 } from "./relay-protocol.js";
|
|
24
|
+
const enc = new TextEncoder();
|
|
25
|
+
const dec = new TextDecoder();
|
|
26
|
+
export function newTeamKey(version = 1) {
|
|
27
|
+
return { version, key: toB64(randomBytes(32)) };
|
|
28
|
+
}
|
|
29
|
+
/** Encrypt any JSON value to the team. The hub stores this and can't read it. */
|
|
30
|
+
export function sealForTeam(key, value) {
|
|
31
|
+
const nonce = randomBytes(24);
|
|
32
|
+
const ct = xchacha20poly1305(fromB64(key.key), nonce).encrypt(enc.encode(JSON.stringify(value)));
|
|
33
|
+
const out = new Uint8Array(24 + ct.length);
|
|
34
|
+
out.set(nonce, 0);
|
|
35
|
+
out.set(ct, 24);
|
|
36
|
+
return { v: key.version, c: toB64(out) };
|
|
37
|
+
}
|
|
38
|
+
/** Decrypt with whichever key version sealed it; null if unknown or tampered. */
|
|
39
|
+
export function openFromTeam(keys, sealed) {
|
|
40
|
+
if (!sealed || typeof sealed.c !== "string")
|
|
41
|
+
return null;
|
|
42
|
+
const key = keys.find((k) => k.version === sealed.v);
|
|
43
|
+
if (!key)
|
|
44
|
+
return null;
|
|
45
|
+
try {
|
|
46
|
+
const raw = fromB64(sealed.c);
|
|
47
|
+
if (raw.length < 24 + 16)
|
|
48
|
+
return null;
|
|
49
|
+
const pt = xchacha20poly1305(fromB64(key.key), raw.slice(0, 24)).decrypt(raw.slice(24));
|
|
50
|
+
return JSON.parse(dec.decode(pt));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function newDeviceKeys() {
|
|
57
|
+
const sealPriv = x25519.utils.randomSecretKey();
|
|
58
|
+
const signPriv = ed25519.utils.randomSecretKey();
|
|
59
|
+
return {
|
|
60
|
+
sealPub: toB64(x25519.getPublicKey(sealPriv)),
|
|
61
|
+
sealPriv: toB64(sealPriv),
|
|
62
|
+
signPub: toB64(ed25519.getPublicKey(signPriv)),
|
|
63
|
+
signPriv: toB64(signPriv),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const SEAL_INFO = enc.encode("loom-team-seal-v1");
|
|
67
|
+
/** Seal bytes to a device's X25519 public key. Only that device can open it. */
|
|
68
|
+
export function sealTo(recipientSealPub, plaintext) {
|
|
69
|
+
const eph = x25519.utils.randomSecretKey();
|
|
70
|
+
const ephPub = x25519.getPublicKey(eph);
|
|
71
|
+
const rpub = fromB64(recipientSealPub);
|
|
72
|
+
const shared = x25519.getSharedSecret(eph, rpub);
|
|
73
|
+
const salt = new Uint8Array(64);
|
|
74
|
+
salt.set(ephPub, 0);
|
|
75
|
+
salt.set(rpub, 32);
|
|
76
|
+
const k = hkdf(sha256, shared, salt, SEAL_INFO, 32);
|
|
77
|
+
const nonce = randomBytes(24);
|
|
78
|
+
const ct = xchacha20poly1305(k, nonce).encrypt(plaintext);
|
|
79
|
+
const out = new Uint8Array(32 + 24 + ct.length);
|
|
80
|
+
out.set(ephPub, 0);
|
|
81
|
+
out.set(nonce, 32);
|
|
82
|
+
out.set(ct, 56);
|
|
83
|
+
return toB64(out);
|
|
84
|
+
}
|
|
85
|
+
export function openSealed(device, box) {
|
|
86
|
+
try {
|
|
87
|
+
const raw = fromB64(box);
|
|
88
|
+
if (raw.length < 32 + 24 + 16)
|
|
89
|
+
return null;
|
|
90
|
+
const ephPub = raw.slice(0, 32);
|
|
91
|
+
const mine = fromB64(device.sealPub);
|
|
92
|
+
const shared = x25519.getSharedSecret(fromB64(device.sealPriv), ephPub);
|
|
93
|
+
const salt = new Uint8Array(64);
|
|
94
|
+
salt.set(ephPub, 0);
|
|
95
|
+
salt.set(mine, 32);
|
|
96
|
+
const k = hkdf(sha256, shared, salt, SEAL_INFO, 32);
|
|
97
|
+
return xchacha20poly1305(k, raw.slice(32, 56)).decrypt(raw.slice(56));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Seal a team key to a device — the envelope the hub stores per device. */
|
|
104
|
+
export function sealTeamKey(recipientSealPub, key) {
|
|
105
|
+
return sealTo(recipientSealPub, enc.encode(JSON.stringify(key)));
|
|
106
|
+
}
|
|
107
|
+
export function openTeamKey(device, envelope) {
|
|
108
|
+
const pt = openSealed(device, envelope);
|
|
109
|
+
if (!pt)
|
|
110
|
+
return null;
|
|
111
|
+
try {
|
|
112
|
+
const k = JSON.parse(dec.decode(pt));
|
|
113
|
+
return typeof k.key === "string" && Number.isInteger(k.version) ? k : null;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Signatures
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
/** Deterministic JSON: sorted keys, so signer and verifier hash the same bytes. */
|
|
123
|
+
export function canonicalJson(v) {
|
|
124
|
+
if (v === null || typeof v !== "object")
|
|
125
|
+
return JSON.stringify(v);
|
|
126
|
+
if (Array.isArray(v))
|
|
127
|
+
return `[${v.map(canonicalJson).join(",")}]`;
|
|
128
|
+
const o = v;
|
|
129
|
+
return `{${Object.keys(o)
|
|
130
|
+
.filter((k) => o[k] !== undefined)
|
|
131
|
+
.sort()
|
|
132
|
+
.map((k) => `${JSON.stringify(k)}:${canonicalJson(o[k])}`)
|
|
133
|
+
.join(",")}}`;
|
|
134
|
+
}
|
|
135
|
+
export function signPayload(device, payload) {
|
|
136
|
+
return toB64(ed25519.sign(enc.encode(canonicalJson(payload)), fromB64(device.signPriv)));
|
|
137
|
+
}
|
|
138
|
+
export function verifyPayload(signPub, payload, sig) {
|
|
139
|
+
try {
|
|
140
|
+
return ed25519.verify(fromB64(sig), enc.encode(canonicalJson(payload)), fromB64(signPub));
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** What an invite's signature covers. */
|
|
147
|
+
export function inviteSigned(f) {
|
|
148
|
+
return { invite: f.invite, hub: f.hub, teamId: f.teamId ?? null, team: f.team ?? null, repo: f.repo ?? null, from: f.from ?? null, project: f.project ?? null, crews: f.crews ?? null };
|
|
149
|
+
}
|
|
150
|
+
export function packInvite(f) {
|
|
151
|
+
return toB64(enc.encode(JSON.stringify(f)));
|
|
152
|
+
}
|
|
153
|
+
export function unpackInvite(s) {
|
|
154
|
+
try {
|
|
155
|
+
const f = JSON.parse(dec.decode(fromB64(s)));
|
|
156
|
+
return typeof f.invite === "string" && f.key && typeof f.key.key === "string" && typeof f.hub === "string" ? f : null;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// Memory dedupe (Phase 3, D41)
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
/**
|
|
166
|
+
* A team memory's dedupe key: HMAC-SHA256 of its normalized text under the
|
|
167
|
+
* team key. The hub merges exact duplicates by comparing these without ever
|
|
168
|
+
* reading the text. Prefixed with the key version — after a rotation, a
|
|
169
|
+
* memory only merges with others hashed under the same key.
|
|
170
|
+
*/
|
|
171
|
+
export function memoryHmac(key, text) {
|
|
172
|
+
const norm = text.trim().toLowerCase().replace(/\s+/g, " ");
|
|
173
|
+
return `v${key.version}:${toB64(hmac(sha256, fromB64(key.key), enc.encode(norm)))}`;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=team-crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-crypto.js","sourceRoot":"","sources":["../../src/core/team-crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;AAC9B,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;AAW9B,MAAM,UAAU,UAAU,CAAC,OAAO,GAAG,CAAC;IACpC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAClD,CAAC;AAQD,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,KAAc;IACtD,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjG,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IAC3C,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClB,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAChB,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAAc,IAAe,EAAE,MAAiC;IAC1F,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;IACrD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACxF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAM,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAeD,MAAM,UAAU,aAAa;IAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;IACjD,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC7C,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC;QACzB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC9C,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAElD,gFAAgF;AAChF,MAAM,UAAU,MAAM,CAAC,gBAAwB,EAAE,SAAqB;IACpE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACnB,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnB,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAChB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAgD,EAAE,GAAW;IACtF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QAC3C,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QACpD,OAAO,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,gBAAwB,EAAE,GAAY;IAChE,OAAO,MAAM,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAgD,EAAE,QAAgB;IAC5F,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAY,CAAC;QAChD,OAAO,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,mFAAmF;AACnF,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAClE,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACnE,MAAM,CAAC,GAAG,CAA4B,CAAC;IACvC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;SACtB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;SACjC,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACzD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAoC,EAAE,OAAgB;IAChF,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,OAAgB,EAAE,GAAW;IAC1E,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAmCD,yCAAyC;AACzC,MAAM,UAAU,YAAY,CAAC,CAAiB;IAC5C,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;AAC1L,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAiB;IAC1C,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAmB,CAAC;QAC/D,OAAO,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,+BAA+B;AAC/B,8EAA8E;AAG9E;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,IAAY;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5D,OAAO,IAAI,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACtF,CAAC"}
|