groundcrew-cli 0.16.1 → 0.16.3
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.js +24 -19
- package/package.json +1 -1
- package/src/index.ts +36 -24
package/dist/index.js
CHANGED
|
@@ -494,8 +494,20 @@ function readMultilineInput(sessionId, projectName, gitCtx) {
|
|
|
494
494
|
buf.push(" ".repeat(padWidth) + lines[i]);
|
|
495
495
|
}
|
|
496
496
|
}
|
|
497
|
+
let suggestionRows = 0;
|
|
498
|
+
if (lines.length === 1 && lines[0].startsWith("/") && !lines[0].includes(" ")) {
|
|
499
|
+
const partial = lines[0];
|
|
500
|
+
const matches = CHAT_COMMANDS.filter((c) => c.cmd.startsWith(partial));
|
|
501
|
+
if (matches.length > 0 && partial.length >= 1) {
|
|
502
|
+
for (const m of matches) {
|
|
503
|
+
buf.push(`
|
|
504
|
+
${cyan(m.cmd.padEnd(14))} ${dim(m.desc)}`);
|
|
505
|
+
suggestionRows++;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
497
509
|
const lastRow = lines.length - 1;
|
|
498
|
-
const rowsUp = lastRow - crow;
|
|
510
|
+
const rowsUp = lastRow - crow + suggestionRows;
|
|
499
511
|
if (rowsUp > 0) buf.push(`\x1B[${rowsUp}A`);
|
|
500
512
|
buf.push("\r");
|
|
501
513
|
const col = padWidth + ccol;
|
|
@@ -509,13 +521,17 @@ function readMultilineInput(sessionId, projectName, gitCtx) {
|
|
|
509
521
|
};
|
|
510
522
|
const submit = () => {
|
|
511
523
|
const text = fullText();
|
|
512
|
-
const lastRow = lines.length - 1;
|
|
513
|
-
const rowsDown = lastRow - crow;
|
|
514
524
|
const buf = [];
|
|
515
|
-
if (
|
|
516
|
-
buf.push("\r");
|
|
517
|
-
|
|
518
|
-
|
|
525
|
+
if (lastTermRow > 0) buf.push(`\x1B[${lastTermRow}A`);
|
|
526
|
+
buf.push("\r\x1B[J");
|
|
527
|
+
for (let i = 0; i < lines.length; i++) {
|
|
528
|
+
if (i > 0) buf.push("\n");
|
|
529
|
+
if (i === 0) {
|
|
530
|
+
buf.push(dim(`[${sessionId}]`) + " " + bold(">") + " " + lines[i]);
|
|
531
|
+
} else {
|
|
532
|
+
buf.push(" ".repeat(padWidth) + lines[i]);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
519
535
|
buf.push("\n");
|
|
520
536
|
process.stdout.write(buf.join(""));
|
|
521
537
|
lastTermRow = 0;
|
|
@@ -664,15 +680,10 @@ function readMultilineInput(sessionId, projectName, gitCtx) {
|
|
|
664
680
|
switch (codepoint) {
|
|
665
681
|
case 99:
|
|
666
682
|
if (fullText() || lines.length > 1 || lines[0].length > 0) {
|
|
667
|
-
const lastRow = lines.length - 1;
|
|
668
|
-
const rowsDown = lastRow - crow;
|
|
669
|
-
if (rowsDown > 0) process.stdout.write(`\x1B[${rowsDown}B`);
|
|
670
|
-
process.stdout.write("\r\n");
|
|
671
683
|
lines.length = 0;
|
|
672
684
|
lines.push("");
|
|
673
685
|
crow = 0;
|
|
674
686
|
ccol = 0;
|
|
675
|
-
lastTermRow = 0;
|
|
676
687
|
render();
|
|
677
688
|
} else {
|
|
678
689
|
process.stdout.write("\r\n");
|
|
@@ -748,17 +759,11 @@ function readMultilineInput(sessionId, projectName, gitCtx) {
|
|
|
748
759
|
continue;
|
|
749
760
|
}
|
|
750
761
|
if (str[i] === "") {
|
|
751
|
-
|
|
752
|
-
if (hasText || lines.length > 1 || lines[0].length > 0) {
|
|
753
|
-
const lastRow = lines.length - 1;
|
|
754
|
-
const rowsDown = lastRow - crow;
|
|
755
|
-
if (rowsDown > 0) process.stdout.write(`\x1B[${rowsDown}B`);
|
|
756
|
-
process.stdout.write("\r\n");
|
|
762
|
+
if (fullText() || lines.length > 1 || lines[0].length > 0) {
|
|
757
763
|
lines.length = 0;
|
|
758
764
|
lines.push("");
|
|
759
765
|
crow = 0;
|
|
760
766
|
ccol = 0;
|
|
761
|
-
lastTermRow = 0;
|
|
762
767
|
render();
|
|
763
768
|
} else {
|
|
764
769
|
process.stdout.write("\r\n");
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -626,7 +626,7 @@ function readMultilineInput(sessionId: string, projectName: string, gitCtx: { br
|
|
|
626
626
|
const render = () => {
|
|
627
627
|
const buf: string[] = [];
|
|
628
628
|
|
|
629
|
-
// Move to start of input area (includes separator line)
|
|
629
|
+
// Move to start of input area (includes separator line + suggestions)
|
|
630
630
|
if (lastTermRow > 0) buf.push(`\x1b[${lastTermRow}A`);
|
|
631
631
|
buf.push("\r\x1b[J"); // col 0 + clear to end of screen
|
|
632
632
|
|
|
@@ -652,17 +652,31 @@ function readMultilineInput(sessionId: string, projectName: string, gitCtx: { br
|
|
|
652
652
|
}
|
|
653
653
|
}
|
|
654
654
|
|
|
655
|
+
// Auto-show slash command suggestions below input
|
|
656
|
+
let suggestionRows = 0;
|
|
657
|
+
if (lines.length === 1 && lines[0].startsWith("/") && !lines[0].includes(" ")) {
|
|
658
|
+
const partial = lines[0];
|
|
659
|
+
const matches = CHAT_COMMANDS.filter(c => c.cmd.startsWith(partial));
|
|
660
|
+
if (matches.length > 0 && partial.length >= 1) {
|
|
661
|
+
for (const m of matches) {
|
|
662
|
+
buf.push(`\n ${cyan(m.cmd.padEnd(14))} ${dim(m.desc)}`);
|
|
663
|
+
suggestionRows++;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
655
668
|
// Position cursor at (crow, ccol)
|
|
656
669
|
const lastRow = lines.length - 1;
|
|
657
|
-
|
|
670
|
+
// Position cursor at (crow, ccol) — move up past remaining input lines + suggestions
|
|
671
|
+
const rowsUp = (lastRow - crow) + suggestionRows;
|
|
658
672
|
if (rowsUp > 0) buf.push(`\x1b[${rowsUp}A`);
|
|
659
673
|
|
|
660
674
|
buf.push("\r");
|
|
661
675
|
const col = padWidth + ccol;
|
|
662
676
|
if (col > 0) buf.push(`\x1b[${col}C`);
|
|
663
677
|
|
|
664
|
-
// lastTermRow = rows
|
|
665
|
-
//
|
|
678
|
+
// lastTermRow = rows above cursor (separator + input lines above crow)
|
|
679
|
+
// Suggestion rows below cursor are cleared by \x1b[J on next render
|
|
666
680
|
lastTermRow = 1 + crow;
|
|
667
681
|
process.stdout.write(buf.join(""));
|
|
668
682
|
};
|
|
@@ -674,14 +688,20 @@ function readMultilineInput(sessionId: string, projectName: string, gitCtx: { br
|
|
|
674
688
|
|
|
675
689
|
const submit = () => {
|
|
676
690
|
const text = fullText();
|
|
677
|
-
//
|
|
678
|
-
const lastRow = lines.length - 1;
|
|
679
|
-
const rowsDown = lastRow - crow;
|
|
691
|
+
// Erase the separator + input area, then re-draw only the prompt (no separator in history)
|
|
680
692
|
const buf: string[] = [];
|
|
681
|
-
if (
|
|
682
|
-
buf.push("\r");
|
|
683
|
-
|
|
684
|
-
|
|
693
|
+
if (lastTermRow > 0) buf.push(`\x1b[${lastTermRow}A`);
|
|
694
|
+
buf.push("\r\x1b[J"); // clear from separator line down
|
|
695
|
+
|
|
696
|
+
// Re-draw only the input lines (no separator)
|
|
697
|
+
for (let i = 0; i < lines.length; i++) {
|
|
698
|
+
if (i > 0) buf.push("\n");
|
|
699
|
+
if (i === 0) {
|
|
700
|
+
buf.push(dim(`[${sessionId}]`) + " " + bold(">") + " " + lines[i]);
|
|
701
|
+
} else {
|
|
702
|
+
buf.push(" ".repeat(padWidth) + lines[i]);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
685
705
|
buf.push("\n");
|
|
686
706
|
process.stdout.write(buf.join(""));
|
|
687
707
|
lastTermRow = 0;
|
|
@@ -816,12 +836,9 @@ function readMultilineInput(sessionId: string, projectName: string, gitCtx: { br
|
|
|
816
836
|
switch (codepoint) {
|
|
817
837
|
case 99: // Ctrl+C
|
|
818
838
|
if (fullText() || lines.length > 1 || lines[0].length > 0) {
|
|
819
|
-
|
|
820
|
-
const rowsDown = lastRow - crow;
|
|
821
|
-
if (rowsDown > 0) process.stdout.write(`\x1b[${rowsDown}B`);
|
|
822
|
-
process.stdout.write("\r\n");
|
|
839
|
+
// Clear input in-place (no scrollback residue)
|
|
823
840
|
lines.length = 0; lines.push("");
|
|
824
|
-
crow = 0; ccol = 0;
|
|
841
|
+
crow = 0; ccol = 0;
|
|
825
842
|
render();
|
|
826
843
|
} else {
|
|
827
844
|
process.stdout.write("\r\n");
|
|
@@ -869,15 +886,10 @@ function readMultilineInput(sessionId: string, projectName: string, gitCtx: { br
|
|
|
869
886
|
|
|
870
887
|
// Ctrl+C — clear input or exit
|
|
871
888
|
if (str[i] === "\x03") {
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
// Move past current rendering to below last line, start fresh
|
|
875
|
-
const lastRow = lines.length - 1;
|
|
876
|
-
const rowsDown = lastRow - crow;
|
|
877
|
-
if (rowsDown > 0) process.stdout.write(`\x1b[${rowsDown}B`);
|
|
878
|
-
process.stdout.write("\r\n");
|
|
889
|
+
if (fullText() || lines.length > 1 || lines[0].length > 0) {
|
|
890
|
+
// Clear input in-place (no scrollback residue)
|
|
879
891
|
lines.length = 0; lines.push("");
|
|
880
|
-
crow = 0; ccol = 0;
|
|
892
|
+
crow = 0; ccol = 0;
|
|
881
893
|
render();
|
|
882
894
|
} else {
|
|
883
895
|
process.stdout.write("\r\n");
|