pi-obsidian-memory 0.0.0 → 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/README.md +173 -7
- package/package.json +45 -7
- package/skills/obsidian-memory/SKILL.md +101 -0
- package/src/domain/capture/constants.ts +5 -0
- package/src/domain/capture/index.ts +6 -0
- package/src/domain/capture/input-problems.ts +9 -0
- package/src/domain/capture/schemas.ts +92 -0
- package/src/domain/capture/tally.ts +26 -0
- package/src/domain/capture/types.ts +49 -0
- package/src/domain/capture/validate.ts +75 -0
- package/src/domain/command-flags/constants.ts +141 -0
- package/src/domain/command-flags/index.ts +1 -0
- package/src/domain/config/change.ts +105 -0
- package/src/domain/config/constants.ts +25 -0
- package/src/domain/config/diagnostics.ts +35 -0
- package/src/domain/config/disclosures.ts +8 -0
- package/src/domain/config/fields.ts +7 -0
- package/src/domain/config/index.ts +11 -0
- package/src/domain/config/inspection.ts +43 -0
- package/src/domain/config/invariants.ts +68 -0
- package/src/domain/config/legacy-capture.ts +17 -0
- package/src/domain/config/observations.ts +109 -0
- package/src/domain/config/parse.ts +25 -0
- package/src/domain/config/paths.ts +61 -0
- package/src/domain/config/registration.ts +34 -0
- package/src/domain/config/repair.ts +36 -0
- package/src/domain/config/resources.ts +65 -0
- package/src/domain/config/rules.ts +49 -0
- package/src/domain/config/schemas.ts +155 -0
- package/src/domain/config/settings.ts +23 -0
- package/src/domain/config/types.ts +239 -0
- package/src/domain/decision-model/constants.ts +7 -0
- package/src/domain/decision-model/cutoffs.ts +8 -0
- package/src/domain/decision-model/endpoint.ts +11 -0
- package/src/domain/decision-model/failure-detail.ts +8 -0
- package/src/domain/decision-model/index.ts +6 -0
- package/src/domain/decision-model/rank.ts +36 -0
- package/src/domain/decision-model/types.ts +77 -0
- package/src/domain/embeddings/constants.ts +55 -0
- package/src/domain/embeddings/identity.ts +30 -0
- package/src/domain/embeddings/index.ts +5 -0
- package/src/domain/embeddings/schemas.ts +25 -0
- package/src/domain/embeddings/types.ts +52 -0
- package/src/domain/embeddings/vectors.ts +53 -0
- package/src/domain/folder-index/constants.ts +9 -0
- package/src/domain/folder-index/display.ts +22 -0
- package/src/domain/folder-index/index.ts +5 -0
- package/src/domain/folder-index/listing.ts +58 -0
- package/src/domain/folder-index/render.ts +114 -0
- package/src/domain/folder-index/types.ts +41 -0
- package/src/domain/index.ts +22 -0
- package/src/domain/lifecycle/index.ts +2 -0
- package/src/domain/lifecycle/lifecycle.ts +39 -0
- package/src/domain/lifecycle/types.ts +17 -0
- package/src/domain/loaded-memory/budget.ts +14 -0
- package/src/domain/loaded-memory/constants.ts +9 -0
- package/src/domain/loaded-memory/index.ts +4 -0
- package/src/domain/loaded-memory/render.ts +30 -0
- package/src/domain/loaded-memory/types.ts +19 -0
- package/src/domain/memory/draft.ts +12 -0
- package/src/domain/memory/index.ts +4 -0
- package/src/domain/memory/schemas.ts +15 -0
- package/src/domain/memory/target.ts +27 -0
- package/src/domain/memory/types.ts +20 -0
- package/src/domain/memory-agent/index.ts +5 -0
- package/src/domain/memory-agent/input-problems.ts +9 -0
- package/src/domain/memory-agent/refusal.ts +6 -0
- package/src/domain/memory-agent/schemas.ts +112 -0
- package/src/domain/memory-agent/types.ts +25 -0
- package/src/domain/memory-agent/validate.ts +67 -0
- package/src/domain/names/constants.ts +32 -0
- package/src/domain/names/index.ts +2 -0
- package/src/domain/names/names.ts +83 -0
- package/src/domain/note/check.ts +68 -0
- package/src/domain/note/constants.ts +15 -0
- package/src/domain/note/frontmatter-fields.ts +175 -0
- package/src/domain/note/frontmatter.ts +138 -0
- package/src/domain/note/index.ts +9 -0
- package/src/domain/note/parse.ts +41 -0
- package/src/domain/note/render.ts +27 -0
- package/src/domain/note/schema-errors.ts +41 -0
- package/src/domain/note/schemas.ts +38 -0
- package/src/domain/note/types.ts +53 -0
- package/src/domain/note/validate.ts +19 -0
- package/src/domain/path-platform/index.ts +2 -0
- package/src/domain/path-platform/path-module.ts +11 -0
- package/src/domain/path-platform/types.ts +1 -0
- package/src/domain/search-catalog/constants.ts +1 -0
- package/src/domain/search-catalog/coverage.ts +35 -0
- package/src/domain/search-catalog/dont-forget.ts +10 -0
- package/src/domain/search-catalog/fingerprint.ts +9 -0
- package/src/domain/search-catalog/index.ts +10 -0
- package/src/domain/search-catalog/inspection.ts +47 -0
- package/src/domain/search-catalog/plan.ts +68 -0
- package/src/domain/search-catalog/ranking.ts +27 -0
- package/src/domain/search-catalog/schemas.ts +49 -0
- package/src/domain/search-catalog/types.ts +103 -0
- package/src/domain/search-catalog/vector-refresh.ts +22 -0
- package/src/domain/shell-edit/command-segments.ts +28 -0
- package/src/domain/shell-edit/command-words.ts +22 -0
- package/src/domain/shell-edit/constants.ts +125 -0
- package/src/domain/shell-edit/executed-files.ts +154 -0
- package/src/domain/shell-edit/index.ts +6 -0
- package/src/domain/shell-edit/powershell-files.ts +38 -0
- package/src/domain/shell-edit/rules.ts +19 -0
- package/src/domain/shell-edit/types.ts +75 -0
- package/src/domain/tool-flags/constants.ts +178 -0
- package/src/domain/tool-flags/index.ts +2 -0
- package/src/domain/tool-flags/types.ts +7 -0
- package/src/domain/validation/constants.ts +1 -0
- package/src/domain/validation/describe.ts +137 -0
- package/src/domain/validation/index.ts +3 -0
- package/src/domain/validation/types.ts +3 -0
- package/src/domain/vault-access/absolute-candidate.ts +81 -0
- package/src/domain/vault-access/argument-tokens.ts +22 -0
- package/src/domain/vault-access/command-mentions-vault.ts +115 -0
- package/src/domain/vault-access/constants.ts +54 -0
- package/src/domain/vault-access/index.ts +7 -0
- package/src/domain/vault-access/types.ts +18 -0
- package/src/domain/vault-access/vault-access-refusal.ts +36 -0
- package/src/domain/vault-access/vault-location.ts +22 -0
- package/src/domain/vault-assets/index.ts +2 -0
- package/src/domain/vault-assets/render.ts +51 -0
- package/src/domain/vault-assets/types.ts +36 -0
- package/src/domain/vault-catalog/analyze.ts +37 -0
- package/src/domain/vault-catalog/classify.ts +37 -0
- package/src/domain/vault-catalog/dont-forget.ts +6 -0
- package/src/domain/vault-catalog/export-entries.ts +10 -0
- package/src/domain/vault-catalog/index.ts +5 -0
- package/src/domain/vault-catalog/types.ts +114 -0
- package/src/domain/vault-diagnosis/diagnose.ts +79 -0
- package/src/domain/vault-diagnosis/index.ts +2 -0
- package/src/domain/vault-diagnosis/types.ts +31 -0
- package/src/domain/vault-path/constants.ts +13 -0
- package/src/domain/vault-path/index.ts +2 -0
- package/src/domain/vault-path/vault-path.ts +65 -0
- package/src/pi/capture/cadence.ts +49 -0
- package/src/pi/capture/completion.ts +26 -0
- package/src/pi/capture/constants.ts +5 -0
- package/src/pi/capture/handlers.ts +30 -0
- package/src/pi/capture/index.ts +8 -0
- package/src/pi/capture/runtime.ts +83 -0
- package/src/pi/capture/schemas.ts +8 -0
- package/src/pi/capture/tool-calls.ts +6 -0
- package/src/pi/capture/transcript.ts +55 -0
- package/src/pi/capture/types.ts +46 -0
- package/src/pi/change-report/constants.ts +15 -0
- package/src/pi/change-report/index.ts +3 -0
- package/src/pi/change-report/report.ts +54 -0
- package/src/pi/change-report/types.ts +8 -0
- package/src/pi/context/constants.ts +5 -0
- package/src/pi/context/index.ts +3 -0
- package/src/pi/context/status.ts +15 -0
- package/src/pi/context/types.ts +98 -0
- package/src/pi/extension.ts +100 -0
- package/src/pi/index.ts +26 -0
- package/src/pi/memory-add/constants.ts +13 -0
- package/src/pi/memory-add/index.ts +5 -0
- package/src/pi/memory-add/memory-add.ts +31 -0
- package/src/pi/memory-add/respond.ts +55 -0
- package/src/pi/memory-add/schemas.ts +29 -0
- package/src/pi/memory-add/types.ts +15 -0
- package/src/pi/memory-archive/constants.ts +8 -0
- package/src/pi/memory-archive/index.ts +4 -0
- package/src/pi/memory-archive/memory-archive.ts +29 -0
- package/src/pi/memory-archive/schemas.ts +15 -0
- package/src/pi/memory-archive/types.ts +8 -0
- package/src/pi/memory-block/block.ts +75 -0
- package/src/pi/memory-block/constants.ts +24 -0
- package/src/pi/memory-block/index.ts +4 -0
- package/src/pi/memory-block/render.ts +54 -0
- package/src/pi/memory-block/types.ts +24 -0
- package/src/pi/memory-doctor/constants.ts +43 -0
- package/src/pi/memory-doctor/index.ts +4 -0
- package/src/pi/memory-doctor/memory-doctor.ts +135 -0
- package/src/pi/memory-doctor/report.ts +101 -0
- package/src/pi/memory-doctor/types.ts +13 -0
- package/src/pi/memory-export/constants.ts +15 -0
- package/src/pi/memory-export/index.ts +4 -0
- package/src/pi/memory-export/memory-export.ts +57 -0
- package/src/pi/memory-export/name.ts +9 -0
- package/src/pi/memory-export/types.ts +4 -0
- package/src/pi/memory-get/constants.ts +12 -0
- package/src/pi/memory-get/index.ts +5 -0
- package/src/pi/memory-get/memory-get.ts +23 -0
- package/src/pi/memory-get/respond.ts +38 -0
- package/src/pi/memory-get/schemas.ts +13 -0
- package/src/pi/memory-get/types.ts +10 -0
- package/src/pi/memory-init/constants.ts +17 -0
- package/src/pi/memory-init/index.ts +2 -0
- package/src/pi/memory-init/memory-init.ts +63 -0
- package/src/pi/memory-search/constants.ts +16 -0
- package/src/pi/memory-search/index.ts +5 -0
- package/src/pi/memory-search/memory-search.ts +22 -0
- package/src/pi/memory-search/respond.ts +62 -0
- package/src/pi/memory-search/schemas.ts +11 -0
- package/src/pi/memory-search/types.ts +10 -0
- package/src/pi/memory-session/constants.ts +7 -0
- package/src/pi/memory-session/index.ts +4 -0
- package/src/pi/memory-session/keeper.ts +101 -0
- package/src/pi/memory-session/respond.ts +6 -0
- package/src/pi/memory-session/types.ts +23 -0
- package/src/pi/memory-settings/constants.ts +69 -0
- package/src/pi/memory-settings/edits.ts +46 -0
- package/src/pi/memory-settings/index.ts +9 -0
- package/src/pi/memory-settings/lines.ts +119 -0
- package/src/pi/memory-settings/models.ts +81 -0
- package/src/pi/memory-settings/projects.ts +46 -0
- package/src/pi/memory-settings/providers.ts +77 -0
- package/src/pi/memory-settings/save.ts +16 -0
- package/src/pi/memory-settings/screen.ts +27 -0
- package/src/pi/memory-settings/types.ts +87 -0
- package/src/pi/memory-setup/constants.ts +33 -0
- package/src/pi/memory-setup/disclosure.ts +22 -0
- package/src/pi/memory-setup/index.ts +4 -0
- package/src/pi/memory-setup/memory-setup.ts +153 -0
- package/src/pi/memory-setup/types.ts +6 -0
- package/src/pi/memory-succeed/constants.ts +10 -0
- package/src/pi/memory-succeed/index.ts +4 -0
- package/src/pi/memory-succeed/memory-succeed.ts +34 -0
- package/src/pi/memory-succeed/schemas.ts +30 -0
- package/src/pi/memory-succeed/types.ts +8 -0
- package/src/pi/memory-update/constants.ts +8 -0
- package/src/pi/memory-update/index.ts +4 -0
- package/src/pi/memory-update/memory-update.ts +29 -0
- package/src/pi/memory-update/schemas.ts +24 -0
- package/src/pi/memory-update/types.ts +8 -0
- package/src/pi/paths/constants.ts +7 -0
- package/src/pi/paths/index.ts +2 -0
- package/src/pi/paths/paths.ts +15 -0
- package/src/pi/paths/platform.ts +7 -0
- package/src/pi/registrar.ts +25 -0
- package/src/pi/registration-report/constants.ts +13 -0
- package/src/pi/registration-report/index.ts +2 -0
- package/src/pi/registration-report/report.ts +26 -0
- package/src/pi/relevant-memory/constants.ts +3 -0
- package/src/pi/relevant-memory/index.ts +4 -0
- package/src/pi/relevant-memory/prompt.ts +23 -0
- package/src/pi/relevant-memory/runtime.ts +88 -0
- package/src/pi/relevant-memory/types.ts +14 -0
- package/src/pi/semantic/constants.ts +3 -0
- package/src/pi/semantic/index.ts +2 -0
- package/src/pi/semantic/runtime.ts +59 -0
- package/src/pi/session-start/constants.ts +7 -0
- package/src/pi/session-start/index.ts +3 -0
- package/src/pi/session-start/session-start.ts +48 -0
- package/src/pi/session-start/types.ts +5 -0
- package/src/pi/shell-edit-guard/guard.ts +41 -0
- package/src/pi/shell-edit-guard/index.ts +3 -0
- package/src/pi/shell-edit-guard/prompt.ts +30 -0
- package/src/pi/shell-edit-guard/types.ts +13 -0
- package/src/pi/types.ts +44 -0
- package/src/pi/vault-guard/constants.ts +1 -0
- package/src/pi/vault-guard/index.ts +4 -0
- package/src/pi/vault-guard/request.ts +39 -0
- package/src/pi/vault-guard/types.ts +5 -0
- package/src/pi/vault-guard/vault-guard.ts +21 -0
- package/src/services/capture-cadence/domain-rules.ts +8 -0
- package/src/services/capture-cadence/index.ts +1 -0
- package/src/services/clock/clock.ts +7 -0
- package/src/services/clock/index.ts +1 -0
- package/src/services/config/canonicalize.ts +163 -0
- package/src/services/config/constants.ts +1 -0
- package/src/services/config/fully-qualified-path.ts +14 -0
- package/src/services/config/index.ts +12 -0
- package/src/services/config/path-identity.ts +65 -0
- package/src/services/config/publication.ts +75 -0
- package/src/services/config/read.ts +47 -0
- package/src/services/config/registration.ts +26 -0
- package/src/services/config/resolve-input.ts +27 -0
- package/src/services/config/snapshot.ts +26 -0
- package/src/services/config/target.ts +2 -0
- package/src/services/config/types.ts +97 -0
- package/src/services/config/vault-access.ts +2 -0
- package/src/services/config/volume-namespace.ts +5 -0
- package/src/services/config/write.ts +63 -0
- package/src/services/decision-model/constants.ts +16 -0
- package/src/services/decision-model/decide.ts +42 -0
- package/src/services/decision-model/diagnostics.ts +6 -0
- package/src/services/decision-model/endpoint.ts +1 -0
- package/src/services/decision-model/failure-detail.ts +1 -0
- package/src/services/decision-model/index.ts +7 -0
- package/src/services/decision-model/interruption.ts +29 -0
- package/src/services/decision-model/jev.ts +61 -0
- package/src/services/decision-model/laya-batch.ts +64 -0
- package/src/services/decision-model/laya-http-failure.ts +41 -0
- package/src/services/decision-model/laya-response.ts +95 -0
- package/src/services/decision-model/laya.ts +35 -0
- package/src/services/decision-model/preflight.ts +24 -0
- package/src/services/decision-model/prompts.ts +36 -0
- package/src/services/decision-model/schemas.ts +43 -0
- package/src/services/decision-model/score-candidates.ts +41 -0
- package/src/services/decision-model/types.ts +182 -0
- package/src/services/embeddings/asset-download.ts +45 -0
- package/src/services/embeddings/asset-fetch.ts +39 -0
- package/src/services/embeddings/asset-inspection.ts +36 -0
- package/src/services/embeddings/batch.ts +32 -0
- package/src/services/embeddings/chunks.ts +80 -0
- package/src/services/embeddings/configuration.ts +8 -0
- package/src/services/embeddings/constants.ts +24 -0
- package/src/services/embeddings/errors.ts +11 -0
- package/src/services/embeddings/google.ts +90 -0
- package/src/services/embeddings/http.ts +64 -0
- package/src/services/embeddings/index.ts +17 -0
- package/src/services/embeddings/inference.ts +35 -0
- package/src/services/embeddings/local.ts +138 -0
- package/src/services/embeddings/model-asset.ts +68 -0
- package/src/services/embeddings/model-cache.ts +30 -0
- package/src/services/embeddings/openai.ts +64 -0
- package/src/services/embeddings/operation.ts +31 -0
- package/src/services/embeddings/responses.ts +41 -0
- package/src/services/embeddings/runtime.ts +13 -0
- package/src/services/embeddings/schemas.ts +53 -0
- package/src/services/embeddings/types.ts +116 -0
- package/src/services/id/id.ts +5 -0
- package/src/services/id/index.ts +1 -0
- package/src/services/index.ts +11 -0
- package/src/services/llm/capture.ts +19 -0
- package/src/services/llm/check-chat-models.ts +38 -0
- package/src/services/llm/complete.ts +57 -0
- package/src/services/llm/constants.ts +32 -0
- package/src/services/llm/domain-rules.ts +2 -0
- package/src/services/llm/index.ts +6 -0
- package/src/services/llm/lifetime.ts +16 -0
- package/src/services/llm/retrieve.ts +19 -0
- package/src/services/llm/schemas.ts +9 -0
- package/src/services/llm/types.ts +94 -0
- package/src/services/search-index/catalog-query.ts +34 -0
- package/src/services/search-index/catalog-statements.ts +33 -0
- package/src/services/search-index/catalog.ts +19 -0
- package/src/services/search-index/cleanup.ts +13 -0
- package/src/services/search-index/close.ts +5 -0
- package/src/services/search-index/constants.ts +102 -0
- package/src/services/search-index/dont-forget.ts +1 -0
- package/src/services/search-index/fingerprint.ts +17 -0
- package/src/services/search-index/folder-index-statements.ts +17 -0
- package/src/services/search-index/folder-index-storage.ts +54 -0
- package/src/services/search-index/folder-indexes.ts +13 -0
- package/src/services/search-index/index.ts +14 -0
- package/src/services/search-index/inspection.ts +1 -0
- package/src/services/search-index/inventory.ts +67 -0
- package/src/services/search-index/legacy.ts +64 -0
- package/src/services/search-index/location.ts +12 -0
- package/src/services/search-index/open.ts +46 -0
- package/src/services/search-index/query.ts +39 -0
- package/src/services/search-index/ranking.ts +12 -0
- package/src/services/search-index/reconcile.ts +93 -0
- package/src/services/search-index/recovery.ts +56 -0
- package/src/services/search-index/refusals.ts +21 -0
- package/src/services/search-index/schema.ts +42 -0
- package/src/services/search-index/schemas.ts +181 -0
- package/src/services/search-index/search.ts +5 -0
- package/src/services/search-index/statements.ts +18 -0
- package/src/services/search-index/storage.ts +207 -0
- package/src/services/search-index/types.ts +113 -0
- package/src/services/search-index/vector-statements.ts +18 -0
- package/src/services/search-index/vector-storage.ts +169 -0
- package/src/services/search-index/vectors.ts +18 -0
- package/src/services/search-index/write.ts +9 -0
- package/src/services/shell-edit/ask.ts +53 -0
- package/src/services/shell-edit/domain-rules.ts +2 -0
- package/src/services/shell-edit/index.ts +4 -0
- package/src/services/shell-edit/schemas.ts +23 -0
- package/src/services/shell-edit/types.ts +61 -0
- package/src/services/shell-scripts/constants.ts +1 -0
- package/src/services/shell-scripts/files.ts +16 -0
- package/src/services/shell-scripts/index.ts +5 -0
- package/src/services/shell-scripts/package-scripts.ts +74 -0
- package/src/services/shell-scripts/schemas.ts +3 -0
- package/src/services/shell-scripts/scripts.ts +27 -0
- package/src/services/shell-scripts/types.ts +11 -0
- package/src/services/vault/archive.ts +31 -0
- package/src/services/vault/bootstrap/ensure.ts +50 -0
- package/src/services/vault/bootstrap/index.ts +2 -0
- package/src/services/vault/bootstrap/paths.ts +57 -0
- package/src/services/vault/bootstrap/types.ts +17 -0
- package/src/services/vault/bootstrap/write.ts +47 -0
- package/src/services/vault/catalog/bytes.ts +51 -0
- package/src/services/vault/catalog/dont-forget.ts +1 -0
- package/src/services/vault/catalog/enumerate.ts +69 -0
- package/src/services/vault/catalog/export.ts +21 -0
- package/src/services/vault/catalog/failures.ts +16 -0
- package/src/services/vault/catalog/index.ts +10 -0
- package/src/services/vault/catalog/inspect.ts +41 -0
- package/src/services/vault/catalog/observe.ts +35 -0
- package/src/services/vault/catalog/resolve.ts +94 -0
- package/src/services/vault/catalog/stat.ts +23 -0
- package/src/services/vault/catalog/types.ts +69 -0
- package/src/services/vault/catalog/visit.ts +58 -0
- package/src/services/vault/complete-blank.ts +66 -0
- package/src/services/vault/constants.ts +3 -0
- package/src/services/vault/context/index.ts +1 -0
- package/src/services/vault/context/types.ts +10 -0
- package/src/services/vault/create.ts +19 -0
- package/src/services/vault/display.ts +6 -0
- package/src/services/vault/domain-rules.ts +10 -0
- package/src/services/vault/draft.ts +2 -0
- package/src/services/vault/filesystem/failures.ts +53 -0
- package/src/services/vault/filesystem/hash.ts +5 -0
- package/src/services/vault/filesystem/index.ts +5 -0
- package/src/services/vault/filesystem/read.ts +61 -0
- package/src/services/vault/filesystem/types.ts +36 -0
- package/src/services/vault/filesystem/write.ts +80 -0
- package/src/services/vault/find.ts +27 -0
- package/src/services/vault/folder-contents.ts +31 -0
- package/src/services/vault/folder-index/index.ts +2 -0
- package/src/services/vault/folder-index/read.ts +87 -0
- package/src/services/vault/folder-index/types.ts +19 -0
- package/src/services/vault/folder-listing.ts +1 -0
- package/src/services/vault/index.ts +21 -0
- package/src/services/vault/inspect-folder.ts +13 -0
- package/src/services/vault/list.ts +121 -0
- package/src/services/vault/memory-folder.ts +24 -0
- package/src/services/vault/paths.ts +11 -0
- package/src/services/vault/publish.ts +52 -0
- package/src/services/vault/read.ts +46 -0
- package/src/services/vault/refresh-folders.ts +197 -0
- package/src/services/vault/refresh-plan.ts +79 -0
- package/src/services/vault/refresh.ts +8 -0
- package/src/services/vault/refusals.ts +23 -0
- package/src/services/vault/relocate.ts +131 -0
- package/src/services/vault/relocation-checks.ts +89 -0
- package/src/services/vault/resolve-stored-file.ts +43 -0
- package/src/services/vault/resolve.ts +109 -0
- package/src/services/vault/succeed.ts +45 -0
- package/src/services/vault/types.ts +199 -0
- package/src/services/vault/update-file.ts +58 -0
- package/src/services/vault/update.ts +22 -0
- package/src/services/vault/write-new-file.ts +37 -0
- package/src/shared/index.ts +1 -0
- package/src/shared/result/index.ts +1 -0
- package/src/shared/result/types.ts +17 -0
- package/src/usecases/add-memory/add-memory.ts +83 -0
- package/src/usecases/add-memory/index.ts +4 -0
- package/src/usecases/add-memory/maintenance.ts +23 -0
- package/src/usecases/add-memory/schemas.ts +12 -0
- package/src/usecases/add-memory/types.ts +47 -0
- package/src/usecases/archive-memory/archive-memory.ts +27 -0
- package/src/usecases/archive-memory/index.ts +3 -0
- package/src/usecases/archive-memory/schemas.ts +11 -0
- package/src/usecases/archive-memory/types.ts +17 -0
- package/src/usecases/capture-memory/apply.ts +73 -0
- package/src/usecases/capture-memory/capture-memory.ts +117 -0
- package/src/usecases/capture-memory/constants.ts +15 -0
- package/src/usecases/capture-memory/index.ts +5 -0
- package/src/usecases/capture-memory/observe.ts +122 -0
- package/src/usecases/capture-memory/settings.ts +20 -0
- package/src/usecases/capture-memory/types.ts +103 -0
- package/src/usecases/check-shell-edit/check-shell-edit.ts +28 -0
- package/src/usecases/check-shell-edit/index.ts +2 -0
- package/src/usecases/check-shell-edit/types.ts +30 -0
- package/src/usecases/check-vault-access/check-vault-access.ts +23 -0
- package/src/usecases/check-vault-access/constants.ts +7 -0
- package/src/usecases/check-vault-access/index.ts +4 -0
- package/src/usecases/check-vault-access/raw-device.ts +10 -0
- package/src/usecases/check-vault-access/targets.ts +49 -0
- package/src/usecases/check-vault-access/types.ts +33 -0
- package/src/usecases/complete-blank-memory/complete-blank-memory.ts +48 -0
- package/src/usecases/complete-blank-memory/constants.ts +3 -0
- package/src/usecases/complete-blank-memory/index.ts +4 -0
- package/src/usecases/complete-blank-memory/schemas.ts +14 -0
- package/src/usecases/complete-blank-memory/types.ts +28 -0
- package/src/usecases/diagnose-memory/constants.ts +3 -0
- package/src/usecases/diagnose-memory/decision.ts +36 -0
- package/src/usecases/diagnose-memory/diagnose-memory.ts +52 -0
- package/src/usecases/diagnose-memory/embeddings.ts +39 -0
- package/src/usecases/diagnose-memory/index.ts +5 -0
- package/src/usecases/diagnose-memory/types.ts +86 -0
- package/src/usecases/diagnose-memory/vault.ts +33 -0
- package/src/usecases/export-memory/collect.ts +20 -0
- package/src/usecases/export-memory/constants.ts +3 -0
- package/src/usecases/export-memory/export-memory.ts +84 -0
- package/src/usecases/export-memory/index.ts +3 -0
- package/src/usecases/export-memory/types.ts +28 -0
- package/src/usecases/get-memory/get-memory.ts +97 -0
- package/src/usecases/get-memory/index.ts +2 -0
- package/src/usecases/get-memory/types.ts +25 -0
- package/src/usecases/index.ts +25 -0
- package/src/usecases/list-memory/index.ts +2 -0
- package/src/usecases/list-memory/leased/index.ts +2 -0
- package/src/usecases/list-memory/leased/read.ts +16 -0
- package/src/usecases/list-memory/leased/types.ts +21 -0
- package/src/usecases/list-memory/list-memory.ts +33 -0
- package/src/usecases/list-memory/types.ts +8 -0
- package/src/usecases/load-dont-forget/index.ts +2 -0
- package/src/usecases/load-dont-forget/load-dont-forget.ts +111 -0
- package/src/usecases/load-dont-forget/types.ts +26 -0
- package/src/usecases/memory-change/change.ts +42 -0
- package/src/usecases/memory-change/index.ts +5 -0
- package/src/usecases/memory-change/maintenance.ts +11 -0
- package/src/usecases/memory-change/partial.ts +18 -0
- package/src/usecases/memory-change/receipt.ts +40 -0
- package/src/usecases/memory-change/types.ts +44 -0
- package/src/usecases/operation-context/context.ts +37 -0
- package/src/usecases/operation-context/index.ts +2 -0
- package/src/usecases/operation-context/types.ts +19 -0
- package/src/usecases/registration/check.ts +6 -0
- package/src/usecases/registration/entry.ts +33 -0
- package/src/usecases/registration/index.ts +8 -0
- package/src/usecases/registration/init.ts +94 -0
- package/src/usecases/registration/prepare-init.ts +43 -0
- package/src/usecases/registration/prepare.ts +35 -0
- package/src/usecases/registration/propose.ts +34 -0
- package/src/usecases/registration/publication.ts +90 -0
- package/src/usecases/registration/setup.ts +41 -0
- package/src/usecases/registration/types.ts +107 -0
- package/src/usecases/relevant-memory/agent.ts +55 -0
- package/src/usecases/relevant-memory/constants.ts +28 -0
- package/src/usecases/relevant-memory/cutoffs.ts +29 -0
- package/src/usecases/relevant-memory/decision.ts +102 -0
- package/src/usecases/relevant-memory/index.ts +11 -0
- package/src/usecases/relevant-memory/loaded.ts +31 -0
- package/src/usecases/relevant-memory/refresh.ts +30 -0
- package/src/usecases/relevant-memory/retrieve-memory.ts +62 -0
- package/src/usecases/relevant-memory/schemas.ts +20 -0
- package/src/usecases/relevant-memory/session-memory.ts +53 -0
- package/src/usecases/relevant-memory/track-dont-forget.ts +13 -0
- package/src/usecases/relevant-memory/types.ts +106 -0
- package/src/usecases/resolve-memory/index.ts +2 -0
- package/src/usecases/resolve-memory/leased/index.ts +2 -0
- package/src/usecases/resolve-memory/leased/resolve.ts +109 -0
- package/src/usecases/resolve-memory/leased/types.ts +35 -0
- package/src/usecases/resolve-memory/resolve-memory.ts +23 -0
- package/src/usecases/resolve-memory/types.ts +7 -0
- package/src/usecases/search-memory/constants.ts +1 -0
- package/src/usecases/search-memory/index.ts +3 -0
- package/src/usecases/search-memory/search-memory.ts +132 -0
- package/src/usecases/search-memory/types.ts +39 -0
- package/src/usecases/semantic/constants.ts +7 -0
- package/src/usecases/semantic/index.ts +5 -0
- package/src/usecases/semantic/prepare.ts +30 -0
- package/src/usecases/semantic/rank.ts +83 -0
- package/src/usecases/semantic/refresh-vectors.ts +95 -0
- package/src/usecases/semantic/types.ts +17 -0
- package/src/usecases/semantic-port/index.ts +1 -0
- package/src/usecases/semantic-port/types.ts +20 -0
- package/src/usecases/semantic-provider/constants.ts +6 -0
- package/src/usecases/semantic-provider/index.ts +5 -0
- package/src/usecases/semantic-provider/local.ts +33 -0
- package/src/usecases/semantic-provider/remote.ts +10 -0
- package/src/usecases/semantic-provider/size.ts +10 -0
- package/src/usecases/semantic-provider/types.ts +19 -0
- package/src/usecases/session/index.ts +2 -0
- package/src/usecases/session/lease.ts +70 -0
- package/src/usecases/session/receipts.ts +46 -0
- package/src/usecases/session/state.ts +106 -0
- package/src/usecases/session/types.ts +45 -0
- package/src/usecases/settings/change.ts +142 -0
- package/src/usecases/settings/index.ts +3 -0
- package/src/usecases/settings/prepare.ts +24 -0
- package/src/usecases/settings/types.ts +32 -0
- package/src/usecases/succeed-memory/index.ts +3 -0
- package/src/usecases/succeed-memory/schemas.ts +13 -0
- package/src/usecases/succeed-memory/succeed-memory.ts +34 -0
- package/src/usecases/succeed-memory/types.ts +18 -0
- package/src/usecases/synchronize-memory/index.ts +2 -0
- package/src/usecases/synchronize-memory/leased/aliases.ts +55 -0
- package/src/usecases/synchronize-memory/leased/folder-states.ts +58 -0
- package/src/usecases/synchronize-memory/leased/index.ts +2 -0
- package/src/usecases/synchronize-memory/leased/inspection.ts +32 -0
- package/src/usecases/synchronize-memory/leased/maintenance.ts +41 -0
- package/src/usecases/synchronize-memory/leased/publication.ts +55 -0
- package/src/usecases/synchronize-memory/leased/scan.ts +37 -0
- package/src/usecases/synchronize-memory/leased/synchronize.ts +102 -0
- package/src/usecases/synchronize-memory/leased/types.ts +60 -0
- package/src/usecases/synchronize-memory/synchronize-memory.ts +26 -0
- package/src/usecases/synchronize-memory/types.ts +5 -0
- package/src/usecases/update-memory/index.ts +3 -0
- package/src/usecases/update-memory/schemas.ts +14 -0
- package/src/usecases/update-memory/types.ts +16 -0
- package/src/usecases/update-memory/update-memory.ts +31 -0
- package/CHANGELOG.md +0 -6
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { isAbsolute, join, relative, sep } from "node:path"
|
|
2
|
+
|
|
3
|
+
import { checkFileName, checkVaultPath, joinVaultPath, VAULT_PATH_SEPARATOR } from "#src/domain"
|
|
4
|
+
import { linkStatOf, realPathOf } from "#src/services/vault/filesystem"
|
|
5
|
+
import type { ResolveResult } from "./types.ts"
|
|
6
|
+
|
|
7
|
+
export async function resolveFolder(vault: string, folder: string): Promise<ResolveResult> {
|
|
8
|
+
return resolveParts(vault, checkVaultPath(folder), partsOf(folder), "directory")
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function resolveFile(vault: string, folder: string, fileName: string): Promise<ResolveResult> {
|
|
12
|
+
const problems = [...checkVaultPath(folder), ...checkFileName(fileName)]
|
|
13
|
+
return resolveParts(vault, problems, [...partsOf(folder), fileName], "file")
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function resolveParts(
|
|
17
|
+
vault: string,
|
|
18
|
+
problems: string[],
|
|
19
|
+
parts: string[],
|
|
20
|
+
kind: "directory" | "file",
|
|
21
|
+
): Promise<ResolveResult> {
|
|
22
|
+
if (problems.length > 0) {
|
|
23
|
+
return { succeeded: false, reason: "invalid", problems }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const root = await resolveRoot(vault)
|
|
27
|
+
if (!root.succeeded) {
|
|
28
|
+
return root
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let current = root.output
|
|
32
|
+
for (const [depth, part] of parts.entries()) {
|
|
33
|
+
const path = join(current, part)
|
|
34
|
+
const target = await resolveEntry(root.output, path, joinVaultPath(...parts.slice(0, depth + 1)))
|
|
35
|
+
if (!target.succeeded) {
|
|
36
|
+
return target
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const stat = await linkStatOf(target.output)
|
|
40
|
+
if (!stat.succeeded) {
|
|
41
|
+
if (stat.reason === "not-found") {
|
|
42
|
+
return { succeeded: true, output: join(target.output, ...parts.slice(depth + 1)) }
|
|
43
|
+
}
|
|
44
|
+
return stat
|
|
45
|
+
}
|
|
46
|
+
if ((depth < parts.length - 1 || kind === "directory") && !stat.output.isDirectory()) {
|
|
47
|
+
return { succeeded: false, reason: "not-directory", problems: [`${path} is not a directory`] }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
current = target.output
|
|
51
|
+
}
|
|
52
|
+
return { succeeded: true, output: current }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function resolveRoot(vault: string): Promise<ResolveResult> {
|
|
56
|
+
const root = await realPathOf(vault)
|
|
57
|
+
if (!root.succeeded) {
|
|
58
|
+
if (root.reason === "not-found") {
|
|
59
|
+
return { succeeded: false, reason: "vault-missing", problems: [`the vault folder ${vault} does not exist`] }
|
|
60
|
+
}
|
|
61
|
+
return root
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const stat = await linkStatOf(root.output)
|
|
65
|
+
if (!stat.succeeded) {
|
|
66
|
+
if (stat.reason === "not-found") {
|
|
67
|
+
return { succeeded: false, reason: "vault-missing", problems: stat.problems }
|
|
68
|
+
}
|
|
69
|
+
return stat
|
|
70
|
+
}
|
|
71
|
+
if (!stat.output.isDirectory()) {
|
|
72
|
+
return { succeeded: false, reason: "not-directory", problems: [`the vault ${vault} is not a directory`] }
|
|
73
|
+
}
|
|
74
|
+
return root
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function resolveEntry(root: string, path: string, displayPath: string): Promise<ResolveResult> {
|
|
78
|
+
const stat = await linkStatOf(path)
|
|
79
|
+
if (!stat.succeeded) {
|
|
80
|
+
if (stat.reason === "not-found") {
|
|
81
|
+
return { succeeded: true, output: path }
|
|
82
|
+
}
|
|
83
|
+
return stat
|
|
84
|
+
}
|
|
85
|
+
if (!stat.output.isSymbolicLink()) {
|
|
86
|
+
return { succeeded: true, output: path }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const target = await realPathOf(path)
|
|
90
|
+
if (!target.succeeded) {
|
|
91
|
+
if (target.reason === "not-found" || target.code === "ELOOP") {
|
|
92
|
+
return { succeeded: false, reason: "outside-vault", problems: [`${displayPath} is a link that does not resolve`] }
|
|
93
|
+
}
|
|
94
|
+
return target
|
|
95
|
+
}
|
|
96
|
+
if (!isInside(root, target.output)) {
|
|
97
|
+
return { succeeded: false, reason: "outside-vault", problems: [`${displayPath} leads outside the vault`] }
|
|
98
|
+
}
|
|
99
|
+
return target
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function isInside(root: string, path: string): boolean {
|
|
103
|
+
const fromRoot = relative(root, path)
|
|
104
|
+
return !isAbsolute(fromRoot) && fromRoot !== ".." && !fromRoot.startsWith(`..${sep}`)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function partsOf(folder: string): string[] {
|
|
108
|
+
return folder.split(VAULT_PATH_SEPARATOR).filter((part) => part.length > 0)
|
|
109
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { checkMemoryFolder, succeedNote } from "#src/domain"
|
|
2
|
+
import type { NamedVaultContext } from "#src/services/vault/context"
|
|
3
|
+
import { resolveMemoryFolder } from "./memory-folder.ts"
|
|
4
|
+
import { relocateNote } from "./relocate.ts"
|
|
5
|
+
import type { ExactSucceedRequest, SucceedRequest, SuccessionResult } from "./types.ts"
|
|
6
|
+
|
|
7
|
+
export async function succeedStoredNote(vault: NamedVaultContext, request: SucceedRequest): Promise<SuccessionResult> {
|
|
8
|
+
return succeedOriginal(vault, request, null)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function succeedStoredFile(
|
|
12
|
+
vault: NamedVaultContext,
|
|
13
|
+
request: ExactSucceedRequest,
|
|
14
|
+
): Promise<SuccessionResult> {
|
|
15
|
+
return succeedOriginal(vault, request, request.path)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function succeedOriginal(
|
|
19
|
+
vault: NamedVaultContext,
|
|
20
|
+
request: SucceedRequest,
|
|
21
|
+
originalPath: string | null,
|
|
22
|
+
): Promise<SuccessionResult> {
|
|
23
|
+
const problems = checkMemoryFolder(request.successor.folder)
|
|
24
|
+
if (problems.length > 0) {
|
|
25
|
+
return { succeeded: false, reason: "invalid", problems }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const destination = await resolveMemoryFolder(vault.path, request.successor.folder)
|
|
29
|
+
if (!destination.succeeded) {
|
|
30
|
+
return destination
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const succession = succeedNote(request.previous, request.successor, request.today)
|
|
34
|
+
const relocated = await relocateNote(vault, {
|
|
35
|
+
original: request.previous,
|
|
36
|
+
originalPath,
|
|
37
|
+
hashWhenRead: request.hashWhenRead,
|
|
38
|
+
written: [succession.archived, succession.successor],
|
|
39
|
+
})
|
|
40
|
+
if (!relocated.succeeded) {
|
|
41
|
+
return relocated
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return { ...relocated, output: succession }
|
|
45
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
InvalidNote,
|
|
3
|
+
Note,
|
|
4
|
+
ParsedNote,
|
|
5
|
+
PlacedNote,
|
|
6
|
+
ProblemFolder,
|
|
7
|
+
Succession,
|
|
8
|
+
VaultCatalogFailure,
|
|
9
|
+
VaultFileStat,
|
|
10
|
+
} from "#src/domain"
|
|
11
|
+
import type { Done, Failed, Succeeded } from "#src/shared"
|
|
12
|
+
|
|
13
|
+
export interface ExactUpdateRequest {
|
|
14
|
+
path: string
|
|
15
|
+
note: Note
|
|
16
|
+
expectedHash: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface StoredFilePath {
|
|
20
|
+
folder: string
|
|
21
|
+
fileName: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface UpdateFileRequest {
|
|
25
|
+
folder: string
|
|
26
|
+
fileName: string
|
|
27
|
+
note: Note
|
|
28
|
+
expectedHash: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface CompleteBlankRequest {
|
|
32
|
+
path: string
|
|
33
|
+
expectedHash: string
|
|
34
|
+
note: Note
|
|
35
|
+
confirmed: true
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface BlankCompletionRefusal extends Failed {
|
|
39
|
+
reason: "not-blank" | "path-mismatch"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type CompleteBlankResult = UpdateResult | BlankCompletionRefusal | VaultCatalogFailure
|
|
43
|
+
|
|
44
|
+
export interface StoredNote {
|
|
45
|
+
note: Note
|
|
46
|
+
hash: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface MaintenanceWarnings {
|
|
50
|
+
maintenanceProblems?: string[]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface FolderListing {
|
|
54
|
+
subjects: string[]
|
|
55
|
+
notes: Note[]
|
|
56
|
+
invalid: InvalidNote[]
|
|
57
|
+
problemFolders?: ProblemFolder[]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ArchiveRequest {
|
|
61
|
+
note: PlacedNote
|
|
62
|
+
hashWhenRead: string
|
|
63
|
+
today: string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ExactArchiveRequest extends ArchiveRequest {
|
|
67
|
+
path: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface SucceedRequest {
|
|
71
|
+
previous: PlacedNote
|
|
72
|
+
hashWhenRead: string
|
|
73
|
+
successor: PlacedNote
|
|
74
|
+
today: string
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface ExactSucceedRequest extends SucceedRequest {
|
|
78
|
+
path: string
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface FileRelocationRequest extends RelocationRequest {
|
|
82
|
+
originalPath: string | null
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface RelocationRequest {
|
|
86
|
+
original: PlacedNote
|
|
87
|
+
hashWhenRead: string
|
|
88
|
+
written: [PlacedNote, ...PlacedNote[]]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface ResolveRefusal extends Failed {
|
|
92
|
+
reason: "invalid" | "outside-vault" | "vault-missing" | "not-directory" | "not-readable"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface ReadRefusal extends Failed {
|
|
96
|
+
reason: ResolveRefusal["reason"] | "not-found"
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface CreateRefusal extends Failed {
|
|
100
|
+
reason: ResolveRefusal["reason"] | "not-writable" | "not-found"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface ExistingNoteRefusal extends Failed {
|
|
104
|
+
reason: "exists"
|
|
105
|
+
existingStatement: string
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface UpdateRefusal extends Failed {
|
|
109
|
+
reason: CreateRefusal["reason"] | "conflict"
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface IoRefusal extends Failed {
|
|
113
|
+
reason: "io-error"
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface RefreshRefusal extends Failed {
|
|
117
|
+
reason: CreateRefusal["reason"] | "io-error" | "interrupted"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface RefreshPlan {
|
|
121
|
+
folders: Set<string>
|
|
122
|
+
refusals: RefreshRefusal[]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export type RefreshContinuation = () => boolean
|
|
126
|
+
export type RefreshScope = "with-ancestors" | "exact"
|
|
127
|
+
|
|
128
|
+
export type IndexStat = VaultFileStat
|
|
129
|
+
|
|
130
|
+
export interface RefreshedFolder {
|
|
131
|
+
folder: string
|
|
132
|
+
index: IndexStat
|
|
133
|
+
settled: boolean
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface RefreshedFolders {
|
|
137
|
+
refreshed: RefreshedFolder[]
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface FolderRefreshed extends MaintenanceWarnings {
|
|
141
|
+
index: IndexStat
|
|
142
|
+
settled: boolean
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface ListingDraft extends FolderListing {
|
|
146
|
+
settled: boolean
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface SettledListing {
|
|
150
|
+
listing: FolderListing
|
|
151
|
+
settled: boolean
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export type LifecycleRefusal = UpdateRefusal | ExistingNoteRefusal
|
|
155
|
+
export type VaultRefusal = LifecycleRefusal | IoRefusal
|
|
156
|
+
export type VaultFailureReason = VaultRefusal["reason"]
|
|
157
|
+
|
|
158
|
+
export interface PartialRelocation extends Failed {
|
|
159
|
+
reason: "partial"
|
|
160
|
+
cause: LifecycleRefusal | IoRefusal
|
|
161
|
+
written: PlacedNote[]
|
|
162
|
+
originalState: "present" | "missing" | "unknown"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface RelocationProgress {
|
|
166
|
+
written: PlacedNote[]
|
|
167
|
+
maintenanceProblems: string[]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface NeedsFixingNote extends Failed {
|
|
171
|
+
reason: "needs-fixing"
|
|
172
|
+
parsed: ParsedNote
|
|
173
|
+
hash: string
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export type CreateResult = (Succeeded<StoredNote> & MaintenanceWarnings) | CreateRefusal | ExistingNoteRefusal
|
|
177
|
+
export type UpdateResult = (Succeeded<StoredNote> & MaintenanceWarnings) | UpdateRefusal
|
|
178
|
+
export type VaultResult = CreateResult | UpdateResult
|
|
179
|
+
export type ReadNoteResult = Succeeded<StoredNote> | ReadRefusal | NeedsFixingNote
|
|
180
|
+
export type CheckResult = Done | LifecycleRefusal
|
|
181
|
+
export type RemovalResult = Succeeded<string> | LifecycleRefusal
|
|
182
|
+
export type RelocationWriteResult = RemovalResult | PartialRelocation
|
|
183
|
+
export type RelocationResult = (Done & MaintenanceWarnings) | LifecycleRefusal | PartialRelocation
|
|
184
|
+
export type PlacedResult = (Succeeded<PlacedNote> & MaintenanceWarnings) | LifecycleRefusal | PartialRelocation
|
|
185
|
+
export type SuccessionResult = (Succeeded<Succession> & MaintenanceWarnings) | LifecycleRefusal | PartialRelocation
|
|
186
|
+
export type RefreshResult = (Done & MaintenanceWarnings) | RefreshRefusal
|
|
187
|
+
export type FolderRefreshResult = RefreshResult & RefreshedFolders
|
|
188
|
+
export type FolderRefreshOutcome = Succeeded<FolderRefreshed> | RefreshRefusal
|
|
189
|
+
export type ResolveResult = Succeeded<string> | ResolveRefusal
|
|
190
|
+
export type ListResult = Succeeded<FolderListing> | ReadRefusal
|
|
191
|
+
export type SettledListResult = Succeeded<SettledListing> | ReadRefusal
|
|
192
|
+
export type VaultFolderState = "missing" | "empty" | "populated" | "not-directory"
|
|
193
|
+
export type VaultFolderResult = Succeeded<VaultFolderState> | IoRefusal
|
|
194
|
+
|
|
195
|
+
export interface NewFileRefusal extends Failed {
|
|
196
|
+
reason: "exists" | "not-found" | "io-error"
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export type WriteNewFileResult = Done | NewFileRefusal
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { checkFileName, checkNote, renderNote } from "#src/domain"
|
|
2
|
+
import type { VaultContext } from "#src/services/vault/context"
|
|
3
|
+
import { hashOf, readRawFile, writeAtomically } from "#src/services/vault/filesystem"
|
|
4
|
+
import { displayNotePath } from "./display.ts"
|
|
5
|
+
import { refuseWrite } from "./refusals.ts"
|
|
6
|
+
import { resolveFile } from "./resolve.ts"
|
|
7
|
+
import { resolveStoredFile } from "./resolve-stored-file.ts"
|
|
8
|
+
import type { ResolveResult, UpdateFileRequest, UpdateResult } from "./types.ts"
|
|
9
|
+
|
|
10
|
+
export async function updateNoteFile(
|
|
11
|
+
vault: VaultContext,
|
|
12
|
+
request: UpdateFileRequest,
|
|
13
|
+
exactPath?: string,
|
|
14
|
+
): Promise<UpdateResult> {
|
|
15
|
+
const { folder, fileName, note, expectedHash } = request
|
|
16
|
+
const problems = [...checkNote(note, vault.limits), ...checkFileName(fileName)]
|
|
17
|
+
if (fileName.slice(-3).toLowerCase() !== ".md" || fileName.slice(0, -3) !== note.statement) {
|
|
18
|
+
problems.push("The destination filename must match the note statement and have a Markdown extension")
|
|
19
|
+
}
|
|
20
|
+
if (problems.length > 0) {
|
|
21
|
+
return { succeeded: false, reason: "invalid", problems }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const path = await resolveUpdatePath(vault.path, request, exactPath)
|
|
25
|
+
if (!path.succeeded) {
|
|
26
|
+
return path
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const current = await readRawFile(path.output)
|
|
30
|
+
if (!current.succeeded && current.reason !== "not-found") {
|
|
31
|
+
return current
|
|
32
|
+
}
|
|
33
|
+
if (!current.succeeded || hashOf(current.output) !== expectedHash) {
|
|
34
|
+
const problem = `${displayNotePath(folder, note.statement)} changed on disk since it was read`
|
|
35
|
+
return { succeeded: false, reason: "conflict", problems: [problem] }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const text = renderNote(note)
|
|
39
|
+
const written = await writeAtomically(path.output, text)
|
|
40
|
+
if (!written.succeeded) {
|
|
41
|
+
return refuseWrite(folder, note.statement, written)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const result: UpdateResult = { succeeded: true, output: { note, hash: hashOf(text) } }
|
|
45
|
+
if (written.maintenanceProblems) {
|
|
46
|
+
result.maintenanceProblems = written.maintenanceProblems
|
|
47
|
+
}
|
|
48
|
+
return result
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function resolveUpdatePath(
|
|
52
|
+
vault: string,
|
|
53
|
+
request: UpdateFileRequest,
|
|
54
|
+
exactPath: string | undefined,
|
|
55
|
+
): Promise<ResolveResult> {
|
|
56
|
+
if (typeof exactPath === "string") return resolveStoredFile(vault, exactPath, request.note.statement)
|
|
57
|
+
return resolveFile(vault, request.folder, request.fileName)
|
|
58
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Note } from "#src/domain"
|
|
2
|
+
import type { VaultContext } from "#src/services/vault/context"
|
|
3
|
+
import { noteFileName, storedFilePath } from "./paths.ts"
|
|
4
|
+
import type { ExactUpdateRequest, UpdateResult } from "./types.ts"
|
|
5
|
+
import { updateNoteFile } from "./update-file.ts"
|
|
6
|
+
|
|
7
|
+
export async function updateStoredFile(vault: VaultContext, request: ExactUpdateRequest): Promise<UpdateResult> {
|
|
8
|
+
return updateNoteFile(
|
|
9
|
+
vault,
|
|
10
|
+
{ ...storedFilePath(request.path), note: request.note, expectedHash: request.expectedHash },
|
|
11
|
+
request.path,
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function updateNote(
|
|
16
|
+
vault: VaultContext,
|
|
17
|
+
folder: string,
|
|
18
|
+
note: Note,
|
|
19
|
+
hashWhenRead: string,
|
|
20
|
+
): Promise<UpdateResult> {
|
|
21
|
+
return updateNoteFile(vault, { folder, fileName: noteFileName(note.statement), note, expectedHash: hashWhenRead })
|
|
22
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { open } from "node:fs/promises"
|
|
2
|
+
|
|
3
|
+
import { errorCode, removeFile } from "#src/services/vault/filesystem"
|
|
4
|
+
import type { NewFileRefusal, WriteNewFileResult } from "./types.ts"
|
|
5
|
+
|
|
6
|
+
export async function writeNewFile(path: string, bytes: Uint8Array): Promise<WriteNewFileResult> {
|
|
7
|
+
let created = false
|
|
8
|
+
try {
|
|
9
|
+
const handle = await open(path, "wx")
|
|
10
|
+
created = true
|
|
11
|
+
try {
|
|
12
|
+
await handle.writeFile(bytes)
|
|
13
|
+
} finally {
|
|
14
|
+
await handle.close()
|
|
15
|
+
}
|
|
16
|
+
return { succeeded: true }
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (!(error instanceof Error)) throw error
|
|
19
|
+
const refusal = refusalOf(error, path)
|
|
20
|
+
if (!created) return refusal
|
|
21
|
+
const removed = await removeFile(path)
|
|
22
|
+
if (removed.succeeded) return refusal
|
|
23
|
+
return { ...refusal, problems: [...refusal.problems, ...removed.problems.map(partialFileProblem)] }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function partialFileProblem(problem: string): string {
|
|
28
|
+
return `The partly written file was left behind: ${problem}`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function refusalOf(error: Error, path: string): NewFileRefusal {
|
|
32
|
+
const code = errorCode(error)
|
|
33
|
+
const problems = [`${path} cannot be created (${code})`]
|
|
34
|
+
if (code === "EEXIST") return { succeeded: false, reason: "exists", problems }
|
|
35
|
+
if (code === "ENOENT" || code === "ENOTDIR") return { succeeded: false, reason: "not-found", problems }
|
|
36
|
+
return { succeeded: false, reason: "io-error", problems }
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./result/index.ts"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./types.ts"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface Succeeded<Output> {
|
|
2
|
+
succeeded: true
|
|
3
|
+
output: Output
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface Done {
|
|
7
|
+
succeeded: true
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface Failed {
|
|
11
|
+
succeeded: false
|
|
12
|
+
problems: string[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface Absent {
|
|
16
|
+
succeeded: false
|
|
17
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createMemoryNote,
|
|
3
|
+
displayNotePath,
|
|
4
|
+
type ExistingNoteRefusal,
|
|
5
|
+
newNote,
|
|
6
|
+
newNoteId,
|
|
7
|
+
type ReadNoteResult,
|
|
8
|
+
readConfig,
|
|
9
|
+
readNote,
|
|
10
|
+
targetVault,
|
|
11
|
+
today,
|
|
12
|
+
} from "#src/services"
|
|
13
|
+
import {
|
|
14
|
+
captureMemoryOperationContext,
|
|
15
|
+
type MemoryOperationContext,
|
|
16
|
+
memoryAdmissionRefusal,
|
|
17
|
+
memoryOperationInterruption,
|
|
18
|
+
} from "#src/usecases/operation-context"
|
|
19
|
+
import { maintainAddedMemory } from "./maintenance.ts"
|
|
20
|
+
import type { AddMemoryRequest, AddMemoryResult } from "./types.ts"
|
|
21
|
+
|
|
22
|
+
export async function addMemory(
|
|
23
|
+
request: AddMemoryRequest,
|
|
24
|
+
callerContext: MemoryOperationContext,
|
|
25
|
+
): Promise<AddMemoryResult> {
|
|
26
|
+
const context = captureMemoryOperationContext(callerContext)
|
|
27
|
+
const lease = await context.session.acquire(context.stamp, context.signal)
|
|
28
|
+
if (!lease) return memoryAdmissionRefusal(context)
|
|
29
|
+
try {
|
|
30
|
+
const interrupted = memoryOperationInterruption(context)
|
|
31
|
+
if (interrupted) return interrupted
|
|
32
|
+
return await addLeasedMemory(request, context)
|
|
33
|
+
} finally {
|
|
34
|
+
lease.release()
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function addLeasedMemory(request: AddMemoryRequest, context: MemoryOperationContext): Promise<AddMemoryResult> {
|
|
39
|
+
const config = await readConfig(context.configPath, context.platform)
|
|
40
|
+
if (!config.succeeded) {
|
|
41
|
+
return config
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const target = targetVault(config.output, request.scope, context.workingFolder, context.platform)
|
|
45
|
+
if (!target.succeeded) {
|
|
46
|
+
return { ...target, configPath: context.configPath }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const { path, name } = target.output
|
|
50
|
+
const { limits } = config.output
|
|
51
|
+
const vault = { path, name, limits }
|
|
52
|
+
const created = await createMemoryNote(vault, request.folder, newNote(request.draft, newNoteId(), today()))
|
|
53
|
+
if (!created.succeeded && created.reason === "exists") {
|
|
54
|
+
const existing = await readNote(vault, request.folder, created.existingStatement)
|
|
55
|
+
return refuseExisting(created, existing)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!created.succeeded) {
|
|
59
|
+
return created
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const maintenanceProblems = await maintainAddedMemory(vault, request.folder, created)
|
|
63
|
+
const notePath = displayNotePath(request.folder, created.output.note.statement)
|
|
64
|
+
return {
|
|
65
|
+
succeeded: true,
|
|
66
|
+
output: {
|
|
67
|
+
scope: request.scope,
|
|
68
|
+
vaultName: name,
|
|
69
|
+
folder: request.folder,
|
|
70
|
+
notePath,
|
|
71
|
+
stored: created.output,
|
|
72
|
+
maintenanceProblems,
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function refuseExisting(refusal: ExistingNoteRefusal, existing: ReadNoteResult): AddMemoryResult {
|
|
78
|
+
if (!existing.succeeded) {
|
|
79
|
+
return refusal
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { succeeded: false, reason: "exists", problems: refusal.problems, existing: existing.output }
|
|
83
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type CreateResult, type NamedVaultContext, type RefreshResult, refreshIndexes } from "#src/services"
|
|
2
|
+
import type { Done } from "#src/shared"
|
|
3
|
+
|
|
4
|
+
export async function maintainAddedMemory(
|
|
5
|
+
vault: NamedVaultContext,
|
|
6
|
+
folder: string,
|
|
7
|
+
created: Extract<CreateResult, Done>,
|
|
8
|
+
): Promise<string[]> {
|
|
9
|
+
const refreshed = await refreshIndexes(vault, folder)
|
|
10
|
+
return [...maintenanceProblemsOf(created), ...maintenanceProblemsOf(refreshed)]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function maintenanceProblemsOf(result: CreateResult | RefreshResult): string[] {
|
|
14
|
+
if (!result.succeeded) {
|
|
15
|
+
return result.problems.map((problem) => `${result.reason}: ${problem}`)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (result.maintenanceProblems) {
|
|
19
|
+
return result.maintenanceProblems
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return []
|
|
23
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Type from "typebox"
|
|
2
|
+
|
|
3
|
+
import { MemoryDraftSchema, MemoryScopeSchema } from "#src/services"
|
|
4
|
+
|
|
5
|
+
export const AddMemoryRequestSchema = Type.Object(
|
|
6
|
+
{
|
|
7
|
+
scope: MemoryScopeSchema,
|
|
8
|
+
folder: Type.String(),
|
|
9
|
+
draft: MemoryDraftSchema,
|
|
10
|
+
},
|
|
11
|
+
{ additionalProperties: false },
|
|
12
|
+
)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Static } from "typebox"
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
ConfigRefusal,
|
|
5
|
+
CreateResult,
|
|
6
|
+
MemoryScope,
|
|
7
|
+
NoProjectRefusal,
|
|
8
|
+
PathPlatform,
|
|
9
|
+
StoredNote,
|
|
10
|
+
} from "#src/services"
|
|
11
|
+
import type { Failed, Succeeded } from "#src/shared"
|
|
12
|
+
import type { MemoryOperationRefusal } from "#src/usecases/operation-context"
|
|
13
|
+
import type { AddMemoryRequestSchema } from "./schemas.ts"
|
|
14
|
+
|
|
15
|
+
export type AddMemoryRequest = Static<typeof AddMemoryRequestSchema>
|
|
16
|
+
|
|
17
|
+
export interface MemoryContext {
|
|
18
|
+
configPath: string
|
|
19
|
+
workingFolder: string
|
|
20
|
+
platform: PathPlatform
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AddedMemory {
|
|
24
|
+
scope: MemoryScope
|
|
25
|
+
vaultName: string
|
|
26
|
+
folder: string
|
|
27
|
+
notePath: string
|
|
28
|
+
stored: StoredNote
|
|
29
|
+
maintenanceProblems: string[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface UnregisteredProjectRefusal extends NoProjectRefusal {
|
|
33
|
+
configPath: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ExistingMemoryRefusal extends Failed {
|
|
37
|
+
reason: "exists"
|
|
38
|
+
existing: StoredNote
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type AddMemoryResult =
|
|
42
|
+
| Succeeded<AddedMemory>
|
|
43
|
+
| ConfigRefusal
|
|
44
|
+
| UnregisteredProjectRefusal
|
|
45
|
+
| Extract<CreateResult, Failed>
|
|
46
|
+
| ExistingMemoryRefusal
|
|
47
|
+
| MemoryOperationRefusal
|