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,8 +1,10 @@
|
|
|
1
|
+
import { handleGitHubEventsWebhook } from '../connectors/github/webhook.js';
|
|
2
|
+
import { handleSlackEventsWebhook } from '../connectors/slack/webhook.js';
|
|
1
3
|
import { withSqliteOffLoop } from '../db/index.js';
|
|
2
|
-
import { hasGroup } from '../store/index.js';
|
|
4
|
+
import { hasGroup, requireGroup } from '../store/index.js';
|
|
3
5
|
import { runsOffLoop } from '../store/sqlite/worker-store.js';
|
|
4
6
|
import { HttpError, JSON_HEADERS, sendJson, STORE_NOT_PORTED_MESSAGE } from '../util/http-util.js';
|
|
5
|
-
import { buildContextWithAuth,
|
|
7
|
+
import { assertCrossTenantAdmin, buildContextWithAuth, isLoopback } from './auth.js';
|
|
6
8
|
import { matchPath, noteAccess } from './request.js';
|
|
7
9
|
import { handleApproveQuarantine, handleCreateAuthKey, handleListAudit, handleListAuthKeys, handleListQuarantine, handleRejectQuarantine, handleRevokeAuthKey } from './routes/admin.js';
|
|
8
10
|
import { handleCloseCustomerNote, handleCreateCustomerNote, handleGetCustomerNote, handleListCustomerNotes, handleSupersedeCustomerNote } from './routes/customer-notes.js';
|
|
@@ -16,102 +18,134 @@ import { handleCloseProjectBrief, handleCreateProjectBrief, handleGetProjectBrie
|
|
|
16
18
|
import { handleAssembleSession, handleDrillRecall, handleGetContext, handleRecallMemories } from './routes/recall.js';
|
|
17
19
|
import { handleCloseSkill, handleCreateSkill, handleExportSkills, handleGetSkill, handleListSkills, handleSupersedeSkill } from './routes/skills.js';
|
|
18
20
|
import { parseJsonBody } from './validation.js';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// a no-op (auth still applies), so the failure mode is fail-closed.
|
|
28
|
-
// The only other unauthenticated paths are ServeOpts.publicJson's: GET only, checked at boot by assertPublicJson.
|
|
29
|
-
const PUBLIC_ROUTES = new Set([
|
|
30
|
-
'POST /v1/connectors/slack/events',
|
|
31
|
-
'POST /v1/connectors/github/events',
|
|
32
|
-
]);
|
|
33
|
-
export function isPublicRoute(method, path) {
|
|
34
|
-
return PUBLIC_ROUTES.has(`${method} ${path}`);
|
|
21
|
+
const WEBHOOK_GROUPS = ['entryWrites', 'connectorWrites', 'connectorEvents'];
|
|
22
|
+
/** A store missing a group a delivery writes through refuses the webhook up front, so no delivery is acknowledged and then half stored. */
|
|
23
|
+
function webhook(handle) {
|
|
24
|
+
return async ({ req, res, opts }) => {
|
|
25
|
+
for (const group of WEBHOOK_GROUPS)
|
|
26
|
+
requireGroup(opts.store, group);
|
|
27
|
+
await handle({ req, res, opts }, opts.store);
|
|
28
|
+
};
|
|
35
29
|
}
|
|
36
|
-
/** The /v1 routes in dispatch order; the first entry whose method and path match handles the request.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
{ method: '
|
|
40
|
-
{ method: 'GET', path: '/v1/
|
|
41
|
-
{ method: 'GET',
|
|
42
|
-
{ method: 'GET', pattern: '/v1/
|
|
43
|
-
{ method: '
|
|
44
|
-
{ method: 'POST', pattern: '/v1/memories/:id/
|
|
45
|
-
{ method: 'POST', pattern: '/v1/memories/:id/
|
|
46
|
-
{ method: '
|
|
47
|
-
|
|
48
|
-
{ method: '
|
|
49
|
-
{ method: 'POST', path: '/v1/
|
|
50
|
-
{ method: '
|
|
51
|
-
{ method: '
|
|
52
|
-
|
|
53
|
-
{ method: '
|
|
54
|
-
{ method: '
|
|
55
|
-
{ method: '
|
|
56
|
-
{ method: 'GET', path: '/v1/
|
|
57
|
-
{ method: 'POST',
|
|
58
|
-
{ method: '
|
|
59
|
-
{ method: 'GET', path: '/v1/
|
|
60
|
-
{ method: '
|
|
61
|
-
{ method: '
|
|
62
|
-
{ method: '
|
|
63
|
-
{ method: 'GET',
|
|
64
|
-
{ method: 'POST', regex: /^\/v1\/
|
|
65
|
-
{ method: 'POST',
|
|
66
|
-
{ method: 'GET',
|
|
67
|
-
{ method: 'POST',
|
|
68
|
-
{ method: '
|
|
69
|
-
{ method: '
|
|
70
|
-
{ method: 'POST',
|
|
71
|
-
{ method: 'GET',
|
|
72
|
-
{ method: 'POST',
|
|
73
|
-
{ method: '
|
|
74
|
-
{ method: '
|
|
75
|
-
{ method: 'POST',
|
|
76
|
-
{ method: 'GET',
|
|
77
|
-
{ method: 'POST',
|
|
78
|
-
{ method: '
|
|
79
|
-
{ method: 'GET',
|
|
80
|
-
{ method: 'POST',
|
|
81
|
-
{ method: '
|
|
82
|
-
{ method: 'GET',
|
|
83
|
-
{ method: 'POST',
|
|
84
|
-
{ method: '
|
|
85
|
-
{ method: 'GET',
|
|
86
|
-
{ method: 'POST',
|
|
87
|
-
{ method: '
|
|
88
|
-
{ method: 'GET',
|
|
89
|
-
{ method: 'POST',
|
|
90
|
-
{ method: '
|
|
91
|
-
{ method: '
|
|
92
|
-
{ method: 'POST',
|
|
93
|
-
{ method: '
|
|
94
|
-
{ method: '
|
|
95
|
-
{ method: 'POST',
|
|
96
|
-
|
|
97
|
-
{ method: 'POST', regex: /^\/v1\/
|
|
98
|
-
{ method: '
|
|
99
|
-
{ method: '
|
|
30
|
+
/** The /v1 routes in dispatch order; the first entry whose method and path match handles the request. Each row's `auth` is what the
|
|
31
|
+
* dispatch gate proves before its handler runs, so a handler never checks the caller itself. */
|
|
32
|
+
export const V1_ROUTES = [
|
|
33
|
+
{ method: 'POST', path: '/v1/memories', auth: 'caller', storeReady: 'entryWrites', loop: 'off', handler: handleCreateMemory },
|
|
34
|
+
{ method: 'GET', path: '/v1/graph', auth: 'caller', storeReady: 'graphReads', loop: 'off', handler: handleGetGraph },
|
|
35
|
+
{ method: 'GET', path: '/v1/memories', auth: 'caller', storeReady: 'base', loop: 'off', handler: handleRecallMemories },
|
|
36
|
+
{ method: 'GET', pattern: '/v1/sessions/:id/assemble', auth: 'caller', storeReady: 'dagReads', loop: 'off', handler: handleAssembleSession },
|
|
37
|
+
{ method: 'GET', pattern: '/v1/recall/drill/:id', auth: 'caller', storeReady: 'dagReads', handler: handleDrillRecall },
|
|
38
|
+
{ method: 'POST', pattern: '/v1/memories/:id/archive', auth: 'caller', storeReady: 'entryWrites', loop: 'off', handler: handleArchiveMemory },
|
|
39
|
+
{ method: 'POST', pattern: '/v1/memories/:id/supersede', auth: 'caller', storeReady: 'entryWrites', loop: 'off', handler: handleSupersedeMemory },
|
|
40
|
+
{ method: 'POST', pattern: '/v1/memories/:id/promote', auth: 'caller', sqliteOnly: 'copies a memory between the two local hippo.db files',
|
|
41
|
+
handler: handlePromoteMemory },
|
|
42
|
+
{ method: 'DELETE', pattern: '/v1/memories/:id', auth: 'caller', storeReady: 'entryWrites', loop: 'off', handler: handleForgetMemory },
|
|
43
|
+
{ method: 'POST', path: '/v1/outcome', auth: 'caller', storeReady: 'entryWrites', handler: handleApplyOutcome },
|
|
44
|
+
{ method: 'GET', path: '/v1/context', auth: 'caller', storeReady: 'contextReads', handler: handleGetContext },
|
|
45
|
+
{ method: 'POST', path: '/v1/sleep', auth: 'host-admin-local', sqliteOnly: 'consolidates every tenant under the local hippo root in this process',
|
|
46
|
+
handler: handleSleep },
|
|
47
|
+
{ method: 'POST', path: '/v1/auth/keys', auth: 'caller', storeReady: 'keyWrites', loop: 'off', handler: handleCreateAuthKey },
|
|
48
|
+
{ method: 'GET', path: '/v1/auth/keys', auth: 'caller', storeReady: 'keyWrites', loop: 'off', handler: handleListAuthKeys },
|
|
49
|
+
{ method: 'DELETE', pattern: '/v1/auth/keys/:keyId', auth: 'caller', storeReady: 'keyAudit', loop: 'off', handler: handleRevokeAuthKey },
|
|
50
|
+
{ method: 'GET', path: '/v1/quarantine', auth: 'admin', storeReady: 'quarantine', loop: 'off', handler: handleListQuarantine },
|
|
51
|
+
{ method: 'POST', pattern: '/v1/quarantine/:id/approve', auth: 'admin', storeReady: 'quarantine', loop: 'off', handler: handleApproveQuarantine },
|
|
52
|
+
{ method: 'POST', pattern: '/v1/quarantine/:id/reject', auth: 'admin', storeReady: 'quarantine', loop: 'off', handler: handleRejectQuarantine },
|
|
53
|
+
{ method: 'GET', path: '/v1/audit', auth: 'caller', storeReady: 'auditLog', loop: 'off', handler: handleListAudit },
|
|
54
|
+
{ method: 'POST', path: '/v1/predictions', auth: 'caller', storeReady: 'predictions', loop: 'off', handler: handleCreatePrediction },
|
|
55
|
+
{ method: 'GET', path: '/v1/predictions', auth: 'caller', storeReady: 'predictions', loop: 'off', handler: handleListPredictions },
|
|
56
|
+
{ method: 'GET', path: '/v1/predictions/stats', auth: 'caller', storeReady: 'predictions', loop: 'off', handler: handlePredictionStats },
|
|
57
|
+
{ method: 'GET', regex: /^\/v1\/predictions\/(\d+)$/, auth: 'caller', storeReady: 'predictions', loop: 'off', handler: handleGetPrediction },
|
|
58
|
+
{ method: 'POST', regex: /^\/v1\/predictions\/(\d+)\/close$/, auth: 'caller', storeReady: 'predictions', loop: 'off', handler: handleClosePrediction },
|
|
59
|
+
{ method: 'POST', path: '/v1/decisions', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCreateDecision },
|
|
60
|
+
{ method: 'GET', path: '/v1/decisions', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleListDecisions },
|
|
61
|
+
{ method: 'POST', regex: /^\/v1\/decisions\/(\d+)\/supersede$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleSupersedeDecision },
|
|
62
|
+
{ method: 'POST', regex: /^\/v1\/decisions\/(\d+)\/close$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCloseDecision },
|
|
63
|
+
{ method: 'GET', regex: /^\/v1\/decisions\/(\d+)$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleGetDecision },
|
|
64
|
+
{ method: 'POST', path: '/v1/incidents', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCreateIncident },
|
|
65
|
+
{ method: 'GET', path: '/v1/incidents', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleListIncidents },
|
|
66
|
+
{ method: 'POST', regex: /^\/v1\/incidents\/(\d+)\/resolve$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleResolveIncident },
|
|
67
|
+
{ method: 'POST', regex: /^\/v1\/incidents\/(\d+)\/close$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCloseIncident },
|
|
68
|
+
{ method: 'GET', regex: /^\/v1\/incidents\/(\d+)$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleGetIncident },
|
|
69
|
+
{ method: 'POST', path: '/v1/processes', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCreateProcess },
|
|
70
|
+
{ method: 'GET', path: '/v1/processes', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleListProcesses },
|
|
71
|
+
{ method: 'POST', regex: /^\/v1\/processes\/(\d+)\/supersede$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleSupersedeProcess },
|
|
72
|
+
{ method: 'POST', regex: /^\/v1\/processes\/(\d+)\/close$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCloseProcess },
|
|
73
|
+
{ method: 'GET', regex: /^\/v1\/processes\/(\d+)$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleGetProcess },
|
|
74
|
+
{ method: 'POST', path: '/v1/policies', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCreatePolicy },
|
|
75
|
+
{ method: 'GET', path: '/v1/policies', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleListPolicies },
|
|
76
|
+
{ method: 'GET', path: '/v1/policies/asof', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handlePoliciesAsOf },
|
|
77
|
+
{ method: 'POST', regex: /^\/v1\/policies\/(\d+)\/supersede$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleSupersedePolicy },
|
|
78
|
+
{ method: 'POST', regex: /^\/v1\/policies\/(\d+)\/close$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleClosePolicy },
|
|
79
|
+
{ method: 'GET', regex: /^\/v1\/policies\/(\d+)$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleGetPolicy },
|
|
80
|
+
{ method: 'POST', path: '/v1/skills', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCreateSkill },
|
|
81
|
+
{ method: 'GET', path: '/v1/skills', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleListSkills },
|
|
82
|
+
{ method: 'GET', path: '/v1/skills/export', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleExportSkills },
|
|
83
|
+
{ method: 'POST', regex: /^\/v1\/skills\/(\d+)\/supersede$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleSupersedeSkill },
|
|
84
|
+
{ method: 'POST', regex: /^\/v1\/skills\/(\d+)\/close$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCloseSkill },
|
|
85
|
+
{ method: 'GET', regex: /^\/v1\/skills\/(\d+)$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleGetSkill },
|
|
86
|
+
{ method: 'POST', path: '/v1/project-briefs', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCreateProjectBrief },
|
|
87
|
+
{ method: 'GET', path: '/v1/project-briefs', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleListProjectBriefs },
|
|
88
|
+
{ method: 'POST', path: '/v1/project-briefs/refresh', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleRefreshProjectBrief },
|
|
89
|
+
{ method: 'POST', regex: /^\/v1\/project-briefs\/(\d+)\/supersede$/, auth: 'caller', storeReady: 'objects', loop: 'off',
|
|
90
|
+
handler: handleSupersedeProjectBrief },
|
|
91
|
+
{ method: 'POST', regex: /^\/v1\/project-briefs\/(\d+)\/close$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCloseProjectBrief },
|
|
92
|
+
{ method: 'GET', regex: /^\/v1\/project-briefs\/(\d+)$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleGetProjectBrief },
|
|
93
|
+
{ method: 'POST', path: '/v1/customer-notes', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCreateCustomerNote },
|
|
94
|
+
{ method: 'GET', path: '/v1/customer-notes', auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleListCustomerNotes },
|
|
95
|
+
{ method: 'POST', regex: /^\/v1\/customer-notes\/(\d+)\/supersede$/, auth: 'caller', storeReady: 'objects', loop: 'off',
|
|
96
|
+
handler: handleSupersedeCustomerNote },
|
|
97
|
+
{ method: 'POST', regex: /^\/v1\/customer-notes\/(\d+)\/close$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleCloseCustomerNote },
|
|
98
|
+
{ method: 'GET', regex: /^\/v1\/customer-notes\/(\d+)$/, auth: 'caller', storeReady: 'objects', loop: 'off', handler: handleGetCustomerNote },
|
|
99
|
+
{ method: 'POST', path: '/v1/connectors/slack/events', auth: 'webhook-signature', storeReady: 'connectorEvents', handler: webhook(handleSlackEventsWebhook) },
|
|
100
|
+
{ method: 'POST', path: '/v1/connectors/github/events', auth: 'webhook-signature', storeReady: 'connectorEvents',
|
|
101
|
+
handler: webhook(handleGitHubEventsWebhook) },
|
|
100
102
|
];
|
|
101
|
-
/** The
|
|
102
|
-
|
|
103
|
-
function routeMatches(route, method, path) {
|
|
103
|
+
/** The handler bound to this path's params, or null when the path differs. */
|
|
104
|
+
function bindPath(route, path) {
|
|
104
105
|
if ('path' in route)
|
|
105
|
-
return
|
|
106
|
+
return path === route.path ? route.handler : null;
|
|
106
107
|
if ('pattern' in route) {
|
|
107
108
|
const params = matchPath(route.pattern, path);
|
|
108
|
-
return
|
|
109
|
+
return params ? (r) => route.handler(r, params) : null;
|
|
109
110
|
}
|
|
110
111
|
const match = path.match(route.regex);
|
|
111
|
-
return
|
|
112
|
+
return match ? (r) => route.handler(r, match) : null;
|
|
113
|
+
}
|
|
114
|
+
/** The route's run for this request, gate first, or null when method or path differ. The matcher runs before the method check,
|
|
115
|
+
* as the inline route blocks did, so a malformed `%` escape still throws from matchPath on any method. */
|
|
116
|
+
export function routeMatches(route, method, path) {
|
|
117
|
+
if (route.auth === 'webhook-signature') {
|
|
118
|
+
const run = bindPath(route, path);
|
|
119
|
+
if (run === null || method !== route.method)
|
|
120
|
+
return null;
|
|
121
|
+
return async (r) => {
|
|
122
|
+
assertRoutePorted(r.opts, route.storeReady);
|
|
123
|
+
await run(r);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
const run = bindPath(route, path);
|
|
127
|
+
if (run === null || method !== route.method)
|
|
128
|
+
return null;
|
|
129
|
+
return async (r) => run({ ...r, ctx: await passAuthGate(route, r) });
|
|
130
|
+
}
|
|
131
|
+
/** The one caller check a gated route passes: sleep refuses a caller off this host before any key work, then one charged auth,
|
|
132
|
+
* then 501 for an unported route, so a bad key is still a 401 there, and the row's role last. */
|
|
133
|
+
async function passAuthGate(route, { req, opts }) {
|
|
134
|
+
const label = routeLabel(route);
|
|
135
|
+
// Defence in depth, not the boundary: a socket address says where a request came from, never who sent it.
|
|
136
|
+
if (route.auth === 'host-admin-local' && !isLoopback(req.socket.remoteAddress)) {
|
|
137
|
+
throw new HttpError(403, `${label} is loopback-only (host-wide consolidation; see CHANGELOG v1.11.4)`);
|
|
138
|
+
}
|
|
139
|
+
const ctx = await buildContextWithAuth(req, opts);
|
|
140
|
+
assertRoutePorted(opts, route.storeReady);
|
|
141
|
+
if (route.auth === 'admin' && ctx.actor.role !== 'admin')
|
|
142
|
+
throw new HttpError(403, `${label} requires admin role`);
|
|
143
|
+
if (route.auth === 'host-admin-local')
|
|
144
|
+
assertCrossTenantAdmin(ctx, label);
|
|
145
|
+
return ctx;
|
|
112
146
|
}
|
|
113
147
|
/** The route as the access line names it; a regex route reads as its pattern would, so no line carries a caller's id. */
|
|
114
|
-
function routeLabel(route) {
|
|
148
|
+
export function routeLabel(route) {
|
|
115
149
|
if ('path' in route)
|
|
116
150
|
return route.path;
|
|
117
151
|
if ('pattern' in route)
|
|
@@ -125,61 +159,20 @@ export async function dispatchV1Route(r, method, path) {
|
|
|
125
159
|
if (run === null)
|
|
126
160
|
continue;
|
|
127
161
|
noteAccess(r.req, { route: routeLabel(route) });
|
|
128
|
-
await refuseUnportedRoute(r.req, r.opts, route.storeReady);
|
|
129
162
|
// Only a store with worker threads has moved the route's SQLite work; under any other the handler still opens hippo.db itself.
|
|
130
163
|
await (route.loop === 'off' && runsOffLoop(r.opts.store) ? withSqliteOffLoop(() => run(r)) : run(r));
|
|
131
164
|
return true;
|
|
132
165
|
}
|
|
133
166
|
return false;
|
|
134
167
|
}
|
|
135
|
-
const PLAIN_SEGMENT_RE = /^[A-Za-z0-9._~-]+$/;
|
|
136
|
-
function isPlainV1Path(path) {
|
|
137
|
-
return path.startsWith('/v1/') && new URL(path, 'http://h').pathname === path
|
|
138
|
-
&& path.slice('/v1/'.length).split('/').every((segment) => PLAIN_SEGMENT_RE.test(segment));
|
|
139
|
-
}
|
|
140
|
-
// A plain path never holds a `%`, so matchPath cannot throw here.
|
|
141
|
-
function isCorePath(method, path) {
|
|
142
|
-
return PUBLIC_ROUTES.has(`${method} ${path}`) || V1_ROUTES.some((route) => routeMatches(route, method, path) !== null);
|
|
143
|
-
}
|
|
144
|
-
/** Boot-time check: an add-on path must be plain, unique and not one core serves, so no add-on shadows a core route or hides from dispatch. */
|
|
145
|
-
export function assertAddonRoutes(routes) {
|
|
146
|
-
const seen = new Set();
|
|
147
|
-
for (const { path } of routes) {
|
|
148
|
-
if (!isPlainV1Path(path))
|
|
149
|
-
throw new Error(`add-on route '${path}' is not a plain /v1/ path (segments use A-Z a-z 0-9 . _ ~ -)`);
|
|
150
|
-
if (seen.has(path))
|
|
151
|
-
throw new Error(`add-on route '${path}' is registered twice`);
|
|
152
|
-
if (isCorePath('POST', path))
|
|
153
|
-
throw new Error(`add-on route '${path}' is already served by core`);
|
|
154
|
-
seen.add(path);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
const PUBLIC_JSON_MAX_BYTES = 64 * 1024;
|
|
158
|
-
/** Boot-time check and serialization: a public path that a core GET route serves would open that route to anyone. */
|
|
159
|
-
export function assertPublicJson(publicJson) {
|
|
160
|
-
const bodies = new Map();
|
|
161
|
-
for (const [path, value] of Object.entries(publicJson)) {
|
|
162
|
-
if (!isPlainV1Path(path))
|
|
163
|
-
throw new Error(`public JSON path '${path}' is not a plain /v1/ path (segments use A-Z a-z 0-9 . _ ~ -)`);
|
|
164
|
-
if (isCorePath('GET', path))
|
|
165
|
-
throw new Error(`public JSON path '${path}' is already served by core`);
|
|
166
|
-
const text = JSON.stringify(value);
|
|
167
|
-
if (text === undefined)
|
|
168
|
-
throw new Error(`public JSON at '${path}' is not JSON`);
|
|
169
|
-
if (Buffer.byteLength(text) > PUBLIC_JSON_MAX_BYTES)
|
|
170
|
-
throw new Error(`public JSON at '${path}' is over 64 KiB`);
|
|
171
|
-
bodies.set(path, text);
|
|
172
|
-
}
|
|
173
|
-
return bodies;
|
|
174
|
-
}
|
|
175
168
|
/** Core authenticates and parses before the handler runs, so an add-on route gets the same 401, 400 and 501 as a core one. */
|
|
176
169
|
export async function dispatchAddonRoute({ req, res, opts }, method, path) {
|
|
177
170
|
const route = method === 'POST' ? opts.routes?.find((r) => r.path === path) : undefined;
|
|
178
171
|
if (!route)
|
|
179
172
|
return false;
|
|
180
173
|
noteAccess(req, { route: route.path });
|
|
181
|
-
await refuseUnportedRoute(req, opts, route.storeReady);
|
|
182
174
|
const ctx = await buildContextWithAuth(req, opts);
|
|
175
|
+
assertRoutePorted(opts, route.storeReady);
|
|
183
176
|
noteAccess(req, { tenant: ctx.tenantId });
|
|
184
177
|
const body = await parseJsonBody(req, ctx);
|
|
185
178
|
sendJson(res, 200, await route.handler({ ctx, body }));
|
|
@@ -195,15 +188,10 @@ export function dispatchPublicJson({ req, res, opts }, method, path) {
|
|
|
195
188
|
res.end(text);
|
|
196
189
|
return true;
|
|
197
190
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
throw new HttpError(501, STORE_NOT_PORTED_MESSAGE);
|
|
201
|
-
}
|
|
202
|
-
/** Under another store, a route that names no group, or one the store lacks, answers 501 without running; the caller is checked first, so a bad key is still a 401. */
|
|
203
|
-
async function refuseUnportedRoute(req, opts, group) {
|
|
191
|
+
/** Under another store, a route that names no group, or one the store lacks, answers 501 without running. */
|
|
192
|
+
function assertRoutePorted(opts, group) {
|
|
204
193
|
if (opts.store.kind === 'sqlite' || (group !== undefined && hasGroup(opts.store, group)))
|
|
205
194
|
return;
|
|
206
|
-
|
|
207
|
-
assertSqliteStore(opts);
|
|
195
|
+
throw new HttpError(501, STORE_NOT_PORTED_MESSAGE);
|
|
208
196
|
}
|
|
209
197
|
//# sourceMappingURL=route-table.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function handleCreateAuthKey({ req, res, opts }:
|
|
3
|
-
export declare function handleListAuthKeys({
|
|
4
|
-
export declare function handleRevokeAuthKey({
|
|
5
|
-
export declare function handleListQuarantine({
|
|
6
|
-
export declare function handleApproveQuarantine({
|
|
7
|
-
export declare function handleRejectQuarantine({
|
|
8
|
-
export declare function handleListAudit({
|
|
1
|
+
import type { AuthedRouteRequest } from '../types.js';
|
|
2
|
+
export declare function handleCreateAuthKey({ req, res, opts }: AuthedRouteRequest): Promise<void>;
|
|
3
|
+
export declare function handleListAuthKeys({ res, ctx, query }: AuthedRouteRequest): Promise<void>;
|
|
4
|
+
export declare function handleRevokeAuthKey({ res, ctx }: AuthedRouteRequest, keyMatch: Record<string, string>): Promise<void>;
|
|
5
|
+
export declare function handleListQuarantine({ res, ctx, query }: AuthedRouteRequest): Promise<void>;
|
|
6
|
+
export declare function handleApproveQuarantine({ res, ctx }: AuthedRouteRequest, quarantineApproveMatch: Record<string, string>): Promise<void>;
|
|
7
|
+
export declare function handleRejectQuarantine({ res, ctx }: AuthedRouteRequest, quarantineRejectMatch: Record<string, string>): Promise<void>;
|
|
8
|
+
export declare function handleListAudit({ res, ctx, query }: AuthedRouteRequest): Promise<void>;
|
|
9
9
|
//# sourceMappingURL=admin.d.ts.map
|
|
@@ -1,38 +1,33 @@
|
|
|
1
1
|
// Admin routes: API keys, quarantine and the audit log.
|
|
2
|
+
import { DEFAULT_LIST_LIMIT } from '../../util/limits.js';
|
|
2
3
|
import { AUDIT_OPS } from '../../store/audit.js';
|
|
3
4
|
import { auditList, authCreate, authListRows, authRevoke, quarantineApprove, quarantineList, quarantineReject } from '../../api/index.js';
|
|
4
5
|
import { HttpError, readBody, sendJson } from '../../util/http-util.js';
|
|
5
|
-
import {
|
|
6
|
-
import { assertCrossTenantAdmin, buildContextWithAuth } from '../auth.js';
|
|
6
|
+
import { assertCrossTenantAdmin, recheckContextWithAuth } from '../auth.js';
|
|
7
7
|
import { pageOf, parseCursor, setNextCursorHeader } from '../cursor.js';
|
|
8
8
|
import { isSetMember, parseJsonObjectText, parseListLimit, validateIdSegment } from '../validation.js';
|
|
9
|
-
import { isJsonString } from '../../util/json.js';
|
|
9
|
+
import { isJsonBoolean, isJsonNumber, isJsonString } from '../../util/json.js';
|
|
10
10
|
const VALID_AUDIT_OPS = new Set(AUDIT_OPS);
|
|
11
|
-
//
|
|
11
|
+
// A key mint is a few short fields, so even an authenticated caller gets a small cap and a short wait.
|
|
12
12
|
// ServeOpts.mintBodyDeadlineMs overrides the wait for tests only, so a 408 test need not sit through it.
|
|
13
13
|
const MINT_BODY_MAX_BYTES = 4 * 1024;
|
|
14
14
|
const MINT_BODY_DEADLINE_MS = 10_000;
|
|
15
|
-
// Cap on GET /v1/audit?limit
|
|
16
|
-
// enough to dump a small deployment's full audit log without paginating, but
|
|
17
|
-
// small enough that a malicious client can't ask for the world.
|
|
15
|
+
// Cap on GET /v1/audit?limit=: large enough to dump a small deployment's audit log unpaginated, small enough that a client cannot ask for the world.
|
|
18
16
|
const MAX_AUDIT_LIMIT = 10000;
|
|
19
17
|
// GET /v1/auth/keys had no limit, so its default page is the cap: a deployment below 1000 keys sees no change.
|
|
20
18
|
const MAX_AUTH_KEYS_PAGE = 1000;
|
|
21
|
-
// POST /v1/auth/keys
|
|
22
|
-
// body: the HTTP layer hands it to the client; the user-facing
|
|
23
|
-
// "store this somewhere safe" warning belongs in the CLI client, not here.
|
|
19
|
+
// POST /v1/auth/keys: mints a key; plaintext is in the response body (the CLI client, not this layer, carries the "store this somewhere safe" warning).
|
|
24
20
|
export async function handleCreateAuthKey({ req, res, opts }) {
|
|
25
|
-
//
|
|
21
|
+
// The dispatch gate authenticated before the body, so an unknown caller costs no read; this recheck runs the resolver right before the mint.
|
|
26
22
|
const raw = await readBody(req, { maxBytes: MINT_BODY_MAX_BYTES, deadlineMs: opts.mintBodyDeadlineMs ?? MINT_BODY_DEADLINE_MS });
|
|
27
|
-
const ctx = await
|
|
23
|
+
const ctx = await recheckContextWithAuth(req, opts);
|
|
28
24
|
const body = parseJsonObjectText(raw);
|
|
29
25
|
const labelRaw = body['label'];
|
|
30
26
|
if (labelRaw !== undefined && !isJsonString(labelRaw)) {
|
|
31
27
|
throw new HttpError(400, 'label must be a string');
|
|
32
28
|
}
|
|
33
|
-
// Optional body.role mirrors the --role CLI flag
|
|
34
|
-
//
|
|
35
|
-
// fallback to admin). authCreate refuses a member caller with a 403.
|
|
29
|
+
// Optional body.role mirrors the --role CLI flag and is validated strictly: anything but 'admin'|'member' is a 400; authCreate refuses a member caller
|
|
30
|
+
// with a 403.
|
|
36
31
|
const roleRaw = body['role'];
|
|
37
32
|
let role;
|
|
38
33
|
if (roleRaw !== undefined) {
|
|
@@ -41,25 +36,28 @@ export async function handleCreateAuthKey({ req, res, opts }) {
|
|
|
41
36
|
}
|
|
42
37
|
role = roleRaw;
|
|
43
38
|
}
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
// A null is a 400 too: a client that serialises an unset field as null must not get a key that never expires.
|
|
40
|
+
const ttlDays = body['ttlDays'];
|
|
41
|
+
if (ttlDays !== undefined && !isJsonNumber(ttlDays)) {
|
|
42
|
+
throw new HttpError(400, 'ttlDays must be a number');
|
|
43
|
+
}
|
|
44
|
+
const noExpiry = body['noExpiry'];
|
|
45
|
+
if (noExpiry !== undefined && !isJsonBoolean(noExpiry)) {
|
|
46
|
+
throw new HttpError(400, 'noExpiry must be true or false');
|
|
47
|
+
}
|
|
48
|
+
// Security: any body `tenantId` is IGNORED; the key is bound to the caller's authenticated tenant, or tenant A could mint a key for tenant B (see
|
|
49
|
+
// authCreate).
|
|
48
50
|
const result = await authCreate(ctx, {
|
|
49
51
|
label: labelRaw,
|
|
50
52
|
role,
|
|
53
|
+
ttlDays,
|
|
54
|
+
noExpiry,
|
|
51
55
|
});
|
|
52
|
-
// The reply cannot change shape, so the server log is where a defaulted admin key gets noticed.
|
|
53
|
-
if (role === undefined && result.role === 'admin') {
|
|
54
|
-
log.warn(`auth key ${result.keyId} was minted with no role in the body, so it is an admin key, and it never expires; send "role": "member" for a narrower one`);
|
|
55
|
-
}
|
|
56
56
|
sendJson(res, 200, result);
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
|
-
// GET /v1/auth/keys?active=true&limit=&cursor=:
|
|
60
|
-
|
|
61
|
-
// a single GET; ?active=false includes revoked and expired rows.
|
|
62
|
-
export async function handleListAuthKeys({ req, res, opts, query }) {
|
|
59
|
+
// GET /v1/auth/keys?active=true&limit=&cursor=: lists keys visible to ctx.tenantId; `active` defaults to true, ?active=false includes revoked and expired rows.
|
|
60
|
+
export async function handleListAuthKeys({ res, ctx, query }) {
|
|
63
61
|
const activeRaw = query.get('active');
|
|
64
62
|
let active = true;
|
|
65
63
|
if (activeRaw !== null) {
|
|
@@ -72,28 +70,21 @@ export async function handleListAuthKeys({ req, res, opts, query }) {
|
|
|
72
70
|
}
|
|
73
71
|
const limit = parseListLimit(query.get('limit'), MAX_AUTH_KEYS_PAGE, MAX_AUTH_KEYS_PAGE);
|
|
74
72
|
const after = parseCursor(query.get('cursor'), 'integer', 'integer');
|
|
75
|
-
const ctx = await buildContextWithAuth(req, opts);
|
|
76
73
|
const page = pageOf(await authListRows(ctx, { active, limit: limit + 1, after }), limit, (r) => ({ key: r.rowId, id: r.rowId }));
|
|
77
74
|
setNextCursorHeader(res, page.nextCursor);
|
|
78
75
|
sendJson(res, 200, page.items.map((r) => r.key));
|
|
79
76
|
return;
|
|
80
77
|
}
|
|
81
|
-
// DELETE /v1/auth/keys/:keyId
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
export async function handleRevokeAuthKey({ req, res, opts }, keyMatch) {
|
|
78
|
+
// DELETE /v1/auth/keys/:keyId revokes: missing or cross-tenant keys are 404 (no leak); a member is 403 on any key but its own or, via the resolver, those it
|
|
79
|
+
// minted. Returns 200 with the body rather than 204 so the caller sees revokedAt.
|
|
80
|
+
export async function handleRevokeAuthKey({ res, ctx }, keyMatch) {
|
|
85
81
|
validateIdSegment(keyMatch.keyId, 'key id');
|
|
86
|
-
const ctx = await buildContextWithAuth(req, opts);
|
|
87
82
|
const result = await authRevoke(ctx, keyMatch.keyId);
|
|
88
83
|
sendJson(res, 200, result);
|
|
89
84
|
return;
|
|
90
85
|
}
|
|
91
|
-
// GET /v1/quarantine?status=&limit=&cursor=: quarantine review queue. quarantineList carries no role gate itself, so
|
|
92
|
-
export async function handleListQuarantine({
|
|
93
|
-
const ctx = await buildContextWithAuth(req, opts);
|
|
94
|
-
if (ctx.actor.role !== 'admin') {
|
|
95
|
-
throw new HttpError(403, '/v1/quarantine requires admin role');
|
|
96
|
-
}
|
|
86
|
+
// GET /v1/quarantine?status=&limit=&cursor=: quarantine review queue. quarantineList carries no role gate itself, so its row's admin gate is the check.
|
|
87
|
+
export async function handleListQuarantine({ res, ctx, query }) {
|
|
97
88
|
const statusRaw = query.get('status');
|
|
98
89
|
let status = 'pending';
|
|
99
90
|
if (statusRaw !== null) {
|
|
@@ -109,25 +100,21 @@ export async function handleListQuarantine({ req, res, opts, query }) {
|
|
|
109
100
|
return;
|
|
110
101
|
}
|
|
111
102
|
// POST /v1/quarantine/:id/approve: admin only; ForbiddenError falls through to mapApiError's 403.
|
|
112
|
-
export async function handleApproveQuarantine({
|
|
103
|
+
export async function handleApproveQuarantine({ res, ctx }, quarantineApproveMatch) {
|
|
113
104
|
validateIdSegment(quarantineApproveMatch.id, 'memory id');
|
|
114
|
-
const ctx = await buildContextWithAuth(req, opts);
|
|
115
105
|
await quarantineApprove(ctx, quarantineApproveMatch.id);
|
|
116
106
|
sendJson(res, 200, { approved: quarantineApproveMatch.id });
|
|
117
107
|
return;
|
|
118
108
|
}
|
|
119
109
|
// POST /v1/quarantine/:id/reject: admin only; ForbiddenError falls through to mapApiError's 403.
|
|
120
|
-
export async function handleRejectQuarantine({
|
|
110
|
+
export async function handleRejectQuarantine({ res, ctx }, quarantineRejectMatch) {
|
|
121
111
|
validateIdSegment(quarantineRejectMatch.id, 'memory id');
|
|
122
|
-
const ctx = await buildContextWithAuth(req, opts);
|
|
123
112
|
await quarantineReject(ctx, quarantineRejectMatch.id);
|
|
124
113
|
sendJson(res, 200, { rejected: quarantineRejectMatch.id });
|
|
125
114
|
return;
|
|
126
115
|
}
|
|
127
|
-
// GET /v1/audit?op=&since=&limit=&cursor=:
|
|
128
|
-
|
|
129
|
-
// we hit the DB.
|
|
130
|
-
export async function handleListAudit({ req, res, opts, query }) {
|
|
116
|
+
// GET /v1/audit?op=&since=&limit=&cursor=: all three filters are validated at the route boundary so an invalid value is a 400 before the DB is hit.
|
|
117
|
+
export async function handleListAudit({ res, ctx, query }) {
|
|
131
118
|
const opRaw = query.get('op');
|
|
132
119
|
let op;
|
|
133
120
|
if (opRaw !== null) {
|
|
@@ -146,7 +133,7 @@ export async function handleListAudit({ req, res, opts, query }) {
|
|
|
146
133
|
since = sinceRaw;
|
|
147
134
|
}
|
|
148
135
|
const limitRaw = query.get('limit');
|
|
149
|
-
let limit =
|
|
136
|
+
let limit = DEFAULT_LIST_LIMIT;
|
|
150
137
|
if (limitRaw !== null) {
|
|
151
138
|
const parsed = Number(limitRaw);
|
|
152
139
|
if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < 1 || parsed > MAX_AUDIT_LIMIT) {
|
|
@@ -155,7 +142,6 @@ export async function handleListAudit({ req, res, opts, query }) {
|
|
|
155
142
|
limit = parsed;
|
|
156
143
|
}
|
|
157
144
|
const after = parseCursor(query.get('cursor'), 'string', 'integer');
|
|
158
|
-
const ctx = await buildContextWithAuth(req, opts);
|
|
159
145
|
// ?tenant=<t> reads another tenant (e.g. '__host__' for consolidate rows); admin only.
|
|
160
146
|
const tenantOverride = query.get('tenant');
|
|
161
147
|
const crossTenant = tenantOverride !== null && tenantOverride !== '' && tenantOverride !== ctx.tenantId;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function handleCreateCustomerNote(rr:
|
|
3
|
-
export declare function handleListCustomerNotes(rr:
|
|
4
|
-
export declare function handleSupersedeCustomerNote(rr:
|
|
5
|
-
export declare function handleCloseCustomerNote(rr:
|
|
6
|
-
export declare function handleGetCustomerNote(rr:
|
|
1
|
+
import type { AuthedRouteRequest } from '../types.js';
|
|
2
|
+
export declare function handleCreateCustomerNote(rr: AuthedRouteRequest): Promise<void>;
|
|
3
|
+
export declare function handleListCustomerNotes(rr: AuthedRouteRequest): Promise<void>;
|
|
4
|
+
export declare function handleSupersedeCustomerNote(rr: AuthedRouteRequest, match: RegExpMatchArray): Promise<void>;
|
|
5
|
+
export declare function handleCloseCustomerNote(rr: AuthedRouteRequest, match: RegExpMatchArray): Promise<void>;
|
|
6
|
+
export declare function handleGetCustomerNote(rr: AuthedRouteRequest, match: RegExpMatchArray): Promise<void>;
|
|
7
7
|
//# sourceMappingURL=customer-notes.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// /v1/customer-notes routes.
|
|
2
|
-
import { CUSTOMER_NOTE, MAX_CUSTOMER_LEN } from '../../objects/customer-notes.js';
|
|
2
|
+
import { CUSTOMER_NOTE, MAX_CHANGE_SUMMARY_LEN, MAX_CUSTOMER_LEN } from '../../objects/customer-notes.js';
|
|
3
3
|
import { sendJson } from '../../util/http-util.js';
|
|
4
|
-
import { buildContextWithAuth } from '../auth.js';
|
|
5
4
|
import { parseJsonBody } from '../validation.js';
|
|
6
|
-
import {
|
|
5
|
+
import { saveFor } from '../../api/objects.js';
|
|
6
|
+
import { closeRoute, getRoute, listRoute, optionalString, requiredString, supersedeRoute } from './object-routes.js';
|
|
7
7
|
const noteRoutes = {
|
|
8
8
|
noun: 'customer note',
|
|
9
9
|
field: 'note',
|
|
@@ -12,22 +12,16 @@ const noteRoutes = {
|
|
|
12
12
|
filterParam: 'customer',
|
|
13
13
|
revise: (body) => {
|
|
14
14
|
const note = requiredString(body, 'note', { max: 8192 });
|
|
15
|
-
const changeSummary = optionalString(body, 'changeSummary',
|
|
15
|
+
const changeSummary = optionalString(body, 'changeSummary', MAX_CHANGE_SUMMARY_LEN);
|
|
16
16
|
return (existing, id) => ({ customer: existing.customer, note, changeSummary, supersedesNoteId: id });
|
|
17
17
|
},
|
|
18
18
|
};
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
// 5 routes (no assembler/refresh): POST /v1/customer-notes (new; body customer +
|
|
22
|
-
// note), GET /v1/customer-notes (list; status + customer filter; shared
|
|
23
|
-
// parseListLimit), GET /v1/customer-notes/:id, POST /v1/customer-notes/:id/supersede,
|
|
24
|
-
// POST /v1/customer-notes/:id/close. DoS caps: customer 256, note 8192,
|
|
25
|
-
// changeSummary 4096. The store validates + throws; the boundary maps validation ->
|
|
26
|
-
// 400, not-found -> 404, not-active -> 409. Mirrors /v1/project-briefs.
|
|
19
|
+
// Routes: customer notes under /v1/customer-notes (create, list, show, supersede, close), mirroring /v1/project-briefs. The store validates and throws;
|
|
20
|
+
// the boundary maps validation -> 400, not-found -> 404, not-active -> 409.
|
|
27
21
|
export async function handleCreateCustomerNote(rr) {
|
|
28
|
-
const ctx =
|
|
22
|
+
const { ctx } = rr;
|
|
29
23
|
const body = await parseJsonBody(rr.req, ctx);
|
|
30
|
-
const customerNote = await saveFor(
|
|
24
|
+
const customerNote = await saveFor(ctx, CUSTOMER_NOTE, {
|
|
31
25
|
customer: requiredString(body, 'customer', { max: MAX_CUSTOMER_LEN }),
|
|
32
26
|
note: requiredString(body, 'note', { max: 8192 }),
|
|
33
27
|
});
|