hippo-memory 1.59.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 -1260
- package/dist/api.js +25 -2711
- package/dist/audit.d.ts +3 -0
- package/dist/audit.js +7 -3
- package/dist/auth.d.ts +45 -4
- package/dist/auth.js +125 -48
- package/dist/autolearn.js +7 -4
- 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 +319 -13
- package/dist/cli.js +436 -8580
- package/dist/client.js +15 -8
- package/dist/compaction-record.js +12 -9
- package/dist/config.js +12 -11
- package/dist/connectors/github/backfill.js +94 -87
- package/dist/connectors/github/cli-impl.js +5 -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 +13 -12
- 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 +231 -203
- 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 -3036
- package/dist/decisions.d.ts +4 -1
- package/dist/decisions.js +9 -7
- package/dist/dedupe.js +3 -2
- package/dist/delivery-recorder.js +5 -1
- package/dist/doctor.js +4 -3
- package/dist/dormant.js +1 -0
- package/dist/embedding-provider.d.ts +1 -1
- package/dist/embedding-provider.js +7 -5
- package/dist/embeddings.d.ts +9 -52
- package/dist/embeddings.js +47 -298
- 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 +5 -4
- 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} +8 -391
- 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/handoff.js +3 -0
- 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 +8 -5
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -6
- package/dist/invalidation.js +2 -1
- package/dist/judgment.js +7 -3
- 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 -70
- package/dist/mcp/server.js +8 -1172
- 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 +8 -3
- 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 +8 -5
- package/dist/project-briefs.d.ts +3 -0
- package/dist/project-briefs.js +7 -5
- package/dist/project-identity.d.ts +1 -1
- package/dist/project-identity.js +12 -6
- package/dist/project-merge.js +3 -1
- package/dist/quarantine.d.ts +2 -1
- package/dist/quarantine.js +8 -5
- package/dist/raw-archive-mirror-cleanup.js +2 -1
- 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 +3 -3
- package/dist/recall-trace.js +10 -14
- package/dist/refine-llm.js +20 -11
- package/dist/reject-flow.js +6 -1
- package/dist/rerankers/clef.d.ts +2 -2
- package/dist/rerankers/clef.js +72 -30
- package/dist/rerankers/cross-encoder.js +6 -4
- package/dist/rerankers/jev.d.ts +4 -2
- package/dist/rerankers/jev.js +24 -19
- package/dist/rerankers/llm.d.ts +4 -2
- package/dist/rerankers/llm.js +61 -41
- package/dist/rerankers/types.d.ts +1 -1
- package/dist/salience.js +1 -1
- package/dist/same-text.d.ts +2 -0
- package/dist/same-text.js +4 -0
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.js +26 -3
- 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 +3 -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 +92 -2368
- 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 +46 -40
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +7 -5
- package/dist/stdin.js +3 -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/token-ledger.js +1 -0
- 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 +2 -1
- package/dist/capture.d.ts +0 -155
- package/dist/capture.js +0 -1293
- package/dist/consolidate.d.ts +0 -58
- package/dist/consolidate.js +0 -1123
- package/dist/graph.d.ts +0 -245
- package/dist/hooks.d.ts +0 -208
- package/dist/hooks.js +0 -1073
- package/dist/importers.js +0 -897
- package/dist/predictions.js +0 -620
- package/dist/search.d.ts +0 -320
- package/dist/search.js +0 -968
- package/dist/store.d.ts +0 -744
- package/dist/store.js +0 -3372
- 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
package/dist/audit.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type MemoryEntry } from './memory.js';
|
|
2
2
|
import type { DatabaseSyncLike } from './db.js';
|
|
3
3
|
import type { JsonObject } from './working-memory.js';
|
|
4
|
+
import { type KeysetPosition } from './keyset.js';
|
|
4
5
|
export type AuditSeverity = 'warning' | 'error';
|
|
5
6
|
export interface AuditIssue {
|
|
6
7
|
memoryId: string;
|
|
@@ -42,6 +43,8 @@ export interface QueryAuditOpts {
|
|
|
42
43
|
op?: AuditOp;
|
|
43
44
|
since?: string;
|
|
44
45
|
limit?: number;
|
|
46
|
+
/** Resume after this row: the (ts, id) position the previous page ended on. */
|
|
47
|
+
after?: KeysetPosition;
|
|
45
48
|
}
|
|
46
49
|
export interface AuditEvent {
|
|
47
50
|
id: number;
|
package/dist/audit.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { canAutoDelete } from './memory.js';
|
|
3
3
|
import { log } from './log.js';
|
|
4
|
+
import { keysetAfter } from './keyset.js';
|
|
4
5
|
export const STOP_WORDS = new Set([
|
|
5
6
|
'the', 'a', 'an', 'is', 'was', 'are', 'were', 'be', 'been', 'being',
|
|
6
7
|
'to', 'of', 'in', 'for', 'on', 'with', 'at', 'by', 'from', 'it',
|
|
@@ -274,11 +275,13 @@ export function queryAuditEvents(db, opts) {
|
|
|
274
275
|
where.push('ts >= ?');
|
|
275
276
|
params.push(opts.since);
|
|
276
277
|
}
|
|
277
|
-
const
|
|
278
|
+
const after = keysetAfter('ts', 'id', opts.after);
|
|
279
|
+
// One past the route's 10000 cap: GET /v1/audit reads a row ahead to tell whether another page exists.
|
|
280
|
+
const limit = Math.max(1, Math.min(opts.limit ?? 100, 10001));
|
|
278
281
|
// SAFETY: AUDIT_COLUMNS names exactly the AuditRow columns, in this order.
|
|
279
282
|
const rows = db
|
|
280
|
-
.prepare(`SELECT ${AUDIT_COLUMNS} FROM audit_log WHERE ${where.join(' AND ')} ORDER BY ts DESC, id DESC LIMIT ?`)
|
|
281
|
-
.all(...params, limit);
|
|
283
|
+
.prepare(`SELECT ${AUDIT_COLUMNS} FROM audit_log WHERE ${where.join(' AND ')}${after.sql} ORDER BY ts DESC, id DESC LIMIT ?`)
|
|
284
|
+
.all(...params, ...after.params, limit);
|
|
282
285
|
return rows.map(rowToAuditEvent);
|
|
283
286
|
}
|
|
284
287
|
/**
|
|
@@ -330,6 +333,7 @@ function safeJsonParse(raw) {
|
|
|
330
333
|
return v instanceof Object ? v : {};
|
|
331
334
|
}
|
|
332
335
|
catch {
|
|
336
|
+
// Malformed metadata reads as empty so the audit row itself stays listable.
|
|
333
337
|
return {};
|
|
334
338
|
}
|
|
335
339
|
}
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type DatabaseSyncLike } from './db.js';
|
|
2
|
+
import { type KeysetPosition } from './keyset.js';
|
|
2
3
|
/** Every minted API key starts with this, so the server can route a bearer token by shape. */
|
|
3
4
|
export declare const API_KEY_PREFIX = "hk_";
|
|
4
|
-
|
|
5
|
+
/** Counts since process start, so a flood of bad tokens shows as scrypt work, not just as 401s. */
|
|
6
|
+
export interface ApiKeyVerifyStats {
|
|
7
|
+
readonly storeLookups: number;
|
|
8
|
+
readonly scryptRuns: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function apiKeyVerifyStats(): ApiKeyVerifyStats;
|
|
5
11
|
export interface CreateApiKeyOpts {
|
|
6
12
|
tenantId: string;
|
|
7
13
|
label?: string;
|
|
@@ -22,7 +28,29 @@ export interface ValidateResult {
|
|
|
22
28
|
/** EI2: scope grants for this key. Present only when valid=true. */
|
|
23
29
|
scopes?: string[];
|
|
24
30
|
}
|
|
31
|
+
/** The identity a verified API key carries. */
|
|
32
|
+
export interface VerifiedApiKey {
|
|
33
|
+
tenantId: string;
|
|
34
|
+
keyId: string;
|
|
35
|
+
role: 'admin' | 'member';
|
|
36
|
+
scopes: string[];
|
|
37
|
+
}
|
|
25
38
|
export declare function validateApiKey(db: DatabaseSyncLike, plaintext: string): ValidateResult;
|
|
39
|
+
/** How long a verified key is trusted without a store read; also the ceiling on a revoke made by another process. */
|
|
40
|
+
export declare const VERIFIED_KEY_TTL_MS = 60000;
|
|
41
|
+
/** LRU of verified keys with an absolute TTL. Holds a SHA-256 of the token, never the token. */
|
|
42
|
+
export declare class VerifiedKeyCache {
|
|
43
|
+
private readonly capacity;
|
|
44
|
+
private readonly ttlMs;
|
|
45
|
+
private readonly entries;
|
|
46
|
+
constructor(capacity: number, ttlMs: number);
|
|
47
|
+
get size(): number;
|
|
48
|
+
get(hippoRoot: string, keyId: string, plaintext: string, now: number): VerifiedApiKey | undefined;
|
|
49
|
+
set(hippoRoot: string, keyId: string, plaintext: string, key: VerifiedApiKey, now: number): void;
|
|
50
|
+
delete(keyId: string): void;
|
|
51
|
+
}
|
|
52
|
+
/** Verify a bearer API key for `hippoRoot`; a cache hit skips both scrypt and the DB open. Null when invalid. */
|
|
53
|
+
export declare function verifyApiKeyCached(hippoRoot: string, plaintext: string): VerifiedApiKey | null;
|
|
26
54
|
export declare function revokeApiKey(db: DatabaseSyncLike, keyId: string): void;
|
|
27
55
|
/** EI2: grant `keyId` read access to one restricted `scope`. Idempotent. */
|
|
28
56
|
export declare function grantScope(db: DatabaseSyncLike, keyId: string, scope: string): void;
|
|
@@ -45,7 +73,20 @@ export interface ApiKeyListItem {
|
|
|
45
73
|
/** EI2: restricted scopes this key may read. */
|
|
46
74
|
scopes: string[];
|
|
47
75
|
}
|
|
48
|
-
export
|
|
76
|
+
export interface ListApiKeysOpts {
|
|
49
77
|
active: boolean;
|
|
50
|
-
|
|
78
|
+
/** Only this tenant's keys; omit for every tenant (the CLI's single-tenant view). */
|
|
79
|
+
tenantId?: string;
|
|
80
|
+
/** Resume after this row: the position the previous page ended on (key and id are both the row id). */
|
|
81
|
+
after?: KeysetPosition;
|
|
82
|
+
limit?: number;
|
|
83
|
+
}
|
|
84
|
+
/** A listed key plus its row id, the paging key the list item itself does not expose. */
|
|
85
|
+
export interface ApiKeyListRow {
|
|
86
|
+
rowId: number;
|
|
87
|
+
key: ApiKeyListItem;
|
|
88
|
+
}
|
|
89
|
+
/** Keys newest first, with their row ids, filtered and limited in SQL. */
|
|
90
|
+
export declare function listApiKeyRows(db: DatabaseSyncLike, opts: ListApiKeysOpts): ApiKeyListRow[];
|
|
91
|
+
export declare function listApiKeys(db: DatabaseSyncLike, opts: ListApiKeysOpts): ApiKeyListItem[];
|
|
51
92
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { randomBytes, scryptSync, timingSafeEqual } from 'node:crypto';
|
|
1
|
+
import { createHash, randomBytes, scryptSync, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { openHippoDb, closeHippoDb } from './db.js';
|
|
3
|
+
import { keysetAfter } from './keyset.js';
|
|
2
4
|
/** Every minted API key starts with this, so the server can route a bearer token by shape. */
|
|
3
5
|
export const API_KEY_PREFIX = 'hk_';
|
|
4
6
|
const ID_LEN = 24; // base32 chars after prefix
|
|
5
7
|
const SECRET_LEN = 32; // base32 chars after dot
|
|
6
8
|
const SCRYPT_KEYLEN = 32;
|
|
7
9
|
const BASE32 = 'abcdefghijklmnopqrstuvwxyz234567';
|
|
10
|
+
const MINTED_KEY_PATTERN = new RegExp(`^${API_KEY_PREFIX}[a-z2-7]{${ID_LEN}}\\.[a-z2-7]{${SECRET_LEN}}$`);
|
|
8
11
|
function randBase32(n) {
|
|
9
12
|
const bytes = randomBytes(n);
|
|
10
13
|
let out = '';
|
|
@@ -18,18 +21,9 @@ function hashKey(plaintext) {
|
|
|
18
21
|
const hash = scryptSync(plaintext, salt, SCRYPT_KEYLEN);
|
|
19
22
|
return `scrypt$${salt.toString('hex')}$${hash.toString('hex')}`;
|
|
20
23
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// itself can still leak via cache effects — v0.40 follow-up: request-level
|
|
25
|
-
// rate limit on /v1/* to bound key-id enumeration. Stored format identical to
|
|
26
|
-
// real hashes: scrypt$saltHex$hashHex.
|
|
27
|
-
const DUMMY_PLAINTEXT = 'hk_dummy_constant_padding_for_timing.dummy_secret_padding_for_timing_x';
|
|
28
|
-
// Precomputed `hashKey(DUMMY_PLAINTEXT)`: computing it at module load put one scrypt on every CLI start.
|
|
29
|
-
const DUMMY_HASH = 'scrypt$5b2117156f1ad78738fd8b6a5bace454$92e098fa28003b7c38ba8f1451bd8618260a4a3c5a64b87cc2b471567c0960e7';
|
|
30
|
-
// Not a secret (it's padding, not a real key hash): exposed only so a test can pin its shape.
|
|
31
|
-
export function _dummyHashForTests() {
|
|
32
|
-
return DUMMY_HASH;
|
|
24
|
+
const verifyStats = { storeLookups: 0, scryptRuns: 0 };
|
|
25
|
+
export function apiKeyVerifyStats() {
|
|
26
|
+
return { ...verifyStats };
|
|
33
27
|
}
|
|
34
28
|
function verifyKey(plaintext, stored) {
|
|
35
29
|
const parts = stored.split('$');
|
|
@@ -37,6 +31,7 @@ function verifyKey(plaintext, stored) {
|
|
|
37
31
|
return false;
|
|
38
32
|
const salt = Buffer.from(parts[1], 'hex');
|
|
39
33
|
const expected = Buffer.from(parts[2], 'hex');
|
|
34
|
+
verifyStats.scryptRuns++;
|
|
40
35
|
const actual = scryptSync(plaintext, salt, expected.length);
|
|
41
36
|
return expected.length === actual.length && timingSafeEqual(expected, actual);
|
|
42
37
|
}
|
|
@@ -52,49 +47,115 @@ export function createApiKey(db, opts) {
|
|
|
52
47
|
db.prepare(`INSERT INTO api_keys (key_id, key_hash, tenant_id, label, created_at, role) VALUES (?, ?, ?, ?, ?, ?)`).run(keyId, hash, opts.tenantId, opts.label ?? null, new Date().toISOString(), opts.role ?? 'admin');
|
|
53
48
|
return { keyId, plaintext };
|
|
54
49
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
verifyKey(DUMMY_PLAINTEXT, DUMMY_HASH);
|
|
61
|
-
return { valid: false };
|
|
62
|
-
}
|
|
63
|
-
const keyId = plaintext.slice(0, dot);
|
|
50
|
+
/** One full check against the store: shape, row, revocation, then scrypt. Null for any failure. */
|
|
51
|
+
function lookupApiKey(db, plaintext) {
|
|
52
|
+
if (!MINTED_KEY_PATTERN.test(plaintext))
|
|
53
|
+
return null;
|
|
54
|
+
const keyId = plaintext.slice(0, API_KEY_PREFIX.length + ID_LEN);
|
|
64
55
|
// SAFETY: row comes from the SELECT above, which projects exactly
|
|
65
56
|
// key_hash, tenant_id, revoked_at, role; `.get` returns undefined when no
|
|
66
57
|
// row matches key_id.
|
|
67
58
|
const row = db
|
|
68
59
|
.prepare(`SELECT key_hash, tenant_id, revoked_at, role FROM api_keys WHERE key_id = ?`)
|
|
69
60
|
.get(keyId);
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
//
|
|
74
|
-
const target = (row && !row.revoked_at) ? row.key_hash : DUMMY_HASH;
|
|
75
|
-
const matches = verifyKey(plaintext, target);
|
|
76
|
-
if (!row || row.revoked_at || !matches)
|
|
77
|
-
return { valid: false };
|
|
78
|
-
// v1.12.0: fail-safe to least privilege — only 'admin' is admitted as admin,
|
|
79
|
-
// anything else (including future schema drift, manual DB tampering inserting
|
|
80
|
-
// 'superuser', or a NULL slipped past the NOT NULL constraint) downgrades to
|
|
81
|
-
// 'member'. The migration constrains to 'admin' DEFAULT, but defense-in-depth.
|
|
61
|
+
// Ids are 120 random bits and not secret, so padding the miss path with scrypt hid nothing and let junk tokens burn CPU.
|
|
62
|
+
if (!row || row.revoked_at || !verifyKey(plaintext, row.key_hash))
|
|
63
|
+
return null;
|
|
64
|
+
// Fail-safe to least privilege: any role value but 'admin' reads as 'member'.
|
|
82
65
|
const role = row.role === 'admin' ? 'admin' : 'member';
|
|
83
|
-
|
|
84
|
-
|
|
66
|
+
return { tenantId: row.tenant_id, keyId, role, scopes: listScopeGrants(db, keyId) };
|
|
67
|
+
}
|
|
68
|
+
export function validateApiKey(db, plaintext) {
|
|
69
|
+
const key = lookupApiKey(db, plaintext);
|
|
70
|
+
return key ? { valid: true, ...key } : { valid: false };
|
|
71
|
+
}
|
|
72
|
+
/** How long a verified key is trusted without a store read; also the ceiling on a revoke made by another process. */
|
|
73
|
+
export const VERIFIED_KEY_TTL_MS = 60_000;
|
|
74
|
+
const VERIFIED_KEY_CACHE_CAP = 1_000;
|
|
75
|
+
function secretDigest(plaintext) {
|
|
76
|
+
return createHash('sha256').update(plaintext).digest();
|
|
77
|
+
}
|
|
78
|
+
/** LRU of verified keys with an absolute TTL. Holds a SHA-256 of the token, never the token. */
|
|
79
|
+
export class VerifiedKeyCache {
|
|
80
|
+
capacity;
|
|
81
|
+
ttlMs;
|
|
82
|
+
// Map iterates in insertion order, so re-inserting on a hit makes the first key the least recent.
|
|
83
|
+
entries = new Map();
|
|
84
|
+
constructor(capacity, ttlMs) {
|
|
85
|
+
this.capacity = capacity;
|
|
86
|
+
this.ttlMs = ttlMs;
|
|
87
|
+
}
|
|
88
|
+
get size() {
|
|
89
|
+
return this.entries.size;
|
|
90
|
+
}
|
|
91
|
+
get(hippoRoot, keyId, plaintext, now) {
|
|
92
|
+
const entry = this.entries.get(keyId);
|
|
93
|
+
if (!entry || entry.hippoRoot !== hippoRoot)
|
|
94
|
+
return undefined;
|
|
95
|
+
if (now >= entry.expiresAt) {
|
|
96
|
+
this.entries.delete(keyId);
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
// A wrong secret misses but leaves the entry, so a flood of bad guesses cannot evict a good key.
|
|
100
|
+
if (!timingSafeEqual(entry.digest, secretDigest(plaintext)))
|
|
101
|
+
return undefined;
|
|
102
|
+
this.entries.delete(keyId);
|
|
103
|
+
this.entries.set(keyId, entry);
|
|
104
|
+
return { ...entry.key, scopes: [...entry.key.scopes] };
|
|
105
|
+
}
|
|
106
|
+
set(hippoRoot, keyId, plaintext, key, now) {
|
|
107
|
+
this.entries.delete(keyId);
|
|
108
|
+
if (this.entries.size >= this.capacity) {
|
|
109
|
+
const oldest = this.entries.keys().next();
|
|
110
|
+
if (!oldest.done)
|
|
111
|
+
this.entries.delete(oldest.value);
|
|
112
|
+
}
|
|
113
|
+
const frozen = Object.freeze({ ...key, scopes: [...key.scopes] });
|
|
114
|
+
this.entries.set(keyId, { hippoRoot, digest: secretDigest(plaintext), key: frozen, expiresAt: now + this.ttlMs });
|
|
115
|
+
}
|
|
116
|
+
delete(keyId) {
|
|
117
|
+
this.entries.delete(keyId);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// SHORTCUT: per-process cache, so a revoke or scope change made by another process (the CLI) lands within VERIFIED_KEY_TTL_MS; a shared revocation epoch in the store if that is too slow.
|
|
121
|
+
const verifiedKeys = new VerifiedKeyCache(VERIFIED_KEY_CACHE_CAP, VERIFIED_KEY_TTL_MS);
|
|
122
|
+
/** Verify a bearer API key for `hippoRoot`; a cache hit skips both scrypt and the DB open. Null when invalid. */
|
|
123
|
+
export function verifyApiKeyCached(hippoRoot, plaintext) {
|
|
124
|
+
if (!MINTED_KEY_PATTERN.test(plaintext))
|
|
125
|
+
return null;
|
|
126
|
+
const keyId = plaintext.slice(0, API_KEY_PREFIX.length + ID_LEN);
|
|
127
|
+
const hit = verifiedKeys.get(hippoRoot, keyId, plaintext, Date.now());
|
|
128
|
+
if (hit)
|
|
129
|
+
return hit;
|
|
130
|
+
verifyStats.storeLookups++;
|
|
131
|
+
const db = openHippoDb(hippoRoot);
|
|
132
|
+
let key;
|
|
133
|
+
try {
|
|
134
|
+
key = lookupApiKey(db, plaintext);
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
closeHippoDb(db);
|
|
138
|
+
}
|
|
139
|
+
// Only successes are cached: caching misses would let junk tokens fill the cache and evict real keys.
|
|
140
|
+
if (key)
|
|
141
|
+
verifiedKeys.set(hippoRoot, keyId, plaintext, key, Date.now());
|
|
142
|
+
return key;
|
|
85
143
|
}
|
|
86
144
|
export function revokeApiKey(db, keyId) {
|
|
87
145
|
db.prepare(`UPDATE api_keys SET revoked_at = ? WHERE key_id = ? AND revoked_at IS NULL`)
|
|
88
146
|
.run(new Date().toISOString(), keyId);
|
|
147
|
+
verifiedKeys.delete(keyId);
|
|
89
148
|
}
|
|
90
149
|
/** EI2: grant `keyId` read access to one restricted `scope`. Idempotent. */
|
|
91
150
|
export function grantScope(db, keyId, scope) {
|
|
92
151
|
db.prepare(`INSERT INTO api_key_scope_grants (key_id, scope, granted_at) VALUES (?, ?, ?)
|
|
93
152
|
ON CONFLICT(key_id, scope) DO NOTHING`).run(keyId, scope, new Date().toISOString());
|
|
153
|
+
verifiedKeys.delete(keyId);
|
|
94
154
|
}
|
|
95
155
|
/** EI2: revoke `keyId`'s grant on `scope`. Not an error when no such grant exists. */
|
|
96
156
|
export function ungrantScope(db, keyId, scope) {
|
|
97
157
|
db.prepare(`DELETE FROM api_key_scope_grants WHERE key_id = ? AND scope = ?`).run(keyId, scope);
|
|
158
|
+
verifiedKeys.delete(keyId);
|
|
98
159
|
}
|
|
99
160
|
/** EI2: every restricted scope `keyId` may read. */
|
|
100
161
|
export function listScopeGrants(db, keyId) {
|
|
@@ -104,19 +165,35 @@ export function listScopeGrants(db, keyId) {
|
|
|
104
165
|
.all(keyId);
|
|
105
166
|
return rows.map((r) => r.scope);
|
|
106
167
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
168
|
+
/** Keys newest first, with their row ids, filtered and limited in SQL. */
|
|
169
|
+
export function listApiKeyRows(db, opts) {
|
|
170
|
+
const where = ['1 = 1'];
|
|
171
|
+
const params = [];
|
|
172
|
+
if (opts.active)
|
|
173
|
+
where.push('revoked_at IS NULL');
|
|
174
|
+
if (opts.tenantId !== undefined) {
|
|
175
|
+
where.push('tenant_id = ?');
|
|
176
|
+
params.push(opts.tenantId);
|
|
177
|
+
}
|
|
178
|
+
const after = keysetAfter('id', 'id', opts.after);
|
|
179
|
+
params.push(...after.params);
|
|
180
|
+
const limitSql = opts.limit === undefined ? '' : ' LIMIT ?';
|
|
181
|
+
if (opts.limit !== undefined)
|
|
182
|
+
params.push(opts.limit);
|
|
183
|
+
const sql = `SELECT id, key_id, tenant_id, label, created_at, revoked_at, role FROM api_keys WHERE ${where.join(' AND ')}${after.sql} ORDER BY id DESC${limitSql}`;
|
|
184
|
+
// SAFETY: the SELECT above projects exactly these 7 columns, in this order.
|
|
185
|
+
const rows = db.prepare(sql).all(...params);
|
|
115
186
|
return rows.map(r => ({
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
187
|
+
rowId: r.id,
|
|
188
|
+
key: {
|
|
189
|
+
keyId: r.key_id, tenantId: r.tenant_id, label: r.label,
|
|
190
|
+
createdAt: r.created_at, revokedAt: r.revoked_at,
|
|
191
|
+
role: r.role === 'admin' ? 'admin' : 'member',
|
|
192
|
+
scopes: listScopeGrants(db, r.key_id),
|
|
193
|
+
},
|
|
120
194
|
}));
|
|
121
195
|
}
|
|
196
|
+
export function listApiKeys(db, opts) {
|
|
197
|
+
return listApiKeyRows(db, opts).map(r => r.key);
|
|
198
|
+
}
|
|
122
199
|
//# sourceMappingURL=auth.js.map
|
package/dist/autolearn.js
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { execSync, execFileSync, spawn } from 'child_process';
|
|
6
6
|
import { createMemory, Layer, DEFAULT_HALF_LIFE_DAYS } from './memory.js';
|
|
7
|
-
import { loadAllEntries } from './store.js';
|
|
8
|
-
import { textOverlap } from './
|
|
7
|
+
import { loadAllEntries } from './store/entry-reads.js';
|
|
8
|
+
import { textOverlap } from './tokenize.js';
|
|
9
9
|
import { isContentWorthStoring } from './audit.js';
|
|
10
10
|
import { redactSecretsStrict } from './secret-detect.js';
|
|
11
|
+
import { log } from './log.js';
|
|
11
12
|
/** A memory of a failed command, "Command '<cmd>' failed: <truncated stderr>"; no store is in reach, so `hippo watch` re-derives its half-life from the store's config. */
|
|
12
13
|
export function captureError(exitCode, stderr, command, tenantId) {
|
|
13
14
|
// Truncate to first 500 chars to avoid storing megabytes of build logs
|
|
@@ -154,7 +155,8 @@ export function isGitRepo(cwd) {
|
|
|
154
155
|
});
|
|
155
156
|
return raw.trim() === 'true';
|
|
156
157
|
}
|
|
157
|
-
catch {
|
|
158
|
+
catch (err) {
|
|
159
|
+
log.debug(`autolearn: not a git repo: ${err instanceof Error ? err.message : String(err)}`);
|
|
158
160
|
return false;
|
|
159
161
|
}
|
|
160
162
|
}
|
|
@@ -169,7 +171,8 @@ export function fetchGitLog(cwd, days) {
|
|
|
169
171
|
], { encoding: 'utf8', cwd, timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true });
|
|
170
172
|
return raw;
|
|
171
173
|
}
|
|
172
|
-
catch {
|
|
174
|
+
catch (err) {
|
|
175
|
+
log.debug(`autolearn: git log unavailable: ${err instanceof Error ? err.message : String(err)}`);
|
|
173
176
|
return '';
|
|
174
177
|
}
|
|
175
178
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type SessionTurn } from './transcript.js';
|
|
2
|
+
export interface CaptureOptions {
|
|
3
|
+
source: 'stdin' | 'file' | 'last-session';
|
|
4
|
+
filePath?: string;
|
|
5
|
+
/** Explicit transcript path for `--last-session`. Without one, `stdinText`
|
|
6
|
+
* is used, then auto-discovery under `~/.claude/projects/` on a manual run. */
|
|
7
|
+
transcriptPath?: string;
|
|
8
|
+
/** Read from stdin by the caller (cli.ts), which owns the bounded wait.
|
|
9
|
+
* `stdinTimedOut` marks an empty read "unknown", not "no payload". */
|
|
10
|
+
stdinText?: string;
|
|
11
|
+
stdinTimedOut?: boolean;
|
|
12
|
+
sessionTurns?: readonly SessionTurn[];
|
|
13
|
+
/**
|
|
14
|
+
* Tee stdout/stderr to this log file while capture runs. Mirrors the
|
|
15
|
+
* pattern used by `hippo sleep --log-file` so the SessionEnd hook output
|
|
16
|
+
* (invisible during TUI teardown) can be surfaced via `hippo last-sleep`
|
|
17
|
+
* on the next session start. Appends rather than truncates — `hippo sleep`
|
|
18
|
+
* writes the same file first in the SessionEnd sequence.
|
|
19
|
+
*/
|
|
20
|
+
logFile?: string;
|
|
21
|
+
dryRun: boolean;
|
|
22
|
+
global: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* L9: tenant scope for the dedup read in `cmdCaptureCore`. When provided
|
|
25
|
+
* AND `global` is false, the dedup check only considers this tenant's
|
|
26
|
+
* existing memories. Undefined preserves pre-1.12.1 host-wide dedup
|
|
27
|
+
* behaviour. Ignored when `global: true` (global captures are host-wide).
|
|
28
|
+
*/
|
|
29
|
+
tenantId?: string;
|
|
30
|
+
originProject?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function cmdCapture(hippoRoot: string, options: CaptureOptions): void;
|
|
33
|
+
//# sourceMappingURL=command.d.ts.map
|