adhdev 0.4.0 → 0.5.0

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 (150) hide show
  1. package/dist/cli-entrypoint.js +7216 -5706
  2. package/dist/cli-entrypoint.js.map +1 -1
  3. package/dist/index.js +7199 -5688
  4. package/dist/index.js.map +1 -1
  5. package/package.json +2 -2
  6. package/providers/_builtin/COMPATIBILITY.md +0 -217
  7. package/providers/_builtin/CONTRIBUTING.md +0 -141
  8. package/providers/_builtin/README.md +0 -51
  9. package/providers/_builtin/_helpers/index.js +0 -188
  10. package/providers/_builtin/acp/agentpool/provider.json +0 -54
  11. package/providers/_builtin/acp/amp/provider.json +0 -52
  12. package/providers/_builtin/acp/auggie/provider.json +0 -57
  13. package/providers/_builtin/acp/autodev/provider.json +0 -54
  14. package/providers/_builtin/acp/autohand/provider.json +0 -52
  15. package/providers/_builtin/acp/blackbox-ai/provider.json +0 -54
  16. package/providers/_builtin/acp/claude-agent/provider.json +0 -57
  17. package/providers/_builtin/acp/cline-acp/provider.json +0 -54
  18. package/providers/_builtin/acp/codebuddy/provider.json +0 -54
  19. package/providers/_builtin/acp/codex-cli/provider.json +0 -57
  20. package/providers/_builtin/acp/corust-agent/provider.json +0 -52
  21. package/providers/_builtin/acp/crow-cli/provider.json +0 -54
  22. package/providers/_builtin/acp/cursor-acp/provider.json +0 -54
  23. package/providers/_builtin/acp/deepagents/provider.json +0 -52
  24. package/providers/_builtin/acp/dimcode/provider.json +0 -54
  25. package/providers/_builtin/acp/docker-cagent/provider.json +0 -57
  26. package/providers/_builtin/acp/factory-droid/provider.json +0 -60
  27. package/providers/_builtin/acp/fast-agent/provider.json +0 -52
  28. package/providers/_builtin/acp/gemini-cli/provider.json +0 -114
  29. package/providers/_builtin/acp/github-copilot/provider.json +0 -54
  30. package/providers/_builtin/acp/goose/provider.json +0 -57
  31. package/providers/_builtin/acp/junie/provider.json +0 -52
  32. package/providers/_builtin/acp/kilo/provider.json +0 -54
  33. package/providers/_builtin/acp/kimi-cli/provider.json +0 -57
  34. package/providers/_builtin/acp/minion-code/provider.json +0 -52
  35. package/providers/_builtin/acp/mistral-vibe/provider.json +0 -57
  36. package/providers/_builtin/acp/nova/provider.json +0 -54
  37. package/providers/_builtin/acp/openclaw/provider.json +0 -54
  38. package/providers/_builtin/acp/opencode/provider.json +0 -52
  39. package/providers/_builtin/acp/openhands/provider.json +0 -54
  40. package/providers/_builtin/acp/pi-acp/provider.json +0 -52
  41. package/providers/_builtin/acp/qoder/provider.json +0 -54
  42. package/providers/_builtin/acp/qwen-code/provider.json +0 -60
  43. package/providers/_builtin/acp/stakpak/provider.json +0 -54
  44. package/providers/_builtin/acp/vtcode/provider.json +0 -54
  45. package/providers/_builtin/cli/claude-cli/provider.json +0 -100
  46. package/providers/_builtin/cli/codex-cli/provider.json +0 -89
  47. package/providers/_builtin/cli/gemini-cli/provider.json +0 -93
  48. package/providers/_builtin/docs/CDP_SELECTOR_GUIDE.md +0 -370
  49. package/providers/_builtin/docs/PROVIDER_GUIDE.md +0 -916
  50. package/providers/_builtin/extension/cline/provider.json +0 -35
  51. package/providers/_builtin/extension/cline/scripts/focus_editor.js +0 -48
  52. package/providers/_builtin/extension/cline/scripts/list_chats.js +0 -100
  53. package/providers/_builtin/extension/cline/scripts/list_models.js +0 -43
  54. package/providers/_builtin/extension/cline/scripts/list_modes.js +0 -35
  55. package/providers/_builtin/extension/cline/scripts/new_session.js +0 -85
  56. package/providers/_builtin/extension/cline/scripts/open_panel.js +0 -25
  57. package/providers/_builtin/extension/cline/scripts/read_chat.js +0 -257
  58. package/providers/_builtin/extension/cline/scripts/resolve_action.js +0 -83
  59. package/providers/_builtin/extension/cline/scripts/send_message.js +0 -95
  60. package/providers/_builtin/extension/cline/scripts/set_mode.js +0 -36
  61. package/providers/_builtin/extension/cline/scripts/set_model.js +0 -36
  62. package/providers/_builtin/extension/cline/scripts/switch_session.js +0 -206
  63. package/providers/_builtin/extension/cline/scripts.js +0 -73
  64. package/providers/_builtin/extension/roo-code/provider.json +0 -35
  65. package/providers/_builtin/extension/roo-code/scripts.js +0 -659
  66. package/providers/_builtin/ide/antigravity/provider.json +0 -63
  67. package/providers/_builtin/ide/antigravity/scripts/focus_editor.js +0 -20
  68. package/providers/_builtin/ide/antigravity/scripts/legacy/list_models.js +0 -38
  69. package/providers/_builtin/ide/antigravity/scripts/legacy/list_modes.js +0 -48
  70. package/providers/_builtin/ide/antigravity/scripts/legacy/scripts.js +0 -64
  71. package/providers/_builtin/ide/antigravity/scripts/legacy/set_mode.js +0 -34
  72. package/providers/_builtin/ide/antigravity/scripts/legacy/set_model.js +0 -47
  73. package/providers/_builtin/ide/antigravity/scripts/list_chats.js +0 -137
  74. package/providers/_builtin/ide/antigravity/scripts/list_models.js +0 -61
  75. package/providers/_builtin/ide/antigravity/scripts/list_modes.js +0 -72
  76. package/providers/_builtin/ide/antigravity/scripts/new_session.js +0 -75
  77. package/providers/_builtin/ide/antigravity/scripts/read_chat.js +0 -262
  78. package/providers/_builtin/ide/antigravity/scripts/resolve_action.js +0 -68
  79. package/providers/_builtin/ide/antigravity/scripts/send_message.js +0 -56
  80. package/providers/_builtin/ide/antigravity/scripts/set_mode.js +0 -67
  81. package/providers/_builtin/ide/antigravity/scripts/set_model.js +0 -72
  82. package/providers/_builtin/ide/antigravity/scripts/switch_session.js +0 -114
  83. package/providers/_builtin/ide/antigravity/scripts.js +0 -67
  84. package/providers/_builtin/ide/cursor/provider.json +0 -59
  85. package/providers/_builtin/ide/cursor/scripts.js +0 -458
  86. package/providers/_builtin/ide/kiro/provider.json +0 -60
  87. package/providers/_builtin/ide/kiro/scripts/focus_editor.js +0 -20
  88. package/providers/_builtin/ide/kiro/scripts/open_panel.js +0 -47
  89. package/providers/_builtin/ide/kiro/scripts/resolve_action.js +0 -54
  90. package/providers/_builtin/ide/kiro/scripts/send_message.js +0 -29
  91. package/providers/_builtin/ide/kiro/scripts/webview_list_models.js +0 -39
  92. package/providers/_builtin/ide/kiro/scripts/webview_list_modes.js +0 -39
  93. package/providers/_builtin/ide/kiro/scripts/webview_list_sessions.js +0 -21
  94. package/providers/_builtin/ide/kiro/scripts/webview_new_session.js +0 -34
  95. package/providers/_builtin/ide/kiro/scripts/webview_read_chat.js +0 -68
  96. package/providers/_builtin/ide/kiro/scripts/webview_send_message.js +0 -72
  97. package/providers/_builtin/ide/kiro/scripts/webview_set_mode.js +0 -15
  98. package/providers/_builtin/ide/kiro/scripts/webview_set_model.js +0 -15
  99. package/providers/_builtin/ide/kiro/scripts/webview_switch_session.js +0 -26
  100. package/providers/_builtin/ide/kiro/scripts.js +0 -62
  101. package/providers/_builtin/ide/pearai/provider.json +0 -60
  102. package/providers/_builtin/ide/pearai/scripts/focus_editor.js +0 -20
  103. package/providers/_builtin/ide/pearai/scripts/list_sessions.js +0 -38
  104. package/providers/_builtin/ide/pearai/scripts/new_session.js +0 -55
  105. package/providers/_builtin/ide/pearai/scripts/open_panel.js +0 -46
  106. package/providers/_builtin/ide/pearai/scripts/resolve_action.js +0 -54
  107. package/providers/_builtin/ide/pearai/scripts/send_message.js +0 -29
  108. package/providers/_builtin/ide/pearai/scripts/webview_list_models.js +0 -43
  109. package/providers/_builtin/ide/pearai/scripts/webview_list_modes.js +0 -35
  110. package/providers/_builtin/ide/pearai/scripts/webview_list_sessions.js +0 -62
  111. package/providers/_builtin/ide/pearai/scripts/webview_new_session.js +0 -49
  112. package/providers/_builtin/ide/pearai/scripts/webview_read_chat.js +0 -92
  113. package/providers/_builtin/ide/pearai/scripts/webview_resolve_action.js +0 -59
  114. package/providers/_builtin/ide/pearai/scripts/webview_send_message.js +0 -72
  115. package/providers/_builtin/ide/pearai/scripts/webview_set_mode.js +0 -36
  116. package/providers/_builtin/ide/pearai/scripts/webview_set_model.js +0 -36
  117. package/providers/_builtin/ide/pearai/scripts/webview_switch_session.js +0 -34
  118. package/providers/_builtin/ide/pearai/scripts.js +0 -74
  119. package/providers/_builtin/ide/trae/provider.json +0 -59
  120. package/providers/_builtin/ide/trae/scripts/focus_editor.js +0 -20
  121. package/providers/_builtin/ide/trae/scripts/list_chats.js +0 -24
  122. package/providers/_builtin/ide/trae/scripts/list_models.js +0 -39
  123. package/providers/_builtin/ide/trae/scripts/list_modes.js +0 -39
  124. package/providers/_builtin/ide/trae/scripts/new_session.js +0 -30
  125. package/providers/_builtin/ide/trae/scripts/open_panel.js +0 -44
  126. package/providers/_builtin/ide/trae/scripts/read_chat.js +0 -113
  127. package/providers/_builtin/ide/trae/scripts/resolve_action.js +0 -54
  128. package/providers/_builtin/ide/trae/scripts/send_message.js +0 -69
  129. package/providers/_builtin/ide/trae/scripts/set_mode.js +0 -15
  130. package/providers/_builtin/ide/trae/scripts/set_model.js +0 -15
  131. package/providers/_builtin/ide/trae/scripts/switch_session.js +0 -23
  132. package/providers/_builtin/ide/trae/scripts.js +0 -57
  133. package/providers/_builtin/ide/vscode/provider.json +0 -57
  134. package/providers/_builtin/ide/vscode-insiders/provider.json +0 -55
  135. package/providers/_builtin/ide/vscodium/provider.json +0 -56
  136. package/providers/_builtin/ide/windsurf/provider.json +0 -46
  137. package/providers/_builtin/ide/windsurf/scripts/focus_editor.js +0 -30
  138. package/providers/_builtin/ide/windsurf/scripts/list_chats.js +0 -117
  139. package/providers/_builtin/ide/windsurf/scripts/list_models.js +0 -39
  140. package/providers/_builtin/ide/windsurf/scripts/list_modes.js +0 -39
  141. package/providers/_builtin/ide/windsurf/scripts/new_session.js +0 -69
  142. package/providers/_builtin/ide/windsurf/scripts/open_panel.js +0 -58
  143. package/providers/_builtin/ide/windsurf/scripts/read_chat.js +0 -297
  144. package/providers/_builtin/ide/windsurf/scripts/resolve_action.js +0 -68
  145. package/providers/_builtin/ide/windsurf/scripts/send_message.js +0 -87
  146. package/providers/_builtin/ide/windsurf/scripts/set_mode.js +0 -15
  147. package/providers/_builtin/ide/windsurf/scripts/set_model.js +0 -15
  148. package/providers/_builtin/ide/windsurf/scripts/switch_session.js +0 -58
  149. package/providers/_builtin/ide/windsurf/scripts.js +0 -57
  150. package/providers/_builtin/validate.js +0 -156
@@ -1,63 +0,0 @@
1
- {
2
- "type": "antigravity",
3
- "name": "Antigravity",
4
- "category": "ide",
5
- "displayName": "Antigravity",
6
- "icon": "🚀",
7
- "cli": "antigravity",
8
- "cdpPorts": [
9
- 9335,
10
- 9336
11
- ],
12
- "processNames": {
13
- "darwin": "Antigravity",
14
- "win32": [
15
- "Antigravity.exe"
16
- ]
17
- },
18
- "paths": {
19
- "darwin": [
20
- "/Applications/Antigravity.app"
21
- ],
22
- "win32": [
23
- "C:\\Users\\*\\AppData\\Local\\Programs\\antigravity\\Antigravity.exe"
24
- ],
25
- "linux": [
26
- "/opt/Antigravity",
27
- "/usr/share/antigravity"
28
- ]
29
- },
30
- "inputMethod": "cdp-type-and-send",
31
- "inputSelector": "[contenteditable=\"true\"][role=\"textbox\"]",
32
- "versionCommand": "antigravity --version",
33
- "testedVersions": ["1.107.0"],
34
- "versions": {
35
- "< 1.107.0": {
36
- "__dir": "scripts/legacy"
37
- }
38
- },
39
- "settings": {
40
- "approvalAlert": {
41
- "type": "boolean",
42
- "default": true,
43
- "public": true,
44
- "label": "Approval Notifications",
45
- "description": "Show notification when approval is needed"
46
- },
47
- "longGeneratingAlert": {
48
- "type": "boolean",
49
- "default": true,
50
- "public": true,
51
- "label": "Long Generation Alert",
52
- "description": "Alert when generation takes too long"
53
- },
54
- "longGeneratingThresholdSec": {
55
- "type": "number",
56
- "default": 180,
57
- "public": true,
58
- "label": "Long Generation Threshold (sec)",
59
- "min": 30,
60
- "max": 600
61
- }
62
- }
63
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * Cursor v1 — focus_editor
3
- *
4
- * CURSOR.md 4-5: 셀렉터 우선순위
5
- * [contenteditable="true"][role="textbox"]
6
- * → .chat-input textarea
7
- * → .composer-input
8
- * → textarea
9
- *
10
- * 최종 확인: 2026-03-06
11
- */
12
- (() => {
13
- const editor = document.querySelector('[contenteditable="true"][role="textbox"]')
14
- || document.querySelector('.chat-input textarea')
15
- || document.querySelector('.composer-input')
16
- || document.querySelector('textarea.native-input')
17
- || document.querySelector('textarea');
18
- if (editor) { editor.focus(); return 'focused'; }
19
- return 'no editor found';
20
- })()
@@ -1,38 +0,0 @@
1
- /**
2
- * Antigravity — list_models
3
- * antigravity-agent-side-panel 내부 모델 드롭다운에서 목록 + 현재 모델 추출
4
- * → { models: string[], current: string }
5
- */
6
- (() => {
7
- try {
8
- const models = [];
9
- let current = '';
10
-
11
- // 1. 모델 항목에서 목록 추출
12
- // 셀렉터: .px-2.py-1.flex.items-center.justify-between.cursor-pointer
13
- const items = document.querySelectorAll('.px-2.py-1.flex.items-center.justify-between.cursor-pointer');
14
- for (const item of items) {
15
- const label = item.querySelector('.text-xs.font-medium');
16
- const text = (label || item).textContent?.trim();
17
- if (!text || text.length > 60) continue;
18
- // 모델명 검증 (Claude, Gemini, GPT, etc.)
19
- models.push(text);
20
- // 선택된 항목: bg-gray-500/20
21
- if ((item.className || '').includes('bg-gray-500/20')) {
22
- current = text;
23
- }
24
- }
25
-
26
- // 2. 모델 목록이 없으면 (드롭다운 닫힘) → 트리거 버튼에서 현재 모델만
27
- if (models.length === 0) {
28
- const trigger = document.querySelector('.flex.min-w-0.max-w-full.cursor-pointer.items-center');
29
- if (trigger) {
30
- current = trigger.textContent?.trim() || '';
31
- }
32
- }
33
-
34
- return JSON.stringify({ models, current });
35
- } catch (e) {
36
- return JSON.stringify({ models: [], current: '', error: e.message });
37
- }
38
- })()
@@ -1,48 +0,0 @@
1
- /**
2
- * Antigravity — list_modes
3
- * Conversation mode: Planning / Fast 세그먼트 컨트롤
4
- * inputBox 근처의 "Conversation mode" 패널에서 읽기
5
- * → { modes: string[], current: string }
6
- */
7
- (() => {
8
- try {
9
- const modes = [];
10
- let current = '';
11
-
12
- // "Conversation mode" 헤더를 포함하는 패널 찾기
13
- const headers = document.querySelectorAll('.text-xs.px-2.pb-1.opacity-80');
14
- for (const header of headers) {
15
- if (header.textContent?.trim() === 'Conversation mode') {
16
- // 형제 요소들에서 모드 항목 추출
17
- const parent = header.parentElement;
18
- if (!parent) continue;
19
- const items = parent.querySelectorAll('.font-medium');
20
- for (const item of items) {
21
- const text = item.textContent?.trim();
22
- if (text && text.length < 20) {
23
- modes.push(text);
24
- }
25
- }
26
- break;
27
- }
28
- }
29
-
30
- // 현재 모드: Fast 버튼의 텍스트 (현재 활성 모드 표시)
31
- const modeBtn = [...document.querySelectorAll('button')].find(b => {
32
- const cls = b.className || '';
33
- return cls.includes('py-1') && cls.includes('pl-1') && cls.includes('pr-2') && b.offsetWidth > 0;
34
- });
35
- if (modeBtn) {
36
- current = modeBtn.textContent?.trim() || '';
37
- }
38
-
39
- // modes가 비어있으면 기본값
40
- if (modes.length === 0) {
41
- modes.push('Planning', 'Fast');
42
- }
43
-
44
- return JSON.stringify({ modes, current });
45
- } catch (e) {
46
- return JSON.stringify({ modes: [], current: '', error: e.message });
47
- }
48
- })()
@@ -1,64 +0,0 @@
1
- /**
2
- * Antigravity CDP Scripts — legacy (< 1.107.0)
3
- * DOM uses exact CSS class selectors (original Tailwind classes without arbitrary values)
4
- */
5
-
6
- 'use strict';
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
- const DIR = __dirname; // scripts/legacy/
11
-
12
- function load(name) {
13
- try { return fs.readFileSync(path.join(DIR, name), 'utf-8'); }
14
- catch { return null; }
15
- }
16
-
17
- // Non-model/mode scripts fall back to parent scripts/
18
- const PARENT_DIR = path.join(DIR, '..');
19
- function loadParent(name) {
20
- try { return fs.readFileSync(path.join(PARENT_DIR, name), 'utf-8'); }
21
- catch { return null; }
22
- }
23
-
24
- module.exports.readChat = () => loadParent('read_chat.js');
25
- module.exports.focusEditor = () => loadParent('focus_editor.js');
26
- module.exports.listSessions = () => loadParent('list_chats.js');
27
- module.exports.newSession = () => loadParent('new_session.js');
28
- module.exports.listModels = () => load('list_models.js');
29
- module.exports.listModes = () => load('list_modes.js');
30
-
31
- module.exports.sendMessage = (text) => {
32
- const script = loadParent('send_message.js');
33
- if (!script) return null;
34
- return script.replace(/\$\{\s*MESSAGE\s*\}/g, JSON.stringify(text));
35
- };
36
-
37
- module.exports.switchSession = (sessionId) => {
38
- const script = loadParent('switch_session.js');
39
- if (!script) return null;
40
- return script.replace(/\$\{\s*SESSION_ID\s*\}/g, JSON.stringify(sessionId));
41
- };
42
-
43
- module.exports.resolveAction = (params) => {
44
- const action = typeof params === 'string' ? params : params?.action || 'approve';
45
- const buttonText = params?.button || params?.buttonText
46
- || (action === 'approve' ? 'Accept' : action === 'reject' ? 'Reject' : action);
47
- const script = loadParent('resolve_action.js');
48
- if (!script) return null;
49
- return script.replace(/\$\{\s*BUTTON_TEXT\s*\}/g, JSON.stringify(buttonText));
50
- };
51
-
52
- module.exports.setModel = (params) => {
53
- const model = typeof params === 'string' ? params : params?.model;
54
- const script = load('set_model.js');
55
- if (!script) return null;
56
- return script.replace(/\$\{\s*MODEL\s*\}/g, JSON.stringify(model));
57
- };
58
-
59
- module.exports.setMode = (params) => {
60
- const mode = typeof params === 'string' ? params : params?.mode;
61
- const script = load('set_mode.js');
62
- if (!script) return null;
63
- return script.replace(/\$\{\s*MODE\s*\}/g, JSON.stringify(mode));
64
- };
@@ -1,34 +0,0 @@
1
- /**
2
- * Antigravity — set_mode
3
- * Conversation mode 패널에서 Planning/Fast 클릭
4
- * ${MODE} → JSON.stringify(modeName)
5
- * → { success: boolean, mode?: string }
6
- */
7
- (async () => {
8
- try {
9
- const target = ${MODE};
10
-
11
- // "Conversation mode" 헤더의 부모에서 .font-medium 항목 찾기
12
- const headers = document.querySelectorAll('.text-xs.px-2.pb-1.opacity-80');
13
- for (const header of headers) {
14
- if (header.textContent?.trim() === 'Conversation mode') {
15
- const parent = header.parentElement;
16
- if (!parent) continue;
17
- const items = parent.querySelectorAll('.font-medium');
18
- for (const item of items) {
19
- const text = item.textContent?.trim();
20
- if (text && text.toLowerCase() === target.toLowerCase()) {
21
- item.click();
22
- await new Promise(r => setTimeout(r, 300));
23
- return JSON.stringify({ success: true, mode: text });
24
- }
25
- }
26
- break;
27
- }
28
- }
29
-
30
- return JSON.stringify({ success: false, error: 'mode not found: ' + target });
31
- } catch (e) {
32
- return JSON.stringify({ success: false, error: e.message });
33
- }
34
- })()
@@ -1,47 +0,0 @@
1
- /**
2
- * Antigravity — set_model
3
- * antigravity-agent-side-panel 모델 드롭다운에서 모델 선택
4
- * ${MODEL} → JSON.stringify(modelName)
5
- * → { success: boolean, model?: string }
6
- */
7
- (async () => {
8
- try {
9
- const target = ${MODEL};
10
-
11
- // 1. 모델 드롭다운이 열려 있는 경우 → 직접 선택
12
- const items = document.querySelectorAll('.px-2.py-1.flex.items-center.justify-between.cursor-pointer');
13
- for (const item of items) {
14
- const label = item.querySelector('.text-xs.font-medium');
15
- const text = (label || item).textContent?.trim();
16
- if (text && (text === target || text.toLowerCase().includes(target.toLowerCase()))) {
17
- item.click();
18
- await new Promise(r => setTimeout(r, 200));
19
- return JSON.stringify({ success: true, model: text });
20
- }
21
- }
22
-
23
- // 2. 드롭다운이 닫혀 있으면 → 트리거 버튼 클릭해서 열기
24
- const trigger = document.querySelector('.flex.min-w-0.max-w-full.cursor-pointer.items-center');
25
- if (trigger) {
26
- trigger.click();
27
- await new Promise(r => setTimeout(r, 400));
28
-
29
- // 다시 항목 탐색
30
- const newItems = document.querySelectorAll('.px-2.py-1.flex.items-center.justify-between.cursor-pointer');
31
- for (const item of newItems) {
32
- const label = item.querySelector('.text-xs.font-medium');
33
- const text = (label || item).textContent?.trim();
34
- if (text && (text === target || text.toLowerCase().includes(target.toLowerCase()))) {
35
- item.click();
36
- return JSON.stringify({ success: true, model: text });
37
- }
38
- }
39
- // 못 찾으면 드롭다운 닫기
40
- trigger.click();
41
- }
42
-
43
- return JSON.stringify({ success: false, error: 'model not found: ' + target });
44
- } catch (e) {
45
- return JSON.stringify({ success: false, error: e.message });
46
- }
47
- })()
@@ -1,137 +0,0 @@
1
- /**
2
- * Antigravity v1 — list_chats (v3 — 강화된 셀렉터)
3
- *
4
- * 히스토리 토글을 클릭하여 대화 목록 패널을 열고,
5
- * DOM에서 직접 대화 목록을 파싱한 뒤 패널을 닫고 결과를 반환.
6
- *
7
- * DOM 구조 (2026-03-03 확인):
8
- * 토글: [data-past-conversations-toggle="true"]
9
- * 패널: input[placeholder="Select a conversation"] 근처
10
- * 섹션 헤더: .opacity-50 텍스트 (Current, Recent, Other)
11
- * 행: .cursor-pointer.justify-between.rounded-md
12
- * ├── 제목: span > span
13
- * ├── 워크스페이스: .opacity-50.truncate > span
14
- * └── 시간: .opacity-50.flex-shrink-0
15
- */
16
- (async () => {
17
- const sleep = (ms) => new Promise(r => setTimeout(r, ms));
18
-
19
- try {
20
- // 1. 토글 클릭하여 히스토리 패널 열기
21
- const toggle = document.querySelector('[data-past-conversations-toggle="true"]');
22
- if (!toggle) return [];
23
- toggle.click();
24
- await sleep(1000);
25
-
26
- // 2. 정확한 검색 input 찾기 (placeholder 정확 매칭)
27
- const allInputs = document.querySelectorAll('input[type="text"]');
28
- let searchInput = null;
29
- for (const inp of allInputs) {
30
- if (inp.placeholder === 'Select a conversation' && inp.offsetWidth > 0) {
31
- searchInput = inp;
32
- break;
33
- }
34
- }
35
-
36
- if (!searchInput) {
37
- document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true }));
38
- return [];
39
- }
40
-
41
- // 3. "Current" 텍스트를 기준으로 대화 목록 스크롤 컨테이너 찾기
42
- let container = null;
43
- const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);
44
- while (walker.nextNode()) {
45
- if (walker.currentNode.textContent.trim() === 'Current') {
46
- // "Current" 텍스트의 조상 — overflow-auto/scroll이 있는 스크롤 컨테이너까지 올라감
47
- let el = walker.currentNode.parentElement;
48
- for (let i = 0; i < 10 && el; i++) {
49
- const cls = (el.className || '');
50
- if (typeof cls === 'string' && (cls.includes('overflow-auto') || cls.includes('overflow-y-scroll'))) {
51
- container = el;
52
- break;
53
- }
54
- el = el.parentElement;
55
- }
56
- // overflow 컨테이너 못 찾으면 행이 가장 많은 조상 사용
57
- if (!container) {
58
- el = walker.currentNode.parentElement;
59
- let bestEl = null;
60
- let bestCount = 0;
61
- for (let i = 0; i < 8 && el; i++) {
62
- const rows = el.querySelectorAll('[class*="cursor-pointer"][class*="justify-between"][class*="rounded-md"]');
63
- if (rows.length > bestCount) {
64
- bestCount = rows.length;
65
- bestEl = el;
66
- }
67
- el = el.parentElement;
68
- }
69
- container = bestEl;
70
- }
71
- if (container) break;
72
- }
73
- }
74
-
75
- // 폴백: "Current" 텍스트가 없을 때 (새 대화 직후 등) searchInput 기반
76
- if (!container && searchInput) {
77
- let el = searchInput.parentElement;
78
- for (let i = 0; i < 10 && el; i++) {
79
- const cls = (el.className || '');
80
- if (typeof cls === 'string' && (cls.includes('overflow-auto') || cls.includes('overflow-y-scroll'))) {
81
- container = el; break;
82
- }
83
- const rows = el.querySelectorAll('[class*="cursor-pointer"][class*="justify-between"][class*="rounded-md"]');
84
- if (rows.length > 0 && !container) {
85
- container = el;
86
- }
87
- el = el.parentElement;
88
- }
89
- }
90
-
91
- if (!container) {
92
- document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true }));
93
- return [];
94
- }
95
-
96
- // 4. 대화 행 파싱
97
- const rows = container.querySelectorAll('[class*="cursor-pointer"][class*="justify-between"][class*="rounded-md"]');
98
- const chats = [];
99
-
100
- for (const row of rows) {
101
- const titleEl = row.querySelector('span span');
102
- const title = titleEl ? titleEl.textContent.trim() : '';
103
- if (!title) continue;
104
-
105
- const timeEl = row.querySelector('span[class*="opacity-50"][class*="flex-shrink-0"]');
106
- const time = timeEl ? timeEl.textContent.trim() : '';
107
-
108
- const wsEl = row.querySelector('span[class*="opacity-50"][class*="truncate"] span');
109
- const workspace = wsEl ? wsEl.textContent.trim() : '';
110
-
111
- const isCurrent = (row.className || '').includes('focusBackground');
112
-
113
- let section = '';
114
- const sectionHeader = row.parentElement?.querySelector('[class*="opacity-50"]:not([class*="cursor-pointer"])');
115
- if (sectionHeader) {
116
- section = sectionHeader.textContent.trim();
117
- }
118
-
119
- chats.push({
120
- id: title,
121
- title,
122
- status: isCurrent ? 'current' : '',
123
- time,
124
- workspace,
125
- section,
126
- });
127
- }
128
-
129
- // 5. 패널 닫기
130
- document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true }));
131
-
132
- return chats;
133
- } catch (e) {
134
- try { document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true })); } catch (_) { }
135
- return [];
136
- }
137
- })()
@@ -1,61 +0,0 @@
1
- /**
2
- * Antigravity — list_models
3
- * 모델 드롭다운 트리거 버튼 + 항목 목록 추출
4
- *
5
- * Version compatibility:
6
- * v0 (old): .flex.min-w-0.max-w-full.cursor-pointer.items-center (exact CSS selector works)
7
- * v1 (new): Tailwind arbitrary values (pl-[0.125rem]) — must use partial class matching
8
- * Both: dropdown items use .px-2.py-1.flex.items-center.justify-between.cursor-pointer
9
- *
10
- * → { models: string[], current: string }
11
- */
12
- (() => {
13
- try {
14
- const models = [];
15
- let current = '';
16
-
17
- // ── Step 1: Dropdown open state — extract item list ──────────────────
18
- // Selector works for both v0 and v1 (hover class changed but cursor-pointer persists)
19
- const items = document.querySelectorAll('.px-2.py-1.flex.items-center.justify-between.cursor-pointer');
20
- for (const item of items) {
21
- const label = item.querySelector('.text-xs.font-medium');
22
- const text = (label || item).textContent?.trim();
23
- if (!text || text.length > 60) continue;
24
- models.push(text);
25
- // Selected item: bg-gray-500/20 (both v0 & v1)
26
- if ((item.className || '').includes('bg-gray-500/20')) {
27
- current = text;
28
- }
29
- }
30
-
31
- // ── Step 2: Dropdown closed — extract current model from trigger ──────
32
- if (models.length === 0) {
33
- // v0: exact class match works
34
- let trigger = document.querySelector('.flex.min-w-0.max-w-full.cursor-pointer.items-center');
35
-
36
- // v1: arbitrary Tailwind classes → partial matching
37
- if (!trigger || trigger.offsetWidth === 0) {
38
- trigger = [...document.querySelectorAll('div, button')].find(e => {
39
- const cls = e.className || '';
40
- return cls.includes('min-w-0') &&
41
- cls.includes('max-w-full') &&
42
- cls.includes('cursor-pointer') &&
43
- cls.includes('items-center') &&
44
- e.offsetWidth > 0;
45
- }) || null;
46
- }
47
-
48
- if (trigger) {
49
- // v0: .text-xs.font-medium span / v1: .text-xs span with opacity-70
50
- const span = trigger.querySelector('.text-xs.font-medium') ||
51
- trigger.querySelector('span.text-xs') ||
52
- trigger;
53
- current = span.textContent?.trim() || '';
54
- }
55
- }
56
-
57
- return JSON.stringify({ models, current });
58
- } catch (e) {
59
- return JSON.stringify({ models: [], current: '', error: e.message });
60
- }
61
- })()
@@ -1,72 +0,0 @@
1
- /**
2
- * Antigravity — list_modes
3
- * 현재 모드 + 사용 가능한 모드 목록 추출
4
- *
5
- * Version compatibility:
6
- * v0 (old): span-based mode button (plain text, no opacity class)
7
- * v1 (new): BUTTON element with py-1 pl-1 pr-2 opacity-70 classes
8
- * Both: "Conversation mode" panel with .font-medium items (when dropdown open)
9
- *
10
- * → { modes: string[], current: string }
11
- */
12
- (() => {
13
- try {
14
- const modes = [];
15
- let current = '';
16
-
17
- // ── Helper: find mode trigger button (v0 + v1 compat) ────────────────
18
- function findModeTrigger() {
19
- // v1: BUTTON with opacity-70 + py-1 pl-1 pr-2
20
- const v1 = [...document.querySelectorAll('button')].find(b => {
21
- const cls = b.className || '';
22
- return cls.includes('py-1') &&
23
- cls.includes('pl-1') &&
24
- cls.includes('pr-2') &&
25
- cls.includes('opacity-70') &&
26
- b.offsetWidth > 0;
27
- });
28
- if (v1) return v1;
29
-
30
- // v0: span/button with py-1 pl-1 pr-2 (without opacity-70)
31
- return [...document.querySelectorAll('button, span')].find(b => {
32
- const cls = b.className || '';
33
- return cls.includes('py-1') &&
34
- cls.includes('pl-1') &&
35
- cls.includes('pr-2') &&
36
- b.offsetWidth > 0 &&
37
- // ensure it's in the model/mode area (not some other button)
38
- (b.textContent?.trim() === 'Fast' || b.textContent?.trim() === 'Planning' || b.textContent?.trim() === 'Normal');
39
- }) || null;
40
- }
41
-
42
- // ── Step 1: "Conversation mode" panel open — extract items ───────────
43
- const headers = document.querySelectorAll('.text-xs.px-2.pb-1.opacity-80');
44
- for (const header of headers) {
45
- if (header.textContent?.trim() === 'Conversation mode') {
46
- const parent = header.parentElement;
47
- if (!parent) continue;
48
- const items = parent.querySelectorAll('.font-medium');
49
- for (const item of items) {
50
- const text = item.textContent?.trim();
51
- if (text && text.length < 20) modes.push(text);
52
- }
53
- break;
54
- }
55
- }
56
-
57
- // ── Step 2: Read current mode from trigger button ─────────────────────
58
- const modeBtn = findModeTrigger();
59
- if (modeBtn) {
60
- current = modeBtn.textContent?.trim() || '';
61
- }
62
-
63
- // ── Fallback: default modes ───────────────────────────────────────────
64
- if (modes.length === 0) {
65
- modes.push('Planning', 'Fast');
66
- }
67
-
68
- return JSON.stringify({ modes, current });
69
- } catch (e) {
70
- return JSON.stringify({ modes: [], current: '', error: e.message });
71
- }
72
- })()
@@ -1,75 +0,0 @@
1
- /**
2
- * Antigravity v1 — new_session
3
- *
4
- * Antigravity Agent 패널 상단의 + 아이콘 클릭으로 새 대화 시작.
5
- *
6
- * DOM 구조:
7
- * .antigravity-agent-side-panel 상단 아이콘 바
8
- * [0] <a> + (Plus) → 새 대화 ← 이것을 클릭
9
- * [1] <a> 히스토리 (data-past-conversations-toggle)
10
- * [2] <div> 더보기 (⋯)
11
- * [3] <a> 닫기 (✕)
12
- *
13
- * 전략:
14
- * 1. 히스토리 토글의 이전 형제 <a> 클릭 (Plus 아이콘)
15
- * 2. SVG path "M12 4.5v15m7.5-7.5h-15" (+ 모양) 찾기
16
- * 3. 패널 상단 첫 번째 <a> 클릭 폴백
17
- *
18
- * 최종 확인: 2026-03-11
19
- */
20
- (() => {
21
- try {
22
- // ─── 1. 히스토리 토글의 이전 형제 요소 (Plus 아이콘) ───
23
- const toggle = document.querySelector('[data-past-conversations-toggle="true"]');
24
- if (toggle) {
25
- const parent = toggle.parentElement;
26
- if (parent) {
27
- const children = Array.from(parent.children).filter(c => c.offsetWidth > 0);
28
- const toggleIdx = children.indexOf(toggle);
29
- // Plus 아이콘은 히스토리 바로 앞
30
- if (toggleIdx > 0) {
31
- const plusBtn = children[toggleIdx - 1];
32
- plusBtn.click();
33
- return 'clicked (sibling of toggle)';
34
- }
35
- }
36
- }
37
-
38
- // ─── 2. SVG path 기반: Plus(+) 모양 SVG ───
39
- const panel = document.querySelector('.antigravity-agent-side-panel') || document.querySelector('#conversation');
40
- if (panel) {
41
- const svgs = panel.querySelectorAll('svg');
42
- for (const svg of svgs) {
43
- const path = svg.querySelector('path');
44
- if (path) {
45
- const d = path.getAttribute('d') || '';
46
- // Plus 아이콘 SVG: 세로선 + 가로선
47
- if (d.includes('v15') && d.includes('h-15')) {
48
- const clickable = svg.closest('a') || svg.closest('button') || svg.parentElement;
49
- if (clickable) {
50
- clickable.click();
51
- return 'clicked (svg plus)';
52
- }
53
- }
54
- }
55
- }
56
- }
57
-
58
- // ─── 3. 폴백: 패널 상단 영역의 첫 번째 <a> ───
59
- if (panel) {
60
- const topLinks = Array.from(panel.querySelectorAll('a')).filter(a => {
61
- const r = a.getBoundingClientRect();
62
- const pr = panel.getBoundingClientRect();
63
- return r.y < pr.y + 30 && a.offsetWidth > 0 && a.offsetWidth < 30;
64
- });
65
- if (topLinks.length > 0) {
66
- topLinks[0].click();
67
- return 'clicked (first top link)';
68
- }
69
- }
70
-
71
- return 'no new session button found';
72
- } catch (e) {
73
- return 'error: ' + e.message;
74
- }
75
- })()