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
package/dist/connectors/dlq.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type HippoStore } from '../store/index.js';
|
|
2
2
|
import type { ConnectorDeadLetter } from '../store/port.js';
|
|
3
|
+
import type { JsonValue } from '../util/json.js';
|
|
3
4
|
declare const DEFAULT_BUCKET = "parse_error";
|
|
4
5
|
/** What a caller hands over to park one payload, whatever the connector. */
|
|
5
6
|
export interface ParkOpts<Bucket extends string> {
|
|
@@ -18,10 +19,14 @@ export interface ParkedRow<Bucket extends string> {
|
|
|
18
19
|
bucket: Bucket | typeof DEFAULT_BUCKET;
|
|
19
20
|
signature: string | null;
|
|
20
21
|
}
|
|
21
|
-
/** What one connector supplies: the tag that names its table to the store,
|
|
22
|
+
/** What one connector supplies: the tag that names its table to the store, its list, its one-row read and its retry bump.
|
|
23
|
+
* `Own` is the columns only its table has. */
|
|
22
24
|
export interface ConnectorDlq<Own, Bucket extends string, Item> {
|
|
23
25
|
readonly letter: (row: ParkedRow<Bucket> & Own) => ConnectorDeadLetter;
|
|
24
26
|
readonly list: (hippoRoot: string, tenantId: string, limit: number) => Item[];
|
|
27
|
+
readonly entry: (hippoRoot: string, id: number) => Item | null;
|
|
28
|
+
/** Adds one to `retry_count` and stamps `retried_at`. */
|
|
29
|
+
readonly bump: (hippoRoot: string, id: number) => void;
|
|
25
30
|
}
|
|
26
31
|
/** Parks on `store`, else on hippo.db under `hippoRoot`. */
|
|
27
32
|
export declare function parkInDlq<Own, Bucket extends string>(dlq: ConnectorDlq<Own, Bucket, unknown>, hippoRoot: string, opts: ParkOpts<Bucket> & NoInfer<Own>, store?: HippoStore): Promise<number>;
|
|
@@ -38,7 +43,38 @@ export interface ReplayResult {
|
|
|
38
43
|
retryCount: number;
|
|
39
44
|
reason?: string;
|
|
40
45
|
}
|
|
41
|
-
/**
|
|
42
|
-
|
|
46
|
+
/** The columns a replay reads from any connector's row. */
|
|
47
|
+
interface ParkedEntry {
|
|
48
|
+
readonly id: number;
|
|
49
|
+
readonly retryCount: number;
|
|
50
|
+
readonly rawPayload: string;
|
|
51
|
+
}
|
|
52
|
+
/** A row that cannot pass the signature gate: 'sig_missing' is not counted, since only --force can get it through. */
|
|
53
|
+
export interface SignatureRefusal {
|
|
54
|
+
readonly status: 'sig_missing' | 'sig_fail';
|
|
55
|
+
readonly reason: string;
|
|
56
|
+
}
|
|
57
|
+
/** What a connector's re-ingest of a parsed envelope reports. */
|
|
58
|
+
export type Reingest = {
|
|
59
|
+
readonly ok: true;
|
|
60
|
+
readonly status: ReplayStatus;
|
|
61
|
+
readonly memoryId: string | null;
|
|
62
|
+
readonly reason?: string;
|
|
63
|
+
} | {
|
|
64
|
+
readonly ok: false;
|
|
65
|
+
readonly status: ReplayStatus;
|
|
66
|
+
readonly reason: string;
|
|
67
|
+
};
|
|
68
|
+
/** The parts of a replay only the connector knows. */
|
|
69
|
+
export interface ReplaySteps<Item, Envelope extends JsonValue> {
|
|
70
|
+
readonly dlq: ConnectorDlq<never, never, Item>;
|
|
71
|
+
/** Skipped under --force. */
|
|
72
|
+
readonly refuseSignature: (row: Item) => SignatureRefusal | null;
|
|
73
|
+
readonly isEnvelope: (parsed: JsonValue) => parsed is Envelope;
|
|
74
|
+
readonly notEnvelope: string;
|
|
75
|
+
readonly reingest: (row: Item, envelope: Envelope) => Promise<Reingest>;
|
|
76
|
+
}
|
|
77
|
+
/** Re-runs a parked row under today's secret and routing; every attempt past the read is counted once, except a missing signature. */
|
|
78
|
+
export declare function replayParked<Item extends ParkedEntry, Envelope extends JsonValue>(steps: ReplaySteps<Item, Envelope>, hippoRoot: string, id: number, force: boolean): Promise<ReplayResult>;
|
|
43
79
|
export {};
|
|
44
80
|
//# sourceMappingURL=dlq.d.ts.map
|
package/dist/connectors/dlq.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// The dead-letter queue every webhook connector parks into: one redaction, one unroutable sentinel, one set of defaults, one replay result.
|
|
2
|
+
import { DEFAULT_LIST_LIMIT } from '../util/limits.js';
|
|
2
3
|
import { DLQ_REDACTED_NOTE, redactPayload } from '../util/secret-detect.js';
|
|
3
4
|
import { requireGroup, storeFor } from '../store/index.js';
|
|
5
|
+
import { errorMessage } from '../util/log.js';
|
|
4
6
|
/** The tenant stored on a row no tenant was resolved for; the column is NOT NULL. */
|
|
5
7
|
const UNROUTABLE_TENANT = '__unroutable__';
|
|
6
8
|
const DEFAULT_BUCKET = 'parse_error';
|
|
7
|
-
const DEFAULT_LIST_LIMIT = 100;
|
|
8
9
|
/** Parks on `store`, else on hippo.db under `hippoRoot`. */
|
|
9
10
|
export async function parkInDlq(dlq, hippoRoot, opts, store) {
|
|
10
11
|
const rawPayload = redactPayload(opts.rawPayload);
|
|
@@ -23,8 +24,41 @@ export async function parkInDlq(dlq, hippoRoot, opts, store) {
|
|
|
23
24
|
export function listDlq(dlq, hippoRoot, opts) {
|
|
24
25
|
return dlq.list(hippoRoot, opts.tenantId, opts.limit ?? DEFAULT_LIST_LIMIT);
|
|
25
26
|
}
|
|
26
|
-
/** A replay that did not go through; `retryCount` is the row's count after any bump
|
|
27
|
-
|
|
27
|
+
/** A replay that did not go through; `retryCount` is the row's count after any bump made. */
|
|
28
|
+
function replayFailed(status, retryCount, reason) {
|
|
28
29
|
return { ok: false, status, memoryId: null, retryCount, reason };
|
|
29
30
|
}
|
|
31
|
+
/** A replay that failed after the row was read: counts it exactly once, then reports the new count. */
|
|
32
|
+
function failAndBump(dlq, hippoRoot, row, status, reason) {
|
|
33
|
+
dlq.bump(hippoRoot, row.id);
|
|
34
|
+
return replayFailed(status, row.retryCount + 1, reason);
|
|
35
|
+
}
|
|
36
|
+
/** Re-runs a parked row under today's secret and routing; every attempt past the read is counted once, except a missing signature. */
|
|
37
|
+
export async function replayParked(steps, hippoRoot, id, force) {
|
|
38
|
+
const row = steps.dlq.entry(hippoRoot, id);
|
|
39
|
+
if (!row)
|
|
40
|
+
return replayFailed('not_found', 0, `dlq id ${id} not found`);
|
|
41
|
+
const refusal = force ? null : steps.refuseSignature(row);
|
|
42
|
+
if (refusal?.status === 'sig_missing')
|
|
43
|
+
return replayFailed(refusal.status, row.retryCount, refusal.reason);
|
|
44
|
+
if (refusal)
|
|
45
|
+
return failAndBump(steps.dlq, hippoRoot, row, refusal.status, refusal.reason);
|
|
46
|
+
let parsed;
|
|
47
|
+
try {
|
|
48
|
+
parsed = JSON.parse(row.rawPayload);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
return failAndBump(steps.dlq, hippoRoot, row, 'parse_error', `still unparseable: ${errorMessage(e)}`);
|
|
52
|
+
}
|
|
53
|
+
if (!steps.isEnvelope(parsed))
|
|
54
|
+
return failAndBump(steps.dlq, hippoRoot, row, 'unhandled', steps.notEnvelope);
|
|
55
|
+
const outcome = await steps.reingest(row, parsed);
|
|
56
|
+
if (!outcome.ok)
|
|
57
|
+
return failAndBump(steps.dlq, hippoRoot, row, outcome.status, outcome.reason);
|
|
58
|
+
steps.dlq.bump(hippoRoot, row.id);
|
|
59
|
+
const result = { ok: true, status: outcome.status, memoryId: outcome.memoryId, retryCount: row.retryCount + 1 };
|
|
60
|
+
if (outcome.reason !== undefined)
|
|
61
|
+
result.reason = outcome.reason;
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
30
64
|
//# sourceMappingURL=dlq.js.map
|
|
@@ -1,28 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* - /repos/{repo}/issues -> issues_hwm
|
|
5
|
-
* - /repos/{repo}/issues/comments -> issue_comments_hwm
|
|
6
|
-
* - /repos/{repo}/pulls/comments -> pr_review_comments_hwm
|
|
7
|
-
*
|
|
8
|
-
* Crash safety: each stream's HWM is persisted ONLY after
|
|
9
|
-
* the stream fully drains. If stream 2 throws mid-flight, stream 1's HWM
|
|
10
|
-
* is committed and stream 2's stays NULL (or its prior value). Rerun
|
|
11
|
-
* picks up from stream 1's saved HWM and re-fetches stream 2 from its
|
|
12
|
-
* last committed point.
|
|
13
|
-
*
|
|
14
|
-
* The /issues endpoint returns BOTH issues and PRs (a PR is
|
|
15
|
-
* an issue with a `pull_request` field). We skip PRs here so they don't
|
|
16
|
-
* get ingested under the issues schema. PRs are handled via webhook in
|
|
17
|
-
* V1 (no /pulls backfill stream — review comments cover the discussion
|
|
18
|
-
* surface).
|
|
19
|
-
*
|
|
20
|
-
* Privacy (V1 limitation): the REST list endpoints don't reliably set
|
|
21
|
-
* `repository.private`, and resolving it requires an extra API call per
|
|
22
|
-
* repo. Backfill leaves the field undefined so scopeFromRepository falls
|
|
23
|
-
* through to private. Callers who know the repo is public can re-tag
|
|
24
|
-
* downstream; the fail-safe default protects private orgs.
|
|
25
|
-
*/
|
|
1
|
+
/** Paginated backfill of the GitHub issues, issue-comments and PR-review-comments streams, each with its own high-water mark (HWM).
|
|
2
|
+
* An HWM is persisted only after its stream fully drains, so a crash in stream 2 leaves stream 1 committed and stream 2 resumes from its prior HWM.
|
|
3
|
+
* `repository.private` is left undefined (REST lists omit it), so scopeFromRepository falls through to private. */
|
|
26
4
|
import type { Context } from '../../api/index.js';
|
|
27
5
|
import type { GitHubFetcher } from './octokit-client.js';
|
|
28
6
|
export interface BackfillOpts {
|
|
@@ -32,6 +10,8 @@ export interface BackfillOpts {
|
|
|
32
10
|
token: string;
|
|
33
11
|
/** Optional cap on items per stream. Useful for tests. */
|
|
34
12
|
maxPerStream?: number;
|
|
13
|
+
/** First-run `--since`; seeds all three HWMs, COALESCE keeps any HWM a stream already saved. */
|
|
14
|
+
sinceIso?: string;
|
|
35
15
|
/** sleep ms — injectable so tests don't actually wait. */
|
|
36
16
|
sleepMs?: (ms: number) => Promise<void>;
|
|
37
17
|
}
|
|
@@ -1,38 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
* - /repos/{repo}/issues/comments -> issue_comments_hwm
|
|
6
|
-
* - /repos/{repo}/pulls/comments -> pr_review_comments_hwm
|
|
7
|
-
*
|
|
8
|
-
* Crash safety: each stream's HWM is persisted ONLY after
|
|
9
|
-
* the stream fully drains. If stream 2 throws mid-flight, stream 1's HWM
|
|
10
|
-
* is committed and stream 2's stays NULL (or its prior value). Rerun
|
|
11
|
-
* picks up from stream 1's saved HWM and re-fetches stream 2 from its
|
|
12
|
-
* last committed point.
|
|
13
|
-
*
|
|
14
|
-
* The /issues endpoint returns BOTH issues and PRs (a PR is
|
|
15
|
-
* an issue with a `pull_request` field). We skip PRs here so they don't
|
|
16
|
-
* get ingested under the issues schema. PRs are handled via webhook in
|
|
17
|
-
* V1 (no /pulls backfill stream — review comments cover the discussion
|
|
18
|
-
* surface).
|
|
19
|
-
*
|
|
20
|
-
* Privacy (V1 limitation): the REST list endpoints don't reliably set
|
|
21
|
-
* `repository.private`, and resolving it requires an extra API call per
|
|
22
|
-
* repo. Backfill leaves the field undefined so scopeFromRepository falls
|
|
23
|
-
* through to private. Callers who know the repo is public can re-tag
|
|
24
|
-
* downstream; the fail-safe default protects private orgs.
|
|
25
|
-
*/
|
|
26
|
-
import { readCursors, writeHwm } from '../../store/connectors/github.js';
|
|
1
|
+
/** Paginated backfill of the GitHub issues, issue-comments and PR-review-comments streams, each with its own high-water mark (HWM).
|
|
2
|
+
* An HWM is persisted only after its stream fully drains, so a crash in stream 2 leaves stream 1 committed and stream 2 resumes from its prior HWM.
|
|
3
|
+
* `repository.private` is left undefined (REST lists omit it), so scopeFromRepository falls through to private. */
|
|
4
|
+
import { readCursors, seedCursors, writeHwm } from '../../store/connectors/github.js';
|
|
27
5
|
import { ingestEvent } from './ingest.js';
|
|
28
6
|
import { isJsonObject } from '../../util/json.js';
|
|
29
7
|
const API = 'https://api.github.com';
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
* REST list endpoints often omit the full repository object on each item;
|
|
33
|
-
* we already know the repo since the caller passed it. `private` left
|
|
34
|
-
* undefined so scopeFromRepository falls through to private.
|
|
35
|
-
*/
|
|
8
|
+
/** Build a synthetic `repository` from the known repo full name, because REST list items often omit it.
|
|
9
|
+
* `private` stays undefined so scopeFromRepository falls through to private. */
|
|
36
10
|
function syntheticRepository(repoFullName) {
|
|
37
11
|
const [owner, name] = repoFullName.split('/');
|
|
38
12
|
return {
|
|
@@ -42,11 +16,7 @@ function syntheticRepository(repoFullName) {
|
|
|
42
16
|
// private intentionally omitted — fail-safe to private scope.
|
|
43
17
|
};
|
|
44
18
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Parse the trailing issue/PR number from a REST API URL.
|
|
47
|
-
* e.g. https://api.github.com/repos/o/r/issues/42 -> 42
|
|
48
|
-
* https://api.github.com/repos/o/r/pulls/7 -> 7
|
|
49
|
-
*/
|
|
19
|
+
/** Parse the trailing issue/PR number from a REST API URL, e.g. .../issues/42 -> 42. */
|
|
50
20
|
function parseTrailingNumber(url) {
|
|
51
21
|
if (!url)
|
|
52
22
|
return null;
|
|
@@ -86,9 +56,7 @@ async function drainStream(ctx, url0, options) {
|
|
|
86
56
|
pages++;
|
|
87
57
|
for (const item of page.items) {
|
|
88
58
|
// Track updated_at on EVERY item, before the toIngestEvent filter, so PR-only pages don't loop forever.
|
|
89
|
-
// SAFETY: updated_at is GitHub's ISO-timestamp field on every item
|
|
90
|
-
// shape this stream returns; a non-string value would only fail the
|
|
91
|
-
// string comparisons below, matching pre-migration passthrough.
|
|
59
|
+
// SAFETY: updated_at is GitHub's ISO-timestamp field on every item shape this stream returns.
|
|
92
60
|
const updatedAt = isJsonObject(item)
|
|
93
61
|
? (item.updated_at ?? null)
|
|
94
62
|
: null;
|
|
@@ -114,14 +82,23 @@ async function drainStream(ctx, url0, options) {
|
|
|
114
82
|
}
|
|
115
83
|
return { ingested, pages, maxUpdatedAt, drained: true };
|
|
116
84
|
}
|
|
85
|
+
// A reset hours away must fail the run for a later rerun; sleeping through it would hold the process for the whole window.
|
|
86
|
+
const MAX_RATE_LIMIT_ATTEMPTS = 5;
|
|
87
|
+
const MAX_RATE_LIMIT_WAIT_MS = 10 * 60 * 1000;
|
|
117
88
|
async function fetchPagePastRateLimit(options, url) {
|
|
118
89
|
const { fetcher, token, sleep } = options;
|
|
119
|
-
|
|
120
|
-
|
|
90
|
+
let waitedMs = 0;
|
|
91
|
+
for (let attempt = 1;; attempt++) {
|
|
121
92
|
const page = await fetcher({ url, token });
|
|
122
93
|
if (page.rateLimit.reason === 'none')
|
|
123
94
|
return page;
|
|
124
|
-
|
|
95
|
+
const waitMs = page.rateLimit.sleepSeconds * 1000;
|
|
96
|
+
if (attempt >= MAX_RATE_LIMIT_ATTEMPTS || waitedMs + waitMs > MAX_RATE_LIMIT_WAIT_MS) {
|
|
97
|
+
const resetAt = new Date(Date.now() + waitMs).toISOString();
|
|
98
|
+
throw new Error(`GitHub rate limit still active after ${attempt} attempts and ${Math.round(waitedMs / 1000)}s waited; resets at ${resetAt}`);
|
|
99
|
+
}
|
|
100
|
+
await sleep(waitMs);
|
|
101
|
+
waitedMs += waitMs;
|
|
125
102
|
}
|
|
126
103
|
}
|
|
127
104
|
function issueItemToEvent(item, repository) {
|
|
@@ -146,9 +123,8 @@ function issueItemToEvent(item, repository) {
|
|
|
146
123
|
function issueCommentItemToEvent(item, repository) {
|
|
147
124
|
if (!isCommentItem(item))
|
|
148
125
|
return null;
|
|
149
|
-
// SAFETY: this closure only runs against the /issues/comments stream,
|
|
150
|
-
//
|
|
151
|
-
// IssueCommentItem; a missing issue_url is handled defensively below.
|
|
126
|
+
// SAFETY: this closure only runs against the /issues/comments stream, so every item isCommentItem
|
|
127
|
+
// validates is an IssueCommentItem; a missing issue_url is handled below.
|
|
152
128
|
const c = item;
|
|
153
129
|
const issueNumber = parseTrailingNumber(c.issue_url);
|
|
154
130
|
if (issueNumber === null)
|
|
@@ -169,9 +145,8 @@ function issueCommentItemToEvent(item, repository) {
|
|
|
169
145
|
function prReviewCommentItemToEvent(item, repository) {
|
|
170
146
|
if (!isCommentItem(item))
|
|
171
147
|
return null;
|
|
172
|
-
// SAFETY: this closure only runs against the /pulls/comments stream,
|
|
173
|
-
//
|
|
174
|
-
// PrReviewCommentItem; a missing pull_request_url is handled below.
|
|
148
|
+
// SAFETY: this closure only runs against the /pulls/comments stream, so every item isCommentItem
|
|
149
|
+
// validates is a PrReviewCommentItem; a missing pull_request_url is handled below.
|
|
175
150
|
const c = item;
|
|
176
151
|
const prNumber = parseTrailingNumber(c.pull_request_url);
|
|
177
152
|
if (prNumber === null)
|
|
@@ -206,13 +181,14 @@ async function backfillStream(ctx, opts, sleep, stream) {
|
|
|
206
181
|
}
|
|
207
182
|
export async function backfillRepo(ctx, opts) {
|
|
208
183
|
const sleep = opts.sleepMs ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
184
|
+
if (opts.sinceIso)
|
|
185
|
+
seedCursors(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, opts.sinceIso);
|
|
209
186
|
const cursors = readCursors(ctx.hippoRoot, ctx.tenantId, opts.repoFullName);
|
|
210
187
|
const repository = syntheticRepository(opts.repoFullName);
|
|
211
188
|
const result = {
|
|
212
189
|
ingested: { issues: 0, issueComments: 0, prReviewComments: 0 },
|
|
213
190
|
pages: { issues: 0, issueComments: 0, prReviewComments: 0 },
|
|
214
191
|
};
|
|
215
|
-
// ---------- Stream 1: issues (skip PRs) ----------
|
|
216
192
|
const issuesRes = await backfillStream(ctx, opts, sleep, {
|
|
217
193
|
url: `${API}/repos/${opts.repoFullName}/issues?state=all&per_page=100` +
|
|
218
194
|
(cursors.issues ? `&since=${encodeURIComponent(cursors.issues)}` : ''),
|
|
@@ -221,7 +197,6 @@ export async function backfillRepo(ctx, opts) {
|
|
|
221
197
|
});
|
|
222
198
|
result.ingested.issues = issuesRes.ingested;
|
|
223
199
|
result.pages.issues = issuesRes.pages;
|
|
224
|
-
// ---------- Stream 2: repo-level issue comments ----------
|
|
225
200
|
const commentsRes = await backfillStream(ctx, opts, sleep, {
|
|
226
201
|
url: `${API}/repos/${opts.repoFullName}/issues/comments?per_page=100` +
|
|
227
202
|
(cursors.issueComments ? `&since=${encodeURIComponent(cursors.issueComments)}` : ''),
|
|
@@ -230,7 +205,6 @@ export async function backfillRepo(ctx, opts) {
|
|
|
230
205
|
});
|
|
231
206
|
result.ingested.issueComments = commentsRes.ingested;
|
|
232
207
|
result.pages.issueComments = commentsRes.pages;
|
|
233
|
-
// ---------- Stream 3: repo-level PR review comments ----------
|
|
234
208
|
const prCommentsRes = await backfillStream(ctx, opts, sleep, {
|
|
235
209
|
url: `${API}/repos/${opts.repoFullName}/pulls/comments?per_page=100` +
|
|
236
210
|
(cursors.prReviewComments ? `&since=${encodeURIComponent(cursors.prReviewComments)}` : ''),
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { type Context } from '../../api/index.js';
|
|
2
2
|
export interface DeletionInput {
|
|
3
|
-
/** artifact_ref of the comment, e.g
|
|
4
|
-
* 'github://acme/repo/
|
|
5
|
-
* 'github://acme/repo/pull/7/review_comment/456'. */
|
|
3
|
+
/** artifact_ref of the comment, e.g. 'github://acme/repo/issue/42/comment/123'
|
|
4
|
+
* or 'github://acme/repo/pull/7/review_comment/456'. */
|
|
6
5
|
artifactRef: string;
|
|
7
6
|
/** Source idempotency key for this delete event (sha256 of artifact_ref + ':' + updated_at). */
|
|
8
7
|
idempotencyKey: string;
|
|
@@ -16,20 +15,7 @@ export interface DeletionResult {
|
|
|
16
15
|
status: DeletionStatus;
|
|
17
16
|
archivedCount: number;
|
|
18
17
|
}
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* Filter by tenant_id + kind='raw'. Multi-row archive:
|
|
23
|
-
* GitHub edits keep the same artifact_ref, so multiple active raw rows can
|
|
24
|
-
* match a single deletion event. Archive ALL of them.
|
|
25
|
-
*
|
|
26
|
-
* The store runs ALL archives + the idempotency mark as one write: a per-row
|
|
27
|
-
* failure rolls back the whole batch, idempotency included, so a retry
|
|
28
|
-
* re-attempts cleanly instead of leaving searchable survivors.
|
|
29
|
-
*
|
|
30
|
-
* Tenant scope and kind='raw' filtering are load-bearing: without them a
|
|
31
|
-
* deletion event from tenant A could archive tenant B's row sharing the same
|
|
32
|
-
* artifact_ref, or accidentally target a distilled row.
|
|
33
|
-
*/
|
|
18
|
+
/** Handle `issue_comment.deleted` and `pull_request_review_comment.deleted`: archive ALL active raw rows for the artifact_ref in one write.
|
|
19
|
+
* Tenant and kind='raw' filtering are load-bearing: without them a deletion could archive another tenant's row or a distilled row. */
|
|
34
20
|
export declare function handleCommentDeleted(ctx: Context, input: DeletionInput): Promise<DeletionResult>;
|
|
35
21
|
//# sourceMappingURL=deletion.d.ts.map
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import { requireGroup, storeFor } from '../../store/index.js';
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Filter by tenant_id + kind='raw'. Multi-row archive:
|
|
6
|
-
* GitHub edits keep the same artifact_ref, so multiple active raw rows can
|
|
7
|
-
* match a single deletion event. Archive ALL of them.
|
|
8
|
-
*
|
|
9
|
-
* The store runs ALL archives + the idempotency mark as one write: a per-row
|
|
10
|
-
* failure rolls back the whole batch, idempotency included, so a retry
|
|
11
|
-
* re-attempts cleanly instead of leaving searchable survivors.
|
|
12
|
-
*
|
|
13
|
-
* Tenant scope and kind='raw' filtering are load-bearing: without them a
|
|
14
|
-
* deletion event from tenant A could archive tenant B's row sharing the same
|
|
15
|
-
* artifact_ref, or accidentally target a distilled row.
|
|
16
|
-
*/
|
|
2
|
+
/** Handle `issue_comment.deleted` and `pull_request_review_comment.deleted`: archive ALL active raw rows for the artifact_ref in one write.
|
|
3
|
+
* Tenant and kind='raw' filtering are load-bearing: without them a deletion could archive another tenant's row or a distilled row. */
|
|
17
4
|
export async function handleCommentDeleted(ctx, input) {
|
|
18
5
|
const { artifactRef, idempotencyKey, deliveryId, eventName } = input;
|
|
19
6
|
const done = await requireGroup(storeFor(ctx), 'connectorEvents').archiveDeletedArtifact({
|
|
@@ -1,32 +1,20 @@
|
|
|
1
1
|
import type { Context } from '../../api/index.js';
|
|
2
|
-
import { type DlqBucket, type DlqItem, type
|
|
2
|
+
import { type DlqBucket, type DlqItem, type GitHubDlqInsert } from '../../store/connectors/github.js';
|
|
3
3
|
import { type ConnectorDlq, type ReplayResult } from '../dlq.js';
|
|
4
4
|
export type { DlqBucket, DlqItem };
|
|
5
|
-
type
|
|
5
|
+
type GitHubOwnColumns = Pick<GitHubDlqInsert, 'eventName' | 'deliveryId' | 'installationId' | 'repoFullName'>;
|
|
6
6
|
/** GitHub's dead-letter table; the event, delivery, installation and repo columns let an operator triage a row without re-reading the payload. */
|
|
7
|
-
export declare const githubDlq: ConnectorDlq<
|
|
7
|
+
export declare const githubDlq: ConnectorDlq<GitHubOwnColumns, DlqBucket, DlqItem>;
|
|
8
8
|
export interface ReplayDlqOpts {
|
|
9
9
|
/** Current webhook secret. If omitted, signature check is skipped (force-only path). */
|
|
10
10
|
webhookSecret?: string;
|
|
11
|
-
/**
|
|
12
|
-
* Previous webhook secret during rotation.
|
|
13
|
-
* Operators rotating GITHUB_WEBHOOK_SECRET would otherwise be forced into
|
|
14
|
-
* --force on DLQ rows written under the old secret. Plumbed through to
|
|
15
|
-
* verifyGitHubSignature.previousSecret.
|
|
16
|
-
*/
|
|
11
|
+
/** Previous webhook secret during rotation, passed to verifyGitHubSignature.previousSecret so old-secret DLQ rows need no --force. */
|
|
17
12
|
previousSecret?: string;
|
|
18
13
|
/** When true, skip signature verification (used for legacy entries after secret rotation). */
|
|
19
14
|
force?: boolean;
|
|
20
15
|
}
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
* the dispatch keeps this module free of every event-type handler — the
|
|
24
|
-
* route already knows how to route an envelope, so it passes that capability
|
|
25
|
-
* back in.
|
|
26
|
-
*
|
|
27
|
-
* No `idempotencyKey` field: ingest re-derives the key from the parsed event,
|
|
28
|
-
* so a hook trusting a passed-in key would dedupe against a stale one.
|
|
29
|
-
*/
|
|
16
|
+
/** Hook the webhook route injects to re-ingest a row, which keeps this module free of every event-type handler.
|
|
17
|
+
* No `idempotencyKey` field: ingest re-derives it from the parsed event, and a passed-in key could be stale. */
|
|
30
18
|
export type IngestHook = (ctx: Context, args: {
|
|
31
19
|
rawPayload: string;
|
|
32
20
|
eventName: string;
|
|
@@ -34,21 +22,8 @@ export type IngestHook = (ctx: Context, args: {
|
|
|
34
22
|
}) => Promise<{
|
|
35
23
|
memoryId: string | null;
|
|
36
24
|
}>;
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
39
|
-
* 1. Fetch row by id. Not found → `not_found`.
|
|
40
|
-
* 2. If !force and webhookSecret provided, verify signature with the
|
|
41
|
-
* current secret. Fail → bump retry_count, `sig_fail`.
|
|
42
|
-
* Missing signature on the row → `sig_missing` (no bump; --force required).
|
|
43
|
-
* 3. JSON.parse the raw payload. Fail → bump, `parse_error`.
|
|
44
|
-
* 4. Type-guard the envelope. Fail → bump, `unhandled`.
|
|
45
|
-
* 5. If an `ingestHook` is supplied, call it and return its memoryId.
|
|
46
|
-
* If not (dry-run path), bump retry_count and return status `replayed`
|
|
47
|
-
* with memoryId=null. The webhook route wires the real hook.
|
|
48
|
-
*
|
|
49
|
-
* Mirrors Slack's "always use current routing" policy: replays use the
|
|
50
|
-
* deployment state NOW, not at the time of original DLQing.
|
|
51
|
-
*/
|
|
25
|
+
/** Replay a DLQ row through the normal ingest path; a failed signature, parse or envelope check bumps retry_count.
|
|
26
|
+
* Without an `ingestHook` (dry-run) it bumps retry_count and returns `replayed` with memoryId=null; replays use today's routing, not the original's. */
|
|
52
27
|
export declare function replayDlqEntry(ctx: Context, id: number, opts?: ReplayDlqOpts & {
|
|
53
28
|
ingestHook?: IngestHook;
|
|
54
29
|
}): Promise<ReplayResult>;
|
|
@@ -1,105 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { githubDlqEntry, markGitHubDlqRetried, listGitHubDlq, } from '../../store/connectors/github.js';
|
|
2
|
+
import { replayParked } from '../dlq.js';
|
|
3
3
|
import { verifyGitHubSignature } from './signature.js';
|
|
4
4
|
import { isGitHubWebhookEnvelope } from './types.js';
|
|
5
5
|
/** GitHub's dead-letter table; the event, delivery, installation and repo columns let an operator triage a row without re-reading the payload. */
|
|
6
6
|
export const githubDlq = {
|
|
7
7
|
letter: (row) => ({ connector: 'github', ...row }),
|
|
8
|
-
list:
|
|
8
|
+
list: listGitHubDlq,
|
|
9
|
+
entry: githubDlqEntry,
|
|
10
|
+
bump: markGitHubDlqRetried,
|
|
9
11
|
};
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* 1. Fetch row by id. Not found → `not_found`.
|
|
13
|
-
* 2. If !force and webhookSecret provided, verify signature with the
|
|
14
|
-
* current secret. Fail → bump retry_count, `sig_fail`.
|
|
15
|
-
* Missing signature on the row → `sig_missing` (no bump; --force required).
|
|
16
|
-
* 3. JSON.parse the raw payload. Fail → bump, `parse_error`.
|
|
17
|
-
* 4. Type-guard the envelope. Fail → bump, `unhandled`.
|
|
18
|
-
* 5. If an `ingestHook` is supplied, call it and return its memoryId.
|
|
19
|
-
* If not (dry-run path), bump retry_count and return status `replayed`
|
|
20
|
-
* with memoryId=null. The webhook route wires the real hook.
|
|
21
|
-
*
|
|
22
|
-
* Mirrors Slack's "always use current routing" policy: replays use the
|
|
23
|
-
* deployment state NOW, not at the time of original DLQing.
|
|
24
|
-
*/
|
|
12
|
+
/** Replay a DLQ row through the normal ingest path; a failed signature, parse or envelope check bumps retry_count.
|
|
13
|
+
* Without an `ingestHook` (dry-run) it bumps retry_count and returns `replayed` with memoryId=null; replays use today's routing, not the original's. */
|
|
25
14
|
export async function replayDlqEntry(ctx, id, opts = {}) {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
ok: true,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
retryCount: row.retryCount + 1,
|
|
46
|
-
reason: 'dry-run: no ingest hook supplied',
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
// Real replay path. The route's IngestHook is responsible for routing,
|
|
50
|
-
// idempotency, and writing the memory. The DLQ module only validates the
|
|
51
|
-
// surface and bumps the retry counter.
|
|
52
|
-
// No idempotencyKey arg: the hook re-derives it from the parsed event (artifact_ref + updated_at).
|
|
53
|
-
const eventName = row.eventName ?? '';
|
|
54
|
-
const deliveryId = row.deliveryId ?? '';
|
|
55
|
-
const { memoryId } = await opts.ingestHook(ctx, {
|
|
56
|
-
rawPayload: row.rawPayload,
|
|
57
|
-
eventName,
|
|
58
|
-
deliveryId,
|
|
59
|
-
});
|
|
60
|
-
bumpDlqRetry(ctx.hippoRoot, id);
|
|
61
|
-
return {
|
|
62
|
-
ok: true,
|
|
63
|
-
status: 'replayed',
|
|
64
|
-
memoryId,
|
|
65
|
-
retryCount: row.retryCount + 1,
|
|
66
|
-
};
|
|
15
|
+
const { webhookSecret, previousSecret, ingestHook } = opts;
|
|
16
|
+
return replayParked({
|
|
17
|
+
dlq: githubDlq,
|
|
18
|
+
// The secret in effect now, not the one in effect when the row was parked.
|
|
19
|
+
refuseSignature: (row) => (webhookSecret ? refuseSignature(row, webhookSecret, previousSecret) : null),
|
|
20
|
+
isEnvelope: isGitHubWebhookEnvelope,
|
|
21
|
+
notEnvelope: 'not a GitHub webhook envelope',
|
|
22
|
+
reingest: async (row) => {
|
|
23
|
+
if (!ingestHook)
|
|
24
|
+
return { ok: true, status: 'replayed', memoryId: null, reason: 'dry-run: no ingest hook supplied' };
|
|
25
|
+
// The hook owns routing, idempotency and the memory write, and re-derives the key from the parsed event.
|
|
26
|
+
const { memoryId } = await ingestHook(ctx, {
|
|
27
|
+
rawPayload: row.rawPayload,
|
|
28
|
+
eventName: row.eventName ?? '',
|
|
29
|
+
deliveryId: row.deliveryId ?? '',
|
|
30
|
+
});
|
|
31
|
+
return { ok: true, status: 'replayed', memoryId };
|
|
32
|
+
},
|
|
33
|
+
}, ctx.hippoRoot, id, opts.force === true);
|
|
67
34
|
}
|
|
68
|
-
|
|
69
|
-
function checkReplaySignature(hippoRoot, id, row, webhookSecret, previousSecret) {
|
|
35
|
+
function refuseSignature(row, webhookSecret, previousSecret) {
|
|
70
36
|
if (!row.signature) {
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
const sigOk = verifyGitHubSignature({
|
|
74
|
-
rawBody: row.rawPayload,
|
|
75
|
-
signature: row.signature,
|
|
76
|
-
webhookSecret,
|
|
77
|
-
previousSecret,
|
|
78
|
-
});
|
|
79
|
-
if (!sigOk) {
|
|
80
|
-
bumpDlqRetry(hippoRoot, id);
|
|
81
|
-
return replayFailed('sig_fail', row.retryCount + 1, 'signature did not verify against current GITHUB_WEBHOOK_SECRET; pass --force to replay anyway');
|
|
37
|
+
return { status: 'sig_missing', reason: 'row has no signature (legacy, or redacted before storing); pass --force to replay' };
|
|
82
38
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
parsed = JSON.parse(row.rawPayload);
|
|
90
|
-
}
|
|
91
|
-
catch (e) {
|
|
92
|
-
bumpDlqRetry(hippoRoot, id);
|
|
93
|
-
// SAFETY: this is a best-effort error message only; property access on
|
|
94
|
-
// any JS value is safe (undefined if absent), preserving the existing
|
|
95
|
-
// lenient formatting even when something non-Error was thrown.
|
|
96
|
-
const message = e.message;
|
|
97
|
-
return replayFailed('parse_error', row.retryCount + 1, `still unparseable: ${message}`);
|
|
98
|
-
}
|
|
99
|
-
if (!isGitHubWebhookEnvelope(parsed)) {
|
|
100
|
-
bumpDlqRetry(hippoRoot, id);
|
|
101
|
-
return replayFailed('unhandled', row.retryCount + 1, 'not a GitHub webhook envelope');
|
|
102
|
-
}
|
|
103
|
-
return null;
|
|
39
|
+
if (verifyGitHubSignature({ rawBody: row.rawPayload, signature: row.signature, webhookSecret, previousSecret }))
|
|
40
|
+
return null;
|
|
41
|
+
return {
|
|
42
|
+
status: 'sig_fail',
|
|
43
|
+
reason: 'signature did not verify against current GITHUB_WEBHOOK_SECRET; pass --force to replay anyway',
|
|
44
|
+
};
|
|
104
45
|
}
|
|
105
46
|
//# sourceMappingURL=dlq.js.map
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Context } from '../../api/index.js';
|
|
2
|
+
import { type IngestResult } from '../ingest.js';
|
|
2
3
|
import type { GitHubIssueEvent, GitHubIssueCommentEvent, GitHubPullRequestEvent, GitHubPullRequestReviewCommentEvent } from './types.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
status: IngestStatus;
|
|
6
|
-
memoryId: string | null;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Discriminated union of the four event shapes V1 ingests. The eventName
|
|
10
|
-
* field MUST equal the X-GitHub-Event header value; computeIdempotencyKey
|
|
11
|
-
* folds it into the dedupe key so the same body posted under two different
|
|
12
|
-
* X-GitHub-Event headers produces two distinct keys (test 7).
|
|
13
|
-
*/
|
|
4
|
+
/** Discriminated union of the four event shapes V1 ingests; eventName MUST equal the X-GitHub-Event header,
|
|
5
|
+
* since computeIdempotencyKey folds it into the dedupe key. */
|
|
14
6
|
export type IngestEvent = {
|
|
15
7
|
eventName: 'issues';
|
|
16
8
|
payload: GitHubIssueEvent;
|