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
|
@@ -8,7 +8,7 @@ import { assertSafeMapping } from '../core/safe-paths.js';
|
|
|
8
8
|
import { safeText } from '../core/util/index.js';
|
|
9
9
|
import { isSafeFileName } from '../shared/paths/index.js';
|
|
10
10
|
import { removeRefusal, safeRemove } from '../shared/io/index.js';
|
|
11
|
-
import { writeJsonAtomic } from '../shared/io/index.js';
|
|
11
|
+
import { rotateLog, writeJsonAtomic } from '../shared/io/index.js';
|
|
12
12
|
export const hostileInputSuite = {
|
|
13
13
|
name: 'hostile-input',
|
|
14
14
|
title: 'file names, deletes, printed text, mappings and state files from an untrusted sandbox',
|
|
@@ -63,5 +63,15 @@ export const hostileInputSuite = {
|
|
|
63
63
|
fs.writeFileSync(path.join(repoDir, '.sandbox-config.json'), '{"readOnly": true}' + ' '.repeat(1100 * 1024));
|
|
64
64
|
await t.throws(() => f.run({ cwd: repoDir, trustConfig: true }), 'over 1 MB', 'a .sandbox-config.json over 1 MB is refused before it is parsed');
|
|
65
65
|
fs.rmSync(path.join(repoDir, '.sandbox-config.json'));
|
|
66
|
+
t.section('a log that grows for ever (Headroom appends to one on the data disk)');
|
|
67
|
+
const logFile = t.at('rotate', 'proxy.log');
|
|
68
|
+
fs.mkdirSync(path.dirname(logFile), { recursive: true });
|
|
69
|
+
t.check(!rotateLog(logFile, 10), 'no log yet: nothing to rotate');
|
|
70
|
+
fs.writeFileSync(logFile, 'x'.repeat(10));
|
|
71
|
+
t.check(!rotateLog(logFile, 10) && fs.existsSync(logFile), 'a log at the limit stays');
|
|
72
|
+
fs.writeFileSync(logFile + '.1', 'old');
|
|
73
|
+
fs.writeFileSync(logFile, 'y'.repeat(11));
|
|
74
|
+
t.check(rotateLog(logFile, 10), 'a log over the limit is rotated');
|
|
75
|
+
t.check(!fs.existsSync(logFile) && fs.readFileSync(logFile + '.1', 'utf8') === 'y'.repeat(11), 'it replaces the older copy');
|
|
66
76
|
},
|
|
67
77
|
};
|
package/dist/selftest/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { persistedInstallsSuite } from './persisted-installs.test.js';
|
|
|
16
16
|
import { pcInstallsSuite } from './pc-installs.test.js';
|
|
17
17
|
import { steamSuite } from './steam.test.js';
|
|
18
18
|
import { enginesSuite } from './engines.test.js';
|
|
19
|
+
import { mixamoSuite } from './mixamo.test.js';
|
|
19
20
|
import { unitySuite } from './unity.test.js';
|
|
20
21
|
import { fivemSuite } from './fivem.test.js';
|
|
21
22
|
import { androidSuite } from './android.test.js';
|
|
@@ -139,6 +140,7 @@ export const SUITES = [
|
|
|
139
140
|
persistedInstallsSuite,
|
|
140
141
|
steamSuite,
|
|
141
142
|
enginesSuite,
|
|
143
|
+
mixamoSuite,
|
|
142
144
|
unitySuite,
|
|
143
145
|
fivemSuite,
|
|
144
146
|
androidSuite,
|
|
@@ -10,6 +10,7 @@ import { appsOptions, stageTicks } from '../cli/menu/pages/apps-page.js';
|
|
|
10
10
|
import { maintenanceOptions } from '../cli/menu/pages/maintenance-page.js';
|
|
11
11
|
import { sandboxOptions } from '../cli/menu/pages/sandbox-page.js';
|
|
12
12
|
import { sessionsOptions } from '../cli/menu/pages/sessions-page.js';
|
|
13
|
+
import { UNREAL_SAMPLE } from './support/unreal-sample.js';
|
|
13
14
|
import { settingsOf, settingsOptions } from '../cli/menu/pages/settings-page.js';
|
|
14
15
|
import { CATEGORIES } from '../app/features/settings/index.js';
|
|
15
16
|
import { agentsOptions } from '../cli/menu/pages/agents-page.js';
|
|
@@ -199,6 +200,7 @@ export function renderScreens(dir) {
|
|
|
199
200
|
{ name: 'redis', running: false, port: 6379, title: 'Redis' },
|
|
200
201
|
],
|
|
201
202
|
defaultAgent: 'claude',
|
|
203
|
+
unreal: UNREAL_SAMPLE,
|
|
202
204
|
};
|
|
203
205
|
const stopped = {
|
|
204
206
|
...sandbox,
|
|
@@ -399,7 +401,7 @@ export function renderScreens(dir) {
|
|
|
399
401
|
out.push(block('1 Agents · Start', draw(0, { ...agentsOptions(agentsModel, API_FOLDER), startCategory: 'start' }, size, status), size), block('1 Agents · Options (navigation focused)', draw(0, { ...agentsOptions(agentsModel, API_FOLDER), startCategory: 'options' }, size, status, 0, true), size), block('1 Agents · On this PC', draw(0, { ...agentsOptions(agentsModel, API_FOLDER), startCategory: 'host' }, size, status), size), block('2 Sessions', draw(1, sessionsOptions({ sandboxRunning: true, sessions: SESSIONS, defaultAgent: 'claude' }), size, status), size), block('2 Sessions (no sandbox)', draw(1, sessionsOptions({ sandboxRunning: false, sessions: [], defaultAgent: 'claude' }), size), size));
|
|
400
402
|
for (const category of ['status', 'databases'])
|
|
401
403
|
out.push(block('3 Sandbox (stopped) · ' + category, draw(2, { ...sandboxOptions(stopped), startCategory: category }, size), size));
|
|
402
|
-
for (const category of ['status', 'projects', 'databases'])
|
|
404
|
+
for (const category of ['status', 'projects', 'databases', 'unreal'])
|
|
403
405
|
out.push(block('3 Sandbox · ' + category, draw(2, { ...sandboxOptions(sandbox), startCategory: category }, size, status), size));
|
|
404
406
|
out.push(block('4 Apps (1 unsaved)', draw(3, appsOptions(user, appsData, appsDraft, 'user'), size, status, appsDraft.count()), size));
|
|
405
407
|
for (const category of CATEGORIES)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Mixamo: the browser policy table (downloads folder, no GPU) and the guide's Mixamo lines and editor names.
|
|
2
|
+
import { browserPolicies } from '../shared/browser-policy.js';
|
|
3
|
+
import { unrealGuideLines } from '../shared/unreal/guide.js';
|
|
4
|
+
const DOWNLOADS = 'C:\\AgentData\\downloads';
|
|
5
|
+
const PROJECT = { workspace: 'C:\\P\\Game', uproject: 'C:\\P\\Game\\Game.uproject' };
|
|
6
|
+
function statusWith(version) {
|
|
7
|
+
return {
|
|
8
|
+
updatedAt: 'now',
|
|
9
|
+
engines: [
|
|
10
|
+
{
|
|
11
|
+
id: 'UE_' + version,
|
|
12
|
+
dir: 'C:\\E',
|
|
13
|
+
version,
|
|
14
|
+
build: 'installed',
|
|
15
|
+
origin: 'pc',
|
|
16
|
+
writable: true,
|
|
17
|
+
sizeBytes: null,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
projects: [{ workspace: PROJECT.workspace, engine: 'C:\\E', reason: 'test' }],
|
|
21
|
+
launcher: { installed: false, installLocation: null, problem: null, freeBytes: null, needBytes: 1 },
|
|
22
|
+
visualStudio: { version: '17.14', path: 'C:/VS', how: 'kept', check: 'ok', ok: true },
|
|
23
|
+
debugger: null,
|
|
24
|
+
ddc: { mode: 'persisted', dir: null },
|
|
25
|
+
vaults: [],
|
|
26
|
+
mcpUrl: null,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export const mixamoSuite = {
|
|
30
|
+
name: 'mixamo',
|
|
31
|
+
title: 'Mixamo: browser downloads folder and the guide lines for bringing characters into Unreal',
|
|
32
|
+
run: async (t) => {
|
|
33
|
+
t.section('browser policies');
|
|
34
|
+
const four = browserPolicies({ downloads: DOWNLOADS });
|
|
35
|
+
t.equal(four.length, 4, 'two browsers, two policies each');
|
|
36
|
+
t.equal(four.filter((p) => p.name === 'DefaultDownloadDirectory').map((p) => p.data), [DOWNLOADS, DOWNLOADS], 'both browsers download to the data disk');
|
|
37
|
+
t.equal(browserPolicies({ downloads: null }).length, 2, 'no folder: only the GPU policy');
|
|
38
|
+
await t.throws(() => browserPolicies({ downloads: 'C:\\a"b' }), 'not a folder', 'a quote in the folder is refused');
|
|
39
|
+
await t.throws(() => browserPolicies({ downloads: 'downloads' }), 'not a folder', 'a relative folder is refused');
|
|
40
|
+
t.section('the guide');
|
|
41
|
+
const on = { mixamo: { downloads: DOWNLOADS, script: null } };
|
|
42
|
+
const guide = unrealGuideLines(statusWith('5.4.4'), [PROJECT], on).join('\n');
|
|
43
|
+
t.includes(guide, 'https://www.mixamo.com', 'the Mixamo line is there');
|
|
44
|
+
t.includes(guide, DOWNLOADS, 'it names the downloads folder');
|
|
45
|
+
t.includes(guide, 'Mixamo into Unreal', 'and the import line');
|
|
46
|
+
t.excludes(guide, 'Mixamo import script', 'no script line without a script');
|
|
47
|
+
const withScript = unrealGuideLines(statusWith('5.4.4'), [PROJECT], {
|
|
48
|
+
mixamo: { downloads: DOWNLOADS, script: 'C:\\x\\import_mixamo.py' },
|
|
49
|
+
}).join('\n');
|
|
50
|
+
t.includes(withScript, 'Mixamo import script', 'a script adds its line');
|
|
51
|
+
t.excludes(unrealGuideLines(statusWith('5.4.4'), [PROJECT]).join('\n'), 'Mixamo', 'off by default');
|
|
52
|
+
const noEngine = { ...statusWith('5.4.4'), engines: [] };
|
|
53
|
+
t.excludes(unrealGuideLines(noEngine, [PROJECT], on).join('\n'), 'Mixamo', 'no engine: no Mixamo lines');
|
|
54
|
+
t.section('UE4 names');
|
|
55
|
+
const ue4 = unrealGuideLines(statusWith('4.27.2'), [PROJECT]).join('\n');
|
|
56
|
+
t.includes(ue4, 'UE4Editor-Cmd.exe', 'a UE4 engine uses UE4Editor-Cmd.exe');
|
|
57
|
+
t.excludes(ue4, 'UnrealEditor', 'and not the UE5 names');
|
|
58
|
+
t.includes(unrealGuideLines(statusWith('5.4.4'), [PROJECT]).join('\n'), 'UnrealEditor-Cmd.exe', 'UE5 keeps its names');
|
|
59
|
+
},
|
|
60
|
+
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// What reaches the sandbox from this PC's Claude files, and what is stripped first: API keys, cloud credentials, tokens
|
|
2
2
|
// in MCP server definitions. Also the secret-looking files in a workspace that the launch warns about.
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import { DEFAULTS } from '../core/config/index.js';
|
|
6
|
+
import { findSecretFiles, pluginFilter, pluginTrimLevel, sandboxGlobalState, stageClaudeProfile, stripMcpServers, stripSettings, } from '../host/profile/index.js';
|
|
5
7
|
const REMOVED = '[removed by agent-sandbox]';
|
|
6
8
|
export const secretsSuite = {
|
|
7
9
|
name: 'secrets',
|
|
@@ -111,5 +113,38 @@ export const secretsSuite = {
|
|
|
111
113
|
])
|
|
112
114
|
t.write(path.join(workspace, file), 'x');
|
|
113
115
|
t.equal(findSecretFiles(workspace).sort(), ['.env', 'api\\credentials.json', 'server.pem'], 'secret-looking workspace files are found for the launch warning (templates and dependencies ignored)');
|
|
116
|
+
t.section('plugins staged from this PC');
|
|
117
|
+
const hostClaude = t.at('plugins-host');
|
|
118
|
+
const plugins = path.join(hostClaude, 'plugins');
|
|
119
|
+
t.write(path.join(plugins, 'installed_plugins.json'), '{"version":2,"plugins":{}}');
|
|
120
|
+
t.write(path.join(plugins, 'known_marketplaces.json'), '{}');
|
|
121
|
+
t.write(path.join(plugins, 'cache', 'm', 'p', '1.0', 'plugin.json'), '{}');
|
|
122
|
+
t.write(path.join(plugins, 'cache', 'm', 'p', '1.0', 'node_modules', 'dep', 'index.js'), 'x');
|
|
123
|
+
t.write(path.join(plugins, 'cache', 'temp_git_1_abc', 'junk.txt'), 'x');
|
|
124
|
+
t.write(path.join(plugins, 'marketplaces', 'm', 'marketplace.json'), '{}');
|
|
125
|
+
t.write(path.join(plugins, 'marketplaces', 'm', '.git', 'HEAD'), 'ref');
|
|
126
|
+
t.write(path.join(plugins, 'marketplaces', 'm.backup', 'old.txt'), 'x');
|
|
127
|
+
t.write(path.join(plugins, 'marketplaces', 'temp_subdir_2.clone', 'junk.txt'), 'x');
|
|
128
|
+
t.write(path.join(hostClaude, 'settings.json'), '{"enabledPlugins":{"p@m":true}}');
|
|
129
|
+
const launch = t.at('plugins-launch');
|
|
130
|
+
const profile = { ...DEFAULTS.claudeProfile, hostDir: hostClaude, globalStateFile: '' };
|
|
131
|
+
const staged = stageClaudeProfile(profile, launch, 'D:/Code/app', DEFAULTS.secrets);
|
|
132
|
+
const out = path.join(launch, 'claude-profile', 'plugins');
|
|
133
|
+
t.check(staged.staged.includes('plugins'), 'plugins are staged');
|
|
134
|
+
t.check(fs.existsSync(path.join(out, 'cache', 'm', 'p', '1.0', 'plugin.json')) &&
|
|
135
|
+
fs.existsSync(path.join(out, 'marketplaces', 'm', 'marketplace.json')) &&
|
|
136
|
+
fs.existsSync(path.join(out, 'marketplaces', 'm', '.git', 'HEAD')) &&
|
|
137
|
+
fs.existsSync(path.join(out, 'cache', 'm', 'p', '1.0', 'node_modules', 'dep', 'index.js')), 'the plugin cache, marketplaces and (when they fit) their git folders and dependencies are copied');
|
|
138
|
+
t.check(!fs.existsSync(path.join(out, 'cache', 'temp_git_1_abc')) &&
|
|
139
|
+
!fs.existsSync(path.join(out, 'marketplaces', 'm.backup')) &&
|
|
140
|
+
!fs.existsSync(path.join(out, 'marketplaces', 'temp_subdir_2.clone')), 'interrupted clones, backups and staging folders of plugins are left out');
|
|
141
|
+
t.check(pluginTrimLevel(plugins) === 0, 'a plugins folder under the cap is not trimmed');
|
|
142
|
+
const git = path.join(plugins, 'marketplaces', 'm', '.git');
|
|
143
|
+
const deps = path.join(plugins, 'cache', 'm', 'p', '1.0', 'node_modules');
|
|
144
|
+
t.check(pluginFilter(plugins, 0)(git) &&
|
|
145
|
+
!pluginFilter(plugins, 1)(git) &&
|
|
146
|
+
pluginFilter(plugins, 1)(deps) &&
|
|
147
|
+
!pluginFilter(plugins, 2)(deps), 'a plugins folder over the cap loses git history first, then node_modules');
|
|
148
|
+
t.check(fs.readFileSync(path.join(launch, 'claude-profile', 'settings.json'), 'utf8').includes('p@m'), 'enabledPlugins reach the sandbox');
|
|
114
149
|
},
|
|
115
150
|
};
|
|
@@ -69,6 +69,7 @@ export const LAUNCH_FILES_GOLDEN = [
|
|
|
69
69
|
'sandbox/csharp/SandboxTools/MemoryLog.cs',
|
|
70
70
|
'sandbox/csharp/SandboxTools/PageFile.cs',
|
|
71
71
|
'sandbox/csharp/SandboxTools/Program.cs',
|
|
72
|
+
'sandbox/csharp/VsSetup.cs',
|
|
72
73
|
'sandbox/csharp/VsWhere.cs',
|
|
73
74
|
'sandbox/csharp/VtInput.cs',
|
|
74
75
|
'sandbox/scripts/add-firewall-port.ps1',
|
|
@@ -76,6 +77,7 @@ export const LAUNCH_FILES_GOLDEN = [
|
|
|
76
77
|
'sandbox/scripts/expand-archive.ps1',
|
|
77
78
|
'sandbox/scripts/get-gpu-names.ps1',
|
|
78
79
|
'sandbox/scripts/get-signature.ps1',
|
|
80
|
+
'sandbox/scripts/get-vs-setup.ps1',
|
|
79
81
|
'sandbox/scripts/install-shell-path.ps1',
|
|
80
82
|
'sandbox/scripts/link-profile-dirs.ps1',
|
|
81
83
|
'sandbox/scripts/new-shortcuts.ps1',
|
|
@@ -85,6 +87,7 @@ export const LAUNCH_FILES_GOLDEN = [
|
|
|
85
87
|
'sandbox/scripts/set-desktop.ps1',
|
|
86
88
|
'sandbox/scripts/set-dns-servers.ps1',
|
|
87
89
|
'sandbox/scripts/set-machine-environment.ps1',
|
|
90
|
+
'sandbox/scripts/set-registry-values.ps1',
|
|
88
91
|
'sandbox/templates/fivem/README.txt',
|
|
89
92
|
'sandbox/templates/fivem/cs/Client/Client.csproj',
|
|
90
93
|
'sandbox/templates/fivem/cs/Client/ClientMain.cs',
|
|
@@ -142,7 +142,9 @@ export declare function createFixtures(t: Harness): {
|
|
|
142
142
|
pcInstalls: {
|
|
143
143
|
steamGames: boolean | number[];
|
|
144
144
|
epicGames: boolean | string[];
|
|
145
|
-
unrealEngines: boolean | string[];
|
|
145
|
+
unrealEngines: boolean | string[] | "auto";
|
|
146
|
+
unrealEngineFolders: string[];
|
|
147
|
+
unrealAssets: boolean | "auto";
|
|
146
148
|
unityEditors: boolean | string[];
|
|
147
149
|
};
|
|
148
150
|
provisioning: {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export const UNREAL_SAMPLE = {
|
|
2
|
+
setUp: true,
|
|
3
|
+
checkedAt: '2026-11-04T12:00:00.000Z',
|
|
4
|
+
engines: [
|
|
5
|
+
{
|
|
6
|
+
id: 'UE_5.6',
|
|
7
|
+
version: '5.6.1',
|
|
8
|
+
dir: 'C:\\PcInstalls\\unreal\\UE_5.6',
|
|
9
|
+
where: 'this PC, read-only',
|
|
10
|
+
writable: false,
|
|
11
|
+
build: 'installed',
|
|
12
|
+
sizeBytes: null,
|
|
13
|
+
projects: ['ShooterGame'],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: 'UE_5.4',
|
|
17
|
+
version: '5.4.4',
|
|
18
|
+
dir: 'C:\\AgentData\\tools\\unreal\\engines\\UE_5.4',
|
|
19
|
+
where: 'Epic Games Launcher, data disk',
|
|
20
|
+
writable: true,
|
|
21
|
+
build: 'installed',
|
|
22
|
+
sizeBytes: 48 * 1024 ** 3,
|
|
23
|
+
projects: [],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
projects: [{ project: 'ShooterGame', engine: 'UE_5.6', reason: 'the project asks for 5.6' }],
|
|
27
|
+
launcher: {
|
|
28
|
+
installed: true,
|
|
29
|
+
installLocation: 'C:\\AgentData\\tools\\unreal\\engines',
|
|
30
|
+
problem: null,
|
|
31
|
+
free: '812 GB',
|
|
32
|
+
},
|
|
33
|
+
visualStudio: {
|
|
34
|
+
version: '17.14.37827.9',
|
|
35
|
+
path: 'C:\\AgentData\\tools\\visualstudio\\persist\\Community',
|
|
36
|
+
how: 'kept on the data disk',
|
|
37
|
+
check: 'Visual Studio 17.14.37827.9, MSVC 14.44.35207, Windows SDK 10.0.22621.0',
|
|
38
|
+
ok: true,
|
|
39
|
+
},
|
|
40
|
+
debugger: 'C:\\AgentData\\tools\\visualstudio\\persist\\WindowsKits10\\Debuggers\\x64\\cdb.exe',
|
|
41
|
+
ddc: 'C:\\AgentData\\tools\\unreal\\ddc',
|
|
42
|
+
mcpUrl: null,
|
|
43
|
+
pc: {
|
|
44
|
+
setting: 'auto',
|
|
45
|
+
engines: [
|
|
46
|
+
{
|
|
47
|
+
id: 'UE_5.6',
|
|
48
|
+
name: 'Unreal Engine 5.6.1',
|
|
49
|
+
folder: 'C:\\Program Files\\Epic Games\\UE_5.6',
|
|
50
|
+
writable: false,
|
|
51
|
+
source: false,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'dir-UnrealEngine',
|
|
55
|
+
name: 'Unreal Engine 5.7.0 (UnrealEngine)',
|
|
56
|
+
folder: 'D:\\Src\\UnrealEngine',
|
|
57
|
+
writable: true,
|
|
58
|
+
source: false,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
problem: null,
|
|
62
|
+
},
|
|
63
|
+
vault: {
|
|
64
|
+
setting: 'auto',
|
|
65
|
+
folders: [
|
|
66
|
+
{
|
|
67
|
+
folder: 'C:\\ProgramData\\Epic\\EpicGamesLauncher\\VaultCache',
|
|
68
|
+
packs: [
|
|
69
|
+
{ name: 'CityParkEnvironment', size: '2.1 GB', kind: 'content' },
|
|
70
|
+
{ name: 'ToolkitPlugin', size: '45 MB', kind: 'plugin' },
|
|
71
|
+
],
|
|
72
|
+
more: 0,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
settings: {
|
|
77
|
+
enabled: 'auto',
|
|
78
|
+
acceptLicense: true,
|
|
79
|
+
persistEngines: true,
|
|
80
|
+
derivedDataCache: 'persisted',
|
|
81
|
+
visualStudio: 'full',
|
|
82
|
+
},
|
|
83
|
+
};
|
|
@@ -8,12 +8,12 @@ import { decidePwsh, pcHasPwsh, PWSH_MAX_BYTES, readPwshScripts, usesPwsh } from
|
|
|
8
8
|
import { projectFolderLines, toolLines } from '../guest/boot/guide-lines.js';
|
|
9
9
|
import { binstallAsset, CLI_TOOLS, decideCli, pwshAsset } from '../guest/toolchains/catalogue.js';
|
|
10
10
|
import { missingExtensions, vscodeExtensions, vscodeSettings } from '../guest/toolchains/tools/vscode-profile.js';
|
|
11
|
-
import { addonGuideLine, addonMcpServer, APP_CATEGORIES, APPS, appsNeedMesa, appsNeedUv, appsToInstall, CCUSAGE_VERSION, claudeManagedSettings, CONTEXT7_MCP_VERSION, exeMatcher, HEADROOM_VERSION, headroomArgs, headroomEnv, headroomUrl, PLAYWRIGHT_MCP_VERSION, RTK_VERSION, withAddonMcpServers, } from '../shared/apps/index.js';
|
|
11
|
+
import { addonGuideLine, addonMcpServer, APP_CATEGORIES, APPS, associationPlan, appsNeedMesa, appsNeedUv, appsToInstall, CCUSAGE_VERSION, claudeManagedSettings, CONTEXT7_MCP_VERSION, exeMatcher, HEADROOM_VERSION, headroomArgs, headroomEnv, headroomUrl, PLAYWRIGHT_MCP_VERSION, previewGuideLine, RTK_VERSION, withAddonMcpServers, } from '../shared/apps/index.js';
|
|
12
12
|
import { ConfigSchema, LocalOverridesSchema } from '../core/schema/index.js';
|
|
13
13
|
export const toolchainsSuite = {
|
|
14
14
|
name: 'toolchains',
|
|
15
15
|
title: 'version pickers, release assets, PowerShell 7 and CLI tool decisions',
|
|
16
|
-
run: (t) => {
|
|
16
|
+
run: async (t) => {
|
|
17
17
|
t.section('version pickers');
|
|
18
18
|
const releases = [
|
|
19
19
|
{ version: 'v23.1.0', lts: false },
|
|
@@ -198,6 +198,36 @@ export const toolchainsSuite = {
|
|
|
198
198
|
t.check(ids.every((id, i) => ids.indexOf(id) === i) &&
|
|
199
199
|
APPS.every((a) => APP_CATEGORIES.some((c) => c.id === a.category)) &&
|
|
200
200
|
!APPS.some(badPattern), 'apps: ids are unique, every app is in a known category, every GitHub asset pattern compiles');
|
|
201
|
+
t.section('asset preview apps');
|
|
202
|
+
const previewPick = (id, files) => {
|
|
203
|
+
const source = APPS.find((x) => x.id === id)?.source;
|
|
204
|
+
const re = new RegExp(source && 'github' in source ? source.asset : '$^');
|
|
205
|
+
return files.filter((f) => re.test(f));
|
|
206
|
+
};
|
|
207
|
+
t.check(['f3d', 'imagemagick', 'nomacs'].every((id) => APPS.some((a) => a.id === id && a.category === 'gamedev')) &&
|
|
208
|
+
previewPick('f3d', [
|
|
209
|
+
'F3D-4.0.1-Windows-x86_64.zip',
|
|
210
|
+
'F3D-4.0.1-Windows-x86_64.exe',
|
|
211
|
+
'F3D-4.0.1-Windows-x86_64-raytracing.zip',
|
|
212
|
+
]).join() === 'F3D-4.0.1-Windows-x86_64.zip' &&
|
|
213
|
+
previewPick('imagemagick', [
|
|
214
|
+
'ImageMagick-7.1.2-35-portable-Q16-HDRI-x64.7z',
|
|
215
|
+
'ImageMagick-7.1.2-35-portable-Q16-x64.7z',
|
|
216
|
+
'ImageMagick-7.1.2-35-portable-Q16-HDRI-arm64.7z',
|
|
217
|
+
]).join() === 'ImageMagick-7.1.2-35-portable-Q16-HDRI-x64.7z' &&
|
|
218
|
+
previewPick('nomacs', ['nomacs-portable-win.zip', 'nomacs-setup.exe']).join() === 'nomacs-portable-win.zip', 'preview apps: F3D, ImageMagick and nomacs are in the catalogue and pick the portable download only');
|
|
219
|
+
const f3d = associationPlan('f3d', 'C:\\x\\f3d.exe');
|
|
220
|
+
t.check(f3d.some((v) => v.key === 'Software\\Classes\\.fbx' && v.value === 'Sandbox.f3d') &&
|
|
221
|
+
f3d.some((v) => v.key.endsWith('\\shell\\open\\command') && v.value === '"C:\\x\\f3d.exe" "%1"') &&
|
|
222
|
+
f3d.every((v) => v.hive === 'HKCU' && v.name === '') &&
|
|
223
|
+
associationPlan('nomacs', 'C:\\x\\nomacs.exe').some((v) => v.key === 'Software\\Classes\\.tga') &&
|
|
224
|
+
associationPlan('krita', 'C:\\x\\k.exe').length === 0, 'preview apps: double-click associations name the app per extension; an app without any gets none');
|
|
225
|
+
await t.throws(() => associationPlan('f3d', 'f3d.exe'), 'not a program path', 'a relative program path is refused');
|
|
226
|
+
await t.throws(() => associationPlan('f3d', 'C:\\a"b.exe'), 'not a program path', 'a quoted program path is refused');
|
|
227
|
+
t.check(previewGuideLine([]) === null &&
|
|
228
|
+
previewGuideLine(['jq']) === null &&
|
|
229
|
+
(previewGuideLine(['f3d']) ?? '').includes('--output=') &&
|
|
230
|
+
previewGuideLine(['imagemagick']) !== null, 'preview apps: the agent preview line appears only when F3D or ImageMagick is installed');
|
|
201
231
|
t.check(exeMatcher('/^Godot_v[\\d.]+-stable_win64\\.exe$/')('Godot_v4.7.2-stable_win64.exe') &&
|
|
202
232
|
!exeMatcher('/^Godot_v[\\d.]+-stable_win64\\.exe$/')('Godot_v4.7.2-stable_win64_console.exe') &&
|
|
203
233
|
exeMatcher('Code.exe')('code.EXE'), 'apps: the program is found by name or by pattern');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from './kinds.js';
|
|
2
2
|
export * from './payloads.js';
|
|
3
3
|
export { fingerprint } from './fingerprint.js';
|
|
4
|
-
export { epicSettingsFile, MAX_EPIC_INI_BYTES, readEpicLogin, withEpicLogin, type EpicPayload } from './kinds/epic.js';
|
|
4
|
+
export { epicSettingsFile, epicSettingsFiles, MAX_EPIC_INI_BYTES, readEpicLogin, withEpicLogin, type EpicPayload, } from './kinds/epic.js';
|
|
5
5
|
export * from './kinds/steam.js';
|
|
6
6
|
export { PERPLEXITY_ENV, perplexityKeyFromText, perplexitySummary, type PerplexityPayload, } from './kinds/perplexity.js';
|
|
7
7
|
export { cometPayloadFromCookies, cometSummary, cookiesToRestore, type CometPayload } from './kinds/comet.js';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
export * from './kinds.js';
|
|
4
4
|
export * from './payloads.js';
|
|
5
5
|
export { fingerprint } from './fingerprint.js';
|
|
6
|
-
export { epicSettingsFile, MAX_EPIC_INI_BYTES, readEpicLogin, withEpicLogin } from './kinds/epic.js';
|
|
6
|
+
export { epicSettingsFile, epicSettingsFiles, MAX_EPIC_INI_BYTES, readEpicLogin, withEpicLogin, } from './kinds/epic.js';
|
|
7
7
|
export * from './kinds/steam.js';
|
|
8
8
|
export { PERPLEXITY_ENV, perplexityKeyFromText, perplexitySummary, } from './kinds/perplexity.js';
|
|
9
9
|
export { cometPayloadFromCookies, cometSummary, cookiesToRestore } from './kinds/comet.js';
|
|
@@ -2,8 +2,13 @@ import type { Payload } from '../payloads.js';
|
|
|
2
2
|
/** At most this much of a GameUserSettings.ini is read. */
|
|
3
3
|
export declare const MAX_EPIC_INI_BYTES: number;
|
|
4
4
|
export type EpicPayload = Payload<'epic'>;
|
|
5
|
-
/** GameUserSettings.ini under a LocalAppData folder (the PC's or the sandbox's). */
|
|
5
|
+
/** GameUserSettings.ini under a LocalAppData folder (the PC's or the sandbox's), where launchers before 17 keep it. */
|
|
6
6
|
export declare function epicSettingsFile(localAppData: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Every GameUserSettings.ini the launcher may read, newest place first: launcher 17 and later (20.3 checked) keep it in
|
|
9
|
+
* Config\WindowsEditor, older ones in Config\Windows.
|
|
10
|
+
*/
|
|
11
|
+
export declare function epicSettingsFiles(localAppData: string): string[];
|
|
7
12
|
/** The saved sign-in in an ini text, or null (none, turned off, or not the expected shape). */
|
|
8
13
|
export declare function readEpicLogin(ini: string): EpicPayload | null;
|
|
9
14
|
/** The ini text with its [RememberMe] section replaced by this sign-in (the other sections are kept). */
|
|
@@ -6,10 +6,20 @@ import { EpicPayloadSchema } from '../payloads.js';
|
|
|
6
6
|
/** At most this much of a GameUserSettings.ini is read. */
|
|
7
7
|
export const MAX_EPIC_INI_BYTES = 1024 * 1024;
|
|
8
8
|
const SECTION = '[rememberme]';
|
|
9
|
-
/** GameUserSettings.ini under a LocalAppData folder (the PC's or the sandbox's). */
|
|
9
|
+
/** GameUserSettings.ini under a LocalAppData folder (the PC's or the sandbox's), where launchers before 17 keep it. */
|
|
10
10
|
export function epicSettingsFile(localAppData) {
|
|
11
11
|
return localAppData + '\\EpicGamesLauncher\\Saved\\Config\\Windows\\GameUserSettings.ini';
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Every GameUserSettings.ini the launcher may read, newest place first: launcher 17 and later (20.3 checked) keep it in
|
|
15
|
+
* Config\WindowsEditor, older ones in Config\Windows.
|
|
16
|
+
*/
|
|
17
|
+
export function epicSettingsFiles(localAppData) {
|
|
18
|
+
return [
|
|
19
|
+
localAppData + '\\EpicGamesLauncher\\Saved\\Config\\WindowsEditor\\GameUserSettings.ini',
|
|
20
|
+
epicSettingsFile(localAppData),
|
|
21
|
+
];
|
|
22
|
+
}
|
|
13
23
|
const isHeader = (line) => line.trimStart().startsWith('[');
|
|
14
24
|
/** The saved sign-in in an ini text, or null (none, turned off, or not the expected shape). */
|
|
15
25
|
export function readEpicLogin(ini) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RegistryValue } from '../unreal/engines.js';
|
|
2
|
+
export declare const ASSOCIATIONS: {
|
|
3
|
+
readonly f3d: readonly [".fbx", ".glb", ".gltf", ".obj", ".stl", ".ply", ".3ds", ".usd", ".usdz"];
|
|
4
|
+
readonly nomacs: readonly [".tga", ".psd", ".dds", ".exr"];
|
|
5
|
+
};
|
|
6
|
+
/** The registry values that make `appId` open its file types; no values for an app that opens none. */
|
|
7
|
+
export declare function associationPlan(appId: string, exe: string): RegistryValue[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Which apps open which game-asset files when you double-click them (per user, written to the registry each boot
|
|
2
|
+
// because the sandbox's registry is new every time). Pure: the guest writes the plan with set-registry-values.ps1.
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
export const ASSOCIATIONS = {
|
|
5
|
+
f3d: ['.fbx', '.glb', '.gltf', '.obj', '.stl', '.ply', '.3ds', '.usd', '.usdz'],
|
|
6
|
+
nomacs: ['.tga', '.psd', '.dds', '.exr'],
|
|
7
|
+
};
|
|
8
|
+
const NAMES = { f3d: 'F3D', nomacs: 'nomacs' };
|
|
9
|
+
/** The registry values that make `appId` open its file types; no values for an app that opens none. */
|
|
10
|
+
export function associationPlan(appId, exe) {
|
|
11
|
+
if (!Object.hasOwn(ASSOCIATIONS, appId))
|
|
12
|
+
return [];
|
|
13
|
+
const id = appId;
|
|
14
|
+
if (!path.win32.isAbsolute(exe) || /["\r\n]/.test(exe))
|
|
15
|
+
throw new Error('not a program path: ' + exe);
|
|
16
|
+
const classes = 'Software\\Classes';
|
|
17
|
+
const type = classes + '\\Sandbox.' + id;
|
|
18
|
+
const quoted = '"' + exe + '"';
|
|
19
|
+
const v = (key, value) => ({ hive: 'HKCU', key, name: '', value });
|
|
20
|
+
return [
|
|
21
|
+
...ASSOCIATIONS[id].map((ext) => v(classes + '\\' + ext, 'Sandbox.' + id)),
|
|
22
|
+
v(type, NAMES[id] + ' file'),
|
|
23
|
+
v(type + '\\DefaultIcon', quoted + ',0'),
|
|
24
|
+
v(type + '\\shell\\open\\command', quoted + ' "%1"'),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
@@ -9,6 +9,9 @@ export declare const BROWSER_USE_VERSION = "0.13.14";
|
|
|
9
9
|
export declare const PERPLEXITY_COMPUTER_MCP_URL = "https://www.perplexity.ai/rest/computer/mcp";
|
|
10
10
|
/** Comet's Windows installer: a redirect to the current release (no checksum is published; its signer is checked). */
|
|
11
11
|
export declare const COMET_DOWNLOAD_URL = "https://www.perplexity.ai/rest/browser/download?platform=win_x64&channel=stable";
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Who signs Comet: Perplexity AI, Inc., with an EV code-signing certificate from GlobalSign. Windows reports the
|
|
14
|
+
* subject with E=<contact address> first (E=..., CN="PERPLEXITY AI, INC.", O=...), so CN is not at the start.
|
|
15
|
+
*/
|
|
13
16
|
export declare const COMET_SIGNER: AppSigner;
|
|
14
17
|
export declare const AGENTS_WEB_APPS: readonly AppEntry[];
|
|
@@ -7,9 +7,12 @@ export const BROWSER_USE_VERSION = '0.13.14';
|
|
|
7
7
|
export const PERPLEXITY_COMPUTER_MCP_URL = 'https://www.perplexity.ai/rest/computer/mcp';
|
|
8
8
|
/** Comet's Windows installer: a redirect to the current release (no checksum is published; its signer is checked). */
|
|
9
9
|
export const COMET_DOWNLOAD_URL = 'https://www.perplexity.ai/rest/browser/download?platform=win_x64&channel=stable';
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Who signs Comet: Perplexity AI, Inc., with an EV code-signing certificate from GlobalSign. Windows reports the
|
|
12
|
+
* subject with E=<contact address> first (E=..., CN="PERPLEXITY AI, INC.", O=...), so CN is not at the start.
|
|
13
|
+
*/
|
|
11
14
|
export const COMET_SIGNER = {
|
|
12
|
-
subject: ['
|
|
15
|
+
subject: ['(^|, )CN="?PERPLEXITY AI, INC\\.?"?(,|$)', '(^|, )O="?PERPLEXITY AI, INC\\.?"?(,|$)'],
|
|
13
16
|
issuer: ['^CN=GlobalSign GCC R45 EV CodeSigning CA 2020(,|$)'],
|
|
14
17
|
};
|
|
15
18
|
/** Microsoft Edge, already in every sandbox: the browser Chrome DevTools MCP starts. */
|
|
@@ -1 +1,71 @@
|
|
|
1
|
-
export const GAMEDEV_APPS = [
|
|
1
|
+
export const GAMEDEV_APPS = [
|
|
2
|
+
{
|
|
3
|
+
id: 'krita',
|
|
4
|
+
name: 'Krita',
|
|
5
|
+
category: 'gamedev',
|
|
6
|
+
about: 'Painting and texture editor (PSD, layers, brushes), checked against the SHA-256 download.kde.org publishes.',
|
|
7
|
+
size: '450 MB',
|
|
8
|
+
source: { resolve: 'krita' },
|
|
9
|
+
exe: 'krita.exe',
|
|
10
|
+
needs: ['mesa'],
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: 'inkscape',
|
|
14
|
+
name: 'Inkscape',
|
|
15
|
+
category: 'gamedev',
|
|
16
|
+
about: 'Vector graphics for UI, icons and 2D art (SVG), checked against the SHA-256 inkscape.org publishes.',
|
|
17
|
+
size: '400 MB',
|
|
18
|
+
source: { resolve: 'inkscape' },
|
|
19
|
+
exe: 'inkscape.exe',
|
|
20
|
+
needs: ['7zip'],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'audacity',
|
|
24
|
+
name: 'Audacity',
|
|
25
|
+
category: 'gamedev',
|
|
26
|
+
about: 'Records and edits sound effects and music (WAV, OGG, FLAC).',
|
|
27
|
+
size: '80 MB',
|
|
28
|
+
source: { github: 'audacity/audacity', asset: '^audacity-win-[\\d.]+-(?:64bit\\.zip|x86_64\\.7z)$' },
|
|
29
|
+
exe: 'Audacity.exe',
|
|
30
|
+
needs: ['7zip'],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'renderdoc',
|
|
34
|
+
name: 'RenderDoc',
|
|
35
|
+
category: 'gamedev',
|
|
36
|
+
about: "Captures a frame of a game (Unreal's -d3d12/-vulkan builds) to inspect every draw call, texture and shader. Needs the sandbox's GPU (vGPU) for live captures.",
|
|
37
|
+
size: '70 MB',
|
|
38
|
+
source: { resolve: 'renderdoc' },
|
|
39
|
+
exe: 'qrenderdoc.exe',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'f3d',
|
|
43
|
+
name: 'F3D',
|
|
44
|
+
category: 'gamedev',
|
|
45
|
+
about: 'Fast 3D viewer (FBX, glTF/GLB, OBJ, STL, PLY, 3DS, USD); renders still previews from the command line.',
|
|
46
|
+
size: '100 MB',
|
|
47
|
+
source: { github: 'f3d-app/f3d', asset: '^F3D-[\\d.]+-Windows-x86_64\\.zip$' },
|
|
48
|
+
exe: 'f3d.exe',
|
|
49
|
+
needs: ['mesa'],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'imagemagick',
|
|
53
|
+
name: 'ImageMagick',
|
|
54
|
+
category: 'gamedev',
|
|
55
|
+
about: 'Converts and thumbnails textures (TGA, PSD, DDS, EXR, HDR) and builds contact sheets (magick montage).',
|
|
56
|
+
size: '150 MB',
|
|
57
|
+
source: { github: 'ImageMagick/ImageMagick', asset: '^ImageMagick-[\\d.]+-\\d+-portable-Q16-HDRI-x64\\.7z$' },
|
|
58
|
+
exe: 'magick.exe',
|
|
59
|
+
cli: true,
|
|
60
|
+
needs: ['7zip'],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'nomacs',
|
|
64
|
+
name: 'nomacs',
|
|
65
|
+
category: 'gamedev',
|
|
66
|
+
about: 'Image viewer for textures (TGA, PSD, DDS, EXR).',
|
|
67
|
+
size: '60 MB',
|
|
68
|
+
source: { github: 'nomacs/nomacs', asset: '^nomacs-portable-win\\.zip$' },
|
|
69
|
+
exe: 'nomacs.exe',
|
|
70
|
+
},
|
|
71
|
+
];
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { type AddonMcp, type AppCategory, APP_CATEGORIES, type AppSource, type AppEntry, APPS, appById, CCUSAGE_VERSION, CONTEXT7_MCP_VERSION, HEADROOM_VERSION, PLAYWRIGHT_MCP_VERSION, RTK_VERSION, } from './catalogue.js';
|
|
2
|
+
export { ASSOCIATIONS, associationPlan } from './associations.js';
|
|
3
|
+
export { previewGuideLine } from './preview.js';
|
|
2
4
|
export { exeMatcher, appsToInstall, appsNeedMesa, appsNeedUv } from './selection.js';
|
|
3
5
|
export { signerMatches, type AppSigner, type Signature } from '../signer.js';
|
|
4
6
|
export { AGENTS_WEB_APPS, BROWSER_USE_VERSION, CHROME_DEVTOOLS_MCP_VERSION, COMET_DOWNLOAD_URL, COMET_MCP_VERSION, COMET_SIGNER, PERPLEXITY_COMPUTER_MCP_URL, PERPLEXITY_MCP_VERSION, } from './catalogue-agents-web.js';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { APP_CATEGORIES, APPS, appById, CCUSAGE_VERSION, CONTEXT7_MCP_VERSION, HEADROOM_VERSION, PLAYWRIGHT_MCP_VERSION, RTK_VERSION, } from './catalogue.js';
|
|
2
|
+
export { ASSOCIATIONS, associationPlan } from './associations.js';
|
|
3
|
+
export { previewGuideLine } from './preview.js';
|
|
2
4
|
export { exeMatcher, appsToInstall, appsNeedMesa, appsNeedUv } from './selection.js';
|
|
3
5
|
export { signerMatches } from '../signer.js';
|
|
4
6
|
export { AGENTS_WEB_APPS, BROWSER_USE_VERSION, CHROME_DEVTOOLS_MCP_VERSION, COMET_DOWNLOAD_URL, COMET_MCP_VERSION, COMET_SIGNER, PERPLEXITY_COMPUTER_MCP_URL, PERPLEXITY_MCP_VERSION, } from './catalogue-agents-web.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// The one line that tells an agent how to render previews of meshes and textures for the owner (pure).
|
|
2
|
+
/** Null unless F3D or ImageMagick is installed; `installed` holds app ids. */
|
|
3
|
+
export function previewGuideLine(installed) {
|
|
4
|
+
if (!installed.includes('f3d') && !installed.includes('imagemagick'))
|
|
5
|
+
return null;
|
|
6
|
+
return ('asset previews: `f3d "<mesh>" --output="<pkg>\\previews\\<name>.png" --resolution=1024,768 --up=+Y` per mesh ' +
|
|
7
|
+
'(--up=+Z for Unreal-space files), `magick montage "<pkg>\\source\\**\\*.png" -thumbnail 256x256 -geometry +4+4 ' +
|
|
8
|
+
'-label %f "<pkg>\\previews\\textures.png"` for textures (convert TGA/PSD/DDS/EXR to PNG first with magick); ' +
|
|
9
|
+
"leave them in the package's previews\\ folder for the owner to look at before import");
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface BrowserPolicy {
|
|
2
|
+
readonly key: string;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly type: 'REG_DWORD' | 'REG_SZ';
|
|
5
|
+
readonly data: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const BROWSER_POLICY_KEYS: readonly ["HKLM\\SOFTWARE\\Policies\\Microsoft\\Edge", "HKLM\\SOFTWARE\\Policies\\Google\\Chrome"];
|
|
8
|
+
/**
|
|
9
|
+
* The policies for each browser: no hardware acceleration (today's behaviour) and, when a downloads folder is given,
|
|
10
|
+
* DefaultDownloadDirectory (the default only: Playwright's download path and the user's own choice still win).
|
|
11
|
+
*/
|
|
12
|
+
export declare function browserPolicies(o: {
|
|
13
|
+
readonly downloads: string | null;
|
|
14
|
+
}): BrowserPolicy[];
|