@phuetz/code-buddy 0.1.0 → 0.1.2

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 (305) hide show
  1. package/.codebuddy/skills/bundled/brave-search/SKILL.md +490 -0
  2. package/.codebuddy/skills/bundled/exa-search/SKILL.md +1122 -0
  3. package/.codebuddy/skills/bundled/perplexity/SKILL.md +748 -0
  4. package/.codebuddy/skills/bundled/playwright/SKILL.md +520 -0
  5. package/.codebuddy/skills/bundled/puppeteer/SKILL.md +708 -0
  6. package/.codebuddy/skills/bundled/web-fetch/SKILL.md +1003 -0
  7. package/README.md +56 -0
  8. package/dist/agent/agent-state.d.ts +3 -3
  9. package/dist/agent/agent-state.js +6 -6
  10. package/dist/agent/agent-state.js.map +1 -1
  11. package/dist/agent/base-agent.d.ts +4 -4
  12. package/dist/agent/base-agent.js +22 -9
  13. package/dist/agent/base-agent.js.map +1 -1
  14. package/dist/agent/cache-trace.d.ts +56 -0
  15. package/dist/agent/cache-trace.js +98 -0
  16. package/dist/agent/cache-trace.js.map +1 -0
  17. package/dist/agent/codebuddy-agent.js +4 -2
  18. package/dist/agent/codebuddy-agent.js.map +1 -1
  19. package/dist/agent/execution/agent-executor.d.ts +4 -4
  20. package/dist/agent/execution/agent-executor.js +46 -14
  21. package/dist/agent/execution/agent-executor.js.map +1 -1
  22. package/dist/agent/facades/agent-context-facade.js +1 -3
  23. package/dist/agent/facades/agent-context-facade.js.map +1 -1
  24. package/dist/agent/facades/message-history-manager.js +14 -12
  25. package/dist/agent/facades/message-history-manager.js.map +1 -1
  26. package/dist/agent/facades/session-facade.d.ts +3 -3
  27. package/dist/agent/facades/session-facade.js +6 -6
  28. package/dist/agent/facades/session-facade.js.map +1 -1
  29. package/dist/agent/history-repair.d.ts +37 -0
  30. package/dist/agent/history-repair.js +124 -0
  31. package/dist/agent/history-repair.js.map +1 -0
  32. package/dist/agent/index.d.ts +3 -3
  33. package/dist/agent/index.js +3 -3
  34. package/dist/agent/index.js.map +1 -1
  35. package/dist/agent/isolation/agent-workspace.d.ts +1 -0
  36. package/dist/agent/isolation/agent-workspace.js +10 -0
  37. package/dist/agent/isolation/agent-workspace.js.map +1 -1
  38. package/dist/agent/specialized/archive-agent.d.ts +3 -0
  39. package/dist/agent/specialized/archive-agent.js +71 -31
  40. package/dist/agent/specialized/archive-agent.js.map +1 -1
  41. package/dist/agent/specialized/index.d.ts +9 -8
  42. package/dist/agent/specialized/index.js +16 -8
  43. package/dist/agent/specialized/index.js.map +1 -1
  44. package/dist/agent/specialized/security-review/agent.js +19 -8
  45. package/dist/agent/specialized/security-review/agent.js.map +1 -1
  46. package/dist/agent/tool-executor.js +5 -0
  47. package/dist/agent/tool-executor.js.map +1 -1
  48. package/dist/agent/turn-diff-tracker.d.ts +79 -0
  49. package/dist/agent/turn-diff-tracker.js +195 -0
  50. package/dist/agent/turn-diff-tracker.js.map +1 -0
  51. package/dist/browser/controller.js +8 -4
  52. package/dist/browser/controller.js.map +1 -1
  53. package/dist/browser-automation/browser-manager.js +8 -1
  54. package/dist/browser-automation/browser-manager.js.map +1 -1
  55. package/dist/checkpoints/checkpoint-versioning.js +78 -20
  56. package/dist/checkpoints/checkpoint-versioning.js.map +1 -1
  57. package/dist/cli/config-loader.js +2 -4
  58. package/dist/cli/config-loader.js.map +1 -1
  59. package/dist/codebuddy/client.js +70 -11
  60. package/dist/codebuddy/client.js.map +1 -1
  61. package/dist/codebuddy/tools.d.ts +1 -7
  62. package/dist/codebuddy/tools.js +2 -30
  63. package/dist/codebuddy/tools.js.map +1 -1
  64. package/dist/commands/cli/daemon-commands.d.ts +14 -0
  65. package/dist/commands/cli/daemon-commands.js +166 -0
  66. package/dist/commands/cli/daemon-commands.js.map +1 -0
  67. package/dist/commands/cli/speak-command.d.ts +10 -0
  68. package/dist/commands/cli/speak-command.js +97 -0
  69. package/dist/commands/cli/speak-command.js.map +1 -0
  70. package/dist/commands/cli/utility-commands.d.ts +10 -0
  71. package/dist/commands/cli/utility-commands.js +88 -0
  72. package/dist/commands/cli/utility-commands.js.map +1 -0
  73. package/dist/commands/handlers/fcs-handlers.js +1 -1
  74. package/dist/commands/handlers/fcs-handlers.js.map +1 -1
  75. package/dist/commands/handlers/memory-handlers.js +2 -1
  76. package/dist/commands/handlers/memory-handlers.js.map +1 -1
  77. package/dist/commands/handlers/vibe-handlers.js +0 -1
  78. package/dist/commands/handlers/vibe-handlers.js.map +1 -1
  79. package/dist/commands/handlers/worktree-handlers.js +11 -0
  80. package/dist/commands/handlers/worktree-handlers.js.map +1 -1
  81. package/dist/commands/index.d.ts +8 -7
  82. package/dist/commands/index.js +10 -8
  83. package/dist/commands/index.js.map +1 -1
  84. package/dist/commands/mcp.d.ts +1 -0
  85. package/dist/commands/mcp.js +66 -7
  86. package/dist/commands/mcp.js.map +1 -1
  87. package/dist/commands/pipeline.js +25 -13
  88. package/dist/commands/pipeline.js.map +1 -1
  89. package/dist/config/hot-reload/watcher.js +4 -4
  90. package/dist/config/hot-reload/watcher.js.map +1 -1
  91. package/dist/config/model-tools.d.ts +41 -0
  92. package/dist/config/model-tools.js +194 -0
  93. package/dist/config/model-tools.js.map +1 -0
  94. package/dist/context/context-manager-v2.d.ts +2 -1
  95. package/dist/context/context-manager-v2.js +34 -5
  96. package/dist/context/context-manager-v2.js.map +1 -1
  97. package/dist/context/index.d.ts +12 -12
  98. package/dist/context/index.js +25 -12
  99. package/dist/context/index.js.map +1 -1
  100. package/dist/daemon/daemon-manager.js +23 -19
  101. package/dist/daemon/daemon-manager.js.map +1 -1
  102. package/dist/database/database-manager.d.ts +4 -0
  103. package/dist/database/database-manager.js +16 -7
  104. package/dist/database/database-manager.js.map +1 -1
  105. package/dist/desktop-automation/nutjs-provider.js +89 -0
  106. package/dist/desktop-automation/nutjs-provider.js.map +1 -1
  107. package/dist/errors/index.d.ts +4 -4
  108. package/dist/errors/index.js +8 -4
  109. package/dist/errors/index.js.map +1 -1
  110. package/dist/fcs/builtins.d.ts +2 -6
  111. package/dist/fcs/builtins.js +2 -568
  112. package/dist/fcs/builtins.js.map +1 -1
  113. package/dist/fcs/codebuddy-bindings.d.ts +3 -43
  114. package/dist/fcs/codebuddy-bindings.js +2 -606
  115. package/dist/fcs/codebuddy-bindings.js.map +1 -1
  116. package/dist/fcs/index.d.ts +2 -27
  117. package/dist/fcs/index.js +2 -53
  118. package/dist/fcs/index.js.map +1 -1
  119. package/dist/fcs/lexer.d.ts +2 -37
  120. package/dist/fcs/lexer.js +2 -459
  121. package/dist/fcs/lexer.js.map +1 -1
  122. package/dist/fcs/parser.d.ts +2 -68
  123. package/dist/fcs/parser.js +2 -893
  124. package/dist/fcs/parser.js.map +1 -1
  125. package/dist/fcs/runtime.d.ts +2 -59
  126. package/dist/fcs/runtime.js +2 -623
  127. package/dist/fcs/runtime.js.map +1 -1
  128. package/dist/fcs/script-registry.d.ts +3 -69
  129. package/dist/fcs/script-registry.js +2 -219
  130. package/dist/fcs/script-registry.js.map +1 -1
  131. package/dist/fcs/sync-bindings.d.ts +3 -101
  132. package/dist/fcs/sync-bindings.js +2 -410
  133. package/dist/fcs/sync-bindings.js.map +1 -1
  134. package/dist/fcs/types.d.ts +2 -285
  135. package/dist/fcs/types.js +2 -103
  136. package/dist/fcs/types.js.map +1 -1
  137. package/dist/hooks/index.d.ts +4 -4
  138. package/dist/hooks/index.js +4 -4
  139. package/dist/hooks/index.js.map +1 -1
  140. package/dist/hooks/use-input-handler.d.ts +1 -1
  141. package/dist/index.js +20 -330
  142. package/dist/index.js.map +1 -1
  143. package/dist/input/voice-control.js +11 -5
  144. package/dist/input/voice-control.js.map +1 -1
  145. package/dist/integrations/json-rpc/server.d.ts +9 -0
  146. package/dist/integrations/json-rpc/server.js +43 -13
  147. package/dist/integrations/json-rpc/server.js.map +1 -1
  148. package/dist/integrations/mcp/mcp-server.js +1 -1
  149. package/dist/integrations/mcp/mcp-server.js.map +1 -1
  150. package/dist/integrations/notification-integrations.d.ts +1 -0
  151. package/dist/integrations/notification-integrations.js +6 -1
  152. package/dist/integrations/notification-integrations.js.map +1 -1
  153. package/dist/mcp/client.js +2 -1
  154. package/dist/mcp/client.js.map +1 -1
  155. package/dist/mcp/config.js +89 -5
  156. package/dist/mcp/config.js.map +1 -1
  157. package/dist/mcp/mcp-client.js +65 -14
  158. package/dist/mcp/mcp-client.js.map +1 -1
  159. package/dist/mcp/transports.d.ts +0 -1
  160. package/dist/mcp/transports.js +1 -5
  161. package/dist/mcp/transports.js.map +1 -1
  162. package/dist/mcp/types.d.ts +2 -0
  163. package/dist/memory/index.d.ts +2 -2
  164. package/dist/memory/index.js +2 -2
  165. package/dist/memory/index.js.map +1 -1
  166. package/dist/persistence/session-lock.d.ts +42 -0
  167. package/dist/persistence/session-lock.js +165 -0
  168. package/dist/persistence/session-lock.js.map +1 -0
  169. package/dist/persistence/session-store.d.ts +18 -3
  170. package/dist/persistence/session-store.js +90 -21
  171. package/dist/persistence/session-store.js.map +1 -1
  172. package/dist/plugins/conflict-detection.js +2 -1
  173. package/dist/plugins/conflict-detection.js.map +1 -1
  174. package/dist/plugins/index.d.ts +3 -3
  175. package/dist/plugins/index.js +3 -3
  176. package/dist/plugins/index.js.map +1 -1
  177. package/dist/plugins/isolated-plugin-runner.d.ts +6 -0
  178. package/dist/plugins/isolated-plugin-runner.js +19 -1
  179. package/dist/plugins/isolated-plugin-runner.js.map +1 -1
  180. package/dist/providers/local-llm-provider.js +28 -8
  181. package/dist/providers/local-llm-provider.js.map +1 -1
  182. package/dist/sandbox/docker-sandbox.js +7 -4
  183. package/dist/sandbox/docker-sandbox.js.map +1 -1
  184. package/dist/scripting/builtins.d.ts +8 -3
  185. package/dist/scripting/builtins.js +506 -355
  186. package/dist/scripting/builtins.js.map +1 -1
  187. package/dist/scripting/codebuddy-bindings.d.ts +47 -0
  188. package/dist/scripting/codebuddy-bindings.js +488 -0
  189. package/dist/scripting/codebuddy-bindings.js.map +1 -0
  190. package/dist/scripting/index.d.ts +33 -30
  191. package/dist/scripting/index.js +41 -36
  192. package/dist/scripting/index.js.map +1 -1
  193. package/dist/scripting/lexer.d.ts +31 -13
  194. package/dist/scripting/lexer.js +379 -292
  195. package/dist/scripting/lexer.js.map +1 -1
  196. package/dist/scripting/parser.d.ts +63 -44
  197. package/dist/scripting/parser.js +700 -473
  198. package/dist/scripting/parser.js.map +1 -1
  199. package/dist/scripting/runtime.d.ts +55 -24
  200. package/dist/scripting/runtime.js +600 -288
  201. package/dist/scripting/runtime.js.map +1 -1
  202. package/dist/scripting/script-registry.d.ts +54 -0
  203. package/dist/scripting/script-registry.js +202 -0
  204. package/dist/scripting/script-registry.js.map +1 -0
  205. package/dist/scripting/sync-bindings.d.ts +105 -0
  206. package/dist/scripting/sync-bindings.js +353 -0
  207. package/dist/scripting/sync-bindings.js.map +1 -0
  208. package/dist/scripting/types.d.ts +297 -199
  209. package/dist/scripting/types.js +86 -60
  210. package/dist/scripting/types.js.map +1 -1
  211. package/dist/search/usearch-index.js +42 -7
  212. package/dist/search/usearch-index.js.map +1 -1
  213. package/dist/security/bash-parser.d.ts +51 -0
  214. package/dist/security/bash-parser.js +327 -0
  215. package/dist/security/bash-parser.js.map +1 -0
  216. package/dist/security/index.d.ts +7 -5
  217. package/dist/security/index.js +8 -7
  218. package/dist/security/index.js.map +1 -1
  219. package/dist/security/skill-scanner.d.ts +36 -0
  220. package/dist/security/skill-scanner.js +149 -0
  221. package/dist/security/skill-scanner.js.map +1 -0
  222. package/dist/security/trust-folders.d.ts +1 -0
  223. package/dist/security/trust-folders.js +19 -1
  224. package/dist/security/trust-folders.js.map +1 -1
  225. package/dist/server/auth/index.d.ts +2 -2
  226. package/dist/server/auth/index.js +2 -2
  227. package/dist/server/auth/index.js.map +1 -1
  228. package/dist/server/middleware/index.d.ts +5 -5
  229. package/dist/server/middleware/index.js +5 -5
  230. package/dist/server/middleware/index.js.map +1 -1
  231. package/dist/server/middleware/rate-limit.js +15 -3
  232. package/dist/server/middleware/rate-limit.js.map +1 -1
  233. package/dist/server/websocket/handler.js +54 -6
  234. package/dist/server/websocket/handler.js.map +1 -1
  235. package/dist/skills/eligibility.js +26 -4
  236. package/dist/skills/eligibility.js.map +1 -1
  237. package/dist/tasks/background-tasks.js +5 -1
  238. package/dist/tasks/background-tasks.js.map +1 -1
  239. package/dist/tools/apply-patch.d.ts +55 -0
  240. package/dist/tools/apply-patch.js +273 -0
  241. package/dist/tools/apply-patch.js.map +1 -0
  242. package/dist/tools/hooks/default-hooks.d.ts +1 -1
  243. package/dist/tools/hooks/default-hooks.js +2 -1
  244. package/dist/tools/hooks/default-hooks.js.map +1 -1
  245. package/dist/tools/index.d.ts +10 -10
  246. package/dist/tools/index.js +11 -11
  247. package/dist/tools/index.js.map +1 -1
  248. package/dist/tools/registry/bash-tools.js +6 -3
  249. package/dist/tools/registry/bash-tools.js.map +1 -1
  250. package/dist/tools/registry/misc-tools.js +1 -2
  251. package/dist/tools/registry/misc-tools.js.map +1 -1
  252. package/dist/tools/registry/search-tools.js +1 -1
  253. package/dist/tools/registry/search-tools.js.map +1 -1
  254. package/dist/tools/registry/text-editor-tools.js +1 -1
  255. package/dist/tools/registry/text-editor-tools.js.map +1 -1
  256. package/dist/tools/registry/todo-tools.js +37 -5
  257. package/dist/tools/registry/todo-tools.js.map +1 -1
  258. package/dist/tools/registry/tool-registry.js +5 -4
  259. package/dist/tools/registry/tool-registry.js.map +1 -1
  260. package/dist/tools/registry/web-tools.d.ts +1 -1
  261. package/dist/tools/registry/web-tools.js +28 -8
  262. package/dist/tools/registry/web-tools.js.map +1 -1
  263. package/dist/tools/text-editor.d.ts +1 -1
  264. package/dist/tools/text-editor.js +23 -5
  265. package/dist/tools/text-editor.js.map +1 -1
  266. package/dist/tools/web-search.d.ts +52 -37
  267. package/dist/tools/web-search.js +368 -163
  268. package/dist/tools/web-search.js.map +1 -1
  269. package/dist/types/errors.d.ts +1 -1
  270. package/dist/types/errors.js +2 -8
  271. package/dist/types/errors.js.map +1 -1
  272. package/dist/types/index.d.ts +2 -1
  273. package/dist/types/index.js +1 -2
  274. package/dist/types/index.js.map +1 -1
  275. package/dist/ui/components/ChatInterface.d.ts +1 -1
  276. package/dist/ui/index.d.ts +17 -21
  277. package/dist/ui/index.js +25 -22
  278. package/dist/ui/index.js.map +1 -1
  279. package/dist/utils/config-validation/schema.d.ts +15 -15
  280. package/dist/utils/head-tail-truncation.d.ts +34 -0
  281. package/dist/utils/head-tail-truncation.js +98 -0
  282. package/dist/utils/head-tail-truncation.js.map +1 -0
  283. package/dist/utils/logger.js +3 -9
  284. package/dist/utils/logger.js.map +1 -1
  285. package/dist/utils/sanitize.d.ts +5 -0
  286. package/dist/utils/sanitize.js +19 -0
  287. package/dist/utils/sanitize.js.map +1 -1
  288. package/dist/utils/settings-manager.js +4 -4
  289. package/dist/utils/settings-manager.js.map +1 -1
  290. package/dist/workflows/index.d.ts +4 -279
  291. package/dist/workflows/index.js +8 -822
  292. package/dist/workflows/index.js.map +1 -1
  293. package/dist/workflows/state-manager.d.ts +77 -0
  294. package/dist/workflows/state-manager.js +198 -0
  295. package/dist/workflows/state-manager.js.map +1 -0
  296. package/dist/workflows/step-manager.d.ts +39 -0
  297. package/dist/workflows/step-manager.js +196 -0
  298. package/dist/workflows/step-manager.js.map +1 -0
  299. package/dist/workflows/types.d.ts +87 -0
  300. package/dist/workflows/types.js +5 -0
  301. package/dist/workflows/types.js.map +1 -0
  302. package/dist/workflows/workflow-engine.d.ts +34 -0
  303. package/dist/workflows/workflow-engine.js +354 -0
  304. package/dist/workflows/workflow-engine.js.map +1 -0
  305. package/package.json +5 -1
@@ -0,0 +1,520 @@
1
+ ---
2
+ name: playwright
3
+ version: 1.0.0
4
+ description: Browser automation, end-to-end testing, web scraping, form filling, screenshots, and PDF generation
5
+ author: Code Buddy
6
+ tags: browser, automation, testing, scraping, e2e, screenshots, pdf
7
+ env:
8
+ PLAYWRIGHT_BROWSERS_PATH: ""
9
+ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: ""
10
+ ---
11
+
12
+ # Playwright Browser Automation
13
+
14
+ Playwright is a powerful browser automation framework that supports Chromium, Firefox, and WebKit. It enables reliable end-to-end testing, web scraping, form automation, screenshot capture, and PDF generation with a modern async API.
15
+
16
+ ## Direct Control (CLI / API / Scripting)
17
+
18
+ ### Installation
19
+
20
+ ```bash
21
+ # Install Playwright
22
+ npm install -D @playwright/test playwright
23
+
24
+ # Install browsers (Chromium, Firefox, WebKit)
25
+ npx playwright install
26
+
27
+ # Install specific browser only
28
+ npx playwright install chromium
29
+
30
+ # Install with system dependencies
31
+ npx playwright install --with-deps
32
+ ```
33
+
34
+ ### Node.js API Examples
35
+
36
+ ```javascript
37
+ const { chromium, firefox, webkit } = require('playwright');
38
+
39
+ // Basic page navigation and scraping
40
+ async function scrapePage(url) {
41
+ const browser = await chromium.launch({ headless: true });
42
+ const context = await browser.newContext();
43
+ const page = await context.newPage();
44
+
45
+ await page.goto(url);
46
+ await page.waitForLoadState('networkidle');
47
+
48
+ // Extract data
49
+ const title = await page.title();
50
+ const content = await page.textContent('body');
51
+ const links = await page.$$eval('a', anchors =>
52
+ anchors.map(a => ({ text: a.textContent, href: a.href }))
53
+ );
54
+
55
+ await browser.close();
56
+ return { title, content, links };
57
+ }
58
+
59
+ // Form filling and submission
60
+ async function fillForm(url, formData) {
61
+ const browser = await chromium.launch({ headless: false });
62
+ const page = await browser.newPage();
63
+
64
+ await page.goto(url);
65
+
66
+ // Fill form fields
67
+ await page.fill('input[name="username"]', formData.username);
68
+ await page.fill('input[name="email"]', formData.email);
69
+ await page.fill('textarea[name="message"]', formData.message);
70
+
71
+ // Select dropdown
72
+ await page.selectOption('select[name="country"]', formData.country);
73
+
74
+ // Check checkbox
75
+ await page.check('input[type="checkbox"][name="terms"]');
76
+
77
+ // Click submit and wait for navigation
78
+ await Promise.all([
79
+ page.waitForNavigation(),
80
+ page.click('button[type="submit"]')
81
+ ]);
82
+
83
+ // Verify success
84
+ const successMessage = await page.textContent('.success-message');
85
+ await browser.close();
86
+ return successMessage;
87
+ }
88
+
89
+ // Screenshot capture
90
+ async function captureScreenshot(url, outputPath, options = {}) {
91
+ const browser = await chromium.launch();
92
+ const page = await browser.newPage({
93
+ viewport: { width: 1920, height: 1080 }
94
+ });
95
+
96
+ await page.goto(url);
97
+ await page.waitForLoadState('networkidle');
98
+
99
+ // Full page screenshot
100
+ await page.screenshot({
101
+ path: outputPath,
102
+ fullPage: options.fullPage || false,
103
+ type: options.type || 'png'
104
+ });
105
+
106
+ // Element screenshot
107
+ if (options.selector) {
108
+ const element = await page.$(options.selector);
109
+ await element.screenshot({ path: outputPath });
110
+ }
111
+
112
+ await browser.close();
113
+ }
114
+
115
+ // PDF generation
116
+ async function generatePDF(url, outputPath, options = {}) {
117
+ const browser = await chromium.launch();
118
+ const page = await browser.newPage();
119
+
120
+ await page.goto(url);
121
+ await page.waitForLoadState('networkidle');
122
+
123
+ await page.pdf({
124
+ path: outputPath,
125
+ format: options.format || 'A4',
126
+ printBackground: true,
127
+ margin: options.margin || { top: '1cm', bottom: '1cm', left: '1cm', right: '1cm' }
128
+ });
129
+
130
+ await browser.close();
131
+ }
132
+
133
+ // Handle authentication
134
+ async function loginAndNavigate(loginUrl, targetUrl, credentials) {
135
+ const browser = await chromium.launch();
136
+ const context = await browser.newContext();
137
+ const page = await context.newPage();
138
+
139
+ // Login
140
+ await page.goto(loginUrl);
141
+ await page.fill('#username', credentials.username);
142
+ await page.fill('#password', credentials.password);
143
+ await page.click('button[type="submit"]');
144
+
145
+ // Wait for login to complete
146
+ await page.waitForURL(/dashboard|home/);
147
+
148
+ // Save authentication state
149
+ await context.storageState({ path: 'auth.json' });
150
+
151
+ // Navigate to target with auth
152
+ await page.goto(targetUrl);
153
+ const data = await page.evaluate(() => document.body.innerText);
154
+
155
+ await browser.close();
156
+ return data;
157
+ }
158
+
159
+ // Advanced: Intercept network requests
160
+ async function interceptRequests(url) {
161
+ const browser = await chromium.launch();
162
+ const page = await browser.newPage();
163
+
164
+ // Block images and stylesheets for faster loading
165
+ await page.route('**/*', route => {
166
+ const type = route.request().resourceType();
167
+ if (type === 'image' || type === 'stylesheet') {
168
+ route.abort();
169
+ } else {
170
+ route.continue();
171
+ }
172
+ });
173
+
174
+ // Listen to API responses
175
+ const apiData = [];
176
+ page.on('response', async response => {
177
+ if (response.url().includes('/api/')) {
178
+ apiData.push({
179
+ url: response.url(),
180
+ status: response.status(),
181
+ body: await response.json().catch(() => null)
182
+ });
183
+ }
184
+ });
185
+
186
+ await page.goto(url);
187
+ await page.waitForTimeout(3000);
188
+
189
+ await browser.close();
190
+ return apiData;
191
+ }
192
+
193
+ // Multi-browser testing
194
+ async function testAcrossBrowsers(url, testFn) {
195
+ const browsers = [chromium, firefox, webkit];
196
+ const results = {};
197
+
198
+ for (const browserType of browsers) {
199
+ const browser = await browserType.launch();
200
+ const page = await browser.newPage();
201
+
202
+ try {
203
+ await page.goto(url);
204
+ results[browserType.name()] = await testFn(page);
205
+ } catch (error) {
206
+ results[browserType.name()] = { error: error.message };
207
+ }
208
+
209
+ await browser.close();
210
+ }
211
+
212
+ return results;
213
+ }
214
+ ```
215
+
216
+ ### Python API Examples
217
+
218
+ ```python
219
+ from playwright.sync_api import sync_playwright
220
+ import json
221
+
222
+ # Basic scraping
223
+ def scrape_page(url):
224
+ with sync_playwright() as p:
225
+ browser = p.chromium.launch(headless=True)
226
+ page = browser.new_page()
227
+ page.goto(url)
228
+
229
+ title = page.title()
230
+ content = page.inner_text('body')
231
+
232
+ browser.close()
233
+ return {'title': title, 'content': content}
234
+
235
+ # Form automation
236
+ def automate_form(url, form_data):
237
+ with sync_playwright() as p:
238
+ browser = p.chromium.launch(headless=False)
239
+ page = browser.new_page()
240
+ page.goto(url)
241
+
242
+ page.fill('input[name="email"]', form_data['email'])
243
+ page.fill('input[name="password"]', form_data['password'])
244
+ page.click('button[type="submit"]')
245
+
246
+ page.wait_for_load_state('networkidle')
247
+ result = page.text_content('.result')
248
+
249
+ browser.close()
250
+ return result
251
+
252
+ # Screenshot with mobile viewport
253
+ def mobile_screenshot(url, output):
254
+ with sync_playwright() as p:
255
+ browser = p.chromium.launch()
256
+ context = browser.new_context(
257
+ viewport={'width': 375, 'height': 667},
258
+ user_agent='Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)'
259
+ )
260
+ page = context.new_page()
261
+ page.goto(url)
262
+ page.screenshot(path=output, full_page=True)
263
+ browser.close()
264
+ ```
265
+
266
+ ### CLI Commands
267
+
268
+ ```bash
269
+ # Run Playwright tests
270
+ npx playwright test
271
+
272
+ # Run specific test file
273
+ npx playwright test tests/login.spec.ts
274
+
275
+ # Run tests in headed mode (see browser)
276
+ npx playwright test --headed
277
+
278
+ # Run tests in specific browser
279
+ npx playwright test --project=firefox
280
+
281
+ # Debug tests with Playwright Inspector
282
+ npx playwright test --debug
283
+
284
+ # Generate code from browser interactions (codegen)
285
+ npx playwright codegen https://example.com
286
+
287
+ # Generate code with custom viewport
288
+ npx playwright codegen --viewport-size=1280,720 https://example.com
289
+
290
+ # Show trace viewer
291
+ npx playwright show-trace trace.zip
292
+
293
+ # Show HTML report
294
+ npx playwright show-report
295
+
296
+ # Install system dependencies
297
+ npx playwright install-deps
298
+
299
+ # Clear browser cache
300
+ rm -rf ~/.cache/ms-playwright
301
+ ```
302
+
303
+ ## MCP Server Integration
304
+
305
+ Add to `.codebuddy/mcp.json`:
306
+
307
+ ```json
308
+ {
309
+ "mcpServers": {
310
+ "playwright": {
311
+ "command": "npx",
312
+ "args": [
313
+ "-y",
314
+ "@executeautomation/playwright-mcp-server"
315
+ ],
316
+ "env": {
317
+ "PLAYWRIGHT_BROWSERS_PATH": "~/.cache/ms-playwright"
318
+ }
319
+ }
320
+ }
321
+ }
322
+ ```
323
+
324
+ ### Available MCP Tools
325
+
326
+ **From microsoft/playwright-mcp:**
327
+ - `playwright_navigate` - Navigate to URL
328
+ - `playwright_click` - Click element by selector
329
+ - `playwright_fill` - Fill input field
330
+ - `playwright_screenshot` - Capture screenshot
331
+ - `playwright_evaluate` - Execute JavaScript in page context
332
+ - `playwright_close` - Close browser/page
333
+
334
+ **From executeautomation/playwright-mcp-server:**
335
+ - `playwright_launch_browser` - Launch browser instance
336
+ - `playwright_goto` - Navigate to URL
337
+ - `playwright_click_element` - Click element with wait
338
+ - `playwright_fill_form` - Fill form fields
339
+ - `playwright_get_text` - Extract text content
340
+ - `playwright_wait_for_selector` - Wait for element
341
+ - `playwright_screenshot_element` - Screenshot specific element
342
+ - `playwright_pdf` - Generate PDF
343
+ - `playwright_execute_script` - Run JavaScript
344
+
345
+ ## Common Workflows
346
+
347
+ ### 1. Web Scraping: Extract Product Information
348
+
349
+ ```javascript
350
+ // Step 1: Launch browser and navigate
351
+ const browser = await chromium.launch({ headless: true });
352
+ const page = await browser.newPage();
353
+ await page.goto('https://example-shop.com/products');
354
+
355
+ // Step 2: Wait for products to load
356
+ await page.waitForSelector('.product-card', { timeout: 10000 });
357
+
358
+ // Step 3: Extract product data
359
+ const products = await page.$$eval('.product-card', cards => {
360
+ return cards.map(card => ({
361
+ name: card.querySelector('.product-name')?.textContent,
362
+ price: card.querySelector('.product-price')?.textContent,
363
+ image: card.querySelector('img')?.src,
364
+ url: card.querySelector('a')?.href
365
+ }));
366
+ });
367
+
368
+ // Step 4: Paginate through results
369
+ let allProducts = [...products];
370
+ while (await page.$('.next-page')) {
371
+ await page.click('.next-page');
372
+ await page.waitForLoadState('networkidle');
373
+ const moreProducts = await page.$$eval('.product-card', /* ... */);
374
+ allProducts = [...allProducts, ...moreProducts];
375
+ }
376
+
377
+ // Step 5: Save results and cleanup
378
+ await fs.writeFile('products.json', JSON.stringify(allProducts, null, 2));
379
+ await browser.close();
380
+ ```
381
+
382
+ ### 2. E2E Testing: Login Flow Verification
383
+
384
+ ```javascript
385
+ // Step 1: Setup test with authentication state
386
+ const browser = await chromium.launch();
387
+ const context = await browser.newContext();
388
+ const page = await context.newPage();
389
+
390
+ // Step 2: Navigate to login page
391
+ await page.goto('https://app.example.com/login');
392
+ await page.fill('#email', 'test@example.com');
393
+ await page.fill('#password', 'SecurePassword123');
394
+
395
+ // Step 3: Submit and verify redirect
396
+ await Promise.all([
397
+ page.waitForNavigation({ url: /dashboard/ }),
398
+ page.click('button[type="submit"]')
399
+ ]);
400
+
401
+ // Step 4: Verify authenticated state
402
+ await expect(page.locator('.user-profile')).toBeVisible();
403
+ const username = await page.textContent('.user-name');
404
+ expect(username).toBe('Test User');
405
+
406
+ // Step 5: Test logout
407
+ await page.click('.logout-button');
408
+ await page.waitForURL(/login/);
409
+ await browser.close();
410
+ ```
411
+
412
+ ### 3. Form Automation: Multi-Step Checkout
413
+
414
+ ```javascript
415
+ // Step 1: Navigate to checkout
416
+ const browser = await chromium.launch({ headless: false });
417
+ const page = await browser.newPage();
418
+ await page.goto('https://shop.example.com/checkout');
419
+
420
+ // Step 2: Fill shipping information
421
+ await page.fill('#firstName', 'John');
422
+ await page.fill('#lastName', 'Doe');
423
+ await page.fill('#address', '123 Main St');
424
+ await page.fill('#city', 'San Francisco');
425
+ await page.selectOption('#state', 'CA');
426
+ await page.fill('#zip', '94105');
427
+ await page.click('button.continue-to-payment');
428
+
429
+ // Step 3: Fill payment details
430
+ await page.waitForSelector('#card-number');
431
+ await page.fill('#card-number', '4111111111111111');
432
+ await page.fill('#card-expiry', '12/25');
433
+ await page.fill('#card-cvc', '123');
434
+
435
+ // Step 4: Review and submit order
436
+ await page.click('button.continue-to-review');
437
+ await page.waitForSelector('.order-summary');
438
+ const total = await page.textContent('.total-amount');
439
+ console.log(`Order total: ${total}`);
440
+
441
+ // Step 5: Complete purchase
442
+ await page.click('button.place-order');
443
+ await page.waitForSelector('.confirmation-number');
444
+ const confirmationNumber = await page.textContent('.confirmation-number');
445
+ await browser.close();
446
+ return confirmationNumber;
447
+ ```
448
+
449
+ ### 4. Visual Testing: Screenshot Comparison
450
+
451
+ ```javascript
452
+ // Step 1: Setup baseline screenshot
453
+ const browser = await chromium.launch();
454
+ const page = await browser.newPage({ viewport: { width: 1280, height: 720 } });
455
+ await page.goto('https://example.com');
456
+ await page.screenshot({ path: 'baseline.png', fullPage: true });
457
+
458
+ // Step 2: Make changes (e.g., deploy new version)
459
+ // ... deployment happens ...
460
+
461
+ // Step 3: Capture new screenshot
462
+ await page.goto('https://example.com');
463
+ await page.screenshot({ path: 'current.png', fullPage: true });
464
+
465
+ // Step 4: Compare screenshots (using pixelmatch or similar)
466
+ const baseline = await fs.readFile('baseline.png');
467
+ const current = await fs.readFile('current.png');
468
+ const diff = compareImages(baseline, current);
469
+
470
+ // Step 5: Report differences
471
+ if (diff.pixelsDifferent > 100) {
472
+ console.error(`Visual regression detected: ${diff.pixelsDifferent} pixels differ`);
473
+ await fs.writeFile('diff.png', diff.image);
474
+ }
475
+ await browser.close();
476
+ ```
477
+
478
+ ### 5. Monitoring: Check Website Availability
479
+
480
+ ```javascript
481
+ // Step 1: Setup monitoring function
482
+ async function monitorWebsite(url, checks) {
483
+ const browser = await chromium.launch({ headless: true });
484
+ const page = await browser.newPage();
485
+ const results = { url, timestamp: new Date(), checks: {} };
486
+
487
+ // Step 2: Navigate and measure load time
488
+ const startTime = Date.now();
489
+ const response = await page.goto(url, { waitUntil: 'networkidle' });
490
+ results.loadTime = Date.now() - startTime;
491
+ results.statusCode = response.status();
492
+
493
+ // Step 3: Verify expected elements
494
+ for (const check of checks) {
495
+ const element = await page.$(check.selector);
496
+ results.checks[check.name] = {
497
+ found: !!element,
498
+ text: element ? await element.textContent() : null
499
+ };
500
+ }
501
+
502
+ // Step 4: Check for errors in console
503
+ const logs = [];
504
+ page.on('console', msg => logs.push({ type: msg.type(), text: msg.text() }));
505
+ await page.waitForTimeout(2000);
506
+ results.consoleLogs = logs.filter(l => l.type === 'error');
507
+
508
+ // Step 5: Cleanup and return results
509
+ await browser.close();
510
+ return results;
511
+ }
512
+
513
+ // Usage
514
+ const checks = [
515
+ { name: 'header', selector: 'header.main-nav' },
516
+ { name: 'content', selector: 'main.content' },
517
+ { name: 'footer', selector: 'footer' }
518
+ ];
519
+ const status = await monitorWebsite('https://example.com', checks);
520
+ ```