@neuralnomads/codenomad-dev 0.11.3-dev-20260219-e84adebe → 0.11.3-dev-20260219-2124e540

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import { connect } from "net";
4
4
  import { FileSystemBrowser } from "../filesystem/browser";
5
5
  import { searchWorkspaceFiles } from "../filesystem/search";
6
6
  import { clearWorkspaceSearchCache } from "../filesystem/search-cache";
7
- import { WorkspaceRuntime, probeBinaryVersion } from "./runtime";
7
+ import { WorkspaceRuntime } from "./runtime";
8
8
  import { getOpencodeConfigDir } from "../opencode-config.js";
9
9
  import { buildOpencodeBasicAuthHeader, DEFAULT_OPENCODE_USERNAME, generateOpencodeServerPassword, OPENCODE_SERVER_PASSWORD_ENV, OPENCODE_SERVER_USERNAME_ENV, } from "./opencode-auth";
10
10
  const STARTUP_STABILITY_DELAY_MS = 1500;
@@ -67,9 +67,6 @@ export class WorkspaceManager {
67
67
  createdAt: new Date().toISOString(),
68
68
  updatedAt: new Date().toISOString(),
69
69
  };
70
- if (!descriptor.binaryVersion) {
71
- descriptor.binaryVersion = this.detectBinaryVersion(resolvedBinaryPath);
72
- }
73
70
  this.workspaces.set(id, descriptor);
74
71
  this.options.eventBus.publish({ type: "workspace.created", workspace: descriptor });
75
72
  const serverConfig = this.options.settings.getOwner("config", "server");
@@ -99,7 +96,10 @@ export class WorkspaceManager {
99
96
  environment,
100
97
  onExit: (info) => this.handleProcessExit(info.workspaceId, info),
101
98
  });
102
- await this.waitForWorkspaceReadiness({ workspaceId: id, port, exitPromise, getLastOutput });
99
+ const runtimeVersion = await this.waitForWorkspaceReadiness({ workspaceId: id, port, exitPromise, getLastOutput });
100
+ if (runtimeVersion) {
101
+ descriptor.binaryVersion = runtimeVersion;
102
+ }
103
103
  descriptor.pid = pid;
104
104
  descriptor.port = port;
105
105
  descriptor.status = "ready";
@@ -208,27 +208,6 @@ export class WorkspaceManager {
208
208
  }
209
209
  return candidates[0] ?? "";
210
210
  }
211
- detectBinaryVersion(resolvedPath) {
212
- if (!resolvedPath) {
213
- return undefined;
214
- }
215
- const result = probeBinaryVersion(resolvedPath);
216
- if (result.valid) {
217
- if (result.version) {
218
- this.options.logger.debug({ binary: resolvedPath, version: result.version }, "Detected binary version");
219
- return result.version;
220
- }
221
- if (result.reported) {
222
- this.options.logger.debug({ binary: resolvedPath, reported: result.reported }, "Binary reported version string");
223
- return result.reported;
224
- }
225
- return undefined;
226
- }
227
- if (result.error) {
228
- this.options.logger.warn({ binary: resolvedPath, err: result.error }, "Failed to detect binary version");
229
- }
230
- return undefined;
231
- }
232
211
  async waitForWorkspaceReadiness(params) {
233
212
  await Promise.race([
234
213
  this.waitForPortAvailability(params.port),
@@ -236,13 +215,14 @@ export class WorkspaceManager {
236
215
  throw this.buildStartupError(params.workspaceId, "exited before becoming ready", info, params.getLastOutput());
237
216
  }),
238
217
  ]);
239
- await this.waitForInstanceHealth(params);
218
+ const version = await this.waitForInstanceHealth(params);
240
219
  await Promise.race([
241
220
  this.delay(STARTUP_STABILITY_DELAY_MS),
242
221
  params.exitPromise.then((info) => {
243
222
  throw this.buildStartupError(params.workspaceId, "exited shortly after start", info, params.getLastOutput());
244
223
  }),
245
224
  ]);
225
+ return version;
246
226
  }
247
227
  async waitForInstanceHealth(params) {
248
228
  const probeResult = await Promise.race([
@@ -252,7 +232,7 @@ export class WorkspaceManager {
252
232
  }),
253
233
  ]);
254
234
  if (probeResult.ok) {
255
- return;
235
+ return probeResult.version;
256
236
  }
257
237
  const latestOutput = params.getLastOutput().trim();
258
238
  if (latestOutput) {
@@ -262,7 +242,7 @@ export class WorkspaceManager {
262
242
  throw new Error(`Workspace ${params.workspaceId} failed health check: ${reason}.`);
263
243
  }
264
244
  async probeInstance(workspaceId, port) {
265
- const url = `http://127.0.0.1:${port}/project/current`;
245
+ const url = `http://127.0.0.1:${port}/global/health`;
266
246
  try {
267
247
  const headers = {};
268
248
  const authHeader = this.opencodeAuth.get(workspaceId)?.authorization;
@@ -271,11 +251,19 @@ export class WorkspaceManager {
271
251
  }
272
252
  const response = await fetch(url, { headers });
273
253
  if (!response.ok) {
274
- const reason = `health probe returned HTTP ${response.status}`;
254
+ const reason = `/global/health returned HTTP ${response.status}`;
275
255
  this.options.logger.debug({ workspaceId, status: response.status }, "Health probe returned server error");
276
256
  return { ok: false, reason };
277
257
  }
278
- return { ok: true };
258
+ const payload = (await response.json().catch(() => null));
259
+ const healthy = payload?.healthy === true;
260
+ const version = typeof payload?.version === "string" ? payload.version.trim() : undefined;
261
+ if (!healthy) {
262
+ const reason = "Instance reported unhealthy";
263
+ this.options.logger.debug({ workspaceId, payload }, "Health probe returned unhealthy response");
264
+ return { ok: false, reason };
265
+ }
266
+ return { ok: true, version: version || undefined };
279
267
  }
280
268
  catch (error) {
281
269
  const reason = error instanceof Error ? error.message : String(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuralnomads/codenomad-dev",
3
- "version": "0.11.3-dev-20260219-e84adebe",
3
+ "version": "0.11.3-dev-20260219-2124e540",
4
4
  "description": "CodeNomad Server",
5
5
  "license": "MIT",
6
6
  "author": {