@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.
- package/LICENSE +21 -0
- package/README.md +55 -0
- package/dist/audit-formatter.d.ts +36 -0
- package/dist/audit-formatter.d.ts.map +1 -0
- package/dist/audit-formatter.js +173 -0
- package/dist/audit-formatter.js.map +1 -0
- package/dist/audit-score.d.ts +76 -0
- package/dist/audit-score.d.ts.map +1 -0
- package/dist/audit-score.js +490 -0
- package/dist/audit-score.js.map +1 -0
- package/dist/audit-types.d.ts +81 -0
- package/dist/audit-types.d.ts.map +1 -0
- package/dist/audit-types.js +2 -0
- package/dist/audit-types.js.map +1 -0
- package/dist/audit.d.ts +17 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +567 -0
- package/dist/audit.js.map +1 -0
- package/dist/canonical.d.ts +36 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +148 -0
- package/dist/canonical.js.map +1 -0
- package/dist/config-renderer.d.ts +16 -0
- package/dist/config-renderer.d.ts.map +1 -0
- package/dist/config-renderer.js +296 -0
- package/dist/config-renderer.js.map +1 -0
- package/dist/config-types.d.ts +144 -0
- package/dist/config-types.d.ts.map +1 -0
- package/dist/config-types.js +2 -0
- package/dist/config-types.js.map +1 -0
- package/dist/docs-scanner.d.ts +40 -0
- package/dist/docs-scanner.d.ts.map +1 -0
- package/dist/docs-scanner.js +176 -0
- package/dist/docs-scanner.js.map +1 -0
- package/dist/examples-scanner.d.ts +39 -0
- package/dist/examples-scanner.d.ts.map +1 -0
- package/dist/examples-scanner.js +221 -0
- package/dist/examples-scanner.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/llms-txt.d.ts +20 -0
- package/dist/llms-txt.d.ts.map +1 -0
- package/dist/llms-txt.js +187 -0
- package/dist/llms-txt.js.map +1 -0
- package/dist/markdown-parser.d.ts +11 -0
- package/dist/markdown-parser.d.ts.map +1 -0
- package/dist/markdown-parser.js +222 -0
- package/dist/markdown-parser.js.map +1 -0
- package/dist/markdown-types.d.ts +48 -0
- package/dist/markdown-types.d.ts.map +1 -0
- package/dist/markdown-types.js +2 -0
- package/dist/markdown-types.js.map +1 -0
- package/dist/readme-parser.d.ts +21 -0
- package/dist/readme-parser.d.ts.map +1 -0
- package/dist/readme-parser.js +137 -0
- package/dist/readme-parser.js.map +1 -0
- package/dist/references-mcp.d.ts +79 -0
- package/dist/references-mcp.d.ts.map +1 -0
- package/dist/references-mcp.js +130 -0
- package/dist/references-mcp.js.map +1 -0
- package/dist/refine/ast-edit.d.ts +21 -0
- package/dist/refine/ast-edit.d.ts.map +1 -0
- package/dist/refine/ast-edit.js +147 -0
- package/dist/refine/ast-edit.js.map +1 -0
- package/dist/refine/index.d.ts +7 -0
- package/dist/refine/index.d.ts.map +1 -0
- package/dist/refine/index.js +6 -0
- package/dist/refine/index.js.map +1 -0
- package/dist/refine/jsdoc-edit.d.ts +4 -0
- package/dist/refine/jsdoc-edit.d.ts.map +1 -0
- package/dist/refine/jsdoc-edit.js +6 -0
- package/dist/refine/jsdoc-edit.js.map +1 -0
- package/dist/refine/loop.d.ts +8 -0
- package/dist/refine/loop.d.ts.map +1 -0
- package/dist/refine/loop.js +98 -0
- package/dist/refine/loop.js.map +1 -0
- package/dist/refine/select-targets.d.ts +5 -0
- package/dist/refine/select-targets.d.ts.map +1 -0
- package/dist/refine/select-targets.js +30 -0
- package/dist/refine/select-targets.js.map +1 -0
- package/dist/refine/types.d.ts +67 -0
- package/dist/refine/types.d.ts.map +1 -0
- package/dist/refine/types.js +2 -0
- package/dist/refine/types.js.map +1 -0
- package/dist/renderer.d.ts +27 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +1244 -0
- package/dist/renderer.js.map +1 -0
- package/dist/tokens.d.ts +14 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +26 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +519 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/writer.d.ts +17 -0
- package/dist/writer.d.ts.map +1 -0
- package/dist/writer.js +313 -0
- package/dist/writer.js.map +1 -0
- 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 @@
|
|
|
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"}
|