hippo-memory 1.60.0 → 1.61.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 +1 -1
- package/dist/ablation.js +9 -27
- package/dist/agent-memories/apply.js +4 -1
- package/dist/agent-memories/claude-code.js +1 -1
- 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.js +8 -3
- 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 +152 -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-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 +705 -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 +123 -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 +203 -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 +634 -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 +271 -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 +435 -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 +366 -0
- package/dist/cli/continuity.d.ts +6 -0
- package/dist/cli/continuity.js +445 -0
- package/dist/cli/curate.d.ts +19 -0
- package/dist/cli/curate.js +555 -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 +150 -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 +179 -0
- package/dist/cli/playbooks.d.ts +4 -0
- package/dist/cli/playbooks.js +556 -0
- package/dist/cli/projects.js +1 -1
- package/dist/cli/recall.d.ts +7 -0
- package/dist/cli/recall.js +597 -0
- package/dist/cli/remember.d.ts +5 -0
- package/dist/cli/remember.js +442 -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 +637 -0
- package/dist/cli/setup.d.ts +4 -0
- package/dist/cli/setup.js +376 -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 +400 -0
- package/dist/cli/transfer.d.ts +10 -0
- package/dist/cli/transfer.js +438 -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.js +6 -4
- 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 +6 -4
- package/dist/dag.js +6 -5
- 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 +9 -7
- package/dist/dedupe.js +3 -2
- package/dist/delivery-recorder.js +4 -1
- package/dist/doctor.js +3 -3
- 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 +18 -0
- 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 +7 -5
- 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 +8 -6
- 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 +7 -5
- package/dist/project-briefs.d.ts +3 -0
- package/dist/project-briefs.js +7 -5
- package/dist/project-identity.js +3 -2
- package/dist/project-merge.js +3 -1
- 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 +3 -1
- package/dist/shared.js +26 -22
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +7 -5
- 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 +254 -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
package/dist/client.js
CHANGED
|
@@ -13,8 +13,19 @@
|
|
|
13
13
|
* Network errors (ECONNREFUSED on a stale pidfile, etc.) propagate as the
|
|
14
14
|
* native fetch failure so the caller can detect them and self-heal.
|
|
15
15
|
*/
|
|
16
|
+
import { fetchWithRetry } from './http-retry.js';
|
|
16
17
|
/** A write the local server has not answered in this long is stuck; the caller treats it as delivery-unknown. */
|
|
17
18
|
const SERVER_TIMEOUT_MS = 30_000;
|
|
19
|
+
/** Five tries at the server's 1 s Retry-After keeps the roughly 5 s wait the CLI had before the server answered busy with 503. */
|
|
20
|
+
const STORE_BUSY_ATTEMPTS = 5;
|
|
21
|
+
/** The server sets Retry-After on a 503 only for a held write lock (server.ts replyFor); the auth-provider 503 has none. */
|
|
22
|
+
function isStoreBusy(res) {
|
|
23
|
+
return res.status === 503 && res.headers.has('retry-after');
|
|
24
|
+
}
|
|
25
|
+
/** Replaying is safe because each routed write commits in one transaction and anything after it is best-effort, so a busy 503 means nothing landed. */
|
|
26
|
+
function sendWrite(url, init) {
|
|
27
|
+
return fetchWithRetry(url, init, { timeoutMs: SERVER_TIMEOUT_MS, attempts: STORE_BUSY_ATTEMPTS, retryOn: isStoreBusy });
|
|
28
|
+
}
|
|
18
29
|
function buildHeaders(apiKey, withBody) {
|
|
19
30
|
const headers = {};
|
|
20
31
|
if (withBody)
|
|
@@ -57,10 +68,9 @@ async function throwForStatus(res) {
|
|
|
57
68
|
throw new HttpResponseError(message, res.status);
|
|
58
69
|
}
|
|
59
70
|
export async function remember(serverUrl, apiKey, opts) {
|
|
60
|
-
const res = await
|
|
71
|
+
const res = await sendWrite(`${serverUrl}/v1/memories`, {
|
|
61
72
|
method: 'POST',
|
|
62
73
|
headers: buildHeaders(apiKey, true),
|
|
63
|
-
signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),
|
|
64
74
|
body: JSON.stringify(opts),
|
|
65
75
|
});
|
|
66
76
|
if (!res.ok)
|
|
@@ -69,10 +79,9 @@ export async function remember(serverUrl, apiKey, opts) {
|
|
|
69
79
|
return result;
|
|
70
80
|
}
|
|
71
81
|
export async function forget(serverUrl, apiKey, id) {
|
|
72
|
-
const res = await
|
|
82
|
+
const res = await sendWrite(`${serverUrl}/v1/memories/${encodeURIComponent(id)}`, {
|
|
73
83
|
method: 'DELETE',
|
|
74
84
|
headers: buildHeaders(apiKey, false),
|
|
75
|
-
signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),
|
|
76
85
|
});
|
|
77
86
|
if (!res.ok)
|
|
78
87
|
await throwForStatus(res);
|
|
@@ -80,10 +89,9 @@ export async function forget(serverUrl, apiKey, id) {
|
|
|
80
89
|
return result;
|
|
81
90
|
}
|
|
82
91
|
export async function promote(serverUrl, apiKey, id) {
|
|
83
|
-
const res = await
|
|
92
|
+
const res = await sendWrite(`${serverUrl}/v1/memories/${encodeURIComponent(id)}/promote`, {
|
|
84
93
|
method: 'POST',
|
|
85
94
|
headers: buildHeaders(apiKey, false),
|
|
86
|
-
signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),
|
|
87
95
|
});
|
|
88
96
|
if (!res.ok)
|
|
89
97
|
await throwForStatus(res);
|
|
@@ -91,10 +99,9 @@ export async function promote(serverUrl, apiKey, id) {
|
|
|
91
99
|
return result;
|
|
92
100
|
}
|
|
93
101
|
export async function archiveRaw(serverUrl, apiKey, id, reason) {
|
|
94
|
-
const res = await
|
|
102
|
+
const res = await sendWrite(`${serverUrl}/v1/memories/${encodeURIComponent(id)}/archive`, {
|
|
95
103
|
method: 'POST',
|
|
96
104
|
headers: buildHeaders(apiKey, true),
|
|
97
|
-
signal: AbortSignal.timeout(SERVER_TIMEOUT_MS),
|
|
98
105
|
body: JSON.stringify({ reason }),
|
|
99
106
|
});
|
|
100
107
|
if (!res.ok)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// One record per Claude Code compaction, and what turns its summary into kept memories.
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
-
import { errorMessage, readTranscriptTail, truncateCodePointSafe } from './capture.js';
|
|
5
4
|
import { isObjectLike, isStringValue } from './capture-contract.js';
|
|
6
5
|
import { compactSummaryBody, parseCompactionItems, selectItemRows } from './compaction-items.js';
|
|
7
6
|
import { loadConfig } from './config.js';
|
|
@@ -10,9 +9,12 @@ import { gatedWrite } from './gated-write.js';
|
|
|
10
9
|
import { COMPACTION_MEMORY_TAG, COMPACTION_SOURCE_PREFIX, Layer, createMemory, generateId } from './memory.js';
|
|
11
10
|
import { deriveOriginProject, isGlobalStoreRoot } from './project-identity.js';
|
|
12
11
|
import { maskEmails, redactSecretsStrict } from './secret-detect.js';
|
|
13
|
-
import { strengthenRetrievedOn,
|
|
12
|
+
import { strengthenRetrievedOn, writeEntryMirrors } from './store/entry-writes.js';
|
|
13
|
+
import { isRecallBoostAblated } from './ablation.js';
|
|
14
|
+
import { updateStats } from './store/index-and-stats.js';
|
|
14
15
|
import { resolveTenantId } from './tenant.js';
|
|
15
|
-
import { log as logger } from './log.js';
|
|
16
|
+
import { errorMessage, log as logger } from './log.js';
|
|
17
|
+
import { readTranscriptTail, truncateCodePointSafe } from './transcript-tail.js';
|
|
16
18
|
/** PostCompact has 10 s in all (PreCompact 30 s), so a locked store must be given up on early. */
|
|
17
19
|
export const COMPACTION_DB_WAIT_MS = 2000;
|
|
18
20
|
/** Tested verbatim: Claude Code hands PreCompact stdout to the summariser as instructions. */
|
|
@@ -226,7 +228,7 @@ export function saveItems(db, hippoRoot, ctx, log) {
|
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
230
|
// Said again by another session is the same signal as being recalled; the same session carrying it forward is not.
|
|
229
|
-
strengthenRetrievedOn(db, [...restated], ctx.tenantId);
|
|
231
|
+
strengthenRetrievedOn(db, [...restated], { tenantId: ctx.tenantId, recallBoostAblated: isRecallBoostAblated() });
|
|
230
232
|
if (ctx.recordId !== null) {
|
|
231
233
|
db.prepare(`UPDATE compactions SET items_written = ?, status = 'done' WHERE tenant_id = ? AND id = ?`).run(written.length, ctx.tenantId, ctx.recordId);
|
|
232
234
|
}
|
|
@@ -172,6 +172,82 @@ async function drainStream(ctx, url0, toIngestEvent, fetcher, token, sleep, maxI
|
|
|
172
172
|
}
|
|
173
173
|
return { ingested, pages, maxUpdatedAt, drained: true };
|
|
174
174
|
}
|
|
175
|
+
function issueItemToEvent(item, repository) {
|
|
176
|
+
if (!isIssuesItem(item))
|
|
177
|
+
return null;
|
|
178
|
+
// Codex P1 #2: /issues returns PRs too — skip them.
|
|
179
|
+
if (item.pull_request)
|
|
180
|
+
return null;
|
|
181
|
+
const payload = {
|
|
182
|
+
action: 'opened',
|
|
183
|
+
repository,
|
|
184
|
+
issue: {
|
|
185
|
+
number: item.number,
|
|
186
|
+
title: item.title,
|
|
187
|
+
body: item.body ?? null,
|
|
188
|
+
user: { login: item.user.login, id: item.user.id },
|
|
189
|
+
updated_at: item.updated_at,
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
return { eventName: 'issues', payload };
|
|
193
|
+
}
|
|
194
|
+
function issueCommentItemToEvent(item, repository) {
|
|
195
|
+
if (!isCommentItem(item))
|
|
196
|
+
return null;
|
|
197
|
+
// SAFETY: this closure only runs against the /issues/comments stream,
|
|
198
|
+
// so every item isCommentItem validates here is genuinely an
|
|
199
|
+
// IssueCommentItem; a missing issue_url is handled defensively below.
|
|
200
|
+
const c = item;
|
|
201
|
+
const issueNumber = parseTrailingNumber(c.issue_url);
|
|
202
|
+
if (issueNumber === null)
|
|
203
|
+
return null;
|
|
204
|
+
const payload = {
|
|
205
|
+
action: 'created',
|
|
206
|
+
repository,
|
|
207
|
+
issue: { number: issueNumber },
|
|
208
|
+
comment: {
|
|
209
|
+
id: c.id,
|
|
210
|
+
body: c.body ?? null,
|
|
211
|
+
user: { login: c.user.login, id: c.user.id },
|
|
212
|
+
updated_at: c.updated_at,
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
return { eventName: 'issue_comment', payload };
|
|
216
|
+
}
|
|
217
|
+
function prReviewCommentItemToEvent(item, repository) {
|
|
218
|
+
if (!isCommentItem(item))
|
|
219
|
+
return null;
|
|
220
|
+
// SAFETY: this closure only runs against the /pulls/comments stream,
|
|
221
|
+
// so every item isCommentItem validates here is genuinely a
|
|
222
|
+
// PrReviewCommentItem; a missing pull_request_url is handled below.
|
|
223
|
+
const c = item;
|
|
224
|
+
const prNumber = parseTrailingNumber(c.pull_request_url);
|
|
225
|
+
if (prNumber === null)
|
|
226
|
+
return null;
|
|
227
|
+
const payload = {
|
|
228
|
+
action: 'created',
|
|
229
|
+
repository,
|
|
230
|
+
pull_request: { number: prNumber },
|
|
231
|
+
comment: {
|
|
232
|
+
id: c.id,
|
|
233
|
+
body: c.body ?? null,
|
|
234
|
+
user: { login: c.user.login, id: c.user.id },
|
|
235
|
+
updated_at: c.updated_at,
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
return { eventName: 'pull_request_review_comment', payload };
|
|
239
|
+
}
|
|
240
|
+
/** Drains one stream, then persists its HWM only when the stream ran to the end. */
|
|
241
|
+
async function backfillStream(ctx, opts, sleep, stream) {
|
|
242
|
+
const res = await drainStream(ctx, stream.url, stream.toIngestEvent, opts.fetcher, opts.token, sleep, opts.maxPerStream);
|
|
243
|
+
// v1.3.1: only advance HWM when the stream actually drained. A capped run
|
|
244
|
+
// (--max) must leave the HWM at its previous value so the next invocation
|
|
245
|
+
// re-fetches the unprocessed tail.
|
|
246
|
+
if (res.drained && res.maxUpdatedAt) {
|
|
247
|
+
writeOneHwm(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, stream.column, res.maxUpdatedAt);
|
|
248
|
+
}
|
|
249
|
+
return { ingested: res.ingested, pages: res.pages };
|
|
250
|
+
}
|
|
175
251
|
export async function backfillRepo(ctx, opts) {
|
|
176
252
|
const sleep = opts.sleepMs ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
177
253
|
const cursors = readCursor(ctx.hippoRoot, ctx.tenantId, opts.repoFullName);
|
|
@@ -181,101 +257,32 @@ export async function backfillRepo(ctx, opts) {
|
|
|
181
257
|
pages: { issues: 0, issueComments: 0, prReviewComments: 0 },
|
|
182
258
|
};
|
|
183
259
|
// ---------- Stream 1: issues (skip PRs) ----------
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (item.pull_request)
|
|
191
|
-
return null;
|
|
192
|
-
const payload = {
|
|
193
|
-
action: 'opened',
|
|
194
|
-
repository,
|
|
195
|
-
issue: {
|
|
196
|
-
number: item.number,
|
|
197
|
-
title: item.title,
|
|
198
|
-
body: item.body ?? null,
|
|
199
|
-
user: { login: item.user.login, id: item.user.id },
|
|
200
|
-
updated_at: item.updated_at,
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
|
-
return { eventName: 'issues', payload };
|
|
204
|
-
}, opts.fetcher, opts.token, sleep, opts.maxPerStream);
|
|
260
|
+
const issuesRes = await backfillStream(ctx, opts, sleep, {
|
|
261
|
+
url: `${API}/repos/${opts.repoFullName}/issues?state=all&per_page=100` +
|
|
262
|
+
(cursors.issues ? `&since=${encodeURIComponent(cursors.issues)}` : ''),
|
|
263
|
+
column: 'issues_hwm',
|
|
264
|
+
toIngestEvent: (item) => issueItemToEvent(item, repository),
|
|
265
|
+
});
|
|
205
266
|
result.ingested.issues = issuesRes.ingested;
|
|
206
267
|
result.pages.issues = issuesRes.pages;
|
|
207
|
-
// v1.3.1: only advance HWM when the stream actually drained. A capped run
|
|
208
|
-
// (--max) must leave the HWM at its previous value so the next invocation
|
|
209
|
-
// re-fetches the unprocessed tail.
|
|
210
|
-
if (issuesRes.drained && issuesRes.maxUpdatedAt) {
|
|
211
|
-
writeOneHwm(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, 'issues_hwm', issuesRes.maxUpdatedAt);
|
|
212
|
-
}
|
|
213
268
|
// ---------- Stream 2: repo-level issue comments ----------
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
? `&since=${encodeURIComponent(cursors.issueComments)}`
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return null;
|
|
221
|
-
// SAFETY: this closure only runs against the /issues/comments stream,
|
|
222
|
-
// so every item isCommentItem validates here is genuinely an
|
|
223
|
-
// IssueCommentItem; a missing issue_url is handled defensively below.
|
|
224
|
-
const c = item;
|
|
225
|
-
const issueNumber = parseTrailingNumber(c.issue_url);
|
|
226
|
-
if (issueNumber === null)
|
|
227
|
-
return null;
|
|
228
|
-
const payload = {
|
|
229
|
-
action: 'created',
|
|
230
|
-
repository,
|
|
231
|
-
issue: { number: issueNumber },
|
|
232
|
-
comment: {
|
|
233
|
-
id: c.id,
|
|
234
|
-
body: c.body ?? null,
|
|
235
|
-
user: { login: c.user.login, id: c.user.id },
|
|
236
|
-
updated_at: c.updated_at,
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
return { eventName: 'issue_comment', payload };
|
|
240
|
-
}, opts.fetcher, opts.token, sleep, opts.maxPerStream);
|
|
269
|
+
const commentsRes = await backfillStream(ctx, opts, sleep, {
|
|
270
|
+
url: `${API}/repos/${opts.repoFullName}/issues/comments?per_page=100` +
|
|
271
|
+
(cursors.issueComments ? `&since=${encodeURIComponent(cursors.issueComments)}` : ''),
|
|
272
|
+
column: 'issue_comments_hwm',
|
|
273
|
+
toIngestEvent: (item) => issueCommentItemToEvent(item, repository),
|
|
274
|
+
});
|
|
241
275
|
result.ingested.issueComments = commentsRes.ingested;
|
|
242
276
|
result.pages.issueComments = commentsRes.pages;
|
|
243
|
-
if (commentsRes.drained && commentsRes.maxUpdatedAt) {
|
|
244
|
-
writeOneHwm(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, 'issue_comments_hwm', commentsRes.maxUpdatedAt);
|
|
245
|
-
}
|
|
246
277
|
// ---------- Stream 3: repo-level PR review comments ----------
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
? `&since=${encodeURIComponent(cursors.prReviewComments)}`
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
return null;
|
|
254
|
-
// SAFETY: this closure only runs against the /pulls/comments stream,
|
|
255
|
-
// so every item isCommentItem validates here is genuinely a
|
|
256
|
-
// PrReviewCommentItem; a missing pull_request_url is handled below.
|
|
257
|
-
const c = item;
|
|
258
|
-
const prNumber = parseTrailingNumber(c.pull_request_url);
|
|
259
|
-
if (prNumber === null)
|
|
260
|
-
return null;
|
|
261
|
-
const payload = {
|
|
262
|
-
action: 'created',
|
|
263
|
-
repository,
|
|
264
|
-
pull_request: { number: prNumber },
|
|
265
|
-
comment: {
|
|
266
|
-
id: c.id,
|
|
267
|
-
body: c.body ?? null,
|
|
268
|
-
user: { login: c.user.login, id: c.user.id },
|
|
269
|
-
updated_at: c.updated_at,
|
|
270
|
-
},
|
|
271
|
-
};
|
|
272
|
-
return { eventName: 'pull_request_review_comment', payload };
|
|
273
|
-
}, opts.fetcher, opts.token, sleep, opts.maxPerStream);
|
|
278
|
+
const prCommentsRes = await backfillStream(ctx, opts, sleep, {
|
|
279
|
+
url: `${API}/repos/${opts.repoFullName}/pulls/comments?per_page=100` +
|
|
280
|
+
(cursors.prReviewComments ? `&since=${encodeURIComponent(cursors.prReviewComments)}` : ''),
|
|
281
|
+
column: 'pr_review_comments_hwm',
|
|
282
|
+
toIngestEvent: (item) => prReviewCommentItemToEvent(item, repository),
|
|
283
|
+
});
|
|
274
284
|
result.ingested.prReviewComments = prCommentsRes.ingested;
|
|
275
285
|
result.pages.prReviewComments = prCommentsRes.pages;
|
|
276
|
-
if (prCommentsRes.drained && prCommentsRes.maxUpdatedAt) {
|
|
277
|
-
writeOneHwm(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, 'pr_review_comments_hwm', prCommentsRes.maxUpdatedAt);
|
|
278
|
-
}
|
|
279
286
|
return result;
|
|
280
287
|
}
|
|
281
288
|
//# sourceMappingURL=backfill.js.map
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - hippo github dlq list
|
|
10
10
|
* - hippo github dlq replay <id> [--force]
|
|
11
11
|
*/
|
|
12
|
+
import { envGithubToken, envGithubWebhookSecret, envGithubWebhookSecretPrevious } from '../../env.js';
|
|
12
13
|
import { adminActor } from '../../api.js';
|
|
13
14
|
import { openHippoDb, closeHippoDb } from '../../db.js';
|
|
14
15
|
import { resolveTenantId } from '../../tenant.js';
|
|
@@ -70,7 +71,7 @@ export async function cmdGithubBackfill(hippoRoot, flags, fetcher = realGitHubFe
|
|
|
70
71
|
printGithubBackfillUsage();
|
|
71
72
|
process.exit(2);
|
|
72
73
|
}
|
|
73
|
-
const token =
|
|
74
|
+
const token = envGithubToken();
|
|
74
75
|
if (!token) {
|
|
75
76
|
console.error('GITHUB_TOKEN is not set. Backfill requires a personal access token with repo read scope.');
|
|
76
77
|
process.exit(2);
|
|
@@ -166,8 +167,8 @@ export async function cmdGithubDlqReplay(hippoRoot, args, flags) {
|
|
|
166
167
|
// real hook so `replay` actually re-runs the ingest path.
|
|
167
168
|
const result = await replayDlqEntry(ctx, id, {
|
|
168
169
|
force,
|
|
169
|
-
webhookSecret:
|
|
170
|
-
previousSecret:
|
|
170
|
+
webhookSecret: envGithubWebhookSecret(),
|
|
171
|
+
previousSecret: envGithubWebhookSecretPrevious(),
|
|
171
172
|
ingestHook: async (innerCtx, args) => {
|
|
172
173
|
const parsed = JSON.parse(args.rawPayload);
|
|
173
174
|
const event = parsedToIngestEvent(parsed, args.eventName);
|
|
@@ -104,61 +104,13 @@ export async function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
104
104
|
}
|
|
105
105
|
// Signature verification (current secret, not the one in effect when DLQed).
|
|
106
106
|
if (!opts.force && opts.webhookSecret) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
status: 'sig_missing',
|
|
111
|
-
memoryId: null,
|
|
112
|
-
retryCount: row.retryCount,
|
|
113
|
-
reason: 'row has no signature (legacy, or redacted before storing); pass --force to replay',
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
const sigOk = verifyGitHubSignature({
|
|
117
|
-
rawBody: row.rawPayload,
|
|
118
|
-
signature: row.signature,
|
|
119
|
-
webhookSecret: opts.webhookSecret,
|
|
120
|
-
previousSecret: opts.previousSecret,
|
|
121
|
-
});
|
|
122
|
-
if (!sigOk) {
|
|
123
|
-
bumpRetryCount(ctx.hippoRoot, id);
|
|
124
|
-
return {
|
|
125
|
-
ok: false,
|
|
126
|
-
status: 'sig_fail',
|
|
127
|
-
memoryId: null,
|
|
128
|
-
retryCount: row.retryCount + 1,
|
|
129
|
-
reason: 'signature did not verify against current GITHUB_WEBHOOK_SECRET; pass --force to replay anyway',
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
// Parse + envelope guard.
|
|
134
|
-
let parsed;
|
|
135
|
-
try {
|
|
136
|
-
parsed = JSON.parse(row.rawPayload);
|
|
137
|
-
}
|
|
138
|
-
catch (e) {
|
|
139
|
-
bumpRetryCount(ctx.hippoRoot, id);
|
|
140
|
-
// SAFETY: this is a best-effort error message only; property access on
|
|
141
|
-
// any JS value is safe (undefined if absent), preserving the existing
|
|
142
|
-
// lenient formatting even when something non-Error was thrown.
|
|
143
|
-
const message = e.message;
|
|
144
|
-
return {
|
|
145
|
-
ok: false,
|
|
146
|
-
status: 'parse_error',
|
|
147
|
-
memoryId: null,
|
|
148
|
-
retryCount: row.retryCount + 1,
|
|
149
|
-
reason: `still unparseable: ${message}`,
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
if (!isGitHubWebhookEnvelope(parsed)) {
|
|
153
|
-
bumpRetryCount(ctx.hippoRoot, id);
|
|
154
|
-
return {
|
|
155
|
-
ok: false,
|
|
156
|
-
status: 'unhandled',
|
|
157
|
-
memoryId: null,
|
|
158
|
-
retryCount: row.retryCount + 1,
|
|
159
|
-
reason: 'not a GitHub webhook envelope',
|
|
160
|
-
};
|
|
107
|
+
const sigFailure = checkReplaySignature(ctx.hippoRoot, id, row, opts.webhookSecret, opts.previousSecret);
|
|
108
|
+
if (sigFailure)
|
|
109
|
+
return sigFailure;
|
|
161
110
|
}
|
|
111
|
+
const envelopeFailure = checkReplayEnvelope(ctx.hippoRoot, id, row);
|
|
112
|
+
if (envelopeFailure)
|
|
113
|
+
return envelopeFailure;
|
|
162
114
|
// Without an ingest hook this is a dry-run validation. Bump and report.
|
|
163
115
|
if (!opts.ingestHook) {
|
|
164
116
|
bumpRetryCount(ctx.hippoRoot, id);
|
|
@@ -190,4 +142,65 @@ export async function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
190
142
|
retryCount: row.retryCount + 1,
|
|
191
143
|
};
|
|
192
144
|
}
|
|
145
|
+
/** The failure result when the row cannot pass the signature gate, else null. */
|
|
146
|
+
function checkReplaySignature(hippoRoot, id, row, webhookSecret, previousSecret) {
|
|
147
|
+
if (!row.signature) {
|
|
148
|
+
return {
|
|
149
|
+
ok: false,
|
|
150
|
+
status: 'sig_missing',
|
|
151
|
+
memoryId: null,
|
|
152
|
+
retryCount: row.retryCount,
|
|
153
|
+
reason: 'row has no signature (legacy, or redacted before storing); pass --force to replay',
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const sigOk = verifyGitHubSignature({
|
|
157
|
+
rawBody: row.rawPayload,
|
|
158
|
+
signature: row.signature,
|
|
159
|
+
webhookSecret,
|
|
160
|
+
previousSecret,
|
|
161
|
+
});
|
|
162
|
+
if (!sigOk) {
|
|
163
|
+
bumpRetryCount(hippoRoot, id);
|
|
164
|
+
return {
|
|
165
|
+
ok: false,
|
|
166
|
+
status: 'sig_fail',
|
|
167
|
+
memoryId: null,
|
|
168
|
+
retryCount: row.retryCount + 1,
|
|
169
|
+
reason: 'signature did not verify against current GITHUB_WEBHOOK_SECRET; pass --force to replay anyway',
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
/** Parse + envelope guard; the failure result after bumping the count, else null. */
|
|
175
|
+
function checkReplayEnvelope(hippoRoot, id, row) {
|
|
176
|
+
let parsed;
|
|
177
|
+
try {
|
|
178
|
+
parsed = JSON.parse(row.rawPayload);
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
bumpRetryCount(hippoRoot, id);
|
|
182
|
+
// SAFETY: this is a best-effort error message only; property access on
|
|
183
|
+
// any JS value is safe (undefined if absent), preserving the existing
|
|
184
|
+
// lenient formatting even when something non-Error was thrown.
|
|
185
|
+
const message = e.message;
|
|
186
|
+
return {
|
|
187
|
+
ok: false,
|
|
188
|
+
status: 'parse_error',
|
|
189
|
+
memoryId: null,
|
|
190
|
+
retryCount: row.retryCount + 1,
|
|
191
|
+
reason: `still unparseable: ${message}`,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (!isGitHubWebhookEnvelope(parsed)) {
|
|
195
|
+
bumpRetryCount(hippoRoot, id);
|
|
196
|
+
return {
|
|
197
|
+
ok: false,
|
|
198
|
+
status: 'unhandled',
|
|
199
|
+
memoryId: null,
|
|
200
|
+
retryCount: row.retryCount + 1,
|
|
201
|
+
reason: 'not a GitHub webhook envelope',
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
193
206
|
//# sourceMappingURL=dlq.js.map
|
|
@@ -69,6 +69,7 @@ function eventUpdatedAt(event) {
|
|
|
69
69
|
return event.payload.comment.updated_at ?? null;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
+
const INSERT_EVENT_LOG_SQL = `INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`;
|
|
72
73
|
export function ingestEvent(ctx, input) {
|
|
73
74
|
const idempotencyKey = computeIdempotencyKey(eventArtifactRef(input.event), eventUpdatedAt(input.event));
|
|
74
75
|
// Fast path: pre-check. Avoids running the transform / opening a write tx
|
|
@@ -87,15 +88,7 @@ export function ingestEvent(ctx, input) {
|
|
|
87
88
|
// Empty body: no memory to write, but mark seen so a retry of the same
|
|
88
89
|
// empty event returns 'duplicate' (not 'skipped' again — that would
|
|
89
90
|
// re-run the transform on every retry).
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
db2
|
|
93
|
-
.prepare(`INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`)
|
|
94
|
-
.run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), null);
|
|
95
|
-
}
|
|
96
|
-
finally {
|
|
97
|
-
closeHippoDb(db2);
|
|
98
|
-
}
|
|
91
|
+
markKeySeenWithoutMemory(ctx.hippoRoot, idempotencyKey, input);
|
|
99
92
|
return { status: 'skipped', memoryId: null };
|
|
100
93
|
}
|
|
101
94
|
// Atomic write via afterWrite. Inside writeEntry's SAVEPOINT:
|
|
@@ -105,23 +98,7 @@ export function ingestEvent(ctx, input) {
|
|
|
105
98
|
// the test injection) beat us, changes=0 -> throw -> SAVEPOINT rolls
|
|
106
99
|
// back our memory row. Other worker's commit stands.
|
|
107
100
|
try {
|
|
108
|
-
|
|
109
|
-
const result = remember(ctx, {
|
|
110
|
-
...opts,
|
|
111
|
-
untrusted: true,
|
|
112
|
-
afterWrite: (innerDb, memoryId) => {
|
|
113
|
-
if (input.__testInjectBeforeLog) {
|
|
114
|
-
input.__testInjectBeforeLog(innerDb, idempotencyKey);
|
|
115
|
-
}
|
|
116
|
-
const inserted = innerDb
|
|
117
|
-
.prepare(`INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`)
|
|
118
|
-
.run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), memoryId);
|
|
119
|
-
if (Number(inserted.changes ?? 0) === 0) {
|
|
120
|
-
throw new DuplicateIdempotencyError(idempotencyKey);
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
return { status: 'ingested', memoryId: result.id };
|
|
101
|
+
return rememberWithEventLog(ctx, input, idempotencyKey, opts);
|
|
125
102
|
}
|
|
126
103
|
catch (e) {
|
|
127
104
|
if (e instanceof DuplicateIdempotencyError) {
|
|
@@ -140,18 +117,40 @@ export function ingestEvent(ctx, input) {
|
|
|
140
117
|
// a transient failure — never DLQ-retry it. Mark the idempotency key
|
|
141
118
|
// seen exactly like the empty-body branch above so a GitHub retry of
|
|
142
119
|
// the same delivery acks as done, not error.
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
db4
|
|
146
|
-
.prepare(`INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`)
|
|
147
|
-
.run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), null);
|
|
148
|
-
}
|
|
149
|
-
finally {
|
|
150
|
-
closeHippoDb(db4);
|
|
151
|
-
}
|
|
120
|
+
markKeySeenWithoutMemory(ctx.hippoRoot, idempotencyKey, input);
|
|
152
121
|
return { status: 'skipped', memoryId: null };
|
|
153
122
|
}
|
|
154
123
|
throw e;
|
|
155
124
|
}
|
|
156
125
|
}
|
|
126
|
+
function markKeySeenWithoutMemory(hippoRoot, idempotencyKey, input) {
|
|
127
|
+
const db = openHippoDb(hippoRoot);
|
|
128
|
+
try {
|
|
129
|
+
db
|
|
130
|
+
.prepare(INSERT_EVENT_LOG_SQL)
|
|
131
|
+
.run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), null);
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
closeHippoDb(db);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function rememberWithEventLog(ctx, input, idempotencyKey, opts) {
|
|
138
|
+
// v1.12.0: drop the legacy `|| 'connector:github'` fallback (see slack/ingest.ts:73 for rationale).
|
|
139
|
+
const result = remember(ctx, {
|
|
140
|
+
...opts,
|
|
141
|
+
untrusted: true,
|
|
142
|
+
afterWrite: (innerDb, memoryId) => {
|
|
143
|
+
if (input.__testInjectBeforeLog) {
|
|
144
|
+
input.__testInjectBeforeLog(innerDb, idempotencyKey);
|
|
145
|
+
}
|
|
146
|
+
const inserted = innerDb
|
|
147
|
+
.prepare(INSERT_EVENT_LOG_SQL)
|
|
148
|
+
.run(idempotencyKey, input.deliveryId, input.event.eventName, new Date().toISOString(), memoryId);
|
|
149
|
+
if (Number(inserted.changes ?? 0) === 0) {
|
|
150
|
+
throw new DuplicateIdempotencyError(idempotencyKey);
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
return { status: 'ingested', memoryId: result.id };
|
|
155
|
+
}
|
|
157
156
|
//# sourceMappingURL=ingest.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { envGithubAllowUnknownInstallationFallback, envTenant } from '../../env.js';
|
|
1
2
|
/**
|
|
2
3
|
* Resolve the tenant_id for a GitHub webhook envelope.
|
|
3
4
|
*
|
|
@@ -23,8 +24,8 @@
|
|
|
23
24
|
* replay, future MCP) gets identical protection.
|
|
24
25
|
*/
|
|
25
26
|
export function resolveTenantForGitHub(db, args) {
|
|
26
|
-
const envFallback = () =>
|
|
27
|
-
const escapeHatch =
|
|
27
|
+
const envFallback = () => envTenant();
|
|
28
|
+
const escapeHatch = envGithubAllowUnknownInstallationFallback();
|
|
28
29
|
// SAFETY: the row comes from the SELECT above, which projects exactly one
|
|
29
30
|
// column, `c`, as a COUNT(*).
|
|
30
31
|
const instCount = db
|