@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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +16 -5
- package/dist/cli.js +560 -242
- package/opencode/caret.plugin.ts +91 -30
- package/package.json +1 -1
- package/ui/dist/assets/{angular-html-BKAxvPIm.js → angular-html-BOjikgNB.js} +1 -1
- package/ui/dist/assets/{angular-ts-BTws7Hd_.js → angular-ts-BjxNvVmD.js} +1 -1
- package/ui/dist/assets/{apl-JlctHwEB.js → apl-BkiW4daM.js} +1 -1
- package/ui/dist/assets/{astro-db0B6jhI.js → astro-3adpTlIH.js} +1 -1
- package/ui/dist/assets/{blade-CeLm7ibc.js → blade-DPTGWOFi.js} +1 -1
- package/ui/dist/assets/{c-BiR9gE2S.js → c-Gr6AqmnN.js} +1 -1
- package/ui/dist/assets/{cobol-B8bx-sRj.js → cobol-C8hrPk4X.js} +1 -1
- package/ui/dist/assets/{coffee-CGdE90Vi.js → coffee-COAUS6hR.js} +1 -1
- package/ui/dist/assets/{cpp-DkHVqrL7.js → cpp-DRNHed7s.js} +1 -1
- package/ui/dist/assets/{crystal-lJ6f8uow.js → crystal-xGCPBQ2Z.js} +1 -1
- package/ui/dist/assets/{css-Cuixf2-q.js → css-g3rqYwXR.js} +1 -1
- package/ui/dist/assets/{dist-C0wLz8-w.js → dist--Ppdbw_u.js} +1 -1
- package/ui/dist/assets/{dist-BeZiUXBO.js → dist-ALQWrgOU.js} +1 -1
- package/ui/dist/assets/{dist-7sSi10pU.js → dist-B0fJR4WS.js} +1 -1
- package/ui/dist/assets/{dist-BJ5lZ2OR.js → dist-B3rxpa4n.js} +1 -1
- package/ui/dist/assets/{dist-sZOQfyQ_.js → dist-B57N0_ad.js} +1 -1
- package/ui/dist/assets/{dist-DSqn_Y_F.js → dist-B8chzuGI.js} +1 -1
- package/ui/dist/assets/{dist-FJ3OQ5zZ.js → dist-Baejo1Q0.js} +1 -1
- package/ui/dist/assets/{dist-CYAIY__V.js → dist-BeBmdH90.js} +1 -1
- package/ui/dist/assets/{dist-ClyhZj-J.js → dist-BtEZoKjT.js} +1 -1
- package/ui/dist/assets/{dist-D80FK4KE.js → dist-CbLm1gmp.js} +1 -1
- package/ui/dist/assets/{dist-hZtmZorK.js → dist-CqeZRBk3.js} +1 -1
- package/ui/dist/assets/{dist-CRGmZgdx.js → dist-D55VuegY.js} +1 -1
- package/ui/dist/assets/{dist-BXa1PZK8.js → dist-D8G49gMQ.js} +1 -1
- package/ui/dist/assets/{dist-DEkqXBbt.js → dist-DAyUKqoN.js} +1 -1
- package/ui/dist/assets/{dist-CiOYdD34.js → dist-DGuk1LV9.js} +1 -1
- package/ui/dist/assets/{dist-B0RCUsKg.js → dist-DPkspc9Q.js} +1 -1
- package/ui/dist/assets/{dist-BWn8_3c2.js → dist-ekL3xCM_.js} +1 -1
- package/ui/dist/assets/{edge-DF1cr81u.js → edge-1tf_B5nG.js} +1 -1
- package/ui/dist/assets/{elixir-71c6h9Ri.js → elixir-Ca3rBU7D.js} +1 -1
- package/ui/dist/assets/{elm-BSWMNwTH.js → elm-CbkPZkSz.js} +1 -1
- package/ui/dist/assets/{erb-DL0d5EiM.js → erb-DV7pKwEX.js} +1 -1
- package/ui/dist/assets/{git-rebase-CySRZDuc.js → git-rebase-DItBLEqi.js} +1 -1
- package/ui/dist/assets/{glimmer-js-eROyzkAo.js → glimmer-js-CAykgXKb.js} +1 -1
- package/ui/dist/assets/{glimmer-ts-CDYBP3ca.js → glimmer-ts-BPT-EGHX.js} +1 -1
- package/ui/dist/assets/{glsl-CZPp7InQ.js → glsl-CMfWGTLW.js} +1 -1
- package/ui/dist/assets/{graphql-VnzRM8lu.js → graphql-CR_NOWo2.js} +1 -1
- package/ui/dist/assets/{hack-B2Ad61Yp.js → hack-BWP6dwsC.js} +1 -1
- package/ui/dist/assets/{haml-D_aPEilH.js → haml-CDa-RN50.js} +1 -1
- package/ui/dist/assets/{handlebars-CaNTUlW9.js → handlebars-sJHLZ5A7.js} +1 -1
- package/ui/dist/assets/{html-BBxxOqkf.js → html-63fn47vQ.js} +1 -1
- package/ui/dist/assets/{html-derivative-qfdNd7Ig.js → html-derivative-BXnhYyFs.js} +1 -1
- package/ui/dist/assets/{http-B3Fs1J8E.js → http-IOW0RfUa.js} +1 -1
- package/ui/dist/assets/{hurl-1_d5iFYp.js → hurl-CTSYkbKC.js} +1 -1
- package/ui/dist/assets/index-B-GFE-1x.css +1 -0
- package/ui/dist/assets/{index-DlSszbQY.js → index-CtmSI3Ho.js} +171 -132
- package/ui/dist/assets/{java-Dns-uIyX.js → java-DOX-o9K8.js} +1 -1
- package/ui/dist/assets/{javascript-BkvJR4Ak.js → javascript-NWcTx9fC.js} +1 -1
- package/ui/dist/assets/{jinja-xjBAgjJd.js → jinja-TT5Clkg-.js} +1 -1
- package/ui/dist/assets/{jison-cIldhYjc.js → jison-DoZAP4a3.js} +1 -1
- package/ui/dist/assets/{json-D1TV_MA9.js → json-Dd1DbJZw.js} +1 -1
- package/ui/dist/assets/{jsx-D0sju--k.js → jsx-D95PvYev.js} +1 -1
- package/ui/dist/assets/{julia-BtKmWBHV.js → julia-DzNcHVqx.js} +1 -1
- package/ui/dist/assets/{just-C_ahnckv.js → just-DapN_z3p.js} +1 -1
- package/ui/dist/assets/{latex-jGkpHz-Q.js → latex-Bf3O2fQb.js} +1 -1
- package/ui/dist/assets/{liquid-BCx1Z1yo.js → liquid-NXRAWoEl.js} +1 -1
- package/ui/dist/assets/{lua-C05Cq4kC.js → lua-DgnpxH9p.js} +1 -1
- package/ui/dist/assets/{marko-DSlNWh3P.js → marko-wkWPjoQ9.js} +1 -1
- package/ui/dist/assets/{mdc-OEBu9A0B.js → mdc-DtOun-X2.js} +1 -1
- package/ui/dist/assets/{nginx-C1aCdDVd.js → nginx-XCdDX9Gp.js} +1 -1
- package/ui/dist/assets/{nim-DyogFwyD.js → nim-CnDu2vnO.js} +1 -1
- package/ui/dist/assets/{perl-Cq7AUp25.js → perl-mCSP7zn3.js} +1 -1
- package/ui/dist/assets/{php-ZsSMpvwe.js → php-CnDYV7m9.js} +1 -1
- package/ui/dist/assets/{pug-CXpvWTPP.js → pug-DUv1_GFU.js} +1 -1
- package/ui/dist/assets/{qml-GHV7U9Iz.js → qml-Cw49qsJy.js} +1 -1
- package/ui/dist/assets/{r-ZPvQYZrP.js → r-DUSb08Z8.js} +1 -1
- package/ui/dist/assets/{razor-Dbcx8YhK.js → razor-CKco3Dbd.js} +1 -1
- package/ui/dist/assets/{regexp-DkIUUpmd.js → regexp-DbjqCAsi.js} +1 -1
- package/ui/dist/assets/{rst-Bu5XaW3b.js → rst-iLrpHokU.js} +1 -1
- package/ui/dist/assets/{ruby-C9oSZU7n.js → ruby-BBYneGfk.js} +1 -1
- package/ui/dist/assets/{sas-BCxfFQA2.js → sas-DoS0TCZm.js} +1 -1
- package/ui/dist/assets/{scss-B3Yk29WR.js → scss-DwjazCIb.js} +1 -1
- package/ui/dist/assets/{shellscript-D8gXEcYe.js → shellscript-bR-cjL3L.js} +1 -1
- package/ui/dist/assets/{shellsession-D77yCV20.js → shellsession-D54KuySr.js} +1 -1
- package/ui/dist/assets/{soy-CprWnkpt.js → soy-QeEusSoH.js} +1 -1
- package/ui/dist/assets/{sql-CIQipKVb.js → sql-BjJgWH0F.js} +1 -1
- package/ui/dist/assets/{stata-B10L7ajY.js → stata---E5T02y.js} +1 -1
- package/ui/dist/assets/{surrealql-DpM6G529.js → surrealql-B3nSLmva.js} +1 -1
- package/ui/dist/assets/{svelte-CF0XZujx.js → svelte-BrJnUGsO.js} +1 -1
- package/ui/dist/assets/{templ-FAVfFvOb.js → templ-Cp6BywaR.js} +1 -1
- package/ui/dist/assets/{tex-Bk_ASCGx.js → tex-yFYe_F-5.js} +1 -1
- package/ui/dist/assets/{ts-tags-Z2hr36mA.js → ts-tags-Dn1XZNS9.js} +1 -1
- package/ui/dist/assets/{tsx-Dg-3IW-0.js → tsx-BnhO4Hkv.js} +1 -1
- package/ui/dist/assets/{twig-CAfYLJ73.js → twig-B-zB3u-Z.js} +1 -1
- package/ui/dist/assets/{typescript-CuQC_OIP.js → typescript-D49Rl_Ln.js} +1 -1
- package/ui/dist/assets/{vue-DjlgTag0.js → vue-DmTXiGeI.js} +1 -1
- package/ui/dist/assets/{vue-html-car_Y-EZ.js → vue-html-CeXpHptR.js} +1 -1
- package/ui/dist/assets/{vue-vine-ClPFRhPz.js → vue-vine-C2uWvGRx.js} +1 -1
- package/ui/dist/assets/{xml-CJiqUkS6.js → xml-SZiG-U1T.js} +1 -1
- package/ui/dist/assets/{xsl-DoOf1m_u.js → xsl-DksAOCj6.js} +1 -1
- package/ui/dist/assets/{yaml-C8DZp3NU.js → yaml-DX7HDqJF.js} +1 -1
- package/ui/dist/index.html +2 -2
- 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:
|
|
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"] ||
|
|
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:
|
|
2511
|
+
var { existsSync: existsSync4 } = __require("fs");
|
|
2512
2512
|
var getCallers = require_caller();
|
|
2513
|
-
var { join:
|
|
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) && !
|
|
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"] ||
|
|
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"] ||
|
|
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
|
|
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
|
|
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
|
-
|
|
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 +=
|
|
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 += `${
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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 +=
|
|
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 += `${
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 +=
|
|
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 += `${
|
|
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
|
|
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,
|
|
3885
|
+
res += stringifyTypedArray(value, join7, maximumBreadth);
|
|
3886
3886
|
keys = keys.slice(value.length);
|
|
3887
3887
|
maximumPropertiesToStringify -= value.length;
|
|
3888
|
-
separator =
|
|
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 =
|
|
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 =
|
|
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
|
|
5807
|
-
import { dirname as
|
|
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
|
-
|
|
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
|
|
6521
|
-
const 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
|
|
8252
|
-
import { join as
|
|
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
|
-
|
|
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
|
-
|
|
9609
|
-
|
|
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 (!
|
|
9797
|
+
if (!existsSync3(dir)) {
|
|
9616
9798
|
return { pluginVersion: "unknown", pluginEnabled: "unknown", hookInUserSettings: "unknown" };
|
|
9617
9799
|
}
|
|
9618
|
-
const
|
|
9800
|
+
const version = readCachedCaretVersion(existingOpencodeCachePackageDirs()) ?? "unknown";
|
|
9619
9801
|
return {
|
|
9620
|
-
pluginVersion:
|
|
9621
|
-
pluginEnabled:
|
|
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 =
|
|
9637
|
-
if (!
|
|
9810
|
+
const path = join5(dir, name);
|
|
9811
|
+
if (!existsSync3(path))
|
|
9638
9812
|
continue;
|
|
9639
9813
|
let cfg;
|
|
9640
9814
|
try {
|
|
9641
|
-
cfg = parse3(
|
|
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
|
|
9896
|
+
import { existsSync as existsSync6, unlinkSync as unlinkSync3 } from "fs";
|
|
9723
9897
|
|
|
9724
9898
|
// src/config/settings.ts
|
|
9725
|
-
import { readFileSync as
|
|
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
|
|
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
|
|
24085
|
-
const full =
|
|
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
|
|
24107
|
-
|
|
24108
|
-
|
|
24109
|
-
|
|
24110
|
-
|
|
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.
|
|
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
|
|
24280
|
-
var PKG_ROOT =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
25047
|
-
import { extname, isAbsolute, join as
|
|
25048
|
-
var EXCERPT_RADIUS =
|
|
25049
|
-
var EXCERPT_HEAD_LINES =
|
|
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 =
|
|
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
|
|
25326
|
+
return join7(currentDir, entry.name);
|
|
25143
25327
|
} else if (entry.isDirectory() && !SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
25144
|
-
queue.push(
|
|
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
|
|
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 =
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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
|
|
25288
|
-
var RUMDL_VERSION = "0.2.
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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(
|
|
25527
|
+
const work = await mkdtemp(join8(tmpdir(), "caret-rumdl-"));
|
|
25329
25528
|
try {
|
|
25330
|
-
const archive =
|
|
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 =
|
|
25336
|
-
if (!
|
|
25534
|
+
const extracted = join8(work, "rumdl");
|
|
25535
|
+
if (!existsSync5(extracted))
|
|
25337
25536
|
throw new Error(`rumdl: binary not found in ${asset.url}`);
|
|
25338
|
-
mkdirSync2(
|
|
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 (!
|
|
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
|
|
25748
|
-
|
|
25749
|
-
|
|
25750
|
-
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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",
|
|
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: () =>
|
|
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
|
|
26349
|
+
import { existsSync as existsSync7 } from "fs";
|
|
26140
26350
|
import { release } from "os";
|
|
26141
26351
|
|
|
26142
26352
|
// src/discovery.ts
|
|
26143
|
-
import { readdirSync as
|
|
26144
|
-
import { basename, join as
|
|
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 =
|
|
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 =
|
|
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(
|
|
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: () =>
|
|
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
|
|
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
|
|
26672
|
+
import { join as join12, resolve as resolve2 } from "path";
|
|
26463
26673
|
|
|
26464
26674
|
// src/adapters/opencode/packaging.ts
|
|
26465
|
-
import { existsSync as
|
|
26466
|
-
import { dirname as
|
|
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(
|
|
26472
|
-
candidates.push(
|
|
26681
|
+
candidates.push(join11(dirname7(script), ".."));
|
|
26682
|
+
candidates.push(join11(dirname7(process.execPath), ".."));
|
|
26473
26683
|
for (const root of candidates) {
|
|
26474
|
-
if (
|
|
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 =
|
|
26481
|
-
const commandsDir =
|
|
26690
|
+
const binPath = join11(root, "bin", "caret");
|
|
26691
|
+
const commandsDir = join11(root, "opencode", "commands");
|
|
26482
26692
|
let commands = [];
|
|
26483
26693
|
try {
|
|
26484
|
-
commands =
|
|
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
|
|
26703
|
+
return join12(stateDir(), "dev-marketplace");
|
|
26494
26704
|
}
|
|
26495
26705
|
function resolveLocalCheckout(opts = {}, deps = {}) {
|
|
26496
26706
|
const repoDir = resolve2(caretRoot(deps));
|
|
26497
|
-
if (!
|
|
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(
|
|
26503
|
-
isDirectory(
|
|
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
|
-
|
|
26522
|
-
mkdirSync3(
|
|
26523
|
-
symlinkSync(resolve2(repoDir),
|
|
26524
|
-
writeFileSync5(
|
|
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([
|
|
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([
|
|
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: [
|
|
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
|
-
|
|
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
|
|
26762
|
-
import { basename as
|
|
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
|
|
26812
|
-
import { dirname as
|
|
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(
|
|
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 (!
|
|
27042
|
+
if (!existsSync11(p3))
|
|
26831
27043
|
continue;
|
|
26832
27044
|
if (!opts.dryRun)
|
|
26833
|
-
|
|
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 = {
|
|
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 ??
|
|
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;
|