@adhdev/daemon-core 0.6.36 → 0.6.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/index.d.ts +0 -1
  2. package/dist/index.js +9 -12
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/providers/_builtin/acp/codex-cli/provider.json +2 -2
  6. package/providers/_builtin/cli/codex-cli/provider.json +8 -18
  7. package/providers/_builtin/ide/antigravity/provider.json +2 -3
  8. package/providers/_builtin/ide/cursor/provider.json +2 -2
  9. package/providers/_builtin/ide/cursor/scripts/{0.49 → 1.0}/read_chat.js +1 -1
  10. package/providers/_builtin/ide/cursor/scripts/{0.49 → 1.0}/resolve_action.js +1 -1
  11. package/providers/_builtin/ide/windsurf/scripts/1.0/focus_editor.js +16 -10
  12. package/providers/_builtin/ide/windsurf/scripts/1.0/list_chats.js +9 -103
  13. package/providers/_builtin/ide/windsurf/scripts/1.0/list_models.js +43 -26
  14. package/providers/_builtin/ide/windsurf/scripts/1.0/list_modes.js +51 -27
  15. package/providers/_builtin/ide/windsurf/scripts/1.0/list_sessions.js +79 -0
  16. package/providers/_builtin/ide/windsurf/scripts/1.0/new_session.js +30 -41
  17. package/providers/_builtin/ide/windsurf/scripts/1.0/open_panel.js +44 -35
  18. package/providers/_builtin/ide/windsurf/scripts/1.0/read_chat.js +211 -273
  19. package/providers/_builtin/ide/windsurf/scripts/1.0/resolve_action.js +64 -50
  20. package/providers/_builtin/ide/windsurf/scripts/1.0/send_message.js +14 -81
  21. package/providers/_builtin/ide/windsurf/scripts/1.0/set_mode.js +34 -6
  22. package/providers/_builtin/ide/windsurf/scripts/1.0/set_model.js +40 -6
  23. package/providers/_builtin/ide/windsurf/scripts/1.0/switch_session.js +66 -42
  24. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/focus_editor.js +30 -0
  25. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_chats.js +117 -0
  26. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_models.js +39 -0
  27. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_modes.js +39 -0
  28. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/new_session.js +69 -0
  29. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/open_panel.js +58 -0
  30. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/read_chat.js +315 -0
  31. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/resolve_action.js +68 -0
  32. package/providers/_builtin/ide/{cursor/scripts/0.49 → windsurf/scripts/1.0.bak}/scripts.js +27 -23
  33. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/send_message.js +87 -0
  34. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_mode.js +15 -0
  35. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_model.js +15 -0
  36. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/switch_session.js +58 -0
  37. package/providers/_builtin/registry.json +5 -9
  38. package/src/commands/handler.ts +1 -8
  39. package/src/daemon/dev-server.ts +12 -3
  40. package/src/detection/ide-detector.ts +0 -3
  41. package/src/providers/provider-loader.ts +0 -1
  42. package/providers/_builtin/ide/antigravity/scripts/1.106/list_models.js +0 -38
  43. package/providers/_builtin/ide/antigravity/scripts/1.106/list_modes.js +0 -48
  44. package/providers/_builtin/ide/antigravity/scripts/1.106/read_chat.js +0 -290
  45. package/providers/_builtin/ide/antigravity/scripts/1.106/scripts.js +0 -57
  46. package/providers/_builtin/ide/antigravity/scripts/1.106/set_mode.js +0 -34
  47. package/providers/_builtin/ide/antigravity/scripts/1.106/set_model.js +0 -47
  48. package/providers/_builtin/ide/antigravity/scripts/1.107/focus_editor.js +0 -20
  49. package/providers/_builtin/ide/antigravity/scripts/1.107/list_chats.js +0 -137
  50. package/providers/_builtin/ide/antigravity/scripts/1.107/new_session.js +0 -75
  51. package/providers/_builtin/ide/antigravity/scripts/1.107/resolve_action.js +0 -63
  52. package/providers/_builtin/ide/antigravity/scripts/1.107/send_message.js +0 -56
  53. package/providers/_builtin/ide/antigravity/scripts/1.107/switch_session.js +0 -114
  54. package/providers/_builtin/ide/cursor/scripts/0.49/dismiss_notification.js +0 -30
  55. package/providers/_builtin/ide/cursor/scripts/0.49/focus_editor.js +0 -13
  56. package/providers/_builtin/ide/cursor/scripts/0.49/list_models.js +0 -78
  57. package/providers/_builtin/ide/cursor/scripts/0.49/list_modes.js +0 -40
  58. package/providers/_builtin/ide/cursor/scripts/0.49/list_notifications.js +0 -23
  59. package/providers/_builtin/ide/cursor/scripts/0.49/new_session.js +0 -20
  60. package/providers/_builtin/ide/cursor/scripts/0.49/open_panel.js +0 -23
  61. package/providers/_builtin/ide/cursor/scripts/0.49/send_message.js +0 -23
  62. package/providers/_builtin/ide/cursor/scripts/0.49/set_mode.js +0 -38
  63. package/providers/_builtin/ide/cursor/scripts/0.49/set_model.js +0 -81
  64. package/providers/_builtin/ide/cursor/scripts/0.49/switch_session.js +0 -28
  65. package/providers/_builtin/ide/cursor/scripts/0.49.bak/list_sessions.js +0 -42
  66. package/providers/_builtin/ide/cursor/scripts/0.49.bak/read_chat.js +0 -79
  67. package/providers/_builtin/ide/cursor/scripts/0.49.bak/resolve_action.js +0 -19
  68. /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/focus_editor.js +0 -0
  69. /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/list_chats.js +0 -0
  70. /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/list_models.js +0 -0
  71. /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/list_modes.js +0 -0
  72. /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/new_session.js +0 -0
  73. /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/read_chat.js +0 -0
  74. /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/resolve_action.js +0 -0
  75. /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/scripts.js +0 -0
  76. /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/send_message.js +0 -0
  77. /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/set_mode.js +0 -0
  78. /package/providers/_builtin/ide/antigravity/scripts/{1.107 → 1.0}/set_model.js +0 -0
  79. /package/providers/_builtin/ide/antigravity/scripts/{1.106 → 1.0}/switch_session.js +0 -0
  80. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/dismiss_notification.js +0 -0
  81. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/focus_editor.js +0 -0
  82. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/list_models.js +0 -0
  83. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/list_modes.js +0 -0
  84. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/list_notifications.js +0 -0
  85. /package/providers/_builtin/ide/cursor/scripts/{0.49 → 1.0}/list_sessions.js +0 -0
  86. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/new_session.js +0 -0
  87. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/open_panel.js +0 -0
  88. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/scripts.js +0 -0
  89. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/send_message.js +0 -0
  90. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/set_mode.js +0 -0
  91. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/set_model.js +0 -0
  92. /package/providers/_builtin/ide/cursor/scripts/{0.49.bak → 1.0}/switch_session.js +0 -0
@@ -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
- }
@@ -1,42 +0,0 @@
1
- /**
2
- * Cursor — list_sessions
3
- *
4
- * 사이드바 셀 목록에서 세션 파싱:
5
- * 셀: .agent-sidebar-cell
6
- * 제목: .agent-sidebar-cell-text
7
- * 선택 상태: data-selected="true"
8
- * 활성 ID: [data-composer-id]에서 추출
9
- *
10
- * → { sessions: [{ id, title, active, index }] }
11
- */
12
- (() => {
13
- try {
14
- const sessions = [];
15
- const cells = [...document.querySelectorAll('.agent-sidebar-cell')];
16
- const activeComposer = document.querySelector('[data-composer-id]');
17
- const activeId = activeComposer?.getAttribute('data-composer-id') || null;
18
- cells.forEach((cell, i) => {
19
- const titleEl = cell.querySelector('.agent-sidebar-cell-text');
20
- const title = titleEl?.textContent?.trim() || 'Untitled';
21
- const isSelected = cell.getAttribute('data-selected') === 'true';
22
- sessions.push({
23
- id: isSelected && activeId ? activeId : 'sidebar-' + i,
24
- title,
25
- active: isSelected,
26
- index: i,
27
- });
28
- });
29
- // If no sidebar cells, fallback to current composer
30
- if (sessions.length === 0 && activeComposer) {
31
- sessions.push({
32
- id: activeId,
33
- title: document.title.split(' — ')[0],
34
- active: true,
35
- index: 0,
36
- });
37
- }
38
- return JSON.stringify({ sessions });
39
- } catch(e) {
40
- return JSON.stringify({ sessions: [], error: e.message });
41
- }
42
- })()
@@ -1,79 +0,0 @@
1
- /**
2
- * Cursor — read_chat
3
- *
4
- * DOM 구조 (v0.49):
5
- * 컴포저: [data-composer-id] + [data-composer-status]
6
- * 메시지 쌍: .composer-human-ai-pair-container
7
- * 사용자: .composer-human-message
8
- * AI: direct children after first (tool/assistant)
9
- * 입력: .aislash-editor-input[contenteditable="true"]
10
- * 승인: .run-command-review-active + button/cursor-pointer 요소
11
- *
12
- * → { id, status, title, messages[], inputContent, activeModal }
13
- */
14
- (() => {
15
- try {
16
- const c = document.querySelector('[data-composer-id]');
17
- const id = c?.getAttribute('data-composer-id') || 'active';
18
- const rawStatus = c?.getAttribute('data-composer-status') || 'idle';
19
- let status = rawStatus;
20
- if (rawStatus === 'thinking' || rawStatus === 'streaming') status = 'generating';
21
- else if (rawStatus === 'completed' || rawStatus === 'idle' || !rawStatus) status = 'idle';
22
-
23
- // Detect approval dialogs
24
- let activeModal = null;
25
-
26
- // Primary signal: Cursor uses .run-command-review-active on conversations container
27
- const reviewActive = !!document.querySelector('.run-command-review-active');
28
-
29
- // Also check clickable elements (Cursor uses divs with cursor-pointer, not buttons)
30
- // Note: Cursor concatenates button text with shortcut key labels (e.g. "SkipEsc", "Run⏎")
31
- const clickableEls = [...document.querySelectorAll('button, [role="button"], .cursor-pointer')].filter(b =>
32
- b.offsetWidth > 0 && /^(accept|reject|approve|deny|run|skip|allow|cancel)/i.test((b.textContent || b.getAttribute('aria-label') || '').trim())
33
- );
34
-
35
- if (reviewActive || clickableEls.length > 0) {
36
- status = 'waiting_approval';
37
- const reviewContainer = document.querySelector('.run-command-review-active');
38
- const renderedMsgs = reviewContainer?.querySelectorAll('.composer-rendered-message');
39
- const lastRendered = renderedMsgs?.length ? renderedMsgs[renderedMsgs.length - 1] : null;
40
- const toolMsg = lastRendered || reviewContainer?.querySelector('.composer-tool-former-message:last-of-type');
41
- activeModal = {
42
- message: toolMsg?.textContent?.trim()?.substring(0, 200) || 'Command approval required',
43
- buttons: clickableEls.map(b => b.textContent.trim().replace(/[⏎↵]/g, '').trim()).filter(Boolean),
44
- };
45
- }
46
-
47
- const msgs = [];
48
- document.querySelectorAll('.composer-human-ai-pair-container').forEach((p, i) => {
49
- if (p.children.length === 0) return; // skip virtual-scroll placeholders
50
- const h = p.querySelector('.composer-human-message');
51
- if (h) {
52
- const userText = (h.innerText || '').trim().substring(0, 6000);
53
- if (userText) msgs.push({ role: 'user', content: userText, index: msgs.length });
54
- }
55
- // Iterate direct children after the first (user message block)
56
- for (let ci = 1; ci < p.children.length; ci++) {
57
- const b = p.children[ci];
58
- if ((b.className || '').includes('opacity-50')) continue;
59
- const t = (b.innerText || '').trim();
60
- if (t.length < 2) continue;
61
- // Filter noise: "Thought for Xs", "Explored N files", step group timing headers (e.g. "Crafting a minimal response\n1s")
62
- if (/^Thought\nfor \d+s?$/i.test(t) || /^Explored\n/i.test(t)) continue;
63
- if (/^.{1,80}\n\d+s$/.test(t) && !t.includes('\n\n')) continue; // step-group collapsible header with timing
64
- // Skip step-group collapsible headers (e.g. "Crafting a minimal response\n1s")
65
- if (b.querySelector('.ui-step-group-collapsible, .ui-collapsible-header') &&
66
- !b.querySelector('.composer-rendered-message, .composer-tool-former-message, .composer-diff-block')) continue;
67
- const hasTool = b.querySelector('.composer-tool-former-message, .composer-diff-block, .composer-code-block-container');
68
- msgs.push({ role: hasTool ? 'tool' : 'assistant', content: t.substring(0, 6000), index: msgs.length });
69
- }
70
- });
71
- const inputEl = document.querySelector('.aislash-editor-input[contenteditable="true"]');
72
- const inputContent = inputEl?.textContent?.trim() || '';
73
- const titleParts = document.title.split(' — ');
74
- const projectTitle = (titleParts.length >= 2 ? titleParts[titleParts.length - 2] : titleParts[0] || '').trim();
75
- return JSON.stringify({ id, status, title: projectTitle, messages: msgs, inputContent, activeModal });
76
- } catch(e) {
77
- return JSON.stringify({ id: '', status: 'error', messages: [] });
78
- }
79
- })()
@@ -1,19 +0,0 @@
1
- /**
2
- * Cursor — resolve_action
3
- *
4
- * 승인/거부 버튼 찾기 + 클릭:
5
- * button, [role="button"], .cursor-pointer 중 텍스트 매칭
6
- * Cursor는 단축키 라벨을 붙임 (e.g. "Run⏎", "SkipEsc") → ⏎↵ 제거 후 비교
7
- *
8
- * params.buttonText: string — 찾을 버튼 텍스트
9
- * → { resolved: true/false, clicked?, available? }
10
- */
11
- (params) => {
12
- try {
13
- const btns = [...document.querySelectorAll('button, [role="button"], .cursor-pointer')].filter(b => b.offsetWidth > 0);
14
- const searchText = (params.buttonText || '').toLowerCase();
15
- const target = btns.find(b => (b.textContent||'').trim().replace(/[⏎↵]/g, '').trim().toLowerCase().includes(searchText));
16
- if (target) { target.click(); return JSON.stringify({ resolved: true, clicked: target.textContent.trim() }); }
17
- return JSON.stringify({ resolved: false, available: btns.map(b => b.textContent.trim()).filter(Boolean).slice(0, 15) });
18
- } catch(e) { return JSON.stringify({ resolved: false, error: e.message }); }
19
- }