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
package/dist/cli.js CHANGED
@@ -12502,10 +12502,15 @@ async function writeErrorReport(context) {
12502
12502
 
12503
12503
  // ../toolcraft/src/number-schema.ts
12504
12504
  function isValidNumberSchemaValue(value, schema) {
12505
- return typeof value === "number" && Number.isFinite(value) && (schema.jsonType !== "integer" || Number.isInteger(value));
12505
+ return typeof value === "number" && Number.isFinite(value) && (schema.jsonType !== "integer" || Number.isInteger(value)) && (schema.minimum === void 0 || value >= schema.minimum) && (schema.maximum === void 0 || value <= schema.maximum);
12506
12506
  }
12507
12507
  function getExpectedNumberDescription(schema) {
12508
- return schema.jsonType === "integer" ? "an integer" : "a number";
12508
+ const type2 = schema.jsonType === "integer" ? "an integer" : "a number";
12509
+ const bounds = [
12510
+ schema.minimum === void 0 ? void 0 : `greater than or equal to ${schema.minimum}`,
12511
+ schema.maximum === void 0 ? void 0 : `less than or equal to ${schema.maximum}`
12512
+ ].filter((bound) => bound !== void 0);
12513
+ return bounds.length === 0 ? type2 : `${type2} ${bounds.join(" and ")}`;
12509
12514
  }
12510
12515
 
12511
12516
  // ../toolcraft/src/renderer.ts
@@ -13334,10 +13339,17 @@ function parseEnumValue(value, values, label) {
13334
13339
  return match;
13335
13340
  }
13336
13341
  function validateStringPattern(value, schema, label) {
13337
- if (schema.pattern === void 0) {
13338
- return value;
13342
+ if (schema.minLength !== void 0 && value.length < schema.minLength) {
13343
+ throw new UserError(
13344
+ `Invalid value for "${label}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`
13345
+ );
13339
13346
  }
13340
- if (!matchesStringPattern(value, schema.pattern)) {
13347
+ if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
13348
+ throw new UserError(
13349
+ `Invalid value for "${label}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`
13350
+ );
13351
+ }
13352
+ if (schema.pattern !== void 0 && !matchesStringPattern(value, schema.pattern)) {
13341
13353
  throw new UserError(
13342
13354
  `Invalid value for "${label}": "${value}" does not match pattern "${schema.pattern}".`
13343
13355
  );
@@ -13519,6 +13531,18 @@ function parseArrayValue(value, schema, label) {
13519
13531
  (item) => parseScalarValue(item, itemSchema, label)
13520
13532
  );
13521
13533
  }
13534
+ function validateArrayBounds(value, schema, label) {
13535
+ if (schema.minItems !== void 0 && value.length < schema.minItems) {
13536
+ throw new UserError(
13537
+ `Invalid value for "${label}". Expected an array with at least ${schema.minItems} items, got array(${value.length}).`
13538
+ );
13539
+ }
13540
+ if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
13541
+ throw new UserError(
13542
+ `Invalid value for "${label}". Expected an array with at most ${schema.maxItems} items, got array(${value.length}).`
13543
+ );
13544
+ }
13545
+ }
13522
13546
  function createOption(field, globalLongOptionFlags) {
13523
13547
  const flags = formatOptionFlags(field, globalLongOptionFlags);
13524
13548
  const collidesWithGlobalFlag = globalLongOptionFlags.has(field.optionFlag);
@@ -14488,6 +14512,9 @@ function describeExpectedPresetValue(schema) {
14488
14512
  if (schema.kind === "array") {
14489
14513
  return "an array";
14490
14514
  }
14515
+ if (schema.kind === "number") {
14516
+ return getExpectedNumberDescription(schema);
14517
+ }
14491
14518
  if (schema.kind === "json") {
14492
14519
  return "valid JSON";
14493
14520
  }
@@ -14505,6 +14532,16 @@ function validatePresetScalarValue(value, schema, fieldPath, presetPath) {
14505
14532
  if (typeof value !== "string") {
14506
14533
  break;
14507
14534
  }
14535
+ if (schema.minLength !== void 0 && value.length < schema.minLength) {
14536
+ throw new UserError(
14537
+ `Preset file "${presetPath}" has an invalid value for "${fieldPath}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`
14538
+ );
14539
+ }
14540
+ if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
14541
+ throw new UserError(
14542
+ `Preset file "${presetPath}" has an invalid value for "${fieldPath}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`
14543
+ );
14544
+ }
14508
14545
  if (schema.pattern !== void 0 && !matchesStringPattern(value, schema.pattern)) {
14509
14546
  throw new UserError(
14510
14547
  `Preset file "${presetPath}" has an invalid value for "${fieldPath}": "${value}" does not match pattern "${schema.pattern}".`
@@ -14554,6 +14591,16 @@ function validatePresetFieldValue(value, field, presetPath) {
14554
14591
  `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array, got ${describeReceived(value)}.`
14555
14592
  );
14556
14593
  }
14594
+ if (field.schema.minItems !== void 0 && value.length < field.schema.minItems) {
14595
+ throw new UserError(
14596
+ `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array with at least ${field.schema.minItems} items, got array(${value.length}).`
14597
+ );
14598
+ }
14599
+ if (field.schema.maxItems !== void 0 && value.length > field.schema.maxItems) {
14600
+ throw new UserError(
14601
+ `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array with at most ${field.schema.maxItems} items, got array(${value.length}).`
14602
+ );
14603
+ }
14557
14604
  return value.map(
14558
14605
  (item) => validatePresetScalarValue(item, itemSchema, field.displayPath, presetPath)
14559
14606
  );
@@ -14963,12 +15010,17 @@ function parseOptionFieldValue(field, value, errors2) {
14963
15010
  }
14964
15011
  parsedValues.push(...parsed);
14965
15012
  }
15013
+ validateArrayBounds(parsedValues, field.schema, field.displayPath);
14966
15014
  return { ok: true, value: parsedValues };
14967
15015
  }
14968
15016
  if (typeof value !== "string") {
14969
15017
  return { ok: true, value };
14970
15018
  }
14971
- return { ok: true, value: parseFieldInputValue(value, field.schema, field.displayPath) };
15019
+ const parsedValue = parseFieldInputValue(value, field.schema, field.displayPath);
15020
+ if (field.schema.kind === "array" && Array.isArray(parsedValue)) {
15021
+ validateArrayBounds(parsedValue, field.schema, field.displayPath);
15022
+ }
15023
+ return { ok: true, value: parsedValue };
14972
15024
  } catch (error3) {
14973
15025
  if (error3 instanceof UserError || error3 instanceof InvalidArgumentError) {
14974
15026
  errors2.push({
@@ -15029,6 +15081,7 @@ function consumeFieldValue(args, index, schema, label, inlineValue) {
15029
15081
  if (values.length === 0) {
15030
15082
  throw new InvalidArgumentError(`option '${label}' argument missing`);
15031
15083
  }
15084
+ validateArrayBounds(values, schema, label);
15032
15085
  return {
15033
15086
  nextIndex,
15034
15087
  value: values
@@ -16475,6 +16528,10 @@ var TerminalBuffer = class {
16475
16528
  }
16476
16529
  _writePrintable(ch) {
16477
16530
  const width = this._cellWidth(ch);
16531
+ if (width === 0) {
16532
+ this._appendCombiningMark(ch);
16533
+ return;
16534
+ }
16478
16535
  if (this._autoWrap && this._pendingWrap) {
16479
16536
  this._cursorX = 0;
16480
16537
  this._newline();
@@ -16509,11 +16566,40 @@ var TerminalBuffer = class {
16509
16566
  _cellWidth(ch) {
16510
16567
  const codePoint = ch.codePointAt(0);
16511
16568
  if (codePoint === void 0) return 0;
16569
+ if (isCombiningCodePoint2(codePoint)) {
16570
+ return 0;
16571
+ }
16512
16572
  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) {
16513
16573
  return Math.min(2, this._cols);
16514
16574
  }
16515
16575
  return 1;
16516
16576
  }
16577
+ _appendCombiningMark(ch) {
16578
+ const target = this._findCombiningTarget();
16579
+ if (target === null) {
16580
+ return;
16581
+ }
16582
+ const cell = this._screen[target.y]?.[target.x];
16583
+ if (cell === null || cell === void 0) {
16584
+ return;
16585
+ }
16586
+ cell[1] += ch;
16587
+ }
16588
+ _findCombiningTarget() {
16589
+ const startX = this._pendingWrap ? this._cursorX : this._cursorX - 1;
16590
+ for (let y = this._cursorY; y >= 0; y -= 1) {
16591
+ const row = this._screen[y];
16592
+ if (row === void 0) {
16593
+ continue;
16594
+ }
16595
+ for (let x = y === this._cursorY ? startX : this._cols - 1; x >= 0; x -= 1) {
16596
+ if (row[x] !== null) {
16597
+ return { x, y };
16598
+ }
16599
+ }
16600
+ }
16601
+ return null;
16602
+ }
16517
16603
  _setChar(y, x, ch) {
16518
16604
  const row = this._screen[y];
16519
16605
  if (row && x >= 0 && x < this._cols) {
@@ -16654,7 +16740,8 @@ var TerminalBuffer = class {
16654
16740
  case "J":
16655
16741
  if (p0 === 0) {
16656
16742
  this._eraseLine(this._cursorY, this._cursorX, this._cols - 1);
16657
- for (let y = this._cursorY + 1; y < this._rows; y++) this._eraseLine(y, 0, this._cols - 1);
16743
+ for (let y = this._cursorY + 1; y < this._rows; y++)
16744
+ this._eraseLine(y, 0, this._cols - 1);
16658
16745
  } else if (p0 === 1) {
16659
16746
  for (let y = 0; y < this._cursorY; y++) this._eraseLine(y, 0, this._cols - 1);
16660
16747
  this._eraseLine(this._cursorY, 0, this._cursorX);
@@ -17019,6 +17106,9 @@ function createDefaultStyleState() {
17019
17106
  strikethrough: false
17020
17107
  };
17021
17108
  }
17109
+ function isCombiningCodePoint2(codePoint) {
17110
+ return codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071;
17111
+ }
17022
17112
  function serializeStyleState(state) {
17023
17113
  const codes = [];
17024
17114
  if (state.bold) {
@@ -17072,6 +17162,8 @@ var NAMED_KEY_LOWER = new Map(
17072
17162
  Object.entries(NAMED_KEY_SEQUENCES).map(([k, v]) => [k.toLowerCase(), v])
17073
17163
  );
17074
17164
  var VALID_KEYS_HINT = `Valid keys: ${Object.keys(NAMED_KEY_SEQUENCES).join(", ")}, Control+<letter>, Alt+<key>`;
17165
+ var NAMED_KEY_PATTERN = Object.keys(NAMED_KEY_SEQUENCES).map(caseInsensitivePattern).join("|");
17166
+ var TERMINAL_KEY_PATTERN = `^(?:${NAMED_KEY_PATTERN}|.|[Cc][Oo][Nn][Tt][Rr][Oo][Ll]\\+[A-Za-z]|[Aa][Ll][Tt]\\+.+)$`;
17075
17167
  function unknownKeyError(key2) {
17076
17168
  return new Error(`Unknown terminal key: ${key2}. ${VALID_KEYS_HINT}`);
17077
17169
  }
@@ -17114,6 +17206,18 @@ function controlKeyToSequence(controlKey) {
17114
17206
  }
17115
17207
  return String.fromCharCode(charCode - 64);
17116
17208
  }
17209
+ function caseInsensitivePattern(value) {
17210
+ let pattern = "";
17211
+ for (const character of value) {
17212
+ const lower = character.toLowerCase();
17213
+ const upper = character.toUpperCase();
17214
+ pattern += lower === upper ? escapePatternCharacter(character) : `[${upper}${lower}]`;
17215
+ }
17216
+ return pattern;
17217
+ }
17218
+ function escapePatternCharacter(character) {
17219
+ return character.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
17220
+ }
17117
17221
 
17118
17222
  // src/terminal-screen.ts
17119
17223
  var TerminalScreen = class {
@@ -17553,7 +17657,11 @@ function createTerminalPilotRuntime(options = {}) {
17553
17657
  const pendingNames = /* @__PURE__ */ new Set();
17554
17658
  let pilotPromise;
17555
17659
  function getRequestedName(name, env) {
17556
- return name ?? env?.get(SESSION_ENV_VAR);
17660
+ const requestedName = name ?? env?.get(SESSION_ENV_VAR);
17661
+ if (requestedName !== void 0 && requestedName.trim().length === 0) {
17662
+ throw new UserError("Session name must not be empty.");
17663
+ }
17664
+ return requestedName;
17557
17665
  }
17558
17666
  async function getPilot() {
17559
17667
  pilotPromise ??= launchPilot();
@@ -17589,7 +17697,9 @@ function createTerminalPilotRuntime(options = {}) {
17589
17697
  const sessionId = nameToId.get(name);
17590
17698
  if (sessionId === void 0) {
17591
17699
  const active = await listSessions2();
17592
- throw new UserError(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
17700
+ throw new UserError(
17701
+ `Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
17702
+ );
17593
17703
  }
17594
17704
  const pilot = await getPilot();
17595
17705
  try {
@@ -17597,7 +17707,9 @@ function createTerminalPilotRuntime(options = {}) {
17597
17707
  } catch {
17598
17708
  forgetSession(name, sessionId);
17599
17709
  const active = await listSessions2();
17600
- throw new UserError(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
17710
+ throw new UserError(
17711
+ `Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
17712
+ );
17601
17713
  }
17602
17714
  }
17603
17715
  async function listSessions2() {
@@ -17628,6 +17740,9 @@ function createTerminalPilotRuntime(options = {}) {
17628
17740
  }
17629
17741
  return {
17630
17742
  async createSession(params17, env) {
17743
+ if (params17.command.trim().length === 0) {
17744
+ throw new UserError("Command must not be empty.");
17745
+ }
17631
17746
  const requestedName = getRequestedName(params17.session, env) ?? nextSessionName();
17632
17747
  await discardExitedSessionName(requestedName);
17633
17748
  if (nameToId.has(requestedName) || pendingNames.has(requestedName)) {
@@ -17693,7 +17808,9 @@ function createTerminalPilotRuntime(options = {}) {
17693
17808
 
17694
17809
  // src/commands/close-session.ts
17695
17810
  var params = S.Object({
17696
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17811
+ session: S.Optional(
17812
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17813
+ )
17697
17814
  });
17698
17815
  var closeSession = defineCommand({
17699
17816
  name: "close-session",
@@ -17701,19 +17818,28 @@ var closeSession = defineCommand({
17701
17818
  scope: ["cli", "mcp", "sdk"],
17702
17819
  params,
17703
17820
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17704
- const { exitCode } = await getTerminalPilotRuntime(terminalPilotRuntime).closeSession(params17.session, env);
17821
+ const { exitCode } = await getTerminalPilotRuntime(terminalPilotRuntime).closeSession(
17822
+ params17.session,
17823
+ env
17824
+ );
17705
17825
  return { exitCode };
17706
17826
  }
17707
17827
  });
17708
17828
 
17709
17829
  // src/commands/create-session.ts
17710
17830
  var params2 = S.Object({
17711
- command: S.String({ description: "Command to execute" }),
17831
+ command: S.String({ description: "Command to execute", minLength: 1, pattern: "\\S" }),
17712
17832
  args: S.Optional(S.Array(S.String(), { description: "Command arguments" })),
17713
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
17833
+ session: S.Optional(
17834
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17835
+ ),
17714
17836
  cwd: S.Optional(S.String({ description: "Working directory" })),
17715
- cols: S.Optional(S.Number({ description: "Terminal width in columns" })),
17716
- rows: S.Optional(S.Number({ description: "Terminal height in rows" })),
17837
+ cols: S.Optional(
17838
+ S.Number({ description: "Terminal width in columns", jsonType: "integer", minimum: 1 })
17839
+ ),
17840
+ rows: S.Optional(
17841
+ S.Number({ description: "Terminal height in rows", jsonType: "integer", minimum: 1 })
17842
+ ),
17717
17843
  observe: S.Optional(S.Boolean({ description: "Mirror PTY output to stderr" }))
17718
17844
  });
17719
17845
  var createSession = defineCommand({
@@ -17723,7 +17849,10 @@ var createSession = defineCommand({
17723
17849
  positional: ["command", "args"],
17724
17850
  params: params2,
17725
17851
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17726
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).createSession(params17, env);
17852
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).createSession(
17853
+ params17,
17854
+ env
17855
+ );
17727
17856
  return { session: namedSession.name, pid: namedSession.session.pid };
17728
17857
  }
17729
17858
  });
@@ -17731,7 +17860,9 @@ var createSession = defineCommand({
17731
17860
  // src/commands/fill.ts
17732
17861
  var params3 = S.Object({
17733
17862
  text: S.String({ description: "Text to write to the session" }),
17734
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17863
+ session: S.Optional(
17864
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17865
+ )
17735
17866
  });
17736
17867
  var fill = defineCommand({
17737
17868
  name: "fill",
@@ -17740,7 +17871,10 @@ var fill = defineCommand({
17740
17871
  positional: ["text"],
17741
17872
  params: params3,
17742
17873
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17743
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
17874
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
17875
+ params17.session,
17876
+ env
17877
+ );
17744
17878
  await namedSession.session.fill(params17.text);
17745
17879
  return void 0;
17746
17880
  }
@@ -17748,7 +17882,9 @@ var fill = defineCommand({
17748
17882
 
17749
17883
  // src/commands/get-session.ts
17750
17884
  var params4 = S.Object({
17751
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17885
+ session: S.Optional(
17886
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17887
+ )
17752
17888
  });
17753
17889
  var getSession = defineCommand({
17754
17890
  name: "get-session",
@@ -17756,7 +17892,10 @@ var getSession = defineCommand({
17756
17892
  scope: ["cli", "mcp", "sdk"],
17757
17893
  params: params4,
17758
17894
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17759
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
17895
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
17896
+ params17.session,
17897
+ env
17898
+ );
17760
17899
  return {
17761
17900
  session: namedSession.name,
17762
17901
  pid: namedSession.session.pid,
@@ -17784,7 +17923,7 @@ var claudeCodeAgent = {
17784
17923
  CLAUDE_CODE_ENABLE_TELEMETRY: "1"
17785
17924
  }
17786
17925
  },
17787
- configPath: "~/.claude/settings.json",
17926
+ configPath: "~/.claude.json",
17788
17927
  branding: {
17789
17928
  colors: {
17790
17929
  dark: "#C15F3C",
@@ -17799,7 +17938,12 @@ var claudeDesktopAgent = {
17799
17938
  name: "claude-desktop",
17800
17939
  label: "Claude Desktop",
17801
17940
  summary: "Anthropic's official desktop application for Claude",
17802
- configPath: "~/.claude/settings.json",
17941
+ configPath: "~/.config/Claude/claude_desktop_config.json",
17942
+ configPaths: {
17943
+ darwin: "~/Library/Application Support/Claude/claude_desktop_config.json",
17944
+ linux: "~/.config/Claude/claude_desktop_config.json",
17945
+ win32: "~/AppData/Roaming/Claude/claude_desktop_config.json"
17946
+ },
17803
17947
  branding: {
17804
17948
  colors: {
17805
17949
  dark: "#D97757",
@@ -17843,7 +17987,7 @@ var cursorAgent = {
17843
17987
  label: "Cursor",
17844
17988
  summary: "Cursor's CLI coding agent.",
17845
17989
  binaryName: "cursor-agent",
17846
- configPath: "~/.cursor/cli-config.json",
17990
+ configPath: "~/.cursor/mcp.json",
17847
17991
  branding: {
17848
17992
  colors: {
17849
17993
  dark: "#FFFFFF",
@@ -17883,7 +18027,7 @@ var openCodeAgent = {
17883
18027
  OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
17884
18028
  }
17885
18029
  },
17886
- configPath: "~/.config/opencode/config.json",
18030
+ configPath: "~/.config/opencode/opencode.json",
17887
18031
  branding: {
17888
18032
  colors: {
17889
18033
  dark: "#4A4F55",
@@ -17901,7 +18045,7 @@ var kimiAgent = {
17901
18045
  aliases: ["kimi-cli"],
17902
18046
  binaryName: "kimi",
17903
18047
  apiShapes: ["openai-chat-completions"],
17904
- configPath: "~/.kimi/config.toml",
18048
+ configPath: "~/.kimi/mcp.json",
17905
18049
  branding: {
17906
18050
  colors: {
17907
18051
  dark: "#7B68EE",
@@ -19601,8 +19745,10 @@ var listSessions = defineCommand({
19601
19745
 
19602
19746
  // src/commands/press-key.ts
19603
19747
  var params7 = S.Object({
19604
- key: S.String({ description: "Named key to press" }),
19605
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19748
+ key: S.String({ description: "Named key to press", pattern: TERMINAL_KEY_PATTERN }),
19749
+ session: S.Optional(
19750
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19751
+ )
19606
19752
  });
19607
19753
  var pressKey = defineCommand({
19608
19754
  name: "press-key",
@@ -19611,16 +19757,36 @@ var pressKey = defineCommand({
19611
19757
  positional: ["key"],
19612
19758
  params: params7,
19613
19759
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19614
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19760
+ assertTerminalKey(params17.key);
19761
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19762
+ params17.session,
19763
+ env
19764
+ );
19615
19765
  await namedSession.session.press(params17.key);
19616
19766
  return void 0;
19617
19767
  }
19618
19768
  });
19769
+ function assertTerminalKey(key2) {
19770
+ try {
19771
+ keyToSequence(key2);
19772
+ } catch (error3) {
19773
+ throw new UserError(error3 instanceof Error ? error3.message : String(error3));
19774
+ }
19775
+ }
19619
19776
 
19620
19777
  // src/commands/read-history.ts
19621
19778
  var params8 = S.Object({
19622
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
19623
- last: S.Optional(S.Number({ short: "n", description: "Return only the last N lines" }))
19779
+ session: S.Optional(
19780
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19781
+ ),
19782
+ last: S.Optional(
19783
+ S.Number({
19784
+ short: "n",
19785
+ description: "Return only the last N lines",
19786
+ jsonType: "integer",
19787
+ minimum: 0
19788
+ })
19789
+ )
19624
19790
  });
19625
19791
  var readHistory = defineCommand({
19626
19792
  name: "read-history",
@@ -19628,7 +19794,10 @@ var readHistory = defineCommand({
19628
19794
  scope: ["cli", "mcp", "sdk"],
19629
19795
  params: params8,
19630
19796
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19631
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19797
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19798
+ params17.session,
19799
+ env
19800
+ );
19632
19801
  const lines = await namedSession.session.history({ last: params17.last });
19633
19802
  return { lines, exitCode: namedSession.session.exitCode };
19634
19803
  }
@@ -19636,7 +19805,9 @@ var readHistory = defineCommand({
19636
19805
 
19637
19806
  // src/commands/read-screen.ts
19638
19807
  var params9 = S.Object({
19639
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19808
+ session: S.Optional(
19809
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19810
+ )
19640
19811
  });
19641
19812
  var readScreen = defineCommand({
19642
19813
  name: "read-screen",
@@ -19644,7 +19815,10 @@ var readScreen = defineCommand({
19644
19815
  scope: ["cli", "mcp", "sdk"],
19645
19816
  params: params9,
19646
19817
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19647
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19818
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19819
+ params17.session,
19820
+ env
19821
+ );
19648
19822
  const screen = await namedSession.session.screen();
19649
19823
  return {
19650
19824
  lines: [...screen.lines],
@@ -19657,9 +19831,11 @@ var readScreen = defineCommand({
19657
19831
 
19658
19832
  // src/commands/resize.ts
19659
19833
  var params10 = S.Object({
19660
- cols: S.Number({ description: "Terminal width in columns" }),
19661
- rows: S.Number({ description: "Terminal height in rows" }),
19662
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19834
+ cols: S.Number({ description: "Terminal width in columns", jsonType: "integer", minimum: 1 }),
19835
+ rows: S.Number({ description: "Terminal height in rows", jsonType: "integer", minimum: 1 }),
19836
+ session: S.Optional(
19837
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19838
+ )
19663
19839
  });
19664
19840
  var resize = defineCommand({
19665
19841
  name: "resize",
@@ -19667,7 +19843,10 @@ var resize = defineCommand({
19667
19843
  scope: ["cli", "mcp", "sdk"],
19668
19844
  params: params10,
19669
19845
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19670
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19846
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19847
+ params17.session,
19848
+ env
19849
+ );
19671
19850
  await namedSession.session.resize(params17.cols, params17.rows);
19672
19851
  return void 0;
19673
19852
  }
@@ -19679,6 +19858,9 @@ import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises
19679
19858
 
19680
19859
  // ../terminal-png/src/ansi-parser.ts
19681
19860
  var ESC2 = "\x1B";
19861
+ var TAB_WIDTH = 8;
19862
+ var MAX_TERMINAL_ROWS = 1e3;
19863
+ var MAX_TERMINAL_COLUMNS = 1e3;
19682
19864
  function createDefaultStyle() {
19683
19865
  return {
19684
19866
  fg: null,
@@ -19963,10 +20145,34 @@ function positionParameter(params17, index, fallback) {
19963
20145
  const value = toInteger(params17.split(";")[index]);
19964
20146
  return value === null || value < 1 ? fallback : value;
19965
20147
  }
20148
+ function modeParameter(params17, fallback) {
20149
+ const value = toInteger(params17.split(";")[0]);
20150
+ return value === null ? fallback : value;
20151
+ }
20152
+ function displayWidth3(text4) {
20153
+ if (text4 === " ") {
20154
+ return TAB_WIDTH;
20155
+ }
20156
+ const codePoint = text4.codePointAt(0);
20157
+ if (codePoint === void 0) {
20158
+ return 0;
20159
+ }
20160
+ if (codePoint >= 4352 && codePoint <= 4447 || codePoint === 9001 || codePoint === 9002 || codePoint >= 11904 && codePoint <= 42191 && codePoint !== 12351 || codePoint >= 44032 && codePoint <= 55203 || codePoint >= 63744 && codePoint <= 64255 || codePoint >= 65040 && codePoint <= 65049 || codePoint >= 65072 && codePoint <= 65135 || codePoint >= 65280 && codePoint <= 65376 || codePoint >= 65504 && codePoint <= 65510 || codePoint >= 127744 && codePoint <= 128591 || codePoint >= 129280 && codePoint <= 129535 || codePoint >= 131072 && codePoint <= 262141) {
20161
+ return 2;
20162
+ }
20163
+ return 1;
20164
+ }
20165
+ function hasRenderableCell(line) {
20166
+ return (line ?? []).some((cell) => cell !== void 0 && cell.text.length > 0);
20167
+ }
19966
20168
  function buildRuns(lines, lineBreakStyles) {
19967
20169
  const runs = [];
19968
20170
  const defaultStyle = createDefaultStyle();
19969
- for (let row = 0; row < lines.length; row += 1) {
20171
+ let lastRow = lines.length - 1;
20172
+ while (lastRow > 0 && !hasRenderableCell(lines[lastRow]) && lineBreakStyles[lastRow - 1] === void 0) {
20173
+ lastRow -= 1;
20174
+ }
20175
+ for (let row = 0; row <= lastRow; row += 1) {
19970
20176
  const line = lines[row] ?? [];
19971
20177
  let lastCell = line.length - 1;
19972
20178
  while (lastCell >= 0 && line[lastCell] === void 0) {
@@ -19976,7 +20182,7 @@ function buildRuns(lines, lineBreakStyles) {
19976
20182
  const cell = line[column] ?? { text: " ", style: defaultStyle };
19977
20183
  pushRun(runs, cell.style, cell.text);
19978
20184
  }
19979
- if (row < lines.length - 1) {
20185
+ if (row < lastRow) {
19980
20186
  pushRun(runs, lineBreakStyles[row] ?? defaultStyle, "\n");
19981
20187
  }
19982
20188
  }
@@ -19988,7 +20194,21 @@ function parseAnsi2(input) {
19988
20194
  let style = createDefaultStyle();
19989
20195
  let row = 0;
19990
20196
  let column = 0;
20197
+ let savedRow = 0;
20198
+ let savedColumn = 0;
19991
20199
  let index = 0;
20200
+ const clampRow = (nextRow) => {
20201
+ if (nextRow < 0) {
20202
+ return 0;
20203
+ }
20204
+ return Math.min(nextRow, MAX_TERMINAL_ROWS - 1);
20205
+ };
20206
+ const clampColumn = (nextColumn) => {
20207
+ if (nextColumn < 0) {
20208
+ return 0;
20209
+ }
20210
+ return Math.min(nextColumn, MAX_TERMINAL_COLUMNS - 1);
20211
+ };
19992
20212
  const ensureLine = () => {
19993
20213
  while (lines.length <= row) {
19994
20214
  lines.push([]);
@@ -19996,12 +20216,64 @@ function parseAnsi2(input) {
19996
20216
  };
19997
20217
  const moveDown = (keepColumn) => {
19998
20218
  lineBreakStyles[row] = cloneStyle(style);
19999
- row += 1;
20219
+ row = clampRow(row + 1);
20000
20220
  if (!keepColumn) {
20001
20221
  column = 0;
20002
20222
  }
20003
20223
  ensureLine();
20004
20224
  };
20225
+ const eraseLine = (mode) => {
20226
+ const line = lines[row] ?? [];
20227
+ if (mode === 1) {
20228
+ for (let cell = 0; cell <= column; cell += 1) {
20229
+ delete line[cell];
20230
+ }
20231
+ return;
20232
+ }
20233
+ if (mode === 2) {
20234
+ lines[row] = [];
20235
+ return;
20236
+ }
20237
+ line.splice(column);
20238
+ };
20239
+ const eraseDisplay = (mode) => {
20240
+ if (mode === 1) {
20241
+ for (let lineRow = 0; lineRow < row; lineRow += 1) {
20242
+ lines[lineRow] = [];
20243
+ }
20244
+ eraseLine(1);
20245
+ return;
20246
+ }
20247
+ if (mode === 2 || mode === 3) {
20248
+ lines.length = 0;
20249
+ lineBreakStyles.length = 0;
20250
+ ensureLine();
20251
+ return;
20252
+ }
20253
+ eraseLine(0);
20254
+ lines.splice(row + 1);
20255
+ lineBreakStyles.splice(row);
20256
+ };
20257
+ const saveCursor = () => {
20258
+ savedRow = row;
20259
+ savedColumn = column;
20260
+ };
20261
+ const restoreCursor = () => {
20262
+ row = clampRow(savedRow);
20263
+ column = clampColumn(savedColumn);
20264
+ ensureLine();
20265
+ };
20266
+ const writeText = (text4) => {
20267
+ const width = displayWidth3(text4);
20268
+ if (width === 0) {
20269
+ return;
20270
+ }
20271
+ lines[row][column] = { text: text4, style: cloneStyle(style) };
20272
+ for (let offset = 1; offset < width && column + offset < MAX_TERMINAL_COLUMNS; offset += 1) {
20273
+ lines[row][column + offset] = { text: "", style: cloneStyle(style) };
20274
+ }
20275
+ column = clampColumn(column + width);
20276
+ };
20005
20277
  while (index < input.length) {
20006
20278
  const char = input[index];
20007
20279
  if (char === "\n") {
@@ -20024,38 +20296,73 @@ function parseAnsi2(input) {
20024
20296
  index += 1;
20025
20297
  continue;
20026
20298
  }
20299
+ if (char === " ") {
20300
+ const nextTabStop = Math.min(
20301
+ Math.floor(column / TAB_WIDTH) * TAB_WIDTH + TAB_WIDTH,
20302
+ MAX_TERMINAL_COLUMNS
20303
+ );
20304
+ while (column < nextTabStop) {
20305
+ writeText(" ");
20306
+ }
20307
+ index += 1;
20308
+ continue;
20309
+ }
20027
20310
  if (char === ESC2 && input[index + 1] === "]") {
20028
20311
  index = parseOscEnd(input, index);
20029
20312
  continue;
20030
20313
  }
20314
+ if (char === ESC2 && input[index + 1] === "7") {
20315
+ saveCursor();
20316
+ index += 2;
20317
+ continue;
20318
+ }
20319
+ if (char === ESC2 && input[index + 1] === "8") {
20320
+ restoreCursor();
20321
+ index += 2;
20322
+ continue;
20323
+ }
20031
20324
  const csiPrefixLength = char === "\x9B" ? 1 : char === ESC2 && input[index + 1] === "[" ? 2 : null;
20032
20325
  if (csiPrefixLength !== null) {
20033
20326
  const sequence = parseCsi(input, index, csiPrefixLength);
20034
20327
  if (sequence.final === "m") {
20035
20328
  style = applySgr(style, sequence.params);
20036
20329
  } else if (sequence.final === "G") {
20037
- column = positionParameter(sequence.params, 0, 1) - 1;
20330
+ column = clampColumn(positionParameter(sequence.params, 0, 1) - 1);
20038
20331
  } else if (sequence.final === "C") {
20039
- column += positionParameter(sequence.params, 0, 1);
20332
+ column = clampColumn(column + positionParameter(sequence.params, 0, 1));
20040
20333
  } else if (sequence.final === "D") {
20041
20334
  column = Math.max(0, column - positionParameter(sequence.params, 0, 1));
20042
20335
  } else if (sequence.final === "A") {
20043
- row = Math.max(0, row - positionParameter(sequence.params, 0, 1));
20336
+ row = clampRow(row - positionParameter(sequence.params, 0, 1));
20044
20337
  } else if (sequence.final === "B") {
20045
- row += positionParameter(sequence.params, 0, 1);
20338
+ row = clampRow(row + positionParameter(sequence.params, 0, 1));
20046
20339
  ensureLine();
20340
+ } else if (sequence.final === "E") {
20341
+ row = clampRow(row + positionParameter(sequence.params, 0, 1));
20342
+ column = 0;
20343
+ ensureLine();
20344
+ } else if (sequence.final === "F") {
20345
+ row = clampRow(row - positionParameter(sequence.params, 0, 1));
20346
+ column = 0;
20047
20347
  } else if (sequence.final === "H" || sequence.final === "f") {
20048
- row = positionParameter(sequence.params, 0, 1) - 1;
20049
- column = positionParameter(sequence.params, 1, 1) - 1;
20348
+ row = clampRow(positionParameter(sequence.params, 0, 1) - 1);
20349
+ column = clampColumn(positionParameter(sequence.params, 1, 1) - 1);
20050
20350
  ensureLine();
20351
+ } else if (sequence.final === "K") {
20352
+ eraseLine(modeParameter(sequence.params, 0));
20353
+ } else if (sequence.final === "J") {
20354
+ eraseDisplay(modeParameter(sequence.params, 0));
20355
+ } else if (sequence.final === "s") {
20356
+ saveCursor();
20357
+ } else if (sequence.final === "u") {
20358
+ restoreCursor();
20051
20359
  }
20052
20360
  index = sequence.end;
20053
20361
  continue;
20054
20362
  }
20055
20363
  const codePoint = input.codePointAt(index);
20056
20364
  const text4 = codePoint === void 0 ? "" : String.fromCodePoint(codePoint);
20057
- lines[row][column] = { text: text4, style: cloneStyle(style) };
20058
- column += 1;
20365
+ writeText(text4);
20059
20366
  index += text4.length;
20060
20367
  }
20061
20368
  return buildRuns(lines, lineBreakStyles);
@@ -20463,11 +20770,11 @@ function splitIntoLines(runs) {
20463
20770
  }
20464
20771
  function measureLines(lines) {
20465
20772
  return Math.max(
20466
- ...lines.map((line) => displayWidth3(line.map((run) => run.text).join("")) * CHARACTER_WIDTH),
20773
+ ...lines.map((line) => displayWidth4(line.map((run) => run.text).join("")) * CHARACTER_WIDTH),
20467
20774
  0
20468
20775
  );
20469
20776
  }
20470
- function displayWidth3(text4, startColumn = 0) {
20777
+ function displayWidth4(text4, startColumn = 0) {
20471
20778
  const segmenter = new Intl.Segmenter();
20472
20779
  let column = startColumn;
20473
20780
  for (const { segment } of segmenter.segment(text4)) {
@@ -20529,7 +20836,7 @@ function renderBackgrounds(line, startX, y, height) {
20529
20836
  let column = 0;
20530
20837
  const rectangles = [];
20531
20838
  for (const run of line) {
20532
- const width = displayWidth3(run.text, column);
20839
+ const width = displayWidth4(run.text, column);
20533
20840
  const background = resolveBackgroundColor(run);
20534
20841
  if (background !== BACKGROUND && width > 0) {
20535
20842
  rectangles.push(`<rect x="${formatNumber(startX + column * CHARACTER_WIDTH)}" y="${formatNumber(y)}" width="${formatNumber(width * CHARACTER_WIDTH)}" height="${formatNumber(height)}" fill="${escapeXmlAttribute(background)}" />`);
@@ -20563,7 +20870,7 @@ function renderRun(run) {
20563
20870
  if (run.dim) {
20564
20871
  attributes.push('opacity="0.7"');
20565
20872
  }
20566
- const text4 = run.conceal ? " ".repeat(displayWidth3(run.text)) : run.text;
20873
+ const text4 = run.conceal ? " ".repeat(displayWidth4(run.text)) : run.text;
20567
20874
  return `<tspan ${attributes.join(" ")}>${escapeXmlText(text4)}</tspan>`;
20568
20875
  }
20569
20876
  function renderWindowControls() {
@@ -20612,13 +20919,16 @@ async function renderTerminalPng(ansiText, options = {}) {
20612
20919
  if (options.padding !== void 0 && (!Number.isInteger(options.padding) || options.padding < 0)) {
20613
20920
  throw new Error("Padding must be a non-negative integer.");
20614
20921
  }
20922
+ if (options.output !== void 0 && options.output.length === 0) {
20923
+ throw new Error("Output path must not be empty.");
20924
+ }
20615
20925
  const runs = parseAnsi2(ansiText);
20616
20926
  const svg = renderSvg(runs, {
20617
20927
  padding: options.padding,
20618
20928
  window: options.window
20619
20929
  });
20620
20930
  const png = renderPng(svg);
20621
- if (options.output) {
20931
+ if (options.output !== void 0) {
20622
20932
  const temporaryPath = `${options.output}.${randomUUID10()}.tmp`;
20623
20933
  let temporaryCreated = false;
20624
20934
  try {
@@ -20644,10 +20954,19 @@ function isAlreadyExistsError3(error3) {
20644
20954
 
20645
20955
  // src/commands/screenshot.ts
20646
20956
  var params11 = S.Object({
20647
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20957
+ session: S.Optional(
20958
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
20959
+ ),
20648
20960
  output: S.String({ short: "o", description: "Path to the output PNG file" }),
20649
20961
  window: S.Optional(S.Boolean({ description: "Include terminal window chrome", default: true })),
20650
- padding: S.Optional(S.Number({ short: "p", description: "Padding around terminal content" }))
20962
+ padding: S.Optional(
20963
+ S.Number({
20964
+ short: "p",
20965
+ description: "Padding around terminal content",
20966
+ jsonType: "integer",
20967
+ minimum: 0
20968
+ })
20969
+ )
20651
20970
  });
20652
20971
  var screenshot = defineCommand({
20653
20972
  name: "screenshot",
@@ -20655,7 +20974,10 @@ var screenshot = defineCommand({
20655
20974
  scope: ["cli"],
20656
20975
  params: params11,
20657
20976
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20658
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
20977
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
20978
+ params17.session,
20979
+ env
20980
+ );
20659
20981
  const screen = await namedSession.session.screen();
20660
20982
  await renderTerminalPng(screen.rawLines.join("\n"), {
20661
20983
  output: params17.output,
@@ -20669,7 +20991,9 @@ var screenshot = defineCommand({
20669
20991
  // src/commands/send-signal.ts
20670
20992
  var params12 = S.Object({
20671
20993
  signal: S.String({ description: "Signal to send to the session process" }),
20672
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
20994
+ session: S.Optional(
20995
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
20996
+ )
20673
20997
  });
20674
20998
  var sendSignal = defineCommand({
20675
20999
  name: "send-signal",
@@ -20678,7 +21002,10 @@ var sendSignal = defineCommand({
20678
21002
  positional: ["signal"],
20679
21003
  params: params12,
20680
21004
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20681
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21005
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21006
+ params17.session,
21007
+ env
21008
+ );
20682
21009
  await namedSession.session.signal(params17.signal);
20683
21010
  return void 0;
20684
21011
  }
@@ -20687,7 +21014,9 @@ var sendSignal = defineCommand({
20687
21014
  // src/commands/type.ts
20688
21015
  var params13 = S.Object({
20689
21016
  text: S.String({ description: "Text to write to the session" }),
20690
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
21017
+ session: S.Optional(
21018
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21019
+ )
20691
21020
  });
20692
21021
  var type = defineCommand({
20693
21022
  name: "type",
@@ -20696,7 +21025,10 @@ var type = defineCommand({
20696
21025
  positional: ["text"],
20697
21026
  params: params13,
20698
21027
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20699
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21028
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21029
+ params17.session,
21030
+ env
21031
+ );
20700
21032
  await namedSession.session.type(params17.text);
20701
21033
  return void 0;
20702
21034
  }
@@ -20774,9 +21106,17 @@ async function folderExists(fs4, folderPath) {
20774
21106
 
20775
21107
  // src/commands/wait-for.ts
20776
21108
  var params15 = S.Object({
20777
- pattern: S.String({ description: "Regular expression pattern to wait for" }),
20778
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20779
- timeout: S.Optional(S.Number({ short: "t", description: "Maximum wait time in milliseconds" })),
21109
+ pattern: S.String({
21110
+ description: "Regular expression pattern to wait for",
21111
+ minLength: 1,
21112
+ pattern: "\\S"
21113
+ }),
21114
+ session: S.Optional(
21115
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21116
+ ),
21117
+ timeout: S.Optional(
21118
+ S.Number({ short: "t", description: "Maximum wait time in milliseconds", minimum: 0 })
21119
+ ),
20780
21120
  literal: S.Optional(
20781
21121
  S.Boolean({
20782
21122
  short: "l",
@@ -20791,17 +21131,33 @@ var waitFor = defineCommand({
20791
21131
  positional: ["pattern"],
20792
21132
  params: params15,
20793
21133
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20794
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21134
+ if (params17.pattern.trim().length === 0) {
21135
+ throw new UserError("Wait pattern must not be empty.");
21136
+ }
21137
+ assertTimeout2(params17.timeout);
21138
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21139
+ params17.session,
21140
+ env
21141
+ );
20795
21142
  const pattern = params17.literal === true ? params17.pattern : new RegExp(params17.pattern);
20796
21143
  const line = params17.timeout === void 0 ? await namedSession.session.waitFor(pattern) : await namedSession.session.waitFor(pattern, { timeout: params17.timeout });
20797
21144
  return { matched: true, line };
20798
21145
  }
20799
21146
  });
21147
+ function assertTimeout2(timeout) {
21148
+ if (timeout !== void 0 && (!Number.isFinite(timeout) || timeout < 0)) {
21149
+ throw new UserError("Timeout must be a finite non-negative number.");
21150
+ }
21151
+ }
20800
21152
 
20801
21153
  // src/commands/wait-for-exit.ts
20802
21154
  var params16 = S.Object({
20803
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20804
- timeout: S.Optional(S.Number({ short: "t", description: "Maximum wait time in milliseconds" }))
21155
+ session: S.Optional(
21156
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21157
+ ),
21158
+ timeout: S.Optional(
21159
+ S.Number({ short: "t", description: "Maximum wait time in milliseconds", minimum: 0 })
21160
+ )
20805
21161
  });
20806
21162
  var waitForExit2 = defineCommand({
20807
21163
  name: "wait-for-exit",
@@ -20809,7 +21165,13 @@ var waitForExit2 = defineCommand({
20809
21165
  scope: ["cli", "mcp", "sdk"],
20810
21166
  params: params16,
20811
21167
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20812
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21168
+ if (params17.timeout !== void 0 && (!Number.isFinite(params17.timeout) || params17.timeout < 0)) {
21169
+ throw new UserError("Timeout must be a finite non-negative number.");
21170
+ }
21171
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21172
+ params17.session,
21173
+ env
21174
+ );
20813
21175
  const exitCode = await namedSession.session.waitForExit(
20814
21176
  params17.timeout === void 0 ? void 0 : { timeout: params17.timeout }
20815
21177
  );