@cydm/pie 2.7.3 → 2.7.5

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.
@@ -5,18 +5,37 @@ import { createRequire as __createRequire } from "node:module"; const require =
5
5
  import { randomUUID as randomUUID2 } from "node:crypto";
6
6
  import { pathToFileURL } from "node:url";
7
7
 
8
+ // vendor/computer-use-axi/src/test-backend-guard.ts
9
+ function requireFakeBackend(env = process.env) {
10
+ return env.PIE_COMPUTER_USE_REQUIRE_FAKE_BACKEND === "1";
11
+ }
12
+ function resolveTestOnlyBackend(env = process.env) {
13
+ if (requireFakeBackend(env) && (env.PIE_COMPUTER_USE_FAKE_BACKEND !== "1" || env.PIE_COMPUTER_USE_ENABLE_TEST_COMMANDS !== "1")) {
14
+ throw new Error("Required fake backend needs PIE_COMPUTER_USE_FAKE_BACKEND=1 and PIE_COMPUTER_USE_ENABLE_TEST_COMMANDS=1.");
15
+ }
16
+ if (env.PIE_COMPUTER_USE_FAKE_BACKEND !== "1") return { enabled: false };
17
+ if (env.PIE_COMPUTER_USE_ENABLE_TEST_COMMANDS !== "1") {
18
+ return {
19
+ enabled: false,
20
+ warning: "PIE_COMPUTER_USE_FAKE_BACKEND is test-only and was ignored: it requires PIE_COMPUTER_USE_ENABLE_TEST_COMMANDS=1 as well."
21
+ };
22
+ }
23
+ return { enabled: true };
24
+ }
25
+
8
26
  // vendor/computer-use-axi/src/broker-client.ts
9
27
  import { spawn } from "node:child_process";
10
28
  import { closeSync, existsSync as existsSync2, mkdirSync as mkdirSync2, openSync } from "node:fs";
11
29
  import net from "node:net";
12
- import path3 from "node:path";
30
+ import path4 from "node:path";
13
31
  import { fileURLToPath as fileURLToPath2 } from "node:url";
14
32
 
15
33
  // vendor/computer-use-axi/src/broker-protocol.ts
16
34
  import { createHash, randomUUID } from "node:crypto";
17
- import path2 from "node:path";
35
+ import path3 from "node:path";
18
36
 
19
- // vendor/computer-use-axi/src/persist.ts
37
+ // vendor/computer-use-axi/src/config.ts
38
+ import { AsyncLocalStorage } from "node:async_hooks";
20
39
  import path from "node:path";
21
40
 
22
41
  // src/config.ts
@@ -60,11 +79,59 @@ function getConfigDir() {
60
79
  return join(homedir(), CONFIG_DIR_NAME);
61
80
  }
62
81
 
82
+ // vendor/computer-use-axi/src/config.ts
83
+ var DEFAULT_CONFIG = {
84
+ browser_use: true,
85
+ headless: false,
86
+ cursor_overlay: true,
87
+ managed_browser: "chrome"
88
+ };
89
+ var REQUEST_ENV_KEYS = ["PIE_COMPUTER_USE_BROWSER_USE", "PIE_COMPUTER_USE_HEADLESS", "PIE_COMPUTER_USE_CURSOR_OVERLAY", "PIE_COMPUTER_USE_MANAGED_BROWSER", "PIE_COMPUTER_USE_HELIUM_EXECUTABLE", "PIE_COMPUTER_USE_CHROME_EXECUTABLE", "PIE_COMPUTER_USE_CDP_PORT", "PIE_COMPUTER_USE_DELIVERY_POLICY", "PIE_COMPUTER_USE_EVENT_DELIVERY"];
90
+ function captureComputerUseEnvironment(env = process.env) {
91
+ const out = {};
92
+ for (const key of REQUEST_ENV_KEYS) {
93
+ const value = env[key]?.trim();
94
+ if (!value) continue;
95
+ if (Buffer.byteLength(value) > 4096 || value.includes("\0")) throw new Error(`Invalid ${key}`);
96
+ if (["PIE_COMPUTER_USE_BROWSER_USE", "PIE_COMPUTER_USE_HEADLESS", "PIE_COMPUTER_USE_CURSOR_OVERLAY"].includes(key)) {
97
+ const parsed = parseBoolean(value);
98
+ if (parsed === void 0) throw new Error(`Invalid ${key}`);
99
+ out[key] = String(parsed);
100
+ } else if (key === "PIE_COMPUTER_USE_MANAGED_BROWSER") {
101
+ if (value !== "helium" && value !== "chrome") throw new Error(`Invalid ${key}`);
102
+ out[key] = value;
103
+ } else if (key === "PIE_COMPUTER_USE_DELIVERY_POLICY" || key === "PIE_COMPUTER_USE_EVENT_DELIVERY") {
104
+ const policy = value.toLowerCase();
105
+ if (!["default", "background", "pid", "foreground", "hid", "ax_only", "ax-only"].includes(policy)) throw new Error(`Invalid ${key}`);
106
+ out[key] = policy;
107
+ } else if (key === "PIE_COMPUTER_USE_CDP_PORT") {
108
+ if (!/^\d+$/.test(value) || Number(value) < 1 || Number(value) > 65535) throw new Error(`Invalid ${key}`);
109
+ out[key] = String(Number(value));
110
+ } else {
111
+ if (!path.isAbsolute(value)) throw new Error(`Invalid ${key}: expected absolute path`);
112
+ out[key] = value;
113
+ }
114
+ }
115
+ return Object.freeze(out);
116
+ }
117
+ var operationConfig = new AsyncLocalStorage();
118
+ var defaultLoaded = Object.freeze({ config: Object.freeze({ ...DEFAULT_CONFIG }), sources: [], env: {}, environment: {} });
119
+ function parseBoolean(value) {
120
+ if (typeof value === "boolean") return value;
121
+ if (typeof value === "number") return value === 1 ? true : value === 0 ? false : void 0;
122
+ if (typeof value !== "string") return void 0;
123
+ const normalized = value.trim().toLowerCase();
124
+ if (["1", "true", "yes", "on", "enabled"].includes(normalized)) return true;
125
+ if (["0", "false", "no", "off", "disabled"].includes(normalized)) return false;
126
+ return void 0;
127
+ }
128
+
63
129
  // vendor/computer-use-axi/src/persist.ts
130
+ import path2 from "node:path";
64
131
  function stateRootDir(env = process.env) {
65
132
  const override = env.PIE_COMPUTER_USE_STATE_DIR?.trim();
66
133
  if (override) return override;
67
- return path.join(getConfigDir(), "computer-use");
134
+ return path2.join(getConfigDir(), "computer-use");
68
135
  }
69
136
 
70
137
  // src/runtime/computer-use-owner.ts
@@ -83,8 +150,8 @@ function computerUseOwnerFromEnv(env = process.env) {
83
150
  }
84
151
 
85
152
  // vendor/computer-use-axi/src/broker-protocol.ts
86
- var BROKER_PROTOCOL_VERSION = 1;
87
- var BROKER_ENGINE_VERSION = 2;
153
+ var BROKER_PROTOCOL_VERSION = 3;
154
+ var BROKER_ENGINE_VERSION = 4;
88
155
  var BROKER_PACKAGE_VERSION = "0.5.1-pie.1";
89
156
  var BROKER_MAX_FRAME_BYTES = 4 * 1024 * 1024;
90
157
  var BROKER_MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
@@ -132,6 +199,7 @@ var FrameDecoder = class {
132
199
  for (; ; ) {
133
200
  const newline = this.buffer.indexOf(10);
134
201
  if (newline < 0) break;
202
+ if (newline > this.maxBytes) throw new BrokerProtocolError("frame_too_large", `Frame exceeds the ${this.maxBytes}-byte limit.`);
135
203
  const line = this.buffer.subarray(0, newline).toString("utf8").trim();
136
204
  this.buffer = this.buffer.subarray(newline + 1);
137
205
  if (!line) continue;
@@ -156,11 +224,11 @@ function resolveBrokerEndpoint(env = process.env) {
156
224
  const key = createHash("sha256").update(seed).digest("hex").slice(0, 16);
157
225
  return { kind: "named-pipe", path: `\\\\.\\pipe\\pie-computer-use-axi-${key}` };
158
226
  }
159
- const socketPath = socketOverride || path2.join(stateRootDir(env), "run", "broker.sock");
227
+ const socketPath = socketOverride || path3.join(stateRootDir(env), "run", "broker.sock");
160
228
  if (Buffer.byteLength(socketPath, "utf8") > 100) {
161
229
  throw new BrokerProtocolError("endpoint_too_long", `Unix socket path is ${Buffer.byteLength(socketPath)} bytes (limit ~104): ${socketPath}. Set PIE_COMPUTER_USE_BROKER_SOCKET to a shorter path.`);
162
230
  }
163
- return { kind: "unix-socket", path: socketPath, directory: path2.dirname(socketPath) };
231
+ return { kind: "unix-socket", path: socketPath, directory: path3.dirname(socketPath) };
164
232
  }
165
233
 
166
234
  // vendor/computer-use-axi/src/broker-client.ts
@@ -192,7 +260,7 @@ var SocketFrames = class {
192
260
  socket.on("close", () => this.close());
193
261
  }
194
262
  socket;
195
- decoder = new FrameDecoder();
263
+ decoder = new FrameDecoder(BROKER_MAX_RESPONSE_BYTES);
196
264
  queue = [];
197
265
  waiters = [];
198
266
  closed = false;
@@ -240,12 +308,12 @@ function sleep(ms) {
240
308
  return new Promise((resolve2) => setTimeout(resolve2, ms));
241
309
  }
242
310
  function resolveBrokerSpawn() {
243
- const here = path3.dirname(fileURLToPath2(import.meta.url));
311
+ const here = path4.dirname(fileURLToPath2(import.meta.url));
244
312
  const override = process.env.PIE_COMPUTER_USE_BROKER_ENTRY?.trim();
245
313
  const candidates = [
246
314
  override,
247
- path3.join(here, "computer-use-axi-broker.js"),
248
- path3.join(here, "broker-main.ts")
315
+ path4.join(here, "computer-use-axi-broker.js"),
316
+ path4.join(here, "broker-main.ts")
249
317
  ].filter((candidate) => Boolean(candidate));
250
318
  for (const candidate of candidates) {
251
319
  if (!existsSync2(candidate)) continue;
@@ -259,9 +327,9 @@ function spawnBroker() {
259
327
  let stdio = "ignore";
260
328
  let logFd;
261
329
  try {
262
- const logDir = path3.join(stateRootDir(), "broker");
330
+ const logDir = path4.join(stateRootDir(), "broker");
263
331
  mkdirSync2(logDir, { recursive: true, mode: 448 });
264
- logFd = openSync(path3.join(logDir, "broker.log"), "a", 384);
332
+ logFd = openSync(path4.join(logDir, "broker.log"), "a", 384);
265
333
  stdio = ["ignore", logFd, logFd];
266
334
  } catch {
267
335
  stdio = "ignore";
@@ -309,6 +377,8 @@ function isBrokerResponse(value) {
309
377
  return Boolean(value) && typeof value === "object" && value.type === "response";
310
378
  }
311
379
  async function callBroker(options) {
380
+ if (options.command !== "stop") resolveTestOnlyBackend();
381
+ const environment = captureComputerUseEnvironment();
312
382
  const endpoint = resolveBrokerEndpoint();
313
383
  const budgetMs = Math.min(Math.max(options.budgetMs ?? BROKER_DEFAULT_REQUEST_BUDGET_MS, 100), 15 * 6e4);
314
384
  const spawnState = { spawned: false };
@@ -318,7 +388,7 @@ async function callBroker(options) {
318
388
  const socket = await connectOrSpawn(endpoint, options.spawnIfMissing !== false, spawnState);
319
389
  const frames = new SocketFrames(socket);
320
390
  try {
321
- socket.write(encodeFrame({ type: "hello", protocolVersion: BROKER_PROTOCOL_VERSION, clientVersion: "cli" }));
391
+ socket.write(encodeFrame({ type: "hello", protocolVersion: BROKER_PROTOCOL_VERSION, clientVersion: "cli", buildIdentity: BROKER_BUILD.identity }));
322
392
  const helloFrame = await frames.next(BROKER_HANDSHAKE_TIMEOUT_MS);
323
393
  if (!helloFrame || typeof helloFrame !== "object" || helloFrame.type !== "hello") {
324
394
  throw new BrokerCallError("broker_no_handshake", "The computer-use broker did not answer the protocol handshake.", { exitCode: 1 });
@@ -347,6 +417,12 @@ async function callBroker(options) {
347
417
  );
348
418
  }
349
419
  }
420
+ if (options.command !== "stop" && (hello.protocolVersion !== BROKER_PROTOCOL_VERSION || hello.build?.identity !== BROKER_BUILD.identity)) {
421
+ throw new BrokerCallError("broker_incompatible", "The running broker protocol or engine build differs. Run 'computer-use-axi stop' before retrying; no request was sent.", { exitCode: 3, incompatible: true, brokerPid: hello.pid });
422
+ }
423
+ if (options.command !== "stop" && requireFakeBackend() && (!hello.ok || hello.backend?.fakeInstalled !== true || hello.backend.requireFake !== true)) {
424
+ throw new BrokerCallError("broker_incompatible", "Required fake backend: running broker does not attest installed fake and enforced requirement; no request was sent.", { exitCode: 3, incompatible: true, brokerPid: hello.pid });
425
+ }
350
426
  const brokerProtocol = hello.protocolVersion ?? BROKER_PROTOCOL_VERSION;
351
427
  const request = {
352
428
  type: "request",
@@ -358,6 +434,7 @@ async function callBroker(options) {
358
434
  command: options.command,
359
435
  params: options.params,
360
436
  cwd: options.cwd,
437
+ environment,
361
438
  budgetMs
362
439
  };
363
440
  socket.write(encodeFrame(request));