@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.56",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"license": "AGPL-3.0-or-later",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@agentclientprotocol/sdk": "^0.16.1",
|
|
34
|
+
"@xterm/xterm": "^6.0.0",
|
|
34
35
|
"chalk": "^5.3.0",
|
|
35
36
|
"conf": "^13.0.0",
|
|
36
37
|
"ws": "^8.19.0"
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Provider Helpers —
|
|
2
|
+
* Provider Helpers — Shared utilities
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Common functions available via require in each provider.js.
|
|
5
|
+
* Usage is optional — each provider.js can be self-contained.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Usage (inside provider.js):
|
|
8
8
|
* const { getWebviewDoc, htmlToMd, waitFor } = require('../../_helpers/index.js');
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
* @param {string} [selector='iframe'] - iframe
|
|
14
|
-
* @returns {string} CDP evaluate
|
|
12
|
+
* Access contentDocument of extension webview iframe
|
|
13
|
+
* @param {string} [selector='iframe'] - iframe selector
|
|
14
|
+
* @returns {string} JS code for CDP evaluate (sets document variable)
|
|
15
15
|
*/
|
|
16
16
|
function getWebviewDoc(selector = 'iframe') {
|
|
17
17
|
return `
|
|
@@ -21,11 +21,11 @@ function getWebviewDoc(selector = 'iframe') {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
* React Fiber
|
|
25
|
-
*
|
|
26
|
-
* @param {string[]} entrySelectors -
|
|
27
|
-
* @param {number} [maxDepth=200] - Fiber
|
|
28
|
-
* @returns {string} CDP evaluate
|
|
24
|
+
* React Fiber data extraction helper code
|
|
25
|
+
* Traverse memoizedState starting from specific entry points
|
|
26
|
+
* @param {string[]} entrySelectors - Entry point CSS selectors
|
|
27
|
+
* @param {number} [maxDepth=200] - Max Fiber tree traversal depth
|
|
28
|
+
* @returns {string} JS code for CDP evaluate (sets _fiberData variable)
|
|
29
29
|
*/
|
|
30
30
|
function getFiber(entrySelectors, maxDepth = 200) {
|
|
31
31
|
const sels = JSON.stringify(entrySelectors);
|
|
@@ -61,10 +61,10 @@ function getFiber(entrySelectors, maxDepth = 200) {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
*
|
|
65
|
-
* @param {string} varName -
|
|
66
|
-
* @param {string} selectorExpr -
|
|
67
|
-
* @returns {string} CDP evaluate
|
|
64
|
+
* Generate text input + Enter submission code
|
|
65
|
+
* @param {string} varName - Variable name containing the text
|
|
66
|
+
* @param {string} selectorExpr - JS expression referencing the editor element
|
|
67
|
+
* @returns {string} JS code for CDP evaluate
|
|
68
68
|
*/
|
|
69
69
|
function typeAndSubmit(varName, selectorExpr) {
|
|
70
70
|
return `
|
|
@@ -85,10 +85,10 @@ function typeAndSubmit(varName, selectorExpr) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
*
|
|
89
|
-
* @param {string} selector - CSS
|
|
90
|
-
* @param {number} [timeout=5000] -
|
|
91
|
-
* @returns {string} CDP evaluate
|
|
88
|
+
* Generate element wait code
|
|
89
|
+
* @param {string} selector - CSS selector
|
|
90
|
+
* @param {number} [timeout=5000] - Max wait time (ms)
|
|
91
|
+
* @returns {string} JS code for CDP evaluate (expression → element or null)
|
|
92
92
|
*/
|
|
93
93
|
function waitFor(selector, timeout = 5000) {
|
|
94
94
|
return `
|
|
@@ -106,9 +106,9 @@ function waitFor(selector, timeout = 5000) {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
|
-
* HTML → Markdown
|
|
110
|
-
*
|
|
111
|
-
* @returns {string} htmlToMd, childrenToMd
|
|
109
|
+
* HTML → Markdown conversion function (CDP code string)
|
|
110
|
+
* Dashboard uses ReactMarkdown+remarkGfm, so HTML must be converted to GFM
|
|
111
|
+
* @returns {string} htmlToMd, childrenToMd function declaration code
|
|
112
112
|
*/
|
|
113
113
|
function htmlToMdCode() {
|
|
114
114
|
return `
|
|
@@ -166,9 +166,9 @@ function htmlToMdCode() {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
|
-
*
|
|
170
|
-
* @param {string} text -
|
|
171
|
-
* @returns {boolean} true
|
|
169
|
+
* Noise text filtering (status messages, MCP, etc.)
|
|
170
|
+
* @param {string} text - Original text
|
|
171
|
+
* @returns {boolean} true if noise
|
|
172
172
|
*/
|
|
173
173
|
function isNoiseText(text) {
|
|
174
174
|
const low = (text || '').trim().toLowerCase();
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "aider-cli",
|
|
3
|
+
"name": "Aider",
|
|
4
|
+
"category": "cli",
|
|
5
|
+
"aliases": [
|
|
6
|
+
"aider"
|
|
7
|
+
],
|
|
8
|
+
"icon": "🤖",
|
|
9
|
+
"displayName": "Aider",
|
|
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": "aider",
|
|
24
|
+
"spawn": {
|
|
25
|
+
"command": "aider",
|
|
26
|
+
"args": [],
|
|
27
|
+
"shell": true,
|
|
28
|
+
"env": {}
|
|
29
|
+
},
|
|
30
|
+
"compatibility": [
|
|
31
|
+
{
|
|
32
|
+
"ideVersion": ">=0.86.0",
|
|
33
|
+
"scriptDir": "scripts/1.0"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"defaultScriptDir": "scripts/1.0"
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aider — detect_status
|
|
3
|
+
* Aider uses a simpler TUI with '>' prompts and tool output markers.
|
|
4
|
+
*/
|
|
5
|
+
'use strict';
|
|
6
|
+
module.exports = function detectStatus(input) {
|
|
7
|
+
const { tail } = input;
|
|
8
|
+
if (!tail) return 'idle';
|
|
9
|
+
// Aider approval: "Allow creation of new file" / "Run shell command?"
|
|
10
|
+
if (/Allow\s*creation/i.test(tail) && /\(y\/n\)/i.test(tail)) return 'waiting_approval';
|
|
11
|
+
if (/Run\s*shell\s*command/i.test(tail)) return 'waiting_approval';
|
|
12
|
+
if (/Apply\s*(edit|change)/i.test(tail) && /\(y\/n\)/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|Sending|Streaming/i.test(tail)) return 'generating';
|
|
17
|
+
// Aider shows "Tokens:" after completion — if we see that, it's idle
|
|
18
|
+
if (/Tokens:/i.test(tail)) return 'idle';
|
|
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 = /Allow\s*creation/i.test(tail) || /Run\s*shell\s*command/i.test(tail) ||
|
|
6
|
+
/Apply\s*(edit|change)/i.test(tail) || /\(y\/n\)/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: ['Yes (y)', 'No (n)'] };
|
|
10
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
// Aider prompt is just '>' at start of line
|
|
13
|
+
const userMatch = trimmed.match(/^[❯›>]\s+(.+)$/);
|
|
14
|
+
if (userMatch && userMatch[1].length > 1) {
|
|
15
|
+
started = true;
|
|
16
|
+
if (currentRole && currentContent.length > 0) {
|
|
17
|
+
const text = currentContent.join('\n').trim();
|
|
18
|
+
if (text.length > 1) { messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' }); msgIndex++; }
|
|
19
|
+
}
|
|
20
|
+
currentRole = 'user'; currentContent = [userMatch[1]]; continue;
|
|
21
|
+
}
|
|
22
|
+
if (!started) continue;
|
|
23
|
+
if (currentRole === 'user' && trimmed && !userMatch) {
|
|
24
|
+
const text = currentContent.join('\n').trim();
|
|
25
|
+
if (text.length > 1) { messages.push({ id: `msg_${msgIndex}`, role: 'user', content: text, index: msgIndex, kind: 'standard' }); msgIndex++; }
|
|
26
|
+
currentRole = 'assistant'; currentContent = [];
|
|
27
|
+
}
|
|
28
|
+
if (!trimmed || /^[\u2800-\u28ff]+$/.test(trimmed)) continue;
|
|
29
|
+
if (currentRole) currentContent.push(trimmed);
|
|
30
|
+
}
|
|
31
|
+
if (currentRole && currentContent.length > 0) {
|
|
32
|
+
const text = currentContent.join('\n').trim();
|
|
33
|
+
if (text.length > 1) messages.push({ id: `msg_${msgIndex}`, role: currentRole, content: text.slice(0, 6000), index: msgIndex, kind: 'standard' });
|
|
34
|
+
}
|
|
35
|
+
return messages.length > 50 ? messages.slice(-50) : messages;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = function parseOutput(input) {
|
|
39
|
+
const { buffer, recentBuffer, partialResponse, screenText } = input;
|
|
40
|
+
const transcript = screenText || buffer;
|
|
41
|
+
const tail = recentBuffer || (transcript || '').slice(-500);
|
|
42
|
+
const status = detectStatus({ tail });
|
|
43
|
+
const activeModal = status === 'waiting_approval' ? parseApproval({ buffer: transcript, tail }) : null;
|
|
44
|
+
const messages = splitTurns(transcript);
|
|
45
|
+
if (status === 'generating' && partialResponse && partialResponse.trim().length > 2) {
|
|
46
|
+
messages.push({ id: 'msg_partial', role: 'assistant', content: partialResponse.trim().slice(0, 6000), index: messages.length, kind: 'standard', meta: { streaming: true } });
|
|
47
|
+
}
|
|
48
|
+
return { id: 'cli_session', status, title: 'Aider', messages, activeModal };
|
|
49
|
+
};
|
|
@@ -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; };
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"settings": {
|
|
12
12
|
"mode": {
|
|
13
13
|
"type": "select",
|
|
14
|
-
"default": "
|
|
14
|
+
"default": "chat",
|
|
15
15
|
"public": true,
|
|
16
16
|
"label": "Display Mode",
|
|
17
17
|
"description": "terminal: Native PTY view, chat: Parsed message view",
|
|
@@ -98,5 +98,12 @@
|
|
|
98
98
|
"0": "1",
|
|
99
99
|
"1": "2",
|
|
100
100
|
"2": "3"
|
|
101
|
-
}
|
|
101
|
+
},
|
|
102
|
+
"compatibility": [
|
|
103
|
+
{
|
|
104
|
+
"ideVersion": ">=2.1.0",
|
|
105
|
+
"scriptDir": "scripts/1.0"
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"defaultScriptDir": "scripts/1.0"
|
|
102
109
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code — detect_status
|
|
3
|
+
*
|
|
4
|
+
* Lightweight status detection for high-frequency polling.
|
|
5
|
+
* Input: { tail: string } — last ~500 chars of ANSI-stripped PTY output
|
|
6
|
+
* Output: 'idle' | 'generating' | 'waiting_approval'
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
module.exports = function detectStatus(input) {
|
|
12
|
+
const { tail } = input;
|
|
13
|
+
if (!tail) return 'idle';
|
|
14
|
+
|
|
15
|
+
// ─── waiting_approval (highest priority) ───
|
|
16
|
+
// Claude Code approval menu items
|
|
17
|
+
if (/Allow\s*once/i.test(tail) || /Always\s*allow/i.test(tail)) return 'waiting_approval';
|
|
18
|
+
if (/\(y\/n\)/i.test(tail) || /\[Y\/n\]/i.test(tail)) return 'waiting_approval';
|
|
19
|
+
|
|
20
|
+
// ─── generating ───
|
|
21
|
+
// Braille spinner characters (universal TUI spinner)
|
|
22
|
+
if (/[\u2800-\u28ff]/.test(tail)) return 'generating';
|
|
23
|
+
// Status line indicators
|
|
24
|
+
if (/esc to (cancel|interrupt|stop)/i.test(tail)) return 'generating';
|
|
25
|
+
if (/generating\.\.\./i.test(tail)) return 'generating';
|
|
26
|
+
if (/Claude is (?:thinking|processing|working)/i.test(tail)) return 'generating';
|
|
27
|
+
if (/Flummoxing/i.test(tail)) return 'generating';
|
|
28
|
+
|
|
29
|
+
// ─── idle ───
|
|
30
|
+
return 'idle';
|
|
31
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code — parse_approval
|
|
3
|
+
*
|
|
4
|
+
* Extract approval modal info from PTY output.
|
|
5
|
+
* Input: { buffer: string, tail: string }
|
|
6
|
+
* Output: { message: string, buttons: string[] } | null
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
module.exports = function parseApproval(input) {
|
|
12
|
+
const { buffer, tail } = input;
|
|
13
|
+
const check = tail || (buffer || '').slice(-800);
|
|
14
|
+
if (!check) return null;
|
|
15
|
+
|
|
16
|
+
// Claude Code approval patterns
|
|
17
|
+
const hasApproval =
|
|
18
|
+
/Allow\s*once/i.test(check) ||
|
|
19
|
+
/Always\s*allow/i.test(check) ||
|
|
20
|
+
/\(y\/n\)/i.test(check) ||
|
|
21
|
+
/\[Y\/n\]/i.test(check);
|
|
22
|
+
|
|
23
|
+
if (!hasApproval) return null;
|
|
24
|
+
|
|
25
|
+
// Extract context message (last few meaningful lines before the approval)
|
|
26
|
+
const lines = check.split('\n')
|
|
27
|
+
.map(l => l.trim())
|
|
28
|
+
.filter(l => l && !/^[─═╭╮╰╯│]+$/.test(l));
|
|
29
|
+
|
|
30
|
+
const message = lines.slice(-5).join(' ').slice(0, 200) || 'Approval required';
|
|
31
|
+
|
|
32
|
+
// Claude Code-specific button labels
|
|
33
|
+
// These map to approvalKeys in provider.json: { "0": "1", "1": "2", "2": "3" }
|
|
34
|
+
return {
|
|
35
|
+
message,
|
|
36
|
+
buttons: ['Yes (y)', 'Always allow (a)', 'Deny (Esc)'],
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code — parse_output
|
|
3
|
+
*
|
|
4
|
+
* Full PTY buffer → ReadChatResult conversion.
|
|
5
|
+
* Called less frequently than detectStatus (on demand, not polling).
|
|
6
|
+
*
|
|
7
|
+
* Input: {
|
|
8
|
+
* buffer: string, // Full ANSI-stripped accumulated PTY output
|
|
9
|
+
* rawBuffer: string, // Raw PTY output (with ANSI)
|
|
10
|
+
* recentBuffer: string, // Recent 1000 chars (ANSI-stripped)
|
|
11
|
+
* messages: Array, // Previously parsed messages (for delta)
|
|
12
|
+
* partialResponse: string, // Current partial response being generated
|
|
13
|
+
* }
|
|
14
|
+
*
|
|
15
|
+
* Output: ReadChatResult {
|
|
16
|
+
* messages: [{ id, role, content, index, kind?, meta? }],
|
|
17
|
+
* status: AgentStatus,
|
|
18
|
+
* activeModal?: ModalInfo | null,
|
|
19
|
+
* title?: string,
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
'use strict';
|
|
24
|
+
|
|
25
|
+
const detectStatus = require('./detect_status.js');
|
|
26
|
+
const parseApproval = require('./parse_approval.js');
|
|
27
|
+
|
|
28
|
+
function normalizeText(text) {
|
|
29
|
+
return String(text || '')
|
|
30
|
+
.replace(/\s+/g, ' ')
|
|
31
|
+
.trim();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function sanitizeLine(line) {
|
|
35
|
+
return String(line || '').replace(/\s+$/, '');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isNoiseLine(line) {
|
|
39
|
+
const trimmed = line.trim();
|
|
40
|
+
if (!trimmed) return true;
|
|
41
|
+
if (/^[─═╭╮╰╯│┌┐└┘├┤┬┴┼]+$/.test(trimmed)) return true;
|
|
42
|
+
if (/^Type your message/i.test(trimmed)) return true;
|
|
43
|
+
if (/^for\s*shortcuts/i.test(trimmed)) return true;
|
|
44
|
+
if (/^\? for help/i.test(trimmed)) return true;
|
|
45
|
+
if (/^Press enter/i.test(trimmed)) return true;
|
|
46
|
+
if (/^[\u2800-\u28ff]+$/.test(trimmed)) return true;
|
|
47
|
+
if (/^esc to (cancel|interrupt|stop)/i.test(trimmed)) return true;
|
|
48
|
+
if (/^Allow\s*once/i.test(trimmed)) return true;
|
|
49
|
+
if (/^Always\s*allow/i.test(trimmed)) return true;
|
|
50
|
+
if (/^\[(Y\/n|y\/n)\]$/i.test(trimmed)) return true;
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function extractPromptLine(lines) {
|
|
55
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
56
|
+
const trimmed = lines[i].trim();
|
|
57
|
+
const match = trimmed.match(/^[❯›>]\s+(.+)$/);
|
|
58
|
+
if (match && match[1].trim().length > 0) {
|
|
59
|
+
return { index: i, text: match[1].trim() };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { index: -1, text: '' };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function extractVisibleAssistant(screenText) {
|
|
66
|
+
if (!screenText) return { promptText: '', assistantText: '' };
|
|
67
|
+
const lines = screenText.split('\n').map(sanitizeLine);
|
|
68
|
+
const prompt = extractPromptLine(lines);
|
|
69
|
+
const afterPrompt = prompt.index >= 0 ? lines.slice(prompt.index + 1) : lines;
|
|
70
|
+
const contentLines = afterPrompt.filter(line => !isNoiseLine(line));
|
|
71
|
+
return {
|
|
72
|
+
promptText: prompt.text,
|
|
73
|
+
assistantText: contentLines.join('\n').trim(),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function toMessageObjects(messages, status) {
|
|
78
|
+
const max = 50;
|
|
79
|
+
const slice = messages.slice(-max);
|
|
80
|
+
return slice.map((message, index) => ({
|
|
81
|
+
id: `msg_${index}`,
|
|
82
|
+
role: message.role,
|
|
83
|
+
content: typeof message.content === 'string' && message.content.length > 6000
|
|
84
|
+
? message.content.slice(0, 6000) + '\n[... truncated]'
|
|
85
|
+
: message.content,
|
|
86
|
+
index,
|
|
87
|
+
kind: 'standard',
|
|
88
|
+
...(status === 'generating' && index === slice.length - 1 && message.role === 'assistant'
|
|
89
|
+
? { meta: { streaming: true } }
|
|
90
|
+
: {}),
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function buildMessages(previousMessages, promptText, assistantText, status, partialResponse) {
|
|
95
|
+
const base = Array.isArray(previousMessages)
|
|
96
|
+
? previousMessages.map(m => ({
|
|
97
|
+
role: m.role,
|
|
98
|
+
content: typeof m.content === 'string' ? m.content : String(m.content || ''),
|
|
99
|
+
timestamp: m.timestamp,
|
|
100
|
+
}))
|
|
101
|
+
: [];
|
|
102
|
+
|
|
103
|
+
const last = base[base.length - 1];
|
|
104
|
+
if (promptText) {
|
|
105
|
+
const normalizedPrompt = normalizeText(promptText);
|
|
106
|
+
if (!last || last.role !== 'user' || normalizeText(last.content) !== normalizedPrompt) {
|
|
107
|
+
base.push({ role: 'user', content: promptText });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const candidateAssistant = normalizeText(partialResponse || '') || assistantText;
|
|
112
|
+
if (candidateAssistant) {
|
|
113
|
+
const normalizedAssistant = normalizeText(candidateAssistant);
|
|
114
|
+
const lastMsg = base[base.length - 1];
|
|
115
|
+
if (lastMsg && lastMsg.role === 'assistant') {
|
|
116
|
+
const existing = normalizeText(lastMsg.content);
|
|
117
|
+
if (normalizedAssistant !== existing) {
|
|
118
|
+
lastMsg.content = candidateAssistant;
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
base.push({ role: 'assistant', content: candidateAssistant });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (status !== 'generating') {
|
|
126
|
+
const lastMsg = base[base.length - 1];
|
|
127
|
+
if (lastMsg?.role === 'assistant') {
|
|
128
|
+
const visible = normalizeText(assistantText);
|
|
129
|
+
if (visible && visible !== normalizeText(lastMsg.content)) {
|
|
130
|
+
lastMsg.content = assistantText;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return base;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module.exports = function parseOutput(input) {
|
|
139
|
+
const { buffer, recentBuffer, partialResponse, screenText, messages: previousMessages } = input;
|
|
140
|
+
const transcript = screenText || buffer || '';
|
|
141
|
+
|
|
142
|
+
// Status
|
|
143
|
+
const tail = (recentBuffer || (transcript || '').slice(-500));
|
|
144
|
+
const status = detectStatus({ tail });
|
|
145
|
+
|
|
146
|
+
// Modal
|
|
147
|
+
const activeModal = status === 'waiting_approval'
|
|
148
|
+
? parseApproval({ buffer: transcript, tail })
|
|
149
|
+
: null;
|
|
150
|
+
|
|
151
|
+
const { promptText, assistantText } = extractVisibleAssistant(transcript);
|
|
152
|
+
const messages = toMessageObjects(
|
|
153
|
+
buildMessages(previousMessages, promptText, assistantText, status, partialResponse),
|
|
154
|
+
status
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
id: 'cli_session',
|
|
159
|
+
status,
|
|
160
|
+
title: 'Claude Code',
|
|
161
|
+
messages,
|
|
162
|
+
activeModal,
|
|
163
|
+
};
|
|
164
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
};
|
|
@@ -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",
|
|
@@ -77,5 +77,12 @@
|
|
|
77
77
|
{ "source": "Allow command\\?", "flags": "i" }
|
|
78
78
|
],
|
|
79
79
|
"ready": []
|
|
80
|
-
}
|
|
80
|
+
},
|
|
81
|
+
"compatibility": [
|
|
82
|
+
{
|
|
83
|
+
"ideVersion": ">=0.42.0",
|
|
84
|
+
"scriptDir": "scripts/1.0"
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"defaultScriptDir": "scripts/1.0"
|
|
81
88
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex CLI — detect_status
|
|
3
|
+
* OpenAI Codex CLI uses a different TUI pattern.
|
|
4
|
+
*/
|
|
5
|
+
'use strict';
|
|
6
|
+
module.exports = function detectStatus(input) {
|
|
7
|
+
const { tail } = input;
|
|
8
|
+
if (!tail) return 'idle';
|
|
9
|
+
|
|
10
|
+
// waiting_approval
|
|
11
|
+
if (/approve|deny|allow|reject/i.test(tail) && /\[.*\]/i.test(tail)) return 'waiting_approval';
|
|
12
|
+
if (/Run command/i.test(tail) && /\(y\/n\)/i.test(tail)) return 'waiting_approval';
|
|
13
|
+
|
|
14
|
+
// generating
|
|
15
|
+
if (/[\u2800-\u28ff]/.test(tail)) return 'generating';
|
|
16
|
+
if (/[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/.test(tail)) return 'generating';
|
|
17
|
+
if (/thinking|processing|running/i.test(tail)) return 'generating';
|
|
18
|
+
|
|
19
|
+
return 'idle';
|
|
20
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex CLI — parse_approval
|
|
3
|
+
*/
|
|
4
|
+
'use strict';
|
|
5
|
+
module.exports = function parseApproval(input) {
|
|
6
|
+
const { tail } = input;
|
|
7
|
+
if (!tail) return null;
|
|
8
|
+
const hasApproval = /approve|allow/i.test(tail) && /deny|reject/i.test(tail);
|
|
9
|
+
if (!hasApproval && !/\(y\/n\)/i.test(tail)) return null;
|
|
10
|
+
const lines = tail.split('\n').map(l => l.trim()).filter(l => l && !/^[─═╭╮╰╯│]+$/.test(l));
|
|
11
|
+
return {
|
|
12
|
+
message: lines.slice(-5).join(' ').slice(0, 200) || 'Approval required',
|
|
13
|
+
buttons: ['Approve', 'Deny'],
|
|
14
|
+
};
|
|
15
|
+
};
|