@adhdev/daemon-core 0.6.53 → 0.6.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +76 -34
- package/dist/index.js +714 -271
- package/dist/index.js.map +1 -1
- package/package.json +1 -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 +267 -251
- package/src/cli-adapters/terminal-screen.ts +268 -0
- package/src/commands/chat-commands.ts +41 -15
- package/src/commands/cli-manager.ts +4 -2
- package/src/daemon/dev-server.ts +245 -35
- package/src/providers/acp-provider-instance.ts +1 -1
- package/src/providers/cli-provider-instance.ts +21 -8
- 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/dist/index.js
CHANGED
|
@@ -591,6 +591,246 @@ var init_logger = __esm({
|
|
|
591
591
|
}
|
|
592
592
|
});
|
|
593
593
|
|
|
594
|
+
// src/cli-adapters/terminal-screen.ts
|
|
595
|
+
function clamp(value, min, max) {
|
|
596
|
+
return Math.max(min, Math.min(max, value));
|
|
597
|
+
}
|
|
598
|
+
var TerminalScreen;
|
|
599
|
+
var init_terminal_screen = __esm({
|
|
600
|
+
"src/cli-adapters/terminal-screen.ts"() {
|
|
601
|
+
"use strict";
|
|
602
|
+
TerminalScreen = class {
|
|
603
|
+
rows;
|
|
604
|
+
cols;
|
|
605
|
+
cursorRow = 0;
|
|
606
|
+
cursorCol = 0;
|
|
607
|
+
savedRow = 0;
|
|
608
|
+
savedCol = 0;
|
|
609
|
+
lines;
|
|
610
|
+
constructor(rows = 40, cols = 120) {
|
|
611
|
+
this.rows = rows;
|
|
612
|
+
this.cols = cols;
|
|
613
|
+
this.lines = this.makeLines(rows, cols);
|
|
614
|
+
}
|
|
615
|
+
reset(rows = this.rows, cols = this.cols) {
|
|
616
|
+
this.rows = rows;
|
|
617
|
+
this.cols = cols;
|
|
618
|
+
this.cursorRow = 0;
|
|
619
|
+
this.cursorCol = 0;
|
|
620
|
+
this.savedRow = 0;
|
|
621
|
+
this.savedCol = 0;
|
|
622
|
+
this.lines = this.makeLines(rows, cols);
|
|
623
|
+
}
|
|
624
|
+
resize(rows, cols) {
|
|
625
|
+
const nextRows = Math.max(1, rows | 0);
|
|
626
|
+
const nextCols = Math.max(1, cols | 0);
|
|
627
|
+
const next = this.makeLines(nextRows, nextCols);
|
|
628
|
+
const copyRows = Math.min(this.rows, nextRows);
|
|
629
|
+
const copyCols = Math.min(this.cols, nextCols);
|
|
630
|
+
for (let r = 0; r < copyRows; r++) {
|
|
631
|
+
for (let c = 0; c < copyCols; c++) {
|
|
632
|
+
next[r][c] = this.lines[r][c];
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
this.rows = nextRows;
|
|
636
|
+
this.cols = nextCols;
|
|
637
|
+
this.lines = next;
|
|
638
|
+
this.cursorRow = clamp(this.cursorRow, 0, this.rows - 1);
|
|
639
|
+
this.cursorCol = clamp(this.cursorCol, 0, this.cols - 1);
|
|
640
|
+
this.savedRow = clamp(this.savedRow, 0, this.rows - 1);
|
|
641
|
+
this.savedCol = clamp(this.savedCol, 0, this.cols - 1);
|
|
642
|
+
}
|
|
643
|
+
write(data) {
|
|
644
|
+
let i = 0;
|
|
645
|
+
while (i < data.length) {
|
|
646
|
+
const ch = data[i];
|
|
647
|
+
if (ch === "\x1B") {
|
|
648
|
+
const consumed = this.consumeEscape(data, i);
|
|
649
|
+
i = consumed > i ? consumed : i + 1;
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
if (ch === "\r") {
|
|
653
|
+
this.cursorCol = 0;
|
|
654
|
+
i++;
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
if (ch === "\n") {
|
|
658
|
+
this.newLine();
|
|
659
|
+
i++;
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
if (ch === "\b") {
|
|
663
|
+
this.cursorCol = Math.max(0, this.cursorCol - 1);
|
|
664
|
+
i++;
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
if (ch === " ") {
|
|
668
|
+
const nextStop = Math.min(this.cols - 1, this.cursorCol + (8 - (this.cursorCol % 8 || 8)));
|
|
669
|
+
while (this.cursorCol < nextStop) this.putChar(" ");
|
|
670
|
+
i++;
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
673
|
+
if (ch >= " " && ch !== "\x7F") {
|
|
674
|
+
this.putChar(ch);
|
|
675
|
+
}
|
|
676
|
+
i++;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
getText() {
|
|
680
|
+
const raw = this.lines.map((line) => line.join("").replace(/\s+$/, ""));
|
|
681
|
+
let start = 0;
|
|
682
|
+
let end = raw.length;
|
|
683
|
+
while (start < end && raw[start] === "") start++;
|
|
684
|
+
while (end > start && raw[end - 1] === "") end--;
|
|
685
|
+
return raw.slice(start, end).join("\n");
|
|
686
|
+
}
|
|
687
|
+
consumeEscape(data, start) {
|
|
688
|
+
const next = data[start + 1];
|
|
689
|
+
if (!next) return start + 1;
|
|
690
|
+
if (next === "[") {
|
|
691
|
+
let end = start + 2;
|
|
692
|
+
while (end < data.length && !/[@-~]/.test(data[end])) end++;
|
|
693
|
+
if (end >= data.length) return data.length;
|
|
694
|
+
this.applyCsi(data.slice(start + 2, end), data[end]);
|
|
695
|
+
return end + 1;
|
|
696
|
+
}
|
|
697
|
+
if (next === "]") {
|
|
698
|
+
let end = start + 2;
|
|
699
|
+
while (end < data.length) {
|
|
700
|
+
if (data[end] === "\x07") return end + 1;
|
|
701
|
+
if (data[end] === "\x1B" && data[end + 1] === "\\") return end + 2;
|
|
702
|
+
end++;
|
|
703
|
+
}
|
|
704
|
+
return data.length;
|
|
705
|
+
}
|
|
706
|
+
if (next === "7") {
|
|
707
|
+
this.savedRow = this.cursorRow;
|
|
708
|
+
this.savedCol = this.cursorCol;
|
|
709
|
+
return start + 2;
|
|
710
|
+
}
|
|
711
|
+
if (next === "8") {
|
|
712
|
+
this.cursorRow = this.savedRow;
|
|
713
|
+
this.cursorCol = this.savedCol;
|
|
714
|
+
return start + 2;
|
|
715
|
+
}
|
|
716
|
+
return start + 2;
|
|
717
|
+
}
|
|
718
|
+
applyCsi(paramText, finalChar) {
|
|
719
|
+
const privateMode = paramText.startsWith("?");
|
|
720
|
+
const normalized = privateMode ? paramText.slice(1) : paramText;
|
|
721
|
+
const params = normalized.length > 0 ? normalized.split(";").map((p) => parseInt(p || "0", 10) || 0) : [0];
|
|
722
|
+
switch (finalChar) {
|
|
723
|
+
case "A":
|
|
724
|
+
this.cursorRow = clamp(this.cursorRow - (params[0] || 1), 0, this.rows - 1);
|
|
725
|
+
return;
|
|
726
|
+
case "B":
|
|
727
|
+
this.cursorRow = clamp(this.cursorRow + (params[0] || 1), 0, this.rows - 1);
|
|
728
|
+
return;
|
|
729
|
+
case "C":
|
|
730
|
+
this.cursorCol = clamp(this.cursorCol + (params[0] || 1), 0, this.cols - 1);
|
|
731
|
+
return;
|
|
732
|
+
case "D":
|
|
733
|
+
this.cursorCol = clamp(this.cursorCol - (params[0] || 1), 0, this.cols - 1);
|
|
734
|
+
return;
|
|
735
|
+
case "E":
|
|
736
|
+
this.cursorRow = clamp(this.cursorRow + (params[0] || 1), 0, this.rows - 1);
|
|
737
|
+
this.cursorCol = 0;
|
|
738
|
+
return;
|
|
739
|
+
case "F":
|
|
740
|
+
this.cursorRow = clamp(this.cursorRow - (params[0] || 1), 0, this.rows - 1);
|
|
741
|
+
this.cursorCol = 0;
|
|
742
|
+
return;
|
|
743
|
+
case "G":
|
|
744
|
+
this.cursorCol = clamp((params[0] || 1) - 1, 0, this.cols - 1);
|
|
745
|
+
return;
|
|
746
|
+
case "H":
|
|
747
|
+
case "f": {
|
|
748
|
+
const row = (params[0] || 1) - 1;
|
|
749
|
+
const col = (params[1] || 1) - 1;
|
|
750
|
+
this.cursorRow = clamp(row, 0, this.rows - 1);
|
|
751
|
+
this.cursorCol = clamp(col, 0, this.cols - 1);
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
case "J": {
|
|
755
|
+
const mode = params[0] || 0;
|
|
756
|
+
if (mode === 2 || mode === 3) {
|
|
757
|
+
this.reset(this.rows, this.cols);
|
|
758
|
+
} else if (mode === 0) {
|
|
759
|
+
this.clearToEndOfScreen();
|
|
760
|
+
} else if (mode === 1) {
|
|
761
|
+
this.clearToStartOfScreen();
|
|
762
|
+
}
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
case "K": {
|
|
766
|
+
const mode = params[0] || 0;
|
|
767
|
+
if (mode === 2) this.clearLine(this.cursorRow, 0, this.cols - 1);
|
|
768
|
+
else if (mode === 1) this.clearLine(this.cursorRow, 0, this.cursorCol);
|
|
769
|
+
else this.clearLine(this.cursorRow, this.cursorCol, this.cols - 1);
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
case "m":
|
|
773
|
+
return;
|
|
774
|
+
case "s":
|
|
775
|
+
this.savedRow = this.cursorRow;
|
|
776
|
+
this.savedCol = this.cursorCol;
|
|
777
|
+
return;
|
|
778
|
+
case "u":
|
|
779
|
+
this.cursorRow = this.savedRow;
|
|
780
|
+
this.cursorCol = this.savedCol;
|
|
781
|
+
return;
|
|
782
|
+
case "h":
|
|
783
|
+
case "l":
|
|
784
|
+
if (privateMode && (normalized === "1049" || normalized === "47")) {
|
|
785
|
+
this.reset(this.rows, this.cols);
|
|
786
|
+
}
|
|
787
|
+
return;
|
|
788
|
+
default:
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
putChar(ch) {
|
|
793
|
+
if (this.cursorRow < 0 || this.cursorRow >= this.rows) return;
|
|
794
|
+
if (this.cursorCol < 0) this.cursorCol = 0;
|
|
795
|
+
if (this.cursorCol >= this.cols) this.newLine();
|
|
796
|
+
this.lines[this.cursorRow][this.cursorCol] = ch;
|
|
797
|
+
this.cursorCol++;
|
|
798
|
+
if (this.cursorCol >= this.cols) this.newLine();
|
|
799
|
+
}
|
|
800
|
+
newLine() {
|
|
801
|
+
this.cursorCol = 0;
|
|
802
|
+
if (this.cursorRow >= this.rows - 1) {
|
|
803
|
+
this.lines.shift();
|
|
804
|
+
this.lines.push(Array.from({ length: this.cols }, () => " "));
|
|
805
|
+
} else {
|
|
806
|
+
this.cursorRow++;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
clearLine(row, start, end) {
|
|
810
|
+
if (row < 0 || row >= this.rows) return;
|
|
811
|
+
for (let c = clamp(start, 0, this.cols - 1); c <= clamp(end, 0, this.cols - 1); c++) {
|
|
812
|
+
this.lines[row][c] = " ";
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
clearToEndOfScreen() {
|
|
816
|
+
this.clearLine(this.cursorRow, this.cursorCol, this.cols - 1);
|
|
817
|
+
for (let r = this.cursorRow + 1; r < this.rows; r++) {
|
|
818
|
+
this.clearLine(r, 0, this.cols - 1);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
clearToStartOfScreen() {
|
|
822
|
+
for (let r = 0; r < this.cursorRow; r++) {
|
|
823
|
+
this.clearLine(r, 0, this.cols - 1);
|
|
824
|
+
}
|
|
825
|
+
this.clearLine(this.cursorRow, 0, this.cursorCol);
|
|
826
|
+
}
|
|
827
|
+
makeLines(rows, cols) {
|
|
828
|
+
return Array.from({ length: rows }, () => Array.from({ length: cols }, () => " "));
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
|
|
594
834
|
// src/cli-adapters/provider-cli-adapter.ts
|
|
595
835
|
var provider_cli_adapter_exports = {};
|
|
596
836
|
__export(provider_cli_adapter_exports, {
|
|
@@ -663,28 +903,19 @@ function parsePatternEntry(x) {
|
|
|
663
903
|
}
|
|
664
904
|
return null;
|
|
665
905
|
}
|
|
666
|
-
function coercePatternArray(raw
|
|
667
|
-
if (!Array.isArray(raw)) return [
|
|
668
|
-
|
|
669
|
-
return parsed.length > 0 ? parsed : [...fallbacks];
|
|
670
|
-
}
|
|
671
|
-
function defaultCleanOutput(raw, _lastUserInput) {
|
|
672
|
-
return stripAnsi(raw).trim();
|
|
906
|
+
function coercePatternArray(raw) {
|
|
907
|
+
if (!Array.isArray(raw)) return [];
|
|
908
|
+
return raw.map(parsePatternEntry).filter((r) => r != null);
|
|
673
909
|
}
|
|
674
910
|
function normalizeCliProviderForRuntime(raw) {
|
|
675
911
|
const patterns = raw?.patterns || {};
|
|
676
912
|
return {
|
|
677
|
-
...raw,
|
|
678
913
|
patterns: {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
approval: coercePatternArray(patterns.approval, FALLBACK_APPROVAL),
|
|
682
|
-
ready: coercePatternArray(patterns.ready, [])
|
|
683
|
-
},
|
|
684
|
-
cleanOutput: typeof raw?.cleanOutput === "function" ? raw.cleanOutput : defaultCleanOutput
|
|
914
|
+
approval: coercePatternArray(patterns.approval)
|
|
915
|
+
}
|
|
685
916
|
};
|
|
686
917
|
}
|
|
687
|
-
var os11, path9, import_child_process5, pty,
|
|
918
|
+
var os11, path9, import_child_process5, pty, ProviderCliAdapter;
|
|
688
919
|
var init_provider_cli_adapter = __esm({
|
|
689
920
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
690
921
|
"use strict";
|
|
@@ -692,6 +923,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
692
923
|
path9 = __toESM(require("path"));
|
|
693
924
|
import_child_process5 = require("child_process");
|
|
694
925
|
init_logger();
|
|
926
|
+
init_terminal_screen();
|
|
695
927
|
try {
|
|
696
928
|
pty = require("node-pty");
|
|
697
929
|
if (os11.platform() !== "win32") {
|
|
@@ -713,40 +945,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
713
945
|
} catch {
|
|
714
946
|
LOG.error("CLI", "[ProviderCliAdapter] node-pty not found. Terminal features disabled.");
|
|
715
947
|
}
|
|
716
|
-
|
|
717
|
-
/Type your message/i,
|
|
718
|
-
/for\s*shortcuts/i,
|
|
719
|
-
// Claude Code prompt
|
|
720
|
-
/\?\s*for\s*help/i,
|
|
721
|
-
// Claude Code help prompt
|
|
722
|
-
/Press enter/i,
|
|
723
|
-
/^[>›❯]\s*$/i,
|
|
724
|
-
// Prompt char as the complete evaluated string
|
|
725
|
-
/[>›❯]\s*$/
|
|
726
|
-
// Prompt char at the very end of evaluated string
|
|
727
|
-
];
|
|
728
|
-
FALLBACK_GENERATING = [
|
|
729
|
-
/[\u2800-\u28ff]/,
|
|
730
|
-
// Braille spinner blocks (universal TUI)
|
|
731
|
-
/esc to (cancel|interrupt|stop)/i,
|
|
732
|
-
// Common TUI generation status line
|
|
733
|
-
/generating\.\.\./i,
|
|
734
|
-
/Claude is (?:thinking|processing|working)/i
|
|
735
|
-
// Specific Claude Code status
|
|
736
|
-
];
|
|
737
|
-
FALLBACK_APPROVAL = [
|
|
738
|
-
/Allow\s*once/i,
|
|
739
|
-
// ANSI strip may remove spaces
|
|
740
|
-
/Always\s*allow/i,
|
|
741
|
-
/\(y\/n\)/i,
|
|
742
|
-
/\[Y\/n\]/i,
|
|
743
|
-
/Yes,?\s*don'?t\s*ask/i
|
|
744
|
-
// "Yes, don't ask again" (Claude Code)
|
|
745
|
-
];
|
|
746
|
-
ProviderCliAdapter = class {
|
|
948
|
+
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
747
949
|
constructor(provider, workingDir, extraArgs = []) {
|
|
748
950
|
this.extraArgs = extraArgs;
|
|
749
|
-
this.provider =
|
|
951
|
+
this.provider = provider;
|
|
750
952
|
this.cliType = provider.type;
|
|
751
953
|
this.cliName = provider.name;
|
|
752
954
|
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os11.homedir()) : workingDir;
|
|
@@ -763,6 +965,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
763
965
|
};
|
|
764
966
|
const rawKeys = provider.approvalKeys;
|
|
765
967
|
this.approvalKeys = rawKeys && typeof rawKeys === "object" ? rawKeys : {};
|
|
968
|
+
this.cliScripts = provider.scripts || {};
|
|
969
|
+
const scriptNames = Object.keys(this.cliScripts).filter((k) => typeof this.cliScripts[k] === "function");
|
|
970
|
+
if (scriptNames.length > 0) {
|
|
971
|
+
LOG.info("CLI", `[${this.cliType}] CLI scripts: [${scriptNames.join(", ")}]`);
|
|
972
|
+
} else {
|
|
973
|
+
LOG.warn("CLI", `[${this.cliType}] \u26A0 No CLI scripts loaded! Provider needs scripts/{version}/scripts.js`);
|
|
974
|
+
}
|
|
766
975
|
}
|
|
767
976
|
cliType;
|
|
768
977
|
cliName;
|
|
@@ -770,6 +979,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
770
979
|
provider;
|
|
771
980
|
ptyProcess = null;
|
|
772
981
|
messages = [];
|
|
982
|
+
structuredMessages = [];
|
|
773
983
|
currentStatus = "starting";
|
|
774
984
|
onStatusChange = null;
|
|
775
985
|
responseBuffer = "";
|
|
@@ -780,7 +990,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
780
990
|
idleTimeout = null;
|
|
781
991
|
ready = false;
|
|
782
992
|
startupBuffer = "";
|
|
783
|
-
/** After spawn: briefly skip generating/settle so splash/redraw does not flip status; not used to gate sendMessage */
|
|
784
993
|
startupParseGate = false;
|
|
785
994
|
spawnAt = 0;
|
|
786
995
|
// PTY I/O
|
|
@@ -798,11 +1007,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
798
1007
|
// Output settle debounce — fires after PTY output goes quiet
|
|
799
1008
|
settleTimer = null;
|
|
800
1009
|
settledBuffer = "";
|
|
801
|
-
// snapshot of recentOutputBuffer at settle time
|
|
802
1010
|
// Resize redraw suppression
|
|
803
1011
|
resizeSuppressUntil = 0;
|
|
804
1012
|
// Debug: status transition history
|
|
805
1013
|
statusHistory = [];
|
|
1014
|
+
// ─── CLI Scripts (script-based parsing) ───
|
|
1015
|
+
cliScripts;
|
|
1016
|
+
/** Full accumulated ANSI-stripped PTY output */
|
|
1017
|
+
accumulatedBuffer = "";
|
|
1018
|
+
/** Full accumulated raw PTY output (with ANSI) */
|
|
1019
|
+
accumulatedRawBuffer = "";
|
|
1020
|
+
/** Current visible terminal screen snapshot */
|
|
1021
|
+
terminalScreen = new TerminalScreen(40, 120);
|
|
1022
|
+
/** Max accumulated buffer size (last 50KB) */
|
|
1023
|
+
static MAX_ACCUMULATED_BUFFER = 5e4;
|
|
806
1024
|
setStatus(status, trigger) {
|
|
807
1025
|
const prev = this.currentStatus;
|
|
808
1026
|
if (prev === status) return;
|
|
@@ -811,10 +1029,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
811
1029
|
if (this.statusHistory.length > 50) this.statusHistory.shift();
|
|
812
1030
|
LOG.info("CLI", `[${this.cliType}] status: ${prev} \u2192 ${status}${trigger ? ` (${trigger})` : ""}`);
|
|
813
1031
|
}
|
|
814
|
-
// Resolved timeouts
|
|
1032
|
+
// Resolved timeouts
|
|
815
1033
|
timeouts;
|
|
816
|
-
// Provider approval key mapping
|
|
1034
|
+
// Provider approval key mapping
|
|
817
1035
|
approvalKeys;
|
|
1036
|
+
/** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
|
|
1037
|
+
setCliScripts(scripts) {
|
|
1038
|
+
this.cliScripts = scripts;
|
|
1039
|
+
const scriptNames = Object.keys(scripts).filter((k) => typeof scripts[k] === "function");
|
|
1040
|
+
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
1041
|
+
}
|
|
818
1042
|
// ─── Lifecycle ─────────────────────────────────
|
|
819
1043
|
setServerConn(serverConn) {
|
|
820
1044
|
this.serverConn = serverConn;
|
|
@@ -903,15 +1127,19 @@ var init_provider_cli_adapter = __esm({
|
|
|
903
1127
|
this.spawnAt = Date.now();
|
|
904
1128
|
this.startupParseGate = true;
|
|
905
1129
|
this.startupBuffer = "";
|
|
1130
|
+
this.terminalScreen.reset(40, 120);
|
|
906
1131
|
this.ready = true;
|
|
907
1132
|
this.setStatus("idle", "pty_ready");
|
|
908
1133
|
this.onStatusChange?.();
|
|
909
1134
|
}
|
|
910
|
-
// ─── Output
|
|
1135
|
+
// ─── Output Handling ────────────────────────────
|
|
911
1136
|
handleOutput(rawData) {
|
|
912
1137
|
if (Date.now() < this.resizeSuppressUntil) return;
|
|
1138
|
+
this.terminalScreen.write(rawData);
|
|
913
1139
|
const cleanData = stripAnsi(rawData);
|
|
914
|
-
|
|
1140
|
+
if (this.isWaitingForResponse && cleanData) {
|
|
1141
|
+
this.responseBuffer = (this.responseBuffer + cleanData).slice(-8e3);
|
|
1142
|
+
}
|
|
915
1143
|
if (cleanData.trim()) {
|
|
916
1144
|
if (this.serverConn) {
|
|
917
1145
|
this.serverConn.sendMessage("log", { message: cleanData.trim(), level: "info" });
|
|
@@ -920,9 +1148,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
920
1148
|
}
|
|
921
1149
|
}
|
|
922
1150
|
this.recentOutputBuffer = (this.recentOutputBuffer + cleanData).slice(-1e3);
|
|
1151
|
+
this.accumulatedBuffer = (this.accumulatedBuffer + cleanData).slice(-_ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
1152
|
+
this.accumulatedRawBuffer = (this.accumulatedRawBuffer + rawData).slice(-_ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
923
1153
|
if (this.startupParseGate) {
|
|
924
1154
|
this.startupBuffer += cleanData;
|
|
925
|
-
LOG.info("CLI", `[${this.cliType}] startup chunk (${cleanData.length} chars): ${cleanData.slice(0, 200).replace(/\n/g, "\\n")}`);
|
|
926
1155
|
const dialogPatterns = [
|
|
927
1156
|
/Do you want to connect/i,
|
|
928
1157
|
/Do you trust the files/i,
|
|
@@ -937,60 +1166,17 @@ var init_provider_cli_adapter = __esm({
|
|
|
937
1166
|
}
|
|
938
1167
|
const elapsed = Date.now() - this.spawnAt;
|
|
939
1168
|
const bufCap = this.startupBuffer.length > 12e3;
|
|
940
|
-
const
|
|
941
|
-
|
|
1169
|
+
const scriptStatus = this.runDetectStatus(this.startupBuffer);
|
|
1170
|
+
const isReady = scriptStatus === "idle" || elapsed > 8e3 || bufCap;
|
|
1171
|
+
if (isReady) {
|
|
942
1172
|
this.startupParseGate = false;
|
|
943
|
-
|
|
944
|
-
LOG.info("CLI", `[${this.cliType}] \u2713 Startup gate end (prompt matched)`);
|
|
945
|
-
} else {
|
|
946
|
-
LOG.info("CLI", `[${this.cliType}] startup gate end (${elapsed}ms, cap=${bufCap}, prompt=${promptMatched})`);
|
|
947
|
-
}
|
|
1173
|
+
LOG.info("CLI", `[${this.cliType}] Startup gate end (${elapsed}ms, scriptStatus=${scriptStatus})`);
|
|
948
1174
|
} else {
|
|
949
1175
|
return;
|
|
950
1176
|
}
|
|
951
1177
|
}
|
|
952
|
-
if (cleanData.trim().length > 5) {
|
|
953
|
-
LOG.debug("CLI", `[${this.cliType}] output chunk (${cleanData.length}): ${cleanData.slice(0, 300).replace(/\n/g, "\\n")}`);
|
|
954
|
-
}
|
|
955
|
-
if (!this.isWaitingForResponse) {
|
|
956
|
-
if (patterns.generating.some((p) => p.test(cleanData))) {
|
|
957
|
-
if (this.settleTimer) {
|
|
958
|
-
clearTimeout(this.settleTimer);
|
|
959
|
-
this.settleTimer = null;
|
|
960
|
-
}
|
|
961
|
-
this.isWaitingForResponse = true;
|
|
962
|
-
this.responseBuffer = "";
|
|
963
|
-
this.setStatus("generating", "autonomous_gen");
|
|
964
|
-
this.onStatusChange?.();
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
if (this.isWaitingForResponse) {
|
|
968
|
-
this.responseBuffer += cleanData;
|
|
969
|
-
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
970
|
-
if (patterns.generating.some((p) => p.test(cleanData))) {
|
|
971
|
-
this.setStatus("generating", "still_generating");
|
|
972
|
-
this.idleTimeout = setTimeout(() => {
|
|
973
|
-
if (this.isWaitingForResponse) this.finishResponse();
|
|
974
|
-
}, this.timeouts.generatingIdle);
|
|
975
|
-
this.onStatusChange?.();
|
|
976
|
-
if (this.settleTimer) {
|
|
977
|
-
clearTimeout(this.settleTimer);
|
|
978
|
-
this.settleTimer = null;
|
|
979
|
-
}
|
|
980
|
-
return;
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
if (this.currentStatus === "waiting_approval") {
|
|
984
|
-
this.approvalTransitionBuffer = (this.approvalTransitionBuffer + cleanData).slice(-500);
|
|
985
|
-
this.scheduleSettle();
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
1178
|
this.scheduleSettle();
|
|
989
1179
|
}
|
|
990
|
-
/**
|
|
991
|
-
* Fired after output goes quiet for outputSettle ms.
|
|
992
|
-
* Evaluates the stabilised buffer for approval, prompt (idle), or timeout.
|
|
993
|
-
*/
|
|
994
1180
|
scheduleSettle() {
|
|
995
1181
|
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
996
1182
|
this.settleTimer = setTimeout(() => {
|
|
@@ -1000,59 +1186,25 @@ var init_provider_cli_adapter = __esm({
|
|
|
1000
1186
|
}, this.timeouts.outputSettle);
|
|
1001
1187
|
}
|
|
1002
1188
|
evaluateSettled() {
|
|
1003
|
-
const
|
|
1004
|
-
const
|
|
1005
|
-
if (
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
if (genResume) {
|
|
1009
|
-
if (this.approvalExitTimeout) {
|
|
1010
|
-
clearTimeout(this.approvalExitTimeout);
|
|
1011
|
-
this.approvalExitTimeout = null;
|
|
1012
|
-
}
|
|
1013
|
-
this.setStatus("generating", "approval_gen_resume");
|
|
1014
|
-
this.activeModal = null;
|
|
1015
|
-
this.recentOutputBuffer = "";
|
|
1016
|
-
this.approvalTransitionBuffer = "";
|
|
1017
|
-
this.lastApprovalResolvedAt = Date.now();
|
|
1018
|
-
this.onStatusChange?.();
|
|
1019
|
-
} else if (promptResume) {
|
|
1020
|
-
if (this.approvalExitTimeout) {
|
|
1021
|
-
clearTimeout(this.approvalExitTimeout);
|
|
1022
|
-
this.approvalExitTimeout = null;
|
|
1023
|
-
}
|
|
1024
|
-
this.activeModal = null;
|
|
1025
|
-
this.recentOutputBuffer = "";
|
|
1026
|
-
this.approvalTransitionBuffer = "";
|
|
1027
|
-
this.lastApprovalResolvedAt = Date.now();
|
|
1028
|
-
this.finishResponse();
|
|
1029
|
-
}
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1032
|
-
const hasApproval = patterns.approval.some((p) => p.test(buf));
|
|
1033
|
-
if (hasApproval) {
|
|
1189
|
+
const tail = this.settledBuffer;
|
|
1190
|
+
const scriptStatus = this.runDetectStatus(tail);
|
|
1191
|
+
if (!scriptStatus) return;
|
|
1192
|
+
const prevStatus = this.currentStatus;
|
|
1193
|
+
if (scriptStatus === "waiting_approval") {
|
|
1034
1194
|
const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
1035
1195
|
if (!inCooldown) {
|
|
1036
|
-
const ctxLines = buf.split("\n").map((l) => l.trim()).filter((l) => l && !/^[─═╭╮╰╯│]+$/.test(l));
|
|
1037
1196
|
this.isWaitingForResponse = true;
|
|
1038
|
-
this.setStatus("waiting_approval", "
|
|
1039
|
-
|
|
1040
|
-
this.
|
|
1041
|
-
this.activeModal = {
|
|
1042
|
-
message: ctxLines.slice(-5).join(" ").slice(0, 200) || "Approval required",
|
|
1043
|
-
buttons: this.cliType === "claude-cli" ? ["Yes (y)", "Always allow (a)", "Deny (Esc)"] : ["Allow once", "Always allow", "Deny"]
|
|
1044
|
-
};
|
|
1197
|
+
this.setStatus("waiting_approval", "script_detect");
|
|
1198
|
+
const modal = this.runParseApproval(tail);
|
|
1199
|
+
this.activeModal = modal || { message: "Approval required", buttons: ["Allow", "Deny"] };
|
|
1045
1200
|
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
1046
1201
|
if (this.approvalExitTimeout) clearTimeout(this.approvalExitTimeout);
|
|
1047
1202
|
this.approvalExitTimeout = setTimeout(() => {
|
|
1048
1203
|
if (this.currentStatus === "waiting_approval") {
|
|
1049
|
-
LOG.warn("CLI", `[${this.cliType}] Approval timeout \u2014 auto-
|
|
1204
|
+
LOG.warn("CLI", `[${this.cliType}] Approval timeout \u2014 auto-clearing`);
|
|
1050
1205
|
this.activeModal = null;
|
|
1051
1206
|
this.lastApprovalResolvedAt = Date.now();
|
|
1052
|
-
this.
|
|
1053
|
-
this.approvalTransitionBuffer = "";
|
|
1054
|
-
this.approvalExitTimeout = null;
|
|
1055
|
-
this.setStatus(this.isWaitingForResponse ? "generating" : "idle", "approval_cleared");
|
|
1207
|
+
this.setStatus("idle", "approval_timeout");
|
|
1056
1208
|
this.onStatusChange?.();
|
|
1057
1209
|
}
|
|
1058
1210
|
}, 6e4);
|
|
@@ -1060,19 +1212,42 @@ var init_provider_cli_adapter = __esm({
|
|
|
1060
1212
|
return;
|
|
1061
1213
|
}
|
|
1062
1214
|
}
|
|
1063
|
-
if (
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
this.
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1215
|
+
if (scriptStatus === "generating") {
|
|
1216
|
+
if (prevStatus === "waiting_approval") {
|
|
1217
|
+
if (this.approvalExitTimeout) {
|
|
1218
|
+
clearTimeout(this.approvalExitTimeout);
|
|
1219
|
+
this.approvalExitTimeout = null;
|
|
1220
|
+
}
|
|
1221
|
+
this.activeModal = null;
|
|
1222
|
+
this.lastApprovalResolvedAt = Date.now();
|
|
1223
|
+
}
|
|
1224
|
+
if (!this.isWaitingForResponse) {
|
|
1225
|
+
this.isWaitingForResponse = true;
|
|
1226
|
+
this.responseBuffer = "";
|
|
1074
1227
|
}
|
|
1228
|
+
this.setStatus("generating", "script_detect");
|
|
1229
|
+
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
1230
|
+
this.idleTimeout = setTimeout(() => {
|
|
1231
|
+
if (this.isWaitingForResponse) this.finishResponse();
|
|
1232
|
+
}, this.timeouts.generatingIdle);
|
|
1075
1233
|
this.onStatusChange?.();
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
if (scriptStatus === "idle") {
|
|
1237
|
+
if (prevStatus === "waiting_approval") {
|
|
1238
|
+
if (this.approvalExitTimeout) {
|
|
1239
|
+
clearTimeout(this.approvalExitTimeout);
|
|
1240
|
+
this.approvalExitTimeout = null;
|
|
1241
|
+
}
|
|
1242
|
+
this.activeModal = null;
|
|
1243
|
+
this.lastApprovalResolvedAt = Date.now();
|
|
1244
|
+
}
|
|
1245
|
+
if (this.isWaitingForResponse) {
|
|
1246
|
+
this.finishResponse();
|
|
1247
|
+
} else if (prevStatus !== "idle") {
|
|
1248
|
+
this.setStatus("idle", "script_detect");
|
|
1249
|
+
this.onStatusChange?.();
|
|
1250
|
+
}
|
|
1076
1251
|
}
|
|
1077
1252
|
}
|
|
1078
1253
|
finishResponse() {
|
|
@@ -1088,25 +1263,50 @@ var init_provider_cli_adapter = __esm({
|
|
|
1088
1263
|
clearTimeout(this.approvalExitTimeout);
|
|
1089
1264
|
this.approvalExitTimeout = null;
|
|
1090
1265
|
}
|
|
1091
|
-
const lastUserText = this.messages.filter((m) => m.role === "user").pop()?.content;
|
|
1092
|
-
let response = this.provider.cleanOutput(this.responseBuffer, lastUserText);
|
|
1093
|
-
if (lastUserText && response) {
|
|
1094
|
-
const userTrimmed = lastUserText.trim();
|
|
1095
|
-
response = response.split("\n").filter((l) => l.trim() !== userTrimmed).join("\n").trim();
|
|
1096
|
-
}
|
|
1097
|
-
if (response) {
|
|
1098
|
-
this.messages.push({ role: "assistant", content: response, timestamp: Date.now() });
|
|
1099
|
-
if (this.messages.length > 200) this.messages = this.messages.slice(-200);
|
|
1100
|
-
LOG.info("CLI", `[${this.cliType}] Response (${response.length} chars)`);
|
|
1101
|
-
}
|
|
1102
1266
|
this.responseBuffer = "";
|
|
1103
1267
|
this.isWaitingForResponse = false;
|
|
1104
1268
|
this.activeModal = null;
|
|
1105
1269
|
this.setStatus("idle", "response_finished");
|
|
1106
1270
|
this.onStatusChange?.();
|
|
1107
1271
|
}
|
|
1108
|
-
// ───
|
|
1272
|
+
// ─── Script Execution ──────────────────────────
|
|
1273
|
+
runDetectStatus(text) {
|
|
1274
|
+
if (!this.cliScripts?.detectStatus) return null;
|
|
1275
|
+
try {
|
|
1276
|
+
return this.cliScripts.detectStatus({ tail: text.slice(-500) });
|
|
1277
|
+
} catch (e) {
|
|
1278
|
+
LOG.warn("CLI", `[${this.cliType}] detectStatus error: ${e.message}`);
|
|
1279
|
+
return null;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
runParseApproval(tail) {
|
|
1283
|
+
if (!this.cliScripts?.parseApproval) return null;
|
|
1284
|
+
try {
|
|
1285
|
+
return this.cliScripts.parseApproval({
|
|
1286
|
+
buffer: this.terminalScreen.getText() || this.accumulatedBuffer,
|
|
1287
|
+
rawBuffer: this.accumulatedRawBuffer,
|
|
1288
|
+
tail
|
|
1289
|
+
});
|
|
1290
|
+
} catch (e) {
|
|
1291
|
+
LOG.warn("CLI", `[${this.cliType}] parseApproval error: ${e.message}`);
|
|
1292
|
+
return null;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
// ─── Public API (CliAdapter) ───────────────────
|
|
1109
1296
|
getStatus() {
|
|
1297
|
+
const scriptResult = this.getScriptParsedStatus();
|
|
1298
|
+
if (scriptResult) {
|
|
1299
|
+
return {
|
|
1300
|
+
status: this.currentStatus,
|
|
1301
|
+
messages: (scriptResult.messages || []).map((m) => ({
|
|
1302
|
+
role: m.role,
|
|
1303
|
+
content: m.content,
|
|
1304
|
+
timestamp: m.timestamp
|
|
1305
|
+
})),
|
|
1306
|
+
workingDir: this.workingDir,
|
|
1307
|
+
activeModal: this.activeModal
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1110
1310
|
return {
|
|
1111
1311
|
status: this.currentStatus,
|
|
1112
1312
|
messages: [...this.messages],
|
|
@@ -1114,11 +1314,71 @@ var init_provider_cli_adapter = __esm({
|
|
|
1114
1314
|
activeModal: this.activeModal
|
|
1115
1315
|
};
|
|
1116
1316
|
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Script-based full parse — returns ReadChatResult.
|
|
1319
|
+
* Called by command handler / dashboard for rich content rendering.
|
|
1320
|
+
*/
|
|
1321
|
+
getScriptParsedStatus() {
|
|
1322
|
+
if (!this.cliScripts?.parseOutput) return null;
|
|
1323
|
+
try {
|
|
1324
|
+
const input = {
|
|
1325
|
+
buffer: this.accumulatedBuffer,
|
|
1326
|
+
rawBuffer: this.accumulatedRawBuffer,
|
|
1327
|
+
recentBuffer: this.recentOutputBuffer,
|
|
1328
|
+
screenText: this.terminalScreen.getText(),
|
|
1329
|
+
messages: [...this.structuredMessages.length > 0 ? this.structuredMessages : this.messages],
|
|
1330
|
+
partialResponse: this.responseBuffer
|
|
1331
|
+
};
|
|
1332
|
+
const result = this.cliScripts.parseOutput(input);
|
|
1333
|
+
if (result && typeof result === "object") {
|
|
1334
|
+
if (Array.isArray(result.messages)) {
|
|
1335
|
+
this.structuredMessages = result.messages.map((m) => ({
|
|
1336
|
+
role: m.role,
|
|
1337
|
+
content: m.content,
|
|
1338
|
+
timestamp: m.timestamp
|
|
1339
|
+
}));
|
|
1340
|
+
}
|
|
1341
|
+
return result;
|
|
1342
|
+
}
|
|
1343
|
+
} catch (e) {
|
|
1344
|
+
LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${e.message}`);
|
|
1345
|
+
}
|
|
1346
|
+
return null;
|
|
1347
|
+
}
|
|
1348
|
+
/** Whether this adapter has CLI scripts loaded */
|
|
1349
|
+
hasCliScripts() {
|
|
1350
|
+
return typeof this.cliScripts?.detectStatus === "function";
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Resolves an action (like 'fix' lint error) from the dashboard.
|
|
1354
|
+
* Uses resolveAction script if available, otherwise falls back to standard text.
|
|
1355
|
+
*/
|
|
1356
|
+
async resolveAction(data) {
|
|
1357
|
+
let promptText = "";
|
|
1358
|
+
if (this.cliScripts && typeof this.cliScripts.resolveAction === "function") {
|
|
1359
|
+
try {
|
|
1360
|
+
promptText = this.cliScripts.resolveAction(data);
|
|
1361
|
+
} catch (e) {
|
|
1362
|
+
LOG.warn("CLI", `[${this.cliType}] resolveAction error: ${e.message}`);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
if (!promptText && data) {
|
|
1366
|
+
promptText = `Please fix the following issue:
|
|
1367
|
+
${data.title || ""}
|
|
1368
|
+
${data.explanation || ""}
|
|
1369
|
+
|
|
1370
|
+
${data.message || ""}`.trim();
|
|
1371
|
+
}
|
|
1372
|
+
if (promptText) {
|
|
1373
|
+
await this.sendMessage(promptText);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1117
1376
|
async sendMessage(text) {
|
|
1118
1377
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
1119
1378
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
1120
1379
|
if (this.isWaitingForResponse) return;
|
|
1121
1380
|
this.messages.push({ role: "user", content: text, timestamp: Date.now() });
|
|
1381
|
+
this.structuredMessages.push({ role: "user", content: text, timestamp: Date.now() });
|
|
1122
1382
|
this.isWaitingForResponse = true;
|
|
1123
1383
|
this.responseBuffer = "";
|
|
1124
1384
|
this.setStatus("generating", "sendMessage");
|
|
@@ -1130,8 +1390,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1130
1390
|
}
|
|
1131
1391
|
getPartialResponse() {
|
|
1132
1392
|
if (!this.isWaitingForResponse) return "";
|
|
1133
|
-
|
|
1134
|
-
return partial || (this.isWaitingForResponse ? "(generating...)" : "");
|
|
1393
|
+
return this.responseBuffer;
|
|
1135
1394
|
}
|
|
1136
1395
|
cancel() {
|
|
1137
1396
|
this.shutdown();
|
|
@@ -1163,6 +1422,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
1163
1422
|
}
|
|
1164
1423
|
clearHistory() {
|
|
1165
1424
|
this.messages = [];
|
|
1425
|
+
this.structuredMessages = [];
|
|
1426
|
+
this.accumulatedBuffer = "";
|
|
1427
|
+
this.accumulatedRawBuffer = "";
|
|
1428
|
+
this.terminalScreen.reset();
|
|
1166
1429
|
this.onStatusChange?.();
|
|
1167
1430
|
}
|
|
1168
1431
|
isProcessing() {
|
|
@@ -1174,11 +1437,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
1174
1437
|
writeRaw(data) {
|
|
1175
1438
|
this.ptyProcess?.write(data);
|
|
1176
1439
|
}
|
|
1177
|
-
/**
|
|
1178
|
-
* Resolve an approval modal by navigating to the button at `buttonIndex` and pressing Enter.
|
|
1179
|
-
* Index 0 = first option (already selected by default — just Enter).
|
|
1180
|
-
* Index N = press Arrow Down N times, then Enter.
|
|
1181
|
-
*/
|
|
1182
1440
|
resolveModal(buttonIndex) {
|
|
1183
1441
|
if (!this.ptyProcess || this.currentStatus !== "waiting_approval") return;
|
|
1184
1442
|
if (buttonIndex in this.approvalKeys) {
|
|
@@ -1193,25 +1451,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
1193
1451
|
if (this.ptyProcess) {
|
|
1194
1452
|
try {
|
|
1195
1453
|
this.ptyProcess.resize(cols, rows);
|
|
1454
|
+
this.terminalScreen.resize(rows, cols);
|
|
1196
1455
|
this.resizeSuppressUntil = Date.now() + 300;
|
|
1197
1456
|
} catch {
|
|
1198
1457
|
}
|
|
1199
1458
|
}
|
|
1200
1459
|
}
|
|
1201
|
-
/**
|
|
1202
|
-
* Full debug state — exposes all internal buffers, status, and patterns for debugging.
|
|
1203
|
-
* Used by DevServer /api/cli/debug endpoint.
|
|
1204
|
-
*/
|
|
1205
1460
|
getDebugState() {
|
|
1206
|
-
const sb = this.startupBuffer;
|
|
1207
|
-
const testOnStartup = (p) => {
|
|
1208
|
-
const flags = p.flags.includes("g") ? p.flags.replace(/g/g, "") : p.flags;
|
|
1209
|
-
return new RegExp(p.source, flags).test(sb);
|
|
1210
|
-
};
|
|
1211
|
-
const promptDiagnostics = this.provider.patterns.prompt.map((p) => ({
|
|
1212
|
-
pattern: p.toString(),
|
|
1213
|
-
matchedAgainstStartupBuffer: testOnStartup(p)
|
|
1214
|
-
}));
|
|
1215
1461
|
return {
|
|
1216
1462
|
type: this.cliType,
|
|
1217
1463
|
name: this.cliName,
|
|
@@ -1221,32 +1467,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
1221
1467
|
spawnAt: this.spawnAt,
|
|
1222
1468
|
workingDir: this.workingDir,
|
|
1223
1469
|
messages: this.messages.slice(-20),
|
|
1470
|
+
structuredMessages: this.structuredMessages.slice(-20),
|
|
1224
1471
|
messageCount: this.messages.length,
|
|
1225
|
-
|
|
1226
|
-
startupBuffer: sb.slice(-4e3),
|
|
1227
|
-
startupBufferLength: sb.length,
|
|
1228
|
-
promptDiagnostics,
|
|
1472
|
+
startupBuffer: this.startupBuffer.slice(-4e3),
|
|
1229
1473
|
recentOutputBuffer: this.recentOutputBuffer.slice(-500),
|
|
1230
1474
|
settledBuffer: this.settledBuffer.slice(-500),
|
|
1231
|
-
|
|
1232
|
-
approvalTransitionBuffer: this.approvalTransitionBuffer.slice(-500),
|
|
1233
|
-
// State
|
|
1475
|
+
accumulatedBufferLength: this.accumulatedBuffer.length,
|
|
1234
1476
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
1235
1477
|
activeModal: this.activeModal,
|
|
1236
1478
|
lastApprovalResolvedAt: this.lastApprovalResolvedAt,
|
|
1237
1479
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
prompt: this.provider.patterns.prompt.map((p) => p.toString()),
|
|
1241
|
-
generating: this.provider.patterns.generating.map((p) => p.toString()),
|
|
1242
|
-
approval: this.provider.patterns.approval.map((p) => p.toString()),
|
|
1243
|
-
ready: this.provider.patterns.ready.map((p) => p.toString())
|
|
1244
|
-
},
|
|
1245
|
-
// Status history
|
|
1480
|
+
hasCliScripts: this.hasCliScripts(),
|
|
1481
|
+
scriptNames: Object.keys(this.cliScripts).filter((k) => typeof this.cliScripts[k] === "function"),
|
|
1246
1482
|
statusHistory: this.statusHistory.slice(-30),
|
|
1247
|
-
// Timeouts config
|
|
1248
1483
|
timeouts: this.timeouts,
|
|
1249
|
-
// PTY alive
|
|
1250
1484
|
ptyAlive: !!this.ptyProcess
|
|
1251
1485
|
};
|
|
1252
1486
|
}
|
|
@@ -3987,6 +4221,9 @@ init_logger();
|
|
|
3987
4221
|
|
|
3988
4222
|
// src/commands/chat-commands.ts
|
|
3989
4223
|
init_logger();
|
|
4224
|
+
function getTargetedCliAdapter(h, args, providerType) {
|
|
4225
|
+
return h.getCliAdapter(args?._targetInstance || h.currentIdeType || providerType);
|
|
4226
|
+
}
|
|
3990
4227
|
async function handleChatHistory(h, args) {
|
|
3991
4228
|
const { agentType, offset, limit, instanceId } = args;
|
|
3992
4229
|
try {
|
|
@@ -3999,10 +4236,10 @@ async function handleChatHistory(h, args) {
|
|
|
3999
4236
|
}
|
|
4000
4237
|
}
|
|
4001
4238
|
async function handleReadChat(h, args) {
|
|
4002
|
-
const provider = h.getProvider();
|
|
4239
|
+
const provider = h.getProvider(args?.agentType);
|
|
4003
4240
|
const _log = (msg) => LOG.debug("Command", `[read_chat] ${msg}`);
|
|
4004
4241
|
if (provider?.category === "cli" || provider?.category === "acp") {
|
|
4005
|
-
const adapter = h
|
|
4242
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
4006
4243
|
if (adapter) {
|
|
4007
4244
|
_log(`${provider.category} adapter: ${adapter.cliType}`);
|
|
4008
4245
|
const status = adapter.getStatus?.();
|
|
@@ -4118,7 +4355,7 @@ async function handleSendChat(h, args) {
|
|
|
4118
4355
|
const text = args?.text || args?.message;
|
|
4119
4356
|
if (!text) return { success: false, error: "text required" };
|
|
4120
4357
|
const _log = (msg) => LOG.debug("Command", `[send_chat] ${msg}`);
|
|
4121
|
-
const provider = h.getProvider();
|
|
4358
|
+
const provider = h.getProvider(args?.agentType);
|
|
4122
4359
|
const _logSendSuccess = (method, targetAgent) => {
|
|
4123
4360
|
h.historyWriter.appendNewMessages(
|
|
4124
4361
|
targetAgent || provider?.type || h.currentIdeType || "unknown_agent",
|
|
@@ -4130,7 +4367,7 @@ async function handleSendChat(h, args) {
|
|
|
4130
4367
|
return { success: true, sent: true, method, targetAgent };
|
|
4131
4368
|
};
|
|
4132
4369
|
if (provider?.category === "cli" || provider?.category === "acp") {
|
|
4133
|
-
const adapter = h
|
|
4370
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
4134
4371
|
if (adapter) {
|
|
4135
4372
|
_log(`${provider.category} adapter: ${adapter.cliType}`);
|
|
4136
4373
|
try {
|
|
@@ -4283,7 +4520,7 @@ async function handleSendChat(h, args) {
|
|
|
4283
4520
|
return { success: false, error: "No provider method could send the message" };
|
|
4284
4521
|
}
|
|
4285
4522
|
async function handleListChats(h, args) {
|
|
4286
|
-
const provider = h.getProvider();
|
|
4523
|
+
const provider = h.getProvider(args?.agentType);
|
|
4287
4524
|
if (provider?.category === "extension" && h.agentStream && h.getCdp()) {
|
|
4288
4525
|
try {
|
|
4289
4526
|
const chats = await h.agentStream.listAgentChats(h.getCdp(), provider.type);
|
|
@@ -4335,7 +4572,16 @@ async function handleListChats(h, args) {
|
|
|
4335
4572
|
return { success: false, error: "listSessions script not available for this provider" };
|
|
4336
4573
|
}
|
|
4337
4574
|
async function handleNewChat(h, args) {
|
|
4338
|
-
const provider = h.getProvider();
|
|
4575
|
+
const provider = h.getProvider(args?.agentType);
|
|
4576
|
+
if (provider?.category === "cli") {
|
|
4577
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
4578
|
+
if (!adapter) return { success: false, error: "CLI adapter not running" };
|
|
4579
|
+
if (typeof adapter.clearHistory === "function") {
|
|
4580
|
+
adapter.clearHistory();
|
|
4581
|
+
return { success: true, cleared: true };
|
|
4582
|
+
}
|
|
4583
|
+
return { success: false, error: "new_chat not supported by this CLI provider" };
|
|
4584
|
+
}
|
|
4339
4585
|
if (provider?.category === "extension" && h.agentStream && h.getCdp()) {
|
|
4340
4586
|
const ok = await h.agentStream.newAgentSession(h.getCdp(), provider.type, h.currentIdeType);
|
|
4341
4587
|
return { success: ok };
|
|
@@ -4360,7 +4606,7 @@ async function handleNewChat(h, args) {
|
|
|
4360
4606
|
return { success: false, error: "newSession script not available for this provider" };
|
|
4361
4607
|
}
|
|
4362
4608
|
async function handleSwitchChat(h, args) {
|
|
4363
|
-
const provider = h.getProvider();
|
|
4609
|
+
const provider = h.getProvider(args?.agentType);
|
|
4364
4610
|
const ideType = h.currentIdeType;
|
|
4365
4611
|
const sessionId = args?.sessionId || args?.id || args?.chatId;
|
|
4366
4612
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
@@ -4454,10 +4700,10 @@ async function handleSwitchChat(h, args) {
|
|
|
4454
4700
|
}
|
|
4455
4701
|
}
|
|
4456
4702
|
async function handleSetMode(h, args) {
|
|
4457
|
-
const provider = h.getProvider();
|
|
4703
|
+
const provider = h.getProvider(args?.agentType);
|
|
4458
4704
|
const mode = args?.mode || "agent";
|
|
4459
4705
|
if (provider?.category === "acp") {
|
|
4460
|
-
const adapter = h
|
|
4706
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
4461
4707
|
if (adapter) {
|
|
4462
4708
|
const acpInstance = adapter._acpInstance;
|
|
4463
4709
|
if (acpInstance && typeof acpInstance.onEvent === "function") {
|
|
@@ -4509,11 +4755,11 @@ async function handleSetMode(h, args) {
|
|
|
4509
4755
|
return { success: false, error: `setMode '${mode}' not supported by this provider` };
|
|
4510
4756
|
}
|
|
4511
4757
|
async function handleChangeModel(h, args) {
|
|
4512
|
-
const provider = h.getProvider();
|
|
4758
|
+
const provider = h.getProvider(args?.agentType);
|
|
4513
4759
|
const model = args?.model;
|
|
4514
4760
|
LOG.info("Command", `[change_model] model=${model} provider=${provider?.type} category=${provider?.category} ideType=${h.currentIdeType} providerType=${h.currentProviderType}`);
|
|
4515
4761
|
if (provider?.category === "acp") {
|
|
4516
|
-
const adapter = h
|
|
4762
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
4517
4763
|
LOG.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
|
|
4518
4764
|
if (adapter) {
|
|
4519
4765
|
const acpInstance = adapter._acpInstance;
|
|
@@ -4570,11 +4816,11 @@ async function handleSetThoughtLevel(h, args) {
|
|
|
4570
4816
|
const configId = args?.configId;
|
|
4571
4817
|
const value = args?.value;
|
|
4572
4818
|
if (!configId || !value) return { success: false, error: "configId and value required" };
|
|
4573
|
-
const provider = h.getProvider();
|
|
4819
|
+
const provider = h.getProvider(args?.agentType);
|
|
4574
4820
|
if (!provider || provider.category !== "acp") {
|
|
4575
4821
|
return { success: false, error: "set_thought_level only for ACP providers" };
|
|
4576
4822
|
}
|
|
4577
|
-
const adapter = h
|
|
4823
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
4578
4824
|
const acpInstance = adapter?._acpInstance;
|
|
4579
4825
|
if (!acpInstance) return { success: false, error: "ACP instance not found" };
|
|
4580
4826
|
try {
|
|
@@ -4586,13 +4832,22 @@ async function handleSetThoughtLevel(h, args) {
|
|
|
4586
4832
|
}
|
|
4587
4833
|
}
|
|
4588
4834
|
async function handleResolveAction(h, args) {
|
|
4589
|
-
const provider = h.getProvider();
|
|
4835
|
+
const provider = h.getProvider(args?.agentType);
|
|
4590
4836
|
const action = args?.action || "approve";
|
|
4591
4837
|
const button = args?.button || args?.buttonText || (action === "approve" ? "Accept" : action === "reject" ? "Reject" : "Accept");
|
|
4592
4838
|
LOG.info("Command", `[resolveAction] action=${action} button="${button}" provider=${provider?.type}`);
|
|
4593
4839
|
if (provider?.category === "cli") {
|
|
4594
|
-
const adapter = h
|
|
4840
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
4595
4841
|
if (!adapter) return { success: false, error: "CLI adapter not running" };
|
|
4842
|
+
if (args?.data && typeof adapter.resolveAction === "function") {
|
|
4843
|
+
try {
|
|
4844
|
+
await adapter.resolveAction(args.data);
|
|
4845
|
+
LOG.info("Command", `[resolveAction] CLI PTY \u2192 resolveAction triggered with data payload`);
|
|
4846
|
+
return { success: true, method: "cli-resolve-action" };
|
|
4847
|
+
} catch (e) {
|
|
4848
|
+
return { success: false, error: `CLI resolveAction failed: ${e.message}` };
|
|
4849
|
+
}
|
|
4850
|
+
}
|
|
4596
4851
|
const status = adapter.getStatus?.();
|
|
4597
4852
|
if (status?.status !== "waiting_approval") {
|
|
4598
4853
|
return { success: false, error: "Not in approval state" };
|
|
@@ -6790,8 +7045,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
6790
7045
|
}
|
|
6791
7046
|
}
|
|
6792
7047
|
compareVersions(a, b) {
|
|
6793
|
-
const
|
|
6794
|
-
const
|
|
7048
|
+
const normalize2 = (v) => v.split(/[-_+]/)[0].split(".").map((x) => parseInt(x, 10) || 0);
|
|
7049
|
+
const pa = normalize2(a);
|
|
7050
|
+
const pb = normalize2(b);
|
|
6795
7051
|
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
6796
7052
|
const va = pa[i] || 0;
|
|
6797
7053
|
const vb = pb[i] || 0;
|
|
@@ -7868,21 +8124,27 @@ var CliProviderInstance = class {
|
|
|
7868
8124
|
async onTick() {
|
|
7869
8125
|
}
|
|
7870
8126
|
getState() {
|
|
7871
|
-
const
|
|
8127
|
+
const rawStatus = this.adapter.getStatus();
|
|
8128
|
+
const parsedStatus = this.adapter.getScriptParsedStatus();
|
|
8129
|
+
const adapterStatus = parsedStatus ? {
|
|
8130
|
+
...rawStatus,
|
|
8131
|
+
messages: parsedStatus.messages || rawStatus.messages,
|
|
8132
|
+
activeModal: parsedStatus.activeModal || rawStatus.activeModal
|
|
8133
|
+
} : rawStatus;
|
|
7872
8134
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
7873
|
-
const recentMessages = adapterStatus.messages.slice(-50).map((m) =>
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
}));
|
|
8135
|
+
const recentMessages = adapterStatus.messages.slice(-50).map((m) => {
|
|
8136
|
+
const content = typeof m.content === "string" && m.content.length > 8e3 ? m.content.slice(0, 8e3) + "\n... (truncated)" : m.content;
|
|
8137
|
+
return { ...m, content };
|
|
8138
|
+
});
|
|
7878
8139
|
const partial = this.adapter.getPartialResponse();
|
|
7879
8140
|
if (adapterStatus.status === "generating" && partial) {
|
|
7880
8141
|
const cleaned = partial.trim();
|
|
7881
8142
|
if (cleaned && cleaned !== "(generating...)") {
|
|
7882
8143
|
recentMessages.push({
|
|
7883
8144
|
role: "assistant",
|
|
7884
|
-
content: (cleaned.length >
|
|
7885
|
-
timestamp: Date.now()
|
|
8145
|
+
content: (cleaned.length > 8e3 ? cleaned.slice(0, 8e3) + "..." : cleaned) + "...",
|
|
8146
|
+
timestamp: Date.now(),
|
|
8147
|
+
meta: { streaming: true }
|
|
7886
8148
|
});
|
|
7887
8149
|
}
|
|
7888
8150
|
}
|
|
@@ -7921,6 +8183,8 @@ var CliProviderInstance = class {
|
|
|
7921
8183
|
this.adapter.sendMessage(data.text);
|
|
7922
8184
|
} else if (event === "server_connected" && data?.serverConn) {
|
|
7923
8185
|
this.adapter.setServerConn(data.serverConn);
|
|
8186
|
+
} else if (event === "resolve_action" && data) {
|
|
8187
|
+
this.adapter.resolveAction(data);
|
|
7924
8188
|
}
|
|
7925
8189
|
}
|
|
7926
8190
|
dispose() {
|
|
@@ -8978,7 +9242,8 @@ var DaemonCliManager = class {
|
|
|
8978
9242
|
const provider = this.providerLoader.getMeta(normalizedType);
|
|
8979
9243
|
if (provider && provider.category === "cli" && provider.patterns && provider.spawn) {
|
|
8980
9244
|
console.log(import_chalk.default.cyan(` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
|
|
8981
|
-
|
|
9245
|
+
const resolvedProvider = this.providerLoader.resolve(normalizedType) || provider;
|
|
9246
|
+
return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs);
|
|
8982
9247
|
}
|
|
8983
9248
|
throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
|
|
8984
9249
|
}
|
|
@@ -9063,7 +9328,8 @@ ${installInfo}`
|
|
|
9063
9328
|
}
|
|
9064
9329
|
const instanceManager = this.deps.getInstanceManager();
|
|
9065
9330
|
if (provider && instanceManager) {
|
|
9066
|
-
const
|
|
9331
|
+
const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
|
|
9332
|
+
const cliInstance = new CliProviderInstance(resolvedProvider, resolvedDir, cliArgs, key);
|
|
9067
9333
|
try {
|
|
9068
9334
|
await instanceManager.addInstance(key, cliInstance, {
|
|
9069
9335
|
serverConn: this.deps.getServerConn(),
|
|
@@ -12261,6 +12527,46 @@ var DevServer = class _DevServer {
|
|
|
12261
12527
|
}
|
|
12262
12528
|
}
|
|
12263
12529
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
12530
|
+
getDefaultAutoImplReference(category, type) {
|
|
12531
|
+
if (category === "cli") {
|
|
12532
|
+
return type === "codex-cli" ? "claude-cli" : "codex-cli";
|
|
12533
|
+
}
|
|
12534
|
+
return "antigravity";
|
|
12535
|
+
}
|
|
12536
|
+
resolveAutoImplReference(category, requestedReference, targetType) {
|
|
12537
|
+
const desired = requestedReference || this.getDefaultAutoImplReference(category, targetType);
|
|
12538
|
+
const ref = this.providerLoader.resolve(desired) || this.providerLoader.getMeta(desired);
|
|
12539
|
+
if (ref?.category === category) return desired;
|
|
12540
|
+
const all = this.providerLoader.getAll();
|
|
12541
|
+
const fallback = all.find((p) => p.category === category && p.type !== targetType);
|
|
12542
|
+
return fallback?.type || null;
|
|
12543
|
+
}
|
|
12544
|
+
loadAutoImplReferenceScripts(category, referenceType) {
|
|
12545
|
+
if (!referenceType) return {};
|
|
12546
|
+
const builtinDir = this.providerLoader.getPrimaryBuiltinDir();
|
|
12547
|
+
const refDir = path12.join(builtinDir, category, referenceType);
|
|
12548
|
+
if (!fs9.existsSync(refDir)) return {};
|
|
12549
|
+
const referenceScripts = {};
|
|
12550
|
+
const scriptsDir = path12.join(refDir, "scripts");
|
|
12551
|
+
if (!fs9.existsSync(scriptsDir)) return referenceScripts;
|
|
12552
|
+
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
12553
|
+
try {
|
|
12554
|
+
return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
|
|
12555
|
+
} catch {
|
|
12556
|
+
return false;
|
|
12557
|
+
}
|
|
12558
|
+
}).sort().reverse();
|
|
12559
|
+
if (versions.length === 0) return referenceScripts;
|
|
12560
|
+
const latestDir = path12.join(scriptsDir, versions[0]);
|
|
12561
|
+
for (const file of fs9.readdirSync(latestDir)) {
|
|
12562
|
+
if (!file.endsWith(".js")) continue;
|
|
12563
|
+
try {
|
|
12564
|
+
referenceScripts[file] = fs9.readFileSync(path12.join(latestDir, file), "utf-8");
|
|
12565
|
+
} catch {
|
|
12566
|
+
}
|
|
12567
|
+
}
|
|
12568
|
+
return referenceScripts;
|
|
12569
|
+
}
|
|
12264
12570
|
async handleAutoImplement(type, req, res) {
|
|
12265
12571
|
const body = await this.readBody(req);
|
|
12266
12572
|
const { agent = "claude-cli", functions, reference = "antigravity", model, comment } = body;
|
|
@@ -12283,36 +12589,26 @@ var DevServer = class _DevServer {
|
|
|
12283
12589
|
return;
|
|
12284
12590
|
}
|
|
12285
12591
|
try {
|
|
12286
|
-
this.
|
|
12592
|
+
const resolvedReference = this.resolveAutoImplReference(provider.category, reference, type);
|
|
12593
|
+
this.sendAutoImplSSE({
|
|
12594
|
+
event: "progress",
|
|
12595
|
+
data: {
|
|
12596
|
+
function: "_init",
|
|
12597
|
+
status: "analyzing",
|
|
12598
|
+
message: provider.category === "cli" ? "Initializing agent (granting CLI PTY debug access)..." : "Initializing agent (granting DOM access)..."
|
|
12599
|
+
}
|
|
12600
|
+
});
|
|
12287
12601
|
const domContext = null;
|
|
12288
|
-
this.sendAutoImplSSE({
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
12292
|
-
|
|
12293
|
-
|
|
12294
|
-
if (fs9.existsSync(scriptsDir)) {
|
|
12295
|
-
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
12296
|
-
try {
|
|
12297
|
-
return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
|
|
12298
|
-
} catch {
|
|
12299
|
-
return false;
|
|
12300
|
-
}
|
|
12301
|
-
}).sort().reverse();
|
|
12302
|
-
if (versions.length > 0) {
|
|
12303
|
-
const latestDir = path12.join(scriptsDir, versions[0]);
|
|
12304
|
-
for (const file of fs9.readdirSync(latestDir)) {
|
|
12305
|
-
if (file.endsWith(".js")) {
|
|
12306
|
-
try {
|
|
12307
|
-
referenceScripts[file] = fs9.readFileSync(path12.join(latestDir, file), "utf-8");
|
|
12308
|
-
} catch {
|
|
12309
|
-
}
|
|
12310
|
-
}
|
|
12311
|
-
}
|
|
12312
|
-
}
|
|
12602
|
+
this.sendAutoImplSSE({
|
|
12603
|
+
event: "progress",
|
|
12604
|
+
data: {
|
|
12605
|
+
function: "_init",
|
|
12606
|
+
status: "loading_reference",
|
|
12607
|
+
message: `Loading reference script (${resolvedReference || "none"})...`
|
|
12313
12608
|
}
|
|
12314
|
-
}
|
|
12315
|
-
const
|
|
12609
|
+
});
|
|
12610
|
+
const referenceScripts = this.loadAutoImplReferenceScripts(provider.category, resolvedReference);
|
|
12611
|
+
const prompt = this.buildAutoImplPrompt(type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference);
|
|
12316
12612
|
const tmpDir = path12.join(os14.tmpdir(), "adhdev-autoimpl");
|
|
12317
12613
|
if (!fs9.existsSync(tmpDir)) fs9.mkdirSync(tmpDir, { recursive: true });
|
|
12318
12614
|
const promptFile = path12.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
@@ -12330,7 +12626,7 @@ var DevServer = class _DevServer {
|
|
|
12330
12626
|
}
|
|
12331
12627
|
const agentCategory = agentProvider?.category;
|
|
12332
12628
|
if (agentCategory === "acp") {
|
|
12333
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "spawning", message: `ACP
|
|
12629
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "spawning", message: `Spawning ACP agent: ${spawn3.command} ${(spawn3.args || []).join(" ")}` } });
|
|
12334
12630
|
this.autoImplStatus = { running: true, type, progress: [] };
|
|
12335
12631
|
const { ClientSideConnection: ClientSideConnection2, ndJsonStream: ndJsonStream2, PROTOCOL_VERSION: PROTOCOL_VERSION2 } = await import("@agentclientprotocol/sdk");
|
|
12336
12632
|
const { Readable: Readable2, Writable: Writable2 } = await import("stream");
|
|
@@ -12417,7 +12713,7 @@ var DevServer = class _DevServer {
|
|
|
12417
12713
|
this.autoImplProcess = null;
|
|
12418
12714
|
this.autoImplStatus.running = false;
|
|
12419
12715
|
const success = code === 0;
|
|
12420
|
-
this.sendAutoImplSSE({ event: "complete", data: { success, exitCode: code, functions, message: success ? "\u2705 ACP Auto-implement
|
|
12716
|
+
this.sendAutoImplSSE({ event: "complete", data: { success, exitCode: code, functions, message: success ? "\u2705 ACP Auto-implement complete" : `\u274C ACP agent exited (code: ${code})` } });
|
|
12421
12717
|
try {
|
|
12422
12718
|
this.providerLoader.reload();
|
|
12423
12719
|
} catch {
|
|
@@ -12432,16 +12728,16 @@ var DevServer = class _DevServer {
|
|
|
12432
12728
|
try {
|
|
12433
12729
|
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "initializing", message: "ACP initialize..." } });
|
|
12434
12730
|
await connection.initialize({ protocolVersion: PROTOCOL_VERSION2, clientCapabilities: {} });
|
|
12435
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "session", message: "ACP session
|
|
12731
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "session", message: "Creating ACP session..." } });
|
|
12436
12732
|
const session = await connection.newSession({ cwd: providerDir, mcpServers: [] });
|
|
12437
12733
|
const sessionId = session?.sessionId;
|
|
12438
12734
|
if (!sessionId) throw new Error("No sessionId returned from session/new");
|
|
12439
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "prompting", message:
|
|
12735
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "prompting", message: `Sending prompt (${prompt.length} chars)...` } });
|
|
12440
12736
|
await connection.prompt({
|
|
12441
12737
|
sessionId,
|
|
12442
12738
|
prompt: [{ type: "text", text: prompt }]
|
|
12443
12739
|
});
|
|
12444
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_done", status: "complete", message: "\u2705 ACP
|
|
12740
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_done", status: "complete", message: "\u2705 ACP prompt processing complete" } });
|
|
12445
12741
|
} catch (e) {
|
|
12446
12742
|
this.sendAutoImplSSE({ event: "output", data: { chunk: `[ACP Error] ${e.message}
|
|
12447
12743
|
`, stream: "stderr" } });
|
|
@@ -12493,7 +12789,7 @@ var DevServer = class _DevServer {
|
|
|
12493
12789
|
const escapedArgs = baseArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
|
|
12494
12790
|
shellCmd = `cat '${promptFile}' | ${command} ${escapedArgs}`;
|
|
12495
12791
|
}
|
|
12496
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "spawning", message:
|
|
12792
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "spawning", message: `Spawning agent: ${shellCmd.substring(0, 200)}... (prompt: ${prompt.length} chars)` } });
|
|
12497
12793
|
this.autoImplStatus = { running: true, type, progress: [] };
|
|
12498
12794
|
const spawnedAt = Date.now();
|
|
12499
12795
|
let child;
|
|
@@ -12589,7 +12885,7 @@ var DevServer = class _DevServer {
|
|
|
12589
12885
|
const success = code === 0;
|
|
12590
12886
|
this.sendAutoImplSSE({
|
|
12591
12887
|
event: "complete",
|
|
12592
|
-
data: { success, exitCode: code, functions, message: success ? "\u2705 Auto-implement
|
|
12888
|
+
data: { success, exitCode: code, functions, message: success ? "\u2705 Auto-implement complete" : `\u274C Agent exited (code: ${code})` }
|
|
12593
12889
|
});
|
|
12594
12890
|
try {
|
|
12595
12891
|
this.providerLoader.reload();
|
|
@@ -12624,7 +12920,7 @@ var DevServer = class _DevServer {
|
|
|
12624
12920
|
success,
|
|
12625
12921
|
exitCode: code,
|
|
12626
12922
|
functions,
|
|
12627
|
-
message: success ? "\u2705 Auto-implement
|
|
12923
|
+
message: success ? "\u2705 Auto-implement complete" : `\u274C Agent exited (code: ${code})`
|
|
12628
12924
|
}
|
|
12629
12925
|
});
|
|
12630
12926
|
try {
|
|
@@ -12652,7 +12948,10 @@ var DevServer = class _DevServer {
|
|
|
12652
12948
|
this.json(res, 500, { error: `Auto-implement failed: ${e.message}` });
|
|
12653
12949
|
}
|
|
12654
12950
|
}
|
|
12655
|
-
buildAutoImplPrompt(type, provider, providerDir, functions, domContext, referenceScripts, userComment) {
|
|
12951
|
+
buildAutoImplPrompt(type, provider, providerDir, functions, domContext, referenceScripts, userComment, referenceType) {
|
|
12952
|
+
if (provider.category === "cli") {
|
|
12953
|
+
return this.buildCliAutoImplPrompt(type, provider, providerDir, functions, referenceScripts, userComment, referenceType);
|
|
12954
|
+
}
|
|
12656
12955
|
const lines = [];
|
|
12657
12956
|
lines.push("You are implementing browser automation scripts for an IDE provider.");
|
|
12658
12957
|
lines.push("Be concise. Do NOT explain your reasoning. Just edit files directly.");
|
|
@@ -12715,7 +13014,7 @@ var DevServer = class _DevServer {
|
|
|
12715
13014
|
setMode: "set_mode.js"
|
|
12716
13015
|
};
|
|
12717
13016
|
if (Object.keys(referenceScripts).length > 0) {
|
|
12718
|
-
lines.push(
|
|
13017
|
+
lines.push(`## Reference Implementation (from ${referenceType || "antigravity"} provider)`);
|
|
12719
13018
|
lines.push("These are WORKING scripts from another IDE. Adapt the PATTERNS (not selectors) for the target IDE.");
|
|
12720
13019
|
lines.push("");
|
|
12721
13020
|
for (const fn of functions) {
|
|
@@ -12864,6 +13163,150 @@ var DevServer = class _DevServer {
|
|
|
12864
13163
|
lines.push("Start NOW. Do not ask for permission. Explore the DOM -> Code -> Test.");
|
|
12865
13164
|
return lines.join("\n");
|
|
12866
13165
|
}
|
|
13166
|
+
buildCliAutoImplPrompt(type, provider, providerDir, functions, referenceScripts, userComment, referenceType) {
|
|
13167
|
+
const lines = [];
|
|
13168
|
+
lines.push("You are implementing PTY parsing scripts for a CLI provider.");
|
|
13169
|
+
lines.push("Be concise. Do NOT explain your reasoning. Edit files directly and verify with the local DevServer.");
|
|
13170
|
+
lines.push("");
|
|
13171
|
+
lines.push(`# Target: ${provider.name || type} (${type})`);
|
|
13172
|
+
lines.push(`Provider directory: \`${providerDir}\``);
|
|
13173
|
+
lines.push("Provider category: `cli`");
|
|
13174
|
+
lines.push("");
|
|
13175
|
+
lines.push("## Current Target Files");
|
|
13176
|
+
lines.push("These are the files you need to edit. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
13177
|
+
lines.push("");
|
|
13178
|
+
const scriptsDir = path12.join(providerDir, "scripts");
|
|
13179
|
+
if (fs9.existsSync(scriptsDir)) {
|
|
13180
|
+
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
13181
|
+
try {
|
|
13182
|
+
return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
|
|
13183
|
+
} catch {
|
|
13184
|
+
return false;
|
|
13185
|
+
}
|
|
13186
|
+
}).sort().reverse();
|
|
13187
|
+
if (versions.length > 0) {
|
|
13188
|
+
const vDir = path12.join(scriptsDir, versions[0]);
|
|
13189
|
+
lines.push(`Scripts version directory: \`${vDir}\``);
|
|
13190
|
+
lines.push("");
|
|
13191
|
+
for (const file of fs9.readdirSync(vDir)) {
|
|
13192
|
+
if (!file.endsWith(".js")) continue;
|
|
13193
|
+
try {
|
|
13194
|
+
const content = fs9.readFileSync(path12.join(vDir, file), "utf-8");
|
|
13195
|
+
lines.push(`### \`${file}\``);
|
|
13196
|
+
lines.push("```javascript");
|
|
13197
|
+
lines.push(content);
|
|
13198
|
+
lines.push("```");
|
|
13199
|
+
lines.push("");
|
|
13200
|
+
} catch {
|
|
13201
|
+
}
|
|
13202
|
+
}
|
|
13203
|
+
}
|
|
13204
|
+
}
|
|
13205
|
+
const funcToFile = {
|
|
13206
|
+
parseOutput: "parse_output.js",
|
|
13207
|
+
detectStatus: "detect_status.js",
|
|
13208
|
+
parseApproval: "parse_approval.js"
|
|
13209
|
+
};
|
|
13210
|
+
if (Object.keys(referenceScripts).length > 0) {
|
|
13211
|
+
lines.push(`## Reference Implementation (from ${referenceType || "another CLI"} provider)`);
|
|
13212
|
+
lines.push("These are working CLI PTY parser scripts. Reuse the parsing shape and runtime contract, but adapt to the target CLI screen.");
|
|
13213
|
+
lines.push("");
|
|
13214
|
+
for (const fn of functions) {
|
|
13215
|
+
const fileName = funcToFile[fn];
|
|
13216
|
+
if (fileName && referenceScripts[fileName]) {
|
|
13217
|
+
lines.push(`### ${fn} \u2192 \`${fileName}\``);
|
|
13218
|
+
lines.push("```javascript");
|
|
13219
|
+
lines.push(referenceScripts[fileName]);
|
|
13220
|
+
lines.push("```");
|
|
13221
|
+
lines.push("");
|
|
13222
|
+
}
|
|
13223
|
+
}
|
|
13224
|
+
if (referenceScripts["scripts.js"]) {
|
|
13225
|
+
lines.push("### Router \u2192 `scripts.js`");
|
|
13226
|
+
lines.push("```javascript");
|
|
13227
|
+
lines.push(referenceScripts["scripts.js"]);
|
|
13228
|
+
lines.push("```");
|
|
13229
|
+
lines.push("");
|
|
13230
|
+
}
|
|
13231
|
+
}
|
|
13232
|
+
lines.push("## Runtime Contract");
|
|
13233
|
+
lines.push("The daemon runtime is already implemented in `packages/daemon-core/src/cli-adapters/provider-cli-adapter.ts`.");
|
|
13234
|
+
lines.push("Your scripts receive PTY-derived input and must return plain JS objects.");
|
|
13235
|
+
lines.push("");
|
|
13236
|
+
lines.push("| Function | Input | Return |");
|
|
13237
|
+
lines.push("|---|---|---|");
|
|
13238
|
+
lines.push("| `parseOutput` | `{ buffer, rawBuffer, recentBuffer, screenText, messages, partialResponse }` | `{ id, status, title, messages, activeModal }` |");
|
|
13239
|
+
lines.push("| `detectStatus` | `{ tail }` | `idle`, `generating`, `waiting_approval`, or `error` |");
|
|
13240
|
+
lines.push("| `parseApproval` | `{ buffer, rawBuffer, tail }` | `{ message, buttons }` or `null` |");
|
|
13241
|
+
lines.push("");
|
|
13242
|
+
lines.push("## Rules");
|
|
13243
|
+
lines.push("1. These scripts run in Node.js CommonJS, not in the browser. Do NOT use DOM APIs.");
|
|
13244
|
+
lines.push("2. Prefer `screenText` for current visible UI state. That is the PTY equivalent of parsing the current IDE DOM.");
|
|
13245
|
+
lines.push("3. Use `messages` as prior transcript state so redraws do not duplicate old turns on every parse.");
|
|
13246
|
+
lines.push("4. Use `partialResponse` for the actively streaming assistant text when status is `generating`.");
|
|
13247
|
+
lines.push("5. `detectStatus` must stay lightweight and tail-based. Do not scan the entire history there.");
|
|
13248
|
+
lines.push("6. `parseApproval` should understand the live approval area and return clean button labels.");
|
|
13249
|
+
lines.push("7. Use `rawBuffer` only when ANSI/control-sequence artifacts matter. Do not depend on raw escape noise unless necessary.");
|
|
13250
|
+
lines.push("8. Keep exports compatible with the existing `scripts.js` router (`module.exports = function ...`).");
|
|
13251
|
+
lines.push("9. Do not rewrite unrelated provider config. Only touch the scripts needed for this task unless a tiny supporting change is required.");
|
|
13252
|
+
lines.push("");
|
|
13253
|
+
lines.push("## Task");
|
|
13254
|
+
lines.push(`Edit files in \`${providerDir}\` to implement: **${functions.join(", ")}**`);
|
|
13255
|
+
lines.push("");
|
|
13256
|
+
lines.push("## Verification API");
|
|
13257
|
+
lines.push("Use the DevServer CLI debug endpoints, not DOM/CDP routes.");
|
|
13258
|
+
lines.push("");
|
|
13259
|
+
lines.push("### 1. Launch the target CLI");
|
|
13260
|
+
lines.push("```bash");
|
|
13261
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/launch \\`);
|
|
13262
|
+
lines.push(' -H "Content-Type: application/json" \\');
|
|
13263
|
+
lines.push(` -d '{"type":"${type}","workingDir":"${providerDir.replace(/\\/g, "\\\\")}"}'`);
|
|
13264
|
+
lines.push("```");
|
|
13265
|
+
lines.push("");
|
|
13266
|
+
lines.push("### 2. Inspect parsed + raw adapter state");
|
|
13267
|
+
lines.push("```bash");
|
|
13268
|
+
lines.push(`curl -sS http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/debug/${type}`);
|
|
13269
|
+
lines.push(`curl -sS http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/status`);
|
|
13270
|
+
lines.push("```");
|
|
13271
|
+
lines.push("");
|
|
13272
|
+
lines.push("### 3. Send a rich test prompt");
|
|
13273
|
+
lines.push("```bash");
|
|
13274
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/send \\`);
|
|
13275
|
+
lines.push(' -H "Content-Type: application/json" \\');
|
|
13276
|
+
lines.push(` -d '{"type":"${type}","text":"Write a short python snippet, include a markdown table, and briefly explain what you did."}'`);
|
|
13277
|
+
lines.push("```");
|
|
13278
|
+
lines.push("");
|
|
13279
|
+
lines.push("### 4. If approval appears, resolve it");
|
|
13280
|
+
lines.push("```bash");
|
|
13281
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/resolve \\`);
|
|
13282
|
+
lines.push(' -H "Content-Type: application/json" \\');
|
|
13283
|
+
lines.push(` -d '{"type":"${type}","buttonIndex":0}'`);
|
|
13284
|
+
lines.push("```");
|
|
13285
|
+
lines.push("");
|
|
13286
|
+
lines.push("### 5. Stop the CLI when finished");
|
|
13287
|
+
lines.push("```bash");
|
|
13288
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/stop \\`);
|
|
13289
|
+
lines.push(' -H "Content-Type: application/json" \\');
|
|
13290
|
+
lines.push(` -d '{"type":"${type}"}'`);
|
|
13291
|
+
lines.push("```");
|
|
13292
|
+
lines.push("");
|
|
13293
|
+
lines.push("## Required Validation");
|
|
13294
|
+
lines.push("1. Confirm `detectStatus` changes sensibly between startup, generating, approval, and idle.");
|
|
13295
|
+
lines.push("2. Confirm `parseOutput` produces a stable transcript without duplicating past turns when the PTY redraws.");
|
|
13296
|
+
lines.push("3. Confirm the latest assistant message streams through `partialResponse` while generation is in progress.");
|
|
13297
|
+
lines.push("4. Confirm approval parsing returns meaningful button labels when the CLI requests permission.");
|
|
13298
|
+
lines.push("5. Re-run the debug endpoints after edits. Do NOT finish until the parsed result looks correct.");
|
|
13299
|
+
lines.push("");
|
|
13300
|
+
if (userComment) {
|
|
13301
|
+
lines.push("## \u26A0\uFE0F User Instructions (HIGH PRIORITY)");
|
|
13302
|
+
lines.push("The user has provided the following additional instructions. Follow them strictly:");
|
|
13303
|
+
lines.push("");
|
|
13304
|
+
lines.push(userComment);
|
|
13305
|
+
lines.push("");
|
|
13306
|
+
}
|
|
13307
|
+
lines.push("Start NOW. Launch the CLI, inspect PTY state, edit the scripts, and verify via the CLI debug endpoints.");
|
|
13308
|
+
return lines.join("\n");
|
|
13309
|
+
}
|
|
12867
13310
|
handleAutoImplSSE(type, req, res) {
|
|
12868
13311
|
res.writeHead(200, {
|
|
12869
13312
|
"Content-Type": "text/event-stream",
|
|
@@ -12891,7 +13334,7 @@ data: ${JSON.stringify(p.data)}
|
|
|
12891
13334
|
setTimeout(() => {
|
|
12892
13335
|
if (this.autoImplProcess) this.autoImplProcess.kill("SIGKILL");
|
|
12893
13336
|
}, 3e3);
|
|
12894
|
-
this.sendAutoImplSSE({ event: "complete", data: { success: false, exitCode: -1, message: "\u26D4
|
|
13337
|
+
this.sendAutoImplSSE({ event: "complete", data: { success: false, exitCode: -1, message: "\u26D4 Aborted by user" } });
|
|
12895
13338
|
this.autoImplProcess = null;
|
|
12896
13339
|
this.autoImplStatus.running = false;
|
|
12897
13340
|
this.json(res, 200, { cancelled: true });
|