macro-agent 0.1.0 → 0.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/.claude/settings.local.json +3 -1
- package/.sudocode/issues.jsonl +28 -0
- package/.sudocode/specs.jsonl +8 -0
- package/CLAUDE.md +25 -17
- package/README.md +11 -29
- package/dist/acp/macro-agent.d.ts +15 -0
- package/dist/acp/macro-agent.d.ts.map +1 -1
- package/dist/acp/macro-agent.js +131 -35
- package/dist/acp/macro-agent.js.map +1 -1
- package/dist/acp/types.d.ts +32 -1
- package/dist/acp/types.d.ts.map +1 -1
- package/dist/acp/types.js.map +1 -1
- package/dist/agent/agent-manager.d.ts +65 -1
- package/dist/agent/agent-manager.d.ts.map +1 -1
- package/dist/agent/agent-manager.js +544 -200
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/agent/types.d.ts +8 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/server.d.ts +8 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +136 -8
- package/dist/api/server.js.map +1 -1
- package/dist/api/types.d.ts +1 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/token.d.ts +41 -0
- package/dist/auth/token.d.ts.map +1 -0
- package/dist/auth/token.js +73 -0
- package/dist/auth/token.js.map +1 -0
- package/dist/cli/acp.d.ts +2 -23
- package/dist/cli/acp.d.ts.map +1 -1
- package/dist/cli/acp.js +197 -61
- package/dist/cli/acp.js.map +1 -1
- package/dist/cli/index.js +152 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.d.ts +6 -0
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +279 -173
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/parse-args.d.ts +20 -0
- package/dist/cli/parse-args.d.ts.map +1 -0
- package/dist/cli/parse-args.js +43 -0
- package/dist/cli/parse-args.js.map +1 -0
- package/dist/cli/stable-instance-id.d.ts +8 -0
- package/dist/cli/stable-instance-id.d.ts.map +1 -0
- package/dist/cli/stable-instance-id.js +14 -0
- package/dist/cli/stable-instance-id.js.map +1 -0
- package/dist/config/project-config.d.ts +85 -7
- package/dist/config/project-config.d.ts.map +1 -1
- package/dist/config/project-config.js +133 -20
- package/dist/config/project-config.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/handlers/index.d.ts +7 -3
- package/dist/lifecycle/handlers/index.d.ts.map +1 -1
- package/dist/lifecycle/handlers/index.js +25 -8
- package/dist/lifecycle/handlers/index.js.map +1 -1
- package/dist/lifecycle/types.d.ts +2 -0
- package/dist/lifecycle/types.d.ts.map +1 -1
- package/dist/lifecycle/types.js.map +1 -1
- package/dist/map/adapter/acp-over-map.d.ts +17 -0
- package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
- package/dist/map/adapter/acp-over-map.js +384 -23
- package/dist/map/adapter/acp-over-map.js.map +1 -1
- package/dist/map/adapter/connection-manager.d.ts.map +1 -1
- package/dist/map/adapter/connection-manager.js +3 -0
- package/dist/map/adapter/connection-manager.js.map +1 -1
- package/dist/map/adapter/event-log.d.ts +87 -0
- package/dist/map/adapter/event-log.d.ts.map +1 -0
- package/dist/map/adapter/event-log.js +122 -0
- package/dist/map/adapter/event-log.js.map +1 -0
- package/dist/map/adapter/event-translator.js +6 -6
- package/dist/map/adapter/event-translator.js.map +1 -1
- package/dist/map/adapter/extensions/agent-lifecycle.d.ts +82 -0
- package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +1 -0
- package/dist/map/adapter/extensions/agent-lifecycle.js +164 -0
- package/dist/map/adapter/extensions/agent-lifecycle.js.map +1 -0
- package/dist/map/adapter/extensions/index.d.ts +13 -1
- package/dist/map/adapter/extensions/index.d.ts.map +1 -1
- package/dist/map/adapter/extensions/index.js +61 -0
- package/dist/map/adapter/extensions/index.js.map +1 -1
- package/dist/map/adapter/extensions/mcp-bridge.d.ts +57 -0
- package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +1 -0
- package/dist/map/adapter/extensions/mcp-bridge.js +745 -0
- package/dist/map/adapter/extensions/mcp-bridge.js.map +1 -0
- package/dist/map/adapter/extensions/rename.d.ts +29 -0
- package/dist/map/adapter/extensions/rename.d.ts.map +1 -0
- package/dist/map/adapter/extensions/rename.js +49 -0
- package/dist/map/adapter/extensions/rename.js.map +1 -0
- package/dist/map/adapter/extensions/streams.d.ts +95 -0
- package/dist/map/adapter/extensions/streams.d.ts.map +1 -0
- package/dist/map/adapter/extensions/streams.js +515 -0
- package/dist/map/adapter/extensions/streams.js.map +1 -0
- package/dist/map/adapter/extensions/task.d.ts.map +1 -1
- package/dist/map/adapter/extensions/task.js +10 -0
- package/dist/map/adapter/extensions/task.js.map +1 -1
- package/dist/map/adapter/extensions/update-metadata.d.ts +29 -0
- package/dist/map/adapter/extensions/update-metadata.d.ts.map +1 -0
- package/dist/map/adapter/extensions/update-metadata.js +67 -0
- package/dist/map/adapter/extensions/update-metadata.js.map +1 -0
- package/dist/map/adapter/index.d.ts +2 -1
- package/dist/map/adapter/index.d.ts.map +1 -1
- package/dist/map/adapter/index.js +10 -2
- package/dist/map/adapter/index.js.map +1 -1
- package/dist/map/adapter/interface.d.ts +2 -0
- package/dist/map/adapter/interface.d.ts.map +1 -1
- package/dist/map/adapter/map-adapter.d.ts +3 -0
- package/dist/map/adapter/map-adapter.d.ts.map +1 -1
- package/dist/map/adapter/map-adapter.js +258 -35
- package/dist/map/adapter/map-adapter.js.map +1 -1
- package/dist/map/adapter/subscription-manager.d.ts.map +1 -1
- package/dist/map/adapter/subscription-manager.js +5 -1
- package/dist/map/adapter/subscription-manager.js.map +1 -1
- package/dist/map/adapter/types.d.ts +3 -1
- package/dist/map/adapter/types.d.ts.map +1 -1
- package/dist/mcp/map-client.d.ts +39 -0
- package/dist/mcp/map-client.d.ts.map +1 -0
- package/dist/mcp/map-client.js +129 -0
- package/dist/mcp/map-client.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts +16 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +125 -88
- package/dist/mcp/mcp-server.js.map +1 -1
- package/dist/mcp/tools/done.d.ts.map +1 -1
- package/dist/mcp/tools/done.js +18 -0
- package/dist/mcp/tools/done.js.map +1 -1
- package/dist/mcp/types.d.ts +9 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/mcp/types.js.map +1 -1
- package/dist/metrics/metrics.js +1 -1
- package/dist/metrics/metrics.js.map +1 -1
- package/dist/roles/builtin/coordinator.d.ts.map +1 -1
- package/dist/roles/builtin/coordinator.js +2 -1
- package/dist/roles/builtin/coordinator.js.map +1 -1
- package/dist/roles/builtin/integrator.d.ts.map +1 -1
- package/dist/roles/builtin/integrator.js +2 -1
- package/dist/roles/builtin/integrator.js.map +1 -1
- package/dist/roles/builtin/worker.d.ts.map +1 -1
- package/dist/roles/builtin/worker.js +3 -1
- package/dist/roles/builtin/worker.js.map +1 -1
- package/dist/roles/capabilities.d.ts +9 -1
- package/dist/roles/capabilities.d.ts.map +1 -1
- package/dist/roles/capabilities.js +27 -7
- package/dist/roles/capabilities.js.map +1 -1
- package/dist/roles/config-loader.d.ts +6 -6
- package/dist/roles/config-loader.d.ts.map +1 -1
- package/dist/roles/config-loader.js +8 -7
- package/dist/roles/config-loader.js.map +1 -1
- package/dist/roles/registry.d.ts +2 -2
- package/dist/roles/registry.js +2 -2
- package/dist/roles/types.d.ts +3 -1
- package/dist/roles/types.d.ts.map +1 -1
- package/dist/server/combined-server.d.ts +28 -1
- package/dist/server/combined-server.d.ts.map +1 -1
- package/dist/server/combined-server.js +111 -8
- package/dist/server/combined-server.js.map +1 -1
- package/dist/store/event-store.d.ts +2 -1
- package/dist/store/event-store.d.ts.map +1 -1
- package/dist/store/event-store.js +80 -24
- package/dist/store/event-store.js.map +1 -1
- package/dist/store/instance.d.ts +1 -1
- package/dist/store/instance.d.ts.map +1 -1
- package/dist/store/instance.js +2 -2
- package/dist/store/instance.js.map +1 -1
- package/dist/store/types/agents.d.ts +23 -0
- package/dist/store/types/agents.d.ts.map +1 -1
- package/dist/store/types/events.d.ts +1 -1
- package/dist/store/types/events.d.ts.map +1 -1
- package/dist/task/backend/index.d.ts +47 -29
- package/dist/task/backend/index.d.ts.map +1 -1
- package/dist/task/backend/index.js +109 -71
- package/dist/task/backend/index.js.map +1 -1
- package/dist/task/backend/memory.d.ts +1 -0
- package/dist/task/backend/memory.d.ts.map +1 -1
- package/dist/task/backend/memory.js +3 -0
- package/dist/task/backend/memory.js.map +1 -1
- package/dist/task/backend/opentasks/backend.d.ts +140 -0
- package/dist/task/backend/opentasks/backend.d.ts.map +1 -0
- package/dist/task/backend/opentasks/backend.js +1023 -0
- package/dist/task/backend/opentasks/backend.js.map +1 -0
- package/dist/task/backend/opentasks/client.d.ts +337 -0
- package/dist/task/backend/opentasks/client.d.ts.map +1 -0
- package/dist/task/backend/opentasks/client.js +225 -0
- package/dist/task/backend/opentasks/client.js.map +1 -0
- package/dist/task/backend/opentasks/daemon-manager.d.ts +89 -0
- package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -0
- package/dist/task/backend/opentasks/daemon-manager.js +195 -0
- package/dist/task/backend/opentasks/daemon-manager.js.map +1 -0
- package/dist/task/backend/opentasks/index.d.ts +21 -0
- package/dist/task/backend/opentasks/index.d.ts.map +1 -0
- package/dist/task/backend/opentasks/index.js +21 -0
- package/dist/task/backend/opentasks/index.js.map +1 -0
- package/dist/task/backend/opentasks/mapping.d.ts +48 -0
- package/dist/task/backend/opentasks/mapping.d.ts.map +1 -0
- package/dist/task/backend/opentasks/mapping.js +77 -0
- package/dist/task/backend/opentasks/mapping.js.map +1 -0
- package/dist/task/backend/types.d.ts +33 -53
- package/dist/task/backend/types.d.ts.map +1 -1
- package/dist/task/backend/types.js +7 -11
- package/dist/task/backend/types.js.map +1 -1
- package/dist/task/backend/unified-tool-provider.d.ts +57 -0
- package/dist/task/backend/unified-tool-provider.d.ts.map +1 -0
- package/dist/task/backend/unified-tool-provider.js +623 -0
- package/dist/task/backend/unified-tool-provider.js.map +1 -0
- package/dist/teams/index.d.ts +3 -1
- package/dist/teams/index.d.ts.map +1 -1
- package/dist/teams/index.js +2 -0
- package/dist/teams/index.js.map +1 -1
- package/dist/teams/seed-defaults.d.ts +20 -0
- package/dist/teams/seed-defaults.d.ts.map +1 -0
- package/dist/teams/seed-defaults.js +71 -0
- package/dist/teams/seed-defaults.js.map +1 -0
- package/dist/teams/team-loader.d.ts +7 -3
- package/dist/teams/team-loader.d.ts.map +1 -1
- package/dist/teams/team-loader.js +156 -164
- package/dist/teams/team-loader.js.map +1 -1
- package/dist/teams/team-manager.d.ts +112 -0
- package/dist/teams/team-manager.d.ts.map +1 -0
- package/dist/teams/team-manager.js +305 -0
- package/dist/teams/team-manager.js.map +1 -0
- package/dist/teams/team-runtime.d.ts +125 -19
- package/dist/teams/team-runtime.d.ts.map +1 -1
- package/dist/teams/team-runtime.js +529 -119
- package/dist/teams/team-runtime.js.map +1 -1
- package/dist/teams/types.d.ts +41 -151
- package/dist/teams/types.d.ts.map +1 -1
- package/dist/teams/types.js +2 -3
- package/dist/teams/types.js.map +1 -1
- package/docs/architecture.md +7 -6
- package/docs/configuration.md +26 -62
- package/docs/implementation-details.md +5 -5
- package/docs/implementation-summary.md +17 -17
- package/docs/plan-self-driving-support.md +4 -4
- package/docs/spec-self-driving-support.md +10 -10
- package/docs/team-templates.md +2 -2
- package/docs/teams.md +76 -3
- package/docs/troubleshooting.md +10 -11
- package/package.json +7 -4
- package/references/minimem/.claude/settings.json +7 -0
- package/references/minimem/.sudocode/issues.jsonl +18 -0
- package/references/minimem/.sudocode/specs.jsonl +1 -0
- package/references/minimem/CLAUDE.md +310 -0
- package/references/minimem/README.md +562 -0
- package/references/minimem/claude-plugin/.claude-plugin/plugin.json +10 -0
- package/references/minimem/claude-plugin/.mcp.json +7 -0
- package/references/minimem/claude-plugin/README.md +158 -0
- package/references/minimem/claude-plugin/commands/recall.md +47 -0
- package/references/minimem/claude-plugin/commands/remember.md +41 -0
- package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +272 -0
- package/references/minimem/claude-plugin/hooks/hooks.json +27 -0
- package/references/minimem/claude-plugin/hooks/session-end.sh +86 -0
- package/references/minimem/claude-plugin/hooks/session-start.sh +85 -0
- package/references/minimem/claude-plugin/skills/memory/SKILL.md +108 -0
- package/references/minimem/media/banner.png +0 -0
- package/references/minimem/package-lock.json +5373 -0
- package/references/minimem/package.json +72 -0
- package/references/minimem/scripts/postbuild.js +35 -0
- package/references/minimem/src/__tests__/edge-cases.test.ts +371 -0
- package/references/minimem/src/__tests__/errors.test.ts +265 -0
- package/references/minimem/src/__tests__/helpers.ts +199 -0
- package/references/minimem/src/__tests__/internal.test.ts +407 -0
- package/references/minimem/src/__tests__/knowledge.test.ts +287 -0
- package/references/minimem/src/__tests__/minimem.integration.test.ts +1127 -0
- package/references/minimem/src/__tests__/session.test.ts +190 -0
- package/references/minimem/src/cli/__tests__/commands.test.ts +759 -0
- package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +141 -0
- package/references/minimem/src/cli/commands/append.ts +76 -0
- package/references/minimem/src/cli/commands/config.ts +262 -0
- package/references/minimem/src/cli/commands/conflicts.ts +413 -0
- package/references/minimem/src/cli/commands/daemon.ts +169 -0
- package/references/minimem/src/cli/commands/index.ts +12 -0
- package/references/minimem/src/cli/commands/init.ts +88 -0
- package/references/minimem/src/cli/commands/mcp.ts +177 -0
- package/references/minimem/src/cli/commands/push-pull.ts +213 -0
- package/references/minimem/src/cli/commands/search.ts +158 -0
- package/references/minimem/src/cli/commands/status.ts +84 -0
- package/references/minimem/src/cli/commands/sync-init.ts +290 -0
- package/references/minimem/src/cli/commands/sync.ts +70 -0
- package/references/minimem/src/cli/commands/upsert.ts +197 -0
- package/references/minimem/src/cli/config.ts +584 -0
- package/references/minimem/src/cli/index.ts +264 -0
- package/references/minimem/src/cli/shared.ts +161 -0
- package/references/minimem/src/cli/sync/__tests__/central.test.ts +152 -0
- package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +209 -0
- package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +118 -0
- package/references/minimem/src/cli/sync/__tests__/detection.test.ts +207 -0
- package/references/minimem/src/cli/sync/__tests__/integration.test.ts +476 -0
- package/references/minimem/src/cli/sync/__tests__/registry.test.ts +363 -0
- package/references/minimem/src/cli/sync/__tests__/state.test.ts +255 -0
- package/references/minimem/src/cli/sync/__tests__/validation.test.ts +193 -0
- package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +178 -0
- package/references/minimem/src/cli/sync/central.ts +292 -0
- package/references/minimem/src/cli/sync/conflicts.ts +204 -0
- package/references/minimem/src/cli/sync/daemon.ts +407 -0
- package/references/minimem/src/cli/sync/detection.ts +138 -0
- package/references/minimem/src/cli/sync/index.ts +107 -0
- package/references/minimem/src/cli/sync/operations.ts +373 -0
- package/references/minimem/src/cli/sync/registry.ts +279 -0
- package/references/minimem/src/cli/sync/state.ts +355 -0
- package/references/minimem/src/cli/sync/validation.ts +206 -0
- package/references/minimem/src/cli/sync/watcher.ts +234 -0
- package/references/minimem/src/cli/version.ts +34 -0
- package/references/minimem/src/core/index.ts +9 -0
- package/references/minimem/src/core/indexer.ts +628 -0
- package/references/minimem/src/core/searcher.ts +221 -0
- package/references/minimem/src/db/schema.ts +183 -0
- package/references/minimem/src/db/sqlite-vec.ts +24 -0
- package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +431 -0
- package/references/minimem/src/embeddings/batch-gemini.ts +392 -0
- package/references/minimem/src/embeddings/batch-openai.ts +409 -0
- package/references/minimem/src/embeddings/embeddings.ts +434 -0
- package/references/minimem/src/index.ts +109 -0
- package/references/minimem/src/internal.ts +299 -0
- package/references/minimem/src/minimem.ts +1276 -0
- package/references/minimem/src/search/__tests__/hybrid.test.ts +247 -0
- package/references/minimem/src/search/graph.ts +234 -0
- package/references/minimem/src/search/hybrid.ts +151 -0
- package/references/minimem/src/search/search.ts +256 -0
- package/references/minimem/src/server/__tests__/mcp.test.ts +341 -0
- package/references/minimem/src/server/__tests__/tools.test.ts +364 -0
- package/references/minimem/src/server/mcp.ts +326 -0
- package/references/minimem/src/server/tools.ts +720 -0
- package/references/minimem/src/session.ts +460 -0
- package/references/minimem/tsconfig.json +19 -0
- package/references/minimem/tsup.config.ts +26 -0
- package/references/minimem/vitest.config.ts +24 -0
- package/references/openteams/.claude/settings.json +6 -0
- package/references/openteams/README.md +1 -0
- package/references/openteams/SKILL.md +341 -0
- package/references/openteams/design.md +411 -0
- package/references/openteams/examples/bmad-method/prompts/analyst/ROLE.md +16 -0
- package/references/openteams/examples/bmad-method/prompts/analyst/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/architect/ROLE.md +24 -0
- package/references/openteams/examples/bmad-method/prompts/architect/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/developer/ROLE.md +25 -0
- package/references/openteams/examples/bmad-method/prompts/developer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/master/ROLE.md +21 -0
- package/references/openteams/examples/bmad-method/prompts/master/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/pm/ROLE.md +20 -0
- package/references/openteams/examples/bmad-method/prompts/pm/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/qa/ROLE.md +17 -0
- package/references/openteams/examples/bmad-method/prompts/qa/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/ROLE.md +23 -0
- package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/scrum-master/ROLE.md +27 -0
- package/references/openteams/examples/bmad-method/prompts/scrum-master/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/tech-writer/ROLE.md +21 -0
- package/references/openteams/examples/bmad-method/prompts/tech-writer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/ux-designer/ROLE.md +16 -0
- package/references/openteams/examples/bmad-method/prompts/ux-designer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/roles/analyst.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/architect.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/developer.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/master.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/pm.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/qa.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/quick-flow-dev.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/scrum-master.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/tech-writer.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/ux-designer.yaml +8 -0
- package/references/openteams/examples/bmad-method/team.yaml +161 -0
- package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/ROLE.md +17 -0
- package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/debugger/ROLE.md +25 -0
- package/references/openteams/examples/get-shit-done/prompts/debugger/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/executor/ROLE.md +34 -0
- package/references/openteams/examples/get-shit-done/prompts/executor/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/integration-checker/ROLE.md +18 -0
- package/references/openteams/examples/get-shit-done/prompts/integration-checker/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/orchestrator/ROLE.md +42 -0
- package/references/openteams/examples/get-shit-done/prompts/orchestrator/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/phase-researcher/ROLE.md +15 -0
- package/references/openteams/examples/get-shit-done/prompts/phase-researcher/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/plan-checker/ROLE.md +17 -0
- package/references/openteams/examples/get-shit-done/prompts/plan-checker/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/planner/ROLE.md +28 -0
- package/references/openteams/examples/get-shit-done/prompts/planner/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/project-researcher/ROLE.md +16 -0
- package/references/openteams/examples/get-shit-done/prompts/project-researcher/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/ROLE.md +13 -0
- package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/roadmapper/ROLE.md +14 -0
- package/references/openteams/examples/get-shit-done/prompts/roadmapper/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/verifier/ROLE.md +19 -0
- package/references/openteams/examples/get-shit-done/prompts/verifier/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/roles/codebase-mapper.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/debugger.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/executor.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/integration-checker.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/orchestrator.yaml +9 -0
- package/references/openteams/examples/get-shit-done/roles/phase-researcher.yaml +7 -0
- package/references/openteams/examples/get-shit-done/roles/plan-checker.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/planner.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/project-researcher.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/research-synthesizer.yaml +7 -0
- package/references/openteams/examples/get-shit-done/roles/roadmapper.yaml +7 -0
- package/references/openteams/examples/get-shit-done/roles/verifier.yaml +8 -0
- package/references/openteams/examples/get-shit-done/team.yaml +154 -0
- package/references/openteams/package-lock.json +2181 -0
- package/references/openteams/package.json +48 -0
- package/references/openteams/schema/role.schema.json +125 -0
- package/references/openteams/schema/team.schema.json +284 -0
- package/references/openteams/src/cli/agent.ts +104 -0
- package/references/openteams/src/cli/cli.test.ts +381 -0
- package/references/openteams/src/cli/generate.ts +220 -0
- package/references/openteams/src/cli/message.ts +241 -0
- package/references/openteams/src/cli/task.ts +154 -0
- package/references/openteams/src/cli/team.ts +104 -0
- package/references/openteams/src/cli/template.ts +207 -0
- package/references/openteams/src/cli.ts +45 -0
- package/references/openteams/src/db/database.test.ts +185 -0
- package/references/openteams/src/db/database.ts +240 -0
- package/references/openteams/src/generators/agent-prompt-generator.test.ts +332 -0
- package/references/openteams/src/generators/agent-prompt-generator.ts +521 -0
- package/references/openteams/src/generators/package-generator.test.ts +129 -0
- package/references/openteams/src/generators/package-generator.ts +102 -0
- package/references/openteams/src/generators/skill-generator.test.ts +246 -0
- package/references/openteams/src/generators/skill-generator.ts +374 -0
- package/references/openteams/src/index.ts +104 -0
- package/references/openteams/src/services/agent-service.test.ts +158 -0
- package/references/openteams/src/services/agent-service.ts +84 -0
- package/references/openteams/src/services/communication-service.test.ts +455 -0
- package/references/openteams/src/services/communication-service.ts +371 -0
- package/references/openteams/src/services/message-service.test.ts +342 -0
- package/references/openteams/src/services/message-service.ts +203 -0
- package/references/openteams/src/services/task-service.test.ts +434 -0
- package/references/openteams/src/services/task-service.ts +239 -0
- package/references/openteams/src/services/team-service.test.ts +181 -0
- package/references/openteams/src/services/team-service.ts +139 -0
- package/references/openteams/src/services/template-service.test.ts +306 -0
- package/references/openteams/src/services/template-service.ts +182 -0
- package/references/openteams/src/spawner/acp-factory.ts +96 -0
- package/references/openteams/src/spawner/interface.ts +31 -0
- package/references/openteams/src/spawner/mock.test.ts +93 -0
- package/references/openteams/src/spawner/mock.ts +59 -0
- package/references/openteams/src/template/loader.test.ts +1319 -0
- package/references/openteams/src/template/loader.ts +698 -0
- package/references/openteams/src/template/types.ts +200 -0
- package/references/openteams/src/types.ts +205 -0
- package/references/openteams/tsconfig.json +18 -0
- package/references/openteams/vitest.config.ts +9 -0
- package/references/skill-tree/.claude/settings.json +6 -0
- package/references/skill-tree/.sudocode/issues.jsonl +11 -0
- package/references/skill-tree/.sudocode/specs.jsonl +1 -0
- package/references/skill-tree/CLAUDE.md +150 -0
- package/references/skill-tree/README.md +324 -0
- package/references/skill-tree/docs/GAPS_v1.md +221 -0
- package/references/skill-tree/docs/INTEGRATION_PLAN.md +467 -0
- package/references/skill-tree/docs/TODOS.md +91 -0
- package/references/skill-tree/docs/anthropic_skill_guide.md +1364 -0
- package/references/skill-tree/docs/design/federated-skill-trees.md +524 -0
- package/references/skill-tree/docs/design/multi-agent-sync.md +759 -0
- package/references/skill-tree/docs/scraper/BRAINSTORM.md +583 -0
- package/references/skill-tree/docs/scraper/POC_PLAN.md +420 -0
- package/references/skill-tree/docs/scraper/README.md +170 -0
- package/references/skill-tree/examples/basic-usage.ts +190 -0
- package/references/skill-tree/package-lock.json +1509 -0
- package/references/skill-tree/package.json +66 -0
- package/references/skill-tree/scraper/README.md +123 -0
- package/references/skill-tree/scraper/docs/DESIGN.md +683 -0
- package/references/skill-tree/scraper/docs/PLAN.md +336 -0
- package/references/skill-tree/scraper/drizzle.config.ts +10 -0
- package/references/skill-tree/scraper/package-lock.json +6329 -0
- package/references/skill-tree/scraper/package.json +68 -0
- package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +7 -0
- package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +7 -0
- package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +27 -0
- package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +21 -0
- package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +54 -0
- package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +24 -0
- package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +93 -0
- package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +22 -0
- package/references/skill-tree/scraper/tsup.config.ts +14 -0
- package/references/skill-tree/scraper/vitest.config.ts +17 -0
- package/references/skill-tree/scripts/convert-to-vitest.ts +166 -0
- package/references/skill-tree/skills/skill-writer/SKILL.md +339 -0
- package/references/skill-tree/skills/skill-writer/references/examples.md +326 -0
- package/references/skill-tree/skills/skill-writer/references/patterns.md +210 -0
- package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +123 -0
- package/references/skill-tree/test/run-all.ts +106 -0
- package/references/skill-tree/test/utils.ts +128 -0
- package/references/skill-tree/vitest.config.ts +16 -0
- package/src/__tests__/e2e/agent-spawn-visibility.e2e.test.ts +761 -0
- package/src/__tests__/e2e/full-agent-conflict-resolution.e2e.test.ts +2 -2
- package/src/__tests__/e2e/mcp-thin-client-bridge.e2e.test.ts +304 -0
- package/src/__tests__/e2e/mcp-tools-available.e2e.test.ts +324 -0
- package/src/__tests__/e2e/multi-agent.e2e.test.ts +5 -5
- package/src/__tests__/e2e/spawn-session-streaming.e2e.test.ts +563 -0
- package/src/acp/__tests__/integration.test.ts +56 -31
- package/src/acp/__tests__/macro-agent.test.ts +16 -7
- package/src/acp/macro-agent.ts +170 -36
- package/src/acp/types.ts +46 -1
- package/src/agent/__tests__/agent-manager.test.ts +228 -2
- package/src/agent/agent-manager.ts +809 -285
- package/src/agent/types.ts +12 -1
- package/src/api/__tests__/server.test.ts +203 -4
- package/src/api/server.ts +169 -10
- package/src/api/types.ts +3 -1
- package/src/auth/__tests__/token.test.ts +100 -0
- package/src/auth/index.ts +1 -0
- package/src/auth/token.ts +82 -0
- package/src/cli/__tests__/acp.test.ts +1 -1
- package/src/cli/__tests__/stable-instance-id.test.ts +1 -1
- package/src/cli/acp.ts +197 -72
- package/src/cli/index.ts +125 -15
- package/src/cli/mcp.ts +315 -197
- package/src/cli/parse-args.ts +54 -0
- package/src/cli/stable-instance-id.ts +14 -0
- package/src/config/project-config.ts +214 -27
- package/src/index.ts +3 -0
- package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
- package/src/lifecycle/__tests__/handlers.test.ts +53 -0
- package/src/lifecycle/handlers/index.ts +25 -8
- package/src/lifecycle/types.ts +3 -0
- package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +22 -4
- package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +355 -0
- package/src/map/adapter/__tests__/acp-over-map-history.test.ts +263 -0
- package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +1 -1
- package/src/map/adapter/__tests__/event-broadcast.test.ts +420 -0
- package/src/map/adapter/__tests__/event-log.test.ts +527 -0
- package/src/map/adapter/__tests__/event-translator.test.ts +3 -3
- package/src/map/adapter/__tests__/extensions.test.ts +408 -0
- package/src/map/adapter/__tests__/map-adapter.test.ts +99 -0
- package/src/map/adapter/__tests__/mcp-bridge.test.ts +1187 -0
- package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +711 -0
- package/src/map/adapter/__tests__/stream-extensions.test.ts +494 -0
- package/src/map/adapter/__tests__/websocket-integration.test.ts +218 -0
- package/src/map/adapter/acp-over-map.ts +678 -66
- package/src/map/adapter/connection-manager.ts +3 -0
- package/src/map/adapter/event-log.ts +208 -0
- package/src/map/adapter/event-translator.ts +6 -6
- package/src/map/adapter/extensions/agent-lifecycle.ts +267 -0
- package/src/map/adapter/extensions/index.ts +96 -0
- package/src/map/adapter/extensions/mcp-bridge.ts +995 -0
- package/src/map/adapter/extensions/streams.ts +839 -0
- package/src/map/adapter/extensions/task.ts +11 -0
- package/src/map/adapter/extensions/update-metadata.ts +126 -0
- package/src/map/adapter/index.ts +33 -0
- package/src/map/adapter/interface.ts +2 -0
- package/src/map/adapter/map-adapter.ts +312 -47
- package/src/map/adapter/subscription-manager.ts +5 -1
- package/src/map/adapter/types.ts +10 -1
- package/src/mcp/__tests__/map-client.test.ts +386 -0
- package/src/mcp/__tests__/mcp-server-thin-client.test.ts +368 -0
- package/src/mcp/__tests__/mcp-server.test.ts +100 -1
- package/src/mcp/map-client.ts +177 -0
- package/src/mcp/mcp-server.ts +205 -103
- package/src/mcp/tools/done.ts +19 -0
- package/src/mcp/types.ts +6 -1
- package/src/metrics/metrics.ts +1 -1
- package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +1 -1
- package/src/roles/__tests__/config-loader.test.ts +7 -7
- package/src/roles/builtin/coordinator.ts +2 -0
- package/src/roles/builtin/integrator.ts +2 -0
- package/src/roles/builtin/worker.ts +3 -0
- package/src/roles/capabilities.ts +28 -7
- package/src/roles/config-loader.ts +8 -7
- package/src/roles/registry.ts +2 -2
- package/src/roles/types.ts +7 -0
- package/src/server/__tests__/combined-server.test.ts +94 -21
- package/src/server/combined-server.ts +203 -33
- package/src/steering/__tests__/steering-integration.test.ts +1 -1
- package/src/store/__tests__/event-store-oob.test.ts +109 -0
- package/src/store/__tests__/event-store.test.ts +196 -1
- package/src/store/__tests__/instance.test.ts +3 -3
- package/src/store/event-store.ts +92 -23
- package/src/store/instance.ts +2 -2
- package/src/store/types/agents.ts +20 -0
- package/src/store/types/events.ts +1 -1
- package/src/task/backend/__tests__/create-task-backend.test.ts +225 -0
- package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +524 -0
- package/src/task/backend/__tests__/memory-pull-mode.test.ts +153 -0
- package/src/task/backend/__tests__/unified-tool-provider.test.ts +579 -0
- package/src/task/backend/index.ts +156 -106
- package/src/task/backend/memory.ts +4 -0
- package/src/task/backend/opentasks/__tests__/backend.test.ts +968 -0
- package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +406 -0
- package/src/task/backend/opentasks/__tests__/mapping.test.ts +84 -0
- package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +1338 -0
- package/src/task/backend/opentasks/backend.ts +1323 -0
- package/src/task/backend/opentasks/client.ts +652 -0
- package/src/task/backend/opentasks/daemon-manager.ts +256 -0
- package/src/task/backend/opentasks/index.ts +69 -0
- package/src/task/backend/opentasks/mapping.ts +94 -0
- package/src/task/backend/types.ts +42 -66
- package/src/task/backend/unified-tool-provider.ts +779 -0
- package/src/teams/CLAUDE.md +180 -0
- package/src/teams/__tests__/cross-subsystem.integration.test.ts +1 -1
- package/src/teams/__tests__/e2e/workspace-isolation.e2e.test.ts +1263 -0
- package/src/teams/__tests__/team-manager.test.ts +814 -0
- package/src/teams/__tests__/team-system.test.ts +1291 -8
- package/src/teams/index.ts +21 -3
- package/src/teams/seed-defaults.ts +79 -0
- package/src/teams/team-loader.ts +202 -236
- package/src/teams/team-manager.ts +387 -0
- package/src/teams/team-runtime.ts +592 -121
- package/src/teams/types.ts +99 -200
- package/test_fixtures/README.md +2 -3
- package/test_fixtures/fixtures/index.ts +0 -3
- package/test_fixtures/fixtures/projects/project-with-specs.ts +7 -149
- package/test_fixtures/fixtures/repos/index.ts +1 -3
- package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -116
- package/test_fixtures/fixtures/repos/types.ts +0 -11
- package/test_fixtures/harness/__tests__/fixtures.test.ts +10 -102
- package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -33
- package/test_fixtures/harness/simulator/agent-simulator.ts +4 -4
- package/vitest.config.ts +1 -1
- package/vitest.e2e.config.ts +1 -1
- package/vitest.setup.ts +1 -30
- package/.macro-agent/teams/self-driving/prompts/grinder.md +0 -27
- package/.macro-agent/teams/self-driving/prompts/judge.md +0 -27
- package/.macro-agent/teams/self-driving/prompts/planner.md +0 -33
- package/.macro-agent/teams/self-driving/roles/grinder.yaml +0 -17
- package/.macro-agent/teams/self-driving/roles/judge.yaml +0 -24
- package/.macro-agent/teams/self-driving/roles/planner.yaml +0 -18
- package/.macro-agent/teams/self-driving/team.yaml +0 -103
- package/.macro-agent/teams/structured/prompts/developer.md +0 -26
- package/.macro-agent/teams/structured/prompts/lead.md +0 -25
- package/.macro-agent/teams/structured/prompts/reviewer.md +0 -24
- package/.macro-agent/teams/structured/roles/developer.yaml +0 -12
- package/.macro-agent/teams/structured/roles/lead.yaml +0 -11
- package/.macro-agent/teams/structured/roles/reviewer.yaml +0 -19
- package/.macro-agent/teams/structured/team.yaml +0 -89
- package/docs/sudocode-integration.md +0 -383
- package/src/task/backend/__tests__/backend-parity.test.ts +0 -451
- package/src/task/backend/__tests__/tool-provider-edge-cases.test.ts +0 -430
- package/src/task/backend/__tests__/tool-provider.test.ts +0 -983
- package/src/task/backend/sudocode/__tests__/backend-edge-cases.test.ts +0 -575
- package/src/task/backend/sudocode/__tests__/backend.test.ts +0 -1194
- package/src/task/backend/sudocode/__tests__/client-integration.test.ts +0 -418
- package/src/task/backend/sudocode/__tests__/client.test.ts +0 -345
- package/src/task/backend/sudocode/__tests__/e2e/backend.e2e.test.ts +0 -753
- package/src/task/backend/sudocode/__tests__/e2e/server-client.e2e.test.ts +0 -680
- package/src/task/backend/sudocode/__tests__/e2e-workflow.test.ts +0 -666
- package/src/task/backend/sudocode/__tests__/integration/standalone-client.integration.test.ts +0 -396
- package/src/task/backend/sudocode/__tests__/integration/sudocode-cli.integration.test.ts +0 -328
- package/src/task/backend/sudocode/__tests__/integration/test-utils.ts +0 -175
- package/src/task/backend/sudocode/__tests__/mapping-edge-cases.test.ts +0 -265
- package/src/task/backend/sudocode/__tests__/server-client.test.ts +0 -675
- package/src/task/backend/sudocode/__tests__/sync-policy-edge-cases.test.ts +0 -521
- package/src/task/backend/sudocode/__tests__/sync-policy.test.ts +0 -519
- package/src/task/backend/sudocode/__tests__/tools.test.ts +0 -471
- package/src/task/backend/sudocode/backend.ts +0 -1237
- package/src/task/backend/sudocode/client.ts +0 -515
- package/src/task/backend/sudocode/index.ts +0 -120
- package/src/task/backend/sudocode/mapping.ts +0 -93
- package/src/task/backend/sudocode/server-client.ts +0 -522
- package/src/task/backend/sudocode/standalone-client.ts +0 -623
- package/src/task/backend/sudocode/sync-policy.ts +0 -387
- package/src/task/backend/sudocode/tools.ts +0 -896
- package/src/task/backend/tool-provider.ts +0 -506
- package/test_fixtures/fixtures/sudocode/index.ts +0 -29
- package/test_fixtures/fixtures/sudocode/issues.ts +0 -185
- package/test_fixtures/fixtures/sudocode/specs.ts +0 -159
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { TemplateService } from "../services/template-service";
|
|
3
|
+
import { CommunicationService } from "../services/communication-service";
|
|
4
|
+
import { TemplateLoader } from "../template/loader";
|
|
5
|
+
import type Database from "better-sqlite3";
|
|
6
|
+
|
|
7
|
+
export function createTemplateCommands(db: Database.Database): Command {
|
|
8
|
+
const templateService = new TemplateService(db);
|
|
9
|
+
const commService = new CommunicationService(db);
|
|
10
|
+
const template = new Command("template").description(
|
|
11
|
+
"Load and manage team templates"
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
template
|
|
15
|
+
.command("load <dir>")
|
|
16
|
+
.description("Load a team template from a directory and create a team")
|
|
17
|
+
.option("-n, --name <name>", "Override the team name from the manifest")
|
|
18
|
+
.action((dir: string, opts) => {
|
|
19
|
+
try {
|
|
20
|
+
const result = templateService.bootstrap(dir, opts.name);
|
|
21
|
+
console.log(`Team "${result.team.name}" created from template.`);
|
|
22
|
+
console.log(` Roles: ${result.roles.join(", ")}`);
|
|
23
|
+
if (result.channels.length > 0) {
|
|
24
|
+
console.log(` Channels: ${result.channels.join(", ")}`);
|
|
25
|
+
}
|
|
26
|
+
if (result.spawnRules.length > 0) {
|
|
27
|
+
console.log(" Spawn rules:");
|
|
28
|
+
for (const rule of result.spawnRules) {
|
|
29
|
+
console.log(
|
|
30
|
+
` ${rule.from} -> [${rule.canSpawn.join(", ")}]`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} catch (err: any) {
|
|
35
|
+
console.error(`Error: ${err.message}`);
|
|
36
|
+
process.exitCode = 1;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
template
|
|
41
|
+
.command("validate <dir>")
|
|
42
|
+
.description("Validate a team template directory without creating a team")
|
|
43
|
+
.action((dir: string) => {
|
|
44
|
+
try {
|
|
45
|
+
const resolved = TemplateLoader.load(dir);
|
|
46
|
+
console.log(`Template "${resolved.manifest.name}" is valid.`);
|
|
47
|
+
console.log(` Version: ${resolved.manifest.version}`);
|
|
48
|
+
console.log(` Roles: ${resolved.manifest.roles.join(", ")}`);
|
|
49
|
+
console.log(` Root: ${resolved.manifest.topology.root.role}`);
|
|
50
|
+
if (resolved.manifest.topology.companions) {
|
|
51
|
+
const companions = resolved.manifest.topology.companions.map(
|
|
52
|
+
(c) => c.role
|
|
53
|
+
);
|
|
54
|
+
console.log(` Companions: ${companions.join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
if (resolved.prompts.size > 0) {
|
|
57
|
+
console.log(
|
|
58
|
+
` Prompts loaded: ${Array.from(resolved.prompts.keys()).join(", ")}`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
if (resolved.manifest.communication?.channels) {
|
|
62
|
+
console.log(
|
|
63
|
+
` Channels: ${Object.keys(resolved.manifest.communication.channels).join(", ")}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
} catch (err: any) {
|
|
67
|
+
console.error(`Invalid template: ${err.message}`);
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
template
|
|
73
|
+
.command("info <team>")
|
|
74
|
+
.description("Show template information for a team")
|
|
75
|
+
.action((teamName: string) => {
|
|
76
|
+
const info = templateService.getTemplateInfo(teamName);
|
|
77
|
+
if (!info) {
|
|
78
|
+
console.error(`Error: Team "${teamName}" not found.`);
|
|
79
|
+
process.exitCode = 1;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!info.templateName) {
|
|
83
|
+
console.log(`Team "${teamName}" was not created from a template.`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
console.log(`Template: ${info.templateName}`);
|
|
87
|
+
if (info.templatePath) {
|
|
88
|
+
console.log(`Source: ${info.templatePath}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Show communication topology
|
|
92
|
+
const channels = commService.listChannels(teamName);
|
|
93
|
+
if (channels.length > 0) {
|
|
94
|
+
console.log("\nChannels:");
|
|
95
|
+
for (const ch of channels) {
|
|
96
|
+
const desc = ch.description ? ` - ${ch.description}` : "";
|
|
97
|
+
console.log(` ${ch.name}${desc}`);
|
|
98
|
+
console.log(` Signals: ${ch.signals.join(", ")}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const subs = commService.listSubscriptions(teamName);
|
|
103
|
+
if (subs.length > 0) {
|
|
104
|
+
console.log("\nSubscriptions:");
|
|
105
|
+
// Group by role
|
|
106
|
+
const grouped: Record<string, string[]> = {};
|
|
107
|
+
for (const sub of subs) {
|
|
108
|
+
if (!grouped[sub.role]) grouped[sub.role] = [];
|
|
109
|
+
const label = sub.signal
|
|
110
|
+
? `${sub.channel}:${sub.signal}`
|
|
111
|
+
: `${sub.channel}:*`;
|
|
112
|
+
grouped[sub.role].push(label);
|
|
113
|
+
}
|
|
114
|
+
for (const [role, channels] of Object.entries(grouped)) {
|
|
115
|
+
console.log(` ${role}: ${channels.join(", ")}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const routes = commService.listPeerRoutes(teamName);
|
|
120
|
+
if (routes.length > 0) {
|
|
121
|
+
console.log("\nPeer Routes:");
|
|
122
|
+
for (const route of routes) {
|
|
123
|
+
const signals =
|
|
124
|
+
route.signals.length > 0
|
|
125
|
+
? ` [${route.signals.join(", ")}]`
|
|
126
|
+
: "";
|
|
127
|
+
console.log(
|
|
128
|
+
` ${route.from_role} -> ${route.to_role} via ${route.via}${signals}`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const spawnRules = templateService.listSpawnRules(teamName);
|
|
134
|
+
if (spawnRules.length > 0) {
|
|
135
|
+
console.log("\nSpawn Rules:");
|
|
136
|
+
for (const rule of spawnRules) {
|
|
137
|
+
console.log(
|
|
138
|
+
` ${rule.from} -> [${rule.canSpawn.join(", ")}]`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
template
|
|
145
|
+
.command("emit <team>")
|
|
146
|
+
.description("Emit a signal on a channel")
|
|
147
|
+
.requiredOption("-c, --channel <channel>", "Channel name")
|
|
148
|
+
.requiredOption("-s, --signal <signal>", "Signal name")
|
|
149
|
+
.requiredOption("--sender <sender>", "Sender agent/role name")
|
|
150
|
+
.option("-p, --payload <json>", "JSON payload")
|
|
151
|
+
.action((teamName: string, opts) => {
|
|
152
|
+
try {
|
|
153
|
+
const { event, permitted, enforcement } = commService.emit({
|
|
154
|
+
teamName,
|
|
155
|
+
channel: opts.channel,
|
|
156
|
+
signal: opts.signal,
|
|
157
|
+
sender: opts.sender,
|
|
158
|
+
payload: opts.payload ? JSON.parse(opts.payload) : undefined,
|
|
159
|
+
});
|
|
160
|
+
let msg = `Signal ${event.signal} emitted on ${event.channel} by ${event.sender} (event #${event.id}).`;
|
|
161
|
+
if (!permitted && enforcement === "audit") {
|
|
162
|
+
msg += ` [AUDIT: "${opts.sender}" is not permitted to emit "${opts.signal}"]`;
|
|
163
|
+
}
|
|
164
|
+
console.log(msg);
|
|
165
|
+
} catch (err: any) {
|
|
166
|
+
console.error(`Error: ${err.message}`);
|
|
167
|
+
process.exitCode = 1;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
template
|
|
172
|
+
.command("events <team>")
|
|
173
|
+
.description("List signal events for a team")
|
|
174
|
+
.option("-c, --channel <channel>", "Filter by channel")
|
|
175
|
+
.option("-s, --signal <signal>", "Filter by signal")
|
|
176
|
+
.option("--sender <sender>", "Filter by sender")
|
|
177
|
+
.option("--role <role>", "Show events visible to a specific role")
|
|
178
|
+
.action((teamName: string, opts) => {
|
|
179
|
+
let events;
|
|
180
|
+
if (opts.role) {
|
|
181
|
+
events = commService.getEventsForRole(teamName, opts.role);
|
|
182
|
+
} else {
|
|
183
|
+
events = commService.listEvents(teamName, {
|
|
184
|
+
channel: opts.channel,
|
|
185
|
+
signal: opts.signal,
|
|
186
|
+
sender: opts.sender,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (events.length === 0) {
|
|
191
|
+
console.log("No signal events found.");
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
for (const e of events) {
|
|
196
|
+
const payload =
|
|
197
|
+
e.payload && Object.keys(e.payload).length > 0
|
|
198
|
+
? ` ${JSON.stringify(e.payload)}`
|
|
199
|
+
: "";
|
|
200
|
+
console.log(
|
|
201
|
+
` #${e.id} [${e.channel}] ${e.signal} from ${e.sender}${payload}`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
return template;
|
|
207
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { createDatabase } from "./db/database";
|
|
5
|
+
import { createTeamCommands } from "./cli/team";
|
|
6
|
+
import { createTaskCommands } from "./cli/task";
|
|
7
|
+
import { createMessageCommands } from "./cli/message";
|
|
8
|
+
import { createAgentCommands } from "./cli/agent";
|
|
9
|
+
import { createTemplateCommands } from "./cli/template";
|
|
10
|
+
import { createGenerateCommands } from "./cli/generate";
|
|
11
|
+
import { MockSpawner } from "./spawner/mock";
|
|
12
|
+
import type { AgentSpawner } from "./types";
|
|
13
|
+
|
|
14
|
+
function loadSpawner(): AgentSpawner {
|
|
15
|
+
try {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
|
+
const { ACPFactorySpawner } = require("./spawner/acp-factory");
|
|
18
|
+
return new ACPFactorySpawner();
|
|
19
|
+
} catch {
|
|
20
|
+
// Fall back to mock spawner if acp-factory is not available
|
|
21
|
+
return new MockSpawner();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const db = createDatabase();
|
|
26
|
+
const spawner = loadSpawner();
|
|
27
|
+
|
|
28
|
+
const program = new Command();
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.name("openteams")
|
|
32
|
+
.description("Multi-agent team coordination CLI")
|
|
33
|
+
.version("0.1.0");
|
|
34
|
+
|
|
35
|
+
program.addCommand(createTeamCommands(db));
|
|
36
|
+
program.addCommand(createTaskCommands(db));
|
|
37
|
+
program.addCommand(createMessageCommands(db));
|
|
38
|
+
program.addCommand(createAgentCommands(db, spawner));
|
|
39
|
+
program.addCommand(createTemplateCommands(db));
|
|
40
|
+
program.addCommand(createGenerateCommands());
|
|
41
|
+
|
|
42
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
43
|
+
console.error(err.message);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
});
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
import {
|
|
4
|
+
createInMemoryDatabase,
|
|
5
|
+
getSchemaVersion,
|
|
6
|
+
applyMigrations,
|
|
7
|
+
CURRENT_VERSION,
|
|
8
|
+
} from "./database";
|
|
9
|
+
import type { Migration } from "./database";
|
|
10
|
+
|
|
11
|
+
describe("database", () => {
|
|
12
|
+
it("creates an in-memory database with all tables", () => {
|
|
13
|
+
const db = createInMemoryDatabase();
|
|
14
|
+
|
|
15
|
+
const tables = db
|
|
16
|
+
.prepare(
|
|
17
|
+
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
|
|
18
|
+
)
|
|
19
|
+
.all() as Array<{ name: string }>;
|
|
20
|
+
|
|
21
|
+
const tableNames = tables.map((t) => t.name);
|
|
22
|
+
expect(tableNames).toContain("teams");
|
|
23
|
+
expect(tableNames).toContain("members");
|
|
24
|
+
expect(tableNames).toContain("tasks");
|
|
25
|
+
expect(tableNames).toContain("task_deps");
|
|
26
|
+
expect(tableNames).toContain("messages");
|
|
27
|
+
expect(tableNames).toContain("schema_version");
|
|
28
|
+
expect(tableNames).toContain("channels");
|
|
29
|
+
expect(tableNames).toContain("channel_signals");
|
|
30
|
+
expect(tableNames).toContain("subscriptions");
|
|
31
|
+
expect(tableNames).toContain("emissions");
|
|
32
|
+
expect(tableNames).toContain("peer_routes");
|
|
33
|
+
expect(tableNames).toContain("signal_events");
|
|
34
|
+
expect(tableNames).toContain("spawn_rules");
|
|
35
|
+
|
|
36
|
+
db.close();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("stores schema version", () => {
|
|
40
|
+
const db = createInMemoryDatabase();
|
|
41
|
+
|
|
42
|
+
const row = db
|
|
43
|
+
.prepare("SELECT version FROM schema_version LIMIT 1")
|
|
44
|
+
.get() as { version: number };
|
|
45
|
+
|
|
46
|
+
expect(row.version).toBe(CURRENT_VERSION);
|
|
47
|
+
db.close();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("enables WAL mode and foreign keys", () => {
|
|
51
|
+
const db = createInMemoryDatabase();
|
|
52
|
+
|
|
53
|
+
const wal = db.pragma("journal_mode") as Array<{ journal_mode: string }>;
|
|
54
|
+
// In-memory databases may use 'memory' instead of 'wal'
|
|
55
|
+
expect(["wal", "memory"]).toContain(wal[0].journal_mode);
|
|
56
|
+
|
|
57
|
+
const fk = db.pragma("foreign_keys") as Array<{ foreign_keys: number }>;
|
|
58
|
+
expect(fk[0].foreign_keys).toBe(1);
|
|
59
|
+
|
|
60
|
+
db.close();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("is idempotent - can be called multiple times on same db", () => {
|
|
64
|
+
const db = createInMemoryDatabase();
|
|
65
|
+
|
|
66
|
+
// Calling schema creation again should not fail
|
|
67
|
+
db.exec(
|
|
68
|
+
"CREATE TABLE IF NOT EXISTS teams (name TEXT PRIMARY KEY, description TEXT, agent_type TEXT, created_at TEXT, status TEXT)"
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
db.close();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe("migrations", () => {
|
|
76
|
+
it("getSchemaVersion returns 0 for empty schema_version table", () => {
|
|
77
|
+
const db = new Database(":memory:");
|
|
78
|
+
db.exec("CREATE TABLE schema_version (version INTEGER PRIMARY KEY)");
|
|
79
|
+
|
|
80
|
+
expect(getSchemaVersion(db)).toBe(0);
|
|
81
|
+
db.close();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("getSchemaVersion returns stored version", () => {
|
|
85
|
+
const db = createInMemoryDatabase();
|
|
86
|
+
expect(getSchemaVersion(db)).toBe(CURRENT_VERSION);
|
|
87
|
+
db.close();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("applyMigrations runs pending migrations in order", () => {
|
|
91
|
+
const db = createInMemoryDatabase();
|
|
92
|
+
|
|
93
|
+
// Simulate a v2 database that needs v3 and v4
|
|
94
|
+
const migrations: Migration[] = [
|
|
95
|
+
{ version: 3, up: "ALTER TABLE teams ADD COLUMN extra1 TEXT;" },
|
|
96
|
+
{ version: 4, up: "ALTER TABLE teams ADD COLUMN extra2 TEXT;" },
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
const result = applyMigrations(db, 2, migrations);
|
|
100
|
+
expect(result).toBe(4);
|
|
101
|
+
|
|
102
|
+
// Verify version was updated
|
|
103
|
+
expect(getSchemaVersion(db)).toBe(4);
|
|
104
|
+
|
|
105
|
+
// Verify columns were added
|
|
106
|
+
const info = db.prepare("PRAGMA table_info(teams)").all() as Array<{
|
|
107
|
+
name: string;
|
|
108
|
+
}>;
|
|
109
|
+
const colNames = info.map((c) => c.name);
|
|
110
|
+
expect(colNames).toContain("extra1");
|
|
111
|
+
expect(colNames).toContain("extra2");
|
|
112
|
+
|
|
113
|
+
db.close();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("applyMigrations skips already-applied versions", () => {
|
|
117
|
+
const db = createInMemoryDatabase();
|
|
118
|
+
|
|
119
|
+
const migrations: Migration[] = [
|
|
120
|
+
{ version: 1, up: "SELECT 1;" }, // already past this
|
|
121
|
+
{ version: 2, up: "SELECT 1;" }, // already at this
|
|
122
|
+
{ version: 3, up: "ALTER TABLE teams ADD COLUMN new_col TEXT;" },
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
const result = applyMigrations(db, 2, migrations);
|
|
126
|
+
expect(result).toBe(3);
|
|
127
|
+
|
|
128
|
+
// Only the v3 migration should have run
|
|
129
|
+
const info = db.prepare("PRAGMA table_info(teams)").all() as Array<{
|
|
130
|
+
name: string;
|
|
131
|
+
}>;
|
|
132
|
+
const colNames = info.map((c) => c.name);
|
|
133
|
+
expect(colNames).toContain("new_col");
|
|
134
|
+
|
|
135
|
+
db.close();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("applyMigrations returns current version when nothing to apply", () => {
|
|
139
|
+
const db = createInMemoryDatabase();
|
|
140
|
+
|
|
141
|
+
const result = applyMigrations(db, CURRENT_VERSION, []);
|
|
142
|
+
expect(result).toBe(CURRENT_VERSION);
|
|
143
|
+
|
|
144
|
+
db.close();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("applyMigrations rolls back on failure", () => {
|
|
148
|
+
const db = createInMemoryDatabase();
|
|
149
|
+
|
|
150
|
+
const migrations: Migration[] = [
|
|
151
|
+
{ version: 3, up: "ALTER TABLE teams ADD COLUMN good_col TEXT;" },
|
|
152
|
+
{ version: 4, up: "ALTER TABLE nonexistent_table ADD COLUMN bad TEXT;" },
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
expect(() => applyMigrations(db, 2, migrations)).toThrow();
|
|
156
|
+
|
|
157
|
+
// Version should still be 2 — transaction rolled back
|
|
158
|
+
expect(getSchemaVersion(db)).toBe(CURRENT_VERSION);
|
|
159
|
+
|
|
160
|
+
// The v3 column should NOT exist — entire transaction rolled back
|
|
161
|
+
const info = db.prepare("PRAGMA table_info(teams)").all() as Array<{
|
|
162
|
+
name: string;
|
|
163
|
+
}>;
|
|
164
|
+
const colNames = info.map((c) => c.name);
|
|
165
|
+
expect(colNames).not.toContain("good_col");
|
|
166
|
+
|
|
167
|
+
db.close();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("applies migrations in version order regardless of array order", () => {
|
|
171
|
+
const db = createInMemoryDatabase();
|
|
172
|
+
|
|
173
|
+
// Provide migrations out of order
|
|
174
|
+
const migrations: Migration[] = [
|
|
175
|
+
{ version: 4, up: "ALTER TABLE teams ADD COLUMN col_b TEXT;" },
|
|
176
|
+
{ version: 3, up: "ALTER TABLE teams ADD COLUMN col_a TEXT;" },
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
const result = applyMigrations(db, 2, migrations);
|
|
180
|
+
expect(result).toBe(4);
|
|
181
|
+
expect(getSchemaVersion(db)).toBe(4);
|
|
182
|
+
|
|
183
|
+
db.close();
|
|
184
|
+
});
|
|
185
|
+
});
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Migration framework
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// SCHEMA_SQL is the full current schema for fresh installs.
|
|
10
|
+
// MIGRATIONS handles upgrades for existing databases.
|
|
11
|
+
//
|
|
12
|
+
// When adding a new schema change:
|
|
13
|
+
// 1. Update SCHEMA_SQL to include the change (for fresh installs)
|
|
14
|
+
// 2. Add a Migration entry with the next version number (for existing installs)
|
|
15
|
+
// 3. Bump CURRENT_VERSION to match
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
export interface Migration {
|
|
19
|
+
version: number;
|
|
20
|
+
up: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const CURRENT_VERSION = 2;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Migrations applied incrementally to existing databases.
|
|
27
|
+
* Each migration brings the schema from (version - 1) to version.
|
|
28
|
+
* For now this is empty because v2 is the baseline — no users have
|
|
29
|
+
* older databases. Future changes add entries here.
|
|
30
|
+
*/
|
|
31
|
+
export const MIGRATIONS: Migration[] = [
|
|
32
|
+
// Example for a future change:
|
|
33
|
+
// {
|
|
34
|
+
// version: 3,
|
|
35
|
+
// up: `ALTER TABLE teams ADD COLUMN some_new_col TEXT;`
|
|
36
|
+
// },
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const SCHEMA_SQL = `
|
|
40
|
+
CREATE TABLE IF NOT EXISTS schema_version (
|
|
41
|
+
version INTEGER PRIMARY KEY
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
CREATE TABLE IF NOT EXISTS teams (
|
|
45
|
+
name TEXT PRIMARY KEY,
|
|
46
|
+
description TEXT,
|
|
47
|
+
agent_type TEXT,
|
|
48
|
+
template_name TEXT,
|
|
49
|
+
template_path TEXT,
|
|
50
|
+
enforcement TEXT DEFAULT 'permissive' CHECK (enforcement IN ('strict', 'permissive', 'audit')),
|
|
51
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
52
|
+
status TEXT DEFAULT 'active' CHECK (status IN ('active', 'deleted'))
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
CREATE TABLE IF NOT EXISTS members (
|
|
56
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
57
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
58
|
+
agent_name TEXT NOT NULL,
|
|
59
|
+
agent_id TEXT,
|
|
60
|
+
agent_type TEXT DEFAULT 'general-purpose',
|
|
61
|
+
role TEXT,
|
|
62
|
+
status TEXT DEFAULT 'idle' CHECK (status IN ('idle', 'running', 'shutdown')),
|
|
63
|
+
spawn_prompt TEXT,
|
|
64
|
+
model TEXT,
|
|
65
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
66
|
+
UNIQUE(team_name, agent_name)
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
70
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
71
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
72
|
+
subject TEXT NOT NULL,
|
|
73
|
+
description TEXT NOT NULL,
|
|
74
|
+
active_form TEXT,
|
|
75
|
+
status TEXT DEFAULT 'pending' CHECK (status IN ('pending', 'in_progress', 'completed', 'deleted')),
|
|
76
|
+
owner TEXT,
|
|
77
|
+
metadata TEXT DEFAULT '{}',
|
|
78
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
79
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
CREATE TABLE IF NOT EXISTS task_deps (
|
|
83
|
+
task_id INTEGER NOT NULL REFERENCES tasks(id),
|
|
84
|
+
blocked_by INTEGER NOT NULL REFERENCES tasks(id),
|
|
85
|
+
PRIMARY KEY (task_id, blocked_by)
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
89
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
90
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
91
|
+
type TEXT NOT NULL CHECK (type IN ('message', 'broadcast', 'shutdown_request', 'shutdown_response', 'plan_approval_response')),
|
|
92
|
+
sender TEXT NOT NULL,
|
|
93
|
+
recipient TEXT,
|
|
94
|
+
content TEXT NOT NULL,
|
|
95
|
+
summary TEXT,
|
|
96
|
+
request_id TEXT,
|
|
97
|
+
approve INTEGER,
|
|
98
|
+
delivered INTEGER DEFAULT 0,
|
|
99
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
-- Communication: channel definitions per team
|
|
103
|
+
CREATE TABLE IF NOT EXISTS channels (
|
|
104
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
105
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
106
|
+
name TEXT NOT NULL,
|
|
107
|
+
description TEXT,
|
|
108
|
+
UNIQUE(team_name, name)
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
-- Signals belonging to a channel
|
|
112
|
+
CREATE TABLE IF NOT EXISTS channel_signals (
|
|
113
|
+
channel_id INTEGER NOT NULL REFERENCES channels(id),
|
|
114
|
+
signal TEXT NOT NULL,
|
|
115
|
+
PRIMARY KEY (channel_id, signal)
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
-- Role subscriptions to channels (with optional signal filter)
|
|
119
|
+
CREATE TABLE IF NOT EXISTS subscriptions (
|
|
120
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
121
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
122
|
+
role TEXT NOT NULL,
|
|
123
|
+
channel TEXT NOT NULL,
|
|
124
|
+
signal TEXT,
|
|
125
|
+
UNIQUE(team_name, role, channel, signal)
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
-- Emission permissions per role
|
|
129
|
+
CREATE TABLE IF NOT EXISTS emissions (
|
|
130
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
131
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
132
|
+
role TEXT NOT NULL,
|
|
133
|
+
signal TEXT NOT NULL,
|
|
134
|
+
UNIQUE(team_name, role, signal)
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
-- Peer routing rules
|
|
138
|
+
CREATE TABLE IF NOT EXISTS peer_routes (
|
|
139
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
140
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
141
|
+
from_role TEXT NOT NULL,
|
|
142
|
+
to_role TEXT NOT NULL,
|
|
143
|
+
via TEXT NOT NULL DEFAULT 'direct' CHECK (via IN ('direct', 'topic', 'scope')),
|
|
144
|
+
signals TEXT DEFAULT '[]'
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
-- Signal events log
|
|
148
|
+
CREATE TABLE IF NOT EXISTS signal_events (
|
|
149
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
150
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
151
|
+
channel TEXT NOT NULL,
|
|
152
|
+
signal TEXT NOT NULL,
|
|
153
|
+
sender TEXT NOT NULL,
|
|
154
|
+
payload TEXT DEFAULT '{}',
|
|
155
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
-- Spawn rules per team
|
|
159
|
+
CREATE TABLE IF NOT EXISTS spawn_rules (
|
|
160
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
161
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
162
|
+
from_role TEXT NOT NULL,
|
|
163
|
+
to_role TEXT NOT NULL,
|
|
164
|
+
UNIQUE(team_name, from_role, to_role)
|
|
165
|
+
);
|
|
166
|
+
`;
|
|
167
|
+
|
|
168
|
+
function getDefaultDbPath(): string {
|
|
169
|
+
const dir = path.join(os.homedir(), ".openteams");
|
|
170
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
171
|
+
return path.join(dir, "openteams.db");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Read the current schema version from the database.
|
|
176
|
+
* Returns 0 if no version row exists (fresh install).
|
|
177
|
+
*/
|
|
178
|
+
export function getSchemaVersion(db: Database.Database): number {
|
|
179
|
+
const row = db
|
|
180
|
+
.prepare("SELECT version FROM schema_version LIMIT 1")
|
|
181
|
+
.get() as { version: number } | undefined;
|
|
182
|
+
return row?.version ?? 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Apply pending migrations to bring the database up to CURRENT_VERSION.
|
|
187
|
+
* Runs inside a transaction so partial migrations are rolled back.
|
|
188
|
+
*/
|
|
189
|
+
export function applyMigrations(
|
|
190
|
+
db: Database.Database,
|
|
191
|
+
fromVersion: number,
|
|
192
|
+
migrations: Migration[] = MIGRATIONS
|
|
193
|
+
): number {
|
|
194
|
+
const pending = migrations
|
|
195
|
+
.filter((m) => m.version > fromVersion)
|
|
196
|
+
.sort((a, b) => a.version - b.version);
|
|
197
|
+
|
|
198
|
+
if (pending.length === 0) return fromVersion;
|
|
199
|
+
|
|
200
|
+
const targetVersion = pending[pending.length - 1].version;
|
|
201
|
+
|
|
202
|
+
const migrate = db.transaction(() => {
|
|
203
|
+
for (const migration of pending) {
|
|
204
|
+
db.exec(migration.up);
|
|
205
|
+
}
|
|
206
|
+
db.prepare("UPDATE schema_version SET version = ?").run(targetVersion);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
migrate();
|
|
210
|
+
return targetVersion;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function createDatabase(dbPath?: string): Database.Database {
|
|
214
|
+
const resolvedPath = dbPath ?? getDefaultDbPath();
|
|
215
|
+
const db = new Database(resolvedPath);
|
|
216
|
+
|
|
217
|
+
db.pragma("journal_mode = WAL");
|
|
218
|
+
db.pragma("foreign_keys = ON");
|
|
219
|
+
|
|
220
|
+
// Create all tables (IF NOT EXISTS is safe for both fresh and existing DBs)
|
|
221
|
+
db.exec(SCHEMA_SQL);
|
|
222
|
+
|
|
223
|
+
const currentVersion = getSchemaVersion(db);
|
|
224
|
+
|
|
225
|
+
if (currentVersion === 0) {
|
|
226
|
+
// Fresh install — stamp with current version
|
|
227
|
+
db.prepare("INSERT INTO schema_version (version) VALUES (?)").run(
|
|
228
|
+
CURRENT_VERSION
|
|
229
|
+
);
|
|
230
|
+
} else if (currentVersion < CURRENT_VERSION) {
|
|
231
|
+
// Existing database needs migration
|
|
232
|
+
applyMigrations(db, currentVersion);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return db;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function createInMemoryDatabase(): Database.Database {
|
|
239
|
+
return createDatabase(":memory:");
|
|
240
|
+
}
|