@framers/agentos-ext-browser-automation 0.2.0 → 0.3.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 (143) hide show
  1. package/README.md +91 -0
  2. package/dist/BrowserService.js +9 -45
  3. package/dist/BrowserService.js.map +1 -1
  4. package/dist/attach/AttachController.d.ts +54 -0
  5. package/dist/attach/AttachController.d.ts.map +1 -1
  6. package/dist/attach/AttachController.js +129 -41
  7. package/dist/attach/AttachController.js.map +1 -1
  8. package/dist/attach/backends/jxa.d.ts.map +1 -1
  9. package/dist/attach/backends/jxa.js +35 -62
  10. package/dist/attach/backends/jxa.js.map +1 -1
  11. package/dist/attach/backends/raw-cdp.d.ts +14 -0
  12. package/dist/attach/backends/raw-cdp.d.ts.map +1 -1
  13. package/dist/attach/backends/raw-cdp.js +66 -35
  14. package/dist/attach/backends/raw-cdp.js.map +1 -1
  15. package/dist/attach/daemon/client.d.ts +10 -0
  16. package/dist/attach/daemon/client.d.ts.map +1 -1
  17. package/dist/attach/daemon/client.js +34 -23
  18. package/dist/attach/daemon/client.js.map +1 -1
  19. package/dist/attach/daemon/daemon-lock.js +14 -17
  20. package/dist/attach/daemon/daemon-lock.js.map +1 -1
  21. package/dist/attach/daemon/daemon-main.d.ts +11 -0
  22. package/dist/attach/daemon/daemon-main.d.ts.map +1 -1
  23. package/dist/attach/daemon/daemon-main.js +39 -18
  24. package/dist/attach/daemon/daemon-main.js.map +1 -1
  25. package/dist/attach/daemon/daemon.d.ts.map +1 -1
  26. package/dist/attach/daemon/daemon.js +49 -32
  27. package/dist/attach/daemon/daemon.js.map +1 -1
  28. package/dist/attach/daemon/index.js +7 -25
  29. package/dist/attach/daemon/index.js.map +1 -1
  30. package/dist/attach/daemon/protocol.d.ts +1 -1
  31. package/dist/attach/daemon/protocol.d.ts.map +1 -1
  32. package/dist/attach/daemon/protocol.js +33 -45
  33. package/dist/attach/daemon/protocol.js.map +1 -1
  34. package/dist/attach/daemon/runner.js +1 -4
  35. package/dist/attach/daemon/runner.js.map +1 -1
  36. package/dist/attach/daemon/surface.d.ts +5 -0
  37. package/dist/attach/daemon/surface.d.ts.map +1 -1
  38. package/dist/attach/daemon/surface.js +16 -14
  39. package/dist/attach/daemon/surface.js.map +1 -1
  40. package/dist/attach/devtools-port.js +1 -4
  41. package/dist/attach/devtools-port.js.map +1 -1
  42. package/dist/attach/errors.js +4 -9
  43. package/dist/attach/errors.js.map +1 -1
  44. package/dist/attach/evidence.d.ts +64 -0
  45. package/dist/attach/evidence.d.ts.map +1 -0
  46. package/dist/attach/evidence.js +269 -0
  47. package/dist/attach/evidence.js.map +1 -0
  48. package/dist/attach/lease.js +18 -23
  49. package/dist/attach/lease.js.map +1 -1
  50. package/dist/attach/singleton-lock.js +1 -4
  51. package/dist/attach/singleton-lock.js.map +1 -1
  52. package/dist/attach/state.js +6 -13
  53. package/dist/attach/state.js.map +1 -1
  54. package/dist/attach/tools.d.ts +42 -2
  55. package/dist/attach/tools.d.ts.map +1 -1
  56. package/dist/attach/tools.js +124 -88
  57. package/dist/attach/tools.js.map +1 -1
  58. package/dist/attach/url-policy.js +2 -6
  59. package/dist/attach/url-policy.js.map +1 -1
  60. package/dist/attach.js +7 -23
  61. package/dist/attach.js.map +1 -1
  62. package/dist/captcha/CaptchaSolver.js +4 -7
  63. package/dist/captcha/CaptchaSolver.js.map +1 -1
  64. package/dist/captcha/ICaptchaProvider.js +1 -2
  65. package/dist/captcha/ICaptchaProvider.js.map +1 -1
  66. package/dist/index.d.ts +8 -0
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +56 -75
  69. package/dist/index.js.map +1 -1
  70. package/dist/proxy/IProxyProvider.js +1 -2
  71. package/dist/proxy/IProxyProvider.js.map +1 -1
  72. package/dist/proxy/ProxyManager.js +7 -10
  73. package/dist/proxy/ProxyManager.js.map +1 -1
  74. package/dist/tools/ClickTool.js +17 -20
  75. package/dist/tools/ClickTool.js.map +1 -1
  76. package/dist/tools/EvaluateTool.js +16 -19
  77. package/dist/tools/EvaluateTool.js.map +1 -1
  78. package/dist/tools/ExtractTool.js +23 -26
  79. package/dist/tools/ExtractTool.js.map +1 -1
  80. package/dist/tools/FillTool.js +17 -20
  81. package/dist/tools/FillTool.js.map +1 -1
  82. package/dist/tools/NavigateTool.js +31 -34
  83. package/dist/tools/NavigateTool.js.map +1 -1
  84. package/dist/tools/PageSnapshotTool.js +13 -16
  85. package/dist/tools/PageSnapshotTool.js.map +1 -1
  86. package/dist/tools/ScreenshotTool.js +16 -19
  87. package/dist/tools/ScreenshotTool.js.map +1 -1
  88. package/dist/tools/ScrollTool.js +17 -20
  89. package/dist/tools/ScrollTool.js.map +1 -1
  90. package/dist/tools/SessionTool.js +24 -27
  91. package/dist/tools/SessionTool.js.map +1 -1
  92. package/dist/tools/WaitTool.js +22 -25
  93. package/dist/tools/WaitTool.js.map +1 -1
  94. package/manifest.json +1 -1
  95. package/package.json +5 -4
  96. package/dist/attach/__tests__/AttachController.test.d.ts +0 -2
  97. package/dist/attach/__tests__/AttachController.test.d.ts.map +0 -1
  98. package/dist/attach/__tests__/AttachController.test.js +0 -278
  99. package/dist/attach/__tests__/AttachController.test.js.map +0 -1
  100. package/dist/attach/__tests__/attach-primitives.test.d.ts +0 -2
  101. package/dist/attach/__tests__/attach-primitives.test.d.ts.map +0 -1
  102. package/dist/attach/__tests__/attach-primitives.test.js +0 -158
  103. package/dist/attach/__tests__/attach-primitives.test.js.map +0 -1
  104. package/dist/attach/__tests__/jxa-args.test.d.ts +0 -2
  105. package/dist/attach/__tests__/jxa-args.test.d.ts.map +0 -1
  106. package/dist/attach/__tests__/jxa-args.test.js +0 -37
  107. package/dist/attach/__tests__/jxa-args.test.js.map +0 -1
  108. package/dist/attach/__tests__/pack-registration.test.d.ts +0 -2
  109. package/dist/attach/__tests__/pack-registration.test.d.ts.map +0 -1
  110. package/dist/attach/__tests__/pack-registration.test.js +0 -34
  111. package/dist/attach/__tests__/pack-registration.test.js.map +0 -1
  112. package/dist/attach/__tests__/tools.test.d.ts +0 -2
  113. package/dist/attach/__tests__/tools.test.d.ts.map +0 -1
  114. package/dist/attach/__tests__/tools.test.js +0 -155
  115. package/dist/attach/__tests__/tools.test.js.map +0 -1
  116. package/dist/attach/backends/__tests__/raw-cdp.test.d.ts +0 -2
  117. package/dist/attach/backends/__tests__/raw-cdp.test.d.ts.map +0 -1
  118. package/dist/attach/backends/__tests__/raw-cdp.test.js +0 -133
  119. package/dist/attach/backends/__tests__/raw-cdp.test.js.map +0 -1
  120. package/dist/attach/daemon/__tests__/client.test.d.ts +0 -2
  121. package/dist/attach/daemon/__tests__/client.test.d.ts.map +0 -1
  122. package/dist/attach/daemon/__tests__/client.test.js +0 -58
  123. package/dist/attach/daemon/__tests__/client.test.js.map +0 -1
  124. package/dist/attach/daemon/__tests__/daemon-lock.test.d.ts +0 -2
  125. package/dist/attach/daemon/__tests__/daemon-lock.test.d.ts.map +0 -1
  126. package/dist/attach/daemon/__tests__/daemon-lock.test.js +0 -72
  127. package/dist/attach/daemon/__tests__/daemon-lock.test.js.map +0 -1
  128. package/dist/attach/daemon/__tests__/daemon-loop.integration.test.d.ts +0 -2
  129. package/dist/attach/daemon/__tests__/daemon-loop.integration.test.d.ts.map +0 -1
  130. package/dist/attach/daemon/__tests__/daemon-loop.integration.test.js +0 -102
  131. package/dist/attach/daemon/__tests__/daemon-loop.integration.test.js.map +0 -1
  132. package/dist/attach/daemon/__tests__/harness.d.ts +0 -44
  133. package/dist/attach/daemon/__tests__/harness.d.ts.map +0 -1
  134. package/dist/attach/daemon/__tests__/harness.js +0 -96
  135. package/dist/attach/daemon/__tests__/harness.js.map +0 -1
  136. package/dist/attach/daemon/__tests__/protocol.test.d.ts +0 -2
  137. package/dist/attach/daemon/__tests__/protocol.test.d.ts.map +0 -1
  138. package/dist/attach/daemon/__tests__/protocol.test.js +0 -71
  139. package/dist/attach/daemon/__tests__/protocol.test.js.map +0 -1
  140. package/dist/attach/daemon/__tests__/runner.test.d.ts +0 -2
  141. package/dist/attach/daemon/__tests__/runner.test.d.ts.map +0 -1
  142. package/dist/attach/daemon/__tests__/runner.test.js +0 -67
  143. package/dist/attach/daemon/__tests__/runner.test.js.map +0 -1
@@ -0,0 +1,269 @@
1
+ /**
2
+ * @fileoverview Where an attach session's screenshots are written: one
3
+ * evidence directory, and the checks that keep a write inside it.
4
+ *
5
+ * A screenshot's path comes from a tool argument, so it must not reach the
6
+ * rest of the disk or replace a file. It is read against the evidence
7
+ * directory, refused when it leaves it or passes through a link, and written
8
+ * to a new file only.
9
+ *
10
+ * The directory is private to this user, by the rules the media packs keep
11
+ * for the files they save (`imageFiles.ts`, `audioFiles.ts`). The evidence
12
+ * directory and each directory in it on the way to the file belong to this
13
+ * user and are writable by no one else. Each directory above the evidence
14
+ * directory belongs to this user or root and is writable by no one else
15
+ * unless it is sticky, as /tmp is. A user who could rename an entry on that
16
+ * path could swap a directory for a link between the checks and the write,
17
+ * and Node has no `openat` to create a file in a checked directory. On
18
+ * Windows, where Node reads no ACLs, only the directories' kind is checked.
19
+ *
20
+ * A page takes seconds to capture, so the directories are checked twice:
21
+ * before the capture, so that nothing is asked of the browser for a path
22
+ * that will be refused, and again around the creation of the file, before
23
+ * the image is written through its handle.
24
+ *
25
+ * @module browser-automation/attach/evidence
26
+ */
27
+ import { constants as fsConstants } from 'node:fs';
28
+ import { access, lstat, mkdir, open, realpath, unlink } from 'node:fs/promises';
29
+ import { homedir } from 'node:os';
30
+ import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
31
+ import { AttachError } from './errors.js';
32
+ /** The evidence directory when none is configured. */
33
+ export const DEFAULT_EVIDENCE_DIR = join(homedir(), '.wunderland', 'attach-evidence');
34
+ const blocked = (message) => new AttachError('POLICY_BLOCKED', message);
35
+ /** A mode's permission bits as four octal digits. */
36
+ const octal = (mode) => (mode & 4095n).toString(8).padStart(4, '0');
37
+ /**
38
+ * The path inside `root` that `filePath` names when read against it, or
39
+ * `undefined` when it names `root` itself or a place outside it.
40
+ */
41
+ function insideOf(root, filePath) {
42
+ const inside = relative(root, resolve(root, filePath));
43
+ return inside === '' || inside === '..' || inside.startsWith(`..${sep}`) || isAbsolute(inside) ? undefined : inside;
44
+ }
45
+ /**
46
+ * Refuses, by the text of the path alone, a path that names no file, and a
47
+ * relative path that leaves the evidence directory. A relative path reads the
48
+ * same against the directory however the directory is named, so it is settled
49
+ * here, before the disk is touched. An absolute path is settled by
50
+ * {@link nameInside}, once the directory's real path is known.
51
+ *
52
+ * @throws POLICY_BLOCKED
53
+ */
54
+ function checkName(filePath, configured) {
55
+ if (typeof filePath !== 'string' ||
56
+ !filePath.trim() ||
57
+ filePath.includes('\0') ||
58
+ filePath.endsWith('/') ||
59
+ filePath.endsWith(sep)) {
60
+ throw blocked('screenshot path must name a file inside the evidence directory');
61
+ }
62
+ if (!isAbsolute(filePath) && insideOf(configured, filePath) === undefined) {
63
+ throw blocked(`screenshot path must stay inside the evidence directory (${configured})`);
64
+ }
65
+ }
66
+ /**
67
+ * The path inside the evidence directory that `filePath` names. An absolute
68
+ * path may name the directory by its real path (`root`), as a result of
69
+ * {@link prepareEvidenceFile} does, or as it is configured.
70
+ *
71
+ * @throws POLICY_BLOCKED when the path is outside the directory.
72
+ */
73
+ function nameInside(filePath, configured, root) {
74
+ const inside = insideOf(root, filePath) ?? insideOf(configured, filePath);
75
+ if (inside === undefined) {
76
+ throw blocked(`screenshot path must stay inside the evidence directory (${root})`);
77
+ }
78
+ return inside;
79
+ }
80
+ /**
81
+ * `dir` as a directory private to this user: a directory, not a link, that
82
+ * this user owns and that neither its group nor others can write. Where the
83
+ * platform has no user ids (Windows) only the kind is checked.
84
+ *
85
+ * @throws POLICY_BLOCKED when it is anything else.
86
+ */
87
+ async function privateDirectory(dir) {
88
+ const stat = await lstat(dir, { bigint: true });
89
+ if (!stat.isDirectory()) {
90
+ throw blocked(`screenshot path passes through ${dir}, which is not a directory (a link is refused)`);
91
+ }
92
+ if (typeof process.getuid === 'function' && (stat.uid !== BigInt(process.getuid()) || (stat.mode & 18n) !== 0n)) {
93
+ throw blocked(`${dir} must belong to this user and be writable by no one else (owner uid ${stat.uid}, mode ${octal(stat.mode)}): chmod 700 it, or set another evidence directory`);
94
+ }
95
+ return { path: dir, dev: stat.dev, ino: stat.ino };
96
+ }
97
+ /**
98
+ * Why another user could change a directory above `dir`, a real path, or
99
+ * `undefined` when none can: each directory above it must belong to this
100
+ * user or root and be writable by no one else, unless it is sticky, where
101
+ * only an entry's owner can rename it. Where the platform has no user ids
102
+ * (Windows) nothing is checked.
103
+ */
104
+ async function changeableParent(dir) {
105
+ if (typeof process.getuid !== 'function')
106
+ return undefined;
107
+ const uid = BigInt(process.getuid());
108
+ for (let parent = dirname(dir);; parent = dirname(parent)) {
109
+ const stat = await lstat(parent, { bigint: true });
110
+ if (!stat.isDirectory())
111
+ return `${parent}, above it, is not a directory`;
112
+ if (stat.uid !== uid && stat.uid !== 0n) {
113
+ return `${parent}, above it, belongs to uid ${stat.uid} (mode ${octal(stat.mode)})`;
114
+ }
115
+ if ((stat.mode & 18n) !== 0n && (stat.mode & 512n) === 0n) {
116
+ return `${parent}, above it, can be written by others and is not sticky (owner uid ${stat.uid}, mode ${octal(stat.mode)})`;
117
+ }
118
+ if (dirname(parent) === parent)
119
+ return undefined;
120
+ }
121
+ }
122
+ /** Whether each checked directory is still that directory: the same device and inode, and not a link. */
123
+ async function unchanged(directories) {
124
+ for (const checked of directories) {
125
+ const now = await lstat(checked.path, { bigint: true }).catch(() => undefined);
126
+ if (!now?.isDirectory() || now.dev !== checked.dev || now.ino !== checked.ino)
127
+ return false;
128
+ }
129
+ return true;
130
+ }
131
+ /**
132
+ * The path a screenshot at `filePath` would be written to, for a dry run:
133
+ * the same reading of the path as {@link prepareEvidenceFile}, with nothing
134
+ * made on the disk. The evidence directory is named by its real path when it
135
+ * exists, as a written screenshot's path is.
136
+ *
137
+ * @param evidenceDir - The configured evidence directory, or `undefined` for the default.
138
+ * @param filePath - The path asked for, relative to the directory or absolute inside it.
139
+ * @throws POLICY_BLOCKED when the path names no file or leaves the directory.
140
+ */
141
+ export async function plannedEvidencePath(evidenceDir, filePath) {
142
+ const configured = resolve(evidenceDir ?? DEFAULT_EVIDENCE_DIR);
143
+ checkName(filePath, configured);
144
+ const root = await realpath(configured).catch(() => configured);
145
+ return join(root, nameInside(filePath, configured, root));
146
+ }
147
+ /**
148
+ * Prepares the file a screenshot is written to, before the page is captured.
149
+ * The evidence directory is made when missing (mode 0700) and read by its
150
+ * real path, so a link swapped in for it later moves nothing. Each directory
151
+ * from it to the file is made (mode 0700) or checked: a directory, not a
152
+ * link, private to this user, with no directory above the evidence directory
153
+ * that another user can change. A file already at the path is refused.
154
+ *
155
+ * @param evidenceDir - The configured evidence directory, or `undefined` for the default.
156
+ * @param filePath - The path asked for, relative to the directory or absolute inside it.
157
+ * @throws POLICY_BLOCKED for a path that names no file, leaves the directory,
158
+ * passes through a link or a file, or names something that exists, and for
159
+ * a directory that is not private to this user.
160
+ * @throws UNKNOWN when the directory cannot take a new file (its mode, or a
161
+ * file system mounted read-only).
162
+ */
163
+ export async function prepareEvidenceFile(evidenceDir, filePath) {
164
+ const configured = resolve(evidenceDir ?? DEFAULT_EVIDENCE_DIR);
165
+ checkName(filePath, configured);
166
+ await mkdir(configured, { recursive: true, mode: 0o700 });
167
+ const root = await realpath(configured);
168
+ const target = join(root, nameInside(filePath, configured, root));
169
+ const directories = [await privateDirectory(root)];
170
+ const changeable = await changeableParent(root);
171
+ if (changeable) {
172
+ throw blocked(`the evidence directory ${root} cannot be used: ${changeable}. Set one under directories that no other user can change`);
173
+ }
174
+ let dir = root;
175
+ for (const part of relative(root, dirname(target)).split(sep).filter(Boolean)) {
176
+ dir = join(dir, part);
177
+ await mkdir(dir, { mode: 0o700 }).catch((err) => {
178
+ // Something is there already: the check below says whether it will do.
179
+ if (err.code !== 'EEXIST')
180
+ throw err;
181
+ });
182
+ directories.push(await privateDirectory(dir));
183
+ }
184
+ if (await lstat(target).catch(() => undefined)) {
185
+ throw blocked(`a file is already at ${target}: a screenshot never replaces one`);
186
+ }
187
+ // A directory this user owns can still refuse a new file: asked now, not
188
+ // after the page is captured.
189
+ await access(dir, fsConstants.W_OK | fsConstants.X_OK).catch((err) => {
190
+ throw new AttachError('UNKNOWN', `${dir} cannot take a new file (${err.code ?? err.message})`);
191
+ });
192
+ return { target, directories };
193
+ }
194
+ /**
195
+ * Whether the opened file, by its `stat`, is the one at the prepared path,
196
+ * with no other name, in the directories as they were checked.
197
+ */
198
+ async function inPlace(prepared, file) {
199
+ const named = await lstat(prepared.target, { bigint: true }).catch(() => undefined);
200
+ return (file.isFile() &&
201
+ named !== undefined &&
202
+ named.nlink === 1n &&
203
+ named.dev === file.dev &&
204
+ named.ino === file.ino &&
205
+ (await unchanged(prepared.directories)));
206
+ }
207
+ /**
208
+ * Removes what a failed write left. The bytes go through the handle, when it
209
+ * is still open (after a failed close it is not). The file itself goes only
210
+ * when its path can still be shown to reach it: nothing is removed by path
211
+ * alone, since by now the path may name another file.
212
+ */
213
+ async function discard(prepared, handle, file) {
214
+ await handle.truncate(0).catch(() => { });
215
+ if (await inPlace(prepared, file))
216
+ await unlink(prepared.target).catch(() => { });
217
+ }
218
+ /**
219
+ * Creates the prepared file and writes `bytes` to it.
220
+ *
221
+ * The directories are checked to be the ones prepared, the file is created
222
+ * with flag `wx` (it never replaces a file, and a link at its name is not
223
+ * followed), and with the file open the directories are checked again and the
224
+ * file is checked to be the one at its path, with no other name. Only then
225
+ * are the bytes written, through the handle. Node has no `openat`, so this is
226
+ * the order that keeps an image out of a directory swapped in while the page
227
+ * was captured: a file created in the wrong place stays empty.
228
+ *
229
+ * A write that fails leaves no partial image: the file is emptied through
230
+ * its handle, and removed when it is still the file at its path. A close
231
+ * that reports the write failed is an error of the call too, and the file is
232
+ * removed by the same rule.
233
+ *
234
+ * @throws POLICY_BLOCKED when a file is already there or a directory changed.
235
+ */
236
+ export async function writeEvidenceFile(prepared, bytes) {
237
+ const changed = () => blocked('the evidence directory changed while the page was captured; no image was written');
238
+ if (!(await unchanged(prepared.directories)))
239
+ throw changed();
240
+ let handle;
241
+ try {
242
+ handle = await open(prepared.target, 'wx', 0o600);
243
+ }
244
+ catch (err) {
245
+ throw err.code === 'EEXIST'
246
+ ? blocked(`a file is already at ${prepared.target}: a screenshot never replaces one`)
247
+ : err;
248
+ }
249
+ try {
250
+ const file = await handle.stat({ bigint: true });
251
+ if (!(await inPlace(prepared, file)))
252
+ throw changed();
253
+ try {
254
+ await handle.writeFile(bytes);
255
+ // Closed here, and its error kept: a file system may report a failed
256
+ // write only when the file is closed (NFS, a quota).
257
+ await handle.close();
258
+ }
259
+ catch (err) {
260
+ await discard(prepared, handle, file);
261
+ throw err;
262
+ }
263
+ }
264
+ finally {
265
+ // After a close above this does nothing.
266
+ await handle.close().catch(() => { });
267
+ }
268
+ }
269
+ //# sourceMappingURL=evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/attach/evidence.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.acquireLease = acquireLease;
4
- exports.requireLease = requireLease;
5
- exports.releaseLease = releaseLease;
6
1
  /**
7
2
  * @fileoverview Cross-process attach lease — exactly ONE session may drive the
8
3
  * user's browser at a time.
@@ -16,10 +11,10 @@ exports.releaseLease = releaseLease;
16
11
  *
17
12
  * @module browser-automation/attach/lease
18
13
  */
19
- const node_crypto_1 = require("node:crypto");
20
- const node_fs_1 = require("node:fs");
21
- const node_path_1 = require("node:path");
22
- const errors_js_1 = require("./errors.js");
14
+ import { randomBytes } from 'node:crypto';
15
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
16
+ import { dirname } from 'node:path';
17
+ import { AttachError } from './errors.js';
23
18
  const DEFAULT_TTL_MS = 10 * 60 * 1000;
24
19
  function defaultIsPidAlive(pid) {
25
20
  try {
@@ -32,7 +27,7 @@ function defaultIsPidAlive(pid) {
32
27
  }
33
28
  function readLease(file) {
34
29
  try {
35
- return JSON.parse((0, node_fs_1.readFileSync)(file, 'utf8'));
30
+ return JSON.parse(readFileSync(file, 'utf8'));
36
31
  }
37
32
  catch {
38
33
  return undefined;
@@ -44,34 +39,34 @@ function readLease(file) {
44
39
  * @returns The acquired lease (persist the nonce; ops require it).
45
40
  * @throws {AttachError} `LEASE_DENIED` when a live, unexpired lease exists.
46
41
  */
47
- function acquireLease(opts) {
42
+ export function acquireLease(opts) {
48
43
  const now = opts.now ?? Date.now;
49
44
  const alive = opts.isPidAlive ?? defaultIsPidAlive;
50
- const existing = (0, node_fs_1.existsSync)(opts.file) ? readLease(opts.file) : undefined;
45
+ const existing = existsSync(opts.file) ? readLease(opts.file) : undefined;
51
46
  if (existing) {
52
47
  const fresh = existing.expiresAt > now();
53
48
  if (fresh && alive(existing.pid)) {
54
- throw new errors_js_1.AttachError('LEASE_DENIED', `attach lease held by pid ${existing.pid} until ${new Date(existing.expiresAt).toISOString()}`);
49
+ throw new AttachError('LEASE_DENIED', `attach lease held by pid ${existing.pid} until ${new Date(existing.expiresAt).toISOString()}`);
55
50
  }
56
51
  }
57
52
  const lease = {
58
53
  pid: opts.pid ?? process.pid,
59
- nonce: (0, node_crypto_1.randomBytes)(16).toString('hex'),
54
+ nonce: randomBytes(16).toString('hex'),
60
55
  acquiredAt: now(),
61
56
  expiresAt: now() + (opts.ttlMs ?? DEFAULT_TTL_MS),
62
57
  };
63
- (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(opts.file), { recursive: true });
64
- (0, node_fs_1.writeFileSync)(opts.file, JSON.stringify(lease));
58
+ mkdirSync(dirname(opts.file), { recursive: true });
59
+ writeFileSync(opts.file, JSON.stringify(lease));
65
60
  return lease;
66
61
  }
67
62
  /**
68
63
  * Assert `nonce` matches the current lease.
69
64
  * @throws {AttachError} `LEASE_DENIED` on missing lease or nonce mismatch.
70
65
  */
71
- function requireLease(file, nonce) {
72
- const lease = (0, node_fs_1.existsSync)(file) ? readLease(file) : undefined;
66
+ export function requireLease(file, nonce) {
67
+ const lease = existsSync(file) ? readLease(file) : undefined;
73
68
  if (!lease || lease.nonce !== nonce) {
74
- throw new errors_js_1.AttachError('LEASE_DENIED', 'operation presented a stale or unknown lease nonce');
69
+ throw new AttachError('LEASE_DENIED', 'operation presented a stale or unknown lease nonce');
75
70
  }
76
71
  return lease;
77
72
  }
@@ -80,13 +75,13 @@ function requireLease(file, nonce) {
80
75
  * missing lease is a no-op.
81
76
  * @throws {AttachError} `LEASE_DENIED` when the nonce does not match.
82
77
  */
83
- function releaseLease(file, nonce) {
84
- const lease = (0, node_fs_1.existsSync)(file) ? readLease(file) : undefined;
78
+ export function releaseLease(file, nonce) {
79
+ const lease = existsSync(file) ? readLease(file) : undefined;
85
80
  if (!lease)
86
81
  return;
87
82
  if (lease.nonce !== nonce) {
88
- throw new errors_js_1.AttachError('LEASE_DENIED', 'refusing to release a lease held by another session');
83
+ throw new AttachError('LEASE_DENIED', 'refusing to release a lease held by another session');
89
84
  }
90
- (0, node_fs_1.unlinkSync)(file);
85
+ unlinkSync(file);
91
86
  }
92
87
  //# sourceMappingURL=lease.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lease.js","sourceRoot":"","sources":["../../src/attach/lease.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lease.js","sourceRoot":"","sources":["../../src/attach/lease.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * @fileoverview Resolve the running Chrome's PID from its `SingletonLock`.
4
3
  *
@@ -11,8 +10,6 @@
11
10
  *
12
11
  * @module browser-automation/attach/singleton-lock
13
12
  */
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.pidFromSingletonLock = pidFromSingletonLock;
16
13
  /**
17
14
  * Extract the owning PID from a `SingletonLock` symlink target.
18
15
  *
@@ -20,7 +17,7 @@ exports.pidFromSingletonLock = pidFromSingletonLock;
20
17
  * @returns The PID (e.g. `666`).
21
18
  * @throws {Error} When the target does not end in `-<digits>`.
22
19
  */
23
- function pidFromSingletonLock(symlinkTarget) {
20
+ export function pidFromSingletonLock(symlinkTarget) {
24
21
  const m = /-(\d+)$/.exec(String(symlinkTarget).trim());
25
22
  if (!m) {
26
23
  throw new Error(`SingletonLock target malformed (expected "<host>-<pid>"): "${symlinkTarget}"`);
@@ -1 +1 @@
1
- {"version":3,"file":"singleton-lock.js","sourceRoot":"","sources":["../../src/attach/singleton-lock.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AASH,oDAMC;AAbD;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAAC,aAAqB;IACxD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,8DAA8D,aAAa,GAAG,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"singleton-lock.js","sourceRoot":"","sources":["../../src/attach/singleton-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB;IACxD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,8DAA8D,aAAa,GAAG,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC"}
@@ -1,7 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AttachStateMachine = void 0;
4
- exports.withDeadline = withDeadline;
5
1
  /**
6
2
  * @fileoverview Attach-session state machine + operation deadlines.
7
3
  *
@@ -13,7 +9,7 @@ exports.withDeadline = withDeadline;
13
9
  *
14
10
  * @module browser-automation/attach/state
15
11
  */
16
- const errors_js_1 = require("./errors.js");
12
+ import { AttachError } from './errors.js';
17
13
  const LEGAL = Object.freeze({
18
14
  disconnected: ['connecting'],
19
15
  connecting: ['ready', 'failed', 'disconnected'],
@@ -29,10 +25,8 @@ const LEGAL = Object.freeze({
29
25
  * `reading`, a failure lands in `failed` and the ONLY way forward is an
30
26
  * explicit `disconnected` reset by the owner — never a silent retry.
31
27
  */
32
- class AttachStateMachine {
33
- constructor() {
34
- this.current = 'disconnected';
35
- }
28
+ export class AttachStateMachine {
29
+ current = 'disconnected';
36
30
  /** The current state. */
37
31
  get state() {
38
32
  return this.current;
@@ -43,7 +37,7 @@ class AttachStateMachine {
43
37
  */
44
38
  to(next) {
45
39
  if (!LEGAL[this.current].includes(next)) {
46
- throw new errors_js_1.AttachError('UNKNOWN', `illegal attach-state transition ${this.current} → ${next}`);
40
+ throw new AttachError('UNKNOWN', `illegal attach-state transition ${this.current} → ${next}`);
47
41
  }
48
42
  this.current = next;
49
43
  return this.current;
@@ -53,7 +47,6 @@ class AttachStateMachine {
53
47
  return this.current === 'connecting' || this.current === 'navigating' || this.current === 'reading';
54
48
  }
55
49
  }
56
- exports.AttachStateMachine = AttachStateMachine;
57
50
  /**
58
51
  * Bound a transport promise with a hard deadline.
59
52
  *
@@ -62,10 +55,10 @@ exports.AttachStateMachine = AttachStateMachine;
62
55
  * @param label Operation label for the failure message.
63
56
  * @throws {AttachError} `NAV_TIMEOUT` when the deadline expires first.
64
57
  */
65
- async function withDeadline(p, ms, label) {
58
+ export async function withDeadline(p, ms, label) {
66
59
  let timer;
67
60
  const gate = new Promise((_, reject) => {
68
- timer = setTimeout(() => reject(new errors_js_1.AttachError('NAV_TIMEOUT', `${label} exceeded ${ms}ms deadline`)), ms);
61
+ timer = setTimeout(() => reject(new AttachError('NAV_TIMEOUT', `${label} exceeded ${ms}ms deadline`)), ms);
69
62
  });
70
63
  try {
71
64
  return await Promise.race([p, gate]);
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/attach/state.ts"],"names":[],"mappings":";;;AAwEA,oCAUC;AAlFD;;;;;;;;;;GAUG;AACH,2CAA0C;AAW1C,MAAM,KAAK,GAA0D,MAAM,CAAC,MAAM,CAAC;IACjF,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC;IAC/C,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,CAAC;IAC1D,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC/B,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC5B,MAAM,EAAE,CAAC,cAAc,CAAC;CACzB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAa,kBAAkB;IAA/B;QACU,YAAO,GAAgB,cAAc,CAAC;IAuBhD,CAAC;IArBC,yBAAyB;IACzB,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,EAAE,CAAC,IAAiB;QAClB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,uBAAW,CAAC,SAAS,EAAE,mCAAmC,IAAI,CAAC,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC;QAChG,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,kEAAkE;IAClE,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC;IACtG,CAAC;CACF;AAxBD,gDAwBC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,YAAY,CAAI,CAAa,EAAE,EAAU,EAAE,KAAa;IAC5E,IAAI,KAAgD,CAAC;IACrD,MAAM,IAAI,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAC5C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,uBAAW,CAAC,aAAa,EAAE,GAAG,KAAK,aAAa,EAAE,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7G,CAAC,CAAC,CAAC;IACH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/attach/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAW1C,MAAM,KAAK,GAA0D,MAAM,CAAC,MAAM,CAAC;IACjF,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC;IAC/C,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,CAAC;IAC1D,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC/B,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC5B,MAAM,EAAE,CAAC,cAAc,CAAC;CACzB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,OAAO,kBAAkB;IACrB,OAAO,GAAgB,cAAc,CAAC;IAE9C,yBAAyB;IACzB,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,EAAE,CAAC,IAAiB;QAClB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,WAAW,CAAC,SAAS,EAAE,mCAAmC,IAAI,CAAC,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC;QAChG,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,kEAAkE;IAClE,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC;IACtG,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,CAAa,EAAE,EAAU,EAAE,KAAa;IAC5E,IAAI,KAAgD,CAAC;IACrD,MAAM,IAAI,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAC5C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,aAAa,EAAE,GAAG,KAAK,aAAa,EAAE,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7G,CAAC,CAAC,CAAC;IACH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;AACH,CAAC"}
@@ -138,6 +138,46 @@ export declare class AttachReadTool {
138
138
  data?: undefined;
139
139
  }>;
140
140
  }
141
+ /** `browser_attach_screenshot` — PNG evidence capture of the agent tab (CDP only). */
142
+ export declare class AttachScreenshotTool {
143
+ private controller;
144
+ readonly id = "browser_attach_screenshot";
145
+ readonly name = "browser_attach_screenshot";
146
+ readonly displayName = "Attach: screenshot";
147
+ readonly description = "Capture a PNG screenshot of the agent tab to a new file in the evidence directory \u2014 visual evidence for a research report. The result gives the path written. Requires the CDP transport (the AppleScript/JXA transport has no pixel access and refuses with UNSUPPORTED_OP). Never navigates or mutates the page; it writes one file, and never replaces one.";
148
+ readonly category = "browser";
149
+ readonly version = "0.1.0";
150
+ readonly hasSideEffects = true;
151
+ readonly inputSchema: {
152
+ type: "object";
153
+ properties: {
154
+ path: {
155
+ type: string;
156
+ description: string;
157
+ };
158
+ fullPage: {
159
+ type: string;
160
+ description: string;
161
+ };
162
+ };
163
+ required: string[];
164
+ };
165
+ constructor(controller: AttachSurface);
166
+ execute(args: {
167
+ path: string;
168
+ fullPage?: boolean;
169
+ }): Promise<{
170
+ success: boolean;
171
+ data: any;
172
+ error?: undefined;
173
+ code?: undefined;
174
+ } | {
175
+ success: boolean;
176
+ error: string;
177
+ code: import("./errors.js").AttachErrorCode;
178
+ data?: undefined;
179
+ }>;
180
+ }
141
181
  /** `browser_attach_release` — park + release the lease (no browser teardown). */
142
182
  export declare class AttachReleaseTool {
143
183
  private controller;
@@ -202,7 +242,7 @@ export declare class AttachControlTool {
202
242
  }>;
203
243
  }
204
244
  /** Instantiate the full attach tool set sharing one controller. */
205
- export declare function createAttachTools(controller: AttachSurface): (AttachStatusTool | AttachClaimTool | AttachGotoTool | AttachReadTool | AttachReleaseTool | AttachControlTool)[];
245
+ export declare function createAttachTools(controller: AttachSurface): (AttachStatusTool | AttachClaimTool | AttachGotoTool | AttachReadTool | AttachScreenshotTool | AttachReleaseTool | AttachControlTool)[];
206
246
  /** All attach tool ids (for registry/policy classification). */
207
- export declare const ATTACH_TOOL_IDS: readonly ["browser_attach_status", "browser_attach_claim", "browser_attach_goto", "browser_attach_read", "browser_attach_release", "browser_attach_control"];
247
+ export declare const ATTACH_TOOL_IDS: readonly ["browser_attach_status", "browser_attach_claim", "browser_attach_goto", "browser_attach_read", "browser_attach_screenshot", "browser_attach_release", "browser_attach_control"];
208
248
  //# sourceMappingURL=tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/attach/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/attach/tools.ts"],"names":[],"mappings":"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"}