@macintacos/caret 0.13.0 → 0.14.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 (93) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +13 -0
  3. package/dist/cli.js +350 -118
  4. package/package.json +1 -1
  5. package/ui/dist/assets/{angular-html-JsdW_WcC.js → angular-html-C0XElF0f.js} +1 -1
  6. package/ui/dist/assets/{angular-ts-DB5trF48.js → angular-ts-BVnV1Yg5.js} +1 -1
  7. package/ui/dist/assets/{apl-BHONMsFL.js → apl-BFyMAB9c.js} +1 -1
  8. package/ui/dist/assets/{astro-Ds0Hdj6N.js → astro-DAtaAFYq.js} +1 -1
  9. package/ui/dist/assets/{blade-u3yPcwZm.js → blade-BoZH76v_.js} +1 -1
  10. package/ui/dist/assets/{c-DrTWjY43.js → c-DyRawzd0.js} +1 -1
  11. package/ui/dist/assets/{chapel-BQ3j01mw.js → chapel-CAaCMdek.js} +1 -1
  12. package/ui/dist/assets/{cobol-CYMPXcxw.js → cobol-BjXiLsat.js} +1 -1
  13. package/ui/dist/assets/{coffee-BTAQjKY2.js → coffee-DvjcTlIE.js} +1 -1
  14. package/ui/dist/assets/{cpp-Bi8OcMQs.js → cpp-sRP7rZGr.js} +1 -1
  15. package/ui/dist/assets/{crystal-BeA91aRl.js → crystal-CaRkbKnA.js} +1 -1
  16. package/ui/dist/assets/{css-Bxrmub2j.js → css-Igh3vvbt.js} +1 -1
  17. package/ui/dist/assets/{dist-ChMSH6xV.js → dist-B5Dwvt_o.js} +1 -1
  18. package/ui/dist/assets/{dist-DqAJNUky.js → dist-BdaKUV8X.js} +1 -1
  19. package/ui/dist/assets/{dist-DH1_ZbAP.js → dist-BkB3Dkvt.js} +1 -1
  20. package/ui/dist/assets/{dist-C5v67AiS.js → dist-CF48ImGm.js} +1 -1
  21. package/ui/dist/assets/{dist-CR6NZa0h.js → dist-CF4FIhxu.js} +1 -1
  22. package/ui/dist/assets/{dist-Bz_ap3g2.js → dist-CYIXdHF6.js} +1 -1
  23. package/ui/dist/assets/{dist-sQ_pTc4a.js → dist-CZeI5UV9.js} +1 -1
  24. package/ui/dist/assets/{dist-DQgprm5S.js → dist-D4FUs8dC.js} +1 -1
  25. package/ui/dist/assets/{dist-IqwiD_4c.js → dist-YE9up3VR.js} +1 -1
  26. package/ui/dist/assets/{dist-B0Do-tNS.js → dist-lE2sJQyW.js} +1 -1
  27. package/ui/dist/assets/{edge-CM4DKqp3.js → edge-CvHTOXgI.js} +1 -1
  28. package/ui/dist/assets/{elixir-D76HLRzC.js → elixir-CtokNUaA.js} +1 -1
  29. package/ui/dist/assets/{elm-BYD2LdpG.js → elm-B34p-CC5.js} +1 -1
  30. package/ui/dist/assets/{erb-Depv6q0i.js → erb-FjaGN5LV.js} +1 -1
  31. package/ui/dist/assets/{git-rebase-By6KsZra.js → git-rebase-BFUCuD7O.js} +1 -1
  32. package/ui/dist/assets/{glimmer-js-B9OgS597.js → glimmer-js-CRs6sgzF.js} +1 -1
  33. package/ui/dist/assets/{glimmer-ts-BQ9yXV5i.js → glimmer-ts-Bkt0v-q2.js} +1 -1
  34. package/ui/dist/assets/{glsl-CgWn_pPL.js → glsl-Ckh3d22M.js} +1 -1
  35. package/ui/dist/assets/{graphql-C6705FXv.js → graphql-IqxoIj3x.js} +1 -1
  36. package/ui/dist/assets/{hack-CuMDN2go.js → hack-DG1p8zpS.js} +1 -1
  37. package/ui/dist/assets/{haml-BiSYPvKJ.js → haml-DA2jQcOV.js} +1 -1
  38. package/ui/dist/assets/{handlebars-C1r5dETi.js → handlebars-CqT0epoo.js} +1 -1
  39. package/ui/dist/assets/{html-iBfWgjFQ.js → html-CoTd-Axz.js} +1 -1
  40. package/ui/dist/assets/{html-derivative-clnDfVNs.js → html-derivative-DDt5A1xL.js} +1 -1
  41. package/ui/dist/assets/{http-hT30HceR.js → http-TEp9u8BR.js} +1 -1
  42. package/ui/dist/assets/{hurl-DQ0AcU20.js → hurl-OLD-GtJJ.js} +1 -1
  43. package/ui/dist/assets/{index-CjqVXWlr.js → index-BucWCjoT.js} +209 -209
  44. package/ui/dist/assets/index-Djrj2rps.css +1 -0
  45. package/ui/dist/assets/{java-Dm4xXBhF.js → java-DYZ_BnxQ.js} +1 -1
  46. package/ui/dist/assets/{javascript-PW_29aC7.js → javascript-B4vvB79r.js} +1 -1
  47. package/ui/dist/assets/{jinja-grwkrR8u.js → jinja-BTulBbvB.js} +1 -1
  48. package/ui/dist/assets/{jison-DFY8lcfy.js → jison-CDVJmcGj.js} +1 -1
  49. package/ui/dist/assets/{json-C34uLNh4.js → json-DahQZwqh.js} +1 -1
  50. package/ui/dist/assets/{jsx-CWBlf8VC.js → jsx-Dzcw0XhS.js} +1 -1
  51. package/ui/dist/assets/{julia-DCj8-aMw.js → julia-BB_aSeOr.js} +1 -1
  52. package/ui/dist/assets/{just-B_yigvdA.js → just-C3IsNIar.js} +1 -1
  53. package/ui/dist/assets/{latex-QDkoREbu.js → latex-D7dYt9yW.js} +1 -1
  54. package/ui/dist/assets/{liquid-BgxQ_Ybv.js → liquid-CO9g2vFd.js} +1 -1
  55. package/ui/dist/assets/{lua-B7jopNUe.js → lua-D6OK3PTP.js} +1 -1
  56. package/ui/dist/assets/{marko-ClWMCpy4.js → marko-YPWiYUQ_.js} +1 -1
  57. package/ui/dist/assets/{mdc-B5qjhcv5.js → mdc-DoQ9fqeC.js} +1 -1
  58. package/ui/dist/assets/{nginx-BLvCl2vo.js → nginx-BuX_dG5x.js} +1 -1
  59. package/ui/dist/assets/{nim-D1vVna5G.js → nim-oEF2CEaX.js} +1 -1
  60. package/ui/dist/assets/{org-CQUu5Xjo.js → org-C1kwr3b8.js} +1 -1
  61. package/ui/dist/assets/{perl-Cn9pqCpd.js → perl-CzZcVIM9.js} +1 -1
  62. package/ui/dist/assets/{php-DQA4j1w3.js → php-C_i1TWmy.js} +1 -1
  63. package/ui/dist/assets/{pug-Dcu9qjZu.js → pug-Oz2JZVGZ.js} +1 -1
  64. package/ui/dist/assets/{qml-CFaCL8zR.js → qml-DWZFG7aa.js} +1 -1
  65. package/ui/dist/assets/{r-BeWyCF96.js → r-CKwXeGZ_.js} +1 -1
  66. package/ui/dist/assets/{razor-DhTjYPP2.js → razor-DT1mg2x6.js} +1 -1
  67. package/ui/dist/assets/{regexp-BZBzV8k3.js → regexp-C2K6ptTb.js} +1 -1
  68. package/ui/dist/assets/{rst-CPeugCoY.js → rst-C5gmF0mo.js} +1 -1
  69. package/ui/dist/assets/{ruby-S1Kev63y.js → ruby-CrEJdgPT.js} +1 -1
  70. package/ui/dist/assets/{sas-DzuTM5FV.js → sas-D1TGFNd_.js} +1 -1
  71. package/ui/dist/assets/{scss-CimGOfjN.js → scss-DBO_Sp1C.js} +1 -1
  72. package/ui/dist/assets/{shellscript-BTeF_2ej.js → shellscript-QIWVo1P5.js} +1 -1
  73. package/ui/dist/assets/{shellsession-DFdgXQ-h.js → shellsession-iBMCyJwd.js} +1 -1
  74. package/ui/dist/assets/{soy-CJHYVIlT.js → soy-NHBvJjBh.js} +1 -1
  75. package/ui/dist/assets/{sql-HmJC1LPx.js → sql-Yf21hpnW.js} +1 -1
  76. package/ui/dist/assets/{stata-C1JKV9ST.js → stata-CluZWHbV.js} +1 -1
  77. package/ui/dist/assets/{surrealql-DdWTVOJW.js → surrealql-Bu2dU1Qj.js} +1 -1
  78. package/ui/dist/assets/{svelte-B3DUwjVb.js → svelte-Owb3qG7g.js} +1 -1
  79. package/ui/dist/assets/{templ-Dx_nsS-N.js → templ-DScnsiaP.js} +1 -1
  80. package/ui/dist/assets/{tex-BHbvXPLE.js → tex-DvCQ8DJI.js} +1 -1
  81. package/ui/dist/assets/{ts-tags-BV7lCDbe.js → ts-tags-Fh6nOEbM.js} +1 -1
  82. package/ui/dist/assets/{tsx-BYZjS03A.js → tsx-C_2AyD6m.js} +1 -1
  83. package/ui/dist/assets/{twig-DAWYqd9-.js → twig-DjT0rOpv.js} +1 -1
  84. package/ui/dist/assets/{typescript-BBlnjAR4.js → typescript-NDIZTg4J.js} +1 -1
  85. package/ui/dist/assets/{typst-BHcXb2UY.js → typst-DNJZJFvq.js} +1 -1
  86. package/ui/dist/assets/{vue-YvTBU6lw.js → vue-BTZXwXJ_.js} +1 -1
  87. package/ui/dist/assets/{vue-html-Dy8_dd5p.js → vue-html-CBhLp-FO.js} +1 -1
  88. package/ui/dist/assets/{vue-vine-BLSdEcQ9.js → vue-vine-KGJI1qvi.js} +1 -1
  89. package/ui/dist/assets/{xml-DEOP2atk.js → xml-CeV6vl7T.js} +1 -1
  90. package/ui/dist/assets/{xsl-D__kBjbu.js → xsl-CibkluSG.js} +1 -1
  91. package/ui/dist/assets/{yaml-D2r1aQ0B.js → yaml-D89KUdIt.js} +1 -1
  92. package/ui/dist/index.html +2 -2
  93. package/ui/dist/assets/index-Dn0ZHhG9.css +0 -1
package/dist/cli.js CHANGED
@@ -5804,7 +5804,7 @@ __export(exports_dist, {
5804
5804
  import { styleText as styleText2, stripVTControlCharacters } from "util";
5805
5805
  import process$1 from "process";
5806
5806
  import { existsSync as existsSync11, lstatSync, readdirSync as readdirSync6 } from "fs";
5807
- import { dirname as dirname8, join as join17 } from "path";
5807
+ import { dirname as dirname9, join as join17 } from "path";
5808
5808
  function isUnicodeSupported() {
5809
5809
  if (process$1.platform !== "win32") {
5810
5810
  return process$1.env.TERM !== "linux";
@@ -6515,7 +6515,7 @@ ${n3}
6515
6515
  return [];
6516
6516
  try {
6517
6517
  let i;
6518
- existsSync11(t2) ? lstatSync(t2).isDirectory() && (!e.directory || t2.endsWith("/")) ? i = t2 : i = dirname8(t2) : i = dirname8(t2);
6518
+ existsSync11(t2) ? lstatSync(t2).isDirectory() && (!e.directory || t2.endsWith("/")) ? i = t2 : i = dirname9(t2) : i = dirname9(t2);
6519
6519
  const c2 = t2.length > 1 && t2.endsWith("/") ? t2.slice(0, -1) : t2;
6520
6520
  return readdirSync6(i).map((r2) => {
6521
6521
  const n3 = join17(i, r2), m3 = lstatSync(n3);
@@ -9841,9 +9841,7 @@ function removePluginFromConfigText(existing, pkg) {
9841
9841
  return applyEdits(existing, edits);
9842
9842
  }
9843
9843
 
9844
- // src/adapters/opencode/upgrade.ts
9845
- var NPM_LATEST_URL = `https://registry.npmjs.org/${CARET_PACKAGE}/latest`;
9846
- var NPM_TIMEOUT_MS = 3000;
9844
+ // src/lib/semver.ts
9847
9845
  function parseVersionTriple(v) {
9848
9846
  const m = v.trim().replace(/^v/, "").match(/^(\d+)\.(\d+)\.(\d+)/);
9849
9847
  return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
@@ -9861,6 +9859,8 @@ function isNewer(latest, current) {
9861
9859
  return a1 > b1;
9862
9860
  return a2 > b2;
9863
9861
  }
9862
+
9863
+ // src/adapters/opencode/upgrade.ts
9864
9864
  function upgradeVerdict(input) {
9865
9865
  const { entry, cached, published } = input;
9866
9866
  if (published === null) {
@@ -9903,18 +9903,6 @@ function clearCachedCaret(dirs = existingOpencodeCachePackageDirs()) {
9903
9903
  }
9904
9904
  return cleared;
9905
9905
  }
9906
- async function publishedCaretVersion(fetchImpl = fetch) {
9907
- try {
9908
- const res = await fetchImpl(NPM_LATEST_URL, { signal: AbortSignal.timeout(NPM_TIMEOUT_MS) });
9909
- if (!res.ok)
9910
- return null;
9911
- const body = await res.json();
9912
- const v = body?.version;
9913
- return typeof v === "string" && v.length > 0 ? v : null;
9914
- } catch {
9915
- return null;
9916
- }
9917
- }
9918
9906
 
9919
9907
  // src/adapters/opencode/install.ts
9920
9908
  function readOpencodeInstallState() {
@@ -10051,7 +10039,7 @@ function fatalDeny(reason) {
10051
10039
 
10052
10040
  // src/commands/daemon.ts
10053
10041
  import { randomUUID } from "crypto";
10054
- import { existsSync as existsSync7, unlinkSync as unlinkSync4 } from "fs";
10042
+ import { existsSync as existsSync7 } from "fs";
10055
10043
 
10056
10044
  // src/config/settings.ts
10057
10045
  import { readFileSync as readFileSync7, statSync as statSync2 } from "fs";
@@ -24435,6 +24423,9 @@ function configFile() {
24435
24423
  function prefsFile() {
24436
24424
  return `${stateDir()}/prefs.json`;
24437
24425
  }
24426
+ function updateCheckFile() {
24427
+ return `${stateDir()}/update-check.json`;
24428
+ }
24438
24429
  function logsDir() {
24439
24430
  return `${stateDir()}/logs`;
24440
24431
  }
@@ -24535,7 +24526,7 @@ async function loadUiAssets() {
24535
24526
  // package.json
24536
24527
  var package_default = {
24537
24528
  name: "@macintacos/caret",
24538
- version: "0.13.0",
24529
+ version: "0.14.0",
24539
24530
  license: "MIT",
24540
24531
  type: "module",
24541
24532
  description: "A Claude Code plugin that replaces the terminal plan-approval prompt with a local web UI for inline review, annotation, and approval.",
@@ -25241,6 +25232,53 @@ function warnInvalidEnvVars(warn) {
25241
25232
  warn(`${name} invalid; using config/default`);
25242
25233
  }
25243
25234
 
25235
+ // src/config/prefs.ts
25236
+ import { readFile as readFile3, writeFile } from "fs/promises";
25237
+ import { dirname as dirname4 } from "path";
25238
+ var DEFAULT_SET = { valid: ["default"], fallback: "default" };
25239
+ async function readApproveMode(file2 = prefsFile(), log = noopLogger, set2 = DEFAULT_SET) {
25240
+ try {
25241
+ const parsed = JSON.parse(await readFile3(file2, "utf-8"));
25242
+ if (typeof parsed.approveMode === "string" && set2.valid.includes(parsed.approveMode)) {
25243
+ return parsed.approveMode;
25244
+ }
25245
+ log.debug("prefs", "unrecognized approve mode; using default");
25246
+ return set2.fallback;
25247
+ } catch (err) {
25248
+ const absent = err?.code === "ENOENT";
25249
+ log.debug("prefs", absent ? "no prefs file; using default approve mode" : "prefs unreadable; using default approve mode");
25250
+ return set2.fallback;
25251
+ }
25252
+ }
25253
+ async function readUpdatesCheck(file2 = prefsFile()) {
25254
+ const parsed = await readJsonFile(file2);
25255
+ return parsed?.updates?.check !== false;
25256
+ }
25257
+ function createPrefsWriter(file2 = prefsFile()) {
25258
+ let tail = Promise.resolve();
25259
+ return {
25260
+ merge(patch) {
25261
+ const next = tail.then(async () => {
25262
+ ensureStateDir(dirname4(file2));
25263
+ const existing = await readJsonFile(file2) ?? {};
25264
+ await writeFile(file2, JSON.stringify({ ...existing, ...patch }, null, 2), {
25265
+ mode: 384
25266
+ });
25267
+ });
25268
+ tail = next.catch(() => {});
25269
+ return next;
25270
+ }
25271
+ };
25272
+ }
25273
+ async function writeApproveMode(mode, writer, log = noopLogger, set2 = DEFAULT_SET) {
25274
+ if (!set2.valid.includes(mode)) {
25275
+ log.warn("prefs", "ignoring invalid approve mode");
25276
+ return;
25277
+ }
25278
+ await writer.merge({ approveMode: mode });
25279
+ log.debug("prefs", `approve mode saved: ${mode}`);
25280
+ }
25281
+
25244
25282
  // src/daemon/diagnostics.ts
25245
25283
  function buildDiagnostics(deps) {
25246
25284
  return {
@@ -25393,6 +25431,10 @@ function removeDaemonLock() {
25393
25431
  unlinkSync2(daemonLock());
25394
25432
  } catch {}
25395
25433
  }
25434
+ function removeOwnDaemonLock() {
25435
+ if (readDaemonLock()?.pid === process.pid)
25436
+ removeDaemonLock();
25437
+ }
25396
25438
  async function retireDaemon(baseUrl, lock, currentStateDir, kill = (pid, sig) => process.kill(pid, sig)) {
25397
25439
  try {
25398
25440
  const res = await fetch(`${baseUrl}/api/retire`, {
@@ -25465,34 +25507,6 @@ async function prodEnsureDeps(s) {
25465
25507
  import { renameSync as renameSync3, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "fs";
25466
25508
  import { dirname as dirname6 } from "path";
25467
25509
 
25468
- // src/config/prefs.ts
25469
- import { readFile as readFile3, writeFile } from "fs/promises";
25470
- import { dirname as dirname4 } from "path";
25471
- var DEFAULT_SET = { valid: ["default"], fallback: "default" };
25472
- async function readApproveMode(file2 = prefsFile(), log = noopLogger, set2 = DEFAULT_SET) {
25473
- try {
25474
- const parsed = JSON.parse(await readFile3(file2, "utf-8"));
25475
- if (typeof parsed.approveMode === "string" && set2.valid.includes(parsed.approveMode)) {
25476
- return parsed.approveMode;
25477
- }
25478
- log.debug("prefs", "unrecognized approve mode; using default");
25479
- return set2.fallback;
25480
- } catch (err) {
25481
- const absent = err?.code === "ENOENT";
25482
- log.debug("prefs", absent ? "no prefs file; using default approve mode" : "prefs unreadable; using default approve mode");
25483
- return set2.fallback;
25484
- }
25485
- }
25486
- async function writeApproveMode(mode, file2 = prefsFile(), log = noopLogger, set2 = DEFAULT_SET) {
25487
- if (!set2.valid.includes(mode)) {
25488
- log.warn("prefs", "ignoring invalid approve mode");
25489
- return;
25490
- }
25491
- ensureStateDir(dirname4(file2));
25492
- await writeFile(file2, JSON.stringify({ approveMode: mode }, null, 2), { mode: 384 });
25493
- log.debug("prefs", `approve mode saved: ${mode}`);
25494
- }
25495
-
25496
25510
  // src/daemon/guards.ts
25497
25511
  var LIVE_CLIENT_WINDOW_MS = 120000;
25498
25512
  function isClientLive(lastPollAt, now, windowMs) {
@@ -25501,17 +25515,33 @@ function isClientLive(lastPollAt, now, windowMs) {
25501
25515
  function isSafeMethod(method) {
25502
25516
  return method === "GET" || method === "HEAD";
25503
25517
  }
25504
- function isCrossOrigin(req) {
25505
- const origin = req.headers.get("origin");
25506
- if (origin) {
25507
- try {
25508
- const host = new URL(origin).hostname;
25509
- if (host !== "127.0.0.1" && host !== "localhost" && host !== VANITY_HOST)
25510
- return true;
25511
- } catch {
25512
- return true;
25513
- }
25518
+ var OWN_HOSTNAMES = new Set(["127.0.0.1", "localhost", VANITY_HOST]);
25519
+ function isOwnAuthority(authority, port) {
25520
+ try {
25521
+ const u = new URL(`http://${authority}`);
25522
+ if (u.href !== `http://${u.host}/`)
25523
+ return false;
25524
+ return OWN_HOSTNAMES.has(u.hostname) && (u.port || "80") === String(port);
25525
+ } catch {
25526
+ return false;
25514
25527
  }
25528
+ }
25529
+ function isForeignHost(req, port) {
25530
+ const host = req.headers.get("host");
25531
+ return host === null || !isOwnAuthority(host, port);
25532
+ }
25533
+ function isOwnOrigin(origin, port) {
25534
+ try {
25535
+ const u = new URL(origin);
25536
+ return u.protocol === "http:" && isOwnAuthority(u.host, port);
25537
+ } catch {
25538
+ return false;
25539
+ }
25540
+ }
25541
+ function isCrossOrigin(req, port) {
25542
+ const origin = req.headers.get("origin");
25543
+ if (origin && !isOwnOrigin(origin, port))
25544
+ return true;
25515
25545
  const site = req.headers.get("sec-fetch-site");
25516
25546
  if (site && site !== "same-origin" && site !== "none")
25517
25547
  return true;
@@ -25536,6 +25566,7 @@ var ResolveBodySchema = exports_external.object({
25536
25566
  feedback: exports_external.string().optional(),
25537
25567
  acceptMode: exports_external.string().optional().catch(undefined)
25538
25568
  }).catch({ behavior: "allow" });
25569
+ var PrefsPatchSchema = exports_external.object({ updates: exports_external.object({ check: exports_external.boolean() }).strict().optional() }).strict();
25539
25570
  var LineAnnotationSchema = exports_external.object({
25540
25571
  id: exports_external.string(),
25541
25572
  startLine: exports_external.number().int().min(1),
@@ -26293,6 +26324,7 @@ var PLACEHOLDER_HTML = `<!doctype html><html lang="en"><head><meta charset="utf-
26293
26324
  var INDEX_CACHE_CONTROL = "no-cache";
26294
26325
  var ASSET_CACHE_CONTROL = "public, max-age=31536000, immutable";
26295
26326
  var INDEX_PATH = "/index.html";
26327
+ var FILE_REF_BATCH = 64;
26296
26328
  function resolveOptions(opts) {
26297
26329
  return {
26298
26330
  store: opts.store,
@@ -26312,6 +26344,8 @@ function resolveOptions(opts) {
26312
26344
  listSkills: opts.listSkills,
26313
26345
  readSkillDescription: opts.readSkillDescription,
26314
26346
  diagnostics: opts.diagnostics,
26347
+ updateReport: opts.updateReport,
26348
+ onUpdatesEnabled: opts.onUpdatesEnabled,
26315
26349
  markPaneRead: opts.markPaneRead ?? ((pane) => markPaneRead(pane, { log: opts.log })),
26316
26350
  log: opts.log ?? noopLogger
26317
26351
  };
@@ -26329,6 +26363,7 @@ function createServer(opts) {
26329
26363
  const { buildId, commit, stateDir: stateDir2, instanceId, approveVariants, source, lockPath } = cfg;
26330
26364
  const { awaitDecision, resolveDecision, clearDecision, openDecisionCount } = createDecisions(log);
26331
26365
  const approveModeSet = approveVariants && approveVariants.length > 0 ? { valid: approveVariants.map((v) => v.id), fallback: approveVariants[0]?.id ?? "default" } : { valid: ["default"], fallback: "default" };
26366
+ const prefsWriter = createPrefsWriter(prefsPath);
26332
26367
  function raceDecision(id, ms) {
26333
26368
  return new Promise((resolve2) => {
26334
26369
  const t = setTimeout(() => resolve2(null), ms);
@@ -26397,6 +26432,11 @@ function createServer(opts) {
26397
26432
  return notFound();
26398
26433
  return Response.json(cfg.diagnostics());
26399
26434
  }
26435
+ async function handleUpdate() {
26436
+ if (!cfg.updateReport)
26437
+ return notFound();
26438
+ return Response.json(await cfg.updateReport());
26439
+ }
26400
26440
  function handleRetire() {
26401
26441
  log.info("retire", "retire requested");
26402
26442
  setTimeout(() => {
@@ -26470,7 +26510,23 @@ function createServer(opts) {
26470
26510
  return new Response(null, { status: 204 });
26471
26511
  }
26472
26512
  async function handlePrefs() {
26473
- return Response.json({ approveMode: await readApproveMode(prefsPath, log, approveModeSet) });
26513
+ const body = {
26514
+ approveMode: await readApproveMode(prefsPath, log, approveModeSet)
26515
+ };
26516
+ return Response.json(body);
26517
+ }
26518
+ async function handleSetPrefs(req) {
26519
+ const parsed = PrefsPatchSchema.safeParse(await req.json().catch(() => null));
26520
+ if (!parsed.success) {
26521
+ const error51 = parsed.error.issues[0]?.message ?? "invalid prefs patch";
26522
+ log.warn("prefs", "prefs patch rejected", { reason: error51 });
26523
+ return Response.json({ error: error51 }, { status: 400 });
26524
+ }
26525
+ await prefsWriter.merge(parsed.data);
26526
+ log.debug("prefs", "prefs saved");
26527
+ if (parsed.data.updates?.check === true)
26528
+ cfg.onUpdatesEnabled?.();
26529
+ return Response.json({ ok: true });
26474
26530
  }
26475
26531
  function handleGetReview(id) {
26476
26532
  const r = store.get(id);
@@ -26490,10 +26546,13 @@ function createServer(opts) {
26490
26546
  if (unique.push(p) === MAX_FILE_REFS)
26491
26547
  break;
26492
26548
  }
26493
- const entries = await Promise.all(unique.map(async (p) => {
26494
- const hit = await resolveInCwd(r.cwd, p);
26495
- return hit === null ? null : [p, hit.kind];
26496
- }));
26549
+ const entries = [];
26550
+ for (let i = 0;i < unique.length; i += FILE_REF_BATCH) {
26551
+ entries.push(...await Promise.all(unique.slice(i, i + FILE_REF_BATCH).map(async (p) => {
26552
+ const hit = await resolveInCwd(r.cwd, p);
26553
+ return hit === null ? null : [p, hit.kind];
26554
+ })));
26555
+ }
26497
26556
  const resolved = Object.fromEntries(entries.filter((e) => e !== null));
26498
26557
  log.debug("request", `file-refs resolved: ${Object.keys(resolved).length}/${unique.length}`, {
26499
26558
  reviewId: id,
@@ -26642,7 +26701,7 @@ function createServer(opts) {
26642
26701
  store.bumpEpoch(existing.sessionId);
26643
26702
  await store.remove(id);
26644
26703
  if (decision.acceptMode !== undefined && approveModeSet.valid.includes(decision.acceptMode)) {
26645
- writeApproveMode(decision.acceptMode, prefsPath, log, approveModeSet).catch(() => {
26704
+ writeApproveMode(decision.acceptMode, prefsWriter, log, approveModeSet).catch(() => {
26646
26705
  log.warn("prefs", "approve mode write failed");
26647
26706
  });
26648
26707
  }
@@ -26682,6 +26741,8 @@ function createServer(opts) {
26682
26741
  return handleHealth();
26683
26742
  if (method === "GET" && path === "/api/diagnostics")
26684
26743
  return handleDiagnostics();
26744
+ if (method === "GET" && path === "/api/update")
26745
+ return handleUpdate();
26685
26746
  if (method === "POST" && path === "/api/retire")
26686
26747
  return handleRetire();
26687
26748
  if (method === "GET" && (path === "/" || path === INDEX_PATH))
@@ -26696,6 +26757,8 @@ function createServer(opts) {
26696
26757
  return handleListReviews();
26697
26758
  if (method === "GET" && path === "/api/prefs")
26698
26759
  return handlePrefs();
26760
+ if (method === "POST" && path === "/api/prefs")
26761
+ return handleSetPrefs(req);
26699
26762
  const route = matchIdRoute(path);
26700
26763
  if (route) {
26701
26764
  const { id, sub } = route;
@@ -26732,14 +26795,18 @@ function createServer(opts) {
26732
26795
  }
26733
26796
  return notFound();
26734
26797
  }
26735
- async function handle(req) {
26798
+ async function handle(req, self) {
26736
26799
  inFlight++;
26737
26800
  cancelIdle();
26738
26801
  try {
26802
+ const port = self.port ?? -1;
26803
+ if (isForeignHost(req, port)) {
26804
+ return new Response("host not recognized", { status: 403 });
26805
+ }
26739
26806
  const url2 = new URL(req.url);
26740
26807
  const path = url2.pathname;
26741
26808
  const method = req.method;
26742
- if (!isSafeMethod(method) && isCrossOrigin(req)) {
26809
+ if (!isSafeMethod(method) && isCrossOrigin(req, port)) {
26743
26810
  return new Response("cross-origin request blocked", { status: 403 });
26744
26811
  }
26745
26812
  return await dispatch(req, method, path);
@@ -26804,6 +26871,150 @@ function createServer(opts) {
26804
26871
  return { port: server.port ?? 0, stop };
26805
26872
  }
26806
26873
 
26874
+ // src/daemon/update-check.ts
26875
+ import { writeFileSync as writeFileSync6 } from "fs";
26876
+ import { dirname as dirname7 } from "path";
26877
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
26878
+ var REFRESH_COMMAND = "bunx --no-cache @macintacos/caret@latest install --refresh";
26879
+ var REBUILD_COMMAND = "mise run build --install";
26880
+ var NEEDS_COMPARE = "could not compare this build against trunk";
26881
+ var NEVER_CHECKED = {
26882
+ kind: "unknown",
26883
+ reason: "no update check has run for this build yet"
26884
+ };
26885
+ var DISABLED = { kind: "unavailable", reason: "disabled" };
26886
+ function updateStatusFor(facts) {
26887
+ if (facts.kind === "dev")
26888
+ return { kind: "unavailable", reason: "dev" };
26889
+ if (facts.kind === "bundle") {
26890
+ if (facts.npmLatest === null)
26891
+ return unknown2("could not reach npm for the published version");
26892
+ return isNewer(facts.npmLatest, facts.version) ? { kind: "behind-release", available: facts.npmLatest, command: REFRESH_COMMAND } : { kind: "current" };
26893
+ }
26894
+ if (facts.release === null)
26895
+ return unknown2("could not reach GitHub for the newest release");
26896
+ if (isNewer(facts.release, facts.version)) {
26897
+ return { kind: "behind-release", available: facts.release, command: REFRESH_COMMAND };
26898
+ }
26899
+ if (facts.commit === "unknown")
26900
+ return { kind: "current" };
26901
+ if (facts.aheadBy === null)
26902
+ return unknown2(NEEDS_COMPARE);
26903
+ return facts.aheadBy > 0 ? { kind: "behind-commit", aheadBy: facts.aheadBy, command: REBUILD_COMMAND } : { kind: "current" };
26904
+ }
26905
+ function updateReportFor(identity, status, checkEnabled) {
26906
+ const devBuild = status.kind === "unavailable" && status.reason === "dev";
26907
+ return { ...identity, checkEnabled, status: checkEnabled || devBuild ? status : DISABLED };
26908
+ }
26909
+ function readCachedStatus(cache, version2, commit) {
26910
+ const rec = cache.read();
26911
+ if (!rec || rec.version !== version2 || rec.commit !== commit)
26912
+ return NEVER_CHECKED;
26913
+ return rec.status;
26914
+ }
26915
+ async function runUpdateCheck(deps) {
26916
+ if (deps.kind === "dev")
26917
+ return { kind: "unavailable", reason: "dev" };
26918
+ try {
26919
+ if (!await deps.enabled())
26920
+ return null;
26921
+ const now = deps.now();
26922
+ const prev = deps.cache.read();
26923
+ const sameBuild = prev?.version === deps.version && prev?.commit === deps.commit;
26924
+ if (prev && sameBuild && Math.abs(now - prev.checkedAt) < CHECK_INTERVAL_MS)
26925
+ return null;
26926
+ const record2 = (status2) => {
26927
+ deps.cache.write({ checkedAt: now, version: deps.version, commit: deps.commit, status: status2 });
26928
+ };
26929
+ record2(prev && sameBuild ? prev.status : NEVER_CHECKED);
26930
+ const status = await gather(deps);
26931
+ record2(status);
26932
+ deps.log.info("update", `update check: ${status.kind}`, status.kind === "unknown" ? { detail: status.reason } : undefined);
26933
+ return status;
26934
+ } catch (err) {
26935
+ deps.log.warn("update", "update check failed", { detail: errorMessage(err) });
26936
+ return unknown2("the update check failed");
26937
+ }
26938
+ }
26939
+ function fileUpdateCache(path) {
26940
+ return {
26941
+ read: () => asRecord(readJsonFileSync(path)),
26942
+ write: (entry) => {
26943
+ try {
26944
+ ensureStateDir(dirname7(path));
26945
+ writeFileSync6(path, JSON.stringify(entry, null, 2), { mode: 384 });
26946
+ } catch {}
26947
+ }
26948
+ };
26949
+ }
26950
+ async function gather(deps) {
26951
+ const base = { kind: deps.kind, version: deps.version, commit: deps.commit };
26952
+ if (deps.kind === "bundle") {
26953
+ return updateStatusFor({
26954
+ ...base,
26955
+ npmLatest: await deps.npmLatest(),
26956
+ release: null,
26957
+ aheadBy: null
26958
+ });
26959
+ }
26960
+ const release = await deps.release();
26961
+ const first = updateStatusFor({ ...base, npmLatest: null, release, aheadBy: null });
26962
+ if (first.kind !== "unknown" || first.reason !== NEEDS_COMPARE)
26963
+ return first;
26964
+ const aheadBy = await deps.aheadBy(deps.commit);
26965
+ return updateStatusFor({ ...base, npmLatest: null, release, aheadBy });
26966
+ }
26967
+ function asRecord(value) {
26968
+ const r = value;
26969
+ if (typeof r?.checkedAt !== "number")
26970
+ return null;
26971
+ if (typeof r.version !== "string" || typeof r.commit !== "string")
26972
+ return null;
26973
+ if (typeof r.status?.kind !== "string")
26974
+ return null;
26975
+ return r;
26976
+ }
26977
+ function unknown2(reason) {
26978
+ return { kind: "unknown", reason };
26979
+ }
26980
+
26981
+ // src/lib/upstream.ts
26982
+ var NPM_LATEST_URL = `https://registry.npmjs.org/${package_default.name}/latest`;
26983
+ var LATEST_RELEASE_URL = "https://api.github.com/repos/macintacos/caret/releases/latest";
26984
+ var COMPARE_URL = "https://api.github.com/repos/macintacos/caret/compare";
26985
+ var UPSTREAM_TIMEOUT_MS = 3000;
26986
+ var GITHUB_HEADERS = { "user-agent": "caret" };
26987
+ async function readJson(url2, fetchImpl, headers) {
26988
+ try {
26989
+ const res = await fetchImpl(url2, {
26990
+ signal: AbortSignal.timeout(UPSTREAM_TIMEOUT_MS),
26991
+ ...headers ? { headers } : {}
26992
+ });
26993
+ return res.ok ? await res.json() : null;
26994
+ } catch {
26995
+ return null;
26996
+ }
26997
+ }
26998
+ async function publishedCaretVersion(fetchImpl = fetch) {
26999
+ const body = await readJson(NPM_LATEST_URL, fetchImpl);
27000
+ const v = body?.version;
27001
+ return typeof v === "string" && v.length > 0 ? v : null;
27002
+ }
27003
+ async function latestReleaseTag(fetchImpl = fetch) {
27004
+ const body = await readJson(LATEST_RELEASE_URL, fetchImpl, GITHUB_HEADERS);
27005
+ const tag = body?.tag_name;
27006
+ if (typeof tag !== "string" || tag.length === 0)
27007
+ return null;
27008
+ const stripped = tag.replace(/^v/, "");
27009
+ return stripped.length > 0 ? stripped : null;
27010
+ }
27011
+ async function commitsAheadOfTrunk(commit, fetchImpl = fetch) {
27012
+ const url2 = `${COMPARE_URL}/${encodeURIComponent(commit)}...trunk`;
27013
+ const body = await readJson(url2, fetchImpl, GITHUB_HEADERS);
27014
+ const ahead = body?.ahead_by;
27015
+ return typeof ahead === "number" && Number.isFinite(ahead) ? ahead : null;
27016
+ }
27017
+
26807
27018
  // src/review/store.ts
26808
27019
  import { readdir as readdir6, readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
26809
27020
  import { join as join13 } from "path";
@@ -26917,6 +27128,28 @@ async function runDaemon(opts) {
26917
27128
  log.info("settings", existsSync7(cfg) ? `settings: reading ${cfg}` : `settings: no config at ${cfg}; using defaults`, { settings: boot });
26918
27129
  warnInvalidEnvVars((msg) => log.warn("env", msg));
26919
27130
  const adapter = selectAdapter();
27131
+ const install = buildKind();
27132
+ const version2 = VERSION;
27133
+ const commit = currentCommit();
27134
+ const updateCache = fileUpdateCache(updateCheckFile());
27135
+ let updateStatus = readCachedStatus(updateCache, version2, commit);
27136
+ function refreshUpdate() {
27137
+ runUpdateCheck({
27138
+ kind: install,
27139
+ version: version2,
27140
+ commit,
27141
+ enabled: () => readUpdatesCheck(),
27142
+ now: Date.now,
27143
+ cache: updateCache,
27144
+ npmLatest: publishedCaretVersion,
27145
+ release: latestReleaseTag,
27146
+ aheadBy: commitsAheadOfTrunk,
27147
+ log
27148
+ }).then((status) => {
27149
+ if (status)
27150
+ updateStatus = status;
27151
+ }, (err) => log.error("update", err));
27152
+ }
26920
27153
  const store = createStore(reviewsDir(), log);
26921
27154
  await store.rehydrate();
26922
27155
  const assets = await loadUiAssets();
@@ -26924,6 +27157,19 @@ async function runDaemon(opts) {
26924
27157
  log.info("ui", "no embedded ui; serving placeholder");
26925
27158
  const ephemeral = opts.ephemeral;
26926
27159
  let server;
27160
+ const shutdown = (code) => {
27161
+ server?.stop();
27162
+ process.exit(code);
27163
+ };
27164
+ process.once("SIGTERM", () => {
27165
+ log.info("signal", "sigterm: shutting down");
27166
+ shutdown(0);
27167
+ });
27168
+ process.once("SIGINT", () => {
27169
+ log.info("signal", "sigint: shutting down");
27170
+ shutdown(0);
27171
+ });
27172
+ process.once("exit", removeOwnDaemonLock);
26927
27173
  try {
26928
27174
  server = createServer({
26929
27175
  store,
@@ -26933,7 +27179,7 @@ async function runDaemon(opts) {
26933
27179
  assets,
26934
27180
  lockPath: daemonLock(),
26935
27181
  buildId: await currentBuildId(),
26936
- commit: currentCommit(),
27182
+ commit,
26937
27183
  stateDir: stateDir(),
26938
27184
  instanceId: randomUUID().slice(0, 8),
26939
27185
  approveVariants: adapter.approveVariants,
@@ -26953,6 +27199,8 @@ async function runDaemon(opts) {
26953
27199
  configExists: () => existsSync7(cfg),
26954
27200
  envOverrides
26955
27201
  }),
27202
+ updateReport: async () => updateReportFor({ install, version: version2, commit }, updateStatus, await readUpdatesCheck()),
27203
+ onUpdatesEnabled: refreshUpdate,
26956
27204
  log
26957
27205
  });
26958
27206
  } catch (e) {
@@ -26963,29 +27211,13 @@ async function runDaemon(opts) {
26963
27211
  }
26964
27212
  throw e;
26965
27213
  }
26966
- const shutdown = (code) => {
26967
- server.stop();
26968
- process.exit(code);
26969
- };
26970
- process.once("SIGTERM", () => {
26971
- log.info("signal", "sigterm: shutting down");
26972
- shutdown(0);
26973
- });
26974
- process.once("SIGINT", () => {
26975
- log.info("signal", "sigint: shutting down");
26976
- shutdown(0);
26977
- });
26978
27214
  const onFatal = (label) => (err) => {
26979
27215
  log.error(label, err);
26980
27216
  shutdown(1);
26981
27217
  };
26982
27218
  process.once("uncaughtException", onFatal("uncaughtException"));
26983
27219
  process.once("unhandledRejection", onFatal("unhandledRejection"));
26984
- process.once("exit", () => {
26985
- try {
26986
- unlinkSync4(daemonLock());
26987
- } catch {}
26988
- });
27220
+ refreshUpdate();
26989
27221
  }
26990
27222
 
26991
27223
  // src/commands/discovery.ts
@@ -27315,19 +27547,19 @@ import {
27315
27547
  rmSync as rmSync2,
27316
27548
  statSync as statSync5,
27317
27549
  symlinkSync,
27318
- writeFileSync as writeFileSync6
27550
+ writeFileSync as writeFileSync7
27319
27551
  } from "fs";
27320
27552
  import { join as join16, resolve as resolve2 } from "path";
27321
27553
 
27322
27554
  // src/adapters/opencode/packaging.ts
27323
27555
  import { existsSync as existsSync9, readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
27324
- import { dirname as dirname7, join as join15 } from "path";
27556
+ import { dirname as dirname8, join as join15 } from "path";
27325
27557
  function resolveCaretRoot() {
27326
27558
  const candidates = [];
27327
27559
  const script = process.argv[1];
27328
27560
  if (script)
27329
- candidates.push(join15(dirname7(script), ".."));
27330
- candidates.push(join15(dirname7(process.execPath), ".."));
27561
+ candidates.push(join15(dirname8(script), ".."));
27562
+ candidates.push(join15(dirname8(process.execPath), ".."));
27331
27563
  for (const root of candidates) {
27332
27564
  if (existsSync9(join15(root, "opencode", "caret.plugin.ts")))
27333
27565
  return root;
@@ -27379,7 +27611,7 @@ function writeDevMarketplace(repoDir, outDir) {
27379
27611
  rmSync2(outDir, { recursive: true, force: true });
27380
27612
  mkdirSync3(join16(outDir, ".claude-plugin"), { recursive: true });
27381
27613
  symlinkSync(resolve2(repoDir), join16(outDir, "caret"));
27382
- writeFileSync6(join16(outDir, ".claude-plugin", "marketplace.json"), `${JSON.stringify({
27614
+ writeFileSync7(join16(outDir, ".claude-plugin", "marketplace.json"), `${JSON.stringify({
27383
27615
  name: "caret",
27384
27616
  description: "Local caret dev build (generated by caret install --from-local).",
27385
27617
  owner: { name: "macintacos" },
@@ -27664,12 +27896,12 @@ async function runInstallClaudeTarget(opts, deps = {}) {
27664
27896
  }
27665
27897
 
27666
27898
  // src/commands/install/opencode.ts
27667
- import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
27899
+ import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
27668
27900
  import { basename as basename4, join as join18 } from "path";
27669
27901
 
27670
27902
  // src/adapters/opencode/deploy.ts
27671
- import { existsSync as existsSync12, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "fs";
27672
- import { dirname as dirname9 } from "path";
27903
+ import { existsSync as existsSync12, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "fs";
27904
+ import { dirname as dirname10 } from "path";
27673
27905
  function renderPlugin(source, opts) {
27674
27906
  return source.replaceAll("__CARET_VERSION__", () => opts.version).replaceAll("__CARET_BIN__", () => opts.binPath);
27675
27907
  }
@@ -27677,8 +27909,8 @@ function deployFiles(files, opts) {
27677
27909
  const paths = [];
27678
27910
  for (const f2 of files) {
27679
27911
  if (!opts.dryRun) {
27680
- mkdirSync4(dirname9(f2.path), { recursive: true });
27681
- writeFileSync7(f2.path, f2.contents);
27912
+ mkdirSync4(dirname10(f2.path), { recursive: true });
27913
+ writeFileSync8(f2.path, f2.contents);
27682
27914
  }
27683
27915
  paths.push(f2.path);
27684
27916
  }
@@ -27873,7 +28105,7 @@ function editConfig(path2, transform2) {
27873
28105
  const next = transform2(existing);
27874
28106
  if (next === null || next === existing)
27875
28107
  return [];
27876
- writeFileSync8(path2, next);
28108
+ writeFileSync9(path2, next);
27877
28109
  return [path2];
27878
28110
  }
27879
28111
 
@@ -27885,10 +28117,10 @@ function parseTargets(raw) {
27885
28117
  error: `--target names no agent (it takes a comma-separated list of: ${INSTALL_TARGET_IDS.join(", ")}) \u2014 omit it entirely to choose interactively.`
27886
28118
  };
27887
28119
  }
27888
- const unknown2 = parts.filter((p3) => !INSTALL_TARGET_IDS.includes(p3));
27889
- if (unknown2.length > 0) {
28120
+ const unknown3 = parts.filter((p3) => !INSTALL_TARGET_IDS.includes(p3));
28121
+ if (unknown3.length > 0) {
27890
28122
  return {
27891
- error: `unknown --target value(s): ${unknown2.join(", ")}. Valid: ${INSTALL_TARGET_IDS.join(", ")}.`
28123
+ error: `unknown --target value(s): ${unknown3.join(", ")}. Valid: ${INSTALL_TARGET_IDS.join(", ")}.`
27892
28124
  };
27893
28125
  }
27894
28126
  const targets = [];
@@ -30942,7 +31174,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
30942
31174
  });
30943
31175
  this.runningCommand = proc;
30944
31176
  }
30945
- _dispatchSubcommand(commandName, operands, unknown2) {
31177
+ _dispatchSubcommand(commandName, operands, unknown3) {
30946
31178
  const subCommand = this._findCommand(commandName);
30947
31179
  if (!subCommand)
30948
31180
  this.help({ error: true });
@@ -30951,9 +31183,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
30951
31183
  promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
30952
31184
  promiseChain = this._chainOrCall(promiseChain, () => {
30953
31185
  if (subCommand._executableHandler) {
30954
- this._executeSubCommand(subCommand, operands.concat(unknown2));
31186
+ this._executeSubCommand(subCommand, operands.concat(unknown3));
30955
31187
  } else {
30956
- return subCommand._parseCommand(operands, unknown2);
31188
+ return subCommand._parseCommand(operands, unknown3);
30957
31189
  }
30958
31190
  });
30959
31191
  return promiseChain;
@@ -31050,22 +31282,22 @@ Expecting one of '${allowedValues.join("', '")}'`);
31050
31282
  }
31051
31283
  return result;
31052
31284
  }
31053
- _parseCommand(operands, unknown2) {
31054
- const parsed = this.parseOptions(unknown2);
31285
+ _parseCommand(operands, unknown3) {
31286
+ const parsed = this.parseOptions(unknown3);
31055
31287
  this._parseOptionsEnv();
31056
31288
  this._parseOptionsImplied();
31057
31289
  operands = operands.concat(parsed.operands);
31058
- unknown2 = parsed.unknown;
31059
- this.args = operands.concat(unknown2);
31290
+ unknown3 = parsed.unknown;
31291
+ this.args = operands.concat(unknown3);
31060
31292
  if (operands && this._findCommand(operands[0])) {
31061
- return this._dispatchSubcommand(operands[0], operands.slice(1), unknown2);
31293
+ return this._dispatchSubcommand(operands[0], operands.slice(1), unknown3);
31062
31294
  }
31063
31295
  if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
31064
31296
  return this._dispatchHelpCommand(operands[1]);
31065
31297
  }
31066
31298
  if (this._defaultCommandName) {
31067
- this._outputHelpIfRequested(unknown2);
31068
- return this._dispatchSubcommand(this._defaultCommandName, operands, unknown2);
31299
+ this._outputHelpIfRequested(unknown3);
31300
+ return this._dispatchSubcommand(this._defaultCommandName, operands, unknown3);
31069
31301
  }
31070
31302
  if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
31071
31303
  this.help({ error: true });
@@ -31087,7 +31319,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
31087
31319
  promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
31088
31320
  if (this.parent) {
31089
31321
  promiseChain = this._chainOrCall(promiseChain, () => {
31090
- this.parent.emit(commandEvent, operands, unknown2);
31322
+ this.parent.emit(commandEvent, operands, unknown3);
31091
31323
  });
31092
31324
  }
31093
31325
  promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
@@ -31096,13 +31328,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
31096
31328
  if (this.parent?.listenerCount(commandEvent)) {
31097
31329
  checkForUnknownOptions();
31098
31330
  this._processArguments();
31099
- this.parent.emit(commandEvent, operands, unknown2);
31331
+ this.parent.emit(commandEvent, operands, unknown3);
31100
31332
  } else if (operands.length) {
31101
31333
  if (this._findCommand("*")) {
31102
- return this._dispatchSubcommand("*", operands, unknown2);
31334
+ return this._dispatchSubcommand("*", operands, unknown3);
31103
31335
  }
31104
31336
  if (this.listenerCount("command:*")) {
31105
- this.emit("command:*", operands, unknown2);
31337
+ this.emit("command:*", operands, unknown3);
31106
31338
  } else if (this.commands.length) {
31107
31339
  this.unknownCommand();
31108
31340
  } else {
@@ -31157,7 +31389,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
31157
31389
  }
31158
31390
  parseOptions(args) {
31159
31391
  const operands = [];
31160
- const unknown2 = [];
31392
+ const unknown3 = [];
31161
31393
  let dest = operands;
31162
31394
  function maybeOption(arg) {
31163
31395
  return arg.length > 1 && arg[0] === "-";
@@ -31174,7 +31406,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
31174
31406
  const arg = activeGroup ?? args[i2++];
31175
31407
  activeGroup = null;
31176
31408
  if (arg === "--") {
31177
- if (dest === unknown2)
31409
+ if (dest === unknown3)
31178
31410
  dest.push(arg);
31179
31411
  dest.push(...args.slice(i2));
31180
31412
  break;
@@ -31226,18 +31458,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
31226
31458
  }
31227
31459
  }
31228
31460
  if (dest === operands && maybeOption(arg) && !(this.commands.length === 0 && negativeNumberArg(arg))) {
31229
- dest = unknown2;
31461
+ dest = unknown3;
31230
31462
  }
31231
- if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown2.length === 0) {
31463
+ if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown3.length === 0) {
31232
31464
  if (this._findCommand(arg)) {
31233
31465
  operands.push(arg);
31234
- unknown2.push(...args.slice(i2));
31466
+ unknown3.push(...args.slice(i2));
31235
31467
  break;
31236
31468
  } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
31237
31469
  operands.push(arg, ...args.slice(i2));
31238
31470
  break;
31239
31471
  } else if (this._defaultCommandName) {
31240
- unknown2.push(arg, ...args.slice(i2));
31472
+ unknown3.push(arg, ...args.slice(i2));
31241
31473
  break;
31242
31474
  }
31243
31475
  }
@@ -31247,7 +31479,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
31247
31479
  }
31248
31480
  dest.push(arg);
31249
31481
  }
31250
- return { operands, unknown: unknown2 };
31482
+ return { operands, unknown: unknown3 };
31251
31483
  }
31252
31484
  opts() {
31253
31485
  if (this._storeOptionsAsProperties) {