From 43ba2cbfaecac45ab25434325ca30612e367328a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 14:58:36 +0000 Subject: [PATCH 1/3] feat: add VS Code extension with terminal launcher and custom theme Agent-Logs-Url: https://github.com/devNull-bootloader/openclaude/sessions/5c0e9230-42be-4cce-a5d6-e85d665ea72a Co-authored-by: devNull-bootloader <189463177+devNull-bootloader@users.noreply.github.com> --- README.md | 5 ++ vscode-extension/openclaude-vscode/README.md | 40 ++++++++++ .../openclaude-vscode/package.json | 76 ++++++++++++++++++ .../openclaude-vscode/src/extension.js | 35 +++++++++ .../themes/OpenClaude-Terminal-Black.json | 78 +++++++++++++++++++ 5 files changed, 234 insertions(+) create mode 100644 vscode-extension/openclaude-vscode/README.md create mode 100644 vscode-extension/openclaude-vscode/package.json create mode 100644 vscode-extension/openclaude-vscode/src/extension.js create mode 100644 vscode-extension/openclaude-vscode/themes/OpenClaude-Terminal-Black.json diff --git a/README.md b/README.md index 0a8e0d2a..93279c49 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,11 @@ Best if you want local inference on Apple Silicon with Atomic Chat. See [Advance --- + +## VS Code Extension + +Want a native VS Code experience? Use the in-repo extension at `vscode-extension/openclaude-vscode` for one-command terminal launch and the `OpenClaude Terminal Black` theme. + ## What Works - **All tools**: Bash, FileRead, FileWrite, FileEdit, Glob, Grep, WebFetch, WebSearch, Agent, MCP, LSP, NotebookEdit, Tasks diff --git a/vscode-extension/openclaude-vscode/README.md b/vscode-extension/openclaude-vscode/README.md new file mode 100644 index 00000000..b90c59fc --- /dev/null +++ b/vscode-extension/openclaude-vscode/README.md @@ -0,0 +1,40 @@ +# OpenClaude VS Code Extension + +A sleek, terminal-first VS Code companion for OpenClaude. + +## Features + +- **Launch OpenClaude instantly** in the integrated terminal via `OpenClaude: Launch in Terminal` +- **Open repository/docs quickly** via `OpenClaude: Open Repository` +- **Built-in dark theme**: `OpenClaude Terminal Black` (terminal-inspired, low-glare, neon accents) + +## Requirements + +- VS Code `1.95+` +- `openclaude` available in your terminal PATH (`npm install -g @gitlawb/openclaude`) + +## Commands + +- `OpenClaude: Launch in Terminal` +- `OpenClaude: Open Repository` + +## Settings + +- `openclaude.launchCommand` (default: `openclaude`) +- `openclaude.terminalName` (default: `OpenClaude`) +- `openclaude.useOpenAIShim` (default: `true`) + +## Development + +From this folder: + +```bash +npm run lint +``` + +To package (optional): + +```bash +npm run package +``` + diff --git a/vscode-extension/openclaude-vscode/package.json b/vscode-extension/openclaude-vscode/package.json new file mode 100644 index 00000000..53057bfe --- /dev/null +++ b/vscode-extension/openclaude-vscode/package.json @@ -0,0 +1,76 @@ +{ + "name": "openclaude-vscode", + "displayName": "OpenClaude", + "description": "Sleek terminal-first VS Code extension for launching OpenClaude and using a matching dark hacker-style theme.", + "version": "0.1.0", + "publisher": "devnull-bootloader", + "engines": { + "vscode": "^1.95.0" + }, + "categories": [ + "Themes", + "Other" + ], + "activationEvents": [ + "onCommand:openclaude.start", + "onCommand:openclaude.openDocs" + ], + "main": "./src/extension.js", + "contributes": { + "commands": [ + { + "command": "openclaude.start", + "title": "OpenClaude: Launch in Terminal", + "category": "OpenClaude" + }, + { + "command": "openclaude.openDocs", + "title": "OpenClaude: Open Repository", + "category": "OpenClaude" + } + ], + "configuration": { + "title": "OpenClaude", + "properties": { + "openclaude.launchCommand": { + "type": "string", + "default": "openclaude", + "description": "Command run in the integrated terminal when launching OpenClaude." + }, + "openclaude.terminalName": { + "type": "string", + "default": "OpenClaude", + "description": "Integrated terminal tab name for OpenClaude sessions." + }, + "openclaude.useOpenAIShim": { + "type": "boolean", + "default": true, + "description": "Set CLAUDE_CODE_USE_OPENAI=1 in launched OpenClaude terminals." + } + } + }, + "themes": [ + { + "label": "OpenClaude Terminal Black", + "uiTheme": "vs-dark", + "path": "./themes/OpenClaude-Terminal-Black.json" + } + ] + }, + "scripts": { + "lint": "node --check ./src/extension.js", + "package": "npx @vscode/vsce package --no-dependencies" + }, + "keywords": [ + "openclaude", + "terminal", + "theme", + "cli", + "llm" + ], + "repository": { + "type": "git", + "url": "https://github.com/devNull-bootloader/openclaude" + }, + "license": "MIT" +} diff --git a/vscode-extension/openclaude-vscode/src/extension.js b/vscode-extension/openclaude-vscode/src/extension.js new file mode 100644 index 00000000..537954a3 --- /dev/null +++ b/vscode-extension/openclaude-vscode/src/extension.js @@ -0,0 +1,35 @@ +const vscode = require('vscode'); + +/** + * @param {vscode.ExtensionContext} context + */ +function activate(context) { + const startCommand = vscode.commands.registerCommand('openclaude.start', async () => { + const configured = vscode.workspace.getConfiguration('openclaude'); + const launchCommand = configured.get('launchCommand', 'openclaude'); + const terminalName = configured.get('terminalName', 'OpenClaude'); + + const terminal = vscode.window.createTerminal({ + name: terminalName, + env: { + CLAUDE_CODE_USE_OPENAI: configured.get('useOpenAIShim', true) ? '1' : undefined, + }, + }); + + terminal.show(true); + terminal.sendText(launchCommand, true); + }); + + const openDocsCommand = vscode.commands.registerCommand('openclaude.openDocs', async () => { + await vscode.env.openExternal(vscode.Uri.parse('https://github.com/devNull-bootloader/openclaude')); + }); + + context.subscriptions.push(startCommand, openDocsCommand); +} + +function deactivate() {} + +module.exports = { + activate, + deactivate, +}; diff --git a/vscode-extension/openclaude-vscode/themes/OpenClaude-Terminal-Black.json b/vscode-extension/openclaude-vscode/themes/OpenClaude-Terminal-Black.json new file mode 100644 index 00000000..ab4962c1 --- /dev/null +++ b/vscode-extension/openclaude-vscode/themes/OpenClaude-Terminal-Black.json @@ -0,0 +1,78 @@ +{ + "$schema": "vscode://schemas/color-theme", + "name": "OpenClaude Terminal Black", + "type": "dark", + "colors": { + "editor.background": "#090B10", + "editor.foreground": "#D6E2FF", + "editorCursor.foreground": "#66D9EF", + "editorLineNumber.foreground": "#3D4458", + "editorLineNumber.activeForeground": "#7F8AA3", + "editor.selectionBackground": "#1C2333", + "editor.inactiveSelectionBackground": "#141A27", + "editor.wordHighlightBackground": "#1C233344", + "editor.wordHighlightStrongBackground": "#24304B66", + "editorIndentGuide.background1": "#131825", + "editorIndentGuide.activeBackground1": "#2A3350", + "editorBracketMatch.background": "#25304B66", + "editorBracketMatch.border": "#66D9EF", + "terminal.background": "#090B10", + "terminal.foreground": "#D6E2FF", + "terminalCursor.background": "#66D9EF", + "terminalCursor.foreground": "#66D9EF", + "terminal.ansiBlack": "#090B10", + "terminal.ansiRed": "#FF6B6B", + "terminal.ansiGreen": "#89DD7C", + "terminal.ansiYellow": "#F2C14E", + "terminal.ansiBlue": "#5CA9FF", + "terminal.ansiMagenta": "#C792EA", + "terminal.ansiCyan": "#66D9EF", + "terminal.ansiWhite": "#D6E2FF", + "terminal.ansiBrightBlack": "#4A5165", + "terminal.ansiBrightRed": "#FF8787", + "terminal.ansiBrightGreen": "#A4EFA0", + "terminal.ansiBrightYellow": "#FFD479", + "terminal.ansiBrightBlue": "#86C1FF", + "terminal.ansiBrightMagenta": "#D8B0F5", + "terminal.ansiBrightCyan": "#9DE9FF", + "terminal.ansiBrightWhite": "#E8F0FF", + "statusBar.background": "#0F1420", + "statusBar.foreground": "#D6E2FF", + "activityBar.background": "#0D111B", + "activityBar.foreground": "#D6E2FF", + "sideBar.background": "#0B0F18", + "sideBar.foreground": "#B3BDD4", + "titleBar.activeBackground": "#0B0F18", + "titleBar.activeForeground": "#D6E2FF" + }, + "tokenColors": [ + { + "scope": ["comment", "punctuation.definition.comment"], + "settings": { "foreground": "#5A637B", "fontStyle": "italic" } + }, + { + "scope": ["keyword", "storage.type", "storage.modifier"], + "settings": { "foreground": "#C792EA" } + }, + { + "scope": ["string", "constant.other.symbol"], + "settings": { "foreground": "#89DD7C" } + }, + { + "scope": ["constant.numeric", "constant.language"], + "settings": { "foreground": "#F2C14E" } + }, + { + "scope": ["entity.name.function", "support.function"], + "settings": { "foreground": "#5CA9FF" } + }, + { + "scope": ["variable", "entity.name.variable"], + "settings": { "foreground": "#D6E2FF" } + }, + { + "scope": ["entity.name.type", "support.type", "entity.name.class"], + "settings": { "foreground": "#66D9EF" } + } + ] +} From 8e8671fc51bf2c4361d2f1cb5493f10de6cf467b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:07:20 +0000 Subject: [PATCH 2/3] feat: add visual OpenClaude control center UI in VS Code extension Agent-Logs-Url: https://github.com/devNull-bootloader/openclaude/sessions/30a4694d-1125-4280-a593-74b5e3da601e Co-authored-by: devNull-bootloader <189463177+devNull-bootloader@users.noreply.github.com> --- vscode-extension/openclaude-vscode/README.md | 10 +- .../openclaude-vscode/media/openclaude.svg | 6 + .../openclaude-vscode/package.json | 31 +++- .../openclaude-vscode/src/extension.js | 132 ++++++++++++++++-- 4 files changed, 159 insertions(+), 20 deletions(-) create mode 100644 vscode-extension/openclaude-vscode/media/openclaude.svg diff --git a/vscode-extension/openclaude-vscode/README.md b/vscode-extension/openclaude-vscode/README.md index b90c59fc..9d67cad1 100644 --- a/vscode-extension/openclaude-vscode/README.md +++ b/vscode-extension/openclaude-vscode/README.md @@ -1,11 +1,14 @@ # OpenClaude VS Code Extension -A sleek, terminal-first VS Code companion for OpenClaude. +A sleek VS Code companion for OpenClaude with a visual **Control Center** plus terminal-first workflows. ## Features -- **Launch OpenClaude instantly** in the integrated terminal via `OpenClaude: Launch in Terminal` -- **Open repository/docs quickly** via `OpenClaude: Open Repository` +- **Control Center sidebar UI** in the Activity Bar: + - Launch OpenClaude + - Open repository/docs + - Open VS Code theme picker +- **Terminal launch command**: `OpenClaude: Launch in Terminal` - **Built-in dark theme**: `OpenClaude Terminal Black` (terminal-inspired, low-glare, neon accents) ## Requirements @@ -15,6 +18,7 @@ A sleek, terminal-first VS Code companion for OpenClaude. ## Commands +- `OpenClaude: Open Control Center` - `OpenClaude: Launch in Terminal` - `OpenClaude: Open Repository` diff --git a/vscode-extension/openclaude-vscode/media/openclaude.svg b/vscode-extension/openclaude-vscode/media/openclaude.svg new file mode 100644 index 00000000..b492c423 --- /dev/null +++ b/vscode-extension/openclaude-vscode/media/openclaude.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/vscode-extension/openclaude-vscode/package.json b/vscode-extension/openclaude-vscode/package.json index 53057bfe..4cd42b1d 100644 --- a/vscode-extension/openclaude-vscode/package.json +++ b/vscode-extension/openclaude-vscode/package.json @@ -1,8 +1,8 @@ { "name": "openclaude-vscode", "displayName": "OpenClaude", - "description": "Sleek terminal-first VS Code extension for launching OpenClaude and using a matching dark hacker-style theme.", - "version": "0.1.0", + "description": "Sleek VS Code extension for OpenClaude with a visual Control Center and terminal-aligned theme.", + "version": "0.1.1", "publisher": "devnull-bootloader", "engines": { "vscode": "^1.95.0" @@ -13,7 +13,9 @@ ], "activationEvents": [ "onCommand:openclaude.start", - "onCommand:openclaude.openDocs" + "onCommand:openclaude.openDocs", + "onCommand:openclaude.openControlCenter", + "onView:openclaude.controlCenter" ], "main": "./src/extension.js", "contributes": { @@ -27,8 +29,31 @@ "command": "openclaude.openDocs", "title": "OpenClaude: Open Repository", "category": "OpenClaude" + }, + { + "command": "openclaude.openControlCenter", + "title": "OpenClaude: Open Control Center", + "category": "OpenClaude" } ], + "viewsContainers": { + "activitybar": [ + { + "id": "openclaude", + "title": "OpenClaude", + "icon": "media/openclaude.svg" + } + ] + }, + "views": { + "openclaude": [ + { + "id": "openclaude.controlCenter", + "name": "Control Center", + "type": "webview" + } + ] + }, "configuration": { "title": "OpenClaude", "properties": { diff --git a/vscode-extension/openclaude-vscode/src/extension.js b/vscode-extension/openclaude-vscode/src/extension.js index 537954a3..b59725a3 100644 --- a/vscode-extension/openclaude-vscode/src/extension.js +++ b/vscode-extension/openclaude-vscode/src/extension.js @@ -1,30 +1,134 @@ const vscode = require('vscode'); +function launchOpenClaude() { + const configured = vscode.workspace.getConfiguration('openclaude'); + const launchCommand = configured.get('launchCommand', 'openclaude'); + const terminalName = configured.get('terminalName', 'OpenClaude'); + + const terminal = vscode.window.createTerminal({ + name: terminalName, + env: { + CLAUDE_CODE_USE_OPENAI: configured.get('useOpenAIShim', true) ? '1' : undefined, + }, + }); + + terminal.show(true); + terminal.sendText(launchCommand, true); +} + +class OpenClaudeControlCenterProvider { + resolveWebviewView(webviewView) { + webviewView.webview.options = { enableScripts: true }; + webviewView.webview.html = this.getHtml(webviewView.webview); + + webviewView.webview.onDidReceiveMessage(async (message) => { + if (message?.type === 'launch') { + launchOpenClaude(); + return; + } + + if (message?.type === 'docs') { + await vscode.env.openExternal(vscode.Uri.parse('https://github.com/devNull-bootloader/openclaude')); + return; + } + + if (message?.type === 'theme') { + await vscode.commands.executeCommand('workbench.action.selectTheme'); + } + }); + } + + getHtml(webview) { + const nonce = String(Date.now()); + return ` + + + + + + + + +
+
OpenClaude Control Center
+
Launch OpenClaude, jump to docs, and quickly tune the editor vibe.
+ + + +
+ + +`; + } +} + /** * @param {vscode.ExtensionContext} context */ function activate(context) { const startCommand = vscode.commands.registerCommand('openclaude.start', async () => { - const configured = vscode.workspace.getConfiguration('openclaude'); - const launchCommand = configured.get('launchCommand', 'openclaude'); - const terminalName = configured.get('terminalName', 'OpenClaude'); - - const terminal = vscode.window.createTerminal({ - name: terminalName, - env: { - CLAUDE_CODE_USE_OPENAI: configured.get('useOpenAIShim', true) ? '1' : undefined, - }, - }); - - terminal.show(true); - terminal.sendText(launchCommand, true); + launchOpenClaude(); }); const openDocsCommand = vscode.commands.registerCommand('openclaude.openDocs', async () => { await vscode.env.openExternal(vscode.Uri.parse('https://github.com/devNull-bootloader/openclaude')); }); - context.subscriptions.push(startCommand, openDocsCommand); + const openUiCommand = vscode.commands.registerCommand('openclaude.openControlCenter', async () => { + await vscode.commands.executeCommand('workbench.view.extension.openclaude'); + }); + + const provider = new OpenClaudeControlCenterProvider(); + const providerDisposable = vscode.window.registerWebviewViewProvider('openclaude.controlCenter', provider); + + context.subscriptions.push(startCommand, openDocsCommand, openUiCommand, providerDisposable); } function deactivate() {} From ff124dcdfbbc1fe3348c3063c9d1844e84bc75e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:08:22 +0000 Subject: [PATCH 3/3] fix: use cryptographic nonce for extension webview CSP Agent-Logs-Url: https://github.com/devNull-bootloader/openclaude/sessions/30a4694d-1125-4280-a593-74b5e3da601e Co-authored-by: devNull-bootloader <189463177+devNull-bootloader@users.noreply.github.com> --- vscode-extension/openclaude-vscode/src/extension.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vscode-extension/openclaude-vscode/src/extension.js b/vscode-extension/openclaude-vscode/src/extension.js index b59725a3..daf48133 100644 --- a/vscode-extension/openclaude-vscode/src/extension.js +++ b/vscode-extension/openclaude-vscode/src/extension.js @@ -1,4 +1,5 @@ const vscode = require('vscode'); +const crypto = require('crypto'); function launchOpenClaude() { const configured = vscode.workspace.getConfiguration('openclaude'); @@ -39,7 +40,7 @@ class OpenClaudeControlCenterProvider { } getHtml(webview) { - const nonce = String(Date.now()); + const nonce = crypto.randomBytes(16).toString('base64'); return `