windows-development-sandbox 1.25.0 → 1.25.1
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/config.example.json +5 -2
- package/dist/app/features/data/data.def.d.ts +4 -4
- package/dist/app/features/data/data.run.d.ts +1 -1
- package/dist/app/features/defs.d.ts +161 -6
- package/dist/app/features/defs.js +7 -0
- package/dist/app/features/projects/projects.def.d.ts +1 -1
- package/dist/app/features/projects/projects.run.d.ts +1 -1
- package/dist/app/features/unreal/index.d.ts +2 -0
- package/dist/app/features/unreal/index.js +3 -0
- package/dist/app/features/unreal/unreal.def.d.ts +236 -0
- package/dist/app/features/unreal/unreal.def.js +379 -0
- package/dist/app/features/unreal/unreal.run.d.ts +96 -0
- package/dist/app/features/unreal/unreal.run.js +217 -0
- package/dist/app/registry.js +5 -0
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-SUYYVIDW.js → chunk-3GAXLATK.js} +58 -5
- package/dist/bin/{chunk-IZRGTSQ5.js → chunk-F4PVBN23.js} +2465 -1392
- package/dist/bin/{chunk-KH4MI2U5.js → chunk-G3TG4ZT7.js} +1 -1
- 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/commands/launch/launch.js +5 -2
- package/dist/cli/commands/registry.js +3 -0
- package/dist/cli/manifest.d.ts +18 -0
- package/dist/cli/manifest.js +26 -0
- package/dist/cli/menu/coverage-exempt.js +1 -0
- package/dist/cli/menu/pages/sandbox-page.d.ts +3 -0
- package/dist/cli/menu/pages/sandbox-page.js +34 -4
- package/dist/cli/menu/views.js +2 -0
- package/dist/core/config/defaults.js +18 -4
- package/dist/core/schema/config.d.ts +9 -7
- package/dist/core/schema/pc-installs.d.ts +3 -1
- package/dist/core/schema/pc-installs.js +10 -1
- package/dist/core/schema/toolchains.js +1 -1
- package/dist/guest/accounts/kinds/epic.js +18 -13
- package/dist/guest/apps/after-install.d.ts +1 -1
- package/dist/guest/apps/after-install.js +6 -1
- package/dist/guest/apps/app-installer.d.ts +1 -0
- package/dist/guest/apps/app-installer.js +13 -3
- package/dist/guest/apps/comet-unpack.js +3 -2
- package/dist/guest/apps/resolvers-gamedev.js +55 -1
- package/dist/guest/boot/boot.js +14 -1
- package/dist/guest/boot/guide.js +24 -0
- package/dist/guest/daemon/daemon.js +3 -0
- package/dist/guest/setup/addon-mcp.d.ts +7 -0
- package/dist/guest/setup/addon-mcp.js +19 -4
- package/dist/guest/setup/browser-gpu.js +14 -11
- package/dist/guest/setup/headroom.js +4 -0
- package/dist/guest/toolchains/engines/epic-launcher.d.ts +26 -0
- package/dist/guest/toolchains/engines/epic-launcher.js +127 -0
- package/dist/guest/toolchains/engines/unreal-engines.d.ts +21 -1
- package/dist/guest/toolchains/engines/unreal-engines.js +163 -3
- package/dist/guest/toolchains/engines/unreal-status.d.ts +13 -0
- package/dist/guest/toolchains/engines/unreal-status.js +41 -0
- package/dist/guest/toolchains/native/debuggers.d.ts +6 -0
- package/dist/guest/toolchains/native/debuggers.js +57 -0
- package/dist/guest/toolchains/native/mesa.js +15 -8
- package/dist/guest/toolchains/native/rust-extras.d.ts +7 -0
- package/dist/guest/toolchains/native/rust-extras.js +23 -1
- package/dist/guest/toolchains/native/unreal.d.ts +2 -2
- package/dist/guest/toolchains/native/unreal.js +96 -18
- package/dist/guest/toolchains/plan.js +12 -1
- package/dist/guest/toolchains/tools/vscode-profile.js +2 -0
- package/dist/host/accounts/kinds/epic.js +11 -5
- package/dist/host/accounts/source.d.ts +2 -0
- package/dist/host/accounts/source.js +1 -0
- package/dist/host/pc-installs/discover.d.ts +2 -0
- package/dist/host/pc-installs/discover.js +25 -5
- package/dist/host/pc-installs/epic.d.ts +3 -0
- package/dist/host/pc-installs/epic.js +33 -2
- package/dist/host/pc-installs/source.d.ts +1 -1
- package/dist/host/pc-installs/unreal-vault.d.ts +11 -0
- package/dist/host/pc-installs/unreal-vault.js +78 -0
- package/dist/host/pc-installs/unreal.d.ts +36 -0
- package/dist/host/pc-installs/unreal.js +145 -2
- package/dist/host/profile/claude-profile.d.ts +8 -0
- package/dist/host/profile/claude-profile.js +43 -4
- package/dist/host/profile/index.d.ts +1 -1
- package/dist/host/profile/index.js +1 -1
- package/dist/runtime/agent.js +81 -7
- package/dist/runtime/daemon.js +2645 -1287
- package/dist/runtime/db.js +81 -7
- package/dist/runtime/main.js +2901 -1722
- package/dist/runtime/netproxy.js +81 -7
- package/dist/runtime/tool.js +81 -7
- package/dist/runtime/view.js +81 -7
- package/dist/selftest/agent-paths.test.js +1 -0
- package/dist/selftest/agents-web.test.js +12 -0
- package/dist/selftest/engines.test.js +602 -3
- package/dist/selftest/heavy-load.test.js +3 -1
- package/dist/selftest/hostile-input.test.js +11 -1
- package/dist/selftest/index.js +2 -0
- package/dist/selftest/menu-screens.js +3 -1
- package/dist/selftest/mixamo.test.d.ts +2 -0
- package/dist/selftest/mixamo.test.js +60 -0
- package/dist/selftest/secrets.test.js +36 -1
- package/dist/selftest/support/engine-golden.js +3 -0
- package/dist/selftest/support/fixtures.d.ts +3 -1
- package/dist/selftest/support/unreal-sample.d.ts +2 -0
- package/dist/selftest/support/unreal-sample.js +83 -0
- package/dist/selftest/toolchains.test.js +32 -2
- package/dist/shared/accounts/index.d.ts +1 -1
- package/dist/shared/accounts/index.js +1 -1
- package/dist/shared/accounts/kinds/epic.d.ts +6 -1
- package/dist/shared/accounts/kinds/epic.js +11 -1
- package/dist/shared/apps/associations.d.ts +7 -0
- package/dist/shared/apps/associations.js +26 -0
- package/dist/shared/apps/catalogue-agents-web.d.ts +4 -1
- package/dist/shared/apps/catalogue-agents-web.js +5 -2
- package/dist/shared/apps/catalogue-gamedev.js +71 -1
- package/dist/shared/apps/index.d.ts +2 -0
- package/dist/shared/apps/index.js +2 -0
- package/dist/shared/apps/preview.d.ts +2 -0
- package/dist/shared/apps/preview.js +10 -0
- package/dist/shared/browser-policy.d.ts +14 -0
- package/dist/shared/browser-policy.js +22 -0
- package/dist/shared/io/index.d.ts +1 -0
- package/dist/shared/io/index.js +1 -0
- package/dist/shared/io/rotate-log.d.ts +2 -0
- package/dist/shared/io/rotate-log.js +16 -0
- package/dist/shared/memory/policy.d.ts +5 -0
- package/dist/shared/memory/policy.js +7 -0
- package/dist/shared/paths/pc-installs.d.ts +13 -2
- package/dist/shared/paths/pc-installs.js +1 -0
- package/dist/shared/readiness.d.ts +0 -1
- package/dist/shared/readiness.js +0 -1
- package/dist/shared/signer.d.ts +4 -0
- package/dist/shared/signer.js +2 -0
- package/dist/shared/unreal/engines.d.ts +161 -0
- package/dist/shared/unreal/engines.js +308 -0
- package/dist/shared/unreal/guide.d.ts +19 -0
- package/dist/shared/unreal/guide.js +105 -0
- package/dist/shared/unreal/index.d.ts +7 -0
- package/dist/shared/unreal/index.js +8 -0
- package/dist/shared/unreal/launcher-files.d.ts +88 -0
- package/dist/shared/unreal/launcher-files.js +292 -0
- package/dist/shared/unreal/mixamo.d.ts +5 -0
- package/dist/shared/unreal/mixamo.js +16 -0
- package/dist/shared/unreal/room.d.ts +17 -0
- package/dist/shared/unreal/room.js +34 -0
- package/dist/shared/unreal/status.d.ts +54 -0
- package/dist/shared/unreal/status.js +57 -0
- package/dist/shared/unreal/vault.d.ts +21 -0
- package/dist/shared/unreal/vault.js +67 -0
- package/dist/shared/unreal/vs-check.d.ts +39 -0
- package/dist/shared/unreal/vs-check.js +79 -0
- package/dist/web/index.html +1 -1
- package/dist/web/{main-CCILLX2M.js → main-FNE6XEHA.js} +84 -84
- package/package.json +1 -1
- package/sandbox/csharp/VsSetup.cs +210 -0
- package/sandbox/scripts/get-vs-setup.ps1 +93 -0
- package/sandbox/scripts/set-registry-values.ps1 +35 -0
- package/schemas/config.schema.json +35 -2
- package/schemas/sandbox-config.schema.json +8 -1
package/dist/bin/claude-host.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
run
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3GAXLATK.js";
|
|
6
|
+
import "./chunk-F4PVBN23.js";
|
|
7
7
|
|
|
8
8
|
// src/bin/claude-host.ts
|
|
9
9
|
var args = process.argv.slice(2);
|
package/dist/bin/claude-sbx.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
run
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3GAXLATK.js";
|
|
6
|
+
import "./chunk-F4PVBN23.js";
|
|
7
7
|
|
|
8
8
|
// src/bin/claude-sbx.ts
|
|
9
9
|
run(process.argv.slice(2), { harness: "claude" });
|
package/dist/bin/codex-sbx.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
run
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3GAXLATK.js";
|
|
6
|
+
import "./chunk-F4PVBN23.js";
|
|
7
7
|
|
|
8
8
|
// src/bin/codex-sbx.ts
|
|
9
9
|
run(process.argv.slice(2), { harness: "codex" });
|
package/dist/bin/gemini-sbx.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
run
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3GAXLATK.js";
|
|
6
|
+
import "./chunk-F4PVBN23.js";
|
|
7
7
|
|
|
8
8
|
// src/bin/gemini-sbx.ts
|
|
9
9
|
run(process.argv.slice(2), { harness: "gemini" });
|
package/dist/bin/sandbox.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
run
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3GAXLATK.js";
|
|
6
|
+
import "./chunk-F4PVBN23.js";
|
|
7
7
|
|
|
8
8
|
// src/bin/sandbox.ts
|
|
9
9
|
run(process.argv.slice(2));
|
package/dist/bin/sbx-hide.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
run
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3GAXLATK.js";
|
|
6
|
+
import "./chunk-F4PVBN23.js";
|
|
7
7
|
|
|
8
8
|
// src/bin/sbx-hide.ts
|
|
9
9
|
run(process.argv.slice(2), { command: "hide" });
|
package/dist/bin/sbx-show.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
run
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3GAXLATK.js";
|
|
6
|
+
import "./chunk-F4PVBN23.js";
|
|
7
7
|
|
|
8
8
|
// src/bin/sbx-show.ts
|
|
9
9
|
run(process.argv.slice(2), { command: "show" });
|
|
@@ -180,22 +180,25 @@ class Launcher {
|
|
|
180
180
|
: prepareGithubToken(config, ctx.storageRoot, undefined, bootWants.wants.projects);
|
|
181
181
|
// accounts.<kind>.share: the saved service sign-ins this boot's toolchains use, for the one-shot file only.
|
|
182
182
|
const launchId = newLaunchId();
|
|
183
|
+
const toolchainsOn = toolchainsOnForBoot({ run }, bootWants.wants.projects);
|
|
183
184
|
const accounts = generateOnly
|
|
184
185
|
? null
|
|
185
186
|
: prepareServiceAccounts({
|
|
186
187
|
config,
|
|
187
188
|
others: bootWants.wants.projects,
|
|
188
|
-
on:
|
|
189
|
+
on: toolchainsOn,
|
|
189
190
|
storageRoot: ctx.storageRoot,
|
|
190
191
|
dataPath: run.dataPath,
|
|
191
192
|
launchId,
|
|
192
193
|
// A new launch needs no sandbox running, so a lease held elsewhere is from one that stopped.
|
|
193
194
|
isRunning: () => isSandboxRunning(),
|
|
194
195
|
});
|
|
195
|
-
// pcInstalls: this PC's games, engines and editors, read-only (yours only: never from a project file).
|
|
196
|
+
// pcInstalls: this PC's games, engines and editors, read-only (yours only: never from a project file). The
|
|
197
|
+
// engines ("auto") come along whenever this launch sets the sandbox up for Unreal.
|
|
196
198
|
const pcInstalls = discoverPcInstalls(ctx.loaded.config.pcInstalls, {
|
|
197
199
|
packageRoot: ctx.packageRoot,
|
|
198
200
|
storageRoot: ctx.storageRoot,
|
|
201
|
+
unrealOn: toolchainsOn.has('unreal'),
|
|
199
202
|
});
|
|
200
203
|
// This PC's commit (RAM plus paging file) bounds the sandbox's memory as much as free RAM does.
|
|
201
204
|
const hostMemory = generateOnly ? null : readHostMemory(ctx.storageRoot);
|
|
@@ -7,6 +7,7 @@ import { agentCommandsStatus } from '../../app/features/agent-commands/index.js'
|
|
|
7
7
|
import { listAccounts } from '../../app/features/accounts/index.js';
|
|
8
8
|
import { containedStatus, showStorage } from '../../app/features/storage/index.js';
|
|
9
9
|
import { listProjects } from '../../app/features/projects/index.js';
|
|
10
|
+
import { unrealOverview } from '../../app/features/unreal/index.js';
|
|
10
11
|
import { definitionHandler } from '../operations/index.js';
|
|
11
12
|
import { fail } from '../../core/util/index.js';
|
|
12
13
|
import { claudeHost, config, doctor, hostCommand, logs, sync, watcher } from './maintenance/index.js';
|
|
@@ -48,6 +49,8 @@ export const HANDLERS = {
|
|
|
48
49
|
return fail('Unknown storage action "' + action + '".', 'Use: sandbox storage, sandbox storage move <folder>, sandbox storage use <folder> or sandbox storage contained on|off|status');
|
|
49
50
|
},
|
|
50
51
|
engine: engine,
|
|
52
|
+
// The bare command shows the overview; its actions (add-engine, forget-engine, launcher) are the operations' hints.
|
|
53
|
+
unreal: definitionHandler(unrealOverview),
|
|
51
54
|
'host-claude': claudeHost,
|
|
52
55
|
host: hostCommand,
|
|
53
56
|
_watch: watcher,
|
package/dist/cli/manifest.d.ts
CHANGED
|
@@ -488,6 +488,24 @@ declare const COMMAND_LIST: readonly [{
|
|
|
488
488
|
shownAs?: string | undefined;
|
|
489
489
|
}];
|
|
490
490
|
readonly json: true;
|
|
491
|
+
}, {
|
|
492
|
+
readonly name: "unreal";
|
|
493
|
+
readonly summary: "Unreal Engine: the sandbox's engines, this PC's engines and assets, register an engine folder, open the launcher";
|
|
494
|
+
readonly group: "Projects & accounts";
|
|
495
|
+
readonly json: true;
|
|
496
|
+
readonly examples: readonly ["sandbox unreal engines, which project uses which, Visual Studio", "sandbox unreal add-engine D:\\UE5 use this engine folder in sandboxes (writable)", "sandbox unreal launcher open the Epic Games Launcher in the running sandbox"];
|
|
497
|
+
readonly args: readonly [{
|
|
498
|
+
readonly name: "action";
|
|
499
|
+
readonly description: "status, add-engine, forget-engine, launcher";
|
|
500
|
+
readonly required: false;
|
|
501
|
+
readonly choices: readonly ["status"];
|
|
502
|
+
}, {
|
|
503
|
+
readonly name: "folder";
|
|
504
|
+
readonly description: "(add-engine, forget-engine) the engine folder";
|
|
505
|
+
readonly required: false;
|
|
506
|
+
readonly when: readonly [];
|
|
507
|
+
}];
|
|
508
|
+
readonly options: readonly [];
|
|
491
509
|
}, {
|
|
492
510
|
readonly name: "engine";
|
|
493
511
|
readonly summary: "(beta) what runs your sandbox (Windows Sandbox or HCS) and what each engine can do on this PC";
|
package/dist/cli/manifest.js
CHANGED
|
@@ -381,6 +381,32 @@ const COMMAND_LIST = [
|
|
|
381
381
|
],
|
|
382
382
|
json,
|
|
383
383
|
},
|
|
384
|
+
{
|
|
385
|
+
name: 'unreal',
|
|
386
|
+
summary: "Unreal Engine: the sandbox's engines, this PC's engines and assets, register an engine folder, open the launcher",
|
|
387
|
+
group: 'Projects & accounts',
|
|
388
|
+
json,
|
|
389
|
+
examples: [
|
|
390
|
+
'sandbox unreal engines, which project uses which, Visual Studio',
|
|
391
|
+
'sandbox unreal add-engine D:\\UE5 use this engine folder in sandboxes (writable)',
|
|
392
|
+
'sandbox unreal launcher open the Epic Games Launcher in the running sandbox',
|
|
393
|
+
],
|
|
394
|
+
args: [
|
|
395
|
+
{
|
|
396
|
+
name: 'action',
|
|
397
|
+
description: 'status, add-engine, forget-engine, launcher',
|
|
398
|
+
required: false,
|
|
399
|
+
choices: ['status'],
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
name: 'folder',
|
|
403
|
+
description: '(add-engine, forget-engine) the engine folder',
|
|
404
|
+
required: false,
|
|
405
|
+
when: [],
|
|
406
|
+
},
|
|
407
|
+
],
|
|
408
|
+
options: [],
|
|
409
|
+
},
|
|
384
410
|
{
|
|
385
411
|
name: 'engine',
|
|
386
412
|
summary: '(beta) what runs your sandbox (Windows Sandbox or HCS) and what each engine can do on this PC',
|
|
@@ -12,6 +12,7 @@ export const COMMAND_PLACES = {
|
|
|
12
12
|
data: { place: 'Maintenance > Data' },
|
|
13
13
|
storage: { place: 'Maintenance > Storage' },
|
|
14
14
|
engine: { place: 'Maintenance > Engine' },
|
|
15
|
+
unreal: { place: 'Sandbox > Unreal Engine' },
|
|
15
16
|
sync: { place: 'Maintenance > More commands' },
|
|
16
17
|
logs: { place: 'Maintenance > Logs (key f follows)' },
|
|
17
18
|
setup: { place: 'Maintenance > Health' },
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ProjectsList } from '../../../app/features/projects/index.js';
|
|
2
2
|
import { type SandboxStatus } from '../../../app/features/sandbox/index.js';
|
|
3
|
+
import { type UnrealOverview } from '../../../app/features/unreal/index.js';
|
|
3
4
|
import type { Context } from '../../commands/context.js';
|
|
4
5
|
import { type DatabaseRow } from '../../services/index.js';
|
|
5
6
|
import { type App, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
@@ -11,6 +12,8 @@ export interface SandboxModel {
|
|
|
11
12
|
readonly databases: DatabaseRow[] | null;
|
|
12
13
|
/** The agent "Start the sandbox" offers while nothing runs. */
|
|
13
14
|
readonly defaultAgent: string;
|
|
15
|
+
/** The Unreal overview; null when it could not be read. */
|
|
16
|
+
readonly unreal: UnrealOverview | null;
|
|
14
17
|
}
|
|
15
18
|
/** The list for the sandbox tab. Pure. */
|
|
16
19
|
export declare function sandboxOptions(m: SandboxModel): ListOptions<string>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Section 3: the sandbox as a whole. Status (the sandbox view: its facts, the window, stopping it), Projects (the
|
|
2
|
-
// projects view: roots, the projects and the all-projects setting)
|
|
3
|
-
// the left.
|
|
2
|
+
// projects view: roots, the projects and the all-projects setting), Databases (start and stop) and Unreal Engine (the
|
|
3
|
+
// unreal view), each a category on the left.
|
|
4
4
|
import { listProjects, projectsPage } from '../../../app/features/projects/index.js';
|
|
5
5
|
import { sandboxPage, sandboxStatus } from '../../../app/features/sandbox/index.js';
|
|
6
6
|
import { readQuery } from '../../../app/registry.js';
|
|
7
|
+
import { unrealOverview, unrealPage } from '../../../app/features/unreal/index.js';
|
|
7
8
|
import { errMsg, safeText } from '../../../core/util/index.js';
|
|
8
9
|
import { RunDir } from '../../../shared/channel/index.js';
|
|
9
10
|
import { DatabasesService } from '../../services/index.js';
|
|
@@ -19,7 +20,18 @@ const CATEGORIES = [
|
|
|
19
20
|
description: 'Project roots (folders of projects, opened without a restart) and the projects started before.',
|
|
20
21
|
},
|
|
21
22
|
{ id: 'databases', label: 'Databases', description: 'Databases the sandbox can run: start and stop them.' },
|
|
23
|
+
{
|
|
24
|
+
id: 'unreal',
|
|
25
|
+
label: 'Unreal Engine',
|
|
26
|
+
description: "Engines, which project uses which, this PC's engines and assets, Visual Studio and the debugger.",
|
|
27
|
+
},
|
|
22
28
|
];
|
|
29
|
+
/** The Unreal category: the Unreal view's rows and keys (prefixed, so they never clash with other rows). */
|
|
30
|
+
function unrealMenu(m) {
|
|
31
|
+
return m.unreal
|
|
32
|
+
? menuView(unrealPage(m.unreal), { category: 'unreal', prefix: 'unreal:', refresh: false })
|
|
33
|
+
: undefined;
|
|
34
|
+
}
|
|
23
35
|
/** The status category: the sandbox view's rows (prefixed, so they never clash with the projects' rows). */
|
|
24
36
|
function statusView(m) {
|
|
25
37
|
return menuView(sandboxPage(m.report), { category: 'status', prefix: 'status:', refresh: false });
|
|
@@ -32,6 +44,8 @@ function projectsView(m) {
|
|
|
32
44
|
function viewFor(m, category) {
|
|
33
45
|
if (category === 'projects')
|
|
34
46
|
return projectsView(m);
|
|
47
|
+
if (category === 'unreal')
|
|
48
|
+
return unrealMenu(m);
|
|
35
49
|
if (category === 'status' || category === undefined)
|
|
36
50
|
return statusView(m);
|
|
37
51
|
return undefined;
|
|
@@ -64,16 +78,31 @@ export function sandboxOptions(m) {
|
|
|
64
78
|
section: 'Databases',
|
|
65
79
|
description: d.title + '. Enter ' + (d.running ? 'stops' : 'starts') + ' it (the first start downloads it).',
|
|
66
80
|
}));
|
|
81
|
+
const unreal = unrealMenu(m);
|
|
82
|
+
const noUnreal = unreal
|
|
83
|
+
? []
|
|
84
|
+
: [
|
|
85
|
+
{
|
|
86
|
+
value: 'info:unreal',
|
|
87
|
+
label: 'Could not read the Unreal set-up',
|
|
88
|
+
category: 'unreal',
|
|
89
|
+
section: 'Unreal Engine',
|
|
90
|
+
description: 'l looks again.',
|
|
91
|
+
disabled: 'l looks again.',
|
|
92
|
+
},
|
|
93
|
+
];
|
|
67
94
|
return {
|
|
68
95
|
path: [],
|
|
69
|
-
items: [...statusItems, ...projects.items, ...databases, ...noDatabases],
|
|
96
|
+
items: [...statusItems, ...projects.items, ...databases, ...noDatabases, ...(unreal?.items ?? []), ...noUnreal],
|
|
70
97
|
categories: CATEGORIES,
|
|
71
98
|
empty: 'Nothing here yet.',
|
|
72
99
|
actions: (category) => category === 'projects'
|
|
73
100
|
? [...projects.actions, REFRESH]
|
|
74
101
|
: category === 'databases'
|
|
75
102
|
? [REFRESH]
|
|
76
|
-
:
|
|
103
|
+
: category === 'unreal'
|
|
104
|
+
? [...(unreal?.actions ?? []), REFRESH]
|
|
105
|
+
: [...status.actions, REFRESH],
|
|
77
106
|
enterLabel: (category, id) => viewFor(m, category)?.enterLabel(category, id) || enterLabel(id ?? '', m),
|
|
78
107
|
};
|
|
79
108
|
}
|
|
@@ -133,6 +162,7 @@ export class SandboxPage extends ListPage {
|
|
|
133
162
|
projects: await readQuery(listProjects, this.ctx),
|
|
134
163
|
databases,
|
|
135
164
|
defaultAgent: this.defaultAgent(),
|
|
165
|
+
unreal: await readQuery(unrealOverview, this.ctx).catch(() => null),
|
|
136
166
|
};
|
|
137
167
|
}
|
|
138
168
|
/** The folder `sbx-db` runs in: the sandbox's own workspace. */
|
package/dist/cli/menu/views.js
CHANGED
|
@@ -19,6 +19,7 @@ import { webView } from '../../app/features/web/index.js';
|
|
|
19
19
|
import { vpnView } from '../../app/features/vpn/index.js';
|
|
20
20
|
import { githubView } from '../../app/features/github/index.js';
|
|
21
21
|
import { accessView } from '../../app/features/access/index.js';
|
|
22
|
+
import { unrealView } from '../../app/features/unreal/index.js';
|
|
22
23
|
export const MENU_VIEWS = [
|
|
23
24
|
{ view: agentsView, section: 'Agents' },
|
|
24
25
|
{ view: agentEnvView, section: 'Agents' },
|
|
@@ -28,6 +29,7 @@ export const MENU_VIEWS = [
|
|
|
28
29
|
{ view: accountsView, section: 'Accounts' },
|
|
29
30
|
{ view: appsView, section: 'Apps' },
|
|
30
31
|
{ view: projectsView, section: 'Sandbox' },
|
|
32
|
+
{ view: unrealView, section: 'Sandbox' },
|
|
31
33
|
{ view: healthView, section: 'Maintenance' },
|
|
32
34
|
{ view: dataView, section: 'Maintenance' },
|
|
33
35
|
{ view: storageView, section: 'Maintenance' },
|
|
@@ -58,7 +58,14 @@ export const DEFAULTS = {
|
|
|
58
58
|
perplexity: { share: false },
|
|
59
59
|
comet: { share: false },
|
|
60
60
|
},
|
|
61
|
-
pcInstalls: {
|
|
61
|
+
pcInstalls: {
|
|
62
|
+
steamGames: false,
|
|
63
|
+
epicGames: false,
|
|
64
|
+
unrealEngines: 'auto',
|
|
65
|
+
unrealEngineFolders: [],
|
|
66
|
+
unrealAssets: 'auto',
|
|
67
|
+
unityEditors: false,
|
|
68
|
+
},
|
|
62
69
|
provisioning: {
|
|
63
70
|
copyFromHost: true,
|
|
64
71
|
fallbackToInstall: true,
|
|
@@ -196,9 +203,16 @@ export const DEFAULTS = {
|
|
|
196
203
|
home: { env: { CODEX_HOME: 'codex' }, loginFiles: ['auth.json', '.credentials.json'], hostDir: '~/.codex' },
|
|
197
204
|
localState: { CODEX_SQLITE_HOME: 'sqlite' },
|
|
198
205
|
// Its own command sandbox keeps local users' passwords sealed with DPAPI: unreadable in the next sandbox
|
|
199
|
-
// ("CryptUnprotectData" on every command), so it sets that sandbox up again at each boot. tmp\arg0
|
|
200
|
-
// Codex cannot remove in a mapped folder (os error 145, a warning at
|
|
201
|
-
|
|
206
|
+
// ("CryptUnprotectData" on every command), so it sets that sandbox up again at each boot. tmp\arg0 and
|
|
207
|
+
// tmp\arg0-windows (newer Codex): folders Codex cannot remove in a mapped folder (os error 145, a warning at
|
|
208
|
+
// every start); nothing holds them at boot.
|
|
209
|
+
bootReset: [
|
|
210
|
+
'.sandbox-secrets',
|
|
211
|
+
'.sandbox\\setup_marker.json',
|
|
212
|
+
'.sandbox\\deny_read_acl_state.json',
|
|
213
|
+
'tmp\\arg0',
|
|
214
|
+
'tmp\\arg0-windows',
|
|
215
|
+
],
|
|
202
216
|
resumeArguments: ['resume', '--last'],
|
|
203
217
|
},
|
|
204
218
|
gemini: {
|
|
@@ -131,7 +131,9 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
131
131
|
pcInstalls: z.ZodObject<{
|
|
132
132
|
steamGames: z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodNumber>]>;
|
|
133
133
|
epicGames: z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>;
|
|
134
|
-
unrealEngines: z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>;
|
|
134
|
+
unrealEngines: z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodBoolean, z.ZodArray<z.ZodString>]>;
|
|
135
|
+
unrealEngineFolders: z.ZodArray<z.ZodString>;
|
|
136
|
+
unrealAssets: z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodBoolean]>;
|
|
135
137
|
unityEditors: z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>;
|
|
136
138
|
}, z.core.$strict>;
|
|
137
139
|
provisioning: z.ZodObject<{
|
|
@@ -689,7 +691,7 @@ export declare const LocalOverridesSchema: z.ZodObject<{
|
|
|
689
691
|
zstd: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
690
692
|
openssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
691
693
|
}, z.core.$strict>>;
|
|
692
|
-
|
|
694
|
+
node: z.ZodOptional<z.ZodObject<{
|
|
693
695
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
694
696
|
}, z.core.$strict> | z.ZodObject<{
|
|
695
697
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -704,7 +706,7 @@ export declare const LocalOverridesSchema: z.ZodObject<{
|
|
|
704
706
|
zstd: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
705
707
|
openssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
706
708
|
}, z.core.$strict>>;
|
|
707
|
-
|
|
709
|
+
go: z.ZodOptional<z.ZodObject<{
|
|
708
710
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
709
711
|
}, z.core.$strict> | z.ZodObject<{
|
|
710
712
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -719,7 +721,7 @@ export declare const LocalOverridesSchema: z.ZodObject<{
|
|
|
719
721
|
zstd: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
720
722
|
openssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
721
723
|
}, z.core.$strict>>;
|
|
722
|
-
|
|
724
|
+
python: z.ZodOptional<z.ZodObject<{
|
|
723
725
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
724
726
|
}, z.core.$strict> | z.ZodObject<{
|
|
725
727
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -734,7 +736,7 @@ export declare const LocalOverridesSchema: z.ZodObject<{
|
|
|
734
736
|
zstd: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
735
737
|
openssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
736
738
|
}, z.core.$strict>>;
|
|
737
|
-
|
|
739
|
+
rust: z.ZodOptional<z.ZodObject<{
|
|
738
740
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
739
741
|
}, z.core.$strict> | z.ZodObject<{
|
|
740
742
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -749,7 +751,7 @@ export declare const LocalOverridesSchema: z.ZodObject<{
|
|
|
749
751
|
zstd: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
750
752
|
openssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
751
753
|
}, z.core.$strict>>;
|
|
752
|
-
|
|
754
|
+
msvc: z.ZodOptional<z.ZodObject<{
|
|
753
755
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
754
756
|
}, z.core.$strict> | z.ZodObject<{
|
|
755
757
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -764,7 +766,7 @@ export declare const LocalOverridesSchema: z.ZodObject<{
|
|
|
764
766
|
zstd: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
765
767
|
openssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>>;
|
|
766
768
|
}, z.core.$strict>>;
|
|
767
|
-
|
|
769
|
+
unreal: z.ZodOptional<z.ZodObject<{
|
|
768
770
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
769
771
|
}, z.core.$strict> | z.ZodObject<{
|
|
770
772
|
version: z.ZodOptional<z.ZodString>;
|
|
@@ -2,6 +2,8 @@ import { z } from 'zod';
|
|
|
2
2
|
export declare const PcInstallsSchema: z.ZodObject<{
|
|
3
3
|
steamGames: z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodNumber>]>;
|
|
4
4
|
epicGames: z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>;
|
|
5
|
-
unrealEngines: z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>;
|
|
5
|
+
unrealEngines: z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodBoolean, z.ZodArray<z.ZodString>]>;
|
|
6
|
+
unrealEngineFolders: z.ZodArray<z.ZodString>;
|
|
7
|
+
unrealAssets: z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodBoolean]>;
|
|
6
8
|
unityEditors: z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>;
|
|
7
9
|
}, z.core.$strict>;
|
|
@@ -11,7 +11,16 @@ export const PcInstallsSchema = z
|
|
|
11
11
|
.strictObject({
|
|
12
12
|
steamGames: pick(z.number().int().positive(), 'Steam games (true maps each library; a list of app IDs maps only those games)', '[480, 730]'),
|
|
13
13
|
epicGames: pick(z.string().regex(/^[A-Za-z0-9._-]{1,100}$/), 'Epic Games Launcher games (by their app name)', '["Fortnite"]'),
|
|
14
|
-
unrealEngines:
|
|
14
|
+
unrealEngines: z
|
|
15
|
+
.union([z.literal('auto'), z.boolean(), z.array(z.string().regex(/^(UE_)?\d+\.\d+$/))])
|
|
16
|
+
.describe('Unreal Engine versions installed on this PC (with the Epic Games Launcher, or source builds it lists), read-only in the sandbox under C:\\PcInstalls\\unreal and registered there, so projects build with them without a download. "auto" = all of them whenever the sandbox is set up for Unreal, true = always, false = never, or a list (e.g. ["5.4"]).'),
|
|
17
|
+
unrealEngineFolders: z
|
|
18
|
+
.array(z.string().min(3).max(260))
|
|
19
|
+
.max(8)
|
|
20
|
+
.describe('Unreal Engine folders of this PC to use in the sandbox, writable (a source build, or a copy you build plugins into): each must hold Engine\\Build\\Build.version. Mapped under C:\\PcInstalls\\unreal and registered there.'),
|
|
21
|
+
unrealAssets: z
|
|
22
|
+
.union([z.literal('auto'), z.boolean()])
|
|
23
|
+
.describe('The Epic Games Launcher\'s vault cache of this PC (the Fab and Marketplace packs you downloaded), read-only in the sandbox at C:\\PcInstalls\\unreal\\Vault: what you download on your PC is there for the agents at once. "auto" = whenever the sandbox is set up for Unreal, true = always, false = never.'),
|
|
15
24
|
unityEditors: pick(z.string().regex(/^\d+\.\d+\.\d+[abfp]\d+$/), 'Unity editors installed with Unity Hub', '["6000.0.32f1"]'),
|
|
16
25
|
})
|
|
17
26
|
.describe("Games, engines and editors installed on this PC, mapped read-only into sandboxes (no copy, no room on the sandbox's disk).");
|
|
@@ -40,7 +40,7 @@ export const ToolchainsSchema = z.strictObject({
|
|
|
40
40
|
.describe('"auto" (default): on the sandbox\'s own disk when C: has 25 GB free at boot, else "separate" (builds then write through the mapped workspace, which can overload this PC\'s disk). "shared": cargo\'s default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox\'s own disk (fastest, lost every boot), or a guest path.'),
|
|
41
41
|
linker: z
|
|
42
42
|
.enum(['lld', 'gnu'])
|
|
43
|
-
.describe('
|
|
43
|
+
.describe('"lld" (default) links with Rust\'s own lld: through MinGW\'s gcc on the GNU host (much less memory than GNU ld), and instead of link.exe on the MSVC host (link.exe writes executables into mapped folders as all zeros: os error 1392). "gnu" keeps GNU ld / link.exe.'),
|
|
44
44
|
linkSlots: z
|
|
45
45
|
.union([z.literal('auto'), z.number().int().min(1).max(32)])
|
|
46
46
|
.describe('GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 6 GB of sandbox memory, 1 to 4 (the memory governor slows links down too when memory runs short).'),
|
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
// Epic Games: the handed-over sign-in goes into the launcher's GameUserSettings.ini before anyone opens it (its other
|
|
2
|
-
// settings are kept, and the file keeps the encoding it had: the launcher often writes UTF-16).
|
|
3
|
-
//
|
|
2
|
+
// settings are kept, and the file keeps the encoding it had: the launcher often writes UTF-16). Launcher 17+ reads
|
|
3
|
+
// Config\WindowsEditor, older ones Config\Windows: both get it. The watch reads it back to notice when the launcher
|
|
4
|
+
// renews it, or when you sign in here the first time.
|
|
4
5
|
import fs from 'node:fs';
|
|
5
6
|
import path from 'node:path';
|
|
6
|
-
import {
|
|
7
|
+
import { epicSettingsFiles, MAX_EPIC_INI_BYTES, readEpicLogin, withEpicLogin, } from '../../../shared/accounts/index.js';
|
|
7
8
|
import { decodeText, encodeText, readBoundedFile } from '../../../shared/io/index.js';
|
|
8
9
|
import { localAppData } from '../adapter.js';
|
|
9
|
-
function settingsFile() {
|
|
10
|
-
return epicSettingsFile(localAppData());
|
|
11
|
-
}
|
|
12
10
|
export const epicAdapter = {
|
|
13
11
|
kind: 'epic',
|
|
14
12
|
apply(p) {
|
|
15
|
-
const file
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
for (const file of epicSettingsFiles(localAppData())) {
|
|
14
|
+
const bytes = readBoundedFile(file, MAX_EPIC_INI_BYTES);
|
|
15
|
+
const read = bytes ? decodeText(bytes) : { text: '', encoding: 'utf8' };
|
|
16
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
17
|
+
fs.writeFileSync(file, encodeText(withEpicLogin(read.text, p), read.encoding));
|
|
18
|
+
}
|
|
20
19
|
return { summary: 'Epic Games Launcher: signed in with your saved sign-in' };
|
|
21
20
|
},
|
|
22
21
|
current() {
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// The newest place first: the one the launcher in this sandbox writes when it renews the sign-in.
|
|
23
|
+
for (const file of epicSettingsFiles(localAppData())) {
|
|
24
|
+
const bytes = readBoundedFile(file, MAX_EPIC_INI_BYTES);
|
|
25
|
+
const login = bytes ? readEpicLogin(decodeText(bytes).text) : null;
|
|
26
|
+
if (login)
|
|
27
|
+
return login;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
25
30
|
},
|
|
26
31
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AppEntry } from '../../shared/apps/index.js';
|
|
2
2
|
/** Settings an app needs on every boot (the sandbox's registry is new each time), and files next to its program. */
|
|
3
3
|
export declare function afterInstall(entry: AppEntry, exe: string): Promise<void>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { associationPlan } from '../../shared/apps/index.js';
|
|
3
4
|
import { SYSTEM } from '../../shared/system.js';
|
|
4
5
|
import { errMsg } from '../../core/util/errors.js';
|
|
5
6
|
import { takePendingComet } from '../accounts/kinds/comet.js';
|
|
6
7
|
import { restoreCometSignIn } from '../browser/comet.js';
|
|
7
8
|
import { log, warn } from '../runtime/log.js';
|
|
8
|
-
import { execAsync } from '../runtime/process.js';
|
|
9
|
+
import { execAsync, runScriptWithJsonAsync } from '../runtime/process.js';
|
|
9
10
|
import { exists, mkdirp } from '../runtime/fs.js';
|
|
10
11
|
import { arch, tool } from '../toolchains/tool-env.js';
|
|
11
12
|
/** The Sysinternals tools whose EULA is accepted up front (each asks once otherwise). */
|
|
@@ -58,6 +59,10 @@ export async function afterInstall(entry, exe) {
|
|
|
58
59
|
mkdirp(path.join(dir, 'Data'));
|
|
59
60
|
if (entry.id === 'comet')
|
|
60
61
|
await restoreComet(exe);
|
|
62
|
+
const plan = associationPlan(entry.id, exe);
|
|
63
|
+
if (plan.length) {
|
|
64
|
+
await runScriptWithJsonAsync('set-registry-values.ps1', 'PlanFile', { values: plan }).catch((e) => warn(entry.name + ': double-click file types were not set (' + errMsg(e) + ')'));
|
|
65
|
+
}
|
|
61
66
|
if (entry.id === 'sysinternals') {
|
|
62
67
|
for (const name of SYSINTERNALS_TOOLS) {
|
|
63
68
|
await execAsync(SYSTEM.reg(), ['add', 'HKCU\\Software\\Sysinternals\\' + name, '/v', 'EulaAccepted', '/t', 'REG_DWORD', '/d', '1', '/f'], { stdio: 'ignore' }).catch(() => undefined);
|
|
@@ -13,6 +13,7 @@ export declare class AppInstaller {
|
|
|
13
13
|
private readonly parallel;
|
|
14
14
|
private readonly gui;
|
|
15
15
|
private readonly installed;
|
|
16
|
+
private readonly installedIds;
|
|
16
17
|
constructor(env: ToolEnv, options: AppsOptions, parallel?: number);
|
|
17
18
|
/**
|
|
18
19
|
* Downloads the plain downloads (not pinned, not npm, not remote) of the apps that are not installed yet, into
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// failing is reported and never stops the others.
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import { appsToInstall } from '../../shared/apps/index.js';
|
|
5
|
+
import { appsToInstall, previewGuideLine } from '../../shared/apps/index.js';
|
|
6
6
|
import { downloader, moveIntoPlace, stagingFolder } from '../../shared/download/index.js';
|
|
7
7
|
import { safeRemove } from '../../shared/io/safe-remove.js';
|
|
8
8
|
import { dryRun, launchDir } from '../runtime/paths.js';
|
|
@@ -33,6 +33,7 @@ export class AppInstaller {
|
|
|
33
33
|
parallel;
|
|
34
34
|
gui = [];
|
|
35
35
|
installed = [];
|
|
36
|
+
installedIds = [];
|
|
36
37
|
constructor(env, options, parallel = PARALLEL) {
|
|
37
38
|
this.env = env;
|
|
38
39
|
this.options = options;
|
|
@@ -82,6 +83,9 @@ export class AppInstaller {
|
|
|
82
83
|
}
|
|
83
84
|
if (this.installed.length)
|
|
84
85
|
this.env.summary.push('apps: ' + this.installed.join(', ') + ' (shortcuts on the desktop and in Start > Sandbox apps)');
|
|
86
|
+
const preview = previewGuideLine(this.installedIds);
|
|
87
|
+
if (preview)
|
|
88
|
+
this.env.summary.push(preview);
|
|
85
89
|
}
|
|
86
90
|
async installOne(entry) {
|
|
87
91
|
try {
|
|
@@ -102,11 +106,17 @@ export class AppInstaller {
|
|
|
102
106
|
throw new Error(entry.exe + ' not found in the download');
|
|
103
107
|
await afterInstall(entry, exe);
|
|
104
108
|
// A proxy or MCP server (agent add-ons) is started by the sandbox or the agent: no PATH entry, no shortcut.
|
|
105
|
-
if (!entry.service && (entry.cli || entry.id === 'sysinternals'))
|
|
106
|
-
|
|
109
|
+
if (!entry.service && (entry.cli || entry.id === 'sysinternals')) {
|
|
110
|
+
// rustup's rust-analyzer proxy (in cargo's bin folder) only errors until its component is added.
|
|
111
|
+
if (entry.id === 'rust-analyzer')
|
|
112
|
+
this.env.prepend.unshift(path.dirname(exe));
|
|
113
|
+
else
|
|
114
|
+
this.env.prepend.push(path.dirname(exe));
|
|
115
|
+
}
|
|
107
116
|
if (!entry.cli && !entry.service)
|
|
108
117
|
this.gui.push({ name: entry.name, exe, ...this.launchArgs(entry) });
|
|
109
118
|
this.installed.push(entry.name);
|
|
119
|
+
this.installedIds.push(entry.id);
|
|
110
120
|
}
|
|
111
121
|
catch (e) {
|
|
112
122
|
warn(entry.name + ' could not be installed and is skipped; the other apps are not affected. Reason: ' + errMsg(e));
|
|
@@ -15,10 +15,11 @@ const INNER = [
|
|
|
15
15
|
/^chrome\.7z$/i,
|
|
16
16
|
/^chrome\.packed\.7z$/i,
|
|
17
17
|
/^mini_installer\.exe$/i,
|
|
18
|
-
/^updater\.packed\.7z$/i,
|
|
18
|
+
/^updater\.(packed\.)?7z$/i,
|
|
19
19
|
];
|
|
20
20
|
const MAX_LEVELS = 6;
|
|
21
|
-
|
|
21
|
+
/** Comet's installer nests mini_installer.exe five folders down (bin\Offline\{id}\{id}). */
|
|
22
|
+
const MAX_DEPTH = 7;
|
|
22
23
|
const MAX_ENTRIES = 20000;
|
|
23
24
|
/** Where the installer is kept when it could not be unpacked (below the app's folder). */
|
|
24
25
|
export const KEPT_INSTALLER_DIR = 'installer';
|