tokentracker-cli 0.84.4 → 0.84.6

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 (95) hide show
  1. package/dashboard/dist/assets/{AchievementBadge-C29PwsK_.js → AchievementBadge-CKIvD3lG.js} +1 -1
  2. package/dashboard/dist/assets/{AchievementsPage-BlZODLp8.js → AchievementsPage-CZWCUiS5.js} +2 -2
  3. package/dashboard/dist/assets/{AchievementsSection-Bc6NMnIa.js → AchievementsSection-BSk_fR8P.js} +1 -1
  4. package/dashboard/dist/assets/{BadgeDetailModal-BUy4636q.js → BadgeDetailModal-CjHkcmuq.js} +1 -1
  5. package/dashboard/dist/assets/{Card-CqxuFMAN.js → Card-D6hdzwvI.js} +1 -1
  6. package/dashboard/dist/assets/{ClawdAnimated-BG3m8BgW.js → ClawdAnimated-Cl6gmF7u.js} +1 -1
  7. package/dashboard/dist/assets/{CommandPalette-Dcwtom2b.js → CommandPalette-B0rcodcF.js} +1 -1
  8. package/dashboard/dist/assets/{CommunityStatsModal-dBjHrgjE.js → CommunityStatsModal-BtlTJbf4.js} +1 -1
  9. package/dashboard/dist/assets/{ConfirmModal-DncQkptq.js → ConfirmModal-tJCWVZQH.js} +1 -1
  10. package/dashboard/dist/assets/{DashboardPage-CdF5WNHN.js → DashboardPage-Dtxq8dzI.js} +1 -1
  11. package/dashboard/dist/assets/{DevicePage-B-PO4s-r.js → DevicePage-9USuEsRu.js} +1 -1
  12. package/dashboard/dist/assets/{DialogClose-DGtj17VY.js → DialogClose-DxHdqMcl.js} +1 -1
  13. package/dashboard/dist/assets/DialogDescription-DgUSe6A1.js +1 -0
  14. package/dashboard/dist/assets/{DialogTitle-DLkuu1Iw.js → DialogTitle-C1ZeQgf2.js} +1 -1
  15. package/dashboard/dist/assets/{FadeIn-Dd5RBmXd.js → FadeIn-Cx4jLl9G.js} +1 -1
  16. package/dashboard/dist/assets/{HeaderGithubStar-BBCOpHqO.js → HeaderGithubStar-BOyuGkoA.js} +1 -1
  17. package/dashboard/dist/assets/{HoverTooltip-BbigYxdC.js → HoverTooltip-BDhqMR3L.js} +1 -1
  18. package/dashboard/dist/assets/{IpCheckPage-BBpZYjSC.js → IpCheckPage-DTvA9Wmx.js} +1 -1
  19. package/dashboard/dist/assets/{LandingPage-ttXnt_s9.js → LandingPage-k1271lWV.js} +2 -2
  20. package/dashboard/dist/assets/{LeaderboardAvatar-DOl_cOO9.js → LeaderboardAvatar-3ibNg6If.js} +1 -1
  21. package/dashboard/dist/assets/{LeaderboardPage-BYIyoLkB.js → LeaderboardPage-Byww5UpT.js} +2 -2
  22. package/dashboard/dist/assets/{LeaderboardProfileModal-BO2n4LSQ.js → LeaderboardProfileModal-DeGbJtvi.js} +3 -3
  23. package/dashboard/dist/assets/{LeaderboardProfilePage-CqwW5yMw.js → LeaderboardProfilePage-DEPzO6hW.js} +1 -1
  24. package/dashboard/dist/assets/{LimitsPage-B-w771Tl.js → LimitsPage-DPtqL0PS.js} +1 -1
  25. package/dashboard/dist/assets/{LocalOnlyNotice-Cqc_diwF.js → LocalOnlyNotice-C76LAT_3.js} +1 -1
  26. package/dashboard/dist/assets/{LoginCard-D6zc1JKY.js → LoginCard-DEyCJT67.js} +1 -1
  27. package/dashboard/dist/assets/{LoginModal-udN3TqoF.js → LoginModal-CueMQgAZ.js} +1 -1
  28. package/dashboard/dist/assets/{LoginPage-BucPr3_X.js → LoginPage-CwqBb5Fd.js} +1 -1
  29. package/dashboard/dist/assets/{PetPage-6_nmMXWp.js → PetPage--xQAjW4_.js} +1 -1
  30. package/dashboard/dist/assets/{PopoverPopup-DntczBmH.js → PopoverPopup-Dt9VY2VQ.js} +1 -1
  31. package/dashboard/dist/assets/{ProviderIcon-Z6qlwSj1.js → ProviderIcon-CHx4ohfx.js} +1 -1
  32. package/dashboard/dist/assets/{ResetPasswordPage-WqQwsQC1.js → ResetPasswordPage-DB6R7fjf.js} +1 -1
  33. package/dashboard/dist/assets/{SegmentedControl-D3NM3dOv.js → SegmentedControl-BINOpXIY.js} +1 -1
  34. package/dashboard/dist/assets/{Select-DCpwSFK7.js → Select-DcYXcsKv.js} +1 -1
  35. package/dashboard/dist/assets/{SelectItemText-DICaclqa.js → SelectItemText-BDv2Kb3x.js} +1 -1
  36. package/dashboard/dist/assets/{SessionsPage-COHoSjPP.js → SessionsPage-cL_w0ytB.js} +1 -1
  37. package/dashboard/dist/assets/{SettingsPage-nzbrBo_U.js → SettingsPage-CHGA0bQS.js} +1 -1
  38. package/dashboard/dist/assets/{SkillsPage-DE8mK1lS.js → SkillsPage-I29SqkXO.js} +1 -1
  39. package/dashboard/dist/assets/{TokenGalaxy-BSWGbByr.js → TokenGalaxy-BHq4YSv2.js} +1 -1
  40. package/dashboard/dist/assets/{ToolbarRootContext-CxxXTuTT.js → ToolbarRootContext-akXaaKb6.js} +1 -1
  41. package/dashboard/dist/assets/{TrendMonitor-DillSTMV.js → TrendMonitor-DPhFXzQc.js} +1 -1
  42. package/dashboard/dist/assets/{WidgetsPage-LqyxKYAt.js → WidgetsPage-Nf0UEz7s.js} +1 -1
  43. package/dashboard/dist/assets/{WrappedPage-DNDuRKjf.js → WrappedPage-D4zOSsqD.js} +1 -1
  44. package/dashboard/dist/assets/{__vite-browser-external-DEhUaWQY.js → __vite-browser-external-UqlSqI-1.js} +2 -2
  45. package/dashboard/dist/assets/{agent-logos-D34B25op.js → agent-logos-Bja3VCAa.js} +1 -1
  46. package/dashboard/dist/assets/{arrow-up-right-BYWbL4WV.js → arrow-up-right-CzcCNJJ2.js} +1 -1
  47. package/dashboard/dist/assets/{check-DkfaR6JX.js → check-DUHSZCYn.js} +1 -1
  48. package/dashboard/dist/assets/{chevron-right-D2cpt_J3.js → chevron-right-jLvhaNUy.js} +1 -1
  49. package/dashboard/dist/assets/{copy-Cv5Ix0Pn.js → copy-ChyH-ynx.js} +1 -1
  50. package/dashboard/dist/assets/{download-5nr9Tl80.js → download-CgwvXrUe.js} +1 -1
  51. package/dashboard/dist/assets/{flame-B6M-msYH.js → flame-ysf1F8uB.js} +1 -1
  52. package/dashboard/dist/assets/{format-tokens-DiRRwgY8.js → format-tokens-DAa2cubl.js} +1 -1
  53. package/dashboard/dist/assets/{icons-DQHoG48j.js → icons-DccoWQq9.js} +1 -1
  54. package/dashboard/dist/assets/{index-hSxFduER.js → index-CAycNPQf.js} +1 -1
  55. package/dashboard/dist/assets/{index-BoH_HaYH.js → index-CxExExXh.js} +1 -1
  56. package/dashboard/dist/assets/{index-vFee2-sp.js → index-kkQrDRat.js} +1 -1
  57. package/dashboard/dist/assets/{info-CM5MR8lk.js → info-DWQQIq9M.js} +1 -1
  58. package/dashboard/dist/assets/{limits-providers-BV4Y9nI4.js → limits-providers-B_18X9Rp.js} +1 -1
  59. package/dashboard/dist/assets/{link-2-Bd5jF09Z.js → link-2-CKeVVq4P.js} +1 -1
  60. package/dashboard/dist/assets/{loader-circle-B5oZJSYV.js → loader-circle-Dw0tu6IN.js} +1 -1
  61. package/dashboard/dist/assets/{maximize-2-CiYy9Kri.js → maximize-2-BMU0YzEF.js} +1 -1
  62. package/dashboard/dist/assets/{provider-display-lzLynfde.js → provider-display-Cf9I-VLS.js} +1 -1
  63. package/dashboard/dist/assets/{react-CllryaXi.js → react-BhbcISKy.js} +1 -1
  64. package/dashboard/dist/assets/{search-DDdsotHp.js → search-BoY8EW1z.js} +1 -1
  65. package/dashboard/dist/assets/{skills-api-487vZmwI.js → skills-api-KVH21GJw.js} +1 -1
  66. package/dashboard/dist/assets/{store-CYaTRd_k.js → store-BL7rSajG.js} +1 -1
  67. package/dashboard/dist/assets/{terminal-OyeOY0tb.js → terminal-CeMuITdm.js} +1 -1
  68. package/dashboard/dist/assets/{trash-2-COI9stXJ.js → trash-2-jVUCKqrR.js} +1 -1
  69. package/dashboard/dist/assets/{use-community-stats-DkzinngC.js → use-community-stats-uWK0fE6l.js} +1 -1
  70. package/dashboard/dist/assets/{use-limits-display-prefs-CiMETU5Y.js → use-limits-display-prefs-DWsF4ShM.js} +1 -1
  71. package/dashboard/dist/assets/{use-native-settings-qzpxm9Bh.js → use-native-settings-SEbqWDvc.js} +1 -1
  72. package/dashboard/dist/assets/{use-ordered-list-BI-Qh9xR.js → use-ordered-list-D4UhrPvw.js} +1 -1
  73. package/dashboard/dist/assets/use-reduced-motion-C3UrOh55.js +1 -0
  74. package/dashboard/dist/assets/{use-session-efficiency-pref-1WyhIjeG.js → use-session-efficiency-pref-DbysyUTJ.js} +1 -1
  75. package/dashboard/dist/assets/{use-transform-D5i_ArzG.js → use-transform-DaEssGaZ.js} +1 -1
  76. package/dashboard/dist/assets/{use-usage-limits-Drcnt7__.js → use-usage-limits-CmmQ34Ov.js} +1 -1
  77. package/dashboard/dist/assets/{useCurrency-KWJo1GIr.js → useCurrency-DvBEn4rx.js} +1 -1
  78. package/dashboard/dist/assets/{useScrollLock-K0FPky1Y.js → useScrollLock-QozsdFng.js} +1 -1
  79. package/dashboard/dist/assets/{useTokenFormat-CwG4ck8v.js → useTokenFormat-BTLrL7Mi.js} +1 -1
  80. package/dashboard/dist/assets/{zap-wZ6IQAyU.js → zap-Dp_aJ1q6.js} +1 -1
  81. package/dashboard/dist/index.html +1 -1
  82. package/dashboard/dist/ip-check.html +1 -1
  83. package/dashboard/dist/leaderboard.html +1 -1
  84. package/dashboard/dist/share.html +1 -1
  85. package/package.json +1 -1
  86. package/src/commands/status.js +17 -7
  87. package/src/commands/sync.js +333 -5
  88. package/src/lib/codex-rollout-parser.js +17 -39
  89. package/src/lib/codex-token-usage.js +195 -0
  90. package/src/lib/pricing/curated-overrides.json +536 -101
  91. package/src/lib/pricing/seed-snapshot.json +1 -1
  92. package/src/lib/rollout.js +732 -163
  93. package/src/lib/usage-limits.js +211 -41
  94. package/dashboard/dist/assets/DialogDescription-wStLk8Br.js +0 -1
  95. package/dashboard/dist/assets/use-reduced-motion-DrsPn1ux.js +0 -1
@@ -1222,11 +1222,24 @@ function runCommand(commandRunner, command, args, options = {}) {
1222
1222
  return Promise.resolve(commandRunner(command, args, merged));
1223
1223
  }
1224
1224
 
1225
- const { timeout, maxBuffer, ...spawnOptions } = merged;
1225
+ const {
1226
+ timeout,
1227
+ maxBuffer,
1228
+ completeWhen,
1229
+ completionGraceMs = 250,
1230
+ killProcessGroup = false,
1231
+ ...spawnOptions
1232
+ } = merged;
1226
1233
  return new Promise((resolve) => {
1227
1234
  let child;
1235
+ const useProcessGroup =
1236
+ killProcessGroup && process.platform !== "win32";
1228
1237
  try {
1229
- child = cp.spawn(command, args, { ...spawnOptions, stdio: ["ignore", "pipe", "pipe"] });
1238
+ child = cp.spawn(command, args, {
1239
+ ...spawnOptions,
1240
+ detached: useProcessGroup || spawnOptions.detached,
1241
+ stdio: ["ignore", "pipe", "pipe"],
1242
+ });
1230
1243
  } catch (error) {
1231
1244
  resolve({ status: null, stdout: "", stderr: "", error });
1232
1245
  return;
@@ -1238,12 +1251,14 @@ function runCommand(commandRunner, command, args, options = {}) {
1238
1251
  let timedOut = false;
1239
1252
  let timer = null;
1240
1253
  let hardTimer = null;
1254
+ let completionTimer = null;
1241
1255
 
1242
1256
  const settle = ({ status = null, error = null } = {}) => {
1243
1257
  if (settled) return;
1244
1258
  settled = true;
1245
1259
  if (timer) clearTimeout(timer);
1246
1260
  if (hardTimer) clearTimeout(hardTimer);
1261
+ if (completionTimer) clearTimeout(completionTimer);
1247
1262
  let finalError = error;
1248
1263
  if (!finalError && timedOut) {
1249
1264
  finalError = new Error(`spawn ${command} ETIMEDOUT`);
@@ -1254,19 +1269,49 @@ function runCommand(commandRunner, command, args, options = {}) {
1254
1269
  resolve(result);
1255
1270
  };
1256
1271
 
1272
+ const signalChild = (signal) => {
1273
+ try {
1274
+ if (useProcessGroup && Number.isInteger(child.pid)) {
1275
+ process.kill(-child.pid, signal);
1276
+ } else {
1277
+ child.kill(signal);
1278
+ }
1279
+ } catch (_error) {}
1280
+ };
1281
+
1282
+ const stopChild = ({ timeoutExpired = false } = {}) => {
1283
+ if (settled) return;
1284
+ if (timeoutExpired) timedOut = true;
1285
+ signalChild("SIGTERM");
1286
+ // Guarantee settlement even if the process group ignores SIGTERM or
1287
+ // keeps inherited stdio open.
1288
+ hardTimer = setTimeout(() => {
1289
+ signalChild("SIGKILL");
1290
+ settle({ status: null });
1291
+ }, 1000);
1292
+ if (typeof hardTimer.unref === "function") hardTimer.unref();
1293
+ };
1294
+
1257
1295
  if (Number.isFinite(timeout) && timeout > 0) {
1258
1296
  timer = setTimeout(() => {
1259
- timedOut = true;
1260
- try { child.kill("SIGTERM"); } catch (_error) {}
1261
- // Guarantee settlement even if the child ignores SIGTERM or keeps stdio open.
1262
- hardTimer = setTimeout(() => {
1263
- try { child.kill("SIGKILL"); } catch (_error) {}
1264
- settle({ status: null });
1265
- }, 1000);
1266
- if (typeof hardTimer.unref === "function") hardTimer.unref();
1297
+ stopChild({ timeoutExpired: true });
1267
1298
  }, timeout);
1268
1299
  }
1269
1300
 
1301
+ const scheduleCompletion = () => {
1302
+ if (typeof completeWhen !== "function" || settled) return;
1303
+ let complete = false;
1304
+ try {
1305
+ complete = Boolean(completeWhen(stdout, stderr));
1306
+ } catch (_error) {}
1307
+ if (!complete) return;
1308
+ if (completionTimer) clearTimeout(completionTimer);
1309
+ completionTimer = setTimeout(
1310
+ () => stopChild(),
1311
+ Math.max(0, Number(completionGraceMs) || 0),
1312
+ );
1313
+ };
1314
+
1270
1315
  const collect = (stream, append) => {
1271
1316
  if (!stream) return;
1272
1317
  stream.setEncoding("utf8");
@@ -1275,9 +1320,11 @@ function runCommand(commandRunner, command, args, options = {}) {
1275
1320
  if (stdout.length + stderr.length > maxBuffer) {
1276
1321
  const error = new Error(`spawn ${command} maxBuffer length exceeded`);
1277
1322
  error.code = "ERR_CHILD_PROCESS_STDIO_MAXBUFFER";
1278
- try { child.kill("SIGKILL"); } catch (_error) {}
1323
+ signalChild("SIGKILL");
1279
1324
  settle({ status: null, error });
1325
+ return;
1280
1326
  }
1327
+ scheduleCompletion();
1281
1328
  });
1282
1329
  };
1283
1330
  collect(child.stdout, (chunk) => { stdout += chunk; });
@@ -1324,14 +1371,94 @@ function parseMonthDayResetDate(dateStr, now = new Date()) {
1324
1371
  return candidate.toISOString();
1325
1372
  }
1326
1373
 
1374
+ function parseKiroResetDate(dateStr, now = new Date()) {
1375
+ if (typeof dateStr !== "string") return null;
1376
+ if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
1377
+ const candidate = new Date(`${dateStr}T00:00:00.000Z`);
1378
+ if (
1379
+ Number.isFinite(candidate.getTime()) &&
1380
+ candidate.toISOString().slice(0, 10) === dateStr
1381
+ ) {
1382
+ return candidate.toISOString();
1383
+ }
1384
+ return null;
1385
+ }
1386
+ return parseMonthDayResetDate(dateStr, now);
1387
+ }
1388
+
1327
1389
  function isKiroUsageOutputComplete(output) {
1328
- const lowered = stripAnsi(output).toLowerCase();
1329
- return lowered.includes("covered in plan")
1330
- || lowered.includes("resets on")
1331
- || lowered.includes("bonus credits")
1332
- || lowered.includes("plan:")
1333
- || lowered.includes("managed by admin")
1334
- || lowered.includes("managed by organization");
1390
+ try {
1391
+ parseKiroUsageOutput(output);
1392
+ return true;
1393
+ } catch (_error) {
1394
+ return false;
1395
+ }
1396
+ }
1397
+
1398
+ function parseKiroCliVersion(output) {
1399
+ const match = String(output || "").match(
1400
+ /(?:kiro-cli\s+)?(\d+)\.(\d+)\.(\d+)/i,
1401
+ );
1402
+ if (!match) return null;
1403
+ return {
1404
+ major: Number(match[1]),
1405
+ minor: Number(match[2]),
1406
+ patch: Number(match[3]),
1407
+ };
1408
+ }
1409
+
1410
+ function kiroCliRequiresPty(version) {
1411
+ if (!version) return false;
1412
+ if (version.major !== 2) return version.major > 2;
1413
+ return version.minor >= 13;
1414
+ }
1415
+
1416
+ function quotePosixShellArg(value) {
1417
+ return `'${String(value).replace(/'/g, `'"'"'`)}'`;
1418
+ }
1419
+
1420
+ function kiroPtyInvocation(binaryPath, args, platform = process.platform) {
1421
+ if (platform === "darwin") {
1422
+ return {
1423
+ command: "/usr/bin/script",
1424
+ args: ["-q", "/dev/null", binaryPath, ...args],
1425
+ };
1426
+ }
1427
+ if (platform === "linux") {
1428
+ const commandLine = [binaryPath, ...args]
1429
+ .map(quotePosixShellArg)
1430
+ .join(" ");
1431
+ return {
1432
+ command: "script",
1433
+ args: ["-q", "-c", commandLine, "/dev/null"],
1434
+ };
1435
+ }
1436
+ return null;
1437
+ }
1438
+
1439
+ function combineKiroCommandOutput(result) {
1440
+ const stdout =
1441
+ typeof result?.stdout === "string" ? result.stdout.trim() : "";
1442
+ const stderr =
1443
+ typeof result?.stderr === "string" ? result.stderr.trim() : "";
1444
+ return [stdout, stderr].filter(Boolean).join("\n");
1445
+ }
1446
+
1447
+ function parseKiroCommandResult(result, { now = new Date() } = {}) {
1448
+ const output = combineKiroCommandOutput(result);
1449
+ if (
1450
+ result?.error?.code === "ETIMEDOUT" &&
1451
+ !isKiroUsageOutputComplete(output)
1452
+ ) {
1453
+ throw new Error("Kiro CLI timed out.");
1454
+ }
1455
+ if (!output && result?.status !== 0) {
1456
+ const detail = result?.error?.message
1457
+ ? `: ${result.error.message}`
1458
+ : ".";
1459
+ throw new Error(`Kiro CLI failed with status ${result?.status ?? "unknown"}${detail}`);
1460
+ }
1461
+ return parseKiroUsageOutput(output, { now });
1335
1462
  }
1336
1463
 
1337
1464
  function parseKiroUsageOutput(output, { now = new Date() } = {}) {
@@ -1364,8 +1491,12 @@ function parseKiroUsageOutput(output, { now = new Date() } = {}) {
1364
1491
  planName = modernPlan[1].split("\n")[0].trim() || planName;
1365
1492
  }
1366
1493
 
1367
- const resetMatch = stripped.match(/resets on (\d{2}\/\d{2})/i);
1368
- const primaryReset = resetMatch ? parseMonthDayResetDate(resetMatch[1], now) : null;
1494
+ const resetMatch = stripped.match(
1495
+ /resets on (\d{4}-\d{2}-\d{2}|\d{2}\/\d{2})/i,
1496
+ );
1497
+ const primaryReset = resetMatch
1498
+ ? parseKiroResetDate(resetMatch[1], now)
1499
+ : null;
1369
1500
 
1370
1501
  let creditsPercent = null;
1371
1502
  const percentMatch = stripped.match(/█+\s*(\d+)%/);
@@ -1845,38 +1976,76 @@ async function fetchCopilotLimits({
1845
1976
  }
1846
1977
  }
1847
1978
 
1848
- async function fetchKiroLimits({ commandRunner, now = new Date() } = {}) {
1849
- if (!(await isBinaryAvailable("kiro-cli", { commandRunner }))) {
1979
+ async function fetchKiroLimits({
1980
+ commandRunner,
1981
+ now = new Date(),
1982
+ platform = process.platform,
1983
+ } = {}) {
1984
+ const binaryPath = await whichBinary("kiro-cli", { commandRunner });
1985
+ if (!binaryPath) {
1850
1986
  return { configured: false };
1851
1987
  }
1852
1988
 
1853
- const result = await runCommand(
1989
+ const versionResult = await runCommand(
1854
1990
  commandRunner,
1855
- "kiro-cli",
1856
- ["chat", "--no-interactive", "/usage"],
1991
+ binaryPath,
1992
+ ["--version"],
1857
1993
  {
1858
- timeout: 20_000,
1994
+ timeout: 2_000,
1859
1995
  env: { ...process.env, TERM: "xterm-256color" },
1860
1996
  },
1861
1997
  );
1998
+ const version = parseKiroCliVersion(
1999
+ combineKiroCommandOutput(versionResult),
2000
+ );
2001
+ const args = ["chat", "--no-interactive", "/usage"];
2002
+ const pty = kiroPtyInvocation(binaryPath, args, platform);
2003
+
2004
+ // Kiro CLI 2.13 changed pipe behavior: /usage is treated as a normal model
2005
+ // prompt without a terminal. Go straight to a PTY so a refresh does not
2006
+ // accidentally spend credits on an assistant response. Older/unknown builds
2007
+ // retain the existing pipe-first behavior, with a bounded PTY fallback if
2008
+ // the output is not a recognizable usage panel.
2009
+ const attempts = [];
2010
+ if (kiroCliRequiresPty(version)) {
2011
+ if (pty) attempts.push(pty);
2012
+ } else {
2013
+ attempts.push({ command: binaryPath, args });
2014
+ if (pty) attempts.push(pty);
2015
+ }
1862
2016
 
1863
- const stdout = typeof result?.stdout === "string" ? result.stdout : "";
1864
- const stderr = typeof result?.stderr === "string" ? result.stderr : "";
1865
- const output = stderr.trim() || stdout.trim();
1866
-
2017
+ let lastError = null;
1867
2018
  try {
1868
- if (result?.error?.code === "ETIMEDOUT" && !isKiroUsageOutputComplete(output)) {
1869
- throw new Error("Kiro CLI timed out.");
2019
+ if (attempts.length === 0) {
2020
+ throw new Error(
2021
+ `Kiro CLI ${version ? `${version.major}.${version.minor}.${version.patch}` : ""} requires a pseudo-terminal on ${platform}.`,
2022
+ );
1870
2023
  }
1871
- if (!output && result?.status !== 0) {
1872
- throw new Error(`Kiro CLI failed with status ${result.status}.`);
2024
+ for (const attempt of attempts) {
2025
+ const result = await runCommand(
2026
+ commandRunner,
2027
+ attempt.command,
2028
+ attempt.args,
2029
+ {
2030
+ timeout: 20_000,
2031
+ env: { ...process.env, TERM: "xterm-256color" },
2032
+ completeWhen: (stdout, stderr) =>
2033
+ isKiroUsageOutputComplete(`${stdout}\n${stderr}`),
2034
+ completionGraceMs: 750,
2035
+ killProcessGroup: Boolean(pty),
2036
+ },
2037
+ );
2038
+ try {
2039
+ return {
2040
+ configured: true,
2041
+ error: null,
2042
+ ...parseKiroCommandResult(result, { now }),
2043
+ };
2044
+ } catch (error) {
2045
+ lastError = error;
2046
+ }
1873
2047
  }
1874
-
1875
- return {
1876
- configured: true,
1877
- error: null,
1878
- ...parseKiroUsageOutput(output, { now }),
1879
- };
2048
+ throw lastError || new Error("Failed to read Kiro usage.");
1880
2049
  } catch (error) {
1881
2050
  return {
1882
2051
  configured: true,
@@ -2906,7 +3075,7 @@ async function fetchUsageLimitsUncached({
2906
3075
  .catch((reason) => ({ configured: true, error: reason?.message || "Unknown error" })),
2907
3076
  withProviderTimeout(fetchGeminiLimits({ home, env, fetchImpl: providerFetch, commandRunner }), "Gemini", providerTimeoutMs)
2908
3077
  .catch((reason) => ({ configured: true, error: reason?.message || "Unknown error" })),
2909
- fetchKiroLimits({ commandRunner, now }),
3078
+ fetchKiroLimits({ commandRunner, now, platform }),
2910
3079
  fetchAntigravityLimits({ home, commandRunner, requestFn, fetchImpl: providerFetch, nowMs }),
2911
3080
  withProviderTimeout(fetchCopilotLimits({ home, env, fetchImpl: providerFetch, platform, securityRunner }), "GitHub Copilot", providerTimeoutMs)
2912
3081
  .catch((reason) => ({ configured: true, error: reason?.message || "Unknown error" })),
@@ -3086,6 +3255,7 @@ module.exports = {
3086
3255
  normalizeGeminiQuotaResponse,
3087
3256
  normalizeKimiUsageResponse,
3088
3257
  parseKiroUsageOutput,
3258
+ fetchKiroLimits,
3089
3259
  normalizeAntigravityResponse,
3090
3260
  parseListeningPorts,
3091
3261
  detectAntigravityProcess,
@@ -1 +0,0 @@
1
- import{r as n,z as a}from"./__vite-browser-external-DEhUaWQY.js";import{u as p}from"./DialogTitle-DLkuu1Iw.js";import{u as c}from"./useScrollLock-K0FPky1Y.js";const x=n.forwardRef(function(e,r){const{render:l,className:u,style:m,id:s,...t}=e,{store:i}=p(),o=c(s);return i.useSyncedValueWithCleanup("descriptionElementId",o),a("p",e,{ref:r,props:[{id:o},t]})});export{x as D};
@@ -1 +0,0 @@
1
- import{r as o}from"./__vite-browser-external-DEhUaWQY.js";import{h as r,i as t,p as s}from"./react-CllryaXi.js";function i(){!r.current&&t();const[e]=o.useState(s.current);return e}export{i as u};