@mneme-ai/core 0.8.4 → 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.
- package/dist/entities/go-parser.d.ts +47 -0
- package/dist/entities/go-parser.d.ts.map +1 -0
- package/dist/entities/go-parser.js +315 -0
- package/dist/entities/go-parser.js.map +1 -0
- package/dist/entities/go-parser.test.d.ts +2 -0
- package/dist/entities/go-parser.test.d.ts.map +1 -0
- package/dist/entities/go-parser.test.js +147 -0
- package/dist/entities/go-parser.test.js.map +1 -0
- package/dist/entities/index.d.ts +1 -0
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/index.js +1 -0
- package/dist/entities/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/indexer/indexer.d.ts +12 -0
- package/dist/indexer/indexer.d.ts.map +1 -1
- package/dist/indexer/indexer.js +28 -1
- package/dist/indexer/indexer.js.map +1 -1
- package/dist/insights/decisions.d.ts +38 -0
- package/dist/insights/decisions.d.ts.map +1 -0
- package/dist/insights/decisions.js +125 -0
- package/dist/insights/decisions.js.map +1 -0
- package/dist/insights/decisions.test.d.ts +2 -0
- package/dist/insights/decisions.test.d.ts.map +1 -0
- package/dist/insights/decisions.test.js +141 -0
- package/dist/insights/decisions.test.js.map +1 -0
- package/dist/insights/dream.d.ts +71 -0
- package/dist/insights/dream.d.ts.map +1 -0
- package/dist/insights/dream.js +235 -0
- package/dist/insights/dream.js.map +1 -0
- package/dist/insights/dream.test.d.ts +2 -0
- package/dist/insights/dream.test.d.ts.map +1 -0
- package/dist/insights/dream.test.js +127 -0
- package/dist/insights/dream.test.js.map +1 -0
- package/dist/insights/index.d.ts +16 -0
- package/dist/insights/index.d.ts.map +1 -0
- package/dist/insights/index.js +16 -0
- package/dist/insights/index.js.map +1 -0
- package/dist/insights/obsidian.d.ts +42 -0
- package/dist/insights/obsidian.d.ts.map +1 -0
- package/dist/insights/obsidian.js +263 -0
- package/dist/insights/obsidian.js.map +1 -0
- package/dist/insights/obsidian.test.d.ts +2 -0
- package/dist/insights/obsidian.test.d.ts.map +1 -0
- package/dist/insights/obsidian.test.js +241 -0
- package/dist/insights/obsidian.test.js.map +1 -0
- package/dist/insights/stack-trace.d.ts +40 -0
- package/dist/insights/stack-trace.d.ts.map +1 -0
- package/dist/insights/stack-trace.js +127 -0
- package/dist/insights/stack-trace.js.map +1 -0
- package/dist/insights/stack-trace.test.d.ts +2 -0
- package/dist/insights/stack-trace.test.d.ts.map +1 -0
- package/dist/insights/stack-trace.test.js +103 -0
- package/dist/insights/stack-trace.test.js.map +1 -0
- package/dist/insights/story.d.ts +34 -0
- package/dist/insights/story.d.ts.map +1 -0
- package/dist/insights/story.js +100 -0
- package/dist/insights/story.js.map +1 -0
- package/dist/insights/story.test.d.ts +2 -0
- package/dist/insights/story.test.d.ts.map +1 -0
- package/dist/insights/story.test.js +99 -0
- package/dist/insights/story.test.js.map +1 -0
- package/dist/insights/suggest.d.ts +29 -0
- package/dist/insights/suggest.d.ts.map +1 -0
- package/dist/insights/suggest.js +93 -0
- package/dist/insights/suggest.js.map +1 -0
- package/dist/insights/suggest.test.d.ts +2 -0
- package/dist/insights/suggest.test.d.ts.map +1 -0
- package/dist/insights/suggest.test.js +71 -0
- package/dist/insights/suggest.test.js.map +1 -0
- package/dist/insights/who-knows.d.ts +48 -0
- package/dist/insights/who-knows.d.ts.map +1 -0
- package/dist/insights/who-knows.js +96 -0
- package/dist/insights/who-knows.js.map +1 -0
- package/dist/insights/who-knows.test.d.ts +2 -0
- package/dist/insights/who-knows.test.d.ts.map +1 -0
- package/dist/insights/who-knows.test.js +47 -0
- package/dist/insights/who-knows.test.js.map +1 -0
- package/dist/retrieve/index.d.ts +2 -0
- package/dist/retrieve/index.d.ts.map +1 -1
- package/dist/retrieve/index.js +2 -0
- package/dist/retrieve/index.js.map +1 -1
- package/dist/retrieve/intent.d.ts +32 -0
- package/dist/retrieve/intent.d.ts.map +1 -0
- package/dist/retrieve/intent.js +104 -0
- package/dist/retrieve/intent.js.map +1 -0
- package/dist/retrieve/intent.test.d.ts +2 -0
- package/dist/retrieve/intent.test.d.ts.map +1 -0
- package/dist/retrieve/intent.test.js +106 -0
- package/dist/retrieve/intent.test.js.map +1 -0
- package/dist/retrieve/search.d.ts +30 -0
- package/dist/retrieve/search.d.ts.map +1 -1
- package/dist/retrieve/search.js +48 -0
- package/dist/retrieve/search.js.map +1 -1
- package/dist/retrieve/search.test.js +84 -1
- package/dist/retrieve/search.test.js.map +1 -1
- package/dist/retrieve/synthesize.d.ts +57 -0
- package/dist/retrieve/synthesize.d.ts.map +1 -0
- package/dist/retrieve/synthesize.js +160 -0
- package/dist/retrieve/synthesize.js.map +1 -0
- package/dist/retrieve/synthesize.test.d.ts +2 -0
- package/dist/retrieve/synthesize.test.d.ts.map +1 -0
- package/dist/retrieve/synthesize.test.js +116 -0
- package/dist/retrieve/synthesize.test.js.map +1 -0
- package/dist/store/schema.d.ts +2 -2
- package/dist/store/schema.d.ts.map +1 -1
- package/dist/store/schema.js +55 -1
- package/dist/store/schema.js.map +1 -1
- package/dist/store/sqlite.test.js +1 -1
- package/dist/util/index.d.ts +2 -0
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +2 -1
- package/dist/util/index.js.map +1 -1
- package/dist/util/redact.d.ts +58 -0
- package/dist/util/redact.d.ts.map +1 -0
- package/dist/util/redact.js +129 -0
- package/dist/util/redact.js.map +1 -0
- package/dist/util/redact.test.d.ts +2 -0
- package/dist/util/redact.test.d.ts.map +1 -0
- package/dist/util/redact.test.js +148 -0
- package/dist/util/redact.test.js.map +1 -0
- package/dist/wisdom/calibrator.d.ts +43 -0
- package/dist/wisdom/calibrator.d.ts.map +1 -0
- package/dist/wisdom/calibrator.js +120 -0
- package/dist/wisdom/calibrator.js.map +1 -0
- package/dist/wisdom/feedback.d.ts +45 -0
- package/dist/wisdom/feedback.d.ts.map +1 -0
- package/dist/wisdom/feedback.js +116 -0
- package/dist/wisdom/feedback.js.map +1 -0
- package/dist/wisdom/index.d.ts +15 -0
- package/dist/wisdom/index.d.ts.map +1 -0
- package/dist/wisdom/index.js +15 -0
- package/dist/wisdom/index.js.map +1 -0
- package/dist/wisdom/types.d.ts +67 -0
- package/dist/wisdom/types.d.ts.map +1 -0
- package/dist/wisdom/types.js +20 -0
- package/dist/wisdom/types.js.map +1 -0
- package/dist/wisdom/wisdom.test.d.ts +2 -0
- package/dist/wisdom/wisdom.test.d.ts.map +1 -0
- package/dist/wisdom/wisdom.test.js +144 -0
- package/dist/wisdom/wisdom.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,235 @@
|
|
|
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
|
+
/**
|
|
15
|
+
* Gather signals from the indexed memory. Pure read-only — no LLM call.
|
|
16
|
+
* Designed to fit into one LLM prompt without truncation.
|
|
17
|
+
*/
|
|
18
|
+
export function gatherRepoSignals(store) {
|
|
19
|
+
const totalCommits = store.countCommits();
|
|
20
|
+
// Incident count via raw query — store doesn't expose a helper.
|
|
21
|
+
let totalIncidents = 0;
|
|
22
|
+
try {
|
|
23
|
+
const row = store.db.prepare("SELECT COUNT(*) AS n FROM incidents").get();
|
|
24
|
+
totalIncidents = row?.n ?? 0;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// table may not exist yet on older DBs — treat as zero
|
|
28
|
+
}
|
|
29
|
+
// Language distribution from entities table.
|
|
30
|
+
const langRows = store.db
|
|
31
|
+
.prepare(`SELECT language, COUNT(*) AS n FROM entities GROUP BY language ORDER BY n DESC LIMIT 10`)
|
|
32
|
+
.all();
|
|
33
|
+
const languages = langRows.map((r) => ({ name: r.language, count: r.n }));
|
|
34
|
+
const totalEntities = languages.reduce((s, l) => s + l.count, 0);
|
|
35
|
+
// Recent commit subjects.
|
|
36
|
+
const recentRows = store.db
|
|
37
|
+
.prepare(`SELECT subject FROM commits ORDER BY author_date DESC LIMIT 30`)
|
|
38
|
+
.all();
|
|
39
|
+
const recentSubjects = recentRows.map((r) => r.subject);
|
|
40
|
+
// Top modules — first two path segments of file_path.
|
|
41
|
+
const moduleRows = store.db
|
|
42
|
+
.prepare(`SELECT file_path FROM entities`)
|
|
43
|
+
.all();
|
|
44
|
+
const moduleCounts = new Map();
|
|
45
|
+
for (const r of moduleRows) {
|
|
46
|
+
const parts = r.file_path.split("/");
|
|
47
|
+
const key = parts.length >= 2 ? `${parts[0]}/${parts[1]}` : parts[0];
|
|
48
|
+
moduleCounts.set(key, (moduleCounts.get(key) ?? 0) + 1);
|
|
49
|
+
}
|
|
50
|
+
const topModules = [...moduleCounts.entries()]
|
|
51
|
+
.map(([name, count]) => ({ name, count }))
|
|
52
|
+
.sort((a, b) => b.count - a.count)
|
|
53
|
+
.slice(0, 10);
|
|
54
|
+
// Pattern suffixes — entity names ending in a CamelCase suffix tell us
|
|
55
|
+
// about architectural style ("Service", "Controller", "Adapter", etc.).
|
|
56
|
+
const nameRows = store.db
|
|
57
|
+
.prepare(`SELECT name FROM entities WHERE kind IN ('class','function','type')`)
|
|
58
|
+
.all();
|
|
59
|
+
const suffixCounts = new Map();
|
|
60
|
+
const SUFFIX_RE = /([A-Z][a-z]+)$/;
|
|
61
|
+
for (const r of nameRows) {
|
|
62
|
+
const m = SUFFIX_RE.exec(r.name);
|
|
63
|
+
if (!m)
|
|
64
|
+
continue;
|
|
65
|
+
const s = m[1];
|
|
66
|
+
if (s.length < 4 || s.length > 20)
|
|
67
|
+
continue;
|
|
68
|
+
suffixCounts.set(s, (suffixCounts.get(s) ?? 0) + 1);
|
|
69
|
+
}
|
|
70
|
+
const patternSuffixes = [...suffixCounts.entries()]
|
|
71
|
+
.filter(([, n]) => n >= 2)
|
|
72
|
+
.map(([suffix, count]) => ({ suffix, count }))
|
|
73
|
+
.sort((a, b) => b.count - a.count)
|
|
74
|
+
.slice(0, 10);
|
|
75
|
+
return {
|
|
76
|
+
totalCommits,
|
|
77
|
+
totalEntities,
|
|
78
|
+
languages,
|
|
79
|
+
recentSubjects,
|
|
80
|
+
topModules,
|
|
81
|
+
patternSuffixes,
|
|
82
|
+
totalIncidents,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Build the prompt for the dream LLM. Compact enough to fit a small Ollama
|
|
87
|
+
* model (llama3.2:3b) without truncation, but rich enough to ground the
|
|
88
|
+
* speculation in real signals.
|
|
89
|
+
*/
|
|
90
|
+
export function buildDreamPrompt(signals, n) {
|
|
91
|
+
const lines = [];
|
|
92
|
+
lines.push("Given the signals below from a real codebase, suggest exactly", String(n), "speculative");
|
|
93
|
+
lines.push("ideas for features that would fit this codebase's style. Each idea should");
|
|
94
|
+
lines.push("cite at least one existing pattern from the signals as a precedent.");
|
|
95
|
+
lines.push("");
|
|
96
|
+
lines.push(`Total commits indexed: ${signals.totalCommits}`);
|
|
97
|
+
lines.push(`Total entities indexed: ${signals.totalEntities}`);
|
|
98
|
+
lines.push(`Total incidents recorded: ${signals.totalIncidents}`);
|
|
99
|
+
lines.push("");
|
|
100
|
+
lines.push("Languages by entity count:");
|
|
101
|
+
for (const l of signals.languages)
|
|
102
|
+
lines.push(` • ${l.name}: ${l.count}`);
|
|
103
|
+
lines.push("");
|
|
104
|
+
lines.push("Top modules:");
|
|
105
|
+
for (const m of signals.topModules.slice(0, 8))
|
|
106
|
+
lines.push(` • ${m.name} (${m.count} entities)`);
|
|
107
|
+
lines.push("");
|
|
108
|
+
if (signals.patternSuffixes.length > 0) {
|
|
109
|
+
lines.push("Common architectural suffixes (entity names ending with):");
|
|
110
|
+
for (const s of signals.patternSuffixes.slice(0, 6))
|
|
111
|
+
lines.push(` • ${s.suffix} (${s.count}×)`);
|
|
112
|
+
lines.push("");
|
|
113
|
+
}
|
|
114
|
+
lines.push("Recent commit subjects:");
|
|
115
|
+
for (const s of signals.recentSubjects.slice(0, 12))
|
|
116
|
+
lines.push(` • ${s}`);
|
|
117
|
+
lines.push("");
|
|
118
|
+
lines.push("Output format: JSON array, each element has fields:");
|
|
119
|
+
lines.push(" title (string), pitch (2-3 sentences), precedents (array of pattern names),");
|
|
120
|
+
lines.push(" effort ('small'|'medium'|'large'), risk ('low'|'medium'|'high').");
|
|
121
|
+
lines.push("Output JSON only, no markdown, no preamble.");
|
|
122
|
+
return lines.join("\n");
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Parse LLM JSON output into typed DreamIdea[] with permissive validation.
|
|
126
|
+
* Returns [] on parse failure rather than throwing — dream is best-effort.
|
|
127
|
+
*/
|
|
128
|
+
export function parseDreamIdeas(raw) {
|
|
129
|
+
// The LLM might wrap JSON in markdown fences or add prose before/after.
|
|
130
|
+
const jsonStart = raw.indexOf("[");
|
|
131
|
+
const jsonEnd = raw.lastIndexOf("]");
|
|
132
|
+
if (jsonStart < 0 || jsonEnd <= jsonStart)
|
|
133
|
+
return [];
|
|
134
|
+
const slice = raw.slice(jsonStart, jsonEnd + 1);
|
|
135
|
+
let parsed;
|
|
136
|
+
try {
|
|
137
|
+
parsed = JSON.parse(slice);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
if (!Array.isArray(parsed))
|
|
143
|
+
return [];
|
|
144
|
+
const out = [];
|
|
145
|
+
for (const item of parsed) {
|
|
146
|
+
if (!item || typeof item !== "object")
|
|
147
|
+
continue;
|
|
148
|
+
const o = item;
|
|
149
|
+
const title = typeof o.title === "string" ? o.title : "";
|
|
150
|
+
const pitch = typeof o.pitch === "string" ? o.pitch : "";
|
|
151
|
+
if (!title || !pitch)
|
|
152
|
+
continue;
|
|
153
|
+
const precedents = Array.isArray(o.precedents)
|
|
154
|
+
? o.precedents.filter((p) => typeof p === "string")
|
|
155
|
+
: [];
|
|
156
|
+
const effort = ["small", "medium", "large"].includes(o.effort)
|
|
157
|
+
? o.effort
|
|
158
|
+
: "medium";
|
|
159
|
+
const risk = ["low", "medium", "high"].includes(o.risk)
|
|
160
|
+
? o.risk
|
|
161
|
+
: "medium";
|
|
162
|
+
out.push({ title, pitch, precedents, effort, risk });
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* No-LLM fallback — generate ideas from heuristic patterns. Useful for
|
|
168
|
+
* deterministic mode and as a sanity-check baseline.
|
|
169
|
+
*/
|
|
170
|
+
export function heuristicDream(signals, n) {
|
|
171
|
+
const ideas = [];
|
|
172
|
+
// Idea 1 — incident-driven, if incidents exist.
|
|
173
|
+
if (signals.totalIncidents > 0) {
|
|
174
|
+
ideas.push({
|
|
175
|
+
title: "IncidentReplayHarness",
|
|
176
|
+
pitch: "You already have incident data indexed. A replay harness would let you re-run an incident's commit chain against the current code to see if the bug returned.",
|
|
177
|
+
precedents: ["correlate", "blast"],
|
|
178
|
+
effort: "medium",
|
|
179
|
+
risk: "low",
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// Idea 2 — pattern-suffix-driven.
|
|
183
|
+
const topSuffix = signals.patternSuffixes[0];
|
|
184
|
+
if (topSuffix) {
|
|
185
|
+
ideas.push({
|
|
186
|
+
title: `${topSuffix.suffix}Registry`,
|
|
187
|
+
pitch: `You have ${topSuffix.count} entities ending in "${topSuffix.suffix}". A central registry would make discovery and DI cleaner; the pattern is already pervasive.`,
|
|
188
|
+
precedents: [`${topSuffix.suffix} entities (${topSuffix.count}×)`],
|
|
189
|
+
effort: "small",
|
|
190
|
+
risk: "low",
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// Idea 3 — multi-language coverage.
|
|
194
|
+
if (signals.languages.length >= 2) {
|
|
195
|
+
const second = signals.languages[1];
|
|
196
|
+
ideas.push({
|
|
197
|
+
title: `${capitalize(second.name)}DeepDive`,
|
|
198
|
+
pitch: `Your repo has ${second.count} entities in ${second.name} but most tooling targets the dominant language. A focused parser/linter pass would surface tribal knowledge that's currently invisible.`,
|
|
199
|
+
precedents: [`${second.name} parser`],
|
|
200
|
+
effort: "medium",
|
|
201
|
+
risk: "medium",
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// Idea 4 — module-driven.
|
|
205
|
+
const topMod = signals.topModules[0];
|
|
206
|
+
if (topMod) {
|
|
207
|
+
ideas.push({
|
|
208
|
+
title: `${moduleToPascal(topMod.name)}HealthCheck`,
|
|
209
|
+
pitch: `Your largest module (${topMod.name}, ${topMod.count} entities) has no central health check. A small module-level diagnostic would catch silent regressions early.`,
|
|
210
|
+
precedents: [topMod.name],
|
|
211
|
+
effort: "small",
|
|
212
|
+
risk: "low",
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
// Idea 5 — bus-factor.
|
|
216
|
+
ideas.push({
|
|
217
|
+
title: "BusFactorReport",
|
|
218
|
+
pitch: "You already track per-author commit history. A weekly bus-factor report (which files only one person has ever touched) is a tiny extension that compounds.",
|
|
219
|
+
precedents: ["mirror", "who-knows"],
|
|
220
|
+
effort: "small",
|
|
221
|
+
risk: "low",
|
|
222
|
+
});
|
|
223
|
+
return ideas.slice(0, n);
|
|
224
|
+
}
|
|
225
|
+
function capitalize(s) {
|
|
226
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
227
|
+
}
|
|
228
|
+
function moduleToPascal(modulePath) {
|
|
229
|
+
return modulePath
|
|
230
|
+
.split(/[/_-]/)
|
|
231
|
+
.filter(Boolean)
|
|
232
|
+
.map((p) => capitalize(p))
|
|
233
|
+
.join("");
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=dream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dream.js","sourceRoot":"","sources":["../../src/insights/dream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dream.test.d.ts","sourceRoot":"","sources":["../../src/insights/dream.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { buildDreamPrompt, parseDreamIdeas, heuristicDream, } from "./dream.js";
|
|
3
|
+
const sampleSignals = {
|
|
4
|
+
totalCommits: 100,
|
|
5
|
+
totalEntities: 500,
|
|
6
|
+
totalIncidents: 5,
|
|
7
|
+
languages: [
|
|
8
|
+
{ name: "typescript", count: 400 },
|
|
9
|
+
{ name: "python", count: 80 },
|
|
10
|
+
{ name: "go", count: 20 },
|
|
11
|
+
],
|
|
12
|
+
recentSubjects: [
|
|
13
|
+
"fix: stripe webhook on bigint",
|
|
14
|
+
"feat: add jwt rotation",
|
|
15
|
+
"refactor: extract OrderService",
|
|
16
|
+
],
|
|
17
|
+
topModules: [
|
|
18
|
+
{ name: "src/payment", count: 60 },
|
|
19
|
+
{ name: "src/auth", count: 40 },
|
|
20
|
+
{ name: "src/orders", count: 30 },
|
|
21
|
+
],
|
|
22
|
+
patternSuffixes: [
|
|
23
|
+
{ suffix: "Service", count: 12 },
|
|
24
|
+
{ suffix: "Adapter", count: 8 },
|
|
25
|
+
{ suffix: "Controller", count: 6 },
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
describe("buildDreamPrompt", () => {
|
|
29
|
+
it("includes total counts and language distribution", () => {
|
|
30
|
+
const p = buildDreamPrompt(sampleSignals, 5);
|
|
31
|
+
expect(p).toContain("Total commits indexed: 100");
|
|
32
|
+
expect(p).toContain("Total entities indexed: 500");
|
|
33
|
+
expect(p).toContain("typescript: 400");
|
|
34
|
+
expect(p).toContain("python: 80");
|
|
35
|
+
});
|
|
36
|
+
it("includes top modules and pattern suffixes", () => {
|
|
37
|
+
const p = buildDreamPrompt(sampleSignals, 5);
|
|
38
|
+
expect(p).toContain("src/payment");
|
|
39
|
+
expect(p).toContain("Service (12×)");
|
|
40
|
+
});
|
|
41
|
+
it("includes recent commit subjects (capped)", () => {
|
|
42
|
+
const p = buildDreamPrompt(sampleSignals, 5);
|
|
43
|
+
expect(p).toContain("stripe webhook on bigint");
|
|
44
|
+
});
|
|
45
|
+
it("requests JSON output", () => {
|
|
46
|
+
const p = buildDreamPrompt(sampleSignals, 3);
|
|
47
|
+
expect(p.toLowerCase()).toContain("json");
|
|
48
|
+
expect(p).toContain("3");
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("parseDreamIdeas", () => {
|
|
52
|
+
it("parses a clean JSON array", () => {
|
|
53
|
+
const raw = JSON.stringify([
|
|
54
|
+
{
|
|
55
|
+
title: "MultiCurrencyAdapter",
|
|
56
|
+
pitch: "You already abstract Stripe via PaymentAdapter. Extending to multi-currency is a small parallel.",
|
|
57
|
+
precedents: ["PaymentAdapter"],
|
|
58
|
+
effort: "small",
|
|
59
|
+
risk: "low",
|
|
60
|
+
},
|
|
61
|
+
]);
|
|
62
|
+
const ideas = parseDreamIdeas(raw);
|
|
63
|
+
expect(ideas).toHaveLength(1);
|
|
64
|
+
expect(ideas[0].title).toBe("MultiCurrencyAdapter");
|
|
65
|
+
expect(ideas[0].effort).toBe("small");
|
|
66
|
+
});
|
|
67
|
+
it("strips markdown fences and prose around the JSON", () => {
|
|
68
|
+
const raw = "Here are some ideas:\n```json\n" +
|
|
69
|
+
JSON.stringify([{ title: "X", pitch: "Y", precedents: [], effort: "medium", risk: "low" }]) +
|
|
70
|
+
"\n```\nLet me know if you want more.";
|
|
71
|
+
expect(parseDreamIdeas(raw)).toHaveLength(1);
|
|
72
|
+
});
|
|
73
|
+
it("returns [] on malformed JSON instead of throwing", () => {
|
|
74
|
+
expect(parseDreamIdeas("this is not json at all")).toEqual([]);
|
|
75
|
+
expect(parseDreamIdeas("[invalid, json,]")).toEqual([]);
|
|
76
|
+
});
|
|
77
|
+
it("filters out items without title or pitch", () => {
|
|
78
|
+
const raw = JSON.stringify([
|
|
79
|
+
{ title: "Good", pitch: "yes" },
|
|
80
|
+
{ title: "BadNoOitch" }, // missing pitch
|
|
81
|
+
{ pitch: "no title" }, // missing title
|
|
82
|
+
]);
|
|
83
|
+
const ideas = parseDreamIdeas(raw);
|
|
84
|
+
expect(ideas).toHaveLength(1);
|
|
85
|
+
expect(ideas[0].title).toBe("Good");
|
|
86
|
+
});
|
|
87
|
+
it("normalizes invalid effort/risk to defaults", () => {
|
|
88
|
+
const raw = JSON.stringify([
|
|
89
|
+
{ title: "X", pitch: "y", effort: "extreme", risk: "🚨" },
|
|
90
|
+
]);
|
|
91
|
+
const ideas = parseDreamIdeas(raw);
|
|
92
|
+
expect(ideas[0].effort).toBe("medium");
|
|
93
|
+
expect(ideas[0].risk).toBe("medium");
|
|
94
|
+
});
|
|
95
|
+
it("handles non-array input gracefully", () => {
|
|
96
|
+
expect(parseDreamIdeas('{"not": "array"}')).toEqual([]);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe("heuristicDream — deterministic no-LLM fallback", () => {
|
|
100
|
+
it("returns up to N ideas", () => {
|
|
101
|
+
expect(heuristicDream(sampleSignals, 3).length).toBeLessThanOrEqual(3);
|
|
102
|
+
expect(heuristicDream(sampleSignals, 5).length).toBeLessThanOrEqual(5);
|
|
103
|
+
});
|
|
104
|
+
it("includes IncidentReplayHarness when incidents > 0", () => {
|
|
105
|
+
const ideas = heuristicDream(sampleSignals, 5);
|
|
106
|
+
expect(ideas.find((i) => i.title === "IncidentReplayHarness")).toBeDefined();
|
|
107
|
+
});
|
|
108
|
+
it("omits IncidentReplayHarness when incidents = 0", () => {
|
|
109
|
+
const noIncidents = { ...sampleSignals, totalIncidents: 0 };
|
|
110
|
+
const ideas = heuristicDream(noIncidents, 5);
|
|
111
|
+
expect(ideas.find((i) => i.title === "IncidentReplayHarness")).toBeUndefined();
|
|
112
|
+
});
|
|
113
|
+
it("uses the top pattern suffix in idea naming", () => {
|
|
114
|
+
const ideas = heuristicDream(sampleSignals, 5);
|
|
115
|
+
expect(ideas.some((i) => i.title.includes("Service"))).toBe(true);
|
|
116
|
+
});
|
|
117
|
+
it("every idea has the required fields populated", () => {
|
|
118
|
+
const ideas = heuristicDream(sampleSignals, 5);
|
|
119
|
+
for (const idea of ideas) {
|
|
120
|
+
expect(idea.title.length).toBeGreaterThan(0);
|
|
121
|
+
expect(idea.pitch.length).toBeGreaterThan(20);
|
|
122
|
+
expect(["small", "medium", "large"]).toContain(idea.effort);
|
|
123
|
+
expect(["low", "medium", "high"]).toContain(idea.risk);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=dream.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dream.test.js","sourceRoot":"","sources":["../../src/insights/dream.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Insights — high-level analyses on top of the indexed memory.
|
|
3
|
+
*
|
|
4
|
+
* who-knows — surface human experts on a topic
|
|
5
|
+
* decisions — auto-extract architectural decisions from commit text
|
|
6
|
+
* stack-trace — parse an error and find historical context for each frame
|
|
7
|
+
* story — narrate the evolution of a topic across acts
|
|
8
|
+
*/
|
|
9
|
+
export * from "./who-knows.js";
|
|
10
|
+
export * from "./decisions.js";
|
|
11
|
+
export * from "./stack-trace.js";
|
|
12
|
+
export * from "./story.js";
|
|
13
|
+
export * from "./dream.js";
|
|
14
|
+
export * from "./suggest.js";
|
|
15
|
+
export * from "./obsidian.js";
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/insights/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Insights — high-level analyses on top of the indexed memory.
|
|
3
|
+
*
|
|
4
|
+
* who-knows — surface human experts on a topic
|
|
5
|
+
* decisions — auto-extract architectural decisions from commit text
|
|
6
|
+
* stack-trace — parse an error and find historical context for each frame
|
|
7
|
+
* story — narrate the evolution of a topic across acts
|
|
8
|
+
*/
|
|
9
|
+
export * from "./who-knows.js";
|
|
10
|
+
export * from "./decisions.js";
|
|
11
|
+
export * from "./stack-trace.js";
|
|
12
|
+
export * from "./story.js";
|
|
13
|
+
export * from "./dream.js";
|
|
14
|
+
export * from "./suggest.js";
|
|
15
|
+
export * from "./obsidian.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/insights/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Obsidian export — turn Mneme insights into a wiki-linked Markdown vault
|
|
3
|
+
* compatible with Obsidian's [[wiki-links]] + YAML frontmatter conventions.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: the "LLM Wiki" / "second brain" approach (Karpathy, et al.)
|
|
6
|
+
* pairs personal notes with linked knowledge. Mneme already extracts decisions,
|
|
7
|
+
* stories, and expert maps from git history — exporting them as an Obsidian
|
|
8
|
+
* vault lets users keep their code memory next to their personal notes.
|
|
9
|
+
*
|
|
10
|
+
* Pure functions only. No I/O. The CLI does the file writes.
|
|
11
|
+
*
|
|
12
|
+
* Output shape:
|
|
13
|
+
* vault/
|
|
14
|
+
* index.md ← top-level table
|
|
15
|
+
* decisions/<filename>.md ← one note per decision
|
|
16
|
+
* authors/<name>.md ← per-author backlink hub
|
|
17
|
+
* story/<topic>.md ← per-topic story timeline
|
|
18
|
+
*/
|
|
19
|
+
import type { ExtractedDecision } from "./decisions.js";
|
|
20
|
+
import type { Story } from "./story.js";
|
|
21
|
+
import type { ExpertCandidate } from "./who-knows.js";
|
|
22
|
+
/** A logical "note" — caller writes filename → content to disk. */
|
|
23
|
+
export interface VaultFile {
|
|
24
|
+
/** Relative path inside the vault, e.g. "decisions/2024-08-12-switched.md". */
|
|
25
|
+
path: string;
|
|
26
|
+
/** Full Markdown content including frontmatter. */
|
|
27
|
+
content: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function decisionsToVault(decisions: ExtractedDecision[]): VaultFile[];
|
|
30
|
+
export declare function storyToVault(story: Story, llmActSummaries?: Map<number, string>): VaultFile[];
|
|
31
|
+
export declare function expertsToVault(topic: string, experts: ExpertCandidate[]): VaultFile[];
|
|
32
|
+
/**
|
|
33
|
+
* Filesystem- and Obsidian-friendly slug. Lowercases, removes non-alnum
|
|
34
|
+
* except `-`, collapses whitespace and dashes.
|
|
35
|
+
*/
|
|
36
|
+
export declare function slug(s: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Minimal Markdown-escape — only escapes pipe (table separator) and the
|
|
39
|
+
* Obsidian wiki-link delimiters that would corrupt rendering.
|
|
40
|
+
*/
|
|
41
|
+
export declare function escapeMd(s: string): string;
|
|
42
|
+
//# sourceMappingURL=obsidian.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"obsidian.d.ts","sourceRoot":"","sources":["../../src/insights/obsidian.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAY,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,mEAAmE;AACnE,MAAM,WAAW,SAAS;IACxB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,iBAAiB,EAAE,GAAG,SAAS,EAAE,CAwC5E;AA+GD,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAAE,CAmD7F;AAID,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,CA8BrF;AAID;;;GAGG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAQtC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1C"}
|