pi-obsidian-memory 0.0.1 → 0.1.1
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 +237 -7
- package/package.json +41 -11
- 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 -21
package/README.md
CHANGED
|
@@ -1,15 +1,245 @@
|
|
|
1
1
|
# pi-obsidian-memory
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Long-term memory for the [pi coding agent](https://pi.dev), stored as Markdown notes in
|
|
4
|
+
[Obsidian](https://obsidian.md) vaults.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
pi forgets everything when a session ends. With this package it keeps what matters (your preferences, the rules and
|
|
7
|
+
decisions of each project, lessons from past mistakes) and brings it back when it helps. You can read and edit every
|
|
8
|
+
note in Obsidian.
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
- Notas nativas do Obsidian, com índice e templates: só aprendizados e pontos importantes.
|
|
9
|
-
- Tudo configurável, com onboarding (`/memory-setup` e `/memory-init`).
|
|
10
|
+
## Contents
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
1. [Requirements](#requirements)
|
|
13
|
+
2. [Install](#install)
|
|
14
|
+
3. [Set up](#set-up)
|
|
15
|
+
4. [How it works](#how-it-works)
|
|
16
|
+
5. [Settings](#settings)
|
|
17
|
+
6. [Where things are stored](#where-things-are-stored)
|
|
18
|
+
7. [Privacy](#privacy)
|
|
19
|
+
8. [Troubleshooting](#troubleshooting)
|
|
20
|
+
9. [Known limits](#known-limits)
|
|
21
|
+
10. [Development](#development)
|
|
12
22
|
|
|
13
|
-
##
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
| What | Why | Required? |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| [pi](https://pi.dev) | Runs the package. Tested with pi 1.3.0. | Yes |
|
|
28
|
+
| Node 22.19 or later | pi runs the package on it. | Yes |
|
|
29
|
+
| A chat model configured in pi | Saves notes in the background (capture) and finds notes for each message (memory agent). Any model pi can use works; a small, cheap one is enough for the memory agent. | Yes |
|
|
30
|
+
| A TypeSafe API key (`TYPESAFE_API_KEY`) | Jev, TypeSafe's classifier, decides which notes help each message and checks shell commands (see [Guards](#guards)). Get a key at [typesafe.ai](https://docs.typesafe.ai). Price: $0.042 per million input tokens. | Strongly recommended |
|
|
31
|
+
| [Obsidian](https://obsidian.md) | Reading and editing the notes. | No: notes are plain Markdown |
|
|
32
|
+
|
|
33
|
+
**Without `TYPESAFE_API_KEY`:** no notes are added to your messages (pi tells you once per session), and every
|
|
34
|
+
`bash` or `powershell` call is refused, because the shell-edit guard cannot check it.
|
|
35
|
+
|
|
36
|
+
### Setting the TypeSafe key
|
|
37
|
+
|
|
38
|
+
Set the environment variable before starting pi:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# macOS / Linux (add it to ~/.bashrc or ~/.zshrc to keep it)
|
|
42
|
+
export TYPESAFE_API_KEY=your-key
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```powershell
|
|
46
|
+
# Windows (kept for new terminals)
|
|
47
|
+
setx TYPESAFE_API_KEY "your-key"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The key can also be pi's stored credential for the `typesafe` provider. It is never written to this package's config.
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pi install npm:pi-obsidian-memory
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Then restart pi. To try it for one run without installing: `pi -e npm:pi-obsidian-memory`.
|
|
59
|
+
|
|
60
|
+
`pi list` shows installed packages; `pi update` updates them.
|
|
61
|
+
|
|
62
|
+
## Set up
|
|
63
|
+
|
|
64
|
+
1. **Create the global vault.** Run `/memory-setup` in pi. It asks:
|
|
65
|
+
- where the global vault goes: a new folder, or an existing folder (an Obsidian vault you already have works);
|
|
66
|
+
- which chat model saves memory (capture); the model in use is the default;
|
|
67
|
+
- which chat model runs the memory agent; the list is sorted by price, cheapest first.
|
|
68
|
+
|
|
69
|
+
It shows what each choice sends where, then writes the config and the vault.
|
|
70
|
+
2. **Give each project its own vault.** Open pi in the project folder and run `/memory-init`. A folder without a
|
|
71
|
+
project vault uses the global vault only.
|
|
72
|
+
3. **Use pi as usual.** Say "remember that …" to save something. The rest happens on its own.
|
|
73
|
+
|
|
74
|
+
Run `/memory-setup` again at any time to open the settings screen. Both commands need pi's interactive mode.
|
|
75
|
+
|
|
76
|
+
## How it works
|
|
77
|
+
|
|
78
|
+
### Two vaults
|
|
79
|
+
|
|
80
|
+
- **Global vault:** about you. How to address you, your preferences, your patterns, lessons that apply everywhere.
|
|
81
|
+
- **Project vault:** about one project. Its rules, decisions, facts, open issues.
|
|
82
|
+
|
|
83
|
+
Each note holds one point. Its file name is the statement (for example `pnpm/Use pnpm, never npm.md`), the body has
|
|
84
|
+
the detail, and the frontmatter says what kind of memory it is:
|
|
85
|
+
|
|
86
|
+
```markdown
|
|
87
|
+
---
|
|
88
|
+
id: 01JABCDE7XKQ2M9V3RTN8WPZ5F
|
|
89
|
+
type: rule
|
|
90
|
+
created: 2026-10-04
|
|
91
|
+
updated: 2026-10-04
|
|
92
|
+
dontForget: true
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
Use pnpm for every install and script. In CI: `pnpm install --frozen-lockfile`.
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Types: `rule`, `procedure`, `constraint`, `fact`, `issue`, `question`, `decision`, `lesson`, `goal`, `risk`, `idea`,
|
|
99
|
+
`reference`. Notes are written in English. They are never deleted: a retired note moves to `archive/`. The full format
|
|
100
|
+
is in [docs/vault-format.md](docs/vault-format.md).
|
|
101
|
+
|
|
102
|
+
### What happens during a session
|
|
103
|
+
|
|
104
|
+
1. **Session start.** Every note marked `dontForget: true` is loaded into pi's system prompt, in full.
|
|
105
|
+
2. **Each message.** Jev decides whether stored memory would help. If yes, the memory agent searches and reads the
|
|
106
|
+
vaults, Jev scores each note it found, and the notes that help are added after your message, within
|
|
107
|
+
`context.budgetChars` (12,000 characters by default). A note you changed since it was loaded is sent again.
|
|
108
|
+
3. **In the background (capture).** Every 10 assistant turns or 15 tool calls, once the session has at least three of
|
|
109
|
+
your messages, a review reads the new part of the conversation and saves, updates, archives or replaces notes. What
|
|
110
|
+
was not reviewed yet is also saved before pi compacts the session and when it ends. Capture never asks you
|
|
111
|
+
anything: what it is unsure of is not saved. The cadence follows
|
|
112
|
+
[pi-hermes-memory](https://github.com/chandra447/pi-hermes-memory).
|
|
113
|
+
|
|
114
|
+
You change notes in Obsidian whenever you want. pi must read a note before changing it, and a note you edited since
|
|
115
|
+
then is never overwritten.
|
|
116
|
+
|
|
117
|
+
### Tools the agent uses
|
|
118
|
+
|
|
119
|
+
| Tool | Does |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `memory_search` | Finds notes by words and by meaning, in the global vault, the project vault or both |
|
|
122
|
+
| `memory_get` | Reads a note, a folder's index, or anything under `archive/` |
|
|
123
|
+
| `memory_add` | Saves a new note |
|
|
124
|
+
| `memory_update` | Changes a note |
|
|
125
|
+
| `memory_archive` | Moves a note to `archive/` |
|
|
126
|
+
| `memory_succeed` | Replaces a note with a new one; both link to each other |
|
|
127
|
+
|
|
128
|
+
The bundled skill `obsidian-memory` teaches the agent where notes go and how to use these tools.
|
|
129
|
+
|
|
130
|
+
### Commands
|
|
131
|
+
|
|
132
|
+
| Command | Does |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `/memory-setup` | First setup; afterwards, the settings screen |
|
|
135
|
+
| `/memory-init` | Gives the current project its own vault |
|
|
136
|
+
| `/memory-doctor` | Checks the vaults, the config, the models and the keys, and says what is wrong |
|
|
137
|
+
| `/memory-export` | Saves both vaults to a new `.zip` |
|
|
138
|
+
|
|
139
|
+
### Guards
|
|
140
|
+
|
|
141
|
+
- **Vault guard.** The agent reaches the vaults only through the memory tools. pi's file tools (`read`, `write`,
|
|
142
|
+
`edit`, `grep`, `find`, `ls`) on a vault are refused, and so are shell commands that write a vault path out. You and
|
|
143
|
+
Obsidian are not affected.
|
|
144
|
+
- **Shell-edit guard.** Before every `bash` or `powershell` call, Jev checks whether the command edits a file: a
|
|
145
|
+
redirect, an in-place edit, inline code, a script that writes, a copy or download that creates a file, or a
|
|
146
|
+
hardlink. If so, the call is refused and the agent is told to use `edit` or `write`. When Jev cannot answer, the
|
|
147
|
+
call is refused.
|
|
148
|
+
|
|
149
|
+
### Dashboard
|
|
150
|
+
|
|
151
|
+
Each vault gets a `Memory.base` file: an Obsidian view of all notes, the Don't forget notes and the archive. Your edits
|
|
152
|
+
to it are kept.
|
|
153
|
+
|
|
154
|
+
## Settings
|
|
155
|
+
|
|
156
|
+
All settings are changed in the `/memory-setup` screen, or by asking pi. You never need to edit the file.
|
|
157
|
+
|
|
158
|
+
| Setting | Default | What it does |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| Global vault | chosen at setup | Folder of the global vault |
|
|
161
|
+
| Projects | none | Each project folder and its vault, added by `/memory-init` |
|
|
162
|
+
| Capture model | the model in use at setup | Chat model that saves memory |
|
|
163
|
+
| Memory agent model | chosen at setup | Chat model that searches and reads notes for each message |
|
|
164
|
+
| `capture.nudgeInterval` | 10 | Assistant turns between background reviews |
|
|
165
|
+
| `capture.nudgeToolCalls` | 15 | Tool calls between background reviews |
|
|
166
|
+
| `capture.flushMinTurns` | 6 | Your messages a session needs before it is saved at compaction or at the end |
|
|
167
|
+
| `capture.reviewEnabled` | on | Background review during the session |
|
|
168
|
+
| `capture.flushOnCompact` | on | Save before pi compacts the session |
|
|
169
|
+
| `capture.flushOnShutdown` | on | Save when the session ends |
|
|
170
|
+
| `context.budgetChars` | 12,000 | Characters of relevant notes added at session start and to each message (Don't forget notes do not count) |
|
|
171
|
+
| `limits.maxStatementChars` | 100 | Longest note name |
|
|
172
|
+
| `limits.maxBodyChars` | 1,000 | Longest note body |
|
|
173
|
+
| `limits.maxNotesPerFolder` | 20 | `/memory-doctor` suggests splitting a folder above this |
|
|
174
|
+
| Embeddings | local | Model for search by meaning: local (no key), OpenAI (`OPENAI_API_KEY`) or Google (`GEMINI_API_KEY`) |
|
|
175
|
+
| Decision model | Jev | Jev (TypeSafe, cutoffs 0.5/0.5) or Laya (local server, you set the cutoffs) |
|
|
176
|
+
|
|
177
|
+
Every field, the file format and running Laya locally are in [docs/config.md](docs/config.md).
|
|
178
|
+
|
|
179
|
+
## Where things are stored
|
|
180
|
+
|
|
181
|
+
| What | Where |
|
|
182
|
+
|---|---|
|
|
183
|
+
| Notes | The vault folders you chose |
|
|
184
|
+
| Settings | `pi-obsidian-memory/config.json` in pi's agent folder (`~/.pi/agent` by default) |
|
|
185
|
+
| Search index | `pi-obsidian-memory/index/` in pi's agent folder; rebuilt from the notes when needed |
|
|
186
|
+
| Local search model | `pi-obsidian-memory/models/` in pi's agent folder; downloaded once, about 135 MB |
|
|
187
|
+
|
|
188
|
+
The vaults hold only notes, their `index.md` files, `_templates/` and `Memory.base`, so they can live in any synced
|
|
189
|
+
folder (OneDrive, iCloud, Dropbox).
|
|
190
|
+
|
|
191
|
+
## Privacy
|
|
192
|
+
|
|
193
|
+
- Capture and the memory agent send conversation and note content to the chat models you choose.
|
|
194
|
+
- Jev sends your messages, candidate notes and shell commands to TypeSafe.
|
|
195
|
+
- Search by meaning runs on your machine by default; OpenAI or Google receive note content and queries only if you
|
|
196
|
+
choose them.
|
|
197
|
+
- `/memory-setup` shows each of these before it saves.
|
|
198
|
+
- Notes are saved as written, without masking. The config file never holds a key.
|
|
199
|
+
|
|
200
|
+
## Troubleshooting
|
|
201
|
+
|
|
202
|
+
Run `/memory-doctor` first: it checks the vaults, the config, the models and the keys, and says what is wrong. The only
|
|
203
|
+
thing it offers to change is a blank note, after asking you.
|
|
204
|
+
|
|
205
|
+
| You see | Do |
|
|
206
|
+
|---|---|
|
|
207
|
+
| "Memory is off" or "Run /memory-setup first" | Run `/memory-setup` |
|
|
208
|
+
| "No chat model is available" during setup | Connect a model in pi (`/login`), then run `/memory-setup` again |
|
|
209
|
+
| No relevant notes are ever added | Check that `TYPESAFE_API_KEY` is set, then run `/memory-doctor` |
|
|
210
|
+
| "Refused: the shell-edit guard could not check this command" | Same: the shell-edit guard needs Jev |
|
|
211
|
+
| "Memory capture did not finish: …" | The text after the colon names the cause, for example a model without a key |
|
|
212
|
+
| `No API key found for "<provider>"` in `/memory-doctor` | Log in to that provider in pi (`/login`) or set its key |
|
|
213
|
+
|
|
214
|
+
## Known limits
|
|
215
|
+
|
|
216
|
+
- Paths are compared ignoring case on Windows and macOS and with case on Linux, whatever the volume.
|
|
217
|
+
- The vault guard does not see a vault path the shell builds indirectly (variables, globs, scripts), tools of other
|
|
218
|
+
extensions, or foreground subagents.
|
|
219
|
+
- How well capture judges what to save is not yet measured against a real model.
|
|
220
|
+
|
|
221
|
+
## Development
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
npm install
|
|
225
|
+
npm run lint
|
|
226
|
+
npm run typecheck
|
|
227
|
+
npm test # offline: pure tests and tests on a real temporary disk
|
|
228
|
+
npm run test:e2e # the real pi over RPC, through OmniRoute
|
|
229
|
+
npm run test:model # live tests: real models and network
|
|
230
|
+
pi -e ./src/pi/extension.ts
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`npm run test:e2e` runs one test per feature with the real `cc/claude-haiku-5-5` through OmniRoute
|
|
234
|
+
(`pi-omniroute-sync`) and the real Jev. It reads `OMNIROUTE_URL`, `OMNIROUTE_API_KEY` and `TYPESAFE_API_KEY` from the
|
|
235
|
+
environment. CI runs it on Windows, and lint, typecheck and `npm test` on Windows, macOS and Linux.
|
|
236
|
+
|
|
237
|
+
Releases are automatic: a push to `main` with a `feat` or `fix` commit bumps the version, rewrites `CHANGELOG.md`,
|
|
238
|
+
publishes to npm and creates the GitHub release.
|
|
239
|
+
|
|
240
|
+
More: [vision](docs/VISION.md), [roadmap](docs/ROADMAP.md), [note format](docs/vault-format.md),
|
|
241
|
+
[settings](docs/config.md).
|
|
242
|
+
|
|
243
|
+
## License
|
|
14
244
|
|
|
15
245
|
[MIT](LICENSE)
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-obsidian-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Long-term memory for the pi coding agent, stored in Obsidian vaults",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi",
|
|
7
7
|
"pi-coding-agent",
|
|
8
|
+
"pi-package",
|
|
8
9
|
"obsidian",
|
|
9
10
|
"memory",
|
|
10
11
|
"agent-memory"
|
|
@@ -20,24 +21,53 @@
|
|
|
20
21
|
"url": "https://github.com/DavyMassoneto/pi-obsidian-memory/issues"
|
|
21
22
|
},
|
|
22
23
|
"type": "module",
|
|
24
|
+
"imports": {
|
|
25
|
+
"#src/*": "./src/*/index.ts",
|
|
26
|
+
"#test-helpers": "./tests/helpers/index.ts"
|
|
27
|
+
},
|
|
23
28
|
"engines": {
|
|
24
|
-
"node": ">=
|
|
29
|
+
"node": ">=22.19.0"
|
|
25
30
|
},
|
|
26
31
|
"files": [
|
|
27
|
-
"
|
|
32
|
+
"src",
|
|
33
|
+
"skills"
|
|
28
34
|
],
|
|
29
35
|
"scripts": {
|
|
30
|
-
"
|
|
31
|
-
"
|
|
36
|
+
"format": "biome check --write .",
|
|
37
|
+
"lint": "biome check .",
|
|
38
|
+
"test": "vitest run --project unit",
|
|
39
|
+
"test:model": "vitest run --project model",
|
|
40
|
+
"test:e2e": "vitest run --project e2e",
|
|
32
41
|
"typecheck": "tsc --noEmit"
|
|
33
42
|
},
|
|
34
|
-
"
|
|
35
|
-
"
|
|
43
|
+
"pi": {
|
|
44
|
+
"extensions": [
|
|
45
|
+
"./src/pi/extension.ts"
|
|
46
|
+
],
|
|
47
|
+
"skills": [
|
|
48
|
+
"./skills"
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
53
|
+
"typebox": "*"
|
|
36
54
|
},
|
|
37
55
|
"devDependencies": {
|
|
38
|
-
"@
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
56
|
+
"@biomejs/biome": "2.5.15",
|
|
57
|
+
"@earendil-works/pi-coding-agent": "1.3.0",
|
|
58
|
+
"@types/node": "24.19.1",
|
|
59
|
+
"@types/stopword": "2.0.3",
|
|
60
|
+
"git-cliff": "2.14.2",
|
|
61
|
+
"pi-omniroute-sync": "1.2.1",
|
|
62
|
+
"typebox": "1.3.27",
|
|
63
|
+
"typescript": "7.0.2",
|
|
64
|
+
"vitest": "5.0.3"
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@huggingface/transformers": "4.3.1",
|
|
68
|
+
"fflate": "0.8.3",
|
|
69
|
+
"stopword": "3.1.5",
|
|
70
|
+
"ulid": "3.0.2",
|
|
71
|
+
"yaml": "2.9.1"
|
|
42
72
|
}
|
|
43
73
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: obsidian-memory
|
|
3
|
+
description: How to use the Obsidian long-term memory (global and project vaults) - where notes go, note types, what is not memory, and the memory tools. Load before searching or reading memory, before saving something the user asked to remember, or when a memory block appears in the context.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Obsidian memory
|
|
7
|
+
|
|
8
|
+
Long-term memory lives in Obsidian vaults. Notes are in English, whatever language the user speaks.
|
|
9
|
+
|
|
10
|
+
## Two layers
|
|
11
|
+
|
|
12
|
+
- Global vault: about the user (how to address them, preferences, patterns, global lessons).
|
|
13
|
+
- Project vault: everything else about the current project.
|
|
14
|
+
- Classify each memory. When unsure which vault, ask the user.
|
|
15
|
+
- A folder with no registered project has the global vault only.
|
|
16
|
+
|
|
17
|
+
## Layout and placement
|
|
18
|
+
|
|
19
|
+
- One folder per subject. Each folder holds short notes, one point per note. Subjects nest with no depth limit.
|
|
20
|
+
- Place a note from general to specific: `typescript/testing/`, not `testing/typescript/`.
|
|
21
|
+
- Reuse before creating: walk the existing tree (read folder indexes level by level) and use the path that already covers the subject.
|
|
22
|
+
- When two paths fit, ask the user.
|
|
23
|
+
- Every folder has an `index.md` listing its subfolders and its notes (type and don't forget mark). The system keeps it up to date; never write it by hand.
|
|
24
|
+
- Not subjects: hidden folders, and at the vault root `archive/` and `_templates/`.
|
|
25
|
+
- `index` (any case) is reserved: no note can use it as its statement.
|
|
26
|
+
|
|
27
|
+
## Notes
|
|
28
|
+
|
|
29
|
+
- The file name is the statement: reading the name tells exactly what the note says. The body holds the detail.
|
|
30
|
+
- Keep notes short, one point each. A new point in the same subject is a new note in that folder.
|
|
31
|
+
- Name: at most 100 characters by default. It must be a valid Windows file name and must not contain `< > : " / \ | ? * [ ] # ^`, control characters, a leading or trailing space, or a trailing dot. No Windows reserved names (`CON`, `NUL`, `COM1`...).
|
|
32
|
+
- Body: never empty, at most 1,000 characters by default. Record the detail even when the name says it all.
|
|
33
|
+
- An invalid note is refused with every reason. Rewrite it or split it into smaller notes.
|
|
34
|
+
- A note can be marked Don't forget: it is loaded in full at session start.
|
|
35
|
+
|
|
36
|
+
## Types
|
|
37
|
+
|
|
38
|
+
Pick exactly one. The list is closed. When unsure which type fits, ask the user.
|
|
39
|
+
|
|
40
|
+
- `rule`: how to do things; a user preference or a project convention.
|
|
41
|
+
- `procedure`: steps to do something in this project.
|
|
42
|
+
- `constraint`: a limit imposed from outside (platform, deadline, client).
|
|
43
|
+
- `fact`: how things are, about the user or the project.
|
|
44
|
+
- `issue`: a known problem that is still open, with its workaround.
|
|
45
|
+
- `question`: something still undecided or unknown.
|
|
46
|
+
- `decision`: a choice that was made, with its why.
|
|
47
|
+
- `lesson`: something learned from a mistake or a bug.
|
|
48
|
+
- `goal`: a committed objective for the future.
|
|
49
|
+
- `risk`: a problem that may happen.
|
|
50
|
+
- `idea`: a possibility not committed to yet.
|
|
51
|
+
- `reference`: where to find something external.
|
|
52
|
+
|
|
53
|
+
## Not memory
|
|
54
|
+
|
|
55
|
+
- Tasks and TODOs.
|
|
56
|
+
- Session logs.
|
|
57
|
+
- Anything the code or git history already records.
|
|
58
|
+
|
|
59
|
+
Secrets (keys, passwords, tokens) are memory: the vault is the user's own safe. Save them like any other note, with no masking. When unsure whether something is memory at all, ask the user.
|
|
60
|
+
|
|
61
|
+
## Reading
|
|
62
|
+
|
|
63
|
+
The memory block at session start, and the relevant notes added to a message, are only part of the memory. A note added again as replacing an earlier copy supersedes it; a note marked no longer valid must not be relied on. Search and read more when you need it.
|
|
64
|
+
|
|
65
|
+
- `memory_search`: search by words and, when semantic search is on, by meaning, over one or both vaults. When it says semantic search is off, try other words too. Each result gives the vault, the path, the type, the Don't forget mark and whether the note needs fixing. Archived notes and notes with invalid frontmatter are not searched.
|
|
66
|
+
- `memory_get`: takes a vault and a path.
|
|
67
|
+
- A note path returns the note in full, with every problem if it breaks any rule.
|
|
68
|
+
- A folder path returns its index. `""` is the vault root.
|
|
69
|
+
- Paths under `archive/` can be read.
|
|
70
|
+
- To place a note, read the root index and walk down the folder indexes with `memory_get`.
|
|
71
|
+
|
|
72
|
+
## Saving
|
|
73
|
+
|
|
74
|
+
- Memory is captured, updated and retired automatically by a background review of the conversation; you don't need to save anything for it.
|
|
75
|
+
- Use `memory_add` only when the user explicitly asks you to remember something. Never save on your own initiative, and never nudge the user to save.
|
|
76
|
+
- Choose the vault, the folder and the type as described above. Ask when unsure.
|
|
77
|
+
- A name already taken (in any case) is refused with the existing note. If it is the same point, read it with `memory_get` and, only if the user asked for a change, use `memory_update`; otherwise choose a statement that says what is new.
|
|
78
|
+
- Do not save skills or instructions to a vault. Vaults hold only memory.
|
|
79
|
+
|
|
80
|
+
## Changing and retiring
|
|
81
|
+
|
|
82
|
+
Use these only when the user explicitly asks. Always read the note with `memory_get` in this session first, with the exact vault and path; a note not read, or changed on disk since it was read, is refused.
|
|
83
|
+
|
|
84
|
+
- `memory_update`: changes the body, type or Don't forget mark of a note. It never renames: a different statement is a new note that replaces the old one.
|
|
85
|
+
- `memory_archive`: retires a note that stopped being true and has no successor. It moves to `archive/`; nothing is ever deleted.
|
|
86
|
+
- `memory_succeed`: replaces a note with a new one (new statement, folder, type and body). The old note moves to `archive/` and both are linked.
|
|
87
|
+
- Notes under `archive/` cannot be changed.
|
|
88
|
+
- After a partial result, do not call again: tell the user what was done and ask them to check the vault.
|
|
89
|
+
|
|
90
|
+
## Vault access
|
|
91
|
+
|
|
92
|
+
- Never read or write vault files with file tools (`read`, `write`, `edit`, `grep`, `find`, `ls`) or with the shell, however the path is reached.
|
|
93
|
+
- Use only the memory tools. Files outside the vaults are unaffected.
|
|
94
|
+
- The user edits the vault freely in Obsidian; a note can change between sessions.
|
|
95
|
+
|
|
96
|
+
## Setup
|
|
97
|
+
|
|
98
|
+
- With no global vault registered there is no memory: tell the user to run `/memory-setup`.
|
|
99
|
+
- A folder not registered as a project has global memory only: the user can run `/memory-init` to register it.
|
|
100
|
+
- Notes listed under Needs fixing, blank notes and duplicate ids: suggest the user run `/memory-doctor`.
|
|
101
|
+
- A copy of the memory as a zip: the user can run `/memory-export`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Value } from "typebox/value"
|
|
2
|
+
|
|
3
|
+
import { describeSchemaErrors } from "#src/domain/validation"
|
|
4
|
+
import { CaptureInputSchema } from "./schemas.ts"
|
|
5
|
+
import type { CaptureInput } from "./types.ts"
|
|
6
|
+
|
|
7
|
+
export function captureInputProblems(input: CaptureInput): string[] {
|
|
8
|
+
return describeSchemaErrors(Value.Errors(CaptureInputSchema, input), "capture input")
|
|
9
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import Type from "typebox"
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AgentContextSchema,
|
|
5
|
+
HashSchema,
|
|
6
|
+
ObservationSchema,
|
|
7
|
+
PathSchema,
|
|
8
|
+
ReadActionSchema,
|
|
9
|
+
ReadObservationSchema,
|
|
10
|
+
TextSchema,
|
|
11
|
+
VaultSchema,
|
|
12
|
+
} from "#src/domain/memory-agent"
|
|
13
|
+
import { NoteIdSchema, NoteTypeSchema } from "#src/domain/note"
|
|
14
|
+
|
|
15
|
+
export const CaptureDraftSchema = Type.Object(
|
|
16
|
+
{ folder: PathSchema, statement: TextSchema, body: TextSchema, type: NoteTypeSchema, dontForget: Type.Boolean() },
|
|
17
|
+
{ additionalProperties: false },
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
export const CaptureActionSchema = Type.Union([
|
|
21
|
+
ReadActionSchema,
|
|
22
|
+
Type.Object(
|
|
23
|
+
{ action: Type.Literal("add"), vault: VaultSchema, note: CaptureDraftSchema },
|
|
24
|
+
{ additionalProperties: false },
|
|
25
|
+
),
|
|
26
|
+
Type.Object(
|
|
27
|
+
{
|
|
28
|
+
action: Type.Enum(["update", "succeed"]),
|
|
29
|
+
vault: VaultSchema,
|
|
30
|
+
path: PathSchema,
|
|
31
|
+
id: NoteIdSchema,
|
|
32
|
+
expectedHash: HashSchema,
|
|
33
|
+
note: CaptureDraftSchema,
|
|
34
|
+
},
|
|
35
|
+
{ additionalProperties: false },
|
|
36
|
+
),
|
|
37
|
+
Type.Object(
|
|
38
|
+
{
|
|
39
|
+
action: Type.Literal("archive"),
|
|
40
|
+
vault: VaultSchema,
|
|
41
|
+
path: PathSchema,
|
|
42
|
+
id: NoteIdSchema,
|
|
43
|
+
expectedHash: HashSchema,
|
|
44
|
+
},
|
|
45
|
+
{ additionalProperties: false },
|
|
46
|
+
),
|
|
47
|
+
Type.Object({ action: Type.Literal("finish") }, { additionalProperties: false }),
|
|
48
|
+
])
|
|
49
|
+
|
|
50
|
+
export const WriteObservationSchema = Type.Object(
|
|
51
|
+
{
|
|
52
|
+
kind: Type.Literal("write"),
|
|
53
|
+
operation: Type.Enum(["add", "update", "archive", "succeed"]),
|
|
54
|
+
status: Type.Enum(["applied", "conflict", "refused"]),
|
|
55
|
+
vault: VaultSchema,
|
|
56
|
+
path: PathSchema,
|
|
57
|
+
detail: TextSchema,
|
|
58
|
+
},
|
|
59
|
+
{ additionalProperties: false },
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
export const RefusedObservationSchema = Type.Object(
|
|
63
|
+
{
|
|
64
|
+
kind: Type.Literal("refused"),
|
|
65
|
+
action: Type.Enum(["search", "get", "list", "add", "update", "archive", "succeed", "finish", "unparseable"]),
|
|
66
|
+
problems: Type.Array(TextSchema),
|
|
67
|
+
},
|
|
68
|
+
{ additionalProperties: false },
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
export const CaptureObservationSchema = Type.Union([
|
|
72
|
+
ObservationSchema,
|
|
73
|
+
WriteObservationSchema,
|
|
74
|
+
RefusedObservationSchema,
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
export const CaptureInputSchema = Type.Object(
|
|
78
|
+
{
|
|
79
|
+
context: AgentContextSchema,
|
|
80
|
+
transcriptDelta: Type.Array(
|
|
81
|
+
Type.Object({ role: Type.Enum(["user", "assistant"]), text: TextSchema }, { additionalProperties: false }),
|
|
82
|
+
{ minItems: 1 },
|
|
83
|
+
),
|
|
84
|
+
observations: Type.Array(CaptureObservationSchema),
|
|
85
|
+
explicitSaves: Type.Array(ReadObservationSchema),
|
|
86
|
+
limits: Type.Object(
|
|
87
|
+
{ maxBodyChars: Type.Integer({ minimum: 1 }), maxStatementChars: Type.Integer({ minimum: 1 }) },
|
|
88
|
+
{ additionalProperties: false },
|
|
89
|
+
),
|
|
90
|
+
},
|
|
91
|
+
{ additionalProperties: false },
|
|
92
|
+
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MIN_USER_MESSAGES_BEFORE_REVIEW } from "./constants.ts"
|
|
2
|
+
import type { CaptureCadenceSettings, CaptureTally, FinishedTurn, FlushMoment, TurnOutcome } from "./types.ts"
|
|
3
|
+
|
|
4
|
+
export function tallyUserMessage(tally: CaptureTally): CaptureTally {
|
|
5
|
+
return { ...tally, userMessages: tally.userMessages + 1 }
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function tallyTurn(
|
|
9
|
+
tally: CaptureTally,
|
|
10
|
+
turn: FinishedTurn,
|
|
11
|
+
settings: CaptureCadenceSettings | null,
|
|
12
|
+
): TurnOutcome {
|
|
13
|
+
const counted = { ...tally, turnsSinceReview: tally.turnsSinceReview + 1 }
|
|
14
|
+
if (!settings?.reviewEnabled || turn.reviewActive) return { tally: counted, review: false }
|
|
15
|
+
counted.toolCallsSinceReview += turn.toolCalls
|
|
16
|
+
const reached =
|
|
17
|
+
counted.turnsSinceReview >= settings.nudgeInterval || counted.toolCallsSinceReview >= settings.nudgeToolCalls
|
|
18
|
+
if (!reached || counted.userMessages < MIN_USER_MESSAGES_BEFORE_REVIEW) return { tally: counted, review: false }
|
|
19
|
+
return { tally: { ...counted, turnsSinceReview: 0, toolCallsSinceReview: 0 }, review: true }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function shouldFlush(tally: CaptureTally, settings: CaptureCadenceSettings, moment: FlushMoment): boolean {
|
|
23
|
+
if (tally.userMessages < settings.flushMinTurns) return false
|
|
24
|
+
if (moment === "compact") return settings.flushOnCompact
|
|
25
|
+
return settings.flushOnShutdown
|
|
26
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Static } from "typebox"
|
|
2
|
+
|
|
3
|
+
import type { Failed, Succeeded } from "#src/shared"
|
|
4
|
+
import type {
|
|
5
|
+
CaptureActionSchema,
|
|
6
|
+
CaptureDraftSchema,
|
|
7
|
+
CaptureInputSchema,
|
|
8
|
+
CaptureObservationSchema,
|
|
9
|
+
} from "./schemas.ts"
|
|
10
|
+
|
|
11
|
+
export interface CaptureCadenceSettings {
|
|
12
|
+
nudgeInterval: number
|
|
13
|
+
nudgeToolCalls: number
|
|
14
|
+
flushMinTurns: number
|
|
15
|
+
reviewEnabled: boolean
|
|
16
|
+
flushOnCompact: boolean
|
|
17
|
+
flushOnShutdown: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CaptureTally {
|
|
21
|
+
userMessages: number
|
|
22
|
+
turnsSinceReview: number
|
|
23
|
+
toolCallsSinceReview: number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface FinishedTurn {
|
|
27
|
+
toolCalls: number
|
|
28
|
+
reviewActive: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface TurnOutcome {
|
|
32
|
+
tally: CaptureTally
|
|
33
|
+
review: boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type FlushMoment = "compact" | "shutdown"
|
|
37
|
+
|
|
38
|
+
export type CaptureDraft = Static<typeof CaptureDraftSchema>
|
|
39
|
+
export type CaptureAction = Static<typeof CaptureActionSchema>
|
|
40
|
+
export type CaptureInput = Static<typeof CaptureInputSchema>
|
|
41
|
+
export type CaptureObservation = Static<typeof CaptureObservationSchema>
|
|
42
|
+
export type CaptureResult = Succeeded<CaptureAction> | Failed
|
|
43
|
+
export type TranscriptMessage = CaptureInput["transcriptDelta"][number]
|
|
44
|
+
|
|
45
|
+
export interface AddDiscriminant {
|
|
46
|
+
action: "add"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type CaptureAdd = Extract<CaptureAction, AddDiscriminant>
|