vskill 1.0.12 → 1.0.14
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/README.md +2 -2
- package/agents.json +1 -1
- package/dist/commands/check.d.ts +55 -0
- package/dist/commands/check.js +279 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/core/agent-prompts.d.ts +35 -0
- package/dist/core/agent-prompts.js +201 -0
- package/dist/core/agent-prompts.js.map +1 -0
- package/dist/core/skill-generator.d.ts +25 -3
- package/dist/core/skill-generator.js +131 -0
- package/dist/core/skill-generator.js.map +1 -1
- package/dist/eval-server/api-routes.d.ts +16 -35
- package/dist/eval-server/api-routes.js +45 -169
- package/dist/eval-server/api-routes.js.map +1 -1
- package/dist/eval-server/skill-create-routes.d.ts +8 -0
- package/dist/eval-server/skill-create-routes.js +96 -0
- package/dist/eval-server/skill-create-routes.js.map +1 -1
- package/dist/eval-server/source-link.d.ts +73 -0
- package/dist/eval-server/source-link.js +275 -0
- package/dist/eval-server/source-link.js.map +1 -0
- package/dist/eval-server/utils/resolve-editor.d.ts +13 -0
- package/dist/eval-server/utils/resolve-editor.js +92 -0
- package/dist/eval-server/utils/resolve-editor.js.map +1 -0
- package/dist/eval-ui/assets/{CreateSkillPage--g_NEIiD.js → CreateSkillPage-CKvqAya0.js} +1 -1
- package/dist/eval-ui/assets/{FindSkillsPalette-XKomH8zI.js → FindSkillsPalette-B8pTa5NP.js} +2 -2
- package/dist/eval-ui/assets/{SearchPaletteCore-DE6FhFNX.js → SearchPaletteCore-CkVRvaZk.js} +1 -1
- package/dist/eval-ui/assets/SkillDetailPanel-d4_LquVH.js +1 -0
- package/dist/eval-ui/assets/{UpdateDropdown-DcRoBdFQ.js → UpdateDropdown-DA7OktXO.js} +1 -1
- package/dist/eval-ui/assets/{index-DhrY6PTA.js → index-DCbohW6l.js} +37 -37
- package/dist/eval-ui/index.html +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/shared/copy-plugin-filtered.js +5 -0
- package/dist/shared/copy-plugin-filtered.js.map +1 -1
- package/dist/studio/lib/scope-transfer.js +31 -6
- package/dist/studio/lib/scope-transfer.js.map +1 -1
- package/package.json +1 -1
- package/dist/eval-ui/assets/SkillDetailPanel-BEqkY3lG.js +0 -1
package/README.md
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
<a href="https://www.npmjs.com/package/vskill"><img src="https://img.shields.io/npm/v/vskill?color=cb3837&logo=npm" alt="npm" /></a>
|
|
10
10
|
<a href="https://www.npmjs.com/package/vskill"><img src="https://img.shields.io/npm/dw/vskill?color=cb3837&logo=npm&label=downloads" alt="downloads" /></a>
|
|
11
11
|
<img src="https://img.shields.io/badge/agents-53_platforms-0969DA" alt="53 agents" />
|
|
12
|
-
<img src="https://img.shields.io/badge/plugins-
|
|
13
|
-
<img src="https://img.shields.io/badge/skills-
|
|
12
|
+
<img src="https://img.shields.io/badge/plugins-9-8B5CF6" alt="9 plugins" />
|
|
13
|
+
<img src="https://img.shields.io/badge/skills-16-10B981" alt="16 skills" />
|
|
14
14
|
<a href="https://verified-skill.com"><img src="https://img.shields.io/badge/registry-verified--skill.com-F59E0B" alt="registry" /></a>
|
|
15
15
|
<img src="https://img.shields.io/badge/license-MIT-green" alt="MIT" />
|
|
16
16
|
</p>
|
package/agents.json
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface CheckOptions {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
/** Override skill search root (default: cwd). */
|
|
4
|
+
root?: string;
|
|
5
|
+
}
|
|
6
|
+
interface CheckRow {
|
|
7
|
+
status: "ok" | "missing" | "warning";
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
interface CheckReport {
|
|
11
|
+
skill: string;
|
|
12
|
+
dir: string;
|
|
13
|
+
mcps: Array<{
|
|
14
|
+
name: string;
|
|
15
|
+
} & CheckRow>;
|
|
16
|
+
secrets: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
} & CheckRow>;
|
|
19
|
+
runtime: Array<{
|
|
20
|
+
key: string;
|
|
21
|
+
} & CheckRow>;
|
|
22
|
+
tests: CheckRow | null;
|
|
23
|
+
exitCode: 0 | 1 | 2;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Locate a skill directory by name, searching common layouts inside `root`:
|
|
27
|
+
* - {root}/plugins/<plugin>/skills/<name>/
|
|
28
|
+
* - {root}/skills/<name>/
|
|
29
|
+
* - {root}/<name>/ (flat layout)
|
|
30
|
+
* Returns the first matching absolute path with a SKILL.md, or null.
|
|
31
|
+
*/
|
|
32
|
+
export declare function findSkillDir(name: string, root: string): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Check whether a named MCP server is configured in any known Claude config
|
|
35
|
+
* file. Returns "configured" if found, "missing" otherwise. Tolerant of
|
|
36
|
+
* malformed JSON — a parse error is treated as "not configured here".
|
|
37
|
+
*/
|
|
38
|
+
export declare function checkMcpConfigured(serverName: string, projectRoot: string): "configured" | "missing";
|
|
39
|
+
/**
|
|
40
|
+
* Compare a `python3 --version` output line ("Python 3.11.4") against a
|
|
41
|
+
* declared minimum in the form ">=3.10" or "3.10" (treated as exact-major+).
|
|
42
|
+
* Returns true if the runtime satisfies the declaration, false otherwise.
|
|
43
|
+
*/
|
|
44
|
+
export declare function pythonVersionSatisfies(installed: string, declared: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Build the structured CheckReport for a skill. Pure, testable — no console
|
|
47
|
+
* I/O. The CLI wrapper (`checkCommand`) renders this report to stdout.
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildCheckReport(skillName: string, projectRoot: string): CheckReport;
|
|
50
|
+
/**
|
|
51
|
+
* CLI entry point — prints the report and exits with the appropriate code.
|
|
52
|
+
* Never echoes secret values; only names + statuses.
|
|
53
|
+
*/
|
|
54
|
+
export declare function checkCommand(skillName: string, opts?: CheckOptions): Promise<void>;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// commands/check.ts — preflight verification for multi-file skills (0815).
|
|
3
|
+
//
|
|
4
|
+
// Reads a skill's SKILL.md frontmatter and verifies that every declared
|
|
5
|
+
// dependency is satisfied before the skill runs:
|
|
6
|
+
// - mcpDeps[] → present in ~/.claude/mcp.json or project .claude/mcp.json
|
|
7
|
+
// - secrets[] → resolvable via env or .env.local (resolveCredential)
|
|
8
|
+
// - runtime.python → `python3 --version` ≥ declared minimum
|
|
9
|
+
// - runtime.pip → declared (informational; we don't auto-install)
|
|
10
|
+
// - integrationTests.runner === "pytest" → `pytest --collect-only` succeeds
|
|
11
|
+
//
|
|
12
|
+
// Exit codes:
|
|
13
|
+
// 0 → all green
|
|
14
|
+
// 1 → at least one required dep missing / unsatisfiable
|
|
15
|
+
// 2 → only soft warnings (e.g. unknown MCP, no integration test runner)
|
|
16
|
+
//
|
|
17
|
+
// Reuses the existing infra: parseSkillFrontmatter + buildSkillMetadata from
|
|
18
|
+
// api-routes.ts (so the same wire format the studio writes is the same one we
|
|
19
|
+
// validate), plus resolveAllCredentials from credential-resolver.ts.
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
|
|
22
|
+
import { homedir } from "node:os";
|
|
23
|
+
import { join, resolve } from "node:path";
|
|
24
|
+
import { spawnSync } from "node:child_process";
|
|
25
|
+
import { buildSkillMetadata } from "../eval-server/api-routes.js";
|
|
26
|
+
import { resolveAllCredentials } from "../eval/credential-resolver.js";
|
|
27
|
+
/**
|
|
28
|
+
* Locate a skill directory by name, searching common layouts inside `root`:
|
|
29
|
+
* - {root}/plugins/<plugin>/skills/<name>/
|
|
30
|
+
* - {root}/skills/<name>/
|
|
31
|
+
* - {root}/<name>/ (flat layout)
|
|
32
|
+
* Returns the first matching absolute path with a SKILL.md, or null.
|
|
33
|
+
*/
|
|
34
|
+
export function findSkillDir(name, root) {
|
|
35
|
+
const candidates = [];
|
|
36
|
+
const pluginsDir = join(root, "plugins");
|
|
37
|
+
if (existsSync(pluginsDir)) {
|
|
38
|
+
try {
|
|
39
|
+
for (const plugin of readdirSync(pluginsDir, { withFileTypes: true })) {
|
|
40
|
+
if (!plugin.isDirectory())
|
|
41
|
+
continue;
|
|
42
|
+
const skillsDir = join(pluginsDir, plugin.name, "skills");
|
|
43
|
+
if (!existsSync(skillsDir))
|
|
44
|
+
continue;
|
|
45
|
+
candidates.push(join(skillsDir, name));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch { /* ignore */ }
|
|
49
|
+
}
|
|
50
|
+
candidates.push(join(root, "skills", name));
|
|
51
|
+
candidates.push(join(root, name));
|
|
52
|
+
for (const c of candidates) {
|
|
53
|
+
try {
|
|
54
|
+
if (existsSync(join(c, "SKILL.md")) && statSync(c).isDirectory())
|
|
55
|
+
return c;
|
|
56
|
+
}
|
|
57
|
+
catch { /* ignore */ }
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check whether a named MCP server is configured in any known Claude config
|
|
63
|
+
* file. Returns "configured" if found, "missing" otherwise. Tolerant of
|
|
64
|
+
* malformed JSON — a parse error is treated as "not configured here".
|
|
65
|
+
*/
|
|
66
|
+
export function checkMcpConfigured(serverName, projectRoot) {
|
|
67
|
+
const candidates = [
|
|
68
|
+
join(projectRoot, ".claude", "mcp.json"),
|
|
69
|
+
join(homedir(), ".claude", "mcp.json"),
|
|
70
|
+
join(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
71
|
+
];
|
|
72
|
+
for (const p of candidates) {
|
|
73
|
+
if (!existsSync(p))
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
const cfg = JSON.parse(readFileSync(p, "utf-8"));
|
|
77
|
+
const servers = cfg.mcpServers;
|
|
78
|
+
if (servers && typeof servers === "object" && serverName in servers) {
|
|
79
|
+
return "configured";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch { /* ignore parse error */ }
|
|
83
|
+
}
|
|
84
|
+
return "missing";
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Compare a `python3 --version` output line ("Python 3.11.4") against a
|
|
88
|
+
* declared minimum in the form ">=3.10" or "3.10" (treated as exact-major+).
|
|
89
|
+
* Returns true if the runtime satisfies the declaration, false otherwise.
|
|
90
|
+
*/
|
|
91
|
+
export function pythonVersionSatisfies(installed, declared) {
|
|
92
|
+
const m = installed.match(/Python\s+(\d+)\.(\d+)/);
|
|
93
|
+
if (!m)
|
|
94
|
+
return false;
|
|
95
|
+
const haveMaj = parseInt(m[1], 10);
|
|
96
|
+
const haveMin = parseInt(m[2], 10);
|
|
97
|
+
const decl = declared.replace(/^[><=~^]+/, "").trim();
|
|
98
|
+
const dm = decl.match(/^(\d+)\.(\d+)/);
|
|
99
|
+
if (!dm)
|
|
100
|
+
return false;
|
|
101
|
+
const wantMaj = parseInt(dm[1], 10);
|
|
102
|
+
const wantMin = parseInt(dm[2], 10);
|
|
103
|
+
if (haveMaj !== wantMaj)
|
|
104
|
+
return haveMaj > wantMaj;
|
|
105
|
+
return haveMin >= wantMin;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Build the structured CheckReport for a skill. Pure, testable — no console
|
|
109
|
+
* I/O. The CLI wrapper (`checkCommand`) renders this report to stdout.
|
|
110
|
+
*/
|
|
111
|
+
export function buildCheckReport(skillName, projectRoot) {
|
|
112
|
+
const dir = findSkillDir(skillName, projectRoot);
|
|
113
|
+
if (!dir) {
|
|
114
|
+
return {
|
|
115
|
+
skill: skillName,
|
|
116
|
+
dir: "",
|
|
117
|
+
mcps: [],
|
|
118
|
+
secrets: [],
|
|
119
|
+
runtime: [],
|
|
120
|
+
tests: null,
|
|
121
|
+
exitCode: 1,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const meta = buildSkillMetadata(dir, "source", projectRoot);
|
|
125
|
+
const mcps = (meta.mcpDeps ?? []).map((name) => {
|
|
126
|
+
const status = checkMcpConfigured(name, projectRoot);
|
|
127
|
+
return {
|
|
128
|
+
name,
|
|
129
|
+
status: status === "configured" ? "ok" : "missing",
|
|
130
|
+
message: status === "configured" ? "configured" : "not configured in any known Claude config",
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
const secretStatuses = resolveAllCredentials(meta.secrets ?? [], dir);
|
|
134
|
+
const secrets = secretStatuses.map((s) => ({
|
|
135
|
+
name: s.name,
|
|
136
|
+
status: s.status === "ready" ? "ok" : "missing",
|
|
137
|
+
message: s.status === "ready" ? `ready (${s.source})` : "missing — set in env or .env.local",
|
|
138
|
+
}));
|
|
139
|
+
const runtime = [];
|
|
140
|
+
if (meta.runtime?.python) {
|
|
141
|
+
const result = spawnSync("python3", ["--version"], { encoding: "utf-8" });
|
|
142
|
+
if (result.status === 0) {
|
|
143
|
+
const out = (result.stdout || result.stderr || "").trim();
|
|
144
|
+
const ok = pythonVersionSatisfies(out, meta.runtime.python);
|
|
145
|
+
runtime.push({
|
|
146
|
+
key: "python",
|
|
147
|
+
status: ok ? "ok" : "missing",
|
|
148
|
+
message: ok ? `${out} satisfies ${meta.runtime.python}` : `${out} does not satisfy ${meta.runtime.python}`,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
runtime.push({
|
|
153
|
+
key: "python",
|
|
154
|
+
status: "missing",
|
|
155
|
+
message: `python3 not on PATH (declared ${meta.runtime.python})`,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (meta.runtime?.pip && meta.runtime.pip.length > 0) {
|
|
160
|
+
runtime.push({
|
|
161
|
+
key: "pip",
|
|
162
|
+
status: "warning",
|
|
163
|
+
message: `declares ${meta.runtime.pip.length} pip package(s) — install manually before running`,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
let tests = null;
|
|
167
|
+
if (meta.integrationTests?.runner === "pytest") {
|
|
168
|
+
const file = meta.integrationTests.file
|
|
169
|
+
? resolve(dir, meta.integrationTests.file)
|
|
170
|
+
: resolve(dir, "tests");
|
|
171
|
+
if (!existsSync(file)) {
|
|
172
|
+
tests = { status: "missing", message: `pytest target ${meta.integrationTests.file ?? "tests/"} not found` };
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
const result = spawnSync("python3", ["-m", "pytest", "--collect-only", file], {
|
|
176
|
+
encoding: "utf-8",
|
|
177
|
+
cwd: dir,
|
|
178
|
+
});
|
|
179
|
+
if (result.status === 0) {
|
|
180
|
+
tests = { status: "ok", message: "pytest --collect-only succeeded" };
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
tests = {
|
|
184
|
+
status: "missing",
|
|
185
|
+
message: `pytest --collect-only failed (exit ${result.status ?? "?"}): ${(result.stderr || "").split("\n")[0] || "no stderr"}`,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (meta.integrationTests?.runner === "vitest") {
|
|
191
|
+
tests = { status: "warning", message: "vitest collection check not yet implemented" };
|
|
192
|
+
}
|
|
193
|
+
else if (meta.integrationTests?.runner === "none") {
|
|
194
|
+
tests = { status: "ok", message: "no integration tests declared" };
|
|
195
|
+
}
|
|
196
|
+
// Compute exit code: 0 all green, 1 any missing, 2 only warnings.
|
|
197
|
+
let anyMissing = false;
|
|
198
|
+
let anyWarning = false;
|
|
199
|
+
for (const row of [...mcps, ...secrets, ...runtime, ...(tests ? [tests] : [])]) {
|
|
200
|
+
if (row.status === "missing")
|
|
201
|
+
anyMissing = true;
|
|
202
|
+
if (row.status === "warning")
|
|
203
|
+
anyWarning = true;
|
|
204
|
+
}
|
|
205
|
+
const exitCode = anyMissing ? 1 : anyWarning ? 2 : 0;
|
|
206
|
+
return { skill: skillName, dir, mcps, secrets, runtime, tests, exitCode };
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* CLI entry point — prints the report and exits with the appropriate code.
|
|
210
|
+
* Never echoes secret values; only names + statuses.
|
|
211
|
+
*/
|
|
212
|
+
export async function checkCommand(skillName, opts = {}) {
|
|
213
|
+
const root = opts.root ? resolve(opts.root) : process.cwd();
|
|
214
|
+
const report = buildCheckReport(skillName, root);
|
|
215
|
+
if (!report.dir) {
|
|
216
|
+
if (opts.json) {
|
|
217
|
+
process.stdout.write(JSON.stringify({ ...report, error: "skill-not-found" }, null, 2) + "\n");
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
process.stderr.write(`vskill check: skill '${skillName}' not found under ${root}\n`);
|
|
221
|
+
}
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
if (opts.json) {
|
|
225
|
+
process.stdout.write(JSON.stringify(report, null, 2) + "\n");
|
|
226
|
+
process.exit(report.exitCode);
|
|
227
|
+
}
|
|
228
|
+
// Human-readable rendering — never includes secret values.
|
|
229
|
+
const lines = [];
|
|
230
|
+
lines.push(`vskill check: ${report.skill}`);
|
|
231
|
+
lines.push(` ${report.dir}`);
|
|
232
|
+
lines.push("");
|
|
233
|
+
if (report.mcps.length === 0) {
|
|
234
|
+
lines.push("MCPs: (none declared)");
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
lines.push("MCPs:");
|
|
238
|
+
for (const r of report.mcps)
|
|
239
|
+
lines.push(` ${glyph(r.status)} ${r.name}: ${r.message}`);
|
|
240
|
+
}
|
|
241
|
+
if (report.secrets.length === 0) {
|
|
242
|
+
lines.push("Secrets: (none declared)");
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
lines.push("Secrets:");
|
|
246
|
+
for (const r of report.secrets)
|
|
247
|
+
lines.push(` ${glyph(r.status)} ${r.name}: ${r.message}`);
|
|
248
|
+
}
|
|
249
|
+
if (report.runtime.length === 0) {
|
|
250
|
+
lines.push("Runtime: (none declared)");
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
lines.push("Runtime:");
|
|
254
|
+
for (const r of report.runtime)
|
|
255
|
+
lines.push(` ${glyph(r.status)} ${r.key}: ${r.message}`);
|
|
256
|
+
}
|
|
257
|
+
if (report.tests) {
|
|
258
|
+
lines.push(`Tests: ${glyph(report.tests.status)} ${report.tests.message}`);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
lines.push("Tests: (no integration runner declared)");
|
|
262
|
+
}
|
|
263
|
+
lines.push("");
|
|
264
|
+
lines.push(report.exitCode === 0
|
|
265
|
+
? "All checks passed."
|
|
266
|
+
: report.exitCode === 2
|
|
267
|
+
? "Soft warnings only — review above."
|
|
268
|
+
: "One or more required dependencies missing — see above.");
|
|
269
|
+
process.stdout.write(lines.join("\n") + "\n");
|
|
270
|
+
process.exit(report.exitCode);
|
|
271
|
+
}
|
|
272
|
+
function glyph(status) {
|
|
273
|
+
switch (status) {
|
|
274
|
+
case "ok": return "[OK] ";
|
|
275
|
+
case "missing": return "[MISS] ";
|
|
276
|
+
case "warning": return "[WARN] ";
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface AgentFile {
|
|
2
|
+
path: string;
|
|
3
|
+
content: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ScriptAgentResponse {
|
|
6
|
+
files: AgentFile[];
|
|
7
|
+
runtime?: {
|
|
8
|
+
python?: string;
|
|
9
|
+
pip?: string[];
|
|
10
|
+
node?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface GraderAgentResponse {
|
|
14
|
+
files: AgentFile[];
|
|
15
|
+
}
|
|
16
|
+
export interface TestAgentResponse {
|
|
17
|
+
files: AgentFile[];
|
|
18
|
+
secrets?: string[];
|
|
19
|
+
integrationTests?: {
|
|
20
|
+
runner: "vitest" | "pytest" | "none";
|
|
21
|
+
file?: string;
|
|
22
|
+
requires?: string[];
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface ReferenceAgentResponse {
|
|
26
|
+
files: AgentFile[];
|
|
27
|
+
}
|
|
28
|
+
export declare const SCRIPT_SYSTEM_PROMPT = "You generate the deterministic helper script(s) for a skill in Skill Studio.\n\nGiven the user's skill description, produce one or more language-appropriate helper scripts the skill will shell out to (e.g. `scripts/audit.py`, `scripts/format.js`). Scripts must:\n- Be self-contained and runnable from the skill directory.\n- Use only the standard library plus the dependencies you declare in `runtime`.\n- Read secrets from environment variables; never contain hardcoded API keys.\n- Degrade gracefully when env vars or external services are unavailable (print a clear message and exit non-zero, never crash on import).\n\n## Output Format\nReturn ONLY a JSON object:\n{\n \"files\": [\n { \"path\": \"scripts/<name>.<ext>\", \"content\": \"<full source>\" }\n ],\n \"runtime\": { \"python\": \">=3.10\", \"pip\": [\"pkg>=1\"] }\n}\n\n`runtime` is optional \u2014 omit if the script needs no runtime declaration.\n`path` is always relative to the skill root, must start with `scripts/`, and must not contain `..` or absolute paths.\nNo code fences, no preamble.";
|
|
29
|
+
export declare const GRADER_SYSTEM_PROMPT = "You generate a deterministic grader script for a skill in Skill Studio.\n\nGiven the user's skill description, produce a single grader script (e.g. `scripts/grader.py`) that takes the skill's output as input and returns a numeric score in [0, 1]. The grader must:\n- Be a pure function of its input \u2014 no network calls, no env reads.\n- Return a deterministic float between 0 and 1.\n- Match the language of the main script when possible.\n\n## Output Format\nReturn ONLY a JSON object:\n{\n \"files\": [\n { \"path\": \"scripts/grader.<ext>\", \"content\": \"<full source>\" }\n ]\n}\n\n`path` must start with `scripts/` and must not contain `..` or absolute paths.\nNo code fences, no preamble.";
|
|
30
|
+
export declare const TEST_SYSTEM_PROMPT = "You generate a runnable integration test for a skill in Skill Studio.\n\nGiven the user's skill description, produce ONE integration test file (e.g. `tests/integration_test.py` or `tests/integration.test.ts`) plus a top-level secrets declaration. The test must:\n- Be runnable via the declared runner (`pytest` or `vitest`).\n- Skip cleanly when required env vars are missing (e.g. `pytest.skip`).\n- Never include real secret values \u2014 only test-mode placeholders or mocks.\n\n## Output Format\nReturn ONLY a JSON object:\n{\n \"files\": [\n { \"path\": \"tests/<name>\", \"content\": \"<full source>\" }\n ],\n \"secrets\": [\"UPPER_SNAKE_NAME\"],\n \"integrationTests\": {\n \"runner\": \"pytest\",\n \"file\": \"tests/integration_test.py\",\n \"requires\": [\"UPPER_SNAKE_NAME\"]\n }\n}\n\n`secrets` is the list of env-var names the skill needs; purposes/hints will be emitted into `.env.example` by the caller.\n`runner` must be one of: \"pytest\", \"vitest\", \"none\".\n`path` must start with `tests/` and must not contain `..` or absolute paths.\nNo code fences, no preamble.";
|
|
31
|
+
export declare const REFERENCE_SYSTEM_PROMPT = "You generate reference documentation files for a skill in Skill Studio.\n\nGiven the user's skill description, produce 1-3 markdown reference files under `references/` that document external schemas, APIs, or domain concepts the skill needs. Files must:\n- Be useful to a future maintainer reading the skill cold.\n- Cite specific field names, types, and behaviors when describing external schemas.\n- Stay under 300 lines each.\n\n## Output Format\nReturn ONLY a JSON object:\n{\n \"files\": [\n { \"path\": \"references/<name>.md\", \"content\": \"<full markdown>\" }\n ]\n}\n\n`path` must start with `references/` and must not contain `..` or absolute paths.\nNo code fences, no preamble.";
|
|
32
|
+
export declare function parseScriptResponse(text: string): ScriptAgentResponse;
|
|
33
|
+
export declare function parseGraderResponse(text: string): GraderAgentResponse;
|
|
34
|
+
export declare function parseTestResponse(text: string): TestAgentResponse;
|
|
35
|
+
export declare function parseReferenceResponse(text: string): ReferenceAgentResponse;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// agent-prompts.ts — per-role system prompts + JSON parsers for the 0815
|
|
3
|
+
// multi-file generation pipeline.
|
|
4
|
+
//
|
|
5
|
+
// Each agent owns one slice of a multi-file skill. They run in parallel under
|
|
6
|
+
// generateSkill({ multiFile: true }) via Promise.allSettled; the body-agent
|
|
7
|
+
// runs sequentially after, with the merged filename list as input, so SKILL.md
|
|
8
|
+
// can link to produced files.
|
|
9
|
+
//
|
|
10
|
+
// Output shape is unified — every agent returns `{ files: [{path, content}] }`
|
|
11
|
+
// so the route layer can write them in a single batch. Test-agent additionally
|
|
12
|
+
// emits `secrets[]` and `integrationTests` (top-level manifest fields).
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// System prompts. Each is a constant string consumed by createLlmClient().
|
|
16
|
+
// Kept terse on purpose — the user's skill description is the discriminator.
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
export const SCRIPT_SYSTEM_PROMPT = `You generate the deterministic helper script(s) for a skill in Skill Studio.
|
|
19
|
+
|
|
20
|
+
Given the user's skill description, produce one or more language-appropriate helper scripts the skill will shell out to (e.g. \`scripts/audit.py\`, \`scripts/format.js\`). Scripts must:
|
|
21
|
+
- Be self-contained and runnable from the skill directory.
|
|
22
|
+
- Use only the standard library plus the dependencies you declare in \`runtime\`.
|
|
23
|
+
- Read secrets from environment variables; never contain hardcoded API keys.
|
|
24
|
+
- Degrade gracefully when env vars or external services are unavailable (print a clear message and exit non-zero, never crash on import).
|
|
25
|
+
|
|
26
|
+
## Output Format
|
|
27
|
+
Return ONLY a JSON object:
|
|
28
|
+
{
|
|
29
|
+
"files": [
|
|
30
|
+
{ "path": "scripts/<name>.<ext>", "content": "<full source>" }
|
|
31
|
+
],
|
|
32
|
+
"runtime": { "python": ">=3.10", "pip": ["pkg>=1"] }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
\`runtime\` is optional — omit if the script needs no runtime declaration.
|
|
36
|
+
\`path\` is always relative to the skill root, must start with \`scripts/\`, and must not contain \`..\` or absolute paths.
|
|
37
|
+
No code fences, no preamble.`;
|
|
38
|
+
export const GRADER_SYSTEM_PROMPT = `You generate a deterministic grader script for a skill in Skill Studio.
|
|
39
|
+
|
|
40
|
+
Given the user's skill description, produce a single grader script (e.g. \`scripts/grader.py\`) that takes the skill's output as input and returns a numeric score in [0, 1]. The grader must:
|
|
41
|
+
- Be a pure function of its input — no network calls, no env reads.
|
|
42
|
+
- Return a deterministic float between 0 and 1.
|
|
43
|
+
- Match the language of the main script when possible.
|
|
44
|
+
|
|
45
|
+
## Output Format
|
|
46
|
+
Return ONLY a JSON object:
|
|
47
|
+
{
|
|
48
|
+
"files": [
|
|
49
|
+
{ "path": "scripts/grader.<ext>", "content": "<full source>" }
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
\`path\` must start with \`scripts/\` and must not contain \`..\` or absolute paths.
|
|
54
|
+
No code fences, no preamble.`;
|
|
55
|
+
export const TEST_SYSTEM_PROMPT = `You generate a runnable integration test for a skill in Skill Studio.
|
|
56
|
+
|
|
57
|
+
Given the user's skill description, produce ONE integration test file (e.g. \`tests/integration_test.py\` or \`tests/integration.test.ts\`) plus a top-level secrets declaration. The test must:
|
|
58
|
+
- Be runnable via the declared runner (\`pytest\` or \`vitest\`).
|
|
59
|
+
- Skip cleanly when required env vars are missing (e.g. \`pytest.skip\`).
|
|
60
|
+
- Never include real secret values — only test-mode placeholders or mocks.
|
|
61
|
+
|
|
62
|
+
## Output Format
|
|
63
|
+
Return ONLY a JSON object:
|
|
64
|
+
{
|
|
65
|
+
"files": [
|
|
66
|
+
{ "path": "tests/<name>", "content": "<full source>" }
|
|
67
|
+
],
|
|
68
|
+
"secrets": ["UPPER_SNAKE_NAME"],
|
|
69
|
+
"integrationTests": {
|
|
70
|
+
"runner": "pytest",
|
|
71
|
+
"file": "tests/integration_test.py",
|
|
72
|
+
"requires": ["UPPER_SNAKE_NAME"]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
\`secrets\` is the list of env-var names the skill needs; purposes/hints will be emitted into \`.env.example\` by the caller.
|
|
77
|
+
\`runner\` must be one of: "pytest", "vitest", "none".
|
|
78
|
+
\`path\` must start with \`tests/\` and must not contain \`..\` or absolute paths.
|
|
79
|
+
No code fences, no preamble.`;
|
|
80
|
+
export const REFERENCE_SYSTEM_PROMPT = `You generate reference documentation files for a skill in Skill Studio.
|
|
81
|
+
|
|
82
|
+
Given the user's skill description, produce 1-3 markdown reference files under \`references/\` that document external schemas, APIs, or domain concepts the skill needs. Files must:
|
|
83
|
+
- Be useful to a future maintainer reading the skill cold.
|
|
84
|
+
- Cite specific field names, types, and behaviors when describing external schemas.
|
|
85
|
+
- Stay under 300 lines each.
|
|
86
|
+
|
|
87
|
+
## Output Format
|
|
88
|
+
Return ONLY a JSON object:
|
|
89
|
+
{
|
|
90
|
+
"files": [
|
|
91
|
+
{ "path": "references/<name>.md", "content": "<full markdown>" }
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
\`path\` must start with \`references/\` and must not contain \`..\` or absolute paths.
|
|
96
|
+
No code fences, no preamble.`;
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// JSON parsers. Modeled on parseBodyResponse / parseEvalsResponse from
|
|
99
|
+
// skill-create-routes.ts — strip optional code-fence wrappers, JSON.parse,
|
|
100
|
+
// then validate the shape. Throw a descriptive Error on any malformed input
|
|
101
|
+
// so Promise.allSettled in the generator captures it as a rejection.
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
function stripCodeFences(text) {
|
|
104
|
+
// Be tolerant: some models still wrap in ```json\n...\n``` despite "no fences".
|
|
105
|
+
const trimmed = text.trim();
|
|
106
|
+
const fenceMatch = trimmed.match(/^```(?:json)?\s*\n([\s\S]*?)\n```\s*$/);
|
|
107
|
+
return fenceMatch ? fenceMatch[1].trim() : trimmed;
|
|
108
|
+
}
|
|
109
|
+
function parseAgentJson(text, agent) {
|
|
110
|
+
const stripped = stripCodeFences(text);
|
|
111
|
+
// Some models emit a trailing ---REASONING--- block (matches body-agent
|
|
112
|
+
// pattern). Keep only the JSON portion.
|
|
113
|
+
const reasoningCut = stripped.split(/\n---REASONING---/i)[0].trim();
|
|
114
|
+
try {
|
|
115
|
+
return JSON.parse(reasoningCut);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
throw new Error(`${agent}-agent returned invalid JSON: ${err.message}. First 200 chars: ${reasoningCut.slice(0, 200)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function validateFiles(raw, agent, pathPrefix) {
|
|
122
|
+
if (!raw || typeof raw !== "object") {
|
|
123
|
+
throw new Error(`${agent}-agent: response is not an object`);
|
|
124
|
+
}
|
|
125
|
+
const files = raw.files;
|
|
126
|
+
if (!Array.isArray(files) || files.length === 0) {
|
|
127
|
+
throw new Error(`${agent}-agent: missing or empty 'files' array`);
|
|
128
|
+
}
|
|
129
|
+
const out = [];
|
|
130
|
+
for (const f of files) {
|
|
131
|
+
if (!f || typeof f !== "object") {
|
|
132
|
+
throw new Error(`${agent}-agent: file entry is not an object`);
|
|
133
|
+
}
|
|
134
|
+
const path = f.path;
|
|
135
|
+
const content = f.content;
|
|
136
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
137
|
+
throw new Error(`${agent}-agent: file.path must be a non-empty string`);
|
|
138
|
+
}
|
|
139
|
+
if (typeof content !== "string") {
|
|
140
|
+
throw new Error(`${agent}-agent: file.content must be a string`);
|
|
141
|
+
}
|
|
142
|
+
if (path.includes("..") || path.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(path)) {
|
|
143
|
+
throw new Error(`${agent}-agent: refused unsafe path '${path}'`);
|
|
144
|
+
}
|
|
145
|
+
if (!path.startsWith(pathPrefix)) {
|
|
146
|
+
throw new Error(`${agent}-agent: path '${path}' must start with '${pathPrefix}'`);
|
|
147
|
+
}
|
|
148
|
+
out.push({ path, content });
|
|
149
|
+
}
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
export function parseScriptResponse(text) {
|
|
153
|
+
const raw = parseAgentJson(text, "script");
|
|
154
|
+
const files = validateFiles(raw, "script", "scripts/");
|
|
155
|
+
const r = raw.runtime;
|
|
156
|
+
let runtime;
|
|
157
|
+
if (r && typeof r === "object") {
|
|
158
|
+
const ro = r;
|
|
159
|
+
runtime = {
|
|
160
|
+
python: typeof ro.python === "string" ? ro.python : undefined,
|
|
161
|
+
pip: Array.isArray(ro.pip) ? ro.pip.filter((p) => typeof p === "string") : undefined,
|
|
162
|
+
node: typeof ro.node === "string" ? ro.node : undefined,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return { files, runtime };
|
|
166
|
+
}
|
|
167
|
+
export function parseGraderResponse(text) {
|
|
168
|
+
const raw = parseAgentJson(text, "grader");
|
|
169
|
+
const files = validateFiles(raw, "grader", "scripts/");
|
|
170
|
+
return { files };
|
|
171
|
+
}
|
|
172
|
+
export function parseTestResponse(text) {
|
|
173
|
+
const raw = parseAgentJson(text, "test");
|
|
174
|
+
const files = validateFiles(raw, "test", "tests/");
|
|
175
|
+
const r = raw;
|
|
176
|
+
const secrets = Array.isArray(r.secrets)
|
|
177
|
+
? r.secrets.filter((s) => typeof s === "string")
|
|
178
|
+
: undefined;
|
|
179
|
+
let integrationTests;
|
|
180
|
+
const it = r.integrationTests;
|
|
181
|
+
if (it && typeof it === "object") {
|
|
182
|
+
const ito = it;
|
|
183
|
+
const runner = ito.runner;
|
|
184
|
+
if (runner === "pytest" || runner === "vitest" || runner === "none") {
|
|
185
|
+
integrationTests = {
|
|
186
|
+
runner,
|
|
187
|
+
file: typeof ito.file === "string" ? ito.file : undefined,
|
|
188
|
+
requires: Array.isArray(ito.requires)
|
|
189
|
+
? ito.requires.filter((r2) => typeof r2 === "string")
|
|
190
|
+
: undefined,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return { files, secrets, integrationTests };
|
|
195
|
+
}
|
|
196
|
+
export function parseReferenceResponse(text) {
|
|
197
|
+
const raw = parseAgentJson(text, "reference");
|
|
198
|
+
const files = validateFiles(raw, "reference", "references/");
|
|
199
|
+
return { files };
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=agent-prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-prompts.js","sourceRoot":"","sources":["../../src/core/agent-prompts.ts"],"names":[],"mappings":"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"}
|