From 69e413b9e2e107a42d5a4e23d11375c62b8707b3 Mon Sep 17 00:00:00 2001 From: Rhuan Barreto Date: Mon, 23 Mar 2026 22:38:43 +0100 Subject: [PATCH 1/4] feat: add VS Code extension install via `plugin install --editor vscode` Downloads the .vsix from the plugins API and installs it via `code --install-extension`, with a manual fallback when the code CLI is unavailable. Extracts a shared downloadPluginAsset helper to deduplicate fetch logic between cursor and vscode installs. --- src/commands/plugin/install.ts | 27 +++++--- src/helpers/plugin-install.ts | 93 +++++++++++++++++++--------- tests/helpers/plugin-install.test.ts | 8 +++ 3 files changed, 89 insertions(+), 39 deletions(-) diff --git a/src/commands/plugin/install.ts b/src/commands/plugin/install.ts index 0719d17f..6281f32f 100644 --- a/src/commands/plugin/install.ts +++ b/src/commands/plugin/install.ts @@ -13,10 +13,11 @@ import { installClaudePlugin, installCopilotPlugin, installCursorPlugin, + installVscodeExtension, isClaudeCliAvailable, isCopilotCliAvailable, + isVscodeCliAvailable, } from "../../helpers/plugin-install"; -import { configureVscodeSettings } from "../../helpers/vscode-settings"; const editorOption = new Option("--editor ", "target editor") .choices(["claude", "cursor", "vscode", "copilot"] as const) @@ -93,15 +94,21 @@ export function registerPluginInstallCommand(plugin: Command) { } case "vscode": { - const url = buildVscodeMarketplaceUrl(); - await configureVscodeSettings( - findProjectRoot() ?? process.cwd(), - url - ); - logInfo( - `Archgate plugin configured for ${label}.`, - "Marketplace URL added to VS Code user settings." - ); + if (await isVscodeCliAvailable()) { + await installVscodeExtension(credentials.token); + logInfo(`Archgate extension installed for ${label}.`); + } else { + logWarn( + "VS Code CLI (`code`) not found. To install the extension manually, run:" + ); + console.log( + ` ${styleText("bold", "curl")} -H "Authorization: Bearer " https://plugins.archgate.dev/api/vscode -o archgate.vsix` + ); + console.log( + ` ${styleText("bold", "code")} --install-extension archgate.vsix` + ); + console.log(` rm archgate.vsix`); + } break; } } diff --git a/src/helpers/plugin-install.ts b/src/helpers/plugin-install.ts index 66f54514..6f80e128 100644 --- a/src/helpers/plugin-install.ts +++ b/src/helpers/plugin-install.ts @@ -1,16 +1,10 @@ -/** - * plugin-install.ts — Download and install the archgate plugin for supported editors. - * - * - Claude Code: auto-installs via `claude` CLI, or prints manual commands as fallback - * - VS Code: marketplace URL for manual user-settings configuration (application-scoped) - * - Copilot CLI: auto-installs via `copilot` CLI, or prints manual commands as fallback - * - Cursor: downloads cursor.tar.gz from the plugins service and extracts it - */ +/** Download and install the archgate plugin for supported editors. */ import { mkdirSync, unlinkSync } from "node:fs"; import { join } from "node:path"; import { logDebug } from "./log"; +import { internalPath } from "./paths"; import { resolveCommand } from "./platform"; const PLUGINS_API = "https://plugins.archgate.dev"; @@ -104,18 +98,15 @@ export async function installClaudePlugin(): Promise { } // --------------------------------------------------------------------------- -// Cursor — download and extract plugin bundle +// Shared — authenticated asset download // --------------------------------------------------------------------------- -/** - * Download the cursor.tar.gz from the plugins service and extract it to the project root. - * Creates/overwrites .cursor/ folder contents with the pre-built agent and skills. - */ -export async function installCursorPlugin( - projectRoot: string, +/** Download a plugin asset from the plugins API with Bearer auth. */ +async function downloadPluginAsset( + path: string, token: string -): Promise { - const response = await fetch(`${PLUGINS_API}/api/cursor`, { +): Promise { + const response = await fetch(`${PLUGINS_API}${path}`, { headers: { Authorization: `Bearer ${token}`, "User-Agent": "archgate-cli" }, signal: AbortSignal.timeout(30_000), redirect: "error", @@ -123,28 +114,32 @@ export async function installCursorPlugin( if (response.status === 401) { throw new Error( - "Plugin download unauthorized. Your token may have expired — run `archgate login refresh`." + "Download unauthorized. Your token may have expired — run `archgate login refresh`." ); } - if (!response.ok) { throw new Error( - `Plugin download failed (HTTP ${response.status}). Try again later.` + `Download failed (HTTP ${response.status}). Try again later.` ); } - const tarGzBuffer = await response.arrayBuffer(); + return response.arrayBuffer(); +} - logDebug( - `Downloaded cursor plugin archive (${Math.round(tarGzBuffer.byteLength / 1024)} KB)` - ); +// --------------------------------------------------------------------------- +// Cursor — download and extract plugin bundle +// --------------------------------------------------------------------------- - const extractedFiles = await extractTarGz( - new Uint8Array(tarGzBuffer), - projectRoot +/** Download cursor.tar.gz and extract it to the project root. */ +export async function installCursorPlugin( + projectRoot: string, + token: string +): Promise { + const buffer = await downloadPluginAsset("/api/cursor", token); + logDebug( + `Downloaded cursor plugin archive (${Math.round(buffer.byteLength / 1024)} KB)` ); - - return extractedFiles; + return extractTarGz(new Uint8Array(buffer), projectRoot); } // --------------------------------------------------------------------------- @@ -195,6 +190,46 @@ export async function installCopilotPlugin(): Promise { } } +// --------------------------------------------------------------------------- +// VS Code — download .vsix and install via `code` CLI +// --------------------------------------------------------------------------- + +/** + * Check whether the `code` CLI is available on the system PATH. + * On WSL, also checks for `code.exe` (Windows-side installation). + */ +export async function isVscodeCliAvailable(): Promise { + const resolved = await resolveCommand("code"); + return resolved !== null; +} + +/** Download the .vsix from the plugins service and install via `code` CLI. */ +export async function installVscodeExtension(token: string): Promise { + const vsixPath = internalPath("archgate.vsix"); + const buffer = await downloadPluginAsset("/api/vscode", token); + logDebug( + `Downloaded VS Code extension (${Math.round(buffer.byteLength / 1024)} KB)` + ); + await Bun.write(vsixPath, buffer); + + try { + const codeCmd = (await resolveCommand("code")) ?? "code"; + logDebug("Installing VS Code extension via code CLI"); + const result = await run([codeCmd, "--install-extension", vsixPath]); + if (result.exitCode !== 0) { + throw new Error( + `code --install-extension failed (exit ${result.exitCode})` + ); + } + } finally { + try { + unlinkSync(vsixPath); + } catch { + // Ignore cleanup errors + } + } +} + // --------------------------------------------------------------------------- // Shared — tar extraction helper // --------------------------------------------------------------------------- diff --git a/tests/helpers/plugin-install.test.ts b/tests/helpers/plugin-install.test.ts index 24eb8652..a521fb1d 100644 --- a/tests/helpers/plugin-install.test.ts +++ b/tests/helpers/plugin-install.test.ts @@ -5,6 +5,7 @@ import { buildVscodeMarketplaceUrl, isClaudeCliAvailable, isCopilotCliAvailable, + isVscodeCliAvailable, } from "../../src/helpers/plugin-install"; describe("plugin-install", () => { @@ -59,4 +60,11 @@ describe("plugin-install", () => { expect(result === true || result === false).toBe(true); }); }); + + describe("isVscodeCliAvailable", () => { + test("returns a boolean", async () => { + const result = await isVscodeCliAvailable(); + expect(typeof result).toBe("boolean"); + }); + }); }); From 1bed17704458c469beafb42a471d8aeb40c4043c Mon Sep 17 00:00:00 2001 From: Rhuan Barreto Date: Mon, 23 Mar 2026 22:44:27 +0100 Subject: [PATCH 2/4] fix: keep marketplace URL config alongside vscode extension install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VS Code extension is additive — configure the marketplace URL in VS Code user settings first, then download and install the .vsix extension on top. --- src/commands/plugin/install.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/commands/plugin/install.ts b/src/commands/plugin/install.ts index 6281f32f..d8088d94 100644 --- a/src/commands/plugin/install.ts +++ b/src/commands/plugin/install.ts @@ -18,6 +18,7 @@ import { isCopilotCliAvailable, isVscodeCliAvailable, } from "../../helpers/plugin-install"; +import { configureVscodeSettings } from "../../helpers/vscode-settings"; const editorOption = new Option("--editor ", "target editor") .choices(["claude", "cursor", "vscode", "copilot"] as const) @@ -94,6 +95,16 @@ export function registerPluginInstallCommand(plugin: Command) { } case "vscode": { + const url = buildVscodeMarketplaceUrl(); + await configureVscodeSettings( + findProjectRoot() ?? process.cwd(), + url + ); + logInfo( + `Archgate plugin configured for ${label}.`, + "Marketplace URL added to VS Code user settings." + ); + if (await isVscodeCliAvailable()) { await installVscodeExtension(credentials.token); logInfo(`Archgate extension installed for ${label}.`); From fbbfd0f5b1b3101c492e301e822dacf4de462094 Mon Sep 17 00:00:00 2001 From: Rhuan Barreto Date: Mon, 23 Mar 2026 22:48:25 +0100 Subject: [PATCH 3/4] docs: document VS Code extension install in plugin guides and CLI reference Updates both English and Portuguese docs to reflect that `archgate plugin install --editor vscode` now downloads and installs the .vsix extension alongside the marketplace URL configuration. Adds manual installation instructions with curl + code CLI. --- .../src/content/docs/guides/vscode-plugin.mdx | 24 +++++++++++++++---- .../docs/pt-br/guides/vscode-plugin.mdx | 24 +++++++++++++++---- .../docs/pt-br/reference/cli-commands.mdx | 2 +- .../content/docs/reference/cli-commands.mdx | 2 +- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/docs/src/content/docs/guides/vscode-plugin.mdx b/docs/src/content/docs/guides/vscode-plugin.mdx index 09cd038b..62e10ca1 100644 --- a/docs/src/content/docs/guides/vscode-plugin.mdx +++ b/docs/src/content/docs/guides/vscode-plugin.mdx @@ -43,6 +43,7 @@ If you are already logged in, this command: 1. Creates the `.archgate/` governance directory (ADRs, lint rules) 2. Adds the authenticated marketplace URL to your VS Code **user settings** +3. Downloads and installs the Archgate VS Code extension (`.vsix`) if the `code` CLI is available The `chat.plugins.marketplaces` setting is application-scoped in VS Code, so it cannot be set per-workspace. The CLI automatically writes it to your user-level `settings.json`: @@ -68,12 +69,15 @@ archgate plugin install --editor vscode The command creates or updates the following: -| File | Scope | Purpose | -| -------------------- | ----- | ------------------------------------------------------ | -| User `settings.json` | User | `chat.plugins.marketplaces` with the authenticated URL | +| File | Scope | Purpose | +| -------------------- | ----------- | ------------------------------------------------------ | +| User `settings.json` | User | `chat.plugins.marketplaces` with the authenticated URL | +| Archgate extension | Application | VS Code extension installed via `.vsix` | The user settings file is merged additively -- existing settings are never overwritten. VS Code's built-in default marketplaces (`github/copilot-plugins`, `github/awesome-copilot`) are preserved when the key is set for the first time. +The VS Code extension is downloaded from the Archgate plugins service and installed via `code --install-extension`. If the `code` CLI is not available, manual installation instructions are printed. + The user-level marketplace setting (added to your `settings.json`): ```json @@ -86,7 +90,19 @@ The user-level marketplace setting (added to your `settings.json`): ### Manual setup -If you prefer not to let the CLI modify your user settings, you can add the marketplace URL manually. Open VS Code's user settings JSON (`Ctrl+Shift+P` → "Preferences: Open User Settings (JSON)") and add the `chat.plugins.marketplaces` entry shown above. You can find your authenticated URL by running `archgate login` and checking `~/.archgate/credentials`. +If you prefer not to let the CLI modify your user settings, you can set things up manually: + +**Marketplace URL:** Open VS Code's user settings JSON (`Ctrl+Shift+P` → "Preferences: Open User Settings (JSON)") and add the `chat.plugins.marketplaces` entry shown above. You can find your authenticated URL by running `archgate login` and checking `~/.archgate/credentials`. + +**Extension:** Download and install the `.vsix` file directly: + +```bash +curl -H "Authorization: Bearer " https://plugins.archgate.dev/api/vscode -o archgate.vsix +code --install-extension archgate.vsix +rm archgate.vsix +``` + +Replace `` with your archgate token from `~/.archgate/credentials`. ## What the plugin provides diff --git a/docs/src/content/docs/pt-br/guides/vscode-plugin.mdx b/docs/src/content/docs/pt-br/guides/vscode-plugin.mdx index ac56b3fc..a39a701f 100644 --- a/docs/src/content/docs/pt-br/guides/vscode-plugin.mdx +++ b/docs/src/content/docs/pt-br/guides/vscode-plugin.mdx @@ -43,6 +43,7 @@ Se você já estiver logado, este comando: 1. Cria o diretório de governança `.archgate/` (ADRs, regras de lint) 2. Adiciona a URL autenticada do marketplace nas suas **configurações de usuário** do VS Code +3. Baixa e instala a extensão Archgate para VS Code (`.vsix`) se o CLI `code` estiver disponível A configuração `chat.plugins.marketplaces` tem escopo de aplicação no VS Code, então não pode ser definida por workspace. O CLI escreve automaticamente no seu `settings.json` de nível de usuário: @@ -68,12 +69,15 @@ archgate plugin install --editor vscode O comando cria ou atualiza o seguinte: -| Arquivo | Escopo | Propósito | -| -------------------------- | ------- | ------------------------------------------------- | -| `settings.json` do usuário | Usuário | `chat.plugins.marketplaces` com a URL autenticada | +| Arquivo | Escopo | Propósito | +| -------------------------- | --------- | ------------------------------------------------- | +| `settings.json` do usuário | Usuário | `chat.plugins.marketplaces` com a URL autenticada | +| Extensão Archgate | Aplicação | Extensão VS Code instalada via `.vsix` | O arquivo de configurações de usuário é mesclado de forma aditiva -- configurações existentes nunca são sobrescritas. Os marketplaces padrão do VS Code (`github/copilot-plugins`, `github/awesome-copilot`) são preservados quando a chave é definida pela primeira vez. +A extensão do VS Code é baixada do serviço de plugins do Archgate e instalada via `code --install-extension`. Se o CLI `code` não estiver disponível, instruções de instalação manual são exibidas. + A configuração do marketplace no nível de usuário (adicionada ao seu `settings.json`): ```json @@ -86,7 +90,19 @@ A configuração do marketplace no nível de usuário (adicionada ao seu `settin ### Configuração manual -Se preferir não deixar o CLI modificar suas configurações de usuário, você pode adicionar a URL do marketplace manualmente. Abra o JSON de configurações de usuário do VS Code (`Ctrl+Shift+P` → "Preferences: Open User Settings (JSON)") e adicione a entrada `chat.plugins.marketplaces` mostrada acima. Você pode encontrar sua URL autenticada executando `archgate login` e verificando `~/.archgate/credentials`. +Se preferir não deixar o CLI modificar suas configurações, você pode configurar manualmente: + +**URL do marketplace:** Abra o JSON de configurações de usuário do VS Code (`Ctrl+Shift+P` → "Preferences: Open User Settings (JSON)") e adicione a entrada `chat.plugins.marketplaces` mostrada acima. Você pode encontrar sua URL autenticada executando `archgate login` e verificando `~/.archgate/credentials`. + +**Extensão:** Baixe e instale o arquivo `.vsix` diretamente: + +```bash +curl -H "Authorization: Bearer " https://plugins.archgate.dev/api/vscode -o archgate.vsix +code --install-extension archgate.vsix +rm archgate.vsix +``` + +Substitua `` pelo seu token archgate de `~/.archgate/credentials`. ## O que o plugin oferece diff --git a/docs/src/content/docs/pt-br/reference/cli-commands.mdx b/docs/src/content/docs/pt-br/reference/cli-commands.mdx index b72b0d17..88b81275 100644 --- a/docs/src/content/docs/pt-br/reference/cli-commands.mdx +++ b/docs/src/content/docs/pt-br/reference/cli-commands.mdx @@ -246,7 +246,7 @@ O comportamento de instalação varia por editor: - **Claude Code:** Instala automaticamente via CLI `claude` se disponível; exibe comandos manuais caso contrário. - **Copilot CLI:** Instala automaticamente via CLI `copilot` se disponível; exibe comandos manuais caso contrário. - **Cursor:** Baixa e extrai o pacote do plugin no diretório `.cursor/`. -- **VS Code:** Adiciona a URL do marketplace nas configurações de usuário do VS Code. +- **VS Code:** Adiciona a URL do marketplace nas configurações de usuário do VS Code e instala a extensão VS Code (`.vsix`) via CLI `code` se disponível; exibe instruções manuais caso contrário. ### Exemplos diff --git a/docs/src/content/docs/reference/cli-commands.mdx b/docs/src/content/docs/reference/cli-commands.mdx index e4d93872..5345a455 100644 --- a/docs/src/content/docs/reference/cli-commands.mdx +++ b/docs/src/content/docs/reference/cli-commands.mdx @@ -248,7 +248,7 @@ Installation behavior varies by editor: - **Claude Code:** Auto-installs via `claude` CLI if available; prints manual commands otherwise. - **Copilot CLI:** Auto-installs via `copilot` CLI if available; prints manual commands otherwise. - **Cursor:** Downloads and extracts the plugin bundle into `.cursor/`. -- **VS Code:** Adds the marketplace URL to VS Code user settings. +- **VS Code:** Adds the marketplace URL to VS Code user settings and installs the VS Code extension (`.vsix`) via `code` CLI if available; prints manual instructions otherwise. ### Examples From 08e4b45a1e661cd7227d7b52cb01209c913dca47 Mon Sep 17 00:00:00 2001 From: rhuanbarreto <283004+rhuanbarreto@users.noreply.github.com> Date: Mon, 23 Mar 2026 21:48:55 +0000 Subject: [PATCH 4/4] docs: regenerate llms-full.txt --- docs/public/llms-full.txt | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt index 076744e5..8c089e54 100644 --- a/docs/public/llms-full.txt +++ b/docs/public/llms-full.txt @@ -1863,6 +1863,7 @@ If you are already logged in, this command: 1. Creates the `.archgate/` governance directory (ADRs, lint rules) 2. Adds the authenticated marketplace URL to your VS Code **user settings** +3. Downloads and installs the Archgate VS Code extension (`.vsix`) if the `code` CLI is available The `chat.plugins.marketplaces` setting is application-scoped in VS Code, so it cannot be set per-workspace. The CLI automatically writes it to your user-level `settings.json`: @@ -1888,12 +1889,15 @@ archgate plugin install --editor vscode The command creates or updates the following: -| File | Scope | Purpose | -| -------------------- | ----- | ------------------------------------------------------ | -| User `settings.json` | User | `chat.plugins.marketplaces` with the authenticated URL | +| File | Scope | Purpose | +| -------------------- | ----------- | ------------------------------------------------------ | +| User `settings.json` | User | `chat.plugins.marketplaces` with the authenticated URL | +| Archgate extension | Application | VS Code extension installed via `.vsix` | The user settings file is merged additively -- existing settings are never overwritten. VS Code's built-in default marketplaces (`github/copilot-plugins`, `github/awesome-copilot`) are preserved when the key is set for the first time. +The VS Code extension is downloaded from the Archgate plugins service and installed via `code --install-extension`. If the `code` CLI is not available, manual installation instructions are printed. + The user-level marketplace setting (added to your `settings.json`): ```json @@ -1906,7 +1910,19 @@ The user-level marketplace setting (added to your `settings.json`): ### Manual setup -If you prefer not to let the CLI modify your user settings, you can add the marketplace URL manually. Open VS Code's user settings JSON (`Ctrl+Shift+P` → "Preferences: Open User Settings (JSON)") and add the `chat.plugins.marketplaces` entry shown above. You can find your authenticated URL by running `archgate login` and checking `~/.archgate/credentials`. +If you prefer not to let the CLI modify your user settings, you can set things up manually: + +**Marketplace URL:** Open VS Code's user settings JSON (`Ctrl+Shift+P` → "Preferences: Open User Settings (JSON)") and add the `chat.plugins.marketplaces` entry shown above. You can find your authenticated URL by running `archgate login` and checking `~/.archgate/credentials`. + +**Extension:** Download and install the `.vsix` file directly: + +```bash +curl -H "Authorization: Bearer " https://plugins.archgate.dev/api/vscode -o archgate.vsix +code --install-extension archgate.vsix +rm archgate.vsix +``` + +Replace `` with your archgate token from `~/.archgate/credentials`. ## What the plugin provides @@ -3114,7 +3130,7 @@ Installation behavior varies by editor: - **Claude Code:** Auto-installs via `claude` CLI if available; prints manual commands otherwise. - **Copilot CLI:** Auto-installs via `copilot` CLI if available; prints manual commands otherwise. - **Cursor:** Downloads and extracts the plugin bundle into `.cursor/`. -- **VS Code:** Adds the marketplace URL to VS Code user settings. +- **VS Code:** Adds the marketplace URL to VS Code user settings and installs the VS Code extension (`.vsix`) via `code` CLI if available; prints manual instructions otherwise. ### Examples