ai-browser 0.2.1 → 0.2.3

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 (79) hide show
  1. package/README.md +76 -7
  2. package/dist/agent/agent-loop.d.ts.map +1 -1
  3. package/dist/agent/agent-loop.js +2 -1
  4. package/dist/agent/agent-loop.js.map +1 -1
  5. package/dist/api/mcp-sse.d.ts.map +1 -1
  6. package/dist/api/mcp-sse.js +26 -8
  7. package/dist/api/mcp-sse.js.map +1 -1
  8. package/dist/api/routes.js +1 -1
  9. package/dist/api/routes.js.map +1 -1
  10. package/dist/browser/BrowserManager.d.ts.map +1 -1
  11. package/dist/browser/BrowserManager.js +3 -2
  12. package/dist/browser/BrowserManager.js.map +1 -1
  13. package/dist/browser/index.d.ts +1 -1
  14. package/dist/browser/index.d.ts.map +1 -1
  15. package/dist/cli/mcp-stdio.js +1 -1
  16. package/dist/cli/mcp-stdio.js.map +1 -1
  17. package/dist/mcp/browser-mcp-server.d.ts +6 -9
  18. package/dist/mcp/browser-mcp-server.d.ts.map +1 -1
  19. package/dist/mcp/browser-mcp-server.js +125 -218
  20. package/dist/mcp/browser-mcp-server.js.map +1 -1
  21. package/dist/mcp/task-tools.d.ts +6 -0
  22. package/dist/mcp/task-tools.d.ts.map +1 -0
  23. package/dist/mcp/task-tools.js +303 -0
  24. package/dist/mcp/task-tools.js.map +1 -0
  25. package/dist/task/artifact-store.d.ts +36 -0
  26. package/dist/task/artifact-store.d.ts.map +1 -0
  27. package/dist/task/artifact-store.js +115 -0
  28. package/dist/task/artifact-store.js.map +1 -0
  29. package/dist/task/cancel-token.d.ts +13 -0
  30. package/dist/task/cancel-token.d.ts.map +1 -0
  31. package/dist/task/cancel-token.js +42 -0
  32. package/dist/task/cancel-token.js.map +1 -0
  33. package/dist/task/error-codes.d.ts +19 -0
  34. package/dist/task/error-codes.d.ts.map +1 -0
  35. package/dist/task/error-codes.js +22 -0
  36. package/dist/task/error-codes.js.map +1 -0
  37. package/dist/task/index.d.ts +17 -0
  38. package/dist/task/index.d.ts.map +1 -0
  39. package/dist/task/index.js +10 -0
  40. package/dist/task/index.js.map +1 -0
  41. package/dist/task/run-manager.d.ts +77 -0
  42. package/dist/task/run-manager.d.ts.map +1 -0
  43. package/dist/task/run-manager.js +286 -0
  44. package/dist/task/run-manager.js.map +1 -0
  45. package/dist/task/run-store.d.ts +39 -0
  46. package/dist/task/run-store.d.ts.map +1 -0
  47. package/dist/task/run-store.js +88 -0
  48. package/dist/task/run-store.js.map +1 -0
  49. package/dist/task/templates/batch-extract.d.ts +33 -0
  50. package/dist/task/templates/batch-extract.d.ts.map +1 -0
  51. package/dist/task/templates/batch-extract.js +153 -0
  52. package/dist/task/templates/batch-extract.js.map +1 -0
  53. package/dist/task/templates/login-keep-session.d.ts +34 -0
  54. package/dist/task/templates/login-keep-session.d.ts.map +1 -0
  55. package/dist/task/templates/login-keep-session.js +190 -0
  56. package/dist/task/templates/login-keep-session.js.map +1 -0
  57. package/dist/task/templates/multi-tab-compare.d.ts +43 -0
  58. package/dist/task/templates/multi-tab-compare.d.ts.map +1 -0
  59. package/dist/task/templates/multi-tab-compare.js +204 -0
  60. package/dist/task/templates/multi-tab-compare.js.map +1 -0
  61. package/dist/task/templates/registry.d.ts +13 -0
  62. package/dist/task/templates/registry.d.ts.map +1 -0
  63. package/dist/task/templates/registry.js +40 -0
  64. package/dist/task/templates/registry.js.map +1 -0
  65. package/dist/task/tool-actions.d.ts +114 -0
  66. package/dist/task/tool-actions.d.ts.map +1 -0
  67. package/dist/task/tool-actions.js +371 -0
  68. package/dist/task/tool-actions.js.map +1 -0
  69. package/dist/task/tool-context.d.ts +26 -0
  70. package/dist/task/tool-context.d.ts.map +1 -0
  71. package/dist/task/tool-context.js +2 -0
  72. package/dist/task/tool-context.js.map +1 -0
  73. package/dist/utils/url-validator.d.ts +13 -0
  74. package/dist/utils/url-validator.d.ts.map +1 -1
  75. package/dist/utils/url-validator.js +64 -0
  76. package/dist/utils/url-validator.js.map +1 -1
  77. package/package.json +3 -2
  78. package/public/agent.html +3 -927
  79. package/public/index.html +1910 -664
@@ -0,0 +1,371 @@
1
+ import { validateUrlAsync } from '../utils/url-validator.js';
2
+ import { ElementCollector, ElementMatcher, PageAnalyzer, RegionDetector, ContentExtractor, } from '../semantic/index.js';
3
+ import { executeAction } from '../browser/actions.js';
4
+ import { ErrorCode } from './error-codes.js';
5
+ // Shared semantic module instances
6
+ const elementCollector = new ElementCollector();
7
+ const elementMatcher = new ElementMatcher();
8
+ const pageAnalyzer = new PageAnalyzer();
9
+ const regionDetector = new RegionDetector();
10
+ const contentExtractor = new ContentExtractor();
11
+ // ===== Helper =====
12
+ function makeError(message, code) {
13
+ const err = new Error(message);
14
+ err.errorCode = code;
15
+ return err;
16
+ }
17
+ // ===== Tool Actions =====
18
+ /** 导航到指定 URL(操作 active tab) */
19
+ export async function navigate(ctx, sessionId, url) {
20
+ const check = await validateUrlAsync(url, ctx.urlOpts);
21
+ if (!check.valid) {
22
+ throw makeError(check.reason, ErrorCode.INVALID_PARAMETER);
23
+ }
24
+ const tab = ctx.getActiveTab(sessionId);
25
+ await ctx.sessionManager.syncHeadfulCookies();
26
+ await ctx.injectCookies(tab.page);
27
+ let partial = false;
28
+ let statusCode;
29
+ try {
30
+ const response = await tab.page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
31
+ statusCode = response?.status();
32
+ }
33
+ catch (err) {
34
+ if (err.name === 'TimeoutError' || err.message?.includes('timeout')) {
35
+ partial = true;
36
+ }
37
+ else {
38
+ throw new Error(err.message || 'Navigation failed');
39
+ }
40
+ }
41
+ // SPA 额外渲染时间
42
+ try {
43
+ await tab.page.waitForNetworkIdle({ timeout: 3000 });
44
+ }
45
+ catch { }
46
+ tab.url = tab.page.url();
47
+ await ctx.saveCookies(tab.page);
48
+ ctx.sessionManager.updateActivity(sessionId);
49
+ let title = '';
50
+ try {
51
+ title = await tab.page.title();
52
+ }
53
+ catch {
54
+ title = '(无法获取标题)';
55
+ }
56
+ const result = { success: true, partial, statusCode, page: { url: tab.page.url(), title } };
57
+ if (tab.events) {
58
+ const pending = tab.events.getPendingDialog();
59
+ if (pending)
60
+ result.dialog = pending;
61
+ }
62
+ return result;
63
+ }
64
+ /** 等待页面 DOM 稳定(支持显式 tabId) */
65
+ export async function waitForStable(ctx, sessionId, tabId, opts) {
66
+ const tab = ctx.getTab(sessionId, tabId);
67
+ if (!tab)
68
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
69
+ if (!tab.events) {
70
+ return { stable: true, domStable: true, networkPending: 0, loadState: 'loaded' };
71
+ }
72
+ const maxWait = Math.min(opts?.timeout ?? 5000, 30000);
73
+ const stable = await tab.events.waitForStable(maxWait, opts?.quietMs);
74
+ ctx.sessionManager.updateActivity(sessionId);
75
+ const state = tab.events.getStabilityState();
76
+ return { ...state, stable };
77
+ }
78
+ /** 获取页面语义信息(支持显式 tabId) */
79
+ export async function getPageInfo(ctx, sessionId, tabId, opts) {
80
+ const tab = ctx.getTab(sessionId, tabId);
81
+ if (!tab)
82
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
83
+ const limit = opts?.maxElements ?? 50;
84
+ const filterVisible = opts?.visibleOnly ?? true;
85
+ const [elements, analysis, regions] = await Promise.all([
86
+ elementCollector.collect(tab.page),
87
+ pageAnalyzer.analyze(tab.page),
88
+ regionDetector.detect(tab.page),
89
+ ]);
90
+ let filtered = elements;
91
+ // Filter to viewport-visible elements
92
+ if (filterVisible) {
93
+ const viewport = tab.page.viewport();
94
+ if (viewport) {
95
+ filtered = filtered.filter((el) => {
96
+ const b = el.bounds;
97
+ if (!b || (b.width === 0 && b.height === 0))
98
+ return true;
99
+ return b.y + b.height > 0 && b.y < viewport.height
100
+ && b.x + b.width > 0 && b.x < viewport.width;
101
+ });
102
+ }
103
+ }
104
+ // Sort by y position and truncate
105
+ const totalElements = filtered.length;
106
+ filtered.sort((a, b) => (a.bounds?.y ?? 0) - (b.bounds?.y ?? 0));
107
+ const truncated = filtered.length > limit;
108
+ if (truncated)
109
+ filtered = filtered.slice(0, limit);
110
+ // Mask sensitive field values
111
+ for (const el of filtered) {
112
+ if (el.type === 'textbox' || el.type === 'input') {
113
+ const idLower = (el.id || '').toLowerCase();
114
+ const labelLower = (el.label || '').toLowerCase();
115
+ const isSensitive = idLower.includes('password') || idLower.includes('secret') || idLower.includes('token')
116
+ || labelLower.includes('password') || labelLower.includes('secret') || labelLower.includes('token');
117
+ if (isSensitive && el.state?.value) {
118
+ el.state.value = '********';
119
+ }
120
+ }
121
+ }
122
+ ctx.sessionManager.updateActivity(sessionId);
123
+ const result = {
124
+ page: {
125
+ url: tab.page.url(),
126
+ title: await tab.page.title(),
127
+ type: analysis.pageType,
128
+ summary: analysis.summary,
129
+ },
130
+ elements: filtered,
131
+ totalElements,
132
+ truncated,
133
+ regions,
134
+ intents: analysis.intents,
135
+ };
136
+ if (tab.events) {
137
+ result.stability = tab.events.getStabilityState();
138
+ const pending = tab.events.getPendingDialog();
139
+ if (pending)
140
+ result.pendingDialog = pending;
141
+ }
142
+ return result;
143
+ }
144
+ /** 提取页面文本内容(支持显式 tabId) */
145
+ export async function getPageContent(ctx, sessionId, tabId, opts) {
146
+ const tab = ctx.getTab(sessionId, tabId);
147
+ if (!tab)
148
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
149
+ const content = await contentExtractor.extract(tab.page);
150
+ if (opts?.maxLength && content.sections) {
151
+ let totalLen = 0;
152
+ const truncatedSections = [];
153
+ for (const section of content.sections) {
154
+ const sectionText = section.text || '';
155
+ if (totalLen + sectionText.length > opts.maxLength) {
156
+ const remaining = opts.maxLength - totalLen;
157
+ if (remaining > 0) {
158
+ truncatedSections.push({ ...section, text: sectionText.slice(0, remaining) });
159
+ }
160
+ break;
161
+ }
162
+ truncatedSections.push(section);
163
+ totalLen += sectionText.length;
164
+ }
165
+ content.sections = truncatedSections;
166
+ }
167
+ ctx.sessionManager.updateActivity(sessionId);
168
+ return content;
169
+ }
170
+ /** 创建新标签页(可选导航到 URL) */
171
+ export async function createTab(ctx, sessionId, url) {
172
+ const tab = await ctx.sessionManager.createTab(sessionId);
173
+ if (!tab)
174
+ throw makeError(`Session not found: ${sessionId}`, ErrorCode.SESSION_NOT_FOUND);
175
+ // Auto-switch to the new tab
176
+ ctx.sessionManager.switchTab(sessionId, tab.id);
177
+ let partial = false;
178
+ if (url) {
179
+ const check = await validateUrlAsync(url, ctx.urlOpts);
180
+ if (!check.valid) {
181
+ throw makeError(check.reason, ErrorCode.INVALID_PARAMETER);
182
+ }
183
+ await ctx.injectCookies(tab.page);
184
+ try {
185
+ await tab.page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
186
+ }
187
+ catch (err) {
188
+ if (err.name === 'TimeoutError' || err.message?.includes('timeout')) {
189
+ partial = true;
190
+ }
191
+ else {
192
+ throw err;
193
+ }
194
+ }
195
+ tab.url = tab.page.url();
196
+ await ctx.saveCookies(tab.page);
197
+ }
198
+ ctx.sessionManager.updateActivity(sessionId);
199
+ return { tabId: tab.id, url: tab.page.url(), partial };
200
+ }
201
+ /** 关闭指定标签页 */
202
+ export async function closeTab(ctx, sessionId, tabId) {
203
+ const closed = await ctx.sessionManager.closeTab(sessionId, tabId);
204
+ if (!closed)
205
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
206
+ ctx.sessionManager.updateActivity(sessionId);
207
+ return { success: true };
208
+ }
209
+ /** 模糊搜索页面元素 */
210
+ export async function findElement(ctx, sessionId, tabId, query, limit) {
211
+ const tab = ctx.getTab(sessionId, tabId);
212
+ if (!tab)
213
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
214
+ const elements = await elementCollector.collect(tab.page);
215
+ const candidates = elementMatcher.findByQuery(elements, query, limit ?? 5);
216
+ ctx.sessionManager.updateActivity(sessionId);
217
+ return {
218
+ query,
219
+ candidates: candidates.map((c) => ({
220
+ id: c.element.id,
221
+ label: c.element.label,
222
+ type: c.element.type,
223
+ score: c.score,
224
+ matchReason: c.matchReason,
225
+ })),
226
+ };
227
+ }
228
+ /** 点击元素(支持显式 tabId) */
229
+ export async function click(ctx, sessionId, tabId, elementId) {
230
+ const tab = ctx.getTab(sessionId, tabId);
231
+ if (!tab)
232
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
233
+ await executeAction(tab.page, 'click', elementId);
234
+ // Small delay to allow popup/dialog events to fire
235
+ await new Promise(r => setTimeout(r, 200));
236
+ tab.url = tab.page.url();
237
+ await ctx.saveCookies(tab.page);
238
+ // Check for popup windows captured by PageEventTracker
239
+ let newTabCreated;
240
+ if (tab.events) {
241
+ const popups = tab.events.getPopupPages();
242
+ for (const popupPage of popups) {
243
+ const newTab = await ctx.sessionManager.registerPopupAsTab(sessionId, popupPage);
244
+ if (newTab)
245
+ newTabCreated = newTab.id;
246
+ }
247
+ tab.events.clearPopupPages();
248
+ }
249
+ ctx.sessionManager.updateActivity(sessionId);
250
+ const result = {
251
+ success: true,
252
+ page: { url: tab.page.url(), title: await tab.page.title() },
253
+ };
254
+ if (newTabCreated)
255
+ result.newTabCreated = newTabCreated;
256
+ if (tab.events) {
257
+ const pending = tab.events.getPendingDialog();
258
+ if (pending)
259
+ result.dialog = pending;
260
+ }
261
+ return result;
262
+ }
263
+ /** 输入文本(支持显式 tabId) */
264
+ export async function typeText(ctx, sessionId, tabId, elementId, text, submit) {
265
+ const tab = ctx.getTab(sessionId, tabId);
266
+ if (!tab)
267
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
268
+ await executeAction(tab.page, 'type', elementId, text);
269
+ if (submit) {
270
+ await Promise.all([
271
+ tab.page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: 5000 }).catch(() => { }),
272
+ tab.page.keyboard.press('Enter'),
273
+ ]);
274
+ }
275
+ await ctx.saveCookies(tab.page);
276
+ ctx.sessionManager.updateActivity(sessionId);
277
+ return {
278
+ success: true,
279
+ page: { url: tab.page.url(), title: await tab.page.title() },
280
+ };
281
+ }
282
+ // ===== pressKey constants =====
283
+ const ALLOWED_KEYS = new Set([
284
+ 'Enter', 'Escape', 'Tab', 'Backspace', 'Delete', 'Space',
285
+ 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',
286
+ 'Home', 'End', 'PageUp', 'PageDown',
287
+ ]);
288
+ const MODIFIER_COMBO_KEYS = new Set([
289
+ ...ALLOWED_KEYS,
290
+ ...'abcdefghijklmnopqrstuvwxyz'.split(''),
291
+ ...'0123456789'.split(''),
292
+ ]);
293
+ const BLOCKED_COMBOS = [
294
+ { modifiers: ['Control'], key: 'w' },
295
+ { modifiers: ['Meta'], key: 'w' },
296
+ { modifiers: ['Control', 'Shift'], key: 'I' },
297
+ { modifiers: ['Meta', 'Shift'], key: 'I' },
298
+ { modifiers: ['Control', 'Shift'], key: 'J' },
299
+ { modifiers: ['Meta', 'Shift'], key: 'J' },
300
+ { modifiers: ['Control', 'Shift'], key: 'Delete' },
301
+ { modifiers: ['Control'], key: 'q' },
302
+ { modifiers: ['Meta'], key: 'q' },
303
+ ];
304
+ function isComboAllowed(modifiers, key) {
305
+ for (const blocked of BLOCKED_COMBOS) {
306
+ const modSet = new Set(modifiers);
307
+ const blockedSet = new Set(blocked.modifiers);
308
+ if (modSet.size === blockedSet.size &&
309
+ [...blockedSet].every(m => modSet.has(m)) &&
310
+ key.toLowerCase() === blocked.key.toLowerCase()) {
311
+ return false;
312
+ }
313
+ }
314
+ return MODIFIER_COMBO_KEYS.has(key);
315
+ }
316
+ /** 按下键盘按键(支持显式 tabId + 修饰键组合) */
317
+ export async function pressKey(ctx, sessionId, tabId, key, modifiers) {
318
+ const tab = ctx.getTab(sessionId, tabId);
319
+ if (!tab)
320
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
321
+ if (modifiers && modifiers.length > 0) {
322
+ if (!isComboAllowed(modifiers, key)) {
323
+ throw makeError(`不允许的组合键: ${modifiers.join('+')}+${key}`, ErrorCode.INVALID_PARAMETER);
324
+ }
325
+ for (const mod of modifiers) {
326
+ await tab.page.keyboard.down(mod);
327
+ }
328
+ await tab.page.keyboard.press(key);
329
+ for (let i = modifiers.length - 1; i >= 0; i--) {
330
+ await tab.page.keyboard.up(modifiers[i]);
331
+ }
332
+ }
333
+ else {
334
+ if (!ALLOWED_KEYS.has(key)) {
335
+ throw makeError(`不允许的按键: ${key}。允许: ${[...ALLOWED_KEYS].join(', ')}`, ErrorCode.INVALID_PARAMETER);
336
+ }
337
+ await tab.page.keyboard.press(key);
338
+ }
339
+ await new Promise(r => setTimeout(r, 300));
340
+ ctx.sessionManager.updateActivity(sessionId);
341
+ return {
342
+ success: true,
343
+ page: { url: tab.page.url(), title: await tab.page.title() },
344
+ };
345
+ }
346
+ /** 条件等待(支持显式 tabId) */
347
+ export async function wait(ctx, sessionId, tabId, opts) {
348
+ const tab = ctx.getTab(sessionId, tabId);
349
+ if (!tab)
350
+ throw makeError(`Tab not found: ${tabId}`, ErrorCode.SESSION_NOT_FOUND);
351
+ const { condition, milliseconds, selector } = opts;
352
+ if (condition === 'networkidle') {
353
+ await tab.page.waitForNetworkIdle({ timeout: milliseconds || 10000 });
354
+ }
355
+ else if (condition === 'element_hidden') {
356
+ if (!selector)
357
+ throw makeError('selector is required for element_hidden condition', ErrorCode.INVALID_PARAMETER);
358
+ await tab.page.waitForSelector(selector, { hidden: true, timeout: milliseconds || 10000 });
359
+ }
360
+ else if (condition === 'selector' || (!condition && selector)) {
361
+ if (!selector)
362
+ throw makeError('selector is required for selector condition', ErrorCode.INVALID_PARAMETER);
363
+ await tab.page.waitForSelector(selector, { timeout: milliseconds || 10000 });
364
+ }
365
+ else {
366
+ await new Promise(r => setTimeout(r, Math.min(milliseconds || 1000, 30000)));
367
+ }
368
+ ctx.sessionManager.updateActivity(sessionId);
369
+ return { success: true };
370
+ }
371
+ //# sourceMappingURL=tool-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-actions.js","sourceRoot":"","sources":["../../src/task/tool-actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Page } from 'puppeteer-core';
2
+ import type { SessionManager, Tab } from '../browser/index.js';
3
+ import type { CookieStore } from '../browser/CookieStore.js';
4
+ import type { ValidateUrlOptions } from '../utils/url-validator.js';
5
+ export type TrustLevel = 'local' | 'remote';
6
+ /**
7
+ * 工具执行上下文 — 由 MCP handler 或模板执行器构造。
8
+ * 所有 toolAction 函数通过此接口获取依赖,不直接引用全局状态。
9
+ */
10
+ export interface ToolContext {
11
+ sessionManager: SessionManager;
12
+ cookieStore?: CookieStore;
13
+ urlOpts: ValidateUrlOptions;
14
+ trustLevel: TrustLevel;
15
+ /** 解析 sessionId(MCP: defaultSession 逻辑;模板: 直接返回绑定 sessionId) */
16
+ resolveSession(sessionId?: string): Promise<string>;
17
+ /** 获取指定 session 的活跃 tab */
18
+ getActiveTab(sessionId: string): Tab;
19
+ /** 获取指定 session 的指定 tab(并发 tab 场景) */
20
+ getTab(sessionId: string, tabId: string): Tab | undefined;
21
+ /** 注入 cookie 到页面(CDP) */
22
+ injectCookies(page: Page): Promise<void>;
23
+ /** 从页面保存 cookie(CDP) */
24
+ saveCookies(page: Page): Promise<void>;
25
+ }
26
+ //# sourceMappingURL=tool-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-context.d.ts","sourceRoot":"","sources":["../../src/task/tool-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,UAAU,EAAE,UAAU,CAAC;IAEvB,gEAAgE;IAChE,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD,2BAA2B;IAC3B,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC;IAErC,sCAAsC;IACtC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC;IAE1D,yBAAyB;IACzB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC,wBAAwB;IACxB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tool-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-context.js","sourceRoot":"","sources":["../../src/task/tool-context.ts"],"names":[],"mappings":""}
@@ -14,4 +14,17 @@ export declare function validateUrl(url: string, options?: ValidateUrlOptions):
14
14
  valid: false;
15
15
  reason: string;
16
16
  };
17
+ /**
18
+ * Async URL validation with DNS resolution check.
19
+ * When blockPrivate=true and hostname is not an IP literal,
20
+ * resolves DNS and checks if the resolved IP is private (anti-DNS-rebinding).
21
+ * DNS failure → allow original URL (fail-open, avoids false negatives in restricted DNS envs).
22
+ */
23
+ export declare function validateUrlAsync(url: string, options?: ValidateUrlOptions): Promise<{
24
+ valid: true;
25
+ parsed: URL;
26
+ } | {
27
+ valid: false;
28
+ reason: string;
29
+ }>;
17
30
  //# sourceMappingURL=url-validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-validator.d.ts","sourceRoot":"","sources":["../../src/utils/url-validator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kGAAkG;IAClG,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAsBD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAiE1I"}
1
+ {"version":3,"file":"url-validator.d.ts","sourceRoot":"","sources":["../../src/utils/url-validator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kGAAkG;IAClG,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAsBD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAiE1I;AAeD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAuC1E"}
@@ -1,6 +1,9 @@
1
1
  /**
2
2
  * URL validation utility — blocks dangerous protocols and private/loopback addresses.
3
3
  */
4
+ import dns from 'node:dns';
5
+ import { promisify } from 'node:util';
6
+ const dnsLookup = promisify(dns.lookup);
4
7
  // RFC 1918 + loopback + link-local ranges
5
8
  const PRIVATE_IP_PATTERNS = [
6
9
  /^127\./, // 127.0.0.0/8
@@ -77,4 +80,65 @@ export function validateUrl(url, options = {}) {
77
80
  }
78
81
  return { valid: true, parsed };
79
82
  }
83
+ /** Check if hostname is an IP literal (v4 or v6 bracket notation) */
84
+ function isIpLiteral(hostname) {
85
+ if (hostname.startsWith('['))
86
+ return true; // IPv6
87
+ return /^\d{1,3}(\.\d{1,3}){3}$/.test(hostname);
88
+ }
89
+ function isPrivateIp(ip) {
90
+ for (const pattern of PRIVATE_IP_PATTERNS) {
91
+ if (pattern.test(ip))
92
+ return true;
93
+ }
94
+ return false;
95
+ }
96
+ /**
97
+ * Async URL validation with DNS resolution check.
98
+ * When blockPrivate=true and hostname is not an IP literal,
99
+ * resolves DNS and checks if the resolved IP is private (anti-DNS-rebinding).
100
+ * DNS failure → allow original URL (fail-open, avoids false negatives in restricted DNS envs).
101
+ */
102
+ export async function validateUrlAsync(url, options = {}) {
103
+ // Run synchronous checks first
104
+ const syncResult = validateUrl(url, options);
105
+ if (!syncResult.valid)
106
+ return syncResult;
107
+ // DNS check only needed when blockPrivate is enabled and hostname is not an IP literal
108
+ if (!options.blockPrivate)
109
+ return syncResult;
110
+ const { parsed } = syncResult;
111
+ if (parsed.protocol === 'file:')
112
+ return syncResult;
113
+ const hostname = parsed.hostname;
114
+ if (isIpLiteral(hostname))
115
+ return syncResult; // already checked by sync validator
116
+ // Resolve DNS and check resolved IP
117
+ try {
118
+ const { address } = await dnsLookup(hostname);
119
+ if (isPrivateIp(address)) {
120
+ return { valid: false, reason: `DNS resolved to private address: ${hostname} → ${address}` };
121
+ }
122
+ if (PRIVATE_HOSTNAMES.has(address)) {
123
+ return { valid: false, reason: `DNS resolved to private address: ${hostname} → ${address}` };
124
+ }
125
+ }
126
+ catch {
127
+ // Retry once before giving up — handles transient DNS failures.
128
+ try {
129
+ const { address } = await dnsLookup(hostname);
130
+ if (isPrivateIp(address)) {
131
+ return { valid: false, reason: `DNS resolved to private address: ${hostname} → ${address}` };
132
+ }
133
+ if (PRIVATE_HOSTNAMES.has(address)) {
134
+ return { valid: false, reason: `DNS resolved to private address: ${hostname} → ${address}` };
135
+ }
136
+ }
137
+ catch {
138
+ // Fail-open when DNS is unavailable so public URLs are not blocked by local resolver issues.
139
+ return syncResult;
140
+ }
141
+ }
142
+ return syncResult;
143
+ }
80
144
  //# sourceMappingURL=url-validator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-validator.js","sourceRoot":"","sources":["../../src/utils/url-validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"url-validator.js","sourceRoot":"","sources":["../../src/utils/url-validator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-browser",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "AI-friendly browser with semantic output",
6
6
  "main": "dist/index.js",
@@ -27,7 +27,8 @@
27
27
  "test:run": "vitest run",
28
28
  "lint": "eslint src --ext .ts",
29
29
  "agent": "tsx src/agent/index.ts",
30
- "prepublishOnly": "npm run build"
30
+ "prepublishOnly": "npm run build",
31
+ "test:contract": "vitest run tests/login-keep-session.unit.test.ts tests/task-tools.test.ts tests/task-tools-login-contract.test.ts tests/task-tools-regression.test.ts"
31
32
  },
32
33
  "dependencies": {
33
34
  "@fastify/static": "^6.12.0",