@austinthesing/magic-shell 0.2.7 → 0.2.9
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/cli.js +622 -59
- package/dist/tui.js +622 -59
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -20475,6 +20475,523 @@ class EditBufferRenderable extends Renderable {
|
|
|
20475
20475
|
}
|
|
20476
20476
|
}
|
|
20477
20477
|
}
|
|
20478
|
+
var defaultTextareaKeybindings = [
|
|
20479
|
+
{ name: "left", action: "move-left" },
|
|
20480
|
+
{ name: "right", action: "move-right" },
|
|
20481
|
+
{ name: "up", action: "move-up" },
|
|
20482
|
+
{ name: "down", action: "move-down" },
|
|
20483
|
+
{ name: "left", shift: true, action: "select-left" },
|
|
20484
|
+
{ name: "right", shift: true, action: "select-right" },
|
|
20485
|
+
{ name: "up", shift: true, action: "select-up" },
|
|
20486
|
+
{ name: "down", shift: true, action: "select-down" },
|
|
20487
|
+
{ name: "home", action: "buffer-home" },
|
|
20488
|
+
{ name: "end", action: "buffer-end" },
|
|
20489
|
+
{ name: "home", shift: true, action: "select-buffer-home" },
|
|
20490
|
+
{ name: "end", shift: true, action: "select-buffer-end" },
|
|
20491
|
+
{ name: "a", ctrl: true, action: "line-home" },
|
|
20492
|
+
{ name: "e", ctrl: true, action: "line-end" },
|
|
20493
|
+
{ name: "a", ctrl: true, shift: true, action: "select-line-home" },
|
|
20494
|
+
{ name: "e", ctrl: true, shift: true, action: "select-line-end" },
|
|
20495
|
+
{ name: "a", meta: true, action: "visual-line-home" },
|
|
20496
|
+
{ name: "e", meta: true, action: "visual-line-end" },
|
|
20497
|
+
{ name: "a", meta: true, shift: true, action: "select-visual-line-home" },
|
|
20498
|
+
{ name: "e", meta: true, shift: true, action: "select-visual-line-end" },
|
|
20499
|
+
{ name: "f", ctrl: true, action: "move-right" },
|
|
20500
|
+
{ name: "b", ctrl: true, action: "move-left" },
|
|
20501
|
+
{ name: "w", ctrl: true, action: "delete-word-backward" },
|
|
20502
|
+
{ name: "backspace", ctrl: true, action: "delete-word-backward" },
|
|
20503
|
+
{ name: "d", meta: true, action: "delete-word-forward" },
|
|
20504
|
+
{ name: "delete", meta: true, action: "delete-word-forward" },
|
|
20505
|
+
{ name: "delete", ctrl: true, action: "delete-word-forward" },
|
|
20506
|
+
{ name: "d", ctrl: true, shift: true, action: "delete-line" },
|
|
20507
|
+
{ name: "k", ctrl: true, action: "delete-to-line-end" },
|
|
20508
|
+
{ name: "u", ctrl: true, action: "delete-to-line-start" },
|
|
20509
|
+
{ name: "backspace", action: "backspace" },
|
|
20510
|
+
{ name: "backspace", shift: true, action: "backspace" },
|
|
20511
|
+
{ name: "d", ctrl: true, action: "delete" },
|
|
20512
|
+
{ name: "delete", action: "delete" },
|
|
20513
|
+
{ name: "delete", shift: true, action: "delete" },
|
|
20514
|
+
{ name: "return", action: "newline" },
|
|
20515
|
+
{ name: "linefeed", action: "newline" },
|
|
20516
|
+
{ name: "return", meta: true, action: "submit" },
|
|
20517
|
+
{ name: "-", ctrl: true, action: "undo" },
|
|
20518
|
+
{ name: ".", ctrl: true, action: "redo" },
|
|
20519
|
+
{ name: "z", super: true, action: "undo" },
|
|
20520
|
+
{ name: "z", super: true, shift: true, action: "redo" },
|
|
20521
|
+
{ name: "f", meta: true, action: "word-forward" },
|
|
20522
|
+
{ name: "b", meta: true, action: "word-backward" },
|
|
20523
|
+
{ name: "right", meta: true, action: "word-forward" },
|
|
20524
|
+
{ name: "left", meta: true, action: "word-backward" },
|
|
20525
|
+
{ name: "right", ctrl: true, action: "word-forward" },
|
|
20526
|
+
{ name: "left", ctrl: true, action: "word-backward" },
|
|
20527
|
+
{ name: "f", meta: true, shift: true, action: "select-word-forward" },
|
|
20528
|
+
{ name: "b", meta: true, shift: true, action: "select-word-backward" },
|
|
20529
|
+
{ name: "right", meta: true, shift: true, action: "select-word-forward" },
|
|
20530
|
+
{ name: "left", meta: true, shift: true, action: "select-word-backward" },
|
|
20531
|
+
{ name: "backspace", meta: true, action: "delete-word-backward" },
|
|
20532
|
+
{ name: "left", super: true, action: "visual-line-home" },
|
|
20533
|
+
{ name: "right", super: true, action: "visual-line-end" },
|
|
20534
|
+
{ name: "up", super: true, action: "buffer-home" },
|
|
20535
|
+
{ name: "down", super: true, action: "buffer-end" },
|
|
20536
|
+
{ name: "left", super: true, shift: true, action: "select-visual-line-home" },
|
|
20537
|
+
{ name: "right", super: true, shift: true, action: "select-visual-line-end" },
|
|
20538
|
+
{ name: "up", super: true, shift: true, action: "select-buffer-home" },
|
|
20539
|
+
{ name: "down", super: true, shift: true, action: "select-buffer-end" }
|
|
20540
|
+
];
|
|
20541
|
+
|
|
20542
|
+
class TextareaRenderable extends EditBufferRenderable {
|
|
20543
|
+
_placeholder;
|
|
20544
|
+
_unfocusedBackgroundColor;
|
|
20545
|
+
_unfocusedTextColor;
|
|
20546
|
+
_focusedBackgroundColor;
|
|
20547
|
+
_focusedTextColor;
|
|
20548
|
+
_keyBindingsMap;
|
|
20549
|
+
_keyAliasMap;
|
|
20550
|
+
_keyBindings;
|
|
20551
|
+
_actionHandlers;
|
|
20552
|
+
_initialValueSet = false;
|
|
20553
|
+
_submitListener = undefined;
|
|
20554
|
+
static defaults = {
|
|
20555
|
+
backgroundColor: "transparent",
|
|
20556
|
+
textColor: "#FFFFFF",
|
|
20557
|
+
focusedBackgroundColor: "transparent",
|
|
20558
|
+
focusedTextColor: "#FFFFFF",
|
|
20559
|
+
placeholder: null
|
|
20560
|
+
};
|
|
20561
|
+
constructor(ctx, options) {
|
|
20562
|
+
const defaults = TextareaRenderable.defaults;
|
|
20563
|
+
const baseOptions = {
|
|
20564
|
+
...options,
|
|
20565
|
+
backgroundColor: options.backgroundColor || defaults.backgroundColor,
|
|
20566
|
+
textColor: options.textColor || defaults.textColor
|
|
20567
|
+
};
|
|
20568
|
+
super(ctx, baseOptions);
|
|
20569
|
+
this._unfocusedBackgroundColor = parseColor(options.backgroundColor || defaults.backgroundColor);
|
|
20570
|
+
this._unfocusedTextColor = parseColor(options.textColor || defaults.textColor);
|
|
20571
|
+
this._focusedBackgroundColor = parseColor(options.focusedBackgroundColor || options.backgroundColor || defaults.focusedBackgroundColor);
|
|
20572
|
+
this._focusedTextColor = parseColor(options.focusedTextColor || options.textColor || defaults.focusedTextColor);
|
|
20573
|
+
this._placeholder = options.placeholder ?? defaults.placeholder;
|
|
20574
|
+
this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, options.keyAliasMap || {});
|
|
20575
|
+
this._keyBindings = options.keyBindings || [];
|
|
20576
|
+
const mergedBindings = mergeKeyBindings(defaultTextareaKeybindings, this._keyBindings);
|
|
20577
|
+
this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap);
|
|
20578
|
+
this._actionHandlers = this.buildActionHandlers();
|
|
20579
|
+
this._submitListener = options.onSubmit;
|
|
20580
|
+
if (options.initialValue) {
|
|
20581
|
+
this.setText(options.initialValue);
|
|
20582
|
+
this._initialValueSet = true;
|
|
20583
|
+
}
|
|
20584
|
+
this.updateColors();
|
|
20585
|
+
this.applyPlaceholder(this._placeholder);
|
|
20586
|
+
}
|
|
20587
|
+
applyPlaceholder(placeholder) {
|
|
20588
|
+
if (placeholder === null) {
|
|
20589
|
+
this.editorView.setPlaceholderStyledText([]);
|
|
20590
|
+
return;
|
|
20591
|
+
}
|
|
20592
|
+
if (typeof placeholder === "string") {
|
|
20593
|
+
const defaultGray = fg("#666666");
|
|
20594
|
+
const chunks = [defaultGray(placeholder)];
|
|
20595
|
+
this.editorView.setPlaceholderStyledText(chunks);
|
|
20596
|
+
} else {
|
|
20597
|
+
this.editorView.setPlaceholderStyledText(placeholder.chunks);
|
|
20598
|
+
}
|
|
20599
|
+
}
|
|
20600
|
+
buildActionHandlers() {
|
|
20601
|
+
return new Map([
|
|
20602
|
+
["move-left", () => this.moveCursorLeft()],
|
|
20603
|
+
["move-right", () => this.moveCursorRight()],
|
|
20604
|
+
["move-up", () => this.moveCursorUp()],
|
|
20605
|
+
["move-down", () => this.moveCursorDown()],
|
|
20606
|
+
["select-left", () => this.moveCursorLeft({ select: true })],
|
|
20607
|
+
["select-right", () => this.moveCursorRight({ select: true })],
|
|
20608
|
+
["select-up", () => this.moveCursorUp({ select: true })],
|
|
20609
|
+
["select-down", () => this.moveCursorDown({ select: true })],
|
|
20610
|
+
["line-home", () => this.gotoLineHome()],
|
|
20611
|
+
["line-end", () => this.gotoLineEnd()],
|
|
20612
|
+
["select-line-home", () => this.gotoLineHome({ select: true })],
|
|
20613
|
+
["select-line-end", () => this.gotoLineEnd({ select: true })],
|
|
20614
|
+
["visual-line-home", () => this.gotoVisualLineHome()],
|
|
20615
|
+
["visual-line-end", () => this.gotoVisualLineEnd()],
|
|
20616
|
+
["select-visual-line-home", () => this.gotoVisualLineHome({ select: true })],
|
|
20617
|
+
["select-visual-line-end", () => this.gotoVisualLineEnd({ select: true })],
|
|
20618
|
+
["select-buffer-home", () => this.gotoBufferHome({ select: true })],
|
|
20619
|
+
["select-buffer-end", () => this.gotoBufferEnd({ select: true })],
|
|
20620
|
+
["buffer-home", () => this.gotoBufferHome()],
|
|
20621
|
+
["buffer-end", () => this.gotoBufferEnd()],
|
|
20622
|
+
["delete-line", () => this.deleteLine()],
|
|
20623
|
+
["delete-to-line-end", () => this.deleteToLineEnd()],
|
|
20624
|
+
["delete-to-line-start", () => this.deleteToLineStart()],
|
|
20625
|
+
["backspace", () => this.deleteCharBackward()],
|
|
20626
|
+
["delete", () => this.deleteChar()],
|
|
20627
|
+
["newline", () => this.newLine()],
|
|
20628
|
+
["undo", () => this.undo()],
|
|
20629
|
+
["redo", () => this.redo()],
|
|
20630
|
+
["word-forward", () => this.moveWordForward()],
|
|
20631
|
+
["word-backward", () => this.moveWordBackward()],
|
|
20632
|
+
["select-word-forward", () => this.moveWordForward({ select: true })],
|
|
20633
|
+
["select-word-backward", () => this.moveWordBackward({ select: true })],
|
|
20634
|
+
["delete-word-forward", () => this.deleteWordForward()],
|
|
20635
|
+
["delete-word-backward", () => this.deleteWordBackward()],
|
|
20636
|
+
["submit", () => this.submit()]
|
|
20637
|
+
]);
|
|
20638
|
+
}
|
|
20639
|
+
handlePaste(event) {
|
|
20640
|
+
this.insertText(event.text);
|
|
20641
|
+
}
|
|
20642
|
+
handleKeyPress(key) {
|
|
20643
|
+
const bindingKey = getKeyBindingKey({
|
|
20644
|
+
name: key.name,
|
|
20645
|
+
ctrl: key.ctrl,
|
|
20646
|
+
shift: key.shift,
|
|
20647
|
+
meta: key.meta,
|
|
20648
|
+
super: key.super,
|
|
20649
|
+
action: "move-left"
|
|
20650
|
+
});
|
|
20651
|
+
const action = this._keyBindingsMap.get(bindingKey);
|
|
20652
|
+
if (action) {
|
|
20653
|
+
const handler = this._actionHandlers.get(action);
|
|
20654
|
+
if (handler) {
|
|
20655
|
+
return handler();
|
|
20656
|
+
}
|
|
20657
|
+
}
|
|
20658
|
+
if (!key.ctrl && !key.meta && !key.super && !key.hyper) {
|
|
20659
|
+
if (key.name === "space") {
|
|
20660
|
+
this.insertText(" ");
|
|
20661
|
+
return true;
|
|
20662
|
+
}
|
|
20663
|
+
if (key.sequence) {
|
|
20664
|
+
const firstCharCode = key.sequence.charCodeAt(0);
|
|
20665
|
+
if (firstCharCode < 32) {
|
|
20666
|
+
return false;
|
|
20667
|
+
}
|
|
20668
|
+
if (firstCharCode === 127) {
|
|
20669
|
+
return false;
|
|
20670
|
+
}
|
|
20671
|
+
this.insertText(key.sequence);
|
|
20672
|
+
return true;
|
|
20673
|
+
}
|
|
20674
|
+
}
|
|
20675
|
+
return false;
|
|
20676
|
+
}
|
|
20677
|
+
updateColors() {
|
|
20678
|
+
const effectiveBg = this._focused ? this._focusedBackgroundColor : this._unfocusedBackgroundColor;
|
|
20679
|
+
const effectiveFg = this._focused ? this._focusedTextColor : this._unfocusedTextColor;
|
|
20680
|
+
super.backgroundColor = effectiveBg;
|
|
20681
|
+
super.textColor = effectiveFg;
|
|
20682
|
+
}
|
|
20683
|
+
insertChar(char) {
|
|
20684
|
+
if (this.hasSelection()) {
|
|
20685
|
+
this.deleteSelectedText();
|
|
20686
|
+
}
|
|
20687
|
+
this.editBuffer.insertChar(char);
|
|
20688
|
+
this.requestRender();
|
|
20689
|
+
}
|
|
20690
|
+
insertText(text) {
|
|
20691
|
+
if (this.hasSelection()) {
|
|
20692
|
+
this.deleteSelectedText();
|
|
20693
|
+
}
|
|
20694
|
+
this.editBuffer.insertText(text);
|
|
20695
|
+
this.requestRender();
|
|
20696
|
+
}
|
|
20697
|
+
deleteChar() {
|
|
20698
|
+
if (this.hasSelection()) {
|
|
20699
|
+
this.deleteSelectedText();
|
|
20700
|
+
return true;
|
|
20701
|
+
}
|
|
20702
|
+
this._ctx.clearSelection();
|
|
20703
|
+
this.editBuffer.deleteChar();
|
|
20704
|
+
this.requestRender();
|
|
20705
|
+
return true;
|
|
20706
|
+
}
|
|
20707
|
+
deleteCharBackward() {
|
|
20708
|
+
if (this.hasSelection()) {
|
|
20709
|
+
this.deleteSelectedText();
|
|
20710
|
+
return true;
|
|
20711
|
+
}
|
|
20712
|
+
this._ctx.clearSelection();
|
|
20713
|
+
this.editBuffer.deleteCharBackward();
|
|
20714
|
+
this.requestRender();
|
|
20715
|
+
return true;
|
|
20716
|
+
}
|
|
20717
|
+
deleteSelectedText() {
|
|
20718
|
+
this.editorView.deleteSelectedText();
|
|
20719
|
+
this._ctx.clearSelection();
|
|
20720
|
+
this.requestRender();
|
|
20721
|
+
}
|
|
20722
|
+
newLine() {
|
|
20723
|
+
this._ctx.clearSelection();
|
|
20724
|
+
this.editBuffer.newLine();
|
|
20725
|
+
this.requestRender();
|
|
20726
|
+
return true;
|
|
20727
|
+
}
|
|
20728
|
+
deleteLine() {
|
|
20729
|
+
this._ctx.clearSelection();
|
|
20730
|
+
this.editBuffer.deleteLine();
|
|
20731
|
+
this.requestRender();
|
|
20732
|
+
return true;
|
|
20733
|
+
}
|
|
20734
|
+
moveCursorLeft(options) {
|
|
20735
|
+
const select = options?.select ?? false;
|
|
20736
|
+
this.updateSelectionForMovement(select, true);
|
|
20737
|
+
this.editBuffer.moveCursorLeft();
|
|
20738
|
+
this.updateSelectionForMovement(select, false);
|
|
20739
|
+
this.requestRender();
|
|
20740
|
+
return true;
|
|
20741
|
+
}
|
|
20742
|
+
moveCursorRight(options) {
|
|
20743
|
+
const select = options?.select ?? false;
|
|
20744
|
+
this.updateSelectionForMovement(select, true);
|
|
20745
|
+
this.editBuffer.moveCursorRight();
|
|
20746
|
+
this.updateSelectionForMovement(select, false);
|
|
20747
|
+
this.requestRender();
|
|
20748
|
+
return true;
|
|
20749
|
+
}
|
|
20750
|
+
moveCursorUp(options) {
|
|
20751
|
+
const select = options?.select ?? false;
|
|
20752
|
+
this.updateSelectionForMovement(select, true);
|
|
20753
|
+
this.editorView.moveUpVisual();
|
|
20754
|
+
this.updateSelectionForMovement(select, false);
|
|
20755
|
+
this.requestRender();
|
|
20756
|
+
return true;
|
|
20757
|
+
}
|
|
20758
|
+
moveCursorDown(options) {
|
|
20759
|
+
const select = options?.select ?? false;
|
|
20760
|
+
this.updateSelectionForMovement(select, true);
|
|
20761
|
+
this.editorView.moveDownVisual();
|
|
20762
|
+
this.updateSelectionForMovement(select, false);
|
|
20763
|
+
this.requestRender();
|
|
20764
|
+
return true;
|
|
20765
|
+
}
|
|
20766
|
+
gotoLine(line) {
|
|
20767
|
+
this.editBuffer.gotoLine(line);
|
|
20768
|
+
this.requestRender();
|
|
20769
|
+
}
|
|
20770
|
+
gotoLineHome(options) {
|
|
20771
|
+
const select = options?.select ?? false;
|
|
20772
|
+
this.updateSelectionForMovement(select, true);
|
|
20773
|
+
const cursor = this.editorView.getCursor();
|
|
20774
|
+
if (cursor.col === 0 && cursor.row > 0) {
|
|
20775
|
+
this.editBuffer.setCursor(cursor.row - 1, 0);
|
|
20776
|
+
const prevLineEol = this.editBuffer.getEOL();
|
|
20777
|
+
this.editBuffer.setCursor(prevLineEol.row, prevLineEol.col);
|
|
20778
|
+
} else {
|
|
20779
|
+
this.editBuffer.setCursor(cursor.row, 0);
|
|
20780
|
+
}
|
|
20781
|
+
this.updateSelectionForMovement(select, false);
|
|
20782
|
+
this.requestRender();
|
|
20783
|
+
return true;
|
|
20784
|
+
}
|
|
20785
|
+
gotoLineEnd(options) {
|
|
20786
|
+
const select = options?.select ?? false;
|
|
20787
|
+
this.updateSelectionForMovement(select, true);
|
|
20788
|
+
const cursor = this.editorView.getCursor();
|
|
20789
|
+
const eol = this.editBuffer.getEOL();
|
|
20790
|
+
const lineCount = this.editBuffer.getLineCount();
|
|
20791
|
+
if (cursor.col === eol.col && cursor.row < lineCount - 1) {
|
|
20792
|
+
this.editBuffer.setCursor(cursor.row + 1, 0);
|
|
20793
|
+
} else {
|
|
20794
|
+
this.editBuffer.setCursor(eol.row, eol.col);
|
|
20795
|
+
}
|
|
20796
|
+
this.updateSelectionForMovement(select, false);
|
|
20797
|
+
this.requestRender();
|
|
20798
|
+
return true;
|
|
20799
|
+
}
|
|
20800
|
+
gotoVisualLineHome(options) {
|
|
20801
|
+
const select = options?.select ?? false;
|
|
20802
|
+
this.updateSelectionForMovement(select, true);
|
|
20803
|
+
const sol = this.editorView.getVisualSOL();
|
|
20804
|
+
this.editBuffer.setCursor(sol.logicalRow, sol.logicalCol);
|
|
20805
|
+
this.updateSelectionForMovement(select, false);
|
|
20806
|
+
this.requestRender();
|
|
20807
|
+
return true;
|
|
20808
|
+
}
|
|
20809
|
+
gotoVisualLineEnd(options) {
|
|
20810
|
+
const select = options?.select ?? false;
|
|
20811
|
+
this.updateSelectionForMovement(select, true);
|
|
20812
|
+
const eol = this.editorView.getVisualEOL();
|
|
20813
|
+
this.editBuffer.setCursor(eol.logicalRow, eol.logicalCol);
|
|
20814
|
+
this.updateSelectionForMovement(select, false);
|
|
20815
|
+
this.requestRender();
|
|
20816
|
+
return true;
|
|
20817
|
+
}
|
|
20818
|
+
gotoBufferHome(options) {
|
|
20819
|
+
const select = options?.select ?? false;
|
|
20820
|
+
this.updateSelectionForMovement(select, true);
|
|
20821
|
+
this.editBuffer.setCursor(0, 0);
|
|
20822
|
+
this.updateSelectionForMovement(select, false);
|
|
20823
|
+
this.requestRender();
|
|
20824
|
+
return true;
|
|
20825
|
+
}
|
|
20826
|
+
gotoBufferEnd(options) {
|
|
20827
|
+
const select = options?.select ?? false;
|
|
20828
|
+
this.updateSelectionForMovement(select, true);
|
|
20829
|
+
this.editBuffer.gotoLine(999999);
|
|
20830
|
+
this.updateSelectionForMovement(select, false);
|
|
20831
|
+
this.requestRender();
|
|
20832
|
+
return true;
|
|
20833
|
+
}
|
|
20834
|
+
deleteToLineEnd() {
|
|
20835
|
+
const cursor = this.editorView.getCursor();
|
|
20836
|
+
const eol = this.editBuffer.getEOL();
|
|
20837
|
+
if (eol.col > cursor.col) {
|
|
20838
|
+
this.editBuffer.deleteRange(cursor.row, cursor.col, eol.row, eol.col);
|
|
20839
|
+
}
|
|
20840
|
+
this.requestRender();
|
|
20841
|
+
return true;
|
|
20842
|
+
}
|
|
20843
|
+
deleteToLineStart() {
|
|
20844
|
+
const cursor = this.editorView.getCursor();
|
|
20845
|
+
if (cursor.col > 0) {
|
|
20846
|
+
this.editBuffer.deleteRange(cursor.row, 0, cursor.row, cursor.col);
|
|
20847
|
+
}
|
|
20848
|
+
this.requestRender();
|
|
20849
|
+
return true;
|
|
20850
|
+
}
|
|
20851
|
+
undo() {
|
|
20852
|
+
this._ctx.clearSelection();
|
|
20853
|
+
this.editBuffer.undo();
|
|
20854
|
+
this.requestRender();
|
|
20855
|
+
return true;
|
|
20856
|
+
}
|
|
20857
|
+
redo() {
|
|
20858
|
+
this._ctx.clearSelection();
|
|
20859
|
+
this.editBuffer.redo();
|
|
20860
|
+
this.requestRender();
|
|
20861
|
+
return true;
|
|
20862
|
+
}
|
|
20863
|
+
moveWordForward(options) {
|
|
20864
|
+
const select = options?.select ?? false;
|
|
20865
|
+
this.updateSelectionForMovement(select, true);
|
|
20866
|
+
const nextWord = this.editBuffer.getNextWordBoundary();
|
|
20867
|
+
this.editBuffer.setCursorByOffset(nextWord.offset);
|
|
20868
|
+
this.updateSelectionForMovement(select, false);
|
|
20869
|
+
this.requestRender();
|
|
20870
|
+
return true;
|
|
20871
|
+
}
|
|
20872
|
+
moveWordBackward(options) {
|
|
20873
|
+
const select = options?.select ?? false;
|
|
20874
|
+
this.updateSelectionForMovement(select, true);
|
|
20875
|
+
const prevWord = this.editBuffer.getPrevWordBoundary();
|
|
20876
|
+
this.editBuffer.setCursorByOffset(prevWord.offset);
|
|
20877
|
+
this.updateSelectionForMovement(select, false);
|
|
20878
|
+
this.requestRender();
|
|
20879
|
+
return true;
|
|
20880
|
+
}
|
|
20881
|
+
deleteWordForward() {
|
|
20882
|
+
if (this.hasSelection()) {
|
|
20883
|
+
this.deleteSelectedText();
|
|
20884
|
+
return true;
|
|
20885
|
+
}
|
|
20886
|
+
const currentCursor = this.editBuffer.getCursorPosition();
|
|
20887
|
+
const nextWord = this.editBuffer.getNextWordBoundary();
|
|
20888
|
+
if (nextWord.offset > currentCursor.offset) {
|
|
20889
|
+
this.editBuffer.deleteRange(currentCursor.row, currentCursor.col, nextWord.row, nextWord.col);
|
|
20890
|
+
}
|
|
20891
|
+
this._ctx.clearSelection();
|
|
20892
|
+
this.requestRender();
|
|
20893
|
+
return true;
|
|
20894
|
+
}
|
|
20895
|
+
deleteWordBackward() {
|
|
20896
|
+
if (this.hasSelection()) {
|
|
20897
|
+
this.deleteSelectedText();
|
|
20898
|
+
return true;
|
|
20899
|
+
}
|
|
20900
|
+
const currentCursor = this.editBuffer.getCursorPosition();
|
|
20901
|
+
const prevWord = this.editBuffer.getPrevWordBoundary();
|
|
20902
|
+
if (prevWord.offset < currentCursor.offset) {
|
|
20903
|
+
this.editBuffer.deleteRange(prevWord.row, prevWord.col, currentCursor.row, currentCursor.col);
|
|
20904
|
+
}
|
|
20905
|
+
this._ctx.clearSelection();
|
|
20906
|
+
this.requestRender();
|
|
20907
|
+
return true;
|
|
20908
|
+
}
|
|
20909
|
+
focus() {
|
|
20910
|
+
super.focus();
|
|
20911
|
+
this.updateColors();
|
|
20912
|
+
}
|
|
20913
|
+
blur() {
|
|
20914
|
+
super.blur();
|
|
20915
|
+
if (!this.isDestroyed) {
|
|
20916
|
+
this.updateColors();
|
|
20917
|
+
}
|
|
20918
|
+
}
|
|
20919
|
+
get placeholder() {
|
|
20920
|
+
return this._placeholder;
|
|
20921
|
+
}
|
|
20922
|
+
set placeholder(value) {
|
|
20923
|
+
if (this._placeholder !== value) {
|
|
20924
|
+
this._placeholder = value;
|
|
20925
|
+
this.applyPlaceholder(value);
|
|
20926
|
+
this.requestRender();
|
|
20927
|
+
}
|
|
20928
|
+
}
|
|
20929
|
+
get backgroundColor() {
|
|
20930
|
+
return this._unfocusedBackgroundColor;
|
|
20931
|
+
}
|
|
20932
|
+
set backgroundColor(value) {
|
|
20933
|
+
const newColor = parseColor(value ?? TextareaRenderable.defaults.backgroundColor);
|
|
20934
|
+
if (this._unfocusedBackgroundColor !== newColor) {
|
|
20935
|
+
this._unfocusedBackgroundColor = newColor;
|
|
20936
|
+
this.updateColors();
|
|
20937
|
+
}
|
|
20938
|
+
}
|
|
20939
|
+
get textColor() {
|
|
20940
|
+
return this._unfocusedTextColor;
|
|
20941
|
+
}
|
|
20942
|
+
set textColor(value) {
|
|
20943
|
+
const newColor = parseColor(value ?? TextareaRenderable.defaults.textColor);
|
|
20944
|
+
if (this._unfocusedTextColor !== newColor) {
|
|
20945
|
+
this._unfocusedTextColor = newColor;
|
|
20946
|
+
this.updateColors();
|
|
20947
|
+
}
|
|
20948
|
+
}
|
|
20949
|
+
set focusedBackgroundColor(value) {
|
|
20950
|
+
const newColor = parseColor(value ?? TextareaRenderable.defaults.focusedBackgroundColor);
|
|
20951
|
+
if (this._focusedBackgroundColor !== newColor) {
|
|
20952
|
+
this._focusedBackgroundColor = newColor;
|
|
20953
|
+
this.updateColors();
|
|
20954
|
+
}
|
|
20955
|
+
}
|
|
20956
|
+
set focusedTextColor(value) {
|
|
20957
|
+
const newColor = parseColor(value ?? TextareaRenderable.defaults.focusedTextColor);
|
|
20958
|
+
if (this._focusedTextColor !== newColor) {
|
|
20959
|
+
this._focusedTextColor = newColor;
|
|
20960
|
+
this.updateColors();
|
|
20961
|
+
}
|
|
20962
|
+
}
|
|
20963
|
+
set initialValue(value) {
|
|
20964
|
+
if (!this._initialValueSet) {
|
|
20965
|
+
this.setText(value);
|
|
20966
|
+
this._initialValueSet = true;
|
|
20967
|
+
}
|
|
20968
|
+
}
|
|
20969
|
+
submit() {
|
|
20970
|
+
if (this._submitListener) {
|
|
20971
|
+
this._submitListener({});
|
|
20972
|
+
}
|
|
20973
|
+
return true;
|
|
20974
|
+
}
|
|
20975
|
+
set onSubmit(handler) {
|
|
20976
|
+
this._submitListener = handler;
|
|
20977
|
+
}
|
|
20978
|
+
get onSubmit() {
|
|
20979
|
+
return this._submitListener;
|
|
20980
|
+
}
|
|
20981
|
+
set keyBindings(bindings) {
|
|
20982
|
+
this._keyBindings = bindings;
|
|
20983
|
+
const mergedBindings = mergeKeyBindings(defaultTextareaKeybindings, bindings);
|
|
20984
|
+
this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap);
|
|
20985
|
+
}
|
|
20986
|
+
set keyAliasMap(aliases) {
|
|
20987
|
+
this._keyAliasMap = mergeKeyAliases(defaultKeyAliases, aliases);
|
|
20988
|
+
const mergedBindings = mergeKeyBindings(defaultTextareaKeybindings, this._keyBindings);
|
|
20989
|
+
this._keyBindingsMap = buildKeyBindingsMap(mergedBindings, this._keyAliasMap);
|
|
20990
|
+
}
|
|
20991
|
+
get extmarks() {
|
|
20992
|
+
return this.editorView.extmarks;
|
|
20993
|
+
}
|
|
20994
|
+
}
|
|
20478
20995
|
|
|
20479
20996
|
// src/cli.ts
|
|
20480
20997
|
import { spawn } from "child_process";
|
|
@@ -22106,6 +22623,8 @@ var headerText;
|
|
|
22106
22623
|
var statusBarText;
|
|
22107
22624
|
var chatScrollBox;
|
|
22108
22625
|
var inputField;
|
|
22626
|
+
var inputContainer;
|
|
22627
|
+
var inputHintText;
|
|
22109
22628
|
var helpBarText;
|
|
22110
22629
|
var modelSelector = null;
|
|
22111
22630
|
var providerSelector = null;
|
|
@@ -22333,43 +22852,53 @@ function createMainUI() {
|
|
|
22333
22852
|
});
|
|
22334
22853
|
mainContainer.add(chatScrollBox);
|
|
22335
22854
|
addSystemMessage(getWelcomeMessage());
|
|
22336
|
-
|
|
22337
|
-
id: "input-
|
|
22338
|
-
flexDirection: "
|
|
22855
|
+
inputContainer = new BoxRenderable(renderer, {
|
|
22856
|
+
id: "input-container",
|
|
22857
|
+
flexDirection: "column",
|
|
22339
22858
|
width: "100%",
|
|
22340
22859
|
marginTop: 1,
|
|
22341
|
-
|
|
22342
|
-
|
|
22343
|
-
|
|
22344
|
-
|
|
22345
|
-
|
|
22346
|
-
|
|
22347
|
-
|
|
22348
|
-
|
|
22860
|
+
border: true,
|
|
22861
|
+
borderColor: theme.colors.primary,
|
|
22862
|
+
borderStyle: "rounded",
|
|
22863
|
+
paddingLeft: 1,
|
|
22864
|
+
paddingRight: 1,
|
|
22865
|
+
paddingTop: 0,
|
|
22866
|
+
paddingBottom: 0,
|
|
22867
|
+
backgroundColor: theme.colors.backgroundPanel
|
|
22349
22868
|
});
|
|
22350
|
-
|
|
22351
|
-
inputField = new
|
|
22869
|
+
mainContainer.add(inputContainer);
|
|
22870
|
+
inputField = new TextareaRenderable(renderer, {
|
|
22352
22871
|
id: "input-field",
|
|
22353
|
-
|
|
22354
|
-
height:
|
|
22355
|
-
placeholder: "
|
|
22872
|
+
width: "100%",
|
|
22873
|
+
height: 3,
|
|
22874
|
+
placeholder: t`${fg(theme.colors.textMuted)("Describe what you want to do...")}`,
|
|
22356
22875
|
backgroundColor: "transparent",
|
|
22357
|
-
focusedBackgroundColor:
|
|
22876
|
+
focusedBackgroundColor: "transparent",
|
|
22358
22877
|
textColor: theme.colors.text,
|
|
22359
|
-
|
|
22360
|
-
|
|
22361
|
-
|
|
22362
|
-
|
|
22878
|
+
keyBindings: [
|
|
22879
|
+
{ name: "return", action: "submit" },
|
|
22880
|
+
{ name: "linefeed", action: "submit" },
|
|
22881
|
+
{ name: "return", shift: true, action: "newline" },
|
|
22882
|
+
{ name: "linefeed", shift: true, action: "newline" },
|
|
22883
|
+
{ name: "return", meta: true, action: "submit" }
|
|
22884
|
+
],
|
|
22885
|
+
onSubmit: () => {
|
|
22886
|
+
const value = inputField.editBuffer.getText();
|
|
22887
|
+
handleInput(value);
|
|
22363
22888
|
}
|
|
22364
22889
|
});
|
|
22365
|
-
|
|
22890
|
+
inputContainer.add(inputField);
|
|
22891
|
+
inputHintText = new TextRenderable(renderer, {
|
|
22892
|
+
id: "input-hint",
|
|
22893
|
+
content: getInputHintContent()
|
|
22894
|
+
});
|
|
22895
|
+
inputContainer.add(inputHintText);
|
|
22366
22896
|
helpBarText = new TextRenderable(renderer, {
|
|
22367
22897
|
id: "help-bar-text",
|
|
22368
22898
|
content: getHelpBarContent(),
|
|
22369
22899
|
marginTop: 1
|
|
22370
22900
|
});
|
|
22371
22901
|
mainContainer.add(helpBarText);
|
|
22372
|
-
inputField.on(InputRenderableEvents.ENTER, handleInput);
|
|
22373
22902
|
renderer.keyInput.on("keypress", handleKeypress);
|
|
22374
22903
|
inputField.focus();
|
|
22375
22904
|
}
|
|
@@ -22385,10 +22914,14 @@ function getStatusBarContent() {
|
|
|
22385
22914
|
function getHelpBarContent() {
|
|
22386
22915
|
const theme = getTheme();
|
|
22387
22916
|
if (awaitingConfirmation) {
|
|
22388
|
-
return t`${fg(theme.colors.warning)(">>>
|
|
22917
|
+
return t`${fg(theme.colors.warning)(">>> Cmd+Enter or Enter to execute <<<")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.error)("Esc")}${fg(theme.colors.textMuted)(" Cancel")} ${fg(theme.colors.primary)("e")}${fg(theme.colors.textMuted)(" Edit")} ${fg(theme.colors.primary)("c")}${fg(theme.colors.textMuted)(" Copy")}`;
|
|
22389
22918
|
}
|
|
22390
22919
|
return t`${fg(theme.colors.primary)("Ctrl+X P")}${fg(theme.colors.textMuted)(" Commands")} ${fg(theme.colors.primary)("Ctrl+Y")}${fg(theme.colors.textMuted)(" Safety")} ${fg(theme.colors.primary)("Ctrl+Z")}${fg(theme.colors.textMuted)(" Exit")}`;
|
|
22391
22920
|
}
|
|
22921
|
+
function getInputHintContent() {
|
|
22922
|
+
const theme = getTheme();
|
|
22923
|
+
return t`${fg(theme.colors.textMuted)("Enter")}${fg(theme.colors.border)(" send")} ${fg(theme.colors.textMuted)("Shift+Enter")}${fg(theme.colors.border)(" newline")}`;
|
|
22924
|
+
}
|
|
22392
22925
|
function getWelcomeMessage() {
|
|
22393
22926
|
const providerName = config.provider === "opencode-zen" ? "OpenCode Zen" : "OpenRouter";
|
|
22394
22927
|
const freeNote = config.provider === "opencode-zen" ? `
|
|
@@ -22432,13 +22965,15 @@ function addAssistantMessage(content, command, safety) {
|
|
|
22432
22965
|
renderMessage(msg);
|
|
22433
22966
|
return msg;
|
|
22434
22967
|
}
|
|
22435
|
-
function addResultMessage(content, exitCode) {
|
|
22968
|
+
function addResultMessage(content, exitCode, executionKind, parentMessageId) {
|
|
22436
22969
|
const msg = {
|
|
22437
22970
|
id: generateMessageId(),
|
|
22438
22971
|
type: "result",
|
|
22439
22972
|
content,
|
|
22440
22973
|
timestamp: Date.now(),
|
|
22441
|
-
exitCode
|
|
22974
|
+
exitCode,
|
|
22975
|
+
executionKind,
|
|
22976
|
+
parentMessageId
|
|
22442
22977
|
};
|
|
22443
22978
|
chatMessages.push(msg);
|
|
22444
22979
|
renderMessage(msg);
|
|
@@ -22483,7 +23018,7 @@ function createAssistantMessageRenderable(msg, theme) {
|
|
|
22483
23018
|
width: "100%",
|
|
22484
23019
|
border: true,
|
|
22485
23020
|
borderColor: isSelected ? theme.colors.primary : theme.colors.border,
|
|
22486
|
-
borderStyle: "
|
|
23021
|
+
borderStyle: "rounded",
|
|
22487
23022
|
paddingLeft: 1,
|
|
22488
23023
|
paddingRight: 1,
|
|
22489
23024
|
paddingTop: 0,
|
|
@@ -22492,34 +23027,32 @@ function createAssistantMessageRenderable(msg, theme) {
|
|
|
22492
23027
|
});
|
|
22493
23028
|
const commandText = new TextRenderable(renderer, {
|
|
22494
23029
|
id: `msg-${msg.id}-cmd`,
|
|
22495
|
-
content: t`${fg(theme.colors.textMuted)("Command:")} ${fg(theme.colors.
|
|
23030
|
+
content: t`${fg(theme.colors.textMuted)("Command:")} ${fg(theme.colors.secondary)(msg.command || "")}`
|
|
22496
23031
|
});
|
|
22497
23032
|
card.add(commandText);
|
|
22498
23033
|
if (msg.safety) {
|
|
22499
23034
|
const severityColor = getSeverityColor(msg.safety.severity);
|
|
22500
|
-
const
|
|
23035
|
+
const severityLabel = msg.safety.severity === "low" ? "Low risk" : `${msg.safety.severity[0].toUpperCase()}${msg.safety.severity.slice(1)} risk`;
|
|
22501
23036
|
const safetyText = new TextRenderable(renderer, {
|
|
22502
23037
|
id: `msg-${msg.id}-safety`,
|
|
22503
|
-
content: t`${fg(severityColor)(
|
|
23038
|
+
content: t`${fg(severityColor)(severityLabel)}`
|
|
22504
23039
|
});
|
|
22505
23040
|
card.add(safetyText);
|
|
23041
|
+
if (msg.safety.isDangerous && msg.safety.reason) {
|
|
23042
|
+
const reasonText = new TextRenderable(renderer, {
|
|
23043
|
+
id: `msg-${msg.id}-safety-reason`,
|
|
23044
|
+
content: t`${fg(theme.colors.textMuted)(msg.safety.reason)}`
|
|
23045
|
+
});
|
|
23046
|
+
card.add(reasonText);
|
|
23047
|
+
}
|
|
22506
23048
|
}
|
|
22507
23049
|
if (isSelected && !msg.executed) {
|
|
22508
23050
|
const actionsText = new TextRenderable(renderer, {
|
|
22509
23051
|
id: `msg-${msg.id}-actions`,
|
|
22510
|
-
content: t`${fg(theme.colors.warning)("
|
|
23052
|
+
content: t`${fg(theme.colors.warning)("Cmd+Enter or Enter to run")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.primary)("[c]")} ${fg(theme.colors.textMuted)("Copy")} ${fg(theme.colors.primary)("[e]")} ${fg(theme.colors.textMuted)("Edit")} ${fg(theme.colors.error)("[Esc]")} ${fg(theme.colors.textMuted)("Cancel")}`
|
|
22511
23053
|
});
|
|
22512
23054
|
card.add(actionsText);
|
|
22513
23055
|
}
|
|
22514
|
-
if (msg.executed) {
|
|
22515
|
-
const wasAutoRun = !msg.safety?.isDangerous;
|
|
22516
|
-
const execLabel = wasAutoRun ? "Auto-executed (safe)" : "Executed";
|
|
22517
|
-
const execText = new TextRenderable(renderer, {
|
|
22518
|
-
id: `msg-${msg.id}-exec`,
|
|
22519
|
-
content: t`${fg(theme.colors.success)("✓")} ${fg(theme.colors.success)(execLabel)}`
|
|
22520
|
-
});
|
|
22521
|
-
card.add(execText);
|
|
22522
|
-
}
|
|
22523
23056
|
return card;
|
|
22524
23057
|
}
|
|
22525
23058
|
function createResultMessageRenderable(msg, theme) {
|
|
@@ -22530,28 +23063,30 @@ function createResultMessageRenderable(msg, theme) {
|
|
|
22530
23063
|
`) : [];
|
|
22531
23064
|
const isLongOutput = outputLines.length > 5;
|
|
22532
23065
|
const PREVIEW_LINES = 3;
|
|
23066
|
+
const executionKind = msg.executionKind || "manual";
|
|
22533
23067
|
const card = new BoxRenderable(renderer, {
|
|
22534
23068
|
id: `msg-${msg.id}`,
|
|
22535
23069
|
flexDirection: "column",
|
|
22536
23070
|
width: "100%",
|
|
22537
23071
|
border: true,
|
|
22538
|
-
borderColor:
|
|
22539
|
-
borderStyle: "
|
|
23072
|
+
borderColor: theme.colors.border,
|
|
23073
|
+
borderStyle: "rounded",
|
|
22540
23074
|
paddingLeft: 1,
|
|
22541
23075
|
paddingRight: 1,
|
|
23076
|
+
paddingTop: 0,
|
|
23077
|
+
paddingBottom: 0,
|
|
22542
23078
|
backgroundColor: theme.colors.backgroundPanel,
|
|
22543
23079
|
onMouseDown: isLongOutput ? () => {
|
|
22544
23080
|
toggleResultExpand(msg.id);
|
|
22545
23081
|
} : undefined
|
|
22546
23082
|
});
|
|
22547
|
-
const statusIcon = isSuccess ? "✓" : "✗";
|
|
22548
23083
|
const statusColor = isSuccess ? theme.colors.success : theme.colors.error;
|
|
22549
|
-
const statusLabel = isSuccess ? "Executed
|
|
23084
|
+
const statusLabel = isSuccess ? executionKind === "auto" ? "Auto-executed (safe command)" : executionKind === "dry-run" ? "Dry run (not executed)" : "Executed (confirmed)" : `Command failed (exit code: ${msg.exitCode})`;
|
|
22550
23085
|
const expandIcon = isLongOutput ? isExpanded ? "▼" : "▶" : "";
|
|
22551
23086
|
const lineCount = isLongOutput ? ` (${outputLines.length} lines)` : "";
|
|
22552
23087
|
const statusText = new TextRenderable(renderer, {
|
|
22553
23088
|
id: `msg-${msg.id}-status`,
|
|
22554
|
-
content: t`${fg(statusColor)(
|
|
23089
|
+
content: t`${fg(statusColor)(">")} ${fg(statusColor)(statusLabel)}${fg(theme.colors.textMuted)(lineCount)} ${fg(theme.colors.primary)(expandIcon)}`
|
|
22555
23090
|
});
|
|
22556
23091
|
card.add(statusText);
|
|
22557
23092
|
if (hasOutput) {
|
|
@@ -22564,11 +23099,26 @@ function createResultMessageRenderable(msg, theme) {
|
|
|
22564
23099
|
`) + `
|
|
22565
23100
|
... ${outputLines.length - PREVIEW_LINES} more lines`;
|
|
22566
23101
|
}
|
|
23102
|
+
const outputBox = new BoxRenderable(renderer, {
|
|
23103
|
+
id: `msg-${msg.id}-output-box`,
|
|
23104
|
+
flexDirection: "column",
|
|
23105
|
+
width: "100%",
|
|
23106
|
+
border: true,
|
|
23107
|
+
borderColor: theme.colors.borderSubtle,
|
|
23108
|
+
borderStyle: "single",
|
|
23109
|
+
paddingLeft: 1,
|
|
23110
|
+
paddingRight: 1,
|
|
23111
|
+
paddingTop: 0,
|
|
23112
|
+
paddingBottom: 0,
|
|
23113
|
+
backgroundColor: theme.colors.backgroundElement,
|
|
23114
|
+
marginTop: 1
|
|
23115
|
+
});
|
|
22567
23116
|
const outputText = new TextRenderable(renderer, {
|
|
22568
23117
|
id: `msg-${msg.id}-output`,
|
|
22569
23118
|
content: t`${fg(theme.colors.textMuted)(displayContent)}`
|
|
22570
23119
|
});
|
|
22571
|
-
|
|
23120
|
+
outputBox.add(outputText);
|
|
23121
|
+
card.add(outputBox);
|
|
22572
23122
|
if (isLongOutput) {
|
|
22573
23123
|
const hintText = new TextRenderable(renderer, {
|
|
22574
23124
|
id: `msg-${msg.id}-hint`,
|
|
@@ -22649,17 +23199,23 @@ function refreshThemeColors() {
|
|
|
22649
23199
|
};
|
|
22650
23200
|
}
|
|
22651
23201
|
if (inputField) {
|
|
22652
|
-
inputField.focusedBackgroundColor =
|
|
23202
|
+
inputField.focusedBackgroundColor = "transparent";
|
|
22653
23203
|
inputField.textColor = theme.colors.text;
|
|
22654
|
-
inputField.
|
|
22655
|
-
|
|
23204
|
+
inputField.placeholder = t`${fg(theme.colors.textMuted)("Describe what you want to do...")}`;
|
|
23205
|
+
}
|
|
23206
|
+
if (inputContainer) {
|
|
23207
|
+
inputContainer.borderColor = theme.colors.primary;
|
|
23208
|
+
inputContainer.backgroundColor = theme.colors.backgroundPanel;
|
|
23209
|
+
}
|
|
23210
|
+
if (inputHintText) {
|
|
23211
|
+
inputHintText.content = getInputHintContent();
|
|
22656
23212
|
}
|
|
22657
23213
|
}
|
|
22658
23214
|
async function handleInput(value) {
|
|
22659
23215
|
const input = value.trim();
|
|
22660
23216
|
if (!input)
|
|
22661
23217
|
return;
|
|
22662
|
-
inputField.
|
|
23218
|
+
inputField.setText("");
|
|
22663
23219
|
if (input.startsWith("!")) {
|
|
22664
23220
|
await handleSpecialCommand(input);
|
|
22665
23221
|
return;
|
|
@@ -22736,6 +23292,8 @@ async function processDirectCommand(input, command) {
|
|
|
22736
23292
|
}
|
|
22737
23293
|
}
|
|
22738
23294
|
async function executeAndShowResult(input, command, assistantMsgId) {
|
|
23295
|
+
const executionKind = getExecutionKind(assistantMsgId, dryRunMode);
|
|
23296
|
+
updateAssistantMessage(assistantMsgId, { executed: true });
|
|
22739
23297
|
if (command.startsWith("cd ")) {
|
|
22740
23298
|
const path2 = command.slice(3).trim().replace(/^["']|["']$/g, "");
|
|
22741
23299
|
try {
|
|
@@ -22743,7 +23301,7 @@ async function executeAndShowResult(input, command, assistantMsgId) {
|
|
|
22743
23301
|
process.chdir(expandedPath);
|
|
22744
23302
|
currentCwd = getCwd();
|
|
22745
23303
|
statusBarText.content = getStatusBarContent();
|
|
22746
|
-
addResultMessage(`Changed directory to ${currentCwd}`, 0);
|
|
23304
|
+
addResultMessage(`Changed directory to ${currentCwd}`, 0, executionKind, assistantMsgId);
|
|
22747
23305
|
addToHistory({
|
|
22748
23306
|
input,
|
|
22749
23307
|
command,
|
|
@@ -22751,22 +23309,20 @@ async function executeAndShowResult(input, command, assistantMsgId) {
|
|
|
22751
23309
|
timestamp: Date.now()
|
|
22752
23310
|
});
|
|
22753
23311
|
history = loadHistory();
|
|
22754
|
-
updateAssistantMessage(assistantMsgId, { executed: true });
|
|
22755
23312
|
} catch (err) {
|
|
22756
|
-
addResultMessage(`cd: ${err instanceof Error ? err.message : String(err)}`, 1);
|
|
23313
|
+
addResultMessage(`cd: ${err instanceof Error ? err.message : String(err)}`, 1, executionKind, assistantMsgId);
|
|
22757
23314
|
}
|
|
22758
23315
|
clearCommandState();
|
|
22759
23316
|
return;
|
|
22760
23317
|
}
|
|
22761
23318
|
if (dryRunMode) {
|
|
22762
|
-
addResultMessage(`[DRY RUN] Would execute: ${command}`, 0);
|
|
22763
|
-
updateAssistantMessage(assistantMsgId, { executed: true });
|
|
23319
|
+
addResultMessage(`[DRY RUN] Would execute: ${command}`, 0, executionKind, assistantMsgId);
|
|
22764
23320
|
clearCommandState();
|
|
22765
23321
|
return;
|
|
22766
23322
|
}
|
|
22767
23323
|
try {
|
|
22768
23324
|
const { output, exitCode } = await executeCommandWithCode(command);
|
|
22769
|
-
addResultMessage(output || "Command completed successfully", exitCode);
|
|
23325
|
+
addResultMessage(output || "Command completed successfully", exitCode, executionKind, assistantMsgId);
|
|
22770
23326
|
addToHistory({
|
|
22771
23327
|
input,
|
|
22772
23328
|
command,
|
|
@@ -22774,13 +23330,20 @@ async function executeAndShowResult(input, command, assistantMsgId) {
|
|
|
22774
23330
|
timestamp: Date.now()
|
|
22775
23331
|
});
|
|
22776
23332
|
history = loadHistory();
|
|
22777
|
-
updateAssistantMessage(assistantMsgId, { executed: true });
|
|
22778
23333
|
} catch (error) {
|
|
22779
23334
|
const message = error instanceof Error ? error.message : String(error);
|
|
22780
|
-
addResultMessage(`Error: ${message}`, 1);
|
|
23335
|
+
addResultMessage(`Error: ${message}`, 1, executionKind, assistantMsgId);
|
|
22781
23336
|
}
|
|
22782
23337
|
clearCommandState();
|
|
22783
23338
|
}
|
|
23339
|
+
function getExecutionKind(assistantMsgId, isDryRun) {
|
|
23340
|
+
if (isDryRun)
|
|
23341
|
+
return "dry-run";
|
|
23342
|
+
const assistantMsg = chatMessages.find((msg) => msg.id === assistantMsgId);
|
|
23343
|
+
if (!assistantMsg || assistantMsg.type !== "assistant")
|
|
23344
|
+
return "manual";
|
|
23345
|
+
return assistantMsg.safety?.isDangerous ? "manual" : "auto";
|
|
23346
|
+
}
|
|
22784
23347
|
function executeCommandWithCode(command) {
|
|
22785
23348
|
return new Promise((resolve3, reject) => {
|
|
22786
23349
|
const child = spawn(command, {
|
|
@@ -23404,7 +23967,7 @@ function handleKeypress(key) {
|
|
|
23404
23967
|
if (key.name === "e" && awaitingConfirmation && pendingMessageId) {
|
|
23405
23968
|
const msg = chatMessages.find((m) => m.id === pendingMessageId);
|
|
23406
23969
|
if (msg && msg.command) {
|
|
23407
|
-
inputField.
|
|
23970
|
+
inputField.setText(msg.command);
|
|
23408
23971
|
clearCommandState();
|
|
23409
23972
|
inputField.focus();
|
|
23410
23973
|
}
|