@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.
- package/LICENSE +83 -0
- package/README.md +26 -0
- package/config/default.jsonc +548 -0
- package/dist/bench/answer-corpus.d.ts +48 -0
- package/dist/bench/answer-corpus.d.ts.map +1 -0
- package/dist/bench/answer-corpus.js +491 -0
- package/dist/bench/answer-corpus.js.map +1 -0
- package/dist/bench/answer.d.ts +156 -0
- package/dist/bench/answer.d.ts.map +1 -0
- package/dist/bench/answer.js +608 -0
- package/dist/bench/answer.js.map +1 -0
- package/dist/bench/auto-recall-answer-corpus.d.ts +21 -0
- package/dist/bench/auto-recall-answer-corpus.d.ts.map +1 -0
- package/dist/bench/auto-recall-answer-corpus.js +245 -0
- package/dist/bench/auto-recall-answer-corpus.js.map +1 -0
- package/dist/bench/auto-recall-answer.d.ts +198 -0
- package/dist/bench/auto-recall-answer.d.ts.map +1 -0
- package/dist/bench/auto-recall-answer.js +720 -0
- package/dist/bench/auto-recall-answer.js.map +1 -0
- package/dist/bench/auto-recall-corpus.d.ts +45 -0
- package/dist/bench/auto-recall-corpus.d.ts.map +1 -0
- package/dist/bench/auto-recall-corpus.js +221 -0
- package/dist/bench/auto-recall-corpus.js.map +1 -0
- package/dist/bench/auto-recall.d.ts +171 -0
- package/dist/bench/auto-recall.d.ts.map +1 -0
- package/dist/bench/auto-recall.js +651 -0
- package/dist/bench/auto-recall.js.map +1 -0
- package/dist/bench/entity-resolution.d.ts +37 -0
- package/dist/bench/entity-resolution.d.ts.map +1 -0
- package/dist/bench/entity-resolution.js +121 -0
- package/dist/bench/entity-resolution.js.map +1 -0
- package/dist/bench/graph.d.ts +57 -0
- package/dist/bench/graph.d.ts.map +1 -0
- package/dist/bench/graph.js +573 -0
- package/dist/bench/graph.js.map +1 -0
- package/dist/bench/llm-ranking-probe.d.ts +27 -0
- package/dist/bench/llm-ranking-probe.d.ts.map +1 -0
- package/dist/bench/llm-ranking-probe.js +105 -0
- package/dist/bench/llm-ranking-probe.js.map +1 -0
- package/dist/bench/merge-discovery-corpus.d.ts +26 -0
- package/dist/bench/merge-discovery-corpus.d.ts.map +1 -0
- package/dist/bench/merge-discovery-corpus.js +114 -0
- package/dist/bench/merge-discovery-corpus.js.map +1 -0
- package/dist/bench/merge-discovery-review.d.ts +81 -0
- package/dist/bench/merge-discovery-review.d.ts.map +1 -0
- package/dist/bench/merge-discovery-review.js +149 -0
- package/dist/bench/merge-discovery-review.js.map +1 -0
- package/dist/bench/merge-discovery.d.ts +122 -0
- package/dist/bench/merge-discovery.d.ts.map +1 -0
- package/dist/bench/merge-discovery.js +390 -0
- package/dist/bench/merge-discovery.js.map +1 -0
- package/dist/bench/mixed-retrieval.d.ts +35 -0
- package/dist/bench/mixed-retrieval.d.ts.map +1 -0
- package/dist/bench/mixed-retrieval.js +355 -0
- package/dist/bench/mixed-retrieval.js.map +1 -0
- package/dist/bench/ranking-corpus.d.ts +29 -0
- package/dist/bench/ranking-corpus.d.ts.map +1 -0
- package/dist/bench/ranking-corpus.js +514 -0
- package/dist/bench/ranking-corpus.js.map +1 -0
- package/dist/bench/ranking-end-to-end.d.ts +112 -0
- package/dist/bench/ranking-end-to-end.d.ts.map +1 -0
- package/dist/bench/ranking-end-to-end.js +479 -0
- package/dist/bench/ranking-end-to-end.js.map +1 -0
- package/dist/bench/ranking-latency.d.ts +71 -0
- package/dist/bench/ranking-latency.d.ts.map +1 -0
- package/dist/bench/ranking-latency.js +130 -0
- package/dist/bench/ranking-latency.js.map +1 -0
- package/dist/bench/ranking-matrix.d.ts +141 -0
- package/dist/bench/ranking-matrix.d.ts.map +1 -0
- package/dist/bench/ranking-matrix.js +526 -0
- package/dist/bench/ranking-matrix.js.map +1 -0
- package/dist/bench/ranking-review.d.ts +93 -0
- package/dist/bench/ranking-review.d.ts.map +1 -0
- package/dist/bench/ranking-review.js +249 -0
- package/dist/bench/ranking-review.js.map +1 -0
- package/dist/bench/ranking.d.ts +122 -0
- package/dist/bench/ranking.d.ts.map +1 -0
- package/dist/bench/ranking.js +547 -0
- package/dist/bench/ranking.js.map +1 -0
- package/dist/bench.d.ts +60 -0
- package/dist/bench.d.ts.map +1 -0
- package/dist/bench.js +167 -0
- package/dist/bench.js.map +1 -0
- package/dist/config/jsonc.d.ts +8 -0
- package/dist/config/jsonc.d.ts.map +1 -0
- package/dist/config/jsonc.js +85 -0
- package/dist/config/jsonc.js.map +1 -0
- package/dist/config/load.d.ts +43 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +608 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/paths.d.ts +10 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +38 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/schema.d.ts +698 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +394 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/write-rules.d.ts +41 -0
- package/dist/config/write-rules.d.ts.map +1 -0
- package/dist/config/write-rules.js +225 -0
- package/dist/config/write-rules.js.map +1 -0
- package/dist/config/write-setup.d.ts +42 -0
- package/dist/config/write-setup.d.ts.map +1 -0
- package/dist/config/write-setup.js +358 -0
- package/dist/config/write-setup.js.map +1 -0
- package/dist/context.d.ts +64 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +14 -0
- package/dist/context.js.map +1 -0
- package/dist/doctor.d.ts +115 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +388 -0
- package/dist/doctor.js.map +1 -0
- package/dist/index/chunk.d.ts +62 -0
- package/dist/index/chunk.d.ts.map +1 -0
- package/dist/index/chunk.js +307 -0
- package/dist/index/chunk.js.map +1 -0
- package/dist/index/defer.d.ts +32 -0
- package/dist/index/defer.d.ts.map +1 -0
- package/dist/index/defer.js +66 -0
- package/dist/index/defer.js.map +1 -0
- package/dist/index/derive.d.ts +99 -0
- package/dist/index/derive.d.ts.map +1 -0
- package/dist/index/derive.js +378 -0
- package/dist/index/derive.js.map +1 -0
- package/dist/index/entity-resolution.d.ts +68 -0
- package/dist/index/entity-resolution.d.ts.map +1 -0
- package/dist/index/entity-resolution.js +305 -0
- package/dist/index/entity-resolution.js.map +1 -0
- package/dist/index/graph.d.ts +46 -0
- package/dist/index/graph.d.ts.map +1 -0
- package/dist/index/graph.js +618 -0
- package/dist/index/graph.js.map +1 -0
- package/dist/index/indexer.d.ts +301 -0
- package/dist/index/indexer.d.ts.map +1 -0
- package/dist/index/indexer.js +1398 -0
- package/dist/index/indexer.js.map +1 -0
- package/dist/index/revision-barrier.d.ts +30 -0
- package/dist/index/revision-barrier.d.ts.map +1 -0
- package/dist/index/revision-barrier.js +140 -0
- package/dist/index/revision-barrier.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/adoption-eligibility.d.ts +4 -0
- package/dist/ingest/adoption-eligibility.d.ts.map +1 -0
- package/dist/ingest/adoption-eligibility.js +18 -0
- package/dist/ingest/adoption-eligibility.js.map +1 -0
- package/dist/ingest/availability.d.ts +15 -0
- package/dist/ingest/availability.d.ts.map +1 -0
- package/dist/ingest/availability.js +37 -0
- package/dist/ingest/availability.js.map +1 -0
- package/dist/ingest/extract.d.ts +58 -0
- package/dist/ingest/extract.d.ts.map +1 -0
- package/dist/ingest/extract.js +255 -0
- package/dist/ingest/extract.js.map +1 -0
- package/dist/ingest/fetch.d.ts +35 -0
- package/dist/ingest/fetch.d.ts.map +1 -0
- package/dist/ingest/fetch.js +142 -0
- package/dist/ingest/fetch.js.map +1 -0
- package/dist/ingest/inbox.d.ts +53 -0
- package/dist/ingest/inbox.d.ts.map +1 -0
- package/dist/ingest/inbox.js +110 -0
- package/dist/ingest/inbox.js.map +1 -0
- package/dist/ingest/name.d.ts +72 -0
- package/dist/ingest/name.d.ts.map +1 -0
- package/dist/ingest/name.js +208 -0
- package/dist/ingest/name.js.map +1 -0
- package/dist/ingest/parts.d.ts +78 -0
- package/dist/ingest/parts.d.ts.map +1 -0
- package/dist/ingest/parts.js +52 -0
- package/dist/ingest/parts.js.map +1 -0
- package/dist/ingest/rendition.d.ts +75 -0
- package/dist/ingest/rendition.d.ts.map +1 -0
- package/dist/ingest/rendition.js +92 -0
- package/dist/ingest/rendition.js.map +1 -0
- package/dist/ingest/store.d.ts +66 -0
- package/dist/ingest/store.d.ts.map +1 -0
- package/dist/ingest/store.js +92 -0
- package/dist/ingest/store.js.map +1 -0
- package/dist/kb/folders.d.ts +37 -0
- package/dist/kb/folders.d.ts.map +1 -0
- package/dist/kb/folders.js +133 -0
- package/dist/kb/folders.js.map +1 -0
- package/dist/kb/frontmatter.d.ts +91 -0
- package/dist/kb/frontmatter.d.ts.map +1 -0
- package/dist/kb/frontmatter.js +274 -0
- package/dist/kb/frontmatter.js.map +1 -0
- package/dist/kb/line-facts.d.ts +29 -0
- package/dist/kb/line-facts.d.ts.map +1 -0
- package/dist/kb/line-facts.js +23 -0
- package/dist/kb/line-facts.js.map +1 -0
- package/dist/kb/page.d.ts +92 -0
- package/dist/kb/page.d.ts.map +1 -0
- package/dist/kb/page.js +243 -0
- package/dist/kb/page.js.map +1 -0
- package/dist/kb/scan.d.ts +38 -0
- package/dist/kb/scan.d.ts.map +1 -0
- package/dist/kb/scan.js +109 -0
- package/dist/kb/scan.js.map +1 -0
- package/dist/kb/words.d.ts +30 -0
- package/dist/kb/words.d.ts.map +1 -0
- package/dist/kb/words.js +107 -0
- package/dist/kb/words.js.map +1 -0
- package/dist/maintenance/adopt.d.ts +65 -0
- package/dist/maintenance/adopt.d.ts.map +1 -0
- package/dist/maintenance/adopt.js +238 -0
- package/dist/maintenance/adopt.js.map +1 -0
- package/dist/maintenance/budget.d.ts +55 -0
- package/dist/maintenance/budget.d.ts.map +1 -0
- package/dist/maintenance/budget.js +61 -0
- package/dist/maintenance/budget.js.map +1 -0
- package/dist/maintenance/conflicts.d.ts +105 -0
- package/dist/maintenance/conflicts.d.ts.map +1 -0
- package/dist/maintenance/conflicts.js +368 -0
- package/dist/maintenance/conflicts.js.map +1 -0
- package/dist/maintenance/contradictions.d.ts +34 -0
- package/dist/maintenance/contradictions.d.ts.map +1 -0
- package/dist/maintenance/contradictions.js +199 -0
- package/dist/maintenance/contradictions.js.map +1 -0
- package/dist/maintenance/curate.d.ts +156 -0
- package/dist/maintenance/curate.d.ts.map +1 -0
- package/dist/maintenance/curate.js +2070 -0
- package/dist/maintenance/curate.js.map +1 -0
- package/dist/maintenance/dream.d.ts +139 -0
- package/dist/maintenance/dream.d.ts.map +1 -0
- package/dist/maintenance/dream.js +1632 -0
- package/dist/maintenance/dream.js.map +1 -0
- package/dist/maintenance/graph-candidates.d.ts +19 -0
- package/dist/maintenance/graph-candidates.d.ts.map +1 -0
- package/dist/maintenance/graph-candidates.js +120 -0
- package/dist/maintenance/graph-candidates.js.map +1 -0
- package/dist/maintenance/housekeeping.d.ts +81 -0
- package/dist/maintenance/housekeeping.d.ts.map +1 -0
- package/dist/maintenance/housekeeping.js +281 -0
- package/dist/maintenance/housekeeping.js.map +1 -0
- package/dist/maintenance/link-repairs.d.ts +58 -0
- package/dist/maintenance/link-repairs.d.ts.map +1 -0
- package/dist/maintenance/link-repairs.js +281 -0
- package/dist/maintenance/link-repairs.js.map +1 -0
- package/dist/maintenance/log.d.ts +41 -0
- package/dist/maintenance/log.d.ts.map +1 -0
- package/dist/maintenance/log.js +72 -0
- package/dist/maintenance/log.js.map +1 -0
- package/dist/maintenance/managed-item-routing.d.ts +48 -0
- package/dist/maintenance/managed-item-routing.d.ts.map +1 -0
- package/dist/maintenance/managed-item-routing.js +281 -0
- package/dist/maintenance/managed-item-routing.js.map +1 -0
- package/dist/maintenance/managed-item-sources.d.ts +38 -0
- package/dist/maintenance/managed-item-sources.d.ts.map +1 -0
- package/dist/maintenance/managed-item-sources.js +324 -0
- package/dist/maintenance/managed-item-sources.js.map +1 -0
- package/dist/maintenance/managed-items.d.ts +162 -0
- package/dist/maintenance/managed-items.d.ts.map +1 -0
- package/dist/maintenance/managed-items.js +1329 -0
- package/dist/maintenance/managed-items.js.map +1 -0
- package/dist/maintenance/merge-classifier.d.ts +19 -0
- package/dist/maintenance/merge-classifier.d.ts.map +1 -0
- package/dist/maintenance/merge-classifier.js +49 -0
- package/dist/maintenance/merge-classifier.js.map +1 -0
- package/dist/maintenance/model-telemetry.d.ts +45 -0
- package/dist/maintenance/model-telemetry.d.ts.map +1 -0
- package/dist/maintenance/model-telemetry.js +107 -0
- package/dist/maintenance/model-telemetry.js.map +1 -0
- package/dist/maintenance/observe.d.ts +72 -0
- package/dist/maintenance/observe.d.ts.map +1 -0
- package/dist/maintenance/observe.js +265 -0
- package/dist/maintenance/observe.js.map +1 -0
- package/dist/maintenance/path-policy.d.ts +83 -0
- package/dist/maintenance/path-policy.d.ts.map +1 -0
- package/dist/maintenance/path-policy.js +360 -0
- package/dist/maintenance/path-policy.js.map +1 -0
- package/dist/maintenance/plans.d.ts +366 -0
- package/dist/maintenance/plans.d.ts.map +1 -0
- package/dist/maintenance/plans.js +4060 -0
- package/dist/maintenance/plans.js.map +1 -0
- package/dist/maintenance/profile.d.ts +33 -0
- package/dist/maintenance/profile.d.ts.map +1 -0
- package/dist/maintenance/profile.js +99 -0
- package/dist/maintenance/profile.js.map +1 -0
- package/dist/maintenance/recovery.d.ts +38 -0
- package/dist/maintenance/recovery.d.ts.map +1 -0
- package/dist/maintenance/recovery.js +217 -0
- package/dist/maintenance/recovery.js.map +1 -0
- package/dist/maintenance/repair.d.ts +37 -0
- package/dist/maintenance/repair.d.ts.map +1 -0
- package/dist/maintenance/repair.js +183 -0
- package/dist/maintenance/repair.js.map +1 -0
- package/dist/maintenance/rule-drift.d.ts +104 -0
- package/dist/maintenance/rule-drift.d.ts.map +1 -0
- package/dist/maintenance/rule-drift.js +507 -0
- package/dist/maintenance/rule-drift.js.map +1 -0
- package/dist/maintenance/run-verification.d.ts +44 -0
- package/dist/maintenance/run-verification.d.ts.map +1 -0
- package/dist/maintenance/run-verification.js +253 -0
- package/dist/maintenance/run-verification.js.map +1 -0
- package/dist/maintenance/runs.d.ts +142 -0
- package/dist/maintenance/runs.d.ts.map +1 -0
- package/dist/maintenance/runs.js +439 -0
- package/dist/maintenance/runs.js.map +1 -0
- package/dist/maintenance/semantic-merge-discovery.d.ts +54 -0
- package/dist/maintenance/semantic-merge-discovery.d.ts.map +1 -0
- package/dist/maintenance/semantic-merge-discovery.js +308 -0
- package/dist/maintenance/semantic-merge-discovery.js.map +1 -0
- package/dist/maintenance/temporal.d.ts +44 -0
- package/dist/maintenance/temporal.d.ts.map +1 -0
- package/dist/maintenance/temporal.js +295 -0
- package/dist/maintenance/temporal.js.map +1 -0
- package/dist/models/client.d.ts +214 -0
- package/dist/models/client.d.ts.map +1 -0
- package/dist/models/client.js +904 -0
- package/dist/models/client.js.map +1 -0
- package/dist/models/provider-api.d.ts +28 -0
- package/dist/models/provider-api.d.ts.map +1 -0
- package/dist/models/provider-api.js +320 -0
- package/dist/models/provider-api.js.map +1 -0
- package/dist/open.d.ts +163 -0
- package/dist/open.d.ts.map +1 -0
- package/dist/open.js +382 -0
- package/dist/open.js.map +1 -0
- package/dist/ops/adopt.d.ts +12 -0
- package/dist/ops/adopt.d.ts.map +1 -0
- package/dist/ops/adopt.js +138 -0
- package/dist/ops/adopt.js.map +1 -0
- package/dist/ops/answer.d.ts +29 -0
- package/dist/ops/answer.d.ts.map +1 -0
- package/dist/ops/answer.js +557 -0
- package/dist/ops/answer.js.map +1 -0
- package/dist/ops/context.d.ts +18 -0
- package/dist/ops/context.d.ts.map +1 -0
- package/dist/ops/context.js +713 -0
- package/dist/ops/context.js.map +1 -0
- package/dist/ops/folder.d.ts +23 -0
- package/dist/ops/folder.d.ts.map +1 -0
- package/dist/ops/folder.js +130 -0
- package/dist/ops/folder.js.map +1 -0
- package/dist/ops/forget.d.ts +14 -0
- package/dist/ops/forget.d.ts.map +1 -0
- package/dist/ops/forget.js +212 -0
- package/dist/ops/forget.js.map +1 -0
- package/dist/ops/graph.d.ts +10 -0
- package/dist/ops/graph.d.ts.map +1 -0
- package/dist/ops/graph.js +480 -0
- package/dist/ops/graph.js.map +1 -0
- package/dist/ops/ingest.d.ts +40 -0
- package/dist/ops/ingest.d.ts.map +1 -0
- package/dist/ops/ingest.js +434 -0
- package/dist/ops/ingest.js.map +1 -0
- package/dist/ops/list.d.ts +9 -0
- package/dist/ops/list.d.ts.map +1 -0
- package/dist/ops/list.js +217 -0
- package/dist/ops/list.js.map +1 -0
- package/dist/ops/move.d.ts +20 -0
- package/dist/ops/move.d.ts.map +1 -0
- package/dist/ops/move.js +173 -0
- package/dist/ops/move.js.map +1 -0
- package/dist/ops/read.d.ts +9 -0
- package/dist/ops/read.d.ts.map +1 -0
- package/dist/ops/read.js +271 -0
- package/dist/ops/read.js.map +1 -0
- package/dist/ops/recall.d.ts +13 -0
- package/dist/ops/recall.d.ts.map +1 -0
- package/dist/ops/recall.js +297 -0
- package/dist/ops/recall.js.map +1 -0
- package/dist/ops/remember.d.ts +34 -0
- package/dist/ops/remember.d.ts.map +1 -0
- package/dist/ops/remember.js +660 -0
- package/dist/ops/remember.js.map +1 -0
- package/dist/ops/timeline.d.ts +11 -0
- package/dist/ops/timeline.d.ts.map +1 -0
- package/dist/ops/timeline.js +111 -0
- package/dist/ops/timeline.js.map +1 -0
- package/dist/ops/undo.d.ts +9 -0
- package/dist/ops/undo.d.ts.map +1 -0
- package/dist/ops/undo.js +38 -0
- package/dist/ops/undo.js.map +1 -0
- package/dist/ops/write.d.ts +55 -0
- package/dist/ops/write.d.ts.map +1 -0
- package/dist/ops/write.js +463 -0
- package/dist/ops/write.js.map +1 -0
- package/dist/recall/assemble.d.ts +81 -0
- package/dist/recall/assemble.d.ts.map +1 -0
- package/dist/recall/assemble.js +603 -0
- package/dist/recall/assemble.js.map +1 -0
- package/dist/recall/expand.d.ts +55 -0
- package/dist/recall/expand.d.ts.map +1 -0
- package/dist/recall/expand.js +282 -0
- package/dist/recall/expand.js.map +1 -0
- package/dist/recall/graph-arm.d.ts +17 -0
- package/dist/recall/graph-arm.d.ts.map +1 -0
- package/dist/recall/graph-arm.js +227 -0
- package/dist/recall/graph-arm.js.map +1 -0
- package/dist/recall/llm-rerank.d.ts +55 -0
- package/dist/recall/llm-rerank.d.ts.map +1 -0
- package/dist/recall/llm-rerank.js +213 -0
- package/dist/recall/llm-rerank.js.map +1 -0
- package/dist/recall/reranker-calibration.d.ts +23 -0
- package/dist/recall/reranker-calibration.d.ts.map +1 -0
- package/dist/recall/reranker-calibration.js +161 -0
- package/dist/recall/reranker-calibration.js.map +1 -0
- package/dist/recall/search.d.ts +107 -0
- package/dist/recall/search.d.ts.map +1 -0
- package/dist/recall/search.js +530 -0
- package/dist/recall/search.js.map +1 -0
- package/dist/reserved.d.ts +39 -0
- package/dist/reserved.d.ts.map +1 -0
- package/dist/reserved.js +63 -0
- package/dist/reserved.js.map +1 -0
- package/dist/rules/compile.d.ts +27 -0
- package/dist/rules/compile.d.ts.map +1 -0
- package/dist/rules/compile.js +105 -0
- package/dist/rules/compile.js.map +1 -0
- package/dist/setup/model-free.d.ts +15 -0
- package/dist/setup/model-free.d.ts.map +1 -0
- package/dist/setup/model-free.js +26 -0
- package/dist/setup/model-free.js.map +1 -0
- package/dist/setup/openai.d.ts +46 -0
- package/dist/setup/openai.d.ts.map +1 -0
- package/dist/setup/openai.js +165 -0
- package/dist/setup/openai.js.map +1 -0
- package/dist/store/db.d.ts +61 -0
- package/dist/store/db.d.ts.map +1 -0
- package/dist/store/db.js +265 -0
- package/dist/store/db.js.map +1 -0
- package/dist/store/ids.d.ts +29 -0
- package/dist/store/ids.d.ts.map +1 -0
- package/dist/store/ids.js +0 -0
- package/dist/store/ids.js.map +1 -0
- package/dist/store/migrations.d.ts +54 -0
- package/dist/store/migrations.d.ts.map +1 -0
- package/dist/store/migrations.js +923 -0
- package/dist/store/migrations.js.map +1 -0
- package/dist/store/vectors.d.ts +34 -0
- package/dist/store/vectors.d.ts.map +1 -0
- package/dist/store/vectors.js +158 -0
- package/dist/store/vectors.js.map +1 -0
- package/dist/timeline/documents.d.ts +23 -0
- package/dist/timeline/documents.d.ts.map +1 -0
- package/dist/timeline/documents.js +262 -0
- package/dist/timeline/documents.js.map +1 -0
- package/dist/watch/watcher.d.ts +43 -0
- package/dist/watch/watcher.d.ts.map +1 -0
- package/dist/watch/watcher.js +143 -0
- package/dist/watch/watcher.js.map +1 -0
- package/dist/write/atomic.d.ts +34 -0
- package/dist/write/atomic.d.ts.map +1 -0
- package/dist/write/atomic.js +58 -0
- package/dist/write/atomic.js.map +1 -0
- package/dist/write/conflict.d.ts +43 -0
- package/dist/write/conflict.d.ts.map +1 -0
- package/dist/write/conflict.js +149 -0
- package/dist/write/conflict.js.map +1 -0
- package/dist/write/edit.d.ts +59 -0
- package/dist/write/edit.d.ts.map +1 -0
- package/dist/write/edit.js +231 -0
- package/dist/write/edit.js.map +1 -0
- package/dist/write/gate.d.ts +59 -0
- package/dist/write/gate.d.ts.map +1 -0
- package/dist/write/gate.js +99 -0
- package/dist/write/gate.js.map +1 -0
- package/dist/write/journal.d.ts +90 -0
- package/dist/write/journal.d.ts.map +1 -0
- package/dist/write/journal.js +187 -0
- package/dist/write/journal.js.map +1 -0
- package/dist/write/ledger.d.ts +28 -0
- package/dist/write/ledger.d.ts.map +1 -0
- package/dist/write/ledger.js +141 -0
- package/dist/write/ledger.js.map +1 -0
- package/dist/write/placement.d.ts +29 -0
- package/dist/write/placement.d.ts.map +1 -0
- package/dist/write/placement.js +140 -0
- package/dist/write/placement.js.map +1 -0
- package/dist/write/remember-fallback.d.ts +18 -0
- package/dist/write/remember-fallback.d.ts.map +1 -0
- package/dist/write/remember-fallback.js +48 -0
- package/dist/write/remember-fallback.js.map +1 -0
- package/dist/write/retain.d.ts +61 -0
- package/dist/write/retain.d.ts.map +1 -0
- package/dist/write/retain.js +272 -0
- package/dist/write/retain.js.map +1 -0
- package/package.json +50 -0
- package/swift/extract.swift +232 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { AknoError } from '@tenphi/akno-protocol';
|
|
2
|
+
import { declaredFrontmatter, parseFrontmatter, withId } from "../kb/frontmatter.js";
|
|
3
|
+
export function applyEdit(original, edit) {
|
|
4
|
+
const frontmatter = parseFrontmatter(original);
|
|
5
|
+
const head = original.slice(0, frontmatter.bodyOffset);
|
|
6
|
+
const body = original.slice(frontmatter.bodyOffset);
|
|
7
|
+
if (edit.kind === 'content') {
|
|
8
|
+
const declared = declaredFrontmatter(edit.content);
|
|
9
|
+
if (declared) {
|
|
10
|
+
// `id` is Akno's own key and the caller has no reason to be carrying it. Losing it
|
|
11
|
+
// detaches the page from its row, so it survives a rewrite that omits it.
|
|
12
|
+
const id = frontmatter.data.id;
|
|
13
|
+
const nextHead = typeof id === 'string' && id.length > 0 ? withId(declared.head, id) : declared.head;
|
|
14
|
+
// A blank line between the closing fence and the body, matching how every page Akno
|
|
15
|
+
// composes is laid out. `bodyOffset` has already eaten the fence's own newline.
|
|
16
|
+
const separated = declared.body.startsWith('\n') ? declared.body : `\n${declared.body}`;
|
|
17
|
+
const content = nextHead + endWithNewline(separated);
|
|
18
|
+
const dropped = Object.keys(frontmatter.data).filter((key) => key !== 'id' && !Object.hasOwn(declared.data, key));
|
|
19
|
+
return {
|
|
20
|
+
content,
|
|
21
|
+
firstChangedLine: firstDifference(original, content),
|
|
22
|
+
frontmatter: { adopted: true, dropped },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const nextBody = editBody(body, edit);
|
|
27
|
+
const content = head + nextBody;
|
|
28
|
+
return { content, firstChangedLine: firstDifference(original, content) };
|
|
29
|
+
}
|
|
30
|
+
function editBody(body, edit) {
|
|
31
|
+
switch (edit.kind) {
|
|
32
|
+
case 'content':
|
|
33
|
+
return endWithNewline(edit.content);
|
|
34
|
+
case 'append': {
|
|
35
|
+
if (edit.section !== undefined)
|
|
36
|
+
return appendUnderHeading(body, edit.section, edit.text);
|
|
37
|
+
// A blank line before the appended text, unless the body already ends in
|
|
38
|
+
// one. Appending flush against the previous line silently joins two list
|
|
39
|
+
// items or two paragraphs into one.
|
|
40
|
+
const trimmed = body.replace(/\s+$/, '');
|
|
41
|
+
const separator = trimmed.length === 0 ? '' : '\n\n';
|
|
42
|
+
return endWithNewline(`${trimmed}${separator}${edit.text.trim()}`);
|
|
43
|
+
}
|
|
44
|
+
case 'replace': {
|
|
45
|
+
const occurrences = countOccurrences(body, edit.find);
|
|
46
|
+
if (occurrences === 0) {
|
|
47
|
+
throw new AknoError('invalid', `nothing to replace: the page does not contain that text`, {
|
|
48
|
+
find: edit.find.slice(0, 120),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (occurrences > 1) {
|
|
52
|
+
// Replacing the first of several is a coin flip about which line the
|
|
53
|
+
// caller meant, and the wrong guess edits a line nobody was looking at.
|
|
54
|
+
throw new AknoError('invalid', `that text appears ${occurrences} times — include enough context to identify one`, { find: edit.find.slice(0, 120), occurrences });
|
|
55
|
+
}
|
|
56
|
+
return endWithNewline(body.replace(edit.find, edit.with));
|
|
57
|
+
}
|
|
58
|
+
case 'patch':
|
|
59
|
+
return endWithNewline(applyUnifiedDiff(body, edit.patch));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const LIST_ITEM = /^\s*(?:[-*+]\s|\d+[.)]\s)/;
|
|
63
|
+
/**
|
|
64
|
+
* Appends at the end of a heading's section — after its last line, before the next heading at
|
|
65
|
+
* the same level or above.
|
|
66
|
+
*
|
|
67
|
+
* A page has structure and its author put it there. A claim about rent belongs under `## Rent`,
|
|
68
|
+
* and appending it to the end of the file instead puts it under whatever heading happens to be
|
|
69
|
+
* last, where a reader will attribute it to the wrong subject. That is not hypothetical: the
|
|
70
|
+
* host's tool advertised this and the schema silently dropped it, so every heading-scoped
|
|
71
|
+
* append had been landing at the bottom of the page.
|
|
72
|
+
*
|
|
73
|
+
* Absent or ambiguous is an error, matching `replace`. A caller that named a heading had one in
|
|
74
|
+
* mind, and the alternative to saying so is picking one of several and being quietly wrong.
|
|
75
|
+
*/
|
|
76
|
+
function appendUnderHeading(body, section, text) {
|
|
77
|
+
const wanted = section
|
|
78
|
+
.trim()
|
|
79
|
+
.replace(/^#+\s*/, '')
|
|
80
|
+
.toLowerCase();
|
|
81
|
+
const lines = body.split('\n');
|
|
82
|
+
const matches = [];
|
|
83
|
+
lines.forEach((line, index) => {
|
|
84
|
+
const heading = /^(#{1,6})\s+(.*?)\s*$/.exec(line);
|
|
85
|
+
if (heading && heading[2].toLowerCase() === wanted) {
|
|
86
|
+
matches.push({ index, level: heading[1].length });
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
if (matches.length === 0) {
|
|
90
|
+
throw new AknoError('invalid', `the page has no heading called "${section}"`, { section });
|
|
91
|
+
}
|
|
92
|
+
if (matches.length > 1) {
|
|
93
|
+
throw new AknoError('invalid', `"${section}" appears ${matches.length} times on this page — append without a section, or patch`, { section, occurrences: matches.length });
|
|
94
|
+
}
|
|
95
|
+
const { index, level } = matches[0];
|
|
96
|
+
// The section runs to the next heading at the same level or shallower. A deeper one is part
|
|
97
|
+
// of this section, and stopping at it would insert above content that belongs above.
|
|
98
|
+
let end = lines.length;
|
|
99
|
+
for (let i = index + 1; i < lines.length; i++) {
|
|
100
|
+
const heading = /^(#{1,6})\s/.exec(lines[i]);
|
|
101
|
+
if (heading && heading[1].length <= level) {
|
|
102
|
+
end = i;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Back over the blank lines that separate this section from the next, so the insertion lands
|
|
107
|
+
// against the section's own content rather than against the following heading.
|
|
108
|
+
let at = end;
|
|
109
|
+
while (at > index + 1 && lines[at - 1].trim() === '')
|
|
110
|
+
at--;
|
|
111
|
+
// A blank line separates two paragraphs and *breaks* a list — Markdown reads a gap between
|
|
112
|
+
// items as a loose list and renders every item wrapped in a paragraph. Appending a bullet
|
|
113
|
+
// under a heading is the common case here, so the two are distinguished rather than always
|
|
114
|
+
// getting a gap.
|
|
115
|
+
const previous = lines[at - 1];
|
|
116
|
+
const bothListItems = LIST_ITEM.test(previous) && LIST_ITEM.test(text.trim());
|
|
117
|
+
const separator = previous.trim() === '' || bothListItems ? [] : [''];
|
|
118
|
+
lines.splice(at, 0, ...separator, text.trim());
|
|
119
|
+
return endWithNewline(lines.join('\n'));
|
|
120
|
+
}
|
|
121
|
+
function endWithNewline(text) {
|
|
122
|
+
return text.endsWith('\n') ? text : `${text}\n`;
|
|
123
|
+
}
|
|
124
|
+
function countOccurrences(haystack, needle) {
|
|
125
|
+
if (needle.length === 0)
|
|
126
|
+
return 0;
|
|
127
|
+
let count = 0;
|
|
128
|
+
let index = haystack.indexOf(needle);
|
|
129
|
+
while (index !== -1) {
|
|
130
|
+
count++;
|
|
131
|
+
index = haystack.indexOf(needle, index + needle.length);
|
|
132
|
+
}
|
|
133
|
+
return count;
|
|
134
|
+
}
|
|
135
|
+
function firstDifference(before, after) {
|
|
136
|
+
if (before === after)
|
|
137
|
+
return null;
|
|
138
|
+
const a = before.split('\n');
|
|
139
|
+
const b = after.split('\n');
|
|
140
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
141
|
+
if (a[i] !== b[i])
|
|
142
|
+
return i + 1;
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
// ─── Unified diff ───────────────────────────────────────────────────────────
|
|
147
|
+
/**
|
|
148
|
+
* A strict unified-diff applier: every context and removal line must match the
|
|
149
|
+
* file exactly, or the whole patch is refused.
|
|
150
|
+
*
|
|
151
|
+
* Strictness is the feature. A fuzzy applier that "finds the nearest match" will
|
|
152
|
+
* eventually apply a hunk to the wrong place, and in a knowledge base that means a
|
|
153
|
+
* value silently attached to the wrong subject — the exact failure Akno exists
|
|
154
|
+
* to prevent. Refusing costs the caller a re-read; guessing costs correctness.
|
|
155
|
+
*
|
|
156
|
+
* The `@@` line numbers are treated as a hint, not as truth: agents get them wrong
|
|
157
|
+
* constantly, and the context lines identify the location unambiguously anyway.
|
|
158
|
+
*/
|
|
159
|
+
export function applyUnifiedDiff(body, patch) {
|
|
160
|
+
const hunks = parseHunks(patch);
|
|
161
|
+
if (hunks.length === 0) {
|
|
162
|
+
throw new AknoError('invalid', 'the patch contains no @@ hunks');
|
|
163
|
+
}
|
|
164
|
+
const lines = body.split('\n');
|
|
165
|
+
// Apply back to front so earlier hunks' line numbers stay valid.
|
|
166
|
+
const located = hunks.map((hunk) => ({ hunk, at: locate(lines, hunk) }));
|
|
167
|
+
located.sort((a, b) => b.at - a.at);
|
|
168
|
+
for (const { hunk, at } of located) {
|
|
169
|
+
const removals = hunk.lines.filter((line) => line.sign !== '+').length;
|
|
170
|
+
const replacement = hunk.lines.filter((line) => line.sign !== '-').map((line) => line.text);
|
|
171
|
+
lines.splice(at, removals, ...replacement);
|
|
172
|
+
}
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
}
|
|
175
|
+
function parseHunks(patch) {
|
|
176
|
+
const hunks = [];
|
|
177
|
+
let current = null;
|
|
178
|
+
for (const raw of patch.split('\n')) {
|
|
179
|
+
const header = /^@@\s+-(\d+)(?:,\d+)?\s+\+\d+(?:,\d+)?\s+@@/.exec(raw);
|
|
180
|
+
if (header) {
|
|
181
|
+
current = { hint: Number(header[1]), lines: [] };
|
|
182
|
+
hunks.push(current);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (!current)
|
|
186
|
+
continue;
|
|
187
|
+
// `---`/`+++` file headers, and the "\ No newline" marker, are not content.
|
|
188
|
+
if (raw.startsWith('---') || raw.startsWith('+++') || raw.startsWith('\\'))
|
|
189
|
+
continue;
|
|
190
|
+
const sign = raw[0];
|
|
191
|
+
if (sign === ' ' || sign === '+' || sign === '-') {
|
|
192
|
+
current.lines.push({ sign, text: raw.slice(1) });
|
|
193
|
+
}
|
|
194
|
+
else if (raw.length === 0) {
|
|
195
|
+
// A truly empty line in a diff is a context line for an empty line.
|
|
196
|
+
current.lines.push({ sign: ' ', text: '' });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return hunks.filter((hunk) => hunk.lines.length > 0);
|
|
200
|
+
}
|
|
201
|
+
/** Finds the one place a hunk's context matches, searching outward from the hint. */
|
|
202
|
+
function locate(lines, hunk) {
|
|
203
|
+
const expected = hunk.lines.filter((line) => line.sign !== '+').map((line) => line.text);
|
|
204
|
+
if (expected.length === 0) {
|
|
205
|
+
// Pure insertion: the hint is all there is to go on.
|
|
206
|
+
const at = Math.min(Math.max(hunk.hint - 1, 0), lines.length);
|
|
207
|
+
return at;
|
|
208
|
+
}
|
|
209
|
+
const matchesAt = (start) => start >= 0 &&
|
|
210
|
+
start + expected.length <= lines.length &&
|
|
211
|
+
expected.every((text, offset) => lines[start + offset] === text);
|
|
212
|
+
const hinted = hunk.hint - 1;
|
|
213
|
+
if (matchesAt(hinted))
|
|
214
|
+
return hinted;
|
|
215
|
+
// Search outward, and require the match to be unique so an ambiguous hunk is
|
|
216
|
+
// refused rather than applied to whichever copy came first.
|
|
217
|
+
const found = [];
|
|
218
|
+
for (let start = 0; start + expected.length <= lines.length; start++) {
|
|
219
|
+
if (matchesAt(start))
|
|
220
|
+
found.push(start);
|
|
221
|
+
}
|
|
222
|
+
if (found.length === 1)
|
|
223
|
+
return found[0];
|
|
224
|
+
if (found.length === 0) {
|
|
225
|
+
throw new AknoError('invalid', 'patch context does not match the page — re-read it and patch again', {
|
|
226
|
+
expected: expected.slice(0, 3),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
throw new AknoError('invalid', `patch context matches ${found.length} places — include more context to identify one`, { expected: expected.slice(0, 3) });
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/write/edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { FolderRequired } from '@tenphi/akno-protocol';
|
|
2
|
+
import type { Store } from '../store/db.ts';
|
|
3
|
+
import type { AknoConfig } from '../config/schema.ts';
|
|
4
|
+
/**
|
|
5
|
+
* **A page may not appear in a folder nobody has described.**
|
|
6
|
+
*
|
|
7
|
+
* This used to be an approval: a new top-level folder became a proposal, an approval card, and
|
|
8
|
+
* a decision the owner had to make from a phone. That was the wrong question put to the wrong
|
|
9
|
+
* person. An owner cannot usefully rule on whether a research note needs a `research/` folder,
|
|
10
|
+
* and while the question waited the finding was lost. The second-order damage was worse — an
|
|
11
|
+
* agent that learns a folder request can be declined learns to append to whatever page already
|
|
12
|
+
* exists, and claims start landing on the pages of unrelated subjects.
|
|
13
|
+
*
|
|
14
|
+
* So nothing here waits on a human any more. What is refused is not the folder but the
|
|
15
|
+
* *silence*: the write comes back `requires_folder`, the caller declares the folder with the
|
|
16
|
+
* `folder` op — ungated, one call, saying what belongs there — and repeats the write. The user
|
|
17
|
+
* is never asked, and no folder appears that nothing can explain.
|
|
18
|
+
*
|
|
19
|
+
* `gate: "top-level"` (the default) requires a declaration for a new top-level folder and lets
|
|
20
|
+
* subfolders of a described one through. The asymmetry is the same as it always was:
|
|
21
|
+
* `medical/` appearing is a statement about how the knowledge base is organised;
|
|
22
|
+
* `work/projects/atlas/` under an existing `work/projects/` is not.
|
|
23
|
+
*
|
|
24
|
+
* If the user makes a folder themselves, that folder exists and nothing is asked. This module
|
|
25
|
+
* never sees a hand edit.
|
|
26
|
+
*/
|
|
27
|
+
export type GateDecision = {
|
|
28
|
+
allowed: true;
|
|
29
|
+
} | {
|
|
30
|
+
allowed: false;
|
|
31
|
+
requiresFolder: FolderRequired;
|
|
32
|
+
};
|
|
33
|
+
export interface ProposalRow {
|
|
34
|
+
id: string;
|
|
35
|
+
at: string;
|
|
36
|
+
kind: string;
|
|
37
|
+
reason: string;
|
|
38
|
+
subject: string;
|
|
39
|
+
payload: string;
|
|
40
|
+
nearest: string;
|
|
41
|
+
status: 'pending' | 'approved' | 'declined';
|
|
42
|
+
}
|
|
43
|
+
export declare class Gate {
|
|
44
|
+
#private;
|
|
45
|
+
constructor(store: Store, config: AknoConfig);
|
|
46
|
+
/**
|
|
47
|
+
* Checks a slug an agent wants to create.
|
|
48
|
+
*
|
|
49
|
+
* Nothing is recorded when this refuses. A proposal row existed to hold a question for the
|
|
50
|
+
* user; there is no question now, so writing one would leave `akno proposals` full of
|
|
51
|
+
* things nobody will ever answer — and an agent that re-asks after declaring the folder
|
|
52
|
+
* would collect one per attempt.
|
|
53
|
+
*/
|
|
54
|
+
check(slug: string, actor: string): GateDecision;
|
|
55
|
+
pending(): ProposalRow[];
|
|
56
|
+
get(id: string): ProposalRow | null;
|
|
57
|
+
resolve(id: string, status: 'approved' | 'declined', changeId?: string): void;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/write/gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,MAAM,YAAY,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,cAAc,EAAE,cAAc,CAAA;CAAE,CAAC;AAElG,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;CAC7C;AAED,qBAAa,IAAI;;gBAIH,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU;IAK5C;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY;IAuEhD,OAAO,IAAI,WAAW,EAAE;IAMxB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAInC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;CAK9E"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { physicalFolderExists } from "../kb/folders.js";
|
|
2
|
+
export class Gate {
|
|
3
|
+
#store;
|
|
4
|
+
#config;
|
|
5
|
+
constructor(store, config) {
|
|
6
|
+
this.#store = store;
|
|
7
|
+
this.#config = config;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Checks a slug an agent wants to create.
|
|
11
|
+
*
|
|
12
|
+
* Nothing is recorded when this refuses. A proposal row existed to hold a question for the
|
|
13
|
+
* user; there is no question now, so writing one would leave `akno proposals` full of
|
|
14
|
+
* things nobody will ever answer — and an agent that re-asks after declaring the folder
|
|
15
|
+
* would collect one per attempt.
|
|
16
|
+
*/
|
|
17
|
+
check(slug, actor) {
|
|
18
|
+
if (actor === 'user' || this.#config.gate === 'none')
|
|
19
|
+
return { allowed: true };
|
|
20
|
+
const newFolder = this.#firstUndeclaredFolder(slug);
|
|
21
|
+
if (!newFolder)
|
|
22
|
+
return { allowed: true };
|
|
23
|
+
if (this.#config.gate === 'top-level' && newFolder.includes('/'))
|
|
24
|
+
return { allowed: true };
|
|
25
|
+
return { allowed: false, requiresFolder: { folder: newFolder, nearest: this.#nearest(slug) } };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The shallowest folder on the slug's path that holds no page **and** has no rule
|
|
29
|
+
* describing it. Null when every folder on the way is one or the other.
|
|
30
|
+
*
|
|
31
|
+
* The rule half is what makes declare-then-write work in a single turn: a folder that was
|
|
32
|
+
* described a moment ago holds nothing yet, and asking the `pages` table alone would refuse
|
|
33
|
+
* the very write the declaration was made for.
|
|
34
|
+
*/
|
|
35
|
+
#firstUndeclaredFolder(slug) {
|
|
36
|
+
const segments = slug.split('/');
|
|
37
|
+
segments.pop(); // The page's own basename is not a folder.
|
|
38
|
+
if (segments.length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
const exists = this.#store.db.prepare("SELECT 1 AS ok FROM pages WHERE slug LIKE ? || '/%' LIMIT 1");
|
|
41
|
+
for (let depth = 1; depth <= segments.length; depth++) {
|
|
42
|
+
const folder = segments.slice(0, depth).join('/');
|
|
43
|
+
if (exists.get(folder))
|
|
44
|
+
continue;
|
|
45
|
+
// The page index cannot represent an empty directory. A folder the user created on disk is
|
|
46
|
+
// nevertheless an explicit taxonomy decision and must not be reported as nonexistent.
|
|
47
|
+
if (physicalFolderExists(this.#config, folder))
|
|
48
|
+
continue;
|
|
49
|
+
if (this.#described(folder))
|
|
50
|
+
continue;
|
|
51
|
+
return folder;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
/** True when some rule names this exact folder — `research` for a `research/**` rule. */
|
|
56
|
+
#described(folder) {
|
|
57
|
+
return this.#config.rules.some((rule) => rule.glob.replace(/\/\*+$/, '') === folder);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Where this could go instead, so a new folder is a choice rather than a reflex. Existing
|
|
61
|
+
* folders whose name shares a word with the slug, then the busiest top-level folders.
|
|
62
|
+
*/
|
|
63
|
+
#nearest(slug) {
|
|
64
|
+
const words = slug
|
|
65
|
+
.split(/[/\-_\s]+/)
|
|
66
|
+
.filter((word) => word.length > 3)
|
|
67
|
+
.map((word) => word.toLowerCase());
|
|
68
|
+
const out = new Set();
|
|
69
|
+
if (words.length > 0) {
|
|
70
|
+
const like = this.#store.db.prepare('SELECT DISTINCT slug FROM pages WHERE lower(slug) LIKE ? LIMIT 3');
|
|
71
|
+
for (const word of words) {
|
|
72
|
+
for (const row of like.all(`%${word}%`))
|
|
73
|
+
out.add(row.slug);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const folders = this.#store.db
|
|
77
|
+
.prepare(`SELECT substr(slug, 1, instr(slug, '/') - 1) AS folder, count(*) AS n
|
|
78
|
+
FROM pages WHERE instr(slug, '/') > 0
|
|
79
|
+
GROUP BY folder ORDER BY n DESC LIMIT 4`)
|
|
80
|
+
.all();
|
|
81
|
+
for (const row of folders)
|
|
82
|
+
out.add(row.folder);
|
|
83
|
+
return [...out].slice(0, 6);
|
|
84
|
+
}
|
|
85
|
+
pending() {
|
|
86
|
+
return this.#store.db
|
|
87
|
+
.prepare("SELECT * FROM proposals WHERE status = 'pending' ORDER BY at DESC")
|
|
88
|
+
.all();
|
|
89
|
+
}
|
|
90
|
+
get(id) {
|
|
91
|
+
return this.#store.db.prepare('SELECT * FROM proposals WHERE id = ?').get(id) ?? null;
|
|
92
|
+
}
|
|
93
|
+
resolve(id, status, changeId) {
|
|
94
|
+
this.#store.db
|
|
95
|
+
.prepare('UPDATE proposals SET status = ?, resolved_at = ?, change_id = ? WHERE id = ?')
|
|
96
|
+
.run(status, new Date().toISOString(), changeId ?? null, id);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/write/gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Store } from '../store/db.ts';
|
|
2
|
+
import { type WriteResult } from './atomic.ts';
|
|
3
|
+
/**
|
|
4
|
+
* **The journal is the only irreplaceable table.** Everything else is
|
|
5
|
+
* derived from the Markdown and rebuilt by `akno index`; this holds the previous
|
|
6
|
+
* bytes, and there is nowhere else to get them.
|
|
7
|
+
*
|
|
8
|
+
* It records content, not pointers — so `undo` still works after
|
|
9
|
+
* `rm akno.db && akno index` has thrown away every fact id the change might
|
|
10
|
+
* otherwise have referenced — which is why a fact id is never stored here.
|
|
11
|
+
*
|
|
12
|
+
* The unit is a **change**, not a file. One `write` can touch a page, the event
|
|
13
|
+
* ledger and an attachment; `undo` reverses all of them or none, because a page
|
|
14
|
+
* whose ledger line survived it is a knowledge base that now lies.
|
|
15
|
+
*/
|
|
16
|
+
export type FileAction = 'created' | 'modified' | 'deleted' | 'moved';
|
|
17
|
+
export interface ChangeFile {
|
|
18
|
+
relPath: string;
|
|
19
|
+
action: FileAction;
|
|
20
|
+
before: string | null;
|
|
21
|
+
after: string | null;
|
|
22
|
+
/** Set instead of `before` for a binary held in trash. */
|
|
23
|
+
snapshot?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Where a `moved` file went, when its bytes are nowhere else.
|
|
26
|
+
*
|
|
27
|
+
* A page carries its old text in `before`, so undo recreates it and deletes the copy at the
|
|
28
|
+
* new path. An attachment has no text to carry, and reversing it that way deleted the file
|
|
29
|
+
* and restored nothing. With this, the reversal is the rename it should always have been.
|
|
30
|
+
*/
|
|
31
|
+
movedTo?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ChangeSummary {
|
|
34
|
+
id: string;
|
|
35
|
+
at: string;
|
|
36
|
+
actor: string;
|
|
37
|
+
op: string;
|
|
38
|
+
summary: string;
|
|
39
|
+
status: 'applied' | 'undone';
|
|
40
|
+
files: {
|
|
41
|
+
relPath: string;
|
|
42
|
+
action: FileAction;
|
|
43
|
+
}[];
|
|
44
|
+
}
|
|
45
|
+
export declare class Journal {
|
|
46
|
+
#private;
|
|
47
|
+
constructor(store: Store, aknoPath: string, trashDir: string);
|
|
48
|
+
/**
|
|
49
|
+
* Records a change that has already been applied to disk. Deliberately after
|
|
50
|
+
* the fact: a journal entry for a write that then failed is a lie in the one
|
|
51
|
+
* table that has to be trustworthy, and the failure mode of recording late (a
|
|
52
|
+
* crash between write and journal leaves an un-undoable change) is both rarer
|
|
53
|
+
* and far less confusing than the reverse.
|
|
54
|
+
*/
|
|
55
|
+
record(input: {
|
|
56
|
+
actor: string;
|
|
57
|
+
op: string;
|
|
58
|
+
summary: string;
|
|
59
|
+
files: ChangeFile[];
|
|
60
|
+
}): string;
|
|
61
|
+
/**
|
|
62
|
+
* Reverses a change: every file back to its previous bytes, in reverse order.
|
|
63
|
+
*
|
|
64
|
+
* Reverse order matters for a move — the change created the destination and
|
|
65
|
+
* deleted the source, so undoing destination-first leaves the source free to be
|
|
66
|
+
* recreated. Forward order would try to recreate the source while the
|
|
67
|
+
* destination still holds it.
|
|
68
|
+
*/
|
|
69
|
+
undo(changeId: string): Promise<{
|
|
70
|
+
restored: string[];
|
|
71
|
+
removed: string[];
|
|
72
|
+
summary: string;
|
|
73
|
+
}>;
|
|
74
|
+
list(limit?: number): ChangeSummary[];
|
|
75
|
+
/**
|
|
76
|
+
* Moves a file into `trash/<change>/` and returns the snapshot path:
|
|
77
|
+
* `forget({slug})` moves a whole page to trash and stays undoable for the
|
|
78
|
+
* retention window — deleting outright would make "reversible" a lie.
|
|
79
|
+
*/
|
|
80
|
+
trash(relPath: string, changeToken: string): Promise<string>;
|
|
81
|
+
/**
|
|
82
|
+
* Drops trashed files past the retention window. Called from the maintenance
|
|
83
|
+
* path, never from a write — a delete that also expires somebody else's older
|
|
84
|
+
* delete is a surprise nobody asked for.
|
|
85
|
+
*/
|
|
86
|
+
expireTrash(retentionDays: number): Promise<number>;
|
|
87
|
+
}
|
|
88
|
+
/** Convenience: turn an atomic write result into the journal's shape. */
|
|
89
|
+
export declare function fileEntry(result: WriteResult): ChangeFile;
|
|
90
|
+
//# sourceMappingURL=journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/write/journal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5D;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,EAAE,CAAC;CAClD;AAED,qBAAa,OAAO;;gBAKN,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAM5D;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,EAAE,CAAA;KAAE,GAAG,MAAM;IA8B1F;;;;;;;OAOG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAkFjG,IAAI,CAAC,KAAK,SAAK,GAAG,aAAa,EAAE;IAyBjC;;;;OAIG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAalE;;;;OAIG;IACG,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAmB1D;AAED,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAOzD"}
|