tokentracker-cli 0.99.0 → 1.0.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 (106) hide show
  1. package/README.de.md +6 -5
  2. package/README.ja.md +6 -5
  3. package/README.ko.md +6 -5
  4. package/README.md +7 -5
  5. package/README.zh-CN.md +6 -5
  6. package/dashboard/dist/assets/{AchievementBadge-kRsjlB3p.js → AchievementBadge-Dpf3VBcS.js} +1 -1
  7. package/dashboard/dist/assets/{AchievementsPage-C3xybY0k.js → AchievementsPage-BSGbLI5V.js} +2 -2
  8. package/dashboard/dist/assets/{AchievementsSection-y5mok2w0.js → AchievementsSection-C10HXoq1.js} +1 -1
  9. package/dashboard/dist/assets/{BadgeDetailModal-IFLXYuKp.js → BadgeDetailModal-DajrEc3e.js} +1 -1
  10. package/dashboard/dist/assets/{BotAnimated-D6x0PDt2.js → BotAnimated-BpbTCJML.js} +1 -1
  11. package/dashboard/dist/assets/{Card-CiKwEyVu.js → Card-CDCj927L.js} +1 -1
  12. package/dashboard/dist/assets/{ClawdAnimated-BQFcAIOy.js → ClawdAnimated-CiTkm04x.js} +2 -2
  13. package/dashboard/dist/assets/{CommandPalette-BvpX8PM_.js → CommandPalette-CYHUUX7M.js} +1 -1
  14. package/dashboard/dist/assets/{CommunityStatsModal-D5rNlwfO.js → CommunityStatsModal-BHZehk5P.js} +1 -1
  15. package/dashboard/dist/assets/{ConfirmModal-CR0Evu8-.js → ConfirmModal-DZlT_xe_.js} +1 -1
  16. package/dashboard/dist/assets/{Controls-lyLUkbJW.js → Controls-Bcijikco.js} +1 -1
  17. package/dashboard/dist/assets/{DashboardPage-X8CLr_au.js → DashboardPage-yREqx-tx.js} +1 -1
  18. package/dashboard/dist/assets/DevicePage-DzisRlts.js +1 -0
  19. package/dashboard/dist/assets/{DialogClose-Bplj_718.js → DialogClose-CQ9hFUNv.js} +1 -1
  20. package/dashboard/dist/assets/DialogDescription-CLXWH3lG.js +1 -0
  21. package/dashboard/dist/assets/{DialogTitle-Ckzf1tdi.js → DialogTitle--bItxq3K.js} +1 -1
  22. package/dashboard/dist/assets/{FadeIn-C2Jqe95f.js → FadeIn-v5sAHZBu.js} +1 -1
  23. package/dashboard/dist/assets/{HeaderGithubStar-DgE7Cd5u.js → HeaderGithubStar-Bg8R51fN.js} +1 -1
  24. package/dashboard/dist/assets/{HoverTooltip-CEmo0N-P.js → HoverTooltip-DToNFKkJ.js} +1 -1
  25. package/dashboard/dist/assets/{IpCheckPage-BwkpsLaF.js → IpCheckPage-BmFXYXZm.js} +1 -1
  26. package/dashboard/dist/assets/{LandingPage-CA2klwbE.js → LandingPage-COpRacX0.js} +2 -2
  27. package/dashboard/dist/assets/{LeaderboardAvatar-B_PUenGZ.js → LeaderboardAvatar-D0l8_L_d.js} +1 -1
  28. package/dashboard/dist/assets/{LeaderboardPage-D6HGW3jX.js → LeaderboardPage-BJHS44Fq.js} +2 -2
  29. package/dashboard/dist/assets/{LeaderboardProfileModal-Bfo1dSsS.js → LeaderboardProfileModal-C1K9rSGn.js} +3 -3
  30. package/dashboard/dist/assets/{LeaderboardProfilePage-2OqwrqOs.js → LeaderboardProfilePage-CvR48D_y.js} +1 -1
  31. package/dashboard/dist/assets/{LimitsPage-BHrkLXHZ.js → LimitsPage-BN79yMkb.js} +1 -1
  32. package/dashboard/dist/assets/{LocalOnlyNotice-C45MmWYt.js → LocalOnlyNotice-BwTJpkDW.js} +1 -1
  33. package/dashboard/dist/assets/{LoginCard-BikBibax.js → LoginCard-BMXAg1rZ.js} +1 -1
  34. package/dashboard/dist/assets/{LoginModal-D0Aq85Zg.js → LoginModal-Bf0F_UPK.js} +1 -1
  35. package/dashboard/dist/assets/{LoginPage-B-kQaDQ_.js → LoginPage-BylH2waa.js} +1 -1
  36. package/dashboard/dist/assets/{PetPage-ZgPREiwD.js → PetPage-X4v_J-Uj.js} +1 -1
  37. package/dashboard/dist/assets/{PopoverPopup-eQgg3h1i.js → PopoverPopup-yEQVU5C_.js} +1 -1
  38. package/dashboard/dist/assets/{ProviderIcon-nDBPxn0N.js → ProviderIcon-KRXIghW0.js} +1 -1
  39. package/dashboard/dist/assets/{ResetPasswordPage-CjsOtiGr.js → ResetPasswordPage-DQQF2rsl.js} +1 -1
  40. package/dashboard/dist/assets/{SegmentedControl-6NcttkEH.js → SegmentedControl-VkVwcoXk.js} +1 -1
  41. package/dashboard/dist/assets/{Select-CzEhPICe.js → Select-CxW2C8OG.js} +1 -1
  42. package/dashboard/dist/assets/{SelectItemText-BwvzfXwj.js → SelectItemText-D6vhaI0Q.js} +1 -1
  43. package/dashboard/dist/assets/{ServiceStatusPage-C35wpxrT.js → ServiceStatusPage-CCKqUZhI.js} +1 -1
  44. package/dashboard/dist/assets/{SessionsPage-a30adkhf.js → SessionsPage-Huqt77Qt.js} +1 -1
  45. package/dashboard/dist/assets/{SettingsPage-C_7ZPBUF.js → SettingsPage-CpX8GYce.js} +2 -2
  46. package/dashboard/dist/assets/{SkillsPage-DsxkFnrV.js → SkillsPage-S1dtu_Cd.js} +1 -1
  47. package/dashboard/dist/assets/{TokenGalaxy-D_bXRotA.js → TokenGalaxy-BayM0FOG.js} +1 -1
  48. package/dashboard/dist/assets/{ToolbarRootContext-CL7ma7ba.js → ToolbarRootContext-B1KG8B5q.js} +1 -1
  49. package/dashboard/dist/assets/{TrendMonitor-QZBF2IEY.js → TrendMonitor-DYqz9nLw.js} +1 -1
  50. package/dashboard/dist/assets/{WidgetsPage-CWlxR0H-.js → WidgetsPage-WuzVeCBG.js} +1 -1
  51. package/dashboard/dist/assets/{WrappedPage-D8XQ72nF.js → WrappedPage-Bpn9GYHz.js} +1 -1
  52. package/dashboard/dist/assets/{__vite-browser-external-CTGqjrCe.js → __vite-browser-external-B1XxVtUQ.js} +3 -3
  53. package/dashboard/dist/assets/{agent-logos-BscA25fS.js → agent-logos-DVE956SY.js} +1 -1
  54. package/dashboard/dist/assets/{arrow-up-right-DTxCEGbR.js → arrow-up-right-B7aZy0wJ.js} +1 -1
  55. package/dashboard/dist/assets/{check-CCEoh2wj.js → check-55YI8PGo.js} +1 -1
  56. package/dashboard/dist/assets/{composite-B2s880f5.js → composite--O2XKSlW.js} +1 -1
  57. package/dashboard/dist/assets/{copy-CJVQglwG.js → copy-DDVFmqF5.js} +1 -1
  58. package/dashboard/dist/assets/{download-Cn-OpYm6.js → download-DmIFrL1S.js} +1 -1
  59. package/dashboard/dist/assets/{external-link-BnYlUn56.js → external-link-DwG_AAOo.js} +1 -1
  60. package/dashboard/dist/assets/{flame-D4yFLV1L.js → flame-ANwvantJ.js} +1 -1
  61. package/dashboard/dist/assets/{format-tokens-CBUNbBvp.js → format-tokens-BzZ_DfX2.js} +1 -1
  62. package/dashboard/dist/assets/{icons-CcgNgAvb.js → icons-CdyVgzlu.js} +1 -1
  63. package/dashboard/dist/assets/{index-CTjeDkbu.js → index-B-1uJU_R.js} +1 -1
  64. package/dashboard/dist/assets/{index-ZWeEKbo-.js → index-D0VhCSlC.js} +1 -1
  65. package/dashboard/dist/assets/{index-CkELwUyg.js → index-D8g1p_Ee.js} +1 -1
  66. package/dashboard/dist/assets/{info-DoehRSQU.js → info-n2XpcOlm.js} +1 -1
  67. package/dashboard/dist/assets/{link-2-D8xSsPqy.js → link-2-Bq9GUX22.js} +1 -1
  68. package/dashboard/dist/assets/{loader-circle-DMu0-X5r.js → loader-circle-fkYFxXuJ.js} +1 -1
  69. package/dashboard/dist/assets/{maximize-2-DLyYsZvE.js → maximize-2-C5v08iPD.js} +1 -1
  70. package/dashboard/dist/assets/{modifiers.esm-Dm5Xy2jA.js → modifiers.esm-AG_bzlWZ.js} +1 -1
  71. package/dashboard/dist/assets/{monitor-smartphone-5uZGQNGJ.js → monitor-smartphone-BEjlJhuw.js} +1 -1
  72. package/dashboard/dist/assets/{plus-8fnU0dkt.js → plus-BfdtMxnD.js} +1 -1
  73. package/dashboard/dist/assets/{provider-display-B3ed-pSc.js → provider-display-BvjuoQty.js} +2 -2
  74. package/dashboard/dist/assets/{react-Gft01KYk.js → react-f77D-LSn.js} +1 -1
  75. package/dashboard/dist/assets/{search-jqzJg2kG.js → search-Dmczow8i.js} +1 -1
  76. package/dashboard/dist/assets/{skills-api-Bwn_xcHV.js → skills-api-BuqPQei_.js} +1 -1
  77. package/dashboard/dist/assets/{sortable.esm-CYjzLCp7.js → sortable.esm-CDAVQaFQ.js} +1 -1
  78. package/dashboard/dist/assets/{store-CgJHe9jU.js → store-C2inKcM-.js} +1 -1
  79. package/dashboard/dist/assets/{terminal-CZ5j8yEQ.js → terminal-C1O422UZ.js} +1 -1
  80. package/dashboard/dist/assets/{trash-DtMLjI_S.js → trash-CXOKPZfQ.js} +1 -1
  81. package/dashboard/dist/assets/{use-community-stats-Px3dHGlR.js → use-community-stats-CKfyxLvl.js} +1 -1
  82. package/dashboard/dist/assets/{use-latest-request-guard-B7Vw4Wsd.js → use-latest-request-guard-C3rQR4BN.js} +1 -1
  83. package/dashboard/dist/assets/{use-limits-display-prefs-DWWrcMPi.js → use-limits-display-prefs-Ic4GUPRY.js} +1 -1
  84. package/dashboard/dist/assets/{use-ordered-list-CevbB79U.js → use-ordered-list-Cvbz_wcj.js} +1 -1
  85. package/dashboard/dist/assets/use-reduced-motion-DewlF5tk.js +1 -0
  86. package/dashboard/dist/assets/{use-session-efficiency-pref-DoIaI0vm.js → use-session-efficiency-pref-u_qW99gD.js} +1 -1
  87. package/dashboard/dist/assets/{use-transform-qRwUetOk.js → use-transform-CVGiBxJK.js} +1 -1
  88. package/dashboard/dist/assets/{use-usage-limits-DlP7yg78.js → use-usage-limits-MPu696v0.js} +1 -1
  89. package/dashboard/dist/assets/{useCurrency-DRUe8YoY.js → useCurrency-BOBz18If.js} +1 -1
  90. package/dashboard/dist/assets/{useTokenFormat-CmLbznUC.js → useTokenFormat-BooCzJJZ.js} +1 -1
  91. package/dashboard/dist/assets/{zap-CS80c_uN.js → zap-M_x9dAwo.js} +1 -1
  92. package/dashboard/dist/index.html +13 -11
  93. package/dashboard/dist/ip-check.html +1 -1
  94. package/dashboard/dist/leaderboard.html +1 -1
  95. package/dashboard/dist/llms.txt +3 -2
  96. package/dashboard/dist/share.html +1 -1
  97. package/package.json +2 -2
  98. package/src/commands/init.js +10 -0
  99. package/src/commands/status.js +13 -0
  100. package/src/commands/sync.js +33 -0
  101. package/src/lib/pricing/seed-snapshot.json +1 -1
  102. package/src/lib/rollout.js +107 -10
  103. package/src/lib/skills-manager.js +2 -2
  104. package/dashboard/dist/assets/DevicePage-RCIANm45.js +0 -1
  105. package/dashboard/dist/assets/DialogDescription-C2EzE7DU.js +0 -1
  106. package/dashboard/dist/assets/use-reduced-motion-CCuEY-79.js +0 -1
@@ -3465,7 +3465,7 @@ function deriveOpencodeMessageFingerprint({ msg, totals, source }) {
3465
3465
  totals.reasoning_output_tokens,
3466
3466
  model,
3467
3467
  provider,
3468
- ].join("");
3468
+ ].join("\u0000");
3469
3469
  // Hashed rather than stored raw: the fingerprint is persisted per message in
3470
3470
  // cursors.json, and heavy OpenCode users carry tens of thousands of entries.
3471
3471
  return crypto.createHash("sha256").update(raw).digest("base64url").slice(0, 22);
@@ -15313,6 +15313,17 @@ function primeAgentSourceForProvider(provider) {
15313
15313
  return slug ? `prime-agent-${slug}` : "prime-agent";
15314
15314
  }
15315
15315
 
15316
+ // Maps one parsed JSONL line to { id, message, timestamp } or null. pi-family
15317
+ // files wrap each record as { type: "message", id, timestamp, message }.
15318
+ function readPiMessageEntry(entry) {
15319
+ if (!entry || entry.type !== "message") return null;
15320
+ return {
15321
+ id: typeof entry.id === "string" && entry.id ? entry.id : null,
15322
+ message: entry.message,
15323
+ timestamp: entry.timestamp,
15324
+ };
15325
+ }
15326
+
15316
15327
  async function parsePiLikeIncremental({
15317
15328
  sessionFiles,
15318
15329
  cursors,
@@ -15326,6 +15337,7 @@ async function parsePiLikeIncremental({
15326
15337
  resolveSessionFiles,
15327
15338
  resolveDefaultModel,
15328
15339
  sourceForProvider,
15340
+ readEntry = readPiMessageEntry,
15329
15341
  } = {}) {
15330
15342
  await ensureDir(path.dirname(queuePath));
15331
15343
  const projectEnabled = typeof projectQueuePath === "string" && projectQueuePath.length > 0;
@@ -15427,15 +15439,16 @@ async function parsePiLikeIncremental({
15427
15439
  let entry;
15428
15440
  try { entry = JSON.parse(line); } catch { continue; }
15429
15441
 
15430
- if (!entry || entry.type !== "message") continue;
15442
+ const record = readEntry(entry);
15443
+ if (!record) continue;
15431
15444
 
15432
- const msg = entry.message;
15445
+ const msg = record.message;
15433
15446
  if (!msg || msg.role !== "assistant") continue;
15434
15447
 
15435
15448
  const usage = msg.usage;
15436
15449
  if (!usage || typeof usage !== "object") continue;
15437
15450
 
15438
- const entryId = typeof entry.id === "string" && entry.id ? entry.id : null;
15451
+ const entryId = record.id;
15439
15452
  if (!entryId) continue;
15440
15453
  if (seenIds.has(entryId)) continue;
15441
15454
 
@@ -15461,8 +15474,8 @@ async function parsePiLikeIncremental({
15461
15474
  let tsMs = null;
15462
15475
  if (Number.isFinite(Number(msg.timestamp)) && Number(msg.timestamp) > 0) {
15463
15476
  tsMs = Number(msg.timestamp);
15464
- } else if (typeof entry.timestamp === "string" && entry.timestamp) {
15465
- const parsed = Date.parse(entry.timestamp);
15477
+ } else if (typeof record.timestamp === "string" && record.timestamp) {
15478
+ const parsed = Date.parse(record.timestamp);
15466
15479
  if (Number.isFinite(parsed) && parsed > 0) tsMs = parsed;
15467
15480
  }
15468
15481
  if (tsMs == null) {
@@ -15573,11 +15586,12 @@ async function parsePiLikeIncremental({
15573
15586
  if (!line || !line.trim()) continue;
15574
15587
  let entry;
15575
15588
  try { entry = JSON.parse(line); } catch { continue; }
15576
- const msg = entry?.type === "message" ? entry.message : null;
15589
+ const record = readEntry(entry);
15590
+ const msg = record ? record.message : null;
15577
15591
  const usage = msg?.role === "assistant" ? msg.usage : null;
15578
15592
  if (!usage || typeof usage !== "object") continue;
15579
15593
 
15580
- const entryId = typeof entry.id === "string" && entry.id ? entry.id : null;
15594
+ const entryId = record.id;
15581
15595
  if (!entryId || projectSeenIds.has(entryId)) continue;
15582
15596
 
15583
15597
  const input = toNonNegativeInt(usage.input);
@@ -15599,8 +15613,8 @@ async function parsePiLikeIncremental({
15599
15613
  let tsMs = null;
15600
15614
  if (Number.isFinite(Number(msg.timestamp)) && Number(msg.timestamp) > 0) {
15601
15615
  tsMs = Number(msg.timestamp);
15602
- } else if (typeof entry.timestamp === "string" && entry.timestamp) {
15603
- const parsed = Date.parse(entry.timestamp);
15616
+ } else if (typeof record.timestamp === "string" && record.timestamp) {
15617
+ const parsed = Date.parse(record.timestamp);
15604
15618
  if (Number.isFinite(parsed) && parsed > 0) tsMs = parsed;
15605
15619
  }
15606
15620
  const bucketStart = tsMs == null
@@ -15700,6 +15714,85 @@ async function parsePrimeAgentIncremental(options = {}) {
15700
15714
  });
15701
15715
  }
15702
15716
 
15717
+ // ─────────────────────────────────────────────────────────────────────────────
15718
+ // MiniMax Code (MiniMax's desktop coding agent) — passive JSONL reader
15719
+ // (~/.minimax/v2/sessions/YYYY/MM/DD/<HH-MM-SS-mmm>-session_<id>/messages.jsonl)
15720
+ //
15721
+ // Records carry pi-shaped usage (input excludes cacheRead) and a ms-epoch
15722
+ // message.timestamp, but have no type:"message" wrapper and dedupe on the
15723
+ // top-level message_id. MiniMax Code routes to many upstream models and records
15724
+ // the model per message. Its usage.cost block is always 0, so it is ignored in
15725
+ // favor of normal pricing. Migrated legacy sessions replay as model
15726
+ // "historical-transcript" with all-zero usage and are dropped by the engine's
15727
+ // zero-token guard. There is no cwd header, so no project attribution.
15728
+ // ─────────────────────────────────────────────────────────────────────────────
15729
+
15730
+ const MINIMAX_CODE_SOURCE = "minimax-code";
15731
+ const MINIMAX_CODE_SESSION_FILE = "messages.jsonl";
15732
+ // sessions / YYYY / MM / DD / <session dir> / messages.jsonl
15733
+ const MINIMAX_CODE_MAX_SESSION_DEPTH = 5;
15734
+
15735
+ function resolveMinimaxCodeHome(env = process.env) {
15736
+ if (env.TOKENTRACKER_MINIMAX_HOME) return expandHomePath(env.TOKENTRACKER_MINIMAX_HOME, env);
15737
+ const home = env.HOME || require("node:os").homedir();
15738
+ if (process.platform === "win32") {
15739
+ return pickWin32ProviderPath({
15740
+ env,
15741
+ nativeValue: path.join(home, ".minimax"),
15742
+ wslProviderDir: ".minimax",
15743
+ });
15744
+ }
15745
+ return path.join(home, ".minimax");
15746
+ }
15747
+
15748
+ function resolveMinimaxCodeSessionsDir(env = process.env) {
15749
+ const minimaxHome = resolveMinimaxCodeHome(env);
15750
+ return minimaxHome ? path.join(minimaxHome, "v2", "sessions") : null;
15751
+ }
15752
+
15753
+ function resolveMinimaxCodeSessionFiles(env = process.env) {
15754
+ const sessionsDir = resolveMinimaxCodeSessionsDir(env);
15755
+ if (!sessionsDir) return [];
15756
+ const files = [];
15757
+ const walk = (dir, depth) => {
15758
+ let entries;
15759
+ try { entries = fssync.readdirSync(dir, { withFileTypes: true }); } catch { return; }
15760
+ for (const entry of entries) {
15761
+ const fullPath = path.join(dir, entry.name);
15762
+ if (entry.isDirectory()) {
15763
+ if (depth < MINIMAX_CODE_MAX_SESSION_DEPTH) walk(fullPath, depth + 1);
15764
+ } else if (entry.isFile() && entry.name === MINIMAX_CODE_SESSION_FILE && depth > 1) {
15765
+ files.push(fullPath);
15766
+ }
15767
+ }
15768
+ };
15769
+ walk(sessionsDir, 1);
15770
+ files.sort((a, b) => a.localeCompare(b));
15771
+ return files;
15772
+ }
15773
+
15774
+ function readMinimaxCodeEntry(entry) {
15775
+ if (!entry || typeof entry !== "object" || !entry.message) return null;
15776
+ return {
15777
+ id: typeof entry.message_id === "string" && entry.message_id ? entry.message_id : null,
15778
+ message: entry.message,
15779
+ timestamp: null,
15780
+ };
15781
+ }
15782
+
15783
+ async function parseMinimaxCodeIncremental(options = {}) {
15784
+ return parsePiLikeIncremental({
15785
+ ...options,
15786
+ // Session files have no cwd header, so project attribution is unsupported.
15787
+ projectQueuePath: undefined,
15788
+ stateKey: "minimaxCode",
15789
+ resolveSessionFiles: resolveMinimaxCodeSessionFiles,
15790
+ resolveDefaultModel: () => `${MINIMAX_CODE_SOURCE}-unknown`,
15791
+ sourceForProvider: () => MINIMAX_CODE_SOURCE,
15792
+ readEntry: readMinimaxCodeEntry,
15793
+ });
15794
+ }
15795
+
15703
15796
  // ─────────────────────────────────────────────────────────────────────────────
15704
15797
  // Craft Agents (lukilabs/craft-agents-oss) — passive JSONL reader
15705
15798
  //
@@ -22935,6 +23028,10 @@ module.exports = {
22935
23028
  resolvePrimeAgentSessionFiles,
22936
23029
  resolvePrimeAgentDefaultModel,
22937
23030
  parsePrimeAgentIncremental,
23031
+ resolveMinimaxCodeHome,
23032
+ resolveMinimaxCodeSessionsDir,
23033
+ resolveMinimaxCodeSessionFiles,
23034
+ parseMinimaxCodeIncremental,
22938
23035
  resolveCraftConfigDir,
22939
23036
  resolveCraftWorkspaceRoots,
22940
23037
  resolveCraftSessionFiles,
@@ -490,13 +490,13 @@ function hashDirectory(dir) {
490
490
  continue;
491
491
  }
492
492
  const execBit = process.platform === "win32" ? 0 : stat.mode & 0o111 ? 1 : 0;
493
- hash.update(`${rel}${execBit}`);
493
+ hash.update(`${rel}\u0000${execBit}\u0000`);
494
494
  try {
495
495
  hash.update(fs.readFileSync(abs));
496
496
  } catch (_e) {
497
497
  // unreadable file — fold its absence in deterministically
498
498
  }
499
- hash.update("");
499
+ hash.update("\u0000");
500
500
  }
501
501
  }
502
502
  };
@@ -1 +0,0 @@
1
- import{a as b,r as l,j as r,c as e,i as v}from"./__vite-browser-external-CTGqjrCe.js";const x={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1,VITE_APP_VERSION:"0.99.0",VITE_INSFORGE_ANON_KEY:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3OC0xMjM0LTU2NzgtOTBhYi1jZGVmMTIzNDU2NzgiLCJlbWFpbCI6ImFub25AaW5zZm9yZ2UuY29tIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODExNDU5NDd9.T0auta_IrVIh0uXW1bob5QSnzvsnJmN28r5XkSGEuQY",VITE_INSFORGE_BASE_URL:"https://srctyff5.us-east.insforge.app"};function f(){return v(),`${(x&&"https://srctyff5.us-east.insforge.app"||"https://srctyff5.us-east.insforge.app").replace(/\/$/,"")}/functions/tokentracker-device-flow-grant`}function p(s){return(s||"").toUpperCase().replace(/\s+/g,"").replace(/[^A-Z0-9-]/g,"")}function h(){const s=b(),[m,g]=l.useState(""),[i,a]=l.useState({kind:"idle",message:""});l.useEffect(()=>{try{const d=new URLSearchParams(window.location.search).get("user_code");d&&g(p(d))}catch{}},[]);async function u(c){if(c?.preventDefault?.(),!s?.signedIn){a({kind:"error",message:e("device.approval.error.sign_in")});return}const d=p(m);if(!/^[A-HJKMNP-Z2-9]{4}-[A-HJKMNP-Z2-9]{4}$/.test(d)){a({kind:"error",message:e("device.approval.error.invalid_code")});return}a({kind:"working",message:e("device.approval.action.approving")});try{const n=await s.getAccessToken?.();if(!n){a({kind:"error",message:e("device.approval.error.no_token")});return}const o=await fetch(f(),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},body:JSON.stringify({user_code:d})}),t=await o.json().catch(()=>({}));o.ok?a({kind:"success",message:t.status==="already_approved"?t.client_info?e("device.approval.success.already_client",{client:t.client_info}):e("device.approval.success.already"):t.client_info?e("device.approval.success.approved_client",{client:t.client_info}):e("device.approval.success.approved")}):o.status===404?a({kind:"error",message:e("device.approval.error.not_found")}):o.status===410?a({kind:"error",message:e("device.approval.error.expired")}):o.status===401?a({kind:"error",message:e("device.approval.error.session_expired")}):a({kind:"error",message:t?.error?e("device.approval.error.server_detail",{message:t.error}):e("device.approval.error.server",{status:o.status})})}catch(n){a({kind:"error",message:e("device.approval.error.network",{message:n?.message||n})})}}return r.jsx("div",{className:"min-h-screen flex items-center justify-center bg-white dark:bg-oai-gray-950 px-6 py-12",children:r.jsxs("div",{className:"w-full max-w-md rounded-xl border border-oai-gray-200 dark:border-oai-gray-800 bg-white dark:bg-oai-gray-900 p-8",children:[r.jsx("h1",{className:"text-2xl font-semibold text-oai-gray-900 dark:text-white mb-2",children:e("device.approval.title")}),r.jsx("p",{className:"text-sm text-oai-gray-500 dark:text-oai-gray-400 mb-6",children:e("device.approval.description")}),s?.signedIn?null:r.jsx("div",{className:"rounded-md border border-amber-200 bg-amber-50 dark:bg-amber-900/20 dark:border-amber-800 p-4 mb-4",children:r.jsx("p",{className:"text-sm text-amber-700 dark:text-amber-300",children:e("device.approval.sign_in_banner")})}),r.jsxs("form",{onSubmit:u,className:"space-y-4",children:[r.jsxs("label",{className:"block",children:[r.jsx("span",{className:"block text-xs font-medium uppercase tracking-wide text-oai-gray-500 dark:text-oai-gray-400 mb-1",children:e("device.approval.code_label")}),r.jsx("input",{type:"text",value:m,onChange:c=>g(p(c.target.value)),placeholder:"XXXX-XXXX",spellCheck:!1,autoCapitalize:"characters",maxLength:9,className:"w-full font-mono text-xl tracking-widest text-center rounded-md border border-oai-gray-300 dark:border-oai-gray-700 bg-white dark:bg-oai-gray-900 text-oai-gray-900 dark:text-white px-4 py-3 focus:outline-none focus:ring-inset focus:ring-2 focus:ring-emerald-600"})]}),r.jsx("button",{type:"submit",disabled:i.kind==="working"||!s?.signedIn,className:"w-full rounded-md bg-emerald-600 hover:bg-emerald-500 disabled:bg-oai-gray-300 disabled:cursor-not-allowed text-white font-medium py-3 transition-colors",children:i.kind==="working"?e("device.approval.action.approving"):e("device.approval.action.approve")})]}),i.kind==="success"&&r.jsx("div",{className:"mt-4 rounded-md border border-emerald-200 bg-emerald-50 dark:bg-emerald-900/20 dark:border-emerald-800 p-4",children:r.jsx("p",{className:"text-sm text-emerald-700 dark:text-emerald-300",children:i.message})}),i.kind==="error"&&r.jsx("div",{className:"mt-4 rounded-md border border-red-200 bg-red-50 dark:bg-red-900/20 dark:border-red-800 p-4",children:r.jsx("p",{className:"text-sm text-red-700 dark:text-red-300",children:i.message})})]})})}export{h as default};
@@ -1 +0,0 @@
1
- import{r as n,v as a}from"./__vite-browser-external-CTGqjrCe.js";import{u as p}from"./DialogTitle-Ckzf1tdi.js";import{u as c}from"./composite-B2s880f5.js";const x=n.forwardRef(function(e,r){const{render:l,className:u,style:m,id:s,...t}=e,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-CTGqjrCe.js";import{h as r,i as t,p as s}from"./react-Gft01KYk.js";function i(){!r.current&&t();const[e]=o.useState(s.current);return e}export{i as u};