@sightmap/agent-browser 0.9.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fullstory, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # @sightmap/agent-browser
2
+
3
+ Sightmap-aware wrapper around Vercel's [`agent-browser`](https://agent-browser.dev) CLI. Adds four sightmap-aware commands (`snapshot`, `match`, `act`, `network`) that consume your `.sightmap/` corpus; all other commands forward verbatim to `agent-browser` — including the `-p <provider>` flag for hosted Chrome providers.
4
+
5
+ ## Install
6
+
7
+ pnpm add -D @sightmap/agent-browser agent-browser
8
+ agent-browser install # downloads Chrome on first run
9
+
10
+ `agent-browser` is a peer dependency. `sightmap-agent-browser` shells out to it for browser primitives, so it has to be on `PATH` (or installed in the same `node_modules`).
11
+
12
+ ## Usage
13
+
14
+ ```sh
15
+ sightmap-agent-browser [global flags] <command> [args...]
16
+ ```
17
+
18
+ ### Global flags
19
+
20
+ | Flag | Default | Meaning |
21
+ | --- | --- | --- |
22
+ | `-s`, `--session NAME` | `default` | Named agent-browser session |
23
+ | `--sightmap-dir DIR` | `.sightmap` | Path to `.sightmap/` directory |
24
+ | `--json` | `false` | Emit JSON instead of human-readable text |
25
+
26
+ The `.sightmap/` directory is loaded **per invocation** from `--sightmap-dir`, resolved against the current working directory. There is no daemon and no cache — every command re-reads the corpus, so edits to `.sightmap/` are picked up immediately.
27
+
28
+ ## Sightmap-specific commands
29
+
30
+ Four commands consume `.sightmap/` and produce enriched output. Everything else falls through to `agent-browser`.
31
+
32
+ ### `snapshot` — enriched a11y snapshot
33
+
34
+ Captures an ARIA snapshot from the current page and annotates it with the matched sightmap view, view memory, and the sightmap components present on the page.
35
+
36
+ ```text
37
+ $ sightmap-agent-browser -s demo snapshot
38
+ View: Example (/**)
39
+ memory:
40
+ - IANA-reserved domain used for documentation examples
41
+ Components:
42
+ - Heading (view-scoped) — 1 match
43
+
44
+ --- ARIA snapshot ---
45
+ - heading "Example Domain" [level=1, ref=e1]
46
+ - paragraph
47
+ - link "Learn more" [ref=e2]
48
+ ```
49
+
50
+ Pass `--json` for a structured object including an `ariaSnapshot` field carrying the raw a11y text (parity with `@sightmap/mcp`).
51
+
52
+ ### `match URL` — show the matching sightmap view
53
+
54
+ Pure query: resolves a URL (or pathname) against the loaded sightmap and prints the matched view, applicable components, and known requests. No browser is launched.
55
+
56
+ ```text
57
+ $ sightmap-agent-browser match /list/abc123
58
+ View: ListDetailScreen (route /list/*)
59
+ memory: id is opaque; do not parse
60
+ Components:
61
+ - BottomTabBar (global)
62
+ - ListCard (view)
63
+ Requests:
64
+ - GET /api/list/:id → fetchList
65
+ ```
66
+
67
+ ### `act NAME` — resolve a component name to a selector
68
+
69
+ Resolves a sightmap component name to its primary CSS selector (plus any fallbacks). Prints the selector to stdout so it can be piped into another `agent-browser` command. Exits non-zero with a reason for unknown components.
70
+
71
+ ```text
72
+ $ sightmap-agent-browser act SubmitButton
73
+ [data-testid="submit"]
74
+ # fallbacks: button[type="submit"]
75
+ ```
76
+
77
+ Pass `--json` for the full resolution result.
78
+
79
+ ### `network` — annotated network requests
80
+
81
+ Pulls recent network requests from the current session and tags any that match a `requests:` entry in the sightmap, attaching request memory.
82
+
83
+ ```text
84
+ $ sightmap-agent-browser network
85
+ [GET] https://example.test/api/list/abc → 200 [fetchList]
86
+ memory: returns 404 for archived lists; treat as "not found"
87
+ [POST] https://example.test/api/track → 204
88
+ ```
89
+
90
+ ## Passthrough
91
+
92
+ Any command not listed above forwards to `agent-browser` verbatim, with `--session NAME` prepended. This makes `sightmap-agent-browser` a drop-in upgrade for `agent-browser`:
93
+
94
+ sightmap-agent-browser open https://example.com
95
+ sightmap-agent-browser click @e3
96
+ sightmap-agent-browser screenshot page.png
97
+
98
+ You only opt into the sightmap-aware behavior on the four commands above; everything else still works exactly as `agent-browser` documents it.
99
+
100
+ ## Hosted browser providers
101
+
102
+ `agent-browser`'s `-p <provider>` flag flows through unchanged. The provider binds to the session on `open`, and all subsequent sightmap-aware commands inherit it:
103
+
104
+ sightmap-agent-browser -p browserless -s demo open https://example.com
105
+ sightmap-agent-browser -s demo snapshot # runs against the browserless-hosted browser
106
+
107
+ Sightmap layers above whichever provider you pick (Browserless, Browserbase, Kernel, …) — no extra wrapper code needed, no extra cost.
108
+
109
+ ## Sessions
110
+
111
+ `agent-browser` uses **named sessions** to keep a browser context alive across invocations. `sightmap-agent-browser` honors the same flag:
112
+
113
+ ```sh
114
+ sightmap-agent-browser -s checkout open https://shop.test
115
+ sightmap-agent-browser -s checkout snapshot
116
+ sightmap-agent-browser -s checkout network
117
+ sightmap-agent-browser -s checkout close
118
+ ```
119
+
120
+ If you don't pass `-s`/`--session`, the session is `"default"`. Run parallel flows by giving them distinct session names.
121
+
122
+ ## `.sightmap/` resolution
123
+
124
+ Resolved per-invocation, from CWD by default. Override with `--sightmap-dir` when invoking from outside the project root:
125
+
126
+ ```sh
127
+ sightmap-agent-browser --sightmap-dir /path/to/repo/.sightmap snapshot
128
+ ```
129
+
130
+ ## Integration tests
131
+
132
+ Set `SIGHTMAP_AB_INTEGRATION=1` to enable the real-browser smoke test in this package's `test/integration/`. The smoke test runs `open` → `snapshot` → `close` against `https://example.com` and verifies enrichment fires end-to-end.
133
+
134
+ ## See also
135
+
136
+ - [`@sightmap/playwright`](../playwright) — sister wrapper for `@playwright/cli`. Same four enriched commands, different browser backend.
137
+ - [`@sightmap/mcp`](../mcp) — the MCP-server alternative with the curation tool family.
138
+ - [`@sightmap/sightmap`](../sightmap) — the underlying matcher, lint, and validate library.
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,395 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/commands/act.ts
4
+ import {
5
+ loadDirectory,
6
+ resolveSightmapAct
7
+ } from "@sightmap/sightmap";
8
+ async function runActCommand(opts) {
9
+ const sightmap = await loadDirectory(opts.sightmapDir);
10
+ const r = resolveSightmapAct(sightmap, { componentName: opts.componentName });
11
+ if (r.kind === "error") {
12
+ process.stderr.write(r.message + "\n");
13
+ process.exit(1);
14
+ return;
15
+ }
16
+ if (opts.json) {
17
+ process.stdout.write(JSON.stringify(r, null, 2) + "\n");
18
+ return;
19
+ }
20
+ process.stdout.write(`${r.selector}
21
+ `);
22
+ if (r.allSelectors.length > 1) {
23
+ process.stdout.write(`# fallbacks: ${r.allSelectors.slice(1).join(", ")}
24
+ `);
25
+ }
26
+ }
27
+
28
+ // src/commands/match.ts
29
+ import { loadDirectory as loadDirectory2, match } from "@sightmap/sightmap";
30
+ async function runMatchCommand(opts) {
31
+ const sightmap = await loadDirectory2(opts.sightmapDir);
32
+ const result = match(sightmap, { url: opts.url });
33
+ if (opts.json) {
34
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
35
+ return;
36
+ }
37
+ const lines = [];
38
+ if (result.view) {
39
+ lines.push(`View: ${result.view.name} (${result.view.route})`);
40
+ for (const m of result.view.memory ?? []) lines.push(` memory: ${m}`);
41
+ } else {
42
+ lines.push(`View: (no match)`);
43
+ }
44
+ if (result.components.length > 0) {
45
+ lines.push(`Components:`);
46
+ for (const c of result.components) {
47
+ lines.push(` - ${c.name} (${c.scope})`);
48
+ }
49
+ }
50
+ if (result.requests.length > 0) {
51
+ lines.push(`Requests:`);
52
+ for (const r of result.requests) {
53
+ lines.push(` - ${r.method ?? "ANY"} ${r.route} \u2192 ${r.name}`);
54
+ }
55
+ }
56
+ process.stdout.write(lines.join("\n") + "\n");
57
+ }
58
+
59
+ // src/commands/network.ts
60
+ import {
61
+ loadDirectory as loadDirectory3,
62
+ annotateNetworkRequests
63
+ } from "@sightmap/sightmap";
64
+
65
+ // src/exec.ts
66
+ import { spawn } from "child_process";
67
+ async function execAgentBrowser(args, options = {}) {
68
+ const binary = options.binary ?? "agent-browser";
69
+ const timeoutMs = options.timeoutMs ?? 6e4;
70
+ const wantsStdin = options.stdinInput !== void 0;
71
+ return await new Promise((resolve, reject) => {
72
+ const child = spawn(binary, args, {
73
+ cwd: options.cwd ?? process.cwd(),
74
+ env: options.env ?? process.env,
75
+ stdio: [wantsStdin ? "pipe" : "ignore", "pipe", "pipe"]
76
+ });
77
+ const stdoutChunks = [];
78
+ const stderrChunks = [];
79
+ child.stdout.on("data", (c) => stdoutChunks.push(c));
80
+ child.stderr.on("data", (c) => stderrChunks.push(c));
81
+ const killTimer = setTimeout(() => {
82
+ child.kill("SIGTERM");
83
+ }, timeoutMs);
84
+ child.on("error", (err) => {
85
+ clearTimeout(killTimer);
86
+ reject(err);
87
+ });
88
+ child.on("close", (code) => {
89
+ clearTimeout(killTimer);
90
+ resolve({
91
+ exitCode: code ?? -1,
92
+ stdout: Buffer.concat(stdoutChunks).toString("utf8"),
93
+ stderr: Buffer.concat(stderrChunks).toString("utf8")
94
+ });
95
+ });
96
+ if (wantsStdin && child.stdin) {
97
+ child.stdin.write(options.stdinInput);
98
+ child.stdin.end();
99
+ }
100
+ });
101
+ }
102
+ async function streamAgentBrowser(args, options = {}) {
103
+ const binary = options.binary ?? "agent-browser";
104
+ return await new Promise((resolve, reject) => {
105
+ const child = spawn(binary, args, {
106
+ cwd: options.cwd ?? process.cwd(),
107
+ env: options.env ?? process.env,
108
+ stdio: "inherit"
109
+ });
110
+ child.on("error", reject);
111
+ child.on("close", (code) => {
112
+ resolve({ exitCode: code ?? -1 });
113
+ });
114
+ });
115
+ }
116
+
117
+ // src/parse-network.ts
118
+ function parseAgentBrowserNetwork(text) {
119
+ const env = JSON.parse(text);
120
+ if (env.success !== true) {
121
+ throw new Error(
122
+ `agent-browser network --json: ${env.error ?? "unknown error"}`
123
+ );
124
+ }
125
+ const data = env.data ?? [];
126
+ const entries = Array.isArray(data) ? data : Array.isArray(data.requests) ? data.requests : [];
127
+ return entries.map((e) => ({
128
+ method: e.method ?? "",
129
+ url: e.url ?? "",
130
+ status: typeof e.status === "number" ? e.status : 0,
131
+ statusText: e.statusText ?? ""
132
+ }));
133
+ }
134
+
135
+ // src/commands/network.ts
136
+ async function runNetworkCommand(opts) {
137
+ const sightmap = await loadDirectory3(opts.sightmapDir);
138
+ const result = await execAgentBrowser([
139
+ "--session",
140
+ opts.sessionName,
141
+ "network",
142
+ "requests",
143
+ "--json"
144
+ ]);
145
+ if (result.exitCode !== 0) {
146
+ process.stderr.write(result.stderr);
147
+ process.exit(result.exitCode);
148
+ }
149
+ const parsed = parseAgentBrowserNetwork(result.stdout);
150
+ const annotated = annotateNetworkRequests(sightmap, parsed);
151
+ if (opts.json) {
152
+ process.stdout.write(JSON.stringify(annotated, null, 2) + "\n");
153
+ return;
154
+ }
155
+ for (const r of annotated) {
156
+ const tag = r.sightmapName ? ` [${r.sightmapName}]` : "";
157
+ process.stdout.write(`[${r.method}] ${r.url} \u2192 ${r.status}${tag}
158
+ `);
159
+ if (r.sightmapMemory) {
160
+ for (const m of r.sightmapMemory) {
161
+ process.stdout.write(` memory: ${m}
162
+ `);
163
+ }
164
+ }
165
+ }
166
+ }
167
+
168
+ // src/commands/passthrough.ts
169
+ async function runPassthroughCommand(opts) {
170
+ const { exitCode } = await streamAgentBrowser([
171
+ "--session",
172
+ opts.sessionName,
173
+ ...opts.rest
174
+ ]);
175
+ if (exitCode !== 0) process.exit(exitCode);
176
+ }
177
+
178
+ // src/commands/snapshot.ts
179
+ import {
180
+ enrichSnapshot,
181
+ loadDirectory as loadDirectory4,
182
+ match as sightmapMatch
183
+ } from "@sightmap/sightmap";
184
+
185
+ // src/parse-snapshot.ts
186
+ function parseAgentBrowserSnapshot(text) {
187
+ const env = JSON.parse(text);
188
+ if (env.success !== true) {
189
+ throw new Error(
190
+ `agent-browser snapshot --json: ${env.error ?? "unknown error"}`
191
+ );
192
+ }
193
+ const data = env.data ?? {};
194
+ return {
195
+ url: data.origin ?? "",
196
+ ariaText: data.snapshot ?? "",
197
+ refs: data.refs ?? {}
198
+ };
199
+ }
200
+
201
+ // src/in-page-runner.ts
202
+ import {
203
+ buildInPageEvalFunction
204
+ } from "@sightmap/sightmap";
205
+ function parseAgentBrowserEvalEnvelope(stdout) {
206
+ const env = JSON.parse(stdout);
207
+ if (env.success !== true) {
208
+ throw new Error(
209
+ `agent-browser eval --json: ${env.error ?? "unknown error"}`
210
+ );
211
+ }
212
+ const matches = env.data?.result?.matches;
213
+ return Array.isArray(matches) ? matches : [];
214
+ }
215
+ async function runInPageMatcher(components, sessionName, options = {}) {
216
+ if (components.length === 0) return [];
217
+ const js = buildInPageEvalFunction(components);
218
+ const iife = `(${js})()`;
219
+ const result = await execAgentBrowser(
220
+ ["--session", sessionName, "eval", "--stdin", "--json"],
221
+ { ...options, stdinInput: iife }
222
+ );
223
+ if (result.exitCode !== 0) {
224
+ throw new Error(`agent-browser eval failed: ${result.stderr}`);
225
+ }
226
+ return parseAgentBrowserEvalEnvelope(result.stdout);
227
+ }
228
+
229
+ // src/commands/snapshot.ts
230
+ async function runSnapshotCommand(opts) {
231
+ const sightmap = await loadDirectory4(opts.sightmapDir);
232
+ const snapResult = await execAgentBrowser([
233
+ "--session",
234
+ opts.sessionName,
235
+ "snapshot",
236
+ "--json"
237
+ ]);
238
+ if (snapResult.exitCode !== 0) {
239
+ process.stderr.write(snapResult.stderr);
240
+ process.exit(snapResult.exitCode);
241
+ }
242
+ const parsed = parseAgentBrowserSnapshot(snapResult.stdout);
243
+ const matchResult = sightmapMatch(sightmap, { url: parsed.url });
244
+ const allComponents = matchResult.components.map((c) => ({
245
+ name: c.name,
246
+ selector: c.selector
247
+ }));
248
+ const inPage = await runInPageMatcher(allComponents, opts.sessionName);
249
+ const enriched = enrichSnapshot({
250
+ sightmap,
251
+ currentUrl: parsed.url,
252
+ inPageMatches: inPage
253
+ });
254
+ if (opts.json) {
255
+ process.stdout.write(
256
+ JSON.stringify(
257
+ { ...enriched, ariaSnapshot: parsed.ariaText },
258
+ null,
259
+ 2
260
+ ) + "\n"
261
+ );
262
+ } else {
263
+ process.stdout.write(formatHuman(enriched, parsed.ariaText));
264
+ }
265
+ }
266
+ function formatHuman(enriched, ariaText) {
267
+ const lines = [];
268
+ if (enriched.view) {
269
+ lines.push(`View: ${enriched.view.name} (${enriched.view.route})`);
270
+ if (enriched.view.memory.length > 0) {
271
+ lines.push(` memory:`);
272
+ for (const m of enriched.view.memory) lines.push(` - ${m}`);
273
+ }
274
+ } else {
275
+ lines.push(`View: (no match)`);
276
+ }
277
+ if (enriched.components.length > 0) {
278
+ lines.push(`Components:`);
279
+ for (const c of enriched.components) {
280
+ lines.push(
281
+ ` - ${c.name} (${c.scope}) \u2014 ${c.matchCount} match${c.matchCount === 1 ? "" : "es"}`
282
+ );
283
+ for (const m of c.memory) lines.push(` memory: ${m}`);
284
+ }
285
+ }
286
+ lines.push("");
287
+ lines.push("--- ARIA snapshot ---");
288
+ lines.push(ariaText);
289
+ return lines.join("\n");
290
+ }
291
+
292
+ // src/cli.ts
293
+ function requireValue(flag, next) {
294
+ if (next === void 0 || next.startsWith("-")) {
295
+ console.error(
296
+ `${flag}: expected a value, got "${next ?? "(end of args)"}"`
297
+ );
298
+ process.exit(2);
299
+ }
300
+ return next;
301
+ }
302
+ function parseArgs(argv) {
303
+ let session = "default";
304
+ let sightmapDir = ".sightmap";
305
+ let json = false;
306
+ const positional = [];
307
+ for (let i = 0; i < argv.length; i++) {
308
+ const a = argv[i];
309
+ if (a === "-s" || a === "--session") {
310
+ session = requireValue(a, argv[++i]);
311
+ } else if (a === "--sightmap-dir") {
312
+ sightmapDir = requireValue(a, argv[++i]);
313
+ } else if (a === "--json") {
314
+ json = true;
315
+ } else {
316
+ positional.push(a);
317
+ }
318
+ }
319
+ return {
320
+ command: positional[0] ?? "",
321
+ session,
322
+ sightmapDir,
323
+ json,
324
+ rest: positional.slice(1)
325
+ };
326
+ }
327
+ function printHelp() {
328
+ console.log(
329
+ `sightmap-agent-browser \u2014 sightmap-aware wrapper around Vercel's agent-browser CLI
330
+
331
+ Usage:
332
+ sightmap-agent-browser [global flags] <command> [args...]
333
+
334
+ Global flags:
335
+ -s, --session NAME Named agent-browser session (default: "default")
336
+ --sightmap-dir DIR Path to .sightmap/ directory (default: ".sightmap")
337
+ --json Emit JSON instead of human-readable text
338
+
339
+ Sightmap-specific commands:
340
+ snapshot Enriched a11y snapshot with sightmap component names
341
+ match URL Show the matching sightmap view for URL
342
+ act NAME Resolve a sightmap component name to a selector
343
+ network Network requests annotated with sightmap memory
344
+
345
+ All other commands are forwarded to agent-browser verbatim, including
346
+ the -p <provider> flag for hosted browser providers.
347
+ `
348
+ );
349
+ }
350
+ async function main() {
351
+ const argv = process.argv.slice(2);
352
+ if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
353
+ printHelp();
354
+ return;
355
+ }
356
+ const { command, session, sightmapDir, json, rest } = parseArgs(argv);
357
+ switch (command) {
358
+ case "snapshot":
359
+ await runSnapshotCommand({ sessionName: session, sightmapDir, json });
360
+ return;
361
+ case "match": {
362
+ const url = rest[0];
363
+ if (url === void 0) {
364
+ console.error("sightmap-agent-browser match: URL required");
365
+ process.exit(2);
366
+ }
367
+ await runMatchCommand({ url, sightmapDir, json });
368
+ return;
369
+ }
370
+ case "act": {
371
+ const name = rest[0];
372
+ if (name === void 0) {
373
+ console.error("sightmap-agent-browser act: component name required");
374
+ process.exit(2);
375
+ }
376
+ await runActCommand({ componentName: name, sightmapDir, json });
377
+ return;
378
+ }
379
+ case "network":
380
+ await runNetworkCommand({ sessionName: session, sightmapDir, json });
381
+ return;
382
+ default: {
383
+ const passArgs = json ? ["--json", command, ...rest] : [command, ...rest];
384
+ await runPassthroughCommand({
385
+ sessionName: session,
386
+ rest: passArgs.filter((s) => s.length > 0)
387
+ });
388
+ return;
389
+ }
390
+ }
391
+ }
392
+ main().catch((err) => {
393
+ console.error(err instanceof Error ? err.message : String(err));
394
+ process.exit(1);
395
+ });
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@sightmap/agent-browser",
3
+ "version": "0.9.0",
4
+ "description": "Sightmap-aware wrapper around Vercel's agent-browser CLI. Adds sightmap-* commands and enriches snapshot output with component names from .sightmap/.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/sightmap/sightmap-js.git",
9
+ "directory": "packages/agent-browser"
10
+ },
11
+ "homepage": "https://sightmap.org",
12
+ "keywords": [
13
+ "sightmap",
14
+ "agent-browser",
15
+ "cli",
16
+ "agent",
17
+ "browser"
18
+ ],
19
+ "type": "module",
20
+ "bin": {
21
+ "sightmap-agent-browser": "./dist/cli.js"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "devDependencies": {
32
+ "agent-browser": "^0.27.0",
33
+ "@types/node": "^20.19.39",
34
+ "tsup": "^8.5.1",
35
+ "typescript": "~5.7.3",
36
+ "vitest": "^3.0.0"
37
+ },
38
+ "dependencies": {
39
+ "@sightmap/sightmap": "^0.9.0"
40
+ },
41
+ "peerDependencies": {
42
+ "agent-browser": "^0.27.0"
43
+ },
44
+ "peerDependenciesMeta": {
45
+ "agent-browser": {
46
+ "optional": false
47
+ }
48
+ },
49
+ "scripts": {
50
+ "build": "tsup",
51
+ "test": "vitest run",
52
+ "test:watch": "vitest",
53
+ "typecheck": "tsc --noEmit"
54
+ }
55
+ }