@agentorg/computer 0.0.22 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,14 +50,30 @@ This computer:
50
50
  - `apps`: the running apps and their windows, and bringing one forward. Each window's `app_name`, `title`, `pid`, `window_id`, `z_index` (higher in front) and `bounds` are also given as fields. The bounds are in the screen's points, not the pixels `act` aims in: to aim at a window, see it and use its picture.
51
51
  - On a machine the service only lends (`serve --lend`), the agent acts only in the background: `act` takes no `delivery_mode`, and `apps` takes no window to bring forward, which would take the person's front app and their typing. Where the driver's answer to `act` advises the foreground, the agent is told in plain words instead. What `see` and `apps` say of the screen is never rewritten.
52
52
  - The driver's hints and suggested next calls, which can name its own tools, aren't passed on with any of the three.
53
- - **The person installs Cua Driver once,** the signed app from cua.ai/download, and on macOS grants it Screen Recording and Accessibility once. AgentComputer never installs or ships it, nor its optional perception extension, which is AGPL. `info` says whether the screen is ready, at Cua Driver 0.49.7 or later, and if not, what to do; attaching with it is refused with 409 until then. `serve --screen-driver PATH` names the program; otherwise it is `cua-driver` on the path, in `~/.local/bin`, or inside `/Applications/CuaDriver.app`.
53
+ - **The person installs Cua Driver once,** the signed app from cua.ai/download, and on macOS grants it Screen Recording and Accessibility once. AgentComputer never installs or ships it, nor its optional perception extension, which is AGPL. `info` says whether the screen is ready, at Cua Driver 0.49.7 or later, and if not, what to do; attaching with it is refused with 409 until then. Once attached, a computer doesn't rest on its screen: brought back as the service starts, or started again, while the screen can't be used, because the person switched it off or it isn't ready, it runs with its terminal, files and browser. Its screen's tools stay listed and say why, in the switch's words or the screen's. While the screen isn't ready, its `screen` surface is `unavailable` with the same words, and reading it checks the screen again; the switch is for agents, and leaves the person's own live view alone. The next call after the screen can be used works, with no restart. Cua Driver is looked for again at each connection, so one installed meanwhile is reached. `serve --screen-driver PATH` names the program; otherwise it is `cua-driver` on the path, in `~/.local/bin`, or inside `/Applications/CuaDriver.app`.
54
54
  - **An app can carry Cua Driver and host it,** as the driver's embedding guide describes, so that the grants are the app's.
55
55
  - The app runs `cua-driver serve --embedded --socket PATH` itself. The service, started with `serve --screen-driver DRIVER --screen-socket PATH`, where DRIVER is the driver inside the app, reaches it there through `cua-driver mcp --embedded`.
56
56
  - The grants are read from that driver, and listed under the outermost app the driver is inside.
57
- - Asked for, they are asked for by the app: the service opens it through the system with `--args grant` and each grant to ask for, `screen-recording` or `accessibility`, which it asks for in turn.
58
- - Once a grant changes, the app restarts its driver, which reads grants once. That ends the connections of computers using the screen, which then say Cua Driver has stopped.
57
+ - Asked for, they are asked for by the app: the service opens it through the system with `--args grant` and the grant to ask for, `screen-recording` or `accessibility`. The app's `grant` shows nothing of its own, no window and no Dock tile, since the switch opens it for Screen Recording's request, which shows nothing.
58
+ - Once a grant changes, the app restarts its driver, which reads grants once. A computer's connection to the driver ends with it, and its screen connects again at its next call: the computer runs on. The driver reads a point against the last picture its connection took, so after such a connection is made again, `act` aimed at a point is refused, saying so, until the screen is seen again.
59
59
  - **What the service starts of Cua Driver sends no telemetry and checks for no updates,** so no update notice reaches a computer's log. The person's own Cua Driver app follows its own settings: `cua-driver telemetry disable` turns its telemetry off.
60
60
 
61
+ **Upgrading from 0.0.23:**
62
+
63
+ - **A computer with the screen no longer stops working because of its screen.**
64
+ - Brought back as the service starts while the screen can't be used (switched off, or not ready), it is `running`, where it was `failed`. `start` on a stopped one is answered `running`, where it was refused with 409 and the computer stayed `stopped`. Its terminal, files and browser work.
65
+ - Its screen's tools are listed and say why, in the switch's words or the screen's. While the screen isn't ready, its `screen` surface has `unavailable` with the same words; switched off, it hasn't, as before. The next call after the screen can be used works, with no restart.
66
+ - Cua Driver stopping while it runs, as when an app hosting it starts it again for a grant, no longer fails the computer: the next screen call connects again. The surface's "Cua Driver has stopped. Stop the computer and start it again." and the screen endpoint's 502 "Cua Driver has stopped." are gone. After such a connection, `act` aimed at a point is refused until the screen is seen again.
67
+ - A client that showed a failed computer for its screen reads the surface's `unavailable`, or the tools' refusals, instead. Attaching with the screen while it can't be used is still refused with 409.
68
+
69
+ **Upgrading from 0.0.22:**
70
+
71
+ - **Turning a part on shows nothing.** `PUT /v1/setup/{capability}` with `{ "on": true }` makes only the requests that show nothing: from macOS 26, Screen Recording's for an app hosting Cua Driver. Accessibility's alert, Cua Driver's own grant window and a browser's inspect page come from `POST /v1/setup/{capability}/ask` with that need, which a client calls from a button the person presses for it. Before macOS 26 Screen Recording waits for its button too; that is untested. `ask` with no need makes only what turning the part on makes.
72
+ - A client that offered only `settings` for a missing grant, relying on the switch's requests, offers `ask` with the grant: the switch no longer has Accessibility list the app in its pane.
73
+ - Turning the browser on with neither Chrome nor Edge installed no longer answers 409; `GET /v1/setup` lists both as `missing`. Turning the screen on without Cua Driver no longer answers 409 either; the screen lists `install` as `missing`.
74
+ - **Asking for a grant of an app hosting the driver now also opens the grant's pane,** a second later, except at the first request of a grant whose request may draw an alert, and it asks for that grant alone. A client that called `settings` after `ask` for the same click calls `ask` alone.
75
+ - Requests made before this version aren't counted. Where the person already answered Accessibility's alert, the first click after the upgrade makes the request alone, which shows nothing; the next opens the pane.
76
+
61
77
  **Upgrading from 0.0.21:**
62
78
 
63
79
  - **An agent's command keeps it acting on its terminal until the command ends,** and 10 seconds after, in `presence` and `GET /v1/acting`, where it was counted for 10 seconds from the command's start. One left running keeps it there, and its `at` can be older than 10 seconds: take the list as it is sent, and drop no one by their `at`.
@@ -216,13 +232,17 @@ These take the control token, kept in the data folder. A computer's own endpoint
216
232
  - The terminal and files need nothing, and are always ready; on macOS the Mac asks folder by folder.
217
233
  - The screen needs Cua Driver, and on macOS its `screen-recording` and `accessibility` grants, each `granted`, `not-granted` or `unknown`; it is ready once both are granted. While Cua Driver isn't installed, the one item is `{ "need": "install", "state": "missing" }`. `holder` names whom System Settings lists the grants under: the outermost app Cua Driver is inside, CuaDriver for its own app, or an app that carries the driver.
218
234
  - The browser lists Chrome, then Edge, each `on` (open, with remote debugging on), `off`, or `missing` (not installed); a service given one browser's folder, with `--own-browser-data`, lists just that one as `named`. It is ready with one on. With both on, the agent's is Chrome.
219
- - **`POST /v1/setup/{capability}/ask`**, with `{ "need": "..." }` or no body, asks the person, on the service's machine, macOS only, for one thing the part needs, or for everything it is missing. It answers once the steps have started, with each part then:
220
- - `screen-recording` or `accessibility`, while it is missing: Cua Driver's own grant, its app started first, through the system, so the Mac names that app. Cua Driver asks in its own order, Accessibility first. For a driver an app hosts, the app asks, for that grant alone, in its own way. The service opens no pane of System Settings. macOS shows each request once: once it has been answered, asking again shows nothing and answers the same, so a client offers `settings` while a grant stays `not-granted`.
235
+ - **`POST /v1/setup/{capability}/ask`**, with `{ "need": "..." }`, asks the person, on the service's machine, macOS only, for one thing the part needs, for a button they press for it. It answers once the steps have started, with each part then:
236
+ - `screen-recording` or `accessibility`, while it is missing, for a driver an app hosts: the app makes macOS's request each time, so macOS asks again whenever it would, such as after a reset of the app's privacy entries.
237
+ - That grant's pane of System Settings opens as well, a second later, by when macOS has listed the app there.
238
+ - Except at the first request the service has made, for that app's bundle identifier, of a grant whose request may draw an alert: `accessibility`, and `screen-recording` before macOS 26. macOS draws that alert until it has been answered, and the alert's own button opens the pane. Which requests were made is kept in the data folder, so it lasts across a restart. After a reset, the alert and the pane both come.
239
+ - From macOS 26 Screen Recording's request draws nothing, so its pane opens each time. Before 26 it is taken to draw an alert; that is untested.
240
+ - `screen-recording` or `accessibility`, while it is missing, for Cua Driver's own app: its own grant, its app started first, through the system, so the Mac names that app. Cua Driver asks in its own order, Accessibility first, in a window of its own.
221
241
  - `chrome` or `edge`: that browser opens at its inspect page, where remote debugging is switched on. One the service was given only the folder of, the person opens themselves.
222
- - With none named: the screen's grant while either is missing; the first browser installed, Chrome before Edge, while none is on.
223
- - What the part doesn't need, a browser that isn't installed, or steps that couldn't be started answer 409, saying why.
224
- - **`POST /v1/setup/{capability}/settings`**, with `{ "need": "screen-recording" }` or `{ "need": "accessibility" }`, opens that grant's pane of System Settings, under Privacy & Security, on the service's machine, macOS only, whether the grant is missing or not, for the person to switch it there. macOS lists an app there once it has asked, so this follows `ask`. It is for the person's own choice, such as a button they press: the service opens a pane nowhere else. Where an app hosts the driver, it is that app that sees the change and starts its driver again. It answers once the pane is asked to open, with each part then. A need the part doesn't have, one with no pane, a pane that couldn't be opened, or a machine other than a Mac answers 409, saying why.
225
- - **`PUT /v1/setup/{capability}`** with `{ "on": true }` or `{ "on": false }` sets a switch. Turning it on, or on again, also asks for everything the part is missing, as asking with no need does. Where that couldn't be started, it answers 409, saying why, and the switch stays on.
242
+ - With no body, or no need named, it makes only what turning the part on makes.
243
+ - What the part doesn't need, a browser that isn't installed, steps that couldn't be started, or a grant's pane that couldn't be opened once macOS's request was made answer 409, saying why.
244
+ - **`POST /v1/setup/{capability}/settings`**, with `{ "need": "screen-recording" }` or `{ "need": "accessibility" }`, opens that grant's pane of System Settings, under Privacy & Security, on the service's machine, macOS only, whether the grant is missing or not, for the person to switch it there. macOS lists an app there once it has asked, so this follows `ask`. It is for the person's own choice, such as a button they press: the service opens a pane only here and from `ask`, each on the person's click. Where an app hosts the driver, it is that app that sees the change and starts its driver again. It answers once the pane is asked to open, with each part then. A need the part doesn't have, one with no pane, a pane that couldn't be opened, or a machine other than a Mac answers 409, saying why.
245
+ - **`PUT /v1/setup/{capability}`** with `{ "on": true }` or `{ "on": false }` sets a switch. Turning it on, or on again, makes only the requests that show nothing, on the service's machine, macOS only: from macOS 26, Screen Recording's for an app hosting Cua Driver, while it is missing, which lists the app in its pane. Nothing that shows an alert or a window comes from the switch: each comes from `ask` with that need, on the person's click. Where a request it makes couldn't be started, it answers 409, saying why, and the switch stays on.
226
246
  - **`GET /v1/acting`** is who is acting now on every computer attached to this machine, in one list, as each one's `presence` surface has it. A computer in a container isn't included: its own `presence` surface has it.
227
247
 
228
248
  ## SDK
@@ -98140,27 +98140,87 @@ var Driver = class {
98140
98140
  return await this.#client.callTool({ name: tool, arguments: args });
98141
98141
  }
98142
98142
  };
98143
- var Screen = class extends Driver {
98143
+ var Screen = class {
98144
+ /** Cua Driver as it is found at each connection. */
98145
+ #at;
98146
+ #log;
98144
98147
  #noted;
98145
98148
  #refused;
98149
+ /** The driver's connection, while there is one. */
98150
+ #driver;
98151
+ #stopped = false;
98152
+ /** How many connections it has made, and whether the screen was seen on the one there is. */
98153
+ #connections = 0;
98154
+ #seen = false;
98146
98155
  /** On a lent machine: the agent acts only in the background, leaving the person's pointer. */
98147
98156
  #onlyBackground;
98148
98157
  /**
98149
98158
  * `noted` gives the line to add to each answer: who else acted on the screen. `refused` says why
98150
- * no call is answered now, while the person has it switched off. `onlyBackground`: whether the
98151
- * agent acts only in the background, as on a lent machine.
98159
+ * no call is answered now: the person has it switched off, or it isn't ready. `onlyBackground`:
98160
+ * whether the agent acts only in the background, as on a lent machine.
98152
98161
  */
98153
- constructor(driver, log, exited, noted, refused2, onlyBackground) {
98154
- super(driver, log, exited);
98162
+ constructor(driver, log, noted, refused2, onlyBackground) {
98163
+ this.#at = driver;
98164
+ this.#log = log;
98155
98165
  this.#noted = noted;
98156
98166
  this.#refused = refused2;
98157
98167
  this.#onlyBackground = onlyBackground;
98158
98168
  }
98169
+ /** The driver's connection: the one there is, or a new one, once it answers. */
98170
+ async #connected() {
98171
+ if (this.#stopped) throw new ApiError(409, "It has stopped.");
98172
+ if (!this.#driver) {
98173
+ const made = new Driver(this.#at(), this.#log, () => {
98174
+ if (this.#driver === made) this.#driver = void 0;
98175
+ });
98176
+ this.#driver = made;
98177
+ this.#connections += 1;
98178
+ this.#seen = false;
98179
+ }
98180
+ const driver = this.#driver;
98181
+ try {
98182
+ await driver.ready();
98183
+ } catch (error64) {
98184
+ if (this.#driver === driver) this.#driver = void 0;
98185
+ void driver.stop();
98186
+ throw error64;
98187
+ }
98188
+ return driver;
98189
+ }
98190
+ /** Connect now, and wait until the driver answers, or say why it didn't. */
98191
+ async ready() {
98192
+ await this.#connected();
98193
+ }
98194
+ async call(tool, args) {
98195
+ return (await this.#connected()).call(tool, args);
98196
+ }
98197
+ /**
98198
+ * Why a call aimed at a point is refused now: the driver reads a point against the last picture
98199
+ * its connection took, and a connection made again, as when the driver is started again for a
98200
+ * grant, has taken none. Seen again, it aims as it should.
98201
+ */
98202
+ async #unseen(input3) {
98203
+ if (input3.element_token !== void 0 || input3.x === void 0) return void 0;
98204
+ await this.#connected();
98205
+ if (this.#connections === 1 || this.#seen) return void 0;
98206
+ return {
98207
+ content: [
98208
+ text3(
98209
+ "Cua Driver was started again since the screen was last seen, as when a grant changes: see it again, then aim at its point."
98210
+ )
98211
+ ],
98212
+ isError: true
98213
+ };
98214
+ }
98215
+ async stop() {
98216
+ this.#stopped = true;
98217
+ await this.#driver?.stop();
98218
+ }
98159
98219
  /** The agent's three tools, each answered with what the driver answers, and the line after it. */
98160
98220
  #server() {
98161
98221
  const server = new McpServer2({ name: "agentcomputer-screen", version: "1" });
98162
98222
  const answered2 = async (work) => {
98163
- const refusal = this.#refused();
98223
+ const refusal = await this.#refused();
98164
98224
  if (refusal) return { content: [text3(refusal)], isError: true };
98165
98225
  const line = this.#noted();
98166
98226
  const answer = forAgent(await work().catch(failed));
@@ -98178,11 +98238,11 @@ var Screen = class extends Driver {
98178
98238
  inputSchema: Seen
98179
98239
  },
98180
98240
  ({ pid, window_id }) => answered2(async () => {
98181
- if (pid === void 0 && window_id === void 0)
98182
- return this.call("get_desktop_state", {});
98183
- if (pid === void 0 || window_id === void 0)
98241
+ if (pid === void 0 !== (window_id === void 0))
98184
98242
  throw new ApiError(400, "A window is its pid and its window_id, from apps: give both.");
98185
- return this.call("get_window_state", { pid, window_id });
98243
+ const seen = await (pid === void 0 ? this.call("get_desktop_state", {}) : this.call("get_window_state", { pid, window_id }));
98244
+ if (!seen.isError) this.#seen = true;
98245
+ return seen;
98186
98246
  })
98187
98247
  );
98188
98248
  server.registerTool(
@@ -98193,6 +98253,8 @@ var Screen = class extends Driver {
98193
98253
  },
98194
98254
  (input3) => answered2(async () => {
98195
98255
  const [tool, args] = driverCall(input3);
98256
+ const unseen = await this.#unseen(input3);
98257
+ if (unseen) return unseen;
98196
98258
  const answer = await this.call(tool, args).catch(failed);
98197
98259
  const said2 = (answer.content ?? []).map((part) => part.text ?? "").join("\n");
98198
98260
  if (this.#onlyBackground && /delivery_mode\W*foreground/i.test(said2))
@@ -98252,9 +98314,8 @@ var Screen = class extends Driver {
98252
98314
  );
98253
98315
  return server;
98254
98316
  }
98255
- /** Answer one MCP request, as the stateless transport does. */
98317
+ /** Answer one MCP request, as the stateless transport does. Its tools are listed with no driver. */
98256
98318
  async handle(request2, response) {
98257
- await this.ready();
98258
98319
  const server = this.#server();
98259
98320
  const transport = new NodeStreamableHTTPServerTransport2({ sessionIdGenerator: void 0 });
98260
98321
  response.once("close", () => {
@@ -98313,6 +98374,7 @@ var said = (answer) => (answer.content ?? []).flatMap(
98313
98374
  ).join("\n") || "Cua Driver refused it.";
98314
98375
  var ScreenLive = class {
98315
98376
  /** Where Cua Driver is. */
98377
+ /** Cua Driver as it is found at each connection. */
98316
98378
  #at;
98317
98379
  #log;
98318
98380
  /** Heard each time a person acts on the screen. */
@@ -98364,7 +98426,7 @@ var ScreenLive = class {
98364
98426
  /** The driver, connected once for everyone watching, and the frames it is taken for. */
98365
98427
  #begin() {
98366
98428
  if (this.#started) return this.#started;
98367
- const driver = new Driver(this.#at, this.#log, () => {
98429
+ const driver = new Driver(this.#at(), this.#log, () => {
98368
98430
  if (this.#driver === driver) this.#leave(1011, "Cua Driver stopped.");
98369
98431
  });
98370
98432
  this.#driver = driver;
@@ -98591,6 +98653,35 @@ var ProcessRuntime = class {
98591
98653
  const { at: _, ...ready } = this.#screen;
98592
98654
  return ready;
98593
98655
  }
98656
+ /**
98657
+ * Why an agent's screen call is refused now: the person switched it off, or the screen wasn't
98658
+ * ready at the last check. While it isn't, each call checks it afresh, so that a grant given is
98659
+ * used at the next call; while it is, calls aren't held up by checks.
98660
+ */
98661
+ async #screenRefused() {
98662
+ const off = this.#switches?.refused("screen");
98663
+ if (off) return off;
98664
+ if (this.#screen.ready) return void 0;
98665
+ const { readiness: now } = await this.#checkScreen();
98666
+ return now.ready ? void 0 : now.reason ?? "The screen isn't ready.";
98667
+ }
98668
+ /**
98669
+ * Why the screen can't be opened live now: it isn't ready, as the last check says, which is
98670
+ * checked again meanwhile, for the next to read. The person's switch is for agents, and leaves
98671
+ * the person's own live view alone.
98672
+ */
98673
+ #screenUnavailable() {
98674
+ if (this.#screen.ready) return void 0;
98675
+ void this.#checkScreen();
98676
+ return this.#screen.reason ?? "The screen isn't ready.";
98677
+ }
98678
+ /** Cua Driver as it is found now: where it was named or found, or where it was to be. */
98679
+ #driverNow() {
98680
+ return findDriver(this.#screenDriver) ?? {
98681
+ ...this.#screenDriver,
98682
+ program: this.#screenDriver.program ?? "cua-driver"
98683
+ };
98684
+ }
98594
98685
  /** Why the agent can't call this tool now: the person switched off what it reaches. */
98595
98686
  #toolRefused(tool) {
98596
98687
  const which = TOOL_SWITCH[tool];
@@ -98712,31 +98803,35 @@ var ProcessRuntime = class {
98712
98803
  }
98713
98804
  let screen;
98714
98805
  let screenLive;
98715
- let screenDown = false;
98716
98806
  if (spec.screen) {
98717
98807
  const { readiness: ready, driver } = await this.#checkScreen();
98718
- const refused2 = this.#switches?.refused("screen");
98719
- screen = ready.ready && driver && !refused2 ? new Screen(
98720
- driver,
98808
+ const why = this.#switches?.refused("screen") ?? (ready.ready && driver ? void 0 : ready.reason ?? "The screen isn't ready.");
98809
+ if (why && !spec.again) {
98810
+ await Promise.all([exec2?.close(), browser?.stop()]);
98811
+ throw new ApiError(409, why);
98812
+ }
98813
+ const at = () => this.#driverNow();
98814
+ screen = new Screen(
98815
+ at,
98721
98816
  events.log,
98722
- () => {
98723
- screenDown = true;
98724
- events.failed("Cua Driver stopped.");
98725
- },
98726
98817
  () => presence.agentCalled({ capability: "screen" }),
98727
- () => this.#switches?.refused("screen"),
98818
+ () => this.#screenRefused(),
98728
98819
  // On a lent machine the agent acts only in the background.
98729
98820
  this.#switches?.lends ?? false
98730
- ) : void 0;
98731
- try {
98732
- if (!screen) throw new ApiError(409, refused2 ?? ready.reason ?? "The screen isn't ready.");
98733
- await screen.ready();
98734
- } catch (error64) {
98735
- await Promise.all([exec2?.close(), browser?.stop(), screen?.stop()]);
98736
- throw error64;
98737
- }
98821
+ );
98822
+ if (why) events.log(`It started without its screen, which its tools say: ${why}`);
98823
+ else
98824
+ try {
98825
+ await screen.ready();
98826
+ } catch (error64) {
98827
+ if (!spec.again) {
98828
+ await Promise.all([exec2?.close(), browser?.stop(), screen.stop()]);
98829
+ throw error64;
98830
+ }
98831
+ events.log(`Its screen connects at its next call: ${error64.message}`);
98832
+ }
98738
98833
  screenLive = new ScreenLive(
98739
- driver,
98834
+ at,
98740
98835
  (line) => events.log(`Live view: ${line}`),
98741
98836
  () => presence.acted("person", { capability: "screen" })
98742
98837
  );
@@ -98758,19 +98853,21 @@ var ProcessRuntime = class {
98758
98853
  () => presence.acted("person", { capability: "files" })
98759
98854
  );
98760
98855
  const live = new Live(exec2, spec.access, load, presence, files, browserLive, screenLive);
98856
+ const unavailableNow = () => this.#screenUnavailable();
98761
98857
  const surfaces = live.surfaces();
98762
98858
  return {
98763
98859
  browserTools: browser?.tools ?? [],
98764
- /** As they are now: a browser or a driver that has stopped can't be opened, and says so. */
98860
+ /**
98861
+ * As they are now: a browser that has stopped can't be opened, and says so; nor can the
98862
+ * screen while it can't be used, as its tools say.
98863
+ */
98765
98864
  get surfaces() {
98865
+ const screenWhy = screen && unavailableNow();
98766
98866
  return surfaces.map(
98767
98867
  (one) => one.surface === "browser" && browserDown ? {
98768
98868
  ...one,
98769
98869
  unavailable: "Its browser has stopped. Stop the computer and start it again."
98770
- } : one.surface === "screen" && screenDown ? {
98771
- ...one,
98772
- unavailable: "Cua Driver has stopped. Stop the computer and start it again."
98773
- } : one
98870
+ } : one.surface === "screen" && screenWhy ? { ...one, unavailable: screenWhy } : one
98774
98871
  );
98775
98872
  },
98776
98873
  acting: () => presence.acting(),
@@ -98788,10 +98885,7 @@ var ProcessRuntime = class {
98788
98885
  if (refusal) return refuseCall(response, message.id, refusal);
98789
98886
  return agentExec.handle(request2, response, message);
98790
98887
  }
98791
- if (endpoint === "screen") {
98792
- if (screenDown) throw new ApiError(502, "Cua Driver has stopped.");
98793
- return screen.handle(request2, response);
98794
- }
98888
+ if (endpoint === "screen") return screen.handle(request2, response);
98795
98889
  if (browserDown) throw new ApiError(502, "Its browser has stopped.");
98796
98890
  return browser.handle(request2, response);
98797
98891
  },
@@ -98805,7 +98899,7 @@ var ProcessRuntime = class {
98805
98899
  };
98806
98900
 
98807
98901
  // src/handlers.ts
98808
- var VERSION2 = "0.0.22";
98902
+ var VERSION2 = "0.0.24";
98809
98903
  function createHandlers(computers, connections, setup) {
98810
98904
  return {
98811
98905
  getInfo: async () => ({ version: VERSION2, ...await computers.offers() }),
@@ -100264,7 +100358,7 @@ var Computers = class {
100264
100358
  return;
100265
100359
  }
100266
100360
  const live = {};
100267
- await this.#start(stored, live).catch((error64) => {
100361
+ await this.#start(stored, live, true).catch((error64) => {
100268
100362
  const why = `It didn't start again: ${messageOf2(error64)}`;
100269
100363
  this.#log(stored.id, why);
100270
100364
  if (this.#live.get(stored.id) !== live) return;
@@ -100437,7 +100531,7 @@ var Computers = class {
100437
100531
  stored.state = "running";
100438
100532
  const live = {};
100439
100533
  try {
100440
- await this.#start(stored, live);
100534
+ await this.#start(stored, live, true);
100441
100535
  } catch (error64) {
100442
100536
  if (this.#live.get(id) === live) {
100443
100537
  await this.#halt(id);
@@ -100597,7 +100691,7 @@ var Computers = class {
100597
100691
  * Start it, as `live`. Stopped, killed or started again while it waits, it is refused, and what
100598
100692
  * came up meanwhile is stopped: nothing is left that no call reaches.
100599
100693
  */
100600
- async #start(stored, live) {
100694
+ async #start(stored, live, again = false) {
100601
100695
  this.#live.set(stored.id, live);
100602
100696
  const stopped = () => this.#live.get(stored.id) !== live;
100603
100697
  const STOPPED = "It was stopped while it was starting.";
@@ -100617,6 +100711,7 @@ var Computers = class {
100617
100711
  access: stored.access,
100618
100712
  browser: stored.browser,
100619
100713
  screen: stored.screen === true,
100714
+ again,
100620
100715
  workspace: stored.workspace
100621
100716
  },
100622
100717
  this.#folder(stored.id),
@@ -100736,7 +100831,7 @@ var OPENAPI = {
100736
100831
  "openapi": "3.1.0",
100737
100832
  "info": {
100738
100833
  "title": "AgentComputer",
100739
- "version": "0.0.22",
100834
+ "version": "0.0.24",
100740
100835
  "description": "Computers for agents. This file is the source of truth: the HTTP API, the MCP control tools and the SDK are all generated from it. An operation with `x-mcp-tool` is also an MCP tool of that name.",
100741
100836
  "license": {
100742
100837
  "name": "Apache-2.0",
@@ -100832,7 +100927,7 @@ var OPENAPI = {
100832
100927
  ],
100833
100928
  "put": {
100834
100929
  "operationId": "setSetup",
100835
- "summary": "Set a part's switch, which lasts across restarts. Turning it on, or on again, also asks for everything the part is missing, as asking for it with no need named does. Where that couldn't be started, it answers 409, saying why, and the switch stays on.",
100930
+ "summary": "Set a part's switch, which lasts across restarts. Turning it on, or on again, makes only the requests that show nothing, on the service's machine, macOS only: from macOS 26, Screen Recording's for an app hosting Cua Driver, while it is missing, which lists the app in its pane. Nothing that shows an alert or a window comes from the switch: Accessibility's alert, Cua Driver's own grant window and a browser's inspect page each come from ask with that need, on the person's click. Before macOS 26 Screen Recording's request is taken to draw an alert, so it waits for ask too; that is untested. Where a request it makes couldn't be started, it answers 409, saying why, and the switch stays on.",
100836
100931
  "requestBody": {
100837
100932
  "required": true,
100838
100933
  "content": {
@@ -100854,7 +100949,7 @@ var OPENAPI = {
100854
100949
  },
100855
100950
  "responses": {
100856
100951
  "200": {
100857
- "description": "Set, and its steps started.",
100952
+ "description": "Set, and any request it makes started.",
100858
100953
  "content": {
100859
100954
  "application/json": {
100860
100955
  "schema": {
@@ -100867,7 +100962,7 @@ var OPENAPI = {
100867
100962
  "$ref": "#/components/responses/Unauthorized"
100868
100963
  },
100869
100964
  "409": {
100870
- "description": "On, but the steps that ask for what it needs couldn't be started.",
100965
+ "description": "On, but a request it makes couldn't be started.",
100871
100966
  "content": {
100872
100967
  "application/json": {
100873
100968
  "schema": {
@@ -100892,7 +100987,7 @@ var OPENAPI = {
100892
100987
  ],
100893
100988
  "post": {
100894
100989
  "operationId": "askSetup",
100895
- "summary": "Ask the person, on the service's machine, macOS only, for one thing a part needs, or, with none named, for everything it is missing. screen-recording or accessibility, while it is missing: Cua Driver's own grant, its app started first, which makes the system's requests in its own order, Accessibility first. For a driver an app hosts, the app asks, for that grant alone, in its own way. The service opens no pane of System Settings: the person opens one with settings. macOS shows each request once: once it has been answered, asking again shows nothing and answers the same, so a client offers settings while a grant stays not-granted. chrome or edge: that browser opens at its inspect page, where remote debugging is switched on. With none named, the screen's grant while either is missing, and the first browser installed, Chrome before Edge, while none is on. It answers once the steps have started, with each part then; what the person does next is read afresh later. A browser the service was given only the folder of, the person opens. Elsewhere it asks for nothing.",
100990
+ "summary": "Ask the person, on the service's machine, macOS only, for one thing a part needs, for a button they press for it. screen-recording or accessibility, while it is missing: for a driver an app hosts, the app makes macOS's request each time, so that macOS asks again whenever it would, such as after a reset of the app's privacy entries. That grant's pane of System Settings opens as well, a second later, except at the first request the service has made, for that app's bundle identifier, of a grant whose request may draw an alert: accessibility, and screen-recording before macOS 26. macOS draws that alert until it has been answered, and the alert's own button opens the pane; after a reset, the alert and the pane both come. From macOS 26 Screen Recording's request draws nothing, so its pane opens each time. For Cua Driver's own app, while it is missing: its own grant, its app started first, which makes the system's requests in its own order, Accessibility first, in a window of its own. chrome or edge: that browser opens at its inspect page, where remote debugging is switched on. With none named, it makes only what turning the part on makes. It answers once the steps have started, with each part then; what the person does next is read afresh later. A browser the service was given only the folder of, the person opens. Elsewhere it asks for nothing.",
100896
100991
  "requestBody": {
100897
100992
  "content": {
100898
100993
  "application/json": {
@@ -100923,7 +101018,7 @@ var OPENAPI = {
100923
101018
  "$ref": "#/components/responses/Unauthorized"
100924
101019
  },
100925
101020
  "409": {
100926
- "description": "The part doesn't need that here, or what it needs can't be asked for, such as a browser that isn't installed, or the steps couldn't be started.",
101021
+ "description": "The part doesn't need that here, or what it needs can't be asked for, such as a browser that isn't installed, or the steps couldn't be started, or, once macOS's request was made, the grant's pane couldn't be opened.",
100927
101022
  "content": {
100928
101023
  "application/json": {
100929
101024
  "schema": {
@@ -100948,7 +101043,7 @@ var OPENAPI = {
100948
101043
  ],
100949
101044
  "post": {
100950
101045
  "operationId": "openSetupSettings",
100951
- "summary": "Open the pane of System Settings for one thing a part needs, on the service's machine, macOS only, for the person to switch it there: screen-recording or accessibility, that grant's pane under Privacy & Security, whether it is missing or not. macOS lists an app there once it has asked, so this follows ask. It is for the person's own choice, such as a button they press: the service opens a pane nowhere else. Where an app hosts the driver, it is that app that sees the change and starts its driver again. It answers once the pane is asked to open, with each part then. Elsewhere it answers 409.",
101046
+ "summary": "Open the pane of System Settings for one thing a part needs, on the service's machine, macOS only, for the person to switch it there: screen-recording or accessibility, that grant's pane under Privacy & Security, whether it is missing or not. macOS lists an app there once it has asked, so this follows ask. It is for the person's own choice, such as a button they press: the service opens a pane only here and from ask, each on the person's click. Where an app hosts the driver, it is that app that sees the change and starts its driver again. It answers once the pane is asked to open, with each part then. Elsewhere it answers 409.",
100952
101047
  "requestBody": {
100953
101048
  "required": true,
100954
101049
  "content": {
@@ -101495,7 +101590,7 @@ var OPENAPI = {
101495
101590
  "stopped",
101496
101591
  "failed"
101497
101592
  ],
101498
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
101593
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
101499
101594
  },
101500
101595
  "Progress": {
101501
101596
  "type": "object",
@@ -101617,7 +101712,7 @@ var OPENAPI = {
101617
101712
  "screen": {
101618
101713
  "type": "boolean",
101619
101714
  "default": false,
101620
- "description": "Whether its agent has the machine's screen: to see it and act on it, through Cua Driver, which the person installs and grants Screen Recording and Accessibility once. It acts as the person, whatever `access` says. Refused with 409 where `info` says the screen isn't ready."
101715
+ "description": "Whether its agent has the machine's screen: to see it and act on it, through Cua Driver, which the person installs and grants Screen Recording and Accessibility once. It acts as the person, whatever `access` says. Refused with 409 where `info` says the screen isn't ready. Once attached, the computer doesn't rest on it: brought back or started again while the screen can't be used, it runs, and its screen's tools say why."
101621
101716
  },
101622
101717
  "workspace": {
101623
101718
  "type": "string",
@@ -103821,7 +103916,7 @@ var OPERATIONS = [
103821
103916
  "operationId": "setSetup",
103822
103917
  "method": "PUT",
103823
103918
  "path": "/v1/setup/{capability}",
103824
- "summary": "Set a part's switch, which lasts across restarts. Turning it on, or on again, also asks for everything the part is missing, as asking for it with no need named does. Where that couldn't be started, it answers 409, saying why, and the switch stays on.",
103919
+ "summary": "Set a part's switch, which lasts across restarts. Turning it on, or on again, makes only the requests that show nothing, on the service's machine, macOS only: from macOS 26, Screen Recording's for an app hosting Cua Driver, while it is missing, which lists the app in its pane. Nothing that shows an alert or a window comes from the switch: Accessibility's alert, Cua Driver's own grant window and a browser's inspect page each come from ask with that need, on the person's click. Before macOS 26 Screen Recording's request is taken to draw an alert, so it waits for ask too; that is untested. Where a request it makes couldn't be started, it answers 409, saying why, and the switch stays on.",
103825
103920
  "status": 200,
103826
103921
  "hasBody": true,
103827
103922
  "pathParameters": [
@@ -103943,7 +104038,7 @@ var OPERATIONS = [
103943
104038
  "operationId": "askSetup",
103944
104039
  "method": "POST",
103945
104040
  "path": "/v1/setup/{capability}/ask",
103946
- "summary": "Ask the person, on the service's machine, macOS only, for one thing a part needs, or, with none named, for everything it is missing. screen-recording or accessibility, while it is missing: Cua Driver's own grant, its app started first, which makes the system's requests in its own order, Accessibility first. For a driver an app hosts, the app asks, for that grant alone, in its own way. The service opens no pane of System Settings: the person opens one with settings. macOS shows each request once: once it has been answered, asking again shows nothing and answers the same, so a client offers settings while a grant stays not-granted. chrome or edge: that browser opens at its inspect page, where remote debugging is switched on. With none named, the screen's grant while either is missing, and the first browser installed, Chrome before Edge, while none is on. It answers once the steps have started, with each part then; what the person does next is read afresh later. A browser the service was given only the folder of, the person opens. Elsewhere it asks for nothing.",
104041
+ "summary": "Ask the person, on the service's machine, macOS only, for one thing a part needs, for a button they press for it. screen-recording or accessibility, while it is missing: for a driver an app hosts, the app makes macOS's request each time, so that macOS asks again whenever it would, such as after a reset of the app's privacy entries. That grant's pane of System Settings opens as well, a second later, except at the first request the service has made, for that app's bundle identifier, of a grant whose request may draw an alert: accessibility, and screen-recording before macOS 26. macOS draws that alert until it has been answered, and the alert's own button opens the pane; after a reset, the alert and the pane both come. From macOS 26 Screen Recording's request draws nothing, so its pane opens each time. For Cua Driver's own app, while it is missing: its own grant, its app started first, which makes the system's requests in its own order, Accessibility first, in a window of its own. chrome or edge: that browser opens at its inspect page, where remote debugging is switched on. With none named, it makes only what turning the part on makes. It answers once the steps have started, with each part then; what the person does next is read afresh later. A browser the service was given only the folder of, the person opens. Elsewhere it asks for nothing.",
103947
104042
  "status": 200,
103948
104043
  "hasBody": true,
103949
104044
  "pathParameters": [
@@ -104073,7 +104168,7 @@ var OPERATIONS = [
104073
104168
  "operationId": "openSetupSettings",
104074
104169
  "method": "POST",
104075
104170
  "path": "/v1/setup/{capability}/settings",
104076
- "summary": "Open the pane of System Settings for one thing a part needs, on the service's machine, macOS only, for the person to switch it there: screen-recording or accessibility, that grant's pane under Privacy & Security, whether it is missing or not. macOS lists an app there once it has asked, so this follows ask. It is for the person's own choice, such as a button they press: the service opens a pane nowhere else. Where an app hosts the driver, it is that app that sees the change and starts its driver again. It answers once the pane is asked to open, with each part then. Elsewhere it answers 409.",
104171
+ "summary": "Open the pane of System Settings for one thing a part needs, on the service's machine, macOS only, for the person to switch it there: screen-recording or accessibility, that grant's pane under Privacy & Security, whether it is missing or not. macOS lists an app there once it has asked, so this follows ask. It is for the person's own choice, such as a button they press: the service opens a pane only here and from ask, each on the person's click. Where an app hosts the driver, it is that app that sees the change and starts its driver again. It answers once the pane is asked to open, with each part then. Elsewhere it answers 409.",
104077
104172
  "status": 200,
104078
104173
  "hasBody": true,
104079
104174
  "pathParameters": [
@@ -104285,7 +104380,7 @@ var OPERATIONS = [
104285
104380
  "stopped",
104286
104381
  "failed"
104287
104382
  ],
104288
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
104383
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
104289
104384
  }
104290
104385
  },
104291
104386
  "required": []
@@ -104327,7 +104422,7 @@ var OPERATIONS = [
104327
104422
  "stopped",
104328
104423
  "failed"
104329
104424
  ],
104330
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
104425
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
104331
104426
  },
104332
104427
  "reason": {
104333
104428
  "type": [
@@ -104594,7 +104689,7 @@ var OPERATIONS = [
104594
104689
  "stopped",
104595
104690
  "failed"
104596
104691
  ],
104597
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
104692
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
104598
104693
  },
104599
104694
  "reason": {
104600
104695
  "type": [
@@ -104811,7 +104906,7 @@ var OPERATIONS = [
104811
104906
  "screen": {
104812
104907
  "type": "boolean",
104813
104908
  "default": false,
104814
- "description": "Whether its agent has the machine's screen: to see it and act on it, through Cua Driver, which the person installs and grants Screen Recording and Accessibility once. It acts as the person, whatever `access` says. Refused with 409 where `info` says the screen isn't ready."
104909
+ "description": "Whether its agent has the machine's screen: to see it and act on it, through Cua Driver, which the person installs and grants Screen Recording and Accessibility once. It acts as the person, whatever `access` says. Refused with 409 where `info` says the screen isn't ready. Once attached, the computer doesn't rest on it: brought back or started again while the screen can't be used, it runs, and its screen's tools say why."
104815
104910
  },
104816
104911
  "workspace": {
104817
104912
  "type": "string",
@@ -104875,7 +104970,7 @@ var OPERATIONS = [
104875
104970
  "stopped",
104876
104971
  "failed"
104877
104972
  ],
104878
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
104973
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
104879
104974
  },
104880
104975
  "reason": {
104881
104976
  "type": [
@@ -105110,7 +105205,7 @@ var OPERATIONS = [
105110
105205
  "stopped",
105111
105206
  "failed"
105112
105207
  ],
105113
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
105208
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
105114
105209
  },
105115
105210
  "reason": {
105116
105211
  "type": [
@@ -105445,7 +105540,7 @@ var OPERATIONS = [
105445
105540
  "stopped",
105446
105541
  "failed"
105447
105542
  ],
105448
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
105543
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
105449
105544
  },
105450
105545
  "reason": {
105451
105546
  "type": [
@@ -105664,7 +105759,7 @@ var OPERATIONS = [
105664
105759
  "stopped",
105665
105760
  "failed"
105666
105761
  ],
105667
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
105762
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
105668
105763
  },
105669
105764
  "reason": {
105670
105765
  "type": [
@@ -105888,7 +105983,7 @@ var OPERATIONS = [
105888
105983
  "stopped",
105889
105984
  "failed"
105890
105985
  ],
105891
- "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again."
105986
+ "description": "starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again."
105892
105987
  },
105893
105988
  "reason": {
105894
105989
  "type": [
@@ -106444,7 +106539,8 @@ ${JSON.stringify({ code: status, message })}
106444
106539
 
106445
106540
  // src/setup.ts
106446
106541
  import { execFile as execFile5, spawn as spawn6 } from "node:child_process";
106447
- import { realpathSync as realpathSync3 } from "node:fs";
106542
+ import { existsSync as existsSync5, readFileSync as readFileSync9, realpathSync as realpathSync3 } from "node:fs";
106543
+ import { release } from "node:os";
106448
106544
  import { basename as basename3, join as join14 } from "node:path";
106449
106545
  import { promisify as promisify5 } from "node:util";
106450
106546
 
@@ -106472,12 +106568,15 @@ var WHAT = {
106472
106568
  browser: "their own browser"
106473
106569
  };
106474
106570
  var Switches = class {
106571
+ /** The service's own folder, where they are kept. */
106572
+ folder;
106475
106573
  #file;
106476
106574
  #lend;
106477
106575
  /** Only those the person set: the rest take the default of the way the service was started. */
106478
106576
  #set;
106479
106577
  /** `folder` is the service's own; `lend`, whether it only lends its machine. */
106480
106578
  constructor(folder, lend) {
106579
+ this.folder = folder;
106481
106580
  this.#file = join13(folder, "switches.json");
106482
106581
  this.#lend = lend;
106483
106582
  this.#set = existsSync4(this.#file) ? kept(this.#file) : {};
@@ -106508,6 +106607,7 @@ var Switches = class {
106508
106607
  var exec = promisify5(execFile5);
106509
106608
  var thisMachine = () => ({
106510
106609
  ...here(),
106610
+ release: release(),
106511
106611
  run: async (program2, args) => {
106512
106612
  try {
106513
106613
  await exec(program2, args, { timeout: 3e4 });
@@ -106527,6 +106627,8 @@ var thisMachine = () => ({
106527
106627
  });
106528
106628
  var IN_APP = /^(.*?\/[^/]+\.app)\/Contents\/(MacOS\/[^/]+$)?/;
106529
106629
  var APP_MS = 1e4;
106630
+ var PANE_MS = 1e3;
106631
+ var SILENT_FROM = 25;
106530
106632
  async function infoValue(app, key) {
106531
106633
  const plist = join14(app, "Contents", "Info.plist");
106532
106634
  try {
@@ -106548,18 +106650,48 @@ var PANE = {
106548
106650
  "screen-recording": "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture",
106549
106651
  accessibility: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"
106550
106652
  };
106653
+ var Made = class {
106654
+ #file;
106655
+ #made;
106656
+ constructor(folder) {
106657
+ this.#file = join14(folder, "requests.json");
106658
+ this.#made = {};
106659
+ try {
106660
+ const read = existsSync5(this.#file) ? JSON.parse(readFileSync9(this.#file, "utf8")) : {};
106661
+ if (read && typeof read === "object" && !Array.isArray(read)) {
106662
+ for (const [app, needs] of Object.entries(read))
106663
+ if (Array.isArray(needs) && needs.every((need) => typeof need === "string"))
106664
+ this.#made[app] = needs;
106665
+ }
106666
+ } catch {
106667
+ }
106668
+ }
106669
+ has(app, need) {
106670
+ return this.#made[app]?.includes(need) ?? false;
106671
+ }
106672
+ add(app, need) {
106673
+ if (this.has(app, need)) return;
106674
+ this.#made[app] = [...this.#made[app] ?? [], need];
106675
+ try {
106676
+ writePrivate(this.#file, JSON.stringify(this.#made));
106677
+ } catch {
106678
+ }
106679
+ }
106680
+ };
106551
106681
  var NOTHING = { ready: true, needs: [] };
106552
106682
  var Setup = class {
106553
106683
  #switches;
106554
106684
  #driver;
106555
106685
  #browserData;
106556
106686
  #machine;
106687
+ #made;
106557
106688
  /** `driver` and `browserData` are as `serve` names them: Cua Driver, and the browser's folder. */
106558
106689
  constructor(switches, driver = {}, browserData, machine2 = thisMachine()) {
106559
106690
  this.#switches = switches;
106560
106691
  this.#driver = driver;
106561
106692
  this.#browserData = browserData;
106562
106693
  this.#machine = machine2;
106694
+ this.#made = new Made(switches.folder);
106563
106695
  }
106564
106696
  /** Each part, its switch, whether it has all it needs, and each thing it needs. */
106565
106697
  async capabilities() {
@@ -106608,14 +106740,14 @@ var Setup = class {
106608
106740
  return { ready: needs.some((one) => one.state === "on"), needs };
106609
106741
  }
106610
106742
  /**
106611
- * Set a part's switch. Turning it on, or on again, asks for everything it is missing; the switch
106612
- * stays on whether or not that could be started.
106743
+ * Set a part's switch. Turning it on, or on again, makes only the requests that show nothing; the
106744
+ * switch stays on whether or not they could be started.
106613
106745
  */
106614
106746
  async set(capability, on) {
106615
106747
  this.#switches.set(capability, on);
106616
106748
  if (on)
106617
106749
  try {
106618
- await this.#ask(capability);
106750
+ await this.#quietly(capability);
106619
106751
  } catch (error64) {
106620
106752
  throw new ApiError(
106621
106753
  409,
@@ -106624,10 +106756,13 @@ var Setup = class {
106624
106756
  }
106625
106757
  return this.capabilities();
106626
106758
  }
106627
- /** Ask for one thing a part needs, or, with none named, for everything it is missing. */
106759
+ /**
106760
+ * Ask for one thing a part needs, on the person's click; with none named, only what turning the
106761
+ * part on makes.
106762
+ */
106628
106763
  async ask(capability, need) {
106629
106764
  try {
106630
- await this.#ask(capability, need);
106765
+ await (need ? this.#ask(capability, need) : this.#quietly(capability));
106631
106766
  } catch (error64) {
106632
106767
  throw new ApiError(409, error64.message);
106633
106768
  }
@@ -106635,7 +106770,7 @@ var Setup = class {
106635
106770
  }
106636
106771
  /**
106637
106772
  * Open the pane of System Settings for one thing a part needs, whether it is missing or not: for
106638
- * the person's own choice, as nothing else opens one.
106773
+ * the person's own choice, as only this and asking, each on their click, open one.
106639
106774
  */
106640
106775
  async settings(capability, need) {
106641
106776
  try {
@@ -106655,19 +106790,39 @@ var Setup = class {
106655
106790
  throw new Error(`There's no "${need}" for ${capability} here.`);
106656
106791
  return needs;
106657
106792
  }
106658
- /** Only macOS asks: elsewhere there is nothing to ask the person for. No pane opens. */
106793
+ /**
106794
+ * Whether macOS's request for a grant draws nothing: Screen Recording's, from macOS 26, where it
106795
+ * only lists the app in its pane. Before 26 it is commonly seen to draw an alert, so it is taken
106796
+ * as one; that is untested.
106797
+ */
106798
+ #silent(need) {
106799
+ return need === "screen-recording" && Number.parseInt(this.#machine.release, 10) >= SILENT_FROM;
106800
+ }
106801
+ /**
106802
+ * What turning a part on asks for: only the requests that show nothing, so that nothing appears
106803
+ * at a switch. For an app hosting the driver, Screen Recording's while it is missing, where its
106804
+ * request draws nothing. Accessibility's alert, Cua Driver's own grant window and a browser's
106805
+ * inspect page each wait for the person's click on that need. Only macOS asks.
106806
+ */
106807
+ async #quietly(capability) {
106808
+ if (capability !== "screen" || this.#machine.platform !== "darwin") return;
106809
+ const driver = findDriver(this.#driver);
106810
+ if (!driver?.socket || !this.#silent("screen-recording")) return;
106811
+ const needs = await this.#needs(capability);
106812
+ if (needs.some((one) => one.need === "screen-recording" && one.state !== "granted"))
106813
+ await this.#request(driver, "screen-recording");
106814
+ }
106815
+ /** Ask for one thing a part needs, on the person's click. Only macOS asks. */
106659
106816
  async #ask(capability, need) {
106660
106817
  const needs = await this.#needs(capability, need);
106661
106818
  if (this.#machine.platform !== "darwin") return;
106662
106819
  if (capability === "screen") {
106663
106820
  const driver = findDriver(this.#driver);
106664
106821
  if (!driver) throw new Error("Cua Driver isn't installed on this machine.");
106665
- const asked = needs.filter((one) => one.state !== "granted" && (!need || one.need === need)).map((one) => one.need);
106666
- if (asked.length > 0)
106667
- await (driver.socket ? this.#askHost(driver, asked) : this.#askScreen(driver));
106822
+ if (needs.some((one) => one.need === need && one.state === "granted")) return;
106823
+ await (driver.socket ? this.#askHost(driver, need) : this.#askScreen(driver));
106668
106824
  }
106669
- if (capability === "browser" && (need || !needs.some((one) => one.state === "on")))
106670
- await this.#askBrowser(need);
106825
+ if (capability === "browser") await this.#askBrowser(need);
106671
106826
  }
106672
106827
  /**
106673
106828
  * Cua Driver's own grant, with its app running first, started through the system so that the
@@ -106692,38 +106847,55 @@ var Setup = class {
106692
106847
  await this.#machine.start(driver.program, ["permissions", "grant"], quiet());
106693
106848
  }
106694
106849
  /**
106695
- * The grants of the app hosting the driver, which the driver can't ask for: the app asks, opened
106696
- * through the system so that what it asks is its own, whatever started the service, with
106697
- * `grant` and each grant to ask for, in turn.
106850
+ * A grant of the app hosting the driver, which the driver can't ask for, on the person's click.
106851
+ * The app makes macOS's request each time, so macOS asks again whenever it would, such as after a
106852
+ * reset of the app's privacy entries. The grant's pane opens as well, once the app's row is
106853
+ * written there, except at the first request of one whose request may draw an alert: macOS draws
106854
+ * it until the person has answered it once, and its own button opens the pane.
106698
106855
  */
106699
- async #askHost(driver, asked) {
106856
+ async #askHost(driver, need) {
106857
+ const host = await this.#request(driver, need);
106858
+ if (!this.#silent(need)) {
106859
+ const app = await infoValue(host.app, "CFBundleIdentifier") ?? host.app;
106860
+ const first2 = !this.#made.has(app, need);
106861
+ this.#made.add(app, need);
106862
+ if (first2) return;
106863
+ }
106864
+ await this.#pane(need);
106865
+ }
106866
+ /** A grant's pane, once the request just made has had its row written there. */
106867
+ async #pane(need) {
106868
+ const pane = PANE[need];
106869
+ if (!pane) return;
106870
+ await sleep8(PANE_MS);
106871
+ try {
106872
+ await this.#machine.run("/usr/bin/open", [pane]);
106873
+ } catch (error64) {
106874
+ throw new Error(
106875
+ `macOS's request was made, but its pane didn't open: ${error64.message}`
106876
+ );
106877
+ }
106878
+ }
106879
+ /**
106880
+ * macOS's request for a grant of the app hosting the driver: the app makes it, opened through the
106881
+ * system so that it is the app's own, whatever started the service, with `grant` and the grant.
106882
+ */
106883
+ async #request(driver, need) {
106700
106884
  const host = await driverApp(driver.program);
106701
106885
  if (!host)
106702
106886
  throw new Error(
106703
106887
  "The app running Cua Driver can't be told from here: the driver isn't inside it."
106704
106888
  );
106705
- await this.#machine.run("/usr/bin/open", [
106706
- "-n",
106707
- "-g",
106708
- "-a",
106709
- host.app,
106710
- "--args",
106711
- "grant",
106712
- ...asked
106713
- ]);
106889
+ await this.#machine.run("/usr/bin/open", ["-n", "-g", "-a", host.app, "--args", "grant", need]);
106890
+ return host;
106714
106891
  }
106715
106892
  /**
106716
- * The browser asked for, or else the first this can open, Chrome before Edge, opened at its
106717
- * inspect page, where remote debugging is switched on. One the service was given only the folder
106718
- * of, the person opens themselves.
106893
+ * The browser asked for, opened at its inspect page, where remote debugging is switched on. One
106894
+ * the service was given only the folder of, the person opens themselves.
106719
106895
  */
106720
106896
  async #askBrowser(need) {
106721
- const each = browsers(this.#browserData, this.#machine);
106722
- const one = each.find((kind) => need ? kind.browser === need : kind.at);
106723
- if (!one) {
106724
- if (each.some((kind) => kind.installed)) return;
106725
- throw new Error("Neither Chrome nor Edge is installed on this machine.");
106726
- }
106897
+ const one = browsers(this.#browserData, this.#machine).find((kind) => kind.browser === need);
106898
+ if (!one) return;
106727
106899
  if (!one.installed) throw new Error(`${one.name} isn't installed on this machine.`);
106728
106900
  if (!one.at)
106729
106901
  throw new Error(
@@ -65,7 +65,7 @@ export interface paths {
65
65
  cookie?: never;
66
66
  };
67
67
  get?: never;
68
- /** Set a part's switch, which lasts across restarts. Turning it on, or on again, also asks for everything the part is missing, as asking for it with no need named does. Where that couldn't be started, it answers 409, saying why, and the switch stays on. */
68
+ /** Set a part's switch, which lasts across restarts. Turning it on, or on again, makes only the requests that show nothing, on the service's machine, macOS only: from macOS 26, Screen Recording's for an app hosting Cua Driver, while it is missing, which lists the app in its pane. Nothing that shows an alert or a window comes from the switch: Accessibility's alert, Cua Driver's own grant window and a browser's inspect page each come from ask with that need, on the person's click. Before macOS 26 Screen Recording's request is taken to draw an alert, so it waits for ask too; that is untested. Where a request it makes couldn't be started, it answers 409, saying why, and the switch stays on. */
69
69
  put: operations["setSetup"];
70
70
  post?: never;
71
71
  delete?: never;
@@ -85,7 +85,7 @@ export interface paths {
85
85
  };
86
86
  get?: never;
87
87
  put?: never;
88
- /** Ask the person, on the service's machine, macOS only, for one thing a part needs, or, with none named, for everything it is missing. screen-recording or accessibility, while it is missing: Cua Driver's own grant, its app started first, which makes the system's requests in its own order, Accessibility first. For a driver an app hosts, the app asks, for that grant alone, in its own way. The service opens no pane of System Settings: the person opens one with settings. macOS shows each request once: once it has been answered, asking again shows nothing and answers the same, so a client offers settings while a grant stays not-granted. chrome or edge: that browser opens at its inspect page, where remote debugging is switched on. With none named, the screen's grant while either is missing, and the first browser installed, Chrome before Edge, while none is on. It answers once the steps have started, with each part then; what the person does next is read afresh later. A browser the service was given only the folder of, the person opens. Elsewhere it asks for nothing. */
88
+ /** Ask the person, on the service's machine, macOS only, for one thing a part needs, for a button they press for it. screen-recording or accessibility, while it is missing: for a driver an app hosts, the app makes macOS's request each time, so that macOS asks again whenever it would, such as after a reset of the app's privacy entries. That grant's pane of System Settings opens as well, a second later, except at the first request the service has made, for that app's bundle identifier, of a grant whose request may draw an alert: accessibility, and screen-recording before macOS 26. macOS draws that alert until it has been answered, and the alert's own button opens the pane; after a reset, the alert and the pane both come. From macOS 26 Screen Recording's request draws nothing, so its pane opens each time. For Cua Driver's own app, while it is missing: its own grant, its app started first, which makes the system's requests in its own order, Accessibility first, in a window of its own. chrome or edge: that browser opens at its inspect page, where remote debugging is switched on. With none named, it makes only what turning the part on makes. It answers once the steps have started, with each part then; what the person does next is read afresh later. A browser the service was given only the folder of, the person opens. Elsewhere it asks for nothing. */
89
89
  post: operations["askSetup"];
90
90
  delete?: never;
91
91
  options?: never;
@@ -104,7 +104,7 @@ export interface paths {
104
104
  };
105
105
  get?: never;
106
106
  put?: never;
107
- /** Open the pane of System Settings for one thing a part needs, on the service's machine, macOS only, for the person to switch it there: screen-recording or accessibility, that grant's pane under Privacy & Security, whether it is missing or not. macOS lists an app there once it has asked, so this follows ask. It is for the person's own choice, such as a button they press: the service opens a pane nowhere else. Where an app hosts the driver, it is that app that sees the change and starts its driver again. It answers once the pane is asked to open, with each part then. Elsewhere it answers 409. */
107
+ /** Open the pane of System Settings for one thing a part needs, on the service's machine, macOS only, for the person to switch it there: screen-recording or accessibility, that grant's pane under Privacy & Security, whether it is missing or not. macOS lists an app there once it has asked, so this follows ask. It is for the person's own choice, such as a button they press: the service opens a pane only here and from ask, each on the person's click. Where an app hosts the driver, it is that app that sees the change and starts its driver again. It answers once the pane is asked to open, with each part then. Elsewhere it answers 409. */
108
108
  post: operations["openSetupSettings"];
109
109
  delete?: never;
110
110
  options?: never;
@@ -315,7 +315,7 @@ export interface components {
315
315
  */
316
316
  Access: "none" | "read" | "files" | "terminal";
317
317
  /**
318
- * @description starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again.
318
+ * @description starting: it is being made, started, or brought back as the service starts. Its `reason` says what it waits on, and its `progress` how far that has come, where it counts. Its endpoints and live sessions are refused with 409 and that `reason` until it is running. `create` and `start` answer once it is running, and it is listed meanwhile; `start` on one already starting answers at once. failed: it was to be running and isn't, because its browser or container ended by itself, or because it couldn't be brought back when the service started. Its `reason` says why, and its logs say more. Stop it and start it again. The screen fails none: a computer with the screen, brought back or started again while the screen can't be used, is running. Its screen's tools say why, in the switch's words or the screen's, and while the screen isn't ready its `screen` surface is `unavailable` with the same words; the next call after the screen can be used works, with no restart. Cua Driver stopping, as when an app hosting it starts it again for a grant, ends only the connection, which the next call makes again.
319
319
  * @enum {string}
320
320
  */
321
321
  ComputerState: "starting" | "running" | "stopped" | "failed";
@@ -365,7 +365,7 @@ export interface components {
365
365
  */
366
366
  browser: boolean | "own";
367
367
  /**
368
- * @description Whether its agent has the machine's screen: to see it and act on it, through Cua Driver, which the person installs and grants Screen Recording and Accessibility once. It acts as the person, whatever `access` says. Refused with 409 where `info` says the screen isn't ready.
368
+ * @description Whether its agent has the machine's screen: to see it and act on it, through Cua Driver, which the person installs and grants Screen Recording and Accessibility once. It acts as the person, whatever `access` says. Refused with 409 where `info` says the screen isn't ready. Once attached, the computer doesn't rest on it: brought back or started again while the screen can't be used, it runs, and its screen's tools say why.
369
369
  * @default false
370
370
  */
371
371
  screen: boolean;
@@ -980,7 +980,7 @@ export interface operations {
980
980
  };
981
981
  };
982
982
  responses: {
983
- /** @description Set, and its steps started. */
983
+ /** @description Set, and any request it makes started. */
984
984
  200: {
985
985
  headers: {
986
986
  [name: string]: unknown;
@@ -990,7 +990,7 @@ export interface operations {
990
990
  };
991
991
  };
992
992
  401: components["responses"]["Unauthorized"];
993
- /** @description On, but the steps that ask for what it needs couldn't be started. */
993
+ /** @description On, but a request it makes couldn't be started. */
994
994
  409: {
995
995
  headers: {
996
996
  [name: string]: unknown;
@@ -1028,7 +1028,7 @@ export interface operations {
1028
1028
  };
1029
1029
  };
1030
1030
  401: components["responses"]["Unauthorized"];
1031
- /** @description The part doesn't need that here, or what it needs can't be asked for, such as a browser that isn't installed, or the steps couldn't be started. */
1031
+ /** @description The part doesn't need that here, or what it needs can't be asked for, such as a browser that isn't installed, or the steps couldn't be started, or, once macOS's request was made, the grant's pane couldn't be opened. */
1032
1032
  409: {
1033
1033
  headers: {
1034
1034
  [name: string]: unknown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentorg/computer",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "description": "Computers for agents, as a service: a terminal, files and a browser over MCP",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {