terminal-pilot 0.0.28 → 0.0.30

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.
Files changed (57) hide show
  1. package/dist/cli.js +430 -68
  2. package/dist/cli.js.map +3 -3
  3. package/dist/commands/close-session.js +73 -6
  4. package/dist/commands/close-session.js.map +2 -2
  5. package/dist/commands/create-session.js +80 -9
  6. package/dist/commands/create-session.js.map +2 -2
  7. package/dist/commands/fill.js +73 -6
  8. package/dist/commands/fill.js.map +2 -2
  9. package/dist/commands/get-session.js +73 -6
  10. package/dist/commands/get-session.js.map +2 -2
  11. package/dist/commands/index.js +371 -62
  12. package/dist/commands/index.js.map +3 -3
  13. package/dist/commands/install.js +10 -5
  14. package/dist/commands/install.js.map +2 -2
  15. package/dist/commands/installer.js +10 -5
  16. package/dist/commands/installer.js.map +2 -2
  17. package/dist/commands/list-sessions.js +66 -4
  18. package/dist/commands/list-sessions.js.map +2 -2
  19. package/dist/commands/press-key.js +146 -71
  20. package/dist/commands/press-key.js.map +3 -3
  21. package/dist/commands/read-history.js +81 -7
  22. package/dist/commands/read-history.js.map +2 -2
  23. package/dist/commands/read-screen.js +73 -6
  24. package/dist/commands/read-screen.js.map +2 -2
  25. package/dist/commands/resize.js +75 -8
  26. package/dist/commands/resize.js.map +2 -2
  27. package/dist/commands/runtime.js +66 -4
  28. package/dist/commands/runtime.js.map +2 -2
  29. package/dist/commands/screenshot.js +228 -23
  30. package/dist/commands/screenshot.js.map +3 -3
  31. package/dist/commands/send-signal.js +73 -6
  32. package/dist/commands/send-signal.js.map +2 -2
  33. package/dist/commands/type.js +73 -6
  34. package/dist/commands/type.js.map +2 -2
  35. package/dist/commands/uninstall.js +10 -5
  36. package/dist/commands/uninstall.js.map +2 -2
  37. package/dist/commands/wait-for-exit.js +79 -7
  38. package/dist/commands/wait-for-exit.js.map +2 -2
  39. package/dist/commands/wait-for.js +90 -8
  40. package/dist/commands/wait-for.js.map +3 -3
  41. package/dist/index.js +52 -1
  42. package/dist/index.js.map +2 -2
  43. package/dist/keys.d.ts +1 -0
  44. package/dist/keys.js +15 -0
  45. package/dist/keys.js.map +2 -2
  46. package/dist/terminal-buffer.d.ts +2 -0
  47. package/dist/terminal-buffer.js +38 -1
  48. package/dist/terminal-buffer.js.map +2 -2
  49. package/dist/terminal-pilot.js +52 -1
  50. package/dist/terminal-pilot.js.map +2 -2
  51. package/dist/terminal-session.js +52 -1
  52. package/dist/terminal-session.js.map +2 -2
  53. package/dist/testing/cli-repl.js +430 -68
  54. package/dist/testing/cli-repl.js.map +3 -3
  55. package/dist/testing/qa-cli.js +430 -68
  56. package/dist/testing/qa-cli.js.map +3 -3
  57. package/package.json +1 -1
@@ -267,6 +267,10 @@ var TerminalBuffer = class {
267
267
  }
268
268
  _writePrintable(ch) {
269
269
  const width = this._cellWidth(ch);
270
+ if (width === 0) {
271
+ this._appendCombiningMark(ch);
272
+ return;
273
+ }
270
274
  if (this._autoWrap && this._pendingWrap) {
271
275
  this._cursorX = 0;
272
276
  this._newline();
@@ -301,11 +305,40 @@ var TerminalBuffer = class {
301
305
  _cellWidth(ch) {
302
306
  const codePoint = ch.codePointAt(0);
303
307
  if (codePoint === void 0) return 0;
308
+ if (isCombiningCodePoint(codePoint)) {
309
+ return 0;
310
+ }
304
311
  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) {
305
312
  return Math.min(2, this._cols);
306
313
  }
307
314
  return 1;
308
315
  }
316
+ _appendCombiningMark(ch) {
317
+ const target = this._findCombiningTarget();
318
+ if (target === null) {
319
+ return;
320
+ }
321
+ const cell = this._screen[target.y]?.[target.x];
322
+ if (cell === null || cell === void 0) {
323
+ return;
324
+ }
325
+ cell[1] += ch;
326
+ }
327
+ _findCombiningTarget() {
328
+ const startX = this._pendingWrap ? this._cursorX : this._cursorX - 1;
329
+ for (let y = this._cursorY; y >= 0; y -= 1) {
330
+ const row = this._screen[y];
331
+ if (row === void 0) {
332
+ continue;
333
+ }
334
+ for (let x = y === this._cursorY ? startX : this._cols - 1; x >= 0; x -= 1) {
335
+ if (row[x] !== null) {
336
+ return { x, y };
337
+ }
338
+ }
339
+ }
340
+ return null;
341
+ }
309
342
  _setChar(y, x, ch) {
310
343
  const row = this._screen[y];
311
344
  if (row && x >= 0 && x < this._cols) {
@@ -446,7 +479,8 @@ var TerminalBuffer = class {
446
479
  case "J":
447
480
  if (p0 === 0) {
448
481
  this._eraseLine(this._cursorY, this._cursorX, this._cols - 1);
449
- for (let y = this._cursorY + 1; y < this._rows; y++) this._eraseLine(y, 0, this._cols - 1);
482
+ for (let y = this._cursorY + 1; y < this._rows; y++)
483
+ this._eraseLine(y, 0, this._cols - 1);
450
484
  } else if (p0 === 1) {
451
485
  for (let y = 0; y < this._cursorY; y++) this._eraseLine(y, 0, this._cols - 1);
452
486
  this._eraseLine(this._cursorY, 0, this._cursorX);
@@ -811,6 +845,9 @@ function createDefaultStyleState() {
811
845
  strikethrough: false
812
846
  };
813
847
  }
848
+ function isCombiningCodePoint(codePoint) {
849
+ return codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071;
850
+ }
814
851
  function serializeStyleState(state) {
815
852
  const codes = [];
816
853
  if (state.bold) {
@@ -864,6 +901,8 @@ var NAMED_KEY_LOWER = new Map(
864
901
  Object.entries(NAMED_KEY_SEQUENCES).map(([k, v]) => [k.toLowerCase(), v])
865
902
  );
866
903
  var VALID_KEYS_HINT = `Valid keys: ${Object.keys(NAMED_KEY_SEQUENCES).join(", ")}, Control+<letter>, Alt+<key>`;
904
+ var NAMED_KEY_PATTERN = Object.keys(NAMED_KEY_SEQUENCES).map(caseInsensitivePattern).join("|");
905
+ var TERMINAL_KEY_PATTERN = `^(?:${NAMED_KEY_PATTERN}|.|[Cc][Oo][Nn][Tt][Rr][Oo][Ll]\\+[A-Za-z]|[Aa][Ll][Tt]\\+.+)$`;
867
906
  function unknownKeyError(key) {
868
907
  return new Error(`Unknown terminal key: ${key}. ${VALID_KEYS_HINT}`);
869
908
  }
@@ -906,6 +945,18 @@ function controlKeyToSequence(controlKey) {
906
945
  }
907
946
  return String.fromCharCode(charCode - 64);
908
947
  }
948
+ function caseInsensitivePattern(value) {
949
+ let pattern = "";
950
+ for (const character of value) {
951
+ const lower = character.toLowerCase();
952
+ const upper = character.toUpperCase();
953
+ pattern += lower === upper ? escapePatternCharacter(character) : `[${upper}${lower}]`;
954
+ }
955
+ return pattern;
956
+ }
957
+ function escapePatternCharacter(character) {
958
+ return character.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
959
+ }
909
960
 
910
961
  // src/terminal-screen.ts
911
962
  var TerminalScreen = class {
@@ -1345,7 +1396,11 @@ function createTerminalPilotRuntime(options = {}) {
1345
1396
  const pendingNames = /* @__PURE__ */ new Set();
1346
1397
  let pilotPromise;
1347
1398
  function getRequestedName(name, env) {
1348
- return name ?? env?.get(SESSION_ENV_VAR);
1399
+ const requestedName = name ?? env?.get(SESSION_ENV_VAR);
1400
+ if (requestedName !== void 0 && requestedName.trim().length === 0) {
1401
+ throw new UserError("Session name must not be empty.");
1402
+ }
1403
+ return requestedName;
1349
1404
  }
1350
1405
  async function getPilot() {
1351
1406
  pilotPromise ??= launchPilot();
@@ -1381,7 +1436,9 @@ function createTerminalPilotRuntime(options = {}) {
1381
1436
  const sessionId = nameToId.get(name);
1382
1437
  if (sessionId === void 0) {
1383
1438
  const active = await listSessions();
1384
- throw new UserError(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
1439
+ throw new UserError(
1440
+ `Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
1441
+ );
1385
1442
  }
1386
1443
  const pilot = await getPilot();
1387
1444
  try {
@@ -1389,7 +1446,9 @@ function createTerminalPilotRuntime(options = {}) {
1389
1446
  } catch {
1390
1447
  forgetSession(name, sessionId);
1391
1448
  const active = await listSessions();
1392
- throw new UserError(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
1449
+ throw new UserError(
1450
+ `Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
1451
+ );
1393
1452
  }
1394
1453
  }
1395
1454
  async function listSessions() {
@@ -1420,6 +1479,9 @@ function createTerminalPilotRuntime(options = {}) {
1420
1479
  }
1421
1480
  return {
1422
1481
  async createSession(params, env) {
1482
+ if (params.command.trim().length === 0) {
1483
+ throw new UserError("Command must not be empty.");
1484
+ }
1423
1485
  const requestedName = getRequestedName(params.session, env) ?? nextSessionName();
1424
1486
  await discardExitedSessionName(requestedName);
1425
1487
  if (nameToId.has(requestedName) || pendingNames.has(requestedName)) {