terminal-pilot 0.0.19 → 0.0.20

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 (35) hide show
  1. package/dist/cli.js +537 -242
  2. package/dist/cli.js.map +4 -4
  3. package/dist/commands/index.js +261 -37
  4. package/dist/commands/index.js.map +3 -3
  5. package/dist/commands/install.js +261 -37
  6. package/dist/commands/install.js.map +3 -3
  7. package/dist/commands/installer.js.map +1 -1
  8. package/dist/commands/uninstall.js.map +1 -1
  9. package/dist/testing/cli-repl.js +533 -238
  10. package/dist/testing/cli-repl.js.map +4 -4
  11. package/dist/testing/qa-cli.js +543 -248
  12. package/dist/testing/qa-cli.js.map +4 -4
  13. package/node_modules/@poe-code/agent-skill-config/README.md +103 -0
  14. package/node_modules/@poe-code/agent-skill-config/dist/apply.d.ts +25 -0
  15. package/node_modules/@poe-code/agent-skill-config/dist/apply.js +159 -0
  16. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.d.ts +23 -0
  17. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +341 -0
  18. package/node_modules/@poe-code/agent-skill-config/dist/configs.d.ts +16 -0
  19. package/node_modules/@poe-code/agent-skill-config/dist/configs.js +70 -0
  20. package/node_modules/@poe-code/agent-skill-config/dist/exports.compile-check.d.ts +1 -0
  21. package/node_modules/@poe-code/agent-skill-config/dist/exports.compile-check.js +1 -0
  22. package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.d.ts +8 -0
  23. package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.js +159 -0
  24. package/node_modules/@poe-code/agent-skill-config/dist/index.d.ts +11 -0
  25. package/node_modules/@poe-code/agent-skill-config/dist/index.js +6 -0
  26. package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.d.ts +22 -0
  27. package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.js +87 -0
  28. package/node_modules/@poe-code/agent-skill-config/dist/templates/poe-generate.md +47 -0
  29. package/node_modules/@poe-code/agent-skill-config/dist/templates/terminal-pilot.md +45 -0
  30. package/node_modules/@poe-code/agent-skill-config/dist/templates.d.ts +3 -0
  31. package/node_modules/@poe-code/agent-skill-config/dist/templates.js +63 -0
  32. package/node_modules/@poe-code/agent-skill-config/dist/types.d.ts +16 -0
  33. package/node_modules/@poe-code/agent-skill-config/dist/types.js +1 -0
  34. package/node_modules/@poe-code/agent-skill-config/package.json +24 -0
  35. package/package.json +3 -2
package/dist/cli.js CHANGED
@@ -7,12 +7,12 @@ var __export = (target, all) => {
7
7
 
8
8
  // src/cli.ts
9
9
  import { realpath as realpath2 } from "node:fs/promises";
10
- import path22 from "node:path";
10
+ import path23 from "node:path";
11
11
  import { fileURLToPath as fileURLToPath5 } from "node:url";
12
12
 
13
13
  // ../toolcraft/src/cli.ts
14
14
  import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
15
- import path13 from "node:path";
15
+ import path14 from "node:path";
16
16
  import {
17
17
  Command as CommanderCommand,
18
18
  CommanderError as CommanderError2,
@@ -1278,6 +1278,7 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
1278
1278
  }
1279
1279
 
1280
1280
  // ../design-system/src/components/template.ts
1281
+ var MAX_PARTIAL_DEPTH = 100;
1281
1282
  var HTML_ESCAPE = {
1282
1283
  "&": "&",
1283
1284
  "<": "&lt;",
@@ -1289,14 +1290,27 @@ var HTML_ESCAPE = {
1289
1290
  "=": "&#x3D;"
1290
1291
  };
1291
1292
  function renderTemplate(template, view, options = {}) {
1292
- const prepared = options.yield === void 0 ? template : template.split("{{yield}}").join(options.yield);
1293
+ const prepared = options.yield === void 0 ? template : resolveTemplatePartials(template, options.partials ?? {}).split("{{yield}}").join(options.yield);
1293
1294
  const tokens = parseTemplate(prepared);
1294
- const escape = options.escape === "none" ? String : escapeHtml;
1295
- const preserveMissing = options.yield !== void 0 && options.escape === "none";
1296
- return renderTokens(tokens, { view }, prepared, escape, preserveMissing);
1295
+ validatePartialReferences(tokens, options.partials ?? {}, []);
1296
+ if (options.validate === true) {
1297
+ const expanded = resolveTemplatePartials(prepared, options.partials ?? {});
1298
+ validateVariables(parseTemplate(expanded), { view });
1299
+ }
1300
+ const state = {
1301
+ escape: options.escape === "none" ? String : escapeHtml,
1302
+ partials: options.partials ?? {},
1303
+ partialStack: [],
1304
+ preserveMissing: options.yield !== void 0 && options.escape === "none",
1305
+ validate: options.validate === true
1306
+ };
1307
+ return renderTokens(tokens, { view }, prepared, state);
1308
+ }
1309
+ function resolveTemplatePartials(template, partials) {
1310
+ return expandTemplatePartials(template, partials, []);
1297
1311
  }
1298
- function renderTemplateInContext(template, context, escape, preserveMissing) {
1299
- return renderTokens(parseTemplate(template), context, template, escape, preserveMissing);
1312
+ function renderTemplateInContext(template, context, state) {
1313
+ return renderTokens(parseTemplate(template), context, template, state);
1300
1314
  }
1301
1315
  function parseTemplate(template) {
1302
1316
  const root = [];
@@ -1319,9 +1333,6 @@ function parseTemplate(template) {
1319
1333
  index = standalone?.nextIndex ?? parsed.end;
1320
1334
  continue;
1321
1335
  }
1322
- if (parsed.kind === "partial") {
1323
- throw new Error(`Partials are not supported: "${parsed.name}"`);
1324
- }
1325
1336
  if (parsed.kind === "delimiter") {
1326
1337
  throw new Error("Custom delimiters are not supported");
1327
1338
  }
@@ -1339,6 +1350,15 @@ function parseTemplate(template) {
1339
1350
  index = standalone?.nextIndex ?? parsed.end;
1340
1351
  continue;
1341
1352
  }
1353
+ if (parsed.kind === "partial") {
1354
+ tokens.push({
1355
+ type: "partial",
1356
+ name: parsed.name,
1357
+ indent: standalone === void 0 ? "" : template.slice(standalone.lineStart, open)
1358
+ });
1359
+ index = standalone?.nextIndex ?? parsed.end;
1360
+ continue;
1361
+ }
1342
1362
  if (parsed.kind === "close") {
1343
1363
  const frame2 = stack.pop();
1344
1364
  if (frame2 === void 0) {
@@ -1409,7 +1429,7 @@ function getStandalone(template, tagStart, tagEnd, kind) {
1409
1429
  }
1410
1430
  return void 0;
1411
1431
  }
1412
- function renderTokens(tokens, context, template, escape, preserveMissing) {
1432
+ function renderTokens(tokens, context, template, state) {
1413
1433
  let output = "";
1414
1434
  for (const token of tokens) {
1415
1435
  switch (token.type) {
@@ -1418,32 +1438,62 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
1418
1438
  continue;
1419
1439
  case "name":
1420
1440
  case "unescaped": {
1421
- const value = lookup(context, token.name);
1422
- if (value == null) {
1423
- if (preserveMissing) {
1441
+ const result = lookup(context, token.name);
1442
+ if (!result.hit || result.value == null) {
1443
+ if (state.validate) {
1444
+ throw new Error(`Template variable "${token.name}" not found.`);
1445
+ }
1446
+ if (state.preserveMissing) {
1424
1447
  output += token.raw;
1425
1448
  }
1426
1449
  continue;
1427
1450
  }
1428
- const rendered = String(value);
1429
- output += token.type === "name" ? escape(rendered) : rendered;
1451
+ const rendered = String(result.value);
1452
+ output += token.type === "name" ? state.escape(rendered) : rendered;
1453
+ continue;
1454
+ }
1455
+ case "partial": {
1456
+ if (!Object.hasOwn(state.partials, token.name)) {
1457
+ throw new Error(`Partial "${token.name}" not found.`);
1458
+ }
1459
+ if (state.partialStack.includes(token.name)) {
1460
+ throw new Error(
1461
+ `Circular partial reference detected: ${[...state.partialStack, token.name].join(" -> ")}.`
1462
+ );
1463
+ }
1464
+ if (state.partialStack.length >= MAX_PARTIAL_DEPTH) {
1465
+ throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
1466
+ }
1467
+ const partial = indentPartial(state.partials[token.name], token.indent);
1468
+ output += renderTokens(parseTemplate(partial), context, partial, {
1469
+ ...state,
1470
+ partialStack: [...state.partialStack, token.name]
1471
+ });
1430
1472
  continue;
1431
1473
  }
1432
1474
  case "inverted": {
1433
- const value = lookup(context, token.name);
1475
+ const result = lookup(context, token.name);
1476
+ if (!result.hit && state.validate) {
1477
+ throw new Error(`Template variable "${token.name}" not found.`);
1478
+ }
1479
+ const value = result.value;
1434
1480
  if (!value || Array.isArray(value) && value.length === 0) {
1435
- output += renderTokens(token.children, context, template, escape, preserveMissing);
1481
+ output += renderTokens(token.children, context, template, state);
1436
1482
  }
1437
1483
  continue;
1438
1484
  }
1439
1485
  case "section": {
1440
- const value = lookup(context, token.name);
1486
+ const result = lookup(context, token.name);
1487
+ if (!result.hit && state.validate) {
1488
+ throw new Error(`Template variable "${token.name}" not found.`);
1489
+ }
1490
+ const value = result.value;
1441
1491
  if (!value) {
1442
1492
  continue;
1443
1493
  }
1444
1494
  if (Array.isArray(value)) {
1445
1495
  for (const item of value) {
1446
- output += renderTokens(token.children, pushContext(context, item), template, escape, preserveMissing);
1496
+ output += renderTokens(token.children, pushContext(context, item), template, state);
1447
1497
  }
1448
1498
  continue;
1449
1499
  }
@@ -1452,7 +1502,7 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
1452
1502
  const rendered = value.call(
1453
1503
  context.view,
1454
1504
  raw,
1455
- (nextTemplate) => renderTemplateInContext(nextTemplate, context, escape, preserveMissing)
1505
+ (nextTemplate) => renderTemplateInContext(nextTemplate, context, state)
1456
1506
  );
1457
1507
  if (rendered != null) {
1458
1508
  output += String(rendered);
@@ -1460,10 +1510,10 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
1460
1510
  continue;
1461
1511
  }
1462
1512
  if (typeof value === "object" || typeof value === "string" || typeof value === "number") {
1463
- output += renderTokens(token.children, pushContext(context, value), template, escape, preserveMissing);
1513
+ output += renderTokens(token.children, pushContext(context, value), template, state);
1464
1514
  continue;
1465
1515
  }
1466
- output += renderTokens(token.children, context, template, escape, preserveMissing);
1516
+ output += renderTokens(token.children, context, template, state);
1467
1517
  }
1468
1518
  }
1469
1519
  }
@@ -1471,17 +1521,115 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
1471
1521
  }
1472
1522
  function lookup(context, name) {
1473
1523
  if (name === ".") {
1474
- return callLambda(context.view, context.view);
1524
+ return { hit: true, value: callLambda(context.view, context.view) };
1475
1525
  }
1476
1526
  let cursor = context;
1477
1527
  while (cursor !== void 0) {
1478
1528
  const result = name.includes(".") ? lookupDotted(cursor.view, name) : lookupName(cursor.view, name);
1479
1529
  if (result.hit) {
1480
- return callLambda(result.value, cursor.view);
1530
+ return { hit: true, value: callLambda(result.value, cursor.view) };
1481
1531
  }
1482
1532
  cursor = cursor.parent;
1483
1533
  }
1484
- return void 0;
1534
+ return { hit: false, value: void 0 };
1535
+ }
1536
+ function validateVariables(tokens, context) {
1537
+ for (const token of tokens) {
1538
+ if (token.type === "text" || token.type === "partial") {
1539
+ continue;
1540
+ }
1541
+ if (token.type === "name" || token.type === "unescaped") {
1542
+ if (!lookup(context, token.name).hit) {
1543
+ throw new Error(`Template variable "${token.name}" not found.`);
1544
+ }
1545
+ continue;
1546
+ }
1547
+ if (token.type !== "section" && token.type !== "inverted") {
1548
+ continue;
1549
+ }
1550
+ const result = lookup(context, token.name);
1551
+ if (!result.hit) {
1552
+ throw new Error(`Template variable "${token.name}" not found.`);
1553
+ }
1554
+ if (Array.isArray(result.value) && result.value.length > 0) {
1555
+ for (const item of result.value) {
1556
+ validateVariables(token.children, pushContext(context, item));
1557
+ }
1558
+ continue;
1559
+ }
1560
+ if (typeof result.value === "object" && result.value !== null || typeof result.value === "string" || typeof result.value === "number") {
1561
+ validateVariables(token.children, pushContext(context, result.value));
1562
+ continue;
1563
+ }
1564
+ validateVariables(token.children, context);
1565
+ }
1566
+ }
1567
+ function validatePartialReferences(tokens, partials, partialStack) {
1568
+ for (const token of tokens) {
1569
+ if (token.type === "section" || token.type === "inverted") {
1570
+ validatePartialReferences(token.children, partials, partialStack);
1571
+ continue;
1572
+ }
1573
+ if (token.type !== "partial") {
1574
+ continue;
1575
+ }
1576
+ if (!Object.hasOwn(partials, token.name)) {
1577
+ throw new Error(`Partial "${token.name}" not found.`);
1578
+ }
1579
+ if (partialStack.includes(token.name)) {
1580
+ throw new Error(
1581
+ `Circular partial reference detected: ${[...partialStack, token.name].join(" -> ")}.`
1582
+ );
1583
+ }
1584
+ if (partialStack.length >= MAX_PARTIAL_DEPTH) {
1585
+ throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
1586
+ }
1587
+ validatePartialReferences(parseTemplate(partials[token.name]), partials, [
1588
+ ...partialStack,
1589
+ token.name
1590
+ ]);
1591
+ }
1592
+ }
1593
+ function indentPartial(partial, indent) {
1594
+ if (indent === "") {
1595
+ return partial;
1596
+ }
1597
+ return partial.split("\n").map((line) => line === "" ? "" : `${indent}${line}`).join("\n");
1598
+ }
1599
+ function expandTemplatePartials(template, partials, partialStack) {
1600
+ let output = "";
1601
+ let index = 0;
1602
+ while (index < template.length) {
1603
+ const open = template.indexOf("{{", index);
1604
+ if (open === -1) {
1605
+ output += template.slice(index);
1606
+ break;
1607
+ }
1608
+ const parsed = parseTag(template, open);
1609
+ if (parsed.kind !== "partial") {
1610
+ output += template.slice(index, parsed.end);
1611
+ index = parsed.end;
1612
+ continue;
1613
+ }
1614
+ if (!Object.hasOwn(partials, parsed.name)) {
1615
+ throw new Error(`Partial "${parsed.name}" not found.`);
1616
+ }
1617
+ if (partialStack.includes(parsed.name)) {
1618
+ throw new Error(
1619
+ `Circular partial reference detected: ${[...partialStack, parsed.name].join(" -> ")}.`
1620
+ );
1621
+ }
1622
+ if (partialStack.length >= MAX_PARTIAL_DEPTH) {
1623
+ throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
1624
+ }
1625
+ const standalone = getStandalone(template, open, parsed.end, parsed.kind);
1626
+ const beforePartial = standalone === void 0 ? template.slice(index, open) : template.slice(index, standalone.lineStart);
1627
+ const indent = standalone === void 0 ? "" : template.slice(standalone.lineStart, open);
1628
+ const partial = indentPartial(partials[parsed.name], indent);
1629
+ output += beforePartial + expandTemplatePartials(partial, partials, [...partialStack, parsed.name]);
1630
+ index = standalone?.nextIndex ?? parsed.end;
1631
+ }
1632
+ return output;
1485
1633
  }
1486
1634
  function lookupName(view, name) {
1487
1635
  if (!isPropertyContainer(view) || !hasProperty(view, name)) {
@@ -2602,17 +2750,22 @@ import { randomBytes } from "node:crypto";
2602
2750
  // ../process-runner/src/docker/args.ts
2603
2751
  import path2 from "node:path";
2604
2752
 
2753
+ // ../process-runner/src/docker/env-file.ts
2754
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
2755
+ import { tmpdir } from "node:os";
2756
+ import path3 from "node:path";
2757
+
2605
2758
  // ../process-runner/src/docker/docker-execution-env.ts
2606
2759
  import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
2607
- import { mkdtempSync, rmSync } from "node:fs";
2760
+ import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
2608
2761
  import { readdir, readFile, writeFile } from "node:fs/promises";
2609
- import { tmpdir } from "node:os";
2610
- import path4 from "node:path";
2762
+ import { tmpdir as tmpdir2 } from "node:os";
2763
+ import path5 from "node:path";
2611
2764
 
2612
2765
  // ../process-runner/src/host/host-runner.ts
2613
2766
  import { spawn as spawnChildProcess } from "node:child_process";
2614
2767
  function createHostRunner(options = {}) {
2615
- const detached = options.detached === true;
2768
+ const detachedByDefault = options.detached === true;
2616
2769
  return {
2617
2770
  name: "host",
2618
2771
  exec(spec) {
@@ -2630,18 +2783,19 @@ function createHostRunner(options = {}) {
2630
2783
  const stdinMode = spec.stdin ?? "ignore";
2631
2784
  const stdoutMode = spec.stdout ?? "pipe";
2632
2785
  const stderrMode = spec.stderr ?? "pipe";
2786
+ const killProcessGroup = detachedByDefault || spec.killProcessGroup === true;
2633
2787
  const stdio = stdinMode === "inherit" && stdoutMode === "inherit" && stderrMode === "inherit" ? "inherit" : [stdinMode, stdoutMode, stderrMode];
2634
2788
  const child = spawnChildProcess(spec.command, spec.args ?? [], {
2635
2789
  cwd: spec.cwd,
2636
2790
  env: spec.env,
2637
2791
  stdio,
2638
- ...detached ? { detached: true } : {}
2792
+ ...killProcessGroup ? { detached: true } : {}
2639
2793
  });
2640
- if (detached) {
2794
+ if (killProcessGroup) {
2641
2795
  child.unref();
2642
2796
  }
2643
2797
  const kill = (signal) => {
2644
- if (detached && process.platform !== "win32" && child.pid !== void 0) {
2798
+ if (killProcessGroup && process.platform !== "win32" && child.pid !== void 0) {
2645
2799
  process.kill(-child.pid, signal);
2646
2800
  return;
2647
2801
  }
@@ -2699,9 +2853,9 @@ function bindAbortSignal(signal, onAbort) {
2699
2853
  }
2700
2854
 
2701
2855
  // ../process-runner/src/workspace-transfer.ts
2702
- import { createHash } from "node:crypto";
2856
+ import { createHash, randomUUID } from "node:crypto";
2703
2857
  import { promises as nodeFs } from "node:fs";
2704
- import path3 from "node:path";
2858
+ import path4 from "node:path";
2705
2859
 
2706
2860
  // ../process-runner/src/testing/mock-runner.ts
2707
2861
  import { Readable, Writable } from "node:stream";
@@ -2772,7 +2926,7 @@ function resolveEndpoint(options = {}) {
2772
2926
  }
2773
2927
 
2774
2928
  // ../task-list/src/backends/utils.ts
2775
- import path5 from "node:path";
2929
+ import path6 from "node:path";
2776
2930
  function compareCreated(left, right) {
2777
2931
  const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
2778
2932
  const rightCreated = typeof right.raw.created === "string" ? right.raw.created : "";
@@ -2822,12 +2976,12 @@ async function statIfExists(fs4, filePath) {
2822
2976
  }
2823
2977
  }
2824
2978
  async function rejectSymbolicLinkComponents(fs4, filePath) {
2825
- const resolvedPath = path5.resolve(filePath);
2826
- const rootPath = path5.parse(resolvedPath).root;
2827
- const components = resolvedPath.slice(rootPath.length).split(path5.sep).filter(Boolean);
2979
+ const resolvedPath = path6.resolve(filePath);
2980
+ const rootPath = path6.parse(resolvedPath).root;
2981
+ const components = resolvedPath.slice(rootPath.length).split(path6.sep).filter(Boolean);
2828
2982
  let currentPath = rootPath;
2829
2983
  for (const component of components) {
2830
- currentPath = path5.join(currentPath, component);
2984
+ currentPath = path6.join(currentPath, component);
2831
2985
  try {
2832
2986
  if ((await fs4.lstat(currentPath)).isSymbolicLink()) {
2833
2987
  throw new Error(`Path "${filePath}" contains a symbolic link.`);
@@ -2843,7 +2997,7 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
2843
2997
  async function writeAtomically(fs4, filePath, content) {
2844
2998
  const tempPath = `${filePath}.tmp-${process.pid}-${tmpFileCounter}`;
2845
2999
  tmpFileCounter += 1;
2846
- await fs4.mkdir(path5.dirname(filePath), { recursive: true });
3000
+ await fs4.mkdir(path6.dirname(filePath), { recursive: true });
2847
3001
  try {
2848
3002
  await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
2849
3003
  await fs4.rename(tempPath, filePath);
@@ -2859,7 +3013,7 @@ async function writeAtomically(fs4, filePath, content) {
2859
3013
  }
2860
3014
  }
2861
3015
  async function withFileLock(fs4, lockPath, operation) {
2862
- await fs4.mkdir(path5.dirname(lockPath), { recursive: true });
3016
+ await fs4.mkdir(path6.dirname(lockPath), { recursive: true });
2863
3017
  for (; ; ) {
2864
3018
  try {
2865
3019
  await fs4.writeFile(lockPath, String(process.pid), { encoding: "utf8", flag: "wx" });
@@ -3946,7 +4100,7 @@ function parseQualifiedId(qualifiedId, listName) {
3946
4100
  }
3947
4101
 
3948
4102
  // ../task-list/src/backends/markdown-dir.ts
3949
- import path6 from "node:path";
4103
+ import path7 from "node:path";
3950
4104
  import { parseDocument, stringify } from "yaml";
3951
4105
 
3952
4106
  // ../task-list/src/schema/task.schema.json
@@ -4065,16 +4219,16 @@ function parseQualifiedId2(qualifiedId) {
4065
4219
  };
4066
4220
  }
4067
4221
  function listPath(rootPath, layout, list) {
4068
- return layout.kind === "single" ? rootPath : path6.join(rootPath, list);
4222
+ return layout.kind === "single" ? rootPath : path7.join(rootPath, list);
4069
4223
  }
4070
4224
  function archiveDirectoryPath(rootPath, layout, list) {
4071
- return layout.kind === "single" ? path6.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path6.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
4225
+ return layout.kind === "single" ? path7.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path7.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
4072
4226
  }
4073
4227
  function activeTaskFilename(id, order, width) {
4074
4228
  return `${String(order).padStart(width, "0")}-${id}${MARKDOWN_EXTENSION}`;
4075
4229
  }
4076
4230
  function archivedTaskPath(rootPath, layout, list, id) {
4077
- return path6.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
4231
+ return path7.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
4078
4232
  }
4079
4233
  function isMarkdownFile(entryName) {
4080
4234
  return entryName.endsWith(MARKDOWN_EXTENSION);
@@ -4200,7 +4354,7 @@ function createTask(list, id, frontmatter, body, mode, sourcePath) {
4200
4354
  state: frontmatter.state,
4201
4355
  description: body,
4202
4356
  metadata: metadataFromFrontmatter(frontmatter, mode),
4203
- ...sourcePath !== void 0 && { sourcePath: path6.resolve(sourcePath) }
4357
+ ...sourcePath !== void 0 && { sourcePath: path7.resolve(sourcePath) }
4204
4358
  };
4205
4359
  }
4206
4360
  function serializeTaskDocument(frontmatter, description) {
@@ -4240,7 +4394,7 @@ async function readTaskFile(fs4, list, id, filePath, validStates, initialState,
4240
4394
  task: createTask(list, id, frontmatter, document.body, mode, filePath)
4241
4395
  };
4242
4396
  }
4243
- const parsedFilename = parseActiveFilename(path6.basename(filePath));
4397
+ const parsedFilename = parseActiveFilename(path7.basename(filePath));
4244
4398
  const defaultName = parsedFilename?.id ?? id;
4245
4399
  const effectiveFrontmatter = {
4246
4400
  ...frontmatter,
@@ -4269,7 +4423,7 @@ async function findTaskLocation(fs4, rootPath, layout, list, id) {
4269
4423
  await rejectSymbolicLinkComponents(fs4, listDirectoryPath);
4270
4424
  const activeName = await findActiveTaskFilename(fs4, listDirectoryPath, id);
4271
4425
  if (activeName) {
4272
- const activePath = path6.join(listDirectoryPath, activeName);
4426
+ const activePath = path7.join(listDirectoryPath, activeName);
4273
4427
  await rejectSymbolicLinkComponents(fs4, activePath);
4274
4428
  const activeStat = await statIfExists(fs4, activePath);
4275
4429
  if (activeStat?.isFile()) {
@@ -4391,7 +4545,7 @@ function createTasksView2(deps, layout, list) {
4391
4545
  if (isHiddenEntry(entryName)) continue;
4392
4546
  const parsed = parseActiveFilename(entryName);
4393
4547
  if (!parsed) continue;
4394
- const entryPath = path6.join(listDirectoryPath, entryName);
4548
+ const entryPath = path7.join(listDirectoryPath, entryName);
4395
4549
  await rejectSymbolicLinkComponents(deps.fs, entryPath);
4396
4550
  const entryStat = await statIfExists(deps.fs, entryPath);
4397
4551
  if (!entryStat?.isFile()) continue;
@@ -4409,7 +4563,7 @@ function createTasksView2(deps, layout, list) {
4409
4563
  const entries = await readActiveEntries();
4410
4564
  const tasks = /* @__PURE__ */ new Map();
4411
4565
  for (const entry of entries) {
4412
- const filePath = path6.join(listDirectoryPath, entry.filename);
4566
+ const filePath = path7.join(listDirectoryPath, entry.filename);
4413
4567
  const file = await readTaskFile(
4414
4568
  deps.fs,
4415
4569
  list,
@@ -4430,7 +4584,7 @@ function createTasksView2(deps, layout, list) {
4430
4584
  const result = [];
4431
4585
  for (const entryName of entries) {
4432
4586
  if (isHiddenEntry(entryName) || !isMarkdownFile(entryName)) continue;
4433
- const entryPath = path6.join(archivePath, entryName);
4587
+ const entryPath = path7.join(archivePath, entryName);
4434
4588
  await rejectSymbolicLinkComponents(deps.fs, entryPath);
4435
4589
  const entryStat = await statIfExists(deps.fs, entryPath);
4436
4590
  if (!entryStat?.isFile()) continue;
@@ -4460,12 +4614,12 @@ function createTasksView2(deps, layout, list) {
4460
4614
  if (desiredOrder === void 0) continue;
4461
4615
  const desiredFilename = activeTaskFilename(entry.id, desiredOrder, width);
4462
4616
  if (entry.filename !== desiredFilename) {
4463
- const fromPath = path6.join(listDirectoryPath, entry.filename);
4464
- const stagingPath = path6.join(
4617
+ const fromPath = path7.join(listDirectoryPath, entry.filename);
4618
+ const stagingPath = path7.join(
4465
4619
  listDirectoryPath,
4466
4620
  `${desiredFilename}.staging-${process.pid}-${index}`
4467
4621
  );
4468
- const targetPath = path6.join(listDirectoryPath, desiredFilename);
4622
+ const targetPath = path7.join(listDirectoryPath, desiredFilename);
4469
4623
  try {
4470
4624
  await deps.fs.rename(fromPath, stagingPath);
4471
4625
  staged.push({ original: fromPath, staging: stagingPath, target: targetPath, finalized: false });
@@ -4614,7 +4768,7 @@ function createTasksView2(deps, layout, list) {
4614
4768
  assertCreateHasId(input);
4615
4769
  validateTaskId(input.id);
4616
4770
  await rejectSymbolicLinkComponents(deps.fs, listDirectoryPath);
4617
- return withFileLock(deps.fs, path6.join(listDirectoryPath, ".transition.lock"), async () => {
4771
+ return withFileLock(deps.fs, path7.join(listDirectoryPath, ".transition.lock"), async () => {
4618
4772
  const existing = await findTaskLocation(deps.fs, deps.path, layout, list, input.id);
4619
4773
  if (existing) {
4620
4774
  throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
@@ -4627,7 +4781,7 @@ function createTasksView2(deps, layout, list) {
4627
4781
  const nextOrder = maxOrder + 1;
4628
4782
  const width = padWidthForCount(activeEntries.length + 1);
4629
4783
  const filename = activeTaskFilename(input.id, nextOrder, width);
4630
- const targetPath = path6.join(listDirectoryPath, filename);
4784
+ const targetPath = path7.join(listDirectoryPath, filename);
4631
4785
  const frontmatter = createdFrontmatter(
4632
4786
  deps.defaults,
4633
4787
  input,
@@ -4735,7 +4889,7 @@ function createTasksView2(deps, layout, list) {
4735
4889
  validateTaskId(id);
4736
4890
  const { event, nextTask } = await withFileLock(
4737
4891
  deps.fs,
4738
- path6.join(listDirectoryPath, ".transition.lock"),
4892
+ path7.join(listDirectoryPath, ".transition.lock"),
4739
4893
  fireTask
4740
4894
  );
4741
4895
  await event.onEnter?.(nextTask);
@@ -4828,7 +4982,7 @@ async function markdownDirBackend(deps) {
4828
4982
  if (entryName === ARCHIVE_DIRECTORY_NAME || isHiddenEntry(entryName)) {
4829
4983
  continue;
4830
4984
  }
4831
- const entryPath = path6.join(deps.path, entryName);
4985
+ const entryPath = path7.join(deps.path, entryName);
4832
4986
  await rejectSymbolicLinkComponents(deps.fs, entryPath);
4833
4987
  const entryStat = await statIfExists(deps.fs, entryPath);
4834
4988
  if (entryStat?.isDirectory()) {
@@ -4870,7 +5024,7 @@ async function markdownDirBackend(deps) {
4870
5024
  }
4871
5025
  const targetListDir = listPath(deps.path, layout, targetListName);
4872
5026
  await rejectSymbolicLinkComponents(deps.fs, targetListDir);
4873
- return withFileLock(deps.fs, path6.join(targetListDir, ".transition.lock"), async () => {
5027
+ return withFileLock(deps.fs, path7.join(targetListDir, ".transition.lock"), async () => {
4874
5028
  const targetExisting = await findTaskLocation(deps.fs, deps.path, layout, targetListName, id);
4875
5029
  if (targetExisting) {
4876
5030
  throw new TaskAlreadyExistsError(`Task "${targetListName}/${id}" already exists.`);
@@ -4920,7 +5074,7 @@ async function markdownDirBackend(deps) {
4920
5074
  );
4921
5075
  const width = padWidthForCount(targetEntries.length + 1);
4922
5076
  const targetFilename = activeTaskFilename(id, maxOrder + 1, width);
4923
- const targetPath = path6.join(targetListDir, targetFilename);
5077
+ const targetPath = path7.join(targetListDir, targetFilename);
4924
5078
  await deps.fs.rename(sourceLocation.path, targetPath);
4925
5079
  return createTask(
4926
5080
  targetListName,
@@ -4942,7 +5096,7 @@ async function markdownDirBackend(deps) {
4942
5096
  }
4943
5097
 
4944
5098
  // ../task-list/src/backends/yaml-file.ts
4945
- import path7 from "node:path";
5099
+ import path8 from "node:path";
4946
5100
  import { isMap, parseDocument as parseDocument2 } from "yaml";
4947
5101
 
4948
5102
  // ../task-list/src/schema/store.schema.json
@@ -5038,7 +5192,7 @@ function createTask2(list, id, taskRecord, sourcePath) {
5038
5192
  state: taskRecord.state,
5039
5193
  description: descriptionFromTaskRecord(taskRecord),
5040
5194
  metadata: metadataFromTaskRecord(taskRecord),
5041
- ...sourcePath !== void 0 && { sourcePath: path7.resolve(sourcePath) }
5195
+ ...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
5042
5196
  };
5043
5197
  }
5044
5198
  function matchesFilter(task, filter) {
@@ -5603,7 +5757,7 @@ async function openGhIssuesBackend(options) {
5603
5757
 
5604
5758
  // ../task-list/src/move.ts
5605
5759
  import * as fsPromises2 from "node:fs/promises";
5606
- import path8 from "node:path";
5760
+ import path9 from "node:path";
5607
5761
 
5608
5762
  // ../toolcraft/src/human-in-loop/approval-tasks.ts
5609
5763
  import { randomBytes as randomBytes3 } from "node:crypto";
@@ -6099,13 +6253,13 @@ function formatAvailableApprovalCommandPaths(root) {
6099
6253
  }
6100
6254
  function enumerateApprovalCommandPaths(root) {
6101
6255
  const paths = [];
6102
- const visit = (node, path23) => {
6256
+ const visit = (node, path24) => {
6103
6257
  if (node.kind === "command") {
6104
- paths.push(path23.join("."));
6258
+ paths.push(path24.join("."));
6105
6259
  return;
6106
6260
  }
6107
6261
  for (const child of getVisibleCliChildren(node)) {
6108
- visit(child, [...path23, child.name]);
6262
+ visit(child, [...path24, child.name]);
6109
6263
  }
6110
6264
  };
6111
6265
  if (root.kind === "command") {
@@ -6140,21 +6294,21 @@ function createHandlerContext(command, params17) {
6140
6294
  }
6141
6295
  function createFs() {
6142
6296
  return {
6143
- readFile: async (path23, encoding = "utf8") => readFile2(path23, { encoding }),
6144
- writeFile: async (path23, contents) => {
6145
- await writeFile2(path23, contents);
6297
+ readFile: async (path24, encoding = "utf8") => readFile2(path24, { encoding }),
6298
+ writeFile: async (path24, contents) => {
6299
+ await writeFile2(path24, contents);
6146
6300
  },
6147
- exists: async (path23) => {
6301
+ exists: async (path24) => {
6148
6302
  try {
6149
- await access(path23);
6303
+ await access(path24);
6150
6304
  return true;
6151
6305
  } catch {
6152
6306
  return false;
6153
6307
  }
6154
6308
  },
6155
- lstat: async (path23) => lstat(path23),
6309
+ lstat: async (path24) => lstat(path24),
6156
6310
  rename: async (fromPath, toPath) => rename(fromPath, toPath),
6157
- unlink: async (path23) => unlink(path23)
6311
+ unlink: async (path24) => unlink(path24)
6158
6312
  };
6159
6313
  }
6160
6314
  function createEnv(values = process.env) {
@@ -6431,16 +6585,16 @@ function isMissingStateError(error3) {
6431
6585
 
6432
6586
  // ../toolcraft/src/error-report.ts
6433
6587
  import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
6434
- import { randomUUID as randomUUID2 } from "node:crypto";
6588
+ import { randomUUID as randomUUID3 } from "node:crypto";
6435
6589
  import os from "node:os";
6436
- import path12 from "node:path";
6590
+ import path13 from "node:path";
6437
6591
  import { CommanderError } from "commander";
6438
6592
 
6439
6593
  // ../toolcraft/src/mcp-proxy.ts
6440
6594
  import { existsSync as existsSync2 } from "node:fs";
6441
6595
  import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
6442
- import path11 from "node:path";
6443
- import { createHash as createHash3, randomUUID } from "node:crypto";
6596
+ import path12 from "node:path";
6597
+ import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
6444
6598
 
6445
6599
  // ../tiny-mcp-client/src/internal.ts
6446
6600
  import { spawn as spawn5 } from "node:child_process";
@@ -6448,13 +6602,13 @@ import { PassThrough as PassThrough2 } from "node:stream";
6448
6602
 
6449
6603
  // ../mcp-oauth/src/client/auth-store-session-store.ts
6450
6604
  import crypto from "node:crypto";
6451
- import path10 from "node:path";
6605
+ import path11 from "node:path";
6452
6606
 
6453
6607
  // ../auth-store/src/encrypted-file-store.ts
6454
6608
  import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
6455
6609
  import { promises as fs } from "node:fs";
6456
6610
  import { homedir, hostname, userInfo } from "node:os";
6457
- import path9 from "node:path";
6611
+ import path10 from "node:path";
6458
6612
  var derivedKeyCache = /* @__PURE__ */ new Map();
6459
6613
  var ENCRYPTION_ALGORITHM = "aes-256-gcm";
6460
6614
  var ENCRYPTION_VERSION = 1;
@@ -6466,6 +6620,7 @@ var temporaryFileSequence = 0;
6466
6620
  var EncryptedFileStore = class {
6467
6621
  fs;
6468
6622
  filePath;
6623
+ symbolicLinkCheckStartPath;
6469
6624
  salt;
6470
6625
  getMachineIdentity;
6471
6626
  getRandomBytes;
@@ -6473,11 +6628,22 @@ var EncryptedFileStore = class {
6473
6628
  constructor(input) {
6474
6629
  this.fs = input.fs ?? fs;
6475
6630
  this.salt = input.salt;
6476
- this.filePath = input.filePath ?? path9.join(
6477
- (input.getHomeDirectory ?? homedir)(),
6478
- input.defaultDirectory ?? ".auth-store",
6479
- input.defaultFileName ?? "credentials.enc"
6480
- );
6631
+ if (input.filePath === void 0) {
6632
+ const homeDirectory = (input.getHomeDirectory ?? homedir)();
6633
+ const defaultDirectory = input.defaultDirectory ?? ".auth-store";
6634
+ this.filePath = path10.join(
6635
+ homeDirectory,
6636
+ defaultDirectory,
6637
+ input.defaultFileName ?? "credentials.enc"
6638
+ );
6639
+ this.symbolicLinkCheckStartPath = resolveDefaultDirectoryCheckStart(
6640
+ homeDirectory,
6641
+ defaultDirectory
6642
+ );
6643
+ } else {
6644
+ this.filePath = input.filePath;
6645
+ this.symbolicLinkCheckStartPath = null;
6646
+ }
6481
6647
  this.getMachineIdentity = input.getMachineIdentity ?? defaultMachineIdentity;
6482
6648
  this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
6483
6649
  }
@@ -6528,7 +6694,7 @@ var EncryptedFileStore = class {
6528
6694
  authTag: authTag.toString("base64"),
6529
6695
  ciphertext: ciphertext.toString("base64")
6530
6696
  };
6531
- await this.fs.mkdir(path9.dirname(this.filePath), { recursive: true });
6697
+ await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
6532
6698
  await this.assertRegularCredentialPath();
6533
6699
  const temporaryPath = `${this.filePath}.${process.pid}.${temporaryFileSequence++}.tmp`;
6534
6700
  try {
@@ -6557,8 +6723,11 @@ var EncryptedFileStore = class {
6557
6723
  }
6558
6724
  }
6559
6725
  async assertRegularCredentialPath() {
6560
- const resolvedPath = path9.resolve(this.filePath);
6561
- const protectedPaths = [path9.dirname(resolvedPath), resolvedPath];
6726
+ const resolvedPath = path10.resolve(this.filePath);
6727
+ const protectedPaths = getProtectedCredentialPaths(
6728
+ resolvedPath,
6729
+ this.symbolicLinkCheckStartPath
6730
+ );
6562
6731
  for (const currentPath of protectedPaths) {
6563
6732
  try {
6564
6733
  const stats = await this.fs.lstat(currentPath);
@@ -6586,6 +6755,30 @@ var EncryptedFileStore = class {
6586
6755
  return this.keyPromise;
6587
6756
  }
6588
6757
  };
6758
+ function resolveDefaultDirectoryCheckStart(homeDirectory, defaultDirectory) {
6759
+ const [firstSegment] = defaultDirectory.split(/[\\/]+/).filter(Boolean);
6760
+ return path10.resolve(homeDirectory, firstSegment ?? ".");
6761
+ }
6762
+ function getProtectedCredentialPaths(resolvedPath, symbolicLinkCheckStartPath) {
6763
+ if (symbolicLinkCheckStartPath === null) {
6764
+ return [path10.dirname(resolvedPath), resolvedPath];
6765
+ }
6766
+ const resolvedStartPath = path10.resolve(symbolicLinkCheckStartPath);
6767
+ if (!isPathInsideOrEqual(resolvedPath, resolvedStartPath)) {
6768
+ return [path10.dirname(resolvedPath), resolvedPath];
6769
+ }
6770
+ const protectedPaths = [resolvedStartPath];
6771
+ let currentPath = resolvedStartPath;
6772
+ for (const segment of path10.relative(resolvedStartPath, resolvedPath).split(path10.sep).filter(Boolean)) {
6773
+ currentPath = path10.join(currentPath, segment);
6774
+ protectedPaths.push(currentPath);
6775
+ }
6776
+ return protectedPaths;
6777
+ }
6778
+ function isPathInsideOrEqual(childPath, parentPath) {
6779
+ const relativePath = path10.relative(parentPath, childPath);
6780
+ return relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath);
6781
+ }
6589
6782
  async function removeIfPresent(fileSystem, filePath) {
6590
6783
  try {
6591
6784
  await fileSystem.unlink(filePath);
@@ -6736,6 +6929,17 @@ function runSecurityCommand(command, args, options) {
6736
6929
  });
6737
6930
  let stdout = "";
6738
6931
  let stderr = "";
6932
+ let stdinErrorMessage;
6933
+ const appendStderr = (message2) => {
6934
+ stderr = stderr.length === 0 ? message2 : `${stderr}${stderr.endsWith("\n") ? "" : "\n"}${message2}`;
6935
+ };
6936
+ const appendStdinError = () => {
6937
+ if (stdinErrorMessage === void 0) {
6938
+ return;
6939
+ }
6940
+ appendStderr(stdinErrorMessage);
6941
+ stdinErrorMessage = void 0;
6942
+ };
6739
6943
  child.stdout?.setEncoding("utf8");
6740
6944
  child.stdout?.on("data", (chunk) => {
6741
6945
  stdout += chunk.toString();
@@ -6745,17 +6949,23 @@ function runSecurityCommand(command, args, options) {
6745
6949
  stderr += chunk.toString();
6746
6950
  });
6747
6951
  if (options?.stdin !== void 0) {
6952
+ child.stdin?.once("error", (error3) => {
6953
+ stdinErrorMessage = error3 instanceof Error ? error3.message : String(error3);
6954
+ });
6748
6955
  child.stdin?.end(options.stdin);
6749
6956
  }
6750
6957
  child.on("error", (error3) => {
6751
6958
  const message2 = error3 instanceof Error ? error3.message : String(error3 ?? "Unknown error");
6959
+ appendStdinError();
6960
+ appendStderr(message2);
6752
6961
  resolve({
6753
6962
  stdout,
6754
- stderr: stderr ? `${stderr}${message2}` : message2,
6963
+ stderr,
6755
6964
  exitCode: 127
6756
6965
  });
6757
6966
  });
6758
6967
  child.on("close", (code) => {
6968
+ appendStdinError();
6759
6969
  resolve({
6760
6970
  stdout,
6761
6971
  stderr,
@@ -6895,7 +7105,7 @@ function createAuthStoreClientStore(options) {
6895
7105
  }
6896
7106
  function createNamedSecretStore(key2, options, defaults) {
6897
7107
  const hash = crypto.createHash("sha256").update(key2).digest("hex");
6898
- const parsedFilePath = options.fileStore?.filePath === void 0 ? null : path10.parse(options.fileStore.filePath);
7108
+ const parsedFilePath = options.fileStore?.filePath === void 0 ? null : path11.parse(options.fileStore.filePath);
6899
7109
  const fileStore = {
6900
7110
  ...options.fileStore,
6901
7111
  salt: options.fileStore?.salt ?? defaults.salt,
@@ -8478,10 +8688,19 @@ var McpClient = class {
8478
8688
  }
8479
8689
  try {
8480
8690
  let requestId;
8691
+ let cancellationSent = false;
8692
+ const sendCancellationNotification = () => {
8693
+ if (requestId === void 0 || cancellationSent) {
8694
+ return;
8695
+ }
8696
+ cancellationSent = true;
8697
+ messageLayer.sendNotification("notifications/cancelled", { requestId });
8698
+ };
8481
8699
  const requestPromise = messageLayer.sendRequest("tools/call", requestParams, {
8482
8700
  onRequestId: (nextRequestId) => {
8483
8701
  requestId = nextRequestId;
8484
- }
8702
+ },
8703
+ onTimeout: sendCancellationNotification
8485
8704
  }).then((result) => {
8486
8705
  if (!isCallToolResult(result)) {
8487
8706
  throw new McpError(ERROR_INVALID_REQUEST, "Invalid tool result");
@@ -8495,9 +8714,7 @@ var McpClient = class {
8495
8714
  let abortListener;
8496
8715
  const abortPromise = new Promise((_, reject) => {
8497
8716
  const rejectWithAbortReason = () => {
8498
- if (requestId !== void 0) {
8499
- messageLayer.sendNotification("notifications/cancelled", { requestId });
8500
- }
8717
+ sendCancellationNotification();
8501
8718
  reject(signal.reason);
8502
8719
  };
8503
8720
  abortListener = rejectWithAbortReason;
@@ -9308,6 +9525,7 @@ var JsonRpcMessageLayer = class {
9308
9525
  return new Promise((resolve, reject) => {
9309
9526
  const timeout = setTimeout(() => {
9310
9527
  this.pendingRequests.delete(id);
9528
+ options.onTimeout?.(id);
9311
9529
  reject(new Error(`JSON-RPC request "${method}" timed out after ${timeoutMs}ms`));
9312
9530
  }, timeoutMs);
9313
9531
  this.pendingRequests.set(id, { resolve, reject, timeout });
@@ -9720,13 +9938,13 @@ function convertJsonSchema(schema) {
9720
9938
  }
9721
9939
  return convertSchema(schema, schema, []);
9722
9940
  }
9723
- function convertSchema(schema, root, path23) {
9724
- const resolvedSchema = resolveReferencedSchema(schema, root, path23);
9941
+ function convertSchema(schema, root, path24) {
9942
+ const resolvedSchema = resolveReferencedSchema(schema, root, path24);
9725
9943
  const normalizedSchema = normalizeNullability(resolvedSchema);
9726
9944
  const composition = getComposition(normalizedSchema.schema);
9727
9945
  if (Array.isArray(normalizedSchema.schema.type)) {
9728
9946
  throw new Error(
9729
- `JSON Schema "${formatJsonSchemaPath(path23)}" has an unsupported type "${formatJsonSchemaType(
9947
+ `JSON Schema "${formatJsonSchemaPath(path24)}" has an unsupported type "${formatJsonSchemaType(
9730
9948
  normalizedSchema.schema.type
9731
9949
  )}". Supported: string, number, integer, boolean, array, object.`
9732
9950
  );
@@ -9738,13 +9956,13 @@ function convertSchema(schema, root, path23) {
9738
9956
  return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
9739
9957
  }
9740
9958
  if (composition !== void 0) {
9741
- return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path23);
9959
+ return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path24);
9742
9960
  }
9743
9961
  if (isRecordSchema(normalizedSchema.schema)) {
9744
9962
  return applyMetadata(
9745
9963
  S.Record(
9746
9964
  convertSchema(normalizedSchema.schema.additionalProperties, root, [
9747
- ...path23,
9965
+ ...path24,
9748
9966
  "additionalProperties"
9749
9967
  ])
9750
9968
  ),
@@ -9793,12 +10011,12 @@ function convertSchema(schema, root, path23) {
9793
10011
  if (normalizedSchema.schema.items === void 0) {
9794
10012
  throw new Error(
9795
10013
  `JSON Schema "${formatJsonSchemaPath(
9796
- path23
10014
+ path24
9797
10015
  )}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
9798
10016
  );
9799
10017
  }
9800
10018
  return S.Array(
9801
- convertSchema(normalizedSchema.schema.items, root, [...path23, "items"]),
10019
+ convertSchema(normalizedSchema.schema.items, root, [...path24, "items"]),
9802
10020
  createCommonOptions(
9803
10021
  normalizedSchema.schema,
9804
10022
  normalizedSchema.nullable,
@@ -9808,7 +10026,7 @@ function convertSchema(schema, root, path23) {
9808
10026
  case "object":
9809
10027
  return convertObjectSchema(normalizedSchema.schema, root, {
9810
10028
  nullable: normalizedSchema.nullable,
9811
- path: path23
10029
+ path: path24
9812
10030
  });
9813
10031
  case "null":
9814
10032
  return applyMetadata(S.Json(), normalizedSchema.schema, {
@@ -9823,12 +10041,12 @@ function convertSchema(schema, root, path23) {
9823
10041
  }
9824
10042
  throw new Error(
9825
10043
  `JSON Schema "${formatJsonSchemaPath(
9826
- path23
10044
+ path24
9827
10045
  )}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
9828
10046
  );
9829
10047
  }
9830
10048
  throw new Error(
9831
- `JSON Schema "${formatJsonSchemaPath(path23)}" has an unsupported type "${formatJsonSchemaType(
10049
+ `JSON Schema "${formatJsonSchemaPath(path24)}" has an unsupported type "${formatJsonSchemaType(
9832
10050
  normalizedSchema.schema.type
9833
10051
  )}". Supported: string, number, integer, boolean, array, object.`
9834
10052
  );
@@ -9872,21 +10090,21 @@ function convertEnumSchema(schema, nullable) {
9872
10090
  )
9873
10091
  });
9874
10092
  }
9875
- function convertCompositionSchema(schema, root, nullable, path23) {
10093
+ function convertCompositionSchema(schema, root, nullable, path24) {
9876
10094
  const composition = getComposition(schema);
9877
10095
  const branchSchemas = composition?.branches ?? [];
9878
10096
  const keyword = composition?.keyword ?? "oneOf";
9879
10097
  const branches = branchSchemas.map(
9880
- (branch, index) => resolveReferencedSchema(branch, root, [...path23, keyword, String(index)])
10098
+ (branch, index) => resolveReferencedSchema(branch, root, [...path24, keyword, String(index)])
9881
10099
  );
9882
- const discriminator = findDiscriminator(branches, root, path23);
10100
+ const discriminator = findDiscriminator(branches, root, path24);
9883
10101
  if (discriminator !== void 0) {
9884
10102
  const convertedBranches = Object.fromEntries(
9885
10103
  branches.map((branch, index) => [
9886
10104
  getDiscriminatorLiteral(branch, discriminator, root),
9887
10105
  convertObjectSchema(branch, root, {
9888
10106
  omitProperty: discriminator,
9889
- path: [...path23, keyword, String(index)]
10107
+ path: [...path24, keyword, String(index)]
9890
10108
  })
9891
10109
  ])
9892
10110
  );
@@ -9905,7 +10123,7 @@ function convertCompositionSchema(schema, root, nullable, path23) {
9905
10123
  S.Union(
9906
10124
  branches.map(
9907
10125
  (branch, index) => convertObjectSchema(branch, root, {
9908
- path: [...path23, keyword, String(index)]
10126
+ path: [...path24, keyword, String(index)]
9909
10127
  })
9910
10128
  )
9911
10129
  ),
@@ -10007,11 +10225,11 @@ function getComposition(schema) {
10007
10225
  }
10008
10226
  return void 0;
10009
10227
  }
10010
- function formatJsonSchemaPath(path23) {
10011
- if (path23.length === 0) {
10228
+ function formatJsonSchemaPath(path24) {
10229
+ if (path24.length === 0) {
10012
10230
  return "#";
10013
10231
  }
10014
- return `#/${path23.map(escapeJsonPointerSegment).join("/")}`;
10232
+ return `#/${path24.map(escapeJsonPointerSegment).join("/")}`;
10015
10233
  }
10016
10234
  function formatJsonSchemaType(type2) {
10017
10235
  return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
@@ -10027,11 +10245,11 @@ function isRecordSchema(schema) {
10027
10245
  const propertyKeys = Object.keys(schema.properties ?? {});
10028
10246
  return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
10029
10247
  }
10030
- function findDiscriminator(branches, root, path23) {
10248
+ function findDiscriminator(branches, root, path24) {
10031
10249
  const [firstBranch] = branches;
10032
10250
  if (firstBranch === void 0) {
10033
10251
  throw new Error(
10034
- `JSON Schema "${formatJsonSchemaPath(path23)}" uses oneOf/anyOf/allOf but has no branches.`
10252
+ `JSON Schema "${formatJsonSchemaPath(path24)}" uses oneOf/anyOf/allOf but has no branches.`
10035
10253
  );
10036
10254
  }
10037
10255
  const candidateKeys = Object.keys(firstBranch.properties ?? {});
@@ -10071,19 +10289,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
10071
10289
  }
10072
10290
  return void 0;
10073
10291
  }
10074
- function resolveReferencedSchema(schema, root, path23) {
10292
+ function resolveReferencedSchema(schema, root, path24) {
10075
10293
  if (schema.$ref === void 0) {
10076
10294
  return schema;
10077
10295
  }
10078
10296
  const resolvedTarget = resolveLocalRef(root, schema.$ref);
10079
10297
  if (resolvedTarget === void 0) {
10080
10298
  throw new Error(
10081
- `JSON Schema "${formatJsonSchemaPath(path23)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
10299
+ `JSON Schema "${formatJsonSchemaPath(path24)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
10082
10300
  );
10083
10301
  }
10084
10302
  const { $ref: ignoredRef, ...siblingKeywords } = schema;
10085
10303
  void ignoredRef;
10086
- const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path23);
10304
+ const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path24);
10087
10305
  if (Object.keys(siblingKeywords).length === 0) {
10088
10306
  return resolvedSchema;
10089
10307
  }
@@ -10107,9 +10325,9 @@ function mergeJsonSchemas(base, overlay) {
10107
10325
  ...mergedRequired === void 0 ? {} : { required: mergedRequired }
10108
10326
  };
10109
10327
  }
10110
- function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__PURE__ */ new Set()) {
10328
+ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__PURE__ */ new Set()) {
10111
10329
  const nextActivePaths = new Set(activePaths);
10112
- nextActivePaths.add(path23);
10330
+ nextActivePaths.add(path24);
10113
10331
  const localRefPath = getLocalRefPath(schema.$ref);
10114
10332
  if (localRefPath !== void 0) {
10115
10333
  if (nextActivePaths.has(localRefPath)) {
@@ -10120,13 +10338,13 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
10120
10338
  return true;
10121
10339
  }
10122
10340
  }
10123
- if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path23}/items`, nextActivePaths)) {
10341
+ if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path24}/items`, nextActivePaths)) {
10124
10342
  return true;
10125
10343
  }
10126
10344
  if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
10127
10345
  schema.additionalProperties,
10128
10346
  root,
10129
- `${path23}/additionalProperties`,
10347
+ `${path24}/additionalProperties`,
10130
10348
  nextActivePaths
10131
10349
  )) {
10132
10350
  return true;
@@ -10135,7 +10353,7 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
10135
10353
  if (hasSelfReferencingRef(
10136
10354
  childSchema,
10137
10355
  root,
10138
- `${path23}/properties/${escapeJsonPointerSegment(key2)}`,
10356
+ `${path24}/properties/${escapeJsonPointerSegment(key2)}`,
10139
10357
  nextActivePaths
10140
10358
  )) {
10141
10359
  return true;
@@ -10145,24 +10363,24 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
10145
10363
  if (hasSelfReferencingRef(
10146
10364
  childSchema,
10147
10365
  root,
10148
- `${path23}/$defs/${escapeJsonPointerSegment(key2)}`,
10366
+ `${path24}/$defs/${escapeJsonPointerSegment(key2)}`,
10149
10367
  nextActivePaths
10150
10368
  )) {
10151
10369
  return true;
10152
10370
  }
10153
10371
  }
10154
10372
  for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
10155
- if (hasSelfReferencingRef(childSchema, root, `${path23}/oneOf/${index}`, nextActivePaths)) {
10373
+ if (hasSelfReferencingRef(childSchema, root, `${path24}/oneOf/${index}`, nextActivePaths)) {
10156
10374
  return true;
10157
10375
  }
10158
10376
  }
10159
10377
  for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
10160
- if (hasSelfReferencingRef(childSchema, root, `${path23}/anyOf/${index}`, nextActivePaths)) {
10378
+ if (hasSelfReferencingRef(childSchema, root, `${path24}/anyOf/${index}`, nextActivePaths)) {
10161
10379
  return true;
10162
10380
  }
10163
10381
  }
10164
10382
  for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
10165
- if (hasSelfReferencingRef(childSchema, root, `${path23}/allOf/${index}`, nextActivePaths)) {
10383
+ if (hasSelfReferencingRef(childSchema, root, `${path24}/allOf/${index}`, nextActivePaths)) {
10166
10384
  return true;
10167
10385
  }
10168
10386
  }
@@ -10178,14 +10396,14 @@ function getLocalRefPath(ref) {
10178
10396
  return ref.startsWith("#/") ? ref : void 0;
10179
10397
  }
10180
10398
  function resolveLocalRef(root, ref) {
10181
- const path23 = getLocalRefPath(ref);
10182
- if (path23 === void 0) {
10399
+ const path24 = getLocalRefPath(ref);
10400
+ if (path24 === void 0) {
10183
10401
  return void 0;
10184
10402
  }
10185
- if (path23 === "#") {
10403
+ if (path24 === "#") {
10186
10404
  return root;
10187
10405
  }
10188
- const segments = path23.slice(2).split("/").map(unescapeJsonPointerSegment);
10406
+ const segments = path24.slice(2).split("/").map(unescapeJsonPointerSegment);
10189
10407
  let current = root;
10190
10408
  for (const segment of segments) {
10191
10409
  if (Array.isArray(current)) {
@@ -10446,8 +10664,8 @@ async function readCache(cachePath) {
10446
10664
  }
10447
10665
  }
10448
10666
  async function writeCache(cachePath, cache) {
10449
- const directory = path11.dirname(cachePath);
10450
- const tempPath = `${cachePath}.tmp-${randomUUID()}`;
10667
+ const directory = path12.dirname(cachePath);
10668
+ const tempPath = `${cachePath}.tmp-${randomUUID2()}`;
10451
10669
  await assertCachePathHasNoSymlinks(cachePath);
10452
10670
  await assertCachePathHasNoSymlinks(tempPath);
10453
10671
  await mkdir(directory, { recursive: true });
@@ -10627,13 +10845,13 @@ function collectProxyGroups(root) {
10627
10845
  function findProjectRoot(from = process.cwd()) {
10628
10846
  let current = process.cwd();
10629
10847
  if (from !== current) {
10630
- current = path11.resolve(from);
10848
+ current = path12.resolve(from);
10631
10849
  }
10632
10850
  while (true) {
10633
- if (existsSync2(path11.join(current, "package.json"))) {
10851
+ if (existsSync2(path12.join(current, "package.json"))) {
10634
10852
  return current;
10635
10853
  }
10636
- const parent = path11.dirname(current);
10854
+ const parent = path12.dirname(current);
10637
10855
  if (parent === current) {
10638
10856
  return void 0;
10639
10857
  }
@@ -10650,7 +10868,7 @@ function resolveCachePath(name, projectRoot) {
10650
10868
  if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\")) {
10651
10869
  throw new Error(`MCP proxy group name must be a file-safe name: "${name}".`);
10652
10870
  }
10653
- return path11.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
10871
+ return path12.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
10654
10872
  }
10655
10873
  async function assertCachePathHasNoSymlinks(filePath) {
10656
10874
  let currentPath = filePath;
@@ -10664,10 +10882,10 @@ async function assertCachePathHasNoSymlinks(filePath) {
10664
10882
  throw error3;
10665
10883
  }
10666
10884
  }
10667
- if (path11.basename(currentPath) === ".toolcraft") {
10885
+ if (path12.basename(currentPath) === ".toolcraft") {
10668
10886
  return;
10669
10887
  }
10670
- const parentPath = path11.dirname(currentPath);
10888
+ const parentPath = path12.dirname(currentPath);
10671
10889
  if (parentPath === currentPath) {
10672
10890
  return;
10673
10891
  }
@@ -10741,20 +10959,20 @@ function reportsEnabled(option, env) {
10741
10959
  function resolveReportDir(option, projectRoot) {
10742
10960
  const configuredDir = typeof option === "object" ? option.dir : void 0;
10743
10961
  if (configuredDir === void 0 || configuredDir.length === 0) {
10744
- return path12.join(projectRoot, ".toolcraft", "errors");
10962
+ return path13.join(projectRoot, ".toolcraft", "errors");
10745
10963
  }
10746
- return path12.isAbsolute(configuredDir) ? configuredDir : path12.join(projectRoot, configuredDir);
10964
+ return path13.isAbsolute(configuredDir) ? configuredDir : path13.join(projectRoot, configuredDir);
10747
10965
  }
10748
10966
  function reportDirMustStayWithinProject(option) {
10749
10967
  const configuredDir = typeof option === "object" ? option.dir : void 0;
10750
- return configuredDir === void 0 || configuredDir.length === 0 || !path12.isAbsolute(configuredDir);
10968
+ return configuredDir === void 0 || configuredDir.length === 0 || !path13.isAbsolute(configuredDir);
10751
10969
  }
10752
10970
  function isWithinDirectory(parent, child) {
10753
- const relative = path12.relative(parent, child);
10754
- return relative === "" || !path12.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path12.sep}`);
10971
+ const relative = path13.relative(parent, child);
10972
+ return relative === "" || !path13.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path13.sep}`);
10755
10973
  }
10756
10974
  async function assertReportDirWithinProject(projectRoot, reportDir) {
10757
- if (!isWithinDirectory(path12.resolve(projectRoot), path12.resolve(reportDir))) {
10975
+ if (!isWithinDirectory(path13.resolve(projectRoot), path13.resolve(reportDir))) {
10758
10976
  throw new Error("Error report directory resolves outside project root.");
10759
10977
  }
10760
10978
  const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
@@ -10805,7 +11023,7 @@ function slugifyCommandPath(commandPath) {
10805
11023
  return output.length === 0 ? "root" : output;
10806
11024
  }
10807
11025
  function relativeDisplayPath(projectRoot, absolutePath) {
10808
- const relative = path12.relative(projectRoot, absolutePath);
11026
+ const relative = path13.relative(projectRoot, absolutePath);
10809
11027
  return relative.length === 0 || relative.startsWith("..") ? absolutePath : relative;
10810
11028
  }
10811
11029
  function redactValue(value) {
@@ -11045,8 +11263,8 @@ async function writeErrorReport(context) {
11045
11263
  }
11046
11264
  const projectRoot = resolveProjectRoot(context.projectRoot);
11047
11265
  const reportDir = resolveReportDir(context.errorReports, projectRoot);
11048
- const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID2()}.log`;
11049
- const absolutePath = path12.join(reportDir, fileName);
11266
+ const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID3()}.log`;
11267
+ const absolutePath = path13.join(reportDir, fileName);
11050
11268
  await mkdir2(reportDir, { recursive: true });
11051
11269
  if (reportDirMustStayWithinProject(context.errorReports)) {
11052
11270
  await assertReportDirWithinProject(projectRoot, reportDir);
@@ -11510,7 +11728,7 @@ function inferProgramName(argv) {
11510
11728
  if (typeof entrypoint !== "string" || entrypoint.length === 0) {
11511
11729
  return "toolcraft";
11512
11730
  }
11513
- const parsed = path13.parse(entrypoint);
11731
+ const parsed = path14.parse(entrypoint);
11514
11732
  return parsed.name.length > 0 ? parsed.name : "toolcraft";
11515
11733
  }
11516
11734
  function normalizeRoots(roots, argv) {
@@ -11568,11 +11786,11 @@ function formatSegment(segment, casing) {
11568
11786
  const separator = casing === "snake" ? "_" : "-";
11569
11787
  return splitWords3(segment).join(separator);
11570
11788
  }
11571
- function toOptionFlag(path23, casing) {
11572
- return `--${path23.map((segment) => formatSegment(segment, casing)).join(".")}`;
11789
+ function toOptionFlag(path24, casing) {
11790
+ return `--${path24.map((segment) => formatSegment(segment, casing)).join(".")}`;
11573
11791
  }
11574
- function toOptionAttribute(path23, casing) {
11575
- return path23.map((segment) => {
11792
+ function toOptionAttribute(path24, casing) {
11793
+ return path24.map((segment) => {
11576
11794
  const formatted = formatSegment(segment, casing);
11577
11795
  if (casing === "snake") {
11578
11796
  return formatted;
@@ -11583,23 +11801,23 @@ function toOptionAttribute(path23, casing) {
11583
11801
  ).join("");
11584
11802
  }).join(".");
11585
11803
  }
11586
- function toDisplayPath(path23) {
11587
- return path23.join(".");
11804
+ function toDisplayPath(path24) {
11805
+ return path24.join(".");
11588
11806
  }
11589
- function toUnionKindControlPath(path23) {
11590
- if (path23.length === 0) {
11807
+ function toUnionKindControlPath(path24) {
11808
+ if (path24.length === 0) {
11591
11809
  return ["kind"];
11592
11810
  }
11593
- const head = path23.slice(0, -1);
11594
- const tail = path23[path23.length - 1] ?? "";
11811
+ const head = path24.slice(0, -1);
11812
+ const tail = path24[path24.length - 1] ?? "";
11595
11813
  return [...head, `${tail}Kind`];
11596
11814
  }
11597
- function toUnionKindDisplayPath(path23) {
11598
- if (path23.length === 0) {
11815
+ function toUnionKindDisplayPath(path24) {
11816
+ if (path24.length === 0) {
11599
11817
  return "kind";
11600
11818
  }
11601
- const head = path23.slice(0, -1);
11602
- const tail = path23[path23.length - 1] ?? "";
11819
+ const head = path24.slice(0, -1);
11820
+ const tail = path24[path24.length - 1] ?? "";
11603
11821
  return [...head, `${tail}-kind`].join(".");
11604
11822
  }
11605
11823
  function createSyntheticEnumSchema(values) {
@@ -11615,14 +11833,14 @@ function getRequiredBranchFingerprint(branch, casing) {
11615
11833
  const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
11616
11834
  return requiredKeys.join("+");
11617
11835
  }
11618
- function collectFields(schema, casing, globalLongOptionFlags, path23 = [], inheritedOptional = false, variantContext) {
11836
+ function collectFields(schema, casing, globalLongOptionFlags, path24 = [], inheritedOptional = false, variantContext) {
11619
11837
  const collected = {
11620
11838
  dynamicFields: [],
11621
11839
  fields: [],
11622
11840
  variants: []
11623
11841
  };
11624
11842
  for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
11625
- const nextPath = [...path23, key2];
11843
+ const nextPath = [...path24, key2];
11626
11844
  const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
11627
11845
  const childSchema = unwrapOptional2(rawChildSchema);
11628
11846
  const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
@@ -11803,9 +12021,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path23 = [], inher
11803
12021
  }
11804
12022
  return collected;
11805
12023
  }
11806
- function toCommanderOptionAttribute(path23, casing, globalLongOptionFlags) {
11807
- const optionAttribute = toOptionAttribute(path23, casing);
11808
- const optionFlag = toOptionFlag(path23, casing);
12024
+ function toCommanderOptionAttribute(path24, casing, globalLongOptionFlags) {
12025
+ const optionAttribute = toOptionAttribute(path24, casing);
12026
+ const optionFlag = toOptionFlag(path24, casing);
11809
12027
  if (!globalLongOptionFlags.has(optionFlag)) {
11810
12028
  return optionAttribute;
11811
12029
  }
@@ -12774,10 +12992,10 @@ function parseDebugStackMode(value) {
12774
12992
  formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
12775
12993
  );
12776
12994
  }
12777
- function setNestedValue(target, path23, value) {
12995
+ function setNestedValue(target, path24, value) {
12778
12996
  let cursor = target;
12779
- for (let index = 0; index < path23.length - 1; index += 1) {
12780
- const segment = path23[index] ?? "";
12997
+ for (let index = 0; index < path24.length - 1; index += 1) {
12998
+ const segment = path24[index] ?? "";
12781
12999
  const existing = Object.prototype.hasOwnProperty.call(cursor, segment) ? cursor[segment] : void 0;
12782
13000
  if (typeof existing === "object" && existing !== null) {
12783
13001
  cursor = existing;
@@ -12792,7 +13010,7 @@ function setNestedValue(target, path23, value) {
12792
13010
  });
12793
13011
  cursor = next;
12794
13012
  }
12795
- const leaf = path23[path23.length - 1];
13013
+ const leaf = path24[path24.length - 1];
12796
13014
  if (leaf !== void 0) {
12797
13015
  Object.defineProperty(cursor, leaf, {
12798
13016
  value,
@@ -12902,21 +13120,21 @@ async function withOutputFormat2(output, fn) {
12902
13120
  }
12903
13121
  function createFs2() {
12904
13122
  return {
12905
- readFile: async (path23, encoding = "utf8") => readFile4(path23, { encoding }),
12906
- writeFile: async (path23, contents) => {
12907
- await writeFile5(path23, contents);
13123
+ readFile: async (path24, encoding = "utf8") => readFile4(path24, { encoding }),
13124
+ writeFile: async (path24, contents) => {
13125
+ await writeFile5(path24, contents);
12908
13126
  },
12909
- exists: async (path23) => {
13127
+ exists: async (path24) => {
12910
13128
  try {
12911
- await access2(path23);
13129
+ await access2(path24);
12912
13130
  return true;
12913
13131
  } catch {
12914
13132
  return false;
12915
13133
  }
12916
13134
  },
12917
- lstat: async (path23) => lstat3(path23),
13135
+ lstat: async (path24) => lstat3(path24),
12918
13136
  rename: async (fromPath, toPath) => rename3(fromPath, toPath),
12919
- unlink: async (path23) => unlink2(path23)
13137
+ unlink: async (path24) => unlink2(path24)
12920
13138
  };
12921
13139
  }
12922
13140
  function createEnv2(values = process.env) {
@@ -12932,9 +13150,9 @@ function isPlainObject3(value) {
12932
13150
  function hasFieldValue(value) {
12933
13151
  return value !== void 0;
12934
13152
  }
12935
- function hasNestedField(fields, path23) {
13153
+ function hasNestedField(fields, path24) {
12936
13154
  return fields.some(
12937
- (field) => path23.length < field.path.length && path23.every((segment, index) => field.path[index] === segment)
13155
+ (field) => path24.length < field.path.length && path24.every((segment, index) => field.path[index] === segment)
12938
13156
  );
12939
13157
  }
12940
13158
  function describeExpectedPresetValue(schema) {
@@ -13040,9 +13258,9 @@ async function loadPresetValues(fields, presetPath) {
13040
13258
  }
13041
13259
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
13042
13260
  const presetValues = {};
13043
- function visitObject(current, path23) {
13261
+ function visitObject(current, path24) {
13044
13262
  for (const [key2, value] of Object.entries(current)) {
13045
- const nextPath = [...path23, key2];
13263
+ const nextPath = [...path24, key2];
13046
13264
  const displayPath = toDisplayPath(nextPath);
13047
13265
  const field = fieldByPath.get(displayPath);
13048
13266
  if (field !== void 0) {
@@ -13249,8 +13467,8 @@ function createFixtureService(definition) {
13249
13467
  );
13250
13468
  }
13251
13469
  function resolveFixturePath(commandPath) {
13252
- const parsed = path13.parse(commandPath);
13253
- return path13.join(parsed.dir, `${parsed.name}.fixture.json`);
13470
+ const parsed = path14.parse(commandPath);
13471
+ return path14.join(parsed.dir, `${parsed.name}.fixture.json`);
13254
13472
  }
13255
13473
  function selectFixtureScenario(scenarios, selector, fixturePath) {
13256
13474
  if (isNumericFixtureSelector(selector)) {
@@ -13384,8 +13602,8 @@ function validateServices(services) {
13384
13602
  }
13385
13603
  }
13386
13604
  }
13387
- function getNestedValue(target, path23) {
13388
- return path23.reduce(
13605
+ function getNestedValue(target, path24) {
13606
+ return path24.reduce(
13389
13607
  (current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
13390
13608
  target
13391
13609
  );
@@ -14536,7 +14754,8 @@ function configureCommanderSuggestionOutput(command) {
14536
14754
  }
14537
14755
  async function runCLI(roots, options = {}) {
14538
14756
  enableSourceMaps();
14539
- const root = mergeApprovalsGroup(normalizeRoots(roots, process.argv));
14757
+ const normalizedRoot = normalizeRoots(roots, process.argv);
14758
+ const root = options.approvals === false ? normalizedRoot : mergeApprovalsGroup(normalizedRoot);
14540
14759
  await resolveMcpProxies(root, { projectRoot: options.projectRoot });
14541
14760
  const casing = options.casing ?? "kebab";
14542
14761
  const services = options.services ?? {};
@@ -14648,7 +14867,7 @@ async function runCLI(roots, options = {}) {
14648
14867
  }
14649
14868
 
14650
14869
  // src/terminal-pilot.ts
14651
- import { randomUUID as randomUUID3 } from "node:crypto";
14870
+ import { randomUUID as randomUUID4 } from "node:crypto";
14652
14871
 
14653
14872
  // src/terminal-session.ts
14654
14873
  import { EventEmitter } from "node:events";
@@ -14667,7 +14886,7 @@ var DCS = 144;
14667
14886
  var SOS = 152;
14668
14887
  var PM = 158;
14669
14888
  var APC = 159;
14670
- function stripAnsi3(input) {
14889
+ function stripAnsi4(input) {
14671
14890
  let output = "";
14672
14891
  for (let index = 0; index < input.length; index += 1) {
14673
14892
  const code = input.charCodeAt(index);
@@ -15547,7 +15766,7 @@ var TerminalScreen = class {
15547
15766
  cursor,
15548
15767
  size
15549
15768
  }) {
15550
- this.lines = Object.freeze(lines.map((line) => stripAnsi3(line)));
15769
+ this.lines = Object.freeze(lines.map((line) => stripAnsi4(line)));
15551
15770
  this.rawLines = Object.freeze([...rawLines]);
15552
15771
  this.cursor = Object.freeze({ ...cursor });
15553
15772
  this.size = Object.freeze({ ...size });
@@ -15702,7 +15921,7 @@ var TerminalSession = class {
15702
15921
  });
15703
15922
  }
15704
15923
  async history(opts) {
15705
- const normalized = normalizeHistoryBuffer(stripAnsi3(this.rawBuffer));
15924
+ const normalized = normalizeHistoryBuffer(stripAnsi4(this.rawBuffer));
15706
15925
  const lines = splitHistoryLines(normalized);
15707
15926
  if (opts?.last === void 0) {
15708
15927
  return lines;
@@ -15835,7 +16054,7 @@ function isMissingFileError(error3) {
15835
16054
  return "code" in error3 && error3.code === "ENOENT";
15836
16055
  }
15837
16056
  function matchPattern(buffer, pattern) {
15838
- const clean = normalizeHistoryBuffer(stripAnsi3(buffer));
16057
+ const clean = normalizeHistoryBuffer(stripAnsi4(buffer));
15839
16058
  for (const line of clean.split("\n")) {
15840
16059
  if (typeof pattern === "string") {
15841
16060
  if (line.includes(pattern)) return line;
@@ -15923,7 +16142,7 @@ var TerminalPilot = class _TerminalPilot {
15923
16142
  }
15924
16143
  async newSession(opts) {
15925
16144
  const session = new TerminalSession({
15926
- id: randomUUID3(),
16145
+ id: randomUUID4(),
15927
16146
  command: opts.command,
15928
16147
  args: opts.args,
15929
16148
  cwd: opts.cwd,
@@ -16191,7 +16410,7 @@ var getSession = defineCommand({
16191
16410
 
16192
16411
  // ../agent-skill-config/src/configs.ts
16193
16412
  import os2 from "node:os";
16194
- import path14 from "node:path";
16413
+ import path15 from "node:path";
16195
16414
 
16196
16415
  // ../agent-defs/src/agents/claude-code.ts
16197
16416
  var claudeCodeAgent = {
@@ -16500,7 +16719,7 @@ var templateMutation = {
16500
16719
  };
16501
16720
 
16502
16721
  // ../config-mutations/src/execution/apply-mutation.ts
16503
- import path16 from "node:path";
16722
+ import path17 from "node:path";
16504
16723
 
16505
16724
  // ../config-mutations/src/formats/json.ts
16506
16725
  import * as jsonc from "jsonc-parser";
@@ -16538,6 +16757,13 @@ function cloneConfigValue(value) {
16538
16757
  function isConfigObject(value) {
16539
16758
  return typeof value === "object" && value !== null && !Array.isArray(value);
16540
16759
  }
16760
+ function detectIndent(content) {
16761
+ const match = content.match(/^[\t ]+/m);
16762
+ if (match) {
16763
+ return match[0];
16764
+ }
16765
+ return " ";
16766
+ }
16541
16767
  function parse3(content) {
16542
16768
  if (!content || content.trim() === "") {
16543
16769
  return {};
@@ -16577,6 +16803,9 @@ function merge(base, patch) {
16577
16803
  }
16578
16804
  return result;
16579
16805
  }
16806
+ function configValuesEqual(left, right) {
16807
+ return JSON.stringify(left) === JSON.stringify(right);
16808
+ }
16580
16809
  function prune(obj, shape) {
16581
16810
  let changed = false;
16582
16811
  const result = cloneConfigObject(obj);
@@ -16613,9 +16842,56 @@ function prune(obj, shape) {
16613
16842
  }
16614
16843
  return { changed, result };
16615
16844
  }
16845
+ function modifyAtPath(content, path24, value) {
16846
+ const indent = detectIndent(content);
16847
+ const formattingOptions = {
16848
+ tabSize: indent === " " ? 1 : indent.length,
16849
+ insertSpaces: indent !== " ",
16850
+ eol: "\n"
16851
+ };
16852
+ const edits = jsonc.modify(content, path24, value, { formattingOptions });
16853
+ let result = jsonc.applyEdits(content, edits);
16854
+ if (!result.endsWith("\n")) {
16855
+ result += "\n";
16856
+ }
16857
+ return result;
16858
+ }
16859
+ function removeAtPath(content, path24) {
16860
+ return modifyAtPath(content, path24, void 0);
16861
+ }
16862
+ function serializeUpdate(content, current, next) {
16863
+ let result = content || "{}";
16864
+ result = applyObjectUpdate(result, [], current, next);
16865
+ if (!result.endsWith("\n")) {
16866
+ result += "\n";
16867
+ }
16868
+ return result;
16869
+ }
16870
+ function applyObjectUpdate(content, path24, current, next) {
16871
+ let result = content;
16872
+ for (const key2 of Object.keys(current)) {
16873
+ if (!hasConfigEntry(next, key2)) {
16874
+ result = removeAtPath(result, [...path24, key2]);
16875
+ }
16876
+ }
16877
+ for (const [key2, nextValue] of Object.entries(next)) {
16878
+ const nextPath = [...path24, key2];
16879
+ const hasCurrent = hasConfigEntry(current, key2);
16880
+ const currentValue = hasCurrent ? current[key2] : void 0;
16881
+ if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
16882
+ result = applyObjectUpdate(result, nextPath, currentValue, nextValue);
16883
+ continue;
16884
+ }
16885
+ if (!hasCurrent || !configValuesEqual(currentValue, nextValue)) {
16886
+ result = modifyAtPath(result, nextPath, nextValue);
16887
+ }
16888
+ }
16889
+ return result;
16890
+ }
16616
16891
  var jsonFormat = {
16617
16892
  parse: parse3,
16618
16893
  serialize,
16894
+ serializeUpdate,
16619
16895
  merge,
16620
16896
  prune
16621
16897
  };
@@ -16799,20 +17075,20 @@ function getConfigFormat(pathOrFormat) {
16799
17075
  }
16800
17076
  return formatRegistry[formatName];
16801
17077
  }
16802
- function detectFormat(path23) {
16803
- const ext = getExtension(path23);
17078
+ function detectFormat(path24) {
17079
+ const ext = getExtension(path24);
16804
17080
  return extensionMap[ext];
16805
17081
  }
16806
- function getExtension(path23) {
16807
- const lastDot = path23.lastIndexOf(".");
17082
+ function getExtension(path24) {
17083
+ const lastDot = path24.lastIndexOf(".");
16808
17084
  if (lastDot === -1) {
16809
17085
  return "";
16810
17086
  }
16811
- return path23.slice(lastDot).toLowerCase();
17087
+ return path24.slice(lastDot).toLowerCase();
16812
17088
  }
16813
17089
 
16814
17090
  // ../config-mutations/src/execution/path-utils.ts
16815
- import path15 from "node:path";
17091
+ import path16 from "node:path";
16816
17092
  function expandHome(targetPath, homeDir) {
16817
17093
  if (!targetPath?.startsWith("~")) {
16818
17094
  return targetPath;
@@ -16829,7 +17105,7 @@ function expandHome(targetPath, homeDir) {
16829
17105
  remainder = remainder.slice(1);
16830
17106
  }
16831
17107
  }
16832
- return remainder.length === 0 ? homeDir : path15.join(homeDir, remainder);
17108
+ return remainder.length === 0 ? homeDir : path16.join(homeDir, remainder);
16833
17109
  }
16834
17110
  function validateHomePath(targetPath) {
16835
17111
  if (typeof targetPath !== "string" || targetPath.length === 0) {
@@ -16844,21 +17120,21 @@ function validateHomePath(targetPath) {
16844
17120
  function resolvePath(rawPath, homeDir, pathMapper) {
16845
17121
  validateHomePath(rawPath);
16846
17122
  const expanded = expandHome(rawPath, homeDir);
16847
- const canonicalHome = path15.resolve(homeDir);
16848
- const canonicalExpanded = path15.resolve(expanded);
16849
- const relative = path15.relative(canonicalHome, canonicalExpanded);
16850
- if (relative === ".." || relative.startsWith(`..${path15.sep}`) || path15.isAbsolute(relative)) {
17123
+ const canonicalHome = path16.resolve(homeDir);
17124
+ const canonicalExpanded = path16.resolve(expanded);
17125
+ const relative = path16.relative(canonicalHome, canonicalExpanded);
17126
+ if (relative === ".." || relative.startsWith(`..${path16.sep}`) || path16.isAbsolute(relative)) {
16851
17127
  throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
16852
17128
  }
16853
17129
  if (!pathMapper) {
16854
17130
  return canonicalExpanded;
16855
17131
  }
16856
- const rawDirectory = path15.dirname(expanded);
17132
+ const rawDirectory = path16.dirname(expanded);
16857
17133
  const mappedDirectory = pathMapper.mapTargetDirectory({
16858
17134
  targetDirectory: rawDirectory
16859
17135
  });
16860
- const filename = path15.basename(expanded);
16861
- return filename.length === 0 ? mappedDirectory : path15.join(mappedDirectory, filename);
17136
+ const filename = path16.basename(expanded);
17137
+ return filename.length === 0 ? mappedDirectory : path16.join(mappedDirectory, filename);
16862
17138
  }
16863
17139
 
16864
17140
  // ../config-mutations/src/fs-utils.ts
@@ -16922,8 +17198,8 @@ function isAlreadyExists(error3) {
16922
17198
  return Boolean(error3 && typeof error3 === "object" && "code" in error3 && error3.code === "EEXIST");
16923
17199
  }
16924
17200
  async function assertRegularWriteTarget(context, targetPath) {
16925
- const boundary = path16.dirname(path16.resolve(context.homeDir));
16926
- let currentPath = path16.resolve(targetPath);
17201
+ const boundary = path17.dirname(path17.resolve(context.homeDir));
17202
+ let currentPath = path17.resolve(targetPath);
16927
17203
  while (currentPath !== boundary) {
16928
17204
  try {
16929
17205
  if ((await context.fs.lstat(currentPath)).isSymbolicLink()) {
@@ -16934,7 +17210,7 @@ async function assertRegularWriteTarget(context, targetPath) {
16934
17210
  throw error3;
16935
17211
  }
16936
17212
  }
16937
- const parentPath = path16.dirname(currentPath);
17213
+ const parentPath = path17.dirname(currentPath);
16938
17214
  if (parentPath === currentPath) {
16939
17215
  return;
16940
17216
  }
@@ -16997,7 +17273,7 @@ function pruneKeysByPrefix(table, prefix) {
16997
17273
  const result = {};
16998
17274
  for (const [key2, value] of Object.entries(table)) {
16999
17275
  if (!key2.startsWith(prefix)) {
17000
- result[key2] = value;
17276
+ setConfigEntry(result, key2, value);
17001
17277
  }
17002
17278
  }
17003
17279
  return result;
@@ -17006,28 +17282,43 @@ function isConfigObject4(value) {
17006
17282
  return typeof value === "object" && value !== null && !Array.isArray(value);
17007
17283
  }
17008
17284
  function mergeWithPruneByPrefix(base, patch, pruneByPrefix) {
17009
- const result = { ...base };
17285
+ const result = cloneConfigObject(base);
17010
17286
  const prefixMap = pruneByPrefix ?? {};
17011
17287
  for (const [key2, value] of Object.entries(patch)) {
17288
+ if (value === void 0) {
17289
+ continue;
17290
+ }
17012
17291
  const current = result[key2];
17013
17292
  const prefix = prefixMap[key2];
17014
17293
  if (isConfigObject4(current) && isConfigObject4(value)) {
17015
17294
  if (prefix) {
17016
17295
  const pruned = pruneKeysByPrefix(current, prefix);
17017
- result[key2] = { ...pruned, ...value };
17296
+ setConfigEntry(result, key2, mergePrunedConfigObject(pruned, value));
17018
17297
  } else {
17019
- result[key2] = mergeWithPruneByPrefix(
17020
- current,
17021
- value,
17022
- prefixMap
17023
- );
17298
+ setConfigEntry(result, key2, mergeWithPruneByPrefix(current, value, prefixMap));
17024
17299
  }
17025
17300
  continue;
17026
17301
  }
17027
- result[key2] = value;
17302
+ setConfigEntry(result, key2, value);
17028
17303
  }
17029
17304
  return result;
17030
17305
  }
17306
+ function mergePrunedConfigObject(base, patch) {
17307
+ const result = cloneConfigObject(base);
17308
+ for (const [key2, value] of Object.entries(patch)) {
17309
+ if (value === void 0) {
17310
+ continue;
17311
+ }
17312
+ setConfigEntry(result, key2, value);
17313
+ }
17314
+ return result;
17315
+ }
17316
+ function serializeConfigUpdate(format, rawContent, current, next) {
17317
+ if (rawContent !== null && format.serializeUpdate) {
17318
+ return format.serializeUpdate(rawContent, current, next);
17319
+ }
17320
+ return format.serialize(next);
17321
+ }
17031
17322
  async function applyMutation(mutation, context, options) {
17032
17323
  switch (mutation.kind) {
17033
17324
  case "ensureDirectory":
@@ -17340,6 +17631,7 @@ async function applyConfigMerge(mutation, context, options) {
17340
17631
  }
17341
17632
  const format = getConfigFormat(formatName);
17342
17633
  const rawContent = await readFileIfExists(context.fs, targetPath);
17634
+ let preserveContent = rawContent;
17343
17635
  let current;
17344
17636
  try {
17345
17637
  current = rawContent === null ? {} : format.parse(rawContent);
@@ -17348,6 +17640,7 @@ async function applyConfigMerge(mutation, context, options) {
17348
17640
  await backupInvalidDocument(context, targetPath, rawContent);
17349
17641
  }
17350
17642
  current = {};
17643
+ preserveContent = null;
17351
17644
  }
17352
17645
  const value = resolveValue(mutation.value, options);
17353
17646
  let merged;
@@ -17356,7 +17649,7 @@ async function applyConfigMerge(mutation, context, options) {
17356
17649
  } else {
17357
17650
  merged = format.merge(current, value);
17358
17651
  }
17359
- const serialized = format.serialize(merged);
17652
+ const serialized = serializeConfigUpdate(format, preserveContent, current, merged);
17360
17653
  const changed = serialized !== rawContent;
17361
17654
  if (changed && !context.dryRun) {
17362
17655
  await writeAtomically2(context, targetPath, serialized);
@@ -17424,7 +17717,7 @@ async function applyConfigPrune(mutation, context, options) {
17424
17717
  details
17425
17718
  };
17426
17719
  }
17427
- const serialized = format.serialize(result);
17720
+ const serialized = serializeConfigUpdate(format, rawContent, current, result);
17428
17721
  if (!context.dryRun) {
17429
17722
  await writeAtomically2(context, targetPath, serialized);
17430
17723
  }
@@ -17449,6 +17742,7 @@ async function applyConfigTransform(mutation, context, options) {
17449
17742
  }
17450
17743
  const format = getConfigFormat(formatName);
17451
17744
  const rawContent = await readFileIfExists(context.fs, targetPath);
17745
+ let preserveContent = rawContent;
17452
17746
  let current;
17453
17747
  try {
17454
17748
  current = rawContent === null ? {} : format.parse(rawContent);
@@ -17457,6 +17751,7 @@ async function applyConfigTransform(mutation, context, options) {
17457
17751
  await backupInvalidDocument(context, targetPath, rawContent);
17458
17752
  }
17459
17753
  current = {};
17754
+ preserveContent = null;
17460
17755
  }
17461
17756
  const { content: transformed, changed } = mutation.transform(current, options);
17462
17757
  if (!changed) {
@@ -17480,7 +17775,7 @@ async function applyConfigTransform(mutation, context, options) {
17480
17775
  details
17481
17776
  };
17482
17777
  }
17483
- const serialized = format.serialize(transformed);
17778
+ const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
17484
17779
  if (!context.dryRun) {
17485
17780
  await writeAtomically2(context, targetPath, serialized);
17486
17781
  }
@@ -17622,7 +17917,7 @@ async function executeMutation(mutation, context, options) {
17622
17917
 
17623
17918
  // ../agent-skill-config/src/templates.ts
17624
17919
  import { readFile as readFile5, stat } from "node:fs/promises";
17625
- import path17 from "node:path";
17920
+ import path18 from "node:path";
17626
17921
  import { fileURLToPath as fileURLToPath3 } from "node:url";
17627
17922
 
17628
17923
  // ../agent-skill-config/src/apply.ts
@@ -17699,21 +17994,21 @@ async function installSkill(agentId, skill, options) {
17699
17994
 
17700
17995
  // ../agent-skill-config/src/resolve-skill-reference.ts
17701
17996
  import { statSync as statSync2 } from "node:fs";
17702
- import path18 from "node:path";
17997
+ import path19 from "node:path";
17703
17998
 
17704
17999
  // ../agent-skill-config/src/git-exclude.ts
17705
18000
  import { execFileSync } from "node:child_process";
17706
18001
  import * as fs2 from "node:fs";
17707
- import path19 from "node:path";
18002
+ import path20 from "node:path";
17708
18003
 
17709
18004
  // ../agent-skill-config/src/bridge-active-skills.ts
17710
18005
  import * as fs3 from "node:fs";
17711
- import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
17712
- import path20 from "node:path";
18006
+ import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
18007
+ import path21 from "node:path";
17713
18008
 
17714
18009
  // src/commands/installer.ts
17715
18010
  import os3 from "node:os";
17716
- import path21 from "node:path";
18011
+ import path22 from "node:path";
17717
18012
  import * as nodeFs2 from "node:fs/promises";
17718
18013
  import { readFile as readFile6 } from "node:fs/promises";
17719
18014
  var DEFAULT_INSTALL_AGENT = "claude-code";
@@ -17780,7 +18075,7 @@ function resolveHomeRelativePath(targetPath, homeDir) {
17780
18075
  return homeDir;
17781
18076
  }
17782
18077
  if (targetPath.startsWith("~/")) {
17783
- return path21.join(homeDir, targetPath.slice(2));
18078
+ return path22.join(homeDir, targetPath.slice(2));
17784
18079
  }
17785
18080
  return targetPath;
17786
18081
  }
@@ -17790,18 +18085,18 @@ function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
17790
18085
  throwUnsupportedAgent(agent);
17791
18086
  }
17792
18087
  return {
17793
- displayPath: path21.join(
18088
+ displayPath: path22.join(
17794
18089
  scope === "global" ? config.globalSkillDir : config.localSkillDir,
17795
18090
  TERMINAL_PILOT_SKILL_NAME
17796
18091
  ),
17797
- fullPath: path21.join(
17798
- scope === "global" ? resolveHomeRelativePath(config.globalSkillDir, homeDir) : path21.resolve(cwd, config.localSkillDir),
18092
+ fullPath: path22.join(
18093
+ scope === "global" ? resolveHomeRelativePath(config.globalSkillDir, homeDir) : path22.resolve(cwd, config.localSkillDir),
17799
18094
  TERMINAL_PILOT_SKILL_NAME
17800
18095
  )
17801
18096
  };
17802
18097
  }
17803
18098
  async function assertNoSymbolicLinkPath(fs4, targetPath) {
17804
- const rootPath = path21.parse(targetPath).root;
18099
+ const rootPath = path22.parse(targetPath).root;
17805
18100
  let currentPath = targetPath;
17806
18101
  while (currentPath !== rootPath) {
17807
18102
  try {
@@ -17813,7 +18108,7 @@ async function assertNoSymbolicLinkPath(fs4, targetPath) {
17813
18108
  throw error3;
17814
18109
  }
17815
18110
  }
17816
- currentPath = path21.dirname(currentPath);
18111
+ currentPath = path22.dirname(currentPath);
17817
18112
  }
17818
18113
  }
17819
18114
 
@@ -17952,7 +18247,7 @@ var resize = defineCommand({
17952
18247
  });
17953
18248
 
17954
18249
  // ../terminal-png/src/index.ts
17955
- import { randomUUID as randomUUID5 } from "node:crypto";
18250
+ import { randomUUID as randomUUID6 } from "node:crypto";
17956
18251
  import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
17957
18252
 
17958
18253
  // ../terminal-png/src/ansi-parser.ts
@@ -18892,7 +19187,7 @@ async function renderTerminalPng(ansiText, options = {}) {
18892
19187
  });
18893
19188
  const png = renderPng(svg);
18894
19189
  if (options.output) {
18895
- const temporaryPath = `${options.output}.${randomUUID5()}.tmp`;
19190
+ const temporaryPath = `${options.output}.${randomUUID6()}.tmp`;
18896
19191
  try {
18897
19192
  await writeFile6(temporaryPath, png, { flag: "wx" });
18898
19193
  await rename4(temporaryPath, options.output);
@@ -18969,7 +19264,7 @@ var type = defineCommand({
18969
19264
  });
18970
19265
 
18971
19266
  // src/commands/uninstall.ts
18972
- import { randomUUID as randomUUID6 } from "node:crypto";
19267
+ import { randomUUID as randomUUID7 } from "node:crypto";
18973
19268
  var params14 = S.Object({
18974
19269
  agent: S.Enum(installableAgents, {
18975
19270
  description: "Agent to uninstall terminal-pilot from",
@@ -19005,7 +19300,7 @@ var uninstall = defineCommand({
19005
19300
  if (!await folderExists(services.fs, skill.fullPath)) {
19006
19301
  continue;
19007
19302
  }
19008
- const stagingPath = `${skill.fullPath}.removing-${randomUUID6()}`;
19303
+ const stagingPath = `${skill.fullPath}.removing-${randomUUID7()}`;
19009
19304
  await services.fs.rename(skill.fullPath, stagingPath);
19010
19305
  staged.push({ ...skill, stagingPath });
19011
19306
  }
@@ -19135,7 +19430,7 @@ async function isDirectExecution(argv) {
19135
19430
  try {
19136
19431
  const modulePath = fileURLToPath5(import.meta.url);
19137
19432
  const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
19138
- realpath2(path22.resolve(entryPoint)),
19433
+ realpath2(path23.resolve(entryPoint)),
19139
19434
  realpath2(modulePath)
19140
19435
  ]);
19141
19436
  return resolvedEntryPoint === resolvedModulePath;