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,524 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E Tests for UnifiedTaskToolProvider with real OpenTasks daemon
|
|
3
|
+
*
|
|
4
|
+
* Starts a real opentasks daemon, connects via IPCOpenTasksClient,
|
|
5
|
+
* creates an OpenTasksTaskBackend, and exercises all 7 tools end-to-end.
|
|
6
|
+
*
|
|
7
|
+
* Requires: opentasks@0.0.3+ installed
|
|
8
|
+
*
|
|
9
|
+
* @module task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
13
|
+
import * as fs from "fs";
|
|
14
|
+
import * as path from "path";
|
|
15
|
+
import * as os from "os";
|
|
16
|
+
import { createEventStore, type EventStore } from "../../../../store/event-store.js";
|
|
17
|
+
import { OpenTasksTaskBackend } from "../../opentasks/backend.js";
|
|
18
|
+
import { IPCOpenTasksClient } from "../../opentasks/client.js";
|
|
19
|
+
import {
|
|
20
|
+
UnifiedTaskToolProvider,
|
|
21
|
+
type GetToolContext,
|
|
22
|
+
} from "../../unified-tool-provider.js";
|
|
23
|
+
import type { MCPToolDefinition } from "../../types.js";
|
|
24
|
+
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// Helpers
|
|
27
|
+
// =============================================================================
|
|
28
|
+
|
|
29
|
+
const TEST_AGENT_ID = "agent_e2e_test";
|
|
30
|
+
const getContext: GetToolContext = () => ({ agent_id: TEST_AGENT_ID });
|
|
31
|
+
|
|
32
|
+
function findTool(
|
|
33
|
+
tools: MCPToolDefinition[],
|
|
34
|
+
name: string
|
|
35
|
+
): MCPToolDefinition {
|
|
36
|
+
const tool = tools.find((t) => t.name === name);
|
|
37
|
+
if (!tool) throw new Error(`Tool not found: ${name}`);
|
|
38
|
+
return tool;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Wait for a condition with timeout
|
|
43
|
+
*/
|
|
44
|
+
async function waitFor(
|
|
45
|
+
condition: () => Promise<boolean> | boolean,
|
|
46
|
+
timeoutMs = 5000,
|
|
47
|
+
intervalMs = 100
|
|
48
|
+
): Promise<void> {
|
|
49
|
+
const start = Date.now();
|
|
50
|
+
while (Date.now() - start < timeoutMs) {
|
|
51
|
+
if (await condition()) return;
|
|
52
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`Timed out after ${timeoutMs}ms`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// Test Suite
|
|
59
|
+
// =============================================================================
|
|
60
|
+
|
|
61
|
+
describe("UnifiedTaskToolProvider E2E with real OpenTasks", () => {
|
|
62
|
+
let tempDir: string;
|
|
63
|
+
let locationPath: string;
|
|
64
|
+
let daemon: any;
|
|
65
|
+
let socketPath: string;
|
|
66
|
+
let eventStore: EventStore;
|
|
67
|
+
let otClient: IPCOpenTasksClient;
|
|
68
|
+
let backend: OpenTasksTaskBackend;
|
|
69
|
+
let provider: UnifiedTaskToolProvider;
|
|
70
|
+
|
|
71
|
+
beforeAll(async () => {
|
|
72
|
+
// Create temp directory for opentasks data
|
|
73
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "macro-e2e-opentasks-"));
|
|
74
|
+
locationPath = path.join(tempDir, ".opentasks");
|
|
75
|
+
fs.mkdirSync(locationPath, { recursive: true });
|
|
76
|
+
|
|
77
|
+
const registryPath = path.join(tempDir, "registry.json");
|
|
78
|
+
|
|
79
|
+
// Start a real opentasks daemon
|
|
80
|
+
const opentasks = await import("opentasks");
|
|
81
|
+
|
|
82
|
+
daemon = await opentasks.createDaemonWithStore({
|
|
83
|
+
locationPath,
|
|
84
|
+
version: "0.0.3",
|
|
85
|
+
registryPath,
|
|
86
|
+
shutdownTimeoutMs: 2000,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
await daemon.start();
|
|
90
|
+
socketPath = daemon.socketPath;
|
|
91
|
+
|
|
92
|
+
// Create macro-agent event store (in-memory)
|
|
93
|
+
eventStore = await createEventStore({ inMemory: true });
|
|
94
|
+
|
|
95
|
+
// Create IPCOpenTasksClient pointing at the real daemon
|
|
96
|
+
otClient = new IPCOpenTasksClient({
|
|
97
|
+
socketPath,
|
|
98
|
+
autoConnect: true,
|
|
99
|
+
timeout: 10000,
|
|
100
|
+
});
|
|
101
|
+
await otClient.connect();
|
|
102
|
+
|
|
103
|
+
// Create OpenTasks backend
|
|
104
|
+
backend = new OpenTasksTaskBackend(eventStore, otClient, {
|
|
105
|
+
socketPath,
|
|
106
|
+
syncStatus: true,
|
|
107
|
+
sourceLabel: "e2e-test",
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Create unified tool provider with all 7 tools
|
|
111
|
+
provider = new UnifiedTaskToolProvider(backend, getContext, otClient);
|
|
112
|
+
}, 30000);
|
|
113
|
+
|
|
114
|
+
afterAll(async () => {
|
|
115
|
+
// Teardown in reverse order
|
|
116
|
+
try {
|
|
117
|
+
otClient?.disconnect();
|
|
118
|
+
} catch { /* ignore */ }
|
|
119
|
+
try {
|
|
120
|
+
await daemon?.stop();
|
|
121
|
+
} catch { /* ignore */ }
|
|
122
|
+
try {
|
|
123
|
+
await eventStore?.close();
|
|
124
|
+
} catch { /* ignore */ }
|
|
125
|
+
try {
|
|
126
|
+
if (tempDir) fs.rmSync(tempDir, { recursive: true, force: true });
|
|
127
|
+
} catch { /* ignore */ }
|
|
128
|
+
}, 15000);
|
|
129
|
+
|
|
130
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
131
|
+
// Tool Exposure
|
|
132
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
133
|
+
|
|
134
|
+
it("should expose all 8 tools with OpenTasks client", () => {
|
|
135
|
+
const tools = provider.getTools();
|
|
136
|
+
expect(tools).toHaveLength(8);
|
|
137
|
+
expect(tools.map((t) => t.name)).toEqual([
|
|
138
|
+
"create_task",
|
|
139
|
+
"get_task",
|
|
140
|
+
"list_tasks",
|
|
141
|
+
"assign_task",
|
|
142
|
+
"task",
|
|
143
|
+
"link",
|
|
144
|
+
"annotate",
|
|
145
|
+
"list_providers",
|
|
146
|
+
]);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
150
|
+
// Core CRUD Tools (real backend → real daemon)
|
|
151
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
152
|
+
|
|
153
|
+
describe("create_task → get_task roundtrip", () => {
|
|
154
|
+
let createdTaskId: string;
|
|
155
|
+
|
|
156
|
+
it("should create a task via create_task tool", async () => {
|
|
157
|
+
const tool = findTool(provider.getTools(), "create_task");
|
|
158
|
+
const result = (await tool.handler({
|
|
159
|
+
description: "E2E test task",
|
|
160
|
+
})) as { task_id: string; status: string; external_id?: string };
|
|
161
|
+
|
|
162
|
+
expect(result.task_id).toMatch(/^task_/);
|
|
163
|
+
expect(result.status).toBe("pending");
|
|
164
|
+
createdTaskId = result.task_id;
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("should retrieve the task via get_task tool", async () => {
|
|
168
|
+
const tool = findTool(provider.getTools(), "get_task");
|
|
169
|
+
const result = (await tool.handler({
|
|
170
|
+
task_id: createdTaskId,
|
|
171
|
+
})) as { id: string; description: string; status: string };
|
|
172
|
+
|
|
173
|
+
expect(result.id).toBe(createdTaskId);
|
|
174
|
+
expect(result.description).toBe("E2E test task");
|
|
175
|
+
expect(result.status).toBe("pending");
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
describe("list_tasks", () => {
|
|
180
|
+
it("should list tasks with filters", async () => {
|
|
181
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
182
|
+
const listTool = findTool(provider.getTools(), "list_tasks");
|
|
183
|
+
|
|
184
|
+
// Create a couple tasks
|
|
185
|
+
await createTool.handler({ description: "List test A" });
|
|
186
|
+
await createTool.handler({ description: "List test B" });
|
|
187
|
+
|
|
188
|
+
const result = (await listTool.handler({})) as {
|
|
189
|
+
tasks: Array<{ id: string; description: string }>;
|
|
190
|
+
total: number;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
expect(result.total).toBeGreaterThanOrEqual(2);
|
|
194
|
+
expect(result.tasks.some((t) => t.description === "List test A")).toBe(true);
|
|
195
|
+
expect(result.tasks.some((t) => t.description === "List test B")).toBe(true);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe("assign_task", () => {
|
|
200
|
+
it("should assign a task to an agent", async () => {
|
|
201
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
202
|
+
const assignTool = findTool(provider.getTools(), "assign_task");
|
|
203
|
+
const getTool = findTool(provider.getTools(), "get_task");
|
|
204
|
+
|
|
205
|
+
// Create
|
|
206
|
+
const created = (await createTool.handler({
|
|
207
|
+
description: "Assign test task",
|
|
208
|
+
})) as { task_id: string };
|
|
209
|
+
|
|
210
|
+
// Assign
|
|
211
|
+
const assignResult = (await assignTool.handler({
|
|
212
|
+
task_id: created.task_id,
|
|
213
|
+
agent_id: "agent_worker_1",
|
|
214
|
+
})) as { assigned_agent: string; assigned: boolean };
|
|
215
|
+
|
|
216
|
+
expect(assignResult.assigned_agent).toBe("agent_worker_1");
|
|
217
|
+
expect(assignResult.assigned).toBe(true);
|
|
218
|
+
|
|
219
|
+
// Verify
|
|
220
|
+
const task = (await getTool.handler({
|
|
221
|
+
task_id: created.task_id,
|
|
222
|
+
})) as { assigned_agent: string; status: string };
|
|
223
|
+
|
|
224
|
+
expect(task.assigned_agent).toBe("agent_worker_1");
|
|
225
|
+
expect(task.status).toBe("assigned");
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
230
|
+
// OpenTasks Graph Tools (real daemon)
|
|
231
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
232
|
+
|
|
233
|
+
describe("task tool", () => {
|
|
234
|
+
it("should transition a task through its lifecycle and sync to EventStore", async () => {
|
|
235
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
236
|
+
const taskTool = findTool(provider.getTools(), "task");
|
|
237
|
+
const getTool = findTool(provider.getTools(), "get_task");
|
|
238
|
+
|
|
239
|
+
const created = (await createTool.handler({
|
|
240
|
+
description: "Lifecycle test task",
|
|
241
|
+
})) as { task_id: string; external_id?: string };
|
|
242
|
+
|
|
243
|
+
const taskDetails = (await getTool.handler({
|
|
244
|
+
task_id: created.task_id,
|
|
245
|
+
})) as { external_id?: string; status: string };
|
|
246
|
+
|
|
247
|
+
const externalId = taskDetails.external_id;
|
|
248
|
+
expect(externalId).toBeDefined();
|
|
249
|
+
expect(taskDetails.status).toBe("pending");
|
|
250
|
+
|
|
251
|
+
// Start the task via opentasks daemon
|
|
252
|
+
const startResult = await taskTool.handler({
|
|
253
|
+
transition: { id: externalId, action: "start" },
|
|
254
|
+
});
|
|
255
|
+
expect(startResult).toBeDefined();
|
|
256
|
+
|
|
257
|
+
// Verify EventStore was synced — get_task reads from EventStore
|
|
258
|
+
const afterStart = (await getTool.handler({
|
|
259
|
+
task_id: created.task_id,
|
|
260
|
+
})) as { status: string };
|
|
261
|
+
expect(afterStart.status).toBe("in_progress");
|
|
262
|
+
|
|
263
|
+
// Complete the task via opentasks daemon
|
|
264
|
+
const completeResult = await taskTool.handler({
|
|
265
|
+
transition: { id: externalId, action: "complete" },
|
|
266
|
+
});
|
|
267
|
+
expect(completeResult).toBeDefined();
|
|
268
|
+
|
|
269
|
+
// Verify EventStore was synced
|
|
270
|
+
const afterComplete = (await getTool.handler({
|
|
271
|
+
task_id: created.task_id,
|
|
272
|
+
})) as { status: string };
|
|
273
|
+
expect(afterComplete.status).toBe("completed");
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it("should sync task assignment via task tool to EventStore", async () => {
|
|
277
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
278
|
+
const taskTool = findTool(provider.getTools(), "task");
|
|
279
|
+
const getTool = findTool(provider.getTools(), "get_task");
|
|
280
|
+
|
|
281
|
+
const created = (await createTool.handler({
|
|
282
|
+
description: "Assign sync test task",
|
|
283
|
+
})) as { task_id: string };
|
|
284
|
+
|
|
285
|
+
const taskDetails = (await getTool.handler({
|
|
286
|
+
task_id: created.task_id,
|
|
287
|
+
})) as { external_id: string };
|
|
288
|
+
|
|
289
|
+
// Assign via task tool (opentasks daemon path)
|
|
290
|
+
await taskTool.handler({
|
|
291
|
+
assign: { id: taskDetails.external_id, assignee: "agent_worker_2" },
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Verify EventStore was synced
|
|
295
|
+
const afterAssign = (await getTool.handler({
|
|
296
|
+
task_id: created.task_id,
|
|
297
|
+
})) as { assigned_agent: string };
|
|
298
|
+
expect(afterAssign.assigned_agent).toBe("agent_worker_2");
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it("should query ready tasks", async () => {
|
|
302
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
303
|
+
const taskTool = findTool(provider.getTools(), "task");
|
|
304
|
+
|
|
305
|
+
// Create a fresh task (should be ready since no blockers)
|
|
306
|
+
await createTool.handler({ description: "Ready test task" });
|
|
307
|
+
|
|
308
|
+
const readyResult = (await taskTool.handler({
|
|
309
|
+
ready: {},
|
|
310
|
+
})) as { type?: string; items?: unknown[] };
|
|
311
|
+
|
|
312
|
+
expect(readyResult).toBeDefined();
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it("should get valid actions for a task", async () => {
|
|
316
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
317
|
+
const taskTool = findTool(provider.getTools(), "task");
|
|
318
|
+
const getTool = findTool(provider.getTools(), "get_task");
|
|
319
|
+
|
|
320
|
+
const created = (await createTool.handler({
|
|
321
|
+
description: "Valid actions test",
|
|
322
|
+
})) as { task_id: string };
|
|
323
|
+
|
|
324
|
+
const taskDetails = (await getTool.handler({
|
|
325
|
+
task_id: created.task_id,
|
|
326
|
+
})) as { external_id?: string };
|
|
327
|
+
|
|
328
|
+
const result = await taskTool.handler({
|
|
329
|
+
validActions: { id: taskDetails.external_id! },
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
expect(result).toBeDefined();
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
describe("link tool", () => {
|
|
337
|
+
it("should create and remove edges between tasks", async () => {
|
|
338
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
339
|
+
const linkTool = findTool(provider.getTools(), "link");
|
|
340
|
+
const getTool = findTool(provider.getTools(), "get_task");
|
|
341
|
+
|
|
342
|
+
// Create two tasks
|
|
343
|
+
const blocker = (await createTool.handler({
|
|
344
|
+
description: "Blocker task",
|
|
345
|
+
})) as { task_id: string };
|
|
346
|
+
const blocked = (await createTool.handler({
|
|
347
|
+
description: "Blocked task",
|
|
348
|
+
})) as { task_id: string };
|
|
349
|
+
|
|
350
|
+
// Get external IDs
|
|
351
|
+
const blockerDetails = (await getTool.handler({
|
|
352
|
+
task_id: blocker.task_id,
|
|
353
|
+
})) as { external_id: string };
|
|
354
|
+
const blockedDetails = (await getTool.handler({
|
|
355
|
+
task_id: blocked.task_id,
|
|
356
|
+
})) as { external_id: string };
|
|
357
|
+
|
|
358
|
+
// Create a "blocks" edge
|
|
359
|
+
const createResult = (await linkTool.handler({
|
|
360
|
+
from_id: blockerDetails.external_id,
|
|
361
|
+
to_id: blockedDetails.external_id,
|
|
362
|
+
type: "blocks",
|
|
363
|
+
})) as { created: boolean };
|
|
364
|
+
|
|
365
|
+
expect(createResult.created).toBe(true);
|
|
366
|
+
|
|
367
|
+
// Remove the edge
|
|
368
|
+
const removeResult = (await linkTool.handler({
|
|
369
|
+
from_id: blockerDetails.external_id,
|
|
370
|
+
to_id: blockedDetails.external_id,
|
|
371
|
+
type: "blocks",
|
|
372
|
+
remove: true,
|
|
373
|
+
})) as { removed: boolean };
|
|
374
|
+
|
|
375
|
+
expect(removeResult.removed).toBe(true);
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
describe("annotate tool", () => {
|
|
380
|
+
it("should create feedback on a task", async () => {
|
|
381
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
382
|
+
const annotateTool = findTool(provider.getTools(), "annotate");
|
|
383
|
+
const getTool = findTool(provider.getTools(), "get_task");
|
|
384
|
+
|
|
385
|
+
// Create a task
|
|
386
|
+
const created = (await createTool.handler({
|
|
387
|
+
description: "Feedback target task",
|
|
388
|
+
})) as { task_id: string };
|
|
389
|
+
|
|
390
|
+
const details = (await getTool.handler({
|
|
391
|
+
task_id: created.task_id,
|
|
392
|
+
})) as { external_id: string };
|
|
393
|
+
|
|
394
|
+
// Add a comment
|
|
395
|
+
const annotateResult = (await annotateTool.handler({
|
|
396
|
+
target_id: details.external_id,
|
|
397
|
+
content: "E2E test feedback comment",
|
|
398
|
+
feedback_type: "comment",
|
|
399
|
+
})) as { feedback_id: string; created: boolean; type: string };
|
|
400
|
+
|
|
401
|
+
expect(annotateResult.created).toBe(true);
|
|
402
|
+
expect(annotateResult.type).toBe("comment");
|
|
403
|
+
expect(annotateResult.feedback_id).toBeDefined();
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it("should resolve feedback", async () => {
|
|
407
|
+
const createTool = findTool(provider.getTools(), "create_task");
|
|
408
|
+
const annotateTool = findTool(provider.getTools(), "annotate");
|
|
409
|
+
const getTool = findTool(provider.getTools(), "get_task");
|
|
410
|
+
|
|
411
|
+
const created = (await createTool.handler({
|
|
412
|
+
description: "Resolve feedback target",
|
|
413
|
+
})) as { task_id: string };
|
|
414
|
+
|
|
415
|
+
const details = (await getTool.handler({
|
|
416
|
+
task_id: created.task_id,
|
|
417
|
+
})) as { external_id: string };
|
|
418
|
+
|
|
419
|
+
// Create feedback
|
|
420
|
+
const feedback = (await annotateTool.handler({
|
|
421
|
+
target_id: details.external_id,
|
|
422
|
+
content: "Feedback to resolve",
|
|
423
|
+
feedback_type: "suggestion",
|
|
424
|
+
})) as { feedback_id: string };
|
|
425
|
+
|
|
426
|
+
// Resolve it
|
|
427
|
+
const resolveResult = (await annotateTool.handler({
|
|
428
|
+
target_id: details.external_id,
|
|
429
|
+
resolve: feedback.feedback_id,
|
|
430
|
+
})) as { resolved: boolean; feedback_id: string };
|
|
431
|
+
|
|
432
|
+
expect(resolveResult.resolved).toBe(true);
|
|
433
|
+
expect(resolveResult.feedback_id).toBe(feedback.feedback_id);
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
438
|
+
// Full Workflow
|
|
439
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
440
|
+
|
|
441
|
+
describe("full workflow", () => {
|
|
442
|
+
it("should execute a complete task lifecycle: create → assign → link → annotate → transition", async () => {
|
|
443
|
+
const tools = provider.getTools();
|
|
444
|
+
const createTool = findTool(tools, "create_task");
|
|
445
|
+
const getTool = findTool(tools, "get_task");
|
|
446
|
+
const assignTool = findTool(tools, "assign_task");
|
|
447
|
+
const linkTool = findTool(tools, "link");
|
|
448
|
+
const annotateTool = findTool(tools, "annotate");
|
|
449
|
+
const taskTool = findTool(tools, "task");
|
|
450
|
+
|
|
451
|
+
// 1. Create parent and child tasks
|
|
452
|
+
const parent = (await createTool.handler({
|
|
453
|
+
description: "Full workflow parent task",
|
|
454
|
+
})) as { task_id: string };
|
|
455
|
+
|
|
456
|
+
const child = (await createTool.handler({
|
|
457
|
+
description: "Full workflow child task",
|
|
458
|
+
parent_task: parent.task_id,
|
|
459
|
+
})) as { task_id: string };
|
|
460
|
+
|
|
461
|
+
// 2. Get external IDs
|
|
462
|
+
const parentDetails = (await getTool.handler({
|
|
463
|
+
task_id: parent.task_id,
|
|
464
|
+
})) as { external_id: string };
|
|
465
|
+
|
|
466
|
+
const childDetails = (await getTool.handler({
|
|
467
|
+
task_id: child.task_id,
|
|
468
|
+
})) as { external_id: string };
|
|
469
|
+
|
|
470
|
+
expect(parentDetails.external_id).toBeDefined();
|
|
471
|
+
expect(childDetails.external_id).toBeDefined();
|
|
472
|
+
|
|
473
|
+
// 3. Create a "blocks" link: parent blocks child
|
|
474
|
+
const linkResult = (await linkTool.handler({
|
|
475
|
+
from_id: parentDetails.external_id,
|
|
476
|
+
to_id: childDetails.external_id,
|
|
477
|
+
type: "blocks",
|
|
478
|
+
})) as { created: boolean };
|
|
479
|
+
|
|
480
|
+
expect(linkResult.created).toBe(true);
|
|
481
|
+
|
|
482
|
+
// 4. Assign parent task
|
|
483
|
+
const assignResult = (await assignTool.handler({
|
|
484
|
+
task_id: parent.task_id,
|
|
485
|
+
agent_id: TEST_AGENT_ID,
|
|
486
|
+
})) as { assigned: boolean };
|
|
487
|
+
|
|
488
|
+
expect(assignResult.assigned).toBe(true);
|
|
489
|
+
|
|
490
|
+
// 5. Add feedback on the parent
|
|
491
|
+
const feedbackResult = (await annotateTool.handler({
|
|
492
|
+
target_id: parentDetails.external_id,
|
|
493
|
+
content: "Starting work on this task",
|
|
494
|
+
feedback_type: "comment",
|
|
495
|
+
})) as { created: boolean; feedback_id: string };
|
|
496
|
+
|
|
497
|
+
expect(feedbackResult.created).toBe(true);
|
|
498
|
+
|
|
499
|
+
// 6. Start parent via task tool
|
|
500
|
+
const startResult = (await taskTool.handler({
|
|
501
|
+
transition: { id: parentDetails.external_id, action: "start" },
|
|
502
|
+
})) as { success: boolean };
|
|
503
|
+
|
|
504
|
+
expect(startResult).toBeDefined();
|
|
505
|
+
|
|
506
|
+
// 7. Complete parent via task tool
|
|
507
|
+
const completeResult = (await taskTool.handler({
|
|
508
|
+
transition: { id: parentDetails.external_id, action: "complete" },
|
|
509
|
+
})) as { success: boolean };
|
|
510
|
+
|
|
511
|
+
expect(completeResult).toBeDefined();
|
|
512
|
+
|
|
513
|
+
// 8. Verify parent is completed in EventStore (syncExternalTransition)
|
|
514
|
+
const finalParent = (await getTool.handler({
|
|
515
|
+
task_id: parent.task_id,
|
|
516
|
+
})) as { status: string; external_id: string; assigned_agent: string };
|
|
517
|
+
|
|
518
|
+
expect(finalParent).toBeDefined();
|
|
519
|
+
expect(finalParent.external_id).toBe(parentDetails.external_id);
|
|
520
|
+
expect(finalParent.status).toBe("completed");
|
|
521
|
+
expect(finalParent.assigned_agent).toBe(TEST_AGENT_ID);
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
});
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull-Mode Task Backend Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests the claim/unclaim/listClaimable methods of InMemoryTaskBackend
|
|
5
|
+
* which enable the pull model where workers claim tasks from a pool.
|
|
6
|
+
*
|
|
7
|
+
* @module task/backend/__tests__/memory-pull-mode
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
11
|
+
import { createEventStore, type EventStore } from "../../../store/event-store.js";
|
|
12
|
+
import { InMemoryTaskBackend } from "../memory.js";
|
|
13
|
+
import type { AgentId, TaskId } from "../../../store/types/index.js";
|
|
14
|
+
|
|
15
|
+
describe("InMemoryTaskBackend — Pull Mode", () => {
|
|
16
|
+
let eventStore: EventStore;
|
|
17
|
+
let backend: InMemoryTaskBackend;
|
|
18
|
+
|
|
19
|
+
const AGENT_A = "agent-a" as AgentId;
|
|
20
|
+
const AGENT_B = "agent-b" as AgentId;
|
|
21
|
+
const CREATOR = "creator-001" as AgentId;
|
|
22
|
+
|
|
23
|
+
beforeEach(async () => {
|
|
24
|
+
eventStore = await createEventStore({ instanceId: `pull-test-${Date.now()}` });
|
|
25
|
+
backend = new InMemoryTaskBackend(eventStore);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// ─────────────────────────────────────────────────────────────────
|
|
29
|
+
// claim()
|
|
30
|
+
// ─────────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
it("claim returns first pending unblocked task", async () => {
|
|
33
|
+
const t1 = await backend.create({ description: "Task 1", created_by: CREATOR });
|
|
34
|
+
const t2 = await backend.create({ description: "Task 2", created_by: CREATOR });
|
|
35
|
+
const t3 = await backend.create({ description: "Task 3", created_by: CREATOR });
|
|
36
|
+
|
|
37
|
+
const claimed = await backend.claim!(AGENT_A);
|
|
38
|
+
expect(claimed).not.toBeNull();
|
|
39
|
+
expect(claimed!.id).toBe(t1.id);
|
|
40
|
+
expect(claimed!.assigned_agent).toBe(AGENT_A);
|
|
41
|
+
|
|
42
|
+
// Second claim should return t2
|
|
43
|
+
const claimed2 = await backend.claim!(AGENT_B);
|
|
44
|
+
expect(claimed2).not.toBeNull();
|
|
45
|
+
expect(claimed2!.id).toBe(t2.id);
|
|
46
|
+
expect(claimed2!.assigned_agent).toBe(AGENT_B);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("claim skips assigned tasks", async () => {
|
|
50
|
+
const t1 = await backend.create({ description: "Task 1", created_by: CREATOR });
|
|
51
|
+
const t2 = await backend.create({ description: "Task 2", created_by: CREATOR });
|
|
52
|
+
|
|
53
|
+
// Assign t1 directly
|
|
54
|
+
await backend.assign(t1.id, { agent_id: AGENT_A });
|
|
55
|
+
|
|
56
|
+
// claim should skip t1 and return t2
|
|
57
|
+
const claimed = await backend.claim!(AGENT_B);
|
|
58
|
+
expect(claimed).not.toBeNull();
|
|
59
|
+
expect(claimed!.id).toBe(t2.id);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("claim skips blocked tasks", async () => {
|
|
63
|
+
const blocker = await backend.create({ description: "Blocker task", created_by: CREATOR });
|
|
64
|
+
const blocked = await backend.create({ description: "Blocked task", created_by: CREATOR });
|
|
65
|
+
const available = await backend.create({ description: "Available task", created_by: CREATOR });
|
|
66
|
+
|
|
67
|
+
// Add blocker dependency
|
|
68
|
+
await backend.addBlocker(blocked.id, blocker.id);
|
|
69
|
+
|
|
70
|
+
// claim should skip blocked and return available
|
|
71
|
+
const claimed = await backend.claim!(AGENT_A);
|
|
72
|
+
expect(claimed).not.toBeNull();
|
|
73
|
+
// Should return either blocker or available (blocker is pending+unblocked, so it comes first)
|
|
74
|
+
// blocker is pending + not assigned + not blocked → claimable
|
|
75
|
+
// blocked is pending + not assigned but IS blocked → not claimable
|
|
76
|
+
// available is pending + not assigned + not blocked → claimable
|
|
77
|
+
expect([blocker.id, available.id]).toContain(claimed!.id);
|
|
78
|
+
expect(claimed!.id).not.toBe(blocked.id);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("claim returns null when no claimable tasks", async () => {
|
|
82
|
+
// Create a task and assign it
|
|
83
|
+
const t1 = await backend.create({ description: "Task 1", created_by: CREATOR });
|
|
84
|
+
await backend.assign(t1.id, { agent_id: AGENT_A });
|
|
85
|
+
|
|
86
|
+
// No unassigned pending tasks left
|
|
87
|
+
const claimed = await backend.claim!(AGENT_B);
|
|
88
|
+
expect(claimed).toBeNull();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// ─────────────────────────────────────────────────────────────────
|
|
92
|
+
// unclaim()
|
|
93
|
+
// ─────────────────────────────────────────────────────────────────
|
|
94
|
+
|
|
95
|
+
it("unclaim returns task to pending pool", async () => {
|
|
96
|
+
const t1 = await backend.create({ description: "Task 1", created_by: CREATOR });
|
|
97
|
+
|
|
98
|
+
// Claim it
|
|
99
|
+
const claimed = await backend.claim!(AGENT_A);
|
|
100
|
+
expect(claimed!.id).toBe(t1.id);
|
|
101
|
+
expect(claimed!.assigned_agent).toBe(AGENT_A);
|
|
102
|
+
|
|
103
|
+
// Unclaim it
|
|
104
|
+
await backend.unclaim!(t1.id);
|
|
105
|
+
|
|
106
|
+
// Task should be claimable again
|
|
107
|
+
const reClaimed = await backend.claim!(AGENT_B);
|
|
108
|
+
expect(reClaimed).not.toBeNull();
|
|
109
|
+
expect(reClaimed!.id).toBe(t1.id);
|
|
110
|
+
expect(reClaimed!.assigned_agent).toBe(AGENT_B);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("unclaim throws on unassigned task", async () => {
|
|
114
|
+
const t1 = await backend.create({ description: "Task 1", created_by: CREATOR });
|
|
115
|
+
|
|
116
|
+
await expect(backend.unclaim!(t1.id)).rejects.toThrow("not assigned");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// ─────────────────────────────────────────────────────────────────
|
|
120
|
+
// listClaimable()
|
|
121
|
+
// ─────────────────────────────────────────────────────────────────
|
|
122
|
+
|
|
123
|
+
it("listClaimable filters by tags", async () => {
|
|
124
|
+
await backend.create({
|
|
125
|
+
description: "Frontend task",
|
|
126
|
+
created_by: CREATOR,
|
|
127
|
+
tags: ["frontend", "ui"],
|
|
128
|
+
});
|
|
129
|
+
await backend.create({
|
|
130
|
+
description: "Backend task",
|
|
131
|
+
created_by: CREATOR,
|
|
132
|
+
tags: ["backend", "api"],
|
|
133
|
+
});
|
|
134
|
+
await backend.create({
|
|
135
|
+
description: "Untagged task",
|
|
136
|
+
created_by: CREATOR,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Filter by "backend" tag
|
|
140
|
+
const claimable = await backend.listClaimable!({ tags: ["backend"] });
|
|
141
|
+
expect(claimable.length).toBe(1);
|
|
142
|
+
expect(claimable[0].description).toBe("Backend task");
|
|
143
|
+
|
|
144
|
+
// Filter by "frontend" tag
|
|
145
|
+
const frontendTasks = await backend.listClaimable!({ tags: ["frontend"] });
|
|
146
|
+
expect(frontendTasks.length).toBe(1);
|
|
147
|
+
expect(frontendTasks[0].description).toBe("Frontend task");
|
|
148
|
+
|
|
149
|
+
// No filter returns all claimable
|
|
150
|
+
const allClaimable = await backend.listClaimable!();
|
|
151
|
+
expect(allClaimable.length).toBe(3);
|
|
152
|
+
});
|
|
153
|
+
});
|