@adhdev/daemon-core 0.6.58 → 0.6.60
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 +1 -1
- package/dist/index.js +87 -89
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/detection/ide-detector.ts +1 -1
- package/src/providers/provider-loader.ts +3 -6
- package/providers/_builtin/.github/workflows/generate-registry.yml +0 -76
- package/providers/_builtin/COMPATIBILITY.md +0 -217
- package/providers/_builtin/CONTRIBUTING.md +0 -200
- package/providers/_builtin/README.md +0 -119
- package/providers/_builtin/_helpers/index.js +0 -188
- package/providers/_builtin/acp/agentpool/provider.json +0 -54
- package/providers/_builtin/acp/amp/provider.json +0 -52
- package/providers/_builtin/acp/auggie/provider.json +0 -57
- package/providers/_builtin/acp/autodev/provider.json +0 -54
- package/providers/_builtin/acp/autohand/provider.json +0 -52
- package/providers/_builtin/acp/blackbox-ai/provider.json +0 -54
- package/providers/_builtin/acp/claude-agent/provider.json +0 -57
- package/providers/_builtin/acp/cline-acp/provider.json +0 -54
- package/providers/_builtin/acp/codebuddy/provider.json +0 -54
- package/providers/_builtin/acp/codex-cli/provider.json +0 -57
- package/providers/_builtin/acp/corust-agent/provider.json +0 -52
- package/providers/_builtin/acp/crow-cli/provider.json +0 -54
- package/providers/_builtin/acp/cursor-acp/provider.json +0 -54
- package/providers/_builtin/acp/deepagents/provider.json +0 -52
- package/providers/_builtin/acp/dimcode/provider.json +0 -54
- package/providers/_builtin/acp/docker-cagent/provider.json +0 -57
- package/providers/_builtin/acp/factory-droid/provider.json +0 -60
- package/providers/_builtin/acp/fast-agent/provider.json +0 -52
- package/providers/_builtin/acp/gemini-cli/provider.json +0 -114
- package/providers/_builtin/acp/github-copilot/provider.json +0 -54
- package/providers/_builtin/acp/goose/provider.json +0 -57
- package/providers/_builtin/acp/junie/provider.json +0 -52
- package/providers/_builtin/acp/kilo/provider.json +0 -54
- package/providers/_builtin/acp/kimi-cli/provider.json +0 -57
- package/providers/_builtin/acp/minion-code/provider.json +0 -52
- package/providers/_builtin/acp/mistral-vibe/provider.json +0 -57
- package/providers/_builtin/acp/nova/provider.json +0 -54
- package/providers/_builtin/acp/openclaw/provider.json +0 -54
- package/providers/_builtin/acp/opencode/provider.json +0 -52
- package/providers/_builtin/acp/openhands/provider.json +0 -54
- package/providers/_builtin/acp/pi-acp/provider.json +0 -52
- package/providers/_builtin/acp/qoder/provider.json +0 -54
- package/providers/_builtin/acp/qwen-code/provider.json +0 -60
- package/providers/_builtin/acp/stakpak/provider.json +0 -54
- package/providers/_builtin/acp/vtcode/provider.json +0 -54
- package/providers/_builtin/cli/aider-cli/provider.json +0 -37
- package/providers/_builtin/cli/aider-cli/scripts/1.0/detect_status.js +0 -20
- package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_approval.js +0 -10
- package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_output.js +0 -97
- package/providers/_builtin/cli/aider-cli/scripts/1.0/scripts.js +0 -7
- package/providers/_builtin/cli/claude-cli/provider.json +0 -121
- package/providers/_builtin/cli/claude-cli/scripts/1.0/detect_status.js +0 -83
- package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_approval.js +0 -97
- package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_output.js +0 -417
- package/providers/_builtin/cli/claude-cli/scripts/1.0/scripts.js +0 -42
- package/providers/_builtin/cli/codex-cli/provider.json +0 -90
- package/providers/_builtin/cli/codex-cli/scripts/1.0/detect_status.js +0 -54
- package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_approval.js +0 -91
- package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_output.js +0 -522
- package/providers/_builtin/cli/codex-cli/scripts/1.0/scripts.js +0 -11
- package/providers/_builtin/cli/cursor-cli/provider.json +0 -37
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/detect_status.js +0 -19
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_approval.js +0 -10
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_output.js +0 -48
- package/providers/_builtin/cli/cursor-cli/scripts/1.0/scripts.js +0 -7
- package/providers/_builtin/cli/gemini-cli/provider.json +0 -109
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/detect_status.js +0 -26
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_approval.js +0 -22
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/parse_output.js +0 -71
- package/providers/_builtin/cli/gemini-cli/scripts/1.0/scripts.js +0 -12
- package/providers/_builtin/cli/github-copilot-cli/provider.json +0 -37
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/detect_status.js +0 -19
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_approval.js +0 -9
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_output.js +0 -48
- package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/scripts.js +0 -7
- package/providers/_builtin/cli/goose-cli/provider.json +0 -37
- package/providers/_builtin/cli/goose-cli/scripts/1.0/detect_status.js +0 -20
- package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_approval.js +0 -10
- package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_output.js +0 -48
- package/providers/_builtin/cli/goose-cli/scripts/1.0/scripts.js +0 -7
- package/providers/_builtin/cli/opencode-cli/provider.json +0 -37
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/detect_status.js +0 -15
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_approval.js +0 -9
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_output.js +0 -48
- package/providers/_builtin/cli/opencode-cli/scripts/1.0/scripts.js +0 -7
- package/providers/_builtin/docs/CDP_SELECTOR_GUIDE.md +0 -370
- package/providers/_builtin/docs/PROVIDER_GUIDE.md +0 -916
- package/providers/_builtin/extension/cline/provider.json +0 -37
- package/providers/_builtin/extension/cline/scripts/1.0/focus_editor.js +0 -48
- package/providers/_builtin/extension/cline/scripts/1.0/list_chats.js +0 -100
- package/providers/_builtin/extension/cline/scripts/1.0/list_models.js +0 -43
- package/providers/_builtin/extension/cline/scripts/1.0/list_modes.js +0 -35
- package/providers/_builtin/extension/cline/scripts/1.0/new_session.js +0 -85
- package/providers/_builtin/extension/cline/scripts/1.0/open_panel.js +0 -25
- package/providers/_builtin/extension/cline/scripts/1.0/read_chat.js +0 -270
- package/providers/_builtin/extension/cline/scripts/1.0/resolve_action.js +0 -83
- package/providers/_builtin/extension/cline/scripts/1.0/scripts.js +0 -82
- package/providers/_builtin/extension/cline/scripts/1.0/send_message.js +0 -95
- package/providers/_builtin/extension/cline/scripts/1.0/set_mode.js +0 -36
- package/providers/_builtin/extension/cline/scripts/1.0/set_model.js +0 -36
- package/providers/_builtin/extension/cline/scripts/1.0/switch_session.js +0 -206
- package/providers/_builtin/extension/codex/provider.json +0 -38
- package/providers/_builtin/extension/codex/scripts/1.0/click_conversation_webview.js +0 -24
- package/providers/_builtin/extension/codex/scripts/1.0/explore_chat_webview.js +0 -110
- package/providers/_builtin/extension/codex/scripts/1.0/explore_controls_webview.js +0 -75
- package/providers/_builtin/extension/codex/scripts/1.0/explore_dom.js +0 -58
- package/providers/_builtin/extension/codex/scripts/1.0/explore_dropdown_webview.js +0 -64
- package/providers/_builtin/extension/codex/scripts/1.0/inspect_code_webview.js +0 -55
- package/providers/_builtin/extension/codex/scripts/1.0/list_models.js +0 -63
- package/providers/_builtin/extension/codex/scripts/1.0/list_modes.js +0 -140
- package/providers/_builtin/extension/codex/scripts/1.0/message_structure_webview.js +0 -79
- package/providers/_builtin/extension/codex/scripts/1.0/new_session.js +0 -26
- package/providers/_builtin/extension/codex/scripts/1.0/read_chat.js +0 -516
- package/providers/_builtin/extension/codex/scripts/1.0/resolve_action.js +0 -82
- package/providers/_builtin/extension/codex/scripts/1.0/send_message.js +0 -42
- package/providers/_builtin/extension/codex/scripts/1.0/set_mode.js +0 -165
- package/providers/_builtin/extension/codex/scripts/1.0/set_model.js +0 -86
- package/providers/_builtin/extension/roo-code/provider.json +0 -37
- package/providers/_builtin/extension/roo-code/scripts/1.0/scripts.js +0 -82
- package/providers/_builtin/ide/antigravity/provider.json +0 -88
- package/providers/_builtin/ide/antigravity/scripts/1.0/focus_editor.js +0 -20
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_chats.js +0 -137
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_models.js +0 -61
- package/providers/_builtin/ide/antigravity/scripts/1.0/list_modes.js +0 -72
- package/providers/_builtin/ide/antigravity/scripts/1.0/new_session.js +0 -75
- package/providers/_builtin/ide/antigravity/scripts/1.0/read_chat.js +0 -352
- package/providers/_builtin/ide/antigravity/scripts/1.0/resolve_action.js +0 -63
- package/providers/_builtin/ide/antigravity/scripts/1.0/scripts.js +0 -67
- package/providers/_builtin/ide/antigravity/scripts/1.0/send_message.js +0 -56
- package/providers/_builtin/ide/antigravity/scripts/1.0/set_mode.js +0 -67
- package/providers/_builtin/ide/antigravity/scripts/1.0/set_model.js +0 -72
- package/providers/_builtin/ide/antigravity/scripts/1.0/switch_session.js +0 -114
- package/providers/_builtin/ide/cursor/provider.json +0 -70
- package/providers/_builtin/ide/cursor/scripts/1.0/dismiss_notification.js +0 -30
- package/providers/_builtin/ide/cursor/scripts/1.0/focus_editor.js +0 -13
- package/providers/_builtin/ide/cursor/scripts/1.0/list_models.js +0 -78
- package/providers/_builtin/ide/cursor/scripts/1.0/list_modes.js +0 -40
- package/providers/_builtin/ide/cursor/scripts/1.0/list_notifications.js +0 -23
- package/providers/_builtin/ide/cursor/scripts/1.0/list_sessions.js +0 -42
- package/providers/_builtin/ide/cursor/scripts/1.0/new_session.js +0 -20
- package/providers/_builtin/ide/cursor/scripts/1.0/open_panel.js +0 -23
- package/providers/_builtin/ide/cursor/scripts/1.0/read_chat.js +0 -318
- package/providers/_builtin/ide/cursor/scripts/1.0/resolve_action.js +0 -19
- package/providers/_builtin/ide/cursor/scripts/1.0/scripts.js +0 -78
- package/providers/_builtin/ide/cursor/scripts/1.0/send_message.js +0 -23
- package/providers/_builtin/ide/cursor/scripts/1.0/set_mode.js +0 -38
- package/providers/_builtin/ide/cursor/scripts/1.0/set_model.js +0 -81
- package/providers/_builtin/ide/cursor/scripts/1.0/switch_session.js +0 -28
- package/providers/_builtin/ide/kiro/provider.json +0 -68
- package/providers/_builtin/ide/kiro/scripts/1.0/focus_editor.js +0 -20
- package/providers/_builtin/ide/kiro/scripts/1.0/open_panel.js +0 -47
- package/providers/_builtin/ide/kiro/scripts/1.0/resolve_action.js +0 -54
- package/providers/_builtin/ide/kiro/scripts/1.0/send_message.js +0 -29
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_dump_html.js +0 -1
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_models.js +0 -42
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_modes.js +0 -22
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_list_sessions.js +0 -21
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_new_session.js +0 -34
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_read_chat.js +0 -161
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_resolve_action.js +0 -62
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_send_message.js +0 -94
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_mode.js +0 -34
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_set_model.js +0 -47
- package/providers/_builtin/ide/kiro/scripts/1.0/webview_switch_session.js +0 -26
- package/providers/_builtin/ide/pearai/.tmp/after_rich.json +0 -157
- package/providers/_builtin/ide/pearai/.tmp/after_rich_raw.json +0 -161
- package/providers/_builtin/ide/pearai/.tmp/after_switch.json +0 -592
- package/providers/_builtin/ide/pearai/.tmp/after_switch_raw.json +0 -596
- package/providers/_builtin/ide/pearai/.tmp/home_dump_raw.json +0 -176
- package/providers/_builtin/ide/pearai/.tmp/items_raw.json +0 -778
- package/providers/_builtin/ide/pearai/.tmp/webview_dump.json +0 -157
- package/providers/_builtin/ide/pearai/.tmp/webview_dump_raw.json +0 -161
- package/providers/_builtin/ide/pearai/provider.json +0 -71
- package/providers/_builtin/ide/pearai/scripts/1.0/focus_editor.js +0 -16
- package/providers/_builtin/ide/pearai/scripts/1.0/list_models.js +0 -45
- package/providers/_builtin/ide/pearai/scripts/1.0/list_modes.js +0 -44
- package/providers/_builtin/ide/pearai/scripts/1.0/list_sessions.js +0 -93
- package/providers/_builtin/ide/pearai/scripts/1.0/new_session.js +0 -38
- package/providers/_builtin/ide/pearai/scripts/1.0/open_panel.js +0 -23
- package/providers/_builtin/ide/pearai/scripts/1.0/read_chat.js +0 -169
- package/providers/_builtin/ide/pearai/scripts/1.0/resolve_action.js +0 -60
- package/providers/_builtin/ide/pearai/scripts/1.0/scripts.js +0 -111
- package/providers/_builtin/ide/pearai/scripts/1.0/send_message.js +0 -104
- package/providers/_builtin/ide/pearai/scripts/1.0/set_mode.js +0 -51
- package/providers/_builtin/ide/pearai/scripts/1.0/set_model.js +0 -54
- package/providers/_builtin/ide/pearai/scripts/1.0/switch_session.js +0 -81
- package/providers/_builtin/ide/trae/provider.json +0 -72
- package/providers/_builtin/ide/trae/scripts/1.0/focus_editor.js +0 -20
- package/providers/_builtin/ide/trae/scripts/1.0/list_chats.js +0 -24
- package/providers/_builtin/ide/trae/scripts/1.0/list_models.js +0 -39
- package/providers/_builtin/ide/trae/scripts/1.0/list_modes.js +0 -39
- package/providers/_builtin/ide/trae/scripts/1.0/new_session.js +0 -30
- package/providers/_builtin/ide/trae/scripts/1.0/open_panel.js +0 -44
- package/providers/_builtin/ide/trae/scripts/1.0/read_chat.js +0 -113
- package/providers/_builtin/ide/trae/scripts/1.0/resolve_action.js +0 -54
- package/providers/_builtin/ide/trae/scripts/1.0/scripts.js +0 -82
- package/providers/_builtin/ide/trae/scripts/1.0/send_message.js +0 -69
- package/providers/_builtin/ide/trae/scripts/1.0/set_mode.js +0 -15
- package/providers/_builtin/ide/trae/scripts/1.0/set_model.js +0 -15
- package/providers/_builtin/ide/trae/scripts/1.0/switch_session.js +0 -23
- package/providers/_builtin/ide/vscode/provider.json +0 -74
- package/providers/_builtin/ide/vscode/scripts/1.0/focus_editor.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/list_models.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/list_sessions.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/new_session.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/open_panel.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/read_chat.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/resolve_action.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/scripts.js +0 -25
- package/providers/_builtin/ide/vscode/scripts/1.0/send_message.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/set_model.js +0 -1
- package/providers/_builtin/ide/vscode/scripts/1.0/switch_session.js +0 -1
- package/providers/_builtin/ide/vscode-insiders/provider.json +0 -68
- package/providers/_builtin/ide/vscodium/provider.json +0 -69
- package/providers/_builtin/ide/windsurf/provider.json +0 -57
- package/providers/_builtin/ide/windsurf/scripts/1.0/focus_editor.js +0 -36
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_chats.js +0 -23
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_models.js +0 -56
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_modes.js +0 -63
- package/providers/_builtin/ide/windsurf/scripts/1.0/list_sessions.js +0 -79
- package/providers/_builtin/ide/windsurf/scripts/1.0/new_session.js +0 -58
- package/providers/_builtin/ide/windsurf/scripts/1.0/open_panel.js +0 -67
- package/providers/_builtin/ide/windsurf/scripts/1.0/read_chat.js +0 -253
- package/providers/_builtin/ide/windsurf/scripts/1.0/resolve_action.js +0 -82
- package/providers/_builtin/ide/windsurf/scripts/1.0/scripts.js +0 -82
- package/providers/_builtin/ide/windsurf/scripts/1.0/send_message.js +0 -20
- package/providers/_builtin/ide/windsurf/scripts/1.0/set_mode.js +0 -43
- package/providers/_builtin/ide/windsurf/scripts/1.0/set_model.js +0 -49
- package/providers/_builtin/ide/windsurf/scripts/1.0/switch_session.js +0 -82
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/focus_editor.js +0 -30
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_chats.js +0 -117
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_models.js +0 -39
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/list_modes.js +0 -39
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/new_session.js +0 -69
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/open_panel.js +0 -58
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/read_chat.js +0 -315
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/resolve_action.js +0 -68
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/scripts.js +0 -82
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/send_message.js +0 -87
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_mode.js +0 -15
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/set_model.js +0 -15
- package/providers/_builtin/ide/windsurf/scripts/1.0.bak/switch_session.js +0 -58
- package/providers/_builtin/registry.json +0 -376
- package/providers/_builtin/validate.js +0 -156
|
@@ -1,417 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Code — parse_output
|
|
3
|
-
*
|
|
4
|
-
* Reference implementation for CLI PTY parsing:
|
|
5
|
-
* - prefer the visible screen snapshot (`screenText`)
|
|
6
|
-
* - keep transcript state incrementally via `messages`
|
|
7
|
-
* - fall back to noisy rolling buffers when older runtimes do not provide screenText
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
'use strict';
|
|
11
|
-
|
|
12
|
-
const detectStatus = require('./detect_status.js');
|
|
13
|
-
const parseApproval = require('./parse_approval.js');
|
|
14
|
-
|
|
15
|
-
function splitLines(text) {
|
|
16
|
-
return String(text || '')
|
|
17
|
-
.replace(/\u0007/g, '')
|
|
18
|
-
.split(/\r\n|\n|\r/g)
|
|
19
|
-
.map(line => line.replace(/\s+$/, ''));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function sanitizeLine(line) {
|
|
23
|
-
return String(line || '')
|
|
24
|
-
.replace(/\u0007/g, '')
|
|
25
|
-
.replace(/^\d+;/, '')
|
|
26
|
-
.replace(/\s+$/, '');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function normalizeText(text) {
|
|
30
|
-
return String(text || '')
|
|
31
|
-
.replace(/\s+/g, ' ')
|
|
32
|
-
.trim();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function looksLikeSamePrompt(left, right) {
|
|
36
|
-
const a = normalizeText(left);
|
|
37
|
-
const b = normalizeText(right);
|
|
38
|
-
if (!a || !b) return false;
|
|
39
|
-
if (a === b) return true;
|
|
40
|
-
const minLength = Math.min(a.length, b.length);
|
|
41
|
-
if (minLength < 24) return false;
|
|
42
|
-
return a.startsWith(b) || b.startsWith(a) || a.includes(b) || b.includes(a);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function isSpinnerOnlyText(text) {
|
|
46
|
-
const lines = splitLines(text)
|
|
47
|
-
.map(line => stripAssistantPrefix(sanitizeLine(line).trim()))
|
|
48
|
-
.filter(Boolean);
|
|
49
|
-
if (lines.length === 0) return true;
|
|
50
|
-
return lines.every(line => isStatusLine(line) || /^(?:[A-Z][a-z]+ing\u2026?|[✻✶✳✢✽⠂⠐⠒⠓⠦⠴⠶⠷⠿]+)$/.test(line));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function looksLikePromptEchoText(candidate, promptText, previousMessages) {
|
|
54
|
-
const normalizedCandidate = normalizeText(candidate);
|
|
55
|
-
if (!normalizedCandidate) return false;
|
|
56
|
-
if (promptText && looksLikeSamePrompt(normalizedCandidate, promptText)) return true;
|
|
57
|
-
|
|
58
|
-
const lastUser = [...(Array.isArray(previousMessages) ? previousMessages : [])]
|
|
59
|
-
.reverse()
|
|
60
|
-
.find(message => message?.role === 'user' && typeof message.content === 'string');
|
|
61
|
-
return !!lastUser && looksLikeSamePrompt(normalizedCandidate, lastUser.content);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function parsePromptLine(line) {
|
|
65
|
-
const trimmed = sanitizeLine(line).trim();
|
|
66
|
-
const match = trimmed.match(/^[❯›>]\s*(.*)$/);
|
|
67
|
-
if (!match) return null;
|
|
68
|
-
const body = match[1].trim();
|
|
69
|
-
if (/^\d+[.)]\s+/.test(body)) return null;
|
|
70
|
-
return body;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function isBoxLine(trimmed) {
|
|
74
|
-
return /^[─═╭╮╰╯│┌┐└┘├┤┬┴┼]+$/.test(trimmed);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function isFooterLine(trimmed) {
|
|
78
|
-
return /^➜\s+\S+/.test(trimmed)
|
|
79
|
-
|| /^Update available!/i.test(trimmed)
|
|
80
|
-
|| /Claude Code v\d/i.test(trimmed)
|
|
81
|
-
|| /^(Sonnet|Opus|Haiku)\b/i.test(trimmed)
|
|
82
|
-
|| /^[◐◑◒◓◴◵◶◷◸◹◺◿].*\/effort/i.test(trimmed)
|
|
83
|
-
|| /^⏵⏵\s+accept edits on/i.test(trimmed)
|
|
84
|
-
|| /^ctrl\+g to edit in VS Code/i.test(trimmed)
|
|
85
|
-
|| /^✳\s*Claude Code/i.test(trimmed)
|
|
86
|
-
|| /^[▗▖▘▝\s]+~\//.test(trimmed);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function isStatusLine(trimmed) {
|
|
90
|
-
if (!trimmed) return true;
|
|
91
|
-
if (/^[✻✶✳✢✽⠂⠐⠒⠓⠦⠴⠶⠷⠿]+$/.test(trimmed)) return true;
|
|
92
|
-
if (/^[⠂⠐⠒⠓⠦⠴⠶⠷⠿]\s+/.test(trimmed)) return true;
|
|
93
|
-
if (/esc to (cancel|interrupt|stop)/i.test(trimmed)) return true;
|
|
94
|
-
if (/(?:Finagling|Scurrying|Bloviating|Whatchamacallit(?:ing)?|Hatching|Tinkering|Thinking|Processing|Working|Analyzing|Planning|Drafting|Synthesizing|Inspecting|Reading|Searching)\u2026?$/i.test(trimmed)) return true;
|
|
95
|
-
if (/Allow\s*once|Always\s*allow|\(y\/n\)|\[Y\/n\]/i.test(trimmed)) return true;
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function isNoiseLine(line) {
|
|
100
|
-
const trimmed = sanitizeLine(line).trim();
|
|
101
|
-
if (!trimmed) return true;
|
|
102
|
-
if (/^…\s+\+\d+\s+lines\b/i.test(trimmed)) return true;
|
|
103
|
-
if (isBoxLine(trimmed)) return true;
|
|
104
|
-
if (isFooterLine(trimmed)) return true;
|
|
105
|
-
if (isStatusLine(trimmed)) return true;
|
|
106
|
-
if (/^Type your message/i.test(trimmed)) return true;
|
|
107
|
-
if (/^for\s*shortcuts/i.test(trimmed)) return true;
|
|
108
|
-
if (/^\? for help/i.test(trimmed)) return true;
|
|
109
|
-
if (/^Press enter/i.test(trimmed)) return true;
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function stripAssistantPrefix(trimmed) {
|
|
114
|
-
return trimmed
|
|
115
|
-
.replace(/^[⏺•]\s+/, '')
|
|
116
|
-
.replace(/^⎿\s+/, '')
|
|
117
|
-
.replace(/^[✻✶✳✢✽]\s+/, '')
|
|
118
|
-
.trim();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function collectMeaningfulLines(lines) {
|
|
122
|
-
const out = [];
|
|
123
|
-
let captureDetails = false;
|
|
124
|
-
for (let index = 0; index < lines.length; index++) {
|
|
125
|
-
const rawLine = lines[index];
|
|
126
|
-
const promptText = parsePromptLine(rawLine);
|
|
127
|
-
if (promptText !== null) continue;
|
|
128
|
-
|
|
129
|
-
const sanitized = sanitizeLine(rawLine);
|
|
130
|
-
const trimmed = sanitized.trim();
|
|
131
|
-
if (isNoiseLine(trimmed)) continue;
|
|
132
|
-
const nextTrimmed = sanitizeLine(lines[index + 1] || '').trim();
|
|
133
|
-
if (/\u2026\)$/.test(trimmed) && /^⎿\s+/.test(nextTrimmed)) continue;
|
|
134
|
-
|
|
135
|
-
const cleaned = stripAssistantPrefix(trimmed);
|
|
136
|
-
if (!cleaned) continue;
|
|
137
|
-
if (/^⏺\s+/.test(trimmed)) {
|
|
138
|
-
captureDetails = /^(?:Bash|Read|Task)\(/.test(cleaned)
|
|
139
|
-
|| /^(?:Exact output|Output|Result):/i.test(cleaned);
|
|
140
|
-
if (out[out.length - 1] !== cleaned) out.push(cleaned);
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (/^⎿\s+/.test(trimmed)) {
|
|
145
|
-
if (!captureDetails || /^…\s+\+\d+\s+lines\b/i.test(cleaned)) continue;
|
|
146
|
-
if (out[out.length - 1] !== cleaned) out.push(cleaned);
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (!captureDetails && /^\d+\s+/.test(trimmed)) continue;
|
|
151
|
-
if (cleaned.length === 1 && /^[A-Za-z]$/.test(cleaned)) continue;
|
|
152
|
-
if (out[out.length - 1] !== cleaned) out.push(cleaned);
|
|
153
|
-
}
|
|
154
|
-
return out;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function looksLikeStructuredDataLine(text) {
|
|
158
|
-
const line = stripAssistantPrefix(sanitizeLine(text).trim());
|
|
159
|
-
if (!line) return false;
|
|
160
|
-
return /^[{\[]/.test(line)
|
|
161
|
-
|| /^[A-Z0-9_]+=/.test(line)
|
|
162
|
-
|| /^\/[A-Za-z0-9._/-]+$/.test(line)
|
|
163
|
-
|| /^\d+$/.test(line);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function extractDenseOutputBlock(text) {
|
|
167
|
-
const lines = splitLines(text);
|
|
168
|
-
const blocks = [];
|
|
169
|
-
let current = [];
|
|
170
|
-
|
|
171
|
-
for (const rawLine of lines) {
|
|
172
|
-
const promptText = parsePromptLine(rawLine);
|
|
173
|
-
const sanitized = sanitizeLine(rawLine).trim();
|
|
174
|
-
if (promptText !== null || isNoiseLine(sanitized)) {
|
|
175
|
-
if (current.length > 0) {
|
|
176
|
-
blocks.push(current);
|
|
177
|
-
current = [];
|
|
178
|
-
}
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const cleaned = stripAssistantPrefix(sanitized);
|
|
183
|
-
if (!cleaned) {
|
|
184
|
-
if (current.length > 0) {
|
|
185
|
-
blocks.push(current);
|
|
186
|
-
current = [];
|
|
187
|
-
}
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
current.push(cleaned);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (current.length > 0) blocks.push(current);
|
|
194
|
-
|
|
195
|
-
const scored = blocks
|
|
196
|
-
.map(block => ({
|
|
197
|
-
block,
|
|
198
|
-
structured: block.filter(looksLikeStructuredDataLine).length,
|
|
199
|
-
}))
|
|
200
|
-
.filter(entry => entry.block.length >= 5 && entry.structured >= Math.max(3, Math.floor(entry.block.length * 0.6)));
|
|
201
|
-
|
|
202
|
-
const mergeBlocks = (existing, next) => {
|
|
203
|
-
if (existing.length === 0) return [...next];
|
|
204
|
-
const maxOverlap = Math.min(existing.length, next.length);
|
|
205
|
-
for (let overlap = maxOverlap; overlap >= 1; overlap--) {
|
|
206
|
-
let matches = true;
|
|
207
|
-
for (let i = 0; i < overlap; i++) {
|
|
208
|
-
if (existing[existing.length - overlap + i] !== next[i]) {
|
|
209
|
-
matches = false;
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
if (matches) {
|
|
214
|
-
return existing.concat(next.slice(overlap));
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return existing.concat(next);
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const merged = scored.reduce((acc, entry) => mergeBlocks(acc, entry.block), []);
|
|
221
|
-
return merged.join('\n').trim();
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function collectAssistantBlocks(lines) {
|
|
225
|
-
const blocks = [];
|
|
226
|
-
let current = null;
|
|
227
|
-
for (const rawLine of lines) {
|
|
228
|
-
const sanitized = sanitizeLine(rawLine);
|
|
229
|
-
const trimmed = sanitized.trim();
|
|
230
|
-
if (!trimmed || isNoiseLine(trimmed)) continue;
|
|
231
|
-
|
|
232
|
-
if (/^⏺\s+/.test(trimmed)) {
|
|
233
|
-
const title = stripAssistantPrefix(trimmed);
|
|
234
|
-
if (!title) {
|
|
235
|
-
current = null;
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
current = {
|
|
239
|
-
title,
|
|
240
|
-
lines: [title],
|
|
241
|
-
isTool: /^(?:Bash|Read|Write|Edit|MultiEdit|Task|Glob|Grep|LS|NotebookEdit)\(/.test(title),
|
|
242
|
-
};
|
|
243
|
-
blocks.push(current);
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (!current) continue;
|
|
248
|
-
const cleaned = stripAssistantPrefix(trimmed);
|
|
249
|
-
if (!cleaned || /^…\s+\+\d+\s+lines\b/i.test(cleaned)) continue;
|
|
250
|
-
current.lines.push(cleaned);
|
|
251
|
-
}
|
|
252
|
-
return blocks;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function extractVisibleTurn(text, previousMessages) {
|
|
256
|
-
const lines = splitLines(text);
|
|
257
|
-
const emptyPromptIndex = (() => {
|
|
258
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
259
|
-
if (parsePromptLine(lines[i]) === '') return i;
|
|
260
|
-
}
|
|
261
|
-
return -1;
|
|
262
|
-
})();
|
|
263
|
-
|
|
264
|
-
const userPrompt = (() => {
|
|
265
|
-
const upperBound = emptyPromptIndex >= 0 ? emptyPromptIndex - 1 : lines.length - 1;
|
|
266
|
-
for (let i = upperBound; i >= 0; i--) {
|
|
267
|
-
const parsed = parsePromptLine(lines[i]);
|
|
268
|
-
if (parsed) return { index: i, text: parsed };
|
|
269
|
-
}
|
|
270
|
-
return { index: -1, text: '' };
|
|
271
|
-
})();
|
|
272
|
-
|
|
273
|
-
const promptLines = [];
|
|
274
|
-
let assistantStart = userPrompt.index >= 0 ? userPrompt.index + 1 : 0;
|
|
275
|
-
if (userPrompt.index >= 0) {
|
|
276
|
-
promptLines.push(userPrompt.text);
|
|
277
|
-
for (let i = userPrompt.index + 1; i < lines.length; i++) {
|
|
278
|
-
const trimmed = sanitizeLine(lines[i]).trim();
|
|
279
|
-
if (!trimmed) {
|
|
280
|
-
assistantStart = i + 1;
|
|
281
|
-
break;
|
|
282
|
-
}
|
|
283
|
-
if (/^[⏺•]/.test(trimmed) || isBoxLine(trimmed) || isFooterLine(trimmed) || isStatusLine(trimmed) || /^([❯›>]\s*)?\d+[.)]\s+/.test(trimmed)) {
|
|
284
|
-
assistantStart = i;
|
|
285
|
-
break;
|
|
286
|
-
}
|
|
287
|
-
promptLines.push(trimmed);
|
|
288
|
-
assistantStart = i + 1;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const end = emptyPromptIndex >= 0 ? emptyPromptIndex : lines.length;
|
|
293
|
-
const assistantWindow = lines.slice(assistantStart, end);
|
|
294
|
-
const blocks = collectAssistantBlocks(assistantWindow);
|
|
295
|
-
const lastNarrativeBlock = [...blocks].reverse().find(block => !block.isTool);
|
|
296
|
-
let assistantLines = lastNarrativeBlock
|
|
297
|
-
? lastNarrativeBlock.lines
|
|
298
|
-
: collectMeaningfulLines(assistantWindow);
|
|
299
|
-
|
|
300
|
-
if (assistantLines.length === 0 && Array.isArray(previousMessages) && previousMessages.length > 0) {
|
|
301
|
-
assistantLines = collectMeaningfulLines(lines);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return {
|
|
305
|
-
promptText: promptLines.join(' ').trim(),
|
|
306
|
-
assistantText: assistantLines.join('\n').trim(),
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
function extractPartialAssistant(text) {
|
|
311
|
-
const meaningful = collectMeaningfulLines(splitLines(text));
|
|
312
|
-
return meaningful.join('\n').trim();
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
function buildMessages(previousMessages, promptText, assistantText, partialText) {
|
|
316
|
-
const base = Array.isArray(previousMessages)
|
|
317
|
-
? previousMessages
|
|
318
|
-
.filter(message => message && (message.role === 'user' || message.role === 'assistant'))
|
|
319
|
-
.map(message => ({
|
|
320
|
-
role: message.role,
|
|
321
|
-
content: typeof message.content === 'string' ? message.content : String(message.content || ''),
|
|
322
|
-
timestamp: message.timestamp,
|
|
323
|
-
}))
|
|
324
|
-
: [];
|
|
325
|
-
|
|
326
|
-
if (!promptText && base.length === 0) {
|
|
327
|
-
return base;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (promptText) {
|
|
331
|
-
const normalizedPrompt = normalizeText(promptText);
|
|
332
|
-
const last = base[base.length - 1];
|
|
333
|
-
const previousUser = last?.role === 'assistant' ? base[base.length - 2] : last;
|
|
334
|
-
if (!previousUser || previousUser.role !== 'user' || !looksLikeSamePrompt(previousUser.content, normalizedPrompt)) {
|
|
335
|
-
base.push({ role: 'user', content: promptText });
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
const candidateAssistant = assistantText || partialText;
|
|
340
|
-
if (!candidateAssistant) return base;
|
|
341
|
-
|
|
342
|
-
const normalizedAssistant = normalizeText(candidateAssistant);
|
|
343
|
-
if (!normalizedAssistant) return base;
|
|
344
|
-
if (looksLikePromptEchoText(candidateAssistant, promptText, previousMessages)) return base;
|
|
345
|
-
if (!assistantText && isSpinnerOnlyText(candidateAssistant)) return base;
|
|
346
|
-
|
|
347
|
-
const last = base[base.length - 1];
|
|
348
|
-
if (last && last.role === 'assistant') {
|
|
349
|
-
if (normalizeText(last.content) !== normalizedAssistant) {
|
|
350
|
-
last.content = candidateAssistant;
|
|
351
|
-
}
|
|
352
|
-
} else {
|
|
353
|
-
base.push({ role: 'assistant', content: candidateAssistant });
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
return base;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
function toMessageObjects(messages, status) {
|
|
360
|
-
return messages.slice(-50).map((message, index, slice) => ({
|
|
361
|
-
id: `msg_${index}`,
|
|
362
|
-
role: message.role,
|
|
363
|
-
content: typeof message.content === 'string' && message.content.length > 6000
|
|
364
|
-
? message.content.slice(0, 6000) + '\n[... truncated]'
|
|
365
|
-
: message.content,
|
|
366
|
-
index,
|
|
367
|
-
kind: 'standard',
|
|
368
|
-
...(status === 'generating' && index === slice.length - 1 && message.role === 'assistant'
|
|
369
|
-
? { meta: { streaming: true } }
|
|
370
|
-
: {}),
|
|
371
|
-
}));
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
module.exports = function parseOutput(input) {
|
|
375
|
-
const screenText = String(input?.screenText || '');
|
|
376
|
-
const buffer = String(input?.buffer || '');
|
|
377
|
-
const terminalHistory = String(input?.terminalHistory || '');
|
|
378
|
-
const tail = String(input?.recentBuffer || (screenText || buffer).slice(-500));
|
|
379
|
-
const previousMessages = Array.isArray(input?.messages) ? input.messages : [];
|
|
380
|
-
const transcriptSource = screenText || buffer;
|
|
381
|
-
|
|
382
|
-
const status = detectStatus({
|
|
383
|
-
tail,
|
|
384
|
-
screenText,
|
|
385
|
-
rawBuffer: input?.rawBuffer || '',
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
const activeModal = status === 'waiting_approval'
|
|
389
|
-
? parseApproval({ buffer: screenText || buffer, rawBuffer: input?.rawBuffer || '', tail })
|
|
390
|
-
: null;
|
|
391
|
-
|
|
392
|
-
const { promptText, assistantText: visibleAssistantText } = status === 'waiting_approval'
|
|
393
|
-
? { promptText: '', assistantText: '' }
|
|
394
|
-
: extractVisibleTurn(transcriptSource, previousMessages);
|
|
395
|
-
const denseTerminalOutput = extractDenseOutputBlock(terminalHistory || buffer);
|
|
396
|
-
const assistantText = denseTerminalOutput || visibleAssistantText;
|
|
397
|
-
const rawPartialText = status === 'generating'
|
|
398
|
-
? extractPartialAssistant(input?.partialResponse || '')
|
|
399
|
-
: '';
|
|
400
|
-
const partialText = (!rawPartialText
|
|
401
|
-
|| isSpinnerOnlyText(rawPartialText)
|
|
402
|
-
|| looksLikePromptEchoText(rawPartialText, promptText, previousMessages))
|
|
403
|
-
? ''
|
|
404
|
-
: rawPartialText;
|
|
405
|
-
const messages = toMessageObjects(
|
|
406
|
-
buildMessages(previousMessages, promptText, assistantText, partialText),
|
|
407
|
-
status
|
|
408
|
-
);
|
|
409
|
-
|
|
410
|
-
return {
|
|
411
|
-
id: 'cli_session',
|
|
412
|
-
status,
|
|
413
|
-
title: 'Claude Code',
|
|
414
|
-
messages,
|
|
415
|
-
activeModal,
|
|
416
|
-
};
|
|
417
|
-
};
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Code CLI Scripts — v1.0
|
|
3
|
-
*
|
|
4
|
-
* CLI scripts differ from IDE scripts:
|
|
5
|
-
* - IDE scripts return JS code strings for CDP evaluate (browser context)
|
|
6
|
-
* - CLI scripts are Node.js functions that receive PTY buffer and return structured data
|
|
7
|
-
*
|
|
8
|
-
* Each export receives an `input` object:
|
|
9
|
-
* { buffer: string, rawBuffer: string, recentBuffer: string, messages: Array }
|
|
10
|
-
* and returns a result conforming to the output contract.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
'use strict';
|
|
14
|
-
|
|
15
|
-
const fs = require('fs');
|
|
16
|
-
const path = require('path');
|
|
17
|
-
const DIR = __dirname;
|
|
18
|
-
|
|
19
|
-
function loadModule(name) {
|
|
20
|
-
try { return require(path.join(DIR, name)); }
|
|
21
|
-
catch { return null; }
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// ─── Core ───
|
|
25
|
-
|
|
26
|
-
/** Parse full PTY output → ReadChatResult */
|
|
27
|
-
module.exports.parseOutput = (input) => {
|
|
28
|
-
const mod = loadModule('parse_output.js');
|
|
29
|
-
return mod ? mod(input) : null;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/** Lightweight status detection (100ms polling) → AgentStatus string */
|
|
33
|
-
module.exports.detectStatus = (input) => {
|
|
34
|
-
const mod = loadModule('detect_status.js');
|
|
35
|
-
return mod ? mod(input) : null;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/** Parse approval modal from PTY output → ModalInfo | null */
|
|
39
|
-
module.exports.parseApproval = (input) => {
|
|
40
|
-
const mod = loadModule('parse_approval.js');
|
|
41
|
-
return mod ? mod(input) : null;
|
|
42
|
-
};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"type": "codex-cli",
|
|
3
|
-
"name": "Codex CLI",
|
|
4
|
-
"category": "cli",
|
|
5
|
-
"aliases": [
|
|
6
|
-
"codex"
|
|
7
|
-
],
|
|
8
|
-
"icon": "🧠",
|
|
9
|
-
"displayName": "Codex 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
|
-
"notifications": {
|
|
23
|
-
"type": "boolean",
|
|
24
|
-
"default": true,
|
|
25
|
-
"public": true,
|
|
26
|
-
"label": "Notifications",
|
|
27
|
-
"description": "Display notifications on state changes"
|
|
28
|
-
},
|
|
29
|
-
"autoApprove": {
|
|
30
|
-
"type": "boolean",
|
|
31
|
-
"default": false,
|
|
32
|
-
"public": true,
|
|
33
|
-
"label": "Auto Approve",
|
|
34
|
-
"description": "Automatically approve all tool calls without user confirmation"
|
|
35
|
-
},
|
|
36
|
-
"approvalAlert": {
|
|
37
|
-
"type": "boolean",
|
|
38
|
-
"default": true,
|
|
39
|
-
"public": true,
|
|
40
|
-
"label": "Approval Notifications",
|
|
41
|
-
"description": "Show notification when approval is needed"
|
|
42
|
-
},
|
|
43
|
-
"longGeneratingAlert": {
|
|
44
|
-
"type": "boolean",
|
|
45
|
-
"default": true,
|
|
46
|
-
"public": true,
|
|
47
|
-
"label": "Long Generation Alert",
|
|
48
|
-
"description": "Alert when generation takes too long"
|
|
49
|
-
},
|
|
50
|
-
"longGeneratingThresholdSec": {
|
|
51
|
-
"type": "number",
|
|
52
|
-
"default": 180,
|
|
53
|
-
"public": true,
|
|
54
|
-
"label": "Long Generation Threshold (sec)",
|
|
55
|
-
"min": 30,
|
|
56
|
-
"max": 600
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
"binary": "codex",
|
|
60
|
-
"sendDelayMs": 1200,
|
|
61
|
-
"sendKey": "\r",
|
|
62
|
-
"spawn": {
|
|
63
|
-
"command": "codex",
|
|
64
|
-
"args": [],
|
|
65
|
-
"shell": false,
|
|
66
|
-
"env": {}
|
|
67
|
-
},
|
|
68
|
-
"patterns": {
|
|
69
|
-
"prompt": [
|
|
70
|
-
{ "source": "To get started, describe a task or try one of these commands", "flags": "i" },
|
|
71
|
-
{ "source": "^>\\s*$", "flags": "m" }
|
|
72
|
-
],
|
|
73
|
-
"generating": [
|
|
74
|
-
{ "source": "Working \\(\\d+s", "flags": "i" }
|
|
75
|
-
],
|
|
76
|
-
"approval": [
|
|
77
|
-
{ "source": "Always approve this session", "flags": "i" },
|
|
78
|
-
{ "source": "Approve and run now", "flags": "i" },
|
|
79
|
-
{ "source": "Allow command\\?", "flags": "i" }
|
|
80
|
-
],
|
|
81
|
-
"ready": []
|
|
82
|
-
},
|
|
83
|
-
"compatibility": [
|
|
84
|
-
{
|
|
85
|
-
"ideVersion": ">=0.42.0",
|
|
86
|
-
"scriptDir": "scripts/1.0"
|
|
87
|
-
}
|
|
88
|
-
],
|
|
89
|
-
"defaultScriptDir": "scripts/1.0"
|
|
90
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Codex CLI — detect_status
|
|
3
|
-
*/
|
|
4
|
-
'use strict';
|
|
5
|
-
|
|
6
|
-
function sourceText(input) {
|
|
7
|
-
return `${String(input?.screenText || '')}\n${String(input?.tail || '')}`;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function hasWelcomeScreen(text) {
|
|
11
|
-
return /OpenAI Codex/i.test(text)
|
|
12
|
-
&& /To get started, describe a task/i.test(text);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function hasStartupApproval(text) {
|
|
16
|
-
return /You are running Codex in/i.test(text)
|
|
17
|
-
&& /Press Enter to continue/i.test(text)
|
|
18
|
-
&& /(?:^|\n)[▌> \t]*1\.\s+/m.test(text)
|
|
19
|
-
&& /(?:^|\n)[▌> \t]*2\.\s+/m.test(text);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function hasCommandApproval(text) {
|
|
23
|
-
const hasAllowPrompt = /Allow Codex to (?:run|apply)/i.test(text)
|
|
24
|
-
|| /Allow command\?/i.test(text);
|
|
25
|
-
const hasButtons = /Approve and run now/i.test(text)
|
|
26
|
-
|| /Always approve this session/i.test(text)
|
|
27
|
-
|| /(?:^|\n)[▌> \t]*1\.\s+.*(?:approve|allow|run)/im.test(text)
|
|
28
|
-
|| /(?:^|\n)[▌> \t]*2\.\s+.*(?:always|session)/im.test(text);
|
|
29
|
-
const hasFooter = /Press Enter to confirm/i.test(text)
|
|
30
|
-
|| /Esc to cancel/i.test(text);
|
|
31
|
-
return hasAllowPrompt
|
|
32
|
-
|| (hasButtons && hasFooter)
|
|
33
|
-
|| /Approve and run now/i.test(text)
|
|
34
|
-
|| /Always approve this session/i.test(text)
|
|
35
|
-
|| /(?:^|\n)[▌> \t]*1\.\s+.*(?:approve|allow|run)/im.test(text);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
module.exports = function detectStatus(input) {
|
|
39
|
-
const text = sourceText(input);
|
|
40
|
-
if (!text.trim()) return 'idle';
|
|
41
|
-
|
|
42
|
-
if (hasStartupApproval(text) || hasCommandApproval(text)) return 'waiting_approval';
|
|
43
|
-
|
|
44
|
-
if (/Esc to interrupt/i.test(text)) return 'generating';
|
|
45
|
-
if (/(?:Thinking|Planning|Searching|Reading|Working|Analyzing|Inspecting|Responding|Following instructions clearly)[^\n]*\(\d+s\b/i.test(text)) {
|
|
46
|
-
return 'generating';
|
|
47
|
-
}
|
|
48
|
-
if (/[⠁-⣿]/.test(text) && /(?:Working|Thinking|Esc to interrupt)/i.test(text)) return 'generating';
|
|
49
|
-
|
|
50
|
-
if (hasWelcomeScreen(text)) return 'idle';
|
|
51
|
-
if (/⏎\s+send/i.test(text)) return 'idle';
|
|
52
|
-
|
|
53
|
-
return 'idle';
|
|
54
|
-
};
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Codex CLI — parse_approval
|
|
3
|
-
*/
|
|
4
|
-
'use strict';
|
|
5
|
-
|
|
6
|
-
function splitLines(text) {
|
|
7
|
-
return String(text || '')
|
|
8
|
-
.replace(/\u0007/g, '')
|
|
9
|
-
.split(/\r\n|\n|\r/g)
|
|
10
|
-
.map(line => line.replace(/\s+$/, ''));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function normalize(line) {
|
|
14
|
-
return String(line || '')
|
|
15
|
-
.replace(/\u0007/g, '')
|
|
16
|
-
.replace(/^\d+;/, '')
|
|
17
|
-
.replace(/\s+/g, ' ')
|
|
18
|
-
.trim();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function isBoxLine(line) {
|
|
22
|
-
return /^[─═╭╮╰╯│┌┐└┘├┤┬┴┼]+$/.test(line);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function isFooterLine(line) {
|
|
26
|
-
return /⏎\s+send/i.test(line)
|
|
27
|
-
|| /⌃J\s+newline/i.test(line)
|
|
28
|
-
|| /⌃T\s+transcript/i.test(line)
|
|
29
|
-
|| /⌃C\s+quit/i.test(line)
|
|
30
|
-
|| /Press Enter to (?:continue|confirm)/i.test(line)
|
|
31
|
-
|| /Esc to cancel/i.test(line);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function stripLeadingMarkers(s) {
|
|
35
|
-
return s.replace(/^(?:[▌>]\s*)+/, '').trim();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function normalizeButton(line) {
|
|
39
|
-
return stripLeadingMarkers(normalize(line))
|
|
40
|
-
.replace(/^\d+\.\s+/, '')
|
|
41
|
-
.replace(/\s{2,}\([A-Za-z]\)\s.*$/, '')
|
|
42
|
-
.trim();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function isButtonLine(line) {
|
|
46
|
-
return /^\d+\.\s+/.test(stripLeadingMarkers(normalize(line)));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
module.exports = function parseApproval(input) {
|
|
50
|
-
const text = String(input?.buffer || input?.tail || '');
|
|
51
|
-
const lines = splitLines(text);
|
|
52
|
-
if (lines.length === 0) return null;
|
|
53
|
-
|
|
54
|
-
const buttons = [];
|
|
55
|
-
let currentButton = '';
|
|
56
|
-
const recentLines = lines.slice(-60);
|
|
57
|
-
for (const rawLine of recentLines) {
|
|
58
|
-
const line = normalize(rawLine);
|
|
59
|
-
if (!line) continue;
|
|
60
|
-
if (isButtonLine(rawLine)) {
|
|
61
|
-
if (currentButton && !buttons.includes(currentButton)) buttons.push(currentButton);
|
|
62
|
-
currentButton = normalizeButton(rawLine);
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (!currentButton) continue;
|
|
66
|
-
if (isFooterLine(line) || isBoxLine(line)) continue;
|
|
67
|
-
if (/^(?:model|directory):/i.test(line)) continue;
|
|
68
|
-
const continuation = stripLeadingMarkers(line);
|
|
69
|
-
if (!continuation) continue;
|
|
70
|
-
currentButton = `${currentButton} ${continuation}`.replace(/\s+/g, ' ').trim();
|
|
71
|
-
}
|
|
72
|
-
if (currentButton && !buttons.includes(currentButton)) buttons.push(currentButton);
|
|
73
|
-
|
|
74
|
-
const approvalText = lines
|
|
75
|
-
.map(normalize)
|
|
76
|
-
.filter(line => line && !isBoxLine(line) && !isButtonLine(line) && !isFooterLine(line))
|
|
77
|
-
.filter(line => !/^OpenAI Codex\b/i.test(line))
|
|
78
|
-
.filter(line => !/^model:/i.test(line))
|
|
79
|
-
.filter(line => !/^directory:/i.test(line));
|
|
80
|
-
|
|
81
|
-
const hasApproval = /You are running Codex in/i.test(text)
|
|
82
|
-
|| /Allow Codex to (?:run|apply)/i.test(text)
|
|
83
|
-
|| /Allow command\?/i.test(text)
|
|
84
|
-
|| buttons.length > 0;
|
|
85
|
-
if (!hasApproval) return null;
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
message: approvalText.slice(-3).join(' ').slice(0, 240) || 'Codex approval required',
|
|
89
|
-
buttons: buttons.length > 0 ? buttons : ['Approve', 'Deny'],
|
|
90
|
-
};
|
|
91
|
-
};
|