@cydm/pie 2.6.12 → 2.7.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 (34) hide show
  1. package/README.md +68 -2
  2. package/dist/builtin/extensions/ask-user/index.js +3 -3
  3. package/dist/builtin/extensions/plan-mode/index.js +130 -21
  4. package/dist/builtin/extensions/subagent/index.js +4 -5
  5. package/dist/builtin/extensions/todo/index.js +3 -3
  6. package/dist/builtin/skills/computer-use-axi/SKILL.md +103 -0
  7. package/dist/builtin/skills/computer-use-axi/computer-use-axi-cli.js +37 -0
  8. package/dist/builtin/{extensions/computer-use/index.js → skills/computer-use-axi/computer-use-axi-runtime.js} +754 -642
  9. package/dist/builtin/skills/computer-use-axi/package.json +11 -0
  10. package/dist/chunks/{chunk-PPEWRUMQ.js → chunk-6RBSTII7.js} +657 -594
  11. package/dist/chunks/{chunk-AAEBH6KX.js → chunk-IPNAFMOJ.js} +172 -230
  12. package/dist/chunks/{chunk-7B4IIBVS.js → chunk-R5I2QLF2.js} +1269 -4
  13. package/dist/chunks/{chunk-HHNOENEH.js → chunk-TWILEFLD.js} +14 -1
  14. package/dist/chunks/{src-OWQI5M6W.js → src-E7NCXMU5.js} +2 -2
  15. package/dist/chunks/{test-stream-Y7WXELAJ.js → test-stream-BWBJTFNI.js} +1 -1
  16. package/dist/cli.js +463 -232
  17. package/models.schema.json +52 -0
  18. package/package.json +3 -3
  19. package/dist/builtin/extensions/computer-use/package.json +0 -14
  20. package/dist/builtin/extensions/computer-use/scripts/build-native.mjs +0 -278
  21. package/dist/builtin/extensions/computer-use/scripts/test-native-retention.mjs +0 -204
  22. package/dist/chunks/chunk-5353DEEC.js +0 -130
  23. package/dist/chunks/webapi-MBCKO7ZV.js +0 -2481
  24. package/dist/code-intel-worker.cjs +0 -211227
  25. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/linux/arm64/linux-bridge +0 -0
  26. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/linux/x64/linux-bridge +0 -0
  27. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/arm64/pie-computer-use +0 -0
  28. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/universal/pie-computer-use.app/Contents/Info.plist +0 -0
  29. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/universal/pie-computer-use.app/Contents/MacOS/pie-computer-use +0 -0
  30. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/universal/pie-computer-use.app/Contents/_CodeSignature/CodeResources +0 -0
  31. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/x64/pie-computer-use +0 -0
  32. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/windows/windows-bridge.exe +0 -0
  33. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/scripts/helper-path.mjs +0 -0
  34. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/scripts/setup-helper.mjs +0 -0
@@ -1,15 +1,40 @@
1
+ #!/usr/bin/env node
1
2
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
- import {
3
- getConfigDir
4
- } from "../../../chunks/chunk-5353DEEC.js";
5
- import {
6
- Type
7
- } from "../../../chunks/chunk-XXGYUYXI.js";
8
- import {
9
- __commonJS,
10
- __require,
11
- __toESM
12
- } from "../../../chunks/chunk-LZQXQOPJ.js";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
+ }) : x)(function(x) {
12
+ if (typeof require !== "undefined") return require.apply(this, arguments);
13
+ throw Error('Dynamic require of "' + x + '" is not supported');
14
+ });
15
+ var __commonJS = (cb, mod) => function __require2() {
16
+ try {
17
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18
+ } catch (e) {
19
+ throw mod = 0, e;
20
+ }
21
+ };
22
+ var __copyProps = (to, from, except, desc) => {
23
+ if (from && typeof from === "object" || typeof from === "function") {
24
+ for (let key of __getOwnPropNames(from))
25
+ if (!__hasOwnProp.call(to, key) && key !== except)
26
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
27
+ }
28
+ return to;
29
+ };
30
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
31
+ // If the importer is in node compatibility mode or this is not an ESM
32
+ // file that has been converted to a CommonJS file using a Babel-
33
+ // compatible transform (i.e. "__esModule" has not been set), then set
34
+ // "default" to the CommonJS "module.exports" for node compatibility.
35
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
36
+ mod
37
+ ));
13
38
 
14
39
  // ../../node_modules/ws/lib/constants.js
15
40
  var require_constants = __commonJS({
@@ -3694,16 +3719,16 @@ var require_websocket_server = __commonJS({
3694
3719
  }
3695
3720
  });
3696
3721
 
3697
- // builtin/extensions/computer-use/src/bridge.ts
3722
+ // vendor/computer-use-axi/src/bridge.ts
3698
3723
  import { spawn as spawn4 } from "node:child_process";
3699
- import { randomUUID as randomUUID5 } from "node:crypto";
3700
- import { constants as fsConstants5, mkdtempSync as mkdtempSync2 } from "node:fs";
3724
+ import { randomUUID as randomUUID6 } from "node:crypto";
3725
+ import { constants as fsConstants5, mkdtempSync } from "node:fs";
3701
3726
  import { access as access4 } from "node:fs/promises";
3702
3727
  import net2 from "node:net";
3703
- import os5 from "node:os";
3704
- import path10 from "node:path";
3728
+ import os4 from "node:os";
3729
+ import path11 from "node:path";
3705
3730
 
3706
- // builtin/extensions/computer-use/src/platform/coerce.ts
3731
+ // vendor/computer-use-axi/src/platform/coerce.ts
3707
3732
  function toBoolean(value) {
3708
3733
  return value === true || value === "true" || value === 1;
3709
3734
  }
@@ -3719,7 +3744,7 @@ function toOptionalString(value) {
3719
3744
  return typeof value === "string" && value.length > 0 ? value : void 0;
3720
3745
  }
3721
3746
 
3722
- // builtin/extensions/computer-use/src/actions.ts
3747
+ // vendor/computer-use-axi/src/actions.ts
3723
3748
  function mouseButton(value) {
3724
3749
  return value === "right" || value === "middle" ? value : "left";
3725
3750
  }
@@ -3735,9 +3760,9 @@ function keys(value) {
3735
3760
  }
3736
3761
  function path(value, env) {
3737
3762
  if (!Array.isArray(value) || value.length < 2) throw new Error("drag.path must contain at least two points.");
3738
- return value.map((point2, index) => {
3739
- const x = Array.isArray(point2) ? toFiniteNumber(point2[0], NaN) : toFiniteNumber(point2?.x, NaN);
3740
- const y = Array.isArray(point2) ? toFiniteNumber(point2[1], NaN) : toFiniteNumber(point2?.y, NaN);
3763
+ return value.map((point, index) => {
3764
+ const x = Array.isArray(point) ? toFiniteNumber(point[0], NaN) : toFiniteNumber(point?.x, NaN);
3765
+ const y = Array.isArray(point) ? toFiniteNumber(point[1], NaN) : toFiniteNumber(point?.y, NaN);
3741
3766
  env.validatePoint(x, y, `Drag point ${index + 1}`);
3742
3767
  return { x, y };
3743
3768
  });
@@ -3747,17 +3772,17 @@ function nativeTarget(action, operation, env) {
3747
3772
  const node = env.node(action.ref.trim());
3748
3773
  const semanticClick = operation === "click" || operation === "press";
3749
3774
  if (semanticClick && node.isTextInput) {
3750
- const point3 = env.center(node);
3751
- env.validatePoint(point3.x, point3.y);
3752
- return point3;
3775
+ const point2 = env.center(node);
3776
+ env.validatePoint(point2.x, point2.y);
3777
+ return point2;
3753
3778
  }
3754
3779
  const onlyIncidentalActions = node.actions.every((candidate) => candidate === "AXShowMenu" || candidate === "AXScrollToVisible");
3755
3780
  if (node.wireRef && !node.pictureOnly && (!semanticClick || node.canPress || node.canFocus || node.canSetValue || !onlyIncidentalActions)) {
3756
3781
  return { ref: node.wireRef };
3757
3782
  }
3758
- const point2 = env.center(node);
3759
- env.validatePoint(point2.x, point2.y);
3760
- return point2;
3783
+ const point = env.center(node);
3784
+ env.validatePoint(point.x, point.y);
3785
+ return point;
3761
3786
  }
3762
3787
  const x = toFiniteNumber(action.x, NaN);
3763
3788
  const y = toFiniteNumber(action.y, NaN);
@@ -3860,7 +3885,7 @@ function outcomeAfterObservedValues(current, actions, valueForRef) {
3860
3885
  return matches ? "worked" : current;
3861
3886
  }
3862
3887
 
3863
- // builtin/extensions/computer-use/src/cdp.ts
3888
+ // vendor/computer-use-axi/src/cdp.ts
3864
3889
  import { randomUUID } from "node:crypto";
3865
3890
 
3866
3891
  // ../../node_modules/ws/wrapper.mjs
@@ -3874,7 +3899,7 @@ var import_websocket = __toESM(require_websocket(), 1);
3874
3899
  var import_websocket_server = __toESM(require_websocket_server(), 1);
3875
3900
  var wrapper_default = import_websocket.default;
3876
3901
 
3877
- // builtin/extensions/computer-use/src/outline.ts
3902
+ // vendor/computer-use-axi/src/outline.ts
3878
3903
  var DEFAULT_BUDGET = { maxDepth: 2, maxNodes: 150 };
3879
3904
  function isRecord(value) {
3880
3905
  return typeof value === "object" && value !== null;
@@ -4336,7 +4361,7 @@ function graftScopedOutline(outline, targetRef, scoped) {
4336
4361
  return target;
4337
4362
  }
4338
4363
 
4339
- // builtin/extensions/computer-use/src/cdp.ts
4364
+ // vendor/computer-use-axi/src/cdp.ts
4340
4365
  var COMMAND_TIMEOUT_MS = 5e3;
4341
4366
  var CDP_CONTEXT_PREFIX = "browser:";
4342
4367
  var NAVIGATE_LOAD_TIMEOUT_MS = 1e4;
@@ -4367,11 +4392,11 @@ var CdpTab = class _CdpTab {
4367
4392
  const ws = new wrapper_default(wsUrl);
4368
4393
  connectingSockets.add(ws);
4369
4394
  try {
4370
- await new Promise((resolve, reject) => {
4395
+ await new Promise((resolve2, reject) => {
4371
4396
  const timer = setTimeout(() => reject(new Error(`Timed out connecting to CDP target at ${wsUrl}`)), COMMAND_TIMEOUT_MS);
4372
4397
  ws.onopen = () => {
4373
4398
  clearTimeout(timer);
4374
- resolve();
4399
+ resolve2();
4375
4400
  };
4376
4401
  ws.onerror = () => {
4377
4402
  clearTimeout(timer);
@@ -4419,14 +4444,14 @@ var CdpTab = class _CdpTab {
4419
4444
  this.loadFired = void 0;
4420
4445
  this.rejectAllPending(new Error("CDP connection closed."));
4421
4446
  if (this.ws.readyState === wrapper_default.CLOSED) return;
4422
- await new Promise((resolve) => {
4447
+ await new Promise((resolve2) => {
4423
4448
  const timer = setTimeout(() => {
4424
4449
  this.ws.terminate();
4425
- resolve();
4450
+ resolve2();
4426
4451
  }, 500);
4427
4452
  this.ws.once("close", () => {
4428
4453
  clearTimeout(timer);
4429
- resolve();
4454
+ resolve2();
4430
4455
  });
4431
4456
  if (this.ws.readyState === wrapper_default.CONNECTING) this.ws.terminate();
4432
4457
  else this.ws.close();
@@ -4446,13 +4471,13 @@ var CdpTab = class _CdpTab {
4446
4471
  }
4447
4472
  async navigate(url) {
4448
4473
  let timer;
4449
- const loaded = new Promise((resolve) => {
4450
- this.loadFired = resolve;
4474
+ const loaded = new Promise((resolve2) => {
4475
+ this.loadFired = resolve2;
4451
4476
  });
4452
4477
  try {
4453
4478
  await this.send("Page.navigate", { url });
4454
- await Promise.race([loaded, new Promise((resolve) => {
4455
- timer = setTimeout(resolve, NAVIGATE_LOAD_TIMEOUT_MS);
4479
+ await Promise.race([loaded, new Promise((resolve2) => {
4480
+ timer = setTimeout(resolve2, NAVIGATE_LOAD_TIMEOUT_MS);
4456
4481
  })]);
4457
4482
  } finally {
4458
4483
  clearTimeout(timer);
@@ -4489,11 +4514,11 @@ var CdpTab = class _CdpTab {
4489
4514
  async mouseAt(x, y, type, button = "left", clickCount2 = 1) {
4490
4515
  await this.send("Input.dispatchMouseEvent", { type, x, y, button: type === "mouseMoved" ? "none" : button, clickCount: clickCount2 });
4491
4516
  }
4492
- async dragPath(path11) {
4493
- if (path11.length < 2) throw new Error("CDP drag requires at least two points.");
4494
- await this.mouseAt(path11[0].x, path11[0].y, "mousePressed");
4495
- for (const point2 of path11.slice(1)) await this.send("Input.dispatchMouseEvent", { type: "mouseMoved", x: point2.x, y: point2.y, button: "left", buttons: 1 });
4496
- const end = path11[path11.length - 1];
4517
+ async dragPath(path12) {
4518
+ if (path12.length < 2) throw new Error("CDP drag requires at least two points.");
4519
+ await this.mouseAt(path12[0].x, path12[0].y, "mousePressed");
4520
+ for (const point of path12.slice(1)) await this.send("Input.dispatchMouseEvent", { type: "mouseMoved", x: point.x, y: point.y, button: "left", buttons: 1 });
4521
+ const end = path12[path12.length - 1];
4497
4522
  await this.mouseAt(end.x, end.y, "mouseReleased");
4498
4523
  }
4499
4524
  async withBackendNode(backendNodeId, functionDeclaration, args = []) {
@@ -4524,7 +4549,7 @@ var CdpTab = class _CdpTab {
4524
4549
  }
4525
4550
  send(method, params = {}) {
4526
4551
  const id = this.nextId++;
4527
- return new Promise((resolve, reject) => {
4552
+ return new Promise((resolve2, reject) => {
4528
4553
  const timer = setTimeout(() => {
4529
4554
  this.pending.delete(id);
4530
4555
  reject(new Error(`CDP command '${method}' timed out after ${COMMAND_TIMEOUT_MS}ms.`));
@@ -4532,7 +4557,7 @@ var CdpTab = class _CdpTab {
4532
4557
  this.pending.set(id, {
4533
4558
  resolve: (result) => {
4534
4559
  clearTimeout(timer);
4535
- resolve(result);
4560
+ resolve2(result);
4536
4561
  },
4537
4562
  reject: (error) => {
4538
4563
  clearTimeout(timer);
@@ -4712,9 +4737,9 @@ async function cdpMouseForContext(contextId, x, y, type, button = "left", clickC
4712
4737
  return true;
4713
4738
  }) === true;
4714
4739
  }
4715
- async function cdpDragForContext(contextId, path11) {
4740
+ async function cdpDragForContext(contextId, path12) {
4716
4741
  return await withCdpContextTab(contextId, async (tab) => {
4717
- await tab.dragPath(path11);
4742
+ await tab.dragPath(path12);
4718
4743
  return true;
4719
4744
  }) === true;
4720
4745
  }
@@ -4944,16 +4969,57 @@ function titlesMatch(tabTitle, windowTitle) {
4944
4969
  return tab === win || win.startsWith(tab) || tab.startsWith(win);
4945
4970
  }
4946
4971
 
4947
- // builtin/extensions/computer-use/src/config.ts
4948
- import { existsSync, readFileSync } from "node:fs";
4972
+ // vendor/computer-use-axi/src/config.ts
4973
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
4949
4974
  import path2 from "node:path";
4950
4975
 
4951
- // builtin/extensions/computer-use/host.ts
4976
+ // src/config.ts
4977
+ import { existsSync, mkdirSync, readFileSync, renameSync } from "fs";
4978
+ import { homedir } from "os";
4979
+ import { dirname, join } from "path";
4980
+ import { fileURLToPath } from "url";
4981
+ var __filename = fileURLToPath(import.meta.url);
4982
+ var __dirname = dirname(__filename);
4983
+ var isBunRuntime = !!process.versions.bun;
4984
+ function getPackageDir() {
4985
+ const envDir = process.env.PIE_PACKAGE_DIR;
4986
+ if (envDir) {
4987
+ if (envDir === "~") return homedir();
4988
+ if (envDir.startsWith("~/")) return homedir() + envDir.slice(1);
4989
+ return envDir;
4990
+ }
4991
+ let dir = __dirname;
4992
+ while (dir !== dirname(dir)) {
4993
+ if (existsSync(join(dir, "package.json"))) {
4994
+ return dir;
4995
+ }
4996
+ dir = dirname(dir);
4997
+ }
4998
+ return __dirname;
4999
+ }
5000
+ function getPackageJsonPath() {
5001
+ return join(getPackageDir(), "package.json");
5002
+ }
5003
+ var pkg = JSON.parse(readFileSync(getPackageJsonPath(), "utf-8"));
5004
+ var CONFIG_DIR_NAME = ".pie";
5005
+ var VERSION = pkg.version;
5006
+ var ENV_AGENT_DIR = "PIE_CODING_AGENT_DIR";
5007
+ function getConfigDir() {
5008
+ const envDir = process.env[ENV_AGENT_DIR];
5009
+ if (envDir) {
5010
+ if (envDir === "~") return homedir();
5011
+ if (envDir.startsWith("~/")) return homedir() + envDir.slice(1);
5012
+ return envDir;
5013
+ }
5014
+ return join(homedir(), CONFIG_DIR_NAME);
5015
+ }
5016
+
5017
+ // vendor/computer-use-axi/host.ts
4952
5018
  function getAgentDir() {
4953
5019
  return getConfigDir();
4954
5020
  }
4955
5021
 
4956
- // builtin/extensions/computer-use/src/config.ts
5022
+ // vendor/computer-use-axi/src/config.ts
4957
5023
  var DEFAULT_CONFIG = {
4958
5024
  browser_use: true,
4959
5025
  headless: false,
@@ -4986,9 +5052,9 @@ function normalizePartial(raw) {
4986
5052
  return out;
4987
5053
  }
4988
5054
  function readConfigFile(filePath) {
4989
- if (!existsSync(filePath)) return { path: filePath, exists: false };
5055
+ if (!existsSync2(filePath)) return { path: filePath, exists: false };
4990
5056
  try {
4991
- const parsed = JSON.parse(readFileSync(filePath, "utf-8"));
5057
+ const parsed = JSON.parse(readFileSync2(filePath, "utf-8"));
4992
5058
  return { path: filePath, exists: true, values: normalizePartial(parsed) };
4993
5059
  } catch (error) {
4994
5060
  return { path: filePath, exists: true, error: error instanceof Error ? error.message : String(error) };
@@ -5024,9 +5090,6 @@ function loadComputerUseConfig(cwd) {
5024
5090
  function getComputerUseConfig() {
5025
5091
  return activeConfig;
5026
5092
  }
5027
- function getLoadedComputerUseConfig() {
5028
- return activeLoadedConfig;
5029
- }
5030
5093
  function isHeadlessMode() {
5031
5094
  return activeConfig.headless;
5032
5095
  }
@@ -5034,7 +5097,7 @@ function isBrowserUseEnabled() {
5034
5097
  return activeConfig.browser_use;
5035
5098
  }
5036
5099
 
5037
- // builtin/extensions/computer-use/src/note.ts
5100
+ // vendor/computer-use-axi/src/note.ts
5038
5101
  function normalizedLabel(value) {
5039
5102
  return value.toLowerCase().replace(/\s+/g, " ").trim();
5040
5103
  }
@@ -5186,10 +5249,111 @@ function renderNote(note) {
5186
5249
  \u2026 note byte budget reached`;
5187
5250
  }
5188
5251
 
5189
- // builtin/extensions/computer-use/src/output.ts
5190
- import { closeSync, mkdtempSync, openSync, readSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
5191
- import os from "node:os";
5252
+ // vendor/computer-use-axi/src/output.ts
5253
+ import { closeSync, mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync4, readSync, readdirSync as readdirSync2, statSync as statSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "node:fs";
5254
+ import path4 from "node:path";
5255
+
5256
+ // vendor/computer-use-axi/src/persist.ts
5257
+ import { randomUUID as randomUUID2 } from "node:crypto";
5258
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3, renameSync as renameSync2, statSync, unlinkSync, writeFileSync } from "node:fs";
5192
5259
  import path3 from "node:path";
5260
+ function stateRootDir(env = process.env) {
5261
+ const override = env.PIE_COMPUTER_USE_STATE_DIR?.trim();
5262
+ if (override) return override;
5263
+ return path3.join(getConfigDir(), "computer-use");
5264
+ }
5265
+ function statesDir(env = process.env) {
5266
+ return path3.join(stateRootDir(env), "states");
5267
+ }
5268
+ function outputsDir(env = process.env) {
5269
+ return path3.join(stateRootDir(env), "outputs");
5270
+ }
5271
+ function runtimeStatePath(env = process.env) {
5272
+ return path3.join(stateRootDir(env), "runtime.json");
5273
+ }
5274
+ function writeJsonAtomic(filePath, value) {
5275
+ mkdirSync2(path3.dirname(filePath), { recursive: true });
5276
+ const temp = `${filePath}.${process.pid}.tmp`;
5277
+ writeFileSync(temp, JSON.stringify(value), "utf8");
5278
+ renameSync2(temp, filePath);
5279
+ }
5280
+ function readJsonFile(filePath) {
5281
+ try {
5282
+ return JSON.parse(readFileSync3(filePath, "utf8"));
5283
+ } catch {
5284
+ return void 0;
5285
+ }
5286
+ }
5287
+ function fileMtime(filePath) {
5288
+ try {
5289
+ return statSync(filePath).mtimeMs;
5290
+ } catch {
5291
+ return 0;
5292
+ }
5293
+ }
5294
+ var DiskStateStore = class {
5295
+ constructor(limit = 128, env = process.env, transform) {
5296
+ this.limit = limit;
5297
+ this.transform = transform;
5298
+ this.dir = statesDir(env);
5299
+ }
5300
+ limit;
5301
+ transform;
5302
+ dir;
5303
+ recordPath(stateId) {
5304
+ if (!/^[A-Za-z0-9-]+$/.test(stateId)) throw new Error(`Invalid stateId: ${stateId}`);
5305
+ return path3.join(this.dir, `${stateId}.json`);
5306
+ }
5307
+ create(resourceKey, epoch, value) {
5308
+ const record = { stateId: randomUUID2(), resourceKey, epoch, value };
5309
+ this.set(record);
5310
+ return record;
5311
+ }
5312
+ set(record) {
5313
+ const persisted = this.transform ? { ...record, value: this.transform(record.value) } : record;
5314
+ writeJsonAtomic(this.recordPath(record.stateId), persisted);
5315
+ this.enforceLimit();
5316
+ }
5317
+ get(stateId) {
5318
+ const filePath = this.recordPath(stateId);
5319
+ if (!existsSync3(filePath)) return void 0;
5320
+ const record = readJsonFile(filePath);
5321
+ if (!record || record.stateId !== stateId) return void 0;
5322
+ return record;
5323
+ }
5324
+ clear() {
5325
+ try {
5326
+ for (const name of readdirSync(this.dir)) {
5327
+ if (name.endsWith(".json")) unlinkSync(path3.join(this.dir, name));
5328
+ }
5329
+ } catch {
5330
+ }
5331
+ }
5332
+ get size() {
5333
+ try {
5334
+ return readdirSync(this.dir).filter((name) => name.endsWith(".json") && !name.endsWith(".tmp")).length;
5335
+ } catch {
5336
+ return 0;
5337
+ }
5338
+ }
5339
+ enforceLimit() {
5340
+ try {
5341
+ const entries = readdirSync(this.dir).filter((name) => name.endsWith(".json")).map((name) => ({ name, mtime: fileMtime(path3.join(this.dir, name)) })).sort((a, b) => b.mtime - a.mtime);
5342
+ for (const entry of entries.slice(this.limit)) {
5343
+ unlinkSync(path3.join(this.dir, entry.name));
5344
+ }
5345
+ } catch {
5346
+ }
5347
+ }
5348
+ };
5349
+ function loadRuntimeStateSnapshot(env = process.env) {
5350
+ return readJsonFile(runtimeStatePath(env));
5351
+ }
5352
+ function persistRuntimeStateSnapshot(snapshot, env = process.env) {
5353
+ writeJsonAtomic(runtimeStatePath(env), snapshot);
5354
+ }
5355
+
5356
+ // vendor/computer-use-axi/src/output.ts
5193
5357
  var MODEL_TEXT_MAX_BYTES = 48 * 1024;
5194
5358
  var MODEL_TEXT_MAX_LINES = 2e3;
5195
5359
  var OUTPUT_PAGE_BYTES = 16 * 1024;
@@ -5201,6 +5365,53 @@ var outputs = /* @__PURE__ */ new Map();
5201
5365
  var outputDirectory;
5202
5366
  var outputBytes = 0;
5203
5367
  var nextOutputId = 1;
5368
+ var outputsScanned = false;
5369
+ function ensureOutputDirectory() {
5370
+ if (!outputDirectory) {
5371
+ outputDirectory = outputsDir();
5372
+ mkdirSync3(outputDirectory, { recursive: true });
5373
+ }
5374
+ if (!outputsScanned) {
5375
+ outputsScanned = true;
5376
+ try {
5377
+ for (const name of readdirSync2(outputDirectory)) {
5378
+ const match = /^o(\d+)\.meta\.json$/.exec(name);
5379
+ if (!match) continue;
5380
+ const id = Number(match[1]);
5381
+ if (Number.isFinite(id) && id >= nextOutputId) nextOutputId = id + 1;
5382
+ const metaPath = path4.join(outputDirectory, name);
5383
+ try {
5384
+ const meta = JSON.parse(readFileSyncText(metaPath));
5385
+ if (!meta.ref || typeof meta.ref !== "string") continue;
5386
+ const filePath = path4.join(outputDirectory, `${meta.ref.slice(2)}.txt`);
5387
+ if (!statSyncSafe(filePath)) continue;
5388
+ outputs.set(meta.ref, {
5389
+ ref: meta.ref,
5390
+ filePath,
5391
+ storedBytes: Math.max(0, Math.trunc(meta.storedBytes ?? 0)),
5392
+ totalBytes: Math.max(0, Math.trunc(meta.totalBytes ?? meta.storedBytes ?? 0)),
5393
+ complete: meta.complete === true
5394
+ });
5395
+ outputBytes += Math.max(0, Math.trunc(meta.storedBytes ?? 0));
5396
+ } catch {
5397
+ }
5398
+ }
5399
+ } catch {
5400
+ }
5401
+ }
5402
+ return outputDirectory;
5403
+ }
5404
+ function readFileSyncText(filePath) {
5405
+ return readFileSync4(filePath, "utf8");
5406
+ }
5407
+ function statSyncSafe(filePath) {
5408
+ try {
5409
+ statSync2(filePath);
5410
+ return true;
5411
+ } catch {
5412
+ return false;
5413
+ }
5414
+ }
5204
5415
  function utf8Prefix(bytes, maxBytes) {
5205
5416
  if (bytes.byteLength <= maxBytes) return bytes;
5206
5417
  let end = Math.max(0, maxBytes);
@@ -5215,10 +5426,11 @@ function boundedPrefix(value, maxBytes, maxLines) {
5215
5426
  function storeOutput(value) {
5216
5427
  const encoded = new TextEncoder().encode(value);
5217
5428
  const stored = encoded.byteLength > OUTPUT_ENTRY_MAX_BYTES ? utf8Prefix(encoded, OUTPUT_ENTRY_MAX_BYTES) : encoded;
5218
- outputDirectory ??= mkdtempSync(path3.join(os.tmpdir(), "pie-computer-use-output-"));
5429
+ const directory = ensureOutputDirectory();
5219
5430
  const ref = `@o${nextOutputId++}`;
5220
- const filePath = path3.join(outputDirectory, `${ref.slice(2)}.txt`);
5221
- writeFileSync(filePath, stored, { mode: 384 });
5431
+ const filePath = path4.join(directory, `${ref.slice(2)}.txt`);
5432
+ writeFileSync2(filePath, stored, { mode: 384 });
5433
+ writeFileSync2(path4.join(directory, `${ref.slice(2)}.meta.json`), JSON.stringify({ ref, storedBytes: stored.byteLength, totalBytes: encoded.byteLength, complete: stored.byteLength === encoded.byteLength }), { mode: 384 });
5222
5434
  const entry = { ref, filePath, storedBytes: stored.byteLength, totalBytes: encoded.byteLength, complete: stored.byteLength === encoded.byteLength };
5223
5435
  outputs.set(entry.ref, entry);
5224
5436
  outputBytes += entry.storedBytes;
@@ -5229,7 +5441,11 @@ function storeOutput(value) {
5229
5441
  outputs.delete(oldestRef);
5230
5442
  outputBytes -= oldest.storedBytes;
5231
5443
  try {
5232
- unlinkSync(oldest.filePath);
5444
+ unlinkSync2(oldest.filePath);
5445
+ } catch {
5446
+ }
5447
+ try {
5448
+ unlinkSync2(path4.join(directory, `${oldestRef.slice(2)}.meta.json`));
5233
5449
  } catch {
5234
5450
  }
5235
5451
  }
@@ -5278,7 +5494,11 @@ refine: ${refinementFor(tool)}
5278
5494
  continue: read_text({ ref: "${entry.ref}", offset: ${returnedBytes} })${storageNote}`);
5279
5495
  }
5280
5496
  function readStoredOutput(ref, offsetValue) {
5281
- const entry = outputs.get(ref);
5497
+ let entry = outputs.get(ref);
5498
+ if (!entry) {
5499
+ ensureOutputDirectory();
5500
+ entry = outputs.get(ref);
5501
+ }
5282
5502
  if (!entry) return void 0;
5283
5503
  let offset = Math.min(entry.storedBytes, Math.max(0, Math.trunc(typeof offsetValue === "number" && Number.isFinite(offsetValue) ? offsetValue : 0)));
5284
5504
  const requestedBytes = Math.min(entry.storedBytes - offset, OUTPUT_PAGE_BYTES + 4);
@@ -5303,56 +5523,29 @@ function readStoredOutput(ref, offsetValue) {
5303
5523
  complete: entry.complete
5304
5524
  };
5305
5525
  }
5306
- function clearStoredOutputs() {
5307
- outputs.clear();
5308
- if (outputDirectory) {
5309
- try {
5310
- rmSync(outputDirectory, { recursive: true, force: true });
5311
- } catch {
5312
- }
5313
- }
5314
- outputDirectory = void 0;
5315
- outputBytes = 0;
5316
- nextOutputId = 1;
5317
- }
5318
-
5319
- // builtin/extensions/computer-use/src/contract.ts
5320
- var AGENT_TOOL_NAMES = /* @__PURE__ */ new Set([
5321
- "find_roots",
5322
- "read_text",
5323
- "wait_for",
5324
- "observe_ui",
5325
- "search_ui",
5326
- "expand_ui",
5327
- "inspect_ui",
5328
- "act_ui",
5329
- "navigate_browser",
5330
- "evaluate_browser",
5331
- "launch_browser"
5332
- ]);
5333
5526
 
5334
- // builtin/extensions/computer-use/src/platform/macos/helper.ts
5527
+ // vendor/computer-use-axi/src/platform/macos/helper.ts
5335
5528
  import { spawn } from "node:child_process";
5336
5529
  import { constants as fsConstants2 } from "node:fs";
5337
5530
  import { access, mkdir, realpath } from "node:fs/promises";
5338
5531
  import net from "node:net";
5339
- import os3 from "node:os";
5340
- import path6 from "node:path";
5341
-
5342
- // builtin/extensions/computer-use/src/platform/macos/helper-path.mjs
5343
- import { accessSync, constants as fsConstants, existsSync as existsSync2 } from "node:fs";
5344
5532
  import os2 from "node:os";
5345
- import path4 from "node:path";
5533
+ import path7 from "node:path";
5534
+
5535
+ // vendor/computer-use-axi/src/platform/macos/helper-path.mjs
5536
+ import { accessSync, constants as fsConstants, existsSync as existsSync4 } from "node:fs";
5537
+ import os from "node:os";
5538
+ import path5 from "node:path";
5346
5539
  var HELPER_APP_NAME = "pie-computer-use.app";
5347
- var SYSTEM_HELPER_APP_PATH = path4.join("/Applications", HELPER_APP_NAME);
5540
+ var SYSTEM_HELPER_APP_PATH = path5.join("/Applications", HELPER_APP_NAME);
5348
5541
  function resolveMacosHelperAppPath(options = {}) {
5349
5542
  const env = options.env ?? process.env;
5350
5543
  const explicitPath = env.PIE_COMPUTER_USE_HELPER_APP_PATH?.trim();
5351
- if (explicitPath) return path4.resolve(explicitPath);
5352
- const homeDir = options.homeDir ?? os2.homedir();
5544
+ if (explicitPath) return path5.resolve(explicitPath);
5545
+ const homeDir = options.homeDir ?? os.homedir();
5353
5546
  const configDir = options.configDir ?? resolvePieConfigDir(env, homeDir);
5354
5547
  const systemHelperAppPath = options.systemHelperAppPath ?? SYSTEM_HELPER_APP_PATH;
5355
- const fileExists = options.fileExists ?? existsSync2;
5548
+ const fileExists = options.fileExists ?? existsSync4;
5356
5549
  const directoryIsWritable = options.directoryIsWritable ?? ((directoryPath) => {
5357
5550
  try {
5358
5551
  accessSync(directoryPath, fsConstants.W_OK);
@@ -5361,10 +5554,10 @@ function resolveMacosHelperAppPath(options = {}) {
5361
5554
  return false;
5362
5555
  }
5363
5556
  });
5364
- if (fileExists(systemHelperAppPath) && directoryIsWritable(path4.dirname(systemHelperAppPath))) {
5557
+ if (fileExists(systemHelperAppPath) && directoryIsWritable(path5.dirname(systemHelperAppPath))) {
5365
5558
  return systemHelperAppPath;
5366
5559
  }
5367
- return path4.join(configDir, "computer-use", HELPER_APP_NAME);
5560
+ return path5.join(configDir, "computer-use", HELPER_APP_NAME);
5368
5561
  }
5369
5562
  function resolvePieConfigDir(env, homeDir) {
5370
5563
  const envDir = env.PIE_CODING_AGENT_DIR;
@@ -5373,37 +5566,37 @@ function resolvePieConfigDir(env, homeDir) {
5373
5566
  if (envDir.startsWith("~/")) return homeDir + envDir.slice(1);
5374
5567
  return envDir;
5375
5568
  }
5376
- return path4.join(homeDir, ".pie");
5569
+ return path5.join(homeDir, ".pie");
5377
5570
  }
5378
5571
 
5379
- // builtin/extensions/computer-use/src/platform/package-root.ts
5380
- import { existsSync as existsSync3 } from "node:fs";
5381
- import path5 from "node:path";
5382
- import { fileURLToPath } from "node:url";
5572
+ // vendor/computer-use-axi/src/platform/package-root.ts
5573
+ import { existsSync as existsSync5 } from "node:fs";
5574
+ import path6 from "node:path";
5575
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
5383
5576
  function resolveExtensionRoot(moduleUrl) {
5384
5577
  const override = process.env.PIE_COMPUTER_USE_PACKAGE_ROOT?.trim();
5385
- if (override) return path5.resolve(override);
5386
- let dir = path5.dirname(fileURLToPath(moduleUrl));
5578
+ if (override) return path6.resolve(override);
5579
+ let dir = path6.dirname(fileURLToPath2(moduleUrl));
5387
5580
  for (let depth = 0; depth < 12; depth += 1) {
5388
- if (existsSync3(path5.join(dir, "scripts", "setup-helper.mjs"))) return dir;
5389
- const parent = path5.dirname(dir);
5581
+ if (existsSync5(path6.join(dir, "scripts", "setup-helper.mjs"))) return dir;
5582
+ const parent = path6.dirname(dir);
5390
5583
  if (parent === dir) break;
5391
5584
  dir = parent;
5392
5585
  }
5393
- throw new Error(`computer-use: could not locate extension root (scripts/setup-helper.mjs) above ${path5.dirname(fileURLToPath(moduleUrl))}. Set PIE_COMPUTER_USE_PACKAGE_ROOT.`);
5586
+ throw new Error(`computer-use: could not locate extension root (scripts/setup-helper.mjs) above ${path6.dirname(fileURLToPath2(moduleUrl))}. Set PIE_COMPUTER_USE_PACKAGE_ROOT.`);
5394
5587
  }
5395
5588
 
5396
- // builtin/extensions/computer-use/src/platform/macos/helper.ts
5589
+ // vendor/computer-use-axi/src/platform/macos/helper.ts
5397
5590
  var COMMAND_TIMEOUT_MS2 = 15e3;
5398
5591
  var HELPER_PROTOCOL_VERSION = 6;
5399
5592
  var HELPER_SETUP_TIMEOUT_MS = 6e4;
5400
5593
  var HELPER_APP_PATH = resolveMacosHelperAppPath();
5401
- var HELPER_APP_EXECUTABLE_PATH = path6.join(HELPER_APP_PATH, "Contents", "MacOS", "pie-computer-use");
5402
- var DEFAULT_HELPER_SOCKET_PATH = path6.join(os3.homedir(), "Library", "Caches", "pie-computer-use", "bridge.sock");
5594
+ var HELPER_APP_EXECUTABLE_PATH = path7.join(HELPER_APP_PATH, "Contents", "MacOS", "pie-computer-use");
5595
+ var DEFAULT_HELPER_SOCKET_PATH = path7.join(os2.homedir(), "Library", "Caches", "pie-computer-use", "bridge.sock");
5403
5596
  var HELPER_SOCKET_PATH = process.env.PIE_COMPUTER_USE_SOCKET_PATH ?? DEFAULT_HELPER_SOCKET_PATH;
5404
5597
  var usingExternalHelperSocket = HELPER_SOCKET_PATH !== DEFAULT_HELPER_SOCKET_PATH;
5405
5598
  var PACKAGE_ROOT = resolveExtensionRoot(import.meta.url);
5406
- var SETUP_HELPER_SCRIPT = path6.join(PACKAGE_ROOT, "scripts", "setup-helper.mjs");
5599
+ var SETUP_HELPER_SCRIPT = path7.join(PACKAGE_ROOT, "scripts", "setup-helper.mjs");
5407
5600
  var HelperTransportError = class extends Error {
5408
5601
  constructor(message) {
5409
5602
  super(message);
@@ -5423,8 +5616,8 @@ function throwIfAborted(signal) {
5423
5616
  }
5424
5617
  async function sleep(ms, signal) {
5425
5618
  throwIfAborted(signal);
5426
- await new Promise((resolve, reject) => {
5427
- const timer = setTimeout(resolve, ms);
5619
+ await new Promise((resolve2, reject) => {
5620
+ const timer = setTimeout(resolve2, ms);
5428
5621
  const onAbort = () => {
5429
5622
  clearTimeout(timer);
5430
5623
  reject(new Error("Operation aborted."));
@@ -5443,14 +5636,14 @@ async function isExecutable(filePath) {
5443
5636
  async function isResolvedHelperExecutable(filePath) {
5444
5637
  if (!filePath) return true;
5445
5638
  const [actualPath, expectedPath] = await Promise.all([
5446
- realpath(filePath).catch(() => path6.resolve(filePath)),
5447
- realpath(HELPER_APP_EXECUTABLE_PATH).catch(() => path6.resolve(HELPER_APP_EXECUTABLE_PATH))
5639
+ realpath(filePath).catch(() => path7.resolve(filePath)),
5640
+ realpath(HELPER_APP_EXECUTABLE_PATH).catch(() => path7.resolve(HELPER_APP_EXECUTABLE_PATH))
5448
5641
  ]);
5449
5642
  return actualPath === expectedPath;
5450
5643
  }
5451
5644
  async function runProcess(command, args, timeoutMs, signal, env) {
5452
5645
  throwIfAborted(signal);
5453
- await new Promise((resolve, reject) => {
5646
+ await new Promise((resolve2, reject) => {
5454
5647
  const child = spawn(command, args, {
5455
5648
  stdio: ["ignore", "pipe", "pipe"],
5456
5649
  env
@@ -5484,7 +5677,7 @@ async function runProcess(command, args, timeoutMs, signal, env) {
5484
5677
  child.on("close", (code) => {
5485
5678
  cleanup();
5486
5679
  if (code === 0) {
5487
- resolve();
5680
+ resolve2();
5488
5681
  return;
5489
5682
  }
5490
5683
  const output = [stderr.trim(), stdout.trim()].filter(Boolean).join("\n");
@@ -5517,11 +5710,11 @@ var MacosHelperClient = class {
5517
5710
  }
5518
5711
  async launchDaemon(signal) {
5519
5712
  if (usingExternalHelperSocket) throw new HelperTransportError(`External helper socket is unavailable at ${HELPER_SOCKET_PATH}.`);
5520
- await mkdir(path6.dirname(HELPER_SOCKET_PATH), { recursive: true });
5713
+ await mkdir(path7.dirname(HELPER_SOCKET_PATH), { recursive: true });
5521
5714
  await runProcess("open", ["-n", "-g", HELPER_APP_PATH, "--args", "serve", "--socket", HELPER_SOCKET_PATH], COMMAND_TIMEOUT_MS2, signal);
5522
5715
  }
5523
5716
  async daemonCommand(cmd, args, timeoutMs, signal) {
5524
- return await new Promise((resolve, reject) => {
5717
+ return await new Promise((resolve2, reject) => {
5525
5718
  const id = `req_${++this.requestSequence}`;
5526
5719
  const socket = net.createConnection(HELPER_SOCKET_PATH);
5527
5720
  let buffer = "";
@@ -5550,7 +5743,7 @@ var MacosHelperClient = class {
5550
5743
  socket.end();
5551
5744
  try {
5552
5745
  const parsed = JSON.parse(buffer.slice(0, newline));
5553
- if (parsed.ok === true) resolve(parsed.result);
5746
+ if (parsed.ok === true) resolve2(parsed.result);
5554
5747
  else reject(new HelperCommandError(parsed?.error?.message ?? `Daemon command '${cmd}' failed.`, parsed?.error?.code));
5555
5748
  } catch (error) {
5556
5749
  reject(error);
@@ -5640,7 +5833,7 @@ var MacosHelperClient = class {
5640
5833
  };
5641
5834
  var macosHelper = new MacosHelperClient();
5642
5835
 
5643
- // builtin/extensions/computer-use/src/platform/macos/backend.ts
5836
+ // vendor/computer-use-axi/src/platform/macos/backend.ts
5644
5837
  function parseApps(result) {
5645
5838
  const array = Array.isArray(result) ? result : result?.apps;
5646
5839
  if (!Array.isArray(array)) return [];
@@ -5751,7 +5944,7 @@ var macosBackend = {
5751
5944
  }
5752
5945
  };
5753
5946
 
5754
- // builtin/extensions/computer-use/src/platform/macos/browser.ts
5947
+ // vendor/computer-use-axi/src/platform/macos/browser.ts
5755
5948
  var BROWSER_WINDOW_OPEN_TIMEOUT_MS = 1e4;
5756
5949
  var BROWSER_BUNDLE_IDS = /* @__PURE__ */ new Set([
5757
5950
  "com.apple.Safari",
@@ -5849,7 +6042,7 @@ async function openBrowserLocationWithAppleScript(target, url, signal) {
5849
6042
  }
5850
6043
  }
5851
6044
 
5852
- // builtin/extensions/computer-use/src/permissions.ts
6045
+ // vendor/computer-use-axi/src/permissions.ts
5853
6046
  function throwIfAborted2(signal) {
5854
6047
  if (signal?.aborted) throw new Error("Operation aborted.");
5855
6048
  }
@@ -5892,7 +6085,7 @@ async function ensurePermissions(ctx, bridge, helperPath, signal) {
5892
6085
  return status;
5893
6086
  }
5894
6087
 
5895
- // builtin/extensions/computer-use/src/platform/architecture.ts
6088
+ // vendor/computer-use-axi/src/platform/architecture.ts
5896
6089
  var PLATFORM_ARCHITECTURE_VERSION = 1;
5897
6090
  var REQUIRED_PLATFORM_INVARIANTS = [
5898
6091
  "state-scoped-observations",
@@ -5914,7 +6107,7 @@ function assertPlatformArchitecture(platform, diagnostics) {
5914
6107
  }
5915
6108
  }
5916
6109
 
5917
- // builtin/extensions/computer-use/src/platform/macos/permissions.ts
6110
+ // vendor/computer-use-axi/src/platform/macos/permissions.ts
5918
6111
  var GRANT_INSTRUCTIONS = "Grant Accessibility and Screen Recording to pie-computer-use.app in System Settings \u2192 Privacy & Security. Screen Recording lets the agent see the window; Accessibility lets it interact with the window.";
5919
6112
  var SIGNING_MIGRATION_WARNING = "If these permissions were enabled before this install/update, macOS invalidated the old grants because pie-computer-use.app was re-signed. Re-enable both toggles for the newly signed helper. If a toggle is already on, switch it off and on again.";
5920
6113
  var macosPermissionKinds = [
@@ -6033,18 +6226,18 @@ Helper path: ${helperPath}`,
6033
6226
  return { permissionStatus, lastPermissionCheckAt, helperDiagnostics };
6034
6227
  }
6035
6228
 
6036
- // builtin/extensions/computer-use/src/platform/linux/helper.ts
6229
+ // vendor/computer-use-axi/src/platform/linux/helper.ts
6037
6230
  import { spawn as spawn2 } from "node:child_process";
6038
- import { randomUUID as randomUUID2 } from "node:crypto";
6231
+ import { randomUUID as randomUUID3 } from "node:crypto";
6039
6232
  import { constants as fsConstants3 } from "node:fs";
6040
6233
  import { access as access2 } from "node:fs/promises";
6041
- import path7 from "node:path";
6234
+ import path8 from "node:path";
6042
6235
  var PACKAGE_ROOT2 = resolveExtensionRoot(import.meta.url);
6043
- var SETUP_HELPER_SCRIPT2 = path7.join(PACKAGE_ROOT2, "scripts", "setup-helper.mjs");
6236
+ var SETUP_HELPER_SCRIPT2 = path8.join(PACKAGE_ROOT2, "scripts", "setup-helper.mjs");
6044
6237
  var HELPER_SETUP_TIMEOUT_MS2 = 6e4;
6045
6238
  var COMMAND_TIMEOUT_MS3 = 15e3;
6046
6239
  var LINUX_HELPER_PROTOCOL_VERSION = 4;
6047
- var LINUX_HELPER_PATH = process.env.PIE_COMPUTER_USE_LINUX_HELPER_PATH || path7.join(getAgentDir(), "helpers", "computer-use", "linux-bridge");
6240
+ var LINUX_HELPER_PATH = process.env.PIE_COMPUTER_USE_LINUX_HELPER_PATH || path8.join(getAgentDir(), "helpers", "computer-use", "linux-bridge");
6048
6241
  async function isExecutable2(filePath) {
6049
6242
  try {
6050
6243
  await access2(filePath, fsConstants3.X_OK);
@@ -6055,7 +6248,7 @@ async function isExecutable2(filePath) {
6055
6248
  }
6056
6249
  async function runProcess2(command, args, timeoutMs, signal, env) {
6057
6250
  if (signal?.aborted) throw new Error("Operation aborted.");
6058
- await new Promise((resolve, reject) => {
6251
+ await new Promise((resolve2, reject) => {
6059
6252
  const child = spawn2(command, args, { stdio: ["ignore", "pipe", "pipe"], env });
6060
6253
  let stdout = "";
6061
6254
  let stderr = "";
@@ -6066,7 +6259,7 @@ async function runProcess2(command, args, timeoutMs, signal, env) {
6066
6259
  clearTimeout(timer);
6067
6260
  signal?.removeEventListener("abort", onAbort);
6068
6261
  if (error) reject(error);
6069
- else resolve();
6262
+ else resolve2();
6070
6263
  };
6071
6264
  const timer = setTimeout(() => {
6072
6265
  child.kill("SIGTERM");
@@ -6095,13 +6288,13 @@ ${output}`.trim()));
6095
6288
  async function waitForShared(promise, signal) {
6096
6289
  if (!signal) return await promise;
6097
6290
  if (signal.aborted) throw new Error("Operation aborted.");
6098
- return await new Promise((resolve, reject) => {
6291
+ return await new Promise((resolve2, reject) => {
6099
6292
  const onAbort = () => reject(new Error("Operation aborted."));
6100
6293
  signal.addEventListener("abort", onAbort, { once: true });
6101
6294
  promise.then(
6102
6295
  (value) => {
6103
6296
  signal.removeEventListener("abort", onAbort);
6104
- resolve(value);
6297
+ resolve2(value);
6105
6298
  },
6106
6299
  (error) => {
6107
6300
  signal.removeEventListener("abort", onAbort);
@@ -6203,8 +6396,8 @@ var LinuxHelperClient = class {
6203
6396
  });
6204
6397
  this.child = child;
6205
6398
  this.buffer = "";
6206
- return await new Promise((resolve, reject) => {
6207
- child.once("spawn", () => resolve(child));
6399
+ return await new Promise((resolve2, reject) => {
6400
+ child.once("spawn", () => resolve2(child));
6208
6401
  child.once("error", reject);
6209
6402
  });
6210
6403
  }
@@ -6239,9 +6432,9 @@ var LinuxHelperClient = class {
6239
6432
  }
6240
6433
  async command(cmd, args = {}, options) {
6241
6434
  const child = await this.process(options?.signal);
6242
- const id = randomUUID2();
6435
+ const id = randomUUID3();
6243
6436
  const timeoutMs = options?.timeoutMs ?? COMMAND_TIMEOUT_MS3;
6244
- return await new Promise((resolve, reject) => {
6437
+ return await new Promise((resolve2, reject) => {
6245
6438
  const onAbort = () => {
6246
6439
  this.pending.delete(id);
6247
6440
  clearTimeout(timer);
@@ -6255,7 +6448,7 @@ var LinuxHelperClient = class {
6255
6448
  this.pending.set(id, {
6256
6449
  resolve: (value) => {
6257
6450
  options?.signal?.removeEventListener("abort", onAbort);
6258
- resolve(value);
6451
+ resolve2(value);
6259
6452
  },
6260
6453
  reject: (error) => {
6261
6454
  options?.signal?.removeEventListener("abort", onAbort);
@@ -6277,7 +6470,7 @@ var LinuxHelperClient = class {
6277
6470
  };
6278
6471
  var linuxHelper = new LinuxHelperClient();
6279
6472
 
6280
- // builtin/extensions/computer-use/src/platform/linux/backend.ts
6473
+ // vendor/computer-use-axi/src/platform/linux/backend.ts
6281
6474
  function normalizedProcessName(appName) {
6282
6475
  return appName.toLowerCase().split("/").pop().replace(/\.desktop$/i, "");
6283
6476
  }
@@ -6433,18 +6626,18 @@ var linuxBackend = {
6433
6626
  }
6434
6627
  };
6435
6628
 
6436
- // builtin/extensions/computer-use/src/platform/windows/helper.ts
6629
+ // vendor/computer-use-axi/src/platform/windows/helper.ts
6437
6630
  import { spawn as spawn3 } from "node:child_process";
6438
- import { randomUUID as randomUUID3 } from "node:crypto";
6631
+ import { randomUUID as randomUUID4 } from "node:crypto";
6439
6632
  import { constants as fsConstants4 } from "node:fs";
6440
6633
  import { access as access3 } from "node:fs/promises";
6441
- import path8 from "node:path";
6634
+ import path9 from "node:path";
6442
6635
  var PACKAGE_ROOT3 = resolveExtensionRoot(import.meta.url);
6443
- var SETUP_HELPER_SCRIPT3 = path8.join(PACKAGE_ROOT3, "scripts", "setup-helper.mjs");
6636
+ var SETUP_HELPER_SCRIPT3 = path9.join(PACKAGE_ROOT3, "scripts", "setup-helper.mjs");
6444
6637
  var HELPER_SETUP_TIMEOUT_MS3 = 6e4;
6445
6638
  var COMMAND_TIMEOUT_MS4 = 15e3;
6446
6639
  var WINDOWS_HELPER_PROTOCOL_VERSION = 4;
6447
- var WINDOWS_HELPER_PATH = process.env.PIE_COMPUTER_USE_WINDOWS_HELPER_PATH || path8.join(getAgentDir(), "helpers", "computer-use", "windows-bridge.exe");
6640
+ var WINDOWS_HELPER_PATH = process.env.PIE_COMPUTER_USE_WINDOWS_HELPER_PATH || path9.join(getAgentDir(), "helpers", "computer-use", "windows-bridge.exe");
6448
6641
  async function isExecutable3(filePath) {
6449
6642
  try {
6450
6643
  await access3(filePath, fsConstants4.X_OK);
@@ -6455,7 +6648,7 @@ async function isExecutable3(filePath) {
6455
6648
  }
6456
6649
  async function runProcess3(command, args, timeoutMs, signal, env) {
6457
6650
  if (signal?.aborted) throw new Error("Operation aborted.");
6458
- await new Promise((resolve, reject) => {
6651
+ await new Promise((resolve2, reject) => {
6459
6652
  const child = spawn3(command, args, { stdio: ["ignore", "pipe", "pipe"], env });
6460
6653
  let stdout = "";
6461
6654
  let stderr = "";
@@ -6485,7 +6678,7 @@ async function runProcess3(command, args, timeoutMs, signal, env) {
6485
6678
  });
6486
6679
  child.on("close", (code) => {
6487
6680
  cleanup();
6488
- if (code === 0) return resolve();
6681
+ if (code === 0) return resolve2();
6489
6682
  const output = [stderr.trim(), stdout.trim()].filter(Boolean).join("\n");
6490
6683
  reject(new Error(`Command failed (${code}): ${command} ${args.join(" ")}
6491
6684
  ${output}`.trim()));
@@ -6570,14 +6763,14 @@ var WindowsHelperClient = class {
6570
6763
  }
6571
6764
  async command(cmd, args = {}, options) {
6572
6765
  const child = await this.process(options?.signal);
6573
- const id = randomUUID3();
6766
+ const id = randomUUID4();
6574
6767
  const timeoutMs = options?.timeoutMs ?? COMMAND_TIMEOUT_MS4;
6575
- return await new Promise((resolve, reject) => {
6768
+ return await new Promise((resolve2, reject) => {
6576
6769
  const timer = setTimeout(() => {
6577
6770
  this.pending.delete(id);
6578
6771
  reject(new Error(`Helper command '${cmd}' timed out after ${timeoutMs}ms.`));
6579
6772
  }, timeoutMs);
6580
- this.pending.set(id, { resolve, reject, timer });
6773
+ this.pending.set(id, { resolve: resolve2, reject, timer });
6581
6774
  child.stdin.write(`${JSON.stringify({ protocolVersion: WINDOWS_HELPER_PROTOCOL_VERSION, id, cmd, args })}
6582
6775
  `, (error) => {
6583
6776
  if (!error) return;
@@ -6590,7 +6783,7 @@ var WindowsHelperClient = class {
6590
6783
  };
6591
6784
  var windowsHelper = new WindowsHelperClient();
6592
6785
 
6593
- // builtin/extensions/computer-use/src/platform/windows/backend.ts
6786
+ // vendor/computer-use-axi/src/platform/windows/backend.ts
6594
6787
  function normalizedProcessName2(appName) {
6595
6788
  return appName.toLowerCase().replace(/\.exe$/i, "");
6596
6789
  }
@@ -6726,7 +6919,7 @@ var windowsBackend = {
6726
6919
  }
6727
6920
  };
6728
6921
 
6729
- // builtin/extensions/computer-use/src/platform/index.ts
6922
+ // vendor/computer-use-axi/src/platform/index.ts
6730
6923
  var macosPlatformBackend = {
6731
6924
  name: "macos",
6732
6925
  ensureReady: ensureMacosReady,
@@ -6798,8 +6991,8 @@ function platformBackendForRuntime(platform = process.platform) {
6798
6991
  }
6799
6992
  var currentPlatformBackend = platformBackendForRuntime();
6800
6993
 
6801
- // builtin/extensions/computer-use/src/runtime.ts
6802
- import { randomUUID as randomUUID4 } from "node:crypto";
6994
+ // vendor/computer-use-axi/src/runtime.ts
6995
+ import { randomUUID as randomUUID5 } from "node:crypto";
6803
6996
  var StaleResourceStateError = class extends Error {
6804
6997
  constructor(resourceKey, expectedEpoch, actualEpoch) {
6805
6998
  super(`State is stale for ${resourceKey}: expected epoch ${expectedEpoch}, current epoch ${actualEpoch}.`);
@@ -6819,7 +7012,7 @@ var StateStore = class {
6819
7012
  limit;
6820
7013
  records = /* @__PURE__ */ new Map();
6821
7014
  create(resourceKey, epoch, value) {
6822
- const record = { stateId: randomUUID4(), resourceKey, epoch, value };
7015
+ const record = { stateId: randomUUID5(), resourceKey, epoch, value };
6823
7016
  this.set(record);
6824
7017
  return record;
6825
7018
  }
@@ -6832,8 +7025,8 @@ var StateStore = class {
6832
7025
  this.records.delete(oldest);
6833
7026
  }
6834
7027
  }
6835
- get(stateId2) {
6836
- return this.records.get(stateId2);
7028
+ get(stateId) {
7029
+ return this.records.get(stateId);
6837
7030
  }
6838
7031
  clear() {
6839
7032
  this.records.clear();
@@ -6843,8 +7036,16 @@ var StateStore = class {
6843
7036
  }
6844
7037
  };
6845
7038
  var ResourceScheduler = class {
7039
+ constructor(hooks = {}) {
7040
+ this.hooks = hooks;
7041
+ }
7042
+ hooks;
6846
7043
  resources = /* @__PURE__ */ new Map();
6847
7044
  closed = false;
7045
+ /** Current (resourceKey, epoch) pairs for persistence. */
7046
+ epochs() {
7047
+ return [...this.resources.entries()].map(([key, record]) => [key, record.epoch]);
7048
+ }
6848
7049
  epoch(resourceKey) {
6849
7050
  return this.resource(resourceKey).epoch;
6850
7051
  }
@@ -6866,6 +7067,7 @@ var ResourceScheduler = class {
6866
7067
  if (record.epoch !== baseEpoch) throw new StaleResourceStateError(resourceKey, baseEpoch, record.epoch);
6867
7068
  const nextEpoch = record.epoch + 1;
6868
7069
  record.epoch = nextEpoch;
7070
+ this.hooks.onEpochChange?.(resourceKey, nextEpoch);
6869
7071
  return { value: await work(nextEpoch), epoch: nextEpoch };
6870
7072
  });
6871
7073
  }
@@ -6890,8 +7092,8 @@ var ResourceScheduler = class {
6890
7092
  const record = this.resource(resourceKey);
6891
7093
  const previous = record.tail;
6892
7094
  let release;
6893
- const next = new Promise((resolve) => {
6894
- release = resolve;
7095
+ const next = new Promise((resolve2) => {
7096
+ release = resolve2;
6895
7097
  });
6896
7098
  record.tail = previous.catch(() => void 0).then(() => next);
6897
7099
  await previous.catch(() => void 0);
@@ -6904,11 +7106,11 @@ var ResourceScheduler = class {
6904
7106
  }
6905
7107
  };
6906
7108
 
6907
- // builtin/extensions/computer-use/src/browser-owner.ts
7109
+ // vendor/computer-use-axi/src/browser-owner.ts
6908
7110
  import { execFile } from "node:child_process";
6909
7111
  import { rm } from "node:fs/promises";
6910
- import os4 from "node:os";
6911
- import path9 from "node:path";
7112
+ import os3 from "node:os";
7113
+ import path10 from "node:path";
6912
7114
  async function requestBrowserClose(port) {
6913
7115
  const response = await fetch(`http://127.0.0.1:${port}/json/version`, { signal: AbortSignal.timeout(500) });
6914
7116
  const data = await response.json();
@@ -6916,7 +7118,7 @@ async function requestBrowserClose(port) {
6916
7118
  const url = new URL(data.webSocketDebuggerUrl);
6917
7119
  if (url.hostname !== "127.0.0.1" && url.hostname !== "localhost") throw new Error("Owned browser exposed a non-local debugger.");
6918
7120
  if (url.port !== port) throw new Error("Owned browser debugger port changed.");
6919
- await new Promise((resolve) => {
7121
+ await new Promise((resolve2) => {
6920
7122
  const ws = new wrapper_default(url);
6921
7123
  let done = false;
6922
7124
  const finish = () => {
@@ -6924,7 +7126,7 @@ async function requestBrowserClose(port) {
6924
7126
  done = true;
6925
7127
  clearTimeout(timer);
6926
7128
  ws.terminate();
6927
- resolve();
7129
+ resolve2();
6928
7130
  };
6929
7131
  const timer = setTimeout(finish, 700);
6930
7132
  ws.on("open", () => ws.send(JSON.stringify({ id: 1, method: "Browser.close" })));
@@ -6935,15 +7137,15 @@ async function requestBrowserClose(port) {
6935
7137
  }
6936
7138
  async function waitForExit(child, timeoutMs) {
6937
7139
  if (child.exitCode !== null || child.signalCode !== null) return true;
6938
- return new Promise((resolve) => {
7140
+ return new Promise((resolve2) => {
6939
7141
  const finish = () => {
6940
7142
  clearTimeout(timer);
6941
7143
  child.off("exit", finish);
6942
- resolve(true);
7144
+ resolve2(true);
6943
7145
  };
6944
7146
  const timer = setTimeout(() => {
6945
7147
  child.off("exit", finish);
6946
- resolve(false);
7148
+ resolve2(false);
6947
7149
  }, timeoutMs);
6948
7150
  child.once("exit", finish);
6949
7151
  });
@@ -6954,11 +7156,11 @@ async function releaseOwnedBrowser(child, port, profile) {
6954
7156
  if (!await waitForExit(child, 700)) {
6955
7157
  if (process.platform === "win32" && child.pid) {
6956
7158
  const pid = child.pid;
6957
- await new Promise((resolve) => {
7159
+ await new Promise((resolve2) => {
6958
7160
  execFile("taskkill.exe", ["/PID", String(pid), "/T", "/F"], {
6959
7161
  windowsHide: true,
6960
7162
  timeout: 2e3
6961
- }, () => resolve());
7163
+ }, () => resolve2());
6962
7164
  });
6963
7165
  if (!await waitForExit(child, 1500)) {
6964
7166
  try {
@@ -6979,8 +7181,8 @@ async function releaseOwnedBrowser(child, port, profile) {
6979
7181
  }
6980
7182
  }
6981
7183
  if (profile) {
6982
- const resolved = path9.resolve(profile);
6983
- if (path9.dirname(resolved) !== path9.resolve(os4.tmpdir()) || !/^pie-(chrome|helium)-cdp-/.test(path9.basename(resolved))) {
7184
+ const resolved = path10.resolve(profile);
7185
+ if (path10.dirname(resolved) !== path10.resolve(os3.tmpdir()) || !/^pie-(chrome|helium)-cdp-/.test(path10.basename(resolved))) {
6984
7186
  throw new Error("Refusing to remove a profile outside the owned temporary browser directory.");
6985
7187
  }
6986
7188
  await rm(resolved, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
@@ -6992,7 +7194,7 @@ async function releaseOwnedBrowserState(owner) {
6992
7194
  owner.managedBrowserProfileDir = void 0;
6993
7195
  }
6994
7196
 
6995
- // builtin/extensions/computer-use/src/root-selection.ts
7197
+ // vendor/computer-use-axi/src/root-selection.ts
6996
7198
  function scoreWindow(window) {
6997
7199
  let score = 0;
6998
7200
  if (window.isModal) score += 180;
@@ -7011,18 +7213,21 @@ function shouldPreferForegroundModalWindow(current, candidate) {
7011
7213
  return candidateIsInFront && scoreWindow(candidate) >= scoreWindow(current);
7012
7214
  }
7013
7215
 
7014
- // builtin/extensions/computer-use/src/state.ts
7216
+ // vendor/computer-use-axi/src/state.ts
7015
7217
  import { AsyncLocalStorage } from "node:async_hooks";
7016
7218
  var SavedStates = class {
7017
- store = new StateStore(128);
7219
+ store;
7018
7220
  operations = new AsyncLocalStorage();
7221
+ constructor(store = new StateStore(128)) {
7222
+ this.store = store;
7223
+ }
7019
7224
  current() {
7020
7225
  const state = this.operations.getStore();
7021
7226
  if (!state) throw new Error("Computer-use operation state is unavailable.");
7022
7227
  return state;
7023
7228
  }
7024
- get(stateId2) {
7025
- return this.store.get(stateId2);
7229
+ get(stateId) {
7230
+ return this.store.get(stateId);
7026
7231
  }
7027
7232
  set(record) {
7028
7233
  this.store.set(record);
@@ -7090,7 +7295,7 @@ var SavedStates = class {
7090
7295
  }
7091
7296
  };
7092
7297
 
7093
- // builtin/extensions/computer-use/src/view.ts
7298
+ // vendor/computer-use-axi/src/view.ts
7094
7299
  function numericRef(ref) {
7095
7300
  const match = /^@e(\d+)$/.exec(ref);
7096
7301
  return match ? Number(match[1]) : 0;
@@ -7226,7 +7431,7 @@ function renderChanges(changes) {
7226
7431
  }).join("\n");
7227
7432
  }
7228
7433
 
7229
- // builtin/extensions/computer-use/src/bridge.ts
7434
+ // vendor/computer-use-axi/src/bridge.ts
7230
7435
  var MISSING_TARGET_ERROR = "No current controlled window. Call observe_ui first to choose a target window.";
7231
7436
  var CURRENT_TARGET_GONE_ERROR = "The current controlled window is no longer available. Call observe_ui to choose a new target window.";
7232
7437
  var COMMAND_TIMEOUT_MS5 = 15e3;
@@ -7248,6 +7453,69 @@ var runtimeState = {
7248
7453
  var savedStates = new SavedStates();
7249
7454
  var resourceScheduler = new ResourceScheduler();
7250
7455
  var shutdownInFlight;
7456
+ var diskPersistence = false;
7457
+ function enableDiskPersistence(env = process.env) {
7458
+ if (diskPersistence) return;
7459
+ diskPersistence = true;
7460
+ const store = new DiskStateStore(128, env, stripLookImageForDisk);
7461
+ savedStates = new SavedStates(store);
7462
+ resourceScheduler = new ResourceScheduler({ onEpochChange: () => persistRuntimeBridgeState() });
7463
+ const snapshot = loadRuntimeStateSnapshot(env);
7464
+ if (!snapshot) return;
7465
+ for (const record of snapshot.windowRefs) {
7466
+ const stored = record;
7467
+ runtimeState.windowRefs.set(stored.ref, stored);
7468
+ runtimeState.windowRefByIdentity.set(windowRecordIdentity(stored), stored.ref);
7469
+ }
7470
+ for (const entry of snapshot.browserContexts) {
7471
+ runtimeState.browserContextByRoot.set(entry.root, entry.contextId);
7472
+ runtimeState.browserRootByContext.set(entry.contextId, entry.root);
7473
+ }
7474
+ runtimeState.nextRootRefIndex = Math.max(runtimeState.nextRootRefIndex, Math.trunc(snapshot.nextRootRefIndex) || 1);
7475
+ for (const entry of snapshot.epochs) resourceScheduler.restoreEpoch(entry.resourceKey, entry.epoch);
7476
+ if (snapshot.managedBrowser && /^\d+$/.test(snapshot.managedBrowser.cdpPort)) {
7477
+ runtimeState.managedBrowserCdpPort = snapshot.managedBrowser.cdpPort;
7478
+ runtimeState.managedBrowserPid = snapshot.managedBrowser.pid;
7479
+ runtimeState.managedBrowserProfileDir = snapshot.managedBrowser.profileDir;
7480
+ }
7481
+ }
7482
+ async function attachPersistedBrowser() {
7483
+ const port = runtimeState.managedBrowserCdpPort;
7484
+ if (!port || !/^\d+$/.test(port)) return false;
7485
+ try {
7486
+ const response = await fetch(`http://127.0.0.1:${port}/json/version`, { signal: AbortSignal.timeout(2e3) });
7487
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
7488
+ } catch {
7489
+ runtimeState.managedBrowserCdpPort = void 0;
7490
+ runtimeState.managedBrowserPid = void 0;
7491
+ runtimeState.managedBrowserProfileDir = void 0;
7492
+ if (runtimeState.previousCdpPort === void 0) delete process.env.PIE_COMPUTER_USE_CDP_PORT;
7493
+ persistRuntimeBridgeState();
7494
+ return false;
7495
+ }
7496
+ process.env.PIE_COMPUTER_USE_CDP_PORT = port;
7497
+ return true;
7498
+ }
7499
+ function stripLookImageForDisk(value) {
7500
+ if (value.kind !== "desktop" || !value.look.image) return value;
7501
+ return { ...value, look: { ...value.look, image: void 0 } };
7502
+ }
7503
+ function snapshotRuntimeBridgeState() {
7504
+ return {
7505
+ windowRefs: [...runtimeState.windowRefs.values()],
7506
+ browserContexts: [...runtimeState.browserContextByRoot.entries()].map(([root, contextId]) => ({ root, contextId })),
7507
+ nextRootRefIndex: runtimeState.nextRootRefIndex,
7508
+ epochs: resourceScheduler.epochs().map(([resourceKey, epoch]) => ({ resourceKey, epoch })),
7509
+ ...runtimeState.managedBrowserCdpPort && runtimeState.managedBrowserPid ? { managedBrowser: { cdpPort: runtimeState.managedBrowserCdpPort, pid: runtimeState.managedBrowserPid, profileDir: runtimeState.managedBrowserProfileDir } } : {}
7510
+ };
7511
+ }
7512
+ function persistRuntimeBridgeState() {
7513
+ if (!diskPersistence) return;
7514
+ try {
7515
+ persistRuntimeStateSnapshot(snapshotRuntimeBridgeState());
7516
+ } catch {
7517
+ }
7518
+ }
7251
7519
  function operationState() {
7252
7520
  return savedStates.current();
7253
7521
  }
@@ -7260,47 +7528,6 @@ function persistOperation(state) {
7260
7528
  const epoch = state.epoch ?? resourceScheduler.epoch(resourceKey);
7261
7529
  savedStates.saveDesktop(state, resourceKey, epoch);
7262
7530
  }
7263
- function shutdownComputerUseSession() {
7264
- if (shutdownInFlight) return shutdownInFlight;
7265
- shutdownInFlight = releaseComputerUseSession().finally(() => {
7266
- shutdownInFlight = void 0;
7267
- });
7268
- return shutdownInFlight;
7269
- }
7270
- async function releaseComputerUseSession() {
7271
- const drain = resourceScheduler.close();
7272
- const failures = [];
7273
- const attempt = (step, work) => work().catch((error) => {
7274
- failures.push(error instanceof Error ? new Error(`${step}: ${error.message}`) : error);
7275
- });
7276
- await attempt("disconnect CDP", () => disconnectCdp());
7277
- await attempt("platform shutdown", async () => {
7278
- await currentPlatformBackend.shutdown?.();
7279
- });
7280
- await attempt("drain scheduler", () => drain);
7281
- await attempt("release owned browser", () => releaseOwnedBrowserState(runtimeState));
7282
- if (runtimeState.managedBrowserCdpPort && process.env.PIE_COMPUTER_USE_CDP_PORT === runtimeState.managedBrowserCdpPort) {
7283
- if (runtimeState.previousCdpPort === void 0) delete process.env.PIE_COMPUTER_USE_CDP_PORT;
7284
- else process.env.PIE_COMPUTER_USE_CDP_PORT = runtimeState.previousCdpPort;
7285
- }
7286
- runtimeState.previousCdpPort = void 0;
7287
- if (runtimeState.managedBrowser === void 0) {
7288
- runtimeState.managedBrowserCdpPort = void 0;
7289
- }
7290
- savedStates.clear();
7291
- clearStoredOutputs();
7292
- runtimeState.windowRefs.clear();
7293
- runtimeState.windowRefByIdentity.clear();
7294
- runtimeState.browserRootByContext.clear();
7295
- runtimeState.browserContextByRoot.clear();
7296
- runtimeState.nextRootRefIndex = 1;
7297
- runtimeState.permissionStatus = void 0;
7298
- runtimeState.helperDiagnostics = void 0;
7299
- runtimeState.lastPermissionCheckAt = 0;
7300
- resourceScheduler = new ResourceScheduler();
7301
- if (failures.length === 1) throw failures[0];
7302
- if (failures.length > 1) throw new AggregateError(failures, "computer-use session release had partial failures (state was reset)");
7303
- }
7304
7531
  function currentRuntimeMode() {
7305
7532
  return isHeadlessMode() ? "stealth" : "default";
7306
7533
  }
@@ -7341,10 +7568,10 @@ function throwIfAborted3(signal) {
7341
7568
  async function sleep2(ms, signal) {
7342
7569
  if (ms <= 0) return;
7343
7570
  throwIfAborted3(signal);
7344
- await new Promise((resolve, reject) => {
7571
+ await new Promise((resolve2, reject) => {
7345
7572
  const timer = setTimeout(() => {
7346
7573
  cleanup();
7347
- resolve();
7574
+ resolve2();
7348
7575
  }, ms);
7349
7576
  const onAbort = () => {
7350
7577
  cleanup();
@@ -7376,21 +7603,18 @@ function trimOrUndefined(value) {
7376
7603
  function normalizeText2(value) {
7377
7604
  return (value ?? "").trim().toLowerCase();
7378
7605
  }
7379
- function toBoolean3(value) {
7380
- return value === true;
7381
- }
7382
7606
  function outlineNodeCenter(node) {
7383
7607
  if (!node.rect) {
7384
7608
  throw new Error(`Outline ref '${node.ref}' has no full-look coordinates after scoped expansion. Re-observe for coordinates.`);
7385
7609
  }
7386
7610
  return { x: node.rect.x + node.rect.w / 2, y: node.rect.y + node.rect.h / 2 };
7387
7611
  }
7388
- function validateStateId(stateId2) {
7612
+ function validateStateId(stateId) {
7389
7613
  const state = operationState();
7390
7614
  if (!state.currentCapture) {
7391
7615
  throw new Error("No observation state is available. Call observe_ui first.");
7392
7616
  }
7393
- const supplied = stateId2;
7617
+ const supplied = stateId;
7394
7618
  if (supplied && state.currentCapture.stateId !== supplied) {
7395
7619
  throw new Error(
7396
7620
  `Stale state '${supplied}'. The active operation state is '${state.currentCapture.stateId}'. Observe the root again and retry.`
@@ -7550,6 +7774,7 @@ function storeWindowRef(record) {
7550
7774
  const stored = { ...record, ref };
7551
7775
  runtimeState.windowRefByIdentity.set(identity, ref);
7552
7776
  runtimeState.windowRefs.set(ref, stored);
7777
+ persistRuntimeBridgeState();
7553
7778
  return stored;
7554
7779
  }
7555
7780
  function storeBrowserRootRef(contextId) {
@@ -7558,6 +7783,7 @@ function storeBrowserRootRef(contextId) {
7558
7783
  const ref = `@r${runtimeState.nextRootRefIndex++}`;
7559
7784
  runtimeState.browserRootByContext.set(contextId, ref);
7560
7785
  runtimeState.browserContextByRoot.set(ref, contextId);
7786
+ persistRuntimeBridgeState();
7561
7787
  return ref;
7562
7788
  }
7563
7789
  function storeWindowRefForTarget(target) {
@@ -7792,7 +8018,7 @@ async function ensureTargetWindowId(target, signal) {
7792
8018
  }
7793
8019
  function captureForLook(look) {
7794
8020
  return {
7795
- stateId: randomUUID5(),
8021
+ stateId: randomUUID6(),
7796
8022
  width: look.image?.width ?? 0,
7797
8023
  height: look.image?.height ?? 0,
7798
8024
  scaleFactor: look.window.scaleFactor,
@@ -7965,6 +8191,7 @@ function modelRefForRootDelta(delta) {
7965
8191
  };
7966
8192
  runtimeState.windowRefs.set(ref, record);
7967
8193
  runtimeState.windowRefByIdentity.set(windowRecordIdentity(record), ref);
8194
+ persistRuntimeBridgeState();
7968
8195
  return ref;
7969
8196
  }
7970
8197
  function executionTraceFromAct(result, policy = currentDeliveryPolicy()) {
@@ -8403,7 +8630,7 @@ function sameRootIdentity(a, b) {
8403
8630
  }
8404
8631
  async function performObserve(params, signal) {
8405
8632
  const requestedRoot = typeof params.root === "string" ? params.root : void 0;
8406
- if (requestedRoot && !/^@r\d+$/.test(requestedRoot)) throw new Error("observe_ui.root must be an exact @r ref issued by find_roots.");
8633
+ if (requestedRoot && !/^@r\d+$/.test(requestedRoot)) throw new Error("observe --root must be an exact @r ref issued by roots.");
8407
8634
  const browserContextId = requestedRoot ? runtimeState.browserContextByRoot.get(requestedRoot) : void 0;
8408
8635
  if (isBrowserContextId(browserContextId)) {
8409
8636
  const targetId = browserContextId.slice(BROWSER_CONTEXT_PREFIX.length);
@@ -8437,8 +8664,8 @@ async function performObserve(params, signal) {
8437
8664
  const summary = `Observed ${mode} ${captureResult.target.windowRef ? `${captureResult.target.windowRef} ` : ""}${captureResult.target.appName} \u2014 ${captureResult.target.windowTitle}. Returned the latest outline state.`;
8438
8665
  return await buildToolResult("observe_ui", summary, captureResult, executionTrace("look", "stealth"), signal, imageMode);
8439
8666
  }
8440
- function currentOutlineOrThrow(stateId2) {
8441
- validateStateId(stateId2);
8667
+ function currentOutlineOrThrow(stateId) {
8668
+ validateStateId(stateId);
8442
8669
  const outline = operationState().currentOutline;
8443
8670
  if (!outline) throw new Error("No observation outline is available. Call observe_ui first.");
8444
8671
  return outline;
@@ -8809,8 +9036,8 @@ async function performBrowserTransaction(params, actions, signal) {
8809
9036
  return await refreshBrowserSnapshot(contextId, "act_ui", baseView);
8810
9037
  });
8811
9038
  }
8812
- function normalizeActionPath(path11) {
8813
- return (path11 ?? []).map((point2) => Array.isArray(point2) ? { x: toFiniteNumber(point2[0], 0), y: toFiniteNumber(point2[1], 0) } : { x: toFiniteNumber(point2.x, 0), y: toFiniteNumber(point2.y, 0) });
9039
+ function normalizeActionPath(path12) {
9040
+ return (path12 ?? []).map((point) => Array.isArray(point) ? { x: toFiniteNumber(point[0], 0), y: toFiniteNumber(point[1], 0) } : { x: toFiniteNumber(point.x, 0), y: toFiniteNumber(point.y, 0) });
8814
9041
  }
8815
9042
  function validateActionTarget(action) {
8816
9043
  const hasRef = Boolean(trimOrUndefined(action.ref));
@@ -8827,7 +9054,7 @@ function validateActionTarget(action) {
8827
9054
  }
8828
9055
  async function performAct(params, signal) {
8829
9056
  const actions = Array.isArray(params.actions) ? params.actions : [];
8830
- if (actions.length === 0) throw new Error("act_ui.actions must contain at least one action.");
9057
+ if (actions.length === 0) throw new Error("act --actions must contain at least one action.");
8831
9058
  if (actions.length > 20) throw new Error("act_ui supports at most 20 actions per transaction.");
8832
9059
  for (const action of actions) validateActionTarget(action);
8833
9060
  if (operationState().contextId) return await performBrowserTransaction(params, actions, signal);
@@ -8836,25 +9063,25 @@ async function performAct(params, signal) {
8836
9063
  function managedBrowserExecutableCandidates(browser) {
8837
9064
  const overrideName = browser === "helium" ? "PIE_COMPUTER_USE_HELIUM_EXECUTABLE" : "PIE_COMPUTER_USE_CHROME_EXECUTABLE";
8838
9065
  const override = trimOrUndefined(process.env[overrideName]);
8839
- if (override) return [path10.resolve(override)];
9066
+ if (override) return [path11.resolve(override)];
8840
9067
  const platformCandidates = process.platform === "darwin" ? browser === "helium" ? [
8841
9068
  "/Applications/Helium.app/Contents/MacOS/Helium",
8842
- path10.join(os5.homedir(), "Applications", "Helium.app", "Contents", "MacOS", "Helium")
9069
+ path11.join(os4.homedir(), "Applications", "Helium.app", "Contents", "MacOS", "Helium")
8843
9070
  ] : [
8844
9071
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
8845
- path10.join(os5.homedir(), "Applications", "Google Chrome.app", "Contents", "MacOS", "Google Chrome")
9072
+ path11.join(os4.homedir(), "Applications", "Google Chrome.app", "Contents", "MacOS", "Google Chrome")
8846
9073
  ] : process.platform === "win32" ? browser === "helium" ? [
8847
- process.env.LOCALAPPDATA && path10.join(process.env.LOCALAPPDATA, "Helium", "Application", "helium.exe"),
8848
- process.env.PROGRAMFILES && path10.join(process.env.PROGRAMFILES, "Helium", "Application", "helium.exe")
9074
+ process.env.LOCALAPPDATA && path11.join(process.env.LOCALAPPDATA, "Helium", "Application", "helium.exe"),
9075
+ process.env.PROGRAMFILES && path11.join(process.env.PROGRAMFILES, "Helium", "Application", "helium.exe")
8849
9076
  ] : [
8850
- process.env.LOCALAPPDATA && path10.join(process.env.LOCALAPPDATA, "Google", "Chrome", "Application", "chrome.exe"),
8851
- process.env.PROGRAMFILES && path10.join(process.env.PROGRAMFILES, "Google", "Chrome", "Application", "chrome.exe"),
8852
- process.env["PROGRAMFILES(X86)"] && path10.join(process.env["PROGRAMFILES(X86)"], "Google", "Chrome", "Application", "chrome.exe")
9077
+ process.env.LOCALAPPDATA && path11.join(process.env.LOCALAPPDATA, "Google", "Chrome", "Application", "chrome.exe"),
9078
+ process.env.PROGRAMFILES && path11.join(process.env.PROGRAMFILES, "Google", "Chrome", "Application", "chrome.exe"),
9079
+ process.env["PROGRAMFILES(X86)"] && path11.join(process.env["PROGRAMFILES(X86)"], "Google", "Chrome", "Application", "chrome.exe")
8853
9080
  ] : browser === "helium" ? [
8854
9081
  "/usr/bin/helium",
8855
9082
  "/usr/bin/helium-browser",
8856
9083
  "/opt/helium/chrome",
8857
- path10.join(os5.homedir(), ".local", "helium", "chrome")
9084
+ path11.join(os4.homedir(), ".local", "helium", "chrome")
8858
9085
  ] : [
8859
9086
  "/usr/bin/google-chrome",
8860
9087
  "/usr/bin/google-chrome-stable",
@@ -8863,7 +9090,7 @@ function managedBrowserExecutableCandidates(browser) {
8863
9090
  "/snap/bin/chromium"
8864
9091
  ];
8865
9092
  const pathNames = browser === "helium" ? process.platform === "win32" ? ["helium.exe"] : ["helium", "helium-browser"] : process.platform === "win32" ? ["chrome.exe"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"];
8866
- const pathCandidates = (process.env.PATH ?? "").split(path10.delimiter).filter(Boolean).flatMap((directory) => pathNames.map((name) => path10.join(directory, name)));
9093
+ const pathCandidates = (process.env.PATH ?? "").split(path11.delimiter).filter(Boolean).flatMap((directory) => pathNames.map((name) => path11.join(directory, name)));
8867
9094
  return [.../* @__PURE__ */ new Set([...platformCandidates.filter((candidate) => Boolean(candidate)), ...pathCandidates])];
8868
9095
  }
8869
9096
  async function managedBrowserExecutable(browser) {
@@ -8882,13 +9109,13 @@ async function managedBrowserExecutable(browser) {
8882
9109
  throw new Error(`${browser} executable was not found. Set ${overrideName} to its absolute path.`);
8883
9110
  }
8884
9111
  function freeTcpPort() {
8885
- return new Promise((resolve, reject) => {
9112
+ return new Promise((resolve2, reject) => {
8886
9113
  const server = net2.createServer();
8887
9114
  server.on("error", reject);
8888
9115
  server.listen(0, "127.0.0.1", () => {
8889
9116
  const address = server.address();
8890
9117
  const port = typeof address === "object" && address ? address.port : 0;
8891
- server.close(() => port > 0 ? resolve(port) : reject(new Error("Could not allocate a local CDP port.")));
9118
+ server.close(() => port > 0 ? resolve2(port) : reject(new Error("Could not allocate a local CDP port.")));
8892
9119
  });
8893
9120
  });
8894
9121
  }
@@ -8914,7 +9141,7 @@ async function performLaunchBrowser(params, signal) {
8914
9141
  const url = requestedUrl ?? "about:blank";
8915
9142
  await disconnectCdp();
8916
9143
  await releaseOwnedBrowserState(runtimeState);
8917
- const profileDir = mkdtempSync2(path10.join(os5.tmpdir(), `pie-${browser}-cdp-`));
9144
+ const profileDir = mkdtempSync(path11.join(os4.tmpdir(), `pie-${browser}-cdp-`));
8918
9145
  const args = [
8919
9146
  `--remote-debugging-port=${port}`,
8920
9147
  `--user-data-dir=${profileDir}`,
@@ -8925,11 +9152,20 @@ async function performLaunchBrowser(params, signal) {
8925
9152
  if (runtimeState.previousCdpPort === void 0 && runtimeState.managedBrowserCdpPort === void 0) {
8926
9153
  runtimeState.previousCdpPort = process.env.PIE_COMPUTER_USE_CDP_PORT;
8927
9154
  }
8928
- const managedBrowser = spawn4(executable, args, { stdio: "ignore", detached: false });
9155
+ const managedBrowser = spawn4(executable, args, { stdio: "ignore", detached: true });
8929
9156
  managedBrowser.unref();
9157
+ const stalePid = runtimeState.managedBrowserPid;
9158
+ if (stalePid !== void 0 && stalePid !== managedBrowser.pid) {
9159
+ try {
9160
+ process.kill(stalePid, "SIGTERM");
9161
+ } catch {
9162
+ }
9163
+ }
8930
9164
  runtimeState.managedBrowser = managedBrowser;
8931
9165
  runtimeState.managedBrowserCdpPort = String(port);
9166
+ runtimeState.managedBrowserPid = managedBrowser.pid;
8932
9167
  runtimeState.managedBrowserProfileDir = profileDir;
9168
+ persistRuntimeBridgeState();
8933
9169
  process.env.PIE_COMPUTER_USE_CDP_PORT = String(port);
8934
9170
  try {
8935
9171
  await waitForCdpPort(port, signal);
@@ -9031,402 +9267,278 @@ var executeAct = makeToolExecutor("act_ui", performAct);
9031
9267
  var executeNavigateBrowser = makeToolExecutor("navigate_browser", performNavigateBrowser);
9032
9268
  var executeEvaluateBrowser = makeToolExecutor("evaluate_browser", performEvaluateBrowser);
9033
9269
  var executeLaunchBrowser = makeToolExecutor("launch_browser", performLaunchBrowser);
9034
- function reconstructStateFromBranch(ctx) {
9035
- savedStates.clear();
9036
- clearStoredOutputs();
9037
- runtimeState.windowRefs.clear();
9038
- runtimeState.windowRefByIdentity.clear();
9039
- runtimeState.nextRootRefIndex = 1;
9040
- const restoredResources = /* @__PURE__ */ new Set();
9041
- for (const message of [...ctx.getMessages()].reverse()) {
9042
- if (!message || message.role !== "toolResult") continue;
9043
- if (!AGENT_TOOL_NAMES.has(message.toolName)) continue;
9044
- const rawDetails = message.details;
9045
- if (rawDetails?.tool === "find_roots" && Array.isArray(rawDetails.windows)) {
9046
- for (const window of rawDetails.windows) {
9047
- if (typeof window?.windowRef !== "string" || !Number.isFinite(window?.pid)) continue;
9048
- const record = {
9049
- ref: window.windowRef,
9050
- appName: typeof window.app === "string" ? window.app : "Unknown App",
9051
- bundleId: typeof window.bundleId === "string" ? window.bundleId : void 0,
9052
- pid: Math.trunc(window.pid),
9053
- windowTitle: typeof window.windowTitle === "string" ? window.windowTitle : "(untitled)",
9054
- windowId: Number.isFinite(window.windowId) ? Math.trunc(window.windowId) : void 0,
9055
- nativeWindowRef: typeof window.nativeWindowRef === "string" ? window.nativeWindowRef : void 0,
9056
- framePoints: {
9057
- x: toFiniteNumber(window.framePoints?.x, 0),
9058
- y: toFiniteNumber(window.framePoints?.y, 0),
9059
- w: Math.max(1, toFiniteNumber(window.framePoints?.w, 1)),
9060
- h: Math.max(1, toFiniteNumber(window.framePoints?.h, 1))
9061
- },
9062
- scaleFactor: Math.max(1, toFiniteNumber(window.scaleFactor, 1)),
9063
- isMinimized: toBoolean3(window.isMinimized),
9064
- isOnscreen: toBoolean3(window.isOnscreen),
9065
- isMain: toBoolean3(window.isMain),
9066
- isFocused: toBoolean3(window.isFocused)
9067
- };
9068
- runtimeState.windowRefs.set(record.ref, record);
9069
- runtimeState.windowRefByIdentity.set(windowRecordIdentity(record), record.ref);
9070
- const match = /^@r(\d+)$/.exec(record.ref);
9071
- if (match) runtimeState.nextRootRefIndex = Math.max(runtimeState.nextRootRefIndex, Number(match[1]) + 1);
9072
- }
9270
+
9271
+ // vendor/computer-use-axi/src/cli.ts
9272
+ var USAGE = `computer-use-axi \u2014 desktop & browser UI automation
9273
+
9274
+ Lifecycle: roots -> observe (returns stateId) -> search/expand/inspect -> act.
9275
+ @r refs come from roots; @e refs + stateId come from observe/search;
9276
+ @o refs continue long truncated output via read.
9277
+
9278
+ Commands:
9279
+ roots [--text T] [--app A] [--bundle-id B] [--pid N] [--kind K]
9280
+ observe [--root @rN] [--mode semantic|visual|fused]
9281
+ search --state S (--text T | --role R | --capability C)
9282
+ expand --state S --ref @eN [--depth 1-8]
9283
+ inspect --state S --ref @eN
9284
+ read --ref @oN|--eN [--offset BYTES] [--state S]
9285
+ wait --state S (--text T | --role R | --ref @eN) [--until present|absent]
9286
+ [--scope-ref @eN] [--value V] [--timeout-ms MS]
9287
+ act --state S --actions '<JSON array>' [--expect '<JSON object>']
9288
+ browser launch [--url U]
9289
+ browser navigate --state S --url U
9290
+ browser eval --state S --expr '<JavaScript>'
9291
+
9292
+ Options:
9293
+ --json Print { content, details, isError } as JSON
9294
+ --help, -h Show this help
9295
+
9296
+ Examples:
9297
+ computer-use-axi roots --app Finder
9298
+ computer-use-axi observe --root @r1
9299
+ computer-use-axi search --state S1 --text Save
9300
+ computer-use-axi act --state S1 --actions '[{"action":"press","ref":"@e12"}]'
9301
+ computer-use-axi read --ref @o1 --offset 16384`;
9302
+ var FLAG_ALIASES = {
9303
+ "-h": "--help",
9304
+ "--state-id": "--state",
9305
+ "--window": "--root",
9306
+ "--capability-filter": "--capability",
9307
+ "--scope": "--scope-ref",
9308
+ "--timeout": "--timeout-ms",
9309
+ "--expression": "--expr"
9310
+ };
9311
+ function parseArgs(argv) {
9312
+ const rest = [];
9313
+ const flags = /* @__PURE__ */ new Map();
9314
+ let command = "";
9315
+ let json = false;
9316
+ let help = false;
9317
+ const booleanFlags = /* @__PURE__ */ new Set(["--json", "--help"]);
9318
+ for (let i = 0; i < argv.length; i++) {
9319
+ const token = argv[i];
9320
+ const alias = FLAG_ALIASES[token] ?? token;
9321
+ if (!alias.startsWith("-")) {
9322
+ if (!command) command = token;
9323
+ else rest.push(token);
9073
9324
  continue;
9074
9325
  }
9075
- const details = rawDetails;
9076
- if (!details?.target || !details?.capture) continue;
9077
- const app = typeof details.target.app === "string" ? details.target.app : void 0;
9078
- if (!app) continue;
9079
- if (!Number.isFinite(details.target.pid) || !Number.isFinite(details.target.windowId)) continue;
9080
- if (typeof details.capture.stateId !== "string") continue;
9081
- const target = {
9082
- appName: app,
9083
- bundleId: details.target.bundleId,
9084
- pid: Math.trunc(details.target.pid),
9085
- windowTitle: details.target.windowTitle ?? "(untitled)",
9086
- windowId: Math.trunc(details.target.windowId),
9087
- windowRef: typeof details.target.windowRef === "string" ? details.target.windowRef : void 0,
9088
- nativeWindowRef: typeof details.target.nativeWindowRef === "string" ? details.target.nativeWindowRef : void 0
9089
- };
9090
- const resourceKey = desktopResourceKey(target);
9091
- if (restoredResources.has(resourceKey)) continue;
9092
- const capture = {
9093
- stateId: details.capture.stateId,
9094
- width: Math.max(1, Math.trunc(toFiniteNumber(details.capture.width, 1))),
9095
- height: Math.max(1, Math.trunc(toFiniteNumber(details.capture.height, 1))),
9096
- scaleFactor: Math.max(1, toFiniteNumber(details.capture.scaleFactor, 1)),
9097
- timestamp: Number.isFinite(details.capture.timestamp) ? details.capture.timestamp : Date.now()
9098
- };
9099
- if (details.outline?.root && typeof details.outline.lookId === "string") {
9100
- const epoch = 0;
9101
- resourceScheduler.restoreEpoch(resourceKey, epoch);
9102
- savedStates.set({
9103
- stateId: capture.stateId,
9104
- resourceKey,
9105
- epoch,
9106
- value: {
9107
- kind: "desktop",
9108
- target,
9109
- capture,
9110
- outline: details.outline,
9111
- look: {
9112
- lookId: details.outline.lookId,
9113
- capturedAt: details.capture.timestamp / 1e3,
9114
- window: {
9115
- windowId: Math.trunc(details.target.windowId),
9116
- framePoints: { x: 0, y: 0, w: details.capture.width, h: details.capture.height },
9117
- scaleFactor: details.capture.scaleFactor,
9118
- isModal: false,
9119
- role: "",
9120
- subrole: ""
9121
- },
9122
- image: { jpegBase64: "", width: details.capture.width, height: details.capture.height },
9123
- timings: {}
9124
- },
9125
- note: details.note
9126
- }
9127
- });
9128
- restoredResources.add(resourceKey);
9326
+ if (alias === "--json") {
9327
+ json = true;
9328
+ continue;
9129
9329
  }
9330
+ if (alias === "--help") {
9331
+ help = true;
9332
+ continue;
9333
+ }
9334
+ let key = alias;
9335
+ let value;
9336
+ const eq = alias.indexOf("=");
9337
+ if (eq >= 0) {
9338
+ key = alias.slice(0, eq);
9339
+ value = alias.slice(eq + 1);
9340
+ }
9341
+ if (!booleanFlags.has(key) && value === void 0) {
9342
+ const next = argv[i + 1];
9343
+ if (next !== void 0 && !next.startsWith("-")) {
9344
+ value = next;
9345
+ i += 1;
9346
+ }
9347
+ }
9348
+ flags.set(key, value ?? "");
9130
9349
  }
9350
+ return { command, flags, json, help, rest };
9131
9351
  }
9132
-
9133
- // builtin/extensions/computer-use/index.ts
9134
- var stateId = Type.String({ description: "Required state id owning every @e ref used by this operation" });
9135
- var point = { x: Type.Number(), y: Type.Number() };
9136
- var mouseButton2 = Type.Optional(Type.Union([Type.Literal("left"), Type.Literal("right"), Type.Literal("middle")]));
9137
- var clickByRef = Type.Object({ action: Type.Literal("click"), ref: Type.String(), button: mouseButton2, clickCount: Type.Optional(Type.Number({ minimum: 1, maximum: 3 })) });
9138
- var clickByPoint = Type.Object({ action: Type.Literal("click"), ...point, button: mouseButton2, clickCount: Type.Optional(Type.Number({ minimum: 1, maximum: 3 })) });
9139
- var uiAction = Type.Union([
9140
- Type.Object({ action: Type.Literal("press"), ref: Type.String({ description: "Actionable outline ref" }) }),
9141
- clickByRef,
9142
- clickByPoint,
9143
- Type.Object({ action: Type.Literal("setText"), ref: Type.String({ description: "Editable outline ref" }), text: Type.String() }),
9144
- Type.Object({ action: Type.Literal("typeText"), ref: Type.Optional(Type.String({ description: "Omit after a click to type into the focus established by that click" })), text: Type.String() }),
9145
- Type.Object({ action: Type.Literal("keypress"), ref: Type.Optional(Type.String({ description: "Omit to send keys to the focused control" })), keys: Type.Array(Type.String(), { minItems: 1 }) }),
9146
- Type.Object({ action: Type.Literal("scroll"), ref: Type.Optional(Type.String()), scrollX: Type.Optional(Type.Number()), scrollY: Type.Optional(Type.Number()) }),
9147
- Type.Object({ action: Type.Literal("drag"), path: Type.Array(Type.Object(point), { minItems: 2 }) }),
9148
- Type.Object({ action: Type.Literal("moveMouse"), ...point })
9149
- ]);
9150
- var conditionProperties = {
9151
- ref: Type.Optional(Type.String({ description: "Specific @e ref to test", maxLength: 128 })),
9152
- scopeRef: Type.Optional(Type.String({ description: "Restrict matching to this @e subtree", maxLength: 128 })),
9153
- text: Type.Optional(Type.String({ description: "Text that must match", maxLength: 512 })),
9154
- role: Type.Optional(Type.String({ description: "Exact normalized role", maxLength: 128 })),
9155
- value: Type.Optional(Type.String({ description: "Exact normalized value; normally pair with ref" })),
9156
- until: Type.Optional(Type.Union([Type.Literal("present"), Type.Literal("absent")], { description: "Desired condition, default present" })),
9157
- timeoutMs: Type.Optional(Type.Number({ description: "Maximum wait, default 10000ms", minimum: 100, maximum: 6e4 }))
9158
- };
9159
- var OBSERVE_RISK = {
9160
- riskClass: "read_only",
9161
- concurrencySafe: false,
9162
- permissionScope: "host",
9163
- readsHostResource: true,
9164
- allowedForSubagentByDefault: false
9165
- };
9166
- var BROWSER_RISK = {
9167
- riskClass: "external_side_effect",
9168
- concurrencySafe: false,
9169
- requiresPermission: true,
9170
- permissionScope: "host",
9171
- externalSideEffect: true,
9172
- allowedForSubagentByDefault: false
9173
- };
9174
- var ACT_RISK = {
9175
- riskClass: "external_side_effect",
9176
- concurrencySafe: false,
9177
- requiresPermission: true,
9178
- permissionScope: "host",
9179
- writesHostResource: true,
9180
- externalSideEffect: true,
9181
- highRisk: true,
9182
- allowedForSubagentByDefault: false
9183
- };
9184
- function describe(description, ...extra) {
9185
- const lines = [description];
9186
- for (const part of extra) {
9187
- if (!part) continue;
9188
- for (const line of Array.isArray(part) ? part : [part]) lines.push(line);
9189
- }
9190
- return lines.join(" ");
9191
- }
9192
- var findTool = {
9193
- name: "find_roots",
9194
- label: "Find Roots",
9195
- risk: OBSERVE_RISK,
9196
- description: describe(
9197
- "Find a bounded, ranked set of controllable UI roots with refs, geometry, and focus state.",
9198
- "Find a target root before observe_ui when needed. Desktop control is a last resort - prefer API/CLI/web tools when they suffice."
9199
- ),
9200
- parameters: Type.Object({
9201
- text: Type.Optional(Type.String({ description: "Ranked app or title text", maxLength: 256 })),
9202
- app: Type.Optional(Type.String({ description: "Exact normalized app name", maxLength: 256 })),
9203
- bundleId: Type.Optional(Type.String({ description: "Exact bundle id" })),
9204
- pid: Type.Optional(Type.Number({ description: "Exact process id" })),
9205
- kind: Type.Optional(Type.Union([Type.Literal("window"), Type.Literal("menu"), Type.Literal("sheet"), Type.Literal("popover"), Type.Literal("dialog"), Type.Literal("browser_page")], { description: "Exact root kind" }))
9206
- }),
9207
- executor: executeFind
9208
- };
9209
- var observeTool = {
9210
- name: "observe_ui",
9211
- label: "Observe UI",
9212
- risk: OBSERVE_RISK,
9213
- description: describe(
9214
- "Capture the current/frontmost root or one exact @r root and return a bounded UI outline.",
9215
- "Primary UI observation tool. Follow with search_ui, expand_ui, inspect_ui, or act_ui.",
9216
- [
9217
- "Use mode=semantic to skip OCR and images, visual to force them, and fused for automatic selection.",
9218
- "Use @e outline refs from observe_ui/search_ui for act_ui; pictureOnly refs are coordinate-only and blocked by UI-tree-only policy."
9219
- ]
9220
- ),
9221
- parameters: Type.Object({
9222
- root: Type.Optional(Type.String({ description: "Exact @r ref issued by find_roots" })),
9223
- mode: Type.Optional(Type.Union([Type.Literal("semantic"), Type.Literal("visual"), Type.Literal("fused")], { description: "Observation mode, default fused" }))
9224
- }),
9225
- executor: executeObserve
9226
- };
9227
- var searchUiTool = {
9228
- name: "search_ui",
9229
- label: "Search UI",
9230
- risk: OBSERVE_RISK,
9231
- description: describe(
9232
- "Return a bounded, deterministically ranked search of the cached outline. At least one predicate is required.",
9233
- "Find targets not shown in the compact observe_ui output; refine broad searches instead of paging matches."
9234
- ),
9235
- parameters: Type.Object({
9236
- text: Type.Optional(Type.String({ description: "Human-readable text or label", maxLength: 256 })),
9237
- role: Type.Optional(Type.String({ description: "Exact normalized role, e.g. button", maxLength: 128 })),
9238
- capability: Type.Optional(Type.String({ description: "Exact capability, e.g. press", maxLength: 128 })),
9239
- stateId
9240
- }),
9241
- executor: executeSearchUi
9242
- };
9243
- var expandUiTool = {
9244
- name: "expand_ui",
9245
- label: "Expand UI",
9246
- risk: OBSERVE_RISK,
9247
- description: describe(
9248
- "Unfold bounded local outline context for one @e ref.",
9249
- "Expand a specific ref instead of dumping unrelated UI."
9250
- ),
9251
- parameters: Type.Object({ ref: Type.String(), depth: Type.Optional(Type.Number({ minimum: 1, maximum: 8, description: "Subtree depth, default 3" })), stateId }),
9252
- executor: executeExpandUi
9253
- };
9254
- var inspectUiTool = {
9255
- name: "inspect_ui",
9256
- label: "Inspect UI",
9257
- risk: OBSERVE_RISK,
9258
- description: describe(
9259
- "Inspect one exact outline ref with fields, geometry, capabilities, and annotations.",
9260
- "Use when a target's evidence or provenance matters."
9261
- ),
9262
- parameters: Type.Object({ ref: Type.String(), stateId }),
9263
- executor: executeInspectUi
9264
- };
9265
- var actTool = {
9266
- name: "act_ui",
9267
- label: "Act",
9268
- risk: ACT_RISK,
9269
- description: describe(
9270
- "Perform one or more precisely targeted checked actions and return the successor state.",
9271
- "Pass dependent click/type steps together and use expect for observable completion.",
9272
- ["After clicking an editable region, omit ref from typeText/keypress so input follows the established focus."]
9273
- ),
9274
- parameters: Type.Object({ stateId, expect: Type.Optional(Type.Object(conditionProperties)), actions: Type.Array(uiAction, { minItems: 1, maxItems: 20 }) }),
9275
- executor: executeAct
9276
- };
9277
- var readTextTool = {
9278
- name: "read_text",
9279
- label: "Read Text",
9280
- risk: OBSERVE_RISK,
9281
- description: describe(
9282
- "Read a fixed-size page from an @e UI ref or immutable @o truncated-output ref.",
9283
- "Use @e with its stateId; @o continuation refs don't need stateId."
9284
- ),
9285
- parameters: Type.Object({ ref: Type.String(), offset: Type.Optional(Type.Number({ minimum: 0 })), stateId: Type.Optional(stateId) }),
9286
- executor: executeReadText
9287
- };
9288
- var waitForTool = {
9289
- name: "wait_for",
9290
- label: "Wait For",
9291
- risk: OBSERVE_RISK,
9292
- description: describe(
9293
- "Wait for one scoped UI condition and return the successor state.",
9294
- "Use after asynchronous UI changes instead of polling observe_ui."
9295
- ),
9296
- parameters: Type.Object({ ...conditionProperties, stateId }),
9297
- executor: executeWaitFor
9298
- };
9299
- var launchBrowserTool = {
9300
- name: "launch_browser",
9301
- label: "Launch Browser Context",
9302
- risk: BROWSER_RISK,
9303
- description: describe(
9304
- "Launch the configured Pie-managed CDP browser and return an observed browser-page state.",
9305
- "Use for browser work that needs a managed CDP context.",
9306
- ["Prefer curl through bash when the page is directly fetchable."]
9307
- ),
9308
- parameters: Type.Object({ url: Type.Optional(Type.String({ maxLength: 8192 })) }),
9309
- executor: executeLaunchBrowser
9310
- };
9311
- var navigateBrowserTool = {
9312
- name: "navigate_browser",
9313
- label: "Navigate Browser",
9314
- risk: BROWSER_RISK,
9315
- description: describe(
9316
- "Navigate an observed CDP browser-page state to an HTTP(S) URL.",
9317
- "Native browser windows use act_ui; this tool is CDP-only."
9318
- ),
9319
- parameters: Type.Object({ url: Type.String({ maxLength: 8192 }), stateId }),
9320
- executor: executeNavigateBrowser
9321
- };
9322
- var evaluateBrowserTool = {
9323
- name: "evaluate_browser",
9324
- label: "Evaluate Browser",
9325
- risk: BROWSER_RISK,
9326
- description: describe(
9327
- "Evaluate targeted JavaScript in a CDP browser-page state; returned output is strictly bounded.",
9328
- "Prefer observe/search/read; return selected fields, aggregates, or bounded slices."
9329
- ),
9330
- parameters: Type.Object({ stateId, expression: Type.String({ maxLength: 65536 }) }),
9331
- executor: executeEvaluateBrowser
9332
- };
9333
- var OBSERVE_TOOLS = [findTool, observeTool, searchUiTool, expandUiTool, inspectUiTool, readTextTool, waitForTool, launchBrowserTool, navigateBrowserTool, evaluateBrowserTool];
9334
- var ACT_TOOLS = [actTool];
9335
- function summarizeActArgs(args) {
9336
- const actions = args?.actions;
9337
- if (!Array.isArray(actions) || actions.length === 0) return "(no actions)";
9338
- const names = actions.map((action) => action?.action ?? "unknown");
9339
- const unique = [...new Set(names)];
9340
- return `${actions.length} action(s): ${unique.join(", ")}`;
9341
- }
9342
- async function confirmAct(ctx, args) {
9343
- if (ctx.yoloMode) return true;
9344
- if (!ctx.interactions.isAvailable()) return false;
9345
- const response = await ctx.interactions.request({
9346
- type: "confirm",
9347
- id: `computer-use:${Date.now()}`,
9348
- prompt: "Allow computer-use to act on your desktop (click/type/scroll/press)?",
9349
- detail: [
9350
- "Class: computer_use_act",
9351
- `Tool: act_ui \u2014 ${summarizeActArgs(args)}`,
9352
- "",
9353
- "The agent will synthesize real input events on your machine."
9354
- ].join("\n"),
9355
- timeoutMs: 12e4
9356
- }).catch(() => void 0);
9357
- return !!response && response.type === "confirm" && response.confirmed === true;
9358
- }
9359
- function blockedActResult() {
9360
- return {
9361
- content: [{
9362
- type: "text",
9363
- text: "act_ui was blocked: the user did not confirm desktop control (or no interaction handler is available). Do not retry act_ui; explain what you intended to do and ask the user how to proceed."
9364
- }],
9365
- isError: true
9366
- };
9352
+ function requiredFlag(args, name) {
9353
+ const value = args.flags.get(name);
9354
+ if (value === void 0 || value === "") usageError(`missing required option ${name}`);
9355
+ return value;
9367
9356
  }
9368
- function registerPieTool(ctx, spec, options = {}) {
9369
- ctx.registerTool({
9370
- name: spec.name,
9371
- label: spec.label,
9372
- description: spec.description,
9373
- parameters: spec.parameters,
9374
- risk: spec.risk,
9375
- execute: async (args, toolContext) => {
9376
- if (options.confirmAct) {
9377
- const approved = await options.confirmAct(args);
9378
- if (!approved) return blockedActResult();
9379
- }
9380
- const result = await spec.executor(toolContext.toolCallId, args, toolContext.signal, void 0, ctx);
9381
- return result;
9382
- }
9383
- });
9357
+ function optionalFlag(args, name) {
9358
+ const value = args.flags.get(name);
9359
+ return value === void 0 || value === "" ? void 0 : value;
9384
9360
  }
9385
- function formatConfigStatus() {
9386
- const loaded = getLoadedComputerUseConfig();
9387
- return [
9388
- "computer-use configuration",
9389
- `browser_use: ${loaded.config.browser_use ? "enabled" : "disabled"}`,
9390
- `managed_browser: ${loaded.config.managed_browser}`,
9391
- `headless: ${loaded.config.headless ? "enabled" : "disabled"}`,
9392
- `cursor_overlay: ${loaded.config.cursor_overlay ? "enabled" : "disabled"}`,
9393
- "",
9394
- "Sources:",
9395
- ...loaded.sources.map((source) => `- ${source.path}: ${source.error ? `error: ${source.error}` : source.exists ? "loaded" : "not found"}`),
9396
- `- env overrides: ${Object.keys(loaded.env).join(", ") || "none"}`
9397
- ].join("\n");
9361
+ function numericFlag(args, name) {
9362
+ const value = optionalFlag(args, name);
9363
+ if (value === void 0) return void 0;
9364
+ const parsed = Number(value);
9365
+ if (!Number.isFinite(parsed)) usageError(`${name} must be a number (got '${value}')`);
9366
+ return parsed;
9398
9367
  }
9399
- async function initializeSessionState(ctx) {
9400
- loadComputerUseConfig(ctx.cwd);
9401
- reconstructStateFromBranch(ctx);
9402
- }
9403
- function computerUseExtension(ctx) {
9404
- ctx.registerCleanup?.(() => shutdownComputerUseSession());
9405
- let actApproved = false;
9406
- const confirmActOnce = async (args) => {
9407
- if (actApproved) return true;
9408
- const approved = await confirmAct(ctx, args);
9409
- if (approved) actApproved = true;
9410
- return approved;
9411
- };
9412
- for (const spec of OBSERVE_TOOLS) registerPieTool(ctx, spec);
9413
- for (const spec of ACT_TOOLS) registerPieTool(ctx, spec, {
9414
- confirmAct: async (args) => await confirmActOnce(args)
9415
- });
9416
- ctx.registerCommand({
9417
- name: "computer-use",
9418
- description: "Show computer-use configuration",
9419
- handler: (commandCtx) => {
9420
- loadComputerUseConfig(commandCtx.cwd);
9421
- commandCtx.ui.notify(formatConfigStatus(), "info");
9368
+ function jsonFlag(args, name) {
9369
+ const value = requiredFlag(args, name);
9370
+ try {
9371
+ return JSON.parse(value);
9372
+ } catch (error) {
9373
+ usageError(`${name} must be valid JSON (${error.message})`);
9374
+ }
9375
+ }
9376
+ function usageError(message) {
9377
+ process.stderr.write(`computer-use-axi: ${message}
9378
+
9379
+ ${USAGE}
9380
+ `);
9381
+ process.exit(2);
9382
+ }
9383
+ function buildCommand(args) {
9384
+ if (args.command === "browser") {
9385
+ const sub = args.rest[0] ?? usageError("browser requires a subcommand: launch | navigate | eval");
9386
+ if (sub === "launch") return { command: "launch_browser", params: { url: optionalFlag(args, "--url") } };
9387
+ if (sub === "navigate") return { command: "navigate_browser", params: { stateId: requiredFlag(args, "--state"), url: requiredFlag(args, "--url") } };
9388
+ if (sub === "eval") return { command: "evaluate_browser", params: { stateId: requiredFlag(args, "--state"), expression: requiredFlag(args, "--expr") } };
9389
+ usageError(`unknown browser subcommand '${sub}' (expected launch | navigate | eval)`);
9390
+ }
9391
+ switch (args.command) {
9392
+ case "roots":
9393
+ return {
9394
+ command: "find_roots",
9395
+ params: {
9396
+ text: optionalFlag(args, "--text"),
9397
+ app: optionalFlag(args, "--app"),
9398
+ bundleId: optionalFlag(args, "--bundle-id"),
9399
+ pid: numericFlag(args, "--pid"),
9400
+ kind: optionalFlag(args, "--kind")
9401
+ }
9402
+ };
9403
+ case "observe":
9404
+ return {
9405
+ command: "observe_ui",
9406
+ params: { root: optionalFlag(args, "--root"), mode: optionalFlag(args, "--mode") }
9407
+ };
9408
+ case "search": {
9409
+ const params = {
9410
+ text: optionalFlag(args, "--text"),
9411
+ role: optionalFlag(args, "--role"),
9412
+ capability: optionalFlag(args, "--capability"),
9413
+ stateId: requiredFlag(args, "--state")
9414
+ };
9415
+ if (!params.text && !params.role && !params.capability) usageError("search requires at least one of --text, --role, --capability");
9416
+ return { command: "search_ui", params };
9417
+ }
9418
+ case "expand":
9419
+ return { command: "expand_ui", params: { stateId: requiredFlag(args, "--state"), ref: requiredFlag(args, "--ref"), depth: numericFlag(args, "--depth") } };
9420
+ case "inspect":
9421
+ return { command: "inspect_ui", params: { stateId: requiredFlag(args, "--state"), ref: requiredFlag(args, "--ref") } };
9422
+ case "read": {
9423
+ const ref = requiredFlag(args, "--ref");
9424
+ const params = { ref, offset: numericFlag(args, "--offset") };
9425
+ if (ref.startsWith("@e")) params.stateId = requiredFlag(args, "--state");
9426
+ else params.stateId = optionalFlag(args, "--state");
9427
+ return { command: "read_text", params };
9428
+ }
9429
+ case "wait": {
9430
+ const params = {
9431
+ stateId: requiredFlag(args, "--state"),
9432
+ text: optionalFlag(args, "--text"),
9433
+ role: optionalFlag(args, "--role"),
9434
+ value: optionalFlag(args, "--value"),
9435
+ ref: optionalFlag(args, "--ref"),
9436
+ scopeRef: optionalFlag(args, "--scope-ref"),
9437
+ until: optionalFlag(args, "--until"),
9438
+ timeoutMs: numericFlag(args, "--timeout-ms")
9439
+ };
9440
+ if (!params.text && !params.role && !params.ref && !params.value) usageError("wait requires at least one of --text, --role, --value, --ref");
9441
+ if (params.role && !params.text && !params.value && !params.ref && !params.scopeRef) usageError("wait --role requires --ref or --scope-ref (role-only conditions must be scoped)");
9442
+ if (params.value && !params.ref) usageError("wait --value requires --ref (exact element value checks need an exact ref)");
9443
+ return { command: "wait_for", params };
9444
+ }
9445
+ case "act": {
9446
+ const actions = jsonFlag(args, "--actions");
9447
+ if (!Array.isArray(actions) || actions.length === 0) usageError("--actions must be a non-empty JSON array");
9448
+ const params = { stateId: requiredFlag(args, "--state"), actions };
9449
+ const expect = optionalFlag(args, "--expect");
9450
+ if (expect !== void 0) {
9451
+ try {
9452
+ params.expect = JSON.parse(expect);
9453
+ } catch (error) {
9454
+ usageError(`--expect must be valid JSON (${error.message})`);
9455
+ }
9456
+ }
9457
+ return { command: "act_ui", params };
9422
9458
  }
9423
- });
9424
- ctx.on("session:changed", async () => {
9425
- actApproved = false;
9426
- await shutdownComputerUseSession().catch(() => void 0);
9427
- await initializeSessionState(ctx);
9459
+ default:
9460
+ usageError(args.command ? `unknown command '${args.command}'` : "missing command");
9461
+ }
9462
+ }
9463
+ var EXECUTORS = {
9464
+ find_roots: executeFind,
9465
+ observe_ui: executeObserve,
9466
+ search_ui: executeSearchUi,
9467
+ expand_ui: executeExpandUi,
9468
+ inspect_ui: executeInspectUi,
9469
+ read_text: executeReadText,
9470
+ wait_for: executeWaitFor,
9471
+ act_ui: executeAct,
9472
+ launch_browser: executeLaunchBrowser,
9473
+ navigate_browser: executeNavigateBrowser,
9474
+ evaluate_browser: executeEvaluateBrowser
9475
+ };
9476
+ function adaptGuidance(text) {
9477
+ return text.replace(/observe_ui\(\{ root: "(@r\d+)" \}\)/g, "computer-use-axi observe --root $1").replace(/read_text\(\{ ref: "(@o\d+)", offset: (\d+) \}\)/g, "computer-use-axi read --ref $1 --offset $2").replace(/read_text\(\{ ref: "(@o\d+)" \}\)/g, "computer-use-axi read --ref $1").replace(/\bfind_roots\b/g, "computer-use-axi roots").replace(/\bobserve_ui\b/g, "computer-use-axi observe").replace(/\bsearch_ui\b/g, "computer-use-axi search").replace(/\bexpand_ui\b/g, "computer-use-axi expand").replace(/\binspect_ui\b/g, "computer-use-axi inspect").replace(/\bread_text\b/g, "computer-use-axi read").replace(/\bwait_for\b/g, "computer-use-axi wait").replace(/\bact_ui\b/g, "computer-use-axi act").replace(/\blaunch_browser\b/g, "computer-use-axi browser launch").replace(/\bnavigate_browser\b/g, "computer-use-axi browser navigate").replace(/\bevaluate_browser\b/g, "computer-use-axi browser eval").replace(/computer-use-axi observe\(\{ root: "([^"]+)" \}\)/g, 'computer-use-axi observe --root "$1"');
9478
+ }
9479
+ async function main() {
9480
+ const args = parseArgs(process.argv.slice(2));
9481
+ if (args.help || !args.command && args.flags.size === 0) {
9482
+ process.stdout.write(`${USAGE}
9483
+ `);
9484
+ return 0;
9485
+ }
9486
+ const { command, params } = buildCommand(args);
9487
+ const executor = EXECUTORS[command];
9488
+ if (!executor) usageError(`internal: no executor for ${command}`);
9489
+ enableDiskPersistence();
9490
+ await attachPersistedBrowser();
9491
+ const ctx = { cwd: process.cwd(), getMessages: () => [] };
9492
+ const signal = AbortSignal.timeout(Number(process.env.PIE_COMPUTER_USE_AXI_TIMEOUT_MS) > 0 ? Number(process.env.PIE_COMPUTER_USE_AXI_TIMEOUT_MS) : 12e4);
9493
+ try {
9494
+ const result = await executor("cli", params, signal, void 0, ctx);
9495
+ if (args.json) {
9496
+ const adapted = {
9497
+ ...result,
9498
+ content: result.content.map((part) => part.type === "text" && typeof part.text === "string" ? { ...part, text: adaptGuidance(part.text) } : part)
9499
+ };
9500
+ process.stdout.write(`${JSON.stringify(adapted)}
9501
+ `);
9502
+ } else {
9503
+ const text = result.content.map((part) => part.type === "text" && typeof part.text === "string" ? part.text : void 0).filter(Boolean).join("\n");
9504
+ if (text) process.stdout.write(`${adaptGuidance(text)}
9505
+ `);
9506
+ else if (result.content.some((part) => part.type === "image")) process.stdout.write("(image-only observation; use --mode semantic for a text outline or --json for raw content)\n");
9507
+ }
9508
+ if (result.isError) return 1;
9509
+ return 0;
9510
+ } catch (error) {
9511
+ const message = adaptGuidance(error instanceof Error ? error.message : String(error));
9512
+ if (args.json) {
9513
+ process.stdout.write(`${JSON.stringify({ content: [{ type: "text", text: message }], isError: true })}
9514
+ `);
9515
+ } else {
9516
+ process.stderr.write(`${message}
9517
+ `);
9518
+ }
9519
+ return 1;
9520
+ }
9521
+ }
9522
+ var isDirectEntry = (() => {
9523
+ try {
9524
+ return import.meta.url === new URL(`file://${process.argv[1]}`).href;
9525
+ } catch {
9526
+ return false;
9527
+ }
9528
+ })();
9529
+ if (isDirectEntry) {
9530
+ main().then((code) => {
9531
+ process.exitCode = code;
9532
+ }).catch((error) => {
9533
+ process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}
9534
+ `);
9535
+ process.exitCode = 1;
9428
9536
  });
9429
9537
  }
9430
9538
  export {
9431
- computerUseExtension as default
9539
+ USAGE,
9540
+ adaptGuidance,
9541
+ buildCommand,
9542
+ parseArgs,
9543
+ usageError
9432
9544
  };