@pencil-agent/nano-mem 0.0.1
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/CLAUDE.md +258 -0
- package/README.md +146 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +90 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +48 -0
- package/dist/config.js.map +1 -0
- package/dist/consolidation.d.ts +13 -0
- package/dist/consolidation.d.ts.map +1 -0
- package/dist/consolidation.js +111 -0
- package/dist/consolidation.js.map +1 -0
- package/dist/engine.d.ts +67 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +492 -0
- package/dist/engine.js.map +1 -0
- package/dist/eviction.d.ts +16 -0
- package/dist/eviction.d.ts.map +1 -0
- package/dist/eviction.js +22 -0
- package/dist/eviction.js.map +1 -0
- package/dist/extension.d.ts +11 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +264 -0
- package/dist/extension.js.map +1 -0
- package/dist/extraction.d.ts +10 -0
- package/dist/extraction.d.ts.map +1 -0
- package/dist/extraction.js +136 -0
- package/dist/extraction.js.map +1 -0
- package/dist/full-insights-html.d.ts +8 -0
- package/dist/full-insights-html.d.ts.map +1 -0
- package/dist/full-insights-html.js +311 -0
- package/dist/full-insights-html.js.map +1 -0
- package/dist/full-insights.d.ts +21 -0
- package/dist/full-insights.d.ts.map +1 -0
- package/dist/full-insights.js +327 -0
- package/dist/full-insights.js.map +1 -0
- package/dist/i18n.d.ts +50 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +169 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/insights-html.d.ts +8 -0
- package/dist/insights-html.d.ts.map +1 -0
- package/dist/insights-html.js +431 -0
- package/dist/insights-html.js.map +1 -0
- package/dist/linking.d.ts +11 -0
- package/dist/linking.d.ts.map +1 -0
- package/dist/linking.js +40 -0
- package/dist/linking.js.map +1 -0
- package/dist/privacy.d.ts +16 -0
- package/dist/privacy.d.ts.map +1 -0
- package/dist/privacy.js +52 -0
- package/dist/privacy.js.map +1 -0
- package/dist/scoring.d.ts +25 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +63 -0
- package/dist/scoring.js.map +1 -0
- package/dist/store.d.ts +16 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +68 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +191 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/update.d.ts +14 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +126 -0
- package/dist/update.js.map +1 -0
- package/package.json +60 -0
- package/src/cli.ts +99 -0
- package/src/config.ts +72 -0
- package/src/consolidation.ts +127 -0
- package/src/engine.ts +699 -0
- package/src/eviction.ts +30 -0
- package/src/extension.ts +290 -0
- package/src/extraction.ts +152 -0
- package/src/full-insights-html.ts +342 -0
- package/src/full-insights.ts +396 -0
- package/src/i18n.ts +233 -0
- package/src/index.ts +50 -0
- package/src/insights-html.ts +476 -0
- package/src/linking.ts +43 -0
- package/src/privacy.ts +52 -0
- package/src/scoring.ts +94 -0
- package/src/store.ts +84 -0
- package/src/types.ts +209 -0
- package/src/update.ts +141 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [INPUT]: InsightsReport, locale
|
|
3
|
+
* [OUTPUT]: Standalone HTML report
|
|
4
|
+
* [POS]: Pure renderer, no side effects
|
|
5
|
+
*/
|
|
6
|
+
import type { InsightsReport } from "./types.js";
|
|
7
|
+
export declare function renderInsightsHtml(report: InsightsReport, locale: string): string;
|
|
8
|
+
//# sourceMappingURL=insights-html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights-html.d.ts","sourceRoot":"","sources":["../src/insights-html.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAgD,MAAM,YAAY,CAAC;AAgS/F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAoLjF"}
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [INPUT]: InsightsReport, locale
|
|
3
|
+
* [OUTPUT]: Standalone HTML report
|
|
4
|
+
* [POS]: Pure renderer, no side effects
|
|
5
|
+
*/
|
|
6
|
+
import { PROMPTS } from "./i18n.js";
|
|
7
|
+
const UI = {
|
|
8
|
+
en: {
|
|
9
|
+
subtitle: "sessions analyzed",
|
|
10
|
+
atAGlance: "At a Glance",
|
|
11
|
+
whatsWorking: "What's Working",
|
|
12
|
+
whatsHindering: "What's Hindering",
|
|
13
|
+
quickWins: "Quick Wins",
|
|
14
|
+
focusArea: "Focus Area",
|
|
15
|
+
noneYet: "No strong signal yet.",
|
|
16
|
+
workOn: "What You Work On",
|
|
17
|
+
workOnIntro: "Top project areas inferred from your memory graph.",
|
|
18
|
+
sessionWord: "sessions",
|
|
19
|
+
distribution: "Focus Distribution",
|
|
20
|
+
topProjects: "Top Projects",
|
|
21
|
+
frequentTags: "Frequent Tags",
|
|
22
|
+
successes: "Impressive Things You Solved",
|
|
23
|
+
successesIntro: "Resolved struggles and high-value lessons worth repeating.",
|
|
24
|
+
frictions: "Where Things Still Go Wrong",
|
|
25
|
+
frictionsIntro: "Open struggles that are still costing time.",
|
|
26
|
+
details: "Details",
|
|
27
|
+
weight: "Weight",
|
|
28
|
+
access: "Access",
|
|
29
|
+
importance: "Importance",
|
|
30
|
+
attempts: "Attempts",
|
|
31
|
+
solution: "Solution",
|
|
32
|
+
status: "Status",
|
|
33
|
+
resolved: "resolved",
|
|
34
|
+
unresolved: "open",
|
|
35
|
+
knowledgePrefs: "Knowledge and Preferences",
|
|
36
|
+
lessons: "Top Lessons",
|
|
37
|
+
knowledge: "Knowledge Base",
|
|
38
|
+
preferences: "User Preferences",
|
|
39
|
+
generatedBy: "Generated by NanoMem",
|
|
40
|
+
},
|
|
41
|
+
zh: {
|
|
42
|
+
subtitle: "已分析会话",
|
|
43
|
+
atAGlance: "总览",
|
|
44
|
+
whatsWorking: "做得好的地方",
|
|
45
|
+
whatsHindering: "当前阻碍",
|
|
46
|
+
quickWins: "快速改进",
|
|
47
|
+
focusArea: "主要方向",
|
|
48
|
+
noneYet: "暂时没有明显信号。",
|
|
49
|
+
workOn: "你在做什么",
|
|
50
|
+
workOnIntro: "基于记忆图谱推断的项目重点领域。",
|
|
51
|
+
sessionWord: "次会话",
|
|
52
|
+
distribution: "关注分布",
|
|
53
|
+
topProjects: "主要项目",
|
|
54
|
+
frequentTags: "高频标签",
|
|
55
|
+
successes: "你解决得很好的事",
|
|
56
|
+
successesIntro: "已解决问题与高价值经验,建议重复复用。",
|
|
57
|
+
frictions: "仍在反复消耗的点",
|
|
58
|
+
frictionsIntro: "尚未关闭的问题,持续影响效率。",
|
|
59
|
+
details: "详情",
|
|
60
|
+
weight: "权重",
|
|
61
|
+
access: "访问",
|
|
62
|
+
importance: "重要度",
|
|
63
|
+
attempts: "尝试",
|
|
64
|
+
solution: "解法",
|
|
65
|
+
status: "状态",
|
|
66
|
+
resolved: "已解决",
|
|
67
|
+
unresolved: "待处理",
|
|
68
|
+
knowledgePrefs: "知识与偏好",
|
|
69
|
+
lessons: "关键经验",
|
|
70
|
+
knowledge: "知识库",
|
|
71
|
+
preferences: "用户偏好",
|
|
72
|
+
generatedBy: "由 NanoMem 自动生成",
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
function escapeHtml(str) {
|
|
76
|
+
return str
|
|
77
|
+
.replace(/&/g, "&")
|
|
78
|
+
.replace(/</g, "<")
|
|
79
|
+
.replace(/>/g, ">")
|
|
80
|
+
.replace(/"/g, """)
|
|
81
|
+
.replace(/'/g, "'");
|
|
82
|
+
}
|
|
83
|
+
function formatDate(iso, locale) {
|
|
84
|
+
const d = new Date(iso);
|
|
85
|
+
if (Number.isNaN(d.getTime()))
|
|
86
|
+
return iso;
|
|
87
|
+
return d.toLocaleString(locale === "zh" ? "zh-CN" : "en-US");
|
|
88
|
+
}
|
|
89
|
+
function dedupeById(entries) {
|
|
90
|
+
const map = new Map();
|
|
91
|
+
for (const entry of entries)
|
|
92
|
+
map.set(entry.id, entry);
|
|
93
|
+
return [...map.values()];
|
|
94
|
+
}
|
|
95
|
+
function topTags(entries, limit = 8) {
|
|
96
|
+
const counts = new Map();
|
|
97
|
+
for (const entry of entries) {
|
|
98
|
+
for (const tag of entry.tags ?? [])
|
|
99
|
+
counts.set(tag, (counts.get(tag) ?? 0) + 1);
|
|
100
|
+
}
|
|
101
|
+
return [...counts.entries()]
|
|
102
|
+
.map(([label, value]) => ({ label, value }))
|
|
103
|
+
.sort((a, b) => b.value - a.value)
|
|
104
|
+
.slice(0, limit);
|
|
105
|
+
}
|
|
106
|
+
function topProjects(entries, limit = 6) {
|
|
107
|
+
const counts = new Map();
|
|
108
|
+
for (const entry of entries) {
|
|
109
|
+
if (!entry.project)
|
|
110
|
+
continue;
|
|
111
|
+
counts.set(entry.project, (counts.get(entry.project) ?? 0) + 1);
|
|
112
|
+
}
|
|
113
|
+
return [...counts.entries()]
|
|
114
|
+
.map(([label, value]) => ({ label, value }))
|
|
115
|
+
.sort((a, b) => b.value - a.value)
|
|
116
|
+
.slice(0, limit);
|
|
117
|
+
}
|
|
118
|
+
function renderBarRows(rows, colorClass, empty) {
|
|
119
|
+
if (!rows.length)
|
|
120
|
+
return `<p class="empty">${escapeHtml(empty)}</p>`;
|
|
121
|
+
const max = Math.max(...rows.map((row) => row.value), 1);
|
|
122
|
+
return rows
|
|
123
|
+
.map((row) => {
|
|
124
|
+
const width = Math.max(8, Math.round((row.value / max) * 100));
|
|
125
|
+
return `<div class="bar-row">
|
|
126
|
+
<div class="bar-label" title="${escapeHtml(row.label)}">${escapeHtml(row.label)}</div>
|
|
127
|
+
<div class="bar-track"><div class="bar-fill ${colorClass}" style="width:${width}%"></div></div>
|
|
128
|
+
<div class="bar-value">${row.value}</div>
|
|
129
|
+
</div>`;
|
|
130
|
+
})
|
|
131
|
+
.join("");
|
|
132
|
+
}
|
|
133
|
+
function renderProjectAreas(projects, entries, ui) {
|
|
134
|
+
if (!projects.length)
|
|
135
|
+
return `<p class="empty">${escapeHtml(ui.noneYet)}</p>`;
|
|
136
|
+
return projects
|
|
137
|
+
.map((project) => {
|
|
138
|
+
const scopeEntries = entries.filter((entry) => entry.project === project.label);
|
|
139
|
+
const tags = topTags(scopeEntries, 4).map((item) => item.label);
|
|
140
|
+
const desc = tags.length > 0
|
|
141
|
+
? `Top signals: ${tags.map((tag) => `#${escapeHtml(tag)}`).join(" ")}`
|
|
142
|
+
: "No dominant tag signal yet.";
|
|
143
|
+
return `<article class="project-area">
|
|
144
|
+
<div class="area-header">
|
|
145
|
+
<span class="area-name">${escapeHtml(project.label)}</span>
|
|
146
|
+
<span class="area-count">~${project.value} ${escapeHtml(ui.sessionWord)}</span>
|
|
147
|
+
</div>
|
|
148
|
+
<p class="area-desc">${desc}</p>
|
|
149
|
+
</article>`;
|
|
150
|
+
})
|
|
151
|
+
.join("");
|
|
152
|
+
}
|
|
153
|
+
function renderPatternRows(patterns, ui) {
|
|
154
|
+
if (!patterns.length)
|
|
155
|
+
return `<p class="empty">${escapeHtml(ui.noneYet)}</p>`;
|
|
156
|
+
const maxWeight = Math.max(...patterns.map((item) => item.weight), 1);
|
|
157
|
+
return patterns
|
|
158
|
+
.slice(0, 12)
|
|
159
|
+
.map((item) => {
|
|
160
|
+
const width = Math.max(8, Math.round((item.weight / maxWeight) * 100));
|
|
161
|
+
return `<article class="item-card">
|
|
162
|
+
<div class="item-title"><strong>${escapeHtml(item.trigger)}</strong> <span class="arrow">-></span> ${escapeHtml(item.behavior)}</div>
|
|
163
|
+
<div class="weight-track"><div class="weight-fill" style="width:${width}%"></div></div>
|
|
164
|
+
<div class="meta-row">
|
|
165
|
+
<span>${escapeHtml(ui.weight)}: ${item.weight.toFixed(2)}</span>
|
|
166
|
+
<span>${escapeHtml(ui.access)}: ${item.entry.accessCount}</span>
|
|
167
|
+
<span>${escapeHtml(ui.importance)}: ${item.entry.importance}</span>
|
|
168
|
+
</div>
|
|
169
|
+
</article>`;
|
|
170
|
+
})
|
|
171
|
+
.join("");
|
|
172
|
+
}
|
|
173
|
+
function renderStruggleRows(struggles, ui) {
|
|
174
|
+
if (!struggles.length)
|
|
175
|
+
return `<p class="empty">${escapeHtml(ui.noneYet)}</p>`;
|
|
176
|
+
return struggles
|
|
177
|
+
.slice(0, 12)
|
|
178
|
+
.map((item) => {
|
|
179
|
+
const attempts = item.attempts.length
|
|
180
|
+
? `<div class="sub-line"><strong>${escapeHtml(ui.attempts)}:</strong> ${item.attempts.map((a) => escapeHtml(a)).join(" | ")}</div>`
|
|
181
|
+
: "";
|
|
182
|
+
const solution = item.solution
|
|
183
|
+
? `<div class="sub-line"><strong>${escapeHtml(ui.solution)}:</strong> ${escapeHtml(item.solution)}</div>`
|
|
184
|
+
: "";
|
|
185
|
+
return `<article class="item-card ${item.resolved ? "ok" : "warn"}">
|
|
186
|
+
<div class="item-title">${escapeHtml(item.problem)}</div>
|
|
187
|
+
${attempts}
|
|
188
|
+
${solution}
|
|
189
|
+
<div class="meta-row">
|
|
190
|
+
<span>${escapeHtml(ui.status)}: ${item.resolved ? escapeHtml(ui.resolved) : escapeHtml(ui.unresolved)}</span>
|
|
191
|
+
<span>${escapeHtml(ui.weight)}: ${item.weight.toFixed(2)}</span>
|
|
192
|
+
</div>
|
|
193
|
+
</article>`;
|
|
194
|
+
})
|
|
195
|
+
.join("");
|
|
196
|
+
}
|
|
197
|
+
function renderMemoryList(entries, empty) {
|
|
198
|
+
if (!entries.length)
|
|
199
|
+
return `<p class="empty">${escapeHtml(empty)}</p>`;
|
|
200
|
+
return `<ul class="list">${entries
|
|
201
|
+
.map((entry) => `<li>${escapeHtml(entry.content)}${entry.tags.length ? ` <span class="tags">${entry.tags.slice(0, 4).map((tag) => `#${escapeHtml(tag)}`).join(" ")}</span>` : ""}</li>`)
|
|
202
|
+
.join("")}</ul>`;
|
|
203
|
+
}
|
|
204
|
+
function renderAtAGlance(report, projects, ui) {
|
|
205
|
+
const unresolved = report.struggles.filter((item) => !item.resolved);
|
|
206
|
+
const resolved = report.struggles.filter((item) => item.resolved);
|
|
207
|
+
const topPattern = report.patterns[0];
|
|
208
|
+
const topRec = report.recommendations[0];
|
|
209
|
+
const topProject = projects[0];
|
|
210
|
+
const working = resolved.length > 0
|
|
211
|
+
? `${resolved.length} struggles are already resolved; keep reusing those fixes.`
|
|
212
|
+
: report.topLessons.length
|
|
213
|
+
? `${report.topLessons.length} lessons captured; convert the top ones into repeatable checklists.`
|
|
214
|
+
: ui.noneYet;
|
|
215
|
+
const hindering = unresolved.length
|
|
216
|
+
? `${unresolved.length} open struggles remain. Most frequent: "${unresolved[0]?.problem ?? ""}".`
|
|
217
|
+
: "No unresolved struggles currently visible.";
|
|
218
|
+
const quickWins = topRec ? topRec : ui.noneYet;
|
|
219
|
+
const focus = topProject
|
|
220
|
+
? `${topProject.label} appears most often (${topProject.value} memories).`
|
|
221
|
+
: topPattern
|
|
222
|
+
? `Dominant behavior: when "${topPattern.trigger}", you often "${topPattern.behavior}".`
|
|
223
|
+
: ui.noneYet;
|
|
224
|
+
return `<section class="glance">
|
|
225
|
+
<h2>${escapeHtml(ui.atAGlance)}</h2>
|
|
226
|
+
<div class="glance-grid">
|
|
227
|
+
<article class="glance-card">
|
|
228
|
+
<h3>${escapeHtml(ui.whatsWorking)}</h3>
|
|
229
|
+
<p>${escapeHtml(working)}</p>
|
|
230
|
+
</article>
|
|
231
|
+
<article class="glance-card warn">
|
|
232
|
+
<h3>${escapeHtml(ui.whatsHindering)}</h3>
|
|
233
|
+
<p>${escapeHtml(hindering)}</p>
|
|
234
|
+
</article>
|
|
235
|
+
<article class="glance-card">
|
|
236
|
+
<h3>${escapeHtml(ui.quickWins)}</h3>
|
|
237
|
+
<p>${escapeHtml(quickWins)}</p>
|
|
238
|
+
</article>
|
|
239
|
+
<article class="glance-card">
|
|
240
|
+
<h3>${escapeHtml(ui.focusArea)}</h3>
|
|
241
|
+
<p>${escapeHtml(focus)}</p>
|
|
242
|
+
</article>
|
|
243
|
+
</div>
|
|
244
|
+
</section>`;
|
|
245
|
+
}
|
|
246
|
+
function renderRecommendations(report, title, empty) {
|
|
247
|
+
if (!report.recommendations.length)
|
|
248
|
+
return `<section class="section"><h2>${escapeHtml(title)}</h2><p class="empty">${escapeHtml(empty)}</p></section>`;
|
|
249
|
+
return `<section id="section-recommendations" class="section">
|
|
250
|
+
<h2>${escapeHtml(title)}</h2>
|
|
251
|
+
<ul class="recommend-list">${report.recommendations.map((rec) => `<li>${escapeHtml(rec)}</li>`).join("")}</ul>
|
|
252
|
+
</section>`;
|
|
253
|
+
}
|
|
254
|
+
export function renderInsightsHtml(report, locale) {
|
|
255
|
+
const isZh = locale === "zh";
|
|
256
|
+
const ui = UI[isZh ? "zh" : "en"];
|
|
257
|
+
const prompts = PROMPTS[locale] ?? PROMPTS.en;
|
|
258
|
+
const allEntries = dedupeById([...report.topKnowledge, ...report.topLessons, ...report.preferences]);
|
|
259
|
+
const projects = topProjects(allEntries);
|
|
260
|
+
const tags = topTags(allEntries);
|
|
261
|
+
const unresolved = report.struggles.filter((item) => !item.resolved);
|
|
262
|
+
const resolved = report.struggles.filter((item) => item.resolved);
|
|
263
|
+
const statsRow = [
|
|
264
|
+
{ label: "Sessions", value: report.stats.totalSessions },
|
|
265
|
+
{ label: "Knowledge", value: report.stats.knowledge },
|
|
266
|
+
{ label: "Lessons", value: report.stats.lessons },
|
|
267
|
+
{ label: "Preferences", value: report.stats.preferences },
|
|
268
|
+
{ label: "Struggles", value: report.struggles.length },
|
|
269
|
+
{ label: "Patterns", value: report.patterns.length },
|
|
270
|
+
];
|
|
271
|
+
const css = `
|
|
272
|
+
*{box-sizing:border-box}
|
|
273
|
+
body{margin:0;padding:48px 24px;font-family:Inter,"Segoe UI",Arial,sans-serif;background:#f8fafc;color:#334155;line-height:1.65}
|
|
274
|
+
.container{max-width:960px;margin:0 auto}
|
|
275
|
+
h1{font-size:34px;font-weight:700;color:#0f172a;margin:0 0 8px}
|
|
276
|
+
h2{font-size:22px;font-weight:700;color:#0f172a;margin:0 0 14px}
|
|
277
|
+
h3{font-size:15px;font-weight:700;color:#1e293b;margin:0 0 8px}
|
|
278
|
+
.subtitle{color:#64748b;font-size:14px;margin:0 0 24px}
|
|
279
|
+
.toc{display:flex;flex-wrap:wrap;gap:8px;padding:14px;background:#fff;border:1px solid #e2e8f0;border-radius:10px;margin:0 0 24px}
|
|
280
|
+
.toc a{font-size:12px;color:#475569;background:#f1f5f9;border-radius:6px;padding:6px 10px;text-decoration:none}
|
|
281
|
+
.toc a:hover{background:#e2e8f0}
|
|
282
|
+
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px;padding:20px 0;border-top:1px solid #e2e8f0;border-bottom:1px solid #e2e8f0;margin:0 0 28px}
|
|
283
|
+
.stat{text-align:center}
|
|
284
|
+
.stat-value{font-size:24px;font-weight:700;color:#0f172a}
|
|
285
|
+
.stat-label{font-size:11px;color:#64748b;text-transform:uppercase}
|
|
286
|
+
.glance{background:linear-gradient(135deg,#fef3c7 0%,#fde68a 100%);border:1px solid #f59e0b;border-radius:12px;padding:20px 22px;margin:0 0 28px}
|
|
287
|
+
.glance-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px}
|
|
288
|
+
.glance-card{background:rgba(255,255,255,.62);border:1px solid rgba(245,158,11,.28);border-radius:8px;padding:12px}
|
|
289
|
+
.glance-card.warn{background:rgba(255,241,242,.82);border-color:#fca5a5}
|
|
290
|
+
.glance-card p{margin:0;font-size:13px;color:#78350f}
|
|
291
|
+
.section{background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:18px;margin:0 0 16px}
|
|
292
|
+
.section-intro{font-size:13px;color:#64748b;margin:0 0 12px}
|
|
293
|
+
.project-list{display:flex;flex-direction:column;gap:10px}
|
|
294
|
+
.project-area{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:14px}
|
|
295
|
+
.area-header{display:flex;justify-content:space-between;align-items:center;gap:10px}
|
|
296
|
+
.area-name{font-size:15px;font-weight:700;color:#0f172a}
|
|
297
|
+
.area-count{font-size:12px;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:4px}
|
|
298
|
+
.area-desc{margin:8px 0 0;font-size:13px;color:#475569}
|
|
299
|
+
.charts{display:grid;grid-template-columns:1fr 1fr;gap:16px}
|
|
300
|
+
.chart{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:14px}
|
|
301
|
+
.chart-title{font-size:12px;color:#64748b;text-transform:uppercase;margin:0 0 10px}
|
|
302
|
+
.bar-row{display:flex;align-items:center;gap:8px;margin-bottom:7px}
|
|
303
|
+
.bar-label{width:120px;flex-shrink:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;color:#475569}
|
|
304
|
+
.bar-track{flex:1;height:7px;background:#f1f5f9;border-radius:99px}
|
|
305
|
+
.bar-fill{height:100%;border-radius:99px}
|
|
306
|
+
.bar-fill.blue{background:#2563eb}
|
|
307
|
+
.bar-fill.cyan{background:#0891b2}
|
|
308
|
+
.bar-value{width:24px;text-align:right;font-size:12px;color:#64748b}
|
|
309
|
+
.recommend-list{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:8px}
|
|
310
|
+
.recommend-list li{background:#f0fdf4;border:1px solid #bbf7d0;border-left:4px solid #16a34a;border-radius:8px;padding:11px 12px;font-size:14px}
|
|
311
|
+
.item-grid{display:flex;flex-direction:column;gap:10px}
|
|
312
|
+
.item-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:12px}
|
|
313
|
+
.item-card.ok{background:#f0fdf4;border-color:#86efac}
|
|
314
|
+
.item-card.warn{background:#fef2f2;border-color:#fca5a5}
|
|
315
|
+
.item-title{font-size:14px;color:#0f172a}
|
|
316
|
+
.arrow{color:#94a3b8}
|
|
317
|
+
.weight-track{margin-top:8px;height:6px;background:#e2e8f0;border-radius:99px}
|
|
318
|
+
.weight-fill{height:100%;background:#2563eb;border-radius:99px}
|
|
319
|
+
.sub-line{margin-top:8px;font-size:13px;color:#334155}
|
|
320
|
+
.meta-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:8px;font-size:12px;color:#64748b}
|
|
321
|
+
details{border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;padding:10px 12px;margin-bottom:10px}
|
|
322
|
+
summary{cursor:pointer;font-size:14px;font-weight:700;color:#334155}
|
|
323
|
+
.list{margin:10px 0 0;padding-left:18px}
|
|
324
|
+
.list li{margin:0 0 8px;font-size:13px;color:#334155}
|
|
325
|
+
.tags{font-size:12px;color:#64748b}
|
|
326
|
+
.empty{font-size:13px;color:#94a3b8}
|
|
327
|
+
footer{margin-top:22px;text-align:center;font-size:12px;color:#94a3b8}
|
|
328
|
+
@media (max-width:760px){body{padding:28px 14px}.charts{grid-template-columns:1fr}.bar-label{width:96px}}
|
|
329
|
+
`;
|
|
330
|
+
return `<!doctype html>
|
|
331
|
+
<html lang="${isZh ? "zh-CN" : "en"}">
|
|
332
|
+
<head>
|
|
333
|
+
<meta charset="utf-8" />
|
|
334
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
335
|
+
<title>${escapeHtml(prompts.insightsTitle)}</title>
|
|
336
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
337
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
338
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
339
|
+
<style>${css}</style>
|
|
340
|
+
</head>
|
|
341
|
+
<body>
|
|
342
|
+
<main class="container">
|
|
343
|
+
<h1>${escapeHtml(prompts.insightsTitle)}</h1>
|
|
344
|
+
<p class="subtitle">${report.stats.totalSessions} ${escapeHtml(ui.subtitle)} | ${escapeHtml(prompts.insightsGeneratedAt)}: ${escapeHtml(formatDate(report.generatedAt, locale))}</p>
|
|
345
|
+
|
|
346
|
+
<nav class="toc">
|
|
347
|
+
<a href="#section-work">${escapeHtml(ui.workOn)}</a>
|
|
348
|
+
<a href="#section-distribution">${escapeHtml(ui.distribution)}</a>
|
|
349
|
+
<a href="#section-recommendations">${escapeHtml(prompts.insightsSectionRecommendations)}</a>
|
|
350
|
+
<a href="#section-patterns">${escapeHtml(prompts.insightsSectionPatterns)}</a>
|
|
351
|
+
<a href="#section-struggles">${escapeHtml(prompts.insightsSectionStruggles)}</a>
|
|
352
|
+
<a href="#section-memory">${escapeHtml(ui.knowledgePrefs)}</a>
|
|
353
|
+
</nav>
|
|
354
|
+
|
|
355
|
+
<section class="stats">
|
|
356
|
+
${statsRow
|
|
357
|
+
.map((item) => `<div class="stat"><div class="stat-value">${item.value}</div><div class="stat-label">${escapeHtml(item.label)}</div></div>`)
|
|
358
|
+
.join("")}
|
|
359
|
+
</section>
|
|
360
|
+
|
|
361
|
+
${renderAtAGlance(report, projects, ui)}
|
|
362
|
+
|
|
363
|
+
<section id="section-work" class="section">
|
|
364
|
+
<h2>${escapeHtml(ui.workOn)}</h2>
|
|
365
|
+
<p class="section-intro">${escapeHtml(ui.workOnIntro)}</p>
|
|
366
|
+
<div class="project-list">${renderProjectAreas(projects, allEntries, ui)}</div>
|
|
367
|
+
</section>
|
|
368
|
+
|
|
369
|
+
<section id="section-distribution" class="section">
|
|
370
|
+
<h2>${escapeHtml(ui.distribution)}</h2>
|
|
371
|
+
<div class="charts">
|
|
372
|
+
<div class="chart">
|
|
373
|
+
<p class="chart-title">${escapeHtml(ui.topProjects)}</p>
|
|
374
|
+
${renderBarRows(projects, "blue", ui.noneYet)}
|
|
375
|
+
</div>
|
|
376
|
+
<div class="chart">
|
|
377
|
+
<p class="chart-title">${escapeHtml(ui.frequentTags)}</p>
|
|
378
|
+
${renderBarRows(tags, "cyan", ui.noneYet)}
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
</section>
|
|
382
|
+
|
|
383
|
+
${renderRecommendations(report, prompts.insightsSectionRecommendations, prompts.insightsNoData)}
|
|
384
|
+
|
|
385
|
+
<section class="section">
|
|
386
|
+
<h2>${escapeHtml(ui.successes)}</h2>
|
|
387
|
+
<p class="section-intro">${escapeHtml(ui.successesIntro)}</p>
|
|
388
|
+
<div class="item-grid">
|
|
389
|
+
${renderStruggleRows(resolved, ui)}
|
|
390
|
+
${renderMemoryList(report.topLessons.slice(0, 5), ui.noneYet)}
|
|
391
|
+
</div>
|
|
392
|
+
</section>
|
|
393
|
+
|
|
394
|
+
<section class="section">
|
|
395
|
+
<h2>${escapeHtml(ui.frictions)}</h2>
|
|
396
|
+
<p class="section-intro">${escapeHtml(ui.frictionsIntro)}</p>
|
|
397
|
+
<div class="item-grid">${renderStruggleRows(unresolved, ui)}</div>
|
|
398
|
+
</section>
|
|
399
|
+
|
|
400
|
+
<section id="section-patterns" class="section">
|
|
401
|
+
<h2>${escapeHtml(prompts.insightsSectionPatterns)}</h2>
|
|
402
|
+
<div class="item-grid">${renderPatternRows(report.patterns, ui)}</div>
|
|
403
|
+
</section>
|
|
404
|
+
|
|
405
|
+
<section id="section-struggles" class="section">
|
|
406
|
+
<h2>${escapeHtml(prompts.insightsSectionStruggles)}</h2>
|
|
407
|
+
<div class="item-grid">${renderStruggleRows(report.struggles, ui)}</div>
|
|
408
|
+
</section>
|
|
409
|
+
|
|
410
|
+
<section id="section-memory" class="section">
|
|
411
|
+
<h2>${escapeHtml(ui.knowledgePrefs)}</h2>
|
|
412
|
+
<details open>
|
|
413
|
+
<summary>${escapeHtml(ui.lessons)} (${report.topLessons.length})</summary>
|
|
414
|
+
${renderMemoryList(report.topLessons.slice(0, 12), ui.noneYet)}
|
|
415
|
+
</details>
|
|
416
|
+
<details>
|
|
417
|
+
<summary>${escapeHtml(ui.knowledge)} (${report.topKnowledge.length})</summary>
|
|
418
|
+
${renderMemoryList(report.topKnowledge.slice(0, 12), ui.noneYet)}
|
|
419
|
+
</details>
|
|
420
|
+
<details>
|
|
421
|
+
<summary>${escapeHtml(ui.preferences)} (${report.preferences.length})</summary>
|
|
422
|
+
${renderMemoryList(report.preferences.slice(0, 12), ui.noneYet)}
|
|
423
|
+
</details>
|
|
424
|
+
</section>
|
|
425
|
+
|
|
426
|
+
<footer>${escapeHtml(ui.generatedBy)}</footer>
|
|
427
|
+
</main>
|
|
428
|
+
</body>
|
|
429
|
+
</html>`;
|
|
430
|
+
}
|
|
431
|
+
//# sourceMappingURL=insights-html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights-html.js","sourceRoot":"","sources":["../src/insights-html.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqCpC,MAAM,EAAE,GAAgC;IACvC,EAAE,EAAE;QACH,QAAQ,EAAE,mBAAmB;QAC7B,SAAS,EAAE,aAAa;QACxB,YAAY,EAAE,gBAAgB;QAC9B,cAAc,EAAE,kBAAkB;QAClC,SAAS,EAAE,YAAY;QACvB,SAAS,EAAE,YAAY;QACvB,OAAO,EAAE,uBAAuB;QAChC,MAAM,EAAE,kBAAkB;QAC1B,WAAW,EAAE,oDAAoD;QACjE,WAAW,EAAE,UAAU;QACvB,YAAY,EAAE,oBAAoB;QAClC,WAAW,EAAE,cAAc;QAC3B,YAAY,EAAE,eAAe;QAC7B,SAAS,EAAE,8BAA8B;QACzC,cAAc,EAAE,4DAA4D;QAC5E,SAAS,EAAE,6BAA6B;QACxC,cAAc,EAAE,6CAA6C;QAC7D,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,YAAY;QACxB,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,UAAU;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,UAAU;QACpB,UAAU,EAAE,MAAM;QAClB,cAAc,EAAE,2BAA2B;QAC3C,OAAO,EAAE,aAAa;QACtB,SAAS,EAAE,gBAAgB;QAC3B,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE,sBAAsB;KACnC;IACD,EAAE,EAAE;QACH,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,QAAQ;QACtB,cAAc,EAAE,MAAM;QACtB,SAAS,EAAE,MAAM;QACjB,SAAS,EAAE,MAAM;QACjB,OAAO,EAAE,WAAW;QACpB,MAAM,EAAE,OAAO;QACf,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE,KAAK;QAClB,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,MAAM;QACnB,YAAY,EAAE,MAAM;QACpB,SAAS,EAAE,UAAU;QACrB,cAAc,EAAE,qBAAqB;QACrC,SAAS,EAAE,UAAU;QACrB,cAAc,EAAE,iBAAiB;QACjC,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI;QACZ,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,KAAK;QACf,UAAU,EAAE,KAAK;QACjB,cAAc,EAAE,OAAO;QACvB,OAAO,EAAE,MAAM;QACf,SAAS,EAAE,KAAK;QAChB,WAAW,EAAE,MAAM;QACnB,WAAW,EAAE,gBAAgB;KAC7B;CACD,CAAC;AAEF,SAAS,UAAU,CAAC,GAAW;IAC9B,OAAO,GAAG;SACR,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,MAAc;IAC9C,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,GAAG,CAAC;IAC1C,OAAO,CAAC,CAAC,cAAc,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,UAAU,CAAC,OAAsB;IACzC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3C,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,OAAO,CAAC,OAAsB,EAAE,KAAK,GAAG,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,IAAI,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;SAC3C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,WAAW,CAAC,OAAsB,EAAE,KAAK,GAAG,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,SAAS;QAC7B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;SAC3C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,IAA6C,EAAE,UAAkB,EAAE,KAAa;IACtG,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,oBAAoB,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;IACrE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,OAAO,IAAI;SACT,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC/D,OAAO;kCACwB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;gDACjC,UAAU,kBAAkB,KAAK;2BACtD,GAAG,CAAC,KAAK;OAC7B,CAAC;IACN,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAiD,EAAE,OAAsB,EAAE,EAAU;IAChH,IAAI,CAAC,QAAQ,CAAC,MAAM;QAAE,OAAO,oBAAoB,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAC9E,OAAO,QAAQ;SACb,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAChB,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;QAChF,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChE,MAAM,IAAI,GACT,IAAI,CAAC,MAAM,GAAG,CAAC;YACd,CAAC,CAAC,gBAAgB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YACtE,CAAC,CAAC,6BAA6B,CAAC;QAClC,OAAO;;8BAEoB,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;gCACvB,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC;;yBAElD,IAAI;WAClB,CAAC;IACV,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AAED,SAAS,iBAAiB,CAAC,QAA0B,EAAE,EAAU;IAChE,IAAI,CAAC,QAAQ,CAAC,MAAM;QAAE,OAAO,oBAAoB,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAC9E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,OAAO,QAAQ;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACvE,OAAO;oCAC0B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,2CAA2C,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;oEAC5D,KAAK;;YAE7D,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAChD,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW;YAChD,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU;;WAEpD,CAAC;IACV,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AAED,SAAS,kBAAkB,CAAC,SAA4B,EAAE,EAAU;IACnE,IAAI,CAAC,SAAS,CAAC,MAAM;QAAE,OAAO,oBAAoB,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAC/E,OAAO,SAAS;SACd,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACb,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM;YACpC,CAAC,CAAC,iCAAiC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,cAAc,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ;YACnI,CAAC,CAAC,EAAE,CAAC;QACN,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ;YAC7B,CAAC,CAAC,iCAAiC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,cAAc,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ;YACzG,CAAC,CAAC,EAAE,CAAC;QACN,OAAO,6BAA6B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;4BACxC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;IAChD,QAAQ;IACR,QAAQ;;YAEA,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC;YAC7F,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;;WAEjD,CAAC;IACV,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAsB,EAAE,KAAa;IAC9D,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,oBAAoB,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;IACxE,OAAO,oBAAoB,OAAO;SAChC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,uBAAuB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;SACvL,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,MAAsB,EAAE,QAAiD,EAAE,EAAU;IAC7G,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrE,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClE,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,OAAO,GACZ,QAAQ,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,4DAA4D;QAChF,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM;YACzB,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,qEAAqE;YAClG,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;IAChB,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM;QAClC,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,2CAA2C,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,IAAI;QACjG,CAAC,CAAC,4CAA4C,CAAC;IAChD,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;IAC/C,MAAM,KAAK,GAAG,UAAU;QACvB,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,wBAAwB,UAAU,CAAC,KAAK,aAAa;QAC1E,CAAC,CAAC,UAAU;YACX,CAAC,CAAC,4BAA4B,UAAU,CAAC,OAAO,iBAAiB,UAAU,CAAC,QAAQ,IAAI;YACxF,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;IACf,OAAO;QACA,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC;;;YAGpB,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC;WAC5B,UAAU,CAAC,OAAO,CAAC;;;YAGlB,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC;WAC9B,UAAU,CAAC,SAAS,CAAC;;;YAGpB,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC;WACzB,UAAU,CAAC,SAAS,CAAC;;;YAGpB,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC;WACzB,UAAU,CAAC,KAAK,CAAC;;;WAGjB,CAAC;AACZ,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAsB,EAAE,KAAa,EAAE,KAAa;IAClF,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM;QAAE,OAAO,gCAAgC,UAAU,CAAC,KAAK,CAAC,yBAAyB,UAAU,CAAC,KAAK,CAAC,gBAAgB,CAAC;IACvJ,OAAO;QACA,UAAU,CAAC,KAAK,CAAC;+BACM,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;WAC/F,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB,EAAE,MAAc;IACxE,MAAM,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7B,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC;IAE9C,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,YAAY,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;IACrG,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACjC,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrE,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAElE,MAAM,QAAQ,GAAG;QAChB,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE;QACxD,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE;QACrD,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;QACjD,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE;QACzD,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE;QACtD,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE;KACpD,CAAC;IAEF,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DZ,CAAC;IAED,OAAO;cACM,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;;;;WAIxB,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC;;;;WAIjC,GAAG;;;;UAIJ,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC;0BACjB,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;;;gCAGnJ,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC;wCACb,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC;2CACxB,UAAU,CAAC,OAAO,CAAC,8BAA8B,CAAC;oCACzD,UAAU,CAAC,OAAO,CAAC,uBAAuB,CAAC;qCAC1C,UAAU,CAAC,OAAO,CAAC,wBAAwB,CAAC;kCAC/C,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC;;;;QAIvD,QAAQ;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,6CAA6C,IAAI,CAAC,KAAK,iCAAiC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;SAC3I,IAAI,CAAC,EAAE,CAAC;;;MAGP,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;;;YAG/B,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC;iCACA,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC;kCACzB,kBAAkB,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,CAAC;;;;YAIlE,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC;;;mCAGJ,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC;YACjD,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC;;;mCAGpB,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC;YAClD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC;;;;;MAK7C,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,8BAA8B,EAAE,OAAO,CAAC,cAAc,CAAC;;;YAGvF,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC;iCACH,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC;;UAEpD,kBAAkB,CAAC,QAAQ,EAAE,EAAE,CAAC;UAChC,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC;;;;;YAKzD,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC;iCACH,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC;+BAC/B,kBAAkB,CAAC,UAAU,EAAE,EAAE,CAAC;;;;YAIrD,UAAU,CAAC,OAAO,CAAC,uBAAuB,CAAC;+BACxB,iBAAiB,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;;;;YAIzD,UAAU,CAAC,OAAO,CAAC,wBAAwB,CAAC;+BACzB,kBAAkB,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;;;;YAI3D,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC;;mBAEtB,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM;UAC5D,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC;;;mBAGnD,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,YAAY,CAAC,MAAM;UAChE,gBAAgB,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC;;;mBAGrD,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,MAAM,CAAC,WAAW,CAAC,MAAM;UACjE,gBAAgB,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC;;;;cAIzD,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC;;;QAGhC,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [INPUT]: new MemoryEntry, existing entries
|
|
3
|
+
* [OUTPUT]: bidirectional relatedIds links established
|
|
4
|
+
* [POS]: A-MEM style Zettelkasten linking — atomic storage + dynamic associations
|
|
5
|
+
*/
|
|
6
|
+
import type { MemoryEntry } from "./types.js";
|
|
7
|
+
/** Find related entries by tag overlap and establish bidirectional links */
|
|
8
|
+
export declare function linkNewEntry(newEntry: MemoryEntry, allEntries: MemoryEntry[]): void;
|
|
9
|
+
/** Get content summaries for related entries (for injection enrichment) */
|
|
10
|
+
export declare function getRelatedSummaries(entry: MemoryEntry, allEntries: MemoryEntry[], maxCount?: number): string[];
|
|
11
|
+
//# sourceMappingURL=linking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linking.d.ts","sourceRoot":"","sources":["../src/linking.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,IAAI,CAmBnF;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,QAAQ,SAAI,GAAG,MAAM,EAAE,CAOzG"}
|
package/dist/linking.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [INPUT]: new MemoryEntry, existing entries
|
|
3
|
+
* [OUTPUT]: bidirectional relatedIds links established
|
|
4
|
+
* [POS]: A-MEM style Zettelkasten linking — atomic storage + dynamic associations
|
|
5
|
+
*/
|
|
6
|
+
import { tagOverlap } from "./scoring.js";
|
|
7
|
+
const LINK_THRESHOLD = 0.5;
|
|
8
|
+
const MAX_LINKS = 5;
|
|
9
|
+
/** Find related entries by tag overlap and establish bidirectional links */
|
|
10
|
+
export function linkNewEntry(newEntry, allEntries) {
|
|
11
|
+
if (!newEntry.relatedIds)
|
|
12
|
+
newEntry.relatedIds = [];
|
|
13
|
+
const candidates = allEntries
|
|
14
|
+
.filter((e) => e.id !== newEntry.id)
|
|
15
|
+
.map((e) => ({ entry: e, overlap: tagOverlap(newEntry.tags, e.tags) }))
|
|
16
|
+
.filter((c) => c.overlap >= LINK_THRESHOLD)
|
|
17
|
+
.sort((a, b) => b.overlap - a.overlap)
|
|
18
|
+
.slice(0, MAX_LINKS);
|
|
19
|
+
for (const { entry } of candidates) {
|
|
20
|
+
if (!newEntry.relatedIds.includes(entry.id)) {
|
|
21
|
+
newEntry.relatedIds.push(entry.id);
|
|
22
|
+
}
|
|
23
|
+
if (!entry.relatedIds)
|
|
24
|
+
entry.relatedIds = [];
|
|
25
|
+
if (!entry.relatedIds.includes(newEntry.id)) {
|
|
26
|
+
entry.relatedIds.push(newEntry.id);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Get content summaries for related entries (for injection enrichment) */
|
|
31
|
+
export function getRelatedSummaries(entry, allEntries, maxCount = 3) {
|
|
32
|
+
if (!entry.relatedIds?.length)
|
|
33
|
+
return [];
|
|
34
|
+
const idSet = new Set(entry.relatedIds);
|
|
35
|
+
return allEntries
|
|
36
|
+
.filter((e) => idSet.has(e.id))
|
|
37
|
+
.slice(0, maxCount)
|
|
38
|
+
.map((e) => e.content.slice(0, 80));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=linking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linking.js","sourceRoot":"","sources":["../src/linking.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,MAAM,SAAS,GAAG,CAAC,CAAC;AAEpB,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,QAAqB,EAAE,UAAyB;IAC5E,IAAI,CAAC,QAAQ,CAAC,UAAU;QAAE,QAAQ,CAAC,UAAU,GAAG,EAAE,CAAC;IAEnD,MAAM,UAAU,GAAG,UAAU;SAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,CAAC;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACtE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,cAAc,CAAC;SAC1C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;SACrC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAEtB,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7C,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,UAAU;YAAE,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7C,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC;IACF,CAAC;AACF,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,mBAAmB,CAAC,KAAkB,EAAE,UAAyB,EAAE,QAAQ,GAAG,CAAC;IAC9F,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM;QAAE,OAAO,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACxC,OAAO,UAAU;SACf,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC9B,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;SAClB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [INPUT]: text content, MemoryEntry with scope/ttl
|
|
3
|
+
* [OUTPUT]: sanitized text, scope-filtered entries, ttl-expired entries removed
|
|
4
|
+
* [POS]: MemoryOps layer — scope isolation, TTL enforcement, PII filtering
|
|
5
|
+
*/
|
|
6
|
+
import type { MemoryEntry, MemoryScope, WorkEntry } from "./types.js";
|
|
7
|
+
export declare function filterPII(text: string): string;
|
|
8
|
+
export declare function matchesScope(entry: {
|
|
9
|
+
scope?: MemoryScope;
|
|
10
|
+
}, required?: MemoryScope): boolean;
|
|
11
|
+
export declare function filterByScope<T extends {
|
|
12
|
+
scope?: MemoryScope;
|
|
13
|
+
}>(entries: T[], scope?: MemoryScope): T[];
|
|
14
|
+
export declare function evictExpiredEntries(entries: MemoryEntry[]): MemoryEntry[];
|
|
15
|
+
export declare function evictExpiredWork(entries: WorkEntry[]): WorkEntry[];
|
|
16
|
+
//# sourceMappingURL=privacy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../src/privacy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAWtE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAM5F;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,CAAC,EAAE,CAGvG;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAKzE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAKlE"}
|
package/dist/privacy.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [INPUT]: text content, MemoryEntry with scope/ttl
|
|
3
|
+
* [OUTPUT]: sanitized text, scope-filtered entries, ttl-expired entries removed
|
|
4
|
+
* [POS]: MemoryOps layer — scope isolation, TTL enforcement, PII filtering
|
|
5
|
+
*/
|
|
6
|
+
import { daysSince } from "./scoring.js";
|
|
7
|
+
const PII_PATTERNS = [
|
|
8
|
+
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, // email
|
|
9
|
+
/\b(?:\+?1[-.]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g, // US phone
|
|
10
|
+
/\b1[3-9]\d{9}\b/g, // CN mobile
|
|
11
|
+
/\b\d{3}-\d{2}-\d{4}\b/g, // US SSN
|
|
12
|
+
/\b[1-9]\d{5}(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dXx]\b/g, // CN ID
|
|
13
|
+
/\b(?:4\d{3}|5[1-5]\d{2}|6011|3[47]\d{2})[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g, // credit card
|
|
14
|
+
];
|
|
15
|
+
export function filterPII(text) {
|
|
16
|
+
let result = text;
|
|
17
|
+
for (const pattern of PII_PATTERNS) {
|
|
18
|
+
result = result.replace(pattern, "[REDACTED]");
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
export function matchesScope(entry, required) {
|
|
23
|
+
if (!required)
|
|
24
|
+
return true;
|
|
25
|
+
if (!entry.scope)
|
|
26
|
+
return true;
|
|
27
|
+
if (required.userId && entry.scope.userId && entry.scope.userId !== required.userId)
|
|
28
|
+
return false;
|
|
29
|
+
if (required.agentId && entry.scope.agentId && entry.scope.agentId !== required.agentId)
|
|
30
|
+
return false;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
export function filterByScope(entries, scope) {
|
|
34
|
+
if (!scope)
|
|
35
|
+
return entries;
|
|
36
|
+
return entries.filter((e) => matchesScope(e, scope));
|
|
37
|
+
}
|
|
38
|
+
export function evictExpiredEntries(entries) {
|
|
39
|
+
return entries.filter((e) => {
|
|
40
|
+
if (e.ttl === undefined)
|
|
41
|
+
return true;
|
|
42
|
+
return daysSince(e.created) < e.ttl;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export function evictExpiredWork(entries) {
|
|
46
|
+
return entries.filter((w) => {
|
|
47
|
+
if (w.ttl === undefined)
|
|
48
|
+
return true;
|
|
49
|
+
return daysSince(w.created) < w.ttl;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=privacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privacy.js","sourceRoot":"","sources":["../src/privacy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,MAAM,YAAY,GAAG;IACpB,sDAAsD,EAAE,QAAQ;IAChE,wDAAwD,EAAE,WAAW;IACrE,kBAAkB,EAAE,YAAY;IAChC,wBAAwB,EAAE,SAAS;IACnC,kFAAkF,EAAE,QAAQ;IAC5F,8EAA8E,EAAE,cAAc;CAC9F,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,IAAY;IACrC,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAA8B,EAAE,QAAsB;IAClF,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,QAAQ,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAClG,IAAI,QAAQ,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IACtG,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAoC,OAAY,EAAE,KAAmB;IACjG,IAAI,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC;IAC3B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAsB;IACzD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;IACrC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACpD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;IACrC,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [INPUT]: MemoryEntry/Episode/WorkEntry, project, context tags, config weights
|
|
3
|
+
* [OUTPUT]: retrieval score (Stanford: Recency + Importance + Relevance)
|
|
4
|
+
* [POS]: Core ranking algorithm — used by engine for injection budget allocation
|
|
5
|
+
*
|
|
6
|
+
* Key innovation: uses per-entry adaptive strength (not global half-life)
|
|
7
|
+
* for Recency, implementing Ebbinghaus spaced repetition.
|
|
8
|
+
*/
|
|
9
|
+
import type { Episode, MemoryEntry, WorkEntry } from "./types.js";
|
|
10
|
+
export declare function daysSince(iso: string): number;
|
|
11
|
+
/** Ebbinghaus decay: R = e^(-t * ln2 / S) where S = per-entry strength */
|
|
12
|
+
export declare function decay(ageDays: number, strength: number): number;
|
|
13
|
+
export declare function extractTags(text: string): string[];
|
|
14
|
+
export declare function tagOverlap(a: string[], b: string[]): number;
|
|
15
|
+
export interface ScoreWeights {
|
|
16
|
+
recency: number;
|
|
17
|
+
importance: number;
|
|
18
|
+
relevance: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function scoreEntry(e: MemoryEntry, project: string, ctx: string[], defaultHalfLife: Record<string, number>, weights: ScoreWeights): number;
|
|
21
|
+
export declare function scoreEpisode(ep: Episode, project: string, ctx: string[], defaultHalfLife: Record<string, number>, weights: ScoreWeights): number;
|
|
22
|
+
export declare function scoreWorkEntry(w: WorkEntry, project: string, ctx: string[], defaultHalfLife: Record<string, number>, weights: ScoreWeights): number;
|
|
23
|
+
/** Budget-constrained top-k selection by score */
|
|
24
|
+
export declare function pickTop<T>(items: T[], scoreFn: (t: T) => number, lenFn: (t: T) => number, budget: number): T[];
|
|
25
|
+
//# sourceMappingURL=scoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAElE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,0EAA0E;AAC1E,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAElD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAI3D;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,UAAU,CACzB,CAAC,EAAE,WAAW,EACd,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EAAE,EACb,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,OAAO,EAAE,YAAY,GACnB,MAAM,CAOR;AAED,wBAAgB,YAAY,CAC3B,EAAE,EAAE,OAAO,EACX,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EAAE,EACb,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,OAAO,EAAE,YAAY,GACnB,MAAM,CAOR;AAED,wBAAgB,cAAc,CAC7B,CAAC,EAAE,SAAS,EACZ,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EAAE,EACb,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,OAAO,EAAE,YAAY,GACnB,MAAM,CAOR;AAED,kDAAkD;AAClD,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAW9G"}
|