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.
Files changed (57) hide show
  1. package/dist/cli.js +1224 -206
  2. package/dist/cli.js.map +4 -4
  3. package/dist/commands/close-session.js +87 -6
  4. package/dist/commands/close-session.js.map +2 -2
  5. package/dist/commands/create-session.js +94 -9
  6. package/dist/commands/create-session.js.map +2 -2
  7. package/dist/commands/fill.js +87 -6
  8. package/dist/commands/fill.js.map +2 -2
  9. package/dist/commands/get-session.js +87 -6
  10. package/dist/commands/get-session.js.map +2 -2
  11. package/dist/commands/index.js +482 -118
  12. package/dist/commands/index.js.map +4 -4
  13. package/dist/commands/install.js +108 -48
  14. package/dist/commands/install.js.map +4 -4
  15. package/dist/commands/installer.js +88 -42
  16. package/dist/commands/installer.js.map +4 -4
  17. package/dist/commands/list-sessions.js +80 -4
  18. package/dist/commands/list-sessions.js.map +2 -2
  19. package/dist/commands/press-key.js +160 -71
  20. package/dist/commands/press-key.js.map +3 -3
  21. package/dist/commands/read-history.js +95 -7
  22. package/dist/commands/read-history.js.map +2 -2
  23. package/dist/commands/read-screen.js +87 -6
  24. package/dist/commands/read-screen.js.map +2 -2
  25. package/dist/commands/resize.js +89 -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 +242 -23
  30. package/dist/commands/screenshot.js.map +3 -3
  31. package/dist/commands/send-signal.js +87 -6
  32. package/dist/commands/send-signal.js.map +2 -2
  33. package/dist/commands/type.js +87 -6
  34. package/dist/commands/type.js.map +2 -2
  35. package/dist/commands/uninstall.js +102 -42
  36. package/dist/commands/uninstall.js.map +4 -4
  37. package/dist/commands/wait-for-exit.js +93 -7
  38. package/dist/commands/wait-for-exit.js.map +2 -2
  39. package/dist/commands/wait-for.js +104 -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 +1229 -211
  54. package/dist/testing/cli-repl.js.map +4 -4
  55. package/dist/testing/qa-cli.js +1229 -211
  56. package/dist/testing/qa-cli.js.map +4 -4
  57. 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++) this._eraseLine(y, 0, this._cols - 1);
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
- return name ?? env?.get(SESSION_ENV_VAR);
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(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
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(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
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,7 +1958,9 @@ function createTerminalPilotRuntime(options = {}) {
1882
1958
 
1883
1959
  // src/commands/close-session.ts
1884
1960
  var params = S.Object({
1885
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
1961
+ session: S.Optional(
1962
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
1963
+ )
1886
1964
  });
1887
1965
  var closeSession = defineCommand({
1888
1966
  name: "close-session",
@@ -1890,7 +1968,10 @@ var closeSession = defineCommand({
1890
1968
  scope: ["cli", "mcp", "sdk"],
1891
1969
  params,
1892
1970
  handler: async ({ params: params2, env, terminalPilotRuntime }) => {
1893
- const { exitCode } = await getTerminalPilotRuntime(terminalPilotRuntime).closeSession(params2.session, env);
1971
+ const { exitCode } = await getTerminalPilotRuntime(terminalPilotRuntime).closeSession(
1972
+ params2.session,
1973
+ env
1974
+ );
1894
1975
  return { exitCode };
1895
1976
  }
1896
1977
  });