hippo-memory 1.60.0 → 1.62.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 +29 -54
- package/dist/ablation.js +9 -27
- package/dist/agent-memories/apply.d.ts +1 -1
- package/dist/agent-memories/apply.js +4 -1
- package/dist/agent-memories/claude-code.d.ts +3 -1
- package/dist/agent-memories/claude-code.js +54 -10
- package/dist/agent-memories/codex.js +1 -1
- package/dist/agent-memories/gemini.js +1 -1
- package/dist/agent-memories/legacy.js +1 -1
- package/dist/agent-memories/source.js +1 -1
- package/dist/agent-memories/sync.d.ts +3 -3
- package/dist/agent-memories/sync.js +22 -9
- package/dist/agent-memories/types.d.ts +0 -2
- package/dist/ambient-store.d.ts +14 -0
- package/dist/ambient-store.js +90 -0
- package/dist/ambient.d.ts +23 -0
- package/dist/ambient.js +72 -50
- package/dist/api/assemble.d.ts +93 -0
- package/dist/api/assemble.js +153 -0
- package/dist/api/audit.d.ts +17 -0
- package/dist/api/audit.js +23 -0
- package/dist/api/auth.d.ts +79 -0
- package/dist/api/auth.js +178 -0
- package/dist/api/context-select.d.ts +49 -0
- package/dist/api/context-select.js +344 -0
- package/dist/api/context-types.d.ts +105 -0
- package/dist/api/context-types.js +3 -0
- package/dist/api/context.d.ts +31 -0
- package/dist/api/context.js +378 -0
- package/dist/api/dormant.d.ts +30 -0
- package/dist/api/dormant.js +140 -0
- package/dist/api/drill-down.d.ts +84 -0
- package/dist/api/drill-down.js +126 -0
- package/dist/api/forget.d.ts +57 -0
- package/dist/api/forget.js +87 -0
- package/dist/api/goals.d.ts +18 -0
- package/dist/api/goals.js +33 -0
- package/dist/api/learn.d.ts +31 -0
- package/dist/api/learn.js +88 -0
- package/dist/api/outcome.d.ts +61 -0
- package/dist/api/outcome.js +66 -0
- package/dist/api/promote.d.ts +54 -0
- package/dist/api/promote.js +192 -0
- package/dist/api/quarantine.d.ts +24 -0
- package/dist/api/quarantine.js +121 -0
- package/dist/api/recall-types.d.ts +390 -0
- package/dist/api/recall-types.js +3 -0
- package/dist/api/recall.d.ts +36 -0
- package/dist/api/recall.js +499 -0
- package/dist/api/remember.d.ts +35 -0
- package/dist/api/remember.js +43 -0
- package/dist/api/sleep.d.ts +136 -0
- package/dist/api/sleep.js +256 -0
- package/dist/api/tokens.d.ts +26 -0
- package/dist/api/tokens.js +60 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/api/types.js +38 -0
- package/dist/api.d.ts +20 -1262
- package/dist/api.js +25 -2727
- package/dist/audit.d.ts +3 -0
- package/dist/audit.js +6 -3
- package/dist/auth.d.ts +45 -4
- package/dist/auth.js +125 -48
- package/dist/autolearn.js +2 -2
- package/dist/capture/command.d.ts +33 -0
- package/dist/capture/command.js +264 -0
- package/dist/capture/compact.d.ts +44 -0
- package/dist/capture/compact.js +354 -0
- package/dist/capture/extract.d.ts +21 -0
- package/dist/capture/extract.js +464 -0
- package/dist/capture/transcript.d.ts +40 -0
- package/dist/capture/transcript.js +193 -0
- package/dist/capture-error.js +2 -1
- package/dist/churn-git.js +4 -2
- package/dist/cli/audit.d.ts +3 -0
- package/dist/cli/audit.js +159 -0
- package/dist/cli/auth.d.ts +2 -0
- package/dist/cli/auth.js +171 -0
- package/dist/cli/briefs.d.ts +4 -0
- package/dist/cli/briefs.js +453 -0
- package/dist/cli/card.d.ts +3 -0
- package/dist/cli/card.js +333 -0
- package/dist/cli/context.d.ts +15 -0
- package/dist/cli/context.js +376 -0
- package/dist/cli/continuity.d.ts +6 -0
- package/dist/cli/continuity.js +457 -0
- package/dist/cli/curate.d.ts +19 -0
- package/dist/cli/curate.js +556 -0
- package/dist/cli/dag.d.ts +5 -0
- package/dist/cli/dag.js +177 -0
- package/dist/cli/decisions.d.ts +4 -0
- package/dist/cli/decisions.js +528 -0
- package/dist/cli/eval.d.ts +5 -0
- package/dist/cli/eval.js +213 -0
- package/dist/cli/explain.d.ts +4 -0
- package/dist/cli/explain.js +156 -0
- package/dist/cli/goals.d.ts +2 -0
- package/dist/cli/goals.js +196 -0
- package/dist/cli/hook-blocks.d.ts +18 -0
- package/dist/cli/hook-blocks.js +233 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +305 -0
- package/dist/cli/maintenance.d.ts +4 -0
- package/dist/cli/maintenance.js +190 -0
- package/dist/cli/playbooks.d.ts +4 -0
- package/dist/cli/playbooks.js +573 -0
- package/dist/cli/projects.js +9 -6
- package/dist/cli/recall.d.ts +7 -0
- package/dist/cli/recall.js +582 -0
- package/dist/cli/remember.d.ts +5 -0
- package/dist/cli/remember.js +485 -0
- package/dist/cli/serve.d.ts +5 -0
- package/dist/cli/serve.js +40 -0
- package/dist/cli/session-hooks.d.ts +29 -0
- package/dist/cli/session-hooks.js +647 -0
- package/dist/cli/setup.d.ts +4 -0
- package/dist/cli/setup.js +397 -0
- package/dist/cli/shared.d.ts +15 -19
- package/dist/cli/shared.js +50 -341
- package/dist/cli/slack.d.ts +2 -0
- package/dist/cli/slack.js +171 -0
- package/dist/cli/status.d.ts +18 -0
- package/dist/cli/status.js +409 -0
- package/dist/cli/transfer.d.ts +10 -0
- package/dist/cli/transfer.js +424 -0
- package/dist/cli/usage.d.ts +85 -0
- package/dist/cli/usage.js +741 -0
- package/dist/cli.d.ts +71 -120
- package/dist/cli.js +170 -8469
- package/dist/client.js +15 -8
- package/dist/compaction-record.d.ts +0 -2
- package/dist/compaction-record.js +7 -5
- package/dist/connectors/github/backfill.js +94 -87
- package/dist/connectors/github/cli-impl.js +4 -3
- package/dist/connectors/github/dlq.js +67 -54
- package/dist/connectors/github/ingest.js +34 -35
- package/dist/connectors/github/tenant-routing.js +3 -2
- package/dist/connectors/github/webhook.js +135 -216
- package/dist/connectors/slack/dlq.js +49 -61
- package/dist/connectors/slack/ingest.js +55 -48
- package/dist/connectors/slack/tenant-routing.js +4 -3
- package/dist/connectors/slack/webhook.js +72 -74
- package/dist/consolidate/conflicts.d.ts +10 -0
- package/dist/consolidate/conflicts.js +178 -0
- package/dist/consolidate/decay.d.ts +12 -0
- package/dist/consolidate/decay.js +145 -0
- package/dist/consolidate/llm-passes.d.ts +3 -0
- package/dist/consolidate/llm-passes.js +141 -0
- package/dist/consolidate/merge.d.ts +7 -0
- package/dist/consolidate/merge.js +251 -0
- package/dist/consolidate/physics-pass.d.ts +3 -0
- package/dist/consolidate/physics-pass.js +60 -0
- package/dist/consolidate/run.d.ts +69 -0
- package/dist/consolidate/run.js +76 -0
- package/dist/consolidate/sleep.d.ts +18 -0
- package/dist/consolidate/sleep.js +209 -0
- package/dist/consolidate/traces.d.ts +4 -0
- package/dist/consolidate/traces.js +178 -0
- package/dist/context-auto.js +7 -11
- package/dist/context-render.d.ts +1 -1
- package/dist/context-render.js +1 -1
- package/dist/customer-notes.d.ts +3 -0
- package/dist/customer-notes.js +83 -72
- package/dist/dag.js +225 -188
- package/dist/dashboard-actions.d.ts +20 -0
- package/dist/dashboard-actions.js +88 -0
- package/dist/dashboard-params.d.ts +45 -0
- package/dist/dashboard-params.js +127 -0
- package/dist/dashboard-queries.d.ts +15 -0
- package/dist/dashboard-queries.js +355 -0
- package/dist/dashboard-snapshot.d.ts +138 -0
- package/dist/dashboard-snapshot.js +308 -0
- package/dist/dashboard-types.d.ts +163 -0
- package/dist/dashboard-types.js +3 -0
- package/dist/dashboard.d.ts +6 -7
- package/dist/dashboard.js +228 -202
- package/dist/db/busy.d.ts +5 -0
- package/dist/db/busy.js +24 -0
- package/dist/db/continuity.d.ts +5 -0
- package/dist/db/continuity.js +145 -0
- package/dist/db/meta.d.ts +8 -0
- package/dist/db/meta.js +35 -0
- package/dist/db/migrate.d.ts +9 -0
- package/dist/db/migrate.js +138 -0
- package/dist/db/migrations/index.d.ts +5 -0
- package/dist/db/migrations/index.js +109 -0
- package/dist/db/migrations/types.d.ts +14 -0
- package/dist/db/migrations/types.js +2 -0
- package/dist/db/migrations/v01.d.ts +3 -0
- package/dist/db/migrations/v01.js +38 -0
- package/dist/db/migrations/v02.d.ts +3 -0
- package/dist/db/migrations/v02.js +21 -0
- package/dist/db/migrations/v03.d.ts +3 -0
- package/dist/db/migrations/v03.js +22 -0
- package/dist/db/migrations/v04.d.ts +3 -0
- package/dist/db/migrations/v04.js +28 -0
- package/dist/db/migrations/v05.d.ts +3 -0
- package/dist/db/migrations/v05.js +21 -0
- package/dist/db/migrations/v06.d.ts +3 -0
- package/dist/db/migrations/v06.js +25 -0
- package/dist/db/migrations/v07.d.ts +3 -0
- package/dist/db/migrations/v07.js +13 -0
- package/dist/db/migrations/v08.d.ts +3 -0
- package/dist/db/migrations/v08.js +8 -0
- package/dist/db/migrations/v09.d.ts +3 -0
- package/dist/db/migrations/v09.js +13 -0
- package/dist/db/migrations/v10.d.ts +3 -0
- package/dist/db/migrations/v10.js +17 -0
- package/dist/db/migrations/v11.d.ts +3 -0
- package/dist/db/migrations/v11.js +15 -0
- package/dist/db/migrations/v12.d.ts +3 -0
- package/dist/db/migrations/v12.js +11 -0
- package/dist/db/migrations/v13.d.ts +3 -0
- package/dist/db/migrations/v13.js +15 -0
- package/dist/db/migrations/v14.d.ts +3 -0
- package/dist/db/migrations/v14.js +66 -0
- package/dist/db/migrations/v15.d.ts +3 -0
- package/dist/db/migrations/v15.js +42 -0
- package/dist/db/migrations/v16.d.ts +3 -0
- package/dist/db/migrations/v16.js +61 -0
- package/dist/db/migrations/v17.d.ts +3 -0
- package/dist/db/migrations/v17.js +46 -0
- package/dist/db/migrations/v18.d.ts +3 -0
- package/dist/db/migrations/v18.js +60 -0
- package/dist/db/migrations/v19.d.ts +3 -0
- package/dist/db/migrations/v19.js +28 -0
- package/dist/db/migrations/v20.d.ts +3 -0
- package/dist/db/migrations/v20.js +42 -0
- package/dist/db/migrations/v21.d.ts +3 -0
- package/dist/db/migrations/v21.js +16 -0
- package/dist/db/migrations/v22.d.ts +3 -0
- package/dist/db/migrations/v22.js +82 -0
- package/dist/db/migrations/v23.d.ts +3 -0
- package/dist/db/migrations/v23.js +48 -0
- package/dist/db/migrations/v24.d.ts +3 -0
- package/dist/db/migrations/v24.js +72 -0
- package/dist/db/migrations/v25.d.ts +3 -0
- package/dist/db/migrations/v25.js +46 -0
- package/dist/db/migrations/v26.d.ts +3 -0
- package/dist/db/migrations/v26.js +23 -0
- package/dist/db/migrations/v27.d.ts +3 -0
- package/dist/db/migrations/v27.js +57 -0
- package/dist/db/migrations/v28.d.ts +3 -0
- package/dist/db/migrations/v28.js +38 -0
- package/dist/db/migrations/v29.d.ts +3 -0
- package/dist/db/migrations/v29.js +78 -0
- package/dist/db/migrations/v30.d.ts +3 -0
- package/dist/db/migrations/v30.js +92 -0
- package/dist/db/migrations/v31.d.ts +3 -0
- package/dist/db/migrations/v31.js +74 -0
- package/dist/db/migrations/v32.d.ts +3 -0
- package/dist/db/migrations/v32.js +102 -0
- package/dist/db/migrations/v33.d.ts +3 -0
- package/dist/db/migrations/v33.js +104 -0
- package/dist/db/migrations/v34.d.ts +3 -0
- package/dist/db/migrations/v34.js +93 -0
- package/dist/db/migrations/v35.d.ts +3 -0
- package/dist/db/migrations/v35.js +98 -0
- package/dist/db/migrations/v36.d.ts +3 -0
- package/dist/db/migrations/v36.js +98 -0
- package/dist/db/migrations/v37.d.ts +3 -0
- package/dist/db/migrations/v37.js +219 -0
- package/dist/db/migrations/v38.d.ts +3 -0
- package/dist/db/migrations/v38.js +277 -0
- package/dist/db/migrations/v39.d.ts +3 -0
- package/dist/db/migrations/v39.js +59 -0
- package/dist/db/migrations/v40.d.ts +3 -0
- package/dist/db/migrations/v40.js +74 -0
- package/dist/db/migrations/v41.d.ts +3 -0
- package/dist/db/migrations/v41.js +43 -0
- package/dist/db/migrations/v42.d.ts +3 -0
- package/dist/db/migrations/v42.js +41 -0
- package/dist/db/migrations/v43.d.ts +3 -0
- package/dist/db/migrations/v43.js +67 -0
- package/dist/db/migrations/v44.d.ts +3 -0
- package/dist/db/migrations/v44.js +28 -0
- package/dist/db/migrations/v45.d.ts +3 -0
- package/dist/db/migrations/v45.js +30 -0
- package/dist/db/migrations/v46.d.ts +3 -0
- package/dist/db/migrations/v46.js +25 -0
- package/dist/db/migrations/v47.d.ts +3 -0
- package/dist/db/migrations/v47.js +17 -0
- package/dist/db/migrations/v48.d.ts +3 -0
- package/dist/db/migrations/v48.js +10 -0
- package/dist/db/migrations/v49.d.ts +3 -0
- package/dist/db/migrations/v49.js +31 -0
- package/dist/db/migrations/v50.d.ts +3 -0
- package/dist/db/migrations/v50.js +67 -0
- package/dist/db/migrations/v51.d.ts +3 -0
- package/dist/db/migrations/v51.js +14 -0
- package/dist/db/migrations/v52.d.ts +3 -0
- package/dist/db/migrations/v52.js +7 -0
- package/dist/db/open.d.ts +23 -0
- package/dist/db/open.js +146 -0
- package/dist/db/sqlite.d.ts +21 -0
- package/dist/db/sqlite.js +8 -0
- package/dist/db/tables.d.ts +7 -0
- package/dist/db/tables.js +38 -0
- package/dist/db.d.ts +6 -46
- package/dist/db.js +5 -3049
- package/dist/decisions.d.ts +4 -1
- package/dist/decisions.js +102 -83
- package/dist/dedupe.js +3 -2
- package/dist/delivery-recorder.js +4 -1
- package/dist/doctor.js +14 -10
- package/dist/embedding-provider.d.ts +1 -1
- package/dist/embedding-provider.js +4 -3
- package/dist/embeddings.d.ts +9 -52
- package/dist/embeddings.js +43 -297
- package/dist/env.d.ts +75 -0
- package/dist/env.js +119 -0
- package/dist/eval-suite.js +1 -1
- package/dist/eval.js +2 -2
- package/dist/extract.js +1 -1
- package/dist/gated-write.js +3 -1
- package/dist/goals.d.ts +3 -1
- package/dist/goals.js +117 -86
- package/dist/graph/read.d.ts +73 -0
- package/dist/graph/read.js +325 -0
- package/dist/graph/rows.d.ts +45 -0
- package/dist/graph/rows.js +51 -0
- package/dist/graph/types.d.ts +83 -0
- package/dist/graph/types.js +11 -0
- package/dist/graph/write.d.ts +93 -0
- package/dist/{graph.js → graph/write.js} +6 -384
- package/dist/graph-extract.js +2 -1
- package/dist/graph-recall.d.ts +1 -1
- package/dist/graph-recall.js +2 -2
- package/dist/graph-stream.js +1 -1
- package/dist/graph-view.d.ts +1 -1
- package/dist/graph-view.js +1 -1
- package/dist/half-life-migration.d.ts +1 -1
- package/dist/half-life-migration.js +2 -1
- package/dist/hooks/codex-session.d.ts +8 -0
- package/dist/hooks/codex-session.js +76 -0
- package/dist/hooks/codex-wrapper.d.ts +55 -0
- package/dist/hooks/codex-wrapper.js +288 -0
- package/dist/hooks/json-hooks.d.ts +63 -0
- package/dist/hooks/json-hooks.js +356 -0
- package/dist/hooks/opencode.d.ts +50 -0
- package/dist/hooks/opencode.js +202 -0
- package/dist/hooks/shared.d.ts +54 -0
- package/dist/hooks/shared.js +77 -0
- package/dist/http-retry.d.ts +2 -0
- package/dist/http-retry.js +4 -3
- package/dist/http-util.d.ts +3 -0
- package/dist/http-util.js +10 -0
- package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
- package/dist/importers/core.js +141 -0
- package/dist/importers/markdown-parse.d.ts +41 -0
- package/dist/importers/markdown-parse.js +132 -0
- package/dist/importers/markdown.d.ts +3 -0
- package/dist/importers/markdown.js +92 -0
- package/dist/importers/sources.d.ts +7 -0
- package/dist/importers/sources.js +229 -0
- package/dist/importers/vault.d.ts +11 -0
- package/dist/importers/vault.js +352 -0
- package/dist/incidents.d.ts +3 -0
- package/dist/incidents.js +52 -43
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -6
- package/dist/invalidation.js +2 -1
- package/dist/judgment.js +2 -1
- package/dist/keyset.d.ts +13 -0
- package/dist/keyset.js +8 -0
- package/dist/local-embedding.d.ts +13 -0
- package/dist/local-embedding.js +165 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +19 -1
- package/dist/mcp/admin-tools.d.ts +8 -0
- package/dist/mcp/admin-tools.js +116 -0
- package/dist/mcp/format.d.ts +27 -0
- package/dist/mcp/format.js +135 -0
- package/dist/mcp/memory-tools.d.ts +5 -0
- package/dist/mcp/memory-tools.js +83 -0
- package/dist/mcp/protocol.d.ts +83 -0
- package/dist/mcp/protocol.js +55 -0
- package/dist/mcp/recall-tools.d.ts +6 -0
- package/dist/mcp/recall-tools.js +320 -0
- package/dist/mcp/request.d.ts +10 -0
- package/dist/mcp/request.js +163 -0
- package/dist/mcp/server.d.ts +4 -75
- package/dist/mcp/server.js +7 -1190
- package/dist/mcp/session-state.d.ts +11 -0
- package/dist/mcp/session-state.js +28 -0
- package/dist/mcp/stdio.d.ts +8 -0
- package/dist/mcp/stdio.js +79 -0
- package/dist/mcp/tools.d.ts +11 -0
- package/dist/mcp/tools.js +247 -0
- package/dist/memory.d.ts +3 -0
- package/dist/memory.js +27 -1
- package/dist/multihop.d.ts +1 -1
- package/dist/multihop.js +2 -1
- package/dist/owner-validation.js +2 -1
- package/dist/physics-state.js +10 -7
- package/dist/policies.d.ts +3 -0
- package/dist/policies.js +93 -74
- package/dist/postinstall.js +3 -2
- package/dist/predictions/planning-fallacy.d.ts +100 -0
- package/dist/predictions/planning-fallacy.js +190 -0
- package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
- package/dist/predictions/store.js +434 -0
- package/dist/processes.d.ts +3 -0
- package/dist/processes.js +94 -76
- package/dist/project-briefs.d.ts +3 -0
- package/dist/project-briefs.js +142 -113
- package/dist/project-identity.js +3 -2
- package/dist/project-merge.d.ts +12 -4
- package/dist/project-merge.js +132 -45
- package/dist/quarantine.d.ts +2 -1
- package/dist/quarantine.js +8 -5
- package/dist/raw-archive.js +1 -1
- package/dist/recall-history.js +3 -2
- package/dist/recall-pipeline.d.ts +2 -2
- package/dist/recall-pipeline.js +16 -8
- package/dist/recall-scope.js +1 -1
- package/dist/recall-trace.d.ts +1 -1
- package/dist/refine-llm.js +2 -1
- package/dist/reject-flow.js +6 -1
- package/dist/rerankers/clef.js +6 -5
- package/dist/rerankers/jev.d.ts +1 -1
- package/dist/rerankers/jev.js +4 -4
- package/dist/rerankers/llm.d.ts +4 -2
- package/dist/rerankers/llm.js +58 -38
- package/dist/rerankers/types.d.ts +1 -1
- package/dist/salience.js +1 -1
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.js +26 -4
- package/dist/scope.js +4 -3
- package/dist/search/as-of.d.ts +10 -0
- package/dist/search/as-of.js +22 -0
- package/dist/search/bm25-search.d.ts +14 -0
- package/dist/search/bm25-search.js +43 -0
- package/dist/search/bm25.d.ts +15 -0
- package/dist/search/bm25.js +54 -0
- package/dist/search/boosts.d.ts +54 -0
- package/dist/search/boosts.js +94 -0
- package/dist/search/breakdown.d.ts +7 -0
- package/dist/search/breakdown.js +20 -0
- package/dist/search/explain.d.ts +25 -0
- package/dist/search/explain.js +31 -0
- package/dist/search/finalize.d.ts +8 -0
- package/dist/search/finalize.js +52 -0
- package/dist/search/fusion.d.ts +27 -0
- package/dist/search/fusion.js +42 -0
- package/dist/search/hybrid-score.d.ts +20 -0
- package/dist/search/hybrid-score.js +73 -0
- package/dist/search/hybrid.d.ts +46 -0
- package/dist/search/hybrid.js +64 -0
- package/dist/search/physics-search.d.ts +29 -0
- package/dist/search/physics-search.js +162 -0
- package/dist/search/rerank.d.ts +10 -0
- package/dist/search/rerank.js +72 -0
- package/dist/search/temporal.d.ts +15 -0
- package/dist/search/temporal.js +45 -0
- package/dist/search/types.d.ts +91 -0
- package/dist/search/types.js +2 -0
- package/dist/search/vector.d.ts +30 -0
- package/dist/search/vector.js +71 -0
- package/dist/secret-detect.d.ts +2 -0
- package/dist/secret-detect.js +2 -1
- package/dist/server/auth.d.ts +52 -0
- package/dist/server/auth.js +221 -0
- package/dist/server/client-ip.d.ts +25 -0
- package/dist/server/client-ip.js +92 -0
- package/dist/server/cursor.d.ts +23 -0
- package/dist/server/cursor.js +58 -0
- package/dist/server/lifecycle.d.ts +7 -0
- package/dist/server/lifecycle.js +29 -0
- package/dist/server/mcp-http.d.ts +5 -0
- package/dist/server/mcp-http.js +199 -0
- package/dist/server/request.d.ts +33 -0
- package/dist/server/request.js +103 -0
- package/dist/server/routes/admin.d.ts +9 -0
- package/dist/server/routes/admin.js +158 -0
- package/dist/server/routes/customer-notes.d.ts +7 -0
- package/dist/server/routes/customer-notes.js +112 -0
- package/dist/server/routes/decisions.d.ts +7 -0
- package/dist/server/routes/decisions.js +133 -0
- package/dist/server/routes/incidents.d.ts +7 -0
- package/dist/server/routes/incidents.js +126 -0
- package/dist/server/routes/memories.d.ts +10 -0
- package/dist/server/routes/memories.js +179 -0
- package/dist/server/routes/policies.d.ts +8 -0
- package/dist/server/routes/policies.js +151 -0
- package/dist/server/routes/predictions.d.ts +7 -0
- package/dist/server/routes/predictions.js +164 -0
- package/dist/server/routes/processes.d.ts +7 -0
- package/dist/server/routes/processes.js +161 -0
- package/dist/server/routes/project-briefs.d.ts +8 -0
- package/dist/server/routes/project-briefs.js +136 -0
- package/dist/server/routes/recall.d.ts +8 -0
- package/dist/server/routes/recall.js +340 -0
- package/dist/server/routes/skills.d.ts +8 -0
- package/dist/server/routes/skills.js +150 -0
- package/dist/server/types.d.ts +56 -0
- package/dist/server/types.js +2 -0
- package/dist/server/validation.d.ts +14 -0
- package/dist/server/validation.js +91 -0
- package/dist/server.d.ts +7 -61
- package/dist/server.js +69 -2362
- package/dist/session-digest.d.ts +1 -1
- package/dist/session-digest.js +9 -2
- package/dist/shared.d.ts +12 -1
- package/dist/shared.js +33 -27
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +88 -70
- package/dist/stdin.js +2 -2
- package/dist/store/audit-event.d.ts +19 -0
- package/dist/store/audit-event.js +33 -0
- package/dist/store/candidates.d.ts +42 -0
- package/dist/store/candidates.js +152 -0
- package/dist/store/conflicts.d.ts +44 -0
- package/dist/store/conflicts.js +444 -0
- package/dist/store/delete-and-batch.d.ts +63 -0
- package/dist/store/delete-and-batch.js +310 -0
- package/dist/store/entry-reads.d.ts +92 -0
- package/dist/store/entry-reads.js +255 -0
- package/dist/store/entry-row.d.ts +67 -0
- package/dist/store/entry-row.js +208 -0
- package/dist/store/entry-writes.d.ts +46 -0
- package/dist/store/entry-writes.js +148 -0
- package/dist/store/handoffs.d.ts +26 -0
- package/dist/store/handoffs.js +184 -0
- package/dist/store/index-and-stats.d.ts +52 -0
- package/dist/store/index-and-stats.js +214 -0
- package/dist/store/markdown.d.ts +10 -0
- package/dist/store/markdown.js +108 -0
- package/dist/store/mirrors.d.ts +49 -0
- package/dist/store/mirrors.js +312 -0
- package/dist/store/open.d.ts +15 -0
- package/dist/store/open.js +223 -0
- package/dist/store/rows.d.ts +178 -0
- package/dist/store/rows.js +158 -0
- package/dist/store/search-rows.d.ts +86 -0
- package/dist/store/search-rows.js +260 -0
- package/dist/store/sessions.d.ts +83 -0
- package/dist/store/sessions.js +272 -0
- package/dist/store/summaries.d.ts +94 -0
- package/dist/store/summaries.js +377 -0
- package/dist/store/tenant-lookup.d.ts +12 -0
- package/dist/store/tenant-lookup.js +16 -0
- package/dist/store-cards.js +2 -1
- package/dist/summary-dirty.d.ts +4 -0
- package/dist/summary-dirty.js +32 -0
- package/dist/support-bundle.js +4 -3
- package/dist/tenant.js +2 -2
- package/dist/tokenize.d.ts +2 -0
- package/dist/tokenize.js +16 -0
- package/dist/transcript-tail.d.ts +7 -0
- package/dist/transcript-tail.js +48 -0
- package/dist/vector-store.d.ts +27 -0
- package/dist/vector-store.js +210 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/working-memory.js +1 -1
- package/dist/yaml.js +36 -11
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist-ui/assets/index-DPN7cP19.js +33 -0
- package/dist-ui/assets/index-dFloKRVr.css +1 -0
- package/dist-ui/index.html +3 -25
- 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 +1 -1
- package/dist/capture.d.ts +0 -155
- package/dist/capture.js +0 -1295
- package/dist/consolidate.d.ts +0 -58
- package/dist/consolidate.js +0 -1124
- package/dist/graph.d.ts +0 -245
- package/dist/hooks.d.ts +0 -208
- package/dist/hooks.js +0 -1076
- package/dist/importers.js +0 -900
- package/dist/predictions.js +0 -620
- package/dist/search.d.ts +0 -320
- package/dist/search.js +0 -970
- package/dist/store.d.ts +0 -776
- package/dist/store.js +0 -3473
- package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
- package/dist-ui/assets/index-BhT8RvO6.js +0 -61
- package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
- package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { envGithubWebhookSecret, envGithubWebhookSecretPrevious } from '../../env.js';
|
|
1
2
|
import { verifyGitHubSignature } from './signature.js';
|
|
2
3
|
import { isGitHubWebhookEnvelope, isGitHubIssueEvent, isGitHubIssueCommentEvent, isGitHubPullRequestEvent, isGitHubPullRequestReviewCommentEvent, } from './types.js';
|
|
3
4
|
import { ingestEvent as ingestGitHubEvent } from './ingest.js';
|
|
@@ -7,7 +8,6 @@ import { resolveTenantForGitHub } from './tenant-routing.js';
|
|
|
7
8
|
import { computeDeletionKey as computeGitHubDeletionKey } from './signature.js';
|
|
8
9
|
import { resolveTenantId } from '../../tenant.js';
|
|
9
10
|
import { openHippoDb, closeHippoDb } from '../../db.js';
|
|
10
|
-
import { adminActor } from '../../api.js';
|
|
11
11
|
import { HttpError, JSON_HEADERS, isHeaderString, readBody, sendJson, } from '../../http-util.js';
|
|
12
12
|
/**
|
|
13
13
|
* GitHub webhook receiver. Mirrors the Slack route shape but with
|
|
@@ -27,13 +27,13 @@ import { HttpError, JSON_HEADERS, isHeaderString, readBody, sendJson, } from '..
|
|
|
27
27
|
*/
|
|
28
28
|
export async function handleGitHubEventsWebhook({ req, res, opts }) {
|
|
29
29
|
const rawBody = await readBody(req);
|
|
30
|
-
const secret =
|
|
30
|
+
const secret = envGithubWebhookSecret();
|
|
31
31
|
if (!secret) {
|
|
32
32
|
res.writeHead(404, JSON_HEADERS);
|
|
33
33
|
res.end(JSON.stringify({ error: 'not found' }));
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
const previousSecret =
|
|
36
|
+
const previousSecret = envGithubWebhookSecretPrevious();
|
|
37
37
|
const sigHdr = req.headers['x-hub-signature-256'];
|
|
38
38
|
const eventHdr = req.headers['x-github-event'];
|
|
39
39
|
const deliveryHdr = req.headers['x-github-delivery'];
|
|
@@ -51,158 +51,143 @@ export async function handleGitHubEventsWebhook({ req, res, opts }) {
|
|
|
51
51
|
}
|
|
52
52
|
// Signature OK from here on. Everything else is ACK-200; bad envelopes go
|
|
53
53
|
// to the DLQ and a human can replay later.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (deliveryId === null) {
|
|
65
|
-
// Body was signed but caller omitted the audit header. Park.
|
|
66
|
-
const db = openHippoDb(opts.hippoRoot);
|
|
67
|
-
try {
|
|
68
|
-
writeToGitHubDlq(db, {
|
|
69
|
-
tenantId: resolveTenantId({}),
|
|
70
|
-
rawPayload: rawBody,
|
|
71
|
-
error: 'missing X-GitHub-Delivery header',
|
|
72
|
-
bucket: 'parse_error',
|
|
73
|
-
eventName,
|
|
74
|
-
deliveryId: null,
|
|
75
|
-
signature: sigStr,
|
|
76
|
-
installationId: installationFromRaw,
|
|
77
|
-
repoFullName: repoFromRaw,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
finally {
|
|
81
|
-
closeHippoDb(db);
|
|
82
|
-
}
|
|
83
|
-
sendJson(res, 200, { ok: true, status: 'dlq' });
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
// Ping fires once at hook creation. Don't ingest, don't DLQ - just pong.
|
|
87
|
-
if (eventName === 'ping') {
|
|
88
|
-
sendJson(res, 200, { pong: true });
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
const ALLOWED_EVENTS = new Set([
|
|
92
|
-
'issues',
|
|
93
|
-
'issue_comment',
|
|
94
|
-
'pull_request',
|
|
95
|
-
'pull_request_review_comment',
|
|
96
|
-
]);
|
|
97
|
-
if (eventName === null || !ALLOWED_EVENTS.has(eventName)) {
|
|
98
|
-
const db = openHippoDb(opts.hippoRoot);
|
|
99
|
-
try {
|
|
100
|
-
writeToGitHubDlq(db, {
|
|
101
|
-
tenantId: resolveTenantId({}),
|
|
102
|
-
rawPayload: rawBody,
|
|
103
|
-
error: `unhandled event: ${eventName ?? '(missing X-GitHub-Event)'}`,
|
|
104
|
-
bucket: 'unhandled',
|
|
105
|
-
eventName,
|
|
106
|
-
deliveryId,
|
|
107
|
-
signature: sigStr,
|
|
108
|
-
installationId: installationFromRaw,
|
|
109
|
-
repoFullName: repoFromRaw,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
finally {
|
|
113
|
-
closeHippoDb(db);
|
|
114
|
-
}
|
|
115
|
-
sendJson(res, 200, { ok: true, status: 'dlq' });
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
let body;
|
|
54
|
+
routeSignedDelivery({ hippoRoot: opts.hippoRoot, res, rawBody, eventName, deliveryId, signature: sigStr });
|
|
55
|
+
}
|
|
56
|
+
const ALLOWED_EVENTS = new Set([
|
|
57
|
+
'issues',
|
|
58
|
+
'issue_comment',
|
|
59
|
+
'pull_request',
|
|
60
|
+
'pull_request_review_comment',
|
|
61
|
+
]);
|
|
62
|
+
function parkInDlq(d, park) {
|
|
63
|
+
const db = openHippoDb(d.hippoRoot);
|
|
119
64
|
try {
|
|
120
|
-
|
|
65
|
+
writeToGitHubDlq(db, {
|
|
66
|
+
tenantId: park.tenantId,
|
|
67
|
+
rawPayload: d.rawBody,
|
|
68
|
+
error: park.error,
|
|
69
|
+
bucket: park.bucket,
|
|
70
|
+
eventName: d.eventName,
|
|
71
|
+
deliveryId: d.deliveryId,
|
|
72
|
+
signature: d.signature,
|
|
73
|
+
installationId: park.installationId,
|
|
74
|
+
repoFullName: park.repoFullName,
|
|
75
|
+
});
|
|
121
76
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
try {
|
|
125
|
-
writeToGitHubDlq(db, {
|
|
126
|
-
tenantId: resolveTenantId({}),
|
|
127
|
-
rawPayload: rawBody,
|
|
128
|
-
error: 'invalid JSON',
|
|
129
|
-
bucket: 'parse_error',
|
|
130
|
-
eventName,
|
|
131
|
-
deliveryId,
|
|
132
|
-
signature: sigStr,
|
|
133
|
-
installationId: installationFromRaw,
|
|
134
|
-
repoFullName: repoFromRaw,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
finally {
|
|
138
|
-
closeHippoDb(db);
|
|
139
|
-
}
|
|
140
|
-
sendJson(res, 200, { ok: true, status: 'dlq' });
|
|
141
|
-
return;
|
|
77
|
+
finally {
|
|
78
|
+
closeHippoDb(db);
|
|
142
79
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
rawPayload: rawBody,
|
|
149
|
-
error: 'not a GitHub webhook envelope',
|
|
150
|
-
bucket: 'parse_error',
|
|
151
|
-
eventName,
|
|
152
|
-
deliveryId,
|
|
153
|
-
signature: sigStr,
|
|
154
|
-
installationId: installationFromRaw,
|
|
155
|
-
repoFullName: repoFromRaw,
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
finally {
|
|
159
|
-
closeHippoDb(db);
|
|
160
|
-
}
|
|
161
|
-
sendJson(res, 200, { ok: true, status: 'dlq' });
|
|
80
|
+
sendJson(d.res, 200, { ok: true, status: 'dlq' });
|
|
81
|
+
}
|
|
82
|
+
function routeSignedDelivery(d) {
|
|
83
|
+
const body = parseEnvelopeOrPark(d);
|
|
84
|
+
if (body === null || d.deliveryId === null)
|
|
162
85
|
return;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
86
|
+
const routing = {
|
|
87
|
+
installationId: body.installation?.id != null ? String(body.installation.id) : null,
|
|
88
|
+
repoFullName: body.repository?.full_name ?? null,
|
|
89
|
+
};
|
|
166
90
|
// Tenant resolution. Fail closed on multi-tenant installs with unknown
|
|
167
91
|
// routing - same policy as Slack.
|
|
168
92
|
let resolvedTenant;
|
|
169
93
|
{
|
|
170
|
-
const db = openHippoDb(
|
|
94
|
+
const db = openHippoDb(d.hippoRoot);
|
|
171
95
|
try {
|
|
172
|
-
resolvedTenant = resolveTenantForGitHub(db,
|
|
173
|
-
installationId,
|
|
174
|
-
repoFullName,
|
|
175
|
-
});
|
|
96
|
+
resolvedTenant = resolveTenantForGitHub(db, routing);
|
|
176
97
|
}
|
|
177
98
|
finally {
|
|
178
99
|
closeHippoDb(db);
|
|
179
100
|
}
|
|
180
101
|
}
|
|
181
102
|
if (resolvedTenant === null) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
bucket: 'unroutable',
|
|
189
|
-
eventName,
|
|
190
|
-
deliveryId,
|
|
191
|
-
signature: sigStr,
|
|
192
|
-
installationId,
|
|
193
|
-
repoFullName,
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
finally {
|
|
197
|
-
closeHippoDb(db);
|
|
198
|
-
}
|
|
199
|
-
sendJson(res, 200, { ok: true, status: 'dlq' });
|
|
103
|
+
parkInDlq(d, {
|
|
104
|
+
...routing,
|
|
105
|
+
tenantId: null,
|
|
106
|
+
error: `unroutable: installation_id=${routing.installationId ?? '(none)'} repo=${routing.repoFullName ?? '(none)'}`,
|
|
107
|
+
bucket: 'unroutable',
|
|
108
|
+
});
|
|
200
109
|
return;
|
|
201
110
|
}
|
|
202
111
|
const ctx = {
|
|
203
|
-
hippoRoot:
|
|
112
|
+
hippoRoot: d.hippoRoot,
|
|
113
|
+
tenantId: resolvedTenant,
|
|
114
|
+
actor: { subject: 'connector:github', role: 'admin' },
|
|
115
|
+
};
|
|
116
|
+
if (dispatchGitHubEvent(d, ctx, body, d.deliveryId, routing))
|
|
117
|
+
return;
|
|
118
|
+
// Header allow-listed but body shape didn't satisfy the matching guard.
|
|
119
|
+
parkInDlq(d, {
|
|
120
|
+
...routing,
|
|
204
121
|
tenantId: resolvedTenant,
|
|
205
|
-
|
|
122
|
+
error: `body shape did not match X-GitHub-Event=${d.eventName}`,
|
|
123
|
+
bucket: 'parse_error',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/** Answers ping and parks every unusable body; returns the envelope only when ingest should go on. */
|
|
127
|
+
function parseEnvelopeOrPark(d) {
|
|
128
|
+
// Cheap regex extraction of installation_id / repo for DLQ rows that fail
|
|
129
|
+
// to JSON.parse - gives operators something to triage.
|
|
130
|
+
const installationFromRaw = (() => {
|
|
131
|
+
const m = d.rawBody.match(/"installation"\s*:\s*\{[^}]*"id"\s*:\s*(\d+)/);
|
|
132
|
+
return m ? m[1] : null;
|
|
133
|
+
})();
|
|
134
|
+
const repoFromRaw = (() => {
|
|
135
|
+
const m = d.rawBody.match(/"full_name"\s*:\s*"([^"]+)"/);
|
|
136
|
+
return m ? m[1] : null;
|
|
137
|
+
})();
|
|
138
|
+
const parkRaw = (error, bucket) => {
|
|
139
|
+
parkInDlq(d, {
|
|
140
|
+
tenantId: resolveTenantId({}),
|
|
141
|
+
error,
|
|
142
|
+
bucket,
|
|
143
|
+
installationId: installationFromRaw,
|
|
144
|
+
repoFullName: repoFromRaw,
|
|
145
|
+
});
|
|
146
|
+
return null;
|
|
147
|
+
};
|
|
148
|
+
// Body was signed but caller omitted the audit header. Park.
|
|
149
|
+
if (d.deliveryId === null)
|
|
150
|
+
return parkRaw('missing X-GitHub-Delivery header', 'parse_error');
|
|
151
|
+
// Ping fires once at hook creation. Don't ingest, don't DLQ - just pong.
|
|
152
|
+
if (d.eventName === 'ping') {
|
|
153
|
+
sendJson(d.res, 200, { pong: true });
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
if (d.eventName === null || !ALLOWED_EVENTS.has(d.eventName)) {
|
|
157
|
+
return parkRaw(`unhandled event: ${d.eventName ?? '(missing X-GitHub-Event)'}`, 'unhandled');
|
|
158
|
+
}
|
|
159
|
+
let body;
|
|
160
|
+
try {
|
|
161
|
+
body = JSON.parse(d.rawBody);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return parkRaw('invalid JSON', 'parse_error');
|
|
165
|
+
}
|
|
166
|
+
if (body === undefined || !isGitHubWebhookEnvelope(body)) {
|
|
167
|
+
return parkRaw('not a GitHub webhook envelope', 'parse_error');
|
|
168
|
+
}
|
|
169
|
+
return body;
|
|
170
|
+
}
|
|
171
|
+
/** Ingests, archives or parks by event header; false when no guard matched the body. */
|
|
172
|
+
function dispatchGitHubEvent(d, ctx, body, deliveryId, routing) {
|
|
173
|
+
const { res, rawBody, eventName } = d;
|
|
174
|
+
const ingest = (event) => {
|
|
175
|
+
const r = ingestGitHubEvent(ctx, { event, rawBody, deliveryId });
|
|
176
|
+
sendJson(res, 200, { ok: true, status: r.status, memoryId: r.memoryId });
|
|
177
|
+
return true;
|
|
178
|
+
};
|
|
179
|
+
const archiveComment = (event, artifactRef, updatedAt) => {
|
|
180
|
+
// The "deleted:" key namespace keeps this from colliding with the ingest key for the
|
|
181
|
+
// same artifact; a shared key would make hasSeenKey skip the archive.
|
|
182
|
+
const idempotencyKey = computeGitHubDeletionKey(artifactRef, updatedAt);
|
|
183
|
+
const r = handleGitHubCommentDeleted(ctx, {
|
|
184
|
+
artifactRef,
|
|
185
|
+
idempotencyKey,
|
|
186
|
+
deliveryId,
|
|
187
|
+
eventName: event,
|
|
188
|
+
});
|
|
189
|
+
sendJson(res, 200, { ok: true, status: r.status, archivedCount: r.archivedCount });
|
|
190
|
+
return true;
|
|
206
191
|
};
|
|
207
192
|
// Dispatch by event header. Type guards cross-check the body shape against
|
|
208
193
|
// the header so a payload of one event type cannot satisfy another's guard.
|
|
@@ -211,57 +196,26 @@ export async function handleGitHubEventsWebhook({ req, res, opts }) {
|
|
|
211
196
|
// GitHub does fire issues.deleted (admin-initiated). Don't archive - V1
|
|
212
197
|
// policy is to log and let an operator decide. Archive could lose the
|
|
213
198
|
// memory if the issue is being moved between accounts.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
eventName,
|
|
222
|
-
deliveryId,
|
|
223
|
-
signature: sigStr,
|
|
224
|
-
installationId,
|
|
225
|
-
repoFullName,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
finally {
|
|
229
|
-
closeHippoDb(db);
|
|
230
|
-
}
|
|
231
|
-
sendJson(res, 200, { ok: true, status: 'dlq' });
|
|
232
|
-
return;
|
|
199
|
+
parkInDlq(d, {
|
|
200
|
+
...routing,
|
|
201
|
+
tenantId: ctx.tenantId,
|
|
202
|
+
error: 'issues.deleted requires manual review',
|
|
203
|
+
bucket: 'unhandled',
|
|
204
|
+
});
|
|
205
|
+
return true;
|
|
233
206
|
}
|
|
234
|
-
|
|
235
|
-
const r = ingestGitHubEvent(ctx, { event: ingestInput, rawBody, deliveryId });
|
|
236
|
-
sendJson(res, 200, { ok: true, status: r.status, memoryId: r.memoryId });
|
|
237
|
-
return;
|
|
207
|
+
return ingest({ eventName: 'issues', payload: body });
|
|
238
208
|
}
|
|
239
209
|
if (eventName === 'issue_comment' && isGitHubIssueCommentEvent(body, 'issue_comment')) {
|
|
240
210
|
if (body.action === 'deleted') {
|
|
241
211
|
const repo = body.repository?.full_name ?? '';
|
|
242
212
|
const artifactRef = `github://${repo}/issue/${body.issue.number}/comment/${body.comment.id}`;
|
|
243
|
-
|
|
244
|
-
// same artifact; a shared key would make hasSeenKey skip the archive.
|
|
245
|
-
const idempotencyKey = computeGitHubDeletionKey(artifactRef, body.comment.updated_at ?? null);
|
|
246
|
-
const r = handleGitHubCommentDeleted(ctx, {
|
|
247
|
-
artifactRef,
|
|
248
|
-
idempotencyKey,
|
|
249
|
-
deliveryId,
|
|
250
|
-
eventName,
|
|
251
|
-
});
|
|
252
|
-
sendJson(res, 200, { ok: true, status: r.status, archivedCount: r.archivedCount });
|
|
253
|
-
return;
|
|
213
|
+
return archiveComment(eventName, artifactRef, body.comment.updated_at ?? null);
|
|
254
214
|
}
|
|
255
|
-
|
|
256
|
-
const r = ingestGitHubEvent(ctx, { event: ingestInput, rawBody, deliveryId });
|
|
257
|
-
sendJson(res, 200, { ok: true, status: r.status, memoryId: r.memoryId });
|
|
258
|
-
return;
|
|
215
|
+
return ingest({ eventName: 'issue_comment', payload: body });
|
|
259
216
|
}
|
|
260
217
|
if (eventName === 'pull_request' && isGitHubPullRequestEvent(body, 'pull_request')) {
|
|
261
|
-
|
|
262
|
-
const r = ingestGitHubEvent(ctx, { event: ingestInput, rawBody, deliveryId });
|
|
263
|
-
sendJson(res, 200, { ok: true, status: r.status, memoryId: r.memoryId });
|
|
264
|
-
return;
|
|
218
|
+
return ingest({ eventName: 'pull_request', payload: body });
|
|
265
219
|
}
|
|
266
220
|
if (eventName === 'pull_request_review_comment' &&
|
|
267
221
|
isGitHubPullRequestReviewCommentEvent(body, 'pull_request_review_comment')) {
|
|
@@ -269,45 +223,10 @@ export async function handleGitHubEventsWebhook({ req, res, opts }) {
|
|
|
269
223
|
const repo = body.repository?.full_name ?? '';
|
|
270
224
|
const artifactRef = `github://${repo}/pull/${body.pull_request.number}/review_comment/${body.comment.id}`;
|
|
271
225
|
// Same "deleted:" key namespace as the issue_comment branch above.
|
|
272
|
-
|
|
273
|
-
const r = handleGitHubCommentDeleted(ctx, {
|
|
274
|
-
artifactRef,
|
|
275
|
-
idempotencyKey,
|
|
276
|
-
deliveryId,
|
|
277
|
-
eventName,
|
|
278
|
-
});
|
|
279
|
-
sendJson(res, 200, { ok: true, status: r.status, archivedCount: r.archivedCount });
|
|
280
|
-
return;
|
|
226
|
+
return archiveComment(eventName, artifactRef, body.comment.updated_at ?? null);
|
|
281
227
|
}
|
|
282
|
-
|
|
283
|
-
eventName: 'pull_request_review_comment',
|
|
284
|
-
payload: body,
|
|
285
|
-
};
|
|
286
|
-
const r = ingestGitHubEvent(ctx, { event: ingestInput, rawBody, deliveryId });
|
|
287
|
-
sendJson(res, 200, { ok: true, status: r.status, memoryId: r.memoryId });
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
// Header allow-listed but body shape didn't satisfy the matching guard.
|
|
291
|
-
{
|
|
292
|
-
const db = openHippoDb(opts.hippoRoot);
|
|
293
|
-
try {
|
|
294
|
-
writeToGitHubDlq(db, {
|
|
295
|
-
tenantId: resolvedTenant,
|
|
296
|
-
rawPayload: rawBody,
|
|
297
|
-
error: `body shape did not match X-GitHub-Event=${eventName}`,
|
|
298
|
-
bucket: 'parse_error',
|
|
299
|
-
eventName,
|
|
300
|
-
deliveryId,
|
|
301
|
-
signature: sigStr,
|
|
302
|
-
installationId,
|
|
303
|
-
repoFullName,
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
finally {
|
|
307
|
-
closeHippoDb(db);
|
|
308
|
-
}
|
|
309
|
-
sendJson(res, 200, { ok: true, status: 'dlq' });
|
|
310
|
-
return;
|
|
228
|
+
return ingest({ eventName: 'pull_request_review_comment', payload: body });
|
|
311
229
|
}
|
|
230
|
+
return false;
|
|
312
231
|
}
|
|
313
232
|
//# sourceMappingURL=webhook.js.map
|
|
@@ -93,35 +93,9 @@ export function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
93
93
|
}
|
|
94
94
|
// Signature verification (current secret, not previous).
|
|
95
95
|
if (!opts.force) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
status: 'sig_missing',
|
|
100
|
-
memoryId: null,
|
|
101
|
-
retryCount: row.retryCount,
|
|
102
|
-
reason: 'row has no signature/timestamp (legacy, or redacted before storing); pass --force to replay',
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
if (opts.signingSecret) {
|
|
106
|
-
const ok = verifySlackSignature({
|
|
107
|
-
rawBody: row.rawPayload,
|
|
108
|
-
signature: row.signature,
|
|
109
|
-
timestamp: row.slackTimestamp,
|
|
110
|
-
signingSecret: opts.signingSecret,
|
|
111
|
-
now: opts.now,
|
|
112
|
-
// Replays happen long after the fact — give them a wider skew unless overridden.
|
|
113
|
-
skewSeconds: opts.skewSeconds ?? 60 * 60 * 24 * 365,
|
|
114
|
-
});
|
|
115
|
-
if (!ok) {
|
|
116
|
-
return {
|
|
117
|
-
ok: false,
|
|
118
|
-
status: 'sig_fail',
|
|
119
|
-
memoryId: null,
|
|
120
|
-
retryCount: row.retryCount,
|
|
121
|
-
reason: 'signature did not verify against current SLACK_SIGNING_SECRET; pass --force to replay anyway',
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
96
|
+
const sigFailure = checkReplaySignature(row, opts);
|
|
97
|
+
if (sigFailure)
|
|
98
|
+
return sigFailure;
|
|
125
99
|
}
|
|
126
100
|
// Parse + dispatch.
|
|
127
101
|
let parsed;
|
|
@@ -129,24 +103,10 @@ export function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
129
103
|
parsed = JSON.parse(row.rawPayload);
|
|
130
104
|
}
|
|
131
105
|
catch (e) {
|
|
132
|
-
|
|
133
|
-
return {
|
|
134
|
-
ok: false,
|
|
135
|
-
status: 'parse_error',
|
|
136
|
-
memoryId: null,
|
|
137
|
-
retryCount: row.retryCount + 1,
|
|
138
|
-
reason: `still unparseable: ${e instanceof Error ? e.message : String(e)}`,
|
|
139
|
-
};
|
|
106
|
+
return failAndBump(ctx.hippoRoot, row, 'parse_error', `still unparseable: ${e instanceof Error ? e.message : String(e)}`);
|
|
140
107
|
}
|
|
141
108
|
if (!isSlackEventEnvelope(parsed)) {
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
ok: false,
|
|
145
|
-
status: 'unhandled',
|
|
146
|
-
memoryId: null,
|
|
147
|
-
retryCount: row.retryCount + 1,
|
|
148
|
-
reason: 'not an event_callback envelope',
|
|
149
|
-
};
|
|
109
|
+
return failAndBump(ctx.hippoRoot, row, 'unhandled', 'not an event_callback envelope');
|
|
150
110
|
}
|
|
151
111
|
// Resolve tenant against current state. If still unroutable, bail.
|
|
152
112
|
const db2 = openHippoDb(ctx.hippoRoot);
|
|
@@ -158,31 +118,59 @@ export function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
158
118
|
closeHippoDb(db2);
|
|
159
119
|
}
|
|
160
120
|
if (!tenant) {
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
ok: false,
|
|
164
|
-
status: 'unroutable',
|
|
165
|
-
memoryId: null,
|
|
166
|
-
retryCount: row.retryCount + 1,
|
|
167
|
-
reason: `team_id ${parsed.team_id} still unroutable`,
|
|
168
|
-
};
|
|
121
|
+
return failAndBump(ctx.hippoRoot, row, 'unroutable', `team_id ${parsed.team_id} still unroutable`);
|
|
169
122
|
}
|
|
170
123
|
const replayCtx = {
|
|
171
124
|
hippoRoot: ctx.hippoRoot,
|
|
172
125
|
tenantId: tenant,
|
|
173
126
|
actor: adminActor('connector:slack:replay'),
|
|
174
127
|
};
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
128
|
+
return dispatchReplay(replayCtx, row, parsed);
|
|
129
|
+
}
|
|
130
|
+
/** The failure result when the row cannot pass the signature gate, else null; never bumps the count. */
|
|
131
|
+
function checkReplaySignature(row, opts) {
|
|
132
|
+
if (!row.signature || !row.slackTimestamp) {
|
|
178
133
|
return {
|
|
179
134
|
ok: false,
|
|
180
|
-
status: '
|
|
135
|
+
status: 'sig_missing',
|
|
181
136
|
memoryId: null,
|
|
182
|
-
retryCount: row.retryCount
|
|
183
|
-
reason:
|
|
137
|
+
retryCount: row.retryCount,
|
|
138
|
+
reason: 'row has no signature/timestamp (legacy, or redacted before storing); pass --force to replay',
|
|
184
139
|
};
|
|
185
140
|
}
|
|
141
|
+
if (opts.signingSecret) {
|
|
142
|
+
const ok = verifySlackSignature({
|
|
143
|
+
rawBody: row.rawPayload,
|
|
144
|
+
signature: row.signature,
|
|
145
|
+
timestamp: row.slackTimestamp,
|
|
146
|
+
signingSecret: opts.signingSecret,
|
|
147
|
+
now: opts.now,
|
|
148
|
+
// Replays happen long after the fact — give them a wider skew unless overridden.
|
|
149
|
+
skewSeconds: opts.skewSeconds ?? 60 * 60 * 24 * 365,
|
|
150
|
+
});
|
|
151
|
+
if (!ok) {
|
|
152
|
+
return {
|
|
153
|
+
ok: false,
|
|
154
|
+
status: 'sig_fail',
|
|
155
|
+
memoryId: null,
|
|
156
|
+
retryCount: row.retryCount,
|
|
157
|
+
reason: 'signature did not verify against current SLACK_SIGNING_SECRET; pass --force to replay anyway',
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
function failAndBump(hippoRoot, row, status, reason) {
|
|
164
|
+
bumpRetryCount(hippoRoot, row.id);
|
|
165
|
+
return { ok: false, status, memoryId: null, retryCount: row.retryCount + 1, reason };
|
|
166
|
+
}
|
|
167
|
+
function dispatchReplay(replayCtx, row, parsed) {
|
|
168
|
+
const { hippoRoot } = replayCtx;
|
|
169
|
+
const id = row.id;
|
|
170
|
+
const inner = parsed.event;
|
|
171
|
+
if (!isSlackMessageEvent(inner)) {
|
|
172
|
+
return failAndBump(hippoRoot, row, 'unhandled', `unhandled inner event type`);
|
|
173
|
+
}
|
|
186
174
|
if (inner.subtype === 'message_deleted' && inner.deleted_ts) {
|
|
187
175
|
const r = handleMessageDeleted(replayCtx, {
|
|
188
176
|
teamId: parsed.team_id,
|
|
@@ -190,7 +178,7 @@ export function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
190
178
|
deletedTs: inner.deleted_ts,
|
|
191
179
|
eventId: parsed.event_id,
|
|
192
180
|
});
|
|
193
|
-
markRetried(
|
|
181
|
+
markRetried(hippoRoot, id);
|
|
194
182
|
return { ok: true, status: r.status, memoryId: r.memoryId, retryCount: row.retryCount + 1 };
|
|
195
183
|
}
|
|
196
184
|
const result = ingestMessage(replayCtx, {
|
|
@@ -204,7 +192,7 @@ export function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
204
192
|
message: inner,
|
|
205
193
|
eventId: parsed.event_id,
|
|
206
194
|
});
|
|
207
|
-
markRetried(
|
|
195
|
+
markRetried(hippoRoot, id);
|
|
208
196
|
return { ok: true, status: result.status, memoryId: result.memoryId, retryCount: row.retryCount + 1 };
|
|
209
197
|
}
|
|
210
198
|
function markRetried(hippoRoot, id) {
|