smart-claude-memory-mcp 2.1.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 (104) hide show
  1. package/.claude-plugin/plugin.json +38 -0
  2. package/CHANGELOG.md +52 -0
  3. package/LICENSE +21 -0
  4. package/README.md +790 -0
  5. package/dist/chunker.js +33 -0
  6. package/dist/chunker.js.map +1 -0
  7. package/dist/config.js +23 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/curriculum/daemon.js +190 -0
  10. package/dist/curriculum/daemon.js.map +1 -0
  11. package/dist/curriculum/scanner.js +237 -0
  12. package/dist/curriculum/scanner.js.map +1 -0
  13. package/dist/index.js +429 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lib/migrations.js +128 -0
  16. package/dist/lib/migrations.js.map +1 -0
  17. package/dist/ollama.js +59 -0
  18. package/dist/ollama.js.map +1 -0
  19. package/dist/project-detect.js +102 -0
  20. package/dist/project-detect.js.map +1 -0
  21. package/dist/project.js +26 -0
  22. package/dist/project.js.map +1 -0
  23. package/dist/sleep/daemon.js +215 -0
  24. package/dist/sleep/daemon.js.map +1 -0
  25. package/dist/sleep/miner.js +285 -0
  26. package/dist/sleep/miner.js.map +1 -0
  27. package/dist/supabase.js +405 -0
  28. package/dist/supabase.js.map +1 -0
  29. package/dist/telemetry/emit.js +19 -0
  30. package/dist/telemetry/emit.js.map +1 -0
  31. package/dist/telemetry/pruner.js +141 -0
  32. package/dist/telemetry/pruner.js.map +1 -0
  33. package/dist/telemetry/types.js +2 -0
  34. package/dist/telemetry/types.js.map +1 -0
  35. package/dist/tools/backlog.js +599 -0
  36. package/dist/tools/backlog.js.map +1 -0
  37. package/dist/tools/batch-freeze-patterns.js +243 -0
  38. package/dist/tools/batch-freeze-patterns.js.map +1 -0
  39. package/dist/tools/bloat-audit.js +101 -0
  40. package/dist/tools/bloat-audit.js.map +1 -0
  41. package/dist/tools/checkpoint.js +259 -0
  42. package/dist/tools/checkpoint.js.map +1 -0
  43. package/dist/tools/compact.js +60 -0
  44. package/dist/tools/compact.js.map +1 -0
  45. package/dist/tools/conflict.js +102 -0
  46. package/dist/tools/conflict.js.map +1 -0
  47. package/dist/tools/curriculum.js +225 -0
  48. package/dist/tools/curriculum.js.map +1 -0
  49. package/dist/tools/frozen-cache.js +106 -0
  50. package/dist/tools/frozen-cache.js.map +1 -0
  51. package/dist/tools/health.js +368 -0
  52. package/dist/tools/health.js.map +1 -0
  53. package/dist/tools/hygiene.js +309 -0
  54. package/dist/tools/hygiene.js.map +1 -0
  55. package/dist/tools/image.js +107 -0
  56. package/dist/tools/image.js.map +1 -0
  57. package/dist/tools/list-global-patterns.js +101 -0
  58. package/dist/tools/list-global-patterns.js.map +1 -0
  59. package/dist/tools/orchestrator.js +113 -0
  60. package/dist/tools/orchestrator.js.map +1 -0
  61. package/dist/tools/policy.js +90 -0
  62. package/dist/tools/policy.js.map +1 -0
  63. package/dist/tools/refactor.js +220 -0
  64. package/dist/tools/refactor.js.map +1 -0
  65. package/dist/tools/save.js +42 -0
  66. package/dist/tools/save.js.map +1 -0
  67. package/dist/tools/search.js +189 -0
  68. package/dist/tools/search.js.map +1 -0
  69. package/dist/tools/setup.js +868 -0
  70. package/dist/tools/setup.js.map +1 -0
  71. package/dist/tools/shared-schemas.js +24 -0
  72. package/dist/tools/shared-schemas.js.map +1 -0
  73. package/dist/tools/skills.js +174 -0
  74. package/dist/tools/skills.js.map +1 -0
  75. package/dist/tools/sleep.js +239 -0
  76. package/dist/tools/sleep.js.map +1 -0
  77. package/dist/tools/sovereign-constitution.js +319 -0
  78. package/dist/tools/sovereign-constitution.js.map +1 -0
  79. package/dist/tools/summarize.js +55 -0
  80. package/dist/tools/summarize.js.map +1 -0
  81. package/dist/tools/sync.js +255 -0
  82. package/dist/tools/sync.js.map +1 -0
  83. package/dist/tools/system_dashboard.js +181 -0
  84. package/dist/tools/system_dashboard.js.map +1 -0
  85. package/dist/tools/update-rule.js +15 -0
  86. package/dist/tools/update-rule.js.map +1 -0
  87. package/dist/tools/verification.js +333 -0
  88. package/dist/tools/verification.js.map +1 -0
  89. package/dist/trajectory/daemon.js +270 -0
  90. package/dist/trajectory/daemon.js.map +1 -0
  91. package/dist/trajectory/stripper.js +124 -0
  92. package/dist/trajectory/stripper.js.map +1 -0
  93. package/dist/trajectory/summarizer.js +77 -0
  94. package/dist/trajectory/summarizer.js.map +1 -0
  95. package/dist/transactions/checkpoint.js +272 -0
  96. package/dist/transactions/checkpoint.js.map +1 -0
  97. package/dist/verification-gate.js +43 -0
  98. package/dist/verification-gate.js.map +1 -0
  99. package/dist/version.js +16 -0
  100. package/dist/version.js.map +1 -0
  101. package/hooks/README.md +54 -0
  102. package/hooks/md-policy.py +497 -0
  103. package/marketplace.json +13 -0
  104. package/package.json +66 -0
@@ -0,0 +1,272 @@
1
+ // Transactional Workflow Checkpoint Service (Agentic OS 2026 / Mission 4 / Phase A).
2
+ //
3
+ // Pure service layer — NO MCP tool definitions live here (those land in Phase B
4
+ // under src/tools/checkpoint.ts). This module is the binding glue between the
5
+ // three earlier missions:
6
+ //
7
+ // * M1 (agent_skills) — `skillId` ties the checkpoint to a JIT-retrieved
8
+ // skill boundary.
9
+ // * M2 (trajectory_summaries) — `sourceChunkId` pinned on commit IS the replay
10
+ // anchor; restore replays it via the existing
11
+ // `get_trajectory_summary` RPC.
12
+ // * M3 (skill_candidates) — rollback events feed the miner as negative
13
+ // examples (the LEFT JOIN extension itself is
14
+ // deferred to Phase B; this module emits the
15
+ // durable rolledback row that the miner reads).
16
+ //
17
+ // All functions:
18
+ // * validate inputs and throw Error with `[M4]` prefix on bad shape
19
+ // * surface Supabase failures verbatim wrapped with `[M4] <op>: <msg>`
20
+ // * return typed results — no `any`, no placeholders
21
+ //
22
+ // Style mirrors src/sleep/miner.ts and src/trajectory/daemon.ts: throw on
23
+ // I/O failure (the caller / future Phase-B tool wrapper translates to MCP
24
+ // error envelope), use `supabase` from ../supabase.js, no module-level state
25
+ // (this is a pure service — daemon-style state belongs in Phase B if/when
26
+ // we add a checkpoint reaper).
27
+ import { supabase } from "../supabase.js";
28
+ // ─── validation helpers ─────────────────────────────────────────────────────
29
+ function requireProjectId(projectId, fn) {
30
+ if (typeof projectId !== "string" || projectId.trim().length === 0) {
31
+ throw new Error(`[M4] ${fn}: projectId must be a non-empty string`);
32
+ }
33
+ }
34
+ function requireCheckpointId(id, fn) {
35
+ if (typeof id !== "number" || !Number.isInteger(id) || id <= 0) {
36
+ throw new Error(`[M4] ${fn}: checkpointId must be a positive integer`);
37
+ }
38
+ }
39
+ function requireStepIndex(idx, fn) {
40
+ if (typeof idx !== "number" || !Number.isInteger(idx) || idx < 0) {
41
+ throw new Error(`[M4] ${fn}: stepIndex must be a non-negative integer`);
42
+ }
43
+ }
44
+ function requireStepLabel(label, fn) {
45
+ if (typeof label !== "string" || label.trim().length === 0) {
46
+ throw new Error(`[M4] ${fn}: stepLabel must be a non-empty string`);
47
+ }
48
+ }
49
+ function requireSourceChunkId(id, fn) {
50
+ if (typeof id !== "number" || !Number.isInteger(id) || id <= 0) {
51
+ throw new Error(`[M4] ${fn}: sourceChunkId must be a positive integer`);
52
+ }
53
+ }
54
+ function requireReason(reason, fn) {
55
+ if (typeof reason !== "string" || reason.trim().length === 0) {
56
+ throw new Error(`[M4] ${fn}: reason must be a non-empty string`);
57
+ }
58
+ }
59
+ // ─── openCheckpoint ─────────────────────────────────────────────────────────
60
+ export async function openCheckpoint(args) {
61
+ requireProjectId(args.projectId, "openCheckpoint");
62
+ requireStepIndex(args.stepIndex, "openCheckpoint");
63
+ requireStepLabel(args.stepLabel, "openCheckpoint");
64
+ const skillId = args.skillId === undefined || args.skillId === null ? null : args.skillId;
65
+ if (skillId !== null && (!Number.isInteger(skillId) || skillId <= 0)) {
66
+ throw new Error(`[M4] openCheckpoint: skillId must be a positive integer or null`);
67
+ }
68
+ const parentId = args.parentId === undefined || args.parentId === null ? null : args.parentId;
69
+ if (parentId !== null && (!Number.isInteger(parentId) || parentId <= 0)) {
70
+ throw new Error(`[M4] openCheckpoint: parentId must be a positive integer or null`);
71
+ }
72
+ console.log(`[M4] openCheckpoint: project=${args.projectId} step=${args.stepIndex} label=${args.stepLabel} parent=${parentId ?? "root"}`);
73
+ const { data, error } = await supabase
74
+ .from("workflow_checkpoints")
75
+ .insert({
76
+ project_id: args.projectId,
77
+ skill_id: skillId,
78
+ step_index: args.stepIndex,
79
+ step_label: args.stepLabel,
80
+ parent_id: parentId,
81
+ status: "open",
82
+ })
83
+ .select("id, status")
84
+ .single();
85
+ if (error) {
86
+ throw new Error(`[M4] openCheckpoint: insert failed: ${error.message}`);
87
+ }
88
+ if (!data || typeof data.id !== "number") {
89
+ throw new Error(`[M4] openCheckpoint: insert returned no row`);
90
+ }
91
+ if (data.status !== "open") {
92
+ throw new Error(`[M4] openCheckpoint: unexpected status '${String(data.status)}'`);
93
+ }
94
+ return { id: data.id, status: "open" };
95
+ }
96
+ // ─── commitCheckpoint ───────────────────────────────────────────────────────
97
+ export async function commitCheckpoint(args) {
98
+ requireProjectId(args.projectId, "commitCheckpoint");
99
+ requireCheckpointId(args.checkpointId, "commitCheckpoint");
100
+ requireSourceChunkId(args.sourceChunkId, "commitCheckpoint");
101
+ console.log(`[M4] commitCheckpoint: project=${args.projectId} id=${args.checkpointId} source_chunk_id=${args.sourceChunkId}`);
102
+ const { data, error } = await supabase
103
+ .from("workflow_checkpoints")
104
+ .update({
105
+ status: "committed",
106
+ source_chunk_id: args.sourceChunkId,
107
+ committed_at: new Date().toISOString(),
108
+ })
109
+ .eq("id", args.checkpointId)
110
+ .eq("project_id", args.projectId)
111
+ .eq("status", "open") // only open rows commit — idempotency + safety
112
+ .select("id, status, source_chunk_id")
113
+ .single();
114
+ if (error) {
115
+ throw new Error(`[M4] commitCheckpoint: update failed: ${error.message}`);
116
+ }
117
+ if (!data || typeof data.id !== "number") {
118
+ throw new Error(`[M4] commitCheckpoint: row not found, not open, or project mismatch (id=${args.checkpointId})`);
119
+ }
120
+ if (data.status !== "committed") {
121
+ throw new Error(`[M4] commitCheckpoint: unexpected status '${String(data.status)}'`);
122
+ }
123
+ if (typeof data.source_chunk_id !== "number") {
124
+ throw new Error(`[M4] commitCheckpoint: source_chunk_id not persisted`);
125
+ }
126
+ return {
127
+ id: data.id,
128
+ status: "committed",
129
+ sourceChunkId: data.source_chunk_id,
130
+ };
131
+ }
132
+ // ─── rollbackCheckpoint ─────────────────────────────────────────────────────
133
+ //
134
+ // Walks the parent chain to find the deepest committed ancestor's
135
+ // source_chunk_id via the SQL helper terminal_committed_checkpoint, then
136
+ // marks the target row as rolledback. The replay anchor (if any) is
137
+ // returned so the caller can drive restoreFrom().
138
+ export async function rollbackCheckpoint(args) {
139
+ requireProjectId(args.projectId, "rollbackCheckpoint");
140
+ requireCheckpointId(args.checkpointId, "rollbackCheckpoint");
141
+ requireReason(args.reason, "rollbackCheckpoint");
142
+ console.log(`[M4] rollbackCheckpoint: project=${args.projectId} id=${args.checkpointId} reason=${args.reason}`);
143
+ // 1. Load the target row to discover its skill_id and parent_id so we can
144
+ // walk the chain from the parent (rolledback rows never anchor replay).
145
+ const { data: target, error: loadErr } = await supabase
146
+ .from("workflow_checkpoints")
147
+ .select("id, project_id, skill_id, parent_id, status")
148
+ .eq("id", args.checkpointId)
149
+ .eq("project_id", args.projectId)
150
+ .maybeSingle();
151
+ if (loadErr) {
152
+ throw new Error(`[M4] rollbackCheckpoint: lookup failed: ${loadErr.message}`);
153
+ }
154
+ if (!target) {
155
+ throw new Error(`[M4] rollbackCheckpoint: checkpoint ${args.checkpointId} not found in project ${args.projectId}`);
156
+ }
157
+ if (target.status === "rolledback") {
158
+ throw new Error(`[M4] rollbackCheckpoint: checkpoint ${args.checkpointId} is already rolledback`);
159
+ }
160
+ // 2. Find the replay anchor: deepest committed source_chunk_id reachable
161
+ // from the PARENT (not this row — we're rolling this one back).
162
+ // NULL parent = root rollback: no anchor exists.
163
+ let restoredFrom = null;
164
+ const parentId = typeof target.parent_id === "number" ? target.parent_id : null;
165
+ if (parentId !== null) {
166
+ const skillId = typeof target.skill_id === "number" ? target.skill_id : null;
167
+ const { data: rpcData, error: rpcErr } = await supabase.rpc("terminal_committed_checkpoint", {
168
+ p_project_id: args.projectId,
169
+ p_skill_id: skillId,
170
+ p_root_id: parentId,
171
+ });
172
+ if (rpcErr) {
173
+ throw new Error(`[M4] rollbackCheckpoint: terminal_committed_checkpoint RPC failed: ${rpcErr.message}`);
174
+ }
175
+ // Supabase RPC returns the scalar directly (PostgREST flattens single-column functions).
176
+ const sourceChunkId = typeof rpcData === "number"
177
+ ? rpcData
178
+ : Array.isArray(rpcData) && rpcData.length > 0 && typeof rpcData[0] === "number"
179
+ ? rpcData[0]
180
+ : null;
181
+ if (sourceChunkId !== null) {
182
+ restoredFrom = { checkpointId: parentId, sourceChunkId };
183
+ }
184
+ }
185
+ // 3. Mark this row rolledback. We use the same .eq() guard pattern as
186
+ // commit to prevent double-rollback races.
187
+ const { data, error } = await supabase
188
+ .from("workflow_checkpoints")
189
+ .update({
190
+ status: "rolledback",
191
+ rollback_reason: args.reason,
192
+ })
193
+ .eq("id", args.checkpointId)
194
+ .eq("project_id", args.projectId)
195
+ .neq("status", "rolledback")
196
+ .select("id, status")
197
+ .single();
198
+ if (error) {
199
+ throw new Error(`[M4] rollbackCheckpoint: update failed: ${error.message}`);
200
+ }
201
+ if (!data || typeof data.id !== "number") {
202
+ throw new Error(`[M4] rollbackCheckpoint: row not found or already rolledback (id=${args.checkpointId})`);
203
+ }
204
+ if (data.status !== "rolledback") {
205
+ throw new Error(`[M4] rollbackCheckpoint: unexpected status '${String(data.status)}'`);
206
+ }
207
+ return {
208
+ id: data.id,
209
+ status: "rolledback",
210
+ restoredFrom,
211
+ };
212
+ }
213
+ // ─── listCheckpoints ────────────────────────────────────────────────────────
214
+ export async function listCheckpoints(args) {
215
+ requireProjectId(args.projectId, "listCheckpoints");
216
+ const limit = args.limit === undefined ? 50 : args.limit;
217
+ if (!Number.isInteger(limit) || limit <= 0 || limit > 500) {
218
+ throw new Error(`[M4] listCheckpoints: limit must be an integer in (0, 500]`);
219
+ }
220
+ let q = supabase
221
+ .from("workflow_checkpoints")
222
+ .select("id, project_id, skill_id, step_index, step_label, parent_id, source_chunk_id, status, rollback_reason, created_at, committed_at")
223
+ .eq("project_id", args.projectId);
224
+ if (args.status !== undefined) {
225
+ q = q.eq("status", args.status);
226
+ }
227
+ if (args.skillId !== undefined && args.skillId !== null) {
228
+ q = q.eq("skill_id", args.skillId);
229
+ }
230
+ const { data, error } = await q
231
+ .order("id", { ascending: false })
232
+ .limit(limit);
233
+ if (error) {
234
+ throw new Error(`[M4] listCheckpoints: query failed: ${error.message}`);
235
+ }
236
+ return (data ?? []);
237
+ }
238
+ export async function restoreFrom(args) {
239
+ requireProjectId(args.projectId, "restoreFrom");
240
+ requireCheckpointId(args.checkpointId, "restoreFrom");
241
+ console.log(`[M4] restoreFrom: project=${args.projectId} id=${args.checkpointId}`);
242
+ const { data: row, error: loadErr } = await supabase
243
+ .from("workflow_checkpoints")
244
+ .select("id, source_chunk_id, status")
245
+ .eq("id", args.checkpointId)
246
+ .eq("project_id", args.projectId)
247
+ .maybeSingle();
248
+ if (loadErr) {
249
+ throw new Error(`[M4] restoreFrom: lookup failed: ${loadErr.message}`);
250
+ }
251
+ if (!row) {
252
+ throw new Error(`[M4] restoreFrom: checkpoint ${args.checkpointId} not found in project ${args.projectId}`);
253
+ }
254
+ const replayChunkId = typeof row.source_chunk_id === "number" ? row.source_chunk_id : null;
255
+ if (replayChunkId === null) {
256
+ return { replayChunkId: null, summary: null };
257
+ }
258
+ const { data: rpcData, error: rpcErr } = await supabase.rpc("get_trajectory_summary", { p_chunk_id: replayChunkId });
259
+ if (rpcErr) {
260
+ throw new Error(`[M4] restoreFrom: get_trajectory_summary RPC failed: ${rpcErr.message}`);
261
+ }
262
+ const rows = (rpcData ?? []);
263
+ if (rows.length === 0) {
264
+ // Checkpoint pinned a chunk but no summary exists yet (M2 daemon hasn't
265
+ // run on it, or summary was purged). Return the pointer without payload
266
+ // — caller can fall back to raw memory_chunks if desired.
267
+ return { replayChunkId, summary: null };
268
+ }
269
+ const first = rows[0];
270
+ return { replayChunkId, summary: first.summary };
271
+ }
272
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/transactions/checkpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ // Shared pending-verification flag used by the Hard Stop / Manual Test Gate.
2
+ // The MCP server writes this file after any code-producing tool call; the hook
3
+ // reads it to block subsequent destructive tool calls; confirm_verification
4
+ // clears it.
5
+ import { writeFile, rm, stat } from "node:fs/promises";
6
+ import { join } from "node:path";
7
+ import { tmpdir, homedir } from "node:os";
8
+ // TODO(v1.2.0): drop the legacy CLAUDE_MEMORY_GATE_DIR fallback after the Smart Claude Memory rebrand has settled.
9
+ // The on-disk dir `~/.claude-memory` is intentionally preserved to keep existing backups discoverable.
10
+ export const FLAG_DIR = process.env.SMART_CLAUDE_MEMORY_GATE_DIR ??
11
+ process.env.CLAUDE_MEMORY_GATE_DIR ??
12
+ join(homedir(), ".claude-memory");
13
+ export const FLAG_PATH = join(FLAG_DIR, "verification-pending.json");
14
+ export async function setPending(payload) {
15
+ await writeFile(FLAG_PATH, JSON.stringify(payload, null, 2), { flag: "w" }).catch(async () => {
16
+ // If the dir doesn't exist, create it via os.tmpdir fallback then retry at FLAG_DIR.
17
+ const { mkdir } = await import("node:fs/promises");
18
+ await mkdir(FLAG_DIR, { recursive: true });
19
+ await writeFile(FLAG_PATH, JSON.stringify(payload, null, 2));
20
+ });
21
+ }
22
+ export async function clearPending() {
23
+ try {
24
+ await rm(FLAG_PATH, { force: true });
25
+ return true;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ export async function getPending() {
32
+ try {
33
+ await stat(FLAG_PATH);
34
+ const { readFile } = await import("node:fs/promises");
35
+ const raw = await readFile(FLAG_PATH, "utf8");
36
+ return JSON.parse(raw);
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ void tmpdir; // satisfy ts lint; kept for future fallback
43
+ //# sourceMappingURL=verification-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification-gate.js","sourceRoot":"","sources":["../src/verification-gate.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAC5E,aAAa;AACb,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE1C,mHAAmH;AACnH,uGAAuG;AACvG,MAAM,CAAC,MAAM,QAAQ,GACnB,OAAO,CAAC,GAAG,CAAC,4BAA4B;IACxC,OAAO,CAAC,GAAG,CAAC,sBAAsB;IAClC,IAAI,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAC;AAUrE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAoB;IACnD,MAAM,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;QAC3F,qFAAqF;QACrF,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACnD,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,MAAM,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,MAAM,CAAC,CAAC,4CAA4C"}
@@ -0,0 +1,16 @@
1
+ // Single source of truth for the package version.
2
+ //
3
+ // All runtime version reporting (MCP server registration, check_system_health,
4
+ // delegate_task synthesis envelope) MUST import VERSION from here so the value
5
+ // stays in lock-step with package.json. Hard-coded literals are forbidden —
6
+ // they drift silently and make health reports lie.
7
+ //
8
+ // Mechanism: createRequire is the safest cross-Node, NodeNext-friendly way to
9
+ // load a JSON file from an ESM module. tsconfig has resolveJsonModule + the
10
+ // `import ... with { type: "json" }` form would also work, but createRequire
11
+ // avoids loader-flag friction across Node versions.
12
+ import { createRequire } from "node:module";
13
+ const require = createRequire(import.meta.url);
14
+ const pkg = require("../package.json");
15
+ export const VERSION = pkg.version;
16
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,mDAAmD;AACnD,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,oDAAoD;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAE9D,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC"}
@@ -0,0 +1,54 @@
1
+ # Hooks
2
+
3
+ Distributable Claude Code hooks that pair well with `smart-claude-memory`.
4
+
5
+ ## `md-policy.py`
6
+
7
+ Enforces a **Zero-Local-MD policy** in any project: only a whitelisted set of `.md` files may exist at the project root; everything else must live in cloud memory and be retrieved via `search_memory`.
8
+
9
+ ### What it does
10
+
11
+ - **Blocks** `Write`/`Edit` on any `.md` file outside the project root or outside the allowlist.
12
+ - **Warns** (does not block) when `CLAUDE.md` or `MEMORY.md` exceeds a soft token limit — your cue to prune.
13
+
14
+ ### Install per project
15
+
16
+ 1. Pick (or create) the target project's `.claude/settings.json` or `.claude/settings.local.json`.
17
+ 2. Add the hook entry:
18
+
19
+ ```json
20
+ {
21
+ "hooks": {
22
+ "PreToolUse": [
23
+ {
24
+ "matcher": "Write|Edit",
25
+ "hooks": [
26
+ {
27
+ "type": "command",
28
+ "command": "python \"/abs/path/to/smart-claude-memory/hooks/md-policy.py\""
29
+ }
30
+ ]
31
+ }
32
+ ]
33
+ },
34
+ "env": {
35
+ "CLAUDE_MD_POLICY_WORKSPACE": "/abs/path/to/your/project",
36
+ "CLAUDE_MD_POLICY_ALLOW_ROOT_MD": "CLAUDE.md,MEMORY.md,README.md",
37
+ "CLAUDE_MD_POLICY_TOKEN_LIMIT": "3000"
38
+ }
39
+ }
40
+ ```
41
+
42
+ 3. Restart Claude Code.
43
+
44
+ ### Environment variables
45
+
46
+ | Name | Default | Purpose |
47
+ |---|---|---|
48
+ | `CLAUDE_MD_POLICY_WORKSPACE` | — (required) | Absolute path of the project root the policy applies to. If unset, the hook no-ops. |
49
+ | `CLAUDE_MD_POLICY_ALLOW_ROOT_MD` | `CLAUDE.md,MEMORY.md,README.md` | Comma-separated filenames allowed at the root. |
50
+ | `CLAUDE_MD_POLICY_TOKEN_LIMIT` | `3000` | Soft limit for `CLAUDE.md` and `MEMORY.md`. Over → warn, never block. |
51
+
52
+ ### Failure mode
53
+
54
+ Any malformed input, missing env var, or unhandled exception resolves to `{"decision": "allow"}` — the hook never blocks through its own bugs.