@neuralnomads/codenomad-dev 0.11.2-dev-20260218-127a1f62 → 0.11.3-dev-20260219-e84adebe
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.
- package/dist/server/routes/settings.js +3 -31
- package/dist/workspaces/manager.js +12 -20
- package/dist/workspaces/runtime.js +42 -0
- package/package.json +1 -1
- package/public/assets/{main-CFk-S6k5.js → main-BH2MDPrf.js} +77 -77
- package/public/index.html +1 -1
- package/public/sw.js +1 -1
- package/public/ui-version.json +1 -1
|
@@ -1,39 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
import { buildSpawnSpec } from "../../workspaces/runtime";
|
|
2
|
+
import { probeBinaryVersion } from "../../workspaces/runtime";
|
|
4
3
|
const ValidateBinarySchema = z.object({
|
|
5
4
|
path: z.string(),
|
|
6
5
|
});
|
|
7
6
|
function validateBinaryPath(binaryPath) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
const spec = buildSpawnSpec(binaryPath, ["--version"]);
|
|
12
|
-
try {
|
|
13
|
-
const result = spawnSync(spec.command, spec.args, {
|
|
14
|
-
encoding: "utf8",
|
|
15
|
-
windowsVerbatimArguments: Boolean(spec.options.windowsVerbatimArguments),
|
|
16
|
-
});
|
|
17
|
-
if (result.error) {
|
|
18
|
-
return { valid: false, error: result.error.message };
|
|
19
|
-
}
|
|
20
|
-
if (result.status !== 0) {
|
|
21
|
-
const stderr = result.stderr?.trim();
|
|
22
|
-
const stdout = result.stdout?.trim();
|
|
23
|
-
const combined = stderr || stdout;
|
|
24
|
-
const error = combined ? `Exited with code ${result.status}: ${combined}` : `Exited with code ${result.status}`;
|
|
25
|
-
return { valid: false, error };
|
|
26
|
-
}
|
|
27
|
-
const stdout = (result.stdout ?? "").trim();
|
|
28
|
-
const firstLine = stdout.split(/\r?\n/).find((line) => line.trim().length > 0);
|
|
29
|
-
const normalized = firstLine?.trim();
|
|
30
|
-
const versionMatch = normalized?.match(/([0-9]+\.[0-9]+\.[0-9A-Za-z.-]+)/);
|
|
31
|
-
const version = versionMatch?.[1];
|
|
32
|
-
return { valid: true, version };
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
return { valid: false, error: error instanceof Error ? error.message : String(error) };
|
|
36
|
-
}
|
|
7
|
+
const result = probeBinaryVersion(binaryPath);
|
|
8
|
+
return { valid: result.valid, version: result.version, error: result.error };
|
|
37
9
|
}
|
|
38
10
|
export function registerSettingsRoutes(app, deps) {
|
|
39
11
|
// Full-document access
|
|
@@ -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 } from "./runtime";
|
|
7
|
+
import { WorkspaceRuntime, probeBinaryVersion } 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;
|
|
@@ -212,28 +212,20 @@ export class WorkspaceManager {
|
|
|
212
212
|
if (!resolvedPath) {
|
|
213
213
|
return undefined;
|
|
214
214
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (result.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const normalized = line.trim();
|
|
221
|
-
const versionMatch = normalized.match(/([0-9]+\.[0-9]+\.[0-9A-Za-z.-]+)/);
|
|
222
|
-
if (versionMatch) {
|
|
223
|
-
const version = versionMatch[1];
|
|
224
|
-
this.options.logger.debug({ binary: resolvedPath, version }, "Detected binary version");
|
|
225
|
-
return version;
|
|
226
|
-
}
|
|
227
|
-
this.options.logger.debug({ binary: resolvedPath, reported: normalized }, "Binary reported version string");
|
|
228
|
-
return normalized;
|
|
229
|
-
}
|
|
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;
|
|
230
220
|
}
|
|
231
|
-
|
|
232
|
-
this.options.logger.
|
|
221
|
+
if (result.reported) {
|
|
222
|
+
this.options.logger.debug({ binary: resolvedPath, reported: result.reported }, "Binary reported version string");
|
|
223
|
+
return result.reported;
|
|
233
224
|
}
|
|
225
|
+
return undefined;
|
|
234
226
|
}
|
|
235
|
-
|
|
236
|
-
this.options.logger.warn({ binary: resolvedPath, err: error }, "Failed to detect binary version");
|
|
227
|
+
if (result.error) {
|
|
228
|
+
this.options.logger.warn({ binary: resolvedPath, err: result.error }, "Failed to detect binary version");
|
|
237
229
|
}
|
|
238
230
|
return undefined;
|
|
239
231
|
}
|
|
@@ -3,6 +3,7 @@ import { existsSync, statSync } from "fs";
|
|
|
3
3
|
import path from "path";
|
|
4
4
|
export const WINDOWS_CMD_EXTENSIONS = new Set([".cmd", ".bat"]);
|
|
5
5
|
export const WINDOWS_POWERSHELL_EXTENSIONS = new Set([".ps1"]);
|
|
6
|
+
const VERSION_REGEX = /([0-9]+\.[0-9]+\.[0-9A-Za-z.-]+)/;
|
|
6
7
|
export function buildSpawnSpec(binaryPath, args) {
|
|
7
8
|
if (process.platform !== "win32") {
|
|
8
9
|
return { command: binaryPath, args, options: {} };
|
|
@@ -29,6 +30,47 @@ export function buildSpawnSpec(binaryPath, args) {
|
|
|
29
30
|
}
|
|
30
31
|
return { command: binaryPath, args, options: {} };
|
|
31
32
|
}
|
|
33
|
+
export function probeBinaryVersion(binaryPath) {
|
|
34
|
+
if (!binaryPath) {
|
|
35
|
+
return { valid: false, error: "Missing binary path" };
|
|
36
|
+
}
|
|
37
|
+
const spec = buildSpawnSpec(binaryPath, ["--version"]);
|
|
38
|
+
try {
|
|
39
|
+
const result = spawnSync(spec.command, spec.args, {
|
|
40
|
+
encoding: "utf8",
|
|
41
|
+
windowsVerbatimArguments: Boolean(spec.options.windowsVerbatimArguments),
|
|
42
|
+
});
|
|
43
|
+
if (result.error) {
|
|
44
|
+
return { valid: false, error: result.error.message };
|
|
45
|
+
}
|
|
46
|
+
if (result.status !== 0) {
|
|
47
|
+
const stderr = result.stderr?.trim();
|
|
48
|
+
const stdout = result.stdout?.trim();
|
|
49
|
+
const combined = stderr || stdout;
|
|
50
|
+
const error = combined ? `Exited with code ${result.status}: ${combined}` : `Exited with code ${result.status}`;
|
|
51
|
+
return { valid: false, error };
|
|
52
|
+
}
|
|
53
|
+
const stdoutLines = String(result.stdout ?? "")
|
|
54
|
+
.split(/\r?\n/)
|
|
55
|
+
.map((line) => line.trim())
|
|
56
|
+
.filter((line) => line.length > 0);
|
|
57
|
+
const stderrLines = String(result.stderr ?? "")
|
|
58
|
+
.split(/\r?\n/)
|
|
59
|
+
.map((line) => line.trim())
|
|
60
|
+
.filter((line) => line.length > 0);
|
|
61
|
+
// Prefer stdout; fall back to stderr (some tools report version there).
|
|
62
|
+
const reported = stdoutLines[0] ?? stderrLines[0];
|
|
63
|
+
if (!reported) {
|
|
64
|
+
return { valid: true };
|
|
65
|
+
}
|
|
66
|
+
const versionMatch = reported.match(VERSION_REGEX);
|
|
67
|
+
const version = versionMatch?.[1];
|
|
68
|
+
return { valid: true, version, reported };
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return { valid: false, error: error instanceof Error ? error.message : String(error) };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
32
74
|
const SENSITIVE_ENV_KEY = /(PASSWORD|TOKEN|SECRET)/i;
|
|
33
75
|
function redactEnvironment(env) {
|
|
34
76
|
const redacted = {};
|