@mneme-ai/core 0.8.3 → 0.9.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 (144) hide show
  1. package/dist/entities/go-parser.d.ts +47 -0
  2. package/dist/entities/go-parser.d.ts.map +1 -0
  3. package/dist/entities/go-parser.js +315 -0
  4. package/dist/entities/go-parser.js.map +1 -0
  5. package/dist/entities/go-parser.test.d.ts +2 -0
  6. package/dist/entities/go-parser.test.d.ts.map +1 -0
  7. package/dist/entities/go-parser.test.js +147 -0
  8. package/dist/entities/go-parser.test.js.map +1 -0
  9. package/dist/entities/index.d.ts +1 -0
  10. package/dist/entities/index.d.ts.map +1 -1
  11. package/dist/entities/index.js +1 -0
  12. package/dist/entities/index.js.map +1 -1
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +2 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/indexer/indexer.d.ts +12 -0
  18. package/dist/indexer/indexer.d.ts.map +1 -1
  19. package/dist/indexer/indexer.js +28 -1
  20. package/dist/indexer/indexer.js.map +1 -1
  21. package/dist/insights/decisions.d.ts +38 -0
  22. package/dist/insights/decisions.d.ts.map +1 -0
  23. package/dist/insights/decisions.js +125 -0
  24. package/dist/insights/decisions.js.map +1 -0
  25. package/dist/insights/decisions.test.d.ts +2 -0
  26. package/dist/insights/decisions.test.d.ts.map +1 -0
  27. package/dist/insights/decisions.test.js +141 -0
  28. package/dist/insights/decisions.test.js.map +1 -0
  29. package/dist/insights/dream.d.ts +71 -0
  30. package/dist/insights/dream.d.ts.map +1 -0
  31. package/dist/insights/dream.js +235 -0
  32. package/dist/insights/dream.js.map +1 -0
  33. package/dist/insights/dream.test.d.ts +2 -0
  34. package/dist/insights/dream.test.d.ts.map +1 -0
  35. package/dist/insights/dream.test.js +127 -0
  36. package/dist/insights/dream.test.js.map +1 -0
  37. package/dist/insights/index.d.ts +16 -0
  38. package/dist/insights/index.d.ts.map +1 -0
  39. package/dist/insights/index.js +16 -0
  40. package/dist/insights/index.js.map +1 -0
  41. package/dist/insights/obsidian.d.ts +42 -0
  42. package/dist/insights/obsidian.d.ts.map +1 -0
  43. package/dist/insights/obsidian.js +263 -0
  44. package/dist/insights/obsidian.js.map +1 -0
  45. package/dist/insights/obsidian.test.d.ts +2 -0
  46. package/dist/insights/obsidian.test.d.ts.map +1 -0
  47. package/dist/insights/obsidian.test.js +241 -0
  48. package/dist/insights/obsidian.test.js.map +1 -0
  49. package/dist/insights/stack-trace.d.ts +40 -0
  50. package/dist/insights/stack-trace.d.ts.map +1 -0
  51. package/dist/insights/stack-trace.js +127 -0
  52. package/dist/insights/stack-trace.js.map +1 -0
  53. package/dist/insights/stack-trace.test.d.ts +2 -0
  54. package/dist/insights/stack-trace.test.d.ts.map +1 -0
  55. package/dist/insights/stack-trace.test.js +103 -0
  56. package/dist/insights/stack-trace.test.js.map +1 -0
  57. package/dist/insights/story.d.ts +34 -0
  58. package/dist/insights/story.d.ts.map +1 -0
  59. package/dist/insights/story.js +100 -0
  60. package/dist/insights/story.js.map +1 -0
  61. package/dist/insights/story.test.d.ts +2 -0
  62. package/dist/insights/story.test.d.ts.map +1 -0
  63. package/dist/insights/story.test.js +99 -0
  64. package/dist/insights/story.test.js.map +1 -0
  65. package/dist/insights/suggest.d.ts +29 -0
  66. package/dist/insights/suggest.d.ts.map +1 -0
  67. package/dist/insights/suggest.js +93 -0
  68. package/dist/insights/suggest.js.map +1 -0
  69. package/dist/insights/suggest.test.d.ts +2 -0
  70. package/dist/insights/suggest.test.d.ts.map +1 -0
  71. package/dist/insights/suggest.test.js +71 -0
  72. package/dist/insights/suggest.test.js.map +1 -0
  73. package/dist/insights/who-knows.d.ts +48 -0
  74. package/dist/insights/who-knows.d.ts.map +1 -0
  75. package/dist/insights/who-knows.js +96 -0
  76. package/dist/insights/who-knows.js.map +1 -0
  77. package/dist/insights/who-knows.test.d.ts +2 -0
  78. package/dist/insights/who-knows.test.d.ts.map +1 -0
  79. package/dist/insights/who-knows.test.js +47 -0
  80. package/dist/insights/who-knows.test.js.map +1 -0
  81. package/dist/retrieve/index.d.ts +2 -0
  82. package/dist/retrieve/index.d.ts.map +1 -1
  83. package/dist/retrieve/index.js +2 -0
  84. package/dist/retrieve/index.js.map +1 -1
  85. package/dist/retrieve/intent.d.ts +32 -0
  86. package/dist/retrieve/intent.d.ts.map +1 -0
  87. package/dist/retrieve/intent.js +104 -0
  88. package/dist/retrieve/intent.js.map +1 -0
  89. package/dist/retrieve/intent.test.d.ts +2 -0
  90. package/dist/retrieve/intent.test.d.ts.map +1 -0
  91. package/dist/retrieve/intent.test.js +106 -0
  92. package/dist/retrieve/intent.test.js.map +1 -0
  93. package/dist/retrieve/search.d.ts +30 -0
  94. package/dist/retrieve/search.d.ts.map +1 -1
  95. package/dist/retrieve/search.js +48 -0
  96. package/dist/retrieve/search.js.map +1 -1
  97. package/dist/retrieve/search.test.js +84 -1
  98. package/dist/retrieve/search.test.js.map +1 -1
  99. package/dist/retrieve/synthesize.d.ts +57 -0
  100. package/dist/retrieve/synthesize.d.ts.map +1 -0
  101. package/dist/retrieve/synthesize.js +160 -0
  102. package/dist/retrieve/synthesize.js.map +1 -0
  103. package/dist/retrieve/synthesize.test.d.ts +2 -0
  104. package/dist/retrieve/synthesize.test.d.ts.map +1 -0
  105. package/dist/retrieve/synthesize.test.js +116 -0
  106. package/dist/retrieve/synthesize.test.js.map +1 -0
  107. package/dist/store/schema.d.ts +2 -2
  108. package/dist/store/schema.d.ts.map +1 -1
  109. package/dist/store/schema.js +55 -1
  110. package/dist/store/schema.js.map +1 -1
  111. package/dist/store/sqlite.test.js +1 -1
  112. package/dist/util/index.d.ts +2 -0
  113. package/dist/util/index.d.ts.map +1 -1
  114. package/dist/util/index.js +2 -1
  115. package/dist/util/index.js.map +1 -1
  116. package/dist/util/redact.d.ts +58 -0
  117. package/dist/util/redact.d.ts.map +1 -0
  118. package/dist/util/redact.js +129 -0
  119. package/dist/util/redact.js.map +1 -0
  120. package/dist/util/redact.test.d.ts +2 -0
  121. package/dist/util/redact.test.d.ts.map +1 -0
  122. package/dist/util/redact.test.js +148 -0
  123. package/dist/util/redact.test.js.map +1 -0
  124. package/dist/wisdom/calibrator.d.ts +43 -0
  125. package/dist/wisdom/calibrator.d.ts.map +1 -0
  126. package/dist/wisdom/calibrator.js +120 -0
  127. package/dist/wisdom/calibrator.js.map +1 -0
  128. package/dist/wisdom/feedback.d.ts +45 -0
  129. package/dist/wisdom/feedback.d.ts.map +1 -0
  130. package/dist/wisdom/feedback.js +116 -0
  131. package/dist/wisdom/feedback.js.map +1 -0
  132. package/dist/wisdom/index.d.ts +15 -0
  133. package/dist/wisdom/index.d.ts.map +1 -0
  134. package/dist/wisdom/index.js +15 -0
  135. package/dist/wisdom/index.js.map +1 -0
  136. package/dist/wisdom/types.d.ts +67 -0
  137. package/dist/wisdom/types.d.ts.map +1 -0
  138. package/dist/wisdom/types.js +20 -0
  139. package/dist/wisdom/types.js.map +1 -0
  140. package/dist/wisdom/wisdom.test.d.ts +2 -0
  141. package/dist/wisdom/wisdom.test.d.ts.map +1 -0
  142. package/dist/wisdom/wisdom.test.js +144 -0
  143. package/dist/wisdom/wisdom.test.js.map +1 -0
  144. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { readCommits, readFileChanges } from "../git/log.js";
3
+ import { redact, mergeHits } from "../util/redact.js";
3
4
  export class Indexer {
4
5
  opts;
5
6
  constructor(opts) {
@@ -34,6 +35,28 @@ export class Indexer {
34
35
  }
35
36
  }
36
37
  const chunks = buildChunks(commits);
38
+ // Redaction runs BEFORE embedding so secrets never reach a remote provider.
39
+ // Default ON; opt out only on trusted internal repos with no secret history.
40
+ let redactionHits = {};
41
+ if (this.opts.redact !== false) {
42
+ const ropts = typeof this.opts.redact === "object" ? this.opts.redact : {};
43
+ for (const chunk of chunks) {
44
+ const r = redact(chunk.text, ropts);
45
+ if (Object.keys(r.hits).length > 0) {
46
+ chunk.text = r.text;
47
+ redactionHits = mergeHits(redactionHits, r.hits);
48
+ }
49
+ }
50
+ const totalHits = Object.values(redactionHits).reduce((a, b) => a + b, 0);
51
+ if (totalHits > 0) {
52
+ report({
53
+ phase: "writing",
54
+ current: totalHits,
55
+ total: chunks.length,
56
+ message: `redacted ${totalHits} secret(s) across ${Object.keys(redactionHits).length} rule(s)`,
57
+ });
58
+ }
59
+ }
37
60
  if (this.opts.embedder) {
38
61
  const model = this.opts.embedder.name;
39
62
  const batchSize = this.opts.embedBatchSize ?? 32;
@@ -55,7 +78,11 @@ export class Indexer {
55
78
  this.opts.store.upsertChunks(chunks);
56
79
  }
57
80
  report({ phase: "done", current: chunks.length, total: chunks.length });
58
- return { commits: commits.length, chunks: chunks.length };
81
+ return {
82
+ commits: commits.length,
83
+ chunks: chunks.length,
84
+ redactionHits,
85
+ };
59
86
  }
60
87
  }
61
88
  export function buildChunks(commits) {
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/indexer/indexer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/indexer/indexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * `decisions` — auto-extract architectural decisions (ADRs) from commit
3
+ * history. The classic "we should write ADRs" never works in practice;
4
+ * instead, extract them from the commit messages that *already exist*.
5
+ *
6
+ * The extractor is intentionally conservative — it triggers on a small set
7
+ * of high-precision patterns ("decided to", "switched from X to Y",
8
+ * "replaced X with Y", "deprecate X"). False positives are worse than
9
+ * false negatives here: an ADR list with garbage erodes trust faster than
10
+ * a thin one builds it.
11
+ */
12
+ import type { Commit } from "../types.js";
13
+ export interface ExtractedDecision {
14
+ /** Commit hash where the decision was recorded. */
15
+ commitHash: string;
16
+ shortHash: string;
17
+ date: string;
18
+ author: string;
19
+ /** A 1-line summary of the decision, drawn from the matched span. */
20
+ summary: string;
21
+ /** Optional rationale clause, when the message includes "because"/"so that". */
22
+ rationale?: string;
23
+ /** The pattern that fired — for transparency. */
24
+ kind: "decided-to" | "switched" | "replaced" | "deprecated" | "chose-over" | "instead-of" | "migrated" | "adopted" | "rejected";
25
+ /** Confidence score in [0, 1]; calibrated from pattern specificity. */
26
+ confidence: number;
27
+ }
28
+ /**
29
+ * Extract every decision in a single commit's text (subject + body + PR
30
+ * title + PR body). Returns 0..N decisions; one commit can record several.
31
+ */
32
+ export declare function extractDecisions(commit: Commit): ExtractedDecision[];
33
+ /**
34
+ * Render a list of decisions as a Markdown table. Useful for
35
+ * `mneme decisions --format markdown > docs/ADR.md`.
36
+ */
37
+ export declare function renderDecisionsAsMarkdown(decisions: ExtractedDecision[]): string;
38
+ //# sourceMappingURL=decisions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.d.ts","sourceRoot":"","sources":["../../src/insights/decisions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,IAAI,EACA,YAAY,GACZ,UAAU,GACV,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,SAAS,GACT,UAAU,CAAC;IACf,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;CACpB;AAyCD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAyCpE;AA2BD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAgBhF"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * `decisions` — auto-extract architectural decisions (ADRs) from commit
3
+ * history. The classic "we should write ADRs" never works in practice;
4
+ * instead, extract them from the commit messages that *already exist*.
5
+ *
6
+ * The extractor is intentionally conservative — it triggers on a small set
7
+ * of high-precision patterns ("decided to", "switched from X to Y",
8
+ * "replaced X with Y", "deprecate X"). False positives are worse than
9
+ * false negatives here: an ADR list with garbage erodes trust faster than
10
+ * a thin one builds it.
11
+ */
12
+ /**
13
+ * Patterns ordered by specificity. The first matching pattern wins.
14
+ * Each match exposes the decision text via the `text` group.
15
+ */
16
+ const PATTERNS = [
17
+ // Highest specificity: explicit "decided to ..."
18
+ { kind: "decided-to", re: /\b(?:we\s+)?decided\s+to\s+(?<text>[^.\n;]{8,200})/gi, confidence: 0.95 },
19
+ // Switched / migrated FROM A TO B
20
+ { kind: "switched", re: /\bswitch(?:ed)?\s+from\s+(?<from>[^.\n;]{2,80})\s+to\s+(?<text>[^.\n;]{2,120})/gi, confidence: 0.9 },
21
+ { kind: "migrated", re: /\bmigrat(?:e|ed)\s+from\s+(?<from>[^.\n;]{2,80})\s+to\s+(?<text>[^.\n;]{2,120})/gi, confidence: 0.9 },
22
+ // Replaced X with Y
23
+ { kind: "replaced", re: /\breplaced?\s+(?<from>[^.\n;]{2,80})\s+with\s+(?<text>[^.\n;]{2,120})/gi, confidence: 0.85 },
24
+ // Chose X over Y
25
+ { kind: "chose-over", re: /\bch(?:ose|ooses?)\s+(?<text>[^.\n;]{2,80})\s+over\s+(?<from>[^.\n;]{2,80})/gi, confidence: 0.85 },
26
+ // Use X instead of Y — text is lazy so it stops at "instead" instead of greedily eating it.
27
+ { kind: "instead-of", re: /\b(?:use|using|used)\s+(?<text>\S[^.\n;]*?)\s+instead\s+of\s+(?<from>[^.\n;]{2,80})/gi, confidence: 0.8 },
28
+ // Adopted X
29
+ { kind: "adopted", re: /\b(?:we\s+)?adopt(?:ed|ing)?\s+(?<text>[^.\n;]{4,120})/gi, confidence: 0.65 },
30
+ // Deprecated X / Deprecate X
31
+ { kind: "deprecated", re: /\bdeprecat(?:e|ed|ing)\s+(?<text>[^.\n;]{2,120})/gi, confidence: 0.75 },
32
+ // Rejected (the opposite — a decision NOT to do something)
33
+ { kind: "rejected", re: /\b(?:we\s+)?reject(?:ed|ing)?\s+(?<text>[^.\n;]{4,120})/gi, confidence: 0.6 },
34
+ ];
35
+ const RATIONALE_RE = /\b(?:because|so\s+that|in\s+order\s+to|due\s+to)\s+(?<rationale>[^.\n;]{4,200})/i;
36
+ /**
37
+ * Extract every decision in a single commit's text (subject + body + PR
38
+ * title + PR body). Returns 0..N decisions; one commit can record several.
39
+ */
40
+ export function extractDecisions(commit) {
41
+ const fullText = [commit.subject, commit.body, commit.prTitle, commit.prBody]
42
+ .filter(Boolean)
43
+ .join("\n");
44
+ if (!fullText)
45
+ return [];
46
+ const found = [];
47
+ const seen = new Set(); // dedupe by summary text
48
+ for (const p of PATTERNS) {
49
+ // Re-create regex per call to reset lastIndex.
50
+ const re = new RegExp(p.re.source, p.re.flags);
51
+ let m;
52
+ while ((m = re.exec(fullText)) !== null) {
53
+ const text = (m.groups?.text ?? "").trim();
54
+ const from = (m.groups?.from ?? "").trim();
55
+ // Min 2 chars — code identifiers like "Go", "DB", "JS", "Map" are real.
56
+ if (!text || text.length < 2)
57
+ continue;
58
+ const summary = buildSummary(p.kind, text, from);
59
+ if (seen.has(summary.toLowerCase()))
60
+ continue;
61
+ seen.add(summary.toLowerCase());
62
+ // Look for a rationale within ~120 chars after the match.
63
+ const tail = fullText.slice(m.index, m.index + m[0].length + 200);
64
+ const ratMatch = RATIONALE_RE.exec(tail);
65
+ const rationale = ratMatch?.groups?.rationale?.trim();
66
+ found.push({
67
+ commitHash: commit.hash,
68
+ shortHash: commit.shortHash || commit.hash.slice(0, 7),
69
+ date: commit.authorDate.slice(0, 10),
70
+ author: commit.authorName,
71
+ summary,
72
+ rationale: rationale || undefined,
73
+ kind: p.kind,
74
+ confidence: p.confidence,
75
+ });
76
+ }
77
+ }
78
+ return found;
79
+ }
80
+ function buildSummary(kind, text, from) {
81
+ const t = text.replace(/\s+/g, " ").replace(/^[,:\s]+|[,:\s]+$/g, "");
82
+ const f = from.replace(/\s+/g, " ").replace(/^[,:\s]+|[,:\s]+$/g, "");
83
+ switch (kind) {
84
+ case "decided-to":
85
+ return `decided to ${t}`;
86
+ case "switched":
87
+ return `switched from ${f} to ${t}`;
88
+ case "migrated":
89
+ return `migrated from ${f} to ${t}`;
90
+ case "replaced":
91
+ return `replaced ${f} with ${t}`;
92
+ case "chose-over":
93
+ return `chose ${t} over ${f}`;
94
+ case "instead-of":
95
+ return `using ${t} instead of ${f}`;
96
+ case "adopted":
97
+ return `adopted ${t}`;
98
+ case "deprecated":
99
+ return `deprecated ${t}`;
100
+ case "rejected":
101
+ return `rejected ${t}`;
102
+ }
103
+ }
104
+ /**
105
+ * Render a list of decisions as a Markdown table. Useful for
106
+ * `mneme decisions --format markdown > docs/ADR.md`.
107
+ */
108
+ export function renderDecisionsAsMarkdown(decisions) {
109
+ if (decisions.length === 0) {
110
+ return "# Architecture Decisions\n\n(no decisions extracted — try richer commit messages)\n";
111
+ }
112
+ const lines = [];
113
+ lines.push("# Architecture Decisions (auto-extracted)");
114
+ lines.push("");
115
+ lines.push("| Date | Author | Decision | Rationale | Source |");
116
+ lines.push("|---|---|---|---|---|");
117
+ for (const d of decisions) {
118
+ const decision = d.summary.replace(/\|/g, "\\|");
119
+ const rationale = (d.rationale ?? "").replace(/\|/g, "\\|");
120
+ lines.push(`| ${d.date} | ${d.author} | ${decision} | ${rationale} | \`${d.shortHash}\` |`);
121
+ }
122
+ lines.push("");
123
+ return lines.join("\n");
124
+ }
125
+ //# sourceMappingURL=decisions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../src/insights/decisions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=decisions.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.test.d.ts","sourceRoot":"","sources":["../../src/insights/decisions.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,141 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { extractDecisions, renderDecisionsAsMarkdown } from "./decisions.js";
3
+ const commit = (subject, body = "") => ({
4
+ hash: "abcdef1234567890abcdef1234567890abcdef12",
5
+ shortHash: "abcdef1",
6
+ authorName: "alice",
7
+ authorEmail: "alice@example.com",
8
+ authorDate: "2024-08-12T00:00:00Z",
9
+ committerDate: "2024-08-12T00:00:00Z",
10
+ subject,
11
+ body,
12
+ parents: [],
13
+ files: [],
14
+ });
15
+ describe("extractDecisions — high-precision patterns", () => {
16
+ it('catches "decided to X"', () => {
17
+ const out = extractDecisions(commit("refactor: decided to use Postgres for write-heavy paths"));
18
+ expect(out).toHaveLength(1);
19
+ expect(out[0].kind).toBe("decided-to");
20
+ expect(out[0].summary).toContain("Postgres");
21
+ });
22
+ it('catches "switched from X to Y" with rationale', () => {
23
+ const out = extractDecisions(commit("auth: switched from passport to custom middleware", "switched from passport to custom JWT because legal flagged session token storage"));
24
+ expect(out.length).toBeGreaterThan(0);
25
+ const switched = out.find((d) => d.kind === "switched");
26
+ expect(switched).toBeDefined();
27
+ expect(switched.summary).toContain("from passport to custom");
28
+ expect(switched.rationale).toContain("legal");
29
+ });
30
+ it('catches "replaced X with Y"', () => {
31
+ const out = extractDecisions(commit("replaced lodash with native methods"));
32
+ expect(out.find((d) => d.kind === "replaced")).toBeDefined();
33
+ });
34
+ it('catches "chose X over Y"', () => {
35
+ const out = extractDecisions(commit("chose pnpm over npm for monorepo workspaces"));
36
+ const d = out.find((d) => d.kind === "chose-over");
37
+ expect(d).toBeDefined();
38
+ expect(d.summary).toContain("pnpm over npm");
39
+ });
40
+ it('catches "use X instead of Y"', () => {
41
+ const out = extractDecisions(commit("perf: use Map instead of plain object for hot path"));
42
+ expect(out.find((d) => d.kind === "instead-of")).toBeDefined();
43
+ });
44
+ it('catches "deprecated X"', () => {
45
+ const out = extractDecisions(commit("deprecate the legacy /api/v1/auth endpoint"));
46
+ expect(out.find((d) => d.kind === "deprecated")).toBeDefined();
47
+ });
48
+ it('catches "migrated from X to Y"', () => {
49
+ const out = extractDecisions(commit("infra: migrated from Redis to Valkey for license"));
50
+ expect(out.find((d) => d.kind === "migrated")).toBeDefined();
51
+ });
52
+ it('catches "adopted X"', () => {
53
+ const out = extractDecisions(commit("ci: adopted GitHub Actions over Jenkins"));
54
+ expect(out.find((d) => d.kind === "adopted")).toBeDefined();
55
+ });
56
+ });
57
+ describe("extractDecisions — false positives stay low", () => {
58
+ it("does not fire on simple progress commits", () => {
59
+ expect(extractDecisions(commit("fix: typo in README"))).toEqual([]);
60
+ expect(extractDecisions(commit("wip: more tests"))).toEqual([]);
61
+ expect(extractDecisions(commit("update package-lock.json"))).toEqual([]);
62
+ });
63
+ it("does not fire when 'decided' appears without 'to'", () => {
64
+ expect(extractDecisions(commit("the team decided unanimously"))).toEqual([]);
65
+ });
66
+ it("does not fire on too-short text after the trigger", () => {
67
+ // "decided to X" — needs >= 8 chars after, so a 5-char tail is rejected.
68
+ expect(extractDecisions(commit("we decided to wait"))).toEqual([]);
69
+ });
70
+ });
71
+ describe("extractDecisions — rationale capture", () => {
72
+ it('captures "because ..." rationale', () => {
73
+ const out = extractDecisions(commit("auth: switched from passport to custom JWT because compliance flagged session token storage"));
74
+ expect(out[0].rationale).toContain("compliance");
75
+ });
76
+ it('captures "so that ..." rationale', () => {
77
+ const out = extractDecisions(commit("infra: switched from Redis to Valkey so that we keep BSD license compatibility"));
78
+ expect(out[0].rationale).toContain("BSD");
79
+ });
80
+ it("rationale is undefined when no marker present", () => {
81
+ const out = extractDecisions(commit("decided to drop synchronous fs.readFileSync calls"));
82
+ expect(out[0].rationale).toBeUndefined();
83
+ });
84
+ });
85
+ describe("extractDecisions — multi-decision and dedupe", () => {
86
+ it("returns multiple decisions when a commit records several", () => {
87
+ const out = extractDecisions(commit("perf: replaced lodash with native methods", "Also adopted Bun for tests because it is fast."));
88
+ expect(out.length).toBeGreaterThanOrEqual(2);
89
+ const kinds = out.map((d) => d.kind);
90
+ expect(kinds).toContain("replaced");
91
+ expect(kinds).toContain("adopted");
92
+ });
93
+ it("dedupes the same summary if the same line is matched by multiple patterns", () => {
94
+ // A potentially tricky case: "decided to switch from A to B" — both
95
+ // 'decided-to' and 'switched' could fire. Both are useful but on
96
+ // different summary text, so we keep both.
97
+ const out = extractDecisions(commit("decided to switch from passport to custom JWT"));
98
+ const summaries = out.map((d) => d.summary);
99
+ expect(new Set(summaries).size).toBe(summaries.length); // no exact duplicates
100
+ });
101
+ });
102
+ describe("renderDecisionsAsMarkdown", () => {
103
+ it("renders a markdown table with Date, Author, Decision, Rationale, Source", () => {
104
+ const out = renderDecisionsAsMarkdown([
105
+ {
106
+ commitHash: "abc1234",
107
+ shortHash: "abc1234",
108
+ date: "2024-08-12",
109
+ author: "alice",
110
+ summary: "switched from passport to custom JWT",
111
+ rationale: "compliance",
112
+ kind: "switched",
113
+ confidence: 0.9,
114
+ },
115
+ ]);
116
+ expect(out).toContain("| Date | Author | Decision | Rationale | Source |");
117
+ expect(out).toContain("alice");
118
+ expect(out).toContain("switched from passport to custom JWT");
119
+ expect(out).toContain("compliance");
120
+ expect(out).toContain("`abc1234`");
121
+ });
122
+ it("renders a friendly fallback when there are no decisions", () => {
123
+ const out = renderDecisionsAsMarkdown([]);
124
+ expect(out.toLowerCase()).toContain("no decisions extracted");
125
+ });
126
+ it("escapes pipe characters to keep the table valid", () => {
127
+ const out = renderDecisionsAsMarkdown([
128
+ {
129
+ commitHash: "x",
130
+ shortHash: "xxxxxxx",
131
+ date: "2024-01-01",
132
+ author: "bob",
133
+ summary: "decided to use a|b matching",
134
+ kind: "decided-to",
135
+ confidence: 0.95,
136
+ },
137
+ ]);
138
+ expect(out).toContain("a\\|b");
139
+ });
140
+ });
141
+ //# sourceMappingURL=decisions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.test.js","sourceRoot":"","sources":["../../src/insights/decisions.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAG7E,MAAM,MAAM,GAAG,CAAC,OAAe,EAAE,IAAI,GAAG,EAAE,EAAU,EAAE,CAAC,CAAC;IACtD,IAAI,EAAE,0CAA0C;IAChD,SAAS,EAAE,SAAS;IACpB,UAAU,EAAE,OAAO;IACnB,WAAW,EAAE,mBAAmB;IAChC,UAAU,EAAE,sBAAsB;IAClC,aAAa,EAAE,sBAAsB;IACrC,OAAO;IACP,IAAI;IACJ,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,EAAE;CACV,CAAC,CAAC;AAEH,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC,CAAC;QAChG,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,GAAG,GAAG,gBAAgB,CAC1B,MAAM,CACJ,mDAAmD,EACnD,kFAAkF,CACnF,CACF,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QACxD,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,CAAC,QAAS,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;QAC/D,MAAM,CAAC,QAAS,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC;QAC5E,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,6CAA6C,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;QACnD,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,oDAAoD,CAAC,CAAC,CAAC;QAC3F,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,4CAA4C,CAAC,CAAC,CAAC;QACnF,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,kDAAkD,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAChF,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChE,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,yEAAyE;QACzE,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,GAAG,GAAG,gBAAgB,CAC1B,MAAM,CAAC,6FAA6F,CAAC,CACtG,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,GAAG,GAAG,gBAAgB,CAC1B,MAAM,CAAC,gFAAgF,CAAC,CACzF,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,mDAAmD,CAAC,CAAC,CAAC;QAC1F,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,GAAG,GAAG,gBAAgB,CAC1B,MAAM,CACJ,2CAA2C,EAC3C,gDAAgD,CACjD,CACF,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;QACnF,oEAAoE;QACpE,iEAAiE;QACjE,2CAA2C;QAC3C,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,+CAA+C,CAAC,CAAC,CAAC;QACtF,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,sBAAsB;IAChF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,GAAG,GAAG,yBAAyB,CAAC;YACpC;gBACE,UAAU,EAAE,SAAS;gBACrB,SAAS,EAAE,SAAS;gBACpB,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,OAAO;gBACf,OAAO,EAAE,sCAAsC;gBAC/C,SAAS,EAAE,YAAY;gBACvB,IAAI,EAAE,UAAU;gBAChB,UAAU,EAAE,GAAG;aAChB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,mDAAmD,CAAC,CAAC;QAC3E,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACpC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,GAAG,GAAG,yBAAyB,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,GAAG,GAAG,yBAAyB,CAAC;YACpC;gBACE,UAAU,EAAE,GAAG;gBACf,SAAS,EAAE,SAAS;gBACpB,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,6BAA6B;gBACtC,IAAI,EAAE,YAAY;gBAClB,UAAU,EAAE,IAAI;aACjB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * `dream` — speculative ideas from your codebase patterns.
3
+ *
4
+ * The premise: every codebase has *latent shape*. Authentication, payments,
5
+ * logging, queue patterns repeat in similar idioms. Given the patterns you
6
+ * already use, an LLM can suggest features that would fit your codebase's
7
+ * style — citing the existing patterns it learned from.
8
+ *
9
+ * This is the most "AI from the future" command: instead of "what does X
10
+ * do?", it answers "what could you build next that fits your style?"
11
+ *
12
+ * Pure data extraction here (signal gathering); LLM call lives in the CLI.
13
+ */
14
+ import type { MnemeStore } from "../store/sqlite.js";
15
+ export interface RepoSignals {
16
+ totalCommits: number;
17
+ totalEntities: number;
18
+ /** Top 10 most common file-extension languages by entity count. */
19
+ languages: Array<{
20
+ name: string;
21
+ count: number;
22
+ }>;
23
+ /** Recent commit subjects — most recent first, capped at 30. */
24
+ recentSubjects: string[];
25
+ /** Modules (top-2 path segments) ranked by entity count. */
26
+ topModules: Array<{
27
+ name: string;
28
+ count: number;
29
+ }>;
30
+ /** Common entity-name suffixes ("Service", "Controller", "Adapter"). */
31
+ patternSuffixes: Array<{
32
+ suffix: string;
33
+ count: number;
34
+ }>;
35
+ /** Total incidents indexed (if any). */
36
+ totalIncidents: number;
37
+ }
38
+ export interface DreamIdea {
39
+ /** Short title, e.g. "MultiCurrencyAdapter" or "WebhookReplay". */
40
+ title: string;
41
+ /** 2-3 sentence pitch. */
42
+ pitch: string;
43
+ /** Existing patterns in the repo this idea would mirror. */
44
+ precedents: string[];
45
+ /** Effort hint: "small" | "medium" | "large". */
46
+ effort: "small" | "medium" | "large";
47
+ /** Risk hint based on what the idea touches. */
48
+ risk: "low" | "medium" | "high";
49
+ }
50
+ /**
51
+ * Gather signals from the indexed memory. Pure read-only — no LLM call.
52
+ * Designed to fit into one LLM prompt without truncation.
53
+ */
54
+ export declare function gatherRepoSignals(store: MnemeStore): RepoSignals;
55
+ /**
56
+ * Build the prompt for the dream LLM. Compact enough to fit a small Ollama
57
+ * model (llama3.2:3b) without truncation, but rich enough to ground the
58
+ * speculation in real signals.
59
+ */
60
+ export declare function buildDreamPrompt(signals: RepoSignals, n: number): string;
61
+ /**
62
+ * Parse LLM JSON output into typed DreamIdea[] with permissive validation.
63
+ * Returns [] on parse failure rather than throwing — dream is best-effort.
64
+ */
65
+ export declare function parseDreamIdeas(raw: string): DreamIdea[];
66
+ /**
67
+ * No-LLM fallback — generate ideas from heuristic patterns. Useful for
68
+ * deterministic mode and as a sanity-check baseline.
69
+ */
70
+ export declare function heuristicDream(signals: RepoSignals, n: number): DreamIdea[];
71
+ //# sourceMappingURL=dream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dream.d.ts","sourceRoot":"","sources":["../../src/insights/dream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,gEAAgE;IAChE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4DAA4D;IAC5D,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,wEAAwE;IACxE,eAAe,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iDAAiD;IACjD,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrC,gDAAgD;IAChD,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAoEhE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CA6BxE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CAgCxD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CA8D3E"}