@axiomatic-labs/claudeflow 2.14.2 → 2.14.4
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 +77 -7
- package/package.json +1 -1
package/lib/install.js
CHANGED
|
@@ -170,6 +170,13 @@ async function run() {
|
|
|
170
170
|
materializeSharedAppendPrompt(cwd);
|
|
171
171
|
ensureDefaultClaudeMdRules(cwd);
|
|
172
172
|
propagateTemplateRules(cwd, srcTemplates);
|
|
173
|
+
// v2: scaffold the 8 system rules (3 always-loaded + 5 path-scoped)
|
|
174
|
+
// using scaffold-system-rule.js. When setup-context.json exists
|
|
175
|
+
// (brownfield), it derives framework-aware `paths` frontmatter. When
|
|
176
|
+
// setup-context.json is absent (greenfield), it falls back to the
|
|
177
|
+
// template's broad-default paths. No-clobber preserved — existing
|
|
178
|
+
// user customizations win.
|
|
179
|
+
propagateSystemRulesViaScaffold(cwd);
|
|
173
180
|
// After CLAUDE.md exists, append the claudeflow addendum (the load-bearing
|
|
174
181
|
// rule "all code changes flow through /claudeflow-build" + mode-aware
|
|
175
182
|
// mandates). Idempotent: runs every install/update; the block lives
|
|
@@ -970,10 +977,10 @@ function collectManagedPathsFromRelease(extractRoot) {
|
|
|
970
977
|
destPrefix: '.claude/hooks',
|
|
971
978
|
});
|
|
972
979
|
|
|
973
|
-
// Claudeflow dirs: runtime, templates, docs in .claudeflow/.
|
|
974
|
-
//
|
|
975
|
-
//
|
|
976
|
-
['runtime', 'templates', 'docs'].forEach((folder) => {
|
|
980
|
+
// Claudeflow dirs: runtime, templates, docs, playbooks in .claudeflow/.
|
|
981
|
+
// playbooks/ added in v2 — required for the claudeflow-build orchestrator
|
|
982
|
+
// and its always-loaded foundation/routing references.
|
|
983
|
+
['runtime', 'templates', 'docs', 'playbooks'].forEach((folder) => {
|
|
977
984
|
addFilesFromDir(managed, extractRoot, path.join(srcClaudeflow, folder));
|
|
978
985
|
});
|
|
979
986
|
|
|
@@ -1031,9 +1038,10 @@ function collectLegacyManagedPathsFromDisk(projectRoot) {
|
|
|
1031
1038
|
// Claude Code native: hooks stay in .claude/
|
|
1032
1039
|
addFilesFromDir(managed, projectRoot, path.join(claudeDir, 'hooks'));
|
|
1033
1040
|
|
|
1034
|
-
// Claudeflow dirs: runtime, templates, docs in .claudeflow
|
|
1041
|
+
// Claudeflow dirs: runtime, templates, docs, playbooks in .claudeflow/.
|
|
1042
|
+
// playbooks/ added in v2 — required for the claudeflow-build orchestrator.
|
|
1035
1043
|
// (variants/ removed in v2.13.148. .claudeflow/cli/ removed in v2.13.153.)
|
|
1036
|
-
['runtime', 'templates', 'docs'].forEach((folder) => {
|
|
1044
|
+
['runtime', 'templates', 'docs', 'playbooks'].forEach((folder) => {
|
|
1037
1045
|
addFilesFromDir(managed, projectRoot, path.join(claudeflowDir, folder));
|
|
1038
1046
|
});
|
|
1039
1047
|
|
|
@@ -1176,12 +1184,74 @@ function propagateTemplateRules(projectRoot, srcTemplates) {
|
|
|
1176
1184
|
fs.mkdirSync(dstRulesDir, { recursive: true });
|
|
1177
1185
|
for (const filename of fs.readdirSync(srcRulesDir)) {
|
|
1178
1186
|
if (!filename.endsWith('.md')) continue;
|
|
1187
|
+
// Skip the 8 v2 system rules — they're handled by
|
|
1188
|
+
// propagateSystemRulesViaScaffold, which derives framework-aware
|
|
1189
|
+
// `paths` from setup-context.json when available.
|
|
1190
|
+
if (V2_SYSTEM_RULES.has(filename)) continue;
|
|
1179
1191
|
const dstPath = path.join(dstRulesDir, filename);
|
|
1180
1192
|
if (fs.existsSync(dstPath)) continue; // no-clobber: preserve project-specific or user rules
|
|
1181
1193
|
fs.copyFileSync(path.join(srcRulesDir, filename), dstPath);
|
|
1182
1194
|
}
|
|
1183
1195
|
}
|
|
1184
1196
|
|
|
1197
|
+
// The 8 v2 system rules that ship with claudeflow. propagateTemplateRules
|
|
1198
|
+
// skips these because they need scaffold-system-rule.js to derive
|
|
1199
|
+
// framework-aware `paths` frontmatter (e.g., a Next.js+Prisma project
|
|
1200
|
+
// gets `**/*.prisma` and `**/app/api/**` instead of broad defaults).
|
|
1201
|
+
const V2_SYSTEM_RULES = new Set([
|
|
1202
|
+
'claudeflow-context-engineering.md',
|
|
1203
|
+
'claudeflow-engineering-quality.md',
|
|
1204
|
+
'claudeflow-testing.md',
|
|
1205
|
+
'claudeflow-security.md',
|
|
1206
|
+
'claudeflow-api.md',
|
|
1207
|
+
'claudeflow-database.md',
|
|
1208
|
+
'claudeflow-ui-ux.md',
|
|
1209
|
+
'claudeflow-evidence.md',
|
|
1210
|
+
]);
|
|
1211
|
+
|
|
1212
|
+
// Map of v2 rule filenames → rule slug used by scaffold-system-rule.js
|
|
1213
|
+
function ruleSlugFromFilename(filename) {
|
|
1214
|
+
// Strip "claudeflow-" prefix and ".md" suffix. e.g.,
|
|
1215
|
+
// "claudeflow-ui-ux.md" → "ui-ux".
|
|
1216
|
+
return filename.replace(/^claudeflow-/, '').replace(/\.md$/, '');
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
function propagateSystemRulesViaScaffold(projectRoot) {
|
|
1220
|
+
const scaffoldScript = path.join(
|
|
1221
|
+
projectRoot, '.claudeflow', 'runtime', 'scaffold-system-rule.js',
|
|
1222
|
+
);
|
|
1223
|
+
if (!fs.existsSync(scaffoldScript)) {
|
|
1224
|
+
// scaffold-system-rule.js is part of v2 — if missing, the project
|
|
1225
|
+
// was bootstrapped with a pre-v2 ZIP. Skip silently; user can run
|
|
1226
|
+
// /claudeflow-update later to refresh.
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
for (const filename of V2_SYSTEM_RULES) {
|
|
1231
|
+
const slug = ruleSlugFromFilename(filename);
|
|
1232
|
+
try {
|
|
1233
|
+
execFileSync('node', [
|
|
1234
|
+
scaffoldScript,
|
|
1235
|
+
'--rule', slug,
|
|
1236
|
+
'--project-root', projectRoot,
|
|
1237
|
+
'--mode', 'init',
|
|
1238
|
+
// No --force: respect no-clobber. User edits win.
|
|
1239
|
+
], { stdio: ['ignore', 'ignore', 'pipe'] });
|
|
1240
|
+
} catch (err) {
|
|
1241
|
+
// scaffold-system-rule.js exits 1 when target exists (no-clobber).
|
|
1242
|
+
// That's expected on re-install; don't warn. Other exit codes are
|
|
1243
|
+
// real errors; log to stderr but don't abort the install.
|
|
1244
|
+
const exitCode = err && err.status;
|
|
1245
|
+
if (exitCode !== 1) {
|
|
1246
|
+
process.stderr.write(
|
|
1247
|
+
`Warning: failed to scaffold system rule "${slug}" (exit ${exitCode}). ` +
|
|
1248
|
+
`You can re-run with /claudeflow-update later.\n`,
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1185
1255
|
function materializeSharedAppendPrompt(projectRoot) {
|
|
1186
1256
|
const templatePath = path.join(projectRoot, SHARED_APPEND_PROMPT_TEMPLATE);
|
|
1187
1257
|
if (!fs.existsSync(templatePath)) {
|
|
@@ -1308,7 +1378,7 @@ function syncBoostAddendumOnInstall(cwd) {
|
|
|
1308
1378
|
// mandates inside the addendum body explicitly say "fast-only" or
|
|
1309
1379
|
// "normal-only" so the LLM applies them conditionally.
|
|
1310
1380
|
const claudeMdPath = path.join(cwd, 'CLAUDE.md');
|
|
1311
|
-
const addendumPath = path.join(cwd, '.claudeflow', 'templates', '
|
|
1381
|
+
const addendumPath = path.join(cwd, '.claudeflow', 'templates', 'claudeflow-append-claude-md.md');
|
|
1312
1382
|
if (!fs.existsSync(claudeMdPath) || !fs.existsSync(addendumPath)) return;
|
|
1313
1383
|
|
|
1314
1384
|
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.4",
|
|
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"
|