Skip to content
Closed
6 changes: 3 additions & 3 deletions docs/src/content/docs/guides/vscode-plugin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ The Archgate VS Code plugin gives AI agents working in [VS Code](https://code.vi

## How it works

VS Code supports **agent plugins** installed from git-based marketplaces. The Archgate plugin is served from a git repository at `plugins.archgate.dev/archgate-vscode.git`. When you add this marketplace to your VS Code user settings, VS Code discovers and installs the plugin automatically.
VS Code supports **agent plugins** installed from git-based marketplaces. The Archgate plugin is served from a git repository at `plugins.archgate.dev/archgate.git`. When you add this marketplace to your VS Code user settings, VS Code discovers and installs the plugin automatically.

The plugin is served in VS Code Copilot's native `.github/plugin/` manifest format, separate from the Claude Code `.claude-plugin/` format.
The plugin uses the same format as Claude Code plugins (`.claude-plugin/plugin.json`), which VS Code's agent plugin system recognizes natively.

## Installation

Expand Down Expand Up @@ -88,7 +88,7 @@ The user-level marketplace setting (added to your `settings.json`):
```json
{
"chat.plugins.marketplaces": [
"https://<github-user>:<token>@plugins.archgate.dev/archgate-vscode.git"
"https://<github-user>:<token>@plugins.archgate.dev/archgate.git"
]
}
```
Expand Down
4 changes: 2 additions & 2 deletions docs/src/content/docs/pt-br/guides/vscode-plugin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ O plugin Archgate para VS Code oferece aos agentes de IA que trabalham no [VS Co

## Como funciona

O VS Code suporta **plugins de agente** instalados a partir de marketplaces baseados em git. O plugin Archgate é servido a partir de um repositório git em `plugins.archgate.dev/archgate-vscode.git`. Quando você adiciona esse marketplace às suas configurações de usuário do VS Code, o VS Code descobre e instala o plugin automaticamente.
O VS Code suporta **plugins de agente** instalados a partir de marketplaces baseados em git. O plugin Archgate é servido a partir de um repositório git em `plugins.archgate.dev/archgate.git`. Quando você adiciona esse marketplace às suas configurações de usuário do VS Code, o VS Code descobre e instala o plugin automaticamente.

O plugin usa o mesmo formato dos plugins do Claude Code (`.claude-plugin/plugin.json`), que o sistema de plugins de agente do VS Code reconhece nativamente.

Expand Down Expand Up @@ -88,7 +88,7 @@ A configuração do marketplace no nível de usuário (adicionada ao seu `settin
```json
{
"chat.plugins.marketplaces": [
"https://<github-user>:<token>@plugins.archgate.dev/archgate-vscode.git"
"https://<github-user>:<token>@plugins.archgate.dev/archgate.git"
]
}
```
Expand Down
67 changes: 62 additions & 5 deletions src/helpers/copilot-settings.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,77 @@
import { join } from "node:path";
import { existsSync, mkdirSync } from "node:fs";

/**
* MCP server configuration that archgate injects for Copilot CLI.
*
* Copilot CLI uses the same `.github/copilot/mcp.json` format for MCP servers
* and supports git-based plugin repositories via `copilot plugin install`.
*/
export const ARCHGATE_COPILOT_MCP_CONFIG = {
mcpServers: {
archgate: {
command: "archgate",
args: ["mcp"],
},
},
} as const;

type CopilotMcpConfig = Record<string, unknown>;

/**
* Pure, additive merge of archgate MCP server config into existing Copilot MCP config.
*
* - Preserves all existing MCP server entries
* - Adds the archgate server only if not already present
*/
export function mergeCopilotMcpConfig(
existing: CopilotMcpConfig,
archgate: typeof ARCHGATE_COPILOT_MCP_CONFIG
): CopilotMcpConfig {
const existingServers =
typeof existing.mcpServers === "object" &&
existing.mcpServers !== null &&
!Array.isArray(existing.mcpServers)
? (existing.mcpServers as Record<string, unknown>)
: {};

return {
...existing,
mcpServers: {
...existingServers,
...archgate.mcpServers,
},
};
}

/**
* Configure Copilot CLI settings for archgate integration.
*
* Creates the `.github/copilot/` directory if it does not exist.
* Plugin installation is handled separately via `archgate init --install-plugin`.
* Creates/updates `.github/copilot/mcp.json` with archgate MCP server.
*
* @returns Absolute path to the `.github/copilot/` directory.
* @returns Absolute path to the MCP config file.
*/
export function configureCopilotSettings(projectRoot: string): string {
export async function configureCopilotSettings(
projectRoot: string
): Promise<string> {
const copilotDir = join(projectRoot, ".github", "copilot");
const mcpConfigPath = join(copilotDir, "mcp.json");

// Read existing MCP config or start with empty object
let existing: CopilotMcpConfig = {};
if (existsSync(mcpConfigPath)) {
const content = await Bun.file(mcpConfigPath).text();
existing = JSON.parse(content) as CopilotMcpConfig;
}

const merged = mergeCopilotMcpConfig(existing, ARCHGATE_COPILOT_MCP_CONFIG);

// Ensure directories exist
if (!existsSync(copilotDir)) {
mkdirSync(copilotDir, { recursive: true });
}

return copilotDir;
await Bun.write(mcpConfigPath, JSON.stringify(merged, null, 2) + "\n");

return mcpConfigPath;
}
4 changes: 2 additions & 2 deletions src/helpers/init-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ async function configureEditorSettings(
case "cursor":
return configureCursorSettings(projectRoot);
case "vscode": {
// VS Code: marketplace URL to user settings if logged in
// VS Code: .vscode/mcp.json always, marketplace URL to user settings if logged in
const { loadCredentials } = await import("./auth");
const creds = await loadCredentials();
const marketplaceUrl = creds
? (await import("./plugin-install")).buildVscodeMarketplaceUrl(creds)
? (await import("./plugin-install")).buildMarketplaceUrl(creds)
: undefined;
return configureVscodeSettings(projectRoot, marketplaceUrl);
}
Expand Down
10 changes: 0 additions & 10 deletions src/helpers/plugin-install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,6 @@ export function buildMarketplaceUrl(credentials: StoredCredentials): string {
return `https://${credentials.github_user}:${credentials.token}@plugins.archgate.dev/archgate.git`;
}

/**
* Build the authenticated git marketplace URL for VS Code plugin installation.
* VS Code Copilot uses the .github/plugin/ manifest format, served from a separate repo.
*/
export function buildVscodeMarketplaceUrl(
credentials: StoredCredentials
): string {
return `https://${credentials.github_user}:${credentials.token}@plugins.archgate.dev/archgate-vscode.git`;
}

/**
* Check whether the `claude` CLI is available on the system PATH.
*/
Expand Down
64 changes: 60 additions & 4 deletions src/helpers/vscode-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,51 @@ import { join } from "node:path";
import { existsSync, mkdirSync } from "node:fs";
import { homedir } from "node:os";

/**
* MCP server configuration that archgate injects into .vscode/mcp.json.
*
* VS Code uses a dedicated `.vscode/mcp.json` file for MCP server registration
* (not `.vscode/settings.json`). The `servers` key format is defined by VS Code's
* MCP configuration spec.
*/
export const ARCHGATE_VSCODE_MCP_CONFIG = {
servers: {
archgate: {
command: "archgate",
args: ["mcp"],
},
},
} as const;

type VscodeMcpConfig = Record<string, unknown>;
type VscodeUserSettings = Record<string, unknown>;

/**
* Pure, additive merge of archgate MCP server config into existing VS Code MCP config.
*
* - Preserves all existing MCP server entries
* - Adds the archgate server (overwrites if already present)
*/
export function mergeVscodeMcpConfig(
existing: VscodeMcpConfig,
archgate: typeof ARCHGATE_VSCODE_MCP_CONFIG
): VscodeMcpConfig {
const existingServers =
typeof existing.servers === "object" &&
existing.servers !== null &&
!Array.isArray(existing.servers)
? (existing.servers as Record<string, unknown>)
: {};

return {
...existing,
servers: {
...existingServers,
...archgate.servers,
},
};
}

/**
* VS Code's built-in default marketplaces for `chat.plugins.marketplaces`.
*
Expand Down Expand Up @@ -85,27 +128,40 @@ export function getVscodeUserSettingsPath(): string {
/**
* Configure VS Code settings for archgate integration.
*
* If `marketplaceUrl` is provided, adds it to `chat.plugins.marketplaces` in
* the VS Code user-level settings.json (application-scoped — cannot be set per workspace).
* 1. Creates/updates `.vscode/mcp.json` (workspace-level) with the Archgate MCP server.
* 2. If `marketplaceUrl` is provided, adds it to `chat.plugins.marketplaces` in
* the VS Code user-level settings.json (application-scoped — cannot be set per workspace).
*
* @returns Absolute path to the .vscode/ directory.
* @returns Absolute path to the workspace MCP config file.
*/
export async function configureVscodeSettings(
projectRoot: string,
marketplaceUrl?: string
): Promise<string> {
const vscodeDir = join(projectRoot, ".vscode");
const mcpConfigPath = join(vscodeDir, "mcp.json");

// --- Workspace: .vscode/mcp.json ---
let existing: VscodeMcpConfig = {};
if (existsSync(mcpConfigPath)) {
const content = await Bun.file(mcpConfigPath).text();
existing = Bun.JSONC.parse(content) as VscodeMcpConfig;
}

const merged = mergeVscodeMcpConfig(existing, ARCHGATE_VSCODE_MCP_CONFIG);

if (!existsSync(vscodeDir)) {
mkdirSync(vscodeDir, { recursive: true });
}

await Bun.write(mcpConfigPath, JSON.stringify(merged, null, 2) + "\n");

// --- User-level: chat.plugins.marketplaces ---
if (marketplaceUrl) {
await addMarketplaceToUserSettings(marketplaceUrl);
}

return vscodeDir;
return mcpConfigPath;
}

/**
Expand Down
Loading
Loading