@axiomatic-labs/claudeflow 2.43.37 → 2.43.38

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 (2) hide show
  1. package/lib/install.js +40 -6
  2. package/package.json +1 -1
package/lib/install.js CHANGED
@@ -8,11 +8,12 @@ const { writeLocalVersion, readLocalVersion } = require('./version.js');
8
8
  const ui = require('./ui.js');
9
9
 
10
10
  // claudeflow installs a small, namespaced footprint. Most of it is self-contained files that are simply
11
- // PLACED (playbooks, scripts, skills) — those can't conflict with the user's project. The only things
12
- // that need a MERGE (never a clobber) are .claude/settings.json (register our hooks alongside theirs)
13
- // and CLAUDE.md (upsert our guidance block between markers — user content outside stays untouched). That
14
- // merge lives here, in Node, so install works on every
15
- // platform with no shell dependency. The GitHub auth gate (auth.js/download.js) is untouched.
11
+ // PLACED (playbooks, scripts, skills) — those can't conflict with the user's project. The things that need a
12
+ // MERGE (never a clobber) are: .claude/settings.json (register our hooks + env alongside theirs), CLAUDE.md
13
+ // (upsert our guidance block between markers — user content outside stays untouched), and the root .mcp.json
14
+ // (seed the base MCP servers add-if-absent never clobber a server the user configured). Those merges live
15
+ // here, in Node, so install works on every platform with no shell dependency. The GitHub auth gate
16
+ // (auth.js/download.js) is untouched.
16
17
 
17
18
  const CLAUDE_MARK = '<!-- claudeflow:begin -->';
18
19
  const CLAUDE_END = '<!-- claudeflow:end -->';
@@ -70,6 +71,27 @@ function mergeSettings(cwd, payloadSettings) {
70
71
  fs.writeFileSync(sp, JSON.stringify(data, null, 2) + '\n');
71
72
  }
72
73
 
74
+ // Seed the BASE MCP server set (playwright for visual QA / browser_verification, context7 for live library
75
+ // docs during Discover) into the project's root `.mcp.json` — the set the old framework shipped, restored.
76
+ // ADD-IF-ABSENT by server key: create the file if missing, else merge in only the keys the user doesn't
77
+ // already have (never clobber a server they configured). A corrupt/unexpected `.mcp.json` is left untouched
78
+ // (don't risk eating the user's servers). Returns the number of servers added (0 = nothing to do). Like the
79
+ // settings env-merge, a base server the user later removed is re-added on the next install — it's a BASE set.
80
+ function mergeMcp(cwd, baseServers) {
81
+ if (!baseServers || !Object.keys(baseServers).length) return 0;
82
+ const mp = path.join(cwd, '.mcp.json');
83
+ let data = {};
84
+ if (fs.existsSync(mp)) {
85
+ try { data = JSON.parse(fs.readFileSync(mp, 'utf8')); } catch { return 0; } // corrupt → don't clobber
86
+ if (typeof data !== 'object' || data === null || Array.isArray(data)) return 0;
87
+ }
88
+ const servers = data.mcpServers || (data.mcpServers = {});
89
+ let added = 0;
90
+ for (const k of Object.keys(baseServers)) { if (!(k in servers)) { servers[k] = baseServers[k]; added++; } }
91
+ if (added) fs.writeFileSync(mp, JSON.stringify(data, null, 2) + '\n');
92
+ return added;
93
+ }
94
+
73
95
  // UPSERT the claudeflow guidance block. The snippet is a self-contained `<!-- claudeflow:begin -->…<!-- end -->`
74
96
  // region; everything OUTSIDE the markers is the user's own CLAUDE.md and is never touched. Behavior:
75
97
  // • no CLAUDE.md → create it with the block
@@ -102,7 +124,7 @@ function syncClaudeMd(cwd, snippetPath) {
102
124
  // Place + merge the framework from an extracted payload dir into a project. Pure filesystem, no network —
103
125
  // so it is testable on a throwaway dir.
104
126
  function installFromPayload(src, cwd) {
105
- const out = { playbooks: 0, scripts: 0, skills: 0, agents: 0, claudeMd: false, failed: [] };
127
+ const out = { playbooks: 0, scripts: 0, skills: 0, agents: 0, mcp: 0, claudeMd: false, failed: [] };
106
128
  // Each placement step is ISOLATED: a failure in one (a copy error, a permission hiccup, a weird file in the
107
129
  // user's tree) must NOT abort the rest — above all it must not skip the settings/env + CLAUDE.md config, the
108
130
  // two steps a user most needs (the env block wires agent-teams + the autocompact window, etc.). Before this,
@@ -187,6 +209,16 @@ function installFromPayload(src, cwd) {
187
209
  out.claudeMd = syncClaudeMd(cwd, path.join(src, 'assets', 'CLAUDE.snippet.md'));
188
210
  });
189
211
 
212
+ // 7) .mcp.json — seed the base MCP servers (add-if-absent; never clobber the user's own servers).
213
+ step('mcp', () => {
214
+ const srcMcp = path.join(src, 'assets', 'mcp.base.json');
215
+ if (fs.existsSync(srcMcp)) {
216
+ let base = {};
217
+ try { base = JSON.parse(fs.readFileSync(srcMcp, 'utf8')).mcpServers || {}; } catch { base = {}; }
218
+ out.mcp = mergeMcp(cwd, base);
219
+ }
220
+ });
221
+
190
222
  return out;
191
223
  }
192
224
 
@@ -249,6 +281,7 @@ async function run() {
249
281
 
250
282
  ui.success(`claudeflow v${version} installed`);
251
283
  ui.info(` ${summary.playbooks} playbooks · ${summary.scripts} scripts · ${summary.skills} skills`
284
+ + (summary.mcp ? ` · ${summary.mcp} MCP server${summary.mcp > 1 ? 's' : ''} added to .mcp.json` : '')
252
285
  + (summary.claudeMd ? ' · CLAUDE.md guidance synced' : ''));
253
286
  if (summary.failed && summary.failed.length) {
254
287
  ui.warn(` some steps did not complete: ${summary.failed.join(', ')}. Re-run \`npx @axiomatic-labs/claudeflow@latest install\` (the @latest avoids a stale npx cache).`);
@@ -260,3 +293,4 @@ module.exports = run;
260
293
  module.exports.installFromPayload = installFromPayload;
261
294
  module.exports.mergeSettings = mergeSettings;
262
295
  module.exports.syncClaudeMd = syncClaudeMd;
296
+ module.exports.mergeMcp = mergeMcp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomatic-labs/claudeflow",
3
- "version": "2.43.37",
3
+ "version": "2.43.38",
4
4
  "description": "Claudeflow — AI-powered development toolkit for Claude Code. Skills, agents, hooks, and quality gates that ship production apps.",
5
5
  "bin": {
6
6
  "claudeflow": "./bin/cli.js"