@neuralnomads/codenomad-dev 0.14.0-dev-20260420-04fc28c4 → 0.14.0-dev-20260421-68551f67
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 +1 -1
- package/dist/workspaces/__tests__/spawn.test.js +139 -0
- package/dist/workspaces/runtime.js +54 -77
- package/dist/workspaces/spawn.js +219 -0
- package/package.json +1 -1
- package/public/assets/{ChangesTab-eUJ7HXjk.js → ChangesTab-Dt3idhm2.js} +2 -2
- package/public/assets/{DiffToolbar-C2gN4-DU.js → DiffToolbar-C-rXHRQB.js} +1 -1
- package/public/assets/{FilesTab-BtxCG1pv.js → FilesTab-DKzbJvzM.js} +2 -2
- package/public/assets/{GitChangesTab-BVOgrozk.js → GitChangesTab-CgTxNlE0.js} +2 -2
- package/public/assets/{SplitFilePanel-vPBNqijZ.js → SplitFilePanel-DhUmaW0S.js} +1 -1
- package/public/assets/{StatusTab-BLnPWyWk.js → StatusTab-Dbx6AkDk.js} +1 -1
- package/public/assets/{bundle-full-Ddu6qye3.js → bundle-full-DEU8L99_.js} +1 -1
- package/public/assets/{diff-viewer-BZeFsDG4.js → diff-viewer-uToKxdD4.js} +1 -1
- package/public/assets/{index-CcYvh3Uc.js → index--oqVn_K6.js} +1 -1
- package/public/assets/index-Btyhpe4o.js +1 -0
- package/public/assets/index-C6C534z4.js +1 -0
- package/public/assets/index-CMh7_0rm.js +1 -0
- package/public/assets/{index-s309YxXV.css → index-CWmlJG88.css} +1 -1
- package/public/assets/index-D7RMnYOz.js +1 -0
- package/public/assets/index-DE6KDkkL.js +2 -0
- package/public/assets/{index-C72ltV-E.js → index-DbMNXyVd.js} +1 -1
- package/public/assets/index-NrX0Q8eA.js +1 -0
- package/public/assets/index-z-uWAw1M.js +1 -0
- package/public/assets/{loading-CXx1HTRq.js → loading-CjZdFQ4L.js} +1 -1
- package/public/assets/main-3oghJUx8.js +48 -0
- package/public/assets/{markdown-CB_rJhcV.js → markdown-Zg4mawQS.js} +3 -3
- package/public/assets/{monaco-viewer-BAhYjr-N.js → monaco-viewer-DANembz4.js} +1 -1
- package/public/assets/{todo-CAxz-1Tz.js → todo-kNdm04Eg.js} +1 -1
- package/public/assets/tool-call-2zz7f8xn.js +60 -0
- package/public/assets/{unified-picker-d0K5E9QI.js → unified-picker-Be5bKL4U.js} +1 -1
- package/public/assets/{wrap-text-CPc0o1wr.js → wrap-text-DngNWpNA.js} +1 -1
- package/public/index.html +4 -4
- package/public/loading.html +4 -4
- package/public/sw.js +1 -1
- package/public/assets/index-BGjy4SXE.js +0 -1
- package/public/assets/index-BWikFX-R.js +0 -1
- package/public/assets/index-C_TDxjfc.js +0 -2
- package/public/assets/index-CmAwr57o.js +0 -1
- package/public/assets/index-DL8_CQ8W.js +0 -1
- package/public/assets/index-DoLglUyU.js +0 -1
- package/public/assets/index-lqTLZJ_z.js +0 -1
- package/public/assets/main-DAirHb0u.js +0 -48
- package/public/assets/tool-call-ZqXDG9uG.js +0 -60
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { probeBinaryVersion } from "../../workspaces/
|
|
2
|
+
import { probeBinaryVersion } from "../../workspaces/spawn";
|
|
3
3
|
import { sanitizeConfigDoc, sanitizeConfigOwner } from "../../settings/public-config";
|
|
4
4
|
const ValidateBinarySchema = z.object({
|
|
5
5
|
path: z.string(),
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { buildWindowsSpawnSpec, buildWslSignalSpec, parseWslUncPath, resolveWslWorkingDirectory } from "../spawn";
|
|
4
|
+
describe("parseWslUncPath", () => {
|
|
5
|
+
it("parses WSL UNC paths into distro and linux path", () => {
|
|
6
|
+
assert.deepEqual(parseWslUncPath(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`), {
|
|
7
|
+
distro: "Ubuntu",
|
|
8
|
+
linuxPath: "/home/dev/.opencode/bin/opencode",
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
it("supports the legacy wsl$ UNC prefix", () => {
|
|
12
|
+
assert.deepEqual(parseWslUncPath(String.raw `\\wsl$\Ubuntu\home\dev`), {
|
|
13
|
+
distro: "Ubuntu",
|
|
14
|
+
linuxPath: "/home/dev",
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe("resolveWslWorkingDirectory", () => {
|
|
19
|
+
it("keeps WSL workspace folders in the same distro", () => {
|
|
20
|
+
assert.equal(JSON.stringify(resolveWslWorkingDirectory(String.raw `\\wsl.localhost\Ubuntu\home\dev\workspace`, "Ubuntu")), JSON.stringify({ kind: "linux", path: "/home/dev/workspace" }));
|
|
21
|
+
});
|
|
22
|
+
it("keeps Windows drive paths so WSL can resolve them with wslpath", () => {
|
|
23
|
+
assert.equal(JSON.stringify(resolveWslWorkingDirectory(String.raw `C:\Users\dev\workspace`, "Ubuntu")), JSON.stringify({ kind: "windows", path: String.raw `C:\Users\dev\workspace` }));
|
|
24
|
+
});
|
|
25
|
+
it("keeps UNC network paths so WSL can resolve them with wslpath", () => {
|
|
26
|
+
assert.equal(JSON.stringify(resolveWslWorkingDirectory(String.raw `\\server\share\workspace`, "Ubuntu")), JSON.stringify({ kind: "windows", path: String.raw `\\server\share\workspace` }));
|
|
27
|
+
});
|
|
28
|
+
it("rejects WSL workspace folders from a different distro", () => {
|
|
29
|
+
assert.equal(resolveWslWorkingDirectory(String.raw `\\wsl.localhost\Debian\home\dev\workspace`, "Ubuntu"), null);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe("buildWindowsSpawnSpec", () => {
|
|
33
|
+
it("wraps WSL binaries with wsl.exe and propagates required env vars", () => {
|
|
34
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve", "--port", "0"], {
|
|
35
|
+
cwd: String.raw `\\wsl.localhost\Ubuntu\home\dev\workspace`,
|
|
36
|
+
env: {
|
|
37
|
+
OPENCODE_CONFIG_DIR: String.raw `C:\Users\dev\AppData\Roaming\CodeNomad\opencode-config`,
|
|
38
|
+
CODENOMAD_INSTANCE_ID: "workspace-123",
|
|
39
|
+
OPENCODE_SERVER_PASSWORD: "secret",
|
|
40
|
+
},
|
|
41
|
+
propagateEnvKeys: ["OPENCODE_CONFIG_DIR", "CODENOMAD_INSTANCE_ID", "OPENCODE_SERVER_PASSWORD"],
|
|
42
|
+
});
|
|
43
|
+
assert.equal(spec.command, "wsl.exe");
|
|
44
|
+
assert.deepEqual(spec.args, [
|
|
45
|
+
"--distribution",
|
|
46
|
+
"Ubuntu",
|
|
47
|
+
"--cd",
|
|
48
|
+
"/home/dev/workspace",
|
|
49
|
+
"--exec",
|
|
50
|
+
"/home/dev/.opencode/bin/opencode",
|
|
51
|
+
"serve",
|
|
52
|
+
"--port",
|
|
53
|
+
"0",
|
|
54
|
+
]);
|
|
55
|
+
assert.equal(spec.cwd, undefined);
|
|
56
|
+
assert.equal(spec.env?.WSLENV, "OPENCODE_CONFIG_DIR/p:CODENOMAD_INSTANCE_ID:OPENCODE_SERVER_PASSWORD");
|
|
57
|
+
});
|
|
58
|
+
it("upgrades existing WSLENV path entries to include /p", () => {
|
|
59
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve"], {
|
|
60
|
+
env: {
|
|
61
|
+
OPENCODE_CONFIG_DIR: String.raw `C:\Users\dev\AppData\Roaming\CodeNomad\opencode-config`,
|
|
62
|
+
WSLENV: "OPENCODE_CONFIG_DIR:CODENOMAD_INSTANCE_ID/u",
|
|
63
|
+
},
|
|
64
|
+
propagateEnvKeys: ["OPENCODE_CONFIG_DIR", "CODENOMAD_INSTANCE_ID"],
|
|
65
|
+
});
|
|
66
|
+
assert.equal(spec.env?.WSLENV, "OPENCODE_CONFIG_DIR/p:CODENOMAD_INSTANCE_ID/u");
|
|
67
|
+
});
|
|
68
|
+
it("propagates inherited known path variables even when they are not explicitly requested", () => {
|
|
69
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve"], {
|
|
70
|
+
env: {
|
|
71
|
+
NODE_EXTRA_CA_CERTS: String.raw `C:\certs\root.pem`,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
assert.equal(spec.env?.WSLENV, "NODE_EXTRA_CA_CERTS/p");
|
|
75
|
+
});
|
|
76
|
+
it("uses wslpath for Windows workspace folders instead of assuming /mnt", () => {
|
|
77
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve", "--port", "0"], {
|
|
78
|
+
cwd: String.raw `C:\Users\dev\workspace`,
|
|
79
|
+
});
|
|
80
|
+
assert.equal(spec.command, "wsl.exe");
|
|
81
|
+
assert.deepEqual(spec.args, [
|
|
82
|
+
"--distribution",
|
|
83
|
+
"Ubuntu",
|
|
84
|
+
"--exec",
|
|
85
|
+
"sh",
|
|
86
|
+
"-lc",
|
|
87
|
+
'cd "$(wslpath -au "$1")" && shift && exec "$@"',
|
|
88
|
+
"codenomad-wsl-launch",
|
|
89
|
+
String.raw `C:\Users\dev\workspace`,
|
|
90
|
+
"/home/dev/.opencode/bin/opencode",
|
|
91
|
+
"serve",
|
|
92
|
+
"--port",
|
|
93
|
+
"0",
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
it("uses wslpath for UNC network workspace folders", () => {
|
|
97
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve"], {
|
|
98
|
+
cwd: String.raw `\\server\share\workspace`,
|
|
99
|
+
});
|
|
100
|
+
assert.equal(spec.command, "wsl.exe");
|
|
101
|
+
assert.deepEqual(spec.args, [
|
|
102
|
+
"--distribution",
|
|
103
|
+
"Ubuntu",
|
|
104
|
+
"--exec",
|
|
105
|
+
"sh",
|
|
106
|
+
"-lc",
|
|
107
|
+
'cd "$(wslpath -au "$1")" && shift && exec "$@"',
|
|
108
|
+
"codenomad-wsl-launch",
|
|
109
|
+
String.raw `\\server\share\workspace`,
|
|
110
|
+
"/home/dev/.opencode/bin/opencode",
|
|
111
|
+
"serve",
|
|
112
|
+
]);
|
|
113
|
+
});
|
|
114
|
+
it("can wrap WSL launches to emit the Linux PID marker", () => {
|
|
115
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve"], {
|
|
116
|
+
cwd: String.raw `\\wsl.localhost\Ubuntu\home\dev\workspace`,
|
|
117
|
+
wslPidMarker: "__CODENOMAD_WSL_PID__:",
|
|
118
|
+
});
|
|
119
|
+
assert.equal(spec.command, "wsl.exe");
|
|
120
|
+
assert.deepEqual(spec.args, [
|
|
121
|
+
"--distribution",
|
|
122
|
+
"Ubuntu",
|
|
123
|
+
"--exec",
|
|
124
|
+
"sh",
|
|
125
|
+
"-lc",
|
|
126
|
+
`printf '%s%s\\n' '__CODENOMAD_WSL_PID__:' "$$" && cd "$1" && shift && exec "$@"`,
|
|
127
|
+
"codenomad-wsl-launch",
|
|
128
|
+
"/home/dev/workspace",
|
|
129
|
+
"/home/dev/.opencode/bin/opencode",
|
|
130
|
+
"serve",
|
|
131
|
+
]);
|
|
132
|
+
assert.equal(spec.wsl?.pidMarker, "__CODENOMAD_WSL_PID__:");
|
|
133
|
+
});
|
|
134
|
+
it("builds the WSL kill command for tracked Linux PIDs", () => {
|
|
135
|
+
const spec = buildWslSignalSpec("Ubuntu", 4321, "SIGTERM");
|
|
136
|
+
assert.equal(spec.command, "wsl.exe");
|
|
137
|
+
assert.deepEqual(spec.args, ["--distribution", "Ubuntu", "--exec", "kill", "-TERM", "4321"]);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -1,77 +1,9 @@
|
|
|
1
1
|
import { spawn, spawnSync } from "child_process";
|
|
2
2
|
import { existsSync, statSync } from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
-
|
|
5
|
-
export const WINDOWS_POWERSHELL_EXTENSIONS = new Set([".ps1"]);
|
|
6
|
-
const VERSION_REGEX = /([0-9]+\.[0-9]+\.[0-9A-Za-z.-]+)/;
|
|
7
|
-
export function buildSpawnSpec(binaryPath, args) {
|
|
8
|
-
if (process.platform !== "win32") {
|
|
9
|
-
return { command: binaryPath, args, options: {} };
|
|
10
|
-
}
|
|
11
|
-
const extension = path.extname(binaryPath).toLowerCase();
|
|
12
|
-
if (WINDOWS_CMD_EXTENSIONS.has(extension)) {
|
|
13
|
-
const comspec = process.env.ComSpec || "cmd.exe";
|
|
14
|
-
// cmd.exe requires the full command as a single string.
|
|
15
|
-
// Using the ""<script> <args>"" pattern ensures paths with spaces are handled.
|
|
16
|
-
const commandLine = `""${binaryPath}" ${args.join(" ")}"`;
|
|
17
|
-
return {
|
|
18
|
-
command: comspec,
|
|
19
|
-
args: ["/d", "/s", "/c", commandLine],
|
|
20
|
-
options: { windowsVerbatimArguments: true },
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
if (WINDOWS_POWERSHELL_EXTENSIONS.has(extension)) {
|
|
24
|
-
// powershell.exe ships with Windows. (pwsh may not.)
|
|
25
|
-
return {
|
|
26
|
-
command: "powershell.exe",
|
|
27
|
-
args: ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", binaryPath, ...args],
|
|
28
|
-
options: {},
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
return { command: binaryPath, args, options: {} };
|
|
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
|
-
}
|
|
4
|
+
import { buildSpawnSpec, buildWslSignalSpec } from "./spawn";
|
|
74
5
|
const SENSITIVE_ENV_KEY = /(PASSWORD|TOKEN|SECRET)/i;
|
|
6
|
+
const WSL_PID_MARKER = "__CODENOMAD_WSL_PID__:";
|
|
75
7
|
function redactEnvironment(env) {
|
|
76
8
|
const redacted = {};
|
|
77
9
|
for (const [key, value] of Object.entries(env)) {
|
|
@@ -115,7 +47,13 @@ export class WorkspaceRuntime {
|
|
|
115
47
|
return combined.join("\n");
|
|
116
48
|
};
|
|
117
49
|
return new Promise((resolve, reject) => {
|
|
118
|
-
const
|
|
50
|
+
const propagatedEnvKeys = Object.keys(options.environment ?? {});
|
|
51
|
+
const spec = buildSpawnSpec(options.binaryPath, args, {
|
|
52
|
+
cwd: options.folder,
|
|
53
|
+
env,
|
|
54
|
+
propagateEnvKeys: propagatedEnvKeys,
|
|
55
|
+
wslPidMarker: WSL_PID_MARKER,
|
|
56
|
+
});
|
|
119
57
|
const commandLine = [spec.command, ...spec.args].join(" ");
|
|
120
58
|
this.logger.info({
|
|
121
59
|
workspaceId: options.workspaceId,
|
|
@@ -134,13 +72,17 @@ export class WorkspaceRuntime {
|
|
|
134
72
|
}, "OpenCode spawn environment");
|
|
135
73
|
const detached = process.platform !== "win32";
|
|
136
74
|
const child = spawn(spec.command, spec.args, {
|
|
137
|
-
cwd:
|
|
138
|
-
env,
|
|
75
|
+
cwd: spec.cwd,
|
|
76
|
+
env: spec.env,
|
|
139
77
|
stdio: ["ignore", "pipe", "pipe"],
|
|
140
78
|
detached,
|
|
141
79
|
...spec.options,
|
|
142
80
|
});
|
|
143
|
-
const managed = {
|
|
81
|
+
const managed = {
|
|
82
|
+
child,
|
|
83
|
+
requestedStop: false,
|
|
84
|
+
...(spec.wsl ? { wsl: { distro: spec.wsl.distro, linuxPid: null } } : {}),
|
|
85
|
+
};
|
|
144
86
|
this.processes.set(options.workspaceId, managed);
|
|
145
87
|
let stdoutBuffer = "";
|
|
146
88
|
let stderrBuffer = "";
|
|
@@ -210,6 +152,14 @@ export class WorkspaceRuntime {
|
|
|
210
152
|
const trimmed = line.trim();
|
|
211
153
|
if (!trimmed)
|
|
212
154
|
continue;
|
|
155
|
+
if (managed.wsl && trimmed.startsWith(WSL_PID_MARKER)) {
|
|
156
|
+
const linuxPid = Number.parseInt(trimmed.slice(WSL_PID_MARKER.length), 10);
|
|
157
|
+
if (Number.isFinite(linuxPid) && linuxPid > 0) {
|
|
158
|
+
managed.wsl.linuxPid = linuxPid;
|
|
159
|
+
this.logger.debug({ workspaceId: options.workspaceId, linuxPid }, "Captured WSL OpenCode PID");
|
|
160
|
+
}
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
213
163
|
recentStdout.push(trimmed);
|
|
214
164
|
if (recentStdout.length > MAX_OUTPUT_LINES) {
|
|
215
165
|
recentStdout.shift();
|
|
@@ -314,11 +264,38 @@ export class WorkspaceRuntime {
|
|
|
314
264
|
return false;
|
|
315
265
|
}
|
|
316
266
|
};
|
|
267
|
+
const trySignalWslProcess = (signal) => {
|
|
268
|
+
if (process.platform !== "win32" || !managed.wsl?.linuxPid) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
const spec = buildWslSignalSpec(managed.wsl.distro, managed.wsl.linuxPid, signal);
|
|
273
|
+
const result = spawnSync(spec.command, spec.args, { encoding: "utf8" });
|
|
274
|
+
const exitCode = result.status;
|
|
275
|
+
if (exitCode === 0) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
const stderr = (result.stderr ?? "").toString().toLowerCase();
|
|
279
|
+
const stdout = (result.stdout ?? "").toString().toLowerCase();
|
|
280
|
+
const combined = `${stdout}\n${stderr}`;
|
|
281
|
+
if (combined.includes("no such process") || combined.includes("not found")) {
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
this.logger.debug({ workspaceId, pid, linuxPid: managed.wsl.linuxPid, distro: managed.wsl.distro, exitCode, stderr: result.stderr, stdout: result.stdout }, "WSL kill failed");
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
this.logger.debug({ workspaceId, pid, linuxPid: managed.wsl.linuxPid, distro: managed.wsl.distro, err: error }, "WSL kill failed to execute");
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
317
292
|
const sendStopSignal = (signal) => {
|
|
318
293
|
if (process.platform === "win32") {
|
|
319
|
-
//
|
|
320
|
-
|
|
321
|
-
|
|
294
|
+
// WSL-backed launches need a Linux signal first because the tracked Windows PID belongs to wsl.exe.
|
|
295
|
+
if (!trySignalWslProcess(signal)) {
|
|
296
|
+
// Fallback to the Windows process tree rooted at pid. Use /F only for escalation.
|
|
297
|
+
tryTaskkill(signal === "SIGKILL");
|
|
298
|
+
}
|
|
322
299
|
return;
|
|
323
300
|
}
|
|
324
301
|
// Prefer process-group signaling so wrapper launchers (bun/node) don't orphan the real server.
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { spawnSync } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export const WINDOWS_CMD_EXTENSIONS = new Set([".cmd", ".bat"]);
|
|
4
|
+
export const WINDOWS_POWERSHELL_EXTENSIONS = new Set([".ps1"]);
|
|
5
|
+
const VERSION_REGEX = /([0-9]+\.[0-9]+\.[0-9A-Za-z.-]+)/;
|
|
6
|
+
const WSL_UNC_PATH_REGEX = /^\\\\wsl(?:\.localhost|\$)\\([^\\/]+)(?:[\\/](.*))?$/i;
|
|
7
|
+
const WSL_PATH_ENV_KEYS = new Set(["OPENCODE_CONFIG_DIR", "NODE_EXTRA_CA_CERTS"]);
|
|
8
|
+
export function parseWslUncPath(input) {
|
|
9
|
+
const normalized = input.trim().replace(/\//g, "\\");
|
|
10
|
+
const match = normalized.match(WSL_UNC_PATH_REGEX);
|
|
11
|
+
if (!match) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const distro = match[1] ?? "";
|
|
15
|
+
const remainder = match[2] ?? "";
|
|
16
|
+
const segments = remainder.split(/\\+/).filter((segment) => segment.length > 0);
|
|
17
|
+
return {
|
|
18
|
+
distro,
|
|
19
|
+
linuxPath: segments.length > 0 ? `/${segments.join("/")}` : "/",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function resolveWslWorkingDirectory(folder, distro) {
|
|
23
|
+
const wslFolder = parseWslUncPath(folder);
|
|
24
|
+
if (wslFolder) {
|
|
25
|
+
return wslFolder.distro.toLowerCase() === distro.toLowerCase() ? { kind: "linux", path: wslFolder.linuxPath } : null;
|
|
26
|
+
}
|
|
27
|
+
const windowsFolder = normalizeWindowsPath(folder);
|
|
28
|
+
return windowsFolder ? { kind: "windows", path: windowsFolder } : null;
|
|
29
|
+
}
|
|
30
|
+
export function buildWindowsSpawnSpec(binaryPath, args, options = {}) {
|
|
31
|
+
const wslPath = parseWslUncPath(binaryPath);
|
|
32
|
+
if (wslPath) {
|
|
33
|
+
return buildWslSpawnSpec(wslPath, args, options);
|
|
34
|
+
}
|
|
35
|
+
const extension = path.extname(binaryPath).toLowerCase();
|
|
36
|
+
if (WINDOWS_CMD_EXTENSIONS.has(extension)) {
|
|
37
|
+
const comspec = process.env.ComSpec || "cmd.exe";
|
|
38
|
+
// cmd.exe requires the full command as a single string.
|
|
39
|
+
// Using the ""<script> <args>"" pattern ensures paths with spaces are handled.
|
|
40
|
+
const commandLine = `""${binaryPath}" ${args.join(" ")}"`;
|
|
41
|
+
return {
|
|
42
|
+
command: comspec,
|
|
43
|
+
args: ["/d", "/s", "/c", commandLine],
|
|
44
|
+
options: { windowsVerbatimArguments: true },
|
|
45
|
+
cwd: options.cwd,
|
|
46
|
+
env: options.env,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (WINDOWS_POWERSHELL_EXTENSIONS.has(extension)) {
|
|
50
|
+
// powershell.exe ships with Windows. (pwsh may not.)
|
|
51
|
+
return {
|
|
52
|
+
command: "powershell.exe",
|
|
53
|
+
args: ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", binaryPath, ...args],
|
|
54
|
+
options: {},
|
|
55
|
+
cwd: options.cwd,
|
|
56
|
+
env: options.env,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
command: binaryPath,
|
|
61
|
+
args,
|
|
62
|
+
options: {},
|
|
63
|
+
cwd: options.cwd,
|
|
64
|
+
env: options.env,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function buildSpawnSpec(binaryPath, args, options = {}) {
|
|
68
|
+
if (process.platform !== "win32") {
|
|
69
|
+
return {
|
|
70
|
+
command: binaryPath,
|
|
71
|
+
args,
|
|
72
|
+
options: {},
|
|
73
|
+
cwd: options.cwd,
|
|
74
|
+
env: options.env,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return buildWindowsSpawnSpec(binaryPath, args, options);
|
|
78
|
+
}
|
|
79
|
+
export function buildWslSignalSpec(distro, linuxPid, signal) {
|
|
80
|
+
return {
|
|
81
|
+
command: "wsl.exe",
|
|
82
|
+
args: ["--distribution", distro, "--exec", "kill", signal === "SIGKILL" ? "-KILL" : "-TERM", String(linuxPid)],
|
|
83
|
+
options: {},
|
|
84
|
+
wsl: { distro },
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function probeBinaryVersion(binaryPath) {
|
|
88
|
+
if (!binaryPath) {
|
|
89
|
+
return { valid: false, error: "Missing binary path" };
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const spec = buildSpawnSpec(binaryPath, ["--version"]);
|
|
93
|
+
const result = spawnSync(spec.command, spec.args, {
|
|
94
|
+
encoding: "utf8",
|
|
95
|
+
cwd: spec.cwd,
|
|
96
|
+
env: spec.env,
|
|
97
|
+
windowsVerbatimArguments: Boolean(spec.options.windowsVerbatimArguments),
|
|
98
|
+
});
|
|
99
|
+
if (result.error) {
|
|
100
|
+
return { valid: false, error: result.error.message };
|
|
101
|
+
}
|
|
102
|
+
if (result.status !== 0) {
|
|
103
|
+
const stderr = result.stderr?.trim();
|
|
104
|
+
const stdout = result.stdout?.trim();
|
|
105
|
+
const combined = stderr || stdout;
|
|
106
|
+
const error = combined ? `Exited with code ${result.status}: ${combined}` : `Exited with code ${result.status}`;
|
|
107
|
+
return { valid: false, error };
|
|
108
|
+
}
|
|
109
|
+
const stdoutLines = String(result.stdout ?? "")
|
|
110
|
+
.split(/\r?\n/)
|
|
111
|
+
.map((line) => line.trim())
|
|
112
|
+
.filter((line) => line.length > 0);
|
|
113
|
+
const stderrLines = String(result.stderr ?? "")
|
|
114
|
+
.split(/\r?\n/)
|
|
115
|
+
.map((line) => line.trim())
|
|
116
|
+
.filter((line) => line.length > 0);
|
|
117
|
+
// Prefer stdout; fall back to stderr (some tools report version there).
|
|
118
|
+
const reported = stdoutLines[0] ?? stderrLines[0];
|
|
119
|
+
if (!reported) {
|
|
120
|
+
return { valid: true };
|
|
121
|
+
}
|
|
122
|
+
const versionMatch = reported.match(VERSION_REGEX);
|
|
123
|
+
const version = versionMatch?.[1];
|
|
124
|
+
return { valid: true, version, reported };
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
return { valid: false, error: error instanceof Error ? error.message : String(error) };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function buildWslSpawnSpec(wslPath, args, options) {
|
|
131
|
+
const workingDirectory = options.cwd ? resolveWslWorkingDirectory(options.cwd, wslPath.distro) : undefined;
|
|
132
|
+
if (options.cwd && !workingDirectory) {
|
|
133
|
+
throw new Error(`Unable to translate workspace folder for WSL binary in distro "${wslPath.distro}": ${options.cwd}`);
|
|
134
|
+
}
|
|
135
|
+
const wslArgs = ["--distribution", wslPath.distro];
|
|
136
|
+
const shouldWrapWithShell = Boolean(options.wslPidMarker) || workingDirectory?.kind === "windows";
|
|
137
|
+
if (!shouldWrapWithShell && workingDirectory?.kind === "linux") {
|
|
138
|
+
wslArgs.push("--cd", workingDirectory.path);
|
|
139
|
+
}
|
|
140
|
+
if (shouldWrapWithShell) {
|
|
141
|
+
const launchScript = buildWslLaunchScript(workingDirectory ?? undefined, options.wslPidMarker);
|
|
142
|
+
wslArgs.push("--exec", "sh", "-lc", launchScript, "codenomad-wsl-launch");
|
|
143
|
+
if (workingDirectory) {
|
|
144
|
+
wslArgs.push(workingDirectory.path);
|
|
145
|
+
}
|
|
146
|
+
wslArgs.push(wslPath.linuxPath, ...args);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
wslArgs.push("--exec", wslPath.linuxPath, ...args);
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
command: "wsl.exe",
|
|
153
|
+
args: wslArgs,
|
|
154
|
+
options: {},
|
|
155
|
+
env: buildWslEnvironment(options.env, options.propagateEnvKeys),
|
|
156
|
+
wsl: { distro: wslPath.distro, pidMarker: options.wslPidMarker },
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function buildWslLaunchScript(workingDirectory, pidMarker) {
|
|
160
|
+
const steps = [];
|
|
161
|
+
if (pidMarker) {
|
|
162
|
+
steps.push(`printf '%s%s\\n' '${pidMarker}' "$$"`);
|
|
163
|
+
}
|
|
164
|
+
if (workingDirectory?.kind === "linux") {
|
|
165
|
+
steps.push('cd "$1"');
|
|
166
|
+
steps.push("shift");
|
|
167
|
+
}
|
|
168
|
+
else if (workingDirectory?.kind === "windows") {
|
|
169
|
+
steps.push('cd "$(wslpath -au "$1")"');
|
|
170
|
+
steps.push("shift");
|
|
171
|
+
}
|
|
172
|
+
steps.push('exec "$@"');
|
|
173
|
+
return steps.join(" && ");
|
|
174
|
+
}
|
|
175
|
+
function normalizeWindowsPath(input) {
|
|
176
|
+
const normalized = path.win32.normalize(input.trim().replace(/\//g, "\\"));
|
|
177
|
+
if (!normalized) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
if (/^[A-Za-z]:/.test(normalized) || normalized.startsWith("\\\\")) {
|
|
181
|
+
return normalized;
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
function buildWslEnvironment(env, propagateEnvKeys) {
|
|
186
|
+
if (!env) {
|
|
187
|
+
return env;
|
|
188
|
+
}
|
|
189
|
+
const keysToPropagate = Array.from(new Set([
|
|
190
|
+
...(propagateEnvKeys ?? []).filter((key) => env[key] !== undefined),
|
|
191
|
+
...Array.from(WSL_PATH_ENV_KEYS).filter((key) => env[key] !== undefined),
|
|
192
|
+
]));
|
|
193
|
+
if (keysToPropagate.length === 0) {
|
|
194
|
+
return env;
|
|
195
|
+
}
|
|
196
|
+
const next = { ...env };
|
|
197
|
+
const entries = (next.WSLENV ?? "").split(":").filter((entry) => entry.length > 0);
|
|
198
|
+
const byName = new Map(entries.map((entry) => [entry.split("/")[0] ?? entry, entry]));
|
|
199
|
+
for (const key of keysToPropagate) {
|
|
200
|
+
const existingEntry = byName.get(key);
|
|
201
|
+
if (existingEntry) {
|
|
202
|
+
byName.set(key, ensureWslenvEntry(existingEntry, WSL_PATH_ENV_KEYS.has(key)));
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
byName.set(key, WSL_PATH_ENV_KEYS.has(key) ? `${key}/p` : key);
|
|
206
|
+
}
|
|
207
|
+
next.WSLENV = Array.from(byName.values()).join(":");
|
|
208
|
+
return next;
|
|
209
|
+
}
|
|
210
|
+
function ensureWslenvEntry(entry, requiresPathTranslation) {
|
|
211
|
+
if (!requiresPathTranslation) {
|
|
212
|
+
return entry;
|
|
213
|
+
}
|
|
214
|
+
const [name, rawFlags = ""] = entry.split("/");
|
|
215
|
+
if (rawFlags.includes("p")) {
|
|
216
|
+
return entry;
|
|
217
|
+
}
|
|
218
|
+
return rawFlags.length > 0 ? `${name}/${rawFlags}p` : `${name}/p`;
|
|
219
|
+
}
|
package/package.json
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-
|
|
2
|
-
import{_ as K}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-DANembz4.js","assets/git-diff-vendor-CSgooKT_.js","assets/fast-diff-vendor-DgdwVvTQ.js","assets/highlight-vendor-8FKMu9os.js","assets/git-diff-vendor-HAZkIolJ.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{_ as K}from"./index-DE6KDkkL.js";import{m as B,t as g,i as a,d as w,a as F,f as N}from"./monaco-viewer-DANembz4.js";import{c as f,n as c,a as L,F as T,S as W,z as j,A as q}from"./git-diff-vendor-CSgooKT_.js";import{D as G}from"./DiffToolbar-C-rXHRQB.js";import{S as H}from"./SplitFilePanel-DhUmaW0S.js";import"./fast-diff-vendor-DgdwVvTQ.js";import"./highlight-vendor-8FKMu9os.js";import"./main-3oghJUx8.js";import"./wrap-text-DngNWpNA.js";var J=g('<div class="file-viewer-panel flex-1"><div class="file-viewer-content file-viewer-content--monaco">'),p=g("<div class=file-viewer-empty><span class=file-viewer-empty-text>"),Q=g('<div class="p-3 text-xs text-secondary">'),E=g("<div><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text></span></div><div class=file-list-item-stats><span class=file-list-item-additions>+</span><span class=file-list-item-deletions>-"),U=g("<span class=files-tab-selected-path><span class=file-path-text>"),X=g('<div class=files-tab-stats style="flex:0 0 auto"><span class="files-tab-stat files-tab-stat-additions"><span class=files-tab-stat-value>+</span></span><span class="files-tab-stat files-tab-stat-deletions"><span class=files-tab-stat-value>-'),Y=g("<div style=margin-left:auto>");const Z=q(()=>K(()=>import("./monaco-viewer-DANembz4.js").then(e=>e.ad),__vite__mapDeps([0,1,2,3,4])).then(e=>({default:e.MonacoDiffViewer}))),fe=e=>{const M=f(()=>e.activeSessionId()),S=f(()=>!!(M()&&M()!=="info")),D=f(()=>S()?e.activeSessionDiffs():null),m=f(()=>{const n=D();return Array.isArray(n)?[...n].sort((i,l)=>String(i.file||"").localeCompare(String(l.file||""))):[]}),R=f(()=>m().reduce((n,i)=>(n.additions+=typeof i.additions=="number"?i.additions:0,n.deletions+=typeof i.deletions=="number"?i.deletions:0,n),{additions:0,deletions:0})),I=f(()=>{const n=m();return n.length===0?null:n.reduce((i,l)=>{const v=typeof(i==null?void 0:i.additions)=="number"?i.additions:0,y=typeof(i==null?void 0:i.deletions)=="number"?i.deletions:0,x=v+y,k=typeof(l==null?void 0:l.additions)=="number"?l.additions:0,t=typeof(l==null?void 0:l.deletions)=="number"?l.deletions:0,r=k+t;return r>x?l:r<x?i:String(l.file||"").localeCompare(String((i==null?void 0:i.file)||""))<0?l:i},n[0])}),P=f(()=>{const n=e.selectedFile(),i=m();if(n){const l=i.find(v=>v.file===n);if(l)return l}return I()}),O=f(()=>`${e.instanceId}:${S()?M():"no-session"}`),V=f(()=>{if(!S())return e.t("instanceShell.sessionChanges.noSessionSelected");const n=D();return n===void 0?e.t("instanceShell.sessionChanges.loading"):!Array.isArray(n)||n.length===0?e.t("instanceShell.sessionChanges.empty"):e.t("instanceShell.filesShell.viewerEmpty")}),A=f(()=>{const n=P();return n!=null&&n.file?String(n.file):e.t("instanceShell.rightPanel.tabs.changes")});return B(()=>{const n=m(),i=R(),l=P(),v=()=>(()=>{var t=J(),r=t.firstChild;return a(r,c(W,{get when(){return l&&S()&&n.length>0?l:null},get fallback(){return(()=>{var d=p(),s=d.firstChild;return a(s,V),d})()},children:d=>c(j,{get fallback(){return(()=>{var s=p(),u=s.firstChild;return a(u,()=>e.t("instanceInfo.loading")),s})()},get children(){return c(Z,{get scopeKey(){return O()},get path(){return String(d().file||"")},get patch(){return String(d().patch||"")},get viewMode(){return e.diffViewMode()},get contextMode(){return e.diffContextMode()},get wordWrap(){return e.diffWordWrapMode()}})}})})),t})(),y=()=>(()=>{var t=Q();return a(t,V),t})();return c(H,{get header(){return[(()=>{var t=U(),r=t.firstChild;return a(r,A),L(()=>w(t,"title",A())),t})(),(()=>{var t=X(),r=t.firstChild,d=r.firstChild;d.firstChild;var s=r.nextSibling,u=s.firstChild;return u.firstChild,a(d,()=>i.additions,null),a(u,()=>i.deletions,null),t})(),(()=>{var t=Y();return a(t,c(G,{get viewMode(){return e.diffViewMode()},get contextMode(){return e.diffContextMode()},get wordWrapMode(){return e.diffWordWrapMode()},get onViewModeChange(){return e.onViewModeChange},get onContextModeChange(){return e.onContextModeChange},get onWordWrapModeChange(){return e.onWordWrapModeChange}})),t})()]},list:{panel:()=>c(W,{get when(){return n.length>0},get fallback(){return y()},get children(){return c(T,{each:n,children:t=>(()=>{var r=E(),d=r.firstChild,s=d.firstChild,u=s.firstChild,b=s.nextSibling,h=b.firstChild;h.firstChild;var C=h.nextSibling;return C.firstChild,r.$$click=()=>{e.onSelectFile(t.file,e.isPhoneLayout())},a(u,()=>t.file),a(h,()=>t.additions,null),a(C,()=>t.deletions,null),L(o=>{var _=`file-list-item ${(l==null?void 0:l.file)===t.file?"file-list-item-active":""}`,$=t.file;return _!==o.e&&F(r,o.e=_),$!==o.t&&w(s,"title",o.t=$),o},{e:void 0,t:void 0}),r})()})}}),overlay:()=>c(W,{get when(){return n.length>0},get fallback(){return y()},get children(){return c(T,{each:n,children:t=>(()=>{var r=E(),d=r.firstChild,s=d.firstChild,u=s.firstChild,b=s.nextSibling,h=b.firstChild;h.firstChild;var C=h.nextSibling;return C.firstChild,r.$$click=()=>{e.onSelectFile(t.file,!0)},a(u,()=>t.file),a(h,()=>t.additions,null),a(C,()=>t.deletions,null),L(o=>{var _=`file-list-item ${(l==null?void 0:l.file)===t.file?"file-list-item-active":""}`,$=t.file,z=t.file;return _!==o.e&&F(r,o.e=_),$!==o.t&&w(r,"title",o.t=$),z!==o.a&&w(s,"title",o.a=z),o},{e:void 0,t:void 0,a:void 0}),r})()})}})},get viewer(){return v()},get listOpen(){return e.listOpen()},get onToggleList(){return e.onToggleList},get splitWidth(){return e.splitWidth()},get onResizeMouseDown(){return e.onResizeMouseDown},get onResizeTouchStart(){return e.onResizeTouchStart},get isPhoneLayout(){return e.isPhoneLayout()},get overlayAriaLabel(){return e.t("instanceShell.rightPanel.tabs.changes")}})})};N(["click"]);export{fe as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as g,i as c,m as W,d as i,a as S,f as T}from"./monaco-viewer-
|
|
1
|
+
import{t as g,i as c,m as W,d as i,a as S,f as T}from"./monaco-viewer-DANembz4.js";import{u as C}from"./index-DE6KDkkL.js";import{n as o,m as $,a as V}from"./git-diff-vendor-CSgooKT_.js";import{I as U,S as A,T as I}from"./main-3oghJUx8.js";import{A as D,W as E}from"./wrap-text-DngNWpNA.js";const F=[["path",{d:"M12 22v-6",key:"6o8u61"}],["path",{d:"M12 8V2",key:"1wkif3"}],["path",{d:"M4 12H2",key:"rhcxmi"}],["path",{d:"M10 12H8",key:"s88cx1"}],["path",{d:"M16 12h-2",key:"10asgb"}],["path",{d:"M22 12h-2",key:"14jgyd"}],["path",{d:"m15 19-3 3-3-3",key:"11eu04"}],["path",{d:"m15 5-3-3-3 3",key:"itvq4r"}]],H=t=>o(U,$(t,{name:"UnfoldVertical",iconNode:F}));var N=g("<div class=file-viewer-toolbar><button type=button class=file-viewer-toolbar-icon-button></button><button type=button class=file-viewer-toolbar-icon-button></button><button type=button>");const z=t=>{const{t:a}=C(),r=()=>t.viewMode==="split"?"unified":"split",s=()=>t.contextMode==="collapsed"?"expanded":"collapsed",h=()=>t.wordWrapMode==="on"?"off":"on",f=()=>r()==="split"?a("instanceShell.diff.switchToSplit"):a("instanceShell.diff.switchToUnified"),v=()=>s()==="collapsed"?a("instanceShell.diff.hideUnchanged"):a("instanceShell.diff.showFull"),u=()=>h()==="on"?a("instanceShell.diff.enableWordWrap"):a("instanceShell.diff.disableWordWrap");return(()=>{var b=N(),n=b.firstChild,l=n.nextSibling,d=l.nextSibling;return n.$$click=()=>t.onViewModeChange(r()),c(n,(()=>{var e=W(()=>r()==="split");return()=>e()?o(A,{class:"h-4 w-4","aria-hidden":"true"}):o(D,{class:"h-4 w-4","aria-hidden":"true"})})()),l.$$click=()=>t.onContextModeChange(s()),c(l,(()=>{var e=W(()=>s()==="collapsed");return()=>e()?o(I,{class:"h-4 w-4","aria-hidden":"true"}):o(H,{class:"h-4 w-4","aria-hidden":"true"})})()),d.$$click=()=>t.onWordWrapModeChange(h()),c(d,o(E,{class:"h-4 w-4","aria-hidden":"true"})),V(e=>{var m=f(),w=f(),M=v(),p=v(),x=`file-viewer-toolbar-icon-button${t.wordWrapMode==="on"?" active":""}`,k=u(),y=u();return m!==e.e&&i(n,"aria-label",e.e=m),w!==e.t&&i(n,"title",e.t=w),M!==e.a&&i(l,"aria-label",e.a=M),p!==e.o&&i(l,"title",e.o=p),x!==e.i&&S(d,e.i=x),k!==e.n&&i(d,"aria-label",e.n=k),y!==e.s&&i(d,"title",e.s=y),e},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0}),b})()};T(["click"]);export{z as D};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-
|
|
2
|
-
import{_ as R}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-DANembz4.js","assets/git-diff-vendor-CSgooKT_.js","assets/fast-diff-vendor-DgdwVvTQ.js","assets/highlight-vendor-8FKMu9os.js","assets/git-diff-vendor-HAZkIolJ.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{_ as R}from"./index-DE6KDkkL.js";import{m as _,t as o,i as s,d as c,a as z,f as I}from"./monaco-viewer-DANembz4.js";import{n as i,m as D,S as d,a as v,F,z as V,A as M}from"./git-diff-vendor-CSgooKT_.js";import{S as T}from"./SplitFilePanel-DhUmaW0S.js";import{I as A,R as y}from"./main-3oghJUx8.js";import"./fast-diff-vendor-DgdwVvTQ.js";import"./highlight-vendor-8FKMu9os.js";const O=[["path",{d:"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z",key:"1owoqh"}],["polyline",{points:"17 21 17 13 7 13 7 21",key:"1md35c"}],["polyline",{points:"7 3 7 8 15 8",key:"8nz8an"}]],q=e=>i(A,D(e,{name:"Save",iconNode:O}));var g=o("<div class=file-viewer-empty><span class=file-viewer-empty-text>"),K=o('<div class="file-viewer-panel flex-1"><div class="file-viewer-content file-viewer-content--monaco">'),N=o('<div class="p-3 text-xs text-secondary">'),W=o("<div class=file-list-item><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text>.."),H=o('<div><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text></span></div><div class=file-list-item-stats><span class="text-[10px] text-secondary">'),j=o("<span>"),B=o("<div class=files-tab-stats><span class=files-tab-stat><span class=files-tab-selected-path><span class=file-path-text>"),G=o("<button type=button class=files-header-icon-button style=margin-inline-start:auto>"),J=o("<button type=button class=files-header-icon-button>"),Q=o("<span class=text-error>");const U=M(()=>R(()=>import("./monaco-viewer-DANembz4.js").then(e=>e.ae),__vite__mapDeps([0,1,2,3,4])).then(e=>({default:e.MonacoFileViewer}))),ae=e=>{const C=()=>{const h=e.browserSelectedContent();h!=null&&e.onSave(h)};return _(()=>{const h=e.browserEntries(),P=[...h||[]].sort((t,n)=>{const r=t.type==="directory"?0:1,l=n.type==="directory"?0:1;return r!==l?r-l:String(t.name||"").localeCompare(String(n.name||""))}),L=e.parentPath(),w=()=>e.browserSelectedPath()||e.browserPath(),x=()=>e.browserLoading()&&h===null?e.t("instanceInfo.loading"):e.t("instanceShell.filesShell.viewerEmpty"),k=()=>(()=>{var t=K(),n=t.firstChild;return s(n,i(d,{get when(){return e.browserSelectedLoading()},get fallback(){return i(d,{get when(){return e.browserSelectedError()},get fallback(){return i(d,{get when(){return _(()=>!!(e.browserSelectedPath()&&e.browserSelectedContent()!==null))()?{path:e.browserSelectedPath(),content:e.browserSelectedContent()}:null},get fallback(){return(()=>{var r=g(),l=r.firstChild;return s(l,x),r})()},children:r=>i(V,{get fallback(){return(()=>{var l=g(),a=l.firstChild;return s(a,()=>e.t("instanceInfo.loading")),l})()},get children(){return i(U,{get scopeKey(){return e.scopeKey()},get path(){return r().path},get content(){return r().content},get onSave(){return e.onSave},get onContentChange(){return e.onContentChange}})}})})},children:r=>(()=>{var l=g(),a=l.firstChild;return s(a,r),l})()})},get children(){var r=g(),l=r.firstChild;return s(l,()=>e.t("instanceInfo.loading")),r}})),t})(),m=()=>[i(d,{when:L,children:t=>(()=>{var n=W(),r=n.firstChild,l=r.firstChild;return n.$$click=()=>e.onLoadEntries(t()),v(()=>c(l,"title",t())),n})()}),i(d,{get when(){return e.browserLoading()&&h===null},get children(){var t=N();return s(t,()=>e.t("instanceInfo.loading")),t}}),i(F,{each:P,children:t=>(()=>{var n=H(),r=n.firstChild,l=r.firstChild,a=l.firstChild,f=l.nextSibling,E=f.firstChild;return n.$$click=()=>{if(t.type==="directory"){e.onLoadEntries(t.path);return}e.onRequestOpenFile(t.path)},s(a,()=>t.name),s(E,()=>t.type),v(u=>{var b=`file-list-item ${e.browserSelectedPath()===t.path?"file-list-item-active":""}`,S=t.path,$=t.path;return b!==u.e&&z(n,u.e=b),S!==u.t&&c(n,"title",u.t=S),$!==u.a&&c(l,"title",u.a=$),u},{e:void 0,t:void 0,a:void 0}),n})()})];return i(T,{get header(){return[(()=>{var t=B(),n=t.firstChild,r=n.firstChild,l=r.firstChild;return s(l,w),s(t,i(d,{get when(){return e.browserLoading()},get children(){var a=j();return s(a,()=>e.t("instanceInfo.loading")),a}}),null),s(t,i(d,{get when(){return e.browserError()},children:a=>(()=>{var f=Q();return s(f,a),f})()}),null),v(()=>c(r,"title",w())),t})(),(()=>{var t=G();return t.$$click=C,s(t,i(d,{get when(){return e.browserSelectedSaving()},get fallback(){return i(q,{class:"h-4 w-4"})},get children(){return i(y,{class:"h-4 w-4 animate-spin"})}})),v(n=>{var r=e.t("instanceShell.rightPanel.actions.save")||"Save (Ctrl+S)",l=e.t("instanceShell.rightPanel.actions.save")||"Save",a=e.browserSelectedSaving()||!e.browserSelectedDirty();return r!==n.e&&c(t,"title",n.e=r),l!==n.t&&c(t,"aria-label",n.t=l),a!==n.a&&(t.disabled=n.a=a),n},{e:void 0,t:void 0,a:void 0}),t})(),(()=>{var t=J();return t.$$click=()=>e.onRefresh(),s(t,i(y,{get class(){return`h-4 w-4${e.browserLoading()?" animate-spin":""}`}})),v(n=>{var r=e.t("instanceShell.rightPanel.actions.refresh"),l=e.t("instanceShell.rightPanel.actions.refresh"),a=e.browserLoading();return r!==n.e&&c(t,"title",n.e=r),l!==n.t&&c(t,"aria-label",n.t=l),a!==n.a&&(t.disabled=n.a=a),n},{e:void 0,t:void 0,a:void 0}),t})()]},list:{panel:m,overlay:m},get viewer(){return k()},get listOpen(){return e.listOpen()},get onToggleList(){return e.onToggleList},get splitWidth(){return e.splitWidth()},get onResizeMouseDown(){return e.onResizeMouseDown},get onResizeTouchStart(){return e.onResizeTouchStart},get isPhoneLayout(){return e.isPhoneLayout()},get overlayAriaLabel(){return e.t("instanceShell.rightPanel.tabs.files")}})})};I(["click"]);export{ae as default};
|