claude-code-swarm 0.3.3 → 0.3.5
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-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +22 -1
- package/.claude-plugin/run-agent-inbox-mcp.sh +76 -0
- package/.claude-plugin/run-minimem-mcp.sh +98 -0
- package/.claude-plugin/run-opentasks-mcp.sh +65 -0
- package/CLAUDE.md +200 -36
- package/README.md +65 -0
- package/e2e/helpers/cleanup.mjs +17 -3
- package/e2e/helpers/map-mock-server.mjs +201 -25
- package/e2e/helpers/sidecar.mjs +222 -0
- package/e2e/helpers/workspace.mjs +2 -1
- package/e2e/tier5-sidecar-inbox.test.mjs +900 -0
- package/e2e/tier6-inbox-mcp.test.mjs +173 -0
- package/e2e/tier6-live-agent.test.mjs +759 -0
- package/e2e/vitest.config.e2e.mjs +1 -1
- package/hooks/hooks.json +15 -8
- package/package.json +13 -1
- package/references/agent-inbox/CLAUDE.md +151 -0
- package/references/agent-inbox/README.md +238 -0
- package/references/agent-inbox/docs/CLAUDE-CODE-SWARM-PROPOSAL.md +137 -0
- package/references/agent-inbox/docs/DESIGN.md +1156 -0
- package/references/agent-inbox/hooks/inbox-hook.mjs +119 -0
- package/references/agent-inbox/hooks/register-hook.mjs +69 -0
- package/references/agent-inbox/package-lock.json +3347 -0
- package/references/agent-inbox/package.json +58 -0
- package/references/agent-inbox/rules/agent-inbox.md +78 -0
- package/references/agent-inbox/src/federation/address.ts +61 -0
- package/references/agent-inbox/src/federation/connection-manager.ts +573 -0
- package/references/agent-inbox/src/federation/delivery-queue.ts +222 -0
- package/references/agent-inbox/src/federation/index.ts +6 -0
- package/references/agent-inbox/src/federation/routing-engine.ts +188 -0
- package/references/agent-inbox/src/federation/trust.ts +71 -0
- package/references/agent-inbox/src/index.ts +390 -0
- package/references/agent-inbox/src/ipc/ipc-server.ts +207 -0
- package/references/agent-inbox/src/jsonrpc/mail-server.ts +382 -0
- package/references/agent-inbox/src/map/map-client.ts +414 -0
- package/references/agent-inbox/src/mcp/mcp-server.ts +272 -0
- package/references/agent-inbox/src/mesh/delivery-bridge.ts +110 -0
- package/references/agent-inbox/src/mesh/mesh-connector.ts +41 -0
- package/references/agent-inbox/src/mesh/mesh-transport.ts +157 -0
- package/references/agent-inbox/src/mesh/type-mapper.ts +239 -0
- package/references/agent-inbox/src/push/notifier.ts +233 -0
- package/references/agent-inbox/src/registry/warm-registry.ts +255 -0
- package/references/agent-inbox/src/router/message-router.ts +175 -0
- package/references/agent-inbox/src/storage/interface.ts +48 -0
- package/references/agent-inbox/src/storage/memory.ts +145 -0
- package/references/agent-inbox/src/storage/sqlite.ts +671 -0
- package/references/agent-inbox/src/traceability/traceability.ts +183 -0
- package/references/agent-inbox/src/types.ts +303 -0
- package/references/agent-inbox/test/federation/address.test.ts +101 -0
- package/references/agent-inbox/test/federation/connection-manager.test.ts +546 -0
- package/references/agent-inbox/test/federation/delivery-queue.test.ts +159 -0
- package/references/agent-inbox/test/federation/integration.test.ts +857 -0
- package/references/agent-inbox/test/federation/routing-engine.test.ts +117 -0
- package/references/agent-inbox/test/federation/sdk-integration.test.ts +744 -0
- package/references/agent-inbox/test/federation/trust.test.ts +89 -0
- package/references/agent-inbox/test/ipc-jsonrpc.test.ts +113 -0
- package/references/agent-inbox/test/ipc-server.test.ts +197 -0
- package/references/agent-inbox/test/mail-server.test.ts +285 -0
- package/references/agent-inbox/test/map-client.test.ts +408 -0
- package/references/agent-inbox/test/mesh/delivery-bridge.test.ts +178 -0
- package/references/agent-inbox/test/mesh/e2e-mesh.test.ts +527 -0
- package/references/agent-inbox/test/mesh/e2e-real-meshpeer.test.ts +629 -0
- package/references/agent-inbox/test/mesh/federation-mesh.test.ts +269 -0
- package/references/agent-inbox/test/mesh/mesh-connector.test.ts +66 -0
- package/references/agent-inbox/test/mesh/mesh-transport.test.ts +191 -0
- package/references/agent-inbox/test/mesh/meshpeer-integration.test.ts +442 -0
- package/references/agent-inbox/test/mesh/mock-mesh.ts +125 -0
- package/references/agent-inbox/test/mesh/mock-meshpeer.ts +266 -0
- package/references/agent-inbox/test/mesh/type-mapper.test.ts +226 -0
- package/references/agent-inbox/test/message-router.test.ts +184 -0
- package/references/agent-inbox/test/push-notifier.test.ts +139 -0
- package/references/agent-inbox/test/registry/warm-registry.test.ts +171 -0
- package/references/agent-inbox/test/sqlite-prefix.test.ts +192 -0
- package/references/agent-inbox/test/sqlite-storage.test.ts +243 -0
- package/references/agent-inbox/test/storage.test.ts +196 -0
- package/references/agent-inbox/test/traceability.test.ts +123 -0
- package/references/agent-inbox/test/wake.test.ts +330 -0
- package/references/agent-inbox/tsconfig.json +20 -0
- package/references/agent-inbox/tsup.config.ts +10 -0
- package/references/agent-inbox/vitest.config.ts +8 -0
- 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 +329 -0
- package/references/minimem/README.md +565 -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 +76 -0
- package/references/minimem/scripts/postbuild.js +49 -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-frontmatter.test.ts +148 -0
- package/references/minimem/src/__tests__/knowledge.test.ts +148 -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 +760 -0
- package/references/minimem/src/cli/__tests__/contained-layout.test.ts +286 -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 +415 -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 +166 -0
- package/references/minimem/src/cli/commands/mcp.ts +221 -0
- package/references/minimem/src/cli/commands/push-pull.ts +213 -0
- package/references/minimem/src/cli/commands/search.ts +223 -0
- package/references/minimem/src/cli/commands/status.ts +84 -0
- package/references/minimem/src/cli/commands/store.ts +189 -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 +611 -0
- package/references/minimem/src/cli/index.ts +299 -0
- package/references/minimem/src/cli/shared.ts +189 -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 +205 -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 +358 -0
- package/references/minimem/src/cli/sync/validation.ts +206 -0
- package/references/minimem/src/cli/sync/watcher.ts +237 -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 +132 -0
- package/references/minimem/src/internal.ts +299 -0
- package/references/minimem/src/minimem.ts +1291 -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 +347 -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/src/store/__tests__/manifest.test.ts +177 -0
- package/references/minimem/src/store/__tests__/materialize.test.ts +52 -0
- package/references/minimem/src/store/__tests__/store-graph.test.ts +228 -0
- package/references/minimem/src/store/index.ts +27 -0
- package/references/minimem/src/store/manifest.ts +203 -0
- package/references/minimem/src/store/materialize.ts +185 -0
- package/references/minimem/src/store/store-graph.ts +252 -0
- package/references/minimem/tsconfig.json +19 -0
- package/references/minimem/tsup.config.ts +26 -0
- package/references/minimem/vitest.config.ts +29 -0
- package/references/openteams/src/cli/generate.ts +23 -1
- package/references/openteams/src/generators/agent-prompt-generator.test.ts +94 -0
- package/references/openteams/src/generators/agent-prompt-generator.ts +42 -13
- package/references/openteams/src/generators/package-generator.ts +9 -1
- package/references/openteams/src/generators/skill-generator.test.ts +28 -0
- package/references/openteams/src/generators/skill-generator.ts +10 -4
- package/references/skill-tree/.claude/settings.json +6 -0
- package/references/skill-tree/.sudocode/issues.jsonl +19 -0
- package/references/skill-tree/.sudocode/specs.jsonl +3 -0
- package/references/skill-tree/CLAUDE.md +132 -0
- package/references/skill-tree/README.md +396 -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 +157 -0
- package/references/skill-tree/package-lock.json +1852 -0
- package/references/skill-tree/package.json +66 -0
- package/references/skill-tree/plan.md +78 -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/references/swarmkit/src/commands/init/phases/configure.ts +0 -22
- package/references/swarmkit/src/commands/init/phases/global-setup.ts +5 -3
- package/references/swarmkit/src/commands/init/wizard.ts +2 -2
- package/references/swarmkit/src/packages/setup.test.ts +53 -7
- package/references/swarmkit/src/packages/setup.ts +37 -1
- package/scripts/bootstrap.mjs +26 -1
- package/scripts/generate-agents.mjs +5 -1
- package/scripts/map-hook.mjs +97 -64
- package/scripts/map-sidecar.mjs +179 -25
- package/scripts/team-loader.mjs +12 -41
- package/skills/swarm/SKILL.md +89 -25
- package/src/__tests__/agent-generator.test.mjs +6 -13
- package/src/__tests__/bootstrap.test.mjs +124 -1
- package/src/__tests__/config.test.mjs +200 -27
- package/src/__tests__/e2e-live-map.test.mjs +536 -0
- package/src/__tests__/e2e-mesh-sidecar.test.mjs +570 -0
- package/src/__tests__/e2e-native-task-hooks.test.mjs +376 -0
- package/src/__tests__/e2e-sidecar-bridge.test.mjs +477 -0
- package/src/__tests__/helpers.mjs +13 -0
- package/src/__tests__/inbox.test.mjs +22 -89
- package/src/__tests__/index.test.mjs +35 -9
- package/src/__tests__/integration.test.mjs +513 -0
- package/src/__tests__/map-events.test.mjs +514 -150
- package/src/__tests__/mesh-connection.test.mjs +308 -0
- package/src/__tests__/opentasks-client.test.mjs +517 -0
- package/src/__tests__/paths.test.mjs +185 -41
- package/src/__tests__/sidecar-client.test.mjs +35 -0
- package/src/__tests__/sidecar-server.test.mjs +124 -0
- package/src/__tests__/skilltree-client.test.mjs +80 -0
- package/src/agent-generator.mjs +104 -33
- package/src/bootstrap.mjs +150 -10
- package/src/config.mjs +81 -17
- package/src/context-output.mjs +58 -8
- package/src/inbox.mjs +9 -54
- package/src/index.mjs +39 -8
- package/src/map-connection.mjs +4 -3
- package/src/map-events.mjs +350 -80
- package/src/mesh-connection.mjs +148 -0
- package/src/opentasks-client.mjs +269 -0
- package/src/paths.mjs +182 -27
- package/src/sessionlog.mjs +14 -9
- package/src/sidecar-client.mjs +81 -27
- package/src/sidecar-server.mjs +175 -16
- package/src/skilltree-client.mjs +173 -0
- package/src/template.mjs +68 -4
- package/vitest.config.mjs +1 -0
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-swarm",
|
|
3
3
|
"description": "Spin up Claude Code agent teams from openteams YAML topologies with optional MAP (Multi-Agent Protocol) observability and coordination. Provides hooks for session lifecycle, agent spawn/complete tracking, and a /swarm skill to launch team configurations.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.5",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "alexngai"
|
|
7
|
+
},
|
|
8
|
+
"mcpServers": {
|
|
9
|
+
"opentasks": {
|
|
10
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/run-opentasks-mcp.sh",
|
|
11
|
+
"args": [],
|
|
12
|
+
"env": {
|
|
13
|
+
"OPENTASKS_WORKING_DIR": "${workspaceFolder}"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"agent-inbox": {
|
|
17
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/run-agent-inbox-mcp.sh",
|
|
18
|
+
"args": [],
|
|
19
|
+
"env": {}
|
|
20
|
+
},
|
|
21
|
+
"minimem": {
|
|
22
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/run-minimem-mcp.sh",
|
|
23
|
+
"args": [],
|
|
24
|
+
"env": {
|
|
25
|
+
"MINIMEM_WORKING_DIR": "${workspaceFolder}"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
7
28
|
}
|
|
8
29
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Wrapper script to run agent-inbox MCP server
|
|
3
|
+
# Reads scope from swarm config, discovers inbox socket
|
|
4
|
+
# Exits silently if inbox is not enabled or not installed
|
|
5
|
+
|
|
6
|
+
# Check if inbox is enabled in config
|
|
7
|
+
ENABLED=false
|
|
8
|
+
if [ -f .swarm/claude-swarm/config.json ]; then
|
|
9
|
+
ENABLED=$(node -e "
|
|
10
|
+
try {
|
|
11
|
+
const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
|
|
12
|
+
const envEnabled = (process.env.SWARM_INBOX_ENABLED || '').toLowerCase();
|
|
13
|
+
const isEnabled = ['true', '1', 'yes'].includes(envEnabled) || c.inbox?.enabled === true;
|
|
14
|
+
process.stdout.write(isEnabled ? 'true' : 'false');
|
|
15
|
+
} catch { process.stdout.write('false'); }
|
|
16
|
+
" 2>/dev/null || echo "false")
|
|
17
|
+
elif [ -n "$SWARM_INBOX_ENABLED" ]; then
|
|
18
|
+
case "$(echo "$SWARM_INBOX_ENABLED" | tr '[:upper:]' '[:lower:]')" in
|
|
19
|
+
true|1|yes) ENABLED=true ;;
|
|
20
|
+
esac
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
if [ "$ENABLED" != "true" ]; then
|
|
24
|
+
# Not enabled — exit silently so Claude Code doesn't show an error
|
|
25
|
+
sleep 0.1
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Read scope from config (defaults to MAP scope or "default")
|
|
30
|
+
SCOPE="default"
|
|
31
|
+
if [ -f .swarm/claude-swarm/config.json ]; then
|
|
32
|
+
CONFIGURED_SCOPE=$(node -e "
|
|
33
|
+
try {
|
|
34
|
+
const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
|
|
35
|
+
const s = c.inbox?.scope || c.map?.scope || process.env.SWARM_INBOX_SCOPE || '';
|
|
36
|
+
if (s) process.stdout.write(s);
|
|
37
|
+
} catch {}
|
|
38
|
+
" 2>/dev/null)
|
|
39
|
+
if [ -n "$CONFIGURED_SCOPE" ]; then
|
|
40
|
+
SCOPE="$CONFIGURED_SCOPE"
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
if [ -n "$SWARM_INBOX_SCOPE" ]; then
|
|
45
|
+
SCOPE="$SWARM_INBOX_SCOPE"
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Set env vars for agent-inbox MCP mode
|
|
49
|
+
export INBOX_SCOPE="$SCOPE"
|
|
50
|
+
|
|
51
|
+
# Try to find the agent-inbox module entry point
|
|
52
|
+
INBOX_MAIN=""
|
|
53
|
+
|
|
54
|
+
# 1. Check global npm root (swarmkit installs here)
|
|
55
|
+
GLOBAL_ROOT=$(npm root -g 2>/dev/null)
|
|
56
|
+
if [ -n "$GLOBAL_ROOT" ] && [ -f "$GLOBAL_ROOT/agent-inbox/dist/index.js" ]; then
|
|
57
|
+
INBOX_MAIN="$GLOBAL_ROOT/agent-inbox/dist/index.js"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# 2. Check plugin directory's node_modules (dev installs)
|
|
61
|
+
if [ -z "$INBOX_MAIN" ] && [ -n "$CLAUDE_PLUGIN_ROOT" ] && [ -f "$CLAUDE_PLUGIN_ROOT/node_modules/agent-inbox/dist/index.js" ]; then
|
|
62
|
+
INBOX_MAIN="$CLAUDE_PLUGIN_ROOT/node_modules/agent-inbox/dist/index.js"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# 3. Fallback: try require.resolve from CWD
|
|
66
|
+
if [ -z "$INBOX_MAIN" ]; then
|
|
67
|
+
INBOX_MAIN=$(node -e "try { console.log(require.resolve('agent-inbox/dist/index.js')); } catch {}" 2>/dev/null)
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
if [ -n "$INBOX_MAIN" ]; then
|
|
71
|
+
exec node "$INBOX_MAIN" mcp
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# agent-inbox not installed — log to stderr and exit cleanly
|
|
75
|
+
echo "[agent-inbox-mcp] agent-inbox not found. Install with: npm install -g agent-inbox or install via swarmkit" >&2
|
|
76
|
+
exit 0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Wrapper script to run minimem MCP server
|
|
3
|
+
# Reads provider and directory from swarm config
|
|
4
|
+
# Exits silently if minimem is not enabled or not installed
|
|
5
|
+
|
|
6
|
+
# Check if minimem is enabled in config
|
|
7
|
+
ENABLED=false
|
|
8
|
+
if [ -f .swarm/claude-swarm/config.json ]; then
|
|
9
|
+
ENABLED=$(node -e "
|
|
10
|
+
try {
|
|
11
|
+
const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
|
|
12
|
+
const envEnabled = (process.env.SWARM_MINIMEM_ENABLED || '').toLowerCase();
|
|
13
|
+
const isEnabled = ['true', '1', 'yes'].includes(envEnabled) || c.minimem?.enabled === true;
|
|
14
|
+
process.stdout.write(isEnabled ? 'true' : 'false');
|
|
15
|
+
} catch { process.stdout.write('false'); }
|
|
16
|
+
" 2>/dev/null || echo "false")
|
|
17
|
+
elif [ -n "$SWARM_MINIMEM_ENABLED" ]; then
|
|
18
|
+
case "$(echo "$SWARM_MINIMEM_ENABLED" | tr '[:upper:]' '[:lower:]')" in
|
|
19
|
+
true|1|yes) ENABLED=true ;;
|
|
20
|
+
esac
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
if [ "$ENABLED" != "true" ]; then
|
|
24
|
+
# Not enabled — exit silently so Claude Code doesn't show an error
|
|
25
|
+
sleep 0.1
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Read provider from config (defaults to "auto")
|
|
30
|
+
PROVIDER="auto"
|
|
31
|
+
if [ -f .swarm/claude-swarm/config.json ]; then
|
|
32
|
+
CONFIGURED_PROVIDER=$(node -e "
|
|
33
|
+
try {
|
|
34
|
+
const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
|
|
35
|
+
const p = process.env.SWARM_MINIMEM_PROVIDER || c.minimem?.provider || '';
|
|
36
|
+
if (p) process.stdout.write(p);
|
|
37
|
+
} catch {}
|
|
38
|
+
" 2>/dev/null)
|
|
39
|
+
if [ -n "$CONFIGURED_PROVIDER" ]; then
|
|
40
|
+
PROVIDER="$CONFIGURED_PROVIDER"
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
if [ -n "$SWARM_MINIMEM_PROVIDER" ]; then
|
|
45
|
+
PROVIDER="$SWARM_MINIMEM_PROVIDER"
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Discover memory directory: config dir > .swarm/minimem/ > cwd
|
|
49
|
+
MEMORY_DIR=""
|
|
50
|
+
if [ -f .swarm/claude-swarm/config.json ]; then
|
|
51
|
+
CONFIGURED_DIR=$(node -e "
|
|
52
|
+
try {
|
|
53
|
+
const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
|
|
54
|
+
const d = process.env.SWARM_MINIMEM_DIR || c.minimem?.dir || '';
|
|
55
|
+
if (d) process.stdout.write(d);
|
|
56
|
+
} catch {}
|
|
57
|
+
" 2>/dev/null)
|
|
58
|
+
if [ -n "$CONFIGURED_DIR" ]; then
|
|
59
|
+
MEMORY_DIR="$CONFIGURED_DIR"
|
|
60
|
+
fi
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
if [ -n "$SWARM_MINIMEM_DIR" ]; then
|
|
64
|
+
MEMORY_DIR="$SWARM_MINIMEM_DIR"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
if [ -z "$MEMORY_DIR" ]; then
|
|
68
|
+
if [ -d ".swarm/minimem" ]; then
|
|
69
|
+
MEMORY_DIR=".swarm/minimem"
|
|
70
|
+
else
|
|
71
|
+
MEMORY_DIR="."
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# Check if global memory should also be searched
|
|
76
|
+
GLOBAL_ARG=""
|
|
77
|
+
if [ -f .swarm/claude-swarm/config.json ]; then
|
|
78
|
+
USE_GLOBAL=$(node -e "
|
|
79
|
+
try {
|
|
80
|
+
const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
|
|
81
|
+
const envGlobal = (process.env.SWARM_MINIMEM_GLOBAL || '').toLowerCase();
|
|
82
|
+
const isGlobal = ['true', '1', 'yes'].includes(envGlobal) || c.minimem?.global === true;
|
|
83
|
+
process.stdout.write(isGlobal ? 'true' : 'false');
|
|
84
|
+
} catch { process.stdout.write('false'); }
|
|
85
|
+
" 2>/dev/null || echo "false")
|
|
86
|
+
if [ "$USE_GLOBAL" = "true" ]; then
|
|
87
|
+
GLOBAL_ARG="--global"
|
|
88
|
+
fi
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# Try installed minimem command
|
|
92
|
+
if command -v minimem &> /dev/null; then
|
|
93
|
+
exec minimem mcp --dir "$MEMORY_DIR" --provider "$PROVIDER" $GLOBAL_ARG
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# minimem not installed — log to stderr and exit cleanly
|
|
97
|
+
echo "[minimem-mcp] minimem CLI not found. Install with: npm install -g minimem" >&2
|
|
98
|
+
exit 0
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Wrapper script to run opentasks MCP server
|
|
3
|
+
# Reads scope from swarm config, defaults to "tasks"
|
|
4
|
+
# Exits silently if opentasks is not enabled or not installed
|
|
5
|
+
|
|
6
|
+
# Check if opentasks is enabled in config
|
|
7
|
+
ENABLED=false
|
|
8
|
+
if [ -f .swarm/claude-swarm/config.json ]; then
|
|
9
|
+
ENABLED=$(node -e "
|
|
10
|
+
try {
|
|
11
|
+
const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
|
|
12
|
+
const envEnabled = (process.env.SWARM_OPENTASKS_ENABLED || '').toLowerCase();
|
|
13
|
+
const isEnabled = ['true', '1', 'yes'].includes(envEnabled) || c.opentasks?.enabled === true;
|
|
14
|
+
process.stdout.write(isEnabled ? 'true' : 'false');
|
|
15
|
+
} catch { process.stdout.write('false'); }
|
|
16
|
+
" 2>/dev/null || echo "false")
|
|
17
|
+
elif [ -n "$SWARM_OPENTASKS_ENABLED" ]; then
|
|
18
|
+
case "$(echo "$SWARM_OPENTASKS_ENABLED" | tr '[:upper:]' '[:lower:]')" in
|
|
19
|
+
true|1|yes) ENABLED=true ;;
|
|
20
|
+
esac
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
if [ "$ENABLED" != "true" ]; then
|
|
24
|
+
# Not enabled — exit silently so Claude Code doesn't show an error
|
|
25
|
+
# Sleep briefly then exit so the MCP transport doesn't see an immediate close
|
|
26
|
+
sleep 0.1
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Read scope from config
|
|
31
|
+
SCOPE="tasks"
|
|
32
|
+
if [ -f .swarm/claude-swarm/config.json ]; then
|
|
33
|
+
CONFIGURED_SCOPE=$(node -e "
|
|
34
|
+
try {
|
|
35
|
+
const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
|
|
36
|
+
const s = c.opentasks?.scope || process.env.SWARM_OPENTASKS_SCOPE || '';
|
|
37
|
+
if (s) process.stdout.write(s);
|
|
38
|
+
} catch {}
|
|
39
|
+
" 2>/dev/null)
|
|
40
|
+
if [ -n "$CONFIGURED_SCOPE" ]; then
|
|
41
|
+
SCOPE="$CONFIGURED_SCOPE"
|
|
42
|
+
fi
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [ -n "$SWARM_OPENTASKS_SCOPE" ]; then
|
|
46
|
+
SCOPE="$SWARM_OPENTASKS_SCOPE"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Build socket path arg if daemon socket exists
|
|
50
|
+
SOCKET_ARG=""
|
|
51
|
+
for SOCK in .swarm/opentasks/daemon.sock .opentasks/daemon.sock .git/opentasks/daemon.sock; do
|
|
52
|
+
if [ -S "$SOCK" ]; then
|
|
53
|
+
SOCKET_ARG="--socket $SOCK"
|
|
54
|
+
break
|
|
55
|
+
fi
|
|
56
|
+
done
|
|
57
|
+
|
|
58
|
+
# Try installed opentasks command
|
|
59
|
+
if command -v opentasks &> /dev/null; then
|
|
60
|
+
exec opentasks mcp --scope "$SCOPE" $SOCKET_ARG
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# opentasks not installed — log to stderr and exit cleanly
|
|
64
|
+
echo "[opentasks-mcp] opentasks CLI not found. Install with: npm install -g opentasks" >&2
|
|
65
|
+
exit 0
|
package/CLAUDE.md
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
# claude-code-swarm
|
|
2
2
|
|
|
3
|
-
Claude Code plugin that launches agent teams from openteams YAML topologies, using Claude Code's native team features for coordination
|
|
3
|
+
Claude Code plugin that launches agent teams from openteams YAML topologies, using Claude Code's native team features for coordination, optional MAP (Multi-Agent Protocol) for external observability, and optional OpenTasks for cross-system task graph integration.
|
|
4
4
|
|
|
5
5
|
## What this plugin does
|
|
6
6
|
|
|
7
7
|
This plugin bridges [openteams](https://github.com/alexngai/openteams) team templates with Claude Code's native agent teams. It provides:
|
|
8
8
|
|
|
9
9
|
1. **SessionStart hook** (`scripts/bootstrap.mjs`) — Reads `.swarm/claude-swarm/config.json`, installs deps, initializes swarmkit project packages, starts MAP sidecar if configured, and injects team context
|
|
10
|
-
2. **MAP integration** (`scripts/map-sidecar.mjs`, `scripts/map-hook.mjs`) — Persistent sidecar for external observability via MAP server (lifecycle events, agent registration)
|
|
11
|
-
3.
|
|
12
|
-
4.
|
|
13
|
-
5. **
|
|
10
|
+
2. **MAP integration** (`scripts/map-sidecar.mjs`, `scripts/map-hook.mjs`) — Persistent sidecar for external observability via MAP server (lifecycle events, agent registration, task bridge events)
|
|
11
|
+
3. **OpenTasks integration** (`src/opentasks-client.mjs`, MCP server) — Optional cross-system task graph that federates Claude Tasks, MAP tasks, and external systems. Registered as an MCP server for agent use; bridge hooks emit task events to MAP for observability
|
|
12
|
+
4. **`/swarm` skill** (`skills/swarm/SKILL.md`) — User-invocable skill to select a template, create a native Claude Code team via `TeamCreate`, and spawn a coordinator agent
|
|
13
|
+
5. **Agent generator** (`scripts/generate-agents.mjs`) — Converts openteams YAML templates into Claude Code AGENT.md files with native team tool instructions
|
|
14
|
+
6. **Team loader** (`scripts/team-loader.mjs`) — Resolves templates, generates artifacts (with per-template caching), writes roles.json for MAP hook integration
|
|
15
|
+
7. **minimem integration** (MCP server) — Optional agent memory with semantic search. Registered as an MCP server; agents use memory tools to recall past decisions and context
|
|
16
|
+
8. **skill-tree integration** (`src/skilltree-client.mjs`) — Optional per-role skill loadouts compiled from team.yaml `skilltree:` extension and embedded in AGENT.md files at generation time
|
|
14
17
|
|
|
15
18
|
## Plugin structure
|
|
16
19
|
|
|
@@ -29,6 +32,8 @@ claude-code-swarm/
|
|
|
29
32
|
│ ├── sidecar-client.mjs # UNIX socket client + recovery
|
|
30
33
|
│ ├── sidecar-server.mjs # UNIX socket server + command handler
|
|
31
34
|
│ ├── map-events.mjs # Event builders + emit (sidecar → fallback)
|
|
35
|
+
│ ├── opentasks-client.mjs # OpenTasks daemon IPC client (socket discovery, task CRUD, sync)
|
|
36
|
+
│ ├── skilltree-client.mjs # Skill-tree loadout compilation (per-role, cached)
|
|
32
37
|
│ ├── sessionlog.mjs # Session detection, trajectory checkpoints, sync
|
|
33
38
|
│ ├── template.mjs # Template resolution + openteams generation
|
|
34
39
|
│ ├── agent-generator.mjs # AGENT.md generation (tools, frontmatter)
|
|
@@ -105,6 +110,44 @@ MAP options:
|
|
|
105
110
|
- `scope` — MAP scope name (default: `swarm:<template>`)
|
|
106
111
|
- `systemId` — System identifier for federation (default: `system-claude-swarm`)
|
|
107
112
|
- `sidecar` — `"session"` (starts/stops with session, default) or `"persistent"` (user-managed)
|
|
113
|
+
- `auth.token` — Authentication token appended as a query parameter to the server URL
|
|
114
|
+
- `auth.param` — Query parameter name for the token (default: `token`)
|
|
115
|
+
|
|
116
|
+
### With MeshPeer transport (agentic-mesh)
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"template": "gsd",
|
|
120
|
+
"map": {
|
|
121
|
+
"server": "ws://localhost:8080"
|
|
122
|
+
},
|
|
123
|
+
"mesh": {
|
|
124
|
+
"enabled": true
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
When enabled, the sidecar uses an embedded MeshPeer (from agentic-mesh) instead of a direct MAP SDK WebSocket connection. This provides encrypted P2P transport, agent discovery via MapServer registry, and federation with hop/loop detection. Agent-inbox integration gives structured messaging, threading, and delivery tracking.
|
|
130
|
+
|
|
131
|
+
If agentic-mesh is not available, the sidecar falls back to the direct MAP SDK WebSocket connection automatically.
|
|
132
|
+
|
|
133
|
+
Mesh options:
|
|
134
|
+
- `enabled` — Enable MeshPeer transport (default: `false`)
|
|
135
|
+
- `peerId` — MeshPeer peer ID (default: `<teamName>-sidecar`)
|
|
136
|
+
- `mapServer` — Optional MAP server URL for hybrid mode (mesh + MAP bridge)
|
|
137
|
+
|
|
138
|
+
### With OpenTasks
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"template": "gsd",
|
|
142
|
+
"opentasks": {
|
|
143
|
+
"enabled": true
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
When enabled, the plugin registers an OpenTasks MCP server that agents can use for cross-system task operations (`create_task`, `update_task`, `link`, `annotate`, `list_tasks`, `query`). The MCP server communicates with the OpenTasks daemon over a Unix socket. When both OpenTasks and MAP are enabled, `PostToolUse(opentasks)` hooks bridge MCP tool use into MAP task events for observability.
|
|
149
|
+
|
|
150
|
+
OpenTasks is independent from Claude's native task system — native tasks have their own `claude://` provider in the OpenTasks graph (see Task concepts below).
|
|
108
151
|
|
|
109
152
|
### With sessionlog → MAP sync
|
|
110
153
|
```json
|
|
@@ -126,6 +169,61 @@ When both MAP and sessionlog are active, the plugin bridges sessionlog's session
|
|
|
126
169
|
|
|
127
170
|
Requires sessionlog to be installed and active independently (`sessionlog enable`).
|
|
128
171
|
|
|
172
|
+
### With minimem (agent memory)
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"template": "gsd",
|
|
176
|
+
"minimem": {
|
|
177
|
+
"enabled": true,
|
|
178
|
+
"provider": "auto"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
When enabled, the plugin registers a minimem MCP server that agents can use for semantic memory search (`memory_search`, `memory_get_details`, `knowledge_search`, `knowledge_graph`, `knowledge_path`). Memories are stored as Markdown files in `.swarm/minimem/` and indexed with vector embeddings + BM25 hybrid search. Memory is shared team-wide — all agents search the same store.
|
|
184
|
+
|
|
185
|
+
Minimem options:
|
|
186
|
+
- `enabled` — Enable minimem integration (default: `false`)
|
|
187
|
+
- `provider` — Embedding provider: `openai`, `gemini`, `local`, `auto`, `none` (default: `auto`)
|
|
188
|
+
- `global` — Also search the user's global memory store at `~/.minimem` (default: `false`)
|
|
189
|
+
- `dir` — Custom memory directory path (default: `.swarm/minimem/`)
|
|
190
|
+
|
|
191
|
+
### With skill-tree (per-role skill loadouts)
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"template": "gsd",
|
|
195
|
+
"skilltree": {
|
|
196
|
+
"enabled": true,
|
|
197
|
+
"defaultProfile": "implementation"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
When enabled, the plugin compiles per-role skill loadouts from the team.yaml `skilltree:` extension namespace and embeds them in each agent's AGENT.md at generation time. Skills are cached per template alongside other artifacts.
|
|
203
|
+
|
|
204
|
+
Define per-role loadouts in team.yaml:
|
|
205
|
+
```yaml
|
|
206
|
+
skilltree:
|
|
207
|
+
defaults:
|
|
208
|
+
profile: implementation
|
|
209
|
+
maxSkills: 6
|
|
210
|
+
roles:
|
|
211
|
+
orchestrator:
|
|
212
|
+
profile: code-review
|
|
213
|
+
executor:
|
|
214
|
+
profile: implementation
|
|
215
|
+
tags: [development]
|
|
216
|
+
verifier:
|
|
217
|
+
profile: testing
|
|
218
|
+
debugger:
|
|
219
|
+
profile: debugging
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Skill-tree options:
|
|
223
|
+
- `enabled` — Enable skill-tree integration (default: `false`)
|
|
224
|
+
- `basePath` — Path to skill-tree storage directory (default: `.swarm/skill-tree/`)
|
|
225
|
+
- `defaultProfile` — Default profile when no role-specific criteria exist (default: `""`)
|
|
226
|
+
|
|
129
227
|
### Available templates
|
|
130
228
|
|
|
131
229
|
Templates are provided by the openteams package (installed via swarmkit). Built-in templates include:
|
|
@@ -154,8 +252,22 @@ All config values can be overridden via `SWARM_*` environment variables. Priorit
|
|
|
154
252
|
| `map.scope` | `SWARM_MAP_SCOPE` | string | `""` (derived from template) |
|
|
155
253
|
| `map.systemId` | `SWARM_MAP_SYSTEM_ID` | string | `system-claude-swarm` |
|
|
156
254
|
| `map.sidecar` | `SWARM_MAP_SIDECAR` | string | `session` |
|
|
255
|
+
| `map.auth.token` | `SWARM_MAP_AUTH_TOKEN` | string | `""` |
|
|
256
|
+
| `map.auth.param` | `SWARM_MAP_AUTH_PARAM` | string | `token` |
|
|
257
|
+
| `opentasks.enabled` | `SWARM_OPENTASKS_ENABLED` | boolean (`true`/`1`/`yes`) | `false` |
|
|
258
|
+
| `opentasks.scope` | `SWARM_OPENTASKS_SCOPE` | string | `""` |
|
|
157
259
|
| `sessionlog.enabled` | `SWARM_SESSIONLOG_ENABLED` | boolean (`true`/`1`/`yes`) | `false` |
|
|
158
260
|
| `sessionlog.sync` | `SWARM_SESSIONLOG_SYNC` | string | `off` |
|
|
261
|
+
| `minimem.enabled` | `SWARM_MINIMEM_ENABLED` | boolean (`true`/`1`/`yes`) | `false` |
|
|
262
|
+
| `minimem.provider` | `SWARM_MINIMEM_PROVIDER` | string | `auto` |
|
|
263
|
+
| `minimem.global` | `SWARM_MINIMEM_GLOBAL` | boolean (`true`/`1`/`yes`) | `false` |
|
|
264
|
+
| `minimem.dir` | `SWARM_MINIMEM_DIR` | string | `""` |
|
|
265
|
+
| `skilltree.enabled` | `SWARM_SKILLTREE_ENABLED` | boolean (`true`/`1`/`yes`) | `false` |
|
|
266
|
+
| `skilltree.basePath` | `SWARM_SKILLTREE_BASE_PATH` | string | `""` |
|
|
267
|
+
| `skilltree.defaultProfile` | `SWARM_SKILLTREE_DEFAULT_PROFILE` | string | `""` |
|
|
268
|
+
| `mesh.enabled` | `SWARM_MESH_ENABLED` | boolean (`true`/`1`/`yes`) | `false` |
|
|
269
|
+
| `mesh.peerId` | `SWARM_MESH_PEER_ID` | string | `""` |
|
|
270
|
+
| `mesh.mapServer` | `SWARM_MESH_MAP_SERVER` | string | `""` |
|
|
159
271
|
|
|
160
272
|
MAP is implicitly enabled when `map.server` is configured (in file or via `SWARM_MAP_SERVER`). Use `SWARM_MAP_ENABLED=false` to explicitly disable.
|
|
161
273
|
|
|
@@ -164,6 +276,22 @@ Example — point to a MAP server in CI (implicitly enables MAP):
|
|
|
164
276
|
SWARM_MAP_SERVER=ws://map.ci.internal:8080 claude
|
|
165
277
|
```
|
|
166
278
|
|
|
279
|
+
## Task concepts
|
|
280
|
+
|
|
281
|
+
There are three distinct "task" systems in play. They are independent — each has its own storage and lifecycle:
|
|
282
|
+
|
|
283
|
+
- **Claude Native Tasks** (`TaskCreate`/`TaskUpdate`/`TaskList`/`TaskStop`) — Team-wide coordination between agents. Stored by Claude Code's internal task system. The OpenTasks `claude-tasks` provider surfaces these as `claude://` nodes in the graph via a filesystem-backed `ClaudeTaskStore` adapter with chokidar file watching — no swarm hooks needed to sync them.
|
|
284
|
+
|
|
285
|
+
- **OpenTasks** (MCP tools: `create_task`, `update_task`, `link`, etc.) — Cross-system persistent task graph stored in JSONL. Federates tasks from multiple providers (`native://`, `claude://`, `map://`, `beads://`, etc.) via edges. Optional — enabled via `opentasks.enabled` config.
|
|
286
|
+
|
|
287
|
+
- **MAP Tasks** — Remote tasks on a MAP server, surfaced as `map://` nodes by the OpenTasks MAP provider. Ephemeral/pass-through — no local cache. Used for cross-system coordination when agents on different MAP-connected systems need to share tasks.
|
|
288
|
+
|
|
289
|
+
The swarm plugin's role is **observability bridging**, not task creation:
|
|
290
|
+
- `PostToolUse(TaskCreate/TaskUpdate)` → emits MAP bridge events so external observers can see native task activity
|
|
291
|
+
- `PostToolUse(opentasks)` → emits MAP bridge events when agents use opentasks MCP tools
|
|
292
|
+
- `TaskCompleted` → updates the opentasks graph + emits MAP bridge event
|
|
293
|
+
- Agent spawning/completion hooks manage MAP agent lifecycle only (not task creation)
|
|
294
|
+
|
|
167
295
|
## Architecture
|
|
168
296
|
|
|
169
297
|
### Team launch flow
|
|
@@ -194,28 +322,54 @@ All hooks use MAP SDK primitives — no custom `swarm.*` event types. Clients su
|
|
|
194
322
|
- `trajectory.checkpoint` for sessionlog sync
|
|
195
323
|
|
|
196
324
|
Hook dispatch:
|
|
197
|
-
1. **UserPromptSubmit** → `map-hook.mjs inject`: reads MAP inbox, injects external messages into context
|
|
198
|
-
2. **
|
|
199
|
-
3. **PostToolUse(
|
|
200
|
-
4. **
|
|
201
|
-
5. **
|
|
202
|
-
6. **
|
|
203
|
-
7. **
|
|
204
|
-
8. **
|
|
205
|
-
9. **
|
|
325
|
+
1. **UserPromptSubmit** → `map-hook.mjs inject`: reads MAP inbox, injects external messages into context. Forwards incoming `task.*` events to the opentasks graph if `opentasks.enabled`
|
|
326
|
+
2. **PostToolUse(opentasks)** → `map-hook.mjs opentasks-mcp-used`: bridges opentasks MCP tool use into MAP task events (`bridge-task-created`, `bridge-task-status`, `bridge-task-assigned`, `task.linked`, `task.sync`). Gated on both `opentasks.enabled` and `map.enabled`
|
|
327
|
+
3. **PostToolUse(TaskCreate)** → `map-hook.mjs native-task-created`: emits `bridge-task-created` + `bridge-task-assigned` to MAP. Observability only — native tasks enter the opentasks graph via the `claude-tasks` provider, not this hook
|
|
328
|
+
4. **PostToolUse(TaskUpdate)** → `map-hook.mjs native-task-updated`: emits `bridge-task-status` to MAP. Observability only
|
|
329
|
+
5. **TaskCompleted** → `map-hook.mjs task-completed`: updates task in opentasks daemon (`updateTask`) + emits `bridge-task-status` to MAP
|
|
330
|
+
6. **Stop** → `map-hook.mjs turn-completed`: updates sidecar state via `conn.updateState("idle")` (server auto-emits `agent_state_changed`)
|
|
331
|
+
7. **Stop** → `map-hook.mjs sessionlog-sync`: reads sessionlog state, reports `trajectory/checkpoint` to MAP (falls back to `trajectory.checkpoint` message payload if server doesn't support trajectory)
|
|
332
|
+
8. **SubagentStart** → `map-hook.mjs subagent-start`: spawns subagent via `conn.spawn()` with `role: "subagent"`
|
|
333
|
+
9. **SubagentStop** → `map-hook.mjs subagent-stop`: marks subagent done
|
|
334
|
+
10. **TeammateIdle** → `map-hook.mjs teammate-idle`: updates teammate state to idle
|
|
206
335
|
|
|
207
336
|
### MAP sidecar
|
|
208
337
|
|
|
209
|
-
The sidecar (`scripts/map-sidecar.mjs`) is a persistent Node.js process
|
|
338
|
+
The sidecar (`scripts/map-sidecar.mjs`) is a persistent Node.js process with two transport modes:
|
|
339
|
+
|
|
340
|
+
**Mesh mode** (preferred, when `mesh.enabled: true`):
|
|
341
|
+
- Creates an embedded MeshPeer (from agentic-mesh) for encrypted P2P transport
|
|
342
|
+
- Passes the MeshPeer to agent-inbox Phase 2 integration for structured messaging, agent registry, and federation
|
|
343
|
+
- Agent lifecycle (spawn/done) handled by inbox registry, with MAP registration for external observability
|
|
344
|
+
- Task bridge events, trajectory checkpoints, and state updates go through the MeshPeer connection
|
|
345
|
+
- Falls back to WebSocket mode automatically if agentic-mesh is unavailable
|
|
346
|
+
|
|
347
|
+
**WebSocket mode** (fallback/default):
|
|
210
348
|
- Connects to the MAP server via WebSocket with auto-reconnection
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
-
|
|
216
|
-
-
|
|
349
|
+
- Agent lifecycle via MAP SDK primitives: `conn.spawn()`, `conn.callExtension("map/agents/unregister")`, `conn.updateState()`
|
|
350
|
+
- Agent-inbox shares the MAP connection for messaging (legacy integration)
|
|
351
|
+
|
|
352
|
+
Both modes:
|
|
353
|
+
- Listen on a UNIX socket (`.swarm/claude-swarm/tmp/map/sidecar.sock`) for commands from hooks
|
|
354
|
+
- Manage agent-inbox on a separate IPC socket for messaging
|
|
355
|
+
- Send task lifecycle as typed message payloads via `conn.send()`
|
|
356
|
+
- Report trajectory checkpoints via `trajectory/checkpoint` (with broadcast fallback)
|
|
357
|
+
- Self-terminate after 30 minutes of inactivity (session mode)
|
|
358
|
+
|
|
359
|
+
The hook helper (`scripts/map-hook.mjs`) includes best-effort auto-recovery: if the sidecar is down, it attempts to restart it, with a fire-and-forget fallback (mesh or direct WebSocket) if recovery fails.
|
|
360
|
+
|
|
361
|
+
### OpenTasks integration
|
|
362
|
+
|
|
363
|
+
The plugin integrates with OpenTasks at two levels:
|
|
364
|
+
|
|
365
|
+
**MCP server** — Registered in `plugin.json` as an MCP server (`run-opentasks-mcp.sh`). Conditionally started based on `opentasks.enabled` config. Agents use MCP tools (`create_task`, `update_task`, `link`, `annotate`, `list_tasks`, `query`) to interact with the OpenTasks daemon over a Unix socket.
|
|
366
|
+
|
|
367
|
+
**Daemon IPC client** (`src/opentasks-client.mjs`) — Direct IPC to the OpenTasks daemon for hook-initiated operations. Socket discovery follows priority: `.swarm/opentasks/` → `.opentasks/` → `.git/opentasks/` → walk up. Used by:
|
|
368
|
+
- `task-completed` hook → `updateTask()` to mark tasks closed
|
|
369
|
+
- `inject` hook → `pushSyncEvent()` to forward incoming MAP `task.*` events to the graph
|
|
370
|
+
- `map-events.mjs` → `handleTaskCreated()`/`handleTaskCompleted()` (available for two-step pattern: create in opentasks + emit MAP bridge event)
|
|
217
371
|
|
|
218
|
-
|
|
372
|
+
**Relationship to native Claude Tasks** — Native tasks (`TaskCreate`/`TaskUpdate`) enter the OpenTasks graph via the `claude-tasks` provider (in the OpenTasks project), which uses a filesystem-backed `ClaudeTaskStore` adapter with chokidar file watching. The swarm plugin does NOT need to push native tasks into OpenTasks — the provider handles this reactively. The swarm hooks for `PostToolUse(TaskCreate/TaskUpdate)` only emit MAP bridge events for observability.
|
|
219
373
|
|
|
220
374
|
### Agent registration
|
|
221
375
|
|
|
@@ -226,20 +380,23 @@ Only topology-defined roles (from `team.yaml`) get full MAP agent registrations
|
|
|
226
380
|
All logic lives in `src/` as importable ES modules. Scripts in `scripts/` are thin CLI wrappers (~20-30 lines each) that parse args, call `src/` functions, and handle stdout/stderr.
|
|
227
381
|
|
|
228
382
|
```
|
|
229
|
-
src/config.mjs
|
|
230
|
-
src/paths.mjs
|
|
231
|
-
src/roles.mjs
|
|
232
|
-
src/inbox.mjs
|
|
233
|
-
src/map-connection.mjs
|
|
234
|
-
src/
|
|
235
|
-
src/sidecar-
|
|
236
|
-
src/
|
|
237
|
-
src/
|
|
238
|
-
src/
|
|
239
|
-
src/
|
|
240
|
-
src/
|
|
241
|
-
src/
|
|
242
|
-
src/
|
|
383
|
+
src/config.mjs ← readConfig(), resolveScope(), resolveTeamName()
|
|
384
|
+
src/paths.mjs ← SWARM_DIR, CONFIG_PATH, TMP_DIR, TEAMS_DIR, MAP_DIR, teamDir()
|
|
385
|
+
src/roles.mjs ← readRoles(), matchRole(), writeRoles()
|
|
386
|
+
src/inbox.mjs ← readInbox(), clearInbox(), formatInboxAsMarkdown()
|
|
387
|
+
src/map-connection.mjs ← connectToMAP(), fireAndForget(), fireAndForgetTrajectory()
|
|
388
|
+
src/mesh-connection.mjs ← createMeshPeer(), createMeshInbox(), meshFireAndForget()
|
|
389
|
+
src/sidecar-client.mjs ← sendToSidecar(), ensureSidecar(), startSidecar()
|
|
390
|
+
src/sidecar-server.mjs ← createSocketServer(), createCommandHandler()
|
|
391
|
+
src/map-events.mjs ← sendCommand(), emitPayload(), build*Command(), handle*Event()
|
|
392
|
+
src/opentasks-client.mjs ← createTask(), updateTask(), pushSyncEvent(), findSocketPath()
|
|
393
|
+
src/skilltree-client.mjs ← parseSkillTreeExtension(), compileRoleLoadout(), compileAllRoleLoadouts()
|
|
394
|
+
src/sessionlog.mjs ← findActiveSession(), buildTrajectoryCheckpoint(), syncSessionlog()
|
|
395
|
+
src/template.mjs ← resolveTemplatePath(), listAvailableTemplates(), generateTeamArtifacts()
|
|
396
|
+
src/agent-generator.mjs ← generateAllAgents(), generateAgentMd()
|
|
397
|
+
src/context-output.mjs ← format*Context(), format*Message()
|
|
398
|
+
src/bootstrap.mjs ← bootstrap() — full SessionStart orchestration
|
|
399
|
+
src/index.mjs ← barrel re-export of public API
|
|
243
400
|
```
|
|
244
401
|
|
|
245
402
|
## Key dependencies
|
|
@@ -251,7 +408,11 @@ Local (installed via `npm install --production` in plugin directory):
|
|
|
251
408
|
Global (managed by swarmkit, installed on demand during bootstrap):
|
|
252
409
|
- **openteams** — team topology parsing and artifact generation (always installed)
|
|
253
410
|
- **@multi-agent-protocol/sdk** — MAP protocol client (installed when `map.enabled: true`)
|
|
411
|
+
- **agentic-mesh** — encrypted P2P mesh transport with embedded MeshPeer (installed when `mesh.enabled: true`)
|
|
412
|
+
- **agent-inbox** — MAP-native message router with structured messaging (installed when `inbox.enabled: true`)
|
|
254
413
|
- **sessionlog** — git-integrated session capture (installed when `sessionlog.enabled: true`)
|
|
414
|
+
- **minimem** — file-based memory with vector search (installed when `minimem.enabled: true`)
|
|
415
|
+
- **skill-tree** — versioned skill library with serving layer (installed when `skilltree.enabled: true`)
|
|
255
416
|
|
|
256
417
|
Runtime:
|
|
257
418
|
- **Claude Code agent teams** — enabled via `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` in settings.json
|
|
@@ -263,4 +424,7 @@ Runtime:
|
|
|
263
424
|
- Switching between templates is instant if previously cached — artifacts are stored per template in `.swarm/claude-swarm/tmp/teams/<template>/`
|
|
264
425
|
- openteams is config/generation only — Claude Code native teams handle all runtime coordination, MAP handles external observability
|
|
265
426
|
- All logic is in `src/` modules — scripts are thin wrappers, making functions importable and testable
|
|
427
|
+
- Agent spawning/completion hooks are purely MAP agent lifecycle — they do not create or complete tasks. Task creation is handled by agents using `TaskCreate` (native) or opentasks MCP tools
|
|
428
|
+
- Native Claude tasks enter the OpenTasks graph via the `claude-tasks` provider's filesystem watcher, not via swarm hooks. Swarm hooks for `TaskCreate`/`TaskUpdate` only emit MAP bridge events
|
|
429
|
+
- The `opentasks-client.mjs` communicates with the OpenTasks daemon via JSON-RPC 2.0 over Unix socket with best-effort auto-recovery
|
|
266
430
|
- See `docs/design.md` for detailed architecture decisions and `docs/implementation-plan.md` for phase breakdown
|