continuous-improvement 2.2.0 → 3.0.0
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/CHANGELOG.md +17 -0
- package/README.md +183 -26
- package/bin/analyze.sh +27 -41
- package/bin/install.mjs +193 -27
- package/bin/mcp-server.mjs +543 -0
- package/hooks/session.sh +106 -0
- package/package.json +17 -8
- package/plugins/beginner.json +42 -0
- package/plugins/expert.json +62 -0
package/bin/install.mjs
CHANGED
|
@@ -4,12 +4,15 @@
|
|
|
4
4
|
* continuous-improvement installer
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* npx continuous-improvement install
|
|
8
|
-
* npx continuous-improvement install --target claude
|
|
9
|
-
* npx continuous-improvement install --target openclaw
|
|
10
|
-
* npx continuous-improvement install --target cursor
|
|
11
|
-
* npx continuous-improvement install --target all
|
|
12
|
-
* npx continuous-improvement install --
|
|
7
|
+
* npx continuous-improvement install # auto-detect & install (beginner)
|
|
8
|
+
* npx continuous-improvement install --target claude # install to ~/.claude/skills/ + Mulahazah
|
|
9
|
+
* npx continuous-improvement install --target openclaw # install to ~/.openclaw/skills/
|
|
10
|
+
* npx continuous-improvement install --target cursor # install to ~/.cursor/skills/
|
|
11
|
+
* npx continuous-improvement install --target all # install to all detected targets
|
|
12
|
+
* npx continuous-improvement install --mode beginner # hooks only (default)
|
|
13
|
+
* npx continuous-improvement install --mode expert # hooks + MCP server + session hooks
|
|
14
|
+
* npx continuous-improvement install --mode mcp # MCP server only (any editor)
|
|
15
|
+
* npx continuous-improvement install --uninstall # remove from all targets
|
|
13
16
|
*/
|
|
14
17
|
|
|
15
18
|
import {
|
|
@@ -31,6 +34,11 @@ const SKILL_SOURCE = join(__dirname, "..", "SKILL.md");
|
|
|
31
34
|
const SKILL_NAME = "continuous-improvement";
|
|
32
35
|
const REPO_ROOT = join(__dirname, "..");
|
|
33
36
|
|
|
37
|
+
// Parse --mode flag
|
|
38
|
+
const _args = process.argv.slice(2);
|
|
39
|
+
const _modeIdx = _args.indexOf("--mode");
|
|
40
|
+
const INSTALL_MODE = _modeIdx !== -1 && _args[_modeIdx + 1] ? _args[_modeIdx + 1] : "beginner";
|
|
41
|
+
|
|
34
42
|
const TARGETS = {
|
|
35
43
|
claude: {
|
|
36
44
|
label: "Claude Code",
|
|
@@ -70,6 +78,17 @@ function installTo(key) {
|
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
try {
|
|
81
|
+
// MCP-only mode: skip skill file copy, just register MCP server
|
|
82
|
+
if (INSTALL_MODE === "mcp") {
|
|
83
|
+
if (key === "claude") {
|
|
84
|
+
setupMulahazah();
|
|
85
|
+
console.log(` ✓ ${target.label} → MCP server only`);
|
|
86
|
+
} else {
|
|
87
|
+
console.log(` ⊘ ${target.label} — MCP mode only applies to Claude Code`);
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
73
92
|
mkdirSync(target.dir, { recursive: true });
|
|
74
93
|
copyFileSync(SKILL_SOURCE, join(target.dir, "SKILL.md"));
|
|
75
94
|
console.log(` ✓ ${target.label} → ${target.dir}/SKILL.md`);
|
|
@@ -103,7 +122,18 @@ function setupMulahazah() {
|
|
|
103
122
|
console.log(` ✓ observe.sh → ${observeDest}`);
|
|
104
123
|
}
|
|
105
124
|
|
|
106
|
-
// 3. Copy
|
|
125
|
+
// 3. Copy session.sh for expert mode
|
|
126
|
+
if (INSTALL_MODE === "expert") {
|
|
127
|
+
const sessionSrc = join(REPO_ROOT, "hooks", "session.sh");
|
|
128
|
+
const sessionDest = join(instinctsDir, "session.sh");
|
|
129
|
+
if (existsSync(sessionSrc)) {
|
|
130
|
+
copyFileSync(sessionSrc, sessionDest);
|
|
131
|
+
chmodSync(sessionDest, 0o755);
|
|
132
|
+
console.log(` ✓ session.sh → ${sessionDest}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 4. Copy /continuous-improvement command
|
|
107
137
|
const commandsDir = join(home, ".claude", "commands");
|
|
108
138
|
mkdirSync(commandsDir, { recursive: true });
|
|
109
139
|
const cmdSrc = join(REPO_ROOT, "commands", "continuous-improvement.md");
|
|
@@ -113,8 +143,64 @@ function setupMulahazah() {
|
|
|
113
143
|
console.log(` ✓ /continuous-improvement command → ${cmdDest}`);
|
|
114
144
|
}
|
|
115
145
|
|
|
116
|
-
//
|
|
146
|
+
// 5. Patch ~/.claude/settings.json with hooks
|
|
117
147
|
patchClaudeSettings(observeDest);
|
|
148
|
+
|
|
149
|
+
// 6. Setup MCP server for expert or mcp mode
|
|
150
|
+
if (INSTALL_MODE === "expert" || INSTALL_MODE === "mcp") {
|
|
151
|
+
setupMcpServer();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function setupMcpServer() {
|
|
156
|
+
const home = homedir();
|
|
157
|
+
const mcpServerPath = join(REPO_ROOT, "bin", "mcp-server.mjs");
|
|
158
|
+
const mcpMode = INSTALL_MODE === "mcp" ? "beginner" : "expert";
|
|
159
|
+
|
|
160
|
+
// Patch Claude Code settings.json with MCP server config
|
|
161
|
+
const settingsPath = join(home, ".claude", "settings.json");
|
|
162
|
+
let settings = {};
|
|
163
|
+
if (existsSync(settingsPath)) {
|
|
164
|
+
try {
|
|
165
|
+
settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
166
|
+
} catch {
|
|
167
|
+
console.warn(` ! Could not parse settings.json — skipping MCP setup`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (!settings.mcpServers) settings.mcpServers = {};
|
|
173
|
+
|
|
174
|
+
const alreadySetup = settings.mcpServers["continuous-improvement"];
|
|
175
|
+
if (!alreadySetup) {
|
|
176
|
+
settings.mcpServers["continuous-improvement"] = {
|
|
177
|
+
command: "node",
|
|
178
|
+
args: [mcpServerPath, "--mode", mcpMode],
|
|
179
|
+
};
|
|
180
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
181
|
+
console.log(` ✓ MCP server registered (mode: ${mcpMode})`);
|
|
182
|
+
} else {
|
|
183
|
+
console.log(` ✓ MCP server already registered — no change`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Also write claude_desktop_config.json if it exists
|
|
187
|
+
const desktopConfig = join(home, ".claude", "claude_desktop_config.json");
|
|
188
|
+
if (existsSync(desktopConfig)) {
|
|
189
|
+
try {
|
|
190
|
+
const config = JSON.parse(readFileSync(desktopConfig, "utf8"));
|
|
191
|
+
if (!config.mcpServers) config.mcpServers = {};
|
|
192
|
+
if (!config.mcpServers["continuous-improvement"]) {
|
|
193
|
+
config.mcpServers["continuous-improvement"] = {
|
|
194
|
+
command: "node",
|
|
195
|
+
args: [mcpServerPath, "--mode", mcpMode],
|
|
196
|
+
};
|
|
197
|
+
writeFileSync(desktopConfig, JSON.stringify(config, null, 2) + "\n");
|
|
198
|
+
console.log(` ✓ Claude Desktop MCP config updated`);
|
|
199
|
+
}
|
|
200
|
+
} catch {
|
|
201
|
+
// skip
|
|
202
|
+
}
|
|
203
|
+
}
|
|
118
204
|
}
|
|
119
205
|
|
|
120
206
|
function patchClaudeSettings(observePath) {
|
|
@@ -159,11 +245,40 @@ function patchClaudeSettings(observePath) {
|
|
|
159
245
|
}
|
|
160
246
|
}
|
|
161
247
|
|
|
248
|
+
// Expert mode: add session hooks
|
|
249
|
+
if (INSTALL_MODE === "expert") {
|
|
250
|
+
const sessionPath = join(homedir(), ".claude", "instincts", "session.sh");
|
|
251
|
+
const sessionHook = {
|
|
252
|
+
matcher: "",
|
|
253
|
+
hooks: [{ type: "command", command: `bash "${sessionPath}"` }],
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// Note: SessionStart/SessionEnd hooks may not be supported in all versions.
|
|
257
|
+
// We register them — they'll be silently ignored if unsupported.
|
|
258
|
+
for (const hookType of ["SessionStart", "SessionEnd"]) {
|
|
259
|
+
if (!Array.isArray(settings.hooks[hookType])) {
|
|
260
|
+
settings.hooks[hookType] = [];
|
|
261
|
+
}
|
|
262
|
+
const alreadyPatched = settings.hooks[hookType].some(
|
|
263
|
+
(h) =>
|
|
264
|
+
Array.isArray(h.hooks) &&
|
|
265
|
+
h.hooks.some((hh) => hh.command && hh.command.includes("session.sh"))
|
|
266
|
+
);
|
|
267
|
+
if (!alreadyPatched) {
|
|
268
|
+
settings.hooks[hookType].push(sessionHook);
|
|
269
|
+
changed = true;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
162
274
|
if (changed) {
|
|
163
275
|
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
164
|
-
|
|
276
|
+
const hookTypes = INSTALL_MODE === "expert"
|
|
277
|
+
? "PreToolUse/PostToolUse/SessionStart/SessionEnd"
|
|
278
|
+
: "PreToolUse/PostToolUse";
|
|
279
|
+
console.log(` ✓ Patched ~/.claude/settings.json with ${hookTypes} hooks`);
|
|
165
280
|
} else {
|
|
166
|
-
console.log(` ✓ settings.json already has
|
|
281
|
+
console.log(` ✓ settings.json already has hooks — no change needed`);
|
|
167
282
|
}
|
|
168
283
|
}
|
|
169
284
|
|
|
@@ -197,24 +312,28 @@ function uninstallAll() {
|
|
|
197
312
|
}
|
|
198
313
|
}
|
|
199
314
|
|
|
200
|
-
// 3. Remove observe.sh from instincts dir
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
315
|
+
// 3. Remove observe.sh and session.sh from instincts dir
|
|
316
|
+
for (const hookFile of ["observe.sh", "session.sh"]) {
|
|
317
|
+
const filePath = join(home, ".claude", "instincts", hookFile);
|
|
318
|
+
if (existsSync(filePath)) {
|
|
319
|
+
try {
|
|
320
|
+
rmSync(filePath);
|
|
321
|
+
console.log(` ✓ Removed ${hookFile}`);
|
|
322
|
+
} catch (err) {
|
|
323
|
+
console.error(` ✗ ${hookFile}: ${err.message}`);
|
|
324
|
+
}
|
|
208
325
|
}
|
|
209
326
|
}
|
|
210
327
|
|
|
211
|
-
// 4. Remove hooks from settings.json
|
|
328
|
+
// 4. Remove hooks and MCP server from settings.json
|
|
212
329
|
const settingsPath = join(home, ".claude", "settings.json");
|
|
213
330
|
if (existsSync(settingsPath)) {
|
|
214
331
|
try {
|
|
215
332
|
const settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
216
333
|
let changed = false;
|
|
217
|
-
|
|
334
|
+
|
|
335
|
+
// Remove all hook types
|
|
336
|
+
for (const hookType of ["PreToolUse", "PostToolUse", "SessionStart", "SessionEnd"]) {
|
|
218
337
|
if (Array.isArray(settings.hooks?.[hookType])) {
|
|
219
338
|
const before = settings.hooks[hookType].length;
|
|
220
339
|
settings.hooks[hookType] = settings.hooks[hookType].filter(
|
|
@@ -222,22 +341,44 @@ function uninstallAll() {
|
|
|
222
341
|
!(
|
|
223
342
|
Array.isArray(h.hooks) &&
|
|
224
343
|
h.hooks.some(
|
|
225
|
-
(hh) => hh.command && hh.command.includes("observe.sh")
|
|
344
|
+
(hh) => hh.command && (hh.command.includes("observe.sh") || hh.command.includes("session.sh"))
|
|
226
345
|
)
|
|
227
346
|
)
|
|
228
347
|
);
|
|
229
348
|
if (settings.hooks[hookType].length < before) changed = true;
|
|
230
349
|
}
|
|
231
350
|
}
|
|
351
|
+
|
|
352
|
+
// Remove MCP server
|
|
353
|
+
if (settings.mcpServers?.["continuous-improvement"]) {
|
|
354
|
+
delete settings.mcpServers["continuous-improvement"];
|
|
355
|
+
changed = true;
|
|
356
|
+
}
|
|
357
|
+
|
|
232
358
|
if (changed) {
|
|
233
359
|
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
234
|
-
console.log(` ✓ Removed hooks from settings.json`);
|
|
360
|
+
console.log(` ✓ Removed hooks and MCP server from settings.json`);
|
|
235
361
|
}
|
|
236
362
|
} catch {
|
|
237
363
|
console.warn(` ! Could not clean settings.json — remove hooks manually`);
|
|
238
364
|
}
|
|
239
365
|
}
|
|
240
366
|
|
|
367
|
+
// 5. Clean claude_desktop_config.json MCP entry
|
|
368
|
+
const desktopConfig = join(home, ".claude", "claude_desktop_config.json");
|
|
369
|
+
if (existsSync(desktopConfig)) {
|
|
370
|
+
try {
|
|
371
|
+
const config = JSON.parse(readFileSync(desktopConfig, "utf8"));
|
|
372
|
+
if (config.mcpServers?.["continuous-improvement"]) {
|
|
373
|
+
delete config.mcpServers["continuous-improvement"];
|
|
374
|
+
writeFileSync(desktopConfig, JSON.stringify(config, null, 2) + "\n");
|
|
375
|
+
console.log(` ✓ Removed MCP server from Claude Desktop config`);
|
|
376
|
+
}
|
|
377
|
+
} catch {
|
|
378
|
+
// skip
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
241
382
|
if (removed === 0) {
|
|
242
383
|
console.log(" No skill installations found.");
|
|
243
384
|
}
|
|
@@ -253,13 +394,30 @@ Usage: npx continuous-improvement install [options]
|
|
|
253
394
|
|
|
254
395
|
Options:
|
|
255
396
|
--target <name> Install to specific target (claude, openclaw, cursor, codex, all)
|
|
397
|
+
--mode <mode> Installation mode:
|
|
398
|
+
beginner — hooks only, no MCP server (default)
|
|
399
|
+
expert — hooks + MCP server + session hooks + all tools
|
|
400
|
+
mcp — MCP server only (works with any MCP client)
|
|
256
401
|
--uninstall Remove from all targets
|
|
257
402
|
--help Show this help
|
|
258
403
|
|
|
404
|
+
Modes explained:
|
|
405
|
+
BEGINNER (default) Just works. Hooks capture silently, instincts grow over time.
|
|
406
|
+
3 tools via /continuous-improvement command.
|
|
407
|
+
|
|
408
|
+
EXPERT Everything in beginner + MCP server with 8 tools:
|
|
409
|
+
import/export, manual instinct creation, observation viewer,
|
|
410
|
+
confidence tuning. Plus session start/end hooks.
|
|
411
|
+
|
|
412
|
+
MCP MCP server only — for editors that support MCP but not
|
|
413
|
+
Claude Code hooks (Cursor, Zed, Windsurf, VS Code).
|
|
414
|
+
|
|
259
415
|
Examples:
|
|
260
|
-
npx continuous-improvement install
|
|
261
|
-
npx continuous-improvement install --
|
|
262
|
-
npx continuous-improvement install --
|
|
416
|
+
npx continuous-improvement install # beginner (default)
|
|
417
|
+
npx continuous-improvement install --mode expert # full power
|
|
418
|
+
npx continuous-improvement install --mode mcp # MCP server only
|
|
419
|
+
npx continuous-improvement install --target all # install everywhere
|
|
420
|
+
npx continuous-improvement install --uninstall # remove all
|
|
263
421
|
`);
|
|
264
422
|
}
|
|
265
423
|
|
|
@@ -284,7 +442,7 @@ if (args.includes("--uninstall")) {
|
|
|
284
442
|
}
|
|
285
443
|
|
|
286
444
|
console.log(`
|
|
287
|
-
continuous-improvement
|
|
445
|
+
continuous-improvement v3.0 (mode: ${INSTALL_MODE})
|
|
288
446
|
Research → Plan → Execute → Verify → Reflect → Learn → Iterate
|
|
289
447
|
`);
|
|
290
448
|
|
|
@@ -321,11 +479,19 @@ for (const t of targets) {
|
|
|
321
479
|
|
|
322
480
|
const hasClaude = targets.includes("claude");
|
|
323
481
|
|
|
482
|
+
const modeInfo = {
|
|
483
|
+
beginner: "Hooks are capturing silently. System auto-levels as you use it.",
|
|
484
|
+
expert: "Full plugin active: hooks + MCP server + session hooks. 8 tools available.",
|
|
485
|
+
mcp: "MCP server registered. Connect from any MCP-compatible editor.",
|
|
486
|
+
};
|
|
487
|
+
|
|
324
488
|
console.log(`
|
|
325
489
|
${installed > 0 ? "Done." : "Failed."} Installed to ${installed}/${targets.length} target(s).
|
|
326
|
-
${hasClaude ?
|
|
490
|
+
${hasClaude ? `\n${modeInfo[INSTALL_MODE] || modeInfo.beginner}` : ""}
|
|
327
491
|
Next steps:
|
|
328
492
|
1. Start a new Claude Code session
|
|
329
493
|
2. Say: "Use the continuous-improvement framework to [your task]"
|
|
330
494
|
3. After your first task, run: /continuous-improvement
|
|
495
|
+
${INSTALL_MODE === "expert" ? "\nMCP tools available: ci_status, ci_instincts, ci_reflect, ci_reinforce,\n ci_create_instinct, ci_observations, ci_export, ci_import" : ""}
|
|
496
|
+
${INSTALL_MODE === "mcp" ? "\nMCP tools available: ci_status, ci_instincts, ci_reflect" : ""}
|
|
331
497
|
`);
|