@adhdev/daemon-core 0.6.57 → 0.6.59

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 (241) hide show
  1. package/dist/index.d.ts +18 -1
  2. package/dist/index.js +339 -167
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/cli-adapters/provider-cli-adapter.ts +223 -48
  6. package/src/commands/chat-commands.ts +7 -1
  7. package/src/config/chat-history.ts +53 -1
  8. package/src/daemon/dev-server.ts +7 -9
  9. package/src/detection/ide-detector.ts +1 -1
  10. package/src/providers/cli-provider-instance.ts +10 -23
  11. package/src/providers/provider-instance.ts +1 -0
  12. package/src/providers/provider-loader.ts +3 -6
  13. package/src/providers/version-archive.ts +4 -1
  14. package/providers/_builtin/.github/workflows/generate-registry.yml +0 -76
  15. package/providers/_builtin/COMPATIBILITY.md +0 -217
  16. package/providers/_builtin/CONTRIBUTING.md +0 -200
  17. package/providers/_builtin/README.md +0 -119
  18. package/providers/_builtin/_helpers/index.js +0 -188
  19. package/providers/_builtin/acp/agentpool/provider.json +0 -54
  20. package/providers/_builtin/acp/amp/provider.json +0 -52
  21. package/providers/_builtin/acp/auggie/provider.json +0 -57
  22. package/providers/_builtin/acp/autodev/provider.json +0 -54
  23. package/providers/_builtin/acp/autohand/provider.json +0 -52
  24. package/providers/_builtin/acp/blackbox-ai/provider.json +0 -54
  25. package/providers/_builtin/acp/claude-agent/provider.json +0 -57
  26. package/providers/_builtin/acp/cline-acp/provider.json +0 -54
  27. package/providers/_builtin/acp/codebuddy/provider.json +0 -54
  28. package/providers/_builtin/acp/codex-cli/provider.json +0 -57
  29. package/providers/_builtin/acp/corust-agent/provider.json +0 -52
  30. package/providers/_builtin/acp/crow-cli/provider.json +0 -54
  31. package/providers/_builtin/acp/cursor-acp/provider.json +0 -54
  32. package/providers/_builtin/acp/deepagents/provider.json +0 -52
  33. package/providers/_builtin/acp/dimcode/provider.json +0 -54
  34. package/providers/_builtin/acp/docker-cagent/provider.json +0 -57
  35. package/providers/_builtin/acp/factory-droid/provider.json +0 -60
  36. package/providers/_builtin/acp/fast-agent/provider.json +0 -52
  37. package/providers/_builtin/acp/gemini-cli/provider.json +0 -114
  38. package/providers/_builtin/acp/github-copilot/provider.json +0 -54
  39. package/providers/_builtin/acp/goose/provider.json +0 -57
  40. package/providers/_builtin/acp/junie/provider.json +0 -52
  41. package/providers/_builtin/acp/kilo/provider.json +0 -54
  42. package/providers/_builtin/acp/kimi-cli/provider.json +0 -57
  43. package/providers/_builtin/acp/minion-code/provider.json +0 -52
  44. package/providers/_builtin/acp/mistral-vibe/provider.json +0 -57
  45. package/providers/_builtin/acp/nova/provider.json +0 -54
  46. package/providers/_builtin/acp/openclaw/provider.json +0 -54
  47. package/providers/_builtin/acp/opencode/provider.json +0 -52
  48. package/providers/_builtin/acp/openhands/provider.json +0 -54
  49. package/providers/_builtin/acp/pi-acp/provider.json +0 -52
  50. package/providers/_builtin/acp/qoder/provider.json +0 -54
  51. package/providers/_builtin/acp/qwen-code/provider.json +0 -60
  52. package/providers/_builtin/acp/stakpak/provider.json +0 -54
  53. package/providers/_builtin/acp/vtcode/provider.json +0 -54
  54. package/providers/_builtin/cli/aider-cli/provider.json +0 -37
  55. package/providers/_builtin/cli/aider-cli/scripts/1.0/detect_status.js +0 -20
  56. package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_approval.js +0 -10
  57. package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_output.js +0 -49
  58. package/providers/_builtin/cli/aider-cli/scripts/1.0/scripts.js +0 -7
  59. package/providers/_builtin/cli/claude-cli/provider.json +0 -109
  60. package/providers/_builtin/cli/claude-cli/scripts/1.0/detect_status.js +0 -31
  61. package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_approval.js +0 -38
  62. package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_output.js +0 -164
  63. package/providers/_builtin/cli/claude-cli/scripts/1.0/scripts.js +0 -42
  64. package/providers/_builtin/cli/codex-cli/provider.json +0 -88
  65. package/providers/_builtin/cli/codex-cli/scripts/1.0/detect_status.js +0 -20
  66. package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_approval.js +0 -15
  67. package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_output.js +0 -68
  68. package/providers/_builtin/cli/codex-cli/scripts/1.0/scripts.js +0 -11
  69. package/providers/_builtin/cli/cursor-cli/provider.json +0 -37
  70. package/providers/_builtin/cli/cursor-cli/scripts/1.0/detect_status.js +0 -19
  71. package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_approval.js +0 -10
  72. package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_output.js +0 -48
  73. package/providers/_builtin/cli/cursor-cli/scripts/1.0/scripts.js +0 -7
  74. package/providers/_builtin/cli/gemini-cli/provider.json +0 -109
  75. package/providers/_builtin/cli/gemini-cli/scripts/1.0/detect_status.js +0 -26
  76. package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_approval.js +0 -22
  77. package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_output.js +0 -71
  78. package/providers/_builtin/cli/gemini-cli/scripts/1.0/scripts.js +0 -12
  79. package/providers/_builtin/cli/github-copilot-cli/provider.json +0 -37
  80. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/detect_status.js +0 -19
  81. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_approval.js +0 -9
  82. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_output.js +0 -48
  83. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/scripts.js +0 -7
  84. package/providers/_builtin/cli/goose-cli/provider.json +0 -37
  85. package/providers/_builtin/cli/goose-cli/scripts/1.0/detect_status.js +0 -20
  86. package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_approval.js +0 -10
  87. package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_output.js +0 -48
  88. package/providers/_builtin/cli/goose-cli/scripts/1.0/scripts.js +0 -7
  89. package/providers/_builtin/cli/opencode-cli/provider.json +0 -37
  90. package/providers/_builtin/cli/opencode-cli/scripts/1.0/detect_status.js +0 -15
  91. package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_approval.js +0 -9
  92. package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_output.js +0 -48
  93. package/providers/_builtin/cli/opencode-cli/scripts/1.0/scripts.js +0 -7
  94. package/providers/_builtin/docs/CDP_SELECTOR_GUIDE.md +0 -370
  95. package/providers/_builtin/docs/PROVIDER_GUIDE.md +0 -916
  96. package/providers/_builtin/extension/cline/provider.json +0 -37
  97. package/providers/_builtin/extension/cline/scripts/1.0/focus_editor.js +0 -48
  98. package/providers/_builtin/extension/cline/scripts/1.0/list_chats.js +0 -100
  99. package/providers/_builtin/extension/cline/scripts/1.0/list_models.js +0 -43
  100. package/providers/_builtin/extension/cline/scripts/1.0/list_modes.js +0 -35
  101. package/providers/_builtin/extension/cline/scripts/1.0/new_session.js +0 -85
  102. package/providers/_builtin/extension/cline/scripts/1.0/open_panel.js +0 -25
  103. package/providers/_builtin/extension/cline/scripts/1.0/read_chat.js +0 -270
  104. package/providers/_builtin/extension/cline/scripts/1.0/resolve_action.js +0 -83
  105. package/providers/_builtin/extension/cline/scripts/1.0/scripts.js +0 -82
  106. package/providers/_builtin/extension/cline/scripts/1.0/send_message.js +0 -95
  107. package/providers/_builtin/extension/cline/scripts/1.0/set_mode.js +0 -36
  108. package/providers/_builtin/extension/cline/scripts/1.0/set_model.js +0 -36
  109. package/providers/_builtin/extension/cline/scripts/1.0/switch_session.js +0 -206
  110. package/providers/_builtin/extension/codex/provider.json +0 -38
  111. package/providers/_builtin/extension/codex/scripts/1.0/click_conversation_webview.js +0 -24
  112. package/providers/_builtin/extension/codex/scripts/1.0/explore_chat_webview.js +0 -110
  113. package/providers/_builtin/extension/codex/scripts/1.0/explore_controls_webview.js +0 -75
  114. package/providers/_builtin/extension/codex/scripts/1.0/explore_dom.js +0 -58
  115. package/providers/_builtin/extension/codex/scripts/1.0/explore_dropdown_webview.js +0 -64
  116. package/providers/_builtin/extension/codex/scripts/1.0/inspect_code_webview.js +0 -55
  117. package/providers/_builtin/extension/codex/scripts/1.0/list_models.js +0 -63
  118. package/providers/_builtin/extension/codex/scripts/1.0/list_modes.js +0 -140
  119. package/providers/_builtin/extension/codex/scripts/1.0/message_structure_webview.js +0 -79
  120. package/providers/_builtin/extension/codex/scripts/1.0/new_session.js +0 -26
  121. package/providers/_builtin/extension/codex/scripts/1.0/read_chat.js +0 -516
  122. package/providers/_builtin/extension/codex/scripts/1.0/resolve_action.js +0 -82
  123. package/providers/_builtin/extension/codex/scripts/1.0/send_message.js +0 -42
  124. package/providers/_builtin/extension/codex/scripts/1.0/set_mode.js +0 -165
  125. package/providers/_builtin/extension/codex/scripts/1.0/set_model.js +0 -86
  126. package/providers/_builtin/extension/roo-code/provider.json +0 -37
  127. package/providers/_builtin/extension/roo-code/scripts/1.0/scripts.js +0 -82
  128. package/providers/_builtin/ide/antigravity/provider.json +0 -88
  129. package/providers/_builtin/ide/antigravity/scripts/1.0/focus_editor.js +0 -20
  130. package/providers/_builtin/ide/antigravity/scripts/1.0/list_chats.js +0 -137
  131. package/providers/_builtin/ide/antigravity/scripts/1.0/list_models.js +0 -61
  132. package/providers/_builtin/ide/antigravity/scripts/1.0/list_modes.js +0 -72
  133. package/providers/_builtin/ide/antigravity/scripts/1.0/new_session.js +0 -75
  134. package/providers/_builtin/ide/antigravity/scripts/1.0/read_chat.js +0 -352
  135. package/providers/_builtin/ide/antigravity/scripts/1.0/resolve_action.js +0 -63
  136. package/providers/_builtin/ide/antigravity/scripts/1.0/scripts.js +0 -67
  137. package/providers/_builtin/ide/antigravity/scripts/1.0/send_message.js +0 -56
  138. package/providers/_builtin/ide/antigravity/scripts/1.0/set_mode.js +0 -67
  139. package/providers/_builtin/ide/antigravity/scripts/1.0/set_model.js +0 -72
  140. package/providers/_builtin/ide/antigravity/scripts/1.0/switch_session.js +0 -114
  141. package/providers/_builtin/ide/cursor/provider.json +0 -70
  142. package/providers/_builtin/ide/cursor/scripts/1.0/dismiss_notification.js +0 -30
  143. package/providers/_builtin/ide/cursor/scripts/1.0/focus_editor.js +0 -13
  144. package/providers/_builtin/ide/cursor/scripts/1.0/list_models.js +0 -78
  145. package/providers/_builtin/ide/cursor/scripts/1.0/list_modes.js +0 -40
  146. package/providers/_builtin/ide/cursor/scripts/1.0/list_notifications.js +0 -23
  147. package/providers/_builtin/ide/cursor/scripts/1.0/list_sessions.js +0 -42
  148. package/providers/_builtin/ide/cursor/scripts/1.0/new_session.js +0 -20
  149. package/providers/_builtin/ide/cursor/scripts/1.0/open_panel.js +0 -23
  150. package/providers/_builtin/ide/cursor/scripts/1.0/read_chat.js +0 -318
  151. package/providers/_builtin/ide/cursor/scripts/1.0/resolve_action.js +0 -19
  152. package/providers/_builtin/ide/cursor/scripts/1.0/scripts.js +0 -78
  153. package/providers/_builtin/ide/cursor/scripts/1.0/send_message.js +0 -23
  154. package/providers/_builtin/ide/cursor/scripts/1.0/set_mode.js +0 -38
  155. package/providers/_builtin/ide/cursor/scripts/1.0/set_model.js +0 -81
  156. package/providers/_builtin/ide/cursor/scripts/1.0/switch_session.js +0 -28
  157. package/providers/_builtin/ide/kiro/provider.json +0 -68
  158. package/providers/_builtin/ide/kiro/scripts/1.0/focus_editor.js +0 -20
  159. package/providers/_builtin/ide/kiro/scripts/1.0/open_panel.js +0 -47
  160. package/providers/_builtin/ide/kiro/scripts/1.0/resolve_action.js +0 -54
  161. package/providers/_builtin/ide/kiro/scripts/1.0/send_message.js +0 -29
  162. package/providers/_builtin/ide/kiro/scripts/1.0/webview_dump_html.js +0 -1
  163. package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_models.js +0 -42
  164. package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_modes.js +0 -22
  165. package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_sessions.js +0 -21
  166. package/providers/_builtin/ide/kiro/scripts/1.0/webview_new_session.js +0 -34
  167. package/providers/_builtin/ide/kiro/scripts/1.0/webview_read_chat.js +0 -161
  168. package/providers/_builtin/ide/kiro/scripts/1.0/webview_resolve_action.js +0 -62
  169. package/providers/_builtin/ide/kiro/scripts/1.0/webview_send_message.js +0 -94
  170. package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_mode.js +0 -34
  171. package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_model.js +0 -47
  172. package/providers/_builtin/ide/kiro/scripts/1.0/webview_switch_session.js +0 -26
  173. package/providers/_builtin/ide/pearai/.tmp/after_rich.json +0 -157
  174. package/providers/_builtin/ide/pearai/.tmp/after_rich_raw.json +0 -161
  175. package/providers/_builtin/ide/pearai/.tmp/after_switch.json +0 -592
  176. package/providers/_builtin/ide/pearai/.tmp/after_switch_raw.json +0 -596
  177. package/providers/_builtin/ide/pearai/.tmp/home_dump_raw.json +0 -176
  178. package/providers/_builtin/ide/pearai/.tmp/items_raw.json +0 -778
  179. package/providers/_builtin/ide/pearai/.tmp/webview_dump.json +0 -157
  180. package/providers/_builtin/ide/pearai/.tmp/webview_dump_raw.json +0 -161
  181. package/providers/_builtin/ide/pearai/provider.json +0 -71
  182. package/providers/_builtin/ide/pearai/scripts/1.0/focus_editor.js +0 -16
  183. package/providers/_builtin/ide/pearai/scripts/1.0/list_models.js +0 -45
  184. package/providers/_builtin/ide/pearai/scripts/1.0/list_modes.js +0 -44
  185. package/providers/_builtin/ide/pearai/scripts/1.0/list_sessions.js +0 -93
  186. package/providers/_builtin/ide/pearai/scripts/1.0/new_session.js +0 -38
  187. package/providers/_builtin/ide/pearai/scripts/1.0/open_panel.js +0 -23
  188. package/providers/_builtin/ide/pearai/scripts/1.0/read_chat.js +0 -169
  189. package/providers/_builtin/ide/pearai/scripts/1.0/resolve_action.js +0 -60
  190. package/providers/_builtin/ide/pearai/scripts/1.0/scripts.js +0 -111
  191. package/providers/_builtin/ide/pearai/scripts/1.0/send_message.js +0 -104
  192. package/providers/_builtin/ide/pearai/scripts/1.0/set_mode.js +0 -51
  193. package/providers/_builtin/ide/pearai/scripts/1.0/set_model.js +0 -54
  194. package/providers/_builtin/ide/pearai/scripts/1.0/switch_session.js +0 -81
  195. package/providers/_builtin/ide/trae/provider.json +0 -72
  196. package/providers/_builtin/ide/trae/scripts/1.0/focus_editor.js +0 -20
  197. package/providers/_builtin/ide/trae/scripts/1.0/list_chats.js +0 -24
  198. package/providers/_builtin/ide/trae/scripts/1.0/list_models.js +0 -39
  199. package/providers/_builtin/ide/trae/scripts/1.0/list_modes.js +0 -39
  200. package/providers/_builtin/ide/trae/scripts/1.0/new_session.js +0 -30
  201. package/providers/_builtin/ide/trae/scripts/1.0/open_panel.js +0 -44
  202. package/providers/_builtin/ide/trae/scripts/1.0/read_chat.js +0 -113
  203. package/providers/_builtin/ide/trae/scripts/1.0/resolve_action.js +0 -54
  204. package/providers/_builtin/ide/trae/scripts/1.0/scripts.js +0 -82
  205. package/providers/_builtin/ide/trae/scripts/1.0/send_message.js +0 -69
  206. package/providers/_builtin/ide/trae/scripts/1.0/set_mode.js +0 -15
  207. package/providers/_builtin/ide/trae/scripts/1.0/set_model.js +0 -15
  208. package/providers/_builtin/ide/trae/scripts/1.0/switch_session.js +0 -23
  209. package/providers/_builtin/ide/vscode/provider.json +0 -70
  210. package/providers/_builtin/ide/vscode-insiders/provider.json +0 -68
  211. package/providers/_builtin/ide/vscodium/provider.json +0 -69
  212. package/providers/_builtin/ide/windsurf/provider.json +0 -57
  213. package/providers/_builtin/ide/windsurf/scripts/1.0/focus_editor.js +0 -36
  214. package/providers/_builtin/ide/windsurf/scripts/1.0/list_chats.js +0 -23
  215. package/providers/_builtin/ide/windsurf/scripts/1.0/list_models.js +0 -56
  216. package/providers/_builtin/ide/windsurf/scripts/1.0/list_modes.js +0 -63
  217. package/providers/_builtin/ide/windsurf/scripts/1.0/list_sessions.js +0 -79
  218. package/providers/_builtin/ide/windsurf/scripts/1.0/new_session.js +0 -58
  219. package/providers/_builtin/ide/windsurf/scripts/1.0/open_panel.js +0 -67
  220. package/providers/_builtin/ide/windsurf/scripts/1.0/read_chat.js +0 -253
  221. package/providers/_builtin/ide/windsurf/scripts/1.0/resolve_action.js +0 -82
  222. package/providers/_builtin/ide/windsurf/scripts/1.0/scripts.js +0 -82
  223. package/providers/_builtin/ide/windsurf/scripts/1.0/send_message.js +0 -20
  224. package/providers/_builtin/ide/windsurf/scripts/1.0/set_mode.js +0 -43
  225. package/providers/_builtin/ide/windsurf/scripts/1.0/set_model.js +0 -49
  226. package/providers/_builtin/ide/windsurf/scripts/1.0/switch_session.js +0 -82
  227. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/focus_editor.js +0 -30
  228. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_chats.js +0 -117
  229. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_models.js +0 -39
  230. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_modes.js +0 -39
  231. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/new_session.js +0 -69
  232. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/open_panel.js +0 -58
  233. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/read_chat.js +0 -315
  234. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/resolve_action.js +0 -68
  235. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/scripts.js +0 -82
  236. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/send_message.js +0 -87
  237. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_mode.js +0 -15
  238. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_model.js +0 -15
  239. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/switch_session.js +0 -58
  240. package/providers/_builtin/registry.json +0 -376
  241. package/providers/_builtin/validate.js +0 -156
@@ -1,93 +0,0 @@
1
- /**
2
- * PearAI — webview_list_sessions (webview iframe runs inside)
3
- *
4
- * PearAI(Roo Code/Cline based) Session list extract.
5
- * history task-item Tasks .
6
- */
7
- (() => {
8
- try {
9
- const sessions = [];
10
- const seen = new Set();
11
-
12
- const pushSession = (session) => {
13
- if (!session || !session.id || seen.has(session.id)) return;
14
- seen.add(session.id);
15
- sessions.push({
16
- id: session.id,
17
- title: (session.title || '').trim().slice(0, 120),
18
- active: Boolean(session.active),
19
- index: typeof session.index === 'number' ? session.index : sessions.length,
20
- });
21
- };
22
-
23
- // ─── History items: data-testid="task-item-*" ───
24
- const taskItems = document.querySelectorAll('[data-testid^="task-item-"]');
25
-
26
- if (taskItems.length > 0) {
27
- for (let i = 0; i < taskItems.length; i++) {
28
- const item = taskItems[i];
29
- if (!item) continue;
30
-
31
- const testId = item.getAttribute('data-testid') || '';
32
- const taskId = testId.replace('task-item-', '');
33
-
34
- // Extract title from full text
35
- const fullText = (item.textContent || '').trim();
36
-
37
- // structure: "MARCH 16, 1:31 AM 173 B test123 Tokens:10.4k 229"
38
- // strategy: Tokens: before last with text title use
39
- let title = '';
40
-
41
- // Extract date
42
- // title extract: (B/kB) , Tokens: before
43
- const titleMatch = fullText.match(/[AP]M[\d.\s]*[kMG]?B\s*(.*?)(?:Tokens:|$)/s);
44
- if (titleMatch && titleMatch[1]) {
45
- title = titleMatch[1].trim();
46
- }
47
-
48
- // fallback: first 80 chars
49
- if (!title) {
50
- title = fullText.substring(0, 80);
51
- }
52
-
53
- pushSession({
54
- id: taskId || `task-${i}`,
55
- title,
56
- active: item.getAttribute('aria-selected') === 'true' || item.classList.contains('active'),
57
- index: i,
58
- });
59
- }
60
- }
61
-
62
- // ─── Tasks ───
63
- const cards = Array.from(document.querySelectorAll('div')).filter((card) => {
64
- const className = String(card.className || '');
65
- const text = (card.textContent || '').trim();
66
- return className.includes('bg-vscode-editor-background')
67
- && className.includes('cursor-pointer')
68
- && className.includes('overflow-hidden')
69
- && !!card.querySelector('[data-testid="copy-prompt-button"]')
70
- && /↑\s*\d|↓\s*\d/i.test(text)
71
- && /MARCH|APRIL|MAY|JUNE|JULY|AUGUST|SEPTEMBER|OCTOBER|NOVEMBER|DECEMBER|JANUARY|FEBRUARY/i.test(text);
72
- });
73
-
74
- cards.forEach((card, index) => {
75
- const text = (card.textContent || '').trim();
76
- const prompt = card.querySelector('.text-vscode-foreground');
77
- const title = (prompt?.textContent || text)
78
- .replace(/\s*↑\s*\d[\d.,kKmM]*\s*↓\s*\d[\d.,kKmM]*/g, '')
79
- .trim();
80
-
81
- pushSession({
82
- id: card.getAttribute('data-testid') || `card-${index}`,
83
- title,
84
- active: false,
85
- index,
86
- });
87
- });
88
-
89
- return JSON.stringify({ sessions, note: sessions.length ? undefined : 'No sessions found' });
90
- } catch (e) {
91
- return JSON.stringify({ sessions: [], error: String(e.message || e) });
92
- }
93
- })()
@@ -1,38 +0,0 @@
1
- /**
2
- * PearAI — webview_new_session
3
- */
4
- (() => {
5
- try {
6
- const click = (element) => {
7
- if (!element) return false;
8
- element.scrollIntoView({ block: 'center' });
9
- element.focus?.();
10
- element.click?.();
11
- return true;
12
- };
13
-
14
- const closeTask = Array.from(document.querySelectorAll('button[title], button[aria-label]')).find((button) =>
15
- /close task and start a new one/i.test(button.getAttribute('title') || '')
16
- || /close task and start a new one/i.test(button.getAttribute('aria-label') || '')
17
- );
18
- if (click(closeTask)) {
19
- return JSON.stringify({ created: true, method: 'close-task' });
20
- }
21
-
22
- const startNewTask = Array.from(document.querySelectorAll('button, [role="button"], div.cursor-pointer')).find((element) =>
23
- /start new task|new task|new chat/i.test((element.textContent || '').trim())
24
- );
25
- if (click(startNewTask)) {
26
- return JSON.stringify({ created: true, method: 'start-new-task' });
27
- }
28
-
29
- const cards = document.querySelectorAll('[data-testid="copy-prompt-button"]');
30
- if (cards.length > 0) {
31
- return JSON.stringify({ created: true, method: 'already-home' });
32
- }
33
-
34
- return JSON.stringify({ created: false, error: 'new session control not found' });
35
- } catch (error) {
36
- return JSON.stringify({ created: false, error: String(error && error.message || error) });
37
- }
38
- })()
@@ -1,23 +0,0 @@
1
- /**
2
- * PearAI — open_panel
3
- */
4
- (() => {
5
- try {
6
- const sidebar = document.getElementById('workbench.parts.auxiliarybar');
7
- if (sidebar && sidebar.offsetWidth > 0 && sidebar.offsetHeight > 0) {
8
- return JSON.stringify({ opened: true, visible: true });
9
- }
10
-
11
- const toggle = Array.from(document.querySelectorAll('a[aria-label], button[aria-label], [role="button"][aria-label]'))
12
- .find((element) => /toggle pearai side bar|toggle pearai|toggle auxiliary/i.test(element.getAttribute('aria-label') || ''));
13
-
14
- if (!toggle) {
15
- return JSON.stringify({ opened: false, error: 'toggle not found' });
16
- }
17
-
18
- toggle.click();
19
- return JSON.stringify({ opened: true });
20
- } catch (error) {
21
- return JSON.stringify({ opened: false, error: String(error && error.message || error) });
22
- }
23
- })()
@@ -1,169 +0,0 @@
1
- /**
2
- * PearAI — webview_read_chat
3
- */
4
- (() => {
5
- try {
6
- const normalize = (value) => String(value || '').replace(/\r/g, '').replace(/\u00a0/g, ' ');
7
- const collapse = (value) => normalize(value).replace(/[ \t]+\n/g, '\n').replace(/\n{3,}/g, '\n\n').trim();
8
- const fence = '```';
9
-
10
- const markdownFromNode = (node, depth = 0) => {
11
- if (!node || depth > 20) return '';
12
- if (node.nodeType === Node.TEXT_NODE) return node.nodeValue || '';
13
- if (node.nodeType !== Node.ELEMENT_NODE) return '';
14
-
15
- const tag = node.tagName.toLowerCase();
16
- const children = () => Array.from(node.childNodes).map((child) => markdownFromNode(child, depth + 1)).join('');
17
-
18
- if (tag === 'br') return '\n';
19
- if (tag === 'hr') return '\n---\n\n';
20
- if (tag === 'strong' || tag === 'b') return `**${children().trim()}**`;
21
- if (tag === 'em' || tag === 'i') return `*${children().trim()}*`;
22
- if (tag === 'code' && node.parentElement?.tagName?.toLowerCase() !== 'pre') return `\`${node.textContent || ''}\``;
23
- if (tag === 'pre') {
24
- const code = normalize(node.textContent || '').replace(/^\n+|\n+$/g, '');
25
- const lang = Array.from(node.querySelectorAll('code')).map((codeNode) => {
26
- const match = String(codeNode.className || '').match(/language-([\w-]+)/);
27
- return match ? match[1] : '';
28
- }).find(Boolean) || '';
29
- return `\n\n${fence}${lang}\n${code}\n${fence}\n\n`;
30
- }
31
- if (tag === 'a') {
32
- const text = collapse(children()) || collapse(node.textContent || '');
33
- const href = node.getAttribute('href') || '';
34
- return href ? `[${text}](${href})` : text;
35
- }
36
- if (tag === 'li') return `- ${collapse(children())}\n`;
37
- if (tag === 'ul' || tag === 'ol') return `\n${Array.from(node.children).map((child) => markdownFromNode(child, depth + 1)).join('')}\n`;
38
- if (tag === 'p') return `${children().trim()}\n\n`;
39
- if (tag === 'table') {
40
- const rows = Array.from(node.querySelectorAll('tr')).map((row) => Array.from(row.children).map((cell) => collapse(markdownFromNode(cell, depth + 1)) || collapse(cell.textContent || '')));
41
- if (!rows.length) return '';
42
- const header = rows[0];
43
- const divider = header.map(() => '---');
44
- const body = rows.slice(1);
45
- return `\n| ${header.join(' | ')} |\n| ${divider.join(' | ')} |\n${body.map((row) => `| ${row.join(' | ')} |`).join('\n')}\n\n`;
46
- }
47
- if (tag === 'button') return '';
48
- return children();
49
- };
50
-
51
- const title = collapse(
52
- document.querySelector('.font-bold + .ml-1')?.textContent
53
- || document.querySelector('.font-bold')?.nextElementSibling?.textContent
54
- || ''
55
- ).replace(/^Task:\s*/i, '');
56
- const input = document.querySelector('textarea[placeholder*="Type your task" i]') || document.querySelector('textarea');
57
- const inputContent = input ? input.value || '' : '';
58
-
59
- const rawItems = Array.from(document.querySelectorAll('[data-item-index]')).map((element) => ({
60
- element,
61
- text: collapse(element.innerText || element.textContent || ''),
62
- })).filter((item) => item.text);
63
-
64
- const messages = [];
65
- let activeModal = null;
66
-
67
- if (title) {
68
- messages.push({ role: 'user', content: title, index: messages.length });
69
- }
70
-
71
- const significant = rawItems.filter((item) => !/^API Request(?:\n|$)/i.test(item.text) && !/^Initial Checkpoint(?:\n|$)/i.test(item.text));
72
-
73
- for (let itemIndex = 0; itemIndex < significant.length; itemIndex += 1) {
74
- const item = significant[itemIndex];
75
- const { element, text } = item;
76
-
77
- if (/^Thinking$/i.test(text)) continue;
78
- if (element.querySelector('.codicon-trash')) {
79
- messages.push({ role: 'user', content: text, index: messages.length });
80
- continue;
81
- }
82
-
83
- if (element.querySelector('.codicon-terminal') || /^Run Command:/i.test(text)) {
84
- const command = collapse(element.querySelector('.font-mono')?.textContent || text.replace(/^Run Command:\s*/i, ''));
85
- messages.push({
86
- role: 'assistant',
87
- content: command ? `${fence}sh\n${command}\n${fence}` : 'Run Command',
88
- kind: 'terminal',
89
- meta: { label: 'Run Command' },
90
- index: messages.length,
91
- });
92
- continue;
93
- }
94
-
95
- if (element.querySelector('.text-muted-foreground') && text.startsWith('...')) {
96
- messages.push({
97
- role: 'assistant',
98
- content: text.replace(/^\.\.\.\s*/, ''),
99
- kind: 'thought',
100
- meta: { label: 'Thinking' },
101
- index: messages.length,
102
- });
103
- continue;
104
- }
105
-
106
- if (element.querySelector('.codicon-question') || /^Agent has a question:/i.test(text)) {
107
- const contentNode = element.querySelector('.sc-fkSzgi') || element;
108
- let content = collapse(markdownFromNode(contentNode));
109
- const actions = Array.from(element.querySelectorAll('button[aria-label]')).map((button) => collapse(button.getAttribute('aria-label') || button.textContent || '')).filter(Boolean);
110
- if (actions.length) {
111
- content = `${content}\n\n${actions.map((action) => `- ${action}`).join('\n')}`.trim();
112
- if (itemIndex === significant.length - 1) {
113
- activeModal = { title: 'Agent has a question', actions };
114
- }
115
- }
116
- messages.push({ role: 'assistant', content, index: messages.length });
117
- continue;
118
- }
119
-
120
- if (element.querySelector('.codicon-check') && /^Task Completed/i.test(text)) {
121
- const contentNode = element.querySelector('.sc-fkSzgi') || element;
122
- const content = collapse(markdownFromNode(contentNode).replace(/^Task Completed\s*/i, ''));
123
- messages.push({ role: 'assistant', content, index: messages.length });
124
- continue;
125
- }
126
-
127
- const markdownNode = element.querySelector('.sc-fkSzgi') || element;
128
- const content = collapse(markdownFromNode(markdownNode));
129
- if (content) {
130
- messages.push({ role: 'assistant', content, index: messages.length });
131
- }
132
- }
133
-
134
- let status = 'idle';
135
- const visibleButtons = Array.from(document.querySelectorAll('button')).filter((button) => {
136
- const rect = button.getBoundingClientRect();
137
- return rect.width > 0 && rect.height > 0;
138
- });
139
-
140
- const actionButtons = visibleButtons
141
- .map((button) => collapse(button.textContent || button.getAttribute('aria-label') || ''))
142
- .filter((text) => /approve|accept|allow|run|save|reject|deny|abort/i.test(text));
143
- if (!activeModal && actionButtons.length >= 2) {
144
- activeModal = { title: 'Action Required', actions: actionButtons };
145
- }
146
- if (activeModal?.actions?.length) {
147
- status = 'waiting_approval';
148
- }
149
-
150
- const generatingIndicators = [
151
- ...visibleButtons.map((button) => collapse(button.textContent || button.getAttribute('aria-label') || '')),
152
- collapse(document.body.innerText || ''),
153
- ].join('\n');
154
- if (/cancel|stop generating|streaming|responding/i.test(generatingIndicators)) {
155
- status = activeModal?.actions?.length ? 'waiting_approval' : 'generating';
156
- }
157
-
158
- return JSON.stringify({
159
- id: 'pearai-agent',
160
- title: title || undefined,
161
- status,
162
- messages,
163
- inputContent: inputContent || undefined,
164
- activeModal: activeModal || undefined,
165
- });
166
- } catch (error) {
167
- return JSON.stringify({ id: 'pearai-agent', status: 'error', messages: [], error: String(error && error.message || error) });
168
- }
169
- })()
@@ -1,60 +0,0 @@
1
- /**
2
- * PearAI — webview_resolve_action
3
- *
4
- * PearAI Agent(Roo Code based)renders approve/reject button inside webview.
5
- * button click() event .
6
- *
7
- * Parameter: ${ BUTTON_TEXT }
8
- */
9
- (() => {
10
- try {
11
- const doc = document.getElementById("active-frame")?.contentDocument || document;
12
- const want = ${ BUTTON_TEXT };
13
- const wantNorm = (want || '').replace(/\s+/g, ' ').trim().toLowerCase();
14
-
15
- function norm(t) { return (t || '').replace(/\s+/g, ' ').trim().toLowerCase(); }
16
-
17
- function matches(el) {
18
- const t = norm(el.textContent);
19
- if (!t || t.length > 80) return false;
20
- if (t === wantNorm) return true;
21
- if (t.indexOf(wantNorm) === 0) return true;
22
- if (wantNorm.indexOf(t) >= 0 && t.length > 2) return true;
23
- if (/^(run|approve|allow|accept|yes)\b/.test(wantNorm)) {
24
- if (/^(run|allow|accept|approve|save)\b/.test(t)) return true;
25
- }
26
- if (/^(reject|deny|no|abort)\b/.test(wantNorm)) {
27
- if (/^(reject|deny)\b/.test(t)) return true;
28
- }
29
- return false;
30
- }
31
-
32
- const sel = 'button, [role="button"], .vsc-button';
33
- const allBtns = [...doc.querySelectorAll(sel)].filter(b => b.offsetWidth > 0 && b.offsetHeight > 0);
34
-
35
- let found = null;
36
- for (let i = allBtns.length - 1; i >= 0; i--) {
37
- if (matches(allBtns[i])) { found = allBtns[i]; break; }
38
- }
39
-
40
- if (found) {
41
- found.focus?.();
42
- const rect = found.getBoundingClientRect();
43
- const x = rect.left + rect.width / 2;
44
- const y = rect.top + rect.height / 2;
45
- for (const type of ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click']) {
46
- found.dispatchEvent(new PointerEvent(type, {
47
- bubbles: true, cancelable: true, view: window,
48
- clientX: x, clientY: y, pointerId: 1, pointerType: 'mouse'
49
- }));
50
- }
51
- return JSON.stringify({
52
- resolved: true,
53
- clicked: found.textContent || wantNorm
54
- });
55
- }
56
- return JSON.stringify({ resolved: false, error: 'Button not found: ' + wantNorm });
57
- } catch (e) {
58
- return JSON.stringify({ resolved: false, error: e.message });
59
- }
60
- })()
@@ -1,111 +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
- script = script.replace(/\$\{ MESSAGE \}/g, JSON.stringify(msg));
29
- }
30
- if (script.includes('${ BUTTON_TEXT }')) {
31
- const btn = params?.BUTTON_TEXT || params?.buttonText || '';
32
- script = script.replace(/\$\{ BUTTON_TEXT \}/g, JSON.stringify(btn));
33
- }
34
- if (script.includes('${ MODE }')) {
35
- const mode = params?.mode || '';
36
- script = script.replace(/\$\{ MODE \}/g, JSON.stringify(mode));
37
- }
38
- if (script.includes('${ MODEL }')) {
39
- const model = params?.model || '';
40
- script = script.replace(/\$\{ MODEL \}/g, JSON.stringify(model));
41
- }
42
- if (script.includes('${ INDEX }')) {
43
- const index = params?.index ?? 0;
44
- script = script.replace(/\$\{ INDEX \}/g, JSON.stringify(index));
45
- }
46
- if (script.includes('${ TITLE }')) {
47
- const title = params?.title || '';
48
- script = script.replace(/\$\{ TITLE \}/g, JSON.stringify(title));
49
- }
50
-
51
- if (!script.includes('${')) {
52
- return script;
53
- }
54
-
55
- return `(${script})(${JSON.stringify(params)})`;
56
- }
57
-
58
- module.exports.readChat = () => load('read_chat.js');
59
- module.exports.webviewReadChat = module.exports.readChat;
60
-
61
- module.exports.sendMessage = (params) => {
62
- let s = load('send_message.js');
63
- if (!s) return null;
64
- if (s.includes('${ MESSAGE }')) {
65
- const msg = params?.MESSAGE || params?.text || params || '';
66
- return s.replace(/\$\{ MESSAGE \}/g, JSON.stringify(msg));
67
- }
68
- return withParams('send_message.js', params);
69
- };
70
- module.exports.webviewSendMessage = module.exports.sendMessage;
71
-
72
- module.exports.listSessions = () => load('list_sessions.js');
73
- module.exports.webviewListSessions = module.exports.listSessions;
74
- module.exports.newSession = () => load('new_session.js');
75
- module.exports.webviewNewSession = module.exports.newSession;
76
- module.exports.focusEditor = () => load('focus_editor.js');
77
- module.exports.webviewFocusEditor = module.exports.focusEditor;
78
- module.exports.openPanel = () => load('open_panel.js');
79
- module.exports.listModels = () => load('list_models.js');
80
- module.exports.webviewListModels = module.exports.listModels;
81
- module.exports.listModes = () => load('list_modes.js');
82
- module.exports.webviewListModes = module.exports.listModes;
83
-
84
- // ─── With params (function expression) ───
85
-
86
- module.exports.switchSession = (params) => {
87
- const index = typeof params === 'number' ? params : params?.index ?? 0;
88
- const title = typeof params === 'string' ? params : params?.title || null;
89
- return withParams('switch_session.js', { index, title });
90
- };
91
- module.exports.webviewSwitchSession = module.exports.switchSession;
92
-
93
- module.exports.resolveAction = (params) => {
94
- const action = typeof params === 'string' ? params : params?.action || 'approve';
95
- const buttonText = params?.button || params?.buttonText
96
- || (action === 'approve' ? 'Accept' : action === 'reject' ? 'Reject' : action);
97
- return withParams('resolve_action.js', { buttonText, BUTTON_TEXT: buttonText });
98
- };
99
- module.exports.webviewResolveAction = module.exports.resolveAction;
100
-
101
- module.exports.setModel = (params) => {
102
- const model = typeof params === 'string' ? params : params?.model;
103
- return withParams('set_model.js', { model });
104
- };
105
- module.exports.webviewSetModel = module.exports.setModel;
106
-
107
- module.exports.setMode = (params) => {
108
- const mode = typeof params === 'string' ? params : params?.mode;
109
- return withParams('set_mode.js', { mode });
110
- };
111
- module.exports.webviewSetMode = module.exports.setMode;
@@ -1,104 +0,0 @@
1
- /**
2
- * PearAI — webview_send_message
3
- */
4
- (async () => {
5
- try {
6
- const message = ${ MESSAGE };
7
- const editor = document.querySelector('textarea[placeholder*="Type your task" i]')
8
- || document.querySelector('textarea')
9
- || document.querySelector('[contenteditable="true"]');
10
-
11
- if (!editor) {
12
- return JSON.stringify({ sent: false, error: 'input not found' });
13
- }
14
-
15
- editor.scrollIntoView({ block: 'center' });
16
- editor.focus();
17
- await new Promise((resolve) => setTimeout(resolve, 100));
18
-
19
- const isTextarea = editor.tagName === 'TEXTAREA';
20
- if (isTextarea) {
21
- const previousValue = editor.value;
22
- const nativeSetter = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set;
23
- if (nativeSetter) nativeSetter.call(editor, message);
24
- else editor.value = message;
25
- if (editor._valueTracker) {
26
- editor._valueTracker.setValue(previousValue);
27
- }
28
- editor.dispatchEvent(new Event('input', {
29
- bubbles: true,
30
- cancelable: true,
31
- composed: true,
32
- }));
33
- editor.dispatchEvent(new Event('change', { bubbles: true }));
34
-
35
- if ((editor.value || '') !== message) {
36
- editor.value = '';
37
- editor.setSelectionRange?.(0, 0);
38
- editor.setRangeText?.(message, 0, editor.value.length, 'end');
39
- editor.dispatchEvent(new Event('input', { bubbles: true, cancelable: true, composed: true }));
40
- editor.dispatchEvent(new Event('change', { bubbles: true }));
41
- }
42
-
43
- if ((editor.value || '') !== message) {
44
- editor.focus();
45
- editor.select?.();
46
- document.execCommand?.('insertText', false, message);
47
- editor.dispatchEvent(new Event('input', { bubbles: true, cancelable: true, composed: true }));
48
- editor.dispatchEvent(new Event('change', { bubbles: true }));
49
- }
50
- } else {
51
- const selection = window.getSelection();
52
- const range = document.createRange();
53
- range.selectNodeContents(editor);
54
- selection.removeAllRanges();
55
- selection.addRange(range);
56
- document.execCommand('delete', false, null);
57
- document.execCommand('insertText', false, message);
58
- editor.dispatchEvent(new InputEvent('input', {
59
- bubbles: true,
60
- cancelable: true,
61
- composed: true,
62
- data: message,
63
- inputType: 'insertText',
64
- }));
65
- }
66
-
67
- await new Promise((resolve) => setTimeout(resolve, 350));
68
-
69
- const sendButton = Array.from(document.querySelectorAll('button'))
70
- .find((button) => /send/i.test((button.textContent || '').trim()) && !button.disabled);
71
-
72
- if (sendButton) {
73
- sendButton.scrollIntoView({ block: 'center' });
74
- sendButton.focus?.();
75
- for (const type of ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click']) {
76
- sendButton.dispatchEvent(new PointerEvent(type, {
77
- bubbles: true,
78
- cancelable: true,
79
- view: window,
80
- pointerId: 1,
81
- pointerType: 'mouse',
82
- }));
83
- }
84
- }
85
-
86
- const enterOptions = {
87
- key: 'Enter',
88
- code: 'Enter',
89
- keyCode: 13,
90
- which: 13,
91
- bubbles: true,
92
- cancelable: true,
93
- composed: true,
94
- };
95
-
96
- editor.dispatchEvent(new KeyboardEvent('keydown', enterOptions));
97
- editor.dispatchEvent(new KeyboardEvent('keypress', enterOptions));
98
- editor.dispatchEvent(new KeyboardEvent('keyup', enterOptions));
99
-
100
- return JSON.stringify({ sent: true });
101
- } catch (error) {
102
- return JSON.stringify({ sent: false, error: String(error && error.message || error) });
103
- }
104
- })()
@@ -1,51 +0,0 @@
1
- /**
2
- * PearAI — webview_set_mode
3
- * ${ MODE }
4
- */
5
- (async () => {
6
- try {
7
- const target = String(${ MODE }).trim().toLowerCase();
8
- const knownModes = ['💻 code', '🏗️ architect', '❓ ask', '🪲 debug', 'code', 'architect', 'ask', 'debug'];
9
- const trigger = Array.from(document.querySelectorAll('button[data-testid="dropdown-trigger"], button[title], button'))
10
- .find((button) => /select mode for interaction/i.test(button.getAttribute('title') || ''));
11
-
12
- if (!trigger) {
13
- return JSON.stringify({ success: false, error: 'mode trigger not found' });
14
- }
15
-
16
- trigger.click();
17
- await new Promise((resolve) => setTimeout(resolve, 250));
18
-
19
- const options = Array.from(document.querySelectorAll('[role="option"], [cmdk-item], [data-radix-collection-item], button, div, span'))
20
- .filter((node) => {
21
- const rect = node.getBoundingClientRect();
22
- const text = (node.textContent || '').trim();
23
- return node !== trigger
24
- && !trigger.contains(node)
25
- && rect.width > 0
26
- && rect.height > 0
27
- && text
28
- && text.length < 40;
29
- });
30
-
31
- const match = options.find((node) => {
32
- const text = (node.textContent || '').trim().toLowerCase();
33
- return knownModes.includes(text) && (text === target || text.includes(target));
34
- });
35
-
36
- if (!match) {
37
- const current = (trigger.textContent || '').trim();
38
- document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
39
- if (current.toLowerCase() === target || current.toLowerCase().includes(target)) {
40
- return JSON.stringify({ success: true, mode: current });
41
- }
42
- return JSON.stringify({ success: false, error: 'mode not found: ' + target });
43
- }
44
-
45
- match.click();
46
- await new Promise((resolve) => setTimeout(resolve, 200));
47
- return JSON.stringify({ success: true, mode: (match.textContent || '').trim() });
48
- } catch (error) {
49
- return JSON.stringify({ success: false, error: String(error && error.message || error) });
50
- }
51
- })()