@monoes/monomindcli 2.14.0 → 2.15.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 (291) hide show
  1. package/.claude/helpers/control-start.cjs +10 -13
  2. package/.claude/skills/monodesign/scripts/context.mjs +5 -5
  3. package/.claude/skills/monodesign/scripts/critique-storage.mjs +1 -1
  4. package/.claude/skills/monodesign/scripts/detect-csp.mjs +1 -6
  5. package/.claude/skills/monodesign/scripts/detector/browser/injected/index.mjs +16 -18
  6. package/.claude/skills/monodesign/scripts/detector/cli/main.mjs +3 -3
  7. package/.claude/skills/monodesign/scripts/detector/detect-antipatterns-browser.js +69 -49
  8. package/.claude/skills/monodesign/scripts/detector/engines/regex/detect-text.mjs +6 -6
  9. package/.claude/skills/monodesign/scripts/detector/engines/static-html/css-cascade.mjs +6 -5
  10. package/.claude/skills/monodesign/scripts/detector/engines/static-html/detect-html.mjs +6 -6
  11. package/.claude/skills/monodesign/scripts/detector/fix/index.mjs +3 -3
  12. package/.claude/skills/monodesign/scripts/detector/node/file-system.mjs +1 -1
  13. package/.claude/skills/monodesign/scripts/detector/registry/antipatterns.mjs +1 -1
  14. package/.claude/skills/monodesign/scripts/detector/rules/checks.mjs +26 -27
  15. package/.claude/skills/monodesign/scripts/detector/shared/color.mjs +2 -2
  16. package/.claude/skills/monodesign/scripts/detector/shared/constants.mjs +1 -1
  17. package/.claude/skills/monodesign/scripts/detector/shared/inline-ignores.mjs +2 -2
  18. package/.claude/skills/monodesign/scripts/hook-admin.mjs +6 -6
  19. package/.claude/skills/monodesign/scripts/hook-before-edit.mjs +4 -4
  20. package/.claude/skills/monodesign/scripts/hook-lib.mjs +20 -11
  21. package/.claude/skills/monodesign/scripts/hook.mjs +1 -1
  22. package/.claude/skills/monodesign/scripts/lib/design-parser.mjs +9 -42
  23. package/.claude/skills/monodesign/scripts/lib/is-generated.mjs +1 -1
  24. package/.claude/skills/monodesign/scripts/lib/monodesign-config.mjs +5 -5
  25. package/.claude/skills/monodesign/scripts/lib/monodesign-paths.mjs +1 -1
  26. package/.claude/skills/monodesign/scripts/live/event-validation.mjs +13 -13
  27. package/.claude/skills/monodesign/scripts/live/manual-apply.mjs +4 -4
  28. package/.claude/skills/monodesign/scripts/live/manual-edits-buffer.mjs +1 -1
  29. package/.claude/skills/monodesign/scripts/live/session-store.mjs +5 -5
  30. package/.claude/skills/monodesign/scripts/live/svelte-component.mjs +13 -13
  31. package/.claude/skills/monodesign/scripts/live/sveltekit-adapter.mjs +4 -4
  32. package/.claude/skills/monodesign/scripts/live/ui-core.mjs +1 -1
  33. package/.claude/skills/monodesign/scripts/live-accept.mjs +24 -24
  34. package/.claude/skills/monodesign/scripts/live-browser-dom.js +8 -7
  35. package/.claude/skills/monodesign/scripts/live-browser-session.js +8 -7
  36. package/.claude/skills/monodesign/scripts/live-browser.js +406 -433
  37. package/.claude/skills/monodesign/scripts/live-commit-manual-edits.mjs +6 -6
  38. package/.claude/skills/monodesign/scripts/live-copy-edit-agent.mjs +2 -2
  39. package/.claude/skills/monodesign/scripts/live-discard-manual-edits.mjs +1 -1
  40. package/.claude/skills/monodesign/scripts/live-inject.mjs +7 -7
  41. package/.claude/skills/monodesign/scripts/live-insert.mjs +11 -11
  42. package/.claude/skills/monodesign/scripts/live-manual-edit-evidence.mjs +4 -4
  43. package/.claude/skills/monodesign/scripts/live-poll.mjs +5 -5
  44. package/.claude/skills/monodesign/scripts/live-server.mjs +10 -10
  45. package/.claude/skills/monodesign/scripts/live-wrap.mjs +31 -41
  46. package/.claude/skills/monodesign/scripts/live.mjs +5 -5
  47. package/.claude/skills/monodesign/scripts/palette.mjs +3 -1
  48. package/.claude/skills/monodesign/scripts/pin.mjs +1 -1
  49. package/bin/cli.js +21 -1
  50. package/bin/mcp-server.js +21 -1
  51. package/dist/src/capabilities/cap-documents.d.ts.map +1 -1
  52. package/dist/src/capabilities/cap-documents.js +23 -0
  53. package/dist/src/capabilities/cap-documents.js.map +1 -1
  54. package/dist/src/commands/doc-filters.d.ts +19 -0
  55. package/dist/src/commands/doc-filters.d.ts.map +1 -0
  56. package/dist/src/commands/doc-filters.js +64 -0
  57. package/dist/src/commands/doc-filters.js.map +1 -0
  58. package/dist/src/commands/doc-library.d.ts +22 -0
  59. package/dist/src/commands/doc-library.d.ts.map +1 -0
  60. package/dist/src/commands/doc-library.js +454 -0
  61. package/dist/src/commands/doc-library.js.map +1 -0
  62. package/dist/src/commands/doc-list.d.ts +9 -0
  63. package/dist/src/commands/doc-list.d.ts.map +1 -0
  64. package/dist/src/commands/doc-list.js +99 -0
  65. package/dist/src/commands/doc-list.js.map +1 -0
  66. package/dist/src/commands/doc.d.ts.map +1 -1
  67. package/dist/src/commands/doc.js +51 -37
  68. package/dist/src/commands/doc.js.map +1 -1
  69. package/dist/src/commands/ui.d.ts.map +1 -1
  70. package/dist/src/commands/ui.js +60 -0
  71. package/dist/src/commands/ui.js.map +1 -1
  72. package/dist/src/knowledge/capture-envelope.d.ts +85 -0
  73. package/dist/src/knowledge/capture-envelope.d.ts.map +1 -0
  74. package/dist/src/knowledge/capture-envelope.js +167 -0
  75. package/dist/src/knowledge/capture-envelope.js.map +1 -0
  76. package/dist/src/knowledge/capture-text.d.ts +23 -0
  77. package/dist/src/knowledge/capture-text.d.ts.map +1 -0
  78. package/dist/src/knowledge/capture-text.js +49 -0
  79. package/dist/src/knowledge/capture-text.js.map +1 -0
  80. package/dist/src/knowledge/citation.d.ts +121 -0
  81. package/dist/src/knowledge/citation.d.ts.map +1 -0
  82. package/dist/src/knowledge/citation.js +252 -0
  83. package/dist/src/knowledge/citation.js.map +1 -0
  84. package/dist/src/knowledge/document-chunking.d.ts +42 -0
  85. package/dist/src/knowledge/document-chunking.d.ts.map +1 -0
  86. package/dist/src/knowledge/document-chunking.js +288 -0
  87. package/dist/src/knowledge/document-chunking.js.map +1 -0
  88. package/dist/src/knowledge/document-index.d.ts +124 -0
  89. package/dist/src/knowledge/document-index.d.ts.map +1 -0
  90. package/dist/src/knowledge/document-index.js +314 -0
  91. package/dist/src/knowledge/document-index.js.map +1 -0
  92. package/dist/src/knowledge/document-ingest.d.ts +23 -0
  93. package/dist/src/knowledge/document-ingest.d.ts.map +1 -0
  94. package/dist/src/knowledge/document-ingest.js +368 -0
  95. package/dist/src/knowledge/document-ingest.js.map +1 -0
  96. package/dist/src/knowledge/document-pipeline.d.ts +26 -148
  97. package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
  98. package/dist/src/knowledge/document-pipeline.js +25 -920
  99. package/dist/src/knowledge/document-pipeline.js.map +1 -1
  100. package/dist/src/knowledge/document-search.d.ts +27 -0
  101. package/dist/src/knowledge/document-search.d.ts.map +1 -0
  102. package/dist/src/knowledge/document-search.js +138 -0
  103. package/dist/src/knowledge/document-search.js.map +1 -0
  104. package/dist/src/knowledge/document-store.d.ts +28 -0
  105. package/dist/src/knowledge/document-store.d.ts.map +1 -0
  106. package/dist/src/knowledge/document-store.js +61 -0
  107. package/dist/src/knowledge/document-store.js.map +1 -0
  108. package/dist/src/knowledge/document-types.d.ts +103 -0
  109. package/dist/src/knowledge/document-types.d.ts.map +1 -0
  110. package/dist/src/knowledge/document-types.js +12 -0
  111. package/dist/src/knowledge/document-types.js.map +1 -0
  112. package/dist/src/knowledge/highlights.d.ts +168 -0
  113. package/dist/src/knowledge/highlights.d.ts.map +1 -0
  114. package/dist/src/knowledge/highlights.js +311 -0
  115. package/dist/src/knowledge/highlights.js.map +1 -0
  116. package/dist/src/knowledge/html-extract.d.ts +43 -0
  117. package/dist/src/knowledge/html-extract.d.ts.map +1 -0
  118. package/dist/src/knowledge/html-extract.js +286 -0
  119. package/dist/src/knowledge/html-extract.js.map +1 -0
  120. package/dist/src/knowledge/html-tags.d.ts +30 -0
  121. package/dist/src/knowledge/html-tags.d.ts.map +1 -0
  122. package/dist/src/knowledge/html-tags.js +229 -0
  123. package/dist/src/knowledge/html-tags.js.map +1 -0
  124. package/dist/src/knowledge/library.d.ts +106 -0
  125. package/dist/src/knowledge/library.d.ts.map +1 -0
  126. package/dist/src/knowledge/library.js +195 -0
  127. package/dist/src/knowledge/library.js.map +1 -0
  128. package/dist/src/knowledge/lookup.d.ts +80 -0
  129. package/dist/src/knowledge/lookup.d.ts.map +1 -0
  130. package/dist/src/knowledge/lookup.js +156 -0
  131. package/dist/src/knowledge/lookup.js.map +1 -0
  132. package/dist/src/knowledge/mhtml.d.ts +60 -0
  133. package/dist/src/knowledge/mhtml.d.ts.map +1 -0
  134. package/dist/src/knowledge/mhtml.js +154 -0
  135. package/dist/src/knowledge/mhtml.js.map +1 -0
  136. package/dist/src/knowledge/okf-bundle.d.ts +19 -0
  137. package/dist/src/knowledge/okf-bundle.d.ts.map +1 -0
  138. package/dist/src/knowledge/okf-bundle.js +106 -0
  139. package/dist/src/knowledge/okf-bundle.js.map +1 -0
  140. package/dist/src/knowledge/profile-store.d.ts +134 -0
  141. package/dist/src/knowledge/profile-store.d.ts.map +1 -0
  142. package/dist/src/knowledge/profile-store.js +237 -0
  143. package/dist/src/knowledge/profile-store.js.map +1 -0
  144. package/dist/src/knowledge/related.d.ts +58 -0
  145. package/dist/src/knowledge/related.d.ts.map +1 -0
  146. package/dist/src/knowledge/related.js +222 -0
  147. package/dist/src/knowledge/related.js.map +1 -0
  148. package/dist/src/knowledge/section-diff.d.ts +48 -0
  149. package/dist/src/knowledge/section-diff.d.ts.map +1 -0
  150. package/dist/src/knowledge/section-diff.js +151 -0
  151. package/dist/src/knowledge/section-diff.js.map +1 -0
  152. package/dist/src/knowledge/watch.d.ts +92 -0
  153. package/dist/src/knowledge/watch.d.ts.map +1 -0
  154. package/dist/src/knowledge/watch.js +221 -0
  155. package/dist/src/knowledge/watch.js.map +1 -0
  156. package/dist/src/mcp-server.d.ts.map +1 -1
  157. package/dist/src/mcp-server.js +44 -87
  158. package/dist/src/mcp-server.js.map +1 -1
  159. package/dist/src/mcp-tools/browser-instrument-tools.d.ts +35 -0
  160. package/dist/src/mcp-tools/browser-instrument-tools.d.ts.map +1 -0
  161. package/dist/src/mcp-tools/browser-instrument-tools.js +359 -0
  162. package/dist/src/mcp-tools/browser-instrument-tools.js.map +1 -0
  163. package/dist/src/mcp-tools/browser-metrics.d.ts +42 -0
  164. package/dist/src/mcp-tools/browser-metrics.d.ts.map +1 -0
  165. package/dist/src/mcp-tools/browser-metrics.js +91 -0
  166. package/dist/src/mcp-tools/browser-metrics.js.map +1 -0
  167. package/dist/src/mcp-tools/browser-profile-tools.d.ts +16 -0
  168. package/dist/src/mcp-tools/browser-profile-tools.d.ts.map +1 -0
  169. package/dist/src/mcp-tools/browser-profile-tools.js +324 -0
  170. package/dist/src/mcp-tools/browser-profile-tools.js.map +1 -0
  171. package/dist/src/mcp-tools/browser-session.d.ts +68 -0
  172. package/dist/src/mcp-tools/browser-session.d.ts.map +1 -0
  173. package/dist/src/mcp-tools/browser-session.js +224 -0
  174. package/dist/src/mcp-tools/browser-session.js.map +1 -0
  175. package/dist/src/mcp-tools/browser-tools.d.ts.map +1 -1
  176. package/dist/src/mcp-tools/browser-tools.js +10 -176
  177. package/dist/src/mcp-tools/browser-tools.js.map +1 -1
  178. package/dist/src/mcp-tools/capture-resource-read.d.ts +115 -0
  179. package/dist/src/mcp-tools/capture-resource-read.d.ts.map +1 -0
  180. package/dist/src/mcp-tools/capture-resource-read.js +296 -0
  181. package/dist/src/mcp-tools/capture-resource-read.js.map +1 -0
  182. package/dist/src/mcp-tools/capture-resource-tools.d.ts +22 -0
  183. package/dist/src/mcp-tools/capture-resource-tools.d.ts.map +1 -0
  184. package/dist/src/mcp-tools/capture-resource-tools.js +182 -0
  185. package/dist/src/mcp-tools/capture-resource-tools.js.map +1 -0
  186. package/dist/src/mcp-tools/capture-resources.d.ts +142 -0
  187. package/dist/src/mcp-tools/capture-resources.d.ts.map +1 -0
  188. package/dist/src/mcp-tools/capture-resources.js +289 -0
  189. package/dist/src/mcp-tools/capture-resources.js.map +1 -0
  190. package/dist/src/mcp-tools/index.d.ts +3 -0
  191. package/dist/src/mcp-tools/index.d.ts.map +1 -1
  192. package/dist/src/mcp-tools/index.js +6 -0
  193. package/dist/src/mcp-tools/index.js.map +1 -1
  194. package/dist/src/mcp-tools/knowledge-tools.d.ts.map +1 -1
  195. package/dist/src/mcp-tools/knowledge-tools.js +9 -1
  196. package/dist/src/mcp-tools/knowledge-tools.js.map +1 -1
  197. package/dist/src/mcp-tools/resource-router.d.ts +86 -0
  198. package/dist/src/mcp-tools/resource-router.d.ts.map +1 -0
  199. package/dist/src/mcp-tools/resource-router.js +181 -0
  200. package/dist/src/mcp-tools/resource-router.js.map +1 -0
  201. package/dist/src/memory/memory-bridge.js +1 -1
  202. package/dist/src/memory/memory-bridge.js.map +1 -1
  203. package/dist/src/orgrt/agent-runner.d.ts +4 -0
  204. package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
  205. package/dist/src/orgrt/agent-runner.js +22 -0
  206. package/dist/src/orgrt/agent-runner.js.map +1 -1
  207. package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
  208. package/dist/src/orgrt/antigravity-runner.js +2 -1
  209. package/dist/src/orgrt/antigravity-runner.js.map +1 -1
  210. package/dist/src/orgrt/authority-mask.d.ts +32 -0
  211. package/dist/src/orgrt/authority-mask.d.ts.map +1 -0
  212. package/dist/src/orgrt/authority-mask.js +135 -0
  213. package/dist/src/orgrt/authority-mask.js.map +1 -0
  214. package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
  215. package/dist/src/orgrt/codex-runner.js +2 -1
  216. package/dist/src/orgrt/codex-runner.js.map +1 -1
  217. package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
  218. package/dist/src/orgrt/copilot-runner.js +2 -1
  219. package/dist/src/orgrt/copilot-runner.js.map +1 -1
  220. package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
  221. package/dist/src/orgrt/crush-runner.js +6 -1
  222. package/dist/src/orgrt/crush-runner.js.map +1 -1
  223. package/dist/src/orgrt/daemon.d.ts +4 -0
  224. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  225. package/dist/src/orgrt/daemon.js +13 -2
  226. package/dist/src/orgrt/daemon.js.map +1 -1
  227. package/dist/src/orgrt/decisions.d.ts +9 -0
  228. package/dist/src/orgrt/decisions.d.ts.map +1 -1
  229. package/dist/src/orgrt/decisions.js +32 -5
  230. package/dist/src/orgrt/decisions.js.map +1 -1
  231. package/dist/src/orgrt/file-roots.d.ts +2 -1
  232. package/dist/src/orgrt/file-roots.d.ts.map +1 -1
  233. package/dist/src/orgrt/file-roots.js +7 -3
  234. package/dist/src/orgrt/file-roots.js.map +1 -1
  235. package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
  236. package/dist/src/orgrt/grok-runner.js +2 -1
  237. package/dist/src/orgrt/grok-runner.js.map +1 -1
  238. package/dist/src/orgrt/hermes-runner.d.ts.map +1 -1
  239. package/dist/src/orgrt/hermes-runner.js +2 -1
  240. package/dist/src/orgrt/hermes-runner.js.map +1 -1
  241. package/dist/src/orgrt/inbox.d.ts.map +1 -1
  242. package/dist/src/orgrt/inbox.js +70 -4
  243. package/dist/src/orgrt/inbox.js.map +1 -1
  244. package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
  245. package/dist/src/orgrt/kimicode-runner.js +2 -1
  246. package/dist/src/orgrt/kimicode-runner.js.map +1 -1
  247. package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
  248. package/dist/src/orgrt/opencode-runner.js +3 -2
  249. package/dist/src/orgrt/opencode-runner.js.map +1 -1
  250. package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
  251. package/dist/src/orgrt/pi-rpc-runner.js +3 -2
  252. package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
  253. package/dist/src/orgrt/pi-runner.d.ts.map +1 -1
  254. package/dist/src/orgrt/pi-runner.js +2 -1
  255. package/dist/src/orgrt/pi-runner.js.map +1 -1
  256. package/dist/src/orgrt/policy.d.ts.map +1 -1
  257. package/dist/src/orgrt/policy.js +3 -0
  258. package/dist/src/orgrt/policy.js.map +1 -1
  259. package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
  260. package/dist/src/orgrt/qwen-rpc-runner.js +3 -2
  261. package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
  262. package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
  263. package/dist/src/orgrt/qwen-runner.js +2 -1
  264. package/dist/src/orgrt/qwen-runner.js.map +1 -1
  265. package/dist/src/orgrt/role-sandbox.d.ts +21 -0
  266. package/dist/src/orgrt/role-sandbox.d.ts.map +1 -1
  267. package/dist/src/orgrt/role-sandbox.js +31 -6
  268. package/dist/src/orgrt/role-sandbox.js.map +1 -1
  269. package/dist/src/orgrt/session-ledger.d.ts +7 -0
  270. package/dist/src/orgrt/session-ledger.d.ts.map +1 -1
  271. package/dist/src/orgrt/session-ledger.js +15 -0
  272. package/dist/src/orgrt/session-ledger.js.map +1 -1
  273. package/dist/src/orgrt/session.d.ts.map +1 -1
  274. package/dist/src/orgrt/session.js +42 -10
  275. package/dist/src/orgrt/session.js.map +1 -1
  276. package/dist/src/orgrt/task-dag.d.ts +3 -0
  277. package/dist/src/orgrt/task-dag.d.ts.map +1 -1
  278. package/dist/src/orgrt/task-dag.js +1 -0
  279. package/dist/src/orgrt/task-dag.js.map +1 -1
  280. package/dist/src/orgrt/types.d.ts +5 -0
  281. package/dist/src/orgrt/types.d.ts.map +1 -1
  282. package/dist/src/orgrt/types.js +23 -1
  283. package/dist/src/orgrt/types.js.map +1 -1
  284. package/dist/src/ui/dashboard.html +28 -848
  285. package/dist/src/ui/human-auth.mjs +103 -0
  286. package/dist/src/ui/org-hil.mjs +86 -37
  287. package/dist/src/ui/org-runtime.mjs +21 -13
  288. package/dist/src/ui/routes-org.mjs +49 -445
  289. package/dist/src/ui/server.mjs +90 -2
  290. package/dist/tsconfig.tsbuildinfo +1 -1
  291. package/package.json +9 -9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-envelope.js","sourceRoot":"","sources":["../../../src/knowledge/capture-envelope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Text extraction for web captures (RCL-01) — the HTML/MHTML arm of
3
+ * `extractText`, kept here so `cap-documents.ts` stays a dispatch table.
4
+ *
5
+ * @module v1/cli/knowledge/capture-text
6
+ */
7
+ export declare const HTML_EXTENSIONS: Set<string>;
8
+ export declare const MHTML_EXTENSIONS: Set<string>;
9
+ export declare function isCaptureExtension(ext: string): boolean;
10
+ /**
11
+ * Clean text for an archived page.
12
+ *
13
+ * PRECEDENCE — when the file sits in a capture envelope, the sibling
14
+ * `readable.md` wins. It was produced by Readability against the LIVE DOM,
15
+ * with lazy images resolved, the consent modal dismissed and the site's own JS
16
+ * finished; nothing derived from the archived markup can beat that. Our own
17
+ * extractor is the fallback for archives nobody cleaned.
18
+ *
19
+ * Returns '' rather than throwing — an unreadable capture is a document with
20
+ * no text, not a failed ingest.
21
+ */
22
+ export declare function extractCaptureText(absolutePath: string, ext: string): string;
23
+ //# sourceMappingURL=capture-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-text.d.ts","sourceRoot":"","sources":["../../../src/knowledge/capture-text.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,eAAO,MAAM,eAAe,aAAuC,CAAC;AACpE,eAAO,MAAM,gBAAgB,aAA8B,CAAC;AAE5D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAiB5E"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Text extraction for web captures (RCL-01) — the HTML/MHTML arm of
3
+ * `extractText`, kept here so `cap-documents.ts` stays a dispatch table.
4
+ *
5
+ * @module v1/cli/knowledge/capture-text
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import { readableSiblingFor } from './capture-envelope.js';
9
+ import { htmlToMarkdown } from './html-extract.js';
10
+ import { mhtmlToHtml } from './mhtml.js';
11
+ export const HTML_EXTENSIONS = new Set(['.html', '.htm', '.xhtml']);
12
+ export const MHTML_EXTENSIONS = new Set(['.mhtml', '.mht']);
13
+ export function isCaptureExtension(ext) {
14
+ return HTML_EXTENSIONS.has(ext) || MHTML_EXTENSIONS.has(ext);
15
+ }
16
+ /**
17
+ * Clean text for an archived page.
18
+ *
19
+ * PRECEDENCE — when the file sits in a capture envelope, the sibling
20
+ * `readable.md` wins. It was produced by Readability against the LIVE DOM,
21
+ * with lazy images resolved, the consent modal dismissed and the site's own JS
22
+ * finished; nothing derived from the archived markup can beat that. Our own
23
+ * extractor is the fallback for archives nobody cleaned.
24
+ *
25
+ * Returns '' rather than throwing — an unreadable capture is a document with
26
+ * no text, not a failed ingest.
27
+ */
28
+ export function extractCaptureText(absolutePath, ext) {
29
+ try {
30
+ const readable = readableSiblingFor(absolutePath);
31
+ if (readable)
32
+ return fs.readFileSync(readable, 'utf-8');
33
+ }
34
+ catch {
35
+ /* no envelope, or an unreadable one — extract from the file itself */
36
+ }
37
+ try {
38
+ if (MHTML_EXTENSIONS.has(ext)) {
39
+ // latin1 preserves the raw bytes: transfer encoding comes off first, and
40
+ // the real charset is only known per MIME part.
41
+ return htmlToMarkdown(mhtmlToHtml(fs.readFileSync(absolutePath, 'latin1')).html);
42
+ }
43
+ return htmlToMarkdown(fs.readFileSync(absolutePath, 'utf-8'));
44
+ }
45
+ catch {
46
+ return '';
47
+ }
48
+ }
49
+ //# sourceMappingURL=capture-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-text.js","sourceRoot":"","sources":["../../../src/knowledge/capture-text.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,YAAoB,EAAE,GAAW;IAClE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,QAAQ;YAAE,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;IACD,IAAI,CAAC;QACH,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,yEAAyE;YACzE,gDAAgD;YAChD,OAAO,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACnF,CAAC;QACD,OAAO,cAAc,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Paragraph-level citation (RCL-10).
3
+ *
4
+ * A search hit already knows WHICH document it came from. A citation has to
5
+ * know WHERE IN IT: the character span of the chunk against the extracted
6
+ * text, an anchor that survives being written down, and a way back to the
7
+ * live page at that passage.
8
+ *
9
+ * Three pieces, deliberately separate:
10
+ *
11
+ * - `span:<start>-<end>` — a tag written next to every chunk at ingest, so a
12
+ * search result carries offsets without re-reading the document.
13
+ * - the ANCHOR `<hash12>#<start>-<end>` — offsets bound to the content hash
14
+ * of the exact version they were measured against. Quoting an offset range
15
+ * without the version it belongs to is how citations rot: the document is
16
+ * re-captured, the text shifts, and the quote silently points at other
17
+ * words. A stale anchor here is DETECTED (`stale: true`), never served as
18
+ * if it were still true.
19
+ * - a W3C text fragment (`#:~:text=`) — the link a human clicks, which lands
20
+ * on the sentence even though the site never had an id there.
21
+ *
22
+ * Everything above `resolveCitation` is pure and synchronous so the pipeline
23
+ * can use it while ingesting. `resolveCitation` reaches back into the
24
+ * document-pipeline through a DYNAMIC import: the pipeline imports this
25
+ * module statically, and a static import back would close the cycle.
26
+ *
27
+ * @module v1/cli/knowledge/citation
28
+ */
29
+ import type { CaptureProvenance } from './capture-envelope.js';
30
+ export declare const SPAN_TAG_PREFIX = "span:";
31
+ export interface ChunkSpan {
32
+ chunkIndex: number;
33
+ startChar: number;
34
+ endChar: number;
35
+ }
36
+ /** The tag written beside a chunk at ingest: `span:<start>-<end>`. */
37
+ export declare function spanTag(startChar: number, endChar: number): string;
38
+ /** Offsets from a chunk's tag list, or null when it predates span tags. */
39
+ export declare function parseSpanTag(tags: readonly string[] | undefined): {
40
+ startChar: number;
41
+ endChar: number;
42
+ } | null;
43
+ /** `<hash12>#<start>-<end>` — offsets bound to the version they were measured against. */
44
+ export declare function citationAnchor(contentHash: string, startChar: number, endChar: number): string;
45
+ export declare function parseCitationAnchor(anchor: string): {
46
+ hashPrefix: string;
47
+ startChar: number;
48
+ endChar: number;
49
+ } | null;
50
+ /** True when the anchor was cut against this document version. */
51
+ export declare function anchorMatchesHash(anchor: string, contentHash: string): boolean;
52
+ /**
53
+ * The prose of a passage: § context prefixes gone, markdown syntax gone,
54
+ * whitespace collapsed.
55
+ *
56
+ * `skipHeadings` drops heading lines as well, which is what a text fragment
57
+ * wants — a heading is usually its own element on the page, so starting a
58
+ * range there matches less reliably than starting at the paragraph. It falls
59
+ * back to including them when the passage is nothing but headings.
60
+ */
61
+ export declare function passageProse(passage: string, skipHeadings?: boolean): string;
62
+ /** The head of a passage as a quotable sentence or two — the words a reader
63
+ * would see on the page, not the markdown we stored. */
64
+ export declare function passageQuote(passage: string, maxChars?: number): string;
65
+ /**
66
+ * A W3C scroll-to-text fragment for this passage.
67
+ *
68
+ * Long passages use the `textStart,textEnd` form rather than the whole
69
+ * paragraph: the spec matches across the range, and a shorter pair survives
70
+ * the site re-flowing its markup between capture and click.
71
+ */
72
+ export declare function textFragment(passage: string): string;
73
+ /** The captured page's URL, pointed at the passage. Returns undefined when
74
+ * there is no URL — a citation into a local file has no link to give. */
75
+ export declare function citationUrl(url: string | undefined, passage: string): string | undefined;
76
+ export interface Citation {
77
+ /** `<scope>:<filePath>` — the pipeline's own document id. */
78
+ docId: string;
79
+ filePath: string;
80
+ scope: string;
81
+ chunkIndex: number;
82
+ startChar: number;
83
+ endChar: number;
84
+ /** Hash of the text the offsets were cut against, i.e. the file as it is NOW. */
85
+ contentHash: string;
86
+ anchor: string;
87
+ /** The cited text itself, straight out of the extracted document. */
88
+ passage: string;
89
+ /** The head of the passage, collapsed — what an agent puts in quotes. */
90
+ quote: string;
91
+ /** Present only when the anchor asked for a version this file no longer is. */
92
+ stale?: boolean;
93
+ version?: number;
94
+ title?: string;
95
+ url?: string;
96
+ /** `url` with a text fragment appended: the link that lands on the passage. */
97
+ citeUrl?: string;
98
+ capturedAt?: string;
99
+ source?: string;
100
+ provenance?: CaptureProvenance;
101
+ }
102
+ export interface ResolveCitationOptions {
103
+ rootDir?: string;
104
+ scope?: string;
105
+ /** Chunk index, as reported on a search hit. */
106
+ chunkIndex?: number;
107
+ /** An anchor string from a previous citation — resolved by offsets, and
108
+ * flagged `stale` when it names a version this document no longer is. */
109
+ anchor?: string;
110
+ }
111
+ /**
112
+ * Resolve a citation back to the passage it came from.
113
+ *
114
+ * `target` is whatever the caller has written down: an indexed file path, a
115
+ * capture's `canonicalUrl`, or the `<scope>:<path>` docId. Throws with a
116
+ * message meant for a human when the document is not indexed, its file is
117
+ * gone, or the chunk does not exist — a citation that cannot be checked must
118
+ * fail loudly, not resolve to an empty string.
119
+ */
120
+ export declare function resolveCitation(target: string, opts?: ResolveCitationOptions): Promise<Citation>;
121
+ //# sourceMappingURL=citation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation.d.ts","sourceRoot":"","sources":["../../../src/knowledge/citation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Paragraph-level citation (RCL-10).
3
+ *
4
+ * A search hit already knows WHICH document it came from. A citation has to
5
+ * know WHERE IN IT: the character span of the chunk against the extracted
6
+ * text, an anchor that survives being written down, and a way back to the
7
+ * live page at that passage.
8
+ *
9
+ * Three pieces, deliberately separate:
10
+ *
11
+ * - `span:<start>-<end>` — a tag written next to every chunk at ingest, so a
12
+ * search result carries offsets without re-reading the document.
13
+ * - the ANCHOR `<hash12>#<start>-<end>` — offsets bound to the content hash
14
+ * of the exact version they were measured against. Quoting an offset range
15
+ * without the version it belongs to is how citations rot: the document is
16
+ * re-captured, the text shifts, and the quote silently points at other
17
+ * words. A stale anchor here is DETECTED (`stale: true`), never served as
18
+ * if it were still true.
19
+ * - a W3C text fragment (`#:~:text=`) — the link a human clicks, which lands
20
+ * on the sentence even though the site never had an id there.
21
+ *
22
+ * Everything above `resolveCitation` is pure and synchronous so the pipeline
23
+ * can use it while ingesting. `resolveCitation` reaches back into the
24
+ * document-pipeline through a DYNAMIC import: the pipeline imports this
25
+ * module statically, and a static import back would close the cycle.
26
+ *
27
+ * @module v1/cli/knowledge/citation
28
+ */
29
+ import * as crypto from 'node:crypto';
30
+ import * as fs from 'node:fs';
31
+ import * as path from 'node:path';
32
+ export const SPAN_TAG_PREFIX = 'span:';
33
+ /** The tag written beside a chunk at ingest: `span:<start>-<end>`. */
34
+ export function spanTag(startChar, endChar) {
35
+ return `${SPAN_TAG_PREFIX}${startChar}-${endChar}`;
36
+ }
37
+ /** Offsets from a chunk's tag list, or null when it predates span tags. */
38
+ export function parseSpanTag(tags) {
39
+ for (const tag of tags ?? []) {
40
+ if (typeof tag !== 'string' || !tag.startsWith(SPAN_TAG_PREFIX))
41
+ continue;
42
+ const m = /^span:(\d+)-(\d+)$/.exec(tag);
43
+ if (!m)
44
+ continue;
45
+ const startChar = Number(m[1]);
46
+ const endChar = Number(m[2]);
47
+ if (endChar < startChar)
48
+ continue;
49
+ return { startChar, endChar };
50
+ }
51
+ return null;
52
+ }
53
+ const ANCHOR_HASH_CHARS = 12;
54
+ /** `<hash12>#<start>-<end>` — offsets bound to the version they were measured against. */
55
+ export function citationAnchor(contentHash, startChar, endChar) {
56
+ return `${(contentHash || '').slice(0, ANCHOR_HASH_CHARS)}#${startChar}-${endChar}`;
57
+ }
58
+ export function parseCitationAnchor(anchor) {
59
+ const m = /^([0-9a-f]{4,64})#(\d+)-(\d+)$/.exec((anchor || '').trim());
60
+ if (!m)
61
+ return null;
62
+ const startChar = Number(m[2]);
63
+ const endChar = Number(m[3]);
64
+ if (endChar < startChar)
65
+ return null;
66
+ return { hashPrefix: m[1], startChar, endChar };
67
+ }
68
+ /** True when the anchor was cut against this document version. */
69
+ export function anchorMatchesHash(anchor, contentHash) {
70
+ const parsed = parseCitationAnchor(anchor);
71
+ if (!parsed)
72
+ return false;
73
+ return (contentHash || '').startsWith(parsed.hashPrefix);
74
+ }
75
+ // ── Quotes and links ───────────────────────────────────────────────
76
+ const QUOTE_MAX_CHARS = 320;
77
+ const CONTEXT_PREFIX_RE = /^(§ [^\n]*\n)+/;
78
+ const HEADING_LINE_RE = /^\s{0,3}#{1,6}\s+/;
79
+ /**
80
+ * One line of markdown as the words a reader sees.
81
+ *
82
+ * This matters more than it looks: a text fragment built from `# Pricing ##
83
+ * Starter Nine dollars` matches NOTHING on the live page, because the page
84
+ * never contained a `#`. The link is only worth having if it is made of the
85
+ * prose the site actually renders.
86
+ */
87
+ function stripMarkdown(line) {
88
+ return line
89
+ .replace(HEADING_LINE_RE, '')
90
+ .replace(/^\s{0,3}>\s?/, '')
91
+ .replace(/^\s{0,3}([-*+]|\d+\.)\s+/, '')
92
+ .replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1')
93
+ .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
94
+ .replace(/`{1,3}([^`]*)`{1,3}/g, '$1')
95
+ .replace(/(\*\*|__)(.*?)\1/g, '$2')
96
+ .replace(/(\*|_)(?=\S)(.*?)(?<=\S)\1/g, '$2')
97
+ .trim();
98
+ }
99
+ /**
100
+ * The prose of a passage: § context prefixes gone, markdown syntax gone,
101
+ * whitespace collapsed.
102
+ *
103
+ * `skipHeadings` drops heading lines as well, which is what a text fragment
104
+ * wants — a heading is usually its own element on the page, so starting a
105
+ * range there matches less reliably than starting at the paragraph. It falls
106
+ * back to including them when the passage is nothing but headings.
107
+ */
108
+ export function passageProse(passage, skipHeadings = false) {
109
+ const lines = String(passage ?? '')
110
+ .replace(CONTEXT_PREFIX_RE, '')
111
+ .split('\n');
112
+ const keep = (only) => lines
113
+ .filter((l) => !only || !HEADING_LINE_RE.test(l))
114
+ .map(stripMarkdown)
115
+ .filter(Boolean)
116
+ .join(' ')
117
+ .replace(/\s+/g, ' ')
118
+ .trim();
119
+ const body = keep(skipHeadings);
120
+ return body || keep(false);
121
+ }
122
+ /** The head of a passage as a quotable sentence or two — the words a reader
123
+ * would see on the page, not the markdown we stored. */
124
+ export function passageQuote(passage, maxChars = QUOTE_MAX_CHARS) {
125
+ const text = passageProse(passage);
126
+ if (text.length <= maxChars)
127
+ return text;
128
+ const window = text.slice(0, maxChars);
129
+ const stop = Math.max(window.lastIndexOf('. '), window.lastIndexOf('? '), window.lastIndexOf('! '));
130
+ return stop > maxChars * 0.4 ? window.slice(0, stop + 1) : `${window.trimEnd()}…`;
131
+ }
132
+ /** `,` and `-` are syntax inside a text fragment, so they cannot be left raw. */
133
+ function encodeFragmentPart(text) {
134
+ return encodeURIComponent(text).replace(/-/g, '%2D').replace(/,/g, '%2C');
135
+ }
136
+ const FRAGMENT_WORDS = 8;
137
+ /**
138
+ * A W3C scroll-to-text fragment for this passage.
139
+ *
140
+ * Long passages use the `textStart,textEnd` form rather than the whole
141
+ * paragraph: the spec matches across the range, and a shorter pair survives
142
+ * the site re-flowing its markup between capture and click.
143
+ */
144
+ export function textFragment(passage) {
145
+ const text = passageProse(passage, true).slice(0, 2000);
146
+ if (!text)
147
+ return '';
148
+ const words = text.split(' ').filter(Boolean);
149
+ if (words.length <= FRAGMENT_WORDS * 2)
150
+ return `:~:text=${encodeFragmentPart(text)}`;
151
+ const start = words.slice(0, FRAGMENT_WORDS).join(' ');
152
+ const end = words.slice(-FRAGMENT_WORDS).join(' ');
153
+ return `:~:text=${encodeFragmentPart(start)},${encodeFragmentPart(end)}`;
154
+ }
155
+ /** The captured page's URL, pointed at the passage. Returns undefined when
156
+ * there is no URL — a citation into a local file has no link to give. */
157
+ export function citationUrl(url, passage) {
158
+ if (!url)
159
+ return undefined;
160
+ const fragment = textFragment(passage);
161
+ if (!fragment)
162
+ return url;
163
+ const hash = url.indexOf('#');
164
+ const base = hash === -1 ? url : url.slice(0, hash);
165
+ return `${base}#${fragment}`;
166
+ }
167
+ function fileEntry(absolutePath) {
168
+ const stat = fs.statSync(absolutePath);
169
+ return {
170
+ path: absolutePath,
171
+ absolutePath,
172
+ extension: path.extname(absolutePath).toLowerCase(),
173
+ size: stat.size,
174
+ modified: stat.mtime,
175
+ created: stat.birthtime,
176
+ };
177
+ }
178
+ /**
179
+ * Resolve a citation back to the passage it came from.
180
+ *
181
+ * `target` is whatever the caller has written down: an indexed file path, a
182
+ * capture's `canonicalUrl`, or the `<scope>:<path>` docId. Throws with a
183
+ * message meant for a human when the document is not indexed, its file is
184
+ * gone, or the chunk does not exist — a citation that cannot be checked must
185
+ * fail loudly, not resolve to an empty string.
186
+ */
187
+ export async function resolveCitation(target, opts = {}) {
188
+ const pipeline = await import('./document-pipeline.js');
189
+ const { extractText } = await import('../capabilities/cap-documents.js');
190
+ const rootDir = opts.rootDir ?? pipeline.getKnowledgeRoot(opts.scope);
191
+ const scope = opts.scope;
192
+ const record = pipeline.findDocumentRecord(rootDir, target, scope);
193
+ if (!record)
194
+ throw new Error(`not indexed: ${target}`);
195
+ if (!fs.existsSync(record.filePath)) {
196
+ throw new Error(`source file is gone: ${record.filePath} (re-ingest the capture to cite it)`);
197
+ }
198
+ const text = await extractText(fileEntry(record.filePath));
199
+ if (!text)
200
+ throw new Error(`no text could be extracted from ${record.filePath}`);
201
+ const hash = crypto.createHash('sha256').update(text).digest('hex');
202
+ let startChar;
203
+ let endChar;
204
+ let chunkIndex;
205
+ const parsedAnchor = opts.anchor ? parseCitationAnchor(opts.anchor) : null;
206
+ if (opts.anchor && !parsedAnchor)
207
+ throw new Error(`malformed citation anchor: ${opts.anchor}`);
208
+ if (parsedAnchor) {
209
+ startChar = Math.min(parsedAnchor.startChar, text.length);
210
+ endChar = Math.min(parsedAnchor.endChar, text.length);
211
+ const spans = await pipeline.chunkSpans(text);
212
+ chunkIndex = spans.findIndex((s) => s.startChar === startChar);
213
+ if (chunkIndex === -1) {
214
+ chunkIndex = spans.findIndex((s) => s.startChar <= startChar && startChar < s.endChar);
215
+ }
216
+ }
217
+ else {
218
+ chunkIndex = opts.chunkIndex ?? 0;
219
+ const spans = await pipeline.chunkSpans(text);
220
+ const span = spans[chunkIndex];
221
+ if (!span) {
222
+ throw new Error(`chunk ${chunkIndex} is out of range: ${path.basename(record.filePath)} has ${spans.length} chunk(s)`);
223
+ }
224
+ startChar = span.startChar;
225
+ endChar = span.endChar;
226
+ }
227
+ const passage = text.slice(startChar, endChar);
228
+ const url = record.canonicalUrl ?? record.provenance?.canonicalUrl ?? record.provenance?.url;
229
+ const stale = parsedAnchor
230
+ ? !anchorMatchesHash(opts.anchor, hash)
231
+ : hash !== record.contentHash;
232
+ return {
233
+ docId: `${record.scope}:${record.filePath}`,
234
+ filePath: record.filePath,
235
+ scope: record.scope,
236
+ chunkIndex: chunkIndex === -1 ? 0 : chunkIndex,
237
+ startChar,
238
+ endChar,
239
+ contentHash: hash,
240
+ anchor: citationAnchor(hash, startChar, endChar),
241
+ passage,
242
+ quote: passageQuote(passage),
243
+ ...(stale ? { stale: true } : {}),
244
+ ...(record.version ? { version: record.version } : {}),
245
+ ...(record.provenance?.title ? { title: record.provenance.title } : {}),
246
+ ...(url ? { url, citeUrl: citationUrl(url, passage) } : {}),
247
+ ...(record.provenance?.capturedAt ? { capturedAt: record.provenance.capturedAt } : {}),
248
+ ...(record.provenance?.source ? { source: record.provenance.source } : {}),
249
+ ...(record.provenance ? { provenance: record.provenance } : {}),
250
+ };
251
+ }
252
+ //# sourceMappingURL=citation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation.js","sourceRoot":"","sources":["../../../src/knowledge/citation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AAQvC,sEAAsE;AACtE,MAAM,UAAU,OAAO,CAAC,SAAiB,EAAE,OAAe;IACxD,OAAO,GAAG,eAAe,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC;AACrD,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,YAAY,CAAC,IAAmC;IAI9D,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC;YAAE,SAAS;QAC1E,MAAM,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,OAAO,GAAG,SAAS;YAAE,SAAS;QAClC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,SAAiB,EAAE,OAAe;IACpF,OAAO,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,MAAc;IAEd,MAAM,CAAC,GAAG,gCAAgC,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvE,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,OAAO,GAAG,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAClD,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,WAAmB;IACnE,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAC3D,CAAC;AAED,sEAAsE;AAEtE,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAC3C,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAE5C;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI;SACR,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;SAC5B,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,OAAO,CAAC,0BAA0B,EAAE,EAAE,CAAC;SACvC,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC;SACxC,OAAO,CAAC,wBAAwB,EAAE,IAAI,CAAC;SACvC,OAAO,CAAC,sBAAsB,EAAE,IAAI,CAAC;SACrC,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC;SAClC,OAAO,CAAC,6BAA6B,EAAE,IAAI,CAAC;SAC5C,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,YAAY,GAAG,KAAK;IAChE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;SAChC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;SAC9B,KAAK,CAAC,IAAI,CAAC,CAAC;IACf,MAAM,IAAI,GAAG,CAAC,IAAa,EAAE,EAAE,CAC7B,KAAK;SACF,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SAChD,GAAG,CAAC,aAAa,CAAC;SAClB,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC;SACT,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACZ,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IAChC,OAAO,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED;yDACyD;AACzD,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,QAAQ,GAAG,eAAe;IACtE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,EACxB,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,EACxB,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CACzB,CAAC;IACF,OAAO,IAAI,GAAG,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;AACpF,CAAC;AAED,iFAAiF;AACjF,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,KAAK,CAAC,MAAM,IAAI,cAAc,GAAG,CAAC;QAAE,OAAO,WAAW,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;IACrF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,OAAO,WAAW,kBAAkB,CAAC,KAAK,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED;0EAC0E;AAC1E,MAAM,UAAU,WAAW,CAAC,GAAuB,EAAE,OAAe;IAClE,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ;QAAE,OAAO,GAAG,CAAC;IAC1B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,GAAG,IAAI,IAAI,QAAQ,EAAE,CAAC;AAC/B,CAAC;AAyCD,SAAS,SAAS,CAAC,YAAoB;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvC,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,YAAY;QACZ,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE;QACnD,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,KAAK;QACpB,OAAO,EAAE,IAAI,CAAC,SAAS;KACxB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,IAAI,GAA2B,EAAE;IAEjC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IACxD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAEzB,MAAM,MAAM,GAAG,QAAQ,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACnE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,QAAQ,qCAAqC,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjF,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEpE,IAAI,SAAiB,CAAC;IACtB,IAAI,OAAe,CAAC;IACpB,IAAI,UAAkB,CAAC;IACvB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3E,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,YAAY;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAE/F,IAAI,YAAY,EAAE,CAAC;QACjB,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1D,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC9C,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;QAC/D,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,IAAI,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;SAAM,CAAC;QACN,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CACb,SAAS,UAAU,qBAAqB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAAK,CAAC,MAAM,WAAW,CACtG,CAAC;QACJ,CAAC;QACD,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC3B,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IACzB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,UAAU,EAAE,YAAY,IAAI,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC;IAC7F,MAAM,KAAK,GAAG,YAAY;QACxB,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAgB,EAAE,IAAI,CAAC;QACjD,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,WAAW,CAAC;IAEhC,OAAO;QACL,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE;QAC3C,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,UAAU,EAAE,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;QAC9C,SAAS;QACT,OAAO;QACP,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC;QAChD,OAAO;QACP,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC;QAC5B,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Document chunking — turning a document's extracted text into the enriched
3
+ * chunks that get embedded and stored.
4
+ *
5
+ * Two passes, in this order:
6
+ * 1. CHUNK — split on heading/paragraph boundaries (shared `@monoes/memory`
7
+ * chunker, with an inline fallback kept byte-identical to it).
8
+ * 2. ENRICH — replace each chunk's leaf-heading prefix with a situating blurb
9
+ * (doc title + full heading path + summary) so the embedding model can tell
10
+ * two identically-titled sections of different documents apart.
11
+ *
12
+ * Split out of document-pipeline.ts. Pure string work: no fs, no network, no
13
+ * store access — which is what makes chunk spans reproducible at citation time
14
+ * (`chunkSpans`) without re-reading anything.
15
+ *
16
+ * @module v1/cli/knowledge/document-chunking
17
+ */
18
+ import type { ChunkSpan } from './citation.js';
19
+ export interface TextChunk {
20
+ chunkId: string;
21
+ docId: string;
22
+ text: string;
23
+ startChar: number;
24
+ endChar: number;
25
+ chunkIndex: number;
26
+ }
27
+ export declare function chunkDocument(docId: string, text: string): Promise<TextChunk[]>;
28
+ /**
29
+ * Replace each chunk's `§ heading` prefix with a richer situating blurb:
30
+ * § <doc title> · <full heading path>
31
+ * <doc summary for non-first chunks>
32
+ *
33
+ * First chunks that start with their own heading are left untouched (the
34
+ * heading IS the context). The summary line is omitted for the first
35
+ * chunk since it is adjacent to the summary text anyway.
36
+ */
37
+ export declare function enrichChunks(chunks: TextChunk[], fullText: string, filePath: string): TextChunk[];
38
+ /** Chunk spans for a text, using the SAME chunker the ingest used — this is
39
+ * what makes a chunk index resolvable back to a character range without
40
+ * storing the text twice. */
41
+ export declare function chunkSpans(text: string): Promise<ChunkSpan[]>;
42
+ //# sourceMappingURL=document-chunking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-chunking.d.ts","sourceRoot":"","sources":["../../../src/knowledge/document-chunking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AA6GD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAOrF;AAwGD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAoCjG;AAED;;8BAE8B;AAC9B,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAOnE"}