@adhdev/daemon-core 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2662 -0
- package/dist/index.js +11341 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
- package/providers/_builtin/.github/workflows/generate-registry.yml +57 -0
- package/providers/_builtin/COMPATIBILITY.md +217 -0
- package/providers/_builtin/CONTRIBUTING.md +200 -0
- package/providers/_builtin/README.md +119 -0
- package/providers/_builtin/_helpers/index.js +188 -0
- package/providers/_builtin/acp/agentpool/provider.json +54 -0
- package/providers/_builtin/acp/amp/provider.json +52 -0
- package/providers/_builtin/acp/auggie/provider.json +57 -0
- package/providers/_builtin/acp/autodev/provider.json +54 -0
- package/providers/_builtin/acp/autohand/provider.json +52 -0
- package/providers/_builtin/acp/blackbox-ai/provider.json +54 -0
- package/providers/_builtin/acp/claude-agent/provider.json +57 -0
- package/providers/_builtin/acp/cline-acp/provider.json +54 -0
- package/providers/_builtin/acp/codebuddy/provider.json +54 -0
- package/providers/_builtin/acp/codex-cli/provider.json +57 -0
- package/providers/_builtin/acp/corust-agent/provider.json +52 -0
- package/providers/_builtin/acp/crow-cli/provider.json +54 -0
- package/providers/_builtin/acp/cursor-acp/provider.json +54 -0
- package/providers/_builtin/acp/deepagents/provider.json +52 -0
- package/providers/_builtin/acp/dimcode/provider.json +54 -0
- package/providers/_builtin/acp/docker-cagent/provider.json +57 -0
- package/providers/_builtin/acp/factory-droid/provider.json +60 -0
- package/providers/_builtin/acp/fast-agent/provider.json +52 -0
- package/providers/_builtin/acp/gemini-cli/provider.json +114 -0
- package/providers/_builtin/acp/github-copilot/provider.json +54 -0
- package/providers/_builtin/acp/goose/provider.json +57 -0
- package/providers/_builtin/acp/junie/provider.json +52 -0
- package/providers/_builtin/acp/kilo/provider.json +54 -0
- package/providers/_builtin/acp/kimi-cli/provider.json +57 -0
- package/providers/_builtin/acp/minion-code/provider.json +52 -0
- package/providers/_builtin/acp/mistral-vibe/provider.json +57 -0
- package/providers/_builtin/acp/nova/provider.json +54 -0
- package/providers/_builtin/acp/openclaw/provider.json +54 -0
- package/providers/_builtin/acp/opencode/provider.json +52 -0
- package/providers/_builtin/acp/openhands/provider.json +54 -0
- package/providers/_builtin/acp/pi-acp/provider.json +52 -0
- package/providers/_builtin/acp/qoder/provider.json +54 -0
- package/providers/_builtin/acp/qwen-code/provider.json +60 -0
- package/providers/_builtin/acp/stakpak/provider.json +54 -0
- package/providers/_builtin/acp/vtcode/provider.json +54 -0
- package/providers/_builtin/cli/claude-cli/provider.json +100 -0
- package/providers/_builtin/cli/codex-cli/provider.json +89 -0
- package/providers/_builtin/cli/gemini-cli/provider.json +93 -0
- package/providers/_builtin/docs/CDP_SELECTOR_GUIDE.md +370 -0
- package/providers/_builtin/docs/PROVIDER_GUIDE.md +916 -0
- package/providers/_builtin/extension/cline/provider.json +35 -0
- package/providers/_builtin/extension/cline/scripts/focus_editor.js +48 -0
- package/providers/_builtin/extension/cline/scripts/list_chats.js +100 -0
- package/providers/_builtin/extension/cline/scripts/list_models.js +43 -0
- package/providers/_builtin/extension/cline/scripts/list_modes.js +35 -0
- package/providers/_builtin/extension/cline/scripts/new_session.js +85 -0
- package/providers/_builtin/extension/cline/scripts/open_panel.js +25 -0
- package/providers/_builtin/extension/cline/scripts/read_chat.js +257 -0
- package/providers/_builtin/extension/cline/scripts/resolve_action.js +83 -0
- package/providers/_builtin/extension/cline/scripts/send_message.js +95 -0
- package/providers/_builtin/extension/cline/scripts/set_mode.js +36 -0
- package/providers/_builtin/extension/cline/scripts/set_model.js +36 -0
- package/providers/_builtin/extension/cline/scripts/switch_session.js +206 -0
- package/providers/_builtin/extension/cline/scripts.js +73 -0
- package/providers/_builtin/extension/roo-code/provider.json +35 -0
- package/providers/_builtin/extension/roo-code/scripts.js +659 -0
- package/providers/_builtin/ide/antigravity/provider.json +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/focus_editor.js +20 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_chats.js +137 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_models.js +38 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_modes.js +48 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/new_session.js +75 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/read_chat.js +262 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/resolve_action.js +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/scripts.js +57 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/send_message.js +56 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/set_mode.js +34 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/set_model.js +47 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/switch_session.js +114 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/focus_editor.js +20 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_chats.js +137 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_models.js +61 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_modes.js +72 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/new_session.js +75 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/read_chat.js +262 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/resolve_action.js +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/scripts.js +67 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/send_message.js +56 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/set_mode.js +67 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/set_model.js +72 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/switch_session.js +114 -0
- package/providers/_builtin/ide/cursor/provider.json +70 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/dismiss_notification.js +30 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/focus_editor.js +13 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_models.js +78 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_modes.js +40 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_notifications.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_sessions.js +42 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/new_session.js +20 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/open_panel.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/read_chat.js +75 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/resolve_action.js +19 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/scripts.js +78 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/send_message.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/set_mode.js +38 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/set_model.js +81 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/switch_session.js +28 -0
- package/providers/_builtin/ide/kiro/provider.json +67 -0
- package/providers/_builtin/ide/kiro/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/kiro/scripts/open_panel.js +47 -0
- package/providers/_builtin/ide/kiro/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/kiro/scripts/send_message.js +29 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_models.js +39 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_modes.js +39 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_sessions.js +21 -0
- package/providers/_builtin/ide/kiro/scripts/webview_new_session.js +34 -0
- package/providers/_builtin/ide/kiro/scripts/webview_read_chat.js +68 -0
- package/providers/_builtin/ide/kiro/scripts/webview_send_message.js +72 -0
- package/providers/_builtin/ide/kiro/scripts/webview_set_mode.js +15 -0
- package/providers/_builtin/ide/kiro/scripts/webview_set_model.js +15 -0
- package/providers/_builtin/ide/kiro/scripts/webview_switch_session.js +26 -0
- package/providers/_builtin/ide/kiro/scripts.js +62 -0
- package/providers/_builtin/ide/pearai/provider.json +67 -0
- package/providers/_builtin/ide/pearai/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/pearai/scripts/list_sessions.js +38 -0
- package/providers/_builtin/ide/pearai/scripts/new_session.js +55 -0
- package/providers/_builtin/ide/pearai/scripts/open_panel.js +46 -0
- package/providers/_builtin/ide/pearai/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/pearai/scripts/send_message.js +29 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_models.js +43 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_modes.js +35 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_sessions.js +62 -0
- package/providers/_builtin/ide/pearai/scripts/webview_new_session.js +49 -0
- package/providers/_builtin/ide/pearai/scripts/webview_read_chat.js +92 -0
- package/providers/_builtin/ide/pearai/scripts/webview_resolve_action.js +59 -0
- package/providers/_builtin/ide/pearai/scripts/webview_send_message.js +72 -0
- package/providers/_builtin/ide/pearai/scripts/webview_set_mode.js +36 -0
- package/providers/_builtin/ide/pearai/scripts/webview_set_model.js +36 -0
- package/providers/_builtin/ide/pearai/scripts/webview_switch_session.js +34 -0
- package/providers/_builtin/ide/pearai/scripts.js +74 -0
- package/providers/_builtin/ide/trae/provider.json +66 -0
- package/providers/_builtin/ide/trae/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/trae/scripts/list_chats.js +24 -0
- package/providers/_builtin/ide/trae/scripts/list_models.js +39 -0
- package/providers/_builtin/ide/trae/scripts/list_modes.js +39 -0
- package/providers/_builtin/ide/trae/scripts/new_session.js +30 -0
- package/providers/_builtin/ide/trae/scripts/open_panel.js +44 -0
- package/providers/_builtin/ide/trae/scripts/read_chat.js +113 -0
- package/providers/_builtin/ide/trae/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/trae/scripts/send_message.js +69 -0
- package/providers/_builtin/ide/trae/scripts/set_mode.js +15 -0
- package/providers/_builtin/ide/trae/scripts/set_model.js +15 -0
- package/providers/_builtin/ide/trae/scripts/switch_session.js +23 -0
- package/providers/_builtin/ide/trae/scripts.js +57 -0
- package/providers/_builtin/ide/vscode/provider.json +64 -0
- package/providers/_builtin/ide/vscode-insiders/provider.json +62 -0
- package/providers/_builtin/ide/vscodium/provider.json +63 -0
- package/providers/_builtin/ide/windsurf/provider.json +53 -0
- package/providers/_builtin/ide/windsurf/scripts/focus_editor.js +30 -0
- package/providers/_builtin/ide/windsurf/scripts/list_chats.js +117 -0
- package/providers/_builtin/ide/windsurf/scripts/list_models.js +39 -0
- package/providers/_builtin/ide/windsurf/scripts/list_modes.js +39 -0
- package/providers/_builtin/ide/windsurf/scripts/new_session.js +69 -0
- package/providers/_builtin/ide/windsurf/scripts/open_panel.js +58 -0
- package/providers/_builtin/ide/windsurf/scripts/read_chat.js +297 -0
- package/providers/_builtin/ide/windsurf/scripts/resolve_action.js +68 -0
- package/providers/_builtin/ide/windsurf/scripts/send_message.js +87 -0
- package/providers/_builtin/ide/windsurf/scripts/set_mode.js +15 -0
- package/providers/_builtin/ide/windsurf/scripts/set_model.js +15 -0
- package/providers/_builtin/ide/windsurf/scripts/switch_session.js +58 -0
- package/providers/_builtin/ide/windsurf/scripts.js +57 -0
- package/providers/_builtin/registry.json +266 -0
- package/providers/_builtin/validate.js +156 -0
- package/src/agent-stream/index.ts +6 -0
- package/src/agent-stream/manager.ts +286 -0
- package/src/agent-stream/poller.ts +154 -0
- package/src/agent-stream/provider-adapter.ts +138 -0
- package/src/agent-stream/types.ts +61 -0
- package/src/boot/daemon-lifecycle.ts +252 -0
- package/src/cdp/devtools.ts +335 -0
- package/src/cdp/initializer.ts +191 -0
- package/src/cdp/manager.ts +897 -0
- package/src/cdp/scanner.ts +185 -0
- package/src/cdp/setup.ts +150 -0
- package/src/cli-adapter-types.ts +25 -0
- package/src/cli-adapters/provider-cli-adapter.ts +448 -0
- package/src/commands/cdp-commands.ts +208 -0
- package/src/commands/chat-commands.ts +675 -0
- package/src/commands/cli-manager.ts +353 -0
- package/src/commands/handler.ts +328 -0
- package/src/commands/router.ts +258 -0
- package/src/commands/stream-commands.ts +325 -0
- package/src/config/chat-history.ts +211 -0
- package/src/config/config.ts +219 -0
- package/src/daemon/dev-server.ts +2378 -0
- package/src/daemon/scaffold-template.ts +394 -0
- package/src/daemon-core.ts +50 -0
- package/src/detection/cli-detector.ts +89 -0
- package/src/detection/ide-detector.ts +157 -0
- package/src/index.ts +103 -0
- package/src/installer.ts +263 -0
- package/src/ipc-protocol.ts +133 -0
- package/src/launch.ts +433 -0
- package/src/logging/command-log.ts +180 -0
- package/src/logging/logger.ts +316 -0
- package/src/providers/acp-provider-instance.ts +1140 -0
- package/src/providers/cli-provider-instance.ts +207 -0
- package/src/providers/contracts.ts +524 -0
- package/src/providers/extension-provider-instance.ts +156 -0
- package/src/providers/ide-provider-instance.ts +377 -0
- package/src/providers/index.ts +18 -0
- package/src/providers/provider-instance-manager.ts +182 -0
- package/src/providers/provider-instance.ts +112 -0
- package/src/providers/provider-loader.ts +1031 -0
- package/src/providers/status-monitor.ts +125 -0
- package/src/providers/version-archive.ts +266 -0
- package/src/status/reporter.ts +294 -0
- package/src/types.ts +206 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDP DOM Analysis Tools — DOM dump, query, debug
|
|
3
|
+
*
|
|
4
|
+
* Separated from daemon-commands.ts.
|
|
5
|
+
* Tools for analyzing DOM structure when developing new IDE scripts.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { DaemonCdpManager } from './manager.js';
|
|
9
|
+
import type { CommandResult } from '../commands/handler.js';
|
|
10
|
+
|
|
11
|
+
type CdpGetter = (ideType?: string) => DaemonCdpManager | null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* CDP DOM analysis handler
|
|
15
|
+
*
|
|
16
|
+
* Uses getCdp from DaemonCommandHandler.
|
|
17
|
+
*/
|
|
18
|
+
export class CdpDomHandlers {
|
|
19
|
+
private getCdp: CdpGetter;
|
|
20
|
+
|
|
21
|
+
constructor(getCdp: CdpGetter) {
|
|
22
|
+
this.getCdp = getCdp;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* CDP DOM Dump — IDE's DOM tree retrieve
|
|
27
|
+
*
|
|
28
|
+
* args:
|
|
29
|
+
* selector?: string — CSS selector to dump specific area only (default: All)
|
|
30
|
+
* depth?: number — Dump depth limit (default: 10)
|
|
31
|
+
* attrs?: boolean — Whether to include properties (default: true)
|
|
32
|
+
* maxLength?: number — Max character count (default: 200000)
|
|
33
|
+
* format?: 'html' | 'tree' | 'summary' — Output format (default: 'html')
|
|
34
|
+
* sessionId?: string — Agent webview session ID (if provided, match webview DOM)
|
|
35
|
+
*/
|
|
36
|
+
async handleDomDump(args: any): Promise<CommandResult> {
|
|
37
|
+
if (!this.getCdp()?.isConnected) return { success: false, error: 'CDP not connected' };
|
|
38
|
+
|
|
39
|
+
const selector = args?.selector || 'body';
|
|
40
|
+
const depth = args?.depth || 10;
|
|
41
|
+
const maxLength = args?.maxLength || 200000;
|
|
42
|
+
const format = args?.format || 'html';
|
|
43
|
+
const attrs = args?.attrs !== false;
|
|
44
|
+
const sessionId = args?.sessionId;
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
let expression: string;
|
|
48
|
+
|
|
49
|
+
if (format === 'summary') {
|
|
50
|
+
// Summary mode: extract key structure only (classes, tags, roles)
|
|
51
|
+
expression = `(() => {
|
|
52
|
+
const root = document.querySelector('${selector.replace(/'/g, "\\'")}');
|
|
53
|
+
if (!root) return JSON.stringify({ error: 'Selector not found: ${selector}' });
|
|
54
|
+
|
|
55
|
+
function summarize(el, depth, maxD) {
|
|
56
|
+
if (depth > maxD) return { tag: '...', note: 'max depth' };
|
|
57
|
+
const node = {
|
|
58
|
+
tag: el.tagName?.toLowerCase(),
|
|
59
|
+
id: el.id || undefined,
|
|
60
|
+
class: el.className && typeof el.className === 'string' ? el.className.split(' ').filter(c => c).slice(0, 5).join(' ') : undefined,
|
|
61
|
+
role: el.getAttribute?.('role') || undefined,
|
|
62
|
+
'data-testid': el.getAttribute?.('data-testid') || undefined,
|
|
63
|
+
childCount: el.children?.length || 0,
|
|
64
|
+
};
|
|
65
|
+
if (el.children?.length > 0 && depth < maxD) {
|
|
66
|
+
node.children = Array.from(el.children).slice(0, 30).map(c => summarize(c, depth + 1, maxD));
|
|
67
|
+
}
|
|
68
|
+
return node;
|
|
69
|
+
}
|
|
70
|
+
return JSON.stringify(summarize(root, 0, ${depth}));
|
|
71
|
+
})()`;
|
|
72
|
+
} else if (format === 'tree') {
|
|
73
|
+
// Tree mode: text-based tree view
|
|
74
|
+
expression = `(() => {
|
|
75
|
+
const root = document.querySelector('${selector.replace(/'/g, "\\'")}');
|
|
76
|
+
if (!root) return 'Selector not found: ${selector}';
|
|
77
|
+
|
|
78
|
+
function tree(el, indent, depth, maxD) {
|
|
79
|
+
if (depth > maxD) return indent + '...\\n';
|
|
80
|
+
let line = indent + '<' + (el.tagName?.toLowerCase() || '?');
|
|
81
|
+
if (el.id) line += ' #' + el.id;
|
|
82
|
+
if (el.className && typeof el.className === 'string') {
|
|
83
|
+
const cls = el.className.trim().split(' ').filter(c => c).slice(0, 3).join('.');
|
|
84
|
+
if (cls) line += ' .' + cls;
|
|
85
|
+
}
|
|
86
|
+
const role = el.getAttribute?.('role');
|
|
87
|
+
if (role) line += ' [role=' + role + ']';
|
|
88
|
+
const testId = el.getAttribute?.('data-testid');
|
|
89
|
+
if (testId) line += ' [data-testid=' + testId + ']';
|
|
90
|
+
line += '> (' + (el.children?.length || 0) + ')\\n';
|
|
91
|
+
|
|
92
|
+
let result = line;
|
|
93
|
+
if (el.children?.length > 0 && depth < maxD) {
|
|
94
|
+
for (let i = 0; i < Math.min(el.children.length, 30); i++) {
|
|
95
|
+
result += tree(el.children[i], indent + ' ', depth + 1, maxD);
|
|
96
|
+
}
|
|
97
|
+
if (el.children.length > 30) result += indent + ' ... +' + (el.children.length - 30) + ' more\\n';
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
return tree(root, '', 0, ${depth});
|
|
102
|
+
})()`;
|
|
103
|
+
} else {
|
|
104
|
+
// HTML mode: full dump via outerHTML
|
|
105
|
+
expression = `(() => {
|
|
106
|
+
const root = document.querySelector('${selector.replace(/'/g, "\\'")}');
|
|
107
|
+
if (!root) return 'Selector not found: ${selector}';
|
|
108
|
+
let html = root.outerHTML;
|
|
109
|
+
if (html.length > ${maxLength}) {
|
|
110
|
+
html = html.slice(0, ${maxLength}) + '\\n<!-- TRUNCATED at ${maxLength} chars -->';
|
|
111
|
+
}
|
|
112
|
+
return html;
|
|
113
|
+
})()`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let result;
|
|
117
|
+
if (sessionId) {
|
|
118
|
+
result = await this.getCdp()!.evaluateInSession(sessionId, expression);
|
|
119
|
+
} else {
|
|
120
|
+
result = await this.getCdp()!.evaluate(expression, 30000);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Summary mode JSON parsing
|
|
124
|
+
if (format === 'summary' && typeof result === 'string') {
|
|
125
|
+
try {
|
|
126
|
+
result = JSON.parse(result);
|
|
127
|
+
} catch { /* keep as string */ }
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const size = typeof result === 'string' ? result.length : JSON.stringify(result).length;
|
|
131
|
+
return { success: true, result, format, selector, size };
|
|
132
|
+
} catch (e: any) {
|
|
133
|
+
return { success: false, error: e.message };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* CDP DOM Query — CSS Test selector
|
|
139
|
+
* Check how many elements match selector and what elements they are
|
|
140
|
+
*
|
|
141
|
+
* args:
|
|
142
|
+
* selector: string — CSS selector
|
|
143
|
+
* limit?: number — Max element count to return (default: 20)
|
|
144
|
+
* content?: boolean — Whether to include text content (default: true)
|
|
145
|
+
* sessionId?: string — agent webview session ID
|
|
146
|
+
*/
|
|
147
|
+
async handleDomQuery(args: any): Promise<CommandResult> {
|
|
148
|
+
if (!this.getCdp()?.isConnected) return { success: false, error: 'CDP not connected' };
|
|
149
|
+
|
|
150
|
+
const selector = args?.selector;
|
|
151
|
+
if (!selector) return { success: false, error: 'selector required' };
|
|
152
|
+
const limit = args?.limit || 20;
|
|
153
|
+
const content = args?.content !== false;
|
|
154
|
+
const sessionId = args?.sessionId;
|
|
155
|
+
|
|
156
|
+
const expression = `(() => {
|
|
157
|
+
try {
|
|
158
|
+
const els = document.querySelectorAll('${selector.replace(/'/g, "\\'")}');
|
|
159
|
+
const results = [];
|
|
160
|
+
for (let i = 0; i < Math.min(els.length, ${limit}); i++) {
|
|
161
|
+
const el = els[i];
|
|
162
|
+
const item = {
|
|
163
|
+
index: i,
|
|
164
|
+
tag: el.tagName?.toLowerCase(),
|
|
165
|
+
id: el.id || null,
|
|
166
|
+
class: el.className && typeof el.className === 'string' ? el.className.trim().slice(0, 200) : null,
|
|
167
|
+
role: el.getAttribute?.('role') || null,
|
|
168
|
+
'data-testid': el.getAttribute?.('data-testid') || null,
|
|
169
|
+
rect: (() => { try { const r = el.getBoundingClientRect(); return { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) }; } catch { return null; } })(),
|
|
170
|
+
visible: el.offsetParent !== null || el.offsetWidth > 0,
|
|
171
|
+
};
|
|
172
|
+
${content ? `item.text = (el.textContent || '').trim().slice(0, 200);` : ''}
|
|
173
|
+
${content ? `item.value = el.value !== undefined ? String(el.value).slice(0, 200) : undefined;` : ''}
|
|
174
|
+
results.push(item);
|
|
175
|
+
}
|
|
176
|
+
return JSON.stringify({ total: els.length, results });
|
|
177
|
+
} catch(e) {
|
|
178
|
+
return JSON.stringify({ error: e.message });
|
|
179
|
+
}
|
|
180
|
+
})()`;
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
let raw;
|
|
184
|
+
if (sessionId) {
|
|
185
|
+
raw = await this.getCdp()!.evaluateInSession(sessionId, expression);
|
|
186
|
+
} else {
|
|
187
|
+
raw = await this.getCdp()!.evaluate(expression, 15000);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
191
|
+
return { success: true, ...parsed, selector };
|
|
192
|
+
} catch (e: any) {
|
|
193
|
+
return { success: false, error: e.message };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* CDP DOM Debug — IDE AI panel specialized analysis
|
|
199
|
+
* Collect all essential info at once when supporting new IDE
|
|
200
|
+
*
|
|
201
|
+
* args:
|
|
202
|
+
* ideType?: string — IDE type hint
|
|
203
|
+
* sessionId?: string — agent webview session ID
|
|
204
|
+
*/
|
|
205
|
+
async handleDomDebug(args: any): Promise<CommandResult> {
|
|
206
|
+
if (!this.getCdp()?.isConnected) return { success: false, error: 'CDP not connected' };
|
|
207
|
+
const sessionId = args?.sessionId;
|
|
208
|
+
|
|
209
|
+
const expression = `(() => {
|
|
210
|
+
const result = {
|
|
211
|
+
url: location.href,
|
|
212
|
+
title: document.title,
|
|
213
|
+
viewport: { w: window.innerWidth, h: window.innerHeight },
|
|
214
|
+
|
|
215
|
+
// Input field info
|
|
216
|
+
inputs: [],
|
|
217
|
+
// Textarea info
|
|
218
|
+
textareas: [],
|
|
219
|
+
// Contenteditable info
|
|
220
|
+
editables: [],
|
|
221
|
+
// Buttons (send, submit etc)
|
|
222
|
+
buttons: [],
|
|
223
|
+
// iframes (agent webviews)
|
|
224
|
+
iframes: [],
|
|
225
|
+
// role="textbox" info
|
|
226
|
+
textboxes: [],
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Input fields
|
|
230
|
+
document.querySelectorAll('input[type="text"], input:not([type])').forEach((el, i) => {
|
|
231
|
+
if (i >= 10) return;
|
|
232
|
+
result.inputs.push({
|
|
233
|
+
tag: 'input',
|
|
234
|
+
id: el.id || null,
|
|
235
|
+
class: (el.className || '').toString().slice(0, 150),
|
|
236
|
+
placeholder: el.getAttribute('placeholder') || null,
|
|
237
|
+
name: el.name || null,
|
|
238
|
+
value: el.value?.slice(0, 100) || null,
|
|
239
|
+
visible: el.offsetParent !== null,
|
|
240
|
+
rect: (() => { try { const r = el.getBoundingClientRect(); return { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) }; } catch { return null; } })(),
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// textarea
|
|
245
|
+
document.querySelectorAll('textarea').forEach((el, i) => {
|
|
246
|
+
if (i >= 10) return;
|
|
247
|
+
result.textareas.push({
|
|
248
|
+
id: el.id || null,
|
|
249
|
+
class: (el.className || '').toString().slice(0, 150),
|
|
250
|
+
placeholder: el.getAttribute('placeholder') || null,
|
|
251
|
+
rows: el.rows,
|
|
252
|
+
value: el.value?.slice(0, 100) || null,
|
|
253
|
+
visible: el.offsetParent !== null,
|
|
254
|
+
rect: (() => { try { const r = el.getBoundingClientRect(); return { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) }; } catch { return null; } })(),
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// contenteditable
|
|
259
|
+
document.querySelectorAll('[contenteditable="true"]').forEach((el, i) => {
|
|
260
|
+
if (i >= 10) return;
|
|
261
|
+
result.editables.push({
|
|
262
|
+
tag: el.tagName?.toLowerCase(),
|
|
263
|
+
id: el.id || null,
|
|
264
|
+
class: (el.className || '').toString().slice(0, 150),
|
|
265
|
+
role: el.getAttribute('role') || null,
|
|
266
|
+
text: (el.textContent || '').trim().slice(0, 100),
|
|
267
|
+
visible: el.offsetParent !== null,
|
|
268
|
+
rect: (() => { try { const r = el.getBoundingClientRect(); return { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) }; } catch { return null; } })(),
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// role="textbox"
|
|
273
|
+
document.querySelectorAll('[role="textbox"]').forEach((el, i) => {
|
|
274
|
+
if (i >= 10) return;
|
|
275
|
+
result.textboxes.push({
|
|
276
|
+
tag: el.tagName?.toLowerCase(),
|
|
277
|
+
id: el.id || null,
|
|
278
|
+
class: (el.className || '').toString().slice(0, 150),
|
|
279
|
+
'aria-label': el.getAttribute('aria-label') || null,
|
|
280
|
+
text: (el.textContent || '').trim().slice(0, 100),
|
|
281
|
+
visible: el.offsetParent !== null,
|
|
282
|
+
rect: (() => { try { const r = el.getBoundingClientRect(); return { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) }; } catch { return null; } })(),
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Buttons (send, submit, accept, reject, approve etc)
|
|
287
|
+
const btnKeywords = /send|submit|accept|reject|approve|deny|cancel|confirm|run|execute|apply/i;
|
|
288
|
+
document.querySelectorAll('button, [role="button"], input[type="submit"]').forEach((el, i) => {
|
|
289
|
+
const text = (el.textContent || el.getAttribute('aria-label') || '').trim();
|
|
290
|
+
if (i < 30 && (text.length < 30 || btnKeywords.test(text))) {
|
|
291
|
+
result.buttons.push({
|
|
292
|
+
tag: el.tagName?.toLowerCase(),
|
|
293
|
+
id: el.id || null,
|
|
294
|
+
class: (el.className || '').toString().slice(0, 150),
|
|
295
|
+
text: text.slice(0, 80),
|
|
296
|
+
'aria-label': el.getAttribute('aria-label') || null,
|
|
297
|
+
disabled: el.disabled || el.getAttribute('disabled') !== null,
|
|
298
|
+
visible: el.offsetParent !== null,
|
|
299
|
+
rect: (() => { try { const r = el.getBoundingClientRect(); return { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) }; } catch { return null; } })(),
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// iframes
|
|
305
|
+
document.querySelectorAll('iframe, webview').forEach((el, i) => {
|
|
306
|
+
if (i >= 20) return;
|
|
307
|
+
result.iframes.push({
|
|
308
|
+
tag: el.tagName?.toLowerCase(),
|
|
309
|
+
id: el.id || null,
|
|
310
|
+
class: (el.className || '').toString().slice(0, 150),
|
|
311
|
+
src: el.getAttribute('src')?.slice(0, 200) || null,
|
|
312
|
+
title: el.getAttribute('title') || null,
|
|
313
|
+
visible: el.offsetParent !== null,
|
|
314
|
+
rect: (() => { try { const r = el.getBoundingClientRect(); return { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) }; } catch { return null; } })(),
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
return JSON.stringify(result);
|
|
319
|
+
})()`;
|
|
320
|
+
|
|
321
|
+
try {
|
|
322
|
+
let raw;
|
|
323
|
+
if (sessionId) {
|
|
324
|
+
raw = await this.getCdp()!.evaluateInSession(sessionId, expression);
|
|
325
|
+
} else {
|
|
326
|
+
raw = await this.getCdp()!.evaluate(expression, 30000);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
330
|
+
return { success: true, ...parsed };
|
|
331
|
+
} catch (e: any) {
|
|
332
|
+
return { success: false, error: e.message };
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DaemonCdpInitializer — Unified CDP initialization + periodic scanning
|
|
3
|
+
*
|
|
4
|
+
* Replaces initCdp() in both cloud and standalone daemons.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* 1. Initial connection: connectAll() — multi-window aware
|
|
8
|
+
* 2. Periodic scan: startPeriodicScan() — auto-detect newly opened IDEs
|
|
9
|
+
* 3. Discovery: startDiscovery() — periodic agent webview discovery
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { DaemonCdpManager } from './manager.js';
|
|
13
|
+
import { registerExtensionProviders } from './setup.js';
|
|
14
|
+
import { probeCdpPort } from './setup.js';
|
|
15
|
+
import type { ProviderLoader } from '../providers/provider-loader.js';
|
|
16
|
+
import { LOG } from '../logging/logger.js';
|
|
17
|
+
|
|
18
|
+
// ─── Config ───
|
|
19
|
+
|
|
20
|
+
export interface CdpInitializerConfig {
|
|
21
|
+
providerLoader: ProviderLoader;
|
|
22
|
+
cdpManagers: Map<string, DaemonCdpManager>;
|
|
23
|
+
/** Filter: only connect these IDEs (empty/undefined = all) */
|
|
24
|
+
enabledIdes?: string[];
|
|
25
|
+
/** Callback when a new CDP manager is connected */
|
|
26
|
+
onConnected?: (ideType: string, manager: DaemonCdpManager, managerKey: string) => void | Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class DaemonCdpInitializer {
|
|
30
|
+
private config: CdpInitializerConfig;
|
|
31
|
+
private scanTimer: NodeJS.Timeout | null = null;
|
|
32
|
+
private discoveryTimer: NodeJS.Timeout | null = null;
|
|
33
|
+
|
|
34
|
+
constructor(config: CdpInitializerConfig) {
|
|
35
|
+
this.config = config;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ─── Initial connection ───
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Connect to all detected IDEs.
|
|
42
|
+
* Multi-window aware: creates separate CdpManager per workbench page.
|
|
43
|
+
*/
|
|
44
|
+
async connectAll(detectedIdes: any[]): Promise<void> {
|
|
45
|
+
const { providerLoader, cdpManagers, enabledIdes } = this.config;
|
|
46
|
+
const providerCdpMap = providerLoader.getCdpPortMap();
|
|
47
|
+
|
|
48
|
+
// Build port list sorted by detected IDE order
|
|
49
|
+
const portsToTry: { port: number; ide: string }[] = [];
|
|
50
|
+
for (const ide of detectedIdes) {
|
|
51
|
+
if (!ide.installed) continue;
|
|
52
|
+
const ideKey = ide.id || ide.name?.toLowerCase();
|
|
53
|
+
const ports = providerCdpMap[ideKey];
|
|
54
|
+
if (ports) portsToTry.push({ port: ports[0], ide: ideKey });
|
|
55
|
+
}
|
|
56
|
+
// Add undetected IDE ports (provider-based)
|
|
57
|
+
for (const [ide, ports] of Object.entries(providerCdpMap)) {
|
|
58
|
+
if (!portsToTry.find(p => p.port === ports[0])) {
|
|
59
|
+
portsToTry.push({ port: ports[0], ide });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Filter by enabledIdes
|
|
64
|
+
const filtered = enabledIdes?.length
|
|
65
|
+
? portsToTry.filter(p => enabledIdes.includes(p.ide))
|
|
66
|
+
: portsToTry;
|
|
67
|
+
|
|
68
|
+
for (const { port, ide } of filtered) {
|
|
69
|
+
await this.connectIdePort(port, ide);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Summary
|
|
73
|
+
if (cdpManagers.size > 0) {
|
|
74
|
+
LOG.info('CDP', `${cdpManagers.size} IDE(s) connected: ${[...cdpManagers.entries()].map(([k, m]) => `${k}:${m.getPort()}`).join(', ')}`);
|
|
75
|
+
} else {
|
|
76
|
+
LOG.warn('CDP', `No IDEs connected — tried: ${filtered.map(p => `${p.ide}:${p.port}`).join(', ')}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ─── Per-port connection (multi-window aware) ───
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Connect to a single IDE port.
|
|
84
|
+
* Tries multi-window first (listAllTargets), falls back to direct connect.
|
|
85
|
+
*/
|
|
86
|
+
private async connectIdePort(port: number, ide: string): Promise<void> {
|
|
87
|
+
const { providerLoader, cdpManagers } = this.config;
|
|
88
|
+
|
|
89
|
+
// 1. Try multi-window: list all workbench pages on this port
|
|
90
|
+
const targets = await DaemonCdpManager.listAllTargets(port);
|
|
91
|
+
|
|
92
|
+
if (targets.length === 0) {
|
|
93
|
+
// Fallback: direct single connection (probeCdpPort first)
|
|
94
|
+
if (!await probeCdpPort(port)) return;
|
|
95
|
+
const provider = providerLoader.getMeta(ide);
|
|
96
|
+
const manager = new DaemonCdpManager(
|
|
97
|
+
port,
|
|
98
|
+
LOG.forComponent(`CDP:${ide}`).asLogFn(),
|
|
99
|
+
undefined,
|
|
100
|
+
(provider as any)?.targetFilter,
|
|
101
|
+
);
|
|
102
|
+
const connected = await manager.connect();
|
|
103
|
+
if (connected) {
|
|
104
|
+
registerExtensionProviders(providerLoader, manager, ide);
|
|
105
|
+
cdpManagers.set(ide, manager);
|
|
106
|
+
LOG.info('CDP', `Connected: ${ide} (port ${port})`);
|
|
107
|
+
await this.config.onConnected?.(ide, manager, ide);
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 2. Multi-window: create separate CdpManager per page
|
|
113
|
+
for (let i = 0; i < targets.length; i++) {
|
|
114
|
+
const target = targets[i];
|
|
115
|
+
// Key: single page = ide type as-is, multi-page = ide_workspaceName
|
|
116
|
+
let managerKey: string;
|
|
117
|
+
if (targets.length === 1) {
|
|
118
|
+
managerKey = ide;
|
|
119
|
+
} else {
|
|
120
|
+
const workspaceName = (target.title || '').split(' — ')[0].trim() || `window_${i}`;
|
|
121
|
+
managerKey = `${ide}_${workspaceName}`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (cdpManagers.has(managerKey)) continue;
|
|
125
|
+
|
|
126
|
+
const provider = providerLoader.getMeta(ide);
|
|
127
|
+
const manager = new DaemonCdpManager(
|
|
128
|
+
port,
|
|
129
|
+
LOG.forComponent(`CDP:${managerKey}`).asLogFn(),
|
|
130
|
+
target.id,
|
|
131
|
+
(provider as any)?.targetFilter,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const connected = await manager.connect();
|
|
135
|
+
if (connected) {
|
|
136
|
+
registerExtensionProviders(providerLoader, manager, ide);
|
|
137
|
+
cdpManagers.set(managerKey, manager);
|
|
138
|
+
LOG.info('CDP', `Connected: ${managerKey} (port ${port}${targets.length > 1 ? `, page "${target.title}"` : ''})`);
|
|
139
|
+
await this.config.onConnected?.(ide, manager, managerKey);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ─── Periodic scanning ───
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Start periodic scanning for newly opened IDEs.
|
|
148
|
+
* Idempotent — ignored if already started.
|
|
149
|
+
*/
|
|
150
|
+
startPeriodicScan(intervalMs = 30_000): void {
|
|
151
|
+
if (this.scanTimer) return;
|
|
152
|
+
|
|
153
|
+
this.scanTimer = setInterval(async () => {
|
|
154
|
+
const { providerLoader, cdpManagers } = this.config;
|
|
155
|
+
const portMap = providerLoader.getCdpPortMap();
|
|
156
|
+
|
|
157
|
+
for (const [ide, ports] of Object.entries(portMap)) {
|
|
158
|
+
const primaryPort = ports[0];
|
|
159
|
+
|
|
160
|
+
// Skip if already connected
|
|
161
|
+
const alreadyConnected = [...cdpManagers.entries()].some(([key, m]) =>
|
|
162
|
+
m.isConnected && (key === ide || key.startsWith(ide + '_'))
|
|
163
|
+
);
|
|
164
|
+
if (alreadyConnected) continue;
|
|
165
|
+
|
|
166
|
+
await this.connectIdePort(primaryPort, ide);
|
|
167
|
+
}
|
|
168
|
+
}, intervalMs);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Start periodic agent webview discovery.
|
|
173
|
+
*/
|
|
174
|
+
startDiscovery(intervalMs = 30_000): void {
|
|
175
|
+
if (this.discoveryTimer) return;
|
|
176
|
+
|
|
177
|
+
this.discoveryTimer = setInterval(async () => {
|
|
178
|
+
for (const m of this.config.cdpManagers.values()) {
|
|
179
|
+
if (m.isConnected) {
|
|
180
|
+
await m.discoverAgentWebviews();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}, intervalMs);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Stop all timers */
|
|
187
|
+
stop(): void {
|
|
188
|
+
if (this.scanTimer) { clearInterval(this.scanTimer); this.scanTimer = null; }
|
|
189
|
+
if (this.discoveryTimer) { clearInterval(this.discoveryTimer); this.discoveryTimer = null; }
|
|
190
|
+
}
|
|
191
|
+
}
|