@macintacos/caret 0.11.1 → 0.13.0

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 (107) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/cli.js +497 -126
  3. package/opencode/.greptile/files.json +12 -0
  4. package/opencode/caret.plugin.ts +7 -5
  5. package/package.json +3 -1
  6. package/ui/dist/assets/{angular-html-BCtCrX5a.js → angular-html-JsdW_WcC.js} +1 -1
  7. package/ui/dist/assets/{angular-ts-CHydi2Ns.js → angular-ts-DB5trF48.js} +1 -1
  8. package/ui/dist/assets/{apl-Drvu7CDf.js → apl-BHONMsFL.js} +1 -1
  9. package/ui/dist/assets/{astro-D7QjN1UP.js → astro-Ds0Hdj6N.js} +1 -1
  10. package/ui/dist/assets/{blade-fJMvh-87.js → blade-u3yPcwZm.js} +1 -1
  11. package/ui/dist/assets/{c-CekX8pZk.js → c-DrTWjY43.js} +1 -1
  12. package/ui/dist/assets/{chapel-Yat3WM3Z.js → chapel-BQ3j01mw.js} +1 -1
  13. package/ui/dist/assets/{cobol-CpcYU6QJ.js → cobol-CYMPXcxw.js} +1 -1
  14. package/ui/dist/assets/{coffee-C83ly5t5.js → coffee-BTAQjKY2.js} +1 -1
  15. package/ui/dist/assets/{cpp-BkID-Sus.js → cpp-Bi8OcMQs.js} +1 -1
  16. package/ui/dist/assets/{crystal-C3Etyhx4.js → crystal-BeA91aRl.js} +1 -1
  17. package/ui/dist/assets/{css-BpCnu0V7.js → css-Bxrmub2j.js} +1 -1
  18. package/ui/dist/assets/{dist-CdQe3tPj.js → dist-5Bv2mYWj.js} +1 -1
  19. package/ui/dist/assets/{dist-DP5L_loZ.js → dist-B0Do-tNS.js} +1 -1
  20. package/ui/dist/assets/{dist-BGMYonjC.js → dist-Bz_ap3g2.js} +1 -1
  21. package/ui/dist/assets/dist-C5v67AiS.js +1 -0
  22. package/ui/dist/assets/{dist-DigqW6HL.js → dist-CBxRdWpx.js} +1 -1
  23. package/ui/dist/assets/dist-CGl7bSLs.js +1 -0
  24. package/ui/dist/assets/{dist-CZqH1975.js → dist-CR6NZa0h.js} +1 -1
  25. package/ui/dist/assets/{dist-BAGkWecZ.js → dist-C_lXyw3s.js} +1 -1
  26. package/ui/dist/assets/{dist-BRT8QHfd.js → dist-ChMSH6xV.js} +1 -1
  27. package/ui/dist/assets/dist-CiBs4R_k.js +12 -0
  28. package/ui/dist/assets/{dist-DE3I1JlS.js → dist-DH1_ZbAP.js} +1 -1
  29. package/ui/dist/assets/{dist-DaoC_D4S.js → dist-DHAfbOzU.js} +1 -1
  30. package/ui/dist/assets/{dist-CMpTs5ms.js → dist-DQgprm5S.js} +1 -1
  31. package/ui/dist/assets/{dist-CikfqRw0.js → dist-D_g9f9rz.js} +1 -1
  32. package/ui/dist/assets/{dist-C83naKOT.js → dist-DqAJNUky.js} +1 -1
  33. package/ui/dist/assets/{dist-CaX-VV5u.js → dist-Dt1D8SWK.js} +1 -1
  34. package/ui/dist/assets/{dist-C18hcQ4P.js → dist-IqwiD_4c.js} +1 -1
  35. package/ui/dist/assets/dist-sQ_pTc4a.js +1 -0
  36. package/ui/dist/assets/{edge-D5Zqrwyu.js → edge-CM4DKqp3.js} +1 -1
  37. package/ui/dist/assets/{elixir-CH9Za_0Q.js → elixir-D76HLRzC.js} +1 -1
  38. package/ui/dist/assets/{elm-BRsxXryd.js → elm-BYD2LdpG.js} +1 -1
  39. package/ui/dist/assets/{erb-BmBctG8H.js → erb-Depv6q0i.js} +1 -1
  40. package/ui/dist/assets/{git-rebase-Czmn49GX.js → git-rebase-By6KsZra.js} +1 -1
  41. package/ui/dist/assets/{glimmer-js-CPcJ-Kpr.js → glimmer-js-B9OgS597.js} +1 -1
  42. package/ui/dist/assets/{glimmer-ts-BNs1wtxL.js → glimmer-ts-BQ9yXV5i.js} +1 -1
  43. package/ui/dist/assets/{glsl-Qt2fC-Ca.js → glsl-CgWn_pPL.js} +1 -1
  44. package/ui/dist/assets/{graphql-DkQYUTG4.js → graphql-C6705FXv.js} +1 -1
  45. package/ui/dist/assets/{hack-CxhNZd7u.js → hack-CuMDN2go.js} +1 -1
  46. package/ui/dist/assets/{haml-CsxFxMDV.js → haml-BiSYPvKJ.js} +1 -1
  47. package/ui/dist/assets/{handlebars-BdiOITvu.js → handlebars-C1r5dETi.js} +1 -1
  48. package/ui/dist/assets/{html-derivative-CH1IZbFQ.js → html-derivative-clnDfVNs.js} +1 -1
  49. package/ui/dist/assets/{html-QiZEf_SK.js → html-iBfWgjFQ.js} +1 -1
  50. package/ui/dist/assets/{http-B3cBswFA.js → http-hT30HceR.js} +1 -1
  51. package/ui/dist/assets/{hurl-CxLSuJlC.js → hurl-DQ0AcU20.js} +1 -1
  52. package/ui/dist/assets/index-CjqVXWlr.js +6767 -0
  53. package/ui/dist/assets/index-Dn0ZHhG9.css +1 -0
  54. package/ui/dist/assets/{java-BofMVjSW.js → java-Dm4xXBhF.js} +1 -1
  55. package/ui/dist/assets/{javascript-CXxuBuBv.js → javascript-PW_29aC7.js} +1 -1
  56. package/ui/dist/assets/{jinja-CR6mlgq7.js → jinja-grwkrR8u.js} +1 -1
  57. package/ui/dist/assets/{jison-Lnun11yb.js → jison-DFY8lcfy.js} +1 -1
  58. package/ui/dist/assets/{json-CN58fVYV.js → json-C34uLNh4.js} +1 -1
  59. package/ui/dist/assets/{jsx-DCoYQRrE.js → jsx-CWBlf8VC.js} +1 -1
  60. package/ui/dist/assets/{julia-BTSVBcvZ.js → julia-DCj8-aMw.js} +1 -1
  61. package/ui/dist/assets/{just-BHXaIZ4_.js → just-B_yigvdA.js} +1 -1
  62. package/ui/dist/assets/{latex-4pZhxAuK.js → latex-QDkoREbu.js} +1 -1
  63. package/ui/dist/assets/{liquid-BKD3U_oR.js → liquid-BgxQ_Ybv.js} +1 -1
  64. package/ui/dist/assets/{lua-CTFIANPX.js → lua-B7jopNUe.js} +1 -1
  65. package/ui/dist/assets/{marko-ChHXPgtx.js → marko-ClWMCpy4.js} +1 -1
  66. package/ui/dist/assets/{mdc-DUuqpwFU.js → mdc-B5qjhcv5.js} +1 -1
  67. package/ui/dist/assets/{nginx-T0b5wlEx.js → nginx-BLvCl2vo.js} +1 -1
  68. package/ui/dist/assets/{nim-85DDTDOp.js → nim-D1vVna5G.js} +1 -1
  69. package/ui/dist/assets/{org-YVLZnOmG.js → org-CQUu5Xjo.js} +1 -1
  70. package/ui/dist/assets/{perl-DvhyK2f5.js → perl-Cn9pqCpd.js} +1 -1
  71. package/ui/dist/assets/{php-BHJ0Y1qf.js → php-DQA4j1w3.js} +1 -1
  72. package/ui/dist/assets/{pug-Kw39Rh1n.js → pug-Dcu9qjZu.js} +1 -1
  73. package/ui/dist/assets/{qml-B658j8AE.js → qml-CFaCL8zR.js} +1 -1
  74. package/ui/dist/assets/{r-CR7aKAa8.js → r-BeWyCF96.js} +1 -1
  75. package/ui/dist/assets/{razor-C-sVKuwt.js → razor-DhTjYPP2.js} +1 -1
  76. package/ui/dist/assets/{regexp-DxGFa2i7.js → regexp-BZBzV8k3.js} +1 -1
  77. package/ui/dist/assets/{rst-CSAcRVJs.js → rst-CPeugCoY.js} +1 -1
  78. package/ui/dist/assets/{ruby-nwXRunGb.js → ruby-S1Kev63y.js} +1 -1
  79. package/ui/dist/assets/{sas-bPI1gB4G.js → sas-DzuTM5FV.js} +1 -1
  80. package/ui/dist/assets/{scss-pEDYjvcR.js → scss-CimGOfjN.js} +1 -1
  81. package/ui/dist/assets/{shellscript-BMqUwS6Q.js → shellscript-BTeF_2ej.js} +1 -1
  82. package/ui/dist/assets/{shellsession-DNtYOelF.js → shellsession-DFdgXQ-h.js} +1 -1
  83. package/ui/dist/assets/{soy-DnnesykU.js → soy-CJHYVIlT.js} +1 -1
  84. package/ui/dist/assets/{sql-zhmnw-Qu.js → sql-HmJC1LPx.js} +1 -1
  85. package/ui/dist/assets/{stata-DL2EuIvP.js → stata-C1JKV9ST.js} +1 -1
  86. package/ui/dist/assets/{surrealql-CWt3zqL2.js → surrealql-DdWTVOJW.js} +1 -1
  87. package/ui/dist/assets/{svelte-DCo3F0ZU.js → svelte-B3DUwjVb.js} +1 -1
  88. package/ui/dist/assets/{templ-LSVSbai1.js → templ-Dx_nsS-N.js} +1 -1
  89. package/ui/dist/assets/{tex-9pbj95aK.js → tex-BHbvXPLE.js} +1 -1
  90. package/ui/dist/assets/{ts-tags-CW8KiYYw.js → ts-tags-BV7lCDbe.js} +1 -1
  91. package/ui/dist/assets/{tsx-H15NQblA.js → tsx-BYZjS03A.js} +1 -1
  92. package/ui/dist/assets/{twig-gygTtTHa.js → twig-DAWYqd9-.js} +1 -1
  93. package/ui/dist/assets/{typescript-DAM7c_vC.js → typescript-BBlnjAR4.js} +1 -1
  94. package/ui/dist/assets/{typst-DiLVywPa.js → typst-BHcXb2UY.js} +1 -1
  95. package/ui/dist/assets/{vue-DRQFPwfE.js → vue-YvTBU6lw.js} +1 -1
  96. package/ui/dist/assets/{vue-html-vjHeecsY.js → vue-html-Dy8_dd5p.js} +1 -1
  97. package/ui/dist/assets/{vue-vine-BUoL6GNl.js → vue-vine-BLSdEcQ9.js} +1 -1
  98. package/ui/dist/assets/{xml-1zKw7rGe.js → xml-DEOP2atk.js} +1 -1
  99. package/ui/dist/assets/{xsl-D_pz-oBz.js → xsl-D__kBjbu.js} +1 -1
  100. package/ui/dist/assets/{yaml-DVXHqHg_.js → yaml-D2r1aQ0B.js} +1 -1
  101. package/ui/dist/index.html +3 -3
  102. package/ui/dist/assets/dist-BPljwhRM.js +0 -1
  103. package/ui/dist/assets/dist-DfISJt9o.js +0 -12
  104. package/ui/dist/assets/dist-DhOuKeyt.js +0 -1
  105. package/ui/dist/assets/dist-UGYOZkY4.js +0 -1
  106. package/ui/dist/assets/index-DqObFNfe.js +0 -5980
  107. package/ui/dist/assets/index-MiIbURI7.css +0 -1
package/dist/cli.js CHANGED
@@ -1994,7 +1994,7 @@ var require_thread_stream = __commonJS((exports, module) => {
1994
1994
  var { version: version2 } = require_package();
1995
1995
  var { EventEmitter } = __require("events");
1996
1996
  var { Worker } = __require("worker_threads");
1997
- var { join: join7 } = __require("path");
1997
+ var { join: join9 } = __require("path");
1998
1998
  var { pathToFileURL } = __require("url");
1999
1999
  var { wait } = require_wait();
2000
2000
  var {
@@ -2044,7 +2044,7 @@ var require_thread_stream = __commonJS((exports, module) => {
2044
2044
  function createWorker(stream, opts) {
2045
2045
  const { filename, workerData } = opts;
2046
2046
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
2047
- const toExecute = bundlerOverrides["thread-stream-worker"] || join7(__dirname, "lib", "worker.js");
2047
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join9(__dirname, "lib", "worker.js");
2048
2048
  const worker = new Worker(toExecute, {
2049
2049
  ...opts.workerOpts,
2050
2050
  name: opts.workerOpts?.name || "thread-stream",
@@ -2510,7 +2510,7 @@ var require_transport = __commonJS((exports, module) => {
2510
2510
  var { createRequire } = __require("module");
2511
2511
  var { existsSync: existsSync5 } = __require("fs");
2512
2512
  var getCallers = require_caller();
2513
- var { join: join7, isAbsolute, sep } = __require("path");
2513
+ var { join: join9, isAbsolute, sep: sep3 } = __require("path");
2514
2514
  var { fileURLToPath: fileURLToPath2 } = __require("url");
2515
2515
  var sleep = require_atomic_sleep();
2516
2516
  var onExit = require_on_exit_leak_free();
@@ -2663,7 +2663,7 @@ var require_transport = __commonJS((exports, module) => {
2663
2663
  throw new Error("only one of target or targets can be specified");
2664
2664
  }
2665
2665
  if (targets) {
2666
- target = bundlerOverrides["pino-worker"] || join7(__dirname, "worker.js");
2666
+ target = bundlerOverrides["pino-worker"] || join9(__dirname, "worker.js");
2667
2667
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
2668
2668
  return {
2669
2669
  ...dest,
@@ -2680,7 +2680,7 @@ var require_transport = __commonJS((exports, module) => {
2680
2680
  });
2681
2681
  });
2682
2682
  } else if (pipeline) {
2683
- target = bundlerOverrides["pino-worker"] || join7(__dirname, "worker.js");
2683
+ target = bundlerOverrides["pino-worker"] || join9(__dirname, "worker.js");
2684
2684
  options.pipelines = [pipeline.map((dest) => {
2685
2685
  return {
2686
2686
  ...dest,
@@ -2703,12 +2703,12 @@ var require_transport = __commonJS((exports, module) => {
2703
2703
  return origin;
2704
2704
  }
2705
2705
  if (origin === "pino/file") {
2706
- return join7(__dirname, "..", "file.js");
2706
+ return join9(__dirname, "..", "file.js");
2707
2707
  }
2708
2708
  let fixTarget2;
2709
2709
  for (const filePath of callers) {
2710
2710
  try {
2711
- const context = filePath === "node:repl" ? process.cwd() + sep : filePath;
2711
+ const context = filePath === "node:repl" ? process.cwd() + sep3 : filePath;
2712
2712
  fixTarget2 = createRequire(context).resolve(origin);
2713
2713
  break;
2714
2714
  } catch (err) {
@@ -3632,7 +3632,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
3632
3632
  return circularValue;
3633
3633
  }
3634
3634
  let res = "";
3635
- let join7 = ",";
3635
+ let join9 = ",";
3636
3636
  const originalIndentation = indentation;
3637
3637
  if (Array.isArray(value)) {
3638
3638
  if (value.length === 0) {
@@ -3646,7 +3646,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
3646
3646
  indentation += spacer;
3647
3647
  res += `
3648
3648
  ${indentation}`;
3649
- join7 = `,
3649
+ join9 = `,
3650
3650
  ${indentation}`;
3651
3651
  }
3652
3652
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3654,13 +3654,13 @@ ${indentation}`;
3654
3654
  for (;i < maximumValuesToStringify - 1; i++) {
3655
3655
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3656
3656
  res += tmp2 !== undefined ? tmp2 : "null";
3657
- res += join7;
3657
+ res += join9;
3658
3658
  }
3659
3659
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3660
3660
  res += tmp !== undefined ? tmp : "null";
3661
3661
  if (value.length - 1 > maximumBreadth) {
3662
3662
  const removedKeys = value.length - maximumBreadth - 1;
3663
- res += `${join7}"... ${getItemCount(removedKeys)} not stringified"`;
3663
+ res += `${join9}"... ${getItemCount(removedKeys)} not stringified"`;
3664
3664
  }
3665
3665
  if (spacer !== "") {
3666
3666
  res += `
@@ -3681,7 +3681,7 @@ ${originalIndentation}`;
3681
3681
  let separator = "";
3682
3682
  if (spacer !== "") {
3683
3683
  indentation += spacer;
3684
- join7 = `,
3684
+ join9 = `,
3685
3685
  ${indentation}`;
3686
3686
  whitespace = " ";
3687
3687
  }
@@ -3695,13 +3695,13 @@ ${indentation}`;
3695
3695
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
3696
3696
  if (tmp !== undefined) {
3697
3697
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
3698
- separator = join7;
3698
+ separator = join9;
3699
3699
  }
3700
3700
  }
3701
3701
  if (keyLength > maximumBreadth) {
3702
3702
  const removedKeys = keyLength - maximumBreadth;
3703
3703
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
3704
- separator = join7;
3704
+ separator = join9;
3705
3705
  }
3706
3706
  if (spacer !== "" && separator.length > 1) {
3707
3707
  res = `
@@ -3741,7 +3741,7 @@ ${originalIndentation}`;
3741
3741
  }
3742
3742
  const originalIndentation = indentation;
3743
3743
  let res = "";
3744
- let join7 = ",";
3744
+ let join9 = ",";
3745
3745
  if (Array.isArray(value)) {
3746
3746
  if (value.length === 0) {
3747
3747
  return "[]";
@@ -3754,7 +3754,7 @@ ${originalIndentation}`;
3754
3754
  indentation += spacer;
3755
3755
  res += `
3756
3756
  ${indentation}`;
3757
- join7 = `,
3757
+ join9 = `,
3758
3758
  ${indentation}`;
3759
3759
  }
3760
3760
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3762,13 +3762,13 @@ ${indentation}`;
3762
3762
  for (;i < maximumValuesToStringify - 1; i++) {
3763
3763
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3764
3764
  res += tmp2 !== undefined ? tmp2 : "null";
3765
- res += join7;
3765
+ res += join9;
3766
3766
  }
3767
3767
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3768
3768
  res += tmp !== undefined ? tmp : "null";
3769
3769
  if (value.length - 1 > maximumBreadth) {
3770
3770
  const removedKeys = value.length - maximumBreadth - 1;
3771
- res += `${join7}"... ${getItemCount(removedKeys)} not stringified"`;
3771
+ res += `${join9}"... ${getItemCount(removedKeys)} not stringified"`;
3772
3772
  }
3773
3773
  if (spacer !== "") {
3774
3774
  res += `
@@ -3781,7 +3781,7 @@ ${originalIndentation}`;
3781
3781
  let whitespace = "";
3782
3782
  if (spacer !== "") {
3783
3783
  indentation += spacer;
3784
- join7 = `,
3784
+ join9 = `,
3785
3785
  ${indentation}`;
3786
3786
  whitespace = " ";
3787
3787
  }
@@ -3790,7 +3790,7 @@ ${indentation}`;
3790
3790
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
3791
3791
  if (tmp !== undefined) {
3792
3792
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
3793
- separator = join7;
3793
+ separator = join9;
3794
3794
  }
3795
3795
  }
3796
3796
  if (spacer !== "" && separator.length > 1) {
@@ -3847,20 +3847,20 @@ ${originalIndentation}`;
3847
3847
  indentation += spacer;
3848
3848
  let res2 = `
3849
3849
  ${indentation}`;
3850
- const join8 = `,
3850
+ const join10 = `,
3851
3851
  ${indentation}`;
3852
3852
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
3853
3853
  let i = 0;
3854
3854
  for (;i < maximumValuesToStringify - 1; i++) {
3855
3855
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3856
3856
  res2 += tmp2 !== undefined ? tmp2 : "null";
3857
- res2 += join8;
3857
+ res2 += join10;
3858
3858
  }
3859
3859
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3860
3860
  res2 += tmp !== undefined ? tmp : "null";
3861
3861
  if (value.length - 1 > maximumBreadth) {
3862
3862
  const removedKeys = value.length - maximumBreadth - 1;
3863
- res2 += `${join8}"... ${getItemCount(removedKeys)} not stringified"`;
3863
+ res2 += `${join10}"... ${getItemCount(removedKeys)} not stringified"`;
3864
3864
  }
3865
3865
  res2 += `
3866
3866
  ${originalIndentation}`;
@@ -3876,16 +3876,16 @@ ${originalIndentation}`;
3876
3876
  return '"[Object]"';
3877
3877
  }
3878
3878
  indentation += spacer;
3879
- const join7 = `,
3879
+ const join9 = `,
3880
3880
  ${indentation}`;
3881
3881
  let res = "";
3882
3882
  let separator = "";
3883
3883
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
3884
3884
  if (isTypedArrayWithEntries(value)) {
3885
- res += stringifyTypedArray(value, join7, maximumBreadth);
3885
+ res += stringifyTypedArray(value, join9, maximumBreadth);
3886
3886
  keys = keys.slice(value.length);
3887
3887
  maximumPropertiesToStringify -= value.length;
3888
- separator = join7;
3888
+ separator = join9;
3889
3889
  }
3890
3890
  if (deterministic) {
3891
3891
  keys = sort(keys, comparator);
@@ -3896,13 +3896,13 @@ ${indentation}`;
3896
3896
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
3897
3897
  if (tmp !== undefined) {
3898
3898
  res += `${separator}${strEscape(key2)}: ${tmp}`;
3899
- separator = join7;
3899
+ separator = join9;
3900
3900
  }
3901
3901
  }
3902
3902
  if (keyLength > maximumBreadth) {
3903
3903
  const removedKeys = keyLength - maximumBreadth;
3904
3904
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
3905
- separator = join7;
3905
+ separator = join9;
3906
3906
  }
3907
3907
  if (separator !== "") {
3908
3908
  res = `
@@ -5804,7 +5804,7 @@ __export(exports_dist, {
5804
5804
  import { styleText as styleText2, stripVTControlCharacters } from "util";
5805
5805
  import process$1 from "process";
5806
5806
  import { existsSync as existsSync11, lstatSync, readdirSync as readdirSync6 } from "fs";
5807
- import { dirname as dirname8, join as join14 } from "path";
5807
+ import { dirname as dirname8, join as join17 } from "path";
5808
5808
  function isUnicodeSupported() {
5809
5809
  if (process$1.platform !== "win32") {
5810
5810
  return process$1.env.TERM !== "linux";
@@ -6518,7 +6518,7 @@ ${n3}
6518
6518
  existsSync11(t2) ? lstatSync(t2).isDirectory() && (!e.directory || t2.endsWith("/")) ? i = t2 : i = dirname8(t2) : i = dirname8(t2);
6519
6519
  const c2 = t2.length > 1 && t2.endsWith("/") ? t2.slice(0, -1) : t2;
6520
6520
  return readdirSync6(i).map((r2) => {
6521
- const n3 = join14(i, r2), m3 = lstatSync(n3);
6521
+ const n3 = join17(i, r2), m3 = lstatSync(n3);
6522
6522
  return {
6523
6523
  name: r2,
6524
6524
  path: n3,
@@ -7066,9 +7066,18 @@ function fatalDenyLine(reason) {
7066
7066
  });
7067
7067
  }
7068
7068
 
7069
- // src/adapters/claude/install.ts
7069
+ // src/adapters/claude/paths.ts
7070
7070
  import { homedir } from "os";
7071
7071
  import { join } from "path";
7072
+ function claudeConfigDir() {
7073
+ return process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
7074
+ }
7075
+ function installedPluginsFile() {
7076
+ return join(claudeConfigDir(), "plugins", "installed_plugins.json");
7077
+ }
7078
+ function userSettingsFile() {
7079
+ return join(claudeConfigDir(), "settings.json");
7080
+ }
7072
7081
 
7073
7082
  // src/lib/json-file.ts
7074
7083
  import { readFileSync } from "fs";
@@ -7089,16 +7098,12 @@ async function readJsonFile(path) {
7089
7098
  }
7090
7099
 
7091
7100
  // src/adapters/claude/install.ts
7092
- function claudeConfigDir() {
7093
- return process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
7094
- }
7095
7101
  var PLUGIN_ID = "caret@caret";
7096
7102
  function readClaudeInstallState() {
7097
- const dir = claudeConfigDir();
7098
7103
  return {
7099
- pluginVersion: readPluginVersion(join(dir, "plugins", "installed_plugins.json")),
7100
- pluginEnabled: readPluginEnabled(join(dir, "settings.json")),
7101
- hookInUserSettings: readHookInUserSettings(join(dir, "settings.json"))
7104
+ pluginVersion: readPluginVersion(installedPluginsFile()),
7105
+ pluginEnabled: readPluginEnabled(userSettingsFile()),
7106
+ hookInUserSettings: readHookInUserSettings(userSettingsFile())
7102
7107
  };
7103
7108
  }
7104
7109
  function readPluginVersion(path) {
@@ -7141,6 +7146,180 @@ function readHookInUserSettings(path) {
7141
7146
  return false;
7142
7147
  }
7143
7148
 
7149
+ // src/adapters/claude/skills.ts
7150
+ import { access, readdir } from "fs/promises";
7151
+ import { join as join3 } from "path";
7152
+
7153
+ // src/lib/skill-doc.ts
7154
+ import { readFile as readFile2, realpath, stat } from "fs/promises";
7155
+ import { join as join2, sep } from "path";
7156
+ var FENCE = "---";
7157
+ var MAX_DOC_BYTES = 1024 * 1024;
7158
+ var DESCRIPTION_LINE = /^description:[ \t]*(.*)$/;
7159
+ var BLOCK_INTRODUCER = /^([|>])[-+]?\d*$/;
7160
+ function blockJoiner(value) {
7161
+ const introducer = BLOCK_INTRODUCER.exec(value)?.[1];
7162
+ if (introducer === undefined)
7163
+ return;
7164
+ return introducer === "|" ? `
7165
+ ` : " ";
7166
+ }
7167
+ async function containedFile(root, relative) {
7168
+ const [rootReal, real] = await Promise.all([
7169
+ realpath(root).catch(() => null),
7170
+ realpath(join2(root, relative)).catch(() => null)
7171
+ ]);
7172
+ if (rootReal === null || real === null)
7173
+ return null;
7174
+ return real === rootReal || real.startsWith(rootReal + sep) ? real : null;
7175
+ }
7176
+ function frontmatterLines(content) {
7177
+ const lines = content.split(`
7178
+ `).map((line) => line.replace(/\r$/, ""));
7179
+ if (lines[0]?.trimEnd() !== FENCE)
7180
+ return null;
7181
+ const close = lines.findIndex((line, i) => i > 0 && line.trimEnd() === FENCE);
7182
+ return close === -1 ? null : lines.slice(1, close);
7183
+ }
7184
+ function unquote(value) {
7185
+ const quote = value[0];
7186
+ if ((quote === '"' || quote === "'") && value.length > 1 && value.endsWith(quote)) {
7187
+ return value.slice(1, -1);
7188
+ }
7189
+ return value;
7190
+ }
7191
+ function blockScalar(rest, joiner) {
7192
+ const taken = [];
7193
+ for (const line of rest) {
7194
+ if (line.trim() !== "" && !/^[ \t]/.test(line))
7195
+ break;
7196
+ taken.push(line.trim());
7197
+ }
7198
+ const kept = joiner === `
7199
+ ` ? taken : taken.filter((line) => line !== "");
7200
+ return kept.join(joiner).trim();
7201
+ }
7202
+ function descriptionIn(block) {
7203
+ const at = block.findIndex((line) => DESCRIPTION_LINE.test(line));
7204
+ if (at === -1)
7205
+ return null;
7206
+ const value = (block[at]?.match(DESCRIPTION_LINE)?.[1] ?? "").trimEnd();
7207
+ const joiner = blockJoiner(value);
7208
+ const text = joiner === undefined ? unquote(value).trim() : blockScalar(block.slice(at + 1), joiner);
7209
+ return text === "" ? null : text;
7210
+ }
7211
+ async function descriptionOf(abs) {
7212
+ const size = await stat(abs).then((s) => s.size, () => null);
7213
+ if (size === null || size > MAX_DOC_BYTES)
7214
+ return null;
7215
+ let content;
7216
+ try {
7217
+ content = await readFile2(abs, "utf-8");
7218
+ } catch {
7219
+ return null;
7220
+ }
7221
+ const block = frontmatterLines(content);
7222
+ return block === null ? null : descriptionIn(block);
7223
+ }
7224
+ async function readDescriptionUnder(root, relative) {
7225
+ const abs = await containedFile(root, relative);
7226
+ return abs === null ? null : descriptionOf(abs);
7227
+ }
7228
+
7229
+ // src/adapters/claude/skills.ts
7230
+ var SKILL_FILE = "SKILL.md";
7231
+ async function skillNamesUnder(root) {
7232
+ let names;
7233
+ try {
7234
+ names = await readdir(root);
7235
+ } catch {
7236
+ return [];
7237
+ }
7238
+ const found = await Promise.all(names.map((name) => hasSkillFile(join3(root, name))));
7239
+ return names.filter((_, i) => found[i]).sort();
7240
+ }
7241
+ async function hasSkillFile(dir) {
7242
+ try {
7243
+ await access(join3(dir, SKILL_FILE));
7244
+ return true;
7245
+ } catch {
7246
+ return false;
7247
+ }
7248
+ }
7249
+ function settingsLayers(cwd) {
7250
+ const userDir = claudeConfigDir();
7251
+ return [
7252
+ userSettingsFile(),
7253
+ join3(userDir, "settings.local.json"),
7254
+ join3(cwd, ".claude", "settings.json"),
7255
+ join3(cwd, ".claude", "settings.local.json")
7256
+ ];
7257
+ }
7258
+ var userSkillsRoot = () => join3(claudeConfigDir(), "skills");
7259
+ var projectSkillsRoot = (cwd) => join3(cwd, ".claude", "skills");
7260
+ var pluginSkillsRoot = (install) => join3(install, "skills");
7261
+ async function enabledPluginKeys(cwd) {
7262
+ const layers = await Promise.all(settingsLayers(cwd).map((path) => readJsonFile(path)));
7263
+ const merged = {};
7264
+ for (const layer of layers)
7265
+ Object.assign(merged, layer?.enabledPlugins ?? {});
7266
+ return new Set(Object.keys(merged).filter((key) => merged[key] === true));
7267
+ }
7268
+ function pickInstallPath(installs, cwd) {
7269
+ const usable = installs.filter((install) => typeof install.installPath === "string");
7270
+ const here = usable.find((install) => install.projectPath === cwd);
7271
+ const anywhere = usable.find((install) => install.scope === "user" || install.scope === "managed");
7272
+ return (here ?? anywhere ?? usable[0])?.installPath;
7273
+ }
7274
+ async function enabledPlugins(cwd) {
7275
+ const [registry, enabled] = await Promise.all([
7276
+ readJsonFile(installedPluginsFile()),
7277
+ enabledPluginKeys(cwd)
7278
+ ]);
7279
+ const out = [];
7280
+ for (const [key, installs] of Object.entries(registry?.plugins ?? {})) {
7281
+ if (!enabled.has(key))
7282
+ continue;
7283
+ const installPath = pickInstallPath(installs ?? [], cwd);
7284
+ if (installPath === undefined)
7285
+ continue;
7286
+ out.push([key.split("@")[0] ?? key, installPath]);
7287
+ }
7288
+ return out.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
7289
+ }
7290
+ async function readClaudeSkills(cwd) {
7291
+ const [user, project, plugins] = await Promise.all([
7292
+ skillNamesUnder(userSkillsRoot()),
7293
+ skillNamesUnder(projectSkillsRoot(cwd)),
7294
+ enabledPlugins(cwd)
7295
+ ]);
7296
+ const pluginSkills = await Promise.all(plugins.map(async ([plugin, dir]) => (await skillNamesUnder(pluginSkillsRoot(dir))).map((name) => ({ name: `${plugin}:${name}`, origin: "plugin" }))));
7297
+ return [
7298
+ ...user.map((name) => ({ name, origin: "user" })),
7299
+ ...project.map((name) => ({ name, origin: "project" })),
7300
+ ...pluginSkills.flat()
7301
+ ];
7302
+ }
7303
+ async function skillDocLocation(cwd, skill) {
7304
+ const under = (root, name) => ({ root, relative: join3(name, SKILL_FILE) });
7305
+ if (skill.origin === "user")
7306
+ return under(userSkillsRoot(), skill.name);
7307
+ if (skill.origin === "project")
7308
+ return under(projectSkillsRoot(cwd), skill.name);
7309
+ if (skill.origin !== "plugin")
7310
+ return null;
7311
+ const at = skill.name.indexOf(":");
7312
+ if (at === -1)
7313
+ return null;
7314
+ const plugin = skill.name.slice(0, at);
7315
+ const hit = (await enabledPlugins(cwd)).find(([key]) => key === plugin);
7316
+ return hit === undefined ? null : under(pluginSkillsRoot(hit[1]), skill.name.slice(at + 1));
7317
+ }
7318
+ async function readClaudeSkillDescription(cwd, skill) {
7319
+ const at = await skillDocLocation(cwd, skill);
7320
+ return at === null ? null : readDescriptionUnder(at.root, at.relative);
7321
+ }
7322
+
7144
7323
  // src/adapters/claude/index.ts
7145
7324
  function toolInputEcho(input) {
7146
7325
  if (!input)
@@ -7177,6 +7356,12 @@ var claudeAdapter = {
7177
7356
  },
7178
7357
  readInstallState() {
7179
7358
  return readClaudeInstallState();
7359
+ },
7360
+ listSkills(cwd) {
7361
+ return readClaudeSkills(cwd);
7362
+ },
7363
+ readSkillDescription(cwd, skill) {
7364
+ return readClaudeSkillDescription(cwd, skill);
7180
7365
  }
7181
7366
  };
7182
7367
 
@@ -7214,7 +7399,7 @@ function fatalDenyLine2(reason) {
7214
7399
  // src/adapters/codex/install.ts
7215
7400
  import { readFileSync as readFileSync2 } from "fs";
7216
7401
  import { homedir as homedir2 } from "os";
7217
- import { join as join2 } from "path";
7402
+ import { join as join4 } from "path";
7218
7403
 
7219
7404
  // node_modules/.bun/smol-toml@1.8.0/node_modules/smol-toml/dist/date.js
7220
7405
  /*!
@@ -7468,7 +7653,7 @@ function skipVoid(ctx, banNewLines, banComments) {
7468
7653
  skipComment(ctx);
7469
7654
  }
7470
7655
  }
7471
- function skipUntil(ctx, sep, end) {
7656
+ function skipUntil(ctx, sep2, end) {
7472
7657
  let ptr = ctx.p;
7473
7658
  if (!end) {
7474
7659
  ptr = indexOfNewline(ctx.s, ptr);
@@ -7479,7 +7664,7 @@ function skipUntil(ctx, sep, end) {
7479
7664
  let c = ctx.s.charCodeAt(ctx.p);
7480
7665
  if (c === 35) {
7481
7666
  skipComment(ctx);
7482
- } else if (c === end || c === sep) {
7667
+ } else if (c === end || c === sep2) {
7483
7668
  return;
7484
7669
  }
7485
7670
  }
@@ -8095,14 +8280,14 @@ function parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
8095
8280
 
8096
8281
  // src/adapters/codex/install.ts
8097
8282
  function codexConfigDir() {
8098
- return process.env.CODEX_HOME || join2(homedir2(), ".codex");
8283
+ return process.env.CODEX_HOME || join4(homedir2(), ".codex");
8099
8284
  }
8100
8285
  function readCodexInstallState() {
8101
8286
  const dir = codexConfigDir();
8102
8287
  return {
8103
8288
  pluginVersion: "unknown",
8104
- pluginEnabled: readCodexHooksFeature(join2(dir, "config.toml")),
8105
- hookInUserSettings: readHookInUserSettings2(join2(dir, "hooks.json"))
8289
+ pluginEnabled: readCodexHooksFeature(join4(dir, "config.toml")),
8290
+ hookInUserSettings: readHookInUserSettings2(join4(dir, "hooks.json"))
8106
8291
  };
8107
8292
  }
8108
8293
  function readCodexHooksFeature(path) {
@@ -8158,6 +8343,12 @@ var codexAdapter = {
8158
8343
  },
8159
8344
  readInstallState() {
8160
8345
  return readCodexInstallState();
8346
+ },
8347
+ listSkills() {
8348
+ return Promise.resolve([]);
8349
+ },
8350
+ readSkillDescription() {
8351
+ return Promise.resolve(null);
8161
8352
  }
8162
8353
  };
8163
8354
 
@@ -8180,7 +8371,7 @@ function fatalDenyLine3(reason) {
8180
8371
 
8181
8372
  // src/adapters/opencode/install.ts
8182
8373
  import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
8183
- import { join as join5 } from "path";
8374
+ import { join as join7 } from "path";
8184
8375
 
8185
8376
  // node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
8186
8377
  function createScanner(text, ignoreTrivia = false) {
@@ -8962,11 +9153,11 @@ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
8962
9153
  onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
8963
9154
  ensurePropertyComplete(offset + length);
8964
9155
  },
8965
- onSeparator: (sep, offset, length) => {
9156
+ onSeparator: (sep2, offset, length) => {
8966
9157
  if (currentParent.type === "property") {
8967
- if (sep === ":") {
9158
+ if (sep2 === ":") {
8968
9159
  currentParent.colonOffset = offset;
8969
- } else if (sep === ",") {
9160
+ } else if (sep2 === ",") {
8970
9161
  ensurePropertyComplete(offset);
8971
9162
  }
8972
9163
  }
@@ -9508,7 +9699,7 @@ function applyEdits(text, edits) {
9508
9699
  // src/adapters/opencode/paths.ts
9509
9700
  import { existsSync, readdirSync } from "fs";
9510
9701
  import { homedir as homedir3 } from "os";
9511
- import { basename, dirname, join as join3 } from "path";
9702
+ import { basename, dirname, join as join5 } from "path";
9512
9703
  var CARET_PACKAGE = "@macintacos/caret";
9513
9704
  function localPluginSpecifier(repoDir) {
9514
9705
  return `file:${repoDir}`;
@@ -9530,39 +9721,42 @@ function opencodeConfigDir() {
9530
9721
  if (override)
9531
9722
  return override;
9532
9723
  const xdg = process.env.XDG_CONFIG_HOME?.trim();
9533
- return join3(xdg || join3(homedir3(), ".config"), "opencode");
9724
+ return join5(xdg || join5(homedir3(), ".config"), "opencode");
9534
9725
  }
9535
9726
  function resolveConfigFile(configDir) {
9536
9727
  for (const name of CONFIG_FILENAMES) {
9537
- const p = join3(configDir, name);
9728
+ const p = join5(configDir, name);
9538
9729
  if (existsSync(p))
9539
9730
  return p;
9540
9731
  }
9541
- return join3(configDir, "opencode.json");
9732
+ return join5(configDir, "opencode.json");
9542
9733
  }
9543
9734
  function commandDir(configDir) {
9544
- return join3(configDir, COMMAND_DIRNAME);
9735
+ return join5(configDir, COMMAND_DIRNAME);
9736
+ }
9737
+ function commandDirs(configDir) {
9738
+ return [commandDir(configDir), join5(configDir, LEGACY_COMMAND_DIRNAME)];
9545
9739
  }
9546
9740
  var LEGACY_PLUGIN_FILENAME = "caret.ts";
9547
9741
  var LEGACY_PLUGIN_DIRNAMES = ["plugins", "plugin"];
9548
9742
  var LEGACY_COMMAND_DIRNAME = "command";
9549
9743
  function existingLegacyInstallFiles(configDir) {
9550
- const plugins = LEGACY_PLUGIN_DIRNAMES.map((d) => join3(configDir, d, LEGACY_PLUGIN_FILENAME));
9744
+ const plugins = LEGACY_PLUGIN_DIRNAMES.map((d) => join5(configDir, d, LEGACY_PLUGIN_FILENAME));
9551
9745
  let entries;
9552
9746
  try {
9553
- entries = readdirSync(join3(configDir, LEGACY_COMMAND_DIRNAME), { withFileTypes: true });
9747
+ entries = readdirSync(join5(configDir, LEGACY_COMMAND_DIRNAME), { withFileTypes: true });
9554
9748
  } catch {
9555
9749
  entries = [];
9556
9750
  }
9557
- const commands = entries.filter((e) => !e.isDirectory() && e.name.startsWith(COMMAND_NAMESPACE)).filter((e) => e.name.endsWith(".md")).map((e) => join3(configDir, LEGACY_COMMAND_DIRNAME, e.name)).sort();
9751
+ const commands = entries.filter((e) => !e.isDirectory() && e.name.startsWith(COMMAND_NAMESPACE)).filter((e) => e.name.endsWith(".md")).map((e) => join5(configDir, LEGACY_COMMAND_DIRNAME, e.name)).sort();
9558
9752
  return [...plugins, ...commands].filter((p) => existsSync(p));
9559
9753
  }
9560
9754
  function opencodeCachePackagesDir() {
9561
9755
  const xdg = process.env.XDG_CACHE_HOME?.trim();
9562
- return join3(xdg || join3(homedir3(), ".cache"), "opencode", "packages");
9756
+ return join5(xdg || join5(homedir3(), ".cache"), "opencode", "packages");
9563
9757
  }
9564
9758
  function opencodeCachePackageDir(pkg = CARET_PACKAGE) {
9565
- return join3(opencodeCachePackagesDir(), pkg);
9759
+ return join5(opencodeCachePackagesDir(), pkg);
9566
9760
  }
9567
9761
  function existingOpencodeCachePackageDirs(pkg = CARET_PACKAGE) {
9568
9762
  const bare = opencodeCachePackageDir(pkg);
@@ -9575,12 +9769,12 @@ function existingOpencodeCachePackageDirs(pkg = CARET_PACKAGE) {
9575
9769
  return [];
9576
9770
  }
9577
9771
  const pinned = names.filter((n) => n.startsWith(`${leaf}@`)).sort();
9578
- return [...names.includes(leaf) ? [bare] : [], ...pinned.map((n) => join3(parent, n))];
9772
+ return [...names.includes(leaf) ? [bare] : [], ...pinned.map((n) => join5(parent, n))];
9579
9773
  }
9580
9774
 
9581
9775
  // src/adapters/opencode/upgrade.ts
9582
9776
  import { existsSync as existsSync2, readFileSync as readFileSync3, rmSync } from "fs";
9583
- import { join as join4 } from "path";
9777
+ import { join as join6 } from "path";
9584
9778
 
9585
9779
  // src/adapters/opencode/config-plugin.ts
9586
9780
  var FORMATTING = { insertSpaces: true, tabSize: 2 };
@@ -9691,7 +9885,7 @@ function upgradeVerdict(input) {
9691
9885
  function readCachedCaretVersion(dirs = existingOpencodeCachePackageDirs()) {
9692
9886
  for (const d of dirs) {
9693
9887
  try {
9694
- const deps = JSON.parse(readFileSync3(join4(d, "package.json"), "utf-8")).dependencies;
9888
+ const deps = JSON.parse(readFileSync3(join6(d, "package.json"), "utf-8")).dependencies;
9695
9889
  const v = deps?.[CARET_PACKAGE];
9696
9890
  if (typeof v === "string" && v.length > 0)
9697
9891
  return v;
@@ -9738,7 +9932,7 @@ function readOpencodeInstallState() {
9738
9932
  function readCaretInPluginArray(dir) {
9739
9933
  let sawConfig = false;
9740
9934
  for (const name of CONFIG_FILENAMES) {
9741
- const path = join5(dir, name);
9935
+ const path = join7(dir, name);
9742
9936
  if (!existsSync3(path))
9743
9937
  continue;
9744
9938
  let cfg;
@@ -9758,6 +9952,33 @@ function readCaretInPluginArray(dir) {
9758
9952
  return sawConfig ? false : "unknown";
9759
9953
  }
9760
9954
 
9955
+ // src/adapters/opencode/skills.ts
9956
+ import { readdir as readdir2 } from "fs/promises";
9957
+ import { sep as sep2 } from "path";
9958
+ async function commandNamesUnder(dir) {
9959
+ let entries;
9960
+ try {
9961
+ entries = await readdir2(dir, { recursive: true });
9962
+ } catch {
9963
+ return [];
9964
+ }
9965
+ return entries.filter((rel) => rel.endsWith(".md")).map((rel) => rel.slice(0, -".md".length).split(sep2).join("/"));
9966
+ }
9967
+ async function readOpencodeCommands() {
9968
+ const perDir = await Promise.all(commandDirs(opencodeConfigDir()).map(commandNamesUnder));
9969
+ const names = new Set(perDir.flat());
9970
+ return [...names].sort().map((name) => ({ name, origin: "command" }));
9971
+ }
9972
+ async function readOpencodeCommandDescription(name) {
9973
+ const relative = `${name}.md`;
9974
+ for (const dir of commandDirs(opencodeConfigDir())) {
9975
+ const abs = await containedFile(dir, relative);
9976
+ if (abs !== null)
9977
+ return descriptionOf(abs);
9978
+ }
9979
+ return null;
9980
+ }
9981
+
9761
9982
  // src/adapters/opencode/index.ts
9762
9983
  var opencodeAdapter = {
9763
9984
  id: "opencode",
@@ -9784,6 +10005,12 @@ var opencodeAdapter = {
9784
10005
  },
9785
10006
  readInstallState() {
9786
10007
  return readOpencodeInstallState();
10008
+ },
10009
+ listSkills() {
10010
+ return readOpencodeCommands();
10011
+ },
10012
+ readSkillDescription(_cwd, skill) {
10013
+ return readOpencodeCommandDescription(skill.name);
9787
10014
  }
9788
10015
  };
9789
10016
 
@@ -24254,7 +24481,7 @@ import { createHash } from "crypto";
24254
24481
 
24255
24482
  // src/ui/assets.ts
24256
24483
  import { readdirSync as readdirSync2 } from "fs";
24257
- import { dirname as dirname2, join as join6, relative } from "path";
24484
+ import { dirname as dirname2, join as join8, relative } from "path";
24258
24485
  import { fileURLToPath } from "url";
24259
24486
  function fromPathMap(map2) {
24260
24487
  const paths = Object.keys(map2).sort();
@@ -24270,7 +24497,7 @@ function assetsFromDist(distDir) {
24270
24497
  const map2 = {};
24271
24498
  const walk = (dir) => {
24272
24499
  for (const ent of readdirSync2(dir, { withFileTypes: true })) {
24273
- const full = join6(dir, ent.name);
24500
+ const full = join8(dir, ent.name);
24274
24501
  if (ent.isDirectory())
24275
24502
  walk(full);
24276
24503
  else if (ent.isFile())
@@ -24302,13 +24529,13 @@ async function loadUiAssets() {
24302
24529
  if (fromDist)
24303
24530
  return fromDist;
24304
24531
  }
24305
- const besideDist = join6(dirname2(process.execPath), "ui");
24532
+ const besideDist = join8(dirname2(process.execPath), "ui");
24306
24533
  return assetsFromDist(besideDist);
24307
24534
  }
24308
24535
  // package.json
24309
24536
  var package_default = {
24310
24537
  name: "@macintacos/caret",
24311
- version: "0.11.1",
24538
+ version: "0.13.0",
24312
24539
  license: "MIT",
24313
24540
  type: "module",
24314
24541
  description: "A Claude Code plugin that replaces the terminal plan-approval prompt with a local web UI for inline review, annotation, and approval.",
@@ -24344,6 +24571,7 @@ var package_default = {
24344
24571
  },
24345
24572
  devDependencies: {
24346
24573
  "@clack/prompts": "^1.7.0",
24574
+ "@codemirror/autocomplete": "^6.20.3",
24347
24575
  "@codemirror/commands": "^6.10.3",
24348
24576
  "@codemirror/lang-markdown": "^6.5.0",
24349
24577
  "@codemirror/language": "^6.12.3",
@@ -24366,6 +24594,7 @@ var package_default = {
24366
24594
  "bits-ui": "^2.18.1",
24367
24595
  clsx: "^2.1.1",
24368
24596
  commander: "^15.0.0",
24597
+ cuelume: "^0.2.2",
24369
24598
  "happy-dom": "^20.11.2",
24370
24599
  "jsonc-parser": "^3.3.1",
24371
24600
  listr2: "^11.0.0",
@@ -25200,9 +25429,11 @@ function openDaemonStderr(s) {
25200
25429
  return "ignore";
25201
25430
  }
25202
25431
  }
25203
- function spawnDaemon(s) {
25432
+ var DAEMON_CWD = "/";
25433
+ function spawnDaemon(s, spawn = Bun.spawn) {
25204
25434
  const out = openDaemonStderr(s);
25205
- Bun.spawn(daemonCommand(), {
25435
+ spawn(daemonCommand(), {
25436
+ cwd: DAEMON_CWD,
25206
25437
  stdio: ["ignore", out, out],
25207
25438
  detached: true,
25208
25439
  env: process.env
@@ -25235,12 +25466,12 @@ import { renameSync as renameSync3, unlinkSync as unlinkSync3, writeFileSync as
25235
25466
  import { dirname as dirname6 } from "path";
25236
25467
 
25237
25468
  // src/config/prefs.ts
25238
- import { readFile as readFile2, writeFile } from "fs/promises";
25469
+ import { readFile as readFile3, writeFile } from "fs/promises";
25239
25470
  import { dirname as dirname4 } from "path";
25240
25471
  var DEFAULT_SET = { valid: ["default"], fallback: "default" };
25241
25472
  async function readApproveMode(file2 = prefsFile(), log = noopLogger, set2 = DEFAULT_SET) {
25242
25473
  try {
25243
- const parsed = JSON.parse(await readFile2(file2, "utf-8"));
25474
+ const parsed = JSON.parse(await readFile3(file2, "utf-8"));
25244
25475
  if (typeof parsed.approveMode === "string" && set2.valid.includes(parsed.approveMode)) {
25245
25476
  return parsed.approveMode;
25246
25477
  }
@@ -25298,6 +25529,7 @@ var PlanInputSchema = exports_external.object({
25298
25529
  }).catch({});
25299
25530
  var MAX_FILE_REFS = 1000;
25300
25531
  var FileRefsBodySchema = exports_external.object({ paths: exports_external.array(exports_external.string()).catch([]) }).catch({ paths: [] });
25532
+ var FileSearchBodySchema = exports_external.object({ query: exports_external.string().catch("") }).catch({ query: "" });
25301
25533
  var BehaviorSchema = exports_external.enum(["allow", "deny"]);
25302
25534
  var ResolveBodySchema = exports_external.object({
25303
25535
  behavior: BehaviorSchema.catch("allow"),
@@ -25386,13 +25618,13 @@ function markPaneRead(pane, deps = {}) {
25386
25618
  }
25387
25619
 
25388
25620
  // src/plan/directory.ts
25389
- import { readdir as readdir2 } from "fs/promises";
25390
- import { join as join8, relative as relative3, sep as sep2 } from "path";
25621
+ import { readdir as readdir4 } from "fs/promises";
25622
+ import { join as join10, relative as relative3, sep as sep4 } from "path";
25391
25623
 
25392
25624
  // src/plan/excerpt.ts
25393
25625
  import { readFileSync as readFileSync8 } from "fs";
25394
- import { readdir, realpath, stat } from "fs/promises";
25395
- import { extname, isAbsolute, join as join7, relative as relative2, resolve, sep } from "path";
25626
+ import { readdir as readdir3, realpath as realpath2, stat as stat2 } from "fs/promises";
25627
+ import { extname, isAbsolute, join as join9, relative as relative2, resolve, sep as sep3 } from "path";
25396
25628
  var EXCERPT_HEAD_LINES = 60;
25397
25629
  var MAX_EXCERPT_BYTES = 10 * 1024 * 1024;
25398
25630
  var MAX_SCAN_ENTRIES = 5000;
@@ -25448,16 +25680,16 @@ function languageForPath(path) {
25448
25680
  return EXT_LANGUAGE[extname(path).toLowerCase()] ?? "text";
25449
25681
  }
25450
25682
  function safeRealpath(path) {
25451
- return realpath(path).catch(() => null);
25683
+ return realpath2(path).catch(() => null);
25452
25684
  }
25453
25685
  function safeStat(path) {
25454
- return stat(path).catch(() => null);
25686
+ return stat2(path).catch(() => null);
25455
25687
  }
25456
25688
  async function contained(cwdReal, abs) {
25457
25689
  const real = await safeRealpath(abs);
25458
25690
  if (real === null)
25459
25691
  return null;
25460
- if (real !== cwdReal && !real.startsWith(cwdReal + sep))
25692
+ if (real !== cwdReal && !real.startsWith(cwdReal + sep3))
25461
25693
  return null;
25462
25694
  const stats = await safeStat(real);
25463
25695
  if (stats === null)
@@ -25473,7 +25705,7 @@ async function basenameSearch(cwdReal, name) {
25473
25705
  const currentDir = queue.shift();
25474
25706
  let entries;
25475
25707
  try {
25476
- entries = await readdir(currentDir, { withFileTypes: true });
25708
+ entries = await readdir3(currentDir, { withFileTypes: true });
25477
25709
  } catch {
25478
25710
  continue;
25479
25711
  }
@@ -25482,9 +25714,9 @@ async function basenameSearch(cwdReal, name) {
25482
25714
  return null;
25483
25715
  if (entry.isFile()) {
25484
25716
  if (entry.name === name)
25485
- return join7(currentDir, entry.name);
25717
+ return join9(currentDir, entry.name);
25486
25718
  } else if (entry.isDirectory() && !SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
25487
- queue.push(join7(currentDir, entry.name));
25719
+ queue.push(join9(currentDir, entry.name));
25488
25720
  }
25489
25721
  }
25490
25722
  }
@@ -25596,13 +25828,13 @@ async function listDirectory(cwd, root, path) {
25596
25828
  if (target === null || target.kind !== "directory")
25597
25829
  return null;
25598
25830
  const rel = relative3(rootHit.path, target.path);
25599
- if (rel === ".." || rel.startsWith(`..${sep2}`))
25831
+ if (rel === ".." || rel.startsWith(`..${sep4}`))
25600
25832
  return null;
25601
- if (rel !== "" && rel.split(sep2).length > MAX_DIR_DEPTH)
25833
+ if (rel !== "" && rel.split(sep4).length > MAX_DIR_DEPTH)
25602
25834
  return null;
25603
25835
  let dirents;
25604
25836
  try {
25605
- dirents = await readdir2(target.path, { withFileTypes: true });
25837
+ dirents = await readdir4(target.path, { withFileTypes: true });
25606
25838
  } catch {
25607
25839
  return null;
25608
25840
  }
@@ -25616,7 +25848,7 @@ async function listDirectory(cwd, root, path) {
25616
25848
  else if (d.isSymbolicLink())
25617
25849
  links.push(d);
25618
25850
  }
25619
- const targets = await Promise.all(links.map((d) => resolveInCwd(cwd, join8(target.path, d.name))));
25851
+ const targets = await Promise.all(links.map((d) => resolveInCwd(cwd, join10(target.path, d.name))));
25620
25852
  targets.forEach((hit, i) => {
25621
25853
  const link = links[i];
25622
25854
  if (hit !== null && link !== undefined)
@@ -25631,6 +25863,78 @@ async function listDirectory(cwd, root, path) {
25631
25863
  };
25632
25864
  }
25633
25865
 
25866
+ // src/plan/file-search.ts
25867
+ import { readdir as readdir5 } from "fs/promises";
25868
+ import { isAbsolute as isAbsolute2, join as join11 } from "path";
25869
+ var SEARCH_BUDGET = { dirents: 20000, results: 50 };
25870
+ var MAX_SEARCH_QUERY_CHARS = 128;
25871
+ function subsequence(haystack, needle) {
25872
+ let i = 0;
25873
+ for (let h = 0;h < haystack.length && i < needle.length; h++) {
25874
+ if (haystack[h] === needle[i])
25875
+ i++;
25876
+ }
25877
+ return i === needle.length;
25878
+ }
25879
+ function relPath(dir, name) {
25880
+ return dir === "" ? name : `${dir}/${name}`;
25881
+ }
25882
+ function partition(dirents, allowance) {
25883
+ const files = [];
25884
+ const dirs = [];
25885
+ let scanned = 0;
25886
+ for (const entry of dirents) {
25887
+ if (scanned >= allowance)
25888
+ return { files, dirs, scanned, cut: true };
25889
+ scanned++;
25890
+ if (entry.name === ".git")
25891
+ continue;
25892
+ if (entry.isFile())
25893
+ files.push(entry.name);
25894
+ else if (entry.isDirectory() && !SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
25895
+ dirs.push(entry.name);
25896
+ }
25897
+ }
25898
+ files.sort();
25899
+ dirs.sort();
25900
+ return { files, dirs, scanned, cut: false };
25901
+ }
25902
+ async function searchFiles(cwd, query, budget = SEARCH_BUDGET) {
25903
+ if (cwd === "" || !isAbsolute2(cwd))
25904
+ return null;
25905
+ const cwdReal = await safeRealpath(cwd);
25906
+ if (cwdReal === null)
25907
+ return null;
25908
+ const needle = query.slice(0, MAX_SEARCH_QUERY_CHARS).toLowerCase();
25909
+ const paths = [];
25910
+ const queue = [""];
25911
+ let scanned = 0;
25912
+ while (queue.length > 0) {
25913
+ const rel = queue.shift();
25914
+ let dirents;
25915
+ try {
25916
+ dirents = await readdir5(join11(cwdReal, rel), { withFileTypes: true });
25917
+ } catch {
25918
+ continue;
25919
+ }
25920
+ const level = partition(dirents, budget.dirents - scanned);
25921
+ scanned += level.scanned;
25922
+ if (level.cut)
25923
+ return { paths, stoppedAt: "scan" };
25924
+ for (const name of level.files) {
25925
+ const path = relPath(rel, name);
25926
+ if (!subsequence(path.toLowerCase(), needle))
25927
+ continue;
25928
+ if (paths.length === budget.results)
25929
+ return { paths, stoppedAt: "results" };
25930
+ paths.push(path);
25931
+ }
25932
+ for (const name of level.dirs)
25933
+ queue.push(relPath(rel, name));
25934
+ }
25935
+ return { paths, stoppedAt: null };
25936
+ }
25937
+
25634
25938
  // src/review/decisions.ts
25635
25939
  function createDecisions(log = noopLogger) {
25636
25940
  const pending = new Map;
@@ -25707,7 +26011,7 @@ import { createHash as createHash2 } from "crypto";
25707
26011
  import { chmodSync as chmodSync3, existsSync as existsSync6, mkdirSync as mkdirSync2, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "fs";
25708
26012
  import { mkdtemp, rm } from "fs/promises";
25709
26013
  import { tmpdir } from "os";
25710
- import { dirname as dirname5, join as join9 } from "path";
26014
+ import { dirname as dirname5, join as join12 } from "path";
25711
26015
  var RUMDL_VERSION = "0.2.54";
25712
26016
  var ASSETS = {
25713
26017
  "darwin-arm64": {
@@ -25750,14 +26054,14 @@ async function downloadRumdl(binPath, asset, fetchImpl = fetch) {
25750
26054
  if (actual !== asset.sha256) {
25751
26055
  throw new Error(`rumdl: checksum mismatch for ${asset.url} (expected ${asset.sha256}, got ${actual})`);
25752
26056
  }
25753
- const work = await mkdtemp(join9(tmpdir(), "caret-rumdl-"));
26057
+ const work = await mkdtemp(join12(tmpdir(), "caret-rumdl-"));
25754
26058
  try {
25755
- const archive = join9(work, "rumdl.tar.gz");
26059
+ const archive = join12(work, "rumdl.tar.gz");
25756
26060
  await Bun.write(archive, bytes);
25757
26061
  const tar = Bun.spawn(["tar", "-xzf", archive, "-C", work], { stderr: "pipe" });
25758
26062
  if (await tar.exited !== 0)
25759
26063
  throw new Error(`rumdl: failed to extract ${asset.url}`);
25760
- const extracted = join9(work, "rumdl");
26064
+ const extracted = join12(work, "rumdl");
25761
26065
  if (!existsSync6(extracted))
25762
26066
  throw new Error(`rumdl: binary not found in ${asset.url}`);
25763
26067
  mkdirSync2(dirname5(binPath), { recursive: true });
@@ -25784,8 +26088,9 @@ async function installedVersion(bin) {
25784
26088
  return null;
25785
26089
  }
25786
26090
  }
25787
- var inFlightInstall;
25788
- async function ensureRumdl(install = installPinnedRumdl) {
26091
+ var RUMDL_RETRY_COOLDOWN_MS = 10 * 60000;
26092
+ var acquisition = { cooldownUntil: 0 };
26093
+ async function ensureRumdl(install = installPinnedRumdl, now = Date.now, state = acquisition) {
25789
26094
  ensureStateDir(rumdlDir());
25790
26095
  const config2 = rumdlConfig();
25791
26096
  writeFileSync4(config2, RUMDL_CONFIG);
@@ -25796,10 +26101,19 @@ async function ensureRumdl(install = installPinnedRumdl) {
25796
26101
  const bin = rumdlBin();
25797
26102
  if (await installedVersion(bin) === RUMDL_VERSION)
25798
26103
  return { bin, config: config2, installed: false };
25799
- inFlightInstall ??= install(bin).finally(() => {
25800
- inFlightInstall = undefined;
25801
- });
25802
- return { bin: await inFlightInstall, config: config2, installed: true };
26104
+ if (now() < state.cooldownUntil) {
26105
+ throw new Error("rumdl: install on cooldown after a recent failure");
26106
+ }
26107
+ if (!state.inFlight) {
26108
+ state.inFlight = install(bin).catch((err) => {
26109
+ state.cooldownUntil = now() + RUMDL_RETRY_COOLDOWN_MS;
26110
+ throw err;
26111
+ }).finally(() => {
26112
+ state.inFlight = undefined;
26113
+ });
26114
+ }
26115
+ const pending = state.inFlight;
26116
+ return { bin: await pending, config: config2, installed: true };
25803
26117
  }
25804
26118
  async function rumdlFormatPlan(text) {
25805
26119
  if (text.trim() === "")
@@ -25821,7 +26135,8 @@ async function rumdlFormatPlan(text) {
25821
26135
 
25822
26136
  // src/plan/markdown.ts
25823
26137
  var MAX_FORMAT_BYTES = 1024 * 1024;
25824
- async function formatPlanMarkdown(plan, log = noopLogger, doFormat = rumdlFormatPlan) {
26138
+ var FORMAT_BUDGET_MS = 2000;
26139
+ async function formatPlanMarkdown(plan, log = noopLogger, doFormat = rumdlFormatPlan, budgetMs = FORMAT_BUDGET_MS) {
25825
26140
  const bytes = Buffer.byteLength(plan, "utf-8");
25826
26141
  if (bytes > MAX_FORMAT_BYTES) {
25827
26142
  log.warn("review", "plan too large to format, storing raw", {
@@ -25830,13 +26145,19 @@ async function formatPlanMarkdown(plan, log = noopLogger, doFormat = rumdlFormat
25830
26145
  });
25831
26146
  return plan;
25832
26147
  }
26148
+ let timer;
25833
26149
  try {
25834
- return await doFormat(plan);
26150
+ const deadline = new Promise((_, reject) => {
26151
+ timer = setTimeout(() => reject(new Error(`plan format exceeded ${budgetMs}ms`)), budgetMs);
26152
+ });
26153
+ return await Promise.race([doFormat(plan), deadline]);
25835
26154
  } catch (err) {
25836
26155
  const reason = errorMessage(err).split(`
25837
26156
  `, 1)[0] ?? "";
25838
26157
  log.warn("review", "plan format failed, storing raw", { reason });
25839
26158
  return plan;
26159
+ } finally {
26160
+ clearTimeout(timer);
25840
26161
  }
25841
26162
  }
25842
26163
 
@@ -25988,12 +26309,14 @@ function resolveOptions(opts) {
25988
26309
  instanceId: opts.instanceId,
25989
26310
  approveVariants: opts.approveVariants,
25990
26311
  source: opts.source,
26312
+ listSkills: opts.listSkills,
26313
+ readSkillDescription: opts.readSkillDescription,
25991
26314
  diagnostics: opts.diagnostics,
25992
26315
  markPaneRead: opts.markPaneRead ?? ((pane) => markPaneRead(pane, { log: opts.log })),
25993
26316
  log: opts.log ?? noopLogger
25994
26317
  };
25995
26318
  }
25996
- var ID_ROUTE_RE = /^\/api\/reviews\/([^/]+)(\/decision|\/resolve|\/draft|\/expire|\/seen|\/file-refs|\/file|\/dir)?$/;
26319
+ var ID_ROUTE_RE = /^\/api\/reviews\/([^/]+)(\/decision|\/resolve|\/draft|\/expire|\/seen|\/file-refs|\/file-search|\/file|\/dir|\/skills|\/skill-description)?$/;
25997
26320
  function matchIdRoute(path) {
25998
26321
  const m = path.match(ID_ROUTE_RE);
25999
26322
  if (!m)
@@ -26213,6 +26536,45 @@ function createServer(opts) {
26213
26536
  });
26214
26537
  return Response.json(listing);
26215
26538
  }
26539
+ async function handleSkills(id) {
26540
+ if (!cfg.listSkills)
26541
+ return notFound();
26542
+ const r = store.get(id);
26543
+ if (!r)
26544
+ return notFound();
26545
+ const skills = await cfg.listSkills(r.cwd);
26546
+ log.debug("request", "skills listed", { reviewId: id, count: skills.length });
26547
+ return Response.json(skills);
26548
+ }
26549
+ async function handleSkillDescription(req, id) {
26550
+ if (!cfg.readSkillDescription)
26551
+ return notFound();
26552
+ const r = store.get(id);
26553
+ if (!r)
26554
+ return notFound();
26555
+ const params = new URL(req.url).searchParams;
26556
+ const description = await cfg.readSkillDescription(r.cwd, {
26557
+ name: params.get("name") ?? "",
26558
+ origin: params.get("origin") ?? ""
26559
+ });
26560
+ log.debug("request", "skill description read", { reviewId: id, found: description !== null });
26561
+ return Response.json({ description });
26562
+ }
26563
+ async function handleFileSearch(req, id) {
26564
+ const r = store.get(id);
26565
+ if (!r)
26566
+ return notFound();
26567
+ const { query } = await parseBody(req, FileSearchBodySchema);
26568
+ const result = await searchFiles(r.cwd, query);
26569
+ if (result === null)
26570
+ return notFound();
26571
+ log.debug("request", "file search answered", {
26572
+ reviewId: id,
26573
+ returned: result.paths.length,
26574
+ stoppedAt: result.stoppedAt
26575
+ });
26576
+ return Response.json(result);
26577
+ }
26216
26578
  async function handleDecision(id) {
26217
26579
  const inMem = store.get(id);
26218
26580
  if (inMem?.decision) {
@@ -26343,8 +26705,15 @@ function createServer(opts) {
26343
26705
  return handleFileExcerpt(req, id);
26344
26706
  if (method === "GET" && sub === "/dir")
26345
26707
  return handleDirListing(req, id);
26708
+ if (method === "GET" && sub === "/skills")
26709
+ return handleSkills(id);
26710
+ if (method === "GET" && sub === "/skill-description") {
26711
+ return handleSkillDescription(req, id);
26712
+ }
26346
26713
  if (method === "POST" && sub === "/file-refs")
26347
26714
  return handleFileRefs(req, id);
26715
+ if (method === "POST" && sub === "/file-search")
26716
+ return handleFileSearch(req, id);
26348
26717
  if (method === "GET" && sub === "/decision")
26349
26718
  return handleDecision(id);
26350
26719
  if (method === "PUT" && sub === "/draft")
@@ -26436,8 +26805,8 @@ function createServer(opts) {
26436
26805
  }
26437
26806
 
26438
26807
  // src/review/store.ts
26439
- import { readdir as readdir3, readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
26440
- import { join as join10 } from "path";
26808
+ import { readdir as readdir6, readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
26809
+ import { join as join13 } from "path";
26441
26810
  function createStore(dir, log = noopLogger) {
26442
26811
  const reviews = new Map;
26443
26812
  const epochs = new Map;
@@ -26446,7 +26815,7 @@ function createStore(dir, log = noopLogger) {
26446
26815
  const prev = writeChains.get(review.id) ?? Promise.resolve();
26447
26816
  const next = prev.catch(() => {}).then(async () => {
26448
26817
  ensureStateDir(dir);
26449
- await writeFile2(join10(dir, `${review.id}.json`), JSON.stringify(review, null, 2), {
26818
+ await writeFile2(join13(dir, `${review.id}.json`), JSON.stringify(review, null, 2), {
26450
26819
  mode: 384
26451
26820
  });
26452
26821
  log.debug("store", `review persisted: ${shortId(review.id)}`, { reviewId: review.id });
@@ -26496,7 +26865,7 @@ function createStore(dir, log = noopLogger) {
26496
26865
  return review;
26497
26866
  },
26498
26867
  async persisted(id) {
26499
- return await readJsonFile(join10(dir, `${id}.json`)) ?? undefined;
26868
+ return await readJsonFile(join13(dir, `${id}.json`)) ?? undefined;
26500
26869
  },
26501
26870
  size() {
26502
26871
  return reviews.size;
@@ -26513,7 +26882,7 @@ function createStore(dir, log = noopLogger) {
26513
26882
  async rehydrate() {
26514
26883
  let files;
26515
26884
  try {
26516
- files = await readdir3(dir);
26885
+ files = await readdir6(dir);
26517
26886
  } catch {
26518
26887
  log.debug("store", "no reviews dir; nothing to rehydrate");
26519
26888
  return;
@@ -26523,7 +26892,7 @@ function createStore(dir, log = noopLogger) {
26523
26892
  if (!file2.endsWith(".json"))
26524
26893
  continue;
26525
26894
  try {
26526
- const review = JSON.parse(await readFile3(join10(dir, file2), "utf-8"));
26895
+ const review = JSON.parse(await readFile4(join13(dir, file2), "utf-8"));
26527
26896
  if (isUnresolved(review.status)) {
26528
26897
  reviews.set(review.id, review);
26529
26898
  loaded++;
@@ -26569,6 +26938,8 @@ async function runDaemon(opts) {
26569
26938
  instanceId: randomUUID().slice(0, 8),
26570
26939
  approveVariants: adapter.approveVariants,
26571
26940
  source: adapter.id,
26941
+ listSkills: (cwd) => adapter.listSkills(cwd),
26942
+ readSkillDescription: (cwd, skill) => adapter.readSkillDescription(cwd, skill),
26572
26943
  diagnostics: () => buildDiagnostics({
26573
26944
  now: Date.now,
26574
26945
  startedAt,
@@ -26623,7 +26994,7 @@ import { release } from "os";
26623
26994
 
26624
26995
  // src/discovery.ts
26625
26996
  import { readdirSync as readdirSync4, statSync as statSync4 } from "fs";
26626
- import { basename as basename3, join as join11 } from "path";
26997
+ import { basename as basename3, join as join14 } from "path";
26627
26998
  var CARET_BIN = "caret-native";
26628
26999
  async function safe(build) {
26629
27000
  try {
@@ -26834,7 +27205,7 @@ function listReviewFiles() {
26834
27205
  continue;
26835
27206
  if (out.length >= 5000)
26836
27207
  break;
26837
- const raw = readJsonFileSync(join11(dir, file2));
27208
+ const raw = readJsonFileSync(join14(dir, file2));
26838
27209
  if (raw && typeof raw.id === "string" && typeof raw.status === "string") {
26839
27210
  out.push({ id: raw.id, status: raw.status });
26840
27211
  }
@@ -26946,29 +27317,29 @@ import {
26946
27317
  symlinkSync,
26947
27318
  writeFileSync as writeFileSync6
26948
27319
  } from "fs";
26949
- import { join as join13, resolve as resolve2 } from "path";
27320
+ import { join as join16, resolve as resolve2 } from "path";
26950
27321
 
26951
27322
  // src/adapters/opencode/packaging.ts
26952
27323
  import { existsSync as existsSync9, readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
26953
- import { dirname as dirname7, join as join12 } from "path";
27324
+ import { dirname as dirname7, join as join15 } from "path";
26954
27325
  function resolveCaretRoot() {
26955
27326
  const candidates = [];
26956
27327
  const script = process.argv[1];
26957
27328
  if (script)
26958
- candidates.push(join12(dirname7(script), ".."));
26959
- candidates.push(join12(dirname7(process.execPath), ".."));
27329
+ candidates.push(join15(dirname7(script), ".."));
27330
+ candidates.push(join15(dirname7(process.execPath), ".."));
26960
27331
  for (const root of candidates) {
26961
- if (existsSync9(join12(root, "opencode", "caret.plugin.ts")))
27332
+ if (existsSync9(join15(root, "opencode", "caret.plugin.ts")))
26962
27333
  return root;
26963
27334
  }
26964
27335
  throw new Error(`caret OpenCode packaging not found (no opencode/caret.plugin.ts under: ${candidates.join(", ") || "(none)"}). The OpenCode plugin source must ship with caret.`);
26965
27336
  }
26966
27337
  function loadOpencodePackaging(root = resolveCaretRoot()) {
26967
- const binPath = join12(root, "bin", "caret");
26968
- const commandsDir = join12(root, "opencode", "commands");
27338
+ const binPath = join15(root, "bin", "caret");
27339
+ const commandsDir = join15(root, "opencode", "commands");
26969
27340
  let commands = [];
26970
27341
  try {
26971
- commands = readdirSync5(commandsDir).filter((f) => f.endsWith(".md")).sort().map((f) => ({ name: f, contents: readFileSync9(join12(commandsDir, f), "utf-8") }));
27342
+ commands = readdirSync5(commandsDir).filter((f) => f.endsWith(".md")).sort().map((f) => ({ name: f, contents: readFileSync9(join15(commandsDir, f), "utf-8") }));
26972
27343
  } catch {
26973
27344
  commands = [];
26974
27345
  }
@@ -26977,17 +27348,17 @@ function loadOpencodePackaging(root = resolveCaretRoot()) {
26977
27348
 
26978
27349
  // src/commands/install/local.ts
26979
27350
  function devMarketplaceDir() {
26980
- return join13(stateDir(), "dev-marketplace");
27351
+ return join16(stateDir(), "dev-marketplace");
26981
27352
  }
26982
27353
  function resolveLocalCheckout(opts = {}, deps = {}) {
26983
27354
  const repoDir = resolve2(caretRoot(deps));
26984
- if (!existsSync10(join13(repoDir, ".claude-plugin", "marketplace.json"))) {
27355
+ if (!existsSync10(join16(repoDir, ".claude-plugin", "marketplace.json"))) {
26985
27356
  throw new Error(`--from-local must run from a caret checkout (no .claude-plugin/marketplace.json at ${repoDir}). A published caret installs with a plain \`caret install\`.`);
26986
27357
  }
26987
27358
  if (opts.requireArtifacts !== false) {
26988
27359
  const missing = [
26989
- isExecutable(join13(repoDir, "bin", "caret-native")) ? null : "bin/caret-native",
26990
- isDirectory(join13(repoDir, "bin", "ui")) ? null : "bin/ui"
27360
+ isExecutable(join16(repoDir, "bin", "caret-native")) ? null : "bin/caret-native",
27361
+ isDirectory(join16(repoDir, "bin", "ui")) ? null : "bin/ui"
26991
27362
  ].filter((m) => m !== null);
26992
27363
  if (missing.length > 0) {
26993
27364
  throw new Error(`--from-local reuses the build artifacts bin/caret-native + bin/ui, and ${repoDir} is missing ${missing.join(" + ")} \u2014 run \`mise run build\` first.`);
@@ -27006,9 +27377,9 @@ function caretRoot(deps) {
27006
27377
  }
27007
27378
  function writeDevMarketplace(repoDir, outDir) {
27008
27379
  rmSync2(outDir, { recursive: true, force: true });
27009
- mkdirSync3(join13(outDir, ".claude-plugin"), { recursive: true });
27010
- symlinkSync(resolve2(repoDir), join13(outDir, "caret"));
27011
- writeFileSync6(join13(outDir, ".claude-plugin", "marketplace.json"), `${JSON.stringify({
27380
+ mkdirSync3(join16(outDir, ".claude-plugin"), { recursive: true });
27381
+ symlinkSync(resolve2(repoDir), join16(outDir, "caret"));
27382
+ writeFileSync6(join16(outDir, ".claude-plugin", "marketplace.json"), `${JSON.stringify({
27012
27383
  name: "caret",
27013
27384
  description: "Local caret dev build (generated by caret install --from-local).",
27014
27385
  owner: { name: "macintacos" },
@@ -27019,7 +27390,7 @@ function writeDevMarketplace(repoDir, outDir) {
27019
27390
  async function prewarmLocalBuild(repoDir, deps = {}) {
27020
27391
  const spawn = deps.spawn ?? runCaptured;
27021
27392
  try {
27022
- await spawn([join13(repoDir, "bin", "caret-native"), "prewarm"]);
27393
+ await spawn([join16(repoDir, "bin", "caret-native"), "prewarm"]);
27023
27394
  } catch {}
27024
27395
  }
27025
27396
  function isExecutable(path) {
@@ -27294,7 +27665,7 @@ async function runInstallClaudeTarget(opts, deps = {}) {
27294
27665
 
27295
27666
  // src/commands/install/opencode.ts
27296
27667
  import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
27297
- import { basename as basename4, join as join15 } from "path";
27668
+ import { basename as basename4, join as join18 } from "path";
27298
27669
 
27299
27670
  // src/adapters/opencode/deploy.ts
27300
27671
  import { existsSync as existsSync12, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "fs";
@@ -27397,7 +27768,7 @@ async function promptUpgrade(verdict, clack) {
27397
27768
 
27398
27769
  // src/commands/install/opencode.ts
27399
27770
  function isCaretCheckout(dir) {
27400
- return existsSync14(join15(dir, "opencode", "caret.plugin.ts"));
27771
+ return existsSync14(join18(dir, "opencode", "caret.plugin.ts"));
27401
27772
  }
27402
27773
  function caretEntries(text2, isCheckout) {
27403
27774
  return pluginEntries(text2).filter((entry) => {
@@ -27423,7 +27794,7 @@ async function runInstallOpencodeTarget(opts, deps = {}) {
27423
27794
  const ui = deps.ui ?? silentUI;
27424
27795
  const isCheckout = deps.isCheckout ?? isCaretCheckout;
27425
27796
  const configFile2 = resolveConfigFile(dir);
27426
- const commandPaths = pkg.commands.map((c3) => join15(commandDir(dir), namespacedCommandFilename(c3.name)));
27797
+ const commandPaths = pkg.commands.map((c3) => join18(commandDir(dir), namespacedCommandFilename(c3.name)));
27427
27798
  const legacy = existingLegacyInstallFiles(dir);
27428
27799
  const specifier = opts.local ? localPluginSpecifier(opts.local.repoDir) : CARET_PACKAGE;
27429
27800
  if (opts.dryRun) {
@@ -27446,7 +27817,7 @@ async function runInstallOpencodeTarget(opts, deps = {}) {
27446
27817
  await upgradeStep(configFile2, opts, deps, ui);
27447
27818
  await sweepLegacy(legacy, dir, ui);
27448
27819
  const files = pkg.commands.map((c3) => ({
27449
- path: join15(commandDir(dir), namespacedCommandFilename(c3.name)),
27820
+ path: join18(commandDir(dir), namespacedCommandFilename(c3.name)),
27450
27821
  contents: renderPlugin(c3.contents, { version: VERSION, binPath: pkg.binPath })
27451
27822
  }));
27452
27823
  await ui.step("Deploying the /caret:* command files", async () => deployFiles(files, { dryRun: false }), (deployed) => `Deployed ${deployed.paths.length} command file(s) to ${dir}`);
@@ -27610,7 +27981,7 @@ async function rumdlStep(opts, deps, ui) {
27610
27981
  try {
27611
27982
  await ui.step("Installing the rumdl plan formatter", () => (deps.ensureRumdl ?? ensureRumdl)(), ({ bin, installed }) => `rumdl ${RUMDL_VERSION} ${installed ? "installed" : "already present"} at ${bin}`);
27612
27983
  } catch (e) {
27613
- ui.warn(`Could not install rumdl (${errorMessage(e)}) \u2014 caret will retry on your first plan.`);
27984
+ ui.warn(`Could not install rumdl (${errorMessage(e)}) \u2014 plans are stored unformatted until it installs.`);
27614
27985
  }
27615
27986
  }
27616
27987
  function closingLine(targets, opts, local = false) {