Skip to content

feat(vscode): add local runtime extension scaffold#2811

Merged
Hmbown merged 1 commit into
codex/v0.9.0-stewardshipfrom
codex/v090-vscode-scaffold
Jun 6, 2026
Merged

feat(vscode): add local runtime extension scaffold#2811
Hmbown merged 1 commit into
codex/v0.9.0-stewardshipfrom
codex/v090-vscode-scaffold

Conversation

@Hmbown
Copy link
Copy Markdown
Owner

@Hmbown Hmbown commented Jun 6, 2026

Summary

  • add an official extensions/vscode Phase 0 scaffold with commands to open CodeWhale, start codewhale serve --http, and check a local runtime
  • add a CodeWhale activity view, status bar state, local runtime config, VSIX packaging metadata, and built extension output
  • document the slice in the README/changelog and credit the VS Code/GUI request trail

Scope guard

This is intentionally not the full GUI: no chat webview, VS Code Agent View integration, inline edit application, marketplace publishing workflow, or retry/undo/snapshot GUI endpoints yet. The extension only probes public /health and /v1/runtime/info endpoints and launches the runtime in a user-visible terminal.

Credit

Harvested as a maintainer slice from PR #1022 by @lbcheng888 and shaped by the Agent View request in #2580 from @AiurArtanis. Also preserves the v0.9 VS Code/GUI request trail from #461, #462, #480 plus @BigBenLabs, @lzx1545642258, @yangdaowan, @mangdehuang, @VerrPower, @hejia-v, and @ygzhang-cn. Future GUI-runtime details remain informed by #2808 from @gaord.

Verification

  • npm run compile (extensions/vscode)
  • npm run package (extensions/vscode)
  • ./scripts/release/check-versions.sh
  • git diff --check

Harvests the safe Phase 0 VS Code lane from PR #1022 and the Agent View request in #2580 while keeping chat webviews, inline edits, Agent View, and retry/undo runtime endpoints out of this slice.

Credits @lbcheng888 for the earlier extension scaffold and @AiurArtanis plus the v0.9 GUI/VS Code reporters for the request trail.
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmbown has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@Hmbown Hmbown added this to the v0.9.0 milestone Jun 6, 2026
@Hmbown Hmbown merged commit bb8b1d3 into codex/v0.9.0-stewardship Jun 6, 2026
2 checks passed
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an official VS Code extension scaffold (Phase 0) for CodeWhale, enabling terminal launch, local runtime attach checks, status bar state, and a runtime status view. The review feedback highlights several critical improvements: enhancing cross-platform compatibility in shellQuote for Windows users, properly formatting IPv6 addresses in runtimeBaseUrl, securely storing sensitive tokens using VS Code's SecretStorage API, preventing duplicate terminal instances, avoiding webview flickering by using postMessage instead of full HTML reloads, and improving repository hygiene by ignoring compiled out/ files in .gitignore while automating compilation via a vscode:prepublish script.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +148 to +153
function shellQuote(value: string): string {
if (/^[A-Za-z0-9_./:=+-]+$/.test(value)) {
return value;
}
return `'${value.replace(/'/g, "'\\''")}'`;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current shellQuote implementation uses single quotes (') to wrap arguments containing special characters or spaces. While this works on Unix-like systems, it is completely broken on Windows cmd.exe (the default shell for many Windows users), which does not recognize single quotes as string delimiters.

We should check the platform and use double quotes on Windows to ensure compatibility with both cmd.exe and PowerShell.

Suggested change
function shellQuote(value: string): string {
if (/^[A-Za-z0-9_./:=+-]+$/.test(value)) {
return value;
}
return `'${value.replace(/'/g, "'\\''")}'`;
}
function shellQuote(value: string): string {
if (/^[A-Za-z0-9_./:=+-]+$/.test(value)) {
return value;
}
if (process.platform === "win32") {
return `"${value.replace(/"/g, '""')}"`;
}
return `'${value.replace(/'/g, "'\\''")}'`;
}

Comment on lines +34 to +36
export function runtimeBaseUrl(config: RuntimeConfig): string {
return `http://${config.host}:${config.port}`;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If config.host is configured as an IPv6 address (e.g., ::1), runtimeBaseUrl will return an invalid URL format like http://::1:7878. For IPv6 hosts, the IP address must be enclosed in square brackets.

Let's update runtimeBaseUrl to handle IPv6 addresses correctly.

Suggested change
export function runtimeBaseUrl(config: RuntimeConfig): string {
return `http://${config.host}:${config.port}`;
}
export function runtimeBaseUrl(config: RuntimeConfig): string {
const host = config.host.includes(":") ? `[${config.host}]` : config.host;
return `http://${host}:${config.port}`;
}

const commandPath = config.get<string>("commandPath", "codewhale").trim() || "codewhale";
const host = config.get<string>("runtimeHost", "127.0.0.1").trim() || "127.0.0.1";
const port = config.get<number>("runtimePort", 7878);
const token = config.get<string>("runtimeToken", "").trim();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Storing sensitive authentication tokens like runtimeToken in plain text within VS Code's settings.json is a security risk, as settings files are often shared, backed up, or checked into dotfiles repositories.

Consider using VS Code's secure SecretStorage API (context.secrets) to securely store and retrieve the runtimeToken instead of exposing it in plain text settings.

Comment on lines +69 to +70
export function startRuntimeTerminal(config: RuntimeConfig): vscode.Terminal {
const terminal = vscode.window.createTerminal("CodeWhale Runtime");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Every time startRuntimeTerminal is invoked, a new terminal instance is created. If the user clicks "Start Local Runtime" multiple times, it will spawn multiple terminals trying to bind to the same port (7878), leading to "port already in use" errors.

Consider checking if a terminal with the name "CodeWhale Runtime" already exists in vscode.window.terminals before creating a new one.

Comment on lines +29 to +32
update(state: RuntimeState): void {
this.state = state;
this.render();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Overwriting this.view.webview.html on every state update completely reloads the webview's iframe. This causes a noticeable visual flicker/flash in the sidebar and destroys any webview state or scroll position.

A better practice is to set the HTML once during initialization, and then use webview.postMessage to send state updates to the webview, updating the DOM dynamically via a message listener in the webview's script.

@@ -0,0 +1,2 @@
node_modules/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Checking compiled JavaScript files (out/) and source maps (out/**/*.map) into the git repository is discouraged. It causes massive diff noise in pull requests and frequent merge conflicts.

Instead, out/ should be added to .gitignore, and compilation should be automated before packaging/publishing using the vscode:prepublish script in package.json.

node_modules/
out/

}
},
"scripts": {
"compile": "tsc -p ./",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To automate TypeScript compilation before packaging or publishing the extension (especially after ignoring the out/ directory in git), add a vscode:prepublish script.

Suggested change
"compile": "tsc -p ./",
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant