hippo-memory 1.71.0 → 2.0.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 +7 -5
- package/dist/agent-memories/apply.d.ts +0 -11
- package/dist/agent-memories/apply.js +11 -26
- package/dist/agent-memories/claude-code.js +1 -1
- package/dist/agent-memories/codex.js +1 -1
- package/dist/agent-memories/copilot.d.ts +1 -3
- package/dist/agent-memories/copilot.js +1 -17
- package/dist/agent-memories/project-folds.d.ts +10 -0
- package/dist/agent-memories/project-folds.js +34 -0
- package/dist/agent-memories/sync.js +8 -6
- package/dist/api/assemble.js +3 -2
- package/dist/api/audit.d.ts +30 -2
- package/dist/api/audit.js +48 -7
- package/dist/api/auth.d.ts +11 -9
- package/dist/api/auth.js +39 -40
- package/dist/api/auto-sleep.d.ts +5 -2
- package/dist/api/auto-sleep.js +7 -3
- package/dist/api/availability.js +2 -3
- package/dist/api/cards.d.ts +42 -0
- package/dist/api/cards.js +52 -0
- package/dist/api/conflicts.d.ts +28 -0
- package/dist/api/conflicts.js +61 -0
- package/dist/api/context-auto.js +4 -2
- package/dist/api/context-render.js +4 -3
- package/dist/api/context-select.js +15 -29
- package/dist/api/context.js +29 -18
- package/dist/api/continuity.d.ts +47 -0
- package/dist/api/continuity.js +66 -0
- package/dist/api/dormant.js +4 -2
- package/dist/api/drill-down.js +3 -2
- package/dist/api/embeddings.d.ts +17 -0
- package/dist/api/embeddings.js +28 -0
- package/dist/api/error-reply.d.ts +8 -0
- package/dist/api/error-reply.js +21 -0
- package/dist/api/forget.d.ts +7 -3
- package/dist/api/forget.js +24 -14
- package/dist/api/goals.d.ts +1 -1
- package/dist/api/goals.js +5 -9
- package/dist/api/graph.js +2 -1
- package/dist/api/index.d.ts +4 -2
- package/dist/api/index.js +4 -2
- package/dist/api/instruction-detect.js +5 -1
- package/dist/api/learn.d.ts +5 -1
- package/dist/api/learn.js +71 -44
- package/dist/api/ledger-db.d.ts +2 -6
- package/dist/api/ledger-db.js +4 -36
- package/dist/api/memories.d.ts +21 -1
- package/dist/api/memories.js +51 -1
- package/dist/api/objects.d.ts +1 -1
- package/dist/api/objects.js +2 -1
- package/dist/api/outcome.d.ts +5 -5
- package/dist/api/outcome.js +17 -16
- package/dist/api/pilot-arm.d.ts +1 -11
- package/dist/api/pilot-arm.js +5 -45
- package/dist/api/predictions.d.ts +3 -1
- package/dist/api/predictions.js +8 -1
- package/dist/api/projects.d.ts +21 -0
- package/dist/api/projects.js +24 -0
- package/dist/api/promote.d.ts +3 -3
- package/dist/api/promote.js +26 -28
- package/dist/api/prompt-hook.d.ts +17 -2
- package/dist/api/prompt-hook.js +45 -4
- package/dist/api/quarantine.js +2 -1
- package/dist/api/recall-cli.d.ts +3 -0
- package/dist/api/recall-cli.js +13 -4
- package/dist/api/recall-core.js +10 -5
- package/dist/api/recall-pipeline.js +23 -24
- package/dist/api/recall-request.js +1 -1
- package/dist/api/recall-types.d.ts +3 -1
- package/dist/api/recall.d.ts +0 -3
- package/dist/api/recall.js +51 -73
- package/dist/api/remember-local.d.ts +5 -2
- package/dist/api/remember-local.js +15 -7
- package/dist/api/remember.d.ts +7 -3
- package/dist/api/remember.js +19 -16
- package/dist/api/session-end.d.ts +46 -0
- package/dist/api/session-end.js +131 -0
- package/dist/api/sleep-run.d.ts +1 -1
- package/dist/api/sleep-run.js +16 -11
- package/dist/api/sleep.js +4 -3
- package/dist/api/status.d.ts +24 -0
- package/dist/api/status.js +40 -0
- package/dist/api/store-init.d.ts +4 -0
- package/dist/api/store-init.js +9 -0
- package/dist/api/tokens.js +2 -2
- package/dist/api/types.d.ts +3 -7
- package/dist/api/types.js +6 -1
- package/dist/capture/caller-session.d.ts +0 -3
- package/dist/capture/caller-session.js +1 -12
- package/dist/capture/capture-error.d.ts +2 -2
- package/dist/capture/capture-error.js +23 -18
- package/dist/capture/codex-patch.js +3 -1
- package/dist/capture/command.js +36 -95
- package/dist/capture/compact.js +10 -5
- package/dist/capture/compaction-items-caller.js +11 -20
- package/dist/capture/compaction-record.d.ts +7 -93
- package/dist/capture/compaction-record.js +29 -426
- package/dist/capture/compaction-spool.d.ts +7 -7
- package/dist/capture/compaction-spool.js +60 -51
- package/dist/capture/copilot-transcript.d.ts +2 -1
- package/dist/capture/copilot-transcript.js +2 -1
- package/dist/capture/extract.d.ts +5 -2
- package/dist/capture/extract.js +4 -3
- package/dist/capture/failure-caller.d.ts +1 -1
- package/dist/capture/failure-caller.js +21 -16
- package/dist/capture/failure-reading.d.ts +2 -1
- package/dist/capture/failure-reading.js +7 -9
- package/dist/capture/pre-compact-caller.js +5 -4
- package/dist/capture/session-digest.js +4 -3
- package/dist/capture/session-end-caller.js +3 -2
- package/dist/capture/session-worker.js +22 -10
- package/dist/capture/transcript.d.ts +2 -1
- package/dist/capture/transcript.js +6 -3
- package/dist/capture/working-state.d.ts +4 -2
- package/dist/capture/working-state.js +4 -2
- package/dist/cli/audit-prune.d.ts +0 -25
- package/dist/cli/audit-prune.js +1 -27
- package/dist/cli/audit.js +20 -20
- package/dist/cli/auth.d.ts +1 -1
- package/dist/cli/auth.js +16 -17
- package/dist/cli/briefs.d.ts +1 -4
- package/dist/cli/briefs.js +37 -292
- package/dist/cli/card.js +41 -33
- package/dist/cli/client.d.ts +6 -2
- package/dist/cli/client.js +37 -21
- package/dist/cli/compact-resume-payload.js +1 -1
- package/dist/cli/context.d.ts +1 -1
- package/dist/cli/context.js +13 -13
- package/dist/cli/continuity.d.ts +1 -1
- package/dist/cli/continuity.js +36 -39
- package/dist/cli/curate.d.ts +2 -2
- package/dist/cli/curate.js +32 -36
- package/dist/cli/dag.d.ts +1 -1
- package/dist/cli/dag.js +23 -8
- package/dist/cli/decisions.d.ts +0 -2
- package/dist/cli/decisions.js +7 -285
- package/dist/cli/eval.d.ts +1 -1
- package/dist/cli/eval.js +12 -13
- package/dist/cli/explain.d.ts +1 -1
- package/dist/cli/explain.js +21 -25
- package/dist/cli/flag-values.js +16 -6
- package/dist/cli/flags.d.ts +0 -289
- package/dist/cli/flags.js +3 -138
- package/dist/cli/graph.d.ts +3 -0
- package/dist/cli/graph.js +83 -0
- package/dist/cli/hook-runtime.d.ts +6 -6
- package/dist/cli/hook-runtime.js +9 -36
- package/dist/cli/incidents.d.ts +3 -0
- package/dist/cli/incidents.js +112 -0
- package/dist/cli/init.d.ts +1 -1
- package/dist/cli/init.js +28 -19
- package/dist/cli/install-steps.d.ts +2 -1
- package/dist/cli/install-steps.js +11 -3
- package/dist/cli/last-sleep.js +1 -1
- package/dist/cli/maintenance.d.ts +3 -3
- package/dist/cli/maintenance.js +29 -30
- package/dist/cli/notes.d.ts +2 -0
- package/dist/cli/notes.js +41 -0
- package/dist/cli/object-verbs.d.ts +2 -2
- package/dist/cli/object-verbs.js +4 -4
- package/dist/cli/open-browser.d.ts +14 -0
- package/dist/cli/open-browser.js +26 -0
- package/dist/cli/playbooks.d.ts +3 -4
- package/dist/cli/playbooks.js +126 -290
- package/dist/cli/predictions.d.ts +3 -0
- package/dist/cli/predictions.js +174 -0
- package/dist/cli/print.js +2 -1
- package/dist/cli/projects.js +30 -22
- package/dist/cli/quality-repair-once.d.ts +1 -1
- package/dist/cli/quality-repair-once.js +6 -5
- package/dist/cli/recall.js +13 -7
- package/dist/cli/refine-llm.js +18 -17
- package/dist/cli/remember.js +17 -17
- package/dist/cli/scheduler.js +2 -1
- package/dist/cli/serve.js +11 -6
- package/dist/cli/session-hooks.d.ts +1 -5
- package/dist/cli/session-hooks.js +89 -168
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.js +17 -10
- package/dist/cli/shared.d.ts +2 -6
- package/dist/cli/shared.js +9 -29
- package/dist/cli/sleep-render.js +6 -3
- package/dist/cli/sleep.js +6 -37
- package/dist/cli/status.d.ts +3 -3
- package/dist/cli/status.js +32 -35
- package/dist/cli/transfer.d.ts +3 -3
- package/dist/cli/transfer.js +64 -43
- package/dist/cli/usage.d.ts +1 -80
- package/dist/cli/usage.js +2 -696
- package/dist/cli/verb-row.d.ts +34 -0
- package/dist/cli/verb-row.js +6 -0
- package/dist/cli/verbs/health.d.ts +27 -0
- package/dist/cli/verbs/health.js +234 -0
- package/dist/cli/verbs/memory.d.ts +16 -0
- package/dist/cli/verbs/memory.js +236 -0
- package/dist/cli/verbs/objects.d.ts +20 -0
- package/dist/cli/verbs/objects.js +257 -0
- package/dist/cli/verbs/sessions.d.ts +31 -0
- package/dist/cli/verbs/sessions.js +314 -0
- package/dist/cli/verbs.d.ts +81 -0
- package/dist/cli/verbs.js +7 -0
- package/dist/cli/versioned-verbs.d.ts +51 -0
- package/dist/cli/versioned-verbs.js +79 -0
- package/dist/cli.d.ts +1 -272
- package/dist/cli.js +24 -315
- package/dist/connectors/dlq.d.ts +39 -3
- package/dist/connectors/dlq.js +39 -4
- package/dist/connectors/github/backfill.js +12 -3
- package/dist/connectors/github/deletion.js +2 -1
- package/dist/connectors/github/dlq.js +31 -73
- package/dist/connectors/github/ingest.d.ts +2 -6
- package/dist/connectors/github/ingest.js +5 -29
- package/dist/connectors/github/tenant-routing.js +2 -1
- package/dist/connectors/github/webhook.d.ts +2 -1
- package/dist/connectors/github/webhook.js +35 -2
- package/dist/connectors/ingest.d.ts +10 -0
- package/dist/connectors/ingest.js +29 -0
- package/dist/connectors/slack/deletion.js +2 -1
- package/dist/connectors/slack/dlq.js +49 -71
- package/dist/connectors/slack/ingest.d.ts +2 -6
- package/dist/connectors/slack/ingest.js +4 -28
- package/dist/connectors/slack/tenant-routing.js +2 -1
- package/dist/connectors/slack/webhook.d.ts +2 -1
- package/dist/connectors/slack/webhook.js +2 -1
- package/dist/consolidate/conflicts.js +2 -2
- package/dist/consolidate/dag.js +29 -18
- package/dist/consolidate/dedupe.d.ts +7 -0
- package/dist/consolidate/dedupe.js +6 -4
- package/dist/consolidate/llm-passes.js +45 -19
- package/dist/consolidate/memory-value.js +3 -2
- package/dist/consolidate/merge.js +8 -8
- package/dist/consolidate/physics-pass.d.ts +6 -1
- package/dist/consolidate/physics-pass.js +26 -6
- package/dist/consolidate/replay.js +11 -4
- package/dist/consolidate/sleep.js +9 -6
- package/dist/consolidate/traces.js +5 -5
- package/dist/core/ablation.d.ts +10 -0
- package/dist/core/ablation.js +12 -0
- package/dist/{sharing/scope.d.ts → core/active-scope.d.ts} +1 -1
- package/dist/{sharing/scope.js → core/active-scope.js} +1 -1
- package/dist/core/ambient.d.ts +4 -0
- package/dist/core/ambient.js +39 -18
- package/dist/core/api-errors.d.ts +16 -0
- package/dist/core/api-errors.js +20 -0
- package/dist/core/card.js +3 -1
- package/dist/core/compaction-timing.d.ts +7 -0
- package/dist/core/compaction-timing.js +9 -0
- package/dist/core/config.d.ts +1 -1
- package/dist/core/config.js +22 -18
- package/dist/core/cosine.d.ts +3 -0
- package/dist/core/cosine.js +19 -0
- package/dist/{store → core}/markdown.d.ts +1 -1
- package/dist/{store → core}/markdown.js +4 -4
- package/dist/core/memory-audit.d.ts +17 -0
- package/dist/core/memory-audit.js +54 -0
- package/dist/core/memory.d.ts +14 -8
- package/dist/core/memory.js +35 -23
- package/dist/{consolidate → core}/merged-row.d.ts +1 -1
- package/dist/{consolidate → core}/merged-row.js +1 -1
- package/dist/core/physics.d.ts +3 -1
- package/dist/core/physics.js +23 -18
- package/dist/core/prediction.d.ts +3 -0
- package/dist/core/prediction.js +6 -0
- package/dist/core/project-identity.d.ts +3 -0
- package/dist/core/project-identity.js +12 -2
- package/dist/{store → core}/recall-scope.d.ts +1 -10
- package/dist/{store → core}/recall-scope.js +2 -19
- package/dist/core/search-types.d.ts +1 -1
- package/dist/dashboard/dashboard-actions.d.ts +2 -2
- package/dist/dashboard/dashboard-actions.js +5 -5
- package/dist/dashboard/dashboard-queries.js +2 -7
- package/dist/dashboard/dashboard-snapshot.js +1 -3
- package/dist/dashboard/dashboard.js +16 -5
- package/dist/db/busy.d.ts +2 -7
- package/dist/db/busy.js +21 -26
- package/dist/db/connect.d.ts +2 -2
- package/dist/db/connect.js +7 -7
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.js +3 -3
- package/dist/db/migrate.js +14 -7
- package/dist/db/migrations/index.d.ts +1 -1
- package/dist/db/migrations/index.js +3 -1
- package/dist/db/migrations/v11.js +1 -0
- package/dist/db/migrations/v14.js +1 -0
- package/dist/db/migrations/v55.d.ts +3 -0
- package/dist/db/migrations/v55.js +17 -0
- package/dist/db/open.d.ts +0 -2
- package/dist/db/open.js +6 -10
- package/dist/db/physics-state.d.ts +0 -4
- package/dist/db/physics-state.js +7 -33
- package/dist/db/request-stores.d.ts +1 -0
- package/dist/db/request-stores.js +2 -1
- package/dist/db/tables.d.ts +2 -0
- package/dist/db/tables.js +6 -2
- package/dist/db/vector-store.js +19 -5
- package/dist/db/wal-checkpointer.js +2 -1
- package/dist/doctor.d.ts +3 -0
- package/dist/doctor.js +18 -15
- package/dist/embeddings/local.d.ts +62 -0
- package/dist/embeddings/local.js +146 -0
- package/dist/{store/embeddings → embeddings}/provider.d.ts +5 -2
- package/dist/{store/embeddings → embeddings}/provider.js +19 -25
- package/dist/embeddings/transformers.d.ts +26 -0
- package/dist/embeddings/transformers.js +89 -0
- package/dist/entry/session-text.d.ts +1 -1
- package/dist/entry/session-text.js +1 -1
- package/dist/entry/store-kit.d.ts +37 -0
- package/dist/entry/store-kit.js +25 -0
- package/dist/entry/testing.d.ts +6 -0
- package/dist/entry/testing.js +7 -0
- package/dist/eval/eval-suite.js +17 -11
- package/dist/eval/eval.js +1 -1
- package/dist/eval/judgment.js +12 -5
- package/dist/graph/extract.js +3 -3
- package/dist/graph/recall.js +1 -1
- package/dist/graph/view.js +13 -5
- package/dist/graph/write.d.ts +1 -1
- package/dist/graph/write.js +9 -9
- package/dist/hooks/codex-session.js +3 -2
- package/dist/hooks/codex-wrapper.js +2 -1
- package/dist/hooks/json-hooks.js +10 -4
- package/dist/hooks/opencode.js +8 -5
- package/dist/hooks/shared.d.ts +0 -6
- package/dist/hooks/shared.js +4 -15
- package/dist/importers/core.js +4 -4
- package/dist/importers/sources.js +5 -4
- package/dist/importers/vault.d.ts +1 -1
- package/dist/importers/vault.js +25 -23
- package/dist/index.d.ts +5 -4
- package/dist/index.js +4 -3
- package/dist/learn/autolearn.d.ts +15 -3
- package/dist/learn/autolearn.js +38 -16
- package/dist/learn/churn-git.js +13 -4
- package/dist/learn/extract.d.ts +3 -2
- package/dist/learn/extract.js +7 -5
- package/dist/learn/forward-claim-detector.js +4 -2
- package/dist/learn/invalidation.d.ts +2 -1
- package/dist/learn/invalidation.js +18 -9
- package/dist/mcp/admin-tools.d.ts +2 -2
- package/dist/mcp/admin-tools.js +27 -48
- package/dist/mcp/format.js +3 -2
- package/dist/mcp/framing.d.ts +1 -0
- package/dist/mcp/framing.js +1 -1
- package/dist/mcp/memory-tools.d.ts +1 -1
- package/dist/mcp/memory-tools.js +8 -9
- package/dist/mcp/protocol.d.ts +11 -7
- package/dist/mcp/protocol.js +25 -12
- package/dist/mcp/recall-tools.js +12 -9
- package/dist/mcp/request.js +22 -20
- package/dist/mcp/stdio.js +37 -16
- package/dist/mcp/tool-args.js +2 -1
- package/dist/mcp/tools.js +44 -21
- package/dist/objects/customer-notes.d.ts +2 -2
- package/dist/objects/decisions.d.ts +2 -2
- package/dist/objects/descriptor.d.ts +1 -1
- package/dist/objects/incidents.d.ts +2 -2
- package/dist/objects/lifecycle.d.ts +1 -1
- package/dist/objects/lifecycle.js +2 -1
- package/dist/objects/policies.d.ts +2 -2
- package/dist/objects/policies.js +2 -1
- package/dist/objects/processes.d.ts +2 -2
- package/dist/objects/project-briefs.d.ts +2 -2
- package/dist/objects/project-briefs.js +2 -3
- package/dist/objects/skills.d.ts +2 -2
- package/dist/postinstall.js +1 -1
- package/dist/rerankers/clef.js +3 -6
- package/dist/rerankers/cross-encoder.d.ts +31 -2
- package/dist/rerankers/cross-encoder.js +71 -98
- package/dist/rerankers/index.js +5 -4
- package/dist/rerankers/jev.js +2 -4
- package/dist/rerankers/outage-warning.d.ts +3 -1
- package/dist/rerankers/outage-warning.js +5 -3
- package/dist/search/bm25-search.js +1 -1
- package/dist/search/boosts.js +1 -1
- package/dist/search/embed-memories.d.ts +12 -0
- package/dist/search/embed-memories.js +389 -0
- package/dist/search/engine.d.ts +8 -0
- package/dist/search/engine.js +10 -0
- package/dist/search/goal-boost.d.ts +1 -1
- package/dist/search/goal-boost.js +6 -3
- package/dist/search/hybrid.d.ts +9 -2
- package/dist/search/hybrid.js +9 -4
- package/dist/search/physics-search.d.ts +6 -3
- package/dist/search/physics-search.js +22 -15
- package/dist/search/rerank.js +1 -1
- package/dist/search/vector.d.ts +8 -6
- package/dist/search/vector.js +14 -17
- package/dist/server/auth.d.ts +3 -1
- package/dist/server/auth.js +24 -15
- package/dist/server/boot.d.ts +2 -1
- package/dist/server/boot.js +34 -84
- package/dist/server/client-ip.d.ts +9 -6
- package/dist/server/client-ip.js +36 -17
- package/dist/server/deadline.d.ts +0 -2
- package/dist/server/deadline.js +1 -7
- package/dist/server/defaults.d.ts +1 -0
- package/dist/server/defaults.js +1 -0
- package/dist/server/mcp-http.js +16 -11
- package/dist/server/request.js +7 -2
- package/dist/server/route-checks.d.ts +7 -0
- package/dist/server/route-checks.js +42 -0
- package/dist/server/route-table.d.ts +9 -8
- package/dist/server/route-table.js +127 -133
- package/dist/server/routes/admin.d.ts +8 -8
- package/dist/server/routes/admin.js +13 -21
- package/dist/server/routes/customer-notes.d.ts +6 -6
- package/dist/server/routes/customer-notes.js +1 -2
- package/dist/server/routes/decisions.d.ts +6 -6
- package/dist/server/routes/decisions.js +2 -4
- package/dist/server/routes/incidents.d.ts +6 -6
- package/dist/server/routes/incidents.js +2 -5
- package/dist/server/routes/memories.d.ts +9 -9
- package/dist/server/routes/memories.js +19 -40
- package/dist/server/routes/object-routes.d.ts +6 -6
- package/dist/server/routes/object-routes.js +4 -7
- package/dist/server/routes/policies.d.ts +7 -7
- package/dist/server/routes/policies.js +2 -4
- package/dist/server/routes/predictions.d.ts +6 -6
- package/dist/server/routes/predictions.js +9 -13
- package/dist/server/routes/processes.d.ts +6 -6
- package/dist/server/routes/processes.js +1 -2
- package/dist/server/routes/project-briefs.d.ts +7 -7
- package/dist/server/routes/project-briefs.js +2 -4
- package/dist/server/routes/recall.d.ts +5 -5
- package/dist/server/routes/recall.js +6 -10
- package/dist/server/routes/skills.d.ts +7 -7
- package/dist/server/routes/skills.js +2 -4
- package/dist/server/server-detect.d.ts +7 -1
- package/dist/server/server-detect.js +36 -11
- package/dist/server/sleep-child.js +26 -7
- package/dist/server/sleep-offload.d.ts +11 -5
- package/dist/server/sleep-offload.js +17 -11
- package/dist/server/tls.d.ts +7 -2
- package/dist/server/tls.js +17 -5
- package/dist/server/types.d.ts +29 -12
- package/dist/server/validation.d.ts +1 -2
- package/dist/server/validation.js +6 -11
- package/dist/server.d.ts +4 -40
- package/dist/server.js +3 -29
- package/dist/sharing/global-store.d.ts +4 -5
- package/dist/sharing/global-store.js +8 -13
- package/dist/sharing/global-sync.js +38 -45
- package/dist/sharing/project-merge.d.ts +7 -14
- package/dist/sharing/project-merge.js +57 -121
- package/dist/sharing/search-both.js +10 -3
- package/dist/sharing/share.d.ts +2 -0
- package/dist/sharing/share.js +39 -38
- package/dist/store/ambient.js +7 -7
- package/dist/store/audit-event.d.ts +1 -1
- package/dist/store/audit.d.ts +0 -16
- package/dist/store/audit.js +4 -55
- package/dist/store/auth.d.ts +4 -2
- package/dist/store/auth.js +7 -3
- package/dist/store/candidates.d.ts +3 -2
- package/dist/store/candidates.js +59 -30
- package/dist/store/capture-write.d.ts +17 -0
- package/dist/store/capture-write.js +35 -0
- package/dist/store/cards.js +6 -5
- package/dist/store/compaction-caller.d.ts +18 -0
- package/dist/store/compaction-caller.js +29 -0
- package/dist/store/compactions-record.d.ts +115 -0
- package/dist/store/compactions-record.js +418 -0
- package/dist/store/compactions.js +6 -4
- package/dist/store/conflicts.d.ts +7 -1
- package/dist/store/conflicts.js +13 -9
- package/dist/store/connectors/dlq.d.ts +10 -0
- package/dist/store/connectors/dlq.js +33 -0
- package/dist/store/connectors/event-log.d.ts +13 -0
- package/dist/store/connectors/event-log.js +24 -0
- package/dist/store/connectors/github.d.ts +7 -9
- package/dist/store/connectors/github.js +35 -60
- package/dist/store/connectors/slack.d.ts +2 -11
- package/dist/store/connectors/slack.js +24 -57
- package/dist/store/dashboard-reads.js +8 -6
- package/dist/store/delete-and-batch.d.ts +6 -0
- package/dist/store/delete-and-batch.js +40 -6
- package/dist/store/delivery-recorder.d.ts +12 -5
- package/dist/store/delivery-recorder.js +13 -11
- package/dist/store/descendant-page.js +8 -4
- package/dist/store/dormant.d.ts +1 -1
- package/dist/store/dormant.js +10 -4
- package/dist/store/embeddings/index.d.ts +2 -12
- package/dist/store/embeddings/index.js +5 -374
- package/dist/store/entry-reads.d.ts +35 -4
- package/dist/store/entry-reads.js +86 -19
- package/dist/store/entry-row.js +9 -2
- package/dist/store/entry-writes.d.ts +15 -12
- package/dist/store/entry-writes.js +54 -22
- package/dist/store/failure-log-at.d.ts +8 -0
- package/dist/store/failure-log-at.js +16 -0
- package/dist/store/failure-log.d.ts +2 -2
- package/dist/store/failure-log.js +5 -3
- package/dist/{trust → store}/gated-write.d.ts +3 -1
- package/dist/{trust → store}/gated-write.js +7 -5
- package/dist/store/goals.js +22 -19
- package/dist/store/graph-reads.js +9 -6
- package/dist/store/graph-view-rows.js +2 -1
- package/dist/store/graph-writes.d.ts +6 -6
- package/dist/store/graph-writes.js +48 -71
- package/dist/store/half-life.js +2 -2
- package/dist/store/handoffs.d.ts +10 -4
- package/dist/store/handoffs.js +10 -9
- package/dist/store/index-and-stats.js +2 -2
- package/dist/store/index.d.ts +2 -2
- package/dist/store/index.js +1 -1
- package/dist/store/key-writes.js +1 -1
- package/dist/store/ledger-turn.d.ts +9 -0
- package/dist/store/ledger-turn.js +38 -0
- package/dist/store/mirrors.js +19 -10
- package/dist/store/open.d.ts +2 -5
- package/dist/store/open.js +42 -54
- package/dist/store/pilot-arm.d.ts +12 -0
- package/dist/store/pilot-arm.js +42 -0
- package/dist/store/port.d.ts +68 -6
- package/dist/store/port.js +8 -0
- package/dist/store/predictions.d.ts +1 -2
- package/dist/store/predictions.js +3 -6
- package/dist/store/project-tags.d.ts +62 -0
- package/dist/store/project-tags.js +67 -0
- package/dist/store/quality-repair.js +1 -1
- package/dist/store/quarantine.js +2 -1
- package/dist/store/recall-trace.d.ts +2 -0
- package/dist/store/recall-trace.js +20 -3
- package/dist/store/rejected-values.js +16 -10
- package/dist/store/rejection-probe.d.ts +4 -0
- package/dist/store/rejection-probe.js +19 -0
- package/dist/store/rejection.d.ts +0 -17
- package/dist/store/rejection.js +1 -21
- package/dist/store/rows.js +2 -2
- package/dist/store/rule-sql.d.ts +11 -0
- package/dist/store/rule-sql.js +31 -6
- package/dist/store/search-rows.d.ts +5 -5
- package/dist/store/search-rows.js +18 -16
- package/dist/store/sessions.js +4 -2
- package/dist/store/set-aside.d.ts +14 -0
- package/dist/store/set-aside.js +23 -0
- package/dist/store/sqlite/busy.d.ts +3 -0
- package/dist/store/sqlite/busy.js +8 -0
- package/dist/store/sqlite/connector-events-group.js +4 -7
- package/dist/store/sqlite/connector-writes-group.js +6 -4
- package/dist/store/sqlite/entry-writes-group.d.ts +3 -3
- package/dist/store/sqlite/entry-writes-group.js +3 -3
- package/dist/store/sqlite/error-codec.js +4 -3
- package/dist/store/sqlite/executor.js +10 -4
- package/dist/store/sqlite/graph-reads-group.js +1 -1
- package/dist/store/sqlite/held-connection.d.ts +11 -0
- package/dist/store/sqlite/held-connection.js +41 -0
- package/dist/store/sqlite/last-recall-group.d.ts +13 -0
- package/dist/store/sqlite/last-recall-group.js +57 -0
- package/dist/store/sqlite/local.d.ts +0 -17
- package/dist/store/sqlite/local.js +0 -31
- package/dist/store/sqlite/maintenance-groups.d.ts +6 -0
- package/dist/store/sqlite/maintenance-groups.js +60 -0
- package/dist/store/sqlite/object-rows.d.ts +1 -1
- package/dist/store/sqlite/objects-group.d.ts +1 -1
- package/dist/store/sqlite/objects-group.js +15 -7
- package/dist/store/sqlite/store.d.ts +1 -8
- package/dist/store/sqlite/store.js +13 -22
- package/dist/store/summaries.d.ts +10 -3
- package/dist/store/summaries.js +54 -11
- package/dist/store/token-ledger-rows.js +3 -2
- package/dist/store/token-ledger.d.ts +0 -7
- package/dist/store/token-ledger.js +0 -35
- package/dist/store/vector-index.js +8 -4
- package/dist/support-bundle.js +2 -3
- package/dist/trust/reject-flow.js +2 -2
- package/dist/util/agent-homes.d.ts +15 -0
- package/dist/util/agent-homes.js +34 -0
- package/dist/util/anthropic-messages.d.ts +6 -1
- package/dist/util/anthropic-messages.js +26 -7
- package/dist/util/atomic-write.d.ts +5 -2
- package/dist/util/atomic-write.js +12 -8
- package/dist/util/chunked.d.ts +3 -0
- package/dist/util/chunked.js +10 -0
- package/dist/util/ellipsize.d.ts +3 -0
- package/dist/util/ellipsize.js +5 -0
- package/dist/util/env.d.ts +12 -2
- package/dist/util/env.js +12 -2
- package/dist/util/format.d.ts +5 -0
- package/dist/util/format.js +10 -0
- package/dist/util/hook-payload.d.ts +8 -0
- package/dist/util/hook-payload.js +37 -0
- package/dist/util/http-retry.d.ts +6 -0
- package/dist/util/http-retry.js +43 -5
- package/dist/util/http-util.d.ts +0 -8
- package/dist/util/http-util.js +10 -21
- package/dist/util/limits.d.ts +7 -0
- package/dist/util/limits.js +14 -0
- package/dist/util/log.d.ts +4 -0
- package/dist/util/log.js +9 -0
- package/dist/util/request-scope.d.ts +9 -3
- package/dist/util/request-scope.js +18 -9
- package/dist/util/secret-detect.js +6 -1
- package/dist/util/spawn-argv.d.ts +9 -0
- package/dist/util/spawn-argv.js +57 -0
- package/dist/util/sql.d.ts +3 -0
- package/dist/util/sql.js +6 -0
- package/dist/util/sqlite-blocked.d.ts +2 -0
- package/dist/util/sqlite-blocked.js +5 -0
- package/dist/util/stream-tee.d.ts +3 -0
- package/dist/util/stream-tee.js +35 -0
- package/dist/util/time.d.ts +4 -0
- package/dist/util/time.js +4 -0
- package/dist/util/vector-codec.d.ts +4 -0
- package/dist/util/vector-codec.js +15 -0
- package/dist/util/version.d.ts +1 -1
- package/dist/util/version.js +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -2
- package/dist/api/on-store.d.ts +0 -16
- package/dist/api/on-store.js +0 -38
- package/dist/store/embeddings/local.d.ts +0 -15
- package/dist/store/embeddings/local.js +0 -175
- /package/dist/{cli → api}/correction-latency.d.ts +0 -0
- /package/dist/{cli → api}/correction-latency.js +0 -0
- /package/dist/{cli → api}/provenance-coverage.d.ts +0 -0
- /package/dist/{cli → api}/provenance-coverage.js +0 -0
- /package/dist/{store → core}/object-types.d.ts +0 -0
- /package/dist/{store → core}/object-types.js +0 -0
- /package/dist/{capture → util}/compaction-items.d.ts +0 -0
- /package/dist/{capture → util}/compaction-items.js +0 -0
- /package/dist/{store → util}/yaml.d.ts +0 -0
- /package/dist/{store → util}/yaml.js +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync, unlinkSync, renameSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { envHealthProbeMs } from '../util/env.js';
|
|
4
|
+
import { errorCode, errorFields, errorMessage, log } from '../util/log.js';
|
|
4
5
|
// Pidfile sits directly inside hippoRoot (the `.hippo` directory itself, as for openHippoDb), i.e. `${hippoRoot}/server.pid`.
|
|
5
6
|
const PIDFILE = 'server.pid';
|
|
6
7
|
/** How long detectServer waits for the `/health` probe before treating the pidfile as stale; short because it fires only when a pidfile exists with a live
|
|
@@ -11,6 +12,15 @@ const HEALTH_PROBE_TIMEOUT_MS = 300;
|
|
|
11
12
|
const HEALTH_BODY_MAX_BYTES = 64 * 1024;
|
|
12
13
|
/** Loopback hosts a recorded pidfile url may point at (serve() only binds these); any other host is malformed or forged and is not probed. */
|
|
13
14
|
const PIDFILE_LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
|
|
15
|
+
/** The pidfile names a live process on loopback that did not answer /health in time: most likely a busy server, so a caller must neither
|
|
16
|
+
* bypass it with a second writer nor start another server beside it. */
|
|
17
|
+
export class ServerUnresponsiveError extends Error {
|
|
18
|
+
constructor(info, probeMs, options) {
|
|
19
|
+
super(`a hippo server (pid ${info.pid}) is recorded at ${info.url} but did not answer /health within ${probeMs} ms; it may be busy. ` +
|
|
20
|
+
'Retry shortly, raise HIPPO_HEALTH_PROBE_MS, or stop that server.', options);
|
|
21
|
+
this.name = 'ServerUnresponsiveError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
14
24
|
/** False when the pidfile's pid is dead or its url could not be one serve() wrote. */
|
|
15
25
|
function isLiveLoopbackTarget(info) {
|
|
16
26
|
// Signal 0 throws if the pid is dead or owned by another user we cannot signal; either way, treat as stale.
|
|
@@ -56,14 +66,23 @@ async function readCappedBody(body) {
|
|
|
56
66
|
raw += decoder.decode();
|
|
57
67
|
return raw;
|
|
58
68
|
}
|
|
59
|
-
/** True when
|
|
69
|
+
/** True when fetch failed because nothing listens on the port (the error or its cause, or any address tried, is ECONNREFUSED). */
|
|
70
|
+
function isConnectionRefused(err) {
|
|
71
|
+
if (errorCode(err) === 'ECONNREFUSED')
|
|
72
|
+
return true;
|
|
73
|
+
const cause = err instanceof Error ? err.cause : undefined;
|
|
74
|
+
if (errorCode(cause) === 'ECONNREFUSED')
|
|
75
|
+
return true;
|
|
76
|
+
return cause instanceof AggregateError && cause.errors.length > 0 && cause.errors.every((e) => errorCode(e) === 'ECONNREFUSED');
|
|
77
|
+
}
|
|
78
|
+
/** True when /health on info.url reports the pidfile's started_at; unlinks the pidfile on any definitive mismatch and throws ServerUnresponsiveError on a
|
|
79
|
+
* probe timeout. */
|
|
60
80
|
async function healthMatchesPidfile(hippoRoot, info) {
|
|
61
|
-
//
|
|
62
|
-
//
|
|
81
|
+
// Refusal, non-200 or a malformed body unlink the pidfile as stale. A timeout proves neither a dead server nor this one, so it keeps the pidfile and throws.
|
|
82
|
+
// Any other error keeps it and warns.
|
|
83
|
+
const probeMs = envHealthProbeMs() ?? HEALTH_PROBE_TIMEOUT_MS;
|
|
63
84
|
try {
|
|
64
|
-
const res = await fetch(`${info.url}/health`, {
|
|
65
|
-
signal: AbortSignal.timeout(envHealthProbeMs() ?? HEALTH_PROBE_TIMEOUT_MS),
|
|
66
|
-
});
|
|
85
|
+
const res = await fetch(`${info.url}/health`, { signal: AbortSignal.timeout(probeMs) });
|
|
67
86
|
if (!res.ok || !res.body) {
|
|
68
87
|
removePidfile(hippoRoot);
|
|
69
88
|
return false;
|
|
@@ -81,16 +100,21 @@ async function healthMatchesPidfile(hippoRoot, info) {
|
|
|
81
100
|
return true;
|
|
82
101
|
}
|
|
83
102
|
catch (err) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
103
|
+
if (err instanceof Error && err.name === 'TimeoutError')
|
|
104
|
+
throw new ServerUnresponsiveError(info, probeMs, { cause: err });
|
|
105
|
+
// A refusal or a non-JSON body proves no hippo server answers there; any other failure may be a live server, so the file stays.
|
|
106
|
+
if (isConnectionRefused(err) || err instanceof SyntaxError) {
|
|
87
107
|
removePidfile(hippoRoot);
|
|
88
108
|
}
|
|
109
|
+
else {
|
|
110
|
+
log.warn(`server pidfile ${join(hippoRoot, PIDFILE)} kept: the /health probe failed (${errorMessage(err)})`, errorFields(err));
|
|
111
|
+
}
|
|
89
112
|
return false;
|
|
90
113
|
}
|
|
91
114
|
}
|
|
92
115
|
/** Returns the pidfile's ServerInfo if a live hippo server answers on the recorded url, else null (best-effort unlinking of missing/stale/malformed pidfiles).
|
|
93
|
-
* `process.kill(pid, 0)` rules out dead pids; GET /health must then return the pidfile's `started_at` (pids get reused). Probes only if the pid is live.
|
|
116
|
+
* `process.kill(pid, 0)` rules out dead pids; GET /health must then return the pidfile's `started_at` (pids get reused). Probes only if the pid is live.
|
|
117
|
+
* Throws ServerUnresponsiveError when that probe times out. */
|
|
94
118
|
export async function detectServer(hippoRoot) {
|
|
95
119
|
const path = join(hippoRoot, PIDFILE);
|
|
96
120
|
if (!existsSync(path))
|
|
@@ -99,7 +123,8 @@ export async function detectServer(hippoRoot) {
|
|
|
99
123
|
try {
|
|
100
124
|
info = JSON.parse(readFileSync(path, 'utf8'));
|
|
101
125
|
}
|
|
102
|
-
catch {
|
|
126
|
+
catch (err) {
|
|
127
|
+
log.warn(`server pidfile ${path} is unreadable (${errorMessage(err)}); removing it`);
|
|
103
128
|
removePidfile(hippoRoot);
|
|
104
129
|
return null;
|
|
105
130
|
}
|
|
@@ -1,19 +1,38 @@
|
|
|
1
|
-
// Entry of the process that runs one POST /v1/sleep; sleep-offload.ts starts it and nothing imports it.
|
|
2
|
-
// The sleep
|
|
1
|
+
// Entry of the process that runs one POST /v1/sleep or MCP auto-sleep; sleep-offload.ts starts it and nothing imports it.
|
|
2
|
+
// The sleep modules alone: the api barrel loads far more than one sleep needs, and every sleep pays for the start.
|
|
3
3
|
import { sleep } from '../api/sleep.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { consolidate } from '../consolidate/sleep.js';
|
|
5
|
+
import { runWithRequestStores, SERVER_DB_WAIT_MS } from '../db/index.js';
|
|
6
|
+
import { isStoreBusy } from '../store/sqlite/busy.js';
|
|
7
|
+
import { errorFields, errorMessage, log } from '../util/log.js';
|
|
6
8
|
function failed(err) {
|
|
7
9
|
return { ok: false, busy: isStoreBusy(err), message: errorMessage(err), stack: err instanceof Error ? err.stack : undefined };
|
|
8
10
|
}
|
|
11
|
+
/** Resolves to the exit code once the channel has taken the reply, or failed to. */
|
|
12
|
+
function sendReply(reply) {
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
process.send?.(reply, (sendErr) => {
|
|
15
|
+
if (sendErr)
|
|
16
|
+
log.error(`sleep child: sending the reply failed: ${errorMessage(sendErr)}`, errorFields(sendErr));
|
|
17
|
+
resolve(sendErr ? 1 : 0);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
9
21
|
process.once('message', (message) => {
|
|
10
22
|
// SAFETY: sleep-offload.ts is the only writer on this channel and sends exactly one SleepJob.
|
|
11
23
|
const job = message;
|
|
12
|
-
const
|
|
24
|
+
const work = () => job.kind === 'consolidate'
|
|
25
|
+
? consolidate(job.hippoRoot)
|
|
26
|
+
: sleep({ hippoRoot: job.hippoRoot, tenantId: job.tenantId, actor: job.actor }, job.opts);
|
|
13
27
|
// The server's own request scope and lock wait, so a busy store answers as it did when sleep ran in the server.
|
|
14
|
-
runWithRequestStores(
|
|
28
|
+
runWithRequestStores(work, { busyWaitMs: SERVER_DB_WAIT_MS })
|
|
15
29
|
.then((result) => ({ ok: true, result }), failed)
|
|
16
30
|
// Exit only once the reply is written, or the parent could see the process end first.
|
|
17
|
-
.then(
|
|
31
|
+
.then(sendReply)
|
|
32
|
+
.catch((err) => {
|
|
33
|
+
log.error(`sleep child: the reply could not be sent: ${errorMessage(err)}`, errorFields(err));
|
|
34
|
+
return 1;
|
|
35
|
+
})
|
|
36
|
+
.then((code) => process.exit(code));
|
|
18
37
|
});
|
|
19
38
|
//# sourceMappingURL=sleep-child.js.map
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { type Actor, type Context, type SleepOpts, type SleepResult } from '../api/index.js';
|
|
2
|
-
/** What the child needs to rebuild the request's context
|
|
3
|
-
export
|
|
2
|
+
/** What the child needs to rebuild the request's context (the store handle itself cannot cross a process boundary), or the store an auto-sleep consolidates. */
|
|
3
|
+
export type SleepJob = {
|
|
4
|
+
readonly kind: 'sleep';
|
|
4
5
|
readonly hippoRoot: string;
|
|
5
6
|
readonly tenantId: string;
|
|
6
7
|
readonly actor: Actor;
|
|
7
8
|
readonly opts: SleepOpts;
|
|
8
|
-
}
|
|
9
|
-
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'consolidate';
|
|
11
|
+
readonly hippoRoot: string;
|
|
12
|
+
};
|
|
13
|
+
export type SleepReply<R = SleepResult> = {
|
|
10
14
|
readonly ok: true;
|
|
11
|
-
readonly result:
|
|
15
|
+
readonly result: R;
|
|
12
16
|
} | {
|
|
13
17
|
readonly ok: false;
|
|
14
18
|
readonly busy: boolean;
|
|
@@ -17,4 +21,6 @@ export type SleepReply = {
|
|
|
17
21
|
};
|
|
18
22
|
/** `sleep` for the HTTP route: same result and errors, run outside the serving process and stopped at the deadline (10 minutes, or HIPPO_SLEEP_TIMEOUT_MS). */
|
|
19
23
|
export declare function sleepInChild(ctx: Context, opts: SleepOpts): Promise<SleepResult>;
|
|
24
|
+
/** The MCP auto-sleep's consolidation, in the same queue and child as POST /v1/sleep; auto-sleep only starts on a hippo.db store. */
|
|
25
|
+
export declare function consolidateInChild(hippoRoot: string): Promise<void>;
|
|
20
26
|
//# sourceMappingURL=sleep-offload.d.ts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// POST /v1/sleep
|
|
1
|
+
// POST /v1/sleep and the MCP auto-sleep run their consolidation in a child process, so the server keeps answering and a stuck run can be stopped.
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { sleep } from '../api/index.js';
|
|
5
|
-
import { StoreBusyError } from '../
|
|
5
|
+
import { hasGroup, StoreBusyError } from '../store/port.js';
|
|
6
6
|
import { envSleepTimeoutMs } from '../util/env.js';
|
|
7
7
|
import { HttpError } from '../util/http-util.js';
|
|
8
8
|
const DEFAULT_SLEEP_DEADLINE_MS = 600_000;
|
|
@@ -32,7 +32,7 @@ function runInChild(job) {
|
|
|
32
32
|
// SIGKILL because the child is inside synchronous SQLite work and cannot run a handler; the OS drops its write lock.
|
|
33
33
|
const timer = setTimeout(() => { timedOut = true; child.kill('SIGKILL'); }, deadlineMs);
|
|
34
34
|
child.once('message', (message) => {
|
|
35
|
-
// SAFETY: sleep-child.ts is the only writer on this channel and sends exactly one SleepReply.
|
|
35
|
+
// SAFETY: sleep-child.ts is the only writer on this channel and sends exactly one SleepReply for the job it was given.
|
|
36
36
|
reply = message;
|
|
37
37
|
});
|
|
38
38
|
child.once('error', (err) => { clearTimeout(timer); reject(err); });
|
|
@@ -54,20 +54,26 @@ let turn = Promise.resolve();
|
|
|
54
54
|
const MAX_SLEEPS_IN_LINE = 2;
|
|
55
55
|
const SLEEP_RETRY_AFTER_SEC = 30;
|
|
56
56
|
let inLine = 0;
|
|
57
|
-
|
|
58
|
-
export function sleepInChild(ctx, opts) {
|
|
59
|
-
// The child reopens the store by path, which only SQLite has; any other store keeps sleep's own refusal.
|
|
60
|
-
if (ctx.store && ctx.store.kind !== 'sqlite')
|
|
61
|
-
return sleep(ctx, opts);
|
|
57
|
+
function inTurn(job) {
|
|
62
58
|
if (inLine >= MAX_SLEEPS_IN_LINE) {
|
|
63
59
|
return Promise.reject(new HttpError(503, 'a sleep is already running and another is waiting; retry when one has finished', SLEEP_RETRY_AFTER_SEC));
|
|
64
60
|
}
|
|
65
61
|
inLine += 1;
|
|
66
|
-
|
|
67
|
-
// One sleep at a time, as on the server's single thread: a second request waits its turn and does not fight the first for the write lock.
|
|
62
|
+
// One sleep at a time, as on the server's single thread: a second one waits its turn and does not fight the first for the write lock.
|
|
68
63
|
const run = turn.then(() => runInChild(job));
|
|
69
|
-
// A failed sleep reaches its own
|
|
64
|
+
// A failed sleep reaches its own caller through `run`; the queue only needs to know the turn is over.
|
|
70
65
|
turn = run.then(() => undefined, () => undefined).finally(() => { inLine -= 1; });
|
|
71
66
|
return run;
|
|
72
67
|
}
|
|
68
|
+
/** `sleep` for the HTTP route: same result and errors, run outside the serving process and stopped at the deadline (10 minutes, or HIPPO_SLEEP_TIMEOUT_MS). */
|
|
69
|
+
export function sleepInChild(ctx, opts) {
|
|
70
|
+
// The child reopens the store by path, which only a store of local files has; any other store keeps sleep's own refusal.
|
|
71
|
+
if (ctx.store && !hasGroup(ctx.store, 'localFiles'))
|
|
72
|
+
return sleep(ctx, opts);
|
|
73
|
+
return inTurn({ kind: 'sleep', hippoRoot: ctx.hippoRoot, tenantId: ctx.tenantId, actor: ctx.actor, opts });
|
|
74
|
+
}
|
|
75
|
+
/** The MCP auto-sleep's consolidation, in the same queue and child as POST /v1/sleep; auto-sleep only starts on a hippo.db store. */
|
|
76
|
+
export async function consolidateInChild(hippoRoot) {
|
|
77
|
+
await inTurn({ kind: 'consolidate', hippoRoot });
|
|
78
|
+
}
|
|
73
79
|
//# sourceMappingURL=sleep-offload.js.map
|
package/dist/server/tls.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { type RequestListener, type Server } from 'node:http';
|
|
2
2
|
import type { ServeOpts } from './types.js';
|
|
3
3
|
export declare function createListener(tls: ServeOpts['tls'], onRequest: RequestListener): Server;
|
|
4
|
-
/**
|
|
5
|
-
export declare
|
|
4
|
+
/** serve() refused a non-loopback bind without TLS: every key and memory would cross the network as plain text. */
|
|
5
|
+
export declare class CleartextBindError extends Error {
|
|
6
|
+
readonly host: string;
|
|
7
|
+
constructor(host: string);
|
|
8
|
+
}
|
|
9
|
+
/** Throws CleartextBindError for a non-loopback bind without TLS unless the operator allowed cleartext, which is then said once at boot. */
|
|
10
|
+
export declare function assertTlsOrCleartextAllowed(host: string, tls: ServeOpts['tls'], loopbackHosts: ReadonlySet<string>, allowCleartext: boolean): void;
|
|
6
11
|
//# sourceMappingURL=tls.d.ts.map
|
package/dist/server/tls.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The serve() listener: node:https when a certificate is given, else node:http
|
|
1
|
+
// The serve() listener: node:https when a certificate is given, else node:http, which a non-loopback bind must opt into.
|
|
2
2
|
import { createServer as createHttpServer } from 'node:http';
|
|
3
3
|
import { createServer as createHttpsServer } from 'node:https';
|
|
4
4
|
import { errorMessage, log } from '../util/log.js';
|
|
@@ -14,11 +14,23 @@ export function createListener(tls, onRequest) {
|
|
|
14
14
|
throw new Error(`hippo serve: the TLS certificate or key was refused: ${errorMessage(err)}`, { cause: err });
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
export
|
|
17
|
+
/** serve() refused a non-loopback bind without TLS: every key and memory would cross the network as plain text. */
|
|
18
|
+
export class CleartextBindError extends Error {
|
|
19
|
+
host;
|
|
20
|
+
constructor(host) {
|
|
21
|
+
super(`hippo serve: refusing to listen on ${host} without TLS, since API keys and memory text would travel in cleartext. ` +
|
|
22
|
+
'Pass --tls-cert and --tls-key (or set HIPPO_TLS_CERT and HIPPO_TLS_KEY) to serve HTTPS. If a TLS-terminating proxy sits in front, ' +
|
|
23
|
+
'start with --allow-cleartext, set HIPPO_ALLOW_CLEARTEXT=1, or pass allowCleartext: true to serve().');
|
|
24
|
+
this.host = host;
|
|
25
|
+
this.name = 'CleartextBindError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Throws CleartextBindError for a non-loopback bind without TLS unless the operator allowed cleartext, which is then said once at boot. */
|
|
29
|
+
export function assertTlsOrCleartextAllowed(host, tls, loopbackHosts, allowCleartext) {
|
|
19
30
|
if (tls || loopbackHosts.has(host))
|
|
20
31
|
return;
|
|
21
|
-
|
|
22
|
-
|
|
32
|
+
if (!allowCleartext)
|
|
33
|
+
throw new CleartextBindError(host);
|
|
34
|
+
log.warn(`serve: listening on ${host} without TLS, as allowed; API keys and memory text are cleartext until the proxy in front adds TLS.`);
|
|
23
35
|
}
|
|
24
36
|
//# sourceMappingURL=tls.js.map
|
package/dist/server/types.d.ts
CHANGED
|
@@ -66,11 +66,16 @@ export interface ServeOpts {
|
|
|
66
66
|
cert: string | Buffer;
|
|
67
67
|
key: string | Buffer;
|
|
68
68
|
};
|
|
69
|
+
/** Lets a non-loopback bind start without `tls`, for TLS that ends at a proxy in front; else serve() refuses it. Also HIPPO_ALLOW_CLEARTEXT=1. */
|
|
70
|
+
allowCleartext?: boolean;
|
|
71
|
+
/** The role a keyless local request (HIPPO_ALLOW_KEYLESS_LOCAL=1) gets; defaults to HIPPO_KEYLESS_LOCAL_ROLE, else 'member'. Only 'admin' is host admin. */
|
|
72
|
+
keylessLocalRole?: 'member' | 'admin';
|
|
69
73
|
/** Static JSON served to anyone at GET <path>; built once at boot and never authenticated, so it must hold nothing secret. */
|
|
70
74
|
publicJson?: Readonly<Record<string, JsonValue>>;
|
|
71
|
-
/** Request limits: perCaller after auth
|
|
75
|
+
/** Request limits: perCaller after auth, on by default (HIPPO_CALLER_RPS, else 20 per second, burst 40); perAddress replaces HIPPO_V1_RPS when set;
|
|
76
|
+
* 'off' disables either; failedAuthPerAddress guards scrypt. */
|
|
72
77
|
rateLimits?: {
|
|
73
|
-
perCaller?: RateLimitSpec;
|
|
78
|
+
perCaller?: RateLimitSpec | 'off';
|
|
74
79
|
perAddress?: RateLimitSpec | 'off';
|
|
75
80
|
failedAuthPerAddress?: RateLimitSpec;
|
|
76
81
|
};
|
|
@@ -88,6 +93,10 @@ export interface RouteRequest {
|
|
|
88
93
|
opts: ResolvedServeOpts;
|
|
89
94
|
query: URLSearchParams;
|
|
90
95
|
}
|
|
96
|
+
/** A request past the dispatch gate, carrying the caller the gate authenticated. */
|
|
97
|
+
export interface AuthedRouteRequest extends RouteRequest {
|
|
98
|
+
ctx: Context;
|
|
99
|
+
}
|
|
91
100
|
/** A route's store status: a `storeReady` group, a `sqliteOnly` reason, or neither while it waits for a group; never both. */
|
|
92
101
|
type StoreStatus = {
|
|
93
102
|
storeReady?: StoreGroup;
|
|
@@ -96,20 +105,28 @@ type StoreStatus = {
|
|
|
96
105
|
sqliteOnly: string;
|
|
97
106
|
storeReady?: never;
|
|
98
107
|
};
|
|
99
|
-
/**
|
|
100
|
-
*
|
|
101
|
-
export type
|
|
102
|
-
|
|
103
|
-
loop?: 'off';
|
|
104
|
-
} & StoreStatus & ({
|
|
108
|
+
/** What the dispatch gate proves before a handler runs: any caller, an admin, a host admin on loopback, or nothing, for a route
|
|
109
|
+
* whose handler checks the sender's signature itself. */
|
|
110
|
+
export type RouteAuth = 'caller' | 'admin' | 'host-admin-local' | 'webhook-signature';
|
|
111
|
+
export type RouteEndpoint<R> = {
|
|
105
112
|
path: string;
|
|
106
|
-
handler: (r:
|
|
113
|
+
handler: (r: R) => Promise<void>;
|
|
107
114
|
} | {
|
|
108
115
|
pattern: string;
|
|
109
|
-
handler: (r:
|
|
116
|
+
handler: (r: R, params: Record<string, string>) => Promise<void>;
|
|
110
117
|
} | {
|
|
111
118
|
regex: RegExp;
|
|
112
|
-
handler: (r:
|
|
113
|
-
}
|
|
119
|
+
handler: (r: R, match: RegExpMatchArray) => Promise<void>;
|
|
120
|
+
};
|
|
121
|
+
/** One /v1 route: an exact path, a matchPath pattern, or a regex, each paired with one method's handler. Under another store it runs only with its
|
|
122
|
+
* store's `storeReady` group; `loop: 'off'` runs its SQLite work on a worker thread, so the handler opens no hippo.db on the server thread. */
|
|
123
|
+
export type Route = {
|
|
124
|
+
method: string;
|
|
125
|
+
loop?: 'off';
|
|
126
|
+
} & StoreStatus & (({
|
|
127
|
+
auth: Exclude<RouteAuth, 'webhook-signature'>;
|
|
128
|
+
} & RouteEndpoint<AuthedRouteRequest>) | ({
|
|
129
|
+
auth: 'webhook-signature';
|
|
130
|
+
} & RouteEndpoint<RouteRequest>));
|
|
114
131
|
export {};
|
|
115
132
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -3,10 +3,9 @@ import type { Context, RememberOpts } from '../api/index.js';
|
|
|
3
3
|
import { type JsonValue } from '../util/json.js';
|
|
4
4
|
export declare function isSetMember<T extends string>(set: ReadonlySet<T>, value: string): value is T;
|
|
5
5
|
export declare const MAX_SHORT_FIELD_LEN = 4096;
|
|
6
|
-
export declare const MAX_LIST_LIMIT = 1000;
|
|
7
6
|
export declare function parseListLimit(limitRaw: string | null, defaultLimit?: number, maxLimit?: number): number;
|
|
8
7
|
/** `_authed` is proof the caller passed auth, so a full-size body is read only for
|
|
9
|
-
* an authenticated caller; the key mint reads
|
|
8
|
+
* an authenticated caller; the key mint reads under its own small cap. */
|
|
10
9
|
export declare function parseJsonBody(req: IncomingMessage, _authed: Context): Promise<Record<string, JsonValue>>;
|
|
11
10
|
export declare function parseJsonObjectText(raw: string): Record<string, JsonValue>;
|
|
12
11
|
export declare function getString(obj: Record<string, JsonValue>, key: string): string | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { HttpError,
|
|
1
|
+
import { HttpError, readBody } from '../util/http-util.js';
|
|
2
|
+
import { DEFAULT_LIST_LIMIT, MAX_ID_LEN, MAX_LIST_LIMIT, resolveListLimit } from '../util/limits.js';
|
|
2
3
|
import { isJsonString, isJsonObject } from '../util/json.js';
|
|
3
4
|
// Runtime membership check for a `ReadonlySet<T>` of string-literal members: Set<T>.has gives no narrowing, so this is the one place the `as T` assertion lives
|
|
4
5
|
// and callers narrow via the `value is T` return.
|
|
@@ -8,20 +9,14 @@ export function isSetMember(set, value) {
|
|
|
8
9
|
}
|
|
9
10
|
// Cap for short free-text HTTP fields (names, text, context, change summaries) on the object routes.
|
|
10
11
|
export const MAX_SHORT_FIELD_LEN = 4096;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export function parseListLimit(limitRaw, defaultLimit = 100, maxLimit = MAX_LIST_LIMIT) {
|
|
15
|
-
if (limitRaw === null)
|
|
16
|
-
return defaultLimit;
|
|
17
|
-
const limit = Number(limitRaw);
|
|
18
|
-
if (!Number.isInteger(limit) || limit <= 0 || limit > maxLimit) {
|
|
12
|
+
export function parseListLimit(limitRaw, defaultLimit = DEFAULT_LIST_LIMIT, maxLimit = MAX_LIST_LIMIT) {
|
|
13
|
+
const limit = resolveListLimit(limitRaw === null ? undefined : Number(limitRaw), defaultLimit, maxLimit);
|
|
14
|
+
if (limit === undefined)
|
|
19
15
|
throw new HttpError(400, `limit must be a positive integer <= ${maxLimit}`);
|
|
20
|
-
}
|
|
21
16
|
return limit;
|
|
22
17
|
}
|
|
23
18
|
/** `_authed` is proof the caller passed auth, so a full-size body is read only for
|
|
24
|
-
* an authenticated caller; the key mint reads
|
|
19
|
+
* an authenticated caller; the key mint reads under its own small cap. */
|
|
25
20
|
export async function parseJsonBody(req, _authed) {
|
|
26
21
|
return parseJsonObjectText(await readBody(req));
|
|
27
22
|
}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,53 +1,17 @@
|
|
|
1
|
-
import { type Actor, authCreateSelf, type AuthCreateSelfOpts, type AuthCreateSelfResult, authRevoke, type
|
|
2
|
-
import { ForbiddenError, NotFoundError } from './core/api-errors.js';
|
|
1
|
+
import { type Actor, authCreateSelf, type AuthCreateSelfOpts, type AuthCreateSelfResult, authRevoke, type AuthRevokeResult, type Context } from './api/index.js';
|
|
2
|
+
import { BadRequestError, ConflictError, ForbiddenError, NotFoundError } from './core/api-errors.js';
|
|
3
3
|
export { serve } from './server/boot.js';
|
|
4
|
-
export { authCreateSelf, authRevoke, ForbiddenError, NotFoundError, type AuthCreateSelfOpts, type AuthCreateSelfResult, type
|
|
4
|
+
export { authCreateSelf, authRevoke, BadRequestError, ConflictError, ForbiddenError, NotFoundError, type AuthCreateSelfOpts, type AuthCreateSelfResult, type AuthRevokeResult, type Context, type Actor, };
|
|
5
5
|
export { isCrossSite, LOOPBACK_HOST_HEADER } from './util/http-util.js';
|
|
6
|
-
export { __resetSessionRecallHistoryHttp } from './server/routes/recall.js';
|
|
7
6
|
export { clientIpForRateLimit } from './server/client-ip.js';
|
|
8
7
|
export { isLoopback, isReservedActor } from './server/auth.js';
|
|
9
8
|
export type { AddonCall, AddonRoute, AuthResolver, RateLimitSpec, ResolvedBearer, ServeOpts, ServerHandle } from './server/types.js';
|
|
9
|
+
export type { HippoStore } from './store/index.js';
|
|
10
10
|
export { HttpError } from './util/http-util.js';
|
|
11
11
|
export { promptHookContext, type CallerProject } from './api/prompt-hook.js';
|
|
12
12
|
export type { JsonValue } from './util/json.js';
|
|
13
13
|
export { captureSessionTexts, type SessionCaptureRequest, type SessionCaptureResult } from './capture/session-texts.js';
|
|
14
|
-
export { hasGroup, sqliteStore, type AmbientCandidateRequest, type ContextReads, type EntryRemoval, type EntryTarget, type EntryWrite, type EntryWrites, type HippoStore, type KeyAudit, type KeyListQuery, type KeyMint, type KeyRevoke, type KeyWrites, type OutcomeWrite, type RawArchive, type RecallSearchArgs, type RecallWrites, type SelfKeyMint, type StoreGroup, type StoreGroups, type SupersedeWrite, type VectorReads, type VectorBackfillQuery, type VectorRowWrite, type VectorWrite, type VectorWriteResult, type VectorWrites, } from './store/index.js';
|
|
15
|
-
export { entryAfterOutcome } from './core/memory.js';
|
|
16
|
-
export { rejectionDigest, RejectedValueError } from './store/rejection.js';
|
|
17
|
-
export { ownScopeTouches } from './store/recall-scope.js';
|
|
18
|
-
export { BadRequestError, ConflictError } from './core/api-errors.js';
|
|
19
|
-
export type { HippoDbContext, StoreReply } from './api/types.js';
|
|
20
|
-
export type { ApiKeyListItem, ApiKeyListRow, ApiKeyRecord, ListApiKeysOpts, NewApiKey } from './store/auth.js';
|
|
21
|
-
export type { KeysetPosition } from './util/keyset.js';
|
|
22
|
-
export type { AppendAuditOpts, AuditEvent, ListAuditAfterOpts } from './store/audit.js';
|
|
23
|
-
export type { ContinuityBlock } from './api/recall-types.js';
|
|
24
|
-
export type { ActiveGoals, GetActiveGoalsOpts, Goal, GoalRecallLogRow, RetrievalPolicy } from './store/goals.js';
|
|
25
|
-
export type { MemoryEntry } from './core/memory.js';
|
|
26
|
-
export type { ClassResolution, PlanningFallacyEvidence } from './store/planning-fallacy-evidence.js';
|
|
27
|
-
export type { PredictionBaserate } from './store/predictions.js';
|
|
28
|
-
export type { RecallTraceInput } from './store/recall-trace.js';
|
|
29
|
-
export type { StrengthenOptions } from './store/entry-writes.js';
|
|
30
|
-
export type { OriginFilter, RecallScopeFilter, VectorCandidateSpec } from './store/search-rows.js';
|
|
31
|
-
export type { ContinuityKey } from './store/sessions.js';
|
|
32
|
-
export type { SessionEvent, TaskSnapshot } from './store/rows.js';
|
|
33
|
-
export type { SessionHandoff } from './core/handoff.js';
|
|
34
|
-
export type { AmbientLoadResult, AmbientRecallRequest, ContextCandidateFilter, RecentOrigins } from './store/candidates.js';
|
|
35
|
-
export type { AmbientStoreFilter } from './store/ambient.js';
|
|
36
|
-
export type { AmbientTallies } from './core/ambient.js';
|
|
37
|
-
export type { TokenUse } from './store/token-ledger.js';
|
|
38
|
-
export type { EmbeddingIndexState } from './store/vector-index.js';
|
|
39
|
-
export type { PhysicsParticle } from './core/physics.js';
|
|
40
|
-
export { StoreBusyError } from './db/index.js';
|
|
41
|
-
export { decodeVector, EMBEDDING_MODEL_META_KEY, encodeVector, rankVectorRows, type VectorMatch, type VectorRow } from './db/vector-store.js';
|
|
42
|
-
export { bufferToFloat32, float32ToBuffer } from './db/physics-state.js';
|
|
43
|
-
export { replacesIndex } from './store/vector-index.js';
|
|
44
|
-
export { passesScopeFilterForRecall, RECALL_DEFAULT_DENY_SCOPES } from './store/recall-scope.js';
|
|
45
|
-
export { SECRET_TAGS } from './util/secret-detect.js';
|
|
46
|
-
export { tallyAmbientEntries } from './core/ambient.js';
|
|
47
|
-
export { ftsTermParts, rarestFtsQuery } from './core/prompt-recall.js';
|
|
48
|
-
export { OTHER_STORE_MARKER, OtherStoreFolderError, withSqliteAllowed } from './db/index.js';
|
|
49
14
|
export { authCreate, type AuthCreateOpts, type AuthCreateResult } from './api/index.js';
|
|
50
|
-
export { isSharedStore } from './core/config.js';
|
|
51
15
|
export { ownerOrSubject } from './api/index.js';
|
|
52
16
|
export { bindSessionOwner } from './api/session-owners.js';
|
|
53
17
|
export { preCompactForCaller, type CallerHookOutput, type CallerPreCompactRequest } from './capture/pre-compact-caller.js';
|
package/dist/server.js
CHANGED
|
@@ -1,44 +1,18 @@
|
|
|
1
1
|
import { authCreateSelf, authRevoke, } from './api/index.js';
|
|
2
|
-
import { ForbiddenError, NotFoundError } from './core/api-errors.js';
|
|
2
|
+
import { BadRequestError, ConflictError, ForbiddenError, NotFoundError } from './core/api-errors.js';
|
|
3
3
|
export { serve } from './server/boot.js';
|
|
4
4
|
// Add-on packages mint and revoke keys through these without importing the whole api surface.
|
|
5
|
-
export { authCreateSelf, authRevoke, ForbiddenError, NotFoundError, };
|
|
6
|
-
// Published on the hippo-memory/server subpath before they moved to http-util.ts, so they stay exported here.
|
|
5
|
+
export { authCreateSelf, authRevoke, BadRequestError, ConflictError, ForbiddenError, NotFoundError, };
|
|
7
6
|
export { isCrossSite, LOOPBACK_HOST_HEADER } from './util/http-util.js';
|
|
8
|
-
// The code behind these lives in src/server/; this subpath keeps exporting them.
|
|
9
|
-
export { __resetSessionRecallHistoryHttp } from './server/routes/recall.js';
|
|
10
7
|
export { clientIpForRateLimit } from './server/client-ip.js';
|
|
11
8
|
export { isLoopback, isReservedActor } from './server/auth.js';
|
|
12
|
-
//
|
|
13
|
-
// for a caller that renders the prompt hook elsewhere, JsonValue for its body.
|
|
9
|
+
// An add-on route replies 4xx with HttpError, renders the prompt hook elsewhere with promptHookContext, and types its body as JsonValue.
|
|
14
10
|
export { HttpError } from './util/http-util.js';
|
|
15
11
|
export { promptHookContext } from './api/prompt-hook.js';
|
|
16
12
|
// A session-end route stores the turns its caller read from a transcript on the caller's own machine.
|
|
17
13
|
export { captureSessionTexts } from './capture/session-texts.js';
|
|
18
|
-
// An add-on serves from another database by passing serve() its own HippoStore.
|
|
19
|
-
export { hasGroup, sqliteStore, } from './store/index.js';
|
|
20
|
-
// An add-on store's entry writes apply an outcome, guard tombstones and check reach exactly as hippo.db does.
|
|
21
|
-
export { entryAfterOutcome } from './core/memory.js';
|
|
22
|
-
export { rejectionDigest, RejectedValueError } from './store/rejection.js';
|
|
23
|
-
export { ownScopeTouches } from './store/recall-scope.js';
|
|
24
|
-
export { BadRequestError, ConflictError } from './core/api-errors.js';
|
|
25
|
-
export { StoreBusyError } from './db/index.js';
|
|
26
|
-
// An add-on store encodes, decodes and ranks vectors and particles with hippo.db's own code, and drops the index by its rule,
|
|
27
|
-
// so both stores keep the same bytes and return the same ids in the same order.
|
|
28
|
-
export { decodeVector, EMBEDDING_MODEL_META_KEY, encodeVector, rankVectorRows } from './db/vector-store.js';
|
|
29
|
-
export { bufferToFloat32, float32ToBuffer } from './db/physics-state.js';
|
|
30
|
-
export { replacesIndex } from './store/vector-index.js';
|
|
31
|
-
// An add-on's ContextReads applies hippo.db's scope, secret, tally and rarest-term rules with the same code.
|
|
32
|
-
export { passesScopeFilterForRecall, RECALL_DEFAULT_DENY_SCOPES } from './store/recall-scope.js';
|
|
33
|
-
export { SECRET_TAGS } from './util/secret-detect.js';
|
|
34
|
-
export { tallyAmbientEntries } from './core/ambient.js';
|
|
35
|
-
export { ftsTermParts, rarestFtsQuery } from './core/prompt-recall.js';
|
|
36
|
-
// store copy --db writes the marker and reads the old hippo.db under the waiver.
|
|
37
|
-
export { OTHER_STORE_MARKER, OtherStoreFolderError, withSqliteAllowed } from './db/index.js';
|
|
38
14
|
// An add-on's install step mints the first admin key into a store folder it names, which `hippo auth create` cannot reach.
|
|
39
15
|
export { authCreate } from './api/index.js';
|
|
40
|
-
// An add-on that serves a team store checks the flag before it starts.
|
|
41
|
-
export { isSharedStore } from './core/config.js';
|
|
42
16
|
export { ownerOrSubject } from './api/index.js';
|
|
43
17
|
// A route that writes for a session binds it to the caller's owner first.
|
|
44
18
|
export { bindSessionOwner } from './api/session-owners.js';
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { MemoryEntry } from '../core/memory.js';
|
|
2
|
-
import type { DatabaseSyncLike } from '../db/index.js';
|
|
3
2
|
/** Returns the path to the global Hippo store.
|
|
4
3
|
* Resolution order: $HIPPO_HOME > $XDG_DATA_HOME/hippo > ~/.hippo/ */
|
|
5
4
|
export declare function getGlobalRoot(): string;
|
|
6
5
|
/** Ensure the global store exists. */
|
|
7
6
|
export declare function initGlobal(): void;
|
|
8
|
-
|
|
9
|
-
export declare function promoteToGlobal(localRoot: string, id: string, opts?: {
|
|
7
|
+
export interface PromoteOptions {
|
|
10
8
|
actor?: string;
|
|
11
9
|
tenantId?: string;
|
|
12
|
-
afterWrite?: (db: DatabaseSyncLike, globalId: string) => void;
|
|
13
10
|
/** Also writes one `promote` audit row for the copy ({sourceId}), in the copy's own transaction. */
|
|
14
11
|
auditAs?: {
|
|
15
12
|
tenantId: string;
|
|
16
13
|
actor: string;
|
|
17
14
|
};
|
|
18
|
-
}
|
|
15
|
+
}
|
|
16
|
+
/** Copies a local memory to the global store and returns the copy, which gets a new `g_` id so it cannot collide. */
|
|
17
|
+
export declare function promoteToGlobal(localRoot: string, id: string, opts?: PromoteOptions): MemoryEntry;
|
|
19
18
|
//# sourceMappingURL=global-store.d.ts.map
|
|
@@ -3,14 +3,14 @@ import { BadRequestError, NotFoundError } from '../core/api-errors.js';
|
|
|
3
3
|
import * as fs from 'fs';
|
|
4
4
|
import { generateId } from '../core/memory.js';
|
|
5
5
|
import { initStore } from '../store/open.js';
|
|
6
|
-
import {
|
|
6
|
+
import { writeEntryWithHook } from '../store/entry-writes.js';
|
|
7
7
|
import { readEntry } from '../store/entry-reads.js';
|
|
8
|
-
import { isPersonalScope } from '../
|
|
8
|
+
import { isPersonalScope } from '../core/recall-scope.js';
|
|
9
9
|
import { fallbackOrigin, resolveGlobalRootDir } from '../core/project-identity.js';
|
|
10
10
|
import { isSharedStore } from '../core/config.js';
|
|
11
11
|
import { detectSecret } from '../util/secret-detect.js';
|
|
12
12
|
import { isQuarantineScope } from '../trust/quarantine.js';
|
|
13
|
-
import { embedMemory } from '../
|
|
13
|
+
import { embedMemory } from '../search/embed-memories.js';
|
|
14
14
|
import { appendAuditEvent } from '../store/audit.js';
|
|
15
15
|
/** Returns the path to the global Hippo store.
|
|
16
16
|
* Resolution order: $HIPPO_HOME > $XDG_DATA_HOME/hippo > ~/.hippo/ */
|
|
@@ -30,15 +30,6 @@ export function initGlobal() {
|
|
|
30
30
|
initStore(globalRoot);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
/** The copy's write hook: the `promote` row when asked for, then the caller's own hook, both in the copy's transaction. */
|
|
34
|
-
function promoteHook(sourceId, auditAs, afterWrite) {
|
|
35
|
-
if (!auditAs)
|
|
36
|
-
return afterWrite;
|
|
37
|
-
return (db, globalId) => {
|
|
38
|
-
appendAuditEvent(db, { tenantId: auditAs.tenantId, actor: auditAs.actor, op: 'promote', targetId: globalId, metadata: { sourceId } });
|
|
39
|
-
afterWrite?.(db, globalId);
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
33
|
/** Copies a local memory to the global store and returns the copy, which gets a new `g_` id so it cannot collide. */
|
|
43
34
|
export function promoteToGlobal(localRoot, id, opts) {
|
|
44
35
|
const entry = readEntry(localRoot, id, opts?.tenantId);
|
|
@@ -67,7 +58,11 @@ export function promoteToGlobal(localRoot, id, opts) {
|
|
|
67
58
|
source: isSharedStore(localRoot) ? `shared::${new Date().toISOString()}` : `promoted:${localRoot}`,
|
|
68
59
|
origin_project: entry.origin_project ?? fallbackOrigin(localRoot),
|
|
69
60
|
};
|
|
70
|
-
|
|
61
|
+
const { auditAs } = opts ?? {};
|
|
62
|
+
const promoteRow = auditAs && ((db, globalId) => {
|
|
63
|
+
appendAuditEvent(db, { tenantId: auditAs.tenantId, actor: auditAs.actor, op: 'promote', targetId: globalId, metadata: { sourceId: id } });
|
|
64
|
+
});
|
|
65
|
+
writeEntryWithHook(globalRoot, globalEntry, { actor: opts?.actor, afterWrite: promoteRow });
|
|
71
66
|
// Fire-and-forget: embedMemory gates on availability and never rejects.
|
|
72
67
|
void embedMemory(globalRoot, globalEntry);
|
|
73
68
|
return globalEntry;
|