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
package/dist/cli.js CHANGED
@@ -11,7 +11,7 @@ import path23 from "node:path";
11
11
  import { fileURLToPath as fileURLToPath5 } from "node:url";
12
12
 
13
13
  // ../toolcraft/src/cli.ts
14
- import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
14
+ import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
15
15
  import path14 from "node:path";
16
16
  import {
17
17
  Command as CommanderCommand,
@@ -2727,27 +2727,27 @@ function validateMachine(machine) {
2727
2727
  if (!isRecord(machine)) {
2728
2728
  throw new TypeError("State machine must be an object.");
2729
2729
  }
2730
- if (!isStateList(machine.states)) {
2730
+ if (!hasOwnRecordField(machine, "states") || !isStateList(machine.states)) {
2731
2731
  throw new TypeError("State machine states must be a string array.");
2732
2732
  }
2733
2733
  const states = new Set(machine.states);
2734
- if (typeof machine.initial !== "string") {
2734
+ if (!hasOwnRecordField(machine, "initial") || typeof machine.initial !== "string") {
2735
2735
  throw new TypeError("State machine initial must be a string.");
2736
2736
  }
2737
2737
  if (!states.has(machine.initial)) {
2738
2738
  throw new Error(`Initial state "${machine.initial}" is not declared.`);
2739
2739
  }
2740
- if (!isRecord(machine.events)) {
2740
+ if (!hasOwnRecordField(machine, "events") || !isRecord(machine.events)) {
2741
2741
  throw new TypeError("State machine events must be an object.");
2742
2742
  }
2743
2743
  for (const [eventName, event] of Object.entries(machine.events)) {
2744
2744
  if (!isRecord(event)) {
2745
2745
  throw new TypeError(`Event "${eventName}" must be an object.`);
2746
2746
  }
2747
- if (event.from !== "*" && !isStateList(event.from)) {
2747
+ if (!hasOwnRecordField(event, "from") || event.from !== "*" && !isStateList(event.from)) {
2748
2748
  throw new TypeError(`Event "${eventName}" has an invalid "from" definition.`);
2749
2749
  }
2750
- if (typeof event.to !== "string") {
2750
+ if (!hasOwnRecordField(event, "to") || typeof event.to !== "string") {
2751
2751
  throw new TypeError(`Event "${eventName}" target state must be a string.`);
2752
2752
  }
2753
2753
  if (!states.has(event.to)) {
@@ -2762,6 +2762,9 @@ function validateMachine(machine) {
2762
2762
  }
2763
2763
  }
2764
2764
  }
2765
+ function hasOwnRecordField(record, key2) {
2766
+ return Object.prototype.hasOwnProperty.call(record, key2);
2767
+ }
2765
2768
  function eventsFromState(machine, fromState) {
2766
2769
  const events = [];
2767
2770
  for (const [eventName, event] of Object.entries(machine.events)) {
@@ -3033,6 +3036,7 @@ function resolveEndpoint(options = {}) {
3033
3036
  }
3034
3037
 
3035
3038
  // ../task-list/src/backends/utils.ts
3039
+ import { randomUUID as randomUUID2 } from "node:crypto";
3036
3040
  import path6 from "node:path";
3037
3041
  function compareCreated(left, right) {
3038
3042
  const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
@@ -3053,9 +3057,8 @@ function applyOrder(entries, order) {
3053
3057
  }
3054
3058
  return entries.map((entry) => entry.task);
3055
3059
  }
3056
- var tmpFileCounter = 0;
3057
3060
  function hasErrorCode(error3, code) {
3058
- return !!error3 && typeof error3 === "object" && "code" in error3 && error3.code === code;
3061
+ return !!error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
3059
3062
  }
3060
3063
  function isRecord2(value) {
3061
3064
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -3102,18 +3105,22 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
3102
3105
  }
3103
3106
  }
3104
3107
  async function writeAtomically(fs4, filePath, content) {
3105
- const tempPath = `${filePath}.tmp-${process.pid}-${tmpFileCounter}`;
3106
- tmpFileCounter += 1;
3108
+ const tempPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
3109
+ let tempCreated = false;
3107
3110
  await fs4.mkdir(path6.dirname(filePath), { recursive: true });
3108
3111
  try {
3109
3112
  await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
3113
+ tempCreated = true;
3110
3114
  await fs4.rename(tempPath, filePath);
3115
+ tempCreated = false;
3111
3116
  } catch (error3) {
3112
- try {
3113
- await fs4.unlink(tempPath);
3114
- } catch (unlinkError) {
3115
- if (!hasErrorCode(unlinkError, "ENOENT")) {
3116
- throw unlinkError;
3117
+ if (tempCreated || !hasErrorCode(error3, "EEXIST")) {
3118
+ try {
3119
+ await fs4.unlink(tempPath);
3120
+ } catch (unlinkError) {
3121
+ if (!hasErrorCode(unlinkError, "ENOENT")) {
3122
+ throw unlinkError;
3123
+ }
3117
3124
  }
3118
3125
  }
3119
3126
  throw error3;
@@ -3127,6 +3134,7 @@ async function withFileLock(fs4, lockPath, operation) {
3127
3134
  break;
3128
3135
  } catch (error3) {
3129
3136
  if (!hasErrorCode(error3, "EEXIST")) {
3137
+ await fs4.unlink(lockPath).catch(() => void 0);
3130
3138
  throw error3;
3131
3139
  }
3132
3140
  if (await removeAbandonedLock(fs4, lockPath)) {
@@ -4410,27 +4418,30 @@ function readFrontmatter(frontmatterContent, filePath) {
4410
4418
  return parsed;
4411
4419
  }
4412
4420
  function assertValidTaskRecord(frontmatter, filePath, validStates) {
4413
- if ("$schema" in frontmatter && frontmatter.$schema !== TASK_SCHEMA_ID) {
4421
+ if (hasOwnTaskField(frontmatter, "$schema") && frontmatter.$schema !== TASK_SCHEMA_ID) {
4414
4422
  throw malformedTask(filePath, "$schema");
4415
4423
  }
4416
- if ("kind" in frontmatter && frontmatter.kind !== TASK_KIND) {
4424
+ if (hasOwnTaskField(frontmatter, "kind") && frontmatter.kind !== TASK_KIND) {
4417
4425
  throw malformedTask(filePath, "kind");
4418
4426
  }
4419
- if ("version" in frontmatter) {
4427
+ if (hasOwnTaskField(frontmatter, "version")) {
4420
4428
  if (typeof frontmatter.version !== "number" || !Number.isInteger(frontmatter.version) || frontmatter.version !== TASK_VERSION) {
4421
4429
  throw malformedTask(filePath, "version");
4422
4430
  }
4423
4431
  }
4424
- if (typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
4432
+ if (!hasOwnTaskField(frontmatter, "name") || typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
4425
4433
  throw malformedTask(filePath, "name");
4426
4434
  }
4427
- if (typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
4435
+ if (!hasOwnTaskField(frontmatter, "state") || typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
4428
4436
  throw malformedTask(filePath, "state");
4429
4437
  }
4430
- if ("description" in frontmatter && typeof frontmatter.description !== "string") {
4438
+ if (hasOwnTaskField(frontmatter, "description") && typeof frontmatter.description !== "string") {
4431
4439
  throw malformedTask(filePath, "description");
4432
4440
  }
4433
4441
  }
4442
+ function hasOwnTaskField(frontmatter, key2) {
4443
+ return Object.prototype.hasOwnProperty.call(frontmatter, key2);
4444
+ }
4434
4445
  function reservedFrontmatterKeys(mode) {
4435
4446
  return mode === "passthrough" ? PASSTHROUGH_RESERVED_FRONTMATTER_KEYS : RESERVED_FRONTMATTER_KEYS;
4436
4447
  }
@@ -5279,7 +5290,8 @@ function parseQualifiedId3(qualifiedId) {
5279
5290
  };
5280
5291
  }
5281
5292
  function descriptionFromTaskRecord(taskRecord) {
5282
- return typeof taskRecord.description === "string" ? taskRecord.description : "";
5293
+ const description = getOwnEntry(taskRecord, "description");
5294
+ return typeof description === "string" ? description : "";
5283
5295
  }
5284
5296
  function metadataFromTaskRecord(taskRecord) {
5285
5297
  const metadata = /* @__PURE__ */ Object.create(null);
@@ -5295,8 +5307,8 @@ function createTask2(list, id, taskRecord, sourcePath) {
5295
5307
  list,
5296
5308
  id,
5297
5309
  qualifiedId: `${list}/${id}`,
5298
- name: taskRecord.name,
5299
- state: taskRecord.state,
5310
+ name: getOwnEntry(taskRecord, "name"),
5311
+ state: getOwnEntry(taskRecord, "state"),
5300
5312
  description: descriptionFromTaskRecord(taskRecord),
5301
5313
  metadata: metadataFromTaskRecord(taskRecord),
5302
5314
  ...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
@@ -5393,16 +5405,17 @@ function assertValidStoreRecord(store, filePath) {
5393
5405
  if (!isRecord2(store)) {
5394
5406
  throw malformedStore(filePath, "store");
5395
5407
  }
5396
- if (store.$schema !== STORE_SCHEMA_ID) {
5408
+ if (getOwnEntry(store, "$schema") !== STORE_SCHEMA_ID) {
5397
5409
  throw malformedStore(filePath, "$schema");
5398
5410
  }
5399
- if (store.kind !== STORE_KIND) {
5411
+ if (getOwnEntry(store, "kind") !== STORE_KIND) {
5400
5412
  throw malformedStore(filePath, "kind");
5401
5413
  }
5402
- if (typeof store.version !== "number" || !Number.isInteger(store.version) || store.version !== STORE_VERSION) {
5414
+ const version = getOwnEntry(store, "version");
5415
+ if (typeof version !== "number" || !Number.isInteger(version) || version !== STORE_VERSION) {
5403
5416
  throw malformedStore(filePath, "version");
5404
5417
  }
5405
- if (!isRecord2(store.lists)) {
5418
+ if (!isRecord2(getOwnEntry(store, "lists"))) {
5406
5419
  throw malformedStore(filePath, "lists");
5407
5420
  }
5408
5421
  }
@@ -5410,29 +5423,38 @@ function assertValidTaskRecord2(taskRecord, list, id, validStates) {
5410
5423
  if (!isRecord2(taskRecord)) {
5411
5424
  throw malformedTask2(list, id, "task");
5412
5425
  }
5413
- if ("$schema" in taskRecord && taskRecord.$schema !== TASK_SCHEMA_ID2) {
5426
+ if (hasOwnTaskField2(taskRecord, "$schema") && getOwnEntry(taskRecord, "$schema") !== TASK_SCHEMA_ID2) {
5414
5427
  throw malformedTask2(list, id, "$schema");
5415
5428
  }
5416
- if ("kind" in taskRecord && taskRecord.kind !== TASK_KIND2) {
5429
+ if (hasOwnTaskField2(taskRecord, "kind") && getOwnEntry(taskRecord, "kind") !== TASK_KIND2) {
5417
5430
  throw malformedTask2(list, id, "kind");
5418
5431
  }
5419
- if ("version" in taskRecord) {
5420
- if (typeof taskRecord.version !== "number" || !Number.isInteger(taskRecord.version) || taskRecord.version !== TASK_VERSION2) {
5432
+ if (hasOwnTaskField2(taskRecord, "version")) {
5433
+ const version = getOwnEntry(taskRecord, "version");
5434
+ if (typeof version !== "number" || !Number.isInteger(version) || version !== TASK_VERSION2) {
5421
5435
  throw malformedTask2(list, id, "version");
5422
5436
  }
5423
5437
  }
5424
- if (typeof taskRecord.name !== "string" || taskRecord.name.length === 0) {
5438
+ const name = getOwnEntry(taskRecord, "name");
5439
+ if (!hasOwnTaskField2(taskRecord, "name") || typeof name !== "string" || name.length === 0) {
5425
5440
  throw malformedTask2(list, id, "name");
5426
5441
  }
5427
- if (typeof taskRecord.state !== "string" || !validStates.has(taskRecord.state)) {
5442
+ const state = getOwnEntry(taskRecord, "state");
5443
+ if (!hasOwnTaskField2(taskRecord, "state") || typeof state !== "string" || !validStates.has(state)) {
5428
5444
  throw malformedTask2(list, id, "state");
5429
5445
  }
5430
- if ("description" in taskRecord && typeof taskRecord.description !== "string") {
5446
+ if (hasOwnTaskField2(taskRecord, "description") && typeof getOwnEntry(taskRecord, "description") !== "string") {
5431
5447
  throw malformedTask2(list, id, "description");
5432
5448
  }
5433
5449
  }
5450
+ function hasOwnTaskField2(taskRecord, key2) {
5451
+ return Object.prototype.hasOwnProperty.call(taskRecord, key2);
5452
+ }
5453
+ function getOwnEntry(record, key2) {
5454
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
5455
+ }
5434
5456
  function validateStoreEntries(store, filePath, validStates) {
5435
- const lists = store.lists;
5457
+ const lists = getOwnEntry(store, "lists");
5436
5458
  if (!isRecord2(lists)) {
5437
5459
  throw malformedStore(filePath, "lists");
5438
5460
  }
@@ -5472,10 +5494,11 @@ async function readStore(fs4, filePath, validStates) {
5472
5494
  };
5473
5495
  }
5474
5496
  function getListsRecord(store) {
5475
- return store.lists;
5497
+ const lists = getOwnEntry(store, "lists");
5498
+ return isRecord2(lists) ? lists : {};
5476
5499
  }
5477
5500
  function getListRecord(store, list) {
5478
- const listRecord = getListsRecord(store)[list];
5501
+ const listRecord = getOwnEntry(getListsRecord(store), list);
5479
5502
  return isRecord2(listRecord) ? listRecord : void 0;
5480
5503
  }
5481
5504
  function getTaskRecord(store, list, id) {
@@ -5768,7 +5791,7 @@ async function yamlFileBackend(deps) {
5768
5791
  const result = [];
5769
5792
  const listNames = sortStrings(Object.keys(getListsRecord(store)));
5770
5793
  for (const listName of listNames) {
5771
- const listRecord = getListsRecord(store)[listName];
5794
+ const listRecord = getOwnEntry(getListsRecord(store), listName);
5772
5795
  if (!isRecord2(listRecord)) continue;
5773
5796
  const entries = Object.entries(listRecord).map(([id, taskRecord]) => ({
5774
5797
  task: createTask2(listName, id, taskRecord, deps.path),
@@ -6402,8 +6425,8 @@ function createHandlerContext(command, params17) {
6402
6425
  function createFs() {
6403
6426
  return {
6404
6427
  readFile: async (path24, encoding = "utf8") => readFile2(path24, { encoding }),
6405
- writeFile: async (path24, contents) => {
6406
- await writeFile2(path24, contents);
6428
+ writeFile: async (path24, contents, options) => {
6429
+ await writeFile2(path24, contents, options);
6407
6430
  },
6408
6431
  exists: async (path24) => {
6409
6432
  try {
@@ -6692,16 +6715,16 @@ function isMissingStateError(error3) {
6692
6715
 
6693
6716
  // ../toolcraft/src/error-report.ts
6694
6717
  import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
6695
- import { randomUUID as randomUUID3 } from "node:crypto";
6718
+ import { randomUUID as randomUUID5 } from "node:crypto";
6696
6719
  import os from "node:os";
6697
6720
  import path13 from "node:path";
6698
6721
  import { CommanderError } from "commander";
6699
6722
 
6700
6723
  // ../toolcraft/src/mcp-proxy.ts
6701
6724
  import { existsSync as existsSync2 } from "node:fs";
6702
- import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
6725
+ import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
6703
6726
  import path12 from "node:path";
6704
- import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
6727
+ import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
6705
6728
 
6706
6729
  // ../tiny-mcp-client/src/internal.ts
6707
6730
  import { spawn as spawn5 } from "node:child_process";
@@ -6712,7 +6735,7 @@ import crypto from "node:crypto";
6712
6735
  import path11 from "node:path";
6713
6736
 
6714
6737
  // ../auth-store/src/encrypted-file-store.ts
6715
- import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
6738
+ import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, randomUUID as randomUUID3, scrypt } from "node:crypto";
6716
6739
  import { promises as fs } from "node:fs";
6717
6740
  import { homedir, hostname, userInfo } from "node:os";
6718
6741
  import path10 from "node:path";
@@ -6723,7 +6746,6 @@ var ENCRYPTION_KEY_BYTES = 32;
6723
6746
  var ENCRYPTION_IV_BYTES = 12;
6724
6747
  var ENCRYPTION_AUTH_TAG_BYTES = 16;
6725
6748
  var ENCRYPTION_FILE_MODE = 384;
6726
- var temporaryFileSequence = 0;
6727
6749
  var EncryptedFileStore = class {
6728
6750
  fs;
6729
6751
  filePath;
@@ -6755,7 +6777,7 @@ var EncryptedFileStore = class {
6755
6777
  this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
6756
6778
  }
6757
6779
  async get() {
6758
- await this.assertRegularCredentialPath();
6780
+ await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
6759
6781
  let rawDocument;
6760
6782
  try {
6761
6783
  rawDocument = await this.fs.readFile(this.filePath, "utf8");
@@ -6786,7 +6808,7 @@ var EncryptedFileStore = class {
6786
6808
  }
6787
6809
  }
6788
6810
  async set(value) {
6789
- await this.assertRegularCredentialPath();
6811
+ await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
6790
6812
  const key2 = await this.getEncryptionKey();
6791
6813
  const iv = this.getRandomBytes(ENCRYPTION_IV_BYTES);
6792
6814
  const cipher = createCipheriv(ENCRYPTION_ALGORITHM, key2, iv);
@@ -6802,25 +6824,28 @@ var EncryptedFileStore = class {
6802
6824
  ciphertext: ciphertext.toString("base64")
6803
6825
  };
6804
6826
  await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
6805
- await this.assertRegularCredentialPath();
6806
- const temporaryPath = `${this.filePath}.${process.pid}.${temporaryFileSequence++}.tmp`;
6827
+ await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
6828
+ const temporaryPath = `${this.filePath}.${process.pid}.${randomUUID3()}.tmp`;
6829
+ let temporaryCreated = false;
6807
6830
  try {
6831
+ await this.assertCredentialPathHasNoSymbolicLinks(temporaryPath);
6808
6832
  await this.fs.writeFile(temporaryPath, JSON.stringify(document), {
6809
6833
  encoding: "utf8",
6810
6834
  flag: "wx",
6811
6835
  mode: ENCRYPTION_FILE_MODE
6812
6836
  });
6837
+ temporaryCreated = true;
6813
6838
  await this.fs.chmod(temporaryPath, ENCRYPTION_FILE_MODE);
6814
6839
  await this.fs.rename(temporaryPath, this.filePath);
6815
6840
  } catch (error3) {
6816
- if (!isAlreadyExistsError(error3)) {
6841
+ if (temporaryCreated || !isAlreadyExistsError(error3)) {
6817
6842
  await removeIfPresent(this.fs, temporaryPath).catch(() => void 0);
6818
6843
  }
6819
6844
  throw error3;
6820
6845
  }
6821
6846
  }
6822
6847
  async delete() {
6823
- await this.assertRegularCredentialPath();
6848
+ await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
6824
6849
  try {
6825
6850
  await this.fs.unlink(this.filePath);
6826
6851
  } catch (error3) {
@@ -6829,8 +6854,8 @@ var EncryptedFileStore = class {
6829
6854
  }
6830
6855
  }
6831
6856
  }
6832
- async assertRegularCredentialPath() {
6833
- const resolvedPath = path10.resolve(this.filePath);
6857
+ async assertCredentialPathHasNoSymbolicLinks(targetPath) {
6858
+ const resolvedPath = path10.resolve(targetPath);
6834
6859
  const protectedPaths = getProtectedCredentialPaths(
6835
6860
  resolvedPath,
6836
6861
  this.symbolicLinkCheckStartPath
@@ -6895,9 +6920,6 @@ async function removeIfPresent(fileSystem, filePath) {
6895
6920
  }
6896
6921
  }
6897
6922
  }
6898
- function isAlreadyExistsError(error3) {
6899
- return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "EEXIST";
6900
- }
6901
6923
  function defaultMachineIdentity() {
6902
6924
  return {
6903
6925
  hostname: hostname(),
@@ -6935,17 +6957,21 @@ function parseEncryptedDocument(raw) {
6935
6957
  if (!isRecord4(parsed)) {
6936
6958
  return null;
6937
6959
  }
6938
- if (parsed.version !== ENCRYPTION_VERSION) {
6960
+ const version = getOwnEntry2(parsed, "version");
6961
+ const iv = getOwnEntry2(parsed, "iv");
6962
+ const authTag = getOwnEntry2(parsed, "authTag");
6963
+ const ciphertext = getOwnEntry2(parsed, "ciphertext");
6964
+ if (version !== ENCRYPTION_VERSION) {
6939
6965
  return null;
6940
6966
  }
6941
- if (typeof parsed.iv !== "string" || typeof parsed.authTag !== "string" || typeof parsed.ciphertext !== "string") {
6967
+ if (typeof iv !== "string" || typeof authTag !== "string" || typeof ciphertext !== "string") {
6942
6968
  return null;
6943
6969
  }
6944
6970
  return {
6945
- version: parsed.version,
6946
- iv: parsed.iv,
6947
- authTag: parsed.authTag,
6948
- ciphertext: parsed.ciphertext
6971
+ version,
6972
+ iv,
6973
+ authTag,
6974
+ ciphertext
6949
6975
  };
6950
6976
  } catch {
6951
6977
  return null;
@@ -6954,9 +6980,17 @@ function parseEncryptedDocument(raw) {
6954
6980
  function isRecord4(value) {
6955
6981
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
6956
6982
  }
6983
+ function getOwnEntry2(record, key2) {
6984
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
6985
+ }
6957
6986
  function isNotFoundError(error3) {
6958
6987
  return Boolean(
6959
- error3 && typeof error3 === "object" && "code" in error3 && error3.code === "ENOENT"
6988
+ error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT"
6989
+ );
6990
+ }
6991
+ function isAlreadyExistsError(error3) {
6992
+ return Boolean(
6993
+ error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST"
6960
6994
  );
6961
6995
  }
6962
6996
 
@@ -6978,8 +7012,8 @@ var KeychainStore = class {
6978
7012
  ["find-generic-password", "-s", this.service, "-a", this.account, "-w"],
6979
7013
  "read secret from macOS Keychain"
6980
7014
  );
6981
- if (result.exitCode === 0) {
6982
- return stripTrailingLineBreak(result.stdout);
7015
+ if (getCommandExitCode(result) === 0) {
7016
+ return stripTrailingLineBreak(getCommandOutput(result, "stdout"));
6983
7017
  }
6984
7018
  if (isKeychainEntryNotFound(result)) {
6985
7019
  return null;
@@ -7003,7 +7037,7 @@ var KeychainStore = class {
7003
7037
  "store secret in macOS Keychain",
7004
7038
  { stdin: value }
7005
7039
  );
7006
- if (result.exitCode !== 0) {
7040
+ if (getCommandExitCode(result) !== 0) {
7007
7041
  throw createSecurityCliFailure("store secret in macOS Keychain", result);
7008
7042
  }
7009
7043
  }
@@ -7012,7 +7046,7 @@ var KeychainStore = class {
7012
7046
  ["delete-generic-password", "-s", this.service, "-a", this.account],
7013
7047
  "delete secret from macOS Keychain"
7014
7048
  );
7015
- if (result.exitCode === 0 || isKeychainEntryNotFound(result)) {
7049
+ if (getCommandExitCode(result) === 0 || isKeychainEntryNotFound(result)) {
7016
7050
  return;
7017
7051
  }
7018
7052
  throw createSecurityCliFailure("delete secret from macOS Keychain", result);
@@ -7091,16 +7125,28 @@ function stripTrailingLineBreak(value) {
7091
7125
  return value;
7092
7126
  }
7093
7127
  function isKeychainEntryNotFound(result) {
7094
- return result.exitCode === KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE;
7128
+ return getCommandExitCode(result) === KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE;
7095
7129
  }
7096
7130
  function createSecurityCliFailure(operation, result) {
7097
- const details = result.stderr.trim() || result.stdout.trim();
7131
+ const exitCode = getCommandExitCode(result);
7132
+ const details = getCommandOutput(result, "stderr").trim() || getCommandOutput(result, "stdout").trim();
7098
7133
  if (details) {
7099
7134
  return new Error(
7100
- `Failed to ${operation}: security exited with code ${result.exitCode}: ${details}`
7135
+ `Failed to ${operation}: security exited with code ${exitCode}: ${details}`
7101
7136
  );
7102
7137
  }
7103
- return new Error(`Failed to ${operation}: security exited with code ${result.exitCode}`);
7138
+ return new Error(`Failed to ${operation}: security exited with code ${exitCode}`);
7139
+ }
7140
+ function getCommandExitCode(result) {
7141
+ const value = getOwnEntry3(result, "exitCode");
7142
+ return typeof value === "number" && Number.isInteger(value) ? value : 1;
7143
+ }
7144
+ function getCommandOutput(result, key2) {
7145
+ const value = getOwnEntry3(result, key2);
7146
+ return typeof value === "string" ? value : "";
7147
+ }
7148
+ function getOwnEntry3(record, key2) {
7149
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
7104
7150
  }
7105
7151
 
7106
7152
  // ../auth-store/src/create-secret-store.ts
@@ -7133,7 +7179,7 @@ function createSecretStore(input) {
7133
7179
  }
7134
7180
  function resolveBackend(input) {
7135
7181
  const envVar = input.backendEnvVar ?? DEFAULT_BACKEND_ENV_VAR;
7136
- const configuredBackend = input.backend ?? input.env?.[envVar] ?? process.env[envVar];
7182
+ const configuredBackend = input.backend ?? getOwnEnvValue(input.env, envVar) ?? getOwnEnvValue(process.env, envVar);
7137
7183
  if (configuredBackend === "keychain") {
7138
7184
  return "keychain";
7139
7185
  }
@@ -7142,6 +7188,9 @@ function resolveBackend(input) {
7142
7188
  }
7143
7189
  throw new Error(`Unsupported auth store backend: ${configuredBackend}`);
7144
7190
  }
7191
+ function getOwnEnvValue(env, key2) {
7192
+ return env !== void 0 && Object.prototype.hasOwnProperty.call(env, key2) ? env[key2] : void 0;
7193
+ }
7145
7194
 
7146
7195
  // ../mcp-oauth/src/resource-indicator.ts
7147
7196
  function canonicalizeResourceIndicator(value) {
@@ -7195,8 +7244,13 @@ function createAuthStoreClientStore(options) {
7195
7244
  return null;
7196
7245
  }
7197
7246
  const parsed = JSON.parse(value);
7198
- if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && typeof parsed.clientId === "string") {
7199
- return parsed;
7247
+ const clientId = isObjectRecord(parsed) ? getOwnString(parsed, "clientId") : void 0;
7248
+ if (clientId !== void 0) {
7249
+ const client = { clientId };
7250
+ if (isObjectRecord(parsed) && Object.prototype.hasOwnProperty.call(parsed, "clientSecret")) {
7251
+ client.clientSecret = getOwnEntry4(parsed, "clientSecret");
7252
+ }
7253
+ return client;
7200
7254
  }
7201
7255
  throw new Error("Stored OAuth client must be a JSON object with clientId");
7202
7256
  },
@@ -7255,6 +7309,16 @@ function createIssuerSecretStore(issuer, options) {
7255
7309
  }
7256
7310
  );
7257
7311
  }
7312
+ function isObjectRecord(value) {
7313
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7314
+ }
7315
+ function getOwnEntry4(record, key2) {
7316
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
7317
+ }
7318
+ function getOwnString(record, key2) {
7319
+ const value = getOwnEntry4(record, key2);
7320
+ return typeof value === "string" ? value : void 0;
7321
+ }
7258
7322
 
7259
7323
  // ../mcp-oauth/src/client/default-oauth-client-provider.ts
7260
7324
  import { URL as URL2 } from "node:url";
@@ -7280,17 +7344,30 @@ function parseAuthorizationState(value) {
7280
7344
  try {
7281
7345
  const decoded = Buffer.from(value, "base64url").toString("utf8");
7282
7346
  const parsed = JSON.parse(decoded);
7283
- if (parsed.v !== 1 || typeof parsed.n !== "string" || parsed.n.length === 0 || typeof parsed.i !== "string" || parsed.i.length === 0 || typeof parsed.r !== "boolean") {
7347
+ if (!isObjectRecord2(parsed)) {
7348
+ return null;
7349
+ }
7350
+ const version = getOwnEntry5(parsed, "v");
7351
+ const nonce = getOwnEntry5(parsed, "n");
7352
+ const issuer = getOwnEntry5(parsed, "i");
7353
+ const requireIssuer = getOwnEntry5(parsed, "r");
7354
+ if (version !== 1 || typeof nonce !== "string" || nonce.length === 0 || typeof issuer !== "string" || issuer.length === 0 || typeof requireIssuer !== "boolean") {
7284
7355
  return null;
7285
7356
  }
7286
7357
  return {
7287
- issuer: parsed.i,
7288
- requireIssuer: parsed.r
7358
+ issuer,
7359
+ requireIssuer
7289
7360
  };
7290
7361
  } catch {
7291
7362
  return null;
7292
7363
  }
7293
7364
  }
7365
+ function isObjectRecord2(value) {
7366
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7367
+ }
7368
+ function getOwnEntry5(record, key2) {
7369
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
7370
+ }
7294
7371
 
7295
7372
  // ../mcp-oauth/src/client/loopback-authorization.ts
7296
7373
  async function createLoopbackAuthorizationSession(options = {}) {
@@ -7567,22 +7644,26 @@ async function requestTokens(input) {
7567
7644
  body: body.toString()
7568
7645
  });
7569
7646
  const payload = await readOAuthJsonObjectResponse(response);
7570
- if (typeof payload.access_token !== "string" || payload.access_token.trim().length === 0) {
7647
+ const accessToken = getOwnEntry6(payload, "access_token");
7648
+ if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
7571
7649
  throw new Error("OAuth token response missing access_token");
7572
7650
  }
7573
- const tokenType = normalizeBearerTokenType(payload.token_type);
7651
+ const tokenType = normalizeBearerTokenType(getOwnEntry6(payload, "token_type"));
7574
7652
  if (tokenType === null) {
7575
7653
  throw new Error("OAuth token response missing token_type=Bearer");
7576
7654
  }
7577
- if (typeof payload.expires_in === "number" && Number.isFinite(payload.expires_in) && payload.expires_in < 0) {
7655
+ const expiresIn = getOwnEntry6(payload, "expires_in");
7656
+ if (typeof expiresIn === "number" && Number.isFinite(expiresIn) && expiresIn < 0) {
7578
7657
  throw new Error("OAuth token response has invalid expires_in");
7579
7658
  }
7659
+ const refreshToken = getOwnEntry6(payload, "refresh_token");
7660
+ const scope = getOwnEntry6(payload, "scope");
7580
7661
  return {
7581
- accessToken: payload.access_token,
7582
- refreshToken: typeof payload.refresh_token === "string" && payload.refresh_token.length > 0 ? payload.refresh_token : void 0,
7662
+ accessToken,
7663
+ refreshToken: typeof refreshToken === "string" && refreshToken.length > 0 ? refreshToken : void 0,
7583
7664
  tokenType,
7584
- expiresAt: typeof payload.expires_in === "number" && Number.isFinite(payload.expires_in) ? input.now() + payload.expires_in * 1e3 : null,
7585
- scope: typeof payload.scope === "string" && payload.scope.length > 0 ? payload.scope : void 0
7665
+ expiresAt: typeof expiresIn === "number" && Number.isFinite(expiresIn) ? input.now() + expiresIn * 1e3 : null,
7666
+ scope: typeof scope === "string" && scope.length > 0 ? scope : void 0
7586
7667
  };
7587
7668
  }
7588
7669
  async function readOAuthJsonObjectResponse(response) {
@@ -7609,12 +7690,18 @@ async function readOAuthJsonObjectResponse(response) {
7609
7690
  return record;
7610
7691
  }
7611
7692
  function readOAuthError(payload, fallbackError = "server_error") {
7693
+ const error3 = getOwnEntry6(payload, "error");
7694
+ const errorDescription = getOwnEntry6(payload, "error_description");
7695
+ const errorUri = getOwnEntry6(payload, "error_uri");
7612
7696
  return {
7613
- error: typeof payload.error === "string" ? payload.error : fallbackError,
7614
- error_description: typeof payload.error_description === "string" ? payload.error_description : void 0,
7615
- error_uri: typeof payload.error_uri === "string" ? payload.error_uri : void 0
7697
+ error: typeof error3 === "string" ? error3 : fallbackError,
7698
+ error_description: typeof errorDescription === "string" ? errorDescription : void 0,
7699
+ error_uri: typeof errorUri === "string" ? errorUri : void 0
7616
7700
  };
7617
7701
  }
7702
+ function getOwnEntry6(record, key2) {
7703
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
7704
+ }
7618
7705
  function createFallbackOAuthError(status) {
7619
7706
  const error3 = status === 503 ? "temporarily_unavailable" : "server_error";
7620
7707
  return new OAuthError({ error: error3 }, status);
@@ -7719,7 +7806,11 @@ function createDefaultOAuthClientProvider(options) {
7719
7806
  while (true) {
7720
7807
  try {
7721
7808
  refreshedTokens = await refreshAccessToken({
7722
- tokenEndpoint: discovery.authorizationServerMetadata.token_endpoint,
7809
+ tokenEndpoint: requireOwnString(
7810
+ discovery.authorizationServerMetadata,
7811
+ "token_endpoint",
7812
+ "Authorization server metadata"
7813
+ ),
7723
7814
  clientId: session.client.clientId,
7724
7815
  clientSecret: session.client.clientSecret,
7725
7816
  refreshToken: session.tokens.refreshToken,
@@ -7807,7 +7898,11 @@ function createDefaultOAuthClientProvider(options) {
7807
7898
  });
7808
7899
  const code = await loopback.waitForCode(authorizationUrl);
7809
7900
  const tokens = await exchangeAuthorizationCode({
7810
- tokenEndpoint: discovery.authorizationServerMetadata.token_endpoint,
7901
+ tokenEndpoint: requireOwnString(
7902
+ discovery.authorizationServerMetadata,
7903
+ "token_endpoint",
7904
+ "Authorization server metadata"
7905
+ ),
7811
7906
  clientId: resolvedClient.client.clientId,
7812
7907
  clientSecret: resolvedClient.client.clientSecret,
7813
7908
  code,
@@ -7860,7 +7955,10 @@ function createDefaultOAuthClientProvider(options) {
7860
7955
  }
7861
7956
  };
7862
7957
  }
7863
- const registrationEndpoint = discovery.authorizationServerMetadata.registration_endpoint;
7958
+ const registrationEndpoint = getOwnString2(
7959
+ discovery.authorizationServerMetadata,
7960
+ "registration_endpoint"
7961
+ );
7864
7962
  if (registrationEndpoint === void 0 && options.client.clientId !== void 0) {
7865
7963
  return {
7866
7964
  kind: "static",
@@ -7912,12 +8010,14 @@ function createDefaultOAuthClientProvider(options) {
7912
8010
  body: JSON.stringify(registrationBody)
7913
8011
  });
7914
8012
  const payload = await readOAuthJsonObjectResponse(response);
7915
- if (typeof payload.client_id !== "string" || payload.client_id.trim().length === 0) {
8013
+ const clientId = getOwnString2(payload, "client_id");
8014
+ if (clientId === void 0 || clientId.trim().length === 0) {
7916
8015
  throw new Error("OAuth client registration response missing client_id");
7917
8016
  }
8017
+ const clientSecret = getOwnString2(payload, "client_secret");
7918
8018
  const registeredClient = {
7919
- clientId: payload.client_id,
7920
- clientSecret: typeof payload.client_secret === "string" && payload.client_secret.length > 0 ? payload.client_secret : void 0
8019
+ clientId,
8020
+ clientSecret: clientSecret !== void 0 && clientSecret.length > 0 ? clientSecret : void 0
7921
8021
  };
7922
8022
  await saveRegisteredClient(discovery.authorizationServer, registeredClient);
7923
8023
  return {
@@ -7943,12 +8043,13 @@ function createDefaultOAuthClientProvider(options) {
7943
8043
  return null;
7944
8044
  }
7945
8045
  const client = await clientStore.load(issuer);
7946
- if (client !== null && !isUsableClient(client)) {
8046
+ const normalizedClient = client === null ? null : normalizeStoredClient(client);
8047
+ if (client !== null && normalizedClient === null) {
7947
8048
  await clientStore.clear(issuer);
7948
8049
  return null;
7949
8050
  }
7950
- registeredClients.set(issuer, client);
7951
- return client;
8051
+ registeredClients.set(issuer, normalizedClient);
8052
+ return normalizedClient;
7952
8053
  }
7953
8054
  async function saveRegisteredClient(issuer, client) {
7954
8055
  registeredClients.set(issuer, client);
@@ -7964,7 +8065,7 @@ function createDefaultOAuthClientProvider(options) {
7964
8065
  }
7965
8066
  }
7966
8067
  function isProviderOptions(options) {
7967
- return "provider" in options;
8068
+ return Object.prototype.hasOwnProperty.call(options, "provider");
7968
8069
  }
7969
8070
  function isExpired(tokens, now) {
7970
8071
  return tokens.expiresAt !== null && tokens.expiresAt <= now();
@@ -7980,7 +8081,14 @@ function resolveDiscovery(discovery, session) {
7980
8081
  return void 0;
7981
8082
  }
7982
8083
  const metadata = session.discovery.authorizationServerMetadata;
7983
- if (typeof metadata.issuer !== "string" || typeof metadata.authorization_endpoint !== "string" || typeof metadata.token_endpoint !== "string" || !Array.isArray(metadata.code_challenge_methods_supported) || !metadata.code_challenge_methods_supported.includes("S256")) {
8084
+ const issuer = getOwnString2(metadata, "issuer");
8085
+ const authorizationEndpoint = getOwnString2(metadata, "authorization_endpoint");
8086
+ const tokenEndpoint = getOwnString2(metadata, "token_endpoint");
8087
+ const codeChallengeMethodsSupported = getOwnStringArray(
8088
+ metadata,
8089
+ "code_challenge_methods_supported"
8090
+ );
8091
+ if (issuer === void 0 || authorizationEndpoint === void 0 || tokenEndpoint === void 0 || codeChallengeMethodsSupported === void 0 || !codeChallengeMethodsSupported.includes("S256")) {
7984
8092
  return void 0;
7985
8093
  }
7986
8094
  return {
@@ -8004,29 +8112,94 @@ function normalizeLoadedSession(session) {
8004
8112
  if (session === null) {
8005
8113
  return null;
8006
8114
  }
8007
- if (!isUsableClient(session.client)) {
8115
+ const client = normalizeStoredClient(getOwnEntry7(session, "client"));
8116
+ if (client === null) {
8008
8117
  return { ...session, client: { clientId: "" }, tokens: void 0 };
8009
8118
  }
8010
- return isUsableTokens(session.tokens) ? session : { ...session, tokens: void 0 };
8119
+ return {
8120
+ ...session,
8121
+ client,
8122
+ tokens: normalizeStoredTokens(getOwnEntry7(session, "tokens"))
8123
+ };
8011
8124
  }
8012
- function isUsableClient(client) {
8013
- return typeof client.clientId === "string" && client.clientId.trim().length > 0 && (client.clientSecret === void 0 || typeof client.clientSecret === "string" && client.clientSecret.trim().length > 0);
8125
+ function normalizeStoredClient(value) {
8126
+ if (!isObjectRecord3(value)) {
8127
+ return null;
8128
+ }
8129
+ const clientId = getOwnString2(value, "clientId");
8130
+ if (clientId === void 0 || clientId.trim().length === 0) {
8131
+ return null;
8132
+ }
8133
+ const clientSecret = getOwnEntry7(value, "clientSecret");
8134
+ if (clientSecret === void 0) {
8135
+ return { clientId };
8136
+ }
8137
+ if (typeof clientSecret !== "string" || clientSecret.trim().length === 0) {
8138
+ return null;
8139
+ }
8140
+ return { clientId, clientSecret };
8014
8141
  }
8015
- function isUsableTokens(tokens) {
8016
- if (tokens === void 0) {
8017
- return true;
8142
+ function normalizeStoredTokens(value) {
8143
+ if (value === void 0 || !isObjectRecord3(value)) {
8144
+ return void 0;
8018
8145
  }
8019
- return typeof tokens.accessToken === "string" && tokens.accessToken.trim().length > 0 && tokens.tokenType === "Bearer" && (tokens.expiresAt === null || typeof tokens.expiresAt === "number" && Number.isFinite(tokens.expiresAt)) && (tokens.refreshToken === void 0 || typeof tokens.refreshToken === "string" && tokens.refreshToken.trim().length > 0);
8146
+ const accessToken = getOwnString2(value, "accessToken");
8147
+ const tokenType = getOwnString2(value, "tokenType");
8148
+ const expiresAt = getOwnEntry7(value, "expiresAt");
8149
+ const refreshToken = getOwnEntry7(value, "refreshToken");
8150
+ const scope = getOwnString2(value, "scope");
8151
+ const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken : void 0;
8152
+ if (accessToken === void 0 || accessToken.trim().length === 0 || tokenType !== "Bearer" || !(expiresAt === null || typeof expiresAt === "number" && Number.isFinite(expiresAt)) || refreshToken !== void 0 && (typeof refreshToken !== "string" || refreshToken.trim().length === 0)) {
8153
+ return void 0;
8154
+ }
8155
+ return {
8156
+ accessToken,
8157
+ tokenType,
8158
+ expiresAt,
8159
+ ...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
8160
+ ...scope === void 0 || scope.length === 0 ? {} : { scope }
8161
+ };
8020
8162
  }
8021
8163
  function getClientMetadata(client) {
8022
8164
  return client.metadata;
8023
8165
  }
8166
+ function getOwnEntry7(record, key2) {
8167
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
8168
+ }
8169
+ function isObjectRecord3(value) {
8170
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8171
+ }
8172
+ function getOwnString2(record, key2) {
8173
+ const value = getOwnEntry7(record, key2);
8174
+ return typeof value === "string" ? value : void 0;
8175
+ }
8176
+ function requireOwnString(record, key2, label) {
8177
+ const value = getOwnString2(record, key2);
8178
+ if (value === void 0) {
8179
+ throw new Error(`${label} is missing ${key2}`);
8180
+ }
8181
+ return value;
8182
+ }
8183
+ function getOwnStringArray(record, key2) {
8184
+ const value = getOwnEntry7(record, key2);
8185
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
8186
+ }
8024
8187
  function buildAuthorizationUrl(input) {
8025
- const url = new URL2(input.metadata.authorization_endpoint);
8188
+ const authorizationEndpoint = requireOwnString(
8189
+ input.metadata,
8190
+ "authorization_endpoint",
8191
+ "Authorization server metadata"
8192
+ );
8193
+ const issuer = requireOwnString(
8194
+ input.metadata,
8195
+ "issuer",
8196
+ "Authorization server metadata"
8197
+ );
8198
+ const url = new URL2(authorizationEndpoint);
8026
8199
  const resource = canonicalizeResourceIndicator(input.resource);
8027
8200
  const state = createAuthorizationState({
8028
- issuer: input.metadata.issuer,
8029
- requireIssuer: input.metadata.authorization_response_iss_parameter_supported === true
8201
+ issuer,
8202
+ requireIssuer: getOwnEntry7(input.metadata, "authorization_response_iss_parameter_supported") === true
8030
8203
  });
8031
8204
  url.searchParams.set("response_type", "code");
8032
8205
  url.searchParams.set("client_id", input.clientId);
@@ -8041,7 +8214,7 @@ function buildAuthorizationUrl(input) {
8041
8214
  return url.toString();
8042
8215
  }
8043
8216
  function assertS256PkceSupport(metadata) {
8044
- if (!metadata.code_challenge_methods_supported.includes("S256")) {
8217
+ if (!getOwnStringArray(metadata, "code_challenge_methods_supported")?.includes("S256")) {
8045
8218
  throw new Error(
8046
8219
  "Authorization server metadata must advertise code_challenge_methods_supported including S256"
8047
8220
  );
@@ -8065,13 +8238,24 @@ function assertSecureUrl(value, label) {
8065
8238
  throw new Error(`${label} must use https unless it targets a loopback host`);
8066
8239
  }
8067
8240
  function assertSecureOAuthFlowEndpoints(metadata) {
8068
- assertNoAccessTokenInUrl(metadata.authorization_endpoint, "Authorization endpoint");
8069
- assertNoAccessTokenInUrl(metadata.token_endpoint, "Token endpoint");
8070
- assertSecureUrl(metadata.authorization_endpoint, "Authorization endpoint");
8071
- assertSecureUrl(metadata.token_endpoint, "Token endpoint");
8072
- if (metadata.registration_endpoint !== void 0) {
8073
- assertNoAccessTokenInUrl(metadata.registration_endpoint, "Registration endpoint");
8074
- assertSecureUrl(metadata.registration_endpoint, "Registration endpoint");
8241
+ const authorizationEndpoint = requireOwnString(
8242
+ metadata,
8243
+ "authorization_endpoint",
8244
+ "Authorization server metadata"
8245
+ );
8246
+ const tokenEndpoint = requireOwnString(
8247
+ metadata,
8248
+ "token_endpoint",
8249
+ "Authorization server metadata"
8250
+ );
8251
+ const registrationEndpoint = getOwnString2(metadata, "registration_endpoint");
8252
+ assertNoAccessTokenInUrl(authorizationEndpoint, "Authorization endpoint");
8253
+ assertNoAccessTokenInUrl(tokenEndpoint, "Token endpoint");
8254
+ assertSecureUrl(authorizationEndpoint, "Authorization endpoint");
8255
+ assertSecureUrl(tokenEndpoint, "Token endpoint");
8256
+ if (registrationEndpoint !== void 0) {
8257
+ assertNoAccessTokenInUrl(registrationEndpoint, "Registration endpoint");
8258
+ assertSecureUrl(registrationEndpoint, "Registration endpoint");
8075
8259
  }
8076
8260
  }
8077
8261
  function assertNoAccessTokenInUrl(value, label) {
@@ -8094,17 +8278,21 @@ function buildClientRegistrationBody(metadata, redirectUri) {
8094
8278
  response_types: ["code"],
8095
8279
  token_endpoint_auth_method: "none"
8096
8280
  };
8097
- if (metadata?.clientName !== void 0 && metadata.clientName.length > 0) {
8098
- body.client_name = metadata.clientName;
8281
+ const clientName = metadata === void 0 ? void 0 : getOwnString2(metadata, "clientName");
8282
+ const scope = metadata === void 0 ? void 0 : getOwnString2(metadata, "scope");
8283
+ const softwareId = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareId");
8284
+ const softwareVersion = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareVersion");
8285
+ if (clientName !== void 0 && clientName.length > 0) {
8286
+ body.client_name = clientName;
8099
8287
  }
8100
- if (metadata?.scope !== void 0 && metadata.scope.length > 0) {
8101
- body.scope = metadata.scope;
8288
+ if (scope !== void 0 && scope.length > 0) {
8289
+ body.scope = scope;
8102
8290
  }
8103
- if (metadata?.softwareId !== void 0 && metadata.softwareId.length > 0) {
8104
- body.software_id = metadata.softwareId;
8291
+ if (softwareId !== void 0 && softwareId.length > 0) {
8292
+ body.software_id = softwareId;
8105
8293
  }
8106
- if (metadata?.softwareVersion !== void 0 && metadata.softwareVersion.length > 0) {
8107
- body.software_version = metadata.softwareVersion;
8294
+ if (softwareVersion !== void 0 && softwareVersion.length > 0) {
8295
+ body.software_version = softwareVersion;
8108
8296
  }
8109
8297
  return body;
8110
8298
  }
@@ -8140,7 +8328,7 @@ import {
8140
8328
  function defaultOAuthMetadataFetch(input, init) {
8141
8329
  return fetch(input, init);
8142
8330
  }
8143
- function isObjectRecord(value) {
8331
+ function isObjectRecord4(value) {
8144
8332
  return typeof value === "object" && value !== null && !Array.isArray(value);
8145
8333
  }
8146
8334
  function isStringArray(value) {
@@ -8163,7 +8351,7 @@ function assertSecureUrl2(url, label) {
8163
8351
  throw new Error(`${label} must use https unless it targets a loopback host`);
8164
8352
  }
8165
8353
  function validateProtectedResourceMetadata(value, resourceUrl) {
8166
- if (!isObjectRecord(value)) {
8354
+ if (!isObjectRecord4(value)) {
8167
8355
  throw new Error("Protected resource metadata must be a JSON object");
8168
8356
  }
8169
8357
  if (typeof value.resource !== "string" || value.resource.length === 0) {
@@ -8186,7 +8374,7 @@ function validateProtectedResourceMetadata(value, resourceUrl) {
8186
8374
  };
8187
8375
  }
8188
8376
  function validateAuthorizationServerMetadata(value, issuer) {
8189
- if (!isObjectRecord(value)) {
8377
+ if (!isObjectRecord4(value)) {
8190
8378
  throw new Error("Authorization server metadata must be a JSON object");
8191
8379
  }
8192
8380
  if (typeof value.issuer !== "string" || value.issuer.length === 0) {
@@ -8639,7 +8827,7 @@ var McpClient = class {
8639
8827
  await onPromptsChanged();
8640
8828
  });
8641
8829
  messageLayer.onNotification("notifications/message", async (params17) => {
8642
- if (onLog === void 0 || !isObjectRecord2(params17) || !isLogLevel(params17.level)) {
8830
+ if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
8643
8831
  return;
8644
8832
  }
8645
8833
  if (!hasOwn(params17, "data")) {
@@ -8658,7 +8846,7 @@ var McpClient = class {
8658
8846
  await onLog(message2);
8659
8847
  });
8660
8848
  messageLayer.onNotification("notifications/progress", async (params17) => {
8661
- if (onProgress === void 0 || !isObjectRecord2(params17)) {
8849
+ if (onProgress === void 0 || !isObjectRecord5(params17)) {
8662
8850
  return;
8663
8851
  }
8664
8852
  const { progressToken, progress } = params17;
@@ -9859,7 +10047,7 @@ var JsonRpcMessageLayer = class {
9859
10047
  })();
9860
10048
  }
9861
10049
  handleCancellationNotification(params17) {
9862
- if (!isObjectRecord2(params17)) {
10050
+ if (!isObjectRecord5(params17)) {
9863
10051
  return;
9864
10052
  }
9865
10053
  const requestId = params17.requestId;
@@ -9874,34 +10062,34 @@ var JsonRpcMessageLayer = class {
9874
10062
  this.activeIncomingRequests.delete(requestId);
9875
10063
  }
9876
10064
  };
9877
- function isObjectRecord2(value) {
10065
+ function isObjectRecord5(value) {
9878
10066
  return typeof value === "object" && value !== null && !Array.isArray(value);
9879
10067
  }
9880
10068
  function isInitializeResult(value) {
9881
- if (!isObjectRecord2(value) || typeof value.protocolVersion !== "string") {
10069
+ if (!isObjectRecord5(value) || typeof value.protocolVersion !== "string") {
9882
10070
  return false;
9883
10071
  }
9884
10072
  if (!isServerCapabilities(value.capabilities)) {
9885
10073
  return false;
9886
10074
  }
9887
- if (!isObjectRecord2(value.serverInfo) || typeof value.serverInfo.name !== "string" || value.serverInfo.name.length === 0 || typeof value.serverInfo.version !== "string" || value.serverInfo.version.length === 0) {
10075
+ if (!isObjectRecord5(value.serverInfo) || typeof value.serverInfo.name !== "string" || value.serverInfo.name.length === 0 || typeof value.serverInfo.version !== "string" || value.serverInfo.version.length === 0) {
9888
10076
  return false;
9889
10077
  }
9890
10078
  return value.instructions === void 0 || typeof value.instructions === "string";
9891
10079
  }
9892
10080
  function isServerCapabilities(value) {
9893
- if (!isObjectRecord2(value)) {
10081
+ if (!isObjectRecord5(value)) {
9894
10082
  return false;
9895
10083
  }
9896
10084
  for (const capability of ["prompts", "resources", "tools", "logging", "completions", "experimental"]) {
9897
- if (value[capability] !== void 0 && !isObjectRecord2(value[capability])) {
10085
+ if (value[capability] !== void 0 && !isObjectRecord5(value[capability])) {
9898
10086
  return false;
9899
10087
  }
9900
10088
  }
9901
10089
  return true;
9902
10090
  }
9903
10091
  function isCallToolResult(value) {
9904
- if (!isObjectRecord2(value) || !Array.isArray(value.content)) {
10092
+ if (!isObjectRecord5(value) || !Array.isArray(value.content)) {
9905
10093
  return false;
9906
10094
  }
9907
10095
  if (value.isError !== void 0 && typeof value.isError !== "boolean") {
@@ -9910,10 +10098,10 @@ function isCallToolResult(value) {
9910
10098
  return value.content.every(isContentItem);
9911
10099
  }
9912
10100
  function isToolsListResult(value) {
9913
- return isObjectRecord2(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
10101
+ return isObjectRecord5(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
9914
10102
  }
9915
10103
  function isContentItem(value) {
9916
- if (!isObjectRecord2(value)) {
10104
+ if (!isObjectRecord5(value)) {
9917
10105
  return false;
9918
10106
  }
9919
10107
  if (value.type === "text") {
@@ -9922,7 +10110,7 @@ function isContentItem(value) {
9922
10110
  if (value.type === "image" || value.type === "audio") {
9923
10111
  return typeof value.data === "string" && typeof value.mimeType === "string";
9924
10112
  }
9925
- if (value.type !== "resource" || !isObjectRecord2(value.resource)) {
10113
+ if (value.type !== "resource" || !isObjectRecord5(value.resource)) {
9926
10114
  return false;
9927
10115
  }
9928
10116
  return typeof value.resource.uri === "string" && (value.resource.mimeType === void 0 || typeof value.resource.mimeType === "string") && (typeof value.resource.text === "string" || typeof value.resource.blob === "string");
@@ -9946,7 +10134,7 @@ function invalidRequest() {
9946
10134
  return new McpError(ERROR_INVALID_REQUEST, "Invalid Request");
9947
10135
  }
9948
10136
  function isJsonRpcErrorObject(value) {
9949
- if (!isObjectRecord2(value)) {
10137
+ if (!isObjectRecord5(value)) {
9950
10138
  return false;
9951
10139
  }
9952
10140
  if (typeof value.code !== "number" || typeof value.message !== "string") {
@@ -9955,7 +10143,7 @@ function isJsonRpcErrorObject(value) {
9955
10143
  return value.data === void 0 || hasOwn(value, "data");
9956
10144
  }
9957
10145
  function parseJsonRpcPayload(parsed) {
9958
- if (!isObjectRecord2(parsed)) {
10146
+ if (!isObjectRecord5(parsed)) {
9959
10147
  return {
9960
10148
  type: "invalid",
9961
10149
  id: null,
@@ -10282,7 +10470,11 @@ function convertObjectSchema(schema, root, options) {
10282
10470
  "properties",
10283
10471
  key2
10284
10472
  ]);
10285
- shape[key2] = requiredKeys.has(key2) ? convertedProperty : S.Optional(convertedProperty);
10473
+ setOwnShapeProperty(
10474
+ shape,
10475
+ key2,
10476
+ requiredKeys.has(key2) ? convertedProperty : S.Optional(convertedProperty)
10477
+ );
10286
10478
  }
10287
10479
  return applyMetadata(
10288
10480
  S.Object(shape, {
@@ -10294,6 +10486,14 @@ function convertObjectSchema(schema, root, options) {
10294
10486
  }
10295
10487
  );
10296
10488
  }
10489
+ function setOwnShapeProperty(shape, key2, value) {
10490
+ Object.defineProperty(shape, key2, {
10491
+ configurable: true,
10492
+ enumerable: true,
10493
+ writable: true,
10494
+ value
10495
+ });
10496
+ }
10297
10497
  function createCommonOptions(schema, nullable, defaultValue) {
10298
10498
  return {
10299
10499
  ...schema.description === void 0 ? {} : { description: schema.description },
@@ -10544,6 +10744,9 @@ function resolveLocalRef(root, ref) {
10544
10744
  if (!isPlainObject(current)) {
10545
10745
  return void 0;
10546
10746
  }
10747
+ if (!Object.prototype.hasOwnProperty.call(current, segment)) {
10748
+ return void 0;
10749
+ }
10547
10750
  current = current[segment];
10548
10751
  }
10549
10752
  return isPlainObject(current) ? current : void 0;
@@ -10792,16 +10995,34 @@ async function readCache(cachePath) {
10792
10995
  }
10793
10996
  async function writeCache(cachePath, cache) {
10794
10997
  const directory = path12.dirname(cachePath);
10795
- const tempPath = `${cachePath}.tmp-${randomUUID2()}`;
10998
+ const tempPath = `${cachePath}.tmp-${randomUUID4()}`;
10999
+ let tempCreated = false;
10796
11000
  await assertCachePathHasNoSymlinks(cachePath);
10797
11001
  await assertCachePathHasNoSymlinks(tempPath);
10798
11002
  await mkdir(directory, { recursive: true });
10799
11003
  await assertCachePathHasNoSymlinks(directory);
10800
- await writeFile3(tempPath, `${JSON.stringify(cache, null, 2)}
10801
- `);
10802
- await assertCachePathHasNoSymlinks(tempPath);
10803
- await assertCachePathHasNoSymlinks(cachePath);
10804
- await rename2(tempPath, cachePath);
11004
+ try {
11005
+ await writeFile3(tempPath, `${JSON.stringify(cache, null, 2)}
11006
+ `, {
11007
+ encoding: "utf8",
11008
+ flag: "wx"
11009
+ });
11010
+ tempCreated = true;
11011
+ await assertCachePathHasNoSymlinks(tempPath);
11012
+ await assertCachePathHasNoSymlinks(cachePath);
11013
+ await rename2(tempPath, cachePath);
11014
+ tempCreated = false;
11015
+ } catch (error3) {
11016
+ if (tempCreated || !isAlreadyExistsError2(error3)) {
11017
+ await unlink2(tempPath).catch(() => void 0);
11018
+ }
11019
+ throw error3;
11020
+ }
11021
+ }
11022
+ function isAlreadyExistsError2(error3) {
11023
+ return Boolean(
11024
+ error3 && typeof error3 === "object" && error3.code === "EEXIST"
11025
+ );
10805
11026
  }
10806
11027
  async function fetchCache(name, config2) {
10807
11028
  const logger2 = createLogger((message2) => {
@@ -11541,7 +11762,7 @@ async function writeErrorReport(context) {
11541
11762
  }
11542
11763
  const projectRoot = resolveProjectRoot(context.projectRoot);
11543
11764
  const reportDir = resolveReportDir(context.errorReports, projectRoot);
11544
- const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID3()}.log`;
11765
+ const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID5()}.log`;
11545
11766
  const absolutePath = path13.join(reportDir, fileName);
11546
11767
  await mkdir2(reportDir, { recursive: true });
11547
11768
  if (reportDirMustStayWithinProject(context.errorReports)) {
@@ -13020,10 +13241,10 @@ function renderHelpSections(sections) {
13020
13241
  return sections.filter((section) => section.length > 0).join("\n\n");
13021
13242
  }
13022
13243
  function formatHelpCommandList(rows) {
13023
- return process.stdout.isTTY === false ? help_formatter_plain_exports.formatCommandList(rows) : formatCommandList(rows);
13244
+ return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatCommandList(rows) : formatCommandList(rows);
13024
13245
  }
13025
13246
  function formatHelpOptionList(rows) {
13026
- return process.stdout.isTTY === false ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
13247
+ return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
13027
13248
  }
13028
13249
  function buildUsageLine(breadcrumb, rootUsageName, suffix) {
13029
13250
  const visibleBreadcrumb = breadcrumb.filter((segment) => segment.length > 0);
@@ -13311,11 +13532,18 @@ function formatResolvedValue(value) {
13311
13532
  function fieldPromptLabel(field) {
13312
13533
  return field.positionalIndex === void 0 ? field.optionFlag : `<${field.displayPath}>`;
13313
13534
  }
13535
+ function enumOptionLabel(schema, value) {
13536
+ const key2 = String(value);
13537
+ if (schema.labels === void 0 || !Object.prototype.hasOwnProperty.call(schema.labels, key2)) {
13538
+ return key2;
13539
+ }
13540
+ return schema.labels[key2] ?? key2;
13541
+ }
13314
13542
  async function promptForField(field) {
13315
13543
  const schema = field.schema;
13316
13544
  if (schema.kind === "enum") {
13317
13545
  const options = schema.loadOptions ? await schema.loadOptions() : schema.values.map((value) => ({
13318
- label: schema.labels?.[String(value)] ?? String(value),
13546
+ label: enumOptionLabel(schema, value),
13319
13547
  value
13320
13548
  }));
13321
13549
  const selected = await select2({
@@ -13400,8 +13628,8 @@ async function withOutputFormat2(output, fn) {
13400
13628
  function createFs2() {
13401
13629
  return {
13402
13630
  readFile: async (path24, encoding = "utf8") => readFile4(path24, { encoding }),
13403
- writeFile: async (path24, contents) => {
13404
- await writeFile5(path24, contents);
13631
+ writeFile: async (path24, contents, options) => {
13632
+ await writeFile5(path24, contents, options);
13405
13633
  },
13406
13634
  exists: async (path24) => {
13407
13635
  try {
@@ -13413,7 +13641,7 @@ function createFs2() {
13413
13641
  },
13414
13642
  lstat: async (path24) => lstat3(path24),
13415
13643
  rename: async (fromPath, toPath) => rename3(fromPath, toPath),
13416
- unlink: async (path24) => unlink2(path24)
13644
+ unlink: async (path24) => unlink3(path24)
13417
13645
  };
13418
13646
  }
13419
13647
  function createEnv2(values = process.env) {
@@ -14669,7 +14897,7 @@ function isGraphQLErrorEnvelopeLike(body) {
14669
14897
  });
14670
14898
  }
14671
14899
  function styleHttpErrorLine(value, style) {
14672
- return process.stdout.isTTY === false ? value : style(value);
14900
+ return process.stdout.isTTY !== true ? value : style(value);
14673
14901
  }
14674
14902
  function formatHttpErrorStatus(value) {
14675
14903
  return styleHttpErrorLine(value, text.error);
@@ -15151,7 +15379,7 @@ async function runCLI(roots, options = {}) {
15151
15379
  }
15152
15380
 
15153
15381
  // src/terminal-pilot.ts
15154
- import { randomUUID as randomUUID4 } from "node:crypto";
15382
+ import { randomUUID as randomUUID6 } from "node:crypto";
15155
15383
 
15156
15384
  // src/terminal-session.ts
15157
15385
  import { EventEmitter } from "node:events";
@@ -15233,6 +15461,11 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
15233
15461
  return input.length;
15234
15462
  }
15235
15463
 
15464
+ // src/errors.ts
15465
+ function hasOwnErrorCode(error3, code) {
15466
+ return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
15467
+ }
15468
+
15236
15469
  // src/terminal-buffer.ts
15237
15470
  var RESET_SGR = "\x1B[0m";
15238
15471
  var DEC_SPECIAL_GRAPHICS = {
@@ -16332,10 +16565,7 @@ function ensureSpawnHelperExecutable() {
16332
16565
  }
16333
16566
  }
16334
16567
  function isMissingFileError(error3) {
16335
- if (!(error3 instanceof Error)) {
16336
- return false;
16337
- }
16338
- return "code" in error3 && error3.code === "ENOENT";
16568
+ return hasOwnErrorCode(error3, "ENOENT");
16339
16569
  }
16340
16570
  function matchPattern(buffer, pattern) {
16341
16571
  const clean = normalizeHistoryBuffer(stripAnsi4(buffer));
@@ -16426,7 +16656,7 @@ var TerminalPilot = class _TerminalPilot {
16426
16656
  }
16427
16657
  async newSession(opts) {
16428
16658
  const session = new TerminalSession({
16429
- id: randomUUID4(),
16659
+ id: randomUUID6(),
16430
16660
  command: opts.command,
16431
16661
  args: opts.args,
16432
16662
  cwd: opts.cwd,
@@ -16705,6 +16935,11 @@ var claudeCodeAgent = {
16705
16935
  aliases: ["claude"],
16706
16936
  binaryName: "claude",
16707
16937
  apiShapes: ["anthropic-messages"],
16938
+ otelCapture: {
16939
+ env: {
16940
+ CLAUDE_CODE_ENABLE_TELEMETRY: "1"
16941
+ }
16942
+ },
16708
16943
  configPath: "~/.claude/settings.json",
16709
16944
  branding: {
16710
16945
  colors: {
@@ -16737,6 +16972,16 @@ var codexAgent = {
16737
16972
  summary: "Configure Codex to use Poe as the model provider.",
16738
16973
  binaryName: "codex",
16739
16974
  apiShapes: ["openai-responses"],
16975
+ otelCapture: {
16976
+ args: (endpoint, content) => [
16977
+ "-c",
16978
+ `otel.trace_exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/traces`)},protocol="json"}}`,
16979
+ "-c",
16980
+ `otel.exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/logs`)},protocol="json"}}`,
16981
+ "-c",
16982
+ `otel.log_user_prompt=${content}`
16983
+ ]
16984
+ },
16740
16985
  configPath: "~/.codex/config.toml",
16741
16986
  branding: {
16742
16987
  colors: {
@@ -16772,6 +17017,11 @@ var openCodeAgent = {
16772
17017
  summary: "Configure OpenCode CLI to use the Poe API.",
16773
17018
  binaryName: "opencode",
16774
17019
  apiShapes: ["openai-chat-completions"],
17020
+ otelCapture: {
17021
+ env: {
17022
+ OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
17023
+ }
17024
+ },
16775
17025
  configPath: "~/.config/opencode/config.json",
16776
17026
  branding: {
16777
17027
  colors: {
@@ -16807,6 +17057,7 @@ var gooseAgent = {
16807
17057
  summary: "Block's open-source AI agent with ACP support.",
16808
17058
  binaryName: "goose",
16809
17059
  apiShapes: ["openai-chat-completions"],
17060
+ otelCapture: {},
16810
17061
  configPath: "~/.config/goose/config.yaml",
16811
17062
  branding: {
16812
17063
  colors: {
@@ -16840,6 +17091,12 @@ function freezeAgent(agent) {
16840
17091
  if (agent.apiShapes !== void 0) {
16841
17092
  Object.freeze(agent.apiShapes);
16842
17093
  }
17094
+ if (agent.otelCapture?.env !== void 0) {
17095
+ Object.freeze(agent.otelCapture.env);
17096
+ }
17097
+ if (agent.otelCapture !== void 0) {
17098
+ Object.freeze(agent.otelCapture);
17099
+ }
16843
17100
  Object.freeze(agent.branding.colors);
16844
17101
  Object.freeze(agent.branding);
16845
17102
  return Object.freeze(agent);
@@ -17003,6 +17260,7 @@ var templateMutation = {
17003
17260
  };
17004
17261
 
17005
17262
  // ../config-mutations/src/execution/apply-mutation.ts
17263
+ import { randomUUID as randomUUID7 } from "node:crypto";
17006
17264
  import path17 from "node:path";
17007
17265
 
17008
17266
  // ../config-mutations/src/formats/json.ts
@@ -17078,7 +17336,7 @@ function merge(base, patch) {
17078
17336
  if (value === void 0) {
17079
17337
  continue;
17080
17338
  }
17081
- const existing = result[key2];
17339
+ const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
17082
17340
  if (isConfigObject(existing) && isConfigObject(value)) {
17083
17341
  setConfigEntry(result, key2, merge(existing, value));
17084
17342
  continue;
@@ -17206,7 +17464,7 @@ function merge2(base, patch) {
17206
17464
  if (value === void 0) {
17207
17465
  continue;
17208
17466
  }
17209
- const existing = result[key2];
17467
+ const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
17210
17468
  if (isConfigObject2(existing) && isConfigObject2(value)) {
17211
17469
  setConfigEntry(result, key2, merge2(existing, value));
17212
17470
  continue;
@@ -17286,7 +17544,7 @@ function merge3(base, patch) {
17286
17544
  if (value === void 0) {
17287
17545
  continue;
17288
17546
  }
17289
- const existing = result[key2];
17547
+ const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
17290
17548
  if (isConfigObject3(existing) && isConfigObject3(value)) {
17291
17549
  setConfigEntry(result, key2, merge3(existing, value));
17292
17550
  continue;
@@ -17423,7 +17681,7 @@ function resolvePath(rawPath, homeDir, pathMapper) {
17423
17681
 
17424
17682
  // ../config-mutations/src/fs-utils.ts
17425
17683
  function isNotFound(error3) {
17426
- return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "ENOENT";
17684
+ return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT";
17427
17685
  }
17428
17686
  async function readFileIfExists(fs4, target) {
17429
17687
  try {
@@ -17472,6 +17730,7 @@ async function backupInvalidDocument(context, targetPath, content) {
17472
17730
  return;
17473
17731
  } catch (error3) {
17474
17732
  if (!isAlreadyExists(error3)) {
17733
+ await context.fs.unlink(backupPath).catch(() => void 0);
17475
17734
  throw error3;
17476
17735
  }
17477
17736
  attempt += 1;
@@ -17479,7 +17738,7 @@ async function backupInvalidDocument(context, targetPath, content) {
17479
17738
  }
17480
17739
  }
17481
17740
  function isAlreadyExists(error3) {
17482
- return Boolean(error3 && typeof error3 === "object" && "code" in error3 && error3.code === "EEXIST");
17741
+ return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
17483
17742
  }
17484
17743
  async function assertRegularWriteTarget(context, targetPath) {
17485
17744
  const boundary = path17.dirname(path17.resolve(context.homeDir));
@@ -17503,28 +17762,34 @@ async function assertRegularWriteTarget(context, targetPath) {
17503
17762
  }
17504
17763
  async function writeAtomically2(context, targetPath, content) {
17505
17764
  await assertRegularWriteTarget(context, targetPath);
17506
- let attempt = 0;
17507
- while (true) {
17508
- const tempPath = `${targetPath}.mutation-tmp-${attempt}`;
17765
+ for (let attempt = 0; attempt < 10; attempt += 1) {
17766
+ const tempPath = `${targetPath}.mutation-tmp-${process.pid}-${randomUUID7()}`;
17767
+ let tempCreated = false;
17509
17768
  try {
17769
+ await assertRegularWriteTarget(context, tempPath);
17510
17770
  await context.fs.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
17771
+ tempCreated = true;
17511
17772
  await context.fs.rename(tempPath, targetPath);
17773
+ tempCreated = false;
17512
17774
  return;
17513
17775
  } catch (error3) {
17514
- if (isAlreadyExists(error3)) {
17515
- attempt += 1;
17516
- continue;
17517
- }
17518
- try {
17519
- await context.fs.unlink(tempPath);
17520
- } catch (cleanupError) {
17521
- if (!isNotFound(cleanupError)) {
17522
- void cleanupError;
17776
+ const alreadyExists = isAlreadyExists(error3);
17777
+ if (tempCreated || !alreadyExists) {
17778
+ try {
17779
+ await context.fs.unlink(tempPath);
17780
+ } catch (cleanupError) {
17781
+ if (!isNotFound(cleanupError)) {
17782
+ void cleanupError;
17783
+ }
17523
17784
  }
17524
17785
  }
17786
+ if (alreadyExists) {
17787
+ continue;
17788
+ }
17525
17789
  throw error3;
17526
17790
  }
17527
17791
  }
17792
+ throw new Error(`Unable to create temporary mutation file for ${targetPath}.`);
17528
17793
  }
17529
17794
  function describeMutation(kind, targetPath) {
17530
17795
  const displayPath = targetPath ?? "target";
@@ -17816,6 +18081,7 @@ async function applyBackup(mutation, context, options) {
17816
18081
  break;
17817
18082
  } catch (error3) {
17818
18083
  if (!isAlreadyExists(error3)) {
18084
+ await context.fs.unlink(backupPath).catch(() => void 0);
17819
18085
  throw error3;
17820
18086
  }
17821
18087
  attempt += 1;
@@ -18223,7 +18489,7 @@ async function pathExists2(fs4, targetPath) {
18223
18489
  await fs4.stat(targetPath);
18224
18490
  return true;
18225
18491
  } catch (error3) {
18226
- if (error3 && typeof error3 === "object" && "code" in error3 && error3.code === "ENOENT") {
18492
+ if (typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT") {
18227
18493
  return false;
18228
18494
  }
18229
18495
  throw error3;
@@ -18282,12 +18548,13 @@ import path19 from "node:path";
18282
18548
 
18283
18549
  // ../agent-skill-config/src/git-exclude.ts
18284
18550
  import { execFileSync } from "node:child_process";
18551
+ import { randomUUID as randomUUID8 } from "node:crypto";
18285
18552
  import * as fs2 from "node:fs";
18286
18553
  import path20 from "node:path";
18287
18554
 
18288
18555
  // ../agent-skill-config/src/bridge-active-skills.ts
18289
18556
  import * as fs3 from "node:fs";
18290
- import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
18557
+ import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
18291
18558
  import path21 from "node:path";
18292
18559
 
18293
18560
  // src/commands/installer.ts
@@ -18300,7 +18567,7 @@ var DEFAULT_INSTALL_SCOPE = "local";
18300
18567
  var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
18301
18568
  var installableAgents = supportedAgents;
18302
18569
  function isNotFoundError2(error3) {
18303
- return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "ENOENT";
18570
+ return hasOwnErrorCode(error3, "ENOENT");
18304
18571
  }
18305
18572
  function resolveInstallerServices(installer) {
18306
18573
  return {
@@ -18531,7 +18798,7 @@ var resize = defineCommand({
18531
18798
  });
18532
18799
 
18533
18800
  // ../terminal-png/src/index.ts
18534
- import { randomUUID as randomUUID6 } from "node:crypto";
18801
+ import { randomUUID as randomUUID10 } from "node:crypto";
18535
18802
  import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
18536
18803
 
18537
18804
  // ../terminal-png/src/ansi-parser.ts
@@ -19471,21 +19738,28 @@ async function renderTerminalPng(ansiText, options = {}) {
19471
19738
  });
19472
19739
  const png = renderPng(svg);
19473
19740
  if (options.output) {
19474
- const temporaryPath = `${options.output}.${randomUUID6()}.tmp`;
19741
+ const temporaryPath = `${options.output}.${randomUUID10()}.tmp`;
19742
+ let temporaryCreated = false;
19475
19743
  try {
19476
19744
  await writeFile6(temporaryPath, png, { flag: "wx" });
19745
+ temporaryCreated = true;
19477
19746
  await rename4(temporaryPath, options.output);
19478
19747
  } catch (error3) {
19479
- try {
19480
- await rm(temporaryPath, { force: true });
19481
- } catch (cleanupError) {
19482
- void cleanupError;
19748
+ if (temporaryCreated || !isAlreadyExistsError3(error3)) {
19749
+ try {
19750
+ await rm(temporaryPath, { force: true });
19751
+ } catch (cleanupError) {
19752
+ void cleanupError;
19753
+ }
19483
19754
  }
19484
19755
  throw error3;
19485
19756
  }
19486
19757
  }
19487
19758
  return png;
19488
19759
  }
19760
+ function isAlreadyExistsError3(error3) {
19761
+ return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
19762
+ }
19489
19763
 
19490
19764
  // src/commands/screenshot.ts
19491
19765
  var params11 = S.Object({
@@ -19548,7 +19822,7 @@ var type = defineCommand({
19548
19822
  });
19549
19823
 
19550
19824
  // src/commands/uninstall.ts
19551
- import { randomUUID as randomUUID7 } from "node:crypto";
19825
+ import { randomUUID as randomUUID11 } from "node:crypto";
19552
19826
  var params14 = S.Object({
19553
19827
  agent: S.Enum(installableAgents, {
19554
19828
  description: "Agent to uninstall terminal-pilot from",
@@ -19584,7 +19858,7 @@ var uninstall = defineCommand({
19584
19858
  if (!await folderExists(services.fs, skill.fullPath)) {
19585
19859
  continue;
19586
19860
  }
19587
- const stagingPath = `${skill.fullPath}.removing-${randomUUID7()}`;
19861
+ const stagingPath = `${skill.fullPath}.removing-${randomUUID11()}`;
19588
19862
  await services.fs.rename(skill.fullPath, stagingPath);
19589
19863
  staged.push({ ...skill, stagingPath });
19590
19864
  }
@@ -19610,7 +19884,7 @@ async function folderExists(fs4, folderPath) {
19610
19884
  await fs4.stat(folderPath);
19611
19885
  return true;
19612
19886
  } catch (error3) {
19613
- if (typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "ENOENT") {
19887
+ if (hasOwnErrorCode(error3, "ENOENT")) {
19614
19888
  return false;
19615
19889
  }
19616
19890
  throw error3;