@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
@@ -0,0 +1,137 @@
1
+ // Heading alias maps keyed by canonical field name
2
+ const QUICK_START_HEADINGS = new Set([
3
+ 'quick start',
4
+ 'usage',
5
+ 'getting started',
6
+ 'cli usage',
7
+ 'basic usage',
8
+ 'installation'
9
+ ]);
10
+ const FEATURES_HEADINGS = new Set(['features', 'key features', 'highlights']);
11
+ const TROUBLESHOOTING_HEADINGS = new Set([
12
+ 'troubleshooting',
13
+ 'common issues',
14
+ 'common errors',
15
+ 'faq'
16
+ ]);
17
+ /** Return true if the line is a `## level-2` heading. */
18
+ function isH2(line) {
19
+ return /^##\s/.test(line);
20
+ }
21
+ /** Return true if the line is any heading (`#`, `##`, ...). */
22
+ function isHeading(line) {
23
+ return /^#{1,6}\s/.test(line);
24
+ }
25
+ /** Extract the heading text (lowercased, no leading `## ` or emoji prefixes). */
26
+ function headingText(line) {
27
+ return line
28
+ .replace(/^#{1,6}\s+/, '')
29
+ .replace(/^[\p{Emoji_Presentation}\p{Extended_Pictographic}\uFE0F]+\s*/u, '')
30
+ .toLowerCase()
31
+ .trim();
32
+ }
33
+ /** Trim and return undefined when the result is empty. */
34
+ function nonEmpty(s) {
35
+ const t = s.trim();
36
+ return t.length > 0 ? t : undefined;
37
+ }
38
+ /**
39
+ * Parse a README markdown string and extract structured sections.
40
+ *
41
+ * Extraction rules:
42
+ * - **blockquote** – first `> …` line between `# title` and the first `## heading`.
43
+ * - **firstParagraph** – first prose lines before the first `## heading` that are
44
+ * not a heading, badge (`[![`), image (`![`), blockquote, or blank.
45
+ * Consecutive lines are joined with a single space.
46
+ * - **quickStart** – content under `## Quick Start`, `## Usage`, or `## Getting Started`.
47
+ * - **features** – content under `## Features`, `## Key Features`, or `## Highlights`.
48
+ * - **troubleshooting** – content under `## Troubleshooting`, `## Common Issues`, `## Common Errors`,
49
+ * or `## FAQ`.
50
+ *
51
+ * @category Parsing
52
+ * @useWhen
53
+ * - You need structured README sections for audit context or skill enrichment
54
+ * - The audit engine calls this to check for Features and Troubleshooting sections
55
+ */
56
+ export function parseReadme(markdown) {
57
+ if (!markdown.trim())
58
+ return {};
59
+ const lines = markdown.split('\n');
60
+ const result = {};
61
+ // ── Pass 1: collect preamble lines (before first ## heading) ──────────────
62
+ let preambleEnd = lines.length;
63
+ for (let i = 0; i < lines.length; i++) {
64
+ const li = lines[i] ?? '';
65
+ if (isH2(li)) {
66
+ preambleEnd = i;
67
+ break;
68
+ }
69
+ }
70
+ const preambleLines = lines.slice(0, preambleEnd);
71
+ // Extract blockquote from preamble (skip title line)
72
+ for (const line of preambleLines) {
73
+ if (isHeading(line))
74
+ continue; // skip the # title
75
+ if (line.startsWith('> ')) {
76
+ result.blockquote = line.slice(2).trim();
77
+ break;
78
+ }
79
+ }
80
+ // Extract first paragraph from preamble
81
+ const paraLines = [];
82
+ let inPara = false;
83
+ for (const line of preambleLines) {
84
+ if (isHeading(line))
85
+ continue; // skip headings (# title)
86
+ if (line.startsWith('> '))
87
+ continue; // skip blockquotes
88
+ if (line.startsWith('[!['))
89
+ continue; // skip badge lines
90
+ if (line.startsWith('!['))
91
+ continue; // skip image lines
92
+ const trimmed = line.trim();
93
+ if (trimmed === '') {
94
+ if (inPara)
95
+ break; // blank line ends paragraph
96
+ continue;
97
+ }
98
+ inPara = true;
99
+ paraLines.push(trimmed);
100
+ }
101
+ if (paraLines.length > 0) {
102
+ result.firstParagraph = paraLines.join(' ');
103
+ }
104
+ // ── Pass 2: collect named sections ────────────────────────────────────────
105
+ // Walk through H2 sections and capture content
106
+ let i = 0;
107
+ while (i < lines.length) {
108
+ const line = lines[i] ?? '';
109
+ if (isH2(line)) {
110
+ const text = headingText(line);
111
+ let field = null;
112
+ if (QUICK_START_HEADINGS.has(text))
113
+ field = 'quickStart';
114
+ else if (FEATURES_HEADINGS.has(text))
115
+ field = 'features';
116
+ else if (TROUBLESHOOTING_HEADINGS.has(text))
117
+ field = 'troubleshooting';
118
+ if (field !== null) {
119
+ // Collect lines until the next ## heading or EOF
120
+ const contentLines = [];
121
+ i++;
122
+ while (i < lines.length && !isH2(lines[i] ?? '')) {
123
+ contentLines.push(lines[i] ?? '');
124
+ i++;
125
+ }
126
+ const content = nonEmpty(contentLines.join('\n'));
127
+ if (content !== undefined) {
128
+ result[field] = content;
129
+ }
130
+ continue; // don't increment i again
131
+ }
132
+ }
133
+ i++;
134
+ }
135
+ return result;
136
+ }
137
+ //# sourceMappingURL=readme-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readme-parser.js","sourceRoot":"","sources":["../src/readme-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Shared reference-file emitters for MCP-exposed resources and prompts.
3
+ *
4
+ * @remarks
5
+ * Used by core's default render path AND by invocation adapters that delegate
6
+ * body rendering to core (e.g. `@skillit/target-mcp-protocol`'s `McpProtocolAdapter`).
7
+ * Centralizing the markdown shape here means every emitter — bundle and extract,
8
+ * MCP-protocol and CLI-as-proxy — produces identical resources/prompts files.
9
+ *
10
+ * Both functions return `null` when the input is empty so callers can write:
11
+ *
12
+ * ```ts
13
+ * const ref = renderResourcesReference(skill.resources ?? [], opts);
14
+ * if (ref) references.push(ref);
15
+ * ```
16
+ *
17
+ * @module references-mcp
18
+ */
19
+ import type { ExtractedResource, ExtractedPrompt, RenderedFile } from './types.js';
20
+ /** Options for the shared MCP reference emitters. */
21
+ export interface McpReferenceOptions {
22
+ /**
23
+ * Skill name (kebab-case directory) the file is rooted in. The emitter writes
24
+ * to `${skillName}/references/{resources,prompts}.md`.
25
+ */
26
+ skillName: string;
27
+ /** Token budget ceiling. Files exceeding this are truncated with a `<!-- truncated -->` marker. */
28
+ maxTokens: number;
29
+ }
30
+ /**
31
+ * Render the `references/resources.md` file for an MCP server's exposed resources.
32
+ *
33
+ * Output shape:
34
+ *
35
+ * ```markdown
36
+ * # Resources
37
+ *
38
+ * ## <resource.name>
39
+ *
40
+ * **URI**: `<resource.uri>`
41
+ * **MIME type**: `<resource.mimeType>` (omitted when undefined)
42
+ *
43
+ * <resource.description>
44
+ *
45
+ * ---
46
+ *
47
+ * ## <next resource>
48
+ * ```
49
+ *
50
+ * @returns A `RenderedFile` with token estimate, or `null` when `resources` is empty.
51
+ */
52
+ export declare function renderResourcesReference(resources: readonly ExtractedResource[], opts: McpReferenceOptions): RenderedFile | null;
53
+ /**
54
+ * Render the `references/prompts.md` file for an MCP server's exposed prompts.
55
+ *
56
+ * Output shape:
57
+ *
58
+ * ```markdown
59
+ * # Prompts
60
+ *
61
+ * ## <prompt.name>
62
+ *
63
+ * <prompt.description>
64
+ *
65
+ * | Argument | Required | Description |
66
+ * |----------|----------|-------------|
67
+ * | <name> | yes/no | <desc> |
68
+ *
69
+ * ---
70
+ *
71
+ * ## <next prompt>
72
+ * ```
73
+ *
74
+ * The argument table is omitted when `arguments` is empty.
75
+ *
76
+ * @returns A `RenderedFile` with token estimate, or `null` when `prompts` is empty.
77
+ */
78
+ export declare function renderPromptsReference(prompts: readonly ExtractedPrompt[], opts: McpReferenceOptions): RenderedFile | null;
79
+ //# sourceMappingURL=references-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"references-mcp.d.ts","sourceRoot":"","sources":["../src/references-mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGnF,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,mGAAmG;IACnG,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,SAAS,iBAAiB,EAAE,EACvC,IAAI,EAAE,mBAAmB,GACxB,YAAY,GAAG,IAAI,CA8BrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,IAAI,EAAE,mBAAmB,GACxB,YAAY,GAAG,IAAI,CAiCrB"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Shared reference-file emitters for MCP-exposed resources and prompts.
3
+ *
4
+ * @remarks
5
+ * Used by core's default render path AND by invocation adapters that delegate
6
+ * body rendering to core (e.g. `@skillit/target-mcp-protocol`'s `McpProtocolAdapter`).
7
+ * Centralizing the markdown shape here means every emitter — bundle and extract,
8
+ * MCP-protocol and CLI-as-proxy — produces identical resources/prompts files.
9
+ *
10
+ * Both functions return `null` when the input is empty so callers can write:
11
+ *
12
+ * ```ts
13
+ * const ref = renderResourcesReference(skill.resources ?? [], opts);
14
+ * if (ref) references.push(ref);
15
+ * ```
16
+ *
17
+ * @module references-mcp
18
+ */
19
+ import { estimateTokens, truncateToTokenBudget } from './tokens.js';
20
+ /**
21
+ * Render the `references/resources.md` file for an MCP server's exposed resources.
22
+ *
23
+ * Output shape:
24
+ *
25
+ * ```markdown
26
+ * # Resources
27
+ *
28
+ * ## <resource.name>
29
+ *
30
+ * **URI**: `<resource.uri>`
31
+ * **MIME type**: `<resource.mimeType>` (omitted when undefined)
32
+ *
33
+ * <resource.description>
34
+ *
35
+ * ---
36
+ *
37
+ * ## <next resource>
38
+ * ```
39
+ *
40
+ * @returns A `RenderedFile` with token estimate, or `null` when `resources` is empty.
41
+ */
42
+ export function renderResourcesReference(resources, opts) {
43
+ if (resources.length === 0)
44
+ return null;
45
+ const lines = ['# Resources', ''];
46
+ for (let i = 0; i < resources.length; i++) {
47
+ const r = resources[i];
48
+ lines.push(`## ${r.name}`);
49
+ lines.push('');
50
+ lines.push(`**URI**: \`${r.uri}\``);
51
+ if (r.mimeType !== undefined) {
52
+ lines.push(`**MIME type**: \`${r.mimeType}\``);
53
+ }
54
+ if (r.description) {
55
+ lines.push('');
56
+ lines.push(r.description);
57
+ }
58
+ if (i < resources.length - 1) {
59
+ lines.push('');
60
+ lines.push('---');
61
+ lines.push('');
62
+ }
63
+ }
64
+ const content = lines.join('\n');
65
+ const tokens = estimateTokens(content);
66
+ return {
67
+ filename: `${opts.skillName}/references/resources.md`,
68
+ content: truncateToTokenBudget(content, opts.maxTokens),
69
+ tokens
70
+ };
71
+ }
72
+ /**
73
+ * Render the `references/prompts.md` file for an MCP server's exposed prompts.
74
+ *
75
+ * Output shape:
76
+ *
77
+ * ```markdown
78
+ * # Prompts
79
+ *
80
+ * ## <prompt.name>
81
+ *
82
+ * <prompt.description>
83
+ *
84
+ * | Argument | Required | Description |
85
+ * |----------|----------|-------------|
86
+ * | <name> | yes/no | <desc> |
87
+ *
88
+ * ---
89
+ *
90
+ * ## <next prompt>
91
+ * ```
92
+ *
93
+ * The argument table is omitted when `arguments` is empty.
94
+ *
95
+ * @returns A `RenderedFile` with token estimate, or `null` when `prompts` is empty.
96
+ */
97
+ export function renderPromptsReference(prompts, opts) {
98
+ if (prompts.length === 0)
99
+ return null;
100
+ const lines = ['# Prompts', ''];
101
+ for (let i = 0; i < prompts.length; i++) {
102
+ const p = prompts[i];
103
+ lines.push(`## ${p.name}`);
104
+ lines.push('');
105
+ if (p.description) {
106
+ lines.push(p.description);
107
+ lines.push('');
108
+ }
109
+ if (p.arguments.length > 0) {
110
+ lines.push('| Argument | Required | Description |');
111
+ lines.push('|----------|----------|-------------|');
112
+ for (const arg of p.arguments) {
113
+ lines.push(`| ${arg.name} | ${arg.required ? 'yes' : 'no'} | ${arg.description} |`);
114
+ }
115
+ }
116
+ if (i < prompts.length - 1) {
117
+ lines.push('');
118
+ lines.push('---');
119
+ lines.push('');
120
+ }
121
+ }
122
+ const content = lines.join('\n');
123
+ const tokens = estimateTokens(content);
124
+ return {
125
+ filename: `${opts.skillName}/references/prompts.md`,
126
+ content: truncateToTokenBudget(content, opts.maxTokens),
127
+ tokens
128
+ };
129
+ }
130
+ //# sourceMappingURL=references-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"references-mcp.js","sourceRoot":"","sources":["../src/references-mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { RefineTag } from './types.js';
2
+ /**
3
+ * Insert or update a JSDoc tag on a named export declaration.
4
+ *
5
+ * - If no JSDoc block exists before the declaration, one is created.
6
+ * - If a JSDoc block exists and already contains `@tag content`, the source is
7
+ * returned unchanged (idempotent).
8
+ * - If a JSDoc block exists without the tag, the tag is appended before the
9
+ * closing `*\/`.
10
+ * - If the declaration is not found, the source is returned unchanged.
11
+ */
12
+ export declare function upsertJsDocTag(source: string, declName: string, tag: RefineTag, content: string): string;
13
+ /**
14
+ * Parse the leading JSDoc block of a named export declaration and return a
15
+ * map of the RefineTag values found in it.
16
+ *
17
+ * Returns an empty object when the declaration is not found or has no leading
18
+ * JSDoc block.
19
+ */
20
+ export declare function readJsDocTags(source: string, declName: string): Partial<Record<RefineTag, string>>;
21
+ //# sourceMappingURL=ast-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-edit.d.ts","sourceRoot":"","sources":["../../src/refine/ast-edit.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAwF5C;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,MAAM,GACd,MAAM,CA+BR;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAoBpC"}
@@ -0,0 +1,147 @@
1
+ // packages/core/src/refine/ast-edit.ts
2
+ import { parse, Lang } from '@ast-grep/napi';
3
+ // `satisfies` ensures every listed value is a valid RefineTag. The
4
+ // `MissingTags` assertion below makes the inverse hold too: if a value is added
5
+ // to the RefineTag union but not to this list, compilation fails — so the
6
+ // round-trip / readJsDocTags coverage can never silently miss a tag.
7
+ const REFINE_TAGS = [
8
+ 'useWhen',
9
+ 'avoidWhen',
10
+ 'pitfalls',
11
+ 'remarks',
12
+ 'example'
13
+ ];
14
+ const _exhaustive = undefined;
15
+ void _exhaustive;
16
+ /**
17
+ * True when `node` is a top-level declaration named `declName`.
18
+ * Handles: function_declaration, class_declaration, abstract_class_declaration,
19
+ * interface_declaration, enum_declaration, type_alias_declaration, and
20
+ * lexical_declaration / variable_declaration (const/let with variable_declarator).
21
+ */
22
+ function declarationMatches(node, declName) {
23
+ const k = node.kind();
24
+ if (k === 'function_declaration' ||
25
+ k === 'class_declaration' ||
26
+ k === 'abstract_class_declaration' ||
27
+ k === 'interface_declaration' ||
28
+ k === 'enum_declaration' ||
29
+ k === 'type_alias_declaration') {
30
+ const nameNode = node.field('name');
31
+ return nameNode?.text() === declName;
32
+ }
33
+ if (k === 'lexical_declaration' || k === 'variable_declaration') {
34
+ for (const declarator of node.children()) {
35
+ if (declarator.kind() !== 'variable_declarator')
36
+ continue;
37
+ const nameNode = declarator.field('name');
38
+ if (nameNode?.text() === declName)
39
+ return true;
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+ /**
45
+ * Find the anchor node whose leading JSDoc should be read/edited for the
46
+ * top-level declaration named `declName`.
47
+ *
48
+ * - For an `export`-wrapped declaration, the anchor is the `export_statement`
49
+ * node (so leading JSDoc attaches above the `export` keyword).
50
+ * - For a bare top-level declaration, the anchor is the declaration node itself.
51
+ *
52
+ * Returns `undefined` if no matching declaration exists.
53
+ */
54
+ function findDeclaration(root, declName) {
55
+ for (const child of root.children()) {
56
+ if (child.kind() === 'export_statement') {
57
+ // Look for the inner declaration (skip the 'export' keyword token).
58
+ for (const inner of child.children()) {
59
+ if (inner.kind() === 'export')
60
+ continue; // keyword token
61
+ if (declarationMatches(inner, declName))
62
+ return child;
63
+ }
64
+ continue;
65
+ }
66
+ // Bare (non-exported) top-level declaration.
67
+ if (declarationMatches(child, declName))
68
+ return child;
69
+ }
70
+ return undefined;
71
+ }
72
+ /**
73
+ * Returns the leading JSDoc comment node for a given anchor node, or undefined
74
+ * if none exists. A leading JSDoc must be the immediate previous sibling and
75
+ * start with `/**`.
76
+ */
77
+ function leadingJsDoc(anchorNode) {
78
+ const prev = anchorNode.prev();
79
+ if (prev && prev.kind() === 'comment' && prev.text().startsWith('/**')) {
80
+ return prev;
81
+ }
82
+ return undefined;
83
+ }
84
+ /**
85
+ * Insert or update a JSDoc tag on a named export declaration.
86
+ *
87
+ * - If no JSDoc block exists before the declaration, one is created.
88
+ * - If a JSDoc block exists and already contains `@tag content`, the source is
89
+ * returned unchanged (idempotent).
90
+ * - If a JSDoc block exists without the tag, the tag is appended before the
91
+ * closing `*\/`.
92
+ * - If the declaration is not found, the source is returned unchanged.
93
+ */
94
+ export function upsertJsDocTag(source, declName, tag, content) {
95
+ const root = parse(Lang.TypeScript, source).root();
96
+ const anchorNode = findDeclaration(root, declName);
97
+ if (!anchorNode)
98
+ return source;
99
+ const tagText = `@${tag} ${content}`;
100
+ const jsdocNode = leadingJsDoc(anchorNode);
101
+ if (jsdocNode) {
102
+ const block = jsdocNode.text();
103
+ if (block.includes(tagText))
104
+ return source;
105
+ // Determine the indent of the closing */ line
106
+ const closeOffset = block.lastIndexOf('*/');
107
+ const beforeClose = block.slice(0, closeOffset);
108
+ // The whitespace prefix of the closing `*/` line
109
+ const linePrefix = beforeClose.match(/([^\n]*)$/)?.[1] ?? ' ';
110
+ const merged = block.slice(0, closeOffset - linePrefix.length) +
111
+ `${linePrefix}* ${tagText}\n${linePrefix}*/`;
112
+ return root.commitEdits([jsdocNode.replace(merged)]);
113
+ }
114
+ // No existing JSDoc — create one before the anchor node.
115
+ const col = anchorNode.range().start.column;
116
+ const indent = ' '.repeat(col);
117
+ const at = anchorNode.range().start.index;
118
+ const blockText = `/**\n${indent} * ${tagText}\n${indent} */\n${indent}`;
119
+ return source.slice(0, at) + blockText + source.slice(at);
120
+ }
121
+ /**
122
+ * Parse the leading JSDoc block of a named export declaration and return a
123
+ * map of the RefineTag values found in it.
124
+ *
125
+ * Returns an empty object when the declaration is not found or has no leading
126
+ * JSDoc block.
127
+ */
128
+ export function readJsDocTags(source, declName) {
129
+ const root = parse(Lang.TypeScript, source).root();
130
+ const anchorNode = findDeclaration(root, declName);
131
+ if (!anchorNode)
132
+ return {};
133
+ const jsdocNode = leadingJsDoc(anchorNode);
134
+ if (!jsdocNode)
135
+ return {};
136
+ const block = jsdocNode.text();
137
+ const result = {};
138
+ for (const tag of REFINE_TAGS) {
139
+ const pattern = new RegExp(`@${tag}\\s+(.+?)(?:\\s*\\n|\\s*\\*\\/|$)`, 'm');
140
+ const hit = block.match(pattern);
141
+ if (hit) {
142
+ result[tag] = hit[1]?.trim() ?? '';
143
+ }
144
+ }
145
+ return result;
146
+ }
147
+ //# sourceMappingURL=ast-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-edit.js","sourceRoot":"","sources":["../../src/refine/ast-edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export * from './types.js';
2
+ export * from './select-targets.js';
3
+ export { refineSkill } from './loop.js';
4
+ export type { ScoreSkill } from './loop.js';
5
+ export { insertJsDocTag } from './jsdoc-edit.js';
6
+ export { upsertJsDocTag, readJsDocTags } from './ast-edit.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/refine/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './types.js';
2
+ export * from './select-targets.js';
3
+ export { refineSkill } from './loop.js';
4
+ export { insertJsDocTag } from './jsdoc-edit.js';
5
+ export { upsertJsDocTag, readJsDocTags } from './ast-edit.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/refine/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { RefineTag } from './types.js';
2
+ /** @deprecated internal alias — use upsertJsDocTag. Kept for callers/tests. */
3
+ export declare function insertJsDocTag(source: string, exportName: string, tag: RefineTag, content: string): string;
4
+ //# sourceMappingURL=jsdoc-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsdoc-edit.d.ts","sourceRoot":"","sources":["../../src/refine/jsdoc-edit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,MAAM,GACd,MAAM,CAER"}
@@ -0,0 +1,6 @@
1
+ import { upsertJsDocTag } from './ast-edit.js';
2
+ /** @deprecated internal alias — use upsertJsDocTag. Kept for callers/tests. */
3
+ export function insertJsDocTag(source, exportName, tag, content) {
4
+ return upsertJsDocTag(source, exportName, tag, content);
5
+ }
6
+ //# sourceMappingURL=jsdoc-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsdoc-edit.js","sourceRoot":"","sources":["../../src/refine/jsdoc-edit.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,UAAkB,EAClB,GAAc,EACd,OAAe;IAEf,OAAO,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ExtractedSkill, SkillJudgeEstimate } from '../index.js';
2
+ import type { RefineOptions, RefineResult } from './types.js';
3
+ /** @internal — test seam; production callers use the default audit+score path */
4
+ export type ScoreSkill = (skill: ExtractedSkill) => SkillJudgeEstimate;
5
+ export declare function refineSkill(opts: RefineOptions & {
6
+ scoreSkill?: ScoreSkill;
7
+ }): Promise<RefineResult>;
8
+ //# sourceMappingURL=loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/refine/loop.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EAGV,aAAa,EACb,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB,iFAAiF;AACjF,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,kBAAkB,CAAC;AAavE,wBAAsB,WAAW,CAC/B,IAAI,EAAE,aAAa,GAAG;IAAE,UAAU,CAAC,EAAE,UAAU,CAAA;CAAE,GAChD,OAAO,CAAC,YAAY,CAAC,CA0FvB"}