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,33 @@
1
+ import { config } from "./config.js";
2
+ export function chunkMarkdown(md) {
3
+ const size = config.CHUNK_SIZE;
4
+ const overlap = config.CHUNK_OVERLAP;
5
+ const sections = md
6
+ .split(/\n(?=#{1,3}\s)/g)
7
+ .map((s) => s.trim())
8
+ .filter(Boolean);
9
+ const out = [];
10
+ let idx = 0;
11
+ for (const section of sections) {
12
+ const headingMatch = section.match(/^#{1,3}\s+(.+)/);
13
+ const heading = headingMatch?.[1]?.trim();
14
+ if (section.length <= size) {
15
+ out.push({ content: section, chunk_index: idx++, heading });
16
+ continue;
17
+ }
18
+ let cursor = 0;
19
+ while (cursor < section.length) {
20
+ const end = Math.min(cursor + size, section.length);
21
+ out.push({
22
+ content: section.slice(cursor, end),
23
+ chunk_index: idx++,
24
+ heading,
25
+ });
26
+ if (end === section.length)
27
+ break;
28
+ cursor = end - overlap;
29
+ }
30
+ }
31
+ return out;
32
+ }
33
+ //# sourceMappingURL=chunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC;IAErC,MAAM,QAAQ,GAAG,EAAE;SAChB,KAAK,CAAC,iBAAiB,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAE1C,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAC5D,SAAS;QACX,CAAC;QAED,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YACpD,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC;gBACnC,WAAW,EAAE,GAAG,EAAE;gBAClB,OAAO;aACR,CAAC,CAAC;YACH,IAAI,GAAG,KAAK,OAAO,CAAC,MAAM;gBAAE,MAAM;YAClC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,23 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { dirname, resolve } from "node:path";
3
+ import dotenv from "dotenv";
4
+ import { z } from "zod";
5
+ const here = dirname(fileURLToPath(import.meta.url));
6
+ dotenv.config({ path: resolve(here, "..", ".env"), quiet: true });
7
+ const Env = z.object({
8
+ SUPABASE_URL: z.string().url(),
9
+ SUPABASE_SECRET_KEY: z.string().min(10),
10
+ SUPABASE_DB_URL: z.string().min(10),
11
+ OLLAMA_HOST: z.string().url().default("http://localhost:11434"),
12
+ OLLAMA_EMBED_MODEL: z.string().default("nomic-embed-text"),
13
+ EMBED_DIM: z.coerce.number().int().positive().default(768),
14
+ MEMORY_ROOTS: z.string().min(1),
15
+ CHUNK_SIZE: z.coerce.number().int().positive().default(800),
16
+ CHUNK_OVERLAP: z.coerce.number().int().nonnegative().default(100),
17
+ });
18
+ export const config = Env.parse(process.env);
19
+ export const memoryRoots = config.MEMORY_ROOTS
20
+ .split(";")
21
+ .map((s) => s.trim())
22
+ .filter(Boolean);
23
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAElE,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC9B,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACvC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACnC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,wBAAwB,CAAC;IAC/D,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAC1D,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;IAC1D,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;IAC3D,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAE7C,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY;KAC3C,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;KACpB,MAAM,CAAC,OAAO,CAAC,CAAC"}
@@ -0,0 +1,190 @@
1
+ // Curriculum Daemon (Agentic OS 2026 / Mission 5 / SCM-S21-D1).
2
+ //
3
+ // Idle-time deterministic queuer. Every CURRICULUM_INTERVAL_MS, runs the
4
+ // three scanner sources (test_gap, rollback_repro, stale_candidate) and
5
+ // enqueues curriculum_tasks rows. The Orchestrator (Claude) pulls these
6
+ // stubs and writes code; the daemon never authors content.
7
+ //
8
+ // Boundary Invariant #1 (ARCHITECTURE.md §4.7): NO Ollama / Anthropic /
9
+ // OpenAI / generative imports. The CI lint fence asserts this.
10
+ //
11
+ // Style mirrors src/sleep/daemon.ts:
12
+ // * module-level state, .unref()'d interval, re-entrancy guard,
13
+ // try/finally tick so the loop NEVER throws.
14
+ import { currentProjectId } from "../project.js";
15
+ import { runScanOnce } from "./scanner.js";
16
+ import { emit } from "../telemetry/emit.js";
17
+ const DEFAULT_INTERVAL_MS = 3_600_000; // 1 h, staggered +30 min after sleep_learner
18
+ const DEFAULT_BATCH = 10;
19
+ const DEFAULT_MIN_FREQ = 3;
20
+ const DEFAULT_TTL_DAYS = 14;
21
+ const DEFAULT_TEST_GAP_PCT_CEILING = 50;
22
+ const DEFAULT_TEST_GAP_MIN_LINES = 100;
23
+ const DEFAULT_ROLLBACK_THRESHOLD = 3;
24
+ const DEFAULT_ROLLBACK_WINDOW_DAYS = 30;
25
+ const DEFAULT_STALE_CANDIDATE_MIN_AGE_DAYS = 7;
26
+ const state = {
27
+ timer: null,
28
+ enabled: false,
29
+ running: false,
30
+ intervalMs: DEFAULT_INTERVAL_MS,
31
+ batch: DEFAULT_BATCH,
32
+ minFreq: DEFAULT_MIN_FREQ,
33
+ ttlDays: DEFAULT_TTL_DAYS,
34
+ lastRunAt: null,
35
+ lastRunQueued: 0,
36
+ lastRunSkipped: 0,
37
+ lastRunErrored: 0,
38
+ lastRunDurationMs: 0,
39
+ queuedTotal: 0,
40
+ verifiedTotal: 0,
41
+ rejectedTotal: 0,
42
+ autoPromotionsTotal: 0,
43
+ };
44
+ // ─── env helpers (mirror src/sleep/daemon.ts) ─────────────────────────────
45
+ function readIntEnv(name, fallback) {
46
+ const raw = process.env[name];
47
+ if (raw === undefined)
48
+ return fallback;
49
+ const n = parseInt(raw, 10);
50
+ return Number.isFinite(n) && n > 0 ? n : fallback;
51
+ }
52
+ function resolveConfig() {
53
+ return {
54
+ intervalMs: readIntEnv("CURRICULUM_INTERVAL_MS", DEFAULT_INTERVAL_MS),
55
+ batch: readIntEnv("CURRICULUM_BATCH", DEFAULT_BATCH),
56
+ minFreq: readIntEnv("CURRICULUM_MIN_FREQ", DEFAULT_MIN_FREQ),
57
+ ttlDays: readIntEnv("CURRICULUM_TTL_DAYS", DEFAULT_TTL_DAYS),
58
+ testGapPctCeiling: readIntEnv("CURRICULUM_TEST_GAP_PCT", DEFAULT_TEST_GAP_PCT_CEILING),
59
+ testGapMinLines: readIntEnv("CURRICULUM_TEST_GAP_MIN_LINES", DEFAULT_TEST_GAP_MIN_LINES),
60
+ rollbackThreshold: readIntEnv("CURRICULUM_ROLLBACK_THRESHOLD", DEFAULT_ROLLBACK_THRESHOLD),
61
+ rollbackWindowDays: readIntEnv("CURRICULUM_ROLLBACK_WINDOW_DAYS", DEFAULT_ROLLBACK_WINDOW_DAYS),
62
+ staleCandidateMinAgeDays: readIntEnv("CURRICULUM_STALE_CANDIDATE_MIN_AGE_DAYS", DEFAULT_STALE_CANDIDATE_MIN_AGE_DAYS),
63
+ };
64
+ }
65
+ function buildScannerConfig() {
66
+ const cfg = resolveConfig();
67
+ return {
68
+ projectId: currentProjectId,
69
+ workspace: process.cwd(),
70
+ minFreq: cfg.minFreq,
71
+ ttlDays: cfg.ttlDays,
72
+ testGapCoveragePctCeiling: cfg.testGapPctCeiling,
73
+ testGapMinLines: cfg.testGapMinLines,
74
+ rollbackThreshold: cfg.rollbackThreshold,
75
+ rollbackWindowDays: cfg.rollbackWindowDays,
76
+ staleCandidateMinAgeDays: cfg.staleCandidateMinAgeDays,
77
+ };
78
+ }
79
+ // ─── runScanOnce wrapper (publicly callable for smoke tests) ──────────────
80
+ export async function runCurriculumScanOnce() {
81
+ const scannerCfg = buildScannerConfig();
82
+ const result = await runScanOnce(scannerCfg);
83
+ return {
84
+ total_enqueued: result.total_enqueued,
85
+ total_skipped: result.total_skipped,
86
+ total_errored: result.total_errored,
87
+ duration_ms: result.duration_ms,
88
+ per_source: result.per_source,
89
+ };
90
+ }
91
+ // ─── daemon tick ──────────────────────────────────────────────────────────
92
+ async function tick() {
93
+ if (state.running)
94
+ return;
95
+ state.running = true;
96
+ const __tStart = Date.now();
97
+ void emit({ daemon: "curriculum_scanner", event: "run_started" });
98
+ try {
99
+ const r = await runCurriculumScanOnce();
100
+ state.lastRunQueued = r.total_enqueued;
101
+ state.lastRunSkipped = r.total_skipped;
102
+ state.lastRunErrored = r.total_errored;
103
+ state.lastRunDurationMs = r.duration_ms;
104
+ state.lastRunAt = new Date().toISOString();
105
+ state.queuedTotal += r.total_enqueued;
106
+ void emit({
107
+ daemon: "curriculum_scanner",
108
+ event: "run_ended",
109
+ payload: {
110
+ queued: state.lastRunQueued,
111
+ skipped: state.lastRunSkipped,
112
+ errored: state.lastRunErrored,
113
+ duration_ms: Date.now() - __tStart,
114
+ },
115
+ });
116
+ }
117
+ catch (err) {
118
+ state.lastRunErrored++;
119
+ state.lastRunAt = new Date().toISOString();
120
+ void emit({
121
+ daemon: "curriculum_scanner",
122
+ event: "run_errored",
123
+ payload: {
124
+ error_message: err instanceof Error ? err.message : String(err),
125
+ duration_ms: Date.now() - __tStart,
126
+ },
127
+ });
128
+ }
129
+ finally {
130
+ state.running = false;
131
+ }
132
+ }
133
+ // ─── public start/stop ────────────────────────────────────────────────────
134
+ export function startCurriculumDaemon() {
135
+ if (state.timer)
136
+ return;
137
+ const cfg = resolveConfig();
138
+ state.intervalMs = cfg.intervalMs;
139
+ state.batch = cfg.batch;
140
+ state.minFreq = cfg.minFreq;
141
+ state.ttlDays = cfg.ttlDays;
142
+ state.enabled = true;
143
+ state.timer = setInterval(() => {
144
+ if (state.running)
145
+ return;
146
+ void tick();
147
+ }, state.intervalMs);
148
+ state.timer.unref();
149
+ }
150
+ export function stopCurriculumDaemon() {
151
+ if (state.timer)
152
+ clearInterval(state.timer);
153
+ state.timer = null;
154
+ state.enabled = false;
155
+ }
156
+ // ─── stats incrementers (called by tools/curriculum.ts on apply) ──────────
157
+ export function recordVerified(autoPromoted) {
158
+ state.verifiedTotal++;
159
+ if (autoPromoted)
160
+ state.autoPromotionsTotal++;
161
+ void emit({ daemon: "curriculum_scanner", event: "task_outcome", payload: { verified: 1 } });
162
+ if (autoPromoted) {
163
+ void emit({ daemon: "curriculum_scanner", event: "task_outcome", payload: { auto_promoted: 1 } });
164
+ }
165
+ }
166
+ export function recordRejected() {
167
+ state.rejectedTotal++;
168
+ void emit({ daemon: "curriculum_scanner", event: "task_outcome", payload: { rejected: 1 } });
169
+ }
170
+ export function getCurriculumStatus() {
171
+ return {
172
+ running: state.running,
173
+ enabled: state.enabled,
174
+ interval_ms: state.intervalMs,
175
+ batch: state.batch,
176
+ min_freq: state.minFreq,
177
+ ttl_days: state.ttlDays,
178
+ last_run_at: state.lastRunAt,
179
+ last_run_queued: state.lastRunQueued,
180
+ last_run_skipped: state.lastRunSkipped,
181
+ last_run_errored: state.lastRunErrored,
182
+ last_run_duration_ms: state.lastRunDurationMs,
183
+ queued_total: state.queuedTotal,
184
+ verified_total: state.verifiedTotal,
185
+ rejected_total: state.rejectedTotal,
186
+ auto_promotions_total: state.autoPromotionsTotal,
187
+ };
188
+ }
189
+ export const runCurriculumScannerOnce = tick;
190
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/curriculum/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,237 @@
1
+ // Curriculum Scanner (Agentic OS 2026 / Mission 5 / SCM-S21-D1).
2
+ //
3
+ // Deterministic queuer. Reads file-system + Supabase signals and enqueues
4
+ // curriculum_tasks rows. CONTAINS ZERO GENERATIVE AI — no Ollama import,
5
+ // no LLM HTTP client, no name/steps/code generation. The Orchestrator
6
+ // (Claude) authors all downstream content.
7
+ //
8
+ // Boundary Invariant #1 (ARCHITECTURE.md §4.7): this module must remain
9
+ // pure SQL aggregates + filesystem reads. The CI lint fence asserts no
10
+ // imports from ollama / @anthropic-ai / openai / any /generate endpoint.
11
+ //
12
+ // Three signal sources:
13
+ // * scanTestGaps() — reads coverage-summary.json (optional file)
14
+ // and enqueues files with low coverage + size.
15
+ // * scanRollbackHotspots() — SQL aggregate over workflow_checkpoints
16
+ // with status='rolledback' in the last 30 days.
17
+ // * scanStaleCandidates() — SQL select over skill_candidates with
18
+ // state='mined' AND frequency >= N AND aged.
19
+ // ONLY this source sets linked_candidate_id,
20
+ // i.e. only this source can trigger M3
21
+ // auto-promote on a verified apply.
22
+ import { readFile } from "node:fs/promises";
23
+ import { resolve } from "node:path";
24
+ import { supabase } from "../supabase.js";
25
+ // ─── shared: enqueue helper wrapping the SQL RPC ──────────────────────────
26
+ async function enqueue(projectId, kind, targetPath, rationale, signalSource, linkedCandidateId, expiresAt) {
27
+ const { data, error } = await supabase.rpc("enqueue_curriculum_task", {
28
+ p_project_id: projectId,
29
+ p_kind: kind,
30
+ p_target_path: targetPath,
31
+ p_rationale: rationale,
32
+ p_signal_source: signalSource,
33
+ p_linked_candidate_id: linkedCandidateId,
34
+ p_expires_at: expiresAt,
35
+ });
36
+ if (error) {
37
+ throw new Error(`enqueue_curriculum_task failed: ${error.message}`);
38
+ }
39
+ const rows = (data ?? []);
40
+ if (rows.length === 0) {
41
+ throw new Error("enqueue_curriculum_task returned no rows");
42
+ }
43
+ return rows[0];
44
+ }
45
+ function computeExpiresAt(ttlDays) {
46
+ if (ttlDays <= 0)
47
+ return null;
48
+ const expires = new Date(Date.now() + ttlDays * 24 * 60 * 60 * 1000);
49
+ return expires.toISOString();
50
+ }
51
+ export async function scanTestGaps(cfg) {
52
+ const result = {
53
+ source: "test_gap",
54
+ scanned: 0,
55
+ enqueued: 0,
56
+ skipped: 0,
57
+ errored: 0,
58
+ };
59
+ const coveragePath = resolve(cfg.workspace, "coverage", "coverage-summary.json");
60
+ let raw;
61
+ try {
62
+ raw = await readFile(coveragePath, "utf8");
63
+ }
64
+ catch {
65
+ // No coverage file present → no test_gap signals this cycle. Not an error.
66
+ return result;
67
+ }
68
+ let report;
69
+ try {
70
+ report = JSON.parse(raw);
71
+ }
72
+ catch (e) {
73
+ result.errored++;
74
+ return result;
75
+ }
76
+ const expiresAt = computeExpiresAt(cfg.ttlDays);
77
+ for (const [filePath, summary] of Object.entries(report)) {
78
+ if (filePath === "total" || summary === undefined)
79
+ continue;
80
+ result.scanned++;
81
+ const pct = summary.lines?.pct;
82
+ const total = summary.lines?.total;
83
+ if (typeof pct !== "number" || typeof total !== "number") {
84
+ result.skipped++;
85
+ continue;
86
+ }
87
+ if (pct >= cfg.testGapCoveragePctCeiling) {
88
+ result.skipped++;
89
+ continue;
90
+ }
91
+ if (total < cfg.testGapMinLines) {
92
+ result.skipped++;
93
+ continue;
94
+ }
95
+ try {
96
+ const r = await enqueue(cfg.projectId, "test_gap", filePath, `coverage ${pct.toFixed(1)}%, ${total} lines (ceiling ${cfg.testGapCoveragePctCeiling}%, min ${cfg.testGapMinLines})`, {
97
+ coverage_pct: pct,
98
+ line_total: total,
99
+ scanned_at: new Date().toISOString(),
100
+ }, null, expiresAt);
101
+ if (r.is_new)
102
+ result.enqueued++;
103
+ else
104
+ result.skipped++;
105
+ }
106
+ catch {
107
+ result.errored++;
108
+ }
109
+ }
110
+ return result;
111
+ }
112
+ export async function scanRollbackHotspots(cfg) {
113
+ const result = {
114
+ source: "rollback_repro",
115
+ scanned: 0,
116
+ enqueued: 0,
117
+ skipped: 0,
118
+ errored: 0,
119
+ };
120
+ // The PostgREST query: GROUP BY step_label, HAVING count >= threshold,
121
+ // within rollbackWindowDays. step_label is the orchestrator's free-text
122
+ // anchor — it is what carries the file/module reference inside a workflow.
123
+ // We treat step_label as target_path. No LLM interpretation needed.
124
+ const since = new Date(Date.now() - cfg.rollbackWindowDays * 24 * 60 * 60 * 1000).toISOString();
125
+ const { data, error } = await supabase
126
+ .from("workflow_checkpoints")
127
+ .select("step_label, created_at")
128
+ .eq("project_id", cfg.projectId)
129
+ .eq("status", "rolledback")
130
+ .gte("created_at", since);
131
+ if (error) {
132
+ result.errored++;
133
+ return result;
134
+ }
135
+ const counts = new Map();
136
+ for (const row of (data ?? [])) {
137
+ result.scanned++;
138
+ const label = (row.step_label ?? "").trim();
139
+ if (!label) {
140
+ result.skipped++;
141
+ continue;
142
+ }
143
+ counts.set(label, (counts.get(label) ?? 0) + 1);
144
+ }
145
+ const expiresAt = computeExpiresAt(cfg.ttlDays);
146
+ for (const [label, count] of counts.entries()) {
147
+ if (count < cfg.rollbackThreshold) {
148
+ result.skipped++;
149
+ continue;
150
+ }
151
+ try {
152
+ const r = await enqueue(cfg.projectId, "rollback_repro", label, `${count} rollback(s) in last ${cfg.rollbackWindowDays} days (threshold ${cfg.rollbackThreshold})`, {
153
+ rollback_count: count,
154
+ window_days: cfg.rollbackWindowDays,
155
+ scanned_at: new Date().toISOString(),
156
+ }, null, expiresAt);
157
+ if (r.is_new)
158
+ result.enqueued++;
159
+ else
160
+ result.skipped++;
161
+ }
162
+ catch {
163
+ result.errored++;
164
+ }
165
+ }
166
+ return result;
167
+ }
168
+ export async function scanStaleCandidates(cfg) {
169
+ const result = {
170
+ source: "stale_candidate",
171
+ scanned: 0,
172
+ enqueued: 0,
173
+ skipped: 0,
174
+ errored: 0,
175
+ };
176
+ const ageCutoff = new Date(Date.now() - cfg.staleCandidateMinAgeDays * 24 * 60 * 60 * 1000).toISOString();
177
+ const { data, error } = await supabase
178
+ .from("skill_candidates")
179
+ .select("id, project_id, pattern_hash, proposed_name, frequency, success_count, created_at")
180
+ .eq("project_id", cfg.projectId)
181
+ .eq("state", "mined")
182
+ .gte("frequency", cfg.minFreq)
183
+ .lte("created_at", ageCutoff);
184
+ if (error) {
185
+ result.errored++;
186
+ return result;
187
+ }
188
+ const expiresAt = computeExpiresAt(cfg.ttlDays);
189
+ const rows = (data ?? []);
190
+ for (const row of rows) {
191
+ result.scanned++;
192
+ // target_path here is the candidate's pattern_hash — a stable
193
+ // identifier the orchestrator can resolve back to the candidate
194
+ // via signal_source.candidate_id. We do NOT invent a filesystem
195
+ // path; this is the deterministic-queue contract.
196
+ const targetPath = `skill_candidate:${row.pattern_hash}`;
197
+ const rationale = `mined candidate freq=${row.frequency}, success=${row.success_count}, age>${cfg.staleCandidateMinAgeDays}d`;
198
+ try {
199
+ const r = await enqueue(cfg.projectId, "refactor", targetPath, rationale, {
200
+ candidate_id: row.id,
201
+ frequency: row.frequency,
202
+ success_count: row.success_count,
203
+ proposed_name: row.proposed_name,
204
+ scanned_at: new Date().toISOString(),
205
+ }, row.id, expiresAt);
206
+ if (r.is_new)
207
+ result.enqueued++;
208
+ else
209
+ result.skipped++;
210
+ }
211
+ catch {
212
+ result.errored++;
213
+ }
214
+ }
215
+ return result;
216
+ }
217
+ // ─── orchestration: runScanOnce ───────────────────────────────────────────
218
+ export async function runScanOnce(cfg) {
219
+ const t0 = Date.now();
220
+ const perSource = [];
221
+ // Three sources run sequentially — Supabase HTTPS pool is small and the
222
+ // scanner is idle-time work; no need to parallelize.
223
+ perSource.push(await scanTestGaps(cfg));
224
+ perSource.push(await scanRollbackHotspots(cfg));
225
+ perSource.push(await scanStaleCandidates(cfg));
226
+ const total_enqueued = perSource.reduce((s, r) => s + r.enqueued, 0);
227
+ const total_skipped = perSource.reduce((s, r) => s + r.skipped, 0);
228
+ const total_errored = perSource.reduce((s, r) => s + r.errored, 0);
229
+ return {
230
+ total_enqueued,
231
+ total_skipped,
232
+ total_errored,
233
+ per_source: perSource,
234
+ duration_ms: Date.now() - t0,
235
+ };
236
+ }
237
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/curriculum/scanner.ts"],"names":[],"mappings":"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"}