@adhdev/daemon-core 0.6.58 → 0.6.60

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 (245) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +87 -89
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/detection/ide-detector.ts +1 -1
  6. package/src/providers/provider-loader.ts +3 -6
  7. package/providers/_builtin/.github/workflows/generate-registry.yml +0 -76
  8. package/providers/_builtin/COMPATIBILITY.md +0 -217
  9. package/providers/_builtin/CONTRIBUTING.md +0 -200
  10. package/providers/_builtin/README.md +0 -119
  11. package/providers/_builtin/_helpers/index.js +0 -188
  12. package/providers/_builtin/acp/agentpool/provider.json +0 -54
  13. package/providers/_builtin/acp/amp/provider.json +0 -52
  14. package/providers/_builtin/acp/auggie/provider.json +0 -57
  15. package/providers/_builtin/acp/autodev/provider.json +0 -54
  16. package/providers/_builtin/acp/autohand/provider.json +0 -52
  17. package/providers/_builtin/acp/blackbox-ai/provider.json +0 -54
  18. package/providers/_builtin/acp/claude-agent/provider.json +0 -57
  19. package/providers/_builtin/acp/cline-acp/provider.json +0 -54
  20. package/providers/_builtin/acp/codebuddy/provider.json +0 -54
  21. package/providers/_builtin/acp/codex-cli/provider.json +0 -57
  22. package/providers/_builtin/acp/corust-agent/provider.json +0 -52
  23. package/providers/_builtin/acp/crow-cli/provider.json +0 -54
  24. package/providers/_builtin/acp/cursor-acp/provider.json +0 -54
  25. package/providers/_builtin/acp/deepagents/provider.json +0 -52
  26. package/providers/_builtin/acp/dimcode/provider.json +0 -54
  27. package/providers/_builtin/acp/docker-cagent/provider.json +0 -57
  28. package/providers/_builtin/acp/factory-droid/provider.json +0 -60
  29. package/providers/_builtin/acp/fast-agent/provider.json +0 -52
  30. package/providers/_builtin/acp/gemini-cli/provider.json +0 -114
  31. package/providers/_builtin/acp/github-copilot/provider.json +0 -54
  32. package/providers/_builtin/acp/goose/provider.json +0 -57
  33. package/providers/_builtin/acp/junie/provider.json +0 -52
  34. package/providers/_builtin/acp/kilo/provider.json +0 -54
  35. package/providers/_builtin/acp/kimi-cli/provider.json +0 -57
  36. package/providers/_builtin/acp/minion-code/provider.json +0 -52
  37. package/providers/_builtin/acp/mistral-vibe/provider.json +0 -57
  38. package/providers/_builtin/acp/nova/provider.json +0 -54
  39. package/providers/_builtin/acp/openclaw/provider.json +0 -54
  40. package/providers/_builtin/acp/opencode/provider.json +0 -52
  41. package/providers/_builtin/acp/openhands/provider.json +0 -54
  42. package/providers/_builtin/acp/pi-acp/provider.json +0 -52
  43. package/providers/_builtin/acp/qoder/provider.json +0 -54
  44. package/providers/_builtin/acp/qwen-code/provider.json +0 -60
  45. package/providers/_builtin/acp/stakpak/provider.json +0 -54
  46. package/providers/_builtin/acp/vtcode/provider.json +0 -54
  47. package/providers/_builtin/cli/aider-cli/provider.json +0 -37
  48. package/providers/_builtin/cli/aider-cli/scripts/1.0/detect_status.js +0 -20
  49. package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_approval.js +0 -10
  50. package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_output.js +0 -97
  51. package/providers/_builtin/cli/aider-cli/scripts/1.0/scripts.js +0 -7
  52. package/providers/_builtin/cli/claude-cli/provider.json +0 -121
  53. package/providers/_builtin/cli/claude-cli/scripts/1.0/detect_status.js +0 -83
  54. package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_approval.js +0 -97
  55. package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_output.js +0 -417
  56. package/providers/_builtin/cli/claude-cli/scripts/1.0/scripts.js +0 -42
  57. package/providers/_builtin/cli/codex-cli/provider.json +0 -90
  58. package/providers/_builtin/cli/codex-cli/scripts/1.0/detect_status.js +0 -54
  59. package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_approval.js +0 -91
  60. package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_output.js +0 -522
  61. package/providers/_builtin/cli/codex-cli/scripts/1.0/scripts.js +0 -11
  62. package/providers/_builtin/cli/cursor-cli/provider.json +0 -37
  63. package/providers/_builtin/cli/cursor-cli/scripts/1.0/detect_status.js +0 -19
  64. package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_approval.js +0 -10
  65. package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_output.js +0 -48
  66. package/providers/_builtin/cli/cursor-cli/scripts/1.0/scripts.js +0 -7
  67. package/providers/_builtin/cli/gemini-cli/provider.json +0 -109
  68. package/providers/_builtin/cli/gemini-cli/scripts/1.0/detect_status.js +0 -26
  69. package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_approval.js +0 -22
  70. package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_output.js +0 -71
  71. package/providers/_builtin/cli/gemini-cli/scripts/1.0/scripts.js +0 -12
  72. package/providers/_builtin/cli/github-copilot-cli/provider.json +0 -37
  73. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/detect_status.js +0 -19
  74. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_approval.js +0 -9
  75. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_output.js +0 -48
  76. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/scripts.js +0 -7
  77. package/providers/_builtin/cli/goose-cli/provider.json +0 -37
  78. package/providers/_builtin/cli/goose-cli/scripts/1.0/detect_status.js +0 -20
  79. package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_approval.js +0 -10
  80. package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_output.js +0 -48
  81. package/providers/_builtin/cli/goose-cli/scripts/1.0/scripts.js +0 -7
  82. package/providers/_builtin/cli/opencode-cli/provider.json +0 -37
  83. package/providers/_builtin/cli/opencode-cli/scripts/1.0/detect_status.js +0 -15
  84. package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_approval.js +0 -9
  85. package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_output.js +0 -48
  86. package/providers/_builtin/cli/opencode-cli/scripts/1.0/scripts.js +0 -7
  87. package/providers/_builtin/docs/CDP_SELECTOR_GUIDE.md +0 -370
  88. package/providers/_builtin/docs/PROVIDER_GUIDE.md +0 -916
  89. package/providers/_builtin/extension/cline/provider.json +0 -37
  90. package/providers/_builtin/extension/cline/scripts/1.0/focus_editor.js +0 -48
  91. package/providers/_builtin/extension/cline/scripts/1.0/list_chats.js +0 -100
  92. package/providers/_builtin/extension/cline/scripts/1.0/list_models.js +0 -43
  93. package/providers/_builtin/extension/cline/scripts/1.0/list_modes.js +0 -35
  94. package/providers/_builtin/extension/cline/scripts/1.0/new_session.js +0 -85
  95. package/providers/_builtin/extension/cline/scripts/1.0/open_panel.js +0 -25
  96. package/providers/_builtin/extension/cline/scripts/1.0/read_chat.js +0 -270
  97. package/providers/_builtin/extension/cline/scripts/1.0/resolve_action.js +0 -83
  98. package/providers/_builtin/extension/cline/scripts/1.0/scripts.js +0 -82
  99. package/providers/_builtin/extension/cline/scripts/1.0/send_message.js +0 -95
  100. package/providers/_builtin/extension/cline/scripts/1.0/set_mode.js +0 -36
  101. package/providers/_builtin/extension/cline/scripts/1.0/set_model.js +0 -36
  102. package/providers/_builtin/extension/cline/scripts/1.0/switch_session.js +0 -206
  103. package/providers/_builtin/extension/codex/provider.json +0 -38
  104. package/providers/_builtin/extension/codex/scripts/1.0/click_conversation_webview.js +0 -24
  105. package/providers/_builtin/extension/codex/scripts/1.0/explore_chat_webview.js +0 -110
  106. package/providers/_builtin/extension/codex/scripts/1.0/explore_controls_webview.js +0 -75
  107. package/providers/_builtin/extension/codex/scripts/1.0/explore_dom.js +0 -58
  108. package/providers/_builtin/extension/codex/scripts/1.0/explore_dropdown_webview.js +0 -64
  109. package/providers/_builtin/extension/codex/scripts/1.0/inspect_code_webview.js +0 -55
  110. package/providers/_builtin/extension/codex/scripts/1.0/list_models.js +0 -63
  111. package/providers/_builtin/extension/codex/scripts/1.0/list_modes.js +0 -140
  112. package/providers/_builtin/extension/codex/scripts/1.0/message_structure_webview.js +0 -79
  113. package/providers/_builtin/extension/codex/scripts/1.0/new_session.js +0 -26
  114. package/providers/_builtin/extension/codex/scripts/1.0/read_chat.js +0 -516
  115. package/providers/_builtin/extension/codex/scripts/1.0/resolve_action.js +0 -82
  116. package/providers/_builtin/extension/codex/scripts/1.0/send_message.js +0 -42
  117. package/providers/_builtin/extension/codex/scripts/1.0/set_mode.js +0 -165
  118. package/providers/_builtin/extension/codex/scripts/1.0/set_model.js +0 -86
  119. package/providers/_builtin/extension/roo-code/provider.json +0 -37
  120. package/providers/_builtin/extension/roo-code/scripts/1.0/scripts.js +0 -82
  121. package/providers/_builtin/ide/antigravity/provider.json +0 -88
  122. package/providers/_builtin/ide/antigravity/scripts/1.0/focus_editor.js +0 -20
  123. package/providers/_builtin/ide/antigravity/scripts/1.0/list_chats.js +0 -137
  124. package/providers/_builtin/ide/antigravity/scripts/1.0/list_models.js +0 -61
  125. package/providers/_builtin/ide/antigravity/scripts/1.0/list_modes.js +0 -72
  126. package/providers/_builtin/ide/antigravity/scripts/1.0/new_session.js +0 -75
  127. package/providers/_builtin/ide/antigravity/scripts/1.0/read_chat.js +0 -352
  128. package/providers/_builtin/ide/antigravity/scripts/1.0/resolve_action.js +0 -63
  129. package/providers/_builtin/ide/antigravity/scripts/1.0/scripts.js +0 -67
  130. package/providers/_builtin/ide/antigravity/scripts/1.0/send_message.js +0 -56
  131. package/providers/_builtin/ide/antigravity/scripts/1.0/set_mode.js +0 -67
  132. package/providers/_builtin/ide/antigravity/scripts/1.0/set_model.js +0 -72
  133. package/providers/_builtin/ide/antigravity/scripts/1.0/switch_session.js +0 -114
  134. package/providers/_builtin/ide/cursor/provider.json +0 -70
  135. package/providers/_builtin/ide/cursor/scripts/1.0/dismiss_notification.js +0 -30
  136. package/providers/_builtin/ide/cursor/scripts/1.0/focus_editor.js +0 -13
  137. package/providers/_builtin/ide/cursor/scripts/1.0/list_models.js +0 -78
  138. package/providers/_builtin/ide/cursor/scripts/1.0/list_modes.js +0 -40
  139. package/providers/_builtin/ide/cursor/scripts/1.0/list_notifications.js +0 -23
  140. package/providers/_builtin/ide/cursor/scripts/1.0/list_sessions.js +0 -42
  141. package/providers/_builtin/ide/cursor/scripts/1.0/new_session.js +0 -20
  142. package/providers/_builtin/ide/cursor/scripts/1.0/open_panel.js +0 -23
  143. package/providers/_builtin/ide/cursor/scripts/1.0/read_chat.js +0 -318
  144. package/providers/_builtin/ide/cursor/scripts/1.0/resolve_action.js +0 -19
  145. package/providers/_builtin/ide/cursor/scripts/1.0/scripts.js +0 -78
  146. package/providers/_builtin/ide/cursor/scripts/1.0/send_message.js +0 -23
  147. package/providers/_builtin/ide/cursor/scripts/1.0/set_mode.js +0 -38
  148. package/providers/_builtin/ide/cursor/scripts/1.0/set_model.js +0 -81
  149. package/providers/_builtin/ide/cursor/scripts/1.0/switch_session.js +0 -28
  150. package/providers/_builtin/ide/kiro/provider.json +0 -68
  151. package/providers/_builtin/ide/kiro/scripts/1.0/focus_editor.js +0 -20
  152. package/providers/_builtin/ide/kiro/scripts/1.0/open_panel.js +0 -47
  153. package/providers/_builtin/ide/kiro/scripts/1.0/resolve_action.js +0 -54
  154. package/providers/_builtin/ide/kiro/scripts/1.0/send_message.js +0 -29
  155. package/providers/_builtin/ide/kiro/scripts/1.0/webview_dump_html.js +0 -1
  156. package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_models.js +0 -42
  157. package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_modes.js +0 -22
  158. package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_sessions.js +0 -21
  159. package/providers/_builtin/ide/kiro/scripts/1.0/webview_new_session.js +0 -34
  160. package/providers/_builtin/ide/kiro/scripts/1.0/webview_read_chat.js +0 -161
  161. package/providers/_builtin/ide/kiro/scripts/1.0/webview_resolve_action.js +0 -62
  162. package/providers/_builtin/ide/kiro/scripts/1.0/webview_send_message.js +0 -94
  163. package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_mode.js +0 -34
  164. package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_model.js +0 -47
  165. package/providers/_builtin/ide/kiro/scripts/1.0/webview_switch_session.js +0 -26
  166. package/providers/_builtin/ide/pearai/.tmp/after_rich.json +0 -157
  167. package/providers/_builtin/ide/pearai/.tmp/after_rich_raw.json +0 -161
  168. package/providers/_builtin/ide/pearai/.tmp/after_switch.json +0 -592
  169. package/providers/_builtin/ide/pearai/.tmp/after_switch_raw.json +0 -596
  170. package/providers/_builtin/ide/pearai/.tmp/home_dump_raw.json +0 -176
  171. package/providers/_builtin/ide/pearai/.tmp/items_raw.json +0 -778
  172. package/providers/_builtin/ide/pearai/.tmp/webview_dump.json +0 -157
  173. package/providers/_builtin/ide/pearai/.tmp/webview_dump_raw.json +0 -161
  174. package/providers/_builtin/ide/pearai/provider.json +0 -71
  175. package/providers/_builtin/ide/pearai/scripts/1.0/focus_editor.js +0 -16
  176. package/providers/_builtin/ide/pearai/scripts/1.0/list_models.js +0 -45
  177. package/providers/_builtin/ide/pearai/scripts/1.0/list_modes.js +0 -44
  178. package/providers/_builtin/ide/pearai/scripts/1.0/list_sessions.js +0 -93
  179. package/providers/_builtin/ide/pearai/scripts/1.0/new_session.js +0 -38
  180. package/providers/_builtin/ide/pearai/scripts/1.0/open_panel.js +0 -23
  181. package/providers/_builtin/ide/pearai/scripts/1.0/read_chat.js +0 -169
  182. package/providers/_builtin/ide/pearai/scripts/1.0/resolve_action.js +0 -60
  183. package/providers/_builtin/ide/pearai/scripts/1.0/scripts.js +0 -111
  184. package/providers/_builtin/ide/pearai/scripts/1.0/send_message.js +0 -104
  185. package/providers/_builtin/ide/pearai/scripts/1.0/set_mode.js +0 -51
  186. package/providers/_builtin/ide/pearai/scripts/1.0/set_model.js +0 -54
  187. package/providers/_builtin/ide/pearai/scripts/1.0/switch_session.js +0 -81
  188. package/providers/_builtin/ide/trae/provider.json +0 -72
  189. package/providers/_builtin/ide/trae/scripts/1.0/focus_editor.js +0 -20
  190. package/providers/_builtin/ide/trae/scripts/1.0/list_chats.js +0 -24
  191. package/providers/_builtin/ide/trae/scripts/1.0/list_models.js +0 -39
  192. package/providers/_builtin/ide/trae/scripts/1.0/list_modes.js +0 -39
  193. package/providers/_builtin/ide/trae/scripts/1.0/new_session.js +0 -30
  194. package/providers/_builtin/ide/trae/scripts/1.0/open_panel.js +0 -44
  195. package/providers/_builtin/ide/trae/scripts/1.0/read_chat.js +0 -113
  196. package/providers/_builtin/ide/trae/scripts/1.0/resolve_action.js +0 -54
  197. package/providers/_builtin/ide/trae/scripts/1.0/scripts.js +0 -82
  198. package/providers/_builtin/ide/trae/scripts/1.0/send_message.js +0 -69
  199. package/providers/_builtin/ide/trae/scripts/1.0/set_mode.js +0 -15
  200. package/providers/_builtin/ide/trae/scripts/1.0/set_model.js +0 -15
  201. package/providers/_builtin/ide/trae/scripts/1.0/switch_session.js +0 -23
  202. package/providers/_builtin/ide/vscode/provider.json +0 -74
  203. package/providers/_builtin/ide/vscode/scripts/1.0/focus_editor.js +0 -1
  204. package/providers/_builtin/ide/vscode/scripts/1.0/list_models.js +0 -1
  205. package/providers/_builtin/ide/vscode/scripts/1.0/list_sessions.js +0 -1
  206. package/providers/_builtin/ide/vscode/scripts/1.0/new_session.js +0 -1
  207. package/providers/_builtin/ide/vscode/scripts/1.0/open_panel.js +0 -1
  208. package/providers/_builtin/ide/vscode/scripts/1.0/read_chat.js +0 -1
  209. package/providers/_builtin/ide/vscode/scripts/1.0/resolve_action.js +0 -1
  210. package/providers/_builtin/ide/vscode/scripts/1.0/scripts.js +0 -25
  211. package/providers/_builtin/ide/vscode/scripts/1.0/send_message.js +0 -1
  212. package/providers/_builtin/ide/vscode/scripts/1.0/set_model.js +0 -1
  213. package/providers/_builtin/ide/vscode/scripts/1.0/switch_session.js +0 -1
  214. package/providers/_builtin/ide/vscode-insiders/provider.json +0 -68
  215. package/providers/_builtin/ide/vscodium/provider.json +0 -69
  216. package/providers/_builtin/ide/windsurf/provider.json +0 -57
  217. package/providers/_builtin/ide/windsurf/scripts/1.0/focus_editor.js +0 -36
  218. package/providers/_builtin/ide/windsurf/scripts/1.0/list_chats.js +0 -23
  219. package/providers/_builtin/ide/windsurf/scripts/1.0/list_models.js +0 -56
  220. package/providers/_builtin/ide/windsurf/scripts/1.0/list_modes.js +0 -63
  221. package/providers/_builtin/ide/windsurf/scripts/1.0/list_sessions.js +0 -79
  222. package/providers/_builtin/ide/windsurf/scripts/1.0/new_session.js +0 -58
  223. package/providers/_builtin/ide/windsurf/scripts/1.0/open_panel.js +0 -67
  224. package/providers/_builtin/ide/windsurf/scripts/1.0/read_chat.js +0 -253
  225. package/providers/_builtin/ide/windsurf/scripts/1.0/resolve_action.js +0 -82
  226. package/providers/_builtin/ide/windsurf/scripts/1.0/scripts.js +0 -82
  227. package/providers/_builtin/ide/windsurf/scripts/1.0/send_message.js +0 -20
  228. package/providers/_builtin/ide/windsurf/scripts/1.0/set_mode.js +0 -43
  229. package/providers/_builtin/ide/windsurf/scripts/1.0/set_model.js +0 -49
  230. package/providers/_builtin/ide/windsurf/scripts/1.0/switch_session.js +0 -82
  231. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/focus_editor.js +0 -30
  232. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_chats.js +0 -117
  233. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_models.js +0 -39
  234. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_modes.js +0 -39
  235. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/new_session.js +0 -69
  236. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/open_panel.js +0 -58
  237. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/read_chat.js +0 -315
  238. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/resolve_action.js +0 -68
  239. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/scripts.js +0 -82
  240. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/send_message.js +0 -87
  241. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_mode.js +0 -15
  242. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_model.js +0 -15
  243. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/switch_session.js +0 -58
  244. package/providers/_builtin/registry.json +0 -376
  245. package/providers/_builtin/validate.js +0 -156
@@ -1,315 +0,0 @@
1
- /**
2
- * Windsurf v1 — read_chat (v1 — Cascade DOM + Fiber)
3
- *
4
- * Windsurf VS Code fork, chat UI is "Cascade"is called.
5
- *
6
- * DOM structure:
7
- * #windsurf.cascadePanel → .chat-client-root
8
- * scroll: .cascade-scrollbar
9
- * list: .cascade-scrollbar .pb-20 > .flex.flex-col > .flex.flex-col.gap-2\.5
10
- * use : hasProse=false, hasWhitespace=true
11
- * AI : [class*="prose"] (prose-sm)
12
- * UI: .mark-js-ignore (ignore)
13
- * input: [data-lexical-editor="true"]
14
- *
15
- * Fiber props:
16
- * cascadeId: session ID
17
- * isRunning: create status
18
- * hasPendingTerminalCommand: approval wait
19
- * copyableText: AI response source
20
- *
21
- * final Check: Windsurf (2026-03-06)
22
- */
23
- (() => {
24
- try {
25
- // ─── 1. Container ───
26
- const cascade = document.querySelector('#windsurf\\.cascadePanel')
27
- || document.querySelector('.chat-client-root');
28
- if (!cascade) {
29
- return { id: 'no_cascade', status: 'idle', title: 'No Cascade', messages: [], inputContent: '', activeModal: null };
30
- }
31
-
32
- // ─── 2. Extract cascadeId, isRunning from Fiber (search from turn elements) ───
33
- let cascadeId = 'cascade';
34
- let isRunning = false;
35
- let hasPendingCmd = false;
36
- try {
37
- // Search Fiber from turn elements (cascadeId found at depth 6 from cascadePanel root)
38
- const scrollArea = cascade.querySelector('.cascade-scrollbar');
39
- const gapEls = scrollArea ? scrollArea.querySelectorAll('[class*="gap-2"]') : [];
40
- let firstTurn = null;
41
- for (const el of gapEls) {
42
- if (el.children.length >= 1 && el.closest('.cascade-scrollbar')) {
43
- firstTurn = el.children[0]; break;
44
- }
45
- }
46
- const fiberTarget = firstTurn || cascade;
47
- const fk = Object.keys(fiberTarget).find(k => k.startsWith('__reactFiber'));
48
- if (fk) {
49
- let fiber = fiberTarget[fk];
50
- for (let d = 0; d < 50 && fiber; d++) {
51
- const p = fiber.memoizedProps || fiber.pendingProps || {};
52
- if (p.cascadeId && typeof p.cascadeId === 'string') cascadeId = p.cascadeId;
53
- if (p.isRunning === true) isRunning = true;
54
- if (p.hasPendingTerminalCommand === true) hasPendingCmd = true;
55
- fiber = fiber.return;
56
- }
57
- }
58
- } catch (_) { }
59
-
60
- // ─── 3. status detection ───
61
- let status = 'idle';
62
- if (isRunning) status = 'generating';
63
-
64
- // Signal A: Stop button
65
- if (status === 'idle') {
66
- const allBtns = Array.from(document.querySelectorAll('button'));
67
- const stopBtn = allBtns.find(b => {
68
- if (b.offsetWidth === 0) return false;
69
- const label = (b.getAttribute('aria-label') || '').toLowerCase();
70
- const text = (b.textContent || '').trim().toLowerCase();
71
- return label.includes('stop') || label === 'cancel generation'
72
- || text === 'stop' || text === 'stop generating';
73
- });
74
- if (stopBtn) status = 'generating';
75
- }
76
-
77
- // Signal B: input field placeholder
78
- if (status === 'idle') {
79
- const editor = cascade.querySelector('[data-lexical-editor="true"]');
80
- if (editor) {
81
- const ph = (editor.getAttribute('placeholder') || '').toLowerCase();
82
- if (ph.includes('wait') || ph.includes('generating')) status = 'generating';
83
- }
84
- }
85
-
86
- const titleParts = document.title.split(' \u2014 ');
87
- const title = (titleParts.length >= 2 ? titleParts[titleParts.length - 1] : titleParts[0] || '').trim() || 'Cascade';
88
-
89
- // ─── 4. HTML → Markdown converter ───
90
- const BLOCK_TAGS = new Set(['DIV', 'P', 'BR', 'LI', 'TR', 'SECTION', 'ARTICLE', 'HEADER', 'FOOTER']);
91
- function extractCodeText(node) {
92
- if (node.nodeType === 3) return node.textContent || '';
93
- if (node.nodeType !== 1) return '';
94
- if (node.tagName === 'BR') return '\n';
95
- const parts = [];
96
- for (const child of node.childNodes) {
97
- const isBlock = child.nodeType === 1 && BLOCK_TAGS.has(child.tagName);
98
- const text = extractCodeText(child);
99
- if (text) {
100
- if (isBlock && parts.length > 0) parts.push('\n');
101
- parts.push(text);
102
- if (isBlock) parts.push('\n');
103
- }
104
- }
105
- return parts.join('').replace(/\n{2,}/g, '\n');
106
- }
107
- function htmlToMd(node) {
108
- if (node.nodeType === 3) return node.textContent || '';
109
- if (node.nodeType !== 1) return '';
110
- const tag = node.tagName;
111
- if (tag === 'STYLE' || tag === 'SCRIPT' || tag === 'SVG') return '';
112
- if (tag === 'TABLE') {
113
- const rows = Array.from(node.querySelectorAll('tr'));
114
- if (rows.length === 0) return '';
115
- const table = rows.map(tr =>
116
- Array.from(tr.querySelectorAll('th, td')).map(cell => (cell.textContent || '').trim().replace(/\|/g, '\\|'))
117
- );
118
- const colCount = Math.max(...table.map(r => r.length));
119
- const header = table[0] || [];
120
- const sep = Array(colCount).fill('---');
121
- const body = table.slice(1);
122
- let md = '| ' + header.join(' | ') + ' |\n';
123
- md += '| ' + sep.join(' | ') + ' |\n';
124
- for (const row of body) {
125
- while (row.length < colCount) row.push('');
126
- md += '| ' + row.join(' | ') + ' |\n';
127
- }
128
- return '\n' + md + '\n';
129
- }
130
- if (tag === 'UL') return '\n' + Array.from(node.children).map(li => '- ' + childrenToMd(li).trim()).join('\n') + '\n';
131
- if (tag === 'OL') return '\n' + Array.from(node.children).map((li, i) => (i + 1) + '. ' + childrenToMd(li).trim()).join('\n') + '\n';
132
- if (tag === 'LI') return childrenToMd(node);
133
- if (tag === 'H1') return '\n# ' + childrenToMd(node).trim() + '\n';
134
- if (tag === 'H2') return '\n## ' + childrenToMd(node).trim() + '\n';
135
- if (tag === 'H3') return '\n### ' + childrenToMd(node).trim() + '\n';
136
- if (tag === 'H4') return '\n#### ' + childrenToMd(node).trim() + '\n';
137
- if (tag === 'STRONG' || tag === 'B') return '**' + childrenToMd(node).trim() + '**';
138
- if (tag === 'EM' || tag === 'I') return '*' + childrenToMd(node).trim() + '*';
139
- if (tag === 'PRE') {
140
- const codeEl = node.querySelector('code');
141
- const lang = codeEl ? (codeEl.className.match(/language-(\w+)/)?.[1] || '') : '';
142
- const code = extractCodeText(codeEl || node);
143
- return '\n```' + lang + '\n' + code.trim() + '\n```\n';
144
- }
145
- if (tag === 'CODE') {
146
- if (node.parentElement && node.parentElement.tagName === 'PRE') return node.textContent || '';
147
- return '`' + (node.textContent || '').trim() + '`';
148
- }
149
- if (tag === 'BLOCKQUOTE') return '\n> ' + childrenToMd(node).trim().replace(/\n/g, '\n> ') + '\n';
150
- if (tag === 'A') return '[' + childrenToMd(node).trim() + '](' + (node.getAttribute('href') || '') + ')';
151
- if (tag === 'BR') return '\n';
152
- if (tag === 'P') return '\n' + childrenToMd(node).trim() + '\n';
153
- return childrenToMd(node);
154
- }
155
- function childrenToMd(node) {
156
- return Array.from(node.childNodes).map(htmlToMd).join('');
157
- }
158
-
159
- function getCleanMd(el) {
160
- const clone = el.cloneNode(true);
161
- clone.querySelectorAll('button, [role="button"], style, script, svg, .codicon, [class*="feedback"]').forEach(n => n.remove());
162
- clone.querySelectorAll('*').forEach(child => {
163
- if (!child.parentNode) return;
164
- const t = (child.textContent || '').trim();
165
- if (t.length > 60) return;
166
- const low = t.toLowerCase();
167
- if (/^(analyzed\s+\d|edited\s+\d|ran\s+\S|terminal\s|reading|searching)/i.test(low)) child.remove();
168
- });
169
- let md = htmlToMd(clone);
170
- md = md.replace(/\n{3,}/g, '\n\n').trim();
171
- return md;
172
- }
173
-
174
- // ─── 5. Collect messages ───
175
- const collected = [];
176
- const seenHashes = new Set();
177
-
178
- const scrollArea = cascade.querySelector('.cascade-scrollbar');
179
- if (!scrollArea) {
180
- return { id: cascadeId, status, title, messages: [], inputContent: '', activeModal: null };
181
- }
182
-
183
- // list Container search: .gap-2.5 with 2+ children
184
- let msgContainer = null;
185
- const gapEls = scrollArea.querySelectorAll('[class*="gap-2"]');
186
- for (const el of gapEls) {
187
- if (el.children.length >= 2 && el.closest('.cascade-scrollbar')) {
188
- msgContainer = el; break;
189
- }
190
- }
191
-
192
- if (msgContainer) {
193
- const turns = Array.from(msgContainer.children);
194
- for (const turn of turns) {
195
- // .mark-js-ignore = feedback UI → skip
196
- if ((turn.className || '').includes('mark-js-ignore')) continue;
197
- if (turn.offsetHeight < 10) continue;
198
-
199
- // Determine role: .prose = AI, otherwise user
200
- const proseEl = turn.querySelector('[class*="prose"]');
201
- const role = proseEl ? 'assistant' : 'user';
202
-
203
- let text = '';
204
- if (role === 'assistant') {
205
- // AI: Fiber copyableText use ( !)
206
- try {
207
- const fk = Object.keys(turn).find(k => k.startsWith('__reactFiber'));
208
- if (fk) {
209
- let fiber = turn[fk];
210
- for (let d = 0; d < 20 && fiber; d++) {
211
- const p = fiber.memoizedProps || {};
212
- if (p.copyableText && typeof p.copyableText === 'string' && p.copyableText.length > 5) {
213
- text = p.copyableText;
214
- break;
215
- }
216
- fiber = fiber.return;
217
- }
218
- }
219
- } catch (_) { }
220
-
221
- // In Fiber HTML→Markdown
222
- if (!text) {
223
- const mdRoot = proseEl || turn;
224
- text = getCleanMd(mdRoot);
225
- }
226
- } else {
227
- // User: whitespace-pre-wrap elementfrom text extract
228
- const whitespace = turn.querySelector('[class*="whitespace"]');
229
- text = (whitespace || turn).innerText?.trim() || '';
230
- }
231
-
232
- if (!text || text.length < 1) continue;
233
-
234
- const hash = role + ':' + text.slice(0, 200);
235
- if (seenHashes.has(hash)) continue;
236
- seenHashes.add(hash);
237
- collected.push({ role, text, el: turn });
238
- }
239
- }
240
-
241
- // DOM Order sorting
242
- collected.sort((a, b) => {
243
- const pos = a.el.compareDocumentPosition(b.el);
244
- if (pos & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
245
- if (pos & Node.DOCUMENT_POSITION_PRECEDING) return 1;
246
- return 0;
247
- });
248
-
249
- // latest 30only
250
- const trimmed = collected.length > 30 ? collected.slice(-30) : collected;
251
-
252
- const final = trimmed.map((m, i) => ({
253
- id: 'msg_' + i,
254
- role: m.role,
255
- content: m.text.length > 6000 ? m.text.slice(0, 6000) + '\n[... truncated]' : m.text,
256
- index: i,
257
- kind: 'standard'
258
- }));
259
-
260
- // ─── 6. input field ───
261
- const editor = cascade.querySelector('[data-lexical-editor="true"]')
262
- || cascade.querySelector('[contenteditable="true"][role="textbox"]')
263
- || cascade.querySelector('textarea:not(.xterm-helper-textarea)');
264
- const inputContent = editor ? (editor.innerText || editor.value || '').trim() : '';
265
-
266
- // ─── 7. modal/approval detect ───
267
- let activeModal = null;
268
- try {
269
- // Fiber: hasPendingTerminalCommand
270
- if (hasPendingCmd) {
271
- const allBtns = Array.from(document.querySelectorAll('button')).filter(b => b.offsetWidth > 0);
272
- const approvalBtns = allBtns.filter(b => {
273
- const t = (b.textContent || '').trim().toLowerCase();
274
- return /^(run|reject|skip|approve|allow|deny|cancel|accept)\b/i.test(t);
275
- });
276
- const btnTexts = [...new Set(approvalBtns.map(b => (b.textContent || '').trim()).filter(t => t.length < 40))];
277
- activeModal = { message: 'Terminal command pending', buttons: btnTexts.length > 0 ? btnTexts : ['Run', 'Reject'] };
278
- }
279
-
280
- // Dialog fallback
281
- if (!activeModal) {
282
- const dialog = document.querySelector('.monaco-dialog-box, [role="dialog"]');
283
- if (dialog && dialog.offsetWidth > 80) {
284
- const msg = (dialog.querySelector('.dialog-message') || dialog).innerText?.trim() || '';
285
- const buttons = Array.from(dialog.querySelectorAll('.monaco-button, button'))
286
- .map(b => (b.innerText || '').trim()).filter(t => t.length > 0 && t.length < 30);
287
- if (msg || buttons.length > 0) {
288
- activeModal = { message: msg.slice(0, 300), buttons };
289
- }
290
- }
291
- }
292
-
293
- // Inline approval buttons
294
- if (!activeModal) {
295
- const allBtns = Array.from(document.querySelectorAll('button')).filter(b => b.offsetWidth > 0);
296
- const approvalBtns = allBtns.filter(b => {
297
- const t = (b.textContent || '').trim().toLowerCase();
298
- if (t.length > 40) return false;
299
- return /^(run|reject|skip|approve|allow|deny)\b/i.test(t)
300
- || t === 'always allow' || t === 'always deny';
301
- });
302
- if (approvalBtns.length >= 2) {
303
- const btnTexts = [...new Set(approvalBtns.map(b => (b.textContent || '').trim()))];
304
- activeModal = { message: '', buttons: btnTexts };
305
- }
306
- }
307
-
308
- if (activeModal) status = 'waiting_approval';
309
- } catch (_) { activeModal = null; }
310
-
311
- return { id: cascadeId, status, title, messages: final, inputContent, activeModal };
312
- } catch (e) {
313
- return { id: 'error', status: 'error', error: e.message, messages: [] };
314
- }
315
- })()
@@ -1,68 +0,0 @@
1
- /**
2
- * Windsurf v1 — resolve_action
3
- *
4
- * approval Click dialogue/inline button.
5
- *
6
- * Parameter: ${ BUTTON_TEXT } — click button text (lowercase)
7
- *
8
- * final Check: Windsurf (2026-03-06)
9
- */
10
- (() => {
11
- try {
12
- const want = ${ BUTTON_TEXT };
13
- const normalize = (s) => (s || '').replace(/[\s\u200b\u00a0]+/g, ' ').trim().toLowerCase();
14
- const matches = (text) => {
15
- const t = normalize(text);
16
- if (!t) return false;
17
- if (t === want) return true;
18
- if (t.indexOf(want) === 0) return true;
19
- if (want === 'run' && (/^run\s*/.test(t) || t === 'enter' || t === '⏎')) return true;
20
- if (want === 'approve' && (t.includes('approve') || t === 'always allow' || t === 'allow')) return true;
21
- if (want === 'reject' && (t.includes('reject') || t === 'deny' || t === 'always deny')) return true;
22
- return false;
23
- };
24
- const click = (el) => {
25
- el.focus?.();
26
- const rect = el.getBoundingClientRect();
27
- const x = rect.left + rect.width / 2;
28
- const y = rect.top + rect.height / 2;
29
- for (const type of ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click']) {
30
- el.dispatchEvent(new PointerEvent(type, {
31
- bubbles: true, cancelable: true, view: window,
32
- clientX: x, clientY: y, pointerId: 1, pointerType: 'mouse'
33
- }));
34
- }
35
- return true;
36
- };
37
-
38
- // 1. Dialog inside
39
- const dialog = document.querySelector('.monaco-dialog-box, [role="dialog"]');
40
- if (dialog && dialog.offsetWidth > 80) {
41
- const btns = dialog.querySelectorAll('.monaco-button, button');
42
- for (const b of btns) {
43
- if (matches(b.textContent)) return click(b);
44
- }
45
- }
46
-
47
- // 2. all visible button
48
- const sel = 'button, [role="button"], .monaco-button';
49
- const allBtns = Array.from(document.querySelectorAll(sel))
50
- .filter(b => b.offsetWidth > 0 && b.offsetHeight > 0);
51
- for (const b of allBtns) {
52
- if (matches(b.textContent)) return click(b);
53
- }
54
-
55
- // 3. Enter key fallback (run)
56
- if (want === 'run') {
57
- document.activeElement?.dispatchEvent(new KeyboardEvent('keydown', {
58
- key: 'Enter', code: 'Enter', keyCode: 13,
59
- bubbles: true, cancelable: true
60
- }));
61
- return true;
62
- }
63
-
64
- return false;
65
- } catch (e) {
66
- return false;
67
- }
68
- })()
@@ -1,82 +0,0 @@
1
- /**
2
- * CDP Scripts — Router
3
- *
4
- * Version routing is handled by ProviderLoader:
5
- * Pattern:
6
- * - Scripts WITHOUT params: loaded as-is (self-invoking IIFE)
7
- * - Scripts WITH params: loaded as function expression, invoked with params JSON
8
- * e.g. `(${script})(${JSON.stringify(params)})`
9
- */
10
-
11
- 'use strict';
12
-
13
- const fs = require('fs');
14
- const path = require('path');
15
-
16
- function load(name) {
17
- try { return fs.readFileSync(path.join(__dirname, name), 'utf-8'); }
18
- catch { return null; }
19
- }
20
-
21
- function withParams(name, params) {
22
- let script = load(name);
23
- if (!script) return null;
24
-
25
- // For legacy scripts checking MESSAGE, interpolate them manually
26
- if (script.includes('${ MESSAGE }')) {
27
- const msg = params?.MESSAGE || params?.text || '';
28
- return script.replace(/\$\{ MESSAGE \}/g, JSON.stringify(msg));
29
- }
30
- if (script.includes('${ BUTTON_TEXT }')) {
31
- const btn = params?.BUTTON_TEXT || params?.buttonText || '';
32
- return script.replace(/\$\{ BUTTON_TEXT \}/g, JSON.stringify(btn));
33
- }
34
-
35
- return `(${script})(${JSON.stringify(params)})`;
36
- }
37
-
38
- // ─── Core (no params — IIFE) ───
39
-
40
- module.exports.readChat = () => load('read_chat.js') || load('webview_read_chat.js');
41
- module.exports.sendMessage = (params) => {
42
- let s = load('send_message.js');
43
- if (!s) s = load('webview_send_message.js');
44
- if (!s) return null;
45
- // Legacy template substitution fallback
46
- if (s.includes('${ MESSAGE }')) {
47
- const msg = params?.MESSAGE || params?.text || params || '';
48
- return s.replace(/\$\{ MESSAGE \}/g, JSON.stringify(msg));
49
- }
50
- return withParams('send_message.js', params) || withParams('webview_send_message.js', params);
51
- };
52
- module.exports.listSessions = () => load('list_sessions.js');
53
- module.exports.newSession = () => load('new_session.js');
54
- module.exports.focusEditor = () => load('focus_editor.js');
55
- module.exports.openPanel = () => load('open_panel.js');
56
- module.exports.listModels = () => load('list_models.js');
57
- module.exports.listModes = () => load('list_modes.js');
58
-
59
- // ─── With params (function expression) ───
60
-
61
- module.exports.switchSession = (params) => {
62
- const index = typeof params === 'number' ? params : params?.index ?? 0;
63
- const title = typeof params === 'string' ? params : params?.title || null;
64
- return withParams('switch_session.js', { index, title });
65
- };
66
-
67
- module.exports.resolveAction = (params) => {
68
- const action = typeof params === 'string' ? params : params?.action || 'approve';
69
- const buttonText = params?.button || params?.buttonText
70
- || (action === 'approve' ? 'Accept' : action === 'reject' ? 'Reject' : action);
71
- return withParams('resolve_action.js', { buttonText, BUTTON_TEXT: buttonText });
72
- };
73
-
74
- module.exports.setModel = (params) => {
75
- const model = typeof params === 'string' ? params : params?.model;
76
- return withParams('set_model.js', { model });
77
- };
78
-
79
- module.exports.setMode = (params) => {
80
- const mode = typeof params === 'string' ? params : params?.mode;
81
- return withParams('set_mode.js', { mode });
82
- };
@@ -1,87 +0,0 @@
1
- /**
2
- * Windsurf v1 — send_message
3
- *
4
- * Windsurf Lexical editor ([data-lexical-editor="true"])uses.
5
- * contenteditable divsince it is execCommand('insertText') or InputEventallows input via.
6
- *
7
- * ⚠️ Lexicalis input event detect:
8
- * - execCommand('insertText') is most stable
9
- * - nativeSetter approach does not work
10
- * - Uses InputEvent('insertText') as fallback
11
- *
12
- * Enter key needs KeyboardEvent full sequence (keydown + keypress + keyup).
13
- *
14
- * Parameter: ${ MESSAGE }
15
- * final Check: Windsurf 1.108.x (2026-03-10)
16
- */
17
- (async () => {
18
- try {
19
- const msg = ${ MESSAGE };
20
-
21
- // ─── 1. Find Lexical editor (fallback chain) ───
22
- const editor =
23
- document.querySelector('[data-lexical-editor="true"]') ||
24
- document.querySelector('[contenteditable="true"][role="textbox"]') ||
25
- document.querySelector('.cascade-input [contenteditable="true"]') ||
26
- document.querySelector('.chat-input textarea') ||
27
- document.querySelector('textarea:not(.xterm-helper-textarea)');
28
-
29
- if (!editor) return 'error: no input found';
30
-
31
- const isTextarea = editor.tagName === 'TEXTAREA';
32
-
33
- if (isTextarea) {
34
- // ─── textarea fallback (not logged in, etc.) ───
35
- editor.focus();
36
- const proto = HTMLTextAreaElement.prototype;
37
- const nativeSetter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;
38
- if (nativeSetter) nativeSetter.call(editor, msg);
39
- else editor.value = msg;
40
-
41
- editor.dispatchEvent(new Event('input', { bubbles: true }));
42
- editor.dispatchEvent(new Event('change', { bubbles: true }));
43
-
44
- await new Promise(r => setTimeout(r, 300));
45
-
46
- const enterOpts = {
47
- key: 'Enter', code: 'Enter',
48
- keyCode: 13, which: 13,
49
- bubbles: true, cancelable: true, composed: true,
50
- };
51
- editor.dispatchEvent(new KeyboardEvent('keydown', enterOpts));
52
- editor.dispatchEvent(new KeyboardEvent('keypress', enterOpts));
53
- editor.dispatchEvent(new KeyboardEvent('keyup', enterOpts));
54
-
55
- return 'sent';
56
- }
57
-
58
- // ─── 2. contenteditable (Lexical) editor ───
59
- editor.focus();
60
-
61
- // Select existing content and delete
62
- document.execCommand('selectAll', false, null);
63
- document.execCommand('delete', false, null);
64
-
65
- // text insertion (Lexicalis execCommand('insertText')recognizes)
66
- document.execCommand('insertText', false, msg);
67
-
68
- // React/Lexicalnotify changes to
69
- editor.dispatchEvent(new Event('input', { bubbles: true }));
70
-
71
- await new Promise(r => setTimeout(r, 300));
72
-
73
- // ─── 3. Enter key sending (full sequence) ───
74
- const enterOpts = {
75
- key: 'Enter', code: 'Enter',
76
- keyCode: 13, which: 13,
77
- bubbles: true, cancelable: true, composed: true,
78
- };
79
- editor.dispatchEvent(new KeyboardEvent('keydown', enterOpts));
80
- editor.dispatchEvent(new KeyboardEvent('keypress', enterOpts));
81
- editor.dispatchEvent(new KeyboardEvent('keyup', enterOpts));
82
-
83
- return 'sent';
84
- } catch (e) {
85
- return 'error: ' + e.message;
86
- }
87
- })()
@@ -1,15 +0,0 @@
1
- /**
2
- * Generic fallback — set_model
3
- * ${ MODEL }
4
- */
5
- (() => {
6
- try {
7
- const want = ${ MODEL } || '';
8
- const norm = (t) => t.toLowerCase().trim();
9
-
10
- // Very basic click attempt
11
- return JSON.stringify({ success: false, error: 'Model selection requires UI interaction not supported by generic script' });
12
- } catch (e) {
13
- return JSON.stringify({ success: false, error: e.message });
14
- }
15
- })()
@@ -1,15 +0,0 @@
1
- /**
2
- * Generic fallback — set_model
3
- * ${ MODEL }
4
- */
5
- (() => {
6
- try {
7
- const want = ${ MODEL } || '';
8
- const norm = (t) => t.toLowerCase().trim();
9
-
10
- // Very basic click attempt
11
- return JSON.stringify({ success: false, error: 'Model selection requires UI interaction not supported by generic script' });
12
- } catch (e) {
13
- return JSON.stringify({ success: false, error: e.message });
14
- }
15
- })()
@@ -1,58 +0,0 @@
1
- /**
2
- * Windsurf v1 — switch_session
3
- *
4
- * Cascade session(conversation) .
5
- * cascade-tab-{id} actual clickable child DIV inside
6
- * React onClick calls directly.
7
- *
8
- * Parameter: ${ SESSION_ID } — session ID (cascade-tab UUID)
9
- *
10
- * final Check: Windsurf 1.108.x (2026-03-10)
11
- */
12
- (() => {
13
- try {
14
- const id = ${ SESSION_ID };
15
-
16
- // Helper: find React onClick on an element or its children
17
- function clickReact(el) {
18
- // Check element itself and children for React onClick
19
- const targets = [el, ...el.querySelectorAll('*')];
20
- for (const t of targets) {
21
- const rp = Object.keys(t).find(k => k.startsWith('__reactProps'));
22
- if (rp && typeof t[rp].onClick === 'function') {
23
- t[rp].onClick({
24
- preventDefault: () => { },
25
- stopPropagation: () => { },
26
- nativeEvent: { stopImmediatePropagation: () => { } },
27
- target: t, currentTarget: t, button: 0, type: 'click'
28
- });
29
- return true;
30
- }
31
- }
32
- return false;
33
- }
34
-
35
- // 1. cascade-tab-{id} element search
36
- const tab = document.getElementById('cascade-tab-' + id);
37
- if (tab) {
38
- if (clickReact(tab)) return 'switched';
39
- // Fallback: DOM click
40
- tab.click();
41
- return 'switched-dom';
42
- }
43
-
44
- // 2. title matching
45
- const tabs = document.querySelectorAll('[id^="cascade-tab-"]');
46
- for (const t of tabs) {
47
- if (t.textContent?.trim() === id) {
48
- if (clickReact(t)) return 'switched-by-title';
49
- t.click();
50
- return 'switched-by-title-dom';
51
- }
52
- }
53
-
54
- return 'not_found';
55
- } catch (e) {
56
- return 'error: ' + e.message;
57
- }
58
- })()