terminal-pilot 0.0.18 → 0.0.20
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 +3809 -1510
- package/dist/cli.js.map +4 -4
- package/dist/commands/close-session.js +413 -98
- package/dist/commands/close-session.js.map +2 -2
- package/dist/commands/create-session.js +413 -98
- package/dist/commands/create-session.js.map +2 -2
- package/dist/commands/fill.js +413 -98
- package/dist/commands/fill.js.map +2 -2
- package/dist/commands/get-session.js +413 -98
- package/dist/commands/get-session.js.map +2 -2
- package/dist/commands/index.d.ts +224 -1
- package/dist/commands/index.js +1370 -301
- package/dist/commands/index.js.map +4 -4
- package/dist/commands/install.js +718 -144
- package/dist/commands/install.js.map +4 -4
- package/dist/commands/installer.d.ts +5 -0
- package/dist/commands/installer.js +127 -36
- package/dist/commands/installer.js.map +4 -4
- package/dist/commands/list-sessions.js +413 -98
- package/dist/commands/list-sessions.js.map +2 -2
- package/dist/commands/press-key.js +413 -98
- package/dist/commands/press-key.js.map +2 -2
- package/dist/commands/read-history.js +413 -98
- package/dist/commands/read-history.js.map +2 -2
- package/dist/commands/read-screen.js +413 -98
- package/dist/commands/read-screen.js.map +2 -2
- package/dist/commands/resize.js +413 -98
- package/dist/commands/resize.js.map +2 -2
- package/dist/commands/runtime.js +354 -87
- package/dist/commands/runtime.js.map +2 -2
- package/dist/commands/screenshot.js +648 -138
- package/dist/commands/screenshot.js.map +3 -3
- package/dist/commands/send-signal.js +413 -98
- package/dist/commands/send-signal.js.map +2 -2
- package/dist/commands/type.js +413 -98
- package/dist/commands/type.js.map +2 -2
- package/dist/commands/uninstall.js +213 -61
- package/dist/commands/uninstall.js.map +4 -4
- package/dist/commands/wait-for-exit.js +413 -98
- package/dist/commands/wait-for-exit.js.map +2 -2
- package/dist/commands/wait-for.js +413 -98
- package/dist/commands/wait-for.js.map +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +318 -80
- package/dist/index.js.map +3 -3
- package/dist/terminal-buffer.d.ts +18 -0
- package/dist/terminal-buffer.js +234 -43
- package/dist/terminal-buffer.js.map +2 -2
- package/dist/terminal-pilot.js +312 -73
- package/dist/terminal-pilot.js.map +2 -2
- package/dist/terminal-session.d.ts +2 -2
- package/dist/terminal-session.js +306 -68
- package/dist/terminal-session.js.map +2 -2
- package/dist/testing/cli-repl.js +3809 -1510
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +3827 -1528
- package/dist/testing/qa-cli.js.map +4 -4
- package/node_modules/@poe-code/agent-skill-config/README.md +103 -0
- package/node_modules/@poe-code/agent-skill-config/dist/apply.d.ts +25 -0
- package/node_modules/@poe-code/agent-skill-config/dist/apply.js +159 -0
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.d.ts +23 -0
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +341 -0
- package/node_modules/@poe-code/agent-skill-config/dist/configs.d.ts +16 -0
- package/node_modules/@poe-code/agent-skill-config/dist/configs.js +70 -0
- package/node_modules/@poe-code/agent-skill-config/dist/exports.compile-check.d.ts +1 -0
- package/node_modules/@poe-code/agent-skill-config/dist/exports.compile-check.js +1 -0
- package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.d.ts +8 -0
- package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.js +159 -0
- package/node_modules/@poe-code/agent-skill-config/dist/index.d.ts +11 -0
- package/node_modules/@poe-code/agent-skill-config/dist/index.js +6 -0
- package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.d.ts +22 -0
- package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.js +87 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates/poe-generate.md +47 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates/terminal-pilot.md +45 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates.d.ts +3 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates.js +63 -0
- package/node_modules/@poe-code/agent-skill-config/dist/types.d.ts +16 -0
- package/node_modules/@poe-code/agent-skill-config/dist/types.js +1 -0
- package/node_modules/@poe-code/agent-skill-config/package.json +24 -0
- package/package.json +7 -2
package/dist/commands/fill.js
CHANGED
|
@@ -40,13 +40,20 @@ function Json() {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// ../toolcraft-schema/src/oneof.ts
|
|
43
|
-
function assertValidBranches(branches) {
|
|
43
|
+
function assertValidBranches(branches, discriminator) {
|
|
44
44
|
if (Object.keys(branches).length === 0) {
|
|
45
45
|
throw new Error("OneOf schema requires at least one branch");
|
|
46
46
|
}
|
|
47
|
+
for (const [branchName, branch] of Object.entries(branches)) {
|
|
48
|
+
if (Object.prototype.hasOwnProperty.call(branch.shape, discriminator)) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`OneOf branch "${branchName}" must not declare discriminator field "${discriminator}".`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
47
54
|
}
|
|
48
55
|
function OneOf(config) {
|
|
49
|
-
assertValidBranches(config.branches);
|
|
56
|
+
assertValidBranches(config.branches, config.discriminator);
|
|
50
57
|
return {
|
|
51
58
|
kind: "oneOf",
|
|
52
59
|
discriminator: config.discriminator,
|
|
@@ -69,21 +76,25 @@ function isOptionalSchema(schema) {
|
|
|
69
76
|
function getRequiredKeys(schema) {
|
|
70
77
|
return Object.keys(schema.shape).filter((key) => !isOptionalSchema(schema.shape[key])).sort();
|
|
71
78
|
}
|
|
72
|
-
function getRequiredKeyFingerprint(schema) {
|
|
73
|
-
return getRequiredKeys(schema).join("+");
|
|
74
|
-
}
|
|
75
79
|
function assertUniqueRequiredKeyFingerprints(branches) {
|
|
76
80
|
const fingerprints = /* @__PURE__ */ new Map();
|
|
77
81
|
branches.forEach((branch, index) => {
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
const requiredKeys = getRequiredKeys(branch);
|
|
83
|
+
const fingerprint = JSON.stringify(requiredKeys);
|
|
84
|
+
const existing = fingerprints.get(fingerprint);
|
|
85
|
+
if (existing === void 0) {
|
|
86
|
+
fingerprints.set(fingerprint, {
|
|
87
|
+
display: requiredKeys.join("+"),
|
|
88
|
+
indices: [index]
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
existing.indices.push(index);
|
|
82
93
|
});
|
|
83
|
-
for (const
|
|
94
|
+
for (const { display, indices } of fingerprints.values()) {
|
|
84
95
|
if (indices.length > 1) {
|
|
85
96
|
throw new Error(
|
|
86
|
-
`Union branches [${indices.join(", ")}] share required-key fingerprint "${
|
|
97
|
+
`Union branches [${indices.join(", ")}] share required-key fingerprint "${display}". Each branch must require a distinct set of keys.`
|
|
87
98
|
);
|
|
88
99
|
}
|
|
89
100
|
}
|
|
@@ -111,15 +122,47 @@ function assertValidEnumValues(values) {
|
|
|
111
122
|
if (uniqueValues.size !== values.length) {
|
|
112
123
|
throw new Error("Enum schema values must be unique");
|
|
113
124
|
}
|
|
125
|
+
if (values.some((value) => typeof value === "number" && !Number.isFinite(value))) {
|
|
126
|
+
throw new Error("Enum schema numeric values must be finite");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function assertNonNegativeInteger(value, name) {
|
|
130
|
+
if (value !== void 0 && (!Number.isInteger(value) || value < 0)) {
|
|
131
|
+
throw new Error(`${name} must be a non-negative integer`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function assertFiniteNumber(value, name) {
|
|
135
|
+
if (value !== void 0 && !Number.isFinite(value)) {
|
|
136
|
+
throw new Error(`${name} must be finite`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function assertPattern(pattern) {
|
|
140
|
+
if (pattern === void 0) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
new RegExp(pattern);
|
|
145
|
+
} catch {
|
|
146
|
+
throw new Error("pattern must be a valid regular expression");
|
|
147
|
+
}
|
|
114
148
|
}
|
|
115
149
|
var S = {
|
|
116
150
|
String(options = {}) {
|
|
151
|
+
assertNonNegativeInteger(options.minLength, "minLength");
|
|
152
|
+
assertNonNegativeInteger(options.maxLength, "maxLength");
|
|
153
|
+
assertPattern(options.pattern);
|
|
117
154
|
return {
|
|
118
155
|
kind: "string",
|
|
119
156
|
...options
|
|
120
157
|
};
|
|
121
158
|
},
|
|
122
159
|
Number(options = {}) {
|
|
160
|
+
assertFiniteNumber(options.minimum, "minimum");
|
|
161
|
+
assertFiniteNumber(options.maximum, "maximum");
|
|
162
|
+
assertFiniteNumber(options.default, "default");
|
|
163
|
+
if (options.jsonType === "integer" && options.default !== void 0 && !Number.isInteger(options.default)) {
|
|
164
|
+
throw new Error("default must be an integer");
|
|
165
|
+
}
|
|
123
166
|
return {
|
|
124
167
|
kind: "number",
|
|
125
168
|
...options
|
|
@@ -133,6 +176,9 @@ var S = {
|
|
|
133
176
|
},
|
|
134
177
|
Enum(values, options = {}) {
|
|
135
178
|
assertValidEnumValues(values);
|
|
179
|
+
if (options.jsonType === "integer" && values.some((value) => typeof value !== "number" || !Number.isInteger(value))) {
|
|
180
|
+
throw new Error("Integer enum values must be integers");
|
|
181
|
+
}
|
|
136
182
|
return {
|
|
137
183
|
kind: "enum",
|
|
138
184
|
values,
|
|
@@ -140,6 +186,8 @@ var S = {
|
|
|
140
186
|
};
|
|
141
187
|
},
|
|
142
188
|
Array(item, options = {}) {
|
|
189
|
+
assertNonNegativeInteger(options.minItems, "minItems");
|
|
190
|
+
assertNonNegativeInteger(options.maxItems, "maxItems");
|
|
143
191
|
return {
|
|
144
192
|
kind: "array",
|
|
145
193
|
item,
|
|
@@ -448,27 +496,53 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
|
|
|
448
496
|
|
|
449
497
|
// src/terminal-buffer.ts
|
|
450
498
|
var RESET_SGR = "\x1B[0m";
|
|
499
|
+
var DEC_SPECIAL_GRAPHICS = {
|
|
500
|
+
j: "\u2518",
|
|
501
|
+
k: "\u2510",
|
|
502
|
+
l: "\u250C",
|
|
503
|
+
m: "\u2514",
|
|
504
|
+
n: "\u253C",
|
|
505
|
+
q: "\u2500",
|
|
506
|
+
t: "\u251C",
|
|
507
|
+
u: "\u2524",
|
|
508
|
+
v: "\u2534",
|
|
509
|
+
w: "\u252C",
|
|
510
|
+
x: "\u2502"
|
|
511
|
+
};
|
|
451
512
|
var TerminalBuffer = class {
|
|
452
513
|
_cols;
|
|
453
514
|
_rows;
|
|
454
515
|
_screen;
|
|
516
|
+
_primaryScreen = null;
|
|
455
517
|
_cursorX = 0;
|
|
456
518
|
_cursorY = 0;
|
|
457
|
-
_savedCursor
|
|
519
|
+
_savedCursor;
|
|
458
520
|
_scrollTop = 0;
|
|
459
521
|
_scrollBottom;
|
|
460
522
|
_state = 0 /* Normal */;
|
|
461
523
|
_csiParams = "";
|
|
462
524
|
_csiPrivate = "";
|
|
463
525
|
_autoWrap = true;
|
|
526
|
+
_pendingWrap = false;
|
|
527
|
+
_originMode = false;
|
|
528
|
+
_insertMode = false;
|
|
529
|
+
_tabStops;
|
|
530
|
+
_lastPrintedChar = null;
|
|
464
531
|
_style = createDefaultStyleState();
|
|
465
532
|
_styleSequence = "";
|
|
533
|
+
_stringState = 0 /* Normal */;
|
|
534
|
+
_charsetTarget = null;
|
|
535
|
+
_g0Charset = "ascii";
|
|
536
|
+
_g1Charset = "ascii";
|
|
537
|
+
_shiftOut = false;
|
|
466
538
|
displayBuffer;
|
|
467
539
|
constructor(cols, rows) {
|
|
468
540
|
this._cols = cols;
|
|
469
541
|
this._rows = rows;
|
|
470
542
|
this._scrollBottom = rows - 1;
|
|
471
543
|
this._screen = this._makeScreen(cols, rows);
|
|
544
|
+
this._tabStops = this._createDefaultTabStops(cols);
|
|
545
|
+
this._savedCursor = this._createSavedCursorState();
|
|
472
546
|
this.displayBuffer = Object.defineProperties(
|
|
473
547
|
{},
|
|
474
548
|
{
|
|
@@ -524,8 +598,12 @@ var TerminalBuffer = class {
|
|
|
524
598
|
}
|
|
525
599
|
this._cols = cols;
|
|
526
600
|
this._rows = rows;
|
|
527
|
-
this._scrollTop = 0;
|
|
528
|
-
this._scrollBottom = rows - 1;
|
|
601
|
+
this._scrollTop = this._clamp(this._scrollTop, 0, rows - 1);
|
|
602
|
+
this._scrollBottom = this._clamp(this._scrollBottom, 0, rows - 1);
|
|
603
|
+
if (this._scrollTop >= this._scrollBottom) {
|
|
604
|
+
this._scrollTop = 0;
|
|
605
|
+
this._scrollBottom = rows - 1;
|
|
606
|
+
}
|
|
529
607
|
this._cursorX = this._clamp(this._cursorX, 0, cols - 1);
|
|
530
608
|
this._cursorY = this._clamp(this._cursorY, 0, rows - 1);
|
|
531
609
|
}
|
|
@@ -535,13 +613,96 @@ var TerminalBuffer = class {
|
|
|
535
613
|
_makeRow(cols) {
|
|
536
614
|
return Array(cols).fill(null);
|
|
537
615
|
}
|
|
616
|
+
_createDefaultTabStops(cols) {
|
|
617
|
+
const tabStops = /* @__PURE__ */ new Set();
|
|
618
|
+
for (let column = 8; column < cols; column += 8) {
|
|
619
|
+
tabStops.add(column);
|
|
620
|
+
}
|
|
621
|
+
return tabStops;
|
|
622
|
+
}
|
|
538
623
|
_clamp(value, min, max) {
|
|
539
624
|
return Math.max(min, Math.min(max, value));
|
|
540
625
|
}
|
|
626
|
+
_createSavedCursorState() {
|
|
627
|
+
return {
|
|
628
|
+
x: this._cursorX,
|
|
629
|
+
y: this._cursorY,
|
|
630
|
+
autoWrap: this._autoWrap,
|
|
631
|
+
style: { ...this._style, fg: this._style.fg?.slice(), bg: this._style.bg?.slice() },
|
|
632
|
+
styleSequence: this._styleSequence
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
_saveCursor() {
|
|
636
|
+
this._savedCursor = this._createSavedCursorState();
|
|
637
|
+
}
|
|
638
|
+
_restoreCursor() {
|
|
639
|
+
this._cursorX = this._clamp(this._savedCursor.x, 0, this._cols - 1);
|
|
640
|
+
this._cursorY = this._clamp(this._savedCursor.y, 0, this._rows - 1);
|
|
641
|
+
this._autoWrap = this._savedCursor.autoWrap;
|
|
642
|
+
this._style = {
|
|
643
|
+
...this._savedCursor.style,
|
|
644
|
+
fg: this._savedCursor.style.fg?.slice(),
|
|
645
|
+
bg: this._savedCursor.style.bg?.slice()
|
|
646
|
+
};
|
|
647
|
+
this._styleSequence = this._savedCursor.styleSequence;
|
|
648
|
+
}
|
|
649
|
+
_resetModes() {
|
|
650
|
+
this._autoWrap = true;
|
|
651
|
+
this._originMode = false;
|
|
652
|
+
this._insertMode = false;
|
|
653
|
+
this._pendingWrap = false;
|
|
654
|
+
this._tabStops = this._createDefaultTabStops(this._cols);
|
|
655
|
+
this._g0Charset = "ascii";
|
|
656
|
+
this._g1Charset = "ascii";
|
|
657
|
+
this._shiftOut = false;
|
|
658
|
+
this._resetStyle();
|
|
659
|
+
}
|
|
660
|
+
_writePrintable(ch) {
|
|
661
|
+
const width = this._cellWidth(ch);
|
|
662
|
+
if (this._autoWrap && this._pendingWrap) {
|
|
663
|
+
this._cursorX = 0;
|
|
664
|
+
this._newline();
|
|
665
|
+
} else if (this._autoWrap && this._cursorX + width > this._cols) {
|
|
666
|
+
this._cursorX = 0;
|
|
667
|
+
this._newline();
|
|
668
|
+
}
|
|
669
|
+
if (this._insertMode) {
|
|
670
|
+
const row = this._screen[this._cursorY];
|
|
671
|
+
if (row) {
|
|
672
|
+
row.splice(this._cursorX, 0, ...Array(width).fill(null));
|
|
673
|
+
row.splice(this._cols);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
this._setChar(this._cursorY, this._cursorX, ch);
|
|
677
|
+
for (let column = 1; column < width && this._cursorX + column < this._cols; column += 1) {
|
|
678
|
+
const row = this._screen[this._cursorY];
|
|
679
|
+
if (row) row[this._cursorX + column] = null;
|
|
680
|
+
}
|
|
681
|
+
this._lastPrintedChar = ch;
|
|
682
|
+
if (!this._autoWrap) {
|
|
683
|
+
this._cursorX = Math.min(this._cursorX + width, this._cols - 1);
|
|
684
|
+
this._pendingWrap = false;
|
|
685
|
+
} else if (this._cursorX + width >= this._cols) {
|
|
686
|
+
this._cursorX = this._cols - 1;
|
|
687
|
+
this._pendingWrap = true;
|
|
688
|
+
} else {
|
|
689
|
+
this._cursorX += width;
|
|
690
|
+
this._pendingWrap = false;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
_cellWidth(ch) {
|
|
694
|
+
const codePoint = ch.codePointAt(0);
|
|
695
|
+
if (codePoint === void 0) return 0;
|
|
696
|
+
if (codePoint >= 4352 && codePoint <= 4447 || codePoint === 9001 || codePoint === 9002 || codePoint >= 11904 && codePoint <= 12350 || codePoint >= 12353 && codePoint <= 13247 || codePoint >= 13312 && codePoint <= 19903 || codePoint >= 19968 && codePoint <= 42191 || codePoint >= 44032 && codePoint <= 55215 || codePoint >= 63744 && codePoint <= 64255 || codePoint >= 65040 && codePoint <= 65049 || codePoint >= 65072 && codePoint <= 65135 || codePoint >= 65280 && codePoint <= 65376 || codePoint >= 65504 && codePoint <= 65510 || codePoint >= 127488 && codePoint <= 131069 || codePoint >= 131072 && codePoint <= 262141) {
|
|
697
|
+
return Math.min(2, this._cols);
|
|
698
|
+
}
|
|
699
|
+
return 1;
|
|
700
|
+
}
|
|
541
701
|
_setChar(y, x, ch) {
|
|
542
702
|
const row = this._screen[y];
|
|
543
703
|
if (row && x >= 0 && x < this._cols) {
|
|
544
|
-
const
|
|
704
|
+
const renderedChar = this._style.conceal ? " " : ch;
|
|
705
|
+
const cell = [renderedChar.charCodeAt(0), renderedChar];
|
|
545
706
|
if (this._styleSequence.length > 0) {
|
|
546
707
|
Object.defineProperty(cell, "style", {
|
|
547
708
|
value: this._styleSequence,
|
|
@@ -572,6 +733,7 @@ var TerminalBuffer = class {
|
|
|
572
733
|
}
|
|
573
734
|
}
|
|
574
735
|
_newline() {
|
|
736
|
+
this._pendingWrap = false;
|
|
575
737
|
if (this._cursorY === this._scrollBottom) {
|
|
576
738
|
this._scrollUp(1);
|
|
577
739
|
} else {
|
|
@@ -580,7 +742,11 @@ var TerminalBuffer = class {
|
|
|
580
742
|
}
|
|
581
743
|
_parseCsiParams() {
|
|
582
744
|
if (!this._csiParams) return [];
|
|
583
|
-
|
|
745
|
+
const values = this._csiParams.split(";").flatMap((segment) => segment.split(":")).map((segment) => segment === "" ? 0 : parseInt(segment, 10));
|
|
746
|
+
if ((values[0] === 38 || values[0] === 48) && values[1] === 2 && values[2] === 0) {
|
|
747
|
+
values.splice(2, 1);
|
|
748
|
+
}
|
|
749
|
+
return values;
|
|
584
750
|
}
|
|
585
751
|
_execCsi(final) {
|
|
586
752
|
const params2 = this._parseCsiParams();
|
|
@@ -591,21 +757,45 @@ var TerminalBuffer = class {
|
|
|
591
757
|
if (params2.includes(7)) {
|
|
592
758
|
this._autoWrap = final === "h";
|
|
593
759
|
}
|
|
760
|
+
if (params2.includes(6)) {
|
|
761
|
+
this._originMode = final === "h";
|
|
762
|
+
this._cursorX = 0;
|
|
763
|
+
this._cursorY = this._originMode ? this._scrollTop : 0;
|
|
764
|
+
}
|
|
594
765
|
if (params2.includes(1049)) {
|
|
595
766
|
if (final === "h") {
|
|
767
|
+
this._primaryScreen = {
|
|
768
|
+
screen: this._screen,
|
|
769
|
+
cursorX: this._cursorX,
|
|
770
|
+
cursorY: this._cursorY,
|
|
771
|
+
pendingWrap: this._pendingWrap,
|
|
772
|
+
style: { ...this._style, fg: this._style.fg?.slice(), bg: this._style.bg?.slice() },
|
|
773
|
+
styleSequence: this._styleSequence
|
|
774
|
+
};
|
|
596
775
|
this._screen = this._makeScreen(this._cols, this._rows);
|
|
597
776
|
this._cursorX = 0;
|
|
598
777
|
this._cursorY = 0;
|
|
778
|
+
this._pendingWrap = false;
|
|
599
779
|
} else {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
780
|
+
if (this._primaryScreen !== null) {
|
|
781
|
+
this._screen = this._primaryScreen.screen;
|
|
782
|
+
this._cursorX = this._primaryScreen.cursorX;
|
|
783
|
+
this._cursorY = this._primaryScreen.cursorY;
|
|
784
|
+
this._pendingWrap = this._primaryScreen.pendingWrap;
|
|
785
|
+
this._style = this._primaryScreen.style;
|
|
786
|
+
this._styleSequence = this._primaryScreen.styleSequence;
|
|
787
|
+
this._primaryScreen = null;
|
|
788
|
+
}
|
|
603
789
|
}
|
|
604
|
-
this._resetStyle();
|
|
790
|
+
if (final === "h") this._resetStyle();
|
|
605
791
|
}
|
|
606
792
|
}
|
|
607
793
|
return;
|
|
608
794
|
}
|
|
795
|
+
if ((final === "h" || final === "l") && params2.includes(4)) {
|
|
796
|
+
this._insertMode = final === "h";
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
609
799
|
switch (final) {
|
|
610
800
|
case "A":
|
|
611
801
|
this._cursorY = this._clamp(this._cursorY - Math.max(1, p0), 0, this._rows - 1);
|
|
@@ -637,7 +827,7 @@ var TerminalBuffer = class {
|
|
|
637
827
|
case "H":
|
|
638
828
|
// cursor position
|
|
639
829
|
case "f":
|
|
640
|
-
this._cursorY = this._clamp(Math.max(1, p0) - 1, 0, this._rows - 1);
|
|
830
|
+
this._cursorY = this._originMode ? this._clamp(this._scrollTop + Math.max(1, p0) - 1, this._scrollTop, this._scrollBottom) : this._clamp(Math.max(1, p0) - 1, 0, this._rows - 1);
|
|
641
831
|
this._cursorX = this._clamp(Math.max(1, p1) - 1, 0, this._cols - 1);
|
|
642
832
|
break;
|
|
643
833
|
case "I":
|
|
@@ -652,7 +842,7 @@ var TerminalBuffer = class {
|
|
|
652
842
|
} else if (p0 === 1) {
|
|
653
843
|
for (let y = 0; y < this._cursorY; y++) this._eraseLine(y, 0, this._cols - 1);
|
|
654
844
|
this._eraseLine(this._cursorY, 0, this._cursorX);
|
|
655
|
-
} else if (p0 === 2
|
|
845
|
+
} else if (p0 === 2) {
|
|
656
846
|
for (let y = 0; y < this._rows; y++) this._eraseLine(y, 0, this._cols - 1);
|
|
657
847
|
}
|
|
658
848
|
break;
|
|
@@ -665,6 +855,9 @@ var TerminalBuffer = class {
|
|
|
665
855
|
this._eraseLine(this._cursorY, this._cursorX, this._cursorX + Math.max(1, p0) - 1);
|
|
666
856
|
break;
|
|
667
857
|
case "L": {
|
|
858
|
+
if (this._cursorY < this._scrollTop || this._cursorY > this._scrollBottom) {
|
|
859
|
+
break;
|
|
860
|
+
}
|
|
668
861
|
const n = Math.max(1, p0);
|
|
669
862
|
for (let i = 0; i < n; i++) {
|
|
670
863
|
this._screen.splice(this._scrollBottom, 1);
|
|
@@ -673,6 +866,9 @@ var TerminalBuffer = class {
|
|
|
673
866
|
break;
|
|
674
867
|
}
|
|
675
868
|
case "M": {
|
|
869
|
+
if (this._cursorY < this._scrollTop || this._cursorY > this._scrollBottom) {
|
|
870
|
+
break;
|
|
871
|
+
}
|
|
676
872
|
const n = Math.max(1, p0);
|
|
677
873
|
for (let i = 0; i < n; i++) {
|
|
678
874
|
this._screen.splice(this._cursorY, 1);
|
|
@@ -711,6 +907,13 @@ var TerminalBuffer = class {
|
|
|
711
907
|
}
|
|
712
908
|
break;
|
|
713
909
|
}
|
|
910
|
+
case "b":
|
|
911
|
+
if (this._lastPrintedChar !== null) {
|
|
912
|
+
for (let index = 0; index < Math.max(1, p0); index += 1) {
|
|
913
|
+
this._writePrintable(this._lastPrintedChar);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
break;
|
|
714
917
|
case "d":
|
|
715
918
|
this._cursorY = this._clamp(Math.max(1, p0) - 1, 0, this._rows - 1);
|
|
716
919
|
break;
|
|
@@ -725,15 +928,19 @@ var TerminalBuffer = class {
|
|
|
725
928
|
this._scrollBottom = bottom;
|
|
726
929
|
}
|
|
727
930
|
this._cursorX = 0;
|
|
728
|
-
this._cursorY = 0;
|
|
931
|
+
this._cursorY = this._originMode ? this._scrollTop : 0;
|
|
729
932
|
break;
|
|
730
933
|
}
|
|
731
934
|
case "s":
|
|
732
|
-
this.
|
|
935
|
+
this._saveCursor();
|
|
733
936
|
break;
|
|
734
937
|
case "u":
|
|
735
|
-
this.
|
|
736
|
-
|
|
938
|
+
this._restoreCursor();
|
|
939
|
+
break;
|
|
940
|
+
case "p":
|
|
941
|
+
if (this._csiPrivate === "!") {
|
|
942
|
+
this._resetModes();
|
|
943
|
+
}
|
|
737
944
|
break;
|
|
738
945
|
case "m":
|
|
739
946
|
this._applySgr(params2);
|
|
@@ -744,6 +951,14 @@ var TerminalBuffer = class {
|
|
|
744
951
|
}
|
|
745
952
|
_feed(ch) {
|
|
746
953
|
const code = ch.charCodeAt(0);
|
|
954
|
+
if (this._state !== 0 /* Normal */ && (code === 24 || code === 26)) {
|
|
955
|
+
this._state = 0 /* Normal */;
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
if (this._state === 2 /* Csi */ && code === 27) {
|
|
959
|
+
this._state = 1 /* Escape */;
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
747
962
|
switch (this._state) {
|
|
748
963
|
case 0 /* Normal */:
|
|
749
964
|
this._feedNormal(ch, code);
|
|
@@ -758,20 +973,37 @@ var TerminalBuffer = class {
|
|
|
758
973
|
if (code === 7 || code === 156) {
|
|
759
974
|
this._state = 0 /* Normal */;
|
|
760
975
|
} else if (code === 27) {
|
|
761
|
-
this.
|
|
976
|
+
this._stringState = 3 /* Osc */;
|
|
977
|
+
this._state = 5 /* StringEscape */;
|
|
762
978
|
}
|
|
763
979
|
break;
|
|
764
980
|
case 4 /* Str */:
|
|
765
|
-
if (code === 156
|
|
981
|
+
if (code === 156) {
|
|
766
982
|
this._state = 0 /* Normal */;
|
|
767
983
|
} else if (code === 27) {
|
|
768
|
-
this.
|
|
984
|
+
this._stringState = 4 /* Str */;
|
|
985
|
+
this._state = 5 /* StringEscape */;
|
|
769
986
|
}
|
|
770
987
|
break;
|
|
771
|
-
case 5 /*
|
|
988
|
+
case 5 /* StringEscape */:
|
|
989
|
+
this._state = ch === "\\" ? 0 /* Normal */ : this._stringState;
|
|
990
|
+
break;
|
|
991
|
+
case 6 /* EscCharset */:
|
|
992
|
+
if (this._charsetTarget === "g0") this._g0Charset = ch === "0" ? "graphics" : "ascii";
|
|
993
|
+
if (this._charsetTarget === "g1") this._g1Charset = ch === "0" ? "graphics" : "ascii";
|
|
994
|
+
this._charsetTarget = null;
|
|
772
995
|
this._state = 0 /* Normal */;
|
|
773
996
|
break;
|
|
774
|
-
case
|
|
997
|
+
case 7 /* EscHash */:
|
|
998
|
+
if (ch === "8") {
|
|
999
|
+
for (let row = 0; row < this._rows; row += 1) {
|
|
1000
|
+
for (let column = 0; column < this._cols; column += 1) {
|
|
1001
|
+
this._setChar(row, column, "E");
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
this._cursorX = 0;
|
|
1005
|
+
this._cursorY = 0;
|
|
1006
|
+
}
|
|
775
1007
|
this._state = 0 /* Normal */;
|
|
776
1008
|
break;
|
|
777
1009
|
}
|
|
@@ -787,32 +1019,28 @@ var TerminalBuffer = class {
|
|
|
787
1019
|
this._state = 3 /* Osc */;
|
|
788
1020
|
} else if (code === 144 || code === 152 || code === 158 || code === 159) {
|
|
789
1021
|
this._state = 4 /* Str */;
|
|
1022
|
+
} else if (code === 133) {
|
|
1023
|
+
this._cursorX = 0;
|
|
1024
|
+
this._newline();
|
|
1025
|
+
} else if (code === 156) {
|
|
790
1026
|
} else if (code === 7 || code === 5 || code === 6) {
|
|
791
1027
|
} else if (code === 8) {
|
|
1028
|
+
this._pendingWrap = false;
|
|
792
1029
|
if (this._cursorX > 0) this._cursorX--;
|
|
793
1030
|
} else if (code === 127) {
|
|
794
|
-
if (this._cursorX > 0) {
|
|
795
|
-
this._cursorX--;
|
|
796
|
-
this._setChar(this._cursorY, this._cursorX, " ");
|
|
797
|
-
}
|
|
798
1031
|
} else if (code === 9) {
|
|
799
|
-
|
|
1032
|
+
const nextTabStop = [...this._tabStops].sort((left, right) => left - right).find((tabStop) => tabStop > this._cursorX);
|
|
1033
|
+
this._cursorX = nextTabStop ?? this._cols - 1;
|
|
800
1034
|
} else if (code === 10 || code === 11 || code === 12) {
|
|
801
1035
|
this._newline();
|
|
802
1036
|
} else if (code === 13) {
|
|
1037
|
+
this._pendingWrap = false;
|
|
803
1038
|
this._cursorX = 0;
|
|
804
1039
|
} else if (code === 14 || code === 15) {
|
|
1040
|
+
this._shiftOut = code === 14;
|
|
805
1041
|
} else if (code >= 32 && code !== 127) {
|
|
806
|
-
this.
|
|
807
|
-
this.
|
|
808
|
-
if (!this._autoWrap) {
|
|
809
|
-
this._cursorX = Math.min(this._cursorX, this._cols - 1);
|
|
810
|
-
return;
|
|
811
|
-
}
|
|
812
|
-
if (this._cursorX >= this._cols) {
|
|
813
|
-
this._cursorX = 0;
|
|
814
|
-
this._newline();
|
|
815
|
-
}
|
|
1042
|
+
const charset = this._shiftOut ? this._g1Charset : this._g0Charset;
|
|
1043
|
+
this._writePrintable(charset === "graphics" ? DEC_SPECIAL_GRAPHICS[ch] ?? ch : ch);
|
|
816
1044
|
}
|
|
817
1045
|
}
|
|
818
1046
|
_feedEscape(ch, code) {
|
|
@@ -826,14 +1054,14 @@ var TerminalBuffer = class {
|
|
|
826
1054
|
} else if (code === 80 || code === 88 || code === 94 || code === 95) {
|
|
827
1055
|
this._state = 4 /* Str */;
|
|
828
1056
|
} else if (code === 40 || code === 41 || code === 42 || code === 43 || code === 45 || code === 46) {
|
|
829
|
-
this.
|
|
1057
|
+
this._charsetTarget = code === 40 ? "g0" : code === 41 ? "g1" : null;
|
|
1058
|
+
this._state = 6 /* EscCharset */;
|
|
830
1059
|
} else if (code === 35) {
|
|
831
|
-
this._state =
|
|
1060
|
+
this._state = 7 /* EscHash */;
|
|
832
1061
|
} else if (code === 55) {
|
|
833
|
-
this.
|
|
1062
|
+
this._saveCursor();
|
|
834
1063
|
} else if (code === 56) {
|
|
835
|
-
this.
|
|
836
|
-
this._cursorY = this._clamp(this._savedCursor.y, 0, this._rows - 1);
|
|
1064
|
+
this._restoreCursor();
|
|
837
1065
|
} else if (code === 68) {
|
|
838
1066
|
this._newline();
|
|
839
1067
|
} else if (code === 69) {
|
|
@@ -846,14 +1074,15 @@ var TerminalBuffer = class {
|
|
|
846
1074
|
this._cursorY = Math.max(0, this._cursorY - 1);
|
|
847
1075
|
}
|
|
848
1076
|
} else if (code === 72) {
|
|
1077
|
+
this._tabStops.add(this._cursorX);
|
|
849
1078
|
} else if (code === 99) {
|
|
850
1079
|
this._screen = this._makeScreen(this._cols, this._rows);
|
|
851
1080
|
this._cursorX = 0;
|
|
852
1081
|
this._cursorY = 0;
|
|
853
|
-
this._savedCursor = { x: 0, y: 0 };
|
|
854
1082
|
this._scrollTop = 0;
|
|
855
1083
|
this._scrollBottom = this._rows - 1;
|
|
856
|
-
this.
|
|
1084
|
+
this._resetModes();
|
|
1085
|
+
this._savedCursor = this._createSavedCursorState();
|
|
857
1086
|
}
|
|
858
1087
|
}
|
|
859
1088
|
_feedCsi(ch, code) {
|
|
@@ -862,7 +1091,7 @@ var TerminalBuffer = class {
|
|
|
862
1091
|
this._state = 0 /* Normal */;
|
|
863
1092
|
} else if (code === 63 || code === 33 || code === 62 || code === 32) {
|
|
864
1093
|
this._csiPrivate = ch;
|
|
865
|
-
} else if (code >= 48 && code <= 57 || code === 59) {
|
|
1094
|
+
} else if (code >= 48 && code <= 57 || code === 59 || code === 58) {
|
|
866
1095
|
this._csiParams += ch;
|
|
867
1096
|
}
|
|
868
1097
|
}
|
|
@@ -893,6 +1122,9 @@ var TerminalBuffer = class {
|
|
|
893
1122
|
case 7:
|
|
894
1123
|
this._style.inverse = true;
|
|
895
1124
|
break;
|
|
1125
|
+
case 8:
|
|
1126
|
+
this._style.conceal = true;
|
|
1127
|
+
break;
|
|
896
1128
|
case 9:
|
|
897
1129
|
this._style.strikethrough = true;
|
|
898
1130
|
break;
|
|
@@ -910,6 +1142,9 @@ var TerminalBuffer = class {
|
|
|
910
1142
|
case 27:
|
|
911
1143
|
this._style.inverse = false;
|
|
912
1144
|
break;
|
|
1145
|
+
case 28:
|
|
1146
|
+
this._style.conceal = false;
|
|
1147
|
+
break;
|
|
913
1148
|
case 29:
|
|
914
1149
|
this._style.strikethrough = false;
|
|
915
1150
|
break;
|
|
@@ -964,6 +1199,7 @@ function createDefaultStyleState() {
|
|
|
964
1199
|
italic: false,
|
|
965
1200
|
underline: false,
|
|
966
1201
|
inverse: false,
|
|
1202
|
+
conceal: false,
|
|
967
1203
|
strikethrough: false
|
|
968
1204
|
};
|
|
969
1205
|
}
|
|
@@ -984,6 +1220,9 @@ function serializeStyleState(state) {
|
|
|
984
1220
|
if (state.inverse) {
|
|
985
1221
|
codes.push(7);
|
|
986
1222
|
}
|
|
1223
|
+
if (state.conceal) {
|
|
1224
|
+
codes.push(8);
|
|
1225
|
+
}
|
|
987
1226
|
if (state.strikethrough) {
|
|
988
1227
|
codes.push(9);
|
|
989
1228
|
}
|
|
@@ -1102,6 +1341,7 @@ var WAIT_FOR_POLL_MS = 10;
|
|
|
1102
1341
|
var TYPE_DELAY_MS = 15;
|
|
1103
1342
|
var CLOSE_AFTER_SIGNAL_GRACE_MS = 250;
|
|
1104
1343
|
var CLOSE_AFTER_SIGTERM_MS = 1e3;
|
|
1344
|
+
var CLOSE_AFTER_SIGKILL_MS = 1e3;
|
|
1105
1345
|
var TerminalSession = class {
|
|
1106
1346
|
id;
|
|
1107
1347
|
command;
|
|
@@ -1115,8 +1355,7 @@ var TerminalSession = class {
|
|
|
1115
1355
|
lastDataAt = Date.now();
|
|
1116
1356
|
currentCols;
|
|
1117
1357
|
currentRows;
|
|
1118
|
-
|
|
1119
|
-
signalRequested = false;
|
|
1358
|
+
closePromise = null;
|
|
1120
1359
|
constructor({
|
|
1121
1360
|
id,
|
|
1122
1361
|
command,
|
|
@@ -1127,6 +1366,7 @@ var TerminalSession = class {
|
|
|
1127
1366
|
rows = DEFAULT_ROWS,
|
|
1128
1367
|
observe = false
|
|
1129
1368
|
}) {
|
|
1369
|
+
assertTerminalGeometry(cols, rows);
|
|
1130
1370
|
this.id = id;
|
|
1131
1371
|
this.command = command;
|
|
1132
1372
|
this.currentCols = cols;
|
|
@@ -1171,7 +1411,7 @@ var TerminalSession = class {
|
|
|
1171
1411
|
}
|
|
1172
1412
|
async send(raw) {
|
|
1173
1413
|
if (this.exitCode !== null) {
|
|
1174
|
-
|
|
1414
|
+
throw new Error(`Terminal session "${this.id}" has already exited.`);
|
|
1175
1415
|
}
|
|
1176
1416
|
this.pty.write(raw);
|
|
1177
1417
|
}
|
|
@@ -1179,22 +1419,26 @@ var TerminalSession = class {
|
|
|
1179
1419
|
if (this.exitCode !== null) {
|
|
1180
1420
|
return;
|
|
1181
1421
|
}
|
|
1182
|
-
this.signalRequested = true;
|
|
1183
1422
|
this.pty.kill(sig);
|
|
1184
1423
|
}
|
|
1185
1424
|
async waitFor(pattern, opts) {
|
|
1186
1425
|
const timeout = opts?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
1426
|
+
assertTimeout(timeout);
|
|
1187
1427
|
const startedAt = Date.now();
|
|
1188
1428
|
while (Date.now() - startedAt <= timeout) {
|
|
1189
1429
|
const matched = matchPattern(this.rawBuffer, pattern);
|
|
1190
1430
|
if (matched !== null) {
|
|
1191
1431
|
return matched;
|
|
1192
1432
|
}
|
|
1433
|
+
if (this.exitCode !== null) {
|
|
1434
|
+
throw new Error(`Terminal session "${this.id}" exited before matching pattern: ${String(pattern)}`);
|
|
1435
|
+
}
|
|
1193
1436
|
await sleep(WAIT_FOR_POLL_MS);
|
|
1194
1437
|
}
|
|
1195
1438
|
throw new Error(`Timed out waiting for pattern after ${timeout}ms: ${String(pattern)}`);
|
|
1196
1439
|
}
|
|
1197
1440
|
async waitForQuiet(ms) {
|
|
1441
|
+
assertQuietPeriod(ms);
|
|
1198
1442
|
while (true) {
|
|
1199
1443
|
const remaining = ms - (Date.now() - this.lastDataAt);
|
|
1200
1444
|
if (remaining <= 0) {
|
|
@@ -1227,10 +1471,14 @@ var TerminalSession = class {
|
|
|
1227
1471
|
if (opts?.last === void 0) {
|
|
1228
1472
|
return lines;
|
|
1229
1473
|
}
|
|
1474
|
+
if (!Number.isInteger(opts.last) || opts.last < 0) {
|
|
1475
|
+
throw new Error("History last must be a non-negative integer.");
|
|
1476
|
+
}
|
|
1230
1477
|
const start = Math.max(0, lines.length - opts.last);
|
|
1231
1478
|
return lines.slice(start);
|
|
1232
1479
|
}
|
|
1233
1480
|
async resize(cols, rows) {
|
|
1481
|
+
assertTerminalGeometry(cols, rows);
|
|
1234
1482
|
this.currentCols = cols;
|
|
1235
1483
|
this.currentRows = rows;
|
|
1236
1484
|
if (this.exitCode === null) {
|
|
@@ -1239,6 +1487,9 @@ var TerminalSession = class {
|
|
|
1239
1487
|
this.terminal.resize(cols, rows);
|
|
1240
1488
|
}
|
|
1241
1489
|
async waitForExit(opts) {
|
|
1490
|
+
if (opts?.timeout !== void 0) {
|
|
1491
|
+
assertTimeout(opts.timeout);
|
|
1492
|
+
}
|
|
1242
1493
|
if (this.exitCode !== null) {
|
|
1243
1494
|
return this.exitCode;
|
|
1244
1495
|
}
|
|
@@ -1255,32 +1506,52 @@ var TerminalSession = class {
|
|
|
1255
1506
|
if (this.exitCode !== null) {
|
|
1256
1507
|
return this.exitCode;
|
|
1257
1508
|
}
|
|
1258
|
-
|
|
1259
|
-
this.
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1509
|
+
this.closePromise ??= this.closeProcess().catch((error) => {
|
|
1510
|
+
this.closePromise = null;
|
|
1511
|
+
throw error;
|
|
1512
|
+
});
|
|
1513
|
+
return this.closePromise;
|
|
1514
|
+
}
|
|
1515
|
+
async closeProcess() {
|
|
1516
|
+
const gracefulExitCode = await waitForExit(this.exitPromise, CLOSE_AFTER_SIGNAL_GRACE_MS);
|
|
1517
|
+
if (gracefulExitCode !== null) {
|
|
1518
|
+
return gracefulExitCode;
|
|
1519
|
+
}
|
|
1520
|
+
if (this.exitCode === null) {
|
|
1521
|
+
this.pty.kill("SIGTERM");
|
|
1522
|
+
const afterSigterm = await waitForExit(this.exitPromise, CLOSE_AFTER_SIGTERM_MS);
|
|
1523
|
+
if (afterSigterm !== null) {
|
|
1524
|
+
return afterSigterm;
|
|
1273
1525
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1526
|
+
}
|
|
1527
|
+
if (this.exitCode === null) {
|
|
1528
|
+
this.pty.kill("SIGKILL");
|
|
1529
|
+
const afterSigkill = await waitForExit(this.exitPromise, CLOSE_AFTER_SIGKILL_MS);
|
|
1530
|
+
if (afterSigkill !== null) {
|
|
1531
|
+
return afterSigkill;
|
|
1276
1532
|
}
|
|
1277
1533
|
}
|
|
1278
|
-
|
|
1534
|
+
throw new Error("Timed out waiting for process to exit after SIGKILL.");
|
|
1279
1535
|
}
|
|
1280
1536
|
on(event, cb) {
|
|
1281
1537
|
this.emitter.on(event, cb);
|
|
1282
1538
|
}
|
|
1283
1539
|
};
|
|
1540
|
+
function assertTerminalGeometry(cols, rows) {
|
|
1541
|
+
if (!Number.isInteger(cols) || cols <= 0 || !Number.isInteger(rows) || rows <= 0) {
|
|
1542
|
+
throw new Error("Terminal columns and rows must be positive integers.");
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
function assertTimeout(timeout) {
|
|
1546
|
+
if (!Number.isFinite(timeout) || timeout < 0) {
|
|
1547
|
+
throw new Error("Timeout must be a finite non-negative number.");
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
function assertQuietPeriod(duration) {
|
|
1551
|
+
if (!Number.isFinite(duration) || duration < 0) {
|
|
1552
|
+
throw new Error("Quiet period must be a finite non-negative number.");
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1284
1555
|
function createPtyProcess({
|
|
1285
1556
|
command,
|
|
1286
1557
|
args,
|
|
@@ -1357,13 +1628,28 @@ function splitHistoryLines(input) {
|
|
|
1357
1628
|
}
|
|
1358
1629
|
function normalizeHistoryBuffer(input) {
|
|
1359
1630
|
let output = "";
|
|
1631
|
+
let line = "";
|
|
1632
|
+
let cursor = 0;
|
|
1360
1633
|
for (const character of input) {
|
|
1361
|
-
if (character === "\r"
|
|
1634
|
+
if (character === "\r") {
|
|
1635
|
+
cursor = 0;
|
|
1636
|
+
continue;
|
|
1637
|
+
}
|
|
1638
|
+
if (character === "\b") {
|
|
1639
|
+
cursor = Math.max(0, cursor - 1);
|
|
1362
1640
|
continue;
|
|
1363
1641
|
}
|
|
1364
|
-
|
|
1642
|
+
if (character === "\n") {
|
|
1643
|
+
output += `${line}
|
|
1644
|
+
`;
|
|
1645
|
+
line = "";
|
|
1646
|
+
cursor = 0;
|
|
1647
|
+
continue;
|
|
1648
|
+
}
|
|
1649
|
+
line = `${line.slice(0, cursor)}${character}${line.slice(cursor + 1)}`;
|
|
1650
|
+
cursor += 1;
|
|
1365
1651
|
}
|
|
1366
|
-
return output;
|
|
1652
|
+
return output + line;
|
|
1367
1653
|
}
|
|
1368
1654
|
function sleep(ms) {
|
|
1369
1655
|
return new Promise((resolve) => {
|
|
@@ -1428,11 +1714,12 @@ var TerminalPilot = class _TerminalPilot {
|
|
|
1428
1714
|
}
|
|
1429
1715
|
async close() {
|
|
1430
1716
|
const sessions = [...this.sessionMap.values()];
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1717
|
+
await Promise.all(
|
|
1718
|
+
sessions.map(async (session) => {
|
|
1719
|
+
await session.close();
|
|
1720
|
+
this.sessionMap.delete(session.id);
|
|
1721
|
+
})
|
|
1722
|
+
);
|
|
1436
1723
|
}
|
|
1437
1724
|
};
|
|
1438
1725
|
|
|
@@ -1450,6 +1737,7 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1450
1737
|
const launchPilot = options.launchPilot ?? TerminalPilot.launch;
|
|
1451
1738
|
const nameToId = /* @__PURE__ */ new Map();
|
|
1452
1739
|
const idToName = /* @__PURE__ */ new Map();
|
|
1740
|
+
const pendingNames = /* @__PURE__ */ new Set();
|
|
1453
1741
|
let pilotPromise;
|
|
1454
1742
|
function getRequestedName(name, env) {
|
|
1455
1743
|
return name ?? env?.get(SESSION_ENV_VAR);
|
|
@@ -1460,7 +1748,7 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1460
1748
|
}
|
|
1461
1749
|
function nextSessionName() {
|
|
1462
1750
|
let index = 1;
|
|
1463
|
-
while (nameToId.has(`s${index}`)) {
|
|
1751
|
+
while (nameToId.has(`s${index}`) || pendingNames.has(`s${index}`)) {
|
|
1464
1752
|
index += 1;
|
|
1465
1753
|
}
|
|
1466
1754
|
return `s${index}`;
|
|
@@ -1471,8 +1759,12 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1471
1759
|
return { name, session };
|
|
1472
1760
|
}
|
|
1473
1761
|
function forgetSession(name, sessionId) {
|
|
1474
|
-
nameToId.
|
|
1475
|
-
|
|
1762
|
+
if (nameToId.get(name) === sessionId) {
|
|
1763
|
+
nameToId.delete(name);
|
|
1764
|
+
}
|
|
1765
|
+
if (idToName.get(sessionId) === name) {
|
|
1766
|
+
idToName.delete(sessionId);
|
|
1767
|
+
}
|
|
1476
1768
|
}
|
|
1477
1769
|
function formatAvailableSessions(names) {
|
|
1478
1770
|
if (names.length === 0) {
|
|
@@ -1505,22 +1797,44 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1505
1797
|
return [{ name, session }];
|
|
1506
1798
|
});
|
|
1507
1799
|
}
|
|
1800
|
+
async function discardExitedSessionName(name) {
|
|
1801
|
+
const sessionId = nameToId.get(name);
|
|
1802
|
+
if (sessionId === void 0) {
|
|
1803
|
+
return;
|
|
1804
|
+
}
|
|
1805
|
+
const pilot = await getPilot();
|
|
1806
|
+
try {
|
|
1807
|
+
const session = pilot.getSession(sessionId);
|
|
1808
|
+
if (session.exitCode === null) {
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
pilot.deleteSession(sessionId);
|
|
1812
|
+
} catch {
|
|
1813
|
+
}
|
|
1814
|
+
forgetSession(name, sessionId);
|
|
1815
|
+
}
|
|
1508
1816
|
return {
|
|
1509
1817
|
async createSession(params2, env) {
|
|
1510
1818
|
const requestedName = getRequestedName(params2.session, env) ?? nextSessionName();
|
|
1511
|
-
|
|
1819
|
+
await discardExitedSessionName(requestedName);
|
|
1820
|
+
if (nameToId.has(requestedName) || pendingNames.has(requestedName)) {
|
|
1512
1821
|
throw new UserError(`Session "${requestedName}" already exists.`);
|
|
1513
1822
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1823
|
+
pendingNames.add(requestedName);
|
|
1824
|
+
try {
|
|
1825
|
+
const pilot = await getPilot();
|
|
1826
|
+
const session = await pilot.newSession({
|
|
1827
|
+
command: params2.command,
|
|
1828
|
+
args: params2.args,
|
|
1829
|
+
cwd: params2.cwd,
|
|
1830
|
+
cols: params2.cols,
|
|
1831
|
+
rows: params2.rows,
|
|
1832
|
+
observe: params2.observe
|
|
1833
|
+
});
|
|
1834
|
+
return rememberSession(requestedName, session);
|
|
1835
|
+
} finally {
|
|
1836
|
+
pendingNames.delete(requestedName);
|
|
1837
|
+
}
|
|
1524
1838
|
},
|
|
1525
1839
|
async resolveSession(name, env) {
|
|
1526
1840
|
const requestedName = getRequestedName(name, env);
|
|
@@ -1559,6 +1873,7 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1559
1873
|
pilotPromise = void 0;
|
|
1560
1874
|
nameToId.clear();
|
|
1561
1875
|
idToName.clear();
|
|
1876
|
+
pendingNames.clear();
|
|
1562
1877
|
}
|
|
1563
1878
|
};
|
|
1564
1879
|
}
|