@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
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Antigravity v1 — resolve_action
|
|
3
|
-
*
|
|
4
|
-
* 스크롤 최하단 → scrollIntoView → .click()
|
|
5
|
-
* 파라미터: ${BUTTON_TEXT}
|
|
6
|
-
*/
|
|
7
|
-
(() => {
|
|
8
|
-
const want = ${ BUTTON_TEXT };
|
|
9
|
-
const wantNorm = (want || '').replace(/\s+/g, ' ').trim().toLowerCase();
|
|
10
|
-
|
|
11
|
-
function norm(t) { return (t || '').replace(/\s+/g, ' ').trim().toLowerCase(); }
|
|
12
|
-
|
|
13
|
-
function matches(el) {
|
|
14
|
-
const raw = (el.textContent || '').trim();
|
|
15
|
-
const t = norm(raw);
|
|
16
|
-
if (!t || t.length > 80) return false;
|
|
17
|
-
if (t === wantNorm) return true;
|
|
18
|
-
if (t.indexOf(wantNorm) === 0) return true;
|
|
19
|
-
if (wantNorm.indexOf(t) >= 0 && t.length > 2) return true;
|
|
20
|
-
if (t.indexOf(wantNorm) >= 0) return true;
|
|
21
|
-
if (/^(run|approve|allow|accept|always|yes)\b/.test(wantNorm)) {
|
|
22
|
-
if (/^run\b/.test(t)) return true;
|
|
23
|
-
if (/^allow\b/.test(t)) return true;
|
|
24
|
-
if (/^accept\b/.test(t) && !t.includes('changes')) return true;
|
|
25
|
-
if (/^always\b/.test(t)) return true;
|
|
26
|
-
}
|
|
27
|
-
if (/^(reject|deny|no|abort)\b/.test(wantNorm)) {
|
|
28
|
-
if (/^reject\b/.test(t) && !t.includes('changes')) return true;
|
|
29
|
-
if (/^deny\b/.test(t)) return true;
|
|
30
|
-
}
|
|
31
|
-
if (/^(skip|cancel)\b/.test(wantNorm)) {
|
|
32
|
-
if (/^skip\b/.test(t) || /^cancel\b/.test(t)) return true;
|
|
33
|
-
}
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// 1. 채팅 패널 스크롤을 최하단으로
|
|
38
|
-
const conv = document.querySelector('.antigravity-agent-side-panel') || document.querySelector('#conversation');
|
|
39
|
-
const scrollEl = conv ? (conv.querySelector('.overflow-y-auto') || conv) : null;
|
|
40
|
-
if (scrollEl) scrollEl.scrollTop = scrollEl.scrollHeight;
|
|
41
|
-
|
|
42
|
-
// 2. viewport 필터 없이 DOM에 있는 모든 visible 버튼 검색
|
|
43
|
-
const sel = 'button, [role="button"]';
|
|
44
|
-
const allBtns = [...document.querySelectorAll(sel)].filter(b => b.offsetWidth > 0 && b.offsetHeight > 0);
|
|
45
|
-
|
|
46
|
-
// 마지막(최신) 매칭 우선 — 역순 검색
|
|
47
|
-
let found = null;
|
|
48
|
-
for (let i = allBtns.length - 1; i >= 0; i--) {
|
|
49
|
-
if (matches(allBtns[i])) {
|
|
50
|
-
found = allBtns[i];
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (found) {
|
|
56
|
-
const text = found.textContent?.trim()?.substring(0, 40);
|
|
57
|
-
// 버튼이 화면에 보이도록 스크롤 후 클릭
|
|
58
|
-
try { found.scrollIntoView({ block: 'nearest' }); } catch (_) {}
|
|
59
|
-
try { found.click(); } catch (_) {}
|
|
60
|
-
return JSON.stringify({ resolved: true, clicked: text });
|
|
61
|
-
}
|
|
62
|
-
return JSON.stringify({ found: false, want: wantNorm });
|
|
63
|
-
})()
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Antigravity v1 — send_message
|
|
3
|
-
*
|
|
4
|
-
* Antigravity는 contenteditable div[role="textbox"]를 사용.
|
|
5
|
-
* 여러 개의 contenteditable이 있을 수 있으므로 y좌표가 가장 큰 (메인 채팅) 것을 선택.
|
|
6
|
-
*
|
|
7
|
-
* ⚠️ Enter 이벤트에 composed: true + which 필수 (Shadow DOM 경계 통과 + React 호환)
|
|
8
|
-
* ⚠️ keydown + keypress + keyup 전체 시퀀스 필요
|
|
9
|
-
*
|
|
10
|
-
* 파라미터: ${ MESSAGE }
|
|
11
|
-
* 최종 확인: 2026-03-10
|
|
12
|
-
*/
|
|
13
|
-
(async () => {
|
|
14
|
-
try {
|
|
15
|
-
const msg = ${ MESSAGE };
|
|
16
|
-
|
|
17
|
-
// ─── 1. 메인 채팅 입력 필드 찾기 ───
|
|
18
|
-
const editors = document.querySelectorAll('[contenteditable="true"][role="textbox"]');
|
|
19
|
-
if (!editors.length) return 'error: no contenteditable textbox found';
|
|
20
|
-
|
|
21
|
-
// y좌표가 가장 큰 (화면 아래쪽 = 메인 채팅) 에디터 선택
|
|
22
|
-
const editor = [...editors].reduce((a, b) =>
|
|
23
|
-
b.getBoundingClientRect().y > a.getBoundingClientRect().y ? b : a
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
// ─── 2. 텍스트 삽입 ───
|
|
27
|
-
editor.focus();
|
|
28
|
-
|
|
29
|
-
// 기존 내용 삭제
|
|
30
|
-
document.execCommand('selectAll', false, null);
|
|
31
|
-
document.execCommand('delete', false, null);
|
|
32
|
-
|
|
33
|
-
// 텍스트 삽입
|
|
34
|
-
document.execCommand('insertText', false, msg);
|
|
35
|
-
|
|
36
|
-
// React에 변경 알림
|
|
37
|
-
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
|
38
|
-
|
|
39
|
-
await new Promise(r => setTimeout(r, 300));
|
|
40
|
-
|
|
41
|
-
// ─── 3. Enter 키 전송 (full sequence) ───
|
|
42
|
-
const enterOpts = {
|
|
43
|
-
key: 'Enter', code: 'Enter',
|
|
44
|
-
keyCode: 13, which: 13,
|
|
45
|
-
bubbles: true, cancelable: true, composed: true,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
editor.dispatchEvent(new KeyboardEvent('keydown', enterOpts));
|
|
49
|
-
editor.dispatchEvent(new KeyboardEvent('keypress', enterOpts));
|
|
50
|
-
editor.dispatchEvent(new KeyboardEvent('keyup', enterOpts));
|
|
51
|
-
|
|
52
|
-
return 'sent';
|
|
53
|
-
} catch (e) {
|
|
54
|
-
return 'error: ' + e.message;
|
|
55
|
-
}
|
|
56
|
-
})()
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Antigravity v1 — switch_session (v7 — CDP 마우스 클릭 좌표 반환)
|
|
3
|
-
*
|
|
4
|
-
* ⚠️ 삭제 버튼(trash SVG)에 절대 접근하지 않음.
|
|
5
|
-
*
|
|
6
|
-
* 두 가지 모드:
|
|
7
|
-
* 1) 히스토리 토글을 열고 행 좌표를 찾으면 {clickX, clickY} 반환 → daemon이 CDP 클릭으로 처리
|
|
8
|
-
* 2) 워크스페이스 다이얼로그가 뜨면 첫 번째 행 좌표 반환 (자동 선택용)
|
|
9
|
-
*
|
|
10
|
-
* 파라미터: ${SESSION_ID} — 대화 제목 (문자열)
|
|
11
|
-
*/
|
|
12
|
-
(async () => {
|
|
13
|
-
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
14
|
-
const id = ${SESSION_ID};
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
// 1. 히스토리 토글 클릭
|
|
18
|
-
const toggle = document.querySelector('[data-past-conversations-toggle="true"]');
|
|
19
|
-
if (!toggle) return JSON.stringify({ error: 'no_toggle' });
|
|
20
|
-
toggle.click();
|
|
21
|
-
await sleep(1200);
|
|
22
|
-
|
|
23
|
-
// 2. 컨테이너 찾기 (기존 로직: "Current" 텍스트 또는 "Select a conversation" input)
|
|
24
|
-
let container = null;
|
|
25
|
-
|
|
26
|
-
// 2a. "Current" 텍스트 기반
|
|
27
|
-
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);
|
|
28
|
-
while (walker.nextNode()) {
|
|
29
|
-
if (walker.currentNode.textContent.trim() === 'Current') {
|
|
30
|
-
let el = walker.currentNode.parentElement;
|
|
31
|
-
for (let i = 0; i < 10 && el; i++) {
|
|
32
|
-
const cls = (el.className || '');
|
|
33
|
-
if (typeof cls === 'string' && (cls.includes('overflow-auto') || cls.includes('overflow-y-scroll'))) {
|
|
34
|
-
container = el; break;
|
|
35
|
-
}
|
|
36
|
-
el = el.parentElement;
|
|
37
|
-
}
|
|
38
|
-
if (!container) {
|
|
39
|
-
el = walker.currentNode.parentElement;
|
|
40
|
-
let bestEl = null, bestCount = 0;
|
|
41
|
-
for (let i = 0; i < 8 && el; i++) {
|
|
42
|
-
const rows = el.querySelectorAll('[class*="cursor-pointer"][class*="justify-between"][class*="rounded-md"]');
|
|
43
|
-
if (rows.length > bestCount) { bestCount = rows.length; bestEl = el; }
|
|
44
|
-
el = el.parentElement;
|
|
45
|
-
}
|
|
46
|
-
container = bestEl;
|
|
47
|
-
}
|
|
48
|
-
if (container) break;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// 2b. 폴백: "Select a conversation" input 기반
|
|
53
|
-
if (!container) {
|
|
54
|
-
const searchInput = Array.from(document.querySelectorAll('input[type="text"]'))
|
|
55
|
-
.find(i => i.offsetWidth > 0 && (i.placeholder || '').includes('Select a conversation'));
|
|
56
|
-
if (searchInput) {
|
|
57
|
-
let el = searchInput.parentElement;
|
|
58
|
-
for (let i = 0; i < 10 && el; i++) {
|
|
59
|
-
const cls = (el.className || '');
|
|
60
|
-
if (typeof cls === 'string' && (cls.includes('overflow-auto') || cls.includes('overflow-y-scroll'))) {
|
|
61
|
-
container = el; break;
|
|
62
|
-
}
|
|
63
|
-
const rows = el.querySelectorAll('[class*="cursor-pointer"][class*="justify-between"][class*="rounded-md"]');
|
|
64
|
-
if (rows.length > 0 && !container) container = el;
|
|
65
|
-
el = el.parentElement;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (!container) {
|
|
71
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true }));
|
|
72
|
-
return JSON.stringify({ error: 'no_container' });
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 3. 행 매칭
|
|
76
|
-
const rows = container.querySelectorAll('[class*="cursor-pointer"][class*="justify-between"][class*="rounded-md"]');
|
|
77
|
-
const norm = s => (s || '').trim().toLowerCase().replace(/\s+/g, ' ');
|
|
78
|
-
const idNorm = norm(id);
|
|
79
|
-
let targetRow = null;
|
|
80
|
-
|
|
81
|
-
for (const row of rows) {
|
|
82
|
-
// 현재 활성 대화 스킵
|
|
83
|
-
if ((row.className || '').includes('focusBackground')) continue;
|
|
84
|
-
const titleEl = row.querySelector('span span');
|
|
85
|
-
const title = titleEl ? norm(titleEl.textContent) : '';
|
|
86
|
-
if (!title) continue;
|
|
87
|
-
if (title.includes(idNorm) || idNorm.includes(title)) {
|
|
88
|
-
targetRow = row;
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (!targetRow) {
|
|
94
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true }));
|
|
95
|
-
return JSON.stringify({ error: 'no_match', rowCount: rows.length });
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 4. 행의 좌표 계산 → daemon이 CDP Input.dispatchMouseEvent로 클릭
|
|
99
|
-
const rect = targetRow.getBoundingClientRect();
|
|
100
|
-
const clickX = Math.round(rect.left + rect.width * 0.3);
|
|
101
|
-
const clickY = Math.round(rect.top + rect.height / 2);
|
|
102
|
-
|
|
103
|
-
return JSON.stringify({
|
|
104
|
-
action: 'click',
|
|
105
|
-
clickX,
|
|
106
|
-
clickY,
|
|
107
|
-
title: (targetRow.querySelector('span span')?.textContent || '').substring(0, 60)
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
} catch (e) {
|
|
111
|
-
try { document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true })); } catch (_) { }
|
|
112
|
-
return JSON.stringify({ error: e.message });
|
|
113
|
-
}
|
|
114
|
-
})()
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — dismiss_notification
|
|
3
|
-
*
|
|
4
|
-
* 알림 토스트 닫기/버튼 클릭:
|
|
5
|
-
* 인덱스 또는 메시지 매칭으로 대상 선택
|
|
6
|
-
* 버튼 텍스트 지정 시 해당 버튼 클릭, 아니면 닫기
|
|
7
|
-
*
|
|
8
|
-
* params.index: number, params.button: string|null, params.message: string|null
|
|
9
|
-
* → { dismissed: true/false }
|
|
10
|
-
*/
|
|
11
|
-
(params) => {
|
|
12
|
-
try {
|
|
13
|
-
const toasts = [...document.querySelectorAll('.notifications-toasts .notification-toast, .notification-list-item')].filter(t => t.offsetWidth > 0);
|
|
14
|
-
let toast;
|
|
15
|
-
if (params.message) {
|
|
16
|
-
toast = toasts.find(t => (t.querySelector('.notification-list-item-message')?.textContent || t.textContent || '').toLowerCase().includes(params.message.toLowerCase()));
|
|
17
|
-
} else {
|
|
18
|
-
toast = toasts[params.index || 0];
|
|
19
|
-
}
|
|
20
|
-
if (!toast) return JSON.stringify({ dismissed: false, error: 'Toast not found', count: toasts.length });
|
|
21
|
-
if (params.button) {
|
|
22
|
-
const btn = [...toast.querySelectorAll('button')].find(b => b.textContent?.trim().toLowerCase().includes(params.button.toLowerCase()));
|
|
23
|
-
if (btn) { btn.click(); return JSON.stringify({ dismissed: true, clicked: btn.textContent.trim() }); }
|
|
24
|
-
return JSON.stringify({ dismissed: false, error: 'Button not found' });
|
|
25
|
-
}
|
|
26
|
-
const closeBtn = toast.querySelector('.codicon-notifications-clear, .clear-notification-action, .codicon-close');
|
|
27
|
-
if (closeBtn) { closeBtn.click(); return JSON.stringify({ dismissed: true }); }
|
|
28
|
-
return JSON.stringify({ dismissed: false, error: 'Close button not found' });
|
|
29
|
-
} catch(e) { return JSON.stringify({ dismissed: false, error: e.message }); }
|
|
30
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — focus_editor
|
|
3
|
-
*
|
|
4
|
-
* 채팅 입력 필드에 포커스:
|
|
5
|
-
* .aislash-editor-input[contenteditable="true"]
|
|
6
|
-
*/
|
|
7
|
-
(() => {
|
|
8
|
-
try {
|
|
9
|
-
const input = document.querySelector('.aislash-editor-input[contenteditable="true"]');
|
|
10
|
-
if (input) { input.focus(); return JSON.stringify({ focused: true }); }
|
|
11
|
-
return JSON.stringify({ focused: false, error: 'Input not found' });
|
|
12
|
-
} catch(e) { return JSON.stringify({ focused: false, error: e.message }); }
|
|
13
|
-
})()
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — list_models
|
|
3
|
-
*
|
|
4
|
-
* 모델 드롭다운 목록 추출:
|
|
5
|
-
* 버튼: .composer-unified-dropdown-model
|
|
6
|
-
* 메뉴: [data-testid="model-picker-menu"]
|
|
7
|
-
* 아이템: .composer-unified-context-menu-item
|
|
8
|
-
* 모델명: .monaco-highlighted-label
|
|
9
|
-
* Think 모드: codicon-br (brain) 아이콘
|
|
10
|
-
* Auto 토글: rounded-full 24x14 요소
|
|
11
|
-
*
|
|
12
|
-
* → { models[], current }
|
|
13
|
-
*/
|
|
14
|
-
(async () => {
|
|
15
|
-
try {
|
|
16
|
-
let current = '';
|
|
17
|
-
const models = [];
|
|
18
|
-
|
|
19
|
-
const modelBtn = document.querySelector('.composer-unified-dropdown-model');
|
|
20
|
-
if (modelBtn) {
|
|
21
|
-
current = modelBtn.textContent?.trim() || '';
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// 드롭다운 열기
|
|
25
|
-
if (modelBtn) {
|
|
26
|
-
modelBtn.click();
|
|
27
|
-
await new Promise(r => setTimeout(r, 500));
|
|
28
|
-
|
|
29
|
-
const menu = document.querySelector('[data-testid="model-picker-menu"]');
|
|
30
|
-
if (menu) {
|
|
31
|
-
// Auto 토글 확인 및 끄기
|
|
32
|
-
const autoItem = menu.querySelector('.composer-unified-context-menu-item[data-is-selected="true"]');
|
|
33
|
-
const autoToggle = autoItem ? [...autoItem.querySelectorAll('[class*="rounded-full"]')].find(el => el.offsetWidth === 24 && el.offsetHeight === 14) : null;
|
|
34
|
-
let wasAutoOn = false;
|
|
35
|
-
if (autoToggle) {
|
|
36
|
-
const bgStyle = autoToggle.getAttribute('style') || '';
|
|
37
|
-
wasAutoOn = bgStyle.includes('green');
|
|
38
|
-
if (wasAutoOn) {
|
|
39
|
-
autoToggle.click();
|
|
40
|
-
await new Promise(r => setTimeout(r, 500));
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// 모델 목록 수집 (Auto 끈 상태)
|
|
45
|
-
const refreshedMenu = document.querySelector('[data-testid="model-picker-menu"]');
|
|
46
|
-
if (refreshedMenu) {
|
|
47
|
-
const items = refreshedMenu.querySelectorAll('.composer-unified-context-menu-item');
|
|
48
|
-
for (const item of items) {
|
|
49
|
-
const nameEl = item.querySelector('.monaco-highlighted-label');
|
|
50
|
-
const name = nameEl?.textContent?.trim() || '';
|
|
51
|
-
if (name && name !== 'Add Models') {
|
|
52
|
-
const hasBrain = !!item.querySelector('[class*="codicon-br"]');
|
|
53
|
-
const displayName = hasBrain ? name + ' 🧠' : name;
|
|
54
|
-
models.push({ name: displayName, id: displayName });
|
|
55
|
-
if (item.getAttribute('data-is-selected') === 'true') current = displayName;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Auto 다시 켜기 (원래 상태 복원)
|
|
61
|
-
if (wasAutoOn) {
|
|
62
|
-
const newMenu = document.querySelector('[data-testid="model-picker-menu"]');
|
|
63
|
-
const newAutoItem = newMenu?.querySelector('.composer-unified-context-menu-item');
|
|
64
|
-
const newToggle = newAutoItem ? [...newAutoItem.querySelectorAll('[class*="rounded-full"]')].find(el => el.offsetWidth === 24) : null;
|
|
65
|
-
if (newToggle) {
|
|
66
|
-
newToggle.click();
|
|
67
|
-
await new Promise(r => setTimeout(r, 200));
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// 닫기 (Escape)
|
|
73
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return JSON.stringify({ models, current });
|
|
77
|
-
} catch(e) { return JSON.stringify({ models: [], current: '', error: e.message }); }
|
|
78
|
-
})()
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — list_modes
|
|
3
|
-
*
|
|
4
|
-
* 모드 드롭다운 목록 추출:
|
|
5
|
-
* 버튼: .composer-unified-dropdown (model이 아닌 것)
|
|
6
|
-
* 메뉴: [data-testid="model-picker-menu"] 또는 .typeahead-popover
|
|
7
|
-
* 아이템: .composer-unified-context-menu-item
|
|
8
|
-
*
|
|
9
|
-
* → { modes[], current }
|
|
10
|
-
*/
|
|
11
|
-
(async () => {
|
|
12
|
-
try {
|
|
13
|
-
const modes = [];
|
|
14
|
-
let current = '';
|
|
15
|
-
|
|
16
|
-
const modeBtn = document.querySelector('.composer-unified-dropdown:not(.composer-unified-dropdown-model)');
|
|
17
|
-
if (!modeBtn) return JSON.stringify({ modes: [], current: '', error: 'Mode button not found' });
|
|
18
|
-
|
|
19
|
-
modeBtn.click();
|
|
20
|
-
await new Promise(r => setTimeout(r, 500));
|
|
21
|
-
|
|
22
|
-
const menu = document.querySelector('[data-testid="model-picker-menu"]') || document.querySelector('.typeahead-popover');
|
|
23
|
-
if (menu) {
|
|
24
|
-
const items = menu.querySelectorAll('.composer-unified-context-menu-item');
|
|
25
|
-
for (const item of items) {
|
|
26
|
-
const nameEl = item.querySelector('.monaco-highlighted-label');
|
|
27
|
-
const name = nameEl?.textContent?.trim() || '';
|
|
28
|
-
if (name) {
|
|
29
|
-
modes.push({ name, id: name });
|
|
30
|
-
if (item.getAttribute('data-is-selected') === 'true') current = name;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// 닫기
|
|
36
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
37
|
-
|
|
38
|
-
return JSON.stringify({ modes, current });
|
|
39
|
-
} catch(e) { return JSON.stringify({ modes: [], current: '', error: e.message }); }
|
|
40
|
-
})()
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — list_notifications
|
|
3
|
-
*
|
|
4
|
-
* VS Code 알림 토스트 목록:
|
|
5
|
-
* .notifications-toasts .notification-toast
|
|
6
|
-
* .notification-list-item
|
|
7
|
-
*
|
|
8
|
-
* params.filter: string|null — 메시지 필터
|
|
9
|
-
* → [{ index, message, severity, buttons }]
|
|
10
|
-
*/
|
|
11
|
-
(params) => {
|
|
12
|
-
try {
|
|
13
|
-
const toasts = [...document.querySelectorAll('.notifications-toasts .notification-toast, .notification-list-item')];
|
|
14
|
-
const visible = toasts.filter(t => t.offsetWidth > 0).map((t, i) => ({
|
|
15
|
-
index: i,
|
|
16
|
-
message: t.querySelector('.notification-list-item-message')?.textContent?.trim() || t.textContent?.trim().substring(0, 200),
|
|
17
|
-
severity: t.querySelector('.codicon-error') ? 'error' : t.querySelector('.codicon-warning') ? 'warning' : 'info',
|
|
18
|
-
buttons: [...t.querySelectorAll('.notification-list-item-buttons-container button, .monaco-button')].map(b => b.textContent?.trim()).filter(Boolean),
|
|
19
|
-
}));
|
|
20
|
-
const f = params.filter || null;
|
|
21
|
-
return JSON.stringify(f ? visible.filter(n => n.message.toLowerCase().includes(f.toLowerCase())) : visible);
|
|
22
|
-
} catch(e) { return JSON.stringify([]); }
|
|
23
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — new_session
|
|
3
|
-
*
|
|
4
|
-
* 새 채팅/컴포저 버튼 클릭:
|
|
5
|
-
* a.action-label.codicon-add-two
|
|
6
|
-
* [aria-label*="New Chat"]
|
|
7
|
-
* [aria-label*="New Composer"]
|
|
8
|
-
*
|
|
9
|
-
* → { created: true/false }
|
|
10
|
-
*/
|
|
11
|
-
(() => {
|
|
12
|
-
try {
|
|
13
|
-
const newBtn = [...document.querySelectorAll('a.action-label.codicon-add-two, [aria-label*="New Chat"], [aria-label*="New Composer"]')]
|
|
14
|
-
.find(a => a.offsetWidth > 0);
|
|
15
|
-
if (newBtn) { newBtn.click(); return JSON.stringify({ created: true }); }
|
|
16
|
-
return JSON.stringify({ created: false, error: 'New Chat button not found' });
|
|
17
|
-
} catch(e) {
|
|
18
|
-
return JSON.stringify({ created: false, error: e.message });
|
|
19
|
-
}
|
|
20
|
-
})()
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — open_panel
|
|
3
|
-
*
|
|
4
|
-
* 채팅/컴포저 패널 열기:
|
|
5
|
-
* 1. 이미 보이면 'visible' 반환
|
|
6
|
-
* 2. Agent/Chat/Composer 탭 찾아서 클릭
|
|
7
|
-
*/
|
|
8
|
-
(() => {
|
|
9
|
-
try {
|
|
10
|
-
const sidebar = document.getElementById('workbench.parts.auxiliarybar');
|
|
11
|
-
if (sidebar && sidebar.offsetWidth > 0) {
|
|
12
|
-
const chatView = document.querySelector('[data-composer-id]');
|
|
13
|
-
if (chatView) return JSON.stringify({ opened: true });
|
|
14
|
-
}
|
|
15
|
-
const btns = [...document.querySelectorAll('li.action-item a, button, [role="tab"]')];
|
|
16
|
-
const toggle = btns.find(b => {
|
|
17
|
-
const label = (b.textContent || b.getAttribute('aria-label') || '').toLowerCase();
|
|
18
|
-
return /agent|chat|composer|cursor tab/i.test(label);
|
|
19
|
-
});
|
|
20
|
-
if (toggle) { toggle.click(); return JSON.stringify({ opened: true }); }
|
|
21
|
-
return JSON.stringify({ opened: false, error: 'Panel toggle not found' });
|
|
22
|
-
} catch (e) { return JSON.stringify({ opened: false, error: e.message }); }
|
|
23
|
-
})()
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — send_message
|
|
3
|
-
*
|
|
4
|
-
* Cursor는 cdp-type-and-send 방식:
|
|
5
|
-
* 1. 입력 필드 존재 확인
|
|
6
|
-
* 2. needsTypeAndSend: true 반환 → daemon이 CDP로 타이핑 + Enter 처리
|
|
7
|
-
*
|
|
8
|
-
* 입력 셀렉터: .aislash-editor-input[contenteditable="true"]
|
|
9
|
-
* 파라미터: ${ MESSAGE } (사용되지 않음 — daemon이 직접 타이핑)
|
|
10
|
-
*/
|
|
11
|
-
(() => {
|
|
12
|
-
try {
|
|
13
|
-
const input = document.querySelector('.aislash-editor-input[contenteditable="true"]');
|
|
14
|
-
if (!input) return JSON.stringify({ sent: false, error: 'Input box not found' });
|
|
15
|
-
return JSON.stringify({
|
|
16
|
-
sent: false,
|
|
17
|
-
needsTypeAndSend: true,
|
|
18
|
-
selector: '.aislash-editor-input[contenteditable="true"]',
|
|
19
|
-
});
|
|
20
|
-
} catch(e) {
|
|
21
|
-
return JSON.stringify({ sent: false, error: e.message });
|
|
22
|
-
}
|
|
23
|
-
})()
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — set_mode
|
|
3
|
-
*
|
|
4
|
-
* 모드 드롭다운에서 대상 모드 선택:
|
|
5
|
-
* 1. 드롭다운 열기
|
|
6
|
-
* 2. 매칭 아이템 클릭
|
|
7
|
-
*
|
|
8
|
-
* params.mode: string — 모드 이름
|
|
9
|
-
* → { success: true/false, mode? }
|
|
10
|
-
*/
|
|
11
|
-
async (params) => {
|
|
12
|
-
try {
|
|
13
|
-
const target = params.mode;
|
|
14
|
-
|
|
15
|
-
const modeBtn = document.querySelector('.composer-unified-dropdown:not(.composer-unified-dropdown-model)');
|
|
16
|
-
if (!modeBtn) return JSON.stringify({ success: false, error: 'Mode button not found' });
|
|
17
|
-
|
|
18
|
-
modeBtn.click();
|
|
19
|
-
await new Promise(r => setTimeout(r, 500));
|
|
20
|
-
|
|
21
|
-
const menu = document.querySelector('[data-testid="model-picker-menu"]') || document.querySelector('.typeahead-popover');
|
|
22
|
-
if (!menu) return JSON.stringify({ success: false, error: 'Mode menu not found' });
|
|
23
|
-
|
|
24
|
-
const items = menu.querySelectorAll('.composer-unified-context-menu-item');
|
|
25
|
-
for (const item of items) {
|
|
26
|
-
const nameEl = item.querySelector('.monaco-highlighted-label');
|
|
27
|
-
const name = nameEl?.textContent?.trim() || '';
|
|
28
|
-
if (name && (name === target || name.toLowerCase() === target.toLowerCase())) {
|
|
29
|
-
item.click();
|
|
30
|
-
await new Promise(r => setTimeout(r, 200));
|
|
31
|
-
return JSON.stringify({ success: true, mode: name });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
36
|
-
return JSON.stringify({ success: false, error: 'mode not found: ' + target });
|
|
37
|
-
} catch(e) { return JSON.stringify({ success: false, error: e.message }); }
|
|
38
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — set_model
|
|
3
|
-
*
|
|
4
|
-
* 모델 드롭다운에서 대상 모델 선택:
|
|
5
|
-
* 1. 드롭다운 열기
|
|
6
|
-
* 2. Auto 토글 끄기 (필요 시)
|
|
7
|
-
* 3. 검색 입력으로 필터
|
|
8
|
-
* 4. 매칭 아이템 클릭
|
|
9
|
-
* 5. 원래 Auto 상태 복원
|
|
10
|
-
*
|
|
11
|
-
* params.model: string — 모델 이름 (🧠 접미사 가능)
|
|
12
|
-
* → { success: true/false, model? }
|
|
13
|
-
*/
|
|
14
|
-
async (params) => {
|
|
15
|
-
try {
|
|
16
|
-
const target = params.model;
|
|
17
|
-
|
|
18
|
-
const modelBtn = document.querySelector('.composer-unified-dropdown-model');
|
|
19
|
-
if (!modelBtn) return JSON.stringify({ success: false, error: 'Model button not found' });
|
|
20
|
-
|
|
21
|
-
modelBtn.click();
|
|
22
|
-
await new Promise(r => setTimeout(r, 500));
|
|
23
|
-
|
|
24
|
-
const menu = document.querySelector('[data-testid="model-picker-menu"]');
|
|
25
|
-
if (!menu) return JSON.stringify({ success: false, error: 'Model picker menu not found' });
|
|
26
|
-
|
|
27
|
-
// 🧠 접미사 처리
|
|
28
|
-
const wantBrain = target.includes('🧠');
|
|
29
|
-
const searchName = target.replace(/\s*🧠\s*$/, '').trim();
|
|
30
|
-
|
|
31
|
-
// Auto 토글 끄기
|
|
32
|
-
const autoItem = menu.querySelector('.composer-unified-context-menu-item[data-is-selected="true"]');
|
|
33
|
-
const autoToggle = autoItem ? [...autoItem.querySelectorAll('[class*="rounded-full"]')].find(el => el.offsetWidth === 24 && el.offsetHeight === 14) : null;
|
|
34
|
-
let wasAutoOn = false;
|
|
35
|
-
if (autoToggle) {
|
|
36
|
-
const bgStyle = autoToggle.getAttribute('style') || '';
|
|
37
|
-
wasAutoOn = bgStyle.includes('green');
|
|
38
|
-
if (wasAutoOn) {
|
|
39
|
-
autoToggle.click();
|
|
40
|
-
await new Promise(r => setTimeout(r, 500));
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// 검색 입력으로 필터링
|
|
45
|
-
const refreshedMenu = document.querySelector('[data-testid="model-picker-menu"]');
|
|
46
|
-
const searchInput = refreshedMenu?.querySelector('input[placeholder="Search models"]');
|
|
47
|
-
if (searchInput) {
|
|
48
|
-
searchInput.focus();
|
|
49
|
-
searchInput.value = searchName;
|
|
50
|
-
searchInput.dispatchEvent(new Event('input', { bubbles: true }));
|
|
51
|
-
await new Promise(r => setTimeout(r, 300));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// 아이템에서 찾기
|
|
55
|
-
const items = (refreshedMenu || menu).querySelectorAll('.composer-unified-context-menu-item');
|
|
56
|
-
for (const item of items) {
|
|
57
|
-
const nameEl = item.querySelector('.monaco-highlighted-label');
|
|
58
|
-
const name = nameEl?.textContent?.trim() || '';
|
|
59
|
-
if (!name || name === 'Add Models') continue;
|
|
60
|
-
const hasBrain = !!item.querySelector('[class*="codicon-br"]');
|
|
61
|
-
|
|
62
|
-
if (name.toLowerCase().includes(searchName.toLowerCase()) && hasBrain === wantBrain) {
|
|
63
|
-
item.click();
|
|
64
|
-
await new Promise(r => setTimeout(r, 200));
|
|
65
|
-
const displayName = hasBrain ? name + ' 🧠' : name;
|
|
66
|
-
return JSON.stringify({ success: true, model: displayName });
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Auto 복원 + 닫기
|
|
71
|
-
if (wasAutoOn) {
|
|
72
|
-
const nm = document.querySelector('[data-testid="model-picker-menu"]');
|
|
73
|
-
const nai = nm?.querySelector('.composer-unified-context-menu-item');
|
|
74
|
-
const nt = nai ? [...nai.querySelectorAll('[class*="rounded-full"]')].find(el => el.offsetWidth === 24) : null;
|
|
75
|
-
if (nt) nt.click();
|
|
76
|
-
await new Promise(r => setTimeout(r, 200));
|
|
77
|
-
}
|
|
78
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
79
|
-
return JSON.stringify({ success: false, error: 'model not found: ' + target });
|
|
80
|
-
} catch(e) { return JSON.stringify({ success: false, error: e.message }); }
|
|
81
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor — switch_session
|
|
3
|
-
*
|
|
4
|
-
* 사이드바 셀 클릭으로 세션 전환:
|
|
5
|
-
* 제목 매칭 (params.title) 또는 인덱스 (params.index)
|
|
6
|
-
*
|
|
7
|
-
* params.index: number, params.title: string|null
|
|
8
|
-
* → { switched: true/false, title?, error? }
|
|
9
|
-
*/
|
|
10
|
-
(params) => {
|
|
11
|
-
try {
|
|
12
|
-
const cells = [...document.querySelectorAll('.agent-sidebar-cell')];
|
|
13
|
-
let target;
|
|
14
|
-
if (params.title) {
|
|
15
|
-
target = cells.find(c => {
|
|
16
|
-
const t = c.querySelector('.agent-sidebar-cell-text')?.textContent?.trim() || '';
|
|
17
|
-
return t.toLowerCase().includes(params.title.toLowerCase());
|
|
18
|
-
});
|
|
19
|
-
} else {
|
|
20
|
-
target = cells[params.index || 0];
|
|
21
|
-
}
|
|
22
|
-
if (!target) return JSON.stringify({ switched: false, error: 'Session not found', available: cells.length });
|
|
23
|
-
target.click();
|
|
24
|
-
return JSON.stringify({ switched: true, title: target.querySelector('.agent-sidebar-cell-text')?.textContent?.trim() });
|
|
25
|
-
} catch(e) {
|
|
26
|
-
return JSON.stringify({ switched: false, error: e.message });
|
|
27
|
-
}
|
|
28
|
-
}
|