@mneme-ai/core 0.8.4 → 0.10.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 (272) 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 +3 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -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/bus-factor.d.ts +58 -0
  22. package/dist/insights/bus-factor.d.ts.map +1 -0
  23. package/dist/insights/bus-factor.js +117 -0
  24. package/dist/insights/bus-factor.js.map +1 -0
  25. package/dist/insights/bus-factor.test.d.ts +2 -0
  26. package/dist/insights/bus-factor.test.d.ts.map +1 -0
  27. package/dist/insights/bus-factor.test.js +149 -0
  28. package/dist/insights/bus-factor.test.js.map +1 -0
  29. package/dist/insights/commit-coach.d.ts +80 -0
  30. package/dist/insights/commit-coach.d.ts.map +1 -0
  31. package/dist/insights/commit-coach.js +230 -0
  32. package/dist/insights/commit-coach.js.map +1 -0
  33. package/dist/insights/commit-coach.test.d.ts +2 -0
  34. package/dist/insights/commit-coach.test.d.ts.map +1 -0
  35. package/dist/insights/commit-coach.test.js +163 -0
  36. package/dist/insights/commit-coach.test.js.map +1 -0
  37. package/dist/insights/crystal-ball.d.ts +76 -0
  38. package/dist/insights/crystal-ball.d.ts.map +1 -0
  39. package/dist/insights/crystal-ball.js +219 -0
  40. package/dist/insights/crystal-ball.js.map +1 -0
  41. package/dist/insights/crystal-ball.test.d.ts +2 -0
  42. package/dist/insights/crystal-ball.test.d.ts.map +1 -0
  43. package/dist/insights/crystal-ball.test.js +157 -0
  44. package/dist/insights/crystal-ball.test.js.map +1 -0
  45. package/dist/insights/decisions.d.ts +38 -0
  46. package/dist/insights/decisions.d.ts.map +1 -0
  47. package/dist/insights/decisions.js +125 -0
  48. package/dist/insights/decisions.js.map +1 -0
  49. package/dist/insights/decisions.test.d.ts +2 -0
  50. package/dist/insights/decisions.test.d.ts.map +1 -0
  51. package/dist/insights/decisions.test.js +141 -0
  52. package/dist/insights/decisions.test.js.map +1 -0
  53. package/dist/insights/dream.d.ts +71 -0
  54. package/dist/insights/dream.d.ts.map +1 -0
  55. package/dist/insights/dream.js +235 -0
  56. package/dist/insights/dream.js.map +1 -0
  57. package/dist/insights/dream.test.d.ts +2 -0
  58. package/dist/insights/dream.test.d.ts.map +1 -0
  59. package/dist/insights/dream.test.js +127 -0
  60. package/dist/insights/dream.test.js.map +1 -0
  61. package/dist/insights/index.d.ts +21 -0
  62. package/dist/insights/index.d.ts.map +1 -0
  63. package/dist/insights/index.js +21 -0
  64. package/dist/insights/index.js.map +1 -0
  65. package/dist/insights/obsidian.d.ts +42 -0
  66. package/dist/insights/obsidian.d.ts.map +1 -0
  67. package/dist/insights/obsidian.js +263 -0
  68. package/dist/insights/obsidian.js.map +1 -0
  69. package/dist/insights/obsidian.test.d.ts +2 -0
  70. package/dist/insights/obsidian.test.d.ts.map +1 -0
  71. package/dist/insights/obsidian.test.js +241 -0
  72. package/dist/insights/obsidian.test.js.map +1 -0
  73. package/dist/insights/paradox.d.ts +36 -0
  74. package/dist/insights/paradox.d.ts.map +1 -0
  75. package/dist/insights/paradox.js +201 -0
  76. package/dist/insights/paradox.js.map +1 -0
  77. package/dist/insights/paradox.test.d.ts +2 -0
  78. package/dist/insights/paradox.test.d.ts.map +1 -0
  79. package/dist/insights/paradox.test.js +88 -0
  80. package/dist/insights/paradox.test.js.map +1 -0
  81. package/dist/insights/regret.d.ts +57 -0
  82. package/dist/insights/regret.d.ts.map +1 -0
  83. package/dist/insights/regret.js +137 -0
  84. package/dist/insights/regret.js.map +1 -0
  85. package/dist/insights/regret.test.d.ts +2 -0
  86. package/dist/insights/regret.test.d.ts.map +1 -0
  87. package/dist/insights/regret.test.js +153 -0
  88. package/dist/insights/regret.test.js.map +1 -0
  89. package/dist/insights/stack-trace.d.ts +40 -0
  90. package/dist/insights/stack-trace.d.ts.map +1 -0
  91. package/dist/insights/stack-trace.js +127 -0
  92. package/dist/insights/stack-trace.js.map +1 -0
  93. package/dist/insights/stack-trace.test.d.ts +2 -0
  94. package/dist/insights/stack-trace.test.d.ts.map +1 -0
  95. package/dist/insights/stack-trace.test.js +103 -0
  96. package/dist/insights/stack-trace.test.js.map +1 -0
  97. package/dist/insights/story.d.ts +34 -0
  98. package/dist/insights/story.d.ts.map +1 -0
  99. package/dist/insights/story.js +100 -0
  100. package/dist/insights/story.js.map +1 -0
  101. package/dist/insights/story.test.d.ts +2 -0
  102. package/dist/insights/story.test.d.ts.map +1 -0
  103. package/dist/insights/story.test.js +99 -0
  104. package/dist/insights/story.test.js.map +1 -0
  105. package/dist/insights/suggest.d.ts +29 -0
  106. package/dist/insights/suggest.d.ts.map +1 -0
  107. package/dist/insights/suggest.js +93 -0
  108. package/dist/insights/suggest.js.map +1 -0
  109. package/dist/insights/suggest.test.d.ts +2 -0
  110. package/dist/insights/suggest.test.d.ts.map +1 -0
  111. package/dist/insights/suggest.test.js +71 -0
  112. package/dist/insights/suggest.test.js.map +1 -0
  113. package/dist/insights/who-knows.d.ts +66 -0
  114. package/dist/insights/who-knows.d.ts.map +1 -0
  115. package/dist/insights/who-knows.js +125 -0
  116. package/dist/insights/who-knows.js.map +1 -0
  117. package/dist/insights/who-knows.test.d.ts +2 -0
  118. package/dist/insights/who-knows.test.d.ts.map +1 -0
  119. package/dist/insights/who-knows.test.js +109 -0
  120. package/dist/insights/who-knows.test.js.map +1 -0
  121. package/dist/quant/alpha.d.ts +87 -0
  122. package/dist/quant/alpha.d.ts.map +1 -0
  123. package/dist/quant/alpha.js +103 -0
  124. package/dist/quant/alpha.js.map +1 -0
  125. package/dist/quant/alpha.test.d.ts +2 -0
  126. package/dist/quant/alpha.test.d.ts.map +1 -0
  127. package/dist/quant/alpha.test.js +147 -0
  128. package/dist/quant/alpha.test.js.map +1 -0
  129. package/dist/quant/backtest.d.ts +57 -0
  130. package/dist/quant/backtest.d.ts.map +1 -0
  131. package/dist/quant/backtest.js +90 -0
  132. package/dist/quant/backtest.js.map +1 -0
  133. package/dist/quant/backtest.test.d.ts +2 -0
  134. package/dist/quant/backtest.test.d.ts.map +1 -0
  135. package/dist/quant/backtest.test.js +133 -0
  136. package/dist/quant/backtest.test.js.map +1 -0
  137. package/dist/quant/black-swan.d.ts +45 -0
  138. package/dist/quant/black-swan.d.ts.map +1 -0
  139. package/dist/quant/black-swan.js +112 -0
  140. package/dist/quant/black-swan.js.map +1 -0
  141. package/dist/quant/black-swan.test.d.ts +2 -0
  142. package/dist/quant/black-swan.test.d.ts.map +1 -0
  143. package/dist/quant/black-swan.test.js +131 -0
  144. package/dist/quant/black-swan.test.js.map +1 -0
  145. package/dist/quant/correlation-matrix.d.ts +54 -0
  146. package/dist/quant/correlation-matrix.d.ts.map +1 -0
  147. package/dist/quant/correlation-matrix.js +103 -0
  148. package/dist/quant/correlation-matrix.js.map +1 -0
  149. package/dist/quant/correlation-matrix.test.d.ts +2 -0
  150. package/dist/quant/correlation-matrix.test.d.ts.map +1 -0
  151. package/dist/quant/correlation-matrix.test.js +118 -0
  152. package/dist/quant/correlation-matrix.test.js.map +1 -0
  153. package/dist/quant/drawdown.d.ts +51 -0
  154. package/dist/quant/drawdown.d.ts.map +1 -0
  155. package/dist/quant/drawdown.js +96 -0
  156. package/dist/quant/drawdown.js.map +1 -0
  157. package/dist/quant/drawdown.test.d.ts +2 -0
  158. package/dist/quant/drawdown.test.d.ts.map +1 -0
  159. package/dist/quant/drawdown.test.js +166 -0
  160. package/dist/quant/drawdown.test.js.map +1 -0
  161. package/dist/quant/greek.d.ts +55 -0
  162. package/dist/quant/greek.d.ts.map +1 -0
  163. package/dist/quant/greek.js +157 -0
  164. package/dist/quant/greek.js.map +1 -0
  165. package/dist/quant/greek.test.d.ts +2 -0
  166. package/dist/quant/greek.test.d.ts.map +1 -0
  167. package/dist/quant/greek.test.js +138 -0
  168. package/dist/quant/greek.test.js.map +1 -0
  169. package/dist/quant/implied-volatility.d.ts +65 -0
  170. package/dist/quant/implied-volatility.d.ts.map +1 -0
  171. package/dist/quant/implied-volatility.js +149 -0
  172. package/dist/quant/implied-volatility.js.map +1 -0
  173. package/dist/quant/implied-volatility.test.d.ts +2 -0
  174. package/dist/quant/implied-volatility.test.d.ts.map +1 -0
  175. package/dist/quant/implied-volatility.test.js +127 -0
  176. package/dist/quant/implied-volatility.test.js.map +1 -0
  177. package/dist/quant/index.d.ts +28 -0
  178. package/dist/quant/index.d.ts.map +1 -0
  179. package/dist/quant/index.js +28 -0
  180. package/dist/quant/index.js.map +1 -0
  181. package/dist/quant/insider-trading.d.ts +56 -0
  182. package/dist/quant/insider-trading.d.ts.map +1 -0
  183. package/dist/quant/insider-trading.js +129 -0
  184. package/dist/quant/insider-trading.js.map +1 -0
  185. package/dist/quant/insider-trading.test.d.ts +2 -0
  186. package/dist/quant/insider-trading.test.d.ts.map +1 -0
  187. package/dist/quant/insider-trading.test.js +130 -0
  188. package/dist/quant/insider-trading.test.js.map +1 -0
  189. package/dist/quant/moneyball.d.ts +48 -0
  190. package/dist/quant/moneyball.d.ts.map +1 -0
  191. package/dist/quant/moneyball.js +110 -0
  192. package/dist/quant/moneyball.js.map +1 -0
  193. package/dist/quant/moneyball.test.d.ts +2 -0
  194. package/dist/quant/moneyball.test.d.ts.map +1 -0
  195. package/dist/quant/moneyball.test.js +137 -0
  196. package/dist/quant/moneyball.test.js.map +1 -0
  197. package/dist/quant/tax-loss-harvest.d.ts +59 -0
  198. package/dist/quant/tax-loss-harvest.d.ts.map +1 -0
  199. package/dist/quant/tax-loss-harvest.js +126 -0
  200. package/dist/quant/tax-loss-harvest.js.map +1 -0
  201. package/dist/quant/tax-loss-harvest.test.d.ts +2 -0
  202. package/dist/quant/tax-loss-harvest.test.d.ts.map +1 -0
  203. package/dist/quant/tax-loss-harvest.test.js +126 -0
  204. package/dist/quant/tax-loss-harvest.test.js.map +1 -0
  205. package/dist/retrieve/index.d.ts +2 -0
  206. package/dist/retrieve/index.d.ts.map +1 -1
  207. package/dist/retrieve/index.js +2 -0
  208. package/dist/retrieve/index.js.map +1 -1
  209. package/dist/retrieve/intent.d.ts +32 -0
  210. package/dist/retrieve/intent.d.ts.map +1 -0
  211. package/dist/retrieve/intent.js +104 -0
  212. package/dist/retrieve/intent.js.map +1 -0
  213. package/dist/retrieve/intent.test.d.ts +2 -0
  214. package/dist/retrieve/intent.test.d.ts.map +1 -0
  215. package/dist/retrieve/intent.test.js +106 -0
  216. package/dist/retrieve/intent.test.js.map +1 -0
  217. package/dist/retrieve/search.d.ts +30 -0
  218. package/dist/retrieve/search.d.ts.map +1 -1
  219. package/dist/retrieve/search.js +48 -0
  220. package/dist/retrieve/search.js.map +1 -1
  221. package/dist/retrieve/search.test.js +84 -1
  222. package/dist/retrieve/search.test.js.map +1 -1
  223. package/dist/retrieve/synthesize.d.ts +57 -0
  224. package/dist/retrieve/synthesize.d.ts.map +1 -0
  225. package/dist/retrieve/synthesize.js +191 -0
  226. package/dist/retrieve/synthesize.js.map +1 -0
  227. package/dist/retrieve/synthesize.test.d.ts +2 -0
  228. package/dist/retrieve/synthesize.test.d.ts.map +1 -0
  229. package/dist/retrieve/synthesize.test.js +127 -0
  230. package/dist/retrieve/synthesize.test.js.map +1 -0
  231. package/dist/store/schema.d.ts +2 -2
  232. package/dist/store/schema.d.ts.map +1 -1
  233. package/dist/store/schema.js +60 -2
  234. package/dist/store/schema.js.map +1 -1
  235. package/dist/store/sqlite.d.ts +2 -0
  236. package/dist/store/sqlite.d.ts.map +1 -1
  237. package/dist/store/sqlite.js +24 -0
  238. package/dist/store/sqlite.js.map +1 -1
  239. package/dist/store/sqlite.test.js +1 -1
  240. package/dist/util/index.d.ts +2 -0
  241. package/dist/util/index.d.ts.map +1 -1
  242. package/dist/util/index.js +2 -1
  243. package/dist/util/index.js.map +1 -1
  244. package/dist/util/redact.d.ts +58 -0
  245. package/dist/util/redact.d.ts.map +1 -0
  246. package/dist/util/redact.js +129 -0
  247. package/dist/util/redact.js.map +1 -0
  248. package/dist/util/redact.test.d.ts +2 -0
  249. package/dist/util/redact.test.d.ts.map +1 -0
  250. package/dist/util/redact.test.js +148 -0
  251. package/dist/util/redact.test.js.map +1 -0
  252. package/dist/wisdom/calibrator.d.ts +43 -0
  253. package/dist/wisdom/calibrator.d.ts.map +1 -0
  254. package/dist/wisdom/calibrator.js +120 -0
  255. package/dist/wisdom/calibrator.js.map +1 -0
  256. package/dist/wisdom/feedback.d.ts +45 -0
  257. package/dist/wisdom/feedback.d.ts.map +1 -0
  258. package/dist/wisdom/feedback.js +116 -0
  259. package/dist/wisdom/feedback.js.map +1 -0
  260. package/dist/wisdom/index.d.ts +15 -0
  261. package/dist/wisdom/index.d.ts.map +1 -0
  262. package/dist/wisdom/index.js +15 -0
  263. package/dist/wisdom/index.js.map +1 -0
  264. package/dist/wisdom/types.d.ts +67 -0
  265. package/dist/wisdom/types.d.ts.map +1 -0
  266. package/dist/wisdom/types.js +20 -0
  267. package/dist/wisdom/types.js.map +1 -0
  268. package/dist/wisdom/wisdom.test.d.ts +2 -0
  269. package/dist/wisdom/wisdom.test.d.ts.map +1 -0
  270. package/dist/wisdom/wisdom.test.js +144 -0
  271. package/dist/wisdom/wisdom.test.js.map +1 -0
  272. package/package.json +1 -1
@@ -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;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,21 @@
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
+ export * from "./regret.js";
17
+ export * from "./bus-factor.js";
18
+ export * from "./paradox.js";
19
+ export * from "./commit-coach.js";
20
+ export * from "./crystal-ball.js";
21
+ //# 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;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,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"}
@@ -0,0 +1,263 @@
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
+ // ─── Decisions → Obsidian ───────────────────────────────────────────────
20
+ export function decisionsToVault(decisions) {
21
+ if (decisions.length === 0) {
22
+ return [
23
+ {
24
+ path: "index.md",
25
+ content: indexHeader() + "\n_No decisions extracted yet._\n",
26
+ },
27
+ ];
28
+ }
29
+ const files = [];
30
+ // 1. One note per decision.
31
+ for (const d of decisions) {
32
+ files.push({
33
+ path: `decisions/${decisionFilename(d)}.md`,
34
+ content: decisionNoteContent(d),
35
+ });
36
+ }
37
+ // 2. Author hub notes — one per distinct author, with backlinks.
38
+ const byAuthor = new Map();
39
+ for (const d of decisions) {
40
+ if (!byAuthor.has(d.author))
41
+ byAuthor.set(d.author, []);
42
+ byAuthor.get(d.author).push(d);
43
+ }
44
+ for (const [author, list] of byAuthor) {
45
+ files.push({
46
+ path: `authors/${slug(author)}.md`,
47
+ content: authorHubContent(author, list),
48
+ });
49
+ }
50
+ // 3. Top-level index.
51
+ files.push({
52
+ path: "index.md",
53
+ content: decisionsIndexContent(decisions),
54
+ });
55
+ return files;
56
+ }
57
+ function indexHeader() {
58
+ return [
59
+ "---",
60
+ "type: mneme-vault",
61
+ `generated: ${new Date().toISOString()}`,
62
+ "---",
63
+ "",
64
+ "# Mneme Vault — Architecture Decisions",
65
+ "",
66
+ ].join("\n");
67
+ }
68
+ function decisionsIndexContent(decisions) {
69
+ const lines = [indexHeader()];
70
+ lines.push("This vault was auto-extracted from git history by [Mneme](https://github.com/patsa2561-art/mneme-ai).");
71
+ lines.push("");
72
+ lines.push(`**${decisions.length} decisions** across **${new Set(decisions.map((d) => d.author)).size} authors**.`);
73
+ lines.push("");
74
+ lines.push("## Recent decisions");
75
+ lines.push("");
76
+ lines.push("| Date | Decision | Source |");
77
+ lines.push("|---|---|---|");
78
+ for (const d of decisions.slice(0, 50)) {
79
+ const link = `[[decisions/${decisionFilename(d)}|${escapeMd(d.summary)}]]`;
80
+ const author = `[[authors/${slug(d.author)}|${escapeMd(d.author)}]]`;
81
+ lines.push(`| ${d.date} | ${link} | ${author} \\| \`${d.shortHash}\` |`);
82
+ }
83
+ lines.push("");
84
+ lines.push("## By author");
85
+ lines.push("");
86
+ const authors = new Map();
87
+ for (const d of decisions)
88
+ authors.set(d.author, (authors.get(d.author) ?? 0) + 1);
89
+ for (const [a, n] of [...authors.entries()].sort((x, y) => y[1] - x[1])) {
90
+ lines.push(`- [[authors/${slug(a)}|${escapeMd(a)}]] — ${n} decision${n === 1 ? "" : "s"}`);
91
+ }
92
+ lines.push("");
93
+ return lines.join("\n");
94
+ }
95
+ function decisionNoteContent(d) {
96
+ const tags = [`decisions/${d.kind}`, `author/${slug(d.author)}`].map((t) => ` - ${t}`).join("\n");
97
+ const lines = [
98
+ "---",
99
+ `date: ${d.date}`,
100
+ `author: ${escapeMd(d.author)}`,
101
+ `kind: ${d.kind}`,
102
+ `confidence: ${d.confidence}`,
103
+ `commit: ${d.shortHash}`,
104
+ "tags:",
105
+ tags,
106
+ "---",
107
+ "",
108
+ `# ${escapeMd(d.summary)}`,
109
+ "",
110
+ ];
111
+ if (d.rationale) {
112
+ lines.push(`> **Rationale:** ${escapeMd(d.rationale)}`);
113
+ lines.push("");
114
+ }
115
+ lines.push("## Source");
116
+ lines.push("");
117
+ lines.push(`- **Author:** [[authors/${slug(d.author)}|${escapeMd(d.author)}]]`);
118
+ lines.push(`- **Date:** ${d.date}`);
119
+ lines.push(`- **Commit:** \`${d.shortHash}\``);
120
+ lines.push(`- **Pattern:** \`${d.kind}\` (confidence ${d.confidence.toFixed(2)})`);
121
+ lines.push("");
122
+ lines.push("---");
123
+ lines.push("");
124
+ lines.push("← [[index|Back to index]]");
125
+ lines.push("");
126
+ return lines.join("\n");
127
+ }
128
+ function authorHubContent(author, decisions) {
129
+ const lines = [
130
+ "---",
131
+ `type: author`,
132
+ `name: ${escapeMd(author)}`,
133
+ `decisionCount: ${decisions.length}`,
134
+ "---",
135
+ "",
136
+ `# ${escapeMd(author)}`,
137
+ "",
138
+ `${decisions.length} architectural decision${decisions.length === 1 ? "" : "s"} attributed to ${escapeMd(author)} via git history.`,
139
+ "",
140
+ "## Decisions",
141
+ "",
142
+ ];
143
+ for (const d of decisions) {
144
+ lines.push(`- ${d.date} — [[decisions/${decisionFilename(d)}|${escapeMd(d.summary)}]] \`${d.shortHash}\``);
145
+ }
146
+ lines.push("");
147
+ lines.push("---");
148
+ lines.push("");
149
+ lines.push("← [[index|Back to index]]");
150
+ lines.push("");
151
+ return lines.join("\n");
152
+ }
153
+ function decisionFilename(d) {
154
+ // Obsidian-friendly: date-prefix + kind + slug of summary, kept short.
155
+ const summarySlug = slug(d.summary).slice(0, 60);
156
+ return `${d.date}-${d.kind}-${summarySlug}`;
157
+ }
158
+ // ─── Story → Obsidian ───────────────────────────────────────────────────
159
+ export function storyToVault(story, llmActSummaries) {
160
+ if (story.acts.length === 0) {
161
+ return [
162
+ {
163
+ path: `story-${slug(story.topic)}.md`,
164
+ content: `---\ntype: mneme-story\ntopic: ${escapeMd(story.topic)}\n---\n\n# The ${escapeMd(story.topic)} Story\n\n_No commits matched this topic._\n`,
165
+ },
166
+ ];
167
+ }
168
+ const lines = [
169
+ "---",
170
+ "type: mneme-story",
171
+ `topic: ${escapeMd(story.topic)}`,
172
+ `acts: ${story.acts.length}`,
173
+ `commits: ${story.totalCommits}`,
174
+ `spanDays: ${story.spanDays}`,
175
+ `generated: ${new Date().toISOString()}`,
176
+ "tags:",
177
+ " - mneme/story",
178
+ ` - topic/${slug(story.topic)}`,
179
+ "---",
180
+ "",
181
+ `# The ${escapeMd(story.topic)} Story`,
182
+ "",
183
+ `**${story.acts.length} acts · ${story.totalCommits} commits · ${story.spanDays} days**`,
184
+ "",
185
+ ];
186
+ story.acts.forEach((act, i) => {
187
+ lines.push(`## ${escapeMd(act.title)}`);
188
+ lines.push("");
189
+ lines.push(`_${act.fromDate} → ${act.toDate}_`);
190
+ lines.push("");
191
+ const summary = llmActSummaries?.get(i);
192
+ if (summary) {
193
+ lines.push(`> ${summary.replace(/\n/g, " ")}`);
194
+ lines.push("");
195
+ }
196
+ for (const c of act.commits) {
197
+ lines.push(`- ${c.authorDate.slice(0, 10)} — \`${c.shortHash || c.hash.slice(0, 7)}\` ${escapeMd(c.subject)} _(${escapeMd(c.authorName)})_`);
198
+ }
199
+ lines.push("");
200
+ });
201
+ lines.push("---");
202
+ lines.push("");
203
+ lines.push("_Generated by [Mneme](https://github.com/patsa2561-art/mneme-ai) — `mneme story " + story.topic + " --format obsidian`_");
204
+ lines.push("");
205
+ return [{ path: `story-${slug(story.topic)}.md`, content: lines.join("\n") }];
206
+ }
207
+ // ─── Experts (who-knows) → Obsidian ─────────────────────────────────────
208
+ export function expertsToVault(topic, experts) {
209
+ if (experts.length === 0) {
210
+ return [
211
+ {
212
+ path: `experts-${slug(topic)}.md`,
213
+ content: `---\ntype: mneme-experts\ntopic: ${escapeMd(topic)}\n---\n\n# Experts on ${escapeMd(topic)}\n\n_No experts found._\n`,
214
+ },
215
+ ];
216
+ }
217
+ const lines = [
218
+ "---",
219
+ "type: mneme-experts",
220
+ `topic: ${escapeMd(topic)}`,
221
+ `count: ${experts.length}`,
222
+ `generated: ${new Date().toISOString()}`,
223
+ "tags:",
224
+ ` - mneme/experts`,
225
+ ` - topic/${slug(topic)}`,
226
+ "---",
227
+ "",
228
+ `# Top experts on ${escapeMd(topic)}`,
229
+ "",
230
+ "| Tier | Name | Commits | Files | Last touch |",
231
+ "|---|---|---|---|---|",
232
+ ];
233
+ for (const e of experts) {
234
+ lines.push(`| ${e.tier} | [[authors/${slug(e.name)}|${escapeMd(e.name)}]] | ${e.commitCount} | ${e.filesTouched} | ${e.lastTouch.slice(0, 10)} |`);
235
+ }
236
+ lines.push("");
237
+ return [{ path: `experts-${slug(topic)}.md`, content: lines.join("\n") }];
238
+ }
239
+ // ─── helpers ────────────────────────────────────────────────────────────
240
+ /**
241
+ * Filesystem- and Obsidian-friendly slug. Lowercases, removes non-alnum
242
+ * except `-`, collapses whitespace and dashes.
243
+ */
244
+ export function slug(s) {
245
+ return s
246
+ .toLowerCase()
247
+ .replace(/[^\w\s-]/g, "")
248
+ .replace(/\s+/g, "-")
249
+ .replace(/-+/g, "-")
250
+ .replace(/^-|-$/g, "")
251
+ .slice(0, 80);
252
+ }
253
+ /**
254
+ * Minimal Markdown-escape — only escapes pipe (table separator) and the
255
+ * Obsidian wiki-link delimiters that would corrupt rendering.
256
+ */
257
+ export function escapeMd(s) {
258
+ return s
259
+ .replace(/\|/g, "\\|")
260
+ .replace(/\[\[/g, "[ [")
261
+ .replace(/\]\]/g, "] ]");
262
+ }
263
+ //# sourceMappingURL=obsidian.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obsidian.js","sourceRoot":"","sources":["../../src/insights/obsidian.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=obsidian.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obsidian.test.d.ts","sourceRoot":"","sources":["../../src/insights/obsidian.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,241 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { decisionsToVault, storyToVault, expertsToVault, slug, escapeMd, } from "./obsidian.js";
3
+ const decision = (overrides = {}) => ({
4
+ commitHash: "abcdef1234567890abcdef1234567890abcdef12",
5
+ shortHash: "abcdef1",
6
+ date: "2024-08-12",
7
+ author: "Alice",
8
+ summary: "switched from passport to JWT",
9
+ rationale: "compliance flagged session storage",
10
+ kind: "switched",
11
+ confidence: 0.9,
12
+ ...overrides,
13
+ });
14
+ describe("slug", () => {
15
+ it("lowercases and collapses whitespace", () => {
16
+ expect(slug("Hello World")).toBe("hello-world");
17
+ });
18
+ it("strips non-word characters", () => {
19
+ expect(slug("decided to use Map!")).toBe("decided-to-use-map");
20
+ });
21
+ it("collapses multiple dashes", () => {
22
+ expect(slug("foo - - bar")).toBe("foo-bar");
23
+ });
24
+ it("trims leading/trailing dashes", () => {
25
+ expect(slug("--hello--")).toBe("hello");
26
+ });
27
+ it("caps at 80 chars", () => {
28
+ expect(slug("a".repeat(200)).length).toBeLessThanOrEqual(80);
29
+ });
30
+ });
31
+ describe("escapeMd", () => {
32
+ it("escapes pipe characters (table separator)", () => {
33
+ expect(escapeMd("foo|bar")).toBe("foo\\|bar");
34
+ });
35
+ it("breaks wiki-link delimiters that would corrupt rendering", () => {
36
+ expect(escapeMd("see [[other]]")).not.toContain("[[");
37
+ expect(escapeMd("see [[other]]")).not.toContain("]]");
38
+ });
39
+ it("preserves normal text", () => {
40
+ expect(escapeMd("ordinary commit subject")).toBe("ordinary commit subject");
41
+ });
42
+ });
43
+ describe("decisionsToVault — empty case", () => {
44
+ it("returns a single index file when no decisions", () => {
45
+ const files = decisionsToVault([]);
46
+ expect(files).toHaveLength(1);
47
+ expect(files[0].path).toBe("index.md");
48
+ expect(files[0].content).toContain("No decisions extracted");
49
+ });
50
+ });
51
+ describe("decisionsToVault — full case", () => {
52
+ it("emits one note per decision plus authors plus index", () => {
53
+ const decisions = [
54
+ decision({ author: "Alice", summary: "A" }),
55
+ decision({ author: "Alice", summary: "B" }),
56
+ decision({ author: "Bob", summary: "C" }),
57
+ ];
58
+ const files = decisionsToVault(decisions);
59
+ const decisionFiles = files.filter((f) => f.path.startsWith("decisions/"));
60
+ const authorFiles = files.filter((f) => f.path.startsWith("authors/"));
61
+ const indexFiles = files.filter((f) => f.path === "index.md");
62
+ expect(decisionFiles).toHaveLength(3); // one per decision
63
+ expect(authorFiles).toHaveLength(2); // 2 distinct authors
64
+ expect(indexFiles).toHaveLength(1);
65
+ });
66
+ it("each decision note has YAML frontmatter with date, author, kind, confidence", () => {
67
+ const files = decisionsToVault([decision()]);
68
+ const note = files.find((f) => f.path.startsWith("decisions/"));
69
+ expect(note.content).toMatch(/^---\n/);
70
+ expect(note.content).toContain("date: 2024-08-12");
71
+ expect(note.content).toContain("author: Alice");
72
+ expect(note.content).toContain("kind: switched");
73
+ expect(note.content).toContain("confidence: 0.9");
74
+ expect(note.content).toContain("commit: abcdef1");
75
+ });
76
+ it("decision note links back to the author hub", () => {
77
+ const files = decisionsToVault([decision({ author: "Alice" })]);
78
+ const note = files.find((f) => f.path.startsWith("decisions/"));
79
+ expect(note.content).toContain("[[authors/alice|Alice]]");
80
+ });
81
+ it("decision note shows rationale when present", () => {
82
+ const files = decisionsToVault([decision({ rationale: "compliance reasons" })]);
83
+ const note = files.find((f) => f.path.startsWith("decisions/"));
84
+ expect(note.content).toContain("Rationale");
85
+ expect(note.content).toContain("compliance reasons");
86
+ });
87
+ it("author hub lists all decisions for that author", () => {
88
+ const decisions = [
89
+ decision({ author: "Alice", summary: "A1", date: "2024-01-01" }),
90
+ decision({ author: "Alice", summary: "A2", date: "2024-02-01" }),
91
+ ];
92
+ const files = decisionsToVault(decisions);
93
+ const hub = files.find((f) => f.path === "authors/alice.md");
94
+ expect(hub.content).toContain("A1");
95
+ expect(hub.content).toContain("A2");
96
+ expect(hub.content).toContain("decisionCount: 2");
97
+ });
98
+ it("index.md contains a wiki-linked table of recent decisions", () => {
99
+ const files = decisionsToVault([decision({ summary: "use Postgres" })]);
100
+ const index = files.find((f) => f.path === "index.md");
101
+ expect(index.content).toContain("[[decisions/");
102
+ expect(index.content).toContain("use Postgres");
103
+ });
104
+ it("filenames are filesystem- and Obsidian-safe", () => {
105
+ const tricky = decision({ summary: "decided to use C++ / Rust!" });
106
+ const files = decisionsToVault([tricky]);
107
+ for (const f of files) {
108
+ expect(f.path).not.toMatch(/[/\\:*?"<>|]/g.source.replace(/\//g, ""));
109
+ // No spaces in filenames (Obsidian works fine with them, but slugs are cleaner).
110
+ expect(f.path.split("/").pop()).not.toContain(" ");
111
+ }
112
+ });
113
+ });
114
+ describe("storyToVault", () => {
115
+ const sampleStory = {
116
+ topic: "authentication",
117
+ totalCommits: 3,
118
+ spanDays: 90,
119
+ acts: [
120
+ {
121
+ id: "initial",
122
+ title: "Act I — The Beginning",
123
+ fromDate: "2024-01-01",
124
+ toDate: "2024-01-01",
125
+ commits: [
126
+ {
127
+ hash: "a1",
128
+ shortHash: "a1",
129
+ authorName: "alice",
130
+ authorEmail: "a@x",
131
+ authorDate: "2024-01-01T00:00:00Z",
132
+ committerDate: "2024-01-01T00:00:00Z",
133
+ subject: "feat: passport",
134
+ body: "",
135
+ parents: [],
136
+ files: [],
137
+ },
138
+ ],
139
+ },
140
+ {
141
+ id: "refactor",
142
+ title: "Act II — The Refactor",
143
+ fromDate: "2024-02-01",
144
+ toDate: "2024-04-01",
145
+ commits: [
146
+ {
147
+ hash: "b1",
148
+ shortHash: "b1",
149
+ authorName: "alice",
150
+ authorEmail: "a@x",
151
+ authorDate: "2024-02-01T00:00:00Z",
152
+ committerDate: "2024-02-01T00:00:00Z",
153
+ subject: "refactor: replace passport",
154
+ body: "",
155
+ parents: [],
156
+ files: [],
157
+ },
158
+ ],
159
+ },
160
+ ],
161
+ };
162
+ it("returns a single .md file for a story", () => {
163
+ const files = storyToVault(sampleStory);
164
+ expect(files).toHaveLength(1);
165
+ expect(files[0].path).toBe("story-authentication.md");
166
+ });
167
+ it("includes frontmatter with topic, acts, commits, spanDays", () => {
168
+ const files = storyToVault(sampleStory);
169
+ const c = files[0].content;
170
+ expect(c).toContain("type: mneme-story");
171
+ expect(c).toContain("topic: authentication");
172
+ expect(c).toContain("acts: 2");
173
+ expect(c).toContain("commits: 3");
174
+ expect(c).toContain("spanDays: 90");
175
+ });
176
+ it("renders each act as a heading + commit list", () => {
177
+ const c = storyToVault(sampleStory)[0].content;
178
+ expect(c).toContain("## Act I");
179
+ expect(c).toContain("## Act II");
180
+ expect(c).toContain("feat: passport");
181
+ expect(c).toContain("refactor: replace passport");
182
+ });
183
+ it("includes LLM act summaries when provided", () => {
184
+ const summaries = new Map([
185
+ [0, "Started with passport.js OAuth"],
186
+ [1, "Replaced passport with custom JWT"],
187
+ ]);
188
+ const c = storyToVault(sampleStory, summaries)[0].content;
189
+ expect(c).toContain("Started with passport.js");
190
+ expect(c).toContain("Replaced passport");
191
+ });
192
+ it("falls back to a clean note when story has no acts", () => {
193
+ const empty = { topic: "x", totalCommits: 0, spanDays: 0, acts: [] };
194
+ const files = storyToVault(empty);
195
+ expect(files[0].content).toContain("No commits matched");
196
+ });
197
+ });
198
+ describe("expertsToVault", () => {
199
+ const sampleExperts = [
200
+ {
201
+ name: "Alice",
202
+ email: "a@x",
203
+ commitCount: 20,
204
+ filesTouched: 50,
205
+ lastTouch: "2026-04-01T00:00:00Z",
206
+ score: 4.0,
207
+ tier: "definitive",
208
+ },
209
+ {
210
+ name: "Bob",
211
+ email: "b@x",
212
+ commitCount: 5,
213
+ filesTouched: 12,
214
+ lastTouch: "2025-12-01T00:00:00Z",
215
+ score: 1.5,
216
+ tier: "stale",
217
+ },
218
+ ];
219
+ it("returns a single experts note", () => {
220
+ const files = expertsToVault("stripe", sampleExperts);
221
+ expect(files).toHaveLength(1);
222
+ expect(files[0].path).toBe("experts-stripe.md");
223
+ });
224
+ it("renders a markdown table with tier, name, counts, last touch", () => {
225
+ const c = expertsToVault("stripe", sampleExperts)[0].content;
226
+ expect(c).toContain("| Tier | Name | Commits | Files | Last touch |");
227
+ expect(c).toContain("definitive");
228
+ expect(c).toContain("Alice");
229
+ expect(c).toContain("20");
230
+ });
231
+ it("links each name to the author hub", () => {
232
+ const c = expertsToVault("stripe", sampleExperts)[0].content;
233
+ expect(c).toContain("[[authors/alice|Alice]]");
234
+ expect(c).toContain("[[authors/bob|Bob]]");
235
+ });
236
+ it("falls back to a friendly note when no experts found", () => {
237
+ const c = expertsToVault("nothing", [])[0].content;
238
+ expect(c).toContain("No experts found");
239
+ });
240
+ });
241
+ //# sourceMappingURL=obsidian.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obsidian.test.js","sourceRoot":"","sources":["../../src/insights/obsidian.test.ts"],"names":[],"mappings":"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"}