recallnest 1.4.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.
Files changed (261) hide show
  1. package/.claude-plugin/CLAUDE.md +29 -0
  2. package/.claude-plugin/marketplace.json +18 -0
  3. package/.env.example +3 -0
  4. package/.github/workflows/ci.yml +28 -0
  5. package/.mcp.json +9 -0
  6. package/CHANGELOG.md +51 -0
  7. package/CLAUDE.md +42 -0
  8. package/DEMO.md +94 -0
  9. package/EVAL.md +89 -0
  10. package/FAILURES.md +75 -0
  11. package/LICENSE +21 -0
  12. package/OPERATIONS.md +59 -0
  13. package/README.md +427 -0
  14. package/README_CN.md +425 -0
  15. package/ROADMAP.md +198 -0
  16. package/assets/recallnest-workbench.png +0 -0
  17. package/assets/ui/app.js +807 -0
  18. package/assets/ui/index.html +154 -0
  19. package/assets/ui/styles.css +605 -0
  20. package/assets/wechat-qr.jpg +0 -0
  21. package/config.json.example +38 -0
  22. package/daily-recall.sh +87 -0
  23. package/daily-reflections/2026-03-05.md +15 -0
  24. package/daily-reflections/2026-03-06.md +15 -0
  25. package/daily-reflections/2026-03-07.md +7 -0
  26. package/daily-reflections/2026-03-08.md +34 -0
  27. package/daily-reflections/2026-03-09.md +35 -0
  28. package/daily-reflections/2026-03-10.md +36 -0
  29. package/daily-reflections/2026-03-11.md +35 -0
  30. package/daily-reflections/2026-03-12.md +36 -0
  31. package/daily-reflections/2026-03-13.md +35 -0
  32. package/daily-reflections/2026-03-14.md +35 -0
  33. package/daily-reflections/2026-03-15.md +35 -0
  34. package/daily-reflections/2026-03-16.md +41 -0
  35. package/daily-reflections/2026-03-17.md +10 -0
  36. package/daily-reflections/2026-03-18.md +10 -0
  37. package/daily-reflections/2026-03-19.md +10 -0
  38. package/daily-reflections/2026-03-20.md +10 -0
  39. package/daily-reflections/2026-03-21.md +10 -0
  40. package/daily-reflections/2026-03-22.md +10 -0
  41. package/daily-reflections/2026-03-23.md +10 -0
  42. package/daily-reflections/2026-03-24.md +10 -0
  43. package/daily-reflections/2026-03-25.md +32 -0
  44. package/daily-reflections/2026-03-26.md +37 -0
  45. package/daily-reflections/2026-03-27.md +35 -0
  46. package/daily-reflections/2026-03-28.md +35 -0
  47. package/daily-reflections/2026-03-29.md +35 -0
  48. package/daily-reflections/2026-03-30.md +36 -0
  49. package/daily-reflections/2026-03-31.md +35 -0
  50. package/daily-reflections/2026-04-01.md +35 -0
  51. package/docs/api-reference.md +1291 -0
  52. package/docs/architecture.md +168 -0
  53. package/docs/memory-boundary-contract.md +226 -0
  54. package/docs/memory-categories.md +119 -0
  55. package/docs/pipeline-audit-ultramemory.md +177 -0
  56. package/docs/plans/2026-03-08-query-expansion.md +270 -0
  57. package/docs/plans/2026-03-16-continuity-layer.md +196 -0
  58. package/docs/plans/mcp-tiering-plan.md +126 -0
  59. package/docs/research/recall-quality-audit-2026-03-22.md +153 -0
  60. package/docs/self-evolution.md +198 -0
  61. package/docs/superpowers/plans/2026-03-19-ingest-pipeline-upgrade.md +782 -0
  62. package/docs/superpowers/specs/2026-03-19-ingest-pipeline-upgrade-design.md +77 -0
  63. package/docs/superpowers/specs/2026-03-23-pull-claude-desktop-design.md +95 -0
  64. package/eval/cases.json +85 -0
  65. package/eval/continuity/case-seeds.json +90 -0
  66. package/eval/continuity/cases.json +302 -0
  67. package/eval/continuity/memory-seeds.json +26 -0
  68. package/eval/continuity/pattern-seeds.json +100 -0
  69. package/eval/continuity/results-2026-03-16.md +117 -0
  70. package/eval/continuity/results-2026-03-19.md +453 -0
  71. package/eval/continuity/runbook.md +110 -0
  72. package/eval/continuity/seed-cases.md +54 -0
  73. package/eval/reports/2026-03-06-abstract-query-baseline.md +96 -0
  74. package/eval/reports/2026-03-06-aws-ssh-baseline.md +82 -0
  75. package/eval/reports/2026-03-06-baseline.md +82 -0
  76. package/eval/reports/query-expansion.md +138 -0
  77. package/integrations/README.md +57 -0
  78. package/integrations/claude-code/README.md +133 -0
  79. package/integrations/claude-code/claude-md-snippet.md +31 -0
  80. package/integrations/claude-code/setup.sh +66 -0
  81. package/integrations/claude-code/smoke-continuity.sh +452 -0
  82. package/integrations/codex/README.md +49 -0
  83. package/integrations/codex/agents-md-snippet.md +31 -0
  84. package/integrations/codex/setup.sh +58 -0
  85. package/integrations/examples/claude-agent-sdk/memory-agent.ts +182 -0
  86. package/integrations/examples/langchain/memory-chain.py +111 -0
  87. package/integrations/examples/openai-agents-sdk/memory-agent.py +109 -0
  88. package/integrations/gemini-cli/README.md +57 -0
  89. package/integrations/gemini-cli/gemini-md-snippet.md +31 -0
  90. package/integrations/gemini-cli/setup.sh +64 -0
  91. package/integrations/shared/install-managed-block.sh +51 -0
  92. package/lm +19 -0
  93. package/package.json +50 -0
  94. package/plan-v1.2-distributable.md +105 -0
  95. package/scripts/archive-distilled-junk.ts +116 -0
  96. package/scripts/backfill-l0l1l2.ts +98 -0
  97. package/scripts/blind-scan.ts +588 -0
  98. package/scripts/cleanup-step1-exact-dups.ts +117 -0
  99. package/scripts/cleanup-step2-template-dups.ts +113 -0
  100. package/scripts/cleanup-step3-stale-content.ts +149 -0
  101. package/scripts/cleanup-step4-orphan-scopes.ts +131 -0
  102. package/scripts/delete-distilled-junk.ts +88 -0
  103. package/scripts/distill-facts.ts +305 -0
  104. package/scripts/health-check.ts +343 -0
  105. package/scripts/incremental-ingest.sh +71 -0
  106. package/scripts/mlp-health-check.ts +382 -0
  107. package/scripts/pull-claude-desktop.ts +515 -0
  108. package/scripts/re-ingest-cc.sh +66 -0
  109. package/scripts/rebalance-memory-health.ts +181 -0
  110. package/scripts/run-desktop-ingest.sh +11 -0
  111. package/scripts/start-server.sh +12 -0
  112. package/scripts/viz-dashboard.html +423 -0
  113. package/scripts/viz-export.ts +703 -0
  114. package/src/__tests__/access-tracker-novelty.test.ts +228 -0
  115. package/src/__tests__/auto-consolidation.test.ts +168 -0
  116. package/src/__tests__/auto-recall.test.ts +131 -0
  117. package/src/__tests__/batch-dedup.test.ts +65 -0
  118. package/src/__tests__/capture-engine.test.ts +1142 -0
  119. package/src/__tests__/capture-heuristic.test.ts +171 -0
  120. package/src/__tests__/cascade-forget.test.ts +210 -0
  121. package/src/__tests__/category-min-scores.test.ts +33 -0
  122. package/src/__tests__/confidence-tracker.test.ts +196 -0
  123. package/src/__tests__/conflict-advisor.test.ts +206 -0
  124. package/src/__tests__/conflict-escalation.test.ts +149 -0
  125. package/src/__tests__/conflict-lifecycle.test.ts +83 -0
  126. package/src/__tests__/conflict-output.test.ts +85 -0
  127. package/src/__tests__/conflict-store.test.ts +374 -0
  128. package/src/__tests__/consolidation-engine.test.ts +181 -0
  129. package/src/__tests__/context-composer-pins.test.ts +64 -0
  130. package/src/__tests__/context-composer-task-selection.test.ts +24 -0
  131. package/src/__tests__/context-renderer.test.ts +91 -0
  132. package/src/__tests__/continuity-eval.test.ts +275 -0
  133. package/src/__tests__/continuity-schema.test.ts +97 -0
  134. package/src/__tests__/core-recall-eval.test.ts +235 -0
  135. package/src/__tests__/core-summary.test.ts +109 -0
  136. package/src/__tests__/dedup-actions.test.ts +58 -0
  137. package/src/__tests__/deterministic-id.test.ts +39 -0
  138. package/src/__tests__/doctor.test.ts +303 -0
  139. package/src/__tests__/drill-down.test.ts +108 -0
  140. package/src/__tests__/embedder.test.ts +122 -0
  141. package/src/__tests__/entity-resolver.test.ts +58 -0
  142. package/src/__tests__/event-segmenter.test.ts +153 -0
  143. package/src/__tests__/hotness-blend.test.ts +76 -0
  144. package/src/__tests__/ingest.test.ts +360 -0
  145. package/src/__tests__/kg-extractor.test.ts +184 -0
  146. package/src/__tests__/kg-store.test.ts +198 -0
  147. package/src/__tests__/llm-consolidation.test.ts +226 -0
  148. package/src/__tests__/memory-boundaries.test.ts +237 -0
  149. package/src/__tests__/memory-health-rebalance.test.ts +144 -0
  150. package/src/__tests__/memory-output.test.ts +215 -0
  151. package/src/__tests__/multi-vector.test.ts +242 -0
  152. package/src/__tests__/ppr-traversal.test.ts +256 -0
  153. package/src/__tests__/preference-guard-smoke.test.ts +211 -0
  154. package/src/__tests__/preference-matcher.test.ts +230 -0
  155. package/src/__tests__/preference-slots.test.ts +106 -0
  156. package/src/__tests__/prospective-memory.test.ts +283 -0
  157. package/src/__tests__/query-entity-detector.test.ts +171 -0
  158. package/src/__tests__/query-expander.test.ts +34 -0
  159. package/src/__tests__/recall-mode.test.ts +64 -0
  160. package/src/__tests__/result-synthesizer.test.ts +198 -0
  161. package/src/__tests__/resume-context.test.ts +4743 -0
  162. package/src/__tests__/retrieval-trace.test.ts +213 -0
  163. package/src/__tests__/retriever-boundary-weight.test.ts +136 -0
  164. package/src/__tests__/retroactive-boost.test.ts +223 -0
  165. package/src/__tests__/scope-inventory.test.ts +200 -0
  166. package/src/__tests__/scope-policy.test.ts +69 -0
  167. package/src/__tests__/session-checkpoint.test.ts +259 -0
  168. package/src/__tests__/session-gc.test.ts +215 -0
  169. package/src/__tests__/store-scope-audit.test.ts +81 -0
  170. package/src/__tests__/temporal-parser.test.ts +241 -0
  171. package/src/__tests__/term-registry.test.ts +121 -0
  172. package/src/__tests__/tool-output-compressor.test.ts +133 -0
  173. package/src/__tests__/version-manager.test.ts +213 -0
  174. package/src/__tests__/workflow-observation.test.ts +400 -0
  175. package/src/access-tracker.ts +316 -0
  176. package/src/adaptive-retrieval.ts +64 -0
  177. package/src/api-server.ts +667 -0
  178. package/src/asset-sync.ts +79 -0
  179. package/src/auto-consolidation.ts +133 -0
  180. package/src/auto-gc.ts +124 -0
  181. package/src/auto-recall.ts +95 -0
  182. package/src/capture-engine.ts +931 -0
  183. package/src/capture-heuristic.ts +177 -0
  184. package/src/cascade-forget.ts +135 -0
  185. package/src/chunker.ts +253 -0
  186. package/src/cli.ts +1917 -0
  187. package/src/confidence-tracker.ts +166 -0
  188. package/src/conflict-advisor.ts +433 -0
  189. package/src/conflict-engine.ts +181 -0
  190. package/src/conflict-escalation.ts +138 -0
  191. package/src/conflict-lifecycle.ts +67 -0
  192. package/src/conflict-output.ts +218 -0
  193. package/src/conflict-schema.ts +130 -0
  194. package/src/conflict-store.ts +127 -0
  195. package/src/consolidation-engine.ts +256 -0
  196. package/src/context-composer-pins.ts +183 -0
  197. package/src/context-composer-queries.ts +121 -0
  198. package/src/context-composer-scope.ts +56 -0
  199. package/src/context-composer-stable-selection.ts +200 -0
  200. package/src/context-composer-stable.ts +217 -0
  201. package/src/context-composer-task-fallbacks.ts +36 -0
  202. package/src/context-composer-task-ranking.ts +197 -0
  203. package/src/context-composer-task-results.ts +137 -0
  204. package/src/context-composer-task-selection.ts +342 -0
  205. package/src/context-composer-text.ts +57 -0
  206. package/src/context-composer.ts +300 -0
  207. package/src/context-renderer.ts +179 -0
  208. package/src/decay-engine.ts +189 -0
  209. package/src/doctor.ts +543 -0
  210. package/src/embedder.ts +557 -0
  211. package/src/entity-resolver.ts +131 -0
  212. package/src/eval.ts +632 -0
  213. package/src/event-segmenter.ts +216 -0
  214. package/src/ingest.ts +1822 -0
  215. package/src/kg-extractor.ts +217 -0
  216. package/src/kg-store.ts +353 -0
  217. package/src/legacy-scope-review.ts +53 -0
  218. package/src/llm-client.ts +629 -0
  219. package/src/llm-consolidation.ts +168 -0
  220. package/src/mcp-server.ts +1337 -0
  221. package/src/memory-assets.ts +475 -0
  222. package/src/memory-boundaries.ts +354 -0
  223. package/src/memory-health-rebalance.ts +220 -0
  224. package/src/memory-output.ts +474 -0
  225. package/src/memory-schema.ts +184 -0
  226. package/src/multi-vector.ts +234 -0
  227. package/src/noise-filter.ts +155 -0
  228. package/src/ppr-traversal.ts +279 -0
  229. package/src/preference-matcher.ts +174 -0
  230. package/src/preference-slots.ts +259 -0
  231. package/src/prospective-memory.ts +198 -0
  232. package/src/query-entity-detector.ts +207 -0
  233. package/src/query-expander.ts +98 -0
  234. package/src/result-synthesizer.ts +114 -0
  235. package/src/retrieval-profiles.ts +101 -0
  236. package/src/retrieval-trace.ts +94 -0
  237. package/src/retriever.ts +1338 -0
  238. package/src/retroactive-boost.ts +154 -0
  239. package/src/rif.ts +73 -0
  240. package/src/runtime-config.ts +172 -0
  241. package/src/schema-utils.ts +56 -0
  242. package/src/scope-inventory.ts +310 -0
  243. package/src/scope-policy.ts +142 -0
  244. package/src/session-engine.ts +168 -0
  245. package/src/session-output.ts +96 -0
  246. package/src/session-schema.ts +60 -0
  247. package/src/session-store.ts +293 -0
  248. package/src/stderr-log.ts +16 -0
  249. package/src/store.ts +903 -0
  250. package/src/temporal-parser.ts +318 -0
  251. package/src/term-registry.ts +791 -0
  252. package/src/tool-output-compressor.ts +115 -0
  253. package/src/tracker.ts +57 -0
  254. package/src/ui-server.ts +430 -0
  255. package/src/version-manager.ts +172 -0
  256. package/src/workflow-observation-engine.ts +316 -0
  257. package/src/workflow-observation-managed.ts +83 -0
  258. package/src/workflow-observation-output.ts +86 -0
  259. package/src/workflow-observation-schema.ts +87 -0
  260. package/src/workflow-observation-scope-review.ts +409 -0
  261. package/src/workflow-observation-store.ts +69 -0
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Event Segmentation (Tier 4.5)
3
+ *
4
+ * Replaces fixed-character chunking with semantic event boundaries for
5
+ * conversation text. Ensures retrieval gets complete semantic units
6
+ * (a full Q&A exchange, a complete list, an intact code block) rather
7
+ * than fragments cut mid-thought.
8
+ *
9
+ * Design: rule-based (zero LLM calls), CJK-aware, falls back to chunker
10
+ * for segments that exceed embedding model limits.
11
+ */
12
+
13
+ // ============================================================================
14
+ // Types
15
+ // ============================================================================
16
+
17
+ export interface EventSegment {
18
+ text: string;
19
+ /** Reason this boundary was detected */
20
+ boundaryType: "topic_shift" | "qa_boundary" | "list_end" | "code_block" | "time_jump" | "initial" | "max_size";
21
+ }
22
+
23
+ export interface EventSegmenterConfig {
24
+ /** Max chars per segment before forced split (default: 2000) */
25
+ maxSegmentSize: number;
26
+ /** Min chars per segment to avoid fragments (default: 200) */
27
+ minSegmentSize: number;
28
+ }
29
+
30
+ export const DEFAULT_EVENT_SEGMENTER_CONFIG: EventSegmenterConfig = {
31
+ maxSegmentSize: 2000,
32
+ minSegmentSize: 200,
33
+ };
34
+
35
+ // ============================================================================
36
+ // Boundary Detection Signals
37
+ // ============================================================================
38
+
39
+ /**
40
+ * Topic shift markers — words/phrases that signal a new topic in conversation.
41
+ * Ordered roughly by strength of signal.
42
+ */
43
+ const TOPIC_SHIFT_PATTERNS = [
44
+ // Strong signals (explicit topic change)
45
+ /^(?:\[用户\]|\[助手\])?\s*(?:另外|顺便|对了|换个话题|说到|关于另一个)/m,
46
+ /^(?:\[用户\]|\[助手\])?\s*(?:by the way|speaking of|on another note|moving on|anyway|also,? I wanted)/im,
47
+ // Medium signals (new question after discussion)
48
+ /^(?:\[用户\])\s*.{0,20}[??]\s*$/m,
49
+ ];
50
+
51
+ /** Detect if text at a given line index starts a new topic */
52
+ function isTopicShift(line: string): boolean {
53
+ return TOPIC_SHIFT_PATTERNS.some(p => p.test(line));
54
+ }
55
+
56
+ /**
57
+ * Q&A boundary: a [用户] line after an [助手] block signals a new exchange.
58
+ */
59
+ function isQABoundary(line: string, prevLine: string): boolean {
60
+ return /^\[用户\]/.test(line) && /^\[助手\]/.test(prevLine.trimStart());
61
+ }
62
+
63
+ /**
64
+ * Time jump: date/time markers that indicate a temporal discontinuity.
65
+ */
66
+ const TIME_JUMP_PATTERN = /^(?:\[用户\]|\[助手\])?\s*(?:\d{4}[-/]\d{1,2}[-/]\d{1,2}|(?:今天|昨天|前天|上周|上个月|today|yesterday|last week))/i;
67
+
68
+ function isTimeJump(line: string): boolean {
69
+ return TIME_JUMP_PATTERN.test(line);
70
+ }
71
+
72
+ // ============================================================================
73
+ // Code Block Tracking
74
+ // ============================================================================
75
+
76
+ /** Track code fence state to avoid splitting inside code blocks */
77
+ function isCodeFence(line: string): boolean {
78
+ return /^```/.test(line.trim());
79
+ }
80
+
81
+ // ============================================================================
82
+ // List Completeness
83
+ // ============================================================================
84
+
85
+ /** Detect numbered or bulleted list items */
86
+ const LIST_ITEM_PATTERN = /^\s*(?:\d+[.)]\s|[-*+]\s)/;
87
+
88
+ function isListItem(line: string): boolean {
89
+ return LIST_ITEM_PATTERN.test(line);
90
+ }
91
+
92
+ // ============================================================================
93
+ // Core Segmenter
94
+ // ============================================================================
95
+
96
+ /**
97
+ * Segment conversation text into semantic event units.
98
+ *
99
+ * Strategy:
100
+ * 1. Walk lines, tracking state (in-code-block, in-list, etc.)
101
+ * 2. At each potential boundary, decide: split or continue
102
+ * 3. Respect min/max size constraints
103
+ * 4. Never split inside code blocks or mid-list
104
+ */
105
+ export function segmentEvents(
106
+ text: string,
107
+ config: EventSegmenterConfig = DEFAULT_EVENT_SEGMENTER_CONFIG,
108
+ ): EventSegment[] {
109
+ if (!text || text.trim().length === 0) return [];
110
+
111
+ // Very short text: no point in segmenting
112
+ if (text.length <= config.minSegmentSize) {
113
+ return [{ text: text.trim(), boundaryType: "initial" }];
114
+ }
115
+
116
+ const lines = text.split("\n");
117
+ const segments: EventSegment[] = [];
118
+ let currentLines: string[] = [];
119
+ let currentLen = 0;
120
+ let inCodeBlock = false;
121
+ let inList = false;
122
+ let pendingBoundary: EventSegment["boundaryType"] | null = null;
123
+
124
+ function flushSegment(boundaryType: EventSegment["boundaryType"]) {
125
+ const segText = currentLines.join("\n").trim();
126
+ if (segText.length > 0) {
127
+ segments.push({ text: segText, boundaryType });
128
+ }
129
+ currentLines = [];
130
+ currentLen = 0;
131
+ pendingBoundary = null;
132
+ }
133
+
134
+ for (let i = 0; i < lines.length; i++) {
135
+ const line = lines[i];
136
+ const lineLen = line.length + 1; // +1 for \n
137
+
138
+ // Track code block state
139
+ if (isCodeFence(line)) {
140
+ inCodeBlock = !inCodeBlock;
141
+ currentLines.push(line);
142
+ currentLen += lineLen;
143
+ continue;
144
+ }
145
+
146
+ // Never split inside code blocks
147
+ if (inCodeBlock) {
148
+ currentLines.push(line);
149
+ currentLen += lineLen;
150
+ // Safety: if code block is absurdly long, force close
151
+ if (currentLen > config.maxSegmentSize * 2) {
152
+ inCodeBlock = false;
153
+ flushSegment("code_block");
154
+ }
155
+ continue;
156
+ }
157
+
158
+ // Track list state
159
+ if (isListItem(line)) {
160
+ inList = true;
161
+ currentLines.push(line);
162
+ currentLen += lineLen;
163
+ continue;
164
+ } else if (inList && line.trim().length > 0) {
165
+ // Non-list line after list items: list ended
166
+ inList = false;
167
+ // If accumulated enough, this is a good split point
168
+ if (currentLen >= config.minSegmentSize) {
169
+ pendingBoundary = "list_end";
170
+ }
171
+ }
172
+
173
+ // Check boundary signals (only if we have enough content)
174
+ if (currentLen >= config.minSegmentSize) {
175
+ const prevLine = currentLines.length > 0 ? currentLines[currentLines.length - 1] : "";
176
+
177
+ if (isTopicShift(line)) {
178
+ flushSegment("topic_shift");
179
+ } else if (isQABoundary(line, prevLine)) {
180
+ flushSegment("qa_boundary");
181
+ } else if (isTimeJump(line)) {
182
+ flushSegment("time_jump");
183
+ } else if (pendingBoundary) {
184
+ flushSegment(pendingBoundary);
185
+ }
186
+ }
187
+
188
+ // Force split if exceeding max size
189
+ if (currentLen + lineLen > config.maxSegmentSize && currentLen >= config.minSegmentSize) {
190
+ flushSegment("max_size");
191
+ }
192
+
193
+ currentLines.push(line);
194
+ currentLen += lineLen;
195
+ }
196
+
197
+ // Flush remaining
198
+ if (currentLines.length > 0) {
199
+ flushSegment(segments.length === 0 ? "initial" : "max_size");
200
+ }
201
+
202
+ // Merge tiny trailing segments into the previous one
203
+ if (segments.length > 1) {
204
+ const last = segments[segments.length - 1];
205
+ if (last.text.length < config.minSegmentSize) {
206
+ const prev = segments[segments.length - 2];
207
+ segments[segments.length - 2] = {
208
+ text: prev.text + "\n" + last.text,
209
+ boundaryType: prev.boundaryType,
210
+ };
211
+ segments.pop();
212
+ }
213
+ }
214
+
215
+ return segments;
216
+ }