hippo-memory 1.70.0 → 1.72.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 +2 -2
- package/dist/agent-memories/apply.d.ts +0 -11
- package/dist/agent-memories/apply.js +6 -21
- package/dist/agent-memories/claude-code.d.ts +4 -2
- package/dist/agent-memories/claude-code.js +15 -6
- package/dist/agent-memories/codex.js +1 -1
- package/dist/agent-memories/copilot.d.ts +1 -3
- package/dist/agent-memories/copilot.js +1 -17
- 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/project-folds.d.ts +10 -0
- package/dist/agent-memories/project-folds.js +34 -0
- package/dist/agent-memories/report.js +2 -1
- package/dist/agent-memories/sync.d.ts +4 -2
- package/dist/agent-memories/sync.js +18 -11
- package/dist/api/assemble.d.ts +7 -44
- package/dist/api/assemble.js +3 -23
- package/dist/api/audit.d.ts +33 -1
- package/dist/api/audit.js +48 -1
- package/dist/api/auth.d.ts +20 -26
- package/dist/api/auth.js +43 -29
- package/dist/api/auto-sleep.d.ts +5 -2
- package/dist/api/auto-sleep.js +9 -5
- package/dist/api/availability.d.ts +2 -15
- package/dist/api/availability.js +4 -18
- package/dist/api/cards.d.ts +42 -0
- package/dist/api/cards.js +52 -0
- package/dist/api/conflicts.d.ts +28 -0
- package/dist/api/conflicts.js +61 -0
- package/dist/api/context-render.js +4 -3
- package/dist/api/context-select.js +12 -15
- package/dist/api/context-types.d.ts +10 -35
- package/dist/api/context.d.ts +5 -22
- package/dist/api/context.js +38 -46
- package/dist/api/continuity.d.ts +47 -0
- package/dist/api/continuity.js +66 -0
- package/dist/{cli → api}/correction-latency.d.ts +2 -14
- package/dist/{cli → api}/correction-latency.js +2 -14
- package/dist/api/dormant.d.ts +5 -21
- package/dist/api/dormant.js +11 -28
- package/dist/api/drill-down.d.ts +7 -46
- package/dist/api/drill-down.js +6 -27
- package/dist/api/embeddings.d.ts +17 -0
- package/dist/api/embeddings.js +28 -0
- package/dist/api/error-reply.d.ts +8 -0
- package/dist/api/error-reply.js +21 -0
- package/dist/api/forget.d.ts +11 -26
- package/dist/api/forget.js +23 -35
- package/dist/api/goals.d.ts +1 -1
- package/dist/api/goals.js +5 -9
- package/dist/api/graph.d.ts +8 -0
- package/dist/api/graph.js +7 -0
- package/dist/api/index.d.ts +6 -2
- package/dist/api/index.js +6 -2
- package/dist/api/instruction-detect.js +21 -6
- package/dist/api/learn.d.ts +4 -0
- package/dist/api/learn.js +53 -27
- package/dist/api/ledger-db.d.ts +2 -5
- package/dist/api/ledger-db.js +5 -35
- package/dist/api/memories.d.ts +23 -0
- package/dist/api/memories.js +46 -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/outcome.js +1 -1
- package/dist/api/pilot-arm.d.ts +1 -11
- package/dist/api/pilot-arm.js +5 -45
- package/dist/api/predictions.d.ts +11 -0
- package/dist/api/predictions.js +24 -0
- package/dist/api/projects.d.ts +21 -0
- package/dist/api/projects.js +24 -0
- package/dist/api/promote.d.ts +13 -17
- package/dist/api/promote.js +12 -20
- package/dist/api/prompt-hook.d.ts +19 -6
- package/dist/api/prompt-hook.js +54 -13
- package/dist/api/provenance-coverage.d.ts +14 -0
- package/dist/{cli → api}/provenance-coverage.js +2 -6
- package/dist/api/recall-cli.d.ts +58 -0
- package/dist/api/recall-cli.js +103 -0
- package/dist/api/recall-core.js +17 -9
- 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 +21 -15
- package/dist/api/recall-request.js +1 -1
- package/dist/api/recall-types.d.ts +64 -304
- package/dist/api/recall.d.ts +3 -34
- package/dist/api/recall.js +63 -89
- 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 +20 -2
- package/dist/api/remember.js +16 -3
- package/dist/api/session-end.d.ts +22 -0
- package/dist/api/session-end.js +101 -0
- package/dist/api/sleep-run.d.ts +2 -4
- package/dist/api/sleep-run.js +28 -28
- package/dist/api/sleep.d.ts +9 -28
- package/dist/api/status.d.ts +24 -0
- package/dist/api/status.js +40 -0
- package/dist/api/store-init.d.ts +4 -0
- package/dist/api/store-init.js +9 -0
- package/dist/api/tokens.d.ts +3 -10
- package/dist/api/tokens.js +4 -11
- package/dist/api/types.d.ts +8 -29
- package/dist/api/types.js +10 -23
- package/dist/capture/caller-session.d.ts +0 -3
- package/dist/capture/caller-session.js +1 -12
- package/dist/capture/capture-error.d.ts +2 -2
- package/dist/capture/capture-error.js +23 -18
- package/dist/capture/codex-patch.js +3 -1
- package/dist/capture/command.d.ts +4 -12
- package/dist/capture/command.js +39 -114
- package/dist/capture/compact.d.ts +4 -15
- package/dist/capture/compact.js +26 -30
- package/dist/capture/compaction-items-caller.js +11 -20
- package/dist/capture/compaction-record.d.ts +7 -93
- package/dist/capture/compaction-record.js +34 -399
- package/dist/capture/compaction-spool.d.ts +5 -3
- package/dist/capture/compaction-spool.js +21 -7
- package/dist/capture/copilot-transcript.d.ts +2 -1
- package/dist/capture/copilot-transcript.js +2 -1
- package/dist/capture/extract.d.ts +5 -2
- package/dist/capture/extract.js +4 -3
- package/dist/capture/failure-caller.d.ts +1 -1
- package/dist/capture/failure-caller.js +21 -16
- package/dist/capture/failure-reading.d.ts +2 -1
- package/dist/capture/failure-reading.js +7 -9
- package/dist/capture/pre-compact-caller.js +5 -4
- package/dist/capture/session-digest.d.ts +1 -1
- package/dist/capture/session-digest.js +17 -10
- package/dist/capture/session-end-caller.js +2 -1
- package/dist/capture/session-worker.js +3 -4
- package/dist/capture/transcript.d.ts +4 -11
- package/dist/capture/transcript.js +10 -21
- package/dist/capture/working-state.d.ts +4 -2
- package/dist/capture/working-state.js +4 -2
- package/dist/cli/api-context.d.ts +3 -0
- package/dist/cli/api-context.js +6 -0
- package/dist/cli/audit-prune.d.ts +1 -59
- package/dist/cli/audit-prune.js +2 -61
- package/dist/cli/audit.d.ts +1 -1
- package/dist/cli/audit.js +42 -43
- package/dist/cli/auth.d.ts +2 -2
- package/dist/cli/auth.js +61 -44
- package/dist/cli/briefs.d.ts +1 -4
- package/dist/cli/briefs.js +42 -301
- package/dist/cli/card.d.ts +2 -2
- package/dist/cli/card.js +63 -56
- package/dist/cli/client.d.ts +12 -27
- package/dist/cli/client.js +41 -44
- package/dist/cli/compact-resume-payload.js +4 -3
- package/dist/cli/context.d.ts +2 -3
- package/dist/cli/context.js +22 -18
- package/dist/cli/continuity.d.ts +6 -6
- package/dist/cli/continuity.js +81 -86
- package/dist/cli/curate.d.ts +13 -17
- package/dist/cli/curate.js +88 -116
- package/dist/cli/dag.d.ts +4 -4
- package/dist/cli/dag.js +55 -34
- package/dist/cli/decisions.d.ts +2 -4
- package/dist/cli/decisions.js +18 -309
- package/dist/cli/eval.d.ts +1 -1
- package/dist/cli/eval.js +27 -26
- package/dist/cli/exit.d.ts +6 -0
- package/dist/cli/exit.js +11 -0
- package/dist/cli/explain.d.ts +2 -3
- package/dist/cli/explain.js +25 -27
- package/dist/cli/flag-values.d.ts +6 -1
- package/dist/cli/flag-values.js +42 -15
- package/dist/cli/flags.d.ts +0 -288
- package/dist/cli/flags.js +3 -138
- 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/graph.d.ts +3 -0
- package/dist/cli/graph.js +83 -0
- package/dist/cli/hook-runtime.d.ts +12 -32
- package/dist/cli/hook-runtime.js +21 -64
- package/dist/cli/incidents.d.ts +3 -0
- package/dist/cli/incidents.js +112 -0
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.js +33 -30
- package/dist/cli/install-steps.d.ts +2 -1
- package/dist/cli/install-steps.js +13 -14
- package/dist/cli/last-sleep.d.ts +2 -1
- package/dist/cli/last-sleep.js +4 -1
- package/dist/cli/lenient-id.d.ts +2 -0
- package/dist/cli/lenient-id.js +13 -0
- package/dist/cli/maintenance.d.ts +5 -5
- package/dist/cli/maintenance.js +37 -43
- package/dist/cli/notes.d.ts +2 -0
- package/dist/cli/notes.js +41 -0
- package/dist/cli/object-verbs.js +4 -3
- package/dist/cli/open-browser.d.ts +14 -0
- package/dist/cli/open-browser.js +26 -0
- package/dist/cli/owner-validation.d.ts +5 -28
- package/dist/cli/owner-validation.js +5 -28
- package/dist/cli/playbooks.d.ts +3 -4
- package/dist/cli/playbooks.js +131 -300
- package/dist/cli/predictions.d.ts +3 -0
- package/dist/cli/predictions.js +175 -0
- package/dist/cli/print.d.ts +2 -5
- package/dist/cli/print.js +3 -5
- package/dist/cli/projects.d.ts +2 -2
- package/dist/cli/projects.js +31 -25
- package/dist/cli/quality-repair-once.d.ts +1 -1
- package/dist/cli/quality-repair-once.js +7 -6
- package/dist/cli/recall.d.ts +2 -4
- package/dist/cli/recall.js +67 -137
- package/dist/cli/refine-llm.d.ts +5 -31
- package/dist/cli/refine-llm.js +23 -50
- package/dist/cli/remember.d.ts +3 -3
- package/dist/cli/remember.js +134 -192
- package/dist/cli/scheduler.d.ts +2 -17
- package/dist/cli/scheduler.js +14 -19
- package/dist/cli/serve.js +23 -14
- package/dist/cli/session-hooks.d.ts +11 -19
- package/dist/cli/session-hooks.js +143 -214
- package/dist/cli/setup.d.ts +4 -4
- package/dist/cli/setup.js +35 -30
- package/dist/cli/shared.d.ts +7 -25
- package/dist/cli/shared.js +17 -60
- package/dist/cli/slack.d.ts +2 -2
- package/dist/cli/slack.js +19 -23
- package/dist/cli/sleep-render.js +6 -3
- package/dist/cli/sleep.d.ts +3 -2
- package/dist/cli/sleep.js +17 -49
- package/dist/cli/status.d.ts +11 -14
- package/dist/cli/status.js +74 -120
- 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 +87 -108
- package/dist/cli/usage.d.ts +0 -79
- package/dist/cli/usage.js +1 -689
- package/dist/cli/verb-row.d.ts +32 -0
- package/dist/cli/verb-row.js +6 -0
- package/dist/cli/verbs/health.d.ts +27 -0
- package/dist/cli/verbs/health.js +232 -0
- package/dist/cli/verbs/memory.d.ts +16 -0
- package/dist/cli/verbs/memory.js +244 -0
- package/dist/cli/verbs/objects.d.ts +20 -0
- package/dist/cli/verbs/objects.js +254 -0
- package/dist/cli/verbs/sessions.d.ts +31 -0
- package/dist/cli/verbs/sessions.js +312 -0
- package/dist/cli/verbs.d.ts +81 -0
- package/dist/cli/verbs.js +7 -0
- package/dist/cli/versioned-verbs.d.ts +51 -0
- package/dist/cli/versioned-verbs.js +79 -0
- package/dist/cli.d.ts +1 -654
- package/dist/cli.js +44 -510
- package/dist/connectors/dlq.d.ts +39 -3
- package/dist/connectors/dlq.js +37 -3
- package/dist/connectors/github/backfill.d.ts +5 -25
- package/dist/connectors/github/backfill.js +26 -52
- 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 +34 -93
- package/dist/connectors/github/ingest.d.ts +4 -12
- package/dist/connectors/github/ingest.js +5 -36
- 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 +3 -16
- package/dist/connectors/github/webhook.js +38 -23
- package/dist/connectors/ingest.d.ts +10 -0
- package/dist/connectors/ingest.js +28 -0
- 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 +51 -90
- package/dist/connectors/slack/ingest.d.ts +4 -9
- package/dist/connectors/slack/ingest.js +4 -30
- 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 +3 -19
- package/dist/connectors/slack/webhook.js +6 -26
- package/dist/connectors/slack/workspaces.d.ts +4 -24
- package/dist/connectors/slack/workspaces.js +4 -24
- package/dist/consolidate/conflicts.js +7 -15
- 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 +29 -84
- package/dist/consolidate/decay.js +7 -19
- package/dist/consolidate/dedupe.d.ts +13 -52
- package/dist/consolidate/dedupe.js +18 -74
- 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 +49 -40
- 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 +18 -105
- package/dist/consolidate/merge.js +12 -33
- package/dist/consolidate/physics-pass.d.ts +6 -1
- package/dist/consolidate/physics-pass.js +27 -9
- package/dist/consolidate/replay.d.ts +6 -38
- package/dist/consolidate/replay.js +25 -56
- package/dist/consolidate/run.js +1 -1
- package/dist/consolidate/sleep.d.ts +1 -8
- package/dist/consolidate/sleep.js +13 -22
- package/dist/consolidate/trace.d.ts +3 -18
- package/dist/consolidate/trace.js +3 -18
- package/dist/consolidate/traces.js +9 -25
- package/dist/core/ablation.d.ts +14 -91
- package/dist/core/ablation.js +16 -91
- package/dist/core/active-scope.d.ts +7 -0
- package/dist/{sharing/scope.js → core/active-scope.js} +5 -12
- package/dist/core/ambient.d.ts +5 -8
- package/dist/core/ambient.js +40 -26
- package/dist/core/api-errors.d.ts +16 -0
- package/dist/core/api-errors.js +20 -0
- 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 +11 -1
- package/dist/core/compaction-timing.d.ts +7 -0
- package/dist/core/compaction-timing.js +9 -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 +20 -16
- package/dist/core/cosine.d.ts +3 -0
- package/dist/core/cosine.js +19 -0
- package/dist/core/handoff.d.ts +1 -7
- package/dist/core/handoff.js +1 -7
- package/dist/core/markdown.d.ts +6 -0
- package/dist/{store → core}/markdown.js +23 -22
- package/dist/core/memory-audit.d.ts +17 -0
- package/dist/core/memory-audit.js +54 -0
- package/dist/core/memory-quality.js +1 -1
- package/dist/core/memory.d.ts +51 -168
- package/dist/core/memory.js +76 -239
- package/dist/{consolidate → core}/merged-row.d.ts +1 -1
- package/dist/{consolidate → core}/merged-row.js +3 -2
- 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 +65 -138
- package/dist/core/prediction.d.ts +3 -0
- package/dist/core/prediction.js +6 -0
- package/dist/core/project-identity.d.ts +20 -58
- package/dist/core/project-identity.js +27 -39
- 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/recall-scope.d.ts +69 -0
- package/dist/core/recall-scope.js +138 -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 +3 -8
- package/dist/db/busy.js +37 -33
- package/dist/db/connect.js +7 -8
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.js +3 -3
- package/dist/db/migrate.js +3 -3
- package/dist/db/migrations/index.d.ts +1 -1
- package/dist/db/migrations/index.js +3 -1
- 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/migrations/v55.d.ts +3 -0
- package/dist/db/migrations/v55.js +17 -0
- package/dist/db/open.d.ts +2 -2
- package/dist/db/open.js +21 -9
- package/dist/db/physics-state.d.ts +6 -22
- package/dist/db/physics-state.js +28 -39
- package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
- package/dist/db/raw-archive-mirror-cleanup.js +2 -17
- package/dist/db/tables.d.ts +2 -0
- package/dist/db/tables.js +6 -2
- package/dist/db/vector-store.d.ts +2 -0
- package/dist/db/vector-store.js +25 -5
- package/dist/db/wal-checkpointer.js +2 -1
- package/dist/doctor.js +85 -27
- package/dist/embeddings/local.d.ts +62 -0
- package/dist/embeddings/local.js +146 -0
- package/dist/embeddings/provider.d.ts +43 -0
- package/dist/{store/embeddings → embeddings}/provider.js +58 -83
- package/dist/embeddings/transformers.d.ts +26 -0
- package/dist/embeddings/transformers.js +89 -0
- package/dist/entry/session-text.d.ts +1 -1
- package/dist/entry/session-text.js +3 -2
- 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 +91 -45
- package/dist/eval/eval.d.ts +6 -24
- package/dist/eval/eval.js +8 -35
- package/dist/eval/judgment.d.ts +0 -3
- package/dist/eval/judgment.js +30 -15
- package/dist/extensions/openclaw-plugin/index.js +1 -1
- package/dist/graph/extract.d.ts +5 -27
- package/dist/graph/extract.js +10 -36
- package/dist/graph/recall.d.ts +7 -20
- package/dist/graph/recall.js +15 -77
- 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 +24 -44
- package/dist/graph/write.d.ts +1 -1
- package/dist/graph/write.js +9 -9
- package/dist/hooks/codex-session.js +3 -2
- package/dist/hooks/codex-wrapper.js +4 -3
- 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 +22 -59
- package/dist/hooks/opencode.d.ts +0 -38
- package/dist/hooks/opencode.js +17 -81
- package/dist/hooks/shared.d.ts +6 -21
- package/dist/hooks/shared.js +31 -33
- package/dist/importers/core.d.ts +12 -37
- package/dist/importers/core.js +10 -28
- 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 +12 -39
- package/dist/importers/vault.d.ts +2 -8
- package/dist/importers/vault.js +31 -85
- package/dist/index.d.ts +8 -3
- package/dist/index.js +8 -3
- package/dist/learn/autolearn.d.ts +23 -42
- package/dist/learn/autolearn.js +45 -52
- package/dist/learn/churn-git.js +13 -4
- package/dist/learn/extract.d.ts +3 -2
- package/dist/learn/extract.js +8 -8
- package/dist/learn/forward-claim-detector.d.ts +6 -30
- package/dist/learn/forward-claim-detector.js +18 -68
- package/dist/learn/invalidation.d.ts +6 -18
- package/dist/learn/invalidation.js +18 -31
- package/dist/mcp/admin-tools.d.ts +2 -2
- package/dist/mcp/admin-tools.js +30 -53
- package/dist/mcp/format.js +3 -2
- package/dist/mcp/framing.d.ts +1 -0
- package/dist/mcp/framing.js +1 -1
- package/dist/mcp/memory-tools.js +7 -10
- package/dist/mcp/protocol.d.ts +15 -29
- package/dist/mcp/protocol.js +26 -16
- package/dist/mcp/recall-tools.js +14 -11
- package/dist/mcp/request.d.ts +3 -11
- package/dist/mcp/request.js +12 -27
- 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 +68 -16
- package/dist/mcp/tool-args.js +2 -1
- package/dist/mcp/tools.js +47 -22
- package/dist/objects/customer-notes.d.ts +9 -44
- package/dist/objects/customer-notes.js +7 -48
- package/dist/objects/decisions.d.ts +14 -52
- package/dist/objects/decisions.js +15 -53
- package/dist/objects/descriptor.d.ts +1 -1
- package/dist/objects/incidents.d.ts +9 -40
- package/dist/objects/incidents.js +7 -41
- package/dist/objects/lifecycle.d.ts +1 -1
- package/dist/objects/lifecycle.js +2 -1
- package/dist/objects/policies.d.ts +13 -91
- package/dist/objects/policies.js +13 -99
- package/dist/objects/processes.d.ts +9 -54
- package/dist/objects/processes.js +7 -61
- package/dist/objects/project-briefs.d.ts +13 -57
- package/dist/objects/project-briefs.js +16 -78
- package/dist/objects/skills.d.ts +9 -44
- package/dist/objects/skills.js +8 -54
- package/dist/postinstall.js +7 -20
- package/dist/predictions/planning-fallacy.d.ts +11 -34
- package/dist/rerankers/clef.js +6 -37
- package/dist/rerankers/cross-encoder.d.ts +31 -2
- package/dist/rerankers/cross-encoder.js +65 -101
- package/dist/rerankers/index.js +5 -4
- package/dist/rerankers/jev.js +11 -10
- package/dist/rerankers/llm.d.ts +2 -11
- package/dist/rerankers/llm.js +14 -14
- package/dist/rerankers/outage-warning.d.ts +5 -2
- package/dist/rerankers/outage-warning.js +7 -4
- 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/bm25-search.js +1 -1
- package/dist/search/boosts.d.ts +0 -2
- package/dist/search/boosts.js +3 -3
- package/dist/search/embed-memories.d.ts +9 -0
- package/dist/search/embed-memories.js +377 -0
- package/dist/search/goal-boost.d.ts +23 -0
- package/dist/search/goal-boost.js +93 -0
- package/dist/search/hybrid.d.ts +11 -2
- package/dist/search/hybrid.js +9 -4
- 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.d.ts +6 -3
- package/dist/search/physics-search.js +29 -19
- package/dist/search/rerank.js +1 -1
- package/dist/search/rrf.d.ts +7 -35
- package/dist/search/rrf.js +5 -30
- package/dist/search/vector.d.ts +13 -4
- package/dist/search/vector.js +40 -13
- package/dist/server/auth.d.ts +11 -28
- package/dist/server/auth.js +49 -32
- package/dist/server/boot.d.ts +2 -21
- package/dist/server/boot.js +69 -161
- package/dist/server/client-ip.d.ts +3 -21
- package/dist/server/client-ip.js +8 -30
- package/dist/server/deadline.d.ts +0 -2
- package/dist/server/deadline.js +1 -7
- package/dist/server/defaults.d.ts +4 -0
- package/dist/server/defaults.js +5 -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 +24 -53
- 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 +16 -19
- package/dist/server/route-checks.d.ts +7 -0
- package/dist/server/route-checks.js +42 -0
- package/dist/server/route-table.d.ts +9 -8
- package/dist/server/route-table.js +127 -139
- package/dist/server/routes/admin.d.ts +8 -8
- package/dist/server/routes/admin.js +35 -49
- package/dist/server/routes/customer-notes.d.ts +6 -6
- package/dist/server/routes/customer-notes.js +8 -14
- package/dist/server/routes/decisions.d.ts +6 -6
- package/dist/server/routes/decisions.js +12 -21
- package/dist/server/routes/incidents.d.ts +6 -6
- package/dist/server/routes/incidents.js +14 -25
- package/dist/server/routes/memories.d.ts +9 -9
- package/dist/server/routes/memories.js +20 -63
- package/dist/server/routes/object-routes.d.ts +6 -11
- package/dist/server/routes/object-routes.js +11 -22
- package/dist/server/routes/policies.d.ts +7 -7
- package/dist/server/routes/policies.js +12 -22
- package/dist/server/routes/predictions.d.ts +6 -6
- package/dist/server/routes/predictions.js +22 -38
- package/dist/server/routes/processes.d.ts +6 -6
- package/dist/server/routes/processes.js +17 -28
- package/dist/server/routes/project-briefs.d.ts +7 -7
- package/dist/server/routes/project-briefs.js +11 -20
- package/dist/server/routes/recall.d.ts +5 -5
- package/dist/server/routes/recall.js +16 -45
- package/dist/server/routes/skills.d.ts +7 -7
- package/dist/server/routes/skills.js +10 -22
- package/dist/server/server-detect.d.ts +15 -53
- package/dist/server/server-detect.js +55 -96
- package/dist/server/sleep-child.js +26 -7
- package/dist/server/sleep-offload.d.ts +11 -5
- package/dist/server/sleep-offload.js +21 -12
- package/dist/server/types.d.ts +32 -18
- package/dist/server/validation.d.ts +3 -2
- package/dist/server/validation.js +15 -33
- package/dist/server.d.ts +7 -6
- package/dist/server.js +8 -6
- 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 +73 -0
- package/dist/sharing/project-merge.d.ts +11 -19
- package/dist/sharing/project-merge.js +63 -125
- package/dist/sharing/search-both.d.ts +60 -0
- package/dist/sharing/search-both.js +138 -0
- package/dist/sharing/share.d.ts +40 -0
- package/dist/sharing/share.js +229 -0
- package/dist/store/ambient.js +9 -15
- package/dist/store/audit-event.d.ts +5 -13
- package/dist/store/audit-event.js +4 -12
- package/dist/store/audit.d.ts +2 -21
- package/dist/store/audit.js +8 -67
- package/dist/store/auth.d.ts +10 -8
- package/dist/store/auth.js +17 -12
- package/dist/store/candidates.d.ts +23 -5
- package/dist/store/candidates.js +119 -71
- package/dist/store/capture-write.d.ts +17 -0
- package/dist/store/capture-write.js +35 -0
- 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/compaction-caller.d.ts +18 -0
- package/dist/store/compaction-caller.js +29 -0
- package/dist/store/compactions-record.d.ts +115 -0
- package/dist/store/compactions-record.js +417 -0
- package/dist/store/compactions.js +6 -4
- package/dist/store/conflicts.d.ts +4 -21
- package/dist/store/conflicts.js +76 -152
- package/dist/store/connectors/dlq.d.ts +10 -0
- package/dist/store/connectors/dlq.js +32 -0
- package/dist/store/connectors/github.d.ts +14 -16
- package/dist/store/connectors/github.js +34 -57
- package/dist/store/connectors/slack.d.ts +2 -11
- package/dist/store/connectors/slack.js +18 -47
- package/dist/store/dashboard-reads.js +11 -14
- package/dist/store/delete-and-batch.d.ts +17 -31
- package/dist/store/delete-and-batch.js +84 -67
- package/dist/store/delivery-recorder.d.ts +15 -4
- package/dist/store/delivery-recorder.js +34 -17
- package/dist/store/descendant-page.js +6 -3
- package/dist/store/diagnostics.js +6 -13
- package/dist/store/dormant.d.ts +8 -30
- package/dist/store/dormant.js +18 -57
- package/dist/store/embeddings/index.d.ts +11 -90
- package/dist/store/embeddings/index.js +18 -523
- package/dist/store/entry-reads.d.ts +34 -61
- package/dist/store/entry-reads.js +111 -136
- package/dist/store/entry-row.d.ts +6 -35
- package/dist/store/entry-row.js +9 -37
- package/dist/store/entry-writes.d.ts +12 -18
- package/dist/store/entry-writes.js +46 -44
- package/dist/store/failure-log-at.d.ts +8 -0
- package/dist/store/failure-log-at.js +16 -0
- package/dist/store/failure-log.d.ts +2 -2
- package/dist/store/failure-log.js +5 -3
- package/dist/{trust → store}/gated-write.d.ts +3 -1
- package/dist/{trust → store}/gated-write.js +7 -5
- package/dist/store/goals.d.ts +3 -40
- package/dist/store/goals.js +41 -178
- 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 +24 -60
- 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 +10 -35
- package/dist/store/graph-writes.js +59 -106
- package/dist/store/half-life.d.ts +2 -1
- package/dist/store/half-life.js +14 -16
- package/dist/store/handoffs.d.ts +6 -12
- package/dist/store/handoffs.js +22 -40
- package/dist/store/index-and-stats.d.ts +6 -19
- package/dist/store/index-and-stats.js +36 -84
- package/dist/store/key-writes.js +1 -1
- package/dist/store/ledger-turn.d.ts +9 -0
- package/dist/store/ledger-turn.js +38 -0
- package/dist/store/mirrors.d.ts +2 -6
- package/dist/store/mirrors.js +24 -29
- package/dist/store/open.d.ts +0 -4
- package/dist/store/open.js +42 -62
- package/dist/store/pilot-arm.d.ts +12 -0
- package/dist/store/pilot-arm.js +42 -0
- 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 +91 -82
- package/dist/store/port.js +8 -0
- package/dist/store/predictions.d.ts +12 -53
- package/dist/store/predictions.js +41 -125
- package/dist/store/project-tags.d.ts +62 -0
- package/dist/store/project-tags.js +67 -0
- package/dist/{cli → store}/quality-repair.js +15 -31
- package/dist/store/quarantine.js +2 -1
- package/dist/store/raw-archive.d.ts +4 -16
- package/dist/store/raw-archive.js +14 -29
- package/dist/store/recall-trace.d.ts +12 -77
- package/dist/store/recall-trace.js +37 -97
- package/dist/store/rejected-values.js +9 -20
- package/dist/store/rejection-probe.d.ts +4 -0
- package/dist/store/rejection-probe.js +19 -0
- package/dist/store/rejection.d.ts +10 -73
- package/dist/store/rejection.js +12 -84
- 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 +14 -0
- package/dist/store/rule-sql.js +56 -0
- package/dist/store/search-rows.d.ts +7 -38
- package/dist/store/search-rows.js +23 -54
- package/dist/store/sessions.d.ts +10 -47
- package/dist/store/sessions.js +21 -75
- package/dist/store/set-aside.d.ts +14 -0
- package/dist/store/set-aside.js +23 -0
- package/dist/store/sqlite/busy.d.ts +3 -0
- package/dist/store/sqlite/busy.js +8 -0
- package/dist/store/sqlite/connector-events-group.js +5 -8
- package/dist/store/sqlite/connector-writes-group.js +3 -3
- package/dist/store/sqlite/entry-writes-group.js +4 -4
- package/dist/store/sqlite/error-codec.js +8 -5
- package/dist/store/sqlite/executor.d.ts +2 -1
- package/dist/store/sqlite/executor.js +12 -5
- package/dist/store/sqlite/graph-reads-group.js +1 -1
- package/dist/store/sqlite/held-connection.d.ts +9 -0
- package/dist/store/sqlite/held-connection.js +41 -0
- package/dist/store/sqlite/local.d.ts +3 -3
- package/dist/store/sqlite/local.js +1 -0
- package/dist/store/sqlite/object-rows.d.ts +1 -1
- package/dist/store/sqlite/object-rows.js +6 -3
- package/dist/store/sqlite/objects-group.d.ts +1 -1
- package/dist/store/sqlite/objects-group.js +5 -3
- package/dist/store/sqlite/quarantine-group.js +2 -2
- package/dist/store/sqlite/store.d.ts +1 -4
- package/dist/store/sqlite/store.js +16 -15
- 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 +11 -63
- package/dist/store/summaries.js +37 -148
- 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 -50
- package/dist/store/token-ledger.js +19 -85
- package/dist/store/usage-reports.js +5 -13
- package/dist/store/vector-index.d.ts +46 -0
- package/dist/store/vector-index.js +171 -0
- package/dist/store/working-memory.d.ts +6 -25
- package/dist/store/working-memory.js +18 -52
- package/dist/support-bundle.js +9 -8
- package/dist/trust/reject-flow.js +3 -5
- package/dist/util/agent-homes.d.ts +15 -0
- package/dist/util/agent-homes.js +34 -0
- package/dist/util/anthropic-messages.d.ts +3 -0
- package/dist/util/anthropic-messages.js +35 -6
- 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/chunked.d.ts +3 -0
- package/dist/util/chunked.js +10 -0
- package/dist/util/crash-handlers.d.ts +8 -1
- package/dist/util/crash-handlers.js +52 -10
- package/dist/util/ellipsize.d.ts +3 -0
- package/dist/util/ellipsize.js +5 -0
- package/dist/util/env.d.ts +14 -6
- package/dist/util/env.js +15 -7
- package/dist/util/format.d.ts +3 -0
- package/dist/util/format.js +6 -0
- package/dist/util/home-path.d.ts +2 -1
- package/dist/util/home-path.js +4 -2
- package/dist/util/hook-payload.d.ts +8 -0
- package/dist/util/hook-payload.js +37 -0
- package/dist/util/http-retry.d.ts +9 -1
- package/dist/util/http-retry.js +67 -8
- package/dist/util/http-util.d.ts +0 -8
- package/dist/util/http-util.js +10 -21
- package/dist/util/limits.d.ts +7 -0
- package/dist/util/limits.js +14 -0
- package/dist/util/log.d.ts +7 -2
- package/dist/util/log.js +34 -9
- package/dist/util/request-scope.d.ts +5 -2
- package/dist/util/request-scope.js +13 -7
- package/dist/util/secret-detect.d.ts +5 -30
- package/dist/util/secret-detect.js +19 -40
- package/dist/util/sqlite-blocked.d.ts +2 -0
- package/dist/util/sqlite-blocked.js +5 -0
- package/dist/util/stored-json.d.ts +1 -1
- package/dist/util/stored-json.js +1 -1
- package/dist/util/stream-tee.d.ts +3 -0
- package/dist/util/stream-tee.js +35 -0
- package/dist/util/time.d.ts +4 -0
- package/dist/util/time.js +4 -0
- 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/dist/{store → util}/yaml.d.ts +1 -5
- package/dist/{store → util}/yaml.js +2 -6
- 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 +2 -2
- package/dist/cli/provenance-coverage.d.ts +0 -18
- package/dist/connectors/github/cli-impl.d.ts +0 -25
- package/dist/sharing/scope.d.ts +0 -14
- package/dist/sharing/shared.d.ts +0 -187
- package/dist/sharing/shared.js +0 -563
- package/dist/store/embeddings/local.d.ts +0 -15
- package/dist/store/embeddings/local.js +0 -192
- package/dist/store/embeddings/provider.d.ts +0 -77
- package/dist/store/markdown.d.ts +0 -10
- package/dist/store/recall-scope.d.ts +0 -138
- package/dist/store/recall-scope.js +0 -216
- package/dist/store/vector-writes.d.ts +0 -13
- package/dist/store/vector-writes.js +0 -89
- /package/dist/{store → core}/object-types.d.ts +0 -0
- /package/dist/{store → core}/object-types.js +0 -0
- /package/dist/{cli → store}/quality-repair.d.ts +0 -0
- /package/dist/{capture → util}/compaction-items.d.ts +0 -0
- /package/dist/{capture → util}/compaction-items.js +0 -0
|
@@ -1,46 +1,38 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync, unlinkSync, renameSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { envHealthProbeMs } from '../util/env.js';
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
// openHippoDb), so this resolves to `${hippoRoot}/server.pid`.
|
|
4
|
+
import { errorCode, errorFields, errorMessage, log } from '../util/log.js';
|
|
5
|
+
// Pidfile sits directly inside hippoRoot (the `.hippo` directory itself, as for openHippoDb), i.e. `${hippoRoot}/server.pid`.
|
|
7
6
|
const PIDFILE = 'server.pid';
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* treating the pidfile as stale. Short by design: the probe only fires on
|
|
11
|
-
* the rare path where a pidfile exists and its pid is live, and the target
|
|
12
|
-
* is always loopback, so a healthy server answers well within this bound. HIPPO_HEALTH_PROBE_MS overrides it.
|
|
13
|
-
*/
|
|
7
|
+
/** How long detectServer waits for the `/health` probe before treating the pidfile as stale; short because it fires only when a pidfile exists with a live
|
|
8
|
+
* pid on loopback. HIPPO_HEALTH_PROBE_MS overrides it. */
|
|
14
9
|
const HEALTH_PROBE_TIMEOUT_MS = 300;
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* hippo /health payload is well under 1 KB; a larger body means the process
|
|
18
|
-
* answering on the recorded port is not hippo, so the pidfile is stale.
|
|
19
|
-
*/
|
|
10
|
+
/** Hard cap on the /health body detectServer buffers: a real payload is well under 1 KB, so a larger body means the process on the recorded port is not
|
|
11
|
+
* hippo. */
|
|
20
12
|
const HEALTH_BODY_MAX_BYTES = 64 * 1024;
|
|
21
|
-
/**
|
|
22
|
-
* Loopback hosts the recorded pidfile url is allowed to point at. serve()
|
|
23
|
-
* only binds these (it mirrors LOOPBACK_HOSTS in server.ts); a pidfile url
|
|
24
|
-
* with any other host is malformed or forged and must not be probed.
|
|
25
|
-
*/
|
|
13
|
+
/** Loopback hosts a recorded pidfile url may point at (serve() only binds these); any other host is malformed or forged and is not probed. */
|
|
26
14
|
const PIDFILE_LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
|
|
15
|
+
/** The pidfile names a live process on loopback that did not answer /health in time: most likely a busy server, so a caller must neither
|
|
16
|
+
* bypass it with a second writer nor start another server beside it. */
|
|
17
|
+
export class ServerUnresponsiveError extends Error {
|
|
18
|
+
constructor(info, probeMs, options) {
|
|
19
|
+
super(`a hippo server (pid ${info.pid}) is recorded at ${info.url} but did not answer /health within ${probeMs} ms; it may be busy. ` +
|
|
20
|
+
'Retry shortly, raise HIPPO_HEALTH_PROBE_MS, or stop that server.', options);
|
|
21
|
+
this.name = 'ServerUnresponsiveError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
27
24
|
/** False when the pidfile's pid is dead or its url could not be one serve() wrote. */
|
|
28
25
|
function isLiveLoopbackTarget(info) {
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
// Node's process.kill(pid, 0) is implemented on Windows via OpenProcess +
|
|
32
|
-
// GetExitCodeProcess, so this works cross-platform for the dead-pid case.
|
|
26
|
+
// Signal 0 throws if the pid is dead or owned by another user we cannot signal; either way, treat as stale.
|
|
27
|
+
// process.kill(pid, 0) works cross-platform for the dead-pid case (OpenProcess + GetExitCodeProcess on Windows).
|
|
33
28
|
try {
|
|
34
29
|
process.kill(info.pid, 0);
|
|
35
30
|
}
|
|
36
31
|
catch {
|
|
37
32
|
return false;
|
|
38
33
|
}
|
|
39
|
-
// The pid is
|
|
40
|
-
// the recorded
|
|
41
|
-
// binds a loopback host, so a url that is not http on a loopback host and the
|
|
42
|
-
// recorded port is malformed or forged. Reject it before probing: the probe,
|
|
43
|
-
// and the routed request that may follow, can carry HIPPO_API_KEY.
|
|
34
|
+
// The pid may have been reused and the recorded url is read from a forgeable file; serve() only binds loopback, so a url that is not http on a loopback
|
|
35
|
+
// host and the recorded port is malformed or forged. Reject it before probing, since the probe and any routed request can carry HIPPO_API_KEY.
|
|
44
36
|
let probeUrl;
|
|
45
37
|
try {
|
|
46
38
|
probeUrl = new URL(info.url);
|
|
@@ -54,9 +46,8 @@ function isLiveLoopbackTarget(info) {
|
|
|
54
46
|
}
|
|
55
47
|
/** The whole body as text, or null once it passes HEALTH_BODY_MAX_BYTES (the stream is then cancelled). */
|
|
56
48
|
async function readCappedBody(body) {
|
|
57
|
-
// Read the body under a hard byte cap
|
|
58
|
-
//
|
|
59
|
-
// its response is untrusted: never hand an unbounded stream to a parser.
|
|
49
|
+
// Read the body under a hard byte cap: the process on info.url may not be hippo (pid reuse), so its response is untrusted and never goes unbounded into a
|
|
50
|
+
// parser.
|
|
60
51
|
const reader = body.getReader();
|
|
61
52
|
const decoder = new TextDecoder();
|
|
62
53
|
let raw = '';
|
|
@@ -75,18 +66,23 @@ async function readCappedBody(body) {
|
|
|
75
66
|
raw += decoder.decode();
|
|
76
67
|
return raw;
|
|
77
68
|
}
|
|
78
|
-
/** True when
|
|
69
|
+
/** True when fetch failed because nothing listens on the port (the error or its cause, or any address tried, is ECONNREFUSED). */
|
|
70
|
+
function isConnectionRefused(err) {
|
|
71
|
+
if (errorCode(err) === 'ECONNREFUSED')
|
|
72
|
+
return true;
|
|
73
|
+
const cause = err instanceof Error ? err.cause : undefined;
|
|
74
|
+
if (errorCode(cause) === 'ECONNREFUSED')
|
|
75
|
+
return true;
|
|
76
|
+
return cause instanceof AggregateError && cause.errors.length > 0 && cause.errors.every((e) => errorCode(e) === 'ECONNREFUSED');
|
|
77
|
+
}
|
|
78
|
+
/** True when /health on info.url reports the pidfile's started_at; unlinks the pidfile on any definitive mismatch and throws ServerUnresponsiveError on a
|
|
79
|
+
* probe timeout. */
|
|
79
80
|
async function healthMatchesPidfile(hippoRoot, info) {
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
// is deliberately left ambiguous: a live but momentarily-busy server (e.g.
|
|
84
|
-
// blocked on a synchronous query) can miss the 300ms window, so a timeout
|
|
85
|
-
// returns null WITHOUT unlinking. The pidfile survives for the next probe.
|
|
81
|
+
// Refusal, non-200 or a malformed body unlink the pidfile as stale. A timeout proves neither a dead server nor this one, so it keeps the pidfile and throws.
|
|
82
|
+
// Any other error keeps it and warns.
|
|
83
|
+
const probeMs = envHealthProbeMs() ?? HEALTH_PROBE_TIMEOUT_MS;
|
|
86
84
|
try {
|
|
87
|
-
const res = await fetch(`${info.url}/health`, {
|
|
88
|
-
signal: AbortSignal.timeout(envHealthProbeMs() ?? HEALTH_PROBE_TIMEOUT_MS),
|
|
89
|
-
});
|
|
85
|
+
const res = await fetch(`${info.url}/health`, { signal: AbortSignal.timeout(probeMs) });
|
|
90
86
|
if (!res.ok || !res.body) {
|
|
91
87
|
removePidfile(hippoRoot);
|
|
92
88
|
return false;
|
|
@@ -104,32 +100,21 @@ async function healthMatchesPidfile(hippoRoot, info) {
|
|
|
104
100
|
return true;
|
|
105
101
|
}
|
|
106
102
|
catch (err) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
// .name property structurally is safe regardless of the object's actual type.
|
|
112
|
-
if (err?.name !== 'TimeoutError') {
|
|
103
|
+
if (err instanceof Error && err.name === 'TimeoutError')
|
|
104
|
+
throw new ServerUnresponsiveError(info, probeMs, { cause: err });
|
|
105
|
+
// A refusal or a non-JSON body proves no hippo server answers there; any other failure may be a live server, so the file stays.
|
|
106
|
+
if (isConnectionRefused(err) || err instanceof SyntaxError) {
|
|
113
107
|
removePidfile(hippoRoot);
|
|
114
108
|
}
|
|
109
|
+
else {
|
|
110
|
+
log.warn(`server pidfile ${join(hippoRoot, PIDFILE)} kept: the /health probe failed (${errorMessage(err)})`, errorFields(err));
|
|
111
|
+
}
|
|
115
112
|
return false;
|
|
116
113
|
}
|
|
117
114
|
}
|
|
118
|
-
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* malformed, or stale pidfiles, and best-effort unlinks the file in the
|
|
122
|
-
* stale/malformed cases.
|
|
123
|
-
*
|
|
124
|
-
* Liveness is proven in two steps. `process.kill(pid, 0)` rules out dead
|
|
125
|
-
* pids. But a pid can be reused by an unrelated process, so a GET /health
|
|
126
|
-
* then confirms the process that answers is *this* hippo server: its
|
|
127
|
-
* `started_at` must equal the pidfile's. A mismatch, non-200, malformed
|
|
128
|
-
* body, or timeout all mean the pidfile is stale.
|
|
129
|
-
*
|
|
130
|
-
* The /health probe runs only when a pidfile exists and the pid is live, so
|
|
131
|
-
* the common no-server path stays a single fast file existence check.
|
|
132
|
-
*/
|
|
115
|
+
/** Returns the pidfile's ServerInfo if a live hippo server answers on the recorded url, else null (best-effort unlinking of missing/stale/malformed pidfiles).
|
|
116
|
+
* `process.kill(pid, 0)` rules out dead pids; GET /health must then return the pidfile's `started_at` (pids get reused). Probes only if the pid is live.
|
|
117
|
+
* Throws ServerUnresponsiveError when that probe times out. */
|
|
133
118
|
export async function detectServer(hippoRoot) {
|
|
134
119
|
const path = join(hippoRoot, PIDFILE);
|
|
135
120
|
if (!existsSync(path))
|
|
@@ -138,7 +123,8 @@ export async function detectServer(hippoRoot) {
|
|
|
138
123
|
try {
|
|
139
124
|
info = JSON.parse(readFileSync(path, 'utf8'));
|
|
140
125
|
}
|
|
141
|
-
catch {
|
|
126
|
+
catch (err) {
|
|
127
|
+
log.warn(`server pidfile ${path} is unreadable (${errorMessage(err)}); removing it`);
|
|
142
128
|
removePidfile(hippoRoot);
|
|
143
129
|
return null;
|
|
144
130
|
}
|
|
@@ -148,14 +134,8 @@ export async function detectServer(hippoRoot) {
|
|
|
148
134
|
}
|
|
149
135
|
return (await healthMatchesPidfile(hippoRoot, info)) ? info : null;
|
|
150
136
|
}
|
|
151
|
-
/**
|
|
152
|
-
*
|
|
153
|
-
* renames into place, which is atomic on POSIX and on NTFS via MoveFileEx.
|
|
154
|
-
*
|
|
155
|
-
* `startedAt` is supplied by the caller (`serve()`) rather than generated
|
|
156
|
-
* here, so the pidfile and the server's GET /health response carry the same
|
|
157
|
-
* timestamp — detectServer's liveness probe compares the two for equality.
|
|
158
|
-
*/
|
|
137
|
+
/** Atomically writes the pidfile (process-scoped temp file, then rename; atomic on POSIX and NTFS). `startedAt` comes from the caller (`serve()`) so the
|
|
138
|
+
* pidfile and GET /health carry the same timestamp, which detectServer's liveness probe compares. */
|
|
159
139
|
export function writePidfile(hippoRoot, opts) {
|
|
160
140
|
const path = join(hippoRoot, PIDFILE);
|
|
161
141
|
const tmp = `${path}.tmp.${process.pid}`;
|
|
@@ -169,13 +149,8 @@ export function writePidfile(hippoRoot, opts) {
|
|
|
169
149
|
writeFileSync(tmp, JSON.stringify(info));
|
|
170
150
|
renameSync(tmp, path);
|
|
171
151
|
}
|
|
172
|
-
/**
|
|
173
|
-
*
|
|
174
|
-
* caller can use this in shutdown paths without fear of throwing.
|
|
175
|
-
*
|
|
176
|
-
* Identity-blind: deletes whatever pidfile is on disk. A shutdown path that
|
|
177
|
-
* must not clobber a newer server's pidfile should use removePidfileIfOwned.
|
|
178
|
-
*/
|
|
152
|
+
/** Best-effort pidfile removal, silent on any error so shutdown paths can call it. Identity-blind: a shutdown that must not clobber a newer server's pidfile
|
|
153
|
+
* uses removePidfileIfOwned. */
|
|
179
154
|
export function removePidfile(hippoRoot) {
|
|
180
155
|
const path = join(hippoRoot, PIDFILE);
|
|
181
156
|
try {
|
|
@@ -183,24 +158,8 @@ export function removePidfile(hippoRoot) {
|
|
|
183
158
|
}
|
|
184
159
|
catch { /* already gone or undeletable; the next detectServer probe re-checks */ }
|
|
185
160
|
}
|
|
186
|
-
/**
|
|
187
|
-
*
|
|
188
|
-
* Reads and parses the pidfile and unlinks it ONLY when both `pid` and
|
|
189
|
-
* `started_at` match `owner`. A pidfile rewritten by a newer server is left
|
|
190
|
-
* intact, so a shutting-down older server cannot orphan the newer one by
|
|
191
|
-
* deleting its pidfile out from under it.
|
|
192
|
-
*
|
|
193
|
-
* Best-effort and never throws: a missing, unreadable, malformed, or
|
|
194
|
-
* non-object pidfile (including a literal JSON `null`) is "not provably mine"
|
|
195
|
-
* and left alone — detectServer unlinks a malformed pidfile on its next
|
|
196
|
-
* probe, so it does not leak. Returns true iff a matching pidfile was removed.
|
|
197
|
-
*
|
|
198
|
-
* Residual TOCTOU: the pidfile could be rewritten between the read and the
|
|
199
|
-
* unlink. The window is microseconds and the shape is the same read-check-
|
|
200
|
-
* unlink detectServer already uses; this narrows the clobber from an
|
|
201
|
-
* unbounded window (any time between writePidfile and stop) to a negligible
|
|
202
|
-
* one.
|
|
203
|
-
*/
|
|
161
|
+
/** Removes the pidfile ONLY when both `pid` and `started_at` match `owner`, so an older shutting-down server cannot orphan a newer one; never throws.
|
|
162
|
+
* Anything unreadable or malformed is "not provably mine" and left alone (detectServer unlinks it). Returns true iff removed. */
|
|
204
163
|
export function removePidfileIfOwned(hippoRoot, owner) {
|
|
205
164
|
const path = join(hippoRoot, PIDFILE);
|
|
206
165
|
try {
|
|
@@ -1,19 +1,38 @@
|
|
|
1
|
-
// Entry of the process that runs one POST /v1/sleep; sleep-offload.ts starts it and nothing imports it.
|
|
2
|
-
// The sleep
|
|
1
|
+
// Entry of the process that runs one POST /v1/sleep or MCP auto-sleep; sleep-offload.ts starts it and nothing imports it.
|
|
2
|
+
// The sleep modules alone: the api barrel loads far more than one sleep needs, and every sleep pays for the start.
|
|
3
3
|
import { sleep } from '../api/sleep.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { consolidate } from '../consolidate/sleep.js';
|
|
5
|
+
import { runWithRequestStores, SERVER_DB_WAIT_MS } from '../db/index.js';
|
|
6
|
+
import { isStoreBusy } from '../store/sqlite/busy.js';
|
|
7
|
+
import { errorFields, errorMessage, log } from '../util/log.js';
|
|
6
8
|
function failed(err) {
|
|
7
9
|
return { ok: false, busy: isStoreBusy(err), message: errorMessage(err), stack: err instanceof Error ? err.stack : undefined };
|
|
8
10
|
}
|
|
11
|
+
/** Resolves to the exit code once the channel has taken the reply, or failed to. */
|
|
12
|
+
function sendReply(reply) {
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
process.send?.(reply, (sendErr) => {
|
|
15
|
+
if (sendErr)
|
|
16
|
+
log.error(`sleep child: sending the reply failed: ${errorMessage(sendErr)}`, errorFields(sendErr));
|
|
17
|
+
resolve(sendErr ? 1 : 0);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
9
21
|
process.once('message', (message) => {
|
|
10
22
|
// SAFETY: sleep-offload.ts is the only writer on this channel and sends exactly one SleepJob.
|
|
11
23
|
const job = message;
|
|
12
|
-
const
|
|
24
|
+
const work = () => job.kind === 'consolidate'
|
|
25
|
+
? consolidate(job.hippoRoot)
|
|
26
|
+
: sleep({ hippoRoot: job.hippoRoot, tenantId: job.tenantId, actor: job.actor }, job.opts);
|
|
13
27
|
// The server's own request scope and lock wait, so a busy store answers as it did when sleep ran in the server.
|
|
14
|
-
runWithRequestStores(
|
|
28
|
+
runWithRequestStores(work, { busyWaitMs: SERVER_DB_WAIT_MS })
|
|
15
29
|
.then((result) => ({ ok: true, result }), failed)
|
|
16
30
|
// Exit only once the reply is written, or the parent could see the process end first.
|
|
17
|
-
.then(
|
|
31
|
+
.then(sendReply)
|
|
32
|
+
.catch((err) => {
|
|
33
|
+
log.error(`sleep child: the reply could not be sent: ${errorMessage(err)}`, errorFields(err));
|
|
34
|
+
return 1;
|
|
35
|
+
})
|
|
36
|
+
.then((code) => process.exit(code));
|
|
18
37
|
});
|
|
19
38
|
//# sourceMappingURL=sleep-child.js.map
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { type Actor, type Context, type SleepOpts, type SleepResult } from '../api/index.js';
|
|
2
|
-
/** What the child needs to rebuild the request's context
|
|
3
|
-
export
|
|
2
|
+
/** What the child needs to rebuild the request's context (the store handle itself cannot cross a process boundary), or the store an auto-sleep consolidates. */
|
|
3
|
+
export type SleepJob = {
|
|
4
|
+
readonly kind: 'sleep';
|
|
4
5
|
readonly hippoRoot: string;
|
|
5
6
|
readonly tenantId: string;
|
|
6
7
|
readonly actor: Actor;
|
|
7
8
|
readonly opts: SleepOpts;
|
|
8
|
-
}
|
|
9
|
-
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'consolidate';
|
|
11
|
+
readonly hippoRoot: string;
|
|
12
|
+
};
|
|
13
|
+
export type SleepReply<R = SleepResult> = {
|
|
10
14
|
readonly ok: true;
|
|
11
|
-
readonly result:
|
|
15
|
+
readonly result: R;
|
|
12
16
|
} | {
|
|
13
17
|
readonly ok: false;
|
|
14
18
|
readonly busy: boolean;
|
|
@@ -17,4 +21,6 @@ export type SleepReply = {
|
|
|
17
21
|
};
|
|
18
22
|
/** `sleep` for the HTTP route: same result and errors, run outside the serving process and stopped at the deadline (10 minutes, or HIPPO_SLEEP_TIMEOUT_MS). */
|
|
19
23
|
export declare function sleepInChild(ctx: Context, opts: SleepOpts): Promise<SleepResult>;
|
|
24
|
+
/** The MCP auto-sleep's consolidation, in the same queue and child as POST /v1/sleep; auto-sleep only starts on a hippo.db store. */
|
|
25
|
+
export declare function consolidateInChild(hippoRoot: string): Promise<void>;
|
|
20
26
|
//# sourceMappingURL=sleep-offload.d.ts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// POST /v1/sleep
|
|
1
|
+
// POST /v1/sleep and the MCP auto-sleep run their consolidation in a child process, so the server keeps answering and a stuck run can be stopped.
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { sleep } from '../api/index.js';
|
|
5
|
-
import { StoreBusyError } from '../
|
|
5
|
+
import { StoreBusyError } from '../store/port.js';
|
|
6
6
|
import { envSleepTimeoutMs } from '../util/env.js';
|
|
7
7
|
import { HttpError } from '../util/http-util.js';
|
|
8
8
|
const DEFAULT_SLEEP_DEADLINE_MS = 600_000;
|
|
@@ -23,13 +23,16 @@ function runInChild(job) {
|
|
|
23
23
|
const deadlineMs = envSleepTimeoutMs() ?? DEFAULT_SLEEP_DEADLINE_MS;
|
|
24
24
|
return new Promise((resolve, reject) => {
|
|
25
25
|
// The child's stderr is the server's log, so Node's SQLite notice would repeat there on every sleep.
|
|
26
|
-
const child = spawn(process.execPath, ['--disable-warning=ExperimentalWarning', CHILD_ENTRY], {
|
|
26
|
+
const child = spawn(process.execPath, ['--disable-warning=ExperimentalWarning', CHILD_ENTRY], {
|
|
27
|
+
stdio: ['ignore', 'inherit', 'inherit', 'ipc'],
|
|
28
|
+
windowsHide: true
|
|
29
|
+
});
|
|
27
30
|
let reply;
|
|
28
31
|
let timedOut = false;
|
|
29
32
|
// SIGKILL because the child is inside synchronous SQLite work and cannot run a handler; the OS drops its write lock.
|
|
30
33
|
const timer = setTimeout(() => { timedOut = true; child.kill('SIGKILL'); }, deadlineMs);
|
|
31
34
|
child.once('message', (message) => {
|
|
32
|
-
// SAFETY: sleep-child.ts is the only writer on this channel and sends exactly one SleepReply.
|
|
35
|
+
// SAFETY: sleep-child.ts is the only writer on this channel and sends exactly one SleepReply for the job it was given.
|
|
33
36
|
reply = message;
|
|
34
37
|
});
|
|
35
38
|
child.once('error', (err) => { clearTimeout(timer); reject(err); });
|
|
@@ -51,20 +54,26 @@ let turn = Promise.resolve();
|
|
|
51
54
|
const MAX_SLEEPS_IN_LINE = 2;
|
|
52
55
|
const SLEEP_RETRY_AFTER_SEC = 30;
|
|
53
56
|
let inLine = 0;
|
|
54
|
-
|
|
55
|
-
export function sleepInChild(ctx, opts) {
|
|
56
|
-
// The child reopens the store by path, which only SQLite has; any other store keeps sleep's own refusal.
|
|
57
|
-
if (ctx.store && ctx.store.kind !== 'sqlite')
|
|
58
|
-
return sleep(ctx, opts);
|
|
57
|
+
function inTurn(job) {
|
|
59
58
|
if (inLine >= MAX_SLEEPS_IN_LINE) {
|
|
60
59
|
return Promise.reject(new HttpError(503, 'a sleep is already running and another is waiting; retry when one has finished', SLEEP_RETRY_AFTER_SEC));
|
|
61
60
|
}
|
|
62
61
|
inLine += 1;
|
|
63
|
-
|
|
64
|
-
// One sleep at a time, as on the server's single thread: a second request waits its turn and does not fight the first for the write lock.
|
|
62
|
+
// One sleep at a time, as on the server's single thread: a second one waits its turn and does not fight the first for the write lock.
|
|
65
63
|
const run = turn.then(() => runInChild(job));
|
|
66
|
-
// A failed sleep reaches its own
|
|
64
|
+
// A failed sleep reaches its own caller through `run`; the queue only needs to know the turn is over.
|
|
67
65
|
turn = run.then(() => undefined, () => undefined).finally(() => { inLine -= 1; });
|
|
68
66
|
return run;
|
|
69
67
|
}
|
|
68
|
+
/** `sleep` for the HTTP route: same result and errors, run outside the serving process and stopped at the deadline (10 minutes, or HIPPO_SLEEP_TIMEOUT_MS). */
|
|
69
|
+
export function sleepInChild(ctx, opts) {
|
|
70
|
+
// The child reopens the store by path, which only SQLite has; any other store keeps sleep's own refusal.
|
|
71
|
+
if (ctx.store && ctx.store.kind !== 'sqlite')
|
|
72
|
+
return sleep(ctx, opts);
|
|
73
|
+
return inTurn({ kind: 'sleep', hippoRoot: ctx.hippoRoot, tenantId: ctx.tenantId, actor: ctx.actor, opts });
|
|
74
|
+
}
|
|
75
|
+
/** The MCP auto-sleep's consolidation, in the same queue and child as POST /v1/sleep; auto-sleep only starts on a hippo.db store. */
|
|
76
|
+
export async function consolidateInChild(hippoRoot) {
|
|
77
|
+
await inTurn({ kind: 'consolidate', hippoRoot });
|
|
78
|
+
}
|
|
70
79
|
//# sourceMappingURL=sleep-offload.js.map
|
package/dist/server/types.d.ts
CHANGED
|
@@ -7,17 +7,16 @@ export interface ServerHandle {
|
|
|
7
7
|
port: number;
|
|
8
8
|
url: string;
|
|
9
9
|
stop: () => Promise<void>;
|
|
10
|
-
/** Introspection-only: the underlying node:http Server,
|
|
11
|
-
*
|
|
12
|
-
* into serve()'s closure. Additive field — do not depend on it for control
|
|
13
|
-
* flow outside tests. */
|
|
10
|
+
/** Introspection-only: the underlying node:http Server, so tests can assert keep-alive/headers timeout hardening without reaching into serve()'s closure.
|
|
11
|
+
* Do not use for control flow. */
|
|
14
12
|
server?: import('node:http').Server;
|
|
15
13
|
}
|
|
16
14
|
/** Identity an {@link AuthResolver} vouches for. The core sanitises it before use. */
|
|
17
15
|
export interface ResolvedBearer {
|
|
18
16
|
tenantId: string;
|
|
19
17
|
subject: string;
|
|
20
|
-
/** Not 'admin' means 'member'. Admin is tenant-only, yet can mint member API keys (POST /v1/auth/keys);
|
|
18
|
+
/** Not 'admin' means 'member'. Admin is tenant-only, yet can mint member API keys (POST /v1/auth/keys);
|
|
19
|
+
* an add-on revokes them through the exported authRevoke when the IdP deprovisions the minter. */
|
|
21
20
|
role: 'admin' | 'member';
|
|
22
21
|
scopes?: readonly string[];
|
|
23
22
|
}
|
|
@@ -28,7 +27,8 @@ export interface AddonCall {
|
|
|
28
27
|
readonly ctx: Context;
|
|
29
28
|
readonly body: Readonly<Record<string, JsonValue>>;
|
|
30
29
|
}
|
|
31
|
-
/** A POST /v1 route an add-on mounts through serve(): core authenticates and parses first, then sends the
|
|
30
|
+
/** A POST /v1 route an add-on mounts through serve(): core authenticates and parses first, then sends the
|
|
31
|
+
* returned value as 200 JSON. Under another store it runs only when that store has its `storeReady` group. */
|
|
32
32
|
export interface AddonRoute {
|
|
33
33
|
readonly path: string;
|
|
34
34
|
readonly handler: (call: AddonCall) => Promise<JsonValue>;
|
|
@@ -46,7 +46,8 @@ export interface ServeOpts {
|
|
|
46
46
|
authResolverTimeoutMs?: number;
|
|
47
47
|
port?: number;
|
|
48
48
|
host?: string;
|
|
49
|
-
/** Stop and exit on SIGINT/SIGTERM, and drain then exit 1 on an uncaught exception or unhandled rejection.
|
|
49
|
+
/** Stop and exit on SIGINT/SIGTERM, and drain then exit 1 on an uncaught exception or unhandled rejection. A stop still running
|
|
50
|
+
* 10 s past `shutdownDrainMs` ends the process with a failure exit. Only `hippo serve` owns the process, so only it sets this. */
|
|
50
51
|
handleSignals?: boolean;
|
|
51
52
|
/** How long stop() lets in-flight requests finish before closing their sockets; defaults to 5000 ms. */
|
|
52
53
|
shutdownDrainMs?: number;
|
|
@@ -59,7 +60,8 @@ export interface ServeOpts {
|
|
|
59
60
|
mintBodyDeadlineMs?: number;
|
|
60
61
|
/** Tests only: shortens the wait for a signed webhook's body, which defaults to 10 s. */
|
|
61
62
|
webhookBodyDeadlineMs?: number;
|
|
62
|
-
/** PEM certificate and key: serve() then answers HTTPS only. Unset means cleartext
|
|
63
|
+
/** PEM certificate and key: serve() then answers HTTPS only. Unset means cleartext
|
|
64
|
+
* HTTP, which needs a TLS-terminating proxy in front on any non-loopback bind. */
|
|
63
65
|
tls?: {
|
|
64
66
|
cert: string | Buffer;
|
|
65
67
|
key: string | Buffer;
|
|
@@ -86,6 +88,10 @@ export interface RouteRequest {
|
|
|
86
88
|
opts: ResolvedServeOpts;
|
|
87
89
|
query: URLSearchParams;
|
|
88
90
|
}
|
|
91
|
+
/** A request past the dispatch gate, carrying the caller the gate authenticated. */
|
|
92
|
+
export interface AuthedRouteRequest extends RouteRequest {
|
|
93
|
+
ctx: Context;
|
|
94
|
+
}
|
|
89
95
|
/** A route's store status: a `storeReady` group, a `sqliteOnly` reason, or neither while it waits for a group; never both. */
|
|
90
96
|
type StoreStatus = {
|
|
91
97
|
storeReady?: StoreGroup;
|
|
@@ -94,20 +100,28 @@ type StoreStatus = {
|
|
|
94
100
|
sqliteOnly: string;
|
|
95
101
|
storeReady?: never;
|
|
96
102
|
};
|
|
97
|
-
/**
|
|
98
|
-
*
|
|
99
|
-
export type
|
|
100
|
-
|
|
101
|
-
loop?: 'off';
|
|
102
|
-
} & StoreStatus & ({
|
|
103
|
+
/** What the dispatch gate proves before a handler runs: any caller, an admin, a host admin on loopback, or nothing, for a route
|
|
104
|
+
* whose handler checks the sender's signature itself. */
|
|
105
|
+
export type RouteAuth = 'caller' | 'admin' | 'host-admin-local' | 'webhook-signature';
|
|
106
|
+
export type RouteEndpoint<R> = {
|
|
103
107
|
path: string;
|
|
104
|
-
handler: (r:
|
|
108
|
+
handler: (r: R) => Promise<void>;
|
|
105
109
|
} | {
|
|
106
110
|
pattern: string;
|
|
107
|
-
handler: (r:
|
|
111
|
+
handler: (r: R, params: Record<string, string>) => Promise<void>;
|
|
108
112
|
} | {
|
|
109
113
|
regex: RegExp;
|
|
110
|
-
handler: (r:
|
|
111
|
-
}
|
|
114
|
+
handler: (r: R, match: RegExpMatchArray) => Promise<void>;
|
|
115
|
+
};
|
|
116
|
+
/** One /v1 route: an exact path, a matchPath pattern, or a regex, each paired with one method's handler. Under another store it runs only with its
|
|
117
|
+
* store's `storeReady` group; `loop: 'off'` runs its SQLite work on a worker thread, so the handler opens no hippo.db on the server thread. */
|
|
118
|
+
export type Route = {
|
|
119
|
+
method: string;
|
|
120
|
+
loop?: 'off';
|
|
121
|
+
} & StoreStatus & (({
|
|
122
|
+
auth: Exclude<RouteAuth, 'webhook-signature'>;
|
|
123
|
+
} & RouteEndpoint<AuthedRouteRequest>) | ({
|
|
124
|
+
auth: 'webhook-signature';
|
|
125
|
+
} & RouteEndpoint<RouteRequest>));
|
|
112
126
|
export {};
|
|
113
127
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -2,9 +2,10 @@ import type { IncomingMessage } from 'node:http';
|
|
|
2
2
|
import type { Context, RememberOpts } from '../api/index.js';
|
|
3
3
|
import { type JsonValue } from '../util/json.js';
|
|
4
4
|
export declare function isSetMember<T extends string>(set: ReadonlySet<T>, value: string): value is T;
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const MAX_SHORT_FIELD_LEN = 4096;
|
|
6
6
|
export declare function parseListLimit(limitRaw: string | null, defaultLimit?: number, maxLimit?: number): number;
|
|
7
|
-
/** `_authed` is proof the caller passed auth, so a full-size body is read only for
|
|
7
|
+
/** `_authed` is proof the caller passed auth, so a full-size body is read only for
|
|
8
|
+
* an authenticated caller; the key mint reads under its own small cap. */
|
|
8
9
|
export declare function parseJsonBody(req: IncomingMessage, _authed: Context): Promise<Record<string, JsonValue>>;
|
|
9
10
|
export declare function parseJsonObjectText(raw: string): Record<string, JsonValue>;
|
|
10
11
|
export declare function getString(obj: Record<string, JsonValue>, key: string): string | undefined;
|
|
@@ -1,31 +1,22 @@
|
|
|
1
|
-
import { HttpError,
|
|
1
|
+
import { HttpError, readBody } from '../util/http-util.js';
|
|
2
|
+
import { DEFAULT_LIST_LIMIT, MAX_ID_LEN, MAX_LIST_LIMIT, resolveListLimit } from '../util/limits.js';
|
|
2
3
|
import { isJsonString, isJsonObject } from '../util/json.js';
|
|
3
|
-
// Runtime membership check for a `ReadonlySet<T>` of string-literal
|
|
4
|
-
//
|
|
5
|
-
// Set<T>.has(value: T) itself gives no narrowing (its parameter type is T,
|
|
6
|
-
// not a type predicate) so callers previously needed a separate `as T` cast
|
|
7
|
-
// at both the check and the later usage; this helper is the one place that
|
|
8
|
-
// assertion lives, so downstream call sites narrow via the `value is T`
|
|
9
|
-
// return instead of re-asserting.
|
|
4
|
+
// Runtime membership check for a `ReadonlySet<T>` of string-literal members: Set<T>.has gives no narrowing, so this is the one place the `as T` assertion lives
|
|
5
|
+
// and callers narrow via the `value is T` return.
|
|
10
6
|
export function isSetMember(set, value) {
|
|
11
|
-
// SAFETY: `value as T` is discarded unless `set.has` (the real runtime
|
|
12
|
-
// check) confirms membership; the `value is T` return type is what
|
|
13
|
-
// performs the actual narrowing for callers.
|
|
7
|
+
// SAFETY: `value as T` is discarded unless `set.has` (the real runtime check) confirms membership; the `value is T` return type does the narrowing.
|
|
14
8
|
return set.has(value);
|
|
15
9
|
}
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
if (
|
|
21
|
-
return defaultLimit;
|
|
22
|
-
const limit = Number(limitRaw);
|
|
23
|
-
if (!Number.isInteger(limit) || limit <= 0 || limit > maxLimit) {
|
|
10
|
+
// Cap for short free-text HTTP fields (names, text, context, change summaries) on the object routes.
|
|
11
|
+
export const MAX_SHORT_FIELD_LEN = 4096;
|
|
12
|
+
export function parseListLimit(limitRaw, defaultLimit = DEFAULT_LIST_LIMIT, maxLimit = MAX_LIST_LIMIT) {
|
|
13
|
+
const limit = resolveListLimit(limitRaw === null ? undefined : Number(limitRaw), defaultLimit, maxLimit);
|
|
14
|
+
if (limit === undefined)
|
|
24
15
|
throw new HttpError(400, `limit must be a positive integer <= ${maxLimit}`);
|
|
25
|
-
}
|
|
26
16
|
return limit;
|
|
27
17
|
}
|
|
28
|
-
/** `_authed` is proof the caller passed auth, so a full-size body is read only for
|
|
18
|
+
/** `_authed` is proof the caller passed auth, so a full-size body is read only for
|
|
19
|
+
* an authenticated caller; the key mint reads under its own small cap. */
|
|
29
20
|
export async function parseJsonBody(req, _authed) {
|
|
30
21
|
return parseJsonObjectText(await readBody(req));
|
|
31
22
|
}
|
|
@@ -72,18 +63,9 @@ export function getCallerProject(body) {
|
|
|
72
63
|
}
|
|
73
64
|
return { name: v.name, aliases: v.aliases };
|
|
74
65
|
}
|
|
75
|
-
/**
|
|
76
|
-
*
|
|
77
|
-
|
|
78
|
-
* ids with a useful 400 instead of silently falling through to "not found".
|
|
79
|
-
*
|
|
80
|
-
* Allowed charset matches all production id shapes Hippo emits: `mem_<hex>`,
|
|
81
|
-
* `sum_<hex>`, `sess-<id>`, Slack bot ids like `B01ABCD`, etc. The `:` and
|
|
82
|
-
* `.` are allowed for forward-compat. The `/` is intentionally absent —
|
|
83
|
-
* Hippo never emits ids with slashes, and `rejectEncodedSlash` already
|
|
84
|
-
* stops `%2F`-smuggled ones at the front door.
|
|
85
|
-
*/
|
|
86
|
-
const ID_SEGMENT_RE = /^[A-Za-z0-9_:.\-]+$/;
|
|
66
|
+
/** Charset + length validation for `:id` captures, called right after `matchPath` so empty/overlong/illegal ids get a 400, not "not found".
|
|
67
|
+
* Allows every production id shape (`mem_<hex>`, `sess-<id>`, Slack ids) plus `:` and `.`; no `/`, since `rejectEncodedSlash` stops `%2F` smuggling. */
|
|
68
|
+
const ID_SEGMENT_RE = /^[A-Za-z0-9_:.-]+$/;
|
|
87
69
|
export function validateIdSegment(id, fieldName) {
|
|
88
70
|
if (id.length === 0)
|
|
89
71
|
throw new HttpError(400, `${fieldName} is required`);
|
package/dist/server.d.ts
CHANGED
|
@@ -13,8 +13,9 @@ export type { JsonValue } from './util/json.js';
|
|
|
13
13
|
export { captureSessionTexts, type SessionCaptureRequest, type SessionCaptureResult } from './capture/session-texts.js';
|
|
14
14
|
export { hasGroup, sqliteStore, type AmbientCandidateRequest, type ContextReads, type EntryRemoval, type EntryTarget, type EntryWrite, type EntryWrites, type HippoStore, type KeyAudit, type KeyListQuery, type KeyMint, type KeyRevoke, type KeyWrites, type OutcomeWrite, type RawArchive, type RecallSearchArgs, type RecallWrites, type SelfKeyMint, type StoreGroup, type StoreGroups, type SupersedeWrite, type VectorReads, type VectorBackfillQuery, type VectorRowWrite, type VectorWrite, type VectorWriteResult, type VectorWrites, } from './store/index.js';
|
|
15
15
|
export { entryAfterOutcome } from './core/memory.js';
|
|
16
|
-
export { rejectionDigest
|
|
17
|
-
export {
|
|
16
|
+
export { rejectionDigest } from './store/rejection.js';
|
|
17
|
+
export { RejectedValueError } from './core/api-errors.js';
|
|
18
|
+
export { ownScopeTouches } from './core/recall-scope.js';
|
|
18
19
|
export { BadRequestError, ConflictError } from './core/api-errors.js';
|
|
19
20
|
export type { HippoDbContext, StoreReply } from './api/types.js';
|
|
20
21
|
export type { ApiKeyListItem, ApiKeyListRow, ApiKeyRecord, ListApiKeysOpts, NewApiKey } from './store/auth.js';
|
|
@@ -35,13 +36,13 @@ export type { AmbientLoadResult, AmbientRecallRequest, ContextCandidateFilter, R
|
|
|
35
36
|
export type { AmbientStoreFilter } from './store/ambient.js';
|
|
36
37
|
export type { AmbientTallies } from './core/ambient.js';
|
|
37
38
|
export type { TokenUse } from './store/token-ledger.js';
|
|
38
|
-
export type { EmbeddingIndexState } from './store/
|
|
39
|
+
export type { EmbeddingIndexState } from './store/vector-index.js';
|
|
39
40
|
export type { PhysicsParticle } from './core/physics.js';
|
|
40
|
-
export { StoreBusyError } from './
|
|
41
|
+
export { StoreBusyError } from './store/port.js';
|
|
41
42
|
export { decodeVector, EMBEDDING_MODEL_META_KEY, encodeVector, rankVectorRows, type VectorMatch, type VectorRow } from './db/vector-store.js';
|
|
42
43
|
export { bufferToFloat32, float32ToBuffer } from './db/physics-state.js';
|
|
43
|
-
export { replacesIndex } from './store/
|
|
44
|
-
export { passesScopeFilterForRecall, RECALL_DEFAULT_DENY_SCOPES } from './
|
|
44
|
+
export { replacesIndex } from './store/vector-index.js';
|
|
45
|
+
export { passesScopeFilterForRecall, RECALL_DEFAULT_DENY_SCOPES } from './core/recall-scope.js';
|
|
45
46
|
export { SECRET_TAGS } from './util/secret-detect.js';
|
|
46
47
|
export { tallyAmbientEntries } from './core/ambient.js';
|
|
47
48
|
export { ftsTermParts, rarestFtsQuery } from './core/prompt-recall.js';
|
package/dist/server.js
CHANGED
|
@@ -9,7 +9,8 @@ export { isCrossSite, LOOPBACK_HOST_HEADER } from './util/http-util.js';
|
|
|
9
9
|
export { __resetSessionRecallHistoryHttp } from './server/routes/recall.js';
|
|
10
10
|
export { clientIpForRateLimit } from './server/client-ip.js';
|
|
11
11
|
export { isLoopback, isReservedActor } from './server/auth.js';
|
|
12
|
-
// What an add-on route handler needs: HttpError for its 4xx replies, promptHookContext
|
|
12
|
+
// What an add-on route handler needs: HttpError for its 4xx replies, promptHookContext
|
|
13
|
+
// for a caller that renders the prompt hook elsewhere, JsonValue for its body.
|
|
13
14
|
export { HttpError } from './util/http-util.js';
|
|
14
15
|
export { promptHookContext } from './api/prompt-hook.js';
|
|
15
16
|
// A session-end route stores the turns its caller read from a transcript on the caller's own machine.
|
|
@@ -18,17 +19,18 @@ export { captureSessionTexts } from './capture/session-texts.js';
|
|
|
18
19
|
export { hasGroup, sqliteStore, } from './store/index.js';
|
|
19
20
|
// An add-on store's entry writes apply an outcome, guard tombstones and check reach exactly as hippo.db does.
|
|
20
21
|
export { entryAfterOutcome } from './core/memory.js';
|
|
21
|
-
export { rejectionDigest
|
|
22
|
-
export {
|
|
22
|
+
export { rejectionDigest } from './store/rejection.js';
|
|
23
|
+
export { RejectedValueError } from './core/api-errors.js';
|
|
24
|
+
export { ownScopeTouches } from './core/recall-scope.js';
|
|
23
25
|
export { BadRequestError, ConflictError } from './core/api-errors.js';
|
|
24
|
-
export { StoreBusyError } from './
|
|
26
|
+
export { StoreBusyError } from './store/port.js';
|
|
25
27
|
// An add-on store encodes, decodes and ranks vectors and particles with hippo.db's own code, and drops the index by its rule,
|
|
26
28
|
// so both stores keep the same bytes and return the same ids in the same order.
|
|
27
29
|
export { decodeVector, EMBEDDING_MODEL_META_KEY, encodeVector, rankVectorRows } from './db/vector-store.js';
|
|
28
30
|
export { bufferToFloat32, float32ToBuffer } from './db/physics-state.js';
|
|
29
|
-
export { replacesIndex } from './store/
|
|
31
|
+
export { replacesIndex } from './store/vector-index.js';
|
|
30
32
|
// An add-on's ContextReads applies hippo.db's scope, secret, tally and rarest-term rules with the same code.
|
|
31
|
-
export { passesScopeFilterForRecall, RECALL_DEFAULT_DENY_SCOPES } from './
|
|
33
|
+
export { passesScopeFilterForRecall, RECALL_DEFAULT_DENY_SCOPES } from './core/recall-scope.js';
|
|
32
34
|
export { SECRET_TAGS } from './util/secret-detect.js';
|
|
33
35
|
export { tallyAmbientEntries } from './core/ambient.js';
|
|
34
36
|
export { ftsTermParts, rarestFtsQuery } from './core/prompt-recall.js';
|