@vibe-agent-toolkit/cli 0.2.0-rc.11 → 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 +95 -43
- package/dist/bin/vat.d.ts +15 -4
- package/dist/bin/vat.d.ts.map +1 -1
- package/dist/bin/vat.js +95 -43
- 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 +21 -65
- package/dist/commands/ard/emit.d.ts.map +1 -1
- package/dist/commands/ard/emit.js +68 -74
- 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 +14 -11
- 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 +405 -411
- 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 +55 -2
- package/dist/commands/claude/context.d.ts.map +1 -1
- package/dist/commands/claude/context.js +74 -50
- 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 +6 -5
- 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 -149
- package/dist/commands/okf/validate.d.ts.map +1 -1
- package/dist/commands/okf/validate.js +64 -62
- 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 +64 -11
- package/dist/commands/resources/check-progress.d.ts.map +1 -1
- package/dist/commands/resources/check-progress.js +77 -4
- 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 +315 -71
- package/dist/commands/resources/check-supervisor.d.ts.map +1 -1
- package/dist/commands/resources/check-supervisor.js +493 -107
- package/dist/commands/resources/check-supervisor.js.map +1 -1
- package/dist/commands/resources/check.d.ts +56 -249
- package/dist/commands/resources/check.d.ts.map +1 -1
- package/dist/commands/resources/check.js +416 -276
- 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 +165 -91
- 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 +17 -12
- package/dist/commands/resources/query.d.ts.map +1 -1
- package/dist/commands/resources/query.js +60 -48
- 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 -78
- 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 -32
- 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 +6 -4
- 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 +17 -10
- 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 +76 -32
- package/dist/utils/resource-loader.d.ts.map +1 -1
- package/dist/utils/resource-loader.js +132 -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 +16 -19
- 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 +224 -106
- 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 +242 -108
- 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 -194
- package/dist/utils/command-error.d.ts.map +0 -1
- package/dist/utils/command-error.js +0 -237
- package/dist/utils/command-error.js.map +0 -1
|
@@ -6,23 +6,22 @@
|
|
|
6
6
|
* packaging config (schema defaults -> config defaults -> per-skill overrides),
|
|
7
7
|
* validates, and packages into dist/skills/<name>/.
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { allowUnusedIssues, calculateValidationStatus, countBySeverity, createAllowUsageLedger, } from '@vibe-agent-toolkit/schema';
|
|
13
|
-
import { safePath, toForwardSlash } from '@vibe-agent-toolkit/utils';
|
|
9
|
+
import { conventionalSuiteProbe, indexPluginLocalSkills, isSkillPackagingInputError, packageSkills, packagingConfigToPackageOptions, reanchorStagedResult, skillNameToFsPath, stagedPathMapper, validateSkillForPackaging, } from '@vibe-agent-toolkit/agent-skills';
|
|
10
|
+
import { allowUnusedIssues, buildReport, createAllowUsageLedger, toFindings, } from '@vibe-agent-toolkit/schema';
|
|
11
|
+
import { applyTreePlan, forEachInOrder, isFsFaultError, planTreeChanges, safePath, toForwardSlash, TreeRollbackIncompleteError, VatError, } from '@vibe-agent-toolkit/utils';
|
|
14
12
|
import { Command } from 'commander';
|
|
15
|
-
import
|
|
16
|
-
import { reportCommandError } from '../../utils/command-error.js';
|
|
13
|
+
import { errorMessageOf, refusalCodeOf, withFsFaultRemedy } from '../../utils/command-refusal.js';
|
|
17
14
|
import { loadConfig } from '../../utils/config-loader.js';
|
|
18
|
-
import {
|
|
15
|
+
import { endWithReport, leftoverFindingsOf, leftoverIssue, NOTHING_FINISHED, refusalReport } from '../../utils/document-writer.js';
|
|
16
|
+
import { collectPostBuildIssues, countCollapsedFindings, formatCollapsedFindingsHint, formatIssueLines, formatIssueSetHeading, formatPackagedFileCount, formatRunIssueLines, issuesToRenderAtVerbosity, } from '../../utils/issue-rendering.js';
|
|
19
17
|
import { requireProjectRoot } from '../../utils/project-root-policy.js';
|
|
18
|
+
import { relativeLocationOrUndefined } from '../../utils/relativize-paths.js';
|
|
20
19
|
import { withResourcePopulationSource } from '../../utils/resource-loader.js';
|
|
20
|
+
import { verdictBanner } from '../../utils/run-integrity.js';
|
|
21
21
|
import { collectDeclaredEvalSuites, mergeSkillPackagingConfig, publishScope } from '../../utils/skill-packaging-config.js';
|
|
22
22
|
import { applyConfigVerdicts } from '../../utils/verdict-helpers.js';
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import { rejectUnscopablePath } from './scope-guard.js';
|
|
23
|
+
import { filterSkillsByName, setupCommandContext, } from './command-helpers.js';
|
|
24
|
+
import { assertScopableSkillsPath } from './scope-guard.js';
|
|
26
25
|
import { discoverSkillsFromConfig } from './skill-discovery.js';
|
|
27
26
|
/**
|
|
28
27
|
* What a mis-scoped `vat skills build` used to do.
|
|
@@ -46,10 +45,7 @@ export function createBuildCommand() {
|
|
|
46
45
|
.option('--dry-run', 'Preview build without creating files')
|
|
47
46
|
.option('-v, --verbose', 'Show every individual finding, not just the errors')
|
|
48
47
|
.option('--debug', 'Enable debug logging')
|
|
49
|
-
.action(
|
|
50
|
-
rejectUnscopablePath(SCOPE_SUBJECT, pathArg);
|
|
51
|
-
await buildCommand(pathArg, options);
|
|
52
|
-
})
|
|
48
|
+
.action(buildCommand)
|
|
53
49
|
.addHelpText('after', `
|
|
54
50
|
Description:
|
|
55
51
|
Discovers SKILL.md files using include/exclude globs from the skills
|
|
@@ -69,7 +65,6 @@ Description:
|
|
|
69
65
|
claude phase that packages it.
|
|
70
66
|
|
|
71
67
|
Config Structure (vibe-agent-toolkit.config.yaml):
|
|
72
|
-
version: 1
|
|
73
68
|
skills:
|
|
74
69
|
include: ["resources/skills/**/SKILL.md"]
|
|
75
70
|
exclude: ["resources/skills/draft/**"]
|
|
@@ -96,98 +91,51 @@ Validation:
|
|
|
96
91
|
See docs/validation-codes.md for all codes and their defaults.
|
|
97
92
|
|
|
98
93
|
Output:
|
|
99
|
-
YAML
|
|
100
|
-
|
|
94
|
+
YAML report -> stdout: status (ok | findings | error), summary, examined
|
|
95
|
+
(skills discovered after --skill, the publish: false ones and a dry run's
|
|
96
|
+
included), findings (every finding, each with its location), and data:
|
|
97
|
+
dryRun, validated (false when nothing was validated: a dry run, a refused
|
|
98
|
+
--skill), skillsBuilt, skillsFailed (packaging refused the skill's content:
|
|
99
|
+
SKILL_PACKAGING_FAILED), skillsFailedValidation (the pre-build source check
|
|
100
|
+
rejected them), skillsInPlace / skillsPluginOnly (names set aside by
|
|
101
|
+
publish: false), outputCommitted (whether dist/skills was REPLACED — false
|
|
102
|
+
leaves the previous output untouched), promotionError (only when the
|
|
103
|
+
promotion itself failed), and skills[] of { name, source, output, status }
|
|
104
|
+
(status ok | findings, or not-built when nothing was validated or built: a
|
|
105
|
+
dry run, a refusal before the build). A TREE_CLEANUP_INCOMPLETE warning
|
|
106
|
+
names what the run made and could not remove (a replaced dist/skills
|
|
107
|
+
parked beside the new one, a discarded staging tree).
|
|
108
|
+
Paths are relative to the directory holding vibe-agent-toolkit.config.yaml.
|
|
109
|
+
Build progress -> stderr
|
|
101
110
|
|
|
102
111
|
On stderr, every findings heading names its skill, the whole set and its
|
|
103
112
|
severity breakdown, and errors are always printed in full beneath it.
|
|
104
|
-
Warnings and info findings stay collapsed
|
|
105
|
-
|
|
106
|
-
carries 348 LINK_DROPPED_BY_DEPTH warnings alone); one line at the end of
|
|
107
|
-
the run names how many were collapsed.
|
|
108
|
-
|
|
109
|
-
--verbose changes the stderr report ONLY. The stdout YAML is identical at
|
|
110
|
-
either verbosity: every row carries its full issues array (code, message,
|
|
111
|
-
location, fix) whether or not the human report printed it, because filtering
|
|
112
|
-
a machine-readable document by a human report's verbosity breaks the
|
|
113
|
-
consumers that parse it.
|
|
114
|
-
|
|
115
|
-
skills: one row per skill whose bundle EXISTS on disk — empty
|
|
116
|
-
whenever outputCommitted is false
|
|
117
|
-
skillsStaged: the same rows for a run that built its bundles and then
|
|
118
|
-
aborted the promotion. Deliberately a different key, and
|
|
119
|
-
deliberately carrying no outputPath: nothing was written, so
|
|
120
|
-
there is no path to publish. A consumer that installs,
|
|
121
|
-
symlinks or checksums what a build produced reads skills[]
|
|
122
|
-
and correctly finds nothing.
|
|
123
|
-
failedSkills: one row per skill that could not be packaged AT ALL (no
|
|
124
|
-
bundle exists for it); each carries name, error and an
|
|
125
|
-
issueCounts of one error
|
|
126
|
-
validationFailedSkills / skillsFailedValidation:
|
|
127
|
-
the THIRD failure mode — skills rejected by the PRE-build
|
|
128
|
-
source validation, so packaging was never attempted for
|
|
129
|
-
them. Distinct from failedSkills (packaging was attempted
|
|
130
|
-
and threw) because the fix is different: these carry their
|
|
131
|
-
own issueCounts, and the findings behind them are on stderr.
|
|
132
|
-
skillsWithErrors / skillsWithErrorNames:
|
|
133
|
-
the FOURTH failure mode — skills that packaged fine and then
|
|
134
|
-
emitted post-build validation errors. They are counted in
|
|
135
|
-
skillsBuilt, not skillsFailed, so read ALL of these before
|
|
136
|
-
concluding a run was clean: the exit code follows this one too.
|
|
137
|
-
skillsInPlace / skillsInPlaceNames:
|
|
138
|
-
NOT a failure — skills whose merged config says publish: false,
|
|
139
|
-
so this run set them aside unbuilt. Published so a build that
|
|
140
|
-
bundles fewer skills than it discovered says so by count.
|
|
141
|
-
skillsPluginOnly / skillsPluginOnlyNames:
|
|
142
|
-
NOT a failure — plugin-local publish: false skills, set aside
|
|
143
|
-
here too but shipped with their plugin by the claude phase, so
|
|
144
|
-
never counted in skillsInPlace. Both pairs are also in --dry-run.
|
|
145
|
-
runIssueCounts: findings that belong to the run rather than to any one
|
|
146
|
-
skill (ALLOW_UNUSED)
|
|
147
|
-
issueCounts: the run total, which reconciles against the rows above:
|
|
148
|
-
|
|
149
|
-
issueCounts = sum(skills[].issueCounts)
|
|
150
|
-
+ sum(skillsStaged[].issueCounts)
|
|
151
|
-
+ sum(failedSkills[].issueCounts)
|
|
152
|
-
+ sum(validationFailedSkills[].issueCounts)
|
|
153
|
-
+ runIssueCounts
|
|
154
|
-
|
|
155
|
-
Every error, warning and info in the header total is
|
|
156
|
-
therefore attributable to a row you can point at. (Exactly
|
|
157
|
-
one of skills / skillsStaged is ever non-empty, so no
|
|
158
|
-
packaged bundle is counted twice.)
|
|
159
|
-
outputCommitted:
|
|
160
|
-
whether dist/skills was REPLACED by this run. A build writes
|
|
161
|
-
into a staging directory and promotes it only if the whole
|
|
162
|
-
run is clean, so 'false' means nothing on disk changed and
|
|
163
|
-
the previous dist/skills (if any) is exactly as it was — and
|
|
164
|
-
the packaged rows are published as skillsStaged, without an
|
|
165
|
-
outputPath, because none was written.
|
|
166
|
-
promotionError: present ONLY when the promotion/discard step itself failed
|
|
167
|
-
(EACCES, ENOSPC, or the ENOTEMPTY a concurrent build in the
|
|
168
|
-
same dist/ produces). Its text names what is on disk and the
|
|
169
|
-
single 'mv' that recovers it, because the parked path carries
|
|
170
|
-
a random suffix nobody can reconstruct. Read outputCommitted
|
|
171
|
-
beside it: a promotion that landed the tree and then failed to
|
|
172
|
-
clean up still committed the output.
|
|
113
|
+
Warnings and info findings stay collapsed unless --verbose. --verbose
|
|
114
|
+
changes stderr ONLY: the stdout report carries every finding either way.
|
|
173
115
|
|
|
174
116
|
Exit Codes:
|
|
175
|
-
0 -
|
|
176
|
-
1 -
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
117
|
+
0 - Built; findings, if any, are warnings or info (or a dry-run preview)
|
|
118
|
+
1 - An error-severity finding: a skill failed pre-build validation, had its
|
|
119
|
+
content refused by the packager (SKILL_PACKAGING_FAILED), or emitted
|
|
120
|
+
post-build errors (every such failure is collected in ONE pass, and
|
|
121
|
+
dist/skills is left untouched);
|
|
122
|
+
--skill named a publish: false skill (SKILL_BUILD_TARGET_NOT_BUILDABLE);
|
|
123
|
+
or nothing was examined — no skills: block, or globs matching no
|
|
124
|
+
SKILL.md (RESOURCE_CHECK_BROKEN)
|
|
125
|
+
2 - The build could not run (error.code): USAGE_INVALID (a [path] naming no
|
|
126
|
+
directory or none holding a config, an unknown --skill, no project
|
|
127
|
+
root), INPUT_UNREADABLE (a [path] or directory the OS will not read, or
|
|
128
|
+
a file in the git repository the OS will not let git read — named in the
|
|
129
|
+
message), CONFIG_INVALID, or RUN_INCOMPLETE (an output the OS will not
|
|
130
|
+
let the build examine or write: a previous dist/skills it will not
|
|
131
|
+
examine, the staging tree beside it could not be made or written, or
|
|
132
|
+
the swap of dist/skills failed — the report then still carries the
|
|
133
|
+
skills examined, the findings and data.promotionError).
|
|
134
|
+
Any other throw from the packager stops the run under its own code
|
|
135
|
+
(a directory the OS will not list: INPUT_UNREADABLE for the project's
|
|
136
|
+
own sources, RUN_INCOMPLETE for an output); one that
|
|
137
|
+
carries no code is a defect in VAT (INTERNAL_ERROR). Either way
|
|
138
|
+
dist/skills is left untouched
|
|
191
139
|
|
|
192
140
|
Requirements:
|
|
193
141
|
projectRoot: required (errors if no vibe-agent-toolkit.config.yaml or .git/ ancestor)
|
|
@@ -305,13 +253,13 @@ function displayIgnoredErrors(validationResult, logger) {
|
|
|
305
253
|
* discover the work. Returning the failure lets {@link runSkillBuild} collect
|
|
306
254
|
* every one of them and fail once, at the end, with the whole list.
|
|
307
255
|
*
|
|
308
|
-
* The returned
|
|
256
|
+
* The returned issues are `allErrors` — the full EMITTED set including
|
|
309
257
|
* warnings and info (its name lies; see `PackagingValidationResult`) — so the
|
|
310
|
-
*
|
|
311
|
-
*
|
|
258
|
+
* findings that rejected the skill are NAMED on the report's envelope, not
|
|
259
|
+
* only counted.
|
|
312
260
|
*/
|
|
313
261
|
async function validateSkillBeforeBuild(input) {
|
|
314
|
-
const { skillName, sourcePath, packagingConfig, logger, locationRoot, allowLedger, projectSkills, suiteProbe, populationSource, verbose } = input;
|
|
262
|
+
const { skillName, sourcePath, packagingConfig, logger, locationRoot, allowLedger, projectSkills, suiteProbe, populationSource, verbose, outputs } = input;
|
|
315
263
|
logger.debug(` Validating skill: ${skillName}`);
|
|
316
264
|
// The run's ledger, not this call's: an allow entry scoped to a SOURCE
|
|
317
265
|
// filename can only ever match here — packaging renames the file to
|
|
@@ -326,6 +274,7 @@ async function validateSkillBeforeBuild(input) {
|
|
|
326
274
|
// A build must not ship a shorter bundle: a directory the validator's own
|
|
327
275
|
// registry crawl cannot list refuses the run by name.
|
|
328
276
|
unreadable: 'refuse',
|
|
277
|
+
outputs,
|
|
329
278
|
// Likewise the RUN's, and the same instance the packaging phase gets: this
|
|
330
279
|
// lane resolves test input for the subject AND every entry in
|
|
331
280
|
// `projectSkills`, so a per-call probe is S² over the loop.
|
|
@@ -335,7 +284,7 @@ async function validateSkillBeforeBuild(input) {
|
|
|
335
284
|
...(populationSource !== undefined && { populationSource }),
|
|
336
285
|
});
|
|
337
286
|
applyConfigVerdicts(validationResult, packagingConfig.targets, sourcePath, locationRoot);
|
|
338
|
-
if (validationResult.
|
|
287
|
+
if (validationResult.summary.errors === 0) {
|
|
339
288
|
if (validationResult.ignoredErrors.length > 0) {
|
|
340
289
|
logger.debug(` ${validationResult.ignoredErrors.length} issue(s) allowed by config`);
|
|
341
290
|
}
|
|
@@ -350,39 +299,12 @@ async function validateSkillBeforeBuild(input) {
|
|
|
350
299
|
logger.error(line);
|
|
351
300
|
}
|
|
352
301
|
displayIgnoredErrors(validationResult, logger);
|
|
353
|
-
return { name: skillName,
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Output dry-run results
|
|
357
|
-
*/
|
|
358
|
-
function outputDryRunYaml(skills, setAside, duration) {
|
|
359
|
-
writeYamlHeader({
|
|
360
|
-
status: 'success',
|
|
361
|
-
dryRun: true,
|
|
362
|
-
// A dry run validates NOTHING, so it has no severity distribution to
|
|
363
|
-
// publish. Saying so is the point: an absent `issueCounts` next to
|
|
364
|
-
// `status: success` otherwise reads as "clean", which is the reassuring
|
|
365
|
-
// misreading. This field makes the absence explicit instead.
|
|
366
|
-
validated: false,
|
|
367
|
-
skillsFound: skills.length,
|
|
368
|
-
// The same partition the real build publishes: what a preview would NOT
|
|
369
|
-
// bundle is as much a part of the preview as what it would.
|
|
370
|
-
skillsInPlace: setAside.inPlace.length,
|
|
371
|
-
skillsPluginOnly: setAside.pluginOnly.length,
|
|
372
|
-
});
|
|
373
|
-
process.stdout.write(`skills:\n`);
|
|
374
|
-
for (const skill of skills) {
|
|
375
|
-
process.stdout.write(` - name: ${skill.name}\n`);
|
|
376
|
-
process.stdout.write(` source: ${skill.sourcePath}\n`);
|
|
377
|
-
process.stdout.write(` output: dist/skills/${skillNameToFsPath(skill.name)}\n`);
|
|
378
|
-
}
|
|
379
|
-
process.stdout.write(yaml.stringify({ skillsInPlaceNames: [...setAside.inPlace], skillsPluginOnlyNames: [...setAside.pluginOnly] }, { indent: 2, lineWidth: 0 }));
|
|
380
|
-
process.stdout.write(`duration: ${duration}ms\n`);
|
|
302
|
+
return { name: skillName, issues: [...validationResult.allErrors] };
|
|
381
303
|
}
|
|
382
304
|
/**
|
|
383
305
|
* Perform dry-run preview
|
|
384
306
|
*/
|
|
385
|
-
function performDryRun(skillsToBuild, setAside,
|
|
307
|
+
function performDryRun(skillsToBuild, setAside, logger) {
|
|
386
308
|
logger.info(`Dry-run: Analyzing skill build...`);
|
|
387
309
|
logger.info(` Skills to build: ${skillsToBuild.length}`);
|
|
388
310
|
logger.info(` In-place skills (publish: false, not bundled): ${setAside.inPlace.length}`);
|
|
@@ -393,592 +315,192 @@ function performDryRun(skillsToBuild, setAside, duration, logger) {
|
|
|
393
315
|
logger.info(` Source: ${skill.sourcePath}`);
|
|
394
316
|
logger.info(` Output: dist/skills/${skillNameToFsPath(skill.name)}`);
|
|
395
317
|
}
|
|
396
|
-
outputDryRunYaml(skillsToBuild, setAside, duration);
|
|
397
318
|
logger.info(`\nDry-run complete (no files created)`);
|
|
398
319
|
logger.info(` Run without --dry-run to build the skills`);
|
|
399
320
|
}
|
|
321
|
+
/** The gate `vat skills build` is judged by: it offers no `--strict`. */
|
|
322
|
+
const GATE = { strict: false };
|
|
400
323
|
/**
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
* every row at once).
|
|
324
|
+
* The two findings only this command emits. Both are `NonOverridableCode`s —
|
|
325
|
+
* always `error`, never a `validation.severity` / `allow` key — because nothing
|
|
326
|
+
* here reads an override for them, and a key that parses and does nothing is
|
|
327
|
+
* the inert-config shape the registry exists to prevent.
|
|
406
328
|
*/
|
|
407
|
-
|
|
329
|
+
function notBuildableIssue(message, location) {
|
|
330
|
+
return {
|
|
331
|
+
severity: 'error',
|
|
332
|
+
code: 'SKILL_BUILD_TARGET_NOT_BUILDABLE',
|
|
333
|
+
message,
|
|
334
|
+
...(location === undefined ? {} : { location }),
|
|
335
|
+
fix: 'Drop --skill, set publish: true on the skill to distribute it through dist/skills, or — for a plugin-local skill — run vat build --only claude to package its plugin.',
|
|
336
|
+
};
|
|
337
|
+
}
|
|
408
338
|
/**
|
|
409
|
-
* The
|
|
410
|
-
*
|
|
411
|
-
* `status` used to be the literal `success` — printed even for a build that then
|
|
412
|
-
* exited 1 on post-build errors, so the machine-readable half of the output
|
|
413
|
-
* contradicted the exit code, in the reassuring direction. It is now derived
|
|
414
|
-
* from the same issues the human stream renders, and the per-severity counts
|
|
415
|
-
* ride beside it because a status cannot express a three-valued distribution:
|
|
416
|
-
* `success` here means "nothing you must act on", not "there was nothing to see".
|
|
417
|
-
*
|
|
418
|
-
* The header total reconciles against the document, by construction:
|
|
419
|
-
*
|
|
420
|
-
* issueCounts === Σ (skills[] ∪ skillsStaged[])[].issueCounts
|
|
421
|
-
* + Σ failedSkills[].issueCounts
|
|
422
|
-
* + Σ validationFailedSkills[].issueCounts
|
|
423
|
-
* + runIssueCounts
|
|
424
|
-
*
|
|
425
|
-
* `skills` and `skillsStaged` are the same population under two names, and
|
|
426
|
-
* exactly one of them is ever non-empty (see the comment on `skills` below), so
|
|
427
|
-
* summing both is summing each packaged bundle once.
|
|
428
|
-
*
|
|
429
|
-
* Every addend therefore has a ROW a reader can point at. Counting the failures
|
|
430
|
-
* only in the header — which is how this first shipped — reproduced, one command
|
|
431
|
-
* over, the exact defect `vat skills validate` was fixed for: a header reporting
|
|
432
|
-
* more than its rows summed to (there, 1814 warnings against 1800), leaving a
|
|
433
|
-
* consumer to hand-count a list to find out what the difference was. `--help`
|
|
434
|
-
* states this identity; changing it means changing that text too.
|
|
435
|
-
*
|
|
436
|
-
* Each packaged row carries its `issues` as well as its counts. It did not, for
|
|
437
|
-
* a while: the findings were collected here and then dropped at the publish
|
|
438
|
-
* step, so the document offered a count with no `code`, no location and no fix
|
|
439
|
-
* string at ANY verbosity — an adopter run published 67 warnings and zero
|
|
440
|
-
* findings. That is acute for the four detectors this lane added: their output
|
|
441
|
-
* existed only on stderr, where no CI consumer reads it. Full findings on the
|
|
442
|
-
* rows is the shape `vat audit` and `vat skills validate --verbose` already
|
|
443
|
-
* publish, and it is verbosity-INDEPENDENT here for the reason stated in
|
|
444
|
-
* `issuesToRenderAtVerbosity`: filtering a machine-readable document by a human
|
|
445
|
-
* report's verbosity silently breaks the consumers that parse it.
|
|
446
|
-
*
|
|
447
|
-
* Takes the whole {@link SkillBuildRun} rather than a positional list of its
|
|
448
|
-
* parts: the run has four populations now, and a positional call site can
|
|
449
|
-
* transpose two same-shaped lists in silence.
|
|
339
|
+
* The classified fault a packager refusal carries: the thrown value itself, or the
|
|
340
|
+
* fault the packager's content refusal wraps (`asPackagerRefusal`).
|
|
450
341
|
*/
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
// leaves the document in two coordinate systems.
|
|
469
|
-
//
|
|
470
|
-
// Do not read the rest of the report as clean because the failure MESSAGES
|
|
471
|
-
// are: those were scrubbed of absolute project paths and are confirmed clean,
|
|
472
|
-
// but the SUCCESS-path fields were not. This one and the plugin lane's `dir:`
|
|
473
|
-
// (5 places in the measured report — see `pluginBuildCommand` in
|
|
474
|
-
// ../claude/plugin/build.ts) are the two that still publish `$HOME` into CI
|
|
475
|
-
// logs, and they wait on the same `root:` decision — fix them as a pair, or
|
|
476
|
-
// the two lanes end up anchored differently.
|
|
477
|
-
outputPath: result.outputPath,
|
|
478
|
-
filesPackaged: result.files.dependencies.length + 1,
|
|
479
|
-
issueCounts: countBySeverity(issues),
|
|
480
|
-
issues,
|
|
481
|
-
};
|
|
482
|
-
});
|
|
483
|
-
const allIssues = perSkill.flatMap((s) => s.issues);
|
|
484
|
-
const runIssueCounts = countBySeverity(runIssues);
|
|
485
|
-
// A skill that THREW emits no issues at all — it never reached the lanes that
|
|
486
|
-
// produce them. Deriving the header purely from issue channels therefore said
|
|
487
|
-
// `success` for a run the command then exited 1 on, which is exactly the
|
|
488
|
-
// reassuring contradiction this summary exists to prevent. Each failure is
|
|
489
|
-
// counted as one error so `status`, `issueCounts` and the exit code agree —
|
|
490
|
-
// and that error is published ON the failure's own row (see
|
|
491
|
-
// `failureIssueCounts`), never as a header-only addend, so the identity
|
|
492
|
-
// documented in `--help` holds.
|
|
493
|
-
const failedSkills = failures.map(({ name, message }) => ({
|
|
494
|
-
name,
|
|
495
|
-
error: message,
|
|
496
|
-
issueCounts: failureIssueCounts(),
|
|
497
|
-
}));
|
|
498
|
-
// The THIRD population, and the one an adopter meets first: a skill the
|
|
499
|
-
// PRE-build source validation rejected, so packaging was never attempted. It
|
|
500
|
-
// gets its own rows rather than joining either list above, because neither
|
|
501
|
-
// answers the question this one raises — `failedSkills` says packaging was
|
|
502
|
-
// attempted and threw, `skills` says a bundle exists. And unlike a throw, this
|
|
503
|
-
// failure HAS a severity distribution of its own, so it publishes the real
|
|
504
|
-
// counts instead of the flat `failureIssueCounts()` stand-in.
|
|
505
|
-
//
|
|
506
|
-
// KNOWN, DELIBERATELY NOT FIXED — these rows carry no `issues` key, so the
|
|
507
|
-
// findings that just failed the build are COUNTED here and never NAMED. On a
|
|
508
|
-
// real adopter monorepo build, all 28 build-blocking errors were counted but
|
|
509
|
-
// never named — 551 of 1707 findings were named overall. A CI consumer reading
|
|
510
|
-
// stdout gets a number it cannot act on; the findings themselves exist only on
|
|
511
|
-
// stderr.
|
|
512
|
-
//
|
|
513
|
-
// Stated explicitly, because a reader will otherwise assume it is covered: the
|
|
514
|
-
// sibling defect on the `skills` rows — their `issues` array dropped at the
|
|
515
|
-
// publish seam, see the comment on `buildYamlSummary` — was fixed, and that fix
|
|
516
|
-
// does NOT cover this row type. This one is not a publish-seam drop: the
|
|
517
|
-
// findings never reach here at all. `SkillValidationFailure` is `{ name,
|
|
518
|
-
// issueCounts }`, so fixing it means widening that type back at the pre-build
|
|
519
|
-
// validation lane, not adding a key at this call.
|
|
520
|
-
const validationFailedSkills = validationFailures.map(({ name, issueCounts }) => ({
|
|
521
|
-
name,
|
|
522
|
-
issueCounts,
|
|
523
|
-
}));
|
|
342
|
+
function packagerFaultOf(thrown) {
|
|
343
|
+
return isFsFaultError(thrown) ? thrown : thrown?.cause;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* A skill whose content the packager refused (`isSkillPackagingInputError`) — see
|
|
347
|
+
* {@link notBuildableIssue} for why it is not overridable. Shared by every lane
|
|
348
|
+
* whose packager refusals are the same finding; `next` is that lane's own next
|
|
349
|
+
* step, because "rebuild" is wrong advice from a verb that does not build. The ONE
|
|
350
|
+
* place a finding built from a classified fault gets the refusal table's remedy,
|
|
351
|
+
* which the fault's own message leaves to the table.
|
|
352
|
+
*
|
|
353
|
+
* @param message - The packager refusal's message, as the lane words it
|
|
354
|
+
* @param location - The skill's source, relative to the lane's root
|
|
355
|
+
* @param next - What the lane's user runs after fixing it
|
|
356
|
+
* @param thrown - What the packager threw
|
|
357
|
+
*/
|
|
358
|
+
export function packagingFailedIssue(message, location, next, thrown) {
|
|
524
359
|
return {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
? 'error'
|
|
531
|
-
: calculateValidationStatus([...allIssues, ...runIssues]),
|
|
532
|
-
issueCounts: sumSeverityCounts([
|
|
533
|
-
...perSkill.map((s) => s.issueCounts),
|
|
534
|
-
...failedSkills.map((s) => s.issueCounts),
|
|
535
|
-
...validationFailedSkills.map((s) => s.issueCounts),
|
|
536
|
-
runIssueCounts,
|
|
537
|
-
]),
|
|
538
|
-
runIssueCounts,
|
|
539
|
-
skillsBuilt: results.length,
|
|
540
|
-
skillsFailed: failures.length,
|
|
541
|
-
skillsFailedValidation: validationFailures.length,
|
|
542
|
-
// Whether dist/skills was actually REPLACED. Carried through from the run
|
|
543
|
-
// rather than re-derived here: two definitions of "did this build change
|
|
544
|
-
// anything" is exactly how a report ends up contradicting the disk.
|
|
545
|
-
outputCommitted,
|
|
546
|
-
...(run.promotionError === undefined ? {} : { promotionError: run.promotionError }),
|
|
547
|
-
// The OTHER meaning of "failed", published because the exit code follows
|
|
548
|
-
// THIS one and nothing in the document did. `skillsFailed` counts skills
|
|
549
|
-
// that could not be packaged at all; a skill that packaged fine and then
|
|
550
|
-
// emitted post-build validation errors is a `skillsBuilt`, so a real run
|
|
551
|
-
// printed "Build failed: 3 skill(s) emitted post-build validation errors"
|
|
552
|
-
// over `skillsFailed: 0` and `failedSkills: []`, and exited 1. A CI job
|
|
553
|
-
// reading either field saw a clean build. Both categories are now named.
|
|
554
|
-
skillsWithErrors: [...skillsWithErrors],
|
|
555
|
-
// `skills` lists what exists on disk. A failed skill is published in its own
|
|
556
|
-
// list rather than here, because every field of this shape (outputPath,
|
|
557
|
-
// filesPackaged) would have to be invented for a bundle that was not written.
|
|
558
|
-
//
|
|
559
|
-
// That invariant did not survive `outputCommitted: false`, which is the OTHER
|
|
560
|
-
// way a row can name a path nothing was written to: the bundles are built into
|
|
561
|
-
// staging and the promotion is then aborted, so a failed 86-skill run published
|
|
562
|
-
// 86 `dist/skills/<name>` paths of which 85 did not exist (verified with
|
|
563
|
-
// `fs.existsSync` over every row). A CI step reading `skills[].outputPath` to
|
|
564
|
-
// install, symlink or checksum got 85 dead paths, with no signal but a sibling
|
|
565
|
-
// boolean it was not told to read.
|
|
566
|
-
//
|
|
567
|
-
// So the rows MOVE when the swap did not happen, rather than losing a field:
|
|
568
|
-
// a consumer iterating `skills[]` sees the empty list its documented meaning
|
|
569
|
-
// ("what exists on disk") demands, while `skillsStaged[]` — a name that
|
|
570
|
-
// promises nothing about the disk — keeps the findings and the counts the
|
|
571
|
-
// header identity is summed from. Those rows publish no `outputPath` at all,
|
|
572
|
-
// because there is no honest value for it: the staging path has been deleted
|
|
573
|
-
// and the final path was never written.
|
|
574
|
-
skills: outputCommitted ? perSkill : [],
|
|
575
|
-
skillsStaged: outputCommitted
|
|
576
|
-
? []
|
|
577
|
-
: perSkill.map(({ name, filesPackaged, issueCounts, issues }) => ({
|
|
578
|
-
name,
|
|
579
|
-
filesPackaged,
|
|
580
|
-
issueCounts,
|
|
581
|
-
issues,
|
|
582
|
-
})),
|
|
583
|
-
failedSkills,
|
|
584
|
-
validationFailedSkills,
|
|
585
|
-
runIssues: [...runIssues],
|
|
586
|
-
duration: `${duration}ms`,
|
|
360
|
+
severity: 'error',
|
|
361
|
+
code: 'SKILL_PACKAGING_FAILED',
|
|
362
|
+
message: withFsFaultRemedy(message, packagerFaultOf(thrown)),
|
|
363
|
+
...(location === undefined ? {} : { location }),
|
|
364
|
+
fix: `Fix what the message names in the skill or its skills.config entry, then ${next}.`,
|
|
587
365
|
};
|
|
588
366
|
}
|
|
367
|
+
/** A path as the report publishes it: relative to `cwd`, forward slashes. */
|
|
368
|
+
function reportPath(cwd, path) {
|
|
369
|
+
return toForwardSlash(safePath.relative(cwd, path));
|
|
370
|
+
}
|
|
371
|
+
/** A finding's `location` for `path`, or none when it has no `cwd`-relative spelling (another drive). */
|
|
372
|
+
function reportLocation(cwd, path) {
|
|
373
|
+
return relativeLocationOrUndefined(reportPath(cwd, path));
|
|
374
|
+
}
|
|
589
375
|
/**
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
* whole reason this function exists. The summary carries `skillsWithErrors` as
|
|
594
|
-
* an ARRAY of names; the published document carries `skillsWithErrors` as a
|
|
595
|
-
* COUNT (in the header, beside the other tallies) and the names separately under
|
|
596
|
-
* `skillsWithErrorNames`. That projection used to live inside the renderer, so
|
|
597
|
-
* the only way to obtain the real document was to serialize it and parse it back
|
|
598
|
-
* — which is exactly what the parent process did, and exactly what stopped being
|
|
599
|
-
* true when phases stopped being child processes. Returning the summary instead
|
|
600
|
-
* would have flipped `skillsWithErrors` from a number to an array in `vat
|
|
601
|
-
* build`'s output, silently and with nothing to typecheck it against.
|
|
602
|
-
*
|
|
603
|
-
* `skillsInPlace` and `skillsPluginOnly` ride in the header beside `skillsBuilt`,
|
|
604
|
-
* with the names under `skillsInPlaceNames` / `skillsPluginOnlyNames`: a build that
|
|
605
|
-
* ships fewer skills than it discovered is the drop this command exists to prevent,
|
|
606
|
-
* so every skill a `publish: false` removed from `skillsBuilt` must be visible where
|
|
607
|
-
* a consumer reads the count — including a plugin-local one, which is not in place
|
|
608
|
-
* (it ships with its plugin) but is still not bundled here.
|
|
376
|
+
* Every issue ONE skill contributed, keyed by skill name: its pre-build
|
|
377
|
+
* rejection, the packager's refusal of its content (as a `SKILL_PACKAGING_FAILED`
|
|
378
|
+
* finding at its source), or its post-build findings.
|
|
609
379
|
*/
|
|
610
|
-
|
|
611
|
-
const
|
|
612
|
-
const
|
|
380
|
+
function issuesBySkill(input) {
|
|
381
|
+
const { cwd, skills, run } = input;
|
|
382
|
+
const bySkill = new Map();
|
|
383
|
+
if (run === undefined)
|
|
384
|
+
return bySkill;
|
|
385
|
+
const sources = new Map(skills.map((skill) => [skill.name, skill.sourcePath]));
|
|
386
|
+
for (const { name, issues } of run.validationFailures)
|
|
387
|
+
bySkill.set(name, [...issues]);
|
|
388
|
+
for (const { name, message, error } of run.failures) {
|
|
389
|
+
const source = sources.get(name);
|
|
390
|
+
bySkill.set(name, [packagingFailedIssue(message, source === undefined ? undefined : reportLocation(cwd, source), 'rebuild', error)]);
|
|
391
|
+
}
|
|
392
|
+
for (const { name, result } of run.results)
|
|
393
|
+
bySkill.set(name, collectPostBuildIssues(result));
|
|
394
|
+
return bySkill;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* THE document's content for one run — `examined`, the flat findings and
|
|
398
|
+
* `data` — as a completed report or a refusal's finished work.
|
|
399
|
+
*
|
|
400
|
+
* `examined` is every skill the run discovered after `--skill`, the set-aside
|
|
401
|
+
* ones included: a build that bundles fewer skills than it found says so by
|
|
402
|
+
* name (`skillsInPlace`, `skillsPluginOnly`), never by a smaller denominator.
|
|
403
|
+
*
|
|
404
|
+
* Every finding is on the envelope — pre-build, packaging, post-build and the
|
|
405
|
+
* run's own (`ALLOW_UNUSED`) — at every verbosity: `--verbose` changes stderr
|
|
406
|
+
* only. A row carries its status, never a second list. The four failure
|
|
407
|
+
* populations the old document split into four lists are one list here, told
|
|
408
|
+
* apart by code: a pre-build rejection (`skillsFailedValidation`), a packaging
|
|
409
|
+
* throw (`skillsFailed`, `SKILL_PACKAGING_FAILED`), and a bundle that failed its
|
|
410
|
+
* post-build gate (counted in `skillsBuilt`, its findings on the envelope).
|
|
411
|
+
*/
|
|
412
|
+
export function skillsBuildWork(input) {
|
|
413
|
+
const { cwd, skills, setAside, dryRun, run, setAsideIssues } = input;
|
|
414
|
+
const bySkill = issuesBySkill(input);
|
|
415
|
+
const rows = skills.map((skill) => ({
|
|
416
|
+
name: skill.name,
|
|
417
|
+
source: reportPath(cwd, skill.sourcePath),
|
|
418
|
+
output: reportPath(cwd, finalOutputPath(cwd, skill.name)),
|
|
419
|
+
status: rowStatus(run, toFindings(bySkill.get(skill.name) ?? []).length),
|
|
420
|
+
}));
|
|
421
|
+
const issues = [...setAsideIssues, ...skills.flatMap((skill) => bySkill.get(skill.name) ?? []), ...(run?.runIssues ?? []), ...(run?.residue ?? [])];
|
|
613
422
|
return {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
// failed build must not add. `status: error` and `outputCommitted` are
|
|
629
|
-
// already in the header, so a reader who stops there is not misled.
|
|
630
|
-
...(summary.promotionError === undefined ? {} : { promotionError: summary.promotionError }),
|
|
631
|
-
skills,
|
|
632
|
-
// Always published, even empty, for the same reason `failedSkills` is: an
|
|
633
|
-
// absent key reads as "this run had no such concept", and a consumer that
|
|
634
|
-
// has to distinguish absent from empty will get it wrong.
|
|
635
|
-
skillsStaged,
|
|
636
|
-
failedSkills,
|
|
637
|
-
validationFailedSkills,
|
|
638
|
-
skillsWithErrorNames: summary.skillsWithErrors,
|
|
639
|
-
skillsInPlaceNames: [...setAside.inPlace],
|
|
640
|
-
skillsPluginOnlyNames: [...setAside.pluginOnly],
|
|
641
|
-
runIssues: summary.runIssues,
|
|
642
|
-
duration: durationText,
|
|
423
|
+
examined: skills.length + setAside.inPlace.length + setAside.pluginOnly.length,
|
|
424
|
+
findings: toFindings(issues),
|
|
425
|
+
data: {
|
|
426
|
+
dryRun,
|
|
427
|
+
validated: run !== undefined,
|
|
428
|
+
skillsBuilt: run?.results.length ?? 0,
|
|
429
|
+
skillsFailed: run?.failures.length ?? 0,
|
|
430
|
+
skillsFailedValidation: run?.validationFailures.length ?? 0,
|
|
431
|
+
skillsInPlace: [...setAside.inPlace],
|
|
432
|
+
skillsPluginOnly: [...setAside.pluginOnly],
|
|
433
|
+
outputCommitted: run?.outputCommitted ?? false,
|
|
434
|
+
...(run?.promotionFailure === undefined ? {} : { promotionError: run.promotionFailure.description }),
|
|
435
|
+
skills: rows,
|
|
436
|
+
},
|
|
643
437
|
};
|
|
644
438
|
}
|
|
645
439
|
/**
|
|
646
|
-
*
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
* one `yaml.stringify`, so the header lands before a body that can run to
|
|
650
|
-
* megabytes on a large project. The key ORDER here is the document's order; the
|
|
651
|
-
* split is presentation only and adds nothing the document does not carry.
|
|
440
|
+
* A row's status: `not-built` when the run never validated or built anything (a
|
|
441
|
+
* refusal before the build, or a dry run) — `ok` there would read as a clean
|
|
442
|
+
* build beside an output that does not exist — else whether it has findings.
|
|
652
443
|
*/
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
// `outputCommitted` rides up here too — a reader who sees exit 1 needs to know
|
|
658
|
-
// whether their dist/skills still exists before they do anything else.
|
|
659
|
-
writeYamlHeader({
|
|
660
|
-
status: status,
|
|
661
|
-
skillsBuilt: skillsBuilt,
|
|
662
|
-
skillsInPlace: skillsInPlace,
|
|
663
|
-
skillsPluginOnly: skillsPluginOnly,
|
|
664
|
-
skillsFailed: skillsFailed,
|
|
665
|
-
skillsFailedValidation: skillsFailedValidation,
|
|
666
|
-
skillsWithErrors: skillsWithErrors,
|
|
667
|
-
outputCommitted: outputCommitted,
|
|
668
|
-
});
|
|
669
|
-
process.stdout.write(yaml.stringify(body, { indent: 2, lineWidth: 0, aliasDuplicateObjects: false }));
|
|
670
|
-
process.stdout.write(`duration: ${durationText}\n`);
|
|
444
|
+
function rowStatus(run, findingCount) {
|
|
445
|
+
if (run === undefined)
|
|
446
|
+
return 'not-built';
|
|
447
|
+
return findingCount === 0 ? 'ok' : 'findings';
|
|
671
448
|
}
|
|
672
449
|
/** How the human stream names the output tree. One spelling, one place. */
|
|
673
450
|
const DIST_SKILLS_LABEL = 'dist/skills';
|
|
674
|
-
/** The tree a successful build promotes its staged bundles into. */
|
|
675
|
-
function distSkillsDir(cwd) {
|
|
451
|
+
/** The tree a successful build promotes its staged bundles into: what `vat skills build` in `cwd` writes. */
|
|
452
|
+
export function distSkillsDir(cwd) {
|
|
676
453
|
return safePath.resolve(cwd, 'dist', 'skills');
|
|
677
454
|
}
|
|
678
455
|
/**
|
|
679
456
|
* Where a skill's bundle lives once a build has earned the swap.
|
|
680
457
|
*
|
|
681
|
-
* THE one definition, shared by the progress line, the published `
|
|
458
|
+
* THE one definition, shared by the progress line, the published `skills[].output`
|
|
682
459
|
* and the staging promotion — so the path a reader is told about is by
|
|
683
460
|
* construction the path the swap lands on.
|
|
684
461
|
*/
|
|
685
462
|
function finalOutputPath(cwd, skillName) {
|
|
686
463
|
return safePath.join(distSkillsDir(cwd), skillNameToFsPath(skillName));
|
|
687
464
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
*
|
|
692
|
-
* The separator in the prefix test is load-bearing: `beginStagedBuild` parks the
|
|
693
|
-
* previous output at `${root}.previous`, a SIBLING whose string starts with the
|
|
694
|
-
* staging root. A bare `startsWith` would rewrite it into the final tree and
|
|
695
|
-
* report a finding against a path that never held the file.
|
|
696
|
-
*/
|
|
697
|
-
function replacePathPrefix(value, from, to) {
|
|
698
|
-
if (value === from)
|
|
699
|
-
return to;
|
|
700
|
-
return value.startsWith(`${from}/`) ? `${to}${value.slice(from.length)}` : undefined;
|
|
701
|
-
}
|
|
702
|
-
/**
|
|
703
|
-
* Map any path anchored on the run's staging root onto the tree the swap lands
|
|
704
|
-
* on — the ONE re-anchoring, applied to every path a result publishes.
|
|
705
|
-
*
|
|
706
|
-
* Staging is transient in BOTH outcomes: `dist/.vat-skills-<rand>` is renamed
|
|
707
|
-
* away on success and deleted on failure, and the `mkdtemp` suffix means a
|
|
708
|
-
* reader cannot even reconstruct it. Any path that escapes this mapping is
|
|
709
|
-
* therefore unopenable by the time anyone reads it — which is what the published
|
|
710
|
-
* `outputPath` was fixed for, while the per-finding `location` strings kept
|
|
711
|
-
* leaking it (`Location: dist/.vat-skills-uxxJfu/demo/SKILL.md`, observed on a
|
|
712
|
-
* real adopter and on a two-skill fixture). One mapper, applied at one seam, is
|
|
713
|
-
* what keeps the two from drifting apart again.
|
|
714
|
-
*
|
|
715
|
-
* Both spellings are handled because the two carriers use different coordinate
|
|
716
|
-
* systems: `outputPath` is absolute (see `buildYamlSummary`), while a finding's
|
|
717
|
-
* `location` is relative to the project root the validator anchored on. The
|
|
718
|
-
* mapping preserves whichever it was given — re-basing a location here would put
|
|
719
|
-
* the report into two coordinate systems, the very thing `locationRoot` exists
|
|
720
|
-
* to prevent.
|
|
721
|
-
*/
|
|
722
|
-
function createStagingPathMapper(cwd, stagingRoot) {
|
|
723
|
-
const absoluteFrom = toForwardSlash(stagingRoot);
|
|
724
|
-
const absoluteTo = distSkillsDir(cwd);
|
|
725
|
-
const relativeFrom = toForwardSlash(safePath.relative(cwd, stagingRoot));
|
|
726
|
-
const relativeTo = toForwardSlash(safePath.relative(cwd, absoluteTo));
|
|
727
|
-
return (value) => {
|
|
728
|
-
const forward = toForwardSlash(value);
|
|
729
|
-
return (replacePathPrefix(forward, absoluteFrom, absoluteTo)
|
|
730
|
-
?? replacePathPrefix(forward, relativeFrom, relativeTo)
|
|
731
|
-
?? value);
|
|
732
|
-
};
|
|
733
|
-
}
|
|
734
|
-
/** Re-anchor the `location` of every issue that names a staged path. */
|
|
735
|
-
function reanchorIssueLocations(issues, mapPath) {
|
|
736
|
-
return issues.map((issue) => {
|
|
737
|
-
if (issue.location === undefined)
|
|
738
|
-
return issue;
|
|
739
|
-
const location = mapPath(issue.location);
|
|
740
|
-
return location === issue.location ? issue : { ...issue, location };
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
/**
|
|
744
|
-
* Re-anchor everything ONE skill's result says about where things are.
|
|
745
|
-
*
|
|
746
|
-
* Both post-build channels are rewritten, not just the one the summary reads:
|
|
747
|
-
* `collectPostBuildIssues` merges them and either can carry a staged location
|
|
748
|
-
* (the built-output validation runs against the staged `SKILL.md` itself), so a
|
|
749
|
-
* mapper applied to one of them leaves the report half-anchored.
|
|
750
|
-
*
|
|
751
|
-
* The `postBuildIssues` half is a live invariant with NO live producer today, and
|
|
752
|
-
* the distinction matters to anyone changing it. Every issue on that channel is
|
|
753
|
-
* anchored either on the bundle (`checkUnreferencedFiles`,
|
|
754
|
-
* `checkBrokenPackagedLinks`, `detectPackagedAgentInstructionFiles`,
|
|
755
|
-
* `checkPackagedTestInput` — all `relative(outputPath, …)`) or on the SOURCE
|
|
756
|
-
* project root (`droppedGlobMatchesToIssues`, `walkerExclusionsToIssues`,
|
|
757
|
-
* `deferredAssetsToIssues`, `FILENAME_COLLISION` — all `relative(projectRoot, …)`,
|
|
758
|
-
* where `projectRoot` is discovered from the skill's own source path). Neither
|
|
759
|
-
* spelling contains the staging prefix, so deleting this branch changes no
|
|
760
|
-
* fixture in the repo — which is exactly why it is unit-tested directly rather
|
|
761
|
-
* than through a build. Do not delete it on the strength of a green suite: the
|
|
762
|
-
* moment any producer anchors on `outputPath` ABSOLUTELY, this is the only thing
|
|
763
|
-
* standing between a report and a path its reader cannot open.
|
|
764
|
-
*
|
|
765
|
-
* Exported for that unit test.
|
|
766
|
-
*/
|
|
767
|
-
export function reanchorStagedResult(result, mapPath) {
|
|
768
|
-
const reanchored = { ...result, outputPath: mapPath(result.outputPath) };
|
|
769
|
-
if (result.postBuildIssues) {
|
|
770
|
-
reanchored.postBuildIssues = reanchorIssueLocations(result.postBuildIssues, mapPath);
|
|
465
|
+
function buildTarget(cwd, onlySkill) {
|
|
466
|
+
if (onlySkill === undefined) {
|
|
467
|
+
return { dest: distSkillsDir(cwd), label: DIST_SKILLS_LABEL, bundleIn: (staged, skillName) => safePath.join(staged, skillNameToFsPath(skillName)) };
|
|
771
468
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
allErrors: reanchorIssueLocations(result.postBuildValidation.allErrors, mapPath),
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
return reanchored;
|
|
779
|
-
}
|
|
780
|
-
/**
|
|
781
|
-
* Move the previous output aside and open a staging root for this run.
|
|
782
|
-
*
|
|
783
|
-
* Three properties the placement is load-bearing for:
|
|
784
|
-
*
|
|
785
|
-
* 1. **Same filesystem.** The staging root is a SIBLING of `dist/skills` under
|
|
786
|
-
* `dist/`, so promotion is a `rename` — atomic and free — never a
|
|
787
|
-
* cross-device copy of a tree that can be tens of thousands of files.
|
|
788
|
-
* 2. **Invisible to the run.** `createProjectRegistry` crawls the project for
|
|
789
|
-
* `**\/*.md` and excludes `**\/dist/**`, so nothing staged here can enter the
|
|
790
|
-
* registry the packager resolves links against. The leading dot is a second
|
|
791
|
-
* belt: a `files:` glob like `dist/**` does not descend into dot-directories.
|
|
792
|
-
* 3. **The final path is ABSENT while the build runs.** The previous tree is
|
|
793
|
-
* renamed away before the first bundle is written, which is exactly what the
|
|
794
|
-
* delete-up-front flow guaranteed — so no lane can read a half-replaced
|
|
795
|
-
* `dist/skills`, and a stale bundle cannot leak into the new output.
|
|
796
|
-
*
|
|
797
|
-
* `mkdtemp` rather than a fixed name: two builds in one `dist/` must not share a
|
|
798
|
-
* staging root, and a leftover root from a killed run must not be adopted.
|
|
799
|
-
*
|
|
800
|
-
* KNOWN WINDOW, deliberately not closed here: a run killed between the park and
|
|
801
|
-
* the commit/abort (Ctrl-C on a multi-minute build, a CI timeout, a crash) leaves
|
|
802
|
-
* `dist/skills` absent and the previous output parked at
|
|
803
|
-
* `dist/.vat-skills-<rand>.previous`. That is no worse than the delete-up-front
|
|
804
|
-
* flow this replaces — there, the same interrupt lost the tree outright — and the
|
|
805
|
-
* output is recoverable with a single `mv`. Auto-recovering it on the next run is
|
|
806
|
-
* NOT safe as long as `mkdtemp` allows concurrent builds in one `dist/`: a sweep
|
|
807
|
-
* cannot tell a dead run's parked tree from a live run's, and adopting the wrong
|
|
808
|
-
* one would restore stale bundles over fresh output. Closing this needs a lock on
|
|
809
|
-
* `dist/`, not a heuristic.
|
|
810
|
-
*
|
|
811
|
-
* That window covers KILLS only. A promotion that throws — EACCES, ENOSPC, or the
|
|
812
|
-
* ENOTEMPTY a concurrent build produces with no injection at all — is deterministic,
|
|
813
|
-
* needs no signal, and IS handled: see {@link BuildStaging.recover} and
|
|
814
|
-
* {@link settleStaging}.
|
|
815
|
-
*
|
|
816
|
-
* Exported for tests, which drive the primitives directly. Injecting a promotion
|
|
817
|
-
* failure through a whole `runSkillBuild` would mean racing the filesystem;
|
|
818
|
-
* holding the staging handle lets a test create the exact on-disk state
|
|
819
|
-
* (a target reoccupied between the park and the promotion) that produces one.
|
|
820
|
-
*/
|
|
821
|
-
export async function beginStagedBuild(cwd, onlySkill) {
|
|
822
|
-
const distDir = safePath.resolve(cwd, 'dist');
|
|
823
|
-
const skillsDir = safePath.join(distDir, 'skills');
|
|
824
|
-
await mkdir(distDir, { recursive: true });
|
|
825
|
-
const root = toForwardSlash(await mkdtemp(safePath.join(distDir, '.vat-skills-')));
|
|
826
|
-
// `--skill <name>` rebuilds ONE bundle, so the all-or-nothing guarantee is
|
|
827
|
-
// scoped to that bundle: its siblings under dist/skills are neither replaced
|
|
828
|
-
// nor set aside, exactly as the delete-just-that-directory flow behaved.
|
|
829
|
-
const subPath = onlySkill === undefined ? undefined : skillNameToFsPath(onlySkill);
|
|
830
|
-
const promoteFrom = subPath === undefined ? root : safePath.join(root, subPath);
|
|
831
|
-
const promoteTo = subPath === undefined ? skillsDir : safePath.join(skillsDir, subPath);
|
|
832
|
-
// `skillNameToFsPath` yields ONE path segment, so the parent is always known
|
|
833
|
-
// without a dirname call.
|
|
834
|
-
const promoteToParent = subPath === undefined ? distDir : skillsDir;
|
|
835
|
-
const parked = `${root}.previous`;
|
|
836
|
-
const hadPreviousOutput = existsSync(promoteTo);
|
|
837
|
-
if (hadPreviousOutput)
|
|
838
|
-
await rename(promoteTo, parked);
|
|
839
|
-
// Flipped the instant this run's bundles reach `promoteTo`, so a later failure
|
|
840
|
-
// in the SAME call (the parked-tree cleanup, the staging-shell removal) is not
|
|
841
|
-
// mistaken for "the output never landed". Without it, a `commit()` that renamed
|
|
842
|
-
// successfully and then failed to delete the parked copy would report
|
|
843
|
-
// `outputCommitted: false` about a `dist/skills` that holds the new output.
|
|
844
|
-
let promoted = false;
|
|
845
|
-
return {
|
|
846
|
-
root,
|
|
847
|
-
hadPreviousOutput,
|
|
848
|
-
parkedPath: parked,
|
|
849
|
-
promoteLabel: subPath === undefined
|
|
850
|
-
? DIST_SKILLS_LABEL
|
|
851
|
-
: `${DIST_SKILLS_LABEL}/${subPath}`,
|
|
852
|
-
promoted: () => promoted,
|
|
853
|
-
commit: async () => {
|
|
854
|
-
// Guarded because in single-skill mode the staged bundle is a SUBPATH that
|
|
855
|
-
// exists only if that one skill actually built. (In full-build mode the
|
|
856
|
-
// staging root always exists, so a run that built nothing promotes an
|
|
857
|
-
// empty dist/skills — an accurate statement of "this build produced no
|
|
858
|
-
// bundles", where the old delete-up-front flow left the path absent.)
|
|
859
|
-
if (existsSync(promoteFrom)) {
|
|
860
|
-
await mkdir(promoteToParent, { recursive: true });
|
|
861
|
-
await rename(promoteFrom, promoteTo);
|
|
862
|
-
}
|
|
863
|
-
promoted = true;
|
|
864
|
-
await rm(parked, { recursive: true, force: true });
|
|
865
|
-
// A no-op in full-build mode (the rename above consumed it); in
|
|
866
|
-
// single-skill mode this is the now-empty staging shell.
|
|
867
|
-
await rm(root, { recursive: true, force: true });
|
|
868
|
-
},
|
|
869
|
-
abort: async () => {
|
|
870
|
-
await rm(root, { recursive: true, force: true });
|
|
871
|
-
if (!hadPreviousOutput)
|
|
872
|
-
return;
|
|
873
|
-
await mkdir(promoteToParent, { recursive: true });
|
|
874
|
-
await rename(parked, promoteTo);
|
|
875
|
-
},
|
|
876
|
-
recover: async () => {
|
|
877
|
-
const residue = [];
|
|
878
|
-
let restoredPrevious = false;
|
|
879
|
-
const targetFree = !existsSync(promoteTo);
|
|
880
|
-
if (hadPreviousOutput && existsSync(parked)) {
|
|
881
|
-
if (targetFree) {
|
|
882
|
-
try {
|
|
883
|
-
await mkdir(promoteToParent, { recursive: true });
|
|
884
|
-
await rename(parked, promoteTo);
|
|
885
|
-
restoredPrevious = true;
|
|
886
|
-
}
|
|
887
|
-
catch (error) {
|
|
888
|
-
// The repair is best-effort by construction: it runs because the
|
|
889
|
-
// filesystem already refused something. A throw here must not replace
|
|
890
|
-
// the original diagnosis, so the parked path is reported as residue —
|
|
891
|
-
// with this refusal beside it — and the caller still names the real cause.
|
|
892
|
-
residue.push({ path: parked, reason: `restore failed: ${describeThrown(error)}` });
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
else {
|
|
896
|
-
residue.push({ path: parked, reason: 'the promotion target is already occupied' });
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
// This run's own staging root is always safe to drop: it holds output this
|
|
900
|
-
// run produced and can rebuild. Leaving it is what accumulated a complete
|
|
901
|
-
// copy of the build output in `dist/` on every failed promotion.
|
|
902
|
-
try {
|
|
903
|
-
await rm(root, { recursive: true, force: true });
|
|
904
|
-
}
|
|
905
|
-
catch (error) {
|
|
906
|
-
residue.push({ path: root, reason: `removal failed: ${describeThrown(error)}` });
|
|
907
|
-
}
|
|
908
|
-
return { restoredPrevious, residue };
|
|
909
|
-
},
|
|
910
|
-
};
|
|
469
|
+
// `skillNameToFsPath` yields ONE path segment: the bundle sits directly in dist/skills.
|
|
470
|
+
const bundle = skillNameToFsPath(onlySkill);
|
|
471
|
+
return { dest: safePath.join(distSkillsDir(cwd), bundle), label: `${DIST_SKILLS_LABEL}/${bundle}`, bundleIn: (staged) => staged };
|
|
911
472
|
}
|
|
912
473
|
/**
|
|
913
|
-
*
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
* `commit()` / `abort()` used to be called bare. Any throw on that path — the
|
|
917
|
-
* promotion `rename`, the restore `rename`, either cleanup — propagated to
|
|
918
|
-
* `buildCommand`'s catch, which exits 2 WITHOUT emitting the YAML document. The
|
|
919
|
-
* measured result: `dist/skills` absent, the user's previous output orphaned at
|
|
920
|
-
* `dist/.vat-skills-<rand>.previous` under a name the `mkdtemp` suffix makes
|
|
921
|
-
* unguessable, and not one byte of the report whose `outputCommitted` field
|
|
922
|
-
* `--help` tells an operator to read when they see a non-zero exit.
|
|
923
|
-
*
|
|
924
|
-
* So: repair what can be repaired, then return a message rather than throwing —
|
|
925
|
-
* the caller publishes the document first and exits 2 after.
|
|
926
|
-
*
|
|
927
|
-
* `outputCommitted` comes from {@link BuildStaging.promoted}, not from
|
|
928
|
-
* `!runFailed`: a `commit()` that renamed the tree into place and then failed to
|
|
929
|
-
* delete the parked copy DID replace `dist/skills`, and saying otherwise would
|
|
930
|
-
* put the report back into contradiction with the disk — the one thing this whole
|
|
931
|
-
* summary exists to prevent.
|
|
474
|
+
* Thrown from the staging fill when the build finished with a failure: the plan discards what it
|
|
475
|
+
* staged and changes nothing. One per run, so what the discard could not remove is recorded
|
|
476
|
+
* beside THIS run's (`suppressedFaultsOf`).
|
|
932
477
|
*/
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
}
|
|
937
|
-
catch (error) {
|
|
938
|
-
const recovery = await staging.recover();
|
|
939
|
-
return {
|
|
940
|
-
outputCommitted: staging.promoted(),
|
|
941
|
-
promotionError: describePromotionFailure(staging, error, recovery),
|
|
942
|
-
};
|
|
478
|
+
class BuildNotEarned extends VatError {
|
|
479
|
+
constructor() {
|
|
480
|
+
super('SKILLS_BUILD_NOT_EARNED', 'the build failed, so its output does not replace the previous one');
|
|
943
481
|
}
|
|
944
|
-
if (runFailed) {
|
|
945
|
-
logger.error(staging.hadPreviousOutput
|
|
946
|
-
? `\n Nothing was replaced — the previous ${staging.promoteLabel} is intact`
|
|
947
|
-
: `\n Nothing was written — ${staging.promoteLabel} does not exist`);
|
|
948
|
-
}
|
|
949
|
-
return { outputCommitted: !runFailed };
|
|
950
482
|
}
|
|
951
483
|
/**
|
|
952
|
-
*
|
|
953
|
-
*
|
|
954
|
-
*
|
|
955
|
-
* failure is the one moment where "your previous output is at <path>" is the
|
|
956
|
-
* whole remedy, and the path is unreconstructable without being told.
|
|
484
|
+
* The promotion's own failure — the park or the swap the OS refused, after a clean build — and
|
|
485
|
+
* what is on disk now. The tree-change plan has rolled back: the previous output is in place, or
|
|
486
|
+
* (`TREE_ROLLBACK_INCOMPLETE`) parked under a name the message gives, with the `mv` that restores it.
|
|
957
487
|
*/
|
|
958
|
-
function describePromotionFailure(
|
|
959
|
-
const
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
lines.push(` The previous ${staging.promoteLabel} has been restored; nothing this run built was kept.`);
|
|
488
|
+
function describePromotionFailure(error, target, hadPrevious) {
|
|
489
|
+
const lines = [`Build output promotion failed: ${errorMessageOf(error)}`];
|
|
490
|
+
if (error instanceof TreeRollbackIncompleteError) {
|
|
491
|
+
for (const { parked, dest } of error.stranded) {
|
|
492
|
+
if (parked !== undefined)
|
|
493
|
+
lines.push(` Recover the previous ${target.label} with: mv ${parked} ${dest}`);
|
|
494
|
+
}
|
|
966
495
|
}
|
|
967
|
-
else if (
|
|
968
|
-
lines.push(` The previous ${
|
|
496
|
+
else if (hadPrevious) {
|
|
497
|
+
lines.push(` The previous ${target.label} is intact; nothing this run built was kept.`);
|
|
969
498
|
}
|
|
970
499
|
else {
|
|
971
|
-
lines.push(` ${
|
|
972
|
-
}
|
|
973
|
-
for (const { path, reason } of recovery.residue) {
|
|
974
|
-
lines.push(` Left on disk (this run could not remove it): ${path} — ${reason}`);
|
|
500
|
+
lines.push(` ${target.label} was never written, and there was no previous output to lose.`);
|
|
975
501
|
}
|
|
976
502
|
return lines.join('\n');
|
|
977
503
|
}
|
|
978
|
-
/** The message of whatever was thrown, for a report line. */
|
|
979
|
-
function describeThrown(error) {
|
|
980
|
-
return error instanceof Error ? error.message : String(error);
|
|
981
|
-
}
|
|
982
504
|
/**
|
|
983
505
|
* Merge every skill's config and split the pool skills from the ones this run sets aside.
|
|
984
506
|
*
|
|
@@ -1050,16 +572,18 @@ function pluginOnlySkillRefusal(skill, pluginOnly) {
|
|
|
1050
572
|
+ "Run 'vat build --only claude' to package its plugin, set publish: true to also distribute it through dist/skills, "
|
|
1051
573
|
+ 'or drop --skill.');
|
|
1052
574
|
}
|
|
1053
|
-
/** The human success line
|
|
1054
|
-
export function formatBuiltSuccessLine(built, setAside) {
|
|
575
|
+
/** The human success line over the report's `examined`, naming each non-empty set-aside population. */
|
|
576
|
+
export function formatBuiltSuccessLine(examined, built, setAside) {
|
|
1055
577
|
const tails = [
|
|
1056
578
|
...(setAside.inPlace === 0 ? [] : [`${setAside.inPlace} in-place skill(s) not bundled`]),
|
|
1057
579
|
...(setAside.pluginOnly === 0 ? [] : [`${setAside.pluginOnly} plugin-only skill(s) shipped with their plugin`]),
|
|
1058
580
|
];
|
|
1059
|
-
return `\nBuilt ${built} skill(s) successfully` + (tails.length === 0 ? '' : ` (${tails.join(', ')})`);
|
|
581
|
+
return verdictBanner(examined, `\nBuilt ${built} skill(s) successfully` + (tails.length === 0 ? '' : ` (${tails.join(', ')})`));
|
|
1060
582
|
}
|
|
1061
583
|
/**
|
|
1062
|
-
* Validate, package, and drain — the whole span of ONE `vat build` invocation
|
|
584
|
+
* Validate, package, and drain — the whole span of ONE `vat build` invocation —
|
|
585
|
+
* as the `write` fill of ONE tree-change plan replacing `dist/skills` (or one
|
|
586
|
+
* bundle: {@link buildTarget}), so the output lands only if the build earned it.
|
|
1063
587
|
*
|
|
1064
588
|
* The allow-usage ledger created here spans EVERY skill and BOTH validation
|
|
1065
589
|
* lanes (the source-tree pre-build check and the two lanes inside
|
|
@@ -1075,13 +599,59 @@ export function formatBuiltSuccessLine(built, setAside) {
|
|
|
1075
599
|
*
|
|
1076
600
|
* Extracted from the command body so the span is testable without driving
|
|
1077
601
|
* `process.exit` — the drain seam is the thing worth asserting. Nothing in here
|
|
1078
|
-
* exits: every failure
|
|
1079
|
-
* surfaces all the work rather than the first item of it.
|
|
602
|
+
* exits: every failure that is the adopter's to fix is COLLECTED and returned, so
|
|
603
|
+
* one run surfaces all the work rather than the first item of it. A packager
|
|
604
|
+
* defect is the exception — it leaves the run as itself, and the plan discards
|
|
605
|
+
* what was staged ({@link throwPackagerDefect}). So does a filesystem refusal the
|
|
606
|
+
* build meets: a raw errno on the staged tree is the destination's.
|
|
1080
607
|
*/
|
|
1081
608
|
export async function runSkillBuild(input) {
|
|
1082
|
-
const
|
|
609
|
+
const target = buildTarget(input.cwd, input.onlySkill);
|
|
610
|
+
const notEarned = new BuildNotEarned();
|
|
611
|
+
// A holder, not a `let`: the fill assigns it inside the plan, where flow analysis cannot see.
|
|
612
|
+
const holder = {};
|
|
613
|
+
const plan = await planTreeChanges([{
|
|
614
|
+
op: 'replace',
|
|
615
|
+
dest: target.dest,
|
|
616
|
+
ownership: { kind: 'vat-state' },
|
|
617
|
+
label: target.label,
|
|
618
|
+
fill: {
|
|
619
|
+
from: 'write',
|
|
620
|
+
write: async (staged) => {
|
|
621
|
+
const built = await buildInto(input, target, staged);
|
|
622
|
+
holder.built = built;
|
|
623
|
+
if (built.runFailed)
|
|
624
|
+
throw notEarned;
|
|
625
|
+
},
|
|
626
|
+
},
|
|
627
|
+
}]);
|
|
628
|
+
const hadPrevious = plan.changes[0]?.existing !== 'absent';
|
|
629
|
+
let warnings;
|
|
630
|
+
try {
|
|
631
|
+
({ warnings } = await applyTreePlan(plan));
|
|
632
|
+
}
|
|
633
|
+
catch (error) {
|
|
634
|
+
// Thrown before the build finished: the build's own refusal, nothing changed.
|
|
635
|
+
if (holder.built === undefined)
|
|
636
|
+
throw error;
|
|
637
|
+
const { run } = holder.built;
|
|
638
|
+
if (error !== notEarned) {
|
|
639
|
+
return { ...run, outputCommitted: false, residue: [], promotionFailure: { error, description: describePromotionFailure(error, target, hadPrevious) } };
|
|
640
|
+
}
|
|
641
|
+
input.logger.error(hadPrevious
|
|
642
|
+
? `\n Nothing was replaced — the previous ${target.label} is intact`
|
|
643
|
+
: `\n Nothing was written — ${target.label} does not exist`);
|
|
644
|
+
return { ...run, outputCommitted: false, residue: leftoverFindingsOf(error) };
|
|
645
|
+
}
|
|
646
|
+
// The plan resolves only once its fill has run, so a run is there.
|
|
647
|
+
if (holder.built === undefined)
|
|
648
|
+
throw new Error('vat skills build: the plan resolved without running its build');
|
|
649
|
+
return { ...holder.built.run, outputCommitted: true, residue: warnings.map(({ message, path }) => leftoverIssue(message, path)) };
|
|
650
|
+
}
|
|
651
|
+
/** The build itself, into `staged`: every skill validated, the ones that qualified packaged, the outcome judged. */
|
|
652
|
+
async function buildInto(input, target, staged) {
|
|
653
|
+
const { specs, cwd, logger, projectSkills, verbose } = input;
|
|
1083
654
|
const allowLedger = createAllowUsageLedger();
|
|
1084
|
-
const staging = await beginStagedBuild(cwd, onlySkill);
|
|
1085
655
|
// Validate every skill before building ANY of them, and keep going past the
|
|
1086
656
|
// ones that fail: a rejected source is a finding to report, not a reason to
|
|
1087
657
|
// stop looking. The path logged is the FINAL one — it is where the bundle will
|
|
@@ -1118,8 +688,13 @@ export async function runSkillBuild(input) {
|
|
|
1118
688
|
// NOT module-scoped: the answer is a filesystem snapshot, so a cache outliving the
|
|
1119
689
|
// run would keep answering for a tree that has since changed.
|
|
1120
690
|
const suiteProbe = conventionalSuiteProbe();
|
|
691
|
+
// What this run writes — the tree it replaces and the staging it builds it in — declared
|
|
692
|
+
// ONCE for every crawl of the project (which lists `dist/` too): a fault on, in or above
|
|
693
|
+
// them is the run's destination, never its input.
|
|
694
|
+
const outputs = [target.dest, staged, ...input.runOutputs];
|
|
1121
695
|
const outcomes = await withResourcePopulationSource({ root: cwd }, async (populationSource) => {
|
|
1122
|
-
|
|
696
|
+
// In order: shared population source, suite probe and logger; failures listed in spec order.
|
|
697
|
+
await forEachInOrder(specs, async (spec) => {
|
|
1123
698
|
const { skill, packagingConfig } = spec;
|
|
1124
699
|
logger.info(`\nBuilding skill: ${skill.name}`);
|
|
1125
700
|
logger.info(` Source: ${skill.sourcePath}`);
|
|
@@ -1135,13 +710,14 @@ export async function runSkillBuild(input) {
|
|
|
1135
710
|
suiteProbe,
|
|
1136
711
|
populationSource,
|
|
1137
712
|
verbose,
|
|
713
|
+
outputs,
|
|
1138
714
|
});
|
|
1139
715
|
if (failure) {
|
|
1140
716
|
validationFailures.push(failure);
|
|
1141
|
-
|
|
717
|
+
return;
|
|
1142
718
|
}
|
|
1143
719
|
buildable.push(spec);
|
|
1144
|
-
}
|
|
720
|
+
});
|
|
1145
721
|
// Build the skills that qualified, with a shared registry.
|
|
1146
722
|
//
|
|
1147
723
|
// `projectSkills` is the run's declared eval suites — the whole project's, not
|
|
@@ -1150,11 +726,9 @@ export async function runSkillBuild(input) {
|
|
|
1150
726
|
// not ship inside x's bundle.
|
|
1151
727
|
const buildSpecs = buildable.map(({ skill, packagingConfig }) => ({
|
|
1152
728
|
skillPath: skill.sourcePath,
|
|
1153
|
-
options: packagingConfigToPackageOptions(packagingConfig,
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
outputPath: safePath.join(staging.root, skillNameToFsPath(skill.name)),
|
|
1157
|
-
}, projectSkills, suiteProbe),
|
|
729
|
+
options: packagingConfigToPackageOptions(packagingConfig,
|
|
730
|
+
// Into the staged tree, not dist/skills: see `buildTarget`.
|
|
731
|
+
{ skillPath: skill.sourcePath, outputPath: target.bundleIn(staged, skill.name) }, projectSkills, suiteProbe),
|
|
1158
732
|
}));
|
|
1159
733
|
// `packageSkills` builds THE registry for the run, so this is the only seam
|
|
1160
734
|
// that can put `vat skills build` — and therefore `vat build`'s packaging
|
|
@@ -1162,13 +736,42 @@ export async function runSkillBuild(input) {
|
|
|
1162
736
|
// to whatever the source offers, so what gets packaged is unchanged; only how
|
|
1163
737
|
// the file list was obtained differs.
|
|
1164
738
|
return packageSkills(buildSpecs, cwd, allowLedger, {
|
|
739
|
+
outputs,
|
|
1165
740
|
...(populationSource !== undefined && { populationSource }),
|
|
1166
741
|
});
|
|
1167
742
|
});
|
|
743
|
+
throwPackagerDefect(outcomes);
|
|
744
|
+
const packaged = judgeOutcomes(buildable, outcomes, stagedPathMapper(cwd, staged, target.dest), logger, verbose);
|
|
745
|
+
// Drain point: every skill and every lane has now contributed, so this is the
|
|
746
|
+
// first place the run can honestly say an entry matched nothing. A skill that
|
|
747
|
+
// threw still contributed the matches it made before throwing — which is why
|
|
748
|
+
// the drain must stay here, after a partially-failed batch, and not move into
|
|
749
|
+
// a success-only path. (Before per-skill containment the drain never ran at
|
|
750
|
+
// all on a throw, because the exception propagated straight past it.)
|
|
751
|
+
//
|
|
752
|
+
// Known residual: a skill that threw never reached its later lanes, so an
|
|
753
|
+
// allow entry only THAT skill could have matched may now be reported
|
|
754
|
+
// ALLOW_UNUSED. That is a warning, and `runHasErrors` gates on `error` only,
|
|
755
|
+
// so it cannot fail a build on its own — and the run is already exiting 1 on
|
|
756
|
+
// the failure the operator actually needs to fix.
|
|
757
|
+
const runIssues = allowUnusedIssues(allowLedger);
|
|
758
|
+
// ONE predicate, evaluated once, for BOTH "does dist/skills get replaced" and
|
|
759
|
+
// (via `outputCommitted`) "what does the command exit with". Two definitions
|
|
760
|
+
// of "this run failed" is how a report ends up disagreeing with the disk and
|
|
761
|
+
// with the exit code — the failure mode this whole summary exists to prevent.
|
|
762
|
+
// A run-level ALLOW_UNUSED is a `warning`, so it is not in here: a warning must
|
|
763
|
+
// never discard artifacts that were produced correctly.
|
|
764
|
+
const runFailed = packaged.failures.length > 0
|
|
765
|
+
|| validationFailures.length > 0
|
|
766
|
+
|| packaged.skillsWithErrors.length > 0
|
|
767
|
+
|| runIssues.some((i) => i.severity === 'error');
|
|
768
|
+
return { run: { ...packaged, runIssues, validationFailures }, runFailed };
|
|
769
|
+
}
|
|
770
|
+
/** Each packaged skill's outcome, re-anchored and logged: what built, what errored after building, what the packager refused. */
|
|
771
|
+
function judgeOutcomes(buildable, outcomes, mapStagedPath, logger, verbose) {
|
|
1168
772
|
const results = [];
|
|
1169
773
|
const skillsWithErrors = [];
|
|
1170
774
|
const failures = [];
|
|
1171
|
-
const mapStagedPath = createStagingPathMapper(cwd, staging.root);
|
|
1172
775
|
let collapsedFindings = 0;
|
|
1173
776
|
for (const [i, spec] of buildable.entries()) {
|
|
1174
777
|
const outcome = outcomes[i];
|
|
@@ -1180,13 +783,13 @@ export async function runSkillBuild(input) {
|
|
|
1180
783
|
// absent bundle is the misreport this branch exists to avoid.
|
|
1181
784
|
logger.error(`\nBuild failed for skill: ${skillName}`);
|
|
1182
785
|
logger.error(` ${outcome.error.message}`);
|
|
1183
|
-
failures.push({ name: skillName, message: outcome.error.message });
|
|
786
|
+
failures.push({ name: skillName, message: outcome.error.message, error: outcome.error });
|
|
1184
787
|
continue;
|
|
1185
788
|
}
|
|
1186
789
|
// Re-anchored BEFORE anything reads it — the report below and the published
|
|
1187
790
|
// row both. The bundle was written under staging, and staging is transient
|
|
1188
791
|
// in both outcomes, so any path that survives this call unmapped is a path
|
|
1189
|
-
// its reader cannot open. See `
|
|
792
|
+
// its reader cannot open. See `stagedPathMapper` (agent-skills).
|
|
1190
793
|
const result = reanchorStagedResult(outcome.result, mapStagedPath);
|
|
1191
794
|
// Named, because this line is printed in a SECOND pass: the validation pass
|
|
1192
795
|
// above emits every `Building skill: <name>` banner first, so at scale (92
|
|
@@ -1206,39 +809,21 @@ export async function runSkillBuild(input) {
|
|
|
1206
809
|
const collapsedHint = formatCollapsedFindingsHint(collapsedFindings, 'build');
|
|
1207
810
|
if (collapsedHint !== undefined)
|
|
1208
811
|
logger.info(collapsedHint);
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
const
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
// of "this run failed" is how a report ends up disagreeing with the disk and
|
|
1225
|
-
// with the exit code — the failure mode this whole summary exists to prevent.
|
|
1226
|
-
// A run-level ALLOW_UNUSED is a `warning`, so it is not in here: a warning must
|
|
1227
|
-
// never discard artifacts that were produced correctly.
|
|
1228
|
-
const runFailed = failures.length > 0
|
|
1229
|
-
|| validationFailures.length > 0
|
|
1230
|
-
|| skillsWithErrors.length > 0
|
|
1231
|
-
|| runIssues.some((i) => i.severity === 'error');
|
|
1232
|
-
const { outputCommitted, promotionError } = await settleStaging(staging, runFailed, logger);
|
|
1233
|
-
return {
|
|
1234
|
-
results,
|
|
1235
|
-
runIssues,
|
|
1236
|
-
skillsWithErrors,
|
|
1237
|
-
failures,
|
|
1238
|
-
validationFailures,
|
|
1239
|
-
outputCommitted,
|
|
1240
|
-
...(promotionError === undefined ? {} : { promotionError }),
|
|
1241
|
-
};
|
|
812
|
+
return { results, skillsWithErrors, failures };
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Leave the run on the first packager throw that is not the packager refusing
|
|
816
|
+
* the skill's own content — the contract `vat skills package`, `vat agent
|
|
817
|
+
* build`, `vat claude plugin build` and `vat skill test run` implement, through
|
|
818
|
+
* the same predicate. Such a throw is not the adopter's to fix, so it is never a
|
|
819
|
+
* `SKILL_PACKAGING_FAILED` finding telling them to: it is rethrown as itself and
|
|
820
|
+
* published by its own code (`INTERNAL_ERROR` when it has none). The plan it is
|
|
821
|
+
* thrown inside discards what was staged, so the previous output stays.
|
|
822
|
+
*/
|
|
823
|
+
function throwPackagerDefect(outcomes) {
|
|
824
|
+
const defect = outcomes.find((outcome) => outcome.status === 'failed' && !isSkillPackagingInputError(outcome.error));
|
|
825
|
+
if (defect?.status === 'failed')
|
|
826
|
+
throw defect.error;
|
|
1242
827
|
}
|
|
1243
828
|
/**
|
|
1244
829
|
* Name every way this run failed, on stderr, one section per population.
|
|
@@ -1273,70 +858,92 @@ function logRunFailures(run, logger) {
|
|
|
1273
858
|
logger.error(`\nBuild failed: run-level validation errors (project config, not any one skill)`);
|
|
1274
859
|
}
|
|
1275
860
|
}
|
|
861
|
+
/** A report for a run that built nothing, from the skills it examined. */
|
|
862
|
+
function earlyReport(input, startTime) {
|
|
863
|
+
return buildReport({ ...skillsBuildWork({ ...input, run: undefined }), gate: GATE, durationMs: Date.now() - startTime });
|
|
864
|
+
}
|
|
865
|
+
const NO_SKILLS = { inPlace: [], pluginOnly: [] };
|
|
866
|
+
async function prepareBuild(cwd, options, logger, startTime) {
|
|
867
|
+
const empty = { cwd, skills: [], setAside: NO_SKILLS, dryRun: options.dryRun === true, setAsideIssues: [] };
|
|
868
|
+
// Spec §7: `vat skills build` requires a projectRoot. The resolved root is
|
|
869
|
+
// discarded: config is read from `cwd` (the package dir), not the project root.
|
|
870
|
+
requireProjectRoot(cwd, 'vat skills build');
|
|
871
|
+
const config = loadConfig(cwd, 'destination');
|
|
872
|
+
if (!config?.skills) {
|
|
873
|
+
// Examined nothing: the writer refuses the command lane's report. In `vat
|
|
874
|
+
// build` this phase's zero is an answer, since a project with no `skills:`
|
|
875
|
+
// block has no pool to build (see `selectBuildPhases`).
|
|
876
|
+
logger.info('No skills configuration found — nothing to build');
|
|
877
|
+
return { kind: 'done', report: earlyReport(empty, startTime) };
|
|
878
|
+
}
|
|
879
|
+
const skillsConfig = config.skills;
|
|
880
|
+
logger.info(`Discovering skills from config...`);
|
|
881
|
+
// `'refuse'`: a build that silently ships fewer skills is the drop this
|
|
882
|
+
// command exists to prevent — the coded throw is the report's refusal.
|
|
883
|
+
const discoveredSkills = await discoverSkillsFromConfig(skillsConfig, cwd, 'refuse');
|
|
884
|
+
if (discoveredSkills.length === 0) {
|
|
885
|
+
// Before the staging swap, so a glob typo never promotes an EMPTY dist/skills.
|
|
886
|
+
logger.error(`No SKILL.md files found matching include patterns: ${skillsConfig.include.join(', ')}`);
|
|
887
|
+
return { kind: 'done', report: earlyReport(empty, startTime) };
|
|
888
|
+
}
|
|
889
|
+
// Filter by name, then set the `publish: false` skills aside BEFORE the count
|
|
890
|
+
// is announced: "Found N skill(s) to build" is the number this run bundles.
|
|
891
|
+
// Plugin-local = a skill dir the plugin build packages (the same index the
|
|
892
|
+
// consistency check and `vat verify` ask): such a skill is never in place.
|
|
893
|
+
const { buildSpecs, inPlace, pluginOnly } = partitionInPlaceSkills(filterSkillsByName(discoveredSkills, options.skill), skillsConfig, indexPluginLocalSkills(config, cwd));
|
|
894
|
+
const setAside = {
|
|
895
|
+
inPlace: inPlace.map((spec) => spec.skill.name),
|
|
896
|
+
pluginOnly: pluginOnly.map((spec) => spec.skill.name),
|
|
897
|
+
};
|
|
898
|
+
const planned = { ...empty, skills: buildSpecs.map((spec) => spec.skill), setAside };
|
|
899
|
+
const refusal = inPlaceSkillRefusal(options.skill, inPlace) ?? pluginOnlySkillRefusal(options.skill, pluginOnly);
|
|
900
|
+
const target = [...inPlace, ...pluginOnly][0];
|
|
901
|
+
if (refusal !== undefined && target !== undefined) {
|
|
902
|
+
logger.error(refusal.message);
|
|
903
|
+
const issue = notBuildableIssue(refusal.message, reportLocation(cwd, target.skill.sourcePath));
|
|
904
|
+
return { kind: 'done', report: earlyReport({ ...planned, setAsideIssues: [issue] }, startTime) };
|
|
905
|
+
}
|
|
906
|
+
logInPlaceSkills(inPlace, logger);
|
|
907
|
+
logPluginOnlySkills(pluginOnly, logger);
|
|
908
|
+
logger.info(`Found ${buildSpecs.length} skill(s) to build`);
|
|
909
|
+
// Nothing has touched `dist/` yet — the staging directory and the swap live
|
|
910
|
+
// inside `runSkillBuild`, which a dry run never reaches.
|
|
911
|
+
if (options.dryRun) {
|
|
912
|
+
performDryRun(planned.skills, setAside, logger);
|
|
913
|
+
return { kind: 'done', report: earlyReport(planned, startTime) };
|
|
914
|
+
}
|
|
915
|
+
// From the UNFILTERED discovery: `--skill x` narrows the build, not the set
|
|
916
|
+
// of files that count as some skill's declared test input.
|
|
917
|
+
return { kind: 'build', buildSpecs, setAside, projectSkills: collectDeclaredEvalSuites(skillsConfig, discoveredSkills) };
|
|
918
|
+
}
|
|
1276
919
|
/**
|
|
1277
|
-
*
|
|
1278
|
-
* printing
|
|
1279
|
-
*
|
|
1280
|
-
*
|
|
1281
|
-
*
|
|
1282
|
-
* run
|
|
920
|
+
* Run `vat skills build` and hand back its report — the refusal branch when it
|
|
921
|
+
* could not run — printing it nowhere.
|
|
922
|
+
*
|
|
923
|
+
* ONE function for both lanes: the command publishes it with `endWithReport`,
|
|
924
|
+
* and `vat build`'s `skills` phase folds it. The report is the one BEFORE the
|
|
925
|
+
* writer's run-integrity pass: zero skills fails `vat skills build`, and in
|
|
926
|
+
* `vat build` is judged per phase (`selectBuildPhases`) — an answer for a project
|
|
927
|
+
* with no `skills:` block or one that ships plugin-local skills, the same refusal otherwise.
|
|
1283
928
|
*/
|
|
1284
|
-
export async function runSkillsBuildPhase(pathArg, options) {
|
|
929
|
+
export async function runSkillsBuildPhase(pathArg, options, runOutputs) {
|
|
1285
930
|
const { logger, cwd, startTime } = setupCommandContext(pathArg, options.debug);
|
|
931
|
+
// What a refusal carries: nothing until discovery has run, then the skills it
|
|
932
|
+
// found — a staging refusal comes AFTER "Found N skill(s)", and `examined: 0`
|
|
933
|
+
// there contradicted the line the operator just read.
|
|
934
|
+
let finished = NOTHING_FINISHED;
|
|
1286
935
|
try {
|
|
1287
|
-
//
|
|
1288
|
-
//
|
|
1289
|
-
//
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
}
|
|
1298
|
-
const skillsConfig = config.skills;
|
|
1299
|
-
// Discover SKILL.md files from config globs (relative to cwd where config lives)
|
|
1300
|
-
logger.info(`Discovering skills from config...`);
|
|
1301
|
-
// `'refuse'`: a build that silently ships fewer skills is the drop this
|
|
1302
|
-
// command exists to prevent. The throw lands in the catch below →
|
|
1303
|
-
// `reportCommandError`, exit 2.
|
|
1304
|
-
const discoveredSkills = await discoverSkillsFromConfig(skillsConfig, cwd, 'refuse');
|
|
1305
|
-
if (discoveredSkills.length === 0) {
|
|
1306
|
-
throw new Error(`No SKILL.md files found matching include patterns: ${skillsConfig.include.join(', ')}`);
|
|
1307
|
-
}
|
|
1308
|
-
// Filter by skill name if specified, then set the in-place skills aside.
|
|
1309
|
-
// `publish: false` names a skill the pool never carries (see
|
|
1310
|
-
// `isSkillPublished`), so the partition happens BEFORE the count is announced:
|
|
1311
|
-
// "Found N skill(s) to build" must be the number this run will bundle.
|
|
1312
|
-
// Plugin-local = a skill dir the plugin build packages (the same index the
|
|
1313
|
-
// consistency check and `vat verify` ask): such a skill is never in place.
|
|
1314
|
-
const { buildSpecs, inPlace, pluginOnly } = partitionInPlaceSkills(filterSkillsByName(discoveredSkills, options.skill), skillsConfig, indexPluginLocalSkills(config, cwd));
|
|
1315
|
-
const refusal = inPlaceSkillRefusal(options.skill, inPlace) ?? pluginOnlySkillRefusal(options.skill, pluginOnly);
|
|
1316
|
-
if (refusal !== undefined) {
|
|
1317
|
-
return { document: reportCommandError(refusal, logger, startTime, 'SkillsBuild'), exitCode: 1, failed: true };
|
|
1318
|
-
}
|
|
1319
|
-
logInPlaceSkills(inPlace, logger);
|
|
1320
|
-
logPluginOnlySkills(pluginOnly, logger);
|
|
1321
|
-
logger.info(`Found ${buildSpecs.length} skill(s) to build`);
|
|
1322
|
-
const setAside = {
|
|
1323
|
-
inPlace: inPlace.map((spec) => spec.skill.name),
|
|
1324
|
-
pluginOnly: pluginOnly.map((spec) => spec.skill.name),
|
|
1325
|
-
};
|
|
1326
|
-
// Handle dry-run mode. Nothing has touched `dist/` at this point — the
|
|
1327
|
-
// staging directory and the swap both live inside `runSkillBuild`, which a
|
|
1328
|
-
// dry run never reaches, so "preview without creating files" is now true of
|
|
1329
|
-
// the OUTPUT TREE as well as of the bundles. (The old flow deleted
|
|
1330
|
-
// `dist/skills` before this branch and relied on an `if (!options.dryRun)`
|
|
1331
|
-
// guard three lines up to stay honest.)
|
|
1332
|
-
if (options.dryRun) {
|
|
1333
|
-
const duration = Date.now() - startTime;
|
|
1334
|
-
performDryRun(buildSpecs.map((spec) => spec.skill), setAside, duration, logger);
|
|
1335
|
-
return { document: undefined, exitCode: 0 };
|
|
1336
|
-
}
|
|
1337
|
-
// Assembled ONCE, from the UNFILTERED discovery: `--skill x` narrows the build,
|
|
1338
|
-
// not the set of files that count as some skill's declared test input.
|
|
1339
|
-
const projectSkills = collectDeclaredEvalSuites(skillsConfig, discoveredSkills);
|
|
936
|
+
// A `[path]` naming no directory, or none holding a config, is the
|
|
937
|
+
// invocation's mistake (or the input's, when the OS refuses it) — never a
|
|
938
|
+
// silent build of nothing.
|
|
939
|
+
assertScopableSkillsPath(SCOPE_SUBJECT, pathArg);
|
|
940
|
+
const prepared = await prepareBuild(cwd, options, logger, startTime);
|
|
941
|
+
if (prepared.kind === 'done')
|
|
942
|
+
return prepared;
|
|
943
|
+
const { buildSpecs, setAside, projectSkills } = prepared;
|
|
944
|
+
finished = skillsBuildWork({
|
|
945
|
+
cwd, skills: buildSpecs.map((spec) => spec.skill), setAside, dryRun: false, run: undefined, setAsideIssues: [],
|
|
946
|
+
});
|
|
1340
947
|
const run = await runSkillBuild({
|
|
1341
948
|
specs: buildSpecs,
|
|
1342
949
|
cwd,
|
|
@@ -1344,45 +951,35 @@ export async function runSkillsBuildPhase(pathArg, options) {
|
|
|
1344
951
|
projectSkills,
|
|
1345
952
|
onlySkill: options.skill,
|
|
1346
953
|
verbose: options.verbose === true,
|
|
954
|
+
runOutputs,
|
|
1347
955
|
});
|
|
1348
|
-
const duration = Date.now() - startTime;
|
|
1349
|
-
const document = buildBuildDocument(run, setAside, duration);
|
|
1350
956
|
for (const line of formatRunIssueLines(run.runIssues)) {
|
|
1351
957
|
logger.info(line);
|
|
1352
958
|
}
|
|
1353
959
|
logRunFailures(run, logger);
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
//
|
|
1358
|
-
//
|
|
1359
|
-
//
|
|
1360
|
-
if (run.
|
|
1361
|
-
|
|
1362
|
-
return {
|
|
960
|
+
const work = skillsBuildWork({
|
|
961
|
+
cwd, skills: buildSpecs.map((spec) => spec.skill), setAside, dryRun: false, run, setAsideIssues: [],
|
|
962
|
+
});
|
|
963
|
+
// The promotion itself failed: the filesystem refused the swap — a refusal
|
|
964
|
+
// (exit 2) under the failure's own code, carrying everything the run found,
|
|
965
|
+
// `data.promotionError` naming what is on disk and how to recover it.
|
|
966
|
+
if (run.promotionFailure !== undefined) {
|
|
967
|
+
const { error } = run.promotionFailure;
|
|
968
|
+
return { report: refusalReport(refusalCodeOf(error), error, GATE, work) };
|
|
1363
969
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
if (!run.outputCommitted) {
|
|
1368
|
-
return { document, exitCode: 1 };
|
|
970
|
+
const report = buildReport({ ...work, gate: GATE, durationMs: Date.now() - startTime });
|
|
971
|
+
if (run.outputCommitted) {
|
|
972
|
+
logger.info(formatBuiltSuccessLine(report.examined, run.results.length, { inPlace: setAside.inPlace.length, pluginOnly: setAside.pluginOnly.length }));
|
|
1369
973
|
}
|
|
1370
|
-
|
|
1371
|
-
return { document, exitCode: 0 };
|
|
974
|
+
return { report };
|
|
1372
975
|
}
|
|
1373
976
|
catch (error) {
|
|
1374
|
-
return {
|
|
1375
|
-
document: reportCommandError(error, logger, startTime, 'SkillsBuild'),
|
|
1376
|
-
exitCode: 2,
|
|
1377
|
-
failed: true,
|
|
1378
|
-
};
|
|
977
|
+
return { report: refusalReport(refusalCodeOf(error), error, GATE, finished) };
|
|
1379
978
|
}
|
|
1380
979
|
}
|
|
1381
980
|
async function buildCommand(pathArg, options) {
|
|
1382
|
-
//
|
|
1383
|
-
//
|
|
1384
|
-
|
|
1385
|
-
outputBuildYaml(document);
|
|
1386
|
-
}, undefined);
|
|
981
|
+
// This command offers no `--format`: the report is YAML.
|
|
982
|
+
// On its own, this verb writes nothing but dist/skills.
|
|
983
|
+
endWithReport('skills build', (await runSkillsBuildPhase(pathArg, options, [])).report, 'yaml');
|
|
1387
984
|
}
|
|
1388
985
|
//# sourceMappingURL=build.js.map
|