@macintacos/caret 0.8.1 → 0.9.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 (98) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +16 -5
  3. package/dist/cli.js +560 -242
  4. package/opencode/caret.plugin.ts +91 -30
  5. package/package.json +1 -1
  6. package/ui/dist/assets/{angular-html-BKAxvPIm.js → angular-html-BOjikgNB.js} +1 -1
  7. package/ui/dist/assets/{angular-ts-BTws7Hd_.js → angular-ts-BjxNvVmD.js} +1 -1
  8. package/ui/dist/assets/{apl-JlctHwEB.js → apl-BkiW4daM.js} +1 -1
  9. package/ui/dist/assets/{astro-db0B6jhI.js → astro-3adpTlIH.js} +1 -1
  10. package/ui/dist/assets/{blade-CeLm7ibc.js → blade-DPTGWOFi.js} +1 -1
  11. package/ui/dist/assets/{c-BiR9gE2S.js → c-Gr6AqmnN.js} +1 -1
  12. package/ui/dist/assets/{cobol-B8bx-sRj.js → cobol-C8hrPk4X.js} +1 -1
  13. package/ui/dist/assets/{coffee-CGdE90Vi.js → coffee-COAUS6hR.js} +1 -1
  14. package/ui/dist/assets/{cpp-DkHVqrL7.js → cpp-DRNHed7s.js} +1 -1
  15. package/ui/dist/assets/{crystal-lJ6f8uow.js → crystal-xGCPBQ2Z.js} +1 -1
  16. package/ui/dist/assets/{css-Cuixf2-q.js → css-g3rqYwXR.js} +1 -1
  17. package/ui/dist/assets/{dist-C0wLz8-w.js → dist--Ppdbw_u.js} +1 -1
  18. package/ui/dist/assets/{dist-BeZiUXBO.js → dist-ALQWrgOU.js} +1 -1
  19. package/ui/dist/assets/{dist-7sSi10pU.js → dist-B0fJR4WS.js} +1 -1
  20. package/ui/dist/assets/{dist-BJ5lZ2OR.js → dist-B3rxpa4n.js} +1 -1
  21. package/ui/dist/assets/{dist-sZOQfyQ_.js → dist-B57N0_ad.js} +1 -1
  22. package/ui/dist/assets/{dist-DSqn_Y_F.js → dist-B8chzuGI.js} +1 -1
  23. package/ui/dist/assets/{dist-FJ3OQ5zZ.js → dist-Baejo1Q0.js} +1 -1
  24. package/ui/dist/assets/{dist-CYAIY__V.js → dist-BeBmdH90.js} +1 -1
  25. package/ui/dist/assets/{dist-ClyhZj-J.js → dist-BtEZoKjT.js} +1 -1
  26. package/ui/dist/assets/{dist-D80FK4KE.js → dist-CbLm1gmp.js} +1 -1
  27. package/ui/dist/assets/{dist-hZtmZorK.js → dist-CqeZRBk3.js} +1 -1
  28. package/ui/dist/assets/{dist-CRGmZgdx.js → dist-D55VuegY.js} +1 -1
  29. package/ui/dist/assets/{dist-BXa1PZK8.js → dist-D8G49gMQ.js} +1 -1
  30. package/ui/dist/assets/{dist-DEkqXBbt.js → dist-DAyUKqoN.js} +1 -1
  31. package/ui/dist/assets/{dist-CiOYdD34.js → dist-DGuk1LV9.js} +1 -1
  32. package/ui/dist/assets/{dist-B0RCUsKg.js → dist-DPkspc9Q.js} +1 -1
  33. package/ui/dist/assets/{dist-BWn8_3c2.js → dist-ekL3xCM_.js} +1 -1
  34. package/ui/dist/assets/{edge-DF1cr81u.js → edge-1tf_B5nG.js} +1 -1
  35. package/ui/dist/assets/{elixir-71c6h9Ri.js → elixir-Ca3rBU7D.js} +1 -1
  36. package/ui/dist/assets/{elm-BSWMNwTH.js → elm-CbkPZkSz.js} +1 -1
  37. package/ui/dist/assets/{erb-DL0d5EiM.js → erb-DV7pKwEX.js} +1 -1
  38. package/ui/dist/assets/{git-rebase-CySRZDuc.js → git-rebase-DItBLEqi.js} +1 -1
  39. package/ui/dist/assets/{glimmer-js-eROyzkAo.js → glimmer-js-CAykgXKb.js} +1 -1
  40. package/ui/dist/assets/{glimmer-ts-CDYBP3ca.js → glimmer-ts-BPT-EGHX.js} +1 -1
  41. package/ui/dist/assets/{glsl-CZPp7InQ.js → glsl-CMfWGTLW.js} +1 -1
  42. package/ui/dist/assets/{graphql-VnzRM8lu.js → graphql-CR_NOWo2.js} +1 -1
  43. package/ui/dist/assets/{hack-B2Ad61Yp.js → hack-BWP6dwsC.js} +1 -1
  44. package/ui/dist/assets/{haml-D_aPEilH.js → haml-CDa-RN50.js} +1 -1
  45. package/ui/dist/assets/{handlebars-CaNTUlW9.js → handlebars-sJHLZ5A7.js} +1 -1
  46. package/ui/dist/assets/{html-BBxxOqkf.js → html-63fn47vQ.js} +1 -1
  47. package/ui/dist/assets/{html-derivative-qfdNd7Ig.js → html-derivative-BXnhYyFs.js} +1 -1
  48. package/ui/dist/assets/{http-B3Fs1J8E.js → http-IOW0RfUa.js} +1 -1
  49. package/ui/dist/assets/{hurl-1_d5iFYp.js → hurl-CTSYkbKC.js} +1 -1
  50. package/ui/dist/assets/index-B-GFE-1x.css +1 -0
  51. package/ui/dist/assets/{index-DlSszbQY.js → index-CtmSI3Ho.js} +171 -132
  52. package/ui/dist/assets/{java-Dns-uIyX.js → java-DOX-o9K8.js} +1 -1
  53. package/ui/dist/assets/{javascript-BkvJR4Ak.js → javascript-NWcTx9fC.js} +1 -1
  54. package/ui/dist/assets/{jinja-xjBAgjJd.js → jinja-TT5Clkg-.js} +1 -1
  55. package/ui/dist/assets/{jison-cIldhYjc.js → jison-DoZAP4a3.js} +1 -1
  56. package/ui/dist/assets/{json-D1TV_MA9.js → json-Dd1DbJZw.js} +1 -1
  57. package/ui/dist/assets/{jsx-D0sju--k.js → jsx-D95PvYev.js} +1 -1
  58. package/ui/dist/assets/{julia-BtKmWBHV.js → julia-DzNcHVqx.js} +1 -1
  59. package/ui/dist/assets/{just-C_ahnckv.js → just-DapN_z3p.js} +1 -1
  60. package/ui/dist/assets/{latex-jGkpHz-Q.js → latex-Bf3O2fQb.js} +1 -1
  61. package/ui/dist/assets/{liquid-BCx1Z1yo.js → liquid-NXRAWoEl.js} +1 -1
  62. package/ui/dist/assets/{lua-C05Cq4kC.js → lua-DgnpxH9p.js} +1 -1
  63. package/ui/dist/assets/{marko-DSlNWh3P.js → marko-wkWPjoQ9.js} +1 -1
  64. package/ui/dist/assets/{mdc-OEBu9A0B.js → mdc-DtOun-X2.js} +1 -1
  65. package/ui/dist/assets/{nginx-C1aCdDVd.js → nginx-XCdDX9Gp.js} +1 -1
  66. package/ui/dist/assets/{nim-DyogFwyD.js → nim-CnDu2vnO.js} +1 -1
  67. package/ui/dist/assets/{perl-Cq7AUp25.js → perl-mCSP7zn3.js} +1 -1
  68. package/ui/dist/assets/{php-ZsSMpvwe.js → php-CnDYV7m9.js} +1 -1
  69. package/ui/dist/assets/{pug-CXpvWTPP.js → pug-DUv1_GFU.js} +1 -1
  70. package/ui/dist/assets/{qml-GHV7U9Iz.js → qml-Cw49qsJy.js} +1 -1
  71. package/ui/dist/assets/{r-ZPvQYZrP.js → r-DUSb08Z8.js} +1 -1
  72. package/ui/dist/assets/{razor-Dbcx8YhK.js → razor-CKco3Dbd.js} +1 -1
  73. package/ui/dist/assets/{regexp-DkIUUpmd.js → regexp-DbjqCAsi.js} +1 -1
  74. package/ui/dist/assets/{rst-Bu5XaW3b.js → rst-iLrpHokU.js} +1 -1
  75. package/ui/dist/assets/{ruby-C9oSZU7n.js → ruby-BBYneGfk.js} +1 -1
  76. package/ui/dist/assets/{sas-BCxfFQA2.js → sas-DoS0TCZm.js} +1 -1
  77. package/ui/dist/assets/{scss-B3Yk29WR.js → scss-DwjazCIb.js} +1 -1
  78. package/ui/dist/assets/{shellscript-D8gXEcYe.js → shellscript-bR-cjL3L.js} +1 -1
  79. package/ui/dist/assets/{shellsession-D77yCV20.js → shellsession-D54KuySr.js} +1 -1
  80. package/ui/dist/assets/{soy-CprWnkpt.js → soy-QeEusSoH.js} +1 -1
  81. package/ui/dist/assets/{sql-CIQipKVb.js → sql-BjJgWH0F.js} +1 -1
  82. package/ui/dist/assets/{stata-B10L7ajY.js → stata---E5T02y.js} +1 -1
  83. package/ui/dist/assets/{surrealql-DpM6G529.js → surrealql-B3nSLmva.js} +1 -1
  84. package/ui/dist/assets/{svelte-CF0XZujx.js → svelte-BrJnUGsO.js} +1 -1
  85. package/ui/dist/assets/{templ-FAVfFvOb.js → templ-Cp6BywaR.js} +1 -1
  86. package/ui/dist/assets/{tex-Bk_ASCGx.js → tex-yFYe_F-5.js} +1 -1
  87. package/ui/dist/assets/{ts-tags-Z2hr36mA.js → ts-tags-Dn1XZNS9.js} +1 -1
  88. package/ui/dist/assets/{tsx-Dg-3IW-0.js → tsx-BnhO4Hkv.js} +1 -1
  89. package/ui/dist/assets/{twig-CAfYLJ73.js → twig-B-zB3u-Z.js} +1 -1
  90. package/ui/dist/assets/{typescript-CuQC_OIP.js → typescript-D49Rl_Ln.js} +1 -1
  91. package/ui/dist/assets/{vue-DjlgTag0.js → vue-DmTXiGeI.js} +1 -1
  92. package/ui/dist/assets/{vue-html-car_Y-EZ.js → vue-html-CeXpHptR.js} +1 -1
  93. package/ui/dist/assets/{vue-vine-ClPFRhPz.js → vue-vine-C2uWvGRx.js} +1 -1
  94. package/ui/dist/assets/{xml-CJiqUkS6.js → xml-SZiG-U1T.js} +1 -1
  95. package/ui/dist/assets/{xsl-DoOf1m_u.js → xsl-DksAOCj6.js} +1 -1
  96. package/ui/dist/assets/{yaml-C8DZp3NU.js → yaml-DX7HDqJF.js} +1 -1
  97. package/ui/dist/index.html +2 -2
  98. package/ui/dist/assets/index-VdPxwEP-.css +0 -1
package/dist/cli.js CHANGED
@@ -1990,11 +1990,11 @@ var require_indexes = __commonJS((exports, module) => {
1990
1990
 
1991
1991
  // node_modules/.bun/thread-stream@4.2.0/node_modules/thread-stream/index.js
1992
1992
  var require_thread_stream = __commonJS((exports, module) => {
1993
- var __dirname = "/Users/juliantorres/GitLocal/Play/caret/node_modules/.bun/thread-stream@4.2.0/node_modules/thread-stream";
1993
+ var __dirname = "/Users/juliantorres/GitLocal/Play/caret/trunk/node_modules/.bun/thread-stream@4.2.0/node_modules/thread-stream";
1994
1994
  var { version: version2 } = require_package();
1995
1995
  var { EventEmitter } = __require("events");
1996
1996
  var { Worker } = __require("worker_threads");
1997
- var { join: join6 } = __require("path");
1997
+ var { join: join7 } = __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"] || join6(__dirname, "lib", "worker.js");
2047
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join7(__dirname, "lib", "worker.js");
2048
2048
  const worker = new Worker(toExecute, {
2049
2049
  ...opts.workerOpts,
2050
2050
  name: opts.workerOpts?.name || "thread-stream",
@@ -2506,11 +2506,11 @@ var require_thread_stream = __commonJS((exports, module) => {
2506
2506
 
2507
2507
  // node_modules/.bun/pino@10.3.1/node_modules/pino/lib/transport.js
2508
2508
  var require_transport = __commonJS((exports, module) => {
2509
- var __dirname = "/Users/juliantorres/GitLocal/Play/caret/node_modules/.bun/pino@10.3.1/node_modules/pino/lib";
2509
+ var __dirname = "/Users/juliantorres/GitLocal/Play/caret/trunk/node_modules/.bun/pino@10.3.1/node_modules/pino/lib";
2510
2510
  var { createRequire } = __require("module");
2511
- var { existsSync: existsSync3 } = __require("fs");
2511
+ var { existsSync: existsSync4 } = __require("fs");
2512
2512
  var getCallers = require_caller();
2513
- var { join: join6, isAbsolute, sep } = __require("path");
2513
+ var { join: join7, isAbsolute, sep } = __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();
@@ -2582,7 +2582,7 @@ var require_transport = __commonJS((exports, module) => {
2582
2582
  return false;
2583
2583
  }
2584
2584
  }
2585
- return isAbsolute(path) && !existsSync3(path);
2585
+ return isAbsolute(path) && !existsSync4(path);
2586
2586
  }
2587
2587
  function stripQuotes(value) {
2588
2588
  const first = value[0];
@@ -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"] || join6(__dirname, "worker.js");
2666
+ target = bundlerOverrides["pino-worker"] || join7(__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"] || join6(__dirname, "worker.js");
2683
+ target = bundlerOverrides["pino-worker"] || join7(__dirname, "worker.js");
2684
2684
  options.pipelines = [pipeline.map((dest) => {
2685
2685
  return {
2686
2686
  ...dest,
@@ -2703,7 +2703,7 @@ var require_transport = __commonJS((exports, module) => {
2703
2703
  return origin;
2704
2704
  }
2705
2705
  if (origin === "pino/file") {
2706
- return join6(__dirname, "..", "file.js");
2706
+ return join7(__dirname, "..", "file.js");
2707
2707
  }
2708
2708
  let fixTarget2;
2709
2709
  for (const filePath of callers) {
@@ -3632,7 +3632,7 @@ var require_safe_stable_stringify = __commonJS((exports, module) => {
3632
3632
  return circularValue;
3633
3633
  }
3634
3634
  let res = "";
3635
- let join6 = ",";
3635
+ let join7 = ",";
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
- join6 = `,
3649
+ join7 = `,
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 += join6;
3657
+ res += join7;
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 += `${join6}"... ${getItemCount(removedKeys)} not stringified"`;
3663
+ res += `${join7}"... ${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
- join6 = `,
3684
+ join7 = `,
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 = join6;
3698
+ separator = join7;
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 = join6;
3704
+ separator = join7;
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 join6 = ",";
3744
+ let join7 = ",";
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
- join6 = `,
3757
+ join7 = `,
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 += join6;
3765
+ res += join7;
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 += `${join6}"... ${getItemCount(removedKeys)} not stringified"`;
3771
+ res += `${join7}"... ${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
- join6 = `,
3784
+ join7 = `,
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 = join6;
3793
+ separator = join7;
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 join7 = `,
3850
+ const join8 = `,
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 += join7;
3857
+ res2 += join8;
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 += `${join7}"... ${getItemCount(removedKeys)} not stringified"`;
3863
+ res2 += `${join8}"... ${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 join6 = `,
3879
+ const join7 = `,
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, join6, maximumBreadth);
3885
+ res += stringifyTypedArray(value, join7, maximumBreadth);
3886
3886
  keys = keys.slice(value.length);
3887
3887
  maximumPropertiesToStringify -= value.length;
3888
- separator = join6;
3888
+ separator = join7;
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 = join6;
3899
+ separator = join7;
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 = join6;
3905
+ separator = join7;
3906
3906
  }
3907
3907
  if (separator !== "") {
3908
3908
  res = `
@@ -5803,8 +5803,8 @@ __export(exports_dist, {
5803
5803
  });
5804
5804
  import { styleText as styleText2, stripVTControlCharacters } from "util";
5805
5805
  import process$1 from "process";
5806
- import { existsSync as existsSync9, lstatSync, readdirSync as readdirSync5 } from "fs";
5807
- import { dirname as dirname7, join as join12 } from "path";
5806
+ import { existsSync as existsSync10, lstatSync, readdirSync as readdirSync6 } from "fs";
5807
+ import { dirname as dirname8, join as join13 } from "path";
5808
5808
  function isUnicodeSupported() {
5809
5809
  if (process$1.platform !== "win32") {
5810
5810
  return process$1.env.TERM !== "linux";
@@ -6515,10 +6515,10 @@ ${n3}
6515
6515
  return [];
6516
6516
  try {
6517
6517
  let i;
6518
- existsSync9(t2) ? lstatSync(t2).isDirectory() && (!e.directory || t2.endsWith("/")) ? i = t2 : i = dirname7(t2) : i = dirname7(t2);
6518
+ existsSync10(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
- return readdirSync5(i).map((r2) => {
6521
- const n3 = join12(i, r2), m3 = lstatSync(n3);
6520
+ return readdirSync6(i).map((r2) => {
6521
+ const n3 = join13(i, r2), m3 = lstatSync(n3);
6522
6522
  return {
6523
6523
  name: r2,
6524
6524
  path: n3,
@@ -8248,8 +8248,8 @@ function fatalDenyLine3(reason) {
8248
8248
  }
8249
8249
 
8250
8250
  // src/adapters/opencode/install.ts
8251
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
8252
- import { join as join4 } from "path";
8251
+ import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
8252
+ import { join as join5 } from "path";
8253
8253
 
8254
8254
  // node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
8255
8255
  function createScanner(text, ignoreTrivia = false) {
@@ -9575,10 +9575,19 @@ function applyEdits(text, edits) {
9575
9575
  }
9576
9576
 
9577
9577
  // src/adapters/opencode/paths.ts
9578
- import { existsSync } from "fs";
9578
+ import { existsSync, readdirSync } from "fs";
9579
9579
  import { homedir as homedir3 } from "os";
9580
- import { join as join3 } from "path";
9580
+ import { basename, dirname, join as join3 } from "path";
9581
9581
  var CARET_PACKAGE = "@macintacos/caret";
9582
+ function localPluginSpecifier(repoDir) {
9583
+ return `file:${repoDir}`;
9584
+ }
9585
+ function isLocalPluginSpecifier(spec) {
9586
+ return spec.startsWith("file:");
9587
+ }
9588
+ function localSpecifierPath(spec) {
9589
+ return isLocalPluginSpecifier(spec) ? spec.slice("file:".length) : undefined;
9590
+ }
9582
9591
  var COMMAND_DIRNAME = "commands";
9583
9592
  var COMMAND_NAMESPACE = "caret:";
9584
9593
  function namespacedCommandFilename(sourceName) {
@@ -9603,42 +9612,207 @@ function resolveConfigFile(configDir) {
9603
9612
  function commandDir(configDir) {
9604
9613
  return join3(configDir, COMMAND_DIRNAME);
9605
9614
  }
9606
- function opencodeCachePackageDir(pkg = CARET_PACKAGE) {
9615
+ var LEGACY_PLUGIN_FILENAME = "caret.ts";
9616
+ var LEGACY_PLUGIN_DIRNAMES = ["plugins", "plugin"];
9617
+ var LEGACY_COMMAND_DIRNAME = "command";
9618
+ function existingLegacyInstallFiles(configDir) {
9619
+ const plugins = LEGACY_PLUGIN_DIRNAMES.map((d) => join3(configDir, d, LEGACY_PLUGIN_FILENAME));
9620
+ let entries;
9621
+ try {
9622
+ entries = readdirSync(join3(configDir, LEGACY_COMMAND_DIRNAME), { withFileTypes: true });
9623
+ } catch {
9624
+ entries = [];
9625
+ }
9626
+ 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();
9627
+ return [...plugins, ...commands].filter((p) => existsSync(p));
9628
+ }
9629
+ function opencodeCachePackagesDir() {
9607
9630
  const xdg = process.env.XDG_CACHE_HOME?.trim();
9608
- const base = xdg || join3(homedir3(), ".cache");
9609
- return join3(base, "opencode", "node_modules", pkg);
9631
+ return join3(xdg || join3(homedir3(), ".cache"), "opencode", "packages");
9632
+ }
9633
+ function opencodeCachePackageDir(pkg = CARET_PACKAGE) {
9634
+ return join3(opencodeCachePackagesDir(), pkg);
9635
+ }
9636
+ function existingOpencodeCachePackageDirs(pkg = CARET_PACKAGE) {
9637
+ const bare = opencodeCachePackageDir(pkg);
9638
+ const parent = dirname(bare);
9639
+ const leaf = basename(bare);
9640
+ let names;
9641
+ try {
9642
+ names = readdirSync(parent);
9643
+ } catch {
9644
+ return [];
9645
+ }
9646
+ const pinned = names.filter((n) => n.startsWith(`${leaf}@`)).sort();
9647
+ return [...names.includes(leaf) ? [bare] : [], ...pinned.map((n) => join3(parent, n))];
9648
+ }
9649
+
9650
+ // src/adapters/opencode/upgrade.ts
9651
+ import { existsSync as existsSync2, readFileSync as readFileSync3, rmSync } from "fs";
9652
+ import { join as join4 } from "path";
9653
+
9654
+ // src/adapters/opencode/config-plugin.ts
9655
+ var FORMATTING = { insertSpaces: true, tabSize: 2 };
9656
+ function pluginArray(text) {
9657
+ const cfg = parse3(text);
9658
+ return Array.isArray(cfg?.plugin) ? cfg.plugin : [];
9659
+ }
9660
+ function splitPluginSpecifier(spec) {
9661
+ if (isLocalPluginSpecifier(spec))
9662
+ return { pkg: spec, version: null };
9663
+ const from = spec.startsWith("@") ? spec.indexOf("/") : 0;
9664
+ if (from === -1)
9665
+ return { pkg: spec, version: null };
9666
+ const at = spec.indexOf("@", from + 1);
9667
+ return at === -1 ? { pkg: spec, version: null } : { pkg: spec.slice(0, at), version: spec.slice(at + 1) };
9668
+ }
9669
+ function packageName(spec) {
9670
+ return splitPluginSpecifier(spec).pkg;
9671
+ }
9672
+ function entryNames(entry, pkg) {
9673
+ return typeof entry === "string" && packageName(entry) === packageName(pkg);
9674
+ }
9675
+ function addPluginToConfigText(existing, pkg) {
9676
+ const text = existing ?? `{}
9677
+ `;
9678
+ const current = parse3(text)?.plugin;
9679
+ if (Array.isArray(current)) {
9680
+ if (current.some((e) => entryNames(e, pkg)))
9681
+ return text;
9682
+ const path = ["plugin", current.length];
9683
+ const edits2 = modify(text, path, pkg, {
9684
+ isArrayInsertion: true,
9685
+ formattingOptions: FORMATTING
9686
+ });
9687
+ return applyEdits(text, edits2);
9688
+ }
9689
+ const edits = modify(text, ["plugin"], [pkg], { formattingOptions: FORMATTING });
9690
+ return applyEdits(text, edits);
9691
+ }
9692
+ function findPluginEntry(existing, pkg) {
9693
+ if (existing === null)
9694
+ return null;
9695
+ const entry = pluginArray(existing).find((e) => entryNames(e, pkg));
9696
+ return typeof entry === "string" ? entry : null;
9697
+ }
9698
+ function pluginEntries(existing) {
9699
+ return existing === null ? [] : pluginArray(existing).filter((e) => typeof e === "string");
9700
+ }
9701
+ function setPluginVersionInConfigText(existing, pkg, version) {
9702
+ const arr = pluginArray(existing);
9703
+ const i = arr.findIndex((e) => entryNames(e, pkg));
9704
+ if (i === -1)
9705
+ return existing;
9706
+ const next = `${packageName(arr[i])}@${version}`;
9707
+ const edits = modify(existing, ["plugin", i], next, { formattingOptions: FORMATTING });
9708
+ return applyEdits(existing, edits);
9709
+ }
9710
+ function removePluginFromConfigText(existing, pkg) {
9711
+ const arr = pluginArray(existing);
9712
+ if (!arr.some((e) => entryNames(e, pkg)))
9713
+ return existing;
9714
+ const next = arr.filter((e) => !entryNames(e, pkg));
9715
+ const edits = modify(existing, ["plugin"], next, { formattingOptions: FORMATTING });
9716
+ return applyEdits(existing, edits);
9717
+ }
9718
+
9719
+ // src/adapters/opencode/upgrade.ts
9720
+ var NPM_LATEST_URL = `https://registry.npmjs.org/${CARET_PACKAGE}/latest`;
9721
+ var NPM_TIMEOUT_MS = 3000;
9722
+ function parseVersionTriple(v) {
9723
+ const m = v.trim().replace(/^v/, "").match(/^(\d+)\.(\d+)\.(\d+)/);
9724
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
9725
+ }
9726
+ function isNewer(latest, current) {
9727
+ const a = parseVersionTriple(latest);
9728
+ const b = parseVersionTriple(current);
9729
+ if (!a || !b)
9730
+ return false;
9731
+ const [a0, a1, a2] = a;
9732
+ const [b0, b1, b2] = b;
9733
+ if (a0 !== b0)
9734
+ return a0 > b0;
9735
+ if (a1 !== b1)
9736
+ return a1 > b1;
9737
+ return a2 > b2;
9738
+ }
9739
+ function upgradeVerdict(input) {
9740
+ const { entry, cached, published } = input;
9741
+ if (published === null) {
9742
+ return { kind: "unknown", reason: "could not reach npm for the published caret version" };
9743
+ }
9744
+ if (parseVersionTriple(published) === null) {
9745
+ return { kind: "unknown", reason: `npm reported an unreadable version (${published})` };
9746
+ }
9747
+ if (entry === null)
9748
+ return { kind: "fresh" };
9749
+ const pinned = splitPluginSpecifier(entry).version;
9750
+ if (pinned !== null && parseVersionTriple(pinned) !== null) {
9751
+ return isNewer(published, pinned) ? { kind: "stale-pin", entry, pinned, published } : { kind: "current", version: pinned };
9752
+ }
9753
+ if (cached === null)
9754
+ return { kind: "fresh" };
9755
+ if (parseVersionTriple(cached) === null) {
9756
+ return { kind: "unknown", reason: `OpenCode cached an unreadable version (${cached})` };
9757
+ }
9758
+ return isNewer(published, cached) ? { kind: "stale-cache", cached, published } : { kind: "current", version: cached };
9759
+ }
9760
+ function readCachedCaretVersion(dirs = existingOpencodeCachePackageDirs()) {
9761
+ for (const d of dirs) {
9762
+ try {
9763
+ const deps = JSON.parse(readFileSync3(join4(d, "package.json"), "utf-8")).dependencies;
9764
+ const v = deps?.[CARET_PACKAGE];
9765
+ if (typeof v === "string" && v.length > 0)
9766
+ return v;
9767
+ } catch {}
9768
+ }
9769
+ return null;
9770
+ }
9771
+ function clearCachedCaret(dirs = existingOpencodeCachePackageDirs()) {
9772
+ const cleared = [];
9773
+ for (const d of dirs) {
9774
+ if (!existsSync2(d))
9775
+ continue;
9776
+ rmSync(d, { recursive: true, force: true });
9777
+ cleared.push(d);
9778
+ }
9779
+ return cleared;
9780
+ }
9781
+ async function publishedCaretVersion(fetchImpl = fetch) {
9782
+ try {
9783
+ const res = await fetchImpl(NPM_LATEST_URL, { signal: AbortSignal.timeout(NPM_TIMEOUT_MS) });
9784
+ if (!res.ok)
9785
+ return null;
9786
+ const body = await res.json();
9787
+ const v = body?.version;
9788
+ return typeof v === "string" && v.length > 0 ? v : null;
9789
+ } catch {
9790
+ return null;
9791
+ }
9610
9792
  }
9611
9793
 
9612
9794
  // src/adapters/opencode/install.ts
9613
9795
  function readOpencodeInstallState() {
9614
9796
  const dir = opencodeConfigDir();
9615
- if (!existsSync2(dir)) {
9797
+ if (!existsSync3(dir)) {
9616
9798
  return { pluginVersion: "unknown", pluginEnabled: "unknown", hookInUserSettings: "unknown" };
9617
9799
  }
9618
- const cacheDir = opencodeCachePackageDir();
9800
+ const version = readCachedCaretVersion(existingOpencodeCachePackageDirs()) ?? "unknown";
9619
9801
  return {
9620
- pluginVersion: readCachedVersion(cacheDir),
9621
- pluginEnabled: existsSync2(cacheDir),
9802
+ pluginVersion: version,
9803
+ pluginEnabled: version !== "unknown",
9622
9804
  hookInUserSettings: readCaretInPluginArray(dir)
9623
9805
  };
9624
9806
  }
9625
- function readCachedVersion(cachePackageDir) {
9626
- try {
9627
- const v = JSON.parse(readFileSync3(join4(cachePackageDir, "package.json"), "utf-8")).version;
9628
- return typeof v === "string" ? v : "unknown";
9629
- } catch {
9630
- return "unknown";
9631
- }
9632
- }
9633
9807
  function readCaretInPluginArray(dir) {
9634
9808
  let sawConfig = false;
9635
9809
  for (const name of CONFIG_FILENAMES) {
9636
- const path = join4(dir, name);
9637
- if (!existsSync2(path))
9810
+ const path = join5(dir, name);
9811
+ if (!existsSync3(path))
9638
9812
  continue;
9639
9813
  let cfg;
9640
9814
  try {
9641
- cfg = parse3(readFileSync3(path, "utf-8"));
9815
+ cfg = parse3(readFileSync4(path, "utf-8"));
9642
9816
  } catch {
9643
9817
  continue;
9644
9818
  }
@@ -9719,10 +9893,10 @@ function fatalDeny(reason) {
9719
9893
 
9720
9894
  // src/commands/daemon.ts
9721
9895
  import { randomUUID } from "crypto";
9722
- import { existsSync as existsSync5, unlinkSync as unlinkSync3 } from "fs";
9896
+ import { existsSync as existsSync6, unlinkSync as unlinkSync3 } from "fs";
9723
9897
 
9724
9898
  // src/config/settings.ts
9725
- import { readFileSync as readFileSync5, statSync } from "fs";
9899
+ import { readFileSync as readFileSync6, statSync } from "fs";
9726
9900
 
9727
9901
  // node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
9728
9902
  var exports_external = {};
@@ -24065,8 +24239,8 @@ function ensureStateDir(target = stateDir()) {
24065
24239
  import { createHash } from "crypto";
24066
24240
 
24067
24241
  // src/ui/assets.ts
24068
- import { readdirSync } from "fs";
24069
- import { dirname, join as join5, relative } from "path";
24242
+ import { readdirSync as readdirSync2 } from "fs";
24243
+ import { dirname as dirname2, join as join6, relative } from "path";
24070
24244
  import { fileURLToPath } from "url";
24071
24245
  function fromPathMap(map2) {
24072
24246
  const paths = Object.keys(map2).sort();
@@ -24081,8 +24255,8 @@ function fromPathMap(map2) {
24081
24255
  function assetsFromDist(distDir) {
24082
24256
  const map2 = {};
24083
24257
  const walk = (dir) => {
24084
- for (const ent of readdirSync(dir, { withFileTypes: true })) {
24085
- const full = join5(dir, ent.name);
24258
+ for (const ent of readdirSync2(dir, { withFileTypes: true })) {
24259
+ const full = join6(dir, ent.name);
24086
24260
  if (ent.isDirectory())
24087
24261
  walk(full);
24088
24262
  else if (ent.isFile())
@@ -24096,6 +24270,12 @@ function assetsFromDist(distDir) {
24096
24270
  }
24097
24271
  return Object.keys(map2).length > 0 ? fromPathMap(map2) : undefined;
24098
24272
  }
24273
+ function uiDistCandidates(moduleUrl) {
24274
+ return [
24275
+ fileURLToPath(new URL("../ui/dist", moduleUrl)),
24276
+ fileURLToPath(new URL("../../ui/dist", moduleUrl))
24277
+ ];
24278
+ }
24099
24279
  async function loadUiAssets() {
24100
24280
  try {
24101
24281
  const mod = await import("@/ui-manifest.generated.ts");
@@ -24103,17 +24283,18 @@ async function loadUiAssets() {
24103
24283
  return fromPathMap(mod.UI_MANIFEST);
24104
24284
  }
24105
24285
  } catch {}
24106
- const srcDist = fileURLToPath(new URL("../../ui/dist", import.meta.url));
24107
- const fromSrc = assetsFromDist(srcDist);
24108
- if (fromSrc)
24109
- return fromSrc;
24110
- const besideDist = join5(dirname(process.execPath), "ui");
24286
+ for (const dir of uiDistCandidates(import.meta.url)) {
24287
+ const fromDist = assetsFromDist(dir);
24288
+ if (fromDist)
24289
+ return fromDist;
24290
+ }
24291
+ const besideDist = join6(dirname2(process.execPath), "ui");
24111
24292
  return assetsFromDist(besideDist);
24112
24293
  }
24113
24294
  // package.json
24114
24295
  var package_default = {
24115
24296
  name: "@macintacos/caret",
24116
- version: "0.8.1",
24297
+ version: "0.9.0",
24117
24298
  license: "MIT",
24118
24299
  type: "module",
24119
24300
  description: "A Claude Code plugin that replaces the terminal plan-approval prompt with a local web UI for inline review, annotation, and approval.",
@@ -24276,8 +24457,8 @@ function currentCommit() {
24276
24457
  var import_pino = __toESM(require_pino(), 1);
24277
24458
 
24278
24459
  // src/lib/caller-location.ts
24279
- import { dirname as dirname2 } from "path";
24280
- var PKG_ROOT = dirname2(dirname2(import.meta.dir));
24460
+ import { dirname as dirname3 } from "path";
24461
+ var PKG_ROOT = dirname3(dirname3(import.meta.dir));
24281
24462
  var FRAME = /^\s*at (?:.* \()?(?:file:\/\/)?(.+):(\d+):\d+\)?$/;
24282
24463
  var INTERNAL_SUFFIXES = ["src/lib/caller-location.ts", "src/lib/log.ts"];
24283
24464
  function parseCaller(stack, pkgRoot = PKG_ROOT) {
@@ -24375,7 +24556,7 @@ function shortId(id) {
24375
24556
  }
24376
24557
 
24377
24558
  // src/redact/node.ts
24378
- import { readFileSync as readFileSync4, writeFileSync } from "fs";
24559
+ import { readFileSync as readFileSync5, writeFileSync } from "fs";
24379
24560
  import { homedir as homedir5 } from "os";
24380
24561
  var FOREIGN_HOME = /(\/Users\/|\/home\/)[^/\s"']+/g;
24381
24562
  function scrubString(s, home = homedir5()) {
@@ -24402,7 +24583,7 @@ function redactLogFiles(files = [logFile(), daemonLogFile()]) {
24402
24583
  for (const file2 of files) {
24403
24584
  let text;
24404
24585
  try {
24405
- text = readFileSync4(file2, "utf-8");
24586
+ text = readFileSync5(file2, "utf-8");
24406
24587
  } catch {
24407
24588
  continue;
24408
24589
  }
@@ -24580,7 +24761,7 @@ function parseAndValidate(text, isCompiled) {
24580
24761
  function loadSettings(file2 = configFile(), isCompiled = isCompiledBinary()) {
24581
24762
  let text;
24582
24763
  try {
24583
- text = readFileSync5(file2, "utf-8");
24764
+ text = readFileSync6(file2, "utf-8");
24584
24765
  } catch {
24585
24766
  return DEFAULTS;
24586
24767
  }
@@ -24602,7 +24783,7 @@ function createSettings(file2 = configFile(), isCompiled = isCompiledBinary()) {
24602
24783
  }
24603
24784
  let text;
24604
24785
  try {
24605
- text = readFileSync5(file2, "utf-8");
24786
+ text = readFileSync6(file2, "utf-8");
24606
24787
  } catch {
24607
24788
  return lastGood;
24608
24789
  }
@@ -24793,7 +24974,8 @@ function isForeignWorld(h, currentStateDir) {
24793
24974
  return h.stateDir !== undefined && !sameWorldPath(h.stateDir, currentStateDir);
24794
24975
  }
24795
24976
  var FOREIGN_WORLD_ERROR = "port serves a different caret world (state dir mismatch) \u2014 set CARET_PORT to a free port";
24796
- async function ensureDaemon(deps) {
24977
+ async function ensureDaemon(deps, opts = {}) {
24978
+ const takeover = opts.takeover ?? true;
24797
24979
  for (let attempt = 0;attempt < deps.maxAttempts; attempt++) {
24798
24980
  const h = await deps.health(deps.baseUrl);
24799
24981
  if (h && h.service === "caret") {
@@ -24803,6 +24985,8 @@ async function ensureDaemon(deps) {
24803
24985
  if (h.build === deps.currentBuild && h.version === deps.currentVersion) {
24804
24986
  return deps.baseUrl;
24805
24987
  }
24988
+ if (!takeover)
24989
+ return deps.baseUrl;
24806
24990
  const retired = await deps.retire(deps.baseUrl, deps.readLock());
24807
24991
  if (!retired)
24808
24992
  return deps.baseUrl;
@@ -24915,11 +25099,11 @@ async function prodEnsureDeps(s) {
24915
25099
 
24916
25100
  // src/daemon/server.ts
24917
25101
  import { renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "fs";
24918
- import { dirname as dirname5 } from "path";
25102
+ import { dirname as dirname6 } from "path";
24919
25103
 
24920
25104
  // src/config/prefs.ts
24921
25105
  import { readFile as readFile2, writeFile } from "fs/promises";
24922
- import { dirname as dirname3 } from "path";
25106
+ import { dirname as dirname4 } from "path";
24923
25107
  var DEFAULT_SET = { valid: ["default"], fallback: "default" };
24924
25108
  async function readApproveMode(file2 = prefsFile(), log = noopLogger, set2 = DEFAULT_SET) {
24925
25109
  try {
@@ -24940,7 +25124,7 @@ async function writeApproveMode(mode, file2 = prefsFile(), log = noopLogger, set
24940
25124
  log.warn("prefs", "ignoring invalid approve mode");
24941
25125
  return;
24942
25126
  }
24943
- ensureStateDir(dirname3(file2));
25127
+ ensureStateDir(dirname4(file2));
24944
25128
  await writeFile(file2, JSON.stringify({ approveMode: mode }, null, 2), { mode: 384 });
24945
25129
  log.debug("prefs", `approve mode saved: ${mode}`);
24946
25130
  }
@@ -25043,10 +25227,10 @@ async function parseBody(req, schema) {
25043
25227
  }
25044
25228
 
25045
25229
  // src/plan/excerpt.ts
25046
- import { readdirSync as readdirSync2, readFileSync as readFileSync6, realpathSync, statSync as statSync2 } from "fs";
25047
- import { extname, isAbsolute, join as join6, relative as relative2, resolve, sep } from "path";
25048
- var EXCERPT_RADIUS = 6;
25049
- var EXCERPT_HEAD_LINES = 13;
25230
+ import { readdirSync as readdirSync3, readFileSync as readFileSync7, realpathSync, statSync as statSync2 } from "fs";
25231
+ import { extname, isAbsolute, join as join7, relative as relative2, resolve, sep } from "path";
25232
+ var EXCERPT_RADIUS = 30;
25233
+ var EXCERPT_HEAD_LINES = 60;
25050
25234
  var MAX_EXCERPT_BYTES = 2 * 1024 * 1024;
25051
25235
  var MAX_SCAN_ENTRIES = 5000;
25052
25236
  var SKIP_DIRS = new Set(["node_modules", "dist", "build", "coverage", "out"]);
@@ -25130,7 +25314,7 @@ function basenameSearch(cwdReal, name) {
25130
25314
  const currentDir = queue.shift();
25131
25315
  let entries;
25132
25316
  try {
25133
- entries = readdirSync2(currentDir, { withFileTypes: true });
25317
+ entries = readdirSync3(currentDir, { withFileTypes: true });
25134
25318
  } catch {
25135
25319
  continue;
25136
25320
  }
@@ -25139,9 +25323,9 @@ function basenameSearch(cwdReal, name) {
25139
25323
  return null;
25140
25324
  if (entry.isFile()) {
25141
25325
  if (entry.name === name)
25142
- return join6(currentDir, entry.name);
25326
+ return join7(currentDir, entry.name);
25143
25327
  } else if (entry.isDirectory() && !SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
25144
- queue.push(join6(currentDir, entry.name));
25328
+ queue.push(join7(currentDir, entry.name));
25145
25329
  }
25146
25330
  }
25147
25331
  }
@@ -25162,7 +25346,17 @@ function resolveFileInCwd(cwd, candidate) {
25162
25346
  const name = cleaned.split("/").pop() ?? "";
25163
25347
  return basenameSearch(cwdReal, name);
25164
25348
  }
25165
- function readFileExcerpt(cwd, candidate, line) {
25349
+ function isFileTooLargeToPreview(cwd, candidate) {
25350
+ const abs = resolveFileInCwd(cwd, candidate);
25351
+ if (abs === null)
25352
+ return false;
25353
+ try {
25354
+ return statSync2(abs).size > MAX_EXCERPT_BYTES;
25355
+ } catch {
25356
+ return false;
25357
+ }
25358
+ }
25359
+ function readFileExcerpt(cwd, candidate, line, range) {
25166
25360
  const abs = resolveFileInCwd(cwd, candidate);
25167
25361
  if (abs === null)
25168
25362
  return null;
@@ -25176,7 +25370,7 @@ function readFileExcerpt(cwd, candidate, line) {
25176
25370
  return null;
25177
25371
  let content;
25178
25372
  try {
25179
- content = readFileSync6(abs, "utf-8");
25373
+ content = readFileSync7(abs, "utf-8");
25180
25374
  } catch {
25181
25375
  return null;
25182
25376
  }
@@ -25189,7 +25383,10 @@ function readFileExcerpt(cwd, candidate, line) {
25189
25383
  const totalLines = allLines.length;
25190
25384
  let startLine;
25191
25385
  let endLine;
25192
- if (line !== undefined && line >= 1) {
25386
+ if (range !== undefined) {
25387
+ startLine = Math.min(Math.max(1, range.start), totalLines);
25388
+ endLine = Math.min(totalLines, Math.max(range.end, startLine));
25389
+ } else if (line !== undefined && line >= 1) {
25193
25390
  const target = Math.min(line, totalLines);
25194
25391
  startLine = Math.max(1, target - EXCERPT_RADIUS);
25195
25392
  endLine = Math.min(totalLines, target + EXCERPT_RADIUS);
@@ -25254,12 +25451,12 @@ function createDecisions(log = noopLogger) {
25254
25451
  import { randomBytes } from "crypto";
25255
25452
 
25256
25453
  // src/plan/canonical-file.ts
25257
- import { appendFileSync, existsSync as existsSync3, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
25454
+ import { appendFileSync, existsSync as existsSync4, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
25258
25455
  function guardedPlanFileWrite(planFilePath, log, failMsg, write) {
25259
25456
  try {
25260
25457
  if (!planFilePath.endsWith(".md"))
25261
25458
  return;
25262
- if (!existsSync3(planFilePath) || !statSync3(planFilePath).isFile())
25459
+ if (!existsSync4(planFilePath) || !statSync3(planFilePath).isFile())
25263
25460
  return;
25264
25461
  write(planFilePath);
25265
25462
  } catch (err) {
@@ -25281,27 +25478,27 @@ function appendReviewerNotesToPlanFile(planFilePath, notes, log) {
25281
25478
 
25282
25479
  // src/plan/rumdl.ts
25283
25480
  import { createHash as createHash2 } from "crypto";
25284
- import { chmodSync as chmodSync2, existsSync as existsSync4, mkdirSync as mkdirSync2, renameSync, writeFileSync as writeFileSync3 } from "fs";
25481
+ import { chmodSync as chmodSync2, existsSync as existsSync5, mkdirSync as mkdirSync2, renameSync, writeFileSync as writeFileSync3 } from "fs";
25285
25482
  import { mkdtemp, rm } from "fs/promises";
25286
25483
  import { tmpdir } from "os";
25287
- import { dirname as dirname4, join as join7 } from "path";
25288
- var RUMDL_VERSION = "0.2.37";
25484
+ import { dirname as dirname5, join as join8 } from "path";
25485
+ var RUMDL_VERSION = "0.2.47";
25289
25486
  var ASSETS = {
25290
25487
  "darwin-arm64": {
25291
25488
  url: `https://github.com/rvben/rumdl/releases/download/v${RUMDL_VERSION}/rumdl-v${RUMDL_VERSION}-aarch64-apple-darwin.tar.gz`,
25292
- sha256: "ac5f31077c492c3303d27264d8d8840b1279cb5a8cd62f863a2045e1427a6c79"
25489
+ sha256: "10dc23e994327ecc6e98d285802fcad1174608f203062cb18bac55b51976e0cb"
25293
25490
  },
25294
25491
  "darwin-x64": {
25295
25492
  url: `https://github.com/rvben/rumdl/releases/download/v${RUMDL_VERSION}/rumdl-v${RUMDL_VERSION}-x86_64-apple-darwin.tar.gz`,
25296
- sha256: "7cdfbc6ac896bfe433938a050e0f7b4dfc9ebc78d17ec8f4f872580b1fe06eba"
25493
+ sha256: "9a2bf0c692310e0469fdc66fa83f74579cf0331cc1f9b306b25849cffd146c0f"
25297
25494
  },
25298
25495
  "linux-arm64": {
25299
25496
  url: `https://github.com/rvben/rumdl/releases/download/v${RUMDL_VERSION}/rumdl-v${RUMDL_VERSION}-aarch64-unknown-linux-musl.tar.gz`,
25300
- sha256: "2cee94dbc4e577c54869723245be548589e80a5e5a93fe25a3cc535d51e1ac6d"
25497
+ sha256: "b5ab4207b92c0bf0ea6d8946f15545c787e8cf6ecf2176d9e7f26c43aead86a8"
25301
25498
  },
25302
25499
  "linux-x64": {
25303
25500
  url: `https://github.com/rvben/rumdl/releases/download/v${RUMDL_VERSION}/rumdl-v${RUMDL_VERSION}-x86_64-unknown-linux-musl.tar.gz`,
25304
- sha256: "0999d31c6f1429f0b3b5ed86d3ebb2768e5b4a16b373a51a41a7af2d7eb43b7c"
25501
+ sha256: "bd4049763e93d6c25420ec086dee6690af31efc85af463c3ecf5d686a5fcf762"
25305
25502
  }
25306
25503
  };
25307
25504
  function rumdlAsset(platform = process.platform, arch = process.arch) {
@@ -25317,6 +25514,8 @@ code-blocks = false
25317
25514
  tables = false
25318
25515
  reflow = true
25319
25516
  reflow-mode = "normalize"
25517
+ reflow-length-exemptions = true
25518
+ ignore-link-urls = true
25320
25519
  `;
25321
25520
  async function downloadRumdl(binPath, asset, fetchImpl = fetch) {
25322
25521
  const res = await fetchImpl(asset.url);
@@ -25325,17 +25524,17 @@ async function downloadRumdl(binPath, asset, fetchImpl = fetch) {
25325
25524
  if (actual !== asset.sha256) {
25326
25525
  throw new Error(`rumdl: checksum mismatch for ${asset.url} (expected ${asset.sha256}, got ${actual})`);
25327
25526
  }
25328
- const work = await mkdtemp(join7(tmpdir(), "caret-rumdl-"));
25527
+ const work = await mkdtemp(join8(tmpdir(), "caret-rumdl-"));
25329
25528
  try {
25330
- const archive = join7(work, "rumdl.tar.gz");
25529
+ const archive = join8(work, "rumdl.tar.gz");
25331
25530
  await Bun.write(archive, bytes);
25332
25531
  const tar = Bun.spawn(["tar", "-xzf", archive, "-C", work], { stderr: "pipe" });
25333
25532
  if (await tar.exited !== 0)
25334
25533
  throw new Error(`rumdl: failed to extract ${asset.url}`);
25335
- const extracted = join7(work, "rumdl");
25336
- if (!existsSync4(extracted))
25534
+ const extracted = join8(work, "rumdl");
25535
+ if (!existsSync5(extracted))
25337
25536
  throw new Error(`rumdl: binary not found in ${asset.url}`);
25338
- mkdirSync2(dirname4(binPath), { recursive: true });
25537
+ mkdirSync2(dirname5(binPath), { recursive: true });
25339
25538
  const tmp = `${binPath}.${process.pid}.tmp`;
25340
25539
  await Bun.write(tmp, Bun.file(extracted));
25341
25540
  chmodSync2(tmp, 493);
@@ -25347,7 +25546,7 @@ async function downloadRumdl(binPath, asset, fetchImpl = fetch) {
25347
25546
  }
25348
25547
  var installPinnedRumdl = (binPath) => downloadRumdl(binPath, rumdlAsset());
25349
25548
  async function installedVersion(bin) {
25350
- if (!existsSync4(bin))
25549
+ if (!existsSync5(bin))
25351
25550
  return null;
25352
25551
  try {
25353
25552
  const proc = Bun.spawn([bin, "--version"], { stdout: "pipe", stderr: "ignore" });
@@ -25623,6 +25822,9 @@ function createServer(opts) {
25623
25822
  function notFound() {
25624
25823
  return new Response("not found", { status: 404 });
25625
25824
  }
25825
+ function tooLarge() {
25826
+ return new Response("too large", { status: 413 });
25827
+ }
25626
25828
  function handleHealth() {
25627
25829
  const body = {
25628
25830
  ...IDENTITY,
@@ -25744,10 +25946,18 @@ function createServer(opts) {
25744
25946
  return notFound();
25745
25947
  const params = new URL(req.url).searchParams;
25746
25948
  const path = params.get("path") ?? "";
25747
- const lineRaw = params.get("line");
25748
- const line = lineRaw !== null && /^\d+$/.test(lineRaw) ? Number(lineRaw) : undefined;
25749
- const excerpt = readFileExcerpt(r.cwd, path, line);
25750
- return excerpt ? Response.json(excerpt) : notFound();
25949
+ const num = (key) => {
25950
+ const raw = params.get(key);
25951
+ return raw !== null && /^\d+$/.test(raw) ? Number(raw) : undefined;
25952
+ };
25953
+ const line = num("line");
25954
+ const start = num("start");
25955
+ const end = num("end");
25956
+ const range = start !== undefined && end !== undefined ? { start, end } : undefined;
25957
+ const excerpt = readFileExcerpt(r.cwd, path, line, range);
25958
+ if (excerpt)
25959
+ return Response.json(excerpt);
25960
+ return isFileTooLargeToPreview(r.cwd, path) ? tooLarge() : notFound();
25751
25961
  }
25752
25962
  async function handleDecision(id) {
25753
25963
  const inMem = store.get(id);
@@ -25918,7 +26128,7 @@ function createServer(opts) {
25918
26128
  if (!lockPath)
25919
26129
  return;
25920
26130
  try {
25921
- ensureStateDir(dirname5(lockPath));
26131
+ ensureStateDir(dirname6(lockPath));
25922
26132
  const lock = {
25923
26133
  pid: process.pid,
25924
26134
  port: server.port ?? 0,
@@ -25955,7 +26165,7 @@ function createServer(opts) {
25955
26165
 
25956
26166
  // src/review/store.ts
25957
26167
  import { readdir, readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
25958
- import { join as join8 } from "path";
26168
+ import { join as join9 } from "path";
25959
26169
  function createStore(dir, log = noopLogger) {
25960
26170
  const reviews = new Map;
25961
26171
  const epochs = new Map;
@@ -25964,7 +26174,7 @@ function createStore(dir, log = noopLogger) {
25964
26174
  const prev = writeChains.get(review.id) ?? Promise.resolve();
25965
26175
  const next = prev.catch(() => {}).then(async () => {
25966
26176
  ensureStateDir(dir);
25967
- await writeFile2(join8(dir, `${review.id}.json`), JSON.stringify(review, null, 2), {
26177
+ await writeFile2(join9(dir, `${review.id}.json`), JSON.stringify(review, null, 2), {
25968
26178
  mode: 384
25969
26179
  });
25970
26180
  log.debug("store", `review persisted: ${shortId(review.id)}`, { reviewId: review.id });
@@ -26014,7 +26224,7 @@ function createStore(dir, log = noopLogger) {
26014
26224
  return review;
26015
26225
  },
26016
26226
  async persisted(id) {
26017
- return await readJsonFile(join8(dir, `${id}.json`)) ?? undefined;
26227
+ return await readJsonFile(join9(dir, `${id}.json`)) ?? undefined;
26018
26228
  },
26019
26229
  size() {
26020
26230
  return reviews.size;
@@ -26041,7 +26251,7 @@ function createStore(dir, log = noopLogger) {
26041
26251
  if (!file2.endsWith(".json"))
26042
26252
  continue;
26043
26253
  try {
26044
- const review = JSON.parse(await readFile3(join8(dir, file2), "utf-8"));
26254
+ const review = JSON.parse(await readFile3(join9(dir, file2), "utf-8"));
26045
26255
  if (isUnresolved(review.status)) {
26046
26256
  reviews.set(review.id, review);
26047
26257
  loaded++;
@@ -26063,7 +26273,7 @@ async function runDaemon(opts) {
26063
26273
  const log = createDaemonLogger(() => svc.current().logging.level, undefined, () => svc.current().logging.redact);
26064
26274
  const cfg = configFile();
26065
26275
  const boot = svc.current();
26066
- log.info("settings", existsSync5(cfg) ? `settings: reading ${cfg}` : `settings: no config at ${cfg}; using defaults`, { settings: boot });
26276
+ log.info("settings", existsSync6(cfg) ? `settings: reading ${cfg}` : `settings: no config at ${cfg}; using defaults`, { settings: boot });
26067
26277
  warnInvalidEnvVars((msg) => log.warn("env", msg));
26068
26278
  const adapter = selectAdapter();
26069
26279
  const store = createStore(reviewsDir(), log);
@@ -26097,7 +26307,7 @@ async function runDaemon(opts) {
26097
26307
  }),
26098
26308
  settings: () => settings().current(),
26099
26309
  configPath: cfg,
26100
- configExists: () => existsSync5(cfg),
26310
+ configExists: () => existsSync6(cfg),
26101
26311
  envOverrides
26102
26312
  }),
26103
26313
  log
@@ -26136,12 +26346,12 @@ async function runDaemon(opts) {
26136
26346
  }
26137
26347
 
26138
26348
  // src/commands/discovery.ts
26139
- import { existsSync as existsSync6 } from "fs";
26349
+ import { existsSync as existsSync7 } from "fs";
26140
26350
  import { release } from "os";
26141
26351
 
26142
26352
  // src/discovery.ts
26143
- import { readdirSync as readdirSync3, statSync as statSync4 } from "fs";
26144
- import { basename, join as join9 } from "path";
26353
+ import { readdirSync as readdirSync4, statSync as statSync4 } from "fs";
26354
+ import { basename as basename2, join as join10 } from "path";
26145
26355
  var CARET_BIN = "caret-native";
26146
26356
  async function safe(build) {
26147
26357
  try {
@@ -26321,7 +26531,7 @@ function parsePsLines(text) {
26321
26531
  const [, pidStr, comm] = m ?? [];
26322
26532
  if (pidStr === undefined || comm === undefined)
26323
26533
  continue;
26324
- const name = basename(comm.trim());
26534
+ const name = basename2(comm.trim());
26325
26535
  if (name === CARET_BIN)
26326
26536
  out.push({ pid: Number(pidStr), name });
26327
26537
  }
@@ -26341,7 +26551,7 @@ function listReviewFiles() {
26341
26551
  const dir = reviewsDir();
26342
26552
  let files;
26343
26553
  try {
26344
- files = readdirSync3(dir);
26554
+ files = readdirSync4(dir);
26345
26555
  } catch {
26346
26556
  return [];
26347
26557
  }
@@ -26351,7 +26561,7 @@ function listReviewFiles() {
26351
26561
  continue;
26352
26562
  if (out.length >= 5000)
26353
26563
  break;
26354
- const raw = readJsonFileSync(join9(dir, file2));
26564
+ const raw = readJsonFileSync(join10(dir, file2));
26355
26565
  if (raw && typeof raw.id === "string" && typeof raw.status === "string") {
26356
26566
  out.push({ id: raw.id, status: raw.status });
26357
26567
  }
@@ -26414,7 +26624,7 @@ function prodDiscoveryDeps(s) {
26414
26624
  }),
26415
26625
  settings: () => s,
26416
26626
  configPath: configFile(),
26417
- configExists: () => existsSync6(configFile()),
26627
+ configExists: () => existsSync7(configFile()),
26418
26628
  effective: () => ({
26419
26629
  port: getPort(s),
26420
26630
  idleMs: idleMs(s),
@@ -26452,36 +26662,36 @@ async function runDiscoverySubcommand(opts) {
26452
26662
  import {
26453
26663
  accessSync,
26454
26664
  constants,
26455
- existsSync as existsSync8,
26665
+ existsSync as existsSync9,
26456
26666
  mkdirSync as mkdirSync3,
26457
- rmSync,
26667
+ rmSync as rmSync2,
26458
26668
  statSync as statSync5,
26459
26669
  symlinkSync,
26460
26670
  writeFileSync as writeFileSync5
26461
26671
  } from "fs";
26462
- import { join as join11, resolve as resolve2 } from "path";
26672
+ import { join as join12, resolve as resolve2 } from "path";
26463
26673
 
26464
26674
  // src/adapters/opencode/packaging.ts
26465
- import { existsSync as existsSync7, readdirSync as readdirSync4, readFileSync as readFileSync7 } from "fs";
26466
- import { dirname as dirname6, join as join10 } from "path";
26675
+ import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync8 } from "fs";
26676
+ import { dirname as dirname7, join as join11 } from "path";
26467
26677
  function resolveCaretRoot() {
26468
26678
  const candidates = [];
26469
26679
  const script = process.argv[1];
26470
26680
  if (script)
26471
- candidates.push(join10(dirname6(script), ".."));
26472
- candidates.push(join10(dirname6(process.execPath), ".."));
26681
+ candidates.push(join11(dirname7(script), ".."));
26682
+ candidates.push(join11(dirname7(process.execPath), ".."));
26473
26683
  for (const root of candidates) {
26474
- if (existsSync7(join10(root, "opencode", "caret.plugin.ts")))
26684
+ if (existsSync8(join11(root, "opencode", "caret.plugin.ts")))
26475
26685
  return root;
26476
26686
  }
26477
26687
  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.`);
26478
26688
  }
26479
26689
  function loadOpencodePackaging(root = resolveCaretRoot()) {
26480
- const binPath = join10(root, "bin", "caret");
26481
- const commandsDir = join10(root, "opencode", "commands");
26690
+ const binPath = join11(root, "bin", "caret");
26691
+ const commandsDir = join11(root, "opencode", "commands");
26482
26692
  let commands = [];
26483
26693
  try {
26484
- commands = readdirSync4(commandsDir).filter((f) => f.endsWith(".md")).sort().map((f) => ({ name: f, contents: readFileSync7(join10(commandsDir, f), "utf-8") }));
26694
+ commands = readdirSync5(commandsDir).filter((f) => f.endsWith(".md")).sort().map((f) => ({ name: f, contents: readFileSync8(join11(commandsDir, f), "utf-8") }));
26485
26695
  } catch {
26486
26696
  commands = [];
26487
26697
  }
@@ -26490,17 +26700,17 @@ function loadOpencodePackaging(root = resolveCaretRoot()) {
26490
26700
 
26491
26701
  // src/commands/install/local.ts
26492
26702
  function devMarketplaceDir() {
26493
- return join11(stateDir(), "dev-marketplace");
26703
+ return join12(stateDir(), "dev-marketplace");
26494
26704
  }
26495
26705
  function resolveLocalCheckout(opts = {}, deps = {}) {
26496
26706
  const repoDir = resolve2(caretRoot(deps));
26497
- if (!existsSync8(join11(repoDir, ".claude-plugin", "marketplace.json"))) {
26707
+ if (!existsSync9(join12(repoDir, ".claude-plugin", "marketplace.json"))) {
26498
26708
  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\`.`);
26499
26709
  }
26500
26710
  if (opts.requireArtifacts !== false) {
26501
26711
  const missing = [
26502
- isExecutable(join11(repoDir, "bin", "caret-native")) ? null : "bin/caret-native",
26503
- isDirectory(join11(repoDir, "bin", "ui")) ? null : "bin/ui"
26712
+ isExecutable(join12(repoDir, "bin", "caret-native")) ? null : "bin/caret-native",
26713
+ isDirectory(join12(repoDir, "bin", "ui")) ? null : "bin/ui"
26504
26714
  ].filter((m) => m !== null);
26505
26715
  if (missing.length > 0) {
26506
26716
  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.`);
@@ -26518,10 +26728,10 @@ function caretRoot(deps) {
26518
26728
  }
26519
26729
  }
26520
26730
  function writeDevMarketplace(repoDir, outDir) {
26521
- rmSync(outDir, { recursive: true, force: true });
26522
- mkdirSync3(join11(outDir, ".claude-plugin"), { recursive: true });
26523
- symlinkSync(resolve2(repoDir), join11(outDir, "caret"));
26524
- writeFileSync5(join11(outDir, ".claude-plugin", "marketplace.json"), `${JSON.stringify({
26731
+ rmSync2(outDir, { recursive: true, force: true });
26732
+ mkdirSync3(join12(outDir, ".claude-plugin"), { recursive: true });
26733
+ symlinkSync(resolve2(repoDir), join12(outDir, "caret"));
26734
+ writeFileSync5(join12(outDir, ".claude-plugin", "marketplace.json"), `${JSON.stringify({
26525
26735
  name: "caret",
26526
26736
  description: "Local caret dev build (generated by caret install --from-local).",
26527
26737
  owner: { name: "macintacos" },
@@ -26532,7 +26742,7 @@ function writeDevMarketplace(repoDir, outDir) {
26532
26742
  async function prewarmLocalBuild(repoDir, deps = {}) {
26533
26743
  const spawn = deps.spawn ?? runCaptured;
26534
26744
  try {
26535
- await spawn([join11(repoDir, "bin", "caret-native"), "prewarm"]);
26745
+ await spawn([join12(repoDir, "bin", "caret-native"), "prewarm"]);
26536
26746
  } catch {}
26537
26747
  }
26538
26748
  function isExecutable(path) {
@@ -26569,6 +26779,9 @@ async function runCaptured(cmd) {
26569
26779
  }
26570
26780
 
26571
26781
  // src/commands/install/ui.ts
26782
+ function isTerminal() {
26783
+ return process.stdin.isTTY === true && process.stdout.isTTY === true;
26784
+ }
26572
26785
  var silentUI = {
26573
26786
  intro: () => {},
26574
26787
  step: async (_label, work) => work(() => {}),
@@ -26641,15 +26854,41 @@ var PLUGIN_REF = "caret@caret";
26641
26854
  var claudeCli = async (args) => {
26642
26855
  try {
26643
26856
  const proc = Bun.spawn(["claude", ...args], { stdout: "pipe", stderr: "pipe" });
26644
- const [code, err] = await Promise.all([proc.exited, new Response(proc.stderr).text()]);
26857
+ const [code, out, err] = await Promise.all([
26858
+ proc.exited,
26859
+ new Response(proc.stdout).text(),
26860
+ new Response(proc.stderr).text()
26861
+ ]);
26645
26862
  if (code === 0)
26646
- return { ok: true, detail: "" };
26647
- return { ok: false, detail: err.trim() || `claude exited ${code}` };
26863
+ return { ok: true, detail: "", stdout: out };
26864
+ return { ok: false, detail: err.trim() || `claude exited ${code}`, stdout: out };
26648
26865
  } catch (e) {
26649
26866
  const missing = e instanceof Error && e.code === "ENOENT";
26650
- return { ok: false, missing, detail: e instanceof Error ? e.message : String(e) };
26867
+ return { ok: false, missing, detail: e instanceof Error ? e.message : String(e), stdout: "" };
26651
26868
  }
26652
26869
  };
26870
+ function parsePluginVersion(stdout2, id) {
26871
+ try {
26872
+ const parsed = JSON.parse(stdout2);
26873
+ if (!Array.isArray(parsed))
26874
+ return null;
26875
+ const rows = parsed.filter((p3) => typeof p3 === "object" && p3 !== null && ("id" in p3) && p3.id === id);
26876
+ const version2 = (rows.find((p3) => p3.scope === "user") ?? rows[0])?.version;
26877
+ return typeof version2 === "string" ? version2 : null;
26878
+ } catch {
26879
+ return null;
26880
+ }
26881
+ }
26882
+ function updateLine(before, after, updated) {
26883
+ if (!updated) {
26884
+ return before ? `caret ${before} in Claude Code \u2014 the update did not land` : "Could not ask Claude Code for the latest caret";
26885
+ }
26886
+ if (!before || !after)
26887
+ return "Asked Claude Code for the latest caret \u2014 restart to apply";
26888
+ if (before === after)
26889
+ return `caret ${after} in Claude Code \u2014 already current`;
26890
+ return `caret ${before} \u2192 ${after} in Claude Code \u2014 restart to apply`;
26891
+ }
26653
26892
  function phases(uninstall, local, writeDev) {
26654
26893
  if (uninstall) {
26655
26894
  return [
@@ -26689,7 +26928,10 @@ function phases(uninstall, local, writeDev) {
26689
26928
  {
26690
26929
  label: "Registering the caret marketplace",
26691
26930
  done: `Registered the caret marketplace (${MARKETPLACE_SOURCE})`,
26692
- commands: [{ args: ["plugin", "marketplace", "add", MARKETPLACE_SOURCE], fatal: false }]
26931
+ commands: [
26932
+ { args: ["plugin", "marketplace", "add", MARKETPLACE_SOURCE], fatal: false },
26933
+ { args: ["plugin", "marketplace", "update", MARKETPLACE_NAME], fatal: false }
26934
+ ]
26693
26935
  },
26694
26936
  {
26695
26937
  label: "Installing the caret plugin",
@@ -26698,6 +26940,16 @@ function phases(uninstall, local, writeDev) {
26698
26940
  { args: ["plugin", "install", PLUGIN_REF, "--scope", "user"], fatal: true },
26699
26941
  { args: ["plugin", "enable", PLUGIN_REF], fatal: false }
26700
26942
  ]
26943
+ },
26944
+ {
26945
+ label: "Updating the caret plugin",
26946
+ done: ([before, update, after]) => updateLine(parsePluginVersion(before?.stdout ?? "", PLUGIN_REF), parsePluginVersion(after?.stdout ?? "", PLUGIN_REF), update?.ok === true),
26947
+ warn: ([, update]) => update?.ok === false ? `Claude Code did not take the update (${update.detail}) \u2014 caret there is unchanged.` : null,
26948
+ commands: [
26949
+ { args: ["plugin", "list", "--json"], fatal: false },
26950
+ { args: ["plugin", "update", PLUGIN_REF, "--scope", "user"], fatal: false },
26951
+ { args: ["plugin", "list", "--json"], fatal: false }
26952
+ ]
26701
26953
  }
26702
26954
  ];
26703
26955
  }
@@ -26730,8 +26982,9 @@ async function runInstallClaudeTarget(opts, deps = {}) {
26730
26982
  }
26731
26983
  for (const phase of plan) {
26732
26984
  try {
26733
- await ui.step(phase.label, async (detail) => {
26985
+ const results = await ui.step(phase.label, async (detail) => {
26734
26986
  phase.before?.();
26987
+ const collected = [];
26735
26988
  for (const { args, fatal, fallback } of phase.commands) {
26736
26989
  detail(`claude ${args.join(" ")}`);
26737
26990
  let r2 = await run(args);
@@ -26739,6 +26992,7 @@ async function runInstallClaudeTarget(opts, deps = {}) {
26739
26992
  detail(`claude ${fallback.join(" ")}`);
26740
26993
  r2 = await run(fallback);
26741
26994
  }
26995
+ collected.push(r2);
26742
26996
  if (r2.ok)
26743
26997
  continue;
26744
26998
  if (r2.missing)
@@ -26746,7 +27000,11 @@ async function runInstallClaudeTarget(opts, deps = {}) {
26746
27000
  if (fatal)
26747
27001
  throw new PhaseFailure(`\`claude ${args.join(" ")}\`: ${r2.detail}`, false);
26748
27002
  }
26749
- }, () => phase.done);
27003
+ return collected;
27004
+ }, (collected) => typeof phase.done === "string" ? phase.done : phase.done(collected));
27005
+ const warning = phase.warn?.(results);
27006
+ if (warning)
27007
+ ui.warn(warning);
26750
27008
  } catch (e) {
26751
27009
  if (!(e instanceof PhaseFailure))
26752
27010
  throw e;
@@ -26758,58 +27016,12 @@ async function runInstallClaudeTarget(opts, deps = {}) {
26758
27016
  }
26759
27017
 
26760
27018
  // src/commands/install/opencode.ts
26761
- import { existsSync as existsSync11, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
26762
- import { basename as basename2, join as join13 } from "path";
26763
-
26764
- // src/adapters/opencode/config-plugin.ts
26765
- var FORMATTING = { insertSpaces: true, tabSize: 2 };
26766
- function pluginArray(text2) {
26767
- const cfg = parse3(text2);
26768
- return Array.isArray(cfg?.plugin) ? cfg.plugin : [];
26769
- }
26770
- function packageName(spec) {
26771
- if (spec.startsWith("@")) {
26772
- const slash = spec.indexOf("/");
26773
- if (slash === -1)
26774
- return spec;
26775
- const at2 = spec.indexOf("@", slash + 1);
26776
- return at2 === -1 ? spec : spec.slice(0, at2);
26777
- }
26778
- const at = spec.indexOf("@");
26779
- return at === -1 ? spec : spec.slice(0, at);
26780
- }
26781
- function entryNames(entry, pkg) {
26782
- return typeof entry === "string" && packageName(entry) === packageName(pkg);
26783
- }
26784
- function addPluginToConfigText(existing, pkg) {
26785
- const text2 = existing ?? `{}
26786
- `;
26787
- const current = parse3(text2)?.plugin;
26788
- if (Array.isArray(current)) {
26789
- if (current.some((e) => entryNames(e, pkg)))
26790
- return text2;
26791
- const path2 = ["plugin", current.length];
26792
- const edits2 = modify(text2, path2, pkg, {
26793
- isArrayInsertion: true,
26794
- formattingOptions: FORMATTING
26795
- });
26796
- return applyEdits(text2, edits2);
26797
- }
26798
- const edits = modify(text2, ["plugin"], [pkg], { formattingOptions: FORMATTING });
26799
- return applyEdits(text2, edits);
26800
- }
26801
- function removePluginFromConfigText(existing, pkg) {
26802
- const arr = pluginArray(existing);
26803
- if (!arr.some((e) => entryNames(e, pkg)))
26804
- return existing;
26805
- const next = arr.filter((e) => !entryNames(e, pkg));
26806
- const edits = modify(existing, ["plugin"], next, { formattingOptions: FORMATTING });
26807
- return applyEdits(existing, edits);
26808
- }
27019
+ import { existsSync as existsSync13, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
27020
+ import { basename as basename3, join as join14 } from "path";
26809
27021
 
26810
27022
  // src/adapters/opencode/deploy.ts
26811
- import { existsSync as existsSync10, mkdirSync as mkdirSync4, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
26812
- import { dirname as dirname8 } from "path";
27023
+ import { existsSync as existsSync11, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
27024
+ import { dirname as dirname9 } from "path";
26813
27025
  function renderPlugin(source, opts) {
26814
27026
  return source.replaceAll("__CARET_VERSION__", () => opts.version).replaceAll("__CARET_BIN__", () => opts.binPath);
26815
27027
  }
@@ -26817,7 +27029,7 @@ function deployFiles(files, opts) {
26817
27029
  const paths = [];
26818
27030
  for (const f2 of files) {
26819
27031
  if (!opts.dryRun) {
26820
- mkdirSync4(dirname8(f2.path), { recursive: true });
27032
+ mkdirSync4(dirname9(f2.path), { recursive: true });
26821
27033
  writeFileSync6(f2.path, f2.contents);
26822
27034
  }
26823
27035
  paths.push(f2.path);
@@ -26827,49 +27039,15 @@ function deployFiles(files, opts) {
26827
27039
  function removeFiles(targets, opts) {
26828
27040
  const paths = [];
26829
27041
  for (const p3 of targets) {
26830
- if (!existsSync10(p3))
27042
+ if (!existsSync11(p3))
26831
27043
  continue;
26832
27044
  if (!opts.dryRun)
26833
- rmSync2(p3, { force: true });
27045
+ rmSync3(p3, { force: true });
26834
27046
  paths.push(p3);
26835
27047
  }
26836
27048
  return { paths, dryRun: opts.dryRun };
26837
27049
  }
26838
27050
 
26839
- // src/commands/install/opencode.ts
26840
- async function runInstallOpencodeTarget(opts, deps = {}) {
26841
- const dir = deps.configDir ?? opencodeConfigDir();
26842
- const pkg = deps.packaging ?? loadOpencodePackaging();
26843
- const ui = deps.ui ?? silentUI;
26844
- const configFile2 = resolveConfigFile(dir);
26845
- const commandPaths = pkg.commands.map((c3) => join13(commandDir(dir), namespacedCommandFilename(c3.name)));
26846
- if (opts.dryRun) {
26847
- const verb = opts.uninstall ? "remove" : "write";
26848
- ui.note([configFile2, ...commandPaths].join(`
26849
- `), `OpenCode \u2014 would ${verb}`);
26850
- return;
26851
- }
26852
- if (opts.uninstall) {
26853
- await ui.step(`Removing ${CARET_PACKAGE} from OpenCode's plugin array`, async () => editConfig(configFile2, (text2) => text2 === null ? null : removePluginFromConfigText(text2, CARET_PACKAGE)), (changed) => changed.length > 0 ? `Removed ${CARET_PACKAGE} from ${basename2(configFile2)}` : `${CARET_PACKAGE} was not in ${basename2(configFile2)}`);
26854
- await ui.step("Removing the /caret:* command files", async () => removeFiles(commandPaths, { dryRun: false }), (removed) => `Removed ${removed.paths.length} command file(s) from ${dir}`);
26855
- return;
26856
- }
26857
- await ui.step(`Adding ${CARET_PACKAGE} to OpenCode's plugin array`, async () => editConfig(configFile2, (text2) => addPluginToConfigText(text2, CARET_PACKAGE)), (changed) => changed.length > 0 ? `Added ${CARET_PACKAGE} to ${basename2(configFile2)}` : `${CARET_PACKAGE} was already in ${basename2(configFile2)}`);
26858
- const files = pkg.commands.map((c3) => ({
26859
- path: join13(commandDir(dir), namespacedCommandFilename(c3.name)),
26860
- contents: renderPlugin(c3.contents, { version: VERSION, binPath: pkg.binPath })
26861
- }));
26862
- await ui.step("Deploying the /caret:* command files", async () => deployFiles(files, { dryRun: false }), (deployed) => `Deployed ${deployed.paths.length} command file(s) to ${dir}`);
26863
- }
26864
- function editConfig(path2, transform2) {
26865
- const existing = existsSync11(path2) ? readFileSync8(path2, "utf-8") : null;
26866
- const next = transform2(existing);
26867
- if (next === null || next === existing)
26868
- return [];
26869
- writeFileSync7(path2, next);
26870
- return [path2];
26871
- }
26872
-
26873
27051
  // src/commands/install/targets.ts
26874
27052
  import { existsSync as existsSync12 } from "fs";
26875
27053
  var INSTALL_TARGET_IDS = ["claude", "opencode"];
@@ -26916,6 +27094,140 @@ async function promptForTargets(detected, uninstall = false) {
26916
27094
  });
26917
27095
  return isCancel2(chosen) ? null : chosen;
26918
27096
  }
27097
+ function upgradeVerdictLine(verdict) {
27098
+ switch (verdict.kind) {
27099
+ case "fresh":
27100
+ return "OpenCode will resolve caret on its next start";
27101
+ case "current":
27102
+ return `OpenCode's caret is ${verdict.version} \u2014 already current`;
27103
+ case "stale-cache":
27104
+ return `OpenCode's cached caret is ${verdict.cached}; ${verdict.published} is published`;
27105
+ case "stale-pin":
27106
+ return `Your config pins ${verdict.entry}; ${verdict.published} is published`;
27107
+ case "unknown":
27108
+ return "Could not check which caret OpenCode would load";
27109
+ }
27110
+ }
27111
+ function upgradePromptMessage(verdict) {
27112
+ const remedy = verdict.kind === "stale-pin" ? "Bump the pin?" : "Clear the cached copy so OpenCode re-resolves?";
27113
+ return `${upgradeVerdictLine(verdict)}. ${remedy}`;
27114
+ }
27115
+ async function promptUpgrade(verdict, clack) {
27116
+ const { confirm: confirm2, isCancel: isCancel2 } = clack ?? await Promise.resolve().then(() => (init_dist4(), exports_dist));
27117
+ const answer = await confirm2({ message: upgradePromptMessage(verdict) });
27118
+ return isCancel2(answer) ? null : answer === true;
27119
+ }
27120
+
27121
+ // src/commands/install/opencode.ts
27122
+ function isCaretCheckout(dir) {
27123
+ return existsSync13(join14(dir, "opencode", "caret.plugin.ts"));
27124
+ }
27125
+ function caretEntries(text2, isCheckout) {
27126
+ return pluginEntries(text2).filter((entry) => {
27127
+ const path2 = localSpecifierPath(entry);
27128
+ return path2 === undefined ? splitPluginSpecifier(entry).pkg === CARET_PACKAGE : isCheckout(path2);
27129
+ });
27130
+ }
27131
+ function sameEntryForm(entry, specifier) {
27132
+ const entryIsLocal = isLocalPluginSpecifier(entry);
27133
+ if (entryIsLocal !== isLocalPluginSpecifier(specifier))
27134
+ return false;
27135
+ return entryIsLocal ? entry === specifier : true;
27136
+ }
27137
+ function setCaretPluginEntry(text2, specifier, isCheckout) {
27138
+ if (text2 === null)
27139
+ return addPluginToConfigText(null, specifier);
27140
+ const pruned = caretEntries(text2, isCheckout).filter((entry) => !sameEntryForm(entry, specifier)).reduce((acc, entry) => removePluginFromConfigText(acc, entry), text2);
27141
+ return addPluginToConfigText(pruned, specifier);
27142
+ }
27143
+ async function runInstallOpencodeTarget(opts, deps = {}) {
27144
+ const dir = deps.configDir ?? opencodeConfigDir();
27145
+ const pkg = deps.packaging ?? loadOpencodePackaging();
27146
+ const ui = deps.ui ?? silentUI;
27147
+ const isCheckout = deps.isCheckout ?? isCaretCheckout;
27148
+ const configFile2 = resolveConfigFile(dir);
27149
+ const commandPaths = pkg.commands.map((c3) => join14(commandDir(dir), namespacedCommandFilename(c3.name)));
27150
+ const legacy = existingLegacyInstallFiles(dir);
27151
+ const specifier = opts.local ? localPluginSpecifier(opts.local.repoDir) : CARET_PACKAGE;
27152
+ if (opts.dryRun) {
27153
+ const verb = opts.uninstall ? "remove" : "write";
27154
+ const found = checks3(opts) ? ["", previewLine(await check2(configFile2, deps))] : [];
27155
+ const entry = opts.uninstall ? [] : ["", `plugin entry: ${specifier}`];
27156
+ const sweep = legacy.length === 0 ? [] : ["", "pre-array-install files to remove:", ...legacy];
27157
+ ui.note([configFile2, ...commandPaths, ...entry, ...sweep, ...found].join(`
27158
+ `), `OpenCode \u2014 would ${verb}`);
27159
+ return;
27160
+ }
27161
+ if (opts.uninstall) {
27162
+ await ui.step("Removing caret from OpenCode's plugin array", async () => editConfig(configFile2, (text2) => text2 === null ? null : caretEntries(text2, isCheckout).reduce((acc, entry) => removePluginFromConfigText(acc, entry), text2)), (changed) => changed.length > 0 ? `Removed caret from ${basename3(configFile2)}` : `caret was not in ${basename3(configFile2)}`);
27163
+ await ui.step("Removing the /caret:* command files", async () => removeFiles(commandPaths, { dryRun: false }), (removed) => `Removed ${removed.paths.length} command file(s) from ${dir}`);
27164
+ await sweepLegacy(legacy, dir, ui);
27165
+ return;
27166
+ }
27167
+ await ui.step(`Adding ${specifier} to OpenCode's plugin array`, async () => editConfig(configFile2, (text2) => setCaretPluginEntry(text2, specifier, isCheckout)), (changed) => changed.length > 0 ? `Added ${specifier} to ${basename3(configFile2)}` : `${specifier} was already in ${basename3(configFile2)}`);
27168
+ if (checks3(opts))
27169
+ await upgradeStep(configFile2, opts, deps, ui);
27170
+ await sweepLegacy(legacy, dir, ui);
27171
+ const files = pkg.commands.map((c3) => ({
27172
+ path: join14(commandDir(dir), namespacedCommandFilename(c3.name)),
27173
+ contents: renderPlugin(c3.contents, { version: VERSION, binPath: pkg.binPath })
27174
+ }));
27175
+ await ui.step("Deploying the /caret:* command files", async () => deployFiles(files, { dryRun: false }), (deployed) => `Deployed ${deployed.paths.length} command file(s) to ${dir}`);
27176
+ }
27177
+ async function sweepLegacy(legacy, dir, ui) {
27178
+ if (legacy.length === 0)
27179
+ return;
27180
+ await ui.step("Removing the pre-array-install files", async () => removeFiles(legacy, { dryRun: false }), (removed) => `Removed ${removed.paths.length} pre-array-install file(s) from ${dir}`);
27181
+ }
27182
+ function checks3(opts) {
27183
+ return !opts.uninstall && opts.local === undefined;
27184
+ }
27185
+ function previewLine(verdict) {
27186
+ const line = upgradeVerdictLine(verdict);
27187
+ return verdict.kind === "unknown" ? `${line} (${verdict.reason})` : line;
27188
+ }
27189
+ async function check2(configFile2, deps) {
27190
+ return upgradeVerdict({
27191
+ entry: findPluginEntry(readConfigText(configFile2), CARET_PACKAGE),
27192
+ cached: readCachedCaretVersion((deps.cacheDirs ?? existingOpencodeCachePackageDirs)()),
27193
+ published: await (deps.published ?? publishedCaretVersion)()
27194
+ });
27195
+ }
27196
+ async function upgradeStep(configFile2, opts, deps, ui) {
27197
+ const verdict = await ui.step("Checking OpenCode's caret version", () => check2(configFile2, deps), upgradeVerdictLine);
27198
+ if (verdict.kind === "unknown") {
27199
+ ui.warn(`Could not check OpenCode's caret version (${verdict.reason}) \u2014 nothing changed.`);
27200
+ return;
27201
+ }
27202
+ if (verdict.kind !== "stale-cache" && verdict.kind !== "stale-pin")
27203
+ return;
27204
+ if (!opts.refresh) {
27205
+ if (!(deps.isInteractive ?? isTerminal)()) {
27206
+ const take = verdict.kind === "stale-pin" ? "bump the pin" : "take it";
27207
+ ui.info(`${upgradeVerdictLine(verdict)}. Re-run with --refresh to ${take}.`);
27208
+ return;
27209
+ }
27210
+ if (await (deps.confirm ?? promptUpgrade)(verdict) !== true)
27211
+ return;
27212
+ }
27213
+ if (verdict.kind === "stale-cache") {
27214
+ const dirs = (deps.cacheDirs ?? existingOpencodeCachePackageDirs)();
27215
+ await ui.step("Clearing OpenCode's cached caret", async () => (deps.clearCache ?? clearCachedCaret)(dirs), (cleared) => `Cleared ${cleared.length} cached ${cleared.length === 1 ? "copy" : "copies"} \u2014 OpenCode re-resolves on next start`);
27216
+ return;
27217
+ }
27218
+ await ui.step(`Bumping ${CARET_PACKAGE} to ${verdict.published}`, async () => editConfig(configFile2, (text2) => text2 === null ? null : setPluginVersionInConfigText(text2, CARET_PACKAGE, verdict.published)), (changed) => changed.length > 0 ? `Bumped the pin to ${CARET_PACKAGE}@${verdict.published}` : `Left ${basename3(configFile2)} unchanged`);
27219
+ }
27220
+ function readConfigText(path2) {
27221
+ return existsSync13(path2) ? readFileSync9(path2, "utf-8") : null;
27222
+ }
27223
+ function editConfig(path2, transform2) {
27224
+ const existing = readConfigText(path2);
27225
+ const next = transform2(existing);
27226
+ if (next === null || next === existing)
27227
+ return [];
27228
+ writeFileSync7(path2, next);
27229
+ return [path2];
27230
+ }
26919
27231
 
26920
27232
  // src/commands/install/index.ts
26921
27233
  function parseTargets(raw) {
@@ -26953,7 +27265,12 @@ async function runInstallSubcommand(opts, deps = {}) {
26953
27265
  return;
26954
27266
  const runOpencode = deps.runOpencode ?? runInstallOpencodeTarget;
26955
27267
  const runClaude = deps.runClaude ?? runInstallClaudeTarget;
26956
- const targetOpts = { uninstall: opts.uninstall, dryRun: opts.dryRun, local };
27268
+ const targetOpts = {
27269
+ uninstall: opts.uninstall,
27270
+ dryRun: opts.dryRun,
27271
+ refresh: opts.refresh ?? false,
27272
+ local
27273
+ };
26957
27274
  for (const target of targets) {
26958
27275
  let ok;
26959
27276
  try {
@@ -27040,7 +27357,7 @@ async function selectTargets(opts, deps, ui) {
27040
27357
  return parsed.targets;
27041
27358
  }
27042
27359
  const detected = (deps.detect ?? detectTargets)();
27043
- const isInteractive = deps.isInteractive ?? (() => process.stdin.isTTY === true && process.stdout.isTTY === true);
27360
+ const isInteractive = deps.isInteractive ?? isTerminal;
27044
27361
  if (isInteractive() && !opts.dryRun) {
27045
27362
  const chosen = await (deps.prompt ?? promptForTargets)(detected, opts.uninstall);
27046
27363
  if (chosen === null) {
@@ -28546,7 +28863,7 @@ async function runReview(stdin2, deps) {
28546
28863
  if (err instanceof TimeoutError)
28547
28864
  throw err;
28548
28865
  step = "reconnect";
28549
- baseUrl = await deps.ensureDaemon();
28866
+ baseUrl = await deps.ensureDaemon({ takeover: false });
28550
28867
  step = "longPoll";
28551
28868
  }
28552
28869
  }
@@ -28585,7 +28902,7 @@ function openBrowser(url2) {
28585
28902
  function prodReviewDeps(s, adapter) {
28586
28903
  return {
28587
28904
  parseHookInput: (stdin2) => adapter.parseHookInput(stdin2),
28588
- ensureDaemon: async () => ensureDaemon(await prodEnsureDeps(s)),
28905
+ ensureDaemon: async (opts) => ensureDaemon(await prodEnsureDeps(s), opts),
28589
28906
  postReview,
28590
28907
  longPoll,
28591
28908
  openBrowser,
@@ -30696,10 +31013,11 @@ function buildProgram() {
30696
31013
  program2.command("reconcile").description("reconcile a terminal plan approval into the daemon (ExitPlanMode PostToolUse hook)").action(() => runReconcileSubcommand());
30697
31014
  program2.command("redact").description("write redacted copies of the logs").action(() => runRedactSubcommand());
30698
31015
  program2.command("discovery").description("print a diagnostics report").option("--json", "emit the machine-readable JSON document").action((opts) => runDiscoverySubcommand({ json: opts.json ?? false }));
30699
- program2.command("install").description("install caret into a coding agent, plus the rumdl plan formatter (omit --target to choose interactively)").option("--target <targets>", "comma-separated agents to install into: opencode, claude, or opencode,claude").option("--uninstall", "remove caret from the target(s) instead of installing").option("--dry-run", "print what would change without writing").option("--from-local", "dev loop: install the built caret checkout this binary runs from, then hand it the daemon").action((opts) => runInstallSubcommand({
31016
+ program2.command("install").description("install caret into a coding agent, plus the rumdl plan formatter (omit --target to choose interactively)").option("--target <targets>", "comma-separated agents to install into: opencode, claude, or opencode,claude").option("--uninstall", "remove caret from the target(s) instead of installing").option("--dry-run", "print what would change without writing").option("--refresh", "take the published caret in every target without asking \u2014 clears OpenCode's cached copy, or bumps a pinned entry (Claude Code always takes an update)").option("--from-local", "dev loop: install the built caret checkout this binary runs from, then hand it the daemon").action((opts) => runInstallSubcommand({
30700
31017
  target: opts.target,
30701
31018
  uninstall: opts.uninstall ?? false,
30702
31019
  dryRun: opts.dryRun ?? false,
31020
+ refresh: opts.refresh ?? false,
30703
31021
  fromLocal: opts.fromLocal ?? false
30704
31022
  }));
30705
31023
  return program2;