hippo-memory 1.60.0 → 1.61.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 (585) hide show
  1. package/README.md +1 -1
  2. package/dist/ablation.js +9 -27
  3. package/dist/agent-memories/apply.js +4 -1
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/gemini.js +1 -1
  7. package/dist/agent-memories/legacy.js +1 -1
  8. package/dist/agent-memories/source.js +1 -1
  9. package/dist/agent-memories/sync.js +8 -3
  10. package/dist/ambient-store.d.ts +14 -0
  11. package/dist/ambient-store.js +90 -0
  12. package/dist/ambient.d.ts +23 -0
  13. package/dist/ambient.js +72 -50
  14. package/dist/api/assemble.d.ts +93 -0
  15. package/dist/api/assemble.js +152 -0
  16. package/dist/api/audit.d.ts +17 -0
  17. package/dist/api/audit.js +23 -0
  18. package/dist/api/auth.d.ts +79 -0
  19. package/dist/api/auth.js +178 -0
  20. package/dist/api/context-types.d.ts +105 -0
  21. package/dist/api/context-types.js +3 -0
  22. package/dist/api/context.d.ts +31 -0
  23. package/dist/api/context.js +705 -0
  24. package/dist/api/dormant.d.ts +30 -0
  25. package/dist/api/dormant.js +140 -0
  26. package/dist/api/drill-down.d.ts +84 -0
  27. package/dist/api/drill-down.js +123 -0
  28. package/dist/api/forget.d.ts +57 -0
  29. package/dist/api/forget.js +87 -0
  30. package/dist/api/goals.d.ts +18 -0
  31. package/dist/api/goals.js +33 -0
  32. package/dist/api/learn.d.ts +31 -0
  33. package/dist/api/learn.js +88 -0
  34. package/dist/api/outcome.d.ts +61 -0
  35. package/dist/api/outcome.js +66 -0
  36. package/dist/api/promote.d.ts +54 -0
  37. package/dist/api/promote.js +203 -0
  38. package/dist/api/quarantine.d.ts +24 -0
  39. package/dist/api/quarantine.js +121 -0
  40. package/dist/api/recall-types.d.ts +390 -0
  41. package/dist/api/recall-types.js +3 -0
  42. package/dist/api/recall.d.ts +36 -0
  43. package/dist/api/recall.js +634 -0
  44. package/dist/api/remember.d.ts +35 -0
  45. package/dist/api/remember.js +43 -0
  46. package/dist/api/sleep.d.ts +136 -0
  47. package/dist/api/sleep.js +271 -0
  48. package/dist/api/tokens.d.ts +26 -0
  49. package/dist/api/tokens.js +60 -0
  50. package/dist/api/types.d.ts +56 -0
  51. package/dist/api/types.js +38 -0
  52. package/dist/api.d.ts +20 -1262
  53. package/dist/api.js +25 -2727
  54. package/dist/audit.d.ts +3 -0
  55. package/dist/audit.js +6 -3
  56. package/dist/auth.d.ts +45 -4
  57. package/dist/auth.js +125 -48
  58. package/dist/autolearn.js +2 -2
  59. package/dist/capture/command.d.ts +33 -0
  60. package/dist/capture/command.js +264 -0
  61. package/dist/capture/compact.d.ts +44 -0
  62. package/dist/capture/compact.js +354 -0
  63. package/dist/capture/extract.d.ts +21 -0
  64. package/dist/capture/extract.js +464 -0
  65. package/dist/capture/transcript.d.ts +40 -0
  66. package/dist/capture/transcript.js +193 -0
  67. package/dist/capture-error.js +2 -1
  68. package/dist/churn-git.js +4 -2
  69. package/dist/cli/audit.d.ts +3 -0
  70. package/dist/cli/audit.js +159 -0
  71. package/dist/cli/auth.d.ts +2 -0
  72. package/dist/cli/auth.js +171 -0
  73. package/dist/cli/briefs.d.ts +4 -0
  74. package/dist/cli/briefs.js +435 -0
  75. package/dist/cli/card.d.ts +3 -0
  76. package/dist/cli/card.js +333 -0
  77. package/dist/cli/context.d.ts +15 -0
  78. package/dist/cli/context.js +366 -0
  79. package/dist/cli/continuity.d.ts +6 -0
  80. package/dist/cli/continuity.js +445 -0
  81. package/dist/cli/curate.d.ts +19 -0
  82. package/dist/cli/curate.js +555 -0
  83. package/dist/cli/dag.d.ts +5 -0
  84. package/dist/cli/dag.js +177 -0
  85. package/dist/cli/decisions.d.ts +4 -0
  86. package/dist/cli/decisions.js +528 -0
  87. package/dist/cli/eval.d.ts +5 -0
  88. package/dist/cli/eval.js +213 -0
  89. package/dist/cli/explain.d.ts +4 -0
  90. package/dist/cli/explain.js +150 -0
  91. package/dist/cli/goals.d.ts +2 -0
  92. package/dist/cli/goals.js +196 -0
  93. package/dist/cli/hook-blocks.d.ts +18 -0
  94. package/dist/cli/hook-blocks.js +233 -0
  95. package/dist/cli/init.d.ts +2 -0
  96. package/dist/cli/init.js +305 -0
  97. package/dist/cli/maintenance.d.ts +4 -0
  98. package/dist/cli/maintenance.js +179 -0
  99. package/dist/cli/playbooks.d.ts +4 -0
  100. package/dist/cli/playbooks.js +556 -0
  101. package/dist/cli/projects.js +1 -1
  102. package/dist/cli/recall.d.ts +7 -0
  103. package/dist/cli/recall.js +597 -0
  104. package/dist/cli/remember.d.ts +5 -0
  105. package/dist/cli/remember.js +442 -0
  106. package/dist/cli/serve.d.ts +5 -0
  107. package/dist/cli/serve.js +40 -0
  108. package/dist/cli/session-hooks.d.ts +29 -0
  109. package/dist/cli/session-hooks.js +637 -0
  110. package/dist/cli/setup.d.ts +4 -0
  111. package/dist/cli/setup.js +376 -0
  112. package/dist/cli/shared.d.ts +15 -19
  113. package/dist/cli/shared.js +50 -341
  114. package/dist/cli/slack.d.ts +2 -0
  115. package/dist/cli/slack.js +171 -0
  116. package/dist/cli/status.d.ts +18 -0
  117. package/dist/cli/status.js +400 -0
  118. package/dist/cli/transfer.d.ts +10 -0
  119. package/dist/cli/transfer.js +438 -0
  120. package/dist/cli/usage.d.ts +85 -0
  121. package/dist/cli/usage.js +741 -0
  122. package/dist/cli.d.ts +71 -120
  123. package/dist/cli.js +170 -8469
  124. package/dist/client.js +15 -8
  125. package/dist/compaction-record.js +6 -4
  126. package/dist/connectors/github/backfill.js +94 -87
  127. package/dist/connectors/github/cli-impl.js +4 -3
  128. package/dist/connectors/github/dlq.js +67 -54
  129. package/dist/connectors/github/ingest.js +34 -35
  130. package/dist/connectors/github/tenant-routing.js +3 -2
  131. package/dist/connectors/github/webhook.js +135 -216
  132. package/dist/connectors/slack/dlq.js +49 -61
  133. package/dist/connectors/slack/ingest.js +55 -48
  134. package/dist/connectors/slack/tenant-routing.js +4 -3
  135. package/dist/connectors/slack/webhook.js +72 -74
  136. package/dist/consolidate/conflicts.d.ts +10 -0
  137. package/dist/consolidate/conflicts.js +178 -0
  138. package/dist/consolidate/decay.d.ts +12 -0
  139. package/dist/consolidate/decay.js +145 -0
  140. package/dist/consolidate/llm-passes.d.ts +3 -0
  141. package/dist/consolidate/llm-passes.js +141 -0
  142. package/dist/consolidate/merge.d.ts +7 -0
  143. package/dist/consolidate/merge.js +251 -0
  144. package/dist/consolidate/physics-pass.d.ts +3 -0
  145. package/dist/consolidate/physics-pass.js +60 -0
  146. package/dist/consolidate/run.d.ts +69 -0
  147. package/dist/consolidate/run.js +76 -0
  148. package/dist/consolidate/sleep.d.ts +18 -0
  149. package/dist/consolidate/sleep.js +209 -0
  150. package/dist/consolidate/traces.d.ts +4 -0
  151. package/dist/consolidate/traces.js +178 -0
  152. package/dist/context-auto.js +7 -11
  153. package/dist/context-render.d.ts +1 -1
  154. package/dist/context-render.js +1 -1
  155. package/dist/customer-notes.d.ts +3 -0
  156. package/dist/customer-notes.js +6 -4
  157. package/dist/dag.js +6 -5
  158. package/dist/dashboard-actions.d.ts +20 -0
  159. package/dist/dashboard-actions.js +88 -0
  160. package/dist/dashboard-params.d.ts +45 -0
  161. package/dist/dashboard-params.js +127 -0
  162. package/dist/dashboard-queries.d.ts +15 -0
  163. package/dist/dashboard-queries.js +355 -0
  164. package/dist/dashboard-snapshot.d.ts +138 -0
  165. package/dist/dashboard-snapshot.js +308 -0
  166. package/dist/dashboard-types.d.ts +163 -0
  167. package/dist/dashboard-types.js +3 -0
  168. package/dist/dashboard.d.ts +6 -7
  169. package/dist/dashboard.js +228 -202
  170. package/dist/db/busy.d.ts +5 -0
  171. package/dist/db/busy.js +24 -0
  172. package/dist/db/continuity.d.ts +5 -0
  173. package/dist/db/continuity.js +145 -0
  174. package/dist/db/meta.d.ts +8 -0
  175. package/dist/db/meta.js +35 -0
  176. package/dist/db/migrate.d.ts +9 -0
  177. package/dist/db/migrate.js +138 -0
  178. package/dist/db/migrations/index.d.ts +5 -0
  179. package/dist/db/migrations/index.js +109 -0
  180. package/dist/db/migrations/types.d.ts +14 -0
  181. package/dist/db/migrations/types.js +2 -0
  182. package/dist/db/migrations/v01.d.ts +3 -0
  183. package/dist/db/migrations/v01.js +38 -0
  184. package/dist/db/migrations/v02.d.ts +3 -0
  185. package/dist/db/migrations/v02.js +21 -0
  186. package/dist/db/migrations/v03.d.ts +3 -0
  187. package/dist/db/migrations/v03.js +22 -0
  188. package/dist/db/migrations/v04.d.ts +3 -0
  189. package/dist/db/migrations/v04.js +28 -0
  190. package/dist/db/migrations/v05.d.ts +3 -0
  191. package/dist/db/migrations/v05.js +21 -0
  192. package/dist/db/migrations/v06.d.ts +3 -0
  193. package/dist/db/migrations/v06.js +25 -0
  194. package/dist/db/migrations/v07.d.ts +3 -0
  195. package/dist/db/migrations/v07.js +13 -0
  196. package/dist/db/migrations/v08.d.ts +3 -0
  197. package/dist/db/migrations/v08.js +8 -0
  198. package/dist/db/migrations/v09.d.ts +3 -0
  199. package/dist/db/migrations/v09.js +13 -0
  200. package/dist/db/migrations/v10.d.ts +3 -0
  201. package/dist/db/migrations/v10.js +17 -0
  202. package/dist/db/migrations/v11.d.ts +3 -0
  203. package/dist/db/migrations/v11.js +15 -0
  204. package/dist/db/migrations/v12.d.ts +3 -0
  205. package/dist/db/migrations/v12.js +11 -0
  206. package/dist/db/migrations/v13.d.ts +3 -0
  207. package/dist/db/migrations/v13.js +15 -0
  208. package/dist/db/migrations/v14.d.ts +3 -0
  209. package/dist/db/migrations/v14.js +66 -0
  210. package/dist/db/migrations/v15.d.ts +3 -0
  211. package/dist/db/migrations/v15.js +42 -0
  212. package/dist/db/migrations/v16.d.ts +3 -0
  213. package/dist/db/migrations/v16.js +61 -0
  214. package/dist/db/migrations/v17.d.ts +3 -0
  215. package/dist/db/migrations/v17.js +46 -0
  216. package/dist/db/migrations/v18.d.ts +3 -0
  217. package/dist/db/migrations/v18.js +60 -0
  218. package/dist/db/migrations/v19.d.ts +3 -0
  219. package/dist/db/migrations/v19.js +28 -0
  220. package/dist/db/migrations/v20.d.ts +3 -0
  221. package/dist/db/migrations/v20.js +42 -0
  222. package/dist/db/migrations/v21.d.ts +3 -0
  223. package/dist/db/migrations/v21.js +16 -0
  224. package/dist/db/migrations/v22.d.ts +3 -0
  225. package/dist/db/migrations/v22.js +82 -0
  226. package/dist/db/migrations/v23.d.ts +3 -0
  227. package/dist/db/migrations/v23.js +48 -0
  228. package/dist/db/migrations/v24.d.ts +3 -0
  229. package/dist/db/migrations/v24.js +72 -0
  230. package/dist/db/migrations/v25.d.ts +3 -0
  231. package/dist/db/migrations/v25.js +46 -0
  232. package/dist/db/migrations/v26.d.ts +3 -0
  233. package/dist/db/migrations/v26.js +23 -0
  234. package/dist/db/migrations/v27.d.ts +3 -0
  235. package/dist/db/migrations/v27.js +57 -0
  236. package/dist/db/migrations/v28.d.ts +3 -0
  237. package/dist/db/migrations/v28.js +38 -0
  238. package/dist/db/migrations/v29.d.ts +3 -0
  239. package/dist/db/migrations/v29.js +78 -0
  240. package/dist/db/migrations/v30.d.ts +3 -0
  241. package/dist/db/migrations/v30.js +92 -0
  242. package/dist/db/migrations/v31.d.ts +3 -0
  243. package/dist/db/migrations/v31.js +74 -0
  244. package/dist/db/migrations/v32.d.ts +3 -0
  245. package/dist/db/migrations/v32.js +102 -0
  246. package/dist/db/migrations/v33.d.ts +3 -0
  247. package/dist/db/migrations/v33.js +104 -0
  248. package/dist/db/migrations/v34.d.ts +3 -0
  249. package/dist/db/migrations/v34.js +93 -0
  250. package/dist/db/migrations/v35.d.ts +3 -0
  251. package/dist/db/migrations/v35.js +98 -0
  252. package/dist/db/migrations/v36.d.ts +3 -0
  253. package/dist/db/migrations/v36.js +98 -0
  254. package/dist/db/migrations/v37.d.ts +3 -0
  255. package/dist/db/migrations/v37.js +219 -0
  256. package/dist/db/migrations/v38.d.ts +3 -0
  257. package/dist/db/migrations/v38.js +277 -0
  258. package/dist/db/migrations/v39.d.ts +3 -0
  259. package/dist/db/migrations/v39.js +59 -0
  260. package/dist/db/migrations/v40.d.ts +3 -0
  261. package/dist/db/migrations/v40.js +74 -0
  262. package/dist/db/migrations/v41.d.ts +3 -0
  263. package/dist/db/migrations/v41.js +43 -0
  264. package/dist/db/migrations/v42.d.ts +3 -0
  265. package/dist/db/migrations/v42.js +41 -0
  266. package/dist/db/migrations/v43.d.ts +3 -0
  267. package/dist/db/migrations/v43.js +67 -0
  268. package/dist/db/migrations/v44.d.ts +3 -0
  269. package/dist/db/migrations/v44.js +28 -0
  270. package/dist/db/migrations/v45.d.ts +3 -0
  271. package/dist/db/migrations/v45.js +30 -0
  272. package/dist/db/migrations/v46.d.ts +3 -0
  273. package/dist/db/migrations/v46.js +25 -0
  274. package/dist/db/migrations/v47.d.ts +3 -0
  275. package/dist/db/migrations/v47.js +17 -0
  276. package/dist/db/migrations/v48.d.ts +3 -0
  277. package/dist/db/migrations/v48.js +10 -0
  278. package/dist/db/migrations/v49.d.ts +3 -0
  279. package/dist/db/migrations/v49.js +31 -0
  280. package/dist/db/migrations/v50.d.ts +3 -0
  281. package/dist/db/migrations/v50.js +67 -0
  282. package/dist/db/migrations/v51.d.ts +3 -0
  283. package/dist/db/migrations/v51.js +14 -0
  284. package/dist/db/migrations/v52.d.ts +3 -0
  285. package/dist/db/migrations/v52.js +7 -0
  286. package/dist/db/open.d.ts +23 -0
  287. package/dist/db/open.js +146 -0
  288. package/dist/db/sqlite.d.ts +21 -0
  289. package/dist/db/sqlite.js +8 -0
  290. package/dist/db/tables.d.ts +7 -0
  291. package/dist/db/tables.js +38 -0
  292. package/dist/db.d.ts +6 -46
  293. package/dist/db.js +5 -3049
  294. package/dist/decisions.d.ts +4 -1
  295. package/dist/decisions.js +9 -7
  296. package/dist/dedupe.js +3 -2
  297. package/dist/delivery-recorder.js +4 -1
  298. package/dist/doctor.js +3 -3
  299. package/dist/embedding-provider.d.ts +1 -1
  300. package/dist/embedding-provider.js +4 -3
  301. package/dist/embeddings.d.ts +9 -52
  302. package/dist/embeddings.js +43 -297
  303. package/dist/env.d.ts +75 -0
  304. package/dist/env.js +119 -0
  305. package/dist/eval-suite.js +1 -1
  306. package/dist/eval.js +2 -2
  307. package/dist/extract.js +1 -1
  308. package/dist/gated-write.js +3 -1
  309. package/dist/goals.d.ts +3 -1
  310. package/dist/goals.js +18 -0
  311. package/dist/graph/read.d.ts +73 -0
  312. package/dist/graph/read.js +325 -0
  313. package/dist/graph/rows.d.ts +45 -0
  314. package/dist/graph/rows.js +51 -0
  315. package/dist/graph/types.d.ts +83 -0
  316. package/dist/graph/types.js +11 -0
  317. package/dist/graph/write.d.ts +93 -0
  318. package/dist/{graph.js → graph/write.js} +6 -384
  319. package/dist/graph-extract.js +2 -1
  320. package/dist/graph-recall.d.ts +1 -1
  321. package/dist/graph-recall.js +2 -2
  322. package/dist/graph-stream.js +1 -1
  323. package/dist/graph-view.d.ts +1 -1
  324. package/dist/graph-view.js +1 -1
  325. package/dist/half-life-migration.d.ts +1 -1
  326. package/dist/half-life-migration.js +2 -1
  327. package/dist/hooks/codex-session.d.ts +8 -0
  328. package/dist/hooks/codex-session.js +76 -0
  329. package/dist/hooks/codex-wrapper.d.ts +55 -0
  330. package/dist/hooks/codex-wrapper.js +288 -0
  331. package/dist/hooks/json-hooks.d.ts +63 -0
  332. package/dist/hooks/json-hooks.js +356 -0
  333. package/dist/hooks/opencode.d.ts +50 -0
  334. package/dist/hooks/opencode.js +202 -0
  335. package/dist/hooks/shared.d.ts +54 -0
  336. package/dist/hooks/shared.js +77 -0
  337. package/dist/http-retry.d.ts +2 -0
  338. package/dist/http-retry.js +4 -3
  339. package/dist/http-util.d.ts +3 -0
  340. package/dist/http-util.js +10 -0
  341. package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
  342. package/dist/importers/core.js +141 -0
  343. package/dist/importers/markdown-parse.d.ts +41 -0
  344. package/dist/importers/markdown-parse.js +132 -0
  345. package/dist/importers/markdown.d.ts +3 -0
  346. package/dist/importers/markdown.js +92 -0
  347. package/dist/importers/sources.d.ts +7 -0
  348. package/dist/importers/sources.js +229 -0
  349. package/dist/importers/vault.d.ts +11 -0
  350. package/dist/importers/vault.js +352 -0
  351. package/dist/incidents.d.ts +3 -0
  352. package/dist/incidents.js +7 -5
  353. package/dist/index.d.ts +25 -6
  354. package/dist/index.js +23 -6
  355. package/dist/invalidation.js +2 -1
  356. package/dist/judgment.js +2 -1
  357. package/dist/keyset.d.ts +13 -0
  358. package/dist/keyset.js +8 -0
  359. package/dist/local-embedding.d.ts +13 -0
  360. package/dist/local-embedding.js +165 -0
  361. package/dist/log.d.ts +7 -0
  362. package/dist/log.js +19 -1
  363. package/dist/mcp/admin-tools.d.ts +8 -0
  364. package/dist/mcp/admin-tools.js +116 -0
  365. package/dist/mcp/format.d.ts +27 -0
  366. package/dist/mcp/format.js +135 -0
  367. package/dist/mcp/memory-tools.d.ts +5 -0
  368. package/dist/mcp/memory-tools.js +83 -0
  369. package/dist/mcp/protocol.d.ts +83 -0
  370. package/dist/mcp/protocol.js +55 -0
  371. package/dist/mcp/recall-tools.d.ts +6 -0
  372. package/dist/mcp/recall-tools.js +320 -0
  373. package/dist/mcp/request.d.ts +10 -0
  374. package/dist/mcp/request.js +163 -0
  375. package/dist/mcp/server.d.ts +4 -75
  376. package/dist/mcp/server.js +7 -1190
  377. package/dist/mcp/session-state.d.ts +11 -0
  378. package/dist/mcp/session-state.js +28 -0
  379. package/dist/mcp/stdio.d.ts +8 -0
  380. package/dist/mcp/stdio.js +79 -0
  381. package/dist/mcp/tools.d.ts +11 -0
  382. package/dist/mcp/tools.js +247 -0
  383. package/dist/memory.d.ts +3 -0
  384. package/dist/memory.js +27 -1
  385. package/dist/multihop.d.ts +1 -1
  386. package/dist/multihop.js +2 -1
  387. package/dist/owner-validation.js +2 -1
  388. package/dist/physics-state.js +10 -7
  389. package/dist/policies.d.ts +3 -0
  390. package/dist/policies.js +8 -6
  391. package/dist/postinstall.js +3 -2
  392. package/dist/predictions/planning-fallacy.d.ts +100 -0
  393. package/dist/predictions/planning-fallacy.js +190 -0
  394. package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
  395. package/dist/predictions/store.js +434 -0
  396. package/dist/processes.d.ts +3 -0
  397. package/dist/processes.js +7 -5
  398. package/dist/project-briefs.d.ts +3 -0
  399. package/dist/project-briefs.js +7 -5
  400. package/dist/project-identity.js +3 -2
  401. package/dist/project-merge.js +3 -1
  402. package/dist/quarantine.d.ts +2 -1
  403. package/dist/quarantine.js +8 -5
  404. package/dist/raw-archive.js +1 -1
  405. package/dist/recall-history.js +3 -2
  406. package/dist/recall-pipeline.d.ts +2 -2
  407. package/dist/recall-pipeline.js +16 -8
  408. package/dist/recall-scope.js +1 -1
  409. package/dist/recall-trace.d.ts +1 -1
  410. package/dist/refine-llm.js +2 -1
  411. package/dist/reject-flow.js +6 -1
  412. package/dist/rerankers/clef.js +6 -5
  413. package/dist/rerankers/jev.d.ts +1 -1
  414. package/dist/rerankers/jev.js +4 -4
  415. package/dist/rerankers/llm.d.ts +4 -2
  416. package/dist/rerankers/llm.js +58 -38
  417. package/dist/rerankers/types.d.ts +1 -1
  418. package/dist/salience.js +1 -1
  419. package/dist/scheduler.d.ts +1 -0
  420. package/dist/scheduler.js +26 -4
  421. package/dist/scope.js +4 -3
  422. package/dist/search/as-of.d.ts +10 -0
  423. package/dist/search/as-of.js +22 -0
  424. package/dist/search/bm25-search.d.ts +14 -0
  425. package/dist/search/bm25-search.js +43 -0
  426. package/dist/search/bm25.d.ts +15 -0
  427. package/dist/search/bm25.js +54 -0
  428. package/dist/search/boosts.d.ts +54 -0
  429. package/dist/search/boosts.js +94 -0
  430. package/dist/search/breakdown.d.ts +7 -0
  431. package/dist/search/breakdown.js +20 -0
  432. package/dist/search/explain.d.ts +25 -0
  433. package/dist/search/explain.js +31 -0
  434. package/dist/search/finalize.d.ts +8 -0
  435. package/dist/search/finalize.js +52 -0
  436. package/dist/search/fusion.d.ts +27 -0
  437. package/dist/search/fusion.js +42 -0
  438. package/dist/search/hybrid-score.d.ts +20 -0
  439. package/dist/search/hybrid-score.js +73 -0
  440. package/dist/search/hybrid.d.ts +46 -0
  441. package/dist/search/hybrid.js +64 -0
  442. package/dist/search/physics-search.d.ts +29 -0
  443. package/dist/search/physics-search.js +162 -0
  444. package/dist/search/rerank.d.ts +10 -0
  445. package/dist/search/rerank.js +72 -0
  446. package/dist/search/temporal.d.ts +15 -0
  447. package/dist/search/temporal.js +45 -0
  448. package/dist/search/types.d.ts +91 -0
  449. package/dist/search/types.js +2 -0
  450. package/dist/search/vector.d.ts +30 -0
  451. package/dist/search/vector.js +71 -0
  452. package/dist/secret-detect.d.ts +2 -0
  453. package/dist/secret-detect.js +2 -1
  454. package/dist/server/auth.d.ts +52 -0
  455. package/dist/server/auth.js +221 -0
  456. package/dist/server/client-ip.d.ts +25 -0
  457. package/dist/server/client-ip.js +92 -0
  458. package/dist/server/cursor.d.ts +23 -0
  459. package/dist/server/cursor.js +58 -0
  460. package/dist/server/lifecycle.d.ts +7 -0
  461. package/dist/server/lifecycle.js +29 -0
  462. package/dist/server/mcp-http.d.ts +5 -0
  463. package/dist/server/mcp-http.js +199 -0
  464. package/dist/server/request.d.ts +33 -0
  465. package/dist/server/request.js +103 -0
  466. package/dist/server/routes/admin.d.ts +9 -0
  467. package/dist/server/routes/admin.js +158 -0
  468. package/dist/server/routes/customer-notes.d.ts +7 -0
  469. package/dist/server/routes/customer-notes.js +112 -0
  470. package/dist/server/routes/decisions.d.ts +7 -0
  471. package/dist/server/routes/decisions.js +133 -0
  472. package/dist/server/routes/incidents.d.ts +7 -0
  473. package/dist/server/routes/incidents.js +126 -0
  474. package/dist/server/routes/memories.d.ts +10 -0
  475. package/dist/server/routes/memories.js +179 -0
  476. package/dist/server/routes/policies.d.ts +8 -0
  477. package/dist/server/routes/policies.js +151 -0
  478. package/dist/server/routes/predictions.d.ts +7 -0
  479. package/dist/server/routes/predictions.js +164 -0
  480. package/dist/server/routes/processes.d.ts +7 -0
  481. package/dist/server/routes/processes.js +161 -0
  482. package/dist/server/routes/project-briefs.d.ts +8 -0
  483. package/dist/server/routes/project-briefs.js +136 -0
  484. package/dist/server/routes/recall.d.ts +8 -0
  485. package/dist/server/routes/recall.js +340 -0
  486. package/dist/server/routes/skills.d.ts +8 -0
  487. package/dist/server/routes/skills.js +150 -0
  488. package/dist/server/types.d.ts +56 -0
  489. package/dist/server/types.js +2 -0
  490. package/dist/server/validation.d.ts +14 -0
  491. package/dist/server/validation.js +91 -0
  492. package/dist/server.d.ts +7 -61
  493. package/dist/server.js +69 -2362
  494. package/dist/session-digest.d.ts +1 -1
  495. package/dist/session-digest.js +9 -2
  496. package/dist/shared.d.ts +3 -1
  497. package/dist/shared.js +26 -22
  498. package/dist/skills.d.ts +3 -0
  499. package/dist/skills.js +7 -5
  500. package/dist/stdin.js +2 -2
  501. package/dist/store/audit-event.d.ts +19 -0
  502. package/dist/store/audit-event.js +33 -0
  503. package/dist/store/candidates.d.ts +42 -0
  504. package/dist/store/candidates.js +152 -0
  505. package/dist/store/conflicts.d.ts +44 -0
  506. package/dist/store/conflicts.js +444 -0
  507. package/dist/store/delete-and-batch.d.ts +63 -0
  508. package/dist/store/delete-and-batch.js +310 -0
  509. package/dist/store/entry-reads.d.ts +92 -0
  510. package/dist/store/entry-reads.js +255 -0
  511. package/dist/store/entry-row.d.ts +67 -0
  512. package/dist/store/entry-row.js +208 -0
  513. package/dist/store/entry-writes.d.ts +46 -0
  514. package/dist/store/entry-writes.js +148 -0
  515. package/dist/store/handoffs.d.ts +26 -0
  516. package/dist/store/handoffs.js +184 -0
  517. package/dist/store/index-and-stats.d.ts +52 -0
  518. package/dist/store/index-and-stats.js +214 -0
  519. package/dist/store/markdown.d.ts +10 -0
  520. package/dist/store/markdown.js +108 -0
  521. package/dist/store/mirrors.d.ts +49 -0
  522. package/dist/store/mirrors.js +312 -0
  523. package/dist/store/open.d.ts +15 -0
  524. package/dist/store/open.js +223 -0
  525. package/dist/store/rows.d.ts +178 -0
  526. package/dist/store/rows.js +158 -0
  527. package/dist/store/search-rows.d.ts +86 -0
  528. package/dist/store/search-rows.js +254 -0
  529. package/dist/store/sessions.d.ts +83 -0
  530. package/dist/store/sessions.js +272 -0
  531. package/dist/store/summaries.d.ts +94 -0
  532. package/dist/store/summaries.js +377 -0
  533. package/dist/store/tenant-lookup.d.ts +12 -0
  534. package/dist/store/tenant-lookup.js +16 -0
  535. package/dist/store-cards.js +2 -1
  536. package/dist/summary-dirty.d.ts +4 -0
  537. package/dist/summary-dirty.js +32 -0
  538. package/dist/support-bundle.js +4 -3
  539. package/dist/tenant.js +2 -2
  540. package/dist/tokenize.d.ts +2 -0
  541. package/dist/tokenize.js +16 -0
  542. package/dist/transcript-tail.d.ts +7 -0
  543. package/dist/transcript-tail.js +48 -0
  544. package/dist/vector-store.d.ts +27 -0
  545. package/dist/vector-store.js +210 -0
  546. package/dist/version.d.ts +2 -2
  547. package/dist/version.js +2 -2
  548. package/dist/working-memory.js +1 -1
  549. package/dist/yaml.js +36 -11
  550. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  551. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  552. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  553. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  554. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  555. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  556. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  557. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  558. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  559. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  560. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  561. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  562. package/dist-ui/assets/index-DPN7cP19.js +33 -0
  563. package/dist-ui/assets/index-dFloKRVr.css +1 -0
  564. package/dist-ui/index.html +3 -25
  565. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  566. package/extensions/openclaw-plugin/package.json +1 -1
  567. package/openclaw.plugin.json +1 -1
  568. package/package.json +1 -1
  569. package/dist/capture.d.ts +0 -155
  570. package/dist/capture.js +0 -1295
  571. package/dist/consolidate.d.ts +0 -58
  572. package/dist/consolidate.js +0 -1124
  573. package/dist/graph.d.ts +0 -245
  574. package/dist/hooks.d.ts +0 -208
  575. package/dist/hooks.js +0 -1076
  576. package/dist/importers.js +0 -900
  577. package/dist/predictions.js +0 -620
  578. package/dist/search.d.ts +0 -320
  579. package/dist/search.js +0 -970
  580. package/dist/store.d.ts +0 -776
  581. package/dist/store.js +0 -3473
  582. package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
  583. package/dist-ui/assets/index-BhT8RvO6.js +0 -61
  584. package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
  585. package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
@@ -0,0 +1,464 @@
1
+ /**
2
+ * Capture actionable items from conversation text.
3
+ *
4
+ * Uses heuristic pattern matching (no LLM) to extract:
5
+ * - Decisions ("we decided", "let's do", "going with")
6
+ * - Specs / requirements (bullet lists after spec/feature/plan headings)
7
+ * - Rules / constraints ("never", "always", "the rule is", "must")
8
+ * - Errors / gotchas ("error:", "bug:", "gotcha:", "watch out")
9
+ * - Preferences ("prefer", "use X instead of Y", "don't use")
10
+ */
11
+ import { duplicateKey } from '../same-text.js';
12
+ import { isContentWorthStoring } from '../audit.js';
13
+ // Sentence-level patterns
14
+ //
15
+ // T1 (DF2): each pattern now carries TWO capture groups — group 1 is the
16
+ // discriminating keyword (plus its trailing separator, verbatim), group 2 is
17
+ // the content that follows it. Previously only the after-keyword content was
18
+ // captured, so a negation like "never" / "must not" was discarded and a
19
+ // prohibition inverted into an instruction ("Never use X" stored as "use X").
20
+ // `extractFromPatterns` reassembles group1 + a clause-bounded group2 (T2, via
21
+ // `boundToClause` below) rather than reading a single fixed-width group —
22
+ // group 2's own reach is widened to {1,500} because the true stopping point
23
+ // is now found by content, not counted characters. Keeping the keyword in
24
+ // its own group (rather than folding it into one bigger capture) matters:
25
+ // `boundToClause` must scan for a clause boundary only in group 2, never in
26
+ // group 1 — several keywords end in their own colon ("error:", "rule:",
27
+ // "decision:") which is not a clause boundary in the prose sense and would
28
+ // wrongly truncate the capture down to just the keyword if scanned.
29
+ // `PREFERENCE_PATTERNS[0]` is the one exception — its two-capture-group
30
+ // shape means something different (two content spans either side of
31
+ // "instead of"/"over"/"not") and is a separate, backlogged defect (see
32
+ // docs/plans/2026-08-23-df2-capture-anchoring.md); left as-is.
33
+ const DECISION_PATTERNS = [
34
+ /(?:we(?:'ve| have)?|i(?:'ve| have)?|let's)\s+(decid(?:ed|e)\s+(?:to\s+)?)(.{1,500})/i,
35
+ /(?:let's|we(?:'ll| will| should)?)\s+((?:go with|do|use|try|build|implement|switch to)\s+)(.{1,500})/i,
36
+ /((?:going|went)\s+with\s+)(.{1,500})/i,
37
+ /((?:the plan is|plan:)\s+)(.{1,500})/i,
38
+ /(decision:\s*)(.{1,500})/i,
39
+ ];
40
+ const RULE_PATTERNS = [
41
+ /\b((?:never|always|must(?:\s+not)?|do(?:n't| not)\s+ever)\s+)(.{1,500})/i,
42
+ /((?:the rule is|rule:)\s*)(.{1,500})/i,
43
+ /((?:important|critical|remember):\s*)(.{1,500})/i,
44
+ /((?:make sure|ensure)\s+(?:to\s+)?)(.{1,500})/i,
45
+ ];
46
+ const ERROR_PATTERNS = [
47
+ /((?:error|bug|gotcha|watch out|careful|warning|caveat|trap):\s*)(.{1,500})/i,
48
+ /((?:this broke|this breaks|this will break|broke because)\s+)(.{1,500})/i,
49
+ /((?:the (?:issue|problem|fix) (?:is|was))\s+)(.{1,500})/i,
50
+ /((?:don't forget|easy to miss):\s*)(.{1,500})/i,
51
+ ];
52
+ // PREFERENCE_PATTERNS[0] keeps its pre-DF2 two-capture-group shape
53
+ // (match[1]-only, unbounded) — out of scope here, backlogged. See
54
+ // extractFromPatterns' reference check against this exact array element.
55
+ const PREFERENCE_PATTERNS = [
56
+ /(?:prefer|use)\s+(.{5,100})\s+(?:instead of|over|not)\s+(.{3,100})/i,
57
+ /((?:don't use|avoid|skip)\s+)(.{1,500})/i,
58
+ /((?:we(?:'re| are)\s+using|the stack is|we use)\s+)(.{1,500})/i,
59
+ ];
60
+ // Heading patterns that signal a following list of specs/requirements
61
+ const SPEC_HEADING_PATTERNS = [
62
+ /^#+\s*(?:features?|requirements?|specs?|specifications?|plan|design|architecture|interface|api|todo|tasks?|implementation|notes?)(?:\s|:|$)/i,
63
+ /^(?:features?|requirements?|specs?|specifications?|plan|design|tasks?|implementation)(?:\s*:|$)/i,
64
+ ];
65
+ // ---------------------------------------------------------------------------
66
+ // Extraction engine
67
+ // ---------------------------------------------------------------------------
68
+ export function splitSentences(text) {
69
+ // Split on sentence boundaries, keeping reasonable chunks
70
+ return text
71
+ .split(/(?<=[.!?])\s+|\n/)
72
+ .map((s) => s.trim())
73
+ .filter((s) => s.length > 5);
74
+ }
75
+ /**
76
+ * T2 (DF2): bound a keyword+content capture to its clause instead of a fixed
77
+ * character count. `full` is `keywordPrefix + content` (already concatenated
78
+ * so the 200-char ceiling below applies to the whole stored string, not just
79
+ * the part after the keyword); `searchFrom` is `keywordPrefix.length`, so the
80
+ * clause/terminator scan only ever looks INSIDE `content` — several keywords
81
+ * end in their own colon ("error:", "rule:", "decision:") which must never
82
+ * be mistaken for a clause boundary in the prose that follows.
83
+ *
84
+ * Stops at the first `,`/`;`/`:` followed by whitespace, or at a sentence
85
+ * terminator `[.!?]` followed by whitespace or end-of-string — whichever
86
+ * comes first — and never past `maxLen` chars total.
87
+ *
88
+ * The whitespace requirement on the terminator is load-bearing: a bare
89
+ * `[.!?]` would split inside a token like `.env` / `capture.ts` / `v1.35.0`,
90
+ * turning a full clause into a fragment that then fails the write gate and
91
+ * is silently dropped (measured in the plan). The `maxLen` ceiling is also
92
+ * load-bearing: without it, a clause-free span can run past the 500-char
93
+ * gate in `extractFromPatterns` and the whole match is dropped, where today
94
+ * it is truncated and stored.
95
+ */
96
+ /**
97
+ * Does a plausible CLOSING single quote appear after `from`? Mirror of the
98
+ * opener rule in `boundToClause`: a closer sits tight against the literal it
99
+ * ends (non-whitespace before) and is followed by whitespace, punctuation, or
100
+ * end-of-string - never by a letter, which is what makes "user's" an
101
+ * apostrophe rather than a partner.
102
+ */
103
+ function isLetterOrDigit(ch) {
104
+ return ch !== undefined && /[\p{L}\p{N}]/u.test(ch);
105
+ }
106
+ function lastCloserIndex(full) {
107
+ // ONE pass, not one per apostrophe. The previous shape rescanned the whole
108
+ // remaining suffix at every boundary apostrophe, so a transcript full of
109
+ // elisions ("keep 'em", "wait 'til", ...) made extraction quadratic and
110
+ // could stall a moderately sized capture. Codex P2, r7.
111
+ //
112
+ // A quote CLOSES THE SIDE IT IS TIGHT AGAINST. The test needs both
113
+ // neighbours, and one round proved that empirically: these two have the
114
+ // same following character and opposite roles -
115
+ // "preserve 'a, b'-style" next '-' -> CLOSER, content on the left
116
+ // "then run '--force," next '-' -> OPENER, content on the right
117
+ // so no forward-only rule can separate them. An earlier revision tried
118
+ // exactly that and broke in both directions at once (codex P1+P2, r10):
119
+ // it missed closers before token-joining punctuation and accepted
120
+ // "'.env" as a closer because a dot happened to be in its class.
121
+ //
122
+ // never a closer next is a letter/digit "user's", "keep 'em"
123
+ // closer prev is non-whitespace "'a, b' to", "'a, b'-style"
124
+ // closer next is whitespace or end "preserve 'a, b ' exactly"
125
+ // closer next is clause punctuation "preserve 'a, b ', then"
126
+ // that itself ends the token
127
+ //
128
+ // The last clause is what separates ", " from ".env": a dot followed by a
129
+ // letter joins a filename, a dot followed by space ends a sentence.
130
+ for (let j = full.length - 1; j >= 0; j--) {
131
+ if (full[j] !== "'")
132
+ continue;
133
+ const prev = full[j - 1];
134
+ const next = full[j + 1];
135
+ if (isLetterOrDigit(next))
136
+ continue;
137
+ // "tight against content" excludes an OPENING delimiter: in
138
+ // "call parse('--force" the paren is non-whitespace but the quote after
139
+ // it is an opener, and treating it as a closer let an earlier elision
140
+ // pair across the clause boundary. Codex P2, r11.
141
+ const tightBefore = prev !== undefined && !/[\s([{]/.test(prev);
142
+ const endsAfter = next === undefined || /\s/.test(next);
143
+ // Punctuation splits in two, and this is the fact the last three
144
+ // revisions kept rediscovering piecemeal:
145
+ // , ; : ! ? ) ] } never join tokens - they end the literal whatever
146
+ // follows, so "'echo a, b ';then" closes at the ;
147
+ // . - _ / @ # DO join tokens - "'.env" and "'--force" continue a
148
+ // filename or flag, so these only close when trailed
149
+ // by whitespace
150
+ const afterNext = full[j + 2];
151
+ const closesRegardless = next !== undefined && /[,;:!?)\]}]/.test(next);
152
+ const joinerThenSpace = next !== undefined && /[.\-_/@#]/.test(next) &&
153
+ (afterNext === undefined || /\s/.test(afterNext));
154
+ if (tightBefore || endsAfter || closesRegardless || joinerThenSpace)
155
+ return j;
156
+ }
157
+ return -1;
158
+ }
159
+ function boundToClause(full, searchFrom, maxLen = 200) {
160
+ // Scan for the first PROSE clause boundary after `searchFrom`.
161
+ //
162
+ // Depth-awareness is not a nicety here: hippo memories are full of code, and
163
+ // a naive scan reintroduces the exact fragment defect this whole change
164
+ // exists to remove. Measured before this guard existed:
165
+ // "Always call build(x, y) before deploy." -> "Always call build(x"
166
+ // "Never pass {a: 1, b: 2} to the writer." -> "Never pass {a"
167
+ // Both then PASS the write gate, because they contain code punctuation and
168
+ // so read as "specific" — a malformed fragment stored with high confidence.
169
+ // Codex review finding (P1) on this branch.
170
+ //
171
+ // So: a separator only ends the clause at bracket depth zero and outside
172
+ // quotes. Unbalanced closers are tolerated (depth floors at 0) because
173
+ // captured text often starts mid-expression.
174
+ const lastCloser = lastCloserIndex(full);
175
+ let depth = 0;
176
+ let quote = null;
177
+ let cutEnd = full.length;
178
+ for (let i = searchFrom; i < full.length; i++) {
179
+ const ch = full[i];
180
+ if (quote) {
181
+ if (closesQuote(full, i, quote))
182
+ quote = null;
183
+ continue;
184
+ }
185
+ if (ch === '"' || ch === '`') {
186
+ quote = ch;
187
+ continue;
188
+ }
189
+ if (ch === "'") {
190
+ if (opensSingleQuote(full, i, lastCloser)) {
191
+ quote = ch;
192
+ }
193
+ continue;
194
+ }
195
+ if (ch === '(' || ch === '[' || ch === '{') {
196
+ depth++;
197
+ continue;
198
+ }
199
+ if (ch === ')' || ch === ']' || ch === '}') {
200
+ if (depth > 0)
201
+ depth--;
202
+ continue;
203
+ }
204
+ if (depth > 0)
205
+ continue;
206
+ const next = full[i + 1];
207
+ // Prose clause separator: , ; : followed by whitespace.
208
+ if ((ch === ',' || ch === ';' || ch === ':') && next !== undefined && /\s/.test(next)) {
209
+ cutEnd = i;
210
+ break;
211
+ }
212
+ // Sentence terminator, but only when followed by whitespace or end — a
213
+ // bare [.!?] splits inside .env, capture.ts, v1.35.0.
214
+ if ((ch === '.' || ch === '!' || ch === '?') && (next === undefined || /\s/.test(next))) {
215
+ cutEnd = i + 1;
216
+ break;
217
+ }
218
+ }
219
+ let bounded = full.slice(0, cutEnd);
220
+ if (bounded.length > maxLen)
221
+ bounded = bounded.slice(0, maxLen);
222
+ return bounded;
223
+ }
224
+ function closesQuote(full, i, quote) {
225
+ // Closing uses the SAME shape test as opening. This was asymmetric:
226
+ // twelve rounds went into deciding when a quote OPENS a literal, while
227
+ // the close accepted any bare "'" - so the apostrophe in a possessive
228
+ // INSIDE a literal closed it early:
229
+ // "Always pass 'user's a, b list' to the parser."
230
+ // -> "Always pass 'user's a" (master kept the whole literal)
231
+ // a mid-literal fragment that then PASSES the write gate, which is
232
+ // precisely the defect this branch exists to remove. Found by the
233
+ // ship-gate review after every earlier gate missed it.
234
+ return full[i] === quote && (quote !== "'" || !isLetterOrDigit(full[i + 1]));
235
+ }
236
+ function opensSingleQuote(full, i, lastCloser) {
237
+ // Quote handling has to tell an APOSTROPHE from a single-quoted
238
+ // LITERAL, because getting either wrong reintroduces the fragment
239
+ // defect this change exists to remove, and both fragments PASS the
240
+ // write gate (code punctuation reads as "specific"):
241
+ // treat every ' as a quote -> "Always ensure it's enabled, then
242
+ // restart..." never leaves quote mode, bounding disabled entirely
243
+ // treat no ' as a quote -> "Always pass 'a, b' to the parser."
244
+ // cuts at the comma and stores "Always pass 'a"
245
+ // Both were codex P1s on this branch, in consecutive rounds.
246
+ //
247
+ // Discriminator: a ' OPENS a literal only at a word boundary - preceded
248
+ // by start/whitespace/open-bracket AND followed by non-whitespace. An
249
+ // in-word apostrophe ("it's", "user's") has letters on both sides and is
250
+ // just a character.
251
+ const prev = i > 0 ? full[i - 1] : undefined;
252
+ const next = full[i + 1];
253
+ const atBoundary = (prev === undefined || /[\s([{]/.test(prev)) &&
254
+ next !== undefined && !/\s/.test(next);
255
+ // Pairing is VERIFIED, not assumed. A word-boundary test alone still
256
+ // opens quote mode on elided forms ("keep 'em", "wait 'til"), which
257
+ // have no closer, so the scanner never leaves quote mode and bounding
258
+ // is disabled for the rest of the capture. Requiring an actual closing
259
+ // quote later in the string replaces a guess with a checkable fact -
260
+ // an elided form simply has no partner. Codex P2, this round.
261
+ // ...and the partner must LOOK like a closer, not merely be another
262
+ // apostrophe. Distance cannot separate the two cases - both put a `'`
263
+ // far downstream:
264
+ // "Always pass '<600-char literal>' to the parser" -> the far ' IS
265
+ // the closer, and pairing must succeed
266
+ // "keep 'em enabled, then <520 chars> check user's config" -> the far
267
+ // ' is in-word, and pairing against it re-opens quote mode on the
268
+ // elision, disabling bounding for the rest of the capture
269
+ // So apply the SAME shape rule already used to open a literal, mirrored:
270
+ // a closer has non-whitespace before it and whitespace/punctuation (not
271
+ // a letter) after. "user's" fails it on both counts. Codex P2, r6.
272
+ return atBoundary && lastCloser > i;
273
+ }
274
+ function cleanExtract(raw) {
275
+ let content = raw
276
+ .replace(/^[:\s-]+/, '')
277
+ .replace(/[.!?,;:\s]+$/, '')
278
+ .trim();
279
+ // T2 trailing cleanup: clause-bounding can cut inside a parenthetical and
280
+ // leave an unmatched trailing ')' (e.g. "...(two had never got entries),"
281
+ // bounds to "never got entries)"). Strip a trailing ')' ONLY while closes
282
+ // outnumber opens in the string so far — a balanced parenthetical like
283
+ // "always run the suite (twice)" must be left intact.
284
+ while (content.endsWith(')')) {
285
+ const opens = (content.match(/\(/g) ?? []).length;
286
+ const closes = (content.match(/\)/g) ?? []).length;
287
+ if (closes <= opens)
288
+ break;
289
+ content = content
290
+ .slice(0, -1)
291
+ .replace(/[.!?,;:\s]+$/, '')
292
+ .trim();
293
+ }
294
+ return content;
295
+ }
296
+ /** The 500-char write gate minus the 200-char bound counted from the keyword. */
297
+ const RULE_LEAD_CAP = 300;
298
+ /** A modal rule keeps its subject ("We must never ..."); null keeps the keyword-start form when the lead is long or the keyword sits inside a bracket. */
299
+ function ruleLead(sentence, keywordStart, contentStart) {
300
+ if (keywordStart < 0 || contentStart < 0 || contentStart > RULE_LEAD_CAP)
301
+ return null;
302
+ let depth = 0;
303
+ for (const ch of sentence.slice(0, keywordStart)) {
304
+ if (ch === '(' || ch === '[' || ch === '{')
305
+ depth++;
306
+ else if ((ch === ')' || ch === ']' || ch === '}') && depth > 0)
307
+ depth--;
308
+ }
309
+ return depth > 0 ? null : sentence.slice(0, contentStart);
310
+ }
311
+ function extractFromPatterns(sentence, patterns, category, tag) {
312
+ for (const pat of patterns) {
313
+ // `d` gives per-group offsets; see the contentStart comment below.
314
+ const dpat = pat.flags.includes('d') ? pat : new RegExp(pat.source, pat.flags + 'd');
315
+ const match = dpat.exec(sentence);
316
+ if (match) {
317
+ let bounded;
318
+ if (pat === PREFERENCE_PATTERNS[0]) {
319
+ // PREFERENCE_PATTERNS[0] is the one pattern left out of T1/T2 (see
320
+ // comment at its definition) — its match[1] keeps its pre-DF2,
321
+ // unbounded shape rather than going through clause-bounding.
322
+ bounded = match[1] ?? match[0];
323
+ }
324
+ else {
325
+ // group1 = keyword + separator (verbatim, never clause-bounded);
326
+ // group2 = the content that follows it (clause-bounded below).
327
+ //
328
+ // T1 preserves the keyword only when it carries SEMANTIC SIGN — a
329
+ // negation or modality ("never", "must not", "do not ever",
330
+ // "always"). Dropping those inverts the meaning, which is the whole
331
+ // point of T1. A LABEL keyword ("decision:", "rule:", "error:",
332
+ // "important:") carries no sign: it only names the category, which
333
+ // is already recorded in `category`/`tags`, so prefixing it onto the
334
+ // content is duplication that also breaks value-keyed matching
335
+ // (AT1's rejected-value digest hashes the bare content).
336
+ // Discriminator: a label ends in its own colon, or is a "the X is"
337
+ // phrase.
338
+ const rawPrefix = match[1] ?? '';
339
+ // ONLY colon-terminated labels are dropped. Dropping "the X is/was"
340
+ // too left the residue starting with "to ", which isFragment then
341
+ // rejected outright - so "The plan is to ship on Friday" and "The fix
342
+ // was to bump the pool timeout" stored NOTHING, where every prior
343
+ // version stored them. Silent loss on two of the highest-traffic
344
+ // patterns, and invisible: an absent memory leaves no trace. The AT1
345
+ // rejected-value evidence only ever involved colon labels
346
+ // ("decision: "), so the narrower rule keeps that guarantee.
347
+ const isLabelPrefix = /:\s*$/.test(rawPrefix);
348
+ const keywordPrefix = isLabelPrefix ? '' : rawPrefix;
349
+ // Scan the UNTRUNCATED remainder, not match[2]. The patterns cap
350
+ // their content group at 500 chars, so a quoted literal whose closer
351
+ // sits past that point had no visible partner and the pairing check
352
+ // read the opener as prose - cutting inside the literal. That was a
353
+ // blindness built into the scanner's INPUT, not a bad predicate, so
354
+ // no further predicate could have fixed it. boundToClause already
355
+ // caps its OUTPUT at maxLen, so widening the input costs nothing and
356
+ // makes pairing decidable on the whole sentence. Codex P2, round 5.
357
+ // Group 2's REAL offset, read from the regex engine. Deriving it as
358
+ // `match.index + rawPrefix.length` assumes group 1 starts the match,
359
+ // but DECISION_PATTERNS carry an uncaptured subject ("we ", "let's ")
360
+ // ahead of it - so the offset landed inside the keyword and the
361
+ // widened slice duplicated text: "We decided to pin..." stored as
362
+ // "decided to to pin...". Real corruption of the commonest decision
363
+ // capture, shipped in the previous commit. Codex P1, r6.
364
+ const contentStart = match.indices?.[2]?.[0] ?? -1;
365
+ const afterKeyword = contentStart >= 0 ? sentence.slice(contentStart) : (match[2] ?? match[0]);
366
+ const keywordStart = match.indices?.[1]?.[0] ?? -1;
367
+ const lead = pat === RULE_PATTERNS[0] ? ruleLead(sentence, keywordStart, contentStart) : null;
368
+ bounded = lead !== null
369
+ ? boundToClause(lead + afterKeyword, lead.length, keywordStart + 200)
370
+ : boundToClause(keywordPrefix + afterKeyword, keywordPrefix.length);
371
+ }
372
+ const content = cleanExtract(bounded);
373
+ if (content.length >= 8 && content.length <= 500) {
374
+ return { content, category, tags: [tag, 'captured'] };
375
+ }
376
+ }
377
+ }
378
+ return null;
379
+ }
380
+ /** Extract spec items from bullet lists that follow spec-like headings. */
381
+ function extractSpecSections(text) {
382
+ const items = [];
383
+ const lines = text.split('\n');
384
+ let inSpecSection = false;
385
+ for (const line of lines) {
386
+ const trimmed = line.trim();
387
+ // Check if this line is a spec heading
388
+ if (SPEC_HEADING_PATTERNS.some((p) => p.test(trimmed))) {
389
+ inSpecSection = true;
390
+ continue;
391
+ }
392
+ // Another heading resets the section
393
+ if (/^#+\s/.test(trimmed) || /^[A-Z][a-z]+:$/.test(trimmed)) {
394
+ inSpecSection = false;
395
+ continue;
396
+ }
397
+ // Blank line after non-bullet content ends section
398
+ if (!trimmed && inSpecSection) {
399
+ // Keep going, blank lines within spec sections are ok
400
+ continue;
401
+ }
402
+ if (inSpecSection) {
403
+ const bulletMatch = trimmed.match(/^[-*]\s+(.+)/) || trimmed.match(/^\d+\.\s+(.+)/);
404
+ if (bulletMatch) {
405
+ const content = bulletMatch[1].trim();
406
+ if (content.length >= 8 && content.length <= 500) {
407
+ items.push({
408
+ content,
409
+ category: 'spec',
410
+ tags: ['spec', 'captured'],
411
+ });
412
+ }
413
+ }
414
+ }
415
+ }
416
+ return items;
417
+ }
418
+ /**
419
+ * Main extraction function. Scans text for actionable items using heuristics.
420
+ */
421
+ export function extractFromText(text) {
422
+ const items = [];
423
+ const seen = new Set();
424
+ const addIfNew = (item) => {
425
+ const norm = duplicateKey(item.content);
426
+ if (seen.has(norm))
427
+ return;
428
+ if (!isContentWorthStoring(item.content))
429
+ return;
430
+ seen.add(norm);
431
+ items.push(item);
432
+ };
433
+ // 1. Extract spec sections (bullet lists under spec headings)
434
+ for (const item of extractSpecSections(text)) {
435
+ addIfNew(item);
436
+ }
437
+ // 2. Pattern-match on individual sentences
438
+ const sentences = splitSentences(text);
439
+ for (const sentence of sentences) {
440
+ // Try each category in priority order
441
+ const decision = extractFromPatterns(sentence, DECISION_PATTERNS, 'decision', 'decision');
442
+ if (decision) {
443
+ addIfNew(decision);
444
+ continue;
445
+ }
446
+ const rule = extractFromPatterns(sentence, RULE_PATTERNS, 'rule', 'rule');
447
+ if (rule) {
448
+ addIfNew(rule);
449
+ continue;
450
+ }
451
+ const error = extractFromPatterns(sentence, ERROR_PATTERNS, 'error', 'error');
452
+ if (error) {
453
+ addIfNew(error);
454
+ continue;
455
+ }
456
+ const preference = extractFromPatterns(sentence, PREFERENCE_PATTERNS, 'preference', 'preference');
457
+ if (preference) {
458
+ addIfNew(preference);
459
+ continue;
460
+ }
461
+ }
462
+ return items;
463
+ }
464
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1,40 @@
1
+ /** Transcript-line flags isNonHumanUserLine reads (any may be absent); `promptSource: 'system'` marks Claude Code's own notices. */
2
+ interface TranscriptLineFlags {
3
+ type?: unknown;
4
+ isMeta?: unknown;
5
+ isSidechain?: unknown;
6
+ isCompactSummary?: unknown;
7
+ promptSource?: unknown;
8
+ }
9
+ interface TranscriptMessage {
10
+ content?: unknown;
11
+ }
12
+ /** The human's words on a Claude Code user line, '' when none; VS Code stores prompts as text blocks, beside its own open-file, selection and interrupt blocks. */
13
+ export declare function humanUserText(entry: TranscriptLineFlags, message: TranscriptMessage): string;
14
+ export interface SessionTurn {
15
+ role: 'user' | 'assistant';
16
+ text: string;
17
+ }
18
+ export interface TranscriptRecord extends TranscriptLineFlags {
19
+ message?: unknown;
20
+ payload?: unknown;
21
+ cwd?: unknown;
22
+ }
23
+ export declare function collectSessionTurns(jsonl: string, visit?: (record: TranscriptRecord) => void): SessionTurn[];
24
+ export declare function summariseTranscript(jsonl: string): string;
25
+ export declare function summariseSessionTurns(turns: readonly SessionTurn[]): string;
26
+ /**
27
+ * Resolve a transcript path for `--last-session`.
28
+ *
29
+ * Priority, where the first source present is the only one tried:
30
+ * 1. Explicit `transcriptPath` option (from `--transcript <path>`)
31
+ * 2. Stdin JSON payload (Claude Code / OpenCode SessionEnd hook shape)
32
+ * 3. Most recent `.jsonl` under `~/.claude/projects/<any>/`, only when the caller passes `mayScan` (only the caller knows it is not a hook) and there is no path and no stdin text, because this scan spans every project on the box
33
+ *
34
+ * Returns null when nothing resolves, a named transcript or payload whose file is missing included. Never throws.
35
+ */
36
+ export declare function resolveLastSessionTranscript(explicit: string | undefined, stdinText: string | undefined, opts: {
37
+ mayScan: boolean;
38
+ }): string | null;
39
+ export {};
40
+ //# sourceMappingURL=transcript.d.ts.map