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
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { MemoryEntry } from '../memory.js';
|
|
2
|
+
/**
|
|
3
|
+
* Load summaries flagged dirty for the given tenant. Sorted by latest_at
|
|
4
|
+
* DESC (NULLS LAST) so E3's rebuild cap (HIPPO_DAG_REBUILD_CAP, default 20)
|
|
5
|
+
* takes the most-recently-changed summaries first.
|
|
6
|
+
*
|
|
7
|
+
* Returns full MemoryEntry shape via MEMORY_SELECT_COLUMNS + rowToEntry
|
|
8
|
+
* (v28 fields are part of the standard read path).
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadDirtySummaries(hippoRoot: string, tenantId: string): MemoryEntry[];
|
|
11
|
+
/**
|
|
12
|
+
* Mark a summary as dirty. Idempotent (re-marking dirty is a no-op + no
|
|
13
|
+
* second audit row). Tenant-scoped to prevent cross-tenant writes via
|
|
14
|
+
* parent-lookup. Called by E2 from invalidation.ts / writeEntry /
|
|
15
|
+
* forgetMemory / archiveRawMemory whenever a child is invalidated,
|
|
16
|
+
* superseded, forgotten, or archived.
|
|
17
|
+
*
|
|
18
|
+
* Quietly no-ops if the target row doesn't exist or isn't a level-2
|
|
19
|
+
* summary (E5 will widen the dag_level guard to IN (2, 3) when level-3
|
|
20
|
+
* build path lands). Emits a 'summary_marked_dirty' audit row on actual
|
|
21
|
+
* state transitions (0 -> 1) via the audit() helper, which try/catches
|
|
22
|
+
* for missing audit_log (the v27 self-heal scenario).
|
|
23
|
+
*/
|
|
24
|
+
export declare function markSummaryDirty(hippoRoot: string, summaryId: string, tenantId: string, actor?: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* v0.30 / E5 — host-wide loader for L2 topic summaries without an L3 parent.
|
|
27
|
+
* Used by consolidate phase 1.9 (buildEntityProfiles) to cluster L2s into
|
|
28
|
+
* L3 entity profiles. Mirrors loadAllDirtySummaries pattern (E3): SQL-level
|
|
29
|
+
* filter is cheaper than reusing in-memory `survivors` (which doesn't
|
|
30
|
+
* contain L2s freshly created by phase 1.7 buildDag).
|
|
31
|
+
*
|
|
32
|
+
* Returns entries with tenantId attached so per-cluster writes stay
|
|
33
|
+
* tenant-scoped via summary.tenantId.
|
|
34
|
+
*/
|
|
35
|
+
export declare function loadAllL2Summaries(hippoRoot: string): MemoryEntry[];
|
|
36
|
+
/**
|
|
37
|
+
* v0.30 / E3 — host-wide variant of loadDirtySummaries. Iterates all tenants
|
|
38
|
+
* in one query so consolidate.ts (host-wide per L106-109) does not need a
|
|
39
|
+
* per-tenant loop. Each returned MemoryEntry carries its own tenantId (via
|
|
40
|
+
* rowToEntry), so per-summary children + rebuild UPDATE stay tenant-scoped.
|
|
41
|
+
*
|
|
42
|
+
* Sort: latest_at DESC NULLS LAST, id ASC — same as per-tenant variant so
|
|
43
|
+
* HIPPO_DAG_REBUILD_CAP takes most-recently-changed summaries first.
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadAllDirtySummaries(hippoRoot: string): MemoryEntry[];
|
|
46
|
+
/**
|
|
47
|
+
* v0.30 / E3 — load live children of a DAG summary. Used by
|
|
48
|
+
* rebuildDirtySummaries to regenerate content from the CURRENT child set
|
|
49
|
+
* (not the children at create-time). Skips archived. Tenant-scoped
|
|
50
|
+
* (defence in depth — dag_parent_id is unique-ish but tenant guard is
|
|
51
|
+
* cheap). created column is TEXT NOT NULL since db.ts schema v1.
|
|
52
|
+
*/
|
|
53
|
+
export declare function loadChildrenOfSummary(hippoRoot: string, summaryId: string, tenantId: string): MemoryEntry[];
|
|
54
|
+
/**
|
|
55
|
+
* v0.30 / E3 — patch applied by applyRebuildResult. Two-branch shape
|
|
56
|
+
* (bumpRebuildCount false for zero-child case, true for normal rebuild).
|
|
57
|
+
*/
|
|
58
|
+
export interface RebuildPatch {
|
|
59
|
+
content: string;
|
|
60
|
+
descendant_count: number;
|
|
61
|
+
earliest_at: string | null;
|
|
62
|
+
latest_at: string | null;
|
|
63
|
+
bumpRebuildCount: boolean;
|
|
64
|
+
zeroChildren: boolean;
|
|
65
|
+
actor: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* v0.30 / E3 — apply a rebuild result to a dirty summary. Atomic: one
|
|
69
|
+
* prepared UPDATE statement plus syncFtsRow inside one SAVEPOINT.
|
|
70
|
+
* WHERE includes `AND summary_dirty = 1` so concurrent sleep's race-loser
|
|
71
|
+
* becomes a no-op (no rebuild_count bump, no audit row).
|
|
72
|
+
*
|
|
73
|
+
* Returns `{ changed, refused }`. `changed` is true when this call's UPDATE
|
|
74
|
+
* (content or metadata-only) affected a row; false on race-loss / unknown id
|
|
75
|
+
* / archived / wrong dag_level. `refused` is true only when a tombstone hit
|
|
76
|
+
* suppressed the content write AND the metadata UPDATE still landed — see
|
|
77
|
+
* the return-semantics comment below for the full contract.
|
|
78
|
+
*/
|
|
79
|
+
export declare function applyRebuildResult(hippoRoot: string, summary: MemoryEntry, patch: RebuildPatch): {
|
|
80
|
+
changed: boolean;
|
|
81
|
+
refused: boolean;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* v0.30 / E3 — clear summary_dirty on a freshly-built summary. Called by
|
|
85
|
+
* buildDag immediately after the child-link loop finishes. Without this,
|
|
86
|
+
* each member's writeEntry call fires markSummaryDirtyInTx on the just-
|
|
87
|
+
* created parent (E2 hook at store.ts:1214), and the same sleep cycle's
|
|
88
|
+
* E3 rebuild phase would re-rebuild every new summary (2x LLM cost).
|
|
89
|
+
*
|
|
90
|
+
* Idempotent: no-op + no audit if summary isn't dirty. Audit
|
|
91
|
+
* source='buildDag-clean' distinguishes from E3-rebuild source.
|
|
92
|
+
*/
|
|
93
|
+
export declare function clearSummaryDirtyAfterBuild(hippoRoot: string, summaryId: string, tenantId: string, actor?: string, source?: string): void;
|
|
94
|
+
//# sourceMappingURL=summaries.d.ts.map
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { closeHippoDb } from '../db.js';
|
|
2
|
+
import { assertTenantId } from '../tenant.js';
|
|
3
|
+
import { findRejectedValue, rejectionDigest } from '../rejection.js';
|
|
4
|
+
import { log } from '../log.js';
|
|
5
|
+
import { MEMORY_SELECT_COLUMNS, rowToEntry } from './rows.js';
|
|
6
|
+
import { audit } from './audit-event.js';
|
|
7
|
+
import { syncFtsRow } from './entry-row.js';
|
|
8
|
+
import { openStore } from './open.js';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// v0.30 / E1 of DAG live-coupling — dirty-flag helpers for the existing
|
|
11
|
+
// DAG layer's level-2 summaries.
|
|
12
|
+
//
|
|
13
|
+
// Used by E2 (child-write propagation in invalidation.ts / writeEntry /
|
|
14
|
+
// forgetMemory / archiveRawMemory) to mark a summary dirty when one of its
|
|
15
|
+
// children changes, and by E3's sleep-cycle rebuildDirtySummaries phase to
|
|
16
|
+
// enumerate candidates without scanning every memory row.
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/**
|
|
19
|
+
* Load summaries flagged dirty for the given tenant. Sorted by latest_at
|
|
20
|
+
* DESC (NULLS LAST) so E3's rebuild cap (HIPPO_DAG_REBUILD_CAP, default 20)
|
|
21
|
+
* takes the most-recently-changed summaries first.
|
|
22
|
+
*
|
|
23
|
+
* Returns full MemoryEntry shape via MEMORY_SELECT_COLUMNS + rowToEntry
|
|
24
|
+
* (v28 fields are part of the standard read path).
|
|
25
|
+
*/
|
|
26
|
+
export function loadDirtySummaries(hippoRoot, tenantId) {
|
|
27
|
+
assertTenantId('loadDirtySummaries', tenantId);
|
|
28
|
+
const db = openStore(hippoRoot);
|
|
29
|
+
try {
|
|
30
|
+
// SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching
|
|
31
|
+
// MemoryRow's field set.
|
|
32
|
+
const rows = db.prepare(`
|
|
33
|
+
SELECT ${MEMORY_SELECT_COLUMNS}
|
|
34
|
+
FROM memories
|
|
35
|
+
WHERE summary_dirty = 1
|
|
36
|
+
AND tenant_id = ?
|
|
37
|
+
AND kind != 'archived'
|
|
38
|
+
ORDER BY latest_at DESC NULLS LAST, id ASC
|
|
39
|
+
`).all(tenantId);
|
|
40
|
+
return rows.map(rowToEntry);
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
closeHippoDb(db);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Mark a summary as dirty. Idempotent (re-marking dirty is a no-op + no
|
|
48
|
+
* second audit row). Tenant-scoped to prevent cross-tenant writes via
|
|
49
|
+
* parent-lookup. Called by E2 from invalidation.ts / writeEntry /
|
|
50
|
+
* forgetMemory / archiveRawMemory whenever a child is invalidated,
|
|
51
|
+
* superseded, forgotten, or archived.
|
|
52
|
+
*
|
|
53
|
+
* Quietly no-ops if the target row doesn't exist or isn't a level-2
|
|
54
|
+
* summary (E5 will widen the dag_level guard to IN (2, 3) when level-3
|
|
55
|
+
* build path lands). Emits a 'summary_marked_dirty' audit row on actual
|
|
56
|
+
* state transitions (0 -> 1) via the audit() helper, which try/catches
|
|
57
|
+
* for missing audit_log (the v27 self-heal scenario).
|
|
58
|
+
*/
|
|
59
|
+
export function markSummaryDirty(hippoRoot, summaryId, tenantId, actor = 'cli') {
|
|
60
|
+
assertTenantId('markSummaryDirty', tenantId);
|
|
61
|
+
const db = openStore(hippoRoot);
|
|
62
|
+
try {
|
|
63
|
+
// v0.30 / E5: widened dag_level=2 -> IN (2, 3). RETURNING dag_level reads
|
|
64
|
+
// actual level in same round trip.
|
|
65
|
+
// SAFETY: result's shape matches the single `dag_level` column returned
|
|
66
|
+
// above.
|
|
67
|
+
const result = db.prepare(`
|
|
68
|
+
UPDATE memories
|
|
69
|
+
SET summary_dirty = 1
|
|
70
|
+
WHERE id = ?
|
|
71
|
+
AND tenant_id = ?
|
|
72
|
+
AND dag_level IN (2, 3)
|
|
73
|
+
AND summary_dirty = 0
|
|
74
|
+
AND kind != 'archived'
|
|
75
|
+
RETURNING dag_level
|
|
76
|
+
`).get(summaryId, tenantId);
|
|
77
|
+
if (result) {
|
|
78
|
+
// audit() wraps appendAuditEvent in try/catch (v27 heal scenario).
|
|
79
|
+
// metadata.source=E1 leaves a breadcrumb so E2-E5 debugging can
|
|
80
|
+
// distinguish dirty-marks across the arc's wiring layers.
|
|
81
|
+
audit(db, 'summary_marked_dirty', summaryId, { dag_level: result.dag_level, source: 'E1' }, actor, tenantId);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
closeHippoDb(db);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// v0.30 / E3 of DAG live-coupling — sleep-cycle rebuild surface.
|
|
90
|
+
//
|
|
91
|
+
// loadAllDirtySummaries / loadChildrenOfSummary / applyRebuildResult /
|
|
92
|
+
// clearSummaryDirtyAfterBuild live HERE (not in dag.ts) because they need
|
|
93
|
+
// module-private MEMORY_SELECT_COLUMNS, MemoryRow, rowToEntry, audit,
|
|
94
|
+
// syncFtsRow, assertTenantId. dag.ts owns only the thin orchestrator
|
|
95
|
+
// rebuildDirtySummaries() that calls into these.
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
/**
|
|
98
|
+
* v0.30 / E5 — host-wide loader for L2 topic summaries without an L3 parent.
|
|
99
|
+
* Used by consolidate phase 1.9 (buildEntityProfiles) to cluster L2s into
|
|
100
|
+
* L3 entity profiles. Mirrors loadAllDirtySummaries pattern (E3): SQL-level
|
|
101
|
+
* filter is cheaper than reusing in-memory `survivors` (which doesn't
|
|
102
|
+
* contain L2s freshly created by phase 1.7 buildDag).
|
|
103
|
+
*
|
|
104
|
+
* Returns entries with tenantId attached so per-cluster writes stay
|
|
105
|
+
* tenant-scoped via summary.tenantId.
|
|
106
|
+
*/
|
|
107
|
+
export function loadAllL2Summaries(hippoRoot) {
|
|
108
|
+
const db = openStore(hippoRoot);
|
|
109
|
+
try {
|
|
110
|
+
// SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching
|
|
111
|
+
// MemoryRow's field set.
|
|
112
|
+
const rows = db.prepare(`
|
|
113
|
+
SELECT ${MEMORY_SELECT_COLUMNS}
|
|
114
|
+
FROM memories
|
|
115
|
+
WHERE dag_level = 2
|
|
116
|
+
AND dag_parent_id IS NULL
|
|
117
|
+
AND kind != 'archived'
|
|
118
|
+
AND superseded_by IS NULL
|
|
119
|
+
ORDER BY created ASC, id ASC
|
|
120
|
+
`).all();
|
|
121
|
+
return rows.map(rowToEntry);
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
closeHippoDb(db);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* v0.30 / E3 — host-wide variant of loadDirtySummaries. Iterates all tenants
|
|
129
|
+
* in one query so consolidate.ts (host-wide per L106-109) does not need a
|
|
130
|
+
* per-tenant loop. Each returned MemoryEntry carries its own tenantId (via
|
|
131
|
+
* rowToEntry), so per-summary children + rebuild UPDATE stay tenant-scoped.
|
|
132
|
+
*
|
|
133
|
+
* Sort: latest_at DESC NULLS LAST, id ASC — same as per-tenant variant so
|
|
134
|
+
* HIPPO_DAG_REBUILD_CAP takes most-recently-changed summaries first.
|
|
135
|
+
*/
|
|
136
|
+
export function loadAllDirtySummaries(hippoRoot) {
|
|
137
|
+
const db = openStore(hippoRoot);
|
|
138
|
+
try {
|
|
139
|
+
// SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching
|
|
140
|
+
// MemoryRow's field set.
|
|
141
|
+
const rows = db.prepare(`
|
|
142
|
+
SELECT ${MEMORY_SELECT_COLUMNS}
|
|
143
|
+
FROM memories
|
|
144
|
+
WHERE summary_dirty = 1
|
|
145
|
+
AND kind != 'archived'
|
|
146
|
+
ORDER BY latest_at DESC NULLS LAST, id ASC
|
|
147
|
+
`).all();
|
|
148
|
+
return rows.map(rowToEntry);
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
closeHippoDb(db);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* v0.30 / E3 — load live children of a DAG summary. Used by
|
|
156
|
+
* rebuildDirtySummaries to regenerate content from the CURRENT child set
|
|
157
|
+
* (not the children at create-time). Skips archived. Tenant-scoped
|
|
158
|
+
* (defence in depth — dag_parent_id is unique-ish but tenant guard is
|
|
159
|
+
* cheap). created column is TEXT NOT NULL since db.ts schema v1.
|
|
160
|
+
*/
|
|
161
|
+
export function loadChildrenOfSummary(hippoRoot, summaryId, tenantId) {
|
|
162
|
+
assertTenantId('loadChildrenOfSummary', tenantId);
|
|
163
|
+
const db = openStore(hippoRoot);
|
|
164
|
+
try {
|
|
165
|
+
// SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching
|
|
166
|
+
// MemoryRow's field set.
|
|
167
|
+
const rows = db.prepare(`
|
|
168
|
+
SELECT ${MEMORY_SELECT_COLUMNS}
|
|
169
|
+
FROM memories
|
|
170
|
+
WHERE dag_parent_id = ?
|
|
171
|
+
AND tenant_id = ?
|
|
172
|
+
AND kind != 'archived'
|
|
173
|
+
AND superseded_by IS NULL
|
|
174
|
+
ORDER BY created ASC
|
|
175
|
+
`).all(summaryId, tenantId);
|
|
176
|
+
return rows.map(rowToEntry);
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
closeHippoDb(db);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* v0.30 / E3 — apply a rebuild result to a dirty summary. Atomic: one
|
|
184
|
+
* prepared UPDATE statement plus syncFtsRow inside one SAVEPOINT.
|
|
185
|
+
* WHERE includes `AND summary_dirty = 1` so concurrent sleep's race-loser
|
|
186
|
+
* becomes a no-op (no rebuild_count bump, no audit row).
|
|
187
|
+
*
|
|
188
|
+
* Returns `{ changed, refused }`. `changed` is true when this call's UPDATE
|
|
189
|
+
* (content or metadata-only) affected a row; false on race-loss / unknown id
|
|
190
|
+
* / archived / wrong dag_level. `refused` is true only when a tombstone hit
|
|
191
|
+
* suppressed the content write AND the metadata UPDATE still landed — see
|
|
192
|
+
* the return-semantics comment below for the full contract.
|
|
193
|
+
*/
|
|
194
|
+
export function applyRebuildResult(hippoRoot, summary, patch) {
|
|
195
|
+
assertTenantId('applyRebuildResult', summary.tenantId);
|
|
196
|
+
const db = openStore(hippoRoot);
|
|
197
|
+
try {
|
|
198
|
+
db.exec('SAVEPOINT rebuild_summary');
|
|
199
|
+
try {
|
|
200
|
+
const outcome = applyRebuildInSavepoint(db, summary, patch);
|
|
201
|
+
db.exec('RELEASE SAVEPOINT rebuild_summary');
|
|
202
|
+
return outcome;
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
try {
|
|
206
|
+
db.exec('ROLLBACK TO SAVEPOINT rebuild_summary');
|
|
207
|
+
db.exec('RELEASE SAVEPOINT rebuild_summary');
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// Ignore rollback failures — throw below is what matters.
|
|
211
|
+
}
|
|
212
|
+
throw e;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
closeHippoDb(db);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// ONE prepared UPDATE per branch. Test #8 inspects the SQL string.
|
|
220
|
+
// v0.30 / E5: widened dag_level=2 -> IN (2, 3) on both branches.
|
|
221
|
+
const REBUILD_CONTENT_SQL = `UPDATE memories
|
|
222
|
+
SET content = ?,
|
|
223
|
+
descendant_count = ?,
|
|
224
|
+
earliest_at = ?,
|
|
225
|
+
latest_at = ?,
|
|
226
|
+
last_rebuilt_at = ?,
|
|
227
|
+
rebuild_count = COALESCE(rebuild_count, 0) + 1,
|
|
228
|
+
summary_dirty = 0
|
|
229
|
+
WHERE id = ?
|
|
230
|
+
AND tenant_id = ?
|
|
231
|
+
AND dag_level IN (2, 3)
|
|
232
|
+
AND summary_dirty = 1
|
|
233
|
+
AND kind != 'archived'`;
|
|
234
|
+
const REBUILD_METADATA_SQL = `UPDATE memories
|
|
235
|
+
SET descendant_count = ?,
|
|
236
|
+
earliest_at = ?,
|
|
237
|
+
latest_at = ?,
|
|
238
|
+
summary_dirty = 0
|
|
239
|
+
WHERE id = ?
|
|
240
|
+
AND tenant_id = ?
|
|
241
|
+
AND dag_level IN (2, 3)
|
|
242
|
+
AND summary_dirty = 1
|
|
243
|
+
AND kind != 'archived'`;
|
|
244
|
+
function applyRebuildInSavepoint(db, summary, patch) {
|
|
245
|
+
const nowIso = new Date().toISOString();
|
|
246
|
+
// AT1 P1a fix (docs/plans/2026-08-15-at1-rejected-value-tombstone.md):
|
|
247
|
+
// applyRebuildResult's bumpRebuildCount branch wrote patch.content via
|
|
248
|
+
// a direct UPDATE, bypassing the rejection guard entirely (the guard
|
|
249
|
+
// lives in upsertEntryRow's INSERT path, which this function never
|
|
250
|
+
// calls). A rebuild that regenerates byte-identical content to an
|
|
251
|
+
// already-rejected value (e.g. deterministic summarization of an
|
|
252
|
+
// unchanged child set) would silently re-assert it every sleep cycle.
|
|
253
|
+
// Check BEFORE choosing which UPDATE to run — only the
|
|
254
|
+
// bumpRebuildCount branch ever writes content, so a miss or a
|
|
255
|
+
// zero-child call is a no-op here (one indexed point query, guarded
|
|
256
|
+
// path only).
|
|
257
|
+
const tombstone = patch.bumpRebuildCount
|
|
258
|
+
? findRejectedValue(db, summary.tenantId, rejectionDigest(patch.content))
|
|
259
|
+
: null;
|
|
260
|
+
// On a hit: do NOT write the new content. Fall through to the SAME
|
|
261
|
+
// metadata-only behavior the zero-child branch already has —
|
|
262
|
+
// descendant_count/earliest_at/latest_at update + summary_dirty
|
|
263
|
+
// cleared, no content write, no rebuild_count bump. Clearing dirty
|
|
264
|
+
// (rather than leaving it set) is deliberate: leaving it dirty would
|
|
265
|
+
// make every following sleep cycle re-attempt and re-refuse the
|
|
266
|
+
// identical rebuild forever (the DAG-loop this fix closes).
|
|
267
|
+
const applyContentWrite = patch.bumpRebuildCount && !tombstone;
|
|
268
|
+
const result = applyContentWrite
|
|
269
|
+
? db.prepare(REBUILD_CONTENT_SQL).run(patch.content, patch.descendant_count, patch.earliest_at, patch.latest_at, nowIso, summary.id, summary.tenantId)
|
|
270
|
+
: db.prepare(REBUILD_METADATA_SQL).run(patch.descendant_count, patch.earliest_at, patch.latest_at, summary.id, summary.tenantId);
|
|
271
|
+
// Return-value semantics (v0.30/T4 split): `changed` reflects whether
|
|
272
|
+
// THIS call's UPDATE (content or metadata-only) affected a row — NOT
|
|
273
|
+
// whether patch.content specifically landed. On a refusal, metadata
|
|
274
|
+
// still applies, so changed=true even though content did not change.
|
|
275
|
+
// This preserves the pre-T4 no-infinite-retry choice: the caller
|
|
276
|
+
// (dag.ts rebuildDirtySummaries) treats changed=false as "race lost,
|
|
277
|
+
// silently retry next cycle" — returning false on a refusal would
|
|
278
|
+
// retry the same doomed LLM rebuild forever, so changed=true settles
|
|
279
|
+
// this cycle (dirty cleared) regardless of refusal.
|
|
280
|
+
// `refused` is the T4 addition: true only when a tombstone hit AND
|
|
281
|
+
// the metadata UPDATE landed (changed=true) — a refusal that loses
|
|
282
|
+
// the race to a concurrent writer reports refused=false too, since
|
|
283
|
+
// nothing from this call took effect. Before T4, a refusal also
|
|
284
|
+
// counted toward the caller's `rebuilt` stat because `changed` alone
|
|
285
|
+
// could not distinguish it; the caller now increments `refused`
|
|
286
|
+
// instead of `rebuilt` when this is true, so the stat reflects what
|
|
287
|
+
// happened without changing dirty-clearing or retry behavior.
|
|
288
|
+
const changed = (result.changes ?? 0) > 0;
|
|
289
|
+
const refused = Boolean(tombstone) && changed;
|
|
290
|
+
if (tombstone && changed)
|
|
291
|
+
auditRefusedRebuild(db, summary, patch, tombstone);
|
|
292
|
+
if (changed)
|
|
293
|
+
syncRebuiltSummary(db, summary, patch, applyContentWrite, nowIso);
|
|
294
|
+
return { changed, refused };
|
|
295
|
+
}
|
|
296
|
+
/** Audit and log a rebuild whose content matched a rejected value; metadata still landed. */
|
|
297
|
+
function auditRefusedRebuild(db, summary, patch, tombstone) {
|
|
298
|
+
// refused === true here (same condition, narrowed for the tombstone.*
|
|
299
|
+
// access below). Best-effort refusal audit, written INLINE inside
|
|
300
|
+
// this still-open SAVEPOINT — nothing here rolls back on a refusal
|
|
301
|
+
// (the metadata UPDATE above already committed to this savepoint), so the
|
|
302
|
+
// post-rollback auditRejectionRefusal helper (writeEntry/supersede's
|
|
303
|
+
// tool) is the wrong one here; a direct audit() call is correct and
|
|
304
|
+
// commits with the rest of this savepoint.
|
|
305
|
+
audit(db, 'reject_refusal', summary.id, { digest: tombstone.digest, reason: tombstone.reason }, patch.actor, summary.tenantId);
|
|
306
|
+
log.warn(`applyRebuildResult: refused rebuild content for ${summary.id} — matches a rejected value ` +
|
|
307
|
+
`(digest ${tombstone.digest.slice(0, 12)}...); metadata updated, content unchanged`);
|
|
308
|
+
}
|
|
309
|
+
function syncRebuiltSummary(db, summary, patch, applyContentWrite, nowIso) {
|
|
310
|
+
// FTS sync — bare UPDATE on memories does NOT update memories_fts.
|
|
311
|
+
// R1 HIGH must-fix from plan-eng-r1. Construct the patched entry in
|
|
312
|
+
// memory and reuse the existing syncFtsRow helper (delete-then-insert).
|
|
313
|
+
// earliest_at/latest_at preserve null semantics (R2 must-fix).
|
|
314
|
+
// AT1: content stays summary.content (unchanged) when the write was
|
|
315
|
+
// refused — applyContentWrite is false, so patch.content was never
|
|
316
|
+
// written to the row FTS must mirror.
|
|
317
|
+
const patchedEntry = {
|
|
318
|
+
...summary,
|
|
319
|
+
content: applyContentWrite ? patch.content : summary.content,
|
|
320
|
+
descendant_count: patch.descendant_count,
|
|
321
|
+
earliest_at: patch.earliest_at,
|
|
322
|
+
latest_at: patch.latest_at,
|
|
323
|
+
summary_dirty: 0,
|
|
324
|
+
last_rebuilt_at: applyContentWrite ? nowIso : summary.last_rebuilt_at,
|
|
325
|
+
rebuild_count: applyContentWrite
|
|
326
|
+
? (summary.rebuild_count ?? 0) + 1
|
|
327
|
+
: summary.rebuild_count,
|
|
328
|
+
};
|
|
329
|
+
syncFtsRow(db, patchedEntry);
|
|
330
|
+
audit(db, 'summary_rebuilt', summary.id, {
|
|
331
|
+
// v0.30 / E5: read actual level from the summary in scope
|
|
332
|
+
// (NOT hardcoded 2). L2 -> 2, L3 -> 3.
|
|
333
|
+
dag_level: summary.dag_level,
|
|
334
|
+
source: 'E3-rebuild',
|
|
335
|
+
zero_children: patch.zeroChildren,
|
|
336
|
+
descendant_count: patch.descendant_count,
|
|
337
|
+
}, patch.actor, summary.tenantId);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* v0.30 / E3 — clear summary_dirty on a freshly-built summary. Called by
|
|
341
|
+
* buildDag immediately after the child-link loop finishes. Without this,
|
|
342
|
+
* each member's writeEntry call fires markSummaryDirtyInTx on the just-
|
|
343
|
+
* created parent (E2 hook at store.ts:1214), and the same sleep cycle's
|
|
344
|
+
* E3 rebuild phase would re-rebuild every new summary (2x LLM cost).
|
|
345
|
+
*
|
|
346
|
+
* Idempotent: no-op + no audit if summary isn't dirty. Audit
|
|
347
|
+
* source='buildDag-clean' distinguishes from E3-rebuild source.
|
|
348
|
+
*/
|
|
349
|
+
export function clearSummaryDirtyAfterBuild(hippoRoot, summaryId, tenantId, actor = 'cli', source = 'buildDag-clean') {
|
|
350
|
+
assertTenantId('clearSummaryDirtyAfterBuild', tenantId);
|
|
351
|
+
const db = openStore(hippoRoot);
|
|
352
|
+
try {
|
|
353
|
+
// v0.30 / E5: widened dag_level=2 -> IN (2, 3). RETURNING dag_level reads
|
|
354
|
+
// actual level so audit metadata stays accurate without an extra SELECT.
|
|
355
|
+
// SAFETY: result's shape matches the single `dag_level` column returned
|
|
356
|
+
// below.
|
|
357
|
+
const result = db.prepare(`
|
|
358
|
+
UPDATE memories
|
|
359
|
+
SET summary_dirty = 0
|
|
360
|
+
WHERE id = ?
|
|
361
|
+
AND tenant_id = ?
|
|
362
|
+
AND dag_level IN (2, 3)
|
|
363
|
+
AND summary_dirty = 1
|
|
364
|
+
AND kind != 'archived'
|
|
365
|
+
RETURNING dag_level
|
|
366
|
+
`).get(summaryId, tenantId);
|
|
367
|
+
if (result) {
|
|
368
|
+
// v0.30 / E5: source param distinguishes buildDag-clean (L2) from
|
|
369
|
+
// buildEntityProfiles-clean (L3) and any future build path.
|
|
370
|
+
audit(db, 'summary_marked_clean', summaryId, { dag_level: result.dag_level, source }, actor, tenantId);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
finally {
|
|
374
|
+
closeHippoDb(db);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=summaries.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DatabaseSyncLike } from '../db.js';
|
|
2
|
+
/** The api_keys fields a tenant, revocation or rank check reads. */
|
|
3
|
+
export interface ApiKeyOwner {
|
|
4
|
+
tenantId: string;
|
|
5
|
+
revokedAt: string | null;
|
|
6
|
+
role: string;
|
|
7
|
+
}
|
|
8
|
+
/** The owner row of `keyId`, or undefined when no such key exists. */
|
|
9
|
+
export declare function selectApiKeyOwner(db: DatabaseSyncLike, keyId: string): ApiKeyOwner | undefined;
|
|
10
|
+
/** The tenant that owns memory `id`, or undefined when no such memory exists. */
|
|
11
|
+
export declare function selectMemoryTenant(db: DatabaseSyncLike, id: string): string | undefined;
|
|
12
|
+
//# sourceMappingURL=tenant-lookup.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Owner lookups by id: the tenant checks in src/api and the CLI's key-tenant lookup share these queries.
|
|
2
|
+
/** The owner row of `keyId`, or undefined when no such key exists. */
|
|
3
|
+
export function selectApiKeyOwner(db, keyId) {
|
|
4
|
+
// SAFETY: row's shape matches the three columns named in the SELECT.
|
|
5
|
+
const row = db
|
|
6
|
+
.prepare(`SELECT tenant_id, revoked_at, role FROM api_keys WHERE key_id = ?`)
|
|
7
|
+
.get(keyId);
|
|
8
|
+
return row && { tenantId: row.tenant_id, revokedAt: row.revoked_at, role: row.role };
|
|
9
|
+
}
|
|
10
|
+
/** The tenant that owns memory `id`, or undefined when no such memory exists. */
|
|
11
|
+
export function selectMemoryTenant(db, id) {
|
|
12
|
+
// SAFETY: row's shape matches the single tenant_id column named in the SELECT.
|
|
13
|
+
const row = db.prepare(`SELECT tenant_id FROM memories WHERE id = ?`).get(id);
|
|
14
|
+
return row?.tenant_id;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=tenant-lookup.js.map
|
package/dist/store-cards.js
CHANGED
|
@@ -3,7 +3,8 @@ import { closeHippoDb } from './db.js';
|
|
|
3
3
|
import { rowToSessionHandoff, isHandoffOutcome } from './handoff.js';
|
|
4
4
|
import { CARD_TRANSITIONS, CARD_LEASE_MS } from './card.js';
|
|
5
5
|
import { assertTenantId } from './tenant.js';
|
|
6
|
-
import { openStore
|
|
6
|
+
import { openStore } from './store/open.js';
|
|
7
|
+
import { HANDOFF_COLUMNS } from './store/handoffs.js';
|
|
7
8
|
const CARD_COLUMNS = 'id, title, status, assignee_runtime, repo, contract, budget, lease_until, heartbeat_at, created_at, updated_at, tenant_id, scope';
|
|
8
9
|
function rowToCard(row) {
|
|
9
10
|
return {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DatabaseSyncLike } from './db.js';
|
|
2
|
+
/** Runs in the caller's transaction so the mark commits or rolls back with the child change; only a 0 to 1 flip is audited. */
|
|
3
|
+
export declare function markSummaryDirtyInTx(db: DatabaseSyncLike, summaryId: string, tenantId: string, actor: string): void;
|
|
4
|
+
//# sourceMappingURL=summary-dirty.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Leaf module so store.ts and raw-archive.ts can both mark a parent summary dirty without importing each other.
|
|
2
|
+
import { appendAuditEvent, reportAuditWriteFailure } from './audit.js';
|
|
3
|
+
/** Runs in the caller's transaction so the mark commits or rolls back with the child change; only a 0 to 1 flip is audited. */
|
|
4
|
+
export function markSummaryDirtyInTx(db, summaryId, tenantId, actor) {
|
|
5
|
+
// SAFETY: result's shape matches the single `dag_level` column returned below.
|
|
6
|
+
const result = db.prepare(`
|
|
7
|
+
UPDATE memories
|
|
8
|
+
SET summary_dirty = 1
|
|
9
|
+
WHERE id = ?
|
|
10
|
+
AND tenant_id = ?
|
|
11
|
+
AND dag_level IN (2, 3)
|
|
12
|
+
AND summary_dirty = 0
|
|
13
|
+
AND kind != 'archived'
|
|
14
|
+
RETURNING dag_level
|
|
15
|
+
`).get(summaryId, tenantId);
|
|
16
|
+
if (!result)
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
appendAuditEvent(db, {
|
|
20
|
+
tenantId,
|
|
21
|
+
actor,
|
|
22
|
+
op: 'summary_marked_dirty',
|
|
23
|
+
targetId: summaryId,
|
|
24
|
+
metadata: { dag_level: result.dag_level, source: 'E2' },
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
// The mark has already succeeded; a broken audit table must not undo it.
|
|
29
|
+
reportAuditWriteFailure('summary_marked_dirty', String(error), summaryId);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=summary-dirty.js.map
|
package/dist/support-bundle.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/** `hippo support-bundle`: one redacted JSON snapshot for a support ticket. Read-only (SQLite may leave empty -wal and -shm files); never touches memory content. */
|
|
2
|
+
import { envByName, processEnv } from './env.js';
|
|
2
3
|
import * as fs from 'fs';
|
|
3
4
|
import * as os from 'os';
|
|
4
5
|
import * as path from 'path';
|
|
5
6
|
import { pathToFileURL } from 'url';
|
|
6
7
|
import { findHippoStoreDir, isGlobalStoreRoot, realpathOrResolve } from './project-identity.js';
|
|
7
8
|
import { getGlobalRoot } from './shared.js';
|
|
8
|
-
import { isInitialized } from './store.js';
|
|
9
|
+
import { isInitialized } from './store/open.js';
|
|
9
10
|
import { openHippoDbReadOnly, closeHippoDb, getSchemaVersion, getMeta, countTableRows } from './db.js';
|
|
10
11
|
import { runDoctor } from './doctor.js';
|
|
11
12
|
import { loadConfig } from './config.js';
|
|
@@ -118,12 +119,12 @@ function buildStores(opts) {
|
|
|
118
119
|
}
|
|
119
120
|
function listSetEnvNames() {
|
|
120
121
|
const names = new Set();
|
|
121
|
-
for (const key of Object.keys(
|
|
122
|
+
for (const key of Object.keys(processEnv())) {
|
|
122
123
|
if (key.startsWith('HIPPO_'))
|
|
123
124
|
names.add(key);
|
|
124
125
|
}
|
|
125
126
|
for (const key of OTHER_ENV_NAMES) {
|
|
126
|
-
if (
|
|
127
|
+
if (envByName(key) !== undefined)
|
|
127
128
|
names.add(key);
|
|
128
129
|
}
|
|
129
130
|
return [...names].sort();
|
package/dist/tenant.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { envTenant } from './env.js';
|
|
1
2
|
import { validateApiKey } from './auth.js';
|
|
2
3
|
export function resolveTenantId(opts) {
|
|
3
4
|
if (opts.apiKey) {
|
|
@@ -11,8 +12,7 @@ export function resolveTenantId(opts) {
|
|
|
11
12
|
// L1: empty / whitespace-only HIPPO_TENANT must fall through to 'default'.
|
|
12
13
|
// `??` only catches undefined, so HIPPO_TENANT="" leaked through as the
|
|
13
14
|
// literal empty string and broke every downstream tenant filter.
|
|
14
|
-
|
|
15
|
-
return t ? t : 'default';
|
|
15
|
+
return envTenant();
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* Defensive runtime guard for tenant id arguments.
|
package/dist/token-ledger.js
CHANGED
package/dist/tokenize.d.ts
CHANGED
package/dist/tokenize.js
CHANGED
|
@@ -5,4 +5,20 @@ export function tokenize(text) {
|
|
|
5
5
|
.split(/\s+/)
|
|
6
6
|
.filter((t) => t.length > 1);
|
|
7
7
|
}
|
|
8
|
+
/** Jaccard overlap of the two texts' token sets; two empty texts count as identical. */
|
|
9
|
+
export function textOverlap(a, b) {
|
|
10
|
+
const setA = new Set(tokenize(a));
|
|
11
|
+
const setB = new Set(tokenize(b));
|
|
12
|
+
if (setA.size === 0 && setB.size === 0)
|
|
13
|
+
return 1;
|
|
14
|
+
if (setA.size === 0 || setB.size === 0)
|
|
15
|
+
return 0;
|
|
16
|
+
let intersection = 0;
|
|
17
|
+
for (const t of setA) {
|
|
18
|
+
if (setB.has(t))
|
|
19
|
+
intersection++;
|
|
20
|
+
}
|
|
21
|
+
const union = setA.size + setB.size - intersection;
|
|
22
|
+
return intersection / union;
|
|
23
|
+
}
|
|
8
24
|
//# sourceMappingURL=tokenize.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Never read the whole transcript: PreCompact fires exactly when it's largest. */
|
|
2
|
+
export declare const PRE_COMPACT_TAIL_BYTES: number;
|
|
3
|
+
/** Cut to `maxChars` UTF-16 units, backing off one unit rather than leave half a surrogate pair in a stored field. */
|
|
4
|
+
export declare function truncateCodePointSafe(text: string, maxChars: number): string;
|
|
5
|
+
/** The last `capBytes` of a JSONL transcript, read at an offset and starting on a whole line so every line parses. */
|
|
6
|
+
export declare function readTranscriptTail(transcriptPath: string, capBytes?: number): string;
|
|
7
|
+
//# sourceMappingURL=transcript-tail.d.ts.map
|