@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,143 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ /**
4
+ * **FSEvents, not polling.** Node's recursive `fs.watch` uses FSEvents on
5
+ * macOS: native, cheap, and it reports renames as renames.
6
+ *
7
+ * But FSEvents coalesces under load and can drop events after a sleep/wake or a
8
+ * large sync, so a **periodic hash sweep is the backstop.** Watching alone is not
9
+ * a correctness guarantee; hashing is. At ~10ms for a typical knowledge base the
10
+ * sweep can run every few minutes and cost nothing.
11
+ */
12
+ export class Watcher {
13
+ watcher = null;
14
+ sweepTimer = null;
15
+ verifyTimer = null;
16
+ debounceTimer = null;
17
+ pending = new Set();
18
+ running = false;
19
+ /** Set when a change arrived mid-index; guarantees one more pass after it. */
20
+ dirty = false;
21
+ #config;
22
+ #indexer;
23
+ #events;
24
+ constructor(config, indexer, events = {}) {
25
+ this.#config = config;
26
+ this.#indexer = indexer;
27
+ this.#events = events;
28
+ }
29
+ start() {
30
+ if (this.watcher)
31
+ return;
32
+ try {
33
+ this.watcher = fs.watch(this.#config.aknoPath, { recursive: true, persistent: true }, (_type, filename) => {
34
+ if (!filename) {
35
+ // A null filename means FSEvents coalesced and cannot say what moved.
36
+ // The only correct response is to treat the whole tree as suspect.
37
+ this.dirty = true;
38
+ this.schedule();
39
+ return;
40
+ }
41
+ const relPath = filename.split(path.sep).join('/');
42
+ if (this.shouldIgnore(relPath))
43
+ return;
44
+ this.pending.add(relPath);
45
+ this.schedule();
46
+ });
47
+ this.watcher.on('error', (error) => this.#events.onError?.(error));
48
+ }
49
+ catch (error) {
50
+ // A watch that cannot be established is not fatal: the sweep below still
51
+ // reconciles, just with more latency.
52
+ this.#events.onError?.(error);
53
+ }
54
+ if (this.#config.watch.sweepIntervalMs > 0) {
55
+ this.sweepTimer = setInterval(() => {
56
+ this.dirty = true;
57
+ void this.flush();
58
+ }, this.#config.watch.sweepIntervalMs);
59
+ this.sweepTimer.unref();
60
+ }
61
+ if (this.#config.watch.verifyIntervalMs > 0) {
62
+ // The correctness path: a full hash sweep that catches a sync client or a
63
+ // restored backup which preserved mtime across a real content change.
64
+ this.verifyTimer = setInterval(() => {
65
+ void this.flush({ verify: true });
66
+ }, this.#config.watch.verifyIntervalMs);
67
+ this.verifyTimer.unref();
68
+ }
69
+ }
70
+ /**
71
+ * The service reconciles on wake — the gap where a laptop was closed is
72
+ * exactly when the folder gets edited on another device. A host that knows about
73
+ * sleep/wake calls this; the periodic sweep covers the case where nothing does.
74
+ */
75
+ reconcileNow() {
76
+ this.dirty = true;
77
+ return this.flush({ verify: true });
78
+ }
79
+ async stop() {
80
+ this.watcher?.close();
81
+ this.watcher = null;
82
+ if (this.sweepTimer)
83
+ clearInterval(this.sweepTimer);
84
+ if (this.verifyTimer)
85
+ clearInterval(this.verifyTimer);
86
+ if (this.debounceTimer)
87
+ clearTimeout(this.debounceTimer);
88
+ this.sweepTimer = this.verifyTimer = this.debounceTimer = null;
89
+ }
90
+ shouldIgnore(relPath) {
91
+ const segments = relPath.split('/');
92
+ if (segments.some((segment) => segment.startsWith('.')))
93
+ return true;
94
+ if (segments.some((segment) => this.#config.ignore.includes(segment)))
95
+ return true;
96
+ // Editors and sync clients write to a temp name then rename. Indexing the
97
+ // temp file wastes a pass and briefly indexes a partial page.
98
+ const base = segments.at(-1) ?? '';
99
+ return /(^~|\.tmp$|\.swp$|\.crdownload$|\.part$|^\.#|~$)/.test(base);
100
+ }
101
+ schedule() {
102
+ if (this.debounceTimer)
103
+ clearTimeout(this.debounceTimer);
104
+ // FSEvents coalesces, but an editor still produces a write storm on save.
105
+ this.debounceTimer = setTimeout(() => void this.flush(), this.#config.watch.debounceMs);
106
+ }
107
+ async flush(options = {}) {
108
+ if (this.running) {
109
+ // A change that arrived while indexing must not be lost to the guard.
110
+ this.dirty = true;
111
+ return;
112
+ }
113
+ const changed = [...this.pending];
114
+ const wholeTree = this.dirty || options.verify;
115
+ if (changed.length === 0 && !wholeTree)
116
+ return;
117
+ this.pending.clear();
118
+ this.dirty = false;
119
+ this.running = true;
120
+ try {
121
+ const report = await this.#indexer.run({
122
+ ...(options.verify ? { verify: true } : {}),
123
+ // A targeted pass cannot conclude anything about deletions, so a
124
+ // coalesced or swept run deliberately walks the whole tree.
125
+ ...(wholeTree ? {} : { only: changed }),
126
+ });
127
+ this.#events.onIndexed?.(report, changed);
128
+ // After indexing, so an inbox handler sees a knowledge base that already knows
129
+ // about the file it is about to move.
130
+ if (this.#events.onArrival)
131
+ await this.#events.onArrival(changed);
132
+ }
133
+ catch (error) {
134
+ this.#events.onError?.(error);
135
+ }
136
+ finally {
137
+ this.running = false;
138
+ if (this.dirty || this.pending.size > 0)
139
+ this.schedule();
140
+ }
141
+ }
142
+ }
143
+ //# sourceMappingURL=watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/watch/watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { Store } from '../store/db.ts';
2
+ /**
3
+ * Every byte Akno writes into the knowledge base goes through here.
4
+ *
5
+ * Two properties, both of which matter more than they look:
6
+ *
7
+ * **Atomic.** Write a sibling temp file, fsync it, rename over the target. A
8
+ * rename within one APFS directory is atomic, so a reader — the watcher, an
9
+ * editor, a sync client, `recall` reading lines off disk — never sees a half-
10
+ * written page. Writing in place would let a crash or a concurrent read catch a
11
+ * truncated file, and the truncated version is what gets indexed and cited.
12
+ *
13
+ * **Self-aware.** The resulting hash, size and mtime are recorded in `files`
14
+ * immediately, so the watcher recognises Akno's own write and does not schedule
15
+ * a re-index of a page it already has. That promise about the `id`
16
+ * write; it has to hold for every write or the watcher chases its own tail.
17
+ */
18
+ export interface WriteResult {
19
+ relPath: string;
20
+ absPath: string;
21
+ /** Bytes before the write. Null when the file did not exist. */
22
+ before: string | null;
23
+ after: string;
24
+ created: boolean;
25
+ }
26
+ export declare function writeFileAtomic(aknoPath: string, relPath: string, content: string): Promise<WriteResult>;
27
+ /**
28
+ * Records Akno's own write in `files` so the next sweep sees nothing changed.
29
+ * Called after the write and inside the same transaction as the journal entry.
30
+ */
31
+ export declare function recordOwnWrite(store: Store, aknoPath: string, relPath: string, content: string, pageId: string | null): void;
32
+ /** Restores a file to exact prior bytes, or removes it if there were none. */
33
+ export declare function restoreFile(aknoPath: string, relPath: string, before: string | null): Promise<void>;
34
+ //# sourceMappingURL=atomic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atomic.d.ts","sourceRoot":"","sources":["../../src/write/atomic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAKD,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,CAyBtB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,IAAI,CAqBN;AAED,8EAA8E;AAC9E,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAMzG"}
@@ -0,0 +1,58 @@
1
+ import fs from 'node:fs';
2
+ import fsp from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { sha256 } from "../store/ids.js";
5
+ /** The temp suffix the watcher already ignores, so a write never wakes it twice. */
6
+ const TEMP_SUFFIX = '.akno.tmp';
7
+ export async function writeFileAtomic(aknoPath, relPath, content) {
8
+ const absPath = path.join(aknoPath, relPath);
9
+ await fsp.mkdir(path.dirname(absPath), { recursive: true });
10
+ let before = null;
11
+ try {
12
+ before = await fsp.readFile(absPath, 'utf8');
13
+ }
14
+ catch (err) {
15
+ if (err.code !== 'ENOENT')
16
+ throw err;
17
+ }
18
+ const tempPath = `${absPath}${TEMP_SUFFIX}`;
19
+ const handle = await fsp.open(tempPath, 'w', 0o644);
20
+ try {
21
+ await handle.writeFile(content, 'utf8');
22
+ // Without the fsync the rename can land before the data does, and a crash in
23
+ // that window leaves a correctly-named empty file — the worst outcome, because
24
+ // it looks like a page the user emptied on purpose.
25
+ await handle.sync();
26
+ }
27
+ finally {
28
+ await handle.close();
29
+ }
30
+ await fsp.rename(tempPath, absPath);
31
+ return { relPath, absPath, before, after: content, created: before === null };
32
+ }
33
+ /**
34
+ * Records Akno's own write in `files` so the next sweep sees nothing changed.
35
+ * Called after the write and inside the same transaction as the journal entry.
36
+ */
37
+ export function recordOwnWrite(store, aknoPath, relPath, content, pageId) {
38
+ // `bigint: true` to match the scanner exactly. A float mtime loses precision
39
+ // above ~2^53 ns, and a value that differs from what the scanner would read is
40
+ // worse than none — it defeats the stat fast path on every single sweep.
41
+ const stat = fs.statSync(path.join(aknoPath, relPath), { bigint: true, throwIfNoEntry: false });
42
+ store.db
43
+ .prepare(`INSERT INTO files(rel_path, size, mtime_ns, sha256, kind, page_id, indexed_at)
44
+ VALUES(?, ?, ?, ?, 'page', ?, ?)
45
+ ON CONFLICT(rel_path) DO UPDATE SET
46
+ size = excluded.size, mtime_ns = excluded.mtime_ns, sha256 = excluded.sha256,
47
+ page_id = excluded.page_id, indexed_at = excluded.indexed_at`)
48
+ .run(relPath, Buffer.byteLength(content, 'utf8'), stat ? String(stat.mtimeNs) : '0', sha256(content), pageId, new Date().toISOString());
49
+ }
50
+ /** Restores a file to exact prior bytes, or removes it if there were none. */
51
+ export async function restoreFile(aknoPath, relPath, before) {
52
+ if (before === null) {
53
+ await fsp.rm(path.join(aknoPath, relPath), { force: true });
54
+ return;
55
+ }
56
+ await writeFileAtomic(aknoPath, relPath, before);
57
+ }
58
+ //# sourceMappingURL=atomic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atomic.js","sourceRoot":"","sources":["../../src/write/atomic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,GAAG,MAAM,kBAAkB,CAAC;AACnC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA6BzC,oFAAoF;AACpF,MAAM,WAAW,GAAG,WAAW,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,OAAe,EACf,OAAe;IAEf,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7C,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5D,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,GAAG,CAAC;IAClE,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,OAAO,GAAG,WAAW,EAAE,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxC,6EAA6E;QAC7E,+EAA+E;QAC/E,oDAAoD;QACpD,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IACD,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEpC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,EAAE,CAAC;AAChF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAY,EACZ,QAAgB,EAChB,OAAe,EACf,OAAe,EACf,MAAqB;IAErB,6EAA6E;IAC7E,+EAA+E;IAC/E,yEAAyE;IACzE,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAChG,KAAK,CAAC,EAAE;SACL,OAAO,CACN;;;;sEAIgE,CACjE;SACA,GAAG,CACF,OAAO,EACP,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,EAClC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EACjC,MAAM,CAAC,OAAO,CAAC,EACf,MAAM,EACN,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CACzB,CAAC;AACN,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,OAAe,EAAE,MAAqB;IACxF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IACD,MAAM,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { ConflictReport } from '@tenphi/akno-protocol';
2
+ import type { Store } from '../store/db.ts';
3
+ /**
4
+ * Two values differ *meaningfully* when their comparable cores differ. Reached
5
+ * only for values that already contain a number or a decisive word, so this is
6
+ * about "€33 vs €33/month" (same) against "€33 vs €47" (different).
7
+ *
8
+ * Exported for the thorough pass, which joins facts across the whole knowledge base and
9
+ * has to decide "differ" exactly the way the inline check does. Two answers to that question
10
+ * would mean the cycle reporting conflicts a write would have allowed, or missing ones it
11
+ * would have blocked.
12
+ */
13
+ export declare function valuesConflict(existing: string, incoming: string): boolean;
14
+ export interface ConflictOptions {
15
+ store: Store;
16
+ pageId: string;
17
+ slug: string;
18
+ /** The page as it stands. Compared against, line for line. */
19
+ body: string;
20
+ /** Line number the body starts at, so a report addresses the real line. */
21
+ bodyStartLine: number;
22
+ /** The text being written. */
23
+ incoming: string;
24
+ /** Echo of a token the caller already resolved with the user. */
25
+ resolveToken?: string;
26
+ }
27
+ /**
28
+ * Returns the first genuine conflict, or null. First rather than all: a caller has
29
+ * to take this to the user, and one clear question beats a list.
30
+ *
31
+ * Both sides go through the **same extractor**, which is the whole trick. The first
32
+ * implementation compared a structurally-extracted attribute from the incoming text
33
+ * against the `attribute` a model had assigned to an existing fact — and those are
34
+ * different vocabularies. Appending `- Nights: 5` over an existing `- Nights: 3`
35
+ * produced no conflict at all, because the model had labelled the existing line's
36
+ * attribute `total` while the extractor read the new one as `nights`. Two names for
37
+ * the same thing never join.
38
+ *
39
+ * Comparing the page's own lines against the incoming lines also means conflict
40
+ * detection **works with no chat model at all**, which is what makes it cheap.
41
+ */
42
+ export declare function detectConflict(options: ConflictOptions): ConflictReport | null;
43
+ //# sourceMappingURL=conflict.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict.d.ts","sourceRoot":"","sources":["../../src/write/conflict.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAqE5C;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAc1E;AAWD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,GAAG,IAAI,CA0C9E"}
@@ -0,0 +1,149 @@
1
+ import { createHash } from 'node:crypto';
2
+ /**
3
+ * **Cheap inline, thorough offline.**
4
+ *
5
+ * On every write: compare only against facts on the target page, flag only when
6
+ * two claims share a subject and attribute but differ in value, and bias toward
7
+ * numbers, dates, names and identifiers — where conflicts are real and detectable.
8
+ * Free prose rarely conflicts meaningfully, and a detector that thinks it does
9
+ * will block half of all writes.
10
+ *
11
+ * **When uncertain, write — do not block.** A false block costs a turn; a false
12
+ * pass costs a duplicate, and the maintenance cycle finds duplicates later.
13
+ *
14
+ * Deliberately no model call: correctness that requires one per write belongs in the
15
+ * background, not in the turn.
16
+ */
17
+ /** `- **Premium:** €33/month`, `Premium: €33/month`, `| Premium | €33 |`. */
18
+ const KEY_VALUE = /^\s*(?:[-*+]\s*)?(?:\*\*|__)?([A-Za-z][\w\s'/-]{1,40}?)(?:\*\*|__)?\s*:\s*(.+?)\s*$/;
19
+ const TABLE_ROW = /^\s*\|\s*(?:\*\*)?([A-Za-z][\w\s'/-]{1,40}?)(?:\*\*)?\s*\|\s*(.+?)\s*\|/;
20
+ /**
21
+ * A value worth fighting over. A conflict between two prose sentences is usually
22
+ * two ways of saying the same thing; a conflict between two numbers is a fact
23
+ * that changed.
24
+ */
25
+ const HARD_VALUE = /\d|\b(yes|no|true|false|none|active|inactive|expired|cancelled|monthly|weekly|annual|annually)\b/i;
26
+ /**
27
+ * Pulls `attribute: value` shapes out of text about to be written. Structural
28
+ * only — this is what makes the check affordable on every write.
29
+ */
30
+ function extractCandidates(text, startLine = 1) {
31
+ const out = [];
32
+ const lines = text.split('\n');
33
+ for (let i = 0; i < lines.length; i++) {
34
+ const raw = lines[i];
35
+ if (raw.trim().length === 0 || /^\s*#{1,6}\s/.test(raw))
36
+ continue;
37
+ const match = TABLE_ROW.exec(raw) ?? KEY_VALUE.exec(raw);
38
+ if (!match)
39
+ continue;
40
+ const attribute = normalizeAttribute(match[1]);
41
+ const value = match[2].trim();
42
+ if (attribute.length === 0 || value.length === 0)
43
+ continue;
44
+ // A URL or a wikilink is not an attribute assignment, whatever the colon says.
45
+ if (/^\/\/|^https?:|^\[\[/.test(value))
46
+ continue;
47
+ if (!HARD_VALUE.test(value))
48
+ continue;
49
+ out.push({ attribute, value, line: startLine + i, text: raw.trim() });
50
+ }
51
+ return out;
52
+ }
53
+ function normalizeAttribute(raw) {
54
+ return raw.toLowerCase().replace(/[*_`]/g, '').replace(/\s+/g, ' ').trim();
55
+ }
56
+ /**
57
+ * Two values differ *meaningfully* when their comparable cores differ. Reached
58
+ * only for values that already contain a number or a decisive word, so this is
59
+ * about "€33 vs €33/month" (same) against "€33 vs €47" (different).
60
+ *
61
+ * Exported for the thorough pass, which joins facts across the whole knowledge base and
62
+ * has to decide "differ" exactly the way the inline check does. Two answers to that question
63
+ * would mean the cycle reporting conflicts a write would have allowed, or missing ones it
64
+ * would have blocked.
65
+ */
66
+ export function valuesConflict(existing, incoming) {
67
+ const left = comparableCore(existing);
68
+ const right = comparableCore(incoming);
69
+ if (left === right)
70
+ return false;
71
+ const leftNumbers = numbersIn(existing);
72
+ const rightNumbers = numbersIn(incoming);
73
+ // Both carry numbers: the numbers decide. This is the case to bias toward, and the only
74
+ // one where "differ" is unambiguous.
75
+ if (leftNumbers.length > 0 && rightNumbers.length > 0) {
76
+ return leftNumbers.join(',') !== rightNumbers.join(',');
77
+ }
78
+ // Only one side has a number, or neither does. When uncertain, write.
79
+ return false;
80
+ }
81
+ function comparableCore(value) {
82
+ return value.toLowerCase().replace(/[*_`]/g, '').replace(/[\s,]/g, '').replace(/\.$/, '');
83
+ }
84
+ function numbersIn(value) {
85
+ // Thousands separators removed first, so `1,450` reads as one number.
86
+ return [...value.replace(/(\d),(\d{3})\b/g, '$1$2').matchAll(/\d+(?:[.]\d+)?/g)].map((m) => m[0]);
87
+ }
88
+ /**
89
+ * Returns the first genuine conflict, or null. First rather than all: a caller has
90
+ * to take this to the user, and one clear question beats a list.
91
+ *
92
+ * Both sides go through the **same extractor**, which is the whole trick. The first
93
+ * implementation compared a structurally-extracted attribute from the incoming text
94
+ * against the `attribute` a model had assigned to an existing fact — and those are
95
+ * different vocabularies. Appending `- Nights: 5` over an existing `- Nights: 3`
96
+ * produced no conflict at all, because the model had labelled the existing line's
97
+ * attribute `total` while the extractor read the new one as `nights`. Two names for
98
+ * the same thing never join.
99
+ *
100
+ * Comparing the page's own lines against the incoming lines also means conflict
101
+ * detection **works with no chat model at all**, which is what makes it cheap.
102
+ */
103
+ export function detectConflict(options) {
104
+ const incoming = extractCandidates(options.incoming, 1);
105
+ if (incoming.length === 0)
106
+ return null;
107
+ const existing = extractCandidates(options.body, options.bodyStartLine);
108
+ if (existing.length === 0)
109
+ return null;
110
+ // A low-confidence fact is never used for conflict detection, where a shaky
111
+ // claim would fight a solid one. Lines the deriver was unsure about are excluded
112
+ // by line number — the one thing the facts table is genuinely authoritative on.
113
+ const shaky = new Set(options.store.db
114
+ .prepare(`SELECT f.line_start FROM facts f JOIN pages p ON p.id = f.page_id
115
+ WHERE f.page_id = ? AND f.valid_to IS NULL AND f.confidence < 0.5
116
+ AND p.derived_hash = p.body_hash`)
117
+ .all(options.pageId).map((row) => row.line_start));
118
+ for (const candidate of incoming) {
119
+ for (const current of existing) {
120
+ if (shaky.has(current.line))
121
+ continue;
122
+ if (current.attribute !== candidate.attribute)
123
+ continue;
124
+ if (!valuesConflict(current.value, candidate.value))
125
+ continue;
126
+ const token = conflictToken(options.slug, current.line, candidate.value);
127
+ if (options.resolveToken === token)
128
+ continue; // The caller already asked.
129
+ return {
130
+ slug: options.slug,
131
+ line: current.line,
132
+ existing: current.text,
133
+ incoming: candidate.text,
134
+ subject: candidate.attribute,
135
+ token,
136
+ };
137
+ }
138
+ }
139
+ return null;
140
+ }
141
+ /**
142
+ * Ties an override to the exact conflict it resolves. A plain boolean flag would
143
+ * let a caller wave through a *different* conflict discovered on the next attempt
144
+ * — which is the same as not checking.
145
+ */
146
+ function conflictToken(slug, line, incoming) {
147
+ return createHash('sha256').update(`${slug}:${line}:${incoming}`).digest('hex').slice(0, 12);
148
+ }
149
+ //# sourceMappingURL=conflict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict.js","sourceRoot":"","sources":["../../src/write/conflict.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The four ways `write` can change a body, and the rule they obey: **never touch the
3
+ * frontmatter, unless the caller sent one.** Every key is preserved byte for byte, so an
4
+ * edit here operates on the body and splices it back under the original head.
5
+ *
6
+ * The exception is `content` — a whole-page write — and it is not a loophole. `read` returns
7
+ * the file including its frontmatter, so a caller that read a page, revised it and sent the
8
+ * result back arrives holding a block; and `role`, `management` and `temporal` are declarable
9
+ * nowhere else in the write API, so rewriting the declaration is a thing a caller legitimately
10
+ * means. The old behaviour spliced that block under the existing head and produced a page with
11
+ * two, the second invisible to everything that reads frontmatter. Adopting it is both what the
12
+ * caller asked for and the only reading that cannot silently accumulate.
13
+ */
14
+ export type BodyEdit = {
15
+ kind: 'content';
16
+ content: string;
17
+ } | {
18
+ kind: 'append';
19
+ text: string;
20
+ section?: string;
21
+ } | {
22
+ kind: 'patch';
23
+ patch: string;
24
+ } | {
25
+ kind: 'replace';
26
+ find: string;
27
+ with: string;
28
+ };
29
+ export interface EditResult {
30
+ content: string;
31
+ /** Lines that changed, for the journal summary and the write report. */
32
+ firstChangedLine: number | null;
33
+ /**
34
+ * Set when the write carried its own frontmatter block and it replaced the page's.
35
+ * `dropped` names the keys the old block declared and the new one does not, because a
36
+ * caller rewriting a declaration from memory is the likeliest way to lose a key nobody
37
+ * meant to remove — and a rewrite nobody can see is the failure this whole path exists
38
+ * to stop repeating.
39
+ */
40
+ frontmatter?: {
41
+ adopted: true;
42
+ dropped: string[];
43
+ };
44
+ }
45
+ export declare function applyEdit(original: string, edit: BodyEdit): EditResult;
46
+ /**
47
+ * A strict unified-diff applier: every context and removal line must match the
48
+ * file exactly, or the whole patch is refused.
49
+ *
50
+ * Strictness is the feature. A fuzzy applier that "finds the nearest match" will
51
+ * eventually apply a hunk to the wrong place, and in a knowledge base that means a
52
+ * value silently attached to the wrong subject — the exact failure Akno exists
53
+ * to prevent. Refusing costs the caller a re-read; guessing costs correctness.
54
+ *
55
+ * The `@@` line numbers are treated as a hint, not as truth: agents get them wrong
56
+ * constantly, and the context lines identify the location unambiguously anyway.
57
+ */
58
+ export declare function applyUnifiedDiff(body: string, patch: string): string;
59
+ //# sourceMappingURL=edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/write/edit.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;;OAMG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACpD;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,UAAU,CA8BtE;AA2ID;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAkBpE"}