@tenphi/akno-core 0.1.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 (485) hide show
  1. package/LICENSE +83 -0
  2. package/README.md +26 -0
  3. package/config/default.jsonc +548 -0
  4. package/dist/bench/answer-corpus.d.ts +48 -0
  5. package/dist/bench/answer-corpus.d.ts.map +1 -0
  6. package/dist/bench/answer-corpus.js +491 -0
  7. package/dist/bench/answer-corpus.js.map +1 -0
  8. package/dist/bench/answer.d.ts +156 -0
  9. package/dist/bench/answer.d.ts.map +1 -0
  10. package/dist/bench/answer.js +608 -0
  11. package/dist/bench/answer.js.map +1 -0
  12. package/dist/bench/auto-recall-answer-corpus.d.ts +21 -0
  13. package/dist/bench/auto-recall-answer-corpus.d.ts.map +1 -0
  14. package/dist/bench/auto-recall-answer-corpus.js +245 -0
  15. package/dist/bench/auto-recall-answer-corpus.js.map +1 -0
  16. package/dist/bench/auto-recall-answer.d.ts +198 -0
  17. package/dist/bench/auto-recall-answer.d.ts.map +1 -0
  18. package/dist/bench/auto-recall-answer.js +720 -0
  19. package/dist/bench/auto-recall-answer.js.map +1 -0
  20. package/dist/bench/auto-recall-corpus.d.ts +45 -0
  21. package/dist/bench/auto-recall-corpus.d.ts.map +1 -0
  22. package/dist/bench/auto-recall-corpus.js +221 -0
  23. package/dist/bench/auto-recall-corpus.js.map +1 -0
  24. package/dist/bench/auto-recall.d.ts +171 -0
  25. package/dist/bench/auto-recall.d.ts.map +1 -0
  26. package/dist/bench/auto-recall.js +651 -0
  27. package/dist/bench/auto-recall.js.map +1 -0
  28. package/dist/bench/entity-resolution.d.ts +37 -0
  29. package/dist/bench/entity-resolution.d.ts.map +1 -0
  30. package/dist/bench/entity-resolution.js +121 -0
  31. package/dist/bench/entity-resolution.js.map +1 -0
  32. package/dist/bench/graph.d.ts +57 -0
  33. package/dist/bench/graph.d.ts.map +1 -0
  34. package/dist/bench/graph.js +573 -0
  35. package/dist/bench/graph.js.map +1 -0
  36. package/dist/bench/llm-ranking-probe.d.ts +27 -0
  37. package/dist/bench/llm-ranking-probe.d.ts.map +1 -0
  38. package/dist/bench/llm-ranking-probe.js +105 -0
  39. package/dist/bench/llm-ranking-probe.js.map +1 -0
  40. package/dist/bench/merge-discovery-corpus.d.ts +26 -0
  41. package/dist/bench/merge-discovery-corpus.d.ts.map +1 -0
  42. package/dist/bench/merge-discovery-corpus.js +114 -0
  43. package/dist/bench/merge-discovery-corpus.js.map +1 -0
  44. package/dist/bench/merge-discovery-review.d.ts +81 -0
  45. package/dist/bench/merge-discovery-review.d.ts.map +1 -0
  46. package/dist/bench/merge-discovery-review.js +149 -0
  47. package/dist/bench/merge-discovery-review.js.map +1 -0
  48. package/dist/bench/merge-discovery.d.ts +122 -0
  49. package/dist/bench/merge-discovery.d.ts.map +1 -0
  50. package/dist/bench/merge-discovery.js +390 -0
  51. package/dist/bench/merge-discovery.js.map +1 -0
  52. package/dist/bench/mixed-retrieval.d.ts +35 -0
  53. package/dist/bench/mixed-retrieval.d.ts.map +1 -0
  54. package/dist/bench/mixed-retrieval.js +355 -0
  55. package/dist/bench/mixed-retrieval.js.map +1 -0
  56. package/dist/bench/ranking-corpus.d.ts +29 -0
  57. package/dist/bench/ranking-corpus.d.ts.map +1 -0
  58. package/dist/bench/ranking-corpus.js +514 -0
  59. package/dist/bench/ranking-corpus.js.map +1 -0
  60. package/dist/bench/ranking-end-to-end.d.ts +112 -0
  61. package/dist/bench/ranking-end-to-end.d.ts.map +1 -0
  62. package/dist/bench/ranking-end-to-end.js +479 -0
  63. package/dist/bench/ranking-end-to-end.js.map +1 -0
  64. package/dist/bench/ranking-latency.d.ts +71 -0
  65. package/dist/bench/ranking-latency.d.ts.map +1 -0
  66. package/dist/bench/ranking-latency.js +130 -0
  67. package/dist/bench/ranking-latency.js.map +1 -0
  68. package/dist/bench/ranking-matrix.d.ts +141 -0
  69. package/dist/bench/ranking-matrix.d.ts.map +1 -0
  70. package/dist/bench/ranking-matrix.js +526 -0
  71. package/dist/bench/ranking-matrix.js.map +1 -0
  72. package/dist/bench/ranking-review.d.ts +93 -0
  73. package/dist/bench/ranking-review.d.ts.map +1 -0
  74. package/dist/bench/ranking-review.js +249 -0
  75. package/dist/bench/ranking-review.js.map +1 -0
  76. package/dist/bench/ranking.d.ts +122 -0
  77. package/dist/bench/ranking.d.ts.map +1 -0
  78. package/dist/bench/ranking.js +547 -0
  79. package/dist/bench/ranking.js.map +1 -0
  80. package/dist/bench.d.ts +60 -0
  81. package/dist/bench.d.ts.map +1 -0
  82. package/dist/bench.js +167 -0
  83. package/dist/bench.js.map +1 -0
  84. package/dist/config/jsonc.d.ts +8 -0
  85. package/dist/config/jsonc.d.ts.map +1 -0
  86. package/dist/config/jsonc.js +85 -0
  87. package/dist/config/jsonc.js.map +1 -0
  88. package/dist/config/load.d.ts +43 -0
  89. package/dist/config/load.d.ts.map +1 -0
  90. package/dist/config/load.js +608 -0
  91. package/dist/config/load.js.map +1 -0
  92. package/dist/config/paths.d.ts +10 -0
  93. package/dist/config/paths.d.ts.map +1 -0
  94. package/dist/config/paths.js +38 -0
  95. package/dist/config/paths.js.map +1 -0
  96. package/dist/config/schema.d.ts +698 -0
  97. package/dist/config/schema.d.ts.map +1 -0
  98. package/dist/config/schema.js +394 -0
  99. package/dist/config/schema.js.map +1 -0
  100. package/dist/config/write-rules.d.ts +41 -0
  101. package/dist/config/write-rules.d.ts.map +1 -0
  102. package/dist/config/write-rules.js +225 -0
  103. package/dist/config/write-rules.js.map +1 -0
  104. package/dist/config/write-setup.d.ts +42 -0
  105. package/dist/config/write-setup.d.ts.map +1 -0
  106. package/dist/config/write-setup.js +358 -0
  107. package/dist/config/write-setup.js.map +1 -0
  108. package/dist/context.d.ts +64 -0
  109. package/dist/context.d.ts.map +1 -0
  110. package/dist/context.js +14 -0
  111. package/dist/context.js.map +1 -0
  112. package/dist/doctor.d.ts +115 -0
  113. package/dist/doctor.d.ts.map +1 -0
  114. package/dist/doctor.js +388 -0
  115. package/dist/doctor.js.map +1 -0
  116. package/dist/index/chunk.d.ts +62 -0
  117. package/dist/index/chunk.d.ts.map +1 -0
  118. package/dist/index/chunk.js +307 -0
  119. package/dist/index/chunk.js.map +1 -0
  120. package/dist/index/defer.d.ts +32 -0
  121. package/dist/index/defer.d.ts.map +1 -0
  122. package/dist/index/defer.js +66 -0
  123. package/dist/index/defer.js.map +1 -0
  124. package/dist/index/derive.d.ts +99 -0
  125. package/dist/index/derive.d.ts.map +1 -0
  126. package/dist/index/derive.js +378 -0
  127. package/dist/index/derive.js.map +1 -0
  128. package/dist/index/entity-resolution.d.ts +68 -0
  129. package/dist/index/entity-resolution.d.ts.map +1 -0
  130. package/dist/index/entity-resolution.js +305 -0
  131. package/dist/index/entity-resolution.js.map +1 -0
  132. package/dist/index/graph.d.ts +46 -0
  133. package/dist/index/graph.d.ts.map +1 -0
  134. package/dist/index/graph.js +618 -0
  135. package/dist/index/graph.js.map +1 -0
  136. package/dist/index/indexer.d.ts +301 -0
  137. package/dist/index/indexer.d.ts.map +1 -0
  138. package/dist/index/indexer.js +1398 -0
  139. package/dist/index/indexer.js.map +1 -0
  140. package/dist/index/revision-barrier.d.ts +30 -0
  141. package/dist/index/revision-barrier.d.ts.map +1 -0
  142. package/dist/index/revision-barrier.js +140 -0
  143. package/dist/index/revision-barrier.js.map +1 -0
  144. package/dist/index.d.ts +55 -0
  145. package/dist/index.d.ts.map +1 -0
  146. package/dist/index.js +37 -0
  147. package/dist/index.js.map +1 -0
  148. package/dist/ingest/adoption-eligibility.d.ts +4 -0
  149. package/dist/ingest/adoption-eligibility.d.ts.map +1 -0
  150. package/dist/ingest/adoption-eligibility.js +18 -0
  151. package/dist/ingest/adoption-eligibility.js.map +1 -0
  152. package/dist/ingest/availability.d.ts +15 -0
  153. package/dist/ingest/availability.d.ts.map +1 -0
  154. package/dist/ingest/availability.js +37 -0
  155. package/dist/ingest/availability.js.map +1 -0
  156. package/dist/ingest/extract.d.ts +58 -0
  157. package/dist/ingest/extract.d.ts.map +1 -0
  158. package/dist/ingest/extract.js +255 -0
  159. package/dist/ingest/extract.js.map +1 -0
  160. package/dist/ingest/fetch.d.ts +35 -0
  161. package/dist/ingest/fetch.d.ts.map +1 -0
  162. package/dist/ingest/fetch.js +142 -0
  163. package/dist/ingest/fetch.js.map +1 -0
  164. package/dist/ingest/inbox.d.ts +53 -0
  165. package/dist/ingest/inbox.d.ts.map +1 -0
  166. package/dist/ingest/inbox.js +110 -0
  167. package/dist/ingest/inbox.js.map +1 -0
  168. package/dist/ingest/name.d.ts +72 -0
  169. package/dist/ingest/name.d.ts.map +1 -0
  170. package/dist/ingest/name.js +208 -0
  171. package/dist/ingest/name.js.map +1 -0
  172. package/dist/ingest/parts.d.ts +78 -0
  173. package/dist/ingest/parts.d.ts.map +1 -0
  174. package/dist/ingest/parts.js +52 -0
  175. package/dist/ingest/parts.js.map +1 -0
  176. package/dist/ingest/rendition.d.ts +75 -0
  177. package/dist/ingest/rendition.d.ts.map +1 -0
  178. package/dist/ingest/rendition.js +92 -0
  179. package/dist/ingest/rendition.js.map +1 -0
  180. package/dist/ingest/store.d.ts +66 -0
  181. package/dist/ingest/store.d.ts.map +1 -0
  182. package/dist/ingest/store.js +92 -0
  183. package/dist/ingest/store.js.map +1 -0
  184. package/dist/kb/folders.d.ts +37 -0
  185. package/dist/kb/folders.d.ts.map +1 -0
  186. package/dist/kb/folders.js +133 -0
  187. package/dist/kb/folders.js.map +1 -0
  188. package/dist/kb/frontmatter.d.ts +91 -0
  189. package/dist/kb/frontmatter.d.ts.map +1 -0
  190. package/dist/kb/frontmatter.js +274 -0
  191. package/dist/kb/frontmatter.js.map +1 -0
  192. package/dist/kb/line-facts.d.ts +29 -0
  193. package/dist/kb/line-facts.d.ts.map +1 -0
  194. package/dist/kb/line-facts.js +23 -0
  195. package/dist/kb/line-facts.js.map +1 -0
  196. package/dist/kb/page.d.ts +92 -0
  197. package/dist/kb/page.d.ts.map +1 -0
  198. package/dist/kb/page.js +243 -0
  199. package/dist/kb/page.js.map +1 -0
  200. package/dist/kb/scan.d.ts +38 -0
  201. package/dist/kb/scan.d.ts.map +1 -0
  202. package/dist/kb/scan.js +109 -0
  203. package/dist/kb/scan.js.map +1 -0
  204. package/dist/kb/words.d.ts +30 -0
  205. package/dist/kb/words.d.ts.map +1 -0
  206. package/dist/kb/words.js +107 -0
  207. package/dist/kb/words.js.map +1 -0
  208. package/dist/maintenance/adopt.d.ts +65 -0
  209. package/dist/maintenance/adopt.d.ts.map +1 -0
  210. package/dist/maintenance/adopt.js +238 -0
  211. package/dist/maintenance/adopt.js.map +1 -0
  212. package/dist/maintenance/budget.d.ts +55 -0
  213. package/dist/maintenance/budget.d.ts.map +1 -0
  214. package/dist/maintenance/budget.js +61 -0
  215. package/dist/maintenance/budget.js.map +1 -0
  216. package/dist/maintenance/conflicts.d.ts +105 -0
  217. package/dist/maintenance/conflicts.d.ts.map +1 -0
  218. package/dist/maintenance/conflicts.js +368 -0
  219. package/dist/maintenance/conflicts.js.map +1 -0
  220. package/dist/maintenance/contradictions.d.ts +34 -0
  221. package/dist/maintenance/contradictions.d.ts.map +1 -0
  222. package/dist/maintenance/contradictions.js +199 -0
  223. package/dist/maintenance/contradictions.js.map +1 -0
  224. package/dist/maintenance/curate.d.ts +156 -0
  225. package/dist/maintenance/curate.d.ts.map +1 -0
  226. package/dist/maintenance/curate.js +2070 -0
  227. package/dist/maintenance/curate.js.map +1 -0
  228. package/dist/maintenance/dream.d.ts +139 -0
  229. package/dist/maintenance/dream.d.ts.map +1 -0
  230. package/dist/maintenance/dream.js +1632 -0
  231. package/dist/maintenance/dream.js.map +1 -0
  232. package/dist/maintenance/graph-candidates.d.ts +19 -0
  233. package/dist/maintenance/graph-candidates.d.ts.map +1 -0
  234. package/dist/maintenance/graph-candidates.js +120 -0
  235. package/dist/maintenance/graph-candidates.js.map +1 -0
  236. package/dist/maintenance/housekeeping.d.ts +81 -0
  237. package/dist/maintenance/housekeeping.d.ts.map +1 -0
  238. package/dist/maintenance/housekeeping.js +281 -0
  239. package/dist/maintenance/housekeeping.js.map +1 -0
  240. package/dist/maintenance/link-repairs.d.ts +58 -0
  241. package/dist/maintenance/link-repairs.d.ts.map +1 -0
  242. package/dist/maintenance/link-repairs.js +281 -0
  243. package/dist/maintenance/link-repairs.js.map +1 -0
  244. package/dist/maintenance/log.d.ts +41 -0
  245. package/dist/maintenance/log.d.ts.map +1 -0
  246. package/dist/maintenance/log.js +72 -0
  247. package/dist/maintenance/log.js.map +1 -0
  248. package/dist/maintenance/managed-item-routing.d.ts +48 -0
  249. package/dist/maintenance/managed-item-routing.d.ts.map +1 -0
  250. package/dist/maintenance/managed-item-routing.js +281 -0
  251. package/dist/maintenance/managed-item-routing.js.map +1 -0
  252. package/dist/maintenance/managed-item-sources.d.ts +38 -0
  253. package/dist/maintenance/managed-item-sources.d.ts.map +1 -0
  254. package/dist/maintenance/managed-item-sources.js +324 -0
  255. package/dist/maintenance/managed-item-sources.js.map +1 -0
  256. package/dist/maintenance/managed-items.d.ts +162 -0
  257. package/dist/maintenance/managed-items.d.ts.map +1 -0
  258. package/dist/maintenance/managed-items.js +1329 -0
  259. package/dist/maintenance/managed-items.js.map +1 -0
  260. package/dist/maintenance/merge-classifier.d.ts +19 -0
  261. package/dist/maintenance/merge-classifier.d.ts.map +1 -0
  262. package/dist/maintenance/merge-classifier.js +49 -0
  263. package/dist/maintenance/merge-classifier.js.map +1 -0
  264. package/dist/maintenance/model-telemetry.d.ts +45 -0
  265. package/dist/maintenance/model-telemetry.d.ts.map +1 -0
  266. package/dist/maintenance/model-telemetry.js +107 -0
  267. package/dist/maintenance/model-telemetry.js.map +1 -0
  268. package/dist/maintenance/observe.d.ts +72 -0
  269. package/dist/maintenance/observe.d.ts.map +1 -0
  270. package/dist/maintenance/observe.js +265 -0
  271. package/dist/maintenance/observe.js.map +1 -0
  272. package/dist/maintenance/path-policy.d.ts +83 -0
  273. package/dist/maintenance/path-policy.d.ts.map +1 -0
  274. package/dist/maintenance/path-policy.js +360 -0
  275. package/dist/maintenance/path-policy.js.map +1 -0
  276. package/dist/maintenance/plans.d.ts +366 -0
  277. package/dist/maintenance/plans.d.ts.map +1 -0
  278. package/dist/maintenance/plans.js +4060 -0
  279. package/dist/maintenance/plans.js.map +1 -0
  280. package/dist/maintenance/profile.d.ts +33 -0
  281. package/dist/maintenance/profile.d.ts.map +1 -0
  282. package/dist/maintenance/profile.js +99 -0
  283. package/dist/maintenance/profile.js.map +1 -0
  284. package/dist/maintenance/recovery.d.ts +38 -0
  285. package/dist/maintenance/recovery.d.ts.map +1 -0
  286. package/dist/maintenance/recovery.js +217 -0
  287. package/dist/maintenance/recovery.js.map +1 -0
  288. package/dist/maintenance/repair.d.ts +37 -0
  289. package/dist/maintenance/repair.d.ts.map +1 -0
  290. package/dist/maintenance/repair.js +183 -0
  291. package/dist/maintenance/repair.js.map +1 -0
  292. package/dist/maintenance/rule-drift.d.ts +104 -0
  293. package/dist/maintenance/rule-drift.d.ts.map +1 -0
  294. package/dist/maintenance/rule-drift.js +507 -0
  295. package/dist/maintenance/rule-drift.js.map +1 -0
  296. package/dist/maintenance/run-verification.d.ts +44 -0
  297. package/dist/maintenance/run-verification.d.ts.map +1 -0
  298. package/dist/maintenance/run-verification.js +253 -0
  299. package/dist/maintenance/run-verification.js.map +1 -0
  300. package/dist/maintenance/runs.d.ts +142 -0
  301. package/dist/maintenance/runs.d.ts.map +1 -0
  302. package/dist/maintenance/runs.js +439 -0
  303. package/dist/maintenance/runs.js.map +1 -0
  304. package/dist/maintenance/semantic-merge-discovery.d.ts +54 -0
  305. package/dist/maintenance/semantic-merge-discovery.d.ts.map +1 -0
  306. package/dist/maintenance/semantic-merge-discovery.js +308 -0
  307. package/dist/maintenance/semantic-merge-discovery.js.map +1 -0
  308. package/dist/maintenance/temporal.d.ts +44 -0
  309. package/dist/maintenance/temporal.d.ts.map +1 -0
  310. package/dist/maintenance/temporal.js +295 -0
  311. package/dist/maintenance/temporal.js.map +1 -0
  312. package/dist/models/client.d.ts +214 -0
  313. package/dist/models/client.d.ts.map +1 -0
  314. package/dist/models/client.js +904 -0
  315. package/dist/models/client.js.map +1 -0
  316. package/dist/models/provider-api.d.ts +28 -0
  317. package/dist/models/provider-api.d.ts.map +1 -0
  318. package/dist/models/provider-api.js +320 -0
  319. package/dist/models/provider-api.js.map +1 -0
  320. package/dist/open.d.ts +163 -0
  321. package/dist/open.d.ts.map +1 -0
  322. package/dist/open.js +382 -0
  323. package/dist/open.js.map +1 -0
  324. package/dist/ops/adopt.d.ts +12 -0
  325. package/dist/ops/adopt.d.ts.map +1 -0
  326. package/dist/ops/adopt.js +138 -0
  327. package/dist/ops/adopt.js.map +1 -0
  328. package/dist/ops/answer.d.ts +29 -0
  329. package/dist/ops/answer.d.ts.map +1 -0
  330. package/dist/ops/answer.js +557 -0
  331. package/dist/ops/answer.js.map +1 -0
  332. package/dist/ops/context.d.ts +18 -0
  333. package/dist/ops/context.d.ts.map +1 -0
  334. package/dist/ops/context.js +713 -0
  335. package/dist/ops/context.js.map +1 -0
  336. package/dist/ops/folder.d.ts +23 -0
  337. package/dist/ops/folder.d.ts.map +1 -0
  338. package/dist/ops/folder.js +130 -0
  339. package/dist/ops/folder.js.map +1 -0
  340. package/dist/ops/forget.d.ts +14 -0
  341. package/dist/ops/forget.d.ts.map +1 -0
  342. package/dist/ops/forget.js +212 -0
  343. package/dist/ops/forget.js.map +1 -0
  344. package/dist/ops/graph.d.ts +10 -0
  345. package/dist/ops/graph.d.ts.map +1 -0
  346. package/dist/ops/graph.js +480 -0
  347. package/dist/ops/graph.js.map +1 -0
  348. package/dist/ops/ingest.d.ts +40 -0
  349. package/dist/ops/ingest.d.ts.map +1 -0
  350. package/dist/ops/ingest.js +434 -0
  351. package/dist/ops/ingest.js.map +1 -0
  352. package/dist/ops/list.d.ts +9 -0
  353. package/dist/ops/list.d.ts.map +1 -0
  354. package/dist/ops/list.js +217 -0
  355. package/dist/ops/list.js.map +1 -0
  356. package/dist/ops/move.d.ts +20 -0
  357. package/dist/ops/move.d.ts.map +1 -0
  358. package/dist/ops/move.js +173 -0
  359. package/dist/ops/move.js.map +1 -0
  360. package/dist/ops/read.d.ts +9 -0
  361. package/dist/ops/read.d.ts.map +1 -0
  362. package/dist/ops/read.js +271 -0
  363. package/dist/ops/read.js.map +1 -0
  364. package/dist/ops/recall.d.ts +13 -0
  365. package/dist/ops/recall.d.ts.map +1 -0
  366. package/dist/ops/recall.js +297 -0
  367. package/dist/ops/recall.js.map +1 -0
  368. package/dist/ops/remember.d.ts +34 -0
  369. package/dist/ops/remember.d.ts.map +1 -0
  370. package/dist/ops/remember.js +660 -0
  371. package/dist/ops/remember.js.map +1 -0
  372. package/dist/ops/timeline.d.ts +11 -0
  373. package/dist/ops/timeline.d.ts.map +1 -0
  374. package/dist/ops/timeline.js +111 -0
  375. package/dist/ops/timeline.js.map +1 -0
  376. package/dist/ops/undo.d.ts +9 -0
  377. package/dist/ops/undo.d.ts.map +1 -0
  378. package/dist/ops/undo.js +38 -0
  379. package/dist/ops/undo.js.map +1 -0
  380. package/dist/ops/write.d.ts +55 -0
  381. package/dist/ops/write.d.ts.map +1 -0
  382. package/dist/ops/write.js +463 -0
  383. package/dist/ops/write.js.map +1 -0
  384. package/dist/recall/assemble.d.ts +81 -0
  385. package/dist/recall/assemble.d.ts.map +1 -0
  386. package/dist/recall/assemble.js +603 -0
  387. package/dist/recall/assemble.js.map +1 -0
  388. package/dist/recall/expand.d.ts +55 -0
  389. package/dist/recall/expand.d.ts.map +1 -0
  390. package/dist/recall/expand.js +282 -0
  391. package/dist/recall/expand.js.map +1 -0
  392. package/dist/recall/graph-arm.d.ts +17 -0
  393. package/dist/recall/graph-arm.d.ts.map +1 -0
  394. package/dist/recall/graph-arm.js +227 -0
  395. package/dist/recall/graph-arm.js.map +1 -0
  396. package/dist/recall/llm-rerank.d.ts +55 -0
  397. package/dist/recall/llm-rerank.d.ts.map +1 -0
  398. package/dist/recall/llm-rerank.js +213 -0
  399. package/dist/recall/llm-rerank.js.map +1 -0
  400. package/dist/recall/reranker-calibration.d.ts +23 -0
  401. package/dist/recall/reranker-calibration.d.ts.map +1 -0
  402. package/dist/recall/reranker-calibration.js +161 -0
  403. package/dist/recall/reranker-calibration.js.map +1 -0
  404. package/dist/recall/search.d.ts +107 -0
  405. package/dist/recall/search.d.ts.map +1 -0
  406. package/dist/recall/search.js +530 -0
  407. package/dist/recall/search.js.map +1 -0
  408. package/dist/reserved.d.ts +39 -0
  409. package/dist/reserved.d.ts.map +1 -0
  410. package/dist/reserved.js +63 -0
  411. package/dist/reserved.js.map +1 -0
  412. package/dist/rules/compile.d.ts +27 -0
  413. package/dist/rules/compile.d.ts.map +1 -0
  414. package/dist/rules/compile.js +105 -0
  415. package/dist/rules/compile.js.map +1 -0
  416. package/dist/setup/model-free.d.ts +15 -0
  417. package/dist/setup/model-free.d.ts.map +1 -0
  418. package/dist/setup/model-free.js +26 -0
  419. package/dist/setup/model-free.js.map +1 -0
  420. package/dist/setup/openai.d.ts +46 -0
  421. package/dist/setup/openai.d.ts.map +1 -0
  422. package/dist/setup/openai.js +165 -0
  423. package/dist/setup/openai.js.map +1 -0
  424. package/dist/store/db.d.ts +61 -0
  425. package/dist/store/db.d.ts.map +1 -0
  426. package/dist/store/db.js +265 -0
  427. package/dist/store/db.js.map +1 -0
  428. package/dist/store/ids.d.ts +29 -0
  429. package/dist/store/ids.d.ts.map +1 -0
  430. package/dist/store/ids.js +0 -0
  431. package/dist/store/ids.js.map +1 -0
  432. package/dist/store/migrations.d.ts +54 -0
  433. package/dist/store/migrations.d.ts.map +1 -0
  434. package/dist/store/migrations.js +923 -0
  435. package/dist/store/migrations.js.map +1 -0
  436. package/dist/store/vectors.d.ts +34 -0
  437. package/dist/store/vectors.d.ts.map +1 -0
  438. package/dist/store/vectors.js +158 -0
  439. package/dist/store/vectors.js.map +1 -0
  440. package/dist/timeline/documents.d.ts +23 -0
  441. package/dist/timeline/documents.d.ts.map +1 -0
  442. package/dist/timeline/documents.js +262 -0
  443. package/dist/timeline/documents.js.map +1 -0
  444. package/dist/watch/watcher.d.ts +43 -0
  445. package/dist/watch/watcher.d.ts.map +1 -0
  446. package/dist/watch/watcher.js +143 -0
  447. package/dist/watch/watcher.js.map +1 -0
  448. package/dist/write/atomic.d.ts +34 -0
  449. package/dist/write/atomic.d.ts.map +1 -0
  450. package/dist/write/atomic.js +58 -0
  451. package/dist/write/atomic.js.map +1 -0
  452. package/dist/write/conflict.d.ts +43 -0
  453. package/dist/write/conflict.d.ts.map +1 -0
  454. package/dist/write/conflict.js +149 -0
  455. package/dist/write/conflict.js.map +1 -0
  456. package/dist/write/edit.d.ts +59 -0
  457. package/dist/write/edit.d.ts.map +1 -0
  458. package/dist/write/edit.js +231 -0
  459. package/dist/write/edit.js.map +1 -0
  460. package/dist/write/gate.d.ts +59 -0
  461. package/dist/write/gate.d.ts.map +1 -0
  462. package/dist/write/gate.js +99 -0
  463. package/dist/write/gate.js.map +1 -0
  464. package/dist/write/journal.d.ts +90 -0
  465. package/dist/write/journal.d.ts.map +1 -0
  466. package/dist/write/journal.js +187 -0
  467. package/dist/write/journal.js.map +1 -0
  468. package/dist/write/ledger.d.ts +28 -0
  469. package/dist/write/ledger.d.ts.map +1 -0
  470. package/dist/write/ledger.js +141 -0
  471. package/dist/write/ledger.js.map +1 -0
  472. package/dist/write/placement.d.ts +29 -0
  473. package/dist/write/placement.d.ts.map +1 -0
  474. package/dist/write/placement.js +140 -0
  475. package/dist/write/placement.js.map +1 -0
  476. package/dist/write/remember-fallback.d.ts +18 -0
  477. package/dist/write/remember-fallback.d.ts.map +1 -0
  478. package/dist/write/remember-fallback.js +48 -0
  479. package/dist/write/remember-fallback.js.map +1 -0
  480. package/dist/write/retain.d.ts +61 -0
  481. package/dist/write/retain.d.ts.map +1 -0
  482. package/dist/write/retain.js +272 -0
  483. package/dist/write/retain.js.map +1 -0
  484. package/package.json +50 -0
  485. package/swift/extract.swift +232 -0
@@ -0,0 +1,463 @@
1
+ import fsp from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { AknoError, WriteInput } from '@tenphi/akno-protocol';
4
+ import { parsePage } from "../kb/page.js";
5
+ import { declaredFrontmatter, readString, spliceAfterFence } from "../kb/frontmatter.js";
6
+ import { detectConflict } from "../write/conflict.js";
7
+ import { applyEdit } from "../write/edit.js";
8
+ import { insertEvent, newLedger } from "../write/ledger.js";
9
+ import { extract } from "../ingest/extract.js";
10
+ import { provenanceLines, recordDocument, storeDocument } from "../ingest/store.js";
11
+ import { fileEntry } from "../write/journal.js";
12
+ import { writeFileAtomic } from "../write/atomic.js";
13
+ import { ledgerSlug } from "../reserved.js";
14
+ /**
15
+ * Create, append, patch or replace a page — and the only thing that
16
+ * actually happens on disk is that Markdown changes. There is no fact store to
17
+ * insert into: facts appear afterwards because the indexer re-derives them from
18
+ * the sentences that are now there.
19
+ *
20
+ * The order is deliberate. Gate before conflict before write before journal before
21
+ * index, so a write that is going to be refused is refused before anything is
22
+ * touched, and a write that lands is recorded before the indexer can be told
23
+ * about it.
24
+ */
25
+ export async function write(ctx, rawInput) {
26
+ const input = WriteInput.parse(rawInput);
27
+ const actor = ctx.actor;
28
+ // An event with no slug is a real case, not a degenerate one: plenty of things
29
+ // happen that will never have a page. It goes straight to the ledger.
30
+ if (!input.slug && !input.propose_slug && input.event) {
31
+ return writeEventOnly(ctx, input.event, input.dry_run ?? false);
32
+ }
33
+ const slug = normalizeSlug(input.slug ?? input.propose_slug);
34
+ if (refusesLedgerProse({
35
+ slug,
36
+ ledger: ledgerSlug(ctx.config),
37
+ actor,
38
+ edit: input.content !== undefined ? 'content' : input.append !== undefined ? 'append' : null,
39
+ })) {
40
+ throw new AknoError('invalid', `'${slug}' is the event ledger: it takes events, not prose. Record the event with ` +
41
+ '`write({ event: { date, summary }, slug })` — the line is placed under its year for you — ' +
42
+ 'and put what is true on the page the event is about.');
43
+ }
44
+ const existing = ctx.store.db.prepare('SELECT id, rel_path FROM pages WHERE slug = ?').get(slug);
45
+ // ── Gate ────────────────────────────────────────────────────────────────
46
+ if (!existing) {
47
+ const decision = ctx.gate.check(slug, actor);
48
+ if (!decision.allowed) {
49
+ return {
50
+ status: 'ok',
51
+ outcome: 'requires_folder',
52
+ requires_folder: decision.requiresFolder,
53
+ note: `'${decision.requiresFolder.folder}' has not been declared. Call \`folder\` with a ` +
54
+ 'description of what belongs there — nobody is asked and nothing waits on approval — ' +
55
+ 'then repeat this write. Or write into one of the folders that already exists.',
56
+ };
57
+ }
58
+ }
59
+ const relPath = existing?.rel_path ?? `${slug}.md`;
60
+ const absPath = path.join(ctx.config.aknoPath, relPath);
61
+ const before = existing ? await fsp.readFile(absPath, 'utf8') : null;
62
+ const edit = resolveEdit(input, before !== null);
63
+ const edited = before === null
64
+ ? { content: composeNewPage(input, slug, edit), firstChangedLine: null }
65
+ : applyEdit(before, edit);
66
+ if (edited.content === before) {
67
+ return { status: 'ok', outcome: 'noop', note: 'the page already reads exactly that way' };
68
+ }
69
+ // ── Conflict ────────────────────────────────────────────────────────────
70
+ if (existing && before !== null) {
71
+ const parsed = parsePage(relPath, before);
72
+ const conflict = detectConflict({
73
+ store: ctx.store,
74
+ pageId: existing.id,
75
+ slug,
76
+ body: parsed.body,
77
+ bodyStartLine: parsed.bodyLine,
78
+ incoming: incomingText(input, edit),
79
+ ...(input.resolve_conflict ? { resolveToken: input.resolve_conflict } : {}),
80
+ });
81
+ if (conflict) {
82
+ return {
83
+ status: 'ok',
84
+ outcome: 'conflict',
85
+ conflict,
86
+ note: 'an existing line claims something different. Ask the user which is current, then repeat the ' +
87
+ 'write with `resolve_conflict` set to the token above.',
88
+ };
89
+ }
90
+ }
91
+ if (input.dry_run) {
92
+ return {
93
+ status: 'ok',
94
+ outcome: 'ok',
95
+ wrote: [
96
+ {
97
+ slug,
98
+ action: existing ? actionFor(edit) : 'created',
99
+ ...(edited.firstChangedLine ? { line: edited.firstChangedLine } : {}),
100
+ },
101
+ ],
102
+ note: 'dry run — nothing was written',
103
+ };
104
+ }
105
+ // ── Write ───────────────────────────────────────────────────────────────
106
+ const files = [];
107
+ const wrote = [];
108
+ const result = await writeFileAtomic(ctx.config.aknoPath, relPath, edited.content);
109
+ files.push(fileEntry(result));
110
+ wrote.push({
111
+ slug,
112
+ action: existing ? actionFor(edit) : 'created',
113
+ ...(edited.firstChangedLine ? { line: edited.firstChangedLine } : {}),
114
+ });
115
+ // The same storage rules, reached through `write` rather than `ingest`: content-addressed
116
+ // off the page basename, extracted on arrival, embedded in the page. The difference is
117
+ // only who chose the destination — here the caller did, so nothing is routed or named.
118
+ const attached = [];
119
+ if (input.documents?.length) {
120
+ for (const document of input.documents) {
121
+ const source = path.resolve(document.path);
122
+ if (!(await fsp.stat(source).catch(() => null))) {
123
+ throw new AknoError('not_found', `no file to attach at ${source}`);
124
+ }
125
+ const stored = await storeDocument({ ctx, source, pageSlug: slug, move: false });
126
+ files.push(stored.file);
127
+ const extraction = await extract({
128
+ absPath: source,
129
+ maxOcrPages: ctx.config.ingest.maxOcrPages,
130
+ maxBytes: ctx.config.ingest.maxFileBytes,
131
+ ...(ctx.models.vision.available ? { vision: ctx.models.vision } : {}),
132
+ });
133
+ attached.push({
134
+ relPath: stored.relPath,
135
+ extraction,
136
+ ...(document.label ? { label: document.label } : {}),
137
+ });
138
+ wrote.push({ slug, action: 'attached' });
139
+ }
140
+ // The page has to reference what is now beside it, or the attachment is orphaned from
141
+ // a reader's point of view even though the index knows about it.
142
+ const embedded = await appendEmbeds(ctx, relPath, attached, files[0]);
143
+ if (embedded)
144
+ files[0] = embedded;
145
+ }
146
+ // The ledger line and the page land in one change, so the promise holds:
147
+ // there is no way to get a ledger line whose detail page was never written.
148
+ if (input.event) {
149
+ const ledger = await appendToLedger(ctx, { ...input.event, slug });
150
+ // No file when the day already has this event: the page part of this change still stands, and
151
+ // the caller is still told which ledger line the event is on — the existing one.
152
+ if (ledger.file)
153
+ files.push(ledger.file);
154
+ wrote.push({ slug: ledgerSlug(ctx.config), line: ledger.line, action: 'event' });
155
+ }
156
+ const changeId = ctx.journal.record({
157
+ actor,
158
+ op: 'write',
159
+ summary: `${existing ? actionFor(edit) : 'created'} ${slug}${input.event ? ' + event' : ''}`,
160
+ files,
161
+ });
162
+ // ── Index ───────────────────────────────────────────────────────────────
163
+ // The indexer follows exactly as it would for a hand edit: line
164
+ // hashes moved, so old facts retire and new ones are derived from the new lines.
165
+ //
166
+ // It must run *before* anything records the new hash in `files`. Recording first
167
+ // makes the stat fast path conclude the file is unchanged and skip it — the page
168
+ // lands on disk and never reaches the index, which is the worst of both worlds.
169
+ // The indexer records the file itself as part of indexing it.
170
+ //
171
+ // Structure now, meaning now — the page is searchable by its own text, its links resolve, its
172
+ // documents exist. What is deferred is only the *reading* of it: summary, keywords, the claims a
173
+ // deriver finds in the sentences. Awaiting that put a cold local model, a minute to load, inside
174
+ // every write, and the tool calling it gave up at sixty seconds while the write itself had
175
+ // already landed.
176
+ const paths = files.map((file) => file.relPath);
177
+ const report = await ctx.indexer.runForeground({ only: paths, modelPaths: [] });
178
+ ctx.derive.schedule(paths);
179
+ // After indexing: the `documents` rows exist now, so the extraction can be recorded
180
+ // against them. The row keeps the *whole* text — the body carries a capped excerpt, and
181
+ // `read({document})` should not be limited by what fits comfortably in a page.
182
+ const documents = attached.map((entry) => {
183
+ const id = recordDocument({
184
+ ctx,
185
+ relPath: entry.relPath,
186
+ extraction: entry.extraction,
187
+ ...(entry.label ? { label: entry.label } : {}),
188
+ });
189
+ return { id: id ?? '', rel_path: entry.relPath, text_from: entry.extraction.via };
190
+ });
191
+ // A frontmatter rewrite is reported, never silent. The caller may not have realised the block
192
+ // it echoed back was a declaration, and dropping `temporal` or `management` changes how the
193
+ // page behaves for months without changing a word anybody reads.
194
+ const note = edited.frontmatter
195
+ ? `the frontmatter you sent replaced the page's` +
196
+ (edited.frontmatter.dropped.length > 0
197
+ ? `, dropping ${edited.frontmatter.dropped.map((key) => `\`${key}\``).join(', ')} — ` +
198
+ `write again with those keys if that was not deliberate, or \`undo\` the change`
199
+ : '')
200
+ : null;
201
+ return {
202
+ status: 'ok',
203
+ outcome: 'ok',
204
+ change_id: changeId,
205
+ wrote,
206
+ facts: { retired: 0, added: report.factsDerived },
207
+ ...(documents.length > 0 ? { documents } : {}),
208
+ ...(note ? { note } : {}),
209
+ };
210
+ }
211
+ /**
212
+ * Adds `![[file]]` embeds for attachments the page does not already reference, and records
213
+ * each one's provenance beside it.
214
+ *
215
+ * The document's *text* is not written here. It is indexed against the document, where the
216
+ * file's hash can invalidate it and a hit can name the page within the file that produced
217
+ * it. Pasting it into the body as well made the same words arrive twice
218
+ * against one recall budget, and put a copy in the user's Markdown that no file change
219
+ * could ever correct.
220
+ *
221
+ * Appended rather than spliced: a page's structure belongs to whoever wrote it, and
222
+ * guessing where an embed "should" go would rewrite their layout.
223
+ */
224
+ async function appendEmbeds(ctx, relPath, attached, pageEntry) {
225
+ const current = await fsp.readFile(path.join(ctx.config.aknoPath, relPath), 'utf8');
226
+ const additions = [];
227
+ for (const entry of attached) {
228
+ const name = path.basename(entry.relPath);
229
+ if (current.includes(name))
230
+ continue;
231
+ const provenance = provenanceLines(entry.extraction);
232
+ // Blank line between the embed and its provenance: a list crammed against an image
233
+ // reads as part of the image's caption.
234
+ additions.push(provenance.length > 0 ? `![[${name}]]\n\n${provenance.join('\n')}` : `![[${name}]]`);
235
+ }
236
+ if (additions.length === 0)
237
+ return null;
238
+ const next = `${current.replace(/\s+$/, '')}\n\n${additions.join('\n\n')}\n`;
239
+ const written = await writeFileAtomic(ctx.config.aknoPath, relPath, next);
240
+ // The page entry was recorded before the embeds existed; replace its `after` so undo
241
+ // restores the version that was actually on disk when the change completed.
242
+ return { ...pageEntry, after: written.after };
243
+ }
244
+ /**
245
+ * **The ledger takes events. It does not take prose.**
246
+ *
247
+ * `append` and `content` write at the *end of the body*, and the end of the ledger's body is
248
+ * below the last year heading — outside every `- **YYYY-MM-DD** |` line the event parser
249
+ * matches. A claim put there is not merely in the wrong place: it is in a file that will never
250
+ * read it back, and it is a second copy of something whose home is the page it belongs to.
251
+ *
252
+ * This is not a hypothetical. `remember` routes claims by recall, the ledger is a plain `full`
253
+ * page, and a ledger that already mentions a subject scores highest *for that subject* — so a
254
+ * claim about an ongoing complaint landed under the event list of the very page recording it.
255
+ * Routing now skips reserved paths, and this is the layer under it: a guard in the prompt or in
256
+ * the caller is a guard that the next caller does not have.
257
+ *
258
+ * `patch` and `replace` are allowed through. Both are line-targeted and cannot append at the
259
+ * bottom, so a line that went in wrong stays correctable — which the ledger's own append-only
260
+ * rule needs, since a wrong line is corrected rather than removed.
261
+ *
262
+ * `akno` is exempt: a verified `broken_link` curation item rewrites link targets, and a ledger
263
+ * line whose page was renamed is exactly the kind of thing it exists to fix.
264
+ */
265
+ export function refusesLedgerProse(input) {
266
+ if (input.actor === 'akno')
267
+ return false;
268
+ if (input.slug !== input.ledger)
269
+ return false;
270
+ return input.edit === 'append' || input.edit === 'content';
271
+ }
272
+ // ─── Event-only write ───────────────────────────────────────────────────────
273
+ async function writeEventOnly(ctx, event, dryRun) {
274
+ if (dryRun) {
275
+ return {
276
+ status: 'ok',
277
+ outcome: 'ok',
278
+ wrote: [{ slug: ledgerSlug(ctx.config), action: 'event' }],
279
+ note: 'dry run — nothing was written',
280
+ };
281
+ }
282
+ const ledger = await appendToLedger(ctx, event);
283
+ // The day already has this event. Journalling anyway would put a change in `undo --list` that
284
+ // reverses nothing, and tell the caller something was kept when the ledger is exactly as it was.
285
+ if (!ledger.file) {
286
+ return {
287
+ status: 'ok',
288
+ outcome: 'noop',
289
+ note: 'the ledger already records this event for that date',
290
+ wrote: [{ slug: ledgerSlug(ctx.config), line: ledger.line, action: 'event' }],
291
+ };
292
+ }
293
+ const changeId = ctx.journal.record({
294
+ actor: ctx.actor,
295
+ op: 'write',
296
+ summary: `event ${event.date}: ${event.summary.slice(0, 60)}`,
297
+ files: [ledger.file],
298
+ });
299
+ await ctx.indexer.runForeground({ only: [ledger.file.relPath], modelPaths: [] });
300
+ // The ledger's events are parsed structurally, above — this is for the summary and any claims in
301
+ // the prose around them, which nobody is waiting on.
302
+ ctx.derive.schedule([ledger.file.relPath]);
303
+ return {
304
+ status: 'ok',
305
+ outcome: 'ok',
306
+ change_id: changeId,
307
+ // Addressable as `timeline:47`, so it obeys the same provenance rule as
308
+ // everything else — the ledger is a page like any other.
309
+ wrote: [{ slug: ledgerSlug(ctx.config), line: ledger.line, action: 'event' }],
310
+ };
311
+ }
312
+ export async function appendToLedger(ctx, event) {
313
+ const relPath = ctx.config.paths.timeline;
314
+ const absPath = path.join(ctx.config.aknoPath, relPath);
315
+ let current;
316
+ try {
317
+ current = await fsp.readFile(absPath, 'utf8');
318
+ }
319
+ catch (err) {
320
+ if (err.code !== 'ENOENT')
321
+ throw err;
322
+ current = newLedger(event.date.slice(0, 4));
323
+ }
324
+ const inserted = insertEvent(current, event);
325
+ // Nothing to write: the day already has this event, in these words or in others. Rewriting the
326
+ // file with its own bytes would journal a change that added nothing — `undo --list` would offer
327
+ // to reverse an event that was never appended, and the caller would be told it had been kept.
328
+ if (inserted.content === current)
329
+ return { file: null, line: inserted.line };
330
+ const result = await writeFileAtomic(ctx.config.aknoPath, relPath, inserted.content);
331
+ return { file: fileEntry(result), line: inserted.line };
332
+ }
333
+ // ─── Helpers ────────────────────────────────────────────────────────────────
334
+ function resolveEdit(input, exists) {
335
+ if (input.content !== undefined)
336
+ return { kind: 'content', content: input.content };
337
+ if (input.append !== undefined) {
338
+ return { kind: 'append', text: input.append, ...(input.section ? { section: input.section } : {}) };
339
+ }
340
+ if (input.patch !== undefined)
341
+ return { kind: 'patch', patch: input.patch };
342
+ if (input.replace !== undefined) {
343
+ return { kind: 'replace', find: input.replace.find, with: input.replace.with };
344
+ }
345
+ if (!exists) {
346
+ throw new AknoError('invalid', 'a new page needs `content`; there is nothing to append to or patch');
347
+ }
348
+ throw new AknoError('invalid', 'write needs one of: content, append, patch, replace');
349
+ }
350
+ function actionFor(edit) {
351
+ switch (edit.kind) {
352
+ case 'content':
353
+ return 'replaced';
354
+ case 'append':
355
+ return 'appended';
356
+ case 'patch':
357
+ return 'patched';
358
+ case 'replace':
359
+ return 'replaced';
360
+ }
361
+ }
362
+ /** Only the text being introduced is worth checking for conflicts. */
363
+ function incomingText(input, edit) {
364
+ switch (edit.kind) {
365
+ case 'content':
366
+ // A declaration is not a claim. `role: knowledge` is not the page asserting anything
367
+ // about the world, and scanning it for conflicts finds pairs that mean nothing.
368
+ return declaredFrontmatter(edit.content)?.body ?? edit.content;
369
+ case 'append':
370
+ return edit.text;
371
+ case 'replace':
372
+ return edit.with;
373
+ case 'patch':
374
+ // Only the added lines: a context line is not a new claim.
375
+ return input
376
+ .patch.split('\n')
377
+ .filter((line) => line.startsWith('+') && !line.startsWith('+++'))
378
+ .map((line) => line.slice(1))
379
+ .join('\n');
380
+ }
381
+ }
382
+ /**
383
+ * A new page gets frontmatter only for what the caller actually said. Akno
384
+ * inventing a `type` or a `tags` list would be putting words in the user's
385
+ * knowledge base that nobody chose.
386
+ *
387
+ * Composed directly rather than seeded-then-edited: `content` means "this is the
388
+ * body", so running it through the body editor discarded the `# Title` heading the
389
+ * seed had just added, and left the frontmatter fence flush against the first line.
390
+ *
391
+ * A caller who wrote their own frontmatter keeps it verbatim — the same courtesy the body
392
+ * already extends to a caller who wrote their own `# Heading`, and the same rule `applyEdit`
393
+ * follows for a page that already exists. `title`, `type` and `tags` then fill in only the
394
+ * keys the block left out, because an argument and a block that both say `title` are one
395
+ * intent stated twice and the block is the more specific statement of it.
396
+ */
397
+ function composeNewPage(input, slug, edit) {
398
+ const supplied = edit.kind === 'content' ? edit.content : edit.kind === 'append' ? edit.text : '';
399
+ const declared = edit.kind === 'content' ? declaredFrontmatter(supplied) : null;
400
+ const title = readString(declared?.data ?? {}, 'title') ?? input.title ?? titleFromSlug(slug);
401
+ const body = (declared?.body ?? supplied).trim();
402
+ // A caller who wrote their own heading keeps it; one who did not gets the title
403
+ // as an H1, because a page whose body starts mid-sentence reads as a fragment.
404
+ const heading = /^#{1,6}\s/.test(body) ? '' : `# ${title}\n\n`;
405
+ const links = input.links?.length
406
+ ? `\n\n${input.links.map((link) => `Related: [[${link}]]`).join('\n')}`
407
+ : '';
408
+ if (declared) {
409
+ const missing = [
410
+ declared.data.title === undefined ? `title: ${title}` : null,
411
+ input.type && declared.data.type === undefined ? `type: ${input.type}` : null,
412
+ input.tags?.length && declared.data.tags === undefined ? `tags: [${input.tags.join(', ')}]` : null,
413
+ ].filter((line) => line !== null);
414
+ return `${spliceAfterFence(declared.head, missing)}\n${heading}${body}${links}\n`;
415
+ }
416
+ const front = [`title: ${title}`];
417
+ if (input.type)
418
+ front.push(`type: ${input.type}`);
419
+ if (input.tags?.length)
420
+ front.push(`tags: [${input.tags.join(', ')}]`);
421
+ return `---\n${front.join('\n')}\n---\n\n${heading}${body}${links}\n`;
422
+ }
423
+ export function titleFromSlug(slug) {
424
+ const base = slug.split('/').pop() ?? slug;
425
+ return base.replace(/[-_]+/g, ' ').replace(/\b\w/g, (char) => char.toUpperCase());
426
+ }
427
+ export function normalizeSlug(raw) {
428
+ const slug = raw
429
+ .trim()
430
+ .replace(/\\/g, '/')
431
+ .replace(/\.(md|markdown)$/i, '')
432
+ .replace(/\/+/g, '/');
433
+ // A caller must not be able to name a file outside the folder the user pointed
434
+ // Akno at, whatever it sends. An absolute path is **rejected, not stripped**:
435
+ // quietly reading `/etc/passwd` as `etc/passwd` writes somewhere the caller did
436
+ // not ask for and then cannot find.
437
+ const safe = slug.length > 0 &&
438
+ slug.length <= 512 &&
439
+ !slug.startsWith('/') &&
440
+ !slug.startsWith('~') &&
441
+ !/^[a-zA-Z]:/.test(slug) &&
442
+ !slug.includes('\0') &&
443
+ slug.split('/').every((segment) => segment !== '');
444
+ if (!safe)
445
+ throw new AknoError('invalid', `not a usable slug: ${raw}`);
446
+ // **Akno ignores dot paths, so it must refuse to create one.** `scanTree`, the
447
+ // watcher, the folder catalog and both ingest walks all skip any name starting with
448
+ // a dot — that is where Obsidian, git and sync clients keep working state, and none
449
+ // of it is a note. A slug that lands in one is therefore written and then invisible
450
+ // to everything: `indexer.run({only})` *filters the scan output* rather than
451
+ // bypassing it, so the file is never indexed, and recall, read and list will all
452
+ // say the page does not exist while it sits on disk. `.git/config` was accepted and
453
+ // would have put a stray `config.md` inside the git directory.
454
+ //
455
+ // This subsumes `.` and `..`, which were the only two rejected before.
456
+ const dotted = slug.split('/').find((segment) => segment.startsWith('.'));
457
+ if (dotted !== undefined) {
458
+ throw new AknoError('invalid', `'${dotted}' starts with a dot, and Akno does not index dot paths — a page there would be ` +
459
+ `written and then invisible to recall. Choose a name without the leading dot.`, { slug: raw, segment: dotted });
460
+ }
461
+ return slug;
462
+ }
463
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/ops/write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { Card, Depth, PageRole, RecallMode, RecallResult } from '@tenphi/akno-protocol';
2
+ import type { AknoConfig } from '../config/schema.ts';
3
+ import type { Store } from '../store/db.ts';
4
+ import type { ChunkHit } from './search.ts';
5
+ export interface AssembleOptions {
6
+ hits: ChunkHit[];
7
+ mode: RecallMode;
8
+ depth: Depth;
9
+ limit: number;
10
+ budget: number;
11
+ /** Body lines per card: lookup gets deep windows, question gets tight ones. */
12
+ lineWindow: number;
13
+ /** Concepts the query asked about. Terms are matched against what came back. */
14
+ concepts: string[];
15
+ /** `include: ['source'], depth: 'full'` lifts the source quote cap. */
16
+ include: PageRole[] | null;
17
+ }
18
+ export interface Assembled {
19
+ results: RecallResult[];
20
+ cards: Card[];
21
+ budgetUsed: number;
22
+ coverage: Record<string, boolean> | null;
23
+ droppedCards: number;
24
+ }
25
+ /**
26
+ * Recall returns page or document cards — never chunks. A chunk boundary is an
27
+ * indexing artifact and means nothing to a reader.
28
+ */
29
+ export declare class Assembler {
30
+ #private;
31
+ constructor(config: AknoConfig, store: Store);
32
+ assemble(options: AssembleOptions): Assembled;
33
+ private pageResult;
34
+ /**
35
+ * Ranking policy lives in the layer: knowledge pages outrank source pages,
36
+ * which outrank derived inferences. A folder rule can set `rank` to
37
+ * adjust it. Role applies at **assembly**, not at search — source pages
38
+ * compete for relevance on equal terms, then come back capped.
39
+ */
40
+ private rankFactor;
41
+ private pageRow;
42
+ private documentRow;
43
+ private buildDocumentCard;
44
+ private buildCard;
45
+ /**
46
+ * Reads the matching lines from the file rather than from the chunk text, so a
47
+ * line's number is the number it actually has on disk. A citation that points
48
+ * at the wrong line is worse than no citation: cite or stay quiet.
49
+ */
50
+ private readLines;
51
+ private factsFor;
52
+ private linksFor;
53
+ /**
54
+ * The page's attachments, with the matching text quoted from any that matched.
55
+ *
56
+ * The card points at the page, the document, **and the page number within it**. That
57
+ * is the whole reason document text is chunked per page — a quote from page 9 of a
58
+ * contract attributed to nothing is a citation a reader cannot check.
59
+ *
60
+ * A document that matched is always included, even past the display cap: dropping the one
61
+ * that produced the hit would leave a card quoting evidence it does not list.
62
+ */
63
+ private documentsFor;
64
+ /** One query for every hit chunk's metadata, rather than one per hit inside two loops. */
65
+ private chunkMeta;
66
+ }
67
+ /**
68
+ * Deterministic — did the key terms of the expanded query actually appear in
69
+ * what was returned — **not** a model judging whether the answer is there. Cheap,
70
+ * honest, and it closes the most common hallucination path there is: a page ranks
71
+ * first because it matches half the question, the agent reads it, and confidently
72
+ * invents the other half.
73
+ */
74
+ export declare function computeCoverage(concepts: string[], results: Array<Card | RecallResult>): Record<string, boolean>;
75
+ /**
76
+ * Four characters per token. Crude, but the budget's job is to stop an overrun,
77
+ * and a tokenizer per model would make the number precise about the wrong thing —
78
+ * the caller's budget is a ceiling, not an accounting target.
79
+ */
80
+ export declare function estimateTokens(card: Card | RecallResult): number;
81
+ //# sourceMappingURL=assemble.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../src/recall/assemble.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,IAAI,EACJ,KAAK,EAGL,QAAQ,EACR,UAAU,EAGV,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAK5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uEAAuE;IACvE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,YAAY,EAAE,MAAM,CAAC;CACtB;AAkBD;;;GAGG;AACH,qBAAa,SAAS;;gBAIR,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK;IAK5C,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS;IA4G7C,OAAO,CAAC,UAAU;IAYlB;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,iBAAiB;IAmEzB,OAAO,CAAC,SAAS;IAwDjB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IA6CjB,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,QAAQ;IAShB;;;;;;;;;OASG;IACH,OAAO,CAAC,YAAY;IAuFpB,0FAA0F;IAC1F,OAAO,CAAC,SAAS;CAUlB;AAcD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6BzB;AAoBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,GAAG,MAAM,CAwBhE"}