@adhdev/daemon-core 0.6.35 → 0.6.37
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 +2 -1
- package/dist/index.js +112 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/providers/_builtin/acp/codex-cli/provider.json +2 -2
- package/providers/_builtin/cli/codex-cli/provider.json +8 -18
- package/providers/_builtin/ide/antigravity/provider.json +2 -3
- package/providers/_builtin/ide/cursor/provider.json +2 -2
- package/providers/_builtin/ide/cursor/scripts/{0.49 → 1.0}/read_chat.js +1 -1
- package/providers/_builtin/ide/cursor/scripts/{0.49 → 1.0}/resolve_action.js +1 -1
- package/providers/_builtin/ide/windsurf/scripts/1.0/focus_editor.js +16 -10
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_chats.js +9 -103
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_models.js +43 -26
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_modes.js +51 -27
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_sessions.js +79 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0/new_session.js +30 -41
- package/providers/_builtin/ide/windsurf/scripts/1.0/open_panel.js +44 -35
- package/providers/_builtin/ide/windsurf/scripts/1.0/read_chat.js +211 -273
- package/providers/_builtin/ide/windsurf/scripts/1.0/resolve_action.js +64 -50
- package/providers/_builtin/ide/windsurf/scripts/1.0/send_message.js +14 -81
- package/providers/_builtin/ide/windsurf/scripts/1.0/set_mode.js +34 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0/set_model.js +40 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0/switch_session.js +66 -42
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/focus_editor.js +30 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_chats.js +117 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_models.js +39 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_modes.js +39 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/new_session.js +69 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/open_panel.js +58 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/read_chat.js +315 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/resolve_action.js +68 -0
- package/providers/_builtin/ide/{cursor/scripts/0.49 → windsurf/scripts/1.0.bak}/scripts.js +27 -23
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/send_message.js +87 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_mode.js +15 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_model.js +15 -0
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/switch_session.js +58 -0
- package/providers/_builtin/registry.json +5 -9
- package/src/cdp/manager.ts +38 -12
- package/src/commands/handler.ts +1 -8
- package/src/daemon/dev-server.ts +66 -8
- package/src/detection/ide-detector.ts +0 -3
- package/src/providers/provider-loader.ts +4 -2
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_models.js +0 -38
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_modes.js +0 -48
- package/providers/_builtin/ide/antigravity/scripts/1.106/read_chat.js +0 -290
- package/providers/_builtin/ide/antigravity/scripts/1.106/scripts.js +0 -57
- package/providers/_builtin/ide/antigravity/scripts/1.106/set_mode.js +0 -34
- package/providers/_builtin/ide/antigravity/scripts/1.106/set_model.js +0 -47
- package/providers/_builtin/ide/antigravity/scripts/1.107/focus_editor.js +0 -20
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_chats.js +0 -137
- package/providers/_builtin/ide/antigravity/scripts/1.107/new_session.js +0 -75
- package/providers/_builtin/ide/antigravity/scripts/1.107/resolve_action.js +0 -63
- package/providers/_builtin/ide/antigravity/scripts/1.107/send_message.js +0 -56
- package/providers/_builtin/ide/antigravity/scripts/1.107/switch_session.js +0 -114
- package/providers/_builtin/ide/cursor/scripts/0.49/dismiss_notification.js +0 -30
- package/providers/_builtin/ide/cursor/scripts/0.49/focus_editor.js +0 -13
- package/providers/_builtin/ide/cursor/scripts/0.49/list_models.js +0 -78
- package/providers/_builtin/ide/cursor/scripts/0.49/list_modes.js +0 -40
- package/providers/_builtin/ide/cursor/scripts/0.49/list_notifications.js +0 -23
- package/providers/_builtin/ide/cursor/scripts/0.49/new_session.js +0 -20
- package/providers/_builtin/ide/cursor/scripts/0.49/open_panel.js +0 -23
- package/providers/_builtin/ide/cursor/scripts/0.49/send_message.js +0 -23
- package/providers/_builtin/ide/cursor/scripts/0.49/set_mode.js +0 -38
- package/providers/_builtin/ide/cursor/scripts/0.49/set_model.js +0 -81
- package/providers/_builtin/ide/cursor/scripts/0.49/switch_session.js +0 -28
- package/providers/_builtin/ide/cursor/scripts/0.49.bak/list_sessions.js +0 -42
- package/providers/_builtin/ide/cursor/scripts/0.49.bak/read_chat.js +0 -79
- package/providers/_builtin/ide/cursor/scripts/0.49.bak/resolve_action.js +0 -19
- /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/focus_editor.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/list_chats.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/list_models.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/list_modes.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/new_session.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/read_chat.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/resolve_action.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/scripts.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/send_message.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/set_mode.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/set_model.js +0 -0
- /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/switch_session.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/dismiss_notification.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/focus_editor.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/list_models.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/list_modes.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/list_notifications.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49 → 1.0}/list_sessions.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/new_session.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/open_panel.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/scripts.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/send_message.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/set_mode.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/set_model.js +0 -0
- /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/switch_session.js +0 -0
package/package.json
CHANGED
|
@@ -57,33 +57,23 @@
|
|
|
57
57
|
"binary": "codex",
|
|
58
58
|
"spawn": {
|
|
59
59
|
"command": "codex",
|
|
60
|
-
"args": [
|
|
61
|
-
"--full-auto"
|
|
62
|
-
],
|
|
60
|
+
"args": [],
|
|
63
61
|
"shell": false,
|
|
64
62
|
"env": {}
|
|
65
63
|
},
|
|
66
64
|
"patterns": {
|
|
67
65
|
"prompt": [
|
|
68
|
-
{},
|
|
69
|
-
{}
|
|
70
|
-
{}
|
|
66
|
+
{ "source": "To get started, describe a task or try one of these commands", "flags": "i" },
|
|
67
|
+
{ "source": "^>\\s*$", "flags": "m" }
|
|
71
68
|
],
|
|
72
69
|
"generating": [
|
|
73
|
-
{}
|
|
74
|
-
{},
|
|
75
|
-
{}
|
|
70
|
+
{ "source": "Working \\(\\d+s", "flags": "i" }
|
|
76
71
|
],
|
|
77
72
|
"approval": [
|
|
78
|
-
{},
|
|
79
|
-
{},
|
|
80
|
-
{}
|
|
81
|
-
{},
|
|
82
|
-
{}
|
|
73
|
+
{ "source": "Always approve this session", "flags": "i" },
|
|
74
|
+
{ "source": "Approve and run now", "flags": "i" },
|
|
75
|
+
{ "source": "Allow command\\?", "flags": "i" }
|
|
83
76
|
],
|
|
84
|
-
"ready": [
|
|
85
|
-
{},
|
|
86
|
-
{}
|
|
87
|
-
]
|
|
77
|
+
"ready": []
|
|
88
78
|
}
|
|
89
79
|
}
|
|
@@ -37,10 +37,9 @@
|
|
|
37
37
|
"versionCommand": "antigravity --version",
|
|
38
38
|
"providerVersion": "1.0.0",
|
|
39
39
|
"compatibility": [
|
|
40
|
-
{ "ideVersion": ">=1.
|
|
41
|
-
{ "ideVersion": ">=1.105.0", "scriptDir": "scripts/1.106" }
|
|
40
|
+
{ "ideVersion": ">=1.0.0", "scriptDir": "scripts/1.0" }
|
|
42
41
|
],
|
|
43
|
-
"defaultScriptDir": "scripts/1.
|
|
42
|
+
"defaultScriptDir": "scripts/1.0",
|
|
44
43
|
"settings": {
|
|
45
44
|
"approvalAlert": {
|
|
46
45
|
"type": "boolean",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"versionCommand": "cursor --version",
|
|
38
38
|
"providerVersion": "1.0.0",
|
|
39
39
|
"compatibility": [
|
|
40
|
-
{ "ideVersion": ">=0.
|
|
40
|
+
{ "ideVersion": ">=1.0.0", "scriptDir": "scripts/1.0" }
|
|
41
41
|
],
|
|
42
|
-
"defaultScriptDir": "scripts/0
|
|
42
|
+
"defaultScriptDir": "scripts/1.0",
|
|
43
43
|
"vscodeCommands": {
|
|
44
44
|
"changeModel": "cursor.model"
|
|
45
45
|
},
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
const rawStatus = c?.getAttribute('data-composer-status') || 'idle';
|
|
22
22
|
let status = rawStatus;
|
|
23
23
|
if (rawStatus === 'thinking' || rawStatus === 'streaming') status = 'generating';
|
|
24
|
-
else if (rawStatus === 'completed' || rawStatus === 'idle' || !rawStatus) status = 'idle';
|
|
24
|
+
else if (rawStatus === 'completed' || rawStatus === 'cancelled' || rawStatus === 'idle' || !rawStatus) status = 'idle';
|
|
25
25
|
|
|
26
26
|
// ─── Approval Detection ───
|
|
27
27
|
let activeModal = null;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
(params) => {
|
|
12
12
|
try {
|
|
13
13
|
const btns = [...document.querySelectorAll('button, [role="button"], .cursor-pointer')].filter(b => b.offsetWidth > 0);
|
|
14
|
-
const searchText = (params.buttonText || '').toLowerCase();
|
|
14
|
+
const searchText = (params.buttonText || params.action || params.button || '').toLowerCase();
|
|
15
15
|
const target = btns.find(b => (b.textContent||'').trim().replace(/[⏎↵]/g, '').trim().toLowerCase().includes(searchText));
|
|
16
16
|
if (target) { target.click(); return JSON.stringify({ resolved: true, clicked: target.textContent.trim() }); }
|
|
17
17
|
return JSON.stringify({ resolved: false, available: btns.map(b => b.textContent.trim()).filter(Boolean).slice(0, 15) });
|
|
@@ -13,18 +13,24 @@
|
|
|
13
13
|
*/
|
|
14
14
|
(() => {
|
|
15
15
|
try {
|
|
16
|
+
const cascade = document.querySelector('#windsurf\\.cascadePanel') || document.querySelector('.chat-client-root');
|
|
17
|
+
const root = cascade || document;
|
|
16
18
|
const editor =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return
|
|
19
|
+
root.querySelector('[data-lexical-editor="true"]') ||
|
|
20
|
+
root.querySelector('[contenteditable="true"][role="textbox"]') ||
|
|
21
|
+
root.querySelector('.chat-input textarea') ||
|
|
22
|
+
root.querySelector('.cascade-input [contenteditable="true"]') ||
|
|
23
|
+
root.querySelector('textarea:not(.xterm-helper-textarea)');
|
|
24
|
+
|
|
25
|
+
if (!editor) {
|
|
26
|
+
return JSON.stringify({ focused: false });
|
|
25
27
|
}
|
|
26
|
-
|
|
28
|
+
|
|
29
|
+
editor.focus();
|
|
30
|
+
if (typeof editor.click === 'function') editor.click();
|
|
31
|
+
|
|
32
|
+
return JSON.stringify({ focused: document.activeElement === editor || editor.contains?.(document.activeElement) || true });
|
|
27
33
|
} catch (e) {
|
|
28
|
-
return false;
|
|
34
|
+
return JSON.stringify({ focused: false, error: e.message });
|
|
29
35
|
}
|
|
30
36
|
})()
|
|
@@ -9,109 +9,15 @@
|
|
|
9
9
|
*/
|
|
10
10
|
(async () => {
|
|
11
11
|
try {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
(sidebar && sidebar.offsetWidth > 0 && cascade);
|
|
21
|
-
|
|
22
|
-
if (!panelVisible) {
|
|
23
|
-
// Toggle 버튼 클릭 시도
|
|
24
|
-
const toggleBtns = Array.from(document.querySelectorAll('li.action-item a, button, [role="button"]'));
|
|
25
|
-
let toggled = false;
|
|
26
|
-
for (const btn of toggleBtns) {
|
|
27
|
-
const label = (btn.getAttribute('aria-label') || '').toLowerCase();
|
|
28
|
-
if (label.includes('toggle cascade') || label.includes('toggle secondary') ||
|
|
29
|
-
label.includes('toggle auxiliary') || label.includes('cascade')) {
|
|
30
|
-
if (btn.offsetWidth > 0 || btn.offsetHeight > 0) {
|
|
31
|
-
btn.click();
|
|
32
|
-
toggled = true;
|
|
33
|
-
break;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
// 버튼 없으면 Cmd+L
|
|
38
|
-
if (!toggled) {
|
|
39
|
-
document.dispatchEvent(new KeyboardEvent('keydown', {
|
|
40
|
-
key: 'l', code: 'KeyL', keyCode: 76,
|
|
41
|
-
metaKey: true, ctrlKey: false,
|
|
42
|
-
bubbles: true, cancelable: true,
|
|
43
|
-
}));
|
|
44
|
-
document.dispatchEvent(new KeyboardEvent('keyup', {
|
|
45
|
-
key: 'l', code: 'KeyL', keyCode: 76,
|
|
46
|
-
metaKey: true, ctrlKey: false,
|
|
47
|
-
bubbles: true, cancelable: true,
|
|
48
|
-
}));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// 패널 렌더링 대기 (최대 3초)
|
|
52
|
-
for (let i = 0; i < 30; i++) {
|
|
53
|
-
await new Promise(r => setTimeout(r, 100));
|
|
54
|
-
tabs = document.querySelectorAll('[id^="cascade-tab-"]');
|
|
55
|
-
if (tabs.length > 0) break;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ─── 2. 탭 정보 수집 ───
|
|
61
|
-
tabs = document.querySelectorAll('[id^="cascade-tab-"]');
|
|
62
|
-
if (tabs.length === 0) return [];
|
|
63
|
-
|
|
64
|
-
const result = [];
|
|
65
|
-
const seen = new Set();
|
|
66
|
-
|
|
67
|
-
tabs.forEach(tab => {
|
|
68
|
-
const tabId = tab.id.replace('cascade-tab-', '');
|
|
69
|
-
if (seen.has(tabId)) return;
|
|
70
|
-
seen.add(tabId);
|
|
71
|
-
|
|
72
|
-
let title = '';
|
|
73
|
-
let cascadeId = tabId;
|
|
74
|
-
let status = 'completed';
|
|
75
|
-
|
|
76
|
-
// React Fiber에서 제목 추출
|
|
77
|
-
const fk = Object.keys(tab).find(k => k.startsWith('__reactFiber'));
|
|
78
|
-
if (fk) {
|
|
79
|
-
let fiber = tab[fk];
|
|
80
|
-
for (let d = 0; d < 30 && fiber; d++) {
|
|
81
|
-
const p = fiber.memoizedProps;
|
|
82
|
-
if (p) {
|
|
83
|
-
if (p.title && typeof p.title === 'string') {
|
|
84
|
-
title = p.title;
|
|
85
|
-
}
|
|
86
|
-
if (p.cascadeId) {
|
|
87
|
-
cascadeId = p.cascadeId;
|
|
88
|
-
}
|
|
89
|
-
if (p.status && typeof p.status === 'string') {
|
|
90
|
-
status = p.status;
|
|
91
|
-
}
|
|
92
|
-
if (title) break;
|
|
93
|
-
}
|
|
94
|
-
fiber = fiber.return;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// DOM 폴백
|
|
99
|
-
if (!title) {
|
|
100
|
-
title = tab.textContent?.trim().substring(0, 100) || ('Chat ' + (result.length + 1));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const isVisible = tab.offsetHeight > 0 && tab.offsetWidth > 0;
|
|
104
|
-
|
|
105
|
-
result.push({
|
|
106
|
-
id: tabId,
|
|
107
|
-
title: title.substring(0, 100),
|
|
108
|
-
status: status,
|
|
109
|
-
active: isVisible
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
return result;
|
|
12
|
+
const tabs = Array.from(document.querySelectorAll('[id^="cascade-tab-"]')).filter(el => el.offsetWidth > 0 && el.offsetHeight > 0);
|
|
13
|
+
const sessions = tabs.map((tab, index) => ({
|
|
14
|
+
id: tab.id.replace(/^cascade-tab-/, ''),
|
|
15
|
+
title: (tab.textContent || '').replace(/\s+/g, ' ').trim() || `Chat ${index + 1}`,
|
|
16
|
+
active: /bg-ide-tab-active-background-color/.test(tab.innerHTML || ''),
|
|
17
|
+
index,
|
|
18
|
+
}));
|
|
19
|
+
return JSON.stringify({ sessions });
|
|
114
20
|
} catch (e) {
|
|
115
|
-
return [];
|
|
21
|
+
return JSON.stringify({ sessions: [], error: e.message });
|
|
116
22
|
}
|
|
117
23
|
})()
|
|
@@ -1,38 +1,55 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generic fallback — list_models
|
|
3
3
|
*/
|
|
4
|
-
(() => {
|
|
4
|
+
(async () => {
|
|
5
5
|
try {
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
7
|
+
const cascade = document.querySelector('#windsurf\\.cascadePanel') || document.querySelector('.chat-client-root');
|
|
8
|
+
if (!cascade) {
|
|
9
|
+
return JSON.stringify({ models: [], current: '' });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const normalize = (text) => (text || '').replace(/\s+/g, ' ').trim();
|
|
13
|
+
const modelRegex = /(claude|gpt|gemini|sonnet|opus|swe|deepseek|qwen|grok|o1|o3|codex)/i;
|
|
14
|
+
const getCurrentButton = () => {
|
|
15
|
+
const buttons = Array.from(cascade.querySelectorAll('button')).filter(el => el.offsetWidth > 0 && el.offsetHeight > 0);
|
|
16
|
+
const composerButtons = buttons.filter(el => el.getBoundingClientRect().y > window.innerHeight - 90);
|
|
17
|
+
return composerButtons.find(el => {
|
|
18
|
+
const text = normalize(el.innerText || el.textContent);
|
|
19
|
+
return text && text.length <= 60 && modelRegex.test(text) && !/run|skip|accept|reject/i.test(text);
|
|
20
|
+
}) || null;
|
|
21
|
+
};
|
|
22
|
+
const getMenuButtons = () => Array.from(document.querySelectorAll('button')).filter(el => {
|
|
23
|
+
if (!(el.offsetWidth > 0 && el.offsetHeight > 0)) return false;
|
|
24
|
+
const rect = el.getBoundingClientRect();
|
|
25
|
+
const text = normalize(el.innerText || el.textContent);
|
|
26
|
+
return rect.width >= 180 && rect.height >= 20 && rect.x > window.innerWidth - 320 && modelRegex.test(text);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const currentButton = getCurrentButton();
|
|
30
|
+
const current = currentButton ? normalize(currentButton.innerText || currentButton.textContent) : '';
|
|
31
|
+
const wasOpen = getMenuButtons().length > 0;
|
|
8
32
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const txt = (el.textContent || '').trim();
|
|
13
|
-
if (txt && /claude|gpt|gemini|sonnet|opus/i.test(txt)) {
|
|
14
|
-
if (txt.length < 50) {
|
|
15
|
-
models.push(txt);
|
|
16
|
-
if (!current) current = txt;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
33
|
+
if (!wasOpen && currentButton) {
|
|
34
|
+
currentButton.click();
|
|
35
|
+
await wait(250);
|
|
19
36
|
}
|
|
20
37
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
38
|
+
const models = getMenuButtons().map(el => normalize(el.innerText || el.textContent)).filter(Boolean);
|
|
39
|
+
const unique = [];
|
|
40
|
+
const seen = new Set();
|
|
41
|
+
for (const name of models) {
|
|
42
|
+
const key = name.toLowerCase();
|
|
43
|
+
if (seen.has(key)) continue;
|
|
44
|
+
seen.add(key);
|
|
45
|
+
unique.push({ name, id: key.replace(/[^a-z0-9]+/g, '-') });
|
|
30
46
|
}
|
|
31
47
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
if (!wasOpen) {
|
|
49
|
+
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', keyCode: 27, which: 27, bubbles: true, cancelable: true }));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return JSON.stringify({ models: unique, current });
|
|
36
53
|
} catch (e) {
|
|
37
54
|
return JSON.stringify({ models: [], current: '', error: e.message });
|
|
38
55
|
}
|
|
@@ -1,39 +1,63 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generic fallback — list_models
|
|
3
3
|
*/
|
|
4
|
-
(() => {
|
|
4
|
+
(async () => {
|
|
5
5
|
try {
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
7
|
+
const cascade = document.querySelector('#windsurf\\.cascadePanel') || document.querySelector('.chat-client-root');
|
|
8
|
+
if (!cascade) {
|
|
9
|
+
return JSON.stringify({ modes: [], current: '' });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const normalize = (text) => (text || '').replace(/\s+/g, ' ').trim();
|
|
13
|
+
const getModeButton = () => {
|
|
14
|
+
const buttons = Array.from(cascade.querySelectorAll('button')).filter(el => el.offsetWidth > 0 && el.offsetHeight > 0);
|
|
15
|
+
return buttons.find(el => {
|
|
16
|
+
const rect = el.getBoundingClientRect();
|
|
17
|
+
return rect.y > window.innerHeight - 90 && /lucide-code|lucide-message|lucide-search|lucide-wand|lucide-pencil/i.test(el.innerHTML);
|
|
18
|
+
}) || null;
|
|
19
|
+
};
|
|
20
|
+
const inferCurrent = (button) => {
|
|
21
|
+
if (!button) return '';
|
|
22
|
+
if (/lucide-code/i.test(button.innerHTML)) return 'Code';
|
|
23
|
+
if (/lucide-message/i.test(button.innerHTML)) return 'Ask';
|
|
24
|
+
if (/lucide-search/i.test(button.innerHTML)) return 'Search';
|
|
25
|
+
if (/lucide-pencil|lucide-pen|lucide-wand/i.test(button.innerHTML)) return 'Write';
|
|
26
|
+
return '';
|
|
27
|
+
};
|
|
28
|
+
const getMenuButtons = () => Array.from(document.querySelectorAll('button')).filter(el => {
|
|
29
|
+
if (!(el.offsetWidth > 0 && el.offsetHeight > 0)) return false;
|
|
30
|
+
const rect = el.getBoundingClientRect();
|
|
31
|
+
const text = normalize(el.innerText || el.textContent);
|
|
32
|
+
return rect.x > window.innerWidth - 320 && rect.width >= 180 && /^(Code|Ask|Search|Write)\b/i.test(text);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const modeButton = getModeButton();
|
|
36
|
+
const current = inferCurrent(modeButton);
|
|
37
|
+
const wasOpen = getMenuButtons().length > 0;
|
|
8
38
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const txt = (el.textContent || '').trim();
|
|
13
|
-
if (txt && /claude|gpt|gemini|sonnet|opus/i.test(txt)) {
|
|
14
|
-
if (txt.length < 50) {
|
|
15
|
-
models.push(txt);
|
|
16
|
-
if (!current) current = txt;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
39
|
+
if (!wasOpen && modeButton) {
|
|
40
|
+
modeButton.click();
|
|
41
|
+
await wait(200);
|
|
19
42
|
}
|
|
20
43
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
44
|
+
const modes = [];
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
for (const button of getMenuButtons()) {
|
|
47
|
+
const name = normalize((button.innerText || button.textContent || '').split('\n')[0]);
|
|
48
|
+
if (!name) continue;
|
|
49
|
+
const key = name.toLowerCase();
|
|
50
|
+
if (seen.has(key)) continue;
|
|
51
|
+
seen.add(key);
|
|
52
|
+
modes.push({ name, id: key });
|
|
30
53
|
}
|
|
31
54
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
55
|
+
if (!wasOpen) {
|
|
56
|
+
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', keyCode: 27, which: 27, bubbles: true, cancelable: true }));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return JSON.stringify({ modes, current });
|
|
36
60
|
} catch (e) {
|
|
37
|
-
return JSON.stringify({
|
|
61
|
+
return JSON.stringify({ modes: [], current: '', error: e.message });
|
|
38
62
|
}
|
|
39
63
|
})()
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windsurf v1 — list_sessions
|
|
3
|
+
*
|
|
4
|
+
* Cascade 세션 리스트를 가져옵니다.
|
|
5
|
+
* 1. 상단 탭 ([id^="cascade-tab-"])
|
|
6
|
+
* 2. 히스토리 패널 ([data-kb-navigate="true"])
|
|
7
|
+
*/
|
|
8
|
+
(async () => {
|
|
9
|
+
try {
|
|
10
|
+
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
11
|
+
const isVisible = (el) => !!(el && el.offsetWidth > 0 && el.offsetHeight > 0);
|
|
12
|
+
const cascade = document.querySelector('#windsurf\\.cascadePanel') || document.querySelector('.chat-client-root');
|
|
13
|
+
if (!cascade) return JSON.stringify({ sessions: [] });
|
|
14
|
+
|
|
15
|
+
const normalize = (text) => (text || '').replace(/\s+/g, ' ').trim();
|
|
16
|
+
const activeTabEl = document.querySelector('[id^="cascade-tab-"] .bg-ide-tab-active-background-color');
|
|
17
|
+
const activeTabTitle = normalize(activeTabEl?.textContent || document.querySelector('.bg-ide-tab-active-background-color .truncate')?.textContent || '');
|
|
18
|
+
|
|
19
|
+
const sessions = [];
|
|
20
|
+
const seenIds = new Set();
|
|
21
|
+
const seenTitles = new Set();
|
|
22
|
+
|
|
23
|
+
// 1. 상단 탭
|
|
24
|
+
const tabs = Array.from(document.querySelectorAll('[id^="cascade-tab-"]')).filter(isVisible);
|
|
25
|
+
for (const tab of tabs) {
|
|
26
|
+
const fullId = tab.id || '';
|
|
27
|
+
const id = fullId.replace('cascade-tab-', '');
|
|
28
|
+
const title = normalize(tab.textContent);
|
|
29
|
+
if (!title || title === 'New Cascade') continue;
|
|
30
|
+
|
|
31
|
+
// 활성 상태 확인: 특정 클래스 or 내부 요소의 클래스 or ARIA 속성
|
|
32
|
+
const isActive = tab.classList.contains('bg-ide-tab-active-background-color') ||
|
|
33
|
+
!!tab.querySelector('.bg-ide-tab-active-background-color') ||
|
|
34
|
+
tab.getAttribute('aria-selected') === 'true';
|
|
35
|
+
|
|
36
|
+
seenIds.add(id);
|
|
37
|
+
seenTitles.add(title.toLowerCase());
|
|
38
|
+
sessions.push({
|
|
39
|
+
id,
|
|
40
|
+
title,
|
|
41
|
+
active: isActive,
|
|
42
|
+
index: sessions.length
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 2. 히스토리 패널
|
|
47
|
+
const historyButton = Array.from(cascade.querySelectorAll('button')).find(el => isVisible(el) && /lucide-history/.test(el.innerHTML || ''));
|
|
48
|
+
const existingPanel = Array.from(cascade.querySelectorAll('div')).find(el => isVisible(el) && (String(el.className || '').includes('group/panel') || el.hasAttribute('data-kb-navigate')));
|
|
49
|
+
const wasOpen = !!existingPanel;
|
|
50
|
+
|
|
51
|
+
if (!wasOpen && historyButton) {
|
|
52
|
+
historyButton.click();
|
|
53
|
+
await wait(300);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const historyRows = Array.from(document.querySelectorAll('[data-kb-navigate="true"]')).filter(isVisible);
|
|
57
|
+
for (const row of historyRows) {
|
|
58
|
+
const title = normalize(row.querySelector('.truncate, span')?.textContent || row.textContent);
|
|
59
|
+
if (!title || seenTitles.has(title.toLowerCase())) continue;
|
|
60
|
+
|
|
61
|
+
seenTitles.add(title.toLowerCase());
|
|
62
|
+
sessions.push({
|
|
63
|
+
id: title.toLowerCase().replace(/[^a-z0-9]+/g, '-'),
|
|
64
|
+
title,
|
|
65
|
+
active: title === activeTabTitle,
|
|
66
|
+
index: sessions.length
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!wasOpen && historyButton) {
|
|
71
|
+
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', keyCode: 27, which: 27, bubbles: true, cancelable: true }));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return JSON.stringify({ sessions });
|
|
75
|
+
} catch (e) {
|
|
76
|
+
return JSON.stringify({ sessions: [], error: e.message });
|
|
77
|
+
}
|
|
78
|
+
})()
|
|
79
|
+
|
|
@@ -14,56 +14,45 @@
|
|
|
14
14
|
*
|
|
15
15
|
* 최종 확인: Windsurf 1.108.x (2026-03-10)
|
|
16
16
|
*/
|
|
17
|
-
(() => {
|
|
17
|
+
(async () => {
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
19
|
+
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
20
|
+
const cascade = document.querySelector('#windsurf\\.cascadePanel') || document.querySelector('.chat-client-root');
|
|
21
|
+
const beforeTabs = document.querySelectorAll('[id^="cascade-tab-"]').length;
|
|
22
|
+
const headerButtons = Array.from((cascade || document).querySelectorAll('button')).filter(el => el.offsetWidth > 0 && el.offsetHeight > 0);
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return 'clicked (aria)';
|
|
24
|
+
const clickSequence = (el) => {
|
|
25
|
+
const rect = el.getBoundingClientRect();
|
|
26
|
+
const init = { bubbles: true, cancelable: true, clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, pointerId: 1, pointerType: 'mouse' };
|
|
27
|
+
el.focus?.();
|
|
28
|
+
for (const type of ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click']) {
|
|
29
|
+
el.dispatchEvent(new PointerEvent(type, init));
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
};
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
text
|
|
38
|
-
|
|
39
|
-
return '
|
|
40
|
-
}
|
|
33
|
+
let button = headerButtons.find(el => /lucide-plus/.test(el.innerHTML));
|
|
34
|
+
|
|
35
|
+
if (!button) {
|
|
36
|
+
button = headerButtons.find(el => {
|
|
37
|
+
const text = (el.innerText || el.textContent || '').trim().toLowerCase();
|
|
38
|
+
const label = ((el.getAttribute('aria-label') || '') + ' ' + (el.getAttribute('title') || '')).toLowerCase();
|
|
39
|
+
return text === '+' || label.includes('new chat') || label.includes('new cascade') || label.includes('new conversation') || label.includes('new session');
|
|
40
|
+
});
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// Cascade 관련 컨텍스트이거나 라벨이 비어있으면 새 세션 버튼일 가능성
|
|
49
|
-
if (label.includes('chat') || label.includes('cascade') ||
|
|
50
|
-
label.includes('new') || label === '') {
|
|
51
|
-
btn.click();
|
|
52
|
-
return 'clicked (icon)';
|
|
53
|
-
}
|
|
54
|
-
}
|
|
43
|
+
if (button) {
|
|
44
|
+
clickSequence(button);
|
|
45
|
+
await wait(300);
|
|
46
|
+
const afterTabs = document.querySelectorAll('[id^="cascade-tab-"]').length;
|
|
47
|
+
return JSON.stringify({ created: afterTabs >= beforeTabs });
|
|
55
48
|
}
|
|
56
49
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
key: 'l', code: 'KeyL', keyCode: 76,
|
|
61
|
-
metaKey: true, ctrlKey: false,
|
|
62
|
-
bubbles: true, cancelable: true,
|
|
63
|
-
}));
|
|
50
|
+
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'l', code: 'KeyL', keyCode: 76, which: 76, metaKey: true, bubbles: true, cancelable: true }));
|
|
51
|
+
document.dispatchEvent(new KeyboardEvent('keyup', { key: 'l', code: 'KeyL', keyCode: 76, which: 76, metaKey: true, bubbles: true, cancelable: true }));
|
|
52
|
+
await wait(300);
|
|
64
53
|
|
|
65
|
-
return '
|
|
54
|
+
return JSON.stringify({ created: document.querySelectorAll('[id^="cascade-tab-"]').length >= beforeTabs });
|
|
66
55
|
} catch (e) {
|
|
67
|
-
return
|
|
56
|
+
return JSON.stringify({ created: false, error: e.message });
|
|
68
57
|
}
|
|
69
58
|
})()
|