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
@@ -12574,10 +12574,15 @@ async function writeErrorReport(context) {
12574
12574
 
12575
12575
  // ../toolcraft/src/number-schema.ts
12576
12576
  function isValidNumberSchemaValue(value, schema) {
12577
- return typeof value === "number" && Number.isFinite(value) && (schema.jsonType !== "integer" || Number.isInteger(value));
12577
+ 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);
12578
12578
  }
12579
12579
  function getExpectedNumberDescription(schema) {
12580
- return schema.jsonType === "integer" ? "an integer" : "a number";
12580
+ const type2 = schema.jsonType === "integer" ? "an integer" : "a number";
12581
+ const bounds = [
12582
+ schema.minimum === void 0 ? void 0 : `greater than or equal to ${schema.minimum}`,
12583
+ schema.maximum === void 0 ? void 0 : `less than or equal to ${schema.maximum}`
12584
+ ].filter((bound) => bound !== void 0);
12585
+ return bounds.length === 0 ? type2 : `${type2} ${bounds.join(" and ")}`;
12581
12586
  }
12582
12587
 
12583
12588
  // ../toolcraft/src/renderer.ts
@@ -13406,10 +13411,17 @@ function parseEnumValue(value, values, label) {
13406
13411
  return match;
13407
13412
  }
13408
13413
  function validateStringPattern(value, schema, label) {
13409
- if (schema.pattern === void 0) {
13410
- return value;
13414
+ if (schema.minLength !== void 0 && value.length < schema.minLength) {
13415
+ throw new UserError(
13416
+ `Invalid value for "${label}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`
13417
+ );
13411
13418
  }
13412
- if (!matchesStringPattern(value, schema.pattern)) {
13419
+ if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
13420
+ throw new UserError(
13421
+ `Invalid value for "${label}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`
13422
+ );
13423
+ }
13424
+ if (schema.pattern !== void 0 && !matchesStringPattern(value, schema.pattern)) {
13413
13425
  throw new UserError(
13414
13426
  `Invalid value for "${label}": "${value}" does not match pattern "${schema.pattern}".`
13415
13427
  );
@@ -13591,6 +13603,18 @@ function parseArrayValue(value, schema, label) {
13591
13603
  (item) => parseScalarValue(item, itemSchema, label)
13592
13604
  );
13593
13605
  }
13606
+ function validateArrayBounds(value, schema, label) {
13607
+ if (schema.minItems !== void 0 && value.length < schema.minItems) {
13608
+ throw new UserError(
13609
+ `Invalid value for "${label}". Expected an array with at least ${schema.minItems} items, got array(${value.length}).`
13610
+ );
13611
+ }
13612
+ if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
13613
+ throw new UserError(
13614
+ `Invalid value for "${label}". Expected an array with at most ${schema.maxItems} items, got array(${value.length}).`
13615
+ );
13616
+ }
13617
+ }
13594
13618
  function createOption(field, globalLongOptionFlags) {
13595
13619
  const flags = formatOptionFlags(field, globalLongOptionFlags);
13596
13620
  const collidesWithGlobalFlag = globalLongOptionFlags.has(field.optionFlag);
@@ -14560,6 +14584,9 @@ function describeExpectedPresetValue(schema) {
14560
14584
  if (schema.kind === "array") {
14561
14585
  return "an array";
14562
14586
  }
14587
+ if (schema.kind === "number") {
14588
+ return getExpectedNumberDescription(schema);
14589
+ }
14563
14590
  if (schema.kind === "json") {
14564
14591
  return "valid JSON";
14565
14592
  }
@@ -14577,6 +14604,16 @@ function validatePresetScalarValue(value, schema, fieldPath, presetPath) {
14577
14604
  if (typeof value !== "string") {
14578
14605
  break;
14579
14606
  }
14607
+ if (schema.minLength !== void 0 && value.length < schema.minLength) {
14608
+ throw new UserError(
14609
+ `Preset file "${presetPath}" has an invalid value for "${fieldPath}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`
14610
+ );
14611
+ }
14612
+ if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
14613
+ throw new UserError(
14614
+ `Preset file "${presetPath}" has an invalid value for "${fieldPath}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`
14615
+ );
14616
+ }
14580
14617
  if (schema.pattern !== void 0 && !matchesStringPattern(value, schema.pattern)) {
14581
14618
  throw new UserError(
14582
14619
  `Preset file "${presetPath}" has an invalid value for "${fieldPath}": "${value}" does not match pattern "${schema.pattern}".`
@@ -14626,6 +14663,16 @@ function validatePresetFieldValue(value, field, presetPath) {
14626
14663
  `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array, got ${describeReceived(value)}.`
14627
14664
  );
14628
14665
  }
14666
+ if (field.schema.minItems !== void 0 && value.length < field.schema.minItems) {
14667
+ throw new UserError(
14668
+ `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array with at least ${field.schema.minItems} items, got array(${value.length}).`
14669
+ );
14670
+ }
14671
+ if (field.schema.maxItems !== void 0 && value.length > field.schema.maxItems) {
14672
+ throw new UserError(
14673
+ `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array with at most ${field.schema.maxItems} items, got array(${value.length}).`
14674
+ );
14675
+ }
14629
14676
  return value.map(
14630
14677
  (item) => validatePresetScalarValue(item, itemSchema, field.displayPath, presetPath)
14631
14678
  );
@@ -15035,12 +15082,17 @@ function parseOptionFieldValue(field, value, errors2) {
15035
15082
  }
15036
15083
  parsedValues.push(...parsed);
15037
15084
  }
15085
+ validateArrayBounds(parsedValues, field.schema, field.displayPath);
15038
15086
  return { ok: true, value: parsedValues };
15039
15087
  }
15040
15088
  if (typeof value !== "string") {
15041
15089
  return { ok: true, value };
15042
15090
  }
15043
- return { ok: true, value: parseFieldInputValue(value, field.schema, field.displayPath) };
15091
+ const parsedValue = parseFieldInputValue(value, field.schema, field.displayPath);
15092
+ if (field.schema.kind === "array" && Array.isArray(parsedValue)) {
15093
+ validateArrayBounds(parsedValue, field.schema, field.displayPath);
15094
+ }
15095
+ return { ok: true, value: parsedValue };
15044
15096
  } catch (error3) {
15045
15097
  if (error3 instanceof UserError || error3 instanceof InvalidArgumentError) {
15046
15098
  errors2.push({
@@ -15101,6 +15153,7 @@ function consumeFieldValue(args, index, schema, label, inlineValue) {
15101
15153
  if (values.length === 0) {
15102
15154
  throw new InvalidArgumentError(`option '${label}' argument missing`);
15103
15155
  }
15156
+ validateArrayBounds(values, schema, label);
15104
15157
  return {
15105
15158
  nextIndex,
15106
15159
  value: values
@@ -16474,6 +16527,10 @@ var TerminalBuffer = class {
16474
16527
  }
16475
16528
  _writePrintable(ch) {
16476
16529
  const width = this._cellWidth(ch);
16530
+ if (width === 0) {
16531
+ this._appendCombiningMark(ch);
16532
+ return;
16533
+ }
16477
16534
  if (this._autoWrap && this._pendingWrap) {
16478
16535
  this._cursorX = 0;
16479
16536
  this._newline();
@@ -16508,11 +16565,40 @@ var TerminalBuffer = class {
16508
16565
  _cellWidth(ch) {
16509
16566
  const codePoint = ch.codePointAt(0);
16510
16567
  if (codePoint === void 0) return 0;
16568
+ if (isCombiningCodePoint2(codePoint)) {
16569
+ return 0;
16570
+ }
16511
16571
  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) {
16512
16572
  return Math.min(2, this._cols);
16513
16573
  }
16514
16574
  return 1;
16515
16575
  }
16576
+ _appendCombiningMark(ch) {
16577
+ const target = this._findCombiningTarget();
16578
+ if (target === null) {
16579
+ return;
16580
+ }
16581
+ const cell = this._screen[target.y]?.[target.x];
16582
+ if (cell === null || cell === void 0) {
16583
+ return;
16584
+ }
16585
+ cell[1] += ch;
16586
+ }
16587
+ _findCombiningTarget() {
16588
+ const startX = this._pendingWrap ? this._cursorX : this._cursorX - 1;
16589
+ for (let y = this._cursorY; y >= 0; y -= 1) {
16590
+ const row = this._screen[y];
16591
+ if (row === void 0) {
16592
+ continue;
16593
+ }
16594
+ for (let x = y === this._cursorY ? startX : this._cols - 1; x >= 0; x -= 1) {
16595
+ if (row[x] !== null) {
16596
+ return { x, y };
16597
+ }
16598
+ }
16599
+ }
16600
+ return null;
16601
+ }
16516
16602
  _setChar(y, x, ch) {
16517
16603
  const row = this._screen[y];
16518
16604
  if (row && x >= 0 && x < this._cols) {
@@ -16653,7 +16739,8 @@ var TerminalBuffer = class {
16653
16739
  case "J":
16654
16740
  if (p0 === 0) {
16655
16741
  this._eraseLine(this._cursorY, this._cursorX, this._cols - 1);
16656
- for (let y = this._cursorY + 1; y < this._rows; y++) this._eraseLine(y, 0, this._cols - 1);
16742
+ for (let y = this._cursorY + 1; y < this._rows; y++)
16743
+ this._eraseLine(y, 0, this._cols - 1);
16657
16744
  } else if (p0 === 1) {
16658
16745
  for (let y = 0; y < this._cursorY; y++) this._eraseLine(y, 0, this._cols - 1);
16659
16746
  this._eraseLine(this._cursorY, 0, this._cursorX);
@@ -17018,6 +17105,9 @@ function createDefaultStyleState() {
17018
17105
  strikethrough: false
17019
17106
  };
17020
17107
  }
17108
+ function isCombiningCodePoint2(codePoint) {
17109
+ return codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071;
17110
+ }
17021
17111
  function serializeStyleState(state) {
17022
17112
  const codes = [];
17023
17113
  if (state.bold) {
@@ -17071,6 +17161,8 @@ var NAMED_KEY_LOWER = new Map(
17071
17161
  Object.entries(NAMED_KEY_SEQUENCES).map(([k, v]) => [k.toLowerCase(), v])
17072
17162
  );
17073
17163
  var VALID_KEYS_HINT = `Valid keys: ${Object.keys(NAMED_KEY_SEQUENCES).join(", ")}, Control+<letter>, Alt+<key>`;
17164
+ var NAMED_KEY_PATTERN = Object.keys(NAMED_KEY_SEQUENCES).map(caseInsensitivePattern).join("|");
17165
+ var TERMINAL_KEY_PATTERN = `^(?:${NAMED_KEY_PATTERN}|.|[Cc][Oo][Nn][Tt][Rr][Oo][Ll]\\+[A-Za-z]|[Aa][Ll][Tt]\\+.+)$`;
17074
17166
  function unknownKeyError(key2) {
17075
17167
  return new Error(`Unknown terminal key: ${key2}. ${VALID_KEYS_HINT}`);
17076
17168
  }
@@ -17113,6 +17205,18 @@ function controlKeyToSequence(controlKey) {
17113
17205
  }
17114
17206
  return String.fromCharCode(charCode - 64);
17115
17207
  }
17208
+ function caseInsensitivePattern(value) {
17209
+ let pattern = "";
17210
+ for (const character of value) {
17211
+ const lower = character.toLowerCase();
17212
+ const upper = character.toUpperCase();
17213
+ pattern += lower === upper ? escapePatternCharacter(character) : `[${upper}${lower}]`;
17214
+ }
17215
+ return pattern;
17216
+ }
17217
+ function escapePatternCharacter(character) {
17218
+ return character.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
17219
+ }
17116
17220
 
17117
17221
  // src/terminal-screen.ts
17118
17222
  var TerminalScreen = class {
@@ -17552,7 +17656,11 @@ function createTerminalPilotRuntime(options = {}) {
17552
17656
  const pendingNames = /* @__PURE__ */ new Set();
17553
17657
  let pilotPromise;
17554
17658
  function getRequestedName(name, env) {
17555
- return name ?? env?.get(SESSION_ENV_VAR);
17659
+ const requestedName = name ?? env?.get(SESSION_ENV_VAR);
17660
+ if (requestedName !== void 0 && requestedName.trim().length === 0) {
17661
+ throw new UserError("Session name must not be empty.");
17662
+ }
17663
+ return requestedName;
17556
17664
  }
17557
17665
  async function getPilot() {
17558
17666
  pilotPromise ??= launchPilot();
@@ -17588,7 +17696,9 @@ function createTerminalPilotRuntime(options = {}) {
17588
17696
  const sessionId = nameToId.get(name);
17589
17697
  if (sessionId === void 0) {
17590
17698
  const active = await listSessions2();
17591
- throw new UserError(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
17699
+ throw new UserError(
17700
+ `Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
17701
+ );
17592
17702
  }
17593
17703
  const pilot = await getPilot();
17594
17704
  try {
@@ -17596,7 +17706,9 @@ function createTerminalPilotRuntime(options = {}) {
17596
17706
  } catch {
17597
17707
  forgetSession(name, sessionId);
17598
17708
  const active = await listSessions2();
17599
- throw new UserError(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
17709
+ throw new UserError(
17710
+ `Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
17711
+ );
17600
17712
  }
17601
17713
  }
17602
17714
  async function listSessions2() {
@@ -17627,6 +17739,9 @@ function createTerminalPilotRuntime(options = {}) {
17627
17739
  }
17628
17740
  return {
17629
17741
  async createSession(params17, env) {
17742
+ if (params17.command.trim().length === 0) {
17743
+ throw new UserError("Command must not be empty.");
17744
+ }
17630
17745
  const requestedName = getRequestedName(params17.session, env) ?? nextSessionName();
17631
17746
  await discardExitedSessionName(requestedName);
17632
17747
  if (nameToId.has(requestedName) || pendingNames.has(requestedName)) {
@@ -17699,7 +17814,9 @@ async function closeSharedTerminalPilotRuntime() {
17699
17814
 
17700
17815
  // src/commands/close-session.ts
17701
17816
  var params = S.Object({
17702
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17817
+ session: S.Optional(
17818
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17819
+ )
17703
17820
  });
17704
17821
  var closeSession = defineCommand({
17705
17822
  name: "close-session",
@@ -17707,19 +17824,28 @@ var closeSession = defineCommand({
17707
17824
  scope: ["cli", "mcp", "sdk"],
17708
17825
  params,
17709
17826
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17710
- const { exitCode } = await getTerminalPilotRuntime(terminalPilotRuntime).closeSession(params17.session, env);
17827
+ const { exitCode } = await getTerminalPilotRuntime(terminalPilotRuntime).closeSession(
17828
+ params17.session,
17829
+ env
17830
+ );
17711
17831
  return { exitCode };
17712
17832
  }
17713
17833
  });
17714
17834
 
17715
17835
  // src/commands/create-session.ts
17716
17836
  var params2 = S.Object({
17717
- command: S.String({ description: "Command to execute" }),
17837
+ command: S.String({ description: "Command to execute", minLength: 1, pattern: "\\S" }),
17718
17838
  args: S.Optional(S.Array(S.String(), { description: "Command arguments" })),
17719
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
17839
+ session: S.Optional(
17840
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17841
+ ),
17720
17842
  cwd: S.Optional(S.String({ description: "Working directory" })),
17721
- cols: S.Optional(S.Number({ description: "Terminal width in columns" })),
17722
- rows: S.Optional(S.Number({ description: "Terminal height in rows" })),
17843
+ cols: S.Optional(
17844
+ S.Number({ description: "Terminal width in columns", jsonType: "integer", minimum: 1 })
17845
+ ),
17846
+ rows: S.Optional(
17847
+ S.Number({ description: "Terminal height in rows", jsonType: "integer", minimum: 1 })
17848
+ ),
17723
17849
  observe: S.Optional(S.Boolean({ description: "Mirror PTY output to stderr" }))
17724
17850
  });
17725
17851
  var createSession = defineCommand({
@@ -17729,7 +17855,10 @@ var createSession = defineCommand({
17729
17855
  positional: ["command", "args"],
17730
17856
  params: params2,
17731
17857
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17732
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).createSession(params17, env);
17858
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).createSession(
17859
+ params17,
17860
+ env
17861
+ );
17733
17862
  return { session: namedSession.name, pid: namedSession.session.pid };
17734
17863
  }
17735
17864
  });
@@ -17737,7 +17866,9 @@ var createSession = defineCommand({
17737
17866
  // src/commands/fill.ts
17738
17867
  var params3 = S.Object({
17739
17868
  text: S.String({ description: "Text to write to the session" }),
17740
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17869
+ session: S.Optional(
17870
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17871
+ )
17741
17872
  });
17742
17873
  var fill = defineCommand({
17743
17874
  name: "fill",
@@ -17746,7 +17877,10 @@ var fill = defineCommand({
17746
17877
  positional: ["text"],
17747
17878
  params: params3,
17748
17879
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17749
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
17880
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
17881
+ params17.session,
17882
+ env
17883
+ );
17750
17884
  await namedSession.session.fill(params17.text);
17751
17885
  return void 0;
17752
17886
  }
@@ -17754,7 +17888,9 @@ var fill = defineCommand({
17754
17888
 
17755
17889
  // src/commands/get-session.ts
17756
17890
  var params4 = S.Object({
17757
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17891
+ session: S.Optional(
17892
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17893
+ )
17758
17894
  });
17759
17895
  var getSession = defineCommand({
17760
17896
  name: "get-session",
@@ -17762,7 +17898,10 @@ var getSession = defineCommand({
17762
17898
  scope: ["cli", "mcp", "sdk"],
17763
17899
  params: params4,
17764
17900
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17765
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
17901
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
17902
+ params17.session,
17903
+ env
17904
+ );
17766
17905
  return {
17767
17906
  session: namedSession.name,
17768
17907
  pid: namedSession.session.pid,
@@ -17790,7 +17929,7 @@ var claudeCodeAgent = {
17790
17929
  CLAUDE_CODE_ENABLE_TELEMETRY: "1"
17791
17930
  }
17792
17931
  },
17793
- configPath: "~/.claude/settings.json",
17932
+ configPath: "~/.claude.json",
17794
17933
  branding: {
17795
17934
  colors: {
17796
17935
  dark: "#C15F3C",
@@ -17805,7 +17944,12 @@ var claudeDesktopAgent = {
17805
17944
  name: "claude-desktop",
17806
17945
  label: "Claude Desktop",
17807
17946
  summary: "Anthropic's official desktop application for Claude",
17808
- configPath: "~/.claude/settings.json",
17947
+ configPath: "~/.config/Claude/claude_desktop_config.json",
17948
+ configPaths: {
17949
+ darwin: "~/Library/Application Support/Claude/claude_desktop_config.json",
17950
+ linux: "~/.config/Claude/claude_desktop_config.json",
17951
+ win32: "~/AppData/Roaming/Claude/claude_desktop_config.json"
17952
+ },
17809
17953
  branding: {
17810
17954
  colors: {
17811
17955
  dark: "#D97757",
@@ -17849,7 +17993,7 @@ var cursorAgent = {
17849
17993
  label: "Cursor",
17850
17994
  summary: "Cursor's CLI coding agent.",
17851
17995
  binaryName: "cursor-agent",
17852
- configPath: "~/.cursor/cli-config.json",
17996
+ configPath: "~/.cursor/mcp.json",
17853
17997
  branding: {
17854
17998
  colors: {
17855
17999
  dark: "#FFFFFF",
@@ -17889,7 +18033,7 @@ var openCodeAgent = {
17889
18033
  OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
17890
18034
  }
17891
18035
  },
17892
- configPath: "~/.config/opencode/config.json",
18036
+ configPath: "~/.config/opencode/opencode.json",
17893
18037
  branding: {
17894
18038
  colors: {
17895
18039
  dark: "#4A4F55",
@@ -17907,7 +18051,7 @@ var kimiAgent = {
17907
18051
  aliases: ["kimi-cli"],
17908
18052
  binaryName: "kimi",
17909
18053
  apiShapes: ["openai-chat-completions"],
17910
- configPath: "~/.kimi/config.toml",
18054
+ configPath: "~/.kimi/mcp.json",
17911
18055
  branding: {
17912
18056
  colors: {
17913
18057
  dark: "#7B68EE",
@@ -19607,8 +19751,10 @@ var listSessions = defineCommand({
19607
19751
 
19608
19752
  // src/commands/press-key.ts
19609
19753
  var params7 = S.Object({
19610
- key: S.String({ description: "Named key to press" }),
19611
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19754
+ key: S.String({ description: "Named key to press", pattern: TERMINAL_KEY_PATTERN }),
19755
+ session: S.Optional(
19756
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19757
+ )
19612
19758
  });
19613
19759
  var pressKey = defineCommand({
19614
19760
  name: "press-key",
@@ -19617,16 +19763,36 @@ var pressKey = defineCommand({
19617
19763
  positional: ["key"],
19618
19764
  params: params7,
19619
19765
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19620
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19766
+ assertTerminalKey(params17.key);
19767
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19768
+ params17.session,
19769
+ env
19770
+ );
19621
19771
  await namedSession.session.press(params17.key);
19622
19772
  return void 0;
19623
19773
  }
19624
19774
  });
19775
+ function assertTerminalKey(key2) {
19776
+ try {
19777
+ keyToSequence(key2);
19778
+ } catch (error3) {
19779
+ throw new UserError(error3 instanceof Error ? error3.message : String(error3));
19780
+ }
19781
+ }
19625
19782
 
19626
19783
  // src/commands/read-history.ts
19627
19784
  var params8 = S.Object({
19628
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
19629
- last: S.Optional(S.Number({ short: "n", description: "Return only the last N lines" }))
19785
+ session: S.Optional(
19786
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19787
+ ),
19788
+ last: S.Optional(
19789
+ S.Number({
19790
+ short: "n",
19791
+ description: "Return only the last N lines",
19792
+ jsonType: "integer",
19793
+ minimum: 0
19794
+ })
19795
+ )
19630
19796
  });
19631
19797
  var readHistory = defineCommand({
19632
19798
  name: "read-history",
@@ -19634,7 +19800,10 @@ var readHistory = defineCommand({
19634
19800
  scope: ["cli", "mcp", "sdk"],
19635
19801
  params: params8,
19636
19802
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19637
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19803
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19804
+ params17.session,
19805
+ env
19806
+ );
19638
19807
  const lines = await namedSession.session.history({ last: params17.last });
19639
19808
  return { lines, exitCode: namedSession.session.exitCode };
19640
19809
  }
@@ -19642,7 +19811,9 @@ var readHistory = defineCommand({
19642
19811
 
19643
19812
  // src/commands/read-screen.ts
19644
19813
  var params9 = S.Object({
19645
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19814
+ session: S.Optional(
19815
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19816
+ )
19646
19817
  });
19647
19818
  var readScreen = defineCommand({
19648
19819
  name: "read-screen",
@@ -19650,7 +19821,10 @@ var readScreen = defineCommand({
19650
19821
  scope: ["cli", "mcp", "sdk"],
19651
19822
  params: params9,
19652
19823
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19653
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19824
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19825
+ params17.session,
19826
+ env
19827
+ );
19654
19828
  const screen = await namedSession.session.screen();
19655
19829
  return {
19656
19830
  lines: [...screen.lines],
@@ -19663,9 +19837,11 @@ var readScreen = defineCommand({
19663
19837
 
19664
19838
  // src/commands/resize.ts
19665
19839
  var params10 = S.Object({
19666
- cols: S.Number({ description: "Terminal width in columns" }),
19667
- rows: S.Number({ description: "Terminal height in rows" }),
19668
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19840
+ cols: S.Number({ description: "Terminal width in columns", jsonType: "integer", minimum: 1 }),
19841
+ rows: S.Number({ description: "Terminal height in rows", jsonType: "integer", minimum: 1 }),
19842
+ session: S.Optional(
19843
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19844
+ )
19669
19845
  });
19670
19846
  var resize = defineCommand({
19671
19847
  name: "resize",
@@ -19673,7 +19849,10 @@ var resize = defineCommand({
19673
19849
  scope: ["cli", "mcp", "sdk"],
19674
19850
  params: params10,
19675
19851
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19676
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19852
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19853
+ params17.session,
19854
+ env
19855
+ );
19677
19856
  await namedSession.session.resize(params17.cols, params17.rows);
19678
19857
  return void 0;
19679
19858
  }
@@ -19685,6 +19864,9 @@ import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises
19685
19864
 
19686
19865
  // ../terminal-png/src/ansi-parser.ts
19687
19866
  var ESC2 = "\x1B";
19867
+ var TAB_WIDTH = 8;
19868
+ var MAX_TERMINAL_ROWS = 1e3;
19869
+ var MAX_TERMINAL_COLUMNS = 1e3;
19688
19870
  function createDefaultStyle() {
19689
19871
  return {
19690
19872
  fg: null,
@@ -19969,10 +20151,34 @@ function positionParameter(params17, index, fallback) {
19969
20151
  const value = toInteger(params17.split(";")[index]);
19970
20152
  return value === null || value < 1 ? fallback : value;
19971
20153
  }
20154
+ function modeParameter(params17, fallback) {
20155
+ const value = toInteger(params17.split(";")[0]);
20156
+ return value === null ? fallback : value;
20157
+ }
20158
+ function displayWidth3(text4) {
20159
+ if (text4 === " ") {
20160
+ return TAB_WIDTH;
20161
+ }
20162
+ const codePoint = text4.codePointAt(0);
20163
+ if (codePoint === void 0) {
20164
+ return 0;
20165
+ }
20166
+ 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) {
20167
+ return 2;
20168
+ }
20169
+ return 1;
20170
+ }
20171
+ function hasRenderableCell(line) {
20172
+ return (line ?? []).some((cell) => cell !== void 0 && cell.text.length > 0);
20173
+ }
19972
20174
  function buildRuns(lines, lineBreakStyles) {
19973
20175
  const runs = [];
19974
20176
  const defaultStyle = createDefaultStyle();
19975
- for (let row = 0; row < lines.length; row += 1) {
20177
+ let lastRow = lines.length - 1;
20178
+ while (lastRow > 0 && !hasRenderableCell(lines[lastRow]) && lineBreakStyles[lastRow - 1] === void 0) {
20179
+ lastRow -= 1;
20180
+ }
20181
+ for (let row = 0; row <= lastRow; row += 1) {
19976
20182
  const line = lines[row] ?? [];
19977
20183
  let lastCell = line.length - 1;
19978
20184
  while (lastCell >= 0 && line[lastCell] === void 0) {
@@ -19982,7 +20188,7 @@ function buildRuns(lines, lineBreakStyles) {
19982
20188
  const cell = line[column] ?? { text: " ", style: defaultStyle };
19983
20189
  pushRun(runs, cell.style, cell.text);
19984
20190
  }
19985
- if (row < lines.length - 1) {
20191
+ if (row < lastRow) {
19986
20192
  pushRun(runs, lineBreakStyles[row] ?? defaultStyle, "\n");
19987
20193
  }
19988
20194
  }
@@ -19994,7 +20200,21 @@ function parseAnsi2(input) {
19994
20200
  let style = createDefaultStyle();
19995
20201
  let row = 0;
19996
20202
  let column = 0;
20203
+ let savedRow = 0;
20204
+ let savedColumn = 0;
19997
20205
  let index = 0;
20206
+ const clampRow = (nextRow) => {
20207
+ if (nextRow < 0) {
20208
+ return 0;
20209
+ }
20210
+ return Math.min(nextRow, MAX_TERMINAL_ROWS - 1);
20211
+ };
20212
+ const clampColumn = (nextColumn) => {
20213
+ if (nextColumn < 0) {
20214
+ return 0;
20215
+ }
20216
+ return Math.min(nextColumn, MAX_TERMINAL_COLUMNS - 1);
20217
+ };
19998
20218
  const ensureLine = () => {
19999
20219
  while (lines.length <= row) {
20000
20220
  lines.push([]);
@@ -20002,12 +20222,64 @@ function parseAnsi2(input) {
20002
20222
  };
20003
20223
  const moveDown = (keepColumn) => {
20004
20224
  lineBreakStyles[row] = cloneStyle(style);
20005
- row += 1;
20225
+ row = clampRow(row + 1);
20006
20226
  if (!keepColumn) {
20007
20227
  column = 0;
20008
20228
  }
20009
20229
  ensureLine();
20010
20230
  };
20231
+ const eraseLine = (mode) => {
20232
+ const line = lines[row] ?? [];
20233
+ if (mode === 1) {
20234
+ for (let cell = 0; cell <= column; cell += 1) {
20235
+ delete line[cell];
20236
+ }
20237
+ return;
20238
+ }
20239
+ if (mode === 2) {
20240
+ lines[row] = [];
20241
+ return;
20242
+ }
20243
+ line.splice(column);
20244
+ };
20245
+ const eraseDisplay = (mode) => {
20246
+ if (mode === 1) {
20247
+ for (let lineRow = 0; lineRow < row; lineRow += 1) {
20248
+ lines[lineRow] = [];
20249
+ }
20250
+ eraseLine(1);
20251
+ return;
20252
+ }
20253
+ if (mode === 2 || mode === 3) {
20254
+ lines.length = 0;
20255
+ lineBreakStyles.length = 0;
20256
+ ensureLine();
20257
+ return;
20258
+ }
20259
+ eraseLine(0);
20260
+ lines.splice(row + 1);
20261
+ lineBreakStyles.splice(row);
20262
+ };
20263
+ const saveCursor = () => {
20264
+ savedRow = row;
20265
+ savedColumn = column;
20266
+ };
20267
+ const restoreCursor = () => {
20268
+ row = clampRow(savedRow);
20269
+ column = clampColumn(savedColumn);
20270
+ ensureLine();
20271
+ };
20272
+ const writeText = (text4) => {
20273
+ const width = displayWidth3(text4);
20274
+ if (width === 0) {
20275
+ return;
20276
+ }
20277
+ lines[row][column] = { text: text4, style: cloneStyle(style) };
20278
+ for (let offset = 1; offset < width && column + offset < MAX_TERMINAL_COLUMNS; offset += 1) {
20279
+ lines[row][column + offset] = { text: "", style: cloneStyle(style) };
20280
+ }
20281
+ column = clampColumn(column + width);
20282
+ };
20011
20283
  while (index < input.length) {
20012
20284
  const char = input[index];
20013
20285
  if (char === "\n") {
@@ -20030,38 +20302,73 @@ function parseAnsi2(input) {
20030
20302
  index += 1;
20031
20303
  continue;
20032
20304
  }
20305
+ if (char === " ") {
20306
+ const nextTabStop = Math.min(
20307
+ Math.floor(column / TAB_WIDTH) * TAB_WIDTH + TAB_WIDTH,
20308
+ MAX_TERMINAL_COLUMNS
20309
+ );
20310
+ while (column < nextTabStop) {
20311
+ writeText(" ");
20312
+ }
20313
+ index += 1;
20314
+ continue;
20315
+ }
20033
20316
  if (char === ESC2 && input[index + 1] === "]") {
20034
20317
  index = parseOscEnd(input, index);
20035
20318
  continue;
20036
20319
  }
20320
+ if (char === ESC2 && input[index + 1] === "7") {
20321
+ saveCursor();
20322
+ index += 2;
20323
+ continue;
20324
+ }
20325
+ if (char === ESC2 && input[index + 1] === "8") {
20326
+ restoreCursor();
20327
+ index += 2;
20328
+ continue;
20329
+ }
20037
20330
  const csiPrefixLength = char === "\x9B" ? 1 : char === ESC2 && input[index + 1] === "[" ? 2 : null;
20038
20331
  if (csiPrefixLength !== null) {
20039
20332
  const sequence = parseCsi(input, index, csiPrefixLength);
20040
20333
  if (sequence.final === "m") {
20041
20334
  style = applySgr(style, sequence.params);
20042
20335
  } else if (sequence.final === "G") {
20043
- column = positionParameter(sequence.params, 0, 1) - 1;
20336
+ column = clampColumn(positionParameter(sequence.params, 0, 1) - 1);
20044
20337
  } else if (sequence.final === "C") {
20045
- column += positionParameter(sequence.params, 0, 1);
20338
+ column = clampColumn(column + positionParameter(sequence.params, 0, 1));
20046
20339
  } else if (sequence.final === "D") {
20047
20340
  column = Math.max(0, column - positionParameter(sequence.params, 0, 1));
20048
20341
  } else if (sequence.final === "A") {
20049
- row = Math.max(0, row - positionParameter(sequence.params, 0, 1));
20342
+ row = clampRow(row - positionParameter(sequence.params, 0, 1));
20050
20343
  } else if (sequence.final === "B") {
20051
- row += positionParameter(sequence.params, 0, 1);
20344
+ row = clampRow(row + positionParameter(sequence.params, 0, 1));
20052
20345
  ensureLine();
20346
+ } else if (sequence.final === "E") {
20347
+ row = clampRow(row + positionParameter(sequence.params, 0, 1));
20348
+ column = 0;
20349
+ ensureLine();
20350
+ } else if (sequence.final === "F") {
20351
+ row = clampRow(row - positionParameter(sequence.params, 0, 1));
20352
+ column = 0;
20053
20353
  } else if (sequence.final === "H" || sequence.final === "f") {
20054
- row = positionParameter(sequence.params, 0, 1) - 1;
20055
- column = positionParameter(sequence.params, 1, 1) - 1;
20354
+ row = clampRow(positionParameter(sequence.params, 0, 1) - 1);
20355
+ column = clampColumn(positionParameter(sequence.params, 1, 1) - 1);
20056
20356
  ensureLine();
20357
+ } else if (sequence.final === "K") {
20358
+ eraseLine(modeParameter(sequence.params, 0));
20359
+ } else if (sequence.final === "J") {
20360
+ eraseDisplay(modeParameter(sequence.params, 0));
20361
+ } else if (sequence.final === "s") {
20362
+ saveCursor();
20363
+ } else if (sequence.final === "u") {
20364
+ restoreCursor();
20057
20365
  }
20058
20366
  index = sequence.end;
20059
20367
  continue;
20060
20368
  }
20061
20369
  const codePoint = input.codePointAt(index);
20062
20370
  const text4 = codePoint === void 0 ? "" : String.fromCodePoint(codePoint);
20063
- lines[row][column] = { text: text4, style: cloneStyle(style) };
20064
- column += 1;
20371
+ writeText(text4);
20065
20372
  index += text4.length;
20066
20373
  }
20067
20374
  return buildRuns(lines, lineBreakStyles);
@@ -20469,11 +20776,11 @@ function splitIntoLines(runs) {
20469
20776
  }
20470
20777
  function measureLines(lines) {
20471
20778
  return Math.max(
20472
- ...lines.map((line) => displayWidth3(line.map((run) => run.text).join("")) * CHARACTER_WIDTH),
20779
+ ...lines.map((line) => displayWidth4(line.map((run) => run.text).join("")) * CHARACTER_WIDTH),
20473
20780
  0
20474
20781
  );
20475
20782
  }
20476
- function displayWidth3(text4, startColumn = 0) {
20783
+ function displayWidth4(text4, startColumn = 0) {
20477
20784
  const segmenter = new Intl.Segmenter();
20478
20785
  let column = startColumn;
20479
20786
  for (const { segment } of segmenter.segment(text4)) {
@@ -20535,7 +20842,7 @@ function renderBackgrounds(line, startX, y, height) {
20535
20842
  let column = 0;
20536
20843
  const rectangles = [];
20537
20844
  for (const run of line) {
20538
- const width = displayWidth3(run.text, column);
20845
+ const width = displayWidth4(run.text, column);
20539
20846
  const background = resolveBackgroundColor(run);
20540
20847
  if (background !== BACKGROUND && width > 0) {
20541
20848
  rectangles.push(`<rect x="${formatNumber(startX + column * CHARACTER_WIDTH)}" y="${formatNumber(y)}" width="${formatNumber(width * CHARACTER_WIDTH)}" height="${formatNumber(height)}" fill="${escapeXmlAttribute(background)}" />`);
@@ -20569,7 +20876,7 @@ function renderRun(run) {
20569
20876
  if (run.dim) {
20570
20877
  attributes.push('opacity="0.7"');
20571
20878
  }
20572
- const text4 = run.conceal ? " ".repeat(displayWidth3(run.text)) : run.text;
20879
+ const text4 = run.conceal ? " ".repeat(displayWidth4(run.text)) : run.text;
20573
20880
  return `<tspan ${attributes.join(" ")}>${escapeXmlText(text4)}</tspan>`;
20574
20881
  }
20575
20882
  function renderWindowControls() {
@@ -20618,13 +20925,16 @@ async function renderTerminalPng(ansiText, options = {}) {
20618
20925
  if (options.padding !== void 0 && (!Number.isInteger(options.padding) || options.padding < 0)) {
20619
20926
  throw new Error("Padding must be a non-negative integer.");
20620
20927
  }
20928
+ if (options.output !== void 0 && options.output.length === 0) {
20929
+ throw new Error("Output path must not be empty.");
20930
+ }
20621
20931
  const runs = parseAnsi2(ansiText);
20622
20932
  const svg = renderSvg(runs, {
20623
20933
  padding: options.padding,
20624
20934
  window: options.window
20625
20935
  });
20626
20936
  const png = renderPng(svg);
20627
- if (options.output) {
20937
+ if (options.output !== void 0) {
20628
20938
  const temporaryPath = `${options.output}.${randomUUID10()}.tmp`;
20629
20939
  let temporaryCreated = false;
20630
20940
  try {
@@ -20650,10 +20960,19 @@ function isAlreadyExistsError3(error3) {
20650
20960
 
20651
20961
  // src/commands/screenshot.ts
20652
20962
  var params11 = S.Object({
20653
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20963
+ session: S.Optional(
20964
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
20965
+ ),
20654
20966
  output: S.String({ short: "o", description: "Path to the output PNG file" }),
20655
20967
  window: S.Optional(S.Boolean({ description: "Include terminal window chrome", default: true })),
20656
- padding: S.Optional(S.Number({ short: "p", description: "Padding around terminal content" }))
20968
+ padding: S.Optional(
20969
+ S.Number({
20970
+ short: "p",
20971
+ description: "Padding around terminal content",
20972
+ jsonType: "integer",
20973
+ minimum: 0
20974
+ })
20975
+ )
20657
20976
  });
20658
20977
  var screenshot = defineCommand({
20659
20978
  name: "screenshot",
@@ -20661,7 +20980,10 @@ var screenshot = defineCommand({
20661
20980
  scope: ["cli"],
20662
20981
  params: params11,
20663
20982
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20664
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
20983
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
20984
+ params17.session,
20985
+ env
20986
+ );
20665
20987
  const screen = await namedSession.session.screen();
20666
20988
  await renderTerminalPng(screen.rawLines.join("\n"), {
20667
20989
  output: params17.output,
@@ -20675,7 +20997,9 @@ var screenshot = defineCommand({
20675
20997
  // src/commands/send-signal.ts
20676
20998
  var params12 = S.Object({
20677
20999
  signal: S.String({ description: "Signal to send to the session process" }),
20678
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
21000
+ session: S.Optional(
21001
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21002
+ )
20679
21003
  });
20680
21004
  var sendSignal = defineCommand({
20681
21005
  name: "send-signal",
@@ -20684,7 +21008,10 @@ var sendSignal = defineCommand({
20684
21008
  positional: ["signal"],
20685
21009
  params: params12,
20686
21010
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20687
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21011
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21012
+ params17.session,
21013
+ env
21014
+ );
20688
21015
  await namedSession.session.signal(params17.signal);
20689
21016
  return void 0;
20690
21017
  }
@@ -20693,7 +21020,9 @@ var sendSignal = defineCommand({
20693
21020
  // src/commands/type.ts
20694
21021
  var params13 = S.Object({
20695
21022
  text: S.String({ description: "Text to write to the session" }),
20696
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
21023
+ session: S.Optional(
21024
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21025
+ )
20697
21026
  });
20698
21027
  var type = defineCommand({
20699
21028
  name: "type",
@@ -20702,7 +21031,10 @@ var type = defineCommand({
20702
21031
  positional: ["text"],
20703
21032
  params: params13,
20704
21033
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20705
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21034
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21035
+ params17.session,
21036
+ env
21037
+ );
20706
21038
  await namedSession.session.type(params17.text);
20707
21039
  return void 0;
20708
21040
  }
@@ -20780,9 +21112,17 @@ async function folderExists(fs4, folderPath) {
20780
21112
 
20781
21113
  // src/commands/wait-for.ts
20782
21114
  var params15 = S.Object({
20783
- pattern: S.String({ description: "Regular expression pattern to wait for" }),
20784
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20785
- timeout: S.Optional(S.Number({ short: "t", description: "Maximum wait time in milliseconds" })),
21115
+ pattern: S.String({
21116
+ description: "Regular expression pattern to wait for",
21117
+ minLength: 1,
21118
+ pattern: "\\S"
21119
+ }),
21120
+ session: S.Optional(
21121
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21122
+ ),
21123
+ timeout: S.Optional(
21124
+ S.Number({ short: "t", description: "Maximum wait time in milliseconds", minimum: 0 })
21125
+ ),
20786
21126
  literal: S.Optional(
20787
21127
  S.Boolean({
20788
21128
  short: "l",
@@ -20797,17 +21137,33 @@ var waitFor = defineCommand({
20797
21137
  positional: ["pattern"],
20798
21138
  params: params15,
20799
21139
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20800
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21140
+ if (params17.pattern.trim().length === 0) {
21141
+ throw new UserError("Wait pattern must not be empty.");
21142
+ }
21143
+ assertTimeout2(params17.timeout);
21144
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21145
+ params17.session,
21146
+ env
21147
+ );
20801
21148
  const pattern = params17.literal === true ? params17.pattern : new RegExp(params17.pattern);
20802
21149
  const line = params17.timeout === void 0 ? await namedSession.session.waitFor(pattern) : await namedSession.session.waitFor(pattern, { timeout: params17.timeout });
20803
21150
  return { matched: true, line };
20804
21151
  }
20805
21152
  });
21153
+ function assertTimeout2(timeout) {
21154
+ if (timeout !== void 0 && (!Number.isFinite(timeout) || timeout < 0)) {
21155
+ throw new UserError("Timeout must be a finite non-negative number.");
21156
+ }
21157
+ }
20806
21158
 
20807
21159
  // src/commands/wait-for-exit.ts
20808
21160
  var params16 = S.Object({
20809
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20810
- timeout: S.Optional(S.Number({ short: "t", description: "Maximum wait time in milliseconds" }))
21161
+ session: S.Optional(
21162
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21163
+ ),
21164
+ timeout: S.Optional(
21165
+ S.Number({ short: "t", description: "Maximum wait time in milliseconds", minimum: 0 })
21166
+ )
20811
21167
  });
20812
21168
  var waitForExit2 = defineCommand({
20813
21169
  name: "wait-for-exit",
@@ -20815,7 +21171,13 @@ var waitForExit2 = defineCommand({
20815
21171
  scope: ["cli", "mcp", "sdk"],
20816
21172
  params: params16,
20817
21173
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20818
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21174
+ if (params17.timeout !== void 0 && (!Number.isFinite(params17.timeout) || params17.timeout < 0)) {
21175
+ throw new UserError("Timeout must be a finite non-negative number.");
21176
+ }
21177
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21178
+ params17.session,
21179
+ env
21180
+ );
20819
21181
  const exitCode = await namedSession.session.waitForExit(
20820
21182
  params17.timeout === void 0 ? void 0 : { timeout: params17.timeout }
20821
21183
  );