@vibe-agent-toolkit/agent-skills 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -11,6 +11,10 @@ export { parseFrontmatter, type FrontmatterResult, } from './parsers/frontmatter
11
11
  export { validateSkill } from './validators/skill-validator.js';
12
12
  export { validate } from './validators/unified-validator.js';
13
13
  export { detectResourceFormat } from './validators/format-detection.js';
14
+ export { validateSkillForPackaging, type ExcludedReferenceDetail, type PackagingValidationResult, } from './validators/packaging-validator.js';
15
+ export { createIssue, isOverridable, NAVIGATION_FILE_PATTERNS, NON_OVERRIDABLE_RULES, VALIDATION_RULES, VALIDATION_THRESHOLDS, type RuleCategory, type ValidationRule, type ValidationRuleCode, } from './validators/validation-rules.js';
14
16
  export type { ValidationResult, ValidationIssue, ValidateOptions, ResourceFormat, } from './validators/types.js';
15
17
  export { importSkillToAgent, type ImportOptions, type ImportResult, } from './import.js';
18
+ export { collectLinks, type DefaultRule, type ExcludeRule, type LinkCollectionOptions, type LinkCollectionResult, type LinkResolution, } from './link-collector.js';
19
+ export type { ValidationOverride } from '@vibe-agent-toolkit/agent-schema';
16
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EACL,cAAc,EACd,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,GAC/B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE3G,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,gBAAgB,EAChB,KAAK,iBAAiB,GACvB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EACL,cAAc,EACd,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,GAC/B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE3G,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,gBAAgB,EAChB,KAAK,iBAAiB,GACvB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EACL,yBAAyB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,GAC/B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,aAAa,EACb,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,GACxB,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC"}
package/dist/index.js CHANGED
@@ -11,5 +11,8 @@ export { parseFrontmatter, } from './parsers/frontmatter-parser.js';
11
11
  export { validateSkill } from './validators/skill-validator.js';
12
12
  export { validate } from './validators/unified-validator.js';
13
13
  export { detectResourceFormat } from './validators/format-detection.js';
14
+ export { validateSkillForPackaging, } from './validators/packaging-validator.js';
15
+ export { createIssue, isOverridable, NAVIGATION_FILE_PATTERNS, NON_OVERRIDABLE_RULES, VALIDATION_RULES, VALIDATION_THRESHOLDS, } from './validators/validation-rules.js';
14
16
  export { importSkillToAgent, } from './import.js';
17
+ export { collectLinks, } from './link-collector.js';
15
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAuC,MAAM,cAAc,CAAC;AAErF,OAAO,EACL,cAAc,EACd,YAAY,GAIb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,GAGhC,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAqB,MAAM,4BAA4B,CAAC;AAE3G,OAAO,EACL,qBAAqB,EACrB,iBAAiB,GAKlB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,gBAAgB,GAEjB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAQxE,OAAO,EACL,kBAAkB,GAGnB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAuC,MAAM,cAAc,CAAC;AAErF,OAAO,EACL,cAAc,EACd,YAAY,GAIb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,GAGhC,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAqB,MAAM,4BAA4B,CAAC;AAE3G,OAAO,EACL,qBAAqB,EACrB,iBAAiB,GAKlB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,gBAAgB,GAEjB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EACL,yBAAyB,GAG1B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,aAAa,EACb,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,GAItB,MAAM,kCAAkC,CAAC;AAQ1C,OAAO,EACL,kBAAkB,GAGnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,GAMb,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Unified link collection module
3
+ *
4
+ * Provides a single algorithm for collecting and classifying links from a
5
+ * skill's markdown file tree. Used by both the packaging validator (to report
6
+ * excluded references) and the skill packager (to rewrite dead links).
7
+ *
8
+ * Key design decisions:
9
+ * - Non-markdown assets (images, JSON, etc.) are always bundled (no recursion, no depth contribution)
10
+ * unless they match an exclude pattern
11
+ * - Markdown links are subject to depth limits and exclude rules
12
+ * - excludedReferences is NOT deduped: each occurrence preserves per-link context
13
+ * - bundledFiles IS deduped: same file from multiple paths = one bundle entry
14
+ * - Glob matching uses forward-slash paths relative to skillRoot
15
+ */
16
+ /**
17
+ * Resolution result for a single link found in a bundled markdown file.
18
+ */
19
+ export interface LinkResolution {
20
+ /** Absolute path to the linked file */
21
+ path: string;
22
+ /** Whether the file will be bundled */
23
+ bundled: boolean;
24
+ /** Reason it was excluded (only set when bundled is false) */
25
+ excludeReason?: 'depth-exceeded' | 'pattern-matched' | 'directory-target' | undefined;
26
+ /** The rule that matched (only set for pattern-matched exclusions) */
27
+ matchedRule?: ExcludeRule | undefined;
28
+ /** Link text from the source markdown */
29
+ linkText?: string | undefined;
30
+ /** Original href from the markdown */
31
+ linkHref?: string | undefined;
32
+ }
33
+ /**
34
+ * A rule that excludes files from bundling based on glob patterns.
35
+ * First matching rule wins (ordered evaluation).
36
+ */
37
+ export interface ExcludeRule {
38
+ patterns: string[];
39
+ template?: string | undefined;
40
+ }
41
+ /**
42
+ * Default template for depth-exceeded and unmatched excluded links.
43
+ */
44
+ export interface DefaultRule {
45
+ template?: string | undefined;
46
+ }
47
+ /**
48
+ * Options for link collection.
49
+ */
50
+ export interface LinkCollectionOptions {
51
+ /** Max depth (Infinity for 'full') */
52
+ maxDepth: number;
53
+ /** Ordered exclude rules (first match wins) */
54
+ excludeRules: ExcludeRule[];
55
+ /** Default handling for depth-exceeded and unmatched excluded links */
56
+ defaultRule: DefaultRule;
57
+ /** Skill root directory for resolving relative paths in glob matching */
58
+ skillRoot: string;
59
+ /** Package root for boundary enforcement (packager only) */
60
+ packageRoot?: string | undefined;
61
+ }
62
+ /**
63
+ * Result of collecting links from a skill's markdown file tree.
64
+ */
65
+ export interface LinkCollectionResult {
66
+ /** Files within depth AND not excluded -- will be bundled */
67
+ bundledFiles: string[];
68
+ /** Files detected but NOT bundled (depth or exclude) */
69
+ excludedReferences: LinkResolution[];
70
+ /** Actual max depth of the bundled portion */
71
+ maxBundledDepth: number;
72
+ }
73
+ /**
74
+ * Collect all links from a skill's markdown file tree, classifying each as
75
+ * bundled or excluded.
76
+ *
77
+ * This is the core algorithm used by both the packaging validator and the
78
+ * skill packager. It walks the markdown link tree starting from the given
79
+ * skill file, respecting depth limits and exclude rules.
80
+ *
81
+ * @param markdownPath - Absolute path to the root SKILL.md file
82
+ * @param options - Collection options (depth, excludes, etc.)
83
+ * @returns Collection result with bundled files and excluded references
84
+ */
85
+ export declare function collectLinks(markdownPath: string, options: LinkCollectionOptions): Promise<LinkCollectionResult>;
86
+ //# sourceMappingURL=link-collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-collector.d.ts","sourceRoot":"","sources":["../src/link-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,SAAS,CAAC;IACtF,sEAAsE;IACtE,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACtC,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,uEAAuE;IACvE,WAAW,EAAE,WAAW,CAAC;IACzB,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,wDAAwD;IACxD,kBAAkB,EAAE,cAAc,EAAE,CAAC;IACrC,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;CACzB;AA0BD;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAI/B"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Unified link collection module
3
+ *
4
+ * Provides a single algorithm for collecting and classifying links from a
5
+ * skill's markdown file tree. Used by both the packaging validator (to report
6
+ * excluded references) and the skill packager (to rewrite dead links).
7
+ *
8
+ * Key design decisions:
9
+ * - Non-markdown assets (images, JSON, etc.) are always bundled (no recursion, no depth contribution)
10
+ * unless they match an exclude pattern
11
+ * - Markdown links are subject to depth limits and exclude rules
12
+ * - excludedReferences is NOT deduped: each occurrence preserves per-link context
13
+ * - bundledFiles IS deduped: same file from multiple paths = one bundle entry
14
+ * - Glob matching uses forward-slash paths relative to skillRoot
15
+ */
16
+ import { existsSync, statSync } from 'node:fs';
17
+ import { dirname, relative, resolve } from 'node:path';
18
+ import { parseMarkdown } from '@vibe-agent-toolkit/resources';
19
+ import { toForwardSlash } from '@vibe-agent-toolkit/utils';
20
+ import picomatch from 'picomatch';
21
+ // ============================================================================
22
+ // Public API
23
+ // ============================================================================
24
+ /**
25
+ * Collect all links from a skill's markdown file tree, classifying each as
26
+ * bundled or excluded.
27
+ *
28
+ * This is the core algorithm used by both the packaging validator and the
29
+ * skill packager. It walks the markdown link tree starting from the given
30
+ * skill file, respecting depth limits and exclude rules.
31
+ *
32
+ * @param markdownPath - Absolute path to the root SKILL.md file
33
+ * @param options - Collection options (depth, excludes, etc.)
34
+ * @returns Collection result with bundled files and excluded references
35
+ */
36
+ export async function collectLinks(markdownPath, options) {
37
+ const visited = new Set();
38
+ return collectLinksRecursive(markdownPath, visited, options, 0);
39
+ }
40
+ // ============================================================================
41
+ // Internal Implementation
42
+ // ============================================================================
43
+ /**
44
+ * Recursive link collection with depth tracking and cycle prevention.
45
+ *
46
+ * Depth semantics:
47
+ * - currentDepth starts at 0 for links found in the root SKILL.md
48
+ * - The depth check `currentDepth >= maxDepth` is applied to markdown links
49
+ * BEFORE recursing into them
50
+ * - Non-markdown assets bypass the depth check entirely
51
+ *
52
+ * @param markdownPath - Current markdown file being processed
53
+ * @param visited - Set of already-visited normalized paths (cycle prevention)
54
+ * @param options - Collection options
55
+ * @param currentDepth - Current depth in the link tree (0 = root's direct links)
56
+ * @returns Accumulated collection result
57
+ */
58
+ async function collectLinksRecursive(markdownPath, visited, options, currentDepth) {
59
+ const normalizedPath = resolve(markdownPath);
60
+ // Prevent infinite loops from circular references
61
+ if (visited.has(normalizedPath)) {
62
+ return { bundledFiles: [], excludedReferences: [], maxBundledDepth: 0 };
63
+ }
64
+ visited.add(normalizedPath);
65
+ // Parse the markdown file to extract links
66
+ const parseResult = await parseMarkdown(markdownPath);
67
+ // Resolve all local file links (both markdown and non-markdown)
68
+ const resolvedLinks = resolveLocalLinks(parseResult.links, markdownPath, options.packageRoot);
69
+ const bundledFilesSet = new Set();
70
+ const excludedReferences = [];
71
+ let maxBundledDepth = 0;
72
+ // Compile exclude patterns once for this invocation
73
+ const excludeMatchers = options.excludeRules.map((rule) => ({
74
+ rule,
75
+ isMatch: picomatch(rule.patterns),
76
+ }));
77
+ for (const link of resolvedLinks) {
78
+ // Step 0: Directory links are always excluded (directories are not valid bundle targets)
79
+ if (link.isDirectory) {
80
+ excludedReferences.push({
81
+ path: link.path,
82
+ bundled: false,
83
+ excludeReason: 'directory-target',
84
+ linkText: link.linkText,
85
+ linkHref: link.linkHref,
86
+ });
87
+ continue;
88
+ }
89
+ // Step 1: Check exclude rules (applies to ALL file types)
90
+ // Use packageRoot (when available) as the base for glob matching.
91
+ // skillRoot is dirname(SKILL.md) which may be deep inside the package;
92
+ // files outside it produce ../ prefixes that picomatch ** cannot match.
93
+ const matchBase = options.packageRoot ?? options.skillRoot;
94
+ const relativePath = toForwardSlash(relative(matchBase, link.path));
95
+ const matchedExclude = excludeMatchers.find((m) => m.isMatch(relativePath));
96
+ if (matchedExclude) {
97
+ // Excluded by pattern -- record as excluded reference
98
+ excludedReferences.push({
99
+ path: link.path,
100
+ bundled: false,
101
+ excludeReason: 'pattern-matched',
102
+ matchedRule: matchedExclude.rule,
103
+ linkText: link.linkText,
104
+ linkHref: link.linkHref,
105
+ });
106
+ continue;
107
+ }
108
+ // Step 2: Non-markdown assets are always bundled (no recursion, no depth contribution)
109
+ if (!link.isMarkdown) {
110
+ bundledFilesSet.add(link.path);
111
+ continue;
112
+ }
113
+ // Step 3: Markdown link -- check depth limit
114
+ if (currentDepth >= options.maxDepth) {
115
+ // Beyond depth limit -- record as excluded
116
+ excludedReferences.push({
117
+ path: link.path,
118
+ bundled: false,
119
+ excludeReason: 'depth-exceeded',
120
+ linkText: link.linkText,
121
+ linkHref: link.linkHref,
122
+ });
123
+ continue;
124
+ }
125
+ // Within depth -- bundle and recurse
126
+ bundledFilesSet.add(link.path);
127
+ const childResult = await collectLinksRecursive(link.path, visited, options, currentDepth + 1);
128
+ // Merge child results
129
+ for (const childFile of childResult.bundledFiles) {
130
+ bundledFilesSet.add(childFile);
131
+ }
132
+ excludedReferences.push(...childResult.excludedReferences);
133
+ // Track the deepest bundled depth
134
+ // The child was at currentDepth+1, so its maxBundledDepth is relative to the root
135
+ const childDepth = childResult.maxBundledDepth > 0
136
+ ? childResult.maxBundledDepth
137
+ : currentDepth + 1;
138
+ maxBundledDepth = Math.max(maxBundledDepth, childDepth);
139
+ }
140
+ return {
141
+ bundledFiles: [...bundledFilesSet],
142
+ excludedReferences,
143
+ maxBundledDepth,
144
+ };
145
+ }
146
+ /**
147
+ * Resolve all local file links from parsed markdown, returning both markdown
148
+ * and non-markdown targets.
149
+ *
150
+ * Filters to `local_file` type links, strips anchors, resolves relative paths,
151
+ * and checks file existence. Optionally enforces package boundary.
152
+ *
153
+ * @param links - Raw links from parseMarkdown result
154
+ * @param markdownPath - Path of the source markdown file (for relative resolution)
155
+ * @param packageRoot - Optional boundary for path enforcement
156
+ * @returns Array of resolved links with metadata
157
+ */
158
+ function resolveLocalLinks(links, markdownPath, packageRoot) {
159
+ const resolved = [];
160
+ for (const link of links) {
161
+ if (link.type !== 'local_file') {
162
+ continue;
163
+ }
164
+ // Strip anchor from href
165
+ const hrefWithoutAnchor = link.href.split('#')[0] ?? link.href;
166
+ if (hrefWithoutAnchor === '') {
167
+ continue;
168
+ }
169
+ // Resolve to absolute path
170
+ const resolvedPath = resolve(dirname(markdownPath), hrefWithoutAnchor);
171
+ // Check file existence
172
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path constructed from parsed markdown links
173
+ if (!existsSync(resolvedPath)) {
174
+ continue;
175
+ }
176
+ // Enforce package boundary if set
177
+ if (packageRoot) {
178
+ const rel = relative(packageRoot, resolvedPath);
179
+ if (rel.startsWith('..')) {
180
+ continue;
181
+ }
182
+ }
183
+ // Check if target is a directory (not a file)
184
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Path constructed from parsed markdown links
185
+ const stats = statSync(resolvedPath);
186
+ if (stats.isDirectory()) {
187
+ resolved.push({
188
+ path: resolvedPath,
189
+ isMarkdown: false,
190
+ isDirectory: true,
191
+ linkText: link.text ?? '',
192
+ linkHref: link.href,
193
+ });
194
+ continue;
195
+ }
196
+ const isMarkdown = resolvedPath.endsWith('.md');
197
+ resolved.push({
198
+ path: resolvedPath,
199
+ isMarkdown,
200
+ linkText: link.text ?? '',
201
+ linkHref: link.href,
202
+ });
203
+ }
204
+ return resolved;
205
+ }
206
+ //# sourceMappingURL=link-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-collector.js","sourceRoot":"","sources":["../src/link-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,SAAS,MAAM,WAAW,CAAC;AAwFlC,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,YAAoB,EACpB,OAA8B;IAE9B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,OAAO,qBAAqB,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;;;;;;;;;;;;;GAcG;AACH,KAAK,UAAU,qBAAqB,CAClC,YAAoB,EACpB,OAAoB,EACpB,OAA8B,EAC9B,YAAoB;IAEpB,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAE7C,kDAAkD;IAClD,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;IAC1E,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAE5B,2CAA2C;IAC3C,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;IAEtD,gEAAgE;IAChE,MAAM,aAAa,GAAG,iBAAiB,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE9F,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,MAAM,kBAAkB,GAAqB,EAAE,CAAC;IAChD,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,oDAAoD;IACpD,MAAM,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI;QACJ,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;KAClC,CAAC,CAAC,CAAC;IAEJ,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,yFAAyF;QACzF,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,kBAAkB,CAAC,IAAI,CAAC;gBACtB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,kBAAkB;gBACjC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,0DAA0D;QAC1D,kEAAkE;QAClE,uEAAuE;QACvE,yEAAyE;QACzE,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC;QAC3D,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACpE,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QAE5E,IAAI,cAAc,EAAE,CAAC;YACnB,sDAAsD;YACtD,kBAAkB,CAAC,IAAI,CAAC;gBACtB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,iBAAiB;gBAChC,WAAW,EAAE,cAAc,CAAC,IAAI;gBAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,uFAAuF;QACvF,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,6CAA6C;QAC7C,IAAI,YAAY,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrC,2CAA2C;YAC3C,kBAAkB,CAAC,IAAI,CAAC;gBACtB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,gBAAgB;gBAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,qCAAqC;QACrC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE/B,MAAM,WAAW,GAAG,MAAM,qBAAqB,CAC7C,IAAI,CAAC,IAAI,EACT,OAAO,EACP,OAAO,EACP,YAAY,GAAG,CAAC,CACjB,CAAC;QAEF,sBAAsB;QACtB,KAAK,MAAM,SAAS,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;YACjD,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;QACD,kBAAkB,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAE3D,kCAAkC;QAClC,kFAAkF;QAClF,MAAM,UAAU,GAAG,WAAW,CAAC,eAAe,GAAG,CAAC;YAChD,CAAC,CAAC,WAAW,CAAC,eAAe;YAC7B,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC;QACrB,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,YAAY,EAAE,CAAC,GAAG,eAAe,CAAC;QAClC,kBAAkB;QAClB,eAAe;KAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,iBAAiB,CACxB,KAAkG,EAClG,YAAoB,EACpB,WAAgC;IAEhC,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,yBAAyB;QACzB,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;QAC/D,IAAI,iBAAiB,KAAK,EAAE,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QAED,2BAA2B;QAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAC;QAEvE,uBAAuB;QACvB,kHAAkH;QAClH,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9B,SAAS;QACX,CAAC;QAED,kCAAkC;QAClC,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAChD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,SAAS;YACX,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,kHAAkH;QAClH,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QACrC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,YAAY;gBAClB,UAAU,EAAE,KAAK;gBACjB,WAAW,EAAE,IAAI;gBACjB,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;gBACzB,QAAQ,EAAE,IAAI,CAAC,IAAI;aACpB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEhD,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,YAAY;YAClB,UAAU;YACV,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;YACzB,QAAQ,EAAE,IAAI,CAAC,IAAI;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -7,11 +7,11 @@ export declare const ClaudePluginSchema: z.ZodObject<{
7
7
  name: z.ZodOptional<z.ZodString>;
8
8
  email: z.ZodOptional<z.ZodString>;
9
9
  }, "strip", z.ZodTypeAny, {
10
- name?: string | undefined;
11
10
  email?: string | undefined;
12
- }, {
13
11
  name?: string | undefined;
12
+ }, {
14
13
  email?: string | undefined;
14
+ name?: string | undefined;
15
15
  }>>;
16
16
  homepage: z.ZodOptional<z.ZodString>;
17
17
  repository: z.ZodOptional<z.ZodString>;
@@ -72,8 +72,8 @@ export declare const ClaudePluginSchema: z.ZodObject<{
72
72
  version?: string | undefined;
73
73
  license?: string | undefined;
74
74
  author?: {
75
- name?: string | undefined;
76
75
  email?: string | undefined;
76
+ name?: string | undefined;
77
77
  } | undefined;
78
78
  skills?: {
79
79
  path: string;
@@ -105,8 +105,8 @@ export declare const ClaudePluginSchema: z.ZodObject<{
105
105
  version?: string | undefined;
106
106
  license?: string | undefined;
107
107
  author?: {
108
- name?: string | undefined;
109
108
  email?: string | undefined;
109
+ name?: string | undefined;
110
110
  } | undefined;
111
111
  skills?: {
112
112
  path: string;
@@ -11,6 +11,10 @@
11
11
  * - npm: Standard npm package with package.json
12
12
  * - marketplace: JSON manifest for plugin registries
13
13
  */
14
+ /**
15
+ * Resource naming strategy type
16
+ */
17
+ export type ResourceNamingStrategy = 'basename' | 'resource-id' | 'preserve-path';
14
18
  export interface PackageSkillOptions {
15
19
  /**
16
20
  * Output directory for packaged skill
@@ -32,6 +36,46 @@ export interface PackageSkillOptions {
32
36
  * Default: dirname(skillPath)
33
37
  */
34
38
  basePath?: string;
39
+ /**
40
+ * Strategy for naming packaged resource files
41
+ *
42
+ * - 'basename': Use original filename only (default, may cause conflicts)
43
+ * - 'resource-id': Flatten path to kebab-case filename (descriptive, unique)
44
+ * - 'preserve-path': Preserve directory structure in output
45
+ *
46
+ * Default: 'basename'
47
+ *
48
+ * @example
49
+ * // Original: knowledge-base/guides/topics/quickstart/overview.md
50
+ * // basename: overview.md (may conflict)
51
+ * // resource-id: guides-topics-quickstart-overview.md (with stripPrefix: 'knowledge-base-')
52
+ * // preserve-path: guides/topics/quickstart/overview.md (creates subdirectories)
53
+ */
54
+ resourceNaming?: ResourceNamingStrategy;
55
+ /**
56
+ * Path prefix to strip before applying naming strategy
57
+ *
58
+ * Removes a directory prefix from the relative path before the naming strategy is applied.
59
+ * Works with both 'resource-id' and 'preserve-path' strategies.
60
+ *
61
+ * @example
62
+ * // Original: knowledge-base/guides/topics/quickstart/overview.md
63
+ * // stripPrefix: 'knowledge-base'
64
+ * //
65
+ * // resource-id: guides-topics-quickstart-overview.md
66
+ * // preserve-path: guides/topics/quickstart/overview.md
67
+ */
68
+ stripPrefix?: string;
69
+ /** How deep to follow markdown links (default: 2) */
70
+ linkFollowDepth?: number | 'full' | undefined;
71
+ /** Exclude patterns and rewrite templates for non-bundled links */
72
+ excludeReferencesFromBundle?: {
73
+ rules?: Array<{
74
+ patterns: string[];
75
+ template?: string | undefined;
76
+ }> | undefined;
77
+ defaultTemplate?: string | undefined;
78
+ } | undefined;
35
79
  }
36
80
  export interface SkillMetadata {
37
81
  name: string;
@@ -65,6 +109,8 @@ export interface PackageSkillResult {
65
109
  npm?: string;
66
110
  marketplace?: string;
67
111
  };
112
+ /** References excluded from bundle */
113
+ excludedReferences?: string[] | undefined;
68
114
  }
69
115
  /**
70
116
  * Package a skill with all its dependencies
@@ -1 +1 @@
1
- {"version":3,"file":"skill-packager.d.ts","sourceRoot":"","sources":["../src/skill-packager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,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;CACnB;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;CACH;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA4D7B;AAkDD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASlE"}
1
+ {"version":3,"file":"skill-packager.d.ts","sourceRoot":"","sources":["../src/skill-packager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAgBH;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,aAAa,GAAG,eAAe,CAAC;AAElF,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,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;CACf;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;CAC3C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAmG7B;AAkDD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASlE"}