@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.
- package/lib/install.js +129 -7
- 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
|
-
//
|
|
975
|
-
//
|
|
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', '
|
|
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
|
+
"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"
|