pi-interactive-shell 0.4.6 → 0.4.8
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/CHANGELOG.md +20 -0
- package/README.md +108 -102
- package/SKILL.md +49 -16
- package/config.ts +0 -2
- package/index.ts +47 -537
- package/overlay-component.ts +75 -567
- package/package.json +2 -2
- package/pty-session.ts +32 -14
- package/session-manager.ts +6 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-interactive-shell",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.8",
|
|
4
4
|
"description": "Run AI coding agents as foreground subagents in pi TUI overlays with hands-free monitoring",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
]
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"node-pty": "^1.
|
|
26
|
+
"node-pty": "^1.1.0",
|
|
27
27
|
"@xterm/headless": "^5.5.0",
|
|
28
28
|
"@xterm/addon-serialize": "^0.13.0"
|
|
29
29
|
},
|
package/pty-session.ts
CHANGED
|
@@ -501,47 +501,61 @@ export class PtyTerminalSession {
|
|
|
501
501
|
return lines;
|
|
502
502
|
}
|
|
503
503
|
|
|
504
|
-
getTailLines(options: { lines: number; ansi?: boolean; maxChars?: number }):
|
|
504
|
+
getTailLines(options: { lines: number; ansi?: boolean; maxChars?: number }): {
|
|
505
|
+
lines: string[];
|
|
506
|
+
totalLinesInBuffer: number;
|
|
507
|
+
truncatedByChars: boolean;
|
|
508
|
+
} {
|
|
505
509
|
const requested = Math.max(0, Math.trunc(options.lines));
|
|
506
510
|
const maxChars = options.maxChars !== undefined ? Math.max(0, Math.trunc(options.maxChars)) : undefined;
|
|
507
|
-
|
|
508
|
-
|
|
511
|
+
|
|
509
512
|
const buffer = this.xterm.buffer.active;
|
|
510
|
-
const
|
|
511
|
-
|
|
513
|
+
const totalLinesInBuffer = buffer.length;
|
|
514
|
+
|
|
515
|
+
if (requested === 0) {
|
|
516
|
+
return { lines: [], totalLinesInBuffer, truncatedByChars: false };
|
|
517
|
+
}
|
|
512
518
|
|
|
519
|
+
const start = Math.max(0, totalLinesInBuffer - requested);
|
|
513
520
|
const out: string[] = [];
|
|
514
521
|
let remainingChars = maxChars;
|
|
522
|
+
let truncatedByChars = false;
|
|
515
523
|
|
|
516
524
|
const useAnsi = options.ansi && this.serializer;
|
|
517
525
|
if (useAnsi) {
|
|
518
526
|
const serialized = this.serializer!.serialize();
|
|
519
527
|
const serializedLines = serialized.split(/\r?\n/);
|
|
520
|
-
if (serializedLines.length >=
|
|
521
|
-
for (let i = start; i <
|
|
528
|
+
if (serializedLines.length >= totalLinesInBuffer) {
|
|
529
|
+
for (let i = start; i < totalLinesInBuffer; i++) {
|
|
522
530
|
const raw = serializedLines[i] ?? "";
|
|
523
531
|
const line = sanitizeLine(raw) + "\u001b[0m";
|
|
524
532
|
if (remainingChars !== undefined) {
|
|
525
|
-
if (remainingChars <= 0)
|
|
533
|
+
if (remainingChars <= 0) {
|
|
534
|
+
truncatedByChars = true;
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
526
537
|
remainingChars -= line.length;
|
|
527
538
|
}
|
|
528
539
|
out.push(line);
|
|
529
540
|
}
|
|
530
|
-
return out;
|
|
541
|
+
return { lines: out, totalLinesInBuffer, truncatedByChars };
|
|
531
542
|
}
|
|
532
543
|
}
|
|
533
544
|
|
|
534
|
-
for (let i = start; i <
|
|
545
|
+
for (let i = start; i < totalLinesInBuffer; i++) {
|
|
535
546
|
const lineObj = buffer.getLine(i);
|
|
536
547
|
const line = sanitizeLine(lineObj?.translateToString(true) ?? "");
|
|
537
548
|
if (remainingChars !== undefined) {
|
|
538
|
-
if (remainingChars <= 0)
|
|
549
|
+
if (remainingChars <= 0) {
|
|
550
|
+
truncatedByChars = true;
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
539
553
|
remainingChars -= line.length;
|
|
540
554
|
}
|
|
541
555
|
out.push(line);
|
|
542
556
|
}
|
|
543
557
|
|
|
544
|
-
return out;
|
|
558
|
+
return { lines: out, totalLinesInBuffer, truncatedByChars };
|
|
545
559
|
}
|
|
546
560
|
|
|
547
561
|
/**
|
|
@@ -578,6 +592,7 @@ export class PtyTerminalSession {
|
|
|
578
592
|
slice: string;
|
|
579
593
|
totalLines: number;
|
|
580
594
|
totalChars: number;
|
|
595
|
+
sliceLineCount: number;
|
|
581
596
|
} {
|
|
582
597
|
let text = this.rawOutput;
|
|
583
598
|
|
|
@@ -587,7 +602,7 @@ export class PtyTerminalSession {
|
|
|
587
602
|
}
|
|
588
603
|
|
|
589
604
|
if (!text) {
|
|
590
|
-
return { slice: "", totalLines: 0, totalChars: 0 };
|
|
605
|
+
return { slice: "", totalLines: 0, totalChars: 0, sliceLineCount: 0 };
|
|
591
606
|
}
|
|
592
607
|
|
|
593
608
|
// Normalize line endings and split
|
|
@@ -618,10 +633,13 @@ export class PtyTerminalSession {
|
|
|
618
633
|
? start + Math.max(0, Math.floor(options.limit))
|
|
619
634
|
: undefined;
|
|
620
635
|
|
|
636
|
+
const selectedLines = lines.slice(start, end);
|
|
637
|
+
|
|
621
638
|
return {
|
|
622
|
-
slice:
|
|
639
|
+
slice: selectedLines.join("\n"),
|
|
623
640
|
totalLines,
|
|
624
641
|
totalChars,
|
|
642
|
+
sliceLineCount: selectedLines.length,
|
|
625
643
|
};
|
|
626
644
|
}
|
|
627
645
|
|
package/session-manager.ts
CHANGED
|
@@ -24,6 +24,9 @@ export interface OutputResult {
|
|
|
24
24
|
output: string;
|
|
25
25
|
truncated: boolean;
|
|
26
26
|
totalBytes: number;
|
|
27
|
+
// For incremental/offset modes
|
|
28
|
+
totalLines?: number;
|
|
29
|
+
hasMore?: boolean;
|
|
27
30
|
// Rate limiting
|
|
28
31
|
rateLimited?: boolean;
|
|
29
32
|
waitSeconds?: number;
|
|
@@ -34,7 +37,8 @@ export interface OutputOptions {
|
|
|
34
37
|
lines?: number; // Override default 20 lines
|
|
35
38
|
maxChars?: number; // Override default 5KB
|
|
36
39
|
offset?: number; // Line offset for pagination (0-indexed)
|
|
37
|
-
drain?: boolean; // If true, return only NEW output since last query (
|
|
40
|
+
drain?: boolean; // If true, return only NEW output since last query (raw stream)
|
|
41
|
+
incremental?: boolean; // If true, return next N lines not yet seen (server tracks position)
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
export interface ActiveSession {
|
|
@@ -141,7 +145,7 @@ export class ShellSessionManager {
|
|
|
141
145
|
reason?: string;
|
|
142
146
|
write: (data: string) => void;
|
|
143
147
|
kill: () => void;
|
|
144
|
-
getOutput: (
|
|
148
|
+
getOutput: (options?: OutputOptions | boolean) => OutputResult;
|
|
145
149
|
getStatus: () => ActiveSessionStatus;
|
|
146
150
|
getRuntime: () => number;
|
|
147
151
|
getResult: () => ActiveSessionResult | undefined;
|