hippo-memory 1.70.0 → 1.71.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/agent-memories/claude-code.d.ts +4 -2
- package/dist/agent-memories/claude-code.js +14 -5
- package/dist/agent-memories/files.js +23 -12
- package/dist/agent-memories/markdown.d.ts +1 -3
- package/dist/agent-memories/markdown.js +1 -3
- package/dist/agent-memories/report.js +2 -1
- package/dist/agent-memories/sync.d.ts +4 -2
- package/dist/agent-memories/sync.js +10 -5
- package/dist/api/assemble.d.ts +7 -44
- package/dist/api/assemble.js +2 -22
- package/dist/api/audit.d.ts +5 -1
- package/dist/api/audit.js +9 -1
- package/dist/api/auth.d.ts +13 -22
- package/dist/api/auth.js +34 -24
- package/dist/api/auto-sleep.js +2 -2
- package/dist/api/availability.d.ts +2 -15
- package/dist/api/availability.js +2 -15
- package/dist/api/context-select.js +3 -4
- package/dist/api/context-types.d.ts +10 -35
- package/dist/api/context.d.ts +5 -22
- package/dist/api/context.js +21 -38
- package/dist/api/dormant.d.ts +5 -21
- package/dist/api/dormant.js +7 -26
- package/dist/api/drill-down.d.ts +7 -46
- package/dist/api/drill-down.js +5 -26
- package/dist/api/forget.d.ts +5 -24
- package/dist/api/forget.js +5 -28
- package/dist/api/graph.d.ts +8 -0
- package/dist/api/graph.js +7 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/instruction-detect.js +16 -5
- package/dist/api/ledger-db.d.ts +2 -1
- package/dist/api/ledger-db.js +5 -3
- package/dist/api/memories.d.ts +5 -0
- package/dist/api/memories.js +7 -0
- package/dist/api/objects.d.ts +9 -0
- package/dist/api/objects.js +11 -0
- package/dist/api/on-store.js +5 -3
- package/dist/api/predictions.d.ts +9 -0
- package/dist/api/predictions.js +18 -0
- package/dist/api/promote.d.ts +13 -17
- package/dist/api/promote.js +11 -19
- package/dist/api/prompt-hook.d.ts +4 -4
- package/dist/api/prompt-hook.js +10 -9
- package/dist/api/recall-cli.d.ts +55 -0
- package/dist/api/recall-cli.js +94 -0
- package/dist/api/recall-core.js +14 -6
- package/dist/api/recall-finish.d.ts +53 -0
- package/dist/api/recall-finish.js +30 -0
- package/dist/api/recall-history.d.ts +17 -84
- package/dist/api/recall-history.js +15 -88
- package/dist/api/recall-pipeline.d.ts +2 -3
- package/dist/api/recall-pipeline.js +16 -9
- package/dist/api/recall-types.d.ts +64 -304
- package/dist/api/recall.d.ts +5 -33
- package/dist/api/recall.js +59 -60
- package/dist/api/refine.d.ts +7 -0
- package/dist/api/refine.js +10 -0
- package/dist/api/remember-local.d.ts +57 -0
- package/dist/api/remember-local.js +90 -0
- package/dist/api/remember.d.ts +18 -1
- package/dist/api/remember.js +13 -1
- package/dist/api/sleep-run.d.ts +1 -3
- package/dist/api/sleep-run.js +17 -21
- package/dist/api/sleep.d.ts +9 -28
- package/dist/api/tokens.d.ts +3 -10
- package/dist/api/tokens.js +3 -10
- package/dist/api/types.d.ts +6 -29
- package/dist/api/types.js +4 -22
- package/dist/capture/command.d.ts +4 -12
- package/dist/capture/command.js +6 -22
- package/dist/capture/compact.d.ts +4 -15
- package/dist/capture/compact.js +16 -25
- package/dist/capture/compaction-record.js +101 -69
- package/dist/capture/compaction-spool.d.ts +1 -1
- package/dist/capture/compaction-spool.js +1 -1
- package/dist/capture/session-digest.d.ts +1 -1
- package/dist/capture/session-digest.js +13 -7
- package/dist/capture/transcript.d.ts +2 -10
- package/dist/capture/transcript.js +4 -18
- package/dist/cli/api-context.d.ts +3 -0
- package/dist/cli/api-context.js +6 -0
- package/dist/cli/audit-prune.d.ts +6 -39
- package/dist/cli/audit-prune.js +6 -39
- package/dist/cli/audit.d.ts +1 -1
- package/dist/cli/audit.js +33 -34
- package/dist/cli/auth.d.ts +2 -2
- package/dist/cli/auth.js +57 -39
- package/dist/cli/briefs.d.ts +4 -4
- package/dist/cli/briefs.js +18 -22
- package/dist/cli/card.d.ts +2 -2
- package/dist/cli/card.js +31 -32
- package/dist/cli/client.d.ts +7 -27
- package/dist/cli/client.js +24 -43
- package/dist/cli/compact-resume-payload.js +3 -2
- package/dist/cli/context.d.ts +1 -2
- package/dist/cli/context.js +12 -8
- package/dist/cli/continuity.d.ts +6 -6
- package/dist/cli/continuity.js +62 -64
- package/dist/cli/correction-latency.d.ts +2 -14
- package/dist/cli/correction-latency.js +2 -14
- package/dist/cli/curate.d.ts +13 -17
- package/dist/cli/curate.js +68 -92
- package/dist/cli/dag.d.ts +4 -4
- package/dist/cli/dag.js +33 -27
- package/dist/cli/decisions.d.ts +4 -4
- package/dist/cli/decisions.js +33 -47
- package/dist/cli/eval.js +15 -13
- package/dist/cli/exit.d.ts +6 -0
- package/dist/cli/exit.js +11 -0
- package/dist/cli/explain.d.ts +1 -2
- package/dist/cli/explain.js +6 -4
- package/dist/cli/flag-values.d.ts +6 -1
- package/dist/cli/flag-values.js +27 -10
- package/dist/cli/flags.d.ts +1 -0
- package/dist/cli/flags.js +1 -1
- package/dist/cli/github.d.ts +14 -0
- package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
- package/dist/cli/goals.d.ts +2 -2
- package/dist/cli/goals.js +46 -50
- package/dist/cli/hook-runtime.d.ts +9 -27
- package/dist/cli/hook-runtime.js +15 -31
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.js +6 -12
- package/dist/cli/install-steps.js +3 -12
- package/dist/cli/last-sleep.d.ts +2 -1
- package/dist/cli/last-sleep.js +3 -0
- package/dist/cli/maintenance.d.ts +4 -4
- package/dist/cli/maintenance.js +14 -19
- package/dist/cli/object-verbs.js +4 -3
- package/dist/cli/owner-validation.d.ts +5 -28
- package/dist/cli/owner-validation.js +5 -28
- package/dist/cli/playbooks.d.ts +4 -4
- package/dist/cli/playbooks.js +23 -28
- package/dist/cli/print.d.ts +2 -5
- package/dist/cli/print.js +1 -4
- package/dist/cli/projects.d.ts +2 -2
- package/dist/cli/projects.js +1 -3
- package/dist/cli/provenance-coverage.d.ts +2 -6
- package/dist/cli/provenance-coverage.js +2 -6
- package/dist/cli/quality-repair-once.js +2 -2
- package/dist/cli/recall.d.ts +2 -4
- package/dist/cli/recall.js +55 -131
- package/dist/cli/refine-llm.d.ts +5 -31
- package/dist/cli/refine-llm.js +9 -36
- package/dist/cli/remember.d.ts +3 -3
- package/dist/cli/remember.js +122 -180
- package/dist/cli/scheduler.d.ts +2 -17
- package/dist/cli/scheduler.js +12 -18
- package/dist/cli/serve.js +21 -12
- package/dist/cli/session-hooks.d.ts +10 -18
- package/dist/cli/session-hooks.js +112 -113
- package/dist/cli/setup.d.ts +4 -4
- package/dist/cli/setup.js +19 -21
- package/dist/cli/shared.d.ts +9 -23
- package/dist/cli/shared.js +9 -32
- package/dist/cli/slack.d.ts +2 -2
- package/dist/cli/slack.js +19 -23
- package/dist/cli/sleep.d.ts +3 -2
- package/dist/cli/sleep.js +15 -16
- package/dist/cli/status.d.ts +9 -12
- package/dist/cli/status.js +55 -98
- package/dist/cli/stdin.d.ts +4 -6
- package/dist/cli/stdin.js +2 -3
- package/dist/cli/transfer.d.ts +9 -9
- package/dist/cli/transfer.js +66 -89
- package/dist/cli/usage.js +11 -5
- package/dist/cli.d.ts +66 -448
- package/dist/cli.js +87 -263
- package/dist/connectors/github/backfill.d.ts +5 -25
- package/dist/connectors/github/backfill.js +14 -49
- package/dist/connectors/github/deletion.d.ts +4 -18
- package/dist/connectors/github/deletion.js +2 -15
- package/dist/connectors/github/dlq.d.ts +8 -33
- package/dist/connectors/github/dlq.js +12 -29
- package/dist/connectors/github/ingest.d.ts +2 -6
- package/dist/connectors/github/ingest.js +4 -10
- package/dist/connectors/github/octokit-client.d.ts +4 -16
- package/dist/connectors/github/octokit-client.js +27 -24
- package/dist/connectors/github/ratelimit.d.ts +3 -14
- package/dist/connectors/github/ratelimit.js +3 -14
- package/dist/connectors/github/scope.d.ts +3 -5
- package/dist/connectors/github/scope.js +3 -5
- package/dist/connectors/github/signature.d.ts +4 -26
- package/dist/connectors/github/signature.js +4 -26
- package/dist/connectors/github/tenant-routing.d.ts +2 -24
- package/dist/connectors/github/tenant-routing.js +4 -26
- package/dist/connectors/github/transform.js +2 -16
- package/dist/connectors/github/types.d.ts +3 -15
- package/dist/connectors/github/types.js +2 -9
- package/dist/connectors/github/webhook.d.ts +2 -16
- package/dist/connectors/github/webhook.js +6 -22
- package/dist/connectors/slack/backfill.d.ts +4 -17
- package/dist/connectors/slack/backfill.js +4 -13
- package/dist/connectors/slack/dlq.d.ts +2 -19
- package/dist/connectors/slack/dlq.js +2 -19
- package/dist/connectors/slack/ingest.d.ts +2 -3
- package/dist/connectors/slack/ingest.js +2 -3
- package/dist/connectors/slack/scope.d.ts +2 -8
- package/dist/connectors/slack/scope.js +2 -8
- package/dist/connectors/slack/signature.d.ts +1 -6
- package/dist/connectors/slack/tenant-routing.d.ts +2 -19
- package/dist/connectors/slack/tenant-routing.js +2 -21
- package/dist/connectors/slack/transform.d.ts +2 -18
- package/dist/connectors/slack/transform.js +2 -18
- package/dist/connectors/slack/types.d.ts +3 -9
- package/dist/connectors/slack/types.js +2 -4
- package/dist/connectors/slack/web-client.js +33 -27
- package/dist/connectors/slack/webhook.d.ts +2 -19
- package/dist/connectors/slack/webhook.js +5 -26
- package/dist/connectors/slack/workspaces.d.ts +4 -24
- package/dist/connectors/slack/workspaces.js +4 -24
- package/dist/consolidate/conflicts.js +6 -14
- package/dist/consolidate/dag-summary.d.ts +8 -0
- package/dist/consolidate/dag-summary.js +41 -0
- package/dist/consolidate/dag.d.ts +5 -28
- package/dist/consolidate/dag.js +14 -75
- package/dist/consolidate/decay.js +7 -19
- package/dist/consolidate/dedupe.d.ts +6 -52
- package/dist/consolidate/dedupe.js +13 -71
- package/dist/consolidate/flush-units.d.ts +3 -4
- package/dist/consolidate/flush-units.js +3 -3
- package/dist/consolidate/half-life-migration.d.ts +3 -26
- package/dist/consolidate/half-life-migration.js +11 -28
- package/dist/consolidate/llm-passes.js +4 -21
- package/dist/consolidate/memory-value-weights.d.ts +2 -13
- package/dist/consolidate/memory-value-weights.js +2 -13
- package/dist/consolidate/memory-value.d.ts +11 -84
- package/dist/consolidate/memory-value.js +16 -104
- package/dist/consolidate/merge.js +10 -31
- package/dist/consolidate/merged-row.js +2 -1
- package/dist/consolidate/physics-pass.js +1 -3
- package/dist/consolidate/replay.d.ts +6 -38
- package/dist/consolidate/replay.js +14 -52
- package/dist/consolidate/run.js +1 -1
- package/dist/consolidate/sleep.d.ts +1 -8
- package/dist/consolidate/sleep.js +5 -17
- package/dist/consolidate/trace.d.ts +3 -18
- package/dist/consolidate/trace.js +3 -18
- package/dist/consolidate/traces.js +6 -22
- package/dist/core/ablation.d.ts +4 -91
- package/dist/core/ablation.js +4 -91
- package/dist/core/ambient.d.ts +1 -8
- package/dist/core/ambient.js +1 -8
- package/dist/core/capture-contract.d.ts +4 -2
- package/dist/core/capture-contract.js +4 -2
- package/dist/core/card.d.ts +4 -1
- package/dist/core/card.js +8 -0
- package/dist/core/compare.d.ts +11 -67
- package/dist/core/compare.js +9 -63
- package/dist/core/config.d.ts +10 -24
- package/dist/core/config.js +13 -14
- package/dist/core/handoff.d.ts +1 -7
- package/dist/core/handoff.js +1 -7
- package/dist/core/memory-quality.js +1 -1
- package/dist/core/memory.d.ts +41 -164
- package/dist/core/memory.js +51 -221
- package/dist/core/package-root.d.ts +3 -0
- package/dist/core/package-root.js +5 -0
- package/dist/core/physics-config.d.ts +1 -4
- package/dist/core/physics-config.js +3 -8
- package/dist/core/physics.d.ts +15 -61
- package/dist/core/physics.js +59 -122
- package/dist/core/project-identity.d.ts +17 -58
- package/dist/core/project-identity.js +17 -38
- package/dist/core/project-remote.js +13 -2
- package/dist/core/raw-append-only.d.ts +5 -0
- package/dist/core/raw-append-only.js +7 -0
- package/dist/core/salience.d.ts +1 -7
- package/dist/core/salience.js +1 -7
- package/dist/dashboard/dashboard-actions.js +2 -2
- package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
- package/dist/dashboard/dashboard-snapshot.js +11 -2
- package/dist/dashboard/dashboard-types.d.ts +2 -1
- package/dist/dashboard/dashboard.d.ts +1 -0
- package/dist/dashboard/dashboard.js +50 -4
- package/dist/db/busy.d.ts +1 -1
- package/dist/db/busy.js +17 -8
- package/dist/db/connect.d.ts +1 -0
- package/dist/db/connect.js +3 -3
- package/dist/db/migrate.js +3 -3
- package/dist/db/migrations/types.d.ts +2 -5
- package/dist/db/migrations/v14.js +2 -3
- package/dist/db/migrations/v15.js +2 -8
- package/dist/db/migrations/v16.js +2 -3
- package/dist/db/migrations/v17.js +2 -3
- package/dist/db/migrations/v19.js +2 -5
- package/dist/db/migrations/v20.js +2 -7
- package/dist/db/migrations/v22.js +4 -17
- package/dist/db/migrations/v23.js +3 -14
- package/dist/db/migrations/v24.js +2 -4
- package/dist/db/migrations/v25.js +3 -8
- package/dist/db/migrations/v26.js +2 -13
- package/dist/db/migrations/v27.js +3 -11
- package/dist/db/migrations/v28.js +2 -14
- package/dist/db/migrations/v29.js +4 -18
- package/dist/db/migrations/v30.js +4 -16
- package/dist/db/migrations/v31.js +2 -15
- package/dist/db/migrations/v32.js +4 -22
- package/dist/db/migrations/v33.js +2 -15
- package/dist/db/migrations/v34.js +2 -11
- package/dist/db/migrations/v35.js +2 -11
- package/dist/db/migrations/v36.js +2 -11
- package/dist/db/migrations/v37.js +8 -33
- package/dist/db/migrations/v38.js +5 -38
- package/dist/db/migrations/v39.js +9 -20
- package/dist/db/migrations/v40.js +2 -9
- package/dist/db/migrations/v41.js +2 -24
- package/dist/db/migrations/v43.js +1 -1
- package/dist/db/migrations/v44.js +2 -8
- package/dist/db/migrations/v45.js +2 -7
- package/dist/db/migrations/v47.js +2 -3
- package/dist/db/migrations/v51.js +1 -1
- package/dist/db/open.d.ts +2 -0
- package/dist/db/open.js +17 -1
- package/dist/db/physics-state.d.ts +6 -22
- package/dist/db/physics-state.js +25 -36
- package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
- package/dist/db/raw-archive-mirror-cleanup.js +2 -17
- package/dist/db/vector-store.d.ts +2 -0
- package/dist/db/vector-store.js +8 -1
- package/dist/doctor.js +74 -19
- package/dist/entry/session-text.js +2 -1
- package/dist/eval/eval-stats.d.ts +15 -53
- package/dist/eval/eval-stats.js +12 -42
- package/dist/eval/eval-suite.d.ts +2 -13
- package/dist/eval/eval-suite.js +74 -34
- package/dist/eval/eval.d.ts +6 -24
- package/dist/eval/eval.js +7 -34
- package/dist/eval/judgment.d.ts +0 -3
- package/dist/eval/judgment.js +19 -11
- package/dist/extensions/openclaw-plugin/index.js +1 -1
- package/dist/graph/extract.d.ts +5 -27
- package/dist/graph/extract.js +7 -33
- package/dist/graph/recall.d.ts +7 -20
- package/dist/graph/recall.js +14 -76
- package/dist/graph/stream.d.ts +7 -39
- package/dist/graph/stream.js +11 -34
- package/dist/graph/view.d.ts +9 -35
- package/dist/graph/view.js +11 -39
- package/dist/hooks/codex-wrapper.js +2 -2
- package/dist/hooks/copilot.js +2 -1
- package/dist/hooks/hook-blocks.d.ts +6 -2
- package/dist/hooks/hook-blocks.js +37 -124
- package/dist/hooks/json-hooks.d.ts +4 -36
- package/dist/hooks/json-hooks.js +18 -57
- package/dist/hooks/opencode.d.ts +0 -38
- package/dist/hooks/opencode.js +9 -76
- package/dist/hooks/shared.d.ts +8 -17
- package/dist/hooks/shared.js +29 -20
- package/dist/importers/core.d.ts +12 -37
- package/dist/importers/core.js +9 -27
- package/dist/importers/markdown-parse.d.ts +8 -22
- package/dist/importers/markdown-parse.js +8 -25
- package/dist/importers/markdown.js +3 -12
- package/dist/importers/sources.js +7 -35
- package/dist/importers/vault.d.ts +2 -8
- package/dist/importers/vault.js +25 -81
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/learn/autolearn.d.ts +14 -41
- package/dist/learn/autolearn.js +14 -41
- package/dist/learn/extract.js +2 -4
- package/dist/learn/forward-claim-detector.d.ts +6 -30
- package/dist/learn/forward-claim-detector.js +14 -66
- package/dist/learn/invalidation.d.ts +6 -18
- package/dist/learn/invalidation.js +9 -26
- package/dist/mcp/admin-tools.js +3 -5
- package/dist/mcp/memory-tools.js +4 -9
- package/dist/mcp/protocol.d.ts +8 -26
- package/dist/mcp/protocol.js +3 -6
- package/dist/mcp/recall-tools.js +3 -3
- package/dist/mcp/request.d.ts +3 -11
- package/dist/mcp/request.js +10 -26
- package/dist/mcp/server.d.ts +3 -9
- package/dist/mcp/server.js +5 -16
- package/dist/mcp/session-state.d.ts +1 -1
- package/dist/mcp/session-state.js +5 -11
- package/dist/mcp/stdio.d.ts +2 -6
- package/dist/mcp/stdio.js +48 -12
- package/dist/mcp/tools.js +5 -3
- package/dist/objects/customer-notes.d.ts +7 -42
- package/dist/objects/customer-notes.js +7 -48
- package/dist/objects/decisions.d.ts +12 -50
- package/dist/objects/decisions.js +15 -53
- package/dist/objects/incidents.d.ts +7 -38
- package/dist/objects/incidents.js +7 -41
- package/dist/objects/policies.d.ts +11 -89
- package/dist/objects/policies.js +11 -98
- package/dist/objects/processes.d.ts +7 -52
- package/dist/objects/processes.js +7 -61
- package/dist/objects/project-briefs.d.ts +11 -55
- package/dist/objects/project-briefs.js +14 -75
- package/dist/objects/skills.d.ts +7 -42
- package/dist/objects/skills.js +8 -54
- package/dist/postinstall.js +6 -19
- package/dist/predictions/planning-fallacy.d.ts +11 -34
- package/dist/rerankers/clef.js +3 -31
- package/dist/rerankers/cross-encoder.js +4 -6
- package/dist/rerankers/jev.js +9 -6
- package/dist/rerankers/llm.d.ts +2 -11
- package/dist/rerankers/llm.js +14 -14
- package/dist/rerankers/outage-warning.d.ts +2 -1
- package/dist/rerankers/outage-warning.js +2 -1
- package/dist/rerankers/remote.d.ts +1 -0
- package/dist/rerankers/remote.js +2 -0
- package/dist/rerankers/types.d.ts +2 -14
- package/dist/search/boosts.d.ts +0 -2
- package/dist/search/boosts.js +2 -2
- package/dist/search/goal-boost.d.ts +23 -0
- package/dist/search/goal-boost.js +90 -0
- package/dist/search/hybrid.d.ts +2 -0
- package/dist/search/multihop.js +2 -3
- package/dist/search/path-context.d.ts +5 -18
- package/dist/search/path-context.js +5 -18
- package/dist/search/physics-search.js +11 -8
- package/dist/search/rrf.d.ts +7 -35
- package/dist/search/rrf.js +5 -30
- package/dist/search/vector.d.ts +7 -0
- package/dist/search/vector.js +35 -5
- package/dist/server/auth.d.ts +9 -28
- package/dist/server/auth.js +32 -25
- package/dist/server/boot.d.ts +2 -21
- package/dist/server/boot.js +63 -96
- package/dist/server/client-ip.d.ts +3 -19
- package/dist/server/client-ip.js +5 -28
- package/dist/server/defaults.d.ts +3 -0
- package/dist/server/defaults.js +4 -0
- package/dist/server/key-check-bounds.d.ts +2 -1
- package/dist/server/lifecycle.d.ts +5 -4
- package/dist/server/lifecycle.js +19 -4
- package/dist/server/mcp-http.js +10 -44
- package/dist/server/rate-limit.d.ts +5 -18
- package/dist/server/rate-limit.js +4 -13
- package/dist/server/request.d.ts +4 -8
- package/dist/server/request.js +9 -17
- package/dist/server/route-table.js +42 -49
- package/dist/server/routes/admin.js +22 -28
- package/dist/server/routes/customer-notes.js +7 -12
- package/dist/server/routes/decisions.js +10 -17
- package/dist/server/routes/incidents.js +12 -20
- package/dist/server/routes/memories.js +12 -32
- package/dist/server/routes/object-routes.d.ts +0 -5
- package/dist/server/routes/object-routes.js +7 -15
- package/dist/server/routes/policies.js +10 -18
- package/dist/server/routes/predictions.js +13 -25
- package/dist/server/routes/processes.js +16 -26
- package/dist/server/routes/project-briefs.js +9 -16
- package/dist/server/routes/recall.js +10 -35
- package/dist/server/routes/skills.js +8 -18
- package/dist/server/server-detect.d.ts +9 -53
- package/dist/server/server-detect.js +24 -90
- package/dist/server/sleep-offload.js +4 -1
- package/dist/server/types.d.ts +12 -10
- package/dist/server/validation.d.ts +3 -1
- package/dist/server/validation.js +10 -23
- package/dist/server.d.ts +2 -2
- package/dist/server.js +3 -2
- package/dist/sharing/global-store.d.ts +19 -0
- package/dist/sharing/global-store.js +75 -0
- package/dist/sharing/global-sync.d.ts +6 -0
- package/dist/sharing/global-sync.js +80 -0
- package/dist/sharing/project-merge.d.ts +4 -5
- package/dist/sharing/project-merge.js +9 -7
- package/dist/sharing/scope.d.ts +4 -11
- package/dist/sharing/scope.js +4 -11
- package/dist/sharing/search-both.d.ts +60 -0
- package/dist/sharing/search-both.js +138 -0
- package/dist/sharing/share.d.ts +38 -0
- package/dist/sharing/share.js +226 -0
- package/dist/store/ambient.js +4 -9
- package/dist/store/audit-event.d.ts +4 -12
- package/dist/store/audit-event.js +4 -12
- package/dist/store/audit.d.ts +2 -5
- package/dist/store/audit.js +4 -12
- package/dist/store/auth.d.ts +6 -6
- package/dist/store/auth.js +10 -9
- package/dist/store/candidates.d.ts +20 -3
- package/dist/store/candidates.js +77 -48
- package/dist/store/card-detail.d.ts +2 -1
- package/dist/store/card-detail.js +2 -1
- package/dist/store/cards.d.ts +14 -9
- package/dist/store/cards.js +72 -126
- package/dist/store/conflicts.d.ts +4 -21
- package/dist/store/conflicts.js +71 -150
- package/dist/store/connectors/github.d.ts +10 -10
- package/dist/store/connectors/github.js +10 -10
- package/dist/store/dashboard-reads.js +4 -8
- package/dist/store/delete-and-batch.d.ts +11 -31
- package/dist/store/delete-and-batch.js +48 -64
- package/dist/store/delivery-recorder.d.ts +8 -4
- package/dist/store/delivery-recorder.js +25 -15
- package/dist/store/diagnostics.js +6 -13
- package/dist/store/dormant.d.ts +7 -29
- package/dist/store/dormant.js +15 -56
- package/dist/store/embeddings/index.d.ts +11 -80
- package/dist/store/embeddings/index.js +71 -207
- package/dist/store/embeddings/local.js +15 -32
- package/dist/store/embeddings/provider.d.ts +16 -53
- package/dist/store/embeddings/provider.js +41 -69
- package/dist/store/entry-reads.d.ts +21 -57
- package/dist/store/entry-reads.js +65 -126
- package/dist/store/entry-row.d.ts +6 -35
- package/dist/store/entry-row.js +9 -37
- package/dist/store/entry-writes.d.ts +10 -16
- package/dist/store/entry-writes.js +17 -35
- package/dist/store/goals.d.ts +3 -40
- package/dist/store/goals.js +21 -160
- package/dist/store/graph-queue.d.ts +6 -22
- package/dist/store/graph-queue.js +14 -45
- package/dist/store/graph-reads.d.ts +11 -35
- package/dist/store/graph-reads.js +20 -58
- package/dist/store/graph-rows.d.ts +3 -6
- package/dist/store/graph-rows.js +6 -9
- package/dist/store/graph-view-rows.d.ts +2 -1
- package/dist/store/graph-view-rows.js +2 -1
- package/dist/store/graph-writes.d.ts +6 -31
- package/dist/store/graph-writes.js +13 -37
- package/dist/store/half-life.d.ts +2 -1
- package/dist/store/half-life.js +14 -16
- package/dist/store/handoffs.d.ts +5 -11
- package/dist/store/handoffs.js +16 -34
- package/dist/store/index-and-stats.d.ts +6 -19
- package/dist/store/index-and-stats.js +34 -82
- package/dist/store/markdown.d.ts +2 -6
- package/dist/store/markdown.js +21 -20
- package/dist/store/mirrors.d.ts +2 -6
- package/dist/store/mirrors.js +14 -23
- package/dist/store/open.js +6 -13
- package/dist/store/planning-fallacy-evidence.d.ts +2 -30
- package/dist/store/planning-fallacy-evidence.js +8 -37
- package/dist/store/port.d.ts +82 -79
- package/dist/store/predictions.d.ts +11 -51
- package/dist/store/predictions.js +38 -119
- package/dist/{cli → store}/quality-repair.js +15 -31
- package/dist/store/raw-archive.d.ts +4 -16
- package/dist/store/raw-archive.js +14 -29
- package/dist/store/recall-scope.d.ts +19 -79
- package/dist/store/recall-scope.js +21 -82
- package/dist/store/recall-trace.d.ts +10 -77
- package/dist/store/recall-trace.js +19 -95
- package/dist/store/rejected-values.js +7 -19
- package/dist/store/rejection.d.ts +12 -58
- package/dist/store/rejection.js +13 -65
- package/dist/store/report-reads.d.ts +6 -0
- package/dist/store/report-reads.js +29 -0
- package/dist/store/rows.d.ts +9 -19
- package/dist/store/rows.js +36 -34
- package/dist/store/rule-sql.d.ts +5 -0
- package/dist/store/rule-sql.js +37 -0
- package/dist/store/search-rows.d.ts +7 -38
- package/dist/store/search-rows.js +14 -50
- package/dist/store/sessions.d.ts +10 -47
- package/dist/store/sessions.js +17 -73
- package/dist/store/sqlite/connector-events-group.js +2 -2
- package/dist/store/sqlite/entry-writes-group.js +2 -2
- package/dist/store/sqlite/error-codec.js +4 -2
- package/dist/store/sqlite/executor.d.ts +2 -1
- package/dist/store/sqlite/executor.js +2 -1
- package/dist/store/sqlite/local.d.ts +3 -3
- package/dist/store/sqlite/local.js +1 -0
- package/dist/store/sqlite/object-rows.js +6 -3
- package/dist/store/sqlite/objects-group.js +4 -2
- package/dist/store/sqlite/quarantine-group.js +2 -2
- package/dist/store/sqlite/store.d.ts +1 -4
- package/dist/store/sqlite/store.js +2 -3
- package/dist/store/sqlite/vector-reads-group.js +2 -2
- package/dist/store/sqlite/worker-jobs.js +1 -1
- package/dist/store/sqlite/worker-ops.d.ts +13 -2
- package/dist/store/sqlite/worker-ops.js +13 -2
- package/dist/store/sqlite/worker-store.js +5 -2
- package/dist/store/summaries.d.ts +10 -62
- package/dist/store/summaries.js +34 -146
- package/dist/store/summary-dirty.js +1 -1
- package/dist/store/tenant-lookup.d.ts +6 -1
- package/dist/store/tenant-lookup.js +7 -0
- package/dist/store/tenant.d.ts +2 -16
- package/dist/store/tenant.js +4 -19
- package/dist/store/token-ledger.d.ts +13 -43
- package/dist/store/token-ledger.js +19 -50
- package/dist/store/usage-reports.js +5 -13
- package/dist/store/vector-index.d.ts +46 -0
- package/dist/store/vector-index.js +170 -0
- package/dist/store/working-memory.d.ts +6 -25
- package/dist/store/working-memory.js +18 -52
- package/dist/store/yaml.d.ts +1 -5
- package/dist/store/yaml.js +2 -6
- package/dist/support-bundle.js +7 -5
- package/dist/trust/reject-flow.js +1 -3
- package/dist/util/anthropic-messages.js +14 -2
- package/dist/util/atomic-write.d.ts +2 -1
- package/dist/util/atomic-write.js +35 -4
- package/dist/util/capped-json.d.ts +6 -0
- package/dist/util/capped-json.js +46 -0
- package/dist/util/crash-handlers.d.ts +8 -1
- package/dist/util/crash-handlers.js +52 -10
- package/dist/util/env.d.ts +13 -6
- package/dist/util/env.js +14 -7
- package/dist/util/home-path.d.ts +2 -1
- package/dist/util/home-path.js +4 -2
- package/dist/util/http-retry.d.ts +3 -1
- package/dist/util/http-retry.js +26 -5
- package/dist/util/log.d.ts +3 -2
- package/dist/util/log.js +25 -9
- package/dist/util/request-scope.d.ts +2 -1
- package/dist/util/request-scope.js +2 -1
- package/dist/util/secret-detect.d.ts +5 -30
- package/dist/util/secret-detect.js +13 -39
- package/dist/util/stored-json.d.ts +1 -1
- package/dist/util/stored-json.js +1 -1
- package/dist/util/token-text.d.ts +1 -4
- package/dist/util/token-text.js +1 -4
- package/dist/util/transcript-tail.d.ts +2 -0
- package/dist/util/transcript-tail.js +24 -23
- package/dist/util/version.d.ts +5 -20
- package/dist/util/version.js +5 -20
- package/extensions/openclaw-plugin/index.ts +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/connectors/github/cli-impl.d.ts +0 -25
- package/dist/sharing/shared.d.ts +0 -187
- package/dist/sharing/shared.js +0 -563
- package/dist/store/vector-writes.d.ts +0 -13
- package/dist/store/vector-writes.js +0 -89
- /package/dist/{cli → store}/quality-repair.d.ts +0 -0
|
@@ -1,28 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* - /repos/{repo}/issues -> issues_hwm
|
|
5
|
-
* - /repos/{repo}/issues/comments -> issue_comments_hwm
|
|
6
|
-
* - /repos/{repo}/pulls/comments -> pr_review_comments_hwm
|
|
7
|
-
*
|
|
8
|
-
* Crash safety: each stream's HWM is persisted ONLY after
|
|
9
|
-
* the stream fully drains. If stream 2 throws mid-flight, stream 1's HWM
|
|
10
|
-
* is committed and stream 2's stays NULL (or its prior value). Rerun
|
|
11
|
-
* picks up from stream 1's saved HWM and re-fetches stream 2 from its
|
|
12
|
-
* last committed point.
|
|
13
|
-
*
|
|
14
|
-
* The /issues endpoint returns BOTH issues and PRs (a PR is
|
|
15
|
-
* an issue with a `pull_request` field). We skip PRs here so they don't
|
|
16
|
-
* get ingested under the issues schema. PRs are handled via webhook in
|
|
17
|
-
* V1 (no /pulls backfill stream — review comments cover the discussion
|
|
18
|
-
* surface).
|
|
19
|
-
*
|
|
20
|
-
* Privacy (V1 limitation): the REST list endpoints don't reliably set
|
|
21
|
-
* `repository.private`, and resolving it requires an extra API call per
|
|
22
|
-
* repo. Backfill leaves the field undefined so scopeFromRepository falls
|
|
23
|
-
* through to private. Callers who know the repo is public can re-tag
|
|
24
|
-
* downstream; the fail-safe default protects private orgs.
|
|
25
|
-
*/
|
|
1
|
+
/** Paginated backfill of the GitHub issues, issue-comments and PR-review-comments streams, each with its own high-water mark (HWM).
|
|
2
|
+
* An HWM is persisted only after its stream fully drains, so a crash in stream 2 leaves stream 1 committed and stream 2 resumes from its prior HWM.
|
|
3
|
+
* `repository.private` is left undefined (REST lists omit it), so scopeFromRepository falls through to private. */
|
|
26
4
|
import type { Context } from '../../api/index.js';
|
|
27
5
|
import type { GitHubFetcher } from './octokit-client.js';
|
|
28
6
|
export interface BackfillOpts {
|
|
@@ -32,6 +10,8 @@ export interface BackfillOpts {
|
|
|
32
10
|
token: string;
|
|
33
11
|
/** Optional cap on items per stream. Useful for tests. */
|
|
34
12
|
maxPerStream?: number;
|
|
13
|
+
/** First-run `--since`; seeds all three HWMs, COALESCE keeps any HWM a stream already saved. */
|
|
14
|
+
sinceIso?: string;
|
|
35
15
|
/** sleep ms — injectable so tests don't actually wait. */
|
|
36
16
|
sleepMs?: (ms: number) => Promise<void>;
|
|
37
17
|
}
|
|
@@ -1,38 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
* - /repos/{repo}/issues/comments -> issue_comments_hwm
|
|
6
|
-
* - /repos/{repo}/pulls/comments -> pr_review_comments_hwm
|
|
7
|
-
*
|
|
8
|
-
* Crash safety: each stream's HWM is persisted ONLY after
|
|
9
|
-
* the stream fully drains. If stream 2 throws mid-flight, stream 1's HWM
|
|
10
|
-
* is committed and stream 2's stays NULL (or its prior value). Rerun
|
|
11
|
-
* picks up from stream 1's saved HWM and re-fetches stream 2 from its
|
|
12
|
-
* last committed point.
|
|
13
|
-
*
|
|
14
|
-
* The /issues endpoint returns BOTH issues and PRs (a PR is
|
|
15
|
-
* an issue with a `pull_request` field). We skip PRs here so they don't
|
|
16
|
-
* get ingested under the issues schema. PRs are handled via webhook in
|
|
17
|
-
* V1 (no /pulls backfill stream — review comments cover the discussion
|
|
18
|
-
* surface).
|
|
19
|
-
*
|
|
20
|
-
* Privacy (V1 limitation): the REST list endpoints don't reliably set
|
|
21
|
-
* `repository.private`, and resolving it requires an extra API call per
|
|
22
|
-
* repo. Backfill leaves the field undefined so scopeFromRepository falls
|
|
23
|
-
* through to private. Callers who know the repo is public can re-tag
|
|
24
|
-
* downstream; the fail-safe default protects private orgs.
|
|
25
|
-
*/
|
|
26
|
-
import { readCursors, writeHwm } from '../../store/connectors/github.js';
|
|
1
|
+
/** Paginated backfill of the GitHub issues, issue-comments and PR-review-comments streams, each with its own high-water mark (HWM).
|
|
2
|
+
* An HWM is persisted only after its stream fully drains, so a crash in stream 2 leaves stream 1 committed and stream 2 resumes from its prior HWM.
|
|
3
|
+
* `repository.private` is left undefined (REST lists omit it), so scopeFromRepository falls through to private. */
|
|
4
|
+
import { readCursors, seedCursors, writeHwm } from '../../store/connectors/github.js';
|
|
27
5
|
import { ingestEvent } from './ingest.js';
|
|
28
6
|
import { isJsonObject } from '../../util/json.js';
|
|
29
7
|
const API = 'https://api.github.com';
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
* REST list endpoints often omit the full repository object on each item;
|
|
33
|
-
* we already know the repo since the caller passed it. `private` left
|
|
34
|
-
* undefined so scopeFromRepository falls through to private.
|
|
35
|
-
*/
|
|
8
|
+
/** Build a synthetic `repository` from the known repo full name, because REST list items often omit it.
|
|
9
|
+
* `private` stays undefined so scopeFromRepository falls through to private. */
|
|
36
10
|
function syntheticRepository(repoFullName) {
|
|
37
11
|
const [owner, name] = repoFullName.split('/');
|
|
38
12
|
return {
|
|
@@ -42,11 +16,7 @@ function syntheticRepository(repoFullName) {
|
|
|
42
16
|
// private intentionally omitted — fail-safe to private scope.
|
|
43
17
|
};
|
|
44
18
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Parse the trailing issue/PR number from a REST API URL.
|
|
47
|
-
* e.g. https://api.github.com/repos/o/r/issues/42 -> 42
|
|
48
|
-
* https://api.github.com/repos/o/r/pulls/7 -> 7
|
|
49
|
-
*/
|
|
19
|
+
/** Parse the trailing issue/PR number from a REST API URL, e.g. .../issues/42 -> 42. */
|
|
50
20
|
function parseTrailingNumber(url) {
|
|
51
21
|
if (!url)
|
|
52
22
|
return null;
|
|
@@ -86,9 +56,7 @@ async function drainStream(ctx, url0, options) {
|
|
|
86
56
|
pages++;
|
|
87
57
|
for (const item of page.items) {
|
|
88
58
|
// Track updated_at on EVERY item, before the toIngestEvent filter, so PR-only pages don't loop forever.
|
|
89
|
-
// SAFETY: updated_at is GitHub's ISO-timestamp field on every item
|
|
90
|
-
// shape this stream returns; a non-string value would only fail the
|
|
91
|
-
// string comparisons below, matching pre-migration passthrough.
|
|
59
|
+
// SAFETY: updated_at is GitHub's ISO-timestamp field on every item shape this stream returns.
|
|
92
60
|
const updatedAt = isJsonObject(item)
|
|
93
61
|
? (item.updated_at ?? null)
|
|
94
62
|
: null;
|
|
@@ -146,9 +114,8 @@ function issueItemToEvent(item, repository) {
|
|
|
146
114
|
function issueCommentItemToEvent(item, repository) {
|
|
147
115
|
if (!isCommentItem(item))
|
|
148
116
|
return null;
|
|
149
|
-
// SAFETY: this closure only runs against the /issues/comments stream,
|
|
150
|
-
//
|
|
151
|
-
// IssueCommentItem; a missing issue_url is handled defensively below.
|
|
117
|
+
// SAFETY: this closure only runs against the /issues/comments stream, so every item isCommentItem
|
|
118
|
+
// validates is an IssueCommentItem; a missing issue_url is handled below.
|
|
152
119
|
const c = item;
|
|
153
120
|
const issueNumber = parseTrailingNumber(c.issue_url);
|
|
154
121
|
if (issueNumber === null)
|
|
@@ -169,9 +136,8 @@ function issueCommentItemToEvent(item, repository) {
|
|
|
169
136
|
function prReviewCommentItemToEvent(item, repository) {
|
|
170
137
|
if (!isCommentItem(item))
|
|
171
138
|
return null;
|
|
172
|
-
// SAFETY: this closure only runs against the /pulls/comments stream,
|
|
173
|
-
//
|
|
174
|
-
// PrReviewCommentItem; a missing pull_request_url is handled below.
|
|
139
|
+
// SAFETY: this closure only runs against the /pulls/comments stream, so every item isCommentItem
|
|
140
|
+
// validates is a PrReviewCommentItem; a missing pull_request_url is handled below.
|
|
175
141
|
const c = item;
|
|
176
142
|
const prNumber = parseTrailingNumber(c.pull_request_url);
|
|
177
143
|
if (prNumber === null)
|
|
@@ -206,13 +172,14 @@ async function backfillStream(ctx, opts, sleep, stream) {
|
|
|
206
172
|
}
|
|
207
173
|
export async function backfillRepo(ctx, opts) {
|
|
208
174
|
const sleep = opts.sleepMs ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
175
|
+
if (opts.sinceIso)
|
|
176
|
+
seedCursors(ctx.hippoRoot, ctx.tenantId, opts.repoFullName, opts.sinceIso);
|
|
209
177
|
const cursors = readCursors(ctx.hippoRoot, ctx.tenantId, opts.repoFullName);
|
|
210
178
|
const repository = syntheticRepository(opts.repoFullName);
|
|
211
179
|
const result = {
|
|
212
180
|
ingested: { issues: 0, issueComments: 0, prReviewComments: 0 },
|
|
213
181
|
pages: { issues: 0, issueComments: 0, prReviewComments: 0 },
|
|
214
182
|
};
|
|
215
|
-
// ---------- Stream 1: issues (skip PRs) ----------
|
|
216
183
|
const issuesRes = await backfillStream(ctx, opts, sleep, {
|
|
217
184
|
url: `${API}/repos/${opts.repoFullName}/issues?state=all&per_page=100` +
|
|
218
185
|
(cursors.issues ? `&since=${encodeURIComponent(cursors.issues)}` : ''),
|
|
@@ -221,7 +188,6 @@ export async function backfillRepo(ctx, opts) {
|
|
|
221
188
|
});
|
|
222
189
|
result.ingested.issues = issuesRes.ingested;
|
|
223
190
|
result.pages.issues = issuesRes.pages;
|
|
224
|
-
// ---------- Stream 2: repo-level issue comments ----------
|
|
225
191
|
const commentsRes = await backfillStream(ctx, opts, sleep, {
|
|
226
192
|
url: `${API}/repos/${opts.repoFullName}/issues/comments?per_page=100` +
|
|
227
193
|
(cursors.issueComments ? `&since=${encodeURIComponent(cursors.issueComments)}` : ''),
|
|
@@ -230,7 +196,6 @@ export async function backfillRepo(ctx, opts) {
|
|
|
230
196
|
});
|
|
231
197
|
result.ingested.issueComments = commentsRes.ingested;
|
|
232
198
|
result.pages.issueComments = commentsRes.pages;
|
|
233
|
-
// ---------- Stream 3: repo-level PR review comments ----------
|
|
234
199
|
const prCommentsRes = await backfillStream(ctx, opts, sleep, {
|
|
235
200
|
url: `${API}/repos/${opts.repoFullName}/pulls/comments?per_page=100` +
|
|
236
201
|
(cursors.prReviewComments ? `&since=${encodeURIComponent(cursors.prReviewComments)}` : ''),
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { type Context } from '../../api/index.js';
|
|
2
2
|
export interface DeletionInput {
|
|
3
|
-
/** artifact_ref of the comment, e.g
|
|
4
|
-
* 'github://acme/repo/
|
|
5
|
-
* 'github://acme/repo/pull/7/review_comment/456'. */
|
|
3
|
+
/** artifact_ref of the comment, e.g. 'github://acme/repo/issue/42/comment/123'
|
|
4
|
+
* or 'github://acme/repo/pull/7/review_comment/456'. */
|
|
6
5
|
artifactRef: string;
|
|
7
6
|
/** Source idempotency key for this delete event (sha256 of artifact_ref + ':' + updated_at). */
|
|
8
7
|
idempotencyKey: string;
|
|
@@ -16,20 +15,7 @@ export interface DeletionResult {
|
|
|
16
15
|
status: DeletionStatus;
|
|
17
16
|
archivedCount: number;
|
|
18
17
|
}
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* Filter by tenant_id + kind='raw'. Multi-row archive:
|
|
23
|
-
* GitHub edits keep the same artifact_ref, so multiple active raw rows can
|
|
24
|
-
* match a single deletion event. Archive ALL of them.
|
|
25
|
-
*
|
|
26
|
-
* The store runs ALL archives + the idempotency mark as one write: a per-row
|
|
27
|
-
* failure rolls back the whole batch, idempotency included, so a retry
|
|
28
|
-
* re-attempts cleanly instead of leaving searchable survivors.
|
|
29
|
-
*
|
|
30
|
-
* Tenant scope and kind='raw' filtering are load-bearing: without them a
|
|
31
|
-
* deletion event from tenant A could archive tenant B's row sharing the same
|
|
32
|
-
* artifact_ref, or accidentally target a distilled row.
|
|
33
|
-
*/
|
|
18
|
+
/** Handle `issue_comment.deleted` and `pull_request_review_comment.deleted`: archive ALL active raw rows for the artifact_ref in one write.
|
|
19
|
+
* Tenant and kind='raw' filtering are load-bearing: without them a deletion could archive another tenant's row or a distilled row. */
|
|
34
20
|
export declare function handleCommentDeleted(ctx: Context, input: DeletionInput): Promise<DeletionResult>;
|
|
35
21
|
//# sourceMappingURL=deletion.d.ts.map
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import { requireGroup, storeFor } from '../../store/index.js';
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Filter by tenant_id + kind='raw'. Multi-row archive:
|
|
6
|
-
* GitHub edits keep the same artifact_ref, so multiple active raw rows can
|
|
7
|
-
* match a single deletion event. Archive ALL of them.
|
|
8
|
-
*
|
|
9
|
-
* The store runs ALL archives + the idempotency mark as one write: a per-row
|
|
10
|
-
* failure rolls back the whole batch, idempotency included, so a retry
|
|
11
|
-
* re-attempts cleanly instead of leaving searchable survivors.
|
|
12
|
-
*
|
|
13
|
-
* Tenant scope and kind='raw' filtering are load-bearing: without them a
|
|
14
|
-
* deletion event from tenant A could archive tenant B's row sharing the same
|
|
15
|
-
* artifact_ref, or accidentally target a distilled row.
|
|
16
|
-
*/
|
|
2
|
+
/** Handle `issue_comment.deleted` and `pull_request_review_comment.deleted`: archive ALL active raw rows for the artifact_ref in one write.
|
|
3
|
+
* Tenant and kind='raw' filtering are load-bearing: without them a deletion could archive another tenant's row or a distilled row. */
|
|
17
4
|
export async function handleCommentDeleted(ctx, input) {
|
|
18
5
|
const { artifactRef, idempotencyKey, deliveryId, eventName } = input;
|
|
19
6
|
const done = await requireGroup(storeFor(ctx), 'connectorEvents').archiveDeletedArtifact({
|
|
@@ -1,32 +1,20 @@
|
|
|
1
1
|
import type { Context } from '../../api/index.js';
|
|
2
|
-
import { type DlqBucket, type DlqItem, type
|
|
2
|
+
import { type DlqBucket, type DlqItem, type GitHubDlqInsert } from '../../store/connectors/github.js';
|
|
3
3
|
import { type ConnectorDlq, type ReplayResult } from '../dlq.js';
|
|
4
4
|
export type { DlqBucket, DlqItem };
|
|
5
|
-
type
|
|
5
|
+
type GitHubOwnColumns = Pick<GitHubDlqInsert, 'eventName' | 'deliveryId' | 'installationId' | 'repoFullName'>;
|
|
6
6
|
/** GitHub's dead-letter table; the event, delivery, installation and repo columns let an operator triage a row without re-reading the payload. */
|
|
7
|
-
export declare const githubDlq: ConnectorDlq<
|
|
7
|
+
export declare const githubDlq: ConnectorDlq<GitHubOwnColumns, DlqBucket, DlqItem>;
|
|
8
8
|
export interface ReplayDlqOpts {
|
|
9
9
|
/** Current webhook secret. If omitted, signature check is skipped (force-only path). */
|
|
10
10
|
webhookSecret?: string;
|
|
11
|
-
/**
|
|
12
|
-
* Previous webhook secret during rotation.
|
|
13
|
-
* Operators rotating GITHUB_WEBHOOK_SECRET would otherwise be forced into
|
|
14
|
-
* --force on DLQ rows written under the old secret. Plumbed through to
|
|
15
|
-
* verifyGitHubSignature.previousSecret.
|
|
16
|
-
*/
|
|
11
|
+
/** Previous webhook secret during rotation, passed to verifyGitHubSignature.previousSecret so old-secret DLQ rows need no --force. */
|
|
17
12
|
previousSecret?: string;
|
|
18
13
|
/** When true, skip signature verification (used for legacy entries after secret rotation). */
|
|
19
14
|
force?: boolean;
|
|
20
15
|
}
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
* the dispatch keeps this module free of every event-type handler — the
|
|
24
|
-
* route already knows how to route an envelope, so it passes that capability
|
|
25
|
-
* back in.
|
|
26
|
-
*
|
|
27
|
-
* No `idempotencyKey` field: ingest re-derives the key from the parsed event,
|
|
28
|
-
* so a hook trusting a passed-in key would dedupe against a stale one.
|
|
29
|
-
*/
|
|
16
|
+
/** Hook the webhook route injects to re-ingest a row, which keeps this module free of every event-type handler.
|
|
17
|
+
* No `idempotencyKey` field: ingest re-derives it from the parsed event, and a passed-in key could be stale. */
|
|
30
18
|
export type IngestHook = (ctx: Context, args: {
|
|
31
19
|
rawPayload: string;
|
|
32
20
|
eventName: string;
|
|
@@ -34,21 +22,8 @@ export type IngestHook = (ctx: Context, args: {
|
|
|
34
22
|
}) => Promise<{
|
|
35
23
|
memoryId: string | null;
|
|
36
24
|
}>;
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
39
|
-
* 1. Fetch row by id. Not found → `not_found`.
|
|
40
|
-
* 2. If !force and webhookSecret provided, verify signature with the
|
|
41
|
-
* current secret. Fail → bump retry_count, `sig_fail`.
|
|
42
|
-
* Missing signature on the row → `sig_missing` (no bump; --force required).
|
|
43
|
-
* 3. JSON.parse the raw payload. Fail → bump, `parse_error`.
|
|
44
|
-
* 4. Type-guard the envelope. Fail → bump, `unhandled`.
|
|
45
|
-
* 5. If an `ingestHook` is supplied, call it and return its memoryId.
|
|
46
|
-
* If not (dry-run path), bump retry_count and return status `replayed`
|
|
47
|
-
* with memoryId=null. The webhook route wires the real hook.
|
|
48
|
-
*
|
|
49
|
-
* Mirrors Slack's "always use current routing" policy: replays use the
|
|
50
|
-
* deployment state NOW, not at the time of original DLQing.
|
|
51
|
-
*/
|
|
25
|
+
/** Replay a DLQ row through the normal ingest path; a failed signature, parse or envelope check bumps retry_count.
|
|
26
|
+
* Without an `ingestHook` (dry-run) it bumps retry_count and returns `replayed` with memoryId=null; replays use today's routing, not the original's. */
|
|
52
27
|
export declare function replayDlqEntry(ctx: Context, id: number, opts?: ReplayDlqOpts & {
|
|
53
28
|
ingestHook?: IngestHook;
|
|
54
29
|
}): Promise<ReplayResult>;
|
|
@@ -1,29 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bumpGitHubDlqRetryCount, githubDlqEntry, listGitHubDlq, } from '../../store/connectors/github.js';
|
|
2
2
|
import { replayFailed } from '../dlq.js';
|
|
3
3
|
import { verifyGitHubSignature } from './signature.js';
|
|
4
4
|
import { isGitHubWebhookEnvelope } from './types.js';
|
|
5
5
|
/** GitHub's dead-letter table; the event, delivery, installation and repo columns let an operator triage a row without re-reading the payload. */
|
|
6
6
|
export const githubDlq = {
|
|
7
7
|
letter: (row) => ({ connector: 'github', ...row }),
|
|
8
|
-
list:
|
|
8
|
+
list: listGitHubDlq,
|
|
9
9
|
};
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* 1. Fetch row by id. Not found → `not_found`.
|
|
13
|
-
* 2. If !force and webhookSecret provided, verify signature with the
|
|
14
|
-
* current secret. Fail → bump retry_count, `sig_fail`.
|
|
15
|
-
* Missing signature on the row → `sig_missing` (no bump; --force required).
|
|
16
|
-
* 3. JSON.parse the raw payload. Fail → bump, `parse_error`.
|
|
17
|
-
* 4. Type-guard the envelope. Fail → bump, `unhandled`.
|
|
18
|
-
* 5. If an `ingestHook` is supplied, call it and return its memoryId.
|
|
19
|
-
* If not (dry-run path), bump retry_count and return status `replayed`
|
|
20
|
-
* with memoryId=null. The webhook route wires the real hook.
|
|
21
|
-
*
|
|
22
|
-
* Mirrors Slack's "always use current routing" policy: replays use the
|
|
23
|
-
* deployment state NOW, not at the time of original DLQing.
|
|
24
|
-
*/
|
|
10
|
+
/** Replay a DLQ row through the normal ingest path; a failed signature, parse or envelope check bumps retry_count.
|
|
11
|
+
* Without an `ingestHook` (dry-run) it bumps retry_count and returns `replayed` with memoryId=null; replays use today's routing, not the original's. */
|
|
25
12
|
export async function replayDlqEntry(ctx, id, opts = {}) {
|
|
26
|
-
const row =
|
|
13
|
+
const row = githubDlqEntry(ctx.hippoRoot, id);
|
|
27
14
|
if (!row)
|
|
28
15
|
return replayFailed('not_found', 0, `dlq id ${id} not found`);
|
|
29
16
|
// Signature verification (current secret, not the one in effect when DLQed).
|
|
@@ -37,7 +24,7 @@ export async function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
37
24
|
return envelopeFailure;
|
|
38
25
|
// Without an ingest hook this is a dry-run validation. Bump and report.
|
|
39
26
|
if (!opts.ingestHook) {
|
|
40
|
-
|
|
27
|
+
bumpGitHubDlqRetryCount(ctx.hippoRoot, id);
|
|
41
28
|
return {
|
|
42
29
|
ok: true,
|
|
43
30
|
status: 'replayed',
|
|
@@ -46,9 +33,7 @@ export async function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
46
33
|
reason: 'dry-run: no ingest hook supplied',
|
|
47
34
|
};
|
|
48
35
|
}
|
|
49
|
-
// Real replay path
|
|
50
|
-
// idempotency, and writing the memory. The DLQ module only validates the
|
|
51
|
-
// surface and bumps the retry counter.
|
|
36
|
+
// Real replay path: the route's IngestHook owns routing, idempotency and the memory write; this module only validates and bumps the retry counter.
|
|
52
37
|
// No idempotencyKey arg: the hook re-derives it from the parsed event (artifact_ref + updated_at).
|
|
53
38
|
const eventName = row.eventName ?? '';
|
|
54
39
|
const deliveryId = row.deliveryId ?? '';
|
|
@@ -57,7 +42,7 @@ export async function replayDlqEntry(ctx, id, opts = {}) {
|
|
|
57
42
|
eventName,
|
|
58
43
|
deliveryId,
|
|
59
44
|
});
|
|
60
|
-
|
|
45
|
+
bumpGitHubDlqRetryCount(ctx.hippoRoot, id);
|
|
61
46
|
return {
|
|
62
47
|
ok: true,
|
|
63
48
|
status: 'replayed',
|
|
@@ -77,7 +62,7 @@ function checkReplaySignature(hippoRoot, id, row, webhookSecret, previousSecret)
|
|
|
77
62
|
previousSecret,
|
|
78
63
|
});
|
|
79
64
|
if (!sigOk) {
|
|
80
|
-
|
|
65
|
+
bumpGitHubDlqRetryCount(hippoRoot, id);
|
|
81
66
|
return replayFailed('sig_fail', row.retryCount + 1, 'signature did not verify against current GITHUB_WEBHOOK_SECRET; pass --force to replay anyway');
|
|
82
67
|
}
|
|
83
68
|
return null;
|
|
@@ -89,15 +74,13 @@ function checkReplayEnvelope(hippoRoot, id, row) {
|
|
|
89
74
|
parsed = JSON.parse(row.rawPayload);
|
|
90
75
|
}
|
|
91
76
|
catch (e) {
|
|
92
|
-
|
|
93
|
-
// SAFETY:
|
|
94
|
-
// any JS value is safe (undefined if absent), preserving the existing
|
|
95
|
-
// lenient formatting even when something non-Error was thrown.
|
|
77
|
+
bumpGitHubDlqRetryCount(hippoRoot, id);
|
|
78
|
+
// SAFETY: best-effort error message only; property access on any JS value is safe, even for a non-Error throw.
|
|
96
79
|
const message = e.message;
|
|
97
80
|
return replayFailed('parse_error', row.retryCount + 1, `still unparseable: ${message}`);
|
|
98
81
|
}
|
|
99
82
|
if (!isGitHubWebhookEnvelope(parsed)) {
|
|
100
|
-
|
|
83
|
+
bumpGitHubDlqRetryCount(hippoRoot, id);
|
|
101
84
|
return replayFailed('unhandled', row.retryCount + 1, 'not a GitHub webhook envelope');
|
|
102
85
|
}
|
|
103
86
|
return null;
|
|
@@ -5,12 +5,8 @@ export interface IngestResult {
|
|
|
5
5
|
status: IngestStatus;
|
|
6
6
|
memoryId: string | null;
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* field MUST equal the X-GitHub-Event header value; computeIdempotencyKey
|
|
11
|
-
* folds it into the dedupe key so the same body posted under two different
|
|
12
|
-
* X-GitHub-Event headers produces two distinct keys (test 7).
|
|
13
|
-
*/
|
|
8
|
+
/** Discriminated union of the four event shapes V1 ingests; eventName MUST equal the X-GitHub-Event header,
|
|
9
|
+
* since computeIdempotencyKey folds it into the dedupe key. */
|
|
14
10
|
export type IngestEvent = {
|
|
15
11
|
eventName: 'issues';
|
|
16
12
|
payload: GitHubIssueEvent;
|
|
@@ -18,12 +18,8 @@ function transformEvent(event) {
|
|
|
18
18
|
return prReviewCommentEventToRememberOpts(event.payload);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
* Backfill and webhook both produce IngestEvent objects describing the same
|
|
24
|
-
* source revision, so deriving the key from these fields collapses both paths
|
|
25
|
-
* onto the same dedupe row. Mirrors the artifactRef strings in transform.ts.
|
|
26
|
-
*/
|
|
21
|
+
/** Extract the source-normalized identifier the idempotency key needs, so backfill and webhook deliveries of the same
|
|
22
|
+
* source revision collapse onto one dedupe row. Mirrors the artifactRef strings in transform.ts. */
|
|
27
23
|
function eventArtifactRef(event) {
|
|
28
24
|
const repo = event.payload.repository?.full_name ?? 'unknown/unknown';
|
|
29
25
|
switch (event.eventName) {
|
|
@@ -60,9 +56,7 @@ export async function ingestEvent(ctx, input) {
|
|
|
60
56
|
return { status: 'duplicate', memoryId: seen.memoryId };
|
|
61
57
|
const opts = transformEvent(input.event);
|
|
62
58
|
if (!opts) {
|
|
63
|
-
// Empty body: no memory to write, but mark seen so a retry of the
|
|
64
|
-
// empty event returns 'duplicate' (not 'skipped' again — that would
|
|
65
|
-
// re-run the transform on every retry).
|
|
59
|
+
// Empty body: no memory to write, but mark seen so a retry returns 'duplicate' instead of re-running the transform.
|
|
66
60
|
await events.markEventSeen(event);
|
|
67
61
|
return { status: 'skipped', memoryId: null };
|
|
68
62
|
}
|
|
@@ -80,7 +74,7 @@ export async function ingestEvent(ctx, input) {
|
|
|
80
74
|
}
|
|
81
75
|
}
|
|
82
76
|
async function rememberWithEventLog(ctx, event, opts) {
|
|
83
|
-
// No `|| 'connector:github'` fallback (
|
|
77
|
+
// No `|| 'connector:github'` fallback: the caller always builds ctx with the connector subject (same as slack/ingest.ts).
|
|
84
78
|
const result = await remember(ctx, { ...opts, untrusted: true, event });
|
|
85
79
|
// Another worker logged this key between the pre-check and the write: its memory stands and ours was not stored.
|
|
86
80
|
if (result.duplicate)
|
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Production uses `realGitHubFetcher` against `https://api.github.com`.
|
|
5
|
-
* Tests inject a fake `GitHubFetcher` so they never hit the network.
|
|
6
|
-
*
|
|
7
|
-
* Any non-200 response that is NOT a recognized rate-limit pause MUST throw
|
|
8
|
-
* `GitHubFetchError`: an empty page would be an empty backfill with no operator signal.
|
|
9
|
-
*/
|
|
1
|
+
/** Octokit-shaped HTTP fetcher for the GitHub backfill; tests inject a fake `GitHubFetcher`.
|
|
2
|
+
* Any non-200 that is not a recognised rate-limit pause MUST throw `GitHubFetchError`, since an empty page would be a silent empty backfill. */
|
|
10
3
|
import { type RateLimitInfo } from './ratelimit.js';
|
|
11
4
|
import type { JsonValue } from '../../util/json.js';
|
|
12
5
|
export declare class GitHubFetchError extends Error {
|
|
13
6
|
readonly status: number;
|
|
14
7
|
readonly bodyExcerpt: string;
|
|
15
8
|
readonly url: string;
|
|
16
|
-
constructor(status: number, bodyExcerpt: string, url: string);
|
|
9
|
+
constructor(status: number, bodyExcerpt: string, url: string, options?: ErrorOptions);
|
|
17
10
|
}
|
|
18
11
|
export interface GitHubBackfillPage {
|
|
19
12
|
readonly items: ReadonlyArray<JsonValue>;
|
|
@@ -24,12 +17,7 @@ export type GitHubFetcher = (args: {
|
|
|
24
17
|
url: string;
|
|
25
18
|
token: string;
|
|
26
19
|
}) => Promise<GitHubBackfillPage>;
|
|
27
|
-
/**
|
|
28
|
-
* Parse the rel="next" URL from an RFC 5988 `Link` header.
|
|
29
|
-
*
|
|
30
|
-
* Header format: `<url1>; rel="next", <url2>; rel="last"`.
|
|
31
|
-
* Returns the URL whose rel parameter is exactly `"next"`, or null.
|
|
32
|
-
*/
|
|
20
|
+
/** Parse the rel="next" URL from an RFC 5988 `Link` header, or null. */
|
|
33
21
|
export declare function parseNextLink(linkHeader: string): string | null;
|
|
34
22
|
export declare const realGitHubFetcher: GitHubFetcher;
|
|
35
23
|
//# sourceMappingURL=octokit-client.d.ts.map
|
|
@@ -1,32 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Production uses `realGitHubFetcher` against `https://api.github.com`.
|
|
5
|
-
* Tests inject a fake `GitHubFetcher` so they never hit the network.
|
|
6
|
-
*
|
|
7
|
-
* Any non-200 response that is NOT a recognized rate-limit pause MUST throw
|
|
8
|
-
* `GitHubFetchError`: an empty page would be an empty backfill with no operator signal.
|
|
9
|
-
*/
|
|
1
|
+
/** Octokit-shaped HTTP fetcher for the GitHub backfill; tests inject a fake `GitHubFetcher`.
|
|
2
|
+
* Any non-200 that is not a recognised rate-limit pause MUST throw `GitHubFetchError`, since an empty page would be a silent empty backfill. */
|
|
10
3
|
import { parseRateLimit } from './ratelimit.js';
|
|
11
4
|
import { fetchWithRetry } from '../../util/http-retry.js';
|
|
5
|
+
import { readCappedJson, readCappedText } from '../../util/capped-json.js';
|
|
6
|
+
import { errorMessage } from '../../util/log.js';
|
|
12
7
|
export class GitHubFetchError extends Error {
|
|
13
8
|
status;
|
|
14
9
|
bodyExcerpt;
|
|
15
10
|
url;
|
|
16
|
-
constructor(status, bodyExcerpt, url) {
|
|
17
|
-
super(`GitHub ${status} on ${url}: ${bodyExcerpt}
|
|
11
|
+
constructor(status, bodyExcerpt, url, options) {
|
|
12
|
+
super(`GitHub ${status} on ${url}: ${bodyExcerpt}`, options);
|
|
18
13
|
this.status = status;
|
|
19
14
|
this.bodyExcerpt = bodyExcerpt;
|
|
20
15
|
this.url = url;
|
|
21
16
|
this.name = 'GitHubFetchError';
|
|
22
17
|
}
|
|
23
18
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Parse the rel="next" URL from an RFC 5988 `Link` header.
|
|
26
|
-
*
|
|
27
|
-
* Header format: `<url1>; rel="next", <url2>; rel="last"`.
|
|
28
|
-
* Returns the URL whose rel parameter is exactly `"next"`, or null.
|
|
29
|
-
*/
|
|
19
|
+
/** Parse the rel="next" URL from an RFC 5988 `Link` header, or null. */
|
|
30
20
|
export function parseNextLink(linkHeader) {
|
|
31
21
|
if (!linkHeader)
|
|
32
22
|
return null;
|
|
@@ -43,6 +33,24 @@ function headersToRecord(h) {
|
|
|
43
33
|
}
|
|
44
34
|
const GITHUB_TIMEOUT_MS = 30_000;
|
|
45
35
|
const ERROR_BODY_SNIPPET_CHARS = 256;
|
|
36
|
+
const UTF8_MAX_BYTES_PER_CHAR = 4;
|
|
37
|
+
// A page is at most 100 items (per_page=100), each with a body of up to 65,536 characters at 4 bytes, plus its fields.
|
|
38
|
+
const GITHUB_MAX_REPLY_BYTES = 32 * 1024 * 1024;
|
|
39
|
+
/** The items of a 200 list reply. A body that is not JSON, is over the cap or is not an array throws, so it never reaches ingest as items. */
|
|
40
|
+
async function readItems(res, url) {
|
|
41
|
+
// The path only: a `next` link comes from the server, so its query string is not ours to print.
|
|
42
|
+
const path = new URL(url).pathname;
|
|
43
|
+
let body;
|
|
44
|
+
try {
|
|
45
|
+
body = await readCappedJson(res, GITHUB_MAX_REPLY_BYTES);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
throw new GitHubFetchError(res.status, errorMessage(err), path, { cause: err });
|
|
49
|
+
}
|
|
50
|
+
if (!Array.isArray(body))
|
|
51
|
+
throw new GitHubFetchError(res.status, 'the reply is not a JSON array', path);
|
|
52
|
+
return body;
|
|
53
|
+
}
|
|
46
54
|
export const realGitHubFetcher = async ({ url, token }) => {
|
|
47
55
|
const res = await fetchWithRetry(url, {
|
|
48
56
|
headers: {
|
|
@@ -56,15 +64,10 @@ export const realGitHubFetcher = async ({ url, token }) => {
|
|
|
56
64
|
// Don't silently turn 401/403/404/500 into empty pages.
|
|
57
65
|
if (res.status !== 200 && rateLimit.reason === 'none') {
|
|
58
66
|
// The status is the error reported; a body that cannot be read only costs its snippet.
|
|
59
|
-
const body = await res
|
|
67
|
+
const body = await readCappedText(res, ERROR_BODY_SNIPPET_CHARS * UTF8_MAX_BYTES_PER_CHAR).catch(() => '');
|
|
60
68
|
throw new GitHubFetchError(res.status, body.slice(0, ERROR_BODY_SNIPPET_CHARS), url);
|
|
61
69
|
}
|
|
62
|
-
|
|
63
|
-
// only endpoints this backfill fetcher targets) return a JSON array body
|
|
64
|
-
// on 200; per-item shape is intentionally left as `unknown` here since
|
|
65
|
-
// GitHubBackfillPage.items is opaque to this seam (callers parse the
|
|
66
|
-
// shape they expect downstream).
|
|
67
|
-
const items = res.status === 200 ? (await res.json()) : [];
|
|
70
|
+
const items = res.status === 200 ? await readItems(res, url) : [];
|
|
68
71
|
const link = res.headers.get('link') ?? '';
|
|
69
72
|
const next = parseNextLink(link);
|
|
70
73
|
return { items, next, rateLimit };
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* GitHub returns 403 for primary rate-limit (with `X-RateLimit-Remaining: 0`
|
|
5
|
-
* and `X-RateLimit-Reset: <epoch>`) and 429 + `Retry-After: <seconds>` for
|
|
6
|
-
* secondary rate-limit. Backfill must pause and resume rather than error.
|
|
7
|
-
*/
|
|
1
|
+
/** GitHub rate-limit header parser: 403 with `X-RateLimit-Remaining: 0` is primary, 429 with `Retry-After` is secondary.
|
|
2
|
+
* Backfill must pause and resume rather than error. */
|
|
8
3
|
export interface RateLimitInfo {
|
|
9
4
|
readonly sleepSeconds: number;
|
|
10
5
|
readonly reason: 'primary' | 'secondary' | 'none';
|
|
11
6
|
}
|
|
12
|
-
/**
|
|
13
|
-
* Parse rate-limit signal from a GitHub HTTP response.
|
|
14
|
-
*
|
|
15
|
-
* @param headers Lower-cased HTTP response headers.
|
|
16
|
-
* @param status HTTP status code.
|
|
17
|
-
* @param now Optional current epoch seconds (for deterministic tests).
|
|
18
|
-
*/
|
|
7
|
+
/** Parse the rate-limit signal from a GitHub response; `headers` are lower-cased and `now` (epoch seconds) is for deterministic tests. */
|
|
19
8
|
export declare function parseRateLimit(headers: Record<string, string | undefined>, status: number, now?: number): RateLimitInfo;
|
|
20
9
|
//# sourceMappingURL=ratelimit.d.ts.map
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
|
|
4
|
-
* GitHub returns 403 for primary rate-limit (with `X-RateLimit-Remaining: 0`
|
|
5
|
-
* and `X-RateLimit-Reset: <epoch>`) and 429 + `Retry-After: <seconds>` for
|
|
6
|
-
* secondary rate-limit. Backfill must pause and resume rather than error.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Parse rate-limit signal from a GitHub HTTP response.
|
|
10
|
-
*
|
|
11
|
-
* @param headers Lower-cased HTTP response headers.
|
|
12
|
-
* @param status HTTP status code.
|
|
13
|
-
* @param now Optional current epoch seconds (for deterministic tests).
|
|
14
|
-
*/
|
|
1
|
+
/** GitHub rate-limit header parser: 403 with `X-RateLimit-Remaining: 0` is primary, 429 with `Retry-After` is secondary.
|
|
2
|
+
* Backfill must pause and resume rather than error. */
|
|
3
|
+
/** Parse the rate-limit signal from a GitHub response; `headers` are lower-cased and `now` (epoch seconds) is for deterministic tests. */
|
|
15
4
|
export function parseRateLimit(headers, status, now) {
|
|
16
5
|
const _now = now ?? Math.floor(Date.now() / 1000);
|
|
17
6
|
if (status === 429) {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { GitHubRepository } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* nothing) << cost of leaking private into public (data exposure).
|
|
6
|
-
*/
|
|
2
|
+
/** Map a GitHub repository to a hippo scope string. Default-private when
|
|
3
|
+
* privacy is undetermined: cost of leaking public into private (recall returns
|
|
4
|
+
* nothing) << cost of leaking private into public (data exposure). */
|
|
7
5
|
export declare function scopeFromRepository(repo: GitHubRepository | undefined): string;
|
|
8
6
|
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* nothing) << cost of leaking private into public (data exposure).
|
|
5
|
-
*/
|
|
1
|
+
/** Map a GitHub repository to a hippo scope string. Default-private when
|
|
2
|
+
* privacy is undetermined: cost of leaking public into private (recall returns
|
|
3
|
+
* nothing) << cost of leaking private into public (data exposure). */
|
|
6
4
|
export function scopeFromRepository(repo) {
|
|
7
5
|
if (!repo)
|
|
8
6
|
return 'github:private:unknown';
|