@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":"library.d.ts","sourceRoot":"","sources":["../../../src/knowledge/library.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7E,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC,GAAG,MAAM,GAAG,SAAS,CAQrB;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC,GAAG,MAAM,CAET;AAUD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,SAAa,GAAG,MAAM,GAAG,IAAI,CAOpF;AAkBD,iDAAiD;AACjD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,aAAkB,EAC1B,GAAG,SAAa,GACf,OAAO,CAqCT;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,EAAE,EACpB,MAAM,GAAE,aAAkB,EAC1B,GAAG,SAAa,GACf,YAAY,EAAE,CAEhB;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,YAAY,EAAE,EACpB,IAAI,GAAE,WAAwB,EAC9B,KAAK,GAAE,KAAK,GAAG,MAAe,GAC7B,YAAY,EAAE,CAsBhB;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAmB7D;AAED,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,IAAI,GAAE,kBAAuB,GAAG,YAAY,EAAE,CAM/F;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG;IACnD,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,IAAI,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,WAAW,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD,CAiBA"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * The capture library (RCL-09) — browsing what has been captured, rather than
3
+ * searching it.
4
+ *
5
+ * `listDocuments` answers "what is indexed". A library answers a different
6
+ * question: everything from this site, captured last week, tagged `reading`,
7
+ * newest first. The facets come from the capture envelope's `meta.json`
8
+ * (RCL-07), which is already on every record — this module is the query layer
9
+ * over them, and the data layer the desktop GUI renders.
10
+ *
11
+ * Rules, once, here:
12
+ * - within a facet values are OR'd, across facets AND'd (`--site a --site b
13
+ * --tag x` = "from a or b, tagged x");
14
+ * - `--site example.com` matches `www.example.com` and `docs.example.com`,
15
+ * because nobody browsing their own library means the bare host only;
16
+ * - a document with no provenance (an ordinary file on disk) sorts by its
17
+ * index time and matches no capture facet — it is not a capture.
18
+ *
19
+ * @module v1/cli/knowledge/library
20
+ */
21
+ import * as path from 'node:path';
22
+ // ── Facet extraction ───────────────────────────────────────────────
23
+ /** The host a document was captured from, or undefined for a local file. */
24
+ export function documentSite(meta) {
25
+ const url = meta.canonicalUrl ?? meta.provenance?.canonicalUrl ?? meta.provenance?.url;
26
+ if (!url)
27
+ return undefined;
28
+ try {
29
+ return new URL(url).hostname.toLowerCase().replace(/^www\./, '');
30
+ }
31
+ catch {
32
+ return undefined;
33
+ }
34
+ }
35
+ /** When the page was captured; falls back to when it was indexed. */
36
+ export function documentCapturedAt(meta) {
37
+ return meta.provenance?.capturedAt ?? meta.indexedAt ?? '';
38
+ }
39
+ const RELATIVE_RE = /^(\d+(?:\.\d+)?)\s*(m|h|d|w)$/i;
40
+ const UNIT_MS = {
41
+ m: 60_000,
42
+ h: 3_600_000,
43
+ d: 86_400_000,
44
+ w: 604_800_000,
45
+ };
46
+ /**
47
+ * A point in time from `2026-09-01`, a full ISO stamp, or an AGE like `7d`
48
+ * (meaning "7 days ago"). Returns null for anything unparseable so a typo
49
+ * cannot silently filter the whole library away.
50
+ */
51
+ export function parseWhen(value, now = Date.now()) {
52
+ const raw = (value ?? '').trim();
53
+ if (!raw)
54
+ return null;
55
+ const rel = RELATIVE_RE.exec(raw);
56
+ if (rel)
57
+ return now - Number(rel[1]) * UNIT_MS[rel[2].toLowerCase()];
58
+ const parsed = Date.parse(raw.length === 10 ? `${raw}T00:00:00.000Z` : raw);
59
+ return Number.isNaN(parsed) ? null : parsed;
60
+ }
61
+ function siteMatches(host, wanted) {
62
+ if (!host)
63
+ return false;
64
+ return wanted.some((w) => {
65
+ const want = w
66
+ .trim()
67
+ .toLowerCase()
68
+ .replace(/^www\./, '');
69
+ return !!want && (host === want || host.endsWith(`.${want}`));
70
+ });
71
+ }
72
+ function anyOf(values, wanted) {
73
+ const have = (values ?? []).map((v) => v.toLowerCase());
74
+ return wanted.some((w) => have.includes(w.trim().toLowerCase()));
75
+ }
76
+ /** True when a document belongs in this view. */
77
+ export function matchesLibraryFilter(meta, filter = {}, now = Date.now()) {
78
+ if (filter.scope && meta.scope !== filter.scope)
79
+ return false;
80
+ const prov = meta.provenance;
81
+ const isCapture = !!prov || !!meta.canonicalUrl;
82
+ if (filter.capturedOnly && !isCapture)
83
+ return false;
84
+ if (filter.site?.length && !siteMatches(documentSite(meta), filter.site))
85
+ return false;
86
+ if (filter.tag?.length && !anyOf(prov?.tags, filter.tag))
87
+ return false;
88
+ if (filter.collection?.length &&
89
+ !anyOf(prov?.collection ? [prov.collection] : [], filter.collection))
90
+ return false;
91
+ if (filter.source?.length && !anyOf(prov?.source ? [prov.source] : [], filter.source))
92
+ return false;
93
+ if (filter.since || filter.until) {
94
+ const at = Date.parse(documentCapturedAt(meta));
95
+ const since = parseWhen(filter.since, now);
96
+ const until = parseWhen(filter.until, now);
97
+ if (Number.isNaN(at))
98
+ return false;
99
+ if (since !== null && at < since)
100
+ return false;
101
+ if (until !== null && at > until)
102
+ return false;
103
+ }
104
+ if (filter.text) {
105
+ const needle = filter.text.toLowerCase();
106
+ const hay = [
107
+ prov?.title ?? '',
108
+ meta.canonicalUrl ?? prov?.url ?? '',
109
+ meta.filePath,
110
+ prov?.note ?? '',
111
+ ]
112
+ .join(' ')
113
+ .toLowerCase();
114
+ if (!hay.includes(needle))
115
+ return false;
116
+ }
117
+ return true;
118
+ }
119
+ export function filterDocuments(docs, filter = {}, now = Date.now()) {
120
+ return docs.filter((d) => matchesLibraryFilter(d, filter, now));
121
+ }
122
+ export function sortDocuments(docs, sort = 'captured', order = 'desc') {
123
+ const dir = order === 'asc' ? 1 : -1;
124
+ const key = (d) => {
125
+ switch (sort) {
126
+ case 'indexed':
127
+ return d.indexedAt ?? '';
128
+ case 'title':
129
+ return (d.provenance?.title ?? path.basename(d.filePath)).toLowerCase();
130
+ case 'path':
131
+ return d.filePath;
132
+ case 'size':
133
+ return d.size ?? 0;
134
+ default:
135
+ return documentCapturedAt(d);
136
+ }
137
+ };
138
+ return [...docs].sort((a, b) => {
139
+ const ka = key(a);
140
+ const kb = key(b);
141
+ if (ka === kb)
142
+ return a.filePath.localeCompare(b.filePath);
143
+ return ka < kb ? -dir : dir;
144
+ });
145
+ }
146
+ /** The flat, JSON-friendly row the GUI and `--json` consumers read. */
147
+ export function libraryEntry(meta) {
148
+ const prov = meta.provenance;
149
+ const url = meta.canonicalUrl ?? prov?.canonicalUrl ?? prov?.url;
150
+ return {
151
+ filePath: meta.filePath,
152
+ scope: meta.scope,
153
+ title: prov?.title ?? path.basename(meta.filePath),
154
+ ...(url ? { url } : {}),
155
+ ...(documentSite(meta) ? { site: documentSite(meta) } : {}),
156
+ capturedAt: documentCapturedAt(meta),
157
+ indexedAt: meta.indexedAt,
158
+ ...(prov?.source ? { source: prov.source } : {}),
159
+ ...(prov?.collection ? { collection: prov.collection } : {}),
160
+ tags: prov?.tags ?? [],
161
+ chunkCount: meta.chunkCount,
162
+ size: meta.size,
163
+ ...(meta.version ? { version: meta.version } : {}),
164
+ captured: !!prov || !!meta.canonicalUrl,
165
+ };
166
+ }
167
+ /** Browse the library: filter, sort, cap. Never throws on an empty store. */
168
+ export function listLibrary(docs, opts = {}) {
169
+ const now = opts.now ?? Date.now();
170
+ const filtered = filterDocuments(docs, opts, now);
171
+ const sorted = sortDocuments(filtered, opts.sort ?? 'captured', opts.order ?? 'desc');
172
+ const capped = opts.limit && opts.limit > 0 ? sorted.slice(0, opts.limit) : sorted;
173
+ return capped.map(libraryEntry);
174
+ }
175
+ /** Facet counts for the current view — what a sidebar renders. */
176
+ export function libraryFacets(docs) {
177
+ const tally = (values) => {
178
+ const counts = new Map();
179
+ for (const v of values) {
180
+ if (!v)
181
+ continue;
182
+ counts.set(v, (counts.get(v) ?? 0) + 1);
183
+ }
184
+ return [...counts.entries()]
185
+ .map(([value, count]) => ({ value, count }))
186
+ .sort((a, b) => b.count - a.count || a.value.localeCompare(b.value));
187
+ };
188
+ return {
189
+ sites: tally(docs.map(documentSite)),
190
+ tags: tally(docs.flatMap((d) => d.provenance?.tags ?? [])),
191
+ collections: tally(docs.map((d) => d.provenance?.collection)),
192
+ sources: tally(docs.map((d) => d.provenance?.source)),
193
+ };
194
+ }
195
+ //# sourceMappingURL=library.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library.js","sourceRoot":"","sources":["../../../src/knowledge/library.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * "Have I already saved this?" (RCL-02) — one URL in, one answer out.
3
+ *
4
+ * The browser extension asks this on every navigation. That is the only
5
+ * thing that shapes this module:
6
+ *
7
+ * - it NEVER throws. An empty store, a store that has never been written,
8
+ * a URL that is not a URL — all of them are `{saved: false}`, because a
9
+ * page load must not be able to fail on a badge;
10
+ * - it is a pure read. No embedder, no subprocess, no index write. The
11
+ * answer comes off the metadata log, which is a file read;
12
+ * - it answers the WHOLE question in one call. `doc list` can already say
13
+ * that a URL is present, but not what note was written at save time —
14
+ * and "you saved this, and here is why you said you were saving it" is
15
+ * the entire value of the badge over a bookmark.
16
+ *
17
+ * Identity is `captureIdentityUrl`'s rule and nothing else: canonical URL
18
+ * when the capturer resolved one, fragment stripped, nothing else rewritten.
19
+ * Matching more loosely than the ingest side would make the badge claim
20
+ * pages are saved that cannot actually be found again.
21
+ *
22
+ * @module v1/cli/knowledge/lookup
23
+ */
24
+ /** What the badge and the "already saved" panel render. */
25
+ export interface UrlLookup {
26
+ saved: boolean;
27
+ /** The identity URL the lookup was performed against. */
28
+ url: string;
29
+ title?: string;
30
+ site?: string;
31
+ /** When the page was captured (not when it was indexed). */
32
+ capturedAt?: string;
33
+ /** RCL-06: 1 for a first save, +1 per stored revision. 0 when unsaved. */
34
+ versions: number;
35
+ /** The note written at save time (CLIP-07) — the reason it was kept. */
36
+ note?: string;
37
+ tags: string[];
38
+ collection?: string;
39
+ source?: string;
40
+ /** The indexed file (`…/readable.md`). */
41
+ filePath?: string;
42
+ /** The capture envelope directory holding it — what "open the archived
43
+ * copy" opens. Absent when the document is an ordinary file on disk. */
44
+ envelope?: string;
45
+ scope?: string;
46
+ contentHash?: string;
47
+ /** RCL-04: how many highlight notes were saved on this page. */
48
+ highlights?: number;
49
+ }
50
+ export interface LookupOptions {
51
+ rootDir?: string;
52
+ scope?: string;
53
+ /** Skip the `highlights.json` read. The badge path does not need it. */
54
+ withHighlights?: boolean;
55
+ }
56
+ /**
57
+ * identityUrl mirrors `captureIdentityUrl` for a raw URL rather than a
58
+ * provenance record: drop the fragment, trim, rewrite nothing else.
59
+ *
60
+ * Duplicated deliberately rather than reshaping the URL into a fake
61
+ * `CaptureProvenance` to borrow that function — the two callers mean
62
+ * different things ("the URL a tab is on" vs. "what this capture is of")
63
+ * and only happen to agree on the rule.
64
+ */
65
+ export declare function identityUrl(raw: string | undefined): string;
66
+ /** The envelope directory for an indexed file, or undefined when the file
67
+ * is not inside one. */
68
+ export declare function envelopeFor(filePath: string | undefined): string | undefined;
69
+ /**
70
+ * lookupUrl answers whether this URL is in the store, and what is known
71
+ * about it. `rootDir` is the store to look in; pass the global brain's root
72
+ * to ask the personal store.
73
+ */
74
+ export declare function lookupUrl(rawUrl: string, opts?: LookupOptions): UrlLookup;
75
+ /**
76
+ * lookupUrls answers a batch in one pass over the metadata, for a caller
77
+ * with several tabs to ask about. Same rules, same guarantees.
78
+ */
79
+ export declare function lookupUrls(urls: readonly string[], opts?: LookupOptions): UrlLookup[];
80
+ //# sourceMappingURL=lookup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../../src/knowledge/lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAaH,2DAA2D;AAC3D,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;6EACyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAID;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI3D;AAwBD;yBACyB;AACzB,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAQ5E;AAMD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,SAAS,CA8D7E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,GAAE,aAAkB,GAAG,SAAS,EAAE,CAEzF"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * "Have I already saved this?" (RCL-02) — one URL in, one answer out.
3
+ *
4
+ * The browser extension asks this on every navigation. That is the only
5
+ * thing that shapes this module:
6
+ *
7
+ * - it NEVER throws. An empty store, a store that has never been written,
8
+ * a URL that is not a URL — all of them are `{saved: false}`, because a
9
+ * page load must not be able to fail on a badge;
10
+ * - it is a pure read. No embedder, no subprocess, no index write. The
11
+ * answer comes off the metadata log, which is a file read;
12
+ * - it answers the WHOLE question in one call. `doc list` can already say
13
+ * that a URL is present, but not what note was written at save time —
14
+ * and "you saved this, and here is why you said you were saving it" is
15
+ * the entire value of the badge over a bookmark.
16
+ *
17
+ * Identity is `captureIdentityUrl`'s rule and nothing else: canonical URL
18
+ * when the capturer resolved one, fragment stripped, nothing else rewritten.
19
+ * Matching more loosely than the ingest side would make the badge claim
20
+ * pages are saved that cannot actually be found again.
21
+ *
22
+ * @module v1/cli/knowledge/lookup
23
+ */
24
+ import * as fs from 'node:fs';
25
+ import * as path from 'node:path';
26
+ import { isCaptureEnvelope } from './capture-envelope.js';
27
+ import { getKnowledgeRoot, listDocuments, listDocumentVersions, } from './document-pipeline.js';
28
+ import { documentCapturedAt, documentSite } from './library.js';
29
+ const EMPTY = (url) => ({ saved: false, url, versions: 0, tags: [] });
30
+ /**
31
+ * identityUrl mirrors `captureIdentityUrl` for a raw URL rather than a
32
+ * provenance record: drop the fragment, trim, rewrite nothing else.
33
+ *
34
+ * Duplicated deliberately rather than reshaping the URL into a fake
35
+ * `CaptureProvenance` to borrow that function — the two callers mean
36
+ * different things ("the URL a tab is on" vs. "what this capture is of")
37
+ * and only happen to agree on the rule.
38
+ */
39
+ export function identityUrl(raw) {
40
+ const s = String(raw ?? '').trim();
41
+ const hash = s.indexOf('#');
42
+ return (hash === -1 ? s : s.slice(0, hash)).trim();
43
+ }
44
+ /** The identity URL a record is addressable by, or undefined. */
45
+ function recordUrl(meta) {
46
+ const url = meta.canonicalUrl ?? meta.provenance?.canonicalUrl ?? meta.provenance?.url;
47
+ return url ? identityUrl(url) : undefined;
48
+ }
49
+ /**
50
+ * countHighlights reads the `highlights.json` the extension wrote beside
51
+ * the document (RCL-04). Silent on every failure: the count is decoration
52
+ * on an answer that is already complete without it.
53
+ */
54
+ function countHighlights(envelope) {
55
+ try {
56
+ const file = path.join(envelope, 'highlights.json');
57
+ if (!fs.existsSync(file))
58
+ return 0;
59
+ const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
60
+ return Array.isArray(parsed?.highlights) ? parsed.highlights.length : 0;
61
+ }
62
+ catch {
63
+ return 0;
64
+ }
65
+ }
66
+ /** The envelope directory for an indexed file, or undefined when the file
67
+ * is not inside one. */
68
+ export function envelopeFor(filePath) {
69
+ if (!filePath)
70
+ return undefined;
71
+ const dir = path.dirname(path.resolve(filePath));
72
+ try {
73
+ return isCaptureEnvelope(dir) ? dir : undefined;
74
+ }
75
+ catch {
76
+ return undefined;
77
+ }
78
+ }
79
+ function provenanceOf(meta) {
80
+ return meta.provenance ?? {};
81
+ }
82
+ /**
83
+ * lookupUrl answers whether this URL is in the store, and what is known
84
+ * about it. `rootDir` is the store to look in; pass the global brain's root
85
+ * to ask the personal store.
86
+ */
87
+ export function lookupUrl(rawUrl, opts = {}) {
88
+ const url = identityUrl(rawUrl);
89
+ if (!url)
90
+ return EMPTY('');
91
+ // The SAME routing the ingest used: scope `global` lives in the personal
92
+ // cross-project brain, not under `rootDir`. Reading the wrong store would
93
+ // report every globally-captured page as unsaved.
94
+ let root;
95
+ let docs;
96
+ try {
97
+ root = opts.scope ? getKnowledgeRoot(opts.scope, opts.rootDir) : opts.rootDir;
98
+ docs = listDocuments(root, opts.scope);
99
+ }
100
+ catch {
101
+ // A store that has never been written, or one this process cannot
102
+ // read. Neither is an error worth failing a page load over.
103
+ return EMPTY(url);
104
+ }
105
+ const matches = docs.filter((d) => recordUrl(d) === url);
106
+ if (!matches.length)
107
+ return EMPTY(url);
108
+ // The live record with the highest version. A re-captured page lands at
109
+ // a new path, so several records can match and only the newest is the
110
+ // one the badge should describe.
111
+ const best = matches.reduce((a, b) => ((b.version ?? 0) > (a.version ?? 0) ? b : a));
112
+ const prov = provenanceOf(best);
113
+ // The version COUNT is the larger of the record's own number and what
114
+ // the append-only log still holds: the log is compacted past 1MB, and
115
+ // the `version` field is the durable count. Reading only the log would
116
+ // under-report a long-lived document.
117
+ let logged = 0;
118
+ try {
119
+ logged = listDocumentVersions(root, best.canonicalUrl ?? url, opts.scope).length;
120
+ }
121
+ catch {
122
+ logged = 0;
123
+ }
124
+ const versions = Math.max(best.version ?? 1, logged, 1);
125
+ const envelope = envelopeFor(best.filePath);
126
+ const answer = {
127
+ saved: true,
128
+ url,
129
+ versions,
130
+ tags: prov.tags ?? [],
131
+ ...(prov.title ? { title: prov.title } : {}),
132
+ ...(documentSite(best) ? { site: documentSite(best) } : {}),
133
+ ...(documentCapturedAt(best) ? { capturedAt: documentCapturedAt(best) } : {}),
134
+ ...(prov.note ? { note: prov.note } : {}),
135
+ ...(prov.collection ? { collection: prov.collection } : {}),
136
+ ...(prov.source ? { source: prov.source } : {}),
137
+ filePath: best.filePath,
138
+ ...(envelope ? { envelope } : {}),
139
+ scope: best.scope,
140
+ ...(best.contentHash ? { contentHash: best.contentHash } : {}),
141
+ };
142
+ if (opts.withHighlights && envelope) {
143
+ const count = countHighlights(envelope);
144
+ if (count)
145
+ answer.highlights = count;
146
+ }
147
+ return answer;
148
+ }
149
+ /**
150
+ * lookupUrls answers a batch in one pass over the metadata, for a caller
151
+ * with several tabs to ask about. Same rules, same guarantees.
152
+ */
153
+ export function lookupUrls(urls, opts = {}) {
154
+ return urls.map((u) => lookupUrl(u, opts));
155
+ }
156
+ //# sourceMappingURL=lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../../src/knowledge/lookup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * MHTML / MHT container parsing (RCL-01).
3
+ *
4
+ * An MHTML archive is an RFC 2557 `multipart/related` MIME message: the page
5
+ * plus every subresource it referenced, each part carrying its own transfer
6
+ * encoding and charset. Chrome's `Page.captureSnapshot` writes them
7
+ * quoted-printable; Internet Explorer and most "save as web archive" tools
8
+ * write base64.
9
+ *
10
+ * Only the ROOT frame is prose. Picking the first `text/html` part instead is
11
+ * how an ad iframe ends up indexed as the article, so the root is resolved
12
+ * from the container's `Snapshot-Content-Location` / `Content-Location` when
13
+ * one is present.
14
+ *
15
+ * Read the file as `latin1` (or pass a Buffer): byte fidelity matters before
16
+ * transfer decoding, and the real charset is only known per part.
17
+ *
18
+ * @module v1/cli/knowledge/mhtml
19
+ */
20
+ export interface MhtmlPart {
21
+ /** Lowercased MIME type without parameters, e.g. `text/html`. */
22
+ contentType: string;
23
+ /** Charset from the part's Content-Type, lowercased, or null. */
24
+ charset: string | null;
25
+ /** Content-Location, or null. */
26
+ location: string | null;
27
+ /** Lowercased Content-Transfer-Encoding; `binary` when unstated. */
28
+ encoding: string;
29
+ /** Raw bytes after transfer decoding. */
30
+ body: Buffer;
31
+ headers: Record<string, string>;
32
+ }
33
+ export interface ParsedMhtml {
34
+ /** The part holding the page itself, or null when there is no HTML part. */
35
+ root: MhtmlPart | null;
36
+ parts: MhtmlPart[];
37
+ /** Container `Snapshot-Content-Location`/`Content-Location` header. */
38
+ snapshotLocation: string | null;
39
+ /** Container `Subject` header — Chrome writes the page title here. */
40
+ subject: string | null;
41
+ }
42
+ /** Decode a quoted-printable body to bytes: soft line breaks vanish, `=XX`
43
+ * becomes one byte, everything else is its own latin1 byte. */
44
+ export declare function decodeQuotedPrintable(input: string): Buffer;
45
+ /** Decode bytes under a MIME charset, falling back to UTF-8 (then latin1)
46
+ * rather than failing an ingest over an exotic label. */
47
+ export declare function decodeCharset(bytes: Buffer, charset: string | null): string;
48
+ /**
49
+ * Parse an MHTML container. Anything that is not a well-formed multipart
50
+ * message is treated as a single part, so a plain `.html` file renamed to
51
+ * `.mhtml` still ingests.
52
+ */
53
+ export declare function parseMhtml(raw: string | Buffer): ParsedMhtml;
54
+ /** Parse a container and return its root frame decoded to a string. */
55
+ export declare function mhtmlToHtml(raw: string | Buffer): {
56
+ html: string;
57
+ location: string | null;
58
+ subject: string | null;
59
+ };
60
+ //# sourceMappingURL=mhtml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mhtml.d.ts","sourceRoot":"","sources":["../../../src/knowledge/mhtml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,SAAS;IACxB,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sEAAsE;IACtE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;gEACgE;AAChE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAyB3D;AAaD;0DAC0D;AAC1D,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAU3E;AA4CD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAiC5D;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAOA"}