@skillit/core 1.5.0

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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +55 -0
  3. package/dist/audit-formatter.d.ts +36 -0
  4. package/dist/audit-formatter.d.ts.map +1 -0
  5. package/dist/audit-formatter.js +173 -0
  6. package/dist/audit-formatter.js.map +1 -0
  7. package/dist/audit-score.d.ts +76 -0
  8. package/dist/audit-score.d.ts.map +1 -0
  9. package/dist/audit-score.js +490 -0
  10. package/dist/audit-score.js.map +1 -0
  11. package/dist/audit-types.d.ts +81 -0
  12. package/dist/audit-types.d.ts.map +1 -0
  13. package/dist/audit-types.js +2 -0
  14. package/dist/audit-types.js.map +1 -0
  15. package/dist/audit.d.ts +17 -0
  16. package/dist/audit.d.ts.map +1 -0
  17. package/dist/audit.js +567 -0
  18. package/dist/audit.js.map +1 -0
  19. package/dist/canonical.d.ts +36 -0
  20. package/dist/canonical.d.ts.map +1 -0
  21. package/dist/canonical.js +148 -0
  22. package/dist/canonical.js.map +1 -0
  23. package/dist/config-renderer.d.ts +16 -0
  24. package/dist/config-renderer.d.ts.map +1 -0
  25. package/dist/config-renderer.js +296 -0
  26. package/dist/config-renderer.js.map +1 -0
  27. package/dist/config-types.d.ts +144 -0
  28. package/dist/config-types.d.ts.map +1 -0
  29. package/dist/config-types.js +2 -0
  30. package/dist/config-types.js.map +1 -0
  31. package/dist/docs-scanner.d.ts +40 -0
  32. package/dist/docs-scanner.d.ts.map +1 -0
  33. package/dist/docs-scanner.js +176 -0
  34. package/dist/docs-scanner.js.map +1 -0
  35. package/dist/examples-scanner.d.ts +39 -0
  36. package/dist/examples-scanner.d.ts.map +1 -0
  37. package/dist/examples-scanner.js +221 -0
  38. package/dist/examples-scanner.js.map +1 -0
  39. package/dist/index.d.ts +40 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +31 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/llms-txt.d.ts +20 -0
  44. package/dist/llms-txt.d.ts.map +1 -0
  45. package/dist/llms-txt.js +187 -0
  46. package/dist/llms-txt.js.map +1 -0
  47. package/dist/markdown-parser.d.ts +11 -0
  48. package/dist/markdown-parser.d.ts.map +1 -0
  49. package/dist/markdown-parser.js +222 -0
  50. package/dist/markdown-parser.js.map +1 -0
  51. package/dist/markdown-types.d.ts +48 -0
  52. package/dist/markdown-types.d.ts.map +1 -0
  53. package/dist/markdown-types.js +2 -0
  54. package/dist/markdown-types.js.map +1 -0
  55. package/dist/readme-parser.d.ts +21 -0
  56. package/dist/readme-parser.d.ts.map +1 -0
  57. package/dist/readme-parser.js +137 -0
  58. package/dist/readme-parser.js.map +1 -0
  59. package/dist/references-mcp.d.ts +79 -0
  60. package/dist/references-mcp.d.ts.map +1 -0
  61. package/dist/references-mcp.js +130 -0
  62. package/dist/references-mcp.js.map +1 -0
  63. package/dist/refine/ast-edit.d.ts +21 -0
  64. package/dist/refine/ast-edit.d.ts.map +1 -0
  65. package/dist/refine/ast-edit.js +147 -0
  66. package/dist/refine/ast-edit.js.map +1 -0
  67. package/dist/refine/index.d.ts +7 -0
  68. package/dist/refine/index.d.ts.map +1 -0
  69. package/dist/refine/index.js +6 -0
  70. package/dist/refine/index.js.map +1 -0
  71. package/dist/refine/jsdoc-edit.d.ts +4 -0
  72. package/dist/refine/jsdoc-edit.d.ts.map +1 -0
  73. package/dist/refine/jsdoc-edit.js +6 -0
  74. package/dist/refine/jsdoc-edit.js.map +1 -0
  75. package/dist/refine/loop.d.ts +8 -0
  76. package/dist/refine/loop.d.ts.map +1 -0
  77. package/dist/refine/loop.js +98 -0
  78. package/dist/refine/loop.js.map +1 -0
  79. package/dist/refine/select-targets.d.ts +5 -0
  80. package/dist/refine/select-targets.d.ts.map +1 -0
  81. package/dist/refine/select-targets.js +30 -0
  82. package/dist/refine/select-targets.js.map +1 -0
  83. package/dist/refine/types.d.ts +67 -0
  84. package/dist/refine/types.d.ts.map +1 -0
  85. package/dist/refine/types.js +2 -0
  86. package/dist/refine/types.js.map +1 -0
  87. package/dist/renderer.d.ts +27 -0
  88. package/dist/renderer.d.ts.map +1 -0
  89. package/dist/renderer.js +1244 -0
  90. package/dist/renderer.js.map +1 -0
  91. package/dist/tokens.d.ts +14 -0
  92. package/dist/tokens.d.ts.map +1 -0
  93. package/dist/tokens.js +26 -0
  94. package/dist/tokens.js.map +1 -0
  95. package/dist/types.d.ts +519 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.js +2 -0
  98. package/dist/types.js.map +1 -0
  99. package/dist/writer.d.ts +17 -0
  100. package/dist/writer.d.ts.map +1 -0
  101. package/dist/writer.js +313 -0
  102. package/dist/writer.js.map +1 -0
  103. package/package.json +54 -0
package/dist/audit.js ADDED
@@ -0,0 +1,567 @@
1
+ const GENERIC_KEYWORDS = new Set([
2
+ 'typescript',
3
+ 'javascript',
4
+ 'node',
5
+ 'nodejs',
6
+ 'npm',
7
+ 'library',
8
+ 'package',
9
+ 'utils',
10
+ 'utility',
11
+ 'helper',
12
+ 'tool',
13
+ 'framework'
14
+ ]);
15
+ function issue(severity, code, file, line, symbol, message, suggestion) {
16
+ return { severity, code, file, line, symbol, message, suggestion };
17
+ }
18
+ function pass(code, message, detail) {
19
+ return { code, message, detail };
20
+ }
21
+ // ---------------------------------------------------------------------------
22
+ // F1: package.json description must exist and be >10 chars
23
+ // ---------------------------------------------------------------------------
24
+ function checkF1(context, issues, passing) {
25
+ const desc = context.packageDescription?.trim() ?? '';
26
+ if (!desc || desc.length <= 10) {
27
+ issues.push(issue('fatal', 'F1', 'package.json', null, 'description', desc
28
+ ? `package.json description is too short (${desc.length} chars, needs >10)`
29
+ : 'package.json description is missing', 'Add to package.json: "description": "[One sentence: what problem this library solves for the caller]"'));
30
+ }
31
+ else {
32
+ passing.push(pass('F1', 'package.json description exists and is meaningful', desc));
33
+ }
34
+ }
35
+ // ---------------------------------------------------------------------------
36
+ // F2: keywords — 5+ entries, at least 3 non-generic
37
+ // ---------------------------------------------------------------------------
38
+ function checkF2(context, issues, passing) {
39
+ const keywords = context.keywords ?? [];
40
+ const domainKeywords = keywords.filter((k) => !GENERIC_KEYWORDS.has(k.toLowerCase()));
41
+ if (keywords.length < 5 || domainKeywords.length < 3) {
42
+ issues.push(issue('fatal', 'F2', 'package.json', null, 'keywords', keywords.length < 5
43
+ ? `Only ${keywords.length} keyword(s) found (need ≥5)`
44
+ : `Only ${domainKeywords.length} domain-specific keyword(s) (need ≥3 non-generic)`, 'Add to package.json: "keywords": ["[domain-verb]", "[domain-noun]", "[use-case]", "[integration]", "[pattern]"]'));
45
+ }
46
+ else {
47
+ passing.push(pass('F2', 'Keywords meet requirements', `${keywords.length} total, ${domainKeywords.length} domain-specific`));
48
+ }
49
+ }
50
+ // ---------------------------------------------------------------------------
51
+ // F3: README description — blockquote or firstParagraph must exist, >20 chars
52
+ // ---------------------------------------------------------------------------
53
+ function checkF3(context, issues, passing) {
54
+ const readme = context.readme;
55
+ const text = (readme?.blockquote?.trim() ?? '') || (readme?.firstParagraph?.trim() ?? '');
56
+ if (!text || text.length <= 20) {
57
+ issues.push(issue('fatal', 'F3', 'README.md', null, 'description', text
58
+ ? `README description is too short (${text.length} chars, needs >20)`
59
+ : 'README is missing a description (blockquote or first paragraph)', 'Add after title: > [One sentence: what this library does and why someone would use it]'));
60
+ }
61
+ else {
62
+ passing.push(pass('F3', 'README description exists and is meaningful', text.slice(0, 60)));
63
+ }
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // F4: JSDoc on exports — every function/class/type/enum/variable must have non-empty description
67
+ // ---------------------------------------------------------------------------
68
+ function checkF4(skill, issues, passing) {
69
+ let allGood = true;
70
+ for (const fn of skill.functions) {
71
+ if (!fn.description?.trim()) {
72
+ allGood = false;
73
+ issues.push(issue('fatal', 'F4', `${fn.sourceModule ?? skill.name}.ts`, null, fn.name, `Function '${fn.name}' is missing a JSDoc description`, `Add: /** [One sentence: what problem ${fn.name} solves for the caller] */`));
74
+ }
75
+ }
76
+ for (const cls of skill.classes) {
77
+ if (!cls.description?.trim()) {
78
+ allGood = false;
79
+ issues.push(issue('fatal', 'F4', `${cls.sourceModule ?? skill.name}.ts`, null, cls.name, `Class '${cls.name}' is missing a JSDoc description`, `Add: /** [One sentence: what problem ${cls.name} solves for the caller] */`));
80
+ }
81
+ }
82
+ for (const typ of skill.types) {
83
+ if (!typ.description?.trim()) {
84
+ allGood = false;
85
+ issues.push(issue('fatal', 'F4', `${typ.sourceModule ?? skill.name}.ts`, null, typ.name, `Type '${typ.name}' is missing a JSDoc description`, `Add: /** [One sentence: what problem ${typ.name} solves for the caller] */`));
86
+ }
87
+ }
88
+ for (const enm of skill.enums) {
89
+ if (!enm.description?.trim()) {
90
+ allGood = false;
91
+ issues.push(issue('fatal', 'F4', `${enm.sourceModule ?? skill.name}.ts`, null, enm.name, `Enum '${enm.name}' is missing a JSDoc description`, `Add: /** [One sentence: what problem ${enm.name} solves for the caller] */`));
92
+ }
93
+ }
94
+ for (const variable of skill.variables) {
95
+ if (!variable.description?.trim()) {
96
+ allGood = false;
97
+ issues.push(issue('fatal', 'F4', `${variable.sourceModule ?? skill.name}.ts`, null, variable.name, `Variable '${variable.name}' is missing a JSDoc description`, `Add: /** [One sentence: what problem ${variable.name} solves for the caller] */`));
98
+ }
99
+ }
100
+ if (allGood) {
101
+ passing.push(pass('F4', 'All exported symbols have JSDoc descriptions'));
102
+ }
103
+ }
104
+ // ---------------------------------------------------------------------------
105
+ // E1: @param prose — every parameter must have non-empty description
106
+ // that doesn't trivially restate the name or type
107
+ // ---------------------------------------------------------------------------
108
+ function isTrivialParamDesc(desc, paramName) {
109
+ // "The options" for param named "options" — but only check if description IS non-empty
110
+ const normalized = desc
111
+ .trim()
112
+ .toLowerCase()
113
+ .replace(/^the\s+/, '');
114
+ return normalized === paramName.toLowerCase();
115
+ }
116
+ /** Check if a parameter is self-documenting from its name + type */
117
+ function isSelfDocumenting(name, type) {
118
+ const lowerName = name.toLowerCase();
119
+ const lowerType = type.toLowerCase().replace(/[<>[\]|&? ]/g, '');
120
+ // Name matches or contains the type name: texture: Texture, renderer: Renderer
121
+ if (lowerType &&
122
+ lowerName.includes(lowerType.replace(/partial|readonly|array/gi, '').toLowerCase()))
123
+ return true;
124
+ if (lowerType && lowerType.includes(lowerName))
125
+ return true;
126
+ // Well-known options/config pattern: options: SpriteOptions, config: AppConfig
127
+ if (/^(options|config|settings|props|params|args)$/i.test(name) &&
128
+ /options|config|settings|props/i.test(type))
129
+ return true;
130
+ // Common positional/dimensional names with numeric types
131
+ if (/^(x|y|z|w|h|width|height|depth|index|count|length|size|offset|start|end|min|max|top|left|right|bottom|radius|angle|alpha|scale|rotation|delta|time|duration|delay|speed|priority)$/i.test(name) &&
132
+ /number|float|int/i.test(type))
133
+ return true;
134
+ // Boolean flags where name implies meaning: visible, enabled, active, force
135
+ if (/boolean/i.test(type) &&
136
+ /^(is|has|can|should|will|force|enable|disable|visible|active|readonly|optional|required|recursive|deep|strict|lazy|async|sync|auto|skip|include|exclude)/.test(lowerName))
137
+ return true;
138
+ // Callback/handler pattern: callback: () => void, handler: EventHandler
139
+ if (/^(callback|handler|listener|fn|func|predicate|comparator|reducer|mapper|filter|resolver|reject|resolve)$/i.test(name))
140
+ return true;
141
+ return false;
142
+ }
143
+ function checkE1(skill, issues, passing) {
144
+ let allGood = true;
145
+ const checkParams = (fnName, sourceModule, params) => {
146
+ for (const param of params) {
147
+ if (!param.description?.trim() && !isSelfDocumenting(param.name, param.type)) {
148
+ allGood = false;
149
+ issues.push(issue('error', 'E1', `${sourceModule ?? skill.name}.ts`, null, `${fnName}#${param.name}`, `Parameter '${param.name}' in '${fnName}' is missing a description`, `Add: @param ${param.name} — [What the caller controls with this parameter — not the type, but the effect]`));
150
+ }
151
+ }
152
+ };
153
+ for (const fn of skill.functions) {
154
+ checkParams(fn.name, fn.sourceModule, fn.parameters);
155
+ }
156
+ for (const cls of skill.classes) {
157
+ for (const method of cls.methods) {
158
+ checkParams(`${cls.name}.${method.name}`, cls.sourceModule, method.parameters);
159
+ }
160
+ }
161
+ if (allGood) {
162
+ passing.push(pass('E1', 'All parameters have prose descriptions'));
163
+ }
164
+ }
165
+ // ---------------------------------------------------------------------------
166
+ // E2: @returns — every function where returnType !== 'void' must have returnsDescription
167
+ // ---------------------------------------------------------------------------
168
+ function checkE2(skill, issues, passing) {
169
+ let allGood = true;
170
+ const checkFn = (fn, context, sourceModule) => {
171
+ if (fn.returnType && fn.returnType !== 'void' && !fn.returnsDescription?.trim()) {
172
+ // Skip self-documenting returns: type matches function name, boolean predicates, this-returns
173
+ const rt = fn.returnType.toLowerCase();
174
+ const fnName = fn.name.toLowerCase();
175
+ const isSelfDoc = rt.includes(fnName) ||
176
+ fnName.includes(rt.replace(/[[\]<>|& ?]/g, '')) ||
177
+ (rt === 'boolean' &&
178
+ /^(is|has|can|should|contains|includes|equals|matches)/.test(fnName)) ||
179
+ rt === 'this' ||
180
+ rt === 'promise<void>';
181
+ if (isSelfDoc)
182
+ return;
183
+ allGood = false;
184
+ issues.push(issue('error', 'E2', `${sourceModule ?? skill.name}.ts`, null, context, `'${context}' returns '${fn.returnType}' but has no @returns description`, 'Add: @returns [What the caller gets back and what they do with it]'));
185
+ }
186
+ };
187
+ for (const fn of skill.functions) {
188
+ checkFn(fn, fn.name, fn.sourceModule);
189
+ }
190
+ for (const cls of skill.classes) {
191
+ for (const method of cls.methods) {
192
+ checkFn(method, `${cls.name}.${method.name}`, cls.sourceModule);
193
+ }
194
+ }
195
+ if (allGood) {
196
+ passing.push(pass('E2', 'All non-void functions have @returns descriptions'));
197
+ }
198
+ }
199
+ // ---------------------------------------------------------------------------
200
+ // E3: Interface property JSDoc — every property in types[].properties must have description
201
+ // ---------------------------------------------------------------------------
202
+ function checkE3(skill, issues, passing) {
203
+ let allGood = true;
204
+ for (const typ of skill.types) {
205
+ if (!typ.properties)
206
+ continue;
207
+ for (const prop of typ.properties) {
208
+ if (!prop.description?.trim()) {
209
+ allGood = false;
210
+ issues.push(issue('error', 'E3', `${typ.sourceModule ?? skill.name}.ts`, null, `${typ.name}.${prop.name}`, `Property '${prop.name}' in type '${typ.name}' is missing a JSDoc description`, 'Add: /** [What this property controls — one phrase] */'));
211
+ }
212
+ }
213
+ }
214
+ if (allGood) {
215
+ passing.push(pass('E3', 'All interface/type properties have JSDoc descriptions'));
216
+ }
217
+ }
218
+ // ---------------------------------------------------------------------------
219
+ // E4: @example exists — skill.examples.length > 0 OR any function has examples
220
+ // ---------------------------------------------------------------------------
221
+ function checkE4(skill, issues, passing) {
222
+ const hasSkillExamples = skill.examples.length > 0;
223
+ const hasFunctionExamples = skill.functions.some((fn) => fn.examples.length > 0);
224
+ if (!hasSkillExamples && !hasFunctionExamples) {
225
+ issues.push(issue('error', 'E4', `${skill.name}.ts`, null, skill.name, 'No @example tags found anywhere in the package', 'Add @example with: import statement, setup, call, assertion/output'));
226
+ }
227
+ else {
228
+ passing.push(pass('E4', 'At least one @example exists in the package'));
229
+ }
230
+ }
231
+ // ---------------------------------------------------------------------------
232
+ // E5: Repository — context.repository must be non-empty
233
+ // ---------------------------------------------------------------------------
234
+ function checkE5(context, issues, passing) {
235
+ if (!context.repository?.trim()) {
236
+ issues.push(issue('error', 'E5', 'package.json', null, 'repository', 'package.json is missing a repository URL', 'Add to package.json: "repository": { "type": "git", "url": "[repo-url]" }'));
237
+ }
238
+ else {
239
+ passing.push(pass('E5', 'Repository URL is present', context.repository));
240
+ }
241
+ }
242
+ // ---------------------------------------------------------------------------
243
+ // W1: @packageDocumentation — skill.description must be >50 chars
244
+ // ---------------------------------------------------------------------------
245
+ function checkW1(skill, issues, passing) {
246
+ const desc = skill.description?.trim() ?? '';
247
+ if (desc.length <= 50) {
248
+ issues.push(issue('warning', 'W1', `${skill.name}.ts`, null, skill.name, desc
249
+ ? `Module-level description is too short (${desc.length} chars, needs >50)`
250
+ : 'Module-level @packageDocumentation JSDoc is missing', 'Add a /** @packageDocumentation */ comment with a detailed description (>50 chars)'));
251
+ }
252
+ else {
253
+ passing.push(pass('W1', 'Module-level description is sufficiently detailed', `${desc.length} chars`));
254
+ }
255
+ }
256
+ // ---------------------------------------------------------------------------
257
+ // W2: Per-function @example — every function should have examples
258
+ // ---------------------------------------------------------------------------
259
+ function checkW2(skill, issues, passing) {
260
+ let allGood = true;
261
+ for (const fn of skill.functions) {
262
+ if (fn.examples.length === 0) {
263
+ allGood = false;
264
+ issues.push(issue('warning', 'W2', `${fn.sourceModule ?? skill.name}.ts`, null, fn.name, `Function '${fn.name}' has no @example`, `Add an @example code block to the JSDoc for '${fn.name}'`));
265
+ }
266
+ }
267
+ if (allGood) {
268
+ passing.push(pass('W2', 'Every function has at least one @example'));
269
+ }
270
+ }
271
+ // ---------------------------------------------------------------------------
272
+ // W3: Tag usage — at least one function should have a non-empty value in tags
273
+ // ---------------------------------------------------------------------------
274
+ const NOTABLE_TAGS = new Set(['deprecated', 'since', 'throws', 'see']);
275
+ function checkW3(skill, issues, passing) {
276
+ const hasTaggedFn = skill.functions.some((fn) => Object.entries(fn.tags).some(([key, val]) => NOTABLE_TAGS.has(key) && val.trim()));
277
+ if (!hasTaggedFn) {
278
+ issues.push(issue('warning', 'W3', `${skill.name}.ts`, null, skill.name, 'No functions use @deprecated, @since, @throws, or @see tags', 'Add relevant JSDoc tags to document version info, deprecations, errors thrown, or related links'));
279
+ }
280
+ else {
281
+ passing.push(pass('W3', 'At least one function uses notable JSDoc tags'));
282
+ }
283
+ }
284
+ // ---------------------------------------------------------------------------
285
+ // W4: 10+ keywords — domain-specific keyword count >= 10
286
+ // ---------------------------------------------------------------------------
287
+ function checkW4(context, issues, passing) {
288
+ const keywords = context.keywords ?? [];
289
+ const domainKeywords = keywords.filter((k) => !GENERIC_KEYWORDS.has(k.toLowerCase()));
290
+ if (domainKeywords.length < 10) {
291
+ issues.push(issue('warning', 'W4', 'package.json', null, 'keywords', `Only ${domainKeywords.length} domain-specific keyword(s) (recommended ≥10 for discoverability)`, 'Add more domain-specific keywords to improve discoverability'));
292
+ }
293
+ else {
294
+ passing.push(pass('W4', 'Excellent keyword coverage', `${domainKeywords.length} domain-specific keywords`));
295
+ }
296
+ }
297
+ // ---------------------------------------------------------------------------
298
+ // W5: README Features — context.readme?.features must exist
299
+ // ---------------------------------------------------------------------------
300
+ function checkW5(context, skill, issues, passing) {
301
+ if (!context.readme?.features?.trim()) {
302
+ const hasRemarks = !!skill.remarks;
303
+ issues.push(issue('warning', 'W5', hasRemarks ? `${skill.name}.ts` : 'README.md', null, 'features', 'README is missing a Features section', hasRemarks
304
+ ? 'README ## Features is a secondary source — already have @packageDocumentation @remarks as primary'
305
+ : 'Add "## Features" to README.md, or add @packageDocumentation @remarks with capabilities overview (primary source, takes priority)'));
306
+ }
307
+ else {
308
+ passing.push(pass('W5', 'README has a Features section'));
309
+ }
310
+ }
311
+ // ---------------------------------------------------------------------------
312
+ // W6: README Troubleshooting — context.readme?.troubleshooting must exist
313
+ // ---------------------------------------------------------------------------
314
+ function checkW6(context, skill, issues, passing) {
315
+ if (!context.readme?.troubleshooting?.trim()) {
316
+ const hasNever = (skill.pitfalls ?? []).length > 0;
317
+ issues.push(issue('warning', 'W6', hasNever ? `${skill.name}.ts` : 'README.md', null, 'troubleshooting', 'README is missing a Troubleshooting section', hasNever
318
+ ? 'README ## Troubleshooting is a secondary source — already have @never tags as primary anti-patterns'
319
+ : 'Add "## Troubleshooting" to README.md, or add @never tags to key exports with NEVER + Fix patterns (primary source)'));
320
+ }
321
+ else {
322
+ passing.push(pass('W6', 'README has a Troubleshooting section'));
323
+ }
324
+ }
325
+ // ---------------------------------------------------------------------------
326
+ // Routing-tag credit: @useWhen/@avoidWhen/@never may live at the top level
327
+ // (MCP/TypeDoc skills) OR on a CLI configSurface (CLI skills correlate them onto
328
+ // `configSurfaces[].useWhen` etc.). Credit guidance found in either place.
329
+ // ---------------------------------------------------------------------------
330
+ function hasRoutingTag(skill, tag) {
331
+ if ((skill[tag] ?? []).length > 0)
332
+ return true;
333
+ return (skill.configSurfaces ?? []).some((surface) => (surface[tag] ?? []).length > 0);
334
+ }
335
+ // ---------------------------------------------------------------------------
336
+ // W7: @useWhen on at least one export
337
+ // ---------------------------------------------------------------------------
338
+ function checkW7(skill, issues, passing) {
339
+ const hasUseWhen = hasRoutingTag(skill, 'useWhen');
340
+ if (!hasUseWhen) {
341
+ issues.push(issue('warning', 'W7', `${skill.name}.ts`, null, skill.name, 'No exports have a @useWhen tag', 'Add @useWhen to 3-5 key exports: @useWhen - [Scenario where the caller should reach for this — include non-obvious expert knowledge]'));
342
+ }
343
+ else {
344
+ passing.push(pass('W7', 'At least one export has a @useWhen tag'));
345
+ }
346
+ }
347
+ // ---------------------------------------------------------------------------
348
+ // W8: @avoidWhen on at least one export
349
+ // ---------------------------------------------------------------------------
350
+ function checkW8(skill, issues, passing) {
351
+ const hasAvoidWhen = hasRoutingTag(skill, 'avoidWhen');
352
+ if (!hasAvoidWhen) {
353
+ issues.push(issue('warning', 'W8', `${skill.name}.ts`, null, skill.name, 'No exports have an @avoidWhen tag', 'Add @avoidWhen: @avoidWhen - [When NOT to use this — name the alternative]'));
354
+ }
355
+ else {
356
+ passing.push(pass('W8', 'At least one export has an @avoidWhen tag'));
357
+ }
358
+ }
359
+ // ---------------------------------------------------------------------------
360
+ // W9: @never on at least one export
361
+ // ---------------------------------------------------------------------------
362
+ function checkW9(skill, issues, passing) {
363
+ const hasPitfalls = hasRoutingTag(skill, 'pitfalls');
364
+ if (!hasPitfalls) {
365
+ issues.push(issue('warning', 'W9', `${skill.name}.ts`, null, skill.name, 'No exports have a @never tag', 'Add @never: @never - NEVER [action] — [non-obvious reason]. Fix: [recovery path]'));
366
+ }
367
+ else {
368
+ passing.push(pass('W9', 'At least one export has a @never tag'));
369
+ }
370
+ }
371
+ // ---------------------------------------------------------------------------
372
+ // W10: @remarks on complex functions — functions with 3+ params should have @remarks
373
+ // ---------------------------------------------------------------------------
374
+ function checkW10(skill, issues, passing) {
375
+ let allGood = true;
376
+ for (const fn of skill.functions) {
377
+ if (fn.parameters.length >= 3 && !fn.remarks?.trim()) {
378
+ allGood = false;
379
+ issues.push(issue('warning', 'W10', `${fn.sourceModule ?? skill.name}.ts`, null, fn.name, `Function '${fn.name}' has ${fn.parameters.length} parameters but no @remarks`, `Add @remarks to '${fn.name}' to explain parameter interactions and usage nuances`));
380
+ }
381
+ }
382
+ if (allGood) {
383
+ passing.push(pass('W10', 'All complex functions (3+ params) have @remarks'));
384
+ }
385
+ }
386
+ // ---------------------------------------------------------------------------
387
+ // W11: @category for intentional grouping — at least one export should have @category
388
+ // ---------------------------------------------------------------------------
389
+ function checkW11(skill, issues, passing) {
390
+ const hasCategory = skill.functions.some((fn) => fn.category?.trim()) ||
391
+ skill.classes.some((cls) => cls.category?.trim()) ||
392
+ skill.types.some((typ) => typ.category?.trim()) ||
393
+ skill.enums.some((enm) => enm.category?.trim()) ||
394
+ skill.variables.some((v) => v.category?.trim());
395
+ if (!hasCategory) {
396
+ issues.push(issue('warning', 'W11', `${skill.name}.ts`, null, skill.name, 'No exports have a @category tag', 'Add @category <group> to exported symbols to enable intentional grouping in documentation'));
397
+ }
398
+ else {
399
+ passing.push(pass('W11', 'At least one export has a @category tag'));
400
+ }
401
+ }
402
+ // ---------------------------------------------------------------------------
403
+ // A1: Generic keywords — for each generic keyword present, emit alert
404
+ // ---------------------------------------------------------------------------
405
+ function checkA1(context, issues, passing) {
406
+ const keywords = context.keywords ?? [];
407
+ const genericFound = keywords.filter((k) => GENERIC_KEYWORDS.has(k.toLowerCase()));
408
+ for (const kw of genericFound) {
409
+ issues.push(issue('alert', 'A1', 'package.json', null, `keywords[${kw}]`, `Keyword '${kw}' is too generic and adds little discoverability value`, `Replace '${kw}' with a more specific, domain-relevant keyword`));
410
+ }
411
+ if (genericFound.length === 0) {
412
+ passing.push(pass('A1', 'No generic keywords found'));
413
+ }
414
+ }
415
+ // ---------------------------------------------------------------------------
416
+ // A2: @param restates type — description that is just "The {type}" or "The {name}"
417
+ // (only when description IS non-empty — E1 catches empty ones)
418
+ // ---------------------------------------------------------------------------
419
+ function checkA2(skill, issues, passing) {
420
+ let anyRestating = false;
421
+ const checkParams = (fnName, sourceModule, params) => {
422
+ for (const param of params) {
423
+ const desc = param.description?.trim();
424
+ if (!desc)
425
+ continue; // E1 handles empty — skip here
426
+ if (isTrivialParamDesc(desc, param.name)) {
427
+ anyRestating = true;
428
+ issues.push(issue('alert', 'A2', `${sourceModule ?? skill.name}.ts`, null, `${fnName}#${param.name}`, `Parameter '${param.name}' description trivially restates the name: "${desc}"`, `Replace the description with meaningful prose explaining the purpose of '${param.name}'`));
429
+ }
430
+ }
431
+ };
432
+ for (const fn of skill.functions) {
433
+ checkParams(fn.name, fn.sourceModule, fn.parameters);
434
+ }
435
+ for (const cls of skill.classes) {
436
+ for (const method of cls.methods) {
437
+ checkParams(`${cls.name}.${method.name}`, cls.sourceModule, method.parameters);
438
+ }
439
+ }
440
+ if (!anyRestating) {
441
+ passing.push(pass('A2', 'No parameters trivially restate their name'));
442
+ }
443
+ }
444
+ // ---------------------------------------------------------------------------
445
+ // A3: Trivial @example — example is a single line with no import, no assignment, no comment
446
+ // ---------------------------------------------------------------------------
447
+ function isTrivialExample(example) {
448
+ const lines = example
449
+ .trim()
450
+ .split('\n')
451
+ .filter((l) => l.trim());
452
+ if (lines.length !== 1)
453
+ return false;
454
+ const line = (lines[0] ?? '').trim();
455
+ if (line.startsWith('import ') || line.startsWith('//') || line.includes('='))
456
+ return false;
457
+ return true;
458
+ }
459
+ function checkA3(skill, issues, passing) {
460
+ let anyTrivial = false;
461
+ const checkExamples = (symbol, sourceModule, examples) => {
462
+ for (const ex of examples) {
463
+ if (isTrivialExample(ex)) {
464
+ anyTrivial = true;
465
+ issues.push(issue('alert', 'A3', `${sourceModule ?? skill.name}.ts`, null, symbol, `'${symbol}' has a trivial @example (single line, no import/assignment/comment)`, `Expand the example to show a realistic usage pattern with imports and context`));
466
+ }
467
+ }
468
+ };
469
+ for (const fn of skill.functions) {
470
+ checkExamples(fn.name, fn.sourceModule, fn.examples);
471
+ }
472
+ for (const ex of skill.examples) {
473
+ if (isTrivialExample(ex)) {
474
+ anyTrivial = true;
475
+ issues.push(issue('alert', 'A3', `${skill.name}.ts`, null, skill.name, `Package-level example is trivial (single line, no import/assignment/comment)`, `Expand the example to show a realistic usage pattern with imports and context`));
476
+ }
477
+ }
478
+ if (!anyTrivial) {
479
+ passing.push(pass('A3', 'All examples are non-trivial'));
480
+ }
481
+ }
482
+ // ---------------------------------------------------------------------------
483
+ // A4: Quick Start quality — recommend @example when README fallback is too long
484
+ // ---------------------------------------------------------------------------
485
+ function checkA4(context, skill, issues, passing) {
486
+ const quickStart = context.readme?.quickStart;
487
+ const hasCodeExample = skill.functions.some((f) => f.examples.length > 0);
488
+ // If README Quick Start is long and no @example exists, recommend the primary source
489
+ if (quickStart && !hasCodeExample) {
490
+ const quickStartLines = quickStart.split('\n').length;
491
+ if (quickStartLines > 20) {
492
+ issues.push(issue('warning', 'A4', `${skill.name}.ts`, null, 'quickStart', `README Quick Start is ${quickStartLines} lines — too long for inline SKILL.md rendering`, 'Add @example to a key exported function with a focused 5-10 line snippet. @example takes priority over README Quick Start and produces a leaner SKILL.md'));
493
+ return;
494
+ }
495
+ }
496
+ if (!quickStart) {
497
+ passing.push(pass('A4', 'No Quick Start section to check'));
498
+ return;
499
+ }
500
+ // Find code blocks and check their line counts
501
+ const codeBlockRegex = /```[\s\S]*?```/g;
502
+ const blocks = quickStart.match(codeBlockRegex) ?? [];
503
+ let anyVerbose = false;
504
+ for (const block of blocks) {
505
+ const lines = block.split('\n').length;
506
+ if (lines > 15) {
507
+ anyVerbose = true;
508
+ issues.push(issue('alert', 'A4', 'README.md', null, 'quickStart', `Quick Start code block is ${lines} lines (recommended ≤15)`, 'Add @example to a key export with a focused snippet — @example trumps README Quick Start'));
509
+ }
510
+ }
511
+ if (!anyVerbose) {
512
+ passing.push(pass('A4', 'Quick Start code blocks are concise'));
513
+ }
514
+ }
515
+ // ---------------------------------------------------------------------------
516
+ // Main entry point
517
+ // ---------------------------------------------------------------------------
518
+ /**
519
+ * Run the documentation audit on a single extracted skill.
520
+ *
521
+ * Executes 20+ checks across fatal/error/warning/alert severity levels and returns
522
+ * a structured result with issues, passing checks, and summary counts.
523
+ *
524
+ * @category Audit
525
+ * @useWhen
526
+ * - You want programmatic quality feedback on JSDoc coverage before publishing skills
527
+ * - Building a CI gate that blocks PRs with undocumented exports
528
+ * @avoidWhen
529
+ * - Rapid local iteration where audit noise slows you down — use the skillsAudit: false option instead
530
+ */
531
+ export function auditSkill(skill, context) {
532
+ const issues = [];
533
+ const passing = [];
534
+ // Fatal checks
535
+ checkF1(context, issues, passing);
536
+ checkF2(context, issues, passing);
537
+ checkF3(context, issues, passing);
538
+ checkF4(skill, issues, passing);
539
+ // Error checks
540
+ checkE1(skill, issues, passing);
541
+ checkE2(skill, issues, passing);
542
+ checkE3(skill, issues, passing);
543
+ checkE4(skill, issues, passing);
544
+ checkE5(context, issues, passing);
545
+ // Warning checks
546
+ checkW1(skill, issues, passing);
547
+ checkW2(skill, issues, passing);
548
+ checkW3(skill, issues, passing);
549
+ checkW4(context, issues, passing);
550
+ checkW5(context, skill, issues, passing);
551
+ checkW6(context, skill, issues, passing);
552
+ checkW7(skill, issues, passing);
553
+ checkW8(skill, issues, passing);
554
+ checkW9(skill, issues, passing);
555
+ checkW10(skill, issues, passing);
556
+ checkW11(skill, issues, passing);
557
+ // Alert checks
558
+ checkA1(context, issues, passing);
559
+ checkA2(skill, issues, passing);
560
+ checkA3(skill, issues, passing);
561
+ checkA4(context, skill, issues, passing);
562
+ const summary = { fatal: 0, error: 0, warning: 0, alert: 0 };
563
+ for (const iss of issues)
564
+ summary[iss.severity]++;
565
+ return { package: skill.name, summary, issues, passing };
566
+ }
567
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Canonicalization pass — deterministic post-render normalization.
3
+ *
4
+ * Operates on `RenderedSkill` (string content), NOT on the `ExtractedSkill` IR.
5
+ *
6
+ * Division of responsibility (see specs/001-mcp-extract-bundle/research.md §2):
7
+ * - Array ordering of tools/resources/prompts is the ADAPTER's job. Each
8
+ * adapter emits items in sorted order directly from the IR. We do NOT
9
+ * parse rendered markdown sections and reorder entries here — that would
10
+ * be the wrong layer.
11
+ * - This module handles the post-render invariants that any adapter's
12
+ * output should satisfy to be content-identical across runs:
13
+ * 1. YAML frontmatter key sort
14
+ * 2. Line endings normalized to LF
15
+ * 3. Trailing whitespace trimmed per line
16
+ * 4. Runs of 2+ blank lines collapsed to 1
17
+ * 5. Optional regex-based pattern stripping (e.g., timestamps)
18
+ *
19
+ * Must be idempotent: `canonicalize(canonicalize(x))` equals `canonicalize(x)`.
20
+ *
21
+ * @module canonical
22
+ */
23
+ import type { RenderedSkill } from './types.js';
24
+ export interface CanonicalizeOptions {
25
+ /** Regex patterns whose matches are stripped from prose content (e.g. timestamps, PIDs). */
26
+ stripPatterns?: RegExp[];
27
+ }
28
+ /**
29
+ * Normalize a `RenderedSkill` so repeat runs produce content-identical output.
30
+ *
31
+ * @param skill - rendered skill to normalize; input is not mutated
32
+ * @param opts - optional pattern list for stripping nondeterministic prose fragments
33
+ * @returns new `RenderedSkill` with canonicalized content
34
+ */
35
+ export declare function canonicalize(skill: RenderedSkill, opts?: CanonicalizeOptions): RenderedSkill;
36
+ //# sourceMappingURL=canonical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../src/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,mBAAmB;IAClC,4FAA4F;IAC5F,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,aAAa,CAK5F"}