@vibe-agent-toolkit/agent-skills 0.1.33 → 0.1.34

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 (90) hide show
  1. package/dist/index.d.ts +9 -6
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +6 -4
  4. package/dist/index.js.map +1 -1
  5. package/dist/inventory/detectors/declared-but-missing.d.ts +11 -0
  6. package/dist/inventory/detectors/declared-but-missing.d.ts.map +1 -0
  7. package/dist/inventory/detectors/declared-but-missing.js +37 -0
  8. package/dist/inventory/detectors/declared-but-missing.js.map +1 -0
  9. package/dist/inventory/detectors/index.d.ts +5 -0
  10. package/dist/inventory/detectors/index.d.ts.map +1 -0
  11. package/dist/inventory/detectors/index.js +5 -0
  12. package/dist/inventory/detectors/index.js.map +1 -0
  13. package/dist/inventory/detectors/marketplace-source-missing.d.ts +12 -0
  14. package/dist/inventory/detectors/marketplace-source-missing.d.ts.map +1 -0
  15. package/dist/inventory/detectors/marketplace-source-missing.js +20 -0
  16. package/dist/inventory/detectors/marketplace-source-missing.js.map +1 -0
  17. package/dist/inventory/detectors/present-but-undeclared.d.ts +13 -0
  18. package/dist/inventory/detectors/present-but-undeclared.d.ts.map +1 -0
  19. package/dist/inventory/detectors/present-but-undeclared.js +47 -0
  20. package/dist/inventory/detectors/present-but-undeclared.js.map +1 -0
  21. package/dist/inventory/detectors/reference-target-missing.d.ts +11 -0
  22. package/dist/inventory/detectors/reference-target-missing.d.ts.map +1 -0
  23. package/dist/inventory/detectors/reference-target-missing.js +19 -0
  24. package/dist/inventory/detectors/reference-target-missing.js.map +1 -0
  25. package/dist/inventory/index.d.ts +5 -0
  26. package/dist/inventory/index.d.ts.map +1 -0
  27. package/dist/inventory/index.js +4 -0
  28. package/dist/inventory/index.js.map +1 -0
  29. package/dist/inventory/serialize.d.ts +24 -0
  30. package/dist/inventory/serialize.d.ts.map +1 -0
  31. package/dist/inventory/serialize.js +52 -0
  32. package/dist/inventory/serialize.js.map +1 -0
  33. package/dist/inventory/types.d.ts +126 -0
  34. package/dist/inventory/types.d.ts.map +1 -0
  35. package/dist/inventory/types.js +16 -0
  36. package/dist/inventory/types.js.map +1 -0
  37. package/dist/schemas/index.d.ts +0 -1
  38. package/dist/schemas/index.d.ts.map +1 -1
  39. package/dist/schemas/index.js +0 -1
  40. package/dist/schemas/index.js.map +1 -1
  41. package/dist/validators/bundled-resource-link-detection.d.ts +20 -0
  42. package/dist/validators/bundled-resource-link-detection.d.ts.map +1 -0
  43. package/dist/validators/bundled-resource-link-detection.js +92 -0
  44. package/dist/validators/bundled-resource-link-detection.js.map +1 -0
  45. package/dist/validators/code-registry.d.ts +1 -1
  46. package/dist/validators/code-registry.d.ts.map +1 -1
  47. package/dist/validators/code-registry.js +12 -0
  48. package/dist/validators/code-registry.js.map +1 -1
  49. package/dist/validators/format-detection.d.ts +21 -1
  50. package/dist/validators/format-detection.d.ts.map +1 -1
  51. package/dist/validators/format-detection.js +85 -1
  52. package/dist/validators/format-detection.js.map +1 -1
  53. package/dist/validators/imperative-body-detection.d.ts +15 -0
  54. package/dist/validators/imperative-body-detection.d.ts.map +1 -0
  55. package/dist/validators/imperative-body-detection.js +49 -0
  56. package/dist/validators/imperative-body-detection.js.map +1 -0
  57. package/dist/validators/index.d.ts +6 -4
  58. package/dist/validators/index.d.ts.map +1 -1
  59. package/dist/validators/index.js +4 -2
  60. package/dist/validators/index.js.map +1 -1
  61. package/dist/validators/kebab-case-detection.d.ts +22 -0
  62. package/dist/validators/kebab-case-detection.d.ts.map +1 -0
  63. package/dist/validators/kebab-case-detection.js +43 -0
  64. package/dist/validators/kebab-case-detection.js.map +1 -0
  65. package/dist/validators/packaging-validator.d.ts +9 -0
  66. package/dist/validators/packaging-validator.d.ts.map +1 -1
  67. package/dist/validators/packaging-validator.js +4 -1
  68. package/dist/validators/packaging-validator.js.map +1 -1
  69. package/dist/validators/plugin-recommended-fields.d.ts +26 -0
  70. package/dist/validators/plugin-recommended-fields.d.ts.map +1 -0
  71. package/dist/validators/plugin-recommended-fields.js +66 -0
  72. package/dist/validators/plugin-recommended-fields.js.map +1 -0
  73. package/dist/validators/skill-validator.d.ts.map +1 -1
  74. package/dist/validators/skill-validator.js +20 -4
  75. package/dist/validators/skill-validator.js.map +1 -1
  76. package/dist/validators/types.d.ts +23 -0
  77. package/dist/validators/types.d.ts.map +1 -1
  78. package/dist/validators/unified-validator.d.ts +9 -4
  79. package/dist/validators/unified-validator.d.ts.map +1 -1
  80. package/dist/validators/unified-validator.js +19 -6
  81. package/dist/validators/unified-validator.js.map +1 -1
  82. package/package.json +5 -5
  83. package/dist/schemas/claude-plugin.d.ts +0 -98
  84. package/dist/schemas/claude-plugin.d.ts.map +0 -1
  85. package/dist/schemas/claude-plugin.js +0 -79
  86. package/dist/schemas/claude-plugin.js.map +0 -1
  87. package/dist/validators/plugin-validator.d.ts +0 -12
  88. package/dist/validators/plugin-validator.d.ts.map +0 -1
  89. package/dist/validators/plugin-validator.js +0 -99
  90. package/dist/validators/plugin-validator.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,+BAA+B,EAC/B,2BAA2B,EAC3B,8BAA8B,GAG/B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAqB,MAAM,oBAAoB,CAAC;AAEnG,OAAO,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AAErE,OAAO,EACL,kCAAkC,EAClC,8BAA8B,GAG/B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,mCAAmC,EACnC,+BAA+B,GAIhC,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,6BAA6B,EAC7B,yBAAyB,GAE1B,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,+BAA+B,EAC/B,2BAA2B,EAC3B,8BAA8B,GAG/B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AAErE,OAAO,EACL,kCAAkC,EAClC,8BAA8B,GAG/B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,mCAAmC,EACnC,+BAA+B,GAIhC,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,6BAA6B,EAC7B,yBAAyB,GAE1B,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Bundled-resource link detector.
3
+ *
4
+ * Emits SKILL_REFERENCES_BUT_NO_LINKS at info severity when a skill
5
+ * directory contains scripts/, references/, or assets/ subdirectories
6
+ * but neither SKILL.md's body nor any transitively linked file points
7
+ * into them via a markdown link.
8
+ *
9
+ * Plugin-dev's "Mistake 4: Missing Resource References" — bundled assets
10
+ * the body never links to are dead weight in the install. The author
11
+ * intended progressive disclosure but forgot to wire up the references.
12
+ */
13
+ import type { ValidationIssue } from './types.js';
14
+ /**
15
+ * @param skillPath Absolute path to SKILL.md
16
+ * @param skillDir Absolute path to the skill directory (typically dirname(skillPath))
17
+ * @param linkedFiles Absolute paths of files reached during BFS link traversal
18
+ */
19
+ export declare function detectBundledResourceWithoutLinks(skillPath: string, skillDir: string, linkedFiles: readonly string[]): ValidationIssue[];
20
+ //# sourceMappingURL=bundled-resource-link-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundled-resource-link-detection.d.ts","sourceRoot":"","sources":["../../src/validators/bundled-resource-link-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAoDlD;;;;GAIG;AACH,wBAAgB,iCAAiC,CAC/C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,eAAe,EAAE,CAuBnB"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Bundled-resource link detector.
3
+ *
4
+ * Emits SKILL_REFERENCES_BUT_NO_LINKS at info severity when a skill
5
+ * directory contains scripts/, references/, or assets/ subdirectories
6
+ * but neither SKILL.md's body nor any transitively linked file points
7
+ * into them via a markdown link.
8
+ *
9
+ * Plugin-dev's "Mistake 4: Missing Resource References" — bundled assets
10
+ * the body never links to are dead weight in the install. The author
11
+ * intended progressive disclosure but forgot to wire up the references.
12
+ */
13
+ /* eslint-disable security/detect-non-literal-fs-filename -- skill paths validated upstream */
14
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
15
+ import { dirname } from 'node:path';
16
+ import { safePath } from '@vibe-agent-toolkit/utils';
17
+ import { CODE_REGISTRY } from './code-registry.js';
18
+ const BUNDLED_SUBDIRS = ['scripts', 'references', 'assets'];
19
+ /** Read SKILL.md content (best-effort) — empty string if unreadable. */
20
+ function readSkillContent(skillPath) {
21
+ try {
22
+ return readFileSync(skillPath, 'utf-8');
23
+ }
24
+ catch {
25
+ return '';
26
+ }
27
+ }
28
+ /** Subdirectory exists AND contains at least one file (recursive). */
29
+ function isNonEmptyDir(dir) {
30
+ if (!existsSync(dir))
31
+ return false;
32
+ try {
33
+ const entries = readdirSync(dir, { withFileTypes: true });
34
+ for (const entry of entries) {
35
+ if (entry.isFile())
36
+ return true;
37
+ if (entry.isDirectory() && isNonEmptyDir(safePath.join(dir, entry.name))) {
38
+ return true;
39
+ }
40
+ }
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ return false;
46
+ }
47
+ /** Body or linked file references the subdir via path containing `<sub>/`. */
48
+ function bodyMentionsSubdir(body, sub) {
49
+ // Lightweight check: the sub-dir name occurs as part of a markdown
50
+ // path, e.g. `(scripts/cli.mjs)` or `[x](references/detail.md)`. We
51
+ // accept any occurrence of `<sub>/` since false negatives (a real
52
+ // link the heuristic misses) are worse than false positives at info.
53
+ return body.includes(`${sub}/`);
54
+ }
55
+ /** Linked file path is inside the subdir. */
56
+ function linkedFilesCoverSubdir(linkedFiles, skillDir, sub) {
57
+ const subDir = safePath.join(skillDir, sub);
58
+ return linkedFiles.some((f) => {
59
+ const rel = safePath.relative(subDir, f);
60
+ return !rel.startsWith('..') && rel.length > 0;
61
+ });
62
+ }
63
+ /**
64
+ * @param skillPath Absolute path to SKILL.md
65
+ * @param skillDir Absolute path to the skill directory (typically dirname(skillPath))
66
+ * @param linkedFiles Absolute paths of files reached during BFS link traversal
67
+ */
68
+ export function detectBundledResourceWithoutLinks(skillPath, skillDir, linkedFiles) {
69
+ const issues = [];
70
+ const body = readSkillContent(skillPath);
71
+ const baseDir = skillDir.length > 0 ? skillDir : dirname(skillPath);
72
+ for (const sub of BUNDLED_SUBDIRS) {
73
+ const subPath = safePath.join(baseDir, sub);
74
+ if (!isNonEmptyDir(subPath))
75
+ continue;
76
+ if (bodyMentionsSubdir(body, sub))
77
+ continue;
78
+ if (linkedFilesCoverSubdir(linkedFiles, baseDir, sub))
79
+ continue;
80
+ const entry = CODE_REGISTRY.SKILL_REFERENCES_BUT_NO_LINKS;
81
+ issues.push({
82
+ severity: entry.defaultSeverity,
83
+ code: 'SKILL_REFERENCES_BUT_NO_LINKS',
84
+ message: `Skill directory contains "${sub}/" but no markdown link from SKILL.md or linked files points into it.`,
85
+ location: subPath,
86
+ fix: entry.fix,
87
+ reference: entry.reference,
88
+ });
89
+ }
90
+ return issues;
91
+ }
92
+ //# sourceMappingURL=bundled-resource-link-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundled-resource-link-detection.js","sourceRoot":"","sources":["../../src/validators/bundled-resource-link-detection.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@
11
11
  export type IssueSeverity = 'error' | 'warning' | 'info' | 'ignore';
12
12
  /** Non-ignore severities actually emitted to consumers. */
13
13
  export type EmittedSeverity = Exclude<IssueSeverity, 'ignore'>;
14
- export type IssueCode = 'LINK_OUTSIDE_PROJECT' | 'LINK_TARGETS_DIRECTORY' | 'LINK_TO_NAVIGATION_FILE' | 'LINK_TO_GITIGNORED_FILE' | 'LINK_MISSING_TARGET' | 'LINK_TO_SKILL_DEFINITION' | 'LINK_DROPPED_BY_DEPTH' | 'PACKAGED_UNREFERENCED_FILE' | 'PACKAGED_BROKEN_LINK' | 'SKILL_LENGTH_EXCEEDS_RECOMMENDED' | 'SKILL_TOTAL_SIZE_LARGE' | 'SKILL_TOO_MANY_FILES' | 'REFERENCE_TOO_DEEP' | 'DESCRIPTION_TOO_VAGUE' | 'NO_PROGRESSIVE_DISCLOSURE' | 'SKILL_DESCRIPTION_OVER_CLAUDE_CODE_LIMIT' | 'SKILL_DESCRIPTION_FILLER_OPENER' | 'SKILL_DESCRIPTION_WRONG_PERSON' | 'SKILL_NAME_MISMATCHES_DIR' | 'RESERVED_WORD_IN_NAME' | 'SKILL_TIME_SENSITIVE_CONTENT' | 'SKILL_FRONTMATTER_EXTRA_FIELDS' | 'SKILL_CROSS_SKILL_AUTH_UNDECLARED' | 'SKILL_DESCRIPTION_STYLE_MIXED_IN_PACKAGE' | 'CAPABILITY_LOCAL_SHELL' | 'CAPABILITY_EXTERNAL_CLI' | 'CAPABILITY_BROWSER_AUTH' | 'COMPAT_TARGET_INCOMPATIBLE' | 'COMPAT_TARGET_NEEDS_REVIEW' | 'COMPAT_TARGET_UNDECLARED' | 'ALLOW_EXPIRED' | 'ALLOW_UNUSED';
14
+ export type IssueCode = 'LINK_OUTSIDE_PROJECT' | 'LINK_TARGETS_DIRECTORY' | 'LINK_TO_NAVIGATION_FILE' | 'LINK_TO_GITIGNORED_FILE' | 'LINK_MISSING_TARGET' | 'LINK_TO_SKILL_DEFINITION' | 'LINK_DROPPED_BY_DEPTH' | 'PACKAGED_UNREFERENCED_FILE' | 'PACKAGED_BROKEN_LINK' | 'SKILL_LENGTH_EXCEEDS_RECOMMENDED' | 'SKILL_TOTAL_SIZE_LARGE' | 'SKILL_TOO_MANY_FILES' | 'REFERENCE_TOO_DEEP' | 'DESCRIPTION_TOO_VAGUE' | 'NO_PROGRESSIVE_DISCLOSURE' | 'SKILL_DESCRIPTION_OVER_CLAUDE_CODE_LIMIT' | 'SKILL_DESCRIPTION_FILLER_OPENER' | 'SKILL_DESCRIPTION_WRONG_PERSON' | 'SKILL_CLAUDE_PLUGIN_NAME_MISMATCH' | 'SKILL_NAME_MISMATCHES_DIR' | 'RESERVED_WORD_IN_NAME' | 'SKILL_TIME_SENSITIVE_CONTENT' | 'SKILL_FRONTMATTER_EXTRA_FIELDS' | 'SKILL_CROSS_SKILL_AUTH_UNDECLARED' | 'SKILL_DESCRIPTION_STYLE_MIXED_IN_PACKAGE' | 'PLUGIN_MISSING_DESCRIPTION' | 'PLUGIN_MISSING_AUTHOR' | 'PLUGIN_MISSING_LICENSE' | 'PLUGIN_NAME_NOT_KEBAB_CASE' | 'SKILL_NAME_NOT_KEBAB_CASE' | 'SKILL_REFERENCES_BUT_NO_LINKS' | 'SKILL_BODY_NOT_IMPERATIVE' | 'CAPABILITY_LOCAL_SHELL' | 'CAPABILITY_EXTERNAL_CLI' | 'CAPABILITY_BROWSER_AUTH' | 'COMPAT_TARGET_INCOMPATIBLE' | 'COMPAT_TARGET_NEEDS_REVIEW' | 'COMPAT_TARGET_UNDECLARED' | 'ALLOW_EXPIRED' | 'ALLOW_UNUSED' | 'COMPONENT_DECLARED_BUT_MISSING' | 'COMPONENT_PRESENT_BUT_UNDECLARED' | 'REFERENCE_TARGET_MISSING' | 'MARKETPLACE_PLUGIN_SOURCE_MISSING';
15
15
  export interface CodeRegistryEntry {
16
16
  defaultSeverity: EmittedSeverity;
17
17
  description: string;
@@ -1 +1 @@
1
- {"version":3,"file":"code-registry.d.ts","sourceRoot":"","sources":["../../src/validators/code-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpE,2DAA2D;AAC3D,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;AAE/D,MAAM,MAAM,SAAS,GAEjB,sBAAsB,GACtB,wBAAwB,GACxB,yBAAyB,GACzB,yBAAyB,GACzB,qBAAqB,GACrB,0BAA0B,GAE1B,uBAAuB,GACvB,4BAA4B,GAC5B,sBAAsB,GAEtB,kCAAkC,GAClC,wBAAwB,GACxB,sBAAsB,GACtB,oBAAoB,GACpB,uBAAuB,GACvB,2BAA2B,GAC3B,0CAA0C,GAC1C,iCAAiC,GACjC,gCAAgC,GAChC,2BAA2B,GAC3B,uBAAuB,GACvB,8BAA8B,GAC9B,gCAAgC,GAChC,mCAAmC,GACnC,0CAA0C,GAE1C,wBAAwB,GACxB,yBAAyB,GACzB,yBAAyB,GAEzB,4BAA4B,GAC5B,4BAA4B,GAC5B,0BAA0B,GAE1B,eAAe,GACf,cAAc,CAAC;AAEnB,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;CACnB;AASD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,iBAAiB,CAiM9D,CAAC"}
1
+ {"version":3,"file":"code-registry.d.ts","sourceRoot":"","sources":["../../src/validators/code-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpE,2DAA2D;AAC3D,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;AAE/D,MAAM,MAAM,SAAS,GAEjB,sBAAsB,GACtB,wBAAwB,GACxB,yBAAyB,GACzB,yBAAyB,GACzB,qBAAqB,GACrB,0BAA0B,GAE1B,uBAAuB,GACvB,4BAA4B,GAC5B,sBAAsB,GAEtB,kCAAkC,GAClC,wBAAwB,GACxB,sBAAsB,GACtB,oBAAoB,GACpB,uBAAuB,GACvB,2BAA2B,GAC3B,0CAA0C,GAC1C,iCAAiC,GACjC,gCAAgC,GAChC,mCAAmC,GACnC,2BAA2B,GAC3B,uBAAuB,GACvB,8BAA8B,GAC9B,gCAAgC,GAChC,mCAAmC,GACnC,0CAA0C,GAE1C,4BAA4B,GAC5B,uBAAuB,GACvB,wBAAwB,GAExB,4BAA4B,GAC5B,2BAA2B,GAE3B,+BAA+B,GAC/B,2BAA2B,GAE3B,wBAAwB,GACxB,yBAAyB,GACzB,yBAAyB,GAEzB,4BAA4B,GAC5B,4BAA4B,GAC5B,0BAA0B,GAE1B,eAAe,GACf,cAAc,GAEd,gCAAgC,GAChC,kCAAkC,GAClC,0BAA0B,GAC1B,mCAAmC,CAAC;AAExC,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;CACnB;AASD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,iBAAiB,CAyQ9D,CAAC"}
@@ -28,12 +28,20 @@ export const CODE_REGISTRY = {
28
28
  SKILL_DESCRIPTION_OVER_CLAUDE_CODE_LIMIT: entry('warning', 'SKILL.md description exceeds the 250-character Claude Code /skills display limit.', 'Shorten the description below 250 chars (target ≤200 for a safety margin, or ≤130 if shipping a large skill collection).', 'skill_description_over_claude_code_limit'),
29
29
  SKILL_DESCRIPTION_FILLER_OPENER: entry('warning', 'SKILL.md description opens with meta-filler (e.g., "This skill...", "A skill that...", "Use when you want to...").', 'Lead with a verb phrase ("Extracts text from PDFs...") or "Use when <concrete trigger>".', 'skill_description_filler_opener'),
30
30
  SKILL_DESCRIPTION_WRONG_PERSON: entry('warning', 'SKILL.md description uses first-person or conversational second-person voice.', 'Rewrite in third person. "I can extract PDFs" → "Extracts text from PDFs". "You can use this to..." → the action itself.', 'skill_description_wrong_person'),
31
+ SKILL_CLAUDE_PLUGIN_NAME_MISMATCH: entry('warning', 'plugin.json name does not match the co-located root SKILL.md frontmatter name.', 'Align the names: update plugin.json `name` to match SKILL.md `name` (the skill is authoritative), or intentionally namespace the plugin (configure `validation.severity` or `validation.allow` with a reason).', 'skill_claude_plugin_name_mismatch'),
31
32
  SKILL_NAME_MISMATCHES_DIR: entry('warning', 'Frontmatter name field does not match the skill parent directory name.', 'Align them: rename the directory to match name, or update name to match the directory.', 'skill_name_mismatches_dir'),
32
33
  RESERVED_WORD_IN_NAME: entry('warning', 'Frontmatter `name` contains a reserved word (`anthropic` or `claude`); Claude Code rejects non-certified skills using these words.', 'Rename the skill to avoid `anthropic` or `claude` in the name.', 'reserved_word_in_name'),
33
34
  SKILL_TIME_SENSITIVE_CONTENT: entry('info', 'SKILL.md body contains time-sensitive prose (e.g., "as of November 2025") that may become stale.', 'Remove the time qualifier, or move deprecated guidance into a clearly labeled "## Old patterns" section with a <details> block.', 'skill_time_sensitive_content'),
34
35
  SKILL_FRONTMATTER_EXTRA_FIELDS: entry('warning', 'SKILL.md frontmatter contains a field outside the standard agentskills.io + Claude Code key set.', 'Move custom data under `metadata.<key>`, or remove the field. Per-project config belongs in vibe-agent-toolkit.config.yaml, not SKILL.md frontmatter.', 'skill_frontmatter_extra_fields'),
35
36
  SKILL_CROSS_SKILL_AUTH_UNDECLARED: entry('warning', 'SKILL.md body declares a dependency on a sibling skill or ANTHROPIC_*_KEY environment variable that is not mentioned in the description.', 'Name the dependency in the description (e.g. "Requires ado skill for auth" or "Requires ANTHROPIC_ADMIN_API_KEY") so agents loading the skill discover it without reading the body.', 'skill_cross_skill_auth_undeclared'),
36
37
  SKILL_DESCRIPTION_STYLE_MIXED_IN_PACKAGE: entry('warning', 'Sibling skills in the same package use mixed YAML scalar styles for their `description` frontmatter (e.g., folded `>-` alongside inline double-quoted).', 'Pick one YAML style and apply it to every skill in the package.', 'skill_description_style_mixed_in_package'),
38
+ PLUGIN_MISSING_DESCRIPTION: entry('info', 'plugin.json is missing the recommended `description` field.', 'Add a "description" field to plugin.json so users see what the plugin does in the listing.', 'plugin_missing_description'),
39
+ PLUGIN_MISSING_AUTHOR: entry('info', 'plugin.json is missing the recommended `author` field.', 'Add an "author" object (e.g. { "name": "..." }) to plugin.json so downstream consumers can attribute the plugin.', 'plugin_missing_author'),
40
+ PLUGIN_MISSING_LICENSE: entry('info', 'plugin.json is missing the recommended `license` field.', 'Add a "license" SPDX identifier (e.g. "MIT") to plugin.json so redistribution terms are explicit.', 'plugin_missing_license'),
41
+ PLUGIN_NAME_NOT_KEBAB_CASE: entry('info', 'Plugin name does not match the kebab-case convention required by Claude Code (lowercase alphanumeric with single hyphens).', 'Rename the plugin to kebab-case (e.g. "my-plugin"). Schema parse already errors; this code surfaces the same finding with a more actionable message.', 'plugin_name_not_kebab_case'),
42
+ SKILL_NAME_NOT_KEBAB_CASE: entry('info', 'Skill frontmatter `name` does not match the kebab-case convention.', 'Rename the skill to kebab-case (e.g. "my-skill"). Schema parse already errors; this code surfaces the same finding with a more actionable message.', 'skill_name_not_kebab_case'),
43
+ SKILL_REFERENCES_BUT_NO_LINKS: entry('info', 'Skill directory contains scripts/, references/, or assets/ subdirectories but the SKILL.md body has zero markdown links into them.', 'Add explicit markdown links from SKILL.md (or a linked file) into the bundled subdirectories, or remove the unreferenced directory. Allow via validation.allow if the assets are consumed programmatically.', 'skill_references_but_no_links'),
44
+ SKILL_BODY_NOT_IMPERATIVE: entry('info', 'SKILL.md body contains second-person instructional openers (e.g. "You should…", "You need to…", "You can…").', 'Rewrite as imperative ("Configure the MCP server…" instead of "You should configure…"). Skill bodies read more cleanly as instructions to the agent rather than to a human reader. Allow via validation.allow if the heuristic misfires on quoted prompts or user dialog.', 'skill_body_not_imperative'),
37
45
  CAPABILITY_LOCAL_SHELL: entry('info', 'Skill references a local-shell tool (Bash/Edit/Write/NotebookEdit) or invokes a shell.', 'Informational. Declare a plugin target that provides shell (claude-code, claude-cowork) so this observation resolves to an expected verdict.', 'capability_local_shell'),
38
46
  CAPABILITY_EXTERNAL_CLI: entry('info', 'Skill invokes an external CLI binary not bundled with the skill.', 'Informational. Ensure the declared target guarantees the binary or document the prerequisite.', 'capability_external_cli'),
39
47
  CAPABILITY_BROWSER_AUTH: entry('info', 'Skill appears to require an interactive browser login flow.', 'Informational. If a service-principal flow would work, prefer it. Otherwise declare a browser-capable target.', 'capability_browser_auth'),
@@ -42,5 +50,9 @@ export const CODE_REGISTRY = {
42
50
  COMPAT_TARGET_UNDECLARED: entry('info', 'Skill has capability observations but no target is declared.', 'Declare targets in vibe-agent-toolkit.config.yaml, plugin.json, or marketplace.json defaults.', 'compat_target_undeclared'),
43
51
  ALLOW_EXPIRED: entry('warning', "A validation.allow entry's expires date is in the past; the allowance still applies but should be re-reviewed.", 'Re-review the allow entry: extend expires, remove the entry, or fix the underlying issue. Upgrade severity to error for zero-tolerance expiry.', 'allow_expired'),
44
52
  ALLOW_UNUSED: entry('warning', 'A validation.allow entry did not match any emitted issue; the allow entry is dead weight.', 'Remove the entry or fix the pattern. Upgrade severity to error to block on unused allow entries.', 'allow_unused'),
53
+ COMPONENT_DECLARED_BUT_MISSING: entry('warning', 'A component path declared in the plugin manifest does not exist on disk.', 'Add the missing file, remove the manifest declaration, or correct the path. Use validation.allow if the artifact is generated by an install-time build step.', 'component_declared_but_missing'),
54
+ COMPONENT_PRESENT_BUT_UNDECLARED: entry('info', 'A component is present under the canonical layout but the manifest declares an explicit list that omits it; the runtime may silently skip it at install.', 'Add the component to the appropriate manifest field, or remove the file if unintended. Skipped when the manifest omits the field entirely (auto-discovery is intentional).', 'component_present_but_undeclared'),
55
+ REFERENCE_TARGET_MISSING: entry('error', 'A cross-component reference resolved from the manifest points to a path that does not exist.', 'Add the referenced file or correct the path in the manifest.', 'reference_target_missing'),
56
+ MARKETPLACE_PLUGIN_SOURCE_MISSING: entry('error', 'A marketplace declares a plugin with a path-based source that does not exist.', 'Correct the source path or remove the entry from marketplace.plugins[].', 'marketplace_plugin_source_missing'),
45
57
  };
46
58
  //# sourceMappingURL=code-registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"code-registry.js","sourceRoot":"","sources":["../../src/validators/code-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code-registry.js","sourceRoot":"","sources":["../../src/validators/code-registry.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ResourceFormat } from './types.js';
1
+ import type { ResourceFormat, Surface } from './types.js';
2
2
  /**
3
3
  * Detects the format of a resource at the given path
4
4
  *
@@ -23,4 +23,24 @@ import type { ResourceFormat } from './types.js';
23
23
  * @returns ResourceFormat discriminated union
24
24
  */
25
25
  export declare function detectResourceFormat(resourcePath: string): Promise<ResourceFormat>;
26
+ /**
27
+ * Enumerate all manifest surfaces present at a directory's root layer.
28
+ *
29
+ * Unlike {@link detectResourceFormat} (single-answer), this returns every
30
+ * recognized manifest found in the same directory. A skill-claude-plugin
31
+ * (root SKILL.md + .claude-plugin/plugin.json) returns two surfaces; a
32
+ * canonical plugin layout returns one (SKILL.md lives under skills/<name>/,
33
+ * not at the plugin root, so no agent-skill surface at this level).
34
+ *
35
+ * Detection rules (independent, all applied):
36
+ * - `<dir>/SKILL.md` exists → { type: 'agent-skill', path: <dir>/SKILL.md }
37
+ * - `<dir>/.claude-plugin/plugin.json` exists → { type: 'claude-plugin', path: <dir> }
38
+ * - `<dir>/.claude-plugin/marketplace.json` exists → { type: 'marketplace', path: <dir> }
39
+ *
40
+ * Returns `[]` for nonexistent paths, files, or directories with no recognized manifests.
41
+ *
42
+ * @param dirPath - Absolute path to a directory
43
+ * @returns Array of surfaces in enumerator-stable order (skill, plugin, marketplace)
44
+ */
45
+ export declare function enumerateSurfaces(dirPath: string): Promise<Surface[]>;
26
46
  //# sourceMappingURL=format-detection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-detection.d.ts","sourceRoot":"","sources":["../../src/validators/format-detection.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,oBAAoB,CACzC,YAAY,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CAwCzB"}
1
+ {"version":3,"file":"format-detection.d.ts","sourceRoot":"","sources":["../../src/validators/format-detection.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,oBAAoB,CACzC,YAAY,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CAwCzB;AAuID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAyC3E"}
@@ -2,6 +2,7 @@
2
2
  import * as fs from 'node:fs';
3
3
  import * as path from 'node:path';
4
4
  import { safePath } from '@vibe-agent-toolkit/utils';
5
+ const CLAUDE_PLUGIN_DIR_NAME = '.claude-plugin';
5
6
  /**
6
7
  * Detects the format of a resource at the given path
7
8
  *
@@ -66,7 +67,7 @@ export async function detectResourceFormat(resourcePath) {
66
67
  * Detects format for directory resources
67
68
  */
68
69
  function detectDirectoryFormat(dirPath) {
69
- const claudePluginDir = safePath.join(dirPath, '.claude-plugin');
70
+ const claudePluginDir = safePath.join(dirPath, CLAUDE_PLUGIN_DIR_NAME);
70
71
  // Check if .claude-plugin directory exists
71
72
  if (!fs.existsSync(claudePluginDir)) {
72
73
  return {
@@ -178,4 +179,87 @@ function detectFileFormat(filePath) {
178
179
  reason: 'JSON file but not a recognized registry',
179
180
  };
180
181
  }
182
+ /**
183
+ * Enumerate all manifest surfaces present at a directory's root layer.
184
+ *
185
+ * Unlike {@link detectResourceFormat} (single-answer), this returns every
186
+ * recognized manifest found in the same directory. A skill-claude-plugin
187
+ * (root SKILL.md + .claude-plugin/plugin.json) returns two surfaces; a
188
+ * canonical plugin layout returns one (SKILL.md lives under skills/<name>/,
189
+ * not at the plugin root, so no agent-skill surface at this level).
190
+ *
191
+ * Detection rules (independent, all applied):
192
+ * - `<dir>/SKILL.md` exists → { type: 'agent-skill', path: <dir>/SKILL.md }
193
+ * - `<dir>/.claude-plugin/plugin.json` exists → { type: 'claude-plugin', path: <dir> }
194
+ * - `<dir>/.claude-plugin/marketplace.json` exists → { type: 'marketplace', path: <dir> }
195
+ *
196
+ * Returns `[]` for nonexistent paths, files, or directories with no recognized manifests.
197
+ *
198
+ * @param dirPath - Absolute path to a directory
199
+ * @returns Array of surfaces in enumerator-stable order (skill, plugin, marketplace)
200
+ */
201
+ export async function enumerateSurfaces(dirPath) {
202
+ try {
203
+ if (!fs.existsSync(dirPath)) {
204
+ return [];
205
+ }
206
+ const stats = fs.statSync(dirPath);
207
+ if (!stats.isDirectory()) {
208
+ return [];
209
+ }
210
+ }
211
+ catch {
212
+ return [];
213
+ }
214
+ const surfaces = [];
215
+ const skillPath = safePath.join(dirPath, 'SKILL.md');
216
+ if (fs.existsSync(skillPath)) {
217
+ surfaces.push({ type: 'agent-skill', path: skillPath });
218
+ }
219
+ const pluginJsonPath = safePath.join(dirPath, CLAUDE_PLUGIN_DIR_NAME, 'plugin.json');
220
+ const marketplaceJsonPath = safePath.join(dirPath, CLAUDE_PLUGIN_DIR_NAME, 'marketplace.json');
221
+ const hasPlugin = fs.existsSync(pluginJsonPath);
222
+ const hasMarketplace = fs.existsSync(marketplaceJsonPath);
223
+ // Co-located plugin/marketplace pattern: when both plugin.json and
224
+ // marketplace.json are present AND the marketplace references the current
225
+ // directory via `source: "./"`, detectResourceFormat collapses to a single
226
+ // `marketplace` surface. Preserve that collapse here so a co-located
227
+ // marketplace does not produce two parallel results (marketplace AND plugin).
228
+ const isColocated = hasPlugin && hasMarketplace && hasColocatedPluginInMarketplace(marketplaceJsonPath);
229
+ if (hasPlugin && !isColocated) {
230
+ surfaces.push({ type: 'claude-plugin', path: dirPath });
231
+ }
232
+ if (hasMarketplace) {
233
+ surfaces.push({ type: 'marketplace', path: dirPath });
234
+ }
235
+ return surfaces;
236
+ }
237
+ /**
238
+ * Returns true when marketplace.json declares a plugin with `source` pointing
239
+ * at the current directory (`./`, `.`, etc.), indicating a single-directory
240
+ * marketplace that owns the co-located plugin.
241
+ *
242
+ * Best-effort: swallows read/parse errors (caller treats as "not co-located").
243
+ */
244
+ function hasColocatedPluginInMarketplace(marketplaceJsonPath) {
245
+ try {
246
+ const content = fs.readFileSync(marketplaceJsonPath, 'utf-8');
247
+ const data = JSON.parse(content);
248
+ const plugins = data['plugins'];
249
+ if (!Array.isArray(plugins)) {
250
+ return false;
251
+ }
252
+ return plugins.some((plugin) => {
253
+ if (typeof plugin !== 'object' || plugin === null)
254
+ return false;
255
+ const source = plugin['source'];
256
+ if (typeof source !== 'string')
257
+ return false;
258
+ return source === './' || source === '.' || source === '.\\' || source === '';
259
+ });
260
+ }
261
+ catch {
262
+ return false;
263
+ }
264
+ }
181
265
  //# sourceMappingURL=format-detection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-detection.js","sourceRoot":"","sources":["../../src/validators/format-detection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format-detection.js","sourceRoot":"","sources":["../../src/validators/format-detection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Non-imperative body detector (gray-zone heuristic, info severity).
3
+ *
4
+ * Emits SKILL_BODY_NOT_IMPERATIVE for lines that open with a second-
5
+ * person modal phrase ("You should…", "You can…", "You need to…",
6
+ * "You must…", "You will…", "You may…") outside fenced code blocks
7
+ * and quoted blocks.
8
+ *
9
+ * Plugin-dev's "Mistake 3: Second Person Writing" identifies imperative
10
+ * form as more agent-readable. Heuristic; ships at info to gather corpus
11
+ * signal before any promotion.
12
+ */
13
+ import type { ValidationIssue } from './types.js';
14
+ export declare function detectNonImperativeBody(body: string, location: string): ValidationIssue[];
15
+ //# sourceMappingURL=imperative-body-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imperative-body-detection.d.ts","sourceRoot":"","sources":["../../src/validators/imperative-body-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AASlD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,eAAe,EAAE,CA8BnB"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Non-imperative body detector (gray-zone heuristic, info severity).
3
+ *
4
+ * Emits SKILL_BODY_NOT_IMPERATIVE for lines that open with a second-
5
+ * person modal phrase ("You should…", "You can…", "You need to…",
6
+ * "You must…", "You will…", "You may…") outside fenced code blocks
7
+ * and quoted blocks.
8
+ *
9
+ * Plugin-dev's "Mistake 3: Second Person Writing" identifies imperative
10
+ * form as more agent-readable. Heuristic; ships at info to gather corpus
11
+ * signal before any promotion.
12
+ */
13
+ import { CODE_REGISTRY } from './code-registry.js';
14
+ // Targeted modals only — excludes "are" and "did" so we match instructional
15
+ // constructions, not factual ones.
16
+ const SECOND_PERSON_OPENER_RE = /^You\s+(should|can|need|must|will|may)\b/i;
17
+ const FENCE_RE = /^\s*```/;
18
+ const QUOTE_RE = /^\s*>/;
19
+ export function detectNonImperativeBody(body, location) {
20
+ const issues = [];
21
+ const entry = CODE_REGISTRY.SKILL_BODY_NOT_IMPERATIVE;
22
+ let inFence = false;
23
+ const lines = body.split('\n');
24
+ for (const [idx, line] of lines.entries()) {
25
+ if (FENCE_RE.test(line)) {
26
+ inFence = !inFence;
27
+ continue;
28
+ }
29
+ if (inFence)
30
+ continue;
31
+ if (QUOTE_RE.test(line))
32
+ continue;
33
+ const match = SECOND_PERSON_OPENER_RE.exec(line);
34
+ if (match) {
35
+ const lineNumber = idx + 1;
36
+ const sample = line.slice(0, 80);
37
+ issues.push({
38
+ severity: entry.defaultSeverity,
39
+ code: 'SKILL_BODY_NOT_IMPERATIVE',
40
+ message: `Second-person opener "${sample.trim()}" — prefer imperative form (e.g. "Configure…").`,
41
+ location: `${location}:${lineNumber}`,
42
+ fix: entry.fix,
43
+ reference: entry.reference,
44
+ });
45
+ }
46
+ }
47
+ return issues;
48
+ }
49
+ //# sourceMappingURL=imperative-body-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imperative-body-detection.js","sourceRoot":"","sources":["../../src/validators/imperative-body-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,4EAA4E;AAC5E,mCAAmC;AACnC,MAAM,uBAAuB,GAAG,2CAA2C,CAAC;AAE5E,MAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC;AAEzB,MAAM,UAAU,uBAAuB,CACrC,IAAY,EACZ,QAAgB;IAEhB,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,aAAa,CAAC,yBAAyB,CAAC;IAEtD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,OAAO,CAAC;YACnB,SAAS;QACX,CAAC;QACD,IAAI,OAAO;YAAE,SAAS;QACtB,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAElC,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,UAAU,GAAG,GAAG,GAAG,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC;gBACV,QAAQ,EAAE,KAAK,CAAC,eAAe;gBAC/B,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,yBAAyB,MAAM,CAAC,IAAI,EAAE,iDAAiD;gBAChG,QAAQ,EAAE,GAAG,QAAQ,IAAI,UAAU,EAAE;gBACrC,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,SAAS,EAAE,KAAK,CAAC,SAAS;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,7 +1,9 @@
1
- export { detectResourceFormat } from './format-detection.js';
2
- export { validatePlugin } from './plugin-validator.js';
1
+ export { calculateValidationStatus, generateFixSuggestion } from './validation-utils.js';
2
+ export { detectKebabCaseViolation, type KebabCaseSurface } from './kebab-case-detection.js';
3
+ export { detectMissingRecommendedFields } from './plugin-recommended-fields.js';
4
+ export { detectResourceFormat, enumerateSurfaces } from './format-detection.js';
3
5
  export { validateInstalledPluginsRegistry, validateKnownMarketplacesRegistry, } from './registry-validator.js';
4
6
  export { validateSkill } from './skill-validator.js';
5
- export { validate } from './unified-validator.js';
6
- export type { IssueCode, IssueSeverity, LinkedFileValidationResult, ResourceFormat, ValidateOptions, ValidationIssue, ValidationResult, } from './types.js';
7
+ export { validate, type UnifiedValidateOptions } from './unified-validator.js';
8
+ export type { IssueCode, IssueSeverity, LinkedFileValidationResult, ResourceFormat, Surface, ValidateOptions, ValidationIssue, ValidationResult, } from './types.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACN,gCAAgC,EAChC,iCAAiC,GACjC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,YAAY,EACX,SAAS,EACT,aAAa,EACb,0BAA0B,EAC1B,cAAc,EACd,eAAe,EACf,eAAe,EACf,gBAAgB,GAChB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,wBAAwB,EAAE,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC5F,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,EACN,gCAAgC,EAChC,iCAAiC,GACjC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,KAAK,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,YAAY,EACX,SAAS,EACT,aAAa,EACb,0BAA0B,EAC1B,cAAc,EACd,OAAO,EACP,eAAe,EACf,eAAe,EACf,gBAAgB,GAChB,MAAM,YAAY,CAAC"}
@@ -1,5 +1,7 @@
1
- export { detectResourceFormat } from './format-detection.js';
2
- export { validatePlugin } from './plugin-validator.js';
1
+ export { calculateValidationStatus, generateFixSuggestion } from './validation-utils.js';
2
+ export { detectKebabCaseViolation } from './kebab-case-detection.js';
3
+ export { detectMissingRecommendedFields } from './plugin-recommended-fields.js';
4
+ export { detectResourceFormat, enumerateSurfaces } from './format-detection.js';
3
5
  export { validateInstalledPluginsRegistry, validateKnownMarketplacesRegistry, } from './registry-validator.js';
4
6
  export { validateSkill } from './skill-validator.js';
5
7
  export { validate } from './unified-validator.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACN,gCAAgC,EAChC,iCAAiC,GACjC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,wBAAwB,EAAyB,MAAM,2BAA2B,CAAC;AAC5F,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,EACN,gCAAgC,EAChC,iCAAiC,GACjC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAA+B,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Kebab-case naming detector.
3
+ *
4
+ * Plugin-dev's "Name requirements" section: kebab-case is mandatory for
5
+ * both plugin names and skill names. Both the ClaudePluginSchema and
6
+ * agent-skill frontmatter schema enforce the regex via Zod, but Zod
7
+ * surfaces only a generic schema error. This detector emits a named
8
+ * info-severity code so audit output names the convention specifically.
9
+ *
10
+ * The detector is additive — Zod parse continues to error on invalid
11
+ * names (PLUGIN_INVALID_SCHEMA / SKILL_NAME_INVALID), and this code
12
+ * provides a more actionable second message at info severity.
13
+ */
14
+ import type { ValidationIssue } from './types.js';
15
+ export type KebabCaseSurface = 'plugin' | 'skill';
16
+ /**
17
+ * Returns a ValidationIssue when `name` violates kebab-case, or undefined
18
+ * when the name is empty (let upstream "missing name" validators handle
19
+ * that case).
20
+ */
21
+ export declare function detectKebabCaseViolation(surface: KebabCaseSurface, name: string, location: string): ValidationIssue | undefined;
22
+ //# sourceMappingURL=kebab-case-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kebab-case-detection.d.ts","sourceRoot":"","sources":["../../src/validators/kebab-case-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKlD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,eAAe,GAAG,SAAS,CAqB7B"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Kebab-case naming detector.
3
+ *
4
+ * Plugin-dev's "Name requirements" section: kebab-case is mandatory for
5
+ * both plugin names and skill names. Both the ClaudePluginSchema and
6
+ * agent-skill frontmatter schema enforce the regex via Zod, but Zod
7
+ * surfaces only a generic schema error. This detector emits a named
8
+ * info-severity code so audit output names the convention specifically.
9
+ *
10
+ * The detector is additive — Zod parse continues to error on invalid
11
+ * names (PLUGIN_INVALID_SCHEMA / SKILL_NAME_INVALID), and this code
12
+ * provides a more actionable second message at info severity.
13
+ */
14
+ import { CODE_REGISTRY } from './code-registry.js';
15
+ // eslint-disable-next-line security/detect-unsafe-regex -- Simple pattern with bounded length, safe from ReDoS (mirrors the regex in ClaudePluginSchema)
16
+ const KEBAB_CASE_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
17
+ /**
18
+ * Returns a ValidationIssue when `name` violates kebab-case, or undefined
19
+ * when the name is empty (let upstream "missing name" validators handle
20
+ * that case).
21
+ */
22
+ export function detectKebabCaseViolation(surface, name, location) {
23
+ if (name.length === 0) {
24
+ return undefined;
25
+ }
26
+ if (KEBAB_CASE_RE.test(name)) {
27
+ return undefined;
28
+ }
29
+ const code = surface === 'plugin'
30
+ ? 'PLUGIN_NAME_NOT_KEBAB_CASE'
31
+ : 'SKILL_NAME_NOT_KEBAB_CASE';
32
+ const entry = CODE_REGISTRY[code];
33
+ const subject = surface === 'plugin' ? 'plugin' : 'skill';
34
+ return {
35
+ severity: entry.defaultSeverity,
36
+ code,
37
+ message: `${subject} name "${name}" is not kebab-case (lowercase alphanumeric with single hyphens, e.g. "my-${subject}").`,
38
+ location,
39
+ fix: entry.fix,
40
+ reference: entry.reference,
41
+ };
42
+ }
43
+ //# sourceMappingURL=kebab-case-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kebab-case-detection.js","sourceRoot":"","sources":["../../src/validators/kebab-case-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,yJAAyJ;AACzJ,MAAM,aAAa,GAAG,0BAA0B,CAAC;AAIjD;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAyB,EACzB,IAAY,EACZ,QAAgB;IAEhB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,KAAK,QAAQ;QAC/B,CAAC,CAAC,4BAA4B;QAC9B,CAAC,CAAC,2BAA2B,CAAC;IAChC,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1D,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,eAAe;QAC/B,IAAI;QACJ,OAAO,EAAE,GAAG,OAAO,UAAU,IAAI,6EAA6E,OAAO,KAAK;QAC1H,QAAQ;QACR,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;AACJ,CAAC"}
@@ -94,6 +94,15 @@ export interface PackagingValidationResult {
94
94
  excludedReferences: ExcludedReferenceDetail[];
95
95
  };
96
96
  }
97
+ /**
98
+ * Build a fresh ResourceRegistry for a single skill's projectRoot and resolve
99
+ * internal links. Extracted so the skill validator can fall back to a private
100
+ * registry when the caller does not supply a shared one.
101
+ *
102
+ * Exported so external callers (e.g. the inventory layer) can build a registry
103
+ * once and pass it down rather than re-crawling per skill.
104
+ */
105
+ export declare function crawlAndResolveRegistry(projectRoot: string): Promise<ResourceRegistry>;
97
106
  /**
98
107
  * Shared context for batched skill validation runs.
99
108
  *
@@ -1 +1 @@
1
- {"version":3,"file":"packaging-validator.d.ts","sourceRoot":"","sources":["../../src/validators/packaging-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,EAAiB,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAA+D,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEzH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAY1F;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,cAAc,CAAC,EAAE,UAAU,GAAG,aAAa,GAAG,eAAe,CAAC;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,2BAA2B,CAAC,EAAE;QAC5B,KAAK,CAAC,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACzD,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,uFAAuF;IACvF,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC,aAAa,GAAG,eAAe,GAAG,aAAa,CAAC,CAAC;CAC1E;AAED,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,YAAY,CAAC;IACzH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAElB,wBAAwB;IACxB,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAE5B,uEAAuE;IACvE,SAAS,EAAE,eAAe,EAAE,CAAC;IAE7B,oEAAoE;IACpE,YAAY,EAAE,eAAe,EAAE,CAAC;IAEhC,wEAAwE;IACxE,cAAc,EAAE,eAAe,EAAE,CAAC;IAElC,yCAAyC;IACzC,aAAa,EAAE,WAAW,EAAE,CAAC;IAE7B;;;;;OAKG;IACH,YAAY,EAAE,WAAW,EAAE,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,EAAE,cAAc,EAAE,CAAC;IAE3B,+BAA+B;IAC/B,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,kBAAkB,EAAE,uBAAuB,EAAE,CAAC;KAC/C,CAAC;CACH;AAiFD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,4BAA4B;IAC3C,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,kEAAkE;IAClE,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,oBAAoB,EACtC,OAAO,GAAE,QAAQ,GAAG,OAAkB,EACtC,MAAM,CAAC,EAAE,4BAA4B,GACpC,OAAO,CAAC,yBAAyB,CAAC,CAuIpC;AAyFD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,OAAO,EACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,eAAe,GAAG,IAAI,CA4BxB"}
1
+ {"version":3,"file":"packaging-validator.d.ts","sourceRoot":"","sources":["../../src/validators/packaging-validator.ts"],"names":[],"mappings":"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"}
@@ -72,8 +72,11 @@ function createRegistryIssue(code, message, location) {
72
72
  * Build a fresh ResourceRegistry for a single skill's projectRoot and resolve
73
73
  * internal links. Extracted so the skill validator can fall back to a private
74
74
  * registry when the caller does not supply a shared one.
75
+ *
76
+ * Exported so external callers (e.g. the inventory layer) can build a registry
77
+ * once and pass it down rather than re-crawling per skill.
75
78
  */
76
- async function crawlAndResolveRegistry(projectRoot) {
79
+ export async function crawlAndResolveRegistry(projectRoot) {
77
80
  const registry = await ResourceRegistry.fromCrawl({
78
81
  baseDir: projectRoot,
79
82
  include: ['**/*.md'],