hippo-memory 1.70.0 → 1.71.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 +1 -1
- package/dist/agent-memories/claude-code.d.ts +4 -2
- package/dist/agent-memories/claude-code.js +14 -5
- package/dist/agent-memories/files.js +23 -12
- package/dist/agent-memories/markdown.d.ts +1 -3
- package/dist/agent-memories/markdown.js +1 -3
- package/dist/agent-memories/report.js +2 -1
- package/dist/agent-memories/sync.d.ts +4 -2
- package/dist/agent-memories/sync.js +10 -5
- package/dist/api/assemble.d.ts +7 -44
- package/dist/api/assemble.js +2 -22
- package/dist/api/audit.d.ts +5 -1
- package/dist/api/audit.js +9 -1
- package/dist/api/auth.d.ts +13 -22
- package/dist/api/auth.js +34 -24
- package/dist/api/auto-sleep.js +2 -2
- package/dist/api/availability.d.ts +2 -15
- package/dist/api/availability.js +2 -15
- package/dist/api/context-select.js +3 -4
- package/dist/api/context-types.d.ts +10 -35
- package/dist/api/context.d.ts +5 -22
- package/dist/api/context.js +21 -38
- package/dist/api/dormant.d.ts +5 -21
- package/dist/api/dormant.js +7 -26
- package/dist/api/drill-down.d.ts +7 -46
- package/dist/api/drill-down.js +5 -26
- package/dist/api/forget.d.ts +5 -24
- package/dist/api/forget.js +5 -28
- package/dist/api/graph.d.ts +8 -0
- package/dist/api/graph.js +7 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/instruction-detect.js +16 -5
- package/dist/api/ledger-db.d.ts +2 -1
- package/dist/api/ledger-db.js +5 -3
- package/dist/api/memories.d.ts +5 -0
- package/dist/api/memories.js +7 -0
- package/dist/api/objects.d.ts +9 -0
- package/dist/api/objects.js +11 -0
- package/dist/api/on-store.js +5 -3
- package/dist/api/predictions.d.ts +9 -0
- package/dist/api/predictions.js +18 -0
- package/dist/api/promote.d.ts +13 -17
- package/dist/api/promote.js +11 -19
- package/dist/api/prompt-hook.d.ts +4 -4
- package/dist/api/prompt-hook.js +10 -9
- package/dist/api/recall-cli.d.ts +55 -0
- package/dist/api/recall-cli.js +94 -0
- package/dist/api/recall-core.js +14 -6
- package/dist/api/recall-finish.d.ts +53 -0
- package/dist/api/recall-finish.js +30 -0
- package/dist/api/recall-history.d.ts +17 -84
- package/dist/api/recall-history.js +15 -88
- package/dist/api/recall-pipeline.d.ts +2 -3
- package/dist/api/recall-pipeline.js +16 -9
- package/dist/api/recall-types.d.ts +64 -304
- package/dist/api/recall.d.ts +5 -33
- package/dist/api/recall.js +59 -60
- package/dist/api/refine.d.ts +7 -0
- package/dist/api/refine.js +10 -0
- package/dist/api/remember-local.d.ts +57 -0
- package/dist/api/remember-local.js +90 -0
- package/dist/api/remember.d.ts +18 -1
- package/dist/api/remember.js +13 -1
- package/dist/api/sleep-run.d.ts +1 -3
- package/dist/api/sleep-run.js +17 -21
- package/dist/api/sleep.d.ts +9 -28
- package/dist/api/tokens.d.ts +3 -10
- package/dist/api/tokens.js +3 -10
- package/dist/api/types.d.ts +6 -29
- package/dist/api/types.js +4 -22
- package/dist/capture/command.d.ts +4 -12
- package/dist/capture/command.js +6 -22
- package/dist/capture/compact.d.ts +4 -15
- package/dist/capture/compact.js +16 -25
- package/dist/capture/compaction-record.js +101 -69
- package/dist/capture/compaction-spool.d.ts +1 -1
- package/dist/capture/compaction-spool.js +1 -1
- package/dist/capture/session-digest.d.ts +1 -1
- package/dist/capture/session-digest.js +13 -7
- package/dist/capture/transcript.d.ts +2 -10
- package/dist/capture/transcript.js +4 -18
- package/dist/cli/api-context.d.ts +3 -0
- package/dist/cli/api-context.js +6 -0
- package/dist/cli/audit-prune.d.ts +6 -39
- package/dist/cli/audit-prune.js +6 -39
- package/dist/cli/audit.d.ts +1 -1
- package/dist/cli/audit.js +33 -34
- package/dist/cli/auth.d.ts +2 -2
- package/dist/cli/auth.js +57 -39
- package/dist/cli/briefs.d.ts +4 -4
- package/dist/cli/briefs.js +18 -22
- package/dist/cli/card.d.ts +2 -2
- package/dist/cli/card.js +31 -32
- package/dist/cli/client.d.ts +7 -27
- package/dist/cli/client.js +24 -43
- package/dist/cli/compact-resume-payload.js +3 -2
- package/dist/cli/context.d.ts +1 -2
- package/dist/cli/context.js +12 -8
- package/dist/cli/continuity.d.ts +6 -6
- package/dist/cli/continuity.js +62 -64
- package/dist/cli/correction-latency.d.ts +2 -14
- package/dist/cli/correction-latency.js +2 -14
- package/dist/cli/curate.d.ts +13 -17
- package/dist/cli/curate.js +68 -92
- package/dist/cli/dag.d.ts +4 -4
- package/dist/cli/dag.js +33 -27
- package/dist/cli/decisions.d.ts +4 -4
- package/dist/cli/decisions.js +33 -47
- package/dist/cli/eval.js +15 -13
- package/dist/cli/exit.d.ts +6 -0
- package/dist/cli/exit.js +11 -0
- package/dist/cli/explain.d.ts +1 -2
- package/dist/cli/explain.js +6 -4
- package/dist/cli/flag-values.d.ts +6 -1
- package/dist/cli/flag-values.js +27 -10
- package/dist/cli/flags.d.ts +1 -0
- package/dist/cli/flags.js +1 -1
- package/dist/cli/github.d.ts +14 -0
- package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
- package/dist/cli/goals.d.ts +2 -2
- package/dist/cli/goals.js +46 -50
- package/dist/cli/hook-runtime.d.ts +9 -27
- package/dist/cli/hook-runtime.js +15 -31
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.js +6 -12
- package/dist/cli/install-steps.js +3 -12
- package/dist/cli/last-sleep.d.ts +2 -1
- package/dist/cli/last-sleep.js +3 -0
- package/dist/cli/maintenance.d.ts +4 -4
- package/dist/cli/maintenance.js +14 -19
- package/dist/cli/object-verbs.js +4 -3
- package/dist/cli/owner-validation.d.ts +5 -28
- package/dist/cli/owner-validation.js +5 -28
- package/dist/cli/playbooks.d.ts +4 -4
- package/dist/cli/playbooks.js +23 -28
- package/dist/cli/print.d.ts +2 -5
- package/dist/cli/print.js +1 -4
- package/dist/cli/projects.d.ts +2 -2
- package/dist/cli/projects.js +1 -3
- package/dist/cli/provenance-coverage.d.ts +2 -6
- package/dist/cli/provenance-coverage.js +2 -6
- package/dist/cli/quality-repair-once.js +2 -2
- package/dist/cli/recall.d.ts +2 -4
- package/dist/cli/recall.js +55 -131
- package/dist/cli/refine-llm.d.ts +5 -31
- package/dist/cli/refine-llm.js +9 -36
- package/dist/cli/remember.d.ts +3 -3
- package/dist/cli/remember.js +122 -180
- package/dist/cli/scheduler.d.ts +2 -17
- package/dist/cli/scheduler.js +12 -18
- package/dist/cli/serve.js +21 -12
- package/dist/cli/session-hooks.d.ts +10 -18
- package/dist/cli/session-hooks.js +112 -113
- package/dist/cli/setup.d.ts +4 -4
- package/dist/cli/setup.js +19 -21
- package/dist/cli/shared.d.ts +9 -23
- package/dist/cli/shared.js +9 -32
- package/dist/cli/slack.d.ts +2 -2
- package/dist/cli/slack.js +19 -23
- package/dist/cli/sleep.d.ts +3 -2
- package/dist/cli/sleep.js +15 -16
- package/dist/cli/status.d.ts +9 -12
- package/dist/cli/status.js +55 -98
- package/dist/cli/stdin.d.ts +4 -6
- package/dist/cli/stdin.js +2 -3
- package/dist/cli/transfer.d.ts +9 -9
- package/dist/cli/transfer.js +66 -89
- package/dist/cli/usage.js +11 -5
- package/dist/cli.d.ts +66 -448
- package/dist/cli.js +87 -263
- package/dist/connectors/github/backfill.d.ts +5 -25
- package/dist/connectors/github/backfill.js +14 -49
- package/dist/connectors/github/deletion.d.ts +4 -18
- package/dist/connectors/github/deletion.js +2 -15
- package/dist/connectors/github/dlq.d.ts +8 -33
- package/dist/connectors/github/dlq.js +12 -29
- package/dist/connectors/github/ingest.d.ts +2 -6
- package/dist/connectors/github/ingest.js +4 -10
- package/dist/connectors/github/octokit-client.d.ts +4 -16
- package/dist/connectors/github/octokit-client.js +27 -24
- package/dist/connectors/github/ratelimit.d.ts +3 -14
- package/dist/connectors/github/ratelimit.js +3 -14
- package/dist/connectors/github/scope.d.ts +3 -5
- package/dist/connectors/github/scope.js +3 -5
- package/dist/connectors/github/signature.d.ts +4 -26
- package/dist/connectors/github/signature.js +4 -26
- package/dist/connectors/github/tenant-routing.d.ts +2 -24
- package/dist/connectors/github/tenant-routing.js +4 -26
- package/dist/connectors/github/transform.js +2 -16
- package/dist/connectors/github/types.d.ts +3 -15
- package/dist/connectors/github/types.js +2 -9
- package/dist/connectors/github/webhook.d.ts +2 -16
- package/dist/connectors/github/webhook.js +6 -22
- package/dist/connectors/slack/backfill.d.ts +4 -17
- package/dist/connectors/slack/backfill.js +4 -13
- package/dist/connectors/slack/dlq.d.ts +2 -19
- package/dist/connectors/slack/dlq.js +2 -19
- package/dist/connectors/slack/ingest.d.ts +2 -3
- package/dist/connectors/slack/ingest.js +2 -3
- package/dist/connectors/slack/scope.d.ts +2 -8
- package/dist/connectors/slack/scope.js +2 -8
- package/dist/connectors/slack/signature.d.ts +1 -6
- package/dist/connectors/slack/tenant-routing.d.ts +2 -19
- package/dist/connectors/slack/tenant-routing.js +2 -21
- package/dist/connectors/slack/transform.d.ts +2 -18
- package/dist/connectors/slack/transform.js +2 -18
- package/dist/connectors/slack/types.d.ts +3 -9
- package/dist/connectors/slack/types.js +2 -4
- package/dist/connectors/slack/web-client.js +33 -27
- package/dist/connectors/slack/webhook.d.ts +2 -19
- package/dist/connectors/slack/webhook.js +5 -26
- package/dist/connectors/slack/workspaces.d.ts +4 -24
- package/dist/connectors/slack/workspaces.js +4 -24
- package/dist/consolidate/conflicts.js +6 -14
- package/dist/consolidate/dag-summary.d.ts +8 -0
- package/dist/consolidate/dag-summary.js +41 -0
- package/dist/consolidate/dag.d.ts +5 -28
- package/dist/consolidate/dag.js +14 -75
- package/dist/consolidate/decay.js +7 -19
- package/dist/consolidate/dedupe.d.ts +6 -52
- package/dist/consolidate/dedupe.js +13 -71
- package/dist/consolidate/flush-units.d.ts +3 -4
- package/dist/consolidate/flush-units.js +3 -3
- package/dist/consolidate/half-life-migration.d.ts +3 -26
- package/dist/consolidate/half-life-migration.js +11 -28
- package/dist/consolidate/llm-passes.js +4 -21
- package/dist/consolidate/memory-value-weights.d.ts +2 -13
- package/dist/consolidate/memory-value-weights.js +2 -13
- package/dist/consolidate/memory-value.d.ts +11 -84
- package/dist/consolidate/memory-value.js +16 -104
- package/dist/consolidate/merge.js +10 -31
- package/dist/consolidate/merged-row.js +2 -1
- package/dist/consolidate/physics-pass.js +1 -3
- package/dist/consolidate/replay.d.ts +6 -38
- package/dist/consolidate/replay.js +14 -52
- package/dist/consolidate/run.js +1 -1
- package/dist/consolidate/sleep.d.ts +1 -8
- package/dist/consolidate/sleep.js +5 -17
- package/dist/consolidate/trace.d.ts +3 -18
- package/dist/consolidate/trace.js +3 -18
- package/dist/consolidate/traces.js +6 -22
- package/dist/core/ablation.d.ts +4 -91
- package/dist/core/ablation.js +4 -91
- package/dist/core/ambient.d.ts +1 -8
- package/dist/core/ambient.js +1 -8
- package/dist/core/capture-contract.d.ts +4 -2
- package/dist/core/capture-contract.js +4 -2
- package/dist/core/card.d.ts +4 -1
- package/dist/core/card.js +8 -0
- package/dist/core/compare.d.ts +11 -67
- package/dist/core/compare.js +9 -63
- package/dist/core/config.d.ts +10 -24
- package/dist/core/config.js +13 -14
- package/dist/core/handoff.d.ts +1 -7
- package/dist/core/handoff.js +1 -7
- package/dist/core/memory-quality.js +1 -1
- package/dist/core/memory.d.ts +41 -164
- package/dist/core/memory.js +51 -221
- package/dist/core/package-root.d.ts +3 -0
- package/dist/core/package-root.js +5 -0
- package/dist/core/physics-config.d.ts +1 -4
- package/dist/core/physics-config.js +3 -8
- package/dist/core/physics.d.ts +15 -61
- package/dist/core/physics.js +59 -122
- package/dist/core/project-identity.d.ts +17 -58
- package/dist/core/project-identity.js +17 -38
- package/dist/core/project-remote.js +13 -2
- package/dist/core/raw-append-only.d.ts +5 -0
- package/dist/core/raw-append-only.js +7 -0
- package/dist/core/salience.d.ts +1 -7
- package/dist/core/salience.js +1 -7
- package/dist/dashboard/dashboard-actions.js +2 -2
- package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
- package/dist/dashboard/dashboard-snapshot.js +11 -2
- package/dist/dashboard/dashboard-types.d.ts +2 -1
- package/dist/dashboard/dashboard.d.ts +1 -0
- package/dist/dashboard/dashboard.js +50 -4
- package/dist/db/busy.d.ts +1 -1
- package/dist/db/busy.js +17 -8
- package/dist/db/connect.d.ts +1 -0
- package/dist/db/connect.js +3 -3
- package/dist/db/migrate.js +3 -3
- package/dist/db/migrations/types.d.ts +2 -5
- package/dist/db/migrations/v14.js +2 -3
- package/dist/db/migrations/v15.js +2 -8
- package/dist/db/migrations/v16.js +2 -3
- package/dist/db/migrations/v17.js +2 -3
- package/dist/db/migrations/v19.js +2 -5
- package/dist/db/migrations/v20.js +2 -7
- package/dist/db/migrations/v22.js +4 -17
- package/dist/db/migrations/v23.js +3 -14
- package/dist/db/migrations/v24.js +2 -4
- package/dist/db/migrations/v25.js +3 -8
- package/dist/db/migrations/v26.js +2 -13
- package/dist/db/migrations/v27.js +3 -11
- package/dist/db/migrations/v28.js +2 -14
- package/dist/db/migrations/v29.js +4 -18
- package/dist/db/migrations/v30.js +4 -16
- package/dist/db/migrations/v31.js +2 -15
- package/dist/db/migrations/v32.js +4 -22
- package/dist/db/migrations/v33.js +2 -15
- package/dist/db/migrations/v34.js +2 -11
- package/dist/db/migrations/v35.js +2 -11
- package/dist/db/migrations/v36.js +2 -11
- package/dist/db/migrations/v37.js +8 -33
- package/dist/db/migrations/v38.js +5 -38
- package/dist/db/migrations/v39.js +9 -20
- package/dist/db/migrations/v40.js +2 -9
- package/dist/db/migrations/v41.js +2 -24
- package/dist/db/migrations/v43.js +1 -1
- package/dist/db/migrations/v44.js +2 -8
- package/dist/db/migrations/v45.js +2 -7
- package/dist/db/migrations/v47.js +2 -3
- package/dist/db/migrations/v51.js +1 -1
- package/dist/db/open.d.ts +2 -0
- package/dist/db/open.js +17 -1
- package/dist/db/physics-state.d.ts +6 -22
- package/dist/db/physics-state.js +25 -36
- package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
- package/dist/db/raw-archive-mirror-cleanup.js +2 -17
- package/dist/db/vector-store.d.ts +2 -0
- package/dist/db/vector-store.js +8 -1
- package/dist/doctor.js +74 -19
- package/dist/entry/session-text.js +2 -1
- package/dist/eval/eval-stats.d.ts +15 -53
- package/dist/eval/eval-stats.js +12 -42
- package/dist/eval/eval-suite.d.ts +2 -13
- package/dist/eval/eval-suite.js +74 -34
- package/dist/eval/eval.d.ts +6 -24
- package/dist/eval/eval.js +7 -34
- package/dist/eval/judgment.d.ts +0 -3
- package/dist/eval/judgment.js +19 -11
- package/dist/extensions/openclaw-plugin/index.js +1 -1
- package/dist/graph/extract.d.ts +5 -27
- package/dist/graph/extract.js +7 -33
- package/dist/graph/recall.d.ts +7 -20
- package/dist/graph/recall.js +14 -76
- package/dist/graph/stream.d.ts +7 -39
- package/dist/graph/stream.js +11 -34
- package/dist/graph/view.d.ts +9 -35
- package/dist/graph/view.js +11 -39
- package/dist/hooks/codex-wrapper.js +2 -2
- package/dist/hooks/copilot.js +2 -1
- package/dist/hooks/hook-blocks.d.ts +6 -2
- package/dist/hooks/hook-blocks.js +37 -124
- package/dist/hooks/json-hooks.d.ts +4 -36
- package/dist/hooks/json-hooks.js +18 -57
- package/dist/hooks/opencode.d.ts +0 -38
- package/dist/hooks/opencode.js +9 -76
- package/dist/hooks/shared.d.ts +8 -17
- package/dist/hooks/shared.js +29 -20
- package/dist/importers/core.d.ts +12 -37
- package/dist/importers/core.js +9 -27
- package/dist/importers/markdown-parse.d.ts +8 -22
- package/dist/importers/markdown-parse.js +8 -25
- package/dist/importers/markdown.js +3 -12
- package/dist/importers/sources.js +7 -35
- package/dist/importers/vault.d.ts +2 -8
- package/dist/importers/vault.js +25 -81
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/learn/autolearn.d.ts +14 -41
- package/dist/learn/autolearn.js +14 -41
- package/dist/learn/extract.js +2 -4
- package/dist/learn/forward-claim-detector.d.ts +6 -30
- package/dist/learn/forward-claim-detector.js +14 -66
- package/dist/learn/invalidation.d.ts +6 -18
- package/dist/learn/invalidation.js +9 -26
- package/dist/mcp/admin-tools.js +3 -5
- package/dist/mcp/memory-tools.js +4 -9
- package/dist/mcp/protocol.d.ts +8 -26
- package/dist/mcp/protocol.js +3 -6
- package/dist/mcp/recall-tools.js +3 -3
- package/dist/mcp/request.d.ts +3 -11
- package/dist/mcp/request.js +10 -26
- package/dist/mcp/server.d.ts +3 -9
- package/dist/mcp/server.js +5 -16
- package/dist/mcp/session-state.d.ts +1 -1
- package/dist/mcp/session-state.js +5 -11
- package/dist/mcp/stdio.d.ts +2 -6
- package/dist/mcp/stdio.js +48 -12
- package/dist/mcp/tools.js +5 -3
- package/dist/objects/customer-notes.d.ts +7 -42
- package/dist/objects/customer-notes.js +7 -48
- package/dist/objects/decisions.d.ts +12 -50
- package/dist/objects/decisions.js +15 -53
- package/dist/objects/incidents.d.ts +7 -38
- package/dist/objects/incidents.js +7 -41
- package/dist/objects/policies.d.ts +11 -89
- package/dist/objects/policies.js +11 -98
- package/dist/objects/processes.d.ts +7 -52
- package/dist/objects/processes.js +7 -61
- package/dist/objects/project-briefs.d.ts +11 -55
- package/dist/objects/project-briefs.js +14 -75
- package/dist/objects/skills.d.ts +7 -42
- package/dist/objects/skills.js +8 -54
- package/dist/postinstall.js +6 -19
- package/dist/predictions/planning-fallacy.d.ts +11 -34
- package/dist/rerankers/clef.js +3 -31
- package/dist/rerankers/cross-encoder.js +4 -6
- package/dist/rerankers/jev.js +9 -6
- package/dist/rerankers/llm.d.ts +2 -11
- package/dist/rerankers/llm.js +14 -14
- package/dist/rerankers/outage-warning.d.ts +2 -1
- package/dist/rerankers/outage-warning.js +2 -1
- package/dist/rerankers/remote.d.ts +1 -0
- package/dist/rerankers/remote.js +2 -0
- package/dist/rerankers/types.d.ts +2 -14
- package/dist/search/boosts.d.ts +0 -2
- package/dist/search/boosts.js +2 -2
- package/dist/search/goal-boost.d.ts +23 -0
- package/dist/search/goal-boost.js +90 -0
- package/dist/search/hybrid.d.ts +2 -0
- package/dist/search/multihop.js +2 -3
- package/dist/search/path-context.d.ts +5 -18
- package/dist/search/path-context.js +5 -18
- package/dist/search/physics-search.js +11 -8
- package/dist/search/rrf.d.ts +7 -35
- package/dist/search/rrf.js +5 -30
- package/dist/search/vector.d.ts +7 -0
- package/dist/search/vector.js +35 -5
- package/dist/server/auth.d.ts +9 -28
- package/dist/server/auth.js +32 -25
- package/dist/server/boot.d.ts +2 -21
- package/dist/server/boot.js +63 -96
- package/dist/server/client-ip.d.ts +3 -19
- package/dist/server/client-ip.js +5 -28
- package/dist/server/defaults.d.ts +3 -0
- package/dist/server/defaults.js +4 -0
- package/dist/server/key-check-bounds.d.ts +2 -1
- package/dist/server/lifecycle.d.ts +5 -4
- package/dist/server/lifecycle.js +19 -4
- package/dist/server/mcp-http.js +10 -44
- package/dist/server/rate-limit.d.ts +5 -18
- package/dist/server/rate-limit.js +4 -13
- package/dist/server/request.d.ts +4 -8
- package/dist/server/request.js +9 -17
- package/dist/server/route-table.js +42 -49
- package/dist/server/routes/admin.js +22 -28
- package/dist/server/routes/customer-notes.js +7 -12
- package/dist/server/routes/decisions.js +10 -17
- package/dist/server/routes/incidents.js +12 -20
- package/dist/server/routes/memories.js +12 -32
- package/dist/server/routes/object-routes.d.ts +0 -5
- package/dist/server/routes/object-routes.js +7 -15
- package/dist/server/routes/policies.js +10 -18
- package/dist/server/routes/predictions.js +13 -25
- package/dist/server/routes/processes.js +16 -26
- package/dist/server/routes/project-briefs.js +9 -16
- package/dist/server/routes/recall.js +10 -35
- package/dist/server/routes/skills.js +8 -18
- package/dist/server/server-detect.d.ts +9 -53
- package/dist/server/server-detect.js +24 -90
- package/dist/server/sleep-offload.js +4 -1
- package/dist/server/types.d.ts +12 -10
- package/dist/server/validation.d.ts +3 -1
- package/dist/server/validation.js +10 -23
- package/dist/server.d.ts +2 -2
- package/dist/server.js +3 -2
- package/dist/sharing/global-store.d.ts +19 -0
- package/dist/sharing/global-store.js +75 -0
- package/dist/sharing/global-sync.d.ts +6 -0
- package/dist/sharing/global-sync.js +80 -0
- package/dist/sharing/project-merge.d.ts +4 -5
- package/dist/sharing/project-merge.js +9 -7
- package/dist/sharing/scope.d.ts +4 -11
- package/dist/sharing/scope.js +4 -11
- package/dist/sharing/search-both.d.ts +60 -0
- package/dist/sharing/search-both.js +138 -0
- package/dist/sharing/share.d.ts +38 -0
- package/dist/sharing/share.js +226 -0
- package/dist/store/ambient.js +4 -9
- package/dist/store/audit-event.d.ts +4 -12
- package/dist/store/audit-event.js +4 -12
- package/dist/store/audit.d.ts +2 -5
- package/dist/store/audit.js +4 -12
- package/dist/store/auth.d.ts +6 -6
- package/dist/store/auth.js +10 -9
- package/dist/store/candidates.d.ts +20 -3
- package/dist/store/candidates.js +77 -48
- package/dist/store/card-detail.d.ts +2 -1
- package/dist/store/card-detail.js +2 -1
- package/dist/store/cards.d.ts +14 -9
- package/dist/store/cards.js +72 -126
- package/dist/store/conflicts.d.ts +4 -21
- package/dist/store/conflicts.js +71 -150
- package/dist/store/connectors/github.d.ts +10 -10
- package/dist/store/connectors/github.js +10 -10
- package/dist/store/dashboard-reads.js +4 -8
- package/dist/store/delete-and-batch.d.ts +11 -31
- package/dist/store/delete-and-batch.js +48 -64
- package/dist/store/delivery-recorder.d.ts +8 -4
- package/dist/store/delivery-recorder.js +25 -15
- package/dist/store/diagnostics.js +6 -13
- package/dist/store/dormant.d.ts +7 -29
- package/dist/store/dormant.js +15 -56
- package/dist/store/embeddings/index.d.ts +11 -80
- package/dist/store/embeddings/index.js +71 -207
- package/dist/store/embeddings/local.js +15 -32
- package/dist/store/embeddings/provider.d.ts +16 -53
- package/dist/store/embeddings/provider.js +41 -69
- package/dist/store/entry-reads.d.ts +21 -57
- package/dist/store/entry-reads.js +65 -126
- package/dist/store/entry-row.d.ts +6 -35
- package/dist/store/entry-row.js +9 -37
- package/dist/store/entry-writes.d.ts +10 -16
- package/dist/store/entry-writes.js +17 -35
- package/dist/store/goals.d.ts +3 -40
- package/dist/store/goals.js +21 -160
- package/dist/store/graph-queue.d.ts +6 -22
- package/dist/store/graph-queue.js +14 -45
- package/dist/store/graph-reads.d.ts +11 -35
- package/dist/store/graph-reads.js +20 -58
- package/dist/store/graph-rows.d.ts +3 -6
- package/dist/store/graph-rows.js +6 -9
- package/dist/store/graph-view-rows.d.ts +2 -1
- package/dist/store/graph-view-rows.js +2 -1
- package/dist/store/graph-writes.d.ts +6 -31
- package/dist/store/graph-writes.js +13 -37
- package/dist/store/half-life.d.ts +2 -1
- package/dist/store/half-life.js +14 -16
- package/dist/store/handoffs.d.ts +5 -11
- package/dist/store/handoffs.js +16 -34
- package/dist/store/index-and-stats.d.ts +6 -19
- package/dist/store/index-and-stats.js +34 -82
- package/dist/store/markdown.d.ts +2 -6
- package/dist/store/markdown.js +21 -20
- package/dist/store/mirrors.d.ts +2 -6
- package/dist/store/mirrors.js +14 -23
- package/dist/store/open.js +6 -13
- package/dist/store/planning-fallacy-evidence.d.ts +2 -30
- package/dist/store/planning-fallacy-evidence.js +8 -37
- package/dist/store/port.d.ts +82 -79
- package/dist/store/predictions.d.ts +11 -51
- package/dist/store/predictions.js +38 -119
- package/dist/{cli → store}/quality-repair.js +15 -31
- package/dist/store/raw-archive.d.ts +4 -16
- package/dist/store/raw-archive.js +14 -29
- package/dist/store/recall-scope.d.ts +19 -79
- package/dist/store/recall-scope.js +21 -82
- package/dist/store/recall-trace.d.ts +10 -77
- package/dist/store/recall-trace.js +19 -95
- package/dist/store/rejected-values.js +7 -19
- package/dist/store/rejection.d.ts +12 -58
- package/dist/store/rejection.js +13 -65
- package/dist/store/report-reads.d.ts +6 -0
- package/dist/store/report-reads.js +29 -0
- package/dist/store/rows.d.ts +9 -19
- package/dist/store/rows.js +36 -34
- package/dist/store/rule-sql.d.ts +5 -0
- package/dist/store/rule-sql.js +37 -0
- package/dist/store/search-rows.d.ts +7 -38
- package/dist/store/search-rows.js +14 -50
- package/dist/store/sessions.d.ts +10 -47
- package/dist/store/sessions.js +17 -73
- package/dist/store/sqlite/connector-events-group.js +2 -2
- package/dist/store/sqlite/entry-writes-group.js +2 -2
- package/dist/store/sqlite/error-codec.js +4 -2
- package/dist/store/sqlite/executor.d.ts +2 -1
- package/dist/store/sqlite/executor.js +2 -1
- package/dist/store/sqlite/local.d.ts +3 -3
- package/dist/store/sqlite/local.js +1 -0
- package/dist/store/sqlite/object-rows.js +6 -3
- package/dist/store/sqlite/objects-group.js +4 -2
- package/dist/store/sqlite/quarantine-group.js +2 -2
- package/dist/store/sqlite/store.d.ts +1 -4
- package/dist/store/sqlite/store.js +2 -3
- package/dist/store/sqlite/vector-reads-group.js +2 -2
- package/dist/store/sqlite/worker-jobs.js +1 -1
- package/dist/store/sqlite/worker-ops.d.ts +13 -2
- package/dist/store/sqlite/worker-ops.js +13 -2
- package/dist/store/sqlite/worker-store.js +5 -2
- package/dist/store/summaries.d.ts +10 -62
- package/dist/store/summaries.js +34 -146
- package/dist/store/summary-dirty.js +1 -1
- package/dist/store/tenant-lookup.d.ts +6 -1
- package/dist/store/tenant-lookup.js +7 -0
- package/dist/store/tenant.d.ts +2 -16
- package/dist/store/tenant.js +4 -19
- package/dist/store/token-ledger.d.ts +13 -43
- package/dist/store/token-ledger.js +19 -50
- package/dist/store/usage-reports.js +5 -13
- package/dist/store/vector-index.d.ts +46 -0
- package/dist/store/vector-index.js +170 -0
- package/dist/store/working-memory.d.ts +6 -25
- package/dist/store/working-memory.js +18 -52
- package/dist/store/yaml.d.ts +1 -5
- package/dist/store/yaml.js +2 -6
- package/dist/support-bundle.js +7 -5
- package/dist/trust/reject-flow.js +1 -3
- package/dist/util/anthropic-messages.js +14 -2
- package/dist/util/atomic-write.d.ts +2 -1
- package/dist/util/atomic-write.js +35 -4
- package/dist/util/capped-json.d.ts +6 -0
- package/dist/util/capped-json.js +46 -0
- package/dist/util/crash-handlers.d.ts +8 -1
- package/dist/util/crash-handlers.js +52 -10
- package/dist/util/env.d.ts +13 -6
- package/dist/util/env.js +14 -7
- package/dist/util/home-path.d.ts +2 -1
- package/dist/util/home-path.js +4 -2
- package/dist/util/http-retry.d.ts +3 -1
- package/dist/util/http-retry.js +26 -5
- package/dist/util/log.d.ts +3 -2
- package/dist/util/log.js +25 -9
- package/dist/util/request-scope.d.ts +2 -1
- package/dist/util/request-scope.js +2 -1
- package/dist/util/secret-detect.d.ts +5 -30
- package/dist/util/secret-detect.js +13 -39
- package/dist/util/stored-json.d.ts +1 -1
- package/dist/util/stored-json.js +1 -1
- package/dist/util/token-text.d.ts +1 -4
- package/dist/util/token-text.js +1 -4
- package/dist/util/transcript-tail.d.ts +2 -0
- package/dist/util/transcript-tail.js +24 -23
- package/dist/util/version.d.ts +5 -20
- package/dist/util/version.js +5 -20
- package/extensions/openclaw-plugin/index.ts +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 +1 -1
- package/dist/connectors/github/cli-impl.d.ts +0 -25
- package/dist/sharing/shared.d.ts +0 -187
- package/dist/sharing/shared.js +0 -563
- package/dist/store/vector-writes.d.ts +0 -13
- package/dist/store/vector-writes.js +0 -89
- /package/dist/{cli → store}/quality-repair.d.ts +0 -0
package/README.md
CHANGED
|
@@ -784,7 +784,7 @@ hippo watch "npm run build"
|
|
|
784
784
|
| `hippo dashboard` | Open web dashboard at localhost:3333 (memory health by project, and the card board); open the printed URL, which carries a per-start access token |
|
|
785
785
|
| `hippo dashboard --port <n>` | Use custom port |
|
|
786
786
|
| `hippo mcp` | Start MCP server (stdio transport) |
|
|
787
|
-
| `hippo serve` | Start the HTTP API server for this store on `127.0.0.1:6789` (`--port <n>` or `HIPPO_PORT`; `--host <host>`, which off loopback needs `HIPPO_REQUIRE_AUTH=1`) |
|
|
787
|
+
| `hippo serve` | Start the HTTP API server for this store on `127.0.0.1:6789` (`--port <n>` or `HIPPO_PORT`; `--host <host>`, which off loopback needs `HIPPO_REQUIRE_AUTH=1`). Every request needs an API key (`hippo auth create`, then `Authorization: Bearer <key>`; the hippo CLI reads `HIPPO_API_KEY`). `HIPPO_ALLOW_KEYLESS_LOCAL=1` lets requests from this machine in without one, as host admin; `HIPPO_REQUIRE_AUTH=1` wins over it |
|
|
788
788
|
| `hippo serve --tls-cert <file> --tls-key <file>` | Serve HTTPS with that PEM certificate and key (or set `HIPPO_TLS_CERT` and `HIPPO_TLS_KEY`). Without them a network bind still starts, and warns once that API keys and memory text travel in cleartext unless a TLS-terminating proxy sits in front |
|
|
789
789
|
|
|
790
790
|
On `heartbeat`, `block`, `review` and `complete`, a given `--run` is checked against the card's live run and the command is refused, unchanged, if the two do not match.
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { type ProjectIdentity } from '../core/project-identity.js';
|
|
2
2
|
import type { Adapter, AdapterContext, Listing } from './types.js';
|
|
3
|
-
/** Claude Code's rule: a linked worktree shares its main checkout's folder, or the git folder's when that sits outside
|
|
3
|
+
/** Claude Code's rule: a linked worktree shares its main checkout's folder, or the git folder's when that sits outside
|
|
4
|
+
* a checkout (a bare repository, or --separate-git-dir); any other checkout, a submodule included, keeps its own. */
|
|
4
5
|
export declare function claudeCheckoutRoot(top: string, gitDir: string, common: string): string;
|
|
5
6
|
/** Claude Code's folder name for a path: non-alphanumerics made '-', and a name over 200 characters cut to 200 plus a base-36 hash of the whole path. */
|
|
6
7
|
export declare function claudeFolderName(root: string): string;
|
|
7
8
|
export declare const claudeCodeAdapter: Adapter;
|
|
8
9
|
/** A session's own notes folder and nothing else, with no git call, so post-compact can read it inside the hook's time limit. */
|
|
9
10
|
export declare function claudeTranscriptListing(ctx: AdapterContext, transcriptPath: string): Listing;
|
|
10
|
-
/** The project a session folder's notes belong to: the one Claude named the folder
|
|
11
|
+
/** The project a session folder's notes belong to: the one Claude named the folder
|
|
12
|
+
* for, the session's start folder, else cwd or a parent; null when none matches. */
|
|
11
13
|
export declare function transcriptNotesProject(transcriptPath: string, cwd: string | null, machine: Pick<AdapterContext, 'platform' | 'env'>): ProjectIdentity | null;
|
|
12
14
|
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -21,7 +21,8 @@ function claudeMemoryFolderNames(projectRoot, platform) {
|
|
|
21
21
|
roots.push(claudeCheckoutRoot(layout.top, layout.gitDir, layout.common));
|
|
22
22
|
return new Set(roots.map((root) => (platform === 'win32' ? claudeFolderName(root).toLowerCase() : claudeFolderName(root))));
|
|
23
23
|
}
|
|
24
|
-
/** Claude Code's rule: a linked worktree shares its main checkout's folder, or the git folder's when that sits outside
|
|
24
|
+
/** Claude Code's rule: a linked worktree shares its main checkout's folder, or the git folder's when that sits outside
|
|
25
|
+
* a checkout (a bare repository, or --separate-git-dir); any other checkout, a submodule included, keeps its own. */
|
|
25
26
|
export function claudeCheckoutRoot(top, gitDir, common) {
|
|
26
27
|
if (gitDir === common)
|
|
27
28
|
return top;
|
|
@@ -55,7 +56,8 @@ export function claudeTranscriptListing(ctx, transcriptPath) {
|
|
|
55
56
|
const folder = path.join(path.dirname(transcriptPath), 'memory');
|
|
56
57
|
return { tool: 'claude-code', home: config, containers: readFolders([folder], 'project', ctx.platform), warnings: [] };
|
|
57
58
|
}
|
|
58
|
-
/** The project a session folder's notes belong to: the one Claude named the folder
|
|
59
|
+
/** The project a session folder's notes belong to: the one Claude named the folder
|
|
60
|
+
* for, the session's start folder, else cwd or a parent; null when none matches. */
|
|
59
61
|
export function transcriptNotesProject(transcriptPath, cwd, machine) {
|
|
60
62
|
const fold = (name) => (machine.platform === 'win32' ? name.toLowerCase() : name);
|
|
61
63
|
const folder = fold(path.basename(path.dirname(transcriptPath)));
|
|
@@ -79,9 +81,16 @@ export function transcriptNotesProject(transcriptPath, cwd, machine) {
|
|
|
79
81
|
const START_SCAN_BYTES = 64 * 1024;
|
|
80
82
|
/** The cwd on the transcript's first line that has one: the folder Claude named the session folder for, which a folder name alone cannot give back. */
|
|
81
83
|
function transcriptStartCwd(transcriptPath) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
let fd;
|
|
85
|
+
try {
|
|
86
|
+
fd = fs.openSync(transcriptPath, 'r');
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
// A transcript that is not there names no start folder; any other failure is the caller's to see.
|
|
90
|
+
if (err instanceof Error && 'code' in err && (err.code === 'ENOENT' || err.code === 'ENOTDIR'))
|
|
91
|
+
return null;
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
85
94
|
try {
|
|
86
95
|
const buf = Buffer.alloc(START_SCAN_BYTES);
|
|
87
96
|
const lines = buf.subarray(0, fs.readSync(fd, buf, 0, buf.length, 0)).toString('utf8').split('\n');
|
|
@@ -7,23 +7,34 @@ const MAX_DEPTH = 8;
|
|
|
7
7
|
/** A file's text, or why it was skipped: empty, too big, holds a NUL byte (not text), or unreadable. */
|
|
8
8
|
export function readTextFile(file) {
|
|
9
9
|
try {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const buf = fs.readFileSync(file);
|
|
19
|
-
if (buf.includes(0))
|
|
20
|
-
return { ok: false, reason: `${file}: not text` };
|
|
21
|
-
return { ok: true, text: buf.toString('utf8'), mtimeMs: stat.mtimeMs };
|
|
10
|
+
// O_NONBLOCK opens a FIFO at once, for the file check to turn away; Windows has no such flag and the OR adds nothing.
|
|
11
|
+
const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK);
|
|
12
|
+
try {
|
|
13
|
+
return readOpenTextFile(file, fd);
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
fs.closeSync(fd);
|
|
17
|
+
}
|
|
22
18
|
}
|
|
23
19
|
catch (err) {
|
|
24
20
|
return { ok: false, reason: `${file}: ${errorMessage(err)}` };
|
|
25
21
|
}
|
|
26
22
|
}
|
|
23
|
+
/** The checks and the read on one descriptor, so the file measured is the file read. */
|
|
24
|
+
function readOpenTextFile(file, fd) {
|
|
25
|
+
const stat = fs.fstatSync(fd);
|
|
26
|
+
if (!stat.isFile())
|
|
27
|
+
return { ok: false, reason: `${file}: not a file` };
|
|
28
|
+
// A tool rewriting a file truncates it first; read as holding no notes, every row would be set aside.
|
|
29
|
+
if (stat.size === 0)
|
|
30
|
+
return { ok: false, reason: `${file}: empty` };
|
|
31
|
+
if (stat.size > MAX_ITEM_BYTES)
|
|
32
|
+
return { ok: false, reason: `${file}: over ${MAX_ITEM_BYTES} bytes` };
|
|
33
|
+
const buf = fs.readFileSync(fd);
|
|
34
|
+
if (buf.includes(0))
|
|
35
|
+
return { ok: false, reason: `${file}: not text` };
|
|
36
|
+
return { ok: true, text: buf.toString('utf8'), mtimeMs: stat.mtimeMs };
|
|
37
|
+
}
|
|
27
38
|
/** Files in a folder as '/'-separated relative paths, sorted; dot entries skipped, symlinked folders not followed. */
|
|
28
39
|
export function listFiles(dir, opts) {
|
|
29
40
|
if (!fs.existsSync(dir))
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Splits one markdown memory file into items (a top-level bullet or a paragraph), each tagged with its heading. Pure.
|
|
3
|
-
*/
|
|
1
|
+
/** Splits one markdown memory file into items (a top-level bullet or a paragraph), each tagged with its heading. Pure. */
|
|
4
2
|
export interface MarkdownItem {
|
|
5
3
|
readonly heading: string;
|
|
6
4
|
readonly headingSlug: string;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Splits one markdown memory file into items (a top-level bullet or a paragraph), each tagged with its heading. Pure.
|
|
3
|
-
*/
|
|
1
|
+
/** Splits one markdown memory file into items (a top-level bullet or a paragraph), each tagged with its heading. Pure. */
|
|
4
2
|
const HEADING = /^#{1,6}\s+/;
|
|
5
3
|
// Column 0 only: an indented marker is a sub-bullet and stays inside its item.
|
|
6
4
|
const BULLET = /^(?:[-*+]|\d+[.)]) /;
|
|
@@ -47,7 +47,8 @@ export function totalTally(report) {
|
|
|
47
47
|
const plural = (n, one, many) => `${n} ${n === 1 ? one : many}`;
|
|
48
48
|
const TALLY_WORDS = {
|
|
49
49
|
imported: 'new', replaced: 'replaced', restored: 'brought back', setAside: 'set aside', untagged: 'pinned and kept',
|
|
50
|
-
unchanged: 'unchanged', adopted: 'taken over from the old Claude import', renamed: 'moved to the project id', collapsed: 'duplicates folded',
|
|
50
|
+
unchanged: 'unchanged', adopted: 'taken over from the old Claude import', renamed: 'moved to the project id', collapsed: 'duplicates folded',
|
|
51
|
+
retagged: 'retagged',
|
|
51
52
|
handedOver: 'handed over from the global store', duplicate: 'already stored', secret: 'skipped for a secret', short: 'too short',
|
|
52
53
|
rejected: 'skipped as rejected', unread: 'files skipped', unreadable: 'unreadable folders', busy: 'busy folders',
|
|
53
54
|
};
|
|
@@ -24,9 +24,11 @@ export declare function importForStore(hippoRoot: string, opts: SyncOptions): Im
|
|
|
24
24
|
export declare function importProjectMemories(hippoRoot: string, opts: SyncOptions): ImportReport;
|
|
25
25
|
/** Every tool's user-level memory into the global store, created on demand, with no origin. */
|
|
26
26
|
export declare function importUserMemories(invokingRoot: string, opts: SyncOptions): ImportReport;
|
|
27
|
-
/** Session end in a folder with no store of its own: the session's project into the
|
|
27
|
+
/** Session end in a folder with no store of its own: the session's project into the
|
|
28
|
+
* global store with its origin, the session folder's notes, then the user pass. */
|
|
28
29
|
export declare function importAtSessionEnd(cwd: string, transcriptPath: string | undefined, opts: SyncOptions): ImportReport;
|
|
29
|
-
/** The session folder's notes under the project Claude filed them for, never cwd's: a session begun at
|
|
30
|
+
/** The session folder's notes under the project Claude filed them for, never cwd's: a session begun at
|
|
31
|
+
* home keeps its home notes user-global wherever it ends. No git call, so post-compact can run it. */
|
|
30
32
|
export declare function importSessionFolder(hippoRoot: string, transcriptPath: string, cwd: string | null, opts: SyncOptions): ImportReport;
|
|
31
33
|
/** The variable when set (empty or `none` is off); else the tools both the invoking and the target store's config allow. */
|
|
32
34
|
export declare function allowedTools(env: Machine['env'], invoking: string, target: string, warnings: string[]): Set<ToolId>;
|
|
@@ -44,29 +44,34 @@ export function importForStore(hippoRoot, opts) {
|
|
|
44
44
|
export function importProjectMemories(hippoRoot, opts) {
|
|
45
45
|
const ctx = context(opts.machine, { projectRoot: path.dirname(hippoRoot) });
|
|
46
46
|
return runPass({
|
|
47
|
-
scope: 'project', target: hippoRoot, invoking: hippoRoot, list: (a) => a.list(ctx, 'project'), legacy: true, originProject: undefined,
|
|
47
|
+
scope: 'project', target: hippoRoot, invoking: hippoRoot, list: (a) => a.list(ctx, 'project'), legacy: true, originProject: undefined,
|
|
48
|
+
legacyOrigins: [], handover: true,
|
|
48
49
|
}, opts);
|
|
49
50
|
}
|
|
50
51
|
/** Every tool's user-level memory into the global store, created on demand, with no origin. */
|
|
51
52
|
export function importUserMemories(invokingRoot, opts) {
|
|
52
53
|
const ctx = context(opts.machine, {});
|
|
53
54
|
return runPass({
|
|
54
|
-
scope: 'user', target: resolveGlobalRootDir(), invoking: invokingRoot, list: (a) => a.list(ctx, 'user'), legacy: false, originProject: '',
|
|
55
|
+
scope: 'user', target: resolveGlobalRootDir(), invoking: invokingRoot, list: (a) => a.list(ctx, 'user'), legacy: false, originProject: '',
|
|
56
|
+
legacyOrigins: [], handover: false,
|
|
55
57
|
}, opts);
|
|
56
58
|
}
|
|
57
|
-
/** Session end in a folder with no store of its own: the session's project into the
|
|
59
|
+
/** Session end in a folder with no store of its own: the session's project into the
|
|
60
|
+
* global store with its origin, the session folder's notes, then the user pass. */
|
|
58
61
|
export function importAtSessionEnd(cwd, transcriptPath, opts) {
|
|
59
62
|
const globalRoot = resolveGlobalRootDir();
|
|
60
63
|
const ctx = context(opts.machine, { projectRoot: cwd });
|
|
61
64
|
const report = runPass({
|
|
62
|
-
scope: 'project', target: globalRoot, invoking: globalRoot, list: (a) => a.list(ctx, 'project'), legacy: false,
|
|
65
|
+
scope: 'project', target: globalRoot, invoking: globalRoot, list: (a) => a.list(ctx, 'project'), legacy: false,
|
|
66
|
+
...projectOrigins(resolveProjectIdentity(cwd)), handover: false,
|
|
63
67
|
}, opts);
|
|
64
68
|
if (transcriptPath !== undefined)
|
|
65
69
|
mergeReports(report, importSessionFolder(globalRoot, transcriptPath, cwd, opts));
|
|
66
70
|
mergeReports(report, importUserMemories(globalRoot, opts));
|
|
67
71
|
return report;
|
|
68
72
|
}
|
|
69
|
-
/** The session folder's notes under the project Claude filed them for, never cwd's: a session begun at
|
|
73
|
+
/** The session folder's notes under the project Claude filed them for, never cwd's: a session begun at
|
|
74
|
+
* home keeps its home notes user-global wherever it ends. No git call, so post-compact can run it. */
|
|
70
75
|
export function importSessionFolder(hippoRoot, transcriptPath, cwd, opts) {
|
|
71
76
|
const project = transcriptNotesProject(transcriptPath, cwd, opts.machine);
|
|
72
77
|
if (project === null)
|
package/dist/api/assemble.d.ts
CHANGED
|
@@ -9,19 +9,10 @@ export interface AssembleOpts {
|
|
|
9
9
|
/** Substitute parent summaries for older raws when ≥2 share a level-2
|
|
10
10
|
* ancestor. Default true. */
|
|
11
11
|
summarizeOlder?: boolean;
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* `recall`: when set, exact match required (so an authorised caller can
|
|
15
|
-
* assemble a `slack:private:CSEC` session by passing scope explicitly).
|
|
16
|
-
* When undefined, default-deny applies to ANY `<source>:private:*` and
|
|
17
|
-
* `unknown:legacy` rows.
|
|
18
|
-
*/
|
|
12
|
+
/** Exact scope match when set, so an authorised caller can assemble a private session.
|
|
13
|
+
* When undefined, default-deny applies to every `<source>:private:*` and `unknown:legacy` row. */
|
|
19
14
|
scope?: string;
|
|
20
|
-
/**
|
|
21
|
-
* Hard row cap on the SELECT that loads session raws. Default 5000 to
|
|
22
|
-
* protect against degenerate sessions. When the cap is hit, `truncated`
|
|
23
|
-
* is set on the result so the caller knows to widen.
|
|
24
|
-
*/
|
|
15
|
+
/** Hard row cap on the SELECT that loads session raws (default 5000); `truncated` is set when it is hit. */
|
|
25
16
|
rowCap?: number;
|
|
26
17
|
cost?: AssembleCost;
|
|
27
18
|
project?: CallerProject;
|
|
@@ -51,42 +42,14 @@ export interface AssembleResult {
|
|
|
51
42
|
sessionId: string;
|
|
52
43
|
items: AssembledContextItem[];
|
|
53
44
|
tokens: number;
|
|
54
|
-
/**
|
|
55
|
-
* Tenant + scope-filtered raw row count for the session, uncapped by `rowCap`, so
|
|
56
|
-
* "session has N msgs" stays accurate when items[] is the windowed view.
|
|
57
|
-
*/
|
|
45
|
+
/** Tenant + scope-filtered raw row count, uncapped by `rowCap`, so "session has N msgs" stays accurate for a windowed items[]. */
|
|
58
46
|
totalRaw: number;
|
|
59
47
|
summarized: number;
|
|
60
48
|
evicted: number;
|
|
61
|
-
/**
|
|
62
|
-
* True when `rowCap` truncated the loaded window. The cap keeps the NEWEST
|
|
63
|
-
* rows, so the items[] array represents the freshest tail of the session;
|
|
64
|
-
* older rows beyond the cap are silently absent. Use `totalRaw - items.length
|
|
65
|
-
* - summarized + ...` to estimate how much you didn't see, or widen `rowCap`.
|
|
66
|
-
*/
|
|
49
|
+
/** True when `rowCap` truncated the window; the cap keeps the NEWEST rows, so older rows beyond it are absent. */
|
|
67
50
|
truncated: boolean;
|
|
68
51
|
}
|
|
69
|
-
/**
|
|
70
|
-
*
|
|
71
|
-
* lossless-claw context-engine pattern to Hippo's score-ranked memory store.
|
|
72
|
-
*
|
|
73
|
-
* Algorithm:
|
|
74
|
-
* 1. Load all kind='raw' rows for the session, tenant + scope filtered.
|
|
75
|
-
* 2. Split: newest `freshTailCount` are protected (fresh tail).
|
|
76
|
-
* 3. For older rows, when ≥2 share a level-2 parent, substitute the
|
|
77
|
-
* summary; everything else passes through as raw.
|
|
78
|
-
* 4. Hippo-additive eviction: when over-budget, drop the lowest-strength
|
|
79
|
-
* non-fresh-tail item first. Fresh-tail rows are never evicted.
|
|
80
|
-
*
|
|
81
|
-
* Strength-weighted eviction is the differentiator from lossless-claw,
|
|
82
|
-
* which evicts oldest-first. A high-strength older row (high retrieval
|
|
83
|
-
* count, slow decay) survives; a low-strength recent row (newer but
|
|
84
|
-
* unimportant) goes first.
|
|
85
|
-
*
|
|
86
|
-
* Returns `items: []` cleanly when:
|
|
87
|
-
* - sessionId is empty
|
|
88
|
-
* - no raws exist for the session
|
|
89
|
-
* - all rows fail the scope/tenant filter
|
|
90
|
-
*/
|
|
52
|
+
/** Chronological context window for a session; over budget, evicts the lowest-strength non-fresh-tail item first (fresh tail is never evicted).
|
|
53
|
+
* Returns `items: []` for an empty sessionId, no raws, or when every row fails the scope/tenant filter. */
|
|
91
54
|
export declare function assemble(ctx: Context, sessionId: string, opts?: AssembleOpts): Promise<AssembleResult>;
|
|
92
55
|
//# sourceMappingURL=assemble.d.ts.map
|
package/dist/api/assemble.js
CHANGED
|
@@ -6,28 +6,8 @@ import { classifyOriginProject, projectNames } from '../core/project-identity.js
|
|
|
6
6
|
const DEFAULT_FRESH_TAIL_COUNT = 10;
|
|
7
7
|
const DEFAULT_ROW_CAP = 5000;
|
|
8
8
|
export const DEFAULT_ASSEMBLE_BUDGET = 4000;
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* lossless-claw context-engine pattern to Hippo's score-ranked memory store.
|
|
12
|
-
*
|
|
13
|
-
* Algorithm:
|
|
14
|
-
* 1. Load all kind='raw' rows for the session, tenant + scope filtered.
|
|
15
|
-
* 2. Split: newest `freshTailCount` are protected (fresh tail).
|
|
16
|
-
* 3. For older rows, when ≥2 share a level-2 parent, substitute the
|
|
17
|
-
* summary; everything else passes through as raw.
|
|
18
|
-
* 4. Hippo-additive eviction: when over-budget, drop the lowest-strength
|
|
19
|
-
* non-fresh-tail item first. Fresh-tail rows are never evicted.
|
|
20
|
-
*
|
|
21
|
-
* Strength-weighted eviction is the differentiator from lossless-claw,
|
|
22
|
-
* which evicts oldest-first. A high-strength older row (high retrieval
|
|
23
|
-
* count, slow decay) survives; a low-strength recent row (newer but
|
|
24
|
-
* unimportant) goes first.
|
|
25
|
-
*
|
|
26
|
-
* Returns `items: []` cleanly when:
|
|
27
|
-
* - sessionId is empty
|
|
28
|
-
* - no raws exist for the session
|
|
29
|
-
* - all rows fail the scope/tenant filter
|
|
30
|
-
*/
|
|
9
|
+
/** Chronological context window for a session; over budget, evicts the lowest-strength non-fresh-tail item first (fresh tail is never evicted).
|
|
10
|
+
* Returns `items: []` for an empty sessionId, no raws, or when every row fails the scope/tenant filter. */
|
|
31
11
|
export async function assemble(ctx, sessionId, opts = {}) {
|
|
32
12
|
assertScopeRequestAllowed(ctx.actor, opts.scope);
|
|
33
13
|
const budget = opts.budget ?? DEFAULT_ASSEMBLE_BUDGET;
|
package/dist/api/audit.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuditEvent, AuditOp } from '../store/audit.js';
|
|
1
|
+
import type { AuditEvent, AuditIssue, AuditOp } from '../store/audit.js';
|
|
2
2
|
import type { KeysetPosition } from '../util/keyset.js';
|
|
3
3
|
import type { Context } from './types.js';
|
|
4
4
|
export interface AuditListOpts {
|
|
@@ -11,4 +11,8 @@ export interface AuditListOpts {
|
|
|
11
11
|
}
|
|
12
12
|
/** Read audit events scoped to `ctx.tenantId` on the store the request runs on. Read-only, no audit emit. */
|
|
13
13
|
export declare function auditList(ctx: Context, opts: AuditListOpts): Promise<AuditEvent[]>;
|
|
14
|
+
/** The pass that removes audit errors; it leads the reason on each forget row. */
|
|
15
|
+
export type AuditPass = 'audit --fix' | 'sleep-audit';
|
|
16
|
+
/** Delete the memories an audit marked as errors, each with its own forget row, and answer the ids that went: a pinned or raw row stays. */
|
|
17
|
+
export declare function removeAuditErrors(ctx: Context, pass: AuditPass, issues: readonly AuditIssue[]): string[];
|
|
14
18
|
//# sourceMappingURL=audit.d.ts.map
|
package/dist/api/audit.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// Audit log queries.
|
|
1
|
+
// Audit log queries, and the removal of the memories a quality audit marks as errors.
|
|
2
|
+
import { deleteEntry } from '../store/delete-and-batch.js';
|
|
2
3
|
import { requireGroup, storeFor } from '../store/index.js';
|
|
3
4
|
/** Read audit events scoped to `ctx.tenantId` on the store the request runs on. Read-only, no audit emit. */
|
|
4
5
|
export async function auditList(ctx, opts) {
|
|
@@ -6,4 +7,11 @@ export async function auditList(ctx, opts) {
|
|
|
6
7
|
tenantId: ctx.tenantId, op: opts.op, since: opts.since, limit: opts.limit, after: opts.after,
|
|
7
8
|
});
|
|
8
9
|
}
|
|
10
|
+
/** Delete the memories an audit marked as errors, each with its own forget row, and answer the ids that went: a pinned or raw row stays. */
|
|
11
|
+
export function removeAuditErrors(ctx, pass, issues) {
|
|
12
|
+
return issues
|
|
13
|
+
.filter((issue) => issue.severity === 'error')
|
|
14
|
+
.filter((issue) => deleteEntry(ctx.hippoRoot, issue.memoryId, { actor: ctx.actor.subject, reason: `${pass}: ${issue.reason}`, automatic: true }))
|
|
15
|
+
.map((issue) => issue.memoryId);
|
|
16
|
+
}
|
|
9
17
|
//# sourceMappingURL=audit.js.map
|
package/dist/api/auth.d.ts
CHANGED
|
@@ -3,13 +3,12 @@ import type { KeysetPosition } from '../util/keyset.js';
|
|
|
3
3
|
import type { Context, StoreReply } from './types.js';
|
|
4
4
|
export interface AuthCreateOpts {
|
|
5
5
|
label?: string;
|
|
6
|
-
/**
|
|
7
|
-
* Authorization role for the new key. Defaults to `'admin'` for
|
|
8
|
-
* back-compat with keys minted before roles existed (the api_keys.role column DEFAULT also
|
|
9
|
-
* resolves to 'admin' if omitted from the INSERT). Member keys are
|
|
10
|
-
* 403-blocked from admin-gated routes (e.g. `POST /v1/sleep`).
|
|
11
|
-
*/
|
|
6
|
+
/** Defaults to `'member'`, which admin-gated routes such as `POST /v1/sleep` refuse; an admin key has to be asked for by name. */
|
|
12
7
|
role?: 'admin' | 'member';
|
|
8
|
+
/** Days until the key expires: above 0 and at most 3650. Defaults to 90. */
|
|
9
|
+
ttlDays?: number;
|
|
10
|
+
/** True mints a key that never expires, which has to be asked for by name; refused together with `ttlDays`. */
|
|
11
|
+
noExpiry?: boolean;
|
|
13
12
|
}
|
|
14
13
|
export interface AuthCreateResult {
|
|
15
14
|
keyId: string;
|
|
@@ -17,18 +16,11 @@ export interface AuthCreateResult {
|
|
|
17
16
|
tenantId: string;
|
|
18
17
|
/** The role bound to the new key (admin | member). */
|
|
19
18
|
role: 'admin' | 'member';
|
|
19
|
+
/** ISO time the key stops working; null for a key that never expires. */
|
|
20
|
+
expiresAt: string | null;
|
|
20
21
|
}
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
* cannot override the tenant via the opts bag — a previous `tenantId` field
|
|
24
|
-
* was removed because the HTTP layer would happily forward `body.tenantId`,
|
|
25
|
-
* letting tenant A mint a key for tenant B. The HTTP route handler at
|
|
26
|
-
* `src/server.ts` POST /v1/auth/keys mirrors this: it ignores any body
|
|
27
|
-
* `tenantId` and uses the resolved Bearer's tenant exclusively.
|
|
28
|
-
*
|
|
29
|
-
* Only an admin actor can mint (ForbiddenError otherwise), and a key never
|
|
30
|
-
* outranks its minter: a resolver admin is tenant-only, so it mints members.
|
|
31
|
-
*/
|
|
22
|
+
/** Mints a key always bound to `ctx.tenantId`; opts cannot override the tenant, or tenant A could mint a key for tenant B.
|
|
23
|
+
* Admin only (ForbiddenError otherwise), and a key never outranks its minter: a resolver admin is tenant-only, so it mints members. */
|
|
32
24
|
export declare function authCreate<C extends Context>(ctx: C, opts: AuthCreateOpts): StoreReply<C, AuthCreateResult>;
|
|
33
25
|
export interface AuthCreateSelfOpts {
|
|
34
26
|
label?: string;
|
|
@@ -41,7 +33,8 @@ export interface AuthCreateSelfResult extends AuthCreateResult {
|
|
|
41
33
|
/** ISO time the key stops working. */
|
|
42
34
|
expiresAt: string;
|
|
43
35
|
}
|
|
44
|
-
/** Mint a member key for the caller an auth resolver vouched for, whatever its role; the
|
|
36
|
+
/** Mint a member key for the caller an auth resolver vouched for, whatever its role; the
|
|
37
|
+
* binary floor, the cap's revokes, the mint and its audit rows commit or fail together. */
|
|
45
38
|
export declare function authCreateSelf<C extends Context>(ctx: C, opts: AuthCreateSelfOpts): StoreReply<C, AuthCreateSelfResult>;
|
|
46
39
|
type KeyListOpts = {
|
|
47
40
|
active: boolean;
|
|
@@ -58,10 +51,8 @@ export type AuthRevokeReply<C extends Context> = StoreReply<C, AuthRevokeResult>
|
|
|
58
51
|
/** Revoke a key in the caller's tenant: a member API key may revoke only itself, a resolver member only the keys it minted.
|
|
59
52
|
* The revoke and its auth_revoke row commit together on either store, so a failed audit write leaves the key live. */
|
|
60
53
|
export declare function authRevoke<C extends Context>(ctx: C, keyId: string): AuthRevokeReply<C>;
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
* so the local CLI can run revoke and grant in the key's own tenant.
|
|
64
|
-
*/
|
|
54
|
+
/** The tenant that owns `keyId`, or undefined for an unknown key. Host admin only: it reads across tenants,
|
|
55
|
+
* so the local CLI can run revoke and grant in the key's own tenant. */
|
|
65
56
|
export declare function authKeyTenant(ctx: Context, keyId: string): string | undefined;
|
|
66
57
|
/** Shared result shape for authGrant/authUngrant, named per the file's oxlint anti-slop rule. */
|
|
67
58
|
export interface AuthGrantResult {
|
package/dist/api/auth.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// API key management: create, list, revoke, and grant or ungrant restricted scopes.
|
|
2
|
-
import { ForbiddenError, NotFoundError } from '../core/api-errors.js';
|
|
2
|
+
import { BadRequestError, ForbiddenError, NotFoundError } from '../core/api-errors.js';
|
|
3
3
|
import { mintApiKey, } from '../store/auth.js';
|
|
4
4
|
import { changeScopeGrant } from '../store/sqlite/local.js';
|
|
5
5
|
import { sqliteSyncStore } from '../store/sqlite/store.js';
|
|
@@ -10,17 +10,8 @@ const API_KEY_SUBJECT = 'api_key:';
|
|
|
10
10
|
function keyIdOfSubject(subject) {
|
|
11
11
|
return subject.startsWith(API_KEY_SUBJECT) ? subject.slice(API_KEY_SUBJECT.length) : null;
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
* cannot override the tenant via the opts bag — a previous `tenantId` field
|
|
16
|
-
* was removed because the HTTP layer would happily forward `body.tenantId`,
|
|
17
|
-
* letting tenant A mint a key for tenant B. The HTTP route handler at
|
|
18
|
-
* `src/server.ts` POST /v1/auth/keys mirrors this: it ignores any body
|
|
19
|
-
* `tenantId` and uses the resolved Bearer's tenant exclusively.
|
|
20
|
-
*
|
|
21
|
-
* Only an admin actor can mint (ForbiddenError otherwise), and a key never
|
|
22
|
-
* outranks its minter: a resolver admin is tenant-only, so it mints members.
|
|
23
|
-
*/
|
|
13
|
+
/** Mints a key always bound to `ctx.tenantId`; opts cannot override the tenant, or tenant A could mint a key for tenant B.
|
|
14
|
+
* Admin only (ForbiddenError otherwise), and a key never outranks its minter: a resolver admin is tenant-only, so it mints members. */
|
|
24
15
|
export function authCreate(ctx, opts) {
|
|
25
16
|
// The key and its auth_create row commit together on either store, so a failed audit write leaves no key.
|
|
26
17
|
return onStore(ctx, (port) => {
|
|
@@ -34,6 +25,23 @@ function newKey(ctx, fields) {
|
|
|
34
25
|
const { keyId, plaintext, keyHash } = mintApiKey();
|
|
35
26
|
return { plaintext, key: { ...fields, keyId, keyHash, tenantId: ctx.tenantId, createdAt: new Date().toISOString() } };
|
|
36
27
|
}
|
|
28
|
+
/** Days a key lives when its mint names no expiry, so a key nobody remembers stops working by itself. */
|
|
29
|
+
const DEFAULT_KEY_TTL_DAYS = 90;
|
|
30
|
+
// The ceiling keeps toISOString in range.
|
|
31
|
+
const MAX_TTL_DAYS = 3650;
|
|
32
|
+
/** A 400, not a RangeError, since the caller of the mint chose these. */
|
|
33
|
+
function mintExpiry({ ttlDays, noExpiry }) {
|
|
34
|
+
if (noExpiry && ttlDays !== undefined) {
|
|
35
|
+
throw new BadRequestError('send ttlDays or noExpiry, not both');
|
|
36
|
+
}
|
|
37
|
+
if (noExpiry)
|
|
38
|
+
return null;
|
|
39
|
+
const days = ttlDays ?? DEFAULT_KEY_TTL_DAYS;
|
|
40
|
+
if (!Number.isFinite(days) || days <= 0 || days > MAX_TTL_DAYS) {
|
|
41
|
+
throw new BadRequestError(`ttlDays must be above 0 and at most ${MAX_TTL_DAYS}`);
|
|
42
|
+
}
|
|
43
|
+
return new Date(Date.now() + days * DAY_MS).toISOString();
|
|
44
|
+
}
|
|
37
45
|
function adminKeyMint(ctx, opts) {
|
|
38
46
|
if (ctx.actor.role !== 'admin') {
|
|
39
47
|
throw new ForbiddenError('Only an admin key can create API keys');
|
|
@@ -41,16 +49,16 @@ function adminKeyMint(ctx, opts) {
|
|
|
41
49
|
if (ctx.actor.viaAuthResolver && opts.role === 'admin') {
|
|
42
50
|
throw new ForbiddenError('A key minted through the auth resolver can only be a member key');
|
|
43
51
|
}
|
|
44
|
-
const role = opts.role ??
|
|
52
|
+
const role = opts.role ?? 'member';
|
|
45
53
|
const label = opts.label ?? null;
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
const expiresAt = mintExpiry(opts);
|
|
55
|
+
const { plaintext, key } = newKey(ctx, { label, role, ownerSubject: null, expiresAt });
|
|
56
|
+
// The plaintext is NEVER logged; the audit row carries what the key can do and for how long, keyId is non-secret.
|
|
57
|
+
return { plaintext, mint: { key, actor: ctx.actor.subject, metadata: { label, role, expiresAt } } };
|
|
49
58
|
}
|
|
50
59
|
function createResult({ key }, plaintext) {
|
|
51
|
-
return { keyId: key.keyId, plaintext, tenantId: key.tenantId, role: key.role };
|
|
60
|
+
return { keyId: key.keyId, plaintext, tenantId: key.tenantId, role: key.role, expiresAt: key.expiresAt };
|
|
52
61
|
}
|
|
53
|
-
const MAX_TTL_DAYS = 3650;
|
|
54
62
|
/** A RangeError, not a 4xx, since the operator's config sets these; the ttl ceiling keeps toISOString in range and a departed user's key short-lived. */
|
|
55
63
|
function assertSelfMintOpts({ ttlDays, perSubject }) {
|
|
56
64
|
if (!Number.isFinite(ttlDays) || ttlDays <= 0 || ttlDays > MAX_TTL_DAYS) {
|
|
@@ -60,7 +68,8 @@ function assertSelfMintOpts({ ttlDays, perSubject }) {
|
|
|
60
68
|
throw new RangeError(`authCreateSelf: perSubject must be a whole number of at least 1, got ${String(perSubject)}`);
|
|
61
69
|
}
|
|
62
70
|
}
|
|
63
|
-
/** Mint a member key for the caller an auth resolver vouched for, whatever its role; the
|
|
71
|
+
/** Mint a member key for the caller an auth resolver vouched for, whatever its role; the
|
|
72
|
+
* binary floor, the cap's revokes, the mint and its audit rows commit or fail together. */
|
|
64
73
|
export function authCreateSelf(ctx, opts) {
|
|
65
74
|
return onStore(ctx, (port) => {
|
|
66
75
|
const keyWrites = port.keyWrites ?? notPorted(port, 'keyWrites');
|
|
@@ -79,7 +88,10 @@ function selfKeyMint(ctx, opts) {
|
|
|
79
88
|
// Not destructured: a binding pattern makes TypeScript infer F as KeyFields and lose ownerSubject's string type.
|
|
80
89
|
const made = newKey(ctx, { label, role: 'member', ownerSubject: subject, expiresAt });
|
|
81
90
|
// Same op and actor as an admin mint, so a lookup by audit row finds this key too.
|
|
82
|
-
return {
|
|
91
|
+
return {
|
|
92
|
+
plaintext: made.plaintext,
|
|
93
|
+
mint: { key: made.key, actor: subject, metadata: { label, role: 'member', self: true, expiresAt }, perSubject: opts.perSubject }
|
|
94
|
+
};
|
|
83
95
|
}
|
|
84
96
|
function selfResult({ key }, plaintext) {
|
|
85
97
|
return { keyId: key.keyId, plaintext, tenantId: key.tenantId, role: 'member', expiresAt: key.expiresAt };
|
|
@@ -146,10 +158,8 @@ function assertMemberKeyRevokesSelf(ctx, keyId) {
|
|
|
146
158
|
function keyOwnerOf(record) {
|
|
147
159
|
return record ? { tenantId: record.tenantId, revokedAt: record.revokedAt, role: record.role, ownerSubject: record.ownerSubject ?? null } : undefined;
|
|
148
160
|
}
|
|
149
|
-
/**
|
|
150
|
-
*
|
|
151
|
-
* so the local CLI can run revoke and grant in the key's own tenant.
|
|
152
|
-
*/
|
|
161
|
+
/** The tenant that owns `keyId`, or undefined for an unknown key. Host admin only: it reads across tenants,
|
|
162
|
+
* so the local CLI can run revoke and grant in the key's own tenant. */
|
|
153
163
|
export function authKeyTenant(ctx, keyId) {
|
|
154
164
|
if (!ctx.actor.hostAdmin) {
|
|
155
165
|
throw new ForbiddenError('Only the host admin can look up a key across tenants');
|
package/dist/api/auto-sleep.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// When a write starts a background sleep; the MCP remember tool and the session-close hook share it.
|
|
2
|
-
import { errorMessage, log } from '../util/log.js';
|
|
2
|
+
import { errorFields, errorMessage, log } from '../util/log.js';
|
|
3
3
|
import { countCreatedSinceLastSleep } from '../store/index-and-stats.js';
|
|
4
4
|
import { consolidate } from '../consolidate/sleep.js';
|
|
5
5
|
import { outsideRequestStores, runWithRequestStores, scopedBusyWait } from '../db/index.js';
|
|
@@ -25,7 +25,7 @@ export function startAutoSleepIfDue(hippoRoot, tenantId, config, allowed) {
|
|
|
25
25
|
const busyWaitMs = scopedBusyWait();
|
|
26
26
|
outsideRequestStores(() => runWithRequestStores(() => consolidate(hippoRoot), { busyWaitMs }))
|
|
27
27
|
.catch((err) => {
|
|
28
|
-
log.error(`auto-sleep consolidate failed (tenant ${tenantId}): ${errorMessage(err)}
|
|
28
|
+
log.error(`auto-sleep consolidate failed (tenant ${tenantId}): ${errorMessage(err)}`, errorFields(err));
|
|
29
29
|
})
|
|
30
30
|
.finally(() => autoSleepInFlight.delete(hippoRoot));
|
|
31
31
|
}
|
|
@@ -46,20 +46,7 @@ export declare const DEFAULT_RECENT_FRACTION_THRESHOLD = 0.7;
|
|
|
46
46
|
export declare const DEFAULT_MIN_RETURNED = 3;
|
|
47
47
|
export declare const DEFAULT_MIN_POOL = 10;
|
|
48
48
|
export declare const DEFAULT_MIN_OLDER_PASSED_OVER = 3;
|
|
49
|
-
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* Returns an AvailabilityHint when ALL of the following hold:
|
|
53
|
-
* 1. topK.length >= minReturned AND pool.length >= minPool (enough signal);
|
|
54
|
-
* 2. recentFraction > recentFractionThreshold (returned slice is recency-dominated);
|
|
55
|
-
* 3. poolMedianAgeDays > topKMedianAgeDays (the pool genuinely skews older,
|
|
56
|
-
* so recency is not just the corpus being young);
|
|
57
|
-
* 4. olderCandidatesPassedOver >= minOlderPassedOver (older matched memories
|
|
58
|
-
* actually existed and were not returned).
|
|
59
|
-
* Otherwise returns null.
|
|
60
|
-
*
|
|
61
|
-
* Entries with an unparseable `created` are dropped defensively so a malformed
|
|
62
|
-
* row cannot poison the medians with NaN.
|
|
63
|
-
*/
|
|
49
|
+
/** Returns an AvailabilityHint when the returned slice is recency-dominated, the pool skews older and older matches were passed over; else null.
|
|
50
|
+
* Entries with an unparseable `created` are dropped so a malformed row cannot poison the medians with NaN. */
|
|
64
51
|
export declare function detectAvailabilityBias(opts: DetectAvailabilityBiasOpts): AvailabilityHint | null;
|
|
65
52
|
//# sourceMappingURL=availability.d.ts.map
|
package/dist/api/availability.js
CHANGED
|
@@ -17,21 +17,8 @@ function parseTimestamps(refs) {
|
|
|
17
17
|
.map((e) => ({ id: e.id, ts: Date.parse(e.created) }))
|
|
18
18
|
.filter((e) => Number.isFinite(e.ts));
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* Returns an AvailabilityHint when ALL of the following hold:
|
|
24
|
-
* 1. topK.length >= minReturned AND pool.length >= minPool (enough signal);
|
|
25
|
-
* 2. recentFraction > recentFractionThreshold (returned slice is recency-dominated);
|
|
26
|
-
* 3. poolMedianAgeDays > topKMedianAgeDays (the pool genuinely skews older,
|
|
27
|
-
* so recency is not just the corpus being young);
|
|
28
|
-
* 4. olderCandidatesPassedOver >= minOlderPassedOver (older matched memories
|
|
29
|
-
* actually existed and were not returned).
|
|
30
|
-
* Otherwise returns null.
|
|
31
|
-
*
|
|
32
|
-
* Entries with an unparseable `created` are dropped defensively so a malformed
|
|
33
|
-
* row cannot poison the medians with NaN.
|
|
34
|
-
*/
|
|
20
|
+
/** Returns an AvailabilityHint when the returned slice is recency-dominated, the pool skews older and older matches were passed over; else null.
|
|
21
|
+
* Entries with an unparseable `created` are dropped so a malformed row cannot poison the medians with NaN. */
|
|
35
22
|
export function detectAvailabilityBias(opts) {
|
|
36
23
|
const now = opts.now ?? Date.now();
|
|
37
24
|
const recencyWindowMs = opts.recencyWindowMs ?? DEFAULT_RECENCY_WINDOW_MS;
|
|
@@ -4,7 +4,7 @@ import { heldIdLookup } from '../store/entry-reads.js';
|
|
|
4
4
|
import { calculateStrength } from '../core/memory.js';
|
|
5
5
|
import { auditQueryFields, recordAuditEvent } from '../store/audit.js';
|
|
6
6
|
import { isWorthSurfacing } from '../core/memory-quality.js';
|
|
7
|
-
import { rankBothStores } from '../sharing/
|
|
7
|
+
import { rankBothStores } from '../sharing/search-both.js';
|
|
8
8
|
import { evalNow } from '../core/ablation.js';
|
|
9
9
|
import { hybridSearch } from '../search/hybrid.js';
|
|
10
10
|
import { physicsSearch } from '../search/physics-search.js';
|
|
@@ -51,9 +51,8 @@ export function selectPinned(opts, plan, left, pools, admission) {
|
|
|
51
51
|
const [localPool, globalPool] = oneCopyPerMemory(localEntries, globalEntries, nowP);
|
|
52
52
|
obs?.dropMissing([...localEntries, ...globalEntries], [...localPool, ...globalPool], 'load', 'duplicate');
|
|
53
53
|
const picked = { items: [], ids: new Set(), used: 0 };
|
|
54
|
-
// Pinned entries are explicit
|
|
55
|
-
//
|
|
56
|
-
// pins are ranked here and reserve their share before it can spend.
|
|
54
|
+
// Pinned entries are explicit intent, the recent-N list an automatic backfill; both share ONE budget and the recent loop runs first,
|
|
55
|
+
// so pins are ranked here and reserve their share before it can spend.
|
|
57
56
|
const pinnedLocal = localPool.filter((e) => e.pinned);
|
|
58
57
|
const pinnedGlobal = globalPool.filter((e) => e.pinned);
|
|
59
58
|
const rankedPinned = rankPinned(plan, pinnedLocal, pinnedGlobal, nowP);
|