@cleocode/core 2026.10.1 → 2026.10.2
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/build-provenance.json +2 -2
- package/dist/cloud/journal.d.ts +9 -5
- package/dist/cloud/journal.d.ts.map +1 -1
- package/dist/cloud/journal.js +29 -8
- package/dist/cloud/journal.js.map +1 -1
- package/dist/cloud/manifest-check.d.ts +140 -4
- package/dist/cloud/manifest-check.d.ts.map +1 -1
- package/dist/cloud/manifest-check.js +309 -10
- package/dist/cloud/manifest-check.js.map +1 -1
- package/dist/cloud/nexus-attach.d.ts +25 -0
- package/dist/cloud/nexus-attach.d.ts.map +1 -1
- package/dist/cloud/nexus-attach.js +81 -6
- package/dist/cloud/nexus-attach.js.map +1 -1
- package/dist/cloud/nexus-cloud-activity.d.ts +37 -0
- package/dist/cloud/nexus-cloud-activity.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud-activity.js +79 -0
- package/dist/cloud/nexus-cloud-activity.js.map +1 -0
- package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
- package/dist/cloud/nexus-cloud-status.js +36 -0
- package/dist/cloud/nexus-cloud-status.js.map +1 -1
- package/dist/cloud/nexus-device.d.ts +1 -1
- package/dist/cloud/nexus-enrol.d.ts.map +1 -1
- package/dist/cloud/nexus-enrol.js +5 -0
- package/dist/cloud/nexus-enrol.js.map +1 -1
- package/dist/cloud/nexus-home.d.ts +74 -0
- package/dist/cloud/nexus-home.d.ts.map +1 -0
- package/dist/cloud/nexus-home.js +97 -0
- package/dist/cloud/nexus-home.js.map +1 -0
- package/dist/cloud/nexus-vault-keys.d.ts +129 -0
- package/dist/cloud/nexus-vault-keys.d.ts.map +1 -0
- package/dist/cloud/nexus-vault-keys.js +277 -0
- package/dist/cloud/nexus-vault-keys.js.map +1 -0
- package/dist/cloud/nexus-vault-state.d.ts +121 -0
- package/dist/cloud/nexus-vault-state.d.ts.map +1 -0
- package/dist/cloud/nexus-vault-state.js +274 -0
- package/dist/cloud/nexus-vault-state.js.map +1 -0
- package/dist/cloud/nexus-vault.d.ts +160 -0
- package/dist/cloud/nexus-vault.d.ts.map +1 -0
- package/dist/cloud/nexus-vault.js +1733 -0
- package/dist/cloud/nexus-vault.js.map +1 -0
- package/dist/cloud/signing.d.ts +24 -8
- package/dist/cloud/signing.d.ts.map +1 -1
- package/dist/cloud/signing.js +61 -15
- package/dist/cloud/signing.js.map +1 -1
- package/dist/docs/export-document.js +8137 -3318
- package/dist/docs/export-document.js.map +3 -3
- package/dist/doctor/migrations.d.ts +75 -0
- package/dist/doctor/migrations.d.ts.map +1 -0
- package/dist/doctor/migrations.js +136 -0
- package/dist/doctor/migrations.js.map +1 -0
- package/dist/doctor/sync-sealer.d.ts +48 -0
- package/dist/doctor/sync-sealer.d.ts.map +1 -0
- package/dist/doctor/sync-sealer.js +109 -0
- package/dist/doctor/sync-sealer.js.map +1 -0
- package/dist/doctor/sync-triggers.d.ts +53 -0
- package/dist/doctor/sync-triggers.d.ts.map +1 -0
- package/dist/doctor/sync-triggers.js +157 -0
- package/dist/doctor/sync-triggers.js.map +1 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +5 -1
- package/dist/init.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/llm/plugin-facade.js +8442 -3623
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/nexus/projects-clean.d.ts +3 -0
- package/dist/nexus/projects-clean.d.ts.map +1 -1
- package/dist/nexus/projects-clean.js +9 -3
- package/dist/nexus/projects-clean.js.map +1 -1
- package/dist/nexus/registry-roots.d.ts +3 -1
- package/dist/nexus/registry-roots.d.ts.map +1 -1
- package/dist/nexus/registry-roots.js +5 -2
- package/dist/nexus/registry-roots.js.map +1 -1
- package/dist/nexus/registry.d.ts +8 -1
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +24 -10
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/workspace.d.ts +4 -1
- package/dist/nexus/workspace.d.ts.map +1 -1
- package/dist/nexus/workspace.js +10 -4
- package/dist/nexus/workspace.js.map +1 -1
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +7 -2
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestrate/worker-verify.d.ts +121 -12
- package/dist/orchestrate/worker-verify.d.ts.map +1 -1
- package/dist/orchestrate/worker-verify.js +172 -21
- package/dist/orchestrate/worker-verify.js.map +1 -1
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +15 -9
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/release/ci-evidence.d.ts +9 -0
- package/dist/release/ci-evidence.d.ts.map +1 -1
- package/dist/release/ci-evidence.js +9 -2
- package/dist/release/ci-evidence.js.map +1 -1
- package/dist/resources/backend.d.ts +15 -3
- package/dist/resources/backend.d.ts.map +1 -1
- package/dist/resources/backend.js +7 -3
- package/dist/resources/backend.js.map +1 -1
- package/dist/resources/darwin-backend.d.ts +142 -0
- package/dist/resources/darwin-backend.d.ts.map +1 -0
- package/dist/resources/darwin-backend.js +288 -0
- package/dist/resources/darwin-backend.js.map +1 -0
- package/dist/resources/governor.d.ts +44 -1
- package/dist/resources/governor.d.ts.map +1 -1
- package/dist/resources/governor.js +100 -36
- package/dist/resources/governor.js.map +1 -1
- package/dist/resources/heavy-command.d.ts +132 -0
- package/dist/resources/heavy-command.d.ts.map +1 -0
- package/dist/resources/heavy-command.js +768 -0
- package/dist/resources/heavy-command.js.map +1 -0
- package/dist/resources/monitor.d.ts +50 -1
- package/dist/resources/monitor.d.ts.map +1 -1
- package/dist/resources/monitor.js +83 -1
- package/dist/resources/monitor.js.map +1 -1
- package/dist/resources/run-admission.d.ts +303 -0
- package/dist/resources/run-admission.d.ts.map +1 -0
- package/dist/resources/run-admission.js +648 -0
- package/dist/resources/run-admission.js.map +1 -0
- package/dist/resources/run-class.d.ts +111 -0
- package/dist/resources/run-class.d.ts.map +1 -0
- package/dist/resources/run-class.js +658 -0
- package/dist/resources/run-class.js.map +1 -0
- package/dist/resources/run-governed.d.ts +158 -0
- package/dist/resources/run-governed.d.ts.map +1 -0
- package/dist/resources/run-governed.js +406 -0
- package/dist/resources/run-governed.js.map +1 -0
- package/dist/resources/slot-holder.d.ts +267 -0
- package/dist/resources/slot-holder.d.ts.map +1 -0
- package/dist/resources/slot-holder.js +505 -0
- package/dist/resources/slot-holder.js.map +1 -0
- package/dist/resources/tool-groups.d.ts +74 -0
- package/dist/resources/tool-groups.d.ts.map +1 -0
- package/dist/resources/tool-groups.js +118 -0
- package/dist/resources/tool-groups.js.map +1 -0
- package/dist/routing/build-command-groups.d.ts.map +1 -1
- package/dist/routing/build-command-groups.js +1 -0
- package/dist/routing/build-command-groups.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +8446 -3627
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sentient/cross-project-hygiene.d.ts +3 -2
- package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
- package/dist/sentient/cross-project-hygiene.js +5 -2
- package/dist/sentient/cross-project-hygiene.js.map +1 -1
- package/dist/sentient/state.d.ts +7 -0
- package/dist/sentient/state.d.ts.map +1 -1
- package/dist/sentient/state.js.map +1 -1
- package/dist/sentient/tick.d.ts +14 -2
- package/dist/sentient/tick.d.ts.map +1 -1
- package/dist/sentient/tick.js +63 -4
- package/dist/sentient/tick.js.map +1 -1
- package/dist/store/backup-recover.d.ts.map +1 -1
- package/dist/store/backup-recover.js +5 -0
- package/dist/store/backup-recover.js.map +1 -1
- package/dist/store/data-accessor.d.ts +1 -0
- package/dist/store/data-accessor.d.ts.map +1 -1
- package/dist/store/data-accessor.js +7 -0
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +23 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +126 -36
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/recovery.d.ts.map +1 -1
- package/dist/store/exodus/recovery.js +15 -0
- package/dist/store/exodus/recovery.js.map +1 -1
- package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
- package/dist/store/legacy-tasks-lineage.js +5 -0
- package/dist/store/legacy-tasks-lineage.js.map +1 -1
- package/dist/store/lock.d.ts +8 -1
- package/dist/store/lock.d.ts.map +1 -1
- package/dist/store/lock.js +10 -2
- package/dist/store/lock.js.map +1 -1
- package/dist/store/migration-manager.d.ts +5 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +11 -0
- package/dist/store/migration-manager.js.map +1 -1
- package/dist/store/migration-runner.d.ts +158 -0
- package/dist/store/migration-runner.d.ts.map +1 -0
- package/dist/store/migration-runner.js +493 -0
- package/dist/store/migration-runner.js.map +1 -0
- package/dist/store/portable-bundle-import.d.ts +15 -1
- package/dist/store/portable-bundle-import.d.ts.map +1 -1
- package/dist/store/portable-bundle-import.js +24 -4
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-relocate.d.ts +43 -0
- package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
- package/dist/store/portable-bundle-relocate.js +79 -5
- package/dist/store/portable-bundle-relocate.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts +20 -0
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +38 -3
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/portable-bundle.d.ts +33 -0
- package/dist/store/portable-bundle.d.ts.map +1 -1
- package/dist/store/portable-bundle.js +34 -7
- package/dist/store/portable-bundle.js.map +1 -1
- package/dist/store/row-identity-registry.d.ts +137 -7
- package/dist/store/row-identity-registry.d.ts.map +1 -1
- package/dist/store/row-identity-registry.js +364 -9
- package/dist/store/row-identity-registry.js.map +1 -1
- package/dist/store/row-identity.d.ts.map +1 -1
- package/dist/store/row-identity.js +9 -10
- package/dist/store/row-identity.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +10 -0
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.d.ts +31 -0
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +5 -1
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/sync/capture.d.ts +203 -0
- package/dist/store/sync/capture.d.ts.map +1 -0
- package/dist/store/sync/capture.js +562 -0
- package/dist/store/sync/capture.js.map +1 -0
- package/dist/store/sync/clock-store.d.ts.map +1 -1
- package/dist/store/sync/clock-store.js +2 -0
- package/dist/store/sync/clock-store.js.map +1 -1
- package/dist/store/sync/fk-orphans.d.ts +133 -0
- package/dist/store/sync/fk-orphans.d.ts.map +1 -0
- package/dist/store/sync/fk-orphans.js +265 -0
- package/dist/store/sync/fk-orphans.js.map +1 -0
- package/dist/store/sync/flags.d.ts +7 -0
- package/dist/store/sync/flags.d.ts.map +1 -1
- package/dist/store/sync/flags.js +16 -0
- package/dist/store/sync/flags.js.map +1 -1
- package/dist/store/sync/hlc.d.ts.map +1 -1
- package/dist/store/sync/hlc.js +4 -0
- package/dist/store/sync/hlc.js.map +1 -1
- package/dist/store/sync/identity-fill.d.ts +45 -0
- package/dist/store/sync/identity-fill.d.ts.map +1 -0
- package/dist/store/sync/identity-fill.js +85 -0
- package/dist/store/sync/identity-fill.js.map +1 -0
- package/dist/store/sync/machinery.d.ts +27 -0
- package/dist/store/sync/machinery.d.ts.map +1 -0
- package/dist/store/sync/machinery.js +44 -0
- package/dist/store/sync/machinery.js.map +1 -0
- package/dist/store/sync/netting.d.ts +120 -0
- package/dist/store/sync/netting.d.ts.map +1 -0
- package/dist/store/sync/netting.js +336 -0
- package/dist/store/sync/netting.js.map +1 -0
- package/dist/store/sync/replica.d.ts +27 -2
- package/dist/store/sync/replica.d.ts.map +1 -1
- package/dist/store/sync/replica.js +47 -3
- package/dist/store/sync/replica.js.map +1 -1
- package/dist/store/sync/schema.d.ts +12 -0
- package/dist/store/sync/schema.d.ts.map +1 -1
- package/dist/store/sync/schema.js +21 -0
- package/dist/store/sync/schema.js.map +1 -1
- package/dist/store/sync/seal-backlog.d.ts +21 -0
- package/dist/store/sync/seal-backlog.d.ts.map +1 -0
- package/dist/store/sync/seal-backlog.js +24 -0
- package/dist/store/sync/seal-backlog.js.map +1 -0
- package/dist/store/sync/sealer-values.d.ts +34 -0
- package/dist/store/sync/sealer-values.d.ts.map +1 -0
- package/dist/store/sync/sealer-values.js +53 -0
- package/dist/store/sync/sealer-values.js.map +1 -0
- package/dist/store/sync/sealer.d.ts +145 -0
- package/dist/store/sync/sealer.d.ts.map +1 -0
- package/dist/store/sync/sealer.js +906 -0
- package/dist/store/sync/sealer.js.map +1 -0
- package/dist/store/sync/structural.d.ts +63 -0
- package/dist/store/sync/structural.d.ts.map +1 -0
- package/dist/store/sync/structural.js +180 -0
- package/dist/store/sync/structural.js.map +1 -0
- package/dist/store/sync/timestamps.d.ts +92 -0
- package/dist/store/sync/timestamps.d.ts.map +1 -0
- package/dist/store/sync/timestamps.js +228 -0
- package/dist/store/sync/timestamps.js.map +1 -0
- package/dist/store/sync/tombstones.d.ts +75 -0
- package/dist/store/sync/tombstones.d.ts.map +1 -0
- package/dist/store/sync/tombstones.js +103 -0
- package/dist/store/sync/tombstones.js.map +1 -0
- package/dist/store/sync/trigger-classes.d.ts +221 -0
- package/dist/store/sync/trigger-classes.d.ts.map +1 -0
- package/dist/store/sync/trigger-classes.js +441 -0
- package/dist/store/sync/trigger-classes.js.map +1 -0
- package/dist/store/sync/trigger-suspend-at-path.d.ts +23 -0
- package/dist/store/sync/trigger-suspend-at-path.d.ts.map +1 -0
- package/dist/store/sync/trigger-suspend-at-path.js +44 -0
- package/dist/store/sync/trigger-suspend-at-path.js.map +1 -0
- package/dist/store/sync/writer-version.d.ts +43 -0
- package/dist/store/sync/writer-version.d.ts.map +1 -0
- package/dist/store/sync/writer-version.js +90 -0
- package/dist/store/sync/writer-version.js.map +1 -0
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +102 -0
- package/dist/store/table-classification.js.map +1 -1
- package/dist/store/trigger-suspend-schema.d.ts +44 -0
- package/dist/store/trigger-suspend-schema.d.ts.map +1 -0
- package/dist/store/trigger-suspend-schema.js +25 -0
- package/dist/store/trigger-suspend-schema.js.map +1 -0
- package/dist/store/vault-manifest.d.ts +365 -0
- package/dist/store/vault-manifest.d.ts.map +1 -0
- package/dist/store/vault-manifest.js +812 -0
- package/dist/store/vault-manifest.js.map +1 -0
- package/dist/store/writer-lease.d.ts +31 -0
- package/dist/store/writer-lease.d.ts.map +1 -1
- package/dist/store/writer-lease.js +65 -2
- package/dist/store/writer-lease.js.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +21 -0
- package/dist/system/health.js.map +1 -1
- package/dist/system/project-health.d.ts.map +1 -1
- package/dist/system/project-health.js +3 -1
- package/dist/system/project-health.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +58 -0
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +75 -6
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/affected-scope.d.ts +150 -23
- package/dist/tasks/affected-scope.d.ts.map +1 -1
- package/dist/tasks/affected-scope.js +320 -32
- package/dist/tasks/affected-scope.js.map +1 -1
- package/dist/tasks/change-set.d.ts +96 -0
- package/dist/tasks/change-set.d.ts.map +1 -1
- package/dist/tasks/change-set.js +169 -4
- package/dist/tasks/change-set.js.map +1 -1
- package/dist/tasks/complete-ci.d.ts +115 -0
- package/dist/tasks/complete-ci.d.ts.map +1 -0
- package/dist/tasks/complete-ci.js +171 -0
- package/dist/tasks/complete-ci.js.map +1 -0
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +50 -17
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/compute-task-view.d.ts.map +1 -1
- package/dist/tasks/compute-task-view.js +7 -0
- package/dist/tasks/compute-task-view.js.map +1 -1
- package/dist/tasks/done-plan.d.ts.map +1 -1
- package/dist/tasks/done-plan.js +51 -30
- package/dist/tasks/done-plan.js.map +1 -1
- package/dist/tasks/done-record.d.ts +6 -0
- package/dist/tasks/done-record.d.ts.map +1 -1
- package/dist/tasks/done-record.js +9 -3
- package/dist/tasks/done-record.js.map +1 -1
- package/dist/tasks/evidence.d.ts +3 -2
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +143 -12
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/gate-notes.d.ts +22 -0
- package/dist/tasks/gate-notes.d.ts.map +1 -0
- package/dist/tasks/gate-notes.js +33 -0
- package/dist/tasks/gate-notes.js.map +1 -0
- package/dist/tasks/index.d.ts +2 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +2 -1
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/test-run-binding.d.ts +117 -0
- package/dist/tasks/test-run-binding.d.ts.map +1 -0
- package/dist/tasks/test-run-binding.js +365 -0
- package/dist/tasks/test-run-binding.js.map +1 -0
- package/dist/tasks/tool-cache-env.d.ts +123 -0
- package/dist/tasks/tool-cache-env.d.ts.map +1 -0
- package/dist/tasks/tool-cache-env.js +287 -0
- package/dist/tasks/tool-cache-env.js.map +1 -0
- package/dist/tasks/tool-cache-failed-first.d.ts +155 -0
- package/dist/tasks/tool-cache-failed-first.d.ts.map +1 -0
- package/dist/tasks/tool-cache-failed-first.js +285 -0
- package/dist/tasks/tool-cache-failed-first.js.map +1 -0
- package/dist/tasks/tool-cache.d.ts +375 -55
- package/dist/tasks/tool-cache.d.ts.map +1 -1
- package/dist/tasks/tool-cache.js +912 -303
- package/dist/tasks/tool-cache.js.map +1 -1
- package/dist/tasks/tool-resolver.d.ts +4 -3
- package/dist/tasks/tool-resolver.d.ts.map +1 -1
- package/dist/tasks/tool-resolver.js +15 -4
- package/dist/tasks/tool-resolver.js.map +1 -1
- package/dist/tasks/tool-semaphore.d.ts +67 -7
- package/dist/tasks/tool-semaphore.d.ts.map +1 -1
- package/dist/tasks/tool-semaphore.js +134 -56
- package/dist/tasks/tool-semaphore.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +4 -0
- package/dist/upgrade.js.map +1 -1
- package/dist/validation/engine-ops.d.ts +6 -0
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +8 -0
- package/dist/validation/engine-ops.js.map +1 -1
- package/migrations/drizzle-cleo-project/20260930170000_t12819-trigger-suspend-clause/migration.sql +367 -0
- package/migrations/sync-journal/20260930120000_t12343-capture/migration.sql +47 -0
- package/migrations/sync-journal/20261001170000_t12984-sealer/migration.sql +101 -0
- package/package.json +13 -13
- package/templates/CLEO-INJECTION.md +5 -5
- package/templates/CLEO-REFERENCE.md +8 -4
|
@@ -8,15 +8,27 @@
|
|
|
8
8
|
*
|
|
9
9
|
* This module wraps tool execution with:
|
|
10
10
|
*
|
|
11
|
-
* 1. **Content-addressed cache** — keyed on `(canonical, cmd, args,
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* 1. **Content-addressed cache** — keyed on `(canonical, cmd, args,
|
|
12
|
+
* treeHash)`, where `treeHash` is the git tree of the tracked content as
|
|
13
|
+
* it sits in the working tree (T12958, see {@link captureTreeHash}).
|
|
14
|
+
* Cache hits return the prior `exitCode + stdoutTail` without spawning
|
|
15
|
+
* the tool. Two worktrees holding the same content, or a commit, rebase
|
|
16
|
+
* or amend that leaves the tree unchanged, share one result.
|
|
14
17
|
* 2. **Cross-process semaphore** — when N processes simultaneously miss the
|
|
15
18
|
* cache, only one runs the tool; the rest block on a `proper-lockfile`
|
|
16
19
|
* and read the freshly-written cache entry.
|
|
17
|
-
* 3. **Automatic invalidation** — entries become
|
|
18
|
-
* changes
|
|
19
|
-
*
|
|
20
|
+
* 3. **Automatic invalidation** — entries become unreachable as soon as the
|
|
21
|
+
* tracked content changes, because the key moves with it. Nothing is
|
|
22
|
+
* deleted on access (no GC daemon required).
|
|
23
|
+
* 4. **Failed-first reruns** — a failing `test` run remembers its failing
|
|
24
|
+
* test files; the next run re-runs those first and stops if they still
|
|
25
|
+
* fail (T12961, see `tool-cache-failed-first.ts`). A failing run is
|
|
26
|
+
* re-run in full once; a pass then is recorded as `flaky`.
|
|
27
|
+
* 5. **Resource kills are not results** — a run killed by a signal, an
|
|
28
|
+
* exit of 128 + a kill signal, or a heap OOM is returned but never
|
|
29
|
+
* cached, and the key includes the heap and worker limits the run was
|
|
30
|
+
* given, so a retry with more memory always runs (T12989, see
|
|
31
|
+
* {@link resourceKillReason}).
|
|
20
32
|
*
|
|
21
33
|
* Cache layout (under `<projectRoot>/.cleo/cache/evidence/`):
|
|
22
34
|
*
|
|
@@ -29,6 +41,7 @@
|
|
|
29
41
|
* @task T1534
|
|
30
42
|
* @adr ADR-061
|
|
31
43
|
*/
|
|
44
|
+
import { type FailedFirstReport } from './tool-cache-failed-first.js';
|
|
32
45
|
import type { ResolvedToolCommand } from './tool-resolver.js';
|
|
33
46
|
import { type AcquireSlotOptions } from './tool-semaphore.js';
|
|
34
47
|
/**
|
|
@@ -41,20 +54,18 @@ export interface ToolCacheEntry {
|
|
|
41
54
|
* Schema version for forwards compatibility.
|
|
42
55
|
*
|
|
43
56
|
* Bumped 1 -> 2 by gh#1419, which added {@link ToolCacheEntry.executionRoot}
|
|
44
|
-
* to the run's identity
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* `exitCode === null`, then `head === null` — while this field, whose entire
|
|
51
|
-
* purpose is to retire incompatible entries, stayed at 1 through both.
|
|
52
|
-
* Two defects, two hand-written retirement clauses, one unused version
|
|
53
|
-
* counter sitting between them.
|
|
57
|
+
* to the run's identity, 2 -> 3 by T12958, which replaced HEAD + dirty
|
|
58
|
+
* fingerprint + execution root with the tree hash, and 3 -> 4 by T12989,
|
|
59
|
+
* which added {@link ToolCacheEntry.resourceEnv}. Every entry written under
|
|
60
|
+
* an older identity is refused wholesale by {@link readCacheEntry} on this
|
|
61
|
+
* one comparison — the retirement mechanism gh#1380 and gh#1404 each rebuilt
|
|
62
|
+
* by hand with a bespoke null-check on the field they had just added.
|
|
54
63
|
*
|
|
55
64
|
* @task T12190 (gh#1419)
|
|
65
|
+
* @task T12958
|
|
66
|
+
* @task T12989
|
|
56
67
|
*/
|
|
57
|
-
schemaVersion:
|
|
68
|
+
schemaVersion: typeof TOOL_CACHE_SCHEMA_VERSION;
|
|
58
69
|
/** Cache key (also encoded in the filename). */
|
|
59
70
|
key: string;
|
|
60
71
|
/** Canonical tool name from the resolver. */
|
|
@@ -67,28 +78,61 @@ export interface ToolCacheEntry {
|
|
|
67
78
|
args: string[];
|
|
68
79
|
/** Resolution source from the resolver. */
|
|
69
80
|
source: string;
|
|
70
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* Git tree object of the tracked content the run measured — HEAD's tree with
|
|
83
|
+
* every uncommitted tracked change applied (see {@link captureTreeHash}).
|
|
84
|
+
*
|
|
85
|
+
* This is the run's content IDENTITY and the only repo-state input to the
|
|
86
|
+
* key (T12958). It replaced `head` + `dirtyFingerprint` + `executionRoot`,
|
|
87
|
+
* which named WHERE and AFTER WHICH COMMIT a run happened rather than WHAT it
|
|
88
|
+
* measured, so every worktree and every commit missed — including an empty
|
|
89
|
+
* commit or a rebase that left the content byte-identical.
|
|
90
|
+
*
|
|
91
|
+
* The tree object is written to the repository's (shared) object database,
|
|
92
|
+
* so a hit stays auditable after the worktree that produced it is deleted:
|
|
93
|
+
* `git ls-tree <treeHash>` shows exactly the content that ran.
|
|
94
|
+
*
|
|
95
|
+
* @task T12958
|
|
96
|
+
*/
|
|
97
|
+
treeHash: string | null;
|
|
98
|
+
/**
|
|
99
|
+
* Fingerprint of the per-checkout environment the run depended on — the
|
|
100
|
+
* installed-lockfile snapshot, workspace `dist/` file sizes and `.env*`
|
|
101
|
+
* content (see `tool-cache-env.ts`). `'none'` for tools that read only
|
|
102
|
+
* source. Part of the key.
|
|
103
|
+
*
|
|
104
|
+
* @task T12958
|
|
105
|
+
*/
|
|
106
|
+
envFingerprint: string;
|
|
107
|
+
/**
|
|
108
|
+
* The resource limits the run was spawned with, as readable `NAME=value`
|
|
109
|
+
* pairs: the heap flags in `NODE_OPTIONS` and, for heavy tools, every worker
|
|
110
|
+
* count and memory lever `heavyToolEnv` manages (see `captureResourceEnv` in
|
|
111
|
+
* `tool-cache-env.ts`). Part of the key, so a retry with a larger heap or
|
|
112
|
+
* fewer workers is a different run rather than a hit on the old result, and
|
|
113
|
+
* a cached result says which limits produced it.
|
|
114
|
+
*
|
|
115
|
+
* @task T12989
|
|
116
|
+
*/
|
|
117
|
+
resourceEnv: string;
|
|
118
|
+
/** Git HEAD sha at execution time. Informational since T12958: NOT keyed. */
|
|
71
119
|
head: string | null;
|
|
72
|
-
/** sha256 of `git diff HEAD` — CONTENT of the uncommitted tracked changes (gh#1452). */
|
|
73
|
-
dirtyFingerprint: string | null;
|
|
74
120
|
/**
|
|
75
121
|
* Absolute, symlink-resolved path of the tree the tool actually ran in.
|
|
76
122
|
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
123
|
+
* Recorded for audit, NOT part of the key since T12958. gh#1419 keyed it to
|
|
124
|
+
* stop two worktrees at one HEAD sharing a result while their content
|
|
125
|
+
* differed; the tree hash keys on the content itself, so two trees share a
|
|
126
|
+
* result exactly when they hold the same tracked content, which is the case
|
|
127
|
+
* sharing is correct for. Nothing the tool returns depends on the directory
|
|
128
|
+
* name: the command and args are keyed, and script resolution is a function
|
|
129
|
+
* of the tracked `package.json` content the tree hash covers.
|
|
83
130
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* entries found 0 that could say which tree produced them, and 8 that had
|
|
87
|
-
* been produced in worktrees since deleted — every one `exitCode: 0` and
|
|
88
|
-
* still servable, which makes the evidence unfalsifiable rather than merely
|
|
89
|
-
* stale. Nobody can go and look.
|
|
131
|
+
* The gh#1419 "unfalsifiable after the worktree is deleted" concern is met by
|
|
132
|
+
* {@link ToolCacheEntry.treeHash}: the content is a git object, not a path.
|
|
90
133
|
*
|
|
91
134
|
* @task T12190 (gh#1419)
|
|
135
|
+
* @task T12958
|
|
92
136
|
*/
|
|
93
137
|
executionRoot: string;
|
|
94
138
|
/** Process exit code. */
|
|
@@ -100,6 +144,15 @@ export interface ToolCacheEntry {
|
|
|
100
144
|
* it; absent and `null` both mean "not killed by a signal".
|
|
101
145
|
*/
|
|
102
146
|
signal?: NodeJS.Signals | null;
|
|
147
|
+
/**
|
|
148
|
+
* Why the run is not a verdict on the code: it was killed for resources
|
|
149
|
+
* ({@link resourceKillReason}). An entry that carries it is never served or
|
|
150
|
+
* persisted ({@link isEntryUsable}); it appears only on the `entry` of the
|
|
151
|
+
* result that reports the kill.
|
|
152
|
+
*
|
|
153
|
+
* @task T12989
|
|
154
|
+
*/
|
|
155
|
+
resourceKill?: string;
|
|
103
156
|
/** Last 512 bytes of stdout. */
|
|
104
157
|
stdoutTail: string;
|
|
105
158
|
/** Last 512 bytes of stderr. */
|
|
@@ -108,6 +161,50 @@ export interface ToolCacheEntry {
|
|
|
108
161
|
durationMs: number;
|
|
109
162
|
/** ISO 8601 wall-clock timestamp of the run. */
|
|
110
163
|
capturedAt: string;
|
|
164
|
+
/**
|
|
165
|
+
* Test files (relative to the execution root) that failed in this run, when
|
|
166
|
+
* the tool is `test`, the run failed and the runner's output named them.
|
|
167
|
+
* Absent when unknown.
|
|
168
|
+
*
|
|
169
|
+
* @task T12961
|
|
170
|
+
*/
|
|
171
|
+
failedTestFiles?: string[];
|
|
172
|
+
/**
|
|
173
|
+
* Present when a failed-first stage ran before this result. An entry whose
|
|
174
|
+
* `failedFirst.outcome` is `failed` was decided by the focused rerun alone:
|
|
175
|
+
* the previously failing files still failed, so the normal command was
|
|
176
|
+
* never spawned. A failing subset is a failing suite, which is why that
|
|
177
|
+
* result is cached under the normal command's key.
|
|
178
|
+
*
|
|
179
|
+
* @task T12961
|
|
180
|
+
*/
|
|
181
|
+
failedFirst?: FailedFirstReport;
|
|
182
|
+
/**
|
|
183
|
+
* Test files that failed and then passed on their single retry (T12961).
|
|
184
|
+
* Present only on a PASSING entry: the run counts as a pass, but a flaky
|
|
185
|
+
* pass, which is visible here rather than indistinguishable from a clean
|
|
186
|
+
* one.
|
|
187
|
+
*
|
|
188
|
+
* @task T12961
|
|
189
|
+
*/
|
|
190
|
+
flaky?: string[];
|
|
191
|
+
/**
|
|
192
|
+
* The tail of the first, failing run's output when the entry is a flaky
|
|
193
|
+
* pass — the audit trail of what failed before the rerun passed.
|
|
194
|
+
*
|
|
195
|
+
* @task T12961
|
|
196
|
+
*/
|
|
197
|
+
flakyFailureTail?: string;
|
|
198
|
+
/**
|
|
199
|
+
* `focused`: this record describes a failed-first run of only
|
|
200
|
+
* {@link ToolCacheEntry.ranFiles}, not the recorded command. Such records
|
|
201
|
+
* are returned to the caller but never persisted under the command's key.
|
|
202
|
+
*
|
|
203
|
+
* @task T12961
|
|
204
|
+
*/
|
|
205
|
+
scope?: 'focused';
|
|
206
|
+
/** The test files a `scope: 'focused'` run executed. */
|
|
207
|
+
ranFiles?: string[];
|
|
111
208
|
}
|
|
112
209
|
/**
|
|
113
210
|
* Result of {@link runToolCached}. Mirrors the legacy `validateTool`
|
|
@@ -130,6 +227,11 @@ export interface ToolRunResult {
|
|
|
130
227
|
durationMs: number;
|
|
131
228
|
/** `true` when the result came from cache (no spawn occurred). */
|
|
132
229
|
cacheHit: boolean;
|
|
230
|
+
/**
|
|
231
|
+
* Git tree of the source this result measured ({@link captureTreeHash});
|
|
232
|
+
* `null` off git. Exposed so evidence atoms can bind to it (T12958).
|
|
233
|
+
*/
|
|
234
|
+
treeHash: string | null;
|
|
133
235
|
/**
|
|
134
236
|
* `true` when the wall-clock child-process deadline was exceeded and the
|
|
135
237
|
* tool was terminated before producing a result. The lock + semaphore
|
|
@@ -179,6 +281,28 @@ export interface ToolRunResult {
|
|
|
179
281
|
* @task T12116 (gh#1397)
|
|
180
282
|
*/
|
|
181
283
|
harnessFailure: string | null;
|
|
284
|
+
/**
|
|
285
|
+
* Why the run was killed for resources ({@link resourceKillReason}), else
|
|
286
|
+
* `null`: a signal, an exit of 128 + a kill signal, or output reporting a
|
|
287
|
+
* heap OOM. Non-null means the exit code is not a verdict on the code and
|
|
288
|
+
* nothing was cached; a retry runs again, and a retry with a larger heap or
|
|
289
|
+
* fewer workers runs under a different key. `null` too when `timedOut` or
|
|
290
|
+
* `harnessFailure` already explains the non-result.
|
|
291
|
+
*
|
|
292
|
+
* @task T12989
|
|
293
|
+
*/
|
|
294
|
+
resourceKill: string | null;
|
|
295
|
+
/**
|
|
296
|
+
* The failed-first stage of this run (T12961), when one ran: which files
|
|
297
|
+
* were re-run first and whether they decided the result.
|
|
298
|
+
*/
|
|
299
|
+
failedFirst?: FailedFirstReport;
|
|
300
|
+
/**
|
|
301
|
+
* Test files from the first, failing run when its one full rerun passed
|
|
302
|
+
* (T12961). Set only on a pass: it marks a FLAKY pass, distinct from a
|
|
303
|
+
* clean one, for evidence atoms and gates to surface.
|
|
304
|
+
*/
|
|
305
|
+
flaky?: string[];
|
|
182
306
|
/** Full cache entry — useful for audit / debugging. */
|
|
183
307
|
entry: ToolCacheEntry;
|
|
184
308
|
}
|
|
@@ -193,10 +317,9 @@ export interface RunToolOptions {
|
|
|
193
317
|
* written to cache for subsequent calls.
|
|
194
318
|
*
|
|
195
319
|
* When omitted, `CLEO_EVIDENCE_FRESH=1` in the environment turns this on.
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* without committing first.
|
|
320
|
+
* It is the escape hatch for anything the key cannot see — a change under
|
|
321
|
+
* an excluded or gitignored path, or environment state outside the
|
|
322
|
+
* fingerprint. It also skips failed-first reruns (T12961).
|
|
200
323
|
*
|
|
201
324
|
* @defaultValue `false` (or `CLEO_EVIDENCE_FRESH === '1'`)
|
|
202
325
|
* @task T12112 (gh#1221)
|
|
@@ -264,7 +387,32 @@ export interface RunToolOptions {
|
|
|
264
387
|
* @task T12112 (gh#1220, gh#1226, gh#1230)
|
|
265
388
|
*/
|
|
266
389
|
executionRoot?: string;
|
|
390
|
+
/**
|
|
391
|
+
* How long a caller that finds this key's lock held waits for the holder's
|
|
392
|
+
* result before giving up with `lockBusy` (T12958). The holder is running
|
|
393
|
+
* the identical command on identical content, so waiting and reusing its
|
|
394
|
+
* result is always cheaper than running in parallel.
|
|
395
|
+
*
|
|
396
|
+
* @defaultValue 3 × the spawn deadline + 60 s (focused rerun + normal run
|
|
397
|
+
* + one flake retry)
|
|
398
|
+
*/
|
|
399
|
+
lockWaitMs?: number;
|
|
400
|
+
/**
|
|
401
|
+
* Poll interval while waiting on a held lock.
|
|
402
|
+
*
|
|
403
|
+
* @defaultValue `1_000`
|
|
404
|
+
* @internal
|
|
405
|
+
*/
|
|
406
|
+
lockPollMs?: number;
|
|
267
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Most failing test files a failed `test` run may name and still get its one
|
|
410
|
+
* full flake retry (T12961). More, or none named, is treated as a
|
|
411
|
+
* deterministic failure: no retry.
|
|
412
|
+
*
|
|
413
|
+
* @task T12961
|
|
414
|
+
*/
|
|
415
|
+
export declare const MAX_FLAKE_RETRY_FILES = 3;
|
|
268
416
|
/**
|
|
269
417
|
* Default wall-clock deadline for one evidence-tool child process, in ms.
|
|
270
418
|
*
|
|
@@ -388,9 +536,32 @@ export declare function resolveSpawnTimeoutMs(canonical: string, env?: NodeJS.Pr
|
|
|
388
536
|
* {@link isEntryUsable} (gh#1380: an unknown outcome must never be cached).
|
|
389
537
|
* Putting it here would key the cache on its own answer.
|
|
390
538
|
*
|
|
539
|
+
* `head` and `executionRoot` are recorded on every entry but are no longer
|
|
540
|
+
* identity (T12958). Both name a LOCATION — which commit, which directory —
|
|
541
|
+
* rather than the content measured, so keying on them made every worktree and
|
|
542
|
+
* every commit a miss even when the tracked content was byte-identical.
|
|
543
|
+
* `treeHash` is the content itself; it subsumes the old `dirtyFingerprint`.
|
|
544
|
+
* `envFingerprint` covers the per-checkout state git does not see (installed
|
|
545
|
+
* deps, gitignored build output, `.env*`), so sharing across worktrees
|
|
546
|
+
* happens only when BOTH the source and the environment match.
|
|
547
|
+
* `resourceEnv` (T12989) covers the limits the run was spawned with — heap
|
|
548
|
+
* flags and worker counts — which neither the tree nor the checkout shows: a
|
|
549
|
+
* 3 GB run that ran out of memory and a 6 GB retry of the same code are two
|
|
550
|
+
* runs, and keying them as one is what replayed the OOM.
|
|
551
|
+
*
|
|
391
552
|
* @task T12190 (gh#1419)
|
|
553
|
+
* @task T12958
|
|
554
|
+
* @task T12989
|
|
392
555
|
*/
|
|
393
|
-
export declare const TOOL_RUN_IDENTITY_FIELDS: readonly ["canonical", "cmd", "args", "
|
|
556
|
+
export declare const TOOL_RUN_IDENTITY_FIELDS: readonly ["canonical", "cmd", "args", "treeHash", "envFingerprint", "resourceEnv"];
|
|
557
|
+
/**
|
|
558
|
+
* Current {@link ToolCacheEntry.schemaVersion}. Entries of any other version
|
|
559
|
+
* are refused on read.
|
|
560
|
+
*
|
|
561
|
+
* @task T12958
|
|
562
|
+
* @task T12989
|
|
563
|
+
*/
|
|
564
|
+
export declare const TOOL_CACHE_SCHEMA_VERSION = 4;
|
|
394
565
|
/**
|
|
395
566
|
* The identity half of a {@link ToolCacheEntry} — the inputs that determine
|
|
396
567
|
* which run it is, independent of what that run produced.
|
|
@@ -399,43 +570,53 @@ export declare const TOOL_RUN_IDENTITY_FIELDS: readonly ["canonical", "cmd", "ar
|
|
|
399
570
|
*/
|
|
400
571
|
export type ToolRunIdentity = Pick<ToolCacheEntry, (typeof TOOL_RUN_IDENTITY_FIELDS)[number]>;
|
|
401
572
|
/**
|
|
402
|
-
* Compute the cache key for a resolved tool command +
|
|
573
|
+
* Compute the cache key for a resolved tool command + tracked tree content.
|
|
403
574
|
*
|
|
404
575
|
* The key covers exactly {@link TOOL_RUN_IDENTITY_FIELDS} — canonical tool
|
|
405
|
-
* name, resolved command and args,
|
|
406
|
-
*
|
|
407
|
-
* declares, so the hashed payload is a function of the
|
|
408
|
-
* field there changes every key by construction.
|
|
576
|
+
* name, resolved command and args, the tree hash, the environment
|
|
577
|
+
* fingerprint and the resource environment. Fields are projected in
|
|
578
|
+
* the order that array declares, so the hashed payload is a function of the
|
|
579
|
+
* array and adding a field there changes every key by construction.
|
|
409
580
|
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
* shape of the defect this fixes, since `executionRoot` already existed and
|
|
414
|
-
* already reached this function's caller.
|
|
581
|
+
* There is deliberately no directory parameter (T12958): two checkouts with
|
|
582
|
+
* the same tracked content get the same key, which is what lets parallel
|
|
583
|
+
* worktrees and post-rebase re-verifies reuse one run.
|
|
415
584
|
*
|
|
416
585
|
* Using `createHash('sha256')` makes the key collision-resistant and bounded
|
|
417
586
|
* to 32 hex chars regardless of input size.
|
|
418
587
|
*
|
|
588
|
+
* @param command - Resolved tool command.
|
|
589
|
+
* @param treeHash - {@link captureTreeHash} of the execution root.
|
|
590
|
+
* @param envFingerprint - {@link captureEnvFingerprint} of the execution root.
|
|
591
|
+
* @param resourceEnv - {@link captureResourceEnv} of the spawn environment.
|
|
592
|
+
* @returns 32 hex chars.
|
|
593
|
+
*
|
|
419
594
|
* @task T1534
|
|
420
595
|
* @task T12190 (gh#1419)
|
|
596
|
+
* @task T12958
|
|
597
|
+
* @task T12989
|
|
421
598
|
*/
|
|
422
|
-
export declare function computeCacheKey(command: ResolvedToolCommand,
|
|
599
|
+
export declare function computeCacheKey(command: ResolvedToolCommand, treeHash: string | null, envFingerprint: string, resourceEnv: string): string;
|
|
423
600
|
/**
|
|
424
601
|
* Whether a cache entry may be SERVED or PERSISTED as a real result.
|
|
425
602
|
*
|
|
426
603
|
* One predicate, used by both {@link readCacheEntry} and the persist guard in
|
|
427
|
-
* `runToolCached`, so the two cannot drift apart.
|
|
604
|
+
* `runToolCached`, so the two cannot drift apart. Three rules:
|
|
428
605
|
*
|
|
429
606
|
* 1. every field in {@link TOOL_RUN_IDENTITY_FIELDS} is present and
|
|
430
607
|
* non-null — an entry that cannot say which run it describes is not
|
|
431
608
|
* evidence of anything;
|
|
432
609
|
* 2. `exitCode` is non-null — a run that produced no exit code records that
|
|
433
610
|
* we do not know what happened, and an unknown must never be cached
|
|
434
|
-
* (gh#1380)
|
|
611
|
+
* (gh#1380);
|
|
612
|
+
* 3. `resourceKill` is absent — a run killed for resources (an OOM, a heap
|
|
613
|
+
* limit, exit 137) has a real exit code that says nothing about the code,
|
|
614
|
+
* and caching it replays the kill to every retry, including one given
|
|
615
|
+
* the memory it lacked (T12989).
|
|
435
616
|
*
|
|
436
617
|
* Rule 1 subsumes gh#1404's `head === null` clause without naming `head`:
|
|
437
|
-
* when the tool runs off a non-git root
|
|
438
|
-
*
|
|
618
|
+
* when the tool runs off a non-git root `treeHash` is null on EVERY run, so
|
|
619
|
+
* the key is a function of the command alone and nothing a developer
|
|
439
620
|
* does to the source can rotate it. That is not a cache, it is a hardcoded
|
|
440
621
|
* answer with a filename — and unlike gh#1380 it holds a real exit code,
|
|
441
622
|
* which can be a PASS. A poisoned red is investigated within minutes; nobody
|
|
@@ -446,8 +627,76 @@ export declare function computeCacheKey(command: ResolvedToolCommand, head: stri
|
|
|
446
627
|
* getting valid caching today — they are getting one answer forever.
|
|
447
628
|
*
|
|
448
629
|
* @task T12190 (gh#1419)
|
|
630
|
+
* @task T12989
|
|
449
631
|
*/
|
|
450
632
|
export declare function isEntryUsable(entry: Partial<ToolCacheEntry>): boolean;
|
|
633
|
+
/**
|
|
634
|
+
* Why a finished run was killed for resources, or `null` when its outcome is
|
|
635
|
+
* a real result.
|
|
636
|
+
*
|
|
637
|
+
* Decides from the exit and the captured output, in order:
|
|
638
|
+
*
|
|
639
|
+
* 1. a terminating `signal` — the process did not exit on its own;
|
|
640
|
+
* 2. an exit code of `128 + n` for a {@link KILL_SIGNALS} signal — the same
|
|
641
|
+
* kill, reported by a wrapper (`sh` exits 137 for a `SIGKILL`ed child);
|
|
642
|
+
* 3. a non-zero exit whose output carries a {@link RESOURCE_KILL_MARKERS}
|
|
643
|
+
* marker — vitest catches a worker's heap OOM and exits 1.
|
|
644
|
+
*
|
|
645
|
+
* Exit 0 is always a result, and so is a plain non-zero exit such as a failing
|
|
646
|
+
* assertion's 1: that red stays cacheable for failed-first reruns. A run that
|
|
647
|
+
* never started (`exitCode` and `signal` both null) is not a kill; it is
|
|
648
|
+
* reported, and refused by {@link isEntryUsable}, as an unknown outcome.
|
|
649
|
+
*
|
|
650
|
+
* @param run - The finished run's exit code, signal and captured output.
|
|
651
|
+
* @returns A short reason, e.g. `exit 137 (128 + SIGKILL)`, or `null`.
|
|
652
|
+
*
|
|
653
|
+
* @example
|
|
654
|
+
* ```ts
|
|
655
|
+
* resourceKillReason({ exitCode: 1, signal: null, stdout: '', stderr: 'FAIL a.test.ts' }); // null
|
|
656
|
+
* resourceKillReason({ exitCode: 137, signal: null, stdout: '', stderr: '' });
|
|
657
|
+
* // → 'exit 137 (128 + SIGKILL)'
|
|
658
|
+
* ```
|
|
659
|
+
*
|
|
660
|
+
* @task T12989
|
|
661
|
+
*/
|
|
662
|
+
export declare function resourceKillReason(run: {
|
|
663
|
+
exitCode: number | null;
|
|
664
|
+
signal: NodeJS.Signals | null;
|
|
665
|
+
stdout: string;
|
|
666
|
+
stderr: string;
|
|
667
|
+
}): string | null;
|
|
668
|
+
/** Signals whose default action would end cleo and orphan the tool groups it started. */
|
|
669
|
+
declare const TERMINATION_SIGNALS: readonly ["SIGHUP", "SIGINT", "SIGTERM"];
|
|
670
|
+
/** A signal {@link terminateToolGroupsOnSignal} handles. */
|
|
671
|
+
type TerminationSignal = (typeof TERMINATION_SIGNALS)[number];
|
|
672
|
+
/**
|
|
673
|
+
* SIGTERM every tool group this process started, then re-raise the signal to
|
|
674
|
+
* this process so it ends exactly as it would have without us (T12963).
|
|
675
|
+
*
|
|
676
|
+
* Tools run detached, in their own process group, so a signal that ends cleo
|
|
677
|
+
* (Ctrl-C reaches only the terminal's foreground group) never reaches them:
|
|
678
|
+
* the tool kept running, and the slot it held looked free once cleo was gone.
|
|
679
|
+
*
|
|
680
|
+
* Any listener at all suppresses a signal's default action, and
|
|
681
|
+
* `proper-lockfile` loads `signal-exit`, which re-raises only when its own
|
|
682
|
+
* listeners are the last ones left. So ours removes itself and re-raises:
|
|
683
|
+
* `signal-exit` then releases its locks and the process dies by the signal.
|
|
684
|
+
* Another listener of the signal sees it twice.
|
|
685
|
+
*
|
|
686
|
+
* @param signal - The signal received.
|
|
687
|
+
*
|
|
688
|
+
* @internal Exported for tests.
|
|
689
|
+
* @task T12963
|
|
690
|
+
*/
|
|
691
|
+
export declare function terminateToolGroupsOnSignal(signal: TerminationSignal): void;
|
|
692
|
+
/**
|
|
693
|
+
* The `exit` listener: SIGTERM every tool group still running. `exit`
|
|
694
|
+
* listeners must be synchronous, and `process.kill` is.
|
|
695
|
+
*
|
|
696
|
+
* @internal Exported for tests.
|
|
697
|
+
* @task T12963
|
|
698
|
+
*/
|
|
699
|
+
export declare function terminateToolGroupsOnExit(): void;
|
|
451
700
|
/**
|
|
452
701
|
* Capture the repo's git HEAD sha. Returns `null` when the directory is not
|
|
453
702
|
* a git checkout or the command fails.
|
|
@@ -456,6 +705,62 @@ export declare function isEntryUsable(entry: Partial<ToolCacheEntry>): boolean;
|
|
|
456
705
|
*/
|
|
457
706
|
export declare function captureHead(projectRoot: string): Promise<string | null>;
|
|
458
707
|
export declare function captureDirtyFingerprint(projectRoot: string): Promise<string | null>;
|
|
708
|
+
/**
|
|
709
|
+
* Untracked files larger than this are left out of {@link captureTreeHash}
|
|
710
|
+
* rather than hashed into the object database on every call. Such files are
|
|
711
|
+
* rarely source; a change to one does not move the key (force a run with
|
|
712
|
+
* `CLEO_EVIDENCE_FRESH=1`).
|
|
713
|
+
*/
|
|
714
|
+
export declare const MAX_UNTRACKED_HASH_BYTES: number;
|
|
715
|
+
/**
|
|
716
|
+
* Capture the git tree hash of the working tree's SOURCE content: HEAD's tree
|
|
717
|
+
* with every uncommitted change applied — staged or not, to tracked files and
|
|
718
|
+
* to untracked files that are not gitignored. Returns `null` for non-git
|
|
719
|
+
* roots or on any git failure (the entry is then unusable and nothing is
|
|
720
|
+
* cached).
|
|
721
|
+
*
|
|
722
|
+
* ## How (T12958)
|
|
723
|
+
*
|
|
724
|
+
* 1. Copy the checkout's own index to a private temporary file, preserving
|
|
725
|
+
* its atime/mtime. The copy keeps the index's stat cache, so git re-hashes
|
|
726
|
+
* only files whose stat changed. The preserved mtime matters: git's
|
|
727
|
+
* racy-clean check compares each entry's mtime with the INDEX FILE's
|
|
728
|
+
* mtime, and a fresh mtime on the copy would let a same-size edit made in
|
|
729
|
+
* the same timestamp tick as the last index write read as clean. The real
|
|
730
|
+
* index is never touched.
|
|
731
|
+
* 2. `GIT_INDEX_FILE=<copy> git add -u -- .` stages every modified or deleted
|
|
732
|
+
* TRACKED path — all of them, including tracked files under `.cleo/`.
|
|
733
|
+
* 3. `git ls-files -o --exclude-standard -z` lists untracked, not-ignored
|
|
734
|
+
* files; those that are not runtime output ({@link isUntrackedRuntimeOutput})
|
|
735
|
+
* and not over {@link MAX_UNTRACKED_HASH_BYTES} are added with
|
|
736
|
+
* `git update-index --add -z --stdin`.
|
|
737
|
+
* 4. `GIT_INDEX_FILE=<copy> git write-tree` prints the tree.
|
|
738
|
+
*
|
|
739
|
+
* A clean checkout yields exactly `HEAD^{tree}`. Two worktrees with the same
|
|
740
|
+
* source yield the same hash wherever they live, and an empty commit, an
|
|
741
|
+
* amend of only the message, or a rebase that reproduces the same content
|
|
742
|
+
* leave it unchanged.
|
|
743
|
+
*
|
|
744
|
+
* ## Untracked files (review of #1774, supersedes the gh#1221 tracked-only rule)
|
|
745
|
+
*
|
|
746
|
+
* An untracked, not-ignored file IS part of the hash. Tracked-only was safe
|
|
747
|
+
* while the key also carried the execution root; once the key is shared
|
|
748
|
+
* across worktrees it is a false pass: a worker's new, uncommitted module and
|
|
749
|
+
* failing test leave the tracked tree equal to main's, and main's cached pass
|
|
750
|
+
* would be served without the worker's tests ever running.
|
|
751
|
+
*
|
|
752
|
+
* Side effect: staging writes blob objects for dirty and new files into the
|
|
753
|
+
* repository's object database, and `write-tree` writes tree objects. Both
|
|
754
|
+
* are ordinary unreferenced loose objects: `git gc` prunes them after
|
|
755
|
+
* `gc.pruneExpire` (two weeks by default), so `git ls-tree <treeHash>` as an
|
|
756
|
+
* audit of an old entry is best-effort.
|
|
757
|
+
*
|
|
758
|
+
* @param root - Directory to fingerprint (the execution root).
|
|
759
|
+
* @returns 40/64 hex chars of the tree object id, or `null`.
|
|
760
|
+
*
|
|
761
|
+
* @task T12958
|
|
762
|
+
*/
|
|
763
|
+
export declare function captureTreeHash(root: string): Promise<string | null>;
|
|
459
764
|
/**
|
|
460
765
|
* Resolve the absolute path for a cache entry by key.
|
|
461
766
|
*
|
|
@@ -483,12 +788,23 @@ export declare function writeCacheEntry(projectRoot: string, entry: ToolCacheEnt
|
|
|
483
788
|
*
|
|
484
789
|
* Flow:
|
|
485
790
|
*
|
|
486
|
-
* 1. Compute cache key (canonical+cmd+args+
|
|
791
|
+
* 1. Compute cache key (canonical+cmd+args+treeHash+envFingerprint+
|
|
792
|
+
* resourceEnv).
|
|
487
793
|
* 2. If a fresh entry exists → return it (no spawn).
|
|
488
|
-
* 3. Acquire a `proper-lockfile` on the cache entry path.
|
|
794
|
+
* 3. Acquire a `proper-lockfile` on the cache entry path. When another
|
|
795
|
+
* caller holds it (same command, same content — possibly another
|
|
796
|
+
* worktree), wait for its result and reuse it (T12958).
|
|
489
797
|
* 4. Re-check cache inside the lock (another process may have written it
|
|
490
798
|
* while we were waiting).
|
|
491
|
-
* 5.
|
|
799
|
+
* 5. For `test`, when the previous run in this execution root failed on a
|
|
800
|
+
* different tree, re-run only its failing files first; if they still
|
|
801
|
+
* fail, return that (uncached, `scope: 'focused'`) failure without the
|
|
802
|
+
* normal run (T12961).
|
|
803
|
+
* 6. Spawn the tool, capture stdout/stderr tails. For a failing `test`,
|
|
804
|
+
* re-run the FULL command once; a pass there is a pass marked `flaky`
|
|
805
|
+
* (T12961). Write the entry, return. A run killed for resources is
|
|
806
|
+
* returned with `resourceKill` set and is neither retried, recorded for
|
|
807
|
+
* failed-first, nor written (T12989).
|
|
492
808
|
*
|
|
493
809
|
* Locks are auto-released on success or failure. Stale locks are reaped per
|
|
494
810
|
* the `lockStaleMs` option (default 10 min — long enough to cover a full
|
|
@@ -500,6 +816,9 @@ export declare function writeCacheEntry(projectRoot: string, entry: ToolCacheEnt
|
|
|
500
816
|
* @returns Result envelope with `exitCode`, `stdoutTail`, `cacheHit`, etc.
|
|
501
817
|
*
|
|
502
818
|
* @task T1534
|
|
819
|
+
* @task T12958
|
|
820
|
+
* @task T12961
|
|
821
|
+
* @task T12989
|
|
503
822
|
* @adr ADR-061
|
|
504
823
|
*/
|
|
505
824
|
export declare function runToolCached(command: ResolvedToolCommand, projectRoot: string, opts?: RunToolOptions): Promise<ToolRunResult>;
|
|
@@ -511,4 +830,5 @@ export declare function runToolCached(command: ResolvedToolCommand, projectRoot:
|
|
|
511
830
|
export declare function clearToolCache(projectRoot: string): {
|
|
512
831
|
removed: number;
|
|
513
832
|
};
|
|
833
|
+
export {};
|
|
514
834
|
//# sourceMappingURL=tool-cache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-cache.d.ts","sourceRoot":"","sources":["../../src/tasks/tool-cache.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tool-cache.d.ts","sourceRoot":"","sources":["../../src/tasks/tool-cache.ts"],"names":[],"mappings":"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"}
|