project-athena 0.4.0 → 0.5.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 (51) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +10 -0
  3. package/dist/{activity-BKW7G4I5.js → activity-XCHKBZTG.js} +4 -4
  4. package/dist/{agents-DFSNEOP5.js → agents-HUJ4JXIB.js} +4 -4
  5. package/dist/{ai-ASL4FFQ7.js → ai-LGTLQKL4.js} +3 -3
  6. package/dist/{analyze-ZY3MXBOI.js → analyze-AP4XJT7D.js} +7 -7
  7. package/dist/{chunk-ZB7LC6FP.js → chunk-3KFOI2X4.js} +2 -2
  8. package/dist/{chunk-MPG3IEGB.js → chunk-44EGCEB2.js} +23 -14
  9. package/dist/{chunk-GGXPG6OE.js → chunk-4FETKOY3.js} +8 -7
  10. package/dist/chunk-4IIBVTBS.js +76 -0
  11. package/dist/{chunk-LEMPCNAY.js → chunk-56EXAGTM.js} +3 -3
  12. package/dist/{chunk-DZDI2HRT.js → chunk-6OSQMXUP.js} +5 -5
  13. package/dist/{chunk-OLPSEQS5.js → chunk-AKOI4VTD.js} +10 -1
  14. package/dist/{chunk-FVCDMQUQ.js → chunk-C25FDXOO.js} +133 -23
  15. package/dist/{chunk-7DZK6WSQ.js → chunk-DH5AGULY.js} +2 -2
  16. package/dist/{chunk-TDNZ2RYA.js → chunk-F65QINMR.js} +2 -2
  17. package/dist/{chunk-WVQC2EGO.js → chunk-GU3ZX2J7.js} +2 -2
  18. package/dist/{chunk-UAZLPNVC.js → chunk-GYQG4Q2N.js} +4 -4
  19. package/dist/chunk-IDODPGTX.js +595 -0
  20. package/dist/chunk-KJYSNZXS.js +934 -0
  21. package/dist/{chunk-3XSDI5WF.js → chunk-L2EHJCH4.js} +5 -5
  22. package/dist/{chunk-65TSRDQ3.js → chunk-P4TRQMES.js} +2 -2
  23. package/dist/{chunk-KHMBNT66.js → chunk-PZPMWCXS.js} +5 -5
  24. package/dist/{chunk-XDCKZ5TV.js → chunk-R5AX7VST.js} +2 -2
  25. package/dist/{chunk-QLW657NT.js → chunk-RQKGT2EK.js} +2 -2
  26. package/dist/{chunk-VSYBC3VY.js → chunk-UMWX4UTK.js} +2 -2
  27. package/dist/{chunk-RXNRMIZP.js → chunk-WUIC65QO.js} +2 -2
  28. package/dist/{chunk-JCGDR4UV.js → chunk-WWQ5NKEC.js} +3 -1
  29. package/dist/{chunk-RVTNSNGK.js → chunk-X7EYOAEX.js} +2 -2
  30. package/dist/chunk-Y6SDMZET.js +278 -0
  31. package/dist/{clean-MDBYH62P.js → clean-LQOG56AM.js} +2 -2
  32. package/dist/cli.js +2 -2
  33. package/dist/{context-PLPCAPCO.js → context-G5YHY3L2.js} +8 -8
  34. package/dist/{doctor-BX677KRE.js → doctor-L34QJ7WR.js} +8 -8
  35. package/dist/{event-TNT6CQZR.js → event-6YW6TGFI.js} +3 -3
  36. package/dist/{git-hook-YZNZGAAP.js → git-hook-Y7Y262F7.js} +2 -2
  37. package/dist/{init-WQCAOJ2R.js → init-427QR5AS.js} +7 -7
  38. package/dist/{mcp-U7EPH43L.js → mcp-DWNWRGJW.js} +51 -14
  39. package/dist/{memory-VSVNLEJC.js → memory-XBZCYQLW.js} +3 -3
  40. package/dist/{open-UJZRYF4E.js → open-LJMOB6U2.js} +33 -31
  41. package/dist/{program-CWJNGCTZ.js → program-DCP526LU.js} +46 -32
  42. package/dist/{review-OOKXSYMP.js → review-VEJBPACX.js} +10 -9
  43. package/dist/{rules-4FXJUCXB.js → rules-M4DLLXBL.js} +4 -4
  44. package/dist/scan-JVKCVHPD.js +939 -0
  45. package/dist/{security-LME3XFL3.js → security-JTJN3E7K.js} +13 -11
  46. package/dist/{staged-check-X24C3YRD.js → staged-check-PQSLGQBW.js} +11 -11
  47. package/dist/{status-RR57ZNGI.js → status-PO27BSOZ.js} +4 -4
  48. package/dist/{sync-KFJANRXF.js → sync-GVO2VHPI.js} +10 -10
  49. package/dist/{watch-CY7QHIYN.js → watch-TEHFO47V.js} +10 -10
  50. package/package.json +3 -1
  51. package/dist/chunk-SJ4DQFIJ.js +0 -379
@@ -1,4 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ Coverage,
4
+ Finding,
5
+ SECRETS_ENGINE,
6
+ dedupeFindings,
7
+ fileFingerprint,
8
+ hitsFromMatches,
9
+ secretFindings
10
+ } from "./chunk-Y6SDMZET.js";
2
11
  import {
3
12
  listRules,
4
13
  parseRules
@@ -6,7 +15,7 @@ import {
6
15
  import {
7
16
  loadScan,
8
17
  manifestDependencyNames
9
- } from "./chunk-MPG3IEGB.js";
18
+ } from "./chunk-44EGCEB2.js";
10
19
  import {
11
20
  API_ROUTE_PATH,
12
21
  AUTH_PATH,
@@ -21,10 +30,10 @@ import {
21
30
  isSafeRef,
22
31
  parseNameStatusZ,
23
32
  workingChanges
24
- } from "./chunk-OLPSEQS5.js";
33
+ } from "./chunk-AKOI4VTD.js";
25
34
  import {
26
35
  scanText
27
- } from "./chunk-JCGDR4UV.js";
36
+ } from "./chunk-WWQ5NKEC.js";
28
37
  import {
29
38
  athenaDir
30
39
  } from "./chunk-2DY4PUR4.js";
@@ -40,6 +49,82 @@ import {
40
49
  // src/services/review.ts
41
50
  import { promises as fs } from "fs";
42
51
  import path from "path";
52
+
53
+ // src/core/scanners/review.ts
54
+ var REVIEW_ENGINE = "athena-review";
55
+ var LEVEL_SEVERITY = { blocker: "high", warning: "medium", info: "info" };
56
+ var CHECK_CONFIDENCE = { tests: "medium", api: "medium", auth: "medium", database: "medium", leftovers: "medium" };
57
+ var CHECK_CWE = { "env-file": ["CWE-540"] };
58
+ var CHECK_TITLE = {
59
+ "env-file": "Environment file in the change",
60
+ dependencies: "New dependencies",
61
+ tests: "Source changed without tests",
62
+ api: "API surface changed",
63
+ database: "Database schema or migrations changed",
64
+ auth: "Authentication/authorization code changed",
65
+ "large-files": "Large file added",
66
+ leftovers: "TODO/FIXME or debug statement added",
67
+ vulnerabilities: "Known vulnerable dependencies",
68
+ knowledge: "Athena knowledge out of date",
69
+ skipped: "Changed file not checked"
70
+ };
71
+ function checkFinding(check, loc, lines) {
72
+ const ruleId = `review/${check.check}`;
73
+ return {
74
+ fingerprint: fileFingerprint({ ruleId, file: loc?.file, key: loc ? void 0 : check.check }),
75
+ ruleId,
76
+ category: "review",
77
+ severity: LEVEL_SEVERITY[check.level],
78
+ confidence: CHECK_CONFIDENCE[check.check] ?? "high",
79
+ label: "DETECTED",
80
+ potential: false,
81
+ title: CHECK_TITLE[check.check] ?? check.message,
82
+ message: loc && lines.length > 1 ? `${check.message} (${lines.length} lines in this file)` : check.message,
83
+ cwe: CHECK_CWE[check.check] ?? [],
84
+ ...loc ? { location: { file: loc.file, ...lines[0] ? { startLine: lines[0] } : {} } } : {},
85
+ engine: { id: "athena" },
86
+ ...check.hint ? { help: { text: check.hint } } : {}
87
+ };
88
+ }
89
+ function reviewFindings(input) {
90
+ const out = secretFindings(input.secrets);
91
+ for (const { check, locations } of input.checks) {
92
+ if (check.check === "secrets") continue;
93
+ if (!locations.length) {
94
+ out.push(checkFinding(check, null, []));
95
+ continue;
96
+ }
97
+ const byFile = /* @__PURE__ */ new Map();
98
+ for (const l of locations) {
99
+ const lines = byFile.get(l.file) ?? [];
100
+ if (l.line) lines.push(l.line);
101
+ byFile.set(l.file, lines);
102
+ }
103
+ for (const [file, lines] of byFile) out.push(checkFinding(check, { file }, lines.sort((a, b) => a - b)));
104
+ }
105
+ return out;
106
+ }
107
+ function reviewCoverage(c) {
108
+ const filesSkipped = { tooLarge: c.skipped.tooLarge, unreadable: c.skipped.unreadable, binary: 0, minified: 0, unsupported: 0 };
109
+ const reason = c.incomplete ? `${c.skipped.tooLarge + c.skipped.unreadable} changed file(s) could not be read and were not checked` : void 0;
110
+ return [
111
+ { engine: REVIEW_ENGINE, category: "review", status: "ok", ...reason ? { reason } : {}, target: "changed files", filesScanned: c.checked, filesSkipped, network: false, durationMs: c.durationMs },
112
+ { engine: SECRETS_ENGINE, category: "secret", status: "ok", reason: `added lines only${reason ? `; ${reason}` : ""}`, target: "added lines", filesScanned: c.checked, filesSkipped, network: false, durationMs: 0 }
113
+ ];
114
+ }
115
+ function reviewScanner(run) {
116
+ return {
117
+ id: REVIEW_ENGINE,
118
+ category: "review",
119
+ title: "Change review checks",
120
+ async run(ctx) {
121
+ if (ctx.mode === "all") return { findings: [], coverage: [{ engine: REVIEW_ENGINE, category: "review", status: "skipped", reason: "review checks need a diff (staged, changed or base scope)", durationMs: 0 }] };
122
+ return run(ctx);
123
+ }
124
+ };
125
+ }
126
+
127
+ // src/services/review.ts
43
128
  var ENV_FILE = /(^|\/)\.env(\.(local|production|development|prod|dev|staging))?$/;
44
129
  var MANIFEST_FILE = /(^|\/)(package\.json|pyproject\.toml|requirements[^/]*\.txt|go\.mod|Cargo\.toml|composer\.json|Gemfile|pubspec\.yaml|pom\.xml|build\.gradle(\.kts)?)$/;
45
130
  var LARGE_ADDED_BYTES = 512 * 1024;
@@ -113,16 +198,18 @@ function addedLines(patch) {
113
198
  }
114
199
  return out;
115
200
  }
116
- function scanAddedLines(lines) {
201
+ function scanAddedLinesDetailed(lines) {
117
202
  const hits = [];
118
203
  let block = [];
119
204
  const flush = () => {
120
205
  if (!block.length) return;
121
206
  const b = block;
122
207
  block = [];
123
- for (const m of scanText(b.map((l) => l.text).join("\n"))) {
124
- const at = b[m.line - 1] ?? b[0];
125
- hits.push({ type: m.type, file: at.file, line: at.line });
208
+ const text = b.map((l) => l.text).join("\n");
209
+ for (const h of hitsFromMatches("", text, scanText(text))) {
210
+ const at = b[h.line - 1] ?? b[0];
211
+ const endAt = h.endLine ? b[h.endLine - 1] : void 0;
212
+ hits.push({ ...h, file: at.file, line: at.line, ...endAt ? { endLine: endAt.line } : {} });
126
213
  }
127
214
  };
128
215
  for (const l of lines) {
@@ -145,6 +232,7 @@ async function reviewChanges(root, opts = {}) {
145
232
  }
146
233
  }
147
234
  async function review(root, opts) {
235
+ const started = Date.now();
148
236
  const signal = opts.signal;
149
237
  signal?.throwIfAborted();
150
238
  const repoCheck = await git(root, ["rev-parse", "--is-inside-work-tree"], { signal });
@@ -248,14 +336,19 @@ async function review(root, opts) {
248
336
  };
249
337
  const findings = [];
250
338
  const paths = changedFiles.map((f) => f.path);
251
- const add = (f) => findings.push(f);
339
+ const locations = /* @__PURE__ */ new Map();
340
+ const add = (f, all) => {
341
+ findings.push(f);
342
+ locations.set(f, (all ?? f.files).map((x) => typeof x === "string" ? { file: x } : x));
343
+ };
344
+ const secretDetail = scanAddedLinesDetailed(added);
252
345
  const secretHits = /* @__PURE__ */ new Map();
253
- for (const hit of scanAddedLines(added)) {
346
+ for (const hit of secretDetail) {
254
347
  if (!secretHits.has(hit.type)) secretHits.set(hit.type, /* @__PURE__ */ new Set());
255
348
  secretHits.get(hit.type).add(`${hit.file}:${hit.line}`);
256
349
  }
257
- for (const [type, locations] of secretHits) {
258
- add({ level: "blocker", check: "secrets", message: `Possible ${type} added`, files: [...locations].slice(0, 10), hint: "Remove the value, use an environment variable, and rotate the credential if it was real." });
350
+ for (const [type, locations2] of secretHits) {
351
+ add({ level: "blocker", check: "secrets", message: `Possible ${type} added`, files: [...locations2].slice(0, 10), hint: "Remove the value, use an environment variable, and rotate the credential if it was real." });
259
352
  }
260
353
  const envFiles = changedFiles.filter((f) => f.status !== "deleted" && ENV_FILE.test(f.path)).map((f) => f.path);
261
354
  if (envFiles.length) add({ level: "blocker", check: "env-file", message: "Environment file included in the change", files: envFiles, hint: "Add it to .gitignore and commit a .env.example with names only." });
@@ -281,14 +374,14 @@ async function review(root, opts) {
281
374
  const changedSource = paths.filter((p) => SOURCE_FILE.test(p) && !TEST_FILE.test(p));
282
375
  const changedTests = paths.filter((p) => TEST_FILE.test(p));
283
376
  if (changedSource.length && !changedTests.length) {
284
- add({ level: "warning", check: "tests", message: `${changedSource.length} source file(s) changed with no test file changes`, files: changedSource.slice(0, 10), hint: "See `.athena/testing.md` for the project test commands and layout." });
377
+ add({ level: "warning", check: "tests", message: `${changedSource.length} source file(s) changed with no test file changes`, files: changedSource.slice(0, 10), hint: "See `.athena/testing.md` for the project test commands and layout." }, changedSource);
285
378
  }
286
379
  const routeFiles = changedSource.filter((p) => API_ROUTE_PATH.test(p));
287
- if (routeFiles.length) add({ level: "info", check: "api", message: "API surface changed", files: routeFiles.slice(0, 10), hint: "Check auth/authorization and error handling (`.athena/api.md`, `.athena/auth.md`)." });
380
+ if (routeFiles.length) add({ level: "info", check: "api", message: "API surface changed", files: routeFiles.slice(0, 10), hint: "Check auth/authorization and error handling (`.athena/api.md`, `.athena/auth.md`)." }, routeFiles);
288
381
  const schemaFiles = paths.filter((p) => SCHEMA_PATH.test(p));
289
- if (schemaFiles.length) add({ level: "info", check: "database", message: "Database schema or migrations changed", files: schemaFiles.slice(0, 10), hint: "Check indexes, constraints and backward compatibility (`.athena/database.md`)." });
382
+ if (schemaFiles.length) add({ level: "info", check: "database", message: "Database schema or migrations changed", files: schemaFiles.slice(0, 10), hint: "Check indexes, constraints and backward compatibility (`.athena/database.md`)." }, schemaFiles);
290
383
  const authFiles = changedSource.filter((p) => AUTH_PATH.test(p));
291
- if (authFiles.length) add({ level: "warning", check: "auth", message: "Authentication/authorization code changed", files: authFiles.slice(0, 10), hint: "Review against `.athena/auth.md` and `.athena/security.md`." });
384
+ if (authFiles.length) add({ level: "warning", check: "auth", message: "Authentication/authorization code changed", files: authFiles.slice(0, 10), hint: "Review against `.athena/auth.md` and `.athena/security.md`." }, authFiles);
292
385
  for (const f of changedFiles.filter((x) => x.status === "added")) {
293
386
  signal?.throwIfAborted();
294
387
  let size = null;
@@ -304,12 +397,12 @@ async function review(root, opts) {
304
397
  if (large.length) add({ level: "warning", check: "large-files", message: "Large files added", files: large, hint: "Consider whether these belong in Git." });
305
398
  const debugHits = added.filter((l) => /\b(TODO|FIXME|XXX|console\.log|debugger|print\(|binding\.pry|dd\()/.test(l.text) && SOURCE_FILE.test(l.file));
306
399
  if (debugHits.length) {
307
- add({ level: "info", check: "leftovers", message: `${debugHits.length} added line(s) contain TODO/FIXME or debug statements`, files: [...new Set(debugHits.map((l) => `${l.file}:${l.line}`))].slice(0, 10) });
400
+ add({ level: "info", check: "leftovers", message: `${debugHits.length} added line(s) contain TODO/FIXME or debug statements`, files: [...new Set(debugHits.map((l) => `${l.file}:${l.line}`))].slice(0, 10) }, debugHits.map((l) => ({ file: l.file, line: l.line })));
308
401
  }
309
- const scan = await loadScan(root);
310
- if (scan) {
311
- const vulnerable = scan.tools.flatMap((t) => t.findings).filter((f) => ["critical", "high"].includes(f.severity));
312
- if (vulnerable.length) add({ level: "warning", check: "vulnerabilities", message: `${vulnerable.length} high/critical dependency advisor${vulnerable.length === 1 ? "y" : "ies"} from the last scan (${scan.scannedAt.slice(0, 10)})`, files: [], hint: "Run `athena security` for details." });
402
+ const lastScan = await loadScan(root);
403
+ if (lastScan) {
404
+ const vulnerable = lastScan.tools.flatMap((t) => t.findings).filter((f) => ["critical", "high"].includes(f.severity));
405
+ if (vulnerable.length) add({ level: "warning", check: "vulnerabilities", message: `${vulnerable.length} high/critical dependency advisor${vulnerable.length === 1 ? "y" : "ies"} from the last scan (${lastScan.scannedAt.slice(0, 10)})`, files: [], hint: "Run `athena security` for details." });
313
406
  }
314
407
  let knowledgeInSync = null;
315
408
  if (opts.checkSync) {
@@ -321,9 +414,25 @@ async function review(root, opts) {
321
414
  const reviewDoc = await readTextIfExists(path.join(athenaDir(root), "code-review.md"));
322
415
  const checklist = reviewDoc ? [...reviewDoc.matchAll(/^- \[ \] (.+)$/gm)].map((m) => m[1].trim()) : [];
323
416
  if (skipped.length) {
324
- add({ level: "warning", check: "skipped", message: `${skipped.length} changed file${skipped.length === 1 ? " was" : "s were"} not checked`, files: skipped.map((s) => `${s.path} (${SKIP_REASON[s.reason]})`).slice(0, 10), hint: "Athena could not read these files, so their contents were not checked for secrets. Check them yourself." });
417
+ add({ level: "warning", check: "skipped", message: `${skipped.length} changed file${skipped.length === 1 ? " was" : "s were"} not checked`, files: skipped.map((s) => `${s.path} (${SKIP_REASON[s.reason]})`).slice(0, 10), hint: "Athena could not read these files, so their contents were not checked for secrets. Check them yourself." }, skipped.map((s) => s.path));
325
418
  }
326
- return { base, mode, ...mergeBase ? { mergeBase } : {}, changedFiles, findings, rules, checklist, knowledgeInSync, stats: { added: addedCount + untrackedAdded, removed: removedCount, files: changedFiles.length }, incomplete: skipped.length > 0, skipped };
419
+ const durationMs = Date.now() - started;
420
+ const tooLarge = skipped.filter((s) => s.reason === "too-large").length;
421
+ const scan = {
422
+ schemaVersion: 1,
423
+ scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
424
+ durationMs,
425
+ scope: { mode: mode === "working" ? "changed" : mode, ...opts.base !== void 0 ? { base: opts.base } : {}, files: changedFiles.length },
426
+ findings: dedupeFindings(reviewFindings({ checks: findings.map((check) => ({ check, locations: locations.get(check) ?? [] })), secrets: secretDetail }).map((f) => Finding.parse(f))),
427
+ coverage: reviewCoverage({ checked: changedFiles.filter((f) => f.status !== "deleted").length - skipped.length, skipped: { tooLarge, unreadable: skipped.length - tooLarge }, durationMs, incomplete: skipped.length > 0 }).map((c) => Coverage.parse(c))
428
+ };
429
+ return { base, mode, ...mergeBase ? { mergeBase } : {}, changedFiles, findings, rules, checklist, knowledgeInSync, stats: { added: addedCount + untrackedAdded, removed: removedCount, files: changedFiles.length }, incomplete: skipped.length > 0, skipped, scan };
430
+ }
431
+ function createReviewScanner(opts = {}) {
432
+ return reviewScanner(async (ctx) => {
433
+ const r = await reviewChanges(ctx.root, { ...opts, signal: ctx.signal, ...ctx.mode === "staged" ? { staged: true } : {}, ...ctx.mode === "base" ? { base: ctx.base ?? "HEAD" } : {} });
434
+ return { findings: r.scan.findings, coverage: r.scan.coverage };
435
+ });
327
436
  }
328
437
  var SKIP_REASON = {
329
438
  "outside-root": "symlink to a path outside the project",
@@ -338,6 +447,7 @@ function hasBlockers(result) {
338
447
 
339
448
  export {
340
449
  reviewChanges,
450
+ createReviewScanner,
341
451
  hasBlockers
342
452
  };
343
- //# sourceMappingURL=chunk-FVCDMQUQ.js.map
453
+ //# sourceMappingURL=chunk-C25FDXOO.js.map
@@ -37,7 +37,7 @@ async function confirm(question) {
37
37
  async function cleanCommand(opts) {
38
38
  const root = await requireProjectRoot(opts);
39
39
  if (!opts.yes) {
40
- const memory = (await (await import("./memory-VSVNLEJC.js")).memorySummary(root))?.total ?? 0;
40
+ const memory = (await (await import("./memory-XBZCYQLW.js")).memorySummary(root))?.total ?? 0;
41
41
  const memoryNote = memory ? `${memory} project memory ${memory === 1 ? "entry" : "entries"} in .athena/memory/ (shared with your team)` : "";
42
42
  if (!process.stdin.isTTY) throw new AthenaError(`Refusing to delete .athena/${memory ? `, including ${memoryNote},` : ""} without confirmation.`, "Re-run with --yes in non-interactive environments.");
43
43
  line(`This removes ${c.bold(".athena/")} (including rules.md and your Developer Notes)${opts.keepAgents ? "" : " and Athena blocks/files in agent configurations"}.`);
@@ -62,4 +62,4 @@ export {
62
62
  confirm,
63
63
  cleanCommand
64
64
  };
65
- //# sourceMappingURL=chunk-7DZK6WSQ.js.map
65
+ //# sourceMappingURL=chunk-DH5AGULY.js.map
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-SVTEJYMS.js";
9
9
  import {
10
10
  scanText
11
- } from "./chunk-JCGDR4UV.js";
11
+ } from "./chunk-WWQ5NKEC.js";
12
12
  import {
13
13
  parseBlocks
14
14
  } from "./chunk-673EPYYH.js";
@@ -699,4 +699,4 @@ export {
699
699
  forgetMemory,
700
700
  updateMemory
701
701
  };
702
- //# sourceMappingURL=chunk-TDNZ2RYA.js.map
702
+ //# sourceMappingURL=chunk-F65QINMR.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  SCAN_FILE,
4
4
  SecurityScan
5
- } from "./chunk-MPG3IEGB.js";
5
+ } from "./chunk-44EGCEB2.js";
6
6
  import {
7
7
  GRAPH_FILE,
8
8
  ProjectGraph
@@ -163,4 +163,4 @@ export {
163
163
  projectSession,
164
164
  releaseProjectSession
165
165
  };
166
- //# sourceMappingURL=chunk-WVQC2EGO.js.map
166
+ //# sourceMappingURL=chunk-GU3ZX2J7.js.map
@@ -5,13 +5,13 @@ import {
5
5
  listMemory,
6
6
  recall,
7
7
  selectContext
8
- } from "./chunk-TDNZ2RYA.js";
8
+ } from "./chunk-F65QINMR.js";
9
9
  import {
10
10
  projectSession
11
- } from "./chunk-WVQC2EGO.js";
11
+ } from "./chunk-GU3ZX2J7.js";
12
12
  import {
13
13
  analyzeProject
14
- } from "./chunk-MPG3IEGB.js";
14
+ } from "./chunk-44EGCEB2.js";
15
15
  import {
16
16
  GRAPH_FILE,
17
17
  buildGraph,
@@ -105,4 +105,4 @@ export {
105
105
  getRelevantContext,
106
106
  graphSummary
107
107
  };
108
- //# sourceMappingURL=chunk-UAZLPNVC.js.map
108
+ //# sourceMappingURL=chunk-GYQG4Q2N.js.map