@musashishao/agent-kit 1.8.1 → 1.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/.agent/agents/ai-architect.md +39 -0
- package/.agent/agents/cloud-engineer.md +39 -0
- package/.agent/agents/game-asset-curator.md +317 -0
- package/.agent/agents/game-developer.md +190 -89
- package/.agent/agents/game-narrative-designer.md +310 -0
- package/.agent/agents/game-qa-agent.md +441 -0
- package/.agent/agents/marketing-specialist.md +41 -0
- package/.agent/agents/penetration-tester.md +15 -1
- package/.agent/rules/CODEX.md +26 -2
- package/.agent/rules/GEMINI.md +7 -5
- package/.agent/rules/REFERENCE.md +92 -2
- package/.agent/scripts/ak_cli.py +1 -1
- package/.agent/scripts/localize_workflows.py +54 -0
- package/.agent/scripts/memory_manager.py +24 -1
- package/.agent/skills/3d-web-experience/SKILL.md +386 -0
- package/.agent/skills/DEPENDENCIES.md +54 -0
- package/.agent/skills/ab-test-setup/SKILL.md +77 -0
- package/.agent/skills/active-directory-attacks/SKILL.md +59 -0
- package/.agent/skills/agent-evaluation/SKILL.md +430 -0
- package/.agent/skills/agent-memory-systems/SKILL.md +426 -0
- package/.agent/skills/agent-tool-builder/SKILL.md +139 -0
- package/.agent/skills/ai-agents-architect/SKILL.md +115 -0
- package/.agent/skills/ai-product/SKILL.md +86 -0
- package/.agent/skills/ai-wrapper-product/SKILL.md +90 -0
- package/.agent/skills/analytics-tracking/SKILL.md +88 -0
- package/.agent/skills/api-fuzzing-bug-bounty/SKILL.md +66 -0
- package/.agent/skills/app-store-optimization/SKILL.md +66 -0
- package/.agent/skills/autonomous-agent-patterns/SKILL.md +414 -0
- package/.agent/skills/aws-penetration-testing/SKILL.md +50 -0
- package/.agent/skills/aws-serverless/SKILL.md +327 -0
- package/.agent/skills/azure-functions/SKILL.md +340 -0
- package/.agent/skills/broken-authentication/SKILL.md +53 -0
- package/.agent/skills/browser-automation/SKILL.md +408 -0
- package/.agent/skills/browser-extension-builder/SKILL.md +422 -0
- package/.agent/skills/bullmq-specialist/SKILL.md +424 -0
- package/.agent/skills/bun-development/SKILL.md +386 -0
- package/.agent/skills/burp-suite-testing/SKILL.md +60 -0
- package/.agent/skills/clerk-auth/SKILL.md +432 -0
- package/.agent/skills/cloud-penetration-testing/SKILL.md +51 -0
- package/.agent/skills/copywriting/SKILL.md +66 -0
- package/.agent/skills/crewai/SKILL.md +470 -0
- package/.agent/skills/discord-bot-architect/SKILL.md +447 -0
- package/.agent/skills/email-sequence/SKILL.md +73 -0
- package/.agent/skills/ethical-hacking-methodology/SKILL.md +67 -0
- package/.agent/skills/firebase/SKILL.md +377 -0
- package/.agent/skills/game-development/godot-expert/SKILL.md +462 -0
- package/.agent/skills/game-development/npc-ai-integration/SKILL.md +110 -0
- package/.agent/skills/game-development/procedural-generation/SKILL.md +168 -0
- package/.agent/skills/game-development/unity-integration/SKILL.md +358 -0
- package/.agent/skills/game-development/webgpu-shading/SKILL.md +209 -0
- package/.agent/skills/gcp-cloud-run/SKILL.md +358 -0
- package/.agent/skills/graphql/SKILL.md +492 -0
- package/.agent/skills/idor-testing/SKILL.md +64 -0
- package/.agent/skills/inngest/SKILL.md +128 -0
- package/.agent/skills/langfuse/SKILL.md +415 -0
- package/.agent/skills/langgraph/SKILL.md +360 -0
- package/.agent/skills/launch-strategy/SKILL.md +68 -0
- package/.agent/skills/linux-privilege-escalation/SKILL.md +62 -0
- package/.agent/skills/llm-app-patterns/SKILL.md +367 -0
- package/.agent/skills/marketing-ideas/SKILL.md +66 -0
- package/.agent/skills/metasploit-framework/SKILL.md +60 -0
- package/.agent/skills/micro-saas-launcher/SKILL.md +93 -0
- package/.agent/skills/neon-postgres/SKILL.md +339 -0
- package/.agent/skills/paid-ads/SKILL.md +64 -0
- package/.agent/skills/supabase-integration/SKILL.md +411 -0
- package/.agent/workflows/ai-agent.md +36 -0
- package/.agent/workflows/autofix.md +1 -0
- package/.agent/workflows/brainstorm.md +1 -0
- package/.agent/workflows/context.md +1 -0
- package/.agent/workflows/create.md +1 -0
- package/.agent/workflows/dashboard.md +1 -0
- package/.agent/workflows/debug.md +1 -0
- package/.agent/workflows/deploy.md +1 -0
- package/.agent/workflows/enhance.md +1 -0
- package/.agent/workflows/game-prototype.md +154 -0
- package/.agent/workflows/marketing.md +37 -0
- package/.agent/workflows/next.md +1 -0
- package/.agent/workflows/orchestrate.md +1 -0
- package/.agent/workflows/pentest.md +37 -0
- package/.agent/workflows/plan.md +1 -0
- package/.agent/workflows/preview.md +2 -1
- package/.agent/workflows/quality.md +1 -0
- package/.agent/workflows/saas.md +36 -0
- package/.agent/workflows/spec.md +1 -0
- package/.agent/workflows/status.md +1 -0
- package/.agent/workflows/test.md +1 -0
- package/.agent/workflows/ui-ux-pro-max.md +1 -0
- package/README.md +52 -24
- package/bin/cli.js +68 -3
- package/docs/CHANGELOG_AI_INFRA.md +30 -0
- package/docs/MIGRATION_GUIDE_V1.9.md +55 -0
- package/package.json +1 -1
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-automation
|
|
3
|
+
description: "Browser automation with Playwright and Puppeteer. Web scraping, E2E testing, screenshot capture, and PDF generation."
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 🌐 Browser Automation
|
|
8
|
+
|
|
9
|
+
You are a browser automation expert who builds reliable scraping pipelines, E2E tests, and automation workflows. You handle dynamic content, anti-bot measures, and scale across multiple pages.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## When to Use This Skill
|
|
14
|
+
|
|
15
|
+
- Web scraping and data extraction
|
|
16
|
+
- E2E testing automation
|
|
17
|
+
- Screenshot/PDF generation
|
|
18
|
+
- Form filling and submission
|
|
19
|
+
- Monitoring and alerting
|
|
20
|
+
- Social media automation
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Capabilities
|
|
25
|
+
|
|
26
|
+
- `playwright`
|
|
27
|
+
- `puppeteer`
|
|
28
|
+
- `web-scraping`
|
|
29
|
+
- `e2e-testing`
|
|
30
|
+
- `screenshot-capture`
|
|
31
|
+
- `pdf-generation`
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 1. Playwright Setup
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install playwright
|
|
39
|
+
npx playwright install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Basic Automation
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// scraper.ts
|
|
46
|
+
import { chromium, Browser, Page } from 'playwright';
|
|
47
|
+
|
|
48
|
+
async function scrape(url: string) {
|
|
49
|
+
const browser = await chromium.launch({
|
|
50
|
+
headless: true, // Set false for debugging
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const context = await browser.newContext({
|
|
54
|
+
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
|
|
55
|
+
viewport: { width: 1920, height: 1080 },
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const page = await context.newPage();
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
await page.goto(url, { waitUntil: 'networkidle' });
|
|
62
|
+
|
|
63
|
+
// Extract data
|
|
64
|
+
const data = await page.evaluate(() => {
|
|
65
|
+
const items = document.querySelectorAll('.product-card');
|
|
66
|
+
return Array.from(items).map(item => ({
|
|
67
|
+
title: item.querySelector('h2')?.textContent?.trim(),
|
|
68
|
+
price: item.querySelector('.price')?.textContent?.trim(),
|
|
69
|
+
image: item.querySelector('img')?.src,
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return data;
|
|
74
|
+
} finally {
|
|
75
|
+
await browser.close();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Waiting Strategies
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// Wait for selector
|
|
84
|
+
await page.waitForSelector('.content');
|
|
85
|
+
|
|
86
|
+
// Wait for text
|
|
87
|
+
await page.waitForSelector('text=Loading complete');
|
|
88
|
+
|
|
89
|
+
// Wait for network idle
|
|
90
|
+
await page.waitForLoadState('networkidle');
|
|
91
|
+
|
|
92
|
+
// Wait for navigation
|
|
93
|
+
await Promise.all([
|
|
94
|
+
page.waitForNavigation(),
|
|
95
|
+
page.click('a.next-page'),
|
|
96
|
+
]);
|
|
97
|
+
|
|
98
|
+
// Custom wait
|
|
99
|
+
await page.waitForFunction(() => {
|
|
100
|
+
return document.querySelectorAll('.item').length >= 10;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Wait with timeout
|
|
104
|
+
await page.waitForSelector('.slow-content', { timeout: 30000 });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 2. Form Automation
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
async function fillForm(page: Page) {
|
|
113
|
+
// Text input
|
|
114
|
+
await page.fill('input[name="email"]', 'user@example.com');
|
|
115
|
+
await page.fill('input[name="password"]', 'securepassword');
|
|
116
|
+
|
|
117
|
+
// Select dropdown
|
|
118
|
+
await page.selectOption('select[name="country"]', 'US');
|
|
119
|
+
|
|
120
|
+
// Checkbox
|
|
121
|
+
await page.check('input[name="terms"]');
|
|
122
|
+
|
|
123
|
+
// Radio button
|
|
124
|
+
await page.click('input[value="express"]');
|
|
125
|
+
|
|
126
|
+
// File upload
|
|
127
|
+
await page.setInputFiles('input[type="file"]', './document.pdf');
|
|
128
|
+
|
|
129
|
+
// Date input
|
|
130
|
+
await page.fill('input[type="date"]', '2024-12-25');
|
|
131
|
+
|
|
132
|
+
// Submit
|
|
133
|
+
await page.click('button[type="submit"]');
|
|
134
|
+
|
|
135
|
+
// Wait for success
|
|
136
|
+
await page.waitForSelector('.success-message');
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## 3. Authentication Handling
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Save session
|
|
146
|
+
async function loginAndSaveSession(page: Page) {
|
|
147
|
+
await page.goto('https://example.com/login');
|
|
148
|
+
await page.fill('#email', 'user@example.com');
|
|
149
|
+
await page.fill('#password', 'password');
|
|
150
|
+
await page.click('button[type="submit"]');
|
|
151
|
+
|
|
152
|
+
await page.waitForURL('**/dashboard');
|
|
153
|
+
|
|
154
|
+
// Save cookies
|
|
155
|
+
const cookies = await page.context().cookies();
|
|
156
|
+
await fs.writeFile('cookies.json', JSON.stringify(cookies));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Restore session
|
|
160
|
+
async function restoreSession(context: BrowserContext) {
|
|
161
|
+
const cookies = JSON.parse(await fs.readFile('cookies.json', 'utf-8'));
|
|
162
|
+
await context.addCookies(cookies);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Using storage state
|
|
166
|
+
async function saveStorageState() {
|
|
167
|
+
await context.storageState({ path: 'auth.json' });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Restore storage state
|
|
171
|
+
const context = await browser.newContext({
|
|
172
|
+
storageState: 'auth.json',
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 4. Handling Dynamic Content
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// Infinite scroll
|
|
182
|
+
async function scrapeInfiniteScroll(page: Page, maxItems: number) {
|
|
183
|
+
const items: any[] = [];
|
|
184
|
+
|
|
185
|
+
while (items.length < maxItems) {
|
|
186
|
+
// Get current items
|
|
187
|
+
const newItems = await page.$$eval('.item', els =>
|
|
188
|
+
els.map(el => el.textContent)
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
items.push(...newItems.filter(item => !items.includes(item)));
|
|
192
|
+
|
|
193
|
+
// Check if more content
|
|
194
|
+
const hasMore = await page.$('.load-more');
|
|
195
|
+
if (!hasMore) break;
|
|
196
|
+
|
|
197
|
+
// Scroll to bottom
|
|
198
|
+
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
|
|
199
|
+
|
|
200
|
+
// Wait for new content
|
|
201
|
+
await page.waitForTimeout(1000);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return items.slice(0, maxItems);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Handle lazy loading images
|
|
208
|
+
async function loadAllImages(page: Page) {
|
|
209
|
+
await page.evaluate(async () => {
|
|
210
|
+
const images = document.querySelectorAll('img[data-src]');
|
|
211
|
+
images.forEach(img => {
|
|
212
|
+
img.src = img.getAttribute('data-src')!;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Wait for all images to load
|
|
216
|
+
await Promise.all(
|
|
217
|
+
Array.from(images).map(img =>
|
|
218
|
+
new Promise(resolve => {
|
|
219
|
+
if (img.complete) resolve(null);
|
|
220
|
+
else img.onload = () => resolve(null);
|
|
221
|
+
})
|
|
222
|
+
)
|
|
223
|
+
);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 5. Screenshot & PDF
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
// Full page screenshot
|
|
234
|
+
await page.screenshot({
|
|
235
|
+
path: 'screenshot.png',
|
|
236
|
+
fullPage: true,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Element screenshot
|
|
240
|
+
const element = await page.$('.chart');
|
|
241
|
+
await element?.screenshot({ path: 'chart.png' });
|
|
242
|
+
|
|
243
|
+
// PDF generation
|
|
244
|
+
await page.pdf({
|
|
245
|
+
path: 'document.pdf',
|
|
246
|
+
format: 'A4',
|
|
247
|
+
margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' },
|
|
248
|
+
printBackground: true,
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Screenshot with clip
|
|
252
|
+
await page.screenshot({
|
|
253
|
+
path: 'cropped.png',
|
|
254
|
+
clip: { x: 0, y: 0, width: 800, height: 600 },
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 6. Parallel Execution
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
import { chromium, Browser } from 'playwright';
|
|
264
|
+
|
|
265
|
+
async function scrapeMultipleUrls(urls: string[]) {
|
|
266
|
+
const browser = await chromium.launch();
|
|
267
|
+
|
|
268
|
+
// Limit concurrency
|
|
269
|
+
const CONCURRENCY = 5;
|
|
270
|
+
const results: any[] = [];
|
|
271
|
+
|
|
272
|
+
for (let i = 0; i < urls.length; i += CONCURRENCY) {
|
|
273
|
+
const batch = urls.slice(i, i + CONCURRENCY);
|
|
274
|
+
|
|
275
|
+
const batchResults = await Promise.all(
|
|
276
|
+
batch.map(url => scrapePage(browser, url))
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
results.push(...batchResults);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
await browser.close();
|
|
283
|
+
return results;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
async function scrapePage(browser: Browser, url: string) {
|
|
287
|
+
const context = await browser.newContext();
|
|
288
|
+
const page = await context.newPage();
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
await page.goto(url);
|
|
292
|
+
const data = await extractData(page);
|
|
293
|
+
return { url, data, success: true };
|
|
294
|
+
} catch (error) {
|
|
295
|
+
return { url, error: error.message, success: false };
|
|
296
|
+
} finally {
|
|
297
|
+
await context.close();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 7. Anti-Detection
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
const context = await browser.newContext({
|
|
308
|
+
userAgent: randomUserAgent(),
|
|
309
|
+
viewport: { width: 1920, height: 1080 },
|
|
310
|
+
locale: 'en-US',
|
|
311
|
+
timezoneId: 'America/New_York',
|
|
312
|
+
geolocation: { latitude: 40.7128, longitude: -74.0060 },
|
|
313
|
+
permissions: ['geolocation'],
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// Stealth mode
|
|
317
|
+
await page.addInitScript(() => {
|
|
318
|
+
// Override webdriver detection
|
|
319
|
+
Object.defineProperty(navigator, 'webdriver', {
|
|
320
|
+
get: () => false,
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Override plugins
|
|
324
|
+
Object.defineProperty(navigator, 'plugins', {
|
|
325
|
+
get: () => [1, 2, 3, 4, 5],
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// Random delays
|
|
330
|
+
async function humanDelay() {
|
|
331
|
+
const delay = Math.random() * 2000 + 500;
|
|
332
|
+
await page.waitForTimeout(delay);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Human-like typing
|
|
336
|
+
await page.type('input', 'Hello World', { delay: 100 });
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## 8. Error Handling
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
async function resilientScrape(url: string, maxRetries = 3) {
|
|
345
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
346
|
+
const browser = await chromium.launch();
|
|
347
|
+
|
|
348
|
+
try {
|
|
349
|
+
const page = await browser.newPage();
|
|
350
|
+
|
|
351
|
+
// Set timeout
|
|
352
|
+
page.setDefaultTimeout(30000);
|
|
353
|
+
|
|
354
|
+
await page.goto(url, { waitUntil: 'domcontentloaded' });
|
|
355
|
+
|
|
356
|
+
const data = await extractData(page);
|
|
357
|
+
return data;
|
|
358
|
+
|
|
359
|
+
} catch (error) {
|
|
360
|
+
console.error(`Attempt ${attempt} failed:`, error.message);
|
|
361
|
+
|
|
362
|
+
if (attempt === maxRetries) {
|
|
363
|
+
throw error;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Exponential backoff
|
|
367
|
+
await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));
|
|
368
|
+
|
|
369
|
+
} finally {
|
|
370
|
+
await browser.close();
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 9. Anti-Patterns
|
|
379
|
+
|
|
380
|
+
### ❌ No Error Handling
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
// WRONG
|
|
384
|
+
const data = await page.$eval('.content', el => el.textContent);
|
|
385
|
+
|
|
386
|
+
// CORRECT
|
|
387
|
+
const element = await page.$('.content');
|
|
388
|
+
const data = element ? await element.textContent() : null;
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### ❌ Hard-Coded Waits
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
// WRONG
|
|
395
|
+
await page.waitForTimeout(5000);
|
|
396
|
+
|
|
397
|
+
// CORRECT
|
|
398
|
+
await page.waitForSelector('.content');
|
|
399
|
+
await page.waitForLoadState('networkidle');
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Related Skills
|
|
405
|
+
|
|
406
|
+
- `webapp-testing` - E2E testing
|
|
407
|
+
- `nodejs-best-practices` - Node.js patterns
|
|
408
|
+
- `api-patterns` - API scraping alternative
|