terminal-pilot 0.0.27 → 0.0.29
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 +1224 -206
- package/dist/cli.js.map +4 -4
- package/dist/commands/close-session.js +87 -6
- package/dist/commands/close-session.js.map +2 -2
- package/dist/commands/create-session.js +94 -9
- package/dist/commands/create-session.js.map +2 -2
- package/dist/commands/fill.js +87 -6
- package/dist/commands/fill.js.map +2 -2
- package/dist/commands/get-session.js +87 -6
- package/dist/commands/get-session.js.map +2 -2
- package/dist/commands/index.js +482 -118
- package/dist/commands/index.js.map +4 -4
- package/dist/commands/install.js +108 -48
- package/dist/commands/install.js.map +4 -4
- package/dist/commands/installer.js +88 -42
- package/dist/commands/installer.js.map +4 -4
- package/dist/commands/list-sessions.js +80 -4
- package/dist/commands/list-sessions.js.map +2 -2
- package/dist/commands/press-key.js +160 -71
- package/dist/commands/press-key.js.map +3 -3
- package/dist/commands/read-history.js +95 -7
- package/dist/commands/read-history.js.map +2 -2
- package/dist/commands/read-screen.js +87 -6
- package/dist/commands/read-screen.js.map +2 -2
- package/dist/commands/resize.js +89 -8
- package/dist/commands/resize.js.map +2 -2
- package/dist/commands/runtime.js +66 -4
- package/dist/commands/runtime.js.map +2 -2
- package/dist/commands/screenshot.js +242 -23
- package/dist/commands/screenshot.js.map +3 -3
- package/dist/commands/send-signal.js +87 -6
- package/dist/commands/send-signal.js.map +2 -2
- package/dist/commands/type.js +87 -6
- package/dist/commands/type.js.map +2 -2
- package/dist/commands/uninstall.js +102 -42
- package/dist/commands/uninstall.js.map +4 -4
- package/dist/commands/wait-for-exit.js +93 -7
- package/dist/commands/wait-for-exit.js.map +2 -2
- package/dist/commands/wait-for.js +104 -8
- package/dist/commands/wait-for.js.map +3 -3
- package/dist/index.js +52 -1
- package/dist/index.js.map +2 -2
- package/dist/keys.d.ts +1 -0
- package/dist/keys.js +15 -0
- package/dist/keys.js.map +2 -2
- package/dist/terminal-buffer.d.ts +2 -0
- package/dist/terminal-buffer.js +38 -1
- package/dist/terminal-buffer.js.map +2 -2
- package/dist/terminal-pilot.js +52 -1
- package/dist/terminal-pilot.js.map +2 -2
- package/dist/terminal-session.js +52 -1
- package/dist/terminal-session.js.map +2 -2
- package/dist/testing/cli-repl.js +1229 -211
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +1229 -211
- package/dist/testing/qa-cli.js.map +4 -4
- package/package.json +3 -2
|
@@ -249,6 +249,12 @@ function cloneRequires(requires) {
|
|
|
249
249
|
check: requires.check
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
|
+
function cloneCommandExamples(examples) {
|
|
253
|
+
return (examples ?? []).map((example) => ({
|
|
254
|
+
title: example.title,
|
|
255
|
+
params: { ...example.params }
|
|
256
|
+
}));
|
|
257
|
+
}
|
|
252
258
|
function parseStackPath(candidate) {
|
|
253
259
|
if (candidate.startsWith("file://")) {
|
|
254
260
|
try {
|
|
@@ -342,9 +348,11 @@ function createBaseCommand(config) {
|
|
|
342
348
|
kind: "command",
|
|
343
349
|
name: config.name,
|
|
344
350
|
description: config.description,
|
|
351
|
+
examples: cloneCommandExamples(config.examples),
|
|
345
352
|
aliases: [...config.aliases ?? []],
|
|
346
353
|
positional: [...config.positional ?? []],
|
|
347
354
|
params: config.params,
|
|
355
|
+
result: config.result,
|
|
348
356
|
secrets: cloneSecrets(config.secrets),
|
|
349
357
|
scope: resolveCommandScope(config.scope, void 0),
|
|
350
358
|
confirm: config.confirm ?? false,
|
|
@@ -356,6 +364,8 @@ function createBaseCommand(config) {
|
|
|
356
364
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
357
365
|
value: {
|
|
358
366
|
scope: cloneScope(config.scope),
|
|
367
|
+
examples: cloneCommandExamples(config.examples),
|
|
368
|
+
result: config.result,
|
|
359
369
|
humanInLoop: config.humanInLoop,
|
|
360
370
|
secrets: cloneSecrets(config.secrets),
|
|
361
371
|
requires: cloneRequires(config.requires),
|
|
@@ -373,9 +383,11 @@ function materializeCommand(command, inherited) {
|
|
|
373
383
|
kind: "command",
|
|
374
384
|
name: command.name,
|
|
375
385
|
description: command.description,
|
|
386
|
+
examples: cloneCommandExamples(internal.examples),
|
|
376
387
|
aliases: [...command.aliases],
|
|
377
388
|
positional: [...command.positional],
|
|
378
389
|
params: command.params,
|
|
390
|
+
result: internal.result,
|
|
379
391
|
secrets: mergeSecrets(inherited.secrets, internal.secrets),
|
|
380
392
|
scope: resolveCommandScope(internal.scope, inherited.scope),
|
|
381
393
|
confirm: command.confirm,
|
|
@@ -387,6 +399,8 @@ function materializeCommand(command, inherited) {
|
|
|
387
399
|
Object.defineProperty(materialized, commandConfigSymbol, {
|
|
388
400
|
value: {
|
|
389
401
|
scope: cloneScope(internal.scope),
|
|
402
|
+
examples: cloneCommandExamples(internal.examples),
|
|
403
|
+
result: internal.result,
|
|
390
404
|
humanInLoop: internal.humanInLoop,
|
|
391
405
|
secrets: cloneSecrets(internal.secrets),
|
|
392
406
|
requires: cloneRequires(internal.requires),
|
|
@@ -664,6 +678,10 @@ var TerminalBuffer = class {
|
|
|
664
678
|
}
|
|
665
679
|
_writePrintable(ch) {
|
|
666
680
|
const width = this._cellWidth(ch);
|
|
681
|
+
if (width === 0) {
|
|
682
|
+
this._appendCombiningMark(ch);
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
667
685
|
if (this._autoWrap && this._pendingWrap) {
|
|
668
686
|
this._cursorX = 0;
|
|
669
687
|
this._newline();
|
|
@@ -698,11 +716,40 @@ var TerminalBuffer = class {
|
|
|
698
716
|
_cellWidth(ch) {
|
|
699
717
|
const codePoint = ch.codePointAt(0);
|
|
700
718
|
if (codePoint === void 0) return 0;
|
|
719
|
+
if (isCombiningCodePoint(codePoint)) {
|
|
720
|
+
return 0;
|
|
721
|
+
}
|
|
701
722
|
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) {
|
|
702
723
|
return Math.min(2, this._cols);
|
|
703
724
|
}
|
|
704
725
|
return 1;
|
|
705
726
|
}
|
|
727
|
+
_appendCombiningMark(ch) {
|
|
728
|
+
const target = this._findCombiningTarget();
|
|
729
|
+
if (target === null) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const cell = this._screen[target.y]?.[target.x];
|
|
733
|
+
if (cell === null || cell === void 0) {
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
cell[1] += ch;
|
|
737
|
+
}
|
|
738
|
+
_findCombiningTarget() {
|
|
739
|
+
const startX = this._pendingWrap ? this._cursorX : this._cursorX - 1;
|
|
740
|
+
for (let y = this._cursorY; y >= 0; y -= 1) {
|
|
741
|
+
const row = this._screen[y];
|
|
742
|
+
if (row === void 0) {
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
for (let x = y === this._cursorY ? startX : this._cols - 1; x >= 0; x -= 1) {
|
|
746
|
+
if (row[x] !== null) {
|
|
747
|
+
return { x, y };
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return null;
|
|
752
|
+
}
|
|
706
753
|
_setChar(y, x, ch) {
|
|
707
754
|
const row = this._screen[y];
|
|
708
755
|
if (row && x >= 0 && x < this._cols) {
|
|
@@ -843,7 +890,8 @@ var TerminalBuffer = class {
|
|
|
843
890
|
case "J":
|
|
844
891
|
if (p0 === 0) {
|
|
845
892
|
this._eraseLine(this._cursorY, this._cursorX, this._cols - 1);
|
|
846
|
-
for (let y = this._cursorY + 1; y < this._rows; y++)
|
|
893
|
+
for (let y = this._cursorY + 1; y < this._rows; y++)
|
|
894
|
+
this._eraseLine(y, 0, this._cols - 1);
|
|
847
895
|
} else if (p0 === 1) {
|
|
848
896
|
for (let y = 0; y < this._cursorY; y++) this._eraseLine(y, 0, this._cols - 1);
|
|
849
897
|
this._eraseLine(this._cursorY, 0, this._cursorX);
|
|
@@ -1208,6 +1256,9 @@ function createDefaultStyleState() {
|
|
|
1208
1256
|
strikethrough: false
|
|
1209
1257
|
};
|
|
1210
1258
|
}
|
|
1259
|
+
function isCombiningCodePoint(codePoint) {
|
|
1260
|
+
return codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071;
|
|
1261
|
+
}
|
|
1211
1262
|
function serializeStyleState(state) {
|
|
1212
1263
|
const codes = [];
|
|
1213
1264
|
if (state.bold) {
|
|
@@ -1261,6 +1312,8 @@ var NAMED_KEY_LOWER = new Map(
|
|
|
1261
1312
|
Object.entries(NAMED_KEY_SEQUENCES).map(([k, v]) => [k.toLowerCase(), v])
|
|
1262
1313
|
);
|
|
1263
1314
|
var VALID_KEYS_HINT = `Valid keys: ${Object.keys(NAMED_KEY_SEQUENCES).join(", ")}, Control+<letter>, Alt+<key>`;
|
|
1315
|
+
var NAMED_KEY_PATTERN = Object.keys(NAMED_KEY_SEQUENCES).map(caseInsensitivePattern).join("|");
|
|
1316
|
+
var TERMINAL_KEY_PATTERN = `^(?:${NAMED_KEY_PATTERN}|.|[Cc][Oo][Nn][Tt][Rr][Oo][Ll]\\+[A-Za-z]|[Aa][Ll][Tt]\\+.+)$`;
|
|
1264
1317
|
function unknownKeyError(key) {
|
|
1265
1318
|
return new Error(`Unknown terminal key: ${key}. ${VALID_KEYS_HINT}`);
|
|
1266
1319
|
}
|
|
@@ -1303,6 +1356,18 @@ function controlKeyToSequence(controlKey) {
|
|
|
1303
1356
|
}
|
|
1304
1357
|
return String.fromCharCode(charCode - 64);
|
|
1305
1358
|
}
|
|
1359
|
+
function caseInsensitivePattern(value) {
|
|
1360
|
+
let pattern = "";
|
|
1361
|
+
for (const character of value) {
|
|
1362
|
+
const lower = character.toLowerCase();
|
|
1363
|
+
const upper = character.toUpperCase();
|
|
1364
|
+
pattern += lower === upper ? escapePatternCharacter(character) : `[${upper}${lower}]`;
|
|
1365
|
+
}
|
|
1366
|
+
return pattern;
|
|
1367
|
+
}
|
|
1368
|
+
function escapePatternCharacter(character) {
|
|
1369
|
+
return character.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
|
|
1370
|
+
}
|
|
1306
1371
|
|
|
1307
1372
|
// src/terminal-screen.ts
|
|
1308
1373
|
var TerminalScreen = class {
|
|
@@ -1742,7 +1807,11 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1742
1807
|
const pendingNames = /* @__PURE__ */ new Set();
|
|
1743
1808
|
let pilotPromise;
|
|
1744
1809
|
function getRequestedName(name, env) {
|
|
1745
|
-
|
|
1810
|
+
const requestedName = name ?? env?.get(SESSION_ENV_VAR);
|
|
1811
|
+
if (requestedName !== void 0 && requestedName.trim().length === 0) {
|
|
1812
|
+
throw new UserError("Session name must not be empty.");
|
|
1813
|
+
}
|
|
1814
|
+
return requestedName;
|
|
1746
1815
|
}
|
|
1747
1816
|
async function getPilot() {
|
|
1748
1817
|
pilotPromise ??= launchPilot();
|
|
@@ -1778,7 +1847,9 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1778
1847
|
const sessionId = nameToId.get(name);
|
|
1779
1848
|
if (sessionId === void 0) {
|
|
1780
1849
|
const active = await listSessions();
|
|
1781
|
-
throw new UserError(
|
|
1850
|
+
throw new UserError(
|
|
1851
|
+
`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
|
|
1852
|
+
);
|
|
1782
1853
|
}
|
|
1783
1854
|
const pilot = await getPilot();
|
|
1784
1855
|
try {
|
|
@@ -1786,7 +1857,9 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1786
1857
|
} catch {
|
|
1787
1858
|
forgetSession(name, sessionId);
|
|
1788
1859
|
const active = await listSessions();
|
|
1789
|
-
throw new UserError(
|
|
1860
|
+
throw new UserError(
|
|
1861
|
+
`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
|
|
1862
|
+
);
|
|
1790
1863
|
}
|
|
1791
1864
|
}
|
|
1792
1865
|
async function listSessions() {
|
|
@@ -1817,6 +1890,9 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1817
1890
|
}
|
|
1818
1891
|
return {
|
|
1819
1892
|
async createSession(params2, env) {
|
|
1893
|
+
if (params2.command.trim().length === 0) {
|
|
1894
|
+
throw new UserError("Command must not be empty.");
|
|
1895
|
+
}
|
|
1820
1896
|
const requestedName = getRequestedName(params2.session, env) ?? nextSessionName();
|
|
1821
1897
|
await discardExitedSessionName(requestedName);
|
|
1822
1898
|
if (nameToId.has(requestedName) || pendingNames.has(requestedName)) {
|
|
@@ -1882,9 +1958,17 @@ function createTerminalPilotRuntime(options = {}) {
|
|
|
1882
1958
|
|
|
1883
1959
|
// src/commands/wait-for.ts
|
|
1884
1960
|
var params = S.Object({
|
|
1885
|
-
pattern: S.String({
|
|
1886
|
-
|
|
1887
|
-
|
|
1961
|
+
pattern: S.String({
|
|
1962
|
+
description: "Regular expression pattern to wait for",
|
|
1963
|
+
minLength: 1,
|
|
1964
|
+
pattern: "\\S"
|
|
1965
|
+
}),
|
|
1966
|
+
session: S.Optional(
|
|
1967
|
+
S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
|
|
1968
|
+
),
|
|
1969
|
+
timeout: S.Optional(
|
|
1970
|
+
S.Number({ short: "t", description: "Maximum wait time in milliseconds", minimum: 0 })
|
|
1971
|
+
),
|
|
1888
1972
|
literal: S.Optional(
|
|
1889
1973
|
S.Boolean({
|
|
1890
1974
|
short: "l",
|
|
@@ -1899,12 +1983,24 @@ var waitFor = defineCommand({
|
|
|
1899
1983
|
positional: ["pattern"],
|
|
1900
1984
|
params,
|
|
1901
1985
|
handler: async ({ params: params2, env, terminalPilotRuntime }) => {
|
|
1902
|
-
|
|
1986
|
+
if (params2.pattern.trim().length === 0) {
|
|
1987
|
+
throw new UserError("Wait pattern must not be empty.");
|
|
1988
|
+
}
|
|
1989
|
+
assertTimeout2(params2.timeout);
|
|
1990
|
+
const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
|
|
1991
|
+
params2.session,
|
|
1992
|
+
env
|
|
1993
|
+
);
|
|
1903
1994
|
const pattern = params2.literal === true ? params2.pattern : new RegExp(params2.pattern);
|
|
1904
1995
|
const line = params2.timeout === void 0 ? await namedSession.session.waitFor(pattern) : await namedSession.session.waitFor(pattern, { timeout: params2.timeout });
|
|
1905
1996
|
return { matched: true, line };
|
|
1906
1997
|
}
|
|
1907
1998
|
});
|
|
1999
|
+
function assertTimeout2(timeout) {
|
|
2000
|
+
if (timeout !== void 0 && (!Number.isFinite(timeout) || timeout < 0)) {
|
|
2001
|
+
throw new UserError("Timeout must be a finite non-negative number.");
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
1908
2004
|
export {
|
|
1909
2005
|
waitFor
|
|
1910
2006
|
};
|