runwork 0.5.1 → 0.6.1
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/dist/agents/__tests__/claude-code-stats.test.d.ts +1 -0
- package/dist/agents/__tests__/claude-code-stats.test.js +153 -0
- package/dist/agents/__tests__/claude-desktop-stats.test.d.ts +1 -0
- package/dist/agents/__tests__/claude-desktop-stats.test.js +280 -0
- package/dist/agents/__tests__/codex-stats.test.d.ts +1 -0
- package/dist/agents/__tests__/codex-stats.test.js +262 -0
- package/dist/agents/__tests__/cursor-stats.test.d.ts +1 -0
- package/dist/agents/__tests__/cursor-stats.test.js +183 -0
- package/dist/agents/__tests__/graceful-degradation.test.d.ts +1 -0
- package/dist/agents/__tests__/graceful-degradation.test.js +123 -0
- package/dist/agents/__tests__/instruction-hint.test.d.ts +1 -0
- package/dist/agents/__tests__/instruction-hint.test.js +69 -0
- package/dist/agents/__tests__/intro-skill.test.d.ts +1 -0
- package/dist/agents/__tests__/intro-skill.test.js +148 -0
- package/dist/agents/__tests__/schema-validation.test.d.ts +1 -0
- package/dist/agents/__tests__/schema-validation.test.js +212 -0
- package/dist/agents/claude-code.d.ts +16 -1
- package/dist/agents/claude-code.js +344 -21
- package/dist/agents/claude-desktop.d.ts +10 -1
- package/dist/agents/claude-desktop.js +250 -8
- package/dist/agents/cline.d.ts +13 -0
- package/dist/agents/cline.js +88 -0
- package/dist/agents/codex.d.ts +7 -2
- package/dist/agents/codex.js +130 -18
- package/dist/agents/cursor.d.ts +6 -1
- package/dist/agents/cursor.js +164 -7
- package/dist/agents/detect.js +30 -7
- package/dist/agents/gemini.d.ts +6 -3
- package/dist/agents/gemini.js +57 -20
- package/dist/agents/generic-adapter.d.ts +23 -0
- package/dist/agents/generic-adapter.js +106 -0
- package/dist/agents/intro-skill.d.ts +36 -0
- package/dist/agents/intro-skill.js +358 -0
- package/dist/agents/registry.d.ts +53 -0
- package/dist/agents/registry.js +219 -0
- package/dist/agents/types.d.ts +44 -1
- package/dist/agents/types.js +11 -4
- package/dist/agents/utils/instruction-hint.d.ts +11 -0
- package/dist/agents/utils/instruction-hint.js +62 -0
- package/dist/agents/utils/json-config.js +3 -3
- package/dist/agents/windsurf.d.ts +2 -0
- package/dist/agents/windsurf.js +26 -9
- package/dist/api/client.d.ts +85 -2
- package/dist/api/client.js +40 -10
- package/dist/auth/__tests__/login-flow.test.d.ts +1 -0
- package/dist/auth/__tests__/login-flow.test.js +125 -0
- package/dist/auth/login-flow.d.ts +16 -0
- package/dist/auth/login-flow.js +101 -1
- package/dist/commands/clone.d.ts +9 -1
- package/dist/commands/clone.js +40 -12
- package/dist/commands/deploy.js +27 -4
- package/dist/commands/dev.js +35 -1
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +82 -0
- package/dist/commands/info.js +6 -2
- package/dist/commands/init.d.ts +10 -2
- package/dist/commands/init.js +58 -15
- package/dist/commands/integrations.js +47 -10
- package/dist/commands/login.js +31 -4
- package/dist/commands/mcp.js +143 -15
- package/dist/commands/setup.js +47 -122
- package/dist/commands/skills.js +230 -12
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.js +398 -65
- package/dist/commands/welcome.js +6 -3
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/health/__tests__/checks.test.d.ts +1 -0
- package/dist/health/__tests__/checks.test.js +223 -0
- package/dist/health/checks.d.ts +20 -0
- package/dist/health/checks.js +392 -0
- package/dist/health/runner.d.ts +2 -0
- package/dist/health/runner.js +26 -0
- package/dist/health/types.d.ts +12 -0
- package/dist/health/types.js +1 -0
- package/dist/index.js +32 -0
- package/dist/sync/__tests__/change-detect.test.d.ts +1 -0
- package/dist/sync/__tests__/change-detect.test.js +123 -0
- package/dist/sync/__tests__/hash.test.d.ts +1 -0
- package/dist/sync/__tests__/hash.test.js +18 -0
- package/dist/sync/change-detect.d.ts +19 -0
- package/dist/sync/change-detect.js +136 -0
- package/dist/sync/conflict-ui.d.ts +5 -0
- package/dist/sync/conflict-ui.js +78 -0
- package/dist/sync/executor.d.ts +21 -0
- package/dist/sync/executor.js +98 -0
- package/dist/sync/hash.d.ts +1 -0
- package/dist/sync/hash.js +4 -0
- package/dist/sync/types.d.ts +24 -0
- package/dist/sync/types.js +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/ui/__tests__/banner.test.js +17 -1
- package/dist/ui/banner.d.ts +1 -1
- package/dist/ui/banner.js +27 -2
- package/dist/utils/__tests__/resolve.test.d.ts +1 -0
- package/dist/utils/__tests__/resolve.test.js +95 -0
- package/dist/utils/__tests__/sqlite.test.d.ts +1 -0
- package/dist/utils/__tests__/sqlite.test.js +77 -0
- package/dist/utils/agent-guidance.d.ts +32 -0
- package/dist/utils/agent-guidance.js +106 -0
- package/dist/utils/curl-parser.d.ts +1 -1
- package/dist/utils/curl-parser.js +144 -26
- package/dist/utils/fs.js +2 -2
- package/dist/utils/help-json.d.ts +56 -0
- package/dist/utils/help-json.js +85 -0
- package/dist/utils/resolve.d.ts +12 -0
- package/dist/utils/resolve.js +52 -0
- package/dist/utils/setup-state.d.ts +3 -0
- package/dist/utils/setup-state.js +19 -0
- package/dist/utils/sqlite.d.ts +7 -0
- package/dist/utils/sqlite.js +24 -0
- package/dist/utils/which.d.ts +6 -0
- package/dist/utils/which.js +18 -0
- package/package.json +7 -4
- package/dist/agents/copilot-cli.d.ts +0 -10
- package/dist/agents/copilot-cli.js +0 -46
- package/dist/agents/copilot-vscode.d.ts +0 -10
- package/dist/agents/copilot-vscode.js +0 -37
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON help output for AI agents.
|
|
3
|
+
*
|
|
4
|
+
* When --json is active (explicitly or via non-TTY), `runwork --help` and
|
|
5
|
+
* `runwork <command> --help` output a machine-readable command tree instead
|
|
6
|
+
* of Commander's human-readable text.
|
|
7
|
+
*
|
|
8
|
+
* This lets an agent discover the full CLI surface in a single call.
|
|
9
|
+
*/
|
|
10
|
+
function serializeOption(opt) {
|
|
11
|
+
const result = {
|
|
12
|
+
flags: opt.flags,
|
|
13
|
+
description: opt.description,
|
|
14
|
+
required: opt.required,
|
|
15
|
+
optional: opt.optional,
|
|
16
|
+
variadic: opt.variadic,
|
|
17
|
+
};
|
|
18
|
+
if (opt.defaultValue !== undefined)
|
|
19
|
+
result.defaultValue = opt.defaultValue;
|
|
20
|
+
if (opt.argChoices)
|
|
21
|
+
result.choices = opt.argChoices;
|
|
22
|
+
if (opt.envVar)
|
|
23
|
+
result.envVar = opt.envVar;
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
function serializeArgument(arg) {
|
|
27
|
+
const result = {
|
|
28
|
+
name: arg.name(),
|
|
29
|
+
description: arg.description,
|
|
30
|
+
required: arg.required,
|
|
31
|
+
variadic: arg.variadic,
|
|
32
|
+
};
|
|
33
|
+
if (arg.defaultValue !== undefined)
|
|
34
|
+
result.defaultValue = arg.defaultValue;
|
|
35
|
+
if (arg.argChoices)
|
|
36
|
+
result.choices = arg.argChoices;
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
function serializeCommand(cmd) {
|
|
40
|
+
const subcommands = cmd.commands
|
|
41
|
+
.filter((c) => !c._hidden)
|
|
42
|
+
.map(serializeCommand);
|
|
43
|
+
// Get command-level options (exclude inherited global options)
|
|
44
|
+
const options = cmd.options
|
|
45
|
+
.filter((o) => !o.hidden)
|
|
46
|
+
.map(serializeOption);
|
|
47
|
+
const registeredArguments = cmd.registeredArguments ?? [];
|
|
48
|
+
return {
|
|
49
|
+
name: cmd.name(),
|
|
50
|
+
description: cmd.description(),
|
|
51
|
+
aliases: cmd.aliases(),
|
|
52
|
+
usage: cmd.usage(),
|
|
53
|
+
options,
|
|
54
|
+
arguments: registeredArguments.map(serializeArgument),
|
|
55
|
+
subcommands,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Serialize the full command tree to a JSON-friendly structure.
|
|
60
|
+
*/
|
|
61
|
+
export function buildHelpJson(program) {
|
|
62
|
+
const globalOptions = program.options
|
|
63
|
+
.filter((o) => !o.hidden)
|
|
64
|
+
.map(serializeOption);
|
|
65
|
+
const commands = program.commands
|
|
66
|
+
.filter((c) => !c._hidden)
|
|
67
|
+
.map(serializeCommand);
|
|
68
|
+
return {
|
|
69
|
+
version: program.version() ?? 'unknown',
|
|
70
|
+
name: program.name(),
|
|
71
|
+
description: program.description(),
|
|
72
|
+
usage: program.usage(),
|
|
73
|
+
globalOptions,
|
|
74
|
+
commands,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Serialize a single command (for `runwork <cmd> --help --json`).
|
|
79
|
+
*/
|
|
80
|
+
export function buildCommandHelpJson(cmd, version) {
|
|
81
|
+
return {
|
|
82
|
+
version,
|
|
83
|
+
...serializeCommand(cmd),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ApiClient } from '../api/client.js';
|
|
2
|
+
import type { AppInfo, WorkspaceInfo } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a workspace by name or ID from the user's accessible workspaces.
|
|
5
|
+
* Tries exact ID match first, then case-insensitive name match.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveWorkspace(client: ApiClient, nameOrId: string): Promise<WorkspaceInfo>;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve an app by name or ID from the user's accessible apps.
|
|
10
|
+
* Tries exact ID match first, then case-insensitive name match.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveApp(client: ApiClient, nameOrId: string): Promise<AppInfo>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a workspace by name or ID from the user's accessible workspaces.
|
|
3
|
+
* Tries exact ID match first, then case-insensitive name match.
|
|
4
|
+
*/
|
|
5
|
+
export async function resolveWorkspace(client, nameOrId) {
|
|
6
|
+
const workspaces = await client.listWorkspaces();
|
|
7
|
+
if (workspaces.length === 0) {
|
|
8
|
+
console.error('No workspaces found. Create one at runwork.ai first.');
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
// Exact ID match
|
|
12
|
+
const byId = workspaces.find(w => w.id === nameOrId);
|
|
13
|
+
if (byId)
|
|
14
|
+
return byId;
|
|
15
|
+
// Case-insensitive name match
|
|
16
|
+
const lower = nameOrId.toLowerCase();
|
|
17
|
+
const byName = workspaces.filter(w => w.name.toLowerCase() === lower);
|
|
18
|
+
if (byName.length === 1)
|
|
19
|
+
return byName[0];
|
|
20
|
+
if (byName.length > 1) {
|
|
21
|
+
console.error(`Ambiguous workspace name "${nameOrId}". Matches: ${byName.map(w => `${w.name} (${w.id})`).join(', ')}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
console.error(`Workspace "${nameOrId}" not found. Available: ${workspaces.map(w => w.name).join(', ')}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve an app by name or ID from the user's accessible apps.
|
|
29
|
+
* Tries exact ID match first, then case-insensitive name match.
|
|
30
|
+
*/
|
|
31
|
+
export async function resolveApp(client, nameOrId) {
|
|
32
|
+
const apps = await client.listApps();
|
|
33
|
+
if (apps.length === 0) {
|
|
34
|
+
console.error('No apps found.');
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
// Exact ID match
|
|
38
|
+
const byId = apps.find(a => a.id === nameOrId);
|
|
39
|
+
if (byId)
|
|
40
|
+
return byId;
|
|
41
|
+
// Case-insensitive name match
|
|
42
|
+
const lower = nameOrId.toLowerCase();
|
|
43
|
+
const byName = apps.filter(a => a.name.toLowerCase() === lower);
|
|
44
|
+
if (byName.length === 1)
|
|
45
|
+
return byName[0];
|
|
46
|
+
if (byName.length > 1) {
|
|
47
|
+
console.error(`Ambiguous app name "${nameOrId}". Matches: ${byName.map(a => `${a.name} (${a.id})`).join(', ')}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
console.error(`App "${nameOrId}" not found. Available: ${apps.map(a => a.name).join(', ')}`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
/** Load setup state, checking project-level then user-level. */
|
|
5
|
+
export function loadSetupState() {
|
|
6
|
+
const projectPath = join(process.cwd(), '.runwork', 'setup.json');
|
|
7
|
+
const userPath = join(homedir(), '.runwork', 'setup.json');
|
|
8
|
+
for (const p of [projectPath, userPath]) {
|
|
9
|
+
if (existsSync(p)) {
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(readFileSync(p, 'utf-8'));
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query a SQLite database using better-sqlite3.
|
|
3
|
+
* Cross-platform, no CLI dependency.
|
|
4
|
+
* Opens database in readonly mode with a 5-second busy timeout.
|
|
5
|
+
* Returns empty string on any error (missing DB, locked, corrupted).
|
|
6
|
+
*/
|
|
7
|
+
export declare function querySqlite(dbPath: string, sql: string): string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
/**
|
|
3
|
+
* Query a SQLite database using better-sqlite3.
|
|
4
|
+
* Cross-platform, no CLI dependency.
|
|
5
|
+
* Opens database in readonly mode with a 5-second busy timeout.
|
|
6
|
+
* Returns empty string on any error (missing DB, locked, corrupted).
|
|
7
|
+
*/
|
|
8
|
+
export function querySqlite(dbPath, sql) {
|
|
9
|
+
let db = null;
|
|
10
|
+
try {
|
|
11
|
+
db = new Database(dbPath, { readonly: true, timeout: 5000 });
|
|
12
|
+
const rows = db.prepare(sql).all();
|
|
13
|
+
return rows.map(row => Object.values(row).join('|')).join('\n');
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
try {
|
|
20
|
+
db?.close();
|
|
21
|
+
}
|
|
22
|
+
catch { /* ignore close errors */ }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
|
+
import { platform } from 'os';
|
|
3
|
+
/**
|
|
4
|
+
* Cross-platform binary detection.
|
|
5
|
+
* Uses `which` on macOS/Linux, `where.exe` on Windows.
|
|
6
|
+
* Returns the resolved path on success, null if not found.
|
|
7
|
+
*/
|
|
8
|
+
export function whichBinary(name) {
|
|
9
|
+
try {
|
|
10
|
+
const cmd = platform() === 'win32' ? 'where.exe' : 'which';
|
|
11
|
+
const result = execFileSync(cmd, [name], { stdio: 'pipe' }).toString().trim();
|
|
12
|
+
// `where.exe` may return multiple lines; take the first
|
|
13
|
+
return result.split(/[\r\n]+/)[0].trim() || null;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "runwork",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "CLI for Runwork: develop, preview, and deploy Runwork apps from your local machine.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "Runwork <info@runwork.ai> (https://www.runwork.ai)",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"dev": "tsc --watch",
|
|
35
35
|
"typecheck": "tsc --noEmit",
|
|
36
36
|
"test": "vitest run",
|
|
37
|
+
"test:local": "RUNWORK_TEST_LOCAL_AGENTS=1 vitest run",
|
|
37
38
|
"prepublishOnly": "bun run prebuild && tsc",
|
|
38
39
|
"release": "npm publish && npm dist-tag add runwork@$(node -p \"require('./package.json').version\") next",
|
|
39
40
|
"release:binaries": "bun run scripts/release-binaries.ts",
|
|
@@ -42,16 +43,18 @@
|
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|
|
44
45
|
"@clack/prompts": "^1.1.0",
|
|
46
|
+
"better-sqlite3": "^12.8.0",
|
|
45
47
|
"chokidar": "^4.0.0",
|
|
46
48
|
"commander": "^13.0.0",
|
|
47
|
-
"curlconverter": "^4.12.0",
|
|
48
49
|
"fflate": "^0.8.2",
|
|
49
50
|
"open": "^10.0.0",
|
|
50
|
-
"picocolors": "^1.1.1"
|
|
51
|
+
"picocolors": "^1.1.1",
|
|
52
|
+
"smol-toml": "^1.6.1"
|
|
51
53
|
},
|
|
52
54
|
"devDependencies": {
|
|
53
|
-
"
|
|
55
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
54
56
|
"@types/node": "^22.0.0",
|
|
57
|
+
"typescript": "^5.7.0",
|
|
55
58
|
"vitest": "^3.2.0"
|
|
56
59
|
},
|
|
57
60
|
"engines": {
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { AgentAdapter, McpServerEntry, SkillFile } from './types.js';
|
|
2
|
-
export declare class CopilotCliAdapter implements AgentAdapter {
|
|
3
|
-
name: string;
|
|
4
|
-
slug: string;
|
|
5
|
-
detect(): Promise<boolean>;
|
|
6
|
-
supportsMcpScope(_scope: 'project' | 'user'): boolean;
|
|
7
|
-
supportsSkills(): boolean;
|
|
8
|
-
writeMcpServers(servers: McpServerEntry[], scope: 'project' | 'user'): Promise<void>;
|
|
9
|
-
writeSkills(_skills: SkillFile[], _scope: 'project' | 'user'): Promise<void>;
|
|
10
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from 'child_process';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
import { mergeJsonMcpServers } from './utils/json-config.js';
|
|
5
|
-
export class CopilotCliAdapter {
|
|
6
|
-
name = 'GitHub Copilot CLI';
|
|
7
|
-
slug = 'copilot-cli';
|
|
8
|
-
async detect() {
|
|
9
|
-
try {
|
|
10
|
-
execFileSync('which', ['copilot'], { stdio: 'pipe' });
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
try {
|
|
15
|
-
execFileSync('gh', ['copilot', '--version'], { stdio: 'pipe' });
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
supportsMcpScope(_scope) {
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
supportsSkills() {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
async writeMcpServers(servers, scope) {
|
|
30
|
-
const filePath = scope === 'project'
|
|
31
|
-
? join(process.cwd(), '.copilot', 'mcp-config.json')
|
|
32
|
-
: join(homedir(), '.copilot', 'mcp-config.json');
|
|
33
|
-
const entries = {};
|
|
34
|
-
for (const s of servers) {
|
|
35
|
-
entries[s.name] = {
|
|
36
|
-
type: 'http',
|
|
37
|
-
url: s.url,
|
|
38
|
-
...(s.headers ? { headers: s.headers } : {}),
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
mergeJsonMcpServers(filePath, entries, 'mcpServers');
|
|
42
|
-
}
|
|
43
|
-
async writeSkills(_skills, _scope) {
|
|
44
|
-
// Not supported
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { AgentAdapter, McpServerEntry, SkillFile } from './types.js';
|
|
2
|
-
export declare class CopilotVscodeAdapter implements AgentAdapter {
|
|
3
|
-
name: string;
|
|
4
|
-
slug: string;
|
|
5
|
-
detect(): Promise<boolean>;
|
|
6
|
-
supportsMcpScope(scope: 'project' | 'user'): boolean;
|
|
7
|
-
supportsSkills(): boolean;
|
|
8
|
-
writeMcpServers(servers: McpServerEntry[], _scope: 'project' | 'user'): Promise<void>;
|
|
9
|
-
writeSkills(_skills: SkillFile[], _scope: 'project' | 'user'): Promise<void>;
|
|
10
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from 'child_process';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { mergeJsonMcpServers } from './utils/json-config.js';
|
|
4
|
-
export class CopilotVscodeAdapter {
|
|
5
|
-
name = 'GitHub Copilot (VS Code)';
|
|
6
|
-
slug = 'copilot-vscode';
|
|
7
|
-
async detect() {
|
|
8
|
-
try {
|
|
9
|
-
const output = execFileSync('code', ['--list-extensions'], { stdio: 'pipe', encoding: 'utf-8' });
|
|
10
|
-
return output.includes('GitHub.copilot');
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
supportsMcpScope(scope) {
|
|
17
|
-
return scope === 'project';
|
|
18
|
-
}
|
|
19
|
-
supportsSkills() {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
async writeMcpServers(servers, _scope) {
|
|
23
|
-
const filePath = join(process.cwd(), '.vscode', 'mcp.json');
|
|
24
|
-
const entries = {};
|
|
25
|
-
for (const s of servers) {
|
|
26
|
-
entries[s.name] = {
|
|
27
|
-
type: 'http',
|
|
28
|
-
url: s.url,
|
|
29
|
-
...(s.headers ? { headers: s.headers } : {}),
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
mergeJsonMcpServers(filePath, entries, 'servers');
|
|
33
|
-
}
|
|
34
|
-
async writeSkills(_skills, _scope) {
|
|
35
|
-
// Not supported
|
|
36
|
-
}
|
|
37
|
-
}
|