continuous-improvement 3.1.0 → 3.8.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.
Files changed (126) hide show
  1. package/.claude-plugin/marketplace.json +78 -0
  2. package/CHANGELOG.md +191 -0
  3. package/LICENSE +21 -21
  4. package/QUICKSTART.md +101 -81
  5. package/README.md +207 -359
  6. package/SKILL.md +87 -9
  7. package/action.yml +33 -33
  8. package/bin/analyze.sh +161 -153
  9. package/bin/backfill.mjs +172 -0
  10. package/bin/check-docs-substrings.mjs +333 -0
  11. package/bin/check-everything-mirror.mjs +145 -0
  12. package/bin/check-routing-targets.mjs +151 -0
  13. package/bin/check-skill-law-tag.mjs +128 -0
  14. package/bin/check-skill-mirror.mjs +119 -0
  15. package/bin/check-skill-tiers.mjs +116 -0
  16. package/bin/check-third-party-shape.mjs +202 -0
  17. package/bin/generate-plugin-manifests.mjs +169 -0
  18. package/bin/harvest-friction.mjs +279 -0
  19. package/bin/hook-stats.mjs +258 -0
  20. package/bin/install.mjs +417 -516
  21. package/bin/lint-transcript.mjs +182 -210
  22. package/bin/mcp-server.mjs +840 -617
  23. package/bin/observe.mjs +148 -0
  24. package/bin/pre-commit-block-strays.sh +49 -0
  25. package/bin/refresh-third-party.mjs +416 -0
  26. package/bin/unified-cli.mjs +533 -0
  27. package/commands/continuous-improvement.md +115 -74
  28. package/commands/dashboard.md +56 -56
  29. package/commands/discipline.md +51 -37
  30. package/commands/harvest.md +76 -0
  31. package/commands/learn-eval.md +117 -0
  32. package/commands/planning-with-files.md +66 -0
  33. package/commands/proceed-with-the-recommendation.md +62 -0
  34. package/commands/ralph.md +103 -0
  35. package/commands/release-train.md +81 -0
  36. package/commands/seven-laws.md +16 -0
  37. package/commands/superpowers.md +153 -0
  38. package/commands/swarm.md +101 -0
  39. package/commands/workspace-surface-audit.md +77 -0
  40. package/hooks/observe.sh +172 -134
  41. package/hooks/session.sh +106 -106
  42. package/hooks/three-section-close.mjs +181 -0
  43. package/instinct-packs/go.json +58 -58
  44. package/instinct-packs/meta.json +16 -0
  45. package/instinct-packs/python.json +58 -58
  46. package/instinct-packs/react.json +58 -58
  47. package/lib/cli-anything.mjs +401 -0
  48. package/lib/compound-engineering.mjs +831 -0
  49. package/lib/observe-event.mjs +128 -0
  50. package/lib/plugin-metadata.mjs +432 -0
  51. package/lib/pm-marketplace.mjs +61 -0
  52. package/lib/pm-skills.mjs +1274 -0
  53. package/lib/resolve-home-dir.mjs +43 -0
  54. package/lib/skill-tiers.mjs +137 -0
  55. package/lib/unified-plugin.mjs +924 -0
  56. package/llms.txt +68 -43
  57. package/package.json +28 -19
  58. package/plugins/beginner.json +17 -6
  59. package/plugins/continuous-improvement/.claude-plugin/marketplace.json +20 -0
  60. package/plugins/continuous-improvement/.claude-plugin/plugin.json +26 -0
  61. package/plugins/continuous-improvement/LICENSE +21 -0
  62. package/plugins/continuous-improvement/README.md +56 -0
  63. package/plugins/continuous-improvement/bin/backfill.mjs +172 -0
  64. package/plugins/continuous-improvement/bin/mcp-server.mjs +886 -0
  65. package/plugins/continuous-improvement/bin/observe.mjs +148 -0
  66. package/plugins/continuous-improvement/commands/continuous-improvement.md +115 -0
  67. package/plugins/continuous-improvement/commands/dashboard.md +56 -0
  68. package/plugins/continuous-improvement/commands/discipline.md +51 -0
  69. package/plugins/continuous-improvement/commands/harvest.md +76 -0
  70. package/plugins/continuous-improvement/commands/learn-eval.md +117 -0
  71. package/plugins/continuous-improvement/commands/planning-with-files.md +66 -0
  72. package/plugins/continuous-improvement/commands/proceed-with-the-recommendation.md +62 -0
  73. package/plugins/continuous-improvement/commands/ralph.md +103 -0
  74. package/plugins/continuous-improvement/commands/release-train.md +81 -0
  75. package/plugins/continuous-improvement/commands/seven-laws.md +16 -0
  76. package/plugins/continuous-improvement/commands/superpowers.md +153 -0
  77. package/plugins/continuous-improvement/commands/swarm.md +101 -0
  78. package/plugins/continuous-improvement/commands/workspace-surface-audit.md +77 -0
  79. package/plugins/continuous-improvement/hooks/hooks.json +60 -0
  80. package/plugins/continuous-improvement/hooks/observe.sh +172 -0
  81. package/plugins/continuous-improvement/hooks/session.sh +106 -0
  82. package/plugins/continuous-improvement/hooks/three-section-close.mjs +181 -0
  83. package/plugins/continuous-improvement/instinct-packs/go.json +58 -0
  84. package/plugins/continuous-improvement/instinct-packs/meta.json +16 -0
  85. package/plugins/continuous-improvement/instinct-packs/python.json +58 -0
  86. package/plugins/continuous-improvement/instinct-packs/react.json +58 -0
  87. package/plugins/continuous-improvement/lib/observe-event.mjs +128 -0
  88. package/plugins/continuous-improvement/lib/plugin-metadata.mjs +432 -0
  89. package/plugins/continuous-improvement/lib/resolve-home-dir.mjs +43 -0
  90. package/plugins/continuous-improvement/skills/README.md +34 -0
  91. package/plugins/continuous-improvement/skills/continuous-improvement/SKILL.md +249 -0
  92. package/plugins/continuous-improvement/skills/deploy-receipt/SKILL.md +131 -0
  93. package/plugins/continuous-improvement/skills/gateguard/SKILL.md +155 -0
  94. package/plugins/continuous-improvement/skills/para-memory-files/SKILL.md +108 -0
  95. package/plugins/continuous-improvement/skills/proceed-with-the-recommendation/SKILL.md +454 -0
  96. package/plugins/continuous-improvement/skills/ralph/SKILL.md +221 -0
  97. package/plugins/continuous-improvement/skills/safety-guard/SKILL.md +76 -0
  98. package/plugins/continuous-improvement/skills/strategic-compact/SKILL.md +104 -0
  99. package/plugins/continuous-improvement/skills/superpowers/SKILL.md +212 -0
  100. package/plugins/continuous-improvement/skills/tdd-workflow/SKILL.md +411 -0
  101. package/plugins/continuous-improvement/skills/token-budget-advisor/SKILL.md +136 -0
  102. package/plugins/continuous-improvement/skills/verification-loop/SKILL.md +192 -0
  103. package/plugins/continuous-improvement/skills/wild-risa-balance/SKILL.md +191 -0
  104. package/plugins/continuous-improvement/skills/workspace-surface-audit/SKILL.md +147 -0
  105. package/plugins/continuous-improvement/templates/planning-with-files/findings.md +8 -0
  106. package/plugins/continuous-improvement/templates/planning-with-files/progress.md +7 -0
  107. package/plugins/continuous-improvement/templates/planning-with-files/task_plan.md +23 -0
  108. package/plugins/expert.json +26 -5
  109. package/skills/README.md +79 -0
  110. package/skills/deploy-receipt.md +131 -0
  111. package/skills/gateguard.md +155 -0
  112. package/skills/para-memory-files.md +108 -0
  113. package/skills/proceed-with-the-recommendation.md +454 -0
  114. package/skills/ralph.md +221 -0
  115. package/skills/safety-guard.md +76 -0
  116. package/skills/strategic-compact.md +104 -0
  117. package/skills/superpowers.md +212 -0
  118. package/skills/tdd-workflow.md +411 -0
  119. package/skills/token-budget-advisor.md +136 -0
  120. package/skills/verification-loop.md +192 -0
  121. package/skills/wild-risa-balance.md +191 -0
  122. package/skills/workspace-surface-audit.md +147 -0
  123. package/templates/planning-with-files/findings.md +8 -0
  124. package/templates/planning-with-files/progress.md +7 -0
  125. package/templates/planning-with-files/task_plan.md +23 -0
  126. package/templates/verify-ladder.example.json +47 -0
package/bin/install.mjs CHANGED
@@ -1,558 +1,459 @@
1
1
  #!/usr/bin/env node
2
-
3
2
  /**
4
- * continuous-improvement installer
3
+ * continuous-improvement installer (Claude Code)
5
4
  *
6
5
  * Usage:
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
6
+ * npx continuous-improvement install # beginner mode (default)
7
+ * npx continuous-improvement install --mode expert # + MCP server + session hooks
8
+ * npx continuous-improvement install --pack react # load starter instinct pack
9
+ * npx continuous-improvement install --uninstall # remove everything
16
10
  */
17
-
18
- import {
19
- existsSync,
20
- mkdirSync,
21
- copyFileSync,
22
- readFileSync,
23
- writeFileSync,
24
- rmSync,
25
- chmodSync,
26
- readdirSync,
27
- } from "node:fs";
28
- import { join, dirname } from "node:path";
11
+ import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync, } from "node:fs";
12
+ import { execSync } from "node:child_process";
29
13
  import { homedir } from "node:os";
14
+ import { dirname, join } from "node:path";
30
15
  import { fileURLToPath } from "node:url";
31
- import { execSync } from "node:child_process";
32
-
16
+ import { createHash } from "node:crypto";
33
17
  const __filename = fileURLToPath(import.meta.url);
34
18
  const __dirname = dirname(__filename);
35
19
  const SKILL_SOURCE = join(__dirname, "..", "SKILL.md");
36
20
  const SKILL_NAME = "continuous-improvement";
37
21
  const REPO_ROOT = join(__dirname, "..");
38
-
39
- // Parse --mode flag
40
- const _args = process.argv.slice(2);
41
- const _modeIdx = _args.indexOf("--mode");
42
- const INSTALL_MODE = _modeIdx !== -1 && _args[_modeIdx + 1] ? _args[_modeIdx + 1] : "beginner";
43
-
44
- const TARGETS = {
45
- claude: {
46
- label: "Claude Code",
47
- dir: join(homedir(), ".claude", "skills", SKILL_NAME),
48
- },
49
- openclaw: {
50
- label: "OpenClaw",
51
- dir: join(homedir(), ".openclaw", "skills", SKILL_NAME),
52
- },
53
- cursor: {
54
- label: "Cursor",
55
- dir: join(homedir(), ".cursor", "skills", SKILL_NAME),
56
- },
57
- codex: {
58
- label: "Codex",
59
- dir: join(homedir(), ".codex", "skills", SKILL_NAME),
60
- },
61
- };
62
-
63
- function detectTargets() {
64
- const detected = [];
65
- for (const [key, target] of Object.entries(TARGETS)) {
66
- const parentDir = dirname(target.dir);
67
- const configDir = dirname(parentDir);
68
- if (existsSync(configDir)) {
69
- detected.push(key);
70
- }
71
- }
72
- return detected;
22
+ const COMMAND_FILES = [
23
+ "continuous-improvement.md",
24
+ "planning-with-files.md",
25
+ "proceed-with-the-recommendation.md",
26
+ "discipline.md",
27
+ "dashboard.md",
28
+ "learn-eval.md",
29
+ ];
30
+ const HOOK_TYPES = ["PreToolUse", "PostToolUse"];
31
+ const SESSION_HOOK_TYPES = ["SessionStart", "SessionEnd"];
32
+ function getHomeDir() {
33
+ return process.env.HOME || process.env.USERPROFILE || homedir();
73
34
  }
74
-
75
- function installTo(key) {
76
- const target = TARGETS[key];
77
- if (!target) {
78
- console.error(` Unknown target: ${key}`);
79
- return false;
80
- }
81
-
82
- try {
83
- // MCP-only mode: skip skill file copy, just register MCP server
84
- if (INSTALL_MODE === "mcp") {
85
- if (key === "claude") {
35
+ function isInstallMode(value) {
36
+ return value === "beginner" || value === "expert";
37
+ }
38
+ function getErrorMessage(error) {
39
+ return error instanceof Error ? error.message : String(error);
40
+ }
41
+ function readJsonFile(filePath) {
42
+ try {
43
+ return JSON.parse(readFileSync(filePath, "utf8"));
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ }
49
+ const rawArgs = process.argv.slice(2);
50
+ const modeIndex = rawArgs.indexOf("--mode");
51
+ const requestedMode = modeIndex !== -1 ? rawArgs[modeIndex + 1] : undefined;
52
+ const INSTALL_MODE = isInstallMode(requestedMode) ? requestedMode : "beginner";
53
+ const SKILL_DIR = join(getHomeDir(), ".claude", "skills", SKILL_NAME);
54
+ function installSkill() {
55
+ try {
56
+ mkdirSync(SKILL_DIR, { recursive: true });
57
+ copyFileSync(SKILL_SOURCE, join(SKILL_DIR, "SKILL.md"));
58
+ console.log(` ✓ Claude Code skill → ${SKILL_DIR}/SKILL.md`);
86
59
  setupMulahazah();
87
- console.log(` ✓ ${target.label} → MCP server only`);
88
- } else {
89
- console.log(` ⊘ ${target.label} — MCP mode only applies to Claude Code`);
90
- }
91
- return true;
92
- }
93
-
94
- mkdirSync(target.dir, { recursive: true });
95
- copyFileSync(SKILL_SOURCE, join(target.dir, "SKILL.md"));
96
- console.log(` ✓ ${target.label} → ${target.dir}/SKILL.md`);
97
-
98
- if (key === "claude") {
99
- setupMulahazah();
100
- }
101
-
102
- return true;
103
- } catch (err) {
104
- console.error(` ✗ ${target.label}: ${err.message}`);
105
- return false;
106
- }
60
+ return true;
61
+ }
62
+ catch (error) {
63
+ console.error(` ✗ Install failed: ${getErrorMessage(error)}`);
64
+ return false;
65
+ }
107
66
  }
108
-
109
67
  function setupMulahazah() {
110
- const home = homedir();
111
- const instinctsDir = join(home, ".claude", "instincts");
112
- const globalDir = join(instinctsDir, "global");
113
-
114
- // 1. Create directory structure
115
- mkdirSync(globalDir, { recursive: true });
116
- console.log(` ✓ Instincts dir ${instinctsDir}/`);
117
-
118
- // 2. Copy observe.sh and make executable
119
- const observeSrc = join(REPO_ROOT, "hooks", "observe.sh");
120
- const observeDest = join(instinctsDir, "observe.sh");
121
- if (existsSync(observeSrc)) {
122
- copyFileSync(observeSrc, observeDest);
123
- chmodSync(observeDest, 0o755);
124
- console.log(` ✓ observe.sh ${observeDest}`);
125
- }
126
-
127
- // 3. Copy session.sh for expert mode
128
- if (INSTALL_MODE === "expert") {
129
- const sessionSrc = join(REPO_ROOT, "hooks", "session.sh");
130
- const sessionDest = join(instinctsDir, "session.sh");
131
- if (existsSync(sessionSrc)) {
132
- copyFileSync(sessionSrc, sessionDest);
133
- chmodSync(sessionDest, 0o755);
134
- console.log(` ✓ session.sh → ${sessionDest}`);
135
- }
136
- }
137
-
138
- // 4. Copy all commands
139
- const commandsDir = join(home, ".claude", "commands");
140
- mkdirSync(commandsDir, { recursive: true });
141
- const commandFiles = ["continuous-improvement.md", "discipline.md", "dashboard.md"];
142
- for (const cmdFile of commandFiles) {
143
- const cmdSrc = join(REPO_ROOT, "commands", cmdFile);
144
- const cmdDest = join(commandsDir, cmdFile);
145
- if (existsSync(cmdSrc)) {
146
- copyFileSync(cmdSrc, cmdDest);
147
- console.log(` ✓ /${cmdFile.replace(".md", "")} command → ${cmdDest}`);
148
- }
149
- }
150
-
151
- // 5. Patch ~/.claude/settings.json with hooks
152
- patchClaudeSettings(observeDest);
153
-
154
- // 6. Setup MCP server for expert or mcp mode
155
- if (INSTALL_MODE === "expert" || INSTALL_MODE === "mcp") {
156
- setupMcpServer();
157
- }
68
+ const home = getHomeDir();
69
+ const instinctsDir = join(home, ".claude", "instincts");
70
+ const globalDir = join(instinctsDir, "global");
71
+ mkdirSync(globalDir, { recursive: true });
72
+ console.log(` Instincts dir ${instinctsDir}/`);
73
+ const observeSrc = join(REPO_ROOT, "hooks", "observe.sh");
74
+ const observeDest = join(instinctsDir, "observe.sh");
75
+ if (existsSync(observeSrc)) {
76
+ copyFileSync(observeSrc, observeDest);
77
+ chmodSync(observeDest, 0o755);
78
+ console.log(` observe.sh → ${observeDest}`);
79
+ }
80
+ // Node observer (Phase 1 of the two-phase hook). The bash shim above
81
+ // exec's this when `node` and the file are both present; otherwise it
82
+ // falls back to the in-bash thin-schema path. Layout under instinctsDir
83
+ // mirrors the repo's bin/ + lib/ structure so the relative import in
84
+ // observe.mjs (`../lib/observe-event.mjs`) resolves correctly.
85
+ const observerJsSrc = join(REPO_ROOT, "bin", "observe.mjs");
86
+ const observeEventSrc = join(REPO_ROOT, "lib", "observe-event.mjs");
87
+ if (existsSync(observerJsSrc) && existsSync(observeEventSrc)) {
88
+ const binDir = join(instinctsDir, "bin");
89
+ const libDir = join(instinctsDir, "lib");
90
+ mkdirSync(binDir, { recursive: true });
91
+ mkdirSync(libDir, { recursive: true });
92
+ const observerJsDest = join(binDir, "observe.mjs");
93
+ const observeEventDest = join(libDir, "observe-event.mjs");
94
+ copyFileSync(observerJsSrc, observerJsDest);
95
+ copyFileSync(observeEventSrc, observeEventDest);
96
+ console.log(` Node observer ${observerJsDest}`);
97
+ }
98
+ if (INSTALL_MODE === "expert") {
99
+ const sessionSrc = join(REPO_ROOT, "hooks", "session.sh");
100
+ const sessionDest = join(instinctsDir, "session.sh");
101
+ if (existsSync(sessionSrc)) {
102
+ copyFileSync(sessionSrc, sessionDest);
103
+ chmodSync(sessionDest, 0o755);
104
+ console.log(` ✓ session.sh → ${sessionDest}`);
105
+ }
106
+ }
107
+ const commandsDir = join(home, ".claude", "commands");
108
+ mkdirSync(commandsDir, { recursive: true });
109
+ for (const commandFile of COMMAND_FILES) {
110
+ const commandSource = join(REPO_ROOT, "commands", commandFile);
111
+ const commandDest = join(commandsDir, commandFile);
112
+ if (existsSync(commandSource)) {
113
+ copyFileSync(commandSource, commandDest);
114
+ console.log(` ✓ /${commandFile.replace(".md", "")} command → ${commandDest}`);
115
+ }
116
+ }
117
+ patchClaudeSettings(observeDest);
118
+ if (INSTALL_MODE === "expert") {
119
+ setupMcpServer();
120
+ }
158
121
  }
159
-
160
122
  function setupMcpServer() {
161
- const home = homedir();
162
- const mcpServerPath = join(REPO_ROOT, "bin", "mcp-server.mjs");
163
- const mcpMode = INSTALL_MODE === "mcp" ? "beginner" : "expert";
164
-
165
- // Patch Claude Code settings.json with MCP server config
166
- const settingsPath = join(home, ".claude", "settings.json");
167
- let settings = {};
168
- if (existsSync(settingsPath)) {
169
- try {
170
- settings = JSON.parse(readFileSync(settingsPath, "utf8"));
171
- } catch {
172
- console.warn(` ! Could not parse settings.json — skipping MCP setup`);
173
- return;
174
- }
175
- }
176
-
177
- if (!settings.mcpServers) settings.mcpServers = {};
178
-
179
- const alreadySetup = settings.mcpServers["continuous-improvement"];
180
- if (!alreadySetup) {
181
- settings.mcpServers["continuous-improvement"] = {
182
- command: "node",
183
- args: [mcpServerPath, "--mode", mcpMode],
184
- };
185
- writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
186
- console.log(` ✓ MCP server registered (mode: ${mcpMode})`);
187
- } else {
188
- console.log(` ✓ MCP server already registered — no change`);
189
- }
190
-
191
- // Also write claude_desktop_config.json if it exists
192
- const desktopConfig = join(home, ".claude", "claude_desktop_config.json");
193
- if (existsSync(desktopConfig)) {
194
- try {
195
- const config = JSON.parse(readFileSync(desktopConfig, "utf8"));
196
- if (!config.mcpServers) config.mcpServers = {};
197
- if (!config.mcpServers["continuous-improvement"]) {
198
- config.mcpServers["continuous-improvement"] = {
199
- command: "node",
200
- args: [mcpServerPath, "--mode", mcpMode],
123
+ const home = getHomeDir();
124
+ const mcpServerPath = join(REPO_ROOT, "bin", "mcp-server.mjs");
125
+ const settingsPath = join(home, ".claude", "settings.json");
126
+ const settings = existsSync(settingsPath) ? readJsonFile(settingsPath) : {};
127
+ if (settings === null) {
128
+ console.warn(" ! Could not parse settings.json — skipping MCP setup");
129
+ return;
130
+ }
131
+ if (!settings.mcpServers) {
132
+ settings.mcpServers = {};
133
+ }
134
+ if (!settings.mcpServers["continuous-improvement"]) {
135
+ settings.mcpServers["continuous-improvement"] = {
136
+ command: "node",
137
+ args: [mcpServerPath, "--mode", "expert"],
138
+ };
139
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
140
+ console.log(" ✓ MCP server registered (mode: expert)");
141
+ }
142
+ else {
143
+ console.log(" MCP server already registered — no change");
144
+ }
145
+ const desktopConfigPath = join(home, ".claude", "claude_desktop_config.json");
146
+ if (!existsSync(desktopConfigPath)) {
147
+ return;
148
+ }
149
+ const desktopConfig = readJsonFile(desktopConfigPath);
150
+ if (!desktopConfig) {
151
+ return;
152
+ }
153
+ if (!desktopConfig.mcpServers) {
154
+ desktopConfig.mcpServers = {};
155
+ }
156
+ if (!desktopConfig.mcpServers["continuous-improvement"]) {
157
+ desktopConfig.mcpServers["continuous-improvement"] = {
158
+ command: "node",
159
+ args: [mcpServerPath, "--mode", "expert"],
201
160
  };
202
- writeFileSync(desktopConfig, JSON.stringify(config, null, 2) + "\n");
203
- console.log(` ✓ Claude Desktop MCP config updated`);
204
- }
205
- } catch {
206
- // skip
161
+ writeFileSync(desktopConfigPath, JSON.stringify(desktopConfig, null, 2) + "\n");
162
+ console.log(" ✓ Claude Desktop MCP config updated");
207
163
  }
208
- }
209
164
  }
210
-
165
+ function hookAlreadyPatched(entries, scriptName) {
166
+ return entries.some((entry) => Array.isArray(entry.hooks) &&
167
+ entry.hooks.some((hook) => hook.command.includes(scriptName)));
168
+ }
211
169
  function patchClaudeSettings(observePath) {
212
- const settingsPath = join(homedir(), ".claude", "settings.json");
213
-
214
- let settings = {};
215
- if (existsSync(settingsPath)) {
216
- try {
217
- settings = JSON.parse(readFileSync(settingsPath, "utf8"));
218
- } catch {
219
- console.warn(` ! Could not parse ${settingsPath} — skipping hook patch`);
220
- return;
221
- }
222
- }
223
-
224
- if (!settings.hooks) settings.hooks = {};
225
-
226
- const hookEntry = {
227
- matcher: "",
228
- hooks: [
229
- {
230
- type: "command",
231
- command: `bash "${observePath}"`,
232
- },
233
- ],
234
- };
235
-
236
- let changed = false;
237
-
238
- for (const hookType of ["PreToolUse", "PostToolUse"]) {
239
- if (!Array.isArray(settings.hooks[hookType])) {
240
- settings.hooks[hookType] = [];
241
- }
242
- const alreadyPatched = settings.hooks[hookType].some(
243
- (h) =>
244
- Array.isArray(h.hooks) &&
245
- h.hooks.some((hh) => hh.command && hh.command.includes("observe.sh"))
246
- );
247
- if (!alreadyPatched) {
248
- settings.hooks[hookType].push(hookEntry);
249
- changed = true;
250
- }
251
- }
252
-
253
- // Expert mode: add session hooks
254
- if (INSTALL_MODE === "expert") {
255
- const sessionPath = join(homedir(), ".claude", "instincts", "session.sh");
256
- const sessionHook = {
257
- matcher: "",
258
- hooks: [{ type: "command", command: `bash "${sessionPath}"` }],
170
+ const settingsPath = join(getHomeDir(), ".claude", "settings.json");
171
+ const settings = existsSync(settingsPath) ? readJsonFile(settingsPath) : {};
172
+ if (settings === null) {
173
+ console.warn(` ! Could not parse ${settingsPath} — skipping hook patch`);
174
+ return;
175
+ }
176
+ if (!settings.hooks) {
177
+ settings.hooks = {};
178
+ }
179
+ const hookEntry = {
180
+ matcher: "",
181
+ hooks: [
182
+ {
183
+ type: "command",
184
+ command: `bash "${observePath}"`,
185
+ },
186
+ ],
259
187
  };
260
-
261
- // Note: SessionStart/SessionEnd hooks may not be supported in all versions.
262
- // We register them — they'll be silently ignored if unsupported.
263
- for (const hookType of ["SessionStart", "SessionEnd"]) {
264
- if (!Array.isArray(settings.hooks[hookType])) {
265
- settings.hooks[hookType] = [];
266
- }
267
- const alreadyPatched = settings.hooks[hookType].some(
268
- (h) =>
269
- Array.isArray(h.hooks) &&
270
- h.hooks.some((hh) => hh.command && hh.command.includes("session.sh"))
271
- );
272
- if (!alreadyPatched) {
273
- settings.hooks[hookType].push(sessionHook);
274
- changed = true;
275
- }
276
- }
277
- }
278
-
279
- if (changed) {
280
- writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
281
- const hookTypes = INSTALL_MODE === "expert"
282
- ? "PreToolUse/PostToolUse/SessionStart/SessionEnd"
283
- : "PreToolUse/PostToolUse";
284
- console.log(` ✓ Patched ~/.claude/settings.json with ${hookTypes} hooks`);
285
- } else {
286
- console.log(` ✓ settings.json already has hooks — no change needed`);
287
- }
188
+ let changed = false;
189
+ for (const hookType of HOOK_TYPES) {
190
+ if (!Array.isArray(settings.hooks[hookType])) {
191
+ settings.hooks[hookType] = [];
192
+ }
193
+ const hookEntries = settings.hooks[hookType];
194
+ if (!hookAlreadyPatched(hookEntries, "observe.sh")) {
195
+ hookEntries.push(hookEntry);
196
+ changed = true;
197
+ }
198
+ }
199
+ if (INSTALL_MODE === "expert") {
200
+ const sessionPath = join(getHomeDir(), ".claude", "instincts", "session.sh");
201
+ const sessionHook = {
202
+ matcher: "",
203
+ hooks: [{ type: "command", command: `bash "${sessionPath}"` }],
204
+ };
205
+ for (const hookType of SESSION_HOOK_TYPES) {
206
+ if (!Array.isArray(settings.hooks[hookType])) {
207
+ settings.hooks[hookType] = [];
208
+ }
209
+ const hookEntries = settings.hooks[hookType];
210
+ if (!hookAlreadyPatched(hookEntries, "session.sh")) {
211
+ hookEntries.push(sessionHook);
212
+ changed = true;
213
+ }
214
+ }
215
+ }
216
+ if (changed) {
217
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
218
+ const hookTypes = INSTALL_MODE === "expert"
219
+ ? "PreToolUse/PostToolUse/SessionStart/SessionEnd"
220
+ : "PreToolUse/PostToolUse";
221
+ console.log(` ✓ Patched ~/.claude/settings.json with ${hookTypes} hooks`);
222
+ }
223
+ else {
224
+ console.log(" ✓ settings.json already has hooks — no change needed");
225
+ }
288
226
  }
289
-
290
227
  function uninstallAll() {
291
- console.log("\nUninstalling continuous-improvement skill...\n");
292
- const home = homedir();
293
- let removed = 0;
294
-
295
- // 1. Remove skill files from all targets
296
- for (const [key, target] of Object.entries(TARGETS)) {
297
- const skillFile = join(target.dir, "SKILL.md");
298
- if (existsSync(skillFile)) {
299
- try {
300
- rmSync(target.dir, { recursive: true });
301
- console.log(` ✓ Removed skill from ${target.label}`);
302
- removed++;
303
- } catch (err) {
304
- console.error(` ✗ ${target.label}: ${err.message}`);
305
- }
306
- }
307
- }
308
-
309
- // 2. Remove all commands
310
- for (const cmdName of ["continuous-improvement.md", "discipline.md", "dashboard.md"]) {
311
- const cmdFile = join(home, ".claude", "commands", cmdName);
312
- if (existsSync(cmdFile)) {
313
- try {
314
- rmSync(cmdFile);
315
- console.log(` ✓ Removed /${cmdName.replace(".md", "")} command`);
316
- } catch (err) {
317
- console.error(` ✗ ${cmdName}: ${err.message}`);
318
- }
319
- }
320
- }
321
-
322
- // 3. Remove observe.sh and session.sh from instincts dir
323
- for (const hookFile of ["observe.sh", "session.sh"]) {
324
- const filePath = join(home, ".claude", "instincts", hookFile);
325
- if (existsSync(filePath)) {
326
- try {
327
- rmSync(filePath);
328
- console.log(` ✓ Removed ${hookFile}`);
329
- } catch (err) {
330
- console.error(` ✗ ${hookFile}: ${err.message}`);
331
- }
332
- }
333
- }
334
-
335
- // 4. Remove hooks and MCP server from settings.json
336
- const settingsPath = join(home, ".claude", "settings.json");
337
- if (existsSync(settingsPath)) {
338
- try {
339
- const settings = JSON.parse(readFileSync(settingsPath, "utf8"));
340
- let changed = false;
341
-
342
- // Remove all hook types
343
- for (const hookType of ["PreToolUse", "PostToolUse", "SessionStart", "SessionEnd"]) {
344
- if (Array.isArray(settings.hooks?.[hookType])) {
345
- const before = settings.hooks[hookType].length;
346
- settings.hooks[hookType] = settings.hooks[hookType].filter(
347
- (h) =>
348
- !(
349
- Array.isArray(h.hooks) &&
350
- h.hooks.some(
351
- (hh) => hh.command && (hh.command.includes("observe.sh") || hh.command.includes("session.sh"))
352
- )
353
- )
354
- );
355
- if (settings.hooks[hookType].length < before) changed = true;
228
+ console.log("\nUninstalling continuous-improvement skill...\n");
229
+ const home = getHomeDir();
230
+ let removed = 0;
231
+ if (existsSync(SKILL_DIR)) {
232
+ try {
233
+ rmSync(SKILL_DIR, { recursive: true });
234
+ console.log(" ✓ Removed Claude Code skill");
235
+ removed++;
356
236
  }
357
- }
358
-
359
- // Remove MCP server
360
- if (settings.mcpServers?.["continuous-improvement"]) {
361
- delete settings.mcpServers["continuous-improvement"];
362
- changed = true;
363
- }
364
-
365
- if (changed) {
366
- writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
367
- console.log(` ✓ Removed hooks and MCP server from settings.json`);
368
- }
369
- } catch {
370
- console.warn(` ! Could not clean settings.json — remove hooks manually`);
371
- }
372
- }
373
-
374
- // 5. Clean claude_desktop_config.json MCP entry
375
- const desktopConfig = join(home, ".claude", "claude_desktop_config.json");
376
- if (existsSync(desktopConfig)) {
377
- try {
378
- const config = JSON.parse(readFileSync(desktopConfig, "utf8"));
379
- if (config.mcpServers?.["continuous-improvement"]) {
380
- delete config.mcpServers["continuous-improvement"];
381
- writeFileSync(desktopConfig, JSON.stringify(config, null, 2) + "\n");
382
- console.log(` ✓ Removed MCP server from Claude Desktop config`);
383
- }
384
- } catch {
385
- // skip
386
- }
387
- }
388
-
389
- if (removed === 0) {
390
- console.log(" No skill installations found.");
391
- }
392
- console.log(
393
- "\n Note: Instinct data in ~/.claude/instincts/ was preserved.\n" +
394
- " To remove learned data too: rm -rf ~/.claude/instincts/\n"
395
- );
237
+ catch (error) {
238
+ console.error(` ✗ Skill removal failed: ${getErrorMessage(error)}`);
239
+ }
240
+ }
241
+ for (const commandName of COMMAND_FILES) {
242
+ const commandFile = join(home, ".claude", "commands", commandName);
243
+ if (!existsSync(commandFile)) {
244
+ continue;
245
+ }
246
+ try {
247
+ rmSync(commandFile);
248
+ console.log(` ✓ Removed /${commandName.replace(".md", "")} command`);
249
+ }
250
+ catch (error) {
251
+ console.error(` ✗ ${commandName}: ${getErrorMessage(error)}`);
252
+ }
253
+ }
254
+ for (const hookFile of ["observe.sh", "session.sh"]) {
255
+ const filePath = join(home, ".claude", "instincts", hookFile);
256
+ if (!existsSync(filePath)) {
257
+ continue;
258
+ }
259
+ try {
260
+ rmSync(filePath);
261
+ console.log(` ✓ Removed ${hookFile}`);
262
+ }
263
+ catch (error) {
264
+ console.error(` ✗ ${hookFile}: ${getErrorMessage(error)}`);
265
+ }
266
+ }
267
+ // Remove the Node observer artifacts deployed alongside observe.sh.
268
+ for (const observerFile of [
269
+ join("bin", "observe.mjs"),
270
+ join("lib", "observe-event.mjs"),
271
+ ]) {
272
+ const filePath = join(home, ".claude", "instincts", observerFile);
273
+ if (!existsSync(filePath))
274
+ continue;
275
+ try {
276
+ rmSync(filePath);
277
+ console.log(` ✓ Removed ${observerFile}`);
278
+ }
279
+ catch (error) {
280
+ console.error(` ✗ ${observerFile}: ${getErrorMessage(error)}`);
281
+ }
282
+ }
283
+ const settingsPath = join(home, ".claude", "settings.json");
284
+ if (existsSync(settingsPath)) {
285
+ const settings = readJsonFile(settingsPath);
286
+ if (settings) {
287
+ let changed = false;
288
+ for (const hookType of [...HOOK_TYPES, ...SESSION_HOOK_TYPES]) {
289
+ const hookEntries = settings.hooks?.[hookType];
290
+ if (!Array.isArray(hookEntries)) {
291
+ continue;
292
+ }
293
+ const nextEntries = hookEntries.filter((entry) => !entry.hooks.some((hook) => hook.command.includes("observe.sh") || hook.command.includes("session.sh")));
294
+ if (nextEntries.length !== hookEntries.length) {
295
+ changed = true;
296
+ }
297
+ settings.hooks[hookType] = nextEntries;
298
+ }
299
+ if (settings.mcpServers?.["continuous-improvement"]) {
300
+ delete settings.mcpServers["continuous-improvement"];
301
+ changed = true;
302
+ }
303
+ if (changed) {
304
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
305
+ console.log(" ✓ Removed hooks and MCP server from settings.json");
306
+ }
307
+ }
308
+ else {
309
+ console.warn(" ! Could not clean settings.json — remove hooks manually");
310
+ }
311
+ }
312
+ const desktopConfigPath = join(home, ".claude", "claude_desktop_config.json");
313
+ if (existsSync(desktopConfigPath)) {
314
+ const desktopConfig = readJsonFile(desktopConfigPath);
315
+ if (desktopConfig?.mcpServers?.["continuous-improvement"]) {
316
+ delete desktopConfig.mcpServers["continuous-improvement"];
317
+ writeFileSync(desktopConfigPath, JSON.stringify(desktopConfig, null, 2) + "\n");
318
+ console.log(" ✓ Removed MCP server from Claude Desktop config");
319
+ }
320
+ }
321
+ if (removed === 0) {
322
+ console.log(" No skill installations found.");
323
+ }
324
+ console.log("\n Note: Instinct data in ~/.claude/instincts/ was preserved.\n" +
325
+ " To remove learned data too: rm -rf ~/.claude/instincts/\n");
396
326
  }
397
-
398
327
  function printUsage() {
399
- console.log(`
400
- Usage: npx continuous-improvement install [options]
401
-
402
- Options:
403
- --target <name> Install to specific target (claude, openclaw, cursor, codex, all)
404
- --mode <mode> Installation mode:
405
- beginner hooks only, no MCP server (default)
406
- expert — hooks + MCP server + session hooks + all tools
407
- mcp — MCP server only (works with any MCP client)
408
- --uninstall Remove from all targets
409
- --help Show this help
410
-
411
- Modes explained:
412
- BEGINNER (default) Just works. Hooks capture silently, instincts grow over time.
413
- 3 tools via /continuous-improvement command.
414
-
415
- EXPERT Everything in beginner + MCP server with 8 tools:
416
- import/export, manual instinct creation, observation viewer,
417
- confidence tuning. Plus session start/end hooks.
418
-
419
- MCP MCP server only for editors that support MCP but not
420
- Claude Code hooks (Cursor, Zed, Windsurf, VS Code).
421
-
422
- Examples:
423
- npx continuous-improvement install # beginner (default)
424
- npx continuous-improvement install --mode expert # full power
425
- npx continuous-improvement install --mode mcp # MCP server only
426
- npx continuous-improvement install --target all # install everywhere
427
- npx continuous-improvement install --uninstall # remove all
328
+ console.log(`
329
+ Usage: npx continuous-improvement <subcommand> [options]
330
+
331
+ Subcommands:
332
+ install Install the plugin (default subcommand)
333
+ backfill Tag legacy thin-schema rows in observations.jsonl files
334
+ --uninstall Remove all installed files
335
+
336
+ Options for 'install':
337
+ --mode <mode> Installation mode:
338
+ beginner hooks + skill + commands (default)
339
+ expert — beginner + MCP server + session hooks
340
+ --pack <name> Load a starter instinct pack (react, python, go, meta)
341
+ --help Show this help
342
+
343
+ Options for 'backfill':
344
+ --dry-run Report counts only, no file writes
345
+ --help Show backfill-specific help
346
+
347
+ Examples:
348
+ npx continuous-improvement install # beginner (default)
349
+ npx continuous-improvement install --mode expert # full power
350
+ npx continuous-improvement install --pack react # load React instincts
351
+ npx continuous-improvement backfill --dry-run # report thin/rich row counts
352
+ npx continuous-improvement backfill # tag rows in place
353
+ npx continuous-improvement install --uninstall # remove everything
428
354
  `);
429
355
  }
430
-
431
- // --- Main ---
432
-
356
+ function getProjectHashSync() {
357
+ try {
358
+ const root = execSync("git rev-parse --show-toplevel 2>/dev/null", { encoding: "utf8" }).trim();
359
+ const hash = createHash("sha256").update(root).digest("hex").slice(0, 12);
360
+ return { root, hash };
361
+ }
362
+ catch {
363
+ return { root: "global", hash: "global" };
364
+ }
365
+ }
433
366
  const args = process.argv.slice(2);
434
367
  const command = args[0];
435
-
368
+ const validCommands = new Set(["install", "backfill", "--help", "-h", "--uninstall"]);
436
369
  if (args.includes("--help") || args.includes("-h")) {
437
- printUsage();
438
- process.exit(0);
370
+ printUsage();
371
+ process.exit(0);
372
+ }
373
+ if (!command || !validCommands.has(command)) {
374
+ printUsage();
375
+ process.exit(command ? 1 : 0);
439
376
  }
440
-
441
- if (!command || !["install", "--help", "-h", "--uninstall"].includes(command)) {
442
- printUsage();
443
- process.exit(command ? 1 : 0);
377
+ if (command === "backfill") {
378
+ // Delegate to bin/backfill.mjs without spawning a separate process so the
379
+ // user gets one binary surface. Forward the remaining args (e.g. --dry-run).
380
+ const { execFileSync } = await import("node:child_process");
381
+ const backfillBin = join(REPO_ROOT, "bin", "backfill.mjs");
382
+ try {
383
+ execFileSync("node", [backfillBin, ...args.slice(1)], { stdio: "inherit" });
384
+ }
385
+ catch {
386
+ // backfill.mjs always exits 0; if execFileSync threw, propagate the exit
387
+ // status without a stack trace so operator output stays clean.
388
+ }
389
+ process.exit(0);
444
390
  }
445
-
446
391
  if (args.includes("--uninstall")) {
447
- uninstallAll();
448
- process.exit(0);
392
+ uninstallAll();
393
+ process.exit(0);
449
394
  }
450
-
451
- console.log(`
452
- continuous-improvement v3.1 (mode: ${INSTALL_MODE})
453
- Research → Plan → Execute → Verify → Reflect → Learn → Iterate
395
+ console.log(`
396
+ continuous-improvement (mode: ${INSTALL_MODE})
397
+ Research Plan → Execute → Verify → Reflect → Learn → Iterate
454
398
  `);
455
-
456
- const targetIdx = args.indexOf("--target");
457
- let targets;
458
-
459
- if (targetIdx !== -1 && args[targetIdx + 1]) {
460
- const requested = args[targetIdx + 1].toLowerCase();
461
- if (requested === "all") {
462
- targets = Object.keys(TARGETS);
463
- } else if (TARGETS[requested]) {
464
- targets = [requested];
465
- } else {
466
- console.error(`Unknown target: ${requested}`);
467
- console.error(`Available: ${Object.keys(TARGETS).join(", ")}, all`);
468
- process.exit(1);
469
- }
470
- } else {
471
- targets = detectTargets();
472
- if (targets.length === 0) {
473
- console.log("No supported agent configs detected. Installing to Claude Code by default.\n");
474
- targets = ["claude"];
475
- } else {
476
- console.log(`Detected: ${targets.map((t) => TARGETS[t].label).join(", ")}\n`);
477
- }
478
- }
479
-
480
- console.log("Installing...\n");
481
-
482
- let installed = 0;
483
- for (const t of targets) {
484
- if (installTo(t)) installed++;
485
- }
486
-
487
- const hasClaude = targets.includes("claude");
488
-
399
+ console.log("Installing to Claude Code...\n");
400
+ const installed = installSkill() ? 1 : 0;
489
401
  const modeInfo = {
490
- beginner: "Hooks are capturing silently. System auto-levels as you use it.",
491
- expert: "Full plugin active: hooks + MCP server + session hooks. 8 tools available.",
492
- mcp: "MCP server registered. Connect from any MCP-compatible editor.",
402
+ beginner: "Hooks are capturing silently. System auto-levels as you use it.",
403
+ expert: "Full plugin active: hooks + MCP server + session hooks. 12 tools available.",
493
404
  };
494
-
495
- // Handle --pack flag
496
- const packIdx = _args.indexOf("--pack");
497
- if (packIdx !== -1 && _args[packIdx + 1]) {
498
- const packName = _args[packIdx + 1];
499
- const packPath = join(REPO_ROOT, "instinct-packs", `${packName}.json`);
500
- if (existsSync(packPath)) {
501
- const project = getProjectHashSync();
502
- const targetDir = join(homedir(), ".claude", "instincts", project.hash);
503
- mkdirSync(targetDir, { recursive: true });
504
-
505
- const instincts = JSON.parse(readFileSync(packPath, "utf8"));
506
- let loaded = 0;
507
- for (const inst of instincts) {
508
- const instPath = join(targetDir, `${inst.id}.yaml`);
509
- if (!existsSync(instPath)) {
510
- const yaml = [
511
- `id: ${inst.id}`,
512
- `trigger: "${inst.trigger}"`,
513
- `confidence: ${inst.confidence}`,
514
- `domain: ${inst.domain || "workflow"}`,
515
- `source: pack-${packName}`,
516
- `scope: project`,
517
- `project_id: ${project.hash}`,
518
- `created: "${new Date().toISOString().split("T")[0]}"`,
519
- `last_seen: "${new Date().toISOString().split("T")[0]}"`,
520
- `observation_count: 0`,
521
- "---",
522
- inst.body,
523
- ].join("\n");
524
- writeFileSync(instPath, yaml + "\n");
525
- loaded++;
526
- }
527
- }
528
- console.log(` ✓ Loaded ${loaded}/${instincts.length} instincts from ${packName} pack`);
529
- } else {
530
- const available = readdirSync(join(REPO_ROOT, "instinct-packs"))
531
- .filter((f) => f.endsWith(".json"))
532
- .map((f) => f.replace(".json", ""));
533
- console.error(` ✗ Unknown pack: ${packName}. Available: ${available.join(", ")}`);
534
- }
535
- }
536
-
537
- function getProjectHashSync() {
538
- try {
539
- const root = execSync("git rev-parse --show-toplevel 2>/dev/null", { encoding: "utf8" }).trim();
540
- const hash = execSync(`printf '%s' "${root}" | sha256sum | cut -c1-12`, { encoding: "utf8", shell: "/bin/bash" }).trim();
541
- return { root, hash };
542
- } catch {
543
- return { root: "global", hash: "global" };
544
- }
405
+ const packIndex = rawArgs.indexOf("--pack");
406
+ if (packIndex !== -1 && rawArgs[packIndex + 1]) {
407
+ const packName = rawArgs[packIndex + 1];
408
+ const packPath = join(REPO_ROOT, "instinct-packs", `${packName}.json`);
409
+ if (existsSync(packPath)) {
410
+ const project = getProjectHashSync();
411
+ const targetDir = join(getHomeDir(), ".claude", "instincts", project.hash);
412
+ mkdirSync(targetDir, { recursive: true });
413
+ const instincts = JSON.parse(readFileSync(packPath, "utf8"));
414
+ let loaded = 0;
415
+ for (const instinct of instincts) {
416
+ const instinctPath = join(targetDir, `${instinct.id}.yaml`);
417
+ if (existsSync(instinctPath)) {
418
+ continue;
419
+ }
420
+ const today = new Date().toISOString().split("T")[0];
421
+ const yaml = [
422
+ `id: ${instinct.id}`,
423
+ `trigger: "${instinct.trigger}"`,
424
+ `confidence: ${instinct.confidence}`,
425
+ `domain: ${instinct.domain || "workflow"}`,
426
+ `source: pack-${packName}`,
427
+ "scope: project",
428
+ `project_id: ${project.hash}`,
429
+ `created: "${today}"`,
430
+ `last_seen: "${today}"`,
431
+ "observation_count: 0",
432
+ "---",
433
+ instinct.body,
434
+ ].join("\n");
435
+ writeFileSync(instinctPath, yaml + "\n");
436
+ loaded++;
437
+ }
438
+ console.log(` ✓ Loaded ${loaded}/${instincts.length} instincts from ${packName} pack`);
439
+ }
440
+ else {
441
+ const available = readdirSync(join(REPO_ROOT, "instinct-packs"))
442
+ .filter((file) => file.endsWith(".json"))
443
+ .map((file) => file.replace(".json", ""));
444
+ console.error(` ✗ Unknown pack: ${packName}. Available: ${available.join(", ")}`);
445
+ }
545
446
  }
546
-
547
- console.log(`
548
- ${installed > 0 ? "Done." : "Failed."} Installed to ${installed}/${targets.length} target(s).
549
- ${hasClaude ? `\n${modeInfo[INSTALL_MODE] || modeInfo.beginner}` : ""}
550
- Next steps:
551
- 1. Start a new Claude Code session
552
- 2. Say: "Use the continuous-improvement framework to [your task]"
553
- 3. After your first task, run: /continuous-improvement
554
- 4. Try: /discipline for quick reference, /dashboard for instinct health
555
- ${INSTALL_MODE === "expert" ? "\nMCP tools available: ci_status, ci_instincts, ci_reflect, ci_reinforce,\n ci_create_instinct, ci_observations, ci_export, ci_import, ci_dashboard, ci_load_pack" : ""}
556
- ${INSTALL_MODE === "mcp" ? "\nMCP tools available: ci_status, ci_instincts, ci_reflect" : ""}
557
- Available instinct packs: npx continuous-improvement install --pack react|python|go
447
+ console.log(`
448
+ ${installed === 1 ? "Done." : "Failed."}
449
+ ${modeInfo[INSTALL_MODE]}
450
+
451
+ Next steps:
452
+ 1. Start a new Claude Code session
453
+ 2. Say: "Use the continuous-improvement framework to [your task]"
454
+ 3. If a task needs persistent planning, run: /planning-with-files
455
+ 4. After your first task, run: /continuous-improvement
456
+ 5. Try: /discipline for quick reference, /dashboard for instinct health
457
+ ${INSTALL_MODE === "expert" ? "\nMCP tools available: ci_status, ci_instincts, ci_reflect, ci_reinforce,\n ci_create_instinct, ci_observations, ci_export, ci_import, ci_plan_init,\n ci_plan_status, ci_dashboard, ci_load_pack" : ""}
458
+ Available instinct packs: npx continuous-improvement install --pack react|python|go|meta
558
459
  `);