@adhdev/daemon-core 0.6.53 → 0.6.55

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 (164) hide show
  1. package/dist/index.d.ts +76 -34
  2. package/dist/index.js +714 -271
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/providers/_builtin/_helpers/index.js +26 -26
  6. package/providers/_builtin/cli/aider-cli/provider.json +37 -0
  7. package/providers/_builtin/cli/aider-cli/scripts/1.0/detect_status.js +20 -0
  8. package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_approval.js +10 -0
  9. package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_output.js +49 -0
  10. package/providers/_builtin/cli/aider-cli/scripts/1.0/scripts.js +7 -0
  11. package/providers/_builtin/cli/claude-cli/provider.json +9 -2
  12. package/providers/_builtin/cli/claude-cli/scripts/1.0/detect_status.js +31 -0
  13. package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_approval.js +38 -0
  14. package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_output.js +164 -0
  15. package/providers/_builtin/cli/claude-cli/scripts/1.0/scripts.js +42 -0
  16. package/providers/_builtin/cli/codex-cli/provider.json +9 -2
  17. package/providers/_builtin/cli/codex-cli/scripts/1.0/detect_status.js +20 -0
  18. package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_approval.js +15 -0
  19. package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_output.js +68 -0
  20. package/providers/_builtin/cli/codex-cli/scripts/1.0/scripts.js +11 -0
  21. package/providers/_builtin/cli/cursor-cli/provider.json +37 -0
  22. package/providers/_builtin/cli/cursor-cli/scripts/1.0/detect_status.js +19 -0
  23. package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_approval.js +10 -0
  24. package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_output.js +48 -0
  25. package/providers/_builtin/cli/cursor-cli/scripts/1.0/scripts.js +7 -0
  26. package/providers/_builtin/cli/gemini-cli/provider.json +9 -2
  27. package/providers/_builtin/cli/gemini-cli/scripts/1.0/detect_status.js +26 -0
  28. package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_approval.js +22 -0
  29. package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_output.js +71 -0
  30. package/providers/_builtin/cli/gemini-cli/scripts/1.0/scripts.js +12 -0
  31. package/providers/_builtin/cli/github-copilot-cli/provider.json +37 -0
  32. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/detect_status.js +19 -0
  33. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_approval.js +9 -0
  34. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_output.js +48 -0
  35. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/scripts.js +7 -0
  36. package/providers/_builtin/cli/goose-cli/provider.json +37 -0
  37. package/providers/_builtin/cli/goose-cli/scripts/1.0/detect_status.js +20 -0
  38. package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_approval.js +10 -0
  39. package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_output.js +48 -0
  40. package/providers/_builtin/cli/goose-cli/scripts/1.0/scripts.js +7 -0
  41. package/providers/_builtin/cli/opencode-cli/provider.json +37 -0
  42. package/providers/_builtin/cli/opencode-cli/scripts/1.0/detect_status.js +15 -0
  43. package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_approval.js +9 -0
  44. package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_output.js +48 -0
  45. package/providers/_builtin/cli/opencode-cli/scripts/1.0/scripts.js +7 -0
  46. package/providers/_builtin/extension/cline/scripts/1.0/focus_editor.js +5 -5
  47. package/providers/_builtin/extension/cline/scripts/1.0/list_chats.js +11 -11
  48. package/providers/_builtin/extension/cline/scripts/1.0/list_models.js +6 -6
  49. package/providers/_builtin/extension/cline/scripts/1.0/list_modes.js +5 -5
  50. package/providers/_builtin/extension/cline/scripts/1.0/new_session.js +12 -12
  51. package/providers/_builtin/extension/cline/scripts/1.0/open_panel.js +7 -7
  52. package/providers/_builtin/extension/cline/scripts/1.0/read_chat.js +29 -29
  53. package/providers/_builtin/extension/cline/scripts/1.0/resolve_action.js +19 -19
  54. package/providers/_builtin/extension/cline/scripts/1.0/send_message.js +15 -15
  55. package/providers/_builtin/extension/cline/scripts/1.0/set_mode.js +4 -4
  56. package/providers/_builtin/extension/cline/scripts/1.0/set_model.js +4 -4
  57. package/providers/_builtin/extension/cline/scripts/1.0/switch_session.js +21 -21
  58. package/providers/_builtin/extension/codex/scripts/1.0/explore_controls_webview.js +2 -2
  59. package/providers/_builtin/extension/codex/scripts/1.0/list_models.js +1 -1
  60. package/providers/_builtin/extension/codex/scripts/1.0/list_modes.js +1 -1
  61. package/providers/_builtin/extension/codex/scripts/1.0/new_session.js +2 -2
  62. package/providers/_builtin/extension/codex/scripts/1.0/read_chat.js +6 -6
  63. package/providers/_builtin/extension/codex/scripts/1.0/resolve_action.js +3 -3
  64. package/providers/_builtin/extension/codex/scripts/1.0/set_model.js +1 -1
  65. package/providers/_builtin/ide/antigravity/scripts/1.0/focus_editor.js +2 -2
  66. package/providers/_builtin/ide/antigravity/scripts/1.0/list_chats.js +19 -19
  67. package/providers/_builtin/ide/antigravity/scripts/1.0/list_models.js +1 -1
  68. package/providers/_builtin/ide/antigravity/scripts/1.0/list_modes.js +1 -1
  69. package/providers/_builtin/ide/antigravity/scripts/1.0/new_session.js +17 -17
  70. package/providers/_builtin/ide/antigravity/scripts/1.0/read_chat.js +41 -41
  71. package/providers/_builtin/ide/antigravity/scripts/1.0/resolve_action.js +6 -6
  72. package/providers/_builtin/ide/antigravity/scripts/1.0/send_message.js +13 -13
  73. package/providers/_builtin/ide/antigravity/scripts/1.0/set_model.js +1 -1
  74. package/providers/_builtin/ide/antigravity/scripts/1.0/switch_session.js +13 -13
  75. package/providers/_builtin/ide/cursor/scripts/1.0/dismiss_notification.js +3 -3
  76. package/providers/_builtin/ide/cursor/scripts/1.0/focus_editor.js +1 -1
  77. package/providers/_builtin/ide/cursor/scripts/1.0/list_models.js +12 -12
  78. package/providers/_builtin/ide/cursor/scripts/1.0/list_modes.js +5 -5
  79. package/providers/_builtin/ide/cursor/scripts/1.0/list_notifications.js +2 -2
  80. package/providers/_builtin/ide/cursor/scripts/1.0/list_sessions.js +5 -5
  81. package/providers/_builtin/ide/cursor/scripts/1.0/new_session.js +1 -1
  82. package/providers/_builtin/ide/cursor/scripts/1.0/open_panel.js +3 -3
  83. package/providers/_builtin/ide/cursor/scripts/1.0/read_chat.js +9 -9
  84. package/providers/_builtin/ide/cursor/scripts/1.0/resolve_action.js +4 -4
  85. package/providers/_builtin/ide/cursor/scripts/1.0/send_message.js +5 -5
  86. package/providers/_builtin/ide/cursor/scripts/1.0/set_mode.js +4 -4
  87. package/providers/_builtin/ide/cursor/scripts/1.0/set_model.js +12 -12
  88. package/providers/_builtin/ide/cursor/scripts/1.0/switch_session.js +2 -2
  89. package/providers/_builtin/ide/kiro/scripts/1.0/focus_editor.js +2 -2
  90. package/providers/_builtin/ide/kiro/scripts/1.0/open_panel.js +7 -7
  91. package/providers/_builtin/ide/kiro/scripts/1.0/resolve_action.js +3 -3
  92. package/providers/_builtin/ide/kiro/scripts/1.0/send_message.js +4 -4
  93. package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_sessions.js +2 -2
  94. package/providers/_builtin/ide/kiro/scripts/1.0/webview_new_session.js +5 -5
  95. package/providers/_builtin/ide/kiro/scripts/1.0/webview_read_chat.js +13 -13
  96. package/providers/_builtin/ide/kiro/scripts/1.0/webview_resolve_action.js +1 -1
  97. package/providers/_builtin/ide/kiro/scripts/1.0/webview_send_message.js +8 -8
  98. package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_mode.js +1 -1
  99. package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_model.js +1 -1
  100. package/providers/_builtin/ide/kiro/scripts/1.0/webview_switch_session.js +3 -3
  101. package/providers/_builtin/ide/pearai/.tmp/after_rich.json +157 -0
  102. package/providers/_builtin/ide/pearai/.tmp/after_rich_raw.json +161 -0
  103. package/providers/_builtin/ide/pearai/.tmp/after_switch.json +592 -0
  104. package/providers/_builtin/ide/pearai/.tmp/after_switch_raw.json +596 -0
  105. package/providers/_builtin/ide/pearai/.tmp/home_dump_raw.json +176 -0
  106. package/providers/_builtin/ide/pearai/.tmp/items_raw.json +778 -0
  107. package/providers/_builtin/ide/pearai/.tmp/webview_dump.json +157 -0
  108. package/providers/_builtin/ide/pearai/.tmp/webview_dump_raw.json +161 -0
  109. package/providers/_builtin/ide/pearai/provider.json +1 -3
  110. package/providers/_builtin/ide/pearai/scripts/1.0/focus_editor.js +12 -16
  111. package/providers/_builtin/ide/pearai/scripts/1.0/list_models.js +45 -0
  112. package/providers/_builtin/ide/pearai/scripts/1.0/list_modes.js +44 -0
  113. package/providers/_builtin/ide/pearai/scripts/1.0/list_sessions.js +82 -27
  114. package/providers/_builtin/ide/pearai/scripts/1.0/new_session.js +26 -43
  115. package/providers/_builtin/ide/pearai/scripts/1.0/open_panel.js +10 -33
  116. package/providers/_builtin/ide/pearai/scripts/1.0/read_chat.js +169 -0
  117. package/providers/_builtin/ide/pearai/scripts/1.0/resolve_action.js +47 -41
  118. package/providers/_builtin/ide/pearai/scripts/1.0/scripts.js +36 -7
  119. package/providers/_builtin/ide/pearai/scripts/1.0/send_message.js +97 -22
  120. package/providers/_builtin/ide/pearai/scripts/1.0/set_mode.js +51 -0
  121. package/providers/_builtin/ide/pearai/scripts/1.0/set_model.js +54 -0
  122. package/providers/_builtin/ide/pearai/scripts/1.0/switch_session.js +81 -0
  123. package/providers/_builtin/ide/trae/scripts/1.0/focus_editor.js +2 -2
  124. package/providers/_builtin/ide/trae/scripts/1.0/list_chats.js +2 -2
  125. package/providers/_builtin/ide/trae/scripts/1.0/new_session.js +4 -4
  126. package/providers/_builtin/ide/trae/scripts/1.0/open_panel.js +6 -6
  127. package/providers/_builtin/ide/trae/scripts/1.0/read_chat.js +13 -13
  128. package/providers/_builtin/ide/trae/scripts/1.0/resolve_action.js +3 -3
  129. package/providers/_builtin/ide/trae/scripts/1.0/send_message.js +11 -11
  130. package/providers/_builtin/ide/trae/scripts/1.0/switch_session.js +2 -2
  131. package/providers/_builtin/ide/windsurf/scripts/1.0/focus_editor.js +6 -6
  132. package/providers/_builtin/ide/windsurf/scripts/1.0/list_chats.js +4 -4
  133. package/providers/_builtin/ide/windsurf/scripts/1.0/list_sessions.js +6 -6
  134. package/providers/_builtin/ide/windsurf/scripts/1.0/new_session.js +9 -9
  135. package/providers/_builtin/ide/windsurf/scripts/1.0/open_panel.js +6 -6
  136. package/providers/_builtin/ide/windsurf/scripts/1.0/resolve_action.js +8 -8
  137. package/providers/_builtin/ide/windsurf/scripts/1.0/switch_session.js +8 -8
  138. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/focus_editor.js +6 -6
  139. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_chats.js +12 -12
  140. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/new_session.js +15 -15
  141. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/open_panel.js +10 -10
  142. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/read_chat.js +33 -33
  143. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/resolve_action.js +6 -6
  144. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/send_message.js +16 -16
  145. package/providers/_builtin/ide/windsurf/scripts/1.0.bak/switch_session.js +7 -7
  146. package/providers/_builtin/registry.json +76 -3
  147. package/src/cli-adapters/provider-cli-adapter.ts +267 -251
  148. package/src/cli-adapters/terminal-screen.ts +268 -0
  149. package/src/commands/chat-commands.ts +41 -15
  150. package/src/commands/cli-manager.ts +4 -2
  151. package/src/daemon/dev-server.ts +245 -35
  152. package/src/providers/acp-provider-instance.ts +1 -1
  153. package/src/providers/cli-provider-instance.ts +21 -8
  154. package/src/providers/provider-loader.ts +3 -2
  155. package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_models.js +0 -43
  156. package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_modes.js +0 -35
  157. package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_sessions.js +0 -62
  158. package/providers/_builtin/ide/pearai/scripts/1.0/webview_new_session.js +0 -49
  159. package/providers/_builtin/ide/pearai/scripts/1.0/webview_read_chat.js +0 -92
  160. package/providers/_builtin/ide/pearai/scripts/1.0/webview_resolve_action.js +0 -59
  161. package/providers/_builtin/ide/pearai/scripts/1.0/webview_send_message.js +0 -72
  162. package/providers/_builtin/ide/pearai/scripts/1.0/webview_set_mode.js +0 -36
  163. package/providers/_builtin/ide/pearai/scripts/1.0/webview_set_model.js +0 -36
  164. package/providers/_builtin/ide/pearai/scripts/1.0/webview_switch_session.js +0 -34
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Codex CLI Scripts — v1.0
3
+ */
4
+ 'use strict';
5
+ const path = require('path');
6
+ const DIR = __dirname;
7
+ function loadModule(name) { try { return require(path.join(DIR, name)); } catch { return null; } }
8
+
9
+ module.exports.parseOutput = (input) => { const m = loadModule('parse_output.js'); return m ? m(input) : null; };
10
+ module.exports.detectStatus = (input) => { const m = loadModule('detect_status.js'); return m ? m(input) : null; };
11
+ module.exports.parseApproval = (input) => { const m = loadModule('parse_approval.js'); return m ? m(input) : null; };
@@ -0,0 +1,37 @@
1
+ {
2
+ "type": "cursor-cli",
3
+ "name": "Cursor CLI",
4
+ "category": "cli",
5
+ "aliases": [
6
+ "cursor"
7
+ ],
8
+ "icon": "🤖",
9
+ "displayName": "Cursor CLI",
10
+ "settings": {
11
+ "mode": {
12
+ "type": "select",
13
+ "default": "chat",
14
+ "public": true,
15
+ "label": "Display Mode",
16
+ "description": "terminal: Native PTY view, chat: Parsed message view",
17
+ "options": [
18
+ "terminal",
19
+ "chat"
20
+ ]
21
+ }
22
+ },
23
+ "binary": "agent",
24
+ "spawn": {
25
+ "command": "agent",
26
+ "args": [],
27
+ "shell": true,
28
+ "env": {}
29
+ },
30
+ "compatibility": [
31
+ {
32
+ "ideVersion": ">=2026.0.0",
33
+ "scriptDir": "scripts/1.0"
34
+ }
35
+ ],
36
+ "defaultScriptDir": "scripts/1.0"
37
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Cursor CLI — detect_status
3
+ * Cursor's terminal agent uses similar TUI patterns to Claude.
4
+ */
5
+ 'use strict';
6
+ module.exports = function detectStatus(input) {
7
+ const { tail } = input;
8
+ if (!tail) return 'idle';
9
+ // waiting_approval
10
+ if (/Allow\s*once/i.test(tail) || /Always\s*allow/i.test(tail)) return 'waiting_approval';
11
+ if (/\(y\/n\)/i.test(tail) || /\[Y\/n\]/i.test(tail)) return 'waiting_approval';
12
+ if (/approve|confirm/i.test(tail) && /deny|cancel/i.test(tail)) return 'waiting_approval';
13
+ // generating
14
+ if (/[\u2800-\u28ff]/.test(tail)) return 'generating';
15
+ if (/[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/.test(tail)) return 'generating';
16
+ if (/thinking|processing|generating/i.test(tail)) return 'generating';
17
+ if (/esc to (cancel|interrupt|stop)/i.test(tail)) return 'generating';
18
+ return 'idle';
19
+ };
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+ module.exports = function parseApproval(input) {
3
+ const { tail } = input;
4
+ if (!tail) return null;
5
+ const hasApproval = /Allow\s*once/i.test(tail) || /Always\s*allow/i.test(tail) ||
6
+ /\(y\/n\)/i.test(tail) || (/approve/i.test(tail) && /deny/i.test(tail));
7
+ if (!hasApproval) return null;
8
+ const lines = tail.split('\n').map(l => l.trim()).filter(l => l && !/^[─═╭╮╰╯│]+$/.test(l));
9
+ return { message: lines.slice(-5).join(' ').slice(0, 200) || 'Approval required', buttons: ['Allow', 'Always allow', 'Deny'] };
10
+ };
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+ const detectStatus = require('./detect_status.js');
3
+ const parseApproval = require('./parse_approval.js');
4
+
5
+ function splitTurns(buffer) {
6
+ const messages = [];
7
+ if (!buffer || buffer.length < 5) return messages;
8
+ const lines = buffer.split('\n');
9
+ let currentRole = null, currentContent = [], msgIndex = 0, started = false;
10
+ for (const line of lines) {
11
+ const trimmed = line.trim();
12
+ const userMatch = trimmed.match(/^[❯›>$]\s+(.+)$/);
13
+ if (userMatch && userMatch[1].length > 1) {
14
+ started = true;
15
+ if (currentRole && currentContent.length > 0) {
16
+ const text = currentContent.join('\n').trim();
17
+ if (text.length > 1) { messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' }); msgIndex++; }
18
+ }
19
+ currentRole = 'user'; currentContent = [userMatch[1]]; continue;
20
+ }
21
+ if (!started) continue;
22
+ if (currentRole === 'user' && trimmed && !userMatch) {
23
+ const text = currentContent.join('\n').trim();
24
+ if (text.length > 1) { messages.push({ id: `msg_${msgIndex}`, role: 'user', content: text, index: msgIndex, kind: 'standard' }); msgIndex++; }
25
+ currentRole = 'assistant'; currentContent = [];
26
+ }
27
+ if (!trimmed || /^[─═╭╮╰╯│]+$/.test(trimmed) || /^[\u2800-\u28ff]+$/.test(trimmed)) continue;
28
+ if (currentRole) currentContent.push(trimmed);
29
+ }
30
+ if (currentRole && currentContent.length > 0) {
31
+ const text = currentContent.join('\n').trim();
32
+ if (text.length > 1) messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' });
33
+ }
34
+ return messages.length > 50 ? messages.slice(-50) : messages;
35
+ }
36
+
37
+ module.exports = function parseOutput(input) {
38
+ const { buffer, recentBuffer, partialResponse, screenText } = input;
39
+ const transcript = screenText || buffer;
40
+ const tail = recentBuffer || (transcript || '').slice(-500);
41
+ const status = detectStatus({ tail });
42
+ const activeModal = status === 'waiting_approval' ? parseApproval({ buffer: transcript, tail }) : null;
43
+ const messages = splitTurns(transcript);
44
+ if (status === 'generating' && partialResponse && partialResponse.trim().length > 2) {
45
+ messages.push({ id: 'msg_partial', role: 'assistant', content: partialResponse.trim().slice(0, 6000), index: messages.length, kind: 'standard', meta: { streaming: true } });
46
+ }
47
+ return { id: 'cli_session', status, title: 'Cursor CLI', messages, activeModal };
48
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+ const path = require('path');
3
+ const DIR = __dirname;
4
+ function loadModule(name) { try { return require(path.join(DIR, name)); } catch { return null; } }
5
+ module.exports.parseOutput = (input) => { const m = loadModule('parse_output.js'); return m ? m(input) : null; };
6
+ module.exports.detectStatus = (input) => { const m = loadModule('detect_status.js'); return m ? m(input) : null; };
7
+ module.exports.parseApproval = (input) => { const m = loadModule('parse_approval.js'); return m ? m(input) : null; };
@@ -10,7 +10,7 @@
10
10
  "settings": {
11
11
  "mode": {
12
12
  "type": "select",
13
- "default": "terminal",
13
+ "default": "chat",
14
14
  "public": true,
15
15
  "label": "Display Mode",
16
16
  "description": "terminal: Native PTY view, chat: Parsed message view",
@@ -98,5 +98,12 @@
98
98
  "0": "y",
99
99
  "1": "a",
100
100
  "2": "n"
101
- }
101
+ },
102
+ "compatibility": [
103
+ {
104
+ "ideVersion": ">=0.35.0",
105
+ "scriptDir": "scripts/1.0"
106
+ }
107
+ ],
108
+ "defaultScriptDir": "scripts/1.0"
102
109
  }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Gemini CLI — detect_status
3
+ * Input: { tail: string }
4
+ * Output: 'idle' | 'generating' | 'waiting_approval'
5
+ */
6
+ 'use strict';
7
+ module.exports = function detectStatus(input) {
8
+ const { tail } = input;
9
+ if (!tail) return 'idle';
10
+
11
+ // waiting_approval
12
+ if (/Allow\s*once/i.test(tail) || /Always\s*allow/i.test(tail)) return 'waiting_approval';
13
+ if (/\(y\/n\)/i.test(tail) || /\[Y\/n\]/i.test(tail)) return 'waiting_approval';
14
+ if (/Run\s*this\s*command/i.test(tail)) return 'waiting_approval';
15
+ if (/Deny/i.test(tail) && /Allow/i.test(tail)) return 'waiting_approval';
16
+ if (/auto-?approve/i.test(tail) && /Deny/i.test(tail)) return 'waiting_approval';
17
+
18
+ // generating
19
+ if (/[\u2800-\u28ff]/.test(tail)) return 'generating';
20
+ if (/[▀▄▌▐░▒▓█]/.test(tail)) return 'generating';
21
+ if (/Thinking/i.test(tail)) return 'generating';
22
+ if (/Generating/i.test(tail)) return 'generating';
23
+ if (/esc to (cancel|interrupt|stop)/i.test(tail)) return 'generating';
24
+
25
+ return 'idle';
26
+ };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Gemini CLI — parse_approval
3
+ * Input: { buffer: string, tail: string }
4
+ * Output: { message: string, buttons: string[] } | null
5
+ */
6
+ 'use strict';
7
+ module.exports = function parseApproval(input) {
8
+ const { tail } = input;
9
+ if (!tail) return null;
10
+
11
+ const hasApproval =
12
+ /Allow\s*once/i.test(tail) || /Always\s*allow/i.test(tail) ||
13
+ /Run\s*this\s*command/i.test(tail) || /Deny/i.test(tail) ||
14
+ /\(y\/n\)/i.test(tail) || /\[Y\/n\]/i.test(tail);
15
+ if (!hasApproval) return null;
16
+
17
+ const lines = tail.split('\n').map(l => l.trim()).filter(l => l && !/^[─═╭╮╰╯│]+$/.test(l));
18
+ return {
19
+ message: lines.slice(-5).join(' ').slice(0, 200) || 'Approval required',
20
+ buttons: ['Allow (y)', 'Always allow (a)', 'Deny (n)'],
21
+ };
22
+ };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Gemini CLI — parse_output
3
+ * Input: CliScriptInput
4
+ * Output: ReadChatResult
5
+ */
6
+ 'use strict';
7
+ const detectStatus = require('./detect_status.js');
8
+ const parseApproval = require('./parse_approval.js');
9
+
10
+ function splitTurns(buffer) {
11
+ const messages = [];
12
+ if (!buffer || buffer.length < 5) return messages;
13
+ const lines = buffer.split('\n');
14
+ let currentRole = null;
15
+ let currentContent = [];
16
+ let msgIndex = 0;
17
+ let started = false;
18
+
19
+ for (const line of lines) {
20
+ const trimmed = line.trim();
21
+ const userMatch = trimmed.match(/^[❯›>]\s+(.+)$/);
22
+ if (userMatch && userMatch[1].length > 1) {
23
+ started = true;
24
+ if (currentRole && currentContent.length > 0) {
25
+ const text = currentContent.join('\n').trim();
26
+ if (text.length > 1) {
27
+ messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' });
28
+ msgIndex++;
29
+ }
30
+ }
31
+ currentRole = 'user';
32
+ currentContent = [userMatch[1]];
33
+ continue;
34
+ }
35
+ if (!started) continue;
36
+ if (currentRole === 'user' && trimmed && !userMatch) {
37
+ const text = currentContent.join('\n').trim();
38
+ if (text.length > 1) {
39
+ messages.push({ id: `msg_${msgIndex}`, role: 'user', content: text, index: msgIndex, kind: 'standard' });
40
+ msgIndex++;
41
+ }
42
+ currentRole = 'assistant';
43
+ currentContent = [];
44
+ }
45
+ if (!trimmed) continue;
46
+ if (/^[─═╭╮╰╯│┌┐└┘├┤┬┴┼]+$/.test(trimmed)) continue;
47
+ if (/^[\u2800-\u28ff]+$/.test(trimmed)) continue;
48
+ if (/^sandbox/i.test(trimmed)) continue;
49
+ if (currentRole) currentContent.push(trimmed);
50
+ }
51
+ if (currentRole && currentContent.length > 0) {
52
+ const text = currentContent.join('\n').trim();
53
+ if (text.length > 1) {
54
+ messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' });
55
+ }
56
+ }
57
+ return messages.length > 50 ? messages.slice(-50) : messages;
58
+ }
59
+
60
+ module.exports = function parseOutput(input) {
61
+ const { buffer, recentBuffer, partialResponse, screenText } = input;
62
+ const transcript = screenText || buffer;
63
+ const tail = recentBuffer || (transcript || '').slice(-500);
64
+ const status = detectStatus({ tail });
65
+ const activeModal = status === 'waiting_approval' ? parseApproval({ buffer: transcript, tail }) : null;
66
+ const messages = splitTurns(transcript);
67
+ if (status === 'generating' && partialResponse && partialResponse.trim().length > 2) {
68
+ messages.push({ id: 'msg_partial', role: 'assistant', content: partialResponse.trim().slice(0, 6000), index: messages.length, kind: 'standard', meta: { streaming: true } });
69
+ }
70
+ return { id: 'cli_session', status, title: 'Gemini CLI', messages, activeModal };
71
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Gemini CLI Scripts — v1.0
3
+ */
4
+ 'use strict';
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const DIR = __dirname;
8
+ function loadModule(name) { try { return require(path.join(DIR, name)); } catch { return null; } }
9
+
10
+ module.exports.parseOutput = (input) => { const m = loadModule('parse_output.js'); return m ? m(input) : null; };
11
+ module.exports.detectStatus = (input) => { const m = loadModule('detect_status.js'); return m ? m(input) : null; };
12
+ module.exports.parseApproval = (input) => { const m = loadModule('parse_approval.js'); return m ? m(input) : null; };
@@ -0,0 +1,37 @@
1
+ {
2
+ "type": "github-copilot-cli",
3
+ "name": "GitHub Copilot CLI",
4
+ "category": "cli",
5
+ "aliases": [
6
+ "gh-copilot"
7
+ ],
8
+ "icon": "🤖",
9
+ "displayName": "GitHub Copilot CLI",
10
+ "settings": {
11
+ "mode": {
12
+ "type": "select",
13
+ "default": "chat",
14
+ "public": true,
15
+ "label": "Display Mode",
16
+ "description": "terminal: Native PTY view, chat: Parsed message view",
17
+ "options": [
18
+ "terminal",
19
+ "chat"
20
+ ]
21
+ }
22
+ },
23
+ "binary": "gh",
24
+ "spawn": {
25
+ "command": "gh",
26
+ "args": ["copilot"],
27
+ "shell": true,
28
+ "env": {}
29
+ },
30
+ "compatibility": [
31
+ {
32
+ "ideVersion": ">=1.0.0",
33
+ "scriptDir": "scripts/1.0"
34
+ }
35
+ ],
36
+ "defaultScriptDir": "scripts/1.0"
37
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * GitHub Copilot CLI — detect_status
3
+ * `gh copilot` uses a conversational interface.
4
+ */
5
+ 'use strict';
6
+ module.exports = function detectStatus(input) {
7
+ const { tail } = input;
8
+ if (!tail) return 'idle';
9
+ // waiting_approval
10
+ if (/execute\s*command/i.test(tail) && /\[Y\/n\]/i.test(tail)) return 'waiting_approval';
11
+ if (/approve|confirm/i.test(tail) && /\(y\/n\)/i.test(tail)) return 'waiting_approval';
12
+ if (/Run\s*this/i.test(tail) && /deny|cancel|no/i.test(tail)) return 'waiting_approval';
13
+ // generating
14
+ if (/[\u2800-\u28ff]/.test(tail)) return 'generating';
15
+ if (/[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/.test(tail)) return 'generating';
16
+ if (/thinking|generating|processing/i.test(tail)) return 'generating';
17
+ if (/\.{3,}$/.test(tail.trim())) return 'generating';
18
+ return 'idle';
19
+ };
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+ module.exports = function parseApproval(input) {
3
+ const { tail } = input;
4
+ if (!tail) return null;
5
+ const hasApproval = /execute\s*command/i.test(tail) || /\(y\/n\)/i.test(tail) || /\[Y\/n\]/i.test(tail);
6
+ if (!hasApproval) return null;
7
+ const lines = tail.split('\n').map(l => l.trim()).filter(l => l && !/^[─═╭╮╰╯│]+$/.test(l));
8
+ return { message: lines.slice(-5).join(' ').slice(0, 200) || 'Execute command?', buttons: ['Yes', 'No'] };
9
+ };
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+ const detectStatus = require('./detect_status.js');
3
+ const parseApproval = require('./parse_approval.js');
4
+
5
+ function splitTurns(buffer) {
6
+ const messages = [];
7
+ if (!buffer || buffer.length < 5) return messages;
8
+ const lines = buffer.split('\n');
9
+ let currentRole = null, currentContent = [], msgIndex = 0, started = false;
10
+ for (const line of lines) {
11
+ const trimmed = line.trim();
12
+ const userMatch = trimmed.match(/^[❯›>$?]\s+(.+)$/);
13
+ if (userMatch && userMatch[1].length > 1) {
14
+ started = true;
15
+ if (currentRole && currentContent.length > 0) {
16
+ const text = currentContent.join('\n').trim();
17
+ if (text.length > 1) { messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' }); msgIndex++; }
18
+ }
19
+ currentRole = 'user'; currentContent = [userMatch[1]]; continue;
20
+ }
21
+ if (!started) continue;
22
+ if (currentRole === 'user' && trimmed && !userMatch) {
23
+ const text = currentContent.join('\n').trim();
24
+ if (text.length > 1) { messages.push({ id: `msg_${msgIndex}`, role: 'user', content: text, index: msgIndex, kind: 'standard' }); msgIndex++; }
25
+ currentRole = 'assistant'; currentContent = [];
26
+ }
27
+ if (!trimmed || /^[─═╭╮╰╯│]+$/.test(trimmed) || /^[\u2800-\u28ff]+$/.test(trimmed)) continue;
28
+ if (currentRole) currentContent.push(trimmed);
29
+ }
30
+ if (currentRole && currentContent.length > 0) {
31
+ const text = currentContent.join('\n').trim();
32
+ if (text.length > 1) messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' });
33
+ }
34
+ return messages.length > 50 ? messages.slice(-50) : messages;
35
+ }
36
+
37
+ module.exports = function parseOutput(input) {
38
+ const { buffer, recentBuffer, partialResponse, screenText } = input;
39
+ const transcript = screenText || buffer;
40
+ const tail = recentBuffer || (transcript || '').slice(-500);
41
+ const status = detectStatus({ tail });
42
+ const activeModal = status === 'waiting_approval' ? parseApproval({ buffer: transcript, tail }) : null;
43
+ const messages = splitTurns(transcript);
44
+ if (status === 'generating' && partialResponse && partialResponse.trim().length > 2) {
45
+ messages.push({ id: 'msg_partial', role: 'assistant', content: partialResponse.trim().slice(0, 6000), index: messages.length, kind: 'standard', meta: { streaming: true } });
46
+ }
47
+ return { id: 'cli_session', status, title: 'GitHub Copilot CLI', messages, activeModal };
48
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+ const path = require('path');
3
+ const DIR = __dirname;
4
+ function loadModule(name) { try { return require(path.join(DIR, name)); } catch { return null; } }
5
+ module.exports.parseOutput = (input) => { const m = loadModule('parse_output.js'); return m ? m(input) : null; };
6
+ module.exports.detectStatus = (input) => { const m = loadModule('detect_status.js'); return m ? m(input) : null; };
7
+ module.exports.parseApproval = (input) => { const m = loadModule('parse_approval.js'); return m ? m(input) : null; };
@@ -0,0 +1,37 @@
1
+ {
2
+ "type": "goose-cli",
3
+ "name": "Goose",
4
+ "category": "cli",
5
+ "aliases": [
6
+ "goose"
7
+ ],
8
+ "icon": "🤖",
9
+ "displayName": "Goose",
10
+ "settings": {
11
+ "mode": {
12
+ "type": "select",
13
+ "default": "chat",
14
+ "public": true,
15
+ "label": "Display Mode",
16
+ "description": "terminal: Native PTY view, chat: Parsed message view",
17
+ "options": [
18
+ "terminal",
19
+ "chat"
20
+ ]
21
+ }
22
+ },
23
+ "binary": "goose",
24
+ "spawn": {
25
+ "command": "goose",
26
+ "args": [],
27
+ "shell": true,
28
+ "env": {}
29
+ },
30
+ "compatibility": [
31
+ {
32
+ "ideVersion": ">=3.20.0",
33
+ "scriptDir": "scripts/1.0"
34
+ }
35
+ ],
36
+ "defaultScriptDir": "scripts/1.0"
37
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Goose — detect_status
3
+ * Goose is an autonomous AI agent that uses MCP and tools.
4
+ * It typically shows 'thinking...' and uses tool calls.
5
+ */
6
+ 'use strict';
7
+ module.exports = function detectStatus(input) {
8
+ const { tail } = input;
9
+ if (!tail) return 'idle';
10
+ // Goose approval
11
+ if (/approve|confirm/i.test(tail) && /deny|cancel/i.test(tail)) return 'waiting_approval';
12
+ if (/\(y\/n\)/i.test(tail)) return 'waiting_approval';
13
+ if (/Allow.*tool/i.test(tail)) return 'waiting_approval';
14
+ // generating
15
+ if (/[\u2800-\u28ff]/.test(tail)) return 'generating';
16
+ if (/[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/.test(tail)) return 'generating';
17
+ if (/thinking|processing|working|running/i.test(tail)) return 'generating';
18
+ if (/─.*tool.*─/i.test(tail)) return 'generating';
19
+ return 'idle';
20
+ };
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+ module.exports = function parseApproval(input) {
3
+ const { tail } = input;
4
+ if (!tail) return null;
5
+ const hasApproval = (/approve|confirm/i.test(tail) && /deny|cancel/i.test(tail)) ||
6
+ /\(y\/n\)/i.test(tail) || /Allow.*tool/i.test(tail);
7
+ if (!hasApproval) return null;
8
+ const lines = tail.split('\n').map(l => l.trim()).filter(l => l && l.length > 2);
9
+ return { message: lines.slice(-5).join(' ').slice(0, 200) || 'Approval required', buttons: ['Approve', 'Deny'] };
10
+ };
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+ const detectStatus = require('./detect_status.js');
3
+ const parseApproval = require('./parse_approval.js');
4
+
5
+ function splitTurns(buffer) {
6
+ const messages = [];
7
+ if (!buffer || buffer.length < 5) return messages;
8
+ const lines = buffer.split('\n');
9
+ let currentRole = null, currentContent = [], msgIndex = 0, started = false;
10
+ for (const line of lines) {
11
+ const trimmed = line.trim();
12
+ const userMatch = trimmed.match(/^[❯›>$]\s+(.+)$/);
13
+ if (userMatch && userMatch[1].length > 1) {
14
+ started = true;
15
+ if (currentRole && currentContent.length > 0) {
16
+ const text = currentContent.join('\n').trim();
17
+ if (text.length > 1) { messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' }); msgIndex++; }
18
+ }
19
+ currentRole = 'user'; currentContent = [userMatch[1]]; continue;
20
+ }
21
+ if (!started) continue;
22
+ if (currentRole === 'user' && trimmed && !userMatch) {
23
+ const text = currentContent.join('\n').trim();
24
+ if (text.length > 1) { messages.push({ id: `msg_${msgIndex}`, role: 'user', content: text, index: msgIndex, kind: 'standard' }); msgIndex++; }
25
+ currentRole = 'assistant'; currentContent = [];
26
+ }
27
+ if (!trimmed || /^[─═╭╮╰╯│]+$/.test(trimmed) || /^[\u2800-\u28ff]+$/.test(trimmed)) continue;
28
+ if (currentRole) currentContent.push(trimmed);
29
+ }
30
+ if (currentRole && currentContent.length > 0) {
31
+ const text = currentContent.join('\n').trim();
32
+ if (text.length > 1) messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' });
33
+ }
34
+ return messages.length > 50 ? messages.slice(-50) : messages;
35
+ }
36
+
37
+ module.exports = function parseOutput(input) {
38
+ const { buffer, recentBuffer, partialResponse, screenText } = input;
39
+ const transcript = screenText || buffer;
40
+ const tail = recentBuffer || (transcript || '').slice(-500);
41
+ const status = detectStatus({ tail });
42
+ const activeModal = status === 'waiting_approval' ? parseApproval({ buffer: transcript, tail }) : null;
43
+ const messages = splitTurns(transcript);
44
+ if (status === 'generating' && partialResponse && partialResponse.trim().length > 2) {
45
+ messages.push({ id: 'msg_partial', role: 'assistant', content: partialResponse.trim().slice(0, 6000), index: messages.length, kind: 'standard', meta: { streaming: true } });
46
+ }
47
+ return { id: 'cli_session', status, title: 'Goose', messages, activeModal };
48
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+ const path = require('path');
3
+ const DIR = __dirname;
4
+ function loadModule(name) { try { return require(path.join(DIR, name)); } catch { return null; } }
5
+ module.exports.parseOutput = (input) => { const m = loadModule('parse_output.js'); return m ? m(input) : null; };
6
+ module.exports.detectStatus = (input) => { const m = loadModule('detect_status.js'); return m ? m(input) : null; };
7
+ module.exports.parseApproval = (input) => { const m = loadModule('parse_approval.js'); return m ? m(input) : null; };
@@ -0,0 +1,37 @@
1
+ {
2
+ "type": "opencode-cli",
3
+ "name": "OpenCode CLI",
4
+ "category": "cli",
5
+ "aliases": [
6
+ "opencode"
7
+ ],
8
+ "icon": "🤖",
9
+ "displayName": "OpenCode CLI",
10
+ "settings": {
11
+ "mode": {
12
+ "type": "select",
13
+ "default": "chat",
14
+ "public": true,
15
+ "label": "Display Mode",
16
+ "description": "terminal: Native PTY view, chat: Parsed message view",
17
+ "options": [
18
+ "terminal",
19
+ "chat"
20
+ ]
21
+ }
22
+ },
23
+ "binary": "opencode",
24
+ "spawn": {
25
+ "command": "opencode",
26
+ "args": [],
27
+ "shell": true,
28
+ "env": {}
29
+ },
30
+ "compatibility": [
31
+ {
32
+ "ideVersion": ">=1.3.0",
33
+ "scriptDir": "scripts/1.0"
34
+ }
35
+ ],
36
+ "defaultScriptDir": "scripts/1.0"
37
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * OpenCode CLI — detect_status
3
+ * OpenCode uses a TUI that resembles a chat interface.
4
+ */
5
+ 'use strict';
6
+ module.exports = function detectStatus(input) {
7
+ const { tail } = input;
8
+ if (!tail) return 'idle';
9
+ if (/Allow|Deny|approve|reject/i.test(tail) && /\(y\/n\)|confirm/i.test(tail)) return 'waiting_approval';
10
+ if (/[\u2800-\u28ff]/.test(tail)) return 'generating';
11
+ if (/[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/.test(tail)) return 'generating';
12
+ if (/thinking|generating|processing|running/i.test(tail)) return 'generating';
13
+ if (/esc to (cancel|stop)/i.test(tail)) return 'generating';
14
+ return 'idle';
15
+ };
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+ module.exports = function parseApproval(input) {
3
+ const { tail } = input;
4
+ if (!tail) return null;
5
+ const hasApproval = /Allow|approve/i.test(tail) && /Deny|reject/i.test(tail);
6
+ if (!hasApproval && !/\(y\/n\)/i.test(tail)) return null;
7
+ const lines = tail.split('\n').map(l => l.trim()).filter(l => l && !/^[─═╭╮╰╯│]+$/.test(l));
8
+ return { message: lines.slice(-5).join(' ').slice(0, 200) || 'Approval required', buttons: ['Allow', 'Deny'] };
9
+ };