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
|
@@ -9,14 +9,8 @@ export type SlackHistoryFetcher = (args: {
|
|
|
9
9
|
channelId: string;
|
|
10
10
|
/** Slack's opaque pagination token. Null on first page of a backfill run. */
|
|
11
11
|
cursor: string | null;
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* `slack_cursors.latest_ts` on the FIRST page of a rerun; unused on
|
|
15
|
-
* subsequent pages within one run (where `cursor` carries us forward).
|
|
16
|
-
* Distinct from `cursor` because Slack treats `cursor` as opaque token
|
|
17
|
-
* and `oldest` as a numeric ts — feeding `latest_ts` as `cursor` breaks
|
|
18
|
-
* against the live API even though it round-trips through test fetchers.
|
|
19
|
-
*/
|
|
12
|
+
/** Incremental-resume bound: skip messages with ts <= oldest, set from `slack_cursors.latest_ts` on the first page only.
|
|
13
|
+
* Kept apart from `cursor` because Slack treats `cursor` as an opaque token, so feeding latest_ts as cursor fails on the live API. */
|
|
20
14
|
oldest?: string;
|
|
21
15
|
}) => Promise<SlackHistoryPage>;
|
|
22
16
|
export interface BackfillOpts {
|
|
@@ -26,15 +20,8 @@ export interface BackfillOpts {
|
|
|
26
20
|
/** Stop after this many messages. Default: unlimited. */
|
|
27
21
|
maxMessages?: number;
|
|
28
22
|
}
|
|
29
|
-
/**
|
|
30
|
-
*
|
|
31
|
-
* message. The cursor is persisted to `slack_cursors` after every page so a
|
|
32
|
-
* crash mid-backfill resumes near where it left off.
|
|
33
|
-
*
|
|
34
|
-
* Each ingested message uses a synthesized eventId of the form
|
|
35
|
-
* `backfill:${teamId}:${channelId}:${ts}`. Reruns dedupe via the
|
|
36
|
-
* `slack_event_log` PK so calling `backfillChannel` twice is safe.
|
|
37
|
-
*/
|
|
23
|
+
/** Page through `conversations.history` and ingest each message, persisting the cursor to `slack_cursors` after every page.
|
|
24
|
+
* The synthesized eventId `backfill:${teamId}:${channelId}:${ts}` makes reruns dedupe via the `slack_event_log` PK. */
|
|
38
25
|
export declare function backfillChannel(ctx: Context, opts: BackfillOpts): Promise<{
|
|
39
26
|
ingested: number;
|
|
40
27
|
pages: number;
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import { saveSlackCursor, slackCursor } from '../../store/connectors/slack.js';
|
|
2
2
|
import { ingestMessage } from './ingest.js';
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* message. The cursor is persisted to `slack_cursors` after every page so a
|
|
6
|
-
* crash mid-backfill resumes near where it left off.
|
|
7
|
-
*
|
|
8
|
-
* Each ingested message uses a synthesized eventId of the form
|
|
9
|
-
* `backfill:${teamId}:${channelId}:${ts}`. Reruns dedupe via the
|
|
10
|
-
* `slack_event_log` PK so calling `backfillChannel` twice is safe.
|
|
11
|
-
*/
|
|
3
|
+
/** Page through `conversations.history` and ingest each message, persisting the cursor to `slack_cursors` after every page.
|
|
4
|
+
* The synthesized eventId `backfill:${teamId}:${channelId}:${ts}` makes reruns dedupe via the `slack_event_log` PK. */
|
|
12
5
|
export async function backfillChannel(ctx, opts) {
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
// and we feed it back. Mixing the two would feed a numeric ts as an opaque
|
|
16
|
-
// cursor and break against the live API on rerun.
|
|
6
|
+
// `oldest` (numeric ts) is the resume bound for the first page only; `cursor` starts null and Slack mints the next-page token.
|
|
7
|
+
// Mixing the two would feed a numeric ts as an opaque cursor and break on rerun.
|
|
17
8
|
const resumeFrom = slackCursor(ctx.hippoRoot, ctx.tenantId, opts.channel.id);
|
|
18
9
|
let cursor = null;
|
|
19
10
|
let ingested = 0;
|
|
@@ -14,24 +14,7 @@ export interface ReplayDlqOpts {
|
|
|
14
14
|
/** Skew window override for tests. */
|
|
15
15
|
skewSeconds?: number;
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* replay <id> [--force]`.
|
|
20
|
-
*
|
|
21
|
-
* Behavior:
|
|
22
|
-
* 1. SELECT the row.
|
|
23
|
-
* 2. If signature + slack_timestamp are present and `signingSecret` is set,
|
|
24
|
-
* re-verify with the CURRENT secret (not previous). Failure → bail unless
|
|
25
|
-
* --force. Legacy rows from before v19 may have NULL signature; those
|
|
26
|
-
* require --force to replay safely.
|
|
27
|
-
* 3. Re-parse the raw_payload and dispatch to ingestMessage / handleMessageDeleted.
|
|
28
|
-
* 4. On success: mark retried_at, increment retry_count.
|
|
29
|
-
* 5. On failure: increment retry_count only, leave the row.
|
|
30
|
-
*
|
|
31
|
-
* The replay always uses the routing the deployment has NOW (current
|
|
32
|
-
* slack_workspaces table + env), not whatever was in effect when the original
|
|
33
|
-
* envelope was DLQed. That is intentional: the DLQ exists to be drained after
|
|
34
|
-
* the operator fixed the routing.
|
|
35
|
-
*/
|
|
17
|
+
/** Replay a DLQ row via the normal ingest path (`hippo slack dlq replay <id> [--force]`), re-verifying the signature with the CURRENT secret unless forced.
|
|
18
|
+
* Rows with a NULL signature need --force; replays use today's routing, because the DLQ exists to be drained after the operator fixed routing. */
|
|
36
19
|
export declare function replayDlqEntry(ctx: Pick<Context, 'hippoRoot'>, id: number, opts?: ReplayDlqOpts): Promise<ReplayResult>;
|
|
37
20
|
//# sourceMappingURL=dlq.d.ts.map
|
|
@@ -1,113 +1,75 @@
|
|
|
1
1
|
import { adminActor } from '../../api/index.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { listSlackDlq, markSlackDlqRetried, slackDlqEntry, } from '../../store/connectors/slack.js';
|
|
3
|
+
import { replayParked } from '../dlq.js';
|
|
4
4
|
import { ingestMessage } from './ingest.js';
|
|
5
5
|
import { resolveTenantForSlackTeam } from './tenant-routing.js';
|
|
6
6
|
import { verifySlackSignature } from './signature.js';
|
|
7
7
|
import { isSlackEventEnvelope, isSlackMessageEvent } from './types.js';
|
|
8
8
|
import { handleMessageDeleted } from './deletion.js';
|
|
9
|
-
import {
|
|
9
|
+
import { YEAR_S } from '../../util/time.js';
|
|
10
10
|
/** Slack's dead-letter table; `teamId` and `slackTimestamp` are the columns only it has. */
|
|
11
11
|
export const slackDlq = {
|
|
12
12
|
letter: (row) => ({ connector: 'slack', ...row }),
|
|
13
13
|
list: listSlackDlq,
|
|
14
|
+
entry: slackDlqEntry,
|
|
15
|
+
bump: markSlackDlqRetried,
|
|
14
16
|
};
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* replay <id> [--force]`.
|
|
18
|
-
*
|
|
19
|
-
* Behavior:
|
|
20
|
-
* 1. SELECT the row.
|
|
21
|
-
* 2. If signature + slack_timestamp are present and `signingSecret` is set,
|
|
22
|
-
* re-verify with the CURRENT secret (not previous). Failure → bail unless
|
|
23
|
-
* --force. Legacy rows from before v19 may have NULL signature; those
|
|
24
|
-
* require --force to replay safely.
|
|
25
|
-
* 3. Re-parse the raw_payload and dispatch to ingestMessage / handleMessageDeleted.
|
|
26
|
-
* 4. On success: mark retried_at, increment retry_count.
|
|
27
|
-
* 5. On failure: increment retry_count only, leave the row.
|
|
28
|
-
*
|
|
29
|
-
* The replay always uses the routing the deployment has NOW (current
|
|
30
|
-
* slack_workspaces table + env), not whatever was in effect when the original
|
|
31
|
-
* envelope was DLQed. That is intentional: the DLQ exists to be drained after
|
|
32
|
-
* the operator fixed the routing.
|
|
33
|
-
*/
|
|
17
|
+
/** Replay a DLQ row via the normal ingest path (`hippo slack dlq replay <id> [--force]`), re-verifying the signature with the CURRENT secret unless forced.
|
|
18
|
+
* Rows with a NULL signature need --force; replays use today's routing, because the DLQ exists to be drained after the operator fixed routing. */
|
|
34
19
|
export async function replayDlqEntry(ctx, id, opts = {}) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return sigFailure;
|
|
43
|
-
}
|
|
44
|
-
// Parse + dispatch.
|
|
45
|
-
let parsed;
|
|
46
|
-
try {
|
|
47
|
-
parsed = JSON.parse(row.rawPayload);
|
|
48
|
-
}
|
|
49
|
-
catch (e) {
|
|
50
|
-
return failAndBump(ctx.hippoRoot, row, 'parse_error', `still unparseable: ${errorMessage(e)}`);
|
|
51
|
-
}
|
|
52
|
-
if (!isSlackEventEnvelope(parsed)) {
|
|
53
|
-
return failAndBump(ctx.hippoRoot, row, 'unhandled', 'not an event_callback envelope');
|
|
54
|
-
}
|
|
55
|
-
// Resolve tenant against current state. If still unroutable, bail.
|
|
56
|
-
const tenant = await resolveTenantForSlackTeam(ctx.hippoRoot, parsed.team_id);
|
|
57
|
-
if (!tenant) {
|
|
58
|
-
return failAndBump(ctx.hippoRoot, row, 'unroutable', `team_id ${parsed.team_id} still unroutable`);
|
|
59
|
-
}
|
|
60
|
-
const replayCtx = {
|
|
61
|
-
hippoRoot: ctx.hippoRoot,
|
|
62
|
-
tenantId: tenant,
|
|
63
|
-
actor: adminActor('connector:slack:replay'),
|
|
64
|
-
};
|
|
65
|
-
return dispatchReplay(replayCtx, row, parsed);
|
|
20
|
+
return replayParked({
|
|
21
|
+
dlq: slackDlq,
|
|
22
|
+
refuseSignature: (row) => refuseSignature(row, opts),
|
|
23
|
+
isEnvelope: isSlackEventEnvelope,
|
|
24
|
+
notEnvelope: 'not an event_callback envelope',
|
|
25
|
+
reingest: (_row, envelope) => reingest(ctx.hippoRoot, envelope),
|
|
26
|
+
}, ctx.hippoRoot, id, opts.force === true);
|
|
66
27
|
}
|
|
67
|
-
/**
|
|
68
|
-
function
|
|
28
|
+
/** A missing signature or timestamp refuses even without a secret; a mismatch needs the current secret to show. */
|
|
29
|
+
function refuseSignature(row, opts) {
|
|
69
30
|
if (!row.signature || !row.slackTimestamp) {
|
|
70
|
-
return
|
|
31
|
+
return {
|
|
32
|
+
status: 'sig_missing',
|
|
33
|
+
reason: 'row has no signature/timestamp (legacy, or redacted before storing); pass --force to replay',
|
|
34
|
+
};
|
|
71
35
|
}
|
|
72
|
-
if (opts.signingSecret)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
bumpSlackDlqRetryCount(hippoRoot, row.id);
|
|
90
|
-
return replayFailed(status, row.retryCount + 1, reason);
|
|
36
|
+
if (!opts.signingSecret)
|
|
37
|
+
return null;
|
|
38
|
+
const ok = verifySlackSignature({
|
|
39
|
+
rawBody: row.rawPayload,
|
|
40
|
+
signature: row.signature,
|
|
41
|
+
timestamp: row.slackTimestamp,
|
|
42
|
+
signingSecret: opts.signingSecret,
|
|
43
|
+
now: opts.now,
|
|
44
|
+
// Replays happen long after the fact, so give them a wider skew unless overridden.
|
|
45
|
+
skewSeconds: opts.skewSeconds ?? YEAR_S,
|
|
46
|
+
});
|
|
47
|
+
if (ok)
|
|
48
|
+
return null;
|
|
49
|
+
return {
|
|
50
|
+
status: 'sig_fail',
|
|
51
|
+
reason: 'signature did not verify against current SLACK_SIGNING_SECRET; pass --force to replay anyway',
|
|
52
|
+
};
|
|
91
53
|
}
|
|
92
|
-
async function
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
54
|
+
async function reingest(hippoRoot, envelope) {
|
|
55
|
+
const tenantId = await resolveTenantForSlackTeam(hippoRoot, envelope.team_id);
|
|
56
|
+
if (!tenantId)
|
|
57
|
+
return { ok: false, status: 'unroutable', reason: `team_id ${envelope.team_id} still unroutable` };
|
|
58
|
+
const inner = envelope.event;
|
|
59
|
+
if (!isSlackMessageEvent(inner))
|
|
60
|
+
return { ok: false, status: 'unhandled', reason: 'unhandled inner event type' };
|
|
61
|
+
const replayCtx = { hippoRoot, tenantId, actor: adminActor('connector:slack:replay') };
|
|
99
62
|
if (inner.subtype === 'message_deleted' && inner.deleted_ts) {
|
|
100
63
|
const r = await handleMessageDeleted(replayCtx, {
|
|
101
|
-
teamId:
|
|
64
|
+
teamId: envelope.team_id,
|
|
102
65
|
channelId: inner.channel,
|
|
103
66
|
deletedTs: inner.deleted_ts,
|
|
104
|
-
eventId:
|
|
67
|
+
eventId: envelope.event_id,
|
|
105
68
|
});
|
|
106
|
-
|
|
107
|
-
return { ok: true, status: r.status, memoryId: r.memoryId, retryCount: row.retryCount + 1 };
|
|
69
|
+
return { ok: true, status: r.status, memoryId: r.memoryId };
|
|
108
70
|
}
|
|
109
71
|
const result = await ingestMessage(replayCtx, {
|
|
110
|
-
teamId:
|
|
72
|
+
teamId: envelope.team_id,
|
|
111
73
|
channel: {
|
|
112
74
|
id: inner.channel,
|
|
113
75
|
is_private: inner.channel_type !== 'channel',
|
|
@@ -115,9 +77,8 @@ async function dispatchReplay(replayCtx, row, parsed) {
|
|
|
115
77
|
is_mpim: inner.channel_type === 'mpim',
|
|
116
78
|
},
|
|
117
79
|
message: inner,
|
|
118
|
-
eventId:
|
|
80
|
+
eventId: envelope.event_id,
|
|
119
81
|
});
|
|
120
|
-
|
|
121
|
-
return { ok: true, status: result.status, memoryId: result.memoryId, retryCount: row.retryCount + 1 };
|
|
82
|
+
return { ok: true, status: result.status, memoryId: result.memoryId };
|
|
122
83
|
}
|
|
123
84
|
//# sourceMappingURL=dlq.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Context } from '../../api/index.js';
|
|
2
|
+
import { type IngestResult } from '../ingest.js';
|
|
2
3
|
import type { ChannelMeta } from './scope.js';
|
|
3
4
|
import type { SlackMessageEvent } from './types.js';
|
|
4
5
|
export interface IngestInput {
|
|
@@ -8,13 +9,7 @@ export interface IngestInput {
|
|
|
8
9
|
/** Slack event_id for the envelope (or for backfill, a synthesized stable id). */
|
|
9
10
|
eventId: string;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
status: IngestStatus;
|
|
14
|
-
memoryId: string | null;
|
|
15
|
-
}
|
|
16
|
-
/** Ingests a Slack message as a kind='raw' memory, once per event id: Slack redelivers within a minute.
|
|
17
|
-
* The pre-check is only the fast path; the store logs the event in the memory's own transaction, which is what holds when two workers race.
|
|
18
|
-
* An empty body is logged with no memory, so its replay skips the transform. */
|
|
12
|
+
/** Ingests a Slack message as a kind='raw' memory once per event id (Slack redelivers within a minute); the pre-check is only the fast path,
|
|
13
|
+
* the store logs the event in the memory's own transaction, which holds when two workers race. An empty body is logged with no memory. */
|
|
19
14
|
export declare function ingestMessage(ctx: Context, input: IngestInput): Promise<IngestResult>;
|
|
20
15
|
//# sourceMappingURL=ingest.d.ts.map
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { remember } from '../../api/index.js';
|
|
2
1
|
import { requireGroup, storeFor } from '../../store/index.js';
|
|
3
|
-
import {
|
|
2
|
+
import { rememberWithEventLog } from '../ingest.js';
|
|
4
3
|
import { messageToRememberOpts } from './transform.js';
|
|
5
|
-
/** Ingests a Slack message as a kind='raw' memory
|
|
6
|
-
*
|
|
7
|
-
* An empty body is logged with no memory, so its replay skips the transform. */
|
|
4
|
+
/** Ingests a Slack message as a kind='raw' memory once per event id (Slack redelivers within a minute); the pre-check is only the fast path,
|
|
5
|
+
* the store logs the event in the memory's own transaction, which holds when two workers race. An empty body is logged with no memory. */
|
|
8
6
|
export async function ingestMessage(ctx, input) {
|
|
9
7
|
const events = requireGroup(storeFor(ctx), 'connectorEvents');
|
|
10
8
|
const event = { connector: 'slack', eventId: input.eventId };
|
|
@@ -16,30 +14,6 @@ export async function ingestMessage(ctx, input) {
|
|
|
16
14
|
// they first returned; a non-NULL memory_id means a memory was ingested, so 'duplicate'.
|
|
17
15
|
return { status: seen.memoryId === null ? 'skipped' : 'duplicate', memoryId: seen.memoryId };
|
|
18
16
|
}
|
|
19
|
-
|
|
20
|
-
if (!opts) {
|
|
21
|
-
await events.markEventSeen(event);
|
|
22
|
-
return { status: 'skipped', memoryId: null };
|
|
23
|
-
}
|
|
24
|
-
try {
|
|
25
|
-
return await rememberWithEventLog(ctx, event, opts);
|
|
26
|
-
}
|
|
27
|
-
catch (e) {
|
|
28
|
-
if (!(e instanceof RejectedValueError))
|
|
29
|
-
throw e;
|
|
30
|
-
// A tombstone hit is a PERMANENT skip: a DLQ retry would hit the same refusal forever, so mark the
|
|
31
|
-
// event seen like the empty-body branch above and let a Slack retry ack as done, not error.
|
|
32
|
-
await events.markEventSeen(event);
|
|
33
|
-
return { status: 'skipped', memoryId: null };
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
async function rememberWithEventLog(ctx, event, opts) {
|
|
37
|
-
// No `|| 'connector:slack'` fallback: the caller always builds ctx with the connector subject, and with
|
|
38
|
-
// an object-shaped Context.actor an OR-fallback would never fire anyway.
|
|
39
|
-
const result = await remember(ctx, { ...opts, untrusted: true, event });
|
|
40
|
-
// Another worker logged this event between the pre-check and the write: its memory stands and ours was not stored.
|
|
41
|
-
if (result.duplicate)
|
|
42
|
-
return { status: 'skipped_duplicate', memoryId: result.duplicate.memoryId };
|
|
43
|
-
return { status: 'ingested', memoryId: result.id };
|
|
17
|
+
return rememberWithEventLog(ctx, event, messageToRememberOpts(input));
|
|
44
18
|
}
|
|
45
19
|
//# sourceMappingURL=ingest.js.map
|
|
@@ -4,13 +4,7 @@ export interface ChannelMeta {
|
|
|
4
4
|
is_im?: boolean;
|
|
5
5
|
is_mpim?: boolean;
|
|
6
6
|
}
|
|
7
|
-
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Default to private when privacy is undetermined. The cost of leaking a
|
|
11
|
-
* public channel into private scope (recall returns nothing) is far smaller
|
|
12
|
-
* than the cost of leaking a private channel into public scope (data exposed
|
|
13
|
-
* to a tenant that should not see it).
|
|
14
|
-
*/
|
|
7
|
+
/** Map a Slack channel into a hippo scope string, defaulting to private when privacy is undetermined:
|
|
8
|
+
* a public channel leaking into private scope returns nothing, but the reverse exposes data. */
|
|
15
9
|
export declare function scopeFromChannel(ch: ChannelMeta): string;
|
|
16
10
|
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Default to private when privacy is undetermined. The cost of leaking a
|
|
5
|
-
* public channel into private scope (recall returns nothing) is far smaller
|
|
6
|
-
* than the cost of leaking a private channel into public scope (data exposed
|
|
7
|
-
* to a tenant that should not see it).
|
|
8
|
-
*/
|
|
1
|
+
/** Map a Slack channel into a hippo scope string, defaulting to private when privacy is undetermined:
|
|
2
|
+
* a public channel leaking into private scope returns nothing, but the reverse exposes data. */
|
|
9
3
|
export function scopeFromChannel(ch) {
|
|
10
4
|
const isPublic = ch.is_private === false && !ch.is_im && !ch.is_mpim;
|
|
11
5
|
return isPublic ? `slack:public:${ch.id}` : `slack:private:${ch.id}`;
|
|
@@ -3,12 +3,7 @@ export interface VerifyOpts {
|
|
|
3
3
|
timestamp: string;
|
|
4
4
|
signature: string;
|
|
5
5
|
signingSecret: string;
|
|
6
|
-
/**
|
|
7
|
-
* Previous signing secret during a rotation. Deploy with
|
|
8
|
-
* both `SLACK_SIGNING_SECRET` (new) and `SLACK_SIGNING_SECRET_PREVIOUS` (old)
|
|
9
|
-
* set, verify both work, drop previous after rollover. The verifier tries
|
|
10
|
-
* `signingSecret` first, then `previousSecret` if that fails.
|
|
11
|
-
*/
|
|
6
|
+
/** Previous signing secret during rotation (SLACK_SIGNING_SECRET_PREVIOUS); the verifier tries `signingSecret` first, then this. */
|
|
12
7
|
previousSecret?: string;
|
|
13
8
|
/** Current unix seconds. Injectable for tests. */
|
|
14
9
|
now?: number;
|
|
@@ -1,22 +1,5 @@
|
|
|
1
|
-
import type { DatabaseSyncLike } from '../../db/index.js';
|
|
2
1
|
import { type HippoStore } from '../../store/index.js';
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Returns:
|
|
7
|
-
* - mapped tenant_id when slack_workspaces has a row for `teamId`
|
|
8
|
-
* - the deployment's HIPPO_TENANT fallback (or 'default') when slack_workspaces
|
|
9
|
-
* is empty (single-workspace install — env fallback is safe)
|
|
10
|
-
* - null when slack_workspaces is non-empty AND `teamId` is unknown
|
|
11
|
-
* (multi-workspace install — fail closed; an unknown team is not the
|
|
12
|
-
* deployment's tenant). Escape hatch: SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK=1
|
|
13
|
-
* restores the env fallback for emergency rollback only.
|
|
14
|
-
*
|
|
15
|
-
* The fail-closed contract lives here so every caller (route handler, CLI
|
|
16
|
-
* replay, future MCP) gets the same protection against routing a foreign
|
|
17
|
-
* workspace's events into the deployment tenant.
|
|
18
|
-
*/
|
|
19
|
-
export declare function resolveTenantForTeam(db: DatabaseSyncLike, teamId: string): string | null;
|
|
20
|
-
/** resolveTenantForTeam through `store`, else hippo.db under `hippoRoot`. */
|
|
2
|
+
/** Look up the tenant_id for a Slack team_id; the HIPPO_TENANT fallback applies only when slack_workspaces is empty (single-workspace install).
|
|
3
|
+
* An unknown team on a multi-workspace install returns null (fail closed); SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK=1 is the emergency escape. */
|
|
21
4
|
export declare function resolveTenantForSlackTeam(hippoRoot: string, teamId: string, store?: HippoStore): Promise<string | null>;
|
|
22
5
|
//# sourceMappingURL=tenant-routing.d.ts.map
|
|
@@ -1,26 +1,7 @@
|
|
|
1
1
|
import { envSlackAllowUnknownTeamFallback, envTenant } from '../../util/env.js';
|
|
2
2
|
import { requireGroup, storeFor } from '../../store/index.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* Look up the tenant_id for a Slack team_id.
|
|
6
|
-
*
|
|
7
|
-
* Returns:
|
|
8
|
-
* - mapped tenant_id when slack_workspaces has a row for `teamId`
|
|
9
|
-
* - the deployment's HIPPO_TENANT fallback (or 'default') when slack_workspaces
|
|
10
|
-
* is empty (single-workspace install — env fallback is safe)
|
|
11
|
-
* - null when slack_workspaces is non-empty AND `teamId` is unknown
|
|
12
|
-
* (multi-workspace install — fail closed; an unknown team is not the
|
|
13
|
-
* deployment's tenant). Escape hatch: SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK=1
|
|
14
|
-
* restores the env fallback for emergency rollback only.
|
|
15
|
-
*
|
|
16
|
-
* The fail-closed contract lives here so every caller (route handler, CLI
|
|
17
|
-
* replay, future MCP) gets the same protection against routing a foreign
|
|
18
|
-
* workspace's events into the deployment tenant.
|
|
19
|
-
*/
|
|
20
|
-
export function resolveTenantForTeam(db, teamId) {
|
|
21
|
-
return tenantForRoute(slackTeamRouteAt(db, teamId));
|
|
22
|
-
}
|
|
23
|
-
/** resolveTenantForTeam through `store`, else hippo.db under `hippoRoot`. */
|
|
3
|
+
/** Look up the tenant_id for a Slack team_id; the HIPPO_TENANT fallback applies only when slack_workspaces is empty (single-workspace install).
|
|
4
|
+
* An unknown team on a multi-workspace install returns null (fail closed); SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK=1 is the emergency escape. */
|
|
24
5
|
export async function resolveTenantForSlackTeam(hippoRoot, teamId, store) {
|
|
25
6
|
return tenantForRoute(await requireGroup(storeFor({ hippoRoot, store }), 'connectorEvents').slackTeamRoute(teamId));
|
|
26
7
|
}
|
|
@@ -6,23 +6,7 @@ export interface TransformInput {
|
|
|
6
6
|
channel: ChannelMeta;
|
|
7
7
|
message: SlackMessageEvent;
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* null when the message has no usable body (e.g. system events, bot reactions
|
|
12
|
-
* without text). Caller treats null as "skip but mark idempotency seen".
|
|
13
|
-
*
|
|
14
|
-
* Contract:
|
|
15
|
-
* - kind is the literal 'raw' (connector boundary, see src/importers.ts).
|
|
16
|
-
* - artifact_ref format MUST be exactly `slack://${teamId}/${channelId}/${ts}`;
|
|
17
|
-
* the deletion path looks up by this string.
|
|
18
|
-
* - owner is non-null whenever a row is written. Required by the
|
|
19
|
-
* provenance gate (`hippo provenance --strict`).
|
|
20
|
-
* - `user:<slack_user_id>` when the event carries a `user`.
|
|
21
|
-
* - `bot:<bot_id>` for the `bot_message` subtype (or any userless+text event
|
|
22
|
-
* that supplies bot_id).
|
|
23
|
-
* - `bot:unknown` only as a last-resort sentinel so the gate never sees null.
|
|
24
|
-
* Skipping userless messages instead would silently drop bot ingestion
|
|
25
|
-
* via the "skipped but seen" path in ingest.ts.
|
|
26
|
-
*/
|
|
9
|
+
/** Convert a SlackMessageEvent into RememberOpts; returns null when the message has no usable body so the caller marks it seen and skips it.
|
|
10
|
+
* artifact_ref MUST be `slack://${teamId}/${channelId}/${ts}` (deletion looks it up); owner is never null: `user:<id>`, `bot:<bot_id>`, else `bot:unknown`. */
|
|
27
11
|
export declare function messageToRememberOpts(input: TransformInput): RememberOpts | null;
|
|
28
12
|
//# sourceMappingURL=transform.d.ts.map
|
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
import { scopeFromChannel } from './scope.js';
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
* null when the message has no usable body (e.g. system events, bot reactions
|
|
5
|
-
* without text). Caller treats null as "skip but mark idempotency seen".
|
|
6
|
-
*
|
|
7
|
-
* Contract:
|
|
8
|
-
* - kind is the literal 'raw' (connector boundary, see src/importers.ts).
|
|
9
|
-
* - artifact_ref format MUST be exactly `slack://${teamId}/${channelId}/${ts}`;
|
|
10
|
-
* the deletion path looks up by this string.
|
|
11
|
-
* - owner is non-null whenever a row is written. Required by the
|
|
12
|
-
* provenance gate (`hippo provenance --strict`).
|
|
13
|
-
* - `user:<slack_user_id>` when the event carries a `user`.
|
|
14
|
-
* - `bot:<bot_id>` for the `bot_message` subtype (or any userless+text event
|
|
15
|
-
* that supplies bot_id).
|
|
16
|
-
* - `bot:unknown` only as a last-resort sentinel so the gate never sees null.
|
|
17
|
-
* Skipping userless messages instead would silently drop bot ingestion
|
|
18
|
-
* via the "skipped but seen" path in ingest.ts.
|
|
19
|
-
*/
|
|
2
|
+
/** Convert a SlackMessageEvent into RememberOpts; returns null when the message has no usable body so the caller marks it seen and skips it.
|
|
3
|
+
* artifact_ref MUST be `slack://${teamId}/${channelId}/${ts}` (deletion looks it up); owner is never null: `user:<id>`, `bot:<bot_id>`, else `bot:unknown`. */
|
|
20
4
|
export function messageToRememberOpts(input) {
|
|
21
5
|
const text = input.message.text?.trim();
|
|
22
6
|
if (!text)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Spec: https://api.slack.com/events-api
|
|
4
|
-
*/
|
|
1
|
+
/** Slack Events API envelope shapes used by the ingestion connector.
|
|
2
|
+
* Spec: https://api.slack.com/events-api */
|
|
5
3
|
import { type JsonValue } from '../../util/json.js';
|
|
6
4
|
export interface SlackUrlVerification {
|
|
7
5
|
type: 'url_verification';
|
|
@@ -17,11 +15,7 @@ export interface SlackMessageEvent {
|
|
|
17
15
|
text?: string;
|
|
18
16
|
ts: string;
|
|
19
17
|
thread_ts?: string;
|
|
20
|
-
/**
|
|
21
|
-
* Slack `bot_message` subtype carries `bot_id` instead of `user`. The
|
|
22
|
-
* provenance gate requires a non-null `owner`, so transform.ts
|
|
23
|
-
* derives `owner: bot:<bot_id>` when `user` is absent.
|
|
24
|
-
*/
|
|
18
|
+
/** The `bot_message` subtype carries `bot_id` instead of `user`; transform.ts derives `owner: bot:<bot_id>` from it. */
|
|
25
19
|
bot_id?: string;
|
|
26
20
|
/** Present on subtype='message_deleted'. */
|
|
27
21
|
deleted_ts?: string;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Spec: https://api.slack.com/events-api
|
|
4
|
-
*/
|
|
1
|
+
/** Slack Events API envelope shapes used by the ingestion connector.
|
|
2
|
+
* Spec: https://api.slack.com/events-api */
|
|
5
3
|
import { isJsonString, isJsonObject, isJsonNumber } from '../../util/json.js';
|
|
6
4
|
export function isSlackEventEnvelope(x) {
|
|
7
5
|
if (!isJsonObject(x))
|
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
import { fetchWithRetry, isRetryableStatus } from '../../util/http-retry.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Slack omits `channel` from messages in the history response, so we stamp
|
|
9
|
-
* the request channel id onto each parsed message — downstream ingest needs
|
|
10
|
-
* it on every event.
|
|
11
|
-
*/
|
|
2
|
+
import { readCappedJson } from '../../util/capped-json.js';
|
|
3
|
+
import { errorMessage } from '../../util/log.js';
|
|
4
|
+
import { isJsonObject, isJsonString } from '../../util/json.js';
|
|
5
|
+
/** Build a SlackHistoryFetcher that pages `conversations.history` over HTTP via `fetchWithRetry` (429 and 5xx handled).
|
|
6
|
+
* Slack omits `channel` from history messages, so the request channel id is stamped onto each one for ingest. */
|
|
12
7
|
const SLACK_TIMEOUT_MS = 30_000;
|
|
8
|
+
// A page is at most 200 messages, each up to 40,000 characters at 4 bytes, carried once as text and once as rich-text blocks.
|
|
9
|
+
const SLACK_MAX_REPLY_BYTES = 64 * 1024 * 1024;
|
|
10
|
+
function isSlackMessage(m) {
|
|
11
|
+
return isJsonObject(m) && m.type === 'message' && isJsonString(m.ts);
|
|
12
|
+
}
|
|
13
|
+
/** The reply as a JSON object. The error names the status and the path only, since the query string carries channel ids and cursors. */
|
|
14
|
+
async function readHistoryReply(r, url) {
|
|
15
|
+
const where = `slack: HTTP ${r.status} on ${url.pathname}`;
|
|
16
|
+
let body;
|
|
17
|
+
try {
|
|
18
|
+
body = await readCappedJson(r, SLACK_MAX_REPLY_BYTES);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
throw new Error(`${where}: ${errorMessage(err)}`, { cause: err });
|
|
22
|
+
}
|
|
23
|
+
if (!isJsonObject(body))
|
|
24
|
+
throw new Error(`${where}: the reply is not a JSON object`);
|
|
25
|
+
if (body.messages !== undefined && !Array.isArray(body.messages))
|
|
26
|
+
throw new Error(`${where}: \`messages\` is not an array`);
|
|
27
|
+
return body;
|
|
28
|
+
}
|
|
13
29
|
export function slackHistoryFetcher(token, fetchImpl) {
|
|
14
30
|
return async ({ channelId, cursor, oldest }) => {
|
|
15
31
|
const url = new URL('https://slack.com/api/conversations.history');
|
|
@@ -25,27 +41,17 @@ export function slackHistoryFetcher(token, fetchImpl) {
|
|
|
25
41
|
});
|
|
26
42
|
if (isRetryableStatus(r.status))
|
|
27
43
|
throw new Error(`slack: still rate-limited or unavailable (HTTP ${r.status})`);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const messages = (body.messages ?? [])
|
|
34
|
-
.filter((m) => {
|
|
35
|
-
if (m === null || Array.isArray(m) || typeof m !== 'object') {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
// SAFETY: the check above just confirmed m is a non-null, non-array
|
|
39
|
-
// plain object, so it's safe to treat as a JSON-shaped record; the
|
|
40
|
-
// `m is SlackMessageEvent` predicate is what validates the fields.
|
|
41
|
-
const o = m;
|
|
42
|
-
return o.type === 'message' && isJsonString(o.ts);
|
|
43
|
-
})
|
|
44
|
+
const body = await readHistoryReply(r, url);
|
|
45
|
+
if (body.ok !== true)
|
|
46
|
+
throw new Error(`slack: ${isJsonString(body.error) ? body.error : 'unknown error'}`);
|
|
47
|
+
const messages = (Array.isArray(body.messages) ? body.messages : [])
|
|
48
|
+
.filter(isSlackMessage)
|
|
44
49
|
// Slack returns messages without `channel`; stamp it from the request.
|
|
45
50
|
.map((m) => ({ ...m, channel: channelId }));
|
|
51
|
+
const nextCursor = isJsonObject(body.response_metadata) ? body.response_metadata.next_cursor : undefined;
|
|
46
52
|
return {
|
|
47
53
|
messages,
|
|
48
|
-
next_cursor:
|
|
54
|
+
next_cursor: isJsonString(nextCursor) ? nextCursor : null,
|
|
49
55
|
};
|
|
50
56
|
};
|
|
51
57
|
}
|
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
import type { HippoStore } from '../../store/index.js';
|
|
2
2
|
import { type WebhookRequest } from '../../util/http-util.js';
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* this route is in PUBLIC_ROUTES. The route is responsible for:
|
|
7
|
-
* 1. Echoing the one-time url_verification challenge.
|
|
8
|
-
* 2. Verifying the HMAC on every other inbound payload.
|
|
9
|
-
* 3. Resolving body.team_id → tenantId via slack_workspaces, falling
|
|
10
|
-
* back to HIPPO_TENANT then 'default'.
|
|
11
|
-
* 4. Dispatching event_callback envelopes to ingestMessage /
|
|
12
|
-
* handleMessageDeleted.
|
|
13
|
-
* 5. Parking malformed or unhandled payloads in slack_dlq and STILL
|
|
14
|
-
* ACKing 200 - Slack retries forever otherwise.
|
|
15
|
-
*
|
|
16
|
-
* When SLACK_SIGNING_SECRET is unset we return 404, not
|
|
17
|
-
* 503, so an external probe cannot distinguish "route gated off by config"
|
|
18
|
-
* from "route does not exist on this build".
|
|
19
|
-
*
|
|
20
|
-
* Bearer auth is skipped on purpose: server.ts checks isPublicRoute before calling this.
|
|
21
|
-
*/
|
|
3
|
+
/** Slack Events API webhook: HMAC over the raw body with SLACK_SIGNING_SECRET, no Bearer (its route row declares webhook-signature);
|
|
4
|
+
* malformed payloads go to slack_dlq, ACK 200.
|
|
5
|
+
* 404 (not 503) when the secret is unset, so a probe cannot tell a gated-off route from a missing one. */
|
|
22
6
|
export declare function handleSlackEventsWebhook(request: WebhookRequest, store?: HippoStore): Promise<void>;
|
|
23
7
|
//# sourceMappingURL=webhook.d.ts.map
|