groundcrew-cli 0.15.16 → 0.15.17
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 +15 -8
- package/package.json +1 -1
- package/src/index.ts +23 -12
package/dist/index.js
CHANGED
|
@@ -443,8 +443,12 @@ function readMultilineInput(sessionId) {
|
|
|
443
443
|
const buf = [];
|
|
444
444
|
if (lastTermRow > 0) buf.push(`\x1B[${lastTermRow}A`);
|
|
445
445
|
buf.push("\r\x1B[J");
|
|
446
|
+
const termW = process.stdout.columns || 80;
|
|
447
|
+
const info = ` ${sessionId} `;
|
|
448
|
+
const dashRight = "\u2500".repeat(Math.max(0, termW - 4 - info.length));
|
|
449
|
+
buf.push(dim("\u2500\u2500\u2500" + info + dashRight));
|
|
446
450
|
for (let i = 0; i < lines.length; i++) {
|
|
447
|
-
|
|
451
|
+
buf.push("\n");
|
|
448
452
|
if (i === 0) {
|
|
449
453
|
buf.push(dim(`[${sessionId}]`) + " " + bold(">") + " " + lines[i]);
|
|
450
454
|
} else {
|
|
@@ -457,7 +461,7 @@ function readMultilineInput(sessionId) {
|
|
|
457
461
|
buf.push("\r");
|
|
458
462
|
const col = padWidth + ccol;
|
|
459
463
|
if (col > 0) buf.push(`\x1B[${col}C`);
|
|
460
|
-
lastTermRow = crow;
|
|
464
|
+
lastTermRow = 1 + crow;
|
|
461
465
|
process.stdout.write(buf.join(""));
|
|
462
466
|
};
|
|
463
467
|
const finish = (result) => {
|
|
@@ -606,11 +610,12 @@ function readMultilineInput(sessionId) {
|
|
|
606
610
|
continue;
|
|
607
611
|
}
|
|
608
612
|
if (str[i] === "") {
|
|
609
|
-
|
|
613
|
+
const hasText = fullText();
|
|
614
|
+
if (hasText || lines.length > 1 || lines[0].length > 0) {
|
|
610
615
|
const lastRow = lines.length - 1;
|
|
611
616
|
const rowsDown = lastRow - crow;
|
|
612
617
|
if (rowsDown > 0) process.stdout.write(`\x1B[${rowsDown}B`);
|
|
613
|
-
process.stdout.write("\n");
|
|
618
|
+
process.stdout.write("\r\n");
|
|
614
619
|
lines.length = 0;
|
|
615
620
|
lines.push("");
|
|
616
621
|
crow = 0;
|
|
@@ -618,7 +623,7 @@ function readMultilineInput(sessionId) {
|
|
|
618
623
|
lastTermRow = 0;
|
|
619
624
|
render();
|
|
620
625
|
} else {
|
|
621
|
-
process.stdout.write("\n");
|
|
626
|
+
process.stdout.write("\r\n");
|
|
622
627
|
finish(null);
|
|
623
628
|
return;
|
|
624
629
|
}
|
|
@@ -687,8 +692,10 @@ function readMultilineInput(sessionId) {
|
|
|
687
692
|
continue;
|
|
688
693
|
}
|
|
689
694
|
if (str[i] === " ") {
|
|
690
|
-
|
|
691
|
-
|
|
695
|
+
const currentLine = lines[crow];
|
|
696
|
+
if (lines.length === 1 && currentLine.startsWith("/")) {
|
|
697
|
+
const partial = currentLine.split(" ")[0];
|
|
698
|
+
const matches = CHAT_COMMANDS.filter((c) => c.cmd.startsWith(partial));
|
|
692
699
|
if (matches.length === 1) {
|
|
693
700
|
lines[0] = matches[0].cmd + " ";
|
|
694
701
|
ccol = lines[0].length;
|
|
@@ -697,7 +704,7 @@ function readMultilineInput(sessionId) {
|
|
|
697
704
|
const lastRow = lines.length - 1;
|
|
698
705
|
const rowsDown = lastRow - crow;
|
|
699
706
|
if (rowsDown > 0) process.stdout.write(`\x1B[${rowsDown}B`);
|
|
700
|
-
process.stdout.write("\n");
|
|
707
|
+
process.stdout.write("\r\n");
|
|
701
708
|
for (const m of matches) {
|
|
702
709
|
process.stdout.write(` ${cyan(m.cmd.padEnd(14))} ${dim(m.desc)}
|
|
703
710
|
`);
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -587,7 +587,7 @@ function readMultilineInput(sessionId: string): Promise<string | null> {
|
|
|
587
587
|
// Visible width of prompt: "[sessionId] > "
|
|
588
588
|
const padWidth = sessionId.length + 5; // [ + id + ] + space + > + space = len+5
|
|
589
589
|
|
|
590
|
-
// Track
|
|
590
|
+
// Track how many rows up from cursor to top of rendered area (including separator)
|
|
591
591
|
let lastTermRow = 0;
|
|
592
592
|
let pasteBuffer = "";
|
|
593
593
|
let isPasting = false;
|
|
@@ -597,13 +597,19 @@ function readMultilineInput(sessionId: string): Promise<string | null> {
|
|
|
597
597
|
const render = () => {
|
|
598
598
|
const buf: string[] = [];
|
|
599
599
|
|
|
600
|
-
// Move to start of input area
|
|
600
|
+
// Move to start of input area (includes separator line)
|
|
601
601
|
if (lastTermRow > 0) buf.push(`\x1b[${lastTermRow}A`);
|
|
602
602
|
buf.push("\r\x1b[J"); // col 0 + clear to end of screen
|
|
603
603
|
|
|
604
|
-
//
|
|
604
|
+
// Separator line: ─── sessionId ─────────
|
|
605
|
+
const termW = process.stdout.columns || 80;
|
|
606
|
+
const info = ` ${sessionId} `;
|
|
607
|
+
const dashRight = "─".repeat(Math.max(0, termW - 4 - info.length));
|
|
608
|
+
buf.push(dim("───" + info + dashRight));
|
|
609
|
+
|
|
610
|
+
// Draw each input line (below separator)
|
|
605
611
|
for (let i = 0; i < lines.length; i++) {
|
|
606
|
-
|
|
612
|
+
buf.push("\n");
|
|
607
613
|
if (i === 0) {
|
|
608
614
|
buf.push(dim(`[${sessionId}]`) + " " + bold(">") + " " + lines[i]);
|
|
609
615
|
} else {
|
|
@@ -620,7 +626,9 @@ function readMultilineInput(sessionId: string): Promise<string | null> {
|
|
|
620
626
|
const col = padWidth + ccol;
|
|
621
627
|
if (col > 0) buf.push(`\x1b[${col}C`);
|
|
622
628
|
|
|
623
|
-
lastTermRow =
|
|
629
|
+
// lastTermRow = rows from cursor back to top of separator
|
|
630
|
+
// separator is 1 row, then crow rows of input below it
|
|
631
|
+
lastTermRow = 1 + crow;
|
|
624
632
|
process.stdout.write(buf.join(""));
|
|
625
633
|
};
|
|
626
634
|
|
|
@@ -752,17 +760,18 @@ function readMultilineInput(sessionId: string): Promise<string | null> {
|
|
|
752
760
|
|
|
753
761
|
// Ctrl+C — clear input or exit
|
|
754
762
|
if (str[i] === "\x03") {
|
|
755
|
-
|
|
756
|
-
|
|
763
|
+
const hasText = fullText();
|
|
764
|
+
if (hasText || lines.length > 1 || lines[0].length > 0) {
|
|
765
|
+
// Move past current rendering to below last line, start fresh
|
|
757
766
|
const lastRow = lines.length - 1;
|
|
758
767
|
const rowsDown = lastRow - crow;
|
|
759
768
|
if (rowsDown > 0) process.stdout.write(`\x1b[${rowsDown}B`);
|
|
760
|
-
process.stdout.write("\n");
|
|
769
|
+
process.stdout.write("\r\n");
|
|
761
770
|
lines.length = 0; lines.push("");
|
|
762
771
|
crow = 0; ccol = 0; lastTermRow = 0;
|
|
763
772
|
render();
|
|
764
773
|
} else {
|
|
765
|
-
process.stdout.write("\n");
|
|
774
|
+
process.stdout.write("\r\n");
|
|
766
775
|
finish(null); return;
|
|
767
776
|
}
|
|
768
777
|
i++; continue;
|
|
@@ -807,8 +816,10 @@ function readMultilineInput(sessionId: string): Promise<string | null> {
|
|
|
807
816
|
|
|
808
817
|
// Tab — slash command completion
|
|
809
818
|
if (str[i] === "\t") {
|
|
810
|
-
|
|
811
|
-
|
|
819
|
+
const currentLine = lines[crow];
|
|
820
|
+
if (lines.length === 1 && currentLine.startsWith("/")) {
|
|
821
|
+
const partial = currentLine.split(" ")[0]; // only match command part
|
|
822
|
+
const matches = CHAT_COMMANDS.filter(c => c.cmd.startsWith(partial));
|
|
812
823
|
if (matches.length === 1) {
|
|
813
824
|
lines[0] = matches[0].cmd + " ";
|
|
814
825
|
ccol = lines[0].length; render();
|
|
@@ -817,7 +828,7 @@ function readMultilineInput(sessionId: string): Promise<string | null> {
|
|
|
817
828
|
const lastRow = lines.length - 1;
|
|
818
829
|
const rowsDown = lastRow - crow;
|
|
819
830
|
if (rowsDown > 0) process.stdout.write(`\x1b[${rowsDown}B`);
|
|
820
|
-
process.stdout.write("\n");
|
|
831
|
+
process.stdout.write("\r\n");
|
|
821
832
|
for (const m of matches) {
|
|
822
833
|
process.stdout.write(` ${cyan(m.cmd.padEnd(14))} ${dim(m.desc)}\n`);
|
|
823
834
|
}
|