@vibe-agent-toolkit/cli 0.2.0-rc.10 → 0.2.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/bin/supervise-cli.d.ts +45 -0
- package/dist/bin/supervise-cli.d.ts.map +1 -0
- package/dist/bin/supervise-cli.js +83 -0
- package/dist/bin/supervise-cli.js.map +1 -0
- package/dist/bin/vat +94 -40
- package/dist/bin/vat.d.ts +15 -4
- package/dist/bin/vat.d.ts.map +1 -1
- package/dist/bin/vat.js +94 -40
- package/dist/bin/vat.js.map +1 -1
- package/dist/bin.js +21 -29
- package/dist/bin.js.map +1 -1
- package/dist/command-tree.d.ts +45 -0
- package/dist/command-tree.d.ts.map +1 -0
- package/dist/command-tree.js +60 -0
- package/dist/command-tree.js.map +1 -0
- package/dist/commands/agent/build-schema.d.ts +100 -0
- package/dist/commands/agent/build-schema.d.ts.map +1 -0
- package/dist/commands/agent/build-schema.js +32 -0
- package/dist/commands/agent/build-schema.js.map +1 -0
- package/dist/commands/agent/build.d.ts +1 -0
- package/dist/commands/agent/build.d.ts.map +1 -1
- package/dist/commands/agent/build.js +63 -33
- package/dist/commands/agent/build.js.map +1 -1
- package/dist/commands/agent/import-schema.d.ts +75 -0
- package/dist/commands/agent/import-schema.d.ts.map +1 -0
- package/dist/commands/agent/import-schema.js +25 -0
- package/dist/commands/agent/import-schema.js.map +1 -0
- package/dist/commands/agent/import.d.ts.map +1 -1
- package/dist/commands/agent/import.js +33 -27
- package/dist/commands/agent/import.js.map +1 -1
- package/dist/commands/agent/index.d.ts.map +1 -1
- package/dist/commands/agent/index.js +132 -37
- package/dist/commands/agent/index.js.map +1 -1
- package/dist/commands/agent/install-path.d.ts.map +1 -1
- package/dist/commands/agent/install-path.js +2 -1
- package/dist/commands/agent/install-path.js.map +1 -1
- package/dist/commands/agent/install-schema.d.ts +89 -0
- package/dist/commands/agent/install-schema.d.ts.map +1 -0
- package/dist/commands/agent/install-schema.js +29 -0
- package/dist/commands/agent/install-schema.js.map +1 -0
- package/dist/commands/agent/install.d.ts +7 -1
- package/dist/commands/agent/install.d.ts.map +1 -1
- package/dist/commands/agent/install.js +78 -108
- package/dist/commands/agent/install.js.map +1 -1
- package/dist/commands/agent/installed-schema.d.ts +140 -0
- package/dist/commands/agent/installed-schema.d.ts.map +1 -0
- package/dist/commands/agent/installed-schema.js +36 -0
- package/dist/commands/agent/installed-schema.js.map +1 -0
- package/dist/commands/agent/installed.d.ts +1 -1
- package/dist/commands/agent/installed.d.ts.map +1 -1
- package/dist/commands/agent/installed.js +104 -75
- package/dist/commands/agent/installed.js.map +1 -1
- package/dist/commands/agent/list-schema.d.ts +128 -0
- package/dist/commands/agent/list-schema.d.ts.map +1 -0
- package/dist/commands/agent/list-schema.js +34 -0
- package/dist/commands/agent/list-schema.js.map +1 -0
- package/dist/commands/agent/list.d.ts +4 -3
- package/dist/commands/agent/list.d.ts.map +1 -1
- package/dist/commands/agent/list.js +50 -37
- package/dist/commands/agent/list.js.map +1 -1
- package/dist/commands/agent/run.d.ts +3 -0
- package/dist/commands/agent/run.d.ts.map +1 -1
- package/dist/commands/agent/run.js +8 -3
- package/dist/commands/agent/run.js.map +1 -1
- package/dist/commands/agent/uninstall-schema.d.ts +89 -0
- package/dist/commands/agent/uninstall-schema.d.ts.map +1 -0
- package/dist/commands/agent/uninstall-schema.js +29 -0
- package/dist/commands/agent/uninstall-schema.js.map +1 -0
- package/dist/commands/agent/uninstall.d.ts +5 -1
- package/dist/commands/agent/uninstall.d.ts.map +1 -1
- package/dist/commands/agent/uninstall.js +50 -38
- package/dist/commands/agent/uninstall.js.map +1 -1
- package/dist/commands/agent/validate-schema.d.ts +129 -0
- package/dist/commands/agent/validate-schema.d.ts.map +1 -0
- package/dist/commands/agent/validate-schema.js +35 -0
- package/dist/commands/agent/validate-schema.js.map +1 -0
- package/dist/commands/agent/validate.d.ts +6 -0
- package/dist/commands/agent/validate.d.ts.map +1 -1
- package/dist/commands/agent/validate.js +64 -36
- package/dist/commands/agent/validate.js.map +1 -1
- package/dist/commands/ard/emit-schema.d.ts +108 -0
- package/dist/commands/ard/emit-schema.d.ts.map +1 -0
- package/dist/commands/ard/emit-schema.js +37 -0
- package/dist/commands/ard/emit-schema.js.map +1 -0
- package/dist/commands/ard/emit.d.ts +31 -63
- package/dist/commands/ard/emit.d.ts.map +1 -1
- package/dist/commands/ard/emit.js +124 -68
- package/dist/commands/ard/emit.js.map +1 -1
- package/dist/commands/ard/index.d.ts.map +1 -1
- package/dist/commands/ard/index.js +17 -10
- package/dist/commands/ard/index.js.map +1 -1
- package/dist/commands/audit/compat-lane-findings.d.ts +65 -0
- package/dist/commands/audit/compat-lane-findings.d.ts.map +1 -0
- package/dist/commands/audit/compat-lane-findings.js +72 -0
- package/dist/commands/audit/compat-lane-findings.js.map +1 -0
- package/dist/commands/audit/distributed-tree.d.ts +2 -2
- package/dist/commands/audit/distributed-tree.d.ts.map +1 -1
- package/dist/commands/audit/distributed-tree.js +23 -12
- package/dist/commands/audit/distributed-tree.js.map +1 -1
- package/dist/commands/audit/git-url-clone.d.ts +15 -7
- package/dist/commands/audit/git-url-clone.d.ts.map +1 -1
- package/dist/commands/audit/git-url-clone.js +85 -42
- package/dist/commands/audit/git-url-clone.js.map +1 -1
- package/dist/commands/audit/hierarchical-output.d.ts +28 -4
- package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
- package/dist/commands/audit/hierarchical-output.js +44 -27
- package/dist/commands/audit/hierarchical-output.js.map +1 -1
- package/dist/commands/audit/scan-population.d.ts.map +1 -1
- package/dist/commands/audit/scan-population.js +2 -1
- package/dist/commands/audit/scan-population.js.map +1 -1
- package/dist/commands/audit-schema.d.ts +1247 -0
- package/dist/commands/audit-schema.d.ts.map +1 -0
- package/dist/commands/audit-schema.js +139 -0
- package/dist/commands/audit-schema.js.map +1 -0
- package/dist/commands/audit-settings-schema.d.ts +417 -0
- package/dist/commands/audit-settings-schema.d.ts.map +1 -0
- package/dist/commands/audit-settings-schema.js +77 -0
- package/dist/commands/audit-settings-schema.js.map +1 -0
- package/dist/commands/audit-settings.d.ts +28 -9
- package/dist/commands/audit-settings.d.ts.map +1 -1
- package/dist/commands/audit-settings.js +215 -151
- package/dist/commands/audit-settings.js.map +1 -1
- package/dist/commands/audit.d.ts +72 -33
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +415 -397
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/build.d.ts +61 -4
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +176 -190
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/cache/clear-schema.d.ts +111 -0
- package/dist/commands/cache/clear-schema.d.ts.map +1 -0
- package/dist/commands/cache/clear-schema.js +37 -0
- package/dist/commands/cache/clear-schema.js.map +1 -0
- package/dist/commands/cache/clear.d.ts +28 -26
- package/dist/commands/cache/clear.d.ts.map +1 -1
- package/dist/commands/cache/clear.js +108 -103
- package/dist/commands/cache/clear.js.map +1 -1
- package/dist/commands/cache/index.d.ts.map +1 -1
- package/dist/commands/cache/index.js +13 -7
- package/dist/commands/cache/index.js.map +1 -1
- package/dist/commands/claude/claude-config.d.ts +23 -6
- package/dist/commands/claude/claude-config.d.ts.map +1 -1
- package/dist/commands/claude/claude-config.js +29 -15
- package/dist/commands/claude/claude-config.js.map +1 -1
- package/dist/commands/claude/context.d.ts +87 -2
- package/dist/commands/claude/context.d.ts.map +1 -1
- package/dist/commands/claude/context.js +116 -57
- package/dist/commands/claude/context.js.map +1 -1
- package/dist/commands/claude/marketplace/changelog-utils.js +2 -2
- package/dist/commands/claude/marketplace/changelog-utils.js.map +1 -1
- package/dist/commands/claude/marketplace/git-publish.d.ts +14 -1
- package/dist/commands/claude/marketplace/git-publish.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/git-publish.js +135 -68
- package/dist/commands/claude/marketplace/git-publish.js.map +1 -1
- package/dist/commands/claude/marketplace/license-utils.d.ts +3 -5
- package/dist/commands/claude/marketplace/license-utils.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/license-utils.js +16 -7
- package/dist/commands/claude/marketplace/license-utils.js.map +1 -1
- package/dist/commands/claude/marketplace/publish-schema.d.ts +137 -0
- package/dist/commands/claude/marketplace/publish-schema.d.ts.map +1 -0
- package/dist/commands/claude/marketplace/publish-schema.js +32 -0
- package/dist/commands/claude/marketplace/publish-schema.js.map +1 -0
- package/dist/commands/claude/marketplace/publish-tree.d.ts +6 -0
- package/dist/commands/claude/marketplace/publish-tree.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/publish-tree.js +75 -17
- package/dist/commands/claude/marketplace/publish-tree.js.map +1 -1
- package/dist/commands/claude/marketplace/publish.d.ts +27 -0
- package/dist/commands/claude/marketplace/publish.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/publish.js +84 -50
- package/dist/commands/claude/marketplace/publish.js.map +1 -1
- package/dist/commands/claude/marketplace/validate-schema.d.ts +362 -0
- package/dist/commands/claude/marketplace/validate-schema.d.ts.map +1 -0
- package/dist/commands/claude/marketplace/validate-schema.js +67 -0
- package/dist/commands/claude/marketplace/validate-schema.js.map +1 -0
- package/dist/commands/claude/marketplace/validate.d.ts +40 -53
- package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/validate.js +358 -214
- package/dist/commands/claude/marketplace/validate.js.map +1 -1
- package/dist/commands/claude/org/api-keys.d.ts +3 -0
- package/dist/commands/claude/org/api-keys.d.ts.map +1 -1
- package/dist/commands/claude/org/api-keys.js +4 -5
- package/dist/commands/claude/org/api-keys.js.map +1 -1
- package/dist/commands/claude/org/code-analytics.js +1 -1
- package/dist/commands/claude/org/code-analytics.js.map +1 -1
- package/dist/commands/claude/org/cost.d.ts.map +1 -1
- package/dist/commands/claude/org/cost.js +11 -33
- package/dist/commands/claude/org/cost.js.map +1 -1
- package/dist/commands/claude/org/helpers.d.ts +40 -27
- package/dist/commands/claude/org/helpers.d.ts.map +1 -1
- package/dist/commands/claude/org/helpers.js +61 -66
- package/dist/commands/claude/org/helpers.js.map +1 -1
- package/dist/commands/claude/org/index.d.ts.map +1 -1
- package/dist/commands/claude/org/index.js +10 -4
- package/dist/commands/claude/org/index.js.map +1 -1
- package/dist/commands/claude/org/info.d.ts.map +1 -1
- package/dist/commands/claude/org/info.js +2 -3
- package/dist/commands/claude/org/info.js.map +1 -1
- package/dist/commands/claude/org/invites.d.ts +3 -0
- package/dist/commands/claude/org/invites.d.ts.map +1 -1
- package/dist/commands/claude/org/invites.js +5 -7
- package/dist/commands/claude/org/invites.js.map +1 -1
- package/dist/commands/claude/org/skills.d.ts +76 -21
- package/dist/commands/claude/org/skills.d.ts.map +1 -1
- package/dist/commands/claude/org/skills.js +273 -246
- package/dist/commands/claude/org/skills.js.map +1 -1
- package/dist/commands/claude/org/stubs-schema.d.ts +56 -0
- package/dist/commands/claude/org/stubs-schema.d.ts.map +1 -0
- package/dist/commands/claude/org/stubs-schema.js +23 -0
- package/dist/commands/claude/org/stubs-schema.js.map +1 -0
- package/dist/commands/claude/org/stubs.d.ts +8 -3
- package/dist/commands/claude/org/stubs.d.ts.map +1 -1
- package/dist/commands/claude/org/stubs.js +9 -9
- package/dist/commands/claude/org/stubs.js.map +1 -1
- package/dist/commands/claude/org/usage.d.ts.map +1 -1
- package/dist/commands/claude/org/usage.js +1 -2
- package/dist/commands/claude/org/usage.js.map +1 -1
- package/dist/commands/claude/org/users.d.ts +3 -0
- package/dist/commands/claude/org/users.d.ts.map +1 -1
- package/dist/commands/claude/org/users.js +6 -8
- package/dist/commands/claude/org/users.js.map +1 -1
- package/dist/commands/claude/org/workspaces.d.ts +3 -0
- package/dist/commands/claude/org/workspaces.d.ts.map +1 -1
- package/dist/commands/claude/org/workspaces.js +10 -15
- package/dist/commands/claude/org/workspaces.js.map +1 -1
- package/dist/commands/claude/plugin/build-schema.d.ts +642 -0
- package/dist/commands/claude/plugin/build-schema.d.ts.map +1 -0
- package/dist/commands/claude/plugin/build-schema.js +51 -0
- package/dist/commands/claude/plugin/build-schema.js.map +1 -0
- package/dist/commands/claude/plugin/build.d.ts +220 -45
- package/dist/commands/claude/plugin/build.d.ts.map +1 -1
- package/dist/commands/claude/plugin/build.js +466 -249
- package/dist/commands/claude/plugin/build.js.map +1 -1
- package/dist/commands/claude/plugin/helpers.d.ts +186 -24
- package/dist/commands/claude/plugin/helpers.d.ts.map +1 -1
- package/dist/commands/claude/plugin/helpers.js +110 -68
- package/dist/commands/claude/plugin/helpers.js.map +1 -1
- package/dist/commands/claude/plugin/install-schema.d.ts +144 -0
- package/dist/commands/claude/plugin/install-schema.d.ts.map +1 -0
- package/dist/commands/claude/plugin/install-schema.js +36 -0
- package/dist/commands/claude/plugin/install-schema.js.map +1 -0
- package/dist/commands/claude/plugin/install.d.ts +191 -11
- package/dist/commands/claude/plugin/install.d.ts.map +1 -1
- package/dist/commands/claude/plugin/install.js +688 -628
- package/dist/commands/claude/plugin/install.js.map +1 -1
- package/dist/commands/claude/plugin/kept-findings.d.ts +19 -0
- package/dist/commands/claude/plugin/kept-findings.d.ts.map +1 -0
- package/dist/commands/claude/plugin/kept-findings.js +24 -0
- package/dist/commands/claude/plugin/kept-findings.js.map +1 -0
- package/dist/commands/claude/plugin/list-schema.d.ts +223 -0
- package/dist/commands/claude/plugin/list-schema.d.ts.map +1 -0
- package/dist/commands/claude/plugin/list-schema.js +34 -0
- package/dist/commands/claude/plugin/list-schema.js.map +1 -0
- package/dist/commands/claude/plugin/list.d.ts +18 -0
- package/dist/commands/claude/plugin/list.d.ts.map +1 -1
- package/dist/commands/claude/plugin/list.js +53 -45
- package/dist/commands/claude/plugin/list.js.map +1 -1
- package/dist/commands/claude/plugin/npm-pack.d.ts +15 -0
- package/dist/commands/claude/plugin/npm-pack.d.ts.map +1 -0
- package/dist/commands/claude/plugin/npm-pack.js +39 -0
- package/dist/commands/claude/plugin/npm-pack.js.map +1 -0
- package/dist/commands/claude/plugin/plugin-changelog.d.ts +5 -1
- package/dist/commands/claude/plugin/plugin-changelog.d.ts.map +1 -1
- package/dist/commands/claude/plugin/plugin-changelog.js +9 -5
- package/dist/commands/claude/plugin/plugin-changelog.js.map +1 -1
- package/dist/commands/claude/plugin/plugin-files.d.ts +21 -2
- package/dist/commands/claude/plugin/plugin-files.d.ts.map +1 -1
- package/dist/commands/claude/plugin/plugin-files.js +65 -32
- package/dist/commands/claude/plugin/plugin-files.js.map +1 -1
- package/dist/commands/claude/plugin/plugin-validators.d.ts +13 -0
- package/dist/commands/claude/plugin/plugin-validators.d.ts.map +1 -1
- package/dist/commands/claude/plugin/plugin-validators.js +64 -16
- package/dist/commands/claude/plugin/plugin-validators.js.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.js +63 -37
- package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
- package/dist/commands/claude/plugin/uninstall-schema.d.ts +112 -0
- package/dist/commands/claude/plugin/uninstall-schema.d.ts.map +1 -0
- package/dist/commands/claude/plugin/uninstall-schema.js +28 -0
- package/dist/commands/claude/plugin/uninstall-schema.js.map +1 -0
- package/dist/commands/claude/plugin/uninstall.d.ts +57 -0
- package/dist/commands/claude/plugin/uninstall.d.ts.map +1 -1
- package/dist/commands/claude/plugin/uninstall.js +176 -64
- package/dist/commands/claude/plugin/uninstall.js.map +1 -1
- package/dist/commands/consistency-check.d.ts.map +1 -1
- package/dist/commands/consistency-check.js +8 -6
- package/dist/commands/consistency-check.js.map +1 -1
- package/dist/commands/corpus/index.d.ts.map +1 -1
- package/dist/commands/corpus/index.js +26 -10
- package/dist/commands/corpus/index.js.map +1 -1
- package/dist/commands/corpus/report.d.ts +34 -16
- package/dist/commands/corpus/report.d.ts.map +1 -1
- package/dist/commands/corpus/report.js +36 -18
- package/dist/commands/corpus/report.js.map +1 -1
- package/dist/commands/corpus/runner.d.ts +25 -20
- package/dist/commands/corpus/runner.d.ts.map +1 -1
- package/dist/commands/corpus/runner.js +123 -67
- package/dist/commands/corpus/runner.js.map +1 -1
- package/dist/commands/corpus/scan-schema.d.ts +127 -0
- package/dist/commands/corpus/scan-schema.d.ts.map +1 -0
- package/dist/commands/corpus/scan-schema.js +31 -0
- package/dist/commands/corpus/scan-schema.js.map +1 -0
- package/dist/commands/corpus/scan.d.ts +31 -0
- package/dist/commands/corpus/scan.d.ts.map +1 -1
- package/dist/commands/corpus/scan.js +124 -50
- package/dist/commands/corpus/scan.js.map +1 -1
- package/dist/commands/corpus/seed.d.ts +11 -8
- package/dist/commands/corpus/seed.d.ts.map +1 -1
- package/dist/commands/corpus/seed.js +29 -11
- package/dist/commands/corpus/seed.js.map +1 -1
- package/dist/commands/doctor-render.d.ts +52 -0
- package/dist/commands/doctor-render.d.ts.map +1 -0
- package/dist/commands/doctor-render.js +110 -0
- package/dist/commands/doctor-render.js.map +1 -0
- package/dist/commands/doctor-schema.d.ts +191 -0
- package/dist/commands/doctor-schema.d.ts.map +1 -0
- package/dist/commands/doctor-schema.js +44 -0
- package/dist/commands/doctor-schema.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -62
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +126 -165
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/inventory-schema.d.ts +7297 -0
- package/dist/commands/inventory-schema.d.ts.map +1 -0
- package/dist/commands/inventory-schema.js +28 -0
- package/dist/commands/inventory-schema.js.map +1 -0
- package/dist/commands/inventory.d.ts +1 -1
- package/dist/commands/inventory.d.ts.map +1 -1
- package/dist/commands/inventory.js +89 -41
- package/dist/commands/inventory.js.map +1 -1
- package/dist/commands/mcp/index.d.ts.map +1 -1
- package/dist/commands/mcp/index.js +15 -0
- package/dist/commands/mcp/index.js.map +1 -1
- package/dist/commands/mcp/list-collections-schema.d.ts +101 -0
- package/dist/commands/mcp/list-collections-schema.d.ts.map +1 -0
- package/dist/commands/mcp/list-collections-schema.js +22 -0
- package/dist/commands/mcp/list-collections-schema.js.map +1 -0
- package/dist/commands/mcp/list-collections.d.ts +1 -1
- package/dist/commands/mcp/list-collections.d.ts.map +1 -1
- package/dist/commands/mcp/list-collections.js +19 -17
- package/dist/commands/mcp/list-collections.js.map +1 -1
- package/dist/commands/mcp/serve.d.ts +5 -0
- package/dist/commands/mcp/serve.d.ts.map +1 -1
- package/dist/commands/mcp/serve.js +29 -15
- package/dist/commands/mcp/serve.js.map +1 -1
- package/dist/commands/okf/index.d.ts.map +1 -1
- package/dist/commands/okf/index.js +13 -10
- package/dist/commands/okf/index.js.map +1 -1
- package/dist/commands/okf/validate-schema.d.ts +171 -0
- package/dist/commands/okf/validate-schema.d.ts.map +1 -0
- package/dist/commands/okf/validate-schema.js +44 -0
- package/dist/commands/okf/validate-schema.js.map +1 -0
- package/dist/commands/okf/validate.d.ts +16 -145
- package/dist/commands/okf/validate.d.ts.map +1 -1
- package/dist/commands/okf/validate.js +63 -52
- package/dist/commands/okf/validate.js.map +1 -1
- package/dist/commands/orchestrator-schema.d.ts +419 -0
- package/dist/commands/orchestrator-schema.d.ts.map +1 -0
- package/dist/commands/orchestrator-schema.js +91 -0
- package/dist/commands/orchestrator-schema.js.map +1 -0
- package/dist/commands/phase-utils.d.ts +188 -220
- package/dist/commands/phase-utils.d.ts.map +1 -1
- package/dist/commands/phase-utils.js +210 -258
- package/dist/commands/phase-utils.js.map +1 -1
- package/dist/commands/positional-args.d.ts +13 -11
- package/dist/commands/positional-args.d.ts.map +1 -1
- package/dist/commands/positional-args.js +16 -15
- package/dist/commands/positional-args.js.map +1 -1
- package/dist/commands/rag/admin-schema.d.ts +152 -0
- package/dist/commands/rag/admin-schema.d.ts.map +1 -0
- package/dist/commands/rag/admin-schema.js +31 -0
- package/dist/commands/rag/admin-schema.js.map +1 -0
- package/dist/commands/rag/clear-command.d.ts.map +1 -1
- package/dist/commands/rag/clear-command.js +30 -15
- package/dist/commands/rag/clear-command.js.map +1 -1
- package/dist/commands/rag/command-helpers.d.ts +31 -7
- package/dist/commands/rag/command-helpers.d.ts.map +1 -1
- package/dist/commands/rag/command-helpers.js +41 -21
- package/dist/commands/rag/command-helpers.js.map +1 -1
- package/dist/commands/rag/index-command.d.ts +37 -48
- package/dist/commands/rag/index-command.d.ts.map +1 -1
- package/dist/commands/rag/index-command.js +80 -65
- package/dist/commands/rag/index-command.js.map +1 -1
- package/dist/commands/rag/index-schema.d.ts +107 -0
- package/dist/commands/rag/index-schema.d.ts.map +1 -0
- package/dist/commands/rag/index-schema.js +34 -0
- package/dist/commands/rag/index-schema.js.map +1 -0
- package/dist/commands/rag/index.d.ts.map +1 -1
- package/dist/commands/rag/index.js +88 -41
- package/dist/commands/rag/index.js.map +1 -1
- package/dist/commands/rag/query-command.d.ts +18 -4
- package/dist/commands/rag/query-command.d.ts.map +1 -1
- package/dist/commands/rag/query-command.js +42 -27
- package/dist/commands/rag/query-command.js.map +1 -1
- package/dist/commands/rag/query-schema.d.ts +363 -0
- package/dist/commands/rag/query-schema.d.ts.map +1 -0
- package/dist/commands/rag/query-schema.js +59 -0
- package/dist/commands/rag/query-schema.js.map +1 -0
- package/dist/commands/rag/stats-command.d.ts.map +1 -1
- package/dist/commands/rag/stats-command.js +19 -18
- package/dist/commands/rag/stats-command.js.map +1 -1
- package/dist/commands/resources/check-progress.d.ts +79 -13
- package/dist/commands/resources/check-progress.d.ts.map +1 -1
- package/dist/commands/resources/check-progress.js +112 -11
- package/dist/commands/resources/check-progress.js.map +1 -1
- package/dist/commands/resources/check-schema.d.ts +335 -0
- package/dist/commands/resources/check-schema.d.ts.map +1 -0
- package/dist/commands/resources/check-schema.js +104 -0
- package/dist/commands/resources/check-schema.js.map +1 -0
- package/dist/commands/resources/check-supervisor.d.ts +329 -71
- package/dist/commands/resources/check-supervisor.d.ts.map +1 -1
- package/dist/commands/resources/check-supervisor.js +507 -107
- package/dist/commands/resources/check-supervisor.js.map +1 -1
- package/dist/commands/resources/check.d.ts +88 -254
- package/dist/commands/resources/check.d.ts.map +1 -1
- package/dist/commands/resources/check.js +537 -310
- package/dist/commands/resources/check.js.map +1 -1
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +189 -103
- package/dist/commands/resources/index.js.map +1 -1
- package/dist/commands/resources/query-schema.d.ts +188 -0
- package/dist/commands/resources/query-schema.d.ts.map +1 -0
- package/dist/commands/resources/query-schema.js +48 -0
- package/dist/commands/resources/query-schema.js.map +1 -0
- package/dist/commands/resources/query.d.ts +18 -13
- package/dist/commands/resources/query.d.ts.map +1 -1
- package/dist/commands/resources/query.js +61 -49
- package/dist/commands/resources/query.js.map +1 -1
- package/dist/commands/resources/scan-schema.d.ts +195 -0
- package/dist/commands/resources/scan-schema.d.ts.map +1 -0
- package/dist/commands/resources/scan-schema.js +53 -0
- package/dist/commands/resources/scan-schema.js.map +1 -0
- package/dist/commands/resources/scan.d.ts +26 -3
- package/dist/commands/resources/scan.d.ts.map +1 -1
- package/dist/commands/resources/scan.js +51 -53
- package/dist/commands/resources/scan.js.map +1 -1
- package/dist/commands/resources/validate-schema.d.ts +326 -0
- package/dist/commands/resources/validate-schema.d.ts.map +1 -0
- package/dist/commands/resources/validate-schema.js +60 -0
- package/dist/commands/resources/validate-schema.js.map +1 -0
- package/dist/commands/resources/validate.d.ts +45 -169
- package/dist/commands/resources/validate.d.ts.map +1 -1
- package/dist/commands/resources/validate.js +221 -485
- package/dist/commands/resources/validate.js.map +1 -1
- package/dist/commands/skill/review-checklist.d.ts.map +1 -1
- package/dist/commands/skill/review-checklist.js +0 -1
- package/dist/commands/skill/review-checklist.js.map +1 -1
- package/dist/commands/skill/review-schema.d.ts +278 -0
- package/dist/commands/skill/review-schema.d.ts.map +1 -0
- package/dist/commands/skill/review-schema.js +46 -0
- package/dist/commands/skill/review-schema.js.map +1 -0
- package/dist/commands/skill/review.d.ts +8 -234
- package/dist/commands/skill/review.d.ts.map +1 -1
- package/dist/commands/skill/review.js +54 -77
- package/dist/commands/skill/review.js.map +1 -1
- package/dist/commands/skill/test/auth-flags.d.ts +3 -0
- package/dist/commands/skill/test/auth-flags.d.ts.map +1 -1
- package/dist/commands/skill/test/auth-flags.js +6 -2
- package/dist/commands/skill/test/auth-flags.js.map +1 -1
- package/dist/commands/skill/test/configure-schema.d.ts +67 -0
- package/dist/commands/skill/test/configure-schema.d.ts.map +1 -0
- package/dist/commands/skill/test/configure-schema.js +27 -0
- package/dist/commands/skill/test/configure-schema.js.map +1 -0
- package/dist/commands/skill/test/configure.d.ts +12 -5
- package/dist/commands/skill/test/configure.d.ts.map +1 -1
- package/dist/commands/skill/test/configure.js +101 -31
- package/dist/commands/skill/test/configure.js.map +1 -1
- package/dist/commands/skill/test/run-schema.d.ts +107 -0
- package/dist/commands/skill/test/run-schema.d.ts.map +1 -0
- package/dist/commands/skill/test/run-schema.js +36 -0
- package/dist/commands/skill/test/run-schema.js.map +1 -0
- package/dist/commands/skill/test/run.d.ts +3 -2
- package/dist/commands/skill/test/run.d.ts.map +1 -1
- package/dist/commands/skill/test/run.js +316 -155
- package/dist/commands/skill/test/run.js.map +1 -1
- package/dist/commands/skills/build-schema.d.ts +199 -0
- package/dist/commands/skills/build-schema.d.ts.map +1 -0
- package/dist/commands/skills/build-schema.js +55 -0
- package/dist/commands/skills/build-schema.js.map +1 -0
- package/dist/commands/skills/build.d.ts +95 -298
- package/dist/commands/skills/build.d.ts.map +1 -1
- package/dist/commands/skills/build.js +415 -818
- package/dist/commands/skills/build.js.map +1 -1
- package/dist/commands/skills/command-helpers.d.ts +5 -11
- package/dist/commands/skills/command-helpers.d.ts.map +1 -1
- package/dist/commands/skills/command-helpers.js +7 -17
- package/dist/commands/skills/command-helpers.js.map +1 -1
- package/dist/commands/skills/index.js +12 -6
- package/dist/commands/skills/index.js.map +1 -1
- package/dist/commands/skills/install-schema.d.ts +153 -0
- package/dist/commands/skills/install-schema.d.ts.map +1 -0
- package/dist/commands/skills/install-schema.js +44 -0
- package/dist/commands/skills/install-schema.js.map +1 -0
- package/dist/commands/skills/install.d.ts +76 -8
- package/dist/commands/skills/install.d.ts.map +1 -1
- package/dist/commands/skills/install.js +230 -194
- package/dist/commands/skills/install.js.map +1 -1
- package/dist/commands/skills/list-schema.d.ts +145 -0
- package/dist/commands/skills/list-schema.d.ts.map +1 -0
- package/dist/commands/skills/list-schema.js +37 -0
- package/dist/commands/skills/list-schema.js.map +1 -0
- package/dist/commands/skills/list.d.ts +39 -8
- package/dist/commands/skills/list.d.ts.map +1 -1
- package/dist/commands/skills/list.js +110 -122
- package/dist/commands/skills/list.js.map +1 -1
- package/dist/commands/skills/package-schema.d.ts +98 -0
- package/dist/commands/skills/package-schema.d.ts.map +1 -0
- package/dist/commands/skills/package-schema.js +32 -0
- package/dist/commands/skills/package-schema.js.map +1 -0
- package/dist/commands/skills/package.d.ts +85 -14
- package/dist/commands/skills/package.d.ts.map +1 -1
- package/dist/commands/skills/package.js +288 -207
- package/dist/commands/skills/package.js.map +1 -1
- package/dist/commands/skills/scope-guard.d.ts +27 -20
- package/dist/commands/skills/scope-guard.d.ts.map +1 -1
- package/dist/commands/skills/scope-guard.js +43 -28
- package/dist/commands/skills/scope-guard.js.map +1 -1
- package/dist/commands/skills/skill-discovery.d.ts +1 -1
- package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
- package/dist/commands/skills/skill-discovery.js +40 -19
- package/dist/commands/skills/skill-discovery.js.map +1 -1
- package/dist/commands/skills/source-resolvers.d.ts +58 -8
- package/dist/commands/skills/source-resolvers.d.ts.map +1 -1
- package/dist/commands/skills/source-resolvers.js +113 -38
- package/dist/commands/skills/source-resolvers.js.map +1 -1
- package/dist/commands/skills/validate-command.d.ts.map +1 -1
- package/dist/commands/skills/validate-command.js +31 -51
- package/dist/commands/skills/validate-command.js.map +1 -1
- package/dist/commands/skills/validate-schema.d.ts +199 -0
- package/dist/commands/skills/validate-schema.d.ts.map +1 -0
- package/dist/commands/skills/validate-schema.js +44 -0
- package/dist/commands/skills/validate-schema.js.map +1 -0
- package/dist/commands/skills/validate.d.ts +100 -136
- package/dist/commands/skills/validate.d.ts.map +1 -1
- package/dist/commands/skills/validate.js +257 -343
- package/dist/commands/skills/validate.js.map +1 -1
- package/dist/commands/validate.d.ts +17 -5
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +139 -94
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/verify.d.ts +121 -110
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +230 -294
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/report-schemas.d.ts +12398 -35
- package/dist/report-schemas.d.ts.map +1 -1
- package/dist/report-schemas.js +624 -66
- package/dist/report-schemas.js.map +1 -1
- package/dist/skill-resolution/packaging-config.js +2 -2
- package/dist/skill-resolution/packaging-config.js.map +1 -1
- package/dist/skill-resolution/resolve-skill-reference.d.ts.map +1 -1
- package/dist/skill-resolution/resolve-skill-reference.js +20 -13
- package/dist/skill-resolution/resolve-skill-reference.js.map +1 -1
- package/dist/utils/agent-discovery.d.ts +34 -1
- package/dist/utils/agent-discovery.d.ts.map +1 -1
- package/dist/utils/agent-discovery.js +80 -38
- package/dist/utils/agent-discovery.js.map +1 -1
- package/dist/utils/claude-context-lens.d.ts +13 -6
- package/dist/utils/claude-context-lens.d.ts.map +1 -1
- package/dist/utils/claude-context-lens.js +11 -12
- package/dist/utils/claude-context-lens.js.map +1 -1
- package/dist/utils/command-error-codes.d.ts +12 -0
- package/dist/utils/command-error-codes.d.ts.map +1 -0
- package/dist/utils/command-error-codes.js +12 -0
- package/dist/utils/command-error-codes.js.map +1 -0
- package/dist/utils/command-refusal.d.ts +58 -0
- package/dist/utils/command-refusal.d.ts.map +1 -0
- package/dist/utils/command-refusal.js +170 -0
- package/dist/utils/command-refusal.js.map +1 -0
- package/dist/utils/commander-ending.d.ts +40 -0
- package/dist/utils/commander-ending.d.ts.map +1 -0
- package/dist/utils/commander-ending.js +42 -0
- package/dist/utils/commander-ending.js.map +1 -0
- package/dist/utils/config-loader.d.ts +13 -8
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +84 -45
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/corpus-target.d.ts +1 -1
- package/dist/utils/corpus-target.d.ts.map +1 -1
- package/dist/utils/corpus-target.js +44 -5
- package/dist/utils/corpus-target.js.map +1 -1
- package/dist/utils/debug-diagnostics.d.ts +18 -0
- package/dist/utils/debug-diagnostics.d.ts.map +1 -0
- package/dist/utils/debug-diagnostics.js +23 -0
- package/dist/utils/debug-diagnostics.js.map +1 -0
- package/dist/utils/document-writer.d.ts +191 -0
- package/dist/utils/document-writer.d.ts.map +1 -0
- package/dist/utils/document-writer.js +319 -0
- package/dist/utils/document-writer.js.map +1 -0
- package/dist/utils/help-loader.d.ts +2 -2
- package/dist/utils/help-loader.js +2 -2
- package/dist/utils/install-plan.d.ts +99 -0
- package/dist/utils/install-plan.d.ts.map +1 -0
- package/dist/utils/install-plan.js +146 -0
- package/dist/utils/install-plan.js.map +1 -0
- package/dist/utils/issue-anchor.d.ts +1 -1
- package/dist/utils/issue-anchor.d.ts.map +1 -1
- package/dist/utils/issue-anchor.js.map +1 -1
- package/dist/utils/issue-rendering.d.ts +8 -3
- package/dist/utils/issue-rendering.d.ts.map +1 -1
- package/dist/utils/issue-rendering.js +4 -0
- package/dist/utils/issue-rendering.js.map +1 -1
- package/dist/utils/lens-population.d.ts +20 -0
- package/dist/utils/lens-population.d.ts.map +1 -0
- package/dist/utils/lens-population.js +15 -0
- package/dist/utils/lens-population.js.map +1 -0
- package/dist/utils/marketplace-io.d.ts +63 -0
- package/dist/utils/marketplace-io.d.ts.map +1 -0
- package/dist/utils/marketplace-io.js +63 -0
- package/dist/utils/marketplace-io.js.map +1 -0
- package/dist/utils/operator-notices.d.ts +97 -0
- package/dist/utils/operator-notices.d.ts.map +1 -0
- package/dist/utils/operator-notices.js +115 -0
- package/dist/utils/operator-notices.js.map +1 -0
- package/dist/utils/optional-backend.d.ts +18 -15
- package/dist/utils/optional-backend.d.ts.map +1 -1
- package/dist/utils/optional-backend.js +22 -33
- package/dist/utils/optional-backend.js.map +1 -1
- package/dist/utils/output.d.ts +5 -43
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +8 -63
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/package-json.d.ts +3 -4
- package/dist/utils/package-json.d.ts.map +1 -1
- package/dist/utils/package-json.js +8 -8
- package/dist/utils/package-json.js.map +1 -1
- package/dist/utils/population-wiring.d.ts +31 -38
- package/dist/utils/population-wiring.d.ts.map +1 -1
- package/dist/utils/population-wiring.js +38 -32
- package/dist/utils/population-wiring.js.map +1 -1
- package/dist/utils/project-root-policy.d.ts +74 -1
- package/dist/utils/project-root-policy.d.ts.map +1 -1
- package/dist/utils/project-root-policy.js +146 -8
- package/dist/utils/project-root-policy.js.map +1 -1
- package/dist/utils/projection-lenses.d.ts +25 -7
- package/dist/utils/projection-lenses.d.ts.map +1 -1
- package/dist/utils/projection-lenses.js +20 -6
- package/dist/utils/projection-lenses.js.map +1 -1
- package/dist/utils/projection-query.d.ts +18 -11
- package/dist/utils/projection-query.d.ts.map +1 -1
- package/dist/utils/projection-query.js +47 -28
- package/dist/utils/projection-query.js.map +1 -1
- package/dist/utils/projection-store.d.ts +2 -2
- package/dist/utils/projection-store.d.ts.map +1 -1
- package/dist/utils/projection-store.js +74 -45
- package/dist/utils/projection-store.js.map +1 -1
- package/dist/utils/rag-database.d.ts +61 -0
- package/dist/utils/rag-database.d.ts.map +1 -0
- package/dist/utils/rag-database.js +178 -0
- package/dist/utils/rag-database.js.map +1 -0
- package/dist/utils/relation-limits.d.ts +7 -2
- package/dist/utils/relation-limits.d.ts.map +1 -1
- package/dist/utils/relation-limits.js +6 -1
- package/dist/utils/relation-limits.js.map +1 -1
- package/dist/utils/relativize-paths.d.ts +23 -0
- package/dist/utils/relativize-paths.d.ts.map +1 -1
- package/dist/utils/relativize-paths.js +32 -1
- package/dist/utils/relativize-paths.js.map +1 -1
- package/dist/utils/resource-loader.d.ts +78 -32
- package/dist/utils/resource-loader.d.ts.map +1 -1
- package/dist/utils/resource-loader.js +134 -66
- package/dist/utils/resource-loader.js.map +1 -1
- package/dist/utils/run-integrity.d.ts +64 -31
- package/dist/utils/run-integrity.d.ts.map +1 -1
- package/dist/utils/run-integrity.js +76 -35
- package/dist/utils/run-integrity.js.map +1 -1
- package/dist/utils/scope-locations.d.ts +7 -5
- package/dist/utils/scope-locations.d.ts.map +1 -1
- package/dist/utils/scope-locations.js +37 -12
- package/dist/utils/scope-locations.js.map +1 -1
- package/dist/utils/staging-dir.d.ts +7 -0
- package/dist/utils/staging-dir.d.ts.map +1 -0
- package/dist/utils/staging-dir.js +12 -0
- package/dist/utils/staging-dir.js.map +1 -0
- package/dist/utils/url-redact.d.ts +9 -0
- package/dist/utils/url-redact.d.ts.map +1 -1
- package/dist/utils/url-redact.js +13 -0
- package/dist/utils/url-redact.js.map +1 -1
- package/dist/utils/user-context-scanner.d.ts +3 -2
- package/dist/utils/user-context-scanner.d.ts.map +1 -1
- package/dist/utils/user-context-scanner.js +24 -4
- package/dist/utils/user-context-scanner.js.map +1 -1
- package/dist/utils/validate-help-files.d.ts.map +1 -1
- package/dist/utils/validate-help-files.js +8 -14
- package/dist/utils/validate-help-files.js.map +1 -1
- package/dist/utils/vat-bin-path.d.ts.map +1 -1
- package/dist/utils/vat-bin-path.js +3 -3
- package/dist/utils/vat-bin-path.js.map +1 -1
- package/dist/utils/verdict-helpers.d.ts.map +1 -1
- package/dist/utils/verdict-helpers.js +5 -5
- package/dist/utils/verdict-helpers.js.map +1 -1
- package/docs/agent.md +347 -2
- package/docs/audit.md +312 -89
- package/docs/doctor.md +65 -19
- package/docs/index.md +571 -20
- package/docs/mcp.md +64 -12
- package/docs/rag.md +176 -48
- package/docs/resources.md +257 -71
- package/docs/skill-test.md +148 -19
- package/docs/skills.md +459 -174
- package/package.json +17 -20
- package/schemas/agent-build.json +268 -0
- package/schemas/agent-import.json +252 -0
- package/schemas/agent-install.json +260 -0
- package/schemas/agent-installed.json +287 -0
- package/schemas/agent-list.json +279 -0
- package/schemas/agent-uninstall.json +260 -0
- package/schemas/agent-validate.json +279 -0
- package/schemas/ard-emit.json +228 -107
- package/schemas/audit-settings.json +472 -0
- package/schemas/audit.json +635 -0
- package/schemas/cache-clear.json +273 -0
- package/schemas/claude-marketplace-publish.json +286 -0
- package/schemas/claude-marketplace-validate.json +352 -0
- package/schemas/claude-org-not-implemented.json +239 -0
- package/schemas/claude-plugin-build.json +446 -0
- package/schemas/claude-plugin-install.json +291 -0
- package/schemas/claude-plugin-list.json +326 -0
- package/schemas/claude-plugin-uninstall.json +272 -0
- package/schemas/corpus-audit.json +635 -0
- package/schemas/corpus-scan.json +293 -0
- package/schemas/doctor.json +299 -0
- package/schemas/inventory.json +982 -0
- package/schemas/mcp-list-collections.json +268 -0
- package/schemas/okf-validate.json +224 -106
- package/schemas/orchestrator.json +299 -0
- package/schemas/rag-clear.json +253 -0
- package/schemas/rag-index.json +273 -0
- package/schemas/rag-query.json +365 -0
- package/schemas/rag-stats.json +269 -0
- package/schemas/resources-check.json +280 -118
- package/schemas/resources-query.json +333 -0
- package/schemas/resources-scan.json +321 -0
- package/schemas/resources-validate.json +332 -0
- package/schemas/skill-review.json +224 -106
- package/schemas/skill-test-configure.json +256 -0
- package/schemas/skill-test-run.json +296 -0
- package/schemas/skills-build.json +325 -0
- package/schemas/skills-install.json +287 -0
- package/schemas/skills-list.json +283 -0
- package/schemas/skills-package.json +270 -0
- package/schemas/skills-validate.json +285 -0
- package/dist/commands/skills/shared.d.ts +0 -29
- package/dist/commands/skills/shared.d.ts.map +0 -1
- package/dist/commands/skills/shared.js +0 -33
- package/dist/commands/skills/shared.js.map +0 -1
- package/dist/utils/command-error.d.ts +0 -189
- package/dist/utils/command-error.d.ts.map +0 -1
- package/dist/utils/command-error.js +0 -230
- package/dist/utils/command-error.js.map +0 -1
|
@@ -15,12 +15,20 @@
|
|
|
15
15
|
* JS — which is why the parse pool's `terminate()` genuinely works — but a
|
|
16
16
|
* thread inside a synchronous native call is not spinning in JS. Do NOT
|
|
17
17
|
* "align" this design with the parse pool's.
|
|
18
|
-
* - **A signal handler is a REGRESSION.** A
|
|
19
|
-
* `node:sqlite` dies INSTANTLY on SIGINT while
|
|
20
|
-
* SURVIVES both SIGINT and SIGTERM once one is —
|
|
21
|
-
* and the event loop that would schedule it is
|
|
22
|
-
* Installing one removes the operator's Ctrl-C.
|
|
23
|
-
*
|
|
18
|
+
* - **A signal handler in the process RUNNING THE SQL is a REGRESSION.** A
|
|
19
|
+
* process blocked in synchronous `node:sqlite` dies INSTANTLY on SIGINT while
|
|
20
|
+
* no handler is installed, and SURVIVES both SIGINT and SIGTERM once one is —
|
|
21
|
+
* the handler is a JS callback, and the event loop that would schedule it is
|
|
22
|
+
* the resource that is blocked. Installing one removes the operator's Ctrl-C.
|
|
23
|
+
* That process — the supervised child, or this command under `--budget 0` —
|
|
24
|
+
* must never have a `process.on(<signal>)`, and nothing on its path installs
|
|
25
|
+
* one.
|
|
26
|
+
*
|
|
27
|
+
* The SUPERVISING process may, and does: its event loop only waits on the
|
|
28
|
+
* child, so a handler there fires. It guards every `TERMINATING_SIGNALS`
|
|
29
|
+
* member (through `handleTerminatingSignals`, the one way a handler is
|
|
30
|
+
* installed) for exactly the duration of a supervision, only to take the
|
|
31
|
+
* child down with it and re-raise; see `guardSupervision`.
|
|
24
32
|
* - **The kill is `SIGKILL` because SIGKILL cannot be REGRESSED.** No code the
|
|
25
33
|
* child runs, now or after any future edit, can handle, ignore or block it.
|
|
26
34
|
*
|
|
@@ -51,6 +59,20 @@
|
|
|
51
59
|
* check's budget. A gate that can hang forever is the thing being fixed, and
|
|
52
60
|
* that includes hanging before the first statement.
|
|
53
61
|
*
|
|
62
|
+
* 🔑 **The clock starts at the spawn, and the child's first line is `started`.**
|
|
63
|
+
* The spawn is the only instant this process can observe, so the child's own
|
|
64
|
+
* boot — Node's startup and the CLI's module graph — is a unit like any other:
|
|
65
|
+
* bounded by the budget, and closed by the `started` line the child writes
|
|
66
|
+
* before it touches the tree. Without that line the boot was charged to the
|
|
67
|
+
* population, and a loaded runner's slower boot killed a population that was
|
|
68
|
+
* fine. {@link WatchdogState}'s `quietSince` is therefore `startedAt`, and must
|
|
69
|
+
* stay so: starting the clock at the first line instead would leave a child
|
|
70
|
+
* that hangs while booting with no bound at all.
|
|
71
|
+
*
|
|
72
|
+
* Wherever a kill lands — startup, population, a check, the document — the
|
|
73
|
+
* parent publishes the same kind of document and exits 1. A kill is one outcome
|
|
74
|
+
* and gets one exit code; see `buildInterruptedCheckInput`.
|
|
75
|
+
*
|
|
54
76
|
* ⚠️ **That property holds for the CHECKS. It does NOT hold for the population,
|
|
55
77
|
* and the difference is not a detail.** The population emits exactly ONE line,
|
|
56
78
|
* at its end, so for the single longest unit in a cold run the budget degrades
|
|
@@ -68,15 +90,42 @@
|
|
|
68
90
|
*
|
|
69
91
|
* ## Why the child is the CLI itself
|
|
70
92
|
*
|
|
71
|
-
* The child is `vat resources check` with a hidden `--
|
|
93
|
+
* The child is `vat resources check` with a hidden `--supervised-by` flag, running
|
|
72
94
|
* the ordinary in-process path. Forking the logic would give the supervised lane
|
|
73
95
|
* and the unsupervised one two implementations of the same gate — and the one
|
|
74
96
|
* nobody runs interactively is the one that would rot.
|
|
97
|
+
*
|
|
98
|
+
* ## ⚠️ When the SUPERVISOR dies
|
|
99
|
+
*
|
|
100
|
+
* Its signal handlers and `exit` guard take the child down on every ending that
|
|
101
|
+
* runs its code (see `guardSupervision`). SIGKILL, an OOM killer and, on Windows,
|
|
102
|
+
* any outside kill run none of it.
|
|
103
|
+
*
|
|
104
|
+
* - **Windows**: the OS takes the child down. libuv puts every child spawned
|
|
105
|
+
* without `detached` in a job object with `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`
|
|
106
|
+
* whose only handle this process holds (`uv__init_global_job_handle`,
|
|
107
|
+
* `src/win/process.c`), so its `TerminateProcess` terminates the child too, at
|
|
108
|
+
* once and mid-check: none of the child's code runs, nothing is published.
|
|
109
|
+
* - **POSIX**: the child ends ITSELF. Its stdin is a pipe whose write end only
|
|
110
|
+
* this process holds and never writes or ends, so however this process dies
|
|
111
|
+
* the OS closes it and the child reads end-of-file (`endWhenSupervisorGone`).
|
|
112
|
+
* The child notices when its event loop next turns: at once during the
|
|
113
|
+
* population; during the synchronous check loop, once the LAST check has
|
|
114
|
+
* returned (a statement blocked inside SQLite reaches nothing until it
|
|
115
|
+
* returns) — and still before it publishes anything
|
|
116
|
+
* (`letSupervisorLossSurface`). Either way it exits 2 with one stderr line.
|
|
117
|
+
* (The pipe is there on Windows too; the job object simply ends the child
|
|
118
|
+
* first.)
|
|
75
119
|
*/
|
|
76
120
|
import { spawn } from 'node:child_process';
|
|
77
|
-
import {
|
|
78
|
-
import {
|
|
79
|
-
import {
|
|
121
|
+
import { readFileSync } from 'node:fs';
|
|
122
|
+
import { dirname } from 'node:path';
|
|
123
|
+
import { ExitCode, exitCodeForReport } from '@vibe-agent-toolkit/schema';
|
|
124
|
+
import { disposeTempDirSync, isPathAbsentError, requireFollowedStatSync, safePath, withTempDir, } from '@vibe-agent-toolkit/utils';
|
|
125
|
+
import { handleTerminatingSignals, killProcessTree } from '@vibe-agent-toolkit/utils/process';
|
|
126
|
+
import { CommandRefusalError, errorMessageOf } from '../../utils/command-refusal.js';
|
|
127
|
+
import { readForwardedDocument } from '../../utils/document-writer.js';
|
|
128
|
+
import { isSupervisedChild } from '../../utils/operator-notices.js';
|
|
80
129
|
import { resolveVatBinPath } from '../../utils/vat-bin-path.js';
|
|
81
130
|
/**
|
|
82
131
|
* The bound applied when `--budget` is not passed, in seconds.
|
|
@@ -92,7 +141,41 @@ import { resolveVatBinPath } from '../../utils/vat-bin-path.js';
|
|
|
92
141
|
* the whole objective. A tree ten times that adopter's lands near 165 s, still
|
|
93
142
|
* inside the default but no longer comfortably.
|
|
94
143
|
*/
|
|
95
|
-
const DEFAULT_BUDGET_SECONDS = 300;
|
|
144
|
+
export const DEFAULT_BUDGET_SECONDS = 300;
|
|
145
|
+
/**
|
|
146
|
+
* 🔑 THE text that says what interrupting a supervised checks run does — rendered verbatim into
|
|
147
|
+
* BOTH `vat validate --help` and `vat resources check --help` (a unit test pins that), so the two
|
|
148
|
+
* can never describe it differently. Help-text indentation (two spaces), no backticks.
|
|
149
|
+
*
|
|
150
|
+
* Each claim is pinned: POSIX signals by `checks-supervisor-orphan.system.test.ts`, the group
|
|
151
|
+
* Ctrl-C by the same file and `signal-guard-group-ctrl-c.system.test.ts`, the orphan's own ending
|
|
152
|
+
* by `checks-supervisor-orphan.system.test.ts` (population) and
|
|
153
|
+
* `checks-supervisor-orphan-loop.system.test.ts` (the check loop) — on Windows the same two cases
|
|
154
|
+
* pin the job object ending the child with its supervisor — the Windows wrapper by
|
|
155
|
+
* `supervise-cli.test.ts`.
|
|
156
|
+
*/
|
|
157
|
+
export const SUPERVISION_SIGNAL_CONTRACT = `Interrupting a supervised checks run:
|
|
158
|
+
POSIX: SIGTERM, SIGHUP, SIGINT or SIGQUIT sent to this process, to the
|
|
159
|
+
'vat' wrapper (which forwards it), or to the terminal's process group
|
|
160
|
+
(Ctrl-C) kills the checks child, removes the progress directory, publishes
|
|
161
|
+
nothing, and dies of the signal (status 128+n; exit 2 where the signal
|
|
162
|
+
cannot kill it, PID 1). A process the child itself started (git) is not
|
|
163
|
+
killed with it; it ends on its own.
|
|
164
|
+
POSIX, ended where it runs no code (SIGKILL, an OOM killer), this process
|
|
165
|
+
cannot kill the child: the child reads end-of-file on the stdin pipe this
|
|
166
|
+
process held and ends itself -- one stderr line, exit 2, nothing
|
|
167
|
+
published -- at once during its population, and during the checks once
|
|
168
|
+
the last check returns (a statement inside SQLite is not reached until it
|
|
169
|
+
returns). A SIGKILL of the 'vat' wrapper kills the wrapper alone: this
|
|
170
|
+
process (whose stdin is the terminal's, so it reads no end-of-file) and
|
|
171
|
+
its child run on to completion, or until --budget seconds pass with no
|
|
172
|
+
progress.
|
|
173
|
+
Windows: a console Ctrl-C, Ctrl-Break or window close reaches every process
|
|
174
|
+
on the console; this one kills the child and exits 2, no document. An
|
|
175
|
+
outside kill (TerminateProcess, taskkill /F) of the 'vat' wrapper or of
|
|
176
|
+
this process runs no handler and ends the processes it started with it
|
|
177
|
+
(the OS job object Node puts them in): exit 1, nothing published, the
|
|
178
|
+
progress directory left behind.`;
|
|
96
179
|
/** How many times per budget the parent looks at the log. */
|
|
97
180
|
const POLLS_PER_BUDGET = 10;
|
|
98
181
|
/** Poll bounds, so a huge budget still notices promptly and a tiny one is cheap. */
|
|
@@ -102,15 +185,29 @@ const MAX_POLL_MS = 250;
|
|
|
102
185
|
* How many refused SIGKILLs the watchdog sends before it stops trying and
|
|
103
186
|
* REPORTS instead.
|
|
104
187
|
*
|
|
105
|
-
* A retry count, not a bound on anything stored.
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
188
|
+
* A retry count, not a bound on anything stored. A kill of a child that has
|
|
189
|
+
* already exited never reaches here: Node's `subprocess.kill()` swallows
|
|
190
|
+
* `ESRCH` and emits no `error` for it. What does arrive is any other refusal —
|
|
191
|
+
* `EPERM`, in practice — and that may be transient (a refusal raced against the
|
|
192
|
+
* child's own exit, an OS that briefly refuses) or permanent (a permission fact
|
|
193
|
+
* that will be just as true on the thousandth attempt). Retrying a handful of
|
|
194
|
+
* times covers the transient case at negligible cost; continuing past that
|
|
195
|
+
* would turn the supervisor into a second unbounded hang, which is the thing
|
|
196
|
+
* this module exists to abolish. So it escalates to an honest report naming
|
|
197
|
+
* the pid.
|
|
112
198
|
*/
|
|
113
199
|
const KILL_ATTEMPTS_BEFORE_REPORTING = 5;
|
|
200
|
+
/**
|
|
201
|
+
* How many polls after the first ACCEPTED SIGKILL the watchdog waits for the child's `exit`
|
|
202
|
+
* before it REPORTS the kill as one that did not land.
|
|
203
|
+
*
|
|
204
|
+
* The kernel accepting SIGKILL is not the child ending: a process in uninterruptible I/O (state
|
|
205
|
+
* `D` on Linux — a hung NFS mount, a wedged disk) takes the signal and does not die until the I/O
|
|
206
|
+
* returns, which may be never. Without this the watchdog re-sent SIGKILL forever and the
|
|
207
|
+
* supervisor became the second unbounded hang. 20 polls is 1-5 s at the poll bounds — far beyond
|
|
208
|
+
* the moment a SIGKILLed process normally takes to be reaped.
|
|
209
|
+
*/
|
|
210
|
+
const KILL_POLLS_BEFORE_REPORTING_UNREAPED = 20;
|
|
114
211
|
/**
|
|
115
212
|
* Decide whether the child has gone quiet for longer than the budget.
|
|
116
213
|
*
|
|
@@ -184,7 +281,7 @@ export function parseBudgetSeconds(raw) {
|
|
|
184
281
|
if (raw === undefined)
|
|
185
282
|
return DEFAULT_BUDGET_SECONDS;
|
|
186
283
|
if (raw.trim() === '') {
|
|
187
|
-
throw new
|
|
284
|
+
throw new CommandRefusalError('USAGE_INVALID', '--budget was given an empty value. That is almost always an unset shell'
|
|
188
285
|
+ ' variable (`--budget "$CHECK_BUDGET"`), and it is refused rather than read'
|
|
189
286
|
+ ' as `--budget 0` — which would remove the bound entirely and let the run'
|
|
190
287
|
+ ' hang forever. Pass a number of seconds, or `--budget 0` explicitly if that'
|
|
@@ -192,12 +289,12 @@ export function parseBudgetSeconds(raw) {
|
|
|
192
289
|
}
|
|
193
290
|
const seconds = Number(raw);
|
|
194
291
|
if (!Number.isFinite(seconds) || seconds < 0) {
|
|
195
|
-
throw new
|
|
292
|
+
throw new CommandRefusalError('USAGE_INVALID', `--budget must be a non-negative number of seconds, not "${raw}".`
|
|
196
293
|
+ ` It bounds how long the run may go without completing a unit of work;`
|
|
197
294
|
+ ` --budget 0 removes the bound entirely (and can then hang forever).`);
|
|
198
295
|
}
|
|
199
296
|
if (seconds === 0 && raw.trim() !== '0') {
|
|
200
|
-
throw new
|
|
297
|
+
throw new CommandRefusalError('USAGE_INVALID', `--budget "${raw}" is a number that means ZERO — and 0 is this flag's escape`
|
|
201
298
|
+ ' hatch for "no bound at all", so the run would have gone entirely'
|
|
202
299
|
+ ' unsupervised and could hang forever. `1e-400` underflows to zero and `-0`'
|
|
203
300
|
+ ' is negative zero, neither of which reads as a request to remove the bound.'
|
|
@@ -206,68 +303,115 @@ export function parseBudgetSeconds(raw) {
|
|
|
206
303
|
}
|
|
207
304
|
return seconds;
|
|
208
305
|
}
|
|
306
|
+
/** The hidden flag a supervisor hands the child it spawns, and nothing else passes. */
|
|
307
|
+
export const SUPERVISED_BY_FLAG = '--supervised-by';
|
|
308
|
+
/**
|
|
309
|
+
* The value of {@link SUPERVISED_BY_FLAG} for a child this process is about to spawn:
|
|
310
|
+
* `<invoker>:<this process's pid>:<progress log>`.
|
|
311
|
+
*
|
|
312
|
+
* The pid is what makes the flag unforgeable by accident: the child refuses it unless the pid
|
|
313
|
+
* named is its own parent's — see {@link requireSupervisableFlags}.
|
|
314
|
+
*
|
|
315
|
+
* @param child - Who asked, and where the progress goes (the supervisor is always this process)
|
|
316
|
+
* @returns The flag's value
|
|
317
|
+
*/
|
|
318
|
+
export function supervisedByValue(child) {
|
|
319
|
+
return `${child.invoker}:${String(process.pid)}:${child.progressLog}`;
|
|
320
|
+
}
|
|
209
321
|
/**
|
|
210
322
|
* Does this process do the work, or supervise a child that does?
|
|
211
323
|
*
|
|
212
|
-
* 🚨 **The recursion guard, and the reason it is a named function.** `--
|
|
213
|
-
*
|
|
214
|
-
* budget
|
|
215
|
-
*
|
|
216
|
-
*
|
|
324
|
+
* 🚨 **The recursion guard, and the reason it is a named function.** `--supervised-by` is what a
|
|
325
|
+
* supervising parent hands its child, and it must WIN against the budget — a child that consulted
|
|
326
|
+
* the budget first would spawn a child of its own, which would spawn a child of its own. A
|
|
327
|
+
* condition inline in the command would be a fork bomb one refactor away with nothing asserting
|
|
328
|
+
* on it.
|
|
217
329
|
*
|
|
218
|
-
* `--budget 0` also runs here: there is nothing to supervise, and a spawn would
|
|
219
|
-
*
|
|
330
|
+
* `--budget 0` also runs here: there is nothing to supervise, and a spawn would cost a second
|
|
331
|
+
* process startup to buy no bound at all.
|
|
220
332
|
*
|
|
221
333
|
* @param options - The run
|
|
222
|
-
* @param options.
|
|
334
|
+
* @param options.supervisedBy - The hidden `--supervised-by` value, or undefined
|
|
223
335
|
* @param options.budgetSecs - The bound in seconds; 0 means none
|
|
224
336
|
* @returns True when the checks run in this process
|
|
225
337
|
*/
|
|
226
338
|
export function runsInThisProcess(options) {
|
|
227
|
-
return options
|
|
339
|
+
return isSupervisedChild(options) || options.budgetSecs === 0;
|
|
228
340
|
}
|
|
229
341
|
/**
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* `--budget
|
|
246
|
-
*
|
|
342
|
+
* Read `--supervised-by` into the child it describes, refusing it unless this process really is
|
|
343
|
+
* the child of the supervisor it names — and refuse a `--budget` it would silently ignore.
|
|
344
|
+
*
|
|
345
|
+
* 🚨 **Not an operator's flag, and passing it by hand is refused, not tolerated.** It used to be
|
|
346
|
+
* harmless-looking: the process ran the checks unbounded, printed none of the notices its
|
|
347
|
+
* supervisor would have, and appended to a log nobody watched. A flag that silently removes the
|
|
348
|
+
* bound is the shape an operator never discovers until the hang it was meant to prevent. So the
|
|
349
|
+
* value names its supervisor's pid, and a process whose parent is not that pid is refused
|
|
350
|
+
* `USAGE_INVALID` in plain words.
|
|
351
|
+
*
|
|
352
|
+
* 🔑 **One value, so an invalid combination cannot be written.** The invoker and the progress log
|
|
353
|
+
* used to be two hidden flags that had to arrive together, refused when one came alone. Now they
|
|
354
|
+
* are fields of one value, and the only thing left to refuse is a value that does not parse.
|
|
355
|
+
*
|
|
356
|
+
* 🚨 **`--budget` beside it is refused.** The flag wins the fork in {@link runsInThisProcess}
|
|
357
|
+
* unconditionally, so `--budget 60` with it would run UNBOUNDED and say nothing. The RAW
|
|
358
|
+
* `--budget` is the discriminator, not the parsed seconds: the real spawn path never forwards
|
|
359
|
+
* `--budget`, so the child's `budgetSecs` is the default, not anything an operator typed.
|
|
360
|
+
* `--budget 0` beside it is allowed: both say "nobody is supervising this".
|
|
247
361
|
*
|
|
248
362
|
* @param options - The run
|
|
249
|
-
* @param options.
|
|
363
|
+
* @param options.supervisedBy - The hidden `--supervised-by` value, or undefined
|
|
250
364
|
* @param options.budgetRaw - What the operator actually typed for `--budget`
|
|
251
365
|
* @param options.budgetSecs - The parsed bound; 0 means none
|
|
252
|
-
* @
|
|
366
|
+
* @returns The supervised child this process is, or undefined when it is not one
|
|
367
|
+
* @throws When the flag does not parse, names a supervisor that is not this process's parent, or
|
|
368
|
+
* comes with a `--budget` it would ignore
|
|
253
369
|
*/
|
|
254
370
|
export function requireSupervisableFlags(options) {
|
|
255
|
-
if (options
|
|
256
|
-
return;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
371
|
+
if (!isSupervisedChild(options))
|
|
372
|
+
return undefined;
|
|
373
|
+
const child = parseSupervisedBy(options.supervisedBy);
|
|
374
|
+
if (options.budgetRaw !== undefined && options.budgetSecs !== 0) {
|
|
375
|
+
throw new CommandRefusalError('USAGE_INVALID', `--budget cannot be combined with ${SUPERVISED_BY_FLAG}. ${SUPERVISED_BY_FLAG} means "you are`
|
|
376
|
+
+ ' the child a supervisor already spawned", so this process does the work rather than'
|
|
377
|
+
+ ` bounding it, and the budget would be silently ignored. Drop ${SUPERVISED_BY_FLAG}:`
|
|
378
|
+
+ ' it is not an operator\'s flag, and --budget alone gets you the bound.');
|
|
379
|
+
}
|
|
380
|
+
return child;
|
|
264
381
|
}
|
|
382
|
+
/** `<invoker>:<supervisor pid>:<progress log>` — the log last, since a Windows path holds a colon. */
|
|
383
|
+
const SUPERVISED_BY_SHAPE = /^(?<invoker>standalone|phase):(?<pid>\d+):(?<progressLog>.+)$/;
|
|
265
384
|
/**
|
|
266
|
-
*
|
|
385
|
+
* Parse `--supervised-by`, and refuse it unless this process's parent is the supervisor it names.
|
|
386
|
+
*
|
|
387
|
+
* @param raw - The flag's value
|
|
388
|
+
* @returns The supervised child
|
|
389
|
+
* @throws `USAGE_INVALID` for a value that does not parse or names another process
|
|
390
|
+
*/
|
|
391
|
+
function parseSupervisedBy(raw) {
|
|
392
|
+
const notAnOperatorsFlag = `${SUPERVISED_BY_FLAG} is not an operator's flag: it is how`
|
|
393
|
+
+ ' `vat resources check` and `vat validate` hand the checks to the child process they'
|
|
394
|
+
+ ' spawn and supervise.';
|
|
395
|
+
const remedy = ' Run `vat resources check` without it — `--budget <seconds>` sets the bound,'
|
|
396
|
+
+ ' and `--budget 0` runs the checks in this process with none.';
|
|
397
|
+
const fields = SUPERVISED_BY_SHAPE.exec(raw)?.groups;
|
|
398
|
+
if (fields === undefined) {
|
|
399
|
+
throw new CommandRefusalError('USAGE_INVALID', `${notAnOperatorsFlag} "${raw}" is not a value a supervisor writes.${remedy}`);
|
|
400
|
+
}
|
|
401
|
+
const { invoker, pid, progressLog } = fields;
|
|
402
|
+
if (Number(pid) !== process.ppid) {
|
|
403
|
+
throw new CommandRefusalError('USAGE_INVALID', `${notAnOperatorsFlag} This process was not spawned by the supervisor it names (pid ${pid};`
|
|
404
|
+
+ ` this process's parent is ${String(process.ppid)}), so nothing is watching it: it would`
|
|
405
|
+
+ ` run with no bound and print none of the run's notices.${remedy}`);
|
|
406
|
+
}
|
|
407
|
+
return { invoker, supervisorPid: process.ppid, progressLog };
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Read `exit`'s two arguments, and the watchdog's belief, into one answer.
|
|
267
411
|
*
|
|
268
412
|
* ## 🚨 The defect this closes: a signal death READ AS SUCCESS
|
|
269
413
|
*
|
|
270
|
-
* `
|
|
414
|
+
* `exit` fires with `(code, signal)`, and a process that dies from a signal has
|
|
271
415
|
* `code === null` with `signal` set. This handler used to read only the code and
|
|
272
416
|
* coerce it — `resolve(exitCode ?? 0)` — so every signal death became a
|
|
273
417
|
* COMPLETED run with exit code 0. The parent then forwarded an empty stdout and
|
|
@@ -308,12 +452,12 @@ export function requireSupervisableFlags(options) {
|
|
|
308
452
|
* kill), and only then a failure to start. A run whose kill was refused must
|
|
309
453
|
* never claim the watchdog was uninvolved.
|
|
310
454
|
*
|
|
311
|
-
* @param ending - What `
|
|
312
|
-
* @param ending.code - `
|
|
313
|
-
* @param ending.signal - `
|
|
455
|
+
* @param ending - What `exit` reported, plus what the supervisor did and saw
|
|
456
|
+
* @param ending.code - `exit`'s first argument
|
|
457
|
+
* @param ending.signal - `exit`'s second argument
|
|
314
458
|
* @param ending.killed - Whether the watchdog sent SIGKILL
|
|
315
459
|
* @param ending.spawnError - Set when the child never started at all
|
|
316
|
-
* @param ending.killFailure - Set when the watchdog's SIGKILL was
|
|
460
|
+
* @param ending.killFailure - Set when the watchdog's SIGKILL was refused, or did not end the child
|
|
317
461
|
* @returns What actually happened
|
|
318
462
|
*/
|
|
319
463
|
export function resolveChildEnding(ending) {
|
|
@@ -337,13 +481,13 @@ export function resolveChildEnding(ending) {
|
|
|
337
481
|
*
|
|
338
482
|
* ## 🚨 A completion that PUBLISHED NOTHING did not complete
|
|
339
483
|
*
|
|
340
|
-
* {@link resolveChildEnding} answers a question about the process — what `
|
|
484
|
+
* {@link resolveChildEnding} answers a question about the process — what `exit`
|
|
341
485
|
* reported, reconciled with what the supervisor did. This answers a DIFFERENT
|
|
342
486
|
* one, about the artifact, and the two disagree in exactly one place: a child
|
|
343
487
|
* that exited with a code and wrote no document.
|
|
344
488
|
*
|
|
345
|
-
* Every in-process path through `checkCommand` ends at `
|
|
346
|
-
* `
|
|
489
|
+
* Every in-process path through `checkCommand` ends at `endWithReport` or at
|
|
490
|
+
* `endWithRefusal`, and both write to stdout — a clean pass, a violation, a
|
|
347
491
|
* bricked config, a mistyped `--check`. There is no exit this command can take
|
|
348
492
|
* that legitimately publishes nothing. So an empty stdout is not a quiet run, it
|
|
349
493
|
* is a run that was cut off before it could say anything, and forwarding its
|
|
@@ -357,11 +501,10 @@ export function resolveChildEnding(ending) {
|
|
|
357
501
|
* ordering argument that has already been got wrong twice. It runs AFTER, on the
|
|
358
502
|
* one branch it can change, and it changes no other.
|
|
359
503
|
*
|
|
360
|
-
* ⚠️ **Blank, not unparseable.**
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
* limit of this test rather than an oversight.
|
|
504
|
+
* ⚠️ **Blank, not unparseable.** This asks only whether anything was written.
|
|
505
|
+
* Whether the bytes parse is asked next, by {@link readCompletedDocument}, which
|
|
506
|
+
* knows the format: a truncated document — an abort that landed mid-write — is
|
|
507
|
+
* the sibling `unparseable-output` death, and ends the same way.
|
|
365
508
|
*
|
|
366
509
|
* @param resolution - How the process ended
|
|
367
510
|
* @param stdout - Everything the child wrote to stdout
|
|
@@ -375,15 +518,19 @@ export function resolveSilentCompletion(resolution, stdout) {
|
|
|
375
518
|
/**
|
|
376
519
|
* Run `vat resources check` as a child, bounded by the budget.
|
|
377
520
|
*
|
|
378
|
-
* `stdio` is `['
|
|
379
|
-
*
|
|
380
|
-
*
|
|
521
|
+
* `stdio` is `['pipe', 'pipe', 'inherit']`. Its stdin is a pipe this process
|
|
522
|
+
* holds open and NEVER writes to or ends: it exists only so that the child reads
|
|
523
|
+
* end-of-file the moment this process is gone, however it went (see
|
|
524
|
+
* `endWhenSupervisorGone`). Node closes this end itself once the child has
|
|
525
|
+
* exited. The child's stdout is accumulated so the parent can forward the
|
|
526
|
+
* document verbatim, and its stderr is INHERITED so warnings and blob-stage
|
|
527
|
+
* refusals stream live exactly as they do today.
|
|
381
528
|
*
|
|
382
529
|
* ⚠️ Asynchronous `spawn`, never `spawnSync`. The parent's event loop is the
|
|
383
530
|
* thing holding the watchdog timer; a synchronous spawn would block it for
|
|
384
531
|
* precisely as long as the run it is supposed to be bounding.
|
|
385
532
|
*
|
|
386
|
-
* 🚨 There is an `error` listener as well as
|
|
533
|
+
* 🚨 There is an `error` listener as well as an `exit` one, and it is not
|
|
387
534
|
* optional politeness: without it an unspawnable binary is an unhandled `error`
|
|
388
535
|
* event, which Node turns into a stack dump instead of a report. It fails
|
|
389
536
|
* closed, so this is legibility — but a stack dump is not a report.
|
|
@@ -421,20 +568,32 @@ export function resolveSilentCompletion(resolution, stdout) {
|
|
|
421
568
|
* contorted to make it testable; the branch ordering and the message
|
|
422
569
|
* composition are pure functions and are pinned as such.
|
|
423
570
|
*
|
|
571
|
+
* ⏱️ Every interval is read off `performance.now()`, the monotonic clock: a
|
|
572
|
+
* wall clock stepped by NTP or an operator would grow or shrink the budget.
|
|
573
|
+
*
|
|
424
574
|
* @param options - The run
|
|
425
|
-
* @param options.args - The child's argv after the node binary, `--
|
|
426
|
-
* @param options.
|
|
575
|
+
* @param options.args - The child's argv after the node binary, `--supervised-by` included
|
|
576
|
+
* @param options.log - The progress log both sides agreed on, and the guard {@link withProgressLog} holds over it
|
|
427
577
|
* @param options.budgetMs - How long silence is allowed to last
|
|
578
|
+
* @param options.format - The format the child was asked for, to read its document in
|
|
428
579
|
* @returns How the child ended, and what it left behind
|
|
429
580
|
*/
|
|
430
581
|
export async function superviseCheck(options) {
|
|
431
|
-
const
|
|
582
|
+
const logPath = options.log.path;
|
|
583
|
+
const startedAt = performance.now();
|
|
432
584
|
const binary = resolveVatBinPath();
|
|
433
585
|
const child = spawn(process.execPath, [binary, ...options.args], {
|
|
434
|
-
|
|
586
|
+
// ⛔ Never `detached`. A process-group leader is outside the terminal's job control: Ctrl-Z
|
|
587
|
+
// does not stop it, and under `stty tostop` its stderr write stops it with SIGTTOU, so the
|
|
588
|
+
// watchdog false-kills a healthy run. In this process's group it receives a terminal Ctrl-C
|
|
589
|
+
// itself — see `CHECKS_CHILD_TREE` for what that costs.
|
|
590
|
+
stdio: ['pipe', 'pipe', 'inherit'],
|
|
435
591
|
});
|
|
592
|
+
// The guard `withProgressLog` installed now takes this child down with the process too.
|
|
593
|
+
options.log.guard.watch(child);
|
|
436
594
|
const chunks = [];
|
|
437
595
|
child.stdout?.on('data', (chunk) => chunks.push(chunk));
|
|
596
|
+
let exited = false;
|
|
438
597
|
let killed = false;
|
|
439
598
|
let killAttempts = 0;
|
|
440
599
|
let killFailure;
|
|
@@ -445,15 +604,15 @@ export async function superviseCheck(options) {
|
|
|
445
604
|
// put the escalation out of the timer's reach and force the `error` handler
|
|
446
605
|
// back into resolving on a child that is still alive.
|
|
447
606
|
let timer;
|
|
448
|
-
const resolution = await new Promise((resolve) => {
|
|
607
|
+
const resolution = await new Promise((resolve, reject) => {
|
|
449
608
|
// 🪤 `error` does not always end the process, and it is not always followed
|
|
450
|
-
// by `
|
|
609
|
+
// by `exit` — so a SPAWN failure is remembered and resolved on immediately.
|
|
451
610
|
// A promise settles once, so whichever event arrives first wins and the
|
|
452
611
|
// other is a no-op. A failed KILL is the opposite case: see this function's
|
|
453
612
|
// header for why it must not settle here.
|
|
454
613
|
child.on('error', (cause) => {
|
|
455
614
|
if (killed) {
|
|
456
|
-
killFailure = { detail: cause.message, pid: child.pid };
|
|
615
|
+
killFailure = { detail: cause.message, pid: child.pid, refused: true };
|
|
457
616
|
return;
|
|
458
617
|
}
|
|
459
618
|
spawnError = { binary, detail: cause.message };
|
|
@@ -461,42 +620,237 @@ export async function superviseCheck(options) {
|
|
|
461
620
|
});
|
|
462
621
|
// ⛔ BOTH arguments. `exitCode ?? 0` here read every signal death as a
|
|
463
622
|
// successful run — see {@link resolveChildEnding}.
|
|
464
|
-
|
|
465
|
-
|
|
623
|
+
//
|
|
624
|
+
// 🔑 The child's death is its `exit`, never its `close`: `close` waits for every holder of its
|
|
625
|
+
// stdout, and a grandchild (a `git` it spawned) can hold that for ever — the watchdog then
|
|
626
|
+
// went on killing a child already dead and reported a kill that "did not land". `close` only
|
|
627
|
+
// collects the rest of stdout, and gets a bounded grace to do it (`awaitStdout`).
|
|
628
|
+
child.on('exit', (code, signal) => {
|
|
629
|
+
exited = true;
|
|
630
|
+
awaitStdout(child, () => {
|
|
631
|
+
resolve(resolveChildEnding({ code, signal, killed, spawnError, killFailure }));
|
|
632
|
+
});
|
|
466
633
|
});
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
634
|
+
const poll = () => {
|
|
635
|
+
if (exited)
|
|
636
|
+
return;
|
|
637
|
+
const reading = pollWatchdog(state, {
|
|
638
|
+
bytes: logSize(logPath),
|
|
639
|
+
now: performance.now(),
|
|
471
640
|
budgetMs: options.budgetMs,
|
|
472
641
|
});
|
|
473
|
-
state =
|
|
474
|
-
if (!
|
|
642
|
+
state = reading.state;
|
|
643
|
+
if (!reading.breach)
|
|
475
644
|
return;
|
|
476
645
|
killed = true;
|
|
477
646
|
killAttempts += 1;
|
|
478
647
|
// SIGKILL, because no code the child could ever gain can handle, ignore
|
|
479
648
|
// or block it. See this module's header — and note the reason is NOT that
|
|
480
649
|
// SIGTERM fails to reach a blocked process, which was measured false.
|
|
481
|
-
child
|
|
482
|
-
|
|
483
|
-
|
|
650
|
+
killProcessTree(child, CHECKS_CHILD_TREE);
|
|
651
|
+
const unended = unendedKill(killAttempts, killFailure, child.pid);
|
|
652
|
+
if (unended !== undefined)
|
|
653
|
+
resolve(resolveChildEnding({ code: null, signal: null, killed, killFailure: unended }));
|
|
654
|
+
};
|
|
655
|
+
// 🚨 A poll that THROWS — a progress log this process can no longer stat — has no reading,
|
|
656
|
+
// and the timer is outside every caller's `try`: uncaught, it reached the CLI's last-resort
|
|
657
|
+
// handler, which exits 2 with NO document, and `vat validate` lost the phases that had
|
|
658
|
+
// finished. So the throw ends the supervision here, the one place that can: kill the child
|
|
659
|
+
// (nothing bounds it once the timer stops), stop the timer, and REJECT, so the caller
|
|
660
|
+
// publishes it — `vat validate` as RUN_INCOMPLETE, `vat resources check` as its refusal.
|
|
661
|
+
// The `exit` guard stays behind this as the second line.
|
|
662
|
+
timer = setInterval(() => {
|
|
663
|
+
try {
|
|
664
|
+
poll();
|
|
665
|
+
}
|
|
666
|
+
catch (error) {
|
|
667
|
+
clearInterval(timer);
|
|
668
|
+
killProcessTree(child, CHECKS_CHILD_TREE);
|
|
669
|
+
reject(error);
|
|
484
670
|
}
|
|
485
671
|
}, pollIntervalMs(options.budgetMs));
|
|
486
672
|
});
|
|
487
673
|
clearInterval(timer);
|
|
488
674
|
const stdout = Buffer.concat(chunks).toString('utf-8');
|
|
489
675
|
// 🚨 AFTER the ending is resolved, never inside it. A child that exited with a
|
|
490
|
-
// code and published nothing did not complete, whatever `
|
|
676
|
+
// code and published nothing did not complete, whatever `exit` said — see
|
|
491
677
|
// {@link resolveSilentCompletion} for the platform this is about.
|
|
492
678
|
const ending = resolveSilentCompletion(resolution, stdout);
|
|
679
|
+
const wreckage = () => ({ log: readLog(logPath), elapsedMs: performance.now() - startedAt });
|
|
493
680
|
if (ending.kind === 'completed') {
|
|
494
|
-
|
|
681
|
+
// Read while the progress log still exists: a document that is not one is
|
|
682
|
+
// a death, and the log is what its interrupted document is built from.
|
|
683
|
+
const read = readCompletedDocument(stdout, ending.code, options.format);
|
|
684
|
+
return 'document' in read
|
|
685
|
+
? { outcome: 'completed', document: read.document }
|
|
686
|
+
: { outcome: 'abnormal', death: read.death, ...wreckage() };
|
|
495
687
|
}
|
|
496
|
-
const wreckage = { log: readLog(options.logPath), elapsedMs: Date.now() - startedAt };
|
|
497
688
|
return ending.kind === 'killed'
|
|
498
|
-
? { outcome: 'killed', ...wreckage }
|
|
499
|
-
: { outcome: 'abnormal', death: ending.death, ...wreckage };
|
|
689
|
+
? { outcome: 'killed', ...wreckage() }
|
|
690
|
+
: { outcome: 'abnormal', death: ending.death, ...wreckage() };
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* How long, once the child has exited, the rest of its stdout is given to arrive.
|
|
694
|
+
*
|
|
695
|
+
* The child writes its document synchronously before it exits, so all that can still be in flight
|
|
696
|
+
* is one pipe buffer, read in milliseconds. A wait past this is a GRANDCHILD holding the write end
|
|
697
|
+
* open — and that wait has no end.
|
|
698
|
+
*/
|
|
699
|
+
const STDOUT_GRACE_AFTER_EXIT_MS = 2000;
|
|
700
|
+
/**
|
|
701
|
+
* Call `settle` once the exited child's stdout has closed — or once
|
|
702
|
+
* {@link STDOUT_GRACE_AFTER_EXIT_MS} has passed, with whatever was read by then, and the stream
|
|
703
|
+
* destroyed so a grandchild holding it cannot hold this process open either.
|
|
704
|
+
*
|
|
705
|
+
* @param child - A child that has emitted `exit`
|
|
706
|
+
* @param settle - Called exactly once
|
|
707
|
+
*/
|
|
708
|
+
function awaitStdout(child, settle) {
|
|
709
|
+
const grace = setTimeout(() => {
|
|
710
|
+
child.removeListener('close', onClose);
|
|
711
|
+
child.stdout?.destroy();
|
|
712
|
+
settle();
|
|
713
|
+
}, STDOUT_GRACE_AFTER_EXIT_MS);
|
|
714
|
+
function onClose() {
|
|
715
|
+
clearTimeout(grace);
|
|
716
|
+
settle();
|
|
717
|
+
}
|
|
718
|
+
child.once('close', onClose);
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* The kill that did not end the child, once the watchdog has tried long enough to say so — or
|
|
722
|
+
* undefined while it should keep trying.
|
|
723
|
+
*
|
|
724
|
+
* A REFUSED kill is reported after {@link KILL_ATTEMPTS_BEFORE_REPORTING} attempts; an ACCEPTED one
|
|
725
|
+
* that has not ended the child after {@link KILL_POLLS_BEFORE_REPORTING_UNREAPED}. Either way the
|
|
726
|
+
* supervision settles, naming the pid, rather than polling forever.
|
|
727
|
+
*
|
|
728
|
+
* @param killAttempts - SIGKILLs sent so far, one per breaching poll
|
|
729
|
+
* @param refusal - Set when the kernel refused a SIGKILL
|
|
730
|
+
* @param pid - The child's pid
|
|
731
|
+
* @returns The failure to settle on, or undefined to keep trying
|
|
732
|
+
*/
|
|
733
|
+
function unendedKill(killAttempts, refusal, pid) {
|
|
734
|
+
if (refusal !== undefined)
|
|
735
|
+
return killAttempts >= KILL_ATTEMPTS_BEFORE_REPORTING ? refusal : undefined;
|
|
736
|
+
if (killAttempts < KILL_POLLS_BEFORE_REPORTING_UNREAPED)
|
|
737
|
+
return undefined;
|
|
738
|
+
return {
|
|
739
|
+
detail: `SIGKILL was accepted ${String(killAttempts)} times and the process had still not ended`,
|
|
740
|
+
pid,
|
|
741
|
+
refused: false,
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* While a supervision lives, make every way THIS process ends take the child and the progress
|
|
746
|
+
* directory with it.
|
|
747
|
+
*
|
|
748
|
+
* ## 🚨 The defect: a supervisor that ended without its child orphaned an unbounded run
|
|
749
|
+
*
|
|
750
|
+
* The bound is enforced by this process's timer. Anything that ends this process ends the timer —
|
|
751
|
+
* and the child it was bounding was reparented and kept running with nothing left to stop it: the
|
|
752
|
+
* exact unbounded hang the supervisor exists to abolish. Measured ways in: a SIGTERM, SIGHUP or
|
|
753
|
+
* SIGINT sent to this pid alone; an uncaught throw anywhere in this process (the last-resort handler
|
|
754
|
+
* ends it with `process.exit` — the poll's own throw is caught in {@link superviseCheck}, so this is
|
|
755
|
+
* the second line for it); and a kill the kernel refused, which settles the run while the child
|
|
756
|
+
* lives on.
|
|
757
|
+
*
|
|
758
|
+
* So for the supervision's WHOLE life — from before the progress directory is minted until after
|
|
759
|
+
* it is removed, see {@link withProgressLog}:
|
|
760
|
+
*
|
|
761
|
+
* - **`exit`** SIGKILLs the child (`CHECKS_CHILD_TREE`), once there is one and while it runs, and removes the progress directory, once there is one — every ending of this process that
|
|
762
|
+
* runs any of its code passes through it, a last-resort `process.exit` included, and
|
|
763
|
+
* `process.exit` runs no `finally`.
|
|
764
|
+
* - **Every `TERMINATING_SIGNALS` member**, through `handleTerminatingSignals`: does the same,
|
|
765
|
+
* synchronously, and RE-RAISES the signal. On POSIX this process then dies of it (status 128 + n),
|
|
766
|
+
* as a shell and a CI runner expect. On Windows, or where the signal cannot kill it (PID 1), it
|
|
767
|
+
* exits 2 with no document. A repeat with the first is swallowed. The child shares this
|
|
768
|
+
* process's group, so a terminal's Ctrl-C reaches it directly too and, with no handler of its
|
|
769
|
+
* own, ends it; this guard kills it all the same.
|
|
770
|
+
*
|
|
771
|
+
* The release waits for the child's `exit`, not for the run to settle, so a run settled with its
|
|
772
|
+
* child still alive (a refused kill, a poll that threw) still takes the child down however this
|
|
773
|
+
* process then ends.
|
|
774
|
+
*
|
|
775
|
+
* The module header gives why SIGKILL, and why the CHILD must never install a handler. This
|
|
776
|
+
* process may: its event loop is never blocked, which is what makes a handler fire at all.
|
|
777
|
+
*
|
|
778
|
+
* ## ⚠️ What no guard here reaches
|
|
779
|
+
*
|
|
780
|
+
* An ending that runs none of this process's code: SIGKILL, an OOM killer, and on Windows ANY
|
|
781
|
+
* outside kill — `process.kill(pid, <signal>)` there is `TerminateProcess`, which runs neither a
|
|
782
|
+
* signal handler nor the `exit` guard. On Windows the OS ends the child with this process (libuv's
|
|
783
|
+
* kill-on-close job object — see the module header). On POSIX the child covers those itself: it
|
|
784
|
+
* reads end-of-file on the stdin pipe this process held (`endWhenSupervisorGone`). A child blocked
|
|
785
|
+
* inside one SQLite statement reaches nothing until the statement returns.
|
|
786
|
+
*
|
|
787
|
+
* @returns The guard: `cover` names the progress log once it exists, `watch` the child once it is
|
|
788
|
+
* spawned, and `release` ends the guard — at once, or at the watched child's `exit`
|
|
789
|
+
*/
|
|
790
|
+
function guardSupervision() {
|
|
791
|
+
let child;
|
|
792
|
+
let logPath;
|
|
793
|
+
let takenDown = false;
|
|
794
|
+
// Synchronous, so a signal ends this process inside its own turn — nothing publishes meanwhile.
|
|
795
|
+
const takeDown = () => {
|
|
796
|
+
if (takenDown)
|
|
797
|
+
return;
|
|
798
|
+
takenDown = true;
|
|
799
|
+
// 🚨 Only a child still running: one that has exited may be reaped, and its pid reused by a
|
|
800
|
+
// stranger the kill would then reach.
|
|
801
|
+
if (child?.exitCode === null && child.signalCode === null)
|
|
802
|
+
killProcessTree(child, CHECKS_CHILD_TREE);
|
|
803
|
+
if (logPath !== undefined)
|
|
804
|
+
disposeProgressDir(logPath);
|
|
805
|
+
};
|
|
806
|
+
const signals = handleTerminatingSignals({ cleanup: takeDown, fallbackExitCode: ExitCode.ERROR });
|
|
807
|
+
function releaseAll() {
|
|
808
|
+
signals.release();
|
|
809
|
+
process.off('exit', takeDown);
|
|
810
|
+
}
|
|
811
|
+
process.once('exit', takeDown);
|
|
812
|
+
return {
|
|
813
|
+
cover: (path) => {
|
|
814
|
+
logPath = path;
|
|
815
|
+
},
|
|
816
|
+
watch: (spawned) => {
|
|
817
|
+
child = spawned;
|
|
818
|
+
},
|
|
819
|
+
release: () => {
|
|
820
|
+
// Still running: hold every handler until it is gone — its `exit`, not its `close`, which a
|
|
821
|
+
// grandchild holding its stdout can delay for ever. Gone, never started, or never spawned:
|
|
822
|
+
// nothing left to take down.
|
|
823
|
+
if (child?.pid !== undefined && child.exitCode === null && child.signalCode === null)
|
|
824
|
+
child.once('exit', releaseAll);
|
|
825
|
+
else
|
|
826
|
+
releaseAll();
|
|
827
|
+
},
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* How the checks child is killed.
|
|
832
|
+
*
|
|
833
|
+
* POSIX: its pid alone. It shares this process's group (never `detached`, see
|
|
834
|
+
* {@link superviseCheck}), so there is no group of its own to kill: a process it started (`git`)
|
|
835
|
+
* is not killed with it and ends on its own. It is killed through `child.kill` FIRST, because that
|
|
836
|
+
* is the call whose refusal Node reports as the child's `error` — the arm the watchdog retries and
|
|
837
|
+
* then reports — and, on Windows, the only kill whose signal `exit` then reports: a `taskkill`
|
|
838
|
+
* first made the watchdog's kill read as the child exiting 1 on its own. Windows then sweeps the
|
|
839
|
+
* tree with `taskkill /T`, best-effort (see `killProcessTree`).
|
|
840
|
+
*/
|
|
841
|
+
const CHECKS_CHILD_TREE = { groupLeader: false, throughChild: true };
|
|
842
|
+
/**
|
|
843
|
+
* Remove the progress log's directory, synchronously, on the way out of this process — and say so
|
|
844
|
+
* on stderr when the OS would not, since no report will carry it. `disposeTempDirSync` retries a
|
|
845
|
+
* transient refusal briefly: on Windows the child just terminated still holds its handles for a
|
|
846
|
+
* moment.
|
|
847
|
+
*
|
|
848
|
+
* @param logPath - The progress log
|
|
849
|
+
*/
|
|
850
|
+
function disposeProgressDir(logPath) {
|
|
851
|
+
const leftover = disposeTempDirSync(dirname(logPath));
|
|
852
|
+
if (leftover !== undefined)
|
|
853
|
+
process.stderr.write(`${errorMessageOf(leftover)}\n`);
|
|
500
854
|
}
|
|
501
855
|
/**
|
|
502
856
|
* How often to look at the log.
|
|
@@ -520,14 +874,17 @@ function pollIntervalMs(budgetMs) {
|
|
|
520
874
|
* ONLY a missing file. The log lives in a directory this process minted, so a
|
|
521
875
|
* refusal to stat it is not a state the watchdog has a reading for — and the
|
|
522
876
|
* reading it used to take, 0 forever, is "the child has gone quiet", which
|
|
523
|
-
* kills a child that may be doing fine and reports it as a runaway.
|
|
877
|
+
* kills a child that may be doing fine and reports it as a runaway. So it throws,
|
|
878
|
+
* and {@link superviseCheck} ends the supervision on the throw: the child killed,
|
|
879
|
+
* the run reported as one that did not finish.
|
|
524
880
|
*
|
|
525
881
|
* @param path - The progress log
|
|
526
882
|
* @returns Its size in bytes
|
|
527
883
|
*/
|
|
528
884
|
function logSize(path) {
|
|
529
885
|
try {
|
|
530
|
-
|
|
886
|
+
// A file in a directory this process minted: its own `within`.
|
|
887
|
+
return requireFollowedStatSync(path, path).size;
|
|
531
888
|
}
|
|
532
889
|
catch (error) {
|
|
533
890
|
if (isPathAbsentError(error))
|
|
@@ -552,22 +909,65 @@ function readLog(path) {
|
|
|
552
909
|
}
|
|
553
910
|
}
|
|
554
911
|
/**
|
|
555
|
-
* Run `work` with a fresh progress log, and remove it however that ends.
|
|
912
|
+
* Run `work` with a fresh progress log, and remove it however that ends — a signal included.
|
|
556
913
|
*
|
|
557
914
|
* ⚠️ Ephemeral, per run, and it carries NO format version — see
|
|
558
915
|
* `check-progress.ts`. It is written and read by one process pair within one run
|
|
559
916
|
* of one build, so the reader's own `.strict()` schema is the entire contract.
|
|
560
917
|
*
|
|
561
|
-
* @
|
|
562
|
-
*
|
|
918
|
+
* 🔑 The guard ({@link guardSupervision}) is installed BEFORE the directory is
|
|
919
|
+
* minted and released only AFTER it is removed, so a signal in either window —
|
|
920
|
+
* not only while the child runs — still removes it. One guard, one lifetime.
|
|
921
|
+
*
|
|
922
|
+
* @param work - Given the log
|
|
923
|
+
* @returns What `work` returned, with the log's directory as a `leftover` when the OS
|
|
924
|
+
* would not remove it (see `withTempDir`) — for the caller to report as a warning
|
|
563
925
|
*/
|
|
564
926
|
export async function withProgressLog(work) {
|
|
565
|
-
const
|
|
927
|
+
const guard = guardSupervision();
|
|
566
928
|
try {
|
|
567
|
-
return await
|
|
929
|
+
return await withTempDir('vat-check-', (dir) => {
|
|
930
|
+
const path = safePath.join(dir, 'progress.jsonl');
|
|
931
|
+
guard.cover(path);
|
|
932
|
+
return work({ path, guard });
|
|
933
|
+
});
|
|
568
934
|
}
|
|
569
935
|
finally {
|
|
570
|
-
|
|
936
|
+
guard.release();
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* Read what a COMPLETED child wrote as `resources check`'s document, or name
|
|
941
|
+
* the death when it is not one — or when the child's exit disagrees with it.
|
|
942
|
+
*
|
|
943
|
+
* 🔑 The exit is compared with the one the document itself derives. The parent
|
|
944
|
+
* forwards the DOCUMENT's code, never the process's, so a child that wrote a
|
|
945
|
+
* clean report and then exited non-zero would otherwise be published as a pass.
|
|
946
|
+
*
|
|
947
|
+
* @param stdout - Everything the child wrote (known not to be blank)
|
|
948
|
+
* @param code - The child's exit code
|
|
949
|
+
* @param format - The format the child was asked for
|
|
950
|
+
* @returns The forwardable document, or the `unparseable-output` / `exit-disagrees` death
|
|
951
|
+
*/
|
|
952
|
+
export function readCompletedDocument(stdout, code, format) {
|
|
953
|
+
let document;
|
|
954
|
+
try {
|
|
955
|
+
document = readForwardedDocument('resources check', stdout, format);
|
|
956
|
+
}
|
|
957
|
+
catch (error) {
|
|
958
|
+
return { death: { kind: 'unparseable-output', code, detail: errorMessageOf(error) } };
|
|
571
959
|
}
|
|
960
|
+
const documentExit = exitCodeForReport(document.report);
|
|
961
|
+
return documentExit === code
|
|
962
|
+
? { document }
|
|
963
|
+
: { death: { kind: 'exit-disagrees', code, documentExit } };
|
|
572
964
|
}
|
|
965
|
+
/** Test-facing seam: the pure decisions of this module, reached by its unit tests. */
|
|
966
|
+
export const __internal = {
|
|
967
|
+
pollIntervalMs,
|
|
968
|
+
guardSupervision,
|
|
969
|
+
KILL_ATTEMPTS_BEFORE_REPORTING,
|
|
970
|
+
KILL_POLLS_BEFORE_REPORTING_UNREAPED,
|
|
971
|
+
STDOUT_GRACE_AFTER_EXIT_MS,
|
|
972
|
+
};
|
|
573
973
|
//# sourceMappingURL=check-supervisor.js.map
|