continuous-improvement 3.9.2 → 3.12.3

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 (160) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/CHANGELOG.md +95 -0
  3. package/LICENSE +21 -21
  4. package/QUICKSTART.md +13 -8
  5. package/README.md +94 -162
  6. package/SKILL.md +1 -1
  7. package/bin/analyze.sh +161 -161
  8. package/bin/backfill.mjs +19 -19
  9. package/bin/check-docs-substrings.mjs +73 -0
  10. package/bin/check-scripts-citation-drift.mjs +210 -0
  11. package/bin/check-skill-count.mjs +110 -0
  12. package/bin/check-test-imports-only.mjs +126 -0
  13. package/bin/check-tool-count.mjs +129 -0
  14. package/bin/companion-preference-status.mjs +231 -0
  15. package/bin/gateguard-clear.mjs +53 -0
  16. package/bin/generate-plugin-manifests.mjs +8 -1
  17. package/bin/harvest-friction.mjs +1 -1
  18. package/bin/hook-stats.mjs +21 -21
  19. package/bin/install.mjs +185 -28
  20. package/bin/mcp-server.mjs +216 -3
  21. package/bin/refresh-third-party.mjs +315 -313
  22. package/commands/audit.md +34 -0
  23. package/commands/companion-preference.md +58 -0
  24. package/commands/continuous-improvement.md +115 -115
  25. package/commands/dashboard.md +56 -56
  26. package/commands/discipline.md +14 -0
  27. package/commands/distill.md +39 -0
  28. package/commands/goal-check.md +53 -0
  29. package/commands/grill-me.md +40 -0
  30. package/commands/grill-with-docs.md +38 -0
  31. package/commands/handoff.md +42 -0
  32. package/commands/harvest.md +1 -1
  33. package/commands/proceed-with-the-recommendation.md +20 -0
  34. package/commands/recall.md +49 -0
  35. package/commands/reconcile.md +47 -0
  36. package/commands/seven-laws.md +16 -16
  37. package/commands/superpowers.md +3 -3
  38. package/commands/verify-install.md +55 -0
  39. package/commands/workspace-surface-audit.md +77 -77
  40. package/hooks/companion-preference.mjs +190 -0
  41. package/hooks/gateguard.mjs +72 -25
  42. package/hooks/goal-drift-stop.mjs +183 -0
  43. package/hooks/observe.sh +15 -1
  44. package/hooks/recall-briefing.mjs +167 -0
  45. package/hooks/route-prompt.mjs +180 -0
  46. package/hooks/route-table.json +35 -0
  47. package/hooks/session.sh +106 -106
  48. package/hooks/three-section-close.mjs +134 -132
  49. package/instinct-packs/go.json +58 -58
  50. package/instinct-packs/meta.json +16 -16
  51. package/instinct-packs/python.json +58 -58
  52. package/instinct-packs/react.json +58 -58
  53. package/lib/gateguard-state.mjs +54 -2
  54. package/lib/goal-drift-gate.mjs +50 -0
  55. package/lib/goal-state.mjs +285 -0
  56. package/lib/plugin-metadata.mjs +134 -15
  57. package/lib/recall-briefing.mjs +57 -0
  58. package/lib/recall-index.mjs +175 -0
  59. package/lib/skill-distill.mjs +222 -0
  60. package/llms.txt +2 -2
  61. package/package.json +12 -7
  62. package/plugins/beginner.json +9 -4
  63. package/plugins/continuous-improvement/.claude-plugin/marketplace.json +2 -2
  64. package/plugins/continuous-improvement/.claude-plugin/plugin.json +2 -2
  65. package/plugins/continuous-improvement/LICENSE +21 -21
  66. package/plugins/continuous-improvement/agents/README.md +3 -3
  67. package/plugins/continuous-improvement/bin/backfill.mjs +19 -19
  68. package/plugins/continuous-improvement/bin/gateguard-clear.mjs +53 -0
  69. package/plugins/continuous-improvement/bin/mcp-server.mjs +216 -3
  70. package/plugins/continuous-improvement/commands/audit.md +34 -0
  71. package/plugins/continuous-improvement/commands/companion-preference.md +58 -0
  72. package/plugins/continuous-improvement/commands/continuous-improvement.md +115 -115
  73. package/plugins/continuous-improvement/commands/dashboard.md +56 -56
  74. package/plugins/continuous-improvement/commands/discipline.md +14 -0
  75. package/plugins/continuous-improvement/commands/distill.md +39 -0
  76. package/plugins/continuous-improvement/commands/goal-check.md +53 -0
  77. package/plugins/continuous-improvement/commands/grill-me.md +40 -0
  78. package/plugins/continuous-improvement/commands/grill-with-docs.md +38 -0
  79. package/plugins/continuous-improvement/commands/handoff.md +42 -0
  80. package/plugins/continuous-improvement/commands/harvest.md +1 -1
  81. package/plugins/continuous-improvement/commands/proceed-with-the-recommendation.md +20 -0
  82. package/plugins/continuous-improvement/commands/recall.md +49 -0
  83. package/plugins/continuous-improvement/commands/reconcile.md +47 -0
  84. package/plugins/continuous-improvement/commands/seven-laws.md +16 -16
  85. package/plugins/continuous-improvement/commands/superpowers.md +3 -3
  86. package/plugins/continuous-improvement/commands/verify-install.md +55 -0
  87. package/plugins/continuous-improvement/commands/workspace-surface-audit.md +77 -77
  88. package/plugins/continuous-improvement/hooks/companion-preference.mjs +190 -0
  89. package/plugins/continuous-improvement/hooks/gateguard.mjs +72 -25
  90. package/plugins/continuous-improvement/hooks/goal-drift-stop.mjs +183 -0
  91. package/plugins/continuous-improvement/hooks/hooks.json +23 -2
  92. package/plugins/continuous-improvement/hooks/observe.sh +15 -1
  93. package/plugins/continuous-improvement/hooks/recall-briefing.mjs +167 -0
  94. package/plugins/continuous-improvement/hooks/route-prompt.mjs +180 -0
  95. package/plugins/continuous-improvement/hooks/route-table.json +35 -0
  96. package/plugins/continuous-improvement/hooks/session.sh +106 -106
  97. package/plugins/continuous-improvement/hooks/three-section-close.mjs +134 -132
  98. package/plugins/continuous-improvement/instinct-packs/go.json +58 -58
  99. package/plugins/continuous-improvement/instinct-packs/meta.json +16 -16
  100. package/plugins/continuous-improvement/instinct-packs/python.json +58 -58
  101. package/plugins/continuous-improvement/instinct-packs/react.json +58 -58
  102. package/plugins/continuous-improvement/lib/gateguard-state.mjs +137 -0
  103. package/plugins/continuous-improvement/lib/goal-drift-gate.mjs +50 -0
  104. package/plugins/continuous-improvement/lib/goal-state.mjs +285 -0
  105. package/plugins/continuous-improvement/lib/plugin-metadata.mjs +134 -15
  106. package/plugins/continuous-improvement/lib/recall-briefing.mjs +57 -0
  107. package/plugins/continuous-improvement/lib/recall-index.mjs +175 -0
  108. package/plugins/continuous-improvement/lib/skill-distill.mjs +222 -0
  109. package/plugins/continuous-improvement/skills/README.md +8 -0
  110. package/plugins/continuous-improvement/skills/audit/SKILL.md +73 -0
  111. package/plugins/continuous-improvement/skills/continuous-improvement/SKILL.md +1 -1
  112. package/plugins/continuous-improvement/skills/deploy-receipt/SKILL.md +13 -17
  113. package/plugins/continuous-improvement/skills/gateguard/SKILL.md +36 -17
  114. package/plugins/continuous-improvement/skills/goal-monitor/SKILL.md +81 -0
  115. package/plugins/continuous-improvement/skills/grill-me/SKILL.md +66 -0
  116. package/plugins/continuous-improvement/skills/grill-with-docs/SKILL.md +252 -0
  117. package/plugins/continuous-improvement/skills/handoff/SKILL.md +59 -0
  118. package/plugins/continuous-improvement/skills/para-memory-files/SKILL.md +1 -1
  119. package/plugins/continuous-improvement/skills/proceed-with-the-recommendation/SKILL.md +82 -6
  120. package/plugins/continuous-improvement/skills/ralph/SKILL.md +1 -0
  121. package/plugins/continuous-improvement/skills/recall/SKILL.md +50 -0
  122. package/plugins/continuous-improvement/skills/reconcile/SKILL.md +80 -0
  123. package/plugins/continuous-improvement/skills/recovery-classification/SKILL.md +1 -0
  124. package/plugins/continuous-improvement/skills/safety-guard/SKILL.md +1 -0
  125. package/plugins/continuous-improvement/skills/skill-distillation/SKILL.md +57 -0
  126. package/plugins/continuous-improvement/skills/state-reconciliation/SKILL.md +1 -0
  127. package/plugins/continuous-improvement/skills/strategic-compact/SKILL.md +1 -0
  128. package/plugins/continuous-improvement/skills/superpowers/SKILL.md +77 -3
  129. package/plugins/continuous-improvement/skills/tdd-workflow/SKILL.md +411 -411
  130. package/plugins/continuous-improvement/skills/token-budget-advisor/SKILL.md +1 -1
  131. package/plugins/continuous-improvement/skills/verification-loop/SKILL.md +28 -20
  132. package/plugins/continuous-improvement/skills/wild-risa-balance/SKILL.md +1 -0
  133. package/plugins/continuous-improvement/skills/workspace-surface-audit/SKILL.md +1 -1
  134. package/plugins/continuous-improvement/skills/worktree-safety/SKILL.md +3 -2
  135. package/plugins/expert.json +28 -3
  136. package/skills/README.md +3 -0
  137. package/skills/audit.md +73 -0
  138. package/skills/deploy-receipt.md +13 -17
  139. package/skills/gateguard.md +36 -17
  140. package/skills/goal-monitor.md +81 -0
  141. package/skills/grill-me.md +66 -0
  142. package/skills/grill-with-docs.md +252 -0
  143. package/skills/handoff.md +59 -0
  144. package/skills/para-memory-files.md +1 -1
  145. package/skills/proceed-with-the-recommendation.md +82 -6
  146. package/skills/ralph.md +1 -0
  147. package/skills/recall.md +50 -0
  148. package/skills/reconcile.md +80 -0
  149. package/skills/recovery-classification.md +1 -0
  150. package/skills/safety-guard.md +1 -0
  151. package/skills/skill-distillation.md +57 -0
  152. package/skills/state-reconciliation.md +1 -0
  153. package/skills/strategic-compact.md +1 -0
  154. package/skills/superpowers.md +77 -3
  155. package/skills/tdd-workflow.md +411 -411
  156. package/skills/token-budget-advisor.md +1 -1
  157. package/skills/verification-loop.md +28 -20
  158. package/skills/wild-risa-balance.md +1 -0
  159. package/skills/workspace-surface-audit.md +1 -1
  160. package/skills/worktree-safety.md +3 -2
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * /companion-preference status — read & aggregate hook telemetry.
4
+ *
5
+ * Reads ~/.claude/instincts/<project-hash>/companion-preference.jsonl
6
+ * (or an explicit path via --path), groups events by ci_skill within the
7
+ * configured window (default 7 days), and prints a summary report with
8
+ * per-skill totals, action breakdown, and companion_installed%.
9
+ *
10
+ * Usage:
11
+ * node bin/companion-preference-status.mjs # last 7 days, human
12
+ * node bin/companion-preference-status.mjs --days 30 # 30-day window
13
+ * node bin/companion-preference-status.mjs --all # whole file, no window
14
+ * node bin/companion-preference-status.mjs --json # machine-readable JSON
15
+ * node bin/companion-preference-status.mjs --path <p> # override JSONL path
16
+ *
17
+ * Exit codes:
18
+ * 0 — report rendered (including the "no telemetry recorded yet" case)
19
+ * 1 — argument parse error or unexpected runtime failure
20
+ */
21
+ import { execFileSync } from "node:child_process";
22
+ import { createHash } from "node:crypto";
23
+ import { existsSync, readFileSync } from "node:fs";
24
+ import { homedir } from "node:os";
25
+ import { join } from "node:path";
26
+ import { argv, exit, stdout } from "node:process";
27
+ const ACTIONS = [
28
+ "observation",
29
+ "advisory",
30
+ "block",
31
+ "block-not-installed",
32
+ ];
33
+ function parseArgs(args) {
34
+ const out = { days: 7, all: false, json: false, path: null };
35
+ for (let i = 0; i < args.length; i += 1) {
36
+ const a = args[i];
37
+ if (a === "--days") {
38
+ const v = Number(args[++i]);
39
+ if (!Number.isFinite(v) || v <= 0) {
40
+ process.stderr.write(`--days requires a positive integer (got ${args[i]})\n`);
41
+ exit(1);
42
+ }
43
+ out.days = v;
44
+ }
45
+ else if (a === "--all") {
46
+ out.all = true;
47
+ out.days = null;
48
+ }
49
+ else if (a === "--json") {
50
+ out.json = true;
51
+ }
52
+ else if (a === "--path") {
53
+ out.path = args[++i] ?? null;
54
+ if (!out.path) {
55
+ process.stderr.write(`--path requires a value\n`);
56
+ exit(1);
57
+ }
58
+ }
59
+ else if (a === "--help" || a === "-h") {
60
+ printHelp();
61
+ exit(0);
62
+ }
63
+ else if (a !== undefined) {
64
+ process.stderr.write(`unknown argument: ${a}\n`);
65
+ exit(1);
66
+ }
67
+ }
68
+ return out;
69
+ }
70
+ function printHelp() {
71
+ stdout.write([
72
+ "Usage: companion-preference-status [options]",
73
+ "",
74
+ "Options:",
75
+ " --days N Only count events from the last N days (default 7)",
76
+ " --all Ignore the window; count every row in the file",
77
+ " --json Emit a machine-readable JSON report",
78
+ " --path <file> Override the default JSONL path (testing)",
79
+ " -h, --help Print this help",
80
+ "",
81
+ ].join("\n"));
82
+ }
83
+ function resolveProjectRoot() {
84
+ const fromEnv = process.env.CLAUDE_PROJECT_DIR;
85
+ if (fromEnv)
86
+ return fromEnv;
87
+ try {
88
+ const root = execFileSync("git", ["rev-parse", "--show-toplevel"], {
89
+ encoding: "utf8",
90
+ stdio: ["ignore", "pipe", "ignore"],
91
+ }).trim();
92
+ if (root)
93
+ return root;
94
+ }
95
+ catch {
96
+ // not in a git repo
97
+ }
98
+ return "global";
99
+ }
100
+ function defaultJsonlPath() {
101
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? homedir();
102
+ const hash = createHash("sha256")
103
+ .update(resolveProjectRoot())
104
+ .digest("hex")
105
+ .slice(0, 12);
106
+ return join(home, ".claude", "instincts", hash, "companion-preference.jsonl");
107
+ }
108
+ function parseJsonl(raw) {
109
+ const rows = [];
110
+ let parseErrors = 0;
111
+ for (const line of raw.split(/\r?\n/)) {
112
+ if (line.trim().length === 0)
113
+ continue;
114
+ try {
115
+ rows.push(JSON.parse(line));
116
+ }
117
+ catch {
118
+ parseErrors += 1;
119
+ }
120
+ }
121
+ return { rows, parseErrors };
122
+ }
123
+ function aggregate(rows) {
124
+ const bySkill = {};
125
+ const byMode = {};
126
+ const installedYes = {};
127
+ for (const row of rows) {
128
+ const stats = (bySkill[row.ci_skill] ??= {
129
+ total: 0,
130
+ actions: {},
131
+ installed_pct: null,
132
+ });
133
+ stats.total += 1;
134
+ stats.actions[row.action] = (stats.actions[row.action] ?? 0) + 1;
135
+ if (row.companion_installed) {
136
+ installedYes[row.ci_skill] = (installedYes[row.ci_skill] ?? 0) + 1;
137
+ }
138
+ byMode[row.mode] = (byMode[row.mode] ?? 0) + 1;
139
+ }
140
+ for (const [skill, stats] of Object.entries(bySkill)) {
141
+ stats.installed_pct =
142
+ stats.total > 0
143
+ ? Math.round(((installedYes[skill] ?? 0) * 100) / stats.total)
144
+ : null;
145
+ }
146
+ return { bySkill, byMode };
147
+ }
148
+ function pad(s, width) {
149
+ return s.length >= width ? s : s + " ".repeat(width - s.length);
150
+ }
151
+ function rpad(n, width) {
152
+ const s = String(n);
153
+ return s.length >= width ? s : " ".repeat(width - s.length) + s;
154
+ }
155
+ function formatHuman(report) {
156
+ const lines = [];
157
+ const windowLabel = report.window_days === null ? "all-time" : `last ${report.window_days} days`;
158
+ lines.push(`Companion-preference telemetry — ${windowLabel}`);
159
+ lines.push(`File: ${report.file}`);
160
+ if (report.since)
161
+ lines.push(`Window: ${report.since} to ${new Date().toISOString()}`);
162
+ lines.push("");
163
+ if (report.total_events === 0) {
164
+ lines.push("No events in window.");
165
+ }
166
+ else {
167
+ const skillWidth = Math.max(8, ...Object.keys(report.by_skill).map((k) => k.length));
168
+ const header = pad("ci_skill", skillWidth) +
169
+ " " +
170
+ ["total", "observation", "advisory", "block", "block-not-installed", "installed%"]
171
+ .map((h) => rpad(h, h.length))
172
+ .join(" ");
173
+ lines.push(header);
174
+ for (const [skill, stats] of Object.entries(report.by_skill).sort((a, b) => b[1].total - a[1].total)) {
175
+ const cells = [
176
+ rpad(stats.total, "total".length),
177
+ rpad(stats.actions.observation ?? 0, "observation".length),
178
+ rpad(stats.actions.advisory ?? 0, "advisory".length),
179
+ rpad(stats.actions.block ?? 0, "block".length),
180
+ rpad(stats.actions["block-not-installed"] ?? 0, "block-not-installed".length),
181
+ rpad(stats.installed_pct === null ? "—" : `${stats.installed_pct}`, "installed%".length),
182
+ ].join(" ");
183
+ lines.push(pad(skill, skillWidth) + " " + cells);
184
+ }
185
+ }
186
+ lines.push("");
187
+ const modeEntries = Object.entries(report.by_mode);
188
+ if (modeEntries.length > 0) {
189
+ lines.push(`Mode totals: ${modeEntries.map(([k, v]) => `${k} ${v}`).join(", ")}`);
190
+ }
191
+ lines.push(`Total events: ${report.total_events}`);
192
+ if (report.parse_errors > 0)
193
+ lines.push(`Parse errors (skipped): ${report.parse_errors}`);
194
+ return lines.join("\n") + "\n";
195
+ }
196
+ function main() {
197
+ const args = parseArgs(argv.slice(2));
198
+ const filePath = args.path ?? defaultJsonlPath();
199
+ if (!existsSync(filePath)) {
200
+ stdout.write(`Companion-preference telemetry: no telemetry recorded yet at ${filePath}\n`);
201
+ exit(0);
202
+ }
203
+ const raw = readFileSync(filePath, "utf8");
204
+ const { rows, parseErrors } = parseJsonl(raw);
205
+ const cutoff = args.all || args.days === null
206
+ ? null
207
+ : new Date(Date.now() - args.days * 24 * 3600 * 1000).toISOString();
208
+ const filtered = cutoff === null ? rows : rows.filter((r) => r.ts >= cutoff);
209
+ const { bySkill, byMode } = aggregate(filtered);
210
+ const report = {
211
+ file: filePath,
212
+ window_days: args.all ? null : args.days,
213
+ since: cutoff,
214
+ total_events: filtered.length,
215
+ parse_errors: parseErrors,
216
+ by_skill: bySkill,
217
+ by_mode: byMode,
218
+ };
219
+ if (args.json) {
220
+ stdout.write(JSON.stringify(report, null, 2) + "\n");
221
+ }
222
+ else {
223
+ stdout.write(formatHuman(report));
224
+ }
225
+ exit(0);
226
+ }
227
+ const invokedDirectly = argv[1]?.endsWith("companion-preference-status.mjs");
228
+ if (invokedDirectly) {
229
+ main();
230
+ }
231
+ export { ACTIONS, aggregate, parseArgs, parseJsonl, };
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * gateguard-clear — record GateGuard clearance for files from the Bash route.
4
+ *
5
+ * The GateGuard PreToolUse hook blocks the first Edit/Write per file and prints
6
+ * the session-state path in its block reason. After presenting the required
7
+ * facts, run this to clear the gate so the retry is allowed. Bash is not gated
8
+ * (unless the command is destructive), so this surface always works — including
9
+ * where the ci_gateguard_clear MCP tool is not connected.
10
+ *
11
+ * Usage:
12
+ * node bin/gateguard-clear.mjs <file_path> [<file_path>...] [--state <path>]
13
+ *
14
+ * Default resolves the session dir canonically, the same way the hook does.
15
+ * --state <path> writes that exact gateguard-session.json — the path the block
16
+ * reason prints — bypassing resolution for any residual env mismatch.
17
+ */
18
+ import { dirname, join } from "node:path";
19
+ import { MAX_CLEARED_FILES, clearFiles, resolveSessionDir, } from "../lib/gateguard-state.mjs";
20
+ function main() {
21
+ const argv = process.argv.slice(2);
22
+ const files = [];
23
+ let stateFile = "";
24
+ for (let i = 0; i < argv.length; i += 1) {
25
+ const arg = argv[i];
26
+ if (arg === "--state") {
27
+ stateFile = argv[i + 1] ?? "";
28
+ i += 1;
29
+ }
30
+ else {
31
+ files.push(arg);
32
+ }
33
+ }
34
+ if (argv.includes("--state") && stateFile === "") {
35
+ process.stderr.write("--state requires a <gateguard-session.json> path argument\n");
36
+ process.exit(2);
37
+ }
38
+ if (files.length === 0) {
39
+ process.stderr.write("usage: gateguard-clear <file_path> [<file_path>...] [--state <gateguard-session.json>]\n");
40
+ process.exit(2);
41
+ }
42
+ // clearFiles writes <sessionDir>/gateguard-session.json. With --state the
43
+ // caller hands us the full state-file path the block reason printed, so the
44
+ // session dir is its parent.
45
+ const sessionDir = stateFile ? dirname(stateFile) : resolveSessionDir();
46
+ const { cleared, skippedForCap } = clearFiles(sessionDir, files);
47
+ process.stdout.write(`Cleared ${cleared.length}: ${cleared.length > 0 ? cleared.join(", ") : "(none — already cleared)"}\n`);
48
+ if (skippedForCap.length > 0) {
49
+ process.stdout.write(`Skipped — session cap of ${MAX_CLEARED_FILES} reached: ${skippedForCap.join(", ")}\n`);
50
+ }
51
+ process.stdout.write(`State: ${join(sessionDir, "gateguard-session.json")}\n`);
52
+ }
53
+ main();
@@ -35,7 +35,7 @@ async function writeBundledSkills() {
35
35
  const sourceSkillsDir = join(REPO_ROOT, "skills");
36
36
  const targetSkillsDir = join(PLUGIN_BUNDLE_DIR, "skills");
37
37
  const companionSkills = (await readdir(sourceSkillsDir))
38
- .filter((file) => /^[a-z][a-z0-9-]*\.md$/.test(file))
38
+ .filter((file) => file.endsWith(".md") && file !== "README.md")
39
39
  .sort();
40
40
  await mkdir(targetSkillsDir, { recursive: true });
41
41
  await copyFileTo(join(REPO_ROOT, "SKILL.md"), join(targetSkillsDir, PACKAGE_NAME, "SKILL.md"));
@@ -145,9 +145,16 @@ async function writePluginBundle() {
145
145
  copyFileTo(join(REPO_ROOT, "bin", "mcp-server.mjs"), join(PLUGIN_BUNDLE_DIR, "bin", "mcp-server.mjs")),
146
146
  copyFileTo(join(REPO_ROOT, "bin", "observe.mjs"), join(PLUGIN_BUNDLE_DIR, "bin", "observe.mjs")),
147
147
  copyFileTo(join(REPO_ROOT, "bin", "backfill.mjs"), join(PLUGIN_BUNDLE_DIR, "bin", "backfill.mjs")),
148
+ copyFileTo(join(REPO_ROOT, "bin", "gateguard-clear.mjs"), join(PLUGIN_BUNDLE_DIR, "bin", "gateguard-clear.mjs")),
149
+ copyFileTo(join(REPO_ROOT, "lib", "gateguard-state.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "gateguard-state.mjs")),
148
150
  copyFileTo(join(REPO_ROOT, "lib", "plugin-metadata.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "plugin-metadata.mjs")),
149
151
  copyFileTo(join(REPO_ROOT, "lib", "resolve-home-dir.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "resolve-home-dir.mjs")),
150
152
  copyFileTo(join(REPO_ROOT, "lib", "observe-event.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "observe-event.mjs")),
153
+ copyFileTo(join(REPO_ROOT, "lib", "goal-state.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "goal-state.mjs")),
154
+ copyFileTo(join(REPO_ROOT, "lib", "goal-drift-gate.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "goal-drift-gate.mjs")),
155
+ copyFileTo(join(REPO_ROOT, "lib", "recall-index.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "recall-index.mjs")),
156
+ copyFileTo(join(REPO_ROOT, "lib", "recall-briefing.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "recall-briefing.mjs")),
157
+ copyFileTo(join(REPO_ROOT, "lib", "skill-distill.mjs"), join(PLUGIN_BUNDLE_DIR, "lib", "skill-distill.mjs")),
151
158
  copyFileTo(join(REPO_ROOT, "LICENSE"), join(PLUGIN_BUNDLE_DIR, "LICENSE")),
152
159
  writePluginBundleReadme(),
153
160
  ]);
@@ -248,7 +248,7 @@ function main() {
248
248
  console.log(" the Node observer is not on PATH — never tool_complete with output_summary,");
249
249
  console.log(" which is what the classifier needs.");
250
250
  console.log(" Install jq (winget install jqlang.jq | brew install jq | apt install jq)");
251
- console.log(" OR ensure hooks/bin/observe.mjs is reachable from the hook script.");
251
+ console.log(" OR ensure instincts/bin/observe.mjs is reachable from the hook script.");
252
252
  }
253
253
  else if (result.thinSchemaRows > 0 && result.classifiedRows === 0) {
254
254
  console.log("");
@@ -46,27 +46,27 @@ import { platform } from "node:os";
46
46
  import { join } from "node:path";
47
47
  import { argv, cwd, exit, stderr, stdout } from "node:process";
48
48
  import { resolveHomeDir } from "../lib/resolve-home-dir.mjs";
49
- const USAGE = `Usage: node bin/hook-stats.mjs [options]
50
-
51
- Reads JSONL telemetry from <HOME>/.claude/hook-telemetry/*.jsonl and
52
- prints per-hook aggregate counts over a recent time window.
53
-
54
- Options:
55
- --hours=<n> Time window in hours (default: 24)
56
- --hash=<hash> Only read this single <hash>.jsonl file
57
- (default: sha256 of the current working directory,
58
- normalized to forward slashes and lowercased on
59
- Windows, then first 12 hex chars)
60
- --telemetry-dir=<path> Override telemetry dir
61
- (default: <HOME>/.claude/hook-telemetry)
62
- --help Show this help and exit 0
63
-
64
- Output:
65
- One line per hook: "<hook> last <hours>h: pass=<n> block=<n>
66
- skip-short=<n> total=<n> avg-duration=<X>ms".
67
- If there are no records in the window: "no records in last <hours>h".
68
-
69
- The reader is parse-tolerant: malformed JSONL lines are skipped silently.
49
+ const USAGE = `Usage: node bin/hook-stats.mjs [options]
50
+
51
+ Reads JSONL telemetry from <HOME>/.claude/hook-telemetry/*.jsonl and
52
+ prints per-hook aggregate counts over a recent time window.
53
+
54
+ Options:
55
+ --hours=<n> Time window in hours (default: 24)
56
+ --hash=<hash> Only read this single <hash>.jsonl file
57
+ (default: sha256 of the current working directory,
58
+ normalized to forward slashes and lowercased on
59
+ Windows, then first 12 hex chars)
60
+ --telemetry-dir=<path> Override telemetry dir
61
+ (default: <HOME>/.claude/hook-telemetry)
62
+ --help Show this help and exit 0
63
+
64
+ Output:
65
+ One line per hook: "<hook> last <hours>h: pass=<n> block=<n>
66
+ skip-short=<n> total=<n> avg-duration=<X>ms".
67
+ If there are no records in the window: "no records in last <hours>h".
68
+
69
+ The reader is parse-tolerant: malformed JSONL lines are skipped silently.
70
70
  `;
71
71
  function parseArgs(rawArgs) {
72
72
  const opts = {