dev3000 0.0.151 → 0.0.154
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/README.md +121 -103
- package/bin/dev3000 +10 -5
- package/dist/cdp-monitor.d.ts.map +1 -1
- package/dist/cdp-monitor.js +2 -3
- package/dist/cdp-monitor.js.map +1 -1
- package/dist/cli.js +301 -75
- package/dist/cli.js.map +1 -1
- package/dist/commands/cloud-check-pr.d.ts +1 -0
- package/dist/commands/cloud-check-pr.d.ts.map +1 -1
- package/dist/commands/cloud-check-pr.js +18 -6
- package/dist/commands/cloud-check-pr.js.map +1 -1
- package/dist/commands/crawl.d.ts +12 -0
- package/dist/commands/crawl.d.ts.map +1 -0
- package/dist/commands/crawl.js +140 -0
- package/dist/commands/crawl.js.map +1 -0
- package/dist/commands/errors.d.ts +14 -0
- package/dist/commands/errors.d.ts.map +1 -0
- package/dist/commands/errors.js +295 -0
- package/dist/commands/errors.js.map +1 -0
- package/dist/commands/find-component.d.ts +8 -0
- package/dist/commands/find-component.d.ts.map +1 -0
- package/dist/commands/find-component.js +182 -0
- package/dist/commands/find-component.js.map +1 -0
- package/dist/commands/fix.d.ts +13 -0
- package/dist/commands/fix.d.ts.map +1 -0
- package/dist/commands/fix.js +288 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/logs.d.ts +13 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +195 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/restart.d.ts +8 -0
- package/dist/commands/restart.d.ts.map +1 -0
- package/dist/commands/restart.js +92 -0
- package/dist/commands/restart.js.map +1 -0
- package/dist/components/PackageSelector.d.ts +12 -0
- package/dist/components/PackageSelector.d.ts.map +1 -0
- package/dist/components/PackageSelector.js +74 -0
- package/dist/components/PackageSelector.js.map +1 -0
- package/dist/dev-environment.d.ts +0 -7
- package/dist/dev-environment.d.ts.map +1 -1
- package/dist/dev-environment.js +108 -674
- package/dist/dev-environment.js.map +1 -1
- package/dist/screencast-manager.d.ts.map +1 -1
- package/dist/screencast-manager.js +7 -8
- package/dist/screencast-manager.js.map +1 -1
- package/dist/services/parsers/output-processor.js +2 -2
- package/dist/services/parsers/output-processor.js.map +1 -1
- package/dist/skills/d3k/SKILL.md +38 -27
- package/dist/skills/index.d.ts +10 -14
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +47 -77
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/index.test.ts +13 -55
- package/dist/skills/index.ts +48 -81
- package/dist/src/tui-interface-impl.tsx +6 -15
- package/dist/tui-interface-impl.d.ts.map +1 -1
- package/dist/tui-interface-impl.js +4 -4
- package/dist/tui-interface-impl.js.map +1 -1
- package/dist/tui-interface-opentui.d.ts.map +1 -1
- package/dist/tui-interface-opentui.js +227 -100
- package/dist/tui-interface-opentui.js.map +1 -1
- package/dist/utils/agent-browser.d.ts +2 -0
- package/dist/utils/agent-browser.d.ts.map +1 -1
- package/dist/utils/agent-browser.js +46 -8
- package/dist/utils/agent-browser.js.map +1 -1
- package/dist/utils/agent-selection.d.ts.map +1 -1
- package/dist/utils/agent-selection.js +9 -2
- package/dist/utils/agent-selection.js.map +1 -1
- package/dist/utils/skill-installer.d.ts +55 -29
- package/dist/utils/skill-installer.d.ts.map +1 -1
- package/dist/utils/skill-installer.js +118 -229
- package/dist/utils/skill-installer.js.map +1 -1
- package/dist/utils/tmux-helpers.d.ts +1 -2
- package/dist/utils/tmux-helpers.d.ts.map +1 -1
- package/dist/utils/tmux-helpers.js +17 -18
- package/dist/utils/tmux-helpers.js.map +1 -1
- package/dist/utils/version-check.d.ts +2 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +9 -0
- package/dist/utils/version-check.js.map +1 -1
- package/mcp-server/.next/BUILD_ID +1 -1
- package/mcp-server/.next/build-manifest.json +2 -2
- package/mcp-server/.next/fallback-build-manifest.json +2 -2
- package/mcp-server/.next/prerender-manifest.json +3 -3
- package/mcp-server/.next/server/app/_global-error/page.js +1 -1
- package/mcp-server/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/mcp-server/.next/server/app/_global-error.html +2 -2
- package/mcp-server/.next/server/app/_global-error.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found/page.js +1 -1
- package/mcp-server/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/mcp-server/.next/server/app/_not-found.html +1 -1
- package/mcp-server/.next/server/app/_not-found.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/mcp-server/.next/server/app/api/screenshots/capture/route.js +2 -2
- package/mcp-server/.next/server/app/api/screenshots/capture/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/index.html +1 -1
- package/mcp-server/.next/server/app/index.rsc +2 -2
- package/mcp-server/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/mcp-server/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/mcp-server/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/mcp-server/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/mcp-server/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/mcp-server/.next/server/app/logs/page.js +1 -1
- package/mcp-server/.next/server/app/logs/page.js.nft.json +1 -1
- package/mcp-server/.next/server/app/mcp/route.js +4 -4
- package/mcp-server/.next/server/app/mcp/route.js.nft.json +1 -1
- package/mcp-server/.next/server/app/page.js +1 -1
- package/mcp-server/.next/server/app/page.js.nft.json +1 -1
- package/mcp-server/.next/server/app/page_client-reference-manifest.js +1 -1
- package/mcp-server/.next/server/app/video/[session]/page.js +1 -1
- package/mcp-server/.next/server/app/video/[session]/page.js.nft.json +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__2f95edf0._.js +3 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__2f95edf0._.js.map +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__69e6dfb7._.js +3 -0
- package/mcp-server/.next/server/chunks/{[root-of-the-server]__444592aa._.js.map → [root-of-the-server]__69e6dfb7._.js.map} +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6baff21e._.js +4 -0
- package/mcp-server/.next/server/chunks/{[root-of-the-server]__130a5f58._.js.map → [root-of-the-server]__6baff21e._.js.map} +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6f790e1f._.js +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__6f790e1f._.js.map +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__c8cf5b23._.js +3 -0
- package/mcp-server/.next/server/chunks/[root-of-the-server]__e6a83e60._.js +4 -0
- package/mcp-server/.next/server/chunks/{[root-of-the-server]__b71c83ed._.js.map → [root-of-the-server]__e6a83e60._.js.map} +1 -1
- package/mcp-server/.next/server/chunks/mcp-server_app_mcp_tools_ts_faf6d7df._.js +32 -66
- package/mcp-server/.next/server/chunks/mcp-server_app_mcp_tools_ts_faf6d7df._.js.map +1 -1
- package/mcp-server/.next/server/chunks/src_utils_agent-browser_ts_cc00e0d8._.js +1 -1
- package/mcp-server/.next/server/chunks/src_utils_agent-browser_ts_cc00e0d8._.js.map +1 -1
- package/mcp-server/.next/server/chunks/src_utils_project-name_ts_1fab1dd5._.js +3 -0
- package/mcp-server/.next/server/chunks/src_utils_project-name_ts_1fab1dd5._.js.map +1 -0
- package/mcp-server/.next/server/chunks/ssr/{[root-of-the-server]__f66148e5._.js → [root-of-the-server]__b17d4048._.js} +2 -2
- package/mcp-server/.next/server/chunks/ssr/{[root-of-the-server]__50eb2eba._.js → [root-of-the-server]__dcf84f77._.js} +2 -2
- package/mcp-server/.next/server/chunks/ssr/mcp-server_app_page_tsx_9fc46577._.js +1 -1
- package/mcp-server/.next/server/chunks/ssr/mcp-server_app_page_tsx_9fc46577._.js.map +1 -1
- package/mcp-server/.next/server/pages/404.html +1 -1
- package/mcp-server/.next/server/pages/500.html +2 -2
- package/mcp-server/.next/server/server-reference-manifest.js +1 -1
- package/mcp-server/.next/server/server-reference-manifest.json +1 -1
- package/mcp-server/.next/static/chunks/{2422ea9ed874427b.js → 3f3f8e7d16ba3bf4.js} +1 -1
- package/mcp-server/app/api/tools/route.ts +5 -4
- package/mcp-server/app/mcp/route.ts +8 -63
- package/mcp-server/app/mcp/tools.ts +71 -445
- package/mcp-server/app/page.tsx +1 -1
- package/mcp-server/package.json +2 -0
- package/package.json +6 -5
- package/src/tui-interface-impl.tsx +6 -15
- package/dist/components/SkillSelector.d.ts +0 -10
- package/dist/components/SkillSelector.d.ts.map +0 -1
- package/dist/components/SkillSelector.js +0 -87
- package/dist/components/SkillSelector.js.map +0 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__130a5f58._.js +0 -4
- package/mcp-server/.next/server/chunks/[root-of-the-server]__444592aa._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__8f84b4cc._.js +0 -3
- package/mcp-server/.next/server/chunks/[root-of-the-server]__b71c83ed._.js +0 -4
- /package/mcp-server/.next/server/chunks/{[root-of-the-server]__8f84b4cc._.js.map → [root-of-the-server]__c8cf5b23._.js.map} +0 -0
- /package/mcp-server/.next/server/chunks/ssr/{[root-of-the-server]__f66148e5._.js.map → [root-of-the-server]__b17d4048._.js.map} +0 -0
- /package/mcp-server/.next/server/chunks/ssr/{[root-of-the-server]__50eb2eba._.js.map → [root-of-the-server]__dcf84f77._.js.map} +0 -0
- /package/mcp-server/.next/static/{HVxg1xsmhVm6VO2KBlH_- → MfA6U1EFS31sVuHA4xDF_}/_buildManifest.js +0 -0
- /package/mcp-server/.next/static/{HVxg1xsmhVm6VO2KBlH_- → MfA6U1EFS31sVuHA4xDF_}/_clientMiddlewareManifest.json +0 -0
- /package/mcp-server/.next/static/{HVxg1xsmhVm6VO2KBlH_- → MfA6U1EFS31sVuHA4xDF_}/_ssgManifest.js +0 -0
|
@@ -26,13 +26,12 @@ function isInSandbox(): boolean {
|
|
|
26
26
|
export const TOOL_DESCRIPTIONS = {
|
|
27
27
|
// Meta-description for MCP coordination - Claude should see this when listing tools
|
|
28
28
|
_mcp_coordination:
|
|
29
|
-
"**dev3000 is an MCP orchestrator for web development.**
|
|
29
|
+
"**dev3000 is an MCP orchestrator for web development.** For browser automation, use the d3k CLI:\n```bash\nd3k agent-browser --cdp 9222 <command>\n```\nThis connects to d3k's existing Chrome browser. NEVER install Playwright or Chromium - d3k already has a browser open.\n\ndev3000 provides unified error context from server logs + browser console + network, automatic screenshots on errors, and framework-aware diagnostics (Next.js, Svelte).",
|
|
30
30
|
|
|
31
31
|
fix_my_app:
|
|
32
32
|
"Diagnoses application errors from dev3000 logs. Returns a prioritized list of issues requiring fixes.\n\n**CRITICAL: You MUST use this tool in a loop until all errors are resolved:**\n\n```\nwhile (errors exist) {\n 1. DIAGNOSE: Call fix_my_app to get current errors\n 2. FIX: Implement a fix for the highest-priority error\n 3. VERIFY: Call fix_my_app again to confirm the error is gone\n 4. REPEAT: Continue until no errors remain\n}\n```\n\n**This tool does NOT fix anything automatically.** It returns diagnostic data. You must:\n- Read the error output\n- Investigate and fix each issue\n- Call this tool again to verify your fix worked\n- Keep looping until the app is healthy\n\n**What it analyzes:**\n• Server logs, browser console, network requests\n• Categorizes: build errors, server crashes, browser errors, network issues, warnings\n• Prioritizes by severity (fix build errors first, then server, then browser, etc.)\n• Shows user interactions that triggered each error\n\n**Parameters:**\n• focusArea: 'build', 'runtime', 'network', 'ui', 'performance', or 'all' (default)\n• mode: 'snapshot' (current state), 'bisect' (before/after comparison), 'monitor' (continuous)\n• timeRangeMinutes: How far back to analyze (default: 10)\n• createPR: If true, creates a PR branch for the highest-priority issue\n\n**Framework support:** Auto-detects Next.js for framework-specific analysis.\n\n**Attribution for commits/PRs:**\n```\nGenerated with Claude Code using d3k (https://d3k.dev)\nCo-Authored-By: Claude <noreply@anthropic.com>\n```",
|
|
33
33
|
|
|
34
|
-
execute_browser_action
|
|
35
|
-
"Executes browser actions (click, navigate, scroll, type, reload, evaluate JS) in the dev3000-managed Chrome instance.\n\n**PREFER THIS over standalone chrome-devtools-mcp tools.** dev3000 manages the Chrome connection and avoids CDP conflicts.\n\n**Available actions:**\n• screenshot: Capture current page state\n• navigate: Go to a URL\n• reload: Refresh the current page (triggers CLS recapture)\n• click: Click at coordinates {x, y} or selector\n• scroll: Scroll by {x, y} pixels\n• type: Type text into focused element\n• evaluate: Execute JavaScript (read-only operations recommended)\n\n**Use cases:**\n• Reproducing user interactions that triggered errors\n• Verifying fixes by replaying the error scenario\n• Testing specific UI workflows\n• Taking screenshots for visual verification",
|
|
34
|
+
// execute_browser_action removed - use agent_browser_action instead
|
|
36
35
|
|
|
37
36
|
analyze_visual_diff:
|
|
38
37
|
"Compares two screenshots and returns analysis instructions for identifying visual differences.\n\n**What it provides:**\n• Instructions to load both images for comparison\n• Context about what visual changes to look for\n• Guidance on identifying layout shift causes\n\n**Use cases:**\n• Analyzing before/after frames from CLS detection\n• Identifying elements that appeared, moved, or resized\n• Debugging visual regressions",
|
|
@@ -41,7 +40,7 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
41
40
|
"Maps a DOM element to its React component source code location.\n\n**How it works:**\n1. Inspects the element via Chrome DevTools Protocol\n2. Extracts the React component function source\n3. Identifies unique code patterns (JSX, classNames, etc.)\n4. Returns grep patterns to locate the source file\n\n**Use cases:**\n• Finding which file contains a specific UI element\n• Locating components responsible for layout shifts\n• Tracing DOM elements back to source code",
|
|
42
41
|
|
|
43
42
|
restart_dev_server:
|
|
44
|
-
"Restarts the development server
|
|
43
|
+
"⚠️ DANGEROUS: Restarts the development server. This is RARELY needed and often causes d3k to crash.\n\n**BEFORE using this tool, consider:**\n• HMR handles most code changes automatically - just wait a moment\n• Browser reload (Cmd+R) clears most cached state\n• 'use cache' in Next.js auto-invalidates when source files change\n• Restarting often fails and causes d3k to exit, disrupting the user's session\n\n**Only use for:**\n• Changes to next.config.js/ts (rare)\n• Changes to middleware.ts (rare)\n• Changes to .env files (rare)\n\n**DO NOT use for:**\n• Clearing RSC cache (HMR handles this)\n• Testing if a fix worked (just reload the page)\n• Any regular code changes\n\n**Ask the user first** before using this tool. They may prefer to manually restart d3k themselves.",
|
|
45
44
|
|
|
46
45
|
crawl_app:
|
|
47
46
|
"Discovers URLs in the application by crawling links from the homepage.\n\n**Parameters:**\n• depth: How many link levels to follow (1, 2, 3, or 'all')\n• limit: Max links per page (default: 3)\n\n**Behavior:**\n• Starts at localhost homepage\n• Follows same-origin links only\n• Deduplicates discovered URLs\n• Returns list of all found pages\n\n**Use cases:**\n• Discovering all routes before running diagnostics\n• Site-wide testing coverage\n• Verifying all pages load without errors",
|
|
@@ -49,8 +48,10 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
49
48
|
get_skill:
|
|
50
49
|
"Get the content of a d3k/Claude Code skill. Skills are prompt templates that provide specialized instructions for specific tasks.\n\n**Parameters:**\n• name: The skill name (e.g., 'vercel-design-guidelines', 'd3k')\n\n**Returns:**\nThe full SKILL.md content which contains instructions on how to perform the skill's task.\n\n**Available skills:**\n• vercel-design-guidelines - Audit web interfaces against Vercel's design guidelines\n• d3k - Core d3k development assistant skill\n\n**Use cases:**\n• Loading design guidelines audit instructions\n• Getting specialized workflow instructions",
|
|
51
50
|
|
|
52
|
-
agent_browser_action:
|
|
53
|
-
|
|
51
|
+
// agent_browser_action: REMOVED - Use d3k CLI instead: `d3k agent-browser --cdp 9222 <command>`
|
|
52
|
+
// This avoids browser installation issues and connects to d3k's existing Chrome
|
|
53
|
+
_deprecated_agent_browser_action:
|
|
54
|
+
"REMOVED - Use d3k CLI: `d3k agent-browser --cdp 9222 <command>` instead. This connects to d3k's existing Chrome browser without needing to install anything."
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
// Types
|
|
@@ -81,10 +82,7 @@ export interface CreateIntegratedWorkflowParams {
|
|
|
81
82
|
errorContext?: string
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
action: string
|
|
86
|
-
params?: Record<string, unknown>
|
|
87
|
-
}
|
|
85
|
+
// ExecuteBrowserActionParams removed - use AgentBrowserActionParams instead
|
|
88
86
|
|
|
89
87
|
export interface GetMcpCapabilitiesParams {
|
|
90
88
|
mcpName?: string // Optional - if not provided, shows all available MCPs
|
|
@@ -1759,7 +1757,7 @@ async function canDelegateToNextjs(): Promise<boolean> {
|
|
|
1759
1757
|
/**
|
|
1760
1758
|
* Delegate browser action to chrome-devtools MCP
|
|
1761
1759
|
*/
|
|
1762
|
-
async function
|
|
1760
|
+
async function _delegateToChromeDevtools(
|
|
1763
1761
|
action: string,
|
|
1764
1762
|
params: Record<string, unknown>
|
|
1765
1763
|
): Promise<{ content: Array<{ type: "text"; text: string }> }> {
|
|
@@ -1833,436 +1831,9 @@ ${availableFunctions}
|
|
|
1833
1831
|
}
|
|
1834
1832
|
}
|
|
1835
1833
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
}: ExecuteBrowserActionParams): Promise<{ content: Array<{ type: "text"; text: string }> }> {
|
|
1840
|
-
try {
|
|
1841
|
-
// 🎯 INTELLIGENT DELEGATION: Check if chrome-devtools MCP can handle this action
|
|
1842
|
-
const canDelegate = await canDelegateToChromeDevtools(action)
|
|
1843
|
-
if (canDelegate) {
|
|
1844
|
-
logToDevFile(`Browser Action Delegation: Routing '${action}' to chrome-devtools MCP`)
|
|
1845
|
-
return await delegateToChromeDevtools(action, params)
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
// Log fallback to dev3000's own implementation
|
|
1849
|
-
logToDevFile(`Browser Action Fallback: Using dev3000's execute_browser_action for '${action}'`)
|
|
1850
|
-
|
|
1851
|
-
// First, find active session to get CDP URL
|
|
1852
|
-
const sessions = findActiveSessions()
|
|
1853
|
-
if (sessions.length === 0) {
|
|
1854
|
-
return {
|
|
1855
|
-
content: [
|
|
1856
|
-
{
|
|
1857
|
-
type: "text",
|
|
1858
|
-
text: "❌ No active dev3000 sessions found. Make sure dev3000 is running with a browser!"
|
|
1859
|
-
}
|
|
1860
|
-
]
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
|
|
1864
|
-
// Get the most recent session's CDP URL (stored in session data)
|
|
1865
|
-
const sessionData = JSON.parse(readFileSync(sessions[0].sessionFile, "utf-8"))
|
|
1866
|
-
let cdpUrl = sessionData.cdpUrl
|
|
1867
|
-
|
|
1868
|
-
if (!cdpUrl) {
|
|
1869
|
-
// Try to get CDP URL from Chrome debugging port as fallback
|
|
1870
|
-
try {
|
|
1871
|
-
const response = await fetch("http://localhost:9222/json")
|
|
1872
|
-
const pages = await response.json()
|
|
1873
|
-
const activePage = pages.find(
|
|
1874
|
-
(page: { type: string; url: string }) => page.type === "page" && !page.url.startsWith("chrome://")
|
|
1875
|
-
)
|
|
1876
|
-
if (activePage) {
|
|
1877
|
-
cdpUrl = activePage.webSocketDebuggerUrl
|
|
1878
|
-
logToDevFile(`CDP Discovery: Found fallback CDP URL ${cdpUrl}`, sessions[0].projectName)
|
|
1879
|
-
}
|
|
1880
|
-
} catch (error) {
|
|
1881
|
-
logToDevFile(`CDP Discovery: Failed to find fallback CDP URL - ${error}`, sessions[0].projectName)
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
|
|
1885
|
-
if (!cdpUrl) {
|
|
1886
|
-
return {
|
|
1887
|
-
content: [
|
|
1888
|
-
{
|
|
1889
|
-
type: "text",
|
|
1890
|
-
text: `❌ No Chrome DevTools Protocol URL found. Make sure dev3000 is running with browser monitoring enabled (not --servers-only mode). Session CDP URL: ${sessionData.cdpUrl || "null"}`
|
|
1891
|
-
}
|
|
1892
|
-
]
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
|
|
1896
|
-
// Connect to Chrome DevTools Protocol with timeout
|
|
1897
|
-
const result = await new Promise<Record<string, unknown>>((resolve, reject) => {
|
|
1898
|
-
const ws = new WebSocket(cdpUrl)
|
|
1899
|
-
|
|
1900
|
-
// Overall timeout for the entire browser action (60 seconds)
|
|
1901
|
-
const overallTimeout = setTimeout(() => {
|
|
1902
|
-
ws.close()
|
|
1903
|
-
reject(
|
|
1904
|
-
new Error(
|
|
1905
|
-
`Browser action '${action}' timed out after 60 seconds. This may indicate an issue with the browser or invalid parameters.`
|
|
1906
|
-
)
|
|
1907
|
-
)
|
|
1908
|
-
}, 60000)
|
|
1909
|
-
|
|
1910
|
-
ws.on("open", async () => {
|
|
1911
|
-
try {
|
|
1912
|
-
// Get the first page target
|
|
1913
|
-
ws.send(JSON.stringify({ id: 1, method: "Target.getTargets", params: {} }))
|
|
1914
|
-
|
|
1915
|
-
let targetId: string | null = null
|
|
1916
|
-
let _sessionId: string | null = null
|
|
1917
|
-
let messageId = 2
|
|
1918
|
-
|
|
1919
|
-
ws.on("message", async (data) => {
|
|
1920
|
-
try {
|
|
1921
|
-
const message = JSON.parse(data.toString())
|
|
1922
|
-
|
|
1923
|
-
// Handle getting targets
|
|
1924
|
-
if (message.id === 1) {
|
|
1925
|
-
// Check for CDP protocol errors (e.g., "Not allowed" in sandboxed environments)
|
|
1926
|
-
if (message.error) {
|
|
1927
|
-
clearTimeout(overallTimeout)
|
|
1928
|
-
ws.close()
|
|
1929
|
-
reject(
|
|
1930
|
-
new Error(
|
|
1931
|
-
`Browser protocol error: ${message.error.message || JSON.stringify(message.error)}. This may occur in sandboxed browser environments where certain CDP commands are restricted.`
|
|
1932
|
-
)
|
|
1933
|
-
)
|
|
1934
|
-
return
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
|
-
const pageTarget = message.result?.targetInfos?.find((t: Record<string, unknown>) => t.type === "page")
|
|
1938
|
-
if (!pageTarget) {
|
|
1939
|
-
clearTimeout(overallTimeout)
|
|
1940
|
-
ws.close()
|
|
1941
|
-
reject(new Error("No page targets found"))
|
|
1942
|
-
return
|
|
1943
|
-
}
|
|
1944
|
-
|
|
1945
|
-
targetId = pageTarget.targetId
|
|
1946
|
-
|
|
1947
|
-
// Attach to the target
|
|
1948
|
-
ws.send(
|
|
1949
|
-
JSON.stringify({
|
|
1950
|
-
id: messageId++,
|
|
1951
|
-
method: "Target.attachToTarget",
|
|
1952
|
-
params: { targetId, flatten: true }
|
|
1953
|
-
})
|
|
1954
|
-
)
|
|
1955
|
-
return
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
// Handle session creation
|
|
1959
|
-
if (message.method === "Target.attachedToTarget") {
|
|
1960
|
-
_sessionId = message.params.sessionId
|
|
1961
|
-
|
|
1962
|
-
// Now execute the requested action
|
|
1963
|
-
let cdpResult: Record<string, unknown>
|
|
1964
|
-
|
|
1965
|
-
switch (action) {
|
|
1966
|
-
case "click": {
|
|
1967
|
-
let clickX: number
|
|
1968
|
-
let clickY: number
|
|
1969
|
-
|
|
1970
|
-
// Support both coordinate-based and selector-based clicks
|
|
1971
|
-
if (typeof params.selector === "string") {
|
|
1972
|
-
// Get element coordinates from selector and ensure we click in the center
|
|
1973
|
-
const selectorResult = (await sendCDPCommand(ws, messageId++, "Runtime.evaluate", {
|
|
1974
|
-
expression: `(() => {
|
|
1975
|
-
const el = document.querySelector(${JSON.stringify(params.selector)});
|
|
1976
|
-
if (!el) return { found: false };
|
|
1977
|
-
const rect = el.getBoundingClientRect();
|
|
1978
|
-
// Calculate center point, rounding to avoid fractional pixels
|
|
1979
|
-
const centerX = Math.round(rect.left + rect.width / 2);
|
|
1980
|
-
const centerY = Math.round(rect.top + rect.height / 2);
|
|
1981
|
-
// Verify what element is at this point
|
|
1982
|
-
const elementAtPoint = document.elementFromPoint(centerX, centerY);
|
|
1983
|
-
const isCorrectElement = elementAtPoint === el || el.contains(elementAtPoint);
|
|
1984
|
-
return {
|
|
1985
|
-
found: true,
|
|
1986
|
-
x: centerX,
|
|
1987
|
-
y: centerY,
|
|
1988
|
-
width: rect.width,
|
|
1989
|
-
height: rect.height,
|
|
1990
|
-
elementAtPoint: elementAtPoint?.tagName + (elementAtPoint?.className ? '.' + elementAtPoint.className : ''),
|
|
1991
|
-
isCorrectElement: isCorrectElement
|
|
1992
|
-
};
|
|
1993
|
-
})()`,
|
|
1994
|
-
returnByValue: true
|
|
1995
|
-
})) as {
|
|
1996
|
-
result?: {
|
|
1997
|
-
value?: {
|
|
1998
|
-
found: boolean
|
|
1999
|
-
x?: number
|
|
2000
|
-
y?: number
|
|
2001
|
-
width?: number
|
|
2002
|
-
height?: number
|
|
2003
|
-
elementAtPoint?: string
|
|
2004
|
-
isCorrectElement?: boolean
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
|
-
if (
|
|
2010
|
-
selectorResult.result?.value?.found === true &&
|
|
2011
|
-
typeof selectorResult.result.value.x === "number" &&
|
|
2012
|
-
typeof selectorResult.result.value.y === "number"
|
|
2013
|
-
) {
|
|
2014
|
-
clickX = selectorResult.result.value.x
|
|
2015
|
-
clickY = selectorResult.result.value.y
|
|
2016
|
-
|
|
2017
|
-
// Log diagnostic info if element at point doesn't match
|
|
2018
|
-
if (selectorResult.result.value.isCorrectElement === false) {
|
|
2019
|
-
console.warn(
|
|
2020
|
-
`[execute_browser_action] Warning: Center point (${clickX}, ${clickY}) is over ${selectorResult.result.value.elementAtPoint}, not the target element. ` +
|
|
2021
|
-
`This may cause unexpected click behavior. Element size: ${selectorResult.result.value.width}x${selectorResult.result.value.height}`
|
|
2022
|
-
)
|
|
2023
|
-
}
|
|
2024
|
-
} else {
|
|
2025
|
-
throw new Error(`Element not found for selector: ${params.selector}`)
|
|
2026
|
-
}
|
|
2027
|
-
} else if (typeof params.x === "number" && typeof params.y === "number") {
|
|
2028
|
-
clickX = params.x
|
|
2029
|
-
clickY = params.y
|
|
2030
|
-
} else {
|
|
2031
|
-
throw new Error("Click action requires either {x, y} coordinates or a {selector} CSS selector")
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
|
-
cdpResult = await sendCDPCommand(ws, messageId++, "Input.dispatchMouseEvent", {
|
|
2035
|
-
type: "mousePressed",
|
|
2036
|
-
x: clickX,
|
|
2037
|
-
y: clickY,
|
|
2038
|
-
button: "left",
|
|
2039
|
-
clickCount: 1
|
|
2040
|
-
})
|
|
2041
|
-
await sendCDPCommand(ws, messageId++, "Input.dispatchMouseEvent", {
|
|
2042
|
-
type: "mouseReleased",
|
|
2043
|
-
x: clickX,
|
|
2044
|
-
y: clickY,
|
|
2045
|
-
button: "left",
|
|
2046
|
-
clickCount: 1
|
|
2047
|
-
})
|
|
2048
|
-
break
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
case "navigate":
|
|
2052
|
-
if (typeof params.url !== "string") {
|
|
2053
|
-
throw new Error("Navigate action requires url parameter as string")
|
|
2054
|
-
}
|
|
2055
|
-
cdpResult = await sendCDPCommand(ws, messageId++, "Page.navigate", { url: params.url })
|
|
2056
|
-
break
|
|
2057
|
-
|
|
2058
|
-
case "reload":
|
|
2059
|
-
// Use CDP Page.reload for reliable page refresh that triggers CLS capture
|
|
2060
|
-
cdpResult = await sendCDPCommand(ws, messageId++, "Page.reload", {})
|
|
2061
|
-
break
|
|
2062
|
-
|
|
2063
|
-
case "screenshot":
|
|
2064
|
-
ws.close()
|
|
2065
|
-
resolve({
|
|
2066
|
-
warning: "Screenshot action is not recommended!",
|
|
2067
|
-
advice:
|
|
2068
|
-
"Dev3000 automatically captures screenshots during interactions. Instead of manual screenshots, use click/navigate/scroll/type actions to reproduce user workflows, and dev3000 will capture screenshots at optimal times.",
|
|
2069
|
-
suggestion: "Run fix_my_app to see all auto-captured screenshots from your session."
|
|
2070
|
-
})
|
|
2071
|
-
return
|
|
2072
|
-
|
|
2073
|
-
case "evaluate": {
|
|
2074
|
-
if (typeof params.expression !== "string") {
|
|
2075
|
-
throw new Error("Evaluate action requires expression parameter as string")
|
|
2076
|
-
}
|
|
2077
|
-
const expression = params.expression
|
|
2078
|
-
// Validate that the expression is safe (read-only DOM queries)
|
|
2079
|
-
// Block dangerous patterns
|
|
2080
|
-
const dangerousPatterns = [
|
|
2081
|
-
/eval\s*\(/,
|
|
2082
|
-
/Function\s*\(/,
|
|
2083
|
-
/setTimeout/,
|
|
2084
|
-
/setInterval/,
|
|
2085
|
-
/\.innerHTML\s*=/,
|
|
2086
|
-
/\.outerHTML\s*=/,
|
|
2087
|
-
/document\.write/,
|
|
2088
|
-
/document\.cookie\s*=/,
|
|
2089
|
-
/localStorage\.setItem/,
|
|
2090
|
-
/sessionStorage\.setItem/,
|
|
2091
|
-
/\.src\s*=/,
|
|
2092
|
-
/\.href\s*=/,
|
|
2093
|
-
/location\s*=/,
|
|
2094
|
-
/\.addEventListener/,
|
|
2095
|
-
/\.removeEventListener/,
|
|
2096
|
-
/new\s+Function/,
|
|
2097
|
-
/import\s*\(/,
|
|
2098
|
-
/fetch\s*\(/,
|
|
2099
|
-
/XMLHttpRequest/
|
|
2100
|
-
]
|
|
2101
|
-
|
|
2102
|
-
if (dangerousPatterns.some((regex) => regex.test(expression))) {
|
|
2103
|
-
throw new Error(
|
|
2104
|
-
"Expression contains dangerous patterns. Only safe read-only expressions allowed."
|
|
2105
|
-
)
|
|
2106
|
-
}
|
|
2107
|
-
|
|
2108
|
-
cdpResult = await sendCDPCommand(ws, messageId++, "Runtime.evaluate", {
|
|
2109
|
-
expression: expression,
|
|
2110
|
-
returnByValue: true
|
|
2111
|
-
})
|
|
2112
|
-
break
|
|
2113
|
-
}
|
|
2114
|
-
|
|
2115
|
-
case "scroll": {
|
|
2116
|
-
const scrollX = typeof params.deltaX === "number" ? params.deltaX : 0
|
|
2117
|
-
const scrollY = typeof params.deltaY === "number" ? params.deltaY : 0
|
|
2118
|
-
cdpResult = await sendCDPCommand(ws, messageId++, "Input.dispatchMouseEvent", {
|
|
2119
|
-
type: "mouseWheel",
|
|
2120
|
-
x: typeof params.x === "number" ? params.x : 500,
|
|
2121
|
-
y: typeof params.y === "number" ? params.y : 500,
|
|
2122
|
-
deltaX: scrollX,
|
|
2123
|
-
deltaY: scrollY
|
|
2124
|
-
})
|
|
2125
|
-
break
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
|
-
case "type":
|
|
2129
|
-
if (typeof params.text !== "string") {
|
|
2130
|
-
throw new Error("Type action requires text parameter as string")
|
|
2131
|
-
}
|
|
2132
|
-
// Type each character
|
|
2133
|
-
for (const char of params.text) {
|
|
2134
|
-
await sendCDPCommand(ws, messageId++, "Input.dispatchKeyEvent", {
|
|
2135
|
-
type: "char",
|
|
2136
|
-
text: char
|
|
2137
|
-
})
|
|
2138
|
-
}
|
|
2139
|
-
cdpResult = { action: "type", text: params.text }
|
|
2140
|
-
break
|
|
2141
|
-
|
|
2142
|
-
default:
|
|
2143
|
-
throw new Error(`Unsupported action: ${action}`)
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
ws.close()
|
|
2147
|
-
clearTimeout(overallTimeout)
|
|
2148
|
-
resolve(cdpResult)
|
|
2149
|
-
}
|
|
2150
|
-
} catch (error) {
|
|
2151
|
-
// Catch any errors that occur during message handling
|
|
2152
|
-
ws.close()
|
|
2153
|
-
clearTimeout(overallTimeout)
|
|
2154
|
-
reject(
|
|
2155
|
-
error instanceof Error
|
|
2156
|
-
? error
|
|
2157
|
-
: new Error(`Browser action failed: ${error instanceof Error ? error.message : String(error)}`)
|
|
2158
|
-
)
|
|
2159
|
-
}
|
|
2160
|
-
})
|
|
2161
|
-
|
|
2162
|
-
ws.on("error", (error) => {
|
|
2163
|
-
clearTimeout(overallTimeout)
|
|
2164
|
-
reject(error)
|
|
2165
|
-
})
|
|
2166
|
-
|
|
2167
|
-
// Helper function to send CDP commands
|
|
2168
|
-
async function sendCDPCommand(
|
|
2169
|
-
ws: WebSocket,
|
|
2170
|
-
id: number,
|
|
2171
|
-
method: string,
|
|
2172
|
-
params: Record<string, unknown>
|
|
2173
|
-
): Promise<Record<string, unknown>> {
|
|
2174
|
-
return new Promise((cmdResolve, cmdReject) => {
|
|
2175
|
-
const command = { id, method, params }
|
|
2176
|
-
|
|
2177
|
-
const messageHandler = (data: Buffer) => {
|
|
2178
|
-
const message = JSON.parse(data.toString())
|
|
2179
|
-
if (message.id === id) {
|
|
2180
|
-
ws.removeListener("message", messageHandler)
|
|
2181
|
-
if (message.error) {
|
|
2182
|
-
cmdReject(new Error(message.error.message))
|
|
2183
|
-
} else {
|
|
2184
|
-
cmdResolve(message.result)
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
}
|
|
2188
|
-
|
|
2189
|
-
ws.on("message", messageHandler)
|
|
2190
|
-
ws.send(JSON.stringify(command))
|
|
2191
|
-
|
|
2192
|
-
// Command timeout (30 seconds for complex evaluate expressions)
|
|
2193
|
-
setTimeout(() => {
|
|
2194
|
-
ws.removeListener("message", messageHandler)
|
|
2195
|
-
cmdReject(new Error(`CDP command timeout after 30s: ${method}`))
|
|
2196
|
-
}, 30000)
|
|
2197
|
-
})
|
|
2198
|
-
}
|
|
2199
|
-
} catch (error) {
|
|
2200
|
-
ws.close()
|
|
2201
|
-
clearTimeout(overallTimeout)
|
|
2202
|
-
reject(error)
|
|
2203
|
-
}
|
|
2204
|
-
})
|
|
2205
|
-
|
|
2206
|
-
ws.on("error", (error) => {
|
|
2207
|
-
clearTimeout(overallTimeout)
|
|
2208
|
-
reject(error)
|
|
2209
|
-
})
|
|
2210
|
-
})
|
|
2211
|
-
|
|
2212
|
-
// Build success message with augmented suggestions
|
|
2213
|
-
let successMessage = `Browser action '${action}' executed successfully. Result: ${JSON.stringify(result, null, 2)}`
|
|
2214
|
-
|
|
2215
|
-
// Add augmented suggestions for enhanced capabilities
|
|
2216
|
-
const canDelegateChrome = await canDelegateToChromeDevtools("inspect_element")
|
|
2217
|
-
if (canDelegateChrome) {
|
|
2218
|
-
successMessage += "\n\n🔗 **ENHANCED BROWSER ANALYSIS AVAILABLE**"
|
|
2219
|
-
successMessage +=
|
|
2220
|
-
"\n\ndev3000 completed the basic browser action above. For deeper browser insights, consider also:"
|
|
2221
|
-
|
|
2222
|
-
// Generate dynamic suggestions based on the action and available capabilities
|
|
2223
|
-
const dynamicSuggestions = await generateChromeDevtoolsSuggestions(action)
|
|
2224
|
-
const actionRelevantSuggestions = dynamicSuggestions.filter((suggestion) => {
|
|
2225
|
-
const funcName = suggestion.function.toLowerCase()
|
|
2226
|
-
const actionName = action.toLowerCase()
|
|
2227
|
-
|
|
2228
|
-
// Match suggestions to specific actions
|
|
2229
|
-
if (actionName === "screenshot" && (funcName.includes("inspect") || funcName.includes("performance")))
|
|
2230
|
-
return true
|
|
2231
|
-
if (actionName === "evaluate" && (funcName.includes("console") || funcName.includes("inspect"))) return true
|
|
2232
|
-
if (actionName === "navigate" && (funcName.includes("network") || funcName.includes("performance"))) return true
|
|
2233
|
-
if (actionName === "click" && (funcName.includes("console") || funcName.includes("inspect"))) return true
|
|
2234
|
-
|
|
2235
|
-
// Include high-priority suggestions regardless
|
|
2236
|
-
return suggestion.priority === "high"
|
|
2237
|
-
})
|
|
2238
|
-
|
|
2239
|
-
actionRelevantSuggestions.slice(0, 2).forEach((suggestion) => {
|
|
2240
|
-
successMessage += `\n• \`dev3000-chrome-devtools:${suggestion.function}()\` - ${suggestion.reason}`
|
|
2241
|
-
})
|
|
2242
|
-
|
|
2243
|
-
successMessage +=
|
|
2244
|
-
"\n\n💡 **Augmented approach:** Use dev3000 for basic automation, chrome-devtools for detailed analysis and debugging."
|
|
2245
|
-
}
|
|
2246
|
-
|
|
2247
|
-
return {
|
|
2248
|
-
content: [
|
|
2249
|
-
{
|
|
2250
|
-
type: "text",
|
|
2251
|
-
text: successMessage
|
|
2252
|
-
}
|
|
2253
|
-
]
|
|
2254
|
-
}
|
|
2255
|
-
} catch (error) {
|
|
2256
|
-
return {
|
|
2257
|
-
content: [
|
|
2258
|
-
{
|
|
2259
|
-
type: "text",
|
|
2260
|
-
text: `Browser action failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2261
|
-
}
|
|
2262
|
-
]
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
}
|
|
1834
|
+
// executeBrowserAction removed - use executeAgentBrowserAction directly
|
|
1835
|
+
// The legacy execute_browser_action MCP tool has been removed
|
|
1836
|
+
// All browser automation now goes through agent_browser_action
|
|
2266
1837
|
|
|
2267
1838
|
// MCP Integration and Workflow Orchestration Functions
|
|
2268
1839
|
|
|
@@ -4381,10 +3952,22 @@ export async function getSkill(params: GetSkillParams) {
|
|
|
4381
3952
|
// ============================================================
|
|
4382
3953
|
|
|
4383
3954
|
export interface AgentBrowserActionParams {
|
|
4384
|
-
action:
|
|
3955
|
+
action:
|
|
3956
|
+
| "open"
|
|
3957
|
+
| "click"
|
|
3958
|
+
| "type"
|
|
3959
|
+
| "fill"
|
|
3960
|
+
| "scroll"
|
|
3961
|
+
| "screenshot"
|
|
3962
|
+
| "snapshot"
|
|
3963
|
+
| "close"
|
|
3964
|
+
| "reload"
|
|
3965
|
+
| "back"
|
|
3966
|
+
| "evaluate"
|
|
4385
3967
|
params?: Record<string, unknown>
|
|
4386
3968
|
session?: string // Session name for isolation
|
|
4387
3969
|
headed?: boolean // Run with visible browser window
|
|
3970
|
+
profile?: string // Path to persistent browser profile directory (stores cookies, localStorage, etc.)
|
|
4388
3971
|
}
|
|
4389
3972
|
|
|
4390
3973
|
/**
|
|
@@ -4395,7 +3978,8 @@ export async function executeAgentBrowserAction({
|
|
|
4395
3978
|
action,
|
|
4396
3979
|
params = {},
|
|
4397
3980
|
session,
|
|
4398
|
-
headed = false
|
|
3981
|
+
headed = false,
|
|
3982
|
+
profile
|
|
4399
3983
|
}: AgentBrowserActionParams): Promise<{ content: Array<{ type: "text"; text: string }> }> {
|
|
4400
3984
|
try {
|
|
4401
3985
|
// Dynamic import of agent-browser wrapper
|
|
@@ -4413,10 +3997,45 @@ export async function executeAgentBrowserAction({
|
|
|
4413
3997
|
}
|
|
4414
3998
|
}
|
|
4415
3999
|
|
|
4416
|
-
//
|
|
4000
|
+
// Use project-specific profile path if not specified - this enables persistent sessions
|
|
4001
|
+
// (cookies, localStorage, login state) across browser restarts, per-project
|
|
4002
|
+
// Import getProjectDir to get the same profile path that d3k uses for Chrome
|
|
4003
|
+
const { getProjectDir } = await import("../../../src/utils/project-name")
|
|
4004
|
+
const defaultProfile = profile ?? join(getProjectDir(), "chrome-profile")
|
|
4005
|
+
|
|
4006
|
+
// Extract CDP port to connect to existing browser that d3k launched
|
|
4007
|
+
// CDP_URL format: ws://localhost:9222/devtools/browser/...
|
|
4008
|
+
// Try env var first, then fall back to session file (MCP server starts before CDP is ready)
|
|
4009
|
+
let cdpPort: number | undefined
|
|
4010
|
+
let cdpUrl = process.env.CDP_URL
|
|
4011
|
+
|
|
4012
|
+
// If env var is empty, read from session file
|
|
4013
|
+
if (!cdpUrl) {
|
|
4014
|
+
try {
|
|
4015
|
+
const { existsSync, readFileSync } = await import("fs")
|
|
4016
|
+
const sessionFile = join(getProjectDir(), "session.json")
|
|
4017
|
+
if (existsSync(sessionFile)) {
|
|
4018
|
+
const sessionInfo = JSON.parse(readFileSync(sessionFile, "utf8"))
|
|
4019
|
+
cdpUrl = sessionInfo.cdpUrl
|
|
4020
|
+
}
|
|
4021
|
+
} catch {
|
|
4022
|
+
// Ignore errors reading session file
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
|
|
4026
|
+
if (cdpUrl) {
|
|
4027
|
+
const match = cdpUrl.match(/:(\d+)\//)
|
|
4028
|
+
if (match) {
|
|
4029
|
+
cdpPort = parseInt(match[1], 10)
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
|
|
4033
|
+
// Build common options - include cdpPort to connect to existing browser
|
|
4417
4034
|
const options = {
|
|
4418
4035
|
session,
|
|
4419
|
-
headed
|
|
4036
|
+
headed,
|
|
4037
|
+
profile: defaultProfile,
|
|
4038
|
+
cdpPort
|
|
4420
4039
|
}
|
|
4421
4040
|
|
|
4422
4041
|
let result: unknown
|
|
@@ -4500,6 +4119,13 @@ export async function executeAgentBrowserAction({
|
|
|
4500
4119
|
break
|
|
4501
4120
|
}
|
|
4502
4121
|
|
|
4122
|
+
case "evaluate": {
|
|
4123
|
+
const expression = typeof params.expression === "string" ? params.expression : ""
|
|
4124
|
+
const evalResult = await agentBrowser.evaluate(expression, options)
|
|
4125
|
+
result = evalResult
|
|
4126
|
+
break
|
|
4127
|
+
}
|
|
4128
|
+
|
|
4503
4129
|
default:
|
|
4504
4130
|
return {
|
|
4505
4131
|
content: [
|
package/mcp-server/app/page.tsx
CHANGED
|
@@ -358,7 +358,7 @@ export default function HomePage() {
|
|
|
358
358
|
</div>
|
|
359
359
|
<h3 className="font-semibold mb-3 text-lg">AI Verifies Fixes</h3>
|
|
360
360
|
<p className="text-muted-foreground leading-relaxed">
|
|
361
|
-
|
|
361
|
+
agent_browser_action tests the fixes in real-time with screenshots
|
|
362
362
|
</p>
|
|
363
363
|
</div>
|
|
364
364
|
</div>
|
package/mcp-server/package.json
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@modelcontextprotocol/sdk": "1.18.1",
|
|
15
|
+
"agent-browser": "^0.6.0",
|
|
15
16
|
"@radix-ui/react-slot": "1.2.4",
|
|
16
17
|
"@types/pixelmatch": "^5.2.6",
|
|
17
18
|
"@types/pngjs": "^6.0.5",
|
|
@@ -21,6 +22,7 @@
|
|
|
21
22
|
"mcp-handler": "1.0.2",
|
|
22
23
|
"ms": "^2.1.3",
|
|
23
24
|
"next": "16.1.0",
|
|
25
|
+
"styled-jsx": "5.1.6",
|
|
24
26
|
"pixelmatch": "^7.1.0",
|
|
25
27
|
"pngjs": "^7.0.0",
|
|
26
28
|
"react": "19.3.0-canary-09f05694-20251201",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dev3000",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.154",
|
|
4
4
|
"description": "AI-powered development tools with browser monitoring and MCP server integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
],
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@biomejs/biome": "^2.2.4",
|
|
67
|
-
"@opentui/core": "^0.1.
|
|
67
|
+
"@opentui/core": "^0.1.75",
|
|
68
68
|
"@vercel/sandbox": "^1.1.8",
|
|
69
|
-
"agent-browser": "^0.
|
|
69
|
+
"agent-browser": "^0.6.0",
|
|
70
70
|
"ai": "^5.0.87",
|
|
71
71
|
"chalk": "^5.3.0",
|
|
72
72
|
"commander": "^14.0.1",
|
|
@@ -95,8 +95,9 @@
|
|
|
95
95
|
"vitest": "^3.2.4"
|
|
96
96
|
},
|
|
97
97
|
"optionalDependencies": {
|
|
98
|
-
"@d3k/darwin-arm64": "0.0.
|
|
99
|
-
"@d3k/linux-x64": "0.0.
|
|
98
|
+
"@d3k/darwin-arm64": "0.0.154",
|
|
99
|
+
"@d3k/linux-x64": "0.0.154",
|
|
100
|
+
"@d3k/windows-x64": "0.0.154",
|
|
100
101
|
"@opentui/core-linux-x64": "^0.1.71"
|
|
101
102
|
},
|
|
102
103
|
"engines": {
|