@cleocode/core 2026.9.22 → 2026.9.24
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/dist/admin/import-tasks.d.ts.map +1 -1
- package/dist/admin/import-tasks.js +35 -6
- package/dist/admin/import-tasks.js.map +1 -1
- package/dist/admin/import.d.ts.map +1 -1
- package/dist/admin/import.js +25 -6
- package/dist/admin/import.js.map +1 -1
- package/dist/build-provenance.json +6 -0
- package/dist/cloud/http.d.ts +8 -0
- package/dist/cloud/http.d.ts.map +1 -1
- package/dist/cloud/http.js +8 -1
- package/dist/cloud/http.js.map +1 -1
- package/dist/cloud/index.d.ts +6 -1
- package/dist/cloud/index.d.ts.map +1 -1
- package/dist/cloud/index.js +6 -1
- package/dist/cloud/index.js.map +1 -1
- package/dist/cloud/nexus-auth.d.ts +169 -0
- package/dist/cloud/nexus-auth.d.ts.map +1 -0
- package/dist/cloud/nexus-auth.js +372 -0
- package/dist/cloud/nexus-auth.js.map +1 -0
- package/dist/cloud/nexus-credentials.d.ts +188 -0
- package/dist/cloud/nexus-credentials.d.ts.map +1 -0
- package/dist/cloud/nexus-credentials.js +323 -0
- package/dist/cloud/nexus-credentials.js.map +1 -0
- package/dist/cloud/nexus-link.d.ts +85 -0
- package/dist/cloud/nexus-link.d.ts.map +1 -0
- package/dist/cloud/nexus-link.js +226 -0
- package/dist/cloud/nexus-link.js.map +1 -0
- package/dist/cloud/presence.d.ts +88 -0
- package/dist/cloud/presence.d.ts.map +1 -0
- package/dist/cloud/presence.js +137 -0
- package/dist/cloud/presence.js.map +1 -0
- package/dist/cloud/projects.d.ts +3 -1
- package/dist/cloud/projects.d.ts.map +1 -1
- package/dist/cloud/projects.js +4 -2
- package/dist/cloud/projects.js.map +1 -1
- package/dist/crypto/credentials.d.ts +14 -4
- package/dist/crypto/credentials.d.ts.map +1 -1
- package/dist/crypto/credentials.js +15 -1
- package/dist/crypto/credentials.js.map +1 -1
- package/dist/decide/audit.d.ts +7 -1
- package/dist/decide/audit.d.ts.map +1 -1
- package/dist/decide/audit.js.map +1 -1
- package/dist/decide/bench/dataset.d.ts +125 -0
- package/dist/decide/bench/dataset.d.ts.map +1 -0
- package/dist/decide/bench/dataset.js +457 -0
- package/dist/decide/bench/dataset.js.map +1 -0
- package/dist/decide/bench/index.d.ts +23 -0
- package/dist/decide/bench/index.d.ts.map +1 -0
- package/dist/decide/bench/index.js +23 -0
- package/dist/decide/bench/index.js.map +1 -0
- package/dist/decide/bench/metrics.d.ts +55 -0
- package/dist/decide/bench/metrics.d.ts.map +1 -0
- package/dist/decide/bench/metrics.js +100 -0
- package/dist/decide/bench/metrics.js.map +1 -0
- package/dist/decide/bench/operation.d.ts +119 -0
- package/dist/decide/bench/operation.d.ts.map +1 -0
- package/dist/decide/bench/operation.js +171 -0
- package/dist/decide/bench/operation.js.map +1 -0
- package/dist/decide/bench/profiles.d.ts +74 -0
- package/dist/decide/bench/profiles.d.ts.map +1 -0
- package/dist/decide/bench/profiles.js +131 -0
- package/dist/decide/bench/profiles.js.map +1 -0
- package/dist/decide/bench/questions.d.ts +40 -0
- package/dist/decide/bench/questions.d.ts.map +1 -0
- package/dist/decide/bench/questions.js +107 -0
- package/dist/decide/bench/questions.js.map +1 -0
- package/dist/decide/bench/report.d.ts +21 -0
- package/dist/decide/bench/report.d.ts.map +1 -0
- package/dist/decide/bench/report.js +120 -0
- package/dist/decide/bench/report.js.map +1 -0
- package/dist/decide/bench/runner.d.ts +203 -0
- package/dist/decide/bench/runner.d.ts.map +1 -0
- package/dist/decide/bench/runner.js +335 -0
- package/dist/decide/bench/runner.js.map +1 -0
- package/dist/decide/bench/source.d.ts +21 -0
- package/dist/decide/bench/source.d.ts.map +1 -0
- package/dist/decide/bench/source.js +67 -0
- package/dist/decide/bench/source.js.map +1 -0
- package/dist/decide/bench/spot-check.d.ts +117 -0
- package/dist/decide/bench/spot-check.d.ts.map +1 -0
- package/dist/decide/bench/spot-check.js +221 -0
- package/dist/decide/bench/spot-check.js.map +1 -0
- package/dist/decide/bench/stats.d.ts +57 -0
- package/dist/decide/bench/stats.d.ts.map +1 -0
- package/dist/decide/bench/stats.js +82 -0
- package/dist/decide/bench/stats.js.map +1 -0
- package/dist/decide/bench/types.d.ts +216 -0
- package/dist/decide/bench/types.d.ts.map +1 -0
- package/dist/decide/bench/types.js +104 -0
- package/dist/decide/bench/types.js.map +1 -0
- package/dist/decide/client.d.ts +80 -4
- package/dist/decide/client.d.ts.map +1 -1
- package/dist/decide/client.js +428 -39
- package/dist/decide/client.js.map +1 -1
- package/dist/decide/credentials.d.ts +200 -16
- package/dist/decide/credentials.d.ts.map +1 -1
- package/dist/decide/credentials.js +547 -45
- package/dist/decide/credentials.js.map +1 -1
- package/dist/decide/index.d.ts +10 -4
- package/dist/decide/index.d.ts.map +1 -1
- package/dist/decide/index.js +10 -4
- package/dist/decide/index.js.map +1 -1
- package/dist/decide/jev-wire.d.ts +105 -7
- package/dist/decide/jev-wire.d.ts.map +1 -1
- package/dist/decide/jev-wire.js +426 -54
- package/dist/decide/jev-wire.js.map +1 -1
- package/dist/decide/operations.d.ts +149 -21
- package/dist/decide/operations.d.ts.map +1 -1
- package/dist/decide/operations.js +241 -31
- package/dist/decide/operations.js.map +1 -1
- package/dist/decide/provider-state.d.ts +162 -0
- package/dist/decide/provider-state.d.ts.map +1 -0
- package/dist/decide/provider-state.js +267 -0
- package/dist/decide/provider-state.js.map +1 -0
- package/dist/decide/provider.d.ts +31 -5
- package/dist/decide/provider.d.ts.map +1 -1
- package/dist/decide/provider.js.map +1 -1
- package/dist/decide/providers.d.ts +71 -0
- package/dist/decide/providers.d.ts.map +1 -0
- package/dist/decide/providers.js +85 -0
- package/dist/decide/providers.js.map +1 -0
- package/dist/decide/site.d.ts +2 -2
- package/dist/decide/site.d.ts.map +1 -1
- package/dist/decide/site.js +2 -0
- package/dist/decide/site.js.map +1 -1
- package/dist/decide/sites/list.d.ts +46 -0
- package/dist/decide/sites/list.d.ts.map +1 -0
- package/dist/decide/sites/list.js +206 -0
- package/dist/decide/sites/list.js.map +1 -0
- package/dist/decide/sites/registry.d.ts +152 -0
- package/dist/decide/sites/registry.d.ts.map +1 -0
- package/dist/decide/sites/registry.js +398 -0
- package/dist/decide/sites/registry.js.map +1 -0
- package/dist/decide/spend.d.ts +196 -0
- package/dist/decide/spend.d.ts.map +1 -0
- package/dist/decide/spend.js +387 -0
- package/dist/decide/spend.js.map +1 -0
- package/dist/decide/wizard.d.ts +61 -0
- package/dist/decide/wizard.d.ts.map +1 -0
- package/dist/decide/wizard.js +197 -0
- package/dist/decide/wizard.js.map +1 -0
- package/dist/dispatch/mvi-projection.d.ts +15 -2
- package/dist/dispatch/mvi-projection.d.ts.map +1 -1
- package/dist/dispatch/mvi-projection.js +73 -12
- package/dist/dispatch/mvi-projection.js.map +1 -1
- package/dist/docs/adr-allocator.d.ts +2 -2
- package/dist/docs/adr-allocator.d.ts.map +1 -1
- package/dist/docs/adr-allocator.js +17 -4
- package/dist/docs/adr-allocator.js.map +1 -1
- package/dist/docs/blob-consolidation.js +1 -1
- package/dist/docs/blob-consolidation.js.map +1 -1
- package/dist/docs/display-alias.d.ts +1 -1
- package/dist/docs/display-alias.d.ts.map +1 -1
- package/dist/docs/display-alias.js +7 -4
- package/dist/docs/display-alias.js.map +1 -1
- package/dist/docs/docs-audit.d.ts.map +1 -1
- package/dist/docs/docs-audit.js +1 -2
- package/dist/docs/docs-audit.js.map +1 -1
- package/dist/docs/docs-inconsistency-detector.js +1 -1
- package/dist/docs/docs-inconsistency-detector.js.map +1 -1
- package/dist/docs/docs-update.d.ts.map +1 -1
- package/dist/docs/docs-update.js +6 -1
- package/dist/docs/docs-update.js.map +1 -1
- package/dist/docs/export-document.js +3462 -1227
- package/dist/docs/export-document.js.map +3 -3
- package/dist/docs/numbering.js +1 -1
- package/dist/docs/numbering.js.map +1 -1
- package/dist/docs/supersede.d.ts.map +1 -1
- package/dist/docs/supersede.js +6 -3
- package/dist/docs/supersede.js.map +1 -1
- package/dist/docs/version-ssot.js +1 -1
- package/dist/docs/version-ssot.js.map +1 -1
- package/dist/doctor/db-substrate.d.ts.map +1 -1
- package/dist/doctor/db-substrate.js +39 -24
- package/dist/doctor/db-substrate.js.map +1 -1
- package/dist/doctor/knowledge-summary.d.ts +10 -3
- package/dist/doctor/knowledge-summary.d.ts.map +1 -1
- package/dist/doctor/knowledge-summary.js +10 -3
- package/dist/doctor/knowledge-summary.js.map +1 -1
- package/dist/doctor/project-identity.d.ts +128 -37
- package/dist/doctor/project-identity.d.ts.map +1 -1
- package/dist/doctor/project-identity.js +476 -63
- package/dist/doctor/project-identity.js.map +1 -1
- package/dist/doctor/twin-collapse.d.ts +52 -2
- package/dist/doctor/twin-collapse.d.ts.map +1 -1
- package/dist/doctor/twin-collapse.js +108 -4
- package/dist/doctor/twin-collapse.js.map +1 -1
- package/dist/error-catalog.js +2 -2
- package/dist/error-catalog.js.map +1 -1
- package/dist/error-registry.js +1 -1
- package/dist/error-registry.js.map +1 -1
- package/dist/gateway-client/generated/types.gen.d.ts +22 -2
- package/dist/gateway-client/generated/types.gen.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/init/scaffold-workflows.d.ts.map +1 -1
- package/dist/init/scaffold-workflows.js +6 -3
- package/dist/init/scaffold-workflows.js.map +1 -1
- package/dist/init/upgrade-workflows.d.ts.map +1 -1
- package/dist/init/upgrade-workflows.js +6 -3
- package/dist/init/upgrade-workflows.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +20 -11
- package/dist/init.js.map +1 -1
- package/dist/inject/index.d.ts.map +1 -1
- package/dist/inject/index.js +2 -3
- package/dist/inject/index.js.map +1 -1
- package/dist/internal.d.ts +6 -5
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +7 -5
- package/dist/internal.js.map +1 -1
- package/dist/llm/credential-remove-entry.d.ts +59 -0
- package/dist/llm/credential-remove-entry.d.ts.map +1 -0
- package/dist/llm/credential-remove-entry.js +101 -0
- package/dist/llm/credential-remove-entry.js.map +1 -0
- package/dist/llm/oauth/device-code.d.ts +26 -6
- package/dist/llm/oauth/device-code.d.ts.map +1 -1
- package/dist/llm/oauth/device-code.js +44 -12
- package/dist/llm/oauth/device-code.js.map +1 -1
- package/dist/llm/plugin-facade.js +3556 -1321
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/memory/attention.d.ts.map +1 -1
- package/dist/memory/attention.js +5 -3
- package/dist/memory/attention.js.map +1 -1
- package/dist/memory/decision-contradiction.d.ts +3 -3
- package/dist/memory/decision-contradiction.d.ts.map +1 -1
- package/dist/memory/decision-contradiction.js +4 -3
- package/dist/memory/decision-contradiction.js.map +1 -1
- package/dist/memory/decisions.d.ts +48 -3
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/memory/decisions.js +98 -14
- package/dist/memory/decisions.js.map +1 -1
- package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
- package/dist/memory/graph-memory-bridge.js +2 -0
- package/dist/memory/graph-memory-bridge.js.map +1 -1
- package/dist/memory/learnings.d.ts +6 -6
- package/dist/memory/observation-type-decision.d.ts +2 -2
- package/dist/memory/observation-type-decision.d.ts.map +1 -1
- package/dist/memory/observation-type-decision.js +3 -2
- package/dist/memory/observation-type-decision.js.map +1 -1
- package/dist/memory/patterns.d.ts +4 -4
- package/dist/memory/pipeline-manifest-sqlite.d.ts +111 -0
- package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.js +230 -2
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
- package/dist/migration/manual/T10165-backfill-adr-index.d.ts.map +1 -1
- package/dist/migration/manual/T10165-backfill-adr-index.js +5 -1
- package/dist/migration/manual/T10165-backfill-adr-index.js.map +1 -1
- package/dist/nexus/fleet-status.d.ts +83 -0
- package/dist/nexus/fleet-status.d.ts.map +1 -0
- package/dist/nexus/fleet-status.js +414 -0
- package/dist/nexus/fleet-status.js.map +1 -0
- package/dist/nexus/git-state.d.ts +15 -0
- package/dist/nexus/git-state.d.ts.map +1 -1
- package/dist/nexus/git-state.js +67 -2
- package/dist/nexus/git-state.js.map +1 -1
- package/dist/nexus/identity.d.ts.map +1 -1
- package/dist/nexus/identity.js +4 -0
- package/dist/nexus/identity.js.map +1 -1
- package/dist/nexus/index.d.ts +4 -1
- package/dist/nexus/index.d.ts.map +1 -1
- package/dist/nexus/index.js +7 -1
- package/dist/nexus/index.js.map +1 -1
- package/dist/nexus/migrate-json-to-sqlite.d.ts +3 -2
- package/dist/nexus/migrate-json-to-sqlite.d.ts.map +1 -1
- package/dist/nexus/migrate-json-to-sqlite.js +9 -17
- package/dist/nexus/migrate-json-to-sqlite.js.map +1 -1
- package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
- package/dist/nexus/migrations/M-split-graph.js +4 -0
- package/dist/nexus/migrations/M-split-graph.js.map +1 -1
- package/dist/nexus/ops.d.ts +1 -0
- package/dist/nexus/ops.d.ts.map +1 -1
- package/dist/nexus/project-activity.d.ts +104 -0
- package/dist/nexus/project-activity.d.ts.map +1 -0
- package/dist/nexus/project-activity.js +150 -0
- package/dist/nexus/project-activity.js.map +1 -0
- package/dist/nexus/query.d.ts +2 -2
- package/dist/nexus/query.d.ts.map +1 -1
- package/dist/nexus/query.js +4 -19
- package/dist/nexus/query.js.map +1 -1
- package/dist/nexus/registry-errors.d.ts +61 -0
- package/dist/nexus/registry-errors.d.ts.map +1 -0
- package/dist/nexus/registry-errors.js +85 -0
- package/dist/nexus/registry-errors.js.map +1 -0
- package/dist/nexus/registry.d.ts +30 -5
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +115 -70
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/store.d.ts.map +1 -1
- package/dist/nexus/store.js +2 -0
- package/dist/nexus/store.js.map +1 -1
- package/dist/orchestrate/pivot.d.ts +4 -0
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +82 -14
- package/dist/orchestrate/pivot.js.map +1 -1
- package/dist/orchestrate/plan.d.ts.map +1 -1
- package/dist/orchestrate/plan.js +3 -0
- package/dist/orchestrate/plan.js.map +1 -1
- package/dist/orchestrate/query-ops.d.ts.map +1 -1
- package/dist/orchestrate/query-ops.js +29 -27
- package/dist/orchestrate/query-ops.js.map +1 -1
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +29 -3
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/bootstrap.d.ts.map +1 -1
- package/dist/orchestration/bootstrap.js +20 -14
- package/dist/orchestration/bootstrap.js.map +1 -1
- package/dist/orchestration/index.d.ts +15 -1
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +25 -6
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lead-rollup.d.ts +7 -1
- package/dist/orchestration/lead-rollup.d.ts.map +1 -1
- package/dist/orchestration/lead-rollup.js +20 -5
- package/dist/orchestration/lead-rollup.js.map +1 -1
- package/dist/orchestration/owner-decision-readiness.d.ts +2 -2
- package/dist/orchestration/owner-decision-readiness.d.ts.map +1 -1
- package/dist/orchestration/owner-decision-readiness.js +3 -2
- package/dist/orchestration/owner-decision-readiness.js.map +1 -1
- package/dist/orchestration/spawn-prompt.js +1 -1
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/orchestration/validate-spawn.d.ts.map +1 -1
- package/dist/orchestration/validate-spawn.js +2 -0
- package/dist/orchestration/validate-spawn.js.map +1 -1
- package/dist/orchestration/waves.d.ts +21 -10
- package/dist/orchestration/waves.d.ts.map +1 -1
- package/dist/orchestration/waves.js +38 -35
- package/dist/orchestration/waves.js.map +1 -1
- package/dist/paths.d.ts +9 -2
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +30 -13
- package/dist/paths.js.map +1 -1
- package/dist/phases/index.d.ts +1 -1
- package/dist/phases/index.d.ts.map +1 -1
- package/dist/phases/index.js +3 -4
- package/dist/phases/index.js.map +1 -1
- package/dist/project-info.d.ts +40 -3
- package/dist/project-info.d.ts.map +1 -1
- package/dist/project-info.js +74 -6
- package/dist/project-info.js.map +1 -1
- package/dist/project-lifecycle.d.ts +28 -7
- package/dist/project-lifecycle.d.ts.map +1 -1
- package/dist/project-lifecycle.js +114 -47
- package/dist/project-lifecycle.js.map +1 -1
- package/dist/project-scope.d.ts +86 -3
- package/dist/project-scope.d.ts.map +1 -1
- package/dist/project-scope.js +192 -17
- package/dist/project-scope.js.map +1 -1
- package/dist/release/github-pr.d.ts.map +1 -1
- package/dist/release/github-pr.js +2 -1
- package/dist/release/github-pr.js.map +1 -1
- package/dist/release/open.d.ts +12 -2
- package/dist/release/open.d.ts.map +1 -1
- package/dist/release/open.js +32 -3
- package/dist/release/open.js.map +1 -1
- package/dist/release/preflight-skip.d.ts +73 -0
- package/dist/release/preflight-skip.d.ts.map +1 -0
- package/dist/release/preflight-skip.js +254 -0
- package/dist/release/preflight-skip.js.map +1 -0
- package/dist/render/decide/index.d.ts +51 -0
- package/dist/render/decide/index.d.ts.map +1 -0
- package/dist/render/decide/index.js +289 -0
- package/dist/render/decide/index.js.map +1 -0
- package/dist/render/index.d.ts +1 -0
- package/dist/render/index.d.ts.map +1 -1
- package/dist/render/index.js +1 -0
- package/dist/render/index.js.map +1 -1
- package/dist/render/nexus/graph/index.d.ts +5 -0
- package/dist/render/nexus/graph/index.d.ts.map +1 -1
- package/dist/render/nexus/graph/index.js +53 -0
- package/dist/render/nexus/graph/index.js.map +1 -1
- package/dist/routing/capability-matrix.d.ts.map +1 -1
- package/dist/routing/capability-matrix.js +7 -0
- package/dist/routing/capability-matrix.js.map +1 -1
- package/dist/scaffold/ensure-config.d.ts +14 -6
- package/dist/scaffold/ensure-config.d.ts.map +1 -1
- package/dist/scaffold/ensure-config.js +39 -17
- package/dist/scaffold/ensure-config.js.map +1 -1
- package/dist/scaffold/project-identity.d.ts +115 -23
- package/dist/scaffold/project-identity.d.ts.map +1 -1
- package/dist/scaffold/project-identity.js +196 -44
- package/dist/scaffold/project-identity.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +3569 -1334
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sentient/cross-project-hygiene.d.ts +12 -6
- package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
- package/dist/sentient/cross-project-hygiene.js +15 -10
- package/dist/sentient/cross-project-hygiene.js.map +1 -1
- package/dist/session/engine-ops.d.ts +13 -4
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +38 -45
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/briefing.d.ts +7 -3
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +32 -71
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/drift-watchdog.d.ts.map +1 -1
- package/dist/sessions/drift-watchdog.js +11 -19
- package/dist/sessions/drift-watchdog.js.map +1 -1
- package/dist/sessions/focus-state-store.d.ts +109 -27
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +171 -39
- package/dist/sessions/focus-state-store.js.map +1 -1
- package/dist/sessions/handoff.d.ts.map +1 -1
- package/dist/sessions/handoff.js +9 -18
- package/dist/sessions/handoff.js.map +1 -1
- package/dist/sessions/index.d.ts +4 -2
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +35 -6
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/session-drift.d.ts.map +1 -1
- package/dist/sessions/session-drift.js +4 -2
- package/dist/sessions/session-drift.js.map +1 -1
- package/dist/sessions/session-view.d.ts +8 -1
- package/dist/sessions/session-view.d.ts.map +1 -1
- package/dist/sessions/session-view.js +9 -2
- package/dist/sessions/session-view.js.map +1 -1
- package/dist/setup/config-json-merge.d.ts +28 -0
- package/dist/setup/config-json-merge.d.ts.map +1 -1
- package/dist/setup/config-json-merge.js +52 -0
- package/dist/setup/config-json-merge.js.map +1 -1
- package/dist/setup/index.d.ts +15 -10
- package/dist/setup/index.d.ts.map +1 -1
- package/dist/setup/index.js +19 -10
- package/dist/setup/index.js.map +1 -1
- package/dist/setup/sections/llm.js +1 -1
- package/dist/setup/sections/llm.js.map +1 -1
- package/dist/setup/sections/nexus-account.d.ts +32 -0
- package/dist/setup/sections/nexus-account.d.ts.map +1 -0
- package/dist/setup/sections/nexus-account.js +64 -0
- package/dist/setup/sections/nexus-account.js.map +1 -0
- package/dist/setup/sections/system-one.d.ts +28 -0
- package/dist/setup/sections/system-one.d.ts.map +1 -0
- package/dist/setup/sections/system-one.js +53 -0
- package/dist/setup/sections/system-one.js.map +1 -0
- package/dist/setup/wizard.d.ts +15 -1
- package/dist/setup/wizard.d.ts.map +1 -1
- package/dist/setup/wizard.js +15 -0
- package/dist/setup/wizard.js.map +1 -1
- package/dist/skills/orchestrator/startup.d.ts.map +1 -1
- package/dist/skills/orchestrator/startup.js +18 -31
- package/dist/skills/orchestrator/startup.js.map +1 -1
- package/dist/skills/prune-bundled.d.ts +40 -1
- package/dist/skills/prune-bundled.d.ts.map +1 -1
- package/dist/skills/prune-bundled.js +117 -1
- package/dist/skills/prune-bundled.js.map +1 -1
- package/dist/snapshot/index.d.ts.map +1 -1
- package/dist/snapshot/index.js +60 -53
- package/dist/snapshot/index.js.map +1 -1
- package/dist/spawn/agent-identity.d.ts +33 -1
- package/dist/spawn/agent-identity.d.ts.map +1 -1
- package/dist/spawn/agent-identity.js +53 -1
- package/dist/spawn/agent-identity.js.map +1 -1
- package/dist/spawn/index.d.ts +1 -1
- package/dist/spawn/index.d.ts.map +1 -1
- package/dist/spawn/index.js +1 -1
- package/dist/spawn/index.js.map +1 -1
- package/dist/stats/index.d.ts.map +1 -1
- package/dist/stats/index.js +3 -4
- package/dist/stats/index.js.map +1 -1
- package/dist/status/index.d.ts +12 -3
- package/dist/status/index.d.ts.map +1 -1
- package/dist/status/index.js +47 -5
- package/dist/status/index.js.map +1 -1
- package/dist/store/agent-registry-accessor.d.ts.map +1 -1
- package/dist/store/agent-registry-accessor.js +2 -0
- package/dist/store/agent-registry-accessor.js.map +1 -1
- package/dist/store/attachment-repair.d.ts.map +1 -1
- package/dist/store/attachment-repair.js +42 -3
- package/dist/store/attachment-repair.js.map +1 -1
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +30 -46
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/backup-pack.js +1 -1
- package/dist/store/backup-pack.js.map +1 -1
- package/dist/store/backup-recover-brain.d.ts +4 -0
- package/dist/store/backup-recover-brain.d.ts.map +1 -1
- package/dist/store/backup-recover-brain.js +2 -0
- package/dist/store/backup-recover-brain.js.map +1 -1
- package/dist/store/backup-recover.d.ts +9 -0
- package/dist/store/backup-recover.d.ts.map +1 -1
- package/dist/store/backup-recover.js +28 -1
- package/dist/store/backup-recover.js.map +1 -1
- package/dist/store/backup-sidecar.d.ts +30 -0
- package/dist/store/backup-sidecar.d.ts.map +1 -1
- package/dist/store/backup-sidecar.js +90 -2
- package/dist/store/backup-sidecar.js.map +1 -1
- package/dist/store/backup.d.ts +15 -1
- package/dist/store/backup.d.ts.map +1 -1
- package/dist/store/backup.js +18 -2
- package/dist/store/backup.js.map +1 -1
- package/dist/store/blob-keep.d.ts +135 -0
- package/dist/store/blob-keep.d.ts.map +1 -0
- package/dist/store/blob-keep.js +283 -0
- package/dist/store/blob-keep.js.map +1 -0
- package/dist/store/conduit-sqlite.d.ts.map +1 -1
- package/dist/store/conduit-sqlite.js +3 -0
- package/dist/store/conduit-sqlite.js.map +1 -1
- package/dist/store/converters.d.ts.map +1 -1
- package/dist/store/converters.js +11 -0
- package/dist/store/converters.js.map +1 -1
- package/dist/store/credential-transfer.d.ts +37 -5
- package/dist/store/credential-transfer.d.ts.map +1 -1
- package/dist/store/credential-transfer.js +75 -18
- package/dist/store/credential-transfer.js.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.js +2 -0
- package/dist/store/cross-db-cleanup.js.map +1 -1
- package/dist/store/data-accessor.d.ts +1 -1
- package/dist/store/data-accessor.d.ts.map +1 -1
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/db-helpers.d.ts +18 -0
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +46 -0
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +13 -2
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +35 -0
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/runtime-targets.d.ts +3 -3
- package/dist/store/exodus/runtime-targets.js +3 -3
- package/dist/store/import-remap.d.ts +12 -1
- package/dist/store/import-remap.d.ts.map +1 -1
- package/dist/store/import-remap.js +14 -0
- package/dist/store/import-remap.js.map +1 -1
- package/dist/store/legacy-tasks-lineage.d.ts +3 -1
- package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
- package/dist/store/legacy-tasks-lineage.js +3 -1
- package/dist/store/legacy-tasks-lineage.js.map +1 -1
- package/dist/store/memory-accessor.js +1 -1
- package/dist/store/memory-accessor.js.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.js +3 -0
- package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
- package/dist/store/migration-manager.d.ts +61 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +138 -6
- package/dist/store/migration-manager.js.map +1 -1
- package/dist/store/migration-sqlite.d.ts.map +1 -1
- package/dist/store/migration-sqlite.js +2 -0
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/nexus-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-sqlite.js +3 -0
- package/dist/store/nexus-sqlite.js.map +1 -1
- package/dist/store/nexus-validation-schemas.d.ts +64 -0
- package/dist/store/nexus-validation-schemas.d.ts.map +1 -1
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +3 -0
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/portable-bundle-import.d.ts +8 -0
- package/dist/store/portable-bundle-import.d.ts.map +1 -1
- package/dist/store/portable-bundle-import.js +12 -0
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
- package/dist/store/portable-bundle-relocate.js +2 -0
- package/dist/store/portable-bundle-relocate.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +2 -1
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/portable-bundle.d.ts.map +1 -1
- package/dist/store/portable-bundle.js +15 -14
- package/dist/store/portable-bundle.js.map +1 -1
- package/dist/store/ports/domain-binding.d.ts.map +1 -1
- package/dist/store/ports/domain-binding.js +5 -0
- package/dist/store/ports/domain-binding.js.map +1 -1
- package/dist/store/pre-repair-snapshot.d.ts +4 -1
- package/dist/store/pre-repair-snapshot.d.ts.map +1 -1
- package/dist/store/pre-repair-snapshot.js +5 -1
- package/dist/store/pre-repair-snapshot.js.map +1 -1
- package/dist/store/regenerators.d.ts +4 -2
- package/dist/store/regenerators.d.ts.map +1 -1
- package/dist/store/regenerators.js +7 -3
- package/dist/store/regenerators.js.map +1 -1
- package/dist/store/repair-malformed-dbs.d.ts +4 -0
- package/dist/store/repair-malformed-dbs.d.ts.map +1 -1
- package/dist/store/repair-malformed-dbs.js +3 -0
- package/dist/store/repair-malformed-dbs.js.map +1 -1
- package/dist/store/safety-data-accessor.d.ts +8 -3
- package/dist/store/safety-data-accessor.d.ts.map +1 -1
- package/dist/store/safety-data-accessor.js +11 -4
- package/dist/store/safety-data-accessor.js.map +1 -1
- package/dist/store/schema/cleo-global/nexus.d.ts +48 -0
- package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/nexus.js +17 -0
- package/dist/store/schema/cleo-global/nexus.js.map +1 -1
- package/dist/store/schema/cleo-project/docs.d.ts +16 -0
- package/dist/store/schema/cleo-project/docs.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/docs.js +10 -0
- package/dist/store/schema/cleo-project/docs.js.map +1 -1
- package/dist/store/schema/cleo-project/tasks-core.d.ts +80 -0
- package/dist/store/schema/cleo-project/tasks-core.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/tasks-core.js +25 -1
- package/dist/store/schema/cleo-project/tasks-core.js.map +1 -1
- package/dist/store/schema/cleo-shared/brain.d.ts +1 -1
- package/dist/store/schema/memory-schema.d.ts +1 -1
- package/dist/store/schema/nexus-schema.d.ts +48 -0
- package/dist/store/schema/nexus-schema.d.ts.map +1 -1
- package/dist/store/schema/nexus-schema.js +28 -7
- package/dist/store/schema/nexus-schema.js.map +1 -1
- package/dist/store/session-store.d.ts +65 -0
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +108 -7
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/split-brain-import.d.ts.map +1 -1
- package/dist/store/split-brain-import.js +2 -0
- package/dist/store/split-brain-import.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +252 -47
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite-native.d.ts.map +1 -1
- package/dist/store/sqlite-native.js +1 -0
- package/dist/store/sqlite-native.js.map +1 -1
- package/dist/store/sqlite.d.ts +15 -3
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +57 -20
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/store-write-guard.d.ts +9 -3
- package/dist/store/store-write-guard.d.ts.map +1 -1
- package/dist/store/store-write-guard.js +25 -4
- package/dist/store/store-write-guard.js.map +1 -1
- package/dist/store/table-classification.d.ts +1 -1
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +34 -8
- package/dist/store/table-classification.js.map +1 -1
- package/dist/store/task-claim.d.ts +144 -0
- package/dist/store/task-claim.d.ts.map +1 -0
- package/dist/store/task-claim.js +195 -0
- package/dist/store/task-claim.js.map +1 -0
- package/dist/store/task-version.d.ts +43 -5
- package/dist/store/task-version.d.ts.map +1 -1
- package/dist/store/task-version.js +113 -17
- package/dist/store/task-version.js.map +1 -1
- package/dist/store/tasks-schema.d.ts +2 -0
- package/dist/store/tasks-schema.d.ts.map +1 -1
- package/dist/store/tasks-schema.js +1 -0
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/store/tasks-sqlite.js +1 -1
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/twin-collapse.d.ts +339 -22
- package/dist/store/twin-collapse.d.ts.map +1 -1
- package/dist/store/twin-collapse.js +1323 -48
- package/dist/store/twin-collapse.js.map +1 -1
- package/dist/store/umbrella-data-accessor.d.ts +8 -3
- package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
- package/dist/store/umbrella-data-accessor.js +10 -4
- package/dist/store/umbrella-data-accessor.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +161 -1
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/dist/store/with-retry.d.ts +36 -0
- package/dist/store/with-retry.d.ts.map +1 -1
- package/dist/store/with-retry.js +51 -0
- package/dist/store/with-retry.js.map +1 -1
- package/dist/store/worktree-build-guard.d.ts +200 -0
- package/dist/store/worktree-build-guard.d.ts.map +1 -0
- package/dist/store/worktree-build-guard.js +497 -0
- package/dist/store/worktree-build-guard.js.map +1 -0
- package/dist/store/worktree-isolation-guard.d.ts +138 -0
- package/dist/store/worktree-isolation-guard.d.ts.map +1 -1
- package/dist/store/worktree-isolation-guard.js +189 -2
- package/dist/store/worktree-isolation-guard.js.map +1 -1
- package/dist/store/writer-lease.d.ts.map +1 -1
- package/dist/store/writer-lease.js +2 -0
- package/dist/store/writer-lease.js.map +1 -1
- package/dist/system/backup.d.ts +13 -2
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +11 -3
- package/dist/system/backup.js.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +3 -1
- package/dist/system/health.js.map +1 -1
- package/dist/system/inject-generate.d.ts.map +1 -1
- package/dist/system/inject-generate.js +23 -10
- package/dist/system/inject-generate.js.map +1 -1
- package/dist/system/project-health.d.ts +8 -0
- package/dist/system/project-health.d.ts.map +1 -1
- package/dist/system/project-health.js +13 -5
- package/dist/system/project-health.js.map +1 -1
- package/dist/task-tools/index.d.ts +4 -2
- package/dist/task-tools/index.d.ts.map +1 -1
- package/dist/task-tools/index.js +3 -2
- package/dist/task-tools/index.js.map +1 -1
- package/dist/task-tools/score-task-priority.d.ts +131 -18
- package/dist/task-tools/score-task-priority.d.ts.map +1 -1
- package/dist/task-tools/score-task-priority.js +243 -80
- package/dist/task-tools/score-task-priority.js.map +1 -1
- package/dist/task-work/claims.d.ts +215 -0
- package/dist/task-work/claims.d.ts.map +1 -0
- package/dist/task-work/claims.js +272 -0
- package/dist/task-work/claims.js.map +1 -0
- package/dist/task-work/index.d.ts +47 -3
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +74 -41
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +3 -2
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +5 -1
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +21 -3
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/analyze.d.ts +29 -1
- package/dist/tasks/analyze.d.ts.map +1 -1
- package/dist/tasks/analyze.js +47 -37
- package/dist/tasks/analyze.js.map +1 -1
- package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
- package/dist/tasks/backfill-child-projections.js +4 -1
- package/dist/tasks/backfill-child-projections.js.map +1 -1
- package/dist/tasks/change-set.d.ts +5 -0
- package/dist/tasks/change-set.d.ts.map +1 -1
- package/dist/tasks/change-set.js +75 -6
- package/dist/tasks/change-set.js.map +1 -1
- package/dist/tasks/command-line.d.ts +54 -0
- package/dist/tasks/command-line.d.ts.map +1 -0
- package/dist/tasks/command-line.js +151 -0
- package/dist/tasks/command-line.js.map +1 -0
- package/dist/tasks/complete.d.ts +16 -0
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +27 -7
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/component-pr.d.ts +162 -1
- package/dist/tasks/component-pr.d.ts.map +1 -1
- package/dist/tasks/component-pr.js +639 -53
- package/dist/tasks/component-pr.js.map +1 -1
- package/dist/tasks/delete.d.ts.map +1 -1
- package/dist/tasks/delete.js +20 -0
- package/dist/tasks/delete.js.map +1 -1
- package/dist/tasks/done-record.d.ts +14 -1
- package/dist/tasks/done-record.d.ts.map +1 -1
- package/dist/tasks/done-record.js +37 -0
- package/dist/tasks/done-record.js.map +1 -1
- package/dist/tasks/duplicate-detector.d.ts +23 -4
- package/dist/tasks/duplicate-detector.d.ts.map +1 -1
- package/dist/tasks/duplicate-detector.js +14 -5
- package/dist/tasks/duplicate-detector.js.map +1 -1
- package/dist/tasks/engine-wrap-ops.d.ts +48 -10
- package/dist/tasks/engine-wrap-ops.d.ts.map +1 -1
- package/dist/tasks/engine-wrap-ops.js +78 -10
- package/dist/tasks/engine-wrap-ops.js.map +1 -1
- package/dist/tasks/engine-wrap.d.ts +1 -1
- package/dist/tasks/engine-wrap.d.ts.map +1 -1
- package/dist/tasks/engine-wrap.js +1 -1
- package/dist/tasks/engine-wrap.js.map +1 -1
- package/dist/tasks/evidence.d.ts +2 -0
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +30 -4
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +48 -12
- package/dist/tasks/gate-runner.js.map +1 -1
- package/dist/tasks/graph-ops.d.ts +9 -2
- package/dist/tasks/graph-ops.d.ts.map +1 -1
- package/dist/tasks/graph-ops.js +24 -32
- package/dist/tasks/graph-ops.js.map +1 -1
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/ops.d.ts +1 -0
- package/dist/tasks/ops.d.ts.map +1 -1
- package/dist/tasks/plan.d.ts.map +1 -1
- package/dist/tasks/plan.js +16 -60
- package/dist/tasks/plan.js.map +1 -1
- package/dist/tasks/ranking-audit.d.ts +122 -0
- package/dist/tasks/ranking-audit.d.ts.map +1 -0
- package/dist/tasks/ranking-audit.js +193 -0
- package/dist/tasks/ranking-audit.js.map +1 -0
- package/dist/tasks/task-analyze.d.ts.map +1 -1
- package/dist/tasks/task-analyze.js +19 -32
- package/dist/tasks/task-analyze.js.map +1 -1
- package/dist/tasks/task-context.d.ts.map +1 -1
- package/dist/tasks/task-context.js +13 -0
- package/dist/tasks/task-context.js.map +1 -1
- package/dist/tasks/task-import.d.ts.map +1 -1
- package/dist/tasks/task-import.js +21 -12
- package/dist/tasks/task-import.js.map +1 -1
- package/dist/tasks/task-next.d.ts +67 -2
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +99 -102
- package/dist/tasks/task-next.js.map +1 -1
- package/dist/tasks/task-ops.d.ts +1 -1
- package/dist/tasks/task-ops.d.ts.map +1 -1
- package/dist/tasks/task-ops.js +1 -1
- package/dist/tasks/task-ops.js.map +1 -1
- package/dist/tasks/tool-resolver.d.ts +7 -1
- package/dist/tasks/tool-resolver.d.ts.map +1 -1
- package/dist/tasks/tool-resolver.js +24 -10
- package/dist/tasks/tool-resolver.js.map +1 -1
- package/dist/tasks/update.d.ts +8 -2
- package/dist/tasks/update.d.ts.map +1 -1
- package/dist/tasks/update.js +35 -6
- package/dist/tasks/update.js.map +1 -1
- package/dist/telemetry/sqlite.d.ts.map +1 -1
- package/dist/telemetry/sqlite.js +2 -0
- package/dist/telemetry/sqlite.js.map +1 -1
- package/dist/upgrade.d.ts +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +48 -9
- package/dist/upgrade.js.map +1 -1
- package/dist/validation/doctor/checks.d.ts +20 -6
- package/dist/validation/doctor/checks.d.ts.map +1 -1
- package/dist/validation/doctor/checks.js +53 -10
- package/dist/validation/doctor/checks.js.map +1 -1
- package/dist/validation/validate-ops.d.ts.map +1 -1
- package/dist/validation/validate-ops.js +2 -3
- package/dist/validation/validate-ops.js.map +1 -1
- package/migrations/drizzle-cleo-global/20260929010000_t12512-registry-probed-opened/migration.sql +35 -0
- package/migrations/drizzle-cleo-global/20260929020000_t12721-git-state-head-committed-at/migration.sql +25 -0
- package/migrations/drizzle-cleo-project/20260929000000_t12535-docs-attachments-union-shape/migration.sql +21 -0
- package/migrations/drizzle-cleo-project/20260929120000_t12502-task-claim-leases/migration.sql +77 -0
- package/migrations/drizzle-cleo-project/20260929130000_t12736-claim-lease-iso-repair/migration.sql +37 -0
- package/package.json +24 -14
- package/schemas/config.schema.json +13 -0
- package/schemas/project-info.schema.json +10 -4
- package/templates/CLEO-INJECTION.md +1 -1
- package/templates/CLEO-REFERENCE.md +7 -3
- package/templates/cleo-gitignore +11 -0
- package/templates/workflows/release-prepare.yml.tmpl +156 -10
|
@@ -15,23 +15,107 @@
|
|
|
15
15
|
* - its files are the ones its merge commit changed that still exist in the
|
|
16
16
|
* integration PR's merge commit — never the whole integration diff.
|
|
17
17
|
*
|
|
18
|
+
* A component that did not merge into the integration branch as a PR — closed
|
|
19
|
+
* by hand after a `git merge --no-ff`, marked merged by GitHub, stacked on
|
|
20
|
+
* another component, main-merged afterwards, or rebased into the batch — is
|
|
21
|
+
* verified commit by commit instead (T12710): every commit of its own is in
|
|
22
|
+
* the integration merge by ancestry, or by `git patch-id` when rebased, and
|
|
23
|
+
* {@link findComponentLanding} follows it to that integration PR.
|
|
24
|
+
*
|
|
18
25
|
* @task T12671
|
|
19
26
|
* @task T12672
|
|
27
|
+
* @task T12710
|
|
20
28
|
*/
|
|
21
29
|
import { execFileSync } from 'node:child_process';
|
|
22
|
-
import {
|
|
23
|
-
|
|
30
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
31
|
+
import { tmpdir } from 'node:os';
|
|
32
|
+
import { join } from 'node:path';
|
|
33
|
+
import { ghQueryTimeoutMs, ghTimeoutReason, isGhTimeout } from '../release/github-pr.js';
|
|
34
|
+
/** Output ceiling for ordinary git reads. */
|
|
35
|
+
const GIT_MAX_BUFFER = 64 * 1024 * 1024;
|
|
36
|
+
/** Default deadline for one git subprocess. */
|
|
37
|
+
const GIT_TIMEOUT_MS = 30_000;
|
|
38
|
+
/** Default ceiling on the patch a candidate's merge introduces (patch-id mapping). */
|
|
39
|
+
const CANDIDATE_PATCH_MAX_BYTES = 32 * 1024 * 1024;
|
|
40
|
+
/** Default total time spent checking body-hint candidates. */
|
|
41
|
+
const CANDIDATE_BUDGET_MS = 60_000;
|
|
42
|
+
function envInt(name, fallback) {
|
|
43
|
+
const raw = Number(process.env[name]);
|
|
44
|
+
return Number.isInteger(raw) && raw > 0 ? raw : fallback;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Deadline for one git subprocess in component verification
|
|
48
|
+
* (`CLEO_GIT_TIMEOUT_MS`, default 30 s). A read that outlives it is killed
|
|
49
|
+
* and the verification refuses with `E_EVIDENCE_TOOL_FAILED` (T12710 review).
|
|
50
|
+
*
|
|
51
|
+
* @returns Milliseconds.
|
|
52
|
+
* @task T12710
|
|
53
|
+
*/
|
|
54
|
+
export function gitTimeoutMs() {
|
|
55
|
+
return envInt('CLEO_GIT_TIMEOUT_MS', GIT_TIMEOUT_MS);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A git subprocess outlived {@link gitTimeoutMs} and was killed.
|
|
59
|
+
*
|
|
60
|
+
* @task T12710
|
|
61
|
+
*/
|
|
62
|
+
export class GitTimeoutError extends Error {
|
|
63
|
+
/** @param args - The git arguments that timed out. */
|
|
64
|
+
constructor(args) {
|
|
65
|
+
super(`git ${args.slice(0, 3).join(' ')} timed out after ${gitTimeoutMs()}ms (CLEO_GIT_TIMEOUT_MS); the repository or the range is too large to verify here.`);
|
|
66
|
+
this.name = 'GitTimeoutError';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** git output exceeded its buffer ceiling. */
|
|
70
|
+
class GitOutputTooLargeError extends Error {
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Run one bounded git subprocess. SIGKILL at the deadline; lazy fetches of a
|
|
74
|
+
* partial clone are disabled (`GIT_NO_LAZY_FETCH`) so git spawns no network
|
|
75
|
+
* child that could outlive it, and no credential prompt can block.
|
|
76
|
+
*
|
|
77
|
+
* @throws GitTimeoutError at the deadline; GitOutputTooLargeError past
|
|
78
|
+
* `maxBuffer`; the exec error for any other failure.
|
|
79
|
+
*/
|
|
80
|
+
function runGit(root, args, opts = {}) {
|
|
24
81
|
try {
|
|
25
82
|
return execFileSync('git', args, {
|
|
26
83
|
cwd: root,
|
|
27
84
|
encoding: 'utf-8',
|
|
28
|
-
|
|
29
|
-
|
|
85
|
+
input: opts.input,
|
|
86
|
+
stdio: [opts.input === undefined ? 'ignore' : 'pipe', 'pipe', 'ignore'],
|
|
87
|
+
env: { ...(opts.env ?? process.env), GIT_NO_LAZY_FETCH: '1', GIT_TERMINAL_PROMPT: '0' },
|
|
88
|
+
maxBuffer: opts.maxBuffer ?? GIT_MAX_BUFFER,
|
|
89
|
+
timeout: gitTimeoutMs(),
|
|
90
|
+
killSignal: 'SIGKILL',
|
|
91
|
+
});
|
|
30
92
|
}
|
|
31
|
-
catch {
|
|
93
|
+
catch (err) {
|
|
94
|
+
const code = err?.code;
|
|
95
|
+
if (code === 'ETIMEDOUT')
|
|
96
|
+
throw new GitTimeoutError(args);
|
|
97
|
+
if (code === 'ENOBUFS')
|
|
98
|
+
throw new GitOutputTooLargeError(`git ${args[0]} output too large`);
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** A bounded git read, trimmed; null on failure. A timeout propagates. */
|
|
103
|
+
function git(root, args) {
|
|
104
|
+
try {
|
|
105
|
+
return runGit(root, args).trim();
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (err instanceof GitTimeoutError)
|
|
109
|
+
throw err;
|
|
32
110
|
return null;
|
|
33
111
|
}
|
|
34
112
|
}
|
|
113
|
+
/** Map a timeout to the refusal every entry point returns; rethrow anything else. */
|
|
114
|
+
function timeoutRefusal(err) {
|
|
115
|
+
if (err instanceof GitTimeoutError)
|
|
116
|
+
return refuse('E_EVIDENCE_TOOL_FAILED', err.message);
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
35
119
|
function hasCommit(root, sha) {
|
|
36
120
|
return (typeof sha === 'string' &&
|
|
37
121
|
sha !== '' &&
|
|
@@ -46,7 +130,7 @@ export const defaultViewComponentPr = async (prNumber, root) => {
|
|
|
46
130
|
'view',
|
|
47
131
|
String(prNumber),
|
|
48
132
|
'--json',
|
|
49
|
-
'number,title,body,headRefName,baseRefName,state,mergeCommit',
|
|
133
|
+
'number,title,body,headRefName,baseRefName,state,mergeCommit,headRefOid,commits',
|
|
50
134
|
], {
|
|
51
135
|
cwd: root,
|
|
52
136
|
encoding: 'utf-8',
|
|
@@ -69,8 +153,22 @@ export const defaultViewComponentPr = async (prNumber, root) => {
|
|
|
69
153
|
baseRefName: str(row.baseRefName),
|
|
70
154
|
state: str(row.state),
|
|
71
155
|
mergeCommitSha: typeof merge?.oid === 'string' ? merge.oid : null,
|
|
156
|
+
headRefOid: typeof row.headRefOid === 'string' ? row.headRefOid : null,
|
|
157
|
+
commits: commitOids(row.commits),
|
|
72
158
|
};
|
|
73
159
|
};
|
|
160
|
+
/** `commits[].oid` of a `gh --json commits` row, oldest first. */
|
|
161
|
+
function commitOids(raw) {
|
|
162
|
+
if (!Array.isArray(raw))
|
|
163
|
+
return [];
|
|
164
|
+
const out = [];
|
|
165
|
+
for (const c of raw) {
|
|
166
|
+
const oid = c?.oid;
|
|
167
|
+
if (typeof oid === 'string' && oid !== '')
|
|
168
|
+
out.push(oid);
|
|
169
|
+
}
|
|
170
|
+
return out;
|
|
171
|
+
}
|
|
74
172
|
/**
|
|
75
173
|
* The component's change as it landed: first-parent name-status of its merge
|
|
76
174
|
* (or squash) commit, keeping only the changes the landing merge commit still
|
|
@@ -91,6 +189,18 @@ export const defaultViewComponentPr = async (prNumber, root) => {
|
|
|
91
189
|
* @task T12672
|
|
92
190
|
*/
|
|
93
191
|
export function componentLandedChanges(root, componentMerge, landingMerge) {
|
|
192
|
+
try {
|
|
193
|
+
return landedChangesOfMerge(root, componentMerge, landingMerge);
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
// A timed-out read credits nothing (fails closed).
|
|
197
|
+
if (err instanceof GitTimeoutError)
|
|
198
|
+
return { files: [], deleted: [] };
|
|
199
|
+
throw err;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/** {@link componentLandedChanges}, letting a git timeout propagate. */
|
|
203
|
+
function landedChangesOfMerge(root, componentMerge, landingMerge) {
|
|
94
204
|
const out = git(root, [
|
|
95
205
|
'diff-tree',
|
|
96
206
|
'--root',
|
|
@@ -102,28 +212,510 @@ export function componentLandedChanges(root, componentMerge, landingMerge) {
|
|
|
102
212
|
'--first-parent',
|
|
103
213
|
componentMerge,
|
|
104
214
|
]) ?? '';
|
|
215
|
+
return survivingChanges(root, out, `${componentMerge}^1`, componentMerge, landingMerge);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Keep the changes of a `from`..`tip` name-status listing that the landing
|
|
219
|
+
* commit still carries: a changed path whose landing blob equals `tip`'s, or
|
|
220
|
+
* whose `from`..`tip` hunks reverse-apply there and do not re-apply (T12689);
|
|
221
|
+
* a deletion whose path the landing commit lacks.
|
|
222
|
+
*/
|
|
223
|
+
function survivingChanges(root, nameStatus, from, tip, landingMerge) {
|
|
105
224
|
const files = [];
|
|
106
225
|
const deleted = [];
|
|
107
226
|
const blob = (commit, path) => git(root, ['rev-parse', '--verify', '--quiet', `${commit}:${path}`]);
|
|
227
|
+
const stillApplies = hunkChecker(root, from, tip, landingMerge);
|
|
228
|
+
try {
|
|
229
|
+
for (const line of nameStatus.split('\n')) {
|
|
230
|
+
const [status, ...rest] = line.split('\t');
|
|
231
|
+
const path = rest.join('\t');
|
|
232
|
+
if (!status || !path)
|
|
233
|
+
continue;
|
|
234
|
+
if (status.startsWith('D')) {
|
|
235
|
+
if (blob(landingMerge, path) === null)
|
|
236
|
+
deleted.push(path);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const own = blob(tip, path);
|
|
240
|
+
const landed = blob(landingMerge, path);
|
|
241
|
+
// Identical bytes, or (T12689) a file a later change also edited whose
|
|
242
|
+
// own hunks the landing version still carries.
|
|
243
|
+
if (own !== null && landed !== null && (own === landed || stillApplies(path)))
|
|
244
|
+
files.push(path);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
finally {
|
|
248
|
+
stillApplies.dispose();
|
|
249
|
+
}
|
|
250
|
+
return { files: [...new Set(files)], deleted: [...new Set(deleted)] };
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Whether the component's hunks for one path are still present in the
|
|
254
|
+
* landing commit: its first-parent patch reverse-applies cleanly to the
|
|
255
|
+
* landing tree (checked in a throwaway index, never the working tree). A
|
|
256
|
+
* revert fails this; a later edit elsewhere in the file does not (T12689).
|
|
257
|
+
*/
|
|
258
|
+
function hunkChecker(root, from, tip, landingMerge) {
|
|
259
|
+
let dir = null;
|
|
260
|
+
let env = null;
|
|
261
|
+
let failed = false;
|
|
262
|
+
const ready = () => {
|
|
263
|
+
if (env || failed)
|
|
264
|
+
return env;
|
|
265
|
+
dir = mkdtempSync(join(tmpdir(), 'cleo-component-index-'));
|
|
266
|
+
const candidate = { ...process.env, GIT_INDEX_FILE: join(dir, 'index') };
|
|
267
|
+
try {
|
|
268
|
+
runGit(root, ['read-tree', landingMerge], { env: candidate });
|
|
269
|
+
env = candidate;
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
// No index, no credit — and no retry leaving another temp dir behind.
|
|
273
|
+
failed = true;
|
|
274
|
+
rmSync(dir, { recursive: true, force: true });
|
|
275
|
+
dir = null;
|
|
276
|
+
if (err instanceof GitTimeoutError)
|
|
277
|
+
throw err;
|
|
278
|
+
}
|
|
279
|
+
return env;
|
|
280
|
+
};
|
|
281
|
+
const applies = (patch, indexEnv, reverse) => {
|
|
282
|
+
try {
|
|
283
|
+
runGit(root, ['apply', '--cached', '--check', ...(reverse ? ['-R'] : [])], {
|
|
284
|
+
env: indexEnv,
|
|
285
|
+
input: `${patch}\n`,
|
|
286
|
+
});
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
if (err instanceof GitTimeoutError)
|
|
291
|
+
throw err;
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
const check = (path) => {
|
|
296
|
+
const patch = git(root, [
|
|
297
|
+
'diff',
|
|
298
|
+
'--binary',
|
|
299
|
+
'--no-renames',
|
|
300
|
+
'--no-color',
|
|
301
|
+
from,
|
|
302
|
+
tip,
|
|
303
|
+
'--',
|
|
304
|
+
path,
|
|
305
|
+
]);
|
|
306
|
+
const indexEnv = patch ? ready() : null;
|
|
307
|
+
if (!patch || !indexEnv)
|
|
308
|
+
return false;
|
|
309
|
+
// `git apply` finds a hunk at ANY offset (T12689 review MED): the reverse
|
|
310
|
+
// patch can match an identical block elsewhere while the component's own
|
|
311
|
+
// lines were reverted. So the change must also NOT be re-applicable — a
|
|
312
|
+
// reverted change is, at its original spot. When both could match the
|
|
313
|
+
// file is not credited (fails closed).
|
|
314
|
+
return applies(patch, indexEnv, true) && !applies(patch, indexEnv, false);
|
|
315
|
+
};
|
|
316
|
+
return Object.assign(check, {
|
|
317
|
+
dispose: () => {
|
|
318
|
+
if (dir)
|
|
319
|
+
rmSync(dir, { recursive: true, force: true });
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
function refuse(codeName, reason) {
|
|
324
|
+
return { ok: false, codeName, reason };
|
|
325
|
+
}
|
|
326
|
+
function isAncestor(root, ancestor, descendant) {
|
|
327
|
+
return git(root, ['merge-base', '--is-ancestor', ancestor, descendant]) !== null;
|
|
328
|
+
}
|
|
329
|
+
/** Parent count of a commit (0 for a root commit); -1 when unreadable. */
|
|
330
|
+
function parentCount(root, sha) {
|
|
331
|
+
const line = git(root, ['rev-list', '--parents', '-n', '1', sha]);
|
|
332
|
+
return line === null ? -1 : line.split(' ').length - 1;
|
|
333
|
+
}
|
|
334
|
+
/** The PR's commits (oldest first), else its head; empty when neither is known. */
|
|
335
|
+
function componentCommits(c) {
|
|
336
|
+
if (c.commits && c.commits.length > 0)
|
|
337
|
+
return c.commits;
|
|
338
|
+
return c.headRefOid ? [c.headRefOid] : [];
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* `git patch-id --stable` of every non-merge commit `git log -p <args>`
|
|
342
|
+
* prints, keyed by patch id. A patch id survives a rebase that does not
|
|
343
|
+
* change the diff, which is how a rebased batch is mapped back (T12710).
|
|
344
|
+
*/
|
|
345
|
+
function patchIds(root, logArgs) {
|
|
346
|
+
const ids = new Map();
|
|
347
|
+
let patch = '';
|
|
348
|
+
let out = '';
|
|
349
|
+
try {
|
|
350
|
+
// Capped (T12710 review): a candidate whose merge introduces a patch
|
|
351
|
+
// larger than the ceiling throws GitOutputTooLargeError and is skipped.
|
|
352
|
+
patch = runGit(root, ['log', '-p', '--no-color', '--no-merges', ...logArgs], {
|
|
353
|
+
maxBuffer: envInt('CLEO_COMPONENT_PATCH_MAX_BYTES', CANDIDATE_PATCH_MAX_BYTES),
|
|
354
|
+
});
|
|
355
|
+
if (!patch.trim())
|
|
356
|
+
return ids;
|
|
357
|
+
out = runGit(root, ['patch-id', '--stable'], { input: patch });
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
if (err instanceof GitTimeoutError || err instanceof GitOutputTooLargeError)
|
|
361
|
+
throw err;
|
|
362
|
+
return ids;
|
|
363
|
+
}
|
|
108
364
|
for (const line of out.split('\n')) {
|
|
109
|
-
const [
|
|
110
|
-
|
|
111
|
-
|
|
365
|
+
const [id, commit] = line.trim().split(/\s+/);
|
|
366
|
+
if (id && commit && !ids.has(id))
|
|
367
|
+
ids.set(id, commit);
|
|
368
|
+
}
|
|
369
|
+
return ids;
|
|
370
|
+
}
|
|
371
|
+
/** Paths a commit changed against its first parent. */
|
|
372
|
+
function commitPaths(root, sha) {
|
|
373
|
+
const out = git(root, [
|
|
374
|
+
'diff-tree',
|
|
375
|
+
'--root',
|
|
376
|
+
'--no-commit-id',
|
|
377
|
+
'-r',
|
|
378
|
+
'--name-only',
|
|
379
|
+
'--no-renames',
|
|
380
|
+
'-m',
|
|
381
|
+
'--first-parent',
|
|
382
|
+
sha,
|
|
383
|
+
]);
|
|
384
|
+
return out ? out.split('\n').filter(Boolean) : [];
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Verify, commit by commit, that a landing merge carries a component PR's
|
|
388
|
+
* change, whatever happened to the PR itself (T12710): closed by hand, marked
|
|
389
|
+
* merged by GitHub, stacked on another component, main merged into its head
|
|
390
|
+
* afterwards, or rebased into the batch.
|
|
391
|
+
*
|
|
392
|
+
* - Every non-merge commit of the PR is an ancestor of the landing merge, or
|
|
393
|
+
* — when the batch was rebased — has the same `git patch-id` as a commit
|
|
394
|
+
* the landing merge introduced (`<merge>^1..<merge>`). Git is the proof;
|
|
395
|
+
* no PR body is consulted.
|
|
396
|
+
* - At least one of them is new in the landing merge (not already on its
|
|
397
|
+
* first parent), so the landing PR is the one that landed it.
|
|
398
|
+
* - The credited files are only the paths the PR's own commits changed, and
|
|
399
|
+
* only where the landing merge still carries the change (blob identical,
|
|
400
|
+
* or the component's hunks reverse-apply and do not re-apply — T12689).
|
|
401
|
+
*
|
|
402
|
+
* @param root - Git checkout holding every commit.
|
|
403
|
+
* @param c - The component PR, with its commit list.
|
|
404
|
+
* @param landing - The integration PR number and its merge commit.
|
|
405
|
+
* @returns The component's tip and surviving changes, or the refusal.
|
|
406
|
+
* @task T12710
|
|
407
|
+
*/
|
|
408
|
+
export function componentCommitsLanded(root, c, landing) {
|
|
409
|
+
try {
|
|
410
|
+
return proveCommitsLanded(root, c, landing);
|
|
411
|
+
}
|
|
412
|
+
catch (err) {
|
|
413
|
+
if (err instanceof GitOutputTooLargeError) {
|
|
414
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `PR #${landing.prNumber} skipped: the patch its merge introduces exceeds ${envInt('CLEO_COMPONENT_PATCH_MAX_BYTES', CANDIDATE_PATCH_MAX_BYTES)} bytes (CLEO_COMPONENT_PATCH_MAX_BYTES), too large to map by patch-id.`);
|
|
415
|
+
}
|
|
416
|
+
return timeoutRefusal(err);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
/** {@link componentCommitsLanded}, letting timeouts and oversize patches propagate. */
|
|
420
|
+
function proveCommitsLanded(root, c, landing) {
|
|
421
|
+
const n = c.number;
|
|
422
|
+
const i = landing.prNumber;
|
|
423
|
+
const m = landing.mergeCommitSha;
|
|
424
|
+
const commits = componentCommits(c);
|
|
425
|
+
if (commits.length === 0) {
|
|
426
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `gh reports no commits for component PR #${n}.`);
|
|
427
|
+
}
|
|
428
|
+
const missing = commits.find((sha) => !hasCommit(root, sha));
|
|
429
|
+
if (missing || !hasCommit(root, m)) {
|
|
430
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `${missing ? `Component PR #${n}'s commit ${missing.slice(0, 12)}` : `PR #${i}'s merge commit ${m.slice(0, 12)}`} is not available locally in ${root} (git fetch origin pull/${n}/head).`);
|
|
431
|
+
}
|
|
432
|
+
const firstParent = git(root, ['rev-parse', '--verify', '--quiet', `${m}^1`]);
|
|
433
|
+
if (!firstParent) {
|
|
434
|
+
return refuse('E_EVIDENCE_CONTENT_MISMATCH', `PR #${i}'s merge commit has no parent.`);
|
|
435
|
+
}
|
|
436
|
+
const own = commits.filter((sha) => {
|
|
437
|
+
const parents = parentCount(root, sha);
|
|
438
|
+
return parents === 0 || parents === 1;
|
|
439
|
+
});
|
|
440
|
+
if (own.length === 0) {
|
|
441
|
+
return refuse('E_EVIDENCE_CONTENT_MISMATCH', `Component PR #${n} has no commits of its own, only merges.`);
|
|
442
|
+
}
|
|
443
|
+
let introduced = null;
|
|
444
|
+
let landedNow = false;
|
|
445
|
+
for (const sha of own) {
|
|
446
|
+
if (isAncestor(root, sha, m)) {
|
|
447
|
+
if (!isAncestor(root, sha, firstParent))
|
|
448
|
+
landedNow = true;
|
|
112
449
|
continue;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
450
|
+
}
|
|
451
|
+
introduced ??= patchIds(root, [`${firstParent}..${m}`]);
|
|
452
|
+
const [id] = patchIds(root, ['--no-walk', sha]).keys();
|
|
453
|
+
if (id !== undefined && introduced.has(id)) {
|
|
454
|
+
landedNow = true;
|
|
116
455
|
continue;
|
|
117
456
|
}
|
|
118
|
-
|
|
119
|
-
if (own !== null && own === blob(landingMerge, path))
|
|
120
|
-
files.push(path);
|
|
457
|
+
return refuse('E_EVIDENCE_CONTENT_MISMATCH', `Commit ${sha.slice(0, 12)} of component PR #${n} is not in PR #${i}'s merge ${m.slice(0, 12)}, by ancestry or by patch-id.`);
|
|
121
458
|
}
|
|
122
|
-
|
|
459
|
+
if (!landedNow) {
|
|
460
|
+
return refuse('E_EVIDENCE_CONTENT_MISMATCH', `Component PR #${n}'s commits were already on the default branch before PR #${i}; PR #${i} did not land them.`);
|
|
461
|
+
}
|
|
462
|
+
const tip = [...commits].reverse().find((sha) => isAncestor(root, sha, m)) ?? own.at(-1);
|
|
463
|
+
const from = tip ? git(root, ['merge-base', tip, firstParent]) : null;
|
|
464
|
+
if (!tip || !from) {
|
|
465
|
+
return refuse('E_EVIDENCE_CONTENT_MISMATCH', `Component PR #${n} shares no history with PR #${i}'s base.`);
|
|
466
|
+
}
|
|
467
|
+
// Only the paths the PR's own commits changed: a stacked component's diff
|
|
468
|
+
// from the fork point also holds the component below it.
|
|
469
|
+
const paths = [...new Set(own.flatMap((sha) => commitPaths(root, sha)))];
|
|
470
|
+
const nameStatus = paths.length === 0
|
|
471
|
+
? ''
|
|
472
|
+
: (git(root, ['diff', '--name-status', '--no-renames', from, tip, '--', ...paths]) ?? '');
|
|
473
|
+
return { ok: true, tip, ...survivingChanges(root, nameStatus, from, tip, m) };
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* The first commit on `ref`'s first-parent chain that contains `sha`: the
|
|
477
|
+
* commit that landed it on the default branch. `sha` itself when it is on
|
|
478
|
+
* that chain; null when `ref` does not contain it.
|
|
479
|
+
*
|
|
480
|
+
* @param root - Git checkout.
|
|
481
|
+
* @param sha - A commit.
|
|
482
|
+
* @param ref - The default branch ref, e.g. `origin/main`.
|
|
483
|
+
* @returns The landing commit, or null.
|
|
484
|
+
* @task T12710
|
|
485
|
+
*/
|
|
486
|
+
export function landingCommitOn(root, sha, ref) {
|
|
487
|
+
try {
|
|
488
|
+
return landingCommit(root, sha, ref);
|
|
489
|
+
}
|
|
490
|
+
catch (err) {
|
|
491
|
+
if (err instanceof GitTimeoutError)
|
|
492
|
+
return null;
|
|
493
|
+
throw err;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/** {@link landingCommitOn}, letting a git timeout propagate. */
|
|
497
|
+
function landingCommit(root, sha, ref) {
|
|
498
|
+
if (!isAncestor(root, sha, ref))
|
|
499
|
+
return null;
|
|
500
|
+
const chain = git(root, ['rev-list', '--first-parent', `${sha}..${ref}`]);
|
|
501
|
+
if (!chain)
|
|
502
|
+
return sha;
|
|
503
|
+
const descendants = new Set((git(root, ['rev-list', '--ancestry-path', `${sha}..${ref}`]) ?? '').split('\n'));
|
|
504
|
+
const oldest = chain
|
|
505
|
+
.split('\n')
|
|
506
|
+
.reverse()
|
|
507
|
+
.find((c) => descendants.has(c));
|
|
508
|
+
if (!oldest)
|
|
509
|
+
return null;
|
|
510
|
+
return git(root, ['rev-parse', `${oldest}^1`]) === sha ? sha : oldest;
|
|
511
|
+
}
|
|
512
|
+
const LANDING_FIELDS = 'number,headRefName,baseRefName,state,headRefOid,mergeCommit,body';
|
|
513
|
+
/** `gh pr list --state merged --search <q>`, bounded by the evidence gh deadline. */
|
|
514
|
+
function searchMergedPrs(search, root) {
|
|
515
|
+
let parsed;
|
|
516
|
+
try {
|
|
517
|
+
parsed = JSON.parse(execFileSync('gh', [
|
|
518
|
+
'pr',
|
|
519
|
+
'list',
|
|
520
|
+
'--state',
|
|
521
|
+
'merged',
|
|
522
|
+
'--search',
|
|
523
|
+
search,
|
|
524
|
+
'--json',
|
|
525
|
+
LANDING_FIELDS,
|
|
526
|
+
'--limit',
|
|
527
|
+
'20',
|
|
528
|
+
], {
|
|
529
|
+
cwd: root,
|
|
530
|
+
encoding: 'utf-8',
|
|
531
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
532
|
+
timeout: ghQueryTimeoutMs(),
|
|
533
|
+
}));
|
|
534
|
+
}
|
|
535
|
+
catch (err) {
|
|
536
|
+
const what = `gh pr list --search '${search}'`;
|
|
537
|
+
return {
|
|
538
|
+
ok: false,
|
|
539
|
+
reason: isGhTimeout(err)
|
|
540
|
+
? ghTimeoutReason(what)
|
|
541
|
+
: `${what} failed (offline, or gh not authenticated): ${err instanceof Error ? err.message.slice(0, 200) : String(err)}`,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
if (!Array.isArray(parsed))
|
|
545
|
+
return { ok: true, prs: [] };
|
|
546
|
+
const str = (v) => (typeof v === 'string' ? v : '');
|
|
547
|
+
const prs = [];
|
|
548
|
+
for (const raw of parsed) {
|
|
549
|
+
if (raw === null || typeof raw !== 'object')
|
|
550
|
+
continue;
|
|
551
|
+
const row = raw;
|
|
552
|
+
if (typeof row.number !== 'number')
|
|
553
|
+
continue;
|
|
554
|
+
const merge = row.mergeCommit;
|
|
555
|
+
prs.push({
|
|
556
|
+
number: row.number,
|
|
557
|
+
headRefName: str(row.headRefName),
|
|
558
|
+
baseRefName: str(row.baseRefName),
|
|
559
|
+
state: str(row.state),
|
|
560
|
+
headRefOid: typeof row.headRefOid === 'string' ? row.headRefOid : null,
|
|
561
|
+
mergeCommitSha: typeof merge?.oid === 'string' ? merge.oid : null,
|
|
562
|
+
body: str(row.body),
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
return { ok: true, prs };
|
|
566
|
+
}
|
|
567
|
+
/** Default {@link ComponentLandingDeps}: bounded `gh pr list` searches. */
|
|
568
|
+
export const defaultComponentLandingDeps = {
|
|
569
|
+
prsByMergeCommit: async (sha, root) => searchMergedPrs(sha, root),
|
|
570
|
+
prsListingComponent: async (n, root) => searchMergedPrs(`${n} in:body`, root),
|
|
571
|
+
};
|
|
572
|
+
/** Whether a PR body lists `#<n>` (never `#<n>0`). */
|
|
573
|
+
function listsPr(body, n) {
|
|
574
|
+
return new RegExp(`#${n}(?![0-9])`).test(body);
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Follow a component PR to the PR that landed it on the default branch
|
|
578
|
+
* (T12671, T12710). Resolution, git first:
|
|
579
|
+
*
|
|
580
|
+
* 1. Ancestry: the newest PR commit the default branch contains is landed by
|
|
581
|
+
* the first commit on the default branch's first-parent chain containing
|
|
582
|
+
* it; the merged PR whose merge commit that is, is the landing PR. When
|
|
583
|
+
* that commit is the component's own merge, it landed directly: `null`.
|
|
584
|
+
* 2. Rebased batch (no PR commit is on the default branch): merged PRs into
|
|
585
|
+
* the default branch whose body lists `#<component>` are candidates — a
|
|
586
|
+
* hint only — and each is accepted only through patch-id proof.
|
|
587
|
+
*
|
|
588
|
+
* Either way {@link componentCommitsLanded} is the proof: every commit of the
|
|
589
|
+
* component is in the landing merge, and only its surviving files are
|
|
590
|
+
* credited. A `gh` failure (offline, timeout) is a refusal, never a hang.
|
|
591
|
+
*
|
|
592
|
+
* @param root - Git checkout with the default branch fetched.
|
|
593
|
+
* @param c - The component PR (with its commits).
|
|
594
|
+
* @param defaultRef - The default branch ref, e.g. `origin/main`.
|
|
595
|
+
* @param deps - `gh` lookups (tests inject).
|
|
596
|
+
* @returns The landing PR and surviving changes, a refusal, or `null` when the
|
|
597
|
+
* PR landed directly (its own merge is on the default branch).
|
|
598
|
+
* @task T12710
|
|
599
|
+
*/
|
|
600
|
+
export async function findComponentLanding(root, c, defaultRef, deps = {}) {
|
|
601
|
+
try {
|
|
602
|
+
return await locateLanding(root, c, defaultRef, deps);
|
|
603
|
+
}
|
|
604
|
+
catch (err) {
|
|
605
|
+
return timeoutRefusal(err);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
/** {@link findComponentLanding}, letting a git timeout propagate. */
|
|
609
|
+
async function locateLanding(root, c, defaultRef, deps) {
|
|
610
|
+
const n = c.number;
|
|
611
|
+
if (c.state === 'OPEN') {
|
|
612
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `Component PR #${n} is open.`);
|
|
613
|
+
}
|
|
614
|
+
const commits = componentCommits(c);
|
|
615
|
+
if (commits.length === 0) {
|
|
616
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `gh reports no commits for PR #${n}.`);
|
|
617
|
+
}
|
|
618
|
+
const missing = commits.find((sha) => !hasCommit(root, sha));
|
|
619
|
+
if (missing) {
|
|
620
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `PR #${n}'s commit ${missing.slice(0, 12)} is not available locally in ${root} (git fetch origin pull/${n}/head).`);
|
|
621
|
+
}
|
|
622
|
+
const defaultBranch = defaultRef.replace(/^origin\//, '');
|
|
623
|
+
const lookups = { ...defaultComponentLandingDeps, ...deps };
|
|
624
|
+
const onDefault = [...commits].reverse().find((sha) => isAncestor(root, sha, defaultRef));
|
|
625
|
+
let candidates;
|
|
626
|
+
if (onDefault) {
|
|
627
|
+
const m = landingCommit(root, onDefault, defaultRef);
|
|
628
|
+
if (m === null || m === c.mergeCommitSha)
|
|
629
|
+
return null;
|
|
630
|
+
const found = await lookups.prsByMergeCommit(m, root);
|
|
631
|
+
if (!found.ok)
|
|
632
|
+
return refuse('E_EVIDENCE_TOOL_FAILED', found.reason);
|
|
633
|
+
const merged = found.prs.filter((p) => p.state === 'MERGED' && p.mergeCommitSha === m && p.baseRefName === defaultBranch);
|
|
634
|
+
if (merged.some((p) => p.number === n))
|
|
635
|
+
return null;
|
|
636
|
+
candidates = merged;
|
|
637
|
+
if (candidates.length === 0) {
|
|
638
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `No merged PR into ${defaultBranch} has ${m.slice(0, 12)}, the commit that landed PR #${n}'s commits, as its merge commit.`);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
const found = await lookups.prsListingComponent(n, root);
|
|
643
|
+
if (!found.ok)
|
|
644
|
+
return refuse('E_EVIDENCE_TOOL_FAILED', found.reason);
|
|
645
|
+
candidates = found.prs
|
|
646
|
+
.filter((p) => p.number !== n &&
|
|
647
|
+
p.state === 'MERGED' &&
|
|
648
|
+
p.baseRefName === defaultBranch &&
|
|
649
|
+
listsPr(p.body, n) &&
|
|
650
|
+
hasCommit(root, p.mergeCommitSha) &&
|
|
651
|
+
isAncestor(root, p.mergeCommitSha, defaultRef))
|
|
652
|
+
.sort((a, b) => b.number - a.number);
|
|
653
|
+
if (candidates.length === 0) {
|
|
654
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `PR #${n}'s commits are not on ${defaultBranch}, and no merged PR into ${defaultBranch} lists #${n}.`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
const reasons = [];
|
|
658
|
+
const budgetMs = envInt('CLEO_COMPONENT_SEARCH_BUDGET_MS', CANDIDATE_BUDGET_MS);
|
|
659
|
+
const deadline = Date.now() + budgetMs;
|
|
660
|
+
let skipped = 0;
|
|
661
|
+
for (const candidate of candidates) {
|
|
662
|
+
if (Date.now() > deadline) {
|
|
663
|
+
// T12710 review: bounded total work over body-hint candidates.
|
|
664
|
+
skipped++;
|
|
665
|
+
reasons.push(`PR #${candidate.number} skipped: the ${budgetMs}ms candidate budget (CLEO_COMPONENT_SEARCH_BUDGET_MS) is spent.`);
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
const mergeCommitSha = candidate.mergeCommitSha;
|
|
669
|
+
const r = componentCommitsLanded(root, c, { prNumber: candidate.number, mergeCommitSha });
|
|
670
|
+
if (!r.ok && r.codeName === 'E_EVIDENCE_TOOL_FAILED')
|
|
671
|
+
return r;
|
|
672
|
+
if (!r.ok && r.reason.includes(' skipped: '))
|
|
673
|
+
skipped++;
|
|
674
|
+
if (r.ok && (r.files.length > 0 || r.deleted.length > 0)) {
|
|
675
|
+
return {
|
|
676
|
+
ok: true,
|
|
677
|
+
landing: { ...candidate, mergeCommitSha },
|
|
678
|
+
files: r.files,
|
|
679
|
+
deleted: r.deleted,
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
reasons.push(r.ok
|
|
683
|
+
? `None of component PR #${n}'s changes survive in PR #${candidate.number}'s merge commit.`
|
|
684
|
+
: r.reason);
|
|
685
|
+
}
|
|
686
|
+
return refuse(skipped === candidates.length ? 'E_EVIDENCE_INSUFFICIENT' : 'E_EVIDENCE_CONTENT_MISMATCH', reasons.join(' '));
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* The original T12671 proof: the component PR merged into the integration
|
|
690
|
+
* PR's head branch, and that head contains its merge commit. Null when it
|
|
691
|
+
* holds; the refusal otherwise.
|
|
692
|
+
*/
|
|
693
|
+
function mergedIntoIntegration(c, landing, root) {
|
|
694
|
+
const n = c.number;
|
|
695
|
+
if (c.state !== 'MERGED') {
|
|
696
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `Component PR #${n} is ${c.state.toLowerCase() || 'not merged'}.`);
|
|
697
|
+
}
|
|
698
|
+
if (c.baseRefName !== landing.headRefName) {
|
|
699
|
+
return refuse('E_EVIDENCE_CONTENT_MISMATCH', `Component PR #${n} merged into ${c.baseRefName || 'an unknown branch'}, not ${landing.headRefName}, the head of PR #${landing.prNumber}.`);
|
|
700
|
+
}
|
|
701
|
+
if (!hasCommit(root, c.mergeCommitSha) || !hasCommit(root, landing.headRefOid)) {
|
|
702
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `PR #${n}'s merge commit or PR #${landing.prNumber}'s head is not available locally in ${root} (git fetch origin).`);
|
|
703
|
+
}
|
|
704
|
+
if (!isAncestor(root, c.mergeCommitSha, landing.headRefOid)) {
|
|
705
|
+
return refuse('E_EVIDENCE_CONTENT_MISMATCH', `PR #${landing.prNumber}'s head does not contain component PR #${n}'s merge ${c.mergeCommitSha.slice(0, 12)}.`);
|
|
706
|
+
}
|
|
707
|
+
return null;
|
|
123
708
|
}
|
|
124
709
|
/**
|
|
125
710
|
* Verify that `componentPrNumber` is a component the integration PR landed,
|
|
126
|
-
* and derive its landed files.
|
|
711
|
+
* and derive its landed files. Two proofs, first match wins:
|
|
712
|
+
*
|
|
713
|
+
* - the component PR merged into the integration PR's head branch, whose
|
|
714
|
+
* head contains its merge commit (T12671);
|
|
715
|
+
* - otherwise every commit of its own is in the integration merge, by
|
|
716
|
+
* ancestry or patch-id ({@link componentCommitsLanded}, T12710) — a
|
|
717
|
+
* component closed by hand, marked merged by GitHub, stacked, main-merged
|
|
718
|
+
* afterwards, or rebased into the batch.
|
|
127
719
|
*
|
|
128
720
|
* @param componentPrNumber - The task's own (component) PR.
|
|
129
721
|
* @param landing - The integration PR that reached the default branch.
|
|
@@ -131,51 +723,45 @@ export function componentLandedChanges(root, componentMerge, landingMerge) {
|
|
|
131
723
|
* @param view - PR reader (tests inject).
|
|
132
724
|
* @returns The component's linkage fields and files, or the refusal.
|
|
133
725
|
* @task T12671
|
|
726
|
+
* @task T12710
|
|
134
727
|
*/
|
|
135
728
|
export async function resolveComponentPr(componentPrNumber, landing, root, view = defaultViewComponentPr) {
|
|
136
729
|
const c = await view(componentPrNumber, root);
|
|
137
730
|
if (!c) {
|
|
138
|
-
return {
|
|
139
|
-
ok: false,
|
|
140
|
-
codeName: 'E_EVIDENCE_TOOL_FAILED',
|
|
141
|
-
reason: `gh pr view ${componentPrNumber} failed; component PR #${componentPrNumber} cannot be verified.`,
|
|
142
|
-
};
|
|
731
|
+
return refuse('E_EVIDENCE_TOOL_FAILED', `gh pr view ${componentPrNumber} failed; component PR #${componentPrNumber} cannot be verified.`);
|
|
143
732
|
}
|
|
144
|
-
if (c.state
|
|
145
|
-
return {
|
|
146
|
-
ok: false,
|
|
147
|
-
codeName: 'E_EVIDENCE_INSUFFICIENT',
|
|
148
|
-
reason: `Component PR #${componentPrNumber} is ${c.state.toLowerCase() || 'not merged'}.`,
|
|
149
|
-
};
|
|
733
|
+
if (c.state === 'OPEN') {
|
|
734
|
+
return refuse('E_EVIDENCE_INSUFFICIENT', `Component PR #${componentPrNumber} is open.`);
|
|
150
735
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
736
|
+
let changes;
|
|
737
|
+
try {
|
|
738
|
+
// The change set's follow proves with componentCommitsLanded, so the
|
|
739
|
+
// validator tries the SAME prover first (T12710 review): the two can
|
|
740
|
+
// only disagree when commit data is missing, or for a squash-landed
|
|
741
|
+
// integration PR, where the merge-into-integration proof remains.
|
|
742
|
+
const viaCommits = componentCommits(c).length > 0 ? componentCommitsLanded(root, c, landing) : null;
|
|
743
|
+
if (viaCommits?.ok) {
|
|
744
|
+
changes = viaCommits;
|
|
745
|
+
}
|
|
746
|
+
else if (viaCommits && viaCommits.codeName === 'E_EVIDENCE_TOOL_FAILED') {
|
|
747
|
+
return viaCommits;
|
|
748
|
+
}
|
|
749
|
+
else {
|
|
750
|
+
const viaMerge = mergedIntoIntegration(c, landing, root);
|
|
751
|
+
if (viaMerge !== null) {
|
|
752
|
+
return viaCommits
|
|
753
|
+
? refuse(viaCommits.codeName, `${viaMerge.reason} ${viaCommits.reason}`)
|
|
754
|
+
: viaMerge;
|
|
755
|
+
}
|
|
756
|
+
changes = landedChangesOfMerge(root, c.mergeCommitSha, landing.mergeCommitSha);
|
|
757
|
+
}
|
|
164
758
|
}
|
|
165
|
-
|
|
166
|
-
return
|
|
167
|
-
ok: false,
|
|
168
|
-
codeName: 'E_EVIDENCE_CONTENT_MISMATCH',
|
|
169
|
-
reason: `PR #${landing.prNumber}'s head does not contain component PR #${componentPrNumber}'s merge ${c.mergeCommitSha.slice(0, 12)}.`,
|
|
170
|
-
};
|
|
759
|
+
catch (err) {
|
|
760
|
+
return timeoutRefusal(err);
|
|
171
761
|
}
|
|
172
|
-
const { files, deleted } =
|
|
762
|
+
const { files, deleted } = changes;
|
|
173
763
|
if (files.length === 0 && deleted.length === 0) {
|
|
174
|
-
return {
|
|
175
|
-
ok: false,
|
|
176
|
-
codeName: 'E_EVIDENCE_CONTENT_MISMATCH',
|
|
177
|
-
reason: `None of component PR #${componentPrNumber}'s changes survive in PR #${landing.prNumber}'s merge commit.`,
|
|
178
|
-
};
|
|
764
|
+
return refuse('E_EVIDENCE_CONTENT_MISMATCH', `None of component PR #${componentPrNumber}'s changes survive in PR #${landing.prNumber}'s merge commit.`);
|
|
179
765
|
}
|
|
180
766
|
return {
|
|
181
767
|
ok: true,
|