@yuaone/tools 0.1.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 (87) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +15 -0
  3. package/dist/__tests__/file-edit.test.d.ts +8 -0
  4. package/dist/__tests__/file-edit.test.d.ts.map +1 -0
  5. package/dist/__tests__/file-edit.test.js +125 -0
  6. package/dist/__tests__/file-edit.test.js.map +1 -0
  7. package/dist/__tests__/registry.test.d.ts +7 -0
  8. package/dist/__tests__/registry.test.d.ts.map +1 -0
  9. package/dist/__tests__/registry.test.js +83 -0
  10. package/dist/__tests__/registry.test.js.map +1 -0
  11. package/dist/__tests__/validators.test.d.ts +8 -0
  12. package/dist/__tests__/validators.test.d.ts.map +1 -0
  13. package/dist/__tests__/validators.test.js +189 -0
  14. package/dist/__tests__/validators.test.js.map +1 -0
  15. package/dist/base-tool.d.ts +45 -0
  16. package/dist/base-tool.d.ts.map +1 -0
  17. package/dist/base-tool.js +87 -0
  18. package/dist/base-tool.js.map +1 -0
  19. package/dist/browser-tool.d.ts +39 -0
  20. package/dist/browser-tool.d.ts.map +1 -0
  21. package/dist/browser-tool.js +518 -0
  22. package/dist/browser-tool.js.map +1 -0
  23. package/dist/code-search.d.ts +42 -0
  24. package/dist/code-search.d.ts.map +1 -0
  25. package/dist/code-search.js +298 -0
  26. package/dist/code-search.js.map +1 -0
  27. package/dist/design-tools.d.ts +70 -0
  28. package/dist/design-tools.d.ts.map +1 -0
  29. package/dist/design-tools.js +471 -0
  30. package/dist/design-tools.js.map +1 -0
  31. package/dist/dev-server-manager.d.ts +32 -0
  32. package/dist/dev-server-manager.d.ts.map +1 -0
  33. package/dist/dev-server-manager.js +183 -0
  34. package/dist/dev-server-manager.js.map +1 -0
  35. package/dist/file-edit.d.ts +19 -0
  36. package/dist/file-edit.d.ts.map +1 -0
  37. package/dist/file-edit.js +217 -0
  38. package/dist/file-edit.js.map +1 -0
  39. package/dist/file-read.d.ts +19 -0
  40. package/dist/file-read.d.ts.map +1 -0
  41. package/dist/file-read.js +142 -0
  42. package/dist/file-read.js.map +1 -0
  43. package/dist/file-write.d.ts +18 -0
  44. package/dist/file-write.d.ts.map +1 -0
  45. package/dist/file-write.js +139 -0
  46. package/dist/file-write.js.map +1 -0
  47. package/dist/git-ops.d.ts +25 -0
  48. package/dist/git-ops.d.ts.map +1 -0
  49. package/dist/git-ops.js +219 -0
  50. package/dist/git-ops.js.map +1 -0
  51. package/dist/glob.d.ts +18 -0
  52. package/dist/glob.d.ts.map +1 -0
  53. package/dist/glob.js +91 -0
  54. package/dist/glob.js.map +1 -0
  55. package/dist/grep.d.ts +19 -0
  56. package/dist/grep.d.ts.map +1 -0
  57. package/dist/grep.js +177 -0
  58. package/dist/grep.js.map +1 -0
  59. package/dist/index.d.ts +27 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +29 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/security-scan.d.ts +62 -0
  64. package/dist/security-scan.d.ts.map +1 -0
  65. package/dist/security-scan.js +445 -0
  66. package/dist/security-scan.js.map +1 -0
  67. package/dist/shell-exec.d.ts +20 -0
  68. package/dist/shell-exec.d.ts.map +1 -0
  69. package/dist/shell-exec.js +206 -0
  70. package/dist/shell-exec.js.map +1 -0
  71. package/dist/test-run.d.ts +51 -0
  72. package/dist/test-run.d.ts.map +1 -0
  73. package/dist/test-run.js +359 -0
  74. package/dist/test-run.js.map +1 -0
  75. package/dist/tool-registry.d.ts +70 -0
  76. package/dist/tool-registry.d.ts.map +1 -0
  77. package/dist/tool-registry.js +181 -0
  78. package/dist/tool-registry.js.map +1 -0
  79. package/dist/types.d.ts +137 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +8 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/validators.d.ts +57 -0
  84. package/dist/validators.d.ts.map +1 -0
  85. package/dist/validators.js +218 -0
  86. package/dist/validators.js.map +1 -0
  87. package/package.json +42 -0
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @yuaone/tools — Browser Visual Debugging Tool
3
+ *
4
+ * Provides browser automation for visual debugging:
5
+ * - browser open: Launch browser and navigate to URL
6
+ * - browser screenshot: Capture page screenshot (returns base64)
7
+ * - browser click: Click an element by selector
8
+ * - browser type: Type text into an element
9
+ * - browser evaluate: Execute JavaScript in page context
10
+ * - browser dom: Extract DOM structure for analysis
11
+ * - browser close: Close browser
12
+ *
13
+ * Uses Playwright for cross-browser automation.
14
+ * Screenshots are returned as base64 for LLM vision analysis.
15
+ *
16
+ * Security constraints:
17
+ * - Only localhost / 127.0.0.1 / file:// URLs allowed
18
+ * - Script evaluation timeout: 5s
19
+ * - Script length limit: 10KB
20
+ * - DOM extraction depth: 5 levels, max 500 nodes
21
+ * - Max 5 concurrent sessions, 5-minute timeout
22
+ */
23
+ import type { ParameterDef, RiskLevel, ToolResult } from './types.js';
24
+ import { BaseTool } from './base-tool.js';
25
+ export declare class BrowserTool extends BaseTool {
26
+ readonly name = "browser";
27
+ readonly description: string;
28
+ readonly riskLevel: RiskLevel;
29
+ readonly parameters: Record<string, ParameterDef>;
30
+ execute(args: Record<string, unknown>, workDir: string, _abortSignal?: AbortSignal): Promise<ToolResult>;
31
+ private browserOpen;
32
+ private browserScreenshot;
33
+ private browserClick;
34
+ private browserType;
35
+ private browserEvaluate;
36
+ private browserDom;
37
+ private browserClose;
38
+ }
39
+ //# sourceMappingURL=browser-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-tool.d.ts","sourceRoot":"","sources":["../src/browser-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAsK1C,qBAAa,WAAY,SAAQ,QAAQ;IACvC,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,WAAW,SAI8C;IAClE,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAU;IAEvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAgD/C;IAEI,OAAO,CACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,WAAW,GACzB,OAAO,CAAC,UAAU,CAAC;YAkCR,WAAW;YAkEX,iBAAiB;YA8CjB,YAAY;YA+DZ,WAAW;YAiDX,eAAe;YA2Ef,UAAU;YAsCV,YAAY;CAwC3B"}
@@ -0,0 +1,518 @@
1
+ /**
2
+ * @yuaone/tools — Browser Visual Debugging Tool
3
+ *
4
+ * Provides browser automation for visual debugging:
5
+ * - browser open: Launch browser and navigate to URL
6
+ * - browser screenshot: Capture page screenshot (returns base64)
7
+ * - browser click: Click an element by selector
8
+ * - browser type: Type text into an element
9
+ * - browser evaluate: Execute JavaScript in page context
10
+ * - browser dom: Extract DOM structure for analysis
11
+ * - browser close: Close browser
12
+ *
13
+ * Uses Playwright for cross-browser automation.
14
+ * Screenshots are returned as base64 for LLM vision analysis.
15
+ *
16
+ * Security constraints:
17
+ * - Only localhost / 127.0.0.1 / file:// URLs allowed
18
+ * - Script evaluation timeout: 5s
19
+ * - Script length limit: 10KB
20
+ * - DOM extraction depth: 5 levels, max 500 nodes
21
+ * - Max 5 concurrent sessions, 5-minute timeout
22
+ */
23
+ import { BaseTool } from './base-tool.js';
24
+ // ---------------------------------------------------------------------------
25
+ // Lazy-load Playwright so the tool doesn't crash if not installed
26
+ // ---------------------------------------------------------------------------
27
+ let playwrightModule = null;
28
+ async function getPlaywright() {
29
+ if (!playwrightModule) {
30
+ try {
31
+ // Dynamic import with variable to prevent TypeScript from resolving the module
32
+ const moduleName = 'playwright';
33
+ playwrightModule = await Function('m', 'return import(m)')(moduleName);
34
+ }
35
+ catch {
36
+ throw new Error('Playwright is not installed. Run: pnpm --filter @yuaone/tools add playwright && npx playwright install chromium');
37
+ }
38
+ }
39
+ return playwrightModule;
40
+ }
41
+ const sessions = new Map();
42
+ const MAX_SESSIONS = 5;
43
+ const SESSION_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
44
+ /** Generate a short random session ID. */
45
+ function generateSessionId() {
46
+ return `bs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
47
+ }
48
+ /** Evict expired sessions. */
49
+ async function evictExpiredSessions() {
50
+ const now = Date.now();
51
+ for (const [id, session] of sessions) {
52
+ if (now - session.createdAt > SESSION_TIMEOUT_MS) {
53
+ try {
54
+ await session.browser?.close();
55
+ }
56
+ catch {
57
+ // ignore
58
+ }
59
+ sessions.delete(id);
60
+ }
61
+ }
62
+ }
63
+ /** Get a session or return an error ToolResult. */
64
+ function getSession(sessionId) {
65
+ if (!sessionId)
66
+ return null;
67
+ const session = sessions.get(sessionId);
68
+ if (!session)
69
+ return null;
70
+ // Check if expired
71
+ if (Date.now() - session.createdAt > SESSION_TIMEOUT_MS) {
72
+ session.browser?.close().catch(() => { });
73
+ sessions.delete(sessionId);
74
+ return null;
75
+ }
76
+ return session;
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // URL validation — only allow safe local URLs
80
+ // ---------------------------------------------------------------------------
81
+ const ALLOWED_URL_PATTERNS = [
82
+ /^https?:\/\/localhost(:\d+)?(\/|$)/,
83
+ /^https?:\/\/127\.0\.0\.1(:\d+)?(\/|$)/,
84
+ /^https?:\/\/0\.0\.0\.0(:\d+)?(\/|$)/,
85
+ /^https?:\/\/\[::1\](:\d+)?(\/|$)/,
86
+ /^file:\/\//,
87
+ ];
88
+ function isAllowedUrl(url) {
89
+ return ALLOWED_URL_PATTERNS.some((p) => p.test(url));
90
+ }
91
+ // ---------------------------------------------------------------------------
92
+ // DOM extraction helpers
93
+ // ---------------------------------------------------------------------------
94
+ const MAX_DOM_DEPTH = 5;
95
+ const MAX_DOM_NODES = 500;
96
+ /**
97
+ * Script injected into the page to extract a simplified DOM tree.
98
+ * Returns a serializable object with tag, id, class, text, and children.
99
+ */
100
+ function buildDomExtractionScript(maxDepth, maxNodes) {
101
+ return `
102
+ (() => {
103
+ let nodeCount = 0;
104
+ const MAX_DEPTH = ${maxDepth};
105
+ const MAX_NODES = ${maxNodes};
106
+ const SKIP_TAGS = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'SVG', 'PATH']);
107
+
108
+ function extract(el, depth) {
109
+ if (depth > MAX_DEPTH || nodeCount >= MAX_NODES) return null;
110
+ if (!el || !el.tagName) return null;
111
+ if (SKIP_TAGS.has(el.tagName)) return null;
112
+
113
+ nodeCount++;
114
+
115
+ const node = {
116
+ tag: el.tagName.toLowerCase(),
117
+ };
118
+
119
+ if (el.id) node.id = el.id;
120
+ if (el.className && typeof el.className === 'string' && el.className.trim()) {
121
+ node.cls = el.className.trim().split(/\\s+/).slice(0, 5).join(' ');
122
+ }
123
+
124
+ // Direct text content (not from children)
125
+ const textContent = Array.from(el.childNodes)
126
+ .filter(n => n.nodeType === 3)
127
+ .map(n => n.textContent?.trim())
128
+ .filter(Boolean)
129
+ .join(' ')
130
+ .slice(0, 100);
131
+
132
+ if (textContent) node.text = textContent;
133
+
134
+ // Useful attributes
135
+ if (el.href) node.href = el.href;
136
+ if (el.src) node.src = el.src;
137
+ if (el.type) node.type = el.type;
138
+ if (el.name) node.name = el.name;
139
+ if (el.value && el.value.length < 100) node.value = el.value;
140
+ if (el.placeholder) node.placeholder = el.placeholder;
141
+
142
+ // Children
143
+ if (depth < MAX_DEPTH && el.children && el.children.length > 0) {
144
+ const children = [];
145
+ for (const child of el.children) {
146
+ if (nodeCount >= MAX_NODES) break;
147
+ const childNode = extract(child, depth + 1);
148
+ if (childNode) children.push(childNode);
149
+ }
150
+ if (children.length > 0) node.children = children;
151
+ }
152
+
153
+ return node;
154
+ }
155
+
156
+ return extract(document.body, 0);
157
+ })()
158
+ `;
159
+ }
160
+ // ---------------------------------------------------------------------------
161
+ // BrowserTool
162
+ // ---------------------------------------------------------------------------
163
+ export class BrowserTool extends BaseTool {
164
+ name = 'browser';
165
+ description = 'Browser automation for visual debugging. ' +
166
+ 'Actions: open, screenshot, click, type, evaluate, dom, close. ' +
167
+ 'Screenshots are returned as base64 for visual analysis. ' +
168
+ 'Only localhost/127.0.0.1/file:// URLs are allowed (security).';
169
+ riskLevel = 'high';
170
+ parameters = {
171
+ action: {
172
+ type: 'string',
173
+ description: 'Browser action to perform',
174
+ required: true,
175
+ enum: ['open', 'screenshot', 'click', 'type', 'evaluate', 'dom', 'close'],
176
+ },
177
+ url: {
178
+ type: 'string',
179
+ description: 'URL to navigate to (for open action). Only localhost/127.0.0.1/file:// allowed.',
180
+ required: false,
181
+ },
182
+ selector: {
183
+ type: 'string',
184
+ description: 'CSS selector for target element (for click, type actions)',
185
+ required: false,
186
+ },
187
+ text: {
188
+ type: 'string',
189
+ description: 'Text to type (for type action)',
190
+ required: false,
191
+ },
192
+ script: {
193
+ type: 'string',
194
+ description: 'JavaScript to evaluate in page context (for evaluate action, max 10KB)',
195
+ required: false,
196
+ },
197
+ sessionId: {
198
+ type: 'string',
199
+ description: 'Browser session ID. Auto-generated on open; reuse for subsequent actions.',
200
+ required: false,
201
+ },
202
+ fullPage: {
203
+ type: 'boolean',
204
+ description: 'Capture full page screenshot (default: false)',
205
+ required: false,
206
+ default: false,
207
+ },
208
+ viewport: {
209
+ type: 'object',
210
+ description: 'Viewport size { width, height } for open action (default: 1280x720)',
211
+ required: false,
212
+ },
213
+ waitFor: {
214
+ type: 'string',
215
+ description: 'CSS selector to wait for before performing action',
216
+ required: false,
217
+ },
218
+ };
219
+ async execute(args, workDir, _abortSignal) {
220
+ const toolCallId = args._toolCallId ?? '';
221
+ const action = args.action;
222
+ // Evict expired sessions before every action
223
+ await evictExpiredSessions();
224
+ try {
225
+ switch (action) {
226
+ case 'open':
227
+ return await this.browserOpen(toolCallId, args);
228
+ case 'screenshot':
229
+ return await this.browserScreenshot(toolCallId, args);
230
+ case 'click':
231
+ return await this.browserClick(toolCallId, args);
232
+ case 'type':
233
+ return await this.browserType(toolCallId, args);
234
+ case 'evaluate':
235
+ return await this.browserEvaluate(toolCallId, args);
236
+ case 'dom':
237
+ return await this.browserDom(toolCallId, args);
238
+ case 'close':
239
+ return await this.browserClose(toolCallId, args);
240
+ default:
241
+ return this.fail(toolCallId, `Unknown browser action: ${action}. Valid actions: open, screenshot, click, type, evaluate, dom, close`);
242
+ }
243
+ }
244
+ catch (err) {
245
+ const message = err instanceof Error ? err.message : String(err);
246
+ return this.fail(toolCallId, `Browser action "${action}" failed: ${message}`);
247
+ }
248
+ }
249
+ // ─── open ──────────────────────────────────────────────────────────
250
+ async browserOpen(toolCallId, args) {
251
+ const url = args.url;
252
+ if (!url) {
253
+ return this.fail(toolCallId, 'Missing required parameter: url');
254
+ }
255
+ // Security: only allow local URLs
256
+ if (!isAllowedUrl(url)) {
257
+ return this.fail(toolCallId, `URL not allowed: "${url}". Only localhost, 127.0.0.1, 0.0.0.0, [::1], and file:// URLs are permitted.`);
258
+ }
259
+ // Enforce session limit
260
+ if (sessions.size >= MAX_SESSIONS) {
261
+ return this.fail(toolCallId, `Maximum concurrent browser sessions reached (${MAX_SESSIONS}). Close an existing session first.`);
262
+ }
263
+ const pw = await getPlaywright();
264
+ const viewport = args.viewport;
265
+ const vw = viewport?.width ?? 1280;
266
+ const vh = viewport?.height ?? 720;
267
+ const browser = await pw.chromium.launch({ headless: true });
268
+ const context = await browser.newContext({
269
+ viewport: { width: vw, height: vh },
270
+ ignoreHTTPSErrors: true,
271
+ });
272
+ const page = await context.newPage();
273
+ // Navigate
274
+ await page.goto(url, {
275
+ waitUntil: 'networkidle',
276
+ timeout: 30_000,
277
+ });
278
+ const sessionId = generateSessionId();
279
+ sessions.set(sessionId, {
280
+ browser,
281
+ context,
282
+ page,
283
+ createdAt: Date.now(),
284
+ });
285
+ const title = await page.title();
286
+ return this.ok(toolCallId, JSON.stringify({
287
+ sessionId,
288
+ title,
289
+ url: page.url(),
290
+ viewport: { width: vw, height: vh },
291
+ }));
292
+ }
293
+ // ─── screenshot ────────────────────────────────────────────────────
294
+ async browserScreenshot(toolCallId, args) {
295
+ const sessionId = args.sessionId;
296
+ const session = getSession(sessionId);
297
+ if (!session) {
298
+ return this.fail(toolCallId, sessionId
299
+ ? `Session not found or expired: ${sessionId}`
300
+ : 'Missing required parameter: sessionId');
301
+ }
302
+ const fullPage = args.fullPage ?? false;
303
+ const waitFor = args.waitFor;
304
+ if (waitFor) {
305
+ await session.page.waitForSelector(waitFor, { timeout: 10_000 });
306
+ }
307
+ const screenshotBuffer = await session.page.screenshot({
308
+ fullPage,
309
+ type: 'png',
310
+ });
311
+ const base64 = screenshotBuffer.toString('base64');
312
+ const title = await session.page.title();
313
+ return this.ok(toolCallId, JSON.stringify({
314
+ sessionId,
315
+ title,
316
+ url: session.page.url(),
317
+ fullPage,
318
+ imageBase64: base64,
319
+ imageMimeType: 'image/png',
320
+ imageSizeBytes: screenshotBuffer.byteLength,
321
+ }));
322
+ }
323
+ // ─── click ─────────────────────────────────────────────────────────
324
+ async browserClick(toolCallId, args) {
325
+ const sessionId = args.sessionId;
326
+ const session = getSession(sessionId);
327
+ if (!session) {
328
+ return this.fail(toolCallId, sessionId
329
+ ? `Session not found or expired: ${sessionId}`
330
+ : 'Missing required parameter: sessionId');
331
+ }
332
+ const selector = args.selector;
333
+ if (!selector) {
334
+ return this.fail(toolCallId, 'Missing required parameter: selector');
335
+ }
336
+ const waitFor = args.waitFor;
337
+ if (waitFor) {
338
+ await session.page.waitForSelector(waitFor, { timeout: 10_000 });
339
+ }
340
+ // Wait for the target element
341
+ await session.page.waitForSelector(selector, { timeout: 10_000 });
342
+ // Get element info before clicking (evaluate as string to avoid TS DOM type issues)
343
+ const elementInfoScript = `
344
+ (() => {
345
+ const el = document.querySelector(${JSON.stringify(selector)});
346
+ if (!el) return null;
347
+ return {
348
+ tag: el.tagName.toLowerCase(),
349
+ text: (el.textContent || '').trim().slice(0, 100),
350
+ id: el.id || undefined,
351
+ className: el.className && typeof el.className === 'string'
352
+ ? el.className.trim().slice(0, 100)
353
+ : undefined,
354
+ };
355
+ })()
356
+ `;
357
+ const elementInfo = await session.page.evaluate(elementInfoScript);
358
+ // Click and wait for any navigation or network activity to settle
359
+ await session.page.click(selector);
360
+ await session.page.waitForLoadState('networkidle', { timeout: 5_000 }).catch(() => { });
361
+ return this.ok(toolCallId, JSON.stringify({
362
+ sessionId,
363
+ action: 'click',
364
+ selector,
365
+ element: elementInfo,
366
+ url: session.page.url(),
367
+ }));
368
+ }
369
+ // ─── type ──────────────────────────────────────────────────────────
370
+ async browserType(toolCallId, args) {
371
+ const sessionId = args.sessionId;
372
+ const session = getSession(sessionId);
373
+ if (!session) {
374
+ return this.fail(toolCallId, sessionId
375
+ ? `Session not found or expired: ${sessionId}`
376
+ : 'Missing required parameter: sessionId');
377
+ }
378
+ const selector = args.selector;
379
+ if (!selector) {
380
+ return this.fail(toolCallId, 'Missing required parameter: selector');
381
+ }
382
+ const text = args.text;
383
+ if (text === undefined || text === null) {
384
+ return this.fail(toolCallId, 'Missing required parameter: text');
385
+ }
386
+ const waitFor = args.waitFor;
387
+ if (waitFor) {
388
+ await session.page.waitForSelector(waitFor, { timeout: 10_000 });
389
+ }
390
+ // Wait for the target element
391
+ await session.page.waitForSelector(selector, { timeout: 10_000 });
392
+ // Use fill() to clear and set value (works for input/textarea)
393
+ await session.page.fill(selector, text);
394
+ return this.ok(toolCallId, JSON.stringify({
395
+ sessionId,
396
+ action: 'type',
397
+ selector,
398
+ textLength: text.length,
399
+ }));
400
+ }
401
+ // ─── evaluate ──────────────────────────────────────────────────────
402
+ async browserEvaluate(toolCallId, args) {
403
+ const sessionId = args.sessionId;
404
+ const session = getSession(sessionId);
405
+ if (!session) {
406
+ return this.fail(toolCallId, sessionId
407
+ ? `Session not found or expired: ${sessionId}`
408
+ : 'Missing required parameter: sessionId');
409
+ }
410
+ const script = args.script;
411
+ if (!script) {
412
+ return this.fail(toolCallId, 'Missing required parameter: script');
413
+ }
414
+ // Security: limit script length
415
+ const MAX_SCRIPT_LENGTH = 10 * 1024; // 10KB
416
+ if (script.length > MAX_SCRIPT_LENGTH) {
417
+ return this.fail(toolCallId, `Script too long: ${script.length} bytes (max ${MAX_SCRIPT_LENGTH} bytes)`);
418
+ }
419
+ const waitFor = args.waitFor;
420
+ if (waitFor) {
421
+ await session.page.waitForSelector(waitFor, { timeout: 10_000 });
422
+ }
423
+ // Evaluate with timeout
424
+ const EVAL_TIMEOUT = 5_000;
425
+ let result;
426
+ try {
427
+ result = await Promise.race([
428
+ session.page.evaluate(script),
429
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Script evaluation timed out (5s)')), EVAL_TIMEOUT)),
430
+ ]);
431
+ }
432
+ catch (err) {
433
+ const msg = err instanceof Error ? err.message : String(err);
434
+ return this.fail(toolCallId, `Script evaluation error: ${msg}`);
435
+ }
436
+ // Serialize result
437
+ let serialized;
438
+ try {
439
+ serialized = JSON.stringify(result, null, 2);
440
+ }
441
+ catch {
442
+ serialized = String(result);
443
+ }
444
+ // Limit output size
445
+ const MAX_OUTPUT = 50 * 1024; // 50KB
446
+ if (serialized.length > MAX_OUTPUT) {
447
+ serialized = serialized.slice(0, MAX_OUTPUT) + '\n...(truncated)';
448
+ }
449
+ return this.ok(toolCallId, JSON.stringify({
450
+ sessionId,
451
+ action: 'evaluate',
452
+ result: serialized,
453
+ }));
454
+ }
455
+ // ─── dom ───────────────────────────────────────────────────────────
456
+ async browserDom(toolCallId, args) {
457
+ const sessionId = args.sessionId;
458
+ const session = getSession(sessionId);
459
+ if (!session) {
460
+ return this.fail(toolCallId, sessionId
461
+ ? `Session not found or expired: ${sessionId}`
462
+ : 'Missing required parameter: sessionId');
463
+ }
464
+ const waitFor = args.waitFor;
465
+ if (waitFor) {
466
+ await session.page.waitForSelector(waitFor, { timeout: 10_000 });
467
+ }
468
+ const domScript = buildDomExtractionScript(MAX_DOM_DEPTH, MAX_DOM_NODES);
469
+ const domTree = await session.page.evaluate(domScript);
470
+ const title = await session.page.title();
471
+ return this.ok(toolCallId, JSON.stringify({
472
+ sessionId,
473
+ title,
474
+ url: session.page.url(),
475
+ dom: domTree,
476
+ }));
477
+ }
478
+ // ─── close ─────────────────────────────────────────────────────────
479
+ async browserClose(toolCallId, args) {
480
+ const sessionId = args.sessionId;
481
+ // If no sessionId, close all sessions
482
+ if (!sessionId) {
483
+ const count = sessions.size;
484
+ for (const [id, session] of sessions) {
485
+ try {
486
+ await session.browser?.close();
487
+ }
488
+ catch {
489
+ // ignore
490
+ }
491
+ sessions.delete(id);
492
+ }
493
+ return this.ok(toolCallId, JSON.stringify({ action: 'close', closedSessions: count }));
494
+ }
495
+ const session = sessions.get(sessionId);
496
+ if (!session) {
497
+ return this.fail(toolCallId, `Session not found: ${sessionId}`);
498
+ }
499
+ try {
500
+ await session.browser?.close();
501
+ }
502
+ catch {
503
+ // ignore
504
+ }
505
+ sessions.delete(sessionId);
506
+ return this.ok(toolCallId, JSON.stringify({ action: 'close', sessionId }));
507
+ }
508
+ }
509
+ // ---------------------------------------------------------------------------
510
+ // Cleanup all sessions on process exit
511
+ // ---------------------------------------------------------------------------
512
+ process.on('exit', () => {
513
+ for (const [, session] of sessions) {
514
+ session.browser?.close?.().catch(() => { });
515
+ }
516
+ sessions.clear();
517
+ });
518
+ //# sourceMappingURL=browser-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-tool.js","sourceRoot":"","sources":["../src/browser-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @yuaone/tools — code_search tool
3
+ *
4
+ * Phase 1: Symbol-based code search using regex patterns.
5
+ * (Embedding-based semantic search planned for Phase 2)
6
+ *
7
+ * Search modes:
8
+ * 1. symbol: Find function/class/variable/type/interface definitions by name
9
+ * 2. reference: Find usages of a specific symbol
10
+ * 3. definition: Find where a symbol is defined
11
+ *
12
+ * Supports: TypeScript, JavaScript, Python
13
+ * Excludes: node_modules, dist, .git, build, coverage, __pycache__
14
+ *
15
+ * riskLevel: 'low' (read-only)
16
+ */
17
+ import type { ParameterDef, RiskLevel, ToolResult } from './types.js';
18
+ import { BaseTool } from './base-tool.js';
19
+ export declare class CodeSearchTool extends BaseTool {
20
+ readonly name = "code_search";
21
+ readonly description: string;
22
+ readonly riskLevel: RiskLevel;
23
+ readonly parameters: Record<string, ParameterDef>;
24
+ execute(args: Record<string, unknown>, workDir: string): Promise<ToolResult>;
25
+ /**
26
+ * Search a single file for matching symbols.
27
+ */
28
+ private searchFile;
29
+ /**
30
+ * Infer the kind of symbol from the line content.
31
+ */
32
+ private inferKind;
33
+ /**
34
+ * Get a snippet with context lines around a match.
35
+ */
36
+ private getSnippet;
37
+ /**
38
+ * Format results for output.
39
+ */
40
+ private formatResults;
41
+ }
42
+ //# sourceMappingURL=code-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-search.d.ts","sourceRoot":"","sources":["../src/code-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AA2D1C,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,WAAW,SAGyB;IAC7C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAS;IAEtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CA8B/C;IAEI,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAyElF;;OAEG;IACH,OAAO,CAAC,UAAU;IAqElB;;OAEG;IACH,OAAO,CAAC,SAAS;IAiBjB;;OAEG;IACH,OAAO,CAAC,UAAU;IAalB;;OAEG;IACH,OAAO,CAAC,aAAa;CAiBtB"}