mneme-ai 0.8.3

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 (107) hide show
  1. package/README.md +45 -0
  2. package/bin/mneme.js +2 -0
  3. package/dist/commands/adapt.d.ts +6 -0
  4. package/dist/commands/adapt.d.ts.map +1 -0
  5. package/dist/commands/adapt.js +219 -0
  6. package/dist/commands/adapt.js.map +1 -0
  7. package/dist/commands/ask.d.ts +8 -0
  8. package/dist/commands/ask.d.ts.map +1 -0
  9. package/dist/commands/ask.js +76 -0
  10. package/dist/commands/ask.js.map +1 -0
  11. package/dist/commands/blast.d.ts +8 -0
  12. package/dist/commands/blast.d.ts.map +1 -0
  13. package/dist/commands/blast.js +132 -0
  14. package/dist/commands/blast.js.map +1 -0
  15. package/dist/commands/clones.d.ts +19 -0
  16. package/dist/commands/clones.d.ts.map +1 -0
  17. package/dist/commands/clones.js +155 -0
  18. package/dist/commands/clones.js.map +1 -0
  19. package/dist/commands/conscience.d.ts +15 -0
  20. package/dist/commands/conscience.d.ts.map +1 -0
  21. package/dist/commands/conscience.js +202 -0
  22. package/dist/commands/conscience.js.map +1 -0
  23. package/dist/commands/correlate.d.ts +18 -0
  24. package/dist/commands/correlate.d.ts.map +1 -0
  25. package/dist/commands/correlate.js +173 -0
  26. package/dist/commands/correlate.js.map +1 -0
  27. package/dist/commands/echo.d.ts +16 -0
  28. package/dist/commands/echo.d.ts.map +1 -0
  29. package/dist/commands/echo.js +175 -0
  30. package/dist/commands/echo.js.map +1 -0
  31. package/dist/commands/genius.d.ts +13 -0
  32. package/dist/commands/genius.d.ts.map +1 -0
  33. package/dist/commands/genius.js +213 -0
  34. package/dist/commands/genius.js.map +1 -0
  35. package/dist/commands/heal.d.ts +22 -0
  36. package/dist/commands/heal.d.ts.map +1 -0
  37. package/dist/commands/heal.js +160 -0
  38. package/dist/commands/heal.js.map +1 -0
  39. package/dist/commands/index-cmd.d.ts +9 -0
  40. package/dist/commands/index-cmd.d.ts.map +1 -0
  41. package/dist/commands/index-cmd.js +74 -0
  42. package/dist/commands/index-cmd.js.map +1 -0
  43. package/dist/commands/init.d.ts +6 -0
  44. package/dist/commands/init.d.ts.map +1 -0
  45. package/dist/commands/init.js +34 -0
  46. package/dist/commands/init.js.map +1 -0
  47. package/dist/commands/mcp.d.ts +4 -0
  48. package/dist/commands/mcp.d.ts.map +1 -0
  49. package/dist/commands/mcp.js +10 -0
  50. package/dist/commands/mcp.js.map +1 -0
  51. package/dist/commands/palimpsest.d.ts +22 -0
  52. package/dist/commands/palimpsest.d.ts.map +1 -0
  53. package/dist/commands/palimpsest.js +164 -0
  54. package/dist/commands/palimpsest.js.map +1 -0
  55. package/dist/commands/status.d.ts +4 -0
  56. package/dist/commands/status.d.ts.map +1 -0
  57. package/dist/commands/status.js +49 -0
  58. package/dist/commands/status.js.map +1 -0
  59. package/dist/commands/teach.d.ts +16 -0
  60. package/dist/commands/teach.d.ts.map +1 -0
  61. package/dist/commands/teach.js +237 -0
  62. package/dist/commands/teach.js.map +1 -0
  63. package/dist/commands/teach.test.d.ts +2 -0
  64. package/dist/commands/teach.test.d.ts.map +1 -0
  65. package/dist/commands/teach.test.js +44 -0
  66. package/dist/commands/teach.test.js.map +1 -0
  67. package/dist/commands/why.d.ts +12 -0
  68. package/dist/commands/why.d.ts.map +1 -0
  69. package/dist/commands/why.js +85 -0
  70. package/dist/commands/why.js.map +1 -0
  71. package/dist/commands/wild-features.d.ts +42 -0
  72. package/dist/commands/wild-features.d.ts.map +1 -0
  73. package/dist/commands/wild-features.js +483 -0
  74. package/dist/commands/wild-features.js.map +1 -0
  75. package/dist/commands/wild-stubs.d.ts +6 -0
  76. package/dist/commands/wild-stubs.d.ts.map +1 -0
  77. package/dist/commands/wild-stubs.js +112 -0
  78. package/dist/commands/wild-stubs.js.map +1 -0
  79. package/dist/commands/wisdom.d.ts +13 -0
  80. package/dist/commands/wisdom.d.ts.map +1 -0
  81. package/dist/commands/wisdom.js +94 -0
  82. package/dist/commands/wisdom.js.map +1 -0
  83. package/dist/config.d.ts +26 -0
  84. package/dist/config.d.ts.map +1 -0
  85. package/dist/config.js +28 -0
  86. package/dist/config.js.map +1 -0
  87. package/dist/index.d.ts +2 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +371 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/meditations.d.ts +24 -0
  92. package/dist/meditations.d.ts.map +1 -0
  93. package/dist/meditations.js +120 -0
  94. package/dist/meditations.js.map +1 -0
  95. package/dist/meditations.test.d.ts +2 -0
  96. package/dist/meditations.test.d.ts.map +1 -0
  97. package/dist/meditations.test.js +70 -0
  98. package/dist/meditations.test.js.map +1 -0
  99. package/dist/paths.d.ts +7 -0
  100. package/dist/paths.d.ts.map +1 -0
  101. package/dist/paths.js +14 -0
  102. package/dist/paths.js.map +1 -0
  103. package/dist/ui.d.ts +12 -0
  104. package/dist/ui.d.ts.map +1 -0
  105. package/dist/ui.js +30 -0
  106. package/dist/ui.js.map +1 -0
  107. package/package.json +46 -0
@@ -0,0 +1,237 @@
1
+ /**
2
+ * `mneme teach` — explain a folder or file in plain language.
3
+ *
4
+ * Inspiration: tools like Understand-Anything turn codebases into "knowledge
5
+ * graphs" they then *teach*. Mneme already has the indexing primitives. The
6
+ * remaining piece was a small command that synthesizes a short, honest
7
+ * summary from the entities + git context — using the same LLM enricher
8
+ * shipped for `mneme heal`.
9
+ *
10
+ * Three passes (a small "agent pipeline" without ceremony):
11
+ * 1. CLASSIFY — assign each entity a layer (api / service / data / ui /
12
+ * utility / unknown) using path heuristics.
13
+ * 2. AGGREGATE — count by layer + sample names.
14
+ * 3. SUMMARIZE — let the LLM write 3-5 sentences of plain prose.
15
+ *
16
+ * For a single file: the LLM gets the file's source + a short list of its
17
+ * entities and writes a paragraph. For a folder: the aggregate counts +
18
+ * 10 representative entity names and writes the summary.
19
+ */
20
+ import { existsSync, readFileSync, statSync } from "node:fs";
21
+ import { join } from "node:path";
22
+ import kleur from "kleur";
23
+ import { git, store } from "@mneme-ai/core";
24
+ import { resolveEnricher } from "@mneme-ai/embeddings";
25
+ import { dbPath } from "../paths.js";
26
+ import { ui } from "../ui.js";
27
+ // Order matters: more specific rules come first.
28
+ // Tests checked first because `core/tests/foo.ts` is "first and foremost" a test,
29
+ // even though it lives under a service-like folder.
30
+ const LAYER_RULES = [
31
+ { layer: "test", pattern: /(^|\/)(tests?|__tests__|specs?)(\/|$)/ },
32
+ { layer: "config", pattern: /(\.config\.|^config\/|\/config\/)/ },
33
+ { layer: "api", pattern: /(^|\/)(api|routes?|controllers?|handlers?|endpoints?|server)(\/|$)/ },
34
+ { layer: "service", pattern: /(^|\/)(services?|business|domain|usecases?|core)(\/|$)/ },
35
+ { layer: "data", pattern: /(^|\/)(repositor(y|ies)|store|stores|db|database|models?|data)(\/|$)/ },
36
+ { layer: "ui", pattern: /(^|\/)(ui|components?|views?|pages?|screens?|app)(\/|$)/ },
37
+ { layer: "utility", pattern: /(^|\/)(util|utils|helpers?|lib|common|shared)(\/|$)/ },
38
+ ];
39
+ function classifyLayer(filePath) {
40
+ const p = filePath.toLowerCase();
41
+ for (const r of LAYER_RULES) {
42
+ if (r.pattern.test(p))
43
+ return r.layer;
44
+ }
45
+ if (/\.(test|spec)\./.test(p))
46
+ return "test";
47
+ return "unknown";
48
+ }
49
+ export async function teachCommand(opts) {
50
+ if (!(await git.isGitRepo(opts.cwd))) {
51
+ ui.error("Not in a git repo. Run `mneme init` first.");
52
+ return 1;
53
+ }
54
+ const meta = await git.getRepoMeta(opts.cwd);
55
+ const targetPath = join(meta.rootPath, opts.target);
56
+ if (!existsSync(targetPath)) {
57
+ ui.error(`No such path: ${opts.target}`);
58
+ return 1;
59
+ }
60
+ const isDir = statSync(targetPath).isDirectory();
61
+ const s = new store.MnemeStore(dbPath(meta.rootPath));
62
+ ui.banner();
63
+ process.stdout.write(`${kleur.bold().cyan("Teach")} ${opts.target} ${kleur.gray(`(${isDir ? "folder" : "file"})`)}\n\n`);
64
+ // 1. CLASSIFY — pull entities under this path and tag layers.
65
+ const allEntities = loadEntitiesUnder(s, opts.target);
66
+ const layered = allEntities.map((e) => ({ ...e, layer: classifyLayer(e.filePath) }));
67
+ // 2. AGGREGATE
68
+ const layerCounts = new Map();
69
+ for (const e of layered) {
70
+ layerCounts.set(e.layer, (layerCounts.get(e.layer) ?? 0) + 1);
71
+ }
72
+ const sortedLayers = Array.from(layerCounts.entries()).sort((a, b) => b[1] - a[1]);
73
+ process.stdout.write(`${kleur.bold().magenta("Layers")}\n`);
74
+ if (sortedLayers.length === 0) {
75
+ process.stdout.write(` ${kleur.gray("(no entities indexed under this path — run `mneme entities`)")}\n`);
76
+ }
77
+ for (const [layer, n] of sortedLayers) {
78
+ process.stdout.write(` ${kleur.gray("·")} ${kleur.bold(layer.padEnd(8))} ${n}\n`);
79
+ }
80
+ process.stdout.write("\n");
81
+ // 3. SUMMARIZE — call the enricher.
82
+ let enricher;
83
+ try {
84
+ enricher = await resolveEnricher({
85
+ provider: opts.provider ?? "auto",
86
+ model: opts.model,
87
+ });
88
+ }
89
+ catch (err) {
90
+ ui.warn(`No enricher available: ${err.message}`);
91
+ ui.dim("Install Ollama (recommended): https://ollama.com");
92
+ ui.dim("Then pull a small chat model: ollama pull llama3.2:1b");
93
+ if (opts.json) {
94
+ process.stdout.write(JSON.stringify({ target: opts.target, layers: Object.fromEntries(layerCounts) }, null, 2) + "\n");
95
+ }
96
+ s.close();
97
+ return 0;
98
+ }
99
+ const prompt = isDir
100
+ ? buildFolderPrompt(opts.target, layered, sortedLayers)
101
+ : buildFilePrompt(opts.target, targetPath, layered);
102
+ ui.step("teaching", `${enricher.name} …`);
103
+ let summary = "";
104
+ try {
105
+ const out = await enricher.enrich({
106
+ system: TEACH_SYSTEM_PROMPT,
107
+ user: prompt,
108
+ temperature: 0.2,
109
+ maxTokens: 280,
110
+ });
111
+ summary = out.text;
112
+ }
113
+ catch (err) {
114
+ ui.warn(`Enricher failed: ${err.message}`);
115
+ s.close();
116
+ return 1;
117
+ }
118
+ if (opts.json) {
119
+ process.stdout.write(JSON.stringify({
120
+ target: opts.target,
121
+ isDir,
122
+ entityCount: layered.length,
123
+ layers: Object.fromEntries(layerCounts),
124
+ summary,
125
+ }, null, 2) + "\n");
126
+ s.close();
127
+ return 0;
128
+ }
129
+ process.stdout.write(`\n${kleur.bold().magenta("Summary")}\n`);
130
+ for (const line of wrap(summary, 78).split("\n")) {
131
+ process.stdout.write(` ${line}\n`);
132
+ }
133
+ process.stdout.write("\n" +
134
+ kleur.gray(` generated by ${enricher.name} · entities are layer-tagged via path heuristics`) +
135
+ "\n");
136
+ s.close();
137
+ return 0;
138
+ }
139
+ const TEACH_SYSTEM_PROMPT = `You are explaining a folder or file from a codebase to a new contributor.
140
+ Write 3-5 sentences in plain prose. No bullet lists. No markdown.
141
+
142
+ Rules:
143
+ 1. Refer ONLY to entities and signatures that the user provided. Do not invent names.
144
+ 2. Open with what the unit DOES (its purpose), not what it IS.
145
+ 3. Mention the dominant layer (api / service / data / ui / utility) if obvious.
146
+ 4. If you don't know enough to answer, say "Cannot determine purpose from the listed entities alone."
147
+ 5. Avoid filler ("This file...", "Here we have..."). Open with the inferred purpose.
148
+
149
+ Output ONLY the summary. No preamble.`;
150
+ function loadEntitiesUnder(s, target) {
151
+ const norm = target.replace(/\\/g, "/").replace(/^\.\//, "");
152
+ // Use both equality and prefix match for files vs dirs.
153
+ const rows = s.db
154
+ .prepare(`SELECT id, kind, name, file_path, start_line, end_line, signature, language
155
+ FROM entities
156
+ WHERE file_path = ? OR file_path LIKE ?
157
+ ORDER BY file_path ASC, start_line ASC`)
158
+ .all(norm, norm.endsWith("/") ? norm + "%" : norm + "/%");
159
+ return rows.map((r) => ({
160
+ id: String(r.id),
161
+ kind: r.kind,
162
+ name: String(r.name),
163
+ filePath: String(r.file_path),
164
+ startLine: Number(r.start_line),
165
+ endLine: Number(r.end_line),
166
+ signature: r.signature ? String(r.signature) : undefined,
167
+ language: String(r.language),
168
+ }));
169
+ }
170
+ function buildFolderPrompt(target, layered, layerCounts) {
171
+ const lines = [];
172
+ lines.push(`Folder: ${target}`);
173
+ lines.push(`Total entities: ${layered.length}`);
174
+ lines.push(`Layers: ${layerCounts.map(([l, n]) => `${l}=${n}`).join(", ")}`);
175
+ lines.push("");
176
+ lines.push("Sample entities (top 12 by alphabet):");
177
+ for (const e of layered.slice(0, 12)) {
178
+ const sig = e.signature ? ` — ${e.signature.slice(0, 80)}` : "";
179
+ lines.push(` - [${e.kind}] ${e.name} (${e.filePath}:${e.startLine})${sig}`);
180
+ }
181
+ return lines.join("\n");
182
+ }
183
+ function buildFilePrompt(target, absPath, layered) {
184
+ const lines = [];
185
+ lines.push(`File: ${target}`);
186
+ let source = "";
187
+ try {
188
+ source = readFileSync(absPath, "utf8");
189
+ }
190
+ catch {
191
+ // ignore
192
+ }
193
+ if (source.length > 0 && source.length < 4000) {
194
+ lines.push("");
195
+ lines.push("Source:");
196
+ lines.push(source);
197
+ }
198
+ else if (source.length >= 4000) {
199
+ lines.push("");
200
+ lines.push("Source (first 4000 chars):");
201
+ lines.push(source.slice(0, 4000));
202
+ lines.push("…(truncated)");
203
+ }
204
+ if (layered.length) {
205
+ lines.push("");
206
+ lines.push("Indexed entities:");
207
+ for (const e of layered) {
208
+ const sig = e.signature ? ` — ${e.signature.slice(0, 80)}` : "";
209
+ lines.push(` - [${e.kind}] ${e.name} (line ${e.startLine})${sig}`);
210
+ }
211
+ }
212
+ return lines.join("\n");
213
+ }
214
+ function wrap(s, width) {
215
+ const out = [];
216
+ for (const para of s.split(/\n+/)) {
217
+ let line = "";
218
+ for (const word of para.split(/\s+/)) {
219
+ if ((line + " " + word).trim().length > width && line) {
220
+ out.push(line);
221
+ line = word;
222
+ }
223
+ else {
224
+ line += (line ? " " : "") + word;
225
+ }
226
+ }
227
+ if (line.trim())
228
+ out.push(line);
229
+ out.push("");
230
+ }
231
+ return out.join("\n").trim();
232
+ }
233
+ /**
234
+ * Exported for testing — pure helper, no I/O.
235
+ */
236
+ export const _classifyLayer = classifyLayer;
237
+ //# sourceMappingURL=teach.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teach.js","sourceRoot":"","sources":["../../src/commands/teach.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAY,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAe,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAY9B,iDAAiD;AACjD,kFAAkF;AAClF,oDAAoD;AACpD,MAAM,WAAW,GAA6C;IAC5D,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,uCAAuC,EAAE;IACnE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,mCAAmC,EAAE;IACjE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,oEAAoE,EAAE;IAC/F,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,wDAAwD,EAAE;IACvF,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,sEAAsE,EAAE;IAClG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,yDAAyD,EAAE;IACnF,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,qDAAqD,EAAE;CACrF,CAAC;AAEF,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,KAAK,CAAC;IACxC,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAyB;IAC1D,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACrC,EAAE,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEtD,EAAE,CAAC,MAAM,EAAE,CAAC;IACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;IAE1H,8DAA8D;IAC9D,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAErF,eAAe;IACf,MAAM,WAAW,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC,IAAI,CAAC,CAAC;IAC5G,CAAC;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,YAAY,EAAE,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE3B,oCAAoC;IACpC,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,eAAe,CAAC;YAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,MAAM;YACjC,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,EAAE,CAAC,IAAI,CAAC,0BAA2B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,EAAE,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAC3D,EAAE,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;QAChE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACzH,CAAC;QACD,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,KAAK;QAClB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC;QACvD,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAEtD,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;IAC1C,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YAChC,MAAM,EAAE,mBAAmB;YAC3B,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,GAAG;YAChB,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QACH,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;IACrB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,EAAE,CAAC,IAAI,CAAC,oBAAqB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CACZ;YACE,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK;YACL,WAAW,EAAE,OAAO,CAAC,MAAM;YAC3B,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC;YACvC,OAAO;SACR,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;QACF,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/D,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI;QACF,KAAK,CAAC,IAAI,CACR,kBAAkB,QAAQ,CAAC,IAAI,kDAAkD,CAClF;QACD,IAAI,CACP,CAAC;IAEF,CAAC,CAAC,KAAK,EAAE,CAAC;IACV,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,mBAAmB,GAAG;;;;;;;;;;sCAUU,CAAC;AAEvC,SAAS,iBAAiB,CAAC,CAAmB,EAAE,MAAc;IAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC7D,wDAAwD;IACxD,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE;SACd,OAAO,CACN;;;8CAGwC,CACzC;SACA,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAmC,CAAC;IAC9F,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtB,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,IAAI,EAAE,CAAC,CAAC,IAAsB;QAC9B,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7B,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;QAC/B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC3B,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QACxD,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;KAC7B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,iBAAiB,CACxB,MAAc,EACd,OAAyC,EACzC,WAAmC;IAEnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,WAAW,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,eAAe,CACtB,MAAc,EACd,OAAe,EACf,OAAyC;IAEzC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAC9B,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,IAAI,CAAC,CAAS,EAAE,KAAa;IACpC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;gBACtD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACf,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;YACnC,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=teach.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teach.test.d.ts","sourceRoot":"","sources":["../../src/commands/teach.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { _classifyLayer } from "./teach.js";
3
+ describe("classifyLayer", () => {
4
+ it("tags route/handler folders as 'api'", () => {
5
+ expect(_classifyLayer("src/api/users.ts")).toBe("api");
6
+ expect(_classifyLayer("server/routes/checkout.ts")).toBe("api");
7
+ expect(_classifyLayer("backend/handlers/webhook.ts")).toBe("api");
8
+ expect(_classifyLayer("src/controllers/order.ts")).toBe("api");
9
+ });
10
+ it("tags service/domain/usecase as 'service'", () => {
11
+ expect(_classifyLayer("src/services/payment.ts")).toBe("service");
12
+ expect(_classifyLayer("backend/domain/order.ts")).toBe("service");
13
+ expect(_classifyLayer("src/usecases/charge.ts")).toBe("service");
14
+ });
15
+ it("tags repos/db/models as 'data'", () => {
16
+ expect(_classifyLayer("src/repositories/user.ts")).toBe("data");
17
+ expect(_classifyLayer("backend/db/orders.ts")).toBe("data");
18
+ expect(_classifyLayer("src/models/cart.ts")).toBe("data");
19
+ });
20
+ it("tags components/views/screens as 'ui'", () => {
21
+ expect(_classifyLayer("src/ui/Button.tsx")).toBe("ui");
22
+ expect(_classifyLayer("src/components/Header.tsx")).toBe("ui");
23
+ expect(_classifyLayer("src/screens/Home.tsx")).toBe("ui");
24
+ expect(_classifyLayer("app/login.tsx")).toBe("ui");
25
+ });
26
+ it("tags utils/helpers/lib as 'utility'", () => {
27
+ expect(_classifyLayer("src/utils/format.ts")).toBe("utility");
28
+ expect(_classifyLayer("backend/lib/logger.ts")).toBe("utility");
29
+ expect(_classifyLayer("common/helpers.ts")).toBe("utility");
30
+ });
31
+ it("tags test paths as 'test'", () => {
32
+ expect(_classifyLayer("packages/core/tests/something.ts")).toBe("test");
33
+ expect(_classifyLayer("src/__tests__/foo.ts")).toBe("test");
34
+ expect(_classifyLayer("src/foo.test.ts")).toBe("test");
35
+ });
36
+ it("falls back to 'unknown' for unfamiliar paths", () => {
37
+ expect(_classifyLayer("random/foo.ts")).toBe("unknown");
38
+ expect(_classifyLayer("a/b/c.ts")).toBe("unknown");
39
+ });
40
+ it("is case-insensitive", () => {
41
+ expect(_classifyLayer("SRC/SERVICES/Foo.ts")).toBe("service");
42
+ });
43
+ });
44
+ //# sourceMappingURL=teach.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teach.test.js","sourceRoot":"","sources":["../../src/commands/teach.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `mneme why <file>[:<line>[-<line>]]`
3
+ *
4
+ * Combines blame + RAG to answer: "why does this code exist?"
5
+ */
6
+ export interface WhyOptions {
7
+ cwd: string;
8
+ target: string;
9
+ topK?: number;
10
+ }
11
+ export declare function whyCommand(opts: WhyOptions): Promise<number>;
12
+ //# sourceMappingURL=why.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"why.d.ts","sourceRoot":"","sources":["../../src/commands/why.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ElE"}
@@ -0,0 +1,85 @@
1
+ import { git, retrieve, store } from "@mneme-ai/core";
2
+ import { resolveEmbedder } from "@mneme-ai/embeddings";
3
+ import { dbPath } from "../paths.js";
4
+ import { readConfig } from "../config.js";
5
+ import { ui } from "../ui.js";
6
+ import kleur from "kleur";
7
+ export async function whyCommand(opts) {
8
+ if (!(await git.isGitRepo(opts.cwd))) {
9
+ ui.error("Not in a git repo. Run `mneme init` first.");
10
+ return 1;
11
+ }
12
+ const { file, startLine, endLine } = parseTarget(opts.target);
13
+ const meta = await git.getRepoMeta(opts.cwd);
14
+ const cfg = readConfig(meta.rootPath);
15
+ ui.banner();
16
+ process.stdout.write(`${kleur.bold().cyan("Why")} ${file}` + (startLine ? `:${startLine}${endLine ? `-${endLine}` : ""}` : "") + "\n\n");
17
+ const blamed = await git.blame(meta.rootPath, file, startLine, endLine);
18
+ if (!blamed.length) {
19
+ ui.warn("No blame data (file may be untracked or path wrong).");
20
+ return 1;
21
+ }
22
+ const tally = new Map();
23
+ for (const b of blamed) {
24
+ const cur = tally.get(b.commitHash);
25
+ if (cur)
26
+ cur.count++;
27
+ else
28
+ tally.set(b.commitHash, { count: 1, sample: b.content });
29
+ }
30
+ const ranked = Array.from(tally.entries())
31
+ .sort((a, b) => b[1].count - a[1].count)
32
+ .slice(0, 5);
33
+ process.stdout.write(`${kleur.bold().magenta("Originating commits")}\n`);
34
+ const s = new store.MnemeStore(dbPath(meta.rootPath));
35
+ for (const [hash, { count }] of ranked) {
36
+ const c = s.getCommit(hash);
37
+ if (!c) {
38
+ process.stdout.write(` ${kleur.gray("●")} ${hash.slice(0, 8)} ${kleur.gray("(not indexed)")}\n`);
39
+ continue;
40
+ }
41
+ const date = c.authorDate.slice(0, 10);
42
+ process.stdout.write(` ${kleur.green("●")} ${kleur.bold(c.shortHash)} ${kleur.gray(`[${date} · ${c.authorName} · ${count} lines]`)}\n`);
43
+ process.stdout.write(` ${c.subject}\n`);
44
+ }
45
+ if (s.countChunks() > 0) {
46
+ const embedder = await resolveEmbedder({
47
+ provider: cfg.embeddings.provider,
48
+ model: cfg.embeddings.model,
49
+ baseUrl: cfg.embeddings.baseUrl,
50
+ });
51
+ const seedQuery = ranked
52
+ .map(([h]) => s.getCommit(h)?.subject)
53
+ .filter(Boolean)
54
+ .join("\n");
55
+ if (seedQuery.trim()) {
56
+ const related = await retrieve.search(seedQuery, {
57
+ store: s,
58
+ embedder,
59
+ repo: meta,
60
+ topK: opts.topK ?? 5,
61
+ });
62
+ const filtered = related.filter((r) => !tally.has(r.commit.hash));
63
+ if (filtered.length) {
64
+ process.stdout.write(`\n${kleur.bold().magenta("Semantically related")}\n`);
65
+ for (const r of filtered.slice(0, 5)) {
66
+ const c = r.commit;
67
+ process.stdout.write(` ${kleur.cyan("◆")} ${kleur.bold(c.shortHash)} ${kleur.gray(`[${c.authorDate.slice(0, 10)}]`)} ${c.subject}\n`);
68
+ }
69
+ }
70
+ }
71
+ }
72
+ s.close();
73
+ return 0;
74
+ }
75
+ function parseTarget(s) {
76
+ const m = s.match(/^(.+?)(?::(\d+)(?:-(\d+))?)?$/);
77
+ if (!m)
78
+ return { file: s };
79
+ return {
80
+ file: m[1],
81
+ startLine: m[2] ? Number(m[2]) : undefined,
82
+ endLine: m[3] ? Number(m[3]) : m[2] ? Number(m[2]) : undefined,
83
+ };
84
+ }
85
+ //# sourceMappingURL=why.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"why.js","sourceRoot":"","sources":["../../src/commands/why.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export interface RunawayCommandOptions {
2
+ cwd: string;
3
+ topN?: number;
4
+ json?: boolean;
5
+ }
6
+ export declare function runawayCommand(opts: RunawayCommandOptions): Promise<number>;
7
+ export interface MirrorCommandOptions {
8
+ cwd: string;
9
+ topPrs?: number;
10
+ topPeople?: number;
11
+ topIncidents?: number;
12
+ json?: boolean;
13
+ }
14
+ export declare function mirrorCommand(opts: MirrorCommandOptions): Promise<number>;
15
+ export interface RumorCommandOptions {
16
+ cwd: string;
17
+ minMentions?: number;
18
+ json?: boolean;
19
+ }
20
+ export declare function rumorCommand(opts: RumorCommandOptions): Promise<number>;
21
+ export interface FossilCommandOptions {
22
+ cwd: string;
23
+ topN?: number;
24
+ json?: boolean;
25
+ }
26
+ export declare function fossilCommand(opts: FossilCommandOptions): Promise<number>;
27
+ export interface LedgerCommandOptions {
28
+ cwd: string;
29
+ since?: string;
30
+ until?: string;
31
+ format?: "json" | "csv";
32
+ out?: string;
33
+ }
34
+ /**
35
+ * `mneme ledger` — tamper-evident audit log derived from git history.
36
+ *
37
+ * For regulated industries (banks, exchanges, healthcare): every commit + author
38
+ * + linked ticket gets a hash-chained entry. Tampering with any entry breaks
39
+ * the chain — auditors can verify integrity in seconds.
40
+ */
41
+ export declare function ledgerCommand(opts: LedgerCommandOptions): Promise<number>;
42
+ //# sourceMappingURL=wild-features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wild-features.d.ts","sourceRoot":"","sources":["../../src/commands/wild-features.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkEjF;AAID,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqG/E;AAID,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwD7E;AAgFD,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0F/E;AAID,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAuBD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuH/E"}