vskill 1.0.13 → 1.0.15

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 (102) hide show
  1. package/README.md +63 -2
  2. package/agents.json +1 -1
  3. package/dist/bin.js +0 -0
  4. package/dist/clone/github-scaffold.d.ts +38 -0
  5. package/dist/clone/github-scaffold.js +108 -0
  6. package/dist/clone/github-scaffold.js.map +1 -0
  7. package/dist/clone/provenance-fork.d.ts +34 -0
  8. package/dist/clone/provenance-fork.js +97 -0
  9. package/dist/clone/provenance-fork.js.map +1 -0
  10. package/dist/clone/reference-scanner.d.ts +19 -0
  11. package/dist/clone/reference-scanner.js +144 -0
  12. package/dist/clone/reference-scanner.js.map +1 -0
  13. package/dist/clone/skill-locator.d.ts +26 -0
  14. package/dist/clone/skill-locator.js +248 -0
  15. package/dist/clone/skill-locator.js.map +1 -0
  16. package/dist/clone/target-router.d.ts +73 -0
  17. package/dist/clone/target-router.js +200 -0
  18. package/dist/clone/target-router.js.map +1 -0
  19. package/dist/clone/types.d.ts +82 -0
  20. package/dist/clone/types.js +11 -0
  21. package/dist/clone/types.js.map +1 -0
  22. package/dist/commands/add.js +96 -32
  23. package/dist/commands/add.js.map +1 -1
  24. package/dist/commands/auth.d.ts +23 -0
  25. package/dist/commands/auth.js +273 -0
  26. package/dist/commands/auth.js.map +1 -0
  27. package/dist/commands/check.d.ts +55 -0
  28. package/dist/commands/check.js +279 -0
  29. package/dist/commands/check.js.map +1 -0
  30. package/dist/commands/clone-prompts.d.ts +13 -0
  31. package/dist/commands/clone-prompts.js +67 -0
  32. package/dist/commands/clone-prompts.js.map +1 -0
  33. package/dist/commands/clone.d.ts +70 -0
  34. package/dist/commands/clone.js +649 -0
  35. package/dist/commands/clone.js.map +1 -0
  36. package/dist/commands/eval/serve.js +8 -1
  37. package/dist/commands/eval/serve.js.map +1 -1
  38. package/dist/commands/keys.js +54 -2
  39. package/dist/commands/keys.js.map +1 -1
  40. package/dist/core/agent-prompts.d.ts +35 -0
  41. package/dist/core/agent-prompts.js +201 -0
  42. package/dist/core/agent-prompts.js.map +1 -0
  43. package/dist/core/skill-generator.d.ts +25 -3
  44. package/dist/core/skill-generator.js +131 -0
  45. package/dist/core/skill-generator.js.map +1 -1
  46. package/dist/eval/skill-scanner.d.ts +2 -12
  47. package/dist/eval/skill-scanner.js +27 -5
  48. package/dist/eval/skill-scanner.js.map +1 -1
  49. package/dist/eval-server/api-routes.d.ts +14 -0
  50. package/dist/eval-server/api-routes.js +376 -31
  51. package/dist/eval-server/api-routes.js.map +1 -1
  52. package/dist/eval-server/data-events.d.ts +1 -1
  53. package/dist/eval-server/data-events.js.map +1 -1
  54. package/dist/eval-server/install-engine-routes-helpers.d.ts +1 -3
  55. package/dist/eval-server/install-engine-routes-helpers.js +6 -14
  56. package/dist/eval-server/install-engine-routes-helpers.js.map +1 -1
  57. package/dist/eval-server/origin-resolver.d.ts +42 -0
  58. package/dist/eval-server/origin-resolver.js +168 -0
  59. package/dist/eval-server/origin-resolver.js.map +1 -0
  60. package/dist/eval-server/platform-proxy.d.ts +10 -0
  61. package/dist/eval-server/platform-proxy.js +58 -2
  62. package/dist/eval-server/platform-proxy.js.map +1 -1
  63. package/dist/eval-server/skill-create-routes.d.ts +8 -0
  64. package/dist/eval-server/skill-create-routes.js +96 -0
  65. package/dist/eval-server/skill-create-routes.js.map +1 -1
  66. package/dist/eval-server/skill-resolver.js +40 -0
  67. package/dist/eval-server/skill-resolver.js.map +1 -1
  68. package/dist/eval-server/utils/resolve-editor.d.ts +18 -0
  69. package/dist/eval-server/utils/resolve-editor.js +77 -0
  70. package/dist/eval-server/utils/resolve-editor.js.map +1 -0
  71. package/dist/eval-server/utils/scan-install-locations.d.ts +7 -0
  72. package/dist/eval-server/utils/scan-install-locations.js +20 -0
  73. package/dist/eval-server/utils/scan-install-locations.js.map +1 -1
  74. package/dist/eval-server/utils/which.d.ts +15 -0
  75. package/dist/eval-server/utils/which.js +76 -0
  76. package/dist/eval-server/utils/which.js.map +1 -0
  77. package/dist/eval-ui/assets/{CreateSkillPage-T0YWZWw-.js → CreateSkillPage-BmbvQEzE.js} +1 -1
  78. package/dist/eval-ui/assets/{FindSkillsPalette-KcFM32hZ.js → FindSkillsPalette-D0Zjhm31.js} +2 -2
  79. package/dist/eval-ui/assets/{SearchPaletteCore-EhBtr4Xx.js → SearchPaletteCore-EhcN1xEa.js} +1 -1
  80. package/dist/eval-ui/assets/SkillDetailPanel-B5J60ffv.js +1 -0
  81. package/dist/eval-ui/assets/{UpdateDropdown-pjFhHTi6.js → UpdateDropdown-Celf0_Cr.js} +1 -1
  82. package/dist/eval-ui/assets/index-BV7k6fdk.js +124 -0
  83. package/dist/eval-ui/assets/{index-BKAvJDDF.css → index-CKLqBL52.css} +1 -1
  84. package/dist/eval-ui/index.html +2 -2
  85. package/dist/index.js +47 -0
  86. package/dist/index.js.map +1 -1
  87. package/dist/installer/frontmatter.d.ts +26 -0
  88. package/dist/installer/frontmatter.js +90 -0
  89. package/dist/installer/frontmatter.js.map +1 -1
  90. package/dist/lib/github-fetch.d.ts +22 -0
  91. package/dist/lib/github-fetch.js +152 -0
  92. package/dist/lib/github-fetch.js.map +1 -0
  93. package/dist/lib/keychain.d.ts +41 -0
  94. package/dist/lib/keychain.js +232 -0
  95. package/dist/lib/keychain.js.map +1 -0
  96. package/dist/studio/types.d.ts +13 -0
  97. package/dist/utils/claude-plugin.d.ts +26 -0
  98. package/dist/utils/claude-plugin.js +60 -0
  99. package/dist/utils/claude-plugin.js.map +1 -1
  100. package/package.json +2 -1
  101. package/dist/eval-ui/assets/SkillDetailPanel-cyzLsLcK.js +0 -1
  102. package/dist/eval-ui/assets/index-C3S9iHnq.js +0 -122
@@ -0,0 +1,273 @@
1
+ // ---------------------------------------------------------------------------
2
+ // auth.ts — `vskill auth {login,status,logout}`.
3
+ //
4
+ // Device Flow (RFC 8628) against github.com directly:
5
+ // 1. POST https://github.com/login/device/code
6
+ // body: client_id=<VSKILL_GITHUB_CLIENT_ID>&scope=read:user
7
+ // resp: { device_code, user_code, verification_uri, interval, expires_in }
8
+ // 2. Display formatted user_code (XXXX-XXXX) + verification_uri.
9
+ // Optionally open the URL in the user's default browser.
10
+ // 3. Poll https://github.com/login/oauth/access_token every `interval` seconds
11
+ // body: client_id=...&device_code=...&grant_type=urn:ietf:params:oauth:grant-type:device_code
12
+ // resp: { access_token, ... } | { error: "authorization_pending" | "slow_down" | "expired_token" | "access_denied" }
13
+ // slow_down → bump interval +5s.
14
+ // authorization_pending → keep polling.
15
+ // expired_token / access_denied → abort.
16
+ // 4. GET https://api.github.com/user with Bearer token to confirm + print login.
17
+ // 5. Persist token via keychain.
18
+ //
19
+ // All network operations go through dependency-injected `fetchImpl` so tests
20
+ // never hit the real github.com.
21
+ // ---------------------------------------------------------------------------
22
+ import { getDefaultKeychain } from "../lib/keychain.js";
23
+ const DEVICE_CODE_URL = "https://github.com/login/device/code";
24
+ const TOKEN_URL = "https://github.com/login/oauth/access_token";
25
+ const USER_URL = "https://api.github.com/user";
26
+ const DEFAULT_SCOPE = "read:user";
27
+ function isPollError(r) {
28
+ return typeof r.error === "string";
29
+ }
30
+ function formatUserCode(code) {
31
+ // GitHub returns 8 alphanumerics like "ABCD1234" — render as ABCD-1234.
32
+ if (code.length === 8)
33
+ return `${code.slice(0, 4)}-${code.slice(4)}`;
34
+ return code;
35
+ }
36
+ function defaultSleep(ms) {
37
+ return new Promise((resolve) => setTimeout(resolve, ms));
38
+ }
39
+ async function postForm(fetchImpl, url, body, version) {
40
+ const params = new URLSearchParams(body);
41
+ return fetchImpl(url, {
42
+ method: "POST",
43
+ headers: {
44
+ Accept: "application/json",
45
+ "Content-Type": "application/x-www-form-urlencoded",
46
+ "User-Agent": `vskill/${version}`,
47
+ },
48
+ body: params.toString(),
49
+ });
50
+ }
51
+ async function getJson(fetchImpl, url, token, version) {
52
+ const res = await fetchImpl(url, {
53
+ method: "GET",
54
+ headers: {
55
+ Accept: "application/vnd.github+json",
56
+ Authorization: `Bearer ${token}`,
57
+ "User-Agent": `vskill/${version}`,
58
+ },
59
+ });
60
+ let body = null;
61
+ try {
62
+ body = await res.json();
63
+ }
64
+ catch {
65
+ body = null;
66
+ }
67
+ return { status: res.status, body };
68
+ }
69
+ async function loginCmd(deps) {
70
+ const { io, fetchImpl, sleep, version } = deps;
71
+ const keychain = deps.keychain ?? getDefaultKeychain();
72
+ const clientId = deps.clientId ?? process.env.VSKILL_GITHUB_CLIENT_ID ?? "";
73
+ if (!clientId) {
74
+ io.stderr.write("vskill auth login: VSKILL_GITHUB_CLIENT_ID is not set. " +
75
+ "Set it to the Skill Studio GitHub App's client_id, then retry.\n");
76
+ return 2;
77
+ }
78
+ // --- Step 1: device code -------------------------------------------------
79
+ let dcRes;
80
+ try {
81
+ dcRes = await postForm(fetchImpl, DEVICE_CODE_URL, {
82
+ client_id: clientId,
83
+ scope: DEFAULT_SCOPE,
84
+ }, version);
85
+ }
86
+ catch (err) {
87
+ io.stderr.write(`vskill auth login: network error contacting github.com (${err.message})\n`);
88
+ return 1;
89
+ }
90
+ if (!dcRes.ok) {
91
+ io.stderr.write(`vskill auth login: device-code request failed (HTTP ${dcRes.status})\n`);
92
+ return 1;
93
+ }
94
+ const dc = (await dcRes.json());
95
+ io.stdout.write(`\nTo authenticate, visit:\n ${dc.verification_uri}\n\n`);
96
+ io.stdout.write(`And enter the code:\n ${formatUserCode(dc.user_code)}\n\n`);
97
+ io.stdout.write(`(Waiting for authorization. This window will poll every ${dc.interval}s.)\n`);
98
+ if (io.openBrowser) {
99
+ try {
100
+ await io.openBrowser(dc.verification_uri);
101
+ }
102
+ catch {
103
+ // Non-fatal — the user can copy/paste the URL.
104
+ }
105
+ }
106
+ // --- Step 2: poll --------------------------------------------------------
107
+ let interval = Math.max(1, dc.interval);
108
+ const deadline = Date.now() + (dc.expires_in * 1000);
109
+ let accessToken = null;
110
+ while (Date.now() < deadline) {
111
+ await sleep(interval * 1000);
112
+ let pollRes;
113
+ try {
114
+ pollRes = await postForm(fetchImpl, TOKEN_URL, {
115
+ client_id: clientId,
116
+ device_code: dc.device_code,
117
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
118
+ }, version);
119
+ }
120
+ catch (err) {
121
+ io.stderr.write(`vskill auth login: network error during polling (${err.message})\n`);
122
+ return 1;
123
+ }
124
+ let body;
125
+ try {
126
+ body = (await pollRes.json());
127
+ }
128
+ catch {
129
+ io.stderr.write("vskill auth login: malformed token response from github.com\n");
130
+ return 1;
131
+ }
132
+ if (!isPollError(body) && body.access_token) {
133
+ accessToken = body.access_token;
134
+ break;
135
+ }
136
+ if (isPollError(body)) {
137
+ switch (body.error) {
138
+ case "authorization_pending":
139
+ continue;
140
+ case "slow_down":
141
+ interval += 5;
142
+ continue;
143
+ case "expired_token":
144
+ io.stderr.write("vskill auth login: device code expired before authorization. Please try again.\n");
145
+ return 1;
146
+ case "access_denied":
147
+ io.stderr.write("vskill auth login: authorization denied by user.\n");
148
+ return 1;
149
+ default:
150
+ io.stderr.write(`vskill auth login: unexpected error from github.com: ${body.error}\n`);
151
+ return 1;
152
+ }
153
+ }
154
+ }
155
+ if (!accessToken) {
156
+ io.stderr.write("vskill auth login: timed out waiting for authorization.\n");
157
+ return 1;
158
+ }
159
+ // --- Step 3: confirm via /user + persist ---------------------------------
160
+ const user = await getJson(fetchImpl, USER_URL, accessToken, version);
161
+ if (user.status !== 200 || !user.body || typeof user.body.login !== "string") {
162
+ io.stderr.write(`vskill auth login: token saved but /user verification failed (HTTP ${user.status})\n`);
163
+ keychain.setGitHubToken(accessToken);
164
+ return 1;
165
+ }
166
+ const login = user.body.login;
167
+ keychain.setGitHubToken(accessToken);
168
+ io.stdout.write(`\nLogged in as @${login}.\n`);
169
+ return 0;
170
+ }
171
+ async function statusCmd(args, deps) {
172
+ const { io, fetchImpl, version } = deps;
173
+ const keychain = deps.keychain ?? getDefaultKeychain();
174
+ const json = args.includes("--json");
175
+ const refresh = args.includes("--refresh") || args.includes("--validate");
176
+ const token = keychain.getGitHubToken();
177
+ if (!token) {
178
+ if (json) {
179
+ io.stdout.write(JSON.stringify({ loggedIn: false }) + "\n");
180
+ }
181
+ else {
182
+ io.stdout.write("Not logged in. Run `vskill auth login`.\n");
183
+ }
184
+ return 1;
185
+ }
186
+ // Default behavior: validate via /user (cheap, ~50ms) so the user knows the
187
+ // token still works. --json controls output shape; --refresh is accepted for
188
+ // clarity but in this MVP it has the same effect as the default path.
189
+ void refresh;
190
+ const user = await getJson(fetchImpl, USER_URL, token, version);
191
+ if (user.status === 401) {
192
+ if (json) {
193
+ io.stdout.write(JSON.stringify({ loggedIn: false, reason: "token_invalid" }) + "\n");
194
+ }
195
+ else {
196
+ io.stderr.write("Token is invalid or expired. Run `vskill auth login`.\n");
197
+ }
198
+ return 1;
199
+ }
200
+ if (user.status !== 200 || !user.body) {
201
+ if (json) {
202
+ io.stdout.write(JSON.stringify({ loggedIn: true, validated: false, status: user.status }) + "\n");
203
+ }
204
+ else {
205
+ io.stdout.write(`Token present but /user returned HTTP ${user.status}. Network or scope issue.\n`);
206
+ }
207
+ return 1;
208
+ }
209
+ const u = user.body;
210
+ if (json) {
211
+ io.stdout.write(JSON.stringify({ loggedIn: true, login: u.login, id: u.id }) + "\n");
212
+ }
213
+ else {
214
+ io.stdout.write(`Logged in as @${u.login} (id=${u.id}).\n`);
215
+ }
216
+ return 0;
217
+ }
218
+ async function logoutCmd(deps) {
219
+ const { io } = deps;
220
+ const keychain = deps.keychain ?? getDefaultKeychain();
221
+ const had = keychain.clearGitHubToken();
222
+ if (had) {
223
+ io.stdout.write("Logged out. GitHub token cleared from keychain.\n");
224
+ return 0;
225
+ }
226
+ io.stdout.write("Logged out. (No GitHub token was stored.)\n");
227
+ return 0;
228
+ }
229
+ function usage(io) {
230
+ io.stdout.write([
231
+ "Usage: vskill auth <subcommand>",
232
+ "",
233
+ "Subcommands:",
234
+ " login Sign in via GitHub Device Flow",
235
+ " status [--json] [--refresh] Show current GitHub identity",
236
+ " logout Clear stored GitHub credentials",
237
+ "",
238
+ ].join("\n"));
239
+ }
240
+ export async function authCommand(argv, deps) {
241
+ const fetchImpl = deps.fetchImpl ?? fetch;
242
+ const sleep = deps.sleep ?? defaultSleep;
243
+ const version = deps.version ?? "vskill";
244
+ const io = deps.io;
245
+ const sub = argv[0];
246
+ let exit = 0;
247
+ switch (sub) {
248
+ case "login":
249
+ exit = await loginCmd({ ...deps, fetchImpl, sleep, version });
250
+ break;
251
+ case "status":
252
+ exit = await statusCmd(argv.slice(1), { ...deps, fetchImpl, sleep: deps.sleep ?? defaultSleep, version });
253
+ break;
254
+ case "logout":
255
+ exit = await logoutCmd(deps);
256
+ break;
257
+ case undefined:
258
+ case "--help":
259
+ case "-h":
260
+ usage(io);
261
+ exit = sub ? 0 : 1;
262
+ break;
263
+ default:
264
+ io.stderr.write(`unknown subcommand: ${sub}\n`);
265
+ usage(io);
266
+ exit = 1;
267
+ break;
268
+ }
269
+ if (deps.io.exit)
270
+ deps.io.exit(exit);
271
+ return exit;
272
+ }
273
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -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,13 @@
1
+ export interface ConfirmPromptOptions {
2
+ /** When true, bypass all prompts and return true. */
3
+ yes?: boolean;
4
+ /** Override TTY detection (defaults to process.stdin.isTTY). */
5
+ stdinIsTTY?: boolean;
6
+ }
7
+ export declare function confirmPrompt(message: string, opts?: ConfirmPromptOptions): Promise<boolean>;
8
+ export declare function promptInput(message: string): Promise<string>;
9
+ /**
10
+ * Prompt the user to choose one of N labelled options. Returns the chosen
11
+ * index. Re-prompts on bad input.
12
+ */
13
+ export declare function promptChoice(message: string, labels: string[]): Promise<number>;