hippo-memory 1.70.0 → 1.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agent-memories/claude-code.d.ts +4 -2
- package/dist/agent-memories/claude-code.js +14 -5
- package/dist/agent-memories/files.js +23 -12
- package/dist/agent-memories/markdown.d.ts +1 -3
- package/dist/agent-memories/markdown.js +1 -3
- package/dist/agent-memories/report.js +2 -1
- package/dist/agent-memories/sync.d.ts +4 -2
- package/dist/agent-memories/sync.js +10 -5
- package/dist/api/assemble.d.ts +7 -44
- package/dist/api/assemble.js +2 -22
- package/dist/api/audit.d.ts +5 -1
- package/dist/api/audit.js +9 -1
- package/dist/api/auth.d.ts +13 -22
- package/dist/api/auth.js +34 -24
- package/dist/api/auto-sleep.js +2 -2
- package/dist/api/availability.d.ts +2 -15
- package/dist/api/availability.js +2 -15
- package/dist/api/context-select.js +3 -4
- package/dist/api/context-types.d.ts +10 -35
- package/dist/api/context.d.ts +5 -22
- package/dist/api/context.js +21 -38
- package/dist/api/dormant.d.ts +5 -21
- package/dist/api/dormant.js +7 -26
- package/dist/api/drill-down.d.ts +7 -46
- package/dist/api/drill-down.js +5 -26
- package/dist/api/forget.d.ts +5 -24
- package/dist/api/forget.js +5 -28
- package/dist/api/graph.d.ts +8 -0
- package/dist/api/graph.js +7 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/instruction-detect.js +16 -5
- package/dist/api/ledger-db.d.ts +2 -1
- package/dist/api/ledger-db.js +5 -3
- package/dist/api/memories.d.ts +5 -0
- package/dist/api/memories.js +7 -0
- package/dist/api/objects.d.ts +9 -0
- package/dist/api/objects.js +11 -0
- package/dist/api/on-store.js +5 -3
- package/dist/api/predictions.d.ts +9 -0
- package/dist/api/predictions.js +18 -0
- package/dist/api/promote.d.ts +13 -17
- package/dist/api/promote.js +11 -19
- package/dist/api/prompt-hook.d.ts +4 -4
- package/dist/api/prompt-hook.js +10 -9
- package/dist/api/recall-cli.d.ts +55 -0
- package/dist/api/recall-cli.js +94 -0
- package/dist/api/recall-core.js +14 -6
- package/dist/api/recall-finish.d.ts +53 -0
- package/dist/api/recall-finish.js +30 -0
- package/dist/api/recall-history.d.ts +17 -84
- package/dist/api/recall-history.js +15 -88
- package/dist/api/recall-pipeline.d.ts +2 -3
- package/dist/api/recall-pipeline.js +16 -9
- package/dist/api/recall-types.d.ts +64 -304
- package/dist/api/recall.d.ts +5 -33
- package/dist/api/recall.js +59 -60
- package/dist/api/refine.d.ts +7 -0
- package/dist/api/refine.js +10 -0
- package/dist/api/remember-local.d.ts +57 -0
- package/dist/api/remember-local.js +90 -0
- package/dist/api/remember.d.ts +18 -1
- package/dist/api/remember.js +13 -1
- package/dist/api/sleep-run.d.ts +1 -3
- package/dist/api/sleep-run.js +17 -21
- package/dist/api/sleep.d.ts +9 -28
- package/dist/api/tokens.d.ts +3 -10
- package/dist/api/tokens.js +3 -10
- package/dist/api/types.d.ts +6 -29
- package/dist/api/types.js +4 -22
- package/dist/capture/command.d.ts +4 -12
- package/dist/capture/command.js +6 -22
- package/dist/capture/compact.d.ts +4 -15
- package/dist/capture/compact.js +16 -25
- package/dist/capture/compaction-record.js +101 -69
- package/dist/capture/compaction-spool.d.ts +1 -1
- package/dist/capture/compaction-spool.js +1 -1
- package/dist/capture/session-digest.d.ts +1 -1
- package/dist/capture/session-digest.js +13 -7
- package/dist/capture/transcript.d.ts +2 -10
- package/dist/capture/transcript.js +4 -18
- package/dist/cli/api-context.d.ts +3 -0
- package/dist/cli/api-context.js +6 -0
- package/dist/cli/audit-prune.d.ts +6 -39
- package/dist/cli/audit-prune.js +6 -39
- package/dist/cli/audit.d.ts +1 -1
- package/dist/cli/audit.js +33 -34
- package/dist/cli/auth.d.ts +2 -2
- package/dist/cli/auth.js +57 -39
- package/dist/cli/briefs.d.ts +4 -4
- package/dist/cli/briefs.js +18 -22
- package/dist/cli/card.d.ts +2 -2
- package/dist/cli/card.js +31 -32
- package/dist/cli/client.d.ts +7 -27
- package/dist/cli/client.js +24 -43
- package/dist/cli/compact-resume-payload.js +3 -2
- package/dist/cli/context.d.ts +1 -2
- package/dist/cli/context.js +12 -8
- package/dist/cli/continuity.d.ts +6 -6
- package/dist/cli/continuity.js +62 -64
- package/dist/cli/correction-latency.d.ts +2 -14
- package/dist/cli/correction-latency.js +2 -14
- package/dist/cli/curate.d.ts +13 -17
- package/dist/cli/curate.js +68 -92
- package/dist/cli/dag.d.ts +4 -4
- package/dist/cli/dag.js +33 -27
- package/dist/cli/decisions.d.ts +4 -4
- package/dist/cli/decisions.js +33 -47
- package/dist/cli/eval.js +15 -13
- package/dist/cli/exit.d.ts +6 -0
- package/dist/cli/exit.js +11 -0
- package/dist/cli/explain.d.ts +1 -2
- package/dist/cli/explain.js +6 -4
- package/dist/cli/flag-values.d.ts +6 -1
- package/dist/cli/flag-values.js +27 -10
- package/dist/cli/flags.d.ts +1 -0
- package/dist/cli/flags.js +1 -1
- package/dist/cli/github.d.ts +14 -0
- package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
- package/dist/cli/goals.d.ts +2 -2
- package/dist/cli/goals.js +46 -50
- package/dist/cli/hook-runtime.d.ts +9 -27
- package/dist/cli/hook-runtime.js +15 -31
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.js +6 -12
- package/dist/cli/install-steps.js +3 -12
- package/dist/cli/last-sleep.d.ts +2 -1
- package/dist/cli/last-sleep.js +3 -0
- package/dist/cli/maintenance.d.ts +4 -4
- package/dist/cli/maintenance.js +14 -19
- package/dist/cli/object-verbs.js +4 -3
- package/dist/cli/owner-validation.d.ts +5 -28
- package/dist/cli/owner-validation.js +5 -28
- package/dist/cli/playbooks.d.ts +4 -4
- package/dist/cli/playbooks.js +23 -28
- package/dist/cli/print.d.ts +2 -5
- package/dist/cli/print.js +1 -4
- package/dist/cli/projects.d.ts +2 -2
- package/dist/cli/projects.js +1 -3
- package/dist/cli/provenance-coverage.d.ts +2 -6
- package/dist/cli/provenance-coverage.js +2 -6
- package/dist/cli/quality-repair-once.js +2 -2
- package/dist/cli/recall.d.ts +2 -4
- package/dist/cli/recall.js +55 -131
- package/dist/cli/refine-llm.d.ts +5 -31
- package/dist/cli/refine-llm.js +9 -36
- package/dist/cli/remember.d.ts +3 -3
- package/dist/cli/remember.js +122 -180
- package/dist/cli/scheduler.d.ts +2 -17
- package/dist/cli/scheduler.js +12 -18
- package/dist/cli/serve.js +21 -12
- package/dist/cli/session-hooks.d.ts +10 -18
- package/dist/cli/session-hooks.js +112 -113
- package/dist/cli/setup.d.ts +4 -4
- package/dist/cli/setup.js +19 -21
- package/dist/cli/shared.d.ts +9 -23
- package/dist/cli/shared.js +9 -32
- package/dist/cli/slack.d.ts +2 -2
- package/dist/cli/slack.js +19 -23
- package/dist/cli/sleep.d.ts +3 -2
- package/dist/cli/sleep.js +15 -16
- package/dist/cli/status.d.ts +9 -12
- package/dist/cli/status.js +55 -98
- package/dist/cli/stdin.d.ts +4 -6
- package/dist/cli/stdin.js +2 -3
- package/dist/cli/transfer.d.ts +9 -9
- package/dist/cli/transfer.js +66 -89
- package/dist/cli/usage.js +11 -5
- package/dist/cli.d.ts +66 -448
- package/dist/cli.js +87 -263
- package/dist/connectors/github/backfill.d.ts +5 -25
- package/dist/connectors/github/backfill.js +14 -49
- package/dist/connectors/github/deletion.d.ts +4 -18
- package/dist/connectors/github/deletion.js +2 -15
- package/dist/connectors/github/dlq.d.ts +8 -33
- package/dist/connectors/github/dlq.js +12 -29
- package/dist/connectors/github/ingest.d.ts +2 -6
- package/dist/connectors/github/ingest.js +4 -10
- package/dist/connectors/github/octokit-client.d.ts +4 -16
- package/dist/connectors/github/octokit-client.js +27 -24
- package/dist/connectors/github/ratelimit.d.ts +3 -14
- package/dist/connectors/github/ratelimit.js +3 -14
- package/dist/connectors/github/scope.d.ts +3 -5
- package/dist/connectors/github/scope.js +3 -5
- package/dist/connectors/github/signature.d.ts +4 -26
- package/dist/connectors/github/signature.js +4 -26
- package/dist/connectors/github/tenant-routing.d.ts +2 -24
- package/dist/connectors/github/tenant-routing.js +4 -26
- package/dist/connectors/github/transform.js +2 -16
- package/dist/connectors/github/types.d.ts +3 -15
- package/dist/connectors/github/types.js +2 -9
- package/dist/connectors/github/webhook.d.ts +2 -16
- package/dist/connectors/github/webhook.js +6 -22
- package/dist/connectors/slack/backfill.d.ts +4 -17
- package/dist/connectors/slack/backfill.js +4 -13
- package/dist/connectors/slack/dlq.d.ts +2 -19
- package/dist/connectors/slack/dlq.js +2 -19
- package/dist/connectors/slack/ingest.d.ts +2 -3
- package/dist/connectors/slack/ingest.js +2 -3
- package/dist/connectors/slack/scope.d.ts +2 -8
- package/dist/connectors/slack/scope.js +2 -8
- package/dist/connectors/slack/signature.d.ts +1 -6
- package/dist/connectors/slack/tenant-routing.d.ts +2 -19
- package/dist/connectors/slack/tenant-routing.js +2 -21
- package/dist/connectors/slack/transform.d.ts +2 -18
- package/dist/connectors/slack/transform.js +2 -18
- package/dist/connectors/slack/types.d.ts +3 -9
- package/dist/connectors/slack/types.js +2 -4
- package/dist/connectors/slack/web-client.js +33 -27
- package/dist/connectors/slack/webhook.d.ts +2 -19
- package/dist/connectors/slack/webhook.js +5 -26
- package/dist/connectors/slack/workspaces.d.ts +4 -24
- package/dist/connectors/slack/workspaces.js +4 -24
- package/dist/consolidate/conflicts.js +6 -14
- package/dist/consolidate/dag-summary.d.ts +8 -0
- package/dist/consolidate/dag-summary.js +41 -0
- package/dist/consolidate/dag.d.ts +5 -28
- package/dist/consolidate/dag.js +14 -75
- package/dist/consolidate/decay.js +7 -19
- package/dist/consolidate/dedupe.d.ts +6 -52
- package/dist/consolidate/dedupe.js +13 -71
- package/dist/consolidate/flush-units.d.ts +3 -4
- package/dist/consolidate/flush-units.js +3 -3
- package/dist/consolidate/half-life-migration.d.ts +3 -26
- package/dist/consolidate/half-life-migration.js +11 -28
- package/dist/consolidate/llm-passes.js +4 -21
- package/dist/consolidate/memory-value-weights.d.ts +2 -13
- package/dist/consolidate/memory-value-weights.js +2 -13
- package/dist/consolidate/memory-value.d.ts +11 -84
- package/dist/consolidate/memory-value.js +16 -104
- package/dist/consolidate/merge.js +10 -31
- package/dist/consolidate/merged-row.js +2 -1
- package/dist/consolidate/physics-pass.js +1 -3
- package/dist/consolidate/replay.d.ts +6 -38
- package/dist/consolidate/replay.js +14 -52
- package/dist/consolidate/run.js +1 -1
- package/dist/consolidate/sleep.d.ts +1 -8
- package/dist/consolidate/sleep.js +5 -17
- package/dist/consolidate/trace.d.ts +3 -18
- package/dist/consolidate/trace.js +3 -18
- package/dist/consolidate/traces.js +6 -22
- package/dist/core/ablation.d.ts +4 -91
- package/dist/core/ablation.js +4 -91
- package/dist/core/ambient.d.ts +1 -8
- package/dist/core/ambient.js +1 -8
- package/dist/core/capture-contract.d.ts +4 -2
- package/dist/core/capture-contract.js +4 -2
- package/dist/core/card.d.ts +4 -1
- package/dist/core/card.js +8 -0
- package/dist/core/compare.d.ts +11 -67
- package/dist/core/compare.js +9 -63
- package/dist/core/config.d.ts +10 -24
- package/dist/core/config.js +13 -14
- package/dist/core/handoff.d.ts +1 -7
- package/dist/core/handoff.js +1 -7
- package/dist/core/memory-quality.js +1 -1
- package/dist/core/memory.d.ts +41 -164
- package/dist/core/memory.js +51 -221
- package/dist/core/package-root.d.ts +3 -0
- package/dist/core/package-root.js +5 -0
- package/dist/core/physics-config.d.ts +1 -4
- package/dist/core/physics-config.js +3 -8
- package/dist/core/physics.d.ts +15 -61
- package/dist/core/physics.js +59 -122
- package/dist/core/project-identity.d.ts +17 -58
- package/dist/core/project-identity.js +17 -38
- package/dist/core/project-remote.js +13 -2
- package/dist/core/raw-append-only.d.ts +5 -0
- package/dist/core/raw-append-only.js +7 -0
- package/dist/core/salience.d.ts +1 -7
- package/dist/core/salience.js +1 -7
- package/dist/dashboard/dashboard-actions.js +2 -2
- package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
- package/dist/dashboard/dashboard-snapshot.js +11 -2
- package/dist/dashboard/dashboard-types.d.ts +2 -1
- package/dist/dashboard/dashboard.d.ts +1 -0
- package/dist/dashboard/dashboard.js +50 -4
- package/dist/db/busy.d.ts +1 -1
- package/dist/db/busy.js +17 -8
- package/dist/db/connect.d.ts +1 -0
- package/dist/db/connect.js +3 -3
- package/dist/db/migrate.js +3 -3
- package/dist/db/migrations/types.d.ts +2 -5
- package/dist/db/migrations/v14.js +2 -3
- package/dist/db/migrations/v15.js +2 -8
- package/dist/db/migrations/v16.js +2 -3
- package/dist/db/migrations/v17.js +2 -3
- package/dist/db/migrations/v19.js +2 -5
- package/dist/db/migrations/v20.js +2 -7
- package/dist/db/migrations/v22.js +4 -17
- package/dist/db/migrations/v23.js +3 -14
- package/dist/db/migrations/v24.js +2 -4
- package/dist/db/migrations/v25.js +3 -8
- package/dist/db/migrations/v26.js +2 -13
- package/dist/db/migrations/v27.js +3 -11
- package/dist/db/migrations/v28.js +2 -14
- package/dist/db/migrations/v29.js +4 -18
- package/dist/db/migrations/v30.js +4 -16
- package/dist/db/migrations/v31.js +2 -15
- package/dist/db/migrations/v32.js +4 -22
- package/dist/db/migrations/v33.js +2 -15
- package/dist/db/migrations/v34.js +2 -11
- package/dist/db/migrations/v35.js +2 -11
- package/dist/db/migrations/v36.js +2 -11
- package/dist/db/migrations/v37.js +8 -33
- package/dist/db/migrations/v38.js +5 -38
- package/dist/db/migrations/v39.js +9 -20
- package/dist/db/migrations/v40.js +2 -9
- package/dist/db/migrations/v41.js +2 -24
- package/dist/db/migrations/v43.js +1 -1
- package/dist/db/migrations/v44.js +2 -8
- package/dist/db/migrations/v45.js +2 -7
- package/dist/db/migrations/v47.js +2 -3
- package/dist/db/migrations/v51.js +1 -1
- package/dist/db/open.d.ts +2 -0
- package/dist/db/open.js +17 -1
- package/dist/db/physics-state.d.ts +6 -22
- package/dist/db/physics-state.js +25 -36
- package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
- package/dist/db/raw-archive-mirror-cleanup.js +2 -17
- package/dist/db/vector-store.d.ts +2 -0
- package/dist/db/vector-store.js +8 -1
- package/dist/doctor.js +74 -19
- package/dist/entry/session-text.js +2 -1
- package/dist/eval/eval-stats.d.ts +15 -53
- package/dist/eval/eval-stats.js +12 -42
- package/dist/eval/eval-suite.d.ts +2 -13
- package/dist/eval/eval-suite.js +74 -34
- package/dist/eval/eval.d.ts +6 -24
- package/dist/eval/eval.js +7 -34
- package/dist/eval/judgment.d.ts +0 -3
- package/dist/eval/judgment.js +19 -11
- package/dist/extensions/openclaw-plugin/index.js +1 -1
- package/dist/graph/extract.d.ts +5 -27
- package/dist/graph/extract.js +7 -33
- package/dist/graph/recall.d.ts +7 -20
- package/dist/graph/recall.js +14 -76
- package/dist/graph/stream.d.ts +7 -39
- package/dist/graph/stream.js +11 -34
- package/dist/graph/view.d.ts +9 -35
- package/dist/graph/view.js +11 -39
- package/dist/hooks/codex-wrapper.js +2 -2
- package/dist/hooks/copilot.js +2 -1
- package/dist/hooks/hook-blocks.d.ts +6 -2
- package/dist/hooks/hook-blocks.js +37 -124
- package/dist/hooks/json-hooks.d.ts +4 -36
- package/dist/hooks/json-hooks.js +18 -57
- package/dist/hooks/opencode.d.ts +0 -38
- package/dist/hooks/opencode.js +9 -76
- package/dist/hooks/shared.d.ts +8 -17
- package/dist/hooks/shared.js +29 -20
- package/dist/importers/core.d.ts +12 -37
- package/dist/importers/core.js +9 -27
- package/dist/importers/markdown-parse.d.ts +8 -22
- package/dist/importers/markdown-parse.js +8 -25
- package/dist/importers/markdown.js +3 -12
- package/dist/importers/sources.js +7 -35
- package/dist/importers/vault.d.ts +2 -8
- package/dist/importers/vault.js +25 -81
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/learn/autolearn.d.ts +14 -41
- package/dist/learn/autolearn.js +14 -41
- package/dist/learn/extract.js +2 -4
- package/dist/learn/forward-claim-detector.d.ts +6 -30
- package/dist/learn/forward-claim-detector.js +14 -66
- package/dist/learn/invalidation.d.ts +6 -18
- package/dist/learn/invalidation.js +9 -26
- package/dist/mcp/admin-tools.js +3 -5
- package/dist/mcp/memory-tools.js +4 -9
- package/dist/mcp/protocol.d.ts +8 -26
- package/dist/mcp/protocol.js +3 -6
- package/dist/mcp/recall-tools.js +3 -3
- package/dist/mcp/request.d.ts +3 -11
- package/dist/mcp/request.js +10 -26
- package/dist/mcp/server.d.ts +3 -9
- package/dist/mcp/server.js +5 -16
- package/dist/mcp/session-state.d.ts +1 -1
- package/dist/mcp/session-state.js +5 -11
- package/dist/mcp/stdio.d.ts +2 -6
- package/dist/mcp/stdio.js +48 -12
- package/dist/mcp/tools.js +5 -3
- package/dist/objects/customer-notes.d.ts +7 -42
- package/dist/objects/customer-notes.js +7 -48
- package/dist/objects/decisions.d.ts +12 -50
- package/dist/objects/decisions.js +15 -53
- package/dist/objects/incidents.d.ts +7 -38
- package/dist/objects/incidents.js +7 -41
- package/dist/objects/policies.d.ts +11 -89
- package/dist/objects/policies.js +11 -98
- package/dist/objects/processes.d.ts +7 -52
- package/dist/objects/processes.js +7 -61
- package/dist/objects/project-briefs.d.ts +11 -55
- package/dist/objects/project-briefs.js +14 -75
- package/dist/objects/skills.d.ts +7 -42
- package/dist/objects/skills.js +8 -54
- package/dist/postinstall.js +6 -19
- package/dist/predictions/planning-fallacy.d.ts +11 -34
- package/dist/rerankers/clef.js +3 -31
- package/dist/rerankers/cross-encoder.js +4 -6
- package/dist/rerankers/jev.js +9 -6
- package/dist/rerankers/llm.d.ts +2 -11
- package/dist/rerankers/llm.js +14 -14
- package/dist/rerankers/outage-warning.d.ts +2 -1
- package/dist/rerankers/outage-warning.js +2 -1
- package/dist/rerankers/remote.d.ts +1 -0
- package/dist/rerankers/remote.js +2 -0
- package/dist/rerankers/types.d.ts +2 -14
- package/dist/search/boosts.d.ts +0 -2
- package/dist/search/boosts.js +2 -2
- package/dist/search/goal-boost.d.ts +23 -0
- package/dist/search/goal-boost.js +90 -0
- package/dist/search/hybrid.d.ts +2 -0
- package/dist/search/multihop.js +2 -3
- package/dist/search/path-context.d.ts +5 -18
- package/dist/search/path-context.js +5 -18
- package/dist/search/physics-search.js +11 -8
- package/dist/search/rrf.d.ts +7 -35
- package/dist/search/rrf.js +5 -30
- package/dist/search/vector.d.ts +7 -0
- package/dist/search/vector.js +35 -5
- package/dist/server/auth.d.ts +9 -28
- package/dist/server/auth.js +32 -25
- package/dist/server/boot.d.ts +2 -21
- package/dist/server/boot.js +63 -96
- package/dist/server/client-ip.d.ts +3 -19
- package/dist/server/client-ip.js +5 -28
- package/dist/server/defaults.d.ts +3 -0
- package/dist/server/defaults.js +4 -0
- package/dist/server/key-check-bounds.d.ts +2 -1
- package/dist/server/lifecycle.d.ts +5 -4
- package/dist/server/lifecycle.js +19 -4
- package/dist/server/mcp-http.js +10 -44
- package/dist/server/rate-limit.d.ts +5 -18
- package/dist/server/rate-limit.js +4 -13
- package/dist/server/request.d.ts +4 -8
- package/dist/server/request.js +9 -17
- package/dist/server/route-table.js +42 -49
- package/dist/server/routes/admin.js +22 -28
- package/dist/server/routes/customer-notes.js +7 -12
- package/dist/server/routes/decisions.js +10 -17
- package/dist/server/routes/incidents.js +12 -20
- package/dist/server/routes/memories.js +12 -32
- package/dist/server/routes/object-routes.d.ts +0 -5
- package/dist/server/routes/object-routes.js +7 -15
- package/dist/server/routes/policies.js +10 -18
- package/dist/server/routes/predictions.js +13 -25
- package/dist/server/routes/processes.js +16 -26
- package/dist/server/routes/project-briefs.js +9 -16
- package/dist/server/routes/recall.js +10 -35
- package/dist/server/routes/skills.js +8 -18
- package/dist/server/server-detect.d.ts +9 -53
- package/dist/server/server-detect.js +24 -90
- package/dist/server/sleep-offload.js +4 -1
- package/dist/server/types.d.ts +12 -10
- package/dist/server/validation.d.ts +3 -1
- package/dist/server/validation.js +10 -23
- package/dist/server.d.ts +2 -2
- package/dist/server.js +3 -2
- package/dist/sharing/global-store.d.ts +19 -0
- package/dist/sharing/global-store.js +75 -0
- package/dist/sharing/global-sync.d.ts +6 -0
- package/dist/sharing/global-sync.js +80 -0
- package/dist/sharing/project-merge.d.ts +4 -5
- package/dist/sharing/project-merge.js +9 -7
- package/dist/sharing/scope.d.ts +4 -11
- package/dist/sharing/scope.js +4 -11
- package/dist/sharing/search-both.d.ts +60 -0
- package/dist/sharing/search-both.js +138 -0
- package/dist/sharing/share.d.ts +38 -0
- package/dist/sharing/share.js +226 -0
- package/dist/store/ambient.js +4 -9
- package/dist/store/audit-event.d.ts +4 -12
- package/dist/store/audit-event.js +4 -12
- package/dist/store/audit.d.ts +2 -5
- package/dist/store/audit.js +4 -12
- package/dist/store/auth.d.ts +6 -6
- package/dist/store/auth.js +10 -9
- package/dist/store/candidates.d.ts +20 -3
- package/dist/store/candidates.js +77 -48
- package/dist/store/card-detail.d.ts +2 -1
- package/dist/store/card-detail.js +2 -1
- package/dist/store/cards.d.ts +14 -9
- package/dist/store/cards.js +72 -126
- package/dist/store/conflicts.d.ts +4 -21
- package/dist/store/conflicts.js +71 -150
- package/dist/store/connectors/github.d.ts +10 -10
- package/dist/store/connectors/github.js +10 -10
- package/dist/store/dashboard-reads.js +4 -8
- package/dist/store/delete-and-batch.d.ts +11 -31
- package/dist/store/delete-and-batch.js +48 -64
- package/dist/store/delivery-recorder.d.ts +8 -4
- package/dist/store/delivery-recorder.js +25 -15
- package/dist/store/diagnostics.js +6 -13
- package/dist/store/dormant.d.ts +7 -29
- package/dist/store/dormant.js +15 -56
- package/dist/store/embeddings/index.d.ts +11 -80
- package/dist/store/embeddings/index.js +71 -207
- package/dist/store/embeddings/local.js +15 -32
- package/dist/store/embeddings/provider.d.ts +16 -53
- package/dist/store/embeddings/provider.js +41 -69
- package/dist/store/entry-reads.d.ts +21 -57
- package/dist/store/entry-reads.js +65 -126
- package/dist/store/entry-row.d.ts +6 -35
- package/dist/store/entry-row.js +9 -37
- package/dist/store/entry-writes.d.ts +10 -16
- package/dist/store/entry-writes.js +17 -35
- package/dist/store/goals.d.ts +3 -40
- package/dist/store/goals.js +21 -160
- package/dist/store/graph-queue.d.ts +6 -22
- package/dist/store/graph-queue.js +14 -45
- package/dist/store/graph-reads.d.ts +11 -35
- package/dist/store/graph-reads.js +20 -58
- package/dist/store/graph-rows.d.ts +3 -6
- package/dist/store/graph-rows.js +6 -9
- package/dist/store/graph-view-rows.d.ts +2 -1
- package/dist/store/graph-view-rows.js +2 -1
- package/dist/store/graph-writes.d.ts +6 -31
- package/dist/store/graph-writes.js +13 -37
- package/dist/store/half-life.d.ts +2 -1
- package/dist/store/half-life.js +14 -16
- package/dist/store/handoffs.d.ts +5 -11
- package/dist/store/handoffs.js +16 -34
- package/dist/store/index-and-stats.d.ts +6 -19
- package/dist/store/index-and-stats.js +34 -82
- package/dist/store/markdown.d.ts +2 -6
- package/dist/store/markdown.js +21 -20
- package/dist/store/mirrors.d.ts +2 -6
- package/dist/store/mirrors.js +14 -23
- package/dist/store/open.js +6 -13
- package/dist/store/planning-fallacy-evidence.d.ts +2 -30
- package/dist/store/planning-fallacy-evidence.js +8 -37
- package/dist/store/port.d.ts +82 -79
- package/dist/store/predictions.d.ts +11 -51
- package/dist/store/predictions.js +38 -119
- package/dist/{cli → store}/quality-repair.js +15 -31
- package/dist/store/raw-archive.d.ts +4 -16
- package/dist/store/raw-archive.js +14 -29
- package/dist/store/recall-scope.d.ts +19 -79
- package/dist/store/recall-scope.js +21 -82
- package/dist/store/recall-trace.d.ts +10 -77
- package/dist/store/recall-trace.js +19 -95
- package/dist/store/rejected-values.js +7 -19
- package/dist/store/rejection.d.ts +12 -58
- package/dist/store/rejection.js +13 -65
- package/dist/store/report-reads.d.ts +6 -0
- package/dist/store/report-reads.js +29 -0
- package/dist/store/rows.d.ts +9 -19
- package/dist/store/rows.js +36 -34
- package/dist/store/rule-sql.d.ts +5 -0
- package/dist/store/rule-sql.js +37 -0
- package/dist/store/search-rows.d.ts +7 -38
- package/dist/store/search-rows.js +14 -50
- package/dist/store/sessions.d.ts +10 -47
- package/dist/store/sessions.js +17 -73
- package/dist/store/sqlite/connector-events-group.js +2 -2
- package/dist/store/sqlite/entry-writes-group.js +2 -2
- package/dist/store/sqlite/error-codec.js +4 -2
- package/dist/store/sqlite/executor.d.ts +2 -1
- package/dist/store/sqlite/executor.js +2 -1
- package/dist/store/sqlite/local.d.ts +3 -3
- package/dist/store/sqlite/local.js +1 -0
- package/dist/store/sqlite/object-rows.js +6 -3
- package/dist/store/sqlite/objects-group.js +4 -2
- package/dist/store/sqlite/quarantine-group.js +2 -2
- package/dist/store/sqlite/store.d.ts +1 -4
- package/dist/store/sqlite/store.js +2 -3
- package/dist/store/sqlite/vector-reads-group.js +2 -2
- package/dist/store/sqlite/worker-jobs.js +1 -1
- package/dist/store/sqlite/worker-ops.d.ts +13 -2
- package/dist/store/sqlite/worker-ops.js +13 -2
- package/dist/store/sqlite/worker-store.js +5 -2
- package/dist/store/summaries.d.ts +10 -62
- package/dist/store/summaries.js +34 -146
- package/dist/store/summary-dirty.js +1 -1
- package/dist/store/tenant-lookup.d.ts +6 -1
- package/dist/store/tenant-lookup.js +7 -0
- package/dist/store/tenant.d.ts +2 -16
- package/dist/store/tenant.js +4 -19
- package/dist/store/token-ledger.d.ts +13 -43
- package/dist/store/token-ledger.js +19 -50
- package/dist/store/usage-reports.js +5 -13
- package/dist/store/vector-index.d.ts +46 -0
- package/dist/store/vector-index.js +170 -0
- package/dist/store/working-memory.d.ts +6 -25
- package/dist/store/working-memory.js +18 -52
- package/dist/store/yaml.d.ts +1 -5
- package/dist/store/yaml.js +2 -6
- package/dist/support-bundle.js +7 -5
- package/dist/trust/reject-flow.js +1 -3
- package/dist/util/anthropic-messages.js +14 -2
- package/dist/util/atomic-write.d.ts +2 -1
- package/dist/util/atomic-write.js +35 -4
- package/dist/util/capped-json.d.ts +6 -0
- package/dist/util/capped-json.js +46 -0
- package/dist/util/crash-handlers.d.ts +8 -1
- package/dist/util/crash-handlers.js +52 -10
- package/dist/util/env.d.ts +13 -6
- package/dist/util/env.js +14 -7
- package/dist/util/home-path.d.ts +2 -1
- package/dist/util/home-path.js +4 -2
- package/dist/util/http-retry.d.ts +3 -1
- package/dist/util/http-retry.js +26 -5
- package/dist/util/log.d.ts +3 -2
- package/dist/util/log.js +25 -9
- package/dist/util/request-scope.d.ts +2 -1
- package/dist/util/request-scope.js +2 -1
- package/dist/util/secret-detect.d.ts +5 -30
- package/dist/util/secret-detect.js +13 -39
- package/dist/util/stored-json.d.ts +1 -1
- package/dist/util/stored-json.js +1 -1
- package/dist/util/token-text.d.ts +1 -4
- package/dist/util/token-text.js +1 -4
- package/dist/util/transcript-tail.d.ts +2 -0
- package/dist/util/transcript-tail.js +24 -23
- package/dist/util/version.d.ts +5 -20
- package/dist/util/version.js +5 -20
- package/extensions/openclaw-plugin/index.ts +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/connectors/github/cli-impl.d.ts +0 -25
- package/dist/sharing/shared.d.ts +0 -187
- package/dist/sharing/shared.js +0 -563
- package/dist/store/vector-writes.d.ts +0 -13
- package/dist/store/vector-writes.js +0 -89
- /package/dist/{cli → store}/quality-repair.d.ts +0 -0
package/dist/cli/serve.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
// Long-running verbs: `hippo dashboard`, `hippo mcp` and `hippo serve`.
|
|
2
2
|
import { installCrashHandlers } from '../util/crash-handlers.js';
|
|
3
|
-
import { envPort, envRequireAuth, envTlsCert, envTlsKey } from '../util/env.js';
|
|
3
|
+
import { envAllowKeylessLocal, envPort, envRequireAuth, envTlsCert, envTlsKey } from '../util/env.js';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
import { printError } from './output.js';
|
|
7
7
|
import { stringFlagOrExit, stringFlag } from './flag-values.js';
|
|
8
8
|
import { requireInit } from './shared.js';
|
|
9
9
|
import { errorMessage } from '../util/log.js';
|
|
10
|
+
import { CliExit } from './exit.js';
|
|
11
|
+
import { DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT } from '../server/defaults.js';
|
|
10
12
|
export async function handleDashboard({ hippoRoot, flags }) {
|
|
11
13
|
requireInit(hippoRoot);
|
|
12
14
|
const port = parseInt(String(flags['port'] ?? '3333'), 10);
|
|
13
15
|
const { serveDashboard } = await import('../dashboard/dashboard.js');
|
|
14
|
-
serveDashboard(hippoRoot, port);
|
|
15
|
-
// A
|
|
16
|
+
serveDashboard(hippoRoot, port, undefined, { handleSignals: true });
|
|
17
|
+
// A later throw ends in one log line and exit 1, as it does for serve and mcp; a busy port is reported by the dashboard itself.
|
|
16
18
|
installCrashHandlers('dashboard');
|
|
17
19
|
await new Promise(() => { }); // run until Ctrl+C
|
|
18
20
|
}
|
|
@@ -35,33 +37,40 @@ function readTlsFiles(flags) {
|
|
|
35
37
|
return undefined;
|
|
36
38
|
if (certPath === undefined || keyPath === undefined) {
|
|
37
39
|
printError('hippo serve: TLS needs both a certificate and a key: --tls-cert and --tls-key, or HIPPO_TLS_CERT and HIPPO_TLS_KEY.');
|
|
38
|
-
|
|
40
|
+
throw new CliExit(1);
|
|
39
41
|
}
|
|
40
42
|
try {
|
|
41
43
|
return { cert: fs.readFileSync(certPath), key: fs.readFileSync(keyPath) };
|
|
42
44
|
}
|
|
43
45
|
catch (err) {
|
|
44
46
|
printError(`hippo serve: cannot read the TLS files: ${errorMessage(err)}`);
|
|
45
|
-
|
|
47
|
+
throw new CliExit(1);
|
|
46
48
|
}
|
|
47
49
|
}
|
|
50
|
+
/** Said at every start, so the key rule is a choice an operator sees, and an upgrade that changed it explains itself. */
|
|
51
|
+
function keyRuleLine() {
|
|
52
|
+
if (envRequireAuth())
|
|
53
|
+
return 'every request needs an API key (HIPPO_REQUIRE_AUTH=1)';
|
|
54
|
+
if (envAllowKeylessLocal()) {
|
|
55
|
+
return 'requests from this machine need no API key and act as host admin (HIPPO_ALLOW_KEYLESS_LOCAL=1); unset it to require a key on every request';
|
|
56
|
+
}
|
|
57
|
+
return 'every request needs an API key: mint one with `hippo auth create` and send it as "Authorization: Bearer <key>" ' +
|
|
58
|
+
'(the hippo CLI reads HIPPO_API_KEY). To let requests from this machine in without a key, start with HIPPO_ALLOW_KEYLESS_LOCAL=1';
|
|
59
|
+
}
|
|
48
60
|
export async function handleServe({ hippoRoot, flags }) {
|
|
49
61
|
requireInit(hippoRoot);
|
|
50
|
-
const portRaw = flags['port'] ?? envPort() ??
|
|
62
|
+
const portRaw = flags['port'] ?? envPort() ?? DEFAULT_SERVER_PORT;
|
|
51
63
|
const port = Number(portRaw);
|
|
52
64
|
if (!Number.isFinite(port) || port < 0) {
|
|
53
65
|
printError(`Invalid --port: ${String(portRaw)}`);
|
|
54
|
-
|
|
66
|
+
throw new CliExit(1);
|
|
55
67
|
}
|
|
56
|
-
const host = stringFlag(flags, 'host') ??
|
|
68
|
+
const host = stringFlag(flags, 'host') ?? DEFAULT_SERVER_HOST;
|
|
57
69
|
const tls = readTlsFiles(flags);
|
|
58
70
|
const { serve } = await import('../server.js');
|
|
59
71
|
const handle = await serve({ hippoRoot, port, host, handleSignals: true, tls });
|
|
60
72
|
console.log(`hippo serve listening on ${handle.url} (pid ${process.pid})`);
|
|
61
|
-
|
|
62
|
-
if (!envRequireAuth()) {
|
|
63
|
-
console.log('local requests need no API key and act as host admin; set HIPPO_REQUIRE_AUTH=1 to require a key on every request');
|
|
64
|
-
}
|
|
73
|
+
console.log(keyRuleLine());
|
|
65
74
|
console.log(`pidfile: ${path.join(hippoRoot, 'server.pid')}`);
|
|
66
75
|
console.log('press Ctrl+C to stop');
|
|
67
76
|
// The SIGINT/SIGTERM handlers stop the server and exit. Hang until then.
|
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
import { type CliFlags, type CommandContext } from './flag-values.js';
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* get SIGTERM'd mid-consolidation.
|
|
7
|
-
*
|
|
8
|
-
* So we do the minimum inline (read stdin for transcript_path), then spawn
|
|
9
|
-
* a fully detached Node child that runs sleep → capture and exit the parent
|
|
10
|
-
* immediately. The child writes to the log file and survives TUI teardown;
|
|
11
|
-
* the next SessionStart reads the log via `hippo last-sleep`.
|
|
12
|
-
*/
|
|
13
|
-
export declare function cmdSessionEnd(hippoRoot: string, flags: CliFlags): Promise<void>;
|
|
14
|
-
export declare function cmdSessionEndWorker(hippoRoot: string, flags: CliFlags): Promise<void>;
|
|
2
|
+
/** SessionEnd entry: TUI teardown kills children still running, so read stdin inline, spawn a detached child that runs sleep then capture, and exit.
|
|
3
|
+
* The child logs to a file that the next SessionStart reads via `hippo last-sleep`. */
|
|
4
|
+
export declare function handleSessionEnd({ hippoRoot, tenantId, flags }: CommandContext): Promise<void>;
|
|
5
|
+
export declare function handleSessionEndWorker({ hippoRoot, tenantId, flags }: CommandContext): Promise<void>;
|
|
15
6
|
/** Quotes one cmd.exe argument; each `%` leaves the quotes as `^%`, so no %NAME% pair can expand. */
|
|
16
7
|
export declare function quoteCmdArg(arg: string): string;
|
|
17
8
|
/** cmd.exe arguments that run a .cmd or .bat shim with every forwarded argument delivered verbatim. */
|
|
18
9
|
export declare function cmdShimArgs(shimPath: string, forwardArgs: readonly string[]): string[];
|
|
19
|
-
export declare function
|
|
20
|
-
export declare function cmdCodexSessionEndWorker(hippoRoot: string, flags: CliFlags): Promise<void>;
|
|
10
|
+
export declare function handleCodexRun({ hippoRoot, tenantId, args }: CommandContext): void;
|
|
11
|
+
export declare function cmdCodexSessionEndWorker(hippoRoot: string, tenantId: string, flags: CliFlags): Promise<void>;
|
|
12
|
+
export declare function handleCodexSessionEndWorker({ hippoRoot, tenantId, flags }: CommandContext): Promise<void>;
|
|
21
13
|
export declare function handlePreCompact({ hippoRoot, flags }: CommandContext): Promise<void>;
|
|
22
14
|
export declare function handlePostCompact({ hippoRoot, flags }: CommandContext): Promise<void>;
|
|
23
|
-
export declare function handleCaptureError({ hippoRoot, flags }: CommandContext): Promise<void>;
|
|
24
|
-
export declare function handleCompactResume({ hippoRoot }: CommandContext): Promise<void>;
|
|
25
|
-
export declare function handleCapture({ hippoRoot, flags }: CommandContext): Promise<void>;
|
|
15
|
+
export declare function handleCaptureError({ hippoRoot, tenantId, flags }: CommandContext): Promise<void>;
|
|
16
|
+
export declare function handleCompactResume({ hippoRoot, tenantId }: CommandContext): Promise<void>;
|
|
17
|
+
export declare function handleCapture({ hippoRoot, tenantId, flags }: CommandContext): Promise<void>;
|
|
26
18
|
//# sourceMappingURL=session-hooks.d.ts.map
|
|
@@ -9,14 +9,13 @@ import { isInitialized } from '../store/open.js';
|
|
|
9
9
|
import { loadActiveTaskSnapshot, loadFreshActiveTaskSnapshot, closeTaskSnapshotsForSession, listSessionEvents, } from '../store/sessions.js';
|
|
10
10
|
import { writeSessionEndHandoff } from '../store/handoffs.js';
|
|
11
11
|
import { readSessionScan, recordSessionDigest } from '../capture/session-digest.js';
|
|
12
|
-
import { openHippoDb, closeHippoDb } from '../db/index.js';
|
|
13
12
|
import { captureToolFailure } from '../capture/capture-error.js';
|
|
14
13
|
import { readApiCalls, recordRereads, } from '../store/token-ledger.js';
|
|
15
14
|
import { estimateTokens } from '../util/token-text.js';
|
|
16
15
|
import { currentMachine, importSessionFolder } from '../agent-memories/sync.js';
|
|
17
16
|
import { summaryLine } from '../agent-memories/report.js';
|
|
18
17
|
import { resolveProjectIdentity } from '../core/project-identity.js';
|
|
19
|
-
import { getGlobalRoot } from '../sharing/
|
|
18
|
+
import { getGlobalRoot } from '../sharing/global-store.js';
|
|
20
19
|
import { cmdCapture } from '../capture/command.js';
|
|
21
20
|
import { cmdPreCompact, cmdPostCompact } from '../capture/compact.js';
|
|
22
21
|
import { transcriptWorkingState } from '../capture/working-state.js';
|
|
@@ -30,7 +29,6 @@ import { truncateCodePointSafe } from '../util/transcript-tail.js';
|
|
|
30
29
|
import { COMPACTION_DB_WAIT_MS } from '../capture/compaction-record.js';
|
|
31
30
|
import { COMPACT_RESUME_EVENT_CONTENT_CAP, COMPACT_RESUME_MAX_AGE_MS, compactResumeText } from '../api/context-render.js';
|
|
32
31
|
import { normaliseHookPayload, readHookStdin, readStdinBounded } from './stdin.js';
|
|
33
|
-
import { resolveTenantId } from '../store/tenant.js';
|
|
34
32
|
import { errorMessage, log } from '../util/log.js';
|
|
35
33
|
import { bookLedgerTurn } from '../api/ledger-db.js';
|
|
36
34
|
import { flushDeliveryRecorder } from '../api/prompt-hook.js';
|
|
@@ -38,26 +36,17 @@ import { printError } from './output.js';
|
|
|
38
36
|
import { cmdLastSleep } from './last-sleep.js';
|
|
39
37
|
import { readCompactResumePayload } from './compact-resume-payload.js';
|
|
40
38
|
import { boolFlag, flagIsTrue, stringFlag } from './flag-values.js';
|
|
41
|
-
import { logSessionEndImport, appendSessionEndCloseLog, resetHookInjection, hookStoreRoot, hookRuntime, payloadCwdRoot, runHookWithStores, inPilotHoldout, startDeliveryRecorder } from './hook-runtime.js';
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*
|
|
45
|
-
|
|
46
|
-
* memories here — the UserPromptSubmit hook already re-injects those every
|
|
47
|
-
* turn, so duplicating them here would double token cost for nothing.
|
|
48
|
-
*
|
|
49
|
-
* Same exit-0/crash-safety contract as `hippo pre-compact`: every path
|
|
50
|
-
* exits 0. A malformed payload or a store read failure
|
|
51
|
-
* degrades to empty stdout, never a thrown error — a failing SessionStart
|
|
52
|
-
* hook must not pollute session startup.
|
|
53
|
-
*/
|
|
54
|
-
function cmdCompactResume(hippoRoot, stdinText, stdinTimedOut) {
|
|
39
|
+
import { logSessionEndImport, appendSessionEndCloseLog, reportSessionEndFailure, resetHookInjection, hookStoreRoot, hookRuntime, payloadCwdRoot, runHookWithStores, inPilotHoldout, startDeliveryRecorder, } from './hook-runtime.js';
|
|
40
|
+
import { CliExit } from './exit.js';
|
|
41
|
+
/** SessionStart(compact) injector: prints the task snapshot and session trail lost to compaction; no pinned memories (UserPromptSubmit re-injects them).
|
|
42
|
+
* Every path exits 0: a malformed payload or store read failure degrades to empty stdout, never a throw. */
|
|
43
|
+
function cmdCompactResume(hippoRoot, tenantId, stdinText, stdinTimedOut) {
|
|
55
44
|
let rec = null;
|
|
56
45
|
try {
|
|
57
46
|
// Gate on the non-exiting isInitialized check first: the store reads below call initStore, which would
|
|
58
47
|
// silently create a store in a project that never ran `hippo init`, and this hook fires globally.
|
|
59
48
|
if (!isInitialized(hippoRoot)) {
|
|
60
|
-
|
|
49
|
+
throw new CliExit(0);
|
|
61
50
|
}
|
|
62
51
|
const payloadState = readCompactResumePayload(stdinText, stdinTimedOut);
|
|
63
52
|
let suppressOutput = payloadState.suppressOutput;
|
|
@@ -65,23 +54,24 @@ function cmdCompactResume(hippoRoot, stdinText, stdinTimedOut) {
|
|
|
65
54
|
if (payloadState.boundary)
|
|
66
55
|
rec = startDeliveryRecorder(hippoRoot, stdinText, 'claude-code', 'compact-resume');
|
|
67
56
|
// A compaction follows a prompt or SessionStart that booked the arm, so this only reads it.
|
|
68
|
-
if (!suppressOutput && payloadSessionId !== null && inPilotHoldout(hippoRoot,
|
|
57
|
+
if (!suppressOutput && payloadSessionId !== null && inPilotHoldout(hippoRoot, tenantId, payloadSessionId, false)) {
|
|
69
58
|
suppressOutput = true;
|
|
70
59
|
rec?.disabled();
|
|
71
60
|
}
|
|
72
61
|
if (!suppressOutput)
|
|
73
|
-
restoreCompactSnapshot(hippoRoot, payloadSessionId, rec);
|
|
62
|
+
restoreCompactSnapshot(hippoRoot, tenantId, payloadSessionId, rec);
|
|
74
63
|
}
|
|
75
64
|
catch (err) {
|
|
65
|
+
if (err instanceof CliExit)
|
|
66
|
+
throw err;
|
|
76
67
|
// Empty stdout on any store error, never a crashed SessionStart; the reason goes to stderr, which the model never sees.
|
|
77
68
|
log.warn(`hippo compact-resume: skipped: ${errorMessage(err)}`);
|
|
78
69
|
}
|
|
79
70
|
// A no-op when the token ledger's handle already wrote the row; exit would drop it otherwise.
|
|
80
71
|
flushDeliveryRecorder(rec);
|
|
81
|
-
|
|
72
|
+
throw new CliExit(0);
|
|
82
73
|
}
|
|
83
|
-
function restoreCompactSnapshot(hippoRoot, payloadSessionId, rec) {
|
|
84
|
-
const tenantId = resolveTenantId({});
|
|
74
|
+
function restoreCompactSnapshot(hippoRoot, tenantId, payloadSessionId, rec) {
|
|
85
75
|
const snapshot = loadFreshActiveTaskSnapshot(hippoRoot, tenantId, { maxAgeMs: COMPACT_RESUME_MAX_AGE_MS });
|
|
86
76
|
// Concurrent sessions must not cross-restore. Only suppress when BOTH ids are present and differ;
|
|
87
77
|
// either side missing, or a manual invocation with no payload session_id, still prints.
|
|
@@ -115,18 +105,9 @@ function restoreCompactSnapshot(hippoRoot, payloadSessionId, rec) {
|
|
|
115
105
|
delivery: (write) => flushDeliveryRecorder(rec, write),
|
|
116
106
|
});
|
|
117
107
|
}
|
|
118
|
-
/**
|
|
119
|
-
*
|
|
120
|
-
|
|
121
|
-
* the parent returns. Running sleep + capture synchronously here means both
|
|
122
|
-
* get SIGTERM'd mid-consolidation.
|
|
123
|
-
*
|
|
124
|
-
* So we do the minimum inline (read stdin for transcript_path), then spawn
|
|
125
|
-
* a fully detached Node child that runs sleep → capture and exit the parent
|
|
126
|
-
* immediately. The child writes to the log file and survives TUI teardown;
|
|
127
|
-
* the next SessionStart reads the log via `hippo last-sleep`.
|
|
128
|
-
*/
|
|
129
|
-
export async function cmdSessionEnd(hippoRoot, flags) {
|
|
108
|
+
/** SessionEnd entry: TUI teardown kills children still running, so read stdin inline, spawn a detached child that runs sleep then capture, and exit.
|
|
109
|
+
* The child logs to a file that the next SessionStart reads via `hippo last-sleep`. */
|
|
110
|
+
export async function handleSessionEnd({ hippoRoot, tenantId, flags }) {
|
|
130
111
|
const runtime = hookRuntime(flags);
|
|
131
112
|
const turn = flagIsTrue(flags, 'turn');
|
|
132
113
|
// Copilot's hook command carries no path, since one quoted into it would need escaping for each shell; the log goes where the hook table used to point.
|
|
@@ -141,6 +122,8 @@ export async function cmdSessionEnd(hippoRoot, flags) {
|
|
|
141
122
|
// Before the spawn, since the worker finds its store from the folder it inherits.
|
|
142
123
|
const root = payloadCwdRoot(hippoRoot, stdinText, runtime);
|
|
143
124
|
const input = stop ?? sessionEndInput(stdinText, raw.timedOut, runtime);
|
|
125
|
+
// Only a host payload ends a session: a manual run and a reply's end (turn mode) are not boundaries.
|
|
126
|
+
const rec = !turn && input !== null && !input.manual ? startDeliveryRecorder(hookStoreRoot(root), stdinText, runtime, 'session-end') : null;
|
|
144
127
|
const sessionId = input?.sessionId ?? null;
|
|
145
128
|
// Resolved here because only this process saw the payload; the worker captures just the path it is handed.
|
|
146
129
|
// Always a hook, so never scan: an empty stdin here is not a manual run. The Copilot CLI's sessionEnd names no transcript, so its log is found by id.
|
|
@@ -159,9 +142,16 @@ export async function cmdSessionEnd(hippoRoot, flags) {
|
|
|
159
142
|
flags['transcript'] = transcriptPath;
|
|
160
143
|
if (sessionId)
|
|
161
144
|
flags['session-id'] = sessionId;
|
|
162
|
-
|
|
145
|
+
try {
|
|
146
|
+
await cmdSessionEndWorker(root, tenantId, flags);
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
await runHookWithStores(() => flushDeliveryRecorder(rec));
|
|
150
|
+
}
|
|
163
151
|
return;
|
|
164
152
|
}
|
|
153
|
+
// After the spawn, so a locked store delays only the row; the hook's short lock wait bounds it.
|
|
154
|
+
await runHookWithStores(() => flushDeliveryRecorder(rec));
|
|
165
155
|
}
|
|
166
156
|
/** What the session-end payload named; null for one hippo refuses or one that never arrived, and the worker then runs with neither value. */
|
|
167
157
|
function sessionEndInput(stdinText, timedOut, runtime) {
|
|
@@ -198,15 +188,18 @@ function vscodeStopInput(raw) {
|
|
|
198
188
|
const receipt = readVscodeStop(raw.text, raw.timedOut);
|
|
199
189
|
return receipt.status === 'received' && receipt.input.sessionId !== null && SESSION_ID_RE.test(receipt.input.sessionId) ? receipt.input : null;
|
|
200
190
|
}
|
|
201
|
-
|
|
191
|
+
async function cmdSessionEndWorker(hippoRoot, tenantId, flags) {
|
|
202
192
|
const sessionId = flags['session-id'];
|
|
203
|
-
await runSessionWorker(isStringValue(sessionId) ? sessionId : null, flagIsTrue(flags, 'turn') ? 'turn' : 'full', (mode) => sessionEndWork(hippoRoot, flags, mode));
|
|
193
|
+
await runSessionWorker(isStringValue(sessionId) ? sessionId : null, flagIsTrue(flags, 'turn') ? 'turn' : 'full', (mode) => sessionEndWork(hippoRoot, tenantId, flags, mode));
|
|
194
|
+
}
|
|
195
|
+
export function handleSessionEndWorker({ hippoRoot, tenantId, flags }) {
|
|
196
|
+
return cmdSessionEndWorker(hippoRoot, tenantId, flags);
|
|
204
197
|
}
|
|
205
|
-
async function sessionEndWork(hippoRoot, flags, mode) {
|
|
198
|
+
async function sessionEndWork(hippoRoot, tenantId, flags, mode) {
|
|
206
199
|
const transcriptPath = stringFlag(flags, 'transcript');
|
|
207
200
|
const closeLogFile = stringFlag(flags, 'log-file') ?? null;
|
|
208
201
|
const closeSessionId = stringFlag(flags, 'session-id') ?? null;
|
|
209
|
-
const rereadLog = await bookSessionRereads(hippoRoot, transcriptPath, closeSessionId)
|
|
202
|
+
const rereadLog = await bookSessionRereads(hippoRoot, tenantId, transcriptPath, closeSessionId)
|
|
210
203
|
.catch((err) => [`re-read count failed: ${errorMessage(err)}`]);
|
|
211
204
|
// Sleep starts the log file afresh, so the lines go in after it; on exit too, in case sleep exits the process.
|
|
212
205
|
const flushRereadLog = () => { for (const line of rereadLog.splice(0))
|
|
@@ -220,38 +213,37 @@ async function sessionEndWork(hippoRoot, flags, mode) {
|
|
|
220
213
|
return;
|
|
221
214
|
}
|
|
222
215
|
if (mode === 'turn' && closeSessionId)
|
|
223
|
-
await sleepIfDue(hippoRoot, flags, closeLogFile, transcriptPath, closeSessionId);
|
|
216
|
+
await sleepIfDue(hippoRoot, tenantId, flags, closeLogFile, transcriptPath, closeSessionId);
|
|
224
217
|
else
|
|
225
|
-
await sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath);
|
|
218
|
+
await sleepProjectStore(hippoRoot, tenantId, flags, closeLogFile, transcriptPath);
|
|
226
219
|
flushRereadLog();
|
|
227
220
|
const digestLog = (message) => appendSessionEndCloseLog(closeLogFile, message);
|
|
228
221
|
const scan = transcriptPath ? readSessionScan(transcriptPath, digestLog) : null;
|
|
229
|
-
const capture = (turns) => captureEndedSession(hippoRoot, store, flags, transcriptPath, turns);
|
|
222
|
+
const capture = (turns) => captureEndedSession(hippoRoot, tenantId, store, flags, transcriptPath, turns);
|
|
230
223
|
if (mode === 'turn')
|
|
231
224
|
captureNewTurns(transcriptPath, closeSessionId, scan, capture, digestLog);
|
|
232
225
|
else
|
|
233
226
|
capture(scan?.turns);
|
|
234
227
|
recordSessionDigest(hippoRoot, scan, {
|
|
235
228
|
key: closeSessionId || path.basename(transcriptPath ?? '', '.jsonl'),
|
|
236
|
-
tenantId
|
|
229
|
+
tenantId,
|
|
237
230
|
log: digestLog,
|
|
238
231
|
});
|
|
239
|
-
// Close only this session's snapshot, after sleep+capture
|
|
240
|
-
//
|
|
241
|
-
// The handoff is written first, while the snapshot writeSessionEndHandoff reads is still active.
|
|
232
|
+
// Close only this session's snapshot, after sleep+capture; if session-end never fires (crash, kill -9) the freshness bound in
|
|
233
|
+
// loadFreshActiveTaskSnapshot is the backstop. The handoff is written first, while the snapshot writeSessionEndHandoff reads is active.
|
|
242
234
|
if (closeSessionId)
|
|
243
|
-
writeEndHandoff(store, closeSessionId, transcriptPath, closeLogFile, mode === 'turn');
|
|
235
|
+
writeEndHandoff(store, tenantId, closeSessionId, transcriptPath, closeLogFile, mode === 'turn');
|
|
244
236
|
if (mode === 'turn') {
|
|
245
237
|
// The chat goes on after a reply, so its snapshot stays for the next compaction to restore.
|
|
246
238
|
appendSessionEndCloseLog(closeLogFile, 'skip snapshot close: turn mode');
|
|
247
239
|
return;
|
|
248
240
|
}
|
|
249
|
-
closeEndedSessionSnapshot(store, closeSessionId, closeLogFile);
|
|
241
|
+
closeEndedSessionSnapshot(store, tenantId, closeSessionId, closeLogFile);
|
|
250
242
|
}
|
|
251
|
-
function closeEndedSessionSnapshot(store, closeSessionId, closeLogFile) {
|
|
243
|
+
function closeEndedSessionSnapshot(store, tenantId, closeSessionId, closeLogFile) {
|
|
252
244
|
try {
|
|
253
245
|
if (closeSessionId) {
|
|
254
|
-
const closed = closeTaskSnapshotsForSession(store,
|
|
246
|
+
const closed = closeTaskSnapshotsForSession(store, tenantId, closeSessionId);
|
|
255
247
|
appendSessionEndCloseLog(closeLogFile, `closed ${closed} active snapshot(s) for session ${closeSessionId}`);
|
|
256
248
|
}
|
|
257
249
|
else {
|
|
@@ -262,15 +254,15 @@ function closeEndedSessionSnapshot(store, closeSessionId, closeLogFile) {
|
|
|
262
254
|
appendSessionEndCloseLog(closeLogFile, `snapshot close failed: ${errorMessage(err)}`);
|
|
263
255
|
}
|
|
264
256
|
}
|
|
265
|
-
async function sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath) {
|
|
257
|
+
async function sleepProjectStore(hippoRoot, tenantId, flags, closeLogFile, transcriptPath) {
|
|
266
258
|
// Sleeping the global store from here would learn this folder's git commits into it; it has its own daily sleep.
|
|
267
259
|
if (isInitialized(hippoRoot)) {
|
|
268
260
|
try {
|
|
269
|
-
await (await import('./sleep.js')).cmdSleep(hippoRoot, flags);
|
|
261
|
+
await (await import('./sleep.js')).cmdSleep(hippoRoot, tenantId, flags);
|
|
270
262
|
}
|
|
271
263
|
catch (err) {
|
|
272
|
-
// cmdSleep writes its failure line only
|
|
273
|
-
|
|
264
|
+
// cmdSleep writes its own failure line only once its log tee is open, and capture runs regardless.
|
|
265
|
+
reportSessionEndFailure(closeLogFile, 'session-end: sleep', err);
|
|
274
266
|
}
|
|
275
267
|
}
|
|
276
268
|
else {
|
|
@@ -279,18 +271,18 @@ async function sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath)
|
|
|
279
271
|
}
|
|
280
272
|
}
|
|
281
273
|
/** A close after every reply sleeps only at the MCP server's auto-sleep threshold; each line starts the log afresh, as a sleep does. */
|
|
282
|
-
async function sleepIfDue(hippoRoot, flags, closeLogFile, transcriptPath, sessionId) {
|
|
274
|
+
async function sleepIfDue(hippoRoot, tenantId, flags, closeLogFile, transcriptPath, sessionId) {
|
|
283
275
|
if (!isInitialized(hippoRoot))
|
|
284
|
-
return sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath);
|
|
276
|
+
return sleepProjectStore(hippoRoot, tenantId, flags, closeLogFile, transcriptPath);
|
|
285
277
|
const prefix = `turn close, session ${sessionId}`;
|
|
286
278
|
try {
|
|
287
|
-
const { enabled, count, threshold, due } = autoSleepDue(hippoRoot,
|
|
279
|
+
const { enabled, count, threshold, due } = autoSleepDue(hippoRoot, tenantId, loadConfig(hippoRoot).autoSleep);
|
|
288
280
|
if (!due) {
|
|
289
281
|
const why = enabled ? `${count} new memories, threshold ${threshold}` : 'auto-sleep is off';
|
|
290
282
|
appendSessionEndCloseLog(closeLogFile, `${prefix}: skip sleep, ${why}`, { startFresh: true });
|
|
291
283
|
return;
|
|
292
284
|
}
|
|
293
|
-
await sleepProjectStore(hippoRoot, flags, closeLogFile, transcriptPath);
|
|
285
|
+
await sleepProjectStore(hippoRoot, tenantId, flags, closeLogFile, transcriptPath);
|
|
294
286
|
appendSessionEndCloseLog(closeLogFile, `${prefix}: ran sleep at ${count} new memories (threshold ${threshold})`);
|
|
295
287
|
}
|
|
296
288
|
catch (err) {
|
|
@@ -312,7 +304,7 @@ function captureNewTurns(transcriptPath, sessionId, scan, capture, log) {
|
|
|
312
304
|
saveTurnPosition(sessionId, transcriptPath, scan.turns, log);
|
|
313
305
|
}
|
|
314
306
|
/** True when capture ran to the end, so a turn close may move its cursor past these turns. */
|
|
315
|
-
function captureEndedSession(hippoRoot, store, flags, transcriptPath, turns) {
|
|
307
|
+
function captureEndedSession(hippoRoot, tenantId, store, flags, transcriptPath, turns) {
|
|
316
308
|
try {
|
|
317
309
|
const logFile = stringFlag(flags, 'log-file');
|
|
318
310
|
// With no stdin of its own, capture would read this as a manual run and scan every project.
|
|
@@ -326,7 +318,7 @@ function captureEndedSession(hippoRoot, store, flags, transcriptPath, turns) {
|
|
|
326
318
|
logFile,
|
|
327
319
|
dryRun: false,
|
|
328
320
|
global: false,
|
|
329
|
-
tenantId
|
|
321
|
+
tenantId,
|
|
330
322
|
// In the global store, rows would otherwise read as user-global and show up in every project.
|
|
331
323
|
originProject: store === hippoRoot ? undefined : resolveProjectIdentity(process.cwd()),
|
|
332
324
|
sessionTurns: turns,
|
|
@@ -334,13 +326,12 @@ function captureEndedSession(hippoRoot, store, flags, transcriptPath, turns) {
|
|
|
334
326
|
return true;
|
|
335
327
|
}
|
|
336
328
|
catch (err) {
|
|
337
|
-
log
|
|
329
|
+
reportSessionEndFailure(stringFlag(flags, 'log-file') ?? null, 'session-end: capture', err);
|
|
338
330
|
return false;
|
|
339
331
|
}
|
|
340
332
|
}
|
|
341
|
-
function writeEndHandoff(store, closeSessionId, transcriptPath, closeLogFile, inPlace = false) {
|
|
333
|
+
function writeEndHandoff(store, tenantId, closeSessionId, transcriptPath, closeLogFile, inPlace = false) {
|
|
342
334
|
try {
|
|
343
|
-
const tenantId = resolveTenantId({});
|
|
344
335
|
const ownSnapshot = loadActiveTaskSnapshot(store, tenantId)?.session_id === closeSessionId;
|
|
345
336
|
// A never-compacted session has no snapshot; read even when it has one, as another session's PreCompact can take the slot before the write.
|
|
346
337
|
const derived = transcriptPath
|
|
@@ -361,7 +352,7 @@ function writeEndHandoff(store, closeSessionId, transcriptPath, closeLogFile, in
|
|
|
361
352
|
}
|
|
362
353
|
}
|
|
363
354
|
/** Books the ending session's re-reads in each store its ledger rows can land in (project and global); returns the log lines. */
|
|
364
|
-
async function bookSessionRereads(hippoRoot, transcriptPath, sessionId) {
|
|
355
|
+
async function bookSessionRereads(hippoRoot, tenantId, transcriptPath, sessionId) {
|
|
365
356
|
if (!transcriptPath || !sessionId)
|
|
366
357
|
return [];
|
|
367
358
|
let read;
|
|
@@ -376,13 +367,7 @@ async function bookSessionRereads(hippoRoot, transcriptPath, sessionId) {
|
|
|
376
367
|
let tokens = 0;
|
|
377
368
|
for (const root of roots) {
|
|
378
369
|
try {
|
|
379
|
-
|
|
380
|
-
try {
|
|
381
|
-
tokens += recordRereads(db, resolveTenantId({}), sessionId, read.calls);
|
|
382
|
-
}
|
|
383
|
-
finally {
|
|
384
|
-
closeHippoDb(db);
|
|
385
|
-
}
|
|
370
|
+
tokens += recordRereads(root, tenantId, sessionId, read.calls);
|
|
386
371
|
}
|
|
387
372
|
catch (err) {
|
|
388
373
|
lines.push(`re-read count failed: ${errorMessage(err)}`);
|
|
@@ -397,6 +382,7 @@ function loadCodexWrapperMetadata() {
|
|
|
397
382
|
if (!fs.existsSync(metadataPath)) {
|
|
398
383
|
throw new Error('Codex wrapper is not installed. Run `hippo hook install codex` first.');
|
|
399
384
|
}
|
|
385
|
+
// SAFETY: the file is the one installCodexWrapper wrote; handleCodexRun reads only logFile and realCodexPath from it.
|
|
400
386
|
return JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
|
401
387
|
}
|
|
402
388
|
/** Quotes one cmd.exe argument; each `%` leaves the quotes as `^%`, so no %NAME% pair can expand. */
|
|
@@ -423,7 +409,7 @@ function spawnRealCodex(realCodexPath, forwardArgs, cwd) {
|
|
|
423
409
|
}
|
|
424
410
|
return spawn(realCodexPath, forwardArgs, { cwd, stdio: 'inherit', windowsHide: false });
|
|
425
411
|
}
|
|
426
|
-
export function
|
|
412
|
+
export function handleCodexRun({ hippoRoot, tenantId, args }) {
|
|
427
413
|
const metadata = loadCodexWrapperMetadata();
|
|
428
414
|
const startedAtMs = Date.now();
|
|
429
415
|
// Codex reads CODEX_HOME at each launch, so resolve it now, not from the install-time metadata.
|
|
@@ -441,11 +427,11 @@ export function cmdCodexRun(hippoRoot, args) {
|
|
|
441
427
|
process.exit(1);
|
|
442
428
|
});
|
|
443
429
|
child.on('exit', async (code, signal) => {
|
|
444
|
-
await launchCodexSessionEndWorker(hippoRoot, historyPath, startOffsetBytes, startedAtMs, metadata.logFile);
|
|
430
|
+
await launchCodexSessionEndWorker(hippoRoot, tenantId, historyPath, startOffsetBytes, startedAtMs, metadata.logFile);
|
|
445
431
|
exitLikeChild(code, signal);
|
|
446
432
|
});
|
|
447
433
|
}
|
|
448
|
-
async function launchCodexSessionEndWorker(hippoRoot, historyPath, startOffsetBytes, startedAtMs, logFile) {
|
|
434
|
+
async function launchCodexSessionEndWorker(hippoRoot, tenantId, historyPath, startOffsetBytes, startedAtMs, logFile) {
|
|
449
435
|
const workerArgs = [
|
|
450
436
|
process.argv[1],
|
|
451
437
|
'__codex-session-end-worker',
|
|
@@ -460,30 +446,40 @@ async function launchCodexSessionEndWorker(hippoRoot, historyPath, startOffsetBy
|
|
|
460
446
|
'--log-file',
|
|
461
447
|
logFile,
|
|
462
448
|
];
|
|
449
|
+
if (await detachedWorkerStarted(workerArgs))
|
|
450
|
+
return;
|
|
451
|
+
// Awaited so the sleep write can't be killed by the exit calls below.
|
|
463
452
|
try {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
453
|
+
await cmdCodexSessionEndWorker(hippoRoot, tenantId, {
|
|
454
|
+
'codex-home': path.dirname(historyPath),
|
|
455
|
+
'history-path': historyPath,
|
|
456
|
+
'start-offset': String(startOffsetBytes),
|
|
457
|
+
'started-at': String(startedAtMs),
|
|
458
|
+
'log-file': logFile,
|
|
468
459
|
});
|
|
469
|
-
worker.unref();
|
|
470
460
|
}
|
|
471
|
-
catch (
|
|
472
|
-
log.debug(`codex run: the session-end
|
|
473
|
-
|
|
461
|
+
catch (inlineErr) {
|
|
462
|
+
log.debug(`codex run: the inline session-end failed: ${errorMessage(inlineErr)}`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
/** Resolves true once the detached worker is running, false when the spawn fails, whether it throws or reports later. */
|
|
466
|
+
function detachedWorkerStarted(workerArgs) {
|
|
467
|
+
return new Promise((resolve) => {
|
|
468
|
+
const failed = (reason) => {
|
|
469
|
+
log.debug(`codex run: the session-end worker did not spawn, running inline: ${reason}`);
|
|
470
|
+
resolve(false);
|
|
471
|
+
};
|
|
474
472
|
try {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
'log-file': logFile,
|
|
481
|
-
});
|
|
473
|
+
const worker = spawn(process.execPath, workerArgs, { detached: true, stdio: 'ignore', windowsHide: true });
|
|
474
|
+
// An async spawn failure (ENOENT, EAGAIN) arrives as an 'error' event, which a try cannot catch.
|
|
475
|
+
worker.on('error', (err) => failed(err.message));
|
|
476
|
+
worker.once('spawn', () => resolve(true));
|
|
477
|
+
worker.unref();
|
|
482
478
|
}
|
|
483
|
-
catch (
|
|
484
|
-
|
|
479
|
+
catch (err) {
|
|
480
|
+
failed(errorMessage(err));
|
|
485
481
|
}
|
|
486
|
-
}
|
|
482
|
+
});
|
|
487
483
|
}
|
|
488
484
|
function exitLikeChild(code, signal) {
|
|
489
485
|
if (signal) {
|
|
@@ -498,7 +494,7 @@ function exitLikeChild(code, signal) {
|
|
|
498
494
|
}
|
|
499
495
|
process.exit(code ?? 0);
|
|
500
496
|
}
|
|
501
|
-
export async function cmdCodexSessionEndWorker(hippoRoot, flags) {
|
|
497
|
+
export async function cmdCodexSessionEndWorker(hippoRoot, tenantId, flags) {
|
|
502
498
|
const logFile = stringFlag(flags, 'log-file');
|
|
503
499
|
// Like the other hooks: project store, else global; a folder with neither must not get one made.
|
|
504
500
|
const store = hookStoreRoot(hippoRoot);
|
|
@@ -506,17 +502,20 @@ export async function cmdCodexSessionEndWorker(hippoRoot, flags) {
|
|
|
506
502
|
appendSessionEndCloseLog(logFile ?? null, 'skip: no hippo store for this folder or globally', { startFresh: true });
|
|
507
503
|
return;
|
|
508
504
|
}
|
|
509
|
-
await sleepCodexProjectStore(hippoRoot, logFile);
|
|
510
|
-
captureCodexTranscript(hippoRoot, store, flags, logFile);
|
|
505
|
+
await sleepCodexProjectStore(hippoRoot, tenantId, logFile);
|
|
506
|
+
captureCodexTranscript(hippoRoot, tenantId, store, flags, logFile);
|
|
507
|
+
}
|
|
508
|
+
export function handleCodexSessionEndWorker({ hippoRoot, tenantId, flags }) {
|
|
509
|
+
return cmdCodexSessionEndWorker(hippoRoot, tenantId, flags);
|
|
511
510
|
}
|
|
512
|
-
async function sleepCodexProjectStore(hippoRoot, logFile) {
|
|
511
|
+
async function sleepCodexProjectStore(hippoRoot, tenantId, logFile) {
|
|
513
512
|
// Sleeping the global store from here would learn this folder's git commits into it; it has its own daily sleep.
|
|
514
513
|
if (isInitialized(hippoRoot)) {
|
|
515
514
|
try {
|
|
516
|
-
await (await import('./sleep.js')).cmdSleep(hippoRoot, logFile ? { 'log-file': logFile } : {});
|
|
515
|
+
await (await import('./sleep.js')).cmdSleep(hippoRoot, tenantId, logFile ? { 'log-file': logFile } : {});
|
|
517
516
|
}
|
|
518
517
|
catch (err) {
|
|
519
|
-
|
|
518
|
+
reportSessionEndFailure(logFile ?? null, 'codex session-end: sleep', err);
|
|
520
519
|
}
|
|
521
520
|
}
|
|
522
521
|
else {
|
|
@@ -524,7 +523,7 @@ async function sleepCodexProjectStore(hippoRoot, logFile) {
|
|
|
524
523
|
logSessionEndImport(logFile ?? null, undefined);
|
|
525
524
|
}
|
|
526
525
|
}
|
|
527
|
-
function captureCodexTranscript(hippoRoot, store, flags, logFile) {
|
|
526
|
+
function captureCodexTranscript(hippoRoot, tenantId, store, flags, logFile) {
|
|
528
527
|
try {
|
|
529
528
|
const codexHome = stringFlag(flags, 'codex-home') ?? resolveCodexWrapperPaths().codexHome;
|
|
530
529
|
const historyPath = stringFlag(flags, 'history-path') ?? path.join(codexHome, 'history.jsonl');
|
|
@@ -549,7 +548,7 @@ function captureCodexTranscript(hippoRoot, store, flags, logFile) {
|
|
|
549
548
|
logFile,
|
|
550
549
|
dryRun: false,
|
|
551
550
|
global: false,
|
|
552
|
-
tenantId
|
|
551
|
+
tenantId,
|
|
553
552
|
originProject: store === hippoRoot ? undefined : resolveProjectIdentity(process.cwd()),
|
|
554
553
|
sessionTurns: scan?.turns,
|
|
555
554
|
};
|
|
@@ -557,13 +556,13 @@ function captureCodexTranscript(hippoRoot, store, flags, logFile) {
|
|
|
557
556
|
cmdCapture(store, captureOpts);
|
|
558
557
|
}
|
|
559
558
|
catch (err) {
|
|
560
|
-
|
|
559
|
+
reportSessionEndFailure(logFile ?? null, 'codex session-end: capture', err);
|
|
561
560
|
}
|
|
562
561
|
// The Codex wrapper passes no session id, so the rollout file names the session.
|
|
563
|
-
recordSessionDigest(hippoRoot, scan, { key: path.basename(transcriptPath, '.jsonl'), tenantId
|
|
562
|
+
recordSessionDigest(hippoRoot, scan, { key: path.basename(transcriptPath, '.jsonl'), tenantId, log: digestLog });
|
|
564
563
|
}
|
|
565
564
|
catch (err) {
|
|
566
|
-
|
|
565
|
+
reportSessionEndFailure(logFile ?? null, 'codex session-end: transcript scan or digest', err);
|
|
567
566
|
}
|
|
568
567
|
}
|
|
569
568
|
export async function handlePreCompact({ hippoRoot, flags }) {
|
|
@@ -596,7 +595,7 @@ export async function handlePostCompact({ hippoRoot, flags }) {
|
|
|
596
595
|
stdinText: text,
|
|
597
596
|
stdinTimedOut: timedOut,
|
|
598
597
|
logFile: logFlag === true || logFlag === false || Array.isArray(logFlag) ? undefined : logFlag,
|
|
599
|
-
// Passed in, since capture
|
|
598
|
+
// Passed in, since src/capture/ importing the sync would close an import cycle.
|
|
600
599
|
afterSave: (transcriptPath, cwd, log) => {
|
|
601
600
|
const report = importSessionFolder(store, transcriptPath, cwd, { machine: currentMachine(), busyWaitMs: COMPACTION_DB_WAIT_MS });
|
|
602
601
|
const summary = summaryLine(report);
|
|
@@ -609,7 +608,7 @@ export async function handlePostCompact({ hippoRoot, flags }) {
|
|
|
609
608
|
if (line !== null && line !== undefined)
|
|
610
609
|
console.log(line);
|
|
611
610
|
}
|
|
612
|
-
export async function handleCaptureError({ hippoRoot, flags }) {
|
|
611
|
+
export async function handleCaptureError({ hippoRoot, tenantId, flags }) {
|
|
613
612
|
// PostToolUseFailure hook: every path exits 0, and nothing is created
|
|
614
613
|
// when no store exists (the hook fires in every directory).
|
|
615
614
|
const { text } = await readHookStdin();
|
|
@@ -619,7 +618,7 @@ export async function handleCaptureError({ hippoRoot, flags }) {
|
|
|
619
618
|
if (isInitialized(root) && payload) {
|
|
620
619
|
// SAFETY: JSON.parse returns a JSON value by definition.
|
|
621
620
|
const failure = JSON.parse(payload);
|
|
622
|
-
await runHookWithStores(() => captureToolFailure(root,
|
|
621
|
+
await runHookWithStores(() => captureToolFailure(root, tenantId, failure));
|
|
623
622
|
}
|
|
624
623
|
}
|
|
625
624
|
catch (err) {
|
|
@@ -627,14 +626,14 @@ export async function handleCaptureError({ hippoRoot, flags }) {
|
|
|
627
626
|
log.warn(`failure capture skipped: ${errorMessage(err)}`);
|
|
628
627
|
}
|
|
629
628
|
}
|
|
630
|
-
export async function handleCompactResume({ hippoRoot }) {
|
|
629
|
+
export async function handleCompactResume({ hippoRoot, tenantId }) {
|
|
631
630
|
const { text: stdinText, timedOut: stdinTimedOut } = await readHookStdin();
|
|
632
631
|
await runHookWithStores(() => {
|
|
633
632
|
resetHookInjection(hippoRoot, stdinText, 'compact');
|
|
634
|
-
cmdCompactResume(hookStoreRoot(hippoRoot), stdinText, stdinTimedOut);
|
|
633
|
+
cmdCompactResume(hookStoreRoot(hippoRoot), tenantId, stdinText, stdinTimedOut);
|
|
635
634
|
});
|
|
636
635
|
}
|
|
637
|
-
export async function handleCapture({ hippoRoot, flags }) {
|
|
636
|
+
export async function handleCapture({ hippoRoot, tenantId, flags }) {
|
|
638
637
|
let captureSource = null;
|
|
639
638
|
let captureFile;
|
|
640
639
|
let transcriptPath;
|
|
@@ -655,10 +654,10 @@ export async function handleCapture({ hippoRoot, flags }) {
|
|
|
655
654
|
}
|
|
656
655
|
if (!captureSource) {
|
|
657
656
|
printError('Usage: hippo capture --stdin|--file <path>|--last-session [--transcript <path>] [--log-file <path>] [--dry-run] [--global]');
|
|
658
|
-
|
|
657
|
+
throw new CliExit(1);
|
|
659
658
|
}
|
|
660
659
|
// Bounded, and only when last-session has no explicit path: the
|
|
661
|
-
// --stdin source keeps its own blocking read in capture
|
|
660
|
+
// --stdin source keeps its own blocking read in src/capture/ by design.
|
|
662
661
|
const bounded = captureSource === 'last-session' && !transcriptPath
|
|
663
662
|
? await readHookStdin()
|
|
664
663
|
: { text: undefined, timedOut: false };
|
|
@@ -671,7 +670,7 @@ export async function handleCapture({ hippoRoot, flags }) {
|
|
|
671
670
|
logFile: stringFlag(flags, 'log-file'),
|
|
672
671
|
dryRun: boolFlag(flags, 'dry-run'),
|
|
673
672
|
global: boolFlag(flags, 'global'),
|
|
674
|
-
tenantId
|
|
673
|
+
tenantId,
|
|
675
674
|
});
|
|
676
675
|
}
|
|
677
676
|
//# sourceMappingURL=session-hooks.js.map
|