fix(vscode): Change Health Check to Health API Endpoint and increase timeout (#268)

* Try fixing startup

* Add OpenCode Version to debug
This commit is contained in:
wienans
2026-02-02 17:33:45 +02:00
committed by GitHub
parent df1858b424
commit 10165ec604
2 changed files with 27 additions and 8 deletions
+2
View File
@@ -415,6 +415,7 @@ export async function activate(context: vscode.ExtensionContext) {
}; };
const probeTargets: Array<{ label: string; path: string; includeDirectory?: boolean; timeoutMs?: number }> = [ const probeTargets: Array<{ label: string; path: string; includeDirectory?: boolean; timeoutMs?: number }> = [
{ label: 'health', path: '/global/health', includeDirectory: false },
{ label: 'config', path: '/config', includeDirectory: true }, { label: 'config', path: '/config', includeDirectory: true },
{ label: 'providers', path: '/config/providers', includeDirectory: true }, { label: 'providers', path: '/config/providers', includeDirectory: true },
// Can be slower on large configs; keep the probe from producing false negatives. // Can be slower on large configs; keep the probe from producing false negatives.
@@ -446,6 +447,7 @@ export async function activate(context: vscode.ExtensionContext) {
const lines = [ const lines = [
`Time: ${new Date().toISOString()}`, `Time: ${new Date().toISOString()}`,
`OpenChamber version: ${extensionVersion || '(unknown)'}`, `OpenChamber version: ${extensionVersion || '(unknown)'}`,
`OpenCode Version: ${debug?.version ?? '(unknown)'}`,
`VS Code version: ${vscode.version}`, `VS Code version: ${vscode.version}`,
`Platform: ${process.platform} ${process.arch}`, `Platform: ${process.platform} ${process.arch}`,
`Workspace folders: ${workspaceFolders.length}${workspaceFolders.length ? ` (${workspaceFolders.join(', ')})` : ''}`, `Workspace folders: ${workspaceFolders.length}${workspaceFolders.length ? ` (${workspaceFolders.join(', ')})` : ''}`,
+25 -8
View File
@@ -1,7 +1,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as os from 'os'; import * as os from 'os';
import { execSync } from 'child_process'; import { execSync } from 'child_process';
import { createOpencodeServer } from '@opencode-ai/sdk/server'; import { createOpencodeServer } from '@opencode-ai/sdk/v2/server';
const READY_CHECK_TIMEOUT_MS = 30000; const READY_CHECK_TIMEOUT_MS = 30000;
@@ -28,6 +28,7 @@ export type OpenCodeDebugInfo = {
lastReadyElapsedMs: number | null; lastReadyElapsedMs: number | null;
lastReadyAttempts: number | null; lastReadyAttempts: number | null;
lastStartAttempts: number | null; lastStartAttempts: number | null;
version: string | null;
}; };
export interface OpenCodeManager { export interface OpenCodeManager {
@@ -53,8 +54,8 @@ function resolvePortFromUrl(url: string): number | null {
} }
type ReadyResult = type ReadyResult =
| { ok: true; baseUrl: string; elapsedMs: number; attempts: number } | { ok: true; baseUrl: string; elapsedMs: number; attempts: number; version: string | null }
| { ok: false; elapsedMs: number; attempts: number }; | { ok: false; elapsedMs: number; attempts: number; version: null };
function normalizeBaseUrl(value: string): string { function normalizeBaseUrl(value: string): string {
return value.replace(/\/+$/, ''); return value.replace(/\/+$/, '');
@@ -86,6 +87,7 @@ function getCandidateBaseUrls(serverUrl: string): string[] {
} }
async function waitForReady(serverUrl: string, timeoutMs = 15000): Promise<ReadyResult> { async function waitForReady(serverUrl: string, timeoutMs = 15000): Promise<ReadyResult> {
const outputChannel = vscode.window.createOutputChannel('OpenChamberManager');
const start = Date.now(); const start = Date.now();
const candidates = getCandidateBaseUrls(serverUrl); const candidates = getCandidateBaseUrls(serverUrl);
let attempts = 0; let attempts = 0;
@@ -98,16 +100,27 @@ async function waitForReady(serverUrl: string, timeoutMs = 15000): Promise<Ready
const timeout = setTimeout(() => controller.abort(), 3000); const timeout = setTimeout(() => controller.abort(), 3000);
// Keep using /config since the UI proxies to it (via /api -> strip prefix). // Keep using /config since the UI proxies to it (via /api -> strip prefix).
const url = new URL(`${baseUrl}/config`); const url = new URL(`${baseUrl}/global/health`);
const res = await fetch(url.toString(), { const res = await fetch(url.toString(), {
method: 'GET', method: 'GET',
headers: { Accept: 'application/json' }, headers: { Accept: 'application/json' },
signal: controller.signal, signal: controller.signal,
}); });
let body: { healthy?: boolean, version?: string } | null = null;
try {
body = (await res.json()) as { healthy?: boolean, version?: string };
} catch {
body = null;
}
clearTimeout(timeout); clearTimeout(timeout);
if (res.ok) { outputChannel?.appendLine(
return { ok: true, baseUrl, elapsedMs: Date.now() - start, attempts }; `Health check to ${url.toString()} returned ${res.status} with body: ${JSON.stringify(body)}`
);
if (res.ok && body?.healthy === true) {
return { ok: true, baseUrl, elapsedMs: Date.now() - start, attempts, version: body?.version ?? null };
} }
} catch { } catch {
// ignore // ignore
@@ -117,7 +130,7 @@ async function waitForReady(serverUrl: string, timeoutMs = 15000): Promise<Ready
await new Promise(r => setTimeout(r, 100)); await new Promise(r => setTimeout(r, 100));
} }
return { ok: false, elapsedMs: Date.now() - start, attempts }; return { ok: false, elapsedMs: Date.now() - start, attempts, version: null };
} }
export function createOpenCodeManager(_context: vscode.ExtensionContext): OpenCodeManager { export function createOpenCodeManager(_context: vscode.ExtensionContext): OpenCodeManager {
@@ -139,6 +152,7 @@ export function createOpenCodeManager(_context: vscode.ExtensionContext): OpenCo
let lastReadyElapsedMs: number | null = null; let lastReadyElapsedMs: number | null = null;
let lastReadyAttempts: number | null = null; let lastReadyAttempts: number | null = null;
let lastStartAttempts: number | null = null; let lastStartAttempts: number | null = null;
let version: string | null = null;
let detectedPort: number | null = null; let detectedPort: number | null = null;
let cliMissing = false; let cliMissing = false;
@@ -244,12 +258,13 @@ export function createOpenCodeManager(_context: vscode.ExtensionContext): OpenCo
if (server && server.url) { if (server && server.url) {
// Validate readiness for the current workspace context. // Validate readiness for the current workspace context.
const ready = await waitForReady(server.url, 10000); const ready = await waitForReady(server.url, READY_CHECK_TIMEOUT_MS);
lastReadyElapsedMs = ready.elapsedMs; lastReadyElapsedMs = ready.elapsedMs;
lastReadyAttempts = ready.attempts; lastReadyAttempts = ready.attempts;
if (ready.ok) { if (ready.ok) {
managedApiUrlOverride = ready.baseUrl; managedApiUrlOverride = ready.baseUrl;
detectedPort = resolvePortFromUrl(ready.baseUrl); detectedPort = resolvePortFromUrl(ready.baseUrl);
version = ready.version;
setStatus('connected'); setStatus('connected');
} else { } else {
try { try {
@@ -322,6 +337,7 @@ export function createOpenCodeManager(_context: vscode.ExtensionContext): OpenCo
managedApiUrlOverride = null; managedApiUrlOverride = null;
detectedPort = null; detectedPort = null;
version = null;
setStatus('disconnected'); setStatus('disconnected');
} }
@@ -425,6 +441,7 @@ export function createOpenCodeManager(_context: vscode.ExtensionContext): OpenCo
lastReadyElapsedMs, lastReadyElapsedMs,
lastReadyAttempts, lastReadyAttempts,
lastStartAttempts, lastStartAttempts,
version,
}), }),
onStatusChange(callback) { onStatusChange(callback) {
listeners.add(callback); listeners.add(callback);