@namzu/sandbox 23.0.1 → 25.0.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.
Files changed (158) hide show
  1. package/CHANGELOG.md +290 -0
  2. package/dist/backends/http-worker-client.d.ts +3 -1
  3. package/dist/backends/http-worker-client.d.ts.map +1 -1
  4. package/dist/backends/http-worker-client.js +15 -4
  5. package/dist/backends/http-worker-client.js.map +1 -1
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/local-virtual-computer/client.d.ts +21 -0
  11. package/dist/local-virtual-computer/client.d.ts.map +1 -0
  12. package/dist/local-virtual-computer/client.js +503 -0
  13. package/dist/local-virtual-computer/client.js.map +1 -0
  14. package/dist/local-virtual-computer/detached-process.d.ts +15 -0
  15. package/dist/local-virtual-computer/detached-process.d.ts.map +1 -0
  16. package/dist/local-virtual-computer/detached-process.js +111 -0
  17. package/dist/local-virtual-computer/detached-process.js.map +1 -0
  18. package/dist/local-virtual-computer/detached-worker.d.ts +11 -0
  19. package/dist/local-virtual-computer/detached-worker.d.ts.map +1 -0
  20. package/dist/local-virtual-computer/detached-worker.js +97 -0
  21. package/dist/local-virtual-computer/detached-worker.js.map +1 -0
  22. package/dist/local-virtual-computer/dialect.d.ts +26 -0
  23. package/dist/local-virtual-computer/dialect.d.ts.map +1 -0
  24. package/dist/local-virtual-computer/dialect.js +61 -0
  25. package/dist/local-virtual-computer/dialect.js.map +1 -0
  26. package/dist/local-virtual-computer/engine.d.ts +63 -0
  27. package/dist/local-virtual-computer/engine.d.ts.map +1 -0
  28. package/dist/local-virtual-computer/engine.js +125 -0
  29. package/dist/local-virtual-computer/engine.js.map +1 -0
  30. package/dist/local-virtual-computer/guest-stdio.d.ts +15 -0
  31. package/dist/local-virtual-computer/guest-stdio.d.ts.map +1 -0
  32. package/dist/local-virtual-computer/guest-stdio.js +330 -0
  33. package/dist/local-virtual-computer/guest-stdio.js.map +1 -0
  34. package/dist/local-virtual-computer/index.d.ts +36 -0
  35. package/dist/local-virtual-computer/index.d.ts.map +1 -0
  36. package/dist/local-virtual-computer/index.js +341 -0
  37. package/dist/local-virtual-computer/index.js.map +1 -0
  38. package/dist/local-virtual-computer/podman-machine.d.ts +17 -0
  39. package/dist/local-virtual-computer/podman-machine.d.ts.map +1 -0
  40. package/dist/local-virtual-computer/podman-machine.js +181 -0
  41. package/dist/local-virtual-computer/podman-machine.js.map +1 -0
  42. package/dist/local-virtual-computer/setup/contract.d.ts +360 -0
  43. package/dist/local-virtual-computer/setup/contract.d.ts.map +1 -0
  44. package/dist/local-virtual-computer/setup/contract.js +3 -0
  45. package/dist/local-virtual-computer/setup/contract.js.map +1 -0
  46. package/dist/local-virtual-computer/setup/elevated.d.ts +78 -0
  47. package/dist/local-virtual-computer/setup/elevated.d.ts.map +1 -0
  48. package/dist/local-virtual-computer/setup/elevated.js +548 -0
  49. package/dist/local-virtual-computer/setup/elevated.js.map +1 -0
  50. package/dist/local-virtual-computer/setup/host.d.ts +12 -0
  51. package/dist/local-virtual-computer/setup/host.d.ts.map +1 -0
  52. package/dist/local-virtual-computer/setup/host.js +93 -0
  53. package/dist/local-virtual-computer/setup/host.js.map +1 -0
  54. package/dist/local-virtual-computer/setup/idle.d.ts +18 -0
  55. package/dist/local-virtual-computer/setup/idle.d.ts.map +1 -0
  56. package/dist/local-virtual-computer/setup/idle.js +38 -0
  57. package/dist/local-virtual-computer/setup/idle.js.map +1 -0
  58. package/dist/local-virtual-computer/setup/image.d.ts +7 -0
  59. package/dist/local-virtual-computer/setup/image.d.ts.map +1 -0
  60. package/dist/local-virtual-computer/setup/image.js +124 -0
  61. package/dist/local-virtual-computer/setup/image.js.map +1 -0
  62. package/dist/local-virtual-computer/setup/index.d.ts +17 -0
  63. package/dist/local-virtual-computer/setup/index.d.ts.map +1 -0
  64. package/dist/local-virtual-computer/setup/index.js +17 -0
  65. package/dist/local-virtual-computer/setup/index.js.map +1 -0
  66. package/dist/local-virtual-computer/setup/limits.d.ts +30 -0
  67. package/dist/local-virtual-computer/setup/limits.d.ts.map +1 -0
  68. package/dist/local-virtual-computer/setup/limits.js +58 -0
  69. package/dist/local-virtual-computer/setup/limits.js.map +1 -0
  70. package/dist/local-virtual-computer/setup/plan.d.ts +8 -0
  71. package/dist/local-virtual-computer/setup/plan.d.ts.map +1 -0
  72. package/dist/local-virtual-computer/setup/plan.js +131 -0
  73. package/dist/local-virtual-computer/setup/plan.js.map +1 -0
  74. package/dist/local-virtual-computer/setup/readiness.d.ts +11 -0
  75. package/dist/local-virtual-computer/setup/readiness.d.ts.map +1 -0
  76. package/dist/local-virtual-computer/setup/readiness.js +320 -0
  77. package/dist/local-virtual-computer/setup/readiness.js.map +1 -0
  78. package/dist/local-virtual-computer/setup/registry.d.ts +18 -0
  79. package/dist/local-virtual-computer/setup/registry.d.ts.map +1 -0
  80. package/dist/local-virtual-computer/setup/registry.js +50 -0
  81. package/dist/local-virtual-computer/setup/registry.js.map +1 -0
  82. package/dist/local-virtual-computer/setup/restart.d.ts +8 -0
  83. package/dist/local-virtual-computer/setup/restart.d.ts.map +1 -0
  84. package/dist/local-virtual-computer/setup/restart.js +60 -0
  85. package/dist/local-virtual-computer/setup/restart.js.map +1 -0
  86. package/dist/local-virtual-computer/setup/resume.d.ts +14 -0
  87. package/dist/local-virtual-computer/setup/resume.d.ts.map +1 -0
  88. package/dist/local-virtual-computer/setup/resume.js +58 -0
  89. package/dist/local-virtual-computer/setup/resume.js.map +1 -0
  90. package/dist/local-virtual-computer/setup/run.d.ts +8 -0
  91. package/dist/local-virtual-computer/setup/run.d.ts.map +1 -0
  92. package/dist/local-virtual-computer/setup/run.js +200 -0
  93. package/dist/local-virtual-computer/setup/run.js.map +1 -0
  94. package/dist/local-virtual-computer/setup/windows-folder.d.ts +11 -0
  95. package/dist/local-virtual-computer/setup/windows-folder.d.ts.map +1 -0
  96. package/dist/local-virtual-computer/setup/windows-folder.js +14 -0
  97. package/dist/local-virtual-computer/setup/windows-folder.js.map +1 -0
  98. package/dist/local-virtual-computer/setup/wsl-package.d.ts +19 -0
  99. package/dist/local-virtual-computer/setup/wsl-package.d.ts.map +1 -0
  100. package/dist/local-virtual-computer/setup/wsl-package.js +242 -0
  101. package/dist/local-virtual-computer/setup/wsl-package.js.map +1 -0
  102. package/dist/local-virtual-computer/setup/wslc-shared.d.ts +27 -0
  103. package/dist/local-virtual-computer/setup/wslc-shared.d.ts.map +1 -0
  104. package/dist/local-virtual-computer/setup/wslc-shared.js +137 -0
  105. package/dist/local-virtual-computer/setup/wslc-shared.js.map +1 -0
  106. package/dist/local-virtual-computer/ssh-forward.d.ts +19 -0
  107. package/dist/local-virtual-computer/ssh-forward.d.ts.map +1 -0
  108. package/dist/local-virtual-computer/ssh-forward.js +179 -0
  109. package/dist/local-virtual-computer/ssh-forward.js.map +1 -0
  110. package/dist/local-virtual-computer/wslc-engine.d.ts +27 -0
  111. package/dist/local-virtual-computer/wslc-engine.d.ts.map +1 -0
  112. package/dist/local-virtual-computer/wslc-engine.js +98 -0
  113. package/dist/local-virtual-computer/wslc-engine.js.map +1 -0
  114. package/local-computer/Dockerfile +99 -0
  115. package/local-computer/app-catalog.cjs +240 -0
  116. package/local-computer/app-native-host.cjs +144 -0
  117. package/local-computer/browser-home.cjs +249 -0
  118. package/local-computer/build-image.mjs +310 -0
  119. package/local-computer/desktop-worker.cjs +477 -0
  120. package/local-computer/entrypoint.sh +161 -0
  121. package/local-computer/home.html +28 -0
  122. package/local-computer/new-tab/home.css +255 -0
  123. package/local-computer/new-tab/home.js +65 -0
  124. package/local-computer/new-tab/manifest.json +12 -0
  125. package/local-computer/new-tab/wordmark.svg +33 -0
  126. package/local-computer/openbox-rc.xml +41 -0
  127. package/local-computer/prepare-home.cjs +121 -0
  128. package/local-computer/tint2rc +44 -0
  129. package/package.json +13 -4
  130. package/src/backends/http-worker-client.ts +31 -3
  131. package/src/index.ts +13 -0
  132. package/src/local-virtual-computer/client.ts +573 -0
  133. package/src/local-virtual-computer/detached-process.ts +133 -0
  134. package/src/local-virtual-computer/detached-worker.ts +124 -0
  135. package/src/local-virtual-computer/dialect.ts +83 -0
  136. package/src/local-virtual-computer/engine.ts +197 -0
  137. package/src/local-virtual-computer/guest-stdio.ts +332 -0
  138. package/src/local-virtual-computer/index.ts +447 -0
  139. package/src/local-virtual-computer/podman-machine.ts +264 -0
  140. package/src/local-virtual-computer/setup/contract.ts +395 -0
  141. package/src/local-virtual-computer/setup/elevated.ts +655 -0
  142. package/src/local-virtual-computer/setup/host.ts +100 -0
  143. package/src/local-virtual-computer/setup/idle.ts +39 -0
  144. package/src/local-virtual-computer/setup/image.ts +159 -0
  145. package/src/local-virtual-computer/setup/index.ts +16 -0
  146. package/src/local-virtual-computer/setup/limits.ts +68 -0
  147. package/src/local-virtual-computer/setup/plan.ts +144 -0
  148. package/src/local-virtual-computer/setup/readiness.ts +386 -0
  149. package/src/local-virtual-computer/setup/registry.ts +50 -0
  150. package/src/local-virtual-computer/setup/restart.ts +64 -0
  151. package/src/local-virtual-computer/setup/resume.ts +65 -0
  152. package/src/local-virtual-computer/setup/run.ts +225 -0
  153. package/src/local-virtual-computer/setup/windows-folder.ts +13 -0
  154. package/src/local-virtual-computer/setup/wsl-package.ts +242 -0
  155. package/src/local-virtual-computer/setup/wslc-shared.ts +147 -0
  156. package/src/local-virtual-computer/ssh-forward.ts +195 -0
  157. package/src/local-virtual-computer/wslc-engine.ts +124 -0
  158. package/worker/server.js +1499 -0
@@ -0,0 +1,503 @@
1
+ import { generateSandboxId, walkFilesViaExec } from '@namzu/sdk';
2
+ import { HttpWorkerClient, workerAuthorization } from '../backends/http-worker-client.js';
3
+ import { RemoteCancellationUnknownError } from '../backends/remote-execution-controller.js';
4
+ import { startDetachedGuestProcess } from './detached-process.js';
5
+ import { openGuestStdio } from './guest-stdio.js';
6
+ export function localComputerClients(options) {
7
+ let active = true;
8
+ let busy = 0;
9
+ let mode = 'pal';
10
+ let uncertain = false;
11
+ let screenEpoch = 0;
12
+ let needsFreshScreen = false;
13
+ let stopping;
14
+ const detached = new Set();
15
+ const stdio = new Set();
16
+ const heldKeyboards = new Map();
17
+ const assertActive = () => {
18
+ if (!active)
19
+ throw new Error('This Pal computer lease has ended');
20
+ };
21
+ const assertCertain = () => {
22
+ if (uncertain)
23
+ throw new Error('The Pal computer operation outcome is unknown. Stop this computer before retrying.');
24
+ };
25
+ const assertPal = () => {
26
+ assertActive();
27
+ assertCertain();
28
+ if (mode !== 'pal')
29
+ throw new Error('The operator has control of this Pal computer');
30
+ };
31
+ const stop = (destroyOptions) => {
32
+ active = false;
33
+ if (stopping)
34
+ return stopping;
35
+ stopping = options
36
+ .stop(destroyOptions?.signal)
37
+ .then(async () => {
38
+ for (const channel of stdio)
39
+ channel.allocationEnded();
40
+ stdio.clear();
41
+ // Guest removal is confirmed first. These pipes may now end without
42
+ // being mistaken for proof that a guest process was stopped.
43
+ for (const process of detached)
44
+ process.child.kill('SIGKILL');
45
+ await Promise.all([...detached].map((process) => process.closed));
46
+ })
47
+ .catch((error) => {
48
+ stopping = undefined;
49
+ throw error;
50
+ });
51
+ return stopping;
52
+ };
53
+ const headers = {
54
+ 'content-type': 'application/json',
55
+ ...workerAuthorization(options.token),
56
+ };
57
+ // A successfully completed foreground launcher may leave applications owned
58
+ // by this exclusive computer. Detached jobs use their own strict client.
59
+ const worker = new HttpWorkerClient(options.executionUrl, options.token, options.normalExitPolicy ?? 'computer-lifetime');
60
+ const request = async (route, body, signal) => {
61
+ assertPal();
62
+ busy += 1;
63
+ try {
64
+ const response = await fetch(`${options.executionUrl}${route}`, {
65
+ method: 'POST',
66
+ headers,
67
+ body: JSON.stringify(body),
68
+ signal,
69
+ });
70
+ if (!response.ok) {
71
+ if (route === '/write-file' && response.status >= 500)
72
+ uncertain = true;
73
+ throw Object.assign(new Error(`The Pal file worker refused the operation (${response.status})`), { refused: true });
74
+ }
75
+ const result = (await response.json());
76
+ if (route === '/write-file' && result.ok !== true)
77
+ uncertain = true;
78
+ return result;
79
+ }
80
+ catch (error) {
81
+ if (route === '/write-file' && !(error && typeof error === 'object' && 'refused' in error))
82
+ uncertain = true;
83
+ throw error;
84
+ }
85
+ finally {
86
+ busy -= 1;
87
+ }
88
+ };
89
+ let rangeLimit;
90
+ const requireRangeSupport = async (signal) => {
91
+ if (rangeLimit !== undefined)
92
+ return rangeLimit;
93
+ let result;
94
+ try {
95
+ result = await request('/read-file', { capabilitiesOnly: true }, signal);
96
+ }
97
+ catch (error) {
98
+ signal?.throwIfAborted();
99
+ throw new Error('This Pal computer worker did not confirm bounded file reads. Rebuild the local Pal image from the same Namzu release before inspecting artifact images.', { cause: error });
100
+ }
101
+ const capability = result.readFileRanges;
102
+ if (result.ok !== true ||
103
+ !capability ||
104
+ typeof capability !== 'object' ||
105
+ !('version' in capability) ||
106
+ capability.version !== 1 ||
107
+ !('maxBytes' in capability) ||
108
+ typeof capability.maxBytes !== 'number' ||
109
+ !Number.isSafeInteger(capability.maxBytes) ||
110
+ capability.maxBytes < 1 ||
111
+ capability.maxBytes > 32 * 1024 * 1024)
112
+ throw new Error('This Pal computer worker does not acknowledge bounded file reads.');
113
+ rangeLimit = capability.maxBytes;
114
+ return rangeLimit;
115
+ };
116
+ const sandbox = {
117
+ id: generateSandboxId(),
118
+ environment: 'linux-namespace',
119
+ rootDir: '/home/namzu/workspace',
120
+ get status() {
121
+ return !active ? 'destroyed' : busy > 0 || uncertain ? 'busy' : 'ready';
122
+ },
123
+ async openStdio(command, args = [], spawnOptions) {
124
+ const acquire = async (signal) => {
125
+ signal?.throwIfAborted();
126
+ assertPal();
127
+ busy += 1;
128
+ let released = false;
129
+ const release = () => {
130
+ if (!released) {
131
+ released = true;
132
+ busy -= 1;
133
+ }
134
+ };
135
+ try {
136
+ await spawnOptions?.assertExecutionAllowed?.();
137
+ signal?.throwIfAborted();
138
+ assertPal();
139
+ return release;
140
+ }
141
+ catch (error) {
142
+ release();
143
+ throw error;
144
+ }
145
+ };
146
+ const release = await acquire(spawnOptions?.signal);
147
+ try {
148
+ const channel = await openGuestStdio({
149
+ executionUrl: options.executionUrl,
150
+ token: options.token,
151
+ acquire,
152
+ uncertain: () => {
153
+ uncertain = true;
154
+ },
155
+ }, command, args, {
156
+ ...spawnOptions,
157
+ assertExecutionAllowed: async () => {
158
+ await spawnOptions?.assertExecutionAllowed?.();
159
+ assertPal();
160
+ },
161
+ });
162
+ stdio.add(channel);
163
+ void channel.closed.then(() => stdio.delete(channel), () => stdio.delete(channel));
164
+ return channel;
165
+ }
166
+ finally {
167
+ release();
168
+ }
169
+ },
170
+ spawnDetached(command, args, spawnOptions) {
171
+ assertPal();
172
+ const process = startDetachedGuestProcess({
173
+ executionUrl: options.executionUrl,
174
+ token: options.token,
175
+ retire: stop,
176
+ workerPath: options.detachedWorkerPath,
177
+ }, command, args, spawnOptions);
178
+ detached.add(process);
179
+ void process.closed.then(() => detached.delete(process));
180
+ return process;
181
+ },
182
+ async exec(command, args, opts) {
183
+ assertPal();
184
+ busy += 1;
185
+ try {
186
+ return await worker.exec(command, args, opts);
187
+ }
188
+ catch (error) {
189
+ if (error instanceof RemoteCancellationUnknownError) {
190
+ try {
191
+ await stop();
192
+ error.retirement = { accepted: true };
193
+ }
194
+ catch (retirementError) {
195
+ error.retirement = {
196
+ accepted: false,
197
+ error: retirementError instanceof Error
198
+ ? retirementError
199
+ : new Error('Computer retirement failed'),
200
+ };
201
+ }
202
+ }
203
+ throw error;
204
+ }
205
+ finally {
206
+ busy -= 1;
207
+ }
208
+ },
209
+ async writeFile(path, content) {
210
+ const bytes = Buffer.isBuffer(content) ? content : Buffer.from(content);
211
+ const result = await request('/write-file', {
212
+ path,
213
+ content: bytes.toString('base64'),
214
+ encoding: 'base64',
215
+ });
216
+ if (result.ok !== true)
217
+ throw new Error('The Pal file worker did not confirm the write');
218
+ },
219
+ async readFile(path, readOptions) {
220
+ readOptions?.signal?.throwIfAborted();
221
+ assertPal();
222
+ const ranged = readOptions?.offset !== undefined || readOptions?.length !== undefined;
223
+ const offset = readOptions?.offset ?? 0;
224
+ const length = readOptions?.length;
225
+ if (ranged &&
226
+ (!Number.isSafeInteger(offset) ||
227
+ offset < 0 ||
228
+ (length !== undefined &&
229
+ (!Number.isSafeInteger(length) || length < 0 || length > 32 * 1024 * 1024))))
230
+ throw new Error('Invalid or oversized Pal file read range');
231
+ const limit = ranged ? await requireRangeSupport(readOptions?.signal) : undefined;
232
+ if (length !== undefined && limit !== undefined && length > limit)
233
+ throw new Error('The requested file range exceeds this Pal worker’s acknowledged limit');
234
+ const range = {
235
+ version: 1,
236
+ offset,
237
+ ...(length === undefined ? {} : { length }),
238
+ };
239
+ const result = await request('/read-file', { path, encoding: 'base64', ...(ranged ? { range } : {}) }, readOptions?.signal);
240
+ if (result.ok !== true || typeof result.content !== 'string')
241
+ throw new Error('The Pal file worker did not return a file');
242
+ if (ranged) {
243
+ const received = result.range;
244
+ if (!received ||
245
+ typeof received !== 'object' ||
246
+ !('version' in received) ||
247
+ received.version !== 1 ||
248
+ !('offset' in received) ||
249
+ received.offset !== offset ||
250
+ !('length' in received) ||
251
+ received.length !== (length ?? null))
252
+ throw new Error('The Pal file worker did not confirm the requested byte range');
253
+ const maximum = length ?? limit ?? 0;
254
+ if (result.content.length > Math.ceil(maximum / 3) * 4)
255
+ throw new Error('The Pal file worker exceeded the requested byte range');
256
+ }
257
+ const bytes = Buffer.from(result.content, 'base64');
258
+ if (ranged &&
259
+ (bytes.length > (length ?? limit ?? 0) ||
260
+ result.sizeBytes !== bytes.length ||
261
+ bytes.toString('base64') !== result.content))
262
+ throw new Error('The Pal file worker returned invalid bounded file bytes');
263
+ return bytes;
264
+ },
265
+ async listFiles(rootPath) {
266
+ assertPal();
267
+ const entries = [];
268
+ for await (const entry of walkFilesViaExec((...args) => sandbox.exec(...args), rootPath, {
269
+ maxEntries: 100_000,
270
+ }))
271
+ entries.push(entry);
272
+ return entries;
273
+ },
274
+ walkFiles(rootPath, walkOptions) {
275
+ assertPal();
276
+ return walkFilesViaExec((...args) => sandbox.exec(...args), rootPath, walkOptions);
277
+ },
278
+ destroy: stop,
279
+ };
280
+ const executeDesktop = async (action, operator, transitionRelease = false) => {
281
+ assertActive();
282
+ const held = action.type === 'key_down' || action.type === 'key_up' || action.type === 'release_keys';
283
+ if (held && (!operator || !options.heldKeyboard))
284
+ throw new Error('This Pal computer does not support operator held keyboard input');
285
+ const mutation = action.type !== 'screenshot' && action.type !== 'cursor_position';
286
+ const epoch = screenEpoch;
287
+ if (mutation) {
288
+ assertCertain();
289
+ if (operator) {
290
+ if (mode !== 'operator' &&
291
+ !(transitionRelease && mode === 'transitioning' && action.type === 'release_keys'))
292
+ throw new Error('The operator does not have control of this Pal computer');
293
+ }
294
+ else {
295
+ assertPal();
296
+ if (needsFreshScreen)
297
+ throw new Error('Capture a fresh Pal desktop screenshot before sending input');
298
+ }
299
+ }
300
+ busy += 1;
301
+ try {
302
+ let response;
303
+ let result;
304
+ try {
305
+ response = await fetch(`${options.desktopUrl}/action`, {
306
+ method: 'POST',
307
+ headers,
308
+ body: JSON.stringify(action),
309
+ signal: AbortSignal.timeout(30_000),
310
+ });
311
+ if (response.status >= 500)
312
+ throw new Error('Desktop outcome was not confirmed');
313
+ if (!response.ok)
314
+ throw Object.assign(new Error(`The Pal desktop refused the action (${response.status})`), { refused: true });
315
+ const raw = await response.json();
316
+ if (!raw || typeof raw !== 'object')
317
+ throw new Error('Invalid desktop confirmation');
318
+ result = raw;
319
+ if (action.type !== 'screenshot' &&
320
+ action.type !== 'cursor_position' &&
321
+ result.type !== 'ok' &&
322
+ result.outcome !== 'unknown')
323
+ throw new Error('Desktop mutation was not confirmed');
324
+ }
325
+ catch (error) {
326
+ if (error && typeof error === 'object' && 'refused' in error)
327
+ throw error;
328
+ if (mutation) {
329
+ uncertain = true;
330
+ throw Object.assign(new Error('The Pal desktop action may have run; do not automatically replay it'), {
331
+ code: 'computer_use_outcome_unknown',
332
+ action: action.type,
333
+ outcome: 'unknown',
334
+ retrySafety: 'unsafe',
335
+ });
336
+ }
337
+ throw new Error('The Pal desktop is not responding');
338
+ }
339
+ if (result.outcome === 'unknown') {
340
+ uncertain = true;
341
+ throw Object.assign(new Error('The Pal desktop action has an unknown outcome'), {
342
+ code: 'computer_use_outcome_unknown',
343
+ action: action.type,
344
+ outcome: 'unknown',
345
+ retrySafety: 'unsafe',
346
+ });
347
+ }
348
+ if (held && result.type === 'ok') {
349
+ if (action.type === 'key_down') {
350
+ const keys = heldKeyboards.get(action.keyboardId) ?? new Set();
351
+ keys.add(action.key);
352
+ heldKeyboards.set(action.keyboardId, keys);
353
+ }
354
+ else if (action.type === 'key_up') {
355
+ const keys = heldKeyboards.get(action.keyboardId);
356
+ keys?.delete(action.key);
357
+ if (!keys?.size)
358
+ heldKeyboards.delete(action.keyboardId);
359
+ }
360
+ else if (action.type === 'release_keys')
361
+ heldKeyboards.delete(action.keyboardId);
362
+ }
363
+ if (action.type === 'screenshot' &&
364
+ result.type === 'screenshot' &&
365
+ typeof result.data === 'string') {
366
+ const data = Buffer.from(result.data, 'base64');
367
+ if (data.length < 24 || data.toString('hex', 0, 8) !== '89504e470d0a1a0a')
368
+ throw new Error('The Pal desktop returned an invalid PNG');
369
+ const width = data.readUInt32BE(16);
370
+ const height = data.readUInt32BE(20);
371
+ if (mode === 'pal' && epoch === screenEpoch)
372
+ needsFreshScreen = false;
373
+ return {
374
+ type: 'screenshot',
375
+ result: {
376
+ data,
377
+ mimeType: 'image/png',
378
+ width,
379
+ height,
380
+ display: {
381
+ id: 'pal-display',
382
+ x: 0,
383
+ y: 0,
384
+ width,
385
+ height,
386
+ scaleFactor: 1,
387
+ primary: true,
388
+ },
389
+ },
390
+ };
391
+ }
392
+ if (action.type === 'cursor_position' &&
393
+ result.type === 'cursor_position' &&
394
+ result.point &&
395
+ Number.isFinite(result.point.x) &&
396
+ Number.isFinite(result.point.y))
397
+ return { type: 'cursor_position', point: result.point };
398
+ if (action.type !== 'screenshot' && action.type !== 'cursor_position' && result.type === 'ok')
399
+ return { type: 'ok' };
400
+ throw new Error('The Pal desktop returned an invalid action result');
401
+ }
402
+ finally {
403
+ busy -= 1;
404
+ }
405
+ };
406
+ const computerUseHost = {
407
+ id: 'pal-local-container-desktop',
408
+ capabilities: {
409
+ displayServer: 'x11',
410
+ screenshot: true,
411
+ mouse: true,
412
+ keyboard: true,
413
+ cursorPosition: true,
414
+ clipboard: false,
415
+ supportedActions: [
416
+ 'screenshot',
417
+ 'cursor_position',
418
+ 'mouse_move',
419
+ 'mouse_click',
420
+ 'mouse_drag',
421
+ 'scroll',
422
+ 'type_text',
423
+ 'key',
424
+ ],
425
+ mouseClickButtons: ['left', 'middle', 'right'],
426
+ mouseDragButtons: ['left', 'middle', 'right'],
427
+ },
428
+ async getDisplayGeometry() {
429
+ assertActive();
430
+ return options.geometry;
431
+ },
432
+ execute: (action) => executeDesktop(action, false),
433
+ };
434
+ const transfer = async (from, to) => {
435
+ assertActive();
436
+ assertCertain();
437
+ if (mode !== from)
438
+ throw new Error(`This Pal computer is not controlled by ${from}`);
439
+ // This synchronous reservation excludes new guest work before the idle check.
440
+ mode = 'transitioning';
441
+ if (busy > 0 || detached.size > 0) {
442
+ mode = from;
443
+ throw new Error('Wait for all Pal computer work and background jobs to stop before changing control');
444
+ }
445
+ try {
446
+ if (to === 'pal')
447
+ for (const keyboardId of heldKeyboards.keys())
448
+ await executeDesktop({ type: 'release_keys', keyboardId }, true, true);
449
+ screenEpoch += 1;
450
+ needsFreshScreen = to === 'pal';
451
+ mode = to;
452
+ }
453
+ catch (error) {
454
+ mode = from;
455
+ throw error;
456
+ }
457
+ };
458
+ const operatorControl = {
459
+ ...(options.heldKeyboard ? { heldKeyboard: true } : {}),
460
+ get mode() {
461
+ return mode;
462
+ },
463
+ async takeOver() {
464
+ await transfer('pal', 'operator');
465
+ },
466
+ async returnControl() {
467
+ await transfer('operator', 'pal');
468
+ },
469
+ executeInput(input) {
470
+ if (![
471
+ 'mouse_move',
472
+ 'mouse_click',
473
+ 'mouse_drag',
474
+ 'scroll',
475
+ 'type_text',
476
+ 'key',
477
+ 'key_down',
478
+ 'key_up',
479
+ 'release_keys',
480
+ ].includes(input.type))
481
+ throw new Error('Only desktop input is supported for operator control');
482
+ return executeDesktop(input, true);
483
+ },
484
+ };
485
+ const screenStream = options.screenStream
486
+ ? (() => {
487
+ const url = new URL('/stream', options.desktopUrl);
488
+ if (url.protocol !== 'http:' ||
489
+ url.hostname !== '127.0.0.1' ||
490
+ url.username ||
491
+ url.password)
492
+ throw new Error('The Pal screen stream must use the owned guest loopback transport');
493
+ url.protocol = 'ws:';
494
+ return Object.freeze({
495
+ protocol: 'rfb',
496
+ url: url.href,
497
+ authorization: `Bearer ${options.token}`,
498
+ });
499
+ })()
500
+ : undefined;
501
+ return { sandbox, computerUseHost, operatorControl, ...(screenStream ? { screenStream } : {}) };
502
+ }
503
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/local-virtual-computer/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { SandboxDetachedProcess, SandboxSpawnOptions } from '@namzu/sdk';
2
+ export interface DetachedProcessOptions {
3
+ readonly executionUrl: string;
4
+ readonly token: string;
5
+ readonly retire: () => Promise<void>;
6
+ /** Tests using source modules select the already built worker entry. */
7
+ readonly workerPath?: string;
8
+ }
9
+ export interface OwnedDetachedProcess extends SandboxDetachedProcess {
10
+ readonly closed: Promise<void>;
11
+ terminate(signal?: NodeJS.Signals): Promise<void>;
12
+ }
13
+ /** Credentials and command payload travel over private IPC, never argv. */
14
+ export declare function startDetachedGuestProcess(options: DetachedProcessOptions, command: string, args?: readonly string[], spawnOptions?: SandboxSpawnOptions): OwnedDetachedProcess;
15
+ //# sourceMappingURL=detached-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detached-process.d.ts","sourceRoot":"","sources":["../../src/local-virtual-computer/detached-process.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAG7E,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,wEAAwE;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,oBAAqB,SAAQ,sBAAsB;IACnE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACjD;AAED,2EAA2E;AAC3E,wBAAgB,yBAAyB,CACxC,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,SAAS,MAAM,EAAO,EAC5B,YAAY,CAAC,EAAE,mBAAmB,GAChC,oBAAoB,CA4GtB"}
@@ -0,0 +1,111 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { fileURLToPath } from 'node:url';
3
+ /** Credentials and command payload travel over private IPC, never argv. */
4
+ export function startDetachedGuestProcess(options, command, args = [], spawnOptions) {
5
+ const child = spawn(process.execPath, [options.workerPath ?? fileURLToPath(new URL('./detached-worker.js', import.meta.url))], {
6
+ windowsHide: true,
7
+ stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
8
+ env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' },
9
+ });
10
+ let physicallyClosed = false;
11
+ let confirmed = false;
12
+ let recoveryRequired = false;
13
+ let retirement;
14
+ const waiters = new Set();
15
+ const closed = new Promise((resolve) => child.once('close', () => {
16
+ physicallyClosed = true;
17
+ resolve();
18
+ if (!confirmed)
19
+ void retire().catch(() => { });
20
+ }));
21
+ const acceptConfirmation = () => {
22
+ confirmed = true;
23
+ recoveryRequired = false;
24
+ void closed.then(() => {
25
+ for (const waiter of waiters)
26
+ waiter.resolve();
27
+ waiters.clear();
28
+ });
29
+ };
30
+ const retire = () => {
31
+ if (retirement)
32
+ return retirement;
33
+ const attempt = Promise.resolve()
34
+ .then(() => options.retire())
35
+ .then(() => {
36
+ acceptConfirmation();
37
+ if (child.connected)
38
+ child.send({ type: 'retired', confirmed: true }, () => { });
39
+ }, () => {
40
+ recoveryRequired = true;
41
+ const error = new Error('Guest termination and computer retirement could not be confirmed; operator recovery or a termination retry is required');
42
+ for (const waiter of waiters)
43
+ waiter.reject(error);
44
+ waiters.clear();
45
+ if (child.connected)
46
+ child.send({ type: 'retired', confirmed: false }, () => { });
47
+ throw error;
48
+ })
49
+ .finally(() => {
50
+ retirement = undefined;
51
+ });
52
+ retirement = attempt;
53
+ return attempt;
54
+ };
55
+ const requestCancellation = (signal) => {
56
+ if (confirmed)
57
+ return;
58
+ if (recoveryRequired || physicallyClosed) {
59
+ void retire().catch(() => { });
60
+ return;
61
+ }
62
+ if (child.connected)
63
+ child.send({ type: 'cancel', signal }, (error) => {
64
+ if (error)
65
+ void retire().catch(() => { });
66
+ });
67
+ };
68
+ child.once('spawn', () => {
69
+ const config = {
70
+ type: 'start',
71
+ executionUrl: options.executionUrl,
72
+ token: options.token,
73
+ command,
74
+ args: [...args],
75
+ ...(spawnOptions?.cwd ? { cwd: spawnOptions.cwd } : {}),
76
+ ...(spawnOptions?.env ? { env: spawnOptions.env } : {}),
77
+ };
78
+ if (child.connected)
79
+ child.send(config, (error) => {
80
+ if (error)
81
+ child.emit('error', new Error('The guest background bridge could not be initialized'));
82
+ });
83
+ });
84
+ child.on('message', (raw) => {
85
+ if (!raw || typeof raw !== 'object' || !('type' in raw))
86
+ return;
87
+ if (raw.type === 'terminal-confirmed')
88
+ acceptConfirmation();
89
+ if (raw.type === 'retire-computer')
90
+ void retire().catch(() => { });
91
+ });
92
+ return {
93
+ child,
94
+ closed,
95
+ kill(signal) {
96
+ // Both TERM and escalation request confirmed guest cancellation.
97
+ // SIGKILL must never merely kill this host bridge and leave its
98
+ // remote shell running after the registry believes the job stopped.
99
+ requestCancellation(signal);
100
+ },
101
+ terminate(signal = 'SIGTERM') {
102
+ if (confirmed)
103
+ return closed;
104
+ return new Promise((resolve, reject) => {
105
+ waiters.add({ resolve, reject });
106
+ requestCancellation(signal);
107
+ });
108
+ },
109
+ };
110
+ }
111
+ //# sourceMappingURL=detached-process.js.map