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
@@ -12581,10 +12581,15 @@ async function writeErrorReport(context) {
12581
12581
 
12582
12582
  // ../toolcraft/src/number-schema.ts
12583
12583
  function isValidNumberSchemaValue(value, schema) {
12584
- return typeof value === "number" && Number.isFinite(value) && (schema.jsonType !== "integer" || Number.isInteger(value));
12584
+ 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);
12585
12585
  }
12586
12586
  function getExpectedNumberDescription(schema) {
12587
- return schema.jsonType === "integer" ? "an integer" : "a number";
12587
+ const type2 = schema.jsonType === "integer" ? "an integer" : "a number";
12588
+ const bounds = [
12589
+ schema.minimum === void 0 ? void 0 : `greater than or equal to ${schema.minimum}`,
12590
+ schema.maximum === void 0 ? void 0 : `less than or equal to ${schema.maximum}`
12591
+ ].filter((bound) => bound !== void 0);
12592
+ return bounds.length === 0 ? type2 : `${type2} ${bounds.join(" and ")}`;
12588
12593
  }
12589
12594
 
12590
12595
  // ../toolcraft/src/renderer.ts
@@ -13413,10 +13418,17 @@ function parseEnumValue(value, values, label) {
13413
13418
  return match;
13414
13419
  }
13415
13420
  function validateStringPattern(value, schema, label) {
13416
- if (schema.pattern === void 0) {
13417
- return value;
13421
+ if (schema.minLength !== void 0 && value.length < schema.minLength) {
13422
+ throw new UserError(
13423
+ `Invalid value for "${label}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`
13424
+ );
13418
13425
  }
13419
- if (!matchesStringPattern(value, schema.pattern)) {
13426
+ if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
13427
+ throw new UserError(
13428
+ `Invalid value for "${label}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`
13429
+ );
13430
+ }
13431
+ if (schema.pattern !== void 0 && !matchesStringPattern(value, schema.pattern)) {
13420
13432
  throw new UserError(
13421
13433
  `Invalid value for "${label}": "${value}" does not match pattern "${schema.pattern}".`
13422
13434
  );
@@ -13598,6 +13610,18 @@ function parseArrayValue(value, schema, label) {
13598
13610
  (item) => parseScalarValue(item, itemSchema, label)
13599
13611
  );
13600
13612
  }
13613
+ function validateArrayBounds(value, schema, label) {
13614
+ if (schema.minItems !== void 0 && value.length < schema.minItems) {
13615
+ throw new UserError(
13616
+ `Invalid value for "${label}". Expected an array with at least ${schema.minItems} items, got array(${value.length}).`
13617
+ );
13618
+ }
13619
+ if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
13620
+ throw new UserError(
13621
+ `Invalid value for "${label}". Expected an array with at most ${schema.maxItems} items, got array(${value.length}).`
13622
+ );
13623
+ }
13624
+ }
13601
13625
  function createOption(field, globalLongOptionFlags) {
13602
13626
  const flags = formatOptionFlags(field, globalLongOptionFlags);
13603
13627
  const collidesWithGlobalFlag = globalLongOptionFlags.has(field.optionFlag);
@@ -14567,6 +14591,9 @@ function describeExpectedPresetValue(schema) {
14567
14591
  if (schema.kind === "array") {
14568
14592
  return "an array";
14569
14593
  }
14594
+ if (schema.kind === "number") {
14595
+ return getExpectedNumberDescription(schema);
14596
+ }
14570
14597
  if (schema.kind === "json") {
14571
14598
  return "valid JSON";
14572
14599
  }
@@ -14584,6 +14611,16 @@ function validatePresetScalarValue(value, schema, fieldPath, presetPath) {
14584
14611
  if (typeof value !== "string") {
14585
14612
  break;
14586
14613
  }
14614
+ if (schema.minLength !== void 0 && value.length < schema.minLength) {
14615
+ throw new UserError(
14616
+ `Preset file "${presetPath}" has an invalid value for "${fieldPath}". Expected a string with length at least ${schema.minLength}, got string with length ${value.length}.`
14617
+ );
14618
+ }
14619
+ if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
14620
+ throw new UserError(
14621
+ `Preset file "${presetPath}" has an invalid value for "${fieldPath}". Expected a string with length at most ${schema.maxLength}, got string with length ${value.length}.`
14622
+ );
14623
+ }
14587
14624
  if (schema.pattern !== void 0 && !matchesStringPattern(value, schema.pattern)) {
14588
14625
  throw new UserError(
14589
14626
  `Preset file "${presetPath}" has an invalid value for "${fieldPath}": "${value}" does not match pattern "${schema.pattern}".`
@@ -14633,6 +14670,16 @@ function validatePresetFieldValue(value, field, presetPath) {
14633
14670
  `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array, got ${describeReceived(value)}.`
14634
14671
  );
14635
14672
  }
14673
+ if (field.schema.minItems !== void 0 && value.length < field.schema.minItems) {
14674
+ throw new UserError(
14675
+ `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array with at least ${field.schema.minItems} items, got array(${value.length}).`
14676
+ );
14677
+ }
14678
+ if (field.schema.maxItems !== void 0 && value.length > field.schema.maxItems) {
14679
+ throw new UserError(
14680
+ `Preset file "${presetPath}" has an invalid value for "${field.displayPath}". Expected an array with at most ${field.schema.maxItems} items, got array(${value.length}).`
14681
+ );
14682
+ }
14636
14683
  return value.map(
14637
14684
  (item) => validatePresetScalarValue(item, itemSchema, field.displayPath, presetPath)
14638
14685
  );
@@ -15042,12 +15089,17 @@ function parseOptionFieldValue(field, value, errors2) {
15042
15089
  }
15043
15090
  parsedValues.push(...parsed);
15044
15091
  }
15092
+ validateArrayBounds(parsedValues, field.schema, field.displayPath);
15045
15093
  return { ok: true, value: parsedValues };
15046
15094
  }
15047
15095
  if (typeof value !== "string") {
15048
15096
  return { ok: true, value };
15049
15097
  }
15050
- return { ok: true, value: parseFieldInputValue(value, field.schema, field.displayPath) };
15098
+ const parsedValue = parseFieldInputValue(value, field.schema, field.displayPath);
15099
+ if (field.schema.kind === "array" && Array.isArray(parsedValue)) {
15100
+ validateArrayBounds(parsedValue, field.schema, field.displayPath);
15101
+ }
15102
+ return { ok: true, value: parsedValue };
15051
15103
  } catch (error3) {
15052
15104
  if (error3 instanceof UserError || error3 instanceof InvalidArgumentError) {
15053
15105
  errors2.push({
@@ -15108,6 +15160,7 @@ function consumeFieldValue(args, index, schema, label, inlineValue) {
15108
15160
  if (values.length === 0) {
15109
15161
  throw new InvalidArgumentError(`option '${label}' argument missing`);
15110
15162
  }
15163
+ validateArrayBounds(values, schema, label);
15111
15164
  return {
15112
15165
  nextIndex,
15113
15166
  value: values
@@ -16481,6 +16534,10 @@ var TerminalBuffer = class {
16481
16534
  }
16482
16535
  _writePrintable(ch) {
16483
16536
  const width = this._cellWidth(ch);
16537
+ if (width === 0) {
16538
+ this._appendCombiningMark(ch);
16539
+ return;
16540
+ }
16484
16541
  if (this._autoWrap && this._pendingWrap) {
16485
16542
  this._cursorX = 0;
16486
16543
  this._newline();
@@ -16515,11 +16572,40 @@ var TerminalBuffer = class {
16515
16572
  _cellWidth(ch) {
16516
16573
  const codePoint = ch.codePointAt(0);
16517
16574
  if (codePoint === void 0) return 0;
16575
+ if (isCombiningCodePoint2(codePoint)) {
16576
+ return 0;
16577
+ }
16518
16578
  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) {
16519
16579
  return Math.min(2, this._cols);
16520
16580
  }
16521
16581
  return 1;
16522
16582
  }
16583
+ _appendCombiningMark(ch) {
16584
+ const target = this._findCombiningTarget();
16585
+ if (target === null) {
16586
+ return;
16587
+ }
16588
+ const cell = this._screen[target.y]?.[target.x];
16589
+ if (cell === null || cell === void 0) {
16590
+ return;
16591
+ }
16592
+ cell[1] += ch;
16593
+ }
16594
+ _findCombiningTarget() {
16595
+ const startX = this._pendingWrap ? this._cursorX : this._cursorX - 1;
16596
+ for (let y = this._cursorY; y >= 0; y -= 1) {
16597
+ const row = this._screen[y];
16598
+ if (row === void 0) {
16599
+ continue;
16600
+ }
16601
+ for (let x = y === this._cursorY ? startX : this._cols - 1; x >= 0; x -= 1) {
16602
+ if (row[x] !== null) {
16603
+ return { x, y };
16604
+ }
16605
+ }
16606
+ }
16607
+ return null;
16608
+ }
16523
16609
  _setChar(y, x, ch) {
16524
16610
  const row = this._screen[y];
16525
16611
  if (row && x >= 0 && x < this._cols) {
@@ -16660,7 +16746,8 @@ var TerminalBuffer = class {
16660
16746
  case "J":
16661
16747
  if (p0 === 0) {
16662
16748
  this._eraseLine(this._cursorY, this._cursorX, this._cols - 1);
16663
- for (let y = this._cursorY + 1; y < this._rows; y++) this._eraseLine(y, 0, this._cols - 1);
16749
+ for (let y = this._cursorY + 1; y < this._rows; y++)
16750
+ this._eraseLine(y, 0, this._cols - 1);
16664
16751
  } else if (p0 === 1) {
16665
16752
  for (let y = 0; y < this._cursorY; y++) this._eraseLine(y, 0, this._cols - 1);
16666
16753
  this._eraseLine(this._cursorY, 0, this._cursorX);
@@ -17025,6 +17112,9 @@ function createDefaultStyleState() {
17025
17112
  strikethrough: false
17026
17113
  };
17027
17114
  }
17115
+ function isCombiningCodePoint2(codePoint) {
17116
+ return codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071;
17117
+ }
17028
17118
  function serializeStyleState(state) {
17029
17119
  const codes = [];
17030
17120
  if (state.bold) {
@@ -17078,6 +17168,8 @@ var NAMED_KEY_LOWER = new Map(
17078
17168
  Object.entries(NAMED_KEY_SEQUENCES).map(([k, v]) => [k.toLowerCase(), v])
17079
17169
  );
17080
17170
  var VALID_KEYS_HINT = `Valid keys: ${Object.keys(NAMED_KEY_SEQUENCES).join(", ")}, Control+<letter>, Alt+<key>`;
17171
+ var NAMED_KEY_PATTERN = Object.keys(NAMED_KEY_SEQUENCES).map(caseInsensitivePattern).join("|");
17172
+ var TERMINAL_KEY_PATTERN = `^(?:${NAMED_KEY_PATTERN}|.|[Cc][Oo][Nn][Tt][Rr][Oo][Ll]\\+[A-Za-z]|[Aa][Ll][Tt]\\+.+)$`;
17081
17173
  function unknownKeyError(key2) {
17082
17174
  return new Error(`Unknown terminal key: ${key2}. ${VALID_KEYS_HINT}`);
17083
17175
  }
@@ -17120,6 +17212,18 @@ function controlKeyToSequence(controlKey) {
17120
17212
  }
17121
17213
  return String.fromCharCode(charCode - 64);
17122
17214
  }
17215
+ function caseInsensitivePattern(value) {
17216
+ let pattern = "";
17217
+ for (const character of value) {
17218
+ const lower = character.toLowerCase();
17219
+ const upper = character.toUpperCase();
17220
+ pattern += lower === upper ? escapePatternCharacter(character) : `[${upper}${lower}]`;
17221
+ }
17222
+ return pattern;
17223
+ }
17224
+ function escapePatternCharacter(character) {
17225
+ return character.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
17226
+ }
17123
17227
 
17124
17228
  // src/terminal-screen.ts
17125
17229
  var TerminalScreen = class {
@@ -17559,7 +17663,11 @@ function createTerminalPilotRuntime(options = {}) {
17559
17663
  const pendingNames = /* @__PURE__ */ new Set();
17560
17664
  let pilotPromise;
17561
17665
  function getRequestedName(name, env) {
17562
- return name ?? env?.get(SESSION_ENV_VAR);
17666
+ const requestedName = name ?? env?.get(SESSION_ENV_VAR);
17667
+ if (requestedName !== void 0 && requestedName.trim().length === 0) {
17668
+ throw new UserError("Session name must not be empty.");
17669
+ }
17670
+ return requestedName;
17563
17671
  }
17564
17672
  async function getPilot() {
17565
17673
  pilotPromise ??= launchPilot();
@@ -17595,7 +17703,9 @@ function createTerminalPilotRuntime(options = {}) {
17595
17703
  const sessionId = nameToId.get(name);
17596
17704
  if (sessionId === void 0) {
17597
17705
  const active = await listSessions2();
17598
- throw new UserError(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
17706
+ throw new UserError(
17707
+ `Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
17708
+ );
17599
17709
  }
17600
17710
  const pilot = await getPilot();
17601
17711
  try {
@@ -17603,7 +17713,9 @@ function createTerminalPilotRuntime(options = {}) {
17603
17713
  } catch {
17604
17714
  forgetSession(name, sessionId);
17605
17715
  const active = await listSessions2();
17606
- throw new UserError(`Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`);
17716
+ throw new UserError(
17717
+ `Session "${name}" was not found. ${formatAvailableSessions(active.map((entry) => entry.name))}`
17718
+ );
17607
17719
  }
17608
17720
  }
17609
17721
  async function listSessions2() {
@@ -17634,6 +17746,9 @@ function createTerminalPilotRuntime(options = {}) {
17634
17746
  }
17635
17747
  return {
17636
17748
  async createSession(params17, env) {
17749
+ if (params17.command.trim().length === 0) {
17750
+ throw new UserError("Command must not be empty.");
17751
+ }
17637
17752
  const requestedName = getRequestedName(params17.session, env) ?? nextSessionName();
17638
17753
  await discardExitedSessionName(requestedName);
17639
17754
  if (nameToId.has(requestedName) || pendingNames.has(requestedName)) {
@@ -17706,7 +17821,9 @@ async function closeSharedTerminalPilotRuntime() {
17706
17821
 
17707
17822
  // src/commands/close-session.ts
17708
17823
  var params = S.Object({
17709
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17824
+ session: S.Optional(
17825
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17826
+ )
17710
17827
  });
17711
17828
  var closeSession = defineCommand({
17712
17829
  name: "close-session",
@@ -17714,19 +17831,28 @@ var closeSession = defineCommand({
17714
17831
  scope: ["cli", "mcp", "sdk"],
17715
17832
  params,
17716
17833
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17717
- const { exitCode } = await getTerminalPilotRuntime(terminalPilotRuntime).closeSession(params17.session, env);
17834
+ const { exitCode } = await getTerminalPilotRuntime(terminalPilotRuntime).closeSession(
17835
+ params17.session,
17836
+ env
17837
+ );
17718
17838
  return { exitCode };
17719
17839
  }
17720
17840
  });
17721
17841
 
17722
17842
  // src/commands/create-session.ts
17723
17843
  var params2 = S.Object({
17724
- command: S.String({ description: "Command to execute" }),
17844
+ command: S.String({ description: "Command to execute", minLength: 1, pattern: "\\S" }),
17725
17845
  args: S.Optional(S.Array(S.String(), { description: "Command arguments" })),
17726
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
17846
+ session: S.Optional(
17847
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17848
+ ),
17727
17849
  cwd: S.Optional(S.String({ description: "Working directory" })),
17728
- cols: S.Optional(S.Number({ description: "Terminal width in columns" })),
17729
- rows: S.Optional(S.Number({ description: "Terminal height in rows" })),
17850
+ cols: S.Optional(
17851
+ S.Number({ description: "Terminal width in columns", jsonType: "integer", minimum: 1 })
17852
+ ),
17853
+ rows: S.Optional(
17854
+ S.Number({ description: "Terminal height in rows", jsonType: "integer", minimum: 1 })
17855
+ ),
17730
17856
  observe: S.Optional(S.Boolean({ description: "Mirror PTY output to stderr" }))
17731
17857
  });
17732
17858
  var createSession = defineCommand({
@@ -17736,7 +17862,10 @@ var createSession = defineCommand({
17736
17862
  positional: ["command", "args"],
17737
17863
  params: params2,
17738
17864
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17739
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).createSession(params17, env);
17865
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).createSession(
17866
+ params17,
17867
+ env
17868
+ );
17740
17869
  return { session: namedSession.name, pid: namedSession.session.pid };
17741
17870
  }
17742
17871
  });
@@ -17744,7 +17873,9 @@ var createSession = defineCommand({
17744
17873
  // src/commands/fill.ts
17745
17874
  var params3 = S.Object({
17746
17875
  text: S.String({ description: "Text to write to the session" }),
17747
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17876
+ session: S.Optional(
17877
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17878
+ )
17748
17879
  });
17749
17880
  var fill = defineCommand({
17750
17881
  name: "fill",
@@ -17753,7 +17884,10 @@ var fill = defineCommand({
17753
17884
  positional: ["text"],
17754
17885
  params: params3,
17755
17886
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17756
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
17887
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
17888
+ params17.session,
17889
+ env
17890
+ );
17757
17891
  await namedSession.session.fill(params17.text);
17758
17892
  return void 0;
17759
17893
  }
@@ -17761,7 +17895,9 @@ var fill = defineCommand({
17761
17895
 
17762
17896
  // src/commands/get-session.ts
17763
17897
  var params4 = S.Object({
17764
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
17898
+ session: S.Optional(
17899
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
17900
+ )
17765
17901
  });
17766
17902
  var getSession = defineCommand({
17767
17903
  name: "get-session",
@@ -17769,7 +17905,10 @@ var getSession = defineCommand({
17769
17905
  scope: ["cli", "mcp", "sdk"],
17770
17906
  params: params4,
17771
17907
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
17772
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
17908
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
17909
+ params17.session,
17910
+ env
17911
+ );
17773
17912
  return {
17774
17913
  session: namedSession.name,
17775
17914
  pid: namedSession.session.pid,
@@ -17797,7 +17936,7 @@ var claudeCodeAgent = {
17797
17936
  CLAUDE_CODE_ENABLE_TELEMETRY: "1"
17798
17937
  }
17799
17938
  },
17800
- configPath: "~/.claude/settings.json",
17939
+ configPath: "~/.claude.json",
17801
17940
  branding: {
17802
17941
  colors: {
17803
17942
  dark: "#C15F3C",
@@ -17812,7 +17951,12 @@ var claudeDesktopAgent = {
17812
17951
  name: "claude-desktop",
17813
17952
  label: "Claude Desktop",
17814
17953
  summary: "Anthropic's official desktop application for Claude",
17815
- configPath: "~/.claude/settings.json",
17954
+ configPath: "~/.config/Claude/claude_desktop_config.json",
17955
+ configPaths: {
17956
+ darwin: "~/Library/Application Support/Claude/claude_desktop_config.json",
17957
+ linux: "~/.config/Claude/claude_desktop_config.json",
17958
+ win32: "~/AppData/Roaming/Claude/claude_desktop_config.json"
17959
+ },
17816
17960
  branding: {
17817
17961
  colors: {
17818
17962
  dark: "#D97757",
@@ -17856,7 +18000,7 @@ var cursorAgent = {
17856
18000
  label: "Cursor",
17857
18001
  summary: "Cursor's CLI coding agent.",
17858
18002
  binaryName: "cursor-agent",
17859
- configPath: "~/.cursor/cli-config.json",
18003
+ configPath: "~/.cursor/mcp.json",
17860
18004
  branding: {
17861
18005
  colors: {
17862
18006
  dark: "#FFFFFF",
@@ -17896,7 +18040,7 @@ var openCodeAgent = {
17896
18040
  OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
17897
18041
  }
17898
18042
  },
17899
- configPath: "~/.config/opencode/config.json",
18043
+ configPath: "~/.config/opencode/opencode.json",
17900
18044
  branding: {
17901
18045
  colors: {
17902
18046
  dark: "#4A4F55",
@@ -17914,7 +18058,7 @@ var kimiAgent = {
17914
18058
  aliases: ["kimi-cli"],
17915
18059
  binaryName: "kimi",
17916
18060
  apiShapes: ["openai-chat-completions"],
17917
- configPath: "~/.kimi/config.toml",
18061
+ configPath: "~/.kimi/mcp.json",
17918
18062
  branding: {
17919
18063
  colors: {
17920
18064
  dark: "#7B68EE",
@@ -19614,8 +19758,10 @@ var listSessions = defineCommand({
19614
19758
 
19615
19759
  // src/commands/press-key.ts
19616
19760
  var params7 = S.Object({
19617
- key: S.String({ description: "Named key to press" }),
19618
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19761
+ key: S.String({ description: "Named key to press", pattern: TERMINAL_KEY_PATTERN }),
19762
+ session: S.Optional(
19763
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19764
+ )
19619
19765
  });
19620
19766
  var pressKey = defineCommand({
19621
19767
  name: "press-key",
@@ -19624,16 +19770,36 @@ var pressKey = defineCommand({
19624
19770
  positional: ["key"],
19625
19771
  params: params7,
19626
19772
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19627
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19773
+ assertTerminalKey(params17.key);
19774
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19775
+ params17.session,
19776
+ env
19777
+ );
19628
19778
  await namedSession.session.press(params17.key);
19629
19779
  return void 0;
19630
19780
  }
19631
19781
  });
19782
+ function assertTerminalKey(key2) {
19783
+ try {
19784
+ keyToSequence(key2);
19785
+ } catch (error3) {
19786
+ throw new UserError(error3 instanceof Error ? error3.message : String(error3));
19787
+ }
19788
+ }
19632
19789
 
19633
19790
  // src/commands/read-history.ts
19634
19791
  var params8 = S.Object({
19635
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
19636
- last: S.Optional(S.Number({ short: "n", description: "Return only the last N lines" }))
19792
+ session: S.Optional(
19793
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19794
+ ),
19795
+ last: S.Optional(
19796
+ S.Number({
19797
+ short: "n",
19798
+ description: "Return only the last N lines",
19799
+ jsonType: "integer",
19800
+ minimum: 0
19801
+ })
19802
+ )
19637
19803
  });
19638
19804
  var readHistory = defineCommand({
19639
19805
  name: "read-history",
@@ -19641,7 +19807,10 @@ var readHistory = defineCommand({
19641
19807
  scope: ["cli", "mcp", "sdk"],
19642
19808
  params: params8,
19643
19809
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19644
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19810
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19811
+ params17.session,
19812
+ env
19813
+ );
19645
19814
  const lines = await namedSession.session.history({ last: params17.last });
19646
19815
  return { lines, exitCode: namedSession.session.exitCode };
19647
19816
  }
@@ -19649,7 +19818,9 @@ var readHistory = defineCommand({
19649
19818
 
19650
19819
  // src/commands/read-screen.ts
19651
19820
  var params9 = S.Object({
19652
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19821
+ session: S.Optional(
19822
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19823
+ )
19653
19824
  });
19654
19825
  var readScreen = defineCommand({
19655
19826
  name: "read-screen",
@@ -19657,7 +19828,10 @@ var readScreen = defineCommand({
19657
19828
  scope: ["cli", "mcp", "sdk"],
19658
19829
  params: params9,
19659
19830
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19660
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19831
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19832
+ params17.session,
19833
+ env
19834
+ );
19661
19835
  const screen = await namedSession.session.screen();
19662
19836
  return {
19663
19837
  lines: [...screen.lines],
@@ -19670,9 +19844,11 @@ var readScreen = defineCommand({
19670
19844
 
19671
19845
  // src/commands/resize.ts
19672
19846
  var params10 = S.Object({
19673
- cols: S.Number({ description: "Terminal width in columns" }),
19674
- rows: S.Number({ description: "Terminal height in rows" }),
19675
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
19847
+ cols: S.Number({ description: "Terminal width in columns", jsonType: "integer", minimum: 1 }),
19848
+ rows: S.Number({ description: "Terminal height in rows", jsonType: "integer", minimum: 1 }),
19849
+ session: S.Optional(
19850
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
19851
+ )
19676
19852
  });
19677
19853
  var resize = defineCommand({
19678
19854
  name: "resize",
@@ -19680,7 +19856,10 @@ var resize = defineCommand({
19680
19856
  scope: ["cli", "mcp", "sdk"],
19681
19857
  params: params10,
19682
19858
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
19683
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
19859
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
19860
+ params17.session,
19861
+ env
19862
+ );
19684
19863
  await namedSession.session.resize(params17.cols, params17.rows);
19685
19864
  return void 0;
19686
19865
  }
@@ -19692,6 +19871,9 @@ import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises
19692
19871
 
19693
19872
  // ../terminal-png/src/ansi-parser.ts
19694
19873
  var ESC2 = "\x1B";
19874
+ var TAB_WIDTH = 8;
19875
+ var MAX_TERMINAL_ROWS = 1e3;
19876
+ var MAX_TERMINAL_COLUMNS = 1e3;
19695
19877
  function createDefaultStyle() {
19696
19878
  return {
19697
19879
  fg: null,
@@ -19976,10 +20158,34 @@ function positionParameter(params17, index, fallback) {
19976
20158
  const value = toInteger(params17.split(";")[index]);
19977
20159
  return value === null || value < 1 ? fallback : value;
19978
20160
  }
20161
+ function modeParameter(params17, fallback) {
20162
+ const value = toInteger(params17.split(";")[0]);
20163
+ return value === null ? fallback : value;
20164
+ }
20165
+ function displayWidth3(text4) {
20166
+ if (text4 === " ") {
20167
+ return TAB_WIDTH;
20168
+ }
20169
+ const codePoint = text4.codePointAt(0);
20170
+ if (codePoint === void 0) {
20171
+ return 0;
20172
+ }
20173
+ 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) {
20174
+ return 2;
20175
+ }
20176
+ return 1;
20177
+ }
20178
+ function hasRenderableCell(line) {
20179
+ return (line ?? []).some((cell) => cell !== void 0 && cell.text.length > 0);
20180
+ }
19979
20181
  function buildRuns(lines, lineBreakStyles) {
19980
20182
  const runs = [];
19981
20183
  const defaultStyle = createDefaultStyle();
19982
- for (let row = 0; row < lines.length; row += 1) {
20184
+ let lastRow = lines.length - 1;
20185
+ while (lastRow > 0 && !hasRenderableCell(lines[lastRow]) && lineBreakStyles[lastRow - 1] === void 0) {
20186
+ lastRow -= 1;
20187
+ }
20188
+ for (let row = 0; row <= lastRow; row += 1) {
19983
20189
  const line = lines[row] ?? [];
19984
20190
  let lastCell = line.length - 1;
19985
20191
  while (lastCell >= 0 && line[lastCell] === void 0) {
@@ -19989,7 +20195,7 @@ function buildRuns(lines, lineBreakStyles) {
19989
20195
  const cell = line[column] ?? { text: " ", style: defaultStyle };
19990
20196
  pushRun(runs, cell.style, cell.text);
19991
20197
  }
19992
- if (row < lines.length - 1) {
20198
+ if (row < lastRow) {
19993
20199
  pushRun(runs, lineBreakStyles[row] ?? defaultStyle, "\n");
19994
20200
  }
19995
20201
  }
@@ -20001,7 +20207,21 @@ function parseAnsi2(input) {
20001
20207
  let style = createDefaultStyle();
20002
20208
  let row = 0;
20003
20209
  let column = 0;
20210
+ let savedRow = 0;
20211
+ let savedColumn = 0;
20004
20212
  let index = 0;
20213
+ const clampRow = (nextRow) => {
20214
+ if (nextRow < 0) {
20215
+ return 0;
20216
+ }
20217
+ return Math.min(nextRow, MAX_TERMINAL_ROWS - 1);
20218
+ };
20219
+ const clampColumn = (nextColumn) => {
20220
+ if (nextColumn < 0) {
20221
+ return 0;
20222
+ }
20223
+ return Math.min(nextColumn, MAX_TERMINAL_COLUMNS - 1);
20224
+ };
20005
20225
  const ensureLine = () => {
20006
20226
  while (lines.length <= row) {
20007
20227
  lines.push([]);
@@ -20009,12 +20229,64 @@ function parseAnsi2(input) {
20009
20229
  };
20010
20230
  const moveDown = (keepColumn) => {
20011
20231
  lineBreakStyles[row] = cloneStyle(style);
20012
- row += 1;
20232
+ row = clampRow(row + 1);
20013
20233
  if (!keepColumn) {
20014
20234
  column = 0;
20015
20235
  }
20016
20236
  ensureLine();
20017
20237
  };
20238
+ const eraseLine = (mode) => {
20239
+ const line = lines[row] ?? [];
20240
+ if (mode === 1) {
20241
+ for (let cell = 0; cell <= column; cell += 1) {
20242
+ delete line[cell];
20243
+ }
20244
+ return;
20245
+ }
20246
+ if (mode === 2) {
20247
+ lines[row] = [];
20248
+ return;
20249
+ }
20250
+ line.splice(column);
20251
+ };
20252
+ const eraseDisplay = (mode) => {
20253
+ if (mode === 1) {
20254
+ for (let lineRow = 0; lineRow < row; lineRow += 1) {
20255
+ lines[lineRow] = [];
20256
+ }
20257
+ eraseLine(1);
20258
+ return;
20259
+ }
20260
+ if (mode === 2 || mode === 3) {
20261
+ lines.length = 0;
20262
+ lineBreakStyles.length = 0;
20263
+ ensureLine();
20264
+ return;
20265
+ }
20266
+ eraseLine(0);
20267
+ lines.splice(row + 1);
20268
+ lineBreakStyles.splice(row);
20269
+ };
20270
+ const saveCursor = () => {
20271
+ savedRow = row;
20272
+ savedColumn = column;
20273
+ };
20274
+ const restoreCursor = () => {
20275
+ row = clampRow(savedRow);
20276
+ column = clampColumn(savedColumn);
20277
+ ensureLine();
20278
+ };
20279
+ const writeText = (text4) => {
20280
+ const width = displayWidth3(text4);
20281
+ if (width === 0) {
20282
+ return;
20283
+ }
20284
+ lines[row][column] = { text: text4, style: cloneStyle(style) };
20285
+ for (let offset = 1; offset < width && column + offset < MAX_TERMINAL_COLUMNS; offset += 1) {
20286
+ lines[row][column + offset] = { text: "", style: cloneStyle(style) };
20287
+ }
20288
+ column = clampColumn(column + width);
20289
+ };
20018
20290
  while (index < input.length) {
20019
20291
  const char = input[index];
20020
20292
  if (char === "\n") {
@@ -20037,38 +20309,73 @@ function parseAnsi2(input) {
20037
20309
  index += 1;
20038
20310
  continue;
20039
20311
  }
20312
+ if (char === " ") {
20313
+ const nextTabStop = Math.min(
20314
+ Math.floor(column / TAB_WIDTH) * TAB_WIDTH + TAB_WIDTH,
20315
+ MAX_TERMINAL_COLUMNS
20316
+ );
20317
+ while (column < nextTabStop) {
20318
+ writeText(" ");
20319
+ }
20320
+ index += 1;
20321
+ continue;
20322
+ }
20040
20323
  if (char === ESC2 && input[index + 1] === "]") {
20041
20324
  index = parseOscEnd(input, index);
20042
20325
  continue;
20043
20326
  }
20327
+ if (char === ESC2 && input[index + 1] === "7") {
20328
+ saveCursor();
20329
+ index += 2;
20330
+ continue;
20331
+ }
20332
+ if (char === ESC2 && input[index + 1] === "8") {
20333
+ restoreCursor();
20334
+ index += 2;
20335
+ continue;
20336
+ }
20044
20337
  const csiPrefixLength = char === "\x9B" ? 1 : char === ESC2 && input[index + 1] === "[" ? 2 : null;
20045
20338
  if (csiPrefixLength !== null) {
20046
20339
  const sequence = parseCsi(input, index, csiPrefixLength);
20047
20340
  if (sequence.final === "m") {
20048
20341
  style = applySgr(style, sequence.params);
20049
20342
  } else if (sequence.final === "G") {
20050
- column = positionParameter(sequence.params, 0, 1) - 1;
20343
+ column = clampColumn(positionParameter(sequence.params, 0, 1) - 1);
20051
20344
  } else if (sequence.final === "C") {
20052
- column += positionParameter(sequence.params, 0, 1);
20345
+ column = clampColumn(column + positionParameter(sequence.params, 0, 1));
20053
20346
  } else if (sequence.final === "D") {
20054
20347
  column = Math.max(0, column - positionParameter(sequence.params, 0, 1));
20055
20348
  } else if (sequence.final === "A") {
20056
- row = Math.max(0, row - positionParameter(sequence.params, 0, 1));
20349
+ row = clampRow(row - positionParameter(sequence.params, 0, 1));
20057
20350
  } else if (sequence.final === "B") {
20058
- row += positionParameter(sequence.params, 0, 1);
20351
+ row = clampRow(row + positionParameter(sequence.params, 0, 1));
20059
20352
  ensureLine();
20353
+ } else if (sequence.final === "E") {
20354
+ row = clampRow(row + positionParameter(sequence.params, 0, 1));
20355
+ column = 0;
20356
+ ensureLine();
20357
+ } else if (sequence.final === "F") {
20358
+ row = clampRow(row - positionParameter(sequence.params, 0, 1));
20359
+ column = 0;
20060
20360
  } else if (sequence.final === "H" || sequence.final === "f") {
20061
- row = positionParameter(sequence.params, 0, 1) - 1;
20062
- column = positionParameter(sequence.params, 1, 1) - 1;
20361
+ row = clampRow(positionParameter(sequence.params, 0, 1) - 1);
20362
+ column = clampColumn(positionParameter(sequence.params, 1, 1) - 1);
20063
20363
  ensureLine();
20364
+ } else if (sequence.final === "K") {
20365
+ eraseLine(modeParameter(sequence.params, 0));
20366
+ } else if (sequence.final === "J") {
20367
+ eraseDisplay(modeParameter(sequence.params, 0));
20368
+ } else if (sequence.final === "s") {
20369
+ saveCursor();
20370
+ } else if (sequence.final === "u") {
20371
+ restoreCursor();
20064
20372
  }
20065
20373
  index = sequence.end;
20066
20374
  continue;
20067
20375
  }
20068
20376
  const codePoint = input.codePointAt(index);
20069
20377
  const text4 = codePoint === void 0 ? "" : String.fromCodePoint(codePoint);
20070
- lines[row][column] = { text: text4, style: cloneStyle(style) };
20071
- column += 1;
20378
+ writeText(text4);
20072
20379
  index += text4.length;
20073
20380
  }
20074
20381
  return buildRuns(lines, lineBreakStyles);
@@ -20476,11 +20783,11 @@ function splitIntoLines(runs) {
20476
20783
  }
20477
20784
  function measureLines(lines) {
20478
20785
  return Math.max(
20479
- ...lines.map((line) => displayWidth3(line.map((run) => run.text).join("")) * CHARACTER_WIDTH),
20786
+ ...lines.map((line) => displayWidth4(line.map((run) => run.text).join("")) * CHARACTER_WIDTH),
20480
20787
  0
20481
20788
  );
20482
20789
  }
20483
- function displayWidth3(text4, startColumn = 0) {
20790
+ function displayWidth4(text4, startColumn = 0) {
20484
20791
  const segmenter = new Intl.Segmenter();
20485
20792
  let column = startColumn;
20486
20793
  for (const { segment } of segmenter.segment(text4)) {
@@ -20542,7 +20849,7 @@ function renderBackgrounds(line, startX, y, height) {
20542
20849
  let column = 0;
20543
20850
  const rectangles = [];
20544
20851
  for (const run of line) {
20545
- const width = displayWidth3(run.text, column);
20852
+ const width = displayWidth4(run.text, column);
20546
20853
  const background = resolveBackgroundColor(run);
20547
20854
  if (background !== BACKGROUND && width > 0) {
20548
20855
  rectangles.push(`<rect x="${formatNumber(startX + column * CHARACTER_WIDTH)}" y="${formatNumber(y)}" width="${formatNumber(width * CHARACTER_WIDTH)}" height="${formatNumber(height)}" fill="${escapeXmlAttribute(background)}" />`);
@@ -20576,7 +20883,7 @@ function renderRun(run) {
20576
20883
  if (run.dim) {
20577
20884
  attributes.push('opacity="0.7"');
20578
20885
  }
20579
- const text4 = run.conceal ? " ".repeat(displayWidth3(run.text)) : run.text;
20886
+ const text4 = run.conceal ? " ".repeat(displayWidth4(run.text)) : run.text;
20580
20887
  return `<tspan ${attributes.join(" ")}>${escapeXmlText(text4)}</tspan>`;
20581
20888
  }
20582
20889
  function renderWindowControls() {
@@ -20625,13 +20932,16 @@ async function renderTerminalPng(ansiText, options = {}) {
20625
20932
  if (options.padding !== void 0 && (!Number.isInteger(options.padding) || options.padding < 0)) {
20626
20933
  throw new Error("Padding must be a non-negative integer.");
20627
20934
  }
20935
+ if (options.output !== void 0 && options.output.length === 0) {
20936
+ throw new Error("Output path must not be empty.");
20937
+ }
20628
20938
  const runs = parseAnsi2(ansiText);
20629
20939
  const svg = renderSvg(runs, {
20630
20940
  padding: options.padding,
20631
20941
  window: options.window
20632
20942
  });
20633
20943
  const png = renderPng(svg);
20634
- if (options.output) {
20944
+ if (options.output !== void 0) {
20635
20945
  const temporaryPath = `${options.output}.${randomUUID10()}.tmp`;
20636
20946
  let temporaryCreated = false;
20637
20947
  try {
@@ -20657,10 +20967,19 @@ function isAlreadyExistsError3(error3) {
20657
20967
 
20658
20968
  // src/commands/screenshot.ts
20659
20969
  var params11 = S.Object({
20660
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20970
+ session: S.Optional(
20971
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
20972
+ ),
20661
20973
  output: S.String({ short: "o", description: "Path to the output PNG file" }),
20662
20974
  window: S.Optional(S.Boolean({ description: "Include terminal window chrome", default: true })),
20663
- padding: S.Optional(S.Number({ short: "p", description: "Padding around terminal content" }))
20975
+ padding: S.Optional(
20976
+ S.Number({
20977
+ short: "p",
20978
+ description: "Padding around terminal content",
20979
+ jsonType: "integer",
20980
+ minimum: 0
20981
+ })
20982
+ )
20664
20983
  });
20665
20984
  var screenshot = defineCommand({
20666
20985
  name: "screenshot",
@@ -20668,7 +20987,10 @@ var screenshot = defineCommand({
20668
20987
  scope: ["cli"],
20669
20988
  params: params11,
20670
20989
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20671
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
20990
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
20991
+ params17.session,
20992
+ env
20993
+ );
20672
20994
  const screen = await namedSession.session.screen();
20673
20995
  await renderTerminalPng(screen.rawLines.join("\n"), {
20674
20996
  output: params17.output,
@@ -20682,7 +21004,9 @@ var screenshot = defineCommand({
20682
21004
  // src/commands/send-signal.ts
20683
21005
  var params12 = S.Object({
20684
21006
  signal: S.String({ description: "Signal to send to the session process" }),
20685
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
21007
+ session: S.Optional(
21008
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21009
+ )
20686
21010
  });
20687
21011
  var sendSignal = defineCommand({
20688
21012
  name: "send-signal",
@@ -20691,7 +21015,10 @@ var sendSignal = defineCommand({
20691
21015
  positional: ["signal"],
20692
21016
  params: params12,
20693
21017
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20694
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21018
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21019
+ params17.session,
21020
+ env
21021
+ );
20695
21022
  await namedSession.session.signal(params17.signal);
20696
21023
  return void 0;
20697
21024
  }
@@ -20700,7 +21027,9 @@ var sendSignal = defineCommand({
20700
21027
  // src/commands/type.ts
20701
21028
  var params13 = S.Object({
20702
21029
  text: S.String({ description: "Text to write to the session" }),
20703
- session: S.Optional(S.String({ short: "s", description: "Session name" }))
21030
+ session: S.Optional(
21031
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21032
+ )
20704
21033
  });
20705
21034
  var type = defineCommand({
20706
21035
  name: "type",
@@ -20709,7 +21038,10 @@ var type = defineCommand({
20709
21038
  positional: ["text"],
20710
21039
  params: params13,
20711
21040
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20712
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21041
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21042
+ params17.session,
21043
+ env
21044
+ );
20713
21045
  await namedSession.session.type(params17.text);
20714
21046
  return void 0;
20715
21047
  }
@@ -20787,9 +21119,17 @@ async function folderExists(fs4, folderPath) {
20787
21119
 
20788
21120
  // src/commands/wait-for.ts
20789
21121
  var params15 = S.Object({
20790
- pattern: S.String({ description: "Regular expression pattern to wait for" }),
20791
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20792
- timeout: S.Optional(S.Number({ short: "t", description: "Maximum wait time in milliseconds" })),
21122
+ pattern: S.String({
21123
+ description: "Regular expression pattern to wait for",
21124
+ minLength: 1,
21125
+ pattern: "\\S"
21126
+ }),
21127
+ session: S.Optional(
21128
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21129
+ ),
21130
+ timeout: S.Optional(
21131
+ S.Number({ short: "t", description: "Maximum wait time in milliseconds", minimum: 0 })
21132
+ ),
20793
21133
  literal: S.Optional(
20794
21134
  S.Boolean({
20795
21135
  short: "l",
@@ -20804,17 +21144,33 @@ var waitFor = defineCommand({
20804
21144
  positional: ["pattern"],
20805
21145
  params: params15,
20806
21146
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20807
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21147
+ if (params17.pattern.trim().length === 0) {
21148
+ throw new UserError("Wait pattern must not be empty.");
21149
+ }
21150
+ assertTimeout2(params17.timeout);
21151
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21152
+ params17.session,
21153
+ env
21154
+ );
20808
21155
  const pattern = params17.literal === true ? params17.pattern : new RegExp(params17.pattern);
20809
21156
  const line = params17.timeout === void 0 ? await namedSession.session.waitFor(pattern) : await namedSession.session.waitFor(pattern, { timeout: params17.timeout });
20810
21157
  return { matched: true, line };
20811
21158
  }
20812
21159
  });
21160
+ function assertTimeout2(timeout) {
21161
+ if (timeout !== void 0 && (!Number.isFinite(timeout) || timeout < 0)) {
21162
+ throw new UserError("Timeout must be a finite non-negative number.");
21163
+ }
21164
+ }
20813
21165
 
20814
21166
  // src/commands/wait-for-exit.ts
20815
21167
  var params16 = S.Object({
20816
- session: S.Optional(S.String({ short: "s", description: "Session name" })),
20817
- timeout: S.Optional(S.Number({ short: "t", description: "Maximum wait time in milliseconds" }))
21168
+ session: S.Optional(
21169
+ S.String({ short: "s", description: "Session name", minLength: 1, pattern: "\\S" })
21170
+ ),
21171
+ timeout: S.Optional(
21172
+ S.Number({ short: "t", description: "Maximum wait time in milliseconds", minimum: 0 })
21173
+ )
20818
21174
  });
20819
21175
  var waitForExit2 = defineCommand({
20820
21176
  name: "wait-for-exit",
@@ -20822,7 +21178,13 @@ var waitForExit2 = defineCommand({
20822
21178
  scope: ["cli", "mcp", "sdk"],
20823
21179
  params: params16,
20824
21180
  handler: async ({ params: params17, env, terminalPilotRuntime }) => {
20825
- const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(params17.session, env);
21181
+ if (params17.timeout !== void 0 && (!Number.isFinite(params17.timeout) || params17.timeout < 0)) {
21182
+ throw new UserError("Timeout must be a finite non-negative number.");
21183
+ }
21184
+ const namedSession = await getTerminalPilotRuntime(terminalPilotRuntime).resolveSession(
21185
+ params17.session,
21186
+ env
21187
+ );
20826
21188
  const exitCode = await namedSession.session.waitForExit(
20827
21189
  params17.timeout === void 0 ? void 0 : { timeout: params17.timeout }
20828
21190
  );