@antaif3ng/til-work 0.3.0 → 0.4.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.
@@ -1,58 +1,79 @@
1
1
  /**
2
- * Browser automation tool using Playwright (optional dependency).
3
- * Provides navigate, screenshot, click, type, evaluate, get_text, scroll, wait.
4
- * Playwright must be installed separately: `npm install playwright`
2
+ * Browser automation tool powered by agent-browser (Rust CLI).
3
+ * Uses the snapshot-ref workflow: snapshot to get accessible elements with refs,
4
+ * then interact using refs like @e1, @e2.
5
+ * Agent-browser auto-discovers system Chrome — no extra browser download needed.
5
6
  */
6
- let playwrightMod = null;
7
- let browserInstance = null;
8
- let pageInstance = null;
9
- async function getPlaywright() {
10
- if (playwrightMod)
11
- return playwrightMod;
12
- try {
13
- // Dynamic import — playwright is an optional peer dependency
14
- playwrightMod = await Function('return import("playwright")')();
15
- return playwrightMod;
7
+ import { execFile } from "node:child_process";
8
+ import { readFile, unlink } from "node:fs/promises";
9
+ import { join } from "node:path";
10
+ import { tmpdir } from "node:os";
11
+ import { existsSync } from "node:fs";
12
+ let resolvedBin = null;
13
+ let headedMode = true;
14
+ let browserUsed = false;
15
+ function findAgentBrowser() {
16
+ if (resolvedBin)
17
+ return resolvedBin;
18
+ const localBin = join(process.cwd(), "node_modules", ".bin", "agent-browser");
19
+ if (existsSync(localBin)) {
20
+ resolvedBin = localBin;
21
+ return resolvedBin;
16
22
  }
17
- catch {
18
- throw new Error("Playwright is not installed. Install it with:\n" +
19
- " npm install playwright\n" +
20
- " npx playwright install chromium");
23
+ resolvedBin = "agent-browser";
24
+ return resolvedBin;
25
+ }
26
+ function buildArgs(args) {
27
+ if (headedMode && !process.env.AGENT_BROWSER_HEADED) {
28
+ return ["--headed", ...args];
21
29
  }
30
+ return args;
22
31
  }
23
- async function getPage() {
24
- if (pageInstance)
25
- return pageInstance;
26
- const pw = await getPlaywright();
27
- const chromium = pw.chromium ?? pw.default?.chromium;
28
- if (!chromium)
29
- throw new Error("Cannot find chromium launcher in playwright module");
30
- browserInstance = await chromium.launch({ headless: false });
31
- const context = await browserInstance.newContext({
32
- viewport: { width: 1280, height: 720 },
32
+ function runAgentBrowser(args, signal, timeoutMs = 30000) {
33
+ const bin = findAgentBrowser();
34
+ const fullArgs = buildArgs(args);
35
+ return new Promise((resolve, reject) => {
36
+ const child = execFile(bin, fullArgs, { timeout: timeoutMs, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
37
+ if (signal?.aborted) {
38
+ reject(new Error("Operation aborted"));
39
+ return;
40
+ }
41
+ if (err) {
42
+ const msg = stderr?.trim() || stdout?.trim() || err.message;
43
+ reject(new Error(`agent-browser error: ${msg}`));
44
+ return;
45
+ }
46
+ resolve({ stdout: stdout ?? "", stderr: stderr ?? "" });
47
+ });
48
+ if (signal) {
49
+ const onAbort = () => child.kill();
50
+ if (signal.aborted)
51
+ child.kill();
52
+ else
53
+ signal.addEventListener("abort", onAbort, { once: true });
54
+ }
33
55
  });
34
- pageInstance = await context.newPage();
35
- return pageInstance;
36
56
  }
37
- async function closeBrowser() {
38
- if (browserInstance) {
39
- await browserInstance.close().catch(() => { });
40
- browserInstance = null;
41
- pageInstance = null;
57
+ async function takeScreenshot(signal) {
58
+ const screenshotPath = join(tmpdir(), `til-browser-${Date.now()}.png`);
59
+ try {
60
+ await runAgentBrowser(["screenshot", screenshotPath], signal);
61
+ const buf = await readFile(screenshotPath);
62
+ await unlink(screenshotPath).catch(() => { });
63
+ return { type: "image", data: buf.toString("base64"), mimeType: "image/png" };
64
+ }
65
+ catch {
66
+ return null;
42
67
  }
43
- }
44
- async function pageScreenshot() {
45
- const page = await getPage();
46
- const buf = await page.screenshot({ type: "png", fullPage: false });
47
- return { type: "image", data: buf.toString("base64"), mimeType: "image/png" };
48
68
  }
49
69
  export function createBrowserTool() {
50
70
  return {
51
71
  name: "browser",
52
72
  label: "Browser",
53
- description: "Control a browser: navigate to URLs, take page screenshots, click elements, type text, " +
54
- "execute JavaScript, extract text, scroll, and wait. Returns screenshots for visual feedback. " +
55
- "Requires Playwright: `npm install playwright && npx playwright install chromium`.",
73
+ description: "Browser automation via agent-browser. Default: visible browser window (headed mode). " +
74
+ "Workflow: open URL snapshot (get accessibility tree with refs like @e1, @e2) → " +
75
+ "interact using refs (click, fill, type) re-snapshot after page changes. " +
76
+ "Actions: open, snapshot, screenshot, click, fill, type, eval, get_text, scroll, wait, press, select, hover, back, forward, close.",
56
77
  parameters: {
57
78
  type: "object",
58
79
  properties: {
@@ -60,172 +81,201 @@ export function createBrowserTool() {
60
81
  type: "string",
61
82
  description: "Browser action to perform",
62
83
  enum: [
63
- "navigate",
84
+ "open",
85
+ "snapshot",
64
86
  "screenshot",
65
87
  "click",
88
+ "fill",
66
89
  "type",
67
- "evaluate",
90
+ "eval",
68
91
  "get_text",
69
92
  "scroll",
70
93
  "wait",
94
+ "press",
95
+ "select",
96
+ "hover",
71
97
  "back",
72
98
  "forward",
73
99
  "close",
74
100
  ],
75
101
  },
76
- url: { type: "string", description: "URL to navigate to (for navigate action)" },
102
+ url: { type: "string", description: "URL to navigate to (for open action)" },
77
103
  selector: {
78
104
  type: "string",
79
- description: "CSS selector for element targeting (for click, type, get_text)",
105
+ description: 'Element ref from snapshot (e.g. "@e1") or CSS selector (e.g. "#submit")',
80
106
  },
81
- x: { type: "number", description: "X coordinate for positional click" },
82
- y: { type: "number", description: "Y coordinate for positional click" },
83
- text: { type: "string", description: "Text to type (for type action)" },
84
- script: { type: "string", description: "JavaScript to evaluate (for evaluate action)" },
107
+ text: { type: "string", description: "Text to type or fill, or key to press, or option to select" },
108
+ script: { type: "string", description: "JavaScript code to evaluate (for eval action)" },
85
109
  direction: {
86
110
  type: "string",
87
111
  description: 'Scroll direction: "up" or "down" (default "down")',
88
- enum: ["up", "down"],
112
+ enum: ["up", "down", "left", "right"],
89
113
  },
90
114
  amount: { type: "number", description: "Scroll amount in pixels (default 500)" },
91
- timeout: { type: "number", description: "Wait timeout in ms (for wait action, default 3000)" },
115
+ timeout: { type: "number", description: "Wait timeout in ms (for wait action, default 5000)" },
116
+ headed: {
117
+ type: "boolean",
118
+ description: "Show browser window (true, default) or run headless (false). Only affects new browser sessions.",
119
+ },
92
120
  },
93
121
  required: ["action"],
94
122
  },
95
123
  execute: async (_toolCallId, params, signal) => {
96
- const { action, url, selector, x, y, text, script, direction = "down", amount = 500, timeout = 3000, } = params;
124
+ const { action, url, selector, text, script, direction = "down", amount = 500, timeout = 5000, headed, } = params;
125
+ if (headed !== undefined)
126
+ headedMode = headed;
97
127
  if (signal?.aborted)
98
128
  throw new Error("Operation aborted");
99
129
  const content = [];
100
130
  switch (action) {
101
- case "navigate": {
131
+ case "open": {
102
132
  if (!url)
103
- throw new Error("navigate requires url");
104
- const page = await getPage();
105
- await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
106
- const title = await page.title();
107
- const screenshot = await pageScreenshot();
108
- content.push(screenshot);
109
- content.push({ type: "text", text: `Navigated to: ${url}\nTitle: ${title}` });
133
+ throw new Error("open requires url");
134
+ browserUsed = true;
135
+ const { stdout } = await runAgentBrowser(["open", url], signal);
136
+ const screenshot = await takeScreenshot(signal);
137
+ if (screenshot)
138
+ content.push(screenshot);
139
+ content.push({ type: "text", text: stdout.trim() || `Opened: ${url}` });
110
140
  break;
111
141
  }
112
- case "screenshot": {
113
- const screenshot = await pageScreenshot();
114
- const page = await getPage();
115
- const pageUrl = page.url();
116
- content.push(screenshot);
117
- content.push({ type: "text", text: `Page screenshot: ${pageUrl}` });
142
+ case "snapshot": {
143
+ const args = ["snapshot", "-i", "-c"];
144
+ const { stdout } = await runAgentBrowser(args, signal);
145
+ content.push({ type: "text", text: stdout.trim() || "(empty snapshot)" });
118
146
  break;
119
147
  }
120
- case "click": {
121
- const page = await getPage();
122
- if (selector) {
123
- await page.click(selector, { timeout: 5000 });
124
- content.push({ type: "text", text: `Clicked element: ${selector}` });
125
- }
126
- else if (x !== undefined && y !== undefined) {
127
- await page.mouse.click(x, y);
128
- content.push({ type: "text", text: `Clicked at position (${x}, ${y})` });
148
+ case "screenshot": {
149
+ const screenshot = await takeScreenshot(signal);
150
+ if (screenshot) {
151
+ content.push(screenshot);
152
+ content.push({ type: "text", text: "Screenshot taken" });
129
153
  }
130
154
  else {
131
- throw new Error("click requires selector or x,y coordinates");
155
+ content.push({ type: "text", text: "Failed to take screenshot" });
132
156
  }
133
- await page.waitForTimeout(500);
134
- const screenshot = await pageScreenshot();
135
- content.push(screenshot);
157
+ break;
158
+ }
159
+ case "click": {
160
+ if (!selector)
161
+ throw new Error("click requires selector (ref like @e1 or CSS selector)");
162
+ const { stdout } = await runAgentBrowser(["click", selector], signal);
163
+ content.push({ type: "text", text: stdout.trim() || `Clicked: ${selector}` });
164
+ break;
165
+ }
166
+ case "fill": {
167
+ if (!selector)
168
+ throw new Error("fill requires selector");
169
+ if (!text && text !== "")
170
+ throw new Error("fill requires text");
171
+ const { stdout } = await runAgentBrowser(["fill", selector, text], signal);
172
+ content.push({ type: "text", text: stdout.trim() || `Filled ${selector} with "${text}"` });
136
173
  break;
137
174
  }
138
175
  case "type": {
176
+ if (!selector)
177
+ throw new Error("type requires selector");
139
178
  if (!text)
140
179
  throw new Error("type requires text");
141
- const page = await getPage();
142
- if (selector) {
143
- await page.fill(selector, text, { timeout: 5000 });
144
- }
145
- else {
146
- await page.keyboard.type(text);
147
- }
148
- content.push({ type: "text", text: `Typed: "${text.length > 80 ? text.slice(0, 80) + "..." : text}"` });
149
- const screenshot = await pageScreenshot();
150
- content.push(screenshot);
180
+ const { stdout } = await runAgentBrowser(["type", selector, text], signal);
181
+ content.push({ type: "text", text: stdout.trim() || `Typed "${text}" into ${selector}` });
151
182
  break;
152
183
  }
153
- case "evaluate": {
184
+ case "eval": {
154
185
  if (!script)
155
- throw new Error("evaluate requires script");
156
- const page = await getPage();
157
- const result = await page.evaluate(script);
158
- const resultStr = typeof result === "string" ? result : JSON.stringify(result, null, 2);
159
- const truncated = resultStr.length > 10000 ? resultStr.slice(0, 10000) + "\n...(truncated)" : resultStr;
160
- content.push({ type: "text", text: `Evaluate result:\n${truncated}` });
186
+ throw new Error("eval requires script");
187
+ const { stdout } = await runAgentBrowser(["eval", script], signal);
188
+ const result = stdout.trim();
189
+ const truncated = result.length > 10000 ? result.slice(0, 10000) + "\n...(truncated)" : result;
190
+ content.push({ type: "text", text: truncated || "(no result)" });
161
191
  break;
162
192
  }
163
193
  case "get_text": {
164
- const page = await getPage();
165
- let extractedText;
166
- if (selector) {
167
- extractedText = await page.textContent(selector, { timeout: 5000 }) ?? "";
168
- }
169
- else {
170
- extractedText = await page.evaluate("document.body.innerText");
171
- }
172
- const truncated = extractedText.length > 20000
173
- ? extractedText.slice(0, 20000) + "\n...(truncated)"
174
- : extractedText;
194
+ if (!selector)
195
+ throw new Error("get_text requires selector (ref like @e1 or CSS selector)");
196
+ const { stdout } = await runAgentBrowser(["get", "text", selector], signal);
197
+ const result = stdout.trim();
198
+ const truncated = result.length > 20000 ? result.slice(0, 20000) + "\n...(truncated)" : result;
175
199
  content.push({ type: "text", text: truncated || "(empty)" });
176
200
  break;
177
201
  }
178
202
  case "scroll": {
179
- const page = await getPage();
180
- const delta = direction === "up" ? -amount : amount;
181
- await page.mouse.wheel(0, delta);
182
- await page.waitForTimeout(300);
183
- content.push({ type: "text", text: `Scrolled ${direction} by ${amount}px` });
184
- const screenshot = await pageScreenshot();
185
- content.push(screenshot);
203
+ const args = ["scroll", direction];
204
+ if (amount !== 500)
205
+ args.push(String(amount));
206
+ if (selector)
207
+ args.push("--selector", selector);
208
+ const { stdout } = await runAgentBrowser(args, signal);
209
+ content.push({ type: "text", text: stdout.trim() || `Scrolled ${direction} by ${amount}px` });
186
210
  break;
187
211
  }
188
212
  case "wait": {
189
- const page = await getPage();
213
+ const args = ["wait"];
190
214
  if (selector) {
191
- await page.waitForSelector(selector, { timeout });
192
- content.push({ type: "text", text: `Element found: ${selector}` });
215
+ args.push(selector);
193
216
  }
194
217
  else {
195
- await page.waitForTimeout(timeout);
196
- content.push({ type: "text", text: `Waited ${timeout}ms` });
218
+ args.push(String(timeout));
197
219
  }
198
- const screenshot = await pageScreenshot();
199
- content.push(screenshot);
220
+ const { stdout } = await runAgentBrowser(args, signal, timeout + 5000);
221
+ content.push({ type: "text", text: stdout.trim() || `Wait completed` });
222
+ break;
223
+ }
224
+ case "press": {
225
+ if (!text)
226
+ throw new Error("press requires text (key name like Enter, Tab, etc.)");
227
+ const { stdout } = await runAgentBrowser(["press", text], signal);
228
+ content.push({ type: "text", text: stdout.trim() || `Pressed: ${text}` });
229
+ break;
230
+ }
231
+ case "select": {
232
+ if (!selector)
233
+ throw new Error("select requires selector");
234
+ if (!text)
235
+ throw new Error("select requires text (option value)");
236
+ const { stdout } = await runAgentBrowser(["select", selector, text], signal);
237
+ content.push({ type: "text", text: stdout.trim() || `Selected "${text}" in ${selector}` });
238
+ break;
239
+ }
240
+ case "hover": {
241
+ if (!selector)
242
+ throw new Error("hover requires selector");
243
+ const { stdout } = await runAgentBrowser(["hover", selector], signal);
244
+ content.push({ type: "text", text: stdout.trim() || `Hovered: ${selector}` });
200
245
  break;
201
246
  }
202
247
  case "back": {
203
- const page = await getPage();
204
- await page.goBack({ waitUntil: "domcontentloaded" });
205
- const screenshot = await pageScreenshot();
206
- content.push(screenshot);
207
- content.push({ type: "text", text: `Navigated back to: ${page.url()}` });
248
+ const { stdout } = await runAgentBrowser(["back"], signal);
249
+ content.push({ type: "text", text: stdout.trim() || "Navigated back" });
208
250
  break;
209
251
  }
210
252
  case "forward": {
211
- const page = await getPage();
212
- await page.goForward({ waitUntil: "domcontentloaded" });
213
- const screenshot = await pageScreenshot();
214
- content.push(screenshot);
215
- content.push({ type: "text", text: `Navigated forward to: ${page.url()}` });
253
+ const { stdout } = await runAgentBrowser(["forward"], signal);
254
+ content.push({ type: "text", text: stdout.trim() || "Navigated forward" });
216
255
  break;
217
256
  }
218
257
  case "close": {
219
- await closeBrowser();
258
+ try {
259
+ await runAgentBrowser(["close"], signal, 5000);
260
+ }
261
+ catch { /* already closed */ }
220
262
  content.push({ type: "text", text: "Browser closed" });
221
263
  break;
222
264
  }
223
265
  default:
224
- throw new Error(`Unknown browser action: ${action}`);
266
+ throw new Error(`Unknown browser action: ${action}. Available: open, snapshot, screenshot, click, fill, type, eval, get_text, scroll, wait, press, select, hover, back, forward, close`);
225
267
  }
226
268
  return { content };
227
269
  },
228
270
  };
229
271
  }
230
- export { closeBrowser };
272
+ export async function closeBrowser() {
273
+ if (!browserUsed)
274
+ return;
275
+ try {
276
+ await runAgentBrowser(["close"], undefined, 5000);
277
+ }
278
+ catch { /* already closed */ }
279
+ browserUsed = false;
280
+ }
231
281
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/tools/browser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/tools/browser.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antaif3ng/til-work",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "TIL Work — 运行在终端里的个人 AI 助手 (Personal AI assistant CLI powered by LLM)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -43,6 +43,7 @@
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
+ "agent-browser": "^0.20.6",
46
47
  "chalk": "^5.5.0",
47
48
  "cli-highlight": "^2.1.11",
48
49
  "marked": "^17.0.4"
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: agent-browser
3
+ description: "Browser automation via agent-browser CLI. Use when the user needs to navigate websites, interact with page elements, take screenshots, extract data, or perform browser automation workflows."
4
+ ---
5
+
6
+ # Agent-Browser Skill
7
+
8
+ Browser automation powered by [agent-browser](https://github.com/vercel-labs/agent-browser) — a native Rust CLI designed for AI agents.
9
+
10
+ ## Built-in — No Extra Setup
11
+
12
+ agent-browser is bundled as a dependency. It auto-discovers your system Chrome — no extra browser download needed.
13
+
14
+ If Chrome is not found, run `agent-browser install` to download Chrome for Testing, or set `AGENT_BROWSER_EXECUTABLE_PATH` to point to a custom browser.
15
+
16
+ ## Display Mode
17
+
18
+ By default, browser opens in **headed mode** (visible window) so you can watch the agent operate. Set `headed=false` parameter to run headless (no window), or use env `AGENT_BROWSER_HEADED=false`.
19
+
20
+ ## Core Workflow: Snapshot → Ref → Interact
21
+
22
+ agent-browser uses a **ref-based interaction pattern**. This is the recommended workflow:
23
+
24
+ 1. **Open** the target URL
25
+ 2. **Snapshot** to get the accessibility tree with element refs (`@e1`, `@e2`, ...)
26
+ 3. **Interact** using refs (click, fill, type)
27
+ 4. **Re-snapshot** after page changes to get updated refs
28
+ 5. **Close** when done
29
+
30
+ ### Example
31
+
32
+ ```
33
+ # Step 1: Open page
34
+ browser action=open url="https://example.com"
35
+
36
+ # Step 2: Get interactive elements with refs
37
+ browser action=snapshot
38
+ # Output:
39
+ # - heading "Example Domain" [ref=e1]
40
+ # - link "More information..." [ref=e2]
41
+
42
+ # Step 3: Interact by ref
43
+ browser action=click selector="@e2"
44
+
45
+ # Step 4: Re-snapshot after navigation
46
+ browser action=snapshot
47
+ ```
48
+
49
+ ## Available Actions
50
+
51
+ | Action | Parameters | Description |
52
+ |--------|-----------|-------------|
53
+ | `open` | `url` | Navigate to URL |
54
+ | `snapshot` | — | Get accessibility tree with refs (compact, interactive elements only) |
55
+ | `screenshot` | — | Take page screenshot (returns image) |
56
+ | `click` | `selector` | Click element by ref (`@e1`) or CSS selector |
57
+ | `fill` | `selector`, `text` | Clear field and fill with text |
58
+ | `type` | `selector`, `text` | Type text (append, preserves existing) |
59
+ | `press` | `text` | Press keyboard key (Enter, Tab, Escape, etc.) |
60
+ | `select` | `selector`, `text` | Select dropdown option |
61
+ | `hover` | `selector` | Hover over element |
62
+ | `eval` | `script` | Execute JavaScript in page context |
63
+ | `get_text` | `selector` | Get text content of element |
64
+ | `scroll` | `direction`, `amount` | Scroll page (up/down/left/right, default 500px) |
65
+ | `wait` | `selector` or `timeout` | Wait for element or milliseconds |
66
+ | `back` | — | Navigate back |
67
+ | `forward` | — | Navigate forward |
68
+ | `close` | — | Close browser |
69
+
70
+ ## Tips
71
+
72
+ - **Always snapshot before interacting** — refs are assigned from the snapshot and are the most reliable way to target elements.
73
+ - **Use `fill` for input fields** — it clears existing text before typing. Use `type` to append.
74
+ - **Re-snapshot after any page change** — navigation, clicks, or form submissions may update the DOM and invalidate old refs.
75
+ - **Snapshot is compact** — it returns ~200-400 tokens vs ~3000-5000 for full DOM, minimizing context usage.
76
+
77
+ ## Combining with Search Tools
78
+
79
+ agent-browser is for **browser automation only** — it does not provide web search.
80
+
81
+ For searching the web:
82
+ - Use the built-in `web_search` tool (DuckDuckGo works without API key; Brave/Google with optional API keys)
83
+ - Use `web_fetch` to read specific web pages as text
84
+ - External MCP servers (e.g. BigModel web_search) can be configured in `~/.til/config.json` for enhanced search
85
+
86
+ Typical flow for research tasks:
87
+ 1. `web_search` → find relevant URLs
88
+ 2. `web_fetch` → read page content as text (fast, no browser needed)
89
+ 3. `browser` → only when you need interactive automation (forms, JS-heavy pages, screenshots)