@axiomatic-labs/claudeflow 2.13.108 → 2.13.110

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 +66 -0
  2. package/package.json +1 -1
package/lib/install.js CHANGED
@@ -160,6 +160,10 @@ async function run() {
160
160
  materializeSharedAppendPrompt(cwd);
161
161
  ensureDefaultClaudeMdRules(cwd);
162
162
  propagateTemplateRules(cwd, srcTemplates);
163
+ // After CLAUDE.md exists, sync the boost-mode addendum so the user does
164
+ // not have to manually run /claudeflow-mode for the file to match the
165
+ // current variant. Idempotent: runs every install/update.
166
+ syncBoostAddendumOnInstall(cwd);
163
167
 
164
168
  // Copy template agents (only template-managed, preserve user agents)
165
169
  const srcAgents = path.join(srcClaude, 'agents');
@@ -207,6 +211,33 @@ async function run() {
207
211
  }
208
212
  }
209
213
 
214
+ // Copy variant-switch CLI (claudeflow-mode.js + helpers used by the
215
+ // /claudeflow-mode slash command to rotate .claude/ between boost and
216
+ // normal variants).
217
+ const srcCli = path.join(srcClaudeflow, 'cli');
218
+ const dstCli = path.join(cwd, '.claudeflow', 'cli');
219
+ if (fs.existsSync(srcCli)) {
220
+ copyDirSync(srcCli, dstCli);
221
+ }
222
+
223
+ // Copy variants (boost + normal). The /claudeflow-mode command rotates
224
+ // the active .claude/ between these. Each variant is a complete
225
+ // .claude/-shaped tree (skills, hooks, agents, commands, settings).
226
+ const srcVariants = path.join(srcClaudeflow, 'variants');
227
+ const dstVariants = path.join(cwd, '.claudeflow', 'variants');
228
+ if (fs.existsSync(srcVariants)) {
229
+ copyDirSync(srcVariants, dstVariants);
230
+ }
231
+
232
+ // Copy active-mode marker only when the project doesn't have one yet.
233
+ // Preserves the user's current mode (boost | normal) across updates —
234
+ // overwriting would silently rotate them back to the shipped default.
235
+ const srcActiveMode = path.join(srcClaudeflow, 'active-mode');
236
+ const dstActiveMode = path.join(cwd, '.claudeflow', 'active-mode');
237
+ if (fs.existsSync(srcActiveMode) && !fs.existsSync(dstActiveMode)) {
238
+ fs.copyFileSync(srcActiveMode, dstActiveMode);
239
+ }
240
+
210
241
  // Write version file
211
242
  writeLocalVersion(version);
212
243
  nextManagedPaths.add(normalizeRelativePath(path.join('.claudeflow', 'version')));
@@ -1272,6 +1303,41 @@ function copyDirSync(src, dst, skipNames) {
1272
1303
  }
1273
1304
  }
1274
1305
 
1306
+ // Sync the boost-mode addendum into CLAUDE.md based on .claudeflow/active-mode.
1307
+ // Idempotent: safe to call every install. When mode = boost, ensures the
1308
+ // addendum block (between <!-- claudeflow:boost-mode:BEGIN/END --> markers)
1309
+ // is at the end of CLAUDE.md, refreshing its contents if a stale version
1310
+ // already exists. When mode = normal, strips the block if present so the
1311
+ // user's CLAUDE.md is left untouched.
1312
+ function syncBoostAddendumOnInstall(cwd) {
1313
+ const activeModePath = path.join(cwd, '.claudeflow', 'active-mode');
1314
+ const claudeMdPath = path.join(cwd, 'CLAUDE.md');
1315
+ const addendumPath = path.join(cwd, '.claudeflow', 'variants', 'boost', 'CLAUDE_BOOST_ADDENDUM.md');
1316
+ if (!fs.existsSync(activeModePath) || !fs.existsSync(claudeMdPath)) return;
1317
+
1318
+ const ADDENDUM_BEGIN = '<!-- claudeflow:boost-mode:BEGIN -->';
1319
+ const ADDENDUM_END = '<!-- claudeflow:boost-mode:END -->';
1320
+ const activeMode = fs.readFileSync(activeModePath, 'utf8').trim();
1321
+ const original = fs.readFileSync(claudeMdPath, 'utf8');
1322
+ const beginIdx = original.indexOf(ADDENDUM_BEGIN);
1323
+ const endIdx = original.indexOf(ADDENDUM_END);
1324
+ const hasBlock = beginIdx !== -1 && endIdx !== -1 && endIdx > beginIdx;
1325
+
1326
+ let base = original;
1327
+ if (hasBlock) {
1328
+ const blockEnd = endIdx + ADDENDUM_END.length;
1329
+ base = original.slice(0, beginIdx).replace(/\s*$/, '') + original.slice(blockEnd).replace(/^\s*/, '\n');
1330
+ }
1331
+
1332
+ if (activeMode === 'boost' && fs.existsSync(addendumPath)) {
1333
+ const addendumBody = fs.readFileSync(addendumPath, 'utf8').trimEnd();
1334
+ const block = `\n\n${ADDENDUM_BEGIN}\n${addendumBody}\n${ADDENDUM_END}\n`;
1335
+ fs.writeFileSync(claudeMdPath, base.replace(/\s*$/, '') + block);
1336
+ } else if (hasBlock) {
1337
+ fs.writeFileSync(claudeMdPath, base.replace(/\s*$/, '') + '\n');
1338
+ }
1339
+ }
1340
+
1275
1341
  module.exports = Object.assign(run, {
1276
1342
  assertRequiredTemplateRules,
1277
1343
  materializeSharedAppendPrompt,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomatic-labs/claudeflow",
3
- "version": "2.13.108",
3
+ "version": "2.13.110",
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"