@axiomatic-labs/claudeflow 2.35.14 → 2.35.16
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 +31 -9
- package/package.json +1 -1
package/lib/install.js
CHANGED
|
@@ -10,10 +10,12 @@ const ui = require('./ui.js');
|
|
|
10
10
|
// claudeflow installs a small, namespaced footprint. Most of it is self-contained files that are simply
|
|
11
11
|
// PLACED (playbooks, scripts, skills) — those can't conflict with the user's project. The only things
|
|
12
12
|
// that need a MERGE (never a clobber) are .claude/settings.json (register our hooks alongside theirs)
|
|
13
|
-
// and CLAUDE.md (
|
|
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
|
|
14
15
|
// platform with no shell dependency. The GitHub auth gate (auth.js/download.js) is untouched.
|
|
15
16
|
|
|
16
17
|
const CLAUDE_MARK = '<!-- claudeflow:begin -->';
|
|
18
|
+
const CLAUDE_END = '<!-- claudeflow:end -->';
|
|
17
19
|
const HOOK_TAG = 'scripts/claudeflow/hook_'; // identifies OUR hook entries in settings.json
|
|
18
20
|
const PER_PROJECT_CONFIGS = ['brand.json', 'risk-signals.json']; // create-if-absent, never clobber
|
|
19
21
|
const SHARED_CONFIGS = ['playbook-map.json', 'agent-map.json']; // always refreshed (shared system)
|
|
@@ -60,13 +62,32 @@ function mergeSettings(cwd, payloadSettings) {
|
|
|
60
62
|
fs.writeFileSync(sp, JSON.stringify(data, null, 2) + '\n');
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
// UPSERT the claudeflow guidance block. The snippet is a self-contained `<!-- claudeflow:begin -->…<!-- end -->`
|
|
66
|
+
// region; everything OUTSIDE the markers is the user's own CLAUDE.md and is never touched. Behavior:
|
|
67
|
+
// • no CLAUDE.md → create it with the block
|
|
68
|
+
// • CLAUDE.md, no block yet → append the block (preserve the user's content)
|
|
69
|
+
// • CLAUDE.md WITH the block → REPLACE the marked region in place, so guidance updates PROPAGATE on `update`
|
|
70
|
+
// (the old code appended-once and never refreshed → a stale project never got new disciplines).
|
|
71
|
+
// • begin marker but no end (corrupted) → leave it untouched (don't risk eating user content)
|
|
72
|
+
function syncClaudeMd(cwd, snippetPath) {
|
|
64
73
|
if (!fs.existsSync(snippetPath)) return false;
|
|
65
74
|
const target = path.join(cwd, 'CLAUDE.md');
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
const block = fs.readFileSync(snippetPath, 'utf8').trim();
|
|
76
|
+
if (!fs.existsSync(target)) {
|
|
77
|
+
fs.writeFileSync(target, block + '\n');
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
const cur = fs.readFileSync(target, 'utf8');
|
|
81
|
+
const b = cur.indexOf(CLAUDE_MARK);
|
|
82
|
+
if (b === -1) {
|
|
83
|
+
fs.writeFileSync(target, cur.replace(/\s*$/, '') + '\n\n' + block + '\n');
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
const e = cur.indexOf(CLAUDE_END, b);
|
|
87
|
+
if (e === -1) return false; // begin without end → corrupt region; don't clobber
|
|
88
|
+
const updated = cur.slice(0, b) + block + cur.slice(e + CLAUDE_END.length);
|
|
89
|
+
if (updated === cur) return false; // already current
|
|
90
|
+
fs.writeFileSync(target, updated);
|
|
70
91
|
return true;
|
|
71
92
|
}
|
|
72
93
|
|
|
@@ -131,8 +152,8 @@ function installFromPayload(src, cwd) {
|
|
|
131
152
|
try { mergeSettings(cwd, JSON.parse(fs.readFileSync(srcSettings, 'utf8'))); } catch {}
|
|
132
153
|
}
|
|
133
154
|
|
|
134
|
-
// 6) CLAUDE.md —
|
|
135
|
-
out.claudeMd =
|
|
155
|
+
// 6) CLAUDE.md — upsert the managed guidance block between markers (idempotent; updates propagate on re-install).
|
|
156
|
+
out.claudeMd = syncClaudeMd(cwd, path.join(src, 'assets', 'CLAUDE.snippet.md'));
|
|
136
157
|
|
|
137
158
|
return out;
|
|
138
159
|
}
|
|
@@ -170,10 +191,11 @@ async function run() {
|
|
|
170
191
|
|
|
171
192
|
ui.success(`claudeflow v${version} installed`);
|
|
172
193
|
ui.info(` ${summary.playbooks} playbooks · ${summary.scripts} scripts · ${summary.skills} skills`
|
|
173
|
-
+ (summary.claudeMd ? ' · CLAUDE.md guidance
|
|
194
|
+
+ (summary.claudeMd ? ' · CLAUDE.md guidance synced' : ''));
|
|
174
195
|
ui.done(`Describe a change and the ${ui.BOLD}claudeflow-implement${ui.RESET} skill will drive it.`);
|
|
175
196
|
}
|
|
176
197
|
|
|
177
198
|
module.exports = run;
|
|
178
199
|
module.exports.installFromPayload = installFromPayload;
|
|
179
200
|
module.exports.mergeSettings = mergeSettings;
|
|
201
|
+
module.exports.syncClaudeMd = syncClaudeMd;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiomatic-labs/claudeflow",
|
|
3
|
-
"version": "2.35.
|
|
3
|
+
"version": "2.35.16",
|
|
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"
|