hippo-memory 1.60.0 → 1.62.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 +29 -54
- package/dist/ablation.js +9 -27
- package/dist/agent-memories/apply.d.ts +1 -1
- package/dist/agent-memories/apply.js +4 -1
- package/dist/agent-memories/claude-code.d.ts +3 -1
- package/dist/agent-memories/claude-code.js +54 -10
- 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.d.ts +3 -3
- package/dist/agent-memories/sync.js +22 -9
- package/dist/agent-memories/types.d.ts +0 -2
- 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 +153 -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-select.d.ts +49 -0
- package/dist/api/context-select.js +344 -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 +378 -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 +126 -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 +192 -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 +499 -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 +256 -0
- package/dist/api/tokens.d.ts +26 -0
- package/dist/api/tokens.js +60 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/api/types.js +38 -0
- package/dist/api.d.ts +20 -1262
- package/dist/api.js +25 -2727
- package/dist/audit.d.ts +3 -0
- package/dist/audit.js +6 -3
- package/dist/auth.d.ts +45 -4
- package/dist/auth.js +125 -48
- package/dist/autolearn.js +2 -2
- package/dist/capture/command.d.ts +33 -0
- package/dist/capture/command.js +264 -0
- package/dist/capture/compact.d.ts +44 -0
- package/dist/capture/compact.js +354 -0
- package/dist/capture/extract.d.ts +21 -0
- package/dist/capture/extract.js +464 -0
- package/dist/capture/transcript.d.ts +40 -0
- package/dist/capture/transcript.js +193 -0
- package/dist/capture-error.js +2 -1
- package/dist/churn-git.js +4 -2
- package/dist/cli/audit.d.ts +3 -0
- package/dist/cli/audit.js +159 -0
- package/dist/cli/auth.d.ts +2 -0
- package/dist/cli/auth.js +171 -0
- package/dist/cli/briefs.d.ts +4 -0
- package/dist/cli/briefs.js +453 -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 +376 -0
- package/dist/cli/continuity.d.ts +6 -0
- package/dist/cli/continuity.js +457 -0
- package/dist/cli/curate.d.ts +19 -0
- package/dist/cli/curate.js +556 -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 +156 -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 +190 -0
- package/dist/cli/playbooks.d.ts +4 -0
- package/dist/cli/playbooks.js +573 -0
- package/dist/cli/projects.js +9 -6
- package/dist/cli/recall.d.ts +7 -0
- package/dist/cli/recall.js +582 -0
- package/dist/cli/remember.d.ts +5 -0
- package/dist/cli/remember.js +485 -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 +647 -0
- package/dist/cli/setup.d.ts +4 -0
- package/dist/cli/setup.js +397 -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 +409 -0
- package/dist/cli/transfer.d.ts +10 -0
- package/dist/cli/transfer.js +424 -0
- package/dist/cli/usage.d.ts +85 -0
- package/dist/cli/usage.js +741 -0
- package/dist/cli.d.ts +71 -120
- package/dist/cli.js +170 -8469
- package/dist/client.js +15 -8
- package/dist/compaction-record.d.ts +0 -2
- package/dist/compaction-record.js +7 -5
- package/dist/connectors/github/backfill.js +94 -87
- package/dist/connectors/github/cli-impl.js +4 -3
- package/dist/connectors/github/dlq.js +67 -54
- package/dist/connectors/github/ingest.js +34 -35
- package/dist/connectors/github/tenant-routing.js +3 -2
- package/dist/connectors/github/webhook.js +135 -216
- package/dist/connectors/slack/dlq.js +49 -61
- package/dist/connectors/slack/ingest.js +55 -48
- package/dist/connectors/slack/tenant-routing.js +4 -3
- package/dist/connectors/slack/webhook.js +72 -74
- package/dist/consolidate/conflicts.d.ts +10 -0
- package/dist/consolidate/conflicts.js +178 -0
- package/dist/consolidate/decay.d.ts +12 -0
- package/dist/consolidate/decay.js +145 -0
- package/dist/consolidate/llm-passes.d.ts +3 -0
- package/dist/consolidate/llm-passes.js +141 -0
- package/dist/consolidate/merge.d.ts +7 -0
- package/dist/consolidate/merge.js +251 -0
- package/dist/consolidate/physics-pass.d.ts +3 -0
- package/dist/consolidate/physics-pass.js +60 -0
- package/dist/consolidate/run.d.ts +69 -0
- package/dist/consolidate/run.js +76 -0
- package/dist/consolidate/sleep.d.ts +18 -0
- package/dist/consolidate/sleep.js +209 -0
- package/dist/consolidate/traces.d.ts +4 -0
- package/dist/consolidate/traces.js +178 -0
- package/dist/context-auto.js +7 -11
- package/dist/context-render.d.ts +1 -1
- package/dist/context-render.js +1 -1
- package/dist/customer-notes.d.ts +3 -0
- package/dist/customer-notes.js +83 -72
- package/dist/dag.js +225 -188
- package/dist/dashboard-actions.d.ts +20 -0
- package/dist/dashboard-actions.js +88 -0
- package/dist/dashboard-params.d.ts +45 -0
- package/dist/dashboard-params.js +127 -0
- package/dist/dashboard-queries.d.ts +15 -0
- package/dist/dashboard-queries.js +355 -0
- package/dist/dashboard-snapshot.d.ts +138 -0
- package/dist/dashboard-snapshot.js +308 -0
- package/dist/dashboard-types.d.ts +163 -0
- package/dist/dashboard-types.js +3 -0
- package/dist/dashboard.d.ts +6 -7
- package/dist/dashboard.js +228 -202
- package/dist/db/busy.d.ts +5 -0
- package/dist/db/busy.js +24 -0
- package/dist/db/continuity.d.ts +5 -0
- package/dist/db/continuity.js +145 -0
- package/dist/db/meta.d.ts +8 -0
- package/dist/db/meta.js +35 -0
- package/dist/db/migrate.d.ts +9 -0
- package/dist/db/migrate.js +138 -0
- package/dist/db/migrations/index.d.ts +5 -0
- package/dist/db/migrations/index.js +109 -0
- package/dist/db/migrations/types.d.ts +14 -0
- package/dist/db/migrations/types.js +2 -0
- package/dist/db/migrations/v01.d.ts +3 -0
- package/dist/db/migrations/v01.js +38 -0
- package/dist/db/migrations/v02.d.ts +3 -0
- package/dist/db/migrations/v02.js +21 -0
- package/dist/db/migrations/v03.d.ts +3 -0
- package/dist/db/migrations/v03.js +22 -0
- package/dist/db/migrations/v04.d.ts +3 -0
- package/dist/db/migrations/v04.js +28 -0
- package/dist/db/migrations/v05.d.ts +3 -0
- package/dist/db/migrations/v05.js +21 -0
- package/dist/db/migrations/v06.d.ts +3 -0
- package/dist/db/migrations/v06.js +25 -0
- package/dist/db/migrations/v07.d.ts +3 -0
- package/dist/db/migrations/v07.js +13 -0
- package/dist/db/migrations/v08.d.ts +3 -0
- package/dist/db/migrations/v08.js +8 -0
- package/dist/db/migrations/v09.d.ts +3 -0
- package/dist/db/migrations/v09.js +13 -0
- package/dist/db/migrations/v10.d.ts +3 -0
- package/dist/db/migrations/v10.js +17 -0
- package/dist/db/migrations/v11.d.ts +3 -0
- package/dist/db/migrations/v11.js +15 -0
- package/dist/db/migrations/v12.d.ts +3 -0
- package/dist/db/migrations/v12.js +11 -0
- package/dist/db/migrations/v13.d.ts +3 -0
- package/dist/db/migrations/v13.js +15 -0
- package/dist/db/migrations/v14.d.ts +3 -0
- package/dist/db/migrations/v14.js +66 -0
- package/dist/db/migrations/v15.d.ts +3 -0
- package/dist/db/migrations/v15.js +42 -0
- package/dist/db/migrations/v16.d.ts +3 -0
- package/dist/db/migrations/v16.js +61 -0
- package/dist/db/migrations/v17.d.ts +3 -0
- package/dist/db/migrations/v17.js +46 -0
- package/dist/db/migrations/v18.d.ts +3 -0
- package/dist/db/migrations/v18.js +60 -0
- package/dist/db/migrations/v19.d.ts +3 -0
- package/dist/db/migrations/v19.js +28 -0
- package/dist/db/migrations/v20.d.ts +3 -0
- package/dist/db/migrations/v20.js +42 -0
- package/dist/db/migrations/v21.d.ts +3 -0
- package/dist/db/migrations/v21.js +16 -0
- package/dist/db/migrations/v22.d.ts +3 -0
- package/dist/db/migrations/v22.js +82 -0
- package/dist/db/migrations/v23.d.ts +3 -0
- package/dist/db/migrations/v23.js +48 -0
- package/dist/db/migrations/v24.d.ts +3 -0
- package/dist/db/migrations/v24.js +72 -0
- package/dist/db/migrations/v25.d.ts +3 -0
- package/dist/db/migrations/v25.js +46 -0
- package/dist/db/migrations/v26.d.ts +3 -0
- package/dist/db/migrations/v26.js +23 -0
- package/dist/db/migrations/v27.d.ts +3 -0
- package/dist/db/migrations/v27.js +57 -0
- package/dist/db/migrations/v28.d.ts +3 -0
- package/dist/db/migrations/v28.js +38 -0
- package/dist/db/migrations/v29.d.ts +3 -0
- package/dist/db/migrations/v29.js +78 -0
- package/dist/db/migrations/v30.d.ts +3 -0
- package/dist/db/migrations/v30.js +92 -0
- package/dist/db/migrations/v31.d.ts +3 -0
- package/dist/db/migrations/v31.js +74 -0
- package/dist/db/migrations/v32.d.ts +3 -0
- package/dist/db/migrations/v32.js +102 -0
- package/dist/db/migrations/v33.d.ts +3 -0
- package/dist/db/migrations/v33.js +104 -0
- package/dist/db/migrations/v34.d.ts +3 -0
- package/dist/db/migrations/v34.js +93 -0
- package/dist/db/migrations/v35.d.ts +3 -0
- package/dist/db/migrations/v35.js +98 -0
- package/dist/db/migrations/v36.d.ts +3 -0
- package/dist/db/migrations/v36.js +98 -0
- package/dist/db/migrations/v37.d.ts +3 -0
- package/dist/db/migrations/v37.js +219 -0
- package/dist/db/migrations/v38.d.ts +3 -0
- package/dist/db/migrations/v38.js +277 -0
- package/dist/db/migrations/v39.d.ts +3 -0
- package/dist/db/migrations/v39.js +59 -0
- package/dist/db/migrations/v40.d.ts +3 -0
- package/dist/db/migrations/v40.js +74 -0
- package/dist/db/migrations/v41.d.ts +3 -0
- package/dist/db/migrations/v41.js +43 -0
- package/dist/db/migrations/v42.d.ts +3 -0
- package/dist/db/migrations/v42.js +41 -0
- package/dist/db/migrations/v43.d.ts +3 -0
- package/dist/db/migrations/v43.js +67 -0
- package/dist/db/migrations/v44.d.ts +3 -0
- package/dist/db/migrations/v44.js +28 -0
- package/dist/db/migrations/v45.d.ts +3 -0
- package/dist/db/migrations/v45.js +30 -0
- package/dist/db/migrations/v46.d.ts +3 -0
- package/dist/db/migrations/v46.js +25 -0
- package/dist/db/migrations/v47.d.ts +3 -0
- package/dist/db/migrations/v47.js +17 -0
- package/dist/db/migrations/v48.d.ts +3 -0
- package/dist/db/migrations/v48.js +10 -0
- package/dist/db/migrations/v49.d.ts +3 -0
- package/dist/db/migrations/v49.js +31 -0
- package/dist/db/migrations/v50.d.ts +3 -0
- package/dist/db/migrations/v50.js +67 -0
- package/dist/db/migrations/v51.d.ts +3 -0
- package/dist/db/migrations/v51.js +14 -0
- package/dist/db/migrations/v52.d.ts +3 -0
- package/dist/db/migrations/v52.js +7 -0
- package/dist/db/open.d.ts +23 -0
- package/dist/db/open.js +146 -0
- package/dist/db/sqlite.d.ts +21 -0
- package/dist/db/sqlite.js +8 -0
- package/dist/db/tables.d.ts +7 -0
- package/dist/db/tables.js +38 -0
- package/dist/db.d.ts +6 -46
- package/dist/db.js +5 -3049
- package/dist/decisions.d.ts +4 -1
- package/dist/decisions.js +102 -83
- package/dist/dedupe.js +3 -2
- package/dist/delivery-recorder.js +4 -1
- package/dist/doctor.js +14 -10
- package/dist/embedding-provider.d.ts +1 -1
- package/dist/embedding-provider.js +4 -3
- package/dist/embeddings.d.ts +9 -52
- package/dist/embeddings.js +43 -297
- package/dist/env.d.ts +75 -0
- package/dist/env.js +119 -0
- package/dist/eval-suite.js +1 -1
- package/dist/eval.js +2 -2
- package/dist/extract.js +1 -1
- package/dist/gated-write.js +3 -1
- package/dist/goals.d.ts +3 -1
- package/dist/goals.js +117 -86
- package/dist/graph/read.d.ts +73 -0
- package/dist/graph/read.js +325 -0
- package/dist/graph/rows.d.ts +45 -0
- package/dist/graph/rows.js +51 -0
- package/dist/graph/types.d.ts +83 -0
- package/dist/graph/types.js +11 -0
- package/dist/graph/write.d.ts +93 -0
- package/dist/{graph.js → graph/write.js} +6 -384
- package/dist/graph-extract.js +2 -1
- package/dist/graph-recall.d.ts +1 -1
- package/dist/graph-recall.js +2 -2
- package/dist/graph-stream.js +1 -1
- package/dist/graph-view.d.ts +1 -1
- package/dist/graph-view.js +1 -1
- package/dist/half-life-migration.d.ts +1 -1
- package/dist/half-life-migration.js +2 -1
- package/dist/hooks/codex-session.d.ts +8 -0
- package/dist/hooks/codex-session.js +76 -0
- package/dist/hooks/codex-wrapper.d.ts +55 -0
- package/dist/hooks/codex-wrapper.js +288 -0
- package/dist/hooks/json-hooks.d.ts +63 -0
- package/dist/hooks/json-hooks.js +356 -0
- package/dist/hooks/opencode.d.ts +50 -0
- package/dist/hooks/opencode.js +202 -0
- package/dist/hooks/shared.d.ts +54 -0
- package/dist/hooks/shared.js +77 -0
- package/dist/http-retry.d.ts +2 -0
- package/dist/http-retry.js +4 -3
- package/dist/http-util.d.ts +3 -0
- package/dist/http-util.js +10 -0
- package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
- package/dist/importers/core.js +141 -0
- package/dist/importers/markdown-parse.d.ts +41 -0
- package/dist/importers/markdown-parse.js +132 -0
- package/dist/importers/markdown.d.ts +3 -0
- package/dist/importers/markdown.js +92 -0
- package/dist/importers/sources.d.ts +7 -0
- package/dist/importers/sources.js +229 -0
- package/dist/importers/vault.d.ts +11 -0
- package/dist/importers/vault.js +352 -0
- package/dist/incidents.d.ts +3 -0
- package/dist/incidents.js +52 -43
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -6
- package/dist/invalidation.js +2 -1
- package/dist/judgment.js +2 -1
- package/dist/keyset.d.ts +13 -0
- package/dist/keyset.js +8 -0
- package/dist/local-embedding.d.ts +13 -0
- package/dist/local-embedding.js +165 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +19 -1
- package/dist/mcp/admin-tools.d.ts +8 -0
- package/dist/mcp/admin-tools.js +116 -0
- package/dist/mcp/format.d.ts +27 -0
- package/dist/mcp/format.js +135 -0
- package/dist/mcp/memory-tools.d.ts +5 -0
- package/dist/mcp/memory-tools.js +83 -0
- package/dist/mcp/protocol.d.ts +83 -0
- package/dist/mcp/protocol.js +55 -0
- package/dist/mcp/recall-tools.d.ts +6 -0
- package/dist/mcp/recall-tools.js +320 -0
- package/dist/mcp/request.d.ts +10 -0
- package/dist/mcp/request.js +163 -0
- package/dist/mcp/server.d.ts +4 -75
- package/dist/mcp/server.js +7 -1190
- package/dist/mcp/session-state.d.ts +11 -0
- package/dist/mcp/session-state.js +28 -0
- package/dist/mcp/stdio.d.ts +8 -0
- package/dist/mcp/stdio.js +79 -0
- package/dist/mcp/tools.d.ts +11 -0
- package/dist/mcp/tools.js +247 -0
- package/dist/memory.d.ts +3 -0
- package/dist/memory.js +27 -1
- package/dist/multihop.d.ts +1 -1
- package/dist/multihop.js +2 -1
- package/dist/owner-validation.js +2 -1
- package/dist/physics-state.js +10 -7
- package/dist/policies.d.ts +3 -0
- package/dist/policies.js +93 -74
- 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 +94 -76
- package/dist/project-briefs.d.ts +3 -0
- package/dist/project-briefs.js +142 -113
- package/dist/project-identity.js +3 -2
- package/dist/project-merge.d.ts +12 -4
- package/dist/project-merge.js +132 -45
- package/dist/quarantine.d.ts +2 -1
- package/dist/quarantine.js +8 -5
- package/dist/raw-archive.js +1 -1
- package/dist/recall-history.js +3 -2
- package/dist/recall-pipeline.d.ts +2 -2
- package/dist/recall-pipeline.js +16 -8
- package/dist/recall-scope.js +1 -1
- package/dist/recall-trace.d.ts +1 -1
- package/dist/refine-llm.js +2 -1
- package/dist/reject-flow.js +6 -1
- package/dist/rerankers/clef.js +6 -5
- package/dist/rerankers/jev.d.ts +1 -1
- package/dist/rerankers/jev.js +4 -4
- package/dist/rerankers/llm.d.ts +4 -2
- package/dist/rerankers/llm.js +58 -38
- package/dist/rerankers/types.d.ts +1 -1
- package/dist/salience.js +1 -1
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.js +26 -4
- package/dist/scope.js +4 -3
- package/dist/search/as-of.d.ts +10 -0
- package/dist/search/as-of.js +22 -0
- package/dist/search/bm25-search.d.ts +14 -0
- package/dist/search/bm25-search.js +43 -0
- package/dist/search/bm25.d.ts +15 -0
- package/dist/search/bm25.js +54 -0
- package/dist/search/boosts.d.ts +54 -0
- package/dist/search/boosts.js +94 -0
- package/dist/search/breakdown.d.ts +7 -0
- package/dist/search/breakdown.js +20 -0
- package/dist/search/explain.d.ts +25 -0
- package/dist/search/explain.js +31 -0
- package/dist/search/finalize.d.ts +8 -0
- package/dist/search/finalize.js +52 -0
- package/dist/search/fusion.d.ts +27 -0
- package/dist/search/fusion.js +42 -0
- package/dist/search/hybrid-score.d.ts +20 -0
- package/dist/search/hybrid-score.js +73 -0
- package/dist/search/hybrid.d.ts +46 -0
- package/dist/search/hybrid.js +64 -0
- package/dist/search/physics-search.d.ts +29 -0
- package/dist/search/physics-search.js +162 -0
- package/dist/search/rerank.d.ts +10 -0
- package/dist/search/rerank.js +72 -0
- package/dist/search/temporal.d.ts +15 -0
- package/dist/search/temporal.js +45 -0
- package/dist/search/types.d.ts +91 -0
- package/dist/search/types.js +2 -0
- package/dist/search/vector.d.ts +30 -0
- package/dist/search/vector.js +71 -0
- package/dist/secret-detect.d.ts +2 -0
- package/dist/secret-detect.js +2 -1
- package/dist/server/auth.d.ts +52 -0
- package/dist/server/auth.js +221 -0
- package/dist/server/client-ip.d.ts +25 -0
- package/dist/server/client-ip.js +92 -0
- package/dist/server/cursor.d.ts +23 -0
- package/dist/server/cursor.js +58 -0
- package/dist/server/lifecycle.d.ts +7 -0
- package/dist/server/lifecycle.js +29 -0
- package/dist/server/mcp-http.d.ts +5 -0
- package/dist/server/mcp-http.js +199 -0
- package/dist/server/request.d.ts +33 -0
- package/dist/server/request.js +103 -0
- package/dist/server/routes/admin.d.ts +9 -0
- package/dist/server/routes/admin.js +158 -0
- package/dist/server/routes/customer-notes.d.ts +7 -0
- package/dist/server/routes/customer-notes.js +112 -0
- package/dist/server/routes/decisions.d.ts +7 -0
- package/dist/server/routes/decisions.js +133 -0
- package/dist/server/routes/incidents.d.ts +7 -0
- package/dist/server/routes/incidents.js +126 -0
- package/dist/server/routes/memories.d.ts +10 -0
- package/dist/server/routes/memories.js +179 -0
- package/dist/server/routes/policies.d.ts +8 -0
- package/dist/server/routes/policies.js +151 -0
- package/dist/server/routes/predictions.d.ts +7 -0
- package/dist/server/routes/predictions.js +164 -0
- package/dist/server/routes/processes.d.ts +7 -0
- package/dist/server/routes/processes.js +161 -0
- package/dist/server/routes/project-briefs.d.ts +8 -0
- package/dist/server/routes/project-briefs.js +136 -0
- package/dist/server/routes/recall.d.ts +8 -0
- package/dist/server/routes/recall.js +340 -0
- package/dist/server/routes/skills.d.ts +8 -0
- package/dist/server/routes/skills.js +150 -0
- package/dist/server/types.d.ts +56 -0
- package/dist/server/types.js +2 -0
- package/dist/server/validation.d.ts +14 -0
- package/dist/server/validation.js +91 -0
- package/dist/server.d.ts +7 -61
- package/dist/server.js +69 -2362
- package/dist/session-digest.d.ts +1 -1
- package/dist/session-digest.js +9 -2
- package/dist/shared.d.ts +12 -1
- package/dist/shared.js +33 -27
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +88 -70
- package/dist/stdin.js +2 -2
- package/dist/store/audit-event.d.ts +19 -0
- package/dist/store/audit-event.js +33 -0
- package/dist/store/candidates.d.ts +42 -0
- package/dist/store/candidates.js +152 -0
- package/dist/store/conflicts.d.ts +44 -0
- package/dist/store/conflicts.js +444 -0
- package/dist/store/delete-and-batch.d.ts +63 -0
- package/dist/store/delete-and-batch.js +310 -0
- package/dist/store/entry-reads.d.ts +92 -0
- package/dist/store/entry-reads.js +255 -0
- package/dist/store/entry-row.d.ts +67 -0
- package/dist/store/entry-row.js +208 -0
- package/dist/store/entry-writes.d.ts +46 -0
- package/dist/store/entry-writes.js +148 -0
- package/dist/store/handoffs.d.ts +26 -0
- package/dist/store/handoffs.js +184 -0
- package/dist/store/index-and-stats.d.ts +52 -0
- package/dist/store/index-and-stats.js +214 -0
- package/dist/store/markdown.d.ts +10 -0
- package/dist/store/markdown.js +108 -0
- package/dist/store/mirrors.d.ts +49 -0
- package/dist/store/mirrors.js +312 -0
- package/dist/store/open.d.ts +15 -0
- package/dist/store/open.js +223 -0
- package/dist/store/rows.d.ts +178 -0
- package/dist/store/rows.js +158 -0
- package/dist/store/search-rows.d.ts +86 -0
- package/dist/store/search-rows.js +260 -0
- package/dist/store/sessions.d.ts +83 -0
- package/dist/store/sessions.js +272 -0
- package/dist/store/summaries.d.ts +94 -0
- package/dist/store/summaries.js +377 -0
- package/dist/store/tenant-lookup.d.ts +12 -0
- package/dist/store/tenant-lookup.js +16 -0
- package/dist/store-cards.js +2 -1
- package/dist/summary-dirty.d.ts +4 -0
- package/dist/summary-dirty.js +32 -0
- package/dist/support-bundle.js +4 -3
- package/dist/tenant.js +2 -2
- package/dist/tokenize.d.ts +2 -0
- package/dist/tokenize.js +16 -0
- package/dist/transcript-tail.d.ts +7 -0
- package/dist/transcript-tail.js +48 -0
- package/dist/vector-store.d.ts +27 -0
- package/dist/vector-store.js +210 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/working-memory.js +1 -1
- package/dist/yaml.js +36 -11
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist-ui/assets/index-DPN7cP19.js +33 -0
- package/dist-ui/assets/index-dFloKRVr.css +1 -0
- package/dist-ui/index.html +3 -25
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/capture.d.ts +0 -155
- package/dist/capture.js +0 -1295
- package/dist/consolidate.d.ts +0 -58
- package/dist/consolidate.js +0 -1124
- package/dist/graph.d.ts +0 -245
- package/dist/hooks.d.ts +0 -208
- package/dist/hooks.js +0 -1076
- package/dist/importers.js +0 -900
- package/dist/predictions.js +0 -620
- package/dist/search.d.ts +0 -320
- package/dist/search.js +0 -970
- package/dist/store.d.ts +0 -776
- package/dist/store.js +0 -3473
- package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
- package/dist-ui/assets/index-BhT8RvO6.js +0 -61
- package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
- package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type TaskSnapshot } from '../store/rows.js';
|
|
2
|
+
export declare const PRE_COMPACT_TASK_CAP = 200;
|
|
3
|
+
export declare const PRE_COMPACT_SUMMARY_CAP = 2000;
|
|
4
|
+
export declare const PRE_COMPACT_NEXT_STEP_CAP = 500;
|
|
5
|
+
/**
|
|
6
|
+
* Cap from the RECENT end: summariseTranscript emits user turns oldest-to-
|
|
7
|
+
* newest with assistant responses after them, so a head-first cap keeps
|
|
8
|
+
* stale context and drops exactly the newest working state this feature
|
|
9
|
+
* exists to preserve. Keep the LAST maxChars instead, aligned forward to a
|
|
10
|
+
* nearby line start, with a trim marker (codex round 3).
|
|
11
|
+
*/
|
|
12
|
+
export declare function truncateKeepNewest(text: string, maxChars: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Log-forgery guard: messages here interpolate payload-controlled values
|
|
15
|
+
* (transcript paths, session ids). Strip C0 control chars — newlines above
|
|
16
|
+
* all — so a crafted value can't inject fake `[hippo] ...` log lines.
|
|
17
|
+
* Exported for every `[hippo]`-prefixed log writer that interpolates
|
|
18
|
+
* payload-controlled values (cli.ts appendSessionEndCloseLog) — one shared
|
|
19
|
+
* guard, not per-file copies.
|
|
20
|
+
*/
|
|
21
|
+
export declare function sanitizeLogMessage(message: string): string;
|
|
22
|
+
/** A session's task, summary and next step from its transcript tail, secrets scrubbed and capped, '' where none; null with a logged reason when nothing is derivable. */
|
|
23
|
+
export declare function transcriptWorkingState(transcriptPath: string, log: (message: string) => void): Pick<TaskSnapshot, 'task' | 'summary' | 'next_step'> | null;
|
|
24
|
+
export interface PreCompactOptions {
|
|
25
|
+
stdinText?: string;
|
|
26
|
+
stdinTimedOut?: boolean;
|
|
27
|
+
logFile?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* PreCompact hook entry point. Exit code 2 on PreCompact BLOCKS compaction,
|
|
31
|
+
* so this verb must exit 0 on every path — malformed stdin, missing
|
|
32
|
+
* transcript, and store errors all degrade to a logged no-op rather than a
|
|
33
|
+
* thrown error. Callers (src/cli.ts) must not wrap this in anything that
|
|
34
|
+
* could turn a caught-and-logged failure back into a non-zero exit.
|
|
35
|
+
*/
|
|
36
|
+
export declare function cmdPreCompact(hippoRoot: string, options: PreCompactOptions): Promise<void>;
|
|
37
|
+
export interface PostCompactOptions {
|
|
38
|
+
stdinText?: string;
|
|
39
|
+
logFile?: string;
|
|
40
|
+
afterSave?: (transcriptPath: string, cwd: string | null, log: (message: string) => void) => void;
|
|
41
|
+
}
|
|
42
|
+
/** PostCompact entry point: saves the summary and its items, replays earlier leftovers, returns the one line to show. Never throws, so the hook exits 0. */
|
|
43
|
+
export declare function cmdPostCompact(hippoRoot: string, options: PostCompactOptions): string | null;
|
|
44
|
+
//# sourceMappingURL=compact.d.ts.map
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { isInitialized } from '../store/open.js';
|
|
4
|
+
import { saveActiveTaskSnapshot, loadActiveTaskSnapshot } from '../store/sessions.js';
|
|
5
|
+
import { PRE_COMPACT_INSTRUCTION, parsePostCompactPayload, postCompactLine, recordCompactionStart, recordSnapshotSaved, saveCompaction, replayCompactionsAt, COMPACTION_DB_WAIT_MS, } from '../compaction-record.js';
|
|
6
|
+
import { resolveTenantId } from '../tenant.js';
|
|
7
|
+
import { defaultPreCompactLogPath } from '../hooks/shared.js';
|
|
8
|
+
import { maskEmails, redactSecretsStrict } from '../secret-detect.js';
|
|
9
|
+
import { isObjectLike, isStringValue, readClaudeCodePreCompact } from '../capture-contract.js';
|
|
10
|
+
import { errorMessage } from '../log.js';
|
|
11
|
+
import { PRE_COMPACT_TAIL_BYTES, readTranscriptTail, truncateCodePointSafe } from '../transcript-tail.js';
|
|
12
|
+
import { humanUserText, summariseTranscript, resolveLastSessionTranscript } from './transcript.js';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// `hippo pre-compact` — PreCompact hook producer
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
export const PRE_COMPACT_TASK_CAP = 200;
|
|
17
|
+
export const PRE_COMPACT_SUMMARY_CAP = 2000;
|
|
18
|
+
export const PRE_COMPACT_NEXT_STEP_CAP = 500;
|
|
19
|
+
/**
|
|
20
|
+
* Cap from the RECENT end: summariseTranscript emits user turns oldest-to-
|
|
21
|
+
* newest with assistant responses after them, so a head-first cap keeps
|
|
22
|
+
* stale context and drops exactly the newest working state this feature
|
|
23
|
+
* exists to preserve. Keep the LAST maxChars instead, aligned forward to a
|
|
24
|
+
* nearby line start, with a trim marker (codex round 3).
|
|
25
|
+
*/
|
|
26
|
+
export function truncateKeepNewest(text, maxChars) {
|
|
27
|
+
if (text.length <= maxChars)
|
|
28
|
+
return text;
|
|
29
|
+
let start = text.length - maxChars;
|
|
30
|
+
const code = text.charCodeAt(start);
|
|
31
|
+
if (code >= 0xdc00 && code <= 0xdfff)
|
|
32
|
+
start += 1; // never start on a low surrogate
|
|
33
|
+
const nl = text.indexOf('\n', start);
|
|
34
|
+
if (nl !== -1 && nl + 1 < text.length && nl - start < 200)
|
|
35
|
+
start = nl + 1;
|
|
36
|
+
return '[...earlier turns trimmed]\n' + text.slice(start);
|
|
37
|
+
}
|
|
38
|
+
/** Most recent plain-text user message in a JSONL tail. Claude Code transcript shape only (PreCompact is claude-code-only). */
|
|
39
|
+
function lastPlainUserMessage(jsonl) {
|
|
40
|
+
const lines = jsonl.split('\n').filter((l) => l.trim());
|
|
41
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
42
|
+
let entry;
|
|
43
|
+
try {
|
|
44
|
+
entry = JSON.parse(lines[i]);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
continue; // the tail read can start mid-line; skip the torn fragment
|
|
48
|
+
}
|
|
49
|
+
if (!isObjectLike(entry))
|
|
50
|
+
continue;
|
|
51
|
+
if (!('type' in entry) || entry.type !== 'user')
|
|
52
|
+
continue;
|
|
53
|
+
// Meta/sidechain lines carry type:'user' but are not the human: after a
|
|
54
|
+
// FIRST compaction the transcript holds the compact summary as an isMeta
|
|
55
|
+
// user line, and sub-agent turns are isSidechain — deriving "task" from
|
|
56
|
+
// either yields junk on every later compaction.
|
|
57
|
+
if (('isMeta' in entry && entry.isMeta === true) || ('isSidechain' in entry && entry.isSidechain === true))
|
|
58
|
+
continue;
|
|
59
|
+
const message = 'message' in entry && isObjectLike(entry.message) ? entry.message : undefined;
|
|
60
|
+
if (!message)
|
|
61
|
+
continue;
|
|
62
|
+
const text = humanUserText(entry, message);
|
|
63
|
+
if (text)
|
|
64
|
+
return text;
|
|
65
|
+
}
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
/** Last assistant text block in a JSONL tail (skips thinking + tool_use, same as summariseTranscript). */
|
|
69
|
+
function lastAssistantTextBlock(jsonl) {
|
|
70
|
+
const lines = jsonl.split('\n').filter((l) => l.trim());
|
|
71
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
72
|
+
let entry;
|
|
73
|
+
try {
|
|
74
|
+
entry = JSON.parse(lines[i]);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
continue; // the tail read can start mid-line; skip the torn fragment
|
|
78
|
+
}
|
|
79
|
+
if (!isObjectLike(entry))
|
|
80
|
+
continue;
|
|
81
|
+
if (!('type' in entry) || entry.type !== 'assistant')
|
|
82
|
+
continue;
|
|
83
|
+
// Same meta/sidechain guard as lastPlainUserMessage: sub-agent turns
|
|
84
|
+
// (isSidechain) are not this session's next step.
|
|
85
|
+
if (('isMeta' in entry && entry.isMeta === true) || ('isSidechain' in entry && entry.isSidechain === true))
|
|
86
|
+
continue;
|
|
87
|
+
const message = 'message' in entry && isObjectLike(entry.message) ? entry.message : undefined;
|
|
88
|
+
if (!message)
|
|
89
|
+
continue;
|
|
90
|
+
const content = 'content' in message ? message.content : undefined;
|
|
91
|
+
if (!Array.isArray(content))
|
|
92
|
+
continue;
|
|
93
|
+
for (let j = content.length - 1; j >= 0; j--) {
|
|
94
|
+
const block = content[j];
|
|
95
|
+
if (isObjectLike(block)) {
|
|
96
|
+
const blockText = 'type' in block && block.type === 'text' && 'text' in block ? block.text : undefined;
|
|
97
|
+
if (isStringValue(blockText) && blockText.trim()) {
|
|
98
|
+
return blockText.trim();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return '';
|
|
104
|
+
}
|
|
105
|
+
// Diagnostic-only log; a long-lived install must not grow it unbounded.
|
|
106
|
+
const PRE_COMPACT_LOG_MAX_BYTES = 256 * 1024;
|
|
107
|
+
/**
|
|
108
|
+
* Log-forgery guard: messages here interpolate payload-controlled values
|
|
109
|
+
* (transcript paths, session ids). Strip C0 control chars — newlines above
|
|
110
|
+
* all — so a crafted value can't inject fake `[hippo] ...` log lines.
|
|
111
|
+
* Exported for every `[hippo]`-prefixed log writer that interpolates
|
|
112
|
+
* payload-controlled values (cli.ts appendSessionEndCloseLog) — one shared
|
|
113
|
+
* guard, not per-file copies.
|
|
114
|
+
*/
|
|
115
|
+
export function sanitizeLogMessage(message) {
|
|
116
|
+
// eslint-disable-next-line no-control-regex
|
|
117
|
+
return message.replace(/[\x00-\x1f]/g, '');
|
|
118
|
+
}
|
|
119
|
+
function appendPreCompactLog(logFile, message) {
|
|
120
|
+
try {
|
|
121
|
+
fs.mkdirSync(path.dirname(logFile), { recursive: true });
|
|
122
|
+
const stat = fs.existsSync(logFile) ? fs.statSync(logFile) : null;
|
|
123
|
+
if (stat && stat.size > PRE_COMPACT_LOG_MAX_BYTES) {
|
|
124
|
+
fs.writeFileSync(logFile, '', 'utf8'); // start fresh — dumb cap, no rotation
|
|
125
|
+
}
|
|
126
|
+
fs.appendFileSync(logFile, `[hippo] ${new Date().toISOString()} ${sanitizeLogMessage(message)}\n`, 'utf8');
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Diagnostic-only; a log write failure must never affect the exit-0 contract.
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** True iff `filePath` exists and is readable — checks both in one call. */
|
|
133
|
+
function isReadableFile(filePath) {
|
|
134
|
+
try {
|
|
135
|
+
fs.accessSync(filePath, fs.constants.R_OK);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return false; // missing and unreadable both mean "no file" to the caller
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/** PreCompact stdout is the summariser's instructions; sent before the snapshot work because a locked store can run the hook past its 30 s limit, and via writeSync because process.exit drops buffered pipe output. */
|
|
143
|
+
function printPreCompactInstruction(logFile) {
|
|
144
|
+
try {
|
|
145
|
+
fs.writeSync(1, `${PRE_COMPACT_INSTRUCTION}\n`);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
appendPreCompactLog(logFile, `instruction not printed: ${errorMessage(err)}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** A session's task, summary and next step from its transcript tail, secrets scrubbed and capped, '' where none; null with a logged reason when nothing is derivable. */
|
|
152
|
+
export function transcriptWorkingState(transcriptPath, log) {
|
|
153
|
+
let tail = '';
|
|
154
|
+
let rawTask = '';
|
|
155
|
+
let rawNextStep = '';
|
|
156
|
+
try {
|
|
157
|
+
// Compaction fires when a big tool_result lands (CX7), so the last human and assistant turns can sit
|
|
158
|
+
// megabytes back: grow the window a bounded number of times until both turns are in it.
|
|
159
|
+
const size = fs.statSync(transcriptPath).size;
|
|
160
|
+
for (const cap of [PRE_COMPACT_TAIL_BYTES, PRE_COMPACT_TAIL_BYTES * 4, PRE_COMPACT_TAIL_BYTES * 16]) {
|
|
161
|
+
if (cap > PRE_COMPACT_TAIL_BYTES)
|
|
162
|
+
log(`tail window grown to ${cap} bytes (last ${rawTask ? 'assistant' : 'user'} turn is further back)`);
|
|
163
|
+
tail = readTranscriptTail(transcriptPath, cap);
|
|
164
|
+
rawTask = lastPlainUserMessage(tail);
|
|
165
|
+
rawNextStep = lastAssistantTextBlock(tail);
|
|
166
|
+
if ((rawTask && rawNextStep) || size <= cap)
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
log(`skip: could not read transcript tail: ${errorMessage(err)}`);
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
const rawSummary = summariseTranscript(tail);
|
|
175
|
+
if (!rawTask.trim() && !rawSummary.trim() && !rawNextStep.trim()) {
|
|
176
|
+
log('skip: empty summary');
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
// X9: these fields skip the capture content gate and reach a prompt, so the strict scrub runs. The caps protect the
|
|
180
|
+
// re-injection token budget and never split a surrogate pair (X2); `hippo snapshot save` stays uncapped.
|
|
181
|
+
const task = maskEmails(redactSecretsStrict(rawTask));
|
|
182
|
+
const summary = maskEmails(redactSecretsStrict(rawSummary));
|
|
183
|
+
const nextStep = maskEmails(redactSecretsStrict(rawNextStep));
|
|
184
|
+
return {
|
|
185
|
+
task: task.trim() ? truncateCodePointSafe(task, PRE_COMPACT_TASK_CAP) : '',
|
|
186
|
+
summary: summary.trim() ? truncateKeepNewest(summary, PRE_COMPACT_SUMMARY_CAP) : '',
|
|
187
|
+
next_step: nextStep.trim() ? truncateCodePointSafe(nextStep, PRE_COMPACT_NEXT_STEP_CAP) : '',
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/** Runs the PreCompact producer: records the compaction, asks the summariser for memories, saves a working-state snapshot. Never extracts memories itself; SessionEnd capture owns that. */
|
|
191
|
+
function runPreCompact(hippoRoot, stdinText, stdinTimedOut, logFile) {
|
|
192
|
+
// X3: the PreCompact hook fires in every Claude Code project, including
|
|
193
|
+
// ones that never ran `hippo init`, so gate before any store-opening call
|
|
194
|
+
// (saveActiveTaskSnapshot etc. call initStore, which would create one).
|
|
195
|
+
if (!isInitialized(hippoRoot)) {
|
|
196
|
+
appendPreCompactLog(logFile, 'skip: store not initialized');
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const receipt = readClaudeCodePreCompact(stdinText, stdinTimedOut);
|
|
200
|
+
if (receipt.status !== 'received') {
|
|
201
|
+
appendPreCompactLog(logFile, `skip: ${receipt.reason}`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const { sessionId, transcriptPath: payloadTranscriptPath, cwd: payloadCwd, trigger: payloadTrigger } = receipt.input;
|
|
205
|
+
// The record is the "something saved before every compaction", so it lands even when no snapshot is derivable below.
|
|
206
|
+
let recordId = null;
|
|
207
|
+
if (sessionId !== null && sessionId !== '') {
|
|
208
|
+
recordId = recordCompactionStart(hippoRoot, { sessionId, trigger: payloadTrigger, cwd: payloadCwd, transcriptPath: payloadTranscriptPath }, (message) => appendPreCompactLog(logFile, message));
|
|
209
|
+
printPreCompactInstruction(logFile);
|
|
210
|
+
}
|
|
211
|
+
const transcriptPath = resolvePreCompactTranscript(payloadTranscriptPath, stdinText, logFile);
|
|
212
|
+
if (!transcriptPath)
|
|
213
|
+
return;
|
|
214
|
+
// Nothing derivable skips the write, so a user-authored active snapshot is never clobbered with junk.
|
|
215
|
+
const derived = transcriptWorkingState(transcriptPath, (message) => appendPreCompactLog(logFile, message));
|
|
216
|
+
if (!derived)
|
|
217
|
+
return;
|
|
218
|
+
saveDerivedSnapshot(hippoRoot, logFile, sessionId, recordId, derived);
|
|
219
|
+
}
|
|
220
|
+
/** The transcript to snapshot, or null after logging why there is none. */
|
|
221
|
+
function resolvePreCompactTranscript(payloadTranscriptPath, stdinText, logFile) {
|
|
222
|
+
// A payload transcript_path is EXCLUSIVE: never fall back to
|
|
223
|
+
// newest-transcript auto-discovery when it's missing/unreadable. That
|
|
224
|
+
// fallback would snapshot a DIFFERENT session's transcript under THIS
|
|
225
|
+
// payload's session_id — cross-session contamination with wrong linkage
|
|
226
|
+
// (verify-stage E2E finding, 2026-08-03). Auto-discovery only applies
|
|
227
|
+
// on a true manual invocation (no payload at all).
|
|
228
|
+
let transcriptPath;
|
|
229
|
+
if (payloadTranscriptPath !== null) {
|
|
230
|
+
if (isReadableFile(payloadTranscriptPath)) {
|
|
231
|
+
transcriptPath = payloadTranscriptPath;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
appendPreCompactLog(logFile, `skip: payload transcript_path unreadable: ${payloadTranscriptPath}`);
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
transcriptPath = resolveLastSessionTranscript(undefined, stdinText, { mayScan: true });
|
|
240
|
+
}
|
|
241
|
+
if (!transcriptPath) {
|
|
242
|
+
appendPreCompactLog(logFile, 'skip: no transcript resolved');
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
return transcriptPath;
|
|
246
|
+
}
|
|
247
|
+
function saveDerivedSnapshot(hippoRoot, logFile, sessionId, recordId, derived) {
|
|
248
|
+
const tenantId = resolveTenantId({});
|
|
249
|
+
// Per-field merge (X1): a tool-heavy tail whose only user turns are
|
|
250
|
+
// tool_result arrays derives an empty task even though the summary is
|
|
251
|
+
// non-empty. Loading the existing snapshot first lets each field fall
|
|
252
|
+
// back independently instead of the whole write clobbering a
|
|
253
|
+
// user-authored field with blank text.
|
|
254
|
+
let existing = null;
|
|
255
|
+
try {
|
|
256
|
+
existing = loadActiveTaskSnapshot(hippoRoot, tenantId);
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
// No existing snapshot to merge against — proceed with derived-only.
|
|
260
|
+
}
|
|
261
|
+
// CX6 (codex round 2): field fallback must never move content across
|
|
262
|
+
// sessions — session A's task carried into a snapshot saved under session
|
|
263
|
+
// B's id would pass compact-resume's session gate wearing the wrong
|
|
264
|
+
// badge. Fall back only when the existing snapshot has no session, this
|
|
265
|
+
// payload has none, or they match.
|
|
266
|
+
const fallback = existing !== null &&
|
|
267
|
+
(existing.session_id === null || sessionId === null || existing.session_id === sessionId)
|
|
268
|
+
? existing
|
|
269
|
+
: null;
|
|
270
|
+
// Carried-over fields are not re-capped, as `hippo snapshot save` stays uncapped; saveActiveTaskSnapshot scrubs every field.
|
|
271
|
+
const task = derived.task || (fallback?.task ?? '');
|
|
272
|
+
const summary = derived.summary || (fallback?.summary ?? '');
|
|
273
|
+
const nextStep = derived.next_step || (fallback?.next_step ?? '');
|
|
274
|
+
// All-empty fields (cross-session tail with nothing derivable) skip the
|
|
275
|
+
// write so a foreign session's junk never displaces the owning snapshot.
|
|
276
|
+
if (!task && !summary && !nextStep) {
|
|
277
|
+
appendPreCompactLog(logFile, 'skip: no snapshot content for this session (nothing derivable; fallback blocked or empty)');
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
try {
|
|
281
|
+
saveActiveTaskSnapshot(hippoRoot, tenantId, {
|
|
282
|
+
task,
|
|
283
|
+
summary,
|
|
284
|
+
next_step: nextStep,
|
|
285
|
+
source: 'pre-compact',
|
|
286
|
+
session_id: sessionId,
|
|
287
|
+
});
|
|
288
|
+
appendPreCompactLog(logFile, 'snapshot saved');
|
|
289
|
+
if (recordId !== null)
|
|
290
|
+
recordSnapshotSaved(hippoRoot, recordId, (message) => appendPreCompactLog(logFile, message));
|
|
291
|
+
}
|
|
292
|
+
catch (err) {
|
|
293
|
+
appendPreCompactLog(logFile, `snapshot save failed: ${errorMessage(err)}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* PreCompact hook entry point. Exit code 2 on PreCompact BLOCKS compaction,
|
|
299
|
+
* so this verb must exit 0 on every path — malformed stdin, missing
|
|
300
|
+
* transcript, and store errors all degrade to a logged no-op rather than a
|
|
301
|
+
* thrown error. Callers (src/cli.ts) must not wrap this in anything that
|
|
302
|
+
* could turn a caught-and-logged failure back into a non-zero exit.
|
|
303
|
+
*/
|
|
304
|
+
export async function cmdPreCompact(hippoRoot, options) {
|
|
305
|
+
const logFile = options.logFile ?? defaultPreCompactLogPath();
|
|
306
|
+
try {
|
|
307
|
+
runPreCompact(hippoRoot, options.stdinText, options.stdinTimedOut ?? false, logFile);
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
appendPreCompactLog(logFile, `pre-compact failed: ${errorMessage(err)}`);
|
|
311
|
+
}
|
|
312
|
+
process.exit(0);
|
|
313
|
+
}
|
|
314
|
+
/** A PostCompact hook has 10 s in all; replay stops starting new records after this. */
|
|
315
|
+
const POST_COMPACT_REPLAY_BUDGET_MS = 6000;
|
|
316
|
+
/** PostCompact entry point: saves the summary and its items, replays earlier leftovers, returns the one line to show. Never throws, so the hook exits 0. */
|
|
317
|
+
export function cmdPostCompact(hippoRoot, options) {
|
|
318
|
+
const logFile = options.logFile ?? defaultPreCompactLogPath();
|
|
319
|
+
const log = (message) => appendPreCompactLog(logFile, `post-compact: ${message}`);
|
|
320
|
+
const deadline = Date.now() + POST_COMPACT_REPLAY_BUDGET_MS;
|
|
321
|
+
try {
|
|
322
|
+
if (!isInitialized(hippoRoot)) {
|
|
323
|
+
log('skip: no hippo store');
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
const payload = parsePostCompactPayload(options.stdinText);
|
|
327
|
+
let line = null;
|
|
328
|
+
let storeBusy = false;
|
|
329
|
+
if (payload === null) {
|
|
330
|
+
log('skip: no PostCompact payload naming a session');
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
const saved = saveCompaction(hippoRoot, payload, log);
|
|
334
|
+
line = postCompactLine(saved);
|
|
335
|
+
storeBusy = saved.deferred;
|
|
336
|
+
if (!storeBusy && payload.transcriptPath !== null && options.afterSave) {
|
|
337
|
+
try {
|
|
338
|
+
options.afterSave(payload.transcriptPath, payload.cwd, log);
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
log(`agent memory import failed: ${errorMessage(err)}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (!storeBusy)
|
|
346
|
+
replayCompactionsAt(hippoRoot, log, { busyWaitMs: COMPACTION_DB_WAIT_MS, deadline });
|
|
347
|
+
return line;
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
log(`failed: ${errorMessage(err)}`);
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
//# sourceMappingURL=compact.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture actionable items from conversation text.
|
|
3
|
+
*
|
|
4
|
+
* Uses heuristic pattern matching (no LLM) to extract:
|
|
5
|
+
* - Decisions ("we decided", "let's do", "going with")
|
|
6
|
+
* - Specs / requirements (bullet lists after spec/feature/plan headings)
|
|
7
|
+
* - Rules / constraints ("never", "always", "the rule is", "must")
|
|
8
|
+
* - Errors / gotchas ("error:", "bug:", "gotcha:", "watch out")
|
|
9
|
+
* - Preferences ("prefer", "use X instead of Y", "don't use")
|
|
10
|
+
*/
|
|
11
|
+
export interface ExtractedItem {
|
|
12
|
+
content: string;
|
|
13
|
+
category: string;
|
|
14
|
+
tags: string[];
|
|
15
|
+
}
|
|
16
|
+
export declare function splitSentences(text: string): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Main extraction function. Scans text for actionable items using heuristics.
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractFromText(text: string): ExtractedItem[];
|
|
21
|
+
//# sourceMappingURL=extract.d.ts.map
|