terminal-pilot 0.0.21 → 0.0.22

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 (58) hide show
  1. package/dist/cli.js +467 -193
  2. package/dist/cli.js.map +4 -4
  3. package/dist/commands/close-session.js +6 -4
  4. package/dist/commands/close-session.js.map +3 -3
  5. package/dist/commands/create-session.js +6 -4
  6. package/dist/commands/create-session.js.map +3 -3
  7. package/dist/commands/fill.js +6 -4
  8. package/dist/commands/fill.js.map +3 -3
  9. package/dist/commands/get-session.js +6 -4
  10. package/dist/commands/get-session.js.map +3 -3
  11. package/dist/commands/index.js +79 -33
  12. package/dist/commands/index.js.map +4 -4
  13. package/dist/commands/install.js +64 -20
  14. package/dist/commands/install.js.map +4 -4
  15. package/dist/commands/installer.js +36 -2
  16. package/dist/commands/installer.js.map +4 -4
  17. package/dist/commands/list-sessions.js +6 -4
  18. package/dist/commands/list-sessions.js.map +3 -3
  19. package/dist/commands/press-key.js +6 -4
  20. package/dist/commands/press-key.js.map +3 -3
  21. package/dist/commands/read-history.js +6 -4
  22. package/dist/commands/read-history.js.map +3 -3
  23. package/dist/commands/read-screen.js +6 -4
  24. package/dist/commands/read-screen.js.map +3 -3
  25. package/dist/commands/resize.js +6 -4
  26. package/dist/commands/resize.js.map +3 -3
  27. package/dist/commands/runtime.js +6 -4
  28. package/dist/commands/runtime.js.map +3 -3
  29. package/dist/commands/screenshot.js +17 -8
  30. package/dist/commands/screenshot.js.map +3 -3
  31. package/dist/commands/send-signal.js +6 -4
  32. package/dist/commands/send-signal.js.map +3 -3
  33. package/dist/commands/type.js +6 -4
  34. package/dist/commands/type.js.map +3 -3
  35. package/dist/commands/uninstall.js +39 -5
  36. package/dist/commands/uninstall.js.map +4 -4
  37. package/dist/commands/wait-for-exit.js +6 -4
  38. package/dist/commands/wait-for-exit.js.map +3 -3
  39. package/dist/commands/wait-for.js +6 -4
  40. package/dist/commands/wait-for.js.map +3 -3
  41. package/dist/errors.d.ts +1 -0
  42. package/dist/errors.js +8 -0
  43. package/dist/errors.js.map +7 -0
  44. package/dist/index.js +8 -4
  45. package/dist/index.js.map +3 -3
  46. package/dist/terminal-pilot.js +6 -4
  47. package/dist/terminal-pilot.js.map +3 -3
  48. package/dist/terminal-session.js +6 -4
  49. package/dist/terminal-session.js.map +3 -3
  50. package/dist/testing/cli-repl.js +467 -193
  51. package/dist/testing/cli-repl.js.map +4 -4
  52. package/dist/testing/qa-cli.js +467 -193
  53. package/dist/testing/qa-cli.js.map +4 -4
  54. package/node_modules/@poe-code/agent-skill-config/dist/apply.js +4 -1
  55. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +1 -1
  56. package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.js +17 -9
  57. package/node_modules/@poe-code/agent-skill-config/dist/templates.js +4 -1
  58. package/package.json +1 -1
@@ -658,6 +658,11 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
658
658
  return input.length;
659
659
  }
660
660
 
661
+ // src/errors.ts
662
+ function hasOwnErrorCode(error2, code) {
663
+ return error2 instanceof Error && Object.prototype.hasOwnProperty.call(error2, "code") && error2.code === code;
664
+ }
665
+
661
666
  // src/terminal-buffer.ts
662
667
  var RESET_SGR = "\x1B[0m";
663
668
  var DEC_SPECIAL_GRAPHICS = {
@@ -1757,10 +1762,7 @@ function ensureSpawnHelperExecutable() {
1757
1762
  }
1758
1763
  }
1759
1764
  function isMissingFileError(error2) {
1760
- if (!(error2 instanceof Error)) {
1761
- return false;
1762
- }
1763
- return "code" in error2 && error2.code === "ENOENT";
1765
+ return hasOwnErrorCode(error2, "ENOENT");
1764
1766
  }
1765
1767
  function matchPattern(buffer, pattern) {
1766
1768
  const clean = normalizeHistoryBuffer(stripAnsi(buffer));
@@ -2130,6 +2132,11 @@ var claudeCodeAgent = {
2130
2132
  aliases: ["claude"],
2131
2133
  binaryName: "claude",
2132
2134
  apiShapes: ["anthropic-messages"],
2135
+ otelCapture: {
2136
+ env: {
2137
+ CLAUDE_CODE_ENABLE_TELEMETRY: "1"
2138
+ }
2139
+ },
2133
2140
  configPath: "~/.claude/settings.json",
2134
2141
  branding: {
2135
2142
  colors: {
@@ -2162,6 +2169,16 @@ var codexAgent = {
2162
2169
  summary: "Configure Codex to use Poe as the model provider.",
2163
2170
  binaryName: "codex",
2164
2171
  apiShapes: ["openai-responses"],
2172
+ otelCapture: {
2173
+ args: (endpoint, content) => [
2174
+ "-c",
2175
+ `otel.trace_exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/traces`)},protocol="json"}}`,
2176
+ "-c",
2177
+ `otel.exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/logs`)},protocol="json"}}`,
2178
+ "-c",
2179
+ `otel.log_user_prompt=${content}`
2180
+ ]
2181
+ },
2165
2182
  configPath: "~/.codex/config.toml",
2166
2183
  branding: {
2167
2184
  colors: {
@@ -2197,6 +2214,11 @@ var openCodeAgent = {
2197
2214
  summary: "Configure OpenCode CLI to use the Poe API.",
2198
2215
  binaryName: "opencode",
2199
2216
  apiShapes: ["openai-chat-completions"],
2217
+ otelCapture: {
2218
+ env: {
2219
+ OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
2220
+ }
2221
+ },
2200
2222
  configPath: "~/.config/opencode/config.json",
2201
2223
  branding: {
2202
2224
  colors: {
@@ -2232,6 +2254,7 @@ var gooseAgent = {
2232
2254
  summary: "Block's open-source AI agent with ACP support.",
2233
2255
  binaryName: "goose",
2234
2256
  apiShapes: ["openai-chat-completions"],
2257
+ otelCapture: {},
2235
2258
  configPath: "~/.config/goose/config.yaml",
2236
2259
  branding: {
2237
2260
  colors: {
@@ -2265,6 +2288,12 @@ function freezeAgent(agent) {
2265
2288
  if (agent.apiShapes !== void 0) {
2266
2289
  Object.freeze(agent.apiShapes);
2267
2290
  }
2291
+ if (agent.otelCapture?.env !== void 0) {
2292
+ Object.freeze(agent.otelCapture.env);
2293
+ }
2294
+ if (agent.otelCapture !== void 0) {
2295
+ Object.freeze(agent.otelCapture);
2296
+ }
2268
2297
  Object.freeze(agent.branding.colors);
2269
2298
  Object.freeze(agent.branding);
2270
2299
  return Object.freeze(agent);
@@ -2428,6 +2457,7 @@ var templateMutation = {
2428
2457
  };
2429
2458
 
2430
2459
  // ../config-mutations/src/execution/apply-mutation.ts
2460
+ import { randomUUID as randomUUID2 } from "node:crypto";
2431
2461
  import path4 from "node:path";
2432
2462
 
2433
2463
  // ../toolcraft-design/src/internal/color-support.ts
@@ -3510,7 +3540,7 @@ function merge(base, patch) {
3510
3540
  if (value === void 0) {
3511
3541
  continue;
3512
3542
  }
3513
- const existing = result[key];
3543
+ const existing = hasConfigEntry(result, key) ? result[key] : void 0;
3514
3544
  if (isConfigObject(existing) && isConfigObject(value)) {
3515
3545
  setConfigEntry(result, key, merge(existing, value));
3516
3546
  continue;
@@ -3638,7 +3668,7 @@ function merge2(base, patch) {
3638
3668
  if (value === void 0) {
3639
3669
  continue;
3640
3670
  }
3641
- const existing = result[key];
3671
+ const existing = hasConfigEntry(result, key) ? result[key] : void 0;
3642
3672
  if (isConfigObject2(existing) && isConfigObject2(value)) {
3643
3673
  setConfigEntry(result, key, merge2(existing, value));
3644
3674
  continue;
@@ -3718,7 +3748,7 @@ function merge3(base, patch) {
3718
3748
  if (value === void 0) {
3719
3749
  continue;
3720
3750
  }
3721
- const existing = result[key];
3751
+ const existing = hasConfigEntry(result, key) ? result[key] : void 0;
3722
3752
  if (isConfigObject3(existing) && isConfigObject3(value)) {
3723
3753
  setConfigEntry(result, key, merge3(existing, value));
3724
3754
  continue;
@@ -3855,7 +3885,7 @@ function resolvePath(rawPath, homeDir, pathMapper) {
3855
3885
 
3856
3886
  // ../config-mutations/src/fs-utils.ts
3857
3887
  function isNotFound(error2) {
3858
- return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
3888
+ return typeof error2 === "object" && error2 !== null && Object.prototype.hasOwnProperty.call(error2, "code") && error2.code === "ENOENT";
3859
3889
  }
3860
3890
  async function readFileIfExists(fs3, target) {
3861
3891
  try {
@@ -3904,6 +3934,7 @@ async function backupInvalidDocument(context, targetPath, content) {
3904
3934
  return;
3905
3935
  } catch (error2) {
3906
3936
  if (!isAlreadyExists(error2)) {
3937
+ await context.fs.unlink(backupPath).catch(() => void 0);
3907
3938
  throw error2;
3908
3939
  }
3909
3940
  attempt += 1;
@@ -3911,7 +3942,7 @@ async function backupInvalidDocument(context, targetPath, content) {
3911
3942
  }
3912
3943
  }
3913
3944
  function isAlreadyExists(error2) {
3914
- return Boolean(error2 && typeof error2 === "object" && "code" in error2 && error2.code === "EEXIST");
3945
+ return typeof error2 === "object" && error2 !== null && Object.prototype.hasOwnProperty.call(error2, "code") && error2.code === "EEXIST";
3915
3946
  }
3916
3947
  async function assertRegularWriteTarget(context, targetPath) {
3917
3948
  const boundary = path4.dirname(path4.resolve(context.homeDir));
@@ -3935,28 +3966,34 @@ async function assertRegularWriteTarget(context, targetPath) {
3935
3966
  }
3936
3967
  async function writeAtomically(context, targetPath, content) {
3937
3968
  await assertRegularWriteTarget(context, targetPath);
3938
- let attempt = 0;
3939
- while (true) {
3940
- const tempPath = `${targetPath}.mutation-tmp-${attempt}`;
3969
+ for (let attempt = 0; attempt < 10; attempt += 1) {
3970
+ const tempPath = `${targetPath}.mutation-tmp-${process.pid}-${randomUUID2()}`;
3971
+ let tempCreated = false;
3941
3972
  try {
3973
+ await assertRegularWriteTarget(context, tempPath);
3942
3974
  await context.fs.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
3975
+ tempCreated = true;
3943
3976
  await context.fs.rename(tempPath, targetPath);
3977
+ tempCreated = false;
3944
3978
  return;
3945
3979
  } catch (error2) {
3946
- if (isAlreadyExists(error2)) {
3947
- attempt += 1;
3948
- continue;
3949
- }
3950
- try {
3951
- await context.fs.unlink(tempPath);
3952
- } catch (cleanupError) {
3953
- if (!isNotFound(cleanupError)) {
3954
- void cleanupError;
3980
+ const alreadyExists = isAlreadyExists(error2);
3981
+ if (tempCreated || !alreadyExists) {
3982
+ try {
3983
+ await context.fs.unlink(tempPath);
3984
+ } catch (cleanupError) {
3985
+ if (!isNotFound(cleanupError)) {
3986
+ void cleanupError;
3987
+ }
3955
3988
  }
3956
3989
  }
3990
+ if (alreadyExists) {
3991
+ continue;
3992
+ }
3957
3993
  throw error2;
3958
3994
  }
3959
3995
  }
3996
+ throw new Error(`Unable to create temporary mutation file for ${targetPath}.`);
3960
3997
  }
3961
3998
  function describeMutation(kind, targetPath) {
3962
3999
  const displayPath = targetPath ?? "target";
@@ -4248,6 +4285,7 @@ async function applyBackup(mutation, context, options) {
4248
4285
  break;
4249
4286
  } catch (error2) {
4250
4287
  if (!isAlreadyExists(error2)) {
4288
+ await context.fs.unlink(backupPath).catch(() => void 0);
4251
4289
  throw error2;
4252
4290
  }
4253
4291
  attempt += 1;
@@ -4655,7 +4693,7 @@ async function pathExists2(fs3, targetPath) {
4655
4693
  await fs3.stat(targetPath);
4656
4694
  return true;
4657
4695
  } catch (error2) {
4658
- if (error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT") {
4696
+ if (typeof error2 === "object" && error2 !== null && Object.prototype.hasOwnProperty.call(error2, "code") && error2.code === "ENOENT") {
4659
4697
  return false;
4660
4698
  }
4661
4699
  throw error2;
@@ -4714,12 +4752,13 @@ import path6 from "node:path";
4714
4752
 
4715
4753
  // ../agent-skill-config/src/git-exclude.ts
4716
4754
  import { execFileSync } from "node:child_process";
4755
+ import { randomUUID as randomUUID3 } from "node:crypto";
4717
4756
  import * as fs from "node:fs";
4718
4757
  import path7 from "node:path";
4719
4758
 
4720
4759
  // ../agent-skill-config/src/bridge-active-skills.ts
4721
4760
  import * as fs2 from "node:fs";
4722
- import { createHash, randomUUID as randomUUID2 } from "node:crypto";
4761
+ import { createHash, randomUUID as randomUUID4 } from "node:crypto";
4723
4762
  import path8 from "node:path";
4724
4763
 
4725
4764
  // src/commands/installer.ts
@@ -4732,7 +4771,7 @@ var DEFAULT_INSTALL_SCOPE = "local";
4732
4771
  var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
4733
4772
  var installableAgents = supportedAgents;
4734
4773
  function isNotFoundError(error2) {
4735
- return typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT";
4774
+ return hasOwnErrorCode(error2, "ENOENT");
4736
4775
  }
4737
4776
  function resolveInstallerServices(installer) {
4738
4777
  return {
@@ -4963,7 +5002,7 @@ var resize = defineCommand({
4963
5002
  });
4964
5003
 
4965
5004
  // ../terminal-png/src/index.ts
4966
- import { randomUUID as randomUUID3 } from "node:crypto";
5005
+ import { randomUUID as randomUUID5 } from "node:crypto";
4967
5006
  import { rename, rm, writeFile } from "node:fs/promises";
4968
5007
 
4969
5008
  // ../terminal-png/src/ansi-parser.ts
@@ -5903,21 +5942,28 @@ async function renderTerminalPng(ansiText, options = {}) {
5903
5942
  });
5904
5943
  const png = renderPng(svg);
5905
5944
  if (options.output) {
5906
- const temporaryPath = `${options.output}.${randomUUID3()}.tmp`;
5945
+ const temporaryPath = `${options.output}.${randomUUID5()}.tmp`;
5946
+ let temporaryCreated = false;
5907
5947
  try {
5908
5948
  await writeFile(temporaryPath, png, { flag: "wx" });
5949
+ temporaryCreated = true;
5909
5950
  await rename(temporaryPath, options.output);
5910
5951
  } catch (error2) {
5911
- try {
5912
- await rm(temporaryPath, { force: true });
5913
- } catch (cleanupError) {
5914
- void cleanupError;
5952
+ if (temporaryCreated || !isAlreadyExistsError(error2)) {
5953
+ try {
5954
+ await rm(temporaryPath, { force: true });
5955
+ } catch (cleanupError) {
5956
+ void cleanupError;
5957
+ }
5915
5958
  }
5916
5959
  throw error2;
5917
5960
  }
5918
5961
  }
5919
5962
  return png;
5920
5963
  }
5964
+ function isAlreadyExistsError(error2) {
5965
+ return error2 instanceof Error && Object.prototype.hasOwnProperty.call(error2, "code") && error2.code === "EEXIST";
5966
+ }
5921
5967
 
5922
5968
  // src/commands/screenshot.ts
5923
5969
  var params11 = S.Object({
@@ -5980,7 +6026,7 @@ var type = defineCommand({
5980
6026
  });
5981
6027
 
5982
6028
  // src/commands/uninstall.ts
5983
- import { randomUUID as randomUUID4 } from "node:crypto";
6029
+ import { randomUUID as randomUUID6 } from "node:crypto";
5984
6030
  var params14 = S.Object({
5985
6031
  agent: S.Enum(installableAgents, {
5986
6032
  description: "Agent to uninstall terminal-pilot from",
@@ -6016,7 +6062,7 @@ var uninstall = defineCommand({
6016
6062
  if (!await folderExists(services.fs, skill.fullPath)) {
6017
6063
  continue;
6018
6064
  }
6019
- const stagingPath = `${skill.fullPath}.removing-${randomUUID4()}`;
6065
+ const stagingPath = `${skill.fullPath}.removing-${randomUUID6()}`;
6020
6066
  await services.fs.rename(skill.fullPath, stagingPath);
6021
6067
  staged.push({ ...skill, stagingPath });
6022
6068
  }
@@ -6042,7 +6088,7 @@ async function folderExists(fs3, folderPath) {
6042
6088
  await fs3.stat(folderPath);
6043
6089
  return true;
6044
6090
  } catch (error2) {
6045
- if (typeof error2 === "object" && error2 !== null && "code" in error2 && error2.code === "ENOENT") {
6091
+ if (hasOwnErrorCode(error2, "ENOENT")) {
6046
6092
  return false;
6047
6093
  }
6048
6094
  throw error2;