From a60d9c6a78247a2a64903e7e679e7fa73de25d38 Mon Sep 17 00:00:00 2001 From: Debian Date: Sun, 15 Feb 2026 15:17:47 +0000 Subject: [PATCH] feat: implement home screen with OpenClaw detection, install, and config flow --- AGENTS.md | 14 +++ apps/extension/package.json | 12 +- apps/extension/src/extension.ts | 15 ++- apps/extension/src/panels/home.ts | 132 +++++++++++++++----- apps/extension/src/panels/setup.ts | 184 ++++++++++++++++++---------- apps/extension/src/panels/status.ts | 83 ++++++++++--- package-lock.json | 2 +- 7 files changed, 320 insertions(+), 122 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 34e04a29..1e61d34b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -121,3 +121,17 @@ Dominic (boss) + contributors ## Status Draft plan ready. Next step: scaffold wrapper + extension. + +--- + +## Completed Milestones + +### ✅ Home Screen Flow (feat/home-screen-flow) +- **Home panel** (`panels/home.ts`): Branded "Welcome to OpenClaw Code" webview with lobster icon, dark red/black theme +- **Detection**: Checks `~/.openclaw/` directory existence on startup +- **Install flow**: If not installed → "Install OpenClaw" button → opens terminal with `npm install -g openclaw@latest && openclaw onboard` +- **Configure flow**: If installed → "Configure OpenClaw" button → opens side panel to edit `~/.openclaw/openclaw.json` +- **Config panel** (`panels/setup.ts`): Reads/writes openclaw.json, editable model + channels fields +- **Status panel** (`panels/status.ts`): Gateway running detection with start/stop buttons +- **Extension** (`extension.ts`): Registers `openclaw.home`, `openclaw.configure`, `openclaw.install`, `openclaw.status` commands; auto-shows Home on activation +- **package.json**: Updated commands list, bumped to v0.2.0 diff --git a/apps/extension/package.json b/apps/extension/package.json index 20a61090..4e507a21 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -1,8 +1,8 @@ { "name": "openclaw-vscode", "displayName": "OpenClaw", - "description": "OpenClaw home screen, local setup wizard, and status panel for VS Code", - "version": "0.1.0", + "description": "OpenClaw home screen, install wizard, configuration, and status panel for VS Code", + "version": "0.2.0", "publisher": "openclaw", "repository": { "type": "git", @@ -23,8 +23,12 @@ "title": "OpenClaw: Home" }, { - "command": "openclaw.setupLocal", - "title": "OpenClaw: Setup Local" + "command": "openclaw.configure", + "title": "OpenClaw: Configure" + }, + { + "command": "openclaw.install", + "title": "OpenClaw: Install" }, { "command": "openclaw.status", diff --git a/apps/extension/src/extension.ts b/apps/extension/src/extension.ts index 72679a86..c1ef7400 100644 --- a/apps/extension/src/extension.ts +++ b/apps/extension/src/extension.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; import { HomePanel } from './panels/home'; -import { SetupPanel } from './panels/setup'; +import { ConfigPanel } from './panels/setup'; import { StatusPanel } from './panels/status'; export function activate(context: vscode.ExtensionContext) { @@ -8,16 +8,21 @@ export function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand('openclaw.home', () => { HomePanel.createOrShow(context.extensionUri); }), - vscode.commands.registerCommand('openclaw.setupLocal', () => { - SetupPanel.createOrShow(context.extensionUri); + vscode.commands.registerCommand('openclaw.configure', () => { + ConfigPanel.createOrShow(context.extensionUri); + }), + vscode.commands.registerCommand('openclaw.install', () => { + const terminal = vscode.window.createTerminal('OpenClaw Install'); + terminal.show(); + terminal.sendText('npm install -g openclaw@latest && openclaw onboard'); }), vscode.commands.registerCommand('openclaw.status', () => { StatusPanel.createOrShow(context.extensionUri); }), ); - // Show home panel on first activation - vscode.commands.executeCommand('openclaw.home'); + // Auto-show Home panel on startup + HomePanel.createOrShow(context.extensionUri); } export function deactivate() {} diff --git a/apps/extension/src/panels/home.ts b/apps/extension/src/panels/home.ts index 86776ab6..46e03896 100644 --- a/apps/extension/src/panels/home.ts +++ b/apps/extension/src/panels/home.ts @@ -1,13 +1,18 @@ import * as vscode from 'vscode'; +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; export class HomePanel { public static currentPanel: HomePanel | undefined; private readonly _panel: vscode.WebviewPanel; + private readonly _extensionUri: vscode.Uri; private _disposables: vscode.Disposable[] = []; - private constructor(panel: vscode.WebviewPanel) { + private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) { this._panel = panel; - this._panel.webview.html = this._getHtml(); + this._extensionUri = extensionUri; + this._update(); this._panel.onDidDispose(() => this.dispose(), null, this._disposables); this._panel.webview.onDidReceiveMessage(msg => { if (msg.command) { @@ -22,9 +27,10 @@ export class HomePanel { return; } const panel = vscode.window.createWebviewPanel( - 'openclawHome', 'OpenClaw Home', vscode.ViewColumn.One, { enableScripts: true } + 'openclawHome', 'OpenClaw Home', vscode.ViewColumn.One, + { enableScripts: true, localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'media')] } ); - HomePanel.currentPanel = new HomePanel(panel); + HomePanel.currentPanel = new HomePanel(panel, extensionUri); } public dispose() { @@ -33,45 +39,115 @@ export class HomePanel { this._disposables.forEach(d => d.dispose()); } - private _getHtml(): string { + private _update() { + const openclawDir = path.join(os.homedir(), '.openclaw'); + const isInstalled = fs.existsSync(openclawDir); + const iconUri = this._panel.webview.asWebviewUri( + vscode.Uri.joinPath(this._extensionUri, 'media', 'icon.png') + ); + this._panel.webview.html = this._getHtml(isInstalled, iconUri.toString()); + } + + private _getHtml(isInstalled: boolean, iconUri: string): string { + const statusIcon = isInstalled ? '✅' : '⚠️'; + const statusText = isInstalled ? 'OpenClaw detected' : 'OpenClaw not found'; + const statusClass = isInstalled ? 'detected' : 'not-found'; + const buttonLabel = isInstalled ? 'Configure OpenClaw' : 'Install OpenClaw'; + const buttonCommand = isInstalled ? 'openclaw.configure' : 'openclaw.install'; + return ` + -

🐾 OpenClaw

-

Your AI-powered development companion

-
- - -
+ +

Welcome to OpenClaw Code

+

Your AI-powered development environment

+
${statusIcon} ${statusText}
+ +