create-healix 1.2.0 → 1.3.1
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/package.json +3 -3
- package/src/scaffold.js +5 -2
- package/src/templates.js +59 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-healix",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Scaffold a healix WDIO project with MCP integration ready out of the box",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "echo 'No build step required — source is plain ESM'",
|
|
15
|
-
"test": "node test/seed-parity.test.mjs && node bin/create-healix.js --help",
|
|
15
|
+
"test": "node test/seed-parity.test.mjs && node test/rehydrate-hooks.test.mjs && node bin/create-healix.js --help",
|
|
16
16
|
"test:parity": "node test/seed-parity.test.mjs"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"prompts": "^2.4.2",
|
|
20
|
-
"wdio-healix-service": "^0.
|
|
20
|
+
"wdio-healix-service": "^0.3.0"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=18"
|
package/src/scaffold.js
CHANGED
|
@@ -4,7 +4,7 @@ import { execSync } from 'node:child_process';
|
|
|
4
4
|
import {
|
|
5
5
|
tsconfigJson, packageJson, wdioWebConf, mcpJson, healixAgentJson,
|
|
6
6
|
exampleSpec, examplePage, exampleLocators, readme,
|
|
7
|
-
claudeSettings, claudeMd, claudeRehydrateScript,
|
|
7
|
+
claudeSettings, claudeMd, claudeRehydrateScript, cursorHooks,
|
|
8
8
|
} from './templates.js';
|
|
9
9
|
|
|
10
10
|
function write(filePath, content) {
|
|
@@ -54,9 +54,12 @@ export function scaffold(projectName, targetDir, options = {}) {
|
|
|
54
54
|
write(path.join(projectDir, '.mcp.json'), mcpJson(apiPort));
|
|
55
55
|
write(path.join(projectDir, 'healix.agent.json'), healixAgentJson());
|
|
56
56
|
write(path.join(projectDir, 'README.md'), readme(projectName));
|
|
57
|
-
// Durable knowledge delivery:
|
|
57
|
+
// Durable knowledge delivery: re-hydration hook (fires at start + after compaction)
|
|
58
|
+
// wired for EVERY host — Spryv + Claude Code via .claude/settings.json, Cursor via
|
|
59
|
+
// .cursor/hooks.json — all running ONE shared script. Plus a thin project-scope pointer.
|
|
58
60
|
write(path.join(projectDir, '.claude', 'settings.json'), claudeSettings());
|
|
59
61
|
write(path.join(projectDir, '.claude', 'healix-rehydrate.mjs'), claudeRehydrateScript());
|
|
62
|
+
write(path.join(projectDir, '.cursor', 'hooks.json'), cursorHooks());
|
|
60
63
|
write(path.join(projectDir, 'CLAUDE.md'), claudeMd(projectName));
|
|
61
64
|
|
|
62
65
|
write(path.join(projectDir, 'test', 'specs', 'example.spec.ts'), exampleSpec());
|
package/src/templates.js
CHANGED
|
@@ -154,11 +154,66 @@ const REHYDRATE_REMINDER =
|
|
|
154
154
|
'the scaffold tools. If the Healix guide is not currently in your context, run ' +
|
|
155
155
|
'healix_guide before any scaffold/heal/run step — do not operate from memory of it.';
|
|
156
156
|
|
|
157
|
-
//
|
|
158
|
-
// cross-shell quoting hell — the hook command is just
|
|
157
|
+
// The ONE script every host runs to re-anchor the agent. Living in a FILE (not an
|
|
158
|
+
// inline `node -e`) avoids cross-shell quoting hell — the hook command is just
|
|
159
|
+
// `node <path>`. It is host-agnostic: the SAME file is referenced by both
|
|
160
|
+
// • .claude/settings.json (Spryv + Claude Code SessionStart) → wants PLAIN TEXT stdout
|
|
161
|
+
// • .cursor/hooks.json (Cursor sessionStart) → wants JSON {additional_context}
|
|
162
|
+
// We detect Cursor from its stdin payload (it sends composer_mode / is_background_agent)
|
|
163
|
+
// and emit JSON for it; everyone else gets plain text, which both Spryv (captures hook
|
|
164
|
+
// stdout) and Claude Code (adds SessionStart stdout to context) inject verbatim. Cursor
|
|
165
|
+
// has no post-compaction inject event, so its sessionStart additional_context is seeded
|
|
166
|
+
// into the persistent system context — where it survives compaction.
|
|
159
167
|
export function claudeRehydrateScript() {
|
|
160
|
-
return `//
|
|
161
|
-
|
|
168
|
+
return `// Re-anchors the agent on the Healix workflow at session start and after a context
|
|
169
|
+
// compaction. Host-agnostic — referenced by .claude/settings.json (Spryv + Claude Code)
|
|
170
|
+
// AND .cursor/hooks.json (Cursor). Cursor wants JSON; the others want plain text.
|
|
171
|
+
const REMINDER = ${JSON.stringify(REHYDRATE_REMINDER)};
|
|
172
|
+
|
|
173
|
+
let buf = '';
|
|
174
|
+
let settled = false;
|
|
175
|
+
function settle() {
|
|
176
|
+
if (settled) return;
|
|
177
|
+
settled = true;
|
|
178
|
+
let host = null;
|
|
179
|
+
try { host = buf.trim() ? JSON.parse(buf) : null; } catch { host = null; }
|
|
180
|
+
// composer_mode / is_background_agent are Cursor-only stdin keys.
|
|
181
|
+
const isCursor = !!host && ('composer_mode' in host || 'is_background_agent' in host);
|
|
182
|
+
if (isCursor) process.stdout.write(JSON.stringify({ additional_context: REMINDER }));
|
|
183
|
+
else process.stdout.write(REMINDER + '\\n');
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
process.stdin.setEncoding('utf8');
|
|
187
|
+
process.stdin.on('data', (c) => { buf += c; });
|
|
188
|
+
process.stdin.on('end', settle);
|
|
189
|
+
process.stdin.on('error', settle);
|
|
190
|
+
} catch { /* no stdin — the timer below settles it */ }
|
|
191
|
+
// Hosts that ignore stdin (Spryv pipes /dev/null) may not emit 'end' reliably; a short
|
|
192
|
+
// unref'd timer guarantees we print exactly once without keeping the process alive.
|
|
193
|
+
const t = setTimeout(settle, 60);
|
|
194
|
+
if (t && t.unref) t.unref();
|
|
195
|
+
`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Cursor 1.7+ hook config — Cursor reads .cursor/hooks.json (NOT .claude/settings.json)
|
|
199
|
+
// and its hooks speak a stdin-JSON → stdout-JSON contract. `sessionStart` returns
|
|
200
|
+
// { additional_context } which Cursor injects into the agent's system context. (Cursor's
|
|
201
|
+
// only compaction event, `preCompact`, is observational and cannot inject — so seeding at
|
|
202
|
+
// sessionStart, which persists through compaction, is the correct re-hydration vehicle.)
|
|
203
|
+
// The command runs the SAME shared script as the Claude/Spryv hook — one source of truth.
|
|
204
|
+
export function cursorHooks() {
|
|
205
|
+
return JSON.stringify(
|
|
206
|
+
{
|
|
207
|
+
version: 1,
|
|
208
|
+
hooks: {
|
|
209
|
+
sessionStart: [
|
|
210
|
+
{ command: 'node .claude/healix-rehydrate.mjs', type: 'command' },
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
null,
|
|
215
|
+
2,
|
|
216
|
+
);
|
|
162
217
|
}
|
|
163
218
|
|
|
164
219
|
// Claude Code-format SessionStart hook (host-agnostic: read by any host that
|