anno-extension 0.1.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 (199) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +30 -0
  3. package/THIRD_PARTY_NOTICES.md +8 -0
  4. package/dist/browser-fs.d.ts +14 -0
  5. package/dist/browser-fs.d.ts.map +1 -0
  6. package/dist/browser-fs.js +69 -0
  7. package/dist/browser-fs.js.map +1 -0
  8. package/dist/config.d.ts +81 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +82 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/consolidate-v2.d.ts +15 -0
  13. package/dist/consolidate-v2.d.ts.map +1 -0
  14. package/dist/consolidate-v2.js +125 -0
  15. package/dist/consolidate-v2.js.map +1 -0
  16. package/dist/consolidation.d.ts +12 -0
  17. package/dist/consolidation.d.ts.map +1 -0
  18. package/dist/consolidation.js +199 -0
  19. package/dist/consolidation.js.map +1 -0
  20. package/dist/dedup.d.ts +18 -0
  21. package/dist/dedup.d.ts.map +1 -0
  22. package/dist/dedup.js +85 -0
  23. package/dist/dedup.js.map +1 -0
  24. package/dist/diagnostics.d.ts +24 -0
  25. package/dist/diagnostics.d.ts.map +1 -0
  26. package/dist/diagnostics.js +53 -0
  27. package/dist/diagnostics.js.map +1 -0
  28. package/dist/embedding-index.d.ts +27 -0
  29. package/dist/embedding-index.d.ts.map +1 -0
  30. package/dist/embedding-index.js +111 -0
  31. package/dist/embedding-index.js.map +1 -0
  32. package/dist/engine-archive.d.ts +37 -0
  33. package/dist/engine-archive.d.ts.map +1 -0
  34. package/dist/engine-archive.js +155 -0
  35. package/dist/engine-archive.js.map +1 -0
  36. package/dist/engine-episode-sync.d.ts +19 -0
  37. package/dist/engine-episode-sync.d.ts.map +1 -0
  38. package/dist/engine-episode-sync.js +186 -0
  39. package/dist/engine-episode-sync.js.map +1 -0
  40. package/dist/engine-injection-text.d.ts +46 -0
  41. package/dist/engine-injection-text.d.ts.map +1 -0
  42. package/dist/engine-injection-text.js +271 -0
  43. package/dist/engine-injection-text.js.map +1 -0
  44. package/dist/engine-insights.d.ts +22 -0
  45. package/dist/engine-insights.d.ts.map +1 -0
  46. package/dist/engine-insights.js +127 -0
  47. package/dist/engine-insights.js.map +1 -0
  48. package/dist/engine-links.d.ts +43 -0
  49. package/dist/engine-links.d.ts.map +1 -0
  50. package/dist/engine-links.js +223 -0
  51. package/dist/engine-links.js.map +1 -0
  52. package/dist/engine-recall-select.d.ts +84 -0
  53. package/dist/engine-recall-select.d.ts.map +1 -0
  54. package/dist/engine-recall-select.js +127 -0
  55. package/dist/engine-recall-select.js.map +1 -0
  56. package/dist/engine-reinforce.d.ts +18 -0
  57. package/dist/engine-reinforce.d.ts.map +1 -0
  58. package/dist/engine-reinforce.js +116 -0
  59. package/dist/engine-reinforce.js.map +1 -0
  60. package/dist/engine-scoring-v2.d.ts +35 -0
  61. package/dist/engine-scoring-v2.d.ts.map +1 -0
  62. package/dist/engine-scoring-v2.js +178 -0
  63. package/dist/engine-scoring-v2.js.map +1 -0
  64. package/dist/engine-v2-mapping.d.ts +17 -0
  65. package/dist/engine-v2-mapping.d.ts.map +1 -0
  66. package/dist/engine-v2-mapping.js +190 -0
  67. package/dist/engine-v2-mapping.js.map +1 -0
  68. package/dist/engine.d.ts +339 -0
  69. package/dist/engine.d.ts.map +1 -0
  70. package/dist/engine.js +1964 -0
  71. package/dist/engine.js.map +1 -0
  72. package/dist/eviction.d.ts +14 -0
  73. package/dist/eviction.d.ts.map +1 -0
  74. package/dist/eviction.js +26 -0
  75. package/dist/eviction.js.map +1 -0
  76. package/dist/extraction.d.ts +11 -0
  77. package/dist/extraction.d.ts.map +1 -0
  78. package/dist/extraction.js +261 -0
  79. package/dist/extraction.js.map +1 -0
  80. package/dist/full-insights-html.d.ts +9 -0
  81. package/dist/full-insights-html.d.ts.map +1 -0
  82. package/dist/full-insights-html.js +422 -0
  83. package/dist/full-insights-html.js.map +1 -0
  84. package/dist/full-insights-sections.d.ts +48 -0
  85. package/dist/full-insights-sections.d.ts.map +1 -0
  86. package/dist/full-insights-sections.js +231 -0
  87. package/dist/full-insights-sections.js.map +1 -0
  88. package/dist/full-insights.d.ts +22 -0
  89. package/dist/full-insights.d.ts.map +1 -0
  90. package/dist/full-insights.js +370 -0
  91. package/dist/full-insights.js.map +1 -0
  92. package/dist/hash-embedding.d.ts +9 -0
  93. package/dist/hash-embedding.d.ts.map +1 -0
  94. package/dist/hash-embedding.js +44 -0
  95. package/dist/hash-embedding.js.map +1 -0
  96. package/dist/human-insights.d.ts +28 -0
  97. package/dist/human-insights.d.ts.map +1 -0
  98. package/dist/human-insights.js +260 -0
  99. package/dist/human-insights.js.map +1 -0
  100. package/dist/i18n.d.ts +64 -0
  101. package/dist/i18n.d.ts.map +1 -0
  102. package/dist/i18n.js +367 -0
  103. package/dist/i18n.js.map +1 -0
  104. package/dist/index.d.ts +27 -0
  105. package/dist/index.d.ts.map +1 -0
  106. package/dist/index.js +21 -0
  107. package/dist/index.js.map +1 -0
  108. package/dist/insights-html.d.ts +9 -0
  109. package/dist/insights-html.d.ts.map +1 -0
  110. package/dist/insights-html.js +432 -0
  111. package/dist/insights-html.js.map +1 -0
  112. package/dist/linking.d.ts +22 -0
  113. package/dist/linking.d.ts.map +1 -0
  114. package/dist/linking.js +192 -0
  115. package/dist/linking.js.map +1 -0
  116. package/dist/llm-json.d.ts +10 -0
  117. package/dist/llm-json.d.ts.map +1 -0
  118. package/dist/llm-json.js +193 -0
  119. package/dist/llm-json.js.map +1 -0
  120. package/dist/privacy.d.ts +17 -0
  121. package/dist/privacy.d.ts.map +1 -0
  122. package/dist/privacy.js +53 -0
  123. package/dist/privacy.js.map +1 -0
  124. package/dist/procedural-v2.d.ts +9 -0
  125. package/dist/procedural-v2.d.ts.map +1 -0
  126. package/dist/procedural-v2.js +123 -0
  127. package/dist/procedural-v2.js.map +1 -0
  128. package/dist/reconsolidate-v2.d.ts +19 -0
  129. package/dist/reconsolidate-v2.d.ts.map +1 -0
  130. package/dist/reconsolidate-v2.js +115 -0
  131. package/dist/reconsolidate-v2.js.map +1 -0
  132. package/dist/scoring.d.ts +32 -0
  133. package/dist/scoring.d.ts.map +1 -0
  134. package/dist/scoring.js +108 -0
  135. package/dist/scoring.js.map +1 -0
  136. package/dist/store-v2.d.ts +35 -0
  137. package/dist/store-v2.d.ts.map +1 -0
  138. package/dist/store-v2.js +98 -0
  139. package/dist/store-v2.js.map +1 -0
  140. package/dist/store.d.ts +22 -0
  141. package/dist/store.d.ts.map +1 -0
  142. package/dist/store.js +116 -0
  143. package/dist/store.js.map +1 -0
  144. package/dist/turn-context.d.ts +37 -0
  145. package/dist/turn-context.d.ts.map +1 -0
  146. package/dist/turn-context.js +31 -0
  147. package/dist/turn-context.js.map +1 -0
  148. package/dist/types-v2.d.ts +190 -0
  149. package/dist/types-v2.d.ts.map +1 -0
  150. package/dist/types-v2.js +8 -0
  151. package/dist/types-v2.js.map +1 -0
  152. package/dist/types.d.ts +330 -0
  153. package/dist/types.d.ts.map +1 -0
  154. package/dist/types.js +8 -0
  155. package/dist/types.js.map +1 -0
  156. package/dist/update.d.ts +31 -0
  157. package/dist/update.d.ts.map +1 -0
  158. package/dist/update.js +250 -0
  159. package/dist/update.js.map +1 -0
  160. package/package.json +34 -0
  161. package/src/browser-fs.ts +67 -0
  162. package/src/config.ts +138 -0
  163. package/src/consolidate-v2.ts +158 -0
  164. package/src/consolidation.ts +229 -0
  165. package/src/dedup.ts +91 -0
  166. package/src/diagnostics.ts +81 -0
  167. package/src/embedding-index.ts +138 -0
  168. package/src/engine-archive.ts +167 -0
  169. package/src/engine-episode-sync.ts +237 -0
  170. package/src/engine-injection-text.ts +334 -0
  171. package/src/engine-insights.ts +182 -0
  172. package/src/engine-links.ts +311 -0
  173. package/src/engine-recall-select.ts +298 -0
  174. package/src/engine-reinforce.ts +154 -0
  175. package/src/engine-scoring-v2.ts +188 -0
  176. package/src/engine-v2-mapping.ts +204 -0
  177. package/src/engine.ts +2499 -0
  178. package/src/eviction.ts +38 -0
  179. package/src/extraction.ts +300 -0
  180. package/src/full-insights-html.ts +474 -0
  181. package/src/full-insights-sections.ts +305 -0
  182. package/src/full-insights.ts +423 -0
  183. package/src/hash-embedding.ts +48 -0
  184. package/src/human-insights.ts +345 -0
  185. package/src/i18n.ts +455 -0
  186. package/src/index.ts +117 -0
  187. package/src/insights-html.ts +478 -0
  188. package/src/linking.ts +228 -0
  189. package/src/llm-json.ts +194 -0
  190. package/src/privacy.ts +54 -0
  191. package/src/procedural-v2.ts +142 -0
  192. package/src/reconsolidate-v2.ts +145 -0
  193. package/src/scoring.ts +156 -0
  194. package/src/store-v2.ts +138 -0
  195. package/src/store.ts +137 -0
  196. package/src/turn-context.ts +56 -0
  197. package/src/types-v2.ts +244 -0
  198. package/src/types.ts +372 -0
  199. package/src/update.ts +271 -0
@@ -0,0 +1,231 @@
1
+ /**
2
+ * [WHO]: generateParallelFullInsightSections(), FullInsightsSectionPayload
3
+ * [FROM]: Depends on ./llm-json and ./types for structured LLM section generation
4
+ * [TO]: Consumed by full-insights.ts to improve /mem-insights narrative quality
5
+ * [HERE]: packages/mem-core/src/full-insights-sections.ts - Claude-style parallel section generation without copying upstream implementation
6
+ */
7
+ import { parseLlmJson } from "./llm-json.js";
8
+ const OBSERVER_VOICE_RULES = `Voice rules:
9
+ - Be a warm but sharp long-term coding partner: kind, direct, observant.
10
+ - Write like an observant agent keeping a private work diary and a practical field report for the user.
11
+ - Tie every claim to the provided data; if evidence is thin, say the signal is still thin.
12
+ - No generic praise, personality diagnosis, therapy language, motivational fluff, or invented emotion.
13
+ - Each item should name the observed pattern, explain why it matters, and offer one next move when the schema allows.`;
14
+ function compactContext(context) {
15
+ return {
16
+ locale: context.locale,
17
+ outputLanguage: context.outputLanguage,
18
+ stats: context.stats,
19
+ projectAreas: context.projectAreas.slice(0, 8).map((area) => ({
20
+ name: area.name,
21
+ sessionCount: area.sessionCount,
22
+ description: area.description,
23
+ })),
24
+ patterns: context.patterns.slice(0, 8).map((pattern) => ({
25
+ trigger: pattern.trigger,
26
+ behavior: pattern.behavior,
27
+ weight: Number(pattern.weight.toFixed(2)),
28
+ })),
29
+ struggles: context.struggles.slice(0, 8).map((struggle) => ({
30
+ problem: struggle.problem,
31
+ resolved: struggle.resolved,
32
+ attempts: struggle.attempts.slice(0, 3),
33
+ solution: struggle.solution,
34
+ weight: Number(struggle.weight.toFixed(2)),
35
+ })),
36
+ lessons: context.lessons.slice(0, 8).map((lesson) => lesson.summary || lesson.detail || lesson.content || ""),
37
+ topTools: context.topTools.slice(0, 8),
38
+ topLanguages: context.topLanguages.slice(0, 8),
39
+ topErrors: context.topErrors.slice(0, 8),
40
+ };
41
+ }
42
+ function sectionSpecs(outputLanguage) {
43
+ const languageRule = `Write the JSON string values in ${outputLanguage}, matching the user's observed language habits.`;
44
+ return [
45
+ {
46
+ name: "project_areas",
47
+ prompt: `${OBSERVER_VOICE_RULES}
48
+
49
+ Identify the main project/work areas from this developer memory report. Describe each area as something you have been watching the user return to, including what that investment suggests about their current work.
50
+ ${languageRule}
51
+ Return ONLY valid JSON:
52
+ {"descriptions":["one description per provided project area, preserving order"]}`,
53
+ },
54
+ {
55
+ name: "wins",
56
+ prompt: `${OBSERVER_VOICE_RULES}
57
+
58
+ Find concrete workflows that are working well. Make the wins feel seen, not flattered: recognize the user's effective habits with evidence from tools, lessons, resolved struggles, or project areas.
59
+ ${languageRule}
60
+ Return ONLY valid JSON:
61
+ {"wins":[{"title":"3-7 word title","description":"2-3 specific sentences"}]}`,
62
+ },
63
+ {
64
+ name: "frictions",
65
+ prompt: `${OBSERVER_VOICE_RULES}
66
+
67
+ Find recurring friction. Be gentle with the user but incisive about the system of work: prefer root causes over symptoms, avoid blame, and include examples when available.
68
+ ${languageRule}
69
+ Return ONLY valid JSON:
70
+ {"frictions":[{"title":"short category","description":"1-2 sentences","examples":["specific example"]}]}`,
71
+ },
72
+ {
73
+ name: "recommendations",
74
+ prompt: `${OBSERVER_VOICE_RULES}
75
+
76
+ Suggest direct behavior changes. Each recommendation should read like a useful note from a partner who has watched the pattern before: observation, why it matters, next move for the next session.
77
+ ${languageRule}
78
+ Return ONLY valid JSON:
79
+ {"recommendations":["recommendation sentence"]}`,
80
+ },
81
+ {
82
+ name: "features",
83
+ prompt: `${OBSERVER_VOICE_RULES}
84
+
85
+ Suggest Catui features or workflows this user should try based on their actual usage. Prefer skills, MCP, hooks, headless commands, subagents, recap, memory, or token-save only when evidence supports it; explain why it fits this user's observed habits.
86
+ ${languageRule}
87
+ Return ONLY valid JSON:
88
+ {"featuresToTry":[{"title":"feature/workflow","oneLiner":"what it does","whyForYou":"why this user should try it","exampleCode":"optional command or config"}]}`,
89
+ },
90
+ {
91
+ name: "usage_patterns",
92
+ prompt: `${OBSERVER_VOICE_RULES}
93
+
94
+ Suggest reusable prompt/workflow patterns. Make each one copyable and grounded in the reported friction or wins, as if you are leaving the user a practical note for how to begin next time.
95
+ ${languageRule}
96
+ Return ONLY valid JSON:
97
+ {"usagePatterns":[{"title":"pattern","summary":"short summary","detail":"how to apply it","pastePrompt":"copyable prompt"}]}`,
98
+ },
99
+ ];
100
+ }
101
+ async function generateSection(spec, contextJson, llmFn) {
102
+ try {
103
+ const raw = await llmFn("You write structured developer usage insights as a warm but sharp long-term coding partner. Output only valid JSON matching the requested schema.", `${spec.prompt}\n\nDATA:\n${contextJson}`);
104
+ const parsed = parseLlmJson(raw);
105
+ return { name: spec.name, result: parsed && typeof parsed === "object" ? parsed : null };
106
+ }
107
+ catch {
108
+ return { name: spec.name, result: null };
109
+ }
110
+ }
111
+ function asStringArray(value) {
112
+ if (!Array.isArray(value))
113
+ return undefined;
114
+ const items = value.filter((item) => typeof item === "string" && item.trim().length > 0);
115
+ return items.length ? items : undefined;
116
+ }
117
+ function asWins(value) {
118
+ if (!Array.isArray(value))
119
+ return undefined;
120
+ const wins = value
121
+ .map((item) => item)
122
+ .filter((item) => typeof item.title === "string" && typeof item.description === "string")
123
+ .map((item) => ({ title: item.title, description: item.description }));
124
+ return wins.length ? wins : undefined;
125
+ }
126
+ function asFrictions(value) {
127
+ if (!Array.isArray(value))
128
+ return undefined;
129
+ const frictions = value
130
+ .map((item) => item)
131
+ .filter((item) => typeof item.title === "string" && typeof item.description === "string")
132
+ .map((item) => ({
133
+ title: item.title,
134
+ description: item.description,
135
+ examples: Array.isArray(item.examples)
136
+ ? item.examples.filter((example) => typeof example === "string")
137
+ : undefined,
138
+ }));
139
+ return frictions.length ? frictions : undefined;
140
+ }
141
+ function asFeatures(value) {
142
+ if (!Array.isArray(value))
143
+ return undefined;
144
+ const features = value
145
+ .map((item) => item)
146
+ .filter((item) => typeof item.title === "string" && typeof item.oneLiner === "string" && typeof item.whyForYou === "string")
147
+ .map((item) => ({
148
+ title: item.title,
149
+ oneLiner: item.oneLiner,
150
+ whyForYou: item.whyForYou,
151
+ exampleCode: typeof item.exampleCode === "string" ? item.exampleCode : undefined,
152
+ }));
153
+ return features.length ? features : undefined;
154
+ }
155
+ function asUsagePatterns(value) {
156
+ if (!Array.isArray(value))
157
+ return undefined;
158
+ const patterns = value
159
+ .map((item) => item)
160
+ .filter((item) => typeof item.title === "string" && typeof item.summary === "string" && typeof item.detail === "string")
161
+ .map((item) => ({
162
+ title: item.title,
163
+ summary: item.summary,
164
+ detail: item.detail,
165
+ pastePrompt: typeof item.pastePrompt === "string" ? item.pastePrompt : undefined,
166
+ }));
167
+ return patterns.length ? patterns : undefined;
168
+ }
169
+ function mergeSectionPayload(results) {
170
+ const payload = {};
171
+ for (const { name, result } of results) {
172
+ if (!result)
173
+ continue;
174
+ if (name === "project_areas")
175
+ payload.projectAreaDescriptions = asStringArray(result.descriptions);
176
+ if (name === "wins")
177
+ payload.wins = asWins(result.wins);
178
+ if (name === "frictions")
179
+ payload.frictions = asFrictions(result.frictions);
180
+ if (name === "recommendations")
181
+ payload.recommendations = asStringArray(result.recommendations);
182
+ if (name === "features")
183
+ payload.featuresToTry = asFeatures(result.featuresToTry);
184
+ if (name === "usage_patterns")
185
+ payload.usagePatterns = asUsagePatterns(result.usagePatterns);
186
+ }
187
+ return payload;
188
+ }
189
+ async function generateAtAGlance(contextJson, sections, llmFn, outputLanguage) {
190
+ const languageRule = `Write concise natural ${outputLanguage}, matching the user's observed language habits.`;
191
+ try {
192
+ const raw = await llmFn("You write executive summaries for developer usage reports. Output only valid JSON.", `${OBSERVER_VOICE_RULES}
193
+
194
+ ${languageRule}
195
+ Synthesize the section outputs into four short, candid coaching blurbs. Make this read like the opening note of a private diary and field report from a long-term coding partner: intimate enough to feel observed, precise enough to be useful.
196
+ Return ONLY valid JSON:
197
+ {"working":"what is working","hindering":"what is hindering","quickWins":"quick wins to try","ambitious":"ambitious workflows to prepare for"}
198
+
199
+ BASE DATA:
200
+ ${contextJson}
201
+
202
+ SECTION OUTPUTS:
203
+ ${JSON.stringify(sections, null, 2)}`);
204
+ const parsed = parseLlmJson(raw);
205
+ if (typeof parsed?.working === "string" &&
206
+ typeof parsed.hindering === "string" &&
207
+ typeof parsed.quickWins === "string" &&
208
+ typeof parsed.ambitious === "string") {
209
+ return {
210
+ working: parsed.working,
211
+ hindering: parsed.hindering,
212
+ quickWins: parsed.quickWins,
213
+ ambitious: parsed.ambitious,
214
+ };
215
+ }
216
+ }
217
+ catch {
218
+ // Keep caller fallbacks.
219
+ }
220
+ return undefined;
221
+ }
222
+ export async function generateParallelFullInsightSections(context, llmFn) {
223
+ const contextJson = JSON.stringify(compactContext(context), null, 2);
224
+ const results = await Promise.all(sectionSpecs(context.outputLanguage).map((spec) => generateSection(spec, contextJson, llmFn)));
225
+ const payload = mergeSectionPayload(results);
226
+ const atAGlance = await generateAtAGlance(contextJson, payload, llmFn, context.outputLanguage);
227
+ if (atAGlance)
228
+ payload.atAGlance = atAGlance;
229
+ return payload;
230
+ }
231
+ //# sourceMappingURL=full-insights-sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"full-insights-sections.js","sourceRoot":"","sources":["../src/full-insights-sections.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * [WHO]: FullInsightsReport, generateFullInsights
3
+ * [FROM]: Depends on ./i18n.js, ./full-insights-sections.js, ./types.js
4
+ * [TO]: Consumed by packages/mem-core/src/index.ts
5
+ * [HERE]: packages/mem-core/src/full-insights.ts - aggregation + optional LLM for comprehensive insights report
6
+ */
7
+ import type { Episode, FullInsightsReport, LlmFn, MemoryEntry, WorkEntry } from "./types.js";
8
+ export interface ExportAllResult {
9
+ knowledge: MemoryEntry[];
10
+ lessons: MemoryEntry[];
11
+ preferences: MemoryEntry[];
12
+ facets: MemoryEntry[];
13
+ work: WorkEntry[];
14
+ episodes: Episode[];
15
+ meta: {
16
+ totalSessions: number;
17
+ lastConsolidation?: string;
18
+ version: number;
19
+ };
20
+ }
21
+ export declare function buildFullInsightsReport(all: ExportAllResult, llmFn: LlmFn | undefined, locale: string): Promise<FullInsightsReport>;
22
+ //# sourceMappingURL=full-insights.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"full-insights.d.ts","sourceRoot":"","sources":["../src/full-insights.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EACX,OAAO,EAKP,kBAAkB,EAIlB,KAAK,EACL,WAAW,EAGX,SAAS,EACT,MAAM,YAAY,CAAC;AAkBpB,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,IAAI,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7E;AA6QD,wBAAsB,uBAAuB,CAC5C,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,CAAC,CAmG7B"}
@@ -0,0 +1,370 @@
1
+ /**
2
+ * [WHO]: FullInsightsReport, generateFullInsights
3
+ * [FROM]: Depends on ./i18n.js, ./full-insights-sections.js, ./types.js
4
+ * [TO]: Consumed by packages/mem-core/src/index.ts
5
+ * [HERE]: packages/mem-core/src/full-insights.ts - aggregation + optional LLM for comprehensive insights report
6
+ */
7
+ import { PROMPTS } from "./i18n.js";
8
+ import { generateParallelFullInsightSections } from "./full-insights-sections.js";
9
+ const EXT_TO_LANG = {
10
+ ts: "TypeScript",
11
+ js: "JavaScript",
12
+ jsx: "JSX",
13
+ tsx: "TSX",
14
+ md: "Markdown",
15
+ json: "JSON",
16
+ py: "Python",
17
+ html: "HTML",
18
+ css: "CSS",
19
+ yml: "YAML",
20
+ yaml: "YAML",
21
+ sh: "Shell",
22
+ };
23
+ function aggregateTools(episodes, topN = 10) {
24
+ const counts = {};
25
+ for (const ep of episodes) {
26
+ for (const [name, n] of Object.entries(ep.toolsUsed ?? {})) {
27
+ counts[name] = (counts[name] ?? 0) + n;
28
+ }
29
+ }
30
+ const rows = Object.entries(counts)
31
+ .map(([label, value]) => ({ label, value }))
32
+ .sort((a, b) => b.value - a.value)
33
+ .slice(0, topN);
34
+ return { id: "tools", title: "tools", rows };
35
+ }
36
+ function aggregateLanguages(episodes, topN = 8) {
37
+ const counts = {};
38
+ for (const ep of episodes) {
39
+ for (const path of ep.filesModified ?? []) {
40
+ const ext = path.includes(".") ? path.split(".").pop()?.toLowerCase() ?? "other" : "other";
41
+ const label = EXT_TO_LANG[ext] ?? ext;
42
+ counts[label] = (counts[label] ?? 0) + 1;
43
+ }
44
+ }
45
+ const rows = Object.entries(counts)
46
+ .filter(([label]) => label !== "other" || (counts[label] ?? 0) > 0)
47
+ .map(([label, value]) => ({ label, value }))
48
+ .sort((a, b) => b.value - a.value)
49
+ .slice(0, topN);
50
+ return { id: "languages", title: "languages", rows };
51
+ }
52
+ function aggregateErrors(episodes, topN = 8) {
53
+ const counts = {};
54
+ for (const ep of episodes) {
55
+ for (const err of ep.errors ?? []) {
56
+ const key = err.slice(0, 50).trim();
57
+ counts[key] = (counts[key] ?? 0) + 1;
58
+ }
59
+ }
60
+ const rows = Object.entries(counts)
61
+ .map(([label, value]) => ({ label, value }))
62
+ .sort((a, b) => b.value - a.value)
63
+ .slice(0, topN);
64
+ return { id: "errors", title: "errors", rows };
65
+ }
66
+ function buildProjectAreas(episodes, work) {
67
+ const byProject = new Map();
68
+ for (const ep of episodes) {
69
+ const p = ep.project || "default";
70
+ if (!byProject.has(p))
71
+ byProject.set(p, { count: 0, summaries: [], goals: [] });
72
+ const entry = byProject.get(p);
73
+ entry.count++;
74
+ if (ep.summary)
75
+ entry.summaries.push(ep.summary);
76
+ if (ep.userGoal)
77
+ entry.goals.push(ep.userGoal);
78
+ }
79
+ for (const w of work) {
80
+ const p = w.project || "default";
81
+ if (!byProject.has(p))
82
+ byProject.set(p, { count: 0, summaries: [], goals: [] });
83
+ const entry = byProject.get(p);
84
+ if (w.summary)
85
+ entry.summaries.push(w.summary);
86
+ if (w.goal)
87
+ entry.goals.push(w.goal);
88
+ }
89
+ return [...byProject.entries()]
90
+ .filter(([, v]) => v.count >= 1 || v.summaries.length + v.goals.length > 0)
91
+ .map(([name, v]) => ({
92
+ name,
93
+ sessionCount: v.count,
94
+ description: [v.summaries[0], v.goals[0]].filter(Boolean).join(" ").slice(0, 120) || "",
95
+ }))
96
+ .sort((a, b) => b.sessionCount - a.sessionCount)
97
+ .slice(0, 12);
98
+ }
99
+ function buildPatternsAndStruggles(facets) {
100
+ const patternEntries = facets.filter((e) => e.type === "pattern");
101
+ const struggleEntries = facets.filter((e) => e.type === "struggle");
102
+ const calcWeight = (e, unresolvedBonus = false) => {
103
+ const base = (e.accessCount + 1) * (e.importance / 10);
104
+ return unresolvedBonus ? base * 1.5 : base;
105
+ };
106
+ const patterns = patternEntries
107
+ .map((e) => ({
108
+ entry: e,
109
+ weight: calcWeight(e),
110
+ trigger: e.facetData?.kind === "pattern" ? e.facetData.trigger : (e.summary || e.detail || e.content || "").slice(0, 50),
111
+ behavior: e.facetData?.kind === "pattern" ? e.facetData.behavior : (e.summary || e.detail || e.content || ""),
112
+ }))
113
+ .sort((a, b) => b.weight - a.weight);
114
+ const struggles = struggleEntries
115
+ .map((e) => {
116
+ const isResolved = e.facetData?.kind === "struggle" ? !!e.facetData.solution : false;
117
+ return {
118
+ entry: e,
119
+ weight: calcWeight(e, !isResolved),
120
+ problem: e.facetData?.kind === "struggle" ? e.facetData.problem : (e.summary || e.detail || e.content || ""),
121
+ attempts: e.facetData?.kind === "struggle" ? e.facetData.attempts : [],
122
+ solution: e.facetData?.kind === "struggle" ? e.facetData.solution : "",
123
+ resolved: isResolved,
124
+ };
125
+ })
126
+ .sort((a, b) => (a.resolved !== b.resolved ? (a.resolved ? 1 : -1) : b.weight - a.weight));
127
+ return { patterns, struggles };
128
+ }
129
+ function fallbackAtAGlance(patterns, struggles, lessons, locale) {
130
+ const resolved = struggles.filter((s) => s.resolved);
131
+ const unresolved = struggles.filter((s) => !s.resolved);
132
+ const working = resolved.length > 0
133
+ ? `${resolved.length} struggles resolved; keep reusing those fixes.`
134
+ : lessons.length > 0
135
+ ? `${lessons.length} lessons captured; turn the top ones into checklists.`
136
+ : "No strong signal yet.";
137
+ const hindering = unresolved.length > 0
138
+ ? `${unresolved.length} open struggles remain. Most frequent: "${unresolved[0]?.problem ?? ""}".`
139
+ : "No unresolved struggles visible.";
140
+ const topPattern = patterns[0];
141
+ const quickWins = topPattern
142
+ ? `When ${topPattern.trigger}, you often ${topPattern.behavior}. Consider automating.`
143
+ : "Keep using the system; quick wins will appear as data grows.";
144
+ const ambitious = "Consider turning repeat workflows into skills or scripts and using parallel agents.";
145
+ return { working, hindering, quickWins, ambitious };
146
+ }
147
+ function fallbackWins(struggles, lessons) {
148
+ const wins = [];
149
+ for (const s of struggles.filter((x) => x.resolved).slice(0, 5)) {
150
+ wins.push({ title: s.problem.slice(0, 60), description: s.solution || s.problem });
151
+ }
152
+ const sortLessons = [...lessons].sort((a, b) => b.importance * (b.accessCount + 1) - a.importance * (a.accessCount + 1));
153
+ for (const l of sortLessons.slice(0, 3)) {
154
+ const text = l.summary || l.detail || l.content || "";
155
+ wins.push({ title: text.slice(0, 60), description: text });
156
+ }
157
+ return wins.slice(0, 8);
158
+ }
159
+ function fallbackFrictions(struggles) {
160
+ return struggles
161
+ .filter((s) => !s.resolved)
162
+ .slice(0, 8)
163
+ .map((s) => ({
164
+ title: s.problem.slice(0, 60),
165
+ description: s.problem,
166
+ examples: s.attempts.length ? s.attempts : undefined,
167
+ }));
168
+ }
169
+ function fallbackRecommendations(patterns, struggles, lessons, locale) {
170
+ const recs = [];
171
+ if (patterns.length > 0) {
172
+ const top = patterns[0];
173
+ recs.push(`You consistently ${top.behavior} when ${top.trigger}. Consider automating.`);
174
+ }
175
+ const unresolved = struggles.filter((s) => !s.resolved);
176
+ if (unresolved.length >= 2) {
177
+ recs.push(`You have ${unresolved.length} unresolved issues. Tackle them systematically.`);
178
+ }
179
+ if (lessons.length >= 5) {
180
+ recs.push(`You've accumulated ${lessons.length} lessons. Valuable expertise.`);
181
+ }
182
+ if (recs.length === 0) {
183
+ recs.push("Keep using the system to let it learn your habits.");
184
+ }
185
+ return recs.slice(0, 5);
186
+ }
187
+ function fallbackFeaturesAndPatterns(toolRows, struggles, locale) {
188
+ const featuresToTry = [];
189
+ const usagePatterns = [];
190
+ if (toolRows.length > 0) {
191
+ const topTool = toolRows[0].label;
192
+ featuresToTry.push({
193
+ title: "Automate frequent operations",
194
+ oneLiner: "Turn repeat workflows into skills or scripts",
195
+ whyForYou: `You use "${topTool}" often; consider wrapping it in a skill or command.`,
196
+ });
197
+ }
198
+ if (struggles.filter((s) => !s.resolved).length >= 2) {
199
+ usagePatterns.push({
200
+ title: "Batch large tasks",
201
+ summary: "Split large files or batches into smaller chunks",
202
+ detail: "Avoid context overflow by validating each batch before continuing.",
203
+ pastePrompt: "Break this into 3-4 steps; show me the result after each step before continuing.",
204
+ });
205
+ }
206
+ return { featuresToTry, usagePatterns };
207
+ }
208
+ function entryText(entry) {
209
+ return [entry.name, entry.summary, entry.detail, entry.content, entry.tags.join(" ")].filter(Boolean).join("\n");
210
+ }
211
+ function languageFromExplicitPreference(text) {
212
+ if (/(中文|汉语|Chinese|Mandarin|用中文|中文输出|中文交流)/i.test(text))
213
+ return { code: "zh", name: "Chinese" };
214
+ if (/(英文|英语|English|use English|write in English)/i.test(text))
215
+ return { code: "en", name: "English" };
216
+ if (/(日文|日语|日本語|Japanese)/i.test(text))
217
+ return { code: "ja", name: "Japanese" };
218
+ if (/(韩文|韩语|한국어|Korean)/i.test(text))
219
+ return { code: "ko", name: "Korean" };
220
+ if (/(法文|法语|français|French)/i.test(text))
221
+ return { code: "fr", name: "French" };
222
+ if (/(西班牙文|西班牙语|español|Spanish)/i.test(text))
223
+ return { code: "es", name: "Spanish" };
224
+ if (/(德文|德语|Deutsch|German)/i.test(text))
225
+ return { code: "de", name: "German" };
226
+ return undefined;
227
+ }
228
+ function languageFromScript(text) {
229
+ const han = (text.match(/\p{Script=Han}/gu) ?? []).length;
230
+ const kana = (text.match(/[\p{Script=Hiragana}\p{Script=Katakana}]/gu) ?? []).length;
231
+ const hangul = (text.match(/\p{Script=Hangul}/gu) ?? []).length;
232
+ const cyrillic = (text.match(/\p{Script=Cyrillic}/gu) ?? []).length;
233
+ const arabic = (text.match(/\p{Script=Arabic}/gu) ?? []).length;
234
+ const latinWords = (text.match(/[A-Za-z]{3,}/g) ?? []).length;
235
+ if (kana >= 4)
236
+ return { code: "ja", name: "Japanese" };
237
+ if (hangul >= 4)
238
+ return { code: "ko", name: "Korean" };
239
+ if (han >= 8 && han >= latinWords)
240
+ return { code: "zh", name: "Chinese" };
241
+ if (cyrillic >= 8)
242
+ return { code: "ru", name: "Russian" };
243
+ if (arabic >= 8)
244
+ return { code: "ar", name: "Arabic" };
245
+ if (latinWords >= 20 && han + kana + hangul + cyrillic + arabic === 0)
246
+ return { code: "en", name: "English" };
247
+ return undefined;
248
+ }
249
+ function fallbackLanguage(locale) {
250
+ if (locale === "zh")
251
+ return { code: "zh", name: "Chinese" };
252
+ if (locale === "en")
253
+ return { code: "en", name: "English" };
254
+ return { code: locale, name: locale };
255
+ }
256
+ function inferObservedReportLanguage(all, locale) {
257
+ const preferenceText = all.preferences.map(entryText).join("\n");
258
+ const explicit = languageFromExplicitPreference(preferenceText);
259
+ if (explicit)
260
+ return explicit;
261
+ const observedText = [
262
+ preferenceText,
263
+ ...all.episodes.flatMap((episode) => [
264
+ episode.summary,
265
+ episode.userGoal ?? "",
266
+ ...episode.keyObservations,
267
+ ...episode.tags,
268
+ ]),
269
+ ...all.work.flatMap((work) => [work.goal, work.summary, work.detail ?? "", ...work.tags]),
270
+ ...all.lessons.map(entryText),
271
+ ...all.knowledge.map(entryText),
272
+ ...all.facets.map(entryText),
273
+ ].join("\n");
274
+ return languageFromScript(observedText) ?? fallbackLanguage(locale);
275
+ }
276
+ export async function buildFullInsightsReport(all, llmFn, locale) {
277
+ const reportLanguage = inferObservedReportLanguage(all, locale);
278
+ const reportLocale = reportLanguage.code;
279
+ const p = PROMPTS[reportLocale] ?? PROMPTS.en;
280
+ const { patterns, struggles } = buildPatternsAndStruggles(all.facets);
281
+ const sortLessons = [...all.lessons].sort((a, b) => b.importance * (b.accessCount + 1) - a.importance * (a.accessCount + 1));
282
+ const topLessons = sortLessons.slice(0, 10);
283
+ const charts = [];
284
+ const toolsChart = aggregateTools(all.episodes);
285
+ let aggregateToolCount = 0;
286
+ for (const r of toolsChart.rows)
287
+ aggregateToolCount += r.value;
288
+ if (toolsChart.rows.length > 0)
289
+ charts.push({ ...toolsChart, title: p.fullInsightsChartTools });
290
+ const langChart = aggregateLanguages(all.episodes);
291
+ let aggregateFileCount = 0;
292
+ for (const r of langChart.rows)
293
+ aggregateFileCount += r.value;
294
+ if (langChart.rows.length > 0)
295
+ charts.push({ ...langChart, title: p.fullInsightsChartLanguages });
296
+ const errChart = aggregateErrors(all.episodes);
297
+ if (errChart.rows.length > 0)
298
+ charts.push({ ...errChart, title: p.fullInsightsChartErrors });
299
+ const projectAreas = buildProjectAreas(all.episodes, all.work);
300
+ const stats = {
301
+ knowledge: all.knowledge.length,
302
+ lessons: all.lessons.length,
303
+ preferences: all.preferences.length,
304
+ facets: all.facets.length,
305
+ episodes: all.episodes.length,
306
+ work: all.work.length,
307
+ totalSessions: all.meta.totalSessions,
308
+ aggregateToolCount,
309
+ aggregateFileCount,
310
+ };
311
+ let atAGlance = fallbackAtAGlance(patterns, struggles, topLessons, reportLocale);
312
+ let projectAreaDescriptions = projectAreas.map((a) => a.description);
313
+ let wins = fallbackWins(struggles, topLessons);
314
+ let frictions = fallbackFrictions(struggles);
315
+ let recommendations = fallbackRecommendations(patterns, struggles, topLessons, reportLocale);
316
+ let { featuresToTry, usagePatterns } = fallbackFeaturesAndPatterns(toolsChart.rows, struggles, reportLocale);
317
+ if (llmFn) {
318
+ try {
319
+ const payload = await generateParallelFullInsightSections({
320
+ locale: reportLocale,
321
+ outputLanguage: reportLanguage.name,
322
+ stats,
323
+ patterns,
324
+ struggles,
325
+ lessons: topLessons,
326
+ projectAreas,
327
+ topTools: toolsChart.rows,
328
+ topLanguages: langChart.rows,
329
+ topErrors: errChart.rows,
330
+ }, llmFn);
331
+ if (payload.atAGlance)
332
+ atAGlance = payload.atAGlance;
333
+ if (Array.isArray(payload.projectAreaDescriptions) && payload.projectAreaDescriptions.length >= projectAreas.length) {
334
+ projectAreaDescriptions = payload.projectAreaDescriptions.slice(0, projectAreas.length);
335
+ }
336
+ if (Array.isArray(payload.wins) && payload.wins.length > 0)
337
+ wins = payload.wins.slice(0, 8);
338
+ if (Array.isArray(payload.frictions) && payload.frictions.length > 0)
339
+ frictions = payload.frictions.slice(0, 8);
340
+ if (Array.isArray(payload.recommendations) && payload.recommendations.length > 0)
341
+ recommendations = payload.recommendations.slice(0, 5);
342
+ if (Array.isArray(payload.featuresToTry) && payload.featuresToTry.length > 0)
343
+ featuresToTry = payload.featuresToTry.slice(0, 6);
344
+ if (Array.isArray(payload.usagePatterns) && payload.usagePatterns.length > 0)
345
+ usagePatterns = payload.usagePatterns.slice(0, 6);
346
+ }
347
+ catch {
348
+ // keep fallbacks
349
+ }
350
+ }
351
+ const projectAreasWithDesc = projectAreas.map((a, i) => ({
352
+ ...a,
353
+ description: projectAreaDescriptions[i] ?? a.description,
354
+ }));
355
+ return {
356
+ stats,
357
+ atAGlance,
358
+ projectAreas: projectAreasWithDesc,
359
+ charts,
360
+ wins,
361
+ frictions,
362
+ patterns,
363
+ recommendations,
364
+ featuresToTry,
365
+ usagePatterns,
366
+ generatedAt: new Date().toISOString(),
367
+ locale: reportLocale,
368
+ };
369
+ }
370
+ //# sourceMappingURL=full-insights.js.map