@mjasnikovs/pi-task 0.38.28 → 0.38.30
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/config/config.d.ts +70 -70
- package/dist/config/config.js +26 -35
- package/dist/config/extension-list.d.ts +6 -5
- package/dist/config/extension-list.js +3 -2
- package/dist/config/reasoning-args.d.ts +9 -7
- package/dist/config/reasoning-args.js +12 -10
- package/dist/config/reasoning.d.ts +44 -105
- package/dist/config/reasoning.js +27 -704
- package/dist/config/register.d.ts +34 -48
- package/dist/config/register.js +41 -51
- package/dist/config/tool-list.d.ts +16 -16
- package/dist/config/tool-list.js +1 -1
- package/dist/remote/bridge.d.ts +19 -10
- package/dist/remote/bridge.js +3 -2
- package/dist/remote/broadcast.js +3 -1
- package/dist/remote/events.js +12 -11
- package/dist/remote/history.d.ts +1 -1
- package/dist/remote/protocol.d.ts +6 -3
- package/dist/remote/protocol.js +2 -1
- package/dist/remote/push.d.ts +16 -16
- package/dist/remote/push.js +27 -27
- package/dist/remote/register.d.ts +3 -3
- package/dist/remote/register.js +17 -19
- package/dist/remote/server.d.ts +9 -8
- package/dist/remote/server.js +15 -14
- package/dist/remote/session-state.d.ts +5 -4
- package/dist/remote/session-state.js +8 -5
- package/dist/remote/sw.d.ts +7 -6
- package/dist/remote/sw.js +7 -6
- package/dist/remote/tailscale.d.ts +4 -2
- package/dist/remote/tailscale.js +4 -2
- package/dist/remote/ui-highlight.js +6 -5
- package/dist/remote/ui-render.js +4 -4
- package/dist/remote/ui-script.js +24 -24
- package/dist/remote/ui-styles.d.ts +1 -1
- package/dist/remote/ui-styles.js +10 -13
- package/dist/remote/ui-tools.js +9 -6
- package/dist/shared/child-extensions.d.ts +29 -17
- package/dist/shared/child-extensions.js +29 -17
- package/dist/shared/child-output.d.ts +30 -24
- package/dist/shared/child-output.js +25 -17
- package/dist/shared/child-process.d.ts +47 -40
- package/dist/shared/child-process.js +50 -59
- package/dist/shared/command-watchdog.d.ts +22 -16
- package/dist/shared/command-watchdog.js +28 -21
- package/dist/shared/fs-text.d.ts +16 -10
- package/dist/shared/fs-text.js +16 -10
- package/dist/shared/git-runner.d.ts +25 -25
- package/dist/shared/git-runner.js +25 -25
- package/dist/shared/leaked-tool-call.d.ts +17 -11
- package/dist/shared/leaked-tool-call.js +23 -15
- package/dist/shared/model-endpoint.d.ts +29 -16
- package/dist/shared/model-endpoint.js +33 -21
- package/dist/shared/pi-invocation.d.ts +7 -4
- package/dist/shared/pi-invocation.js +12 -7
- package/dist/shared/pkg-version.d.ts +13 -5
- package/dist/shared/pkg-version.js +13 -5
- package/dist/shared/reasoning-capability.d.ts +35 -24
- package/dist/shared/reasoning-capability.js +35 -24
- package/dist/shared/stream-watchdog.d.ts +60 -44
- package/dist/shared/stream-watchdog.js +62 -45
- package/dist/task/accept-debt.d.ts +41 -43
- package/dist/task/accept-debt.js +73 -65
- package/dist/task/api-synthesis.d.ts +24 -21
- package/dist/task/api-synthesis.js +32 -26
- package/dist/task/apis-contract.d.ts +32 -64
- package/dist/task/apis-contract.js +32 -64
- package/dist/task/artifact-closure.d.ts +27 -13
- package/dist/task/artifact-closure.js +95 -67
- package/dist/task/auto-commit.d.ts +46 -35
- package/dist/task/auto-commit.js +51 -38
- package/dist/task/auto-io.d.ts +45 -25
- package/dist/task/auto-io.js +57 -29
- package/dist/task/auto-orchestrator.d.ts +26 -24
- package/dist/task/auto-orchestrator.js +178 -162
- package/dist/task/auto-prompts.d.ts +36 -24
- package/dist/task/auto-prompts.js +40 -26
- package/dist/task/autofix-ledger.d.ts +27 -25
- package/dist/task/autofix-ledger.js +29 -26
- package/dist/task/batch-test-task.d.ts +20 -12
- package/dist/task/batch-test-task.js +67 -60
- package/dist/task/boot-probe.d.ts +60 -44
- package/dist/task/boot-probe.js +91 -72
- package/dist/task/cancel-input.d.ts +30 -16
- package/dist/task/cancel-input.js +20 -11
- package/dist/task/cancel-points.d.ts +27 -20
- package/dist/task/cancel-points.js +30 -22
- package/dist/task/child-runner.d.ts +46 -51
- package/dist/task/child-runner.js +48 -49
- package/dist/task/child-status.d.ts +23 -16
- package/dist/task/child-status.js +23 -16
- package/dist/task/clamp-output.js +12 -5
- package/dist/task/command-run.d.ts +31 -28
- package/dist/task/command-run.js +44 -35
- package/dist/task/command-shrink.d.ts +25 -18
- package/dist/task/command-shrink.js +37 -31
- package/dist/task/command-watchdog.d.ts +9 -6
- package/dist/task/command-watchdog.js +21 -15
- package/dist/task/context-attribution.d.ts +34 -26
- package/dist/task/context-attribution.js +34 -26
- package/dist/task/context-silence.d.ts +39 -29
- package/dist/task/context-silence.js +35 -25
- package/dist/task/context-usage.d.ts +25 -7
- package/dist/task/context-usage.js +21 -6
- package/dist/task/contracts.d.ts +8 -4
- package/dist/task/contracts.js +25 -17
- package/dist/task/coverage-loop.d.ts +22 -18
- package/dist/task/coverage-loop.js +35 -30
- package/dist/task/critique-probes.d.ts +13 -14
- package/dist/task/critique-probes.js +50 -39
- package/dist/task/debug-log.d.ts +13 -5
- package/dist/task/debug-log.js +32 -20
- package/dist/task/decompose-fidelity.d.ts +11 -9
- package/dist/task/decompose-fidelity.js +38 -33
- package/dist/task/decompose-granularity.d.ts +41 -38
- package/dist/task/decompose-granularity.js +41 -38
- package/dist/task/deep-render-check.d.ts +22 -14
- package/dist/task/deep-render-check.js +40 -31
- package/dist/task/dropped-input.d.ts +12 -7
- package/dist/task/dropped-input.js +5 -2
- package/dist/task/enforce-attribution.d.ts +38 -47
- package/dist/task/enforce-attribution.js +46 -52
- package/dist/task/enforce-guidelines.d.ts +31 -20
- package/dist/task/enforce-guidelines.js +32 -21
- package/dist/task/enrichment.d.ts +7 -2
- package/dist/task/enrichment.js +26 -14
- package/dist/task/env-notes.d.ts +16 -7
- package/dist/task/env-notes.js +48 -31
- package/dist/task/env-template-closure.d.ts +4 -4
- package/dist/task/env-template-closure.js +42 -34
- package/dist/task/external-context.d.ts +28 -21
- package/dist/task/external-context.js +17 -12
- package/dist/task/failure-classifier.d.ts +4 -5
- package/dist/task/failure-classifier.js +6 -7
- package/dist/task/file-inventory.d.ts +15 -11
- package/dist/task/file-inventory.js +25 -22
- package/dist/task/final-gate-fix.d.ts +74 -86
- package/dist/task/final-gate-fix.js +97 -116
- package/dist/task/final-gate-progress.d.ts +29 -46
- package/dist/task/final-gate-progress.js +40 -51
- package/dist/task/final-gate.d.ts +64 -97
- package/dist/task/final-gate.js +192 -199
- package/dist/task/fix-child.d.ts +21 -27
- package/dist/task/fix-child.js +21 -27
- package/dist/task/foreign-path.d.ts +6 -5
- package/dist/task/foreign-path.js +0 -0
- package/dist/task/frozen-conflict.d.ts +9 -10
- package/dist/task/frozen-conflict.js +61 -64
- package/dist/task/frozen-path-guard.d.ts +35 -14
- package/dist/task/frozen-path-guard.js +56 -39
- package/dist/task/gate-child.d.ts +27 -28
- package/dist/task/gate-child.js +37 -35
- package/dist/task/gate-deps.d.ts +34 -27
- package/dist/task/gate-deps.js +169 -159
- package/dist/task/gate-tally.d.ts +77 -80
- package/dist/task/gate-tally.js +65 -68
- package/dist/task/git-state-guard.d.ts +15 -11
- package/dist/task/git-state-guard.js +76 -66
- package/dist/task/impl-widget.d.ts +25 -16
- package/dist/task/impl-widget.js +27 -17
- package/dist/task/implementation-thinking.d.ts +33 -31
- package/dist/task/implementation-thinking.js +5 -6
- package/dist/task/implementation-turn.d.ts +34 -31
- package/dist/task/implementation-turn.js +29 -27
- package/dist/task/inline-markdown.d.ts +20 -7
- package/dist/task/inline-markdown.js +15 -6
- package/dist/task/launch-config-gap.js +25 -39
- package/dist/task/launch-contract.d.ts +18 -21
- package/dist/task/launch-contract.js +28 -30
- package/dist/task/launch-manifest.d.ts +6 -2
- package/dist/task/launch-manifest.js +35 -34
- package/dist/task/ledger.js +16 -14
- package/dist/task/lint-fix.d.ts +6 -8
- package/dist/task/lint-fix.js +67 -69
- package/dist/task/loop-detector.d.ts +9 -8
- package/dist/task/loop-detector.js +16 -12
- package/dist/task/mid-run-input.d.ts +17 -15
- package/dist/task/mid-run-input.js +17 -15
- package/dist/task/orchestrator.d.ts +24 -28
- package/dist/task/orchestrator.js +62 -64
- package/dist/task/orientation.d.ts +18 -23
- package/dist/task/orientation.js +24 -31
- package/dist/task/owned-freeze-conflict.d.ts +21 -20
- package/dist/task/owned-freeze-conflict.js +52 -85
- package/dist/task/owned-freeze-reassign.d.ts +40 -60
- package/dist/task/owned-freeze-reassign.js +41 -61
- package/dist/task/parsers.d.ts +4 -2
- package/dist/task/parsers.js +4 -4
- package/dist/task/phases.d.ts +41 -48
- package/dist/task/phases.js +180 -248
- package/dist/task/plan-io.d.ts +6 -7
- package/dist/task/plan-io.js +6 -7
- package/dist/task/plan-orchestrator.d.ts +10 -8
- package/dist/task/plan-orchestrator.js +14 -10
- package/dist/task/plan-prompts.d.ts +6 -5
- package/dist/task/plan-prompts.js +6 -5
- package/dist/task/plan-readonly.d.ts +4 -5
- package/dist/task/plan-readonly.js +4 -5
- package/dist/task/plan-rounds.d.ts +17 -29
- package/dist/task/plan-rounds.js +21 -34
- package/dist/task/plan-session.d.ts +58 -72
- package/dist/task/plan-session.js +61 -83
- package/dist/task/probe-gaming.d.ts +28 -27
- package/dist/task/probe-gaming.js +0 -0
- package/dist/task/prohibition-probe.d.ts +14 -16
- package/dist/task/prompts.d.ts +3 -4
- package/dist/task/prompts.js +17 -26
- package/dist/task/qa-transcript.d.ts +15 -22
- package/dist/task/qa-transcript.js +15 -21
- package/dist/task/question-box.d.ts +17 -13
- package/dist/task/question-box.js +19 -15
- package/dist/task/question-dedup.d.ts +6 -7
- package/dist/task/question-dedup.js +13 -14
- package/dist/task/question-dialog.d.ts +22 -32
- package/dist/task/question-dialog.js +22 -32
- package/dist/task/question-source.d.ts +18 -44
- package/dist/task/question-source.js +22 -51
- package/dist/task/refuted-constraint.d.ts +11 -31
- package/dist/task/refuted-constraint.js +27 -51
- package/dist/task/regenerable-artifacts.d.ts +12 -31
- package/dist/task/regenerable-artifacts.js +12 -31
- package/dist/task/render-check.d.ts +11 -22
- package/dist/task/render-check.js +33 -46
- package/dist/task/repo-health-check.d.ts +10 -14
- package/dist/task/repo-health-check.js +17 -23
- package/dist/task/requirements.d.ts +38 -71
- package/dist/task/requirements.js +78 -126
- package/dist/task/research-fanout-budget.d.ts +51 -88
- package/dist/task/research-fanout-budget.js +51 -88
- package/dist/task/research-worker.d.ts +33 -36
- package/dist/task/research-worker.js +39 -61
- package/dist/task/resume-gap.d.ts +14 -15
- package/dist/task/root-cause-repair.d.ts +9 -9
- package/dist/task/root-cause-repair.js +28 -40
- package/dist/task/run-bracket.d.ts +10 -13
- package/dist/task/run-end.d.ts +12 -22
- package/dist/task/run-end.js +8 -16
- package/dist/task/run-final-gate.d.ts +19 -21
- package/dist/task/run-final-gate.js +62 -80
- package/dist/task/runner-globs.d.ts +12 -13
- package/dist/task/runner-globs.js +12 -13
- package/dist/task/runner-resolve.d.ts +9 -9
- package/dist/task/runner-resolve.js +22 -23
- package/dist/task/script-escape.d.ts +10 -12
- package/dist/task/script-escape.js +13 -14
- package/dist/task/serve-entry.d.ts +1 -1
- package/dist/task/serve-entry.js +22 -25
- package/dist/task/service-blocks.js +4 -2
- package/dist/task/shipped-source.d.ts +11 -29
- package/dist/task/shipped-source.js +11 -29
- package/dist/task/skip-escape.js +10 -14
- package/dist/task/spec-urls.d.ts +26 -65
- package/dist/task/spec-urls.js +26 -65
- package/dist/task/spec-validation.d.ts +17 -20
- package/dist/task/spec-validation.js +17 -20
- package/dist/task/stall-detector.d.ts +23 -30
- package/dist/task/stall-detector.js +23 -30
- package/dist/task/stream-watchdog.d.ts +14 -12
- package/dist/task/stream-watchdog.js +14 -12
- package/dist/task/substitution-probe.d.ts +17 -20
- package/dist/task/substitution-probe.js +17 -20
- package/dist/task/task-gates.d.ts +36 -41
- package/dist/task/task-gates.js +95 -106
- package/dist/task/task-io.d.ts +4 -4
- package/dist/task/task-io.js +4 -4
- package/dist/task/task-parsers.js +4 -3
- package/dist/task/task-provenance.d.ts +2 -2
- package/dist/task/task-provenance.js +11 -13
- package/dist/task/task-types.d.ts +4 -3
- package/dist/task/terminal-outcome.d.ts +14 -16
- package/dist/task/terminal-outcome.js +12 -14
- package/dist/task/test-assembly.d.ts +13 -20
- package/dist/task/test-assembly.js +13 -20
- package/dist/task/timings.d.ts +5 -3
- package/dist/task/timings.js +5 -3
- package/dist/task/title-label.d.ts +9 -4
- package/dist/task/title-label.js +9 -4
- package/dist/task/type-only-answer.d.ts +44 -52
- package/dist/task/type-only-answer.js +44 -52
- package/dist/task/unfailable-command.d.ts +18 -24
- package/dist/task/unfailable-command.js +21 -27
- package/dist/task/unknown-routing.d.ts +10 -4
- package/dist/task/unknown-routing.js +10 -4
- package/dist/task/user-directives.d.ts +5 -8
- package/dist/task/user-directives.js +5 -8
- package/dist/task/verify-quality.d.ts +18 -22
- package/dist/task/verify-quality.js +45 -46
- package/dist/task/verify-reconcile.d.ts +15 -10
- package/dist/task/verify-reconcile.js +45 -43
- package/dist/task/verify-resolution.d.ts +24 -20
- package/dist/task/verify-resolution.js +51 -50
- package/dist/task/verify-work.d.ts +59 -66
- package/dist/task/verify-work.js +101 -138
- package/dist/task/widget.d.ts +15 -14
- package/dist/task/widget.js +22 -17
- package/dist/task/wiring-claims.d.ts +25 -32
- package/dist/task/wiring-claims.js +30 -35
- package/dist/task/write-guard.d.ts +39 -39
- package/dist/task/write-guard.js +48 -51
- package/dist/task/yolo.d.ts +34 -30
- package/dist/task/yolo.js +42 -37
- package/dist/workers/abstention.d.ts +21 -41
- package/dist/workers/abstention.js +27 -48
- package/dist/workers/brave-search.d.ts +4 -3
- package/dist/workers/brave-search.js +5 -2
- package/dist/workers/brave-warning.d.ts +7 -4
- package/dist/workers/brave-warning.js +19 -7
- package/dist/workers/ddg-search.d.ts +6 -6
- package/dist/workers/ddg-search.js +18 -12
- package/dist/workers/docs-cache.js +5 -2
- package/dist/workers/docs-chunk.d.ts +30 -37
- package/dist/workers/docs-chunk.js +37 -41
- package/dist/workers/docs-core.d.ts +28 -44
- package/dist/workers/docs-core.js +25 -44
- package/dist/workers/docs-index.js +4 -3
- package/dist/workers/docs-lookup.d.ts +15 -22
- package/dist/workers/docs-lookup.js +12 -21
- package/dist/workers/docs-project.d.ts +15 -9
- package/dist/workers/docs-project.js +17 -10
- package/dist/workers/docs-resolve.d.ts +19 -20
- package/dist/workers/docs-resolve.js +35 -32
- package/dist/workers/docs-retrieve.d.ts +5 -6
- package/dist/workers/docs-retrieve.js +18 -15
- package/dist/workers/exa-search.d.ts +9 -6
- package/dist/workers/exa-search.js +23 -12
- package/dist/workers/fetch-core.d.ts +13 -16
- package/dist/workers/fetch-core.js +23 -23
- package/dist/workers/focused-extractor.d.ts +12 -12
- package/dist/workers/focused-extractor.js +16 -19
- package/dist/workers/html-clean.js +24 -14
- package/dist/workers/http-request.d.ts +28 -20
- package/dist/workers/http-request.js +22 -17
- package/dist/workers/npm-version.d.ts +28 -11
- package/dist/workers/npm-version.js +24 -15
- package/dist/workers/phantom-imports.d.ts +15 -12
- package/dist/workers/phantom-imports.js +30 -24
- package/dist/workers/pi-worker-core.d.ts +86 -54
- package/dist/workers/pi-worker-core.js +112 -112
- package/dist/workers/pi-worker-docs.d.ts +24 -19
- package/dist/workers/pi-worker-docs.js +67 -76
- package/dist/workers/pi-worker-fetch.d.ts +7 -3
- package/dist/workers/pi-worker-fetch.js +27 -19
- package/dist/workers/pi-worker-search.js +12 -8
- package/dist/workers/pi-worker.d.ts +9 -4
- package/dist/workers/pi-worker.js +23 -10
- package/dist/workers/reasoning-warning.d.ts +18 -17
- package/dist/workers/reasoning-warning.js +22 -20
- package/dist/workers/research-cache.js +50 -78
- package/dist/workers/search-core.js +7 -5
- package/dist/workers/search-types.d.ts +10 -9
- package/dist/workers/search-types.js +9 -8
- package/dist/workers/session-hint.d.ts +13 -14
- package/dist/workers/session-hint.js +8 -9
- package/dist/workers/shared.d.ts +21 -25
- package/dist/workers/shared.js +0 -0
- package/dist/workers/single-read-extension.d.ts +14 -7
- package/dist/workers/single-read-extension.js +14 -7
- package/dist/workers/single-read-guard.d.ts +25 -28
- package/dist/workers/single-read-guard.js +32 -32
- package/dist/workers/typeonly-log.d.ts +12 -9
- package/dist/workers/typeonly-log.js +29 -33
- package/dist/workers/worker-channels.d.ts +15 -23
- package/dist/workers/worker-channels.js +15 -23
- package/dist/workers/worker-failure.d.ts +38 -46
- package/dist/workers/worker-failure.js +31 -39
- package/dist/workers/worker-kill.d.ts +25 -26
- package/dist/workers/worker-kill.js +16 -19
- package/dist/workers/worker-profiles.d.ts +43 -53
- package/dist/workers/worker-profiles.js +30 -38
- package/package.json +10 -8
package/dist/task/env-notes.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* env-notes — a per-run cache of ENVIRONMENT FACTS shared across gate children.
|
|
3
3
|
*
|
|
4
|
-
* The failure this serves
|
|
4
|
+
* The failure this serves: every gate child re-discovers the
|
|
5
5
|
* same environment facts from scratch — where the DB credentials live, which
|
|
6
6
|
* services are reachable, which tools are installed — burning minutes of
|
|
7
7
|
* archaeology per child through the serial model bottleneck.
|
|
@@ -19,18 +19,21 @@
|
|
|
19
19
|
* defect") still governs every verdict — the block injected into prompts says
|
|
20
20
|
* so explicitly. The cache only kills re-discovery time.
|
|
21
21
|
*
|
|
22
|
-
* PROVENANCE + RE-VALIDATION
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
22
|
+
* PROVENANCE + RE-VALIDATION. A shared cache has a failure mode a per-child one
|
|
23
|
+
* does not: a WRONG fact propagates. The shape to fear is a verify child grepping
|
|
24
|
+
* component names in a MINIFIED bundle — identifiers there are mangled, so zero
|
|
25
|
+
* hits is guaranteed regardless of the truth — concluding "the build tree-shakes
|
|
26
|
+
* all route components, pre-existing issue", and every later task inheriting that
|
|
27
|
+
* verbatim as a standing excuse to wave off a genuinely broken deliverable.
|
|
28
|
+
* Nobody re-checks a fact that is already written down.
|
|
29
|
+
*
|
|
30
|
+
* Two guards close it. (a) Each note is stamped host-side with the ORIGIN task
|
|
31
|
+
* that recorded it, so it reads as second-hand hearsay rather than the reader's
|
|
32
|
+
* own observation. (b) The injected block demands the reader RE-VALIDATE a note
|
|
33
|
+
* in the CURRENT tree before citing it to excuse a failure, marks EXCUSE-CLASS
|
|
34
|
+
* notes for exactly that scrutiny, and states outright that a zero-hit grep of a
|
|
35
|
+
* generated artifact is not evidence of absence. Provenance is mechanical;
|
|
36
|
+
* re-validation is prompt-level.
|
|
34
37
|
*/
|
|
35
38
|
import { makeLedger } from './ledger.js';
|
|
36
39
|
const ENV_NOTES_FILE = 'env-notes.md';
|
|
@@ -45,8 +48,10 @@ const MAX_NOTE_LENGTH = 240;
|
|
|
45
48
|
*/
|
|
46
49
|
const ORIGIN_SEP = '\t';
|
|
47
50
|
/**
|
|
48
|
-
* Parse the stored file into fact+origin records.
|
|
49
|
-
*
|
|
51
|
+
* Parse the stored file into fact+origin records. A line with no separator parses
|
|
52
|
+
* with an empty origin rather than being dropped, so a cache written before
|
|
53
|
+
* provenance existed still reads — and `buildEnvNotesBlock` renders those as
|
|
54
|
+
* "origin unrecorded" instead of silently claiming an author.
|
|
50
55
|
*/
|
|
51
56
|
export function parseEnvNotes(raw) {
|
|
52
57
|
const out = [];
|
|
@@ -82,8 +87,10 @@ export async function readEnvNotes(cwd) {
|
|
|
82
87
|
return ledger.readRaw(cwd);
|
|
83
88
|
}
|
|
84
89
|
/**
|
|
85
|
-
* Pull `ENV-NOTE: <fact>` lines out of a child's answer text
|
|
86
|
-
*
|
|
90
|
+
* Pull `ENV-NOTE: <fact>` lines out of a child's answer text: trimmed,
|
|
91
|
+
* deduplicated case-insensitively, and dropped when empty or over
|
|
92
|
+
* MAX_NOTE_LENGTH. Run: a `VERDICT:` line and even a near-miss `ENV-NOTES:` line
|
|
93
|
+
* match nothing, so a verdict cannot leak into the fact cache.
|
|
87
94
|
*/
|
|
88
95
|
export function extractEnvNotes(text) {
|
|
89
96
|
const notes = [];
|
|
@@ -101,17 +108,22 @@ export function extractEnvNotes(text) {
|
|
|
101
108
|
return notes;
|
|
102
109
|
}
|
|
103
110
|
/**
|
|
104
|
-
* EXCUSE-CLASS wording: a note that waves a problem off as someone else's or a
|
|
105
|
-
* prior condition
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
111
|
+
* EXCUSE-CLASS wording: a note that waves a problem off as someone else's or as a
|
|
112
|
+
* prior condition. These are the notes that propagate across slices as standing
|
|
113
|
+
* excuses, and the ones most likely to be masking a real defect rather than
|
|
114
|
+
* describing the environment.
|
|
115
|
+
*
|
|
116
|
+
* Pure text, stack-agnostic. The flag never drops or fails a note — it only marks
|
|
117
|
+
* it as needing live re-validation before it may EXCUSE a failure, so a false
|
|
118
|
+
* positive is harmless: a benign fact re-validates and is used, and the marker
|
|
119
|
+
* only bites a citation-to-wave-off.
|
|
120
|
+
*
|
|
121
|
+
* Run against the shapes it has to separate: "unrelated to this task",
|
|
122
|
+
* "tree-shaken by the build", "pre-existing mismatch in the schema", "not
|
|
123
|
+
* applicable here" and "affects all routes" all flag, while the benign status
|
|
124
|
+
* fact "5 pre-existing warnings" does NOT — a "pre-existing" match needs a
|
|
125
|
+
* co-located problem word — and neither do ordinary facts like "postgres
|
|
126
|
+
* reachable on 5432".
|
|
115
127
|
*/
|
|
116
128
|
const EXCUSE_PATTERNS = [
|
|
117
129
|
/\bunrelated\b/i,
|
|
@@ -130,9 +142,14 @@ export function isExcuseNote(fact) {
|
|
|
130
142
|
/**
|
|
131
143
|
* Append newly discovered facts to the cache, deduplicated against what is
|
|
132
144
|
* already there (case-insensitive fact match), keeping the newest MAX_NOTES.
|
|
133
|
-
* Each new fact is stamped with the `origin` task that recorded it; a fact
|
|
134
|
-
*
|
|
135
|
-
* established it
|
|
145
|
+
* Each new fact is stamped with the `origin` task that recorded it; a fact already
|
|
146
|
+
* present keeps its ORIGINAL origin, so provenance traces to whoever first
|
|
147
|
+
* established it. Confirmed by re-appending the same fact under a different task:
|
|
148
|
+
* one entry survives, still carrying the first writer.
|
|
149
|
+
*
|
|
150
|
+
* Tabs in an emitted fact are normalised to spaces before storage, which is what
|
|
151
|
+
* keeps the separator unambiguous. The cap holds too — sixty further facts leave
|
|
152
|
+
* MAX_NOTES stored. Failures are swallowed: the cache is a sharpener, never a
|
|
136
153
|
* blocker.
|
|
137
154
|
*/
|
|
138
155
|
export async function appendEnvNotes(cwd, notes, origin = '') {
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* entry is a name no `.env.example` is expected to carry. */
|
|
3
3
|
export declare const AMBIENT_ENV: Set<string>;
|
|
4
4
|
/** The same rule by MECHANISM rather than by name: a variable INJECTED by a
|
|
5
|
-
* platform
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* platform — a CI runner, a package manager, freedesktop base dirs. `GITHUB_ENV`,
|
|
6
|
+
* `npm_execpath` and `XDG_CACHE_HOME` all read as "required" to a naive scan in
|
|
7
|
+
* real trees, and a template that declared any of them would be wrong. So the
|
|
8
|
+
* exclusion is the PREFIX, not a list of names that would have to keep growing. */
|
|
9
9
|
export declare const AMBIENT_PREFIXES: string[];
|
|
10
10
|
/** Rule 4: is this variable the platform's to supply? */
|
|
11
11
|
export declare function isAmbient(name: string): boolean;
|
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* env-template-closure — a shipped source file requires an env var the shipped
|
|
3
|
-
* template never mentions
|
|
3
|
+
* template never mentions.
|
|
4
4
|
*
|
|
5
|
-
* The failure this closes
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* a separate artifact nobody
|
|
5
|
+
* The failure this closes: a seed script reads `process.env.ADMIN_PHONE` and
|
|
6
|
+
* `ADMIN_PASSWORD` with no default while the tracked `.env.example` declares only
|
|
7
|
+
* `DATABASE_URL` and `APP_URL`. The seed command then exits 1, and an autofix
|
|
8
|
+
* "resolves" it by writing the two vars into `.env` — which is GITIGNORED, so the
|
|
9
|
+
* COMMITTED tree still cannot seed and nothing at run end says why.
|
|
10
|
+
*
|
|
11
|
+
* Coverage cannot see it: it credits the CONSUMING side, because the script exists,
|
|
12
|
+
* is owned, and passes its own VERIFY. The template is a separate artifact nobody
|
|
13
|
+
* re-reads after the task that wrote it.
|
|
14
|
+
*
|
|
15
|
+
* That exact shape, run against a real repo, produces the two findings and no
|
|
16
|
+
* others — `DATABASE_URL` is declared and stays silent.
|
|
13
17
|
*
|
|
14
18
|
* THE RULE. Every REQUIRED env read in TRACKED source must appear in the TRACKED
|
|
15
19
|
* env template. One-directional: a variable DECLARED but never read is silence, not
|
|
16
|
-
* a finding
|
|
20
|
+
* a finding — a template carrying entries nothing reads yields zero findings, which
|
|
21
|
+
* is what keeps a deliberately over-declared template clean.
|
|
17
22
|
*
|
|
18
23
|
* REQUIRED is mechanical. A read steps aside when it:
|
|
19
24
|
* 1. carries a default — `?? …`, `|| …`, `os.getenv('X', d)`, `environ.get('X', d)`;
|
|
20
25
|
* 2. is compared, not consumed — `===`, `!==`, `==`, `!=` on either side;
|
|
21
26
|
* 3. is an assignment TARGET — `process.env.DATABASE_URL = testDbUrl`, which is
|
|
22
|
-
* what
|
|
23
|
-
*
|
|
27
|
+
* what a test file typically does, and is the readiest source of false
|
|
28
|
+
* positives;
|
|
24
29
|
* 4. names an AMBIENT variable — a short fixed allowlist (below) of things the
|
|
25
30
|
* platform, not the project, supplies.
|
|
26
31
|
*
|
|
@@ -32,14 +37,19 @@
|
|
|
32
37
|
* untracked scratch file can neither declare nor require anything.
|
|
33
38
|
* • generated/vendored trees (`dist/`, `build/`, `node_modules/`, …) are not
|
|
34
39
|
* authored source and are skipped; they only ever mirror a read we already saw.
|
|
35
|
-
* • NO TEMPLATE IN THE TREE ⇒ THE CHECK IS INERT
|
|
36
|
-
*
|
|
37
|
-
* not
|
|
40
|
+
* • NO TEMPLATE IN THE TREE ⇒ THE CHECK IS INERT, the way `repo-health-check`
|
|
41
|
+
* treats a missing manifest. Confirmed: a repo with a required read and no
|
|
42
|
+
* template at all yields zero findings, and so does a directory that is not a
|
|
43
|
+
* git repo. This must never invent a file the project chose not to have.
|
|
44
|
+
*
|
|
45
|
+
* Not npm-shaped: JS/TS (`process.env` / `Bun.env`), Python (`os.environ[…]`,
|
|
46
|
+
* `os.environ.get`, `os.getenv`) and Go (`os.Getenv`) all read the same way. Go's
|
|
47
|
+
* `os.LookupEnv` is the explicit may-be-absent API and gets its own step-aside,
|
|
48
|
+
* `optional-api`.
|
|
38
49
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* `os.
|
|
42
|
-
* explicit may-be-absent API and is treated as its own step-aside.
|
|
50
|
+
* Every rule above was run: each of the four step-asides fires with its own label,
|
|
51
|
+
* comparison is caught on either side, all three languages produce a REQUIRED read,
|
|
52
|
+
* `os.LookupEnv` steps aside, and both dynamic forms extract nothing at all.
|
|
43
53
|
*/
|
|
44
54
|
import { spawnSync } from 'node:child_process';
|
|
45
55
|
import { readFileSync } from 'node:fs';
|
|
@@ -58,9 +68,8 @@ export const AMBIENT_ENV = new Set([
|
|
|
58
68
|
'TMPDIR',
|
|
59
69
|
'LANG',
|
|
60
70
|
// Windows/OS equivalents of the above, and the package manager's own vars —
|
|
61
|
-
// every one of these
|
|
62
|
-
//
|
|
63
|
-
// `XDG_CACHE_HOME`), and none of them belongs in a project's template.
|
|
71
|
+
// every one of these reads as "required" to a naive scan (`npm_execpath`,
|
|
72
|
+
// `LOCALAPPDATA`, `XDG_CACHE_HOME`), and none belongs in a project's template.
|
|
64
73
|
'APPDATA',
|
|
65
74
|
'LOCALAPPDATA',
|
|
66
75
|
'USERPROFILE',
|
|
@@ -73,10 +82,10 @@ export const AMBIENT_ENV = new Set([
|
|
|
73
82
|
'COMSPEC'
|
|
74
83
|
]);
|
|
75
84
|
/** The same rule by MECHANISM rather than by name: a variable INJECTED by a
|
|
76
|
-
* platform
|
|
77
|
-
* `
|
|
78
|
-
*
|
|
79
|
-
*
|
|
85
|
+
* platform — a CI runner, a package manager, freedesktop base dirs. `GITHUB_ENV`,
|
|
86
|
+
* `npm_execpath` and `XDG_CACHE_HOME` all read as "required" to a naive scan in
|
|
87
|
+
* real trees, and a template that declared any of them would be wrong. So the
|
|
88
|
+
* exclusion is the PREFIX, not a list of names that would have to keep growing. */
|
|
80
89
|
export const AMBIENT_PREFIXES = ['npm_', 'GITHUB_', 'RUNNER_', 'CI_', 'XDG_', 'BUN_', 'NODE_'];
|
|
81
90
|
/** Rule 4: is this variable the platform's to supply? */
|
|
82
91
|
export function isAmbient(name) {
|
|
@@ -160,7 +169,7 @@ const MATCHERS = [
|
|
|
160
169
|
* that opens with one? (`process.env.X\n ?? 'y'` is one expression.)
|
|
161
170
|
*
|
|
162
171
|
* A ternary CONDITION counts: `process.env.npm_execpath ? a : b` names both
|
|
163
|
-
* outcomes, so nothing is required
|
|
172
|
+
* outcomes, so nothing is required. `?.` is
|
|
164
173
|
* optional chaining, not a ternary, and must not match. */
|
|
165
174
|
function hasDefault(before, after, nextLine) {
|
|
166
175
|
// The read IS the fallback: `X ?? process.env.BRAVE_API_KEY` (brave-warning.ts)
|
|
@@ -183,14 +192,14 @@ function hasDefault(before, after, nextLine) {
|
|
|
183
192
|
* `if (c) …` Playwright cache when unset
|
|
184
193
|
*
|
|
185
194
|
* The discriminator is the SIGN of the guard, and it is exactly what separates
|
|
186
|
-
* those from the lead:
|
|
195
|
+
* those from the lead: a seed script writes `const phone = process.env.ADMIN_PHONE`
|
|
187
196
|
* … `if (!phone) throw`. A NEGATED guard means the variable is required and the
|
|
188
197
|
* program stops without it; a POSITIVE guard means it is an override. So a bare
|
|
189
198
|
* `if (` / `while (` head steps aside, `if (!` does not, and an assign-then-guard
|
|
190
199
|
* is resolved by looking ahead for the FIRST guard on that variable.
|
|
191
200
|
*/
|
|
192
201
|
const GUARD_HEAD_RE = /\b(?:if|while)\s*\(\s*$/;
|
|
193
|
-
/** How far an assign-then-guard may reach.
|
|
202
|
+
/** How far an assign-then-guard may reach. A few lines is typical; 10 is slack. */
|
|
194
203
|
const GUARD_LOOKAHEAD = 10;
|
|
195
204
|
function isProbeHead(before) {
|
|
196
205
|
return GUARD_HEAD_RE.test(before);
|
|
@@ -202,7 +211,7 @@ function assignedTo(before) {
|
|
|
202
211
|
}
|
|
203
212
|
/**
|
|
204
213
|
* What the guard's own body does. A NEGATED guard only means "required" when the
|
|
205
|
-
* program STOPS without the variable — `if (!phone) throw
|
|
214
|
+
* program STOPS without the variable — `if (!phone) throw`. When
|
|
206
215
|
* it merely returns or falls through — `if (!process.env.PI_REMOTE_PUSH_DEBUG)
|
|
207
216
|
* return` (push.ts, a debug flag) — the variable is optional and the negation
|
|
208
217
|
* proves nothing. Same syntax, opposite meaning; the body is the discriminator.
|
|
@@ -243,7 +252,7 @@ function locallySupplied(text, name) {
|
|
|
243
252
|
* it as an override, so every read of it in that file is a probe. Without this,
|
|
244
253
|
* the CONSUMING read inside the guarded branch — `if (process.env.PI_BIN) return
|
|
245
254
|
* {command: process.env.PI_BIN}` (pi-invocation.ts), `process.env.GOFER_PYTHON ?
|
|
246
|
-
* [process.env.
|
|
255
|
+
* [process.env.PYTHON_BIN] : [...]` — reads as required. */
|
|
247
256
|
function locallyProbed(text, name) {
|
|
248
257
|
const e = `(?:process|Bun)\\.env\\s*\\.\\s*${name}`;
|
|
249
258
|
return (new RegExp(`\\b(?:if|while)\\s*\\(\\s*${e}\\b`).test(text)
|
|
@@ -260,7 +269,7 @@ function isCompared(before, after) {
|
|
|
260
269
|
}
|
|
261
270
|
/** Rule 3: the read is a WRITE — `process.env.X = …` (but not `==`/`===`), or
|
|
262
271
|
* `delete process.env.X`. Both mean the file SUPPLIES the variable rather than
|
|
263
|
-
* consuming it;
|
|
272
|
+
* consuming it; a suite of test files is the assignment case and a
|
|
264
273
|
* `wdio.packaged.conf.ts` (`delete process.env.GOFER_GDFORMAT`) is the delete
|
|
265
274
|
* case — a scrub of a developer override, the opposite of a requirement. */
|
|
266
275
|
function isAssigned(before, after) {
|
|
@@ -290,8 +299,7 @@ export function scanSource(file, text) {
|
|
|
290
299
|
// the RESULT is seen (`os.Getenv("X") == ""`).
|
|
291
300
|
const after = matcher.call ? raw.replace(/^\s*\)/, '') : raw;
|
|
292
301
|
// …and past any WRAPPING call's brackets, so `Number(process.env.X)
|
|
293
|
-
// || 32`
|
|
294
|
-
// found) reads as defaulted. Stepping aside when the `||` in fact
|
|
302
|
+
// || 32` — the largest false-positive class — reads as defaulted. Stepping aside when the `||` in fact
|
|
295
303
|
// defaults an enclosing expression is a false NEGATIVE, which this
|
|
296
304
|
// check spends freely; a false rank-0 gate failure it does not.
|
|
297
305
|
// …and past a trailing accessor chain, so `process.env.X?.trim() ||
|
|
@@ -8,16 +8,19 @@
|
|
|
8
8
|
* from the four research workers. `enrichment.ts` stays a pure parser; the I/O
|
|
9
9
|
* lives here.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* handling, the
|
|
17
|
-
*
|
|
18
|
-
* {@link ExternalContextPolicy},
|
|
19
|
-
* {@link ExternalContextLookups}
|
|
20
|
-
* focused-extractor seam
|
|
11
|
+
* TWO call paths share this assembly: the research phase via
|
|
12
|
+
* {@link gatherExternalContext} (raw workers) and the grill auto-answer via
|
|
13
|
+
* {@link buildExternalContext} directly (focused workers). Everything that shows
|
|
14
|
+
* up in the OUTPUT is identical between them — the "npm blocks lead" ordering, the
|
|
15
|
+
* `### docs:` / `### url:` headings, the service loop's `no_key` / `error`
|
|
16
|
+
* handling, the trailing blank-line terminator — and they differ only on POLICY.
|
|
17
|
+
*
|
|
18
|
+
* So the shape lives here once, the differences are {@link ExternalContextPolicy},
|
|
19
|
+
* and the raw-vs-focused worker choice is {@link ExternalContextLookups}, an
|
|
20
|
+
* adapter the focused-extractor seam made expressible.
|
|
21
|
+
*
|
|
22
|
+
* Run against a mixed source, the emitted headings come out in exactly that order:
|
|
23
|
+
* `### npm:` then `### docs:` then `### url:` then `### service:`.
|
|
21
24
|
*/
|
|
22
25
|
import { type NpmVersionInfo } from '../workers/npm-version.js';
|
|
23
26
|
import type { SearchCoreInput, SearchCoreResult } from '../workers/search-core.js';
|
|
@@ -48,8 +51,9 @@ export interface ExternalTargetResult {
|
|
|
48
51
|
* whole page markdown, truncated), `phaseAutoAnswer` binds the FOCUSED ones (a
|
|
49
52
|
* child's one-question answer). Everything else about the block is identical.
|
|
50
53
|
*
|
|
51
|
-
* A rejected lookup is caught by the builder and yields no blocks for that
|
|
52
|
-
*
|
|
54
|
+
* A rejected lookup is caught by the builder and yields no blocks for that target,
|
|
55
|
+
* so adapters may throw freely. Confirmed: one adapter rejecting mid-fan-out
|
|
56
|
+
* leaves the other targets' blocks intact and contributes nothing of its own.
|
|
53
57
|
*/
|
|
54
58
|
export interface ExternalContextLookups {
|
|
55
59
|
docs(pkg: string): Promise<ExternalTargetResult | null>;
|
|
@@ -58,10 +62,11 @@ export interface ExternalContextLookups {
|
|
|
58
62
|
search?: (input: SearchCoreInput) => Promise<SearchCoreResult>;
|
|
59
63
|
}
|
|
60
64
|
/**
|
|
61
|
-
* The
|
|
62
|
-
* than a default, because every one
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
+
* The five places the two call paths genuinely disagree. Each is a knob rather
|
|
66
|
+
* than a default, because every one is a deliberate choice on at least one path:
|
|
67
|
+
* the auto-answer block is capped and records nothing because it runs per grill
|
|
68
|
+
* question, in front of a waiting user, while research is uncapped and trails its
|
|
69
|
+
* sub-step.
|
|
65
70
|
*/
|
|
66
71
|
export interface ExternalContextPolicy {
|
|
67
72
|
/**
|
|
@@ -74,9 +79,9 @@ export interface ExternalContextPolicy {
|
|
|
74
79
|
/**
|
|
75
80
|
* A cheap live version lookup for every named dep that did NOT get a docs
|
|
76
81
|
* target, so a version block exists for ALL of them. Omit to disable, as the
|
|
77
|
-
* auto-answer path does. Without
|
|
78
|
-
*
|
|
79
|
-
*
|
|
82
|
+
* auto-answer path does. Without it, any dep past the docs cap carries no live
|
|
83
|
+
* version at all, and a "which version?" question falls back to whatever the
|
|
84
|
+
* model remembers — which is how a dependency gets pinned to a stale major.
|
|
80
85
|
*/
|
|
81
86
|
versionLookup?: (pkg: string) => Promise<NpmVersionInfo | null>;
|
|
82
87
|
/** Sub-step label recorded via `deps.recordSubStep`. Omit to record nothing. */
|
|
@@ -89,8 +94,10 @@ export interface ExternalContextPolicy {
|
|
|
89
94
|
earlyReturnOnNoTargets?: boolean;
|
|
90
95
|
}
|
|
91
96
|
/**
|
|
92
|
-
* Assemble the `EXTERNAL CONTEXT\n…\n\n` block for `source`, or `''` when there
|
|
93
|
-
*
|
|
97
|
+
* Assemble the `EXTERNAL CONTEXT\n…\n\n` block for `source`, or `''` when there is
|
|
98
|
+
* nothing to enrich — no targets, or every lookup failed. Both were run: a source
|
|
99
|
+
* naming nothing returns `''`, and so does one whose only target is a service
|
|
100
|
+
* search that errored.
|
|
94
101
|
*/
|
|
95
102
|
export declare function buildExternalContext(source: string, deps: GatherDeps, lookups: ExternalContextLookups, policy?: ExternalContextPolicy): Promise<string>;
|
|
96
103
|
/**
|
|
@@ -8,16 +8,19 @@
|
|
|
8
8
|
* from the four research workers. `enrichment.ts` stays a pure parser; the I/O
|
|
9
9
|
* lives here.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* handling, the
|
|
17
|
-
*
|
|
18
|
-
* {@link ExternalContextPolicy},
|
|
19
|
-
* {@link ExternalContextLookups}
|
|
20
|
-
* focused-extractor seam
|
|
11
|
+
* TWO call paths share this assembly: the research phase via
|
|
12
|
+
* {@link gatherExternalContext} (raw workers) and the grill auto-answer via
|
|
13
|
+
* {@link buildExternalContext} directly (focused workers). Everything that shows
|
|
14
|
+
* up in the OUTPUT is identical between them — the "npm blocks lead" ordering, the
|
|
15
|
+
* `### docs:` / `### url:` headings, the service loop's `no_key` / `error`
|
|
16
|
+
* handling, the trailing blank-line terminator — and they differ only on POLICY.
|
|
17
|
+
*
|
|
18
|
+
* So the shape lives here once, the differences are {@link ExternalContextPolicy},
|
|
19
|
+
* and the raw-vs-focused worker choice is {@link ExternalContextLookups}, an
|
|
20
|
+
* adapter the focused-extractor seam made expressible.
|
|
21
|
+
*
|
|
22
|
+
* Run against a mixed source, the emitted headings come out in exactly that order:
|
|
23
|
+
* `### npm:` then `### docs:` then `### url:` then `### service:`.
|
|
21
24
|
*/
|
|
22
25
|
import { docsRaw } from '../workers/docs-core.js';
|
|
23
26
|
import { fetchRaw } from '../workers/fetch-core.js';
|
|
@@ -28,8 +31,10 @@ import { formatServiceBlock, formatFreshnessSkippedBlock } from './service-block
|
|
|
28
31
|
/** How much of a docs/url body survives into the block, for the raw-worker lookups. */
|
|
29
32
|
const RAW_BODY_LIMIT = 4000;
|
|
30
33
|
/**
|
|
31
|
-
* Assemble the `EXTERNAL CONTEXT\n…\n\n` block for `source`, or `''` when there
|
|
32
|
-
*
|
|
34
|
+
* Assemble the `EXTERNAL CONTEXT\n…\n\n` block for `source`, or `''` when there is
|
|
35
|
+
* nothing to enrich — no targets, or every lookup failed. Both were run: a source
|
|
36
|
+
* naming nothing returns `''`, and so does one whose only target is a service
|
|
37
|
+
* search that errored.
|
|
33
38
|
*/
|
|
34
39
|
export async function buildExternalContext(source, deps, lookups, policy = {}) {
|
|
35
40
|
const searchFn = lookups.search ?? defaultSearch;
|
|
@@ -13,11 +13,10 @@ export interface FailureClass {
|
|
|
13
13
|
}
|
|
14
14
|
export declare function classifyFailure(err: unknown, aborted: boolean): FailureClass;
|
|
15
15
|
/**
|
|
16
|
-
* Persist, flash and announce a failure
|
|
16
|
+
* Persist, flash and announce a failure, and return the classification.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* say `RunEnd` instead.
|
|
18
|
+
* `TaskRunner.run` builds its `RunEnd` from the returned `state` and `reason`.
|
|
19
|
+
* The front-matter write here is what a later resume reads, not the channel
|
|
20
|
+
* this process uses to learn how the run ended.
|
|
22
21
|
*/
|
|
23
22
|
export declare function handleFailure(err: unknown, ctx: ExtensionCommandContext, cwd: string, id: string, aborted: boolean): Promise<FailureClass>;
|
|
@@ -75,20 +75,19 @@ export function classifyFailure(err, aborted) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
* Persist, flash and announce a failure
|
|
78
|
+
* Persist, flash and announce a failure, and return the classification.
|
|
79
79
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* say `RunEnd` instead.
|
|
80
|
+
* `TaskRunner.run` builds its `RunEnd` from the returned `state` and `reason`.
|
|
81
|
+
* The front-matter write here is what a later resume reads, not the channel
|
|
82
|
+
* this process uses to learn how the run ended.
|
|
84
83
|
*/
|
|
85
84
|
export async function handleFailure(err, ctx, cwd, id, aborted) {
|
|
86
85
|
const c = classifyFailure(err, aborted);
|
|
87
86
|
await updateTaskFrontMatter(cwd, id, { state: c.state, reason: c.reason });
|
|
88
87
|
flashTerminalWidget(ctx, c.state, id, c.flash);
|
|
89
88
|
ctx.ui.notify(`${id} ${c.notify}`, c.level);
|
|
90
|
-
// Mirror to remote viewers
|
|
91
|
-
// the remote view shows nothing when a task fails.
|
|
89
|
+
// Mirror to remote viewers. `ctx.ui.notify` reaches the terminal UI only, so
|
|
90
|
+
// without this call the remote view shows nothing when a task fails.
|
|
92
91
|
publishLifecycleNotice(`${id} ${c.notify}`, c.level);
|
|
93
92
|
return c;
|
|
94
93
|
}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project file inventory —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Project file inventory — `git ls-files`, capped, with the task directory
|
|
3
|
+
* stripped. `phaseResearch` computes it once and puts it in the header every
|
|
4
|
+
* research worker gets; `refineExistingFilesBlock` also uses it to pick the
|
|
5
|
+
* paths orientation pre-reads.
|
|
6
|
+
*
|
|
7
|
+
* Returns '' on failure: a non-git tree exits 128, and a missing binary reaches
|
|
8
|
+
* `runChildDefault`'s `error` handler as exit 1. Both callers treat '' as "no
|
|
9
|
+
* inventory" and carry on.
|
|
6
10
|
*/
|
|
7
11
|
/**
|
|
8
|
-
* Drop the committed task directory from the inventory. `git ls-files` lists
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Drop the committed task directory from the inventory. `git ls-files` lists a
|
|
13
|
+
* TRACKED file even when `.gitignore` matches it — confirmed against a real
|
|
14
|
+
* repo where `.pi-tasks/` is both ignored and committed — so once tasks are
|
|
15
|
+
* committed they reach every research worker and feed orientation unless they
|
|
16
|
+
* are stripped here. This is the only filter on the inventory path.
|
|
17
|
+
*
|
|
18
|
+
* `git ls-files` prints forward slashes, so the prefix matches as written.
|
|
15
19
|
*/
|
|
16
20
|
export declare function stripTasksDir(raw: string): string;
|
|
17
21
|
/** Cap output to maxLines real (non-blank) paths; tag truncation when cut. */
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project file inventory —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Project file inventory — `git ls-files`, capped, with the task directory
|
|
3
|
+
* stripped. `phaseResearch` computes it once and puts it in the header every
|
|
4
|
+
* research worker gets; `refineExistingFilesBlock` also uses it to pick the
|
|
5
|
+
* paths orientation pre-reads.
|
|
6
|
+
*
|
|
7
|
+
* Returns '' on failure: a non-git tree exits 128, and a missing binary reaches
|
|
8
|
+
* `runChildDefault`'s `error` handler as exit 1. Both callers treat '' as "no
|
|
9
|
+
* inventory" and carry on.
|
|
6
10
|
*/
|
|
7
11
|
import { makeGit } from '../shared/git-runner.js';
|
|
8
12
|
import { TASKS_DIR_NAME } from './task-types.js';
|
|
9
13
|
const DEFAULT_MAX_LINES = 2000;
|
|
10
14
|
/**
|
|
11
|
-
* Drop the committed task directory from the inventory. `git ls-files` lists
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Drop the committed task directory from the inventory. `git ls-files` lists a
|
|
16
|
+
* TRACKED file even when `.gitignore` matches it — confirmed against a real
|
|
17
|
+
* repo where `.pi-tasks/` is both ignored and committed — so once tasks are
|
|
18
|
+
* committed they reach every research worker and feed orientation unless they
|
|
19
|
+
* are stripped here. This is the only filter on the inventory path.
|
|
20
|
+
*
|
|
21
|
+
* `git ls-files` prints forward slashes, so the prefix matches as written.
|
|
18
22
|
*/
|
|
19
23
|
export function stripTasksDir(raw) {
|
|
20
24
|
const prefix = `${TASKS_DIR_NAME}/`;
|
|
@@ -24,19 +28,18 @@ export function stripTasksDir(raw) {
|
|
|
24
28
|
.join('\n');
|
|
25
29
|
}
|
|
26
30
|
/**
|
|
27
|
-
* `git ls-files`, or '' on ANY failure — non-git tree, missing git, cancelled
|
|
28
|
-
*
|
|
29
|
-
*
|
|
31
|
+
* `git ls-files`, or '' on ANY failure — non-git tree, missing git, cancelled
|
|
32
|
+
* run. '' is the signal both callers branch on, so every unhappy path has to
|
|
33
|
+
* collapse to it.
|
|
30
34
|
*
|
|
31
|
-
* Runs on the shared GitRunner
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* retained child per invocation (GitHub issue #9).
|
|
35
|
+
* Runs on the shared GitRunner, whose child detaches its abort listener when it
|
|
36
|
+
* settles: one AbortController is shared across a whole run, so a listener left
|
|
37
|
+
* attached per call would retain each finished child.
|
|
35
38
|
*
|
|
36
|
-
* The `signal.aborted` check is what
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
39
|
+
* The `signal.aborted` check is what holds the contract on cancellation. A
|
|
40
|
+
* killed child closes with a null exit code and `runChild` reports `code ?? 0`,
|
|
41
|
+
* so without the check a cancelled run would return partial stdout as if the
|
|
42
|
+
* listing were complete.
|
|
40
43
|
*/
|
|
41
44
|
async function runGitLsFiles(cwd, signal) {
|
|
42
45
|
const git = makeGit(cwd, signal);
|