@neuralnomads/codenomad-dev 0.13.3-dev-20260401-9d6a5bcd → 0.13.3-dev-20260402-19a4c3df
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/auth/manager.js +9 -1
- package/dist/config/schema.js +1 -0
- package/dist/index.js +26 -6
- package/dist/server/__tests__/network-addresses.test.js +68 -0
- package/dist/server/http-server.js +2 -0
- package/dist/server/network-addresses.js +43 -1
- package/dist/server/routes/meta.js +0 -3
- package/dist/server/routes/remote-servers.js +142 -0
- package/dist/settings/migrate.js +5 -0
- package/dist/settings/service.js +64 -4
- package/dist/workspaces/manager.js +2 -0
- package/dist/workspaces/runtime.js +2 -1
- package/package.json +1 -1
- package/public/assets/ChangesTab-CmUh1lD6.js +2 -0
- package/public/assets/DiffToolbar-BO2mraG6.js +1 -0
- package/public/assets/{FilesTab-BpYPA_Zr.js → FilesTab-eqP9iJFz.js} +2 -2
- package/public/assets/GitChangesTab-DyQyRmoO.js +2 -0
- package/public/assets/{SplitFilePanel-DwrJM7GQ.js → SplitFilePanel-DvXBnKhO.js} +1 -1
- package/public/assets/StatusTab-B2B6v-Eg.js +1 -0
- package/public/assets/{bundle-full-JwmTIwMd.js → bundle-full-CWbff1l0.js} +1 -1
- package/public/assets/diff-viewer-D0a6LOK6.js +1 -0
- package/public/assets/index-BTg3IYTI.js +1 -0
- package/public/assets/{index-CkYwnPl7.js → index-C9VkLCt-.js} +1 -1
- package/public/assets/index-CY6GNG9A.js +1 -0
- package/public/assets/index-CfoVNw2d.js +2 -0
- package/public/assets/index-DHqgtrcH.js +1 -0
- package/public/assets/index-DPhIvE8c.js +1 -0
- package/public/assets/{index-LmDdmmJP.js → index-Dl_aI0rQ.js} +1 -1
- package/public/assets/index-Wj66Yen3.js +1 -0
- package/public/assets/index-Y07FhVRK.css +1 -0
- package/public/assets/index-vxahkr1I.js +1 -0
- package/public/assets/{loading-CfqkoCbA.js → loading-BMaruoBO.js} +1 -1
- package/public/assets/main-CH4aDUD4.js +56 -0
- package/public/assets/{markdown-D2uUJada.js → markdown-2ayBrByq.js} +3 -3
- package/public/assets/monaco-viewer-DUhWC7BI.js +15 -0
- package/public/assets/{todo-i3zWdksA.js → todo-D5pIlYqO.js} +1 -1
- package/public/assets/tool-call-BuEF2-g9.js +60 -0
- package/public/assets/{unified-picker-B506AoQt.js → unified-picker-C-OVvqSd.js} +1 -1
- package/public/assets/wrap-text-DD_eCVvu.js +1 -0
- package/public/index.html +4 -4
- package/public/loading.html +4 -4
- package/public/sw.js +1 -1
- package/public/assets/ChangesTab-X8IIoIdB.js +0 -2
- package/public/assets/DiffToolbar-Djg0ksr_.js +0 -1
- package/public/assets/GitChangesTab-DeGsV8--.js +0 -2
- package/public/assets/StatusTab-mT1B3wST.js +0 -1
- package/public/assets/diff-viewer-CKnTxbWB.js +0 -1
- package/public/assets/index-BEzx5r3P.css +0 -1
- package/public/assets/index-BHjkPi4D.js +0 -1
- package/public/assets/index-CUkIenrg.js +0 -1
- package/public/assets/index-D9RMxxcS.js +0 -1
- package/public/assets/index-DiFfJ0HM.js +0 -1
- package/public/assets/index-UaIyK67v.js +0 -1
- package/public/assets/index-lhjxIgwf.js +0 -2
- package/public/assets/index-xsUu1uOf.js +0 -1
- package/public/assets/main-B3yZBpaS.js +0 -56
- package/public/assets/monaco-viewer-UU9TfOpS.js +0 -15
- package/public/assets/tool-call-Bl3Lai68.js +0 -60
package/dist/auth/manager.js
CHANGED
|
@@ -11,7 +11,7 @@ export class AuthManager {
|
|
|
11
11
|
this.init = init;
|
|
12
12
|
this.logger = logger;
|
|
13
13
|
this.sessionManager = new SessionManager();
|
|
14
|
-
this.cookieName =
|
|
14
|
+
this.cookieName = sanitizeCookieName(init.cookieName);
|
|
15
15
|
this.authEnabled = !Boolean(init.dangerouslySkipAuth);
|
|
16
16
|
if (!this.authEnabled) {
|
|
17
17
|
this.authStore = null;
|
|
@@ -106,6 +106,14 @@ export class AuthManager {
|
|
|
106
106
|
return this.authStore;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
function sanitizeCookieName(value) {
|
|
110
|
+
const trimmed = value?.trim();
|
|
111
|
+
if (!trimmed) {
|
|
112
|
+
return DEFAULT_AUTH_COOKIE_NAME;
|
|
113
|
+
}
|
|
114
|
+
const sanitized = trimmed.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
115
|
+
return sanitized.length > 0 ? sanitized : DEFAULT_AUTH_COOKIE_NAME;
|
|
116
|
+
}
|
|
109
117
|
function resolveAuthFilePath(configPath) {
|
|
110
118
|
const resolvedConfigPath = resolvePath(configPath);
|
|
111
119
|
return path.join(path.dirname(resolvedConfigPath), "auth.json");
|
package/dist/config/schema.js
CHANGED
|
@@ -23,6 +23,7 @@ const PreferencesSchema = z
|
|
|
23
23
|
showUsageMetrics: z.boolean().default(true),
|
|
24
24
|
autoCleanupBlankSessions: z.boolean().default(true),
|
|
25
25
|
listeningMode: z.enum(["local", "all"]).default("local"),
|
|
26
|
+
logLevel: z.enum(["DEBUG", "INFO", "WARN", "ERROR"]).default("DEBUG"),
|
|
26
27
|
// OS notifications
|
|
27
28
|
osNotificationsEnabled: z.boolean().default(false),
|
|
28
29
|
osNotificationsAllowWhenVisible: z.boolean().default(false),
|
package/dist/index.js
CHANGED
|
@@ -18,9 +18,9 @@ import { InstanceEventBridge } from "./workspaces/instance-events";
|
|
|
18
18
|
import { createLogger } from "./logger";
|
|
19
19
|
import { launchInBrowser } from "./launcher";
|
|
20
20
|
import { resolveUi } from "./ui/remote-ui";
|
|
21
|
-
import { AuthManager, BOOTSTRAP_TOKEN_STDOUT_PREFIX, DEFAULT_AUTH_USERNAME } from "./auth/manager";
|
|
21
|
+
import { AuthManager, BOOTSTRAP_TOKEN_STDOUT_PREFIX, DEFAULT_AUTH_COOKIE_NAME, DEFAULT_AUTH_USERNAME } from "./auth/manager";
|
|
22
22
|
import { resolveHttpsOptions } from "./server/tls";
|
|
23
|
-
import { resolveNetworkAddresses } from "./server/network-addresses";
|
|
23
|
+
import { resolveNetworkAddresses, resolveRemoteAddresses } from "./server/network-addresses";
|
|
24
24
|
import { startDevReleaseMonitor } from "./releases/dev-release-monitor";
|
|
25
25
|
import { SpeechService } from "./speech/service";
|
|
26
26
|
const require = createRequire(import.meta.url);
|
|
@@ -62,6 +62,9 @@ function parseCliOptions(argv) {
|
|
|
62
62
|
.env("CODENOMAD_SERVER_USERNAME")
|
|
63
63
|
.default(DEFAULT_AUTH_USERNAME))
|
|
64
64
|
.addOption(new Option("--password <password>", "Password for server authentication").env("CODENOMAD_SERVER_PASSWORD"))
|
|
65
|
+
.addOption(new Option("--auth-cookie-name <name>", "Cookie name for server authentication")
|
|
66
|
+
.env("CODENOMAD_AUTH_COOKIE_NAME")
|
|
67
|
+
.default(DEFAULT_AUTH_COOKIE_NAME))
|
|
65
68
|
.addOption(new Option("--generate-token", "Emit a one-time bootstrap token for desktop")
|
|
66
69
|
.env("CODENOMAD_GENERATE_TOKEN")
|
|
67
70
|
.default(false))
|
|
@@ -106,6 +109,7 @@ function parseCliOptions(argv) {
|
|
|
106
109
|
launch: Boolean(parsed.launch),
|
|
107
110
|
authUsername: parsed.username,
|
|
108
111
|
authPassword: parsed.password,
|
|
112
|
+
authCookieName: parsed.authCookieName,
|
|
109
113
|
generateToken: Boolean(parsed.generateToken),
|
|
110
114
|
dangerouslySkipAuth: Boolean(parsed.dangerouslySkipAuth),
|
|
111
115
|
};
|
|
@@ -169,6 +173,7 @@ async function main() {
|
|
|
169
173
|
configPath: configLocation.configYamlPath,
|
|
170
174
|
username: options.authUsername,
|
|
171
175
|
password: options.authPassword,
|
|
176
|
+
cookieName: options.authCookieName,
|
|
172
177
|
generateToken: options.generateToken,
|
|
173
178
|
dangerouslySkipAuth: options.dangerouslySkipAuth,
|
|
174
179
|
}, logger.child({ component: "auth" }));
|
|
@@ -323,19 +328,23 @@ async function main() {
|
|
|
323
328
|
// which can lead clients to talk to the wrong process.
|
|
324
329
|
const localUrl = `${localProtocol}://127.0.0.1:${localStart.port}`;
|
|
325
330
|
let remoteUrl;
|
|
331
|
+
let remoteAddresses = [];
|
|
326
332
|
if (remoteStart) {
|
|
327
333
|
const wantsAll = options.host === "0.0.0.0" || !isLoopbackHost(options.host);
|
|
328
334
|
let remoteHost = options.host;
|
|
329
335
|
if (wantsAll) {
|
|
330
336
|
if (options.host === "0.0.0.0") {
|
|
331
|
-
const
|
|
332
|
-
|
|
337
|
+
const resolved = resolveRemoteAddresses({ host: options.host, protocol: remoteProtocol, port: remoteStart.port });
|
|
338
|
+
remoteAddresses = resolved.userVisible;
|
|
339
|
+
remoteUrl = resolved.primaryRemoteUrl ?? `${remoteProtocol}://localhost:${remoteStart.port}`;
|
|
333
340
|
}
|
|
334
341
|
}
|
|
335
342
|
else {
|
|
336
343
|
remoteHost = "localhost";
|
|
337
344
|
}
|
|
338
|
-
remoteUrl
|
|
345
|
+
if (!remoteUrl) {
|
|
346
|
+
remoteUrl = `${remoteProtocol}://${remoteHost}:${remoteStart.port}`;
|
|
347
|
+
}
|
|
339
348
|
}
|
|
340
349
|
serverMeta.localUrl = localUrl;
|
|
341
350
|
serverMeta.localPort = localStart.port;
|
|
@@ -344,7 +353,9 @@ async function main() {
|
|
|
344
353
|
serverMeta.host = options.host;
|
|
345
354
|
serverMeta.listeningMode = options.host === "0.0.0.0" || !isLoopbackHost(options.host) ? "all" : "local";
|
|
346
355
|
if (serverMeta.remotePort && remoteUrl) {
|
|
347
|
-
serverMeta.addresses =
|
|
356
|
+
serverMeta.addresses = remoteAddresses.length
|
|
357
|
+
? remoteAddresses
|
|
358
|
+
: resolveNetworkAddresses({ host: options.host, protocol: remoteProtocol, port: serverMeta.remotePort });
|
|
348
359
|
}
|
|
349
360
|
else {
|
|
350
361
|
serverMeta.addresses = [];
|
|
@@ -352,6 +363,15 @@ async function main() {
|
|
|
352
363
|
console.log(`Local Connection URL : ${serverMeta.localUrl}`);
|
|
353
364
|
if (serverMeta.remoteUrl) {
|
|
354
365
|
console.log(`Remote Connection URL : ${serverMeta.remoteUrl}`);
|
|
366
|
+
const additionalRemoteUrls = serverMeta.addresses
|
|
367
|
+
.map((addr) => addr.remoteUrl)
|
|
368
|
+
.filter((url) => url !== serverMeta.remoteUrl);
|
|
369
|
+
if (additionalRemoteUrls.length > 0) {
|
|
370
|
+
console.log("Other Accessible URLs:");
|
|
371
|
+
for (const url of additionalRemoteUrls) {
|
|
372
|
+
console.log(` - ${url}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
355
375
|
}
|
|
356
376
|
if (options.launch) {
|
|
357
377
|
await launchInBrowser(serverMeta.localUrl, logger.child({ component: "launcher" }));
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import { describe, it } from "node:test";
|
|
4
|
+
import { resolveNetworkAddresses, resolveRemoteAddresses } from "../network-addresses";
|
|
5
|
+
describe("resolveNetworkAddresses", () => {
|
|
6
|
+
it("preserves interface order among external addresses", () => {
|
|
7
|
+
const addresses = [
|
|
8
|
+
{ address: "172.24.0.1", family: "IPv4", internal: false },
|
|
9
|
+
{ address: "192.168.1.128", family: "IPv4", internal: false },
|
|
10
|
+
{ address: "10.0.0.8", family: 4, internal: false },
|
|
11
|
+
{ address: "127.0.0.1", family: "IPv4", internal: true },
|
|
12
|
+
{ address: "169.254.10.20", family: "IPv4", internal: false },
|
|
13
|
+
];
|
|
14
|
+
usingMockedNetworkInterfaces(addresses, () => {
|
|
15
|
+
const result = resolveNetworkAddresses({ host: "0.0.0.0", protocol: "https", port: 9898 });
|
|
16
|
+
assert.deepEqual(result.map((entry) => entry.ip), ["172.24.0.1", "192.168.1.128", "10.0.0.8", "169.254.10.20", "127.0.0.1"]);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe("resolveRemoteAddresses", () => {
|
|
21
|
+
it("keeps all external addresses user-visible while preferring non-link-local addresses for the primary URL", () => {
|
|
22
|
+
const addresses = [
|
|
23
|
+
{ address: "169.254.10.20", family: "IPv4", internal: false },
|
|
24
|
+
{ address: "192.168.1.128", family: "IPv4", internal: false },
|
|
25
|
+
{ address: "172.24.0.1", family: "IPv4", internal: false },
|
|
26
|
+
];
|
|
27
|
+
usingMockedNetworkInterfaces(addresses, () => {
|
|
28
|
+
const result = resolveRemoteAddresses({ host: "0.0.0.0", protocol: "https", port: 9898 });
|
|
29
|
+
assert.deepEqual(result.userVisible.map((entry) => entry.ip), ["192.168.1.128", "172.24.0.1", "169.254.10.20"]);
|
|
30
|
+
assert.equal(result.primaryRemoteUrl, "https://192.168.1.128:9898");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
it("prefers private LAN addresses over public addresses", () => {
|
|
34
|
+
const addresses = [
|
|
35
|
+
{ address: "203.0.113.40", family: "IPv4", internal: false },
|
|
36
|
+
{ address: "192.168.1.128", family: "IPv4", internal: false },
|
|
37
|
+
{ address: "8.8.8.8", family: "IPv4", internal: false },
|
|
38
|
+
];
|
|
39
|
+
usingMockedNetworkInterfaces(addresses, () => {
|
|
40
|
+
const result = resolveRemoteAddresses({ host: "0.0.0.0", protocol: "https", port: 9898 });
|
|
41
|
+
assert.deepEqual(result.userVisible.map((entry) => entry.ip), ["192.168.1.128", "203.0.113.40", "8.8.8.8"]);
|
|
42
|
+
assert.equal(result.primaryRemoteUrl, "https://192.168.1.128:9898");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
it("uses a public address when no private LAN address is available", () => {
|
|
46
|
+
const addresses = [
|
|
47
|
+
{ address: "169.254.10.20", family: "IPv4", internal: false },
|
|
48
|
+
{ address: "203.0.113.40", family: "IPv4", internal: false },
|
|
49
|
+
];
|
|
50
|
+
usingMockedNetworkInterfaces(addresses, () => {
|
|
51
|
+
const result = resolveRemoteAddresses({ host: "0.0.0.0", protocol: "https", port: 9898 });
|
|
52
|
+
assert.deepEqual(result.userVisible.map((entry) => entry.ip), ["203.0.113.40", "169.254.10.20"]);
|
|
53
|
+
assert.equal(result.primaryRemoteUrl, "https://203.0.113.40:9898");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
function usingMockedNetworkInterfaces(addresses, callback) {
|
|
58
|
+
const original = os.networkInterfaces;
|
|
59
|
+
os.networkInterfaces = (() => ({
|
|
60
|
+
ethernet0: addresses,
|
|
61
|
+
}));
|
|
62
|
+
try {
|
|
63
|
+
callback();
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
os.networkInterfaces = original;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -16,6 +16,7 @@ import { registerPluginRoutes } from "./routes/plugin";
|
|
|
16
16
|
import { registerBackgroundProcessRoutes } from "./routes/background-processes";
|
|
17
17
|
import { registerWorktreeRoutes } from "./routes/worktrees";
|
|
18
18
|
import { registerSpeechRoutes } from "./routes/speech";
|
|
19
|
+
import { registerRemoteServerRoutes } from "./routes/remote-servers";
|
|
19
20
|
import { BackgroundProcessManager } from "../background-processes/manager";
|
|
20
21
|
import { registerAuthRoutes } from "./routes/auth";
|
|
21
22
|
import { sendUnauthorized, wantsHtml } from "../auth/http-auth";
|
|
@@ -207,6 +208,7 @@ export function createHttpServer(deps) {
|
|
|
207
208
|
eventBus: deps.eventBus,
|
|
208
209
|
workspaceManager: deps.workspaceManager,
|
|
209
210
|
});
|
|
211
|
+
registerRemoteServerRoutes(app, { logger: apiLogger });
|
|
210
212
|
registerSpeechRoutes(app, { speechService: deps.speechService });
|
|
211
213
|
registerPluginRoutes(app, {
|
|
212
214
|
workspaceManager: deps.workspaceManager,
|
|
@@ -52,9 +52,51 @@ export function resolveNetworkAddresses(args) {
|
|
|
52
52
|
const scopeDelta = scopeWeight[a.scope] - scopeWeight[b.scope];
|
|
53
53
|
if (scopeDelta !== 0)
|
|
54
54
|
return scopeDelta;
|
|
55
|
-
return
|
|
55
|
+
return 0;
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
|
+
export function resolveRemoteAddresses(args) {
|
|
59
|
+
const all = resolveNetworkAddresses(args);
|
|
60
|
+
const userVisible = sortUserVisibleAddresses(all.filter((address) => address.scope === "external"));
|
|
61
|
+
return {
|
|
62
|
+
all,
|
|
63
|
+
userVisible,
|
|
64
|
+
primaryRemoteUrl: userVisible[0]?.remoteUrl,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function sortUserVisibleAddresses(addresses) {
|
|
68
|
+
return [...addresses].sort((left, right) => getUserVisiblePriority(left.ip) - getUserVisiblePriority(right.ip));
|
|
69
|
+
}
|
|
70
|
+
function getUserVisiblePriority(ip) {
|
|
71
|
+
if (isPrivateIPv4(ip))
|
|
72
|
+
return 0;
|
|
73
|
+
if (isLinkLocalIPv4(ip))
|
|
74
|
+
return 2;
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
function isLinkLocalIPv4(ip) {
|
|
78
|
+
const octets = parseIPv4(ip);
|
|
79
|
+
if (!octets)
|
|
80
|
+
return false;
|
|
81
|
+
const [first, second] = octets;
|
|
82
|
+
return first === 169 && second === 254;
|
|
83
|
+
}
|
|
84
|
+
function isPrivateIPv4(ip) {
|
|
85
|
+
const octets = parseIPv4(ip);
|
|
86
|
+
if (!octets)
|
|
87
|
+
return false;
|
|
88
|
+
const [first, second] = octets;
|
|
89
|
+
if (first === 10)
|
|
90
|
+
return true;
|
|
91
|
+
if (first === 192 && second === 168)
|
|
92
|
+
return true;
|
|
93
|
+
return first === 172 && second >= 16 && second <= 31;
|
|
94
|
+
}
|
|
95
|
+
function parseIPv4(value) {
|
|
96
|
+
if (!isIPv4Address(value))
|
|
97
|
+
return null;
|
|
98
|
+
return value.split(".").map((part) => Number(part));
|
|
99
|
+
}
|
|
58
100
|
function isIPv4Address(value) {
|
|
59
101
|
if (!value)
|
|
60
102
|
return false;
|
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import { resolveNetworkAddresses } from "../network-addresses";
|
|
2
1
|
export function registerMetaRoutes(app, deps) {
|
|
3
2
|
app.get("/api/meta", async () => buildMetaResponse(deps.serverMeta));
|
|
4
3
|
}
|
|
5
4
|
function buildMetaResponse(meta) {
|
|
6
5
|
const localPort = resolveLocalPort(meta);
|
|
7
6
|
const remote = resolveRemote(meta);
|
|
8
|
-
const addresses = remote && remote.port > 0 ? resolveNetworkAddresses({ host: meta.host, protocol: remote.protocol, port: remote.port }) : [];
|
|
9
7
|
return {
|
|
10
8
|
...meta,
|
|
11
9
|
localPort,
|
|
12
10
|
remotePort: remote?.port,
|
|
13
11
|
listeningMode: meta.host === "0.0.0.0" || !isLoopbackHost(meta.host) ? "all" : "local",
|
|
14
|
-
addresses,
|
|
15
12
|
};
|
|
16
13
|
}
|
|
17
14
|
function resolveLocalPort(meta) {
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Agent, fetch } from "undici";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const ProbeSchema = z.object({
|
|
4
|
+
baseUrl: z.string().min(1),
|
|
5
|
+
skipTlsVerify: z.boolean().optional(),
|
|
6
|
+
});
|
|
7
|
+
const PROBE_TIMEOUT_MS = 8000;
|
|
8
|
+
export function registerRemoteServerRoutes(app, deps) {
|
|
9
|
+
app.post("/api/remote-servers/probe", async (request, reply) => {
|
|
10
|
+
try {
|
|
11
|
+
const body = ProbeSchema.parse(request.body ?? {});
|
|
12
|
+
return await probeRemoteServer(body.baseUrl, Boolean(body.skipTlsVerify));
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
deps.logger.warn({ err: error }, "Failed to probe remote server");
|
|
16
|
+
reply.code(400);
|
|
17
|
+
return { error: error instanceof Error ? error.message : "Invalid request" };
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async function probeRemoteServer(baseUrl, skipTlsVerify) {
|
|
22
|
+
const normalizedUrl = normalizeBaseUrl(baseUrl);
|
|
23
|
+
const probeUrl = new URL("./api/auth/status", `${normalizedUrl}/`);
|
|
24
|
+
const controller = new AbortController();
|
|
25
|
+
const timeout = setTimeout(() => controller.abort(), PROBE_TIMEOUT_MS);
|
|
26
|
+
const dispatcher = skipTlsVerify ? new Agent({ connect: { rejectUnauthorized: false } }) : undefined;
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(probeUrl, {
|
|
29
|
+
method: "GET",
|
|
30
|
+
dispatcher,
|
|
31
|
+
signal: controller.signal,
|
|
32
|
+
headers: {
|
|
33
|
+
Accept: "application/json",
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
reachable: true,
|
|
40
|
+
normalizedUrl,
|
|
41
|
+
skipTlsVerify,
|
|
42
|
+
requiresAuth: false,
|
|
43
|
+
authenticated: false,
|
|
44
|
+
error: `Remote server returned HTTP ${response.status}`,
|
|
45
|
+
errorCode: "http_error",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const payload = (await response.json());
|
|
49
|
+
if (typeof payload?.authenticated !== "boolean") {
|
|
50
|
+
return {
|
|
51
|
+
ok: false,
|
|
52
|
+
reachable: true,
|
|
53
|
+
normalizedUrl,
|
|
54
|
+
skipTlsVerify,
|
|
55
|
+
requiresAuth: false,
|
|
56
|
+
authenticated: false,
|
|
57
|
+
error: "Remote server did not return a valid CodeNomad auth response",
|
|
58
|
+
errorCode: "invalid_server",
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
ok: true,
|
|
63
|
+
reachable: true,
|
|
64
|
+
normalizedUrl,
|
|
65
|
+
skipTlsVerify,
|
|
66
|
+
requiresAuth: !payload.authenticated,
|
|
67
|
+
authenticated: payload.authenticated,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const message = describeProbeError(error);
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
reachable: false,
|
|
75
|
+
normalizedUrl,
|
|
76
|
+
skipTlsVerify,
|
|
77
|
+
requiresAuth: false,
|
|
78
|
+
authenticated: false,
|
|
79
|
+
error: message.message,
|
|
80
|
+
errorCode: message.code,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
clearTimeout(timeout);
|
|
85
|
+
await dispatcher?.close().catch(() => { });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function normalizeBaseUrl(input) {
|
|
89
|
+
const parsed = new URL(input.trim());
|
|
90
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
91
|
+
throw new Error("Server URL must use http:// or https://");
|
|
92
|
+
}
|
|
93
|
+
parsed.hash = "";
|
|
94
|
+
parsed.search = "";
|
|
95
|
+
parsed.pathname = parsed.pathname === "/" ? "/" : parsed.pathname.replace(/\/+$/, "") || "/";
|
|
96
|
+
const value = parsed.toString();
|
|
97
|
+
return parsed.pathname === "/" ? value.replace(/\/$/, "") : value.replace(/\/$/, "");
|
|
98
|
+
}
|
|
99
|
+
function describeProbeError(error) {
|
|
100
|
+
const chain = unwrapErrorChain(error);
|
|
101
|
+
const detailed = chain.find((entry) => {
|
|
102
|
+
const code = (entry?.code ?? "").toString();
|
|
103
|
+
return Boolean(code) && code !== "UND_ERR_RESPONSE_STATUS_CODE";
|
|
104
|
+
}) ?? chain[0];
|
|
105
|
+
const code = (detailed?.code ?? "").toString();
|
|
106
|
+
const exactMessage = detailed?.message?.trim() || chain.find((entry) => entry.message?.trim())?.message?.trim();
|
|
107
|
+
if (code === "DEPTH_ZERO_SELF_SIGNED_CERT" || code === "SELF_SIGNED_CERT_IN_CHAIN" || code === "CERT_HAS_EXPIRED") {
|
|
108
|
+
return {
|
|
109
|
+
code: "tls_error",
|
|
110
|
+
message: "Certificate check failed while connecting to the remote server.",
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
code: code === "ERR_INVALID_URL"
|
|
115
|
+
? "invalid_url"
|
|
116
|
+
: code === "ECONNREFUSED"
|
|
117
|
+
? "connection_refused"
|
|
118
|
+
: code === "ENOTFOUND"
|
|
119
|
+
? "dns_error"
|
|
120
|
+
: code === "UND_ERR_CONNECT_TIMEOUT" || code === "ABORT_ERR"
|
|
121
|
+
? "timeout"
|
|
122
|
+
: code
|
|
123
|
+
? code.toLowerCase()
|
|
124
|
+
: "probe_failed",
|
|
125
|
+
message: exactMessage || "Failed to connect to the remote server.",
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function unwrapErrorChain(error) {
|
|
129
|
+
const results = [];
|
|
130
|
+
let current = error;
|
|
131
|
+
const seen = new Set();
|
|
132
|
+
while (current && typeof current === "object" && !seen.has(current)) {
|
|
133
|
+
seen.add(current);
|
|
134
|
+
const entry = current;
|
|
135
|
+
results.push({ code: entry.code, message: entry.message });
|
|
136
|
+
current = entry.cause;
|
|
137
|
+
}
|
|
138
|
+
if (results.length === 0 && error instanceof Error) {
|
|
139
|
+
results.push({ message: error.message });
|
|
140
|
+
}
|
|
141
|
+
return results;
|
|
142
|
+
}
|
package/dist/settings/migrate.js
CHANGED
|
@@ -93,6 +93,10 @@ function mapLegacyToOwnerDocs(legacyConfig, legacyState) {
|
|
|
93
93
|
if (typeof listeningMode === "string") {
|
|
94
94
|
serverConfig.listeningMode = listeningMode;
|
|
95
95
|
}
|
|
96
|
+
const logLevel = preferences.logLevel;
|
|
97
|
+
if (typeof logLevel === "string") {
|
|
98
|
+
serverConfig.logLevel = logLevel;
|
|
99
|
+
}
|
|
96
100
|
const lastUsedBinary = preferences.lastUsedBinary;
|
|
97
101
|
if (typeof lastUsedBinary === "string") {
|
|
98
102
|
serverConfig.opencodeBinary = lastUsedBinary;
|
|
@@ -118,6 +122,7 @@ function mapLegacyToOwnerDocs(legacyConfig, legacyState) {
|
|
|
118
122
|
const moved = new Set([
|
|
119
123
|
"environmentVariables",
|
|
120
124
|
"listeningMode",
|
|
125
|
+
"logLevel",
|
|
121
126
|
"lastUsedBinary",
|
|
122
127
|
"modelRecents",
|
|
123
128
|
"modelFavorites",
|
package/dist/settings/service.js
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { YamlDocStore } from "./yaml-doc-store";
|
|
2
3
|
import { migrateSettingsLayout } from "./migrate";
|
|
3
4
|
import { sanitizeConfigOwner } from "./public-config";
|
|
5
|
+
const CanonicalLogLevelSchema = z.preprocess((value) => (typeof value === "string" ? value.trim().toUpperCase() : value), z.enum(["DEBUG", "INFO", "WARN", "ERROR"]));
|
|
6
|
+
function isPlainObject(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function isDeepEqual(a, b) {
|
|
10
|
+
if (a === b)
|
|
11
|
+
return true;
|
|
12
|
+
try {
|
|
13
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function normalizeServerConfigOwner(value) {
|
|
20
|
+
if (!isPlainObject(value)) {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
const next = { ...value };
|
|
24
|
+
const parsedLogLevel = CanonicalLogLevelSchema.safeParse(next.logLevel);
|
|
25
|
+
if (parsedLogLevel.success) {
|
|
26
|
+
next.logLevel = parsedLogLevel.data;
|
|
27
|
+
}
|
|
28
|
+
else if (next.logLevel !== undefined) {
|
|
29
|
+
next.logLevel = "DEBUG";
|
|
30
|
+
}
|
|
31
|
+
return next;
|
|
32
|
+
}
|
|
33
|
+
function normalizeConfigDoc(doc) {
|
|
34
|
+
if (!isPlainObject(doc)) {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
if (!isPlainObject(doc.server)) {
|
|
38
|
+
return doc;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
...doc,
|
|
42
|
+
server: normalizeServerConfigOwner(doc.server),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
4
45
|
export class SettingsService {
|
|
5
46
|
constructor(location, eventBus, logger) {
|
|
6
47
|
this.location = location;
|
|
@@ -11,18 +52,37 @@ export class SettingsService {
|
|
|
11
52
|
this.stateStore = new YamlDocStore(location.stateYamlPath, logger.child({ component: "settings-state" }));
|
|
12
53
|
}
|
|
13
54
|
getDoc(kind) {
|
|
14
|
-
|
|
55
|
+
if (kind !== "config") {
|
|
56
|
+
return this.stateStore.get();
|
|
57
|
+
}
|
|
58
|
+
const current = this.configStore.get();
|
|
59
|
+
const normalized = normalizeConfigDoc(current);
|
|
60
|
+
if (!isDeepEqual(current, normalized)) {
|
|
61
|
+
this.configStore.replace(normalized);
|
|
62
|
+
}
|
|
63
|
+
return normalized;
|
|
15
64
|
}
|
|
16
65
|
mergePatchDoc(kind, patch) {
|
|
17
|
-
const updated = kind === "config"
|
|
66
|
+
const updated = kind === "config"
|
|
67
|
+
? this.configStore.replace(normalizeConfigDoc(this.configStore.mergePatch(patch)))
|
|
68
|
+
: this.stateStore.mergePatch(patch);
|
|
18
69
|
this.publish(kind, "*");
|
|
19
70
|
return updated;
|
|
20
71
|
}
|
|
21
72
|
getOwner(kind, owner) {
|
|
22
|
-
|
|
73
|
+
if (kind !== "config") {
|
|
74
|
+
return this.stateStore.getOwner(owner);
|
|
75
|
+
}
|
|
76
|
+
return owner === "server"
|
|
77
|
+
? normalizeServerConfigOwner(this.getDoc("config").server)
|
|
78
|
+
: this.getDoc("config")[owner];
|
|
23
79
|
}
|
|
24
80
|
mergePatchOwner(kind, owner, patch) {
|
|
25
|
-
const updated = kind === "config"
|
|
81
|
+
const updated = kind === "config"
|
|
82
|
+
? owner === "server"
|
|
83
|
+
? this.configStore.replaceOwner(owner, normalizeServerConfigOwner(this.configStore.mergePatchOwner(owner, patch)))
|
|
84
|
+
: this.configStore.mergePatchOwner(owner, patch)
|
|
85
|
+
: this.stateStore.mergePatchOwner(owner, patch);
|
|
26
86
|
this.publish(kind, owner, updated);
|
|
27
87
|
return updated;
|
|
28
88
|
}
|
|
@@ -93,12 +93,14 @@ export class WorkspaceManager {
|
|
|
93
93
|
[OPENCODE_SERVER_USERNAME_ENV]: opencodeUsername,
|
|
94
94
|
[OPENCODE_SERVER_PASSWORD_ENV]: opencodePassword,
|
|
95
95
|
};
|
|
96
|
+
const logLevel = serverConfig?.logLevel;
|
|
96
97
|
try {
|
|
97
98
|
const { pid, port, exitPromise, getLastOutput } = await this.runtime.launch({
|
|
98
99
|
workspaceId: id,
|
|
99
100
|
folder: workspacePath,
|
|
100
101
|
binaryPath: resolvedBinaryPath,
|
|
101
102
|
environment,
|
|
103
|
+
logLevel,
|
|
102
104
|
onExit: (info) => this.handleProcessExit(info.workspaceId, info),
|
|
103
105
|
});
|
|
104
106
|
const runtimeVersion = await this.waitForWorkspaceReadiness({ workspaceId: id, port, exitPromise, getLastOutput });
|
|
@@ -91,7 +91,8 @@ export class WorkspaceRuntime {
|
|
|
91
91
|
}
|
|
92
92
|
async launch(options) {
|
|
93
93
|
this.validateFolder(options.folder);
|
|
94
|
-
const
|
|
94
|
+
const logLevel = typeof options.logLevel === "string" ? options.logLevel.toUpperCase() : "DEBUG";
|
|
95
|
+
const args = ["serve", "--port", "0", "--print-logs", "--log-level", logLevel];
|
|
95
96
|
const env = { ...process.env, ...(options.environment ?? {}) };
|
|
96
97
|
let exitResolve = null;
|
|
97
98
|
const exitPromise = new Promise((resolveExit) => {
|
package/package.json
CHANGED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-DUhWC7BI.js","assets/git-diff-vendor-CAv-4upN.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-CfoVNw2d.js";import{m as B,t as g,i as a,d as w,a as F,f as N}from"./monaco-viewer-DUhWC7BI.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-CAv-4upN.js";import{D as G}from"./DiffToolbar-BO2mraG6.js";import{S as H}from"./SplitFilePanel-DvXBnKhO.js";import"./fast-diff-vendor-DgdwVvTQ.js";import"./highlight-vendor-8FKMu9os.js";import"./main-CH4aDUD4.js";import"./wrap-text-DD_eCVvu.js";var J=g('<div class="file-viewer-panel flex-1"><div class="file-viewer-content file-viewer-content--monaco">'),E=g("<div class=file-viewer-empty><span class=file-viewer-empty-text>"),Q=g('<div class="p-3 text-xs text-secondary">'),R=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-DUhWC7BI.js").then(e=>e.ab),__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||""))):[]}),I=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})),O=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 O()}),p=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=I(),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 o=E(),s=o.firstChild;return a(s,V),o})()},children:o=>c(j,{get fallback(){return(()=>{var s=E(),u=s.firstChild;return a(u,()=>e.t("instanceInfo.loading")),s})()},get children(){return c(Z,{get scopeKey(){return p()},get path(){return String(o().file||"")},get before(){return String(o().before||"")},get after(){return String(o().after||"")},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,o=r.firstChild;o.firstChild;var s=r.nextSibling,u=s.firstChild;return u.firstChild,a(o,()=>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=R(),o=r.firstChild,s=o.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(d=>{var _=`file-list-item ${(l==null?void 0:l.file)===t.file?"file-list-item-active":""}`,$=t.file;return _!==d.e&&F(r,d.e=_),$!==d.t&&w(s,"title",d.t=$),d},{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=R(),o=r.firstChild,s=o.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(d=>{var _=`file-list-item ${(l==null?void 0:l.file)===t.file?"file-list-item-active":""}`,$=t.file,z=t.file;return _!==d.e&&F(r,d.e=_),$!==d.t&&w(r,"title",d.t=$),z!==d.a&&w(s,"title",d.a=z),d},{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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as g,i as c,m as W,d as i,a as S,f as C}from"./monaco-viewer-DUhWC7BI.js";import{u as T}from"./index-CfoVNw2d.js";import{n as o,m as $,a as V}from"./git-diff-vendor-CAv-4upN.js";import{I as U,S as A,N as I}from"./main-CH4aDUD4.js";import{A as N,W as D}from"./wrap-text-DD_eCVvu.js";const E=[["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"}]],F=t=>o(U,$(t,{name:"UnfoldVertical",iconNode:E}));var H=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}=T(),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=H(),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(N,{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(F,{class:"h-4 w-4","aria-hidden":"true"})})()),d.$$click=()=>t.onWordWrapModeChange(h()),c(d,o(D,{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})()};C(["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-DUhWC7BI.js","assets/git-diff-vendor-CAv-4upN.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-CfoVNw2d.js";import{m as _,t as c,i as s,d as o,a as z,f as I}from"./monaco-viewer-DUhWC7BI.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-CAv-4upN.js";import{S as T}from"./SplitFilePanel-DvXBnKhO.js";import{I as A,R as y}from"./main-CH4aDUD4.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=c("<div class=file-viewer-empty><span class=file-viewer-empty-text>"),K=c('<div class="file-viewer-panel flex-1"><div class="file-viewer-content file-viewer-content--monaco">'),N=c('<div class="p-3 text-xs text-secondary">'),W=c("<div class=file-list-item><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text>.."),H=c('<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=c("<span>"),B=c("<div class=files-tab-stats><span class=files-tab-stat><span class=files-tab-selected-path><span class=file-path-text>"),G=c("<button type=button class=files-header-icon-button style=margin-inline-start:auto>"),J=c("<button type=button class=files-header-icon-button>"),Q=c("<span class=text-error>");const U=M(()=>R(()=>import("./monaco-viewer-DUhWC7BI.js").then(e=>e.ac),__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(()=>o(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&&o(n,"title",u.t=S),$!==u.a&&o(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(()=>o(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&&o(t,"title",n.e=r),l!==n.t&&o(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&&o(t,"title",n.e=r),l!==n.t&&o(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};
|