windows-development-sandbox 1.27.1 → 1.28.0
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/app/context.d.ts +5 -0
- package/dist/app/context.js +13 -0
- package/dist/app/features/accounts/accounts.def.d.ts +16 -0
- package/dist/app/features/accounts/accounts.run.d.ts +4 -0
- package/dist/app/features/accounts/services.def.d.ts +15 -1
- package/dist/app/features/accounts/services.def.js +67 -31
- package/dist/app/features/accounts/services.run.d.ts +7 -2
- package/dist/app/features/accounts/services.run.js +25 -6
- package/dist/app/features/defs.d.ts +17 -0
- package/dist/app/registry.d.ts +1 -1
- package/dist/app/registry.js +15 -2
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-RSIX7C6D.js → chunk-CB44HTTN.js} +444 -175
- package/dist/bin/{chunk-4TLSWPG7.js → chunk-UZ5S3EMB.js} +1 -1
- package/dist/bin/{chunk-QUHNXHVG.js → chunk-ZMZI3625.js} +46 -41
- package/dist/bin/claude-host.js +2 -2
- package/dist/bin/claude-sbx.js +2 -2
- package/dist/bin/codex-sbx.js +2 -2
- package/dist/bin/gemini-sbx.js +2 -2
- package/dist/bin/sandbox.js +2 -2
- package/dist/bin/sbx-hide.js +2 -2
- package/dist/bin/sbx-show.js +2 -2
- package/dist/cli/menu/menu.js +6 -1
- package/dist/cli/menu/pages/accounts-page.js +9 -5
- package/dist/core/schema/sandbox.js +1 -1
- package/dist/guest/apps/app-installer.js +7 -5
- package/dist/guest/apps/comet-unpack.js +2 -2
- package/dist/guest/daemon/heartbeat.js +1 -0
- package/dist/guest/governor/core.d.ts +53 -1
- package/dist/guest/governor/core.js +95 -1
- package/dist/guest/governor/decide.d.ts +4 -0
- package/dist/guest/governor/decide.js +2 -0
- package/dist/guest/governor/governor.js +23 -9
- package/dist/guest/runtime/pools.d.ts +4 -4
- package/dist/guest/runtime/pools.js +4 -15
- package/dist/guest/runtime/process.d.ts +5 -2
- package/dist/guest/runtime/process.js +23 -3
- package/dist/guest/toolchains/engines/epic-launcher.d.ts +6 -0
- package/dist/guest/toolchains/engines/epic-launcher.js +19 -1
- package/dist/guest/toolchains/engines/unreal-engines.js +2 -1
- package/dist/guest/toolchains/installers.d.ts +3 -3
- package/dist/guest/toolchains/installers.js +5 -5
- package/dist/guest/toolchains/native/unreal.js +22 -3
- package/dist/guest/toolchains/native/vcruntime.js +2 -2
- package/dist/guest/toolchains/native/vs-persist.d.ts +2 -2
- package/dist/guest/toolchains/runtimes.js +7 -6
- package/dist/guest/toolchains/signature.d.ts +2 -0
- package/dist/guest/toolchains/signature.js +9 -2
- package/dist/guest/toolchains/step-scheduler.js +1 -1
- package/dist/host/accounts/deliver.js +15 -7
- package/dist/host/life/crash-report.d.ts +4 -0
- package/dist/host/life/crash-report.js +30 -1
- package/dist/host/life/last-end.js +1 -0
- package/dist/host/pc-installs/discover.js +5 -2
- package/dist/host/pc-installs/unreal.d.ts +3 -1
- package/dist/host/pc-installs/unreal.js +27 -1
- package/dist/host/tools/windows-terminal.d.ts +4 -1
- package/dist/host/tools/windows-terminal.js +25 -9
- package/dist/runtime/agent.js +39 -23
- package/dist/runtime/daemon.js +279 -121
- package/dist/runtime/db.js +37 -17
- package/dist/runtime/main.js +340 -109
- package/dist/runtime/netproxy.js +31 -13
- package/dist/runtime/tool.js +37 -16
- package/dist/runtime/view.js +150 -38
- package/dist/selftest/agent-paths.test.js +3 -1
- package/dist/selftest/app.test.js +20 -2
- package/dist/selftest/boot-runner.test.js +15 -1
- package/dist/selftest/channel.test.js +33 -0
- package/dist/selftest/engines.test.js +22 -1
- package/dist/selftest/heavy-load.test.js +116 -4
- package/dist/selftest/live-terminal.test.js +103 -0
- package/dist/selftest/menu-screens.js +52 -1
- package/dist/selftest/menu.test.js +29 -3
- package/dist/selftest/personalization.test.js +2 -1
- package/dist/selftest/service-accounts.test.js +77 -2
- package/dist/selftest/support/engine-golden.js +2 -0
- package/dist/selftest/ui-text.test.js +4 -0
- package/dist/shared/accounts/kinds.js +9 -9
- package/dist/shared/apps/catalogue-gamedev.js +1 -0
- package/dist/shared/apps/catalogue.d.ts +2 -0
- package/dist/shared/channel/schema.d.ts +2 -0
- package/dist/shared/channel/schema.js +4 -0
- package/dist/shared/concurrency/pools.js +1 -1
- package/dist/shared/download/archive.js +4 -2
- package/dist/shared/download/index.d.ts +1 -1
- package/dist/shared/download/index.js +1 -1
- package/dist/shared/download/spawn.d.ts +7 -1
- package/dist/shared/download/spawn.js +16 -1
- package/dist/shared/memory/index.d.ts +1 -0
- package/dist/shared/memory/index.js +1 -0
- package/dist/shared/memory/policy.d.ts +12 -0
- package/dist/shared/memory/policy.js +4 -0
- package/dist/shared/memory/unreal-build.d.ts +2 -0
- package/dist/shared/memory/unreal-build.js +21 -0
- package/dist/shared/paths/pc-installs.d.ts +8 -0
- package/dist/shared/pty/clipboard-watch.d.ts +4 -0
- package/dist/shared/pty/clipboard-watch.js +40 -0
- package/dist/shared/pty/ctrl-c.d.ts +13 -7
- package/dist/shared/pty/ctrl-c.js +35 -19
- package/dist/shared/pty/index.d.ts +1 -0
- package/dist/shared/pty/index.js +1 -0
- package/dist/shared/pty/terminal.d.ts +1 -1
- package/dist/shared/pty/terminal.js +16 -13
- package/dist/shared/unreal/launcher-files.d.ts +7 -0
- package/dist/shared/unreal/launcher-files.js +32 -1
- package/dist/shared/web/ctrl-c.d.ts +26 -0
- package/dist/shared/web/ctrl-c.js +64 -0
- package/dist/shared/web/index.d.ts +1 -0
- package/dist/shared/web/index.js +1 -0
- package/dist/web/index.html +1 -1
- package/dist/web/{main-VPMYTSUL.js → main-7NY4X6YU.js} +67 -67
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/package.json +1 -1
- package/sandbox/csharp/ClipboardWatch.cs +59 -0
- package/sandbox/csharp/MemGov.cs +752 -7
- package/sandbox/scripts/watch-clipboard.ps1 +8 -0
- package/schemas/config.schema.json +10 -10
- package/schemas/sandbox-config.schema.json +9 -9
|
@@ -22806,10 +22806,10 @@ var esm_default2 = createPrompt((config3, done) => {
|
|
|
22806
22806
|
const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, items));
|
|
22807
22807
|
return [prefix, message, answer].filter(Boolean).join(" ");
|
|
22808
22808
|
}
|
|
22809
|
-
let
|
|
22809
|
+
let helpLine2;
|
|
22810
22810
|
if (theme.helpMode !== "never" && instructions !== false) {
|
|
22811
22811
|
if (typeof instructions === "string") {
|
|
22812
|
-
|
|
22812
|
+
helpLine2 = instructions;
|
|
22813
22813
|
} else {
|
|
22814
22814
|
const keys = [
|
|
22815
22815
|
["\u2191\u2193", "navigate"],
|
|
@@ -22820,7 +22820,7 @@ var esm_default2 = createPrompt((config3, done) => {
|
|
|
22820
22820
|
if (shortcuts.invert)
|
|
22821
22821
|
keys.push([shortcuts.invert, "invert"]);
|
|
22822
22822
|
keys.push(["\u23CE", "submit"]);
|
|
22823
|
-
|
|
22823
|
+
helpLine2 = theme.style.keysHelpTip(keys);
|
|
22824
22824
|
}
|
|
22825
22825
|
}
|
|
22826
22826
|
const lines = [
|
|
@@ -22829,7 +22829,7 @@ var esm_default2 = createPrompt((config3, done) => {
|
|
|
22829
22829
|
" ",
|
|
22830
22830
|
description ? theme.style.description(description) : "",
|
|
22831
22831
|
errorMsg ? theme.style.error(errorMsg) : "",
|
|
22832
|
-
|
|
22832
|
+
helpLine2
|
|
22833
22833
|
].filter(Boolean).join("\n").trimEnd();
|
|
22834
22834
|
return `${lines}${cursorHide}`;
|
|
22835
22835
|
});
|
|
@@ -23687,13 +23687,13 @@ var esm_default10 = createPrompt((config3, done) => {
|
|
|
23687
23687
|
}
|
|
23688
23688
|
});
|
|
23689
23689
|
const message = theme.style.message(config3.message, status);
|
|
23690
|
-
let
|
|
23690
|
+
let helpLine2;
|
|
23691
23691
|
if (theme.helpMode !== "never") {
|
|
23692
23692
|
if (config3.instructions) {
|
|
23693
23693
|
const { pager, navigation } = config3.instructions;
|
|
23694
|
-
|
|
23694
|
+
helpLine2 = theme.style.help(searchResults.length > pageSize ? pager : navigation);
|
|
23695
23695
|
} else {
|
|
23696
|
-
|
|
23696
|
+
helpLine2 = theme.style.keysHelpTip([
|
|
23697
23697
|
["\u2191\u2193", "navigate"],
|
|
23698
23698
|
["\u23CE", "select"]
|
|
23699
23699
|
]);
|
|
@@ -23735,7 +23735,7 @@ var esm_default10 = createPrompt((config3, done) => {
|
|
|
23735
23735
|
error62 ?? page,
|
|
23736
23736
|
" ",
|
|
23737
23737
|
description ? theme.style.description(description) : "",
|
|
23738
|
-
|
|
23738
|
+
helpLine2
|
|
23739
23739
|
].filter(Boolean).join("\n").trimEnd();
|
|
23740
23740
|
return [header, body];
|
|
23741
23741
|
});
|
|
@@ -23857,13 +23857,13 @@ var esm_default11 = createPrompt((config3, done) => {
|
|
|
23857
23857
|
clearTimeout(searchTimeoutRef.current);
|
|
23858
23858
|
}, []);
|
|
23859
23859
|
const message = theme.style.message(config3.message, status);
|
|
23860
|
-
let
|
|
23860
|
+
let helpLine2;
|
|
23861
23861
|
if (theme.helpMode !== "never") {
|
|
23862
23862
|
if (config3.instructions) {
|
|
23863
23863
|
const { pager, navigation } = config3.instructions;
|
|
23864
|
-
|
|
23864
|
+
helpLine2 = theme.style.help(items.length > pageSize ? pager : navigation);
|
|
23865
23865
|
} else {
|
|
23866
|
-
|
|
23866
|
+
helpLine2 = theme.style.keysHelpTip([
|
|
23867
23867
|
["\u2191\u2193", "navigate"],
|
|
23868
23868
|
["\u23CE", "select"]
|
|
23869
23869
|
]);
|
|
@@ -23899,7 +23899,7 @@ var esm_default11 = createPrompt((config3, done) => {
|
|
|
23899
23899
|
page,
|
|
23900
23900
|
" ",
|
|
23901
23901
|
description ? theme.style.description(description) : "",
|
|
23902
|
-
|
|
23902
|
+
helpLine2
|
|
23903
23903
|
].filter(Boolean).join("\n").trimEnd();
|
|
23904
23904
|
return `${lines}${cursorHide}`;
|
|
23905
23905
|
});
|
|
@@ -46223,7 +46223,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
46223
46223
|
'The last resort that keeps the sandbox up, in MB below its commit limit (RAM plus paging file): builds are slowed down long before (sandbox.pressureResponse); only if everything the agents start together would take the sandbox to the very edge of its memory, where Windows inside it would start failing, is a build refused memory instead of Windows. "auto" = the larger of 1536 MB and 3 % of the commit limit; "none" = no backstop. Yours only: a project file cannot change it.'
|
|
46224
46224
|
),
|
|
46225
46225
|
pressureResponse: external_exports.boolean().describe(
|
|
46226
|
-
"When the sandbox (or this PC) runs low on memory, slow builds down in steps, like a PC that gets slower instead of failing: build programs get lower CPU and memory priority, then less CPU, then compilers take turns (the waiting ones briefly suspended and trimmed to the paging file). Nothing is stopped or killed, and the agents themselves are never touched. Yours only: a project file cannot change it."
|
|
46226
|
+
"When the sandbox (or this PC) runs low on memory, slow builds down in steps, like a PC that gets slower instead of failing: build programs get lower CPU and memory priority, then less CPU, then compilers take turns (the waiting ones briefly suspended and trimmed to the paging file). Nothing is stopped or killed, and the agents themselves are never touched. A memory gate also holds new compilers and linkers for a moment when the memory of the build programs grows faster than 4 GB in 3 seconds (3 GB with vGPU), and lets them go one at a time. Yours only: a project file cannot change it."
|
|
46227
46227
|
),
|
|
46228
46228
|
vGpu: external_exports.boolean().describe(
|
|
46229
46229
|
"Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it). Browsers in the sandbox never use it (they draw in software)."
|
|
@@ -46814,6 +46814,7 @@ var GAMEDEV_APPS = [
|
|
|
46814
46814
|
size: "100 MB",
|
|
46815
46815
|
source: { github: "f3d-app/f3d", asset: "^F3D-[\\d.]+-Windows-x86_64\\.zip$" },
|
|
46816
46816
|
exe: "f3d.exe",
|
|
46817
|
+
onPath: true,
|
|
46817
46818
|
needs: ["mesa"]
|
|
46818
46819
|
},
|
|
46819
46820
|
{
|
|
@@ -47961,7 +47962,7 @@ var SERVICE_SPECS = {
|
|
|
47961
47962
|
},
|
|
47962
47963
|
steam: {
|
|
47963
47964
|
kind: "steam",
|
|
47964
|
-
label: "Steam
|
|
47965
|
+
label: "Steam",
|
|
47965
47966
|
usedBy: ["steam"],
|
|
47966
47967
|
sources: ["file", "sandbox"],
|
|
47967
47968
|
singleHolder: true,
|
|
@@ -47997,7 +47998,7 @@ var SERVICE_SPECS = {
|
|
|
47997
47998
|
},
|
|
47998
47999
|
cfx: {
|
|
47999
48000
|
kind: "cfx",
|
|
48000
|
-
label: "
|
|
48001
|
+
label: "FiveM key",
|
|
48001
48002
|
usedBy: ["fivem"],
|
|
48002
48003
|
sources: ["typed", "file"],
|
|
48003
48004
|
singleHolder: false,
|
|
@@ -48026,7 +48027,7 @@ var SERVICE_SPECS = {
|
|
|
48026
48027
|
},
|
|
48027
48028
|
keystore: {
|
|
48028
48029
|
kind: "keystore",
|
|
48029
|
-
label: "Android
|
|
48030
|
+
label: "Android keystore",
|
|
48030
48031
|
usedBy: ["android"],
|
|
48031
48032
|
sources: ["file"],
|
|
48032
48033
|
singleHolder: false,
|
|
@@ -48041,7 +48042,7 @@ var SERVICE_SPECS = {
|
|
|
48041
48042
|
},
|
|
48042
48043
|
play: {
|
|
48043
48044
|
kind: "play",
|
|
48044
|
-
label: "Google Play
|
|
48045
|
+
label: "Google Play",
|
|
48045
48046
|
usedBy: ["android"],
|
|
48046
48047
|
sources: ["file"],
|
|
48047
48048
|
singleHolder: false,
|
|
@@ -48052,7 +48053,7 @@ var SERVICE_SPECS = {
|
|
|
48052
48053
|
},
|
|
48053
48054
|
expo: {
|
|
48054
48055
|
kind: "expo",
|
|
48055
|
-
label: "Expo
|
|
48056
|
+
label: "Expo",
|
|
48056
48057
|
usedBy: ["reactNative"],
|
|
48057
48058
|
sources: ["typed"],
|
|
48058
48059
|
singleHolder: false,
|
|
@@ -48063,7 +48064,7 @@ var SERVICE_SPECS = {
|
|
|
48063
48064
|
},
|
|
48064
48065
|
appstore: {
|
|
48065
48066
|
kind: "appstore",
|
|
48066
|
-
label: "App Store Connect
|
|
48067
|
+
label: "App Store Connect",
|
|
48067
48068
|
usedBy: ["reactNative", "flutter"],
|
|
48068
48069
|
sources: ["file", "typed"],
|
|
48069
48070
|
singleHolder: false,
|
|
@@ -48077,7 +48078,7 @@ var SERVICE_SPECS = {
|
|
|
48077
48078
|
},
|
|
48078
48079
|
perplexity: {
|
|
48079
48080
|
kind: "perplexity",
|
|
48080
|
-
label: "Perplexity API
|
|
48081
|
+
label: "Perplexity API",
|
|
48081
48082
|
usedBy: ["perplexity"],
|
|
48082
48083
|
sources: ["pc", "file", "typed"],
|
|
48083
48084
|
singleHolder: false,
|
|
@@ -48101,7 +48102,7 @@ var SERVICE_SPECS = {
|
|
|
48101
48102
|
},
|
|
48102
48103
|
comet: {
|
|
48103
48104
|
kind: "comet",
|
|
48104
|
-
label: "Comet
|
|
48105
|
+
label: "Comet",
|
|
48105
48106
|
usedBy: ["comet"],
|
|
48106
48107
|
sources: ["sandbox"],
|
|
48107
48108
|
singleHolder: false,
|
|
@@ -48117,7 +48118,7 @@ var SERVICE_SPECS = {
|
|
|
48117
48118
|
},
|
|
48118
48119
|
perplexityapp: {
|
|
48119
48120
|
kind: "perplexityapp",
|
|
48120
|
-
label: "Perplexity
|
|
48121
|
+
label: "Perplexity app",
|
|
48121
48122
|
usedBy: ["perplexityapp"],
|
|
48122
48123
|
sources: ["sandbox"],
|
|
48123
48124
|
singleHolder: false,
|
|
@@ -48940,6 +48941,8 @@ var PressureStatusSchema = external_exports.object({
|
|
|
48940
48941
|
lowered: external_exports.number().int().min(0).max(1024),
|
|
48941
48942
|
/** Compilers waiting their turn right now (name, process id, seconds until they may go on). */
|
|
48942
48943
|
paused: external_exports.array(external_exports.object({ name: Text(64), pid: external_exports.number().int(), seconds: external_exports.number().int().min(0).max(60) })).max(8),
|
|
48944
|
+
/** Build programs the memory gate holds right now (let go one at a time). */
|
|
48945
|
+
held: external_exports.number().int().min(0).max(1024).optional(),
|
|
48943
48946
|
/** The CPU share the compilers get together (percent; 100 = no cap). */
|
|
48944
48947
|
cpuPercent: external_exports.number().int().min(0).max(100).optional(),
|
|
48945
48948
|
/** The PC itself asked for slowing down (its memory or CPU is low). */
|
|
@@ -48960,6 +48963,8 @@ var HeartbeatSchema = external_exports.object({
|
|
|
48960
48963
|
topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
|
|
48961
48964
|
/** The disk queue this PC last reported while asking the sandbox to slow down. */
|
|
48962
48965
|
diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
|
|
48966
|
+
/** Build programs the memory gate holds right now (let go one at a time). */
|
|
48967
|
+
held: external_exports.number().int().min(0).max(1024).optional(),
|
|
48963
48968
|
/** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
|
|
48964
48969
|
phase: external_exports.enum(["ready", "working", "ending"])
|
|
48965
48970
|
});
|
|
@@ -53742,7 +53747,7 @@ var clock = (iso) => {
|
|
|
53742
53747
|
};
|
|
53743
53748
|
function heartbeatLine(hb) {
|
|
53744
53749
|
const top = hb.topProcesses.map((p) => safeText(p.name) + " " + p.privateMb + " MB").join(", ");
|
|
53745
|
-
return "last seen inside at " + clock(hb.at) + ": up " + Math.round(hb.uptimeS / 60) + " min, " + hb.ramFreePct + "% RAM free, " + hb.commitPct + "% commit used, builds at step " + hb.step + (hb.hostStep > 0 ? " (this PC asked for step " + hb.hostStep + ")" : "") + (hb.diskQueueReported !== void 0 ? ", this PC disk queue " + hb.diskQueueReported : "") + (top ? "; biggest: " + top : "");
|
|
53750
|
+
return "last seen inside at " + clock(hb.at) + ": up " + Math.round(hb.uptimeS / 60) + " min, " + hb.ramFreePct + "% RAM free, " + hb.commitPct + "% commit used, builds at step " + hb.step + (hb.hostStep > 0 ? " (this PC asked for step " + hb.hostStep + ")" : "") + (hb.diskQueueReported !== void 0 ? ", this PC disk queue " + hb.diskQueueReported : "") + (hb.held ? ", " + hb.held + " builds held by the memory gate" : "") + (top ? "; biggest: " + top : "");
|
|
53746
53751
|
}
|
|
53747
53752
|
function guessReason(hb) {
|
|
53748
53753
|
if (hb && hb.diskQueueReported !== void 0 && hb.hostStep > 0)
|
|
@@ -53816,7 +53821,12 @@ function findingLines(events) {
|
|
|
53816
53821
|
);
|
|
53817
53822
|
if (has2((e) => lower(e).startsWith("hyper-v")))
|
|
53818
53823
|
lines.push("Hyper-V events: the sandbox's virtual machine (or the service that runs it) reported a problem.");
|
|
53819
|
-
|
|
53824
|
+
const isAppCrash = (e) => /^(application error|windows error reporting)$/i.test(e.provider);
|
|
53825
|
+
if (has2((e) => isAppCrash(e) && /vmwp\.exe/i.test(e.process)))
|
|
53826
|
+
lines.push(
|
|
53827
|
+
"vmwp.exe, the Windows program that runs the sandbox's VM, crashed. That is a fault in Windows' Hyper-V code or a driver it uses (with vGPU on, usually the graphics driver), not a program inside the sandbox running out of memory."
|
|
53828
|
+
);
|
|
53829
|
+
else if (has2(isAppCrash))
|
|
53820
53830
|
lines.push("A crash report names vmwp.exe or vmmem, the programs that hold the sandbox's VM.");
|
|
53821
53831
|
return lines;
|
|
53822
53832
|
}
|
|
@@ -53866,6 +53876,17 @@ function hostMemoryTail(storageRoot, dataPath) {
|
|
|
53866
53876
|
return "";
|
|
53867
53877
|
}
|
|
53868
53878
|
}
|
|
53879
|
+
function memoryWasFineLine(hostMemoryLog) {
|
|
53880
|
+
const last = hostMemoryLog.split(/\r?\n/).filter((l) => l.trim() !== "").pop();
|
|
53881
|
+
if (!last) return null;
|
|
53882
|
+
const ram = /RAM free\/total MB (\d{1,9})\/(\d{1,9})/.exec(last);
|
|
53883
|
+
const commit = /commit free\/limit MB (\d{1,9})\/(\d{1,9})/.exec(last);
|
|
53884
|
+
if (!ram || !commit) return null;
|
|
53885
|
+
const freeRam = Number(ram[1]);
|
|
53886
|
+
const freeCommit = Number(commit[1]);
|
|
53887
|
+
if (freeRam < 4096 || freeCommit < 4096) return null;
|
|
53888
|
+
return "This PC still had " + Math.floor(freeRam / 1024) + " GB of RAM and " + Math.floor(freeCommit / 1024) + " GB of memory (RAM plus paging file) free just before, so it did not run out of memory.";
|
|
53889
|
+
}
|
|
53869
53890
|
function crashReportText(cause, events, memoryLog, lastSeen, extra = {}) {
|
|
53870
53891
|
const seen = /* @__PURE__ */ new Set();
|
|
53871
53892
|
const unique = events.filter((e) => {
|
|
@@ -53881,6 +53902,7 @@ function crashReportText(cause, events, memoryLog, lastSeen, extra = {}) {
|
|
|
53881
53902
|
const hostLines = (extra.hostMemoryLog ?? "").split(/\r?\n/).filter(Boolean).slice(-20).map((l) => " " + safeText(l));
|
|
53882
53903
|
const freeze = freezeLine(cause, lastSeen);
|
|
53883
53904
|
const meaning = findingLines(unique);
|
|
53905
|
+
const fine = memoryWasFineLine(extra.hostMemoryLog ?? "");
|
|
53884
53906
|
const dumps = extra.dumps ?? [];
|
|
53885
53907
|
const vgpu = extra.vgpu ? ["vGPU was on for this sandbox. " + vgpuWarning("its launch settings"), ""] : [];
|
|
53886
53908
|
return [
|
|
@@ -53894,6 +53916,7 @@ function crashReportText(cause, events, memoryLog, lastSeen, extra = {}) {
|
|
|
53894
53916
|
...vgpu,
|
|
53895
53917
|
"What that usually means:",
|
|
53896
53918
|
...meaning.length ? meaning.map((l) => " " + l) : [" (no memory, blue screen or hardware event was logged)"],
|
|
53919
|
+
...fine ? [" " + fine] : [],
|
|
53897
53920
|
"",
|
|
53898
53921
|
"Crash dumps Windows left (C:\\Windows\\Minidump, MEMORY.DMP):",
|
|
53899
53922
|
...dumps.length ? dumps.map((d) => " " + d.name + " " + d.at) : [" (none from that time)"],
|
|
@@ -56560,7 +56583,7 @@ function clearLiveRecord(storageRoot, dataPath) {
|
|
|
56560
56583
|
import fs71 from "node:fs";
|
|
56561
56584
|
import path94 from "node:path";
|
|
56562
56585
|
import crypto14 from "node:crypto";
|
|
56563
|
-
import
|
|
56586
|
+
import os17 from "node:os";
|
|
56564
56587
|
|
|
56565
56588
|
// src/shared/accounts/fingerprint.ts
|
|
56566
56589
|
import crypto8 from "node:crypto";
|
|
@@ -58861,10 +58884,20 @@ function scriptArgs(name2, args = []) {
|
|
|
58861
58884
|
}
|
|
58862
58885
|
|
|
58863
58886
|
// src/shared/download/spawn.ts
|
|
58887
|
+
import os14 from "node:os";
|
|
58864
58888
|
import { spawn as spawn9 } from "node:child_process";
|
|
58889
|
+
function lowerPriority(pid) {
|
|
58890
|
+
if (pid === void 0) return;
|
|
58891
|
+
try {
|
|
58892
|
+
os14.setPriority(pid, os14.constants.priority.PRIORITY_BELOW_NORMAL);
|
|
58893
|
+
} catch {
|
|
58894
|
+
}
|
|
58895
|
+
}
|
|
58865
58896
|
function spawnAsync(file2, args, options = {}) {
|
|
58897
|
+
const { lowPriority, ...spawnOptions } = options;
|
|
58866
58898
|
return new Promise((resolve, reject) => {
|
|
58867
|
-
const child = spawn9(file2, args, { stdio: "ignore", windowsHide: true, ...
|
|
58899
|
+
const child = spawn9(file2, args, { stdio: "ignore", windowsHide: true, ...spawnOptions });
|
|
58900
|
+
if (lowPriority) lowerPriority(child.pid);
|
|
58868
58901
|
child.once("error", reject);
|
|
58869
58902
|
child.once("close", (code) => resolve(code ?? -1));
|
|
58870
58903
|
});
|
|
@@ -58885,13 +58918,16 @@ function extractArchive(archive, destination, members2 = []) {
|
|
|
58885
58918
|
}
|
|
58886
58919
|
async function extract(archive, destination, members2) {
|
|
58887
58920
|
fs57.mkdirSync(destination, { recursive: true });
|
|
58888
|
-
let status = await spawnAsync(SYSTEM.tar(), ["-xf", archive, "-C", destination, ...members2]
|
|
58921
|
+
let status = await spawnAsync(SYSTEM.tar(), ["-xf", archive, "-C", destination, ...members2], {
|
|
58922
|
+
lowPriority: true
|
|
58923
|
+
});
|
|
58889
58924
|
if (status !== 0 && /\.(zip|nupkg)$/i.test(archive)) {
|
|
58890
58925
|
const zip = archive.endsWith(".zip") ? archive : archive + ".zip";
|
|
58891
58926
|
if (zip !== archive) fs57.copyFileSync(archive, zip);
|
|
58892
58927
|
status = await spawnAsync(
|
|
58893
58928
|
SYSTEM.powershell(),
|
|
58894
|
-
scriptArgs("expand-archive.ps1", ["-Archive", zip, "-Destination", destination])
|
|
58929
|
+
scriptArgs("expand-archive.ps1", ["-Archive", zip, "-Destination", destination]),
|
|
58930
|
+
{ lowPriority: true }
|
|
58895
58931
|
);
|
|
58896
58932
|
}
|
|
58897
58933
|
if (status !== 0) throw new Error("Could not extract " + archive);
|
|
@@ -59789,10 +59825,10 @@ function pcHasPwsh(env = process.env, exists2 = fs60.existsSync) {
|
|
|
59789
59825
|
|
|
59790
59826
|
// src/host/launch/pc-scan.ts
|
|
59791
59827
|
import fs61 from "node:fs";
|
|
59792
|
-
import
|
|
59828
|
+
import os15 from "node:os";
|
|
59793
59829
|
import path84 from "node:path";
|
|
59794
59830
|
function msvcRust() {
|
|
59795
|
-
const settings = path84.join(process.env.RUSTUP_HOME ?? path84.join(
|
|
59831
|
+
const settings = path84.join(process.env.RUSTUP_HOME ?? path84.join(os15.homedir(), ".rustup"), "settings.toml");
|
|
59796
59832
|
try {
|
|
59797
59833
|
return /default_host_triple\s*=\s*"[^"]*-msvc"/.test(fs61.readFileSync(settings, "utf8").slice(0, 64 * 1024));
|
|
59798
59834
|
} catch {
|
|
@@ -59959,7 +59995,7 @@ function databasePlanner(config3, compose2) {
|
|
|
59959
59995
|
import path89 from "node:path";
|
|
59960
59996
|
|
|
59961
59997
|
// src/host/launch/wsb-file.ts
|
|
59962
|
-
import
|
|
59998
|
+
import os16 from "node:os";
|
|
59963
59999
|
var GUEST = {
|
|
59964
60000
|
launch: "C:\\AgentLaunch",
|
|
59965
60001
|
data: "C:\\AgentData",
|
|
@@ -60002,7 +60038,7 @@ function memoryNote(decision) {
|
|
|
60002
60038
|
if (decision.limitedBy !== "commit" || decision.withoutCommitMb - decision.mb < 2048) return null;
|
|
60003
60039
|
return "The sandbox gets " + decision.mb / 1024 + " GB of memory instead of " + decision.withoutCommitMb / 1024 + " GB: this PC has only " + Math.floor((decision.commitAvailableMb ?? 0) / 1024) + " GB of memory (RAM plus paging file) left to hand out, and if it runs out Windows closes the sandbox. A bigger Windows paging file, or closing other programs, gives it more.";
|
|
60004
60040
|
}
|
|
60005
|
-
function resolveMemoryMb(sandbox, freeMemoryBytes =
|
|
60041
|
+
function resolveMemoryMb(sandbox, freeMemoryBytes = os16.freemem(), totalMemoryBytes = os16.totalmem(), commitAvailableMb = null) {
|
|
60006
60042
|
if (sandbox.memoryMb !== "auto") return sandbox.memoryMb;
|
|
60007
60043
|
const decision = decideMemory(
|
|
60008
60044
|
sandbox,
|
|
@@ -60915,7 +60951,7 @@ function generateSandbox(given, opened) {
|
|
|
60915
60951
|
resolveMemoryMb(config3.sandbox, o.freeMemoryBytes, void 0, commitAvailableMb),
|
|
60916
60952
|
...others.map((p) => typeof p.config.sandbox.memoryMb === "number" ? p.config.sandbox.memoryMb : 0)
|
|
60917
60953
|
);
|
|
60918
|
-
const memoryMb = cappedMemoryMb(askedMb, config3.sandbox, Math.floor(
|
|
60954
|
+
const memoryMb = cappedMemoryMb(askedMb, config3.sandbox, Math.floor(os17.totalmem() / 1048576));
|
|
60919
60955
|
const launchId = o.launchId ?? newLaunchId();
|
|
60920
60956
|
const launchPath = path94.join(storageRoot, "launches", launchId);
|
|
60921
60957
|
ensureDir(dataPath);
|
|
@@ -60988,8 +61024,8 @@ function generateSandbox(given, opened) {
|
|
|
60988
61024
|
memoryNote: residentNote(askedMb, memoryMb) ?? (config3.sandbox.memoryMb === "auto" ? memoryNote(
|
|
60989
61025
|
decideMemory(
|
|
60990
61026
|
config3.sandbox,
|
|
60991
|
-
Math.floor((o.freeMemoryBytes ??
|
|
60992
|
-
Math.floor(
|
|
61027
|
+
Math.floor((o.freeMemoryBytes ?? os17.freemem()) / 1048576),
|
|
61028
|
+
Math.floor(os17.totalmem() / 1048576),
|
|
60993
61029
|
commitAvailableMb
|
|
60994
61030
|
)
|
|
60995
61031
|
) : null),
|
|
@@ -62927,16 +62963,19 @@ function howToSave(spec) {
|
|
|
62927
62963
|
if (spec.returns) return "sign in once in this sandbox, or: sandbox account import " + spec.kind;
|
|
62928
62964
|
return spec.sources.includes("typed") ? "save one: sandbox account login " + spec.kind : "save one: sandbox account import " + spec.kind + " --from <file>";
|
|
62929
62965
|
}
|
|
62930
|
-
function takeFromPc(kind, pc, store) {
|
|
62966
|
+
function takeFromPc(kind, pc, store, saved) {
|
|
62931
62967
|
const source = HOST_SOURCES[kind];
|
|
62932
|
-
if (!pc || !source.fromPc) return
|
|
62968
|
+
if (!pc || !source.fromPc) return saved;
|
|
62969
|
+
if (saved && store.info(kind)?.source !== "pc") return saved;
|
|
62933
62970
|
let payload = null;
|
|
62934
62971
|
try {
|
|
62935
62972
|
payload = source.fromPc(pc);
|
|
62936
62973
|
} catch {
|
|
62937
|
-
return
|
|
62974
|
+
return saved;
|
|
62938
62975
|
}
|
|
62939
|
-
if (payload)
|
|
62976
|
+
if (!payload) return saved;
|
|
62977
|
+
if (!saved || fingerprint(payload) !== fingerprint(saved))
|
|
62978
|
+
store.save(kind, payload, "pc", source.summary(payload));
|
|
62940
62979
|
return payload;
|
|
62941
62980
|
}
|
|
62942
62981
|
function prepareServiceAccounts(i) {
|
|
@@ -62968,7 +63007,7 @@ function prepareServiceAccounts(i) {
|
|
|
62968
63007
|
} catch {
|
|
62969
63008
|
unreadable = true;
|
|
62970
63009
|
}
|
|
62971
|
-
if (!
|
|
63010
|
+
if (!unreadable) payload = takeFromPc(kind, i.pc, store, payload);
|
|
62972
63011
|
if (spec.singleHolder) {
|
|
62973
63012
|
const claim2 = leases.claim(kind, dataSet, i.launchId, payload ? fingerprint(payload) : null, i.isRunning);
|
|
62974
63013
|
if (!claim2.ok) {
|
|
@@ -63178,9 +63217,6 @@ async function prepareStorePackages(apps, o) {
|
|
|
63178
63217
|
return { notes };
|
|
63179
63218
|
}
|
|
63180
63219
|
|
|
63181
|
-
// src/host/pc-installs/epic.ts
|
|
63182
|
-
import path117 from "node:path";
|
|
63183
|
-
|
|
63184
63220
|
// src/shared/unreal/engines.ts
|
|
63185
63221
|
import path113 from "node:path";
|
|
63186
63222
|
var win = path113.win32;
|
|
@@ -63226,6 +63262,9 @@ var stripBom2 = (text) => text.replace(/^\uFEFF/, "");
|
|
|
63226
63262
|
function launcherInstalledFile(programData) {
|
|
63227
63263
|
return win2.join(programData, "Epic", "UnrealEngineLauncher", "LauncherInstalled.dat");
|
|
63228
63264
|
}
|
|
63265
|
+
function launcherManifestsDir(programData) {
|
|
63266
|
+
return win2.join(programData, "Epic", "EpicGamesLauncher", "Data", "Manifests");
|
|
63267
|
+
}
|
|
63229
63268
|
var EntrySchema = external_exports.looseObject({
|
|
63230
63269
|
InstallLocation: external_exports.string().max(1024),
|
|
63231
63270
|
AppName: external_exports.string().max(200),
|
|
@@ -63261,6 +63300,41 @@ var ItemSchema = external_exports.looseObject({
|
|
|
63261
63300
|
InstallSize: external_exports.number().int().min(0).optional(),
|
|
63262
63301
|
bIsIncompleteInstall: external_exports.boolean().optional()
|
|
63263
63302
|
});
|
|
63303
|
+
function itemInstallLocation(text) {
|
|
63304
|
+
return itemInfo(text)?.installLocation ?? null;
|
|
63305
|
+
}
|
|
63306
|
+
function itemInfo(text) {
|
|
63307
|
+
try {
|
|
63308
|
+
const item = ItemSchema.parse(JSON.parse(stripBom2(text)));
|
|
63309
|
+
const at = item.InstallLocation;
|
|
63310
|
+
return at && win2.isAbsolute(at) ? { installLocation: at, sizeBytes: item.InstallSize ?? null } : null;
|
|
63311
|
+
} catch {
|
|
63312
|
+
return null;
|
|
63313
|
+
}
|
|
63314
|
+
}
|
|
63315
|
+
var ITEM_NAME = /^[A-Za-z0-9_-]{1,80}\.item$/;
|
|
63316
|
+
function relocateItem(text, from, to) {
|
|
63317
|
+
let item;
|
|
63318
|
+
try {
|
|
63319
|
+
item = JSON.parse(stripBom2(text));
|
|
63320
|
+
} catch {
|
|
63321
|
+
return null;
|
|
63322
|
+
}
|
|
63323
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return null;
|
|
63324
|
+
const base = win2.resolve(from).toLowerCase();
|
|
63325
|
+
const out = {};
|
|
63326
|
+
for (const [key3, value] of Object.entries(item)) {
|
|
63327
|
+
if (typeof value !== "string" || !win2.isAbsolute(value)) {
|
|
63328
|
+
out[key3] = value;
|
|
63329
|
+
continue;
|
|
63330
|
+
}
|
|
63331
|
+
const full = win2.resolve(value);
|
|
63332
|
+
const low = full.toLowerCase();
|
|
63333
|
+
if (low === base || low.startsWith(base + "\\")) out[key3] = to + full.slice(base.length);
|
|
63334
|
+
}
|
|
63335
|
+
const at = typeof out.InstallLocation === "string" ? out.InstallLocation : "";
|
|
63336
|
+
return at.toLowerCase() === to.toLowerCase() ? JSON.stringify(out, null, " ") : null;
|
|
63337
|
+
}
|
|
63264
63338
|
|
|
63265
63339
|
// src/shared/unreal/status.ts
|
|
63266
63340
|
var UNREAL_STATUS_FILE = "status.json";
|
|
@@ -63404,6 +63478,7 @@ function vaultPacks(vault, fs141) {
|
|
|
63404
63478
|
}
|
|
63405
63479
|
|
|
63406
63480
|
// src/host/pc-installs/epic.ts
|
|
63481
|
+
import path117 from "node:path";
|
|
63407
63482
|
var APP = /^[A-Za-z0-9._-]{1,100}$/;
|
|
63408
63483
|
function findEpicGames(text, wanted) {
|
|
63409
63484
|
const names = wanted === true ? null : new Set(wanted.map((w) => String(w).toLowerCase()));
|
|
@@ -63925,6 +64000,25 @@ var versionOf = (dir, files) => {
|
|
|
63925
64000
|
const bytes = files.read(win9.join(dir, "Engine", "Build", "Build.version"), 64 * 1024);
|
|
63926
64001
|
return bytes ? parseBuildVersion(bytes.toString("utf8")) : null;
|
|
63927
64002
|
};
|
|
64003
|
+
var MAX_ITEM_BYTES2 = 64 * 1024;
|
|
64004
|
+
function launcherItemOf(dir, files) {
|
|
64005
|
+
if (!files.manifests) return {};
|
|
64006
|
+
const want = win9.resolve(dir).toLowerCase();
|
|
64007
|
+
for (const name2 of files.list(files.manifests).filter((n) => ITEM_NAME.test(n))) {
|
|
64008
|
+
const bytes = files.read(win9.join(files.manifests, name2), MAX_ITEM_BYTES2);
|
|
64009
|
+
const at = bytes ? itemInstallLocation(bytes.toString("utf8")) : null;
|
|
64010
|
+
if (bytes && at && win9.resolve(at).toLowerCase() === want)
|
|
64011
|
+
return { launcherItem: { name: name2, text: bytes.toString("utf8") } };
|
|
64012
|
+
}
|
|
64013
|
+
return {};
|
|
64014
|
+
}
|
|
64015
|
+
function launcherIdsOf(dir, files) {
|
|
64016
|
+
const want = win9.resolve(dir).toLowerCase();
|
|
64017
|
+
const entry = (files.launcherInstalled ? launcherInstallations(files.launcherInstalled) : []).find(
|
|
64018
|
+
(i) => APP_NAME.test(i.appName) && i.ids && win9.resolve(i.installLocation).toLowerCase() === want
|
|
64019
|
+
);
|
|
64020
|
+
return entry?.ids ? { launcher: entry.ids } : {};
|
|
64021
|
+
}
|
|
63928
64022
|
var isWanted = (wanted, v) => wanted === true || wanted.map((w) => String(w).replace(/^UE_/i, "")).includes(v.major + "." + v.minor);
|
|
63929
64023
|
function findUnrealInstalls(files, wanted) {
|
|
63930
64024
|
const found = [];
|
|
@@ -63944,7 +64038,8 @@ function findUnrealInstalls(files, wanted) {
|
|
|
63944
64038
|
version: versionText(v),
|
|
63945
64039
|
host: win9.normalize(dir),
|
|
63946
64040
|
guest: "",
|
|
63947
|
-
...ids ? { launcher: ids } : {}
|
|
64041
|
+
...ids ? { launcher: ids } : {},
|
|
64042
|
+
...launcherItemOf(dir, files)
|
|
63948
64043
|
});
|
|
63949
64044
|
};
|
|
63950
64045
|
const listed = files.launcherInstalled ? launcherInstallations(files.launcherInstalled) : [];
|
|
@@ -63989,7 +64084,10 @@ function findEngineFolders(files, folders) {
|
|
|
63989
64084
|
host: dir,
|
|
63990
64085
|
guest: "",
|
|
63991
64086
|
writable: true,
|
|
63992
|
-
...source ? { buildId: source.buildId } : {}
|
|
64087
|
+
...source ? { buildId: source.buildId } : {},
|
|
64088
|
+
// An engine the launcher installed keeps its ids and manifest, so the sandbox's launcher lists it too.
|
|
64089
|
+
...launcherIdsOf(dir, { launcherInstalled: files.launcherInstalled ?? null }),
|
|
64090
|
+
...files.list ? launcherItemOf(dir, { manifests: files.manifests, list: files.list, read: files.read }) : {}
|
|
63993
64091
|
});
|
|
63994
64092
|
}
|
|
63995
64093
|
return found;
|
|
@@ -64017,6 +64115,7 @@ function unrealPcFiles(pc) {
|
|
|
64017
64115
|
win9.join(d, "Program Files", "Epic Games"),
|
|
64018
64116
|
win9.join(d, "Epic Games")
|
|
64019
64117
|
]),
|
|
64118
|
+
manifests: launcherManifestsDir(pc.programData),
|
|
64020
64119
|
list: listDir2,
|
|
64021
64120
|
read: readBoundedFile
|
|
64022
64121
|
};
|
|
@@ -64155,8 +64254,9 @@ function discoverPcInstalls(s3, o, pc = pcEnv()) {
|
|
|
64155
64254
|
readOnly: !writable,
|
|
64156
64255
|
label: writable ? "this PC, writable" : "this PC, read-only"
|
|
64157
64256
|
});
|
|
64158
|
-
const { host: _host, ...shown } = install;
|
|
64159
|
-
|
|
64257
|
+
const { host: _host, launcherItem, ...shown } = install;
|
|
64258
|
+
const moved = launcherItem ? relocateItem(launcherItem.text, install.host, guest) : null;
|
|
64259
|
+
items.push({ ...shown, guest, ...moved ? { launcherItem: { name: launcherItem.name, text: moved } } : {} });
|
|
64160
64260
|
} catch (e) {
|
|
64161
64261
|
notes.push("pcInstalls: " + install.name + " is not mapped: " + errMsg(e));
|
|
64162
64262
|
}
|
|
@@ -64866,7 +64966,7 @@ var SandboxChannel = class {
|
|
|
64866
64966
|
|
|
64867
64967
|
// src/host/channel/attach.ts
|
|
64868
64968
|
import net4 from "node:net";
|
|
64869
|
-
import
|
|
64969
|
+
import os18 from "node:os";
|
|
64870
64970
|
|
|
64871
64971
|
// src/shared/pty/protocol.ts
|
|
64872
64972
|
var FrameType = {
|
|
@@ -65114,8 +65214,37 @@ var OutputFilter = class {
|
|
|
65114
65214
|
}
|
|
65115
65215
|
};
|
|
65116
65216
|
|
|
65117
|
-
// src/shared/pty/
|
|
65217
|
+
// src/shared/pty/clipboard-watch.ts
|
|
65118
65218
|
import { spawn as spawn11 } from "node:child_process";
|
|
65219
|
+
var MAX_PENDING = 1024;
|
|
65220
|
+
function watchClipboard(onChange) {
|
|
65221
|
+
if (process.platform !== "win32") return { stop: () => void 0 };
|
|
65222
|
+
let child = null;
|
|
65223
|
+
try {
|
|
65224
|
+
child = spawn11(SYSTEM.powershell(), scriptArgs("watch-clipboard.ps1", ["-ProcessId", String(process.pid)]), {
|
|
65225
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
65226
|
+
windowsHide: true
|
|
65227
|
+
});
|
|
65228
|
+
} catch {
|
|
65229
|
+
return { stop: () => void 0 };
|
|
65230
|
+
}
|
|
65231
|
+
let pending = "";
|
|
65232
|
+
child.stdout?.setEncoding("latin1");
|
|
65233
|
+
child.stdout?.on("data", (text) => {
|
|
65234
|
+
const lines = (pending + text).split("\n");
|
|
65235
|
+
pending = (lines.pop() ?? "").slice(-MAX_PENDING);
|
|
65236
|
+
for (const line of lines) if (line.trim() === "changed") onChange();
|
|
65237
|
+
});
|
|
65238
|
+
child.on("error", () => void 0);
|
|
65239
|
+
return {
|
|
65240
|
+
stop: () => {
|
|
65241
|
+
if (child && child.exitCode === null && child.signalCode === null) child.kill();
|
|
65242
|
+
}
|
|
65243
|
+
};
|
|
65244
|
+
}
|
|
65245
|
+
|
|
65246
|
+
// src/shared/pty/console-input.ts
|
|
65247
|
+
import { spawn as spawn12 } from "node:child_process";
|
|
65119
65248
|
function enableVtInput() {
|
|
65120
65249
|
if (process.platform !== "win32" || !process.stdin.isTTY)
|
|
65121
65250
|
return { ready: Promise.resolve(false), stop: () => Promise.resolve() };
|
|
@@ -65123,7 +65252,7 @@ function enableVtInput() {
|
|
|
65123
65252
|
let exited = Promise.resolve();
|
|
65124
65253
|
const ready = new Promise((resolve) => {
|
|
65125
65254
|
try {
|
|
65126
|
-
child =
|
|
65255
|
+
child = spawn12(SYSTEM.powershell(), scriptArgs("enable-vt-input.ps1", ["-ProcessId", String(process.pid)]), {
|
|
65127
65256
|
stdio: "ignore",
|
|
65128
65257
|
windowsHide: true
|
|
65129
65258
|
});
|
|
@@ -65182,30 +65311,118 @@ function unfinishedSequence(data) {
|
|
|
65182
65311
|
return data.length;
|
|
65183
65312
|
}
|
|
65184
65313
|
|
|
65185
|
-
// src/shared/
|
|
65314
|
+
// src/shared/web/protocol.ts
|
|
65315
|
+
var CSRF_HEADER = "x-sandbox-web";
|
|
65316
|
+
var CSRF_VALUE = "1";
|
|
65317
|
+
var COOKIE_NAME = "sbxweb";
|
|
65318
|
+
var MIN_COLS = 10;
|
|
65319
|
+
var MAX_COLS = 500;
|
|
65320
|
+
var MIN_ROWS = 2;
|
|
65321
|
+
var MAX_ROWS = 300;
|
|
65322
|
+
var MAX_CLIENT_MESSAGE_BYTES = 256 * 1024;
|
|
65323
|
+
function parseClientMessage(text) {
|
|
65324
|
+
let value;
|
|
65325
|
+
try {
|
|
65326
|
+
value = JSON.parse(text);
|
|
65327
|
+
} catch {
|
|
65328
|
+
return null;
|
|
65329
|
+
}
|
|
65330
|
+
if (typeof value !== "object" || value === null) return null;
|
|
65331
|
+
const m = value;
|
|
65332
|
+
if (m.t !== "resize") return null;
|
|
65333
|
+
const { cols, rows } = m;
|
|
65334
|
+
if (!Number.isInteger(cols) || !Number.isInteger(rows)) return null;
|
|
65335
|
+
const c2 = cols;
|
|
65336
|
+
const r = rows;
|
|
65337
|
+
if (c2 < MIN_COLS || c2 > MAX_COLS || r < MIN_ROWS || r > MAX_ROWS) return null;
|
|
65338
|
+
return { t: "resize", cols: c2, rows: r };
|
|
65339
|
+
}
|
|
65340
|
+
|
|
65341
|
+
// src/shared/web/ctrl-c.ts
|
|
65186
65342
|
var CTRL_C_CONFIRM_MS = 1500;
|
|
65187
65343
|
var CTRL_C_HINT = "Ctrl+C again to send it to the program (Esc stops an agent)";
|
|
65188
|
-
var
|
|
65189
|
-
var
|
|
65344
|
+
var CTRL_C_COPY_HINT = "Copied: Ctrl+C after selecting text is not sent to the program (Esc stops an agent)";
|
|
65345
|
+
var CtrlCDecider = class {
|
|
65346
|
+
constructor(confirm = true) {
|
|
65347
|
+
this.confirm = confirm;
|
|
65348
|
+
}
|
|
65349
|
+
confirm;
|
|
65190
65350
|
armedAt = Number.NEGATIVE_INFINITY;
|
|
65191
|
-
|
|
65192
|
-
/**
|
|
65193
|
-
|
|
65194
|
-
|
|
65351
|
+
selected = false;
|
|
65352
|
+
/** Text was selected in the program: Ctrl+C is "copy" from now on. */
|
|
65353
|
+
selection() {
|
|
65354
|
+
this.selected = true;
|
|
65355
|
+
this.armedAt = Number.NEGATIVE_INFINITY;
|
|
65356
|
+
}
|
|
65357
|
+
/** Any other key or a click: Ctrl+C is an interrupt again. */
|
|
65358
|
+
otherInput() {
|
|
65359
|
+
this.selected = false;
|
|
65360
|
+
}
|
|
65361
|
+
/** What to do with a lone Ctrl+C pressed at `nowMs`. */
|
|
65362
|
+
ctrlC(nowMs) {
|
|
65363
|
+
if (this.selected) return "copy";
|
|
65364
|
+
if (!this.confirm) return "send";
|
|
65195
65365
|
if (nowMs - this.armedAt <= CTRL_C_CONFIRM_MS) {
|
|
65196
65366
|
this.armedAt = Number.NEGATIVE_INFINITY;
|
|
65197
|
-
return
|
|
65367
|
+
return "send";
|
|
65198
65368
|
}
|
|
65199
65369
|
this.armedAt = nowMs;
|
|
65200
|
-
return
|
|
65370
|
+
return "hold";
|
|
65371
|
+
}
|
|
65372
|
+
};
|
|
65373
|
+
var MOUSE_REPORT = /\x1b\[<(\d{1,4});\d{1,5};\d{1,5}([Mm])|\x1b\[M([\s\S])[\s\S]{2}/g;
|
|
65374
|
+
function classifyInput(text) {
|
|
65375
|
+
let drag = false;
|
|
65376
|
+
let click = false;
|
|
65377
|
+
for (const m of text.matchAll(MOUSE_REPORT)) {
|
|
65378
|
+
const sgr = m[1] !== void 0;
|
|
65379
|
+
const b = sgr ? Number(m[1]) : (m[3] ?? " ").charCodeAt(0) - 32;
|
|
65380
|
+
if (b & 64) continue;
|
|
65381
|
+
if (b & 32) {
|
|
65382
|
+
if ((b & 3) !== 3) drag = true;
|
|
65383
|
+
} else if (sgr ? m[2] === "M" : (b & 3) !== 3) click = true;
|
|
65384
|
+
}
|
|
65385
|
+
return { mouse: drag ? "drag" : click ? "click" : null, keys: text.replace(MOUSE_REPORT, "").length > 0 };
|
|
65386
|
+
}
|
|
65387
|
+
function hasClipboardWrite(text) {
|
|
65388
|
+
return /\x1b\]0{0,2}52;/.test(text) || /\u009d0{0,2}52;/.test(text);
|
|
65389
|
+
}
|
|
65390
|
+
|
|
65391
|
+
// src/shared/pty/ctrl-c.ts
|
|
65392
|
+
var OSC_TITLE = /\x1b\][02];([^\x07\x1b]{0,256})(?:\x07|\x1b\\)/g;
|
|
65393
|
+
var CtrlCGuard = class {
|
|
65394
|
+
decider;
|
|
65395
|
+
lastTitle = "";
|
|
65396
|
+
constructor(options = {}) {
|
|
65397
|
+
this.decider = new CtrlCDecider(options.confirm !== false);
|
|
65398
|
+
}
|
|
65399
|
+
/** What to send for one read from the keyboard: a lone Ctrl+C only when it is not held back or taken as "copy". */
|
|
65400
|
+
push(chunk, nowMs) {
|
|
65401
|
+
if (chunk.length === 1 && chunk[0] === 3) {
|
|
65402
|
+
const action2 = this.decider.ctrlC(nowMs);
|
|
65403
|
+
if (action2 === "send") return { send: chunk, held: false, copied: false };
|
|
65404
|
+
return { send: Buffer.alloc(0), held: action2 === "hold", copied: action2 === "copy" };
|
|
65405
|
+
}
|
|
65406
|
+
const c2 = classifyInput(chunk.toString("latin1"));
|
|
65407
|
+
if (c2.keys || c2.mouse === "click") this.decider.otherInput();
|
|
65408
|
+
else if (c2.mouse === "drag") this.decider.selection();
|
|
65409
|
+
return { send: chunk, held: false, copied: false };
|
|
65410
|
+
}
|
|
65411
|
+
/** The clipboard changed since the last key: you just copied. */
|
|
65412
|
+
clipboardChanged() {
|
|
65413
|
+
this.decider.selection();
|
|
65414
|
+
}
|
|
65415
|
+
/** The program wrote to the clipboard: that is a selection too. */
|
|
65416
|
+
watchClipboard(raw) {
|
|
65417
|
+
if (hasClipboardWrite(raw)) this.decider.selection();
|
|
65201
65418
|
}
|
|
65202
65419
|
/** Remembers the title the program last set (from its output), to put it back after the hint. */
|
|
65203
65420
|
watchOutput(text) {
|
|
65204
65421
|
for (const m of text.matchAll(OSC_TITLE)) this.lastTitle = m[1];
|
|
65205
65422
|
}
|
|
65206
65423
|
/** The escape sequence that shows the hint, and the one that puts the program's title back. */
|
|
65207
|
-
hintTitle() {
|
|
65208
|
-
return "\x1B]0;" + CTRL_C_HINT + "\x07";
|
|
65424
|
+
hintTitle(kind = "hold") {
|
|
65425
|
+
return "\x1B]0;" + (kind === "copy" ? CTRL_C_COPY_HINT : CTRL_C_HINT) + "\x07";
|
|
65209
65426
|
}
|
|
65210
65427
|
restoreTitle() {
|
|
65211
65428
|
return "\x1B]0;" + this.lastTitle.replace(/[\x00-\x1f\x7f]/g, "") + "\x07";
|
|
@@ -65409,6 +65626,7 @@ function runTerminalClient(socket, token, options = {}) {
|
|
|
65409
65626
|
clearTimeout(joinTimer);
|
|
65410
65627
|
clearTimeout(hintTimer);
|
|
65411
65628
|
clearTimeout(vtTimer);
|
|
65629
|
+
clipboard.stop();
|
|
65412
65630
|
socket.destroy();
|
|
65413
65631
|
const tracked = mouse.tracking();
|
|
65414
65632
|
const reset = "\x1B[0m\x1B[?25h" + MOUSE_OFF + (mouse.has(2004) ? "\x1B[?2004l" : "") + "\r\n";
|
|
@@ -65426,23 +65644,22 @@ function runTerminalClient(socket, token, options = {}) {
|
|
|
65426
65644
|
if (data.length && !done) socket.write(encodeFrame(FrameType.Input, data));
|
|
65427
65645
|
};
|
|
65428
65646
|
const sendInput = (data) => write(keys.push(passthrough ? mouse.filter(data) : data));
|
|
65429
|
-
const guard2 = options.confirmCtrlC
|
|
65647
|
+
const guard2 = new CtrlCGuard({ confirm: options.confirmCtrlC !== false });
|
|
65430
65648
|
let hintTimer;
|
|
65649
|
+
const clipboard = watchClipboard(() => guard2.clipboardChanged());
|
|
65431
65650
|
const onInput = (chunk) => {
|
|
65432
65651
|
if (options.detachKey !== void 0 && chunk.includes(options.detachKey)) {
|
|
65433
65652
|
finish({ reason: "detach" });
|
|
65434
65653
|
return;
|
|
65435
65654
|
}
|
|
65436
|
-
|
|
65437
|
-
|
|
65438
|
-
|
|
65439
|
-
|
|
65440
|
-
|
|
65441
|
-
|
|
65442
|
-
return;
|
|
65443
|
-
}
|
|
65444
|
-
if (decided.send.length === 1 && decided.send[0] === 3) stdout.write(guard2.restoreTitle());
|
|
65655
|
+
const decided = guard2.push(chunk, Date.now());
|
|
65656
|
+
clearTimeout(hintTimer);
|
|
65657
|
+
if (decided.held || decided.copied) {
|
|
65658
|
+
stdout.write(guard2.hintTitle(decided.copied ? "copy" : "hold"));
|
|
65659
|
+
hintTimer = setTimeout(() => stdout.write(guard2.restoreTitle()), CTRL_C_CONFIRM_MS);
|
|
65660
|
+
return;
|
|
65445
65661
|
}
|
|
65662
|
+
if (decided.send.length === 1 && decided.send[0] === 3) stdout.write(guard2.restoreTitle());
|
|
65446
65663
|
clearTimeout(joinTimer);
|
|
65447
65664
|
sendInput(joiner.push(chunk));
|
|
65448
65665
|
if (joiner.holding()) joinTimer = setTimeout(() => sendInput(joiner.flush()), JOIN_MS);
|
|
@@ -65475,9 +65692,10 @@ function runTerminalClient(socket, token, options = {}) {
|
|
|
65475
65692
|
}
|
|
65476
65693
|
for (const frame of frames) {
|
|
65477
65694
|
if (frame.type === FrameType.Output) {
|
|
65695
|
+
guard2.watchClipboard(frame.payload.toString("latin1"));
|
|
65478
65696
|
const out = filter.push(frame.payload);
|
|
65479
65697
|
mouse.watch(out);
|
|
65480
|
-
guard2
|
|
65698
|
+
guard2.watchOutput(out.toString("latin1"));
|
|
65481
65699
|
stdout.write(out);
|
|
65482
65700
|
} else if (frame.type === FrameType.Console) passthrough = frame.payload.toString("latin1") === "conpty.dll";
|
|
65483
65701
|
else if (frame.type === FrameType.Restarting) {
|
|
@@ -65512,7 +65730,7 @@ function runTerminalClient(socket, token, options = {}) {
|
|
|
65512
65730
|
|
|
65513
65731
|
// src/host/channel/attach.ts
|
|
65514
65732
|
var ipToInt = (ip) => ip.split(".").reduce((n, part) => n * 256 + Number(part), 0);
|
|
65515
|
-
function isSandboxAddress(ip, interfaces =
|
|
65733
|
+
function isSandboxAddress(ip, interfaces = os18.networkInterfaces()) {
|
|
65516
65734
|
if (!net4.isIPv4(ip)) return false;
|
|
65517
65735
|
return Object.entries(interfaces).some(
|
|
65518
65736
|
([name2, list2]) => /^vEthernet/i.test(name2) && !/WSL/i.test(name2) && (list2 ?? []).some((i) => {
|
|
@@ -66353,7 +66571,7 @@ var AuditCollector = class {
|
|
|
66353
66571
|
};
|
|
66354
66572
|
|
|
66355
66573
|
// src/sync/watcher.ts
|
|
66356
|
-
import
|
|
66574
|
+
import os19 from "node:os";
|
|
66357
66575
|
var WATCH_INTERVAL_MS = 60 * 1e3;
|
|
66358
66576
|
var FIRST_SYNC_MS = 3e4;
|
|
66359
66577
|
var AUDIT_FLUSH_MS = 1e4;
|
|
@@ -66412,7 +66630,7 @@ var Watcher = class {
|
|
|
66412
66630
|
memoryStream = null;
|
|
66413
66631
|
watchdog = WATCHDOG_START;
|
|
66414
66632
|
watchdogBusy = false;
|
|
66415
|
-
lastCpu =
|
|
66633
|
+
lastCpu = os19.cpus();
|
|
66416
66634
|
lastHostLog = 0;
|
|
66417
66635
|
/** Runs until the sandbox has closed and the final sync is done (or the end deadline passed). */
|
|
66418
66636
|
async run() {
|
|
@@ -66532,7 +66750,7 @@ var Watcher = class {
|
|
|
66532
66750
|
try {
|
|
66533
66751
|
const settings = readLoadSettings(this.storageRoot, this.dataPath);
|
|
66534
66752
|
const memory = this.memoryStream?.latest() ?? await readHostMemoryAsync(this.storageRoot);
|
|
66535
|
-
const cpus =
|
|
66753
|
+
const cpus = os19.cpus();
|
|
66536
66754
|
const cpuPercent = cpuPercentBetween(this.lastCpu, cpus);
|
|
66537
66755
|
this.lastCpu = cpus;
|
|
66538
66756
|
const nowMs = Date.now();
|
|
@@ -69257,7 +69475,7 @@ function continuesAfterFailedMigration(command2) {
|
|
|
69257
69475
|
|
|
69258
69476
|
// src/cli/services/update-service.ts
|
|
69259
69477
|
import fs112 from "node:fs";
|
|
69260
|
-
import
|
|
69478
|
+
import os20 from "node:os";
|
|
69261
69479
|
import path156 from "node:path";
|
|
69262
69480
|
|
|
69263
69481
|
// src/host/update/release-source.ts
|
|
@@ -69692,7 +69910,7 @@ var Updater = class {
|
|
|
69692
69910
|
var NPM_UPDATE_COMMAND = "npm install -g windows-development-sandbox";
|
|
69693
69911
|
var AUTO_CHECK_HOURS = 24;
|
|
69694
69912
|
var SeenSchema = external_exports.object({ seen: external_exports.string() });
|
|
69695
|
-
function runsAsSystem(env = process.env, username =
|
|
69913
|
+
function runsAsSystem(env = process.env, username = os20.userInfo().username) {
|
|
69696
69914
|
return username.toUpperCase() === "SYSTEM" || (env.USERNAME ?? "").endsWith("$");
|
|
69697
69915
|
}
|
|
69698
69916
|
var UpdateService = class _UpdateService {
|
|
@@ -70315,7 +70533,7 @@ import { spawnSync as spawnSync29 } from "node:child_process";
|
|
|
70315
70533
|
|
|
70316
70534
|
// src/cli/commands/setup/facts.ts
|
|
70317
70535
|
var import_lodash27 = __toESM(require_lodash(), 1);
|
|
70318
|
-
import
|
|
70536
|
+
import os21 from "node:os";
|
|
70319
70537
|
var FEATURE = "Containers-DisposableClientVM";
|
|
70320
70538
|
var ENABLE_COMMAND = "Enable-WindowsOptionalFeature -Online -FeatureName " + FEATURE + " -All -NoRestart";
|
|
70321
70539
|
function parseRegQuery(text) {
|
|
@@ -70363,7 +70581,7 @@ function gatherFacts(storageRoot) {
|
|
|
70363
70581
|
sandboxExe: fileExists(system32("WindowsSandbox.exe")),
|
|
70364
70582
|
virtualizationFirmware: probe.virtualizationFirmware ?? null,
|
|
70365
70583
|
hypervisorPresent: probe.hypervisorPresent ?? null,
|
|
70366
|
-
totalRamBytes:
|
|
70584
|
+
totalRamBytes: os21.totalmem(),
|
|
70367
70585
|
freeDiskBytes: freeBytesAt(storageRoot),
|
|
70368
70586
|
storageRoot,
|
|
70369
70587
|
nodeVersion: process.version
|
|
@@ -71381,6 +71599,12 @@ import path162 from "node:path";
|
|
|
71381
71599
|
|
|
71382
71600
|
// src/app/context.ts
|
|
71383
71601
|
var implement = implementer();
|
|
71602
|
+
function reloadSettings(ctx) {
|
|
71603
|
+
try {
|
|
71604
|
+
ctx.loaded = loadConfig(ctx.loaded.configPath ?? ctx.options.config);
|
|
71605
|
+
} catch {
|
|
71606
|
+
}
|
|
71607
|
+
}
|
|
71384
71608
|
function typedConfirm(io) {
|
|
71385
71609
|
return (prompt, expected) => io.confirm({
|
|
71386
71610
|
title: prompt,
|
|
@@ -72949,7 +73173,7 @@ var AccessStore = class _AccessStore {
|
|
|
72949
73173
|
};
|
|
72950
73174
|
|
|
72951
73175
|
// src/host/remote/door-client.ts
|
|
72952
|
-
import { spawn as
|
|
73176
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
72953
73177
|
var NOT_OWNER = 3;
|
|
72954
73178
|
var NO_PIPE = 4;
|
|
72955
73179
|
var NO_USER = 5;
|
|
@@ -72976,7 +73200,7 @@ async function knockOnDoor(storageRoot, owner) {
|
|
|
72976
73200
|
const exe = hostToolsExe(storageRoot);
|
|
72977
73201
|
if (!exe) fail("Windows sign-in needs HostTools, which could not be built on this PC.", "Run sandbox doctor.");
|
|
72978
73202
|
return new Promise((resolve) => {
|
|
72979
|
-
const child =
|
|
73203
|
+
const child = spawn13(exe, ["door-client", "--owner", owner], { windowsHide: true });
|
|
72980
73204
|
let out = "";
|
|
72981
73205
|
child.stdout.on("data", (d) => {
|
|
72982
73206
|
if (out.length < 1024) out += d.toString("utf8");
|
|
@@ -73088,13 +73312,13 @@ function fingerprintOf(der) {
|
|
|
73088
73312
|
// src/host/remote/firewall.ts
|
|
73089
73313
|
import crypto22 from "node:crypto";
|
|
73090
73314
|
import fs119 from "node:fs";
|
|
73091
|
-
import
|
|
73315
|
+
import os23 from "node:os";
|
|
73092
73316
|
import path168 from "node:path";
|
|
73093
|
-
import { spawn as
|
|
73317
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
73094
73318
|
|
|
73095
73319
|
// src/host/remote/lan.ts
|
|
73096
73320
|
import net7 from "node:net";
|
|
73097
|
-
import
|
|
73321
|
+
import os22 from "node:os";
|
|
73098
73322
|
var toInt = (ip) => ip.split(".").reduce((n, part) => n * 256 + Number(part), 0) >>> 0;
|
|
73099
73323
|
function isPrivateIPv4(ip) {
|
|
73100
73324
|
if (!net7.isIPv4(ip)) return false;
|
|
@@ -73111,7 +73335,7 @@ function plainIPv4(ip) {
|
|
|
73111
73335
|
function virtualAdapter(name2) {
|
|
73112
73336
|
return /^vEthernet/i.test(name2) || /Hyper-V|WSL/i.test(name2);
|
|
73113
73337
|
}
|
|
73114
|
-
function privateAddresses(interfaces =
|
|
73338
|
+
function privateAddresses(interfaces = os22.networkInterfaces()) {
|
|
73115
73339
|
const out = [];
|
|
73116
73340
|
for (const [adapter, list2] of Object.entries(interfaces)) {
|
|
73117
73341
|
if (virtualAdapter(adapter)) continue;
|
|
@@ -73121,7 +73345,7 @@ function privateAddresses(interfaces = os21.networkInterfaces()) {
|
|
|
73121
73345
|
}
|
|
73122
73346
|
return out;
|
|
73123
73347
|
}
|
|
73124
|
-
function chooseLanAddress(configured, interfaces =
|
|
73348
|
+
function chooseLanAddress(configured, interfaces = os22.networkInterfaces()) {
|
|
73125
73349
|
const own2 = privateAddresses(interfaces);
|
|
73126
73350
|
if (configured) {
|
|
73127
73351
|
if (!isPrivateIPv4(configured))
|
|
@@ -73149,7 +73373,7 @@ function sameSubnet(a, b, netmask) {
|
|
|
73149
73373
|
const mask = toInt(netmask);
|
|
73150
73374
|
return mask !== 0 && (toInt(a) & mask) === (toInt(b) & mask);
|
|
73151
73375
|
}
|
|
73152
|
-
function lanPeerProblem(peer, local, bound, interfaces =
|
|
73376
|
+
function lanPeerProblem(peer, local, bound, interfaces = os22.networkInterfaces()) {
|
|
73153
73377
|
const ip = plainIPv4(peer);
|
|
73154
73378
|
if (plainIPv4(local) !== bound.address) return "reached another address of this PC";
|
|
73155
73379
|
if (!isPrivateIPv4(ip)) return "not a private address";
|
|
@@ -73182,7 +73406,7 @@ function removeRuleRequest() {
|
|
|
73182
73406
|
return { action: "remove", ruleName: FIREWALL_RULE_NAME };
|
|
73183
73407
|
}
|
|
73184
73408
|
var spawnRunner3 = (exe, args, timeoutMs) => new Promise((resolve) => {
|
|
73185
|
-
const child =
|
|
73409
|
+
const child = spawn14(exe, [...args], { windowsHide: true });
|
|
73186
73410
|
let stdout = "";
|
|
73187
73411
|
let stderr = "";
|
|
73188
73412
|
const timer = setTimeout(() => child.kill(), timeoutMs);
|
|
@@ -73200,7 +73424,7 @@ var OutcomeSchema3 = external_exports.object({
|
|
|
73200
73424
|
commands: external_exports.array(external_exports.string().max(1e3)).max(4).optional()
|
|
73201
73425
|
});
|
|
73202
73426
|
async function runScript2(request2, dryRun, run3) {
|
|
73203
|
-
const dir = fs119.mkdtempSync(path168.join(
|
|
73427
|
+
const dir = fs119.mkdtempSync(path168.join(os23.tmpdir(), "agent-sandbox-firewall-"));
|
|
73204
73428
|
try {
|
|
73205
73429
|
const file2 = path168.join(dir, "request.json");
|
|
73206
73430
|
fs119.writeFileSync(file2, JSON.stringify(request2, null, 2), "utf8");
|
|
@@ -73259,35 +73483,6 @@ import https from "node:https";
|
|
|
73259
73483
|
|
|
73260
73484
|
// src/host/web/auth.ts
|
|
73261
73485
|
import crypto23 from "node:crypto";
|
|
73262
|
-
|
|
73263
|
-
// src/shared/web/protocol.ts
|
|
73264
|
-
var CSRF_HEADER = "x-sandbox-web";
|
|
73265
|
-
var CSRF_VALUE = "1";
|
|
73266
|
-
var COOKIE_NAME = "sbxweb";
|
|
73267
|
-
var MIN_COLS = 10;
|
|
73268
|
-
var MAX_COLS = 500;
|
|
73269
|
-
var MIN_ROWS = 2;
|
|
73270
|
-
var MAX_ROWS = 300;
|
|
73271
|
-
var MAX_CLIENT_MESSAGE_BYTES = 256 * 1024;
|
|
73272
|
-
function parseClientMessage(text) {
|
|
73273
|
-
let value;
|
|
73274
|
-
try {
|
|
73275
|
-
value = JSON.parse(text);
|
|
73276
|
-
} catch {
|
|
73277
|
-
return null;
|
|
73278
|
-
}
|
|
73279
|
-
if (typeof value !== "object" || value === null) return null;
|
|
73280
|
-
const m = value;
|
|
73281
|
-
if (m.t !== "resize") return null;
|
|
73282
|
-
const { cols, rows } = m;
|
|
73283
|
-
if (!Number.isInteger(cols) || !Number.isInteger(rows)) return null;
|
|
73284
|
-
const c2 = cols;
|
|
73285
|
-
const r = rows;
|
|
73286
|
-
if (c2 < MIN_COLS || c2 > MAX_COLS || r < MIN_ROWS || r > MAX_ROWS) return null;
|
|
73287
|
-
return { t: "resize", cols: c2, rows: r };
|
|
73288
|
-
}
|
|
73289
|
-
|
|
73290
|
-
// src/host/web/auth.ts
|
|
73291
73486
|
var COOKIE_LIFETIME_MS = 12 * 60 * 60 * 1e3;
|
|
73292
73487
|
var MAX_COOKIES = 50;
|
|
73293
73488
|
var MAX_FAILURES = 8;
|
|
@@ -73367,17 +73562,17 @@ function cookieHeader(value) {
|
|
|
73367
73562
|
}
|
|
73368
73563
|
|
|
73369
73564
|
// src/host/web/browser.ts
|
|
73370
|
-
import { spawn as
|
|
73565
|
+
import { spawn as spawn15 } from "node:child_process";
|
|
73371
73566
|
function openBrowser(url2) {
|
|
73372
73567
|
refuseInSelfTest("open a browser");
|
|
73373
73568
|
if (!/^http:\/\/127\.0\.0\.1:\d{1,5}\/(#[kw]=[0-9a-f]{64})?$/.test(url2)) throw new Error("Not a web UI address.");
|
|
73374
|
-
|
|
73569
|
+
spawn15(SYSTEM.cmd(), ["/c", "start", "", url2], { detached: true, stdio: "ignore", windowsHide: true }).unref();
|
|
73375
73570
|
}
|
|
73376
73571
|
var ISSUE_URL = /^https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/issues\/new\?[\w%.~&=+-]*$/;
|
|
73377
73572
|
function openIssuePage(url2) {
|
|
73378
73573
|
refuseInSelfTest("open a browser");
|
|
73379
73574
|
if (!ISSUE_URL.test(url2) || url2.length > 2e3) throw new Error("Not a GitHub new-issue address.");
|
|
73380
|
-
|
|
73575
|
+
spawn15(system32("rundll32.exe"), ["url.dll,FileProtocolHandler", url2], {
|
|
73381
73576
|
detached: true,
|
|
73382
73577
|
stdio: "ignore",
|
|
73383
73578
|
windowsHide: true
|
|
@@ -74357,7 +74552,7 @@ var WebRunner = class {
|
|
|
74357
74552
|
};
|
|
74358
74553
|
|
|
74359
74554
|
// src/host/remote/windows-helper.ts
|
|
74360
|
-
import { spawn as
|
|
74555
|
+
import { spawn as spawn16 } from "node:child_process";
|
|
74361
74556
|
import readline3 from "node:readline";
|
|
74362
74557
|
var SID2 = /^S-1-[0-9-]{1,180}$/;
|
|
74363
74558
|
var MEDIUM_INTEGRITY = 8192;
|
|
@@ -74396,7 +74591,7 @@ var HostToolsHelper = class _HostToolsHelper {
|
|
|
74396
74591
|
answer = async () => "refused Windows sign-in is off.";
|
|
74397
74592
|
problem = () => void 0;
|
|
74398
74593
|
constructor(exe, pipe2) {
|
|
74399
|
-
this.child =
|
|
74594
|
+
this.child = spawn16(exe, ["web-helper", "--pipe", pipe2 ?? "", "--server-pid", String(process.pid)], {
|
|
74400
74595
|
windowsHide: true,
|
|
74401
74596
|
stdio: ["pipe", "pipe", "pipe"]
|
|
74402
74597
|
});
|
|
@@ -74793,7 +74988,7 @@ var RemoteGate = class {
|
|
|
74793
74988
|
};
|
|
74794
74989
|
|
|
74795
74990
|
// src/host/remote/tls-store.ts
|
|
74796
|
-
import
|
|
74991
|
+
import os24 from "node:os";
|
|
74797
74992
|
import path171 from "node:path";
|
|
74798
74993
|
var TlsFileSchema = external_exports.strictObject({
|
|
74799
74994
|
cert: external_exports.string().max(8e3),
|
|
@@ -74835,7 +75030,7 @@ var TlsStore = class {
|
|
|
74835
75030
|
}
|
|
74836
75031
|
/** A new certificate (the old one is gone). */
|
|
74837
75032
|
renew(addresses) {
|
|
74838
|
-
const made = makeCertificate({ addresses, dnsNames: [
|
|
75033
|
+
const made = makeCertificate({ addresses, dnsNames: [os24.hostname()], now: this.now() });
|
|
74839
75034
|
this.file.write({
|
|
74840
75035
|
cert: made.cert,
|
|
74841
75036
|
key: this.secrets.seal(made.key),
|
|
@@ -76331,12 +76526,16 @@ var ServiceRowSchema = external_exports.object({
|
|
|
76331
76526
|
canImport: external_exports.boolean().describe("It can be taken from this PC or a file (sandbox account import)"),
|
|
76332
76527
|
canLogin: external_exports.boolean().describe("It can be typed (sandbox account login)"),
|
|
76333
76528
|
needsFile: external_exports.boolean().describe("Importing it needs --from <file>"),
|
|
76529
|
+
fromPc: external_exports.boolean().describe("This PC's own program can give it (the next launch takes it when sharing is on)"),
|
|
76530
|
+
hasFileSource: external_exports.boolean().describe("It can be read from a file you name"),
|
|
76531
|
+
onPc: external_exports.boolean().nullable().describe("This PC has one to take (null: it cannot be taken from this PC). Only the presence, never the sign-in"),
|
|
76532
|
+
sandboxOnly: external_exports.boolean().describe("Only a sandbox can give it: sign in once inside one and it is kept"),
|
|
76334
76533
|
ready: external_exports.boolean().describe("Its sign-in is written; false: the menu and the web leave it out (the CLI says coming)")
|
|
76335
76534
|
});
|
|
76336
76535
|
var ServicesListSchema = external_exports.object({ services: external_exports.array(ServiceRowSchema) });
|
|
76337
76536
|
var STATE_TEXT = {
|
|
76338
76537
|
none: "not saved",
|
|
76339
|
-
saved: "saved
|
|
76538
|
+
saved: "saved",
|
|
76340
76539
|
unreadable: "cannot be read"
|
|
76341
76540
|
};
|
|
76342
76541
|
var STATE_TONE = {
|
|
@@ -76345,10 +76544,10 @@ var STATE_TONE = {
|
|
|
76345
76544
|
unreadable: "danger"
|
|
76346
76545
|
};
|
|
76347
76546
|
var SOURCE_TEXT = {
|
|
76348
|
-
pc: "
|
|
76547
|
+
pc: "from this PC",
|
|
76349
76548
|
file: "from a file",
|
|
76350
|
-
typed: "
|
|
76351
|
-
sandbox: "
|
|
76549
|
+
typed: "by typing it",
|
|
76550
|
+
sandbox: "from a sandbox"
|
|
76352
76551
|
};
|
|
76353
76552
|
var day = (iso) => iso ? iso.slice(0, 10) : "";
|
|
76354
76553
|
function servicesText(o) {
|
|
@@ -76381,7 +76580,8 @@ var serviceImport = defineOperation({
|
|
|
76381
76580
|
summary: "save a service sign-in from this PC's program or a file, for sandboxes",
|
|
76382
76581
|
input: external_exports.object({
|
|
76383
76582
|
name: KindSchema,
|
|
76384
|
-
from: external_exports.string().max(1e3).optional().describe("(import) the file or folder to take the sign-in from")
|
|
76583
|
+
from: external_exports.string().max(1e3).optional().describe("(import) the file or folder to take the sign-in from"),
|
|
76584
|
+
file: external_exports.boolean().optional().describe("(import) ask for a file even when this PC has one to take")
|
|
76385
76585
|
}),
|
|
76386
76586
|
output: MessageSchema2,
|
|
76387
76587
|
text: (o) => o.message,
|
|
@@ -76410,6 +76610,12 @@ var SERVICE_OPERATIONS = [serviceImport, serviceLogin, serviceLogout];
|
|
|
76410
76610
|
function serviceCategory(kind) {
|
|
76411
76611
|
return "service:" + kind;
|
|
76412
76612
|
}
|
|
76613
|
+
var PC_HELP = {
|
|
76614
|
+
epic: "Sign in to the Epic launcher here, with Remember me on.",
|
|
76615
|
+
steam: "Log in once with SteamCMD in C:\\steamcmd.",
|
|
76616
|
+
unity: "Sign in to the Unity Hub here.",
|
|
76617
|
+
perplexity: "Set PERPLEXITY_API_KEY for your Windows user."
|
|
76618
|
+
};
|
|
76413
76619
|
function serviceActions(s3) {
|
|
76414
76620
|
return [
|
|
76415
76621
|
action(
|
|
@@ -76422,51 +76628,75 @@ function serviceActions(s3) {
|
|
|
76422
76628
|
importance: 1
|
|
76423
76629
|
}
|
|
76424
76630
|
),
|
|
76425
|
-
...s3.
|
|
76426
|
-
|
|
76631
|
+
...s3.fromPc ? [
|
|
76632
|
+
action(
|
|
76633
|
+
serviceImport,
|
|
76634
|
+
{ name: s3.kind },
|
|
76635
|
+
{ key: "i", verb: "take from this PC", label: "Take this PC's sign-in", importance: 1 }
|
|
76636
|
+
)
|
|
76637
|
+
] : [],
|
|
76638
|
+
...s3.hasFileSource ? [
|
|
76639
|
+
action(
|
|
76640
|
+
serviceImport,
|
|
76641
|
+
{ name: s3.kind, file: true },
|
|
76642
|
+
{
|
|
76643
|
+
key: s3.fromPc ? "f" : "i",
|
|
76644
|
+
verb: "import a file",
|
|
76645
|
+
label: "Import from a file\u2026",
|
|
76646
|
+
importance: s3.fromPc ? 2 : 1
|
|
76647
|
+
}
|
|
76648
|
+
)
|
|
76649
|
+
] : [],
|
|
76650
|
+
...s3.canLogin ? [
|
|
76651
|
+
action(
|
|
76652
|
+
serviceLogin,
|
|
76653
|
+
{ name: s3.kind },
|
|
76654
|
+
{ key: "n", verb: "type it in", label: "Type the sign-in\u2026", importance: 1 }
|
|
76655
|
+
)
|
|
76656
|
+
] : [],
|
|
76427
76657
|
...s3.state !== "none" ? [action(serviceLogout, { name: s3.kind }, { key: "x", verb: "forget", importance: 2 })] : []
|
|
76428
76658
|
];
|
|
76429
76659
|
}
|
|
76430
|
-
function
|
|
76431
|
-
|
|
76432
|
-
|
|
76660
|
+
function helpLine(s3) {
|
|
76661
|
+
if (s3.state !== "none") return void 0;
|
|
76662
|
+
if (s3.sandboxOnly) return "Sign in once inside a sandbox; it is kept for the next ones.";
|
|
76663
|
+
if (s3.fromPc && s3.onPc)
|
|
76664
|
+
return s3.share ? "The next sandbox takes this PC's." : "Share it and the next sandbox takes this PC's.";
|
|
76665
|
+
if (s3.fromPc) return PC_HELP[s3.kind] ?? "Not found on this PC.";
|
|
76666
|
+
return s3.canLogin ? "Type it in, or import it from a file." : "Import it from a file.";
|
|
76433
76667
|
}
|
|
76434
76668
|
function serviceSection(s3) {
|
|
76435
76669
|
const facts2 = [
|
|
76436
76670
|
{
|
|
76437
76671
|
id: s3.kind + ":share",
|
|
76438
|
-
label: "Shared
|
|
76672
|
+
label: "Shared",
|
|
76439
76673
|
value: s3.share ? "on" : "off",
|
|
76440
76674
|
tone: s3.share ? "ok" : "muted",
|
|
76441
|
-
description: "
|
|
76675
|
+
description: "The agent can use it."
|
|
76442
76676
|
},
|
|
76443
76677
|
{
|
|
76444
76678
|
id: s3.kind + ":state",
|
|
76445
76679
|
label: "Sign-in",
|
|
76446
76680
|
value: STATE_TEXT[s3.state] + (s3.savedAt ? " " + day(s3.savedAt) : ""),
|
|
76447
76681
|
tone: STATE_TONE[s3.state],
|
|
76448
|
-
description: s3.state === "
|
|
76682
|
+
description: s3.state === "unreadable" ? "Only the Windows user that saved it can read it: save it again." : helpLine(s3) ?? (s3.source ? "Saved " + (SOURCE_TEXT[s3.source] ?? s3.source) + "." : void 0)
|
|
76449
76683
|
},
|
|
76450
|
-
...s3.
|
|
76684
|
+
...s3.onPc === null ? [] : [
|
|
76685
|
+
{
|
|
76686
|
+
id: s3.kind + ":pc",
|
|
76687
|
+
label: "On this PC",
|
|
76688
|
+
value: s3.onPc ? "found" : "not found",
|
|
76689
|
+
tone: s3.onPc ? "ok" : "muted"
|
|
76690
|
+
}
|
|
76691
|
+
],
|
|
76451
76692
|
...s3.summary ? [{ id: s3.kind + ":summary", label: "Account", value: s3.summary }] : [],
|
|
76452
76693
|
...s3.heldBy ? [{ id: s3.kind + ":held", label: "In use by", value: "sandbox " + s3.heldBy, tone: "accent" }] : []
|
|
76453
76694
|
];
|
|
76454
|
-
const warnings = s3.warnings.map((w, i) => ({
|
|
76455
|
-
id: s3.kind + ":warning:" + i,
|
|
76456
|
-
label: w,
|
|
76457
|
-
tone: "warn",
|
|
76458
|
-
group: "Before you share it"
|
|
76459
|
-
}));
|
|
76460
|
-
const notes = [
|
|
76461
|
-
...s3.state === "unreadable" ? [{ text: "Only the Windows user that saved it can read it: save it again.", tone: "muted" }] : []
|
|
76462
|
-
];
|
|
76463
76695
|
return {
|
|
76464
76696
|
id: serviceCategory(s3.kind),
|
|
76465
76697
|
title: s3.label,
|
|
76466
76698
|
summary: (s3.share ? "shared" : "not shared") + " \xB7 " + STATE_TEXT[s3.state],
|
|
76467
76699
|
facts: facts2,
|
|
76468
|
-
items: warnings,
|
|
76469
|
-
notes,
|
|
76470
76700
|
actions: serviceActions(s3)
|
|
76471
76701
|
};
|
|
76472
76702
|
}
|
|
@@ -76781,7 +77011,17 @@ var accountsView = defineView({
|
|
|
76781
77011
|
// src/app/features/accounts/services.run.ts
|
|
76782
77012
|
import fs124 from "node:fs";
|
|
76783
77013
|
import path174 from "node:path";
|
|
76784
|
-
function
|
|
77014
|
+
function presentOnPc(kind, pc) {
|
|
77015
|
+
const source = HOST_SOURCES[kind];
|
|
77016
|
+
if (!source.fromPc) return null;
|
|
77017
|
+
if (!pc) return false;
|
|
77018
|
+
try {
|
|
77019
|
+
return source.fromPc(pc) !== null;
|
|
77020
|
+
} catch {
|
|
77021
|
+
return false;
|
|
77022
|
+
}
|
|
77023
|
+
}
|
|
77024
|
+
function serviceRow(kind, config3, store, leases, pc) {
|
|
76785
77025
|
const spec = SERVICE_SPECS[kind];
|
|
76786
77026
|
const source = HOST_SOURCES[kind];
|
|
76787
77027
|
const state = store.state(kind);
|
|
@@ -76802,6 +77042,10 @@ function serviceRow(kind, config3, store, leases) {
|
|
|
76802
77042
|
canImport: Boolean(source.fromPc || source.fromFile),
|
|
76803
77043
|
canLogin: Boolean(source.fromAnswers),
|
|
76804
77044
|
needsFile: Boolean(source.fromFile && !source.fromPc),
|
|
77045
|
+
fromPc: Boolean(source.fromPc),
|
|
77046
|
+
hasFileSource: Boolean(source.fromFile),
|
|
77047
|
+
onPc: presentOnPc(kind, pc),
|
|
77048
|
+
sandboxOnly: !source.fromPc && !source.fromFile && !source.fromAnswers,
|
|
76805
77049
|
ready: isKindReady(kind)
|
|
76806
77050
|
};
|
|
76807
77051
|
}
|
|
@@ -76849,7 +77093,7 @@ function refuseSandboxOnly(spec) {
|
|
|
76849
77093
|
function savedMessage(kind, share2) {
|
|
76850
77094
|
return "Saved your " + SERVICE_SPECS[kind].label + " sign-in (encrypted for your Windows user)." + (share2 ? "" : " Sandboxes get it once you turn on Share with sandboxes.");
|
|
76851
77095
|
}
|
|
76852
|
-
async function importServiceFlow(io, kind, from, deps) {
|
|
77096
|
+
async function importServiceFlow(io, kind, from, deps, wantFile = false) {
|
|
76853
77097
|
const spec = SERVICE_SPECS[kind];
|
|
76854
77098
|
const source = HOST_SOURCES[kind];
|
|
76855
77099
|
if (!source.fromPc && !source.fromFile) refuseSandboxOnly(spec);
|
|
@@ -76857,7 +77101,7 @@ async function importServiceFlow(io, kind, from, deps) {
|
|
|
76857
77101
|
failWith(spec.label + " cannot be imported.", "Type it instead.", {
|
|
76858
77102
|
op: "accounts.service.login",
|
|
76859
77103
|
input: { name: kind },
|
|
76860
|
-
label: "
|
|
77104
|
+
label: "Type the sign-in\u2026",
|
|
76861
77105
|
cli: "sandbox account login " + kind
|
|
76862
77106
|
});
|
|
76863
77107
|
let file2 = from === void 0 ? void 0 : path174.resolve(from);
|
|
@@ -76868,7 +77112,7 @@ async function importServiceFlow(io, kind, from, deps) {
|
|
|
76868
77112
|
return false;
|
|
76869
77113
|
}
|
|
76870
77114
|
};
|
|
76871
|
-
const useFile = Boolean(source.fromFile && (file2 ? isFile(file2) : !source.fromPc));
|
|
77115
|
+
const useFile = Boolean(source.fromFile && (file2 ? isFile(file2) : wantFile || !source.fromPc));
|
|
76872
77116
|
if (useFile && !file2) {
|
|
76873
77117
|
const asked = await io.path({ title: "The " + spec.label + " file:", pathKind: "file" });
|
|
76874
77118
|
if (asked === void 0) cancelled();
|
|
@@ -76945,7 +77189,8 @@ var listServicesRun = implement(listServices, async (ctx, input2) => {
|
|
|
76945
77189
|
if (name2 !== void 0 && name2 !== "" && !isServiceKind(name2))
|
|
76946
77190
|
fail('There is no service called "' + safeText(input2.name ?? "") + '".', "Use one of: " + SERVICE_KINDS.join(", "));
|
|
76947
77191
|
const kinds = name2 ? [name2] : [...SERVICE_KINDS];
|
|
76948
|
-
|
|
77192
|
+
const pc = pcEnv();
|
|
77193
|
+
return { services: kinds.map((k) => serviceRow(k, ctx.loaded.config, store, leases, pc)) };
|
|
76949
77194
|
});
|
|
76950
77195
|
var serviceImportRun = implement(serviceImport, async (ctx, input2, io) => {
|
|
76951
77196
|
requireOnPc("account import");
|
|
@@ -76955,11 +77200,17 @@ var serviceImportRun = implement(serviceImport, async (ctx, input2, io) => {
|
|
|
76955
77200
|
"import",
|
|
76956
77201
|
(s3) => Boolean(HOST_SOURCES[s3.kind].fromPc || HOST_SOURCES[s3.kind].fromFile)
|
|
76957
77202
|
);
|
|
76958
|
-
return importServiceFlow(
|
|
76959
|
-
|
|
76960
|
-
|
|
76961
|
-
|
|
76962
|
-
|
|
77203
|
+
return importServiceFlow(
|
|
77204
|
+
io,
|
|
77205
|
+
kind,
|
|
77206
|
+
input2.from,
|
|
77207
|
+
{
|
|
77208
|
+
store: new ServiceAccountStore(ctx.storageRoot),
|
|
77209
|
+
pc: pcEnv(),
|
|
77210
|
+
share: ctx.loaded.config.accounts[kind].share
|
|
77211
|
+
},
|
|
77212
|
+
input2.file ?? false
|
|
77213
|
+
);
|
|
76963
77214
|
});
|
|
76964
77215
|
var serviceLoginRun = implement(serviceLogin, async (ctx, input2, io) => {
|
|
76965
77216
|
requireOnPc("account login");
|
|
@@ -80011,6 +80262,9 @@ var SETTINGS = {
|
|
|
80011
80262
|
theme: "dark",
|
|
80012
80263
|
firstWindowPreference: "defaultProfile",
|
|
80013
80264
|
confirmCloseAllTabs: false,
|
|
80265
|
+
// Copied the moment the mouse is released, so an agent's redraw cannot clear the selection first.
|
|
80266
|
+
copyOnSelect: true,
|
|
80267
|
+
copyFormatting: "none",
|
|
80014
80268
|
// New tabs pick up the PATH and variables the runner writes machine-wide after the window opened.
|
|
80015
80269
|
compatibility: { reloadEnvironmentVariables: true },
|
|
80016
80270
|
warning: { confirmCloseAllTabs: false, largePaste: false, multiLinePaste: false },
|
|
@@ -80049,6 +80303,10 @@ function withReloadEnvironment(settings) {
|
|
|
80049
80303
|
if (compatibility?.reloadEnvironmentVariables === true) return null;
|
|
80050
80304
|
return { ...settings, compatibility: { ...compatibility, reloadEnvironmentVariables: true } };
|
|
80051
80305
|
}
|
|
80306
|
+
function withCopyOnSelect(settings) {
|
|
80307
|
+
if ("copyOnSelect" in settings) return null;
|
|
80308
|
+
return { ...settings, copyOnSelect: true };
|
|
80309
|
+
}
|
|
80052
80310
|
function syncPwshProfile(dataPath, allowed) {
|
|
80053
80311
|
const file2 = path185.join(terminalDir(dataPath), "settings", "settings.json");
|
|
80054
80312
|
assertTestWritable2(file2);
|
|
@@ -80066,15 +80324,18 @@ function syncPwshProfile(dataPath, allowed) {
|
|
|
80066
80324
|
}
|
|
80067
80325
|
const withProfile = withPwshProfile(parsed, visible);
|
|
80068
80326
|
if (withProfile) {
|
|
80069
|
-
|
|
80327
|
+
const reloaded = withReloadEnvironment(withProfile) ?? withProfile;
|
|
80328
|
+
writeJson(file2, withCopyOnSelect(reloaded) ?? reloaded);
|
|
80070
80329
|
return;
|
|
80071
80330
|
}
|
|
80072
|
-
|
|
80073
|
-
|
|
80074
|
-
|
|
80075
|
-
|
|
80076
|
-
|
|
80077
|
-
|
|
80331
|
+
const missing = [];
|
|
80332
|
+
if (withReloadEnvironment(parsed)) missing.push([["compatibility", "reloadEnvironmentVariables"], true]);
|
|
80333
|
+
if (withCopyOnSelect(parsed)) missing.push([["copyOnSelect"], true]);
|
|
80334
|
+
if (missing.length === 0) return;
|
|
80335
|
+
let edited = text;
|
|
80336
|
+
for (const [at, value] of missing)
|
|
80337
|
+
edited = applyEdits(edited, modify(edited, at, value, { formattingOptions: { insertSpaces: true, tabSize: 4 } }));
|
|
80338
|
+
writeFileAtomic(file2, edited);
|
|
80078
80339
|
}
|
|
80079
80340
|
async function ensureTerminal(dataPath, refresh, options = {}) {
|
|
80080
80341
|
const result = await installTerminal(dataPath, refresh);
|
|
@@ -83319,7 +83580,7 @@ var vpnLogoutRun = implement(vpnLogout, async (ctx, _input, io) => {
|
|
|
83319
83580
|
});
|
|
83320
83581
|
|
|
83321
83582
|
// src/app/features/github/github.run.ts
|
|
83322
|
-
import
|
|
83583
|
+
import os25 from "node:os";
|
|
83323
83584
|
async function saveGithubTokenFlow(io, store, verify = verifyGithubToken) {
|
|
83324
83585
|
io.log("Make a GitHub token only for sandboxes:");
|
|
83325
83586
|
GITHUB_STEPS.forEach((s3, i) => io.log(" " + (i + 1) + ". " + s3));
|
|
@@ -83380,7 +83641,7 @@ var githubStatusRun = implement(githubStatus, async (ctx) => {
|
|
|
83380
83641
|
expiresAt: token === "none" ? null : store.check()?.expiresAt ?? null,
|
|
83381
83642
|
repoCount: token === "none" ? null : store.check()?.repoCount ?? null,
|
|
83382
83643
|
checkedAt: token === "none" ? null : store.check()?.checkedAt ?? null,
|
|
83383
|
-
tokenUrl: tokenUrlFor(
|
|
83644
|
+
tokenUrl: tokenUrlFor(os25.hostname())
|
|
83384
83645
|
};
|
|
83385
83646
|
});
|
|
83386
83647
|
var githubLoginRun = implement(githubLogin, async (ctx, _input, io) => {
|
|
@@ -84736,7 +84997,14 @@ function implementationOf(id) {
|
|
|
84736
84997
|
function runDefinition(id, ctx, input2, io) {
|
|
84737
84998
|
const impl = implementationOf(id);
|
|
84738
84999
|
if (!impl) throw new Error("No implementation for " + id);
|
|
84739
|
-
return
|
|
85000
|
+
return invokeAndRefresh(impl, ctx, input2, io);
|
|
85001
|
+
}
|
|
85002
|
+
async function invokeAndRefresh(impl, ctx, input2, io) {
|
|
85003
|
+
try {
|
|
85004
|
+
return await invoke(impl, ctx, input2, io);
|
|
85005
|
+
} finally {
|
|
85006
|
+
if (impl.def.kind === "operation") reloadSettings(ctx);
|
|
85007
|
+
}
|
|
84740
85008
|
}
|
|
84741
85009
|
async function readQuery(def, ctx, input2 = {}) {
|
|
84742
85010
|
return await runDefinition(def.id, ctx, input2, NO_QUESTIONS);
|
|
@@ -84761,7 +85029,7 @@ function createRpcHost(ctx) {
|
|
|
84761
85029
|
if (!impl) throw new Error("Not allowed on the web: " + id);
|
|
84762
85030
|
const need = accessNeeded(impl.def, input2);
|
|
84763
85031
|
if (!allows(caller, need)) fail(refusalText(caller, need));
|
|
84764
|
-
return
|
|
85032
|
+
return invokeAndRefresh(impl, ctx, input2, io);
|
|
84765
85033
|
}
|
|
84766
85034
|
};
|
|
84767
85035
|
}
|
|
@@ -85188,7 +85456,7 @@ async function attachOpened(ctx, session) {
|
|
|
85188
85456
|
nextStep("sandbox attach " + session);
|
|
85189
85457
|
return 0;
|
|
85190
85458
|
}
|
|
85191
|
-
const { attach: attach2 } = await import("./chunk-
|
|
85459
|
+
const { attach: attach2 } = await import("./chunk-UZ5S3EMB.js");
|
|
85192
85460
|
return attach2({ ...ctx, options: { ...ctx.options, positionals: [session] } });
|
|
85193
85461
|
}
|
|
85194
85462
|
function definitionHandler(def) {
|
|
@@ -86148,6 +86416,9 @@ export {
|
|
|
86148
86416
|
NAV,
|
|
86149
86417
|
withOperationCommands,
|
|
86150
86418
|
SandboxChannel,
|
|
86419
|
+
CSRF_HEADER,
|
|
86420
|
+
CSRF_VALUE,
|
|
86421
|
+
reloadSettings,
|
|
86151
86422
|
esm_default4 as esm_default,
|
|
86152
86423
|
esm_default11 as esm_default2,
|
|
86153
86424
|
askChoice,
|
|
@@ -86206,8 +86477,6 @@ export {
|
|
|
86206
86477
|
settingRow,
|
|
86207
86478
|
ProjectsService,
|
|
86208
86479
|
StorageService,
|
|
86209
|
-
CSRF_HEADER,
|
|
86210
|
-
CSRF_VALUE,
|
|
86211
86480
|
openBrowser,
|
|
86212
86481
|
import_websocket,
|
|
86213
86482
|
INSTALL,
|