@shahmilsaari/memory-core 1.0.33 → 1.0.35

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 (53) hide show
  1. package/README.md +8 -6
  2. package/dist/{approval-queue-YBYRGBHP.js → approval-queue-4RK46FNE.js} +2 -1
  3. package/dist/{ast-analyzer-JM4CIOFY.js → ast-analyzer-WGTJKGAP.js} +1 -0
  4. package/dist/{check-cache-6NWRTZJD.js → check-cache-ZVFHTA2C.js} +1 -0
  5. package/dist/{check-logger-5HYSWA3S.js → check-logger-F4DW4LBY.js} +1 -0
  6. package/dist/chunk-2LNDQGDD.js +37 -0
  7. package/dist/{chunk-23GUWJ6F.js → chunk-4QWIYO2G.js} +3071 -3271
  8. package/dist/{chunk-GIPKVQSA.js → chunk-5T2QBBYT.js} +3 -29
  9. package/dist/chunk-FPRSYCOZ.js +77 -0
  10. package/dist/chunk-HJCPBM7B.js +238 -0
  11. package/dist/chunk-K3NQKI34.js +10 -0
  12. package/dist/chunk-SKR44CRD.js +35 -0
  13. package/dist/{chunk-W6WEAV3S.js → chunk-UMYJQWIE.js} +13 -11
  14. package/dist/{chunk-PQBWHAZN.js → chunk-XAE3RY5D.js} +5 -2
  15. package/dist/{classifier-MZ65R7FK.js → classifier-D5K3X7FQ.js} +1 -0
  16. package/dist/cli.js +246 -82
  17. package/dist/{confidence-gate-ZQDAOS6P.js → confidence-gate-AT2MW4NK.js} +8 -6
  18. package/dist/dashboard/assets/index-BcDOsQwz.css +1 -0
  19. package/dist/dashboard/assets/index-DGx4sRHq.js +2 -0
  20. package/dist/dashboard/index.html +2 -2
  21. package/dist/{dashboard-server-LWMXEJHE.js → dashboard-server-UBZHOPRC.js} +273 -20
  22. package/dist/{db-FLFZZXG3.js → db-RE23O4DV.js} +3 -1
  23. package/dist/{deterministic-validator-PP56B46I.js → deterministic-validator-3LB234OG.js} +1 -0
  24. package/dist/draft-rule-NUXOSRRS.js +11 -0
  25. package/dist/embedding-VIMV6O2P.js +9 -0
  26. package/dist/{evidence-HVMSONTT.js → evidence-WFMGWSOP.js} +1 -0
  27. package/dist/{graph-TFNTB5OK.js → graph-UJJAKNHD.js} +1 -0
  28. package/dist/{incident-capture-RVPZULS7.js → incident-capture-5YUVJJM3.js} +11 -0
  29. package/dist/mcp-server-3N7R46BS.js +14958 -0
  30. package/dist/memory-selection-A5CQ6ZT5.js +29 -0
  31. package/dist/{deepseek-critique-MALVIYGF.js → model-critique-E2GNZ42U.js} +18 -32
  32. package/dist/{ollama-judge-D2LFK5PB.js → ollama-judge-6ZEZN4JV.js} +29 -41
  33. package/dist/{rate-limiter-SLIPCXRF.js → rate-limiter-KIMXTAAU.js} +1 -0
  34. package/dist/{rules-V3QMN3AR.js → rules-UUVIKEDM.js} +1 -0
  35. package/dist/{watch-errors-B3FA26N4.js → watch-errors-DZMW3CFN.js} +28 -33
  36. package/package.json +2 -1
  37. package/templates/AGENTS.md.hbs +11 -27
  38. package/templates/AI_RULES.md.hbs +9 -23
  39. package/templates/ARCHITECTURE.md.hbs +9 -30
  40. package/templates/CLAUDE.md.hbs +10 -35
  41. package/templates/DEVIN.md.hbs +7 -16
  42. package/templates/PROJECT_MEMORY.md.hbs +5 -21
  43. package/templates/amazonq-guidelines.md.hbs +7 -16
  44. package/templates/clinerules.hbs +8 -17
  45. package/templates/copilot-instructions.md.hbs +7 -16
  46. package/templates/cursor-rule.mdc.hbs +4 -9
  47. package/templates/cursorrules.hbs +8 -14
  48. package/templates/gemini-styleguide.md.hbs +7 -16
  49. package/templates/jetbrains-ai.md.hbs +6 -15
  50. package/templates/roo-rule.md.hbs +6 -15
  51. package/templates/windsurfrules.hbs +9 -18
  52. package/dist/dashboard/assets/index-DqbNcMwV.js +0 -2
  53. package/dist/dashboard/assets/index-y7eHWJtq.css +0 -1
@@ -1,17 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  buildArchRules,
4
- buildLayersTemplate,
4
+ buildLayersTemplate
5
+ } from "./chunk-HJCPBM7B.js";
6
+ import {
5
7
  detectProject,
6
- embed,
7
8
  inferProjectArchitectures,
8
9
  startWatch
9
- } from "./chunk-23GUWJ6F.js";
10
+ } from "./chunk-4QWIYO2G.js";
11
+ import "./chunk-ZZBQEXEO.js";
10
12
  import {
11
- getChatProviderLabel
12
- } from "./chunk-PQBWHAZN.js";
13
+ embed
14
+ } from "./chunk-SKR44CRD.js";
13
15
  import {
14
- Config,
15
16
  closePool,
16
17
  countUsers,
17
18
  createUser,
@@ -19,6 +20,7 @@ import {
19
20
  deleteMemory,
20
21
  deleteUser,
21
22
  getArchProfile,
23
+ getMemory,
22
24
  getPool,
23
25
  getUserByEmail,
24
26
  listArchProfiles,
@@ -27,13 +29,21 @@ import {
27
29
  saveArchProfile,
28
30
  saveMemory,
29
31
  updateLastLogin,
30
- updateMemory
31
- } from "./chunk-GIPKVQSA.js";
32
- import "./chunk-ZZBQEXEO.js";
32
+ updateMemory,
33
+ upsertMemory
34
+ } from "./chunk-5T2QBBYT.js";
35
+ import {
36
+ Config
37
+ } from "./chunk-2LNDQGDD.js";
38
+ import {
39
+ callChatModel,
40
+ getChatProviderLabel
41
+ } from "./chunk-XAE3RY5D.js";
42
+ import "./chunk-K3NQKI34.js";
33
43
 
34
44
  // src/dashboard-server.ts
35
45
  import { createHash } from "crypto";
36
- import { execSync } from "child_process";
46
+ import { execFileSync } from "child_process";
37
47
  import { createReadStream, existsSync, mkdirSync, readFileSync, watch, writeFileSync } from "fs";
38
48
  import { createServer } from "http";
39
49
  import { basename, dirname, extname, join, normalize, relative, resolve } from "path";
@@ -88,6 +98,8 @@ var watcherStatus = {
88
98
  };
89
99
  var RUNTIME_ENV_KEYS = [
90
100
  "DATABASE_URL",
101
+ "EMBEDDING_URL",
102
+ "EMBEDDING_MODEL",
91
103
  "OLLAMA_URL",
92
104
  "OLLAMA_MODEL",
93
105
  "CHAT_PROVIDER",
@@ -127,7 +139,7 @@ function readViolationHistory() {
127
139
  }
128
140
  function getGitAuthor(file) {
129
141
  try {
130
- return execSync(`git log --format="%an" -1 -- "${file}"`, { cwd: projectRoot, stdio: ["ignore", "pipe", "ignore"], timeout: 2e3 }).toString().trim() || void 0;
142
+ return execFileSync("git", ["log", "--format=%an", "-1", "--", file], { cwd: projectRoot, stdio: ["ignore", "pipe", "ignore"], timeout: 2e3 }).toString().trim() || void 0;
131
143
  } catch {
132
144
  return void 0;
133
145
  }
@@ -144,14 +156,65 @@ function appendViolationHistory(file, violations, timestamp) {
144
156
  } catch {
145
157
  }
146
158
  }
159
+ function settingsPath() {
160
+ return join(projectRoot, ".archmind", "dashboard-settings.json");
161
+ }
162
+ var DEFAULT_SETTINGS = {
163
+ autoFix: false,
164
+ verbose: false,
165
+ debug: false,
166
+ scanOnStart: false
167
+ };
168
+ var cachedSettings = null;
169
+ function readSettings() {
170
+ if (cachedSettings) return cachedSettings;
171
+ const path = settingsPath();
172
+ if (!existsSync(path)) {
173
+ cachedSettings = { ...DEFAULT_SETTINGS };
174
+ return cachedSettings;
175
+ }
176
+ try {
177
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
178
+ cachedSettings = { ...DEFAULT_SETTINGS, ...parsed };
179
+ } catch {
180
+ cachedSettings = { ...DEFAULT_SETTINGS };
181
+ }
182
+ return cachedSettings;
183
+ }
184
+ function writeSettings(next) {
185
+ try {
186
+ const archmindDir = join(projectRoot, ".archmind");
187
+ mkdirSync(archmindDir, { recursive: true });
188
+ writeFileSync(settingsPath(), JSON.stringify(next, null, 2), "utf-8");
189
+ cachedSettings = next;
190
+ } catch {
191
+ }
192
+ }
193
+ function markFileResolved(file, timestamp) {
194
+ try {
195
+ const history = readViolationHistory();
196
+ let changed = false;
197
+ for (const entry of history) {
198
+ if (entry.file === file && !entry.resolved) {
199
+ entry.resolved = true;
200
+ entry.resolvedAt = timestamp;
201
+ changed = true;
202
+ }
203
+ }
204
+ if (changed) {
205
+ writeFileSync(historyPath(), JSON.stringify(history, null, 2), "utf-8");
206
+ }
207
+ } catch {
208
+ }
209
+ }
147
210
  function readArchState() {
148
211
  const archmindDir = join(projectRoot, ".archmind");
149
212
  const queuePath = join(archmindDir, "approval-queue.json");
150
213
  const rulesPath = join(archmindDir, "rules.json");
151
214
  const layersPath = join(archmindDir, "layers.json");
152
215
  try {
153
- const queue = readJsonFile(queuePath, {});
154
- archState.pendingRules = Array.isArray(queue.items) ? queue.items.length : 0;
216
+ const queue = existsSync(queuePath) ? JSON.parse(readFileSync(queuePath, "utf-8")) : [];
217
+ archState.pendingRules = Array.isArray(queue) ? queue.filter((i) => i.status === "pending").length : 0;
155
218
  } catch {
156
219
  archState.pendingRules = 0;
157
220
  }
@@ -364,8 +427,8 @@ function buildModelStatusCacheKey() {
364
427
  return [
365
428
  Config.chatProvider,
366
429
  Config.chatModel,
367
- Config.ollamaModel,
368
- Config.ollamaUrl,
430
+ Config.embeddingModel,
431
+ Config.embeddingUrl,
369
432
  Config.chatApiKey ? "key:set" : "key:empty"
370
433
  ].join("|");
371
434
  }
@@ -377,8 +440,8 @@ async function getModelStatus(forceRefresh = false) {
377
440
  }
378
441
  const provider = Config.chatProvider;
379
442
  const checkModel = Config.chatModel;
380
- const embeddingModel = Config.ollamaModel;
381
- const ollamaUrl = Config.ollamaUrl;
443
+ const embeddingModel = Config.embeddingModel;
444
+ const ollamaUrl = Config.embeddingUrl;
382
445
  const status = {
383
446
  provider,
384
447
  checkModel,
@@ -668,6 +731,87 @@ async function handleApi(req, res, url) {
668
731
  scheduleSnapshotBroadcast({ delayMs: 0, forceBaseRefresh: true });
669
732
  return;
670
733
  }
734
+ if (req.method === "POST" && url.pathname.endsWith("/check")) {
735
+ const checkMatch = url.pathname.match(/^\/api\/memories\/(\d+)\/check$/);
736
+ if (!checkMatch) {
737
+ sendJson(res, 400, { error: "Invalid path" });
738
+ return;
739
+ }
740
+ const id = Number(checkMatch[1]);
741
+ const memory = await getMemory(id);
742
+ if (!memory) {
743
+ sendJson(res, 404, { error: `No memory found with ID ${id}` });
744
+ return;
745
+ }
746
+ const config = readProjectConfig();
747
+ const architectures = inferProjectArchitectures(projectRoot, config);
748
+ const projectInfo = [
749
+ `Project: ${config?.projectName ?? "unknown"}`,
750
+ `Type: ${config?.projectType ?? "unknown"}`,
751
+ config?.backendArchitecture ? `Backend: ${config.backendArchitecture}` : "",
752
+ config?.frontendFramework ? `Frontend: ${config.frontendFramework}` : "",
753
+ config?.language ? `Language: ${config.language}` : ""
754
+ ].filter(Boolean).join(", ");
755
+ const systemPrompt = 'Audit memory rule quality. Return JSON: {"status":"valid|stale|duplicate|vague","confidence":0.X,"reasoning":"","suggestion":"","issues":[]}. stale=outdated APIs/patterns. duplicate=says what other rules say. vague=not actionable.';
756
+ const truncatedContent = memory.content.length > 800 ? `${memory.content.slice(0, 800)}\u2026[truncated]` : memory.content;
757
+ const userPrompt = [
758
+ `Project: ${projectInfo}`,
759
+ `Arch: ${architectures.join(",") || "none"}`,
760
+ `Type: ${memory.type} | Scope: ${memory.scope} | Architecture: ${memory.architecture ?? "none"}`,
761
+ `Tags: ${(memory.tags ?? []).join(",") || "none"}`,
762
+ memory.title ? `Title: ${memory.title}` : "",
763
+ "",
764
+ truncatedContent
765
+ ].filter(Boolean).join("\n");
766
+ try {
767
+ const result = await callChatModel([
768
+ { role: "system", content: systemPrompt, cache: true },
769
+ { role: "user", content: userPrompt }
770
+ ], { timeoutMs: 3e4 });
771
+ const trimmed = result.content.trim();
772
+ const jsonMatch = trimmed.match(/(?:```(?:json)?\s*)?(\{[\s\S]*\})(?:\s*```)?/);
773
+ const parsed = jsonMatch ? JSON.parse(jsonMatch[1]) : JSON.parse(trimmed);
774
+ sendJson(res, 200, {
775
+ id: memory.id,
776
+ status: parsed.status ?? "unknown",
777
+ confidence: typeof parsed.confidence === "number" ? parsed.confidence : 0,
778
+ reasoning: parsed.reasoning ?? "",
779
+ suggestion: parsed.suggestion ?? "",
780
+ issues: Array.isArray(parsed.issues) ? parsed.issues : [],
781
+ memory
782
+ });
783
+ } catch (err) {
784
+ sendJson(res, 500, { error: `Model check failed: ${err.message}` });
785
+ }
786
+ return;
787
+ }
788
+ if (req.method === "POST" && url.pathname.endsWith("/apply-suggestion")) {
789
+ const applyMatch = url.pathname.match(/^\/api\/memories\/(\d+)\/apply-suggestion$/);
790
+ if (!applyMatch) {
791
+ sendJson(res, 400, { error: "Invalid path" });
792
+ return;
793
+ }
794
+ const id = Number(applyMatch[1]);
795
+ const body = await readBody(req);
796
+ const content = typeof body.content === "string" ? body.content.trim() : "";
797
+ if (!content) {
798
+ sendJson(res, 400, { error: "content is required" });
799
+ return;
800
+ }
801
+ const updated = await updateMemory(id, {
802
+ content,
803
+ reason: typeof body.reason === "string" && body.reason.trim() ? body.reason.trim() : void 0,
804
+ embedding: await embed(content)
805
+ });
806
+ if (!updated) {
807
+ sendJson(res, 404, { error: `No memory found with ID ${id}` });
808
+ return;
809
+ }
810
+ sendJson(res, 200, updated);
811
+ invalidateSnapshotBase();
812
+ scheduleSnapshotBroadcast({ delayMs: 0, forceBaseRefresh: true });
813
+ return;
814
+ }
671
815
  if (req.method === "POST" && url.pathname === "/api/config/model") {
672
816
  const body = await readBody(req);
673
817
  const provider = typeof body.provider === "string" && body.provider.trim() ? body.provider.trim() : null;
@@ -704,7 +848,7 @@ async function handleApi(req, res, url) {
704
848
  const warnings = [];
705
849
  if (effectiveProvider === "ollama") {
706
850
  try {
707
- const ollamaUrl = process.env.OLLAMA_URL ?? "http://localhost:11434";
851
+ const ollamaUrl = Config.embeddingUrl;
708
852
  const r = await fetch(`${ollamaUrl}/api/tags`, { signal: AbortSignal.timeout(5e3) });
709
853
  if (!r.ok) warnings.push(`Ollama returned HTTP ${r.status}`);
710
854
  } catch (err) {
@@ -808,13 +952,30 @@ async function handleApi(req, res, url) {
808
952
  teamActivity,
809
953
  summary: {
810
954
  total: history.reduce((s, e) => s + e.violations.length, 0),
811
- resolved: history.filter((e) => e.resolved).length,
812
- open: history.filter((e) => !e.resolved).length,
955
+ resolved: history.filter((e) => e.resolved).reduce((s, e) => s + e.violations.length, 0),
956
+ open: history.filter((e) => !e.resolved).reduce((s, e) => s + e.violations.length, 0),
813
957
  uniqueFiles: new Set(history.map((e) => e.file)).size
814
958
  }
815
959
  });
816
960
  return;
817
961
  }
962
+ if (req.method === "GET" && url.pathname === "/api/settings") {
963
+ sendJson(res, 200, readSettings());
964
+ return;
965
+ }
966
+ if (req.method === "POST" && url.pathname === "/api/settings") {
967
+ const body = await readBody(req);
968
+ const current = readSettings();
969
+ const next = {
970
+ autoFix: typeof body.autoFix === "boolean" ? body.autoFix : current.autoFix,
971
+ verbose: typeof body.verbose === "boolean" ? body.verbose : current.verbose,
972
+ debug: typeof body.debug === "boolean" ? body.debug : current.debug,
973
+ scanOnStart: typeof body.scanOnStart === "boolean" ? body.scanOnStart : current.scanOnStart
974
+ };
975
+ writeSettings(next);
976
+ sendJson(res, 200, next);
977
+ return;
978
+ }
818
979
  if (req.method === "DELETE" && url.pathname === "/api/history") {
819
980
  try {
820
981
  const path = historyPath();
@@ -1145,6 +1306,53 @@ async function handleApi(req, res, url) {
1145
1306
  sendJson(res, deleted ? 200 : 404, deleted ? { ok: true } : { error: "User not found" });
1146
1307
  return;
1147
1308
  }
1309
+ if (req.method === "GET" && url.pathname === "/api/proposals") {
1310
+ const queuePath = join(projectRoot, ".archmind", "approval-queue.json");
1311
+ const items = existsSync(queuePath) ? JSON.parse(readFileSync(queuePath, "utf-8")) : [];
1312
+ const pending = Array.isArray(items) ? items.filter((i) => i.status === "pending") : [];
1313
+ sendJson(res, 200, { proposals: pending });
1314
+ return;
1315
+ }
1316
+ const proposalMatch = url.pathname.match(/^\/api\/proposals\/([^/]+)\/(approve|reject)$/);
1317
+ if (proposalMatch && req.method === "POST") {
1318
+ const [, id, action] = proposalMatch;
1319
+ const queuePath = join(projectRoot, ".archmind", "approval-queue.json");
1320
+ if (!existsSync(queuePath)) {
1321
+ sendJson(res, 404, { error: "No proposals" });
1322
+ return;
1323
+ }
1324
+ const items = JSON.parse(readFileSync(queuePath, "utf-8"));
1325
+ const item = items.find((i) => i.id === id);
1326
+ if (!item) {
1327
+ sendJson(res, 404, { error: "Proposal not found" });
1328
+ return;
1329
+ }
1330
+ item.status = action === "approve" ? "approved" : "rejected";
1331
+ writeFileSync(queuePath, JSON.stringify(items, null, 2));
1332
+ if (action === "approve") {
1333
+ try {
1334
+ const embedding = await embed(item.rule.description);
1335
+ await upsertMemory({
1336
+ type: "rule",
1337
+ scope: "project",
1338
+ title: item.rule.name,
1339
+ content: item.rule.description,
1340
+ reason: `Auto-captured from ${item.source} (confidence: ${item.confidence})`,
1341
+ tags: [item.source, item.rule.severity],
1342
+ embedding
1343
+ });
1344
+ const remaining = items.filter((i) => i.status !== "approved");
1345
+ writeFileSync(queuePath, JSON.stringify(remaining, null, 2));
1346
+ readArchState();
1347
+ } catch (err) {
1348
+ sendJson(res, 500, { error: `Saved to queue but DB insert failed: ${err.message}` });
1349
+ return;
1350
+ }
1351
+ }
1352
+ readArchState();
1353
+ sendJson(res, 200, { ok: true });
1354
+ return;
1355
+ }
1148
1356
  sendJson(res, 404, { error: "Not found" });
1149
1357
  } catch (err) {
1150
1358
  sendJson(res, 500, { error: err.message });
@@ -1272,6 +1480,43 @@ function scheduleSnapshotBroadcast(options = {}) {
1272
1480
  void flushSnapshotBroadcast();
1273
1481
  }, Math.max(0, delayMs));
1274
1482
  }
1483
+ async function draftProposalsFromViolations(file, violations) {
1484
+ if (violations.length === 0) return;
1485
+ try {
1486
+ const { draftRuleWithAI, draftRuleFallback } = await import("./draft-rule-NUXOSRRS.js");
1487
+ const { ApprovalQueue } = await import("./approval-queue-4RK46FNE.js");
1488
+ const queue = new ApprovalQueue(join(projectRoot, ".archmind"));
1489
+ let queued = 0;
1490
+ for (const v of violations) {
1491
+ const context = `${v.rule}. Issue: ${v.issue}. File: ${file}`;
1492
+ const aiResult = await draftRuleWithAI({ context, source: "watch" });
1493
+ const { rule, confidence } = aiResult ?? draftRuleFallback({ context, source: "watch" });
1494
+ if (confidence === "high") {
1495
+ try {
1496
+ const embedding = await embed(rule.description);
1497
+ await upsertMemory({
1498
+ type: "rule",
1499
+ scope: "project",
1500
+ title: rule.name,
1501
+ content: rule.description,
1502
+ reason: `Auto-captured from watcher violation in ${file} (high confidence)`,
1503
+ tags: ["watcher", rule.severity],
1504
+ embedding
1505
+ });
1506
+ continue;
1507
+ } catch {
1508
+ }
1509
+ }
1510
+ queue.add(rule, "watch", confidence, { file, evidence: `${v.rule}: ${v.issue}` });
1511
+ queued++;
1512
+ }
1513
+ if (queued > 0) {
1514
+ readArchState();
1515
+ broadcast({ type: "proposals-updated", count: queue.pending().length });
1516
+ }
1517
+ } catch {
1518
+ }
1519
+ }
1275
1520
  function handleWatchEvent(event) {
1276
1521
  recentEvents.push(event);
1277
1522
  if (recentEvents.length > 100) recentEvents.shift();
@@ -1298,6 +1543,7 @@ function handleWatchEvent(event) {
1298
1543
  lastSeen: event.timestamp,
1299
1544
  violations: []
1300
1545
  });
1546
+ markFileResolved(event.file, event.timestamp);
1301
1547
  }
1302
1548
  if (event.type === "skipped") {
1303
1549
  fileStatuses.set(event.file, {
@@ -1316,6 +1562,7 @@ function handleWatchEvent(event) {
1316
1562
  violations: event.violations
1317
1563
  });
1318
1564
  appendViolationHistory(event.file, event.violations, event.timestamp);
1565
+ void draftProposalsFromViolations(event.file, event.violations);
1319
1566
  }
1320
1567
  if (event.type === "error") {
1321
1568
  watcherStatus.error = event.message;
@@ -1444,9 +1691,15 @@ async function startDashboard(options = {}) {
1444
1691
  console.log(chalk.gray(` Project root: ${projectRoot}`));
1445
1692
  if (options.watch ?? true) {
1446
1693
  watcherStatus.enabled = true;
1694
+ const initial = readSettings();
1447
1695
  void startWatch({
1448
1696
  projectRoot,
1449
1697
  path: ".",
1698
+ autoFix: initial.autoFix,
1699
+ verbose: initial.verbose,
1700
+ debug: initial.debug,
1701
+ scanOnStart: initial.scanOnStart,
1702
+ getAutoFix: () => readSettings().autoFix,
1450
1703
  onEvent: handleWatchEvent,
1451
1704
  exitOnSetupFailure: false
1452
1705
  });
@@ -23,7 +23,9 @@ import {
23
23
  updateLastLogin,
24
24
  updateMemory,
25
25
  upsertMemory
26
- } from "./chunk-GIPKVQSA.js";
26
+ } from "./chunk-5T2QBBYT.js";
27
+ import "./chunk-2LNDQGDD.js";
28
+ import "./chunk-K3NQKI34.js";
27
29
  export {
28
30
  closePool,
29
31
  countUsers,
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import "./chunk-K3NQKI34.js";
2
3
 
3
4
  // src/models/deterministic-validator.ts
4
5
  var DeterministicValidator = class {
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ draftRuleFallback,
4
+ draftRuleWithAI
5
+ } from "./chunk-FPRSYCOZ.js";
6
+ import "./chunk-XAE3RY5D.js";
7
+ import "./chunk-K3NQKI34.js";
8
+ export {
9
+ draftRuleFallback,
10
+ draftRuleWithAI
11
+ };
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ embed
4
+ } from "./chunk-SKR44CRD.js";
5
+ import "./chunk-2LNDQGDD.js";
6
+ import "./chunk-K3NQKI34.js";
7
+ export {
8
+ embed
9
+ };
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import "./chunk-K3NQKI34.js";
2
3
 
3
4
  // src/core/evidence.ts
4
5
  import { dirname, resolve } from "path";
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import "./chunk-K3NQKI34.js";
2
3
 
3
4
  // src/core/graph.ts
4
5
  import { dirname, resolve } from "path";
@@ -1,7 +1,18 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ draftRuleFallback,
4
+ draftRuleWithAI
5
+ } from "./chunk-FPRSYCOZ.js";
6
+ import "./chunk-XAE3RY5D.js";
7
+ import "./chunk-K3NQKI34.js";
2
8
 
3
9
  // src/automation/incident-capture.ts
4
10
  var IncidentCaptureService = class {
11
+ async draftRuleWithAI(incident) {
12
+ const context = `What broke: ${incident.what}. Root cause: ${incident.why}. Location: ${incident.where}`;
13
+ const result = await draftRuleWithAI({ context, source: "incident", hint: incident.why });
14
+ return result ?? draftRuleFallback({ context, source: "incident" });
15
+ }
5
16
  draftRule(incident) {
6
17
  return {
7
18
  id: `auto-incident-${Date.now()}`,