@axiomatic-labs/claudeflow 2.14.3 → 2.14.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.
Files changed (2) hide show
  1. package/lib/install.js +129 -7
  2. package/package.json +1 -1
package/lib/install.js CHANGED
@@ -167,9 +167,27 @@ async function run() {
167
167
  if (fs.existsSync(srcTemplates)) {
168
168
  copyDirSync(srcTemplates, dstTemplates);
169
169
  }
170
+
171
+ // Copy v2 orchestrator playbook layer (foundation/methodologies/domain/
172
+ // ui-ux/routing). Required for claudeflow-build / -test / -review skills
173
+ // to @-mention. Without this, those skills' @.claudeflow/playbooks/...
174
+ // refs point to non-existent files.
175
+ const srcPlaybooks = path.join(srcClaudeflow, 'playbooks');
176
+ const dstPlaybooks = path.join(cwd, '.claudeflow', 'playbooks');
177
+ if (fs.existsSync(srcPlaybooks)) {
178
+ copyDirSync(srcPlaybooks, dstPlaybooks);
179
+ }
180
+
170
181
  materializeSharedAppendPrompt(cwd);
171
182
  ensureDefaultClaudeMdRules(cwd);
172
183
  propagateTemplateRules(cwd, srcTemplates);
184
+ // v2: scaffold the 8 system rules (3 always-loaded + 5 path-scoped)
185
+ // using scaffold-system-rule.js. When setup-context.json exists
186
+ // (brownfield), it derives framework-aware `paths` frontmatter. When
187
+ // setup-context.json is absent (greenfield), it falls back to the
188
+ // template's broad-default paths. No-clobber preserved — existing
189
+ // user customizations win.
190
+ propagateSystemRulesViaScaffold(cwd);
173
191
  // After CLAUDE.md exists, append the claudeflow addendum (the load-bearing
174
192
  // rule "all code changes flow through /claudeflow-build" + mode-aware
175
193
  // mandates). Idempotent: runs every install/update; the block lives
@@ -193,6 +211,11 @@ async function run() {
193
211
  // Remove previously template-seeded base rules. Project memory now comes
194
212
  // from setup-context, generated project rules, and root CLAUDE.md.
195
213
  pruneLegacyTemplateRules(cwd);
214
+ // v2 cleanup: remove v1 build-orchestrator artifacts (phases/, references/,
215
+ // and v1-only enforcement hooks). These were template-managed in earlier
216
+ // versions but aren't in the v2 manifest, so install.js's stale-removal
217
+ // doesn't always identify them. Be explicit.
218
+ pruneLegacyV1BuildArtifacts(cwd);
196
219
 
197
220
  // Copy commands
198
221
  const srcCommands = path.join(srcClaude, 'commands');
@@ -970,10 +993,10 @@ function collectManagedPathsFromRelease(extractRoot) {
970
993
  destPrefix: '.claude/hooks',
971
994
  });
972
995
 
973
- // Claudeflow dirs: runtime, templates, docs in .claudeflow/.
974
- // (variants/ removed in v2.13.148. .claudeflow/cli/ removed in v2.13.153
975
- // only held the now-deleted claudeflow-mode.js variant-switcher.)
976
- ['runtime', 'templates', 'docs'].forEach((folder) => {
996
+ // Claudeflow dirs: runtime, templates, docs, playbooks in .claudeflow/.
997
+ // playbooks/ added in v2 required for the claudeflow-build orchestrator
998
+ // and its always-loaded foundation/routing references.
999
+ ['runtime', 'templates', 'docs', 'playbooks'].forEach((folder) => {
977
1000
  addFilesFromDir(managed, extractRoot, path.join(srcClaudeflow, folder));
978
1001
  });
979
1002
 
@@ -1031,9 +1054,10 @@ function collectLegacyManagedPathsFromDisk(projectRoot) {
1031
1054
  // Claude Code native: hooks stay in .claude/
1032
1055
  addFilesFromDir(managed, projectRoot, path.join(claudeDir, 'hooks'));
1033
1056
 
1034
- // Claudeflow dirs: runtime, templates, docs in .claudeflow/
1057
+ // Claudeflow dirs: runtime, templates, docs, playbooks in .claudeflow/.
1058
+ // playbooks/ added in v2 — required for the claudeflow-build orchestrator.
1035
1059
  // (variants/ removed in v2.13.148. .claudeflow/cli/ removed in v2.13.153.)
1036
- ['runtime', 'templates', 'docs'].forEach((folder) => {
1060
+ ['runtime', 'templates', 'docs', 'playbooks'].forEach((folder) => {
1037
1061
  addFilesFromDir(managed, projectRoot, path.join(claudeflowDir, folder));
1038
1062
  });
1039
1063
 
@@ -1159,6 +1183,42 @@ function assertRequiredTemplateRules(rulesDir) {
1159
1183
  }
1160
1184
  }
1161
1185
 
1186
+ // v1 build-orchestrator artifacts that v2 replaces. When upgrading from a
1187
+ // pre-v2 install, these stay on disk because install.js's stale cleanup
1188
+ // can't match files that exist on disk but aren't in the v2 ZIP manifest.
1189
+ // Listing them explicitly here makes the v1 → v2 upgrade leave a clean
1190
+ // .claude/.
1191
+ const LEGACY_V1_BUILD_ARTIFACTS = [
1192
+ // v1 had phases/references inside build/test/review skills; v2 doesn't.
1193
+ '.claude/skills/claudeflow-build/phases',
1194
+ '.claude/skills/claudeflow-build/references',
1195
+ '.claude/skills/claudeflow-test/phases',
1196
+ '.claude/skills/claudeflow-test/references',
1197
+ '.claude/skills/claudeflow-review/phases',
1198
+ '.claude/skills/claudeflow-review/references',
1199
+ // v1 enforcement hooks; v2 uses guard-sensitive-files + validate-closure +
1200
+ // session-env + filter-command-output instead.
1201
+ '.claude/hooks/PreToolUse/enforce-task-creation.js',
1202
+ '.claude/hooks/PreToolUse/enforce-ecosystem-artifacts.js',
1203
+ '.claude/hooks/PreToolUse/freeze-step-contract.js',
1204
+ '.claude/hooks/PreToolUse/freeze-workflow-state.js',
1205
+ '.claude/hooks/PreToolUse/route-exit-plan-mode.js',
1206
+ '.claude/hooks/PreToolUse/stack-debt-guard.js',
1207
+ ];
1208
+
1209
+ function pruneLegacyV1BuildArtifacts(projectRoot) {
1210
+ for (const relPath of LEGACY_V1_BUILD_ARTIFACTS) {
1211
+ const absPath = path.join(projectRoot, relPath);
1212
+ if (!fs.existsSync(absPath)) continue;
1213
+ try {
1214
+ fs.rmSync(absPath, { recursive: true, force: true });
1215
+ } catch {
1216
+ // Best-effort. If the file is locked or permissions issue, skip;
1217
+ // the user can clean up manually. Don't abort the install.
1218
+ }
1219
+ }
1220
+ }
1221
+
1162
1222
  function pruneLegacyTemplateRules(projectRoot) {
1163
1223
  const rulesDir = path.join(projectRoot, '.claude', 'rules');
1164
1224
  for (const filename of LEGACY_TEMPLATE_RULES) {
@@ -1176,12 +1236,74 @@ function propagateTemplateRules(projectRoot, srcTemplates) {
1176
1236
  fs.mkdirSync(dstRulesDir, { recursive: true });
1177
1237
  for (const filename of fs.readdirSync(srcRulesDir)) {
1178
1238
  if (!filename.endsWith('.md')) continue;
1239
+ // Skip the 8 v2 system rules — they're handled by
1240
+ // propagateSystemRulesViaScaffold, which derives framework-aware
1241
+ // `paths` from setup-context.json when available.
1242
+ if (V2_SYSTEM_RULES.has(filename)) continue;
1179
1243
  const dstPath = path.join(dstRulesDir, filename);
1180
1244
  if (fs.existsSync(dstPath)) continue; // no-clobber: preserve project-specific or user rules
1181
1245
  fs.copyFileSync(path.join(srcRulesDir, filename), dstPath);
1182
1246
  }
1183
1247
  }
1184
1248
 
1249
+ // The 8 v2 system rules that ship with claudeflow. propagateTemplateRules
1250
+ // skips these because they need scaffold-system-rule.js to derive
1251
+ // framework-aware `paths` frontmatter (e.g., a Next.js+Prisma project
1252
+ // gets `**/*.prisma` and `**/app/api/**` instead of broad defaults).
1253
+ const V2_SYSTEM_RULES = new Set([
1254
+ 'claudeflow-context-engineering.md',
1255
+ 'claudeflow-engineering-quality.md',
1256
+ 'claudeflow-testing.md',
1257
+ 'claudeflow-security.md',
1258
+ 'claudeflow-api.md',
1259
+ 'claudeflow-database.md',
1260
+ 'claudeflow-ui-ux.md',
1261
+ 'claudeflow-evidence.md',
1262
+ ]);
1263
+
1264
+ // Map of v2 rule filenames → rule slug used by scaffold-system-rule.js
1265
+ function ruleSlugFromFilename(filename) {
1266
+ // Strip "claudeflow-" prefix and ".md" suffix. e.g.,
1267
+ // "claudeflow-ui-ux.md" → "ui-ux".
1268
+ return filename.replace(/^claudeflow-/, '').replace(/\.md$/, '');
1269
+ }
1270
+
1271
+ function propagateSystemRulesViaScaffold(projectRoot) {
1272
+ const scaffoldScript = path.join(
1273
+ projectRoot, '.claudeflow', 'runtime', 'scaffold-system-rule.js',
1274
+ );
1275
+ if (!fs.existsSync(scaffoldScript)) {
1276
+ // scaffold-system-rule.js is part of v2 — if missing, the project
1277
+ // was bootstrapped with a pre-v2 ZIP. Skip silently; user can run
1278
+ // /claudeflow-update later to refresh.
1279
+ return;
1280
+ }
1281
+
1282
+ for (const filename of V2_SYSTEM_RULES) {
1283
+ const slug = ruleSlugFromFilename(filename);
1284
+ try {
1285
+ execFileSync('node', [
1286
+ scaffoldScript,
1287
+ '--rule', slug,
1288
+ '--project-root', projectRoot,
1289
+ '--mode', 'init',
1290
+ // No --force: respect no-clobber. User edits win.
1291
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
1292
+ } catch (err) {
1293
+ // scaffold-system-rule.js exits 1 when target exists (no-clobber).
1294
+ // That's expected on re-install; don't warn. Other exit codes are
1295
+ // real errors; log to stderr but don't abort the install.
1296
+ const exitCode = err && err.status;
1297
+ if (exitCode !== 1) {
1298
+ process.stderr.write(
1299
+ `Warning: failed to scaffold system rule "${slug}" (exit ${exitCode}). ` +
1300
+ `You can re-run with /claudeflow-update later.\n`,
1301
+ );
1302
+ }
1303
+ }
1304
+ }
1305
+ }
1306
+
1185
1307
  function materializeSharedAppendPrompt(projectRoot) {
1186
1308
  const templatePath = path.join(projectRoot, SHARED_APPEND_PROMPT_TEMPLATE);
1187
1309
  if (!fs.existsSync(templatePath)) {
@@ -1308,7 +1430,7 @@ function syncBoostAddendumOnInstall(cwd) {
1308
1430
  // mandates inside the addendum body explicitly say "fast-only" or
1309
1431
  // "normal-only" so the LLM applies them conditionally.
1310
1432
  const claudeMdPath = path.join(cwd, 'CLAUDE.md');
1311
- const addendumPath = path.join(cwd, '.claudeflow', 'templates', 'CLAUDE_BOOST_ADDENDUM.md');
1433
+ const addendumPath = path.join(cwd, '.claudeflow', 'templates', 'claudeflow-append-claude-md.md');
1312
1434
  if (!fs.existsSync(claudeMdPath) || !fs.existsSync(addendumPath)) return;
1313
1435
 
1314
1436
  const ADDENDUM_BEGIN = '<!-- claudeflow:boost-mode:BEGIN -->';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomatic-labs/claudeflow",
3
- "version": "2.14.3",
3
+ "version": "2.14.5",
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"