@hashimkarim/usagestat-linux-x64-gnu 2.0.2 → 2.2.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 (181) hide show
  1. package/native-manifest.json +808 -148
  2. package/package.json +112 -2
  3. package/plugins/abliteration/LICENSE +21 -0
  4. package/plugins/abliteration/icon.svg +5 -0
  5. package/plugins/abliteration/plugin.js +89 -0
  6. package/plugins/abliteration/plugin.json +24 -0
  7. package/plugins/aerostack/LICENSE +21 -0
  8. package/plugins/aerostack/icon.svg +1 -0
  9. package/plugins/aerostack/plugin.js +94 -0
  10. package/plugins/aerostack/plugin.json +24 -0
  11. package/plugins/aixy/icon.svg +1 -0
  12. package/plugins/aixy/plugin.js +5 -0
  13. package/plugins/aixy/plugin.json +9 -1
  14. package/plugins/antigravity/plugin.js +19 -10
  15. package/plugins/antigravity-cli/plugin.js +8 -3
  16. package/plugins/antigravity-ide/plugin.js +8 -5
  17. package/plugins/atlascloud/plugin.js +5 -0
  18. package/plugins/atlascloud/plugin.json +2 -1
  19. package/plugins/bifrost/icon.svg +3 -0
  20. package/plugins/bifrost/plugin.js +5 -0
  21. package/plugins/bifrost/plugin.json +9 -1
  22. package/plugins/chatbox/LICENSE +21 -0
  23. package/plugins/chatbox/icon.svg +4 -0
  24. package/plugins/chatbox/plugin.js +208 -0
  25. package/plugins/chatbox/plugin.json +24 -0
  26. package/plugins/claude/plugin.js +39 -2
  27. package/plugins/claudeplatform/LICENSE +21 -0
  28. package/plugins/claudeplatform/icon.svg +3 -0
  29. package/plugins/claudeplatform/plugin.js +244 -0
  30. package/plugins/claudeplatform/plugin.json +25 -0
  31. package/plugins/codex/plugin.js +14 -8
  32. package/plugins/codex/plugin.json +11 -2
  33. package/plugins/cosmic/LICENSE +21 -0
  34. package/plugins/cosmic/icon.svg +1 -0
  35. package/plugins/cosmic/plugin.js +134 -0
  36. package/plugins/cosmic/plugin.json +32 -0
  37. package/plugins/cursor/plugin.js +27 -8
  38. package/plugins/cursor-nightly/plugin.json +1 -1
  39. package/plugins/devpass/icon.svg +3 -0
  40. package/plugins/devpass/plugin.js +5 -0
  41. package/plugins/devpass/plugin.json +2 -1
  42. package/plugins/exa/LICENSE +21 -0
  43. package/plugins/exa/icon-color.svg +1 -0
  44. package/plugins/exa/icon.svg +1 -0
  45. package/plugins/exa/plugin.js +75 -0
  46. package/plugins/exa/plugin.json +32 -0
  47. package/plugins/fal/LICENSE +21 -0
  48. package/plugins/fal/icon-color.svg +1 -0
  49. package/plugins/fal/icon.svg +1 -0
  50. package/plugins/fal/plugin.js +74 -0
  51. package/plugins/fal/plugin.json +24 -0
  52. package/plugins/flora/LICENSE +21 -0
  53. package/plugins/flora/icon.svg +4 -0
  54. package/plugins/flora/plugin.js +93 -0
  55. package/plugins/flora/plugin.json +32 -0
  56. package/plugins/futureagi/LICENSE +21 -0
  57. package/plugins/futureagi/icon.svg +24 -0
  58. package/plugins/futureagi/plugin.js +139 -0
  59. package/plugins/futureagi/plugin.json +32 -0
  60. package/plugins/gemini-apps/LICENSE +1 -2
  61. package/plugins/gemini-apps/plugin.js +136 -465
  62. package/plugins/gemini-apps/plugin.json +13 -7
  63. package/plugins/gitkraken/icon.svg +2 -0
  64. package/plugins/gitkraken/plugin.js +5 -0
  65. package/plugins/gitkraken/plugin.json +9 -1
  66. package/plugins/googledeveloper/LICENSE +21 -0
  67. package/plugins/googledeveloper/icon.svg +3 -0
  68. package/plugins/googledeveloper/plugin.js +204 -0
  69. package/plugins/googledeveloper/plugin.json +25 -0
  70. package/plugins/helmcode/icon.svg +5 -0
  71. package/plugins/helmcode/plugin.js +120 -55
  72. package/plugins/helmcode/plugin.json +10 -2
  73. package/plugins/huggingface/plugin.js +6 -1
  74. package/plugins/huggingface/plugin.json +4 -3
  75. package/plugins/hyper/plugin.js +53 -47
  76. package/plugins/hyper/plugin.json +3 -2
  77. package/plugins/jetbrains-ai-assistant/LICENSE +22 -0
  78. package/plugins/jetbrains-ai-assistant/plugin.js +502 -16
  79. package/plugins/jetbrains-ai-assistant/plugin.json +27 -4
  80. package/plugins/kimi/plugin.js +54 -14
  81. package/plugins/kimi/plugin.json +46 -6
  82. package/plugins/langdock/LICENSE +21 -0
  83. package/plugins/langdock/icon.svg +4 -0
  84. package/plugins/langdock/plugin.js +106 -0
  85. package/plugins/langdock/plugin.json +25 -0
  86. package/plugins/linkup/LICENSE +21 -0
  87. package/plugins/linkup/icon.svg +10 -0
  88. package/plugins/linkup/plugin.js +46 -0
  89. package/plugins/linkup/plugin.json +24 -0
  90. package/plugins/lithosai/plugin.js +5 -0
  91. package/plugins/lithosai/plugin.json +2 -1
  92. package/plugins/llmman/icon.svg +4 -0
  93. package/plugins/llmman/plugin.js +5 -0
  94. package/plugins/llmman/plugin.json +9 -1
  95. package/plugins/munito/LICENSE +21 -0
  96. package/plugins/munito/icon.svg +7 -0
  97. package/plugins/munito/plugin.js +171 -0
  98. package/plugins/munito/plugin.json +24 -0
  99. package/plugins/muse/icon.svg +3 -0
  100. package/plugins/muse/plugin.js +5 -0
  101. package/plugins/muse/plugin.json +9 -1
  102. package/plugins/museai/plugin.js +10 -3
  103. package/plugins/museai/plugin.json +3 -2
  104. package/plugins/nous/plugin.js +5 -0
  105. package/plugins/nous/plugin.json +9 -1
  106. package/plugins/ollama/plugin.js +58 -0
  107. package/plugins/opencode-go/plugin.js +21 -9
  108. package/plugins/opendesign/LICENSE +21 -0
  109. package/plugins/opendesign/icon.svg +4 -0
  110. package/plugins/opendesign/plugin.js +108 -0
  111. package/plugins/opendesign/plugin.json +25 -0
  112. package/plugins/parallel/LICENSE +21 -0
  113. package/plugins/parallel/icon.svg +11 -0
  114. package/plugins/parallel/plugin.js +97 -0
  115. package/plugins/parallel/plugin.json +25 -0
  116. package/plugins/perplexity/LICENSE +22 -0
  117. package/plugins/perplexity/plugin.js +122 -0
  118. package/plugins/perplexity/plugin.json +36 -7
  119. package/plugins/qwencloud/LICENSE +21 -0
  120. package/plugins/qwencloud/plugin.js +197 -0
  121. package/plugins/qwencloud/plugin.json +17 -0
  122. package/plugins/raycast/icon.svg +4 -0
  123. package/plugins/raycast/plugin.js +5 -0
  124. package/plugins/raycast/plugin.json +9 -1
  125. package/plugins/replicate/plugin.js +5 -0
  126. package/plugins/replicate/plugin.json +2 -1
  127. package/plugins/sailresearch/LICENSE +21 -0
  128. package/plugins/sailresearch/icon.svg +4 -0
  129. package/plugins/sailresearch/plugin.js +104 -0
  130. package/plugins/sailresearch/plugin.json +24 -0
  131. package/plugins/siliconflow/LICENSE +21 -0
  132. package/plugins/siliconflow/icon.svg +3 -0
  133. package/plugins/siliconflow/plugin.js +87 -0
  134. package/plugins/siliconflow/plugin.json +32 -0
  135. package/plugins/sofya/LICENSE +21 -0
  136. package/plugins/sofya/icon.svg +3 -0
  137. package/plugins/sofya/plugin.js +86 -0
  138. package/plugins/sofya/plugin.json +24 -0
  139. package/plugins/soniox/LICENSE +21 -0
  140. package/plugins/soniox/icon.svg +3 -0
  141. package/plugins/soniox/plugin.js +103 -0
  142. package/plugins/soniox/plugin.json +24 -0
  143. package/plugins/synthetic/plugin.js +12 -0
  144. package/plugins/synthetic/plugin.json +51 -9
  145. package/plugins/tavily/LICENSE +21 -0
  146. package/plugins/tavily/icon.svg +3 -0
  147. package/plugins/tavily/plugin.js +61 -0
  148. package/plugins/tavily/plugin.json +24 -0
  149. package/plugins/tinyapi/LICENSE +21 -0
  150. package/plugins/tinyapi/icon.svg +4 -0
  151. package/plugins/tinyapi/plugin.js +73 -0
  152. package/plugins/tinyapi/plugin.json +25 -0
  153. package/plugins/traecn/LICENSE +21 -0
  154. package/plugins/traecn/icon.svg +3 -0
  155. package/plugins/traecn/plugin.js +103 -0
  156. package/plugins/traecn/plugin.json +25 -0
  157. package/plugins/tripo/LICENSE +21 -0
  158. package/plugins/tripo/icon.svg +4 -0
  159. package/plugins/tripo/plugin.js +60 -0
  160. package/plugins/tripo/plugin.json +24 -0
  161. package/plugins/typesafe/icon.svg +4 -0
  162. package/plugins/typesafe/plugin.js +85 -129
  163. package/plugins/typesafe/plugin.json +3 -2
  164. package/plugins/v0/plugin.js +5 -0
  165. package/plugins/v0/plugin.json +9 -1
  166. package/plugins/vercel/plugin.js +147 -0
  167. package/plugins/vercel/plugin.json +34 -3
  168. package/plugins/workbuddy/icon.svg +1 -1
  169. package/plugins/workbuddy/plugin.js +110 -19
  170. package/plugins/workbuddy/plugin.json +32 -2
  171. package/plugins/xai/plugin.js +9 -0
  172. package/plugins/xapi/LICENSE +21 -0
  173. package/plugins/xapi/icon.svg +1 -0
  174. package/plugins/xapi/plugin.js +90 -0
  175. package/plugins/xapi/plugin.json +25 -0
  176. package/plugins/xkiro/icon.svg +1 -0
  177. package/plugins/xkiro/plugin.js +5 -0
  178. package/plugins/xkiro/plugin.json +2 -1
  179. package/usagestat +0 -0
  180. package/usagestatd +0 -0
  181. package/plugins/cursor-nightly/plugin.js +0 -1416
@@ -0,0 +1,171 @@
1
+ // Generated by tools/vendor-codexbar-providers.cjs; see LICENSE.
2
+ globalThis.__usagestat_bundled_options = {"labels":["Daily spend limit","Monthly spend limit","Additional"],"defaults":{},"autoMode":"api"};
3
+ (function(defineProvider) {
4
+ // BEGIN UPSTREAM Sources/CodexBarCore/Resources/Plugins/munito.js
5
+ function _nullishCoalesce(lhs, rhsFn) {
6
+ if (lhs != null) {
7
+ return lhs;
8
+ } else {
9
+ return rhsFn();
10
+ }
11
+ }
12
+ defineProvider({
13
+ id: "munito",
14
+ name: "Munito",
15
+ endpoints: ["https://api.munito.ai"],
16
+ auth: { type: "bearer", secret: "MUNITO_API_KEY" },
17
+ settings: [{ key: "MUNITO_API_KEY", title: "Munito admin API key", type: "secure" }],
18
+ capabilities: ["http-status"],
19
+ async fetchUsage(ctx) {
20
+ const base = "https://api.munito.ai/admin/v1";
21
+ const response = await ctx.http.getWithOptional(`${base}/limits`, `${base}/organization`, {
22
+ retryPolicy: "transientIdempotent",
23
+ });
24
+ const message = `Munito returned HTTP ${response.status}.`;
25
+ if (response.status === 401) throw ctx.fail.authenticationExpired(message);
26
+ if (response.status === 403) {
27
+ throw ctx.fail.permissionDenied(
28
+ "Munito rejected the key: the Admin API needs a key with Read account data permission.",
29
+ );
30
+ }
31
+ // The native transientIdempotent retry already honors Retry-After; an explicit retry hint
32
+ // here would schedule a second, outer retry cycle (docs/plugins.md plugin retry contract).
33
+ if (response.status === 429) throw ctx.fail.rateLimited(message);
34
+ if (response.status >= 500) throw ctx.fail.providerUnavailable(message);
35
+ if (response.status !== 200) throw ctx.fail.apiFailure(message);
36
+ const fail = () => {
37
+ throw ctx.fail.parseFailure("Munito returned an unrecognized spend limits response.");
38
+ };
39
+ let root;
40
+ try {
41
+ root = JSON.parse(response.bodyText);
42
+ } catch (error) {
43
+ void error;
44
+ return fail();
45
+ }
46
+ if (!root || typeof root !== "object" || Array.isArray(root)) return fail();
47
+ const body = root;
48
+ const text = (value) => (typeof value === "string" && value.trim() ? value.trim() : undefined);
49
+ const money = (value, field) => {
50
+ const number =
51
+ typeof value === "number"
52
+ ? value
53
+ : typeof value === "string" && /^\s*-?\d+(?:\.\d+)?\s*$/.test(value)
54
+ ? Number(value)
55
+ : NaN;
56
+ if (!Number.isFinite(number) || number < 0) {
57
+ throw ctx.fail.parseFailure(`Munito returned an unusable ${field}.`);
58
+ }
59
+ return number;
60
+ };
61
+ const limit = (value, field) => (value == null ? undefined : money(value, field));
62
+ if (!Array.isArray(body.periods)) return fail();
63
+
64
+ const periods = [];
65
+ for (const raw of body.periods) {
66
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return fail();
67
+ const entry = raw;
68
+ const kind = text(entry.period);
69
+ if (kind !== "day" && kind !== "month") continue;
70
+ const stopped = text(entry.stopped_until);
71
+ let stoppedUntil;
72
+ if (stopped) {
73
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(stopped)) return fail();
74
+ try {
75
+ stoppedUntil = ctx.date.iso(stopped);
76
+ } catch (error) {
77
+ void error;
78
+ return fail();
79
+ }
80
+ }
81
+ periods.push({
82
+ period: kind,
83
+ spent: money(entry.spent_usd, `${kind} spend`),
84
+ limit: limit(entry.limit_usd, `${kind} limit`),
85
+ organizationLimit: limit(entry.organization_limit_usd, `${kind} organization limit`),
86
+ accountLimit: limit(entry.account_limit_usd, `${kind} account limit`),
87
+ stoppedUntil,
88
+ });
89
+ }
90
+ const find = (kind) => periods.find((entry) => entry.period === kind);
91
+ const day = find("day");
92
+ const month = find("month");
93
+ // The organization is a best-effort companion read; spend and limits stay authoritative.
94
+ let organization;
95
+ if (response.optional && response.optional.status === 200) {
96
+ try {
97
+ const parsed = JSON.parse(response.optional.bodyText);
98
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) organization = parsed;
99
+ } catch (error) {
100
+ void error;
101
+ }
102
+ }
103
+ const usageTier = _nullishCoalesce(text(body.usage_tier), () =>
104
+ organization ? text(organization.usage_tier) : undefined,
105
+ );
106
+ const rows = [];
107
+ const moneyRow = (label, entry) => {
108
+ const spend = ctx.format.usd(entry.spent);
109
+ rows.push({
110
+ label,
111
+ value: entry.limit && entry.limit > 0 ? `${spend} of ${ctx.format.usd(entry.limit)}` : spend,
112
+ progress: entry.limit && entry.limit > 0 ? Math.min(1, entry.spent / entry.limit) : undefined,
113
+ usageValue: entry.spent,
114
+ });
115
+ const organizational =
116
+ entry.organizationLimit != null && entry.organizationLimit > 0 && entry.organizationLimit !== entry.limit
117
+ ? entry.organizationLimit
118
+ : undefined;
119
+ const account =
120
+ entry.accountLimit != null && entry.accountLimit > 0 && entry.accountLimit !== entry.limit
121
+ ? entry.accountLimit
122
+ : undefined;
123
+ if (organizational != null) {
124
+ rows.push({ label: `${label} organization limit`, value: ctx.format.usd(organizational) });
125
+ }
126
+ if (account != null) {
127
+ rows.push({ label: `${label} account limit`, value: ctx.format.usd(account) });
128
+ }
129
+ if (entry.stoppedUntil) rows.push({ label: `${label} stopped until`, value: entry.stoppedUntil.toISOString() });
130
+ };
131
+ if (day) moneyRow("Today", day);
132
+ if (month) moneyRow("This month", month);
133
+ if (usageTier) rows.push({ label: "Usage tier", value: usageTier });
134
+ const details = [];
135
+ if (rows.length) details.push({ title: "Spend limits", rows });
136
+ const organizationRows = [];
137
+ if (organization) {
138
+ const status = text(organization.status);
139
+ if (status) organizationRows.push({ label: "Status", value: status.charAt(0).toUpperCase() + status.slice(1) });
140
+ const region = text(organization.data_region);
141
+ if (region) organizationRows.push({ label: "Data region", value: region });
142
+ if (organizationRows.length) details.push({ title: "Organization", rows: organizationRows });
143
+ }
144
+ // The identity keeps the card visible even when every period is temporarily absent;
145
+ // spend windows and cost appear only while Munito reports them.
146
+ return {
147
+ primary:
148
+ day && day.limit && day.limit > 0 ? { usedPercent: ctx.pct(day.spent, day.limit), windowMinutes: 1440 } : null,
149
+ secondary: month && month.limit && month.limit > 0 ? { usedPercent: ctx.pct(month.spent, month.limit) } : null,
150
+ cost:
151
+ month != null || day != null
152
+ ? {
153
+ used: _nullishCoalesce(month, () => day).spent,
154
+ limit: _nullishCoalesce(_nullishCoalesce(month, () => day).limit, () => 0),
155
+ currency: "USD",
156
+ period: month ? "This month" : "Today",
157
+ }
158
+ : null,
159
+ details,
160
+ identity: {
161
+ organization: organization ? text(organization.name) : undefined,
162
+ accountID: organization ? text(organization.id) : undefined,
163
+ loginMethod: "Admin API key",
164
+ },
165
+ dataConfidence: "exact",
166
+ };
167
+ },
168
+ });
169
+
170
+ // END UPSTREAM
171
+ })(globalThis.defineProvider);
@@ -0,0 +1,24 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "munito",
4
+ "name": "Munito",
5
+ "version": "0.1.0",
6
+ "entry": "plugin.js",
7
+ "enabledByDefault": false,
8
+ "supportedModes": [
9
+ "api"
10
+ ],
11
+ "autoMode": "api",
12
+ "usageDashboardUrl": "https://app.munito.ai",
13
+ "envVars": [
14
+ "MUNITO_API_KEY"
15
+ ],
16
+ "setupFields": [],
17
+ "upstream": {
18
+ "repository": "https://github.com/steipete/CodexBar",
19
+ "revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
20
+ "path": "Sources/CodexBarCore/Resources/Plugins/munito.js",
21
+ "sha256": "6feee407bd3765acb723bca995e660ee9dc8d556e51bfdff158686e3ffaf0ffe",
22
+ "license": "MIT"
23
+ }
24
+ }
@@ -0,0 +1,3 @@
1
+ <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill="currentColor" d="M6.915 4.03c-1.968 0-3.683 1.28-4.871 3.113C.704 9.208 0 11.883 0 14.449c0 .706.07 1.369.21 1.973a6.624 6.624 0 0 0 .265.86 5.297 5.297 0 0 0 .371.761c.696 1.159 1.818 1.927 3.593 1.927 1.497 0 2.633-.671 3.965-2.444.76-1.012 1.144-1.626 2.663-4.32l.756-1.339.186-.325c.061.1.121.196.183.3l2.152 3.595c.724 1.21 1.665 2.556 2.47 3.314 1.046.987 1.992 1.22 3.06 1.22 1.075 0 1.876-.355 2.455-.843a3.743 3.743 0 0 0 .81-.973c.542-.939.861-2.127.861-3.745 0-2.72-.681-5.357-2.084-7.45-1.282-1.912-2.957-2.93-4.716-2.93-1.047 0-2.088.467-3.053 1.308-.652.57-1.257 1.29-1.82 2.05-.69-.875-1.335-1.547-1.958-2.056-1.182-.966-2.315-1.303-3.454-1.303zm10.16 2.053c1.147 0 2.188.758 2.992 1.999 1.132 1.748 1.647 4.195 1.647 6.4 0 1.548-.368 2.9-1.839 2.9-.58 0-1.027-.23-1.664-1.004-.496-.601-1.343-1.878-2.832-4.358l-.617-1.028a44.908 44.908 0 0 0-1.255-1.98c.07-.109.141-.224.211-.327 1.12-1.667 2.118-2.602 3.358-2.602zm-10.201.553c1.265 0 2.058.791 2.675 1.446.307.327.737.871 1.234 1.579l-1.02 1.566c-.757 1.163-1.882 3.017-2.837 4.338-1.191 1.649-1.81 1.817-2.486 1.817-.524 0-1.038-.237-1.383-.794-.263-.426-.464-1.13-.464-2.046 0-2.221.63-4.535 1.66-6.088.454-.687.964-1.226 1.533-1.533a2.264 2.264 0 0 1 1.088-.285z"/>
3
+ </svg>
@@ -1,5 +1,7 @@
1
1
  // Generated by tools/vendor-codexbar-providers.cjs; see LICENSE.
2
2
  globalThis.__usagestat_bundled_options = {"labels":["Session","Weekly","Additional"],"defaults":{},"autoMode":"api"};
3
+ (function(defineProvider) {
4
+ // BEGIN UPSTREAM Sources/CodexBarCore/Resources/Plugins/muse.js
3
5
  function _nullishCoalesce(lhs, rhsFn) {
4
6
  if (lhs != null) {
5
7
  return lhs;
@@ -281,3 +283,6 @@ defineProvider({
281
283
  };
282
284
  },
283
285
  });
286
+
287
+ // END UPSTREAM
288
+ })(globalThis.defineProvider);
@@ -16,9 +16,17 @@
16
16
  "MUSE_WEB_TEAM_ID",
17
17
  "MUSE_COOKIE"
18
18
  ],
19
+ "setupFields": [
20
+ {
21
+ "key": "MUSE_WEB_TEAM_ID",
22
+ "title": "Browser team ID",
23
+ "type": "string",
24
+ "description": "Provider-specific account or source selection."
25
+ }
26
+ ],
19
27
  "upstream": {
20
28
  "repository": "https://github.com/steipete/CodexBar",
21
- "revision": "6ba06fe9ec1522dd5c59e16810115bce28aa148f",
29
+ "revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
22
30
  "path": "Sources/CodexBarCore/Resources/Plugins/muse.js",
23
31
  "sha256": "85b6f9489f4e004d027cca1fe2a0a87884792d0be7aa50ef7b8df3b17902c424",
24
32
  "license": "MIT"
@@ -1,5 +1,7 @@
1
1
  // Generated by tools/vendor-codexbar-providers.cjs; see LICENSE.
2
2
  globalThis.__usagestat_bundled_options = {"labels":["Weekly","Additional tokens","Additional"],"defaults":{},"autoMode":"web","maxRequests":160};
3
+ (function(defineProvider) {
4
+ // BEGIN UPSTREAM Sources/CodexBarCore/Resources/Plugins/museai.js
3
5
  defineProvider({
4
6
  id: "museai",
5
7
  name: "Muse (muse.ai)",
@@ -15,7 +17,8 @@ defineProvider({
15
17
  if (policy === "off") throw ctx.fail.missingCredential("muse.ai cookies are disabled.");
16
18
  const signedOut = (r) =>
17
19
  r.status === 401 || r.status === 403 || (r.headers["location"] ?? "").startsWith("https://auth.muse.ai/");
18
- const staleAction = (r) => r.status === 404 && /server action not found/i.test(r.bodyText);
20
+ // A redeployed muse.ai answers a stale action with 400, 404 or 409 (#5051).
21
+ const actionNeedsRediscovery = (r) => !signedOut(r) && [400, 404, 409].includes(r.status);
19
22
  const discoveryFailure = () =>
20
23
  ctx.fail.parseFailure(
21
24
  "Could not find a working muse.ai subscription action. muse.ai may have changed. Refresh to retry.",
@@ -32,6 +35,7 @@ defineProvider({
32
35
  "Sec-Fetch-Site": "same-origin",
33
36
  "Sec-Fetch-Mode": "cors",
34
37
  "Sec-Fetch-Dest": "empty",
38
+ "Content-Type": "text/plain;charset=UTF-8",
35
39
  "User-Agent": userAgent,
36
40
  },
37
41
  });
@@ -82,14 +86,14 @@ defineProvider({
82
86
  let actionID = ctx.storage.get("actionID");
83
87
  const subscription = async (cookie) => {
84
88
  const response = actionID ? await post(cookie, actionID) : undefined;
85
- if (response && !staleAction(response)) {
89
+ if (response && !actionNeedsRediscovery(response)) {
86
90
  return signedOut(response) ? undefined : response;
87
91
  }
88
92
  ctx.storage.remove("actionID");
89
93
  actionID = await discover(cookie);
90
94
  if (!actionID) return undefined;
91
95
  const fresh = await post(cookie, actionID);
92
- if (staleAction(fresh)) throw discoveryFailure();
96
+ if (actionNeedsRediscovery(fresh)) throw discoveryFailure();
93
97
  return signedOut(fresh) ? undefined : fresh;
94
98
  };
95
99
 
@@ -152,3 +156,6 @@ defineProvider({
152
156
  };
153
157
  },
154
158
  });
159
+
160
+ // END UPSTREAM
161
+ })(globalThis.defineProvider);
@@ -15,11 +15,12 @@
15
15
  "MUSEAI_COOKIE"
16
16
  ],
17
17
  "setupHelp": "Use a session Cookie header from muse.ai. This provider is separate from Muse Code and does not use its CLI login.",
18
+ "setupFields": [],
18
19
  "upstream": {
19
20
  "repository": "https://github.com/steipete/CodexBar",
20
- "revision": "6ba06fe9ec1522dd5c59e16810115bce28aa148f",
21
+ "revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
21
22
  "path": "Sources/CodexBarCore/Resources/Plugins/museai.js",
22
- "sha256": "ab325a1b6cff46bbe347d98340d9212cab732f6b48c0d2ae5c6d955824ac5019",
23
+ "sha256": "fa82f1936a5b59e16aab91d42e3c3591d3f6b50d65017557a341924095234f1d",
23
24
  "license": "MIT"
24
25
  }
25
26
  }
@@ -1,5 +1,7 @@
1
1
  // Generated by tools/vendor-codexbar-providers.cjs; see LICENSE.
2
2
  globalThis.__usagestat_bundled_options = {"labels":["Monthly credits","Weekly","Additional"],"defaults":{"PORTAL_URL":"https://portal.nousresearch.com"},"autoMode":"api"};
3
+ (function(defineProvider) {
4
+ // BEGIN UPSTREAM Sources/CodexBarCore/Resources/Plugins/nous.js
3
5
  function _nullishCoalesce(lhs, rhsFn) {
4
6
  if (lhs != null) {
5
7
  return lhs;
@@ -122,3 +124,6 @@ defineProvider({
122
124
  };
123
125
  },
124
126
  });
127
+
128
+ // END UPSTREAM
129
+ })(globalThis.defineProvider);
@@ -14,9 +14,17 @@
14
14
  "PORTAL_URL",
15
15
  "NOUS_PORTAL_ACCESS_TOKEN"
16
16
  ],
17
+ "setupFields": [
18
+ {
19
+ "key": "PORTAL_URL",
20
+ "title": "Portal URL",
21
+ "type": "string",
22
+ "description": "Provider-specific account or source selection."
23
+ }
24
+ ],
17
25
  "upstream": {
18
26
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "6ba06fe9ec1522dd5c59e16810115bce28aa148f",
27
+ "revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
20
28
  "path": "Sources/CodexBarCore/Resources/Plugins/nous.js",
21
29
  "sha256": "160f5329bf4895a061d3bed74d0476283d3abad47e071fb868d667c0c5cb485e",
22
30
  "license": "MIT"
@@ -2,6 +2,7 @@
2
2
  var SETTINGS_URL = "https://ollama.com/settings";
3
3
  var TAGS_URL = "https://ollama.com/api/tags";
4
4
  var VALIDATION_URL = "https://ollama.com/api/web_search";
5
+ var BALANCE_URL = "https://ollama.com/api/balance";
5
6
  var SESSION_COOKIE = "__Secure-session";
6
7
  var SESSION_MS = 5 * 60 * 60 * 1000;
7
8
  var WEEK_MS = 7 * 24 * 60 * 60 * 1000;
@@ -21,6 +22,7 @@
21
22
  }
22
23
 
23
24
  function env(ctx, name) {
25
+ if (ctx.provider && ctx.provider.instanceId && ctx.provider.instanceId !== 'ollama') return null;
24
26
  try {
25
27
  return clean(ctx.host.env.get(name));
26
28
  } catch (_) {
@@ -89,6 +91,13 @@
89
91
  }
90
92
 
91
93
  function probeApi(ctx, apiKey) {
94
+ var balanceResponse = request(ctx, {method:'GET',url:BALANCE_URL,
95
+ headers:{Authorization:'Bearer '+apiKey,Accept:'application/json'},timeoutMs:15000});
96
+ if (balanceResponse.status !== 404) {
97
+ if (balanceResponse.status === 401 || balanceResponse.status === 403) throw "Ollama API key is invalid or revoked.";
98
+ if (balanceResponse.status !== 200) throw "Ollama balance API returned HTTP " + balanceResponse.status + ".";
99
+ return balanceResult(ctx, parseJson(ctx,balanceResponse.bodyText));
100
+ }
92
101
  var validation = request(ctx, {
93
102
  method: "POST",
94
103
  url: VALIDATION_URL,
@@ -147,6 +156,55 @@
147
156
  };
148
157
  }
149
158
 
159
+ function balanceResult(ctx, payload) {
160
+ var data = payload && payload.data && typeof payload.data === 'object' ? payload.data : payload;
161
+ var fail = function() { throw 'Ollama returned an invalid credit balance response.'; };
162
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return fail();
163
+ var amount = function(value) {
164
+ if (typeof value === 'string' && /^-?\d+(?:\.\d+)?$/.test(value.trim())) value = Number(value);
165
+ return typeof value === 'number' && Number.isFinite(value) ? value : fail();
166
+ };
167
+ var date = function(value) {
168
+ if (value == null) return null;
169
+ if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value)) return fail();
170
+ var parts=value.slice(0,10).split('-').map(Number),ms=Date.parse(value);
171
+ if (!Number.isFinite(ms) || parts[1]<1 || parts[1]>12 || parts[2]<1 || parts[2]>new Date(Date.UTC(parts[0],parts[1],0)).getUTCDate()) return fail();
172
+ return new Date(ms).toISOString();
173
+ };
174
+ var included=data.included,lines=[];
175
+ if (included != null && (typeof included !== 'object' || Array.isArray(included))) return fail();
176
+ if (included && (included.allowance_usd != null || included.balance_usd != null)) {
177
+ var allowance=amount(included.allowance_usd),balance=amount(included.balance_usd);
178
+ if (allowance<0) return fail();
179
+ var used=Math.max(0,allowance-balance),period=included.period;
180
+ if (period!=null && (typeof period!=='object' || Array.isArray(period))) return fail();
181
+ var until=date(period && period.until),from=date(period && period.from);
182
+ if (from && until && Date.parse(until)<=Date.parse(from)) return fail();
183
+ if (allowance>0) lines.push(ctx.line.progress({label:'Monthly credits',used:used,limit:allowance,
184
+ format:{kind:'dollars'},resetsAt:until || undefined,
185
+ periodDurationMs:from && until ? Date.parse(until)-Date.parse(from) : until ? ctx.util.calendarMonthDuration(until) : undefined}));
186
+ else lines.push(ctx.line.text({label:'Monthly allowance',value:'$0.00'}));
187
+ lines.push(ctx.line.text({label:'Monthly remaining',value:'$'+balance.toFixed(2)}));
188
+ }
189
+ var limits=included || data.limits || data;
190
+ for (var spec of [['session','Session',SESSION_MS],['weekly','Weekly',WEEK_MS],['monthly','Monthly',null]]) {
191
+ var window=limits[spec[0]] || limits[spec[0]+'_usage'];
192
+ if (!window) continue;
193
+ var raw=window.used_percent ?? window.usedPercent ?? window.percent ?? window.percentage;
194
+ var percent;
195
+ if (raw!=null) percent=amount(raw);
196
+ else if (window.remaining_percent!=null || window.remainingPercent!=null) percent=100-amount(window.remaining_percent ?? window.remainingPercent);
197
+ else if (window.usage!=null) {percent=amount(window.usage);if(percent<=1) percent*=100;}
198
+ else continue;
199
+ if (percent<0) return fail();
200
+ lines.push(ctx.line.progress({label:spec[1],used:percent,limit:100,format:{kind:'percent'},
201
+ periodDurationMs:spec[2] || undefined,resetsAt:date(window.resets_at || window.resetsAt) || undefined}));
202
+ }
203
+ if (data.purchased!=null) lines.push(ctx.line.text({label:'Purchased credits',value:'$'+amount(data.purchased.balance_usd).toFixed(2)}));
204
+ if (!lines.length) return fail();
205
+ return {displayName:'Ollama',source:'api',plan:typeof data.plan==='string' ? ctx.fmt.planLabel(data.plan) : 'API key',lines:lines};
206
+ }
207
+
150
208
  function blockEnd(html, start, currentLabel) {
151
209
  var labels = ["Monthly usage", "Session usage", "Hourly usage", "Weekly usage"];
152
210
  var end = html.length;
@@ -12,10 +12,12 @@
12
12
  monthly: 60,
13
13
  };
14
14
 
15
- const TABLES_SQL = "SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('message','session_message','credential')";
15
+ const TABLES_SQL = "SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('message','session_message','credential','migration')";
16
+ const CREDENTIALS_IMPORTED_SQL = "SELECT 1 AS imported FROM migration WHERE id = '20260805200742_import_legacy_credentials' LIMIT 1";
16
17
  const CREDENTIAL_SQL = `SELECT value FROM credential
17
- WHERE integration_id = 'opencode-go' AND (active IS NULL OR active = 1)
18
- ORDER BY active DESC, time_updated DESC, id DESC LIMIT 1`;
18
+ WHERE (integration_id = 'opencode-go' AND (active IS NULL OR active = 1))
19
+ OR (integration_id = 'opencode' AND active = 1)
20
+ ORDER BY CASE integration_id WHEN 'opencode-go' THEN 0 ELSE 1 END, active DESC, time_updated DESC, id DESC LIMIT 1`;
19
21
  function historySQL(tables) {
20
22
  const sources = [];
21
23
  if (tables.includes('session_message')) sources.push(`SELECT id, time_created, data FROM session_message
@@ -328,15 +330,19 @@
328
330
  const configured = trim(ctx.provider && ctx.provider.apiKey) || env(ctx, "OPENCODE_GO_API_KEY");
329
331
  if (configured) return configured;
330
332
  const inline = ctx.host.env.get("OPENCODE_AUTH_CONTENT");
331
- // A v2 credential table is authoritative even after logout. The one-time
332
- // imported auth.json must never revive a deleted or inactive account.
333
+ // OpenCode 1 also creates credential tables, but still signs in through
334
+ // auth.json. Only the completed v2 import makes database logout authoritative.
333
335
  if (!inline) {
334
336
  const database = databasePath(ctx);
335
337
  if (ctx.host.fs.exists(database)) {
336
338
  try {
337
339
  const tables = ctx.util.tryParseJson(ctx.host.sqlite.query(database, TABLES_SQL));
338
340
  if (!Array.isArray(tables)) throw new Error('Invalid schema');
339
- if (tables.some(table => table.name === 'credential')) {
341
+ const imported = tables.some(table => table.name === 'migration')
342
+ ? ctx.util.tryParseJson(ctx.host.sqlite.query(database, CREDENTIALS_IMPORTED_SQL)) : [];
343
+ if (!Array.isArray(imported)) throw new Error('Invalid migration result');
344
+ if (imported.length) {
345
+ if (!tables.some(table => table.name === 'credential')) throw new Error('Imported credential storage is missing');
340
346
  const rows = ctx.util.tryParseJson(ctx.host.sqlite.query(database, CREDENTIAL_SQL));
341
347
  if (!Array.isArray(rows)) throw new Error('Invalid credential result');
342
348
  if (!rows.length) return null;
@@ -362,7 +368,7 @@
362
368
  if (inline) throw {code: "credential-malformed", message: "OPENCODE_AUTH_CONTENT must contain an auth JSON object."};
363
369
  throw {code:'credential-malformed',message:'OpenCode auth file is not valid JSON.'};
364
370
  }
365
- const entry = parsed[PROVIDER_ID];
371
+ const entry = parsed[PROVIDER_ID] || parsed.opencode;
366
372
  if (!entry || typeof entry !== "object") return null;
367
373
  const key = typeof entry.key === "string" ? entry.key.trim() : "";
368
374
  return key || null;
@@ -622,6 +628,9 @@
622
628
  if (ctx.util.isAuthStatus(result.resp.status)) throw "OpenCode Go key was rejected. Sign into OpenCode Go again.";
623
629
  if (result.resp.status < 200 || result.resp.status >= 300) throw "OpenCode Go usage API returned HTTP " + result.resp.status + ".";
624
630
  const usage = result.json && result.json.usage;
631
+ const dateHeader = Object.entries(result.resp.headers || {}).find(([key]) => key.toLowerCase() === 'date');
632
+ const serverTime = dateHeader && Date.parse(dateHeader[1]);
633
+ const referenceTime = Number.isFinite(serverTime) ? serverTime : Date.parse(ctx.nowIso);
625
634
  const specs = [["rolling", "Session", FIVE_HOURS_MS], ["weekly", "Weekly", WEEK_MS], ["monthly", "Monthly", null]];
626
635
  const lines = [];
627
636
  for (const spec of specs) {
@@ -630,8 +639,11 @@
630
639
  const percent = window && readNumber(window.percent);
631
640
  if (!Number.isFinite(percent)) throw "OpenCode Go usage API returned an invalid quota.";
632
641
  const resetInSec = readNumber(window.resetInSec);
633
- const resetsAt = ctx.util.toIso(window.resetsAt) || (resetInSec !== null && resetInSec >= 0
634
- ? ctx.util.toIso(Date.parse(ctx.nowIso) + resetInSec * 1000) : null);
642
+ let resetsAt = ctx.util.toIso(window.resetsAt) || (resetInSec !== null && resetInSec >= 0
643
+ ? ctx.util.toIso(referenceTime + resetInSec * 1000) : null);
644
+ if (window.resetsAt != null && !ctx.util.toIso(window.resetsAt)) throw 'OpenCode Go usage API returned an invalid reset.';
645
+ if (spec[0] === 'rolling' && percent === 0 && resetsAt && Math.abs(Date.parse(resetsAt)-referenceTime-FIVE_HOURS_MS)<=2000)
646
+ resetsAt = null;
635
647
  lines.push(ctx.line.progress({ label: spec[1], used: Math.max(0, Math.min(100, percent)), limit: 100,
636
648
  format: { kind: "percent" }, resetsAt, periodDurationMs: spec[2] }));
637
649
  }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Peter Steinberger
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="100 100 385 385" fill="currentColor">
2
+ <path fill-rule="evenodd" d="M292.716 112.374C392.751 112.374 473.845 193.468 473.845 293.503C473.845 393.538 392.751 474.632 292.716 474.632H135.685C122.347 474.632 111.587 463.874 111.587 450.536C111.587 410.139 111.587 329.633 111.587 293.503C111.587 193.468 192.681 112.374 292.716 112.374ZM292.716 148.6C212.689 148.6 147.813 213.476 147.813 293.504C147.813 373.532 212.689 438.407 292.716 438.407C372.744 438.407 437.619 373.532 437.619 293.504C437.619 213.476 372.744 148.6 292.716 148.6Z"/>
3
+ <path d="M281.618 378.232L226.395 232.908C224.608 228.205 229.201 223.594 233.873 225.402L379.265 281.651C385.249 283.966 383.6 292.898 377.189 292.898H292.803V376.155C292.803 382.61 283.91 384.262 281.618 378.232Z"/>
4
+ </svg>
@@ -0,0 +1,108 @@
1
+ // Generated by tools/vendor-codexbar-providers.cjs; see LICENSE.
2
+ globalThis.__usagestat_bundled_options = {"labels":["Session","Weekly","Additional"],"defaults":{},"autoMode":"web"};
3
+ (function(defineProvider) {
4
+ // BEGIN UPSTREAM Sources/CodexBarCore/Resources/Plugins/opendesign.js
5
+ defineProvider({
6
+ id: "opendesign",
7
+ name: "OpenDesign",
8
+ settings: [{ key: "MESSAGES", title: "OpenDesign", type: "plain" }],
9
+ endpoints: ["https://amr-api.open-design.ai"],
10
+ capabilities: ["browser-cookies", "http-status"],
11
+ cookieDomains: ["amr-api.open-design.ai"],
12
+ cookiePolicy: {
13
+ selection: "request-url",
14
+ cache: "nonpersistent",
15
+ imports: "access-gated",
16
+ // The host's optional name filter excludes dots; validate the opaque session at the endpoint.
17
+ },
18
+ async fetchUsage(ctx) {
19
+ const domain = "amr-api.open-design.ai";
20
+ const messages = JSON.parse(ctx.settings.get("MESSAGES") || "{}");
21
+ const message = (key) => messages[key] || key;
22
+ const signIn = message("Sign in to OpenDesign, then refresh CodexBar.");
23
+ const expired = ctx.fail.authenticationExpired(signIn);
24
+ const malformed = () => {
25
+ throw ctx.fail.parseFailure(message("OpenDesign usage response format changed."));
26
+ };
27
+ const text = (value) => (typeof value === "string" && value.trim() ? value.trim() : undefined);
28
+ const credits = (value) => {
29
+ if (typeof value === "string" && /^\d+(\.\d+)?$/.test(value)) value = Number(value);
30
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= Number.MAX_SAFE_INTEGER
31
+ ? value
32
+ : malformed();
33
+ };
34
+ if (ctx.browser.availability(domain) === "off") throw ctx.fail.missingCredential(signIn);
35
+ let rejected = false;
36
+ for await (const session of ctx.browser.sessions(domain)) {
37
+ const get = async (path, workspace) => {
38
+ const response = await ctx.http.get(`https://${domain}/api/v1/workspaces/${path}`, {
39
+ cookieSession: session.id,
40
+ headers: { Accept: "application/json", ...(workspace ? { "X-Vela-Workspace-Id": workspace } : {}) },
41
+ });
42
+ if (response.status === 401) throw expired;
43
+ if (response.status === 403) throw ctx.fail.permissionDenied(message("OpenDesign billing access was denied."));
44
+ const failed = message("OpenDesign request failed. Try again later.");
45
+ if (response.status === 429) throw ctx.fail.rateLimited(failed);
46
+ if (response.status >= 500 || response.status === 408) throw ctx.fail.providerUnavailable(failed);
47
+ if (response.status !== 200) throw ctx.fail.apiFailure(failed);
48
+ try {
49
+ return JSON.parse(response.bodyText);
50
+ } catch {
51
+ return malformed();
52
+ }
53
+ };
54
+ try {
55
+ const workspace = await get("current");
56
+ const id = text(workspace?.workspaceId);
57
+ if (!id || !/^[A-Za-z0-9_-]{1,128}$/.test(id)) return malformed();
58
+ const usage = await get(`${id}/billing/coding-plan-usage`, id);
59
+ if (usage?.workspaceId !== id || typeof usage.eligible !== "boolean" || !Array.isArray(usage.windows))
60
+ return malformed();
61
+ const unavailable = () => {
62
+ throw ctx.fail.providerUnavailable(
63
+ message("OpenDesign subscription usage is unavailable for this workspace."),
64
+ );
65
+ };
66
+ if (!usage.eligible) return unavailable();
67
+ const window = (seconds) => {
68
+ const matches = usage.windows.filter((item) => item?.durationSeconds === seconds);
69
+ if (matches.length === 0) return undefined;
70
+ if (matches.length !== 1) return malformed();
71
+ const item = matches[0];
72
+ const used = credits(item.usedCredits);
73
+ const limit = credits(item.limitCredits);
74
+ if (limit <= 0) return malformed();
75
+ const reset = text(item.resetsAt);
76
+ return {
77
+ usedPercent: ctx.pct(used, limit),
78
+ windowMinutes: seconds / 60,
79
+ quotaLimit: limit,
80
+ quotaUnit: "credits",
81
+ resetsAt:
82
+ reset && /^\d{4}-\d{2}-\d{2}T/.test(reset) && Number.isFinite(Date.parse(reset)) ? reset : undefined,
83
+ };
84
+ };
85
+ const primary = window(18000);
86
+ const secondary = window(604800);
87
+ if (!primary && !secondary) return unavailable();
88
+ return {
89
+ primary,
90
+ secondary,
91
+ identity: {
92
+ accountID: id,
93
+ organization: text(workspace.workspaceName),
94
+ loginMethod: text(usage.tier) ?? text(workspace.personalMembershipTier),
95
+ },
96
+ };
97
+ } catch (error) {
98
+ if (error !== expired) throw error;
99
+ ctx.browser.rejectCookie(domain, session);
100
+ rejected = true;
101
+ }
102
+ }
103
+ throw rejected ? expired : ctx.fail.missingCredential(signIn);
104
+ },
105
+ });
106
+
107
+ // END UPSTREAM
108
+ })(globalThis.defineProvider);