@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,187 @@
1
+ import fsp from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { AknoError } from '@tenphi/akno-protocol';
4
+ import { newPrefixedId } from "../store/ids.js";
5
+ import { restoreFile } from "./atomic.js";
6
+ export class Journal {
7
+ #store;
8
+ #aknoPath;
9
+ #trashDir;
10
+ constructor(store, aknoPath, trashDir) {
11
+ this.#store = store;
12
+ this.#aknoPath = aknoPath;
13
+ this.#trashDir = trashDir;
14
+ }
15
+ /**
16
+ * Records a change that has already been applied to disk. Deliberately after
17
+ * the fact: a journal entry for a write that then failed is a lie in the one
18
+ * table that has to be trustworthy, and the failure mode of recording late (a
19
+ * crash between write and journal leaves an un-undoable change) is both rarer
20
+ * and far less confusing than the reverse.
21
+ */
22
+ record(input) {
23
+ const changeId = newPrefixedId('chg');
24
+ const now = new Date().toISOString();
25
+ this.#store.transaction(() => {
26
+ this.#store.db
27
+ .prepare('INSERT INTO changes(id, at, actor, op, summary, status) VALUES(?, ?, ?, ?, ?, ?)')
28
+ .run(changeId, now, input.actor, input.op, input.summary, 'applied');
29
+ const insert = this.#store.db.prepare(`INSERT INTO change_files(change_id, ord, rel_path, action, before, after, snapshot, moved_to)
30
+ VALUES(?, ?, ?, ?, ?, ?, ?, ?)`);
31
+ input.files.forEach((file, index) => {
32
+ insert.run(changeId, index, file.relPath, file.action, file.before, file.after, file.snapshot ?? null, file.movedTo ?? null);
33
+ });
34
+ });
35
+ return changeId;
36
+ }
37
+ /**
38
+ * Reverses a change: every file back to its previous bytes, in reverse order.
39
+ *
40
+ * Reverse order matters for a move — the change created the destination and
41
+ * deleted the source, so undoing destination-first leaves the source free to be
42
+ * recreated. Forward order would try to recreate the source while the
43
+ * destination still holds it.
44
+ */
45
+ async undo(changeId) {
46
+ const change = this.#store.db.prepare('SELECT * FROM changes WHERE id = ?').get(changeId);
47
+ if (!change)
48
+ throw new AknoError('not_found', `no change with id ${changeId}`);
49
+ if (change.status === 'undone') {
50
+ throw new AknoError('invalid', `${changeId} has already been undone`);
51
+ }
52
+ const files = this.#store.db
53
+ .prepare('SELECT * FROM change_files WHERE change_id = ? ORDER BY ord DESC')
54
+ .all(changeId);
55
+ const restored = [];
56
+ const removed = [];
57
+ const reversedMoves = [];
58
+ for (const file of files) {
59
+ if (file.moved_to) {
60
+ // The change was a rename, so its reversal is the rename back. Nothing was created
61
+ // and nothing was destroyed, which is why this case cannot go through `restoreFile`.
62
+ const from = path.join(this.#aknoPath, file.moved_to);
63
+ const target = path.join(this.#aknoPath, file.rel_path);
64
+ await fsp.mkdir(path.dirname(target), { recursive: true });
65
+ let reversed = true;
66
+ await fsp.rename(from, target).catch(async (err) => {
67
+ // Already gone is not a reason to abandon the rest of the reversal — the file was
68
+ // moved again, or removed, since. Everything else still goes back.
69
+ if (err.code !== 'ENOENT')
70
+ throw err;
71
+ reversed = false;
72
+ });
73
+ if (reversed)
74
+ reversedMoves.push({ from: file.moved_to, to: file.rel_path });
75
+ restored.push(file.rel_path);
76
+ continue;
77
+ }
78
+ if (file.snapshot) {
79
+ // A binary: the bytes are in trash, not in the journal.
80
+ const source = path.join(this.#trashDir, file.snapshot);
81
+ const target = path.join(this.#aknoPath, file.rel_path);
82
+ await fsp.mkdir(path.dirname(target), { recursive: true });
83
+ await fsp.copyFile(source, target);
84
+ }
85
+ else {
86
+ await restoreFile(this.#aknoPath, file.rel_path, file.before);
87
+ }
88
+ // No prior content and no snapshot means the change created this file, so putting it
89
+ // back is deleting it. Two opposite outcomes reported under one word is one of them
90
+ // being reported wrongly.
91
+ if (!file.snapshot && file.before === null)
92
+ removed.push(file.rel_path);
93
+ else
94
+ restored.push(file.rel_path);
95
+ }
96
+ // A document row carries retained extraction and provenance that a structural re-index cannot
97
+ // always reproduce without another model call. Follow successful attachment renames back before
98
+ // the scanner runs, just as the forward move follows them, rather than deleting and recreating
99
+ // the row from its content-derived id.
100
+ if (reversedMoves.length > 0) {
101
+ this.#store.transaction(() => {
102
+ const moveDocument = this.#store.db.prepare('UPDATE OR IGNORE documents SET rel_path = ? WHERE rel_path = ?');
103
+ const moveRenders = this.#store.db.prepare('UPDATE documents SET renders = ? WHERE renders = ?');
104
+ const moveGroup = this.#store.db.prepare('UPDATE documents SET group_key = ? WHERE group_key = ?');
105
+ for (const move of reversedMoves)
106
+ moveDocument.run(move.to, move.from);
107
+ for (const move of reversedMoves) {
108
+ moveRenders.run(move.to, move.from);
109
+ moveGroup.run(move.to, move.from);
110
+ }
111
+ });
112
+ }
113
+ this.#store.db
114
+ .prepare("UPDATE changes SET status = 'undone', undone_at = ? WHERE id = ?")
115
+ .run(new Date().toISOString(), changeId);
116
+ return { restored, removed, summary: change.summary };
117
+ }
118
+ list(limit = 20) {
119
+ // By rowid, not by `at`: two changes in the same millisecond have identical
120
+ // timestamps, and "the most recent change" then depends on SQLite's scan order.
121
+ // `undo --list` showing them out of order is how you undo the wrong one.
122
+ const rows = this.#store.db.prepare('SELECT * FROM changes ORDER BY rowid DESC LIMIT ?').all(limit);
123
+ const filesFor = this.#store.db.prepare('SELECT rel_path, action FROM change_files WHERE change_id = ? ORDER BY ord');
124
+ return rows.map((row) => ({
125
+ ...row,
126
+ files: filesFor.all(row.id).map((file) => ({
127
+ relPath: file.rel_path,
128
+ action: file.action,
129
+ })),
130
+ }));
131
+ }
132
+ /**
133
+ * Moves a file into `trash/<change>/` and returns the snapshot path:
134
+ * `forget({slug})` moves a whole page to trash and stays undoable for the
135
+ * retention window — deleting outright would make "reversible" a lie.
136
+ */
137
+ async trash(relPath, changeToken) {
138
+ const snapshot = path.join(changeToken, relPath);
139
+ const target = path.join(this.#trashDir, snapshot);
140
+ await fsp.mkdir(path.dirname(target), { recursive: true });
141
+ await fsp.rename(path.join(this.#aknoPath, relPath), target).catch(async (err) => {
142
+ // A rename across devices fails; trash may sit on a different volume.
143
+ if (err.code !== 'EXDEV')
144
+ throw err;
145
+ await fsp.copyFile(path.join(this.#aknoPath, relPath), target);
146
+ await fsp.rm(path.join(this.#aknoPath, relPath));
147
+ });
148
+ return snapshot;
149
+ }
150
+ /**
151
+ * Drops trashed files past the retention window. Called from the maintenance
152
+ * path, never from a write — a delete that also expires somebody else's older
153
+ * delete is a surprise nobody asked for.
154
+ */
155
+ async expireTrash(retentionDays) {
156
+ if (retentionDays <= 0)
157
+ return 0;
158
+ const cutoff = Date.now() - retentionDays * 86_400_000;
159
+ let removed = 0;
160
+ let entries;
161
+ try {
162
+ entries = await fsp.readdir(this.#trashDir);
163
+ }
164
+ catch {
165
+ return 0;
166
+ }
167
+ for (const entry of entries) {
168
+ const abs = path.join(this.#trashDir, entry);
169
+ const stat = await fsp.stat(abs).catch(() => null);
170
+ if (!stat || stat.mtimeMs > cutoff)
171
+ continue;
172
+ await fsp.rm(abs, { recursive: true, force: true });
173
+ removed++;
174
+ }
175
+ return removed;
176
+ }
177
+ }
178
+ /** Convenience: turn an atomic write result into the journal's shape. */
179
+ export function fileEntry(result) {
180
+ return {
181
+ relPath: result.relPath,
182
+ action: result.created ? 'created' : 'modified',
183
+ before: result.before,
184
+ after: result.after,
185
+ };
186
+ }
187
+ //# sourceMappingURL=journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/write/journal.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,kBAAkB,CAAC;AACnC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAoB,MAAM,aAAa,CAAC;AA6C5D,MAAM,OAAO,OAAO;IACT,MAAM,CAAQ;IACd,SAAS,CAAS;IAClB,SAAS,CAAS;IAE3B,YAAY,KAAY,EAAE,QAAgB,EAAE,QAAgB;QAC1D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAA0E;QAC/E,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,MAAM,CAAC,EAAE;iBACX,OAAO,CAAC,kFAAkF,CAAC;iBAC3F,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAEvE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CACnC;wCACgC,CACjC,CAAC;YACF,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBAClC,MAAM,CAAC,GAAG,CACR,QAAQ,EACR,KAAK,EACL,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,QAAQ,IAAI,IAAI,EACrB,IAAI,CAAC,OAAO,IAAI,IAAI,CACrB,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CAAC,QAAgB;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,QAAQ,CACf,CAAC;QAC1E,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,SAAS,CAAC,WAAW,EAAE,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QAC/E,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,SAAS,CAAC,SAAS,EAAE,GAAG,QAAQ,0BAA0B,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE;aACzB,OAAO,CAAC,kEAAkE,CAAC;aAC3E,GAAG,CAAC,QAAQ,CAOZ,CAAC;QAEJ,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,aAAa,GAAmC,EAAE,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,mFAAmF;gBACnF,qFAAqF;gBACrF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACtD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACxD,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3D,IAAI,QAAQ,GAAG,IAAI,CAAC;gBACpB,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAA0B,EAAE,EAAE;oBACxE,kFAAkF;oBAClF,mEAAmE;oBACnE,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;wBAAE,MAAM,GAAG,CAAC;oBACrC,QAAQ,GAAG,KAAK,CAAC;gBACnB,CAAC,CAAC,CAAC;gBACH,IAAI,QAAQ;oBAAE,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC7E,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC7B,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,wDAAwD;gBACxD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACxD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACxD,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3D,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACN,MAAM,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAChE,CAAC;YACD,qFAAqF;YACrF,oFAAoF;YACpF,0BAA0B;YAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;gBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;;gBACnE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;QAED,8FAA8F;QAC9F,gGAAgG;QAChG,+FAA+F;QAC/F,uCAAuC;QACvC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE;gBAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CACzC,gEAAgE,CACjE,CAAC;gBACF,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC;gBACjG,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC;gBACnG,KAAK,MAAM,IAAI,IAAI,aAAa;oBAAE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvE,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;oBACjC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBACpC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,EAAE;aACX,OAAO,CAAC,kEAAkE,CAAC;aAC3E,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAC;QAE3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,KAAK,GAAG,EAAE;QACb,4EAA4E;QAC5E,gFAAgF;QAChF,yEAAyE;QACzE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC,GAAG,CAAC,KAAK,CAO/F,CAAC;QAEJ,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CACrC,4EAA4E,CAC7E,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACxB,GAAG,GAAG;YACN,KAAK,EAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAgD,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACzF,OAAO,EAAE,IAAI,CAAC,QAAQ;gBACtB,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC,CAAC;SACJ,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK,CAAC,OAAe,EAAE,WAAmB;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAC/E,sEAAsE;YACtE,IAAK,GAA6B,CAAC,IAAI,KAAK,OAAO;gBAAE,MAAM,GAAG,CAAC;YAC/D,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;YAC/D,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,aAAqB;QACrC,IAAI,aAAa,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,UAAU,CAAC;QACvD,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC;QACX,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACnD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,GAAG,MAAM;gBAAE,SAAS;YAC7C,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACpD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED,yEAAyE;AACzE,MAAM,UAAU,SAAS,CAAC,MAAmB;IAC3C,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;QAC/C,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ export interface LedgerEvent {
2
+ date: string;
3
+ summary: string;
4
+ /** The page holding the detail. Plenty of events will never have one. */
5
+ slug?: string | null;
6
+ }
7
+ export interface LedgerInsert {
8
+ content: string;
9
+ /** 1-based line the new event landed on, so it can be cited as `timeline:47`. */
10
+ line: number;
11
+ }
12
+ export declare function formatEventLine(event: LedgerEvent): string;
13
+ /**
14
+ * Inserts an event under its year heading, creating the heading if the year is new.
15
+ *
16
+ * Placement within a year is newest-first, but only among lines Akno can read as
17
+ * events — an unparseable line a human wrote is stepped over, never reordered
18
+ * around. If the year heading is absent it is added in the right place among the
19
+ * other year headings, so a ledger stays readable without anything being rewritten.
20
+ */
21
+ export declare function insertEvent(content: string, event: LedgerEvent): LedgerInsert;
22
+ /**
23
+ * The header a ledger gets when a write has to create it. Startup creates this on
24
+ * startup only when asked; an event write creates it because the caller asked for
25
+ * an event and there is nowhere else to put it.
26
+ */
27
+ export declare function newLedger(year: string): string;
28
+ //# sourceMappingURL=ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/write/ledger.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAM1D;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,YAAY,CAiF7E;AASD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU9C"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * The event ledger.
3
+ *
4
+ * **The ledger is a source file, not a rendered view.** Generating it from the
5
+ * events index would always be tidy and correctly sorted, and it is rejected: a
6
+ * rendered file silently discards hand edits, and the whole point of a Markdown
7
+ * knowledge base is that hand edits are legitimate.
8
+ *
9
+ * So Akno maintains it **by appending only** — inserting under the right year
10
+ * heading and never rewriting or reordering what is already there. No edit a human
11
+ * made can be lost, and a hand-written line is indexed exactly like a generated
12
+ * one. Automatic upkeep without the destructive part.
13
+ *
14
+ * Nothing about this line syntax ever reaches a prompt: there is no
15
+ * `add_event` op). A caller hands over `{date, summary}`.
16
+ */
17
+ import { saysTheSame } from "../kb/words.js";
18
+ /** The summary out of a formatted event line, without the date marker or the citation. */
19
+ function summaryOf(line) {
20
+ return line
21
+ .replace(EVENT_DATE, '')
22
+ .replace(/\[\[[^\]]*\]\]/g, '')
23
+ .trim();
24
+ }
25
+ /** The same shape the indexer matches, used here to read dates already in place. */
26
+ const EVENT_DATE = /^\s*[-*]\s+\*\*(\d{4}-\d{2}-\d{2})\*\*\s*\|/;
27
+ export function formatEventLine(event) {
28
+ const summary = event.summary.trim().replace(/\s+/g, ' ');
29
+ const link = event.slug ? ` [[${event.slug}]]` : '';
30
+ // The bold date and the `|` are what make a line an event: the indexer matches
31
+ // that exact shape, and prose it cannot match is invisible to search.
32
+ return `- **${event.date}** | ${summary}${link}`;
33
+ }
34
+ /**
35
+ * Inserts an event under its year heading, creating the heading if the year is new.
36
+ *
37
+ * Placement within a year is newest-first, but only among lines Akno can read as
38
+ * events — an unparseable line a human wrote is stepped over, never reordered
39
+ * around. If the year heading is absent it is added in the right place among the
40
+ * other year headings, so a ledger stays readable without anything being rewritten.
41
+ */
42
+ export function insertEvent(content, event) {
43
+ const line = formatEventLine(event);
44
+ const lines = content.length === 0 ? [] : content.replace(/\n$/, '').split('\n');
45
+ const year = event.date.slice(0, 4);
46
+ // Already present, byte for byte: appending it twice is not append-only upkeep,
47
+ // it is duplication. The index collapses duplicates; this avoids making
48
+ // one in the file.
49
+ const existing = lines.indexOf(line);
50
+ if (existing !== -1)
51
+ return { content, line: existing + 1 };
52
+ // Already present in different words. Two callers describing one day's event will not agree on
53
+ // the wording — `They watched "Wicked: For Good"` and `The user watched "Wicked: For Good"` are
54
+ // one event and two strings, and the byte comparison above sees only the strings.
55
+ //
56
+ // Scoped to the date, which is what makes it safe: a ledger is full of events that resemble each
57
+ // other across days — a weekly delivery, a monthly payment — and those are genuinely separate
58
+ // things that happened. Two similar summaries on *one* day are almost always one thing described
59
+ // twice.
60
+ const sameDay = lines.findIndex((text) => {
61
+ const date = EVENT_DATE.exec(text)?.[1];
62
+ if (date !== event.date)
63
+ return false;
64
+ // A shared subject, place and date are not enough: scheduling something and later doing it
65
+ // are separate events whose nouns can overlap heavily. The default 0.7 containment boundary
66
+ // collapsed exactly that transition. Ledger deduplication is intentionally stricter because
67
+ // an extra line is visible and repairable, while a missing completion event is silent loss.
68
+ return saysTheSame(summaryOf(text), event.summary, 0.8);
69
+ });
70
+ if (sameDay !== -1)
71
+ return { content, line: sameDay + 1 };
72
+ const headings = lines
73
+ .map((text, index) => ({ text, index, year: /^##\s+(\d{4})\s*$/.exec(text)?.[1] }))
74
+ .filter((entry) => Boolean(entry.year));
75
+ const target = headings.find((heading) => heading.year === year);
76
+ if (target) {
77
+ // The block ends at the next heading, but its *content* ends before the blank
78
+ // line that separates the years. Inserting after that blank puts the line under
79
+ // the next year's heading as far as any reader is concerned.
80
+ const nextHeading = nextHeadingIndex(lines, target.index);
81
+ let blockEnd = nextHeading;
82
+ while (blockEnd > target.index + 1 && lines[blockEnd - 1].trim().length === 0)
83
+ blockEnd--;
84
+ let at = target.index + 1;
85
+ while (at < blockEnd && lines[at].trim().length === 0)
86
+ at++;
87
+ // Newest first, by date, among the lines Akno can read as events. A
88
+ // backdated entry — last week's appointment recorded today — belongs below
89
+ // the newer ones, and putting it at the top would make the ledger wrong in a
90
+ // way nobody notices until they read it.
91
+ //
92
+ // Still pure insertion: an unparseable line a human wrote is stepped over,
93
+ // never moved, so "never rewrites or reorders" holds.
94
+ for (let i = at; i < blockEnd; i++) {
95
+ const existingDate = EVENT_DATE.exec(lines[i])?.[1];
96
+ if (existingDate && existingDate < event.date) {
97
+ at = i;
98
+ break;
99
+ }
100
+ if (i === blockEnd - 1)
101
+ at = blockEnd;
102
+ }
103
+ lines.splice(at, 0, line);
104
+ return { content: `${lines.join('\n')}\n`, line: at + 1 };
105
+ }
106
+ // A new year. Newer years go above older ones, matching newest-first.
107
+ const laterHeading = headings.find((heading) => heading.year < year);
108
+ const insertAt = laterHeading ? laterHeading.index : lines.length;
109
+ const block = [`## ${year}`, line];
110
+ // Keep one blank line between year blocks, and none at the very top of a file
111
+ // that is only a header.
112
+ const needsGapBefore = insertAt > 0 && lines[insertAt - 1].trim().length > 0;
113
+ const needsGapAfter = insertAt < lines.length;
114
+ lines.splice(insertAt, 0, ...(needsGapBefore ? [''] : []), ...block, ...(needsGapAfter ? [''] : []));
115
+ return {
116
+ content: `${lines.join('\n')}\n`,
117
+ line: insertAt + (needsGapBefore ? 1 : 0) + 2,
118
+ };
119
+ }
120
+ function nextHeadingIndex(lines, from) {
121
+ for (let i = from + 1; i < lines.length; i++) {
122
+ if (/^##?\s+/.test(lines[i]))
123
+ return i;
124
+ }
125
+ return lines.length;
126
+ }
127
+ /**
128
+ * The header a ledger gets when a write has to create it. Startup creates this on
129
+ * startup only when asked; an event write creates it because the caller asked for
130
+ * an event and there is nowhere else to put it.
131
+ */
132
+ export function newLedger(year) {
133
+ return (`---\ntype: timeline\ntitle: Timeline\n---\n\n# Timeline\n\n` +
134
+ `What actually happened, newest first. One line per event; the detail lives on the linked\n` +
135
+ `page, so this stays an index and never a second copy of a fact.\n\n` +
136
+ `Append-only: never edit or remove a line, correct it with a new one. Each line reads\n` +
137
+ `\`- **YYYY-MM-DD** | what happened. [[page/with/detail]]\` — that exact shape is what\n` +
138
+ `makes a line an event, and prose Akno cannot match is invisible to search.\n\n` +
139
+ `## ${year}\n`);
140
+ }
141
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../src/write/ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { type ModelClient } from '../models/client.ts';
3
+ export interface ManagedItem {
4
+ id: string;
5
+ text: string;
6
+ source: string;
7
+ origin: 'user' | 'assistant' | 'unknown';
8
+ }
9
+ export interface PlacementResult {
10
+ content: string;
11
+ unsorted: string[];
12
+ error: string | null;
13
+ }
14
+ /** `id` is checked against the supplied set afterwards — a grammar can require a string
15
+ * there, not that it is one of the ids the model was actually given. */
16
+ export declare const PLACEMENT_SCHEMA: z.ZodObject<{
17
+ placements: z.ZodArray<z.ZodObject<{
18
+ id: z.ZodString;
19
+ heading: z.ZodString;
20
+ }, z.core.$strip>>;
21
+ }, z.core.$strip>;
22
+ /**
23
+ * One model call places all managed items bound for a page. The model chooses only section names;
24
+ * deterministic code performs the edit and preserves every existing byte outside the insertion.
25
+ */
26
+ export declare function placeManagedItems(content: string, items: ManagedItem[], model: ModelClient): Promise<PlacementResult>;
27
+ /** Return the exact source label that survives the bounded marker encoding. */
28
+ export declare function managedSourceReference(value: string): string;
29
+ //# sourceMappingURL=placement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placement.d.ts","sourceRoot":"","sources":["../../src/write/placement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAYD;yEACyE;AACzE,eAAO,MAAM,gBAAgB;;;;;iBAE3B,CAAC;AAEH;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,WAAW,EAAE,EACpB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,eAAe,CAAC,CA8C1B;AAwCD,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS5D"}
@@ -0,0 +1,140 @@
1
+ import { z } from 'zod';
2
+ import { parseFrontmatter } from "../kb/frontmatter.js";
3
+ import { parseJsonLoose } from "../models/client.js";
4
+ const SYSTEM = `You place durable knowledge into one Markdown page.
5
+
6
+ Reply with JSON only:
7
+ {"placements":[{"id":"exact supplied id","heading":"exact existing ## heading, or a concise new heading"}]}
8
+
9
+ Choose the most specific semantically correct section for every item. Reuse an existing ## heading
10
+ when one fits. A new heading is allowed when it materially improves the page. Do not rewrite,
11
+ rephrase, merge or omit items. Do not use the title as a heading. Never return "Unsorted"; the
12
+ caller owns that fallback.`;
13
+ /** `id` is checked against the supplied set afterwards — a grammar can require a string
14
+ * there, not that it is one of the ids the model was actually given. */
15
+ export const PLACEMENT_SCHEMA = z.object({
16
+ placements: z.array(z.object({ id: z.string(), heading: z.string() })),
17
+ });
18
+ /**
19
+ * One model call places all managed items bound for a page. The model chooses only section names;
20
+ * deterministic code performs the edit and preserves every existing byte outside the insertion.
21
+ */
22
+ export async function placeManagedItems(content, items, model) {
23
+ if (items.length === 0)
24
+ return { content, unsorted: [], error: null };
25
+ const frontmatter = parseFrontmatter(content);
26
+ const body = content.slice(frontmatter.bodyOffset);
27
+ const existing = secondLevelHeadings(body);
28
+ let chosen = new Map();
29
+ let error = null;
30
+ if (model.available) {
31
+ const result = await model.chat([
32
+ { role: 'system', content: SYSTEM },
33
+ {
34
+ role: 'user',
35
+ content: `Page:\n${body.slice(0, 24_000)}\n\nExisting ## headings: ${JSON.stringify(existing)}\n\n` +
36
+ `Items:\n${JSON.stringify(items.map(({ id, text }) => ({ id, text })))}`,
37
+ },
38
+ ], { schema: PLACEMENT_SCHEMA, maxTokens: Math.min(1600, 200 + items.length * 100) });
39
+ if (result.ok && result.value) {
40
+ const parsed = parseJsonLoose(result.value);
41
+ chosen = cleanPlacements(parsed?.placements, new Set(items.map((item) => item.id)));
42
+ if (chosen.size !== items.length)
43
+ error = 'placement omitted or invalidated one or more items';
44
+ }
45
+ else {
46
+ error = result.error ?? 'placement failed';
47
+ }
48
+ }
49
+ else {
50
+ error = model.unavailableReason ?? 'placement model unavailable';
51
+ }
52
+ let nextBody = body;
53
+ const unsorted = [];
54
+ for (const item of items) {
55
+ const heading = chosen.get(item.id) ?? 'Unsorted';
56
+ if (heading === 'Unsorted')
57
+ unsorted.push(item.id);
58
+ nextBody = appendManagedBlock(nextBody, heading, managedBlock(item));
59
+ }
60
+ return {
61
+ content: content.slice(0, frontmatter.bodyOffset) + nextBody,
62
+ unsorted,
63
+ error,
64
+ };
65
+ }
66
+ function cleanPlacements(value, itemIds) {
67
+ const out = new Map();
68
+ if (!Array.isArray(value))
69
+ return out;
70
+ for (const entry of value) {
71
+ if (!entry || typeof entry !== 'object')
72
+ continue;
73
+ const record = entry;
74
+ if (typeof record.id !== 'string' || !itemIds.has(record.id) || out.has(record.id))
75
+ continue;
76
+ if (typeof record.heading !== 'string')
77
+ continue;
78
+ const heading = cleanHeading(record.heading);
79
+ if (heading)
80
+ out.set(record.id, heading);
81
+ }
82
+ return out;
83
+ }
84
+ function cleanHeading(raw) {
85
+ const heading = raw
86
+ .replace(/^#+\s*/, '')
87
+ .replace(/[\r\n[\]<>]/g, '')
88
+ .trim();
89
+ if (heading.length === 0 || heading.length > 80 || heading.toLowerCase() === 'unsorted')
90
+ return null;
91
+ return heading;
92
+ }
93
+ function secondLevelHeadings(body) {
94
+ return body
95
+ .split('\n')
96
+ .map((line) => /^##\s+(.+?)\s*$/.exec(line)?.[1]?.trim())
97
+ .filter((heading) => Boolean(heading));
98
+ }
99
+ function managedBlock(item) {
100
+ return `<!-- akno:item ${item.id} source=${encodeMarker(item.source)} origin=${item.origin} -->\n${item.text.trim()}`;
101
+ }
102
+ function encodeMarker(value) {
103
+ return encodeURIComponent(managedSourceReference(value));
104
+ }
105
+ /** Return the exact source label that survives the bounded marker encoding. */
106
+ export function managedSourceReference(value) {
107
+ const cleaned = value.replace(/-->/g, '') || 'remember';
108
+ let bounded = '';
109
+ for (const character of cleaned) {
110
+ const candidate = bounded + character;
111
+ if (encodeURIComponent(candidate).length > 300)
112
+ break;
113
+ bounded = candidate;
114
+ }
115
+ return bounded || 'remember';
116
+ }
117
+ function appendManagedBlock(body, heading, block) {
118
+ const lines = body.replace(/\s+$/, '').split('\n');
119
+ const wanted = heading.toLowerCase();
120
+ const matches = lines
121
+ .map((line, index) => ({ index, match: /^##\s+(.+?)\s*$/.exec(line) }))
122
+ .filter((entry) => entry.match?.[1]?.trim().toLowerCase() === wanted);
123
+ if (matches.length !== 1) {
124
+ const gap = lines.length === 1 && lines[0] === '' ? [] : ['', ''];
125
+ return `${[...lines, ...gap, `## ${heading}`, '', block].join('\n').replace(/^\n+/, '')}\n`;
126
+ }
127
+ const start = matches[0].index;
128
+ let end = lines.length;
129
+ for (let index = start + 1; index < lines.length; index++) {
130
+ if (/^#{1,2}\s+/.test(lines[index])) {
131
+ end = index;
132
+ break;
133
+ }
134
+ }
135
+ while (end > start + 1 && lines[end - 1].trim() === '')
136
+ end--;
137
+ lines.splice(end, 0, '', block);
138
+ return `${lines.join('\n').replace(/\n{3,}/g, '\n\n')}\n`;
139
+ }
140
+ //# sourceMappingURL=placement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placement.js","sourceRoot":"","sources":["../../src/write/placement.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { AknoContext } from '../context.ts';
2
+ import { type FolderCatalogEntry } from '../kb/folders.ts';
3
+ type RememberFallbackUnavailableReason = 'reserved_path' | 'existing_page_not_admitted' | 'unindexed_page_exists' | 'folder_not_admitted';
4
+ export type RememberFallbackResolution = {
5
+ slug: string;
6
+ status: 'existing_page' | 'new_page';
7
+ } | {
8
+ slug: string;
9
+ status: 'unavailable';
10
+ reason: RememberFallbackUnavailableReason;
11
+ };
12
+ /**
13
+ * Resolve the explicit catch-all independently of semantic routing. Configuration names one exact page;
14
+ * admission still comes from the page or its parent folder, so this option cannot grant itself write authority.
15
+ */
16
+ export declare function resolveRememberFallback(ctx: AknoContext, catalog?: FolderCatalogEntry[]): Promise<RememberFallbackResolution | null>;
17
+ export {};
18
+ //# sourceMappingURL=remember-fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remember-fallback.d.ts","sourceRoot":"","sources":["../../src/write/remember-fallback.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG1E,KAAK,iCAAiC,GACpC,eAAe,GAAG,4BAA4B,GAAG,uBAAuB,GAAG,qBAAqB,CAAC;AAEnG,MAAM,MAAM,0BAA0B,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,UAAU,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,iCAAiC,CAAA;CAAE,CAAC;AAEvF;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,WAAW,EAChB,OAAO,GAAE,kBAAkB,EAAyC,GACnE,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CA8B5C"}
@@ -0,0 +1,48 @@
1
+ import fsp from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { folderCatalog } from "../kb/folders.js";
4
+ import { isReserved } from "../reserved.js";
5
+ /**
6
+ * Resolve the explicit catch-all independently of semantic routing. Configuration names one exact page;
7
+ * admission still comes from the page or its parent folder, so this option cannot grant itself write authority.
8
+ */
9
+ export async function resolveRememberFallback(ctx, catalog = folderCatalog(ctx.config, ctx.store)) {
10
+ const slug = ctx.config.maintenance.retain.fallbackPage;
11
+ if (!slug)
12
+ return null;
13
+ if (isReserved(slug, ctx.config))
14
+ return { slug, status: 'unavailable', reason: 'reserved_path' };
15
+ const row = ctx.store.db.prepare('SELECT role, remember_management FROM pages WHERE slug = ?').get(slug);
16
+ if (row) {
17
+ return row.role === 'knowledge' && row.remember_management === 'integrate'
18
+ ? { slug, status: 'existing_page' }
19
+ : { slug, status: 'unavailable', reason: 'existing_page_not_admitted' };
20
+ }
21
+ // An indexed page has policy metadata. Existing bytes without an index row do not, and treating them as a
22
+ // new managed page would overwrite user-authored content before Akno had classified it.
23
+ if (await fallbackFileExists(ctx, slug)) {
24
+ return { slug, status: 'unavailable', reason: 'unindexed_page_exists' };
25
+ }
26
+ const parent = slug.slice(0, slug.lastIndexOf('/'));
27
+ const admitted = catalog.some((folder) => folder.path === parent &&
28
+ folder.role === 'knowledge' &&
29
+ folder.remember === 'integrate' &&
30
+ folder.creatable);
31
+ return admitted
32
+ ? { slug, status: 'new_page' }
33
+ : { slug, status: 'unavailable', reason: 'folder_not_admitted' };
34
+ }
35
+ async function fallbackFileExists(ctx, slug) {
36
+ for (const extension of ctx.config.pageExtensions) {
37
+ try {
38
+ if ((await fsp.stat(path.join(ctx.config.aknoPath, `${slug}${extension}`))).isFile())
39
+ return true;
40
+ }
41
+ catch (error) {
42
+ if (error.code !== 'ENOENT')
43
+ throw error;
44
+ }
45
+ }
46
+ return false;
47
+ }
48
+ //# sourceMappingURL=remember-fallback.js.map