@intentic/machine 1.245.0 → 1.246.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/README.md +27 -18
  2. package/dist/app.js +1 -1
  3. package/dist/app.js.map +1 -1
  4. package/dist/autostart.js +1 -1
  5. package/dist/autostart.js.map +1 -1
  6. package/dist/commands.d.ts +1 -1
  7. package/dist/commands.js +5 -5
  8. package/dist/commands.js.map +1 -1
  9. package/dist/config.d.ts +1 -0
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +1 -0
  12. package/dist/config.js.map +1 -1
  13. package/dist/device/audit.d.ts.map +1 -0
  14. package/dist/device/audit.js.map +1 -0
  15. package/dist/{computer → device}/auto-prepare.d.ts +3 -3
  16. package/dist/device/auto-prepare.d.ts.map +1 -0
  17. package/dist/device/auto-prepare.js.map +1 -0
  18. package/dist/{computer → device}/commands.d.ts +2 -2
  19. package/dist/device/commands.d.ts.map +1 -0
  20. package/dist/{computer → device}/commands.js +19 -19
  21. package/dist/device/commands.js.map +1 -0
  22. package/dist/device/config.d.ts.map +1 -0
  23. package/dist/{computer → device}/config.js +1 -1
  24. package/dist/device/config.js.map +1 -0
  25. package/dist/{computer → device}/connection.d.ts +2 -5
  26. package/dist/device/connection.d.ts.map +1 -0
  27. package/dist/device/connection.js +37 -0
  28. package/dist/device/connection.js.map +1 -0
  29. package/dist/device/mcp.d.ts +11 -0
  30. package/dist/device/mcp.d.ts.map +1 -0
  31. package/dist/{computer → device}/mcp.js +36 -84
  32. package/dist/device/mcp.js.map +1 -0
  33. package/dist/device/policy.d.ts.map +1 -0
  34. package/dist/{computer → device}/policy.js +5 -5
  35. package/dist/device/policy.js.map +1 -0
  36. package/dist/{computer → device}/router.d.ts +35 -0
  37. package/dist/device/router.d.ts.map +1 -0
  38. package/dist/{computer → device}/router.js +7 -3
  39. package/dist/device/router.js.map +1 -0
  40. package/dist/device/testing.d.ts +10 -0
  41. package/dist/device/testing.d.ts.map +1 -0
  42. package/dist/device/testing.js +51 -0
  43. package/dist/device/testing.js.map +1 -0
  44. package/dist/device/tools/agent.d.ts +4 -0
  45. package/dist/device/tools/agent.d.ts.map +1 -0
  46. package/dist/device/tools/agent.js +46 -0
  47. package/dist/device/tools/agent.js.map +1 -0
  48. package/dist/device/tools/apps.d.ts.map +1 -0
  49. package/dist/{computer → device}/tools/apps.js +3 -3
  50. package/dist/device/tools/apps.js.map +1 -0
  51. package/dist/device/tools/browser.d.ts.map +1 -0
  52. package/dist/device/tools/browser.js.map +1 -0
  53. package/dist/device/tools/describe.d.ts.map +1 -0
  54. package/dist/{computer → device}/tools/describe.js +22 -8
  55. package/dist/device/tools/describe.js.map +1 -0
  56. package/dist/{computer/tools/computer.d.ts → device/tools/device.d.ts} +6 -6
  57. package/dist/device/tools/device.d.ts.map +1 -0
  58. package/dist/{computer/tools/computer.js → device/tools/device.js} +2 -2
  59. package/dist/device/tools/device.js.map +1 -0
  60. package/dist/device/tools/files.d.ts.map +1 -0
  61. package/dist/device/tools/files.js.map +1 -0
  62. package/dist/{computer → device}/tools/sandboxes.d.ts +7 -3
  63. package/dist/device/tools/sandboxes.d.ts.map +1 -0
  64. package/dist/{computer → device}/tools/sandboxes.js +98 -8
  65. package/dist/device/tools/sandboxes.js.map +1 -0
  66. package/dist/device/tools/shell.d.ts.map +1 -0
  67. package/dist/{computer → device}/tools/shell.js +6 -4
  68. package/dist/device/tools/shell.js.map +1 -0
  69. package/dist/resident.js +6 -6
  70. package/dist/resident.js.map +1 -1
  71. package/dist/status.d.ts +9 -9
  72. package/dist/status.d.ts.map +1 -1
  73. package/dist/status.js +19 -19
  74. package/dist/status.js.map +1 -1
  75. package/dist/sync/commands.js +4 -4
  76. package/dist/sync/commands.js.map +1 -1
  77. package/dist/sync/mirror.js +4 -4
  78. package/dist/sync/mirror.js.map +1 -1
  79. package/dist/sync/report.d.ts +4 -4
  80. package/dist/sync/report.d.ts.map +1 -1
  81. package/dist/sync/report.js +5 -6
  82. package/dist/sync/report.js.map +1 -1
  83. package/package.json +10 -10
  84. package/dist/computer/audit.d.ts.map +0 -1
  85. package/dist/computer/audit.js.map +0 -1
  86. package/dist/computer/auto-prepare.d.ts.map +0 -1
  87. package/dist/computer/auto-prepare.js.map +0 -1
  88. package/dist/computer/commands.d.ts.map +0 -1
  89. package/dist/computer/commands.js.map +0 -1
  90. package/dist/computer/config.d.ts.map +0 -1
  91. package/dist/computer/config.js.map +0 -1
  92. package/dist/computer/connection.d.ts.map +0 -1
  93. package/dist/computer/connection.js +0 -72
  94. package/dist/computer/connection.js.map +0 -1
  95. package/dist/computer/mcp.d.ts +0 -3
  96. package/dist/computer/mcp.d.ts.map +0 -1
  97. package/dist/computer/mcp.js.map +0 -1
  98. package/dist/computer/policy.d.ts.map +0 -1
  99. package/dist/computer/policy.js.map +0 -1
  100. package/dist/computer/router.d.ts.map +0 -1
  101. package/dist/computer/router.js.map +0 -1
  102. package/dist/computer/tools/apps.d.ts.map +0 -1
  103. package/dist/computer/tools/apps.js.map +0 -1
  104. package/dist/computer/tools/browser.d.ts.map +0 -1
  105. package/dist/computer/tools/browser.js.map +0 -1
  106. package/dist/computer/tools/computer.d.ts.map +0 -1
  107. package/dist/computer/tools/computer.js.map +0 -1
  108. package/dist/computer/tools/describe.d.ts.map +0 -1
  109. package/dist/computer/tools/describe.js.map +0 -1
  110. package/dist/computer/tools/files.d.ts.map +0 -1
  111. package/dist/computer/tools/files.js.map +0 -1
  112. package/dist/computer/tools/sandboxes.d.ts.map +0 -1
  113. package/dist/computer/tools/sandboxes.js.map +0 -1
  114. package/dist/computer/tools/shell.d.ts.map +0 -1
  115. package/dist/computer/tools/shell.js.map +0 -1
  116. /package/dist/{computer → device}/audit.d.ts +0 -0
  117. /package/dist/{computer → device}/audit.js +0 -0
  118. /package/dist/{computer → device}/auto-prepare.js +0 -0
  119. /package/dist/{computer → device}/config.d.ts +0 -0
  120. /package/dist/{computer → device}/policy.d.ts +0 -0
  121. /package/dist/{computer → device}/tools/apps.d.ts +0 -0
  122. /package/dist/{computer → device}/tools/browser.d.ts +0 -0
  123. /package/dist/{computer → device}/tools/browser.js +0 -0
  124. /package/dist/{computer → device}/tools/describe.d.ts +0 -0
  125. /package/dist/{computer → device}/tools/files.d.ts +0 -0
  126. /package/dist/{computer → device}/tools/files.js +0 -0
  127. /package/dist/{computer → device}/tools/shell.d.ts +0 -0
@@ -1,7 +1,8 @@
1
1
  import { errorMessage } from "@intentic/base/errors";
2
2
  import { browser } from "@intentic/browser";
3
3
  import { desktop, pngSize } from "@intentic/desktop";
4
- import { MCP_PROTOCOL_VERSION } from "@intentic/sandbox-contract";
4
+ import { SandboxResourcesAskFieldsSchema } from "@intentic/sandbox-contract";
5
+ import { createMcpServer, textResult, tool } from "@intentic/sandbox-contract/peer-mcp-server";
5
6
  import { z } from "zod";
6
7
  import { audit } from "./audit.js";
7
8
  import { assertScope, ScopeError } from "./policy.js";
@@ -9,23 +10,10 @@ import { describeText } from "./tools/describe.js";
9
10
  import { listDirectory, readTextFile, trashFile, writeTextFile } from "./tools/files.js";
10
11
  import { focusWindow, listWindows, openTarget, readClipboard, writeClipboard } from "./tools/apps.js";
11
12
  import { clickElement, fillElement, listTabs, openPage, pressKey, readPage, selectTab, snapshotPage } from "./tools/browser.js";
12
- import { act, describeAction, settle } from "./tools/computer.js";
13
- import { DEFAULT_LOG_LINES, listSandboxes, manageSandbox, MAX_LOG_LINES, removeSandbox, SandboxOpSchema, SandboxSwapSchema, sandboxLogs, swapSandbox, } from "./tools/sandboxes.js";
13
+ import { act, describeAction, settle } from "./tools/device.js";
14
+ import { DEFAULT_LOG_LINES, listSandboxes, manageSandbox, MAX_LOG_LINES, removeSandbox, reshapeSandbox, SandboxOpSchema, SandboxSwapSchema, sandboxLogs, swapSandbox, } from "./tools/sandboxes.js";
14
15
  import { DEFAULT_TIMEOUT_MS, describeResult, MAX_TIMEOUT_MS, runCommand } from "./tools/shell.js";
15
16
  import { MACHINE_VERSION } from "../version.js";
16
- const textResult = (text, isError = false) => ({ content: [{ type: "text", text }], isError });
17
- const tool = (spec) => {
18
- const { $schema: _dialect, ...inputSchema } = z.toJSONSchema(spec.input, { io: "input" });
19
- return {
20
- name: spec.name,
21
- description: spec.description,
22
- inputSchema,
23
- call: async (args, scopes) => {
24
- const parsed = spec.input.safeParse(args);
25
- return parsed.success ? await spec.run(parsed.data, scopes) : textResult(z.prettifyError(parsed.error), true);
26
- },
27
- };
28
- };
29
17
  const NO_ARGS = z.object({});
30
18
  const screenshotResult = async (scopes) => {
31
19
  assertScope(scopes, "screen");
@@ -34,7 +22,7 @@ const screenshotResult = async (scopes) => {
34
22
  const { width, height } = pngSize(png);
35
23
  return {
36
24
  content: [
37
- { type: "text", text: `Screen is ${width}×${height}. Coordinates for the computer tool are pixels in this image.` },
25
+ { type: "text", text: `Screen is ${width}×${height}. Coordinates for the device tool are pixels in this image.` },
38
26
  { type: "image", data: png.toString("base64"), mimeType: "image/png" },
39
27
  ],
40
28
  isError: false,
@@ -47,13 +35,13 @@ const required = z.string().min(1);
47
35
  const TOOLS = [
48
36
  tool({
49
37
  name: "describe",
50
- description: "What this computer is: OS and version, CPU architecture, the exact shell run_command uses, the home directory, the folders you may touch, and which permissions are on. Call this once before your first command here, it is the difference between writing for this machine and guessing.",
38
+ description: "What this device is: OS and version, CPU architecture, the exact shell run_command uses, the home directory, the folders you may touch, and which permissions are on. Call this once before your first command here, it is the difference between writing for this machine and guessing.",
51
39
  input: NO_ARGS,
52
40
  run: async (_args, scopes) => textResult(await describeText(scopes)),
53
41
  }),
54
42
  tool({
55
43
  name: "run_command",
56
- description: "Run a command on this computer and get back its exit code, stdout and stderr. The shell is PowerShell on Windows and the user's login shell elsewhere (see describe). There is no terminal for anyone to type into: a command that prompts will fail rather than wait. Commands that DELETE (a recursive delete, a formatted disk, a removed Docker volume) need this computer's \"Run destructive commands\" switch, which is off unless its owner turned it on: they are refused with a message naming the switch, so ask the owner to turn it on rather than looking for a spelling that gets past it. Prefer one script that does the whole job over many small calls, every call is a network round trip to somebody's laptop.",
44
+ description: "Run a command on this device and get back its exit code, stdout and stderr. The shell is PowerShell on Windows and the user's login shell elsewhere (see describe). There is no terminal for anyone to type into: a command that prompts will fail rather than wait. Commands that DELETE (a recursive delete, a formatted disk, a removed Docker volume) need this device's \"Run destructive commands\" switch, which is off unless its owner turned it on: they are refused with a message naming the switch, so ask the owner to turn it on rather than looking for a spelling that gets past it. Prefer one script that does the whole job over many small calls, every call is a network round trip to somebody's laptop.",
57
45
  input: z.object({
58
46
  command: required.describe("The command line to run, in this machine's shell."),
59
47
  cwd: required.optional().describe("Working directory. Must be inside the allowed folders. Defaults to the first allowed folder."),
@@ -71,7 +59,7 @@ const TOOLS = [
71
59
  }),
72
60
  tool({
73
61
  name: "read_file",
74
- description: "Read a text file on this computer. Bounded by the folders this machine allows.",
62
+ description: "Read a text file on this device. Bounded by the folders this machine allows.",
75
63
  input: z.object({ path: required }),
76
64
  run: async ({ path }, scopes) => textResult(await readTextFile(path, scopes)),
77
65
  }),
@@ -95,7 +83,7 @@ const TOOLS = [
95
83
  }),
96
84
  tool({
97
85
  name: "list_windows",
98
- description: "Every window open on this computer: its app, title, size, position, and which one has focus. Call this before any GUI work, it is how you find the application you were asked about, and how you know where your typing will land. Requires the 'See the screen' permission.",
86
+ description: "Every window open on this device: its app, title, size, position, and which one has focus. Call this before any GUI work, it is how you find the application you were asked about, and how you know where your typing will land. Requires the 'See the screen' permission.",
99
87
  input: NO_ARGS,
100
88
  run: async (_args, scopes) => textResult(await listWindows(desktop(), scopes)),
101
89
  }),
@@ -107,13 +95,13 @@ const TOOLS = [
107
95
  }),
108
96
  tool({
109
97
  name: "open",
110
- description: "Start an application, or open a URL or file with whatever this computer has registered for it: the usual first step of a task ('open the browser at this page'). Use this rather than working out the platform's own incantation. Requires the 'Run commands' permission.",
98
+ description: "Start an application, or open a URL or file with whatever this device has registered for it: the usual first step of a task ('open the browser at this page'). Use this rather than working out the platform's own incantation. Requires the 'Run commands' permission.",
111
99
  input: z.object({ target: required.describe("An application name, a file path, or a URL.") }),
112
100
  run: async ({ target }, scopes) => textResult(await openTarget(desktop(), target, scopes)),
113
101
  }),
114
102
  tool({
115
103
  name: "clipboard",
116
- description: "Read or replace this computer's clipboard: the reliable way to move text between applications, and often easier than reading it off a screenshot. Reading needs 'See the screen'; writing needs 'Use the mouse and keyboard'.",
104
+ description: "Read or replace this device's clipboard: the reliable way to move text between applications, and often easier than reading it off a screenshot. Reading needs 'See the screen'; writing needs 'Use the mouse and keyboard'.",
117
105
  input: z
118
106
  .object({
119
107
  action: z.enum(["read", "write"]),
@@ -129,7 +117,7 @@ const TOOLS = [
129
117
  }),
130
118
  tool({
131
119
  name: "browser_open",
132
- description: "Open a page in a browser on this computer and answer with what is on it: the page's title, its URL, and every element you can click or type into, each with a reference like [e12]. THIS IS THE RIGHT WAY TO USE A WEBSITE, act on elements by reference, never by clicking pixels, because references survive scrolling, resizing and re-rendering. The browser is a separate instance with its own profile, so the user's own tabs and session are untouched; the first time it opens they may need to sign in. Requires the 'Run commands' permission.",
120
+ description: "Open a page in a browser on this device and answer with what is on it: the page's title, its URL, and every element you can click or type into, each with a reference like [e12]. THIS IS THE RIGHT WAY TO USE A WEBSITE, act on elements by reference, never by clicking pixels, because references survive scrolling, resizing and re-rendering. The browser is a separate instance with its own profile, so the user's own tabs and session are untouched; the first time it opens they may need to sign in. Requires the 'Run commands' permission.",
133
121
  input: z.object({ url: required.describe("The page to open. A bare host like example.com is fine.") }),
134
122
  run: async ({ url }, scopes) => textResult(await openPage(web(), url, scopes)),
135
123
  }),
@@ -174,8 +162,8 @@ const TOOLS = [
174
162
  run: async ({ select }, scopes) => textResult(select === undefined ? await listTabs(web(), scopes) : await selectTab(web(), select, scopes)),
175
163
  }),
176
164
  tool({
177
- name: "computer",
178
- description: "Use this computer's mouse and keyboard: click what is on the screen, type into the focused window, press a key combination, scroll, drag. Coordinates are PIXELS IN THE LAST SCREENSHOT, take one first and read them off it. Every action answers with a fresh screenshot so you can see what happened. Requires the 'Use the mouse and keyboard' permission, which is OFF unless the user turned it on. Prefer a command over the GUI when both would work: a command is exact, and a click is a guess about where something is.",
165
+ name: "device",
166
+ description: "Use this device's mouse and keyboard: click what is on the screen, type into the focused window, press a key combination, scroll, drag. Coordinates are PIXELS IN THE LAST SCREENSHOT, take one first and read them off it. Every action answers with a fresh screenshot so you can see what happened. Requires the 'Use the mouse and keyboard' permission, which is OFF unless the user turned it on. Prefer a command over the GUI when both would work: a command is exact, and a click is a guess about where something is.",
179
167
  input: z.object({
180
168
  action: z.enum([
181
169
  "mouse_move",
@@ -199,7 +187,7 @@ const TOOLS = [
199
187
  run: async (input, scopes) => {
200
188
  await act(desktop(), input, scopes);
201
189
  if (scopes.screen !== "on") {
202
- return textResult(`${describeAction(input)} (No screenshot: "See the screen" is off for this computer.)`);
190
+ return textResult(`${describeAction(input)} (No screenshot: "See the screen" is off for this device.)`);
203
191
  }
204
192
  await settle();
205
193
  const shot = await screenshotResult(scopes);
@@ -208,25 +196,25 @@ const TOOLS = [
208
196
  }),
209
197
  tool({
210
198
  name: "screenshot",
211
- description: "Capture what is on this computer's screen right now, as an image. Use it to read a dialog, check on a window, or see what the user is describing. Requires the 'See the screen' permission.",
199
+ description: "Capture what is on this device's screen right now, as an image. Use it to read a dialog, check on a window, or see what the user is describing. Requires the 'See the screen' permission.",
212
200
  input: NO_ARGS,
213
201
  run: async (_args, scopes) => await screenshotResult(scopes),
214
202
  }),
215
203
  tool({
216
204
  name: "list_sandboxes",
217
- description: "The Intentic sandboxes on this computer, as JSON: each one's slug, whether it is running, and whether its tunnel is up. Only sandbox containers; nothing else on the machine is listed. Requires 'Run commands' or 'Manage sandboxes on this computer'.",
205
+ description: "The Intentic sandboxes on this device, as JSON: each one's slug, whether it is running, whether its tunnel is up, and its share of this machine under `resources` (memory cap in bytes, CPU cap, privileged, GPU, and which of those the approved environment demands versus the owner asked for). Only sandbox containers; nothing else on the machine is listed. Requires 'Run commands' or 'Manage sandboxes on this device'.",
218
206
  input: NO_ARGS,
219
207
  run: async (_args, scopes) => textResult(await listSandboxes(scopes)),
220
208
  }),
221
209
  tool({
222
210
  name: "manage_sandbox",
223
- description: "Start, stop or restart one Intentic sandbox on this computer, by its slug from list_sandboxes. Stopping one interrupts whoever is working in it, and stopping the sandbox you are calling from severs your own connection. Requires the 'Manage sandboxes on this computer' permission, which is OFF unless the user turned it on.",
211
+ description: "Start, stop or restart one Intentic sandbox on this device, by its slug from list_sandboxes. Stopping one interrupts whoever is working in it, and stopping the sandbox you are calling from severs your own connection. Requires the 'Manage sandboxes on this device' permission, which is OFF unless the user turned it on.",
224
212
  input: z.object({ op: SandboxOpSchema, slug: required.describe("The sandbox's slug, from list_sandboxes.") }),
225
213
  run: async ({ op, slug }, scopes) => textResult(await manageSandbox(op, slug, scopes)),
226
214
  }),
227
215
  tool({
228
216
  name: "swap_sandbox",
229
- description: "Move one Intentic sandbox on this computer onto a different image: 'update' pulls the newest image of its release channel, 'rollback' returns it to the image it ran before its last update, and 'rebuild' rebuilds the owner-approved environment overlay. Files (/work) and history are kept in all three. Takes MINUTES, it pulls an image and recreates the container, and the sandbox is down while it happens. 'prepare' is the exception and the one to reach for first: it does the downloading and building of the next update WITHOUT touching the container, so the sandbox keeps running throughout and the 'update' that follows is a restart of seconds instead of a wait of minutes. Requires the 'Manage sandboxes on this computer' permission.",
217
+ description: "Move one Intentic sandbox on this device onto a different image: 'update' pulls the newest image of its release channel, 'rollback' returns it to the image it ran before its last update, and 'rebuild' rebuilds the owner-approved environment overlay. Files (/work) and history are kept in all three. Takes MINUTES, it pulls an image and recreates the container, and the sandbox is down while it happens. 'prepare' is the exception and the one to reach for first: it does the downloading and building of the next update WITHOUT touching the container, so the sandbox keeps running throughout and the 'update' that follows is a restart of seconds instead of a wait of minutes. Requires the 'Manage sandboxes on this device' permission.",
230
218
  input: z.object({
231
219
  op: SandboxSwapSchema,
232
220
  slug: required.describe("The sandbox's slug, from list_sandboxes."),
@@ -234,15 +222,21 @@ const TOOLS = [
234
222
  }),
235
223
  run: async ({ op, slug, hash }, scopes) => textResult(await swapSandbox(op, slug, hash, scopes, () => { })),
236
224
  }),
225
+ tool({
226
+ name: "reshape_sandbox",
227
+ description: "Change how much of this device one Intentic sandbox may use, or its privileges: a memory cap in whole GiB, a CPU cap in whole cores, whether the container runs privileged, and whether this device's NVIDIA GPUs are passed through. Give only what should change; `null` for a cap means back to the default (the memory share derived from this machine; every core). The sandbox RESTARTS onto the same image — about a minute, whoever is working in it is interrupted, and reshaping the sandbox you are calling from severs your own connection until it is back — and the new values live on the container, surviving every later update. A privilege the sandbox's approved environment demands (the Docker capability's --privileged) cannot be withdrawn here, only the owner's own ask. Requires the 'Manage sandboxes on this device' permission.",
228
+ input: SandboxResourcesAskFieldsSchema.extend({ slug: required.describe("The sandbox's slug, from list_sandboxes.") }),
229
+ run: async ({ slug, ...ask }, scopes) => textResult(await reshapeSandbox(slug, ask, scopes, () => { })),
230
+ }),
237
231
  tool({
238
232
  name: "remove_sandbox",
239
- description: "Delete one Intentic sandbox from this computer: its container, its network, and the volumes holding its files and its history. THIS CANNOT BE UNDONE and is not what stopping it does, confirm with the user before calling it. Requires the 'Remove sandboxes from this computer' permission, which is separate from managing them and OFF unless the user turned it on.",
233
+ description: "Delete one Intentic sandbox from this device: its container, its network, and the volumes holding its files and its history. THIS CANNOT BE UNDONE and is not what stopping it does, confirm with the user before calling it. Requires the 'Remove sandboxes from this device' permission, which is separate from managing them and OFF unless the user turned it on.",
240
234
  input: z.object({ slug: required.describe("The sandbox's slug, from list_sandboxes.") }),
241
235
  run: async ({ slug }, scopes) => textResult(await removeSandbox(slug, scopes, () => { })),
242
236
  }),
243
237
  tool({
244
238
  name: "sandbox_logs",
245
- description: "The tail of one Intentic sandbox's container log on this computer: how you find out why it will not start or what it did before it stopped. Requires 'Run commands' or 'Manage sandboxes on this computer'.",
239
+ description: "The tail of one Intentic sandbox's container log on this device: how you find out why it will not start or what it did before it stopped. Requires 'Run commands' or 'Manage sandboxes on this device'.",
246
240
  input: z.object({
247
241
  slug: required.describe("The sandbox's slug, from list_sandboxes."),
248
242
  lines: z
@@ -255,59 +249,17 @@ const TOOLS = [
255
249
  run: async ({ slug, lines }, scopes) => textResult(await sandboxLogs(slug, lines, scopes)),
256
250
  }),
257
251
  ];
258
- const BY_NAME = new Map(TOOLS.map((entry) => [entry.name, entry]));
259
252
  const auditDetail = (name, args) => {
260
- const redact = (name === "computer" && args["action"] === "type") || (name === "clipboard" && args["action"] === "write") || name === "browser_fill";
253
+ const redact = (name === "device" && args["action"] === "type") || (name === "clipboard" && args["action"] === "write") || name === "browser_fill";
261
254
  const safe = redact ? { ...args, text: `<${String(args["text"] ?? "").length} characters>` } : args;
262
255
  return JSON.stringify(safe).slice(0, 500);
263
256
  };
264
- const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
265
- export const handleMcpMessage = async (message, scopes) => {
266
- if (!isRecord(message)) {
267
- return { jsonrpc: "2.0", id: null, error: { code: -32600, message: "invalid request" } };
268
- }
269
- const id = message["id"];
270
- const method = message["method"];
271
- if (id === undefined) {
272
- return undefined;
273
- }
274
- const reply = (result) => ({ jsonrpc: "2.0", id, result });
275
- if (method === "initialize") {
276
- return reply({
277
- protocolVersion: MCP_PROTOCOL_VERSION,
278
- capabilities: { tools: {} },
279
- serverInfo: { name: "intentic-machine", version: MACHINE_VERSION },
280
- });
281
- }
282
- if (method === "ping") {
283
- return reply({});
284
- }
285
- if (method === "tools/list") {
286
- return reply({ tools: TOOLS.map(({ name, description, inputSchema }) => ({ name, description, inputSchema })) });
287
- }
288
- if (method === "tools/call") {
289
- const params = isRecord(message["params"]) ? message["params"] : {};
290
- const name = typeof params["name"] === "string" ? params["name"] : "";
291
- const args = isRecord(params["arguments"]) ? params["arguments"] : {};
292
- const found = BY_NAME.get(name);
293
- if (found === undefined) {
294
- return reply(textResult(`This computer has no tool called "${name}".`, true));
295
- }
296
- try {
297
- const result = await found.call(args, scopes());
298
- void audit({ tool: name, ok: result["isError"] !== true, detail: auditDetail(name, args) });
299
- return reply(result);
300
- }
301
- catch (error) {
302
- const refused = error instanceof ScopeError;
303
- void audit({
304
- tool: name,
305
- ok: false,
306
- detail: `${refused ? "refused" : "failed"}: ${errorMessage(error)}`,
307
- });
308
- return reply(textResult(errorMessage(error), true));
309
- }
310
- }
311
- return { jsonrpc: "2.0", id, error: { code: -32601, message: `method "${String(method)}" is not supported` } };
312
- };
257
+ export const handleMcpMessage = createMcpServer({
258
+ serverInfo: () => ({ name: "intentic-machine", version: MACHINE_VERSION }),
259
+ tools: TOOLS,
260
+ noSuchTool: (name) => `This device has no tool called "${name}".`,
261
+ refused: (error) => error instanceof ScopeError,
262
+ errorMessage,
263
+ audit: ({ tool: name, args, ok, failure }) => audit({ tool: name, ok, detail: failure === undefined ? auditDetail(name, args) : `${failure.refused ? "refused" : "failed"}: ${failure.message}` }),
264
+ });
313
265
  //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/device/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/device/policy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAa7D,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAIxC,eAAO,MAAM,OAAO,WAAY,UAAU,KAAG,MAAM,EAUlD,CAAC;AAOF,eAAO,MAAM,WAAW,SAAU,MAAM,SAAS,SAAS,MAAM,EAAE,KAAG,OAGpE,CAAC;AAIF,eAAO,MAAM,UAAU,SAAU,MAAM,UAAU,UAAU,UAAU,MAAM,KAAG,MAS7E,CAAC;AAIF,eAAO,MAAM,WAAW,WACZ,UAAU,SACX,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,eAAe,GAAG,aAAa,KAChG,IAcF,CAAC"}
@@ -19,8 +19,8 @@ export const withinRoots = (path, roots) => {
19
19
  export const assertPath = (path, scopes, intent) => {
20
20
  const roots = rootsOf(scopes);
21
21
  if (!withinRoots(path, roots)) {
22
- throw new ScopeError(`Refused to ${intent} "${path}": it is outside the folders this computer allows (${roots.join(", ")}). ` +
23
- `Widen "Folders it may touch" on this computer's capability card to change that.`);
22
+ throw new ScopeError(`Refused to ${intent} "${path}": it is outside the folders this device allows (${roots.join(", ")}). ` +
23
+ `Widen "Folders it may touch" on this device's capability card to change that.`);
24
24
  }
25
25
  return resolve(path);
26
26
  };
@@ -33,10 +33,10 @@ export const assertScope = (scopes, scope) => {
33
33
  write: "Create and change files",
34
34
  screen: "See the screen",
35
35
  control: "Use the mouse and keyboard",
36
- sandboxes: "Manage sandboxes on this computer",
37
- sandboxRemove: "Remove sandboxes from this computer",
36
+ sandboxes: "Manage sandboxes on this device",
37
+ sandboxRemove: "Remove sandboxes from this device",
38
38
  destructive: "Run destructive commands",
39
39
  }[scope];
40
- throw new ScopeError(`Refused: "${label}" is switched off for this computer. Turn it on in its capability card to allow this.`);
40
+ throw new ScopeError(`Refused: "${label}" is switched off for this device. Turn it on in its capability card to allow this.`);
41
41
  };
42
42
  //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/device/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAc3D,MAAM,OAAO,UAAW,SAAQ,KAAK;CAAG;AAIxC,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAkB,EAAY,EAAE;IACpD,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;SAChC,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;SAE7B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAC7E,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAClC,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC,CAAC;AAOF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,KAAwB,EAAW,EAAE;IAC3E,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;AACnH,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,MAAkB,EAAE,MAAc,EAAU,EAAE;IACnF,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAChB,cAAc,MAAM,KAAK,IAAI,oDAAoD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YAClG,+EAA+E,CACtF,CAAC;IACN,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,WAAW,GAAG,CACvB,MAAkB,EAClB,KAA+F,EAC3F,EAAE;IACN,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO;IACX,CAAC;IACD,MAAM,KAAK,GAAG;QACV,KAAK,EAAE,cAAc;QACrB,KAAK,EAAE,yBAAyB;QAChC,MAAM,EAAE,gBAAgB;QACxB,OAAO,EAAE,4BAA4B;QACrC,SAAS,EAAE,iCAAiC;QAC5C,aAAa,EAAE,mCAAmC;QAClD,WAAW,EAAE,0BAA0B;KAC1C,CAAC,KAAK,CAAC,CAAC;IACT,MAAM,IAAI,UAAU,CAAC,aAAa,KAAK,qFAAqF,CAAC,CAAC;AAClI,CAAC,CAAC"}
@@ -11,6 +11,10 @@ export declare const createHostRouter: (runtime: HostRuntime) => {
11
11
  shell: import("zod").ZodString;
12
12
  home: import("zod").ZodString;
13
13
  roots: import("zod").ZodArray<import("zod").ZodString>;
14
+ engine: import("zod").ZodOptional<import("zod").ZodObject<{
15
+ memoryBytes: import("zod").ZodNumber;
16
+ cpus: import("zod").ZodNumber;
17
+ }, import("zod/v4/core").$strip>>;
14
18
  }, import("zod/v4/core").$strip>, import("@orpc/server").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
15
19
  setScopes: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<Record<never, never>, Record<never, never>, Record<never, never>>, Record<never, never>, import("zod").ZodObject<{
16
20
  shell: import("zod").ZodDefault<import("zod").ZodEnum<{
@@ -55,6 +59,7 @@ export declare const createHostRouter: (runtime: HostRuntime) => {
55
59
  prepare: "prepare";
56
60
  rebuild: "rebuild";
57
61
  remove: "remove";
62
+ reshape: "reshape";
58
63
  restart: "restart";
59
64
  rollback: "rollback";
60
65
  "runner-remove": "runner-remove";
@@ -65,6 +70,12 @@ export declare const createHostRouter: (runtime: HostRuntime) => {
65
70
  }>;
66
71
  slug: import("zod").ZodString;
67
72
  hash: import("zod").ZodOptional<import("zod").ZodString>;
73
+ resources: import("zod").ZodOptional<import("zod").ZodObject<{
74
+ memoryGib: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodInt>>;
75
+ cpus: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodInt>>;
76
+ privileged: import("zod").ZodOptional<import("zod").ZodBoolean>;
77
+ gpu: import("zod").ZodOptional<import("zod").ZodBoolean>;
78
+ }, import("zod/v4/core").$strip>>;
68
79
  parentUrl: import("zod").ZodOptional<import("zod").ZodString>;
69
80
  pair: import("zod").ZodOptional<import("zod").ZodString>;
70
81
  definition: import("zod").ZodOptional<import("zod").ZodString>;
@@ -89,5 +100,29 @@ export declare const createHostRouter: (runtime: HostRuntime) => {
89
100
  kind: "error";
90
101
  message: string;
91
102
  }, unknown, void>>, import("@orpc/server").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
103
+ runAgentFlow: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<Record<never, never>, Record<never, never>, Record<never, never>>, Record<never, never>, import("zod").ZodObject<{
104
+ op: import("zod").ZodEnum<{
105
+ restart: "restart";
106
+ upgrade: "upgrade";
107
+ }>;
108
+ }, import("zod/v4/core").$strip>, import("@orpc/server").Schema<AsyncIteratorObject<{
109
+ kind: "line";
110
+ text: string;
111
+ } | {
112
+ kind: "result";
113
+ message: string;
114
+ } | {
115
+ kind: "error";
116
+ message: string;
117
+ }, unknown, void>, import("@orpc/server").AsyncIteratorClass<{
118
+ kind: "line";
119
+ text: string;
120
+ } | {
121
+ kind: "result";
122
+ message: string;
123
+ } | {
124
+ kind: "error";
125
+ message: string;
126
+ }, unknown, void>>, import("@orpc/server").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
92
127
  };
93
128
  //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/device/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAA6D,MAAM,4BAA4B,CAAC;AAgBxH,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,UAAU,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAiGD,eAAO,MAAM,gBAAgB,YAAa,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwBpD,CAAC"}
@@ -3,7 +3,8 @@ import { hostContract } from "@intentic/sandbox-contract";
3
3
  import { implement } from "@orpc/server";
4
4
  import { handleMcpMessage } from "./mcp.js";
5
5
  import { hostFacts } from "./tools/describe.js";
6
- import { manageSandbox, removeSandbox, runnerFlow, swapSandbox, tailSandboxLogs } from "./tools/sandboxes.js";
6
+ import { runAgentOp } from "./tools/agent.js";
7
+ import { manageSandbox, removeSandbox, reshapeSandbox, runnerFlow, swapSandbox, tailSandboxLogs } from "./tools/sandboxes.js";
7
8
  async function* streamFlow(run) {
8
9
  const queued = [];
9
10
  let wake;
@@ -41,10 +42,12 @@ async function* streamFlow(run) {
41
42
  ? { kind: "result", message: settled.message }
42
43
  : { kind: "error", message: settled?.message ?? "The operation stopped without saying why." };
43
44
  }
44
- const flowFor = ({ op, slug, hash, parentUrl, pair, definition, overlay, overlayHash }, scopes) => {
45
+ const flowFor = ({ op, slug, hash, resources, parentUrl, pair, definition, overlay, overlayHash }, scopes) => {
45
46
  switch (op) {
46
47
  case "remove":
47
48
  return (onLine) => removeSandbox(slug, scopes, onLine);
49
+ case "reshape":
50
+ return (onLine) => reshapeSandbox(slug, resources, scopes, onLine);
48
51
  case "runner-up":
49
52
  case "runner-remove":
50
53
  return (onLine) => runnerFlow(op, slug, parentUrl, pair, {
@@ -73,8 +76,9 @@ export const createHostRouter = (runtime) => {
73
76
  return { ok: true };
74
77
  }),
75
78
  ping: os.ping.handler(() => ({ ok: true })),
76
- mcp: os.mcp.handler(async ({ input }) => await handleMcpMessage(input, runtime.scopes)),
79
+ mcp: os.mcp.handler(async ({ input }) => await handleMcpMessage(input, runtime.scopes())),
77
80
  runSandboxFlow: os.runSandboxFlow.handler(({ input }) => streamFlow(flowFor(input, runtime.scopes()))),
81
+ runAgentFlow: os.runAgentFlow.handler(({ input }) => streamFlow((onLine) => runAgentOp(input.op, runtime.scopes(), onLine))),
78
82
  });
79
83
  };
80
84
  //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/device/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Desktop, WindowInfo } from "@intentic/desktop";
2
+ export interface FakeDesktop {
3
+ readonly desktop: Desktop;
4
+ readonly calls: string[];
5
+ windows: WindowInfo[];
6
+ clipboard: string;
7
+ }
8
+ export declare const fakeWindow: (overrides?: Partial<WindowInfo>) => WindowInfo;
9
+ export declare const fakeDesktop: () => FakeDesktop;
10
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/device/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAuC,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAUlG,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAEzB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,eAAe,OAAO,CAAC,UAAU,CAAC,KAAQ,UAO/D,CAAC;AAEH,eAAO,MAAM,WAAW,QAAO,WA2C9B,CAAC"}
@@ -0,0 +1,51 @@
1
+ export const fakeWindow = (overrides = {}) => ({
2
+ id: "1",
3
+ title: "Untitled",
4
+ app: "app",
5
+ bounds: { x: 0, y: 0, width: 800, height: 600 },
6
+ focused: false,
7
+ ...overrides,
8
+ });
9
+ export const fakeDesktop = () => {
10
+ const calls = [];
11
+ const state = { windows: [], clipboard: "" };
12
+ const desktop = {
13
+ frame: async () => ({ width: 1920, height: 1080, origin: { x: 0, y: 0 } }),
14
+ capture: async () => Buffer.alloc(0),
15
+ move: async (to) => void calls.push(`move ${to.x},${to.y}`),
16
+ click: async (at, button) => void calls.push(`click ${button} ${at.x},${at.y}`),
17
+ doubleClick: async (at) => void calls.push(`double ${at.x},${at.y}`),
18
+ drag: async (from, to) => void calls.push(`drag ${from.x},${from.y}->${to.x},${to.y}`),
19
+ type: async (text) => void calls.push(`type ${text}`),
20
+ key: async (combo) => void calls.push(`key ${combo}`),
21
+ scroll: async (at, direction, amount) => void calls.push(`scroll ${direction} ${amount} @${at.x},${at.y}`),
22
+ windows: async () => state.windows,
23
+ focusWindow: async (id) => {
24
+ calls.push(`focus ${id}`);
25
+ state.windows = state.windows.map((window) => ({ ...window, focused: window.id === id }));
26
+ },
27
+ launch: async (target) => void calls.push(`launch ${target}`),
28
+ readClipboard: async () => state.clipboard,
29
+ writeClipboard: async (text) => {
30
+ calls.push(`clipboard ${text}`);
31
+ state.clipboard = text;
32
+ },
33
+ };
34
+ return {
35
+ desktop,
36
+ calls,
37
+ get windows() {
38
+ return state.windows;
39
+ },
40
+ set windows(next) {
41
+ state.windows = next;
42
+ },
43
+ get clipboard() {
44
+ return state.clipboard;
45
+ },
46
+ set clipboard(next) {
47
+ state.clipboard = next;
48
+ },
49
+ };
50
+ };
51
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/device/testing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { DeviceAgentOp, HostScopes } from "@intentic/sandbox-contract";
2
+ export declare const AGENT_VERB: Record<DeviceAgentOp, string>;
3
+ export declare const runAgentOp: (op: DeviceAgentOp, scopes: HostScopes, onLine: (line: string) => void) => Promise<string>;
4
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/device/tools/agent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAqC5E,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAA0C,CAAC;AA4BhG,eAAO,MAAM,UAAU,OAAc,aAAa,UAAU,UAAU,UAAU,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAG,OAAO,CAAC,MAAM,CAoCtH,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { setTimeout as sleep } from "node:timers/promises";
3
+ import { isProcessAlive, spawnDetached } from "@intentic/local-agent";
4
+ import { agentLogPath } from "../../config.js";
5
+ import { installedBuild } from "../../installed.js";
6
+ import { machineLauncher } from "../../resident.js";
7
+ import { assertScope } from "../policy.js";
8
+ export const AGENT_VERB = { upgrade: "upgrade", restart: "run" };
9
+ const DRAIN_MS = 1_500;
10
+ const POLL_MS = 250;
11
+ const WATCH_TIMEOUT_MS = 20 * 60 * 1000;
12
+ const readFrom = async (path, from) => {
13
+ const raw = await readFile(path, "utf8").catch(() => "");
14
+ return { text: raw.slice(from), at: raw.length };
15
+ };
16
+ export const runAgentOp = async (op, scopes, onLine) => {
17
+ assertScope(scopes, "shell");
18
+ const installed = installedBuild();
19
+ onLine(op === "upgrade"
20
+ ? `Updating the agent on this device${installed === undefined ? "" : ` (currently ${installed})`}. Its background loop restarts, so this connection drops while that happens.`
21
+ : `Restarting this device's agent loop. This connection drops while that happens.`);
22
+ const start = (await readFrom(agentLogPath, 0)).at;
23
+ const pid = await spawnDetached(agentLogPath, machineLauncher(), [AGENT_VERB[op]]);
24
+ onLine(`Started ${AGENT_VERB[op]} (pid ${pid}), detached from this connection so it finishes either way. Log: ${agentLogPath}`);
25
+ let at = start;
26
+ const deadline = Date.now() + WATCH_TIMEOUT_MS;
27
+ let goneAt;
28
+ while (Date.now() < deadline) {
29
+ const { text, at: next } = await readFrom(agentLogPath, at);
30
+ at = next;
31
+ for (const line of text.split(/\r?\n/).filter((one) => one.trim() !== "")) {
32
+ onLine(line);
33
+ }
34
+ if (!isProcessAlive(pid)) {
35
+ goneAt ??= Date.now();
36
+ if (Date.now() - goneAt > DRAIN_MS) {
37
+ break;
38
+ }
39
+ }
40
+ await sleep(POLL_MS);
41
+ }
42
+ return op === "upgrade"
43
+ ? `The update ran on this device. Whether the new agent is the one serving shows in its version, which this view re-reads on its own.`
44
+ : `The agent loop was restarted on this device.`;
45
+ };
46
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/device/tools/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../../src/device/tools/apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAmB7D,eAAO,MAAM,eAAe,YAAa,SAAS,UAAU,EAAE,KAAG,MAShE,CAAC;AAEF,eAAO,MAAM,WAAW,WAAkB,OAAO,UAAU,UAAU,KAAG,OAAO,CAAC,MAAM,CAGrF,CAAC;AAKF,eAAO,MAAM,WAAW,WAAkB,OAAO,MAAM,MAAM,UAAU,UAAU,KAAG,OAAO,CAAC,MAAM,CAQjG,CAAC;AAEF,eAAO,MAAM,UAAU,WAAkB,OAAO,UAAU,MAAM,UAAU,UAAU,KAAG,OAAO,CAAC,MAAM,CAQpG,CAAC;AAIF,eAAO,MAAM,aAAa,WAAkB,OAAO,UAAU,UAAU,KAAG,OAAO,CAAC,MAAM,CAIvF,CAAC;AAEF,eAAO,MAAM,cAAc,WAAkB,OAAO,QAAQ,MAAM,UAAU,UAAU,KAAG,OAAO,CAAC,MAAM,CAItG,CAAC"}
@@ -2,7 +2,7 @@ import { DesktopError } from "@intentic/desktop";
2
2
  import { assertScope } from "../policy.js";
3
3
  export const describeWindows = (windows) => {
4
4
  if (windows.length === 0) {
5
- return "No windows are open on this computer.";
5
+ return "No windows are open on this device.";
6
6
  }
7
7
  const rows = windows.map((window) => `${window.focused ? "* " : " "}[${window.id}] ${window.app}, ${window.title} (${window.bounds.width}×${window.bounds.height} at ${window.bounds.x},${window.bounds.y})`);
8
8
  return [`${windows.length} window${windows.length === 1 ? "" : "s"} (* = focused). Pass the id in brackets to focus_window.`, ...rows].join("\n");
@@ -18,7 +18,7 @@ export const focusWindow = async (screen, id, scopes) => {
18
18
  }
19
19
  await screen.focusWindow(id);
20
20
  const focused = (await screen.windows().catch(() => [])).find((window) => window.focused);
21
- return focused === undefined ? `Asked this computer to focus window ${id}.` : `Focused: ${focused.app}, ${focused.title}. Typing now goes here.`;
21
+ return focused === undefined ? `Asked this device to focus window ${id}.` : `Focused: ${focused.app}, ${focused.title}. Typing now goes here.`;
22
22
  };
23
23
  export const openTarget = async (screen, target, scopes) => {
24
24
  assertScope(scopes, "shell");
@@ -36,6 +36,6 @@ export const readClipboard = async (screen, scopes) => {
36
36
  export const writeClipboard = async (screen, text, scopes) => {
37
37
  assertScope(scopes, "control");
38
38
  await screen.writeClipboard(text);
39
- return `Put ${text.length} characters on this computer's clipboard.`;
39
+ return `Put ${text.length} characters on this device's clipboard.`;
40
40
  };
41
41
  //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/device/tools/apps.ts"],"names":[],"mappings":"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"}