tokentracker-cli 0.87.4 → 0.87.5

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 (114) hide show
  1. package/dashboard/dist/assets/AchievementBadge-_BbqyV4s.js +1 -0
  2. package/dashboard/dist/assets/{AchievementsPage-CqIWdffx.js → AchievementsPage-DlXdQMuk.js} +2 -2
  3. package/dashboard/dist/assets/{AchievementsSection-RAoIBoQ_.js → AchievementsSection-BAL23Qum.js} +1 -1
  4. package/dashboard/dist/assets/{BadgeDetailModal-CYaSfxwZ.js → BadgeDetailModal-D5VYBn1e.js} +1 -1
  5. package/dashboard/dist/assets/{Card-Cl4XFCGL.js → Card-BCAAH2Tv.js} +1 -1
  6. package/dashboard/dist/assets/{ClawdAnimated-DuFB46-u.js → ClawdAnimated-BaeJ4goq.js} +1 -1
  7. package/dashboard/dist/assets/{CommandPalette-CLfTNQK0.js → CommandPalette-DaBo0N_t.js} +1 -1
  8. package/dashboard/dist/assets/{CommunityStatsModal-DCRCXmPl.js → CommunityStatsModal-DtnbqllK.js} +1 -1
  9. package/dashboard/dist/assets/{ConfirmModal-B0IuSw4g.js → ConfirmModal-BdIbatZd.js} +1 -1
  10. package/dashboard/dist/assets/{Controls-BJF1FutB.js → Controls-CtlnwG2h.js} +1 -1
  11. package/dashboard/dist/assets/DashboardPage-B7YSxJXW.js +1 -0
  12. package/dashboard/dist/assets/{DevicePage-iZn2m4Y3.js → DevicePage-Y1QufKqx.js} +1 -1
  13. package/dashboard/dist/assets/{DialogClose-CdPKVRcX.js → DialogClose-BA6Fr6X7.js} +1 -1
  14. package/dashboard/dist/assets/DialogDescription-JjVfYyrp.js +1 -0
  15. package/dashboard/dist/assets/DialogTitle-CQlYwz-I.js +1 -0
  16. package/dashboard/dist/assets/{FadeIn-Bb3pNOAn.js → FadeIn-C7oxsfI-.js} +1 -1
  17. package/dashboard/dist/assets/{HeaderGithubStar-CtUK-3_x.js → HeaderGithubStar-5eKhC60J.js} +1 -1
  18. package/dashboard/dist/assets/{HoverTooltip-B3TmAZtV.js → HoverTooltip-Tf9XsZ6G.js} +1 -1
  19. package/dashboard/dist/assets/{IpCheckPage-CXcY3jc-.js → IpCheckPage-DEK7d2P9.js} +1 -1
  20. package/dashboard/dist/assets/{LandingPage-BK4sn4MV.js → LandingPage-Cev8vQ3V.js} +2 -2
  21. package/dashboard/dist/assets/{LeaderboardAvatar-AYzG1gTH.js → LeaderboardAvatar-BP8r8s_o.js} +1 -1
  22. package/dashboard/dist/assets/{LeaderboardPage-DhKcc74d.js → LeaderboardPage-CFinKL9O.js} +2 -2
  23. package/dashboard/dist/assets/{LeaderboardProfileModal-DvmDBmOL.js → LeaderboardProfileModal-DKSPH2_U.js} +4 -4
  24. package/dashboard/dist/assets/{LeaderboardProfilePage-1_GGQngL.js → LeaderboardProfilePage-DNSIoOdU.js} +3 -3
  25. package/dashboard/dist/assets/{LimitsPage-dSEtf2TB.js → LimitsPage-DDljQnW7.js} +4 -4
  26. package/dashboard/dist/assets/{LocalOnlyNotice-Bo1dtxi6.js → LocalOnlyNotice-BuNHRmPw.js} +1 -1
  27. package/dashboard/dist/assets/{LoginCard-BpjNU-ah.js → LoginCard-Dq5-__UO.js} +1 -1
  28. package/dashboard/dist/assets/{LoginModal-D3_vPG1R.js → LoginModal-BWuDhVTL.js} +1 -1
  29. package/dashboard/dist/assets/{LoginPage-BoeLhbwK.js → LoginPage-Dwb39YqH.js} +1 -1
  30. package/dashboard/dist/assets/{PetPage-BnkNWvcV.js → PetPage-BcvAOVH2.js} +1 -1
  31. package/dashboard/dist/assets/PopoverPopup-CnywL4jN.js +1 -0
  32. package/dashboard/dist/assets/{ProviderIcon-B3hZ1YWD.js → ProviderIcon-DAn58wfZ.js} +1 -1
  33. package/dashboard/dist/assets/{ResetPasswordPage-BusTiA5M.js → ResetPasswordPage-B-iZ9m8Z.js} +1 -1
  34. package/dashboard/dist/assets/{SegmentedControl-C_IwmWnO.js → SegmentedControl-DUlvUP02.js} +1 -1
  35. package/dashboard/dist/assets/{Select-Dj3hUGFb.js → Select-BbVO0yyC.js} +1 -1
  36. package/dashboard/dist/assets/SelectItemText-BCo4iRHj.js +1 -0
  37. package/dashboard/dist/assets/{ServiceStatusPage-BnnCouAs.js → ServiceStatusPage-Bf65rMHS.js} +1 -1
  38. package/dashboard/dist/assets/{SessionsPage-DMU5CiFf.js → SessionsPage-D2QWuLy9.js} +2 -2
  39. package/dashboard/dist/assets/SettingsPage-BtlZ7v0t.js +1 -0
  40. package/dashboard/dist/assets/SkillsPage-D7CXkuxF.js +1 -0
  41. package/dashboard/dist/assets/{TokenGalaxy-BddGGmti.js → TokenGalaxy-B1VqfzOB.js} +1 -1
  42. package/dashboard/dist/assets/ToolbarRootContext-DlRA_RFX.js +1 -0
  43. package/dashboard/dist/assets/{TrendMonitor-CVi7mLtI.js → TrendMonitor-D945Vzv_.js} +1 -1
  44. package/dashboard/dist/assets/{WidgetsPage-BdIGupvg.js → WidgetsPage-CZLhBVQL.js} +1 -1
  45. package/dashboard/dist/assets/{WrappedPage-BB-orT9Q.js → WrappedPage-Gf15Ax3y.js} +1 -1
  46. package/dashboard/dist/assets/__vite-browser-external-CRYifSM4.css +1 -0
  47. package/dashboard/dist/assets/{__vite-browser-external-egzerGU6.js → __vite-browser-external-_-wIz90P.js} +11 -4
  48. package/dashboard/dist/assets/{agent-logos-B2pH4QTS.js → agent-logos-Ccd-gCmY.js} +1 -1
  49. package/dashboard/dist/assets/{arrow-up-right-CEUtBwnj.js → arrow-up-right-DksoZ7Fm.js} +1 -1
  50. package/dashboard/dist/assets/{check-Ct-iMhaB.js → check-CFyujViz.js} +1 -1
  51. package/dashboard/dist/assets/{chevron-right-CIcqYgwy.js → chevron-right-D2Y9ycoK.js} +1 -1
  52. package/dashboard/dist/assets/{copy-Bx07orpr.js → copy-CvzVu4Jv.js} +1 -1
  53. package/dashboard/dist/assets/{download-6N9dBj_W.js → download-M9hdGe0X.js} +1 -1
  54. package/dashboard/dist/assets/{external-link-B39v_fs8.js → external-link-BrvgYr3H.js} +1 -1
  55. package/dashboard/dist/assets/{flame-xbjyxu-1.js → flame-CanCCWfM.js} +1 -1
  56. package/dashboard/dist/assets/{format-tokens-C1ZXX8ed.js → format-tokens-D-x5NM5s.js} +1 -1
  57. package/dashboard/dist/assets/{icons-D7dTRGnv.js → icons-iDxUXUbD.js} +1 -1
  58. package/dashboard/dist/assets/{index-BJ8Q1dU0.js → index-BPe3pmGu.js} +1 -1
  59. package/dashboard/dist/assets/{index-MbSf_y6N.js → index-CDK-qlvv.js} +1 -1
  60. package/dashboard/dist/assets/index-DhgQVkQR.js +9 -0
  61. package/dashboard/dist/assets/{info-YSmBFAMa.js → info-CS19GYkG.js} +1 -1
  62. package/dashboard/dist/assets/{limits-providers-BDltKBG_.js → limits-providers-Cep8gK1J.js} +1 -1
  63. package/dashboard/dist/assets/{link-2--CbT8swK.js → link-2-_GqbzcZy.js} +1 -1
  64. package/dashboard/dist/assets/{loader-circle-B5Hs89F2.js → loader-circle-DQlJKeCp.js} +1 -1
  65. package/dashboard/dist/assets/{maximize-2-Cj3P-Bay.js → maximize-2-AaA61WoH.js} +1 -1
  66. package/dashboard/dist/assets/{modifiers.esm-BXOR3VJH.js → modifiers.esm-DgAD_X3C.js} +1 -1
  67. package/dashboard/dist/assets/module-Ci-Lrj0I.js +2 -0
  68. package/dashboard/dist/assets/monitor-smartphone-C-KIKlP-.js +1 -0
  69. package/dashboard/dist/assets/provider-display-BWK3HqpN.js +42 -0
  70. package/dashboard/dist/assets/react-BGB0fHad.js +1 -0
  71. package/dashboard/dist/assets/{search-BswhdD2a.js → search-BhQx4B4T.js} +1 -1
  72. package/dashboard/dist/assets/skills-api-BtsImOWQ.js +1 -0
  73. package/dashboard/dist/assets/{sortable.esm-BXiHjoqY.js → sortable.esm-ew4S8Y1L.js} +1 -1
  74. package/dashboard/dist/assets/store-OBiS6gfr.js +1 -0
  75. package/dashboard/dist/assets/{terminal-DawYBEVr.js → terminal-GvWRPCY9.js} +1 -1
  76. package/dashboard/dist/assets/{trash-2-CSt4wZ-I.js → trash-2-COv_kp05.js} +1 -1
  77. package/dashboard/dist/assets/{use-community-stats-CHZTziox.js → use-community-stats-COxOg9PE.js} +1 -1
  78. package/dashboard/dist/assets/{use-limits-display-prefs-ChK-GCxK.js → use-limits-display-prefs-wf8pf1cF.js} +1 -1
  79. package/dashboard/dist/assets/{use-ordered-list-DyyjthSr.js → use-ordered-list-Dw-kLFB1.js} +1 -1
  80. package/dashboard/dist/assets/use-reduced-motion-B3wPPJY8.js +1 -0
  81. package/dashboard/dist/assets/{use-session-efficiency-pref-Dv1clCTZ.js → use-session-efficiency-pref-D9X2CzAz.js} +1 -1
  82. package/dashboard/dist/assets/{use-transform-DyBvIIFA.js → use-transform-BgfBM2dC.js} +1 -1
  83. package/dashboard/dist/assets/{use-usage-limits-DrhY6h3M.js → use-usage-limits-CrHu9ZJi.js} +1 -1
  84. package/dashboard/dist/assets/{useCurrency-BgFo76Yb.js → useCurrency-CmI0tWeH.js} +1 -1
  85. package/dashboard/dist/assets/useScrollLock-BtUfInbu.js +1 -0
  86. package/dashboard/dist/assets/{useTokenFormat-DrVDs8zo.js → useTokenFormat-DAHyFBMr.js} +1 -1
  87. package/dashboard/dist/assets/zap-C9NzWrn0.js +1 -0
  88. package/dashboard/dist/index.html +2 -2
  89. package/dashboard/dist/ip-check.html +2 -2
  90. package/dashboard/dist/leaderboard.html +2 -2
  91. package/dashboard/dist/share.html +2 -2
  92. package/package.json +1 -1
  93. package/src/lib/local-api.js +1 -1
  94. package/src/lib/pricing/seed-snapshot.json +1 -1
  95. package/src/lib/skills-manager.js +170 -7
  96. package/dashboard/dist/assets/AchievementBadge-jaWv39Mh.js +0 -1
  97. package/dashboard/dist/assets/DashboardPage-BFthq-Oc.js +0 -1
  98. package/dashboard/dist/assets/DialogDescription-pCAELf1b.js +0 -1
  99. package/dashboard/dist/assets/DialogTitle-Ul-NH9HD.js +0 -1
  100. package/dashboard/dist/assets/PopoverPopup-CkaOLLN4.js +0 -1
  101. package/dashboard/dist/assets/SelectItemText-BWaMX4pY.js +0 -1
  102. package/dashboard/dist/assets/SettingsPage-_cJl0qwK.js +0 -1
  103. package/dashboard/dist/assets/SkillsPage-Cz3tV65I.js +0 -1
  104. package/dashboard/dist/assets/ToolbarRootContext-Q_DQJlr5.js +0 -1
  105. package/dashboard/dist/assets/__vite-browser-external-CzQk3FUc.css +0 -1
  106. package/dashboard/dist/assets/index-pxtsHew5.js +0 -9
  107. package/dashboard/dist/assets/module-Bah3ijPg.js +0 -2
  108. package/dashboard/dist/assets/provider-display-BXtFP7Ak.js +0 -42
  109. package/dashboard/dist/assets/react-DujpLuOh.js +0 -1
  110. package/dashboard/dist/assets/skills-api-CGohvSGo.js +0 -1
  111. package/dashboard/dist/assets/store-BTdeRhbU.js +0 -1
  112. package/dashboard/dist/assets/use-reduced-motion-B9hTo-eX.js +0 -1
  113. package/dashboard/dist/assets/useScrollLock-DPW-g15w.js +0 -1
  114. package/dashboard/dist/assets/zap-Dsg_ZyH3.js +0 -1
@@ -14,28 +14,63 @@ const DEFAULT_REPOS = [
14
14
 
15
15
  const TARGETS = {
16
16
  claude: { id: "claude", label: "Claude", dir: () => path.join(os.homedir(), ".claude", "skills") },
17
- codex: { id: "codex", label: "Codex", dir: () => path.join(os.homedir(), ".codex", "skills") },
17
+ codex: { id: "codex", label: "Codex", dir: () => path.join(resolveCodexHome(), "skills") },
18
18
  grok: { id: "grok", label: "Grok", dir: () => path.join(resolveGrokHome(process.env), "skills") },
19
19
  antigravity: { id: "antigravity", label: "Antigravity", dirs: () => resolveAntigravitySkillDirs(process.env) },
20
20
  gemini: { id: "gemini", label: "Gemini", dir: () => path.join(os.homedir(), ".gemini", "skills") },
21
21
  opencode: { id: "opencode", label: "OpenCode", dir: () => path.join(os.homedir(), ".config", "opencode", "skills") },
22
+ openclaw: { id: "openclaw", label: "OpenClaw", dir: resolveOpenClawSkillsDir },
22
23
  hermes: { id: "hermes", label: "Hermes", dir: () => path.join(os.homedir(), ".hermes", "skills") },
24
+ // ZCode currently exposes skills through its plugin cache rather than a
25
+ // documented user-writable skills directory. Surface it in the inventory
26
+ // and filters, but never offer sync/delete operations against the cache.
27
+ zcode: { id: "zcode", label: "ZCode", manageable: false },
23
28
  agents: { id: "agents", label: "Agents", visible: false, dir: () => path.join(os.homedir(), ".agents", "skills") },
24
29
  };
25
30
 
31
+ function resolveCodexHome() {
32
+ return String(process.env.CODEX_HOME || "").trim() || path.join(os.homedir(), ".codex");
33
+ }
34
+
35
+ function resolveZcodeHome() {
36
+ return String(process.env.ZCODE_HOME || "").trim() || path.join(os.homedir(), ".zcode");
37
+ }
38
+
39
+ function resolveOpenClawHome() {
40
+ return String(process.env.TOKENTRACKER_OPENCLAW_HOME || "").trim() || path.join(os.homedir(), ".openclaw");
41
+ }
42
+
43
+ // OpenClaw can point at an arbitrary active workspace. Only scan that one
44
+ // explicit workspace; recursively scanning ~/.openclaw would incorrectly
45
+ // import backup/config snapshots belonging to other devices.
46
+ function resolveOpenClawSkillsDir() {
47
+ const home = resolveOpenClawHome();
48
+ const override = String(process.env.TOKENTRACKER_OPENCLAW_WORKSPACE || "").trim();
49
+ let workspace = override;
50
+ if (!workspace) {
51
+ const config = readJson(path.join(home, "openclaw.json"), null);
52
+ workspace = String(config?.agents?.defaults?.workspace || "").trim();
53
+ }
54
+ if (!workspace) workspace = path.join(home, "workspace");
55
+ if (!path.isAbsolute(workspace)) workspace = path.resolve(home, workspace);
56
+ return path.join(workspace, "skills");
57
+ }
58
+
26
59
  // Dual contract: a target exposes either dir() → string (single path) or
27
60
  // dirs() → string[] (parallel-write to multiple paths, e.g. Antigravity which
28
61
  // has separate user-skills dirs for the main app and the IDE). Consumers must
29
62
  // route through these helpers so the single-path targets stay zero-overhead.
30
63
  function targetDirs(target) {
64
+ if (!target || target.manageable === false) return [];
31
65
  if (typeof target.dirs === "function") return target.dirs();
32
- return [target.dir()];
66
+ if (typeof target.dir === "function") return [target.dir()];
67
+ return [];
33
68
  }
34
69
 
35
70
  // Used for surfacing one path in UI/local-api responses. For multi-dir targets
36
71
  // this is the canonical "first" entry by convention (main app before IDE).
37
72
  function targetPrimaryDir(target) {
38
- return targetDirs(target)[0];
73
+ return targetDirs(target)[0] || null;
39
74
  }
40
75
 
41
76
  const FETCH_TIMEOUT_MS = 20_000;
@@ -203,6 +238,7 @@ function targetList() {
203
238
  id: target.id,
204
239
  label: target.label,
205
240
  path: targetPrimaryDir(target),
241
+ manageable: target.manageable !== false,
206
242
  }));
207
243
  }
208
244
 
@@ -267,7 +303,7 @@ function findSkillMarker(dir) {
267
303
 
268
304
  const MAX_LOCAL_SKILL_SCAN_DEPTH = 3;
269
305
 
270
- function scanSkillDirectories(rootDir) {
306
+ function scanSkillDirectories(rootDir, { maxDepth = MAX_LOCAL_SKILL_SCAN_DEPTH } = {}) {
271
307
  const found = [];
272
308
  const walk = (dir, relDir = "", depth = 0) => {
273
309
  let entries = [];
@@ -288,13 +324,136 @@ function scanSkillDirectories(rootDir) {
288
324
  }
289
325
  // Direct symlinked skills are accepted above, but symlinked group folders
290
326
  // are not traversed so the scan stays within the target skills tree.
291
- if (entry.isDirectory() && depth + 1 < MAX_LOCAL_SKILL_SCAN_DEPTH) walk(full, rel, depth + 1);
327
+ if (entry.isDirectory() && depth + 1 < maxDepth) walk(full, rel, depth + 1);
292
328
  }
293
329
  };
294
330
  walk(rootDir);
295
331
  return found;
296
332
  }
297
333
 
334
+ const INVENTORY_PLUGIN_SCAN_DEPTH = 6;
335
+
336
+ function completeTargetStates(activeTargetId) {
337
+ return Object.fromEntries(
338
+ Object.keys(TARGETS).map((id) => [id, id === activeTargetId ? "synced" : "off"]),
339
+ );
340
+ }
341
+
342
+ function inventorySkillFromMarker({
343
+ marker,
344
+ directory,
345
+ id,
346
+ targetId,
347
+ scope,
348
+ sourceName = null,
349
+ }) {
350
+ try {
351
+ const metadata = readSkillMetadata(
352
+ fs.readFileSync(marker, "utf8"),
353
+ installNameFromDirectory(directory) || directory,
354
+ );
355
+ return {
356
+ id,
357
+ key: id,
358
+ name: metadata.name,
359
+ description: metadata.description,
360
+ directory,
361
+ readmeUrl: null,
362
+ repoOwner: null,
363
+ repoName: null,
364
+ repoBranch: null,
365
+ installedAt: null,
366
+ managed: false,
367
+ readOnly: true,
368
+ inventoryOnly: true,
369
+ scope,
370
+ sourceName,
371
+ targets: [targetId],
372
+ targetStates: completeTargetStates(targetId),
373
+ };
374
+ } catch (_e) {
375
+ return null;
376
+ }
377
+ }
378
+
379
+ // Plugin caches use <publisher>/<plugin>/<version>/skills/<skill>/SKILL.md.
380
+ // Walk only far enough to find a directory literally named "skills", then use
381
+ // the bounded skill scanner below it. We never traverse node_modules, hidden
382
+ // metadata directories, or symlinked group directories.
383
+ function scanPluginInventoryRoot({ root, targetId }) {
384
+ const found = [];
385
+ const walk = (dir, depth = 0) => {
386
+ let entries = [];
387
+ try {
388
+ entries = fs.readdirSync(dir, { withFileTypes: true });
389
+ } catch (_e) {
390
+ return;
391
+ }
392
+ entries.sort((a, b) => a.name.localeCompare(b.name));
393
+ for (const entry of entries) {
394
+ if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
395
+ if (!entry.name || entry.name.startsWith(".") || entry.name === "node_modules") continue;
396
+ const full = path.join(dir, entry.name);
397
+ if (entry.name.toLowerCase() === "skills") {
398
+ const container = path.relative(root, full).replace(/\\/g, "/");
399
+ const beforeSkills = container.split("/").filter(Boolean).slice(0, -1);
400
+ // Drop the cache version from the identity so installing a newer plugin
401
+ // version updates one inventory row instead of creating a duplicate.
402
+ const looksLikeVersion = (value) => /^v?\d+(?:\.\d+)*$/.test(String(value || ""));
403
+ const packageParts =
404
+ beforeSkills.length > 1 && looksLikeVersion(beforeSkills[beforeSkills.length - 1])
405
+ ? beforeSkills.slice(0, -1)
406
+ : beforeSkills;
407
+ const sourceName = packageParts.join("/") || beforeSkills.join("/") || null;
408
+ for (const directory of scanSkillDirectories(full, { maxDepth: 5 })) {
409
+ const marker = findSkillMarker(path.join(full, directory));
410
+ if (!marker) continue;
411
+ const sourceKey = sourceName || "plugin";
412
+ const id = `inventory:${targetId}:plugin:${sourceKey}:${directory}`;
413
+ const skill = inventorySkillFromMarker({
414
+ marker,
415
+ directory,
416
+ id,
417
+ targetId,
418
+ scope: "plugin",
419
+ sourceName,
420
+ });
421
+ if (skill) found.push(skill);
422
+ }
423
+ continue;
424
+ }
425
+ if (depth + 1 < INVENTORY_PLUGIN_SCAN_DEPTH) walk(full, depth + 1);
426
+ }
427
+ };
428
+ walk(root);
429
+ return found;
430
+ }
431
+
432
+ function listInventorySkills() {
433
+ const sources = [
434
+ {
435
+ root: path.join(resolveCodexHome(), "plugins", "cache"),
436
+ targetId: "codex",
437
+ },
438
+ {
439
+ root: path.join(os.homedir(), ".claude", "plugins", "cache"),
440
+ targetId: "claude",
441
+ },
442
+ {
443
+ root: path.join(resolveZcodeHome(), "cli", "plugins", "cache"),
444
+ targetId: "zcode",
445
+ },
446
+ ];
447
+ const byId = new Map();
448
+ for (const source of sources) {
449
+ const skills = scanPluginInventoryRoot(source);
450
+ // Later (normally newer, lexically sorted cache version) copies replace an
451
+ // older version with the same stable plugin+skill identity.
452
+ for (const skill of skills) byId.set(skill.id.toLowerCase(), skill);
453
+ }
454
+ return Array.from(byId.values());
455
+ }
456
+
298
457
  const HASH_IGNORE = new Set([".git", ".DS_Store", "Thumbs.db", ".gitignore"]);
299
458
 
300
459
  // Stable content fingerprint of a skill directory: walk files in sorted order,
@@ -625,7 +784,7 @@ function removeEmptyAncestors(startDir, stopDir) {
625
784
 
626
785
  function syncSkillToTarget(directory, targetId) {
627
786
  const target = TARGETS[targetId];
628
- if (!target) throw new Error(`Unsupported target: ${targetId}`);
787
+ if (!target || target.manageable === false) throw new Error(`Unsupported target: ${targetId}`);
629
788
  const source = managedSkillPath(directory);
630
789
  if (!fs.existsSync(source)) throw new Error(`Managed skill not found: ${directory}`);
631
790
  for (const baseDir of targetDirs(target)) {
@@ -738,7 +897,11 @@ function listInstalledSkills() {
738
897
  }
739
898
  }
740
899
 
741
- return [...managed, ...unmanaged.values()].sort((a, b) => a.name.localeCompare(b.name));
900
+ return [...managed, ...unmanaged.values(), ...listInventorySkills()].sort((a, b) => {
901
+ const byName = a.name.localeCompare(b.name);
902
+ if (byName !== 0) return byName;
903
+ return String(a.id || a.key || "").localeCompare(String(b.id || b.key || ""));
904
+ });
742
905
  }
743
906
 
744
907
  async function installSkill(skillInput, targetIds = ["claude", "codex"]) {
@@ -1 +0,0 @@
1
- import{m as o,d as N,j as r}from"./__vite-browser-external-egzerGU6.js";import{Z as $}from"./zap-Dsg_ZyH3.js";import{F as A}from"./flame-xbjyxu-1.js";const j=[["path",{d:"M10 22V7a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5a1 1 0 0 0-1-1H2",key:"1ah6g2"}],["rect",{x:"14",y:"2",width:"8",height:"8",rx:"1",key:"88lufb"}]],E=o("blocks",j);const L=[["path",{d:"M12 18V5",key:"adv99a"}],["path",{d:"M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4",key:"1e3is1"}],["path",{d:"M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5",key:"1gqd8o"}],["path",{d:"M17.997 5.125a4 4 0 0 1 2.526 5.77",key:"iwvgf7"}],["path",{d:"M18 18a4 4 0 0 0 2-7.464",key:"efp6ie"}],["path",{d:"M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517",key:"1gq6am"}],["path",{d:"M6 18a4 4 0 0 1-2-7.464",key:"k1g0md"}],["path",{d:"M6.003 5.125a4 4 0 0 0-2.526 5.77",key:"q97ue3"}]],C=o("brain",L);const T=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}],["path",{d:"M8 14h.01",key:"6423bh"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M8 18h.01",key:"lrp35t"}],["path",{d:"M12 18h.01",key:"mhygvu"}],["path",{d:"M16 18h.01",key:"kzsmim"}]],z=o("calendar-days",T);const B=[["path",{d:"M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z",key:"1vdc57"}],["path",{d:"M5 21h14",key:"11awu3"}]],q=o("crown",B);const H=[["path",{d:"M12.67 19a2 2 0 0 0 1.416-.588l6.154-6.172a6 6 0 0 0-8.49-8.49L5.586 9.914A2 2 0 0 0 5 11.328V18a1 1 0 0 0 1 1z",key:"18jl4k"}],["path",{d:"M16 8 2 22",key:"vp34q"}],["path",{d:"M17.5 15H9",key:"1oz8nu"}]],R=o("feather",H);const D=[["path",{d:"M18 19a5 5 0 0 1-5-5v8",key:"sz5oeg"}],["path",{d:"M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v5",key:"1w6njk"}],["circle",{cx:"13",cy:"12",r:"2",key:"1j92g6"}],["circle",{cx:"20",cy:"19",r:"2",key:"1obnsp"}]],F=o("folder-git-2",D);const I=[["path",{d:"M4 16v-2.38C4 11.5 2.97 10.5 3 8c.03-2.72 1.49-6 4.5-6C9.37 2 10 3.8 10 5.5c0 3.11-2 5.66-2 8.68V16a2 2 0 1 1-4 0Z",key:"1dudjm"}],["path",{d:"M20 20v-2.38c0-2.12 1.03-3.12 1-5.62-.03-2.72-1.49-6-4.5-6C14.63 6 14 7.8 14 9.5c0 3.11 2 5.66 2 8.68V20a2 2 0 1 0 4 0Z",key:"l2t8xc"}],["path",{d:"M16 17h4",key:"1dejxt"}],["path",{d:"M4 13h4",key:"1bwh8b"}]],G=o("footprints",I);const V=[["path",{d:"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5",key:"mvr1a0"}]],S=o("heart",V);const Z=[["path",{d:"M7.21 15 2.66 7.14a2 2 0 0 1 .13-2.2L4.4 2.8A2 2 0 0 1 6 2h12a2 2 0 0 1 1.6.8l1.6 2.14a2 2 0 0 1 .14 2.2L16.79 15",key:"143lza"}],["path",{d:"M11 12 5.12 2.2",key:"qhuxz6"}],["path",{d:"m13 12 5.88-9.8",key:"hbye0f"}],["path",{d:"M8 7h8",key:"i86dvs"}],["circle",{cx:"12",cy:"17",r:"5",key:"qbz8iq"}],["path",{d:"M12 18v-2h-.5",key:"fawc4q"}]],O=o("medal",Z);const P=[["path",{d:"M18 5h4",key:"1lhgn2"}],["path",{d:"M20 3v4",key:"1olli1"}],["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],X=o("moon-star",P);const K=[["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}],["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09",key:"u4xsad"}],["path",{d:"M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z",key:"676m9"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05",key:"92ym6u"}]],U=o("rocket",K);const W=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],Y=o("shield-check",W);const J=[["path",{d:"M16 7h6v6",key:"box55l"}],["path",{d:"m22 7-8.5 8.5-5-5L2 17",key:"1t1m79"}]],Q=o("trending-up",J),k=[{id:"token_titan",scope:"cloud",icon:q,format:"tokens",art:"/achievements/token-titan.png"},{id:"big_day",scope:"cloud",icon:$,format:"tokens",art:"/achievements/big-day.png"},{id:"wordsmith",scope:"cloud",icon:R,format:"tokens",art:"/achievements/wordsmith.png"},{id:"marathoner",scope:"cloud",icon:G,format:"days",art:"/achievements/marathoner.png"},{id:"streak",scope:"cloud",icon:A,format:"days",art:"/achievements/streak.png"},{id:"weekend_warrior",scope:"cloud",icon:z,format:"days",art:"/achievements/weekend-warrior.png"},{id:"momentum",scope:"cloud",icon:Q,format:"multiplier",art:"/achievements/momentum.png"},{id:"polyglot",scope:"cloud",icon:C,format:"count",art:"/achievements/polyglot.png"},{id:"trendsetter",scope:"cloud",icon:U,format:"count",art:"/achievements/trendsetter.png"},{id:"multitool",scope:"cloud",icon:E,format:"count",art:"/achievements/multitool.png"},{id:"podium",scope:"cloud",icon:O,format:"rank",art:"/achievements/podium.png"},{id:"veteran",scope:"cloud",icon:Y,format:"days",art:"/achievements/veteran.png"},{id:"project_hopper",scope:"local",icon:F,format:"count",art:"/achievements/project-hopper.png"},{id:"project_devotion",scope:"local",icon:S,format:"tokens",art:"/achievements/project-devotion.png"},{id:"night_owl",scope:"local",icon:X,format:"count",art:"/achievements/night-owl.png"}],u=new Map(k.map(e=>[e.id,e])),m=new Map(k.map((e,a)=>[e.id,a]));function de(e,a){return`achievements.badge.${e}.${a}`}function ee(e){return[...e||[]].sort((a,t)=>{const c=(t?.tier||0)-(a?.tier||0);return c!==0?c:(m.get(a?.id)??99)-(m.get(t?.id)??99)})}function re(e){const a=(e||[]).filter(t=>t&&(t.tier||0)>=1&&u.has(t.id));return a.length===0?null:ee(a)[0]}const v={1:"bronze",2:"silver",3:"gold",4:"diamond"},ie=["bronze","silver","gold","diamond"],ae={bronze:{rim:["#a06a44","#5c3a22"],face:["#d29a6c","#96602f"],glyph:"#3f2817",ring:"#e8c3a0",sheen:"rgba(255, 236, 220, 0.45)",label:"#a06a44"},silver:{rim:["#aab3bb","#67707b"],face:["#dde2e7","#9ba5ae"],glyph:"#39424b",ring:"#f2f5f7",sheen:"rgba(255, 255, 255, 0.55)",label:"#8b959f"},gold:{rim:["#c9971c","#8a6508"],face:["#f2ca52","#cf9c26"],glyph:"#5c430e",ring:"#ffe9a8",sheen:"rgba(255, 248, 214, 0.55)",label:"#b8860b"},diamond:{rim:["#62b1e0","#7c6fd9"],face:["#c8ecf6","#84b4ea"],glyph:"#27496d",ring:"#eafcff",sheen:"rgba(255, 255, 255, 0.65)",label:"#5a9bd8"}},y={rim:["#a8ada9","#7c817d"],face:["#cdd2ce","#a3a8a4"],glyph:"#6a706c",ring:"#dde1de",sheen:"rgba(255, 255, 255, 0.25)",label:"#8b908c"};function te(e,a=!1){return a||!e||e<1?y:ae[v[Math.min(e,4)]]||y}function se(e){return v[e]||null}const g={xs:18,sm:24,md:44,xl:88,lg:108},f={xs:.75,sm:1,md:1.5,xl:2,lg:2};function le({badgeId:e,tier:a=0,size:t="md",locked:c=!1,label:i,className:M=""}){const s=u.get(e),h=c||!a||a<1,n=te(a,h),d=t==="fill",l=d?"100%":g[t]||g.md,b=d?4:f[t]||f.md,[_,x]=N.useState(!1),p=s?.icon||null,w=!!s?.art&&!_;return r.jsx("span",{role:i?"img":void 0,"aria-label":i||void 0,"aria-hidden":i?void 0:!0,className:`inline-flex shrink-0 rounded-full ${M}`,style:{width:l,height:l,padding:b,background:`linear-gradient(135deg, ${n.rim[0]} 0%, ${n.ring} 42%, ${n.rim[1]} 100%)`,boxShadow:d||t==="md"||t==="xl"||t==="lg"?"0 0 0 1px rgba(10, 15, 12, 0.06), 0 1px 2px rgba(10, 15, 12, 0.08)":void 0},children:w?r.jsx("img",{src:s.art,alt:"",draggable:!1,loading:"lazy",onError:()=>x(!0),className:"h-full w-full rounded-full object-cover",style:h?{filter:"grayscale(1)",opacity:.55}:void 0}):r.jsx("span",{className:"flex h-full w-full items-center justify-center rounded-full",style:{background:`linear-gradient(145deg, ${n.face[0]}, ${n.face[1]})`},children:p?r.jsx(p,{size:d?64:Math.round(l*.5),color:n.glyph,strokeWidth:2}):null})})}export{le as A,k as B,S as H,Q as T,ae as a,de as b,u as c,ie as d,re as h,te as p,ee as s,se as t};