Skip to content

Commit 959080d

Browse files
committed
feat: add skill and MCP status-detection helpers
1 parent bfefda5 commit 959080d

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

src/commands/configureAiTools.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,75 @@ async function installForCopilot(
304304
}
305305
}
306306

307+
// ── Status detection ─────────────────────────────────────────────────────────
308+
309+
/**
310+
* Returns the set of skill dirNames already installed for the given IDE target.
311+
* Errors reading individual paths are silently treated as "not installed".
312+
*/
313+
async function readInstalledSkillDirNames(
314+
rootUri: vscode.Uri,
315+
ideTargetLabel: string,
316+
skills: SkillInfo[]
317+
): Promise<Set<string>> {
318+
const installed = new Set<string>();
319+
320+
if (ideTargetLabel === "VS Code (Copilot)") {
321+
try {
322+
const uri = vscode.Uri.joinPath(rootUri, ".github/copilot-instructions.md");
323+
const bytes = await vscode.workspace.fs.readFile(uri);
324+
const content = Buffer.from(bytes).toString("utf-8");
325+
for (const skill of skills) {
326+
if (content.includes(`## ${skill.name}`)) {
327+
installed.add(skill.dirName);
328+
}
329+
}
330+
} catch {
331+
// file not found — nothing installed
332+
}
333+
return installed;
334+
}
335+
336+
await Promise.all(
337+
skills.map(async (skill) => {
338+
try {
339+
const checkPath =
340+
ideTargetLabel === "Claude Code"
341+
? `.claude/skills/${skill.dirName}/SKILL.md`
342+
: `.cursor/rules/${skill.dirName}.mdc`;
343+
await vscode.workspace.fs.stat(vscode.Uri.joinPath(rootUri, checkPath));
344+
installed.add(skill.dirName);
345+
} catch {
346+
// not installed
347+
}
348+
})
349+
);
350+
return installed;
351+
}
352+
353+
/**
354+
* Returns the set of server keys already present in the MCP config file.
355+
* Returns an empty Set if the file doesn't exist or can't be parsed.
356+
*/
357+
async function readConfiguredMcpServerKeys(
358+
rootUri: vscode.Uri,
359+
mcpFilePath: string,
360+
rootKey: string
361+
): Promise<Set<string>> {
362+
try {
363+
const uri = vscode.Uri.joinPath(rootUri, mcpFilePath);
364+
const bytes = await vscode.workspace.fs.readFile(uri);
365+
const config = JSON.parse(Buffer.from(bytes).toString("utf-8"));
366+
const servers = config[rootKey];
367+
if (servers && typeof servers === "object") {
368+
return new Set(Object.keys(servers));
369+
}
370+
} catch {
371+
// file not found or invalid JSON
372+
}
373+
return new Set();
374+
}
375+
307376
// ── MCP Server definitions ────────────────────────────────────────────────────
308377

309378
const MCP_SERVERS: McpServerDef[] = [

0 commit comments

Comments
 (0)