@vibe-agent-toolkit/agent-skills 0.2.0-rc.7 → 0.2.0-rc.8

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.
Files changed (208) hide show
  1. package/README.md +5 -5
  2. package/dist/builder.d.ts.map +1 -1
  3. package/dist/builder.js +7 -17
  4. package/dist/builder.js.map +1 -1
  5. package/dist/files-config.d.ts +2 -2
  6. package/dist/files-config.d.ts.map +1 -1
  7. package/dist/files-config.js +1 -7
  8. package/dist/files-config.js.map +1 -1
  9. package/dist/import.d.ts.map +1 -1
  10. package/dist/import.js +0 -4
  11. package/dist/import.js.map +1 -1
  12. package/dist/inventory/types.d.ts +8 -0
  13. package/dist/inventory/types.d.ts.map +1 -1
  14. package/dist/inventory/types.js.map +1 -1
  15. package/dist/plugin-distribution-layout.d.ts.map +1 -1
  16. package/dist/plugin-distribution-layout.js +0 -2
  17. package/dist/plugin-distribution-layout.js.map +1 -1
  18. package/dist/post-build-checks.d.ts.map +1 -1
  19. package/dist/post-build-checks.js +12 -11
  20. package/dist/post-build-checks.js.map +1 -1
  21. package/dist/schemas/installed-plugins-registry.d.ts.map +1 -1
  22. package/dist/schemas/installed-plugins-registry.js +7 -1
  23. package/dist/schemas/installed-plugins-registry.js.map +1 -1
  24. package/dist/skill-identity.d.ts +8 -3
  25. package/dist/skill-identity.d.ts.map +1 -1
  26. package/dist/skill-identity.js +13 -6
  27. package/dist/skill-identity.js.map +1 -1
  28. package/dist/skill-packager.d.ts +2 -1
  29. package/dist/skill-packager.d.ts.map +1 -1
  30. package/dist/skill-packager.js +47 -40
  31. package/dist/skill-packager.js.map +1 -1
  32. package/dist/skill-source/content-hash.d.ts.map +1 -1
  33. package/dist/skill-source/content-hash.js +21 -10
  34. package/dist/skill-source/content-hash.js.map +1 -1
  35. package/dist/skill-source/fetch-cache.d.ts.map +1 -1
  36. package/dist/skill-source/fetch-cache.js +0 -5
  37. package/dist/skill-source/fetch-cache.js.map +1 -1
  38. package/dist/skill-source/git-clone.d.ts.map +1 -1
  39. package/dist/skill-source/git-clone.js +0 -2
  40. package/dist/skill-source/git-clone.js.map +1 -1
  41. package/dist/skill-source/sources/url-source.d.ts.map +1 -1
  42. package/dist/skill-source/sources/url-source.js +0 -1
  43. package/dist/skill-source/sources/url-source.js.map +1 -1
  44. package/dist/skill-source/stage.d.ts.map +1 -1
  45. package/dist/skill-source/stage.js +0 -6
  46. package/dist/skill-source/stage.js.map +1 -1
  47. package/dist/skill-test/baseline-integrity.d.ts.map +1 -1
  48. package/dist/skill-test/baseline-integrity.js +8 -2
  49. package/dist/skill-test/baseline-integrity.js.map +1 -1
  50. package/dist/skill-test/build-hook.d.ts +3 -2
  51. package/dist/skill-test/build-hook.d.ts.map +1 -1
  52. package/dist/skill-test/build-hook.js +4 -4
  53. package/dist/skill-test/build-hook.js.map +1 -1
  54. package/dist/skill-test/declared-env.d.ts +5 -4
  55. package/dist/skill-test/declared-env.d.ts.map +1 -1
  56. package/dist/skill-test/declared-env.js +7 -9
  57. package/dist/skill-test/declared-env.js.map +1 -1
  58. package/dist/skill-test/eval-executor.d.ts +1 -1
  59. package/dist/skill-test/eval-executor.js +2 -2
  60. package/dist/skill-test/eval-executor.js.map +1 -1
  61. package/dist/skill-test/eval-fragment.d.ts +7 -5
  62. package/dist/skill-test/eval-fragment.d.ts.map +1 -1
  63. package/dist/skill-test/eval-fragment.js +13 -7
  64. package/dist/skill-test/eval-fragment.js.map +1 -1
  65. package/dist/skill-test/eval-grader.d.ts +56 -4
  66. package/dist/skill-test/eval-grader.d.ts.map +1 -1
  67. package/dist/skill-test/eval-grader.js +138 -73
  68. package/dist/skill-test/eval-grader.js.map +1 -1
  69. package/dist/skill-test/eval-inputs.d.ts +8 -7
  70. package/dist/skill-test/eval-inputs.d.ts.map +1 -1
  71. package/dist/skill-test/eval-inputs.js +9 -11
  72. package/dist/skill-test/eval-inputs.js.map +1 -1
  73. package/dist/skill-test/eval-lint.d.ts +4 -4
  74. package/dist/skill-test/eval-lint.js +5 -5
  75. package/dist/skill-test/eval-lint.js.map +1 -1
  76. package/dist/skill-test/eval-suite-isolation.d.ts.map +1 -1
  77. package/dist/skill-test/eval-suite-isolation.js +8 -5
  78. package/dist/skill-test/eval-suite-isolation.js.map +1 -1
  79. package/dist/skill-test/evals-template.d.ts +1 -1
  80. package/dist/skill-test/evals-template.d.ts.map +1 -1
  81. package/dist/skill-test/evals-template.js +1 -3
  82. package/dist/skill-test/evals-template.js.map +1 -1
  83. package/dist/skill-test/executor-prompt.d.ts +2 -2
  84. package/dist/skill-test/executor-prompt.js +2 -2
  85. package/dist/skill-test/failure-reason.d.ts +113 -0
  86. package/dist/skill-test/failure-reason.d.ts.map +1 -0
  87. package/dist/skill-test/failure-reason.js +124 -0
  88. package/dist/skill-test/failure-reason.js.map +1 -0
  89. package/dist/skill-test/fragment-merge.d.ts +2 -2
  90. package/dist/skill-test/fragment-merge.js +4 -4
  91. package/dist/skill-test/grader-prompt.d.ts +2 -2
  92. package/dist/skill-test/grader-prompt.d.ts.map +1 -1
  93. package/dist/skill-test/grader-prompt.js +12 -8
  94. package/dist/skill-test/grader-prompt.js.map +1 -1
  95. package/dist/skill-test/grading-adapter.d.ts +7 -3
  96. package/dist/skill-test/grading-adapter.d.ts.map +1 -1
  97. package/dist/skill-test/grading-adapter.js +10 -9
  98. package/dist/skill-test/grading-adapter.js.map +1 -1
  99. package/dist/skill-test/harness-location.d.ts +3 -2
  100. package/dist/skill-test/harness-location.d.ts.map +1 -1
  101. package/dist/skill-test/harness-location.js +5 -16
  102. package/dist/skill-test/harness-location.js.map +1 -1
  103. package/dist/skill-test/index.d.ts +1 -1
  104. package/dist/skill-test/index.d.ts.map +1 -1
  105. package/dist/skill-test/index.js +1 -1
  106. package/dist/skill-test/index.js.map +1 -1
  107. package/dist/skill-test/lock.d.ts +11 -10
  108. package/dist/skill-test/lock.d.ts.map +1 -1
  109. package/dist/skill-test/lock.js +13 -14
  110. package/dist/skill-test/lock.js.map +1 -1
  111. package/dist/skill-test/pipeline.d.ts +3 -1
  112. package/dist/skill-test/pipeline.d.ts.map +1 -1
  113. package/dist/skill-test/pipeline.js +5 -1
  114. package/dist/skill-test/pipeline.js.map +1 -1
  115. package/dist/skill-test/preflight.d.ts.map +1 -1
  116. package/dist/skill-test/preflight.js +0 -1
  117. package/dist/skill-test/preflight.js.map +1 -1
  118. package/dist/skill-test/prompt-invariants.d.ts +4 -2
  119. package/dist/skill-test/prompt-invariants.d.ts.map +1 -1
  120. package/dist/skill-test/prompt-invariants.js +5 -4
  121. package/dist/skill-test/prompt-invariants.js.map +1 -1
  122. package/dist/skill-test/run-harness.d.ts +160 -123
  123. package/dist/skill-test/run-harness.d.ts.map +1 -1
  124. package/dist/skill-test/run-harness.js +309 -173
  125. package/dist/skill-test/run-harness.js.map +1 -1
  126. package/dist/skill-test/staging.d.ts +12 -6
  127. package/dist/skill-test/staging.d.ts.map +1 -1
  128. package/dist/skill-test/staging.js +15 -12
  129. package/dist/skill-test/staging.js.map +1 -1
  130. package/dist/skill-test/tier-plan.d.ts +1 -1
  131. package/dist/skill-test/tier-plan.js +1 -1
  132. package/dist/skill-test/tool-eval-schema.js +2 -2
  133. package/dist/skill-test/vendor-manifest.d.ts +2 -1
  134. package/dist/skill-test/vendor-manifest.d.ts.map +1 -1
  135. package/dist/skill-test/vendor-manifest.js +10 -10
  136. package/dist/skill-test/vendor-manifest.js.map +1 -1
  137. package/dist/test-input.d.ts +2 -2
  138. package/dist/test-input.d.ts.map +1 -1
  139. package/dist/test-input.js +4 -5
  140. package/dist/test-input.js.map +1 -1
  141. package/dist/validators/agent-instruction-presence.d.ts.map +1 -1
  142. package/dist/validators/agent-instruction-presence.js +0 -1
  143. package/dist/validators/agent-instruction-presence.js.map +1 -1
  144. package/dist/validators/bundled-resource-link-detection.d.ts +5 -3
  145. package/dist/validators/bundled-resource-link-detection.d.ts.map +1 -1
  146. package/dist/validators/bundled-resource-link-detection.js +38 -38
  147. package/dist/validators/bundled-resource-link-detection.js.map +1 -1
  148. package/dist/validators/format-detection.d.ts +3 -0
  149. package/dist/validators/format-detection.d.ts.map +1 -1
  150. package/dist/validators/format-detection.js +41 -26
  151. package/dist/validators/format-detection.js.map +1 -1
  152. package/dist/validators/frontmatter-validation.js +1 -1
  153. package/dist/validators/frontmatter-validation.js.map +1 -1
  154. package/dist/validators/marketplace-validator.d.ts.map +1 -1
  155. package/dist/validators/marketplace-validator.js +0 -1
  156. package/dist/validators/marketplace-validator.js.map +1 -1
  157. package/dist/validators/mcp-tool-qualification.d.ts +1 -1
  158. package/dist/validators/mcp-tool-qualification.js +1 -1
  159. package/dist/validators/packaged-size-limit.d.ts.map +1 -1
  160. package/dist/validators/packaged-size-limit.js +0 -2
  161. package/dist/validators/packaged-size-limit.js.map +1 -1
  162. package/dist/validators/packaging-validator.d.ts +2 -2
  163. package/dist/validators/packaging-validator.d.ts.map +1 -1
  164. package/dist/validators/packaging-validator.js +8 -11
  165. package/dist/validators/packaging-validator.js.map +1 -1
  166. package/dist/validators/plugin-hosted-shape.d.ts +3 -1
  167. package/dist/validators/plugin-hosted-shape.d.ts.map +1 -1
  168. package/dist/validators/plugin-hosted-shape.js +5 -6
  169. package/dist/validators/plugin-hosted-shape.js.map +1 -1
  170. package/dist/validators/referenced-path-missing.d.ts.map +1 -1
  171. package/dist/validators/referenced-path-missing.js +0 -1
  172. package/dist/validators/referenced-path-missing.js.map +1 -1
  173. package/dist/validators/registry-validator.d.ts.map +1 -1
  174. package/dist/validators/registry-validator.js +0 -1
  175. package/dist/validators/registry-validator.js.map +1 -1
  176. package/dist/validators/rule-engine/index.d.ts +1 -1
  177. package/dist/validators/rule-engine/rule-context.d.ts +3 -3
  178. package/dist/validators/rule-engine/rule-context.js +1 -1
  179. package/dist/validators/rule-engine/rule-engine.d.ts +1 -1
  180. package/dist/validators/rule-engine/rule-engine.js +5 -5
  181. package/dist/validators/rule-engine/rule-engine.js.map +1 -1
  182. package/dist/validators/skill-validator.d.ts.map +1 -1
  183. package/dist/validators/skill-validator.js +41 -51
  184. package/dist/validators/skill-validator.js.map +1 -1
  185. package/dist/validators/source-only-codes.js +1 -1
  186. package/dist/validators/source-only-codes.js.map +1 -1
  187. package/dist/validators/types.d.ts +7 -1
  188. package/dist/validators/types.d.ts.map +1 -1
  189. package/dist/validators/unified-validator.d.ts.map +1 -1
  190. package/dist/validators/unified-validator.js +3 -4
  191. package/dist/validators/unified-validator.js.map +1 -1
  192. package/dist/validators/validation-rules.d.ts +3 -3
  193. package/dist/validators/validation-rules.d.ts.map +1 -1
  194. package/dist/validators/validation-rules.js +9 -38
  195. package/dist/validators/validation-rules.js.map +1 -1
  196. package/dist/validators/walker-to-issues.d.ts +2 -0
  197. package/dist/validators/walker-to-issues.d.ts.map +1 -1
  198. package/dist/validators/walker-to-issues.js +17 -12
  199. package/dist/validators/walker-to-issues.js.map +1 -1
  200. package/dist/walk-link-graph.d.ts +2 -0
  201. package/dist/walk-link-graph.d.ts.map +1 -1
  202. package/dist/walk-link-graph.js +20 -8
  203. package/dist/walk-link-graph.js.map +1 -1
  204. package/package.json +11 -19
  205. package/dist/skill-test/exit-codes.d.ts +0 -134
  206. package/dist/skill-test/exit-codes.d.ts.map +0 -1
  207. package/dist/skill-test/exit-codes.js +0 -224
  208. package/dist/skill-test/exit-codes.js.map +0 -1
@@ -71,7 +71,13 @@ const PluginInstallationSchema = z
71
71
  */
72
72
  export const InstalledPluginsRegistrySchema = z
73
73
  .object({
74
- version: z.literal(2).describe('Registry format version (currently 2)'),
74
+ // Claude Code's file, Claude Code's number: `installed_plugins.json` is
75
+ // written by another vendor and declares its own format version. Reading
76
+ // it is an external fact, like `ANTHROPIC_VERSION`, not a VAT version
77
+ // constant — a registry at a format VAT has never seen should be refused
78
+ // by name rather than parsed on hope.
79
+ // eslint-disable-next-line local/no-version-literal -- external format version declared by Claude Code's own file, not a VAT constant
80
+ version: z.literal(2).describe('Registry format version as Claude Code writes it (currently 2)'),
75
81
  plugins: z
76
82
  .record(z
77
83
  .string()
@@ -1 +1 @@
1
- {"version":3,"file":"installed-plugins-registry.js","sourceRoot":"","sources":["../../src/schemas/installed-plugins-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"installed-plugins-registry.js","sourceRoot":"","sources":["../../src/schemas/installed-plugins-registry.ts"],"names":[],"mappings":"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"}
@@ -13,9 +13,14 @@
13
13
  /**
14
14
  * Read the name a SKILL.md declares for itself.
15
15
  *
16
- * Returns `undefined` when the file is unreadable, has no frontmatter, or
17
- * declares no usable `name` — callers decide whether that is fatal or whether
18
- * some fallback (typically the directory leaf) applies.
16
+ * Returns `undefined` when there is no file at the path, it has no frontmatter,
17
+ * or it declares no usable `name` — callers decide whether that is fatal or
18
+ * whether some fallback (typically the directory leaf) applies.
19
+ *
20
+ * A file that IS there but could not be read (a permission refusal, a path
21
+ * component that is a directory) throws: `undefined` means "declares no name",
22
+ * and a refusal has not established that — a caller falling back to the
23
+ * directory leaf would otherwise rename the skill on the operator's behalf.
19
24
  */
20
25
  export declare function readDeclaredSkillName(skillMdPath: string): string | undefined;
21
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"skill-identity.d.ts","sourceRoot":"","sources":["../src/skill-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASvE"}
1
+ {"version":3,"file":"skill-identity.d.ts","sourceRoot":"","sources":["../src/skill-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASvE"}
@@ -11,22 +11,29 @@
11
11
  * a path, so every lane answers the question the same way.
12
12
  */
13
13
  import { readFileSync } from 'node:fs';
14
+ import { isPathAbsentError } from '@vibe-agent-toolkit/utils';
14
15
  import { parseFrontmatter } from './parsers/frontmatter-parser.js';
15
16
  /**
16
17
  * Read the name a SKILL.md declares for itself.
17
18
  *
18
- * Returns `undefined` when the file is unreadable, has no frontmatter, or
19
- * declares no usable `name` — callers decide whether that is fatal or whether
20
- * some fallback (typically the directory leaf) applies.
19
+ * Returns `undefined` when there is no file at the path, it has no frontmatter,
20
+ * or it declares no usable `name` — callers decide whether that is fatal or
21
+ * whether some fallback (typically the directory leaf) applies.
22
+ *
23
+ * A file that IS there but could not be read (a permission refusal, a path
24
+ * component that is a directory) throws: `undefined` means "declares no name",
25
+ * and a refusal has not established that — a caller falling back to the
26
+ * directory leaf would otherwise rename the skill on the operator's behalf.
21
27
  */
22
28
  export function readDeclaredSkillName(skillMdPath) {
23
29
  let content;
24
30
  try {
25
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- caller-supplied skill path
26
31
  content = readFileSync(skillMdPath, 'utf-8');
27
32
  }
28
- catch {
29
- return undefined;
33
+ catch (error) {
34
+ if (isPathAbsentError(error))
35
+ return undefined;
36
+ throw error;
30
37
  }
31
38
  return declaredSkillNameIn(content);
32
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skill-identity.js","sourceRoot":"","sources":["../src/skill-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,iGAAiG;QACjG,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAEtC,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEnD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9C,CAAC"}
1
+ {"version":3,"file":"skill-identity.js","sourceRoot":"","sources":["../src/skill-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,iBAAiB,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC/C,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAEtC,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEnD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9C,CAAC"}
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import { ResourceRegistry, type ResourceLink, type ResourcePopulationSource } from '@vibe-agent-toolkit/resources';
18
18
  import { type AllowUsageLedger, type ValidationConfig, type ValidationIssue } from '@vibe-agent-toolkit/schema';
19
+ import { VatError } from '@vibe-agent-toolkit/utils';
19
20
  import { type GitTracker } from '@vibe-agent-toolkit/utils/git';
20
21
  import { type PackagingTarget } from './content-type-routing.js';
21
22
  import { type SkillFileEntry } from './files-config.js';
@@ -496,7 +497,7 @@ export declare function generateTargetPath(filePath: string, basePath: string, s
496
497
  * Thrown when a claude-web ZIP exceeds the 8MB Claude.ai upload limit.
497
498
  * The CLI catches this and exits with code 1.
498
499
  */
499
- export declare class ZipSizeLimitError extends Error {
500
+ export declare class ZipSizeLimitError extends VatError {
500
501
  readonly sizeBytes: number;
501
502
  readonly limitBytes: number;
502
503
  constructor(sizeBytes: number, limitBytes: number);
@@ -1 +1 @@
1
- {"version":3,"file":"skill-packager.d.ts","sourceRoot":"","sources":["../src/skill-packager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skill-packager.d.ts","sourceRoot":"","sources":["../src/skill-packager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,EAGL,gBAAgB,EAWhB,KAAK,YAAY,EAEjB,KAAK,wBAAwB,EAE9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAIL,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EASL,QAAQ,EACT,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,KAAK,UAAU,EAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EAIvB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAA6B,KAAK,yBAAyB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AA4E3I;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,aAAa,GAAG,eAAe,CAAC;AAKlF,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,aAAa,CAAC,EAAE,CAAC;IAE1D;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC;IAExC;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAE9C,kGAAkG;IAClG,sBAAsB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAE7C,mEAAmE;IACnE,2BAA2B,CAAC,EAAE;QAC5B,KAAK,CAAC,EAAE,KAAK,CAAC;YACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;YACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SAC/B,CAAC,GAAG,SAAS,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACtC,GAAG,SAAS,CAAC;IAEd;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAExC;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAEpC;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IAErC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,cAAc,EAAE,GAAG,SAAS,CAAC;IAErC;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAE1C;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAErC;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAClD,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,oBAAoB,EAAE,sBAAsB,GAC3C,mBAAmB,CAmCrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,KAAK,EAAE,aAAa,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IAEF;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IAEF,sCAAsC;IACtC,kBAAkB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAE1C;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,EAAE,GAAG,SAAS,CAAC;IAEhD,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAE5D,iEAAiE;IACjE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAClE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EAAE,EACxB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,gBAAgB,EAC7B,UAAU,GAAE,sBAA2B,GACtC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAiChC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA+Y7B;AAgJD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CACzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,gBAAgB,CAAC,CAe3B;AA+CD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3D;AA+sBD;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,cAAc,EAAE,MAAM,IAAI,GACzB,YAAY,EAAE,CAYhB;AAgUD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASlE;AAMD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAsC9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,sBAAmC,EAC7C,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CA6CR;AAWD;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;CAUlD"}
@@ -19,7 +19,7 @@ import { copyFile, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
19
19
  import { basename, dirname } from 'node:path';
20
20
  import { DeferredArtifacts, DuplicateResourceIdError, ResourceRegistry, loadConfig, openFrontmatter, resolveLocalHref, rewriteFrontmatterUriReferencesFromSchema, rewriteHtmlLinks, transformContent, parseFileCached, } from '@vibe-agent-toolkit/resources';
21
21
  import { allowUnusedIssues, createAllowUsageLedger, runValidationFramework, } from '@vibe-agent-toolkit/schema';
22
- import { findProjectRoot, isGlob, issueLocation, resolveAssetReference, toForwardSlash, safePath, } from '@vibe-agent-toolkit/utils';
22
+ import { direntKindFollowingSync, findProjectRoot, isGlob, isSingleFsSegment, issueLocation, resolveAssetReference, safePath, toForwardSlash, VatError, } from '@vibe-agent-toolkit/utils';
23
23
  import { readTextContent } from '@vibe-agent-toolkit/utils/fs';
24
24
  import { getResourceSubdirForFile } from './content-type-routing.js';
25
25
  import { applyFilesConfig, buildArtifactHint, droppedGlobMatchesToIssues, explicitFilesConfigDests, globEntryDest, skippedGlobMatchesToIssues, } from './files-config.js';
@@ -30,7 +30,7 @@ import { detectPackagedAgentInstructionFiles } from './validators/agent-instruct
30
30
  import { checkPackagedSizeLimit } from './validators/packaged-size-limit.js';
31
31
  import { validateSkillForPackaging } from './validators/packaging-validator.js';
32
32
  import { materializeIssue } from './validators/rule-engine/index.js';
33
- import { deferredAssetsToIssues, walkerExclusionsToIssues } from './validators/walker-to-issues.js';
33
+ import { deferredAssetsToIssues, outsideSkillDirLinksToIssues, walkerExclusionsToIssues } from './validators/walker-to-issues.js';
34
34
  import { walkLinkGraph } from './walk-link-graph.js';
35
35
  const PACKAGE_JSON_FILENAME = 'package.json';
36
36
  /** `withFsAttribution` action for a write in `copyAndRewriteFile` — never a copy, since the bytes are rewritten first. */
@@ -295,7 +295,7 @@ export async function packageSkill(skillPath, options = {}) {
295
295
  const registry = options.registry ?? await createProjectRegistry(projectRoot);
296
296
  // 3b. Load per-collection frontmatter schemas (Gap 3: packager rewrites frontmatter URI-refs
297
297
  // against the same schemas the validator uses, with body parity).
298
- const collectionSchemas = await loadCollectionSchemas(registry.config, projectRoot);
298
+ const { schemas: collectionSchemas, issues: collectionSchemaIssues } = await loadCollectionSchemas(registry.config, projectRoot);
299
299
  // 4. Walk the link graph using registry data
300
300
  const linkFollowDepth = options.linkFollowDepth ?? 2;
301
301
  const excludeConfig = options.excludeReferencesFromBundle;
@@ -325,7 +325,7 @@ export async function packageSkill(skillPath, options = {}) {
325
325
  if (options.gitTracker !== undefined) {
326
326
  packagerWalkOptions.gitTracker = options.gitTracker;
327
327
  }
328
- const { bundledResources, bundledAssets, excludedReferences, deferredAssets } = walkLinkGraph(skillResourceId, registry, packagerWalkOptions);
328
+ const { bundledResources, bundledAssets, excludedReferences, outsideSkillDirLinks, deferredAssets } = walkLinkGraph(skillResourceId, registry, packagerWalkOptions);
329
329
  // Register non-markdown bundled assets in the source registry so link rewriting
330
330
  // can resolve them (resolvedId must be set on links pointing to YAML, JSON, etc.).
331
331
  // For any asset whose id is already taken (a path-slug clash — `a-b/c.html`
@@ -347,7 +347,6 @@ export async function packageSkill(skillPath, options = {}) {
347
347
  // 7. Clean stale output (skip when source SKILL.md lives inside the output, e.g. builder flow)
348
348
  const resolvedOutput = safePath.resolve(outputPath);
349
349
  const sourceInOutput = safePath.resolve(skillPath).startsWith(resolvedOutput + '/');
350
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- outputPath is validated
351
350
  if (!sourceInOutput && existsSync(resolvedOutput)) {
352
351
  await rm(resolvedOutput, { recursive: true });
353
352
  }
@@ -410,9 +409,7 @@ export async function packageSkill(skillPath, options = {}) {
410
409
  // The build's own output directory. An unwritable `dist/` or a full disk failed
411
410
  // here with a bare errno naming an output path the author never typed — the
412
411
  // same shape as the copiers, at the step before any of them run.
413
- await withFsAttribution(`skill '${skillMetadata.name}' output directory ${issueLocation(outputPath, projectRoot) || '.'}`,
414
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- outputPath is validated
415
- () => mkdir(outputPath, { recursive: true }), 'created');
412
+ await withFsAttribution(`skill '${skillMetadata.name}' output directory ${issueLocation(outputPath, projectRoot) || '.'}`, () => mkdir(outputPath, { recursive: true }), 'created');
416
413
  await copyAndRewriteFiles(skillPath, bundledFiles, {
417
414
  pathMap,
418
415
  rewriteLinks,
@@ -498,8 +495,8 @@ export async function packageSkill(skillPath, options = {}) {
498
495
  // path a reader can open is its source path.
499
496
  ...droppedGlobMatchesToIssues(appliedFiles.dropped, projectRoot),
500
497
  // The same receipt, for matches that are not copyable files at all. Anchored
501
- // identically and for the identical reason. Until issue #183 this population
502
- // had no channel because the build died on the first one it met.
498
+ // identically and for the identical reason. Without a channel of its own this
499
+ // population is invisible: the build used to die on the first one it met.
503
500
  ...skippedGlobMatchesToIssues(appliedFiles.skipped, projectRoot),
504
501
  // Presence-side backstop for agent-instruction files. The walker excludes
505
502
  // them from link-following, but a `files:` glob can still copy one in, and
@@ -514,6 +511,9 @@ export async function packageSkill(skillPath, options = {}) {
514
511
  // A receipt for each `files:` entry that was dropped for pointing into declared
515
512
  // test input — the build already produced the right artifact; this just says so.
516
513
  ...testInputFileEntryIssues(droppedTestInputFiles),
514
+ // A collection schema that could not be loaded, so its frontmatter was not
515
+ // rewritten (see loadCollectionSchemas).
516
+ ...collectionSchemaIssues,
517
517
  // Backstop: if declared test input reached the output despite both exclusions,
518
518
  // say so rather than shipping an answer key silently.
519
519
  ...checkPackagedTestInput({ pathMap, outputPath, testInputDirs }),
@@ -525,6 +525,7 @@ export async function packageSkill(skillPath, options = {}) {
525
525
  // (a pattern match is author-declared intent; this exclusion is VAT's).
526
526
  ...testInputLinkIssues(excludedReferences, testInputDirs, projectRoot),
527
527
  ...deferredAssetsToIssues(deferredAssets, projectRoot),
528
+ ...outsideSkillDirLinksToIssues(outsideSkillDirLinks, projectRoot),
528
529
  ];
529
530
  // ONE ledger for BOTH lanes below. `options.validation.allow` governs the
530
531
  // build-receipt lane AND the built-SKILL.md lane, but the two see disjoint
@@ -603,7 +604,7 @@ function withRunAllowUnused(framework, ledger) {
603
604
  *
604
605
  * ## 🚨 This lane's link graph is EMPTY — and that is the NORMAL case
605
606
  *
606
- * Measured 2026-08 on a probe fixture (one skill, one `reference.md` reachable by
607
+ * Measured on a probe fixture (one skill, one `reference.md` reachable by
607
608
  * a single relative link from `SKILL.md`), run three ways with ONE variable —
608
609
  * where the packaged output lands:
609
610
  *
@@ -626,7 +627,7 @@ function withRunAllowUnused(framework, ledger) {
626
627
  * `${CLAUDE_PLUGIN_ROOT}` invocation inside a bundled reference is caught at
627
628
  * source and CANNOT be caught in the built artifact.
628
629
  *
629
- * 🔑 Measured vs inferred. The three rows are MEASURED (2026-08, that probe).
630
+ * 🔑 Measured vs inferred. The three rows are MEASURED (that probe).
630
631
  * That the finding is still LIVE is inferred from this function's own body: it
631
632
  * passes only the built `SKILL.md` path, with no registry and no population
632
633
  * source rooted at the output tree, so `validateSkillForPackaging` resolves
@@ -736,30 +737,40 @@ export async function createProjectRegistry(projectRoot, options = {}) {
736
737
  * Mirrors ResourceRegistry.validateAgainstCollectionSchema's loading flow so
737
738
  * the packager rewrites frontmatter URI-refs against the same schemas the
738
739
  * validator uses. Collections without a frontmatterSchema configured are
739
- * absent from the map. Schema file read/parse failures are silently skipped
740
- * — the validator will surface those errors elsewhere; the packager just
741
- * won't rewrite the un-routed collection's frontmatter.
740
+ * absent from the map.
741
+ *
742
+ * A schema that cannot be resolved, read or parsed is absent from the map too,
743
+ * and that is REPORTED as a `FRONTMATTER_SCHEMA_ERROR` issue in the build's own
744
+ * receipt — the same code `vat validate` gives the same config. It used to be
745
+ * swallowed on the theory that "the validator will surface it elsewhere", which
746
+ * left `vat build` shipping a bundle whose frontmatter URI-refs still pointed
747
+ * at source-tree paths, with a clean report and nothing to say why.
742
748
  */
743
749
  async function loadCollectionSchemas(config, baseDir) {
744
750
  const schemas = new Map();
751
+ const issues = [];
745
752
  const collections = config?.resources?.collections;
746
753
  if (!collections)
747
- return schemas;
754
+ return { schemas, issues };
748
755
  for (const [collectionId, collectionConfig] of Object.entries(collections)) {
749
756
  const schemaPath = collectionConfig.validation?.frontmatterSchema;
750
757
  if (schemaPath === undefined)
751
758
  continue;
752
759
  try {
753
760
  const resolvedPath = resolveAssetReference(schemaPath, baseDir);
754
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- schema path from validated config
755
761
  const content = await readFile(resolvedPath, 'utf-8');
756
762
  schemas.set(collectionId, JSON.parse(content));
757
763
  }
758
- catch {
759
- // Schema unavailable — validator will report; packager skips rewrite.
764
+ catch (error) {
765
+ issues.push(materializeIssue('FRONTMATTER_SCHEMA_ERROR', {
766
+ location: schemaPath,
767
+ message: `Collection "${collectionId}" declares frontmatterSchema "${schemaPath}", which could not ` +
768
+ `be loaded: ${error instanceof Error ? error.message : String(error)}. Frontmatter ` +
769
+ `URI-references in this collection were NOT rewritten for the packaged output.`,
770
+ }));
760
771
  }
761
772
  }
762
- return schemas;
773
+ return { schemas, issues };
763
774
  }
764
775
  /**
765
776
  * Generate a synthetic resource ID for a non-markdown asset that collides with an
@@ -986,7 +997,6 @@ function applyFilesEntriesToPathMap(filesConfig, projectRoot, outputPath, pathMa
986
997
  // have helped. A wrong diagnosis with a confident wrong remedy attached.
987
998
  // Only ENOENT is absence; a refusal is reported as itself, naming the entry.
988
999
  try {
989
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- source path from validated config
990
1000
  statSync(absoluteSource);
991
1001
  }
992
1002
  catch (error) {
@@ -1421,7 +1431,6 @@ async function copyAndRewriteFile(sourcePath, targetPath, ctx) {
1421
1431
  const subject = `linked file ${issueLocation(sourcePath, ctx.projectRoot) || '.'}`;
1422
1432
  // Ensure target directory exists
1423
1433
  await withFsAttribution(subject, async () => {
1424
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- targetPath is constructed from validated paths
1425
1434
  await mkdir(dirname(targetPath), { recursive: true });
1426
1435
  });
1427
1436
  const lower = sourcePath.toLowerCase();
@@ -1480,9 +1489,7 @@ async function copyAndRewriteFile(sourcePath, targetPath, ctx) {
1480
1489
  `Source-relative links inside it are not rewritten.`
1481
1490
  : `Copied '${sourcePath}' verbatim without link rewriting: it lost a resource-id collision to ` +
1482
1491
  `'${winner}', which was registered first and holds the id. Source-relative links inside it are not rewritten.`);
1483
- await withFsAttribution(subject,
1484
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- targetPath is constructed from validated paths
1485
- () => writeFile(targetPath, content, 'utf-8'), WRITE_ACTION);
1492
+ await withFsAttribution(subject, () => writeFile(targetPath, content, 'utf-8'), WRITE_ACTION);
1486
1493
  return;
1487
1494
  }
1488
1495
  // HTML: offset-splice link rewrite (no frontmatter, no template body rewrite).
@@ -1492,9 +1499,7 @@ async function copyAndRewriteFile(sourcePath, targetPath, ctx) {
1492
1499
  ctx.warn(`Could not rewrite <${info.tagName} ${info.attr}="${info.from}"> in '${sourcePath}' (${info.reason}); ` +
1493
1500
  `the original value was kept.`);
1494
1501
  });
1495
- await withFsAttribution(subject,
1496
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- targetPath is constructed from validated paths
1497
- () => writeFile(targetPath, rewritten, 'utf-8'), WRITE_ACTION);
1502
+ await withFsAttribution(subject, () => writeFile(targetPath, rewritten, 'utf-8'), WRITE_ACTION);
1498
1503
  return;
1499
1504
  }
1500
1505
  // Parse once via FrontmatterEditor so comments survive any frontmatter
@@ -1528,9 +1533,7 @@ async function copyAndRewriteFile(sourcePath, targetPath, ctx) {
1528
1533
  }
1529
1534
  }
1530
1535
  }
1531
- await withFsAttribution(subject,
1532
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- targetPath is constructed from validated paths
1533
- () => writeFile(targetPath, editor.toString(), 'utf-8'), WRITE_ACTION);
1536
+ await withFsAttribution(subject, () => writeFile(targetPath, editor.toString(), 'utf-8'), WRITE_ACTION);
1534
1537
  }
1535
1538
  /**
1536
1539
  * Build the per-href rewrite callback used for frontmatter URI-refs and HTML attributes.
@@ -1584,10 +1587,10 @@ function buildHrefRewriter(fromRegistry, toRegistry, sourcePath, targetPath, pro
1584
1587
  * but this check acts as a safety net in case files are introduced through other means.
1585
1588
  */
1586
1589
  async function validateNoNestedSkillMd(outputPath, skillName) {
1587
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- outputPath is validated
1588
1590
  const entries = readdirSync(outputPath, { recursive: true, withFileTypes: true });
1589
1591
  const nestedSkillMds = entries
1590
- .filter(entry => entry.isFile() && entry.name === 'SKILL.md')
1592
+ // Followed: a symlinked nested SKILL.md is a nested skill marker all the same.
1593
+ .filter(entry => entry.name === 'SKILL.md' && direntKindFollowingSync(entry.parentPath, entry) === 'file')
1591
1594
  .map(entry => safePath.relative(outputPath, safePath.join(entry.parentPath, entry.name)))
1592
1595
  .filter(relativePath => relativePath !== 'SKILL.md'); // Exclude the root SKILL.md
1593
1596
  if (nestedSkillMds.length > 0) {
@@ -1755,14 +1758,13 @@ const ZIP_SIZE_ERROR_BYTES = 8 * 1024 * 1024;
1755
1758
  * Thrown when a claude-web ZIP exceeds the 8MB Claude.ai upload limit.
1756
1759
  * The CLI catches this and exits with code 1.
1757
1760
  */
1758
- export class ZipSizeLimitError extends Error {
1761
+ export class ZipSizeLimitError extends VatError {
1759
1762
  sizeBytes;
1760
1763
  limitBytes;
1761
1764
  constructor(sizeBytes, limitBytes) {
1762
1765
  const mb = (sizeBytes / 1024 / 1024).toFixed(1);
1763
- super(`ZIP size ${mb}MB exceeds 8MB limit for Claude.ai upload. ` +
1766
+ super('ZIP_SIZE_LIMIT', `ZIP size ${mb}MB exceeds 8MB limit for Claude.ai upload. ` +
1764
1767
  `Reduce the number of linked resources or use --target claude-code.`);
1765
- this.name = 'ZipSizeLimitError';
1766
1768
  this.sizeBytes = sizeBytes;
1767
1769
  this.limitBytes = limitBytes;
1768
1770
  }
@@ -1774,7 +1776,6 @@ export class ZipSizeLimitError extends Error {
1774
1776
  * @param zipPath - Path to the ZIP file
1775
1777
  */
1776
1778
  function validateZipSize(zipPath) {
1777
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- zipPath is constructed from validated outputPath
1778
1779
  const stats = statSync(zipPath);
1779
1780
  const bytes = stats.size;
1780
1781
  if (bytes >= ZIP_SIZE_ERROR_BYTES) {
@@ -1855,7 +1856,6 @@ async function createNpmPackage(outputPath, metadata) {
1855
1856
  files: ['**/*.md'],
1856
1857
  };
1857
1858
  const packageJsonPath = safePath.join(outputPath, PACKAGE_JSON_FILENAME);
1858
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is constructed from validated outputPath
1859
1859
  await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8');
1860
1860
  // For now, just return a placeholder path
1861
1861
  // Full npm pack implementation would require running `npm pack`
@@ -1880,7 +1880,6 @@ async function createMarketplaceManifest(outputPath, metadata) {
1880
1880
  created: new Date().toISOString(),
1881
1881
  };
1882
1882
  const manifestPath = safePath.join(dirname(outputPath), `${metadata.name}.marketplace.json`);
1883
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is constructed from validated outputPath
1884
1883
  await writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');
1885
1884
  return manifestPath;
1886
1885
  }
@@ -1894,6 +1893,15 @@ async function createMarketplaceManifest(outputPath, metadata) {
1894
1893
  * @returns Default output path
1895
1894
  */
1896
1895
  function getDefaultSkillOutputPath(skillPath, skillName) {
1896
+ // The name may have come from the H1 title when frontmatter carries none,
1897
+ // and the directory this returns is `rm -rf`'d before the package is
1898
+ // written: a SKILL.md headed `# ../../../canary` used to delete `<root>/canary`
1899
+ // through the public `packageSkill` export, issues empty, `hasErrors` false.
1900
+ if (!isSingleFsSegment(skillName)) {
1901
+ throw new VatError('SKILL_NAME_NOT_A_SEGMENT', `Cannot derive an output directory from skill name "${skillName}": a name must be a single ` +
1902
+ `path segment (no separators, not "." or ".."). Declare \`name:\` in the SKILL.md frontmatter ` +
1903
+ `or pass an explicit outputPath.`);
1904
+ }
1897
1905
  const skillPackageRoot = findPackageRoot(skillPath);
1898
1906
  return safePath.join(skillPackageRoot, 'dist', 'skills', skillName);
1899
1907
  }
@@ -1912,7 +1920,6 @@ function findPackageRoot(skillPath, fallbackToSkillDir = false) {
1912
1920
  // Walk up until we find a package.json or hit the filesystem root
1913
1921
  while (currentDir !== dirname(currentDir)) {
1914
1922
  const packageJsonPath = safePath.join(currentDir, PACKAGE_JSON_FILENAME);
1915
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Searching for package.json
1916
1923
  if (existsSync(packageJsonPath)) {
1917
1924
  return currentDir;
1918
1925
  }