swarmdo 1.27.0 → 1.29.0

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.
Files changed (38) hide show
  1. package/.claude/helpers/auto-memory-hook.mjs +5 -1
  2. package/.claude-plugin/README.md +3 -3
  3. package/.claude-plugin/docs/INSTALLATION.md +1 -1
  4. package/.claude-plugin/docs/PLUGIN_SUMMARY.md +1 -1
  5. package/.claude-plugin/docs/QUICKSTART.md +3 -3
  6. package/.claude-plugin/hooks/hooks.json +19 -1
  7. package/.claude-plugin/marketplace.json +17 -17
  8. package/.claude-plugin/plugin.json +7 -39
  9. package/.claude-plugin/scripts/install.sh +3 -3
  10. package/.claude-plugin/scripts/swarmdo-hook.sh +1 -1
  11. package/.claude-plugin/scripts/verify.sh +2 -2
  12. package/README.md +10 -8
  13. package/package.json +1 -1
  14. package/v3/@swarmdo/cli/.claude/helpers/auto-memory-hook.mjs +5 -1
  15. package/v3/@swarmdo/cli/bin/cli.js +38 -0
  16. package/v3/@swarmdo/cli/dist/src/apply/apply.d.ts +6 -0
  17. package/v3/@swarmdo/cli/dist/src/apply/apply.js +41 -8
  18. package/v3/@swarmdo/cli/dist/src/commands/apply.js +17 -4
  19. package/v3/@swarmdo/cli/dist/src/commands/compact-snapshot.d.ts +17 -0
  20. package/v3/@swarmdo/cli/dist/src/commands/compact-snapshot.js +133 -0
  21. package/v3/@swarmdo/cli/dist/src/commands/index.js +4 -3
  22. package/v3/@swarmdo/cli/dist/src/commands/pack.d.ts +8 -0
  23. package/v3/@swarmdo/cli/dist/src/commands/pack.js +28 -2
  24. package/v3/@swarmdo/cli/dist/src/compact/compact.js +17 -7
  25. package/v3/@swarmdo/cli/dist/src/compact-snapshot/compact-snapshot.d.ts +58 -0
  26. package/v3/@swarmdo/cli/dist/src/compact-snapshot/compact-snapshot.js +104 -0
  27. package/v3/@swarmdo/cli/dist/src/config-lint/lint.js +16 -2
  28. package/v3/@swarmdo/cli/dist/src/init/helpers-generator.js +33 -3
  29. package/v3/@swarmdo/cli/dist/src/redact/redact.js +1 -1
  30. package/v3/@swarmdo/cli/dist/src/sbom/sbom.js +5 -2
  31. package/v3/@swarmdo/cli/dist/src/swarmvector/model-prices.js +12 -2
  32. package/v3/@swarmdo/cli/dist/src/testreport/testreport.js +11 -2
  33. package/v3/@swarmdo/cli/dist/src/transcript/export.d.ts +5 -0
  34. package/v3/@swarmdo/cli/dist/src/transcript/export.js +8 -1
  35. package/v3/@swarmdo/cli/dist/src/usage/claude-pricing.d.ts +6 -2
  36. package/v3/@swarmdo/cli/dist/src/usage/claude-pricing.js +33 -4
  37. package/v3/@swarmdo/cli/dist/src/usage/transcript-usage.js +1 -1
  38. package/v3/@swarmdo/cli/package.json +2 -2
@@ -99,7 +99,11 @@ class JsonFileBackend {
99
99
  async query(opts) {
100
100
  let results = [...this.entries.values()];
101
101
  if (opts?.namespace) results = results.filter(e => e.namespace === opts.namespace);
102
- if (opts?.type) results = results.filter(e => e.type === opts.type);
102
+ // NOTE: opts.type is the QueryType search STRATEGY (semantic|keyword|hybrid|…),
103
+ // NOT an entry MemoryType. This JSON backend has no vector search, so the
104
+ // strategy is moot — filtering entries by it excluded everything (a 'hybrid'
105
+ // query matched no 'semantic' entries), which zeroed out the bridge's
106
+ // content-hash dedup and let the store bloat ~22x per re-import (#53).
103
107
  if (opts?.limit) results = results.slice(0, opts.limit);
104
108
  return results;
105
109
  }
@@ -297,7 +297,7 @@ Then in Claude Code:
297
297
 
298
298
  ```bash
299
299
  # Add MCP servers to Claude Code
300
- claude mcp add swarmdo npx swarmdo@alpha mcp start
300
+ claude mcp add swarmdo npx swarmdo@latest mcp start
301
301
  claude mcp add swarmdo-swarm npx swarmdo-swarm mcp start # Optional
302
302
  ```
303
303
 
@@ -350,7 +350,7 @@ cp -r agents ~/.claude/agents/
350
350
 
351
351
  ```bash
352
352
  # Run setup via npx
353
- npx swarmdo@alpha init --plugin
353
+ npx swarmdo@latest init --plugin
354
354
 
355
355
  # This will:
356
356
  # 1. Create .claude directory
@@ -499,7 +499,7 @@ Swarmdo integrates with 3 MCP servers providing 110+ tools:
499
499
  "mcpServers": {
500
500
  "swarmdo": {
501
501
  "command": "npx",
502
- "args": ["swarmdo@alpha", "mcp", "start"]
502
+ "args": ["swarmdo@latest", "mcp", "start"]
503
503
  }
504
504
  }
505
505
  }
@@ -128,7 +128,7 @@ The plugin defines MCP servers, but you may need to install the packages:
128
128
 
129
129
  ```bash
130
130
  # Core MCP (recommended)
131
- npm install -g swarmdo@alpha
131
+ npm install -g swarmdo@latest
132
132
 
133
133
  # Optional enhanced coordination
134
134
  npm install -g swarmdo-swarm
@@ -337,7 +337,7 @@ The plugin is configured via `.claude-plugin/plugin.json`:
337
337
  "mcpServers": {
338
338
  "swarmdo": {
339
339
  "command": "npx",
340
- "args": ["swarmdo@alpha", "mcp", "start"]
340
+ "args": ["swarmdo@latest", "mcp", "start"]
341
341
  }
342
342
  }
343
343
  }
@@ -202,7 +202,7 @@ The swarm automatically:
202
202
 
203
203
  ```bash
204
204
  # Core MCP (required)
205
- claude mcp add swarmdo npx swarmdo@alpha mcp start
205
+ claude mcp add swarmdo npx swarmdo@latest mcp start
206
206
 
207
207
  # Enhanced coordination (optional)
208
208
  claude mcp add swarmdo-swarm npx swarmdo-swarm mcp start
@@ -296,10 +296,10 @@ ls ~/.claude/commands/
296
296
  cat ~/.claude/settings.json
297
297
 
298
298
  # Verify MCP package
299
- npx swarmdo@alpha --version
299
+ npx swarmdo@latest --version
300
300
 
301
301
  # Reinstall if needed
302
- npm install -g swarmdo@alpha
302
+ npm install -g swarmdo@latest
303
303
  ```
304
304
 
305
305
  ### Agents Not Spawning
@@ -50,6 +50,10 @@
50
50
  {
51
51
  "type": "command",
52
52
  "command": "/bin/bash -c 'INPUT=$(cat); CUSTOM=$(echo \"$INPUT\" | jq -r \".custom_instructions // \\\"\\\"\"); echo \"🔄 PreCompact Guidance:\"; echo \"📋 IMPORTANT: Review CLAUDE.md in project root for:\"; echo \" • 54 available agents and concurrent usage patterns\"; echo \" • Swarm coordination strategies (hierarchical, mesh, adaptive)\"; echo \" • SPARC methodology workflows with batchtools optimization\"; echo \" • Critical concurrent execution rules (GOLDEN RULE: 1 MESSAGE = ALL OPERATIONS)\"; if [ -n \"$CUSTOM\" ]; then echo \"🎯 Custom compact instructions: $CUSTOM\"; fi; echo \"✅ Ready for compact operation\"'"
53
+ },
54
+ {
55
+ "type": "command",
56
+ "command": "/bin/bash -c '\"${CLAUDE_PLUGIN_ROOT}/bin/swarmdo\" compact-snapshot write || true'"
53
57
  }
54
58
  ]
55
59
  },
@@ -59,11 +63,15 @@
59
63
  {
60
64
  "type": "command",
61
65
  "command": "/bin/bash -c 'echo \"🔄 Auto-Compact Guidance (Context Window Full):\"; echo \"📋 CRITICAL: Before compacting, ensure you understand:\"; echo \" • All 54 agents available in .claude/agents/ directory\"; echo \" • Concurrent execution patterns from CLAUDE.md\"; echo \" • Batchtools optimization for 300% performance gains\"; echo \" • Swarm coordination strategies for complex tasks\"; echo \"⚡ Apply GOLDEN RULE: Always batch operations in single messages\"; echo \"✅ Auto-compact proceeding with full agent context\"'"
66
+ },
67
+ {
68
+ "type": "command",
69
+ "command": "/bin/bash -c '\"${CLAUDE_PLUGIN_ROOT}/bin/swarmdo\" compact-snapshot write || true'"
62
70
  }
63
71
  ]
64
72
  }
65
73
  ],
66
- "Stop": [
74
+ "SessionEnd": [
67
75
  {
68
76
  "hooks": [
69
77
  {
@@ -72,6 +80,16 @@
72
80
  }
73
81
  ]
74
82
  }
83
+ ],
84
+ "UserPromptSubmit": [
85
+ {
86
+ "hooks": [
87
+ {
88
+ "type": "command",
89
+ "command": "/bin/bash -c '\"${CLAUDE_PLUGIN_ROOT}/bin/swarmdo\" compact-snapshot read || true'"
90
+ }
91
+ ]
92
+ }
75
93
  ]
76
94
  }
77
95
  }
@@ -2,8 +2,8 @@
2
2
  "name": "swarmdo",
3
3
  "description": "Swarmdo Marketplace: Claude Code native agents, swarms, workers, and MCP tools for continuous software engineering",
4
4
  "owner": {
5
- "name": "upstream",
6
- "url": "https://the upstream project (see NOTICE)"
5
+ "name": "SwarmDo",
6
+ "url": "https://github.com/SwarmDo/swarmdo"
7
7
  },
8
8
  "plugins": [
9
9
  {
@@ -74,7 +74,7 @@
74
74
  {
75
75
  "name": "swarmdo-agent",
76
76
  "source": "./plugins/swarmdo-agent",
77
- "description": "Agent runtimes \u2014 local WASM-sandboxed agents (rvagent) + Anthropic Claude Managed Agents (cloud); one interface, local-vs-cloud backends"
77
+ "description": "Agent runtimes local WASM-sandboxed agents (rvagent) + Anthropic Claude Managed Agents (cloud); one interface, local-vs-cloud backends"
78
78
  },
79
79
  {
80
80
  "name": "swarmdo-workflows",
@@ -109,7 +109,7 @@
109
109
  {
110
110
  "name": "swarmdo-adr",
111
111
  "source": "./plugins/swarmdo-adr",
112
- "description": "ADR lifecycle management \u2014 create, index, supersede, and link Architecture Decision Records to code"
112
+ "description": "ADR lifecycle management create, index, supersede, and link Architecture Decision Records to code"
113
113
  },
114
114
  {
115
115
  "name": "swarmdo-cost-tracker",
@@ -119,7 +119,7 @@
119
119
  {
120
120
  "name": "swarmdo-ddd",
121
121
  "source": "./plugins/swarmdo-ddd",
122
- "description": "Domain-Driven Design scaffolding \u2014 bounded contexts, aggregate roots, domain events, and anti-corruption layers"
122
+ "description": "Domain-Driven Design scaffolding bounded contexts, aggregate roots, domain events, and anti-corruption layers"
123
123
  },
124
124
  {
125
125
  "name": "swarmdo-federation",
@@ -129,7 +129,7 @@
129
129
  {
130
130
  "name": "swarmdo-graph-intelligence",
131
131
  "source": "./plugins/swarmdo-graph-intelligence",
132
- "description": "Real-time graph intelligence \u2014 personalized PageRank, streaming delta updates, witness-signed reasoning, and federation-distributable vectors"
132
+ "description": "Real-time graph intelligence personalized PageRank, streaming delta updates, witness-signed reasoning, and federation-distributable vectors"
133
133
  },
134
134
  {
135
135
  "name": "swarmdo-iot-cognitum",
@@ -139,57 +139,57 @@
139
139
  {
140
140
  "name": "swarmdo-knowledge-graph",
141
141
  "source": "./plugins/swarmdo-knowledge-graph",
142
- "description": "Knowledge graph construction \u2014 entity extraction, relation mapping, and pathfinder graph traversal"
142
+ "description": "Knowledge graph construction entity extraction, relation mapping, and pathfinder graph traversal"
143
143
  },
144
144
  {
145
145
  "name": "swarmdo-market-data",
146
146
  "source": "./plugins/swarmdo-market-data",
147
- "description": "Market data ingestion \u2014 feed normalization, OHLCV vectorization, and HNSW-indexed pattern matching"
147
+ "description": "Market data ingestion feed normalization, OHLCV vectorization, and HNSW-indexed pattern matching"
148
148
  },
149
149
  {
150
150
  "name": "swarmdo-migrations",
151
151
  "source": "./plugins/swarmdo-migrations",
152
- "description": "Schema migration management \u2014 generate, validate, dry-run, and rollback database migrations"
152
+ "description": "Schema migration management generate, validate, dry-run, and rollback database migrations"
153
153
  },
154
154
  {
155
155
  "name": "swarmdo-neural-trader",
156
156
  "source": "./plugins/swarmdo-neural-trader",
157
- "description": "Neural trading strategies \u2014 self-learning LSTM/Transformer/N-BEATS models with Rust/NAPI backtesting"
157
+ "description": "Neural trading strategies self-learning LSTM/Transformer/N-BEATS models with Rust/NAPI backtesting"
158
158
  },
159
159
  {
160
160
  "name": "swarmdo-observability",
161
161
  "source": "./plugins/swarmdo-observability",
162
- "description": "Structured logging, distributed tracing, and metrics \u2014 correlate agent swarm activity with application telemetry"
162
+ "description": "Structured logging, distributed tracing, and metrics correlate agent swarm activity with application telemetry"
163
163
  },
164
164
  {
165
165
  "name": "swarmdo-swarmvector",
166
166
  "source": "./plugins/swarmdo-swarmvector",
167
- "description": "Self-learning vector database \u2014 HNSW, FlashAttention-3, Graph RAG, hybrid search, DiskANN, and Brain AGI"
167
+ "description": "Self-learning vector database HNSW, FlashAttention-3, Graph RAG, hybrid search, DiskANN, and Brain AGI"
168
168
  },
169
169
  {
170
170
  "name": "swarmdo-sparc",
171
171
  "source": "./plugins/swarmdo-sparc",
172
- "description": "SPARC methodology \u2014 Specification, Pseudocode, Architecture, Refinement, Completion phases with quality gates"
172
+ "description": "SPARC methodology Specification, Pseudocode, Architecture, Refinement, Completion phases with quality gates"
173
173
  },
174
174
  {
175
175
  "name": "swarmdo-metaharness",
176
176
  "source": "./plugins/swarmdo-metaharness",
177
- "description": "MetaHarness integration \u2014 surfaces score/genome/mint/mcp-scan/threat-model via skills; pairs with @metaharness/router (ADR-148/149) for cost-optimal model routing; honors ADR-150 optional-augmentation constraint"
177
+ "description": "MetaHarness integration surfaces score/genome/mint/mcp-scan/threat-model via skills; pairs with @metaharness/router (ADR-148/149) for cost-optimal model routing; honors ADR-150 optional-augmentation constraint"
178
178
  },
179
179
  {
180
180
  "name": "swarmdo-arena",
181
181
  "source": "./plugins/swarmdo-arena",
182
- "description": "Competitive ruliology for swarmdo swarms \u2014 arenas, tournaments, and adaptive co-evolution of program strategies (ADR-147/148); strategies-as-programs compete under payoff games"
182
+ "description": "Competitive ruliology for swarmdo swarms arenas, tournaments, and adaptive co-evolution of program strategies (ADR-147/148); strategies-as-programs compete under payoff games"
183
183
  },
184
184
  {
185
185
  "name": "swarmdo-caveman",
186
186
  "source": "./plugins/swarmdo-caveman",
187
- "description": "Token compression \u2014 /caveman-compress rewrites memory files into few-token caveman-speak, substance preserved (MIT, vendored)"
187
+ "description": "Token compression /caveman-compress rewrites memory files into few-token caveman-speak, substance preserved (MIT, vendored)"
188
188
  },
189
189
  {
190
190
  "name": "swarmdo-ponytail",
191
191
  "source": "./plugins/swarmdo-ponytail",
192
- "description": "Anti-over-engineering \u2014 /ponytail makes agents think like the laziest senior dev: YAGNI, stdlib first, one line before fifty (MIT, vendored)"
192
+ "description": "Anti-over-engineering /ponytail makes agents think like the laziest senior dev: YAGNI, stdlib first, one line before fifty (MIT, vendored)"
193
193
  }
194
194
  ]
195
195
  }
@@ -1,19 +1,13 @@
1
1
  {
2
2
  "name": "swarmdo",
3
- "version": "2.5.0",
4
- "description": "Enterprise AI agent orchestration plugin with 150+ commands, 74+ specialized agents, SPARC methodology, swarm coordination, GitHub integration, and neural training capabilities",
3
+ "version": "1.28.2",
4
+ "description": "AI agent orchestration for Claude Code: swarm coordination, 314 MCP tools, 60+ agent types, persistent AgentDB memory with HNSW vector search, self-learning hooks, SPARC methodology, and GitHub automation",
5
5
  "author": {
6
- "name": "the upstream author",
6
+ "name": "SwarmDo Team",
7
7
  "email": "maintainers@swarmdo.com"
8
8
  },
9
- "homepage": "the upstream project (see NOTICE)",
10
- "repository": {
11
- "type": "git",
12
- "url": "the upstream project (see NOTICE)"
13
- },
14
- "bugs": {
15
- "url": "the upstream project (see NOTICE)"
16
- },
9
+ "homepage": "https://swarmdo.com",
10
+ "repository": "https://github.com/SwarmDo/swarmdo",
17
11
  "license": "MIT",
18
12
  "keywords": [
19
13
  "ai-agents",
@@ -31,43 +25,17 @@
31
25
  "code-review",
32
26
  "performance-optimization"
33
27
  ],
34
- "category": "development",
35
- "tags": [
36
- "productivity",
37
- "automation",
38
- "ai",
39
- "agents",
40
- "swarm",
41
- "coordination",
42
- "sparc",
43
- "github",
44
- "neural-network",
45
- "enterprise"
46
- ],
47
- "engines": {
48
- "claudeCode": ">=2.0.0",
49
- "node": ">=20.0.0"
50
- },
51
28
  "mcpServers": {
52
29
  "swarmdo": {
53
30
  "command": "npx",
54
31
  "args": [
55
- "swarmdo@alpha",
32
+ "-y",
33
+ "swarmdo@latest",
56
34
  "mcp",
57
35
  "start"
58
36
  ],
59
37
  "description": "Core Swarmdo MCP server for swarm coordination, agent management, and task orchestration (40+ tools)",
60
38
  "optional": false
61
- },
62
- "swarmdo-swarm": {
63
- "command": "npx",
64
- "args": [
65
- "swarmdo-swarm",
66
- "mcp",
67
- "start"
68
- ],
69
- "description": "Enhanced swarm coordination with WASM acceleration (2.8-4.4x speed improvement)",
70
- "optional": true
71
39
  }
72
40
  }
73
41
  }
@@ -137,7 +137,7 @@ if [ "$INSTALL_TYPE" = "1" ] || [ "$INSTALL_TYPE" = "4" ]; then
137
137
  "mcpServers": {
138
138
  "swarmdo": {
139
139
  "command": "npx",
140
- "args": ["swarmdo@alpha", "mcp", "start"],
140
+ "args": ["swarmdo@latest", "mcp", "start"],
141
141
  "description": "Core Swarmdo MCP server with 40+ orchestration tools"
142
142
  }
143
143
  }
@@ -154,7 +154,7 @@ Add to ~/.claude/settings.json:
154
154
  "mcpServers": {
155
155
  "swarmdo": {
156
156
  "command": "npx",
157
- "args": ["swarmdo@alpha", "mcp", "start"]
157
+ "args": ["swarmdo@latest", "mcp", "start"]
158
158
  },
159
159
  "swarmdo-swarm": {
160
160
  "command": "npx",
@@ -174,7 +174,7 @@ MCP_INSTRUCTIONS
174
174
 
175
175
  if [ "$INSTALL_MCP" = "y" ]; then
176
176
  info "Installing swarmdo MCP server..."
177
- npx swarmdo@alpha --version 2>/dev/null || npm install -g swarmdo@alpha
177
+ npx swarmdo@latest --version 2>/dev/null || npm install -g swarmdo@latest
178
178
  success "Swarmdo MCP server installed"
179
179
 
180
180
  read -p "Install optional swarmdo-swarm MCP? (y/n) [n]: " INSTALL_SWARM
@@ -27,7 +27,7 @@ if command -v swarmdo >/dev/null 2>&1; then
27
27
  elif command -v swarmdo >/dev/null 2>&1; then
28
28
  run swarmdo hooks "$@"
29
29
  else
30
- run npx --prefer-offline --yes swarmdo@alpha hooks "$@"
30
+ run npx --prefer-offline --yes swarmdo@latest hooks "$@"
31
31
  fi
32
32
 
33
33
  exit 0
@@ -69,8 +69,8 @@ fi
69
69
 
70
70
  # Check MCP packages
71
71
  info "Checking MCP packages..."
72
- if npx swarmdo@alpha --version &> /dev/null; then
73
- VERSION=$(npx swarmdo@alpha --version 2>/dev/null || echo "unknown")
72
+ if npx swarmdo@latest --version &> /dev/null; then
73
+ VERSION=$(npx swarmdo@latest --version 2>/dev/null || echo "unknown")
74
74
  success "swarmdo MCP: $VERSION"
75
75
  else
76
76
  warning "swarmdo MCP not installed"
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![swarmdo](swarmdo/assets/brand/logo-full.svg)](https://swarmdo.com)
4
4
 
5
- [![npm version (swarmdo)](https://img.shields.io/badge/npx%20swarmdo-v1.27.0-cb3837?style=for-the-badge&logo=npm&logoColor=white)](https://github.com/SwarmDo/swarmdo/releases)
5
+ [![npm version (swarmdo)](https://img.shields.io/badge/npx%20swarmdo-v1.29.0-cb3837?style=for-the-badge&logo=npm&logoColor=white)](https://github.com/SwarmDo/swarmdo/releases)
6
6
  [![MIT License](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](https://github.com/SwarmDo/swarmdo/blob/main/LICENSE)
7
7
  [![Website](https://img.shields.io/badge/swarmdo.com-e2a33c?style=for-the-badge&logoColor=black)](https://swarmdo.com)
8
8
  [![Star on GitHub](https://img.shields.io/github/stars/SwarmDo/swarmdo?style=for-the-badge&logo=github&color=gold)](https://github.com/SwarmDo/swarmdo)
@@ -47,17 +47,17 @@ There are **two different install paths** with very different surface areas. Pic
47
47
 
48
48
  | | **Claude Code Plugin** | **CLI install (`npx swarmdo init`)** |
49
49
  |---|---|---|
50
- | What it gives you | Slash commands + a few skills + agent definitions per-plugin | Full Swarmdo loop — 98 agents, 60+ commands, 30 skills, MCP server, hooks, daemon |
50
+ | What it gives you | Slash commands + skills + agent definitions per-plugin; `swarmdo-core` also registers the swarmdo MCP server | Full Swarmdo loop — 98 agents, 60+ commands, 30 skills, MCP server, hooks, daemon |
51
51
  | Files in your workspace | **Zero** | `.claude/`, `.swarmdo/`, `CLAUDE.md`, helpers, settings |
52
- | MCP server registered | **No** (`memory_store`, `swarm_init`, etc. unavailable to Claude) | Yes |
52
+ | MCP server registered | **Yes with `swarmdo-core`** (via the plugin's `.mcp.json`); other plugins are commands/skills only | Yes |
53
53
  | Hooks installed | No | Yes |
54
- | Best for | Try a single plugin's commands without committing to the full install | Production use — everything works as documented |
54
+ | Best for | Try Swarmdo without committing files to your workspace | Production use — everything works as documented |
55
55
 
56
- ### Path A — Claude Code Plugins (lite, slash commands only)
56
+ ### Path A — Claude Code Plugins (zero files in your repo)
57
57
 
58
58
  ```bash
59
59
  # Add the marketplace
60
- /plugin marketplace add upstream/swarmdo
60
+ /plugin marketplace add SwarmDo/swarmdo
61
61
 
62
62
  # Install core + any plugins you need
63
63
  /plugin install swarmdo-core@swarmdo
@@ -66,7 +66,9 @@ There are **two different install paths** with very different surface areas. Pic
66
66
  /plugin install swarmdo-neural-trader@swarmdo
67
67
  ```
68
68
 
69
- This adds slash commands and agent definitions only. The Swarmdo MCP server is NOT registered, so `memory_store`, `swarm_init`, `agent_spawn`, etc. won't be callable from Claude. For the full loop, use Path B below.
69
+ `swarmdo-core` registers the swarmdo MCP server (300+ tools) plus base agents and setup skills; the other plugins add their slash commands and agent definitions. Hooks and the daemon still require Path B.
70
+
71
+ > 📦 `swarmdo-core` has been submitted to Anthropic's Claude Code plugin directory (community marketplace). Once approved it will also be installable via `/plugin install swarmdo-core@claude-community` — no marketplace-add needed.
70
72
 
71
73
  <details>
72
74
  <summary><strong>🔌 All 35 plugins</strong></summary>
@@ -159,7 +161,7 @@ This adds slash commands and agent definitions only. The Swarmdo MCP server is N
159
161
 
160
162
  ```bash
161
163
  # One-line install (POSIX shells only — see Windows note below)
162
- curl -fsSL https://cdn.jsdelivr.net/gh/upstream/swarmdo@main/scripts/install.sh | bash
164
+ curl -fsSL https://cdn.jsdelivr.net/gh/SwarmDo/swarmdo@main/scripts/install.sh | bash
163
165
  ```
164
166
 
165
167
  **All platforms (including native Windows PowerShell / cmd):**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swarmdo",
3
- "version": "1.27.0",
3
+ "version": "1.29.0",
4
4
  "description": "Swarmdo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -99,7 +99,11 @@ class JsonFileBackend {
99
99
  async query(opts) {
100
100
  let results = [...this.entries.values()];
101
101
  if (opts?.namespace) results = results.filter(e => e.namespace === opts.namespace);
102
- if (opts?.type) results = results.filter(e => e.type === opts.type);
102
+ // NOTE: opts.type is the QueryType search STRATEGY (semantic|keyword|hybrid|…),
103
+ // NOT an entry MemoryType. This JSON backend has no vector search, so the
104
+ // strategy is moot — filtering entries by it excluded everything (a 'hybrid'
105
+ // query matched no 'semantic' entries), which zeroed out the bridge's
106
+ // content-hash dedup and let the store bloat ~22x per re-import (#53).
103
107
  if (opts?.limit) results = results.slice(0, opts.limit);
104
108
  return results;
105
109
  }
@@ -93,6 +93,20 @@ console.log = (...args) => {
93
93
  _origLog.apply(console, args);
94
94
  };
95
95
 
96
+ // Claude Code plugin hint (code.claude.com/docs/en/plugin-hints): when a
97
+ // session runs swarmdo through Claude Code's Bash tool, emit the one-line
98
+ // marker so Claude Code can offer to install our plugin. Emitted here in the
99
+ // bin shim — NOT in dist/src/index.js — so it also covers the #2256 fast
100
+ // paths below (--version/--help are exactly the probes Claude runs on an
101
+ // unfamiliar CLI). Claude Code strips the line from all output before it
102
+ // reaches the model and only prompts if/when swarmdo-core is listed in the
103
+ // official Anthropic marketplace; until then it is silently dropped.
104
+ if (process.env.CLAUDECODE) {
105
+ process.stderr.write(
106
+ '<claude-code-hint v="1" type="plugin" value="swarmdo-core@claude-plugins-official" />\n'
107
+ );
108
+ }
109
+
96
110
  // #2256 fast path: --version / -V / --help / -h must NOT trigger heavy
97
111
  // imports (agentic-flow, swarmvector ONNX, etc.) — those eagerly download a
98
112
  // 23 MB ONNX model on cold cache, blocking 60+ s and causing SIGTERM
@@ -116,6 +130,30 @@ console.log = (...args) => {
116
130
  // loading. The version short-circuit is the only one safe to inline.
117
131
  }
118
132
 
133
+ // #45 fast path: `compact-snapshot` is wired to UserPromptSubmit (fires on
134
+ // EVERY prompt) and PreCompact, so it must not pay the full-CLI bootstrap
135
+ // (~0.6s incl. the 23 MB ONNX load). Its own module imports only fs/git/output
136
+ // + the pure engine, so dispatch it directly and exit before any heavy import.
137
+ // A bare `--help` still falls through to the rich help path below.
138
+ {
139
+ const _argv = process.argv.slice(2);
140
+ if (_argv[0] === 'compact-snapshot' && !_argv.includes('--help') && !_argv.includes('-h')) {
141
+ try {
142
+ const mod = await import('../dist/src/commands/compact-snapshot.js');
143
+ const cmd = mod.default ?? mod.compactSnapshotCommand;
144
+ const rest = _argv.slice(1);
145
+ const args = rest.filter((a) => !a.startsWith('-'));
146
+ const flags = {};
147
+ for (const a of rest) if (a.startsWith('--')) flags[a.replace(/^--/, '')] = true;
148
+ const res = await cmd.action({ cwd: process.cwd(), args, flags, rawArgs: rest });
149
+ process.exit(res && typeof res.exitCode === 'number' ? res.exitCode : 0);
150
+ } catch (e) {
151
+ // Best-effort: a failure here must never block a turn (it runs in hooks).
152
+ process.exit(0);
153
+ }
154
+ }
155
+ }
156
+
119
157
  // Check if we should run in MCP server mode
120
158
  // Conditions:
121
159
  // 1. stdin is being piped AND no CLI arguments provided (auto-detect)
@@ -41,6 +41,12 @@ export interface HunkResult {
41
41
  at?: number;
42
42
  /** how many context lines were trimmed to make it fit */
43
43
  fuzzUsed?: number;
44
+ /**
45
+ * True when the matched block occurs at MORE THAN ONE position in the file —
46
+ * the hunk landed at the nearest, but a duplicate/boilerplate block elsewhere
47
+ * means it may have modified the wrong occurrence. Callers should verify.
48
+ */
49
+ ambiguous?: boolean;
44
50
  }
45
51
  export interface ApplyResult {
46
52
  ok: boolean;
@@ -19,7 +19,10 @@ export function parsePatch(text) {
19
19
  let hunk = null;
20
20
  const stripPrefix = (p) => p.replace(/^[ab]\//, '').replace(/\t.*$/, '').trim();
21
21
  for (let i = 0; i < lines.length; i++) {
22
- const line = lines[i];
22
+ // CRLF tolerance (#9): a diff generated on/for CRLF files carries \r on
23
+ // every line; strip it so hunk content compares EOL-agnostically.
24
+ const raw = lines[i];
25
+ const line = raw.endsWith('\r') ? raw.slice(0, -1) : raw;
23
26
  if (line.startsWith('diff --git')) {
24
27
  cur = null;
25
28
  hunk = null;
@@ -90,6 +93,16 @@ function blockMatchesAt(source, at, block) {
90
93
  return false;
91
94
  return true;
92
95
  }
96
+ /** How many positions in `source` the `block` matches. Pure. */
97
+ function countMatches(source, block) {
98
+ if (block.length === 0)
99
+ return 0;
100
+ let n = 0;
101
+ for (let i = 0; i + block.length <= source.length; i++)
102
+ if (blockMatchesAt(source, i, block))
103
+ n++;
104
+ return n;
105
+ }
93
106
  /**
94
107
  * Find where `block` occurs in `source`, preferring the position nearest
95
108
  * `expected` (0-based). Returns -1 if not found. Deterministic: on ties the
@@ -117,9 +130,19 @@ function findBlock(source, block, expected) {
117
130
  export function applyPatch(source, patch, opts = {}) {
118
131
  const fuzz = opts.fuzz ?? 2;
119
132
  const trailingNewline = source.endsWith('\n');
133
+ // CRLF support (#9): match EOL-agnostically, then write inserted lines with
134
+ // the file's dominant EOL so CRLF sources stay CRLF. `lines` keeps each
135
+ // line's original bytes (untouched lines round-trip exactly); `matchLines`
136
+ // is the \r-stripped twin every comparison runs against. The two are spliced
137
+ // in lockstep so indices stay aligned.
138
+ const crlfCount = (source.match(/\r\n/g) ?? []).length;
139
+ const newlineCount = (source.match(/\n/g) ?? []).length;
140
+ const dominantCrlf = crlfCount > newlineCount - crlfCount;
120
141
  const lines = source.split('\n');
121
142
  if (trailingNewline)
122
143
  lines.pop(); // drop the empty element from a trailing \n
144
+ const stripCr = (s) => (s.endsWith('\r') ? s.slice(0, -1) : s);
145
+ const matchLines = lines.map(stripCr);
123
146
  let offset = 0;
124
147
  const results = [];
125
148
  // If a hunk that reaches EOF carries an explicit no-newline marker, it — not
@@ -142,7 +165,7 @@ export function applyPatch(source, patch, opts = {}) {
142
165
  if (lead > leadTrimmable || tail > tailTrimmable)
143
166
  continue;
144
167
  const trimmed = oldBlock.slice(lead, oldBlock.length - tail);
145
- const at = findBlock(lines, trimmed, expected + lead);
168
+ const at = findBlock(matchLines, trimmed, expected + lead);
146
169
  if (at >= 0) {
147
170
  placed = at - lead;
148
171
  usedFuzz = f;
@@ -156,13 +179,18 @@ export function applyPatch(source, patch, opts = {}) {
156
179
  results.push({ hunk, applied: false });
157
180
  continue;
158
181
  }
159
- // Splice: remove oldBlock.length lines at `placed`, insert newBlock.
160
- // (trimLead/trimTail only affected *matching*, not what we replace.)
161
- void trimLead;
162
- void trimTail;
163
- lines.splice(placed, oldBlock.length, ...newBlock);
182
+ // A hunk is AMBIGUOUS if the block it matched on occurs elsewhere too — the
183
+ // nearest-match tiebreak may have picked the wrong duplicate. Check the
184
+ // matched (trimmed) block against the current lines BEFORE splicing.
185
+ const matchedBlock = oldBlock.slice(trimLead, oldBlock.length - trimTail);
186
+ const ambiguous = countMatches(matchLines, matchedBlock) > 1;
187
+ // Splice: remove oldBlock.length lines at `placed`, insert newBlock —
188
+ // raw lines get the file's dominant EOL, the match twin stays stripped.
189
+ const insertRaw = dominantCrlf ? newBlock.map((l) => l + '\r') : newBlock;
190
+ lines.splice(placed, oldBlock.length, ...insertRaw);
191
+ matchLines.splice(placed, oldBlock.length, ...newBlock);
164
192
  offset += newBlock.length - oldBlock.length;
165
- results.push({ hunk, applied: true, at: placed, fuzzUsed: usedFuzz });
193
+ results.push({ hunk, applied: true, at: placed, fuzzUsed: usedFuzz, ...(ambiguous && { ambiguous: true }) });
166
194
  // If this hunk's new content is now the tail of the file, its markers
167
195
  // determine whether the file ends with a newline.
168
196
  if (placed + newBlock.length === lines.length)
@@ -173,6 +201,11 @@ export function applyPatch(source, patch, opts = {}) {
173
201
  const endWithNewline = eofNoEol === undefined ? trailingNewline : !eofNoEol;
174
202
  if (endWithNewline)
175
203
  result += '\n';
204
+ // An inserted line that became the no-trailing-newline tail carries the
205
+ // dominant-EOL \r it was given for joining — a bare CR at EOF is never
206
+ // meaningful, so drop it.
207
+ else if (result.endsWith('\r'))
208
+ result = result.slice(0, -1);
176
209
  return { ok: results.every((r) => r.applied), result, hunks: results };
177
210
  }
178
211
  /**