@intentic/machine 1.308.0 → 1.309.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +52 -2
  2. package/dist/device/connection.d.ts +2 -1
  3. package/dist/device/connection.d.ts.map +1 -1
  4. package/dist/device/connection.js +13 -2
  5. package/dist/device/connection.js.map +1 -1
  6. package/dist/device/indicator.d.ts +28 -0
  7. package/dist/device/indicator.d.ts.map +1 -0
  8. package/dist/device/indicator.js +115 -0
  9. package/dist/device/indicator.js.map +1 -0
  10. package/dist/device/mcp.d.ts.map +1 -1
  11. package/dist/device/mcp.js +62 -8
  12. package/dist/device/mcp.js.map +1 -1
  13. package/dist/device/policy.d.ts +4 -1
  14. package/dist/device/policy.d.ts.map +1 -1
  15. package/dist/device/policy.js +23 -5
  16. package/dist/device/policy.js.map +1 -1
  17. package/dist/device/router.d.ts +2 -0
  18. package/dist/device/router.d.ts.map +1 -1
  19. package/dist/device/router.js +4 -3
  20. package/dist/device/router.js.map +1 -1
  21. package/dist/device/tools/apps.d.ts +3 -2
  22. package/dist/device/tools/apps.d.ts.map +1 -1
  23. package/dist/device/tools/apps.js +5 -2
  24. package/dist/device/tools/apps.js.map +1 -1
  25. package/dist/device/tools/device.d.ts +2 -1
  26. package/dist/device/tools/device.d.ts.map +1 -1
  27. package/dist/device/tools/device.js +30 -37
  28. package/dist/device/tools/device.js.map +1 -1
  29. package/dist/device/tools/files.d.ts +14 -2
  30. package/dist/device/tools/files.d.ts.map +1 -1
  31. package/dist/device/tools/files.js +164 -16
  32. package/dist/device/tools/files.js.map +1 -1
  33. package/dist/device/tools/sandboxes.d.ts +7 -4
  34. package/dist/device/tools/sandboxes.d.ts.map +1 -1
  35. package/dist/device/tools/sandboxes.js +22 -10
  36. package/dist/device/tools/sandboxes.js.map +1 -1
  37. package/dist/device/tools/shell.d.ts +7 -2
  38. package/dist/device/tools/shell.d.ts.map +1 -1
  39. package/dist/device/tools/shell.js +99 -39
  40. package/dist/device/tools/shell.js.map +1 -1
  41. package/dist/status.d.ts +1 -0
  42. package/dist/status.d.ts.map +1 -1
  43. package/dist/status.js +13 -2
  44. package/dist/status.js.map +1 -1
  45. package/package.json +8 -8
@@ -3,6 +3,9 @@ export declare class ScopeError extends Error {
3
3
  }
4
4
  export declare const rootsOf: (scopes: DeviceScopes) => string[];
5
5
  export declare const withinRoots: (path: string, roots: readonly string[]) => boolean;
6
- export declare const assertPath: (path: string, scopes: DeviceScopes, intent: string) => string;
6
+ export declare const realPathOf: (path: string) => Promise<string>;
7
+ export declare const assertPath: (path: string, scopes: DeviceScopes, intent: string, { link }?: {
8
+ readonly link?: "follow" | "itself";
9
+ }) => Promise<string>;
7
10
  export declare const assertScope: (scopes: DeviceScopes, scope: "shell" | "write" | "screen" | "control" | "sandboxes" | "destructive") => void;
8
11
  //# sourceMappingURL=policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/device/policy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAM/D,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAGxC,eAAO,MAAM,OAAO,WAAY,YAAY,KAAG,MAAM,EAUpD,CAAC;AAKF,eAAO,MAAM,WAAW,SAAU,MAAM,SAAS,SAAS,MAAM,EAAE,KAAG,OAGpE,CAAC;AAIF,eAAO,MAAM,UAAU,SAAU,MAAM,UAAU,YAAY,UAAU,MAAM,KAAG,MAS/E,CAAC;AAGF,eAAO,MAAM,WAAW,WACZ,YAAY,SACb,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,KAC9E,IAaF,CAAC"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/device/policy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAM/D,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAGxC,eAAO,MAAM,OAAO,WAAY,YAAY,KAAG,MAAM,EAUpD,CAAC;AAIF,eAAO,MAAM,WAAW,SAAU,MAAM,SAAS,SAAS,MAAM,EAAE,KAAG,OAGpE,CAAC;AAIF,eAAO,MAAM,UAAU,SAAgB,MAAM,KAAG,OAAO,CAAC,MAAM,CAY7D,CAAC;AAIF,eAAO,MAAM,UAAU,SACb,MAAM,UACJ,YAAY,UACZ,MAAM,aACO;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;CAAE,KAC7D,OAAO,CAAC,MAAM,CAchB,CAAC;AAGF,eAAO,MAAM,WAAW,WACZ,YAAY,SACb,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,KAC9E,IAaF,CAAC"}
@@ -1,5 +1,6 @@
1
+ import { realpath } from "node:fs/promises";
1
2
  import { homedir } from "node:os";
2
- import { isAbsolute, join, resolve, sep } from "node:path";
3
+ import { basename, dirname, isAbsolute, join, resolve, sep } from "node:path";
3
4
  export class ScopeError extends Error {
4
5
  }
5
6
  export const rootsOf = (scopes) => {
@@ -16,13 +17,30 @@ export const withinRoots = (path, roots) => {
16
17
  const target = resolve(path);
17
18
  return roots.some((root) => target === root || target.startsWith(root.endsWith(sep) ? root : `${root}${sep}`));
18
19
  };
19
- export const assertPath = (path, scopes, intent) => {
20
+ export const realPathOf = async (path) => {
21
+ const absolute = resolve(path);
22
+ try {
23
+ return await realpath(absolute);
24
+ }
25
+ catch (error) {
26
+ const code = error.code;
27
+ const parent = dirname(absolute);
28
+ if ((code !== "ENOENT" && code !== "ENOTDIR") || parent === absolute) {
29
+ throw error;
30
+ }
31
+ return join(await realPathOf(parent), basename(absolute));
32
+ }
33
+ };
34
+ export const assertPath = async (path, scopes, intent, { link = "follow" } = {}) => {
20
35
  const roots = rootsOf(scopes);
21
- if (!withinRoots(path, roots)) {
22
- throw new ScopeError(`Refused to ${intent} "${path}": it is outside the folders this device allows (${roots.join(", ")}). ` +
36
+ const absolute = resolve(path);
37
+ const real = link === "follow" ? await realPathOf(absolute) : join(await realPathOf(dirname(absolute)), basename(absolute));
38
+ if (!withinRoots(real, await Promise.all(roots.map(realPathOf)))) {
39
+ const leads = real === absolute ? "" : ` (it leads to ${real})`;
40
+ throw new ScopeError(`Refused to ${intent} "${path}"${leads}: it is outside the folders this device allows (${roots.join(", ")}). ` +
23
41
  `Widen "Folders it may touch" on this device's capability card to change that.`);
24
42
  }
25
- return resolve(path);
43
+ return real;
26
44
  };
27
45
  export const assertScope = (scopes, scope) => {
28
46
  if (scopes[scope] === "on") {
@@ -1 +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;AAO3D,MAAM,OAAO,UAAW,SAAQ,KAAK;CAAG;AAGxC,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAoB,EAAY,EAAE;IACtD,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;AAKF,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,MAAoB,EAAE,MAAc,EAAU,EAAE;IACrF,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;AAGF,MAAM,CAAC,MAAM,WAAW,GAAG,CACvB,MAAoB,EACpB,KAA6E,EACzE,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,WAAW,EAAE,0BAA0B;KAC1C,CAAC,KAAK,CAAC,CAAC;IACT,MAAM,IAAI,UAAU,CAAC,aAAa,KAAK,qFAAqF,CAAC,CAAC;AAClI,CAAC,CAAC"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/device/policy.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { type DeviceScopes } from "@intentic/sandbox-contract";
2
2
  export interface HostRuntime {
3
+ readonly sandboxUrl: string;
3
4
  readonly scopes: () => DeviceScopes;
4
5
  readonly setScopes: (scopes: DeviceScopes) => void;
5
6
  readonly log: (message: string) => void;
@@ -153,6 +154,7 @@ export declare const createHostRouter: (runtime: HostRuntime) => {
153
154
  parentUrl: import("zod").ZodOptional<import("zod").ZodString>;
154
155
  pair: import("zod").ZodOptional<import("zod").ZodString>;
155
156
  setupCode: import("zod").ZodOptional<import("zod").ZodString>;
157
+ platformUrl: import("zod").ZodOptional<import("zod").ZodString>;
156
158
  definition: import("zod").ZodOptional<import("zod").ZodString>;
157
159
  overlay: import("zod").ZodOptional<import("zod").ZodString>;
158
160
  overlayHash: import("zod").ZodOptional<import("zod").ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/device/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,YAAY,EAAqF,MAAM,4BAA4B,CAAC;AAqBlJ,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,YAAY,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAkFD,eAAO,MAAM,gBAAgB,YAAa,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BpD,CAAC"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/device/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,YAAY,EAAqF,MAAM,4BAA4B,CAAC;AAsBlJ,MAAM,WAAW,WAAW;IAExB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,YAAY,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAkFD,eAAO,MAAM,gBAAgB,YAAa,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BpD,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { narrate } from "@intentic/base/async";
2
2
  import { deviceContract } from "@intentic/sandbox-contract";
3
3
  import { implement, ORPCError } from "@orpc/server";
4
+ import { calling } from "./indicator.js";
4
5
  import { handleMcpMessage } from "./mcp.js";
5
6
  import { hostFacts } from "./tools/describe.js";
6
7
  import { machineReport } from "../sync/report.js";
@@ -24,8 +25,8 @@ const FLOWS = {
24
25
  reshape: ({ slug, resources }, scopes) => (onLine) => reshapeSandbox(slug, resources, scopes, onLine),
25
26
  remove: ({ slug }, scopes) => (onLine) => removeSandbox(slug, scopes, onLine),
26
27
  logs: ({ slug }, scopes) => (onLine) => tailSandboxLogs(slug, scopes, onLine),
27
- reconnect: ({ slug, setupCode }, scopes) => (onLine) => reconnectSandbox(slug, setupCode, scopes, onLine),
28
- create: ({ slug, setupCode }, scopes) => (onLine) => createSandbox(slug, setupCode, scopes, onLine),
28
+ reconnect: ({ slug, setupCode, platformUrl }, scopes) => (onLine) => reconnectSandbox(slug, setupCode, platformUrl, scopes, onLine),
29
+ create: ({ slug, setupCode, platformUrl }, scopes) => (onLine) => createSandbox(slug, setupCode, platformUrl, scopes, onLine),
29
30
  "runner-up": runnerFlowFor,
30
31
  "runner-remove": runnerFlowFor,
31
32
  };
@@ -45,7 +46,7 @@ export const createHostRouter = (runtime) => {
45
46
  return { ok: true };
46
47
  }),
47
48
  ping: os.ping.handler(() => ({ ok: true })),
48
- mcp: os.mcp.handler(async ({ input }) => await handleMcpMessage(input, runtime.scopes())),
49
+ mcp: os.mcp.handler(async ({ input }) => await calling.run(runtime, async () => await handleMcpMessage(input, runtime.scopes()))),
49
50
  runSandboxFlow: os.runSandboxFlow.handler(({ input }) => streamFlow(FLOWS[input.op](input, runtime.scopes()))),
50
51
  runAgentFlow: os.runAgentFlow.handler(({ input }) => streamFlow((onLine) => runAgentOp(input.op, runtime.scopes(), onLine))),
51
52
  });
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/device/router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/device/router.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  import { type Desktop, type WindowInfo } from "@intentic/desktop-automation";
2
2
  import type { DeviceScopes } from "@intentic/sandbox-contract";
3
+ import { type Indicator } from "../indicator.js";
3
4
  export declare const describeWindows: (windows: readonly WindowInfo[]) => string;
4
5
  export declare const listWindows: (screen: Desktop, scopes: DeviceScopes) => Promise<string>;
5
- export declare const focusWindow: (screen: Desktop, id: string, scopes: DeviceScopes) => Promise<string>;
6
+ export declare const focusWindow: (screen: Desktop, id: string, scopes: DeviceScopes, indicator?: Indicator) => Promise<string>;
6
7
  export declare const openTarget: (screen: Desktop, target: string, scopes: DeviceScopes) => Promise<string>;
7
8
  export declare const readClipboard: (screen: Desktop, scopes: DeviceScopes) => Promise<string>;
8
- export declare const writeClipboard: (screen: Desktop, text: string, scopes: DeviceScopes) => Promise<string>;
9
+ export declare const writeClipboard: (screen: Desktop, text: string, scopes: DeviceScopes, indicator?: Indicator) => Promise<string>;
9
10
  //# sourceMappingURL=apps.d.ts.map
@@ -1 +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,8BAA8B,CAAC;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAS/D,eAAO,MAAM,eAAe,YAAa,SAAS,UAAU,EAAE,KAAG,MAShE,CAAC;AAEF,eAAO,MAAM,WAAW,WAAkB,OAAO,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAGvF,CAAC;AAIF,eAAO,MAAM,WAAW,WAAkB,OAAO,MAAM,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAQnG,CAAC;AAEF,eAAO,MAAM,UAAU,WAAkB,OAAO,UAAU,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAQtG,CAAC;AAIF,eAAO,MAAM,aAAa,WAAkB,OAAO,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAIzF,CAAC;AAEF,eAAO,MAAM,cAAc,WAAkB,OAAO,QAAQ,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAIxG,CAAC"}
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,8BAA8B,CAAC;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAW,KAAK,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAS5E,eAAO,MAAM,eAAe,YAAa,SAAS,UAAU,EAAE,KAAG,MAShE,CAAC;AAEF,eAAO,MAAM,WAAW,WAAkB,OAAO,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAGvF,CAAC;AAIF,eAAO,MAAM,WAAW,WAAkB,OAAO,MAAM,MAAM,UAAU,YAAY,cAAa,SAAS,KAAwB,OAAO,CAAC,MAAM,CAU9I,CAAC;AAEF,eAAO,MAAM,UAAU,WAAkB,OAAO,UAAU,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAQtG,CAAC;AAIF,eAAO,MAAM,aAAa,WAAkB,OAAO,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAIzF,CAAC;AAEF,eAAO,MAAM,cAAc,WAAkB,OAAO,QAAQ,MAAM,UAAU,YAAY,cAAa,SAAS,KAAwB,OAAO,CAAC,MAAM,CAMnJ,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { DesktopError } from "@intentic/desktop-automation";
2
+ import { calling, machineIndicator } from "../indicator.js";
2
3
  import { assertScope } from "../policy.js";
3
4
  export const describeWindows = (windows) => {
4
5
  if (windows.length === 0) {
@@ -11,11 +12,12 @@ export const listWindows = async (screen, scopes) => {
11
12
  assertScope(scopes, "screen");
12
13
  return describeWindows(await screen.windows());
13
14
  };
14
- export const focusWindow = async (screen, id, scopes) => {
15
+ export const focusWindow = async (screen, id, scopes, indicator = machineIndicator()) => {
15
16
  assertScope(scopes, "control");
16
17
  if (id === "") {
17
18
  throw new DesktopError(`"id" is required: take a window list first and pass the id in brackets.`);
18
19
  }
20
+ await indicator.control(calling.getStore());
19
21
  await screen.focusWindow(id);
20
22
  const focused = (await screen.windows().catch(() => [])).find((window) => window.focused);
21
23
  return focused === undefined ? `Asked this device to focus window ${id}.` : `Focused: ${focused.app}, ${focused.title}. Typing now goes here.`;
@@ -33,8 +35,9 @@ export const readClipboard = async (screen, scopes) => {
33
35
  const text = await screen.readClipboard();
34
36
  return text === "" ? "The clipboard is empty." : text;
35
37
  };
36
- export const writeClipboard = async (screen, text, scopes) => {
38
+ export const writeClipboard = async (screen, text, scopes, indicator = machineIndicator()) => {
37
39
  assertScope(scopes, "control");
40
+ await indicator.control(calling.getStore());
38
41
  await screen.writeClipboard(text);
39
42
  return `Put ${text.length} characters on this device's clipboard.`;
40
43
  };
@@ -1 +1 @@
1
- {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/device/tools/apps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/device/tools/apps.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { type Desktop, type ScrollDirection } from "@intentic/desktop-automation";
2
2
  import type { DeviceScopes } from "@intentic/sandbox-contract";
3
+ import { type Indicator } from "../indicator.js";
3
4
  export type DeviceAction = "mouse_move" | "left_click" | "right_click" | "middle_click" | "double_click" | "left_click_drag" | "type" | "key" | "scroll" | "wait";
4
5
  export interface DeviceInput {
5
6
  readonly action: DeviceAction;
@@ -11,6 +12,6 @@ export interface DeviceInput {
11
12
  readonly ms?: number | undefined;
12
13
  }
13
14
  export declare const describeAction: (input: DeviceInput) => string;
14
- export declare const act: (screen: Desktop, input: DeviceInput, scopes: DeviceScopes) => Promise<void>;
15
+ export declare const act: (screen: Desktop, input: DeviceInput, scopes: DeviceScopes, indicator?: Indicator) => Promise<void>;
15
16
  export declare const settle: () => Promise<void>;
16
17
  //# sourceMappingURL=device.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../../src/device/tools/device.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAA8C,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC9H,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAQ/D,MAAM,MAAM,YAAY,GACpB,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3I,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AA4BD,eAAO,MAAM,cAAc,UAAW,WAAW,KAAG,MAenD,CAAC;AAIF,eAAO,MAAM,GAAG,WAAkB,OAAO,SAAS,WAAW,UAAU,YAAY,KAAG,OAAO,CAAC,IAAI,CA6CjG,CAAC;AAIF,eAAO,MAAM,MAAM,QAAa,OAAO,CAAC,IAAI,CAA2B,CAAC"}
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../../src/device/tools/device.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAA8C,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC9H,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAW,KAAK,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAQ5E,MAAM,MAAM,YAAY,GACpB,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3I,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AA4BD,eAAO,MAAM,cAAc,UAAW,WAAW,KAAG,MAenD,CAAC;AAqCF,eAAO,MAAM,GAAG,WAAkB,OAAO,SAAS,WAAW,UAAU,YAAY,cAAa,SAAS,KAAwB,OAAO,CAAC,IAAI,CAQ5I,CAAC;AAIF,eAAO,MAAM,MAAM,QAAa,OAAO,CAAC,IAAI,CAA2B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { sleep } from "@intentic/base/async";
2
2
  import { DesktopError } from "@intentic/desktop-automation";
3
+ import { calling, machineIndicator } from "../indicator.js";
3
4
  import { assertScope } from "../policy.js";
4
5
  const SETTLE_MS = 400;
5
6
  const MAX_WAIT_MS = 10_000;
@@ -32,49 +33,41 @@ export const describeAction = (input) => {
32
33
  return `${input.action.replace(/_/g, " ")} at (${input.coordinate?.join(", ") ?? ""}).`;
33
34
  }
34
35
  };
35
- export const act = async (screen, input, scopes) => {
36
- assertScope(scopes, "control");
37
- if (input.action === "wait") {
38
- await sleep(Math.min(Math.max(0, input.ms ?? SETTLE_MS), MAX_WAIT_MS));
39
- return;
40
- }
41
- if (input.action === "type") {
42
- if (input.text === undefined || input.text === "") {
43
- throw new DesktopError(`"text" is required to type.`);
44
- }
45
- await screen.type(input.text);
46
- return;
47
- }
48
- if (input.action === "key") {
49
- if (input.text === undefined || input.text === "") {
50
- throw new DesktopError(`"text" is required to press a key: for example "Return", "ctrl+c", "alt+Tab".`);
51
- }
52
- await screen.key(input.text);
53
- return;
36
+ const keyboard = async (screen, action, text) => {
37
+ if (text === undefined || text === "") {
38
+ throw new DesktopError(action === "type" ? `"text" is required to type.` : `"text" is required to press a key: for example "Return", "ctrl+c", "alt+Tab".`);
54
39
  }
40
+ await (action === "type" ? screen.type(text) : screen.key(text));
41
+ };
42
+ const pointer = async (screen, input) => {
55
43
  const frame = await screen.frame();
56
44
  const at = within(point(input.coordinate, "coordinate"), frame, "The coordinate");
57
- if (input.action === "mouse_move") {
58
- await screen.move(at);
59
- return;
60
- }
61
- if (input.action === "double_click") {
62
- await screen.doubleClick(at);
63
- return;
64
- }
65
- if (input.action === "left_click_drag") {
66
- await screen.drag(at, within(point(input.to, "to"), frame, "The drag target"));
67
- return;
45
+ switch (input.action) {
46
+ case "mouse_move":
47
+ return await screen.move(at);
48
+ case "double_click":
49
+ return await screen.doubleClick(at);
50
+ case "left_click_drag":
51
+ return await screen.drag(at, within(point(input.to, "to"), frame, "The drag target"));
52
+ case "scroll":
53
+ return await screen.scroll(at, input.direction ?? "down", input.amount ?? 3);
54
+ default: {
55
+ const button = CLICK_BUTTON[input.action];
56
+ if (button === undefined) {
57
+ throw new DesktopError(`"${input.action}" is not something this device can do.`);
58
+ }
59
+ return await screen.click(at, button);
60
+ }
68
61
  }
69
- if (input.action === "scroll") {
70
- await screen.scroll(at, input.direction ?? "down", input.amount ?? 3);
62
+ };
63
+ export const act = async (screen, input, scopes, indicator = machineIndicator()) => {
64
+ assertScope(scopes, "control");
65
+ if (input.action === "wait") {
66
+ await sleep(Math.min(Math.max(0, input.ms ?? SETTLE_MS), MAX_WAIT_MS));
71
67
  return;
72
68
  }
73
- const button = CLICK_BUTTON[input.action];
74
- if (button === undefined) {
75
- throw new DesktopError(`"${input.action}" is not something this device can do.`);
76
- }
77
- await screen.click(at, button);
69
+ await indicator.control(calling.getStore());
70
+ await (input.action === "type" || input.action === "key" ? keyboard(screen, input.action, input.text) : pointer(screen, input));
78
71
  };
79
72
  export const settle = async () => await sleep(SETTLE_MS);
80
73
  //# sourceMappingURL=device.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"device.js","sourceRoot":"","sources":["../../../src/device/tools/device.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../../../src/device/tools/device.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,18 @@
1
1
  import type { DeviceScopes } from "@intentic/sandbox-contract";
2
- export declare const readTextFile: (path: string, scopes: DeviceScopes) => Promise<string>;
3
- export declare const writeTextFile: (path: string, content: string, scopes: DeviceScopes) => Promise<string>;
2
+ export interface FileRead {
3
+ readonly text: string;
4
+ readonly note: string;
5
+ }
6
+ export declare const readTextFile: (path: string, range: {
7
+ readonly offset?: number | undefined;
8
+ readonly limit?: number | undefined;
9
+ }, scopes: DeviceScopes) => Promise<FileRead>;
10
+ export declare const writeTextFile: (path: string, content: string, revision: string | undefined, scopes: DeviceScopes) => Promise<string>;
11
+ export declare const editTextFile: (path: string, edit: {
12
+ readonly oldString: string;
13
+ readonly newString: string;
14
+ readonly revision: string;
15
+ }, scopes: DeviceScopes) => Promise<string>;
4
16
  export interface DirEntry {
5
17
  readonly name: string;
6
18
  readonly kind: "file" | "directory" | "other";
@@ -1 +1 @@
1
- {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/device/tools/files.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAY/D,eAAO,MAAM,YAAY,SAAgB,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAUrF,CAAC;AAEF,eAAO,MAAM,aAAa,SAAgB,MAAM,WAAW,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAYvG,CAAC;AAEF,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,aAAa,SAAgB,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,QAAQ,EAAE,CAe1F,CAAC;AAIF,eAAO,MAAM,SAAS,SAAgB,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAuBlF,CAAC"}
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/device/tools/files.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAyG/D,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAkCD,eAAO,MAAM,YAAY,SACf,MAAM,SACL;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,UAC5E,YAAY,KACrB,OAAO,CAAC,QAAQ,CAOlB,CAAC;AAsCF,eAAO,MAAM,aAAa,SAAgB,MAAM,WAAW,MAAM,YAAY,MAAM,GAAG,SAAS,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAuBrI,CAAC;AAGF,eAAO,MAAM,YAAY,SACf,MAAM,QACN;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,UACnF,YAAY,KACrB,OAAO,CAAC,MAAM,CAsBhB,CAAC;AAEF,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,aAAa,SAAgB,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,QAAQ,EAAE,CAe1F,CAAC;AAMF,eAAO,MAAM,SAAS,SAAgB,MAAM,UAAU,YAAY,KAAG,OAAO,CAAC,MAAM,CAuBlF,CAAC"}
@@ -1,29 +1,177 @@
1
- import { mkdir, readdir, readFile, rename, stat, writeFile } from "node:fs/promises";
1
+ import { isUtf8 } from "node:buffer";
2
+ import { createHash } from "node:crypto";
3
+ import { chmod, lstat, mkdir, readdir, readFile, rename, stat } from "node:fs/promises";
2
4
  import { basename, dirname, join } from "node:path";
3
- import { agentHome } from "@intentic/local-agent";
5
+ import { agentHome, writeFileAtomic } from "@intentic/local-agent";
4
6
  import { assertPath, assertScope } from "../policy.js";
5
- const MAX_READ_BYTES = 2_000_000;
6
- export const readTextFile = async (path, scopes) => {
7
- const target = assertPath(path, scopes, "read");
7
+ const MAX_READ_CHARS = 2_000_000;
8
+ const MAX_FILE_BYTES = 10_000_000;
9
+ const UTF8_BOM = Buffer.from([0xef, 0xbb, 0xbf]);
10
+ const UTF16LE_BOM = Buffer.from([0xff, 0xfe]);
11
+ const revisionOf = (bytes) => createHash("sha256").update(bytes).digest("hex").slice(0, 16);
12
+ const decode = (bytes, path) => {
13
+ const utf16 = bytes.subarray(0, 2).equals(UTF16LE_BOM);
14
+ if (!utf16 && bytes.subarray(0, 8000).includes(0)) {
15
+ throw new Error(`"${path}" is not a text file: it has NUL bytes, which text does not.`);
16
+ }
17
+ const bom = !utf16 && bytes.subarray(0, 3).equals(UTF8_BOM);
18
+ const body = bytes.subarray(utf16 ? 2 : bom ? 3 : 0);
19
+ const encoding = utf16 ? "utf16le-bom" : !isUtf8(body) ? undefined : bom ? "utf8-bom" : "utf8";
20
+ const raw = body.toString(utf16 ? "utf16le" : "utf8");
21
+ const text = raw.replaceAll("\r\n", "\n");
22
+ const crlfs = raw.length - text.length;
23
+ return { text, encoding, crlf: crlfs > text.split("\n").length - 1 - crlfs, revision: revisionOf(bytes) };
24
+ };
25
+ const encode = (text, file) => {
26
+ if (file === undefined) {
27
+ return Buffer.from(text, "utf8");
28
+ }
29
+ const lf = text.replace(/^\uFEFF/, "").replaceAll("\r\n", "\n");
30
+ const body = file.crlf ? lf.replaceAll("\n", "\r\n") : lf;
31
+ if (file.encoding === "utf16le-bom") {
32
+ return Buffer.concat([UTF16LE_BOM, Buffer.from(body, "utf16le")]);
33
+ }
34
+ return file.encoding === "utf8-bom" ? Buffer.concat([UTF8_BOM, Buffer.from(body, "utf8")]) : Buffer.from(body, "utf8");
35
+ };
36
+ const formatOf = (file) => [
37
+ file.encoding === "utf8-bom" ? "as UTF-8 with BOM" : file.encoding === "utf16le-bom" ? "as UTF-16LE with BOM" : "",
38
+ file.crlf ? "with CRLF line endings" : "",
39
+ ]
40
+ .filter((part) => part !== "")
41
+ .join(" and ");
42
+ const noteOf = (file, position) => [
43
+ position,
44
+ `Revision ${file.revision}: write_file and edit_file need it to change this file.`,
45
+ file.encoding === undefined
46
+ ? "Not UTF-8 or UTF-16 text (a legacy code page, most likely): bytes that did not decode show as �, and write_file and edit_file will not change this file."
47
+ : formatOf(file) === ""
48
+ ? ""
49
+ : `Saved ${formatOf(file)}${file.crlf ? " (shown here as LF)" : ""}, which a write keeps.`,
50
+ ]
51
+ .filter((part) => part !== "")
52
+ .join(" ");
53
+ const linesOf = (text) => (text === "" ? [] : (text.endsWith("\n") ? text.slice(0, -1) : text).split("\n"));
54
+ const megabytes = (bytes) => `${(bytes / 1_000_000).toFixed(1)} MB`;
55
+ const linesText = (count) => (count === 1 ? "1 line" : `${count} lines`);
56
+ const load = async (target, path) => {
8
57
  const info = await stat(target);
9
58
  if (info.isDirectory()) {
10
59
  throw new Error(`"${path}" is a directory: use list_dir for it.`);
11
60
  }
12
- if (info.size > MAX_READ_BYTES) {
13
- throw new Error(`"${path}" is ${Math.round(info.size / 1_000_000)} MB, too large to read whole. Read part of it with a command instead.`);
61
+ if (!info.isFile()) {
62
+ throw new Error(`"${path}" is not a regular file, and these tools open only those.`);
63
+ }
64
+ if (info.size > MAX_FILE_BYTES) {
65
+ throw new Error(`"${path}" is ${megabytes(info.size)}, more than these tools open. Read or change it with a command instead.`);
66
+ }
67
+ return { bytes: await readFile(target), mode: info.mode & 0o7777 };
68
+ };
69
+ const wholeRead = (file, lines, path) => {
70
+ if (file.text.length > MAX_READ_CHARS) {
71
+ throw new Error(`"${path}" is ${linesText(lines.length)}, more than one read answers with: read it in parts with offset and limit.`);
14
72
  }
15
- return await readFile(target, "utf8");
73
+ return { text: file.text, note: noteOf(file, lines.length === 0 ? "The file is empty." : `All ${linesText(lines.length)}.`) };
16
74
  };
17
- export const writeTextFile = async (path, content, scopes) => {
75
+ const rangeRead = (file, lines, offset, limit, path) => {
76
+ if (offset > lines.length) {
77
+ throw new Error(`"${path}" has ${linesText(lines.length)}, so there is nothing from line ${offset} on.`);
78
+ }
79
+ const wanted = lines.slice(offset - 1, limit === undefined ? undefined : offset - 1 + limit);
80
+ let size = 0;
81
+ let shown = 0;
82
+ for (const line of wanted) {
83
+ size += line.length + 1;
84
+ if (size > MAX_READ_CHARS) {
85
+ break;
86
+ }
87
+ shown += 1;
88
+ }
89
+ if (shown === 0) {
90
+ throw new Error(`Line ${offset} of "${path}" alone is longer than one read answers with: read it with a command.`);
91
+ }
92
+ const end = offset - 1 + shown;
93
+ const rest = lines.length - end;
94
+ const position = `Lines ${offset}-${end} of ${lines.length}.${rest === 0 ? "" : ` ${rest} more after these: continue with offset ${end + 1}.`}`;
95
+ return { text: wanted.slice(0, shown).join("\n"), note: noteOf(file, position) };
96
+ };
97
+ export const readTextFile = async (path, range, scopes) => {
98
+ const target = await assertPath(path, scopes, "read");
99
+ const file = decode((await load(target, path)).bytes, path);
100
+ const lines = linesOf(file.text);
101
+ return (range.offset === undefined && range.limit === undefined) || lines.length === 0
102
+ ? wholeRead(file, lines, path)
103
+ : rangeRead(file, lines, range.offset ?? 1, range.limit, path);
104
+ };
105
+ const current = async (target, path, revision) => {
106
+ const { bytes, mode } = await load(target, path);
107
+ const file = decode(bytes, path);
108
+ if (file.revision !== revision) {
109
+ throw new Error(`"${path}" has changed since you read it (you read revision ${revision}, it is now ${file.revision}): read it again and make your change to what is there now.`);
110
+ }
111
+ if (file.encoding === undefined) {
112
+ throw new Error(`"${path}" is not UTF-8 or UTF-16 text, so writing it back would corrupt every character that did not decode. Change it with a command instead.`);
113
+ }
114
+ if ((mode & 0o200) === 0) {
115
+ throw new Error(`"${path}" is read-only, and these tools leave it that way.`);
116
+ }
117
+ return { file, mode };
118
+ };
119
+ const replace = async (target, bytes, mode) => {
120
+ await writeFileAtomic(target, bytes, mode);
121
+ await chmod(target, mode);
122
+ };
123
+ const exists = async (target) => await stat(target).then(() => true, (error) => {
124
+ if (error.code === "ENOENT") {
125
+ return false;
126
+ }
127
+ throw error;
128
+ });
129
+ export const writeTextFile = async (path, content, revision, scopes) => {
18
130
  assertScope(scopes, "write");
19
- const target = assertPath(path, scopes, "write");
131
+ const target = await assertPath(path, scopes, "write");
132
+ if (await exists(target)) {
133
+ if (revision === undefined) {
134
+ throw new Error(`"${path}" already exists. Read it first: replacing a file takes the revision read_file answered with, and creating one takes none.`);
135
+ }
136
+ const { file, mode } = await current(target, path, revision);
137
+ const bytes = encode(content, file);
138
+ await replace(target, bytes, mode);
139
+ const kept = formatOf(file) === "" ? "" : `, saved ${formatOf(file)} as before`;
140
+ return `Overwrote ${target} (${content.length} characters${kept}). Revision ${revisionOf(bytes)}.`;
141
+ }
142
+ if (revision !== undefined) {
143
+ throw new Error(`"${path}" no longer exists: it was moved or deleted after you read it. Call write_file without a revision to create it again.`);
144
+ }
20
145
  await mkdir(dirname(target), { recursive: true });
21
- const existed = await stat(target).then(() => true, () => false);
22
- await writeFile(target, content, "utf8");
23
- return existed ? `Overwrote ${target} (${content.length} characters).` : `Created ${target} (${content.length} characters).`;
146
+ const bytes = encode(content, undefined);
147
+ await writeFileAtomic(target, bytes, 0o666);
148
+ return `Created ${target} (${content.length} characters). Revision ${revisionOf(bytes)}.`;
149
+ };
150
+ export const editTextFile = async (path, edit, scopes) => {
151
+ assertScope(scopes, "write");
152
+ const target = await assertPath(path, scopes, "edit");
153
+ if (!(await exists(target))) {
154
+ throw new Error(`"${path}" does not exist: create it with write_file.`);
155
+ }
156
+ const { file, mode } = await current(target, path, edit.revision);
157
+ const before = edit.oldString.replaceAll("\r\n", "\n");
158
+ const after = edit.newString.replaceAll("\r\n", "\n");
159
+ if (before === after) {
160
+ throw new Error("old_string and new_string are the same, so there is nothing to change.");
161
+ }
162
+ const at = file.text.indexOf(before);
163
+ if (at === -1) {
164
+ throw new Error(`old_string is not in "${path}". It has to match the text read_file shows exactly, whitespace and indentation included.`);
165
+ }
166
+ if (file.text.includes(before, at + 1)) {
167
+ throw new Error(`old_string matches more than one place in "${path}": include more of the lines around it, so that it matches one.`);
168
+ }
169
+ const bytes = encode(`${file.text.slice(0, at)}${after}${file.text.slice(at + before.length)}`, file);
170
+ await replace(target, bytes, mode);
171
+ return `Edited ${target}. Revision ${revisionOf(bytes)}.`;
24
172
  };
25
173
  export const listDirectory = async (path, scopes) => {
26
- const target = assertPath(path, scopes, "list");
174
+ const target = await assertPath(path, scopes, "list");
27
175
  const entries = await readdir(target, { withFileTypes: true });
28
176
  return await Promise.all(entries.map(async (entry) => {
29
177
  const kind = entry.isDirectory() ? "directory" : entry.isFile() ? "file" : "other";
@@ -37,8 +185,8 @@ export const listDirectory = async (path, scopes) => {
37
185
  const trashDir = () => join(agentHome("machine").dir, "trash");
38
186
  export const trashFile = async (path, scopes) => {
39
187
  assertScope(scopes, "write");
40
- const target = assertPath(path, scopes, "trash");
41
- await stat(target);
188
+ const target = await assertPath(path, scopes, "trash", { link: "itself" });
189
+ await lstat(target);
42
190
  const stamp = new Date().toISOString().replace(/[:.]/g, "-");
43
191
  const destination = join(trashDir(), stamp);
44
192
  await mkdir(destination, { recursive: true });