@adhdev/daemon-core 0.6.53 → 0.6.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +84 -34
- package/dist/index.js +631 -305
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/providers/_builtin/_helpers/index.js +26 -26
- package/providers/_builtin/cli/aider-cli/provider.json +37 -0
- package/providers/_builtin/cli/aider-cli/scripts/1.0/detect_status.js +20 -0
- package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_approval.js +10 -0
- package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_output.js +49 -0
- package/providers/_builtin/cli/aider-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/cli/claude-cli/provider.json +9 -2
- package/providers/_builtin/cli/claude-cli/scripts/1.0/detect_status.js +31 -0
- package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_approval.js +38 -0
- package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_output.js +164 -0
- package/providers/_builtin/cli/claude-cli/scripts/1.0/scripts.js +42 -0
- package/providers/_builtin/cli/codex-cli/provider.json +9 -2
- package/providers/_builtin/cli/codex-cli/scripts/1.0/detect_status.js +20 -0
- package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_approval.js +15 -0
- package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_output.js +68 -0
- package/providers/_builtin/cli/codex-cli/scripts/1.0/scripts.js +11 -0
- package/providers/_builtin/cli/cursor-cli/provider.json +37 -0
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/detect_status.js +19 -0
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_approval.js +10 -0
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_output.js +48 -0
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/cli/gemini-cli/provider.json +9 -2
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/detect_status.js +26 -0
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_approval.js +22 -0
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_output.js +71 -0
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/scripts.js +12 -0
- package/providers/_builtin/cli/github-copilot-cli/provider.json +37 -0
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/detect_status.js +19 -0
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_approval.js +9 -0
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_output.js +48 -0
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/cli/goose-cli/provider.json +37 -0
- package/providers/_builtin/cli/goose-cli/scripts/1.0/detect_status.js +20 -0
- package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_approval.js +10 -0
- package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_output.js +48 -0
- package/providers/_builtin/cli/goose-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/cli/opencode-cli/provider.json +37 -0
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/detect_status.js +15 -0
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_approval.js +9 -0
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_output.js +48 -0
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/scripts.js +7 -0
- package/providers/_builtin/extension/cline/scripts/1.0/focus_editor.js +5 -5
- package/providers/_builtin/extension/cline/scripts/1.0/list_chats.js +11 -11
- package/providers/_builtin/extension/cline/scripts/1.0/list_models.js +6 -6
- package/providers/_builtin/extension/cline/scripts/1.0/list_modes.js +5 -5
- package/providers/_builtin/extension/cline/scripts/1.0/new_session.js +12 -12
- package/providers/_builtin/extension/cline/scripts/1.0/open_panel.js +7 -7
- package/providers/_builtin/extension/cline/scripts/1.0/read_chat.js +29 -29
- package/providers/_builtin/extension/cline/scripts/1.0/resolve_action.js +19 -19
- package/providers/_builtin/extension/cline/scripts/1.0/send_message.js +15 -15
- package/providers/_builtin/extension/cline/scripts/1.0/set_mode.js +4 -4
- package/providers/_builtin/extension/cline/scripts/1.0/set_model.js +4 -4
- package/providers/_builtin/extension/cline/scripts/1.0/switch_session.js +21 -21
- package/providers/_builtin/extension/codex/scripts/1.0/explore_controls_webview.js +2 -2
- package/providers/_builtin/extension/codex/scripts/1.0/list_models.js +1 -1
- package/providers/_builtin/extension/codex/scripts/1.0/list_modes.js +1 -1
- package/providers/_builtin/extension/codex/scripts/1.0/new_session.js +2 -2
- package/providers/_builtin/extension/codex/scripts/1.0/read_chat.js +6 -6
- package/providers/_builtin/extension/codex/scripts/1.0/resolve_action.js +3 -3
- package/providers/_builtin/extension/codex/scripts/1.0/set_model.js +1 -1
- package/providers/_builtin/ide/antigravity/scripts/1.0/focus_editor.js +2 -2
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_chats.js +19 -19
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_models.js +1 -1
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_modes.js +1 -1
- package/providers/_builtin/ide/antigravity/scripts/1.0/new_session.js +17 -17
- package/providers/_builtin/ide/antigravity/scripts/1.0/read_chat.js +41 -41
- package/providers/_builtin/ide/antigravity/scripts/1.0/resolve_action.js +6 -6
- package/providers/_builtin/ide/antigravity/scripts/1.0/send_message.js +13 -13
- package/providers/_builtin/ide/antigravity/scripts/1.0/set_model.js +1 -1
- package/providers/_builtin/ide/antigravity/scripts/1.0/switch_session.js +13 -13
- package/providers/_builtin/ide/cursor/scripts/1.0/dismiss_notification.js +3 -3
- package/providers/_builtin/ide/cursor/scripts/1.0/focus_editor.js +1 -1
- package/providers/_builtin/ide/cursor/scripts/1.0/list_models.js +12 -12
- package/providers/_builtin/ide/cursor/scripts/1.0/list_modes.js +5 -5
- package/providers/_builtin/ide/cursor/scripts/1.0/list_notifications.js +2 -2
- package/providers/_builtin/ide/cursor/scripts/1.0/list_sessions.js +5 -5
- package/providers/_builtin/ide/cursor/scripts/1.0/new_session.js +1 -1
- package/providers/_builtin/ide/cursor/scripts/1.0/open_panel.js +3 -3
- package/providers/_builtin/ide/cursor/scripts/1.0/read_chat.js +9 -9
- package/providers/_builtin/ide/cursor/scripts/1.0/resolve_action.js +4 -4
- package/providers/_builtin/ide/cursor/scripts/1.0/send_message.js +5 -5
- package/providers/_builtin/ide/cursor/scripts/1.0/set_mode.js +4 -4
- package/providers/_builtin/ide/cursor/scripts/1.0/set_model.js +12 -12
- package/providers/_builtin/ide/cursor/scripts/1.0/switch_session.js +2 -2
- package/providers/_builtin/ide/kiro/scripts/1.0/focus_editor.js +2 -2
- package/providers/_builtin/ide/kiro/scripts/1.0/open_panel.js +7 -7
- package/providers/_builtin/ide/kiro/scripts/1.0/resolve_action.js +3 -3
- package/providers/_builtin/ide/kiro/scripts/1.0/send_message.js +4 -4
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_sessions.js +2 -2
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_new_session.js +5 -5
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_read_chat.js +13 -13
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_resolve_action.js +1 -1
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_send_message.js +8 -8
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_mode.js +1 -1
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_model.js +1 -1
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_switch_session.js +3 -3
- package/providers/_builtin/ide/pearai/.tmp/after_rich.json +157 -0
- package/providers/_builtin/ide/pearai/.tmp/after_rich_raw.json +161 -0
- package/providers/_builtin/ide/pearai/.tmp/after_switch.json +592 -0
- package/providers/_builtin/ide/pearai/.tmp/after_switch_raw.json +596 -0
- package/providers/_builtin/ide/pearai/.tmp/home_dump_raw.json +176 -0
- package/providers/_builtin/ide/pearai/.tmp/items_raw.json +778 -0
- package/providers/_builtin/ide/pearai/.tmp/webview_dump.json +157 -0
- package/providers/_builtin/ide/pearai/.tmp/webview_dump_raw.json +161 -0
- package/providers/_builtin/ide/pearai/provider.json +1 -3
- package/providers/_builtin/ide/pearai/scripts/1.0/focus_editor.js +12 -16
- package/providers/_builtin/ide/pearai/scripts/1.0/list_models.js +45 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/list_modes.js +44 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/list_sessions.js +82 -27
- package/providers/_builtin/ide/pearai/scripts/1.0/new_session.js +26 -43
- package/providers/_builtin/ide/pearai/scripts/1.0/open_panel.js +10 -33
- package/providers/_builtin/ide/pearai/scripts/1.0/read_chat.js +169 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/resolve_action.js +47 -41
- package/providers/_builtin/ide/pearai/scripts/1.0/scripts.js +36 -7
- package/providers/_builtin/ide/pearai/scripts/1.0/send_message.js +97 -22
- package/providers/_builtin/ide/pearai/scripts/1.0/set_mode.js +51 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/set_model.js +54 -0
- package/providers/_builtin/ide/pearai/scripts/1.0/switch_session.js +81 -0
- package/providers/_builtin/ide/trae/scripts/1.0/focus_editor.js +2 -2
- package/providers/_builtin/ide/trae/scripts/1.0/list_chats.js +2 -2
- package/providers/_builtin/ide/trae/scripts/1.0/new_session.js +4 -4
- package/providers/_builtin/ide/trae/scripts/1.0/open_panel.js +6 -6
- package/providers/_builtin/ide/trae/scripts/1.0/read_chat.js +13 -13
- package/providers/_builtin/ide/trae/scripts/1.0/resolve_action.js +3 -3
- package/providers/_builtin/ide/trae/scripts/1.0/send_message.js +11 -11
- package/providers/_builtin/ide/trae/scripts/1.0/switch_session.js +2 -2
- package/providers/_builtin/ide/windsurf/scripts/1.0/focus_editor.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_chats.js +4 -4
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_sessions.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0/new_session.js +9 -9
- package/providers/_builtin/ide/windsurf/scripts/1.0/open_panel.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0/resolve_action.js +8 -8
- package/providers/_builtin/ide/windsurf/scripts/1.0/switch_session.js +8 -8
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/focus_editor.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_chats.js +12 -12
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/new_session.js +15 -15
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/open_panel.js +10 -10
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/read_chat.js +33 -33
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/resolve_action.js +6 -6
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/send_message.js +16 -16
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/switch_session.js +7 -7
- package/providers/_builtin/registry.json +76 -3
- package/src/cli-adapters/provider-cli-adapter.ts +312 -258
- package/src/cli-adapters/terminal-screen.ts +95 -0
- package/src/commands/chat-commands.ts +41 -15
- package/src/commands/cli-manager.ts +4 -2
- package/src/daemon/dev-server.ts +306 -62
- package/src/providers/acp-provider-instance.ts +1 -1
- package/src/providers/cli-provider-instance.ts +23 -9
- package/src/providers/provider-loader.ts +3 -2
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_models.js +0 -43
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_modes.js +0 -35
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_list_sessions.js +0 -62
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_new_session.js +0 -49
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_read_chat.js +0 -92
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_resolve_action.js +0 -59
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_send_message.js +0 -72
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_set_mode.js +0 -36
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_set_model.js +0 -36
- package/providers/_builtin/ide/pearai/scripts/1.0/webview_switch_session.js +0 -34
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex CLI — parse_output
|
|
3
|
+
*/
|
|
4
|
+
'use strict';
|
|
5
|
+
const detectStatus = require('./detect_status.js');
|
|
6
|
+
const parseApproval = require('./parse_approval.js');
|
|
7
|
+
|
|
8
|
+
function splitTurns(buffer) {
|
|
9
|
+
const messages = [];
|
|
10
|
+
if (!buffer || buffer.length < 5) return messages;
|
|
11
|
+
const lines = buffer.split('\n');
|
|
12
|
+
let currentRole = null;
|
|
13
|
+
let currentContent = [];
|
|
14
|
+
let msgIndex = 0;
|
|
15
|
+
let started = false;
|
|
16
|
+
|
|
17
|
+
for (const line of lines) {
|
|
18
|
+
const trimmed = line.trim();
|
|
19
|
+
const userMatch = trimmed.match(/^[❯›>$]\s+(.+)$/);
|
|
20
|
+
if (userMatch && userMatch[1].length > 1) {
|
|
21
|
+
started = true;
|
|
22
|
+
if (currentRole && currentContent.length > 0) {
|
|
23
|
+
const text = currentContent.join('\n').trim();
|
|
24
|
+
if (text.length > 1) {
|
|
25
|
+
messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' });
|
|
26
|
+
msgIndex++;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
currentRole = 'user';
|
|
30
|
+
currentContent = [userMatch[1]];
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!started) continue;
|
|
34
|
+
if (currentRole === 'user' && trimmed && !userMatch) {
|
|
35
|
+
const text = currentContent.join('\n').trim();
|
|
36
|
+
if (text.length > 1) {
|
|
37
|
+
messages.push({ id: `msg_${msgIndex}`, role: 'user', content: text, index: msgIndex, kind: 'standard' });
|
|
38
|
+
msgIndex++;
|
|
39
|
+
}
|
|
40
|
+
currentRole = 'assistant';
|
|
41
|
+
currentContent = [];
|
|
42
|
+
}
|
|
43
|
+
if (!trimmed) continue;
|
|
44
|
+
if (/^[─═╭╮╰╯│]+$/.test(trimmed)) continue;
|
|
45
|
+
if (/^[\u2800-\u28ff]+$/.test(trimmed)) continue;
|
|
46
|
+
if (currentRole) currentContent.push(trimmed);
|
|
47
|
+
}
|
|
48
|
+
if (currentRole && currentContent.length > 0) {
|
|
49
|
+
const text = currentContent.join('\n').trim();
|
|
50
|
+
if (text.length > 1) {
|
|
51
|
+
messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return messages.length > 50 ? messages.slice(-50) : messages;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = function parseOutput(input) {
|
|
58
|
+
const { buffer, recentBuffer, partialResponse, screenText } = input;
|
|
59
|
+
const transcript = screenText || buffer;
|
|
60
|
+
const tail = recentBuffer || (transcript || '').slice(-500);
|
|
61
|
+
const status = detectStatus({ tail });
|
|
62
|
+
const activeModal = status === 'waiting_approval' ? parseApproval({ buffer: transcript, tail }) : null;
|
|
63
|
+
const messages = splitTurns(transcript);
|
|
64
|
+
if (status === 'generating' && partialResponse && partialResponse.trim().length > 2) {
|
|
65
|
+
messages.push({ id: 'msg_partial', role: 'assistant', content: partialResponse.trim().slice(0, 6000), index: messages.length, kind: 'standard', meta: { streaming: true } });
|
|
66
|
+
}
|
|
67
|
+
return { id: 'cli_session', status, title: 'Codex CLI', messages, activeModal };
|
|
68
|
+
};
|
|
@@ -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": "
|
|
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; };
|