@ulpi/browse 0.6.0 → 0.7.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/package.json +1 -1
- package/skill/SKILL.md +3 -2
- package/src/cli.ts +6 -21
- package/src/snapshot.ts +18 -5
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: browse
|
|
3
|
-
version: 2.
|
|
3
|
+
version: 2.5.0
|
|
4
4
|
description: |
|
|
5
5
|
Fast web browsing for AI coding agents via persistent headless Chromium daemon. Navigate to any URL,
|
|
6
6
|
read page content, click elements, fill forms, run JavaScript, take screenshots,
|
|
@@ -260,7 +260,8 @@ browse accessibility Accessibility tree snapshot (ARIA)
|
|
|
260
260
|
### Snapshot (ref-based element selection)
|
|
261
261
|
```
|
|
262
262
|
browse snapshot Full accessibility tree with @refs
|
|
263
|
-
browse snapshot -i Interactive elements only (
|
|
263
|
+
browse snapshot -i Interactive elements only — terse flat list (minimal tokens)
|
|
264
|
+
browse snapshot -i -v Interactive elements — verbose indented tree with props
|
|
264
265
|
browse snapshot -c Compact (no empty structural elements)
|
|
265
266
|
browse snapshot -C Cursor-interactive (detect divs with cursor:pointer/onclick/tabindex)
|
|
266
267
|
browse snapshot -d <N> Limit depth to N levels
|
package/src/cli.ts
CHANGED
|
@@ -20,7 +20,6 @@ const cliFlags = {
|
|
|
20
20
|
contentBoundaries: false,
|
|
21
21
|
allowedDomains: '' as string,
|
|
22
22
|
headed: false,
|
|
23
|
-
runtime: '' as string,
|
|
24
23
|
};
|
|
25
24
|
|
|
26
25
|
const BROWSE_PORT = parseInt(process.env.BROWSE_PORT || '0', 10);
|
|
@@ -253,7 +252,7 @@ async function startServer(): Promise<ServerState> {
|
|
|
253
252
|
: ['bun', 'run', SERVER_SCRIPT];
|
|
254
253
|
const proc = Bun.spawn(spawnCmd, {
|
|
255
254
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
256
|
-
env: { ...process.env, __BROWSE_SERVER_MODE: '1', BROWSE_LOCAL_DIR: LOCAL_DIR, BROWSE_INSTANCE, ...(cliFlags.headed ? { BROWSE_HEADED: '1' } : {})
|
|
255
|
+
env: { ...process.env, __BROWSE_SERVER_MODE: '1', BROWSE_LOCAL_DIR: LOCAL_DIR, BROWSE_INSTANCE, ...(cliFlags.headed ? { BROWSE_HEADED: '1' } : {}) },
|
|
257
256
|
});
|
|
258
257
|
|
|
259
258
|
// Don't hold the CLI open
|
|
@@ -512,7 +511,7 @@ export async function main() {
|
|
|
512
511
|
for (let i = 0; i < a.length; i++) {
|
|
513
512
|
if (!a[i].startsWith('-')) return i;
|
|
514
513
|
// Skip flag values for known value-flags
|
|
515
|
-
if (a[i] === '--session' || a[i] === '--allowed-domains'
|
|
514
|
+
if (a[i] === '--session' || a[i] === '--allowed-domains') i++;
|
|
516
515
|
}
|
|
517
516
|
return a.length;
|
|
518
517
|
}
|
|
@@ -570,25 +569,11 @@ export async function main() {
|
|
|
570
569
|
}
|
|
571
570
|
headed = headed || process.env.BROWSE_HEADED === '1';
|
|
572
571
|
|
|
573
|
-
// Extract --runtime flag (only before command)
|
|
574
|
-
let runtimeName: string | undefined;
|
|
575
|
-
const runtimeIdx = args.indexOf('--runtime');
|
|
576
|
-
if (runtimeIdx !== -1 && runtimeIdx < findCommandIndex(args)) {
|
|
577
|
-
runtimeName = args[runtimeIdx + 1];
|
|
578
|
-
if (!runtimeName || runtimeName.startsWith('-')) {
|
|
579
|
-
console.error('Usage: browse --runtime <name> <command> [args...]');
|
|
580
|
-
process.exit(1);
|
|
581
|
-
}
|
|
582
|
-
args.splice(runtimeIdx, 2);
|
|
583
|
-
}
|
|
584
|
-
runtimeName = runtimeName || process.env.BROWSE_RUNTIME || config.runtime || undefined;
|
|
585
|
-
|
|
586
572
|
// Set global flags for sendCommand()
|
|
587
573
|
cliFlags.json = jsonMode;
|
|
588
574
|
cliFlags.contentBoundaries = contentBoundaries;
|
|
589
575
|
cliFlags.allowedDomains = allowedDomains || '';
|
|
590
576
|
cliFlags.headed = headed;
|
|
591
|
-
cliFlags.runtime = runtimeName || '';
|
|
592
577
|
|
|
593
578
|
// ─── Local commands (no server needed) ─────────────────────
|
|
594
579
|
if (args[0] === 'instances') {
|
|
@@ -620,8 +605,8 @@ Inspection: js <expr> | eval <file> | css <sel> <prop> | attrs <sel>
|
|
|
620
605
|
element-state <sel> | console [--clear] | network [--clear]
|
|
621
606
|
cookies | storage [set <k> <v>] | perf
|
|
622
607
|
value <sel> | count <sel> | clipboard [write <text>]
|
|
623
|
-
Visual: screenshot [path]
|
|
624
|
-
Snapshot: snapshot [-i] [-c] [-C] [-d N] [-s sel]
|
|
608
|
+
Visual: screenshot [path] | pdf [path] | responsive [prefix]
|
|
609
|
+
Snapshot: snapshot [-i] [-v] [-c] [-C] [-d N] [-s sel]
|
|
625
610
|
Find: find role|text|label|placeholder|testid <query> [name]
|
|
626
611
|
Compare: diff <url1> <url2> | screenshot-diff <baseline> [current]
|
|
627
612
|
Multi-step: chain (reads JSON from stdin)
|
|
@@ -645,10 +630,10 @@ Options:
|
|
|
645
630
|
--content-boundaries Wrap page content in nonce-delimited markers
|
|
646
631
|
--allowed-domains <d,d> Block navigation/resources outside allowlist
|
|
647
632
|
--headed Run browser in headed (visible) mode
|
|
648
|
-
--runtime <name> Browser runtime (playwright, rebrowser, lightpanda)
|
|
649
633
|
|
|
650
634
|
Snapshot flags:
|
|
651
|
-
-i Interactive elements only (
|
|
635
|
+
-i Interactive elements only (terse flat list by default)
|
|
636
|
+
-v Verbose — full indented tree with props (use with -i)
|
|
652
637
|
-c Compact — remove empty structural elements
|
|
653
638
|
-C Cursor-interactive — detect divs with cursor:pointer,
|
|
654
639
|
onclick, tabindex, data-action (missed by ARIA tree)
|
package/src/snapshot.ts
CHANGED
|
@@ -30,7 +30,8 @@ const INTERACTIVE_ROLES = new Set([
|
|
|
30
30
|
]);
|
|
31
31
|
|
|
32
32
|
interface SnapshotOptions {
|
|
33
|
-
interactive?: boolean; // -i: only interactive elements
|
|
33
|
+
interactive?: boolean; // -i: only interactive elements (terse flat list by default)
|
|
34
|
+
verbose?: boolean; // -v: full indented ARIA tree with props/children (overrides -i terse default)
|
|
34
35
|
compact?: boolean; // -c: remove empty structural elements
|
|
35
36
|
depth?: number; // -d N: limit tree depth
|
|
36
37
|
selector?: string; // -s SEL: scope to CSS selector
|
|
@@ -72,6 +73,10 @@ export function parseSnapshotArgs(args: string[]): SnapshotOptions {
|
|
|
72
73
|
case '--compact':
|
|
73
74
|
opts.compact = true;
|
|
74
75
|
break;
|
|
76
|
+
case '-v':
|
|
77
|
+
case '--verbose':
|
|
78
|
+
opts.verbose = true;
|
|
79
|
+
break;
|
|
75
80
|
case '-C':
|
|
76
81
|
case '--cursor':
|
|
77
82
|
opts.cursor = true;
|
|
@@ -417,10 +422,18 @@ export async function handleSnapshot(
|
|
|
417
422
|
refMap.set(ref, locator);
|
|
418
423
|
|
|
419
424
|
// Format output line
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
if (
|
|
425
|
+
// -i without -v: terse flat list (no indent, no props, no children)
|
|
426
|
+
const terse = opts.interactive && !opts.verbose;
|
|
427
|
+
let outputLine: string;
|
|
428
|
+
if (terse) {
|
|
429
|
+
outputLine = `@${ref} [${node.role}]`;
|
|
430
|
+
if (node.name) outputLine += ` "${node.name}"`;
|
|
431
|
+
} else {
|
|
432
|
+
outputLine = `${indent}@${ref} [${node.role}]`;
|
|
433
|
+
if (node.name) outputLine += ` "${node.name}"`;
|
|
434
|
+
if (node.props) outputLine += ` ${node.props}`;
|
|
435
|
+
if (node.children) outputLine += `: ${node.children}`;
|
|
436
|
+
}
|
|
424
437
|
|
|
425
438
|
output.push(outputLine);
|
|
426
439
|
}
|