@adhdev/daemon-core 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2662 -0
- package/dist/index.js +11341 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
- package/providers/_builtin/.github/workflows/generate-registry.yml +57 -0
- package/providers/_builtin/COMPATIBILITY.md +217 -0
- package/providers/_builtin/CONTRIBUTING.md +200 -0
- package/providers/_builtin/README.md +119 -0
- package/providers/_builtin/_helpers/index.js +188 -0
- package/providers/_builtin/acp/agentpool/provider.json +54 -0
- package/providers/_builtin/acp/amp/provider.json +52 -0
- package/providers/_builtin/acp/auggie/provider.json +57 -0
- package/providers/_builtin/acp/autodev/provider.json +54 -0
- package/providers/_builtin/acp/autohand/provider.json +52 -0
- package/providers/_builtin/acp/blackbox-ai/provider.json +54 -0
- package/providers/_builtin/acp/claude-agent/provider.json +57 -0
- package/providers/_builtin/acp/cline-acp/provider.json +54 -0
- package/providers/_builtin/acp/codebuddy/provider.json +54 -0
- package/providers/_builtin/acp/codex-cli/provider.json +57 -0
- package/providers/_builtin/acp/corust-agent/provider.json +52 -0
- package/providers/_builtin/acp/crow-cli/provider.json +54 -0
- package/providers/_builtin/acp/cursor-acp/provider.json +54 -0
- package/providers/_builtin/acp/deepagents/provider.json +52 -0
- package/providers/_builtin/acp/dimcode/provider.json +54 -0
- package/providers/_builtin/acp/docker-cagent/provider.json +57 -0
- package/providers/_builtin/acp/factory-droid/provider.json +60 -0
- package/providers/_builtin/acp/fast-agent/provider.json +52 -0
- package/providers/_builtin/acp/gemini-cli/provider.json +114 -0
- package/providers/_builtin/acp/github-copilot/provider.json +54 -0
- package/providers/_builtin/acp/goose/provider.json +57 -0
- package/providers/_builtin/acp/junie/provider.json +52 -0
- package/providers/_builtin/acp/kilo/provider.json +54 -0
- package/providers/_builtin/acp/kimi-cli/provider.json +57 -0
- package/providers/_builtin/acp/minion-code/provider.json +52 -0
- package/providers/_builtin/acp/mistral-vibe/provider.json +57 -0
- package/providers/_builtin/acp/nova/provider.json +54 -0
- package/providers/_builtin/acp/openclaw/provider.json +54 -0
- package/providers/_builtin/acp/opencode/provider.json +52 -0
- package/providers/_builtin/acp/openhands/provider.json +54 -0
- package/providers/_builtin/acp/pi-acp/provider.json +52 -0
- package/providers/_builtin/acp/qoder/provider.json +54 -0
- package/providers/_builtin/acp/qwen-code/provider.json +60 -0
- package/providers/_builtin/acp/stakpak/provider.json +54 -0
- package/providers/_builtin/acp/vtcode/provider.json +54 -0
- package/providers/_builtin/cli/claude-cli/provider.json +100 -0
- package/providers/_builtin/cli/codex-cli/provider.json +89 -0
- package/providers/_builtin/cli/gemini-cli/provider.json +93 -0
- package/providers/_builtin/docs/CDP_SELECTOR_GUIDE.md +370 -0
- package/providers/_builtin/docs/PROVIDER_GUIDE.md +916 -0
- package/providers/_builtin/extension/cline/provider.json +35 -0
- package/providers/_builtin/extension/cline/scripts/focus_editor.js +48 -0
- package/providers/_builtin/extension/cline/scripts/list_chats.js +100 -0
- package/providers/_builtin/extension/cline/scripts/list_models.js +43 -0
- package/providers/_builtin/extension/cline/scripts/list_modes.js +35 -0
- package/providers/_builtin/extension/cline/scripts/new_session.js +85 -0
- package/providers/_builtin/extension/cline/scripts/open_panel.js +25 -0
- package/providers/_builtin/extension/cline/scripts/read_chat.js +257 -0
- package/providers/_builtin/extension/cline/scripts/resolve_action.js +83 -0
- package/providers/_builtin/extension/cline/scripts/send_message.js +95 -0
- package/providers/_builtin/extension/cline/scripts/set_mode.js +36 -0
- package/providers/_builtin/extension/cline/scripts/set_model.js +36 -0
- package/providers/_builtin/extension/cline/scripts/switch_session.js +206 -0
- package/providers/_builtin/extension/cline/scripts.js +73 -0
- package/providers/_builtin/extension/roo-code/provider.json +35 -0
- package/providers/_builtin/extension/roo-code/scripts.js +659 -0
- package/providers/_builtin/ide/antigravity/provider.json +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/focus_editor.js +20 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_chats.js +137 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_models.js +38 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_modes.js +48 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/new_session.js +75 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/read_chat.js +262 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/resolve_action.js +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/scripts.js +57 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/send_message.js +56 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/set_mode.js +34 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/set_model.js +47 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/switch_session.js +114 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/focus_editor.js +20 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_chats.js +137 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_models.js +61 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_modes.js +72 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/new_session.js +75 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/read_chat.js +262 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/resolve_action.js +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/scripts.js +67 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/send_message.js +56 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/set_mode.js +67 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/set_model.js +72 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/switch_session.js +114 -0
- package/providers/_builtin/ide/cursor/provider.json +70 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/dismiss_notification.js +30 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/focus_editor.js +13 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_models.js +78 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_modes.js +40 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_notifications.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_sessions.js +42 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/new_session.js +20 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/open_panel.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/read_chat.js +75 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/resolve_action.js +19 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/scripts.js +78 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/send_message.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/set_mode.js +38 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/set_model.js +81 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/switch_session.js +28 -0
- package/providers/_builtin/ide/kiro/provider.json +67 -0
- package/providers/_builtin/ide/kiro/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/kiro/scripts/open_panel.js +47 -0
- package/providers/_builtin/ide/kiro/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/kiro/scripts/send_message.js +29 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_models.js +39 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_modes.js +39 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_sessions.js +21 -0
- package/providers/_builtin/ide/kiro/scripts/webview_new_session.js +34 -0
- package/providers/_builtin/ide/kiro/scripts/webview_read_chat.js +68 -0
- package/providers/_builtin/ide/kiro/scripts/webview_send_message.js +72 -0
- package/providers/_builtin/ide/kiro/scripts/webview_set_mode.js +15 -0
- package/providers/_builtin/ide/kiro/scripts/webview_set_model.js +15 -0
- package/providers/_builtin/ide/kiro/scripts/webview_switch_session.js +26 -0
- package/providers/_builtin/ide/kiro/scripts.js +62 -0
- package/providers/_builtin/ide/pearai/provider.json +67 -0
- package/providers/_builtin/ide/pearai/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/pearai/scripts/list_sessions.js +38 -0
- package/providers/_builtin/ide/pearai/scripts/new_session.js +55 -0
- package/providers/_builtin/ide/pearai/scripts/open_panel.js +46 -0
- package/providers/_builtin/ide/pearai/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/pearai/scripts/send_message.js +29 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_models.js +43 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_modes.js +35 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_sessions.js +62 -0
- package/providers/_builtin/ide/pearai/scripts/webview_new_session.js +49 -0
- package/providers/_builtin/ide/pearai/scripts/webview_read_chat.js +92 -0
- package/providers/_builtin/ide/pearai/scripts/webview_resolve_action.js +59 -0
- package/providers/_builtin/ide/pearai/scripts/webview_send_message.js +72 -0
- package/providers/_builtin/ide/pearai/scripts/webview_set_mode.js +36 -0
- package/providers/_builtin/ide/pearai/scripts/webview_set_model.js +36 -0
- package/providers/_builtin/ide/pearai/scripts/webview_switch_session.js +34 -0
- package/providers/_builtin/ide/pearai/scripts.js +74 -0
- package/providers/_builtin/ide/trae/provider.json +66 -0
- package/providers/_builtin/ide/trae/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/trae/scripts/list_chats.js +24 -0
- package/providers/_builtin/ide/trae/scripts/list_models.js +39 -0
- package/providers/_builtin/ide/trae/scripts/list_modes.js +39 -0
- package/providers/_builtin/ide/trae/scripts/new_session.js +30 -0
- package/providers/_builtin/ide/trae/scripts/open_panel.js +44 -0
- package/providers/_builtin/ide/trae/scripts/read_chat.js +113 -0
- package/providers/_builtin/ide/trae/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/trae/scripts/send_message.js +69 -0
- package/providers/_builtin/ide/trae/scripts/set_mode.js +15 -0
- package/providers/_builtin/ide/trae/scripts/set_model.js +15 -0
- package/providers/_builtin/ide/trae/scripts/switch_session.js +23 -0
- package/providers/_builtin/ide/trae/scripts.js +57 -0
- package/providers/_builtin/ide/vscode/provider.json +64 -0
- package/providers/_builtin/ide/vscode-insiders/provider.json +62 -0
- package/providers/_builtin/ide/vscodium/provider.json +63 -0
- package/providers/_builtin/ide/windsurf/provider.json +53 -0
- package/providers/_builtin/ide/windsurf/scripts/focus_editor.js +30 -0
- package/providers/_builtin/ide/windsurf/scripts/list_chats.js +117 -0
- package/providers/_builtin/ide/windsurf/scripts/list_models.js +39 -0
- package/providers/_builtin/ide/windsurf/scripts/list_modes.js +39 -0
- package/providers/_builtin/ide/windsurf/scripts/new_session.js +69 -0
- package/providers/_builtin/ide/windsurf/scripts/open_panel.js +58 -0
- package/providers/_builtin/ide/windsurf/scripts/read_chat.js +297 -0
- package/providers/_builtin/ide/windsurf/scripts/resolve_action.js +68 -0
- package/providers/_builtin/ide/windsurf/scripts/send_message.js +87 -0
- package/providers/_builtin/ide/windsurf/scripts/set_mode.js +15 -0
- package/providers/_builtin/ide/windsurf/scripts/set_model.js +15 -0
- package/providers/_builtin/ide/windsurf/scripts/switch_session.js +58 -0
- package/providers/_builtin/ide/windsurf/scripts.js +57 -0
- package/providers/_builtin/registry.json +266 -0
- package/providers/_builtin/validate.js +156 -0
- package/src/agent-stream/index.ts +6 -0
- package/src/agent-stream/manager.ts +286 -0
- package/src/agent-stream/poller.ts +154 -0
- package/src/agent-stream/provider-adapter.ts +138 -0
- package/src/agent-stream/types.ts +61 -0
- package/src/boot/daemon-lifecycle.ts +252 -0
- package/src/cdp/devtools.ts +335 -0
- package/src/cdp/initializer.ts +191 -0
- package/src/cdp/manager.ts +897 -0
- package/src/cdp/scanner.ts +185 -0
- package/src/cdp/setup.ts +150 -0
- package/src/cli-adapter-types.ts +25 -0
- package/src/cli-adapters/provider-cli-adapter.ts +448 -0
- package/src/commands/cdp-commands.ts +208 -0
- package/src/commands/chat-commands.ts +675 -0
- package/src/commands/cli-manager.ts +353 -0
- package/src/commands/handler.ts +328 -0
- package/src/commands/router.ts +258 -0
- package/src/commands/stream-commands.ts +325 -0
- package/src/config/chat-history.ts +211 -0
- package/src/config/config.ts +219 -0
- package/src/daemon/dev-server.ts +2378 -0
- package/src/daemon/scaffold-template.ts +394 -0
- package/src/daemon-core.ts +50 -0
- package/src/detection/cli-detector.ts +89 -0
- package/src/detection/ide-detector.ts +157 -0
- package/src/index.ts +103 -0
- package/src/installer.ts +263 -0
- package/src/ipc-protocol.ts +133 -0
- package/src/launch.ts +433 -0
- package/src/logging/command-log.ts +180 -0
- package/src/logging/logger.ts +316 -0
- package/src/providers/acp-provider-instance.ts +1140 -0
- package/src/providers/cli-provider-instance.ts +207 -0
- package/src/providers/contracts.ts +524 -0
- package/src/providers/extension-provider-instance.ts +156 -0
- package/src/providers/ide-provider-instance.ts +377 -0
- package/src/providers/index.ts +18 -0
- package/src/providers/provider-instance-manager.ts +182 -0
- package/src/providers/provider-instance.ts +112 -0
- package/src/providers/provider-loader.ts +1031 -0
- package/src/providers/status-monitor.ts +125 -0
- package/src/providers/version-archive.ts +266 -0
- package/src/status/reporter.ts +294 -0
- package/src/types.ts +206 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trae — open_panel
|
|
3
|
+
*
|
|
4
|
+
* Trae AI 채팅 패널 열기.
|
|
5
|
+
* "TRAE" 버튼 또는 ⌘L 단축키로 열기.
|
|
6
|
+
*
|
|
7
|
+
* 반환: 'visible' | 'opened' | 'error: ...'
|
|
8
|
+
*/
|
|
9
|
+
(() => {
|
|
10
|
+
try {
|
|
11
|
+
// 1. 이미 열려 있는지 확인
|
|
12
|
+
const sidebar = document.getElementById('workbench.parts.auxiliarybar');
|
|
13
|
+
if (sidebar && sidebar.offsetWidth > 0 && sidebar.offsetHeight > 0) {
|
|
14
|
+
return 'visible';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 2. "TRAE" 버튼 클릭 시도
|
|
18
|
+
const toggleBtns = Array.from(document.querySelectorAll('li.action-item a, button, [role="button"]'));
|
|
19
|
+
for (const btn of toggleBtns) {
|
|
20
|
+
const label = (btn.getAttribute('aria-label') || '');
|
|
21
|
+
if (label === 'TRAE' || label.toLowerCase().includes('toggle secondary') ||
|
|
22
|
+
label.toLowerCase().includes('toggle auxiliary')) {
|
|
23
|
+
btn.click();
|
|
24
|
+
return 'opened (toggle)';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 3. Cmd+L 단축키 폴백 (Trae 기본 단축키)
|
|
29
|
+
document.dispatchEvent(new KeyboardEvent('keydown', {
|
|
30
|
+
key: 'l', code: 'KeyL', keyCode: 76,
|
|
31
|
+
metaKey: true, ctrlKey: false,
|
|
32
|
+
bubbles: true, cancelable: true,
|
|
33
|
+
}));
|
|
34
|
+
document.dispatchEvent(new KeyboardEvent('keyup', {
|
|
35
|
+
key: 'l', code: 'KeyL', keyCode: 76,
|
|
36
|
+
metaKey: true, ctrlKey: false,
|
|
37
|
+
bubbles: true, cancelable: true,
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
return 'opened (⌘L)';
|
|
41
|
+
} catch (e) {
|
|
42
|
+
return 'error: ' + e.message;
|
|
43
|
+
}
|
|
44
|
+
})()
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trae — read_chat
|
|
3
|
+
*
|
|
4
|
+
* Trae는 메인 DOM에서 직접 채팅 내용에 접근 가능.
|
|
5
|
+
* 채팅 턴은 .chat-turn 요소로 구분.
|
|
6
|
+
* 유저: .user-chat-bubble-request__content-wrapper
|
|
7
|
+
* 어시스턴트: .assistant-chat-turn-content .chat-markdown
|
|
8
|
+
*
|
|
9
|
+
* 반환: ReadChatResult { id, status, messages, title?, inputContent?, activeModal? }
|
|
10
|
+
*/
|
|
11
|
+
(() => {
|
|
12
|
+
try {
|
|
13
|
+
const auxbar = document.getElementById('workbench.parts.auxiliarybar');
|
|
14
|
+
if (!auxbar || auxbar.offsetWidth === 0) {
|
|
15
|
+
return JSON.stringify({ id: '', status: 'idle', messages: [] });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ─── 1. 메시지 수집 ───
|
|
19
|
+
const messages = [];
|
|
20
|
+
const turns = auxbar.querySelectorAll('.chat-turn');
|
|
21
|
+
|
|
22
|
+
turns.forEach((turn, idx) => {
|
|
23
|
+
// User message
|
|
24
|
+
const userBubble = turn.querySelector('.user-chat-bubble-request__content-wrapper');
|
|
25
|
+
if (userBubble) {
|
|
26
|
+
messages.push({
|
|
27
|
+
role: 'user',
|
|
28
|
+
content: userBubble.textContent.trim(),
|
|
29
|
+
index: idx,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Assistant message
|
|
34
|
+
const assistantEl = turn.querySelector('.assistant-chat-turn-content');
|
|
35
|
+
if (assistantEl) {
|
|
36
|
+
const mdBlocks = assistantEl.querySelectorAll('.chat-markdown-p, .chat-markdown pre');
|
|
37
|
+
let content = '';
|
|
38
|
+
if (mdBlocks.length > 0) {
|
|
39
|
+
content = Array.from(mdBlocks).map(b => b.textContent.trim()).join('\n');
|
|
40
|
+
} else {
|
|
41
|
+
content = assistantEl.textContent.trim();
|
|
42
|
+
}
|
|
43
|
+
if (content) {
|
|
44
|
+
messages.push({
|
|
45
|
+
role: 'assistant',
|
|
46
|
+
content: content,
|
|
47
|
+
index: idx,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// ─── 2. 상태 감지 ───
|
|
54
|
+
let status = 'idle';
|
|
55
|
+
|
|
56
|
+
// Stop 버튼 존재 → generating
|
|
57
|
+
const stopBtn = auxbar.querySelector('button[class*="stop"], [aria-label*="stop" i], [aria-label*="Stop"]');
|
|
58
|
+
if (stopBtn && stopBtn.offsetWidth > 0) {
|
|
59
|
+
status = 'generating';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// progress bar 활성 → generating
|
|
63
|
+
const progress = auxbar.querySelector('.monaco-progress-container:not(.done)');
|
|
64
|
+
if (progress && progress.offsetWidth > 0) {
|
|
65
|
+
status = 'generating';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// latest-assistant-bar가 가장 정확한 상태 표시 (최종 판정)
|
|
69
|
+
const latestBar = auxbar.querySelector('.latest-assistant-bar');
|
|
70
|
+
if (latestBar) {
|
|
71
|
+
const barText = latestBar.textContent.toLowerCase();
|
|
72
|
+
if (barText.includes('completed') || barText.includes('done')) {
|
|
73
|
+
status = 'idle';
|
|
74
|
+
} else if (barText.includes('thinking') || barText.includes('generating') || barText.includes('running') || barText.includes('searching')) {
|
|
75
|
+
status = 'generating';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ─── 3. 승인 대기 모달 ───
|
|
80
|
+
let activeModal = null;
|
|
81
|
+
const dialogs = auxbar.querySelectorAll('[role="dialog"], .monaco-dialog-box, [class*="approval"], [class*="confirm"]');
|
|
82
|
+
if (dialogs.length > 0) {
|
|
83
|
+
const dialog = dialogs[0];
|
|
84
|
+
const buttons = Array.from(dialog.querySelectorAll('button')).map(b => b.textContent.trim()).filter(Boolean);
|
|
85
|
+
if (buttons.length > 0) {
|
|
86
|
+
activeModal = {
|
|
87
|
+
message: dialog.textContent.trim().substring(0, 200),
|
|
88
|
+
buttons: buttons,
|
|
89
|
+
};
|
|
90
|
+
status = 'waiting_approval';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ─── 4. 입력 필드 내용 ───
|
|
95
|
+
const input = auxbar.querySelector('.chat-input-v2-input-box-editable, [contenteditable="true"]');
|
|
96
|
+
const inputContent = input ? input.textContent.trim() : '';
|
|
97
|
+
|
|
98
|
+
// ─── 5. 세션 ID / 타이틀 ───
|
|
99
|
+
const sessionTab = auxbar.querySelector('[class*="session-tab"], [class*="chat-title"]');
|
|
100
|
+
const title = sessionTab ? sessionTab.textContent.trim() : '';
|
|
101
|
+
|
|
102
|
+
return JSON.stringify({
|
|
103
|
+
id: title || 'trae-default',
|
|
104
|
+
status: status,
|
|
105
|
+
messages: messages,
|
|
106
|
+
title: title || undefined,
|
|
107
|
+
inputContent: inputContent || undefined,
|
|
108
|
+
activeModal: activeModal,
|
|
109
|
+
});
|
|
110
|
+
} catch (e) {
|
|
111
|
+
return JSON.stringify({ id: '', status: 'error', messages: [], error: e.message });
|
|
112
|
+
}
|
|
113
|
+
})()
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trae — resolve_action
|
|
3
|
+
*
|
|
4
|
+
* 승인/거부 버튼 찾기 + 좌표 반환.
|
|
5
|
+
* Trae의 approval 다이얼로그는 메인 DOM에 표시됨.
|
|
6
|
+
*
|
|
7
|
+
* 파라미터: ${ BUTTON_TEXT }
|
|
8
|
+
*/
|
|
9
|
+
(() => {
|
|
10
|
+
const want = ${ BUTTON_TEXT };
|
|
11
|
+
const wantNorm = (want || '').replace(/\s+/g, ' ').trim().toLowerCase();
|
|
12
|
+
|
|
13
|
+
function norm(t) { return (t || '').replace(/\s+/g, ' ').trim().toLowerCase(); }
|
|
14
|
+
|
|
15
|
+
function matches(el) {
|
|
16
|
+
const t = norm(el.textContent);
|
|
17
|
+
if (!t || t.length > 80) return false;
|
|
18
|
+
if (t === wantNorm) return true;
|
|
19
|
+
if (t.indexOf(wantNorm) === 0) return true;
|
|
20
|
+
if (wantNorm.indexOf(t) >= 0 && t.length > 2) return true;
|
|
21
|
+
if (/^(run|approve|allow|accept|yes)\b/.test(wantNorm)) {
|
|
22
|
+
if (/^(run|allow|accept|approve)\b/.test(t)) return true;
|
|
23
|
+
}
|
|
24
|
+
if (/^(reject|deny|no|abort)\b/.test(wantNorm)) {
|
|
25
|
+
if (/^(reject|deny)\b/.test(t)) return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const sel = 'button, [role="button"], .monaco-button';
|
|
31
|
+
const allBtns = [...document.querySelectorAll(sel)].filter(b => {
|
|
32
|
+
if (!b.offsetWidth || !b.getBoundingClientRect().height) return false;
|
|
33
|
+
const rect = b.getBoundingClientRect();
|
|
34
|
+
return rect.y > 0 && rect.y < window.innerHeight;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
let found = null;
|
|
38
|
+
for (let i = allBtns.length - 1; i >= 0; i--) {
|
|
39
|
+
if (matches(allBtns[i])) { found = allBtns[i]; break; }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (found) {
|
|
43
|
+
const rect = found.getBoundingClientRect();
|
|
44
|
+
return JSON.stringify({
|
|
45
|
+
found: true,
|
|
46
|
+
text: found.textContent?.trim()?.substring(0, 40),
|
|
47
|
+
x: Math.round(rect.x + rect.width / 2),
|
|
48
|
+
y: Math.round(rect.y + rect.height / 2),
|
|
49
|
+
w: Math.round(rect.width),
|
|
50
|
+
h: Math.round(rect.height)
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return JSON.stringify({ found: false, want: wantNorm });
|
|
54
|
+
})()
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trae — send_message
|
|
3
|
+
*
|
|
4
|
+
* Trae는 .chat-input-v2-input-box-editable (contenteditable / Lexical) 사용.
|
|
5
|
+
* Lexical의 내부 state를 올바르게 업데이트하기 위해 Selection API + execCommand 사용.
|
|
6
|
+
*
|
|
7
|
+
* 파라미터: ${ MESSAGE }
|
|
8
|
+
*/
|
|
9
|
+
(async () => {
|
|
10
|
+
try {
|
|
11
|
+
const msg = ${ MESSAGE };
|
|
12
|
+
|
|
13
|
+
// ─── 1. 입력 필드 찾기 ───
|
|
14
|
+
const editor =
|
|
15
|
+
document.querySelector('.chat-input-v2-input-box-editable') ||
|
|
16
|
+
document.querySelector('[contenteditable="true"][role="textbox"]') ||
|
|
17
|
+
document.querySelector('[data-lexical-editor="true"]');
|
|
18
|
+
|
|
19
|
+
if (!editor) return JSON.stringify({ sent: false, error: 'no input found' });
|
|
20
|
+
|
|
21
|
+
// ─── 2. 포커스 + 전체 선택 + 삭제 + 삽입 ───
|
|
22
|
+
editor.focus();
|
|
23
|
+
await new Promise(r => setTimeout(r, 100));
|
|
24
|
+
|
|
25
|
+
// Selection API로 전체 선택
|
|
26
|
+
const sel = window.getSelection();
|
|
27
|
+
const range = document.createRange();
|
|
28
|
+
range.selectNodeContents(editor);
|
|
29
|
+
sel.removeAllRanges();
|
|
30
|
+
sel.addRange(range);
|
|
31
|
+
await new Promise(r => setTimeout(r, 50));
|
|
32
|
+
|
|
33
|
+
// 삭제 후 삽입 (Lexical state 동기화)
|
|
34
|
+
document.execCommand('delete', false, null);
|
|
35
|
+
await new Promise(r => setTimeout(r, 50));
|
|
36
|
+
document.execCommand('insertText', false, msg);
|
|
37
|
+
|
|
38
|
+
// Input 이벤트
|
|
39
|
+
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
|
40
|
+
await new Promise(r => setTimeout(r, 500));
|
|
41
|
+
|
|
42
|
+
// ─── 3. send 버튼 클릭 ───
|
|
43
|
+
const sendBtn = document.querySelector('.chat-input-v2-send-button');
|
|
44
|
+
if (sendBtn && !sendBtn.disabled) {
|
|
45
|
+
sendBtn.click();
|
|
46
|
+
return JSON.stringify({ sent: true, method: 'button' });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 버튼이 아직 disabled이면 Enter 키 시도
|
|
50
|
+
const enterOpts = {
|
|
51
|
+
key: 'Enter', code: 'Enter',
|
|
52
|
+
keyCode: 13, which: 13,
|
|
53
|
+
bubbles: true, cancelable: true, composed: true,
|
|
54
|
+
};
|
|
55
|
+
editor.dispatchEvent(new KeyboardEvent('keydown', enterOpts));
|
|
56
|
+
await new Promise(r => setTimeout(r, 50));
|
|
57
|
+
editor.dispatchEvent(new KeyboardEvent('keypress', enterOpts));
|
|
58
|
+
editor.dispatchEvent(new KeyboardEvent('keyup', enterOpts));
|
|
59
|
+
|
|
60
|
+
// 여전히 안 되면 needsTypeAndSend 폴백
|
|
61
|
+
return JSON.stringify({
|
|
62
|
+
sent: false,
|
|
63
|
+
needsTypeAndSend: true,
|
|
64
|
+
selector: '.chat-input-v2-input-box-editable',
|
|
65
|
+
});
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return JSON.stringify({ sent: false, error: e.message });
|
|
68
|
+
}
|
|
69
|
+
})()
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
})()
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
})()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trae — switch_session
|
|
3
|
+
*
|
|
4
|
+
* Trae 세션 탭 전환.
|
|
5
|
+
* 파라미터: ${ SESSION_ID }
|
|
6
|
+
*/
|
|
7
|
+
(() => {
|
|
8
|
+
try {
|
|
9
|
+
const targetId = ${ SESSION_ID };
|
|
10
|
+
const tabs = document.querySelectorAll('.chat-tab-header, [class*="tab-item"], [class*="TabItem"]');
|
|
11
|
+
const idx = parseInt(targetId, 10);
|
|
12
|
+
|
|
13
|
+
if (isNaN(idx) || idx < 0 || idx >= tabs.length) {
|
|
14
|
+
return JSON.stringify({ switched: false, error: `invalid index: ${targetId}` });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
tabs[idx].click();
|
|
18
|
+
const title = (tabs[idx].textContent || '').replace('✕', '').trim();
|
|
19
|
+
return JSON.stringify({ switched: true, title });
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return JSON.stringify({ switched: false, error: e.message });
|
|
22
|
+
}
|
|
23
|
+
})()
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDP Scripts for Trae
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const SCRIPTS_DIR = path.join(__dirname, 'scripts');
|
|
8
|
+
function loadScript(name) {
|
|
9
|
+
try { return fs.readFileSync(path.join(SCRIPTS_DIR, name), 'utf8'); }
|
|
10
|
+
catch { return null; }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
module.exports.readChat = function readChat() { return loadScript('read_chat.js'); };
|
|
15
|
+
|
|
16
|
+
module.exports.sendMessage = function sendMessage(text) {
|
|
17
|
+
const s = loadScript('send_message.js');
|
|
18
|
+
return s ? s.replace(/\$\{\s*MESSAGE\s*\}/g, JSON.stringify(text)) : null;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
module.exports.resolveAction = function resolveAction(params) {
|
|
22
|
+
const action = typeof params === 'string' ? params : params?.action || 'approve';
|
|
23
|
+
const buttonText = params?.button || params?.buttonText
|
|
24
|
+
|| (action === 'approve' ? 'Accept' : action === 'reject' ? 'Reject' : action);
|
|
25
|
+
const s = loadScript('resolve_action.js');
|
|
26
|
+
return s ? s.replace(/\$\{\s*BUTTON_TEXT\s*\}/g, JSON.stringify(buttonText)) : null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
module.exports.openPanel = function openPanel() { return loadScript('open_panel.js'); };
|
|
30
|
+
|
|
31
|
+
module.exports.focusEditor = function focusEditor() { return loadScript('focus_editor.js'); };
|
|
32
|
+
|
|
33
|
+
module.exports.newSession = function newSession() { return loadScript('new_session.js'); };
|
|
34
|
+
|
|
35
|
+
module.exports.listSessions = function listSessions() { return loadScript('list_chats.js'); };
|
|
36
|
+
|
|
37
|
+
module.exports.switchSession = function switchSession(sessionId) {
|
|
38
|
+
const s = loadScript('switch_session.js');
|
|
39
|
+
return s ? s.replace(/\$\{\s*SESSION_ID\s*\}/g, JSON.stringify(sessionId)) : null;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
module.exports.listModels = function listModels() { return loadScript('list_models.js'); };
|
|
43
|
+
|
|
44
|
+
module.exports.setModel = function setModel(params) {
|
|
45
|
+
const model = typeof params === 'string' ? params : params?.model;
|
|
46
|
+
const s = loadScript('set_model.js');
|
|
47
|
+
return s ? s.replace(/\$\{\s*MODEL\s*\}/g, JSON.stringify(model)) : null;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
module.exports.listModes = function listModes() { return loadScript('list_modes.js'); };
|
|
51
|
+
|
|
52
|
+
module.exports.setMode = function setMode(params) {
|
|
53
|
+
const mode = typeof params === 'string' ? params : params?.mode;
|
|
54
|
+
const s = loadScript('set_mode.js');
|
|
55
|
+
return s ? s.replace(/\$\{\s*MODE\s*\}/g, JSON.stringify(mode)) : null;
|
|
56
|
+
};
|
|
57
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "vscode",
|
|
3
|
+
"name": "Visual Studio Code",
|
|
4
|
+
"category": "ide",
|
|
5
|
+
"displayName": "VS Code",
|
|
6
|
+
"icon": "💙",
|
|
7
|
+
"cli": "code",
|
|
8
|
+
"cdpPorts": [
|
|
9
|
+
9339,
|
|
10
|
+
9340
|
|
11
|
+
],
|
|
12
|
+
"targetFilter": {
|
|
13
|
+
"urlIncludes": "workbench.html",
|
|
14
|
+
"urlExcludes": [
|
|
15
|
+
"agent"
|
|
16
|
+
],
|
|
17
|
+
"titleExcludes": "extension-output|ADHDev CDP|Debug Console|Output\\s*$|Launchpad"
|
|
18
|
+
},
|
|
19
|
+
"processNames": {
|
|
20
|
+
"darwin": "Visual Studio Code",
|
|
21
|
+
"win32": [
|
|
22
|
+
"Code.exe"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"paths": {
|
|
26
|
+
"darwin": [
|
|
27
|
+
"/Applications/Visual Studio Code.app"
|
|
28
|
+
],
|
|
29
|
+
"win32": [
|
|
30
|
+
"C:\\Program Files\\Microsoft VS Code\\Code.exe",
|
|
31
|
+
"C:\\Users\\*\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe"
|
|
32
|
+
],
|
|
33
|
+
"linux": [
|
|
34
|
+
"/usr/share/code",
|
|
35
|
+
"/snap/code/current"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"inputMethod": "cdp-type-and-send",
|
|
39
|
+
"inputSelector": "[contenteditable=\"true\"][role=\"textbox\"]",
|
|
40
|
+
"settings": {
|
|
41
|
+
"approvalAlert": {
|
|
42
|
+
"type": "boolean",
|
|
43
|
+
"default": true,
|
|
44
|
+
"public": true,
|
|
45
|
+
"label": "Approval Notifications",
|
|
46
|
+
"description": "Show notification when approval is needed"
|
|
47
|
+
},
|
|
48
|
+
"longGeneratingAlert": {
|
|
49
|
+
"type": "boolean",
|
|
50
|
+
"default": true,
|
|
51
|
+
"public": true,
|
|
52
|
+
"label": "Long Generation Alert",
|
|
53
|
+
"description": "Alert when generation takes too long"
|
|
54
|
+
},
|
|
55
|
+
"longGeneratingThresholdSec": {
|
|
56
|
+
"type": "number",
|
|
57
|
+
"default": 180,
|
|
58
|
+
"public": true,
|
|
59
|
+
"label": "Long Generation Threshold (sec)",
|
|
60
|
+
"min": 30,
|
|
61
|
+
"max": 600
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "vscode-insiders",
|
|
3
|
+
"name": "Visual Studio Code - Insiders",
|
|
4
|
+
"category": "ide",
|
|
5
|
+
"displayName": "VS Code Insiders",
|
|
6
|
+
"icon": "💚",
|
|
7
|
+
"cli": "code-insiders",
|
|
8
|
+
"cdpPorts": [
|
|
9
|
+
9341,
|
|
10
|
+
9342
|
|
11
|
+
],
|
|
12
|
+
"targetFilter": {
|
|
13
|
+
"urlIncludes": "workbench.html",
|
|
14
|
+
"urlExcludes": [
|
|
15
|
+
"agent"
|
|
16
|
+
],
|
|
17
|
+
"titleExcludes": "extension-output|ADHDev CDP|Debug Console|Output\\s*$|Launchpad"
|
|
18
|
+
},
|
|
19
|
+
"processNames": {
|
|
20
|
+
"darwin": "Visual Studio Code - Insiders",
|
|
21
|
+
"win32": [
|
|
22
|
+
"Code - Insiders.exe"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"paths": {
|
|
26
|
+
"darwin": [
|
|
27
|
+
"/Applications/Visual Studio Code - Insiders.app"
|
|
28
|
+
],
|
|
29
|
+
"win32": [
|
|
30
|
+
"C:\\Program Files\\Microsoft VS Code Insiders\\Code - Insiders.exe"
|
|
31
|
+
],
|
|
32
|
+
"linux": [
|
|
33
|
+
"/usr/share/code-insiders"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"inputMethod": "cdp-type-and-send",
|
|
37
|
+
"inputSelector": "[contenteditable=\"true\"][role=\"textbox\"]",
|
|
38
|
+
"settings": {
|
|
39
|
+
"approvalAlert": {
|
|
40
|
+
"type": "boolean",
|
|
41
|
+
"default": true,
|
|
42
|
+
"public": true,
|
|
43
|
+
"label": "Approval Notifications",
|
|
44
|
+
"description": "Show notification when approval is needed"
|
|
45
|
+
},
|
|
46
|
+
"longGeneratingAlert": {
|
|
47
|
+
"type": "boolean",
|
|
48
|
+
"default": true,
|
|
49
|
+
"public": true,
|
|
50
|
+
"label": "Long Generation Alert",
|
|
51
|
+
"description": "Alert when generation takes too long"
|
|
52
|
+
},
|
|
53
|
+
"longGeneratingThresholdSec": {
|
|
54
|
+
"type": "number",
|
|
55
|
+
"default": 180,
|
|
56
|
+
"public": true,
|
|
57
|
+
"label": "Long Generation Threshold (sec)",
|
|
58
|
+
"min": 30,
|
|
59
|
+
"max": 600
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "vscodium",
|
|
3
|
+
"name": "VSCodium",
|
|
4
|
+
"category": "ide",
|
|
5
|
+
"displayName": "VSCodium",
|
|
6
|
+
"icon": "💚",
|
|
7
|
+
"cli": "codium",
|
|
8
|
+
"cdpPorts": [
|
|
9
|
+
9343,
|
|
10
|
+
9344
|
|
11
|
+
],
|
|
12
|
+
"targetFilter": {
|
|
13
|
+
"urlIncludes": "workbench.html",
|
|
14
|
+
"urlExcludes": [
|
|
15
|
+
"agent"
|
|
16
|
+
],
|
|
17
|
+
"titleExcludes": "extension-output|ADHDev CDP|Debug Console|Output\\s*$|Launchpad"
|
|
18
|
+
},
|
|
19
|
+
"processNames": {
|
|
20
|
+
"darwin": "VSCodium",
|
|
21
|
+
"win32": [
|
|
22
|
+
"VSCodium.exe"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"paths": {
|
|
26
|
+
"darwin": [
|
|
27
|
+
"/Applications/VSCodium.app"
|
|
28
|
+
],
|
|
29
|
+
"win32": [
|
|
30
|
+
"C:\\Program Files\\VSCodium\\VSCodium.exe"
|
|
31
|
+
],
|
|
32
|
+
"linux": [
|
|
33
|
+
"/usr/share/codium",
|
|
34
|
+
"/snap/codium/current"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"inputMethod": "cdp-type-and-send",
|
|
38
|
+
"inputSelector": "[contenteditable=\"true\"][role=\"textbox\"]",
|
|
39
|
+
"settings": {
|
|
40
|
+
"approvalAlert": {
|
|
41
|
+
"type": "boolean",
|
|
42
|
+
"default": true,
|
|
43
|
+
"public": true,
|
|
44
|
+
"label": "Approval Notifications",
|
|
45
|
+
"description": "Show notification when approval is needed"
|
|
46
|
+
},
|
|
47
|
+
"longGeneratingAlert": {
|
|
48
|
+
"type": "boolean",
|
|
49
|
+
"default": true,
|
|
50
|
+
"public": true,
|
|
51
|
+
"label": "Long Generation Alert",
|
|
52
|
+
"description": "Alert when generation takes too long"
|
|
53
|
+
},
|
|
54
|
+
"longGeneratingThresholdSec": {
|
|
55
|
+
"type": "number",
|
|
56
|
+
"default": 180,
|
|
57
|
+
"public": true,
|
|
58
|
+
"label": "Long Generation Threshold (sec)",
|
|
59
|
+
"min": 30,
|
|
60
|
+
"max": 600
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "windsurf",
|
|
3
|
+
"name": "Windsurf",
|
|
4
|
+
"category": "ide",
|
|
5
|
+
"displayName": "Windsurf",
|
|
6
|
+
"icon": "🏄",
|
|
7
|
+
"cli": "windsurf",
|
|
8
|
+
"cdpPorts": [
|
|
9
|
+
9337,
|
|
10
|
+
9338
|
|
11
|
+
],
|
|
12
|
+
"targetFilter": {
|
|
13
|
+
"urlIncludes": "workbench.html",
|
|
14
|
+
"urlExcludes": [
|
|
15
|
+
"agent"
|
|
16
|
+
],
|
|
17
|
+
"titleExcludes": "extension-output|ADHDev CDP|Debug Console|Output\\s*$|Launchpad"
|
|
18
|
+
},
|
|
19
|
+
"processNames": {
|
|
20
|
+
"darwin": "Windsurf"
|
|
21
|
+
},
|
|
22
|
+
"paths": {
|
|
23
|
+
"darwin": [
|
|
24
|
+
"/Applications/Windsurf.app"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"inputMethod": "cdp-type-and-send",
|
|
28
|
+
"inputSelector": "[contenteditable=\"true\"][role=\"textbox\"]",
|
|
29
|
+
"settings": {
|
|
30
|
+
"approvalAlert": {
|
|
31
|
+
"type": "boolean",
|
|
32
|
+
"default": true,
|
|
33
|
+
"public": true,
|
|
34
|
+
"label": "Approval Notifications",
|
|
35
|
+
"description": "Show notification when approval is needed"
|
|
36
|
+
},
|
|
37
|
+
"longGeneratingAlert": {
|
|
38
|
+
"type": "boolean",
|
|
39
|
+
"default": true,
|
|
40
|
+
"public": true,
|
|
41
|
+
"label": "Long Generation Alert",
|
|
42
|
+
"description": "Alert when generation takes too long"
|
|
43
|
+
},
|
|
44
|
+
"longGeneratingThresholdSec": {
|
|
45
|
+
"type": "number",
|
|
46
|
+
"default": 180,
|
|
47
|
+
"public": true,
|
|
48
|
+
"label": "Long Generation Threshold (sec)",
|
|
49
|
+
"min": 30,
|
|
50
|
+
"max": 600
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windsurf v1 — focus_editor
|
|
3
|
+
*
|
|
4
|
+
* Cascade(채팅) 입력창에 포커스를 맞춥니다.
|
|
5
|
+
* Windsurf는 VS Code 포크로, 채팅 UI를 "Cascade"라고 부릅니다.
|
|
6
|
+
*
|
|
7
|
+
* DOM 구조:
|
|
8
|
+
* #windsurf.cascadePanel → .chat-client-root
|
|
9
|
+
* 입력: [contenteditable="true"][role="textbox"]
|
|
10
|
+
* 또는 textarea (미로그인)
|
|
11
|
+
*
|
|
12
|
+
* 최종 확인: Windsurf (2026-03-06)
|
|
13
|
+
*/
|
|
14
|
+
(() => {
|
|
15
|
+
try {
|
|
16
|
+
const editor =
|
|
17
|
+
document.querySelector('[contenteditable="true"][role="textbox"]') ||
|
|
18
|
+
document.querySelector('[data-lexical-editor="true"]') ||
|
|
19
|
+
document.querySelector('.chat-input textarea') ||
|
|
20
|
+
document.querySelector('.cascade-input [contenteditable="true"]') ||
|
|
21
|
+
document.querySelector('textarea:not(.xterm-helper-textarea)');
|
|
22
|
+
if (editor) {
|
|
23
|
+
editor.focus();
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
} catch (e) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
})()
|