@vibe-agent-toolkit/cli 0.2.0-rc.1 → 0.2.0-rc.10
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 +4 -5
- package/dist/bin/vat +95 -28
- package/dist/bin/vat.js +95 -28
- package/dist/bin/vat.js.map +1 -1
- package/dist/bin.js +115 -76
- package/dist/bin.js.map +1 -1
- package/dist/command-loaders.d.ts +44 -0
- package/dist/command-loaders.d.ts.map +1 -0
- package/dist/command-loaders.js +60 -0
- package/dist/command-loaders.js.map +1 -0
- package/dist/commands/agent/build.d.ts.map +1 -1
- package/dist/commands/agent/build.js +2 -1
- package/dist/commands/agent/build.js.map +1 -1
- package/dist/commands/agent/import.d.ts.map +1 -1
- package/dist/commands/agent/import.js +3 -2
- package/dist/commands/agent/import.js.map +1 -1
- package/dist/commands/agent/index.js +1 -1
- package/dist/commands/agent/install-path.d.ts +36 -0
- package/dist/commands/agent/install-path.d.ts.map +1 -0
- package/dist/commands/agent/install-path.js +44 -0
- package/dist/commands/agent/install-path.js.map +1 -0
- package/dist/commands/agent/install.d.ts.map +1 -1
- package/dist/commands/agent/install.js +66 -13
- package/dist/commands/agent/install.js.map +1 -1
- package/dist/commands/agent/installed.d.ts.map +1 -1
- package/dist/commands/agent/installed.js +22 -12
- package/dist/commands/agent/installed.js.map +1 -1
- package/dist/commands/agent/list.d.ts.map +1 -1
- package/dist/commands/agent/list.js +2 -1
- package/dist/commands/agent/list.js.map +1 -1
- package/dist/commands/agent/run.d.ts.map +1 -1
- package/dist/commands/agent/run.js +2 -1
- package/dist/commands/agent/run.js.map +1 -1
- package/dist/commands/agent/uninstall.d.ts.map +1 -1
- package/dist/commands/agent/uninstall.js +13 -6
- package/dist/commands/agent/uninstall.js.map +1 -1
- package/dist/commands/agent/validate.d.ts.map +1 -1
- package/dist/commands/agent/validate.js +3 -2
- package/dist/commands/agent/validate.js.map +1 -1
- package/dist/commands/ard/emit.d.ts +153 -0
- package/dist/commands/ard/emit.d.ts.map +1 -0
- package/dist/commands/ard/emit.js +276 -0
- package/dist/commands/ard/emit.js.map +1 -0
- package/dist/commands/ard/index.d.ts +12 -0
- package/dist/commands/ard/index.d.ts.map +1 -0
- package/dist/commands/ard/index.js +80 -0
- package/dist/commands/ard/index.js.map +1 -0
- package/dist/commands/ard/surfaces.d.ts +56 -0
- package/dist/commands/ard/surfaces.d.ts.map +1 -0
- package/dist/commands/ard/surfaces.js +150 -0
- package/dist/commands/ard/surfaces.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 +11 -7
- package/dist/commands/audit/distributed-tree.js.map +1 -1
- package/dist/commands/audit/git-url-clone.d.ts +1 -1
- package/dist/commands/audit/git-url-clone.d.ts.map +1 -1
- package/dist/commands/audit/git-url-clone.js.map +1 -1
- package/dist/commands/audit/hierarchical-output.d.ts +1 -1
- package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
- package/dist/commands/audit/hierarchical-output.js +1 -1
- package/dist/commands/audit/hierarchical-output.js.map +1 -1
- package/dist/commands/audit/provenance.d.ts.map +1 -1
- package/dist/commands/audit/provenance.js +4 -3
- package/dist/commands/audit/provenance.js.map +1 -1
- package/dist/commands/audit/scan-population.d.ts +158 -0
- package/dist/commands/audit/scan-population.d.ts.map +1 -0
- package/dist/commands/audit/scan-population.js +292 -0
- package/dist/commands/audit/scan-population.js.map +1 -0
- package/dist/commands/audit-settings.d.ts.map +1 -1
- package/dist/commands/audit-settings.js +6 -5
- package/dist/commands/audit-settings.js.map +1 -1
- package/dist/commands/audit.d.ts +98 -8
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +1126 -394
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/build.d.ts +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +40 -36
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/cache/cache-control.d.ts +82 -0
- package/dist/commands/cache/cache-control.d.ts.map +1 -0
- package/dist/commands/cache/cache-control.js +86 -0
- package/dist/commands/cache/cache-control.js.map +1 -0
- package/dist/commands/cache/clear.d.ts +34 -6
- package/dist/commands/cache/clear.d.ts.map +1 -1
- package/dist/commands/cache/clear.js +101 -15
- package/dist/commands/cache/clear.js.map +1 -1
- package/dist/commands/cache/index.d.ts +13 -63
- package/dist/commands/cache/index.d.ts.map +1 -1
- package/dist/commands/cache/index.js +47 -79
- package/dist/commands/cache/index.js.map +1 -1
- package/dist/commands/claude/claude-config.d.ts.map +1 -1
- package/dist/commands/claude/claude-config.js +6 -0
- package/dist/commands/claude/claude-config.js.map +1 -1
- package/dist/commands/claude/context.d.ts +340 -0
- package/dist/commands/claude/context.d.ts.map +1 -0
- package/dist/commands/claude/context.js +1080 -0
- package/dist/commands/claude/context.js.map +1 -0
- package/dist/commands/claude/index.d.ts +14 -0
- package/dist/commands/claude/index.d.ts.map +1 -1
- package/dist/commands/claude/index.js +22 -2
- package/dist/commands/claude/index.js.map +1 -1
- package/dist/commands/claude/marketplace/changelog-utils.d.ts +1 -1
- package/dist/commands/claude/marketplace/changelog-utils.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/changelog-utils.js +1 -2
- package/dist/commands/claude/marketplace/changelog-utils.js.map +1 -1
- package/dist/commands/claude/marketplace/git-publish.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/git-publish.js +40 -31
- package/dist/commands/claude/marketplace/git-publish.js.map +1 -1
- package/dist/commands/claude/marketplace/license-utils.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/license-utils.js +0 -1
- package/dist/commands/claude/marketplace/license-utils.js.map +1 -1
- package/dist/commands/claude/marketplace/publish-tree.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/publish-tree.js +0 -6
- package/dist/commands/claude/marketplace/publish-tree.js.map +1 -1
- package/dist/commands/claude/marketplace/publish.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/publish.js +2 -1
- package/dist/commands/claude/marketplace/publish.js.map +1 -1
- package/dist/commands/claude/marketplace/validate.d.ts +73 -22
- package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/validate.js +407 -72
- package/dist/commands/claude/marketplace/validate.js.map +1 -1
- package/dist/commands/claude/org/api-keys.d.ts +0 -3
- package/dist/commands/claude/org/api-keys.d.ts.map +1 -1
- package/dist/commands/claude/org/api-keys.js +2 -1
- package/dist/commands/claude/org/api-keys.js.map +1 -1
- package/dist/commands/claude/org/helpers.d.ts +54 -1
- package/dist/commands/claude/org/helpers.d.ts.map +1 -1
- package/dist/commands/claude/org/helpers.js +42 -7
- 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 +24 -16
- package/dist/commands/claude/org/index.js.map +1 -1
- package/dist/commands/claude/org/invites.d.ts +0 -3
- package/dist/commands/claude/org/invites.d.ts.map +1 -1
- package/dist/commands/claude/org/invites.js +3 -2
- package/dist/commands/claude/org/invites.js.map +1 -1
- package/dist/commands/claude/org/skills.d.ts +527 -0
- package/dist/commands/claude/org/skills.d.ts.map +1 -1
- package/dist/commands/claude/org/skills.js +1414 -108
- package/dist/commands/claude/org/skills.js.map +1 -1
- package/dist/commands/claude/org/users.d.ts +0 -3
- package/dist/commands/claude/org/users.d.ts.map +1 -1
- package/dist/commands/claude/org/users.js +6 -3
- package/dist/commands/claude/org/users.js.map +1 -1
- package/dist/commands/claude/org/workspaces.d.ts +0 -3
- package/dist/commands/claude/org/workspaces.d.ts.map +1 -1
- package/dist/commands/claude/org/workspaces.js +11 -7
- package/dist/commands/claude/org/workspaces.js.map +1 -1
- package/dist/commands/claude/plugin/build.d.ts +41 -3
- package/dist/commands/claude/plugin/build.d.ts.map +1 -1
- package/dist/commands/claude/plugin/build.js +147 -80
- package/dist/commands/claude/plugin/build.js.map +1 -1
- package/dist/commands/claude/plugin/helpers.d.ts.map +1 -1
- package/dist/commands/claude/plugin/helpers.js +2 -7
- package/dist/commands/claude/plugin/helpers.js.map +1 -1
- package/dist/commands/claude/plugin/install.d.ts +12 -0
- package/dist/commands/claude/plugin/install.d.ts.map +1 -1
- package/dist/commands/claude/plugin/install.js +93 -62
- package/dist/commands/claude/plugin/install.js.map +1 -1
- package/dist/commands/claude/plugin/list.d.ts.map +1 -1
- package/dist/commands/claude/plugin/list.js +3 -2
- package/dist/commands/claude/plugin/list.js.map +1 -1
- package/dist/commands/claude/plugin/marketplace-json.d.ts +24 -9
- package/dist/commands/claude/plugin/marketplace-json.d.ts.map +1 -1
- package/dist/commands/claude/plugin/marketplace-json.js +10 -9
- package/dist/commands/claude/plugin/marketplace-json.js.map +1 -1
- package/dist/commands/claude/plugin/plugin-changelog.d.ts.map +1 -1
- package/dist/commands/claude/plugin/plugin-changelog.js +0 -2
- package/dist/commands/claude/plugin/plugin-changelog.js.map +1 -1
- package/dist/commands/claude/plugin/plugin-files.d.ts.map +1 -1
- package/dist/commands/claude/plugin/plugin-files.js +3 -6
- package/dist/commands/claude/plugin/plugin-files.js.map +1 -1
- package/dist/commands/claude/plugin/plugin-validators.d.ts.map +1 -1
- package/dist/commands/claude/plugin/plugin-validators.js +3 -6
- package/dist/commands/claude/plugin/plugin-validators.js.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.d.ts +73 -0
- package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.js +221 -14
- package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
- package/dist/commands/claude/plugin/uninstall.d.ts.map +1 -1
- package/dist/commands/claude/plugin/uninstall.js +4 -4
- package/dist/commands/claude/plugin/uninstall.js.map +1 -1
- package/dist/commands/consistency-check.d.ts +17 -15
- package/dist/commands/consistency-check.d.ts.map +1 -1
- package/dist/commands/consistency-check.js +152 -106
- 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 +3 -0
- package/dist/commands/corpus/index.js.map +1 -1
- package/dist/commands/corpus/report.d.ts +1 -2
- package/dist/commands/corpus/report.d.ts.map +1 -1
- package/dist/commands/corpus/report.js +1 -3
- package/dist/commands/corpus/report.js.map +1 -1
- package/dist/commands/corpus/runner.d.ts +58 -1
- package/dist/commands/corpus/runner.d.ts.map +1 -1
- package/dist/commands/corpus/runner.js +95 -41
- package/dist/commands/corpus/runner.js.map +1 -1
- package/dist/commands/corpus/scan.d.ts.map +1 -1
- package/dist/commands/corpus/scan.js +20 -12
- package/dist/commands/corpus/scan.js.map +1 -1
- package/dist/commands/corpus/seed.d.ts +4 -4
- package/dist/commands/corpus/seed.d.ts.map +1 -1
- package/dist/commands/corpus/seed.js +1 -3
- package/dist/commands/corpus/seed.js.map +1 -1
- package/dist/commands/doctor.d.ts +50 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +245 -52
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/inventory.d.ts +13 -1
- package/dist/commands/inventory.d.ts.map +1 -1
- package/dist/commands/inventory.js +121 -17
- package/dist/commands/inventory.js.map +1 -1
- package/dist/commands/mcp/collections.d.ts +1 -1
- package/dist/commands/mcp/collections.d.ts.map +1 -1
- package/dist/commands/mcp/list-collections.d.ts.map +1 -1
- package/dist/commands/mcp/list-collections.js +2 -1
- package/dist/commands/mcp/list-collections.js.map +1 -1
- package/dist/commands/mcp/serve.d.ts.map +1 -1
- package/dist/commands/mcp/serve.js +3 -2
- package/dist/commands/mcp/serve.js.map +1 -1
- package/dist/commands/okf/index.d.ts +11 -0
- package/dist/commands/okf/index.d.ts.map +1 -0
- package/dist/commands/okf/index.js +114 -0
- package/dist/commands/okf/index.js.map +1 -0
- package/dist/commands/okf/validate.d.ts +191 -0
- package/dist/commands/okf/validate.d.ts.map +1 -0
- package/dist/commands/okf/validate.js +190 -0
- package/dist/commands/okf/validate.js.map +1 -0
- package/dist/commands/phase-utils.d.ts +182 -114
- package/dist/commands/phase-utils.d.ts.map +1 -1
- package/dist/commands/phase-utils.js +154 -163
- package/dist/commands/phase-utils.js.map +1 -1
- package/dist/commands/positional-args.d.ts.map +1 -1
- package/dist/commands/positional-args.js +3 -2
- package/dist/commands/positional-args.js.map +1 -1
- package/dist/commands/rag/clear-command.d.ts.map +1 -1
- package/dist/commands/rag/clear-command.js +2 -1
- package/dist/commands/rag/clear-command.js.map +1 -1
- package/dist/commands/rag/index-command.d.ts +64 -0
- package/dist/commands/rag/index-command.d.ts.map +1 -1
- package/dist/commands/rag/index-command.js +72 -6
- package/dist/commands/rag/index-command.js.map +1 -1
- package/dist/commands/rag/index.d.ts.map +1 -1
- package/dist/commands/rag/index.js +23 -10
- package/dist/commands/rag/index.js.map +1 -1
- package/dist/commands/rag/query-command.d.ts.map +1 -1
- package/dist/commands/rag/query-command.js +2 -1
- package/dist/commands/rag/query-command.js.map +1 -1
- package/dist/commands/rag/stats-command.d.ts.map +1 -1
- package/dist/commands/rag/stats-command.js +2 -1
- package/dist/commands/rag/stats-command.js.map +1 -1
- package/dist/commands/resources/builtin-help.d.ts +27 -0
- package/dist/commands/resources/builtin-help.d.ts.map +1 -0
- package/dist/commands/resources/builtin-help.js +46 -0
- package/dist/commands/resources/builtin-help.js.map +1 -0
- package/dist/commands/resources/check-progress.d.ts +154 -0
- package/dist/commands/resources/check-progress.d.ts.map +1 -0
- package/dist/commands/resources/check-progress.js +222 -0
- package/dist/commands/resources/check-progress.js.map +1 -0
- package/dist/commands/resources/check-supervisor.d.ts +465 -0
- package/dist/commands/resources/check-supervisor.d.ts.map +1 -0
- package/dist/commands/resources/check-supervisor.js +573 -0
- package/dist/commands/resources/check-supervisor.js.map +1 -0
- package/dist/commands/resources/check.d.ts +593 -0
- package/dist/commands/resources/check.d.ts.map +1 -0
- package/dist/commands/resources/check.js +1365 -0
- package/dist/commands/resources/check.js.map +1 -0
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +418 -4
- package/dist/commands/resources/index.js.map +1 -1
- package/dist/commands/resources/query.d.ts +106 -0
- package/dist/commands/resources/query.d.ts.map +1 -0
- package/dist/commands/resources/query.js +177 -0
- package/dist/commands/resources/query.js.map +1 -0
- package/dist/commands/resources/scan.d.ts +24 -0
- package/dist/commands/resources/scan.d.ts.map +1 -1
- package/dist/commands/resources/scan.js +17 -8
- package/dist/commands/resources/scan.js.map +1 -1
- package/dist/commands/resources/validate.d.ts +42 -2
- package/dist/commands/resources/validate.d.ts.map +1 -1
- package/dist/commands/resources/validate.js +208 -55
- package/dist/commands/resources/validate.js.map +1 -1
- package/dist/commands/skill/review-checklist.d.ts +3 -2
- package/dist/commands/skill/review-checklist.d.ts.map +1 -1
- package/dist/commands/skill/review-checklist.js +40 -2
- package/dist/commands/skill/review-checklist.js.map +1 -1
- package/dist/commands/skill/review.d.ts +247 -0
- package/dist/commands/skill/review.d.ts.map +1 -1
- package/dist/commands/skill/review.js +99 -62
- package/dist/commands/skill/review.js.map +1 -1
- package/dist/commands/skill/test/configure.d.ts +56 -0
- package/dist/commands/skill/test/configure.d.ts.map +1 -1
- package/dist/commands/skill/test/configure.js +75 -16
- package/dist/commands/skill/test/configure.js.map +1 -1
- package/dist/commands/skill/test/run.d.ts +63 -10
- package/dist/commands/skill/test/run.d.ts.map +1 -1
- package/dist/commands/skill/test/run.js +258 -77
- package/dist/commands/skill/test/run.js.map +1 -1
- package/dist/commands/skills/build.d.ts +94 -4
- package/dist/commands/skills/build.d.ts.map +1 -1
- package/dist/commands/skills/build.js +325 -97
- package/dist/commands/skills/build.js.map +1 -1
- package/dist/commands/skills/install.d.ts +2 -1
- package/dist/commands/skills/install.d.ts.map +1 -1
- package/dist/commands/skills/install.js +20 -31
- package/dist/commands/skills/install.js.map +1 -1
- package/dist/commands/skills/list.d.ts +2 -1
- package/dist/commands/skills/list.d.ts.map +1 -1
- package/dist/commands/skills/list.js +44 -26
- package/dist/commands/skills/list.js.map +1 -1
- package/dist/commands/skills/package.d.ts +1 -1
- package/dist/commands/skills/package.d.ts.map +1 -1
- package/dist/commands/skills/package.js +6 -8
- package/dist/commands/skills/package.js.map +1 -1
- package/dist/commands/skills/scope-guard.d.ts.map +1 -1
- package/dist/commands/skills/scope-guard.js +3 -5
- package/dist/commands/skills/scope-guard.js.map +1 -1
- package/dist/commands/skills/shared.d.ts.map +1 -1
- package/dist/commands/skills/shared.js +2 -4
- package/dist/commands/skills/shared.js.map +1 -1
- package/dist/commands/skills/skill-discovery.d.ts +47 -6
- package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
- package/dist/commands/skills/skill-discovery.js +61 -11
- package/dist/commands/skills/skill-discovery.js.map +1 -1
- package/dist/commands/skills/source-resolvers.d.ts +15 -0
- package/dist/commands/skills/source-resolvers.d.ts.map +1 -1
- package/dist/commands/skills/source-resolvers.js +25 -4
- 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 +11 -3
- package/dist/commands/skills/validate-command.js.map +1 -1
- package/dist/commands/skills/validate.d.ts +140 -4
- package/dist/commands/skills/validate.d.ts.map +1 -1
- package/dist/commands/skills/validate.js +224 -67
- package/dist/commands/skills/validate.js.map +1 -1
- package/dist/commands/validate.d.ts +1 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +63 -27
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/verify.d.ts +119 -15
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +357 -142
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/report-schemas.d.ts +45 -0
- package/dist/report-schemas.d.ts.map +1 -0
- package/dist/report-schemas.js +100 -0
- package/dist/report-schemas.js.map +1 -0
- package/dist/skill-resolution/classify.js +2 -2
- package/dist/skill-resolution/classify.js.map +1 -1
- package/dist/skill-resolution/packaging-config.d.ts +49 -5
- package/dist/skill-resolution/packaging-config.d.ts.map +1 -1
- package/dist/skill-resolution/packaging-config.js +59 -19
- 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 +55 -57
- package/dist/skill-resolution/resolve-skill-reference.js.map +1 -1
- package/dist/utils/agent-discovery.d.ts.map +1 -1
- package/dist/utils/agent-discovery.js +22 -11
- package/dist/utils/agent-discovery.js.map +1 -1
- package/dist/utils/agent-runner.d.ts.map +1 -1
- package/dist/utils/agent-runner.js +7 -4
- package/dist/utils/agent-runner.js.map +1 -1
- package/dist/utils/claude-context-lens.d.ts +34 -0
- package/dist/utils/claude-context-lens.d.ts.map +1 -0
- package/dist/utils/claude-context-lens.js +39 -0
- package/dist/utils/claude-context-lens.js.map +1 -0
- package/dist/utils/command-error.d.ts +138 -20
- package/dist/utils/command-error.d.ts.map +1 -1
- package/dist/utils/command-error.js +172 -36
- package/dist/utils/command-error.js.map +1 -1
- package/dist/utils/config-loader.d.ts +2 -1
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +40 -14
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/corpus-target.d.ts +26 -0
- package/dist/utils/corpus-target.d.ts.map +1 -0
- package/dist/utils/corpus-target.js +35 -0
- package/dist/utils/corpus-target.js.map +1 -0
- package/dist/utils/edge-lens-evaluation.d.ts +83 -0
- package/dist/utils/edge-lens-evaluation.d.ts.map +1 -0
- package/dist/utils/edge-lens-evaluation.js +110 -0
- package/dist/utils/edge-lens-evaluation.js.map +1 -0
- package/dist/utils/help-loader.d.ts.map +1 -1
- package/dist/utils/help-loader.js +0 -1
- package/dist/utils/help-loader.js.map +1 -1
- package/dist/utils/issue-anchor.d.ts +2 -2
- package/dist/utils/issue-anchor.d.ts.map +1 -1
- package/dist/utils/issue-anchor.js +1 -1
- package/dist/utils/issue-rendering.d.ts +3 -3
- package/dist/utils/issue-rendering.d.ts.map +1 -1
- package/dist/utils/issue-rendering.js +3 -3
- package/dist/utils/issue-rendering.js.map +1 -1
- package/dist/utils/issue-severity.d.ts +12 -5
- package/dist/utils/issue-severity.d.ts.map +1 -1
- package/dist/utils/issue-severity.js +1 -1
- package/dist/utils/issue-severity.js.map +1 -1
- package/dist/utils/optional-backend.d.ts +78 -0
- package/dist/utils/optional-backend.d.ts.map +1 -0
- package/dist/utils/optional-backend.js +117 -0
- package/dist/utils/optional-backend.js.map +1 -0
- package/dist/utils/output.d.ts +26 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +35 -0
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/package-json.d.ts +24 -0
- package/dist/utils/package-json.d.ts.map +1 -0
- package/dist/utils/package-json.js +49 -0
- package/dist/utils/package-json.js.map +1 -0
- package/dist/utils/population-wiring.d.ts +100 -0
- package/dist/utils/population-wiring.d.ts.map +1 -0
- package/dist/utils/population-wiring.js +98 -0
- package/dist/utils/population-wiring.js.map +1 -0
- package/dist/utils/project-root-policy.d.ts +20 -0
- package/dist/utils/project-root-policy.d.ts.map +1 -1
- package/dist/utils/project-root-policy.js +30 -0
- package/dist/utils/project-root-policy.js.map +1 -1
- package/dist/utils/projection-lenses.d.ts +98 -0
- package/dist/utils/projection-lenses.d.ts.map +1 -0
- package/dist/utils/projection-lenses.js +203 -0
- package/dist/utils/projection-lenses.js.map +1 -0
- package/dist/utils/projection-query.d.ts +324 -0
- package/dist/utils/projection-query.d.ts.map +1 -0
- package/dist/utils/projection-query.js +357 -0
- package/dist/utils/projection-query.js.map +1 -0
- package/dist/utils/projection-store.d.ts +335 -0
- package/dist/utils/projection-store.d.ts.map +1 -0
- package/dist/utils/projection-store.js +522 -0
- package/dist/utils/projection-store.js.map +1 -0
- package/dist/utils/relation-limits.d.ts +50 -0
- package/dist/utils/relation-limits.d.ts.map +1 -0
- package/dist/utils/relation-limits.js +50 -0
- package/dist/utils/relation-limits.js.map +1 -0
- package/dist/utils/repeatable-option.d.ts +37 -0
- package/dist/utils/repeatable-option.d.ts.map +1 -0
- package/dist/utils/repeatable-option.js +39 -0
- package/dist/utils/repeatable-option.js.map +1 -0
- package/dist/utils/resource-loader.d.ts +132 -2
- package/dist/utils/resource-loader.d.ts.map +1 -1
- package/dist/utils/resource-loader.js +288 -27
- package/dist/utils/resource-loader.js.map +1 -1
- package/dist/utils/root-argv.d.ts +53 -0
- package/dist/utils/root-argv.d.ts.map +1 -0
- package/dist/utils/root-argv.js +215 -0
- package/dist/utils/root-argv.js.map +1 -0
- package/dist/utils/run-integrity.d.ts +95 -0
- package/dist/utils/run-integrity.d.ts.map +1 -0
- package/dist/utils/run-integrity.js +102 -0
- package/dist/utils/run-integrity.js.map +1 -0
- package/dist/utils/skill-discovery.d.ts.map +1 -1
- package/dist/utils/skill-discovery.js +2 -1
- package/dist/utils/skill-discovery.js.map +1 -1
- package/dist/utils/skill-packaging-config.d.ts +63 -1
- package/dist/utils/skill-packaging-config.d.ts.map +1 -1
- package/dist/utils/skill-packaging-config.js +56 -1
- package/dist/utils/skill-packaging-config.js.map +1 -1
- package/dist/utils/sqlite-experimental-warning.d.ts +69 -0
- package/dist/utils/sqlite-experimental-warning.d.ts.map +1 -0
- package/dist/utils/sqlite-experimental-warning.js +144 -0
- package/dist/utils/sqlite-experimental-warning.js.map +1 -0
- package/dist/utils/url-redact.d.ts.map +1 -1
- package/dist/utils/url-redact.js +4 -6
- package/dist/utils/url-redact.js.map +1 -1
- package/dist/utils/user-context-scanner.d.ts +8 -0
- package/dist/utils/user-context-scanner.d.ts.map +1 -1
- package/dist/utils/user-context-scanner.js +4 -2
- 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 +12 -6
- package/dist/utils/validate-help-files.js.map +1 -1
- package/dist/utils/vat-bin-path.d.ts +36 -0
- package/dist/utils/vat-bin-path.d.ts.map +1 -0
- package/dist/utils/vat-bin-path.js +48 -0
- package/dist/utils/vat-bin-path.js.map +1 -0
- package/dist/utils/verdict-helpers.d.ts +1 -1
- package/dist/utils/verdict-helpers.d.ts.map +1 -1
- package/dist/utils/verdict-helpers.js +1 -1
- package/dist/utils/verdict-helpers.js.map +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -3
- package/dist/version.js.map +1 -1
- package/docs/agent.md +2 -2
- package/docs/audit.md +141 -37
- package/docs/doctor.md +7 -6
- package/docs/index.md +19 -11
- package/docs/mcp.md +2 -2
- package/docs/rag.md +3 -2
- package/docs/resources.md +13 -3
- package/docs/skill-test.md +10 -9
- package/docs/skills.md +53 -69
- package/package.json +35 -26
- package/schemas/ard-emit.json +149 -0
- package/schemas/okf-validate.json +170 -0
- package/schemas/resources-check.json +229 -0
- package/schemas/skill-review.json +230 -0
- package/dist/commands/resources/command-helpers.d.ts +0 -5
- package/dist/commands/resources/command-helpers.d.ts.map +0 -1
- package/dist/commands/resources/command-helpers.js +0 -6
- package/dist/commands/resources/command-helpers.js.map +0 -1
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { existsSync, statSync } from 'node:fs';
|
|
11
11
|
import { readFile } from 'node:fs/promises';
|
|
12
|
-
import {
|
|
12
|
+
import { safePath } from '@vibe-agent-toolkit/utils';
|
|
13
|
+
import { safeExecSync } from '@vibe-agent-toolkit/utils/process';
|
|
13
14
|
import * as tar from 'tar';
|
|
14
15
|
/**
|
|
15
16
|
* Detect source type from user input
|
|
@@ -33,9 +34,7 @@ export function detectSource(input) {
|
|
|
33
34
|
}
|
|
34
35
|
// Check filesystem
|
|
35
36
|
const absolutePath = safePath.resolve(input);
|
|
36
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
|
|
37
37
|
if (existsSync(absolutePath)) {
|
|
38
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument, validated above
|
|
39
38
|
const stat = statSync(absolutePath);
|
|
40
39
|
if (stat.isDirectory()) {
|
|
41
40
|
return 'local';
|
|
@@ -55,11 +54,9 @@ export function detectSource(input) {
|
|
|
55
54
|
*/
|
|
56
55
|
export async function readPackageJsonVatMetadata(dir) {
|
|
57
56
|
const packageJsonPath = safePath.join(dir, 'package.json');
|
|
58
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Directory path validated by caller
|
|
59
57
|
if (!existsSync(packageJsonPath)) {
|
|
60
58
|
throw new Error(`package.json not found in: ${dir}`);
|
|
61
59
|
}
|
|
62
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Directory path validated by caller
|
|
63
60
|
const content = await readFile(packageJsonPath, 'utf-8');
|
|
64
61
|
const packageJson = JSON.parse(content);
|
|
65
62
|
if (!packageJson.vat?.skills || packageJson.vat.skills.length === 0) {
|
|
@@ -94,7 +91,6 @@ export function downloadNpmPackage(packageName, tempDir) {
|
|
|
94
91
|
// npm pack outputs the filename (e.g., "package-1.0.0.tgz")
|
|
95
92
|
const tarballName = packOutput.toString().trim();
|
|
96
93
|
const tarballPath = safePath.join(tempDir, tarballName);
|
|
97
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is constructed from temp dir
|
|
98
94
|
if (!existsSync(tarballPath)) {
|
|
99
95
|
throw new Error(`npm pack succeeded but tarball not found: ${tarballPath}`);
|
|
100
96
|
}
|
|
@@ -106,7 +102,6 @@ export function downloadNpmPackage(packageName, tempDir) {
|
|
|
106
102
|
sync: true,
|
|
107
103
|
});
|
|
108
104
|
const packageDir = safePath.join(tempDir, 'package');
|
|
109
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is constructed from temp dir
|
|
110
105
|
if (!existsSync(packageDir)) {
|
|
111
106
|
throw new Error(`npm tarball extracted but package/ directory not found`);
|
|
112
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,18 @@ import { getClaudeUserPaths } from '@vibe-agent-toolkit/claude-marketplace';
|
|
|
16
16
|
import { Command } from 'commander';
|
|
17
17
|
import { createLogger } from '../../../utils/logger.js';
|
|
18
18
|
import { type PackageJsonVatReplaces } from './helpers.js';
|
|
19
|
+
/**
|
|
20
|
+
* A name about to become `join(skillsDir, name)` on a path that is deleted
|
|
21
|
+
* or overwritten. Refused unless it is ONE entry name — the sweep installed a
|
|
22
|
+
* SKILL.md declaring `name: ../victim` and watched `--force` delete
|
|
23
|
+
* `<skillsDir>/../victim`, exit 0, `status: success`.
|
|
24
|
+
*
|
|
25
|
+
* @param name - The declared name, exactly as it arrived
|
|
26
|
+
* @param origin - What declared it, for the refusal's wording
|
|
27
|
+
* @returns `name`, unchanged, when it is a single segment
|
|
28
|
+
* @throws When it is not
|
|
29
|
+
*/
|
|
30
|
+
export declare function assertSkillEntryName(name: string, origin: string): string;
|
|
19
31
|
export interface PluginInstallCommandOptions {
|
|
20
32
|
skillsDir?: string;
|
|
21
33
|
name?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,EAAE,kBAAkB,EAAkC,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/plugin/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,EAAE,kBAAkB,EAAkC,MAAM,wCAAwC,CAAC;AAK5G,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAKL,KAAK,sBAAsB,EAG5B,MAAM,cAAc,CAAC;AA8EtB;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAQzE;AAED,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CA0DpD;AAkqBD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/G;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,IAAI,CAEpG;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAAE,GAAG,SAAS,EAChC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC5C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,sBAAsB,EAChC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC5C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
|
|
@@ -17,7 +17,9 @@ import { mkdir, mkdtemp, rm, symlink } from 'node:fs/promises';
|
|
|
17
17
|
import { basename } from 'node:path';
|
|
18
18
|
import { readDeclaredSkillName } from '@vibe-agent-toolkit/agent-skills';
|
|
19
19
|
import { getClaudeUserPaths, installPlugin, uninstallPlugin } from '@vibe-agent-toolkit/claude-marketplace';
|
|
20
|
-
import {
|
|
20
|
+
import { ExitCode } from '@vibe-agent-toolkit/schema';
|
|
21
|
+
import { direntKindFollowingSync, isPathAbsentError, isSingleFsSegment, normalizedTmpdir, toForwardSlash, safePath } from '@vibe-agent-toolkit/utils';
|
|
22
|
+
import { safeExecSync } from '@vibe-agent-toolkit/utils/process';
|
|
21
23
|
import AdmZip from 'adm-zip';
|
|
22
24
|
import { Command } from 'commander';
|
|
23
25
|
import * as tar from 'tar';
|
|
@@ -28,16 +30,18 @@ import { detectSource, downloadNpmPackage, isGlobalNpmInstall, readPackageJsonVa
|
|
|
28
30
|
const PLUGIN_MARKETPLACES_SUBPATH = safePath.join('dist', '.claude', 'plugins', 'marketplaces');
|
|
29
31
|
const PACKAGE_JSON = 'package.json';
|
|
30
32
|
/**
|
|
31
|
-
* List immediate subdirectory names inside a directory.
|
|
33
|
+
* List immediate subdirectory names inside a directory, following links.
|
|
32
34
|
* Returns empty array when the directory does not exist.
|
|
35
|
+
*
|
|
36
|
+
* Followed on purpose: a `--dev` install puts a plugin or marketplace here AS
|
|
37
|
+
* a symlink, and `Dirent.isDirectory()` is false for a link — so every dev
|
|
38
|
+
* install was invisible to the listing that uninstalls, lists and re-installs.
|
|
33
39
|
*/
|
|
34
40
|
function listSubdirectories(dir) {
|
|
35
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- caller validates dir
|
|
36
41
|
if (!existsSync(dir))
|
|
37
42
|
return [];
|
|
38
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- caller validates dir
|
|
39
43
|
return readdirSync(dir, { withFileTypes: true })
|
|
40
|
-
.filter(d => d
|
|
44
|
+
.filter(d => direntKindFollowingSync(dir, d) === 'directory')
|
|
41
45
|
.map(d => d.name);
|
|
42
46
|
}
|
|
43
47
|
/**
|
|
@@ -64,13 +68,12 @@ async function registerPlugin(mpName, pluginName, pluginDir, version, packageNam
|
|
|
64
68
|
* Shared between npm and local install paths to avoid duplication.
|
|
65
69
|
*/
|
|
66
70
|
async function installPluginTreeAndExit(rootDir, marketplacesDir, sourceLabel, sourceType, startTime, logger, dryRun) {
|
|
67
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- rootDir from controlled source
|
|
68
71
|
const pkgRaw = readFileSync(safePath.join(rootDir, PACKAGE_JSON), 'utf-8');
|
|
69
72
|
const packageJson = JSON.parse(pkgRaw);
|
|
70
73
|
const installedSkills = await copyPluginTree(marketplacesDir, packageJson, logger, dryRun);
|
|
71
74
|
const duration = Date.now() - startTime;
|
|
72
75
|
outputInstallSuccess(installedSkills, sourceLabel, sourceType, duration, logger, dryRun);
|
|
73
|
-
process.exit(
|
|
76
|
+
process.exit(ExitCode.OK);
|
|
74
77
|
}
|
|
75
78
|
/**
|
|
76
79
|
* Convert a skill name to a filesystem-safe path segment.
|
|
@@ -79,6 +82,24 @@ async function installPluginTreeAndExit(rootDir, marketplacesDir, sourceLabel, s
|
|
|
79
82
|
function skillNameToFsPath(name) {
|
|
80
83
|
return name.replaceAll(':', '__');
|
|
81
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* A name about to become `join(skillsDir, name)` on a path that is deleted
|
|
87
|
+
* or overwritten. Refused unless it is ONE entry name — the sweep installed a
|
|
88
|
+
* SKILL.md declaring `name: ../victim` and watched `--force` delete
|
|
89
|
+
* `<skillsDir>/../victim`, exit 0, `status: success`.
|
|
90
|
+
*
|
|
91
|
+
* @param name - The declared name, exactly as it arrived
|
|
92
|
+
* @param origin - What declared it, for the refusal's wording
|
|
93
|
+
* @returns `name`, unchanged, when it is a single segment
|
|
94
|
+
* @throws When it is not
|
|
95
|
+
*/
|
|
96
|
+
export function assertSkillEntryName(name, origin) {
|
|
97
|
+
if (!isSingleFsSegment(name)) {
|
|
98
|
+
throw new Error(`Refusing to install "${name}" (${origin}): a skill name must be a single path segment ` +
|
|
99
|
+
`(no separators, not "." or "..").`);
|
|
100
|
+
}
|
|
101
|
+
return name;
|
|
102
|
+
}
|
|
82
103
|
export function createPluginInstallCommand() {
|
|
83
104
|
const command = new Command('install');
|
|
84
105
|
command
|
|
@@ -142,7 +163,7 @@ async function installCommand(source, options) {
|
|
|
142
163
|
process.stdout.write(`reason: "claude.ai org provisioning API not yet confirmed as public"\n`);
|
|
143
164
|
process.stdout.write(`requestedTarget: claude.ai\n`);
|
|
144
165
|
process.stdout.write(`guidance: "Use claude.ai admin console to upload a .zip manually, or use --target api.anthropic.com for workspace-scoped skill management"\n`);
|
|
145
|
-
process.exit(
|
|
166
|
+
process.exit(ExitCode.ERROR);
|
|
146
167
|
}
|
|
147
168
|
// Handle --build (implies --dev)
|
|
148
169
|
if (options.build) {
|
|
@@ -209,7 +230,6 @@ async function handleNpmInstall(source, options, logger, startTime) {
|
|
|
209
230
|
const extractedPath = downloadNpmPackage(packageName, tempDir);
|
|
210
231
|
// If the package ships a pre-built plugin tree, install via dumb copy.
|
|
211
232
|
const marketplacesDir = safePath.join(extractedPath, PLUGIN_MARKETPLACES_SUBPATH);
|
|
212
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- path from controlled extractedPath + constant subpath
|
|
213
233
|
const hasPlugin = !options.userInstallWithoutPlugin && existsSync(marketplacesDir);
|
|
214
234
|
if (hasPlugin) {
|
|
215
235
|
logger.info(' Plugin detected — installing via Claude plugin system');
|
|
@@ -238,7 +258,7 @@ async function handleNpmInstall(source, options, logger, startTime) {
|
|
|
238
258
|
name,
|
|
239
259
|
installPath: safePath.join(skillsDir, name),
|
|
240
260
|
})), `npm:${packageName}`, 'npm', duration, logger, options.dryRun);
|
|
241
|
-
process.exit(
|
|
261
|
+
process.exit(ExitCode.OK);
|
|
242
262
|
}
|
|
243
263
|
finally {
|
|
244
264
|
await rm(tempDir, { recursive: true, force: true });
|
|
@@ -253,13 +273,11 @@ async function handleLocalInstall(source, options, logger, startTime) {
|
|
|
253
273
|
const skillsDir = options.skillsDir ?? getClaudeUserPaths().skillsDir;
|
|
254
274
|
// Check for pre-built plugin tree first
|
|
255
275
|
const marketplacesDir = safePath.join(sourcePath, PLUGIN_MARKETPLACES_SUBPATH);
|
|
256
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
|
|
257
276
|
if (!options.userInstallWithoutPlugin && existsSync(marketplacesDir)) {
|
|
258
277
|
await installPluginTreeAndExit(sourcePath, marketplacesDir, `local:${sourcePath}`, 'local', startTime, logger, options.dryRun);
|
|
259
278
|
}
|
|
260
279
|
// Check if directory contains package.json with vat.skills
|
|
261
280
|
const packageJsonPath = safePath.join(sourcePath, 'package.json');
|
|
262
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
|
|
263
281
|
const hasPackageJson = existsSync(packageJsonPath);
|
|
264
282
|
let installed;
|
|
265
283
|
if (hasPackageJson) {
|
|
@@ -287,7 +305,7 @@ async function handleLocalInstall(source, options, logger, startTime) {
|
|
|
287
305
|
}
|
|
288
306
|
const duration = Date.now() - startTime;
|
|
289
307
|
outputInstallSuccess(installed, `local:${sourcePath}`, 'local', duration, logger, options.dryRun);
|
|
290
|
-
process.exit(
|
|
308
|
+
process.exit(ExitCode.OK);
|
|
291
309
|
}
|
|
292
310
|
/**
|
|
293
311
|
* Handle ZIP file installation
|
|
@@ -295,7 +313,6 @@ async function handleLocalInstall(source, options, logger, startTime) {
|
|
|
295
313
|
async function handleZipInstall(source, options, logger, startTime) {
|
|
296
314
|
const sourcePath = safePath.resolve(source);
|
|
297
315
|
logger.info(`📥 Installing skill from ZIP: ${sourcePath}`);
|
|
298
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
|
|
299
316
|
if (!existsSync(sourcePath)) {
|
|
300
317
|
throw new Error(`ZIP file not found: ${sourcePath}`);
|
|
301
318
|
}
|
|
@@ -304,12 +321,11 @@ async function handleZipInstall(source, options, logger, startTime) {
|
|
|
304
321
|
if (!options.dryRun) {
|
|
305
322
|
logger.info(' Extracting ZIP...');
|
|
306
323
|
const zip = new AdmZip(sourcePath);
|
|
307
|
-
// eslint-disable-next-line sonarjs/no-unsafe-unzip -- User-provided local files, isolated plugin directory
|
|
308
324
|
zip.extractAllTo(installPath, /* overwrite */ true);
|
|
309
325
|
}
|
|
310
326
|
const duration = Date.now() - startTime;
|
|
311
327
|
outputInstallSuccess([{ name: skillName, installPath }], sourcePath, 'zip', duration, logger, options.dryRun);
|
|
312
|
-
process.exit(
|
|
328
|
+
process.exit(ExitCode.OK);
|
|
313
329
|
}
|
|
314
330
|
/**
|
|
315
331
|
* Handle npm tarball (.tgz / .tar.gz) installation.
|
|
@@ -319,7 +335,6 @@ async function handleZipInstall(source, options, logger, startTime) {
|
|
|
319
335
|
async function handleTgzInstall(source, options, logger, startTime) {
|
|
320
336
|
const sourcePath = safePath.resolve(source);
|
|
321
337
|
logger.info(`📥 Installing skill from tarball: ${sourcePath}`);
|
|
322
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- User-provided CLI argument
|
|
323
338
|
if (!existsSync(sourcePath)) {
|
|
324
339
|
throw new Error(`Tarball not found: ${sourcePath}`);
|
|
325
340
|
}
|
|
@@ -329,11 +344,9 @@ async function handleTgzInstall(source, options, logger, startTime) {
|
|
|
329
344
|
await tar.extract({ file: sourcePath, cwd: tempDir });
|
|
330
345
|
// npm pack tarballs extract under package/ subdirectory
|
|
331
346
|
const packageDir = safePath.join(tempDir, 'package');
|
|
332
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- tempDir is controlled
|
|
333
347
|
const extractedDir = existsSync(packageDir) ? packageDir : tempDir;
|
|
334
348
|
// Delegate to local install logic
|
|
335
349
|
const marketplacesDir = safePath.join(extractedDir, PLUGIN_MARKETPLACES_SUBPATH);
|
|
336
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- tempDir is controlled
|
|
337
350
|
if (!options.userInstallWithoutPlugin && existsSync(marketplacesDir)) {
|
|
338
351
|
await installPluginTreeAndExit(extractedDir, marketplacesDir, sourcePath, 'tgz', startTime, logger, options.dryRun);
|
|
339
352
|
}
|
|
@@ -347,7 +360,7 @@ async function handleTgzInstall(source, options, logger, startTime) {
|
|
|
347
360
|
}
|
|
348
361
|
const duration = Date.now() - startTime;
|
|
349
362
|
outputInstallSuccess(skillNames.map(name => ({ name, installPath: safePath.join(skillsDir, name) })), sourcePath, 'tgz', duration, logger, options.dryRun);
|
|
350
|
-
process.exit(
|
|
363
|
+
process.exit(ExitCode.OK);
|
|
351
364
|
}
|
|
352
365
|
finally {
|
|
353
366
|
await rm(tempDir, { recursive: true, force: true });
|
|
@@ -358,22 +371,23 @@ async function handleTgzInstall(source, options, logger, startTime) {
|
|
|
358
371
|
* Throws if the path exists and --force was not passed.
|
|
359
372
|
*/
|
|
360
373
|
async function prepareDevSymlinkDest(destPath, skillFsName, options) {
|
|
374
|
+
// The probe is the ONLY thing whose failure may read as "nothing there". A
|
|
375
|
+
// refusal on the probe, or a failed removal, stays loud: this used to catch
|
|
376
|
+
// everything and recognise its own throw by the words in its message.
|
|
361
377
|
try {
|
|
362
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
|
|
363
378
|
lstatSync(destPath);
|
|
364
|
-
if (!options.force) {
|
|
365
|
-
throw new Error(`Skill "${skillFsName}" already installed at ${destPath}.\n` +
|
|
366
|
-
`Use --force to overwrite.`);
|
|
367
|
-
}
|
|
368
|
-
if (!options.dryRun) {
|
|
369
|
-
await rm(destPath, { recursive: true, force: true });
|
|
370
|
-
}
|
|
371
379
|
}
|
|
372
380
|
catch (error) {
|
|
373
|
-
if (error
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
381
|
+
if (isPathAbsentError(error))
|
|
382
|
+
return;
|
|
383
|
+
throw error;
|
|
384
|
+
}
|
|
385
|
+
if (!options.force) {
|
|
386
|
+
throw new Error(`Skill "${skillFsName}" already installed at ${destPath}.\n` +
|
|
387
|
+
`Use --force to overwrite.`);
|
|
388
|
+
}
|
|
389
|
+
if (!options.dryRun) {
|
|
390
|
+
await rm(destPath, { recursive: true, force: true });
|
|
377
391
|
}
|
|
378
392
|
}
|
|
379
393
|
/**
|
|
@@ -383,15 +397,34 @@ async function prepareDevSymlinkDest(destPath, skillFsName, options) {
|
|
|
383
397
|
async function symlinkDevSkill(skillFsName, destSkillsDir, cwd, pluginName, options, logger) {
|
|
384
398
|
const srcSkillPath = safePath.resolve(cwd, 'dist', 'skills', skillFsName);
|
|
385
399
|
const destSkillPath = safePath.join(destSkillsDir, skillFsName);
|
|
386
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
|
|
387
400
|
if (!existsSync(srcSkillPath)) {
|
|
388
401
|
logger.info(` Warning: skill not built at ${srcSkillPath} — skipping symlink`);
|
|
389
402
|
return null;
|
|
390
403
|
}
|
|
391
404
|
await prepareDevSymlinkDest(destSkillPath, skillFsName, options);
|
|
392
405
|
if (!options.dryRun) {
|
|
393
|
-
|
|
394
|
-
|
|
406
|
+
try {
|
|
407
|
+
// eslint-disable-next-line local/no-bare-symlink-in-tests -- eyes open: `handleDevInstall` refuses win32 upstream, so the Windows privilege hazard the rule names cannot be reached here.
|
|
408
|
+
await symlink(srcSkillPath, destSkillPath, 'dir');
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
// ⚠️ POSIX-only in practice: `handleDevInstall` throws on win32 before
|
|
412
|
+
// this call chain begins, so Windows-specific handling here would be dead
|
|
413
|
+
// code — an earlier revision added exactly that. Making `--dev` work on
|
|
414
|
+
// Windows means changing that guard (a junction needs no elevation), not
|
|
415
|
+
// this catch. Not falling back to a copy either — dev mode exists so a
|
|
416
|
+
// rebuild is picked up live, and a copy would quietly stop that.
|
|
417
|
+
//
|
|
418
|
+
// ⚠️ This throws mid-loop, after `devInstallMarketplace` already removed
|
|
419
|
+
// the previous marketplace directory and `devInstallPlugin` copied the
|
|
420
|
+
// non-skill content. Earlier skills are linked, later ones are not, and
|
|
421
|
+
// `registerPlugin` never runs — so the tree is on disk but unregistered.
|
|
422
|
+
// Recoverable by re-running, which starts over.
|
|
423
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
424
|
+
throw new Error(`Could not symlink ${skillFsName} to ${destSkillPath}: ${detail}\n` +
|
|
425
|
+
'Check that the destination directory is writable. This install is now ' +
|
|
426
|
+
'incomplete — re-run the same command to start over.');
|
|
427
|
+
}
|
|
395
428
|
}
|
|
396
429
|
logger.info(` Symlinked: ${safePath.relative(cwd, destSkillPath)} → ${srcSkillPath}`);
|
|
397
430
|
return {
|
|
@@ -406,17 +439,16 @@ async function symlinkDevSkill(skillFsName, destSkillsDir, cwd, pluginName, opti
|
|
|
406
439
|
async function symlinkPluginSkills(srcPluginDir, destPluginDir, pluginName, cwd, options, logger) {
|
|
407
440
|
const installed = [];
|
|
408
441
|
const srcSkillsDir = safePath.join(srcPluginDir, 'skills');
|
|
409
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
|
|
410
442
|
if (!existsSync(srcSkillsDir)) {
|
|
411
443
|
return installed;
|
|
412
444
|
}
|
|
413
445
|
const destSkillsDir = safePath.join(destPluginDir, 'skills');
|
|
414
446
|
if (!options.dryRun) {
|
|
415
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
|
|
416
447
|
await mkdir(destSkillsDir, { recursive: true });
|
|
417
448
|
}
|
|
418
|
-
//
|
|
419
|
-
const skillEntries = readdirSync(srcSkillsDir, { withFileTypes: true })
|
|
449
|
+
// Followed: a skill directory that is itself a link is still a skill to link.
|
|
450
|
+
const skillEntries = readdirSync(srcSkillsDir, { withFileTypes: true })
|
|
451
|
+
.filter(d => direntKindFollowingSync(srcSkillsDir, d) === 'directory');
|
|
420
452
|
for (const skillEntry of skillEntries) {
|
|
421
453
|
const result = await symlinkDevSkill(skillEntry.name, destSkillsDir, cwd, pluginName, options, logger);
|
|
422
454
|
if (result) {
|
|
@@ -431,11 +463,9 @@ async function symlinkPluginSkills(srcPluginDir, destPluginDir, pluginName, cwd,
|
|
|
431
463
|
async function devInstallPlugin(ctx, cwd, options, logger) {
|
|
432
464
|
const { mpName, pluginName, srcPluginDir, destPluginDir, packageName, version, paths } = ctx;
|
|
433
465
|
if (!options.dryRun) {
|
|
434
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
|
|
435
466
|
await mkdir(destPluginDir, { recursive: true });
|
|
436
467
|
}
|
|
437
468
|
// Copy non-skill entries (e.g. .claude-plugin/)
|
|
438
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
|
|
439
469
|
for (const entry of readdirSync(srcPluginDir, { withFileTypes: true })) {
|
|
440
470
|
if (entry.name !== 'skills' && !options.dryRun) {
|
|
441
471
|
const srcEntry = safePath.join(srcPluginDir, entry.name);
|
|
@@ -459,12 +489,10 @@ async function devInstallMarketplace(mpName, srcMpDir, packageInfo, cwd, options
|
|
|
459
489
|
const installed = [];
|
|
460
490
|
if (!options.dryRun) {
|
|
461
491
|
await rm(destMpDir, { recursive: true, force: true });
|
|
462
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
|
|
463
492
|
await mkdir(destMpDir, { recursive: true });
|
|
464
493
|
}
|
|
465
494
|
logger.info(` Marketplace: ${mpName} → ${destMpDir}`);
|
|
466
495
|
// Copy non-plugin content (e.g. .claude-plugin/marketplace.json)
|
|
467
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- controlled path
|
|
468
496
|
for (const entry of readdirSync(srcMpDir, { withFileTypes: true })) {
|
|
469
497
|
if (entry.name !== 'plugins' && !options.dryRun) {
|
|
470
498
|
const srcEntry = safePath.join(srcMpDir, entry.name);
|
|
@@ -510,13 +538,11 @@ async function handleDevInstall(options, logger, startTime) {
|
|
|
510
538
|
}
|
|
511
539
|
// Check for pre-built plugin tree
|
|
512
540
|
const marketplacesDir = safePath.join(cwd, PLUGIN_MARKETPLACES_SUBPATH);
|
|
513
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- cwd from CLI option or process.cwd()
|
|
514
541
|
if (!existsSync(marketplacesDir)) {
|
|
515
542
|
throw new Error(`Plugin tree not found at ${marketplacesDir}\n` +
|
|
516
543
|
`Run: vat build first (builds the plugin tree)`);
|
|
517
544
|
}
|
|
518
545
|
// Read package.json for package name/version
|
|
519
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- cwd from CLI option or process.cwd()
|
|
520
546
|
const pkgRaw = readFileSync(safePath.join(cwd, PACKAGE_JSON), 'utf-8');
|
|
521
547
|
const packageJson = JSON.parse(pkgRaw);
|
|
522
548
|
logger.info(`📥 Dev-installing plugin tree from ${packageJson.name}`);
|
|
@@ -535,7 +561,7 @@ async function handleDevInstall(options, logger, startTime) {
|
|
|
535
561
|
}
|
|
536
562
|
const duration = Date.now() - startTime;
|
|
537
563
|
outputDevSuccess(installed, packageJson.name, duration, logger, options.dryRun);
|
|
538
|
-
process.exit(
|
|
564
|
+
process.exit(ExitCode.OK);
|
|
539
565
|
}
|
|
540
566
|
/**
|
|
541
567
|
* Shell out to vat build (skills + claude plugin tree)
|
|
@@ -556,16 +582,14 @@ async function handleNpmPostinstall(options, logger, startTime) {
|
|
|
556
582
|
logger.info(`📥 Running npm postinstall hook`);
|
|
557
583
|
if (!isGlobalNpmInstall()) {
|
|
558
584
|
logger.info(' Skipping: Not a global npm install');
|
|
559
|
-
process.exit(
|
|
585
|
+
process.exit(ExitCode.OK);
|
|
560
586
|
}
|
|
561
587
|
const cwd = process.cwd();
|
|
562
588
|
// Check for pre-built plugin tree (dist/.claude/plugins/marketplaces/)
|
|
563
589
|
const marketplacesDir = safePath.join(cwd, PLUGIN_MARKETPLACES_SUBPATH);
|
|
564
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated cwd and constant subpath
|
|
565
590
|
const hasPluginTree = existsSync(marketplacesDir);
|
|
566
591
|
if (!options.userInstallWithoutPlugin) {
|
|
567
592
|
if (hasPluginTree) {
|
|
568
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated cwd and constant package.json name
|
|
569
593
|
const pkgRaw = readFileSync(safePath.join(cwd, PACKAGE_JSON), 'utf-8');
|
|
570
594
|
const packageJson = JSON.parse(pkgRaw);
|
|
571
595
|
logger.info(` Package: ${packageJson.name}@${packageJson.version ?? 'unknown'}`);
|
|
@@ -580,7 +604,7 @@ async function handleNpmPostinstall(options, logger, startTime) {
|
|
|
580
604
|
logger.info(` Run 'vat build' to generate plugin artifacts before publishing.`);
|
|
581
605
|
logger.info(` Skipping install — no skills registered.`);
|
|
582
606
|
}
|
|
583
|
-
process.exit(
|
|
607
|
+
process.exit(ExitCode.OK);
|
|
584
608
|
}
|
|
585
609
|
// --user-install-without-plugin: install skills directly to ~/.claude/skills/
|
|
586
610
|
const { packageJson, skills } = await readPackageJsonVatMetadata(cwd);
|
|
@@ -593,7 +617,7 @@ async function handleNpmPostinstall(options, logger, startTime) {
|
|
|
593
617
|
const duration = Date.now() - startTime;
|
|
594
618
|
logger.info(`✅ Installed ${skills.length} skill(s) from ${packageJson.name}`);
|
|
595
619
|
logger.info(` Duration: ${duration}ms`);
|
|
596
|
-
process.exit(
|
|
620
|
+
process.exit(ExitCode.OK);
|
|
597
621
|
}
|
|
598
622
|
/**
|
|
599
623
|
* Execute vat.replaces cleanup before installing the new plugin.
|
|
@@ -630,15 +654,21 @@ export async function executeReplaces(replaces, marketplaceNames, paths, dryRun,
|
|
|
630
654
|
await removeOldPlugins(replaces.plugins, marketplaceNames, paths, dryRun, logger);
|
|
631
655
|
// Remove legacy flat-skill installs from ~/.claude/skills/<name>
|
|
632
656
|
for (const skillName of replaces.flatSkills ?? []) {
|
|
633
|
-
|
|
657
|
+
// The entry comes from the INSTALLED package's package.json, and this is
|
|
658
|
+
// an `rm -rf` with no flag in front of it: `"../victim"` used to remove a
|
|
659
|
+
// sibling of the skills dir (with the default paths, `"../.."` is $HOME).
|
|
660
|
+
const skillPath = safePath.join(paths.skillsDir, assertSkillEntryName(skillName, 'vat.replaces.flatSkills'));
|
|
634
661
|
let pathExists = false;
|
|
635
662
|
try {
|
|
636
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- derived from Claude user paths + skill name
|
|
637
663
|
lstatSync(skillPath); // throws if path itself doesn't exist (doesn't follow symlinks)
|
|
638
664
|
pathExists = true;
|
|
639
665
|
}
|
|
640
|
-
catch {
|
|
641
|
-
//
|
|
666
|
+
catch (error) {
|
|
667
|
+
// Path doesn't exist — nothing to remove. One the OS refuses to examine
|
|
668
|
+
// is not "nothing to remove": the legacy install is still there and a
|
|
669
|
+
// silent skip leaves it beside its replacement.
|
|
670
|
+
if (!isPathAbsentError(error))
|
|
671
|
+
throw error;
|
|
642
672
|
}
|
|
643
673
|
if (pathExists) {
|
|
644
674
|
if (dryRun) {
|
|
@@ -673,7 +703,6 @@ async function copyPluginTree(marketplacesDir, packageJson, logger, dryRun) {
|
|
|
673
703
|
// package do not persist in the user's Claude installation.
|
|
674
704
|
logger.info(` Copying marketplace: ${mpName} → ${destMpDir}`);
|
|
675
705
|
await rm(destMpDir, { recursive: true, force: true });
|
|
676
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Resolved from constant subpath
|
|
677
706
|
await mkdir(destMpDir, { recursive: true });
|
|
678
707
|
cpSync(srcMpDir, destMpDir, { recursive: true, force: true });
|
|
679
708
|
// Register each plugin and collect installed skill names
|
|
@@ -696,15 +725,19 @@ async function copyPluginTree(marketplacesDir, packageJson, logger, dryRun) {
|
|
|
696
725
|
*/
|
|
697
726
|
async function prepareInstallation(skillName, options) {
|
|
698
727
|
const skillsDir = options.skillsDir ?? getClaudeUserPaths().skillsDir;
|
|
699
|
-
|
|
728
|
+
// The declared name is author-controlled (SKILL.md `name:`, package.json
|
|
729
|
+
// `vat.skills[]`) and `--force` turns this path into an `rm -rf`.
|
|
730
|
+
const installPath = safePath.join(skillsDir, assertSkillEntryName(skillName, 'skill name'));
|
|
700
731
|
let exists = false;
|
|
701
732
|
try {
|
|
702
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Install path from config
|
|
703
733
|
lstatSync(installPath);
|
|
704
734
|
exists = true;
|
|
705
735
|
}
|
|
706
|
-
catch {
|
|
707
|
-
// Does not exist
|
|
736
|
+
catch (error) {
|
|
737
|
+
// Does not exist. A refusal is not that: it used to read as "free", and
|
|
738
|
+
// the extraction that followed then met the same refusal without a name.
|
|
739
|
+
if (!isPathAbsentError(error))
|
|
740
|
+
throw error;
|
|
708
741
|
}
|
|
709
742
|
if (exists && !options.force) {
|
|
710
743
|
throw new Error(`Skill already exists at ${installPath}. Use --force to overwrite.`);
|
|
@@ -713,7 +746,6 @@ async function prepareInstallation(skillName, options) {
|
|
|
713
746
|
await rm(installPath, { recursive: true, force: true });
|
|
714
747
|
}
|
|
715
748
|
if (!options.dryRun) {
|
|
716
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Skills directory path, safe
|
|
717
749
|
await mkdir(skillsDir, { recursive: true });
|
|
718
750
|
}
|
|
719
751
|
return { skillsDir, installPath };
|
|
@@ -722,7 +754,6 @@ async function prepareInstallation(skillName, options) {
|
|
|
722
754
|
* Install skill from a path to plugins directory
|
|
723
755
|
*/
|
|
724
756
|
async function installSkillFromPath(skillPath, skillName, options, logger) {
|
|
725
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Validated path
|
|
726
757
|
if (!existsSync(skillPath)) {
|
|
727
758
|
throw new Error(`Skill path not found: ${skillPath}`);
|
|
728
759
|
}
|