@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.
Files changed (217) hide show
  1. package/dist/index.d.ts +2662 -0
  2. package/dist/index.js +11341 -0
  3. package/dist/index.js.map +1 -0
  4. package/package.json +48 -0
  5. package/providers/_builtin/.github/workflows/generate-registry.yml +57 -0
  6. package/providers/_builtin/COMPATIBILITY.md +217 -0
  7. package/providers/_builtin/CONTRIBUTING.md +200 -0
  8. package/providers/_builtin/README.md +119 -0
  9. package/providers/_builtin/_helpers/index.js +188 -0
  10. package/providers/_builtin/acp/agentpool/provider.json +54 -0
  11. package/providers/_builtin/acp/amp/provider.json +52 -0
  12. package/providers/_builtin/acp/auggie/provider.json +57 -0
  13. package/providers/_builtin/acp/autodev/provider.json +54 -0
  14. package/providers/_builtin/acp/autohand/provider.json +52 -0
  15. package/providers/_builtin/acp/blackbox-ai/provider.json +54 -0
  16. package/providers/_builtin/acp/claude-agent/provider.json +57 -0
  17. package/providers/_builtin/acp/cline-acp/provider.json +54 -0
  18. package/providers/_builtin/acp/codebuddy/provider.json +54 -0
  19. package/providers/_builtin/acp/codex-cli/provider.json +57 -0
  20. package/providers/_builtin/acp/corust-agent/provider.json +52 -0
  21. package/providers/_builtin/acp/crow-cli/provider.json +54 -0
  22. package/providers/_builtin/acp/cursor-acp/provider.json +54 -0
  23. package/providers/_builtin/acp/deepagents/provider.json +52 -0
  24. package/providers/_builtin/acp/dimcode/provider.json +54 -0
  25. package/providers/_builtin/acp/docker-cagent/provider.json +57 -0
  26. package/providers/_builtin/acp/factory-droid/provider.json +60 -0
  27. package/providers/_builtin/acp/fast-agent/provider.json +52 -0
  28. package/providers/_builtin/acp/gemini-cli/provider.json +114 -0
  29. package/providers/_builtin/acp/github-copilot/provider.json +54 -0
  30. package/providers/_builtin/acp/goose/provider.json +57 -0
  31. package/providers/_builtin/acp/junie/provider.json +52 -0
  32. package/providers/_builtin/acp/kilo/provider.json +54 -0
  33. package/providers/_builtin/acp/kimi-cli/provider.json +57 -0
  34. package/providers/_builtin/acp/minion-code/provider.json +52 -0
  35. package/providers/_builtin/acp/mistral-vibe/provider.json +57 -0
  36. package/providers/_builtin/acp/nova/provider.json +54 -0
  37. package/providers/_builtin/acp/openclaw/provider.json +54 -0
  38. package/providers/_builtin/acp/opencode/provider.json +52 -0
  39. package/providers/_builtin/acp/openhands/provider.json +54 -0
  40. package/providers/_builtin/acp/pi-acp/provider.json +52 -0
  41. package/providers/_builtin/acp/qoder/provider.json +54 -0
  42. package/providers/_builtin/acp/qwen-code/provider.json +60 -0
  43. package/providers/_builtin/acp/stakpak/provider.json +54 -0
  44. package/providers/_builtin/acp/vtcode/provider.json +54 -0
  45. package/providers/_builtin/cli/claude-cli/provider.json +100 -0
  46. package/providers/_builtin/cli/codex-cli/provider.json +89 -0
  47. package/providers/_builtin/cli/gemini-cli/provider.json +93 -0
  48. package/providers/_builtin/docs/CDP_SELECTOR_GUIDE.md +370 -0
  49. package/providers/_builtin/docs/PROVIDER_GUIDE.md +916 -0
  50. package/providers/_builtin/extension/cline/provider.json +35 -0
  51. package/providers/_builtin/extension/cline/scripts/focus_editor.js +48 -0
  52. package/providers/_builtin/extension/cline/scripts/list_chats.js +100 -0
  53. package/providers/_builtin/extension/cline/scripts/list_models.js +43 -0
  54. package/providers/_builtin/extension/cline/scripts/list_modes.js +35 -0
  55. package/providers/_builtin/extension/cline/scripts/new_session.js +85 -0
  56. package/providers/_builtin/extension/cline/scripts/open_panel.js +25 -0
  57. package/providers/_builtin/extension/cline/scripts/read_chat.js +257 -0
  58. package/providers/_builtin/extension/cline/scripts/resolve_action.js +83 -0
  59. package/providers/_builtin/extension/cline/scripts/send_message.js +95 -0
  60. package/providers/_builtin/extension/cline/scripts/set_mode.js +36 -0
  61. package/providers/_builtin/extension/cline/scripts/set_model.js +36 -0
  62. package/providers/_builtin/extension/cline/scripts/switch_session.js +206 -0
  63. package/providers/_builtin/extension/cline/scripts.js +73 -0
  64. package/providers/_builtin/extension/roo-code/provider.json +35 -0
  65. package/providers/_builtin/extension/roo-code/scripts.js +659 -0
  66. package/providers/_builtin/ide/antigravity/provider.json +68 -0
  67. package/providers/_builtin/ide/antigravity/scripts/1.106/focus_editor.js +20 -0
  68. package/providers/_builtin/ide/antigravity/scripts/1.106/list_chats.js +137 -0
  69. package/providers/_builtin/ide/antigravity/scripts/1.106/list_models.js +38 -0
  70. package/providers/_builtin/ide/antigravity/scripts/1.106/list_modes.js +48 -0
  71. package/providers/_builtin/ide/antigravity/scripts/1.106/new_session.js +75 -0
  72. package/providers/_builtin/ide/antigravity/scripts/1.106/read_chat.js +262 -0
  73. package/providers/_builtin/ide/antigravity/scripts/1.106/resolve_action.js +68 -0
  74. package/providers/_builtin/ide/antigravity/scripts/1.106/scripts.js +57 -0
  75. package/providers/_builtin/ide/antigravity/scripts/1.106/send_message.js +56 -0
  76. package/providers/_builtin/ide/antigravity/scripts/1.106/set_mode.js +34 -0
  77. package/providers/_builtin/ide/antigravity/scripts/1.106/set_model.js +47 -0
  78. package/providers/_builtin/ide/antigravity/scripts/1.106/switch_session.js +114 -0
  79. package/providers/_builtin/ide/antigravity/scripts/1.107/focus_editor.js +20 -0
  80. package/providers/_builtin/ide/antigravity/scripts/1.107/list_chats.js +137 -0
  81. package/providers/_builtin/ide/antigravity/scripts/1.107/list_models.js +61 -0
  82. package/providers/_builtin/ide/antigravity/scripts/1.107/list_modes.js +72 -0
  83. package/providers/_builtin/ide/antigravity/scripts/1.107/new_session.js +75 -0
  84. package/providers/_builtin/ide/antigravity/scripts/1.107/read_chat.js +262 -0
  85. package/providers/_builtin/ide/antigravity/scripts/1.107/resolve_action.js +68 -0
  86. package/providers/_builtin/ide/antigravity/scripts/1.107/scripts.js +67 -0
  87. package/providers/_builtin/ide/antigravity/scripts/1.107/send_message.js +56 -0
  88. package/providers/_builtin/ide/antigravity/scripts/1.107/set_mode.js +67 -0
  89. package/providers/_builtin/ide/antigravity/scripts/1.107/set_model.js +72 -0
  90. package/providers/_builtin/ide/antigravity/scripts/1.107/switch_session.js +114 -0
  91. package/providers/_builtin/ide/cursor/provider.json +70 -0
  92. package/providers/_builtin/ide/cursor/scripts/0.49/dismiss_notification.js +30 -0
  93. package/providers/_builtin/ide/cursor/scripts/0.49/focus_editor.js +13 -0
  94. package/providers/_builtin/ide/cursor/scripts/0.49/list_models.js +78 -0
  95. package/providers/_builtin/ide/cursor/scripts/0.49/list_modes.js +40 -0
  96. package/providers/_builtin/ide/cursor/scripts/0.49/list_notifications.js +23 -0
  97. package/providers/_builtin/ide/cursor/scripts/0.49/list_sessions.js +42 -0
  98. package/providers/_builtin/ide/cursor/scripts/0.49/new_session.js +20 -0
  99. package/providers/_builtin/ide/cursor/scripts/0.49/open_panel.js +23 -0
  100. package/providers/_builtin/ide/cursor/scripts/0.49/read_chat.js +75 -0
  101. package/providers/_builtin/ide/cursor/scripts/0.49/resolve_action.js +19 -0
  102. package/providers/_builtin/ide/cursor/scripts/0.49/scripts.js +78 -0
  103. package/providers/_builtin/ide/cursor/scripts/0.49/send_message.js +23 -0
  104. package/providers/_builtin/ide/cursor/scripts/0.49/set_mode.js +38 -0
  105. package/providers/_builtin/ide/cursor/scripts/0.49/set_model.js +81 -0
  106. package/providers/_builtin/ide/cursor/scripts/0.49/switch_session.js +28 -0
  107. package/providers/_builtin/ide/kiro/provider.json +67 -0
  108. package/providers/_builtin/ide/kiro/scripts/focus_editor.js +20 -0
  109. package/providers/_builtin/ide/kiro/scripts/open_panel.js +47 -0
  110. package/providers/_builtin/ide/kiro/scripts/resolve_action.js +54 -0
  111. package/providers/_builtin/ide/kiro/scripts/send_message.js +29 -0
  112. package/providers/_builtin/ide/kiro/scripts/webview_list_models.js +39 -0
  113. package/providers/_builtin/ide/kiro/scripts/webview_list_modes.js +39 -0
  114. package/providers/_builtin/ide/kiro/scripts/webview_list_sessions.js +21 -0
  115. package/providers/_builtin/ide/kiro/scripts/webview_new_session.js +34 -0
  116. package/providers/_builtin/ide/kiro/scripts/webview_read_chat.js +68 -0
  117. package/providers/_builtin/ide/kiro/scripts/webview_send_message.js +72 -0
  118. package/providers/_builtin/ide/kiro/scripts/webview_set_mode.js +15 -0
  119. package/providers/_builtin/ide/kiro/scripts/webview_set_model.js +15 -0
  120. package/providers/_builtin/ide/kiro/scripts/webview_switch_session.js +26 -0
  121. package/providers/_builtin/ide/kiro/scripts.js +62 -0
  122. package/providers/_builtin/ide/pearai/provider.json +67 -0
  123. package/providers/_builtin/ide/pearai/scripts/focus_editor.js +20 -0
  124. package/providers/_builtin/ide/pearai/scripts/list_sessions.js +38 -0
  125. package/providers/_builtin/ide/pearai/scripts/new_session.js +55 -0
  126. package/providers/_builtin/ide/pearai/scripts/open_panel.js +46 -0
  127. package/providers/_builtin/ide/pearai/scripts/resolve_action.js +54 -0
  128. package/providers/_builtin/ide/pearai/scripts/send_message.js +29 -0
  129. package/providers/_builtin/ide/pearai/scripts/webview_list_models.js +43 -0
  130. package/providers/_builtin/ide/pearai/scripts/webview_list_modes.js +35 -0
  131. package/providers/_builtin/ide/pearai/scripts/webview_list_sessions.js +62 -0
  132. package/providers/_builtin/ide/pearai/scripts/webview_new_session.js +49 -0
  133. package/providers/_builtin/ide/pearai/scripts/webview_read_chat.js +92 -0
  134. package/providers/_builtin/ide/pearai/scripts/webview_resolve_action.js +59 -0
  135. package/providers/_builtin/ide/pearai/scripts/webview_send_message.js +72 -0
  136. package/providers/_builtin/ide/pearai/scripts/webview_set_mode.js +36 -0
  137. package/providers/_builtin/ide/pearai/scripts/webview_set_model.js +36 -0
  138. package/providers/_builtin/ide/pearai/scripts/webview_switch_session.js +34 -0
  139. package/providers/_builtin/ide/pearai/scripts.js +74 -0
  140. package/providers/_builtin/ide/trae/provider.json +66 -0
  141. package/providers/_builtin/ide/trae/scripts/focus_editor.js +20 -0
  142. package/providers/_builtin/ide/trae/scripts/list_chats.js +24 -0
  143. package/providers/_builtin/ide/trae/scripts/list_models.js +39 -0
  144. package/providers/_builtin/ide/trae/scripts/list_modes.js +39 -0
  145. package/providers/_builtin/ide/trae/scripts/new_session.js +30 -0
  146. package/providers/_builtin/ide/trae/scripts/open_panel.js +44 -0
  147. package/providers/_builtin/ide/trae/scripts/read_chat.js +113 -0
  148. package/providers/_builtin/ide/trae/scripts/resolve_action.js +54 -0
  149. package/providers/_builtin/ide/trae/scripts/send_message.js +69 -0
  150. package/providers/_builtin/ide/trae/scripts/set_mode.js +15 -0
  151. package/providers/_builtin/ide/trae/scripts/set_model.js +15 -0
  152. package/providers/_builtin/ide/trae/scripts/switch_session.js +23 -0
  153. package/providers/_builtin/ide/trae/scripts.js +57 -0
  154. package/providers/_builtin/ide/vscode/provider.json +64 -0
  155. package/providers/_builtin/ide/vscode-insiders/provider.json +62 -0
  156. package/providers/_builtin/ide/vscodium/provider.json +63 -0
  157. package/providers/_builtin/ide/windsurf/provider.json +53 -0
  158. package/providers/_builtin/ide/windsurf/scripts/focus_editor.js +30 -0
  159. package/providers/_builtin/ide/windsurf/scripts/list_chats.js +117 -0
  160. package/providers/_builtin/ide/windsurf/scripts/list_models.js +39 -0
  161. package/providers/_builtin/ide/windsurf/scripts/list_modes.js +39 -0
  162. package/providers/_builtin/ide/windsurf/scripts/new_session.js +69 -0
  163. package/providers/_builtin/ide/windsurf/scripts/open_panel.js +58 -0
  164. package/providers/_builtin/ide/windsurf/scripts/read_chat.js +297 -0
  165. package/providers/_builtin/ide/windsurf/scripts/resolve_action.js +68 -0
  166. package/providers/_builtin/ide/windsurf/scripts/send_message.js +87 -0
  167. package/providers/_builtin/ide/windsurf/scripts/set_mode.js +15 -0
  168. package/providers/_builtin/ide/windsurf/scripts/set_model.js +15 -0
  169. package/providers/_builtin/ide/windsurf/scripts/switch_session.js +58 -0
  170. package/providers/_builtin/ide/windsurf/scripts.js +57 -0
  171. package/providers/_builtin/registry.json +266 -0
  172. package/providers/_builtin/validate.js +156 -0
  173. package/src/agent-stream/index.ts +6 -0
  174. package/src/agent-stream/manager.ts +286 -0
  175. package/src/agent-stream/poller.ts +154 -0
  176. package/src/agent-stream/provider-adapter.ts +138 -0
  177. package/src/agent-stream/types.ts +61 -0
  178. package/src/boot/daemon-lifecycle.ts +252 -0
  179. package/src/cdp/devtools.ts +335 -0
  180. package/src/cdp/initializer.ts +191 -0
  181. package/src/cdp/manager.ts +897 -0
  182. package/src/cdp/scanner.ts +185 -0
  183. package/src/cdp/setup.ts +150 -0
  184. package/src/cli-adapter-types.ts +25 -0
  185. package/src/cli-adapters/provider-cli-adapter.ts +448 -0
  186. package/src/commands/cdp-commands.ts +208 -0
  187. package/src/commands/chat-commands.ts +675 -0
  188. package/src/commands/cli-manager.ts +353 -0
  189. package/src/commands/handler.ts +328 -0
  190. package/src/commands/router.ts +258 -0
  191. package/src/commands/stream-commands.ts +325 -0
  192. package/src/config/chat-history.ts +211 -0
  193. package/src/config/config.ts +219 -0
  194. package/src/daemon/dev-server.ts +2378 -0
  195. package/src/daemon/scaffold-template.ts +394 -0
  196. package/src/daemon-core.ts +50 -0
  197. package/src/detection/cli-detector.ts +89 -0
  198. package/src/detection/ide-detector.ts +157 -0
  199. package/src/index.ts +103 -0
  200. package/src/installer.ts +263 -0
  201. package/src/ipc-protocol.ts +133 -0
  202. package/src/launch.ts +433 -0
  203. package/src/logging/command-log.ts +180 -0
  204. package/src/logging/logger.ts +316 -0
  205. package/src/providers/acp-provider-instance.ts +1140 -0
  206. package/src/providers/cli-provider-instance.ts +207 -0
  207. package/src/providers/contracts.ts +524 -0
  208. package/src/providers/extension-provider-instance.ts +156 -0
  209. package/src/providers/ide-provider-instance.ts +377 -0
  210. package/src/providers/index.ts +18 -0
  211. package/src/providers/provider-instance-manager.ts +182 -0
  212. package/src/providers/provider-instance.ts +112 -0
  213. package/src/providers/provider-loader.ts +1031 -0
  214. package/src/providers/status-monitor.ts +125 -0
  215. package/src/providers/version-archive.ts +266 -0
  216. package/src/status/reporter.ts +294 -0
  217. package/src/types.ts +206 -0
@@ -0,0 +1,370 @@
1
+ # CDP DOM Exploration Guide — Building Provider Scripts with AI
2
+
3
+ > **⚠️ These APIs are local DevServer only (`adhdev daemon --dev`, `:19280`)**
4
+ > - Separate from the production/cloud API (`api.adhf.dev`) → [api.md](./api.md)
5
+ > - Used only during provider script development
6
+
7
+ > Use ADHDev's **local DevServer API** to analyze IDE DOM structure and
8
+ > discover selectors needed for `readChat`, `sendMessage`, and other provider scripts.
9
+ > **An AI agent can perform this entire workflow using only API calls.**
10
+
11
+ ---
12
+
13
+ ## Architecture
14
+
15
+ ```
16
+ AI Agent (or script)
17
+
18
+ │ HTTP POST (localhost)
19
+
20
+ ADHDev Dev Server (:19280)
21
+
22
+ │ CDP Runtime.evaluate
23
+
24
+ IDE Browser Process (Electron)
25
+
26
+ └─ DOM access, JS execution, result return
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Getting Started
32
+
33
+ ### 1. Start the daemon in dev mode
34
+
35
+ ```bash
36
+ adhdev daemon --dev
37
+ # DevServer: http://127.0.0.1:19280
38
+ ```
39
+
40
+ ### 2. Verify CDP connection
41
+
42
+ ```bash
43
+ curl -s http://127.0.0.1:19280/api/cdp/status | python3 -m json.tool
44
+ ```
45
+
46
+ ```json
47
+ {
48
+ "connected": ["cursor"],
49
+ "pages": { "cursor": "my-project — App.tsx" }
50
+ }
51
+ ```
52
+
53
+ ---
54
+
55
+ ## Core APIs
56
+
57
+ ### `POST /api/cdp/evaluate` — Execute JS in IDE
58
+
59
+ Run arbitrary JavaScript inside the IDE browser and return the result.
60
+
61
+ ```bash
62
+ curl -s -X POST http://127.0.0.1:19280/api/cdp/evaluate \
63
+ -H 'Content-Type: application/json' \
64
+ -d '{
65
+ "expression": "document.title",
66
+ "ideType": "cursor"
67
+ }'
68
+ ```
69
+
70
+ > **Return value must be a string** — wrap objects with `JSON.stringify()`.
71
+
72
+ ### `POST /api/cdp/dom/find-common` — Text-based selector discovery
73
+
74
+ Automatically find common ancestor selectors from visible text on screen.
75
+
76
+ ```bash
77
+ curl -s -X POST http://127.0.0.1:19280/api/cdp/dom/find-common \
78
+ -H 'Content-Type: application/json' \
79
+ -d '{
80
+ "include": ["Hello World", "Fix the bug"],
81
+ "exclude": [],
82
+ "ideType": "cursor"
83
+ }'
84
+ ```
85
+
86
+ **Response:**
87
+ ```json
88
+ {
89
+ "results": [{
90
+ "selector": "body > div... > div.chat-list",
91
+ "isList": true,
92
+ "listItemCount": 42,
93
+ "renderedCount": 42,
94
+ "placeholderCount": 0,
95
+ "items": [
96
+ { "index": 0, "text": "...Hello World...", "matchedIncludes": ["Hello World"] }
97
+ ]
98
+ }]
99
+ }
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Step-by-Step: Discovering readChat Selectors
105
+
106
+ Below is the actual process an AI used to discover readChat selectors via API calls only.
107
+
108
+ ### Step 1: Find the chat container using visible text
109
+
110
+ Pick **two different chat messages visible on screen** and use them as include texts.
111
+
112
+ ```bash
113
+ curl -s -X POST http://127.0.0.1:19280/api/cdp/dom/find-common \
114
+ -H 'Content-Type: application/json' \
115
+ -d '{
116
+ "include": ["text from first message", "text from second message"],
117
+ "ideType": "cursor"
118
+ }'
119
+ ```
120
+
121
+ **Key information from results:**
122
+ - `selector` → chat list container
123
+ - `isList: true` → confirms list structure
124
+ - `renderedCount` vs `placeholderCount` → detects virtual scrolling
125
+
126
+ ### Step 2: Analyze internal structure of the container
127
+
128
+ ```bash
129
+ curl -s -X POST http://127.0.0.1:19280/api/cdp/evaluate \
130
+ -H 'Content-Type: application/json' \
131
+ -d '{
132
+ "expression": "(() => { const el = document.querySelector(\"SELECTOR_FROM_STEP_1\"); const items = [...el.children]; const rendered = items.filter(c => (c.innerText||\"\").trim().length > 0); return JSON.stringify({ total: items.length, rendered: rendered.length, samples: rendered.slice(0, 5).map((c, i) => ({ tag: c.tagName, cls: c.className.substring(0, 50), text: (c.innerText||\"\").trim().substring(0, 100) })) }); })()",
133
+ "ideType": "cursor"
134
+ }'
135
+ ```
136
+
137
+ ### Step 3: Distinguish user vs assistant messages
138
+
139
+ Look for class patterns that differentiate roles:
140
+
141
+ ```bash
142
+ curl -s -X POST http://127.0.0.1:19280/api/cdp/evaluate \
143
+ -H 'Content-Type: application/json' \
144
+ -d '{
145
+ "expression": "(() => { const chat = document.querySelector(\"CHAT_CONTAINER\"); const rows = chat.querySelectorAll(\"div.flex.flex-row\"); const byClass = {}; rows.forEach(el => { const text = (el.innerText||\"\").trim(); if (text.length < 3) return; const cls = el.className.substring(0, 50); if (!byClass[cls]) byClass[cls] = { count: 0, samples: [] }; byClass[cls].count++; if (byClass[cls].samples.length < 2) byClass[cls].samples.push(text.substring(0, 80)); }); return JSON.stringify(byClass); })()",
146
+ "ideType": "cursor"
147
+ }'
148
+ ```
149
+
150
+ ### Step 4: Build the readChat script
151
+
152
+ Use discovered selectors to construct the final script:
153
+
154
+ ```javascript
155
+ (() => {
156
+ try {
157
+ const chat = document.querySelector('#conversation');
158
+ if (!chat) return JSON.stringify({ id: '', status: 'error', messages: [] });
159
+
160
+ const messages = [];
161
+
162
+ // User messages
163
+ chat.querySelectorAll('USER_SELECTOR').forEach(el => {
164
+ const text = (el.innerText || '').trim();
165
+ if (text.length > 1) {
166
+ messages.push({ role: 'user', content: text, y: el.getBoundingClientRect().top });
167
+ }
168
+ });
169
+
170
+ // Assistant messages
171
+ chat.querySelectorAll('ASSISTANT_SELECTOR').forEach(el => {
172
+ const text = (el.innerText || '').trim();
173
+ if (text.length > 1) {
174
+ messages.push({ role: 'assistant', content: text, y: el.getBoundingClientRect().top });
175
+ }
176
+ });
177
+
178
+ // Sort by vertical position (top→bottom = chronological)
179
+ messages.sort((a, b) => a.y - b.y);
180
+
181
+ // Status detection
182
+ const stopBtn = chat.querySelector('button[aria-label*="stop"], button[aria-label*="Stop"]');
183
+ const status = stopBtn ? 'generating' : 'idle';
184
+
185
+ return JSON.stringify({
186
+ id: 'chat-1',
187
+ status,
188
+ messages: messages.map((m, i) => ({ role: m.role, content: m.content, index: i })),
189
+ });
190
+ } catch (e) {
191
+ return JSON.stringify({ id: '', status: 'error', messages: [] });
192
+ }
193
+ })()
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Exploration Pattern Recipes
199
+
200
+ ### Pattern A: Find elements by text
201
+
202
+ ```javascript
203
+ // Find all elements containing specific text
204
+ (() => {
205
+ const searchText = "search text here";
206
+ const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {
207
+ acceptNode: n => n.textContent.toLowerCase().includes(searchText.toLowerCase())
208
+ ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT
209
+ });
210
+ const results = [];
211
+ let node;
212
+ while ((node = walker.nextNode()) && results.length < 5) {
213
+ const el = node.parentElement;
214
+ results.push({
215
+ tag: el.tagName,
216
+ cls: el.className.substring(0, 50),
217
+ text: el.innerText.substring(0, 100),
218
+ });
219
+ }
220
+ return JSON.stringify(results);
221
+ })()
222
+ ```
223
+
224
+ ### Pattern B: Analyze list container children
225
+
226
+ ```javascript
227
+ // Analyze children structure of a selector
228
+ (() => {
229
+ const el = document.querySelector("YOUR_SELECTOR");
230
+ if (!el) return JSON.stringify({error: "Not found"});
231
+ const children = [...el.children];
232
+ const rendered = children.filter(c => (c.innerText || '').trim().length > 0);
233
+ return JSON.stringify({
234
+ total: children.length,
235
+ rendered: rendered.length,
236
+ placeholders: children.length - rendered.length,
237
+ items: rendered.slice(0, 10).map((c, i) => ({
238
+ tag: c.tagName.toLowerCase(),
239
+ cls: c.className.substring(0, 40),
240
+ text: (c.innerText || '').trim().substring(0, 150),
241
+ }))
242
+ });
243
+ })()
244
+ ```
245
+
246
+ ### Pattern C: Classify elements by class pattern
247
+
248
+ ```javascript
249
+ // Group elements by CSS class pattern
250
+ (() => {
251
+ const container = document.querySelector("CONTAINER_SELECTOR");
252
+ const elements = container.querySelectorAll("div.flex");
253
+ const byClass = {};
254
+ elements.forEach(el => {
255
+ const text = (el.innerText || '').trim();
256
+ if (text.length < 3) return;
257
+ const cls = el.className.substring(0, 50);
258
+ if (!byClass[cls]) byClass[cls] = { count: 0, samples: [] };
259
+ byClass[cls].count++;
260
+ if (byClass[cls].samples.length < 2) {
261
+ byClass[cls].samples.push(text.substring(0, 80));
262
+ }
263
+ });
264
+ return JSON.stringify(byClass);
265
+ })()
266
+ ```
267
+
268
+ ### Pattern D: Find input fields (for sendMessage)
269
+
270
+ ```javascript
271
+ // Find contenteditable or textarea inputs
272
+ (() => {
273
+ const inputs = [
274
+ ...document.querySelectorAll('[contenteditable="true"]'),
275
+ ...document.querySelectorAll('textarea'),
276
+ ...document.querySelectorAll('input[type="text"]'),
277
+ ];
278
+ return JSON.stringify(inputs.map(el => ({
279
+ tag: el.tagName,
280
+ role: el.getAttribute('role'),
281
+ placeholder: el.getAttribute('placeholder') || el.getAttribute('aria-placeholder'),
282
+ cls: el.className.substring(0, 50),
283
+ visible: el.getBoundingClientRect().height > 0,
284
+ selector: el.id ? '#' + el.id : el.tagName.toLowerCase() + '.' + el.className.split(' ').slice(0,2).join('.'),
285
+ })));
286
+ })()
287
+ ```
288
+
289
+ ### Pattern E: Find buttons (for resolveAction)
290
+
291
+ ```javascript
292
+ // Find visible buttons with text and coordinates
293
+ (() => {
294
+ const buttons = [...document.querySelectorAll('button')];
295
+ return JSON.stringify(buttons
296
+ .filter(b => b.offsetHeight > 0)
297
+ .map(b => {
298
+ const r = b.getBoundingClientRect();
299
+ return {
300
+ text: (b.innerText || '').trim().substring(0, 30),
301
+ cls: b.className.substring(0, 40),
302
+ x: Math.round(r.x + r.width/2),
303
+ y: Math.round(r.y + r.height/2),
304
+ w: Math.round(r.width),
305
+ h: Math.round(r.height),
306
+ };
307
+ })
308
+ .filter(b => b.text.length > 0)
309
+ );
310
+ })()
311
+ ```
312
+
313
+ ---
314
+
315
+ ## Important Notes
316
+
317
+ ### Virtual Scrolling
318
+
319
+ Some IDEs (e.g., Antigravity) use virtual scrolling for chat lists.
320
+
321
+ - Only 1-3 visible items are actually rendered in the DOM
322
+ - The rest are empty placeholder divs with height only
323
+ - Filter with innerText: `(c.innerText || '').trim().length > 0`
324
+
325
+ **Detection:**
326
+ ```javascript
327
+ const total = container.children.length;
328
+ const rendered = [...container.children].filter(c => (c.innerText || '').trim().length > 0).length;
329
+ const isVirtualScroll = rendered < total * 0.5;
330
+ ```
331
+
332
+ ### textContent vs innerText
333
+
334
+ | Property | Use case |
335
+ |----------|----------|
336
+ | `textContent` | Includes hidden elements, fast, full node text |
337
+ | `innerText` | **Rendered text only**, slower but matches what user sees |
338
+
339
+ > Use `innerText` for readChat — produces results similar to a screen reader.
340
+
341
+ ### Selector Stability
342
+
343
+ | Stability | Selector type | Example |
344
+ |-----------|--------------|---------|
345
+ | ⭐⭐⭐ | ID | `#conversation` |
346
+ | ⭐⭐⭐ | Role | `[role="textbox"]` |
347
+ | ⭐⭐ | Semantic class | `.chat-message` |
348
+ | ⭐ | Tailwind class | `.flex.flex-row.my-2` |
349
+
350
+ > Tailwind-based selectors may break on IDE updates.
351
+ > Prefer `id`, `role`, `data-*` attribute selectors when available.
352
+
353
+ ---
354
+
355
+ ## Recommended AI Agent Workflow
356
+
357
+ ```
358
+ 1. /api/cdp/status → Verify connected IDEs
359
+ 2. /api/cdp/evaluate → Check document.title (correct IDE?)
360
+ 3. /api/cdp/dom/find-common → Find container using 2 chat texts
361
+ 4. /api/cdp/evaluate → Analyze container children (tags, class patterns)
362
+ 5. /api/cdp/evaluate → Distinguish user vs assistant messages (class, parent chain)
363
+ 6. /api/cdp/evaluate → Find input field selectors (sendMessage)
364
+ 7. /api/cdp/evaluate → Find button selectors (resolveAction)
365
+ 8. → Generate provider.js scripts from results
366
+ ```
367
+
368
+ > [!TIP]
369
+ > Provide **PROVIDER_GUIDE.md** and **this document** as context to an AI agent,
370
+ > and it can auto-generate provider.js scripts using only API calls.