hippo-memory 1.60.0 → 1.61.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/ablation.js +9 -27
- package/dist/agent-memories/apply.js +4 -1
- package/dist/agent-memories/claude-code.js +1 -1
- package/dist/agent-memories/codex.js +1 -1
- package/dist/agent-memories/gemini.js +1 -1
- package/dist/agent-memories/legacy.js +1 -1
- package/dist/agent-memories/source.js +1 -1
- package/dist/agent-memories/sync.js +8 -3
- package/dist/ambient-store.d.ts +14 -0
- package/dist/ambient-store.js +90 -0
- package/dist/ambient.d.ts +23 -0
- package/dist/ambient.js +72 -50
- package/dist/api/assemble.d.ts +93 -0
- package/dist/api/assemble.js +152 -0
- package/dist/api/audit.d.ts +17 -0
- package/dist/api/audit.js +23 -0
- package/dist/api/auth.d.ts +79 -0
- package/dist/api/auth.js +178 -0
- package/dist/api/context-types.d.ts +105 -0
- package/dist/api/context-types.js +3 -0
- package/dist/api/context.d.ts +31 -0
- package/dist/api/context.js +705 -0
- package/dist/api/dormant.d.ts +30 -0
- package/dist/api/dormant.js +140 -0
- package/dist/api/drill-down.d.ts +84 -0
- package/dist/api/drill-down.js +123 -0
- package/dist/api/forget.d.ts +57 -0
- package/dist/api/forget.js +87 -0
- package/dist/api/goals.d.ts +18 -0
- package/dist/api/goals.js +33 -0
- package/dist/api/learn.d.ts +31 -0
- package/dist/api/learn.js +88 -0
- package/dist/api/outcome.d.ts +61 -0
- package/dist/api/outcome.js +66 -0
- package/dist/api/promote.d.ts +54 -0
- package/dist/api/promote.js +203 -0
- package/dist/api/quarantine.d.ts +24 -0
- package/dist/api/quarantine.js +121 -0
- package/dist/api/recall-types.d.ts +390 -0
- package/dist/api/recall-types.js +3 -0
- package/dist/api/recall.d.ts +36 -0
- package/dist/api/recall.js +634 -0
- package/dist/api/remember.d.ts +35 -0
- package/dist/api/remember.js +43 -0
- package/dist/api/sleep.d.ts +136 -0
- package/dist/api/sleep.js +271 -0
- package/dist/api/tokens.d.ts +26 -0
- package/dist/api/tokens.js +60 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/api/types.js +38 -0
- package/dist/api.d.ts +20 -1262
- package/dist/api.js +25 -2727
- package/dist/audit.d.ts +3 -0
- package/dist/audit.js +6 -3
- package/dist/auth.d.ts +45 -4
- package/dist/auth.js +125 -48
- package/dist/autolearn.js +2 -2
- package/dist/capture/command.d.ts +33 -0
- package/dist/capture/command.js +264 -0
- package/dist/capture/compact.d.ts +44 -0
- package/dist/capture/compact.js +354 -0
- package/dist/capture/extract.d.ts +21 -0
- package/dist/capture/extract.js +464 -0
- package/dist/capture/transcript.d.ts +40 -0
- package/dist/capture/transcript.js +193 -0
- package/dist/capture-error.js +2 -1
- package/dist/churn-git.js +4 -2
- package/dist/cli/audit.d.ts +3 -0
- package/dist/cli/audit.js +159 -0
- package/dist/cli/auth.d.ts +2 -0
- package/dist/cli/auth.js +171 -0
- package/dist/cli/briefs.d.ts +4 -0
- package/dist/cli/briefs.js +435 -0
- package/dist/cli/card.d.ts +3 -0
- package/dist/cli/card.js +333 -0
- package/dist/cli/context.d.ts +15 -0
- package/dist/cli/context.js +366 -0
- package/dist/cli/continuity.d.ts +6 -0
- package/dist/cli/continuity.js +445 -0
- package/dist/cli/curate.d.ts +19 -0
- package/dist/cli/curate.js +555 -0
- package/dist/cli/dag.d.ts +5 -0
- package/dist/cli/dag.js +177 -0
- package/dist/cli/decisions.d.ts +4 -0
- package/dist/cli/decisions.js +528 -0
- package/dist/cli/eval.d.ts +5 -0
- package/dist/cli/eval.js +213 -0
- package/dist/cli/explain.d.ts +4 -0
- package/dist/cli/explain.js +150 -0
- package/dist/cli/goals.d.ts +2 -0
- package/dist/cli/goals.js +196 -0
- package/dist/cli/hook-blocks.d.ts +18 -0
- package/dist/cli/hook-blocks.js +233 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +305 -0
- package/dist/cli/maintenance.d.ts +4 -0
- package/dist/cli/maintenance.js +179 -0
- package/dist/cli/playbooks.d.ts +4 -0
- package/dist/cli/playbooks.js +556 -0
- package/dist/cli/projects.js +1 -1
- package/dist/cli/recall.d.ts +7 -0
- package/dist/cli/recall.js +597 -0
- package/dist/cli/remember.d.ts +5 -0
- package/dist/cli/remember.js +442 -0
- package/dist/cli/serve.d.ts +5 -0
- package/dist/cli/serve.js +40 -0
- package/dist/cli/session-hooks.d.ts +29 -0
- package/dist/cli/session-hooks.js +637 -0
- package/dist/cli/setup.d.ts +4 -0
- package/dist/cli/setup.js +376 -0
- package/dist/cli/shared.d.ts +15 -19
- package/dist/cli/shared.js +50 -341
- package/dist/cli/slack.d.ts +2 -0
- package/dist/cli/slack.js +171 -0
- package/dist/cli/status.d.ts +18 -0
- package/dist/cli/status.js +400 -0
- package/dist/cli/transfer.d.ts +10 -0
- package/dist/cli/transfer.js +438 -0
- package/dist/cli/usage.d.ts +85 -0
- package/dist/cli/usage.js +741 -0
- package/dist/cli.d.ts +71 -120
- package/dist/cli.js +170 -8469
- package/dist/client.js +15 -8
- package/dist/compaction-record.js +6 -4
- package/dist/connectors/github/backfill.js +94 -87
- package/dist/connectors/github/cli-impl.js +4 -3
- package/dist/connectors/github/dlq.js +67 -54
- package/dist/connectors/github/ingest.js +34 -35
- package/dist/connectors/github/tenant-routing.js +3 -2
- package/dist/connectors/github/webhook.js +135 -216
- package/dist/connectors/slack/dlq.js +49 -61
- package/dist/connectors/slack/ingest.js +55 -48
- package/dist/connectors/slack/tenant-routing.js +4 -3
- package/dist/connectors/slack/webhook.js +72 -74
- package/dist/consolidate/conflicts.d.ts +10 -0
- package/dist/consolidate/conflicts.js +178 -0
- package/dist/consolidate/decay.d.ts +12 -0
- package/dist/consolidate/decay.js +145 -0
- package/dist/consolidate/llm-passes.d.ts +3 -0
- package/dist/consolidate/llm-passes.js +141 -0
- package/dist/consolidate/merge.d.ts +7 -0
- package/dist/consolidate/merge.js +251 -0
- package/dist/consolidate/physics-pass.d.ts +3 -0
- package/dist/consolidate/physics-pass.js +60 -0
- package/dist/consolidate/run.d.ts +69 -0
- package/dist/consolidate/run.js +76 -0
- package/dist/consolidate/sleep.d.ts +18 -0
- package/dist/consolidate/sleep.js +209 -0
- package/dist/consolidate/traces.d.ts +4 -0
- package/dist/consolidate/traces.js +178 -0
- package/dist/context-auto.js +7 -11
- package/dist/context-render.d.ts +1 -1
- package/dist/context-render.js +1 -1
- package/dist/customer-notes.d.ts +3 -0
- package/dist/customer-notes.js +6 -4
- package/dist/dag.js +6 -5
- package/dist/dashboard-actions.d.ts +20 -0
- package/dist/dashboard-actions.js +88 -0
- package/dist/dashboard-params.d.ts +45 -0
- package/dist/dashboard-params.js +127 -0
- package/dist/dashboard-queries.d.ts +15 -0
- package/dist/dashboard-queries.js +355 -0
- package/dist/dashboard-snapshot.d.ts +138 -0
- package/dist/dashboard-snapshot.js +308 -0
- package/dist/dashboard-types.d.ts +163 -0
- package/dist/dashboard-types.js +3 -0
- package/dist/dashboard.d.ts +6 -7
- package/dist/dashboard.js +228 -202
- package/dist/db/busy.d.ts +5 -0
- package/dist/db/busy.js +24 -0
- package/dist/db/continuity.d.ts +5 -0
- package/dist/db/continuity.js +145 -0
- package/dist/db/meta.d.ts +8 -0
- package/dist/db/meta.js +35 -0
- package/dist/db/migrate.d.ts +9 -0
- package/dist/db/migrate.js +138 -0
- package/dist/db/migrations/index.d.ts +5 -0
- package/dist/db/migrations/index.js +109 -0
- package/dist/db/migrations/types.d.ts +14 -0
- package/dist/db/migrations/types.js +2 -0
- package/dist/db/migrations/v01.d.ts +3 -0
- package/dist/db/migrations/v01.js +38 -0
- package/dist/db/migrations/v02.d.ts +3 -0
- package/dist/db/migrations/v02.js +21 -0
- package/dist/db/migrations/v03.d.ts +3 -0
- package/dist/db/migrations/v03.js +22 -0
- package/dist/db/migrations/v04.d.ts +3 -0
- package/dist/db/migrations/v04.js +28 -0
- package/dist/db/migrations/v05.d.ts +3 -0
- package/dist/db/migrations/v05.js +21 -0
- package/dist/db/migrations/v06.d.ts +3 -0
- package/dist/db/migrations/v06.js +25 -0
- package/dist/db/migrations/v07.d.ts +3 -0
- package/dist/db/migrations/v07.js +13 -0
- package/dist/db/migrations/v08.d.ts +3 -0
- package/dist/db/migrations/v08.js +8 -0
- package/dist/db/migrations/v09.d.ts +3 -0
- package/dist/db/migrations/v09.js +13 -0
- package/dist/db/migrations/v10.d.ts +3 -0
- package/dist/db/migrations/v10.js +17 -0
- package/dist/db/migrations/v11.d.ts +3 -0
- package/dist/db/migrations/v11.js +15 -0
- package/dist/db/migrations/v12.d.ts +3 -0
- package/dist/db/migrations/v12.js +11 -0
- package/dist/db/migrations/v13.d.ts +3 -0
- package/dist/db/migrations/v13.js +15 -0
- package/dist/db/migrations/v14.d.ts +3 -0
- package/dist/db/migrations/v14.js +66 -0
- package/dist/db/migrations/v15.d.ts +3 -0
- package/dist/db/migrations/v15.js +42 -0
- package/dist/db/migrations/v16.d.ts +3 -0
- package/dist/db/migrations/v16.js +61 -0
- package/dist/db/migrations/v17.d.ts +3 -0
- package/dist/db/migrations/v17.js +46 -0
- package/dist/db/migrations/v18.d.ts +3 -0
- package/dist/db/migrations/v18.js +60 -0
- package/dist/db/migrations/v19.d.ts +3 -0
- package/dist/db/migrations/v19.js +28 -0
- package/dist/db/migrations/v20.d.ts +3 -0
- package/dist/db/migrations/v20.js +42 -0
- package/dist/db/migrations/v21.d.ts +3 -0
- package/dist/db/migrations/v21.js +16 -0
- package/dist/db/migrations/v22.d.ts +3 -0
- package/dist/db/migrations/v22.js +82 -0
- package/dist/db/migrations/v23.d.ts +3 -0
- package/dist/db/migrations/v23.js +48 -0
- package/dist/db/migrations/v24.d.ts +3 -0
- package/dist/db/migrations/v24.js +72 -0
- package/dist/db/migrations/v25.d.ts +3 -0
- package/dist/db/migrations/v25.js +46 -0
- package/dist/db/migrations/v26.d.ts +3 -0
- package/dist/db/migrations/v26.js +23 -0
- package/dist/db/migrations/v27.d.ts +3 -0
- package/dist/db/migrations/v27.js +57 -0
- package/dist/db/migrations/v28.d.ts +3 -0
- package/dist/db/migrations/v28.js +38 -0
- package/dist/db/migrations/v29.d.ts +3 -0
- package/dist/db/migrations/v29.js +78 -0
- package/dist/db/migrations/v30.d.ts +3 -0
- package/dist/db/migrations/v30.js +92 -0
- package/dist/db/migrations/v31.d.ts +3 -0
- package/dist/db/migrations/v31.js +74 -0
- package/dist/db/migrations/v32.d.ts +3 -0
- package/dist/db/migrations/v32.js +102 -0
- package/dist/db/migrations/v33.d.ts +3 -0
- package/dist/db/migrations/v33.js +104 -0
- package/dist/db/migrations/v34.d.ts +3 -0
- package/dist/db/migrations/v34.js +93 -0
- package/dist/db/migrations/v35.d.ts +3 -0
- package/dist/db/migrations/v35.js +98 -0
- package/dist/db/migrations/v36.d.ts +3 -0
- package/dist/db/migrations/v36.js +98 -0
- package/dist/db/migrations/v37.d.ts +3 -0
- package/dist/db/migrations/v37.js +219 -0
- package/dist/db/migrations/v38.d.ts +3 -0
- package/dist/db/migrations/v38.js +277 -0
- package/dist/db/migrations/v39.d.ts +3 -0
- package/dist/db/migrations/v39.js +59 -0
- package/dist/db/migrations/v40.d.ts +3 -0
- package/dist/db/migrations/v40.js +74 -0
- package/dist/db/migrations/v41.d.ts +3 -0
- package/dist/db/migrations/v41.js +43 -0
- package/dist/db/migrations/v42.d.ts +3 -0
- package/dist/db/migrations/v42.js +41 -0
- package/dist/db/migrations/v43.d.ts +3 -0
- package/dist/db/migrations/v43.js +67 -0
- package/dist/db/migrations/v44.d.ts +3 -0
- package/dist/db/migrations/v44.js +28 -0
- package/dist/db/migrations/v45.d.ts +3 -0
- package/dist/db/migrations/v45.js +30 -0
- package/dist/db/migrations/v46.d.ts +3 -0
- package/dist/db/migrations/v46.js +25 -0
- package/dist/db/migrations/v47.d.ts +3 -0
- package/dist/db/migrations/v47.js +17 -0
- package/dist/db/migrations/v48.d.ts +3 -0
- package/dist/db/migrations/v48.js +10 -0
- package/dist/db/migrations/v49.d.ts +3 -0
- package/dist/db/migrations/v49.js +31 -0
- package/dist/db/migrations/v50.d.ts +3 -0
- package/dist/db/migrations/v50.js +67 -0
- package/dist/db/migrations/v51.d.ts +3 -0
- package/dist/db/migrations/v51.js +14 -0
- package/dist/db/migrations/v52.d.ts +3 -0
- package/dist/db/migrations/v52.js +7 -0
- package/dist/db/open.d.ts +23 -0
- package/dist/db/open.js +146 -0
- package/dist/db/sqlite.d.ts +21 -0
- package/dist/db/sqlite.js +8 -0
- package/dist/db/tables.d.ts +7 -0
- package/dist/db/tables.js +38 -0
- package/dist/db.d.ts +6 -46
- package/dist/db.js +5 -3049
- package/dist/decisions.d.ts +4 -1
- package/dist/decisions.js +9 -7
- package/dist/dedupe.js +3 -2
- package/dist/delivery-recorder.js +4 -1
- package/dist/doctor.js +3 -3
- package/dist/embedding-provider.d.ts +1 -1
- package/dist/embedding-provider.js +4 -3
- package/dist/embeddings.d.ts +9 -52
- package/dist/embeddings.js +43 -297
- package/dist/env.d.ts +75 -0
- package/dist/env.js +119 -0
- package/dist/eval-suite.js +1 -1
- package/dist/eval.js +2 -2
- package/dist/extract.js +1 -1
- package/dist/gated-write.js +3 -1
- package/dist/goals.d.ts +3 -1
- package/dist/goals.js +18 -0
- package/dist/graph/read.d.ts +73 -0
- package/dist/graph/read.js +325 -0
- package/dist/graph/rows.d.ts +45 -0
- package/dist/graph/rows.js +51 -0
- package/dist/graph/types.d.ts +83 -0
- package/dist/graph/types.js +11 -0
- package/dist/graph/write.d.ts +93 -0
- package/dist/{graph.js → graph/write.js} +6 -384
- package/dist/graph-extract.js +2 -1
- package/dist/graph-recall.d.ts +1 -1
- package/dist/graph-recall.js +2 -2
- package/dist/graph-stream.js +1 -1
- package/dist/graph-view.d.ts +1 -1
- package/dist/graph-view.js +1 -1
- package/dist/half-life-migration.d.ts +1 -1
- package/dist/half-life-migration.js +2 -1
- package/dist/hooks/codex-session.d.ts +8 -0
- package/dist/hooks/codex-session.js +76 -0
- package/dist/hooks/codex-wrapper.d.ts +55 -0
- package/dist/hooks/codex-wrapper.js +288 -0
- package/dist/hooks/json-hooks.d.ts +63 -0
- package/dist/hooks/json-hooks.js +356 -0
- package/dist/hooks/opencode.d.ts +50 -0
- package/dist/hooks/opencode.js +202 -0
- package/dist/hooks/shared.d.ts +54 -0
- package/dist/hooks/shared.js +77 -0
- package/dist/http-retry.d.ts +2 -0
- package/dist/http-retry.js +4 -3
- package/dist/http-util.d.ts +3 -0
- package/dist/http-util.js +10 -0
- package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
- package/dist/importers/core.js +141 -0
- package/dist/importers/markdown-parse.d.ts +41 -0
- package/dist/importers/markdown-parse.js +132 -0
- package/dist/importers/markdown.d.ts +3 -0
- package/dist/importers/markdown.js +92 -0
- package/dist/importers/sources.d.ts +7 -0
- package/dist/importers/sources.js +229 -0
- package/dist/importers/vault.d.ts +11 -0
- package/dist/importers/vault.js +352 -0
- package/dist/incidents.d.ts +3 -0
- package/dist/incidents.js +7 -5
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -6
- package/dist/invalidation.js +2 -1
- package/dist/judgment.js +2 -1
- package/dist/keyset.d.ts +13 -0
- package/dist/keyset.js +8 -0
- package/dist/local-embedding.d.ts +13 -0
- package/dist/local-embedding.js +165 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +19 -1
- package/dist/mcp/admin-tools.d.ts +8 -0
- package/dist/mcp/admin-tools.js +116 -0
- package/dist/mcp/format.d.ts +27 -0
- package/dist/mcp/format.js +135 -0
- package/dist/mcp/memory-tools.d.ts +5 -0
- package/dist/mcp/memory-tools.js +83 -0
- package/dist/mcp/protocol.d.ts +83 -0
- package/dist/mcp/protocol.js +55 -0
- package/dist/mcp/recall-tools.d.ts +6 -0
- package/dist/mcp/recall-tools.js +320 -0
- package/dist/mcp/request.d.ts +10 -0
- package/dist/mcp/request.js +163 -0
- package/dist/mcp/server.d.ts +4 -75
- package/dist/mcp/server.js +7 -1190
- package/dist/mcp/session-state.d.ts +11 -0
- package/dist/mcp/session-state.js +28 -0
- package/dist/mcp/stdio.d.ts +8 -0
- package/dist/mcp/stdio.js +79 -0
- package/dist/mcp/tools.d.ts +11 -0
- package/dist/mcp/tools.js +247 -0
- package/dist/memory.d.ts +3 -0
- package/dist/memory.js +27 -1
- package/dist/multihop.d.ts +1 -1
- package/dist/multihop.js +2 -1
- package/dist/owner-validation.js +2 -1
- package/dist/physics-state.js +10 -7
- package/dist/policies.d.ts +3 -0
- package/dist/policies.js +8 -6
- package/dist/postinstall.js +3 -2
- package/dist/predictions/planning-fallacy.d.ts +100 -0
- package/dist/predictions/planning-fallacy.js +190 -0
- package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
- package/dist/predictions/store.js +434 -0
- package/dist/processes.d.ts +3 -0
- package/dist/processes.js +7 -5
- package/dist/project-briefs.d.ts +3 -0
- package/dist/project-briefs.js +7 -5
- package/dist/project-identity.js +3 -2
- package/dist/project-merge.js +3 -1
- package/dist/quarantine.d.ts +2 -1
- package/dist/quarantine.js +8 -5
- package/dist/raw-archive.js +1 -1
- package/dist/recall-history.js +3 -2
- package/dist/recall-pipeline.d.ts +2 -2
- package/dist/recall-pipeline.js +16 -8
- package/dist/recall-scope.js +1 -1
- package/dist/recall-trace.d.ts +1 -1
- package/dist/refine-llm.js +2 -1
- package/dist/reject-flow.js +6 -1
- package/dist/rerankers/clef.js +6 -5
- package/dist/rerankers/jev.d.ts +1 -1
- package/dist/rerankers/jev.js +4 -4
- package/dist/rerankers/llm.d.ts +4 -2
- package/dist/rerankers/llm.js +58 -38
- package/dist/rerankers/types.d.ts +1 -1
- package/dist/salience.js +1 -1
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.js +26 -4
- package/dist/scope.js +4 -3
- package/dist/search/as-of.d.ts +10 -0
- package/dist/search/as-of.js +22 -0
- package/dist/search/bm25-search.d.ts +14 -0
- package/dist/search/bm25-search.js +43 -0
- package/dist/search/bm25.d.ts +15 -0
- package/dist/search/bm25.js +54 -0
- package/dist/search/boosts.d.ts +54 -0
- package/dist/search/boosts.js +94 -0
- package/dist/search/breakdown.d.ts +7 -0
- package/dist/search/breakdown.js +20 -0
- package/dist/search/explain.d.ts +25 -0
- package/dist/search/explain.js +31 -0
- package/dist/search/finalize.d.ts +8 -0
- package/dist/search/finalize.js +52 -0
- package/dist/search/fusion.d.ts +27 -0
- package/dist/search/fusion.js +42 -0
- package/dist/search/hybrid-score.d.ts +20 -0
- package/dist/search/hybrid-score.js +73 -0
- package/dist/search/hybrid.d.ts +46 -0
- package/dist/search/hybrid.js +64 -0
- package/dist/search/physics-search.d.ts +29 -0
- package/dist/search/physics-search.js +162 -0
- package/dist/search/rerank.d.ts +10 -0
- package/dist/search/rerank.js +72 -0
- package/dist/search/temporal.d.ts +15 -0
- package/dist/search/temporal.js +45 -0
- package/dist/search/types.d.ts +91 -0
- package/dist/search/types.js +2 -0
- package/dist/search/vector.d.ts +30 -0
- package/dist/search/vector.js +71 -0
- package/dist/secret-detect.d.ts +2 -0
- package/dist/secret-detect.js +2 -1
- package/dist/server/auth.d.ts +52 -0
- package/dist/server/auth.js +221 -0
- package/dist/server/client-ip.d.ts +25 -0
- package/dist/server/client-ip.js +92 -0
- package/dist/server/cursor.d.ts +23 -0
- package/dist/server/cursor.js +58 -0
- package/dist/server/lifecycle.d.ts +7 -0
- package/dist/server/lifecycle.js +29 -0
- package/dist/server/mcp-http.d.ts +5 -0
- package/dist/server/mcp-http.js +199 -0
- package/dist/server/request.d.ts +33 -0
- package/dist/server/request.js +103 -0
- package/dist/server/routes/admin.d.ts +9 -0
- package/dist/server/routes/admin.js +158 -0
- package/dist/server/routes/customer-notes.d.ts +7 -0
- package/dist/server/routes/customer-notes.js +112 -0
- package/dist/server/routes/decisions.d.ts +7 -0
- package/dist/server/routes/decisions.js +133 -0
- package/dist/server/routes/incidents.d.ts +7 -0
- package/dist/server/routes/incidents.js +126 -0
- package/dist/server/routes/memories.d.ts +10 -0
- package/dist/server/routes/memories.js +179 -0
- package/dist/server/routes/policies.d.ts +8 -0
- package/dist/server/routes/policies.js +151 -0
- package/dist/server/routes/predictions.d.ts +7 -0
- package/dist/server/routes/predictions.js +164 -0
- package/dist/server/routes/processes.d.ts +7 -0
- package/dist/server/routes/processes.js +161 -0
- package/dist/server/routes/project-briefs.d.ts +8 -0
- package/dist/server/routes/project-briefs.js +136 -0
- package/dist/server/routes/recall.d.ts +8 -0
- package/dist/server/routes/recall.js +340 -0
- package/dist/server/routes/skills.d.ts +8 -0
- package/dist/server/routes/skills.js +150 -0
- package/dist/server/types.d.ts +56 -0
- package/dist/server/types.js +2 -0
- package/dist/server/validation.d.ts +14 -0
- package/dist/server/validation.js +91 -0
- package/dist/server.d.ts +7 -61
- package/dist/server.js +69 -2362
- package/dist/session-digest.d.ts +1 -1
- package/dist/session-digest.js +9 -2
- package/dist/shared.d.ts +3 -1
- package/dist/shared.js +26 -22
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +7 -5
- package/dist/stdin.js +2 -2
- package/dist/store/audit-event.d.ts +19 -0
- package/dist/store/audit-event.js +33 -0
- package/dist/store/candidates.d.ts +42 -0
- package/dist/store/candidates.js +152 -0
- package/dist/store/conflicts.d.ts +44 -0
- package/dist/store/conflicts.js +444 -0
- package/dist/store/delete-and-batch.d.ts +63 -0
- package/dist/store/delete-and-batch.js +310 -0
- package/dist/store/entry-reads.d.ts +92 -0
- package/dist/store/entry-reads.js +255 -0
- package/dist/store/entry-row.d.ts +67 -0
- package/dist/store/entry-row.js +208 -0
- package/dist/store/entry-writes.d.ts +46 -0
- package/dist/store/entry-writes.js +148 -0
- package/dist/store/handoffs.d.ts +26 -0
- package/dist/store/handoffs.js +184 -0
- package/dist/store/index-and-stats.d.ts +52 -0
- package/dist/store/index-and-stats.js +214 -0
- package/dist/store/markdown.d.ts +10 -0
- package/dist/store/markdown.js +108 -0
- package/dist/store/mirrors.d.ts +49 -0
- package/dist/store/mirrors.js +312 -0
- package/dist/store/open.d.ts +15 -0
- package/dist/store/open.js +223 -0
- package/dist/store/rows.d.ts +178 -0
- package/dist/store/rows.js +158 -0
- package/dist/store/search-rows.d.ts +86 -0
- package/dist/store/search-rows.js +254 -0
- package/dist/store/sessions.d.ts +83 -0
- package/dist/store/sessions.js +272 -0
- package/dist/store/summaries.d.ts +94 -0
- package/dist/store/summaries.js +377 -0
- package/dist/store/tenant-lookup.d.ts +12 -0
- package/dist/store/tenant-lookup.js +16 -0
- package/dist/store-cards.js +2 -1
- package/dist/summary-dirty.d.ts +4 -0
- package/dist/summary-dirty.js +32 -0
- package/dist/support-bundle.js +4 -3
- package/dist/tenant.js +2 -2
- package/dist/tokenize.d.ts +2 -0
- package/dist/tokenize.js +16 -0
- package/dist/transcript-tail.d.ts +7 -0
- package/dist/transcript-tail.js +48 -0
- package/dist/vector-store.d.ts +27 -0
- package/dist/vector-store.js +210 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/working-memory.js +1 -1
- package/dist/yaml.js +36 -11
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist-ui/assets/index-DPN7cP19.js +33 -0
- package/dist-ui/assets/index-dFloKRVr.css +1 -0
- package/dist-ui/index.html +3 -25
- 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/capture.d.ts +0 -155
- package/dist/capture.js +0 -1295
- package/dist/consolidate.d.ts +0 -58
- package/dist/consolidate.js +0 -1124
- package/dist/graph.d.ts +0 -245
- package/dist/hooks.d.ts +0 -208
- package/dist/hooks.js +0 -1076
- package/dist/importers.js +0 -900
- package/dist/predictions.js +0 -620
- package/dist/search.d.ts +0 -320
- package/dist/search.js +0 -970
- package/dist/store.d.ts +0 -776
- package/dist/store.js +0 -3473
- package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
- package/dist-ui/assets/index-BhT8RvO6.js +0 -61
- package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
- package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// Session context assembly under a token budget.
|
|
2
|
+
import { loadEntriesByIds, loadSessionRawMemories, countSessionRawMemories } from '../store/entry-reads.js';
|
|
3
|
+
import { estimateTokens } from '../token-ledger.js';
|
|
4
|
+
import { passesScopeFilterForRecall, assertScopeRequestAllowed } from '../recall-scope.js';
|
|
5
|
+
/**
|
|
6
|
+
* Build a chronologically-ordered context window for a session. Adapts the
|
|
7
|
+
* lossless-claw context-engine pattern to Hippo's score-ranked memory store.
|
|
8
|
+
*
|
|
9
|
+
* Algorithm:
|
|
10
|
+
* 1. Load all kind='raw' rows for the session, tenant + scope filtered.
|
|
11
|
+
* 2. Split: newest `freshTailCount` are protected (fresh tail).
|
|
12
|
+
* 3. For older rows, when ≥2 share a level-2 parent, substitute the
|
|
13
|
+
* summary; everything else passes through as raw.
|
|
14
|
+
* 4. Hippo-additive eviction: when over-budget, drop the lowest-strength
|
|
15
|
+
* non-fresh-tail item first. Fresh-tail rows are never evicted.
|
|
16
|
+
*
|
|
17
|
+
* Strength-weighted eviction is the differentiator from lossless-claw,
|
|
18
|
+
* which evicts oldest-first. A high-strength older row (high retrieval
|
|
19
|
+
* count, slow decay) survives; a low-strength recent row (newer but
|
|
20
|
+
* unimportant) goes first.
|
|
21
|
+
*
|
|
22
|
+
* Returns `items: []` cleanly when:
|
|
23
|
+
* - sessionId is empty
|
|
24
|
+
* - no raws exist for the session
|
|
25
|
+
* - all rows fail the scope/tenant filter
|
|
26
|
+
*/
|
|
27
|
+
export function assemble(ctx, sessionId, opts = {}) {
|
|
28
|
+
assertScopeRequestAllowed(ctx.actor, opts.scope);
|
|
29
|
+
const budget = opts.budget ?? 4000;
|
|
30
|
+
const freshTailCount = opts.freshTailCount ?? 10;
|
|
31
|
+
const summarizeOlder = opts.summarizeOlder ?? true;
|
|
32
|
+
const rowCap = opts.rowCap ?? 5000;
|
|
33
|
+
if (!sessionId) {
|
|
34
|
+
return { sessionId, items: [], tokens: 0, totalRaw: 0, summarized: 0, evicted: 0, truncated: false };
|
|
35
|
+
}
|
|
36
|
+
const rows = loadSessionRawMemories(ctx.hippoRoot, sessionId, ctx.tenantId, rowCap);
|
|
37
|
+
const truncated = rows.length === rowCap;
|
|
38
|
+
// v1.6.3 senior-review P0-1: report the FULL post-filter row count even
|
|
39
|
+
// when the cap windows the loaded set. Pre-v1.6.3 used `scoped.length`
|
|
40
|
+
// which under-reported on long sessions and made consumers render
|
|
41
|
+
// wrong "session has N msgs" UX.
|
|
42
|
+
const scoped = rows.filter((r) => passesScopeFilterForRecall(r.scope ?? null, opts.scope));
|
|
43
|
+
let totalRaw;
|
|
44
|
+
if (truncated) {
|
|
45
|
+
// v1.6.3 codex P1 / senior P0: scope-aware unbounded COUNT. The helper
|
|
46
|
+
// SQL-encodes the same default-deny rule passesScopeFilterForRecall
|
|
47
|
+
// applies in TS, so a no-scope caller cannot infer private rows by
|
|
48
|
+
// comparing totalRaw to items.length on a truncated session.
|
|
49
|
+
totalRaw = countSessionRawMemories(ctx.hippoRoot, sessionId, ctx.tenantId, opts.scope);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
totalRaw = scoped.length;
|
|
53
|
+
}
|
|
54
|
+
if (scoped.length === 0) {
|
|
55
|
+
return { sessionId, items: [], tokens: 0, totalRaw, summarized: 0, evicted: 0, truncated };
|
|
56
|
+
}
|
|
57
|
+
// Split newest N into fresh tail; rest is older.
|
|
58
|
+
const tailStartIdx = Math.max(0, scoped.length - freshTailCount);
|
|
59
|
+
const olderRows = scoped.slice(0, tailStartIdx);
|
|
60
|
+
const tailRows = scoped.slice(tailStartIdx);
|
|
61
|
+
// Substitute parent summaries for older rows that share one.
|
|
62
|
+
const olderItems = [];
|
|
63
|
+
let summarized = 0;
|
|
64
|
+
if (summarizeOlder && olderRows.length > 0) {
|
|
65
|
+
const olderByParent = new Map();
|
|
66
|
+
for (const r of olderRows) {
|
|
67
|
+
if (!r.dag_parent_id)
|
|
68
|
+
continue;
|
|
69
|
+
const list = olderByParent.get(r.dag_parent_id) ?? [];
|
|
70
|
+
list.push(r);
|
|
71
|
+
olderByParent.set(r.dag_parent_id, list);
|
|
72
|
+
}
|
|
73
|
+
const eligibleParentIds = Array.from(olderByParent.keys()).filter((pid) => (olderByParent.get(pid)?.length ?? 0) >= 2);
|
|
74
|
+
const parents = eligibleParentIds.length > 0
|
|
75
|
+
? loadEntriesByIds(ctx.hippoRoot, eligibleParentIds, ctx.tenantId)
|
|
76
|
+
.filter((p) => (p.dag_level ?? 0) === 2 && !p.superseded_by)
|
|
77
|
+
.filter((p) => passesScopeFilterForRecall(p.scope ?? null, opts.scope))
|
|
78
|
+
: [];
|
|
79
|
+
const claimedRawIds = new Set();
|
|
80
|
+
for (const parent of parents) {
|
|
81
|
+
const claimed = (olderByParent.get(parent.id) ?? []).map((r) => r.id);
|
|
82
|
+
claimed.forEach((id) => claimedRawIds.add(id));
|
|
83
|
+
olderItems.push({
|
|
84
|
+
id: parent.id,
|
|
85
|
+
content: parent.content,
|
|
86
|
+
createdAt: parent.earliest_at ?? parent.created,
|
|
87
|
+
isSummary: true,
|
|
88
|
+
substitutedFor: claimed,
|
|
89
|
+
strength: parent.strength,
|
|
90
|
+
});
|
|
91
|
+
summarized += claimed.length;
|
|
92
|
+
}
|
|
93
|
+
for (const r of olderRows) {
|
|
94
|
+
if (claimedRawIds.has(r.id))
|
|
95
|
+
continue;
|
|
96
|
+
olderItems.push({
|
|
97
|
+
id: r.id,
|
|
98
|
+
content: r.content,
|
|
99
|
+
createdAt: r.created,
|
|
100
|
+
strength: r.strength,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
for (const r of olderRows) {
|
|
106
|
+
olderItems.push({
|
|
107
|
+
id: r.id,
|
|
108
|
+
content: r.content,
|
|
109
|
+
createdAt: r.created,
|
|
110
|
+
strength: r.strength,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const tailItems = tailRows.map((r) => ({
|
|
115
|
+
id: r.id,
|
|
116
|
+
content: r.content,
|
|
117
|
+
createdAt: r.created,
|
|
118
|
+
isFreshTail: true,
|
|
119
|
+
strength: r.strength,
|
|
120
|
+
}));
|
|
121
|
+
// F4 (v1.6.5): byte compare canonical UTC ISO timestamps. ~50× faster than
|
|
122
|
+
// localeCompare and chronological by virtue of the timestamp invariant
|
|
123
|
+
// documented in src/memory.ts above MemoryEntry.
|
|
124
|
+
const cmpIso = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
125
|
+
olderItems.sort((a, b) => cmpIso(a.createdAt, b.createdAt));
|
|
126
|
+
tailItems.sort((a, b) => cmpIso(a.createdAt, b.createdAt));
|
|
127
|
+
let items = [...olderItems, ...tailItems];
|
|
128
|
+
const itemCost = opts.cost?.item ?? ((it) => estimateTokens(it.content));
|
|
129
|
+
const room = budget - (opts.cost?.fixed(Math.max(budget, totalRaw)) ?? 0);
|
|
130
|
+
let tokens = items.reduce((acc, it) => acc + itemCost(it), 0);
|
|
131
|
+
let evicted = 0;
|
|
132
|
+
while (tokens > room && items.length > 0) {
|
|
133
|
+
let worstIdx = -1;
|
|
134
|
+
let worstStrength = Infinity;
|
|
135
|
+
for (let i = 0; i < items.length; i++) {
|
|
136
|
+
if (items[i].isFreshTail)
|
|
137
|
+
continue;
|
|
138
|
+
if (items[i].strength < worstStrength) {
|
|
139
|
+
worstStrength = items[i].strength;
|
|
140
|
+
worstIdx = i;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (worstIdx === -1)
|
|
144
|
+
break;
|
|
145
|
+
const cost = itemCost(items[worstIdx]);
|
|
146
|
+
items = items.filter((_, i) => i !== worstIdx);
|
|
147
|
+
tokens -= cost;
|
|
148
|
+
evicted++;
|
|
149
|
+
}
|
|
150
|
+
return { sessionId, items, tokens, totalRaw, summarized, evicted, truncated };
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=assemble.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type AuditEvent, type AuditOp } from '../audit.js';
|
|
2
|
+
import type { KeysetPosition } from '../keyset.js';
|
|
3
|
+
import type { Context } from './types.js';
|
|
4
|
+
export interface AuditListOpts {
|
|
5
|
+
op?: AuditOp;
|
|
6
|
+
/** ISO timestamp lower bound. */
|
|
7
|
+
since?: string;
|
|
8
|
+
limit?: number;
|
|
9
|
+
/** Resume after this row: the (ts, id) position the previous page ended on. */
|
|
10
|
+
after?: KeysetPosition;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Read audit events scoped to `ctx.tenantId`. Read-only — no audit emit (matches
|
|
14
|
+
* A5: cmdAuditList does not record a 'recall'-style read event).
|
|
15
|
+
*/
|
|
16
|
+
export declare function auditList(ctx: Context, opts: AuditListOpts): AuditEvent[];
|
|
17
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Audit log queries.
|
|
2
|
+
import { openHippoDb, closeHippoDb } from '../db.js';
|
|
3
|
+
import { queryAuditEvents } from '../audit.js';
|
|
4
|
+
/**
|
|
5
|
+
* Read audit events scoped to `ctx.tenantId`. Read-only — no audit emit (matches
|
|
6
|
+
* A5: cmdAuditList does not record a 'recall'-style read event).
|
|
7
|
+
*/
|
|
8
|
+
export function auditList(ctx, opts) {
|
|
9
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
10
|
+
try {
|
|
11
|
+
return queryAuditEvents(db, {
|
|
12
|
+
tenantId: ctx.tenantId,
|
|
13
|
+
op: opts.op,
|
|
14
|
+
since: opts.since,
|
|
15
|
+
limit: opts.limit,
|
|
16
|
+
after: opts.after,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
closeHippoDb(db);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type ApiKeyListItem, type ApiKeyListRow } from '../auth.js';
|
|
2
|
+
import type { KeysetPosition } from '../keyset.js';
|
|
3
|
+
import type { Context } from './types.js';
|
|
4
|
+
export interface AuthCreateOpts {
|
|
5
|
+
label?: string;
|
|
6
|
+
/**
|
|
7
|
+
* v1.12.3: authorization role for the new key. Defaults to `'admin'` for
|
|
8
|
+
* back-compat with v1.12.0-v1.12.2 (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
|
+
*/
|
|
12
|
+
role?: 'admin' | 'member';
|
|
13
|
+
}
|
|
14
|
+
export interface AuthCreateResult {
|
|
15
|
+
keyId: string;
|
|
16
|
+
plaintext: string;
|
|
17
|
+
tenantId: string;
|
|
18
|
+
/** v1.12.3: the role bound to the new key (admin | member). */
|
|
19
|
+
role: 'admin' | 'member';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Mint a new API key. The new key is ALWAYS bound to `ctx.tenantId`. Callers
|
|
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
|
+
*/
|
|
32
|
+
export declare function authCreate(ctx: Context, opts: AuthCreateOpts): AuthCreateResult;
|
|
33
|
+
/**
|
|
34
|
+
* List API keys visible to the calling tenant.
|
|
35
|
+
*
|
|
36
|
+
* Divergence from `cmdAuthList` in src/cli.ts: the CLI today returns ALL keys
|
|
37
|
+
* regardless of tenant (single-tenant deployments). The API surface is tenant-
|
|
38
|
+
* scoped because future multi-tenant deployments will share a hippoRoot, and
|
|
39
|
+
* tenant A must not see tenant B's keys. Read-only — no audit emit (matches A5).
|
|
40
|
+
*/
|
|
41
|
+
export declare function authList(ctx: Context, opts: {
|
|
42
|
+
active: boolean;
|
|
43
|
+
}): ApiKeyListItem[];
|
|
44
|
+
/** One page of the caller's tenant's keys, newest first, with the row ids a next-page cursor is built from. */
|
|
45
|
+
export declare function authListRows(ctx: Context, opts: {
|
|
46
|
+
active: boolean;
|
|
47
|
+
limit?: number;
|
|
48
|
+
after?: KeysetPosition;
|
|
49
|
+
}): ApiKeyListRow[];
|
|
50
|
+
/**
|
|
51
|
+
* Revoke an API key.
|
|
52
|
+
*
|
|
53
|
+
* Security: the key must belong to `ctx.tenantId`. Cross-tenant revoke is
|
|
54
|
+
* rejected with the "not found" message used for missing keys, and a member may
|
|
55
|
+
* revoke only its own key (checked first), so no caller can probe other key_ids.
|
|
56
|
+
*
|
|
57
|
+
* Audit: emits 'auth_revoke' with `tenantId` set to the KEY ROW's tenant_id
|
|
58
|
+
* (M1 fix from A5 review, mirrors src/cli.ts:cmdAuthRevoke). Skipped on no-op
|
|
59
|
+
* revoke (already revoked) so re-running doesn't pad the audit log.
|
|
60
|
+
*/
|
|
61
|
+
export interface AuthRevokeResult {
|
|
62
|
+
ok: true;
|
|
63
|
+
revokedAt: string;
|
|
64
|
+
}
|
|
65
|
+
export declare function authRevoke(ctx: Context, keyId: string): AuthRevokeResult;
|
|
66
|
+
/**
|
|
67
|
+
* The tenant that owns `keyId`, or undefined for an unknown key. Host admin only: it reads across tenants,
|
|
68
|
+
* so the local CLI can run revoke and grant in the key's own tenant.
|
|
69
|
+
*/
|
|
70
|
+
export declare function authKeyTenant(ctx: Context, keyId: string): string | undefined;
|
|
71
|
+
/** Shared result shape for authGrant/authUngrant, named per the file's oxlint anti-slop rule. */
|
|
72
|
+
export interface AuthGrantResult {
|
|
73
|
+
ok: true;
|
|
74
|
+
}
|
|
75
|
+
/** Grant `keyId` read access to one restricted `scope` (ROADMAP Part VIII EI2). Admin only. */
|
|
76
|
+
export declare function authGrant(ctx: Context, keyId: string, scope: string): AuthGrantResult;
|
|
77
|
+
/** Revoke `keyId`'s grant on `scope`. Same authorization and lookup rules as authGrant. */
|
|
78
|
+
export declare function authUngrant(ctx: Context, keyId: string, scope: string): AuthGrantResult;
|
|
79
|
+
//# sourceMappingURL=auth.d.ts.map
|
package/dist/api/auth.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// API key management: create, list, revoke, and grant or ungrant restricted scopes.
|
|
2
|
+
import { openHippoDb, closeHippoDb } from '../db.js';
|
|
3
|
+
import { BadRequestError, ConflictError, ForbiddenError, NotFoundError } from '../api-errors.js';
|
|
4
|
+
import { appendAuditEvent, reportAuditWriteFailure } from '../audit.js';
|
|
5
|
+
import { createApiKey, listApiKeyRows, revokeApiKey, grantScope, ungrantScope } from '../auth.js';
|
|
6
|
+
import { isRestrictedScope } from '../recall-scope.js';
|
|
7
|
+
import { selectApiKeyOwner } from '../store/tenant-lookup.js';
|
|
8
|
+
/**
|
|
9
|
+
* Mint a new API key. The new key is ALWAYS bound to `ctx.tenantId`. Callers
|
|
10
|
+
* cannot override the tenant via the opts bag — a previous `tenantId` field
|
|
11
|
+
* was removed because the HTTP layer would happily forward `body.tenantId`,
|
|
12
|
+
* letting tenant A mint a key for tenant B. The HTTP route handler at
|
|
13
|
+
* `src/server.ts` POST /v1/auth/keys mirrors this: it ignores any body
|
|
14
|
+
* `tenantId` and uses the resolved Bearer's tenant exclusively.
|
|
15
|
+
*
|
|
16
|
+
* Only an admin actor can mint (ForbiddenError otherwise), and a key never
|
|
17
|
+
* outranks its minter: a resolver admin is tenant-only, so it mints members.
|
|
18
|
+
*/
|
|
19
|
+
export function authCreate(ctx, opts) {
|
|
20
|
+
if (ctx.actor.role !== 'admin') {
|
|
21
|
+
throw new ForbiddenError('Only an admin key can create API keys');
|
|
22
|
+
}
|
|
23
|
+
if (ctx.actor.viaAuthResolver && opts.role === 'admin') {
|
|
24
|
+
throw new ForbiddenError('A key minted through the auth resolver can only be a member key');
|
|
25
|
+
}
|
|
26
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
27
|
+
try {
|
|
28
|
+
const role = opts.role ?? (ctx.actor.viaAuthResolver ? 'member' : 'admin');
|
|
29
|
+
const result = createApiKey(db, { tenantId: ctx.tenantId, label: opts.label, role });
|
|
30
|
+
// v1.12.4: audit emit (closes the gap v1.12.3 CHANGELOG flagged as deferred).
|
|
31
|
+
// Mirrors the auth_revoke pattern at authRevoke — same try/catch so audit
|
|
32
|
+
// failure can't crash a successful mint. The plaintext is NEVER logged;
|
|
33
|
+
// metadata carries label + role + the keyId (which is non-secret).
|
|
34
|
+
try {
|
|
35
|
+
appendAuditEvent(db, {
|
|
36
|
+
tenantId: ctx.tenantId,
|
|
37
|
+
actor: ctx.actor.subject,
|
|
38
|
+
op: 'auth_create',
|
|
39
|
+
targetId: result.keyId,
|
|
40
|
+
metadata: {
|
|
41
|
+
label: opts.label ?? null,
|
|
42
|
+
role,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
// Audit must not crash a successful mint.
|
|
48
|
+
reportAuditWriteFailure('auth_create', String(error), result.keyId);
|
|
49
|
+
}
|
|
50
|
+
return { keyId: result.keyId, plaintext: result.plaintext, tenantId: ctx.tenantId, role };
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
closeHippoDb(db);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* List API keys visible to the calling tenant.
|
|
58
|
+
*
|
|
59
|
+
* Divergence from `cmdAuthList` in src/cli.ts: the CLI today returns ALL keys
|
|
60
|
+
* regardless of tenant (single-tenant deployments). The API surface is tenant-
|
|
61
|
+
* scoped because future multi-tenant deployments will share a hippoRoot, and
|
|
62
|
+
* tenant A must not see tenant B's keys. Read-only — no audit emit (matches A5).
|
|
63
|
+
*/
|
|
64
|
+
export function authList(ctx, opts) {
|
|
65
|
+
return authListRows(ctx, opts).map((r) => r.key);
|
|
66
|
+
}
|
|
67
|
+
/** One page of the caller's tenant's keys, newest first, with the row ids a next-page cursor is built from. */
|
|
68
|
+
export function authListRows(ctx, opts) {
|
|
69
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
70
|
+
try {
|
|
71
|
+
return listApiKeyRows(db, { ...opts, tenantId: ctx.tenantId });
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
closeHippoDb(db);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export function authRevoke(ctx, keyId) {
|
|
78
|
+
if (ctx.actor.role !== 'admin' && ctx.actor.subject !== `api_key:${keyId}`) {
|
|
79
|
+
throw new ForbiddenError('A member key can revoke only itself');
|
|
80
|
+
}
|
|
81
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
82
|
+
try {
|
|
83
|
+
const row = selectApiKeyOwner(db, keyId);
|
|
84
|
+
// Cross-tenant access denied: same message as missing key, no info leak.
|
|
85
|
+
if (!row || row.tenantId !== ctx.tenantId) {
|
|
86
|
+
throw new NotFoundError(`Unknown key_id: ${keyId}`);
|
|
87
|
+
}
|
|
88
|
+
if (ctx.actor.viaAuthResolver && row.role === 'admin') {
|
|
89
|
+
throw new ForbiddenError('An auth resolver admin cannot revoke an admin key, which outranks it');
|
|
90
|
+
}
|
|
91
|
+
let revokedAt;
|
|
92
|
+
let alreadyRevoked = false;
|
|
93
|
+
if (row.revokedAt) {
|
|
94
|
+
alreadyRevoked = true;
|
|
95
|
+
revokedAt = row.revokedAt;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
revokeApiKey(db, keyId);
|
|
99
|
+
revokedAt = selectApiKeyOwner(db, keyId)?.revokedAt ?? new Date().toISOString();
|
|
100
|
+
}
|
|
101
|
+
if (!alreadyRevoked) {
|
|
102
|
+
try {
|
|
103
|
+
appendAuditEvent(db, {
|
|
104
|
+
tenantId: row.tenantId, // M1: KEY's tenant, not ctx.tenantId.
|
|
105
|
+
actor: ctx.actor.subject,
|
|
106
|
+
op: 'auth_revoke',
|
|
107
|
+
targetId: keyId,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
// Audit must not crash a successful revoke.
|
|
112
|
+
reportAuditWriteFailure('auth_revoke', String(error), keyId);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { ok: true, revokedAt };
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
closeHippoDb(db);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The tenant that owns `keyId`, or undefined for an unknown key. Host admin only: it reads across tenants,
|
|
123
|
+
* so the local CLI can run revoke and grant in the key's own tenant.
|
|
124
|
+
*/
|
|
125
|
+
export function authKeyTenant(ctx, keyId) {
|
|
126
|
+
if (!ctx.actor.hostAdmin) {
|
|
127
|
+
throw new ForbiddenError('Only the host admin can look up a key across tenants');
|
|
128
|
+
}
|
|
129
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
130
|
+
try {
|
|
131
|
+
return selectApiKeyOwner(db, keyId)?.tenantId;
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
closeHippoDb(db);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** Grant `keyId` read access to one restricted `scope` (ROADMAP Part VIII EI2). Admin only. */
|
|
138
|
+
export function authGrant(ctx, keyId, scope) {
|
|
139
|
+
return changeScopeGrant(ctx, keyId, scope, 'auth_grant');
|
|
140
|
+
}
|
|
141
|
+
/** Revoke `keyId`'s grant on `scope`. Same authorization and lookup rules as authGrant. */
|
|
142
|
+
export function authUngrant(ctx, keyId, scope) {
|
|
143
|
+
return changeScopeGrant(ctx, keyId, scope, 'auth_ungrant');
|
|
144
|
+
}
|
|
145
|
+
function changeScopeGrant(ctx, keyId, scope, op) {
|
|
146
|
+
if (ctx.actor.role !== 'admin') {
|
|
147
|
+
throw new ForbiddenError('Only an admin key can change scope grants');
|
|
148
|
+
}
|
|
149
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
150
|
+
try {
|
|
151
|
+
const row = selectApiKeyOwner(db, keyId);
|
|
152
|
+
if (!row || row.tenantId !== ctx.tenantId) {
|
|
153
|
+
throw new NotFoundError(`Unknown key_id: ${keyId}`);
|
|
154
|
+
}
|
|
155
|
+
if (op === 'auth_grant' && row.revokedAt) {
|
|
156
|
+
throw new ConflictError(`${keyId} is revoked; a grant on it would never apply`);
|
|
157
|
+
}
|
|
158
|
+
if (!isRestrictedScope(scope)) {
|
|
159
|
+
throw new BadRequestError(`${scope} is not a restricted scope; it is already readable by default`);
|
|
160
|
+
}
|
|
161
|
+
if (op === 'auth_grant')
|
|
162
|
+
grantScope(db, keyId, scope);
|
|
163
|
+
else
|
|
164
|
+
ungrantScope(db, keyId, scope);
|
|
165
|
+
try {
|
|
166
|
+
appendAuditEvent(db, { tenantId: ctx.tenantId, actor: ctx.actor.subject, op, targetId: keyId, metadata: { scope } });
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
// Audit must not undo a grant change that already committed; surface it instead.
|
|
170
|
+
reportAuditWriteFailure(op, String(err), keyId);
|
|
171
|
+
}
|
|
172
|
+
return { ok: true };
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
closeHippoDb(db);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { TaskSnapshot, SessionEvent } from '../store/rows.js';
|
|
2
|
+
import type { SessionHandoff } from '../handoff.js';
|
|
3
|
+
import type { MemoryEntry } from '../memory.js';
|
|
4
|
+
import type { DeliveryObserver } from '../delivery-recorder.js';
|
|
5
|
+
import type { AmbientState } from '../ambient.js';
|
|
6
|
+
/**
|
|
7
|
+
* Options for `getContext` — assemble a budget-bounded context bundle
|
|
8
|
+
* (recalled memories + active task snapshot + handoff + recent events).
|
|
9
|
+
* Extracted from `cmdContext` in `cli.ts` in Episode A of the api.ts refactor.
|
|
10
|
+
*
|
|
11
|
+
* Named `getContext` (not `context`) to avoid collision with the `Context`
|
|
12
|
+
* interface above and the ubiquitous `ctx: Context` convention. Follows the
|
|
13
|
+
* existing `getEntry` naming pattern in store.ts.
|
|
14
|
+
*
|
|
15
|
+
* Scope narrow (T5 execute decision): rendering opts (`format`, `framing`,
|
|
16
|
+
* `rendered`) and host-side opts (`auto`) are NOT included here. The print
|
|
17
|
+
* helpers (`printContextMarkdown`, `printActiveTaskSnapshot`, `printHandoff`,
|
|
18
|
+
* `printSessionEvents`) are shared with `cmdRecall` / `cmdSnapshot` /
|
|
19
|
+
* `cmdHandoffShow` — moving them into api.ts would expand T5 to also rewire
|
|
20
|
+
* those commands. CLI handles rendering + auto-resolution. Episode B can add
|
|
21
|
+
* `api.renderContext` once a shared rendering need actually materializes.
|
|
22
|
+
*/
|
|
23
|
+
export interface ContextOpts {
|
|
24
|
+
q?: string;
|
|
25
|
+
/** Default 1500 tokens. */
|
|
26
|
+
budget?: number;
|
|
27
|
+
limit?: number;
|
|
28
|
+
pinnedOnly?: boolean;
|
|
29
|
+
scope?: string;
|
|
30
|
+
/** Envelope scope to match exactly, as in `recall`: admits that scope even when private, after the actor's scope check. */
|
|
31
|
+
exactScope?: string;
|
|
32
|
+
/** With `pinnedOnly`, also inject the N most recent writes that pass the
|
|
33
|
+
* quality floor (`isContentWorthStoring`, DF3). Filtering happens BEFORE
|
|
34
|
+
* the take-N, so a caller asking for 5 gets 5 qualifying entries rather
|
|
35
|
+
* than 5-minus-junk; pinned entries bypass the floor. Entries are only
|
|
36
|
+
* skipped for this read, never mutated or deleted. Ignored when
|
|
37
|
+
* `pinnedOnly` is false — no other path reads it. */
|
|
38
|
+
includeRecent?: number;
|
|
39
|
+
/** v39 memory scope isolation: re-include other-project memories that the
|
|
40
|
+
* origin partition excludes by default. They come back tagged
|
|
41
|
+
* `category: 'cross-project'` so renderers can demarcate them. */
|
|
42
|
+
crossProject?: boolean;
|
|
43
|
+
/** The active project name for the origin partition ('' = not in a
|
|
44
|
+
* project). Defaults to `resolveProjectIdentity(process.cwd()).name`;
|
|
45
|
+
* surfaces whose process cwd is not the caller's project (HTTP server)
|
|
46
|
+
* should pass it explicitly. */
|
|
47
|
+
currentProject?: string;
|
|
48
|
+
/** DF1 (docs/plans/2026-08-23-df1-snapshot-lifecycle.md, T2): the calling
|
|
49
|
+
* session's id. Stamped on this call's recall trace, and the owner-match input to
|
|
50
|
+
* `loadFreshActiveTaskSnapshot` — when it strictly equals the active
|
|
51
|
+
* snapshot's `session_id`, the read is unbounded (same-session
|
|
52
|
+
* continuity); otherwise the snapshot must pass the freshness bound to
|
|
53
|
+
* surface. Absent (undefined/null/'') never short-circuits as a match;
|
|
54
|
+
* it just means every snapshot goes through the age check. Host-resolved
|
|
55
|
+
* (stdin payload, HIPPO_SESSION_ID, else the host's session var) so this stays host-agnostic. */
|
|
56
|
+
currentSessionId?: string | null;
|
|
57
|
+
/** Z1: raw hook-payload prompt; only the pinned-only branch reads it, gated on `pinnedInject.promptRecall`. */
|
|
58
|
+
prompt?: string;
|
|
59
|
+
/** What the budget pays for, from the caller that renders the block. Absent = the memory text alone. */
|
|
60
|
+
cost?: ContextCost;
|
|
61
|
+
/** @internal The CLI's delivery-ledger observer; it only reads, so selection is the same with or without it. */
|
|
62
|
+
deliveryObserver?: DeliveryObserver;
|
|
63
|
+
}
|
|
64
|
+
/** Budget prices in the text a caller prints, so the budget bounds what reaches the model. */
|
|
65
|
+
export interface ContextCost {
|
|
66
|
+
/** Tokens of one entry as printed. */
|
|
67
|
+
entry: (item: Pick<ContextResultEntry, 'entry' | 'isGlobal' | 'promptRecall' | 'origin' | 'category'>) => number;
|
|
68
|
+
/** Tokens of the headers and footer the block can print at this budget, reserved before any entry. */
|
|
69
|
+
fixed: (budget: number, can: {
|
|
70
|
+
cross: boolean;
|
|
71
|
+
promptRecall: boolean;
|
|
72
|
+
ambient: boolean;
|
|
73
|
+
}) => number;
|
|
74
|
+
/** Tokens of the sections printed ahead of the memories, each as printed. */
|
|
75
|
+
snapshot: (s: TaskSnapshot) => number;
|
|
76
|
+
handoff: (h: SessionHandoff) => number;
|
|
77
|
+
trail: (events: SessionEvent[]) => number;
|
|
78
|
+
}
|
|
79
|
+
export interface ContextResultEntry {
|
|
80
|
+
entry: MemoryEntry;
|
|
81
|
+
score: number;
|
|
82
|
+
/** What this entry cost the budget: its printed line under `ContextOpts.cost`, else its memory text. */
|
|
83
|
+
tokens: number;
|
|
84
|
+
isGlobal?: boolean;
|
|
85
|
+
isFreshTail?: boolean;
|
|
86
|
+
/** Z1: admitted by the prompt-recall gate, not the recent-N backfill or a pin. */
|
|
87
|
+
promptRecall?: boolean;
|
|
88
|
+
/** v39: the entry's owning project ('' = user-global, null = legacy row). */
|
|
89
|
+
origin?: string | null;
|
|
90
|
+
/** v39: how the origin relates to the active project. 'cross-project'
|
|
91
|
+
* entries only appear when ContextOpts.crossProject was set (or isolation
|
|
92
|
+
* is disabled). */
|
|
93
|
+
category?: 'project' | 'user-global' | 'cross-project';
|
|
94
|
+
}
|
|
95
|
+
export interface ContextResult {
|
|
96
|
+
entries: ContextResultEntry[];
|
|
97
|
+
tokens: number;
|
|
98
|
+
activeSnapshot?: TaskSnapshot | null;
|
|
99
|
+
sessionHandoff?: SessionHandoff | null;
|
|
100
|
+
recentEvents?: SessionEvent[];
|
|
101
|
+
/** The ambient landscape summary over every live row the read may see in the local and global stores,
|
|
102
|
+
* not just the rows loaded. Present only when ambient config is on, the caller is not pinned-only, and an entry was returned. */
|
|
103
|
+
ambientState?: AmbientState;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=context-types.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type MemoryEntry } from '../memory.js';
|
|
2
|
+
import type { ContextOpts, ContextResult } from './context-types.js';
|
|
3
|
+
import type { Context } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* v39 S4: the secret half of the ambient policy on its own, for callers
|
|
6
|
+
* that apply their own scope rule. A flagged row is only admitted inside its owning project;
|
|
7
|
+
* flagged rows with no project origin never ambient-inject.
|
|
8
|
+
*/
|
|
9
|
+
export declare function ambientSecretAdmit(e: MemoryEntry, currentProjectName: string): boolean;
|
|
10
|
+
/** Most rows per store a no-query context reads; past it, ranking and ambientState see the strongest by decay. */
|
|
11
|
+
export declare const CONTEXT_CANDIDATE_CAP = 2000;
|
|
12
|
+
export declare function oneCopyPerMemory(local: readonly MemoryEntry[], global: readonly MemoryEntry[], now: Date): [MemoryEntry[], MemoryEntry[]];
|
|
13
|
+
/**
|
|
14
|
+
* Assemble a context bundle: recalled memories (pinned-only / strength-sorted
|
|
15
|
+
* fallback / hybrid search) + active task snapshot + session handoff + recent
|
|
16
|
+
* session events. Budget-bounded, tenant-scoped. Mutates `last_retrieval_ids`
|
|
17
|
+
* + emits a 'recall' audit row for non-pinned, non-'*' queries.
|
|
18
|
+
*
|
|
19
|
+
* Behaves like the pre-extraction `cmdContext` data-loading + selection
|
|
20
|
+
* pipeline. CLI presentation (markdown / json / additional-context rendering)
|
|
21
|
+
* stays in `cli.ts`.
|
|
22
|
+
*
|
|
23
|
+
* Tenant scope: all `loadAllEntries` / snapshot / handoff / events reads use
|
|
24
|
+
* `ctx.tenantId`. Cross-tenant rows are filtered out.
|
|
25
|
+
*
|
|
26
|
+
* Returns an empty result (`entries: []`, snapshot/handoff/events undefined)
|
|
27
|
+
* when there's nothing to surface (no memories AND no snapshot AND no handoff
|
|
28
|
+
* AND no recent events).
|
|
29
|
+
*/
|
|
30
|
+
export declare function getContext(ctx: Context, opts?: ContextOpts): Promise<ContextResult>;
|
|
31
|
+
//# sourceMappingURL=context.d.ts.map
|