hippo-memory 1.72.0 → 2.1.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 +6 -4
- package/dist/agent-memories/apply.d.ts +7 -5
- package/dist/agent-memories/apply.js +66 -39
- package/dist/agent-memories/claude-code.d.ts +8 -2
- package/dist/agent-memories/claude-code.js +26 -7
- package/dist/agent-memories/copilot.js +2 -1
- package/dist/agent-memories/files.js +2 -1
- package/dist/agent-memories/legacy.d.ts +6 -3
- package/dist/agent-memories/legacy.js +35 -14
- package/dist/agent-memories/markdown.d.ts +3 -1
- package/dist/agent-memories/markdown.js +3 -1
- package/dist/agent-memories/openclaw.js +5 -2
- package/dist/agent-memories/plan.js +11 -1
- package/dist/agent-memories/project-folds.js +2 -1
- package/dist/agent-memories/report.d.ts +4 -1
- package/dist/agent-memories/report.js +43 -9
- package/dist/agent-memories/source.d.ts +8 -2
- package/dist/agent-memories/source.js +11 -3
- package/dist/agent-memories/sync.d.ts +7 -2
- package/dist/agent-memories/sync.js +141 -101
- package/dist/api/assemble.d.ts +6 -4
- package/dist/api/assemble.js +11 -5
- package/dist/api/{audit.d.ts → auth/audit.d.ts} +18 -16
- package/dist/api/auth/audit.js +58 -0
- package/dist/api/{auth.d.ts → auth/auth.d.ts} +19 -16
- package/dist/api/{auth.js → auth/auth.js} +66 -54
- package/dist/api/{quarantine.d.ts → auth/quarantine.d.ts} +8 -7
- package/dist/api/{quarantine.js → auth/quarantine.js} +8 -7
- package/dist/api/auth/session-owners.d.ts +10 -0
- package/dist/api/auth/session-owners.js +35 -0
- package/dist/api/availability.d.ts +3 -1
- package/dist/api/availability.js +3 -1
- package/dist/api/busy.d.ts +2 -0
- package/dist/api/busy.js +2 -0
- package/dist/api/cli-surface.d.ts +6 -0
- package/dist/api/cli-surface.js +6 -0
- package/dist/api/config-of.d.ts +5 -0
- package/dist/api/config-of.js +6 -0
- package/dist/api/context-auto.d.ts +4 -1
- package/dist/api/context-auto.js +14 -4
- package/dist/api/context-render.js +14 -7
- package/dist/api/context-select.d.ts +4 -1
- package/dist/api/context-select.js +31 -34
- package/dist/api/context-types.d.ts +38 -12
- package/dist/api/context.d.ts +8 -5
- package/dist/api/context.js +120 -63
- package/dist/api/continuity.d.ts +24 -21
- package/dist/api/continuity.js +18 -20
- package/dist/api/correction-latency.d.ts +3 -1
- package/dist/api/correction-latency.js +3 -1
- package/dist/api/error-reply.d.ts +4 -1
- package/dist/api/error-reply.js +12 -3
- package/dist/api/index.d.ts +39 -23
- package/dist/api/index.js +21 -23
- package/dist/api/instruction-detect.d.ts +4 -1
- package/dist/api/instruction-detect.js +75 -20
- package/dist/api/ledger-db.d.ts +15 -11
- package/dist/api/ledger-db.js +21 -23
- package/dist/api/memories/conflicts.d.ts +33 -0
- package/dist/api/memories/conflicts.js +67 -0
- package/dist/api/{forget.d.ts → memories/forget.d.ts} +11 -9
- package/dist/api/{forget.js → memories/forget.js} +23 -17
- package/dist/api/memories/memories.d.ts +27 -0
- package/dist/api/memories/memories.js +52 -0
- package/dist/api/memories/outcome.d.ts +22 -0
- package/dist/api/memories/outcome.js +28 -0
- package/dist/api/memories/promote.d.ts +40 -0
- package/dist/api/memories/promote.js +76 -0
- package/dist/api/memories/refine.d.ts +10 -0
- package/dist/api/memories/refine.js +12 -0
- package/dist/api/{remember-local.d.ts → memories/remember-local.d.ts} +17 -9
- package/dist/api/{remember-local.js → memories/remember-local.js} +46 -24
- package/dist/api/{remember.d.ts → memories/remember.d.ts} +22 -13
- package/dist/api/{remember.js → memories/remember.js} +50 -32
- package/dist/api/objects/cards.d.ts +39 -0
- package/dist/api/{cards.js → objects/cards.js} +12 -14
- package/dist/api/{drill-down.d.ts → objects/drill-down.d.ts} +12 -10
- package/dist/api/{drill-down.js → objects/drill-down.js} +7 -7
- package/dist/api/objects/goals.d.ts +18 -0
- package/dist/api/{goals.js → objects/goals.js} +12 -12
- package/dist/api/objects/graph.d.ts +11 -0
- package/dist/api/objects/graph.js +16 -0
- package/dist/api/objects/objects.d.ts +9 -0
- package/dist/api/{objects.js → objects/objects.js} +2 -3
- package/dist/api/objects/predictions.d.ts +11 -0
- package/dist/api/{predictions.js → objects/predictions.js} +7 -5
- package/dist/api/{projects.d.ts → objects/projects.d.ts} +8 -5
- package/dist/api/{projects.js → objects/projects.js} +8 -4
- package/dist/api/pilot-arm.d.ts +8 -4
- package/dist/api/pilot-arm.js +5 -4
- package/dist/api/prompt-hook.d.ts +35 -20
- package/dist/api/prompt-hook.js +66 -44
- package/dist/api/provenance-coverage.d.ts +3 -1
- package/dist/api/provenance-coverage.js +3 -1
- package/dist/api/recall/finish.d.ts +185 -0
- package/dist/api/recall/finish.js +301 -0
- package/dist/api/{recall-pipeline.d.ts → recall/pipeline.d.ts} +12 -8
- package/dist/api/{recall-pipeline.js → recall/pipeline.js} +185 -101
- package/dist/api/recall/recall.d.ts +6 -0
- package/dist/api/{recall.js → recall/recall.js} +116 -72
- package/dist/api/recall/render.d.ts +39 -0
- package/dist/api/recall/render.js +60 -0
- package/dist/api/{recall-request.d.ts → recall/request.d.ts} +7 -5
- package/dist/api/recall/request.js +261 -0
- package/dist/api/{recall-cli.d.ts → recall/rows.d.ts} +18 -12
- package/dist/api/{recall-cli.js → recall/rows.js} +28 -27
- package/dist/api/{recall-types.d.ts → recall/types.d.ts} +95 -68
- package/dist/api/{recall-types.js → recall/types.js} +1 -1
- package/dist/api/session-end.d.ts +36 -8
- package/dist/api/session-end.js +71 -25
- package/dist/api/{auto-sleep.d.ts → sleep/auto-sleep.d.ts} +9 -5
- package/dist/api/{auto-sleep.js → sleep/auto-sleep.js} +7 -12
- package/dist/api/sleep/dormant.d.ts +25 -0
- package/dist/api/sleep/dormant.js +64 -0
- package/dist/api/{learn.d.ts → sleep/learn.d.ts} +5 -4
- package/dist/api/sleep/learn.js +138 -0
- package/dist/api/sleep/sleep-run.d.ts +38 -0
- package/dist/api/{sleep-run.js → sleep/sleep-run.js} +54 -45
- package/dist/api/{sleep.d.ts → sleep/sleep.d.ts} +17 -11
- package/dist/api/sleep/sleep.js +9 -0
- package/dist/api/status.d.ts +3 -1
- package/dist/api/status.js +3 -1
- package/dist/api/store-init.d.ts +4 -1
- package/dist/api/store-init.js +4 -1
- package/dist/api/tokens.d.ts +10 -9
- package/dist/api/tokens.js +9 -10
- package/dist/api/types.d.ts +27 -12
- package/dist/api/types.js +13 -4
- package/dist/capture/caller-session.d.ts +8 -2
- package/dist/capture/caller-session.js +16 -6
- package/dist/capture/capture-error.d.ts +3 -1
- package/dist/capture/capture-error.js +3 -1
- package/dist/capture/codex-patch.js +7 -2
- package/dist/capture/command.d.ts +4 -2
- package/dist/capture/command.js +34 -15
- package/dist/capture/compact-resume-caller.js +15 -8
- package/dist/capture/compact.d.ts +8 -5
- package/dist/capture/compact.js +34 -23
- package/dist/capture/compaction-items-caller.js +9 -3
- package/dist/capture/compaction-record.d.ts +4 -3
- package/dist/capture/compaction-record.js +20 -12
- package/dist/capture/compaction-spool.d.ts +18 -9
- package/dist/capture/compaction-spool.js +105 -63
- package/dist/capture/copilot-transcript.d.ts +11 -3
- package/dist/capture/copilot-transcript.js +16 -6
- package/dist/capture/extract.js +20 -8
- package/dist/capture/failure-caller.js +23 -12
- package/dist/capture/failure-reading.d.ts +10 -3
- package/dist/capture/failure-reading.js +24 -7
- package/dist/capture/pre-compact-caller.js +11 -4
- package/dist/capture/session-digest.d.ts +15 -4
- package/dist/capture/session-digest.js +39 -13
- package/dist/capture/session-end-caller.d.ts +4 -1
- package/dist/capture/session-end-caller.js +20 -8
- package/dist/capture/session-texts.d.ts +6 -2
- package/dist/capture/session-texts.js +22 -7
- package/dist/capture/session-worker.d.ts +4 -2
- package/dist/capture/session-worker.js +58 -17
- package/dist/capture/transcript.d.ts +13 -4
- package/dist/capture/transcript.js +32 -10
- package/dist/capture/working-state.d.ts +13 -4
- package/dist/capture/working-state.js +50 -56
- package/dist/cli/api-context.d.ts +14 -2
- package/dist/cli/api-context.js +45 -2
- package/dist/cli/audit.js +33 -33
- package/dist/cli/auth.js +23 -31
- package/dist/cli/briefs.d.ts +1 -1
- package/dist/cli/briefs.js +20 -15
- package/dist/cli/card.d.ts +1 -1
- package/dist/cli/card.js +56 -73
- package/dist/cli/client.d.ts +12 -5
- package/dist/cli/client.js +53 -23
- package/dist/cli/compact-resume-payload.d.ts +4 -1
- package/dist/cli/compact-resume-payload.js +12 -5
- package/dist/cli/context.js +43 -18
- package/dist/cli/continuity.d.ts +5 -5
- package/dist/cli/continuity.js +90 -107
- package/dist/cli/curate.d.ts +5 -4
- package/dist/cli/curate.js +55 -77
- package/dist/cli/dag.d.ts +1 -1
- package/dist/cli/dag.js +14 -17
- package/dist/cli/decisions.js +30 -30
- package/dist/cli/eval.js +16 -21
- package/dist/cli/exit.d.ts +4 -1
- package/dist/cli/exit.js +10 -2
- package/dist/cli/explain.js +12 -11
- package/dist/cli/flag-values.d.ts +1 -1
- package/dist/cli/flag-values.js +9 -18
- package/dist/cli/github.d.ts +6 -0
- package/dist/cli/github.js +25 -13
- package/dist/cli/goals.d.ts +1 -1
- package/dist/cli/goals.js +39 -56
- package/dist/cli/graph.d.ts +1 -1
- package/dist/cli/graph.js +15 -11
- package/dist/cli/hook-runtime.d.ts +34 -10
- package/dist/cli/hook-runtime.js +41 -16
- package/dist/cli/incidents.d.ts +1 -1
- package/dist/cli/incidents.js +25 -25
- package/dist/cli/init.d.ts +1 -1
- package/dist/cli/init.js +35 -20
- package/dist/cli/install-steps.d.ts +12 -3
- package/dist/cli/install-steps.js +42 -18
- package/dist/cli/last-sleep.d.ts +4 -1
- package/dist/cli/last-sleep.js +9 -4
- package/dist/cli/maintenance.d.ts +1 -1
- package/dist/cli/maintenance.js +11 -12
- package/dist/cli/notes.d.ts +1 -1
- package/dist/cli/notes.js +8 -5
- package/dist/cli/object-verbs.d.ts +5 -5
- package/dist/cli/object-verbs.js +13 -16
- package/dist/cli/open-browser.js +11 -2
- package/dist/cli/playbooks.d.ts +3 -3
- package/dist/cli/playbooks.js +40 -32
- package/dist/cli/predictions.js +17 -22
- package/dist/cli/print.js +4 -2
- package/dist/cli/projects.js +21 -11
- package/dist/cli/quality-repair-once.d.ts +1 -1
- package/dist/cli/quality-repair-once.js +7 -6
- package/dist/cli/recall.js +129 -93
- package/dist/cli/refine-llm.d.ts +15 -4
- package/dist/cli/refine-llm.js +17 -7
- package/dist/cli/remember.js +51 -55
- package/dist/cli/scheduler.d.ts +4 -1
- package/dist/cli/scheduler.js +9 -5
- package/dist/cli/serve.js +28 -18
- package/dist/cli/session-hooks.d.ts +2 -6
- package/dist/cli/session-hooks.js +140 -112
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.js +56 -34
- package/dist/cli/shared.d.ts +4 -2
- package/dist/cli/shared.js +26 -11
- package/dist/cli/slack.js +15 -24
- package/dist/cli/sleep-render.d.ts +3 -1
- package/dist/cli/sleep-render.js +8 -5
- package/dist/cli/sleep.js +16 -8
- package/dist/cli/status.d.ts +4 -4
- package/dist/cli/status.js +32 -27
- package/dist/cli/stdin.d.ts +10 -3
- package/dist/cli/stdin.js +10 -3
- package/dist/cli/transfer.d.ts +4 -4
- package/dist/cli/transfer.js +97 -82
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/usage.js +1 -1
- package/dist/cli/verb-row.d.ts +2 -0
- package/dist/cli/verbs/health.js +2 -0
- package/dist/cli/verbs/memory.js +47 -53
- package/dist/cli/verbs/objects.js +16 -7
- package/dist/cli/verbs/sessions.js +4 -2
- package/dist/cli/versioned-verbs.d.ts +8 -7
- package/dist/cli/versioned-verbs.js +31 -21
- package/dist/cli.js +14 -18
- package/dist/connectors/dlq.d.ts +6 -6
- package/dist/connectors/dlq.js +12 -7
- package/dist/connectors/github/backfill.d.ts +4 -4
- package/dist/connectors/github/backfill.js +6 -4
- package/dist/connectors/github/deletion.d.ts +6 -4
- package/dist/connectors/github/deletion.js +5 -4
- package/dist/connectors/github/dlq.d.ts +8 -6
- package/dist/connectors/github/dlq.js +11 -5
- package/dist/connectors/github/ingest.d.ts +2 -2
- package/dist/connectors/github/ingest.js +9 -5
- package/dist/connectors/github/octokit-client.d.ts +3 -1
- package/dist/connectors/github/octokit-client.js +7 -2
- package/dist/connectors/github/ratelimit.d.ts +6 -2
- package/dist/connectors/github/ratelimit.js +6 -2
- package/dist/connectors/github/signature.d.ts +14 -3
- package/dist/connectors/github/signature.js +17 -3
- package/dist/connectors/github/tenant-routing.d.ts +6 -4
- package/dist/connectors/github/tenant-routing.js +6 -5
- package/dist/connectors/github/transform.js +50 -67
- package/dist/connectors/github/types.d.ts +10 -3
- package/dist/connectors/github/types.js +6 -2
- package/dist/connectors/github/webhook.d.ts +5 -5
- package/dist/connectors/github/webhook.js +36 -23
- package/dist/connectors/ingest.d.ts +5 -3
- package/dist/connectors/ingest.js +3 -3
- package/dist/connectors/slack/backfill.d.ts +5 -5
- package/dist/connectors/slack/backfill.js +3 -3
- package/dist/connectors/slack/deletion.d.ts +4 -4
- package/dist/connectors/slack/deletion.js +6 -5
- package/dist/connectors/slack/dlq.d.ts +4 -4
- package/dist/connectors/slack/dlq.js +6 -6
- package/dist/connectors/slack/ingest.d.ts +6 -4
- package/dist/connectors/slack/ingest.js +5 -4
- package/dist/connectors/slack/signature.d.ts +4 -1
- package/dist/connectors/slack/tenant-routing.d.ts +6 -4
- package/dist/connectors/slack/tenant-routing.js +6 -5
- package/dist/connectors/slack/transform.d.ts +6 -2
- package/dist/connectors/slack/transform.js +6 -2
- package/dist/connectors/slack/types.d.ts +3 -1
- package/dist/connectors/slack/web-client.js +8 -3
- package/dist/connectors/slack/webhook.d.ts +5 -5
- package/dist/connectors/slack/webhook.js +19 -11
- package/dist/connectors/slack/workspaces.d.ts +7 -3
- package/dist/connectors/slack/workspaces.js +7 -3
- package/dist/connectors/store.d.ts +8 -0
- package/dist/connectors/store.js +2 -0
- package/dist/consolidate/conflicts.js +24 -10
- package/dist/consolidate/dag-summary.js +2 -1
- package/dist/consolidate/dag.d.ts +10 -5
- package/dist/consolidate/dag.js +45 -39
- package/dist/consolidate/decay.js +19 -6
- package/dist/consolidate/dedupe.d.ts +14 -5
- package/dist/consolidate/dedupe.js +28 -17
- package/dist/consolidate/flush-units.d.ts +4 -1
- package/dist/consolidate/flush-units.js +4 -1
- package/dist/consolidate/half-life-migration.d.ts +18 -8
- package/dist/consolidate/half-life-migration.js +48 -18
- package/dist/consolidate/llm-passes.js +27 -11
- package/dist/consolidate/memory-value-weights.d.ts +6 -2
- package/dist/consolidate/memory-value-weights.js +6 -2
- package/dist/consolidate/memory-value.d.ts +30 -10
- package/dist/consolidate/memory-value.js +37 -14
- package/dist/consolidate/merge.d.ts +4 -1
- package/dist/consolidate/merge.js +47 -37
- package/dist/consolidate/overlap-index.d.ts +8 -2
- package/dist/consolidate/overlap-index.js +11 -4
- package/dist/consolidate/physics-pass.d.ts +3 -1
- package/dist/consolidate/physics-pass.js +10 -7
- package/dist/consolidate/replay.d.ts +11 -4
- package/dist/consolidate/replay.js +19 -7
- package/dist/consolidate/run.d.ts +13 -5
- package/dist/consolidate/run.js +4 -4
- package/dist/consolidate/sleep.d.ts +14 -6
- package/dist/consolidate/sleep.js +42 -39
- package/dist/consolidate/trace.d.ts +7 -2
- package/dist/consolidate/trace.js +7 -2
- package/dist/consolidate/traces.js +27 -30
- package/dist/core/ablation.d.ts +9 -3
- package/dist/core/ablation.js +14 -4
- package/dist/core/active-scope.d.ts +3 -1
- package/dist/core/active-scope.js +3 -1
- package/dist/core/agent-memory-tools.d.ts +2 -0
- package/dist/core/agent-memory-tools.js +2 -0
- package/dist/core/ambient.d.ts +4 -3
- package/dist/core/ambient.js +8 -6
- package/dist/core/api-errors.d.ts +9 -3
- package/dist/core/api-errors.js +9 -3
- package/dist/core/capture-contract.d.ts +4 -1
- package/dist/core/capture-contract.js +27 -8
- package/dist/core/compare.d.ts +24 -8
- package/dist/core/compare.js +24 -8
- package/dist/core/config.d.ts +18 -9
- package/dist/core/config.js +38 -29
- package/dist/core/cosine.d.ts +4 -1
- package/dist/core/cosine.js +4 -1
- package/dist/core/handoff.d.ts +7 -2
- package/dist/core/handoff.js +4 -1
- package/dist/core/markdown.js +22 -17
- package/dist/core/memory-audit.js +14 -3
- package/dist/core/memory-quality.d.ts +12 -3
- package/dist/core/memory-quality.js +57 -21
- package/dist/core/memory.d.ts +87 -30
- package/dist/core/memory.js +82 -33
- package/dist/core/merged-row.d.ts +8 -2
- package/dist/core/merged-row.js +10 -3
- package/dist/core/package-root.d.ts +3 -1
- package/dist/core/package-root.js +3 -1
- package/dist/core/particle-refresh.d.ts +8 -0
- package/dist/core/particle-refresh.js +22 -0
- package/dist/core/physics-config.d.ts +4 -1
- package/dist/core/physics-config.js +6 -2
- package/dist/core/physics.d.ts +39 -11
- package/dist/core/physics.js +71 -21
- package/dist/core/project-identity.d.ts +34 -17
- package/dist/core/project-identity.js +35 -18
- package/dist/core/project-remote.d.ts +8 -4
- package/dist/core/project-remote.js +31 -14
- package/dist/core/recall-scope.d.ts +33 -11
- package/dist/core/recall-scope.js +42 -15
- package/dist/core/rejection-digest.d.ts +7 -0
- package/dist/core/rejection-digest.js +13 -0
- package/dist/core/salience.d.ts +3 -1
- package/dist/core/salience.js +10 -4
- package/dist/core/search-types.d.ts +15 -2
- package/dist/core/search-types.js +11 -0
- package/dist/dashboard/dashboard-actions.d.ts +2 -2
- package/dist/dashboard/dashboard-actions.js +18 -7
- package/dist/dashboard/dashboard-queries.js +2 -7
- package/dist/dashboard/dashboard-snapshot.d.ts +2 -2
- package/dist/dashboard/dashboard-snapshot.js +5 -7
- package/dist/dashboard/dashboard.js +22 -8
- package/dist/db/backup.js +2 -2
- package/dist/db/busy.d.ts +10 -3
- package/dist/db/busy.js +27 -5
- package/dist/db/connect.d.ts +10 -2
- package/dist/db/connect.js +8 -2
- package/dist/db/continuity.d.ts +1 -1
- package/dist/db/continuity.js +27 -11
- package/dist/db/meta.d.ts +4 -1
- package/dist/db/meta.js +4 -1
- package/dist/db/migrate.d.ts +10 -5
- package/dist/db/migrate.js +40 -20
- 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 -1
- package/dist/db/migrations/v11.js +1 -0
- package/dist/db/migrations/v12.js +2 -1
- package/dist/db/migrations/v14.js +2 -0
- package/dist/db/migrations/v15.js +4 -2
- package/dist/db/migrations/v16.js +6 -3
- package/dist/db/migrations/v17.js +2 -1
- package/dist/db/migrations/v19.js +4 -2
- package/dist/db/migrations/v20.js +2 -1
- package/dist/db/migrations/v22.js +12 -6
- package/dist/db/migrations/v23.js +6 -3
- package/dist/db/migrations/v24.js +6 -3
- package/dist/db/migrations/v25.js +4 -2
- package/dist/db/migrations/v26.js +4 -2
- package/dist/db/migrations/v27.js +6 -3
- package/dist/db/migrations/v28.js +4 -2
- package/dist/db/migrations/v29.js +4 -2
- package/dist/db/migrations/v30.js +6 -3
- package/dist/db/migrations/v31.js +4 -2
- package/dist/db/migrations/v32.js +6 -3
- package/dist/db/migrations/v33.js +4 -2
- package/dist/db/migrations/v34.js +2 -1
- package/dist/db/migrations/v35.js +2 -1
- package/dist/db/migrations/v36.js +2 -1
- package/dist/db/migrations/v37.js +10 -5
- package/dist/db/migrations/v38.js +10 -5
- package/dist/db/migrations/v39.js +14 -6
- package/dist/db/migrations/v40.js +4 -2
- package/dist/db/migrations/v41.js +4 -2
- package/dist/db/migrations/v42.js +2 -1
- package/dist/db/migrations/v44.js +4 -2
- package/dist/db/migrations/v45.js +4 -2
- package/dist/db/migrations/v49.js +2 -1
- package/dist/db/migrations/v50.js +4 -2
- package/dist/db/migrations/v51.js +4 -2
- package/dist/db/migrations/v52.js +2 -1
- package/dist/db/migrations/v53.js +8 -4
- package/dist/db/migrations/v54.js +2 -1
- package/dist/db/migrations/v55.js +4 -2
- package/dist/db/migrations/v56.d.ts +3 -0
- package/dist/db/migrations/v56.js +28 -0
- package/dist/db/open.d.ts +24 -12
- package/dist/db/open.js +25 -13
- package/dist/db/physics-state.d.ts +8 -8
- package/dist/db/physics-state.js +17 -50
- package/dist/db/raw-archive-mirror-cleanup.d.ts +4 -2
- package/dist/db/raw-archive-mirror-cleanup.js +6 -4
- package/dist/db/request-stores.d.ts +20 -5
- package/dist/db/request-stores.js +15 -5
- package/dist/db/tables.d.ts +2 -1
- package/dist/db/tables.js +12 -4
- package/dist/db/vector-store.d.ts +13 -4
- package/dist/db/vector-store.js +35 -14
- package/dist/db/wal-checkpointer.d.ts +2 -1
- package/dist/db/wal-checkpointer.js +19 -7
- package/dist/doctor.d.ts +7 -1
- package/dist/doctor.js +128 -46
- package/dist/embeddings/local.d.ts +8 -4
- package/dist/embeddings/local.js +11 -7
- package/dist/embeddings/provider.d.ts +19 -10
- package/dist/embeddings/provider.js +32 -27
- package/dist/embeddings/transformers.d.ts +16 -4
- package/dist/embeddings/transformers.js +32 -15
- package/dist/entry/json-hooks.d.ts +1 -1
- package/dist/entry/json-hooks.js +1 -1
- package/dist/entry/project-identity.js +2 -1
- package/dist/entry/session-text.d.ts +1 -1
- package/dist/entry/session-text.js +1 -1
- package/dist/entry/sqlite-handles.d.ts +10 -0
- package/dist/entry/sqlite-handles.js +9 -0
- package/dist/entry/store-kit.d.ts +50 -0
- package/dist/entry/store-kit.js +27 -0
- package/dist/entry/testing.d.ts +6 -0
- package/dist/entry/testing.js +7 -0
- package/dist/eval/eval-stats.d.ts +27 -8
- package/dist/eval/eval-stats.js +17 -5
- package/dist/eval/eval-suite.d.ts +3 -1
- package/dist/eval/eval-suite.js +409 -187
- package/dist/eval/eval.d.ts +8 -2
- package/dist/eval/eval.js +8 -2
- package/dist/eval/judgment.js +17 -7
- package/dist/graph/delta.d.ts +9 -42
- package/dist/graph/delta.js +17 -11
- package/dist/graph/extract.d.ts +10 -7
- package/dist/graph/extract.js +57 -25
- package/dist/graph/recall.d.ts +12 -4
- package/dist/graph/recall.js +30 -13
- package/dist/graph/stream.d.ts +18 -6
- package/dist/graph/stream.js +32 -10
- package/dist/graph/view.d.ts +19 -6
- package/dist/graph/view.js +42 -17
- package/dist/hooks/codex-session.js +2 -2
- package/dist/hooks/codex-wrapper.d.ts +3 -1
- package/dist/hooks/codex-wrapper.js +9 -4
- package/dist/hooks/copilot.d.ts +19 -5
- package/dist/hooks/copilot.js +54 -15
- package/dist/hooks/hook-blocks.d.ts +4 -1
- package/dist/hooks/hook-blocks.js +8 -3
- package/dist/hooks/json-hooks.d.ts +9 -5
- package/dist/hooks/json-hooks.js +72 -33
- package/dist/hooks/opencode.js +15 -5
- package/dist/hooks/shared.d.ts +27 -8
- package/dist/hooks/shared.js +57 -16
- package/dist/importers/core.d.ts +12 -4
- package/dist/importers/core.js +11 -10
- package/dist/importers/markdown-parse.d.ts +15 -5
- package/dist/importers/markdown-parse.js +16 -7
- package/dist/importers/markdown.js +6 -9
- package/dist/importers/sources.js +10 -23
- package/dist/importers/vault.d.ts +3 -3
- package/dist/importers/vault.js +61 -45
- package/dist/index.d.ts +33 -7
- package/dist/index.js +26 -8
- package/dist/learn/autolearn.d.ts +21 -6
- package/dist/learn/autolearn.js +57 -26
- package/dist/learn/churn-git.d.ts +4 -1
- package/dist/learn/churn-git.js +29 -5
- package/dist/learn/extract.d.ts +4 -1
- package/dist/learn/extract.js +17 -10
- package/dist/learn/forward-claim-detector.d.ts +17 -5
- package/dist/learn/forward-claim-detector.js +34 -15
- package/dist/learn/invalidation.d.ts +12 -6
- package/dist/learn/invalidation.js +62 -28
- package/dist/learn/roots.d.ts +3 -0
- package/dist/learn/roots.js +5 -0
- package/dist/mcp/admin-tools.d.ts +5 -5
- package/dist/mcp/admin-tools.js +28 -23
- package/dist/mcp/format.d.ts +1 -1
- package/dist/mcp/format.js +4 -2
- package/dist/mcp/framing.d.ts +3 -1
- package/dist/mcp/framing.js +20 -8
- package/dist/mcp/memory-tools.d.ts +3 -3
- package/dist/mcp/memory-tools.js +21 -20
- package/dist/mcp/protocol.d.ts +32 -16
- package/dist/mcp/protocol.js +12 -9
- package/dist/mcp/recall-tools.d.ts +3 -3
- package/dist/mcp/recall-tools.js +62 -74
- package/dist/mcp/request.d.ts +7 -5
- package/dist/mcp/request.js +61 -77
- package/dist/mcp/server.d.ts +3 -1
- package/dist/mcp/server.js +8 -3
- package/dist/mcp/session-state.d.ts +1 -1
- package/dist/mcp/session-state.js +4 -3
- package/dist/mcp/shared-gate.d.ts +3 -2
- package/dist/mcp/shared-gate.js +3 -2
- package/dist/mcp/stdio.d.ts +6 -3
- package/dist/mcp/stdio.js +59 -23
- package/dist/mcp/tool-args.d.ts +4 -1
- package/dist/mcp/tool-args.js +8 -3
- package/dist/mcp/tools.js +76 -32
- package/dist/objects/customer-notes.d.ts +12 -10
- package/dist/objects/customer-notes.js +21 -15
- package/dist/objects/decisions.d.ts +18 -10
- package/dist/objects/decisions.js +23 -17
- package/dist/objects/descriptor.js +2 -1
- package/dist/objects/fields.d.ts +4 -1
- package/dist/objects/fields.js +6 -2
- package/dist/objects/incidents.d.ts +14 -16
- package/dist/objects/incidents.js +29 -30
- package/dist/objects/lifecycle.d.ts +0 -4
- package/dist/objects/lifecycle.js +21 -24
- package/dist/objects/policies.d.ts +12 -16
- package/dist/objects/policies.js +17 -21
- package/dist/objects/processes.d.ts +16 -10
- package/dist/objects/processes.js +20 -15
- package/dist/objects/project-briefs.d.ts +13 -14
- package/dist/objects/project-briefs.js +33 -39
- package/dist/objects/skills.d.ts +10 -12
- package/dist/objects/skills.js +17 -22
- package/dist/postinstall.js +15 -7
- package/dist/predictions/planning-fallacy.d.ts +19 -6
- package/dist/predictions/planning-fallacy.js +4 -2
- package/dist/rerankers/clef.d.ts +8 -2
- package/dist/rerankers/clef.js +14 -9
- package/dist/rerankers/cross-encoder.d.ts +2 -1
- package/dist/rerankers/cross-encoder.js +19 -9
- package/dist/rerankers/index.js +2 -1
- package/dist/rerankers/jev.js +2 -1
- package/dist/rerankers/llm.d.ts +6 -2
- package/dist/rerankers/llm.js +8 -3
- package/dist/rerankers/remote.d.ts +3 -1
- package/dist/rerankers/remote.js +5 -2
- package/dist/rerankers/types.d.ts +6 -2
- package/dist/search/bm25-search.d.ts +3 -1
- package/dist/search/bm25-search.js +15 -2
- package/dist/search/boosts.js +4 -3
- package/dist/search/embed-memories.d.ts +12 -4
- package/dist/search/embed-memories.js +96 -58
- package/dist/search/engine.d.ts +11 -0
- package/dist/search/engine.js +14 -0
- package/dist/search/goal-boost.d.ts +10 -3
- package/dist/search/goal-boost.js +13 -6
- package/dist/search/hybrid-score.d.ts +4 -1
- package/dist/search/hybrid-score.js +4 -1
- package/dist/search/hybrid.d.ts +23 -8
- package/dist/search/hybrid.js +12 -7
- package/dist/search/multihop.js +14 -13
- package/dist/search/path-context.d.ts +10 -3
- package/dist/search/path-context.js +10 -3
- package/dist/search/physics-search.d.ts +9 -4
- package/dist/search/physics-search.js +38 -14
- package/dist/search/rerank.d.ts +2 -1
- package/dist/search/rerank.js +2 -1
- package/dist/search/rrf.d.ts +14 -5
- package/dist/search/rrf.js +11 -4
- package/dist/search/vector.d.ts +8 -2
- package/dist/search/vector.js +14 -8
- package/dist/server/auth.d.ts +19 -15
- package/dist/server/auth.js +68 -38
- package/dist/server/boot.d.ts +4 -1
- package/dist/server/boot.js +115 -67
- package/dist/server/client-ip.d.ts +17 -5
- package/dist/server/client-ip.js +56 -21
- package/dist/server/cursor.d.ts +10 -3
- package/dist/server/cursor.js +10 -3
- package/dist/server/deadline.d.ts +5 -2
- package/dist/server/deadline.js +10 -3
- package/dist/server/key-check-bounds.js +12 -4
- package/dist/server/lifecycle.d.ts +4 -1
- package/dist/server/lifecycle.js +10 -4
- package/dist/server/mcp-http.d.ts +2 -1
- package/dist/server/mcp-http.js +37 -22
- package/dist/server/rate-limit.d.ts +17 -5
- package/dist/server/rate-limit.js +55 -26
- package/dist/server/ready.js +7 -4
- package/dist/server/request.d.ts +15 -4
- package/dist/server/request.js +42 -15
- package/dist/server/route-checks.d.ts +4 -1
- package/dist/server/route-checks.js +8 -3
- package/dist/server/route-table.d.ts +8 -6
- package/dist/server/route-table.js +550 -97
- package/dist/server/routes/admin.d.ts +7 -7
- package/dist/server/routes/admin.js +36 -15
- package/dist/server/routes/customer-notes.d.ts +5 -5
- package/dist/server/routes/customer-notes.js +5 -4
- package/dist/server/routes/decisions.d.ts +5 -5
- package/dist/server/routes/decisions.js +12 -6
- package/dist/server/routes/incidents.d.ts +5 -5
- package/dist/server/routes/incidents.js +10 -4
- package/dist/server/routes/memories.d.ts +8 -8
- package/dist/server/routes/memories.js +12 -17
- package/dist/server/routes/object-routes.d.ts +8 -5
- package/dist/server/routes/object-routes.js +4 -2
- package/dist/server/routes/policies.d.ts +6 -6
- package/dist/server/routes/policies.js +11 -4
- package/dist/server/routes/predictions.d.ts +5 -5
- package/dist/server/routes/predictions.js +9 -4
- package/dist/server/routes/processes.d.ts +5 -5
- package/dist/server/routes/processes.js +15 -6
- package/dist/server/routes/project-briefs.d.ts +6 -6
- package/dist/server/routes/project-briefs.js +3 -2
- package/dist/server/routes/recall.d.ts +3 -3
- package/dist/server/routes/recall.js +21 -10
- package/dist/server/routes/skills.d.ts +6 -6
- package/dist/server/routes/skills.js +12 -4
- package/dist/server/server-detect.d.ts +24 -8
- package/dist/server/server-detect.js +57 -22
- package/dist/server/sleep-child.js +16 -10
- package/dist/server/sleep-offload.d.ts +8 -5
- package/dist/server/sleep-offload.js +40 -18
- package/dist/server/tls.d.ts +10 -2
- package/dist/server/tls.js +25 -5
- package/dist/server/types.d.ts +41 -24
- package/dist/server/validation.d.ts +4 -1
- package/dist/server/validation.js +22 -9
- package/dist/server.d.ts +17 -49
- package/dist/server.js +33 -40
- package/dist/sharing/global-store.d.ts +6 -12
- package/dist/sharing/global-store.js +8 -48
- package/dist/sharing/global-sync.d.ts +3 -1
- package/dist/sharing/global-sync.js +17 -7
- package/dist/sharing/project-merge.d.ts +25 -7
- package/dist/sharing/project-merge.js +49 -17
- package/dist/sharing/search-both.d.ts +8 -4
- package/dist/sharing/search-both.js +28 -14
- package/dist/sharing/share.d.ts +8 -4
- package/dist/sharing/share.js +40 -18
- package/dist/store/ambient.js +10 -5
- package/dist/store/audit-event.d.ts +2 -2
- package/dist/store/audit-event.js +8 -3
- package/dist/store/audit.d.ts +6 -3
- package/dist/store/audit.js +16 -6
- package/dist/store/auth.d.ts +4 -2
- package/dist/store/auth.js +63 -20
- package/dist/store/busy.d.ts +9 -0
- package/dist/store/busy.js +16 -0
- package/dist/store/candidates.d.ts +12 -5
- package/dist/store/candidates.js +90 -41
- package/dist/store/capture-write.d.ts +2 -1
- package/dist/store/capture-write.js +2 -1
- package/dist/store/card-detail.d.ts +4 -4
- package/dist/store/card-detail.js +15 -8
- package/dist/store/cards.d.ts +24 -10
- package/dist/store/cards.js +97 -63
- package/dist/store/compaction-caller.d.ts +2 -1
- package/dist/store/compaction-caller.js +2 -1
- package/dist/store/compactions-record.d.ts +14 -8
- package/dist/store/compactions-record.js +101 -37
- package/dist/store/compactions.js +35 -15
- package/dist/store/conflicts.d.ts +16 -5
- package/dist/store/conflicts.js +104 -48
- package/dist/store/connectors/dlq.d.ts +17 -5
- package/dist/store/connectors/dlq.js +58 -6
- package/dist/store/connectors/event-log.d.ts +122 -0
- package/dist/store/connectors/event-log.js +25 -0
- package/dist/store/connectors/github.d.ts +6 -3
- package/dist/store/connectors/github.js +30 -48
- package/dist/store/connectors/slack.d.ts +2 -1
- package/dist/store/connectors/slack.js +31 -47
- package/dist/store/dashboard-reads.d.ts +7 -3
- package/dist/store/dashboard-reads.js +32 -10
- package/dist/store/delete-and-batch.d.ts +17 -11
- package/dist/store/delete-and-batch.js +70 -28
- package/dist/store/delivery-recorder.d.ts +10 -7
- package/dist/store/delivery-recorder.js +70 -37
- package/dist/store/descendant-page.d.ts +2 -1
- package/dist/store/descendant-page.js +26 -10
- package/dist/store/diagnostics.d.ts +2 -1
- package/dist/store/diagnostics.js +2 -1
- package/dist/store/doctor-reads.d.ts +2 -1
- package/dist/store/doctor-reads.js +13 -5
- package/dist/store/dormant.d.ts +19 -11
- package/dist/store/dormant.js +45 -19
- package/dist/store/embeddings/index.d.ts +13 -9
- package/dist/store/embeddings/index.js +19 -12
- package/dist/store/entry-reads.d.ts +72 -21
- package/dist/store/entry-reads.js +215 -69
- package/dist/store/entry-row.d.ts +10 -6
- package/dist/store/entry-row.js +26 -14
- package/dist/store/entry-writes.d.ts +28 -13
- package/dist/store/entry-writes.js +61 -22
- package/dist/store/failure-log-at.js +1 -1
- package/dist/store/failure-log.d.ts +4 -2
- package/dist/store/failure-log.js +13 -6
- package/dist/store/gated-write.d.ts +3 -3
- package/dist/store/gated-write.js +3 -3
- package/dist/store/goals.d.ts +5 -4
- package/dist/store/goals.js +11 -12
- package/dist/store/graph-apply.d.ts +21 -0
- package/dist/{graph/write.js → store/graph-apply.js} +31 -11
- package/dist/store/graph-queue.d.ts +9 -6
- package/dist/store/graph-queue.js +15 -10
- package/dist/store/graph-reads.d.ts +16 -11
- package/dist/store/graph-reads.js +29 -19
- package/dist/store/graph-rows.d.ts +41 -3
- package/dist/store/graph-rows.js +10 -7
- package/dist/store/graph-view-rows.js +15 -7
- package/dist/store/graph-writes.d.ts +16 -10
- package/dist/store/graph-writes.js +59 -36
- package/dist/store/half-life.js +2 -2
- package/dist/store/handoffs.d.ts +13 -7
- package/dist/store/handoffs.js +44 -22
- package/dist/store/index-and-stats.d.ts +2 -2
- package/dist/store/index-and-stats.js +6 -5
- package/dist/store/index.d.ts +4 -2
- package/dist/store/index.js +2 -1
- package/dist/store/key-audit.d.ts +2 -1
- package/dist/store/key-audit.js +2 -1
- package/dist/store/key-writes.d.ts +2 -1
- package/dist/store/key-writes.js +9 -2
- package/dist/store/ledger-turn.d.ts +4 -1
- package/dist/store/ledger-turn.js +7 -2
- package/dist/store/mirrors.d.ts +11 -4
- package/dist/store/mirrors.js +96 -19
- package/dist/store/narrow.d.ts +6 -0
- package/dist/store/narrow.js +11 -0
- package/dist/store/open.d.ts +6 -3
- package/dist/store/open.js +20 -10
- package/dist/store/pilot-arm.d.ts +2 -1
- package/dist/store/pilot-arm.js +18 -6
- package/dist/store/planning-fallacy-evidence.d.ts +2 -2
- package/dist/store/planning-fallacy-evidence.js +8 -5
- package/dist/store/port/agent-import.d.ts +62 -0
- package/dist/store/port/agent-import.js +2 -0
- package/dist/store/port/consolidation.d.ts +129 -0
- package/dist/store/port/consolidation.js +2 -0
- package/dist/store/port/learning.d.ts +19 -0
- package/dist/store/port/learning.js +2 -0
- package/dist/store/port/local-files.d.ts +18 -0
- package/dist/store/port/local-files.js +2 -0
- package/dist/store/port/promotion.d.ts +20 -0
- package/dist/store/port/promotion.js +3 -0
- package/dist/store/port-groups.d.ts +160 -0
- package/dist/store/port-groups.js +2 -0
- package/dist/store/port.d.ts +261 -219
- package/dist/store/port.js +3 -9
- package/dist/store/predictions.d.ts +14 -10
- package/dist/store/predictions.js +37 -17
- package/dist/store/project-tags.d.ts +4 -1
- package/dist/store/project-tags.js +16 -5
- package/dist/store/quality-repair.d.ts +8 -4
- package/dist/store/quality-repair.js +53 -20
- package/dist/store/quarantine.d.ts +1 -0
- package/dist/store/quarantine.js +23 -9
- package/dist/store/raw-archive.d.ts +5 -4
- package/dist/store/raw-archive.js +11 -10
- package/dist/store/recall-trace.d.ts +22 -17
- package/dist/store/recall-trace.js +128 -64
- package/dist/store/rejected-values.d.ts +15 -10
- package/dist/store/rejected-values.js +46 -20
- package/dist/store/rejection.d.ts +12 -11
- package/dist/store/rejection.js +18 -19
- package/dist/store/report-reads.d.ts +2 -1
- package/dist/store/report-reads.js +2 -1
- package/dist/store/rows.d.ts +7 -5
- package/dist/store/rows.js +20 -13
- package/dist/store/rule-sql.d.ts +7 -3
- package/dist/store/rule-sql.js +26 -13
- package/dist/store/search-rows.d.ts +16 -11
- package/dist/store/search-rows.js +54 -32
- package/dist/store/sessions.d.ts +12 -10
- package/dist/store/sessions.js +40 -21
- package/dist/store/set-aside.d.ts +2 -2
- package/dist/store/set-aside.js +18 -5
- package/dist/store/sqlite/agent-import.d.ts +3 -0
- package/dist/store/sqlite/agent-import.js +77 -0
- package/dist/store/sqlite/cards-group.d.ts +6 -0
- package/dist/store/sqlite/cards-group.js +37 -0
- package/dist/store/sqlite/conflicts-group.d.ts +6 -0
- package/dist/store/sqlite/conflicts-group.js +18 -0
- package/dist/store/sqlite/connector-events-group.d.ts +2 -1
- package/dist/store/sqlite/connector-events-group.js +17 -6
- package/dist/store/sqlite/connector-writes-group.d.ts +2 -1
- package/dist/store/sqlite/connector-writes-group.js +12 -5
- package/dist/store/sqlite/consolidation-group.d.ts +4 -0
- package/dist/store/sqlite/consolidation-group.js +64 -0
- package/dist/store/sqlite/dag-reads-group.js +1 -1
- package/dist/store/sqlite/dormant-group.d.ts +6 -0
- package/dist/store/sqlite/dormant-group.js +29 -0
- package/dist/store/sqlite/entry-writes-group.d.ts +9 -6
- package/dist/store/sqlite/entry-writes-group.js +37 -14
- package/dist/store/sqlite/error-codec.d.ts +4 -2
- package/dist/store/sqlite/error-codec.js +32 -10
- package/dist/store/sqlite/executor-counts.js +2 -1
- package/dist/store/sqlite/executor.d.ts +8 -3
- package/dist/store/sqlite/executor.js +56 -18
- package/dist/store/sqlite/global-promote.d.ts +5 -0
- package/dist/store/sqlite/global-promote.js +48 -0
- package/dist/store/sqlite/goals-group.d.ts +6 -0
- package/dist/store/sqlite/goals-group.js +23 -0
- package/dist/store/sqlite/graph-reads-group.d.ts +2 -1
- package/dist/store/sqlite/graph-reads-group.js +2 -1
- package/dist/store/sqlite/held-connection.d.ts +8 -0
- package/dist/store/sqlite/held-connection.js +34 -7
- package/dist/store/sqlite/last-recall-group.d.ts +15 -0
- package/dist/store/sqlite/last-recall-group.js +62 -0
- package/dist/store/sqlite/learning-group.d.ts +4 -0
- package/dist/store/sqlite/learning-group.js +17 -0
- package/dist/store/sqlite/maintenance-groups.d.ts +6 -0
- package/dist/store/sqlite/maintenance-groups.js +61 -0
- package/dist/store/sqlite/object-rows.d.ts +6 -3
- package/dist/store/sqlite/object-rows.js +34 -5
- package/dist/store/sqlite/objects-group.d.ts +5 -4
- package/dist/store/sqlite/objects-group.js +97 -38
- package/dist/store/sqlite/predictions-group.d.ts +2 -1
- package/dist/store/sqlite/predictions-group.js +4 -2
- package/dist/store/sqlite/promotion-group.d.ts +3 -0
- package/dist/store/sqlite/promotion-group.js +10 -0
- package/dist/store/sqlite/quarantine-group.d.ts +2 -1
- package/dist/store/sqlite/quarantine-group.js +4 -2
- package/dist/store/sqlite/reports-group.d.ts +6 -0
- package/dist/store/sqlite/reports-group.js +33 -0
- package/dist/store/sqlite/request-scope.d.ts +6 -0
- package/dist/store/sqlite/request-scope.js +18 -0
- package/dist/store/sqlite/sessions-group.d.ts +6 -0
- package/dist/store/sqlite/sessions-group.js +46 -0
- package/dist/store/sqlite/store.d.ts +22 -18
- package/dist/store/sqlite/store.js +95 -33
- package/dist/store/sqlite/vector-pack.js +2 -1
- package/dist/store/sqlite/vector-reads-group.js +2 -1
- package/dist/store/sqlite/worker-jobs.d.ts +2 -1
- package/dist/store/sqlite/worker-jobs.js +19 -7
- package/dist/store/sqlite/worker-ops.d.ts +10 -5
- package/dist/store/sqlite/worker-ops.js +6 -3
- package/dist/store/sqlite/worker-store.d.ts +4 -3
- package/dist/store/sqlite/worker-store.js +24 -14
- package/dist/store/summaries.d.ts +25 -11
- package/dist/store/summaries.js +84 -27
- package/dist/store/summary-dirty.d.ts +2 -1
- package/dist/store/summary-dirty.js +2 -1
- package/dist/store/tenant.d.ts +3 -2
- package/dist/store/tenant.js +5 -4
- package/dist/store/token-ledger-rows.js +8 -4
- package/dist/store/token-ledger.d.ts +19 -13
- package/dist/store/token-ledger.js +27 -14
- package/dist/store/tombstone-checks.d.ts +4 -1
- package/dist/store/tombstone-checks.js +10 -1
- package/dist/store/usage-reports.js +2 -1
- package/dist/store/vector-index.d.ts +8 -5
- package/dist/store/vector-index.js +28 -11
- package/dist/store/working-memory.d.ts +6 -4
- package/dist/store/working-memory.js +14 -9
- package/dist/support-bundle.js +10 -5
- package/dist/trust/quarantine.d.ts +1 -2
- package/dist/trust/quarantine.js +1 -5
- package/dist/trust/reject-flow.d.ts +12 -3
- package/dist/trust/reject-flow.js +12 -4
- package/dist/util/anthropic-messages.d.ts +7 -2
- package/dist/util/anthropic-messages.js +18 -7
- package/dist/util/atomic-write.d.ts +8 -3
- package/dist/util/atomic-write.js +36 -21
- package/dist/util/compaction-items.d.ts +4 -1
- package/dist/util/compaction-items.js +8 -2
- package/dist/util/crash-handlers.d.ts +7 -2
- package/dist/util/crash-handlers.js +13 -4
- package/dist/util/env.d.ts +26 -5
- package/dist/util/env.js +87 -25
- package/dist/util/format.d.ts +2 -0
- package/dist/util/format.js +4 -0
- package/dist/util/home-path.js +12 -6
- package/dist/util/hook-payload.d.ts +3 -1
- package/dist/util/hook-payload.js +3 -1
- package/dist/util/http-retry.d.ts +12 -6
- package/dist/util/http-retry.js +16 -6
- package/dist/util/http-util.d.ts +20 -5
- package/dist/util/http-util.js +28 -9
- package/dist/util/json.d.ts +4 -1
- package/dist/util/json.js +4 -1
- package/dist/util/keyset.js +2 -1
- package/dist/util/limits.js +4 -2
- package/dist/util/log.d.ts +13 -5
- package/dist/util/log.js +29 -6
- package/dist/util/net.d.ts +5 -0
- package/dist/util/net.js +19 -0
- package/dist/util/real-path.d.ts +2 -1
- package/dist/util/real-path.js +4 -3
- package/dist/util/request-scope.d.ts +16 -4
- package/dist/util/request-scope.js +19 -6
- package/dist/util/same-text.d.ts +10 -3
- package/dist/util/same-text.js +10 -3
- package/dist/util/secret-detect.d.ts +24 -7
- package/dist/util/secret-detect.js +49 -14
- package/dist/util/spawn-argv.d.ts +11 -0
- package/dist/util/spawn-argv.js +66 -0
- package/dist/util/sql.d.ts +3 -0
- package/dist/util/sql.js +6 -0
- package/dist/util/sqlite-blocked.d.ts +15 -4
- package/dist/util/sqlite-blocked.js +19 -6
- package/dist/util/stored-json.d.ts +4 -1
- package/dist/util/stored-json.js +6 -2
- package/dist/util/stream-tee.d.ts +2 -1
- package/dist/util/stream-tee.js +8 -5
- package/dist/util/transcript-tail.d.ts +4 -1
- package/dist/util/transcript-tail.js +4 -1
- package/dist/util/vector-codec.d.ts +4 -0
- package/dist/util/vector-codec.js +15 -0
- package/dist/util/version.d.ts +8 -3
- package/dist/util/version.js +8 -3
- package/dist/util/write-budget.d.ts +7 -2
- package/dist/util/write-budget.js +5 -2
- package/dist/util/yaml.d.ts +4 -1
- package/dist/util/yaml.js +4 -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 +4 -1
- package/scripts/postinstall.cjs +3 -1
- package/dist/api/audit.js +0 -56
- package/dist/api/cards.d.ts +0 -42
- package/dist/api/conflicts.d.ts +0 -28
- package/dist/api/conflicts.js +0 -61
- package/dist/api/dormant.d.ts +0 -14
- package/dist/api/dormant.js +0 -58
- package/dist/api/goals.d.ts +0 -18
- package/dist/api/graph.d.ts +0 -8
- package/dist/api/graph.js +0 -7
- package/dist/api/learn.js +0 -124
- package/dist/api/memories.d.ts +0 -23
- package/dist/api/memories.js +0 -46
- package/dist/api/objects.d.ts +0 -9
- package/dist/api/on-store.d.ts +0 -16
- package/dist/api/on-store.js +0 -38
- package/dist/api/outcome.d.ts +0 -19
- package/dist/api/outcome.js +0 -21
- package/dist/api/predictions.d.ts +0 -11
- package/dist/api/promote.d.ts +0 -36
- package/dist/api/promote.js +0 -65
- package/dist/api/recall-core.d.ts +0 -4
- package/dist/api/recall-core.js +0 -120
- package/dist/api/recall-finish.d.ts +0 -53
- package/dist/api/recall-finish.js +0 -30
- package/dist/api/recall-history.d.ts +0 -64
- package/dist/api/recall-history.js +0 -159
- package/dist/api/recall-record.d.ts +0 -43
- package/dist/api/recall-record.js +0 -78
- package/dist/api/recall-request.js +0 -121
- package/dist/api/recall.d.ts +0 -6
- package/dist/api/refine.d.ts +0 -7
- package/dist/api/refine.js +0 -10
- package/dist/api/session-owners.d.ts +0 -4
- package/dist/api/session-owners.js +0 -17
- package/dist/api/sleep-run.d.ts +0 -26
- package/dist/api/sleep.js +0 -10
- package/dist/cli/lenient-id.d.ts +0 -2
- package/dist/cli/lenient-id.js +0 -13
- package/dist/graph/write.d.ts +0 -14
- package/dist/store/sqlite/busy.d.ts +0 -3
- package/dist/store/sqlite/busy.js +0 -8
- package/dist/store/sqlite/local.d.ts +0 -21
- package/dist/store/sqlite/local.js +0 -39
package/dist/server/auth.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Bearer and loopback auth for the HTTP server.
|
|
2
|
-
import { envAllowKeylessLocal, envRequireAuth } from '../util/env.js';
|
|
2
|
+
import { envAllowKeylessLocal, envKeylessLocalRole, envRequireAuth } from '../util/env.js';
|
|
3
|
+
import { loadConfig } from '../core/config.js';
|
|
3
4
|
import { resolveTenantId } from '../store/tenant.js';
|
|
5
|
+
import { sqliteReach } from '../store/sqlite/store.js';
|
|
4
6
|
import { errorFields, errorMessage, log } from '../util/log.js';
|
|
5
7
|
import { API_KEY_PREFIX, verifyApiKeyCached } from '../store/auth.js';
|
|
6
8
|
import { ownerOrSubject } from '../api/index.js';
|
|
@@ -9,38 +11,40 @@ import { MAX_ID_LEN } from '../util/limits.js';
|
|
|
9
11
|
import { clientLimitKey } from './client-ip.js';
|
|
10
12
|
import { keyCheckBounds } from './key-check-bounds.js';
|
|
11
13
|
import { isJsonString } from '../util/json.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (remoteAddress === '::1')
|
|
19
|
-
return true;
|
|
20
|
-
if (remoteAddress === '::ffff:127.0.0.1')
|
|
21
|
-
return true;
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
// A proxy on this host (nginx, Caddy, cloudflared) connects from loopback, so these headers mean the caller is not local.
|
|
14
|
+
import { MINUTE_MS } from '../util/time.js';
|
|
15
|
+
import { isLoopbackAddress } from '../util/net.js';
|
|
16
|
+
/** Kept under its old name because src/server.ts publishes it. */
|
|
17
|
+
export const isLoopback = isLoopbackAddress;
|
|
18
|
+
// A proxy on this host (nginx, Caddy, cloudflared) connects
|
|
19
|
+
// from loopback, so these headers mean the caller is not local.
|
|
25
20
|
const PROXY_HEADERS = [
|
|
26
|
-
'forwarded',
|
|
21
|
+
'forwarded',
|
|
22
|
+
'x-forwarded-for',
|
|
23
|
+
'x-forwarded-host',
|
|
24
|
+
'x-forwarded-proto',
|
|
25
|
+
'x-real-ip',
|
|
26
|
+
'cf-connecting-ip',
|
|
27
|
+
'true-client-ip',
|
|
27
28
|
'fly-client-ip',
|
|
28
29
|
];
|
|
29
30
|
function proxyHeaderOf(req) {
|
|
30
31
|
return PROXY_HEADERS.find((name) => req.headers[name] !== undefined);
|
|
31
32
|
}
|
|
32
|
-
/** A page in a browser on this machine: another site's request,
|
|
33
|
+
/** A page in a browser on this machine: another site's request,
|
|
34
|
+
* or a hostile name resolved to loopback (DNS rebinding). */
|
|
33
35
|
function isForeignPage(req) {
|
|
34
36
|
const host = req.headers.host;
|
|
35
37
|
return (host !== undefined && !LOOPBACK_HOST_HEADER.test(host)) || isCrossSite(req);
|
|
36
38
|
}
|
|
37
|
-
/** True only for a request made on this machine by its own user: a proxy and a browser page are loopback too, so the
|
|
39
|
+
/** True only for a request made on this machine by its own user: a proxy and a browser page are loopback too, so the
|
|
40
|
+
* socket alone proves nothing. */
|
|
38
41
|
export function isLocalCaller(req) {
|
|
39
|
-
return
|
|
42
|
+
return isLoopbackAddress(req.socket.remoteAddress) && proxyHeaderOf(req) === undefined && !isForeignPage(req);
|
|
40
43
|
}
|
|
41
|
-
// The throwing twin of isLocalCaller, for the no-key fallback:
|
|
44
|
+
// The throwing twin of isLocalCaller, for the no-key fallback:
|
|
45
|
+
// each refusal has its own status, and a proxied one is logged.
|
|
42
46
|
function assertLocalCaller(req) {
|
|
43
|
-
if (!
|
|
47
|
+
if (!isLoopbackAddress(req.socket.remoteAddress))
|
|
44
48
|
throw new HttpError(401, 'auth required');
|
|
45
49
|
const proxyHeader = proxyHeaderOf(req);
|
|
46
50
|
if (proxyHeader !== undefined) {
|
|
@@ -52,10 +56,11 @@ function assertLocalCaller(req) {
|
|
|
52
56
|
throw new HttpError(403, 'cross-site or non-local request refused; send an API key');
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
|
-
/** The 401 a keyless request from this machine gets by default; it names both fixes, since an upgrade is where most
|
|
59
|
+
/** The 401 a keyless request from this machine gets by default; it names both fixes, since an upgrade is where most
|
|
60
|
+
* people meet it. */
|
|
56
61
|
const KEY_REQUIRED_MESSAGE = 'auth required: this server takes no request without an API key. Mint one with `hippo auth create` and send it as ' +
|
|
57
|
-
'"Authorization: Bearer <key>" (the hippo CLI reads HIPPO_API_KEY), or start the server with
|
|
58
|
-
'to let requests from this machine in without a key.';
|
|
62
|
+
'"Authorization: Bearer <key>" (the hippo CLI reads HIPPO_API_KEY), or start the server with ' +
|
|
63
|
+
'HIPPO_ALLOW_KEYLESS_LOCAL=1 to let requests from this machine in without a key.';
|
|
59
64
|
export function readAuthHeader(req) {
|
|
60
65
|
const raw = req.headers['authorization'];
|
|
61
66
|
if (raw === undefined)
|
|
@@ -149,7 +154,8 @@ async function askResolver(resolver, token, deadlineMs) {
|
|
|
149
154
|
return clean;
|
|
150
155
|
}
|
|
151
156
|
const DEFAULT_RESOLVER_DEADLINE_MS = 5000;
|
|
152
|
-
/** Runs only before scrypt, so junk, unknown, revoked and expired
|
|
157
|
+
/** Runs only before scrypt, so junk, unknown, revoked and expired
|
|
158
|
+
* tokens and a proven key's re-check never spend a colleague's budget. */
|
|
153
159
|
function chargeScryptRun(req, opts) {
|
|
154
160
|
const limiter = opts.failedAuthLimiter;
|
|
155
161
|
// Reserving rather than peeking bounds scrypt runs exactly, even when concurrent misses await a slow store.
|
|
@@ -164,17 +170,24 @@ async function resolveBearer(req, token, opts) {
|
|
|
164
170
|
const t = opts.authResolverTimeoutMs;
|
|
165
171
|
const deadlineMs = t !== undefined && Number.isFinite(t) && t > 0 ? t : DEFAULT_RESOLVER_DEADLINE_MS;
|
|
166
172
|
const clean = await askResolver(opts.authResolver, token, deadlineMs);
|
|
167
|
-
|
|
173
|
+
// A resolver vouches for a person, never names one.
|
|
174
|
+
return { ...clean, viaAuthResolver: true, owner: clean.subject };
|
|
168
175
|
}
|
|
169
176
|
const key = await verifyApiKeyCached(token, opts.store, (keyId, derive) => {
|
|
170
|
-
// The key's own bucket first, so a flood on one key id ends at its five tries and leaves the address's budget to
|
|
177
|
+
// The key's own bucket first, so a flood on one key id ends at its five tries and leaves the address's budget to
|
|
178
|
+
// the callers who share it.
|
|
171
179
|
keyChecks.admit(keyId, clientLimitKey(req));
|
|
172
180
|
chargeScryptRun(req, opts);
|
|
173
181
|
return keyChecks.run(derive);
|
|
174
182
|
});
|
|
175
183
|
if (!key)
|
|
176
184
|
throw new HttpError(401, 'invalid api key');
|
|
177
|
-
const id = {
|
|
185
|
+
const id = {
|
|
186
|
+
tenantId: key.tenantId,
|
|
187
|
+
subject: `api_key:${key.keyId}`,
|
|
188
|
+
role: key.role,
|
|
189
|
+
scopes: key.scopes,
|
|
190
|
+
};
|
|
178
191
|
if (key.ownerSubject)
|
|
179
192
|
id.owner = key.ownerSubject;
|
|
180
193
|
return id;
|
|
@@ -213,7 +226,7 @@ function bearerActor(id) {
|
|
|
213
226
|
export const LIMITER_MAX_KEYS = 10_000;
|
|
214
227
|
// One for the process, as the thread pool its derivations run on is.
|
|
215
228
|
const keyChecks = keyCheckBounds(LIMITER_MAX_KEYS);
|
|
216
|
-
const CALLER_WARN_EVERY_MS =
|
|
229
|
+
const CALLER_WARN_EVERY_MS = MINUTE_MS;
|
|
217
230
|
const callerWarnedAt = new Map();
|
|
218
231
|
function warnCallerLimited(key, tenantId, person) {
|
|
219
232
|
const now = Date.now();
|
|
@@ -240,8 +253,8 @@ function chargeCaller(tenantId, actor, opts) {
|
|
|
240
253
|
warnCallerLimited(key, tenantId, person);
|
|
241
254
|
throw new HttpError(429, 'rate limit exceeded for this caller', limiter.retryAfterSec);
|
|
242
255
|
}
|
|
243
|
-
/** Builds a per-request Context from the Authorization header and remote address; throws HttpError(401)
|
|
244
|
-
* Reads the store only for an API-key-shaped Bearer (or any Bearer
|
|
256
|
+
/** Builds a per-request Context from the Authorization header and remote address; throws HttpError(401) on bad ones.
|
|
257
|
+
* Reads the store only for an API-key-shaped Bearer (or any Bearer with no resolver), so keyless calls stay cheap. */
|
|
245
258
|
export async function buildContextWithAuth(req, opts) {
|
|
246
259
|
const id = await checkAuth(req, opts);
|
|
247
260
|
const ctx = contextFor(id, opts);
|
|
@@ -249,29 +262,46 @@ export async function buildContextWithAuth(req, opts) {
|
|
|
249
262
|
chargeCaller(id.tenantId, ctx.actor, opts);
|
|
250
263
|
return ctx;
|
|
251
264
|
}
|
|
252
|
-
/** The auth check again, uncharged, for a handler that authenticated with requireAuth before a slow body read and
|
|
265
|
+
/** The auth check again, uncharged, for a handler that authenticated with requireAuth before a slow body read and
|
|
266
|
+
* must re-check right before it acts. */
|
|
253
267
|
export async function recheckContextWithAuth(req, opts) {
|
|
254
268
|
return contextFor(await checkAuth(req, opts), opts);
|
|
255
269
|
}
|
|
270
|
+
/** The keyless local caller: any process on this machine can reach
|
|
271
|
+
* loopback, so it is a member unless the operator names admin. */
|
|
272
|
+
function keylessLocalActor(opts) {
|
|
273
|
+
const role = opts.keylessLocalRole ?? envKeylessLocalRole();
|
|
274
|
+
return role === 'admin'
|
|
275
|
+
? { subject: 'localhost:cli', role: 'admin', hostAdmin: true }
|
|
276
|
+
: { subject: 'localhost:cli', role: 'member' };
|
|
277
|
+
}
|
|
256
278
|
function contextFor(id, opts) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
//
|
|
279
|
+
// Per request, never cached at serve: the global store can be created while the server runs.
|
|
280
|
+
const reach = sqliteReach(opts.hippoRoot, opts.store);
|
|
281
|
+
// loadConfig caches by file mtime, so each request still sees an edit made while the server runs.
|
|
282
|
+
const config = loadConfig(opts.hippoRoot);
|
|
283
|
+
if (id !== null) {
|
|
284
|
+
const actor = bearerActor(id);
|
|
285
|
+
return { hippoRoot: opts.hippoRoot, tenantId: id.tenantId, actor, store: opts.store, reach, config };
|
|
286
|
+
}
|
|
260
287
|
return {
|
|
261
288
|
hippoRoot: opts.hippoRoot,
|
|
262
289
|
tenantId: resolveTenantId({}),
|
|
263
|
-
actor:
|
|
290
|
+
actor: keylessLocalActor(opts),
|
|
264
291
|
store: opts.store,
|
|
292
|
+
reach,
|
|
293
|
+
config,
|
|
265
294
|
};
|
|
266
295
|
}
|
|
267
|
-
/** Auth check for routes that need no tenant Context (e.g. the MCP transport, which resolves its own root): throws
|
|
268
|
-
* A keyless local request passes only under HIPPO_ALLOW_KEYLESS_LOCAL=1. */
|
|
296
|
+
/** Auth check for routes that need no tenant Context (e.g. the MCP transport, which resolves its own root): throws
|
|
297
|
+
* HttpError 401 like buildContextWithAuth. A keyless local request passes only under HIPPO_ALLOW_KEYLESS_LOCAL=1. */
|
|
269
298
|
export async function requireAuth(req, opts) {
|
|
270
299
|
const id = await checkAuth(req, opts);
|
|
271
300
|
if (id !== null)
|
|
272
301
|
chargeCaller(id.tenantId, bearerActor(id), opts);
|
|
273
302
|
}
|
|
274
|
-
/** Never rejects or charges a caller bucket: an outage (5xx) or a throttle (429) skips one tick; only a definite 4xx
|
|
303
|
+
/** Never rejects or charges a caller bucket: an outage (5xx) or a throttle (429) skips one tick; only a definite 4xx
|
|
304
|
+
* denial closes the stream. */
|
|
275
305
|
export async function heartbeatVerdict(req, opts) {
|
|
276
306
|
try {
|
|
277
307
|
await checkAuth(req, opts);
|
package/dist/server/boot.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ServeOpts, ServerHandle } from './types.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses a non-loopback host unless
|
|
4
|
+
* HIPPO_REQUIRE_AUTH=1 and
|
|
5
|
+
* either `tls` or allowCleartext is given, and refuses HIPPO_CLIENT_IP_HEADER without HIPPO_TRUSTED_PROXIES.
|
|
3
6
|
* Use port: 0 in tests for an ephemeral port. See docs/ARCHITECTURE.md#srcserverbootts. */
|
|
4
7
|
export declare function serve(opts: ServeOpts): Promise<ServerHandle>;
|
|
5
8
|
//# sourceMappingURL=boot.d.ts.map
|
package/dist/server/boot.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { envPort, envRequireAuth, envV1Rps } from '../util/env.js';
|
|
1
|
+
import { envAllowCleartext, envCallerRps, envPort, envRequireAuth, envV1Rps } from '../util/env.js';
|
|
2
2
|
import { detectServer, removePidfileIfOwned, writePidfile } from './server-detect.js';
|
|
3
|
-
import {
|
|
4
|
-
import { isStoreBusy } from '../
|
|
5
|
-
import {
|
|
3
|
+
import { hasGroup } from '../store/index.js';
|
|
4
|
+
import { isStoreBusy } from '../api/busy.js';
|
|
5
|
+
import { createStoreHolder, offLoopFor, outsideRouteBlock, } from '../store/sqlite/held-connection.js';
|
|
6
6
|
import { workerSqliteStore } from '../store/sqlite/worker-store.js';
|
|
7
7
|
import { markSharedStore } from '../core/config.js';
|
|
8
8
|
import { auditWriteFailureCount } from '../store/audit.js';
|
|
9
9
|
import { PACKAGE_VERSION } from '../util/version.js';
|
|
10
|
+
import { MINUTE_MS } from '../util/time.js';
|
|
10
11
|
import { errorFields, errorMessage, log } from '../util/log.js';
|
|
11
12
|
import { runWithRequestId } from '../util/request-scope.js';
|
|
12
13
|
import { createRateLimiter } from './rate-limit.js';
|
|
13
14
|
import { RecallContractError } from '../api/index.js';
|
|
14
|
-
import { BodyTimeoutError, BodyTooLargeError, closeAfterReply, DeadlineExceededError, HttpError, JSON_HEADERS, sendJson } from '../util/http-util.js';
|
|
15
|
+
import { BodyTimeoutError, BodyTooLargeError, closeAfterReply, DeadlineExceededError, HttpError, JSON_HEADERS, sendJson, } from '../util/http-util.js';
|
|
15
16
|
import { workerCounts } from '../store/sqlite/executor-counts.js';
|
|
16
17
|
import { isLocalCaller, LIMITER_MAX_KEYS } from './auth.js';
|
|
17
|
-
import {
|
|
18
|
+
import { assertClientIpHeaderPinned, enforceRateLimit } from './client-ip.js';
|
|
18
19
|
import { answerAtDeadline, handlerDeadlineCount, isAbandoned, requestDeadlineFor } from './deadline.js';
|
|
19
20
|
import { DEFAULT_SHUTDOWN_DRAIN_MS, drainAndClose, setKeepAliveTimeouts, shutdownBoundMs } from './lifecycle.js';
|
|
20
21
|
import { readyProbeFor } from './ready.js';
|
|
@@ -22,8 +23,8 @@ import { DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT } from './defaults.js';
|
|
|
22
23
|
import { installCrashHandlers, installSignalHandlers } from '../util/crash-handlers.js';
|
|
23
24
|
import { handleMcpPost, handleMcpStream } from './mcp-http.js';
|
|
24
25
|
import { MCP_PROJECT_SCOPED_HEADER } from '../core/project-identity.js';
|
|
25
|
-
import { accessRouteOf, logRequestFailure, noteAccess, openRequest, parseRequest, rejectEncodedSlash, replyFor, sendError } from './request.js';
|
|
26
|
-
import {
|
|
26
|
+
import { accessRouteOf, logRequestFailure, noteAccess, openRequest, parseRequest, rejectEncodedSlash, replyFor, sendError, } from './request.js';
|
|
27
|
+
import { assertTlsOrCleartextAllowed, createListener } from './tls.js';
|
|
27
28
|
import { assertAddonRoutes, assertPublicJson } from './route-checks.js';
|
|
28
29
|
import { dispatchAddonRoute, dispatchPublicJson, dispatchV1Route } from './route-table.js';
|
|
29
30
|
// server.address() returns AddressInfo once a TCP socket is bound; null before
|
|
@@ -31,7 +32,8 @@ import { dispatchAddonRoute, dispatchPublicJson, dispatchV1Route } from './route
|
|
|
31
32
|
function isAddressInfo(a) {
|
|
32
33
|
return a !== null && typeof a !== 'string';
|
|
33
34
|
}
|
|
34
|
-
// Pinned at module load, bumped with package.json on releases; reading package.json synchronously here would couple the
|
|
35
|
+
// Pinned at module load, bumped with package.json on releases; reading package.json synchronously here would couple the
|
|
36
|
+
// daemon to its install path,
|
|
35
37
|
// which tests that mkdtemp a hippoRoot avoid.
|
|
36
38
|
const VERSION = PACKAGE_VERSION;
|
|
37
39
|
const LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
|
|
@@ -41,7 +43,8 @@ async function handleRequest(req, res, opts, options) {
|
|
|
41
43
|
// Node's URL parser collapses them and they slip past the route table.
|
|
42
44
|
rejectEncodedSlash(req.url ?? '/');
|
|
43
45
|
const { method, path, query } = parseRequest(req);
|
|
44
|
-
// An older core ignores X-Hippo-Project, so every /mcp reply, a 429 or 401 too, tells the client this one filters by
|
|
46
|
+
// An older core ignores X-Hippo-Project, so every /mcp reply, a 429 or 401 too, tells the client this one filters by
|
|
47
|
+
// it.
|
|
45
48
|
if (path === '/mcp')
|
|
46
49
|
res.setHeader(MCP_PROJECT_SCOPED_HEADER, '1');
|
|
47
50
|
if (method === 'GET' && path === '/health') {
|
|
@@ -56,19 +59,22 @@ async function handleRequest(req, res, opts, options) {
|
|
|
56
59
|
}
|
|
57
60
|
enforceRateLimit(req, path, limiter);
|
|
58
61
|
const routeRequest = { req, res, opts, query };
|
|
59
|
-
if (await
|
|
62
|
+
if (await dispatchScopedRoute(routeRequest, method, path))
|
|
60
63
|
return;
|
|
61
|
-
//
|
|
62
|
-
// heartbeat wait
|
|
64
|
+
// The request scope (the server's lock wait) is kept by the heartbeat timer after it closes, so the key check and
|
|
65
|
+
// every heartbeat wait that long. Store-ready: the stream only authenticates, through the port.
|
|
63
66
|
if (method === 'GET' && path === '/mcp/stream') {
|
|
64
67
|
noteAccess(req, { route: path });
|
|
65
|
-
await
|
|
68
|
+
await handleMcpStream(req, res, opts, streamSlots);
|
|
66
69
|
return;
|
|
67
70
|
}
|
|
68
71
|
res.writeHead(404, JSON_HEADERS);
|
|
69
72
|
res.end(JSON.stringify({ error: 'not found' }));
|
|
70
73
|
}
|
|
71
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Every route that runs inside a request scope, so it opens each store once: the /v1 table with the webhooks, public
|
|
76
|
+
* JSON, add-on routes and POST /mcp.
|
|
77
|
+
*/
|
|
72
78
|
async function dispatchScopedRoute(r, method, path) {
|
|
73
79
|
if (await dispatchV1Route(r, method, path))
|
|
74
80
|
return true;
|
|
@@ -86,8 +92,10 @@ async function dispatchScopedRoute(r, method, path) {
|
|
|
86
92
|
return false;
|
|
87
93
|
}
|
|
88
94
|
function sendHealth(req, res, startedAt) {
|
|
89
|
-
// A caller on this machine (detectServer's probe reads version and pid) gets the full body; anyone else, even a
|
|
90
|
-
//
|
|
95
|
+
// A caller on this machine (detectServer's probe reads version and pid) gets the full body; anyone else, even a
|
|
96
|
+
// proxied caller or a browser page on loopback,
|
|
97
|
+
// gets liveness only: the version would fingerprint the build and the pid is noise. Platform health checks only need
|
|
98
|
+
// the 200.
|
|
91
99
|
if (isLocalCaller(req)) {
|
|
92
100
|
sendJson(res, 200, {
|
|
93
101
|
ok: true,
|
|
@@ -127,7 +135,8 @@ function assertBindable(host) {
|
|
|
127
135
|
}
|
|
128
136
|
}
|
|
129
137
|
async function assertNoLiveServer(hippoRoot) {
|
|
130
|
-
// Refuse to start if a live hippo server already serves this hippoRoot (detectServer probes the recorded /health and
|
|
138
|
+
// Refuse to start if a live hippo server already serves this hippoRoot (detectServer probes the recorded /health and
|
|
139
|
+
// unlinks a stale pidfile):
|
|
131
140
|
// a concurrent `hippo serve` would race for the port and clobber the pidfile.
|
|
132
141
|
const existing = await detectServer(hippoRoot);
|
|
133
142
|
if (existing) {
|
|
@@ -135,53 +144,64 @@ async function assertNoLiveServer(hippoRoot) {
|
|
|
135
144
|
`Stop that server before starting another on the same hippoRoot.`);
|
|
136
145
|
}
|
|
137
146
|
}
|
|
138
|
-
// SHORTCUT: buckets live in this process and reset on restart or LRU eviction; move them to the store if serve ever
|
|
147
|
+
// SHORTCUT: buckets live in this process and reset on restart or LRU eviction; move them to the store if serve ever
|
|
148
|
+
// runs as several processes.
|
|
139
149
|
function limiterFor({ ratePerSec, burst }) {
|
|
140
|
-
return createRateLimiter({ ratePerSec, burst, idleEvictMs:
|
|
150
|
+
return createRateLimiter({ ratePerSec, burst, idleEvictMs: MINUTE_MS, maxKeys: LIMITER_MAX_KEYS });
|
|
141
151
|
}
|
|
142
152
|
function bootRateLimiter(perAddress) {
|
|
143
153
|
if (perAddress === 'off')
|
|
144
154
|
return undefined;
|
|
145
155
|
if (perAddress !== undefined)
|
|
146
156
|
return limiterFor(perAddress);
|
|
147
|
-
// Per-IP rate limiter for /v1/* and /mcp*, built here (not at module scope) so HIPPO_V1_RPS is read at boot and a
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
157
|
+
// Per-IP rate limiter for /v1/* and /mcp*, built here (not at module scope) so HIPPO_V1_RPS is read at boot and a
|
|
158
|
+
// test can set it before serve().
|
|
159
|
+
// A typo must not switch the limit off, so only an explicit 0 does.
|
|
160
|
+
const raw = envV1Rps();
|
|
161
|
+
const v1Rps = raw === undefined ? 20 : Number(raw);
|
|
162
|
+
if (!Number.isFinite(v1Rps) || v1Rps < 0) {
|
|
163
|
+
throw new Error(`HIPPO_V1_RPS must be a number of at least 0 (0 turns the per-address limit off), not '${raw}'`);
|
|
164
|
+
}
|
|
165
|
+
return v1Rps > 0 ? limiterFor({ ratePerSec: v1Rps, burst: v1Rps * 2 }) : undefined;
|
|
151
166
|
}
|
|
152
167
|
const DEFAULT_FAILED_AUTH = { ratePerSec: 20, burst: 40 };
|
|
153
168
|
function assertRateLimitSpec(name, { ratePerSec, burst }) {
|
|
154
|
-
if (!Number.isFinite(ratePerSec) || ratePerSec <= 0)
|
|
169
|
+
if (!Number.isFinite(ratePerSec) || ratePerSec <= 0) {
|
|
155
170
|
throw new Error(`rateLimits.${name}.ratePerSec must be a finite number above 0`);
|
|
156
|
-
|
|
171
|
+
}
|
|
172
|
+
if (!Number.isFinite(burst) || burst < 1) {
|
|
157
173
|
throw new Error(`rateLimits.${name}.burst must be a finite number of at least 1`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const DEFAULT_CALLER_RPS = 20;
|
|
177
|
+
/**
|
|
178
|
+
* The per-caller spec when serve() names none: HIPPO_CALLER_RPS (0 is off), else 20 per second with a burst of twice
|
|
179
|
+
* that.
|
|
180
|
+
*/
|
|
181
|
+
function defaultCallerSpec() {
|
|
182
|
+
const raw = envCallerRps();
|
|
183
|
+
const rps = raw === undefined ? DEFAULT_CALLER_RPS : Number(raw);
|
|
184
|
+
// A typo must not switch the limit off, so only an explicit 0 does.
|
|
185
|
+
if (!Number.isFinite(rps) || rps < 0) {
|
|
186
|
+
throw new Error(`HIPPO_CALLER_RPS must be a number of at least 0 (0 turns the per-caller limit off), not '${raw}'`);
|
|
187
|
+
}
|
|
188
|
+
return rps === 0 ? 'off' : { ratePerSec: rps, burst: Math.max(1, rps * 2) };
|
|
158
189
|
}
|
|
159
190
|
/** Refuses a bad spec at boot, since a NaN or zero rate would otherwise turn a bucket off or refuse every request. */
|
|
160
191
|
function bootLimiters(rateLimits) {
|
|
161
|
-
const { perCaller, perAddress, failedAuthPerAddress = DEFAULT_FAILED_AUTH } = rateLimits ?? {};
|
|
162
|
-
if (perCaller !==
|
|
192
|
+
const { perCaller = defaultCallerSpec(), perAddress, failedAuthPerAddress = DEFAULT_FAILED_AUTH } = rateLimits ?? {};
|
|
193
|
+
if (perCaller !== 'off')
|
|
163
194
|
assertRateLimitSpec('perCaller', perCaller);
|
|
164
195
|
if (perAddress !== undefined && perAddress !== 'off')
|
|
165
196
|
assertRateLimitSpec('perAddress', perAddress);
|
|
166
197
|
assertRateLimitSpec('failedAuthPerAddress', failedAuthPerAddress);
|
|
167
|
-
|
|
198
|
+
assertClientIpHeaderPinned();
|
|
168
199
|
return {
|
|
169
200
|
perAddress: bootRateLimiter(perAddress),
|
|
170
|
-
callerLimiter: perCaller ===
|
|
201
|
+
callerLimiter: perCaller === 'off' ? undefined : limiterFor(perCaller),
|
|
171
202
|
failedAuthLimiter: limiterFor(failedAuthPerAddress),
|
|
172
203
|
};
|
|
173
204
|
}
|
|
174
|
-
function createStoreHolder(hippoRoot, store) {
|
|
175
|
-
if (store.kind !== 'sqlite') {
|
|
176
|
-
log.info(`serve: the '${store.kind}' store serves ${hippoRoot}, so no hippo.db connection is held`);
|
|
177
|
-
return { hold: () => { }, afterResponse: () => { }, release: async () => { } };
|
|
178
|
-
}
|
|
179
|
-
return holdSqliteConnection(hippoRoot);
|
|
180
|
-
}
|
|
181
|
-
// A plugin's resolver may read hippo.db through this package's synchronous functions, so it runs outside the block of a `loop: 'off'` route.
|
|
182
|
-
function outsideRouteBlock(resolver) {
|
|
183
|
-
return resolver && ((token) => outsideSqliteOffLoop(() => resolver(token)));
|
|
184
|
-
}
|
|
185
205
|
function replyWithFailure(req, res, err, requestId) {
|
|
186
206
|
const mapped = replyFor(err);
|
|
187
207
|
logRequestFailure(req, err, mapped.status);
|
|
@@ -192,10 +212,12 @@ function replyWithFailure(req, res, err, requestId) {
|
|
|
192
212
|
catch { /* socket already gone */ }
|
|
193
213
|
return;
|
|
194
214
|
}
|
|
195
|
-
if (isStoreBusy(err))
|
|
215
|
+
if (isStoreBusy(err)) {
|
|
196
216
|
res.setHeader('Retry-After', '1');
|
|
197
|
-
|
|
217
|
+
}
|
|
218
|
+
else if (err instanceof HttpError && err.retryAfterSec !== undefined) {
|
|
198
219
|
res.setHeader('Retry-After', String(err.retryAfterSec));
|
|
220
|
+
}
|
|
199
221
|
if (mapped.status === 500) {
|
|
200
222
|
// The id lets an operator find the logged cause without the client seeing internal text.
|
|
201
223
|
sendJson(res, 500, { error: mapped.message, requestId });
|
|
@@ -210,29 +232,43 @@ function replyWithFailure(req, res, err, requestId) {
|
|
|
210
232
|
sendJson(res, 504, { error: err.message, code: err.code, requestId });
|
|
211
233
|
return;
|
|
212
234
|
}
|
|
213
|
-
// readBody hit its cap or deadline, so close once the 413 or 408 is out rather than drain what the client keeps
|
|
214
|
-
|
|
235
|
+
// readBody hit its cap or deadline, so close once the 413 or 408 is out rather than drain what the client keeps
|
|
236
|
+
// sending.
|
|
237
|
+
if (err instanceof BodyTooLargeError || err instanceof BodyTimeoutError) {
|
|
215
238
|
res.once('finish', () => closeAfterReply(req));
|
|
239
|
+
}
|
|
216
240
|
sendError(res, mapped.status, mapped.message);
|
|
217
241
|
}
|
|
218
242
|
const HANDLER_LATE = 'the request did not finish by its deadline and was abandoned; a write it started may or may not be saved';
|
|
219
|
-
// The caller already has its 504, so this line is the only trace of the failure. The path and the error text can hold
|
|
243
|
+
// The caller already has its 504, so this line is the only trace of the failure. The path and the error text can hold
|
|
244
|
+
// caller data, so it carries neither.
|
|
220
245
|
function logLateFailure(req, err, requestId) {
|
|
221
|
-
const fields = {
|
|
246
|
+
const fields = {
|
|
247
|
+
requestId,
|
|
248
|
+
method: req.method ?? 'GET',
|
|
249
|
+
route: accessRouteOf(req),
|
|
250
|
+
failureStatus: replyFor(err).status,
|
|
251
|
+
};
|
|
222
252
|
log.warn('request failed after its deadline reply', { ...fields, errorClass: errorFields(err).errorClass });
|
|
223
253
|
}
|
|
224
|
-
// A handler that ends after the 504 finds the response finished, so sending its own reply throws this: its work ran to
|
|
254
|
+
// A handler that ends after the 504 finds the response finished, so sending its own reply throws this: its work ran to
|
|
255
|
+
// the end.
|
|
225
256
|
function isDroppedLateReply(err) {
|
|
226
257
|
return err instanceof Error && 'code' in err && err.code === 'ERR_HTTP_HEADERS_SENT';
|
|
227
258
|
}
|
|
228
259
|
/** A GET only reads; every other method this server routes can write. */
|
|
229
260
|
const isRead = (method) => method === 'GET';
|
|
230
|
-
// A read that ends late changed nothing. A write that ends late ran to its end after its caller was told it may not
|
|
261
|
+
// A read that ends late changed nothing. A write that ends late ran to its end after its caller was told it may not
|
|
262
|
+
// have been saved.
|
|
231
263
|
function logLateFinish(req, requestId) {
|
|
232
264
|
const method = req.method ?? 'GET';
|
|
233
265
|
if (isRead(method))
|
|
234
266
|
return;
|
|
235
|
-
log.info('request finished after its deadline reply; its own reply was dropped', {
|
|
267
|
+
log.info('request finished after its deadline reply; its own reply was dropped', {
|
|
268
|
+
requestId,
|
|
269
|
+
method,
|
|
270
|
+
route: accessRouteOf(req),
|
|
271
|
+
});
|
|
236
272
|
}
|
|
237
273
|
function replyOrClose(req, res, err, requestId) {
|
|
238
274
|
try {
|
|
@@ -244,14 +280,19 @@ function replyOrClose(req, res, err, requestId) {
|
|
|
244
280
|
res.destroy();
|
|
245
281
|
}
|
|
246
282
|
}
|
|
247
|
-
/**
|
|
283
|
+
/**
|
|
284
|
+
* Runs `handle` under the request's id and deadline; a failure becomes the reply, unless the deadline has already
|
|
285
|
+
* answered.
|
|
286
|
+
*/
|
|
248
287
|
function answerRequest(req, res, handle, slowWarnMs) {
|
|
249
288
|
const requestId = openRequest(req, res, slowWarnMs);
|
|
250
289
|
const deadline = requestDeadlineFor(req);
|
|
290
|
+
const abort = deadline ? new AbortController() : undefined;
|
|
251
291
|
// Inside the scope, so the failure reply's log line carries the id too.
|
|
252
292
|
runWithRequestId(requestId, () => {
|
|
253
|
-
if (deadline)
|
|
254
|
-
answerAtDeadline(res, deadline, () => replyOrClose(req, res, new DeadlineExceededError(HANDLER_LATE), requestId));
|
|
293
|
+
if (deadline) {
|
|
294
|
+
answerAtDeadline(res, deadline, () => replyOrClose(req, res, new DeadlineExceededError(HANDLER_LATE), requestId), () => abort?.abort(new DeadlineExceededError(HANDLER_LATE)));
|
|
295
|
+
}
|
|
255
296
|
handle().then(() => {
|
|
256
297
|
if (isAbandoned(res))
|
|
257
298
|
logLateFinish(req, requestId);
|
|
@@ -263,7 +304,7 @@ function answerRequest(req, res, handle, slowWarnMs) {
|
|
|
263
304
|
else
|
|
264
305
|
logLateFailure(req, err, requestId);
|
|
265
306
|
});
|
|
266
|
-
}, deadline);
|
|
307
|
+
}, deadline, abort?.signal);
|
|
267
308
|
}
|
|
268
309
|
function listenOn(server, port, host) {
|
|
269
310
|
return new Promise((resolve, reject) => {
|
|
@@ -287,7 +328,10 @@ function exitOnSignalOrCrash(stop, drainMs) {
|
|
|
287
328
|
installSignalHandlers('serve', shutdown);
|
|
288
329
|
installCrashHandlers('serve', shutdown);
|
|
289
330
|
}
|
|
290
|
-
/**
|
|
331
|
+
/**
|
|
332
|
+
* Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses a non-loopback host unless
|
|
333
|
+
* HIPPO_REQUIRE_AUTH=1 and
|
|
334
|
+
* either `tls` or allowCleartext is given, and refuses HIPPO_CLIENT_IP_HEADER without HIPPO_TRUSTED_PROXIES.
|
|
291
335
|
* Use port: 0 in tests for an ephemeral port. See docs/ARCHITECTURE.md#srcserverbootts. */
|
|
292
336
|
export async function serve(opts) {
|
|
293
337
|
const host = opts.host ?? DEFAULT_SERVER_HOST;
|
|
@@ -296,15 +340,17 @@ export async function serve(opts) {
|
|
|
296
340
|
const publicJsonBodies = assertPublicJson(opts.publicJson ?? {});
|
|
297
341
|
const limiters = bootLimiters(opts.rateLimits);
|
|
298
342
|
assertBindable(host);
|
|
343
|
+
assertTlsOrCleartextAllowed(host, opts.tls, LOOPBACK_HOSTS, opts.allowCleartext ?? envAllowCleartext());
|
|
299
344
|
await assertNoLiveServer(opts.hippoRoot);
|
|
300
|
-
// Single source of truth for the start time: returned by GET /health and written into the pidfile, so detectServer
|
|
345
|
+
// Single source of truth for the start time: returned by GET /health and written into the pidfile, so detectServer
|
|
346
|
+
// can prove a pid-reusing impostor is not
|
|
301
347
|
// this server.
|
|
302
348
|
const startedAt = new Date().toISOString();
|
|
303
349
|
// Open /mcp/stream count per client key, so the cap is per server rather than per process.
|
|
304
350
|
const streamSlots = new Map();
|
|
305
351
|
const served = servedOptsFor(opts, routes, publicJsonBodies, limiters);
|
|
306
352
|
// A store other than hippo.db is a team's central server, so its folder's config.json must not decide shared-ness.
|
|
307
|
-
if (served.store
|
|
353
|
+
if (!hasGroup(served.store, 'localFiles'))
|
|
308
354
|
markSharedStore(opts.hippoRoot);
|
|
309
355
|
const holder = createStoreHolder(opts.hippoRoot, served.store);
|
|
310
356
|
const inflight = new Set();
|
|
@@ -330,27 +376,29 @@ export async function serve(opts) {
|
|
|
330
376
|
}
|
|
331
377
|
function frozenAddonRoutes(addonRoutes) {
|
|
332
378
|
// A frozen copy, so a route the caller adds or renames after boot never skips the check below.
|
|
333
|
-
const routes = Object.freeze((addonRoutes ?? []).map(({ path, handler, storeReady }) => Object.freeze(storeReady === undefined
|
|
334
|
-
? { path, handler }
|
|
335
|
-
: { path, handler, storeReady })));
|
|
379
|
+
const routes = Object.freeze((addonRoutes ?? []).map(({ path, handler, storeReady }) => Object.freeze(storeReady === undefined ? { path, handler } : { path, handler, storeReady })));
|
|
336
380
|
assertAddonRoutes(routes);
|
|
337
381
|
return routes;
|
|
338
382
|
}
|
|
339
383
|
function servedOptsFor(opts, routes, publicJsonBodies, { callerLimiter, failedAuthLimiter }) {
|
|
384
|
+
const store = opts.store ?? workerSqliteStore(opts.hippoRoot);
|
|
340
385
|
return {
|
|
341
|
-
...opts,
|
|
386
|
+
...opts,
|
|
387
|
+
routes,
|
|
388
|
+
publicJsonBodies,
|
|
389
|
+
store,
|
|
390
|
+
offLoop: offLoopFor(store),
|
|
391
|
+
callerLimiter,
|
|
392
|
+
failedAuthLimiter,
|
|
342
393
|
authResolver: outsideRouteBlock(opts.authResolver),
|
|
343
394
|
};
|
|
344
395
|
}
|
|
345
396
|
function acceptingServer(served, holder, inflight, options) {
|
|
346
|
-
const { kind } = served.store;
|
|
347
397
|
return createListener(served.tls, (req, res) => {
|
|
348
398
|
res.once('finish', holder.afterResponse);
|
|
349
399
|
inflight.add(res);
|
|
350
400
|
res.once('close', () => inflight.delete(res));
|
|
351
|
-
|
|
352
|
-
// A missed port under another store would otherwise create and write a hippo.db that store never reads.
|
|
353
|
-
answerRequest(req, res, () => (kind === 'sqlite' ? run() : withSqliteBlocked(kind, run)), served.slowRequestWarnMs);
|
|
401
|
+
answerRequest(req, res, () => holder.runRequest(() => handleRequest(req, res, served, options)), served.slowRequestWarnMs);
|
|
354
402
|
});
|
|
355
403
|
}
|
|
356
404
|
async function listenAndDescribe(server, port, host, tls) {
|
|
@@ -362,11 +410,11 @@ async function listenAndDescribe(server, port, host, tls) {
|
|
|
362
410
|
const addressInfo = address;
|
|
363
411
|
const actualPort = addressInfo.port;
|
|
364
412
|
const url = `${tls ? 'https' : 'http'}://${host.includes(':') ? `[${host}]` : host}:${actualPort}`;
|
|
365
|
-
warnIfCleartext(host, tls, LOOPBACK_HOSTS);
|
|
366
413
|
return { port: actualPort, url };
|
|
367
414
|
}
|
|
368
415
|
async function stopListening(opts, server, inflight, startedAt) {
|
|
369
|
-
// Remove the pidfile only if it still names this server: a newer server may have rewritten it, and an unconditional
|
|
416
|
+
// Remove the pidfile only if it still names this server: a newer server may have rewritten it, and an unconditional
|
|
417
|
+
// unlink would orphan it.
|
|
370
418
|
removePidfileIfOwned(opts.hippoRoot, { pid: process.pid, startedAt });
|
|
371
419
|
await drainAndClose(server, inflight, opts.shutdownDrainMs ?? DEFAULT_SHUTDOWN_DRAIN_MS);
|
|
372
420
|
}
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import type { IncomingMessage } from 'node:http';
|
|
2
2
|
import type { RateLimiter } from './rate-limit.js';
|
|
3
3
|
/**
|
|
4
|
-
* Rate-limit key: the socket's remote address, which behind a TLS proxy collapses into one bucket unauthenticated
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Rate-limit key: the socket's remote address, which behind a TLS proxy collapses into one bucket unauthenticated
|
|
5
|
+
* traffic can drain.
|
|
6
|
+
* HIPPO_CLIENT_IP_HEADER (fly-client-ip on Fly) is read only from a peer in HIPPO_TRUSTED_PROXIES (IPs or CIDRs, or `*`
|
|
7
|
+
* for any peer),
|
|
8
|
+
* so a caller that reaches the port past the proxy cannot pick its own bucket. In a comma-joined chain the key is the
|
|
9
|
+
* rightmost hop no trusted proxy added.
|
|
10
|
+
*/
|
|
7
11
|
export declare function clientIpForRateLimit(req: IncomingMessage): string;
|
|
8
|
-
/**
|
|
9
|
-
|
|
12
|
+
/**
|
|
13
|
+
* serve() refused HIPPO_CLIENT_IP_HEADER with no HIPPO_TRUSTED_PROXIES: the header would be read from no one, so the
|
|
14
|
+
* setting is a mistake.
|
|
15
|
+
*/
|
|
16
|
+
export declare class UntrustedClientIpHeaderError extends Error {
|
|
17
|
+
readonly header: string;
|
|
18
|
+
constructor(header: string);
|
|
19
|
+
}
|
|
20
|
+
/** Checked at boot: a client-IP header needs a trusted-proxy list, and `*` is said once, since it believes any peer. */
|
|
21
|
+
export declare function assertClientIpHeaderPinned(): void;
|
|
10
22
|
/** The one key every per-address limit and slot count uses, so rotating inside a /64 never buys a fresh bucket. */
|
|
11
23
|
export declare function clientLimitKey(req: IncomingMessage): string;
|
|
12
24
|
export declare function enforceRateLimit(req: IncomingMessage, path: string, limiter?: RateLimiter): void;
|