@adhdev/daemon-core 0.6.53 → 0.6.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +76 -34
- package/dist/index.js +714 -271
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/providers/_builtin/_helpers/index.js +26 -26
- package/providers/_builtin/cli/aider-cli/provider.json +37 -0
- package/providers/_builtin/cli/aider-cli/scripts/1.0/detect_status.js +20 -0
- package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_approval.js +10 -0
- package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_output.js +49 -0
- package/providers/_builtin/cli/aider-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/cli/claude-cli/provider.json +9 -2
- package/providers/_builtin/cli/claude-cli/scripts/1.0/detect_status.js +31 -0
- package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_approval.js +38 -0
- package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_output.js +164 -0
- package/providers/_builtin/cli/claude-cli/scripts/1.0/scripts.js +42 -0
- package/providers/_builtin/cli/codex-cli/provider.json +9 -2
- package/providers/_builtin/cli/codex-cli/scripts/1.0/detect_status.js +20 -0
- package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_approval.js +15 -0
- package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_output.js +68 -0
- package/providers/_builtin/cli/codex-cli/scripts/1.0/scripts.js +11 -0
- package/providers/_builtin/cli/cursor-cli/provider.json +37 -0
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/detect_status.js +19 -0
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_approval.js +10 -0
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_output.js +48 -0
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/cli/gemini-cli/provider.json +9 -2
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/detect_status.js +26 -0
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_approval.js +22 -0
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_output.js +71 -0
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/scripts.js +12 -0
- package/providers/_builtin/cli/github-copilot-cli/provider.json +37 -0
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/detect_status.js +19 -0
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_approval.js +9 -0
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_output.js +48 -0
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/cli/goose-cli/provider.json +37 -0
- package/providers/_builtin/cli/goose-cli/scripts/1.0/detect_status.js +20 -0
- package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_approval.js +10 -0
- package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_output.js +48 -0
- package/providers/_builtin/cli/goose-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/cli/opencode-cli/provider.json +37 -0
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/detect_status.js +15 -0
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_approval.js +9 -0
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_output.js +48 -0
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/extension/cline/scripts/1.0/focus_editor.js +5 -5
- package/providers/_builtin/extension/cline/scripts/1.0/list_chats.js +11 -11
- package/providers/_builtin/extension/cline/scripts/1.0/list_models.js +6 -6
- package/providers/_builtin/extension/cline/scripts/1.0/list_modes.js +5 -5
- package/providers/_builtin/extension/cline/scripts/1.0/new_session.js +12 -12
- package/providers/_builtin/extension/cline/scripts/1.0/open_panel.js +7 -7
- package/providers/_builtin/extension/cline/scripts/1.0/read_chat.js +29 -29
- package/providers/_builtin/extension/cline/scripts/1.0/resolve_action.js +19 -19
- package/providers/_builtin/extension/cline/scripts/1.0/send_message.js +15 -15
- package/providers/_builtin/extension/cline/scripts/1.0/set_mode.js +4 -4
- package/providers/_builtin/extension/cline/scripts/1.0/set_model.js +4 -4
- package/providers/_builtin/extension/cline/scripts/1.0/switch_session.js +21 -21
- package/providers/_builtin/extension/codex/scripts/1.0/explore_controls_webview.js +2 -2
- package/providers/_builtin/extension/codex/scripts/1.0/list_models.js +1 -1
- package/providers/_builtin/extension/codex/scripts/1.0/list_modes.js +1 -1
- package/providers/_builtin/extension/codex/scripts/1.0/new_session.js +2 -2
- package/providers/_builtin/extension/codex/scripts/1.0/read_chat.js +6 -6
- package/providers/_builtin/extension/codex/scripts/1.0/resolve_action.js +3 -3
- package/providers/_builtin/extension/codex/scripts/1.0/set_model.js +1 -1
- package/providers/_builtin/ide/antigravity/scripts/1.0/focus_editor.js +2 -2
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_chats.js +19 -19
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_models.js +1 -1
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_modes.js +1 -1
- package/providers/_builtin/ide/antigravity/scripts/1.0/new_session.js +17 -17
- package/providers/_builtin/ide/antigravity/scripts/1.0/read_chat.js +41 -41
- package/providers/_builtin/ide/antigravity/scripts/1.0/resolve_action.js +6 -6
- package/providers/_builtin/ide/antigravity/scripts/1.0/send_message.js +13 -13
- package/providers/_builtin/ide/antigravity/scripts/1.0/set_model.js +1 -1
- package/providers/_builtin/ide/antigravity/scripts/1.0/switch_session.js +13 -13
- package/providers/_builtin/ide/cursor/scripts/1.0/dismiss_notification.js +3 -3
- package/providers/_builtin/ide/cursor/scripts/1.0/focus_editor.js +1 -1
- package/providers/_builtin/ide/cursor/scripts/1.0/list_models.js +12 -12
- package/providers/_builtin/ide/cursor/scripts/1.0/list_modes.js +5 -5
- package/providers/_builtin/ide/cursor/scripts/1.0/list_notifications.js +2 -2
- package/providers/_builtin/ide/cursor/scripts/1.0/list_sessions.js +5 -5
- package/providers/_builtin/ide/cursor/scripts/1.0/new_session.js +1 -1
- package/providers/_builtin/ide/cursor/scripts/1.0/open_panel.js +3 -3
- package/providers/_builtin/ide/cursor/scripts/1.0/read_chat.js +9 -9
- package/providers/_builtin/ide/cursor/scripts/1.0/resolve_action.js +4 -4
- package/providers/_builtin/ide/cursor/scripts/1.0/send_message.js +5 -5
- package/providers/_builtin/ide/cursor/scripts/1.0/set_mode.js +4 -4
- package/providers/_builtin/ide/cursor/scripts/1.0/set_model.js +12 -12
- package/providers/_builtin/ide/cursor/scripts/1.0/switch_session.js +2 -2
- package/providers/_builtin/ide/kiro/scripts/1.0/focus_editor.js +2 -2
- package/providers/_builtin/ide/kiro/scripts/1.0/open_panel.js +7 -7
- package/providers/_builtin/ide/kiro/scripts/1.0/resolve_action.js +3 -3
- package/providers/_builtin/ide/kiro/scripts/1.0/send_message.js +4 -4
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_sessions.js +2 -2
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_new_session.js +5 -5
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_read_chat.js +13 -13
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_resolve_action.js +1 -1
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_send_message.js +8 -8
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_mode.js +1 -1
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_model.js +1 -1
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_switch_session.js +3 -3
- package/providers/_builtin/ide/pearai/.tmp/after_rich.json +157 -0
- package/providers/_builtin/ide/pearai/.tmp/after_rich_raw.json +161 -0
- package/providers/_builtin/ide/pearai/.tmp/after_switch.json +592 -0
- package/providers/_builtin/ide/pearai/.tmp/after_switch_raw.json +596 -0
- package/providers/_builtin/ide/pearai/.tmp/home_dump_raw.json +176 -0
- package/providers/_builtin/ide/pearai/.tmp/items_raw.json +778 -0
- package/providers/_builtin/ide/pearai/.tmp/webview_dump.json +157 -0
- package/providers/_builtin/ide/pearai/.tmp/webview_dump_raw.json +161 -0
- package/providers/_builtin/ide/pearai/provider.json +1 -3
- package/providers/_builtin/ide/pearai/scripts/1.0/focus_editor.js +12 -16
- package/providers/_builtin/ide/pearai/scripts/1.0/list_models.js +45 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/list_modes.js +44 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/list_sessions.js +82 -27
- package/providers/_builtin/ide/pearai/scripts/1.0/new_session.js +26 -43
- package/providers/_builtin/ide/pearai/scripts/1.0/open_panel.js +10 -33
- package/providers/_builtin/ide/pearai/scripts/1.0/read_chat.js +169 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/resolve_action.js +47 -41
- package/providers/_builtin/ide/pearai/scripts/1.0/scripts.js +36 -7
- package/providers/_builtin/ide/pearai/scripts/1.0/send_message.js +97 -22
- package/providers/_builtin/ide/pearai/scripts/1.0/set_mode.js +51 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/set_model.js +54 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/switch_session.js +81 -0
- package/providers/_builtin/ide/trae/scripts/1.0/focus_editor.js +2 -2
- package/providers/_builtin/ide/trae/scripts/1.0/list_chats.js +2 -2
- package/providers/_builtin/ide/trae/scripts/1.0/new_session.js +4 -4
- package/providers/_builtin/ide/trae/scripts/1.0/open_panel.js +6 -6
- package/providers/_builtin/ide/trae/scripts/1.0/read_chat.js +13 -13
- package/providers/_builtin/ide/trae/scripts/1.0/resolve_action.js +3 -3
- package/providers/_builtin/ide/trae/scripts/1.0/send_message.js +11 -11
- package/providers/_builtin/ide/trae/scripts/1.0/switch_session.js +2 -2
- package/providers/_builtin/ide/windsurf/scripts/1.0/focus_editor.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_chats.js +4 -4
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_sessions.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0/new_session.js +9 -9
- package/providers/_builtin/ide/windsurf/scripts/1.0/open_panel.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0/resolve_action.js +8 -8
- package/providers/_builtin/ide/windsurf/scripts/1.0/switch_session.js +8 -8
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/focus_editor.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_chats.js +12 -12
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/new_session.js +15 -15
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/open_panel.js +10 -10
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/read_chat.js +33 -33
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/resolve_action.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/send_message.js +16 -16
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/switch_session.js +7 -7
- package/providers/_builtin/registry.json +76 -3
- package/src/cli-adapters/provider-cli-adapter.ts +267 -251
- package/src/cli-adapters/terminal-screen.ts +268 -0
- package/src/commands/chat-commands.ts +41 -15
- package/src/commands/cli-manager.ts +4 -2
- package/src/daemon/dev-server.ts +245 -35
- package/src/providers/acp-provider-instance.ts +1 -1
- package/src/providers/cli-provider-instance.ts +21 -8
- package/src/providers/provider-loader.ts +3 -2
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_models.js +0 -43
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_modes.js +0 -35
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_sessions.js +0 -62
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_new_session.js +0 -49
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_read_chat.js +0 -92
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_resolve_action.js +0 -59
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_send_message.js +0 -72
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_set_mode.js +0 -36
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_set_model.js +0 -36
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_switch_session.js +0 -34
|
@@ -1,29 +1,104 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PearAI —
|
|
3
|
-
*
|
|
4
|
-
* PearAI의 채팅 입력은 webview iframe 안에 있어 메인 DOM에서 직접 접근 불가.
|
|
5
|
-
* auxbar 하단의 입력 필드 좌표를 계산하여 clickCoords로 반환.
|
|
6
|
-
* 데몬이 CDP Input API로 해당 좌표에 클릭+타이핑+Enter를 수행.
|
|
7
|
-
*
|
|
8
|
-
* 파라미터: ${ MESSAGE }
|
|
2
|
+
* PearAI — webview_send_message
|
|
9
3
|
*/
|
|
10
|
-
(() => {
|
|
4
|
+
(async () => {
|
|
11
5
|
try {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
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
|
+
}));
|
|
15
65
|
}
|
|
16
66
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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) });
|
|
28
103
|
}
|
|
29
104
|
})()
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
})()
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PearAI — webview_set_model
|
|
3
|
+
* ${ MODEL }
|
|
4
|
+
*/
|
|
5
|
+
(async () => {
|
|
6
|
+
try {
|
|
7
|
+
const target = String(${ MODEL }).trim().toLowerCase();
|
|
8
|
+
const knownModelPattern = /default|gpt|claude|gemini|sonnet|haiku|o1|o3|4\.1|3\.7/i;
|
|
9
|
+
const trigger = Array.from(document.querySelectorAll('button[data-testid="dropdown-trigger"], button[title], button'))
|
|
10
|
+
.find((button) => /select api configuration/i.test(button.getAttribute('title') || ''));
|
|
11
|
+
|
|
12
|
+
if (!trigger) {
|
|
13
|
+
return JSON.stringify({ success: false, error: 'model 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 < 80
|
|
29
|
+
&& !node.querySelector('textarea')
|
|
30
|
+
&& node.querySelectorAll('button').length === 0
|
|
31
|
+
&& node.children.length <= 2;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const match = options.find((node) => {
|
|
35
|
+
const text = (node.textContent || '').trim().toLowerCase();
|
|
36
|
+
return knownModelPattern.test(text) && (text === target || text.includes(target));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (!match) {
|
|
40
|
+
const current = (trigger.textContent || '').trim();
|
|
41
|
+
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
42
|
+
if (current.toLowerCase() === target || current.toLowerCase().includes(target)) {
|
|
43
|
+
return JSON.stringify({ success: true, model: current });
|
|
44
|
+
}
|
|
45
|
+
return JSON.stringify({ success: false, error: 'model not found: ' + target });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
match.click();
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
50
|
+
return JSON.stringify({ success: true, model: (match.textContent || '').trim() });
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return JSON.stringify({ success: false, error: String(error && error.message || error) });
|
|
53
|
+
}
|
|
54
|
+
})()
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PearAI — webview_switch_session
|
|
3
|
+
* ${ INDEX }
|
|
4
|
+
* ${ TITLE }
|
|
5
|
+
*/
|
|
6
|
+
(() => {
|
|
7
|
+
try {
|
|
8
|
+
const targetIndex = Number(${ INDEX });
|
|
9
|
+
const targetTitle = String(${ TITLE }).trim().toLowerCase();
|
|
10
|
+
|
|
11
|
+
const clickElement = (element) => {
|
|
12
|
+
if (!element) return false;
|
|
13
|
+
const rect = element.getBoundingClientRect();
|
|
14
|
+
const x = rect.left + rect.width / 2;
|
|
15
|
+
const y = rect.top + rect.height / 2;
|
|
16
|
+
element.scrollIntoView({ block: 'center' });
|
|
17
|
+
element.focus?.();
|
|
18
|
+
element.click?.();
|
|
19
|
+
for (const type of ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click']) {
|
|
20
|
+
element.dispatchEvent(new PointerEvent(type, {
|
|
21
|
+
bubbles: true,
|
|
22
|
+
cancelable: true,
|
|
23
|
+
view: window,
|
|
24
|
+
clientX: x,
|
|
25
|
+
clientY: y,
|
|
26
|
+
pointerId: 1,
|
|
27
|
+
pointerType: 'mouse',
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const taskItems = Array.from(document.querySelectorAll('[data-testid^="task-item-"]'));
|
|
34
|
+
if (taskItems.length) {
|
|
35
|
+
let match = null;
|
|
36
|
+
if (targetTitle) {
|
|
37
|
+
match = taskItems.find((item) => (item.textContent || '').trim().toLowerCase().includes(targetTitle));
|
|
38
|
+
}
|
|
39
|
+
if (!match && Number.isInteger(targetIndex) && targetIndex >= 0 && targetIndex < taskItems.length) {
|
|
40
|
+
match = taskItems[targetIndex];
|
|
41
|
+
}
|
|
42
|
+
if (match && clickElement(match)) {
|
|
43
|
+
return JSON.stringify({ switched: true, title: (match.textContent || '').trim().slice(0, 120) });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const cards = Array.from(document.querySelectorAll('div')).filter((card) => {
|
|
48
|
+
const className = String(card.className || '');
|
|
49
|
+
const text = (card.textContent || '').trim();
|
|
50
|
+
return className.includes('bg-vscode-editor-background')
|
|
51
|
+
&& className.includes('cursor-pointer')
|
|
52
|
+
&& className.includes('overflow-hidden')
|
|
53
|
+
&& !!card.querySelector('[data-testid="copy-prompt-button"]')
|
|
54
|
+
&& /↑\s*\d|↓\s*\d/i.test(text)
|
|
55
|
+
&& /MARCH|APRIL|MAY|JUNE|JULY|AUGUST|SEPTEMBER|OCTOBER|NOVEMBER|DECEMBER|JANUARY|FEBRUARY/i.test(text);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
let match = null;
|
|
59
|
+
if (targetTitle) {
|
|
60
|
+
match = cards.find((card) => {
|
|
61
|
+
const promptText = (card.querySelector('.text-vscode-foreground')?.textContent || '').trim().toLowerCase();
|
|
62
|
+
return promptText.includes(targetTitle);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (!match && Number.isInteger(targetIndex) && targetIndex >= 0 && targetIndex < cards.length) {
|
|
66
|
+
match = cards[targetIndex];
|
|
67
|
+
}
|
|
68
|
+
if (!match && cards.length === 1) {
|
|
69
|
+
match = cards[0];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const clickTarget = match ? (match.querySelector('.text-vscode-foreground') || match) : null;
|
|
73
|
+
if (clickTarget && clickElement(clickTarget)) {
|
|
74
|
+
return JSON.stringify({ switched: true, title: (match.textContent || '').trim().slice(0, 120) });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return JSON.stringify({ switched: false, error: 'session not found' });
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return JSON.stringify({ switched: false, error: String(error && error.message || error) });
|
|
80
|
+
}
|
|
81
|
+
})()
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cursor v1 — focus_editor
|
|
3
3
|
*
|
|
4
|
-
* CURSOR.md 4-5:
|
|
4
|
+
* CURSOR.md 4-5: Selector priority
|
|
5
5
|
* [contenteditable="true"][role="textbox"]
|
|
6
6
|
* → .chat-input textarea
|
|
7
7
|
* → .composer-input
|
|
8
8
|
* → textarea
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* final Check: 2026-03-06
|
|
11
11
|
*/
|
|
12
12
|
(() => {
|
|
13
13
|
const editor = document.querySelector('[contenteditable="true"][role="textbox"]')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Trae — list_chats
|
|
3
3
|
*
|
|
4
|
-
* Trae
|
|
4
|
+
* Trae from main DOM / Session list get.
|
|
5
5
|
*/
|
|
6
6
|
(() => {
|
|
7
7
|
try {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
return { id: String(i), title, active };
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
// list history button Check
|
|
20
20
|
return JSON.stringify({ sessions });
|
|
21
21
|
} catch (e) {
|
|
22
22
|
return JSON.stringify({ error: e.message, sessions: [] });
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Trae — new_session
|
|
3
3
|
*
|
|
4
|
-
* "New Task"
|
|
5
|
-
* Trae
|
|
4
|
+
* "New Task" create (⌃⌘N shortcut or button click).
|
|
5
|
+
* Trae from main DOM accessible.
|
|
6
6
|
*/
|
|
7
7
|
(() => {
|
|
8
8
|
try {
|
|
9
|
-
//
|
|
9
|
+
// button search
|
|
10
10
|
const buttons = document.querySelectorAll('button, [role="button"], .action-item a');
|
|
11
11
|
for (const btn of buttons) {
|
|
12
12
|
const text = (btn.textContent || '').trim();
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// shortcut fallback: ⌃⌘N
|
|
21
21
|
document.dispatchEvent(new KeyboardEvent('keydown', {
|
|
22
22
|
key: 'n', code: 'KeyN', keyCode: 78,
|
|
23
23
|
metaKey: true, ctrlKey: true,
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Trae — open_panel
|
|
3
3
|
*
|
|
4
|
-
* Trae AI
|
|
5
|
-
* "TRAE"
|
|
4
|
+
* Trae AI chat panel open.
|
|
5
|
+
* "TRAE" button or ⌘L via shortcut open.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Return: 'visible' | 'opened' | 'error: ...'
|
|
8
8
|
*/
|
|
9
9
|
(() => {
|
|
10
10
|
try {
|
|
11
|
-
// 1.
|
|
11
|
+
// 1. if already open Check
|
|
12
12
|
const sidebar = document.getElementById('workbench.parts.auxiliarybar');
|
|
13
13
|
if (sidebar && sidebar.offsetWidth > 0 && sidebar.offsetHeight > 0) {
|
|
14
14
|
return 'visible';
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
// 2. "TRAE" button click
|
|
18
18
|
const toggleBtns = Array.from(document.querySelectorAll('li.action-item a, button, [role="button"]'));
|
|
19
19
|
for (const btn of toggleBtns) {
|
|
20
20
|
const label = (btn.getAttribute('aria-label') || '');
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
// 3. Cmd+L
|
|
28
|
+
// 3. Cmd+L shortcut fallback (Trae default shortcut)
|
|
29
29
|
document.dispatchEvent(new KeyboardEvent('keydown', {
|
|
30
30
|
key: 'l', code: 'KeyL', keyCode: 76,
|
|
31
31
|
metaKey: true, ctrlKey: false,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Trae — read_chat
|
|
3
3
|
*
|
|
4
|
-
* Trae
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Trae from main DOM chat content accessible.
|
|
5
|
+
* chat is .chat-turn element .
|
|
6
|
+
* : .user-chat-bubble-request__content-wrapper
|
|
7
|
+
* : .assistant-chat-turn-content .chat-markdown
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* Return: ReadChatResult { id, status, messages, title?, inputContent?, activeModal? }
|
|
10
10
|
*/
|
|
11
11
|
(() => {
|
|
12
12
|
try {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
return JSON.stringify({ id: '', status: 'idle', messages: [] });
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
// ─── 1.
|
|
18
|
+
// ─── 1. Collect messages ───
|
|
19
19
|
const messages = [];
|
|
20
20
|
const turns = auxbar.querySelectorAll('.chat-turn');
|
|
21
21
|
|
|
@@ -50,22 +50,22 @@
|
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
// ─── 2.
|
|
53
|
+
// ─── 2. status detection ───
|
|
54
54
|
let status = 'idle';
|
|
55
55
|
|
|
56
|
-
// Stop
|
|
56
|
+
// Stop button exists → generating
|
|
57
57
|
const stopBtn = auxbar.querySelector('button[class*="stop"], [aria-label*="stop" i], [aria-label*="Stop"]');
|
|
58
58
|
if (stopBtn && stopBtn.offsetWidth > 0) {
|
|
59
59
|
status = 'generating';
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
// progress bar → generating
|
|
63
63
|
const progress = auxbar.querySelector('.monaco-progress-container:not(.done)');
|
|
64
64
|
if (progress && progress.offsetWidth > 0) {
|
|
65
65
|
status = 'generating';
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
// latest-assistant-bar most accurate (final determination)
|
|
69
69
|
const latestBar = auxbar.querySelector('.latest-assistant-bar');
|
|
70
70
|
if (latestBar) {
|
|
71
71
|
const barText = latestBar.textContent.toLowerCase();
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
// ─── 3.
|
|
79
|
+
// ─── 3. approval wait modal ───
|
|
80
80
|
let activeModal = null;
|
|
81
81
|
const dialogs = auxbar.querySelectorAll('[role="dialog"], .monaco-dialog-box, [class*="approval"], [class*="confirm"]');
|
|
82
82
|
if (dialogs.length > 0) {
|
|
@@ -91,11 +91,11 @@
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
// ─── 4.
|
|
94
|
+
// ─── 4. Input field content ───
|
|
95
95
|
const input = auxbar.querySelector('.chat-input-v2-input-box-editable, [contenteditable="true"]');
|
|
96
96
|
const inputContent = input ? input.textContent.trim() : '';
|
|
97
97
|
|
|
98
|
-
// ─── 5.
|
|
98
|
+
// ─── 5. Session ID / Title ───
|
|
99
99
|
const sessionTab = auxbar.querySelector('[class*="session-tab"], [class*="chat-title"]');
|
|
100
100
|
const title = sessionTab ? sessionTab.textContent.trim() : '';
|
|
101
101
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Trae — resolve_action
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Find approve/reject buttons + coordinates Return.
|
|
5
|
+
* Traeapproval dialog is displayed in main DOM.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Parameter: ${ BUTTON_TEXT }
|
|
8
8
|
*/
|
|
9
9
|
(() => {
|
|
10
10
|
const want = ${ BUTTON_TEXT };
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Trae — send_message
|
|
3
3
|
*
|
|
4
|
-
* Trae
|
|
5
|
-
* Lexical
|
|
4
|
+
* Trae .chat-input-v2-input-box-editable (contenteditable / Lexical) use.
|
|
5
|
+
* Lexical inside state to correctly update Selection API + execCommand use.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Parameter: ${ MESSAGE }
|
|
8
8
|
*/
|
|
9
9
|
(async () => {
|
|
10
10
|
try {
|
|
11
11
|
const msg = ${ MESSAGE };
|
|
12
12
|
|
|
13
|
-
// ─── 1.
|
|
13
|
+
// ─── 1. Find input field ───
|
|
14
14
|
const editor =
|
|
15
15
|
document.querySelector('.chat-input-v2-input-box-editable') ||
|
|
16
16
|
document.querySelector('[contenteditable="true"][role="textbox"]') ||
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
|
|
19
19
|
if (!editor) return JSON.stringify({ sent: false, error: 'no input found' });
|
|
20
20
|
|
|
21
|
-
// ─── 2.
|
|
21
|
+
// ─── 2. focus + all Select + delete + insert ───
|
|
22
22
|
editor.focus();
|
|
23
23
|
await new Promise(r => setTimeout(r, 100));
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
// Selection API all Select
|
|
26
26
|
const sel = window.getSelection();
|
|
27
27
|
const range = document.createRange();
|
|
28
28
|
range.selectNodeContents(editor);
|
|
@@ -30,23 +30,23 @@
|
|
|
30
30
|
sel.addRange(range);
|
|
31
31
|
await new Promise(r => setTimeout(r, 50));
|
|
32
32
|
|
|
33
|
-
//
|
|
33
|
+
// Delete and insert (sync Lexical state)
|
|
34
34
|
document.execCommand('delete', false, null);
|
|
35
35
|
await new Promise(r => setTimeout(r, 50));
|
|
36
36
|
document.execCommand('insertText', false, msg);
|
|
37
37
|
|
|
38
|
-
// Input
|
|
38
|
+
// Input event
|
|
39
39
|
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
|
40
40
|
await new Promise(r => setTimeout(r, 500));
|
|
41
41
|
|
|
42
|
-
// ─── 3. send
|
|
42
|
+
// ─── 3. send button click ───
|
|
43
43
|
const sendBtn = document.querySelector('.chat-input-v2-send-button');
|
|
44
44
|
if (sendBtn && !sendBtn.disabled) {
|
|
45
45
|
sendBtn.click();
|
|
46
46
|
return JSON.stringify({ sent: true, method: 'button' });
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
// button If still disabled, try Enter key
|
|
50
50
|
const enterOpts = {
|
|
51
51
|
key: 'Enter', code: 'Enter',
|
|
52
52
|
keyCode: 13, which: 13,
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
editor.dispatchEvent(new KeyboardEvent('keypress', enterOpts));
|
|
58
58
|
editor.dispatchEvent(new KeyboardEvent('keyup', enterOpts));
|
|
59
59
|
|
|
60
|
-
//
|
|
60
|
+
// If still fails needsTypeAndSend fallback
|
|
61
61
|
return JSON.stringify({
|
|
62
62
|
sent: false,
|
|
63
63
|
needsTypeAndSend: true,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Windsurf v1 — focus_editor
|
|
3
3
|
*
|
|
4
|
-
* Cascade(
|
|
5
|
-
* Windsurf
|
|
4
|
+
* Cascade(chat) focus on input field.
|
|
5
|
+
* Windsurf VS Code fork, chat UI "Cascade"is called.
|
|
6
6
|
*
|
|
7
|
-
* DOM
|
|
7
|
+
* DOM structure:
|
|
8
8
|
* #windsurf.cascadePanel → .chat-client-root
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* input: [contenteditable="true"][role="textbox"]
|
|
10
|
+
* or textarea ()
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* final Check: Windsurf (2026-03-06)
|
|
13
13
|
*/
|
|
14
14
|
(() => {
|
|
15
15
|
try {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Windsurf v1 — list_chats
|
|
3
3
|
*
|
|
4
|
-
* Cascade
|
|
5
|
-
*
|
|
6
|
-
* cascade-tab-{uuid}
|
|
4
|
+
* Cascade get tab list.
|
|
5
|
+
* If panel is closed open first and wait until tab is rendered.
|
|
6
|
+
* cascade-tab-{uuid} element React Fiberfrom title extract.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* final Check: Windsurf 1.108.x (2026-03-10)
|
|
9
9
|
*/
|
|
10
10
|
(async () => {
|
|
11
11
|
try {
|