@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1 → 2.0.0-alpha.3

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 (273) hide show
  1. package/LICENSE +0 -0
  2. package/native-manifest.json +365 -77
  3. package/package.json +49 -1
  4. package/plugins/UPSTREAM-LICENSES.md +109 -0
  5. package/plugins/abacus-ai/icon.svg +0 -0
  6. package/plugins/abacus-ai/plugin.js +0 -0
  7. package/plugins/abacus-ai/plugin.json +0 -0
  8. package/plugins/aiand/icon.svg +6 -0
  9. package/plugins/aiand/plugin.js +108 -0
  10. package/plugins/aiand/plugin.json +22 -0
  11. package/plugins/alibaba/icon-color.svg +0 -0
  12. package/plugins/alibaba/icon.svg +0 -0
  13. package/plugins/alibaba/plugin.js +0 -0
  14. package/plugins/alibaba/plugin.json +0 -0
  15. package/plugins/alibaba-token-plan/icon-color.svg +0 -0
  16. package/plugins/alibaba-token-plan/icon.svg +0 -0
  17. package/plugins/alibaba-token-plan/plugin.js +0 -0
  18. package/plugins/alibaba-token-plan/plugin.json +0 -0
  19. package/plugins/amp/icon-color.svg +0 -0
  20. package/plugins/amp/icon-conflict.svg +0 -0
  21. package/plugins/amp/icon.svg +0 -0
  22. package/plugins/amp/plugin.js +0 -0
  23. package/plugins/amp/plugin.json +0 -0
  24. package/plugins/antigravity/icon-color.svg +0 -0
  25. package/plugins/antigravity/icon-conflict.svg +0 -0
  26. package/plugins/antigravity/icon.svg +0 -0
  27. package/plugins/antigravity/plugin.js +0 -0
  28. package/plugins/antigravity/plugin.json +0 -0
  29. package/plugins/antigravity-cli/icon.svg +0 -0
  30. package/plugins/antigravity-cli/plugin.js +0 -0
  31. package/plugins/antigravity-cli/plugin.json +0 -0
  32. package/plugins/antigravity-ide/icon.svg +0 -0
  33. package/plugins/antigravity-ide/plugin.js +0 -0
  34. package/plugins/antigravity-ide/plugin.json +0 -0
  35. package/plugins/augment/icon.svg +0 -0
  36. package/plugins/augment/plugin.js +0 -0
  37. package/plugins/augment/plugin.json +0 -0
  38. package/plugins/aws-bedrock/icon-color.svg +0 -0
  39. package/plugins/aws-bedrock/icon.svg +0 -0
  40. package/plugins/aws-bedrock/plugin.js +0 -0
  41. package/plugins/aws-bedrock/plugin.json +0 -0
  42. package/plugins/azure-openai/icon-color.svg +0 -0
  43. package/plugins/azure-openai/icon.svg +0 -0
  44. package/plugins/azure-openai/plugin.js +0 -0
  45. package/plugins/azure-openai/plugin.json +0 -0
  46. package/plugins/chutes/icon.svg +0 -0
  47. package/plugins/chutes/plugin.js +0 -0
  48. package/plugins/chutes/plugin.json +0 -0
  49. package/plugins/claude/icon-color.svg +0 -0
  50. package/plugins/claude/icon.svg +0 -0
  51. package/plugins/claude/plugin.js +70 -23
  52. package/plugins/claude/plugin.json +0 -0
  53. package/plugins/clawrouter/icon.svg +7 -0
  54. package/plugins/clawrouter/plugin.js +45 -0
  55. package/plugins/clawrouter/plugin.json +22 -0
  56. package/plugins/clinepass/icon.svg +4 -0
  57. package/plugins/clinepass/plugin.js +71 -0
  58. package/plugins/clinepass/plugin.json +23 -0
  59. package/plugins/codebuddy/plugin.js +331 -0
  60. package/plugins/codebuddy/plugin.json +30 -0
  61. package/plugins/codebuff/icon.svg +0 -0
  62. package/plugins/codebuff/plugin.js +0 -0
  63. package/plugins/codebuff/plugin.json +0 -0
  64. package/plugins/codex/icon-color.svg +0 -0
  65. package/plugins/codex/icon.svg +0 -0
  66. package/plugins/codex/plugin.js +7 -2
  67. package/plugins/codex/plugin.json +0 -0
  68. package/plugins/command-code/icon.svg +0 -0
  69. package/plugins/command-code/plugin.js +7 -0
  70. package/plugins/command-code/plugin.json +0 -0
  71. package/plugins/copilot/icon-color.svg +0 -0
  72. package/plugins/copilot/icon.svg +0 -0
  73. package/plugins/copilot/plugin.js +61 -9
  74. package/plugins/copilot/plugin.json +4 -1
  75. package/plugins/crof/icon.svg +0 -0
  76. package/plugins/crof/plugin.js +0 -0
  77. package/plugins/crof/plugin.json +0 -0
  78. package/plugins/crofai/icon.svg +0 -0
  79. package/plugins/crofai/plugin.js +0 -0
  80. package/plugins/crofai/plugin.json +0 -0
  81. package/plugins/cursor/icon-conflict.svg +0 -0
  82. package/plugins/cursor/icon.svg +0 -0
  83. package/plugins/cursor/plugin.js +46 -9
  84. package/plugins/cursor/plugin.json +3 -2
  85. package/plugins/cursor-nightly/icon.png +0 -0
  86. package/plugins/cursor-nightly/plugin.js +45 -8
  87. package/plugins/cursor-nightly/plugin.json +3 -2
  88. package/plugins/deepgram/icon.svg +0 -0
  89. package/plugins/deepgram/plugin.js +0 -0
  90. package/plugins/deepgram/plugin.json +0 -0
  91. package/plugins/deepinfra/icon.svg +4 -0
  92. package/plugins/deepinfra/plugin.js +97 -0
  93. package/plugins/deepinfra/plugin.json +28 -0
  94. package/plugins/deepseek/icon-color.svg +0 -0
  95. package/plugins/deepseek/icon.svg +0 -0
  96. package/plugins/deepseek/plugin.js +0 -0
  97. package/plugins/deepseek/plugin.json +0 -0
  98. package/plugins/devin/icon.svg +0 -0
  99. package/plugins/devin/plugin.js +111 -0
  100. package/plugins/devin/plugin.json +2 -1
  101. package/plugins/doubao/icon-color.svg +0 -0
  102. package/plugins/doubao/icon.svg +0 -0
  103. package/plugins/doubao/plugin.js +0 -0
  104. package/plugins/doubao/plugin.json +0 -0
  105. package/plugins/droid/icon.svg +0 -0
  106. package/plugins/droid/plugin.json +2 -1
  107. package/plugins/elevenlabs/icon.svg +0 -0
  108. package/plugins/elevenlabs/plugin.js +17 -2
  109. package/plugins/elevenlabs/plugin.json +0 -0
  110. package/plugins/factory/icon-conflict.svg +0 -0
  111. package/plugins/factory/icon.svg +0 -0
  112. package/plugins/factory/plugin.js +38 -14
  113. package/plugins/factory/plugin.json +2 -1
  114. package/plugins/fireworks-ai/icon.svg +0 -0
  115. package/plugins/fireworks-ai/plugin.js +0 -0
  116. package/plugins/fireworks-ai/plugin.json +0 -0
  117. package/plugins/gemini/icon-color.svg +0 -0
  118. package/plugins/gemini/icon.svg +0 -0
  119. package/plugins/gemini/plugin.js +0 -0
  120. package/plugins/gemini/plugin.json +0 -0
  121. package/plugins/grok/icon.svg +0 -0
  122. package/plugins/grok/plugin.js +30 -5
  123. package/plugins/grok/plugin.json +3 -1
  124. package/plugins/groqcloud/icon.svg +0 -0
  125. package/plugins/groqcloud/plugin.js +0 -0
  126. package/plugins/groqcloud/plugin.json +0 -0
  127. package/plugins/ibmbob/icon.svg +23 -0
  128. package/plugins/ibmbob/plugin.js +61 -0
  129. package/plugins/ibmbob/plugin.json +22 -0
  130. package/plugins/jetbrains-ai-assistant/icon-color.svg +0 -0
  131. package/plugins/jetbrains-ai-assistant/icon-conflict.svg +0 -0
  132. package/plugins/jetbrains-ai-assistant/icon.svg +0 -0
  133. package/plugins/jetbrains-ai-assistant/plugin.js +0 -0
  134. package/plugins/jetbrains-ai-assistant/plugin.json +0 -0
  135. package/plugins/kilo/icon.svg +0 -0
  136. package/plugins/kilo/plugin.js +0 -0
  137. package/plugins/kilo/plugin.json +0 -0
  138. package/plugins/kimi/icon-color.svg +0 -0
  139. package/plugins/kimi/icon-conflict.svg +0 -0
  140. package/plugins/kimi/icon.svg +0 -0
  141. package/plugins/kimi/plugin.js +122 -141
  142. package/plugins/kimi/plugin.json +5 -2
  143. package/plugins/kimi-k2/icon-color.svg +0 -0
  144. package/plugins/kimi-k2/icon.svg +0 -0
  145. package/plugins/kimi-k2/plugin.js +0 -0
  146. package/plugins/kimi-k2/plugin.json +0 -0
  147. package/plugins/kiro/icon-color.svg +0 -0
  148. package/plugins/kiro/icon-conflict.svg +0 -0
  149. package/plugins/kiro/icon.svg +0 -0
  150. package/plugins/kiro/plugin.js +49 -10
  151. package/plugins/kiro/plugin.json +3 -1
  152. package/plugins/litellm/icon.svg +0 -0
  153. package/plugins/litellm/plugin.js +0 -0
  154. package/plugins/litellm/plugin.json +0 -0
  155. package/plugins/llm-proxy/icon.svg +0 -0
  156. package/plugins/llm-proxy/plugin.js +0 -0
  157. package/plugins/llm-proxy/plugin.json +0 -0
  158. package/plugins/longcat/icon.svg +4 -0
  159. package/plugins/longcat/plugin.js +182 -0
  160. package/plugins/longcat/plugin.json +23 -0
  161. package/plugins/manus/icon.svg +0 -0
  162. package/plugins/manus/plugin.js +0 -0
  163. package/plugins/manus/plugin.json +0 -0
  164. package/plugins/mimo/icon.svg +0 -0
  165. package/plugins/mimo/plugin.js +0 -0
  166. package/plugins/mimo/plugin.json +0 -0
  167. package/plugins/minimax/icon-color.svg +0 -0
  168. package/plugins/minimax/icon-conflict.svg +0 -0
  169. package/plugins/minimax/icon.svg +0 -0
  170. package/plugins/minimax/plugin.js +25 -31
  171. package/plugins/minimax/plugin.json +0 -0
  172. package/plugins/mistral/icon-color.svg +0 -0
  173. package/plugins/mistral/icon.svg +0 -0
  174. package/plugins/mistral/plugin.js +0 -0
  175. package/plugins/mistral/plugin.json +0 -0
  176. package/plugins/moonshot/icon.svg +0 -0
  177. package/plugins/moonshot/plugin.js +8 -6
  178. package/plugins/moonshot/plugin.json +0 -0
  179. package/plugins/nanogpt/icon-color.svg +0 -0
  180. package/plugins/nanogpt/icon.svg +0 -0
  181. package/plugins/nanogpt/plugin.js +0 -0
  182. package/plugins/nanogpt/plugin.json +0 -0
  183. package/plugins/neuralwatt/icon.svg +0 -0
  184. package/plugins/neuralwatt/plugin.js +0 -0
  185. package/plugins/neuralwatt/plugin.json +0 -0
  186. package/plugins/notion/icon.svg +1 -0
  187. package/plugins/notion/plugin.js +282 -0
  188. package/plugins/notion/plugin.json +29 -0
  189. package/plugins/ollama/icon.svg +0 -0
  190. package/plugins/ollama/plugin.js +257 -56
  191. package/plugins/ollama/plugin.json +6 -3
  192. package/plugins/openai-api/icon.svg +0 -0
  193. package/plugins/openai-api/plugin.js +0 -0
  194. package/plugins/openai-api/plugin.json +0 -0
  195. package/plugins/opencode/icon.svg +0 -0
  196. package/plugins/opencode/plugin.js +0 -0
  197. package/plugins/opencode/plugin.json +0 -0
  198. package/plugins/opencode-go/icon-conflict.svg +0 -0
  199. package/plugins/opencode-go/icon.svg +0 -0
  200. package/plugins/opencode-go/plugin.js +78 -10
  201. package/plugins/opencode-go/plugin.json +5 -2
  202. package/plugins/openrouter/icon.svg +0 -0
  203. package/plugins/openrouter/plugin.js +371 -114
  204. package/plugins/openrouter/plugin.json +6 -0
  205. package/plugins/perplexity/icon-color.svg +0 -0
  206. package/plugins/perplexity/icon-conflict.svg +0 -0
  207. package/plugins/perplexity/icon.svg +0 -0
  208. package/plugins/perplexity/plugin.js +0 -0
  209. package/plugins/perplexity/plugin.json +0 -0
  210. package/plugins/poe/icon.svg +0 -0
  211. package/plugins/poe/plugin.js +24 -18
  212. package/plugins/poe/plugin.json +2 -0
  213. package/plugins/qoder/icon.svg +3 -0
  214. package/plugins/qoder/plugin.js +227 -0
  215. package/plugins/qoder/plugin.json +23 -0
  216. package/plugins/qwencloud/icon.svg +4 -0
  217. package/plugins/qwencloud/plugin.js +677 -0
  218. package/plugins/qwencloud/plugin.json +29 -0
  219. package/plugins/sakana/icon.svg +5 -0
  220. package/plugins/sakana/plugin.js +156 -0
  221. package/plugins/sakana/plugin.json +23 -0
  222. package/plugins/stepfun/icon-color.svg +0 -0
  223. package/plugins/stepfun/icon.svg +0 -0
  224. package/plugins/stepfun/plugin.js +0 -0
  225. package/plugins/stepfun/plugin.json +0 -0
  226. package/plugins/sub2api/icon.svg +4 -0
  227. package/plugins/sub2api/plugin.js +191 -0
  228. package/plugins/sub2api/plugin.json +16 -0
  229. package/plugins/synthetic/icon-conflict.svg +0 -0
  230. package/plugins/synthetic/icon.svg +0 -0
  231. package/plugins/synthetic/plugin.js +0 -0
  232. package/plugins/synthetic/plugin.json +0 -0
  233. package/plugins/t3chat/icon-color.svg +0 -0
  234. package/plugins/t3chat/icon.svg +0 -0
  235. package/plugins/t3chat/plugin.js +0 -0
  236. package/plugins/t3chat/plugin.json +0 -0
  237. package/plugins/venice/icon-color.svg +0 -0
  238. package/plugins/venice/icon.svg +0 -0
  239. package/plugins/venice/plugin.js +0 -0
  240. package/plugins/venice/plugin.json +0 -0
  241. package/plugins/vertex-ai/icon-color.svg +0 -0
  242. package/plugins/vertex-ai/icon.svg +0 -0
  243. package/plugins/vertex-ai/plugin.js +0 -0
  244. package/plugins/vertex-ai/plugin.json +0 -0
  245. package/plugins/warp/icon-color.svg +0 -0
  246. package/plugins/warp/icon.svg +0 -0
  247. package/plugins/warp/plugin.js +0 -0
  248. package/plugins/warp/plugin.json +0 -0
  249. package/plugins/wayfinder/icon.svg +5 -0
  250. package/plugins/wayfinder/plugin.js +47 -0
  251. package/plugins/wayfinder/plugin.json +16 -0
  252. package/plugins/windsurf/icon-conflict.svg +0 -0
  253. package/plugins/windsurf/icon.svg +0 -0
  254. package/plugins/windsurf/plugin.js +0 -0
  255. package/plugins/windsurf/plugin.json +0 -0
  256. package/plugins/xai/icon.svg +7 -0
  257. package/plugins/xai/plugin.js +162 -0
  258. package/plugins/xai/plugin.json +28 -0
  259. package/plugins/zai/icon-conflict.svg +0 -0
  260. package/plugins/zai/icon.svg +0 -0
  261. package/plugins/zai/plugin.js +111 -161
  262. package/plugins/zai/plugin.json +4 -1
  263. package/plugins/zed/icon.svg +0 -0
  264. package/plugins/zed/plugin.js +0 -0
  265. package/plugins/zed/plugin.json +0 -0
  266. package/plugins/zenmux/icon.svg +3 -0
  267. package/plugins/zenmux/plugin.js +102 -0
  268. package/plugins/zenmux/plugin.json +23 -0
  269. package/plugins/zoommate/icon.svg +1 -0
  270. package/plugins/zoommate/plugin.js +244 -0
  271. package/plugins/zoommate/plugin.json +29 -0
  272. package/usagestat +0 -0
  273. package/usagestatd +0 -0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -34,6 +34,8 @@
34
34
  `;
35
35
 
36
36
  function readNumber(value) {
37
+ if (typeof value !== "number" && typeof value !== "string") return null;
38
+ if (typeof value === "string" && !value.trim()) return null;
37
39
  const n = Number(value);
38
40
  return Number.isFinite(n) ? n : null;
39
41
  }
@@ -318,6 +320,8 @@
318
320
  }
319
321
 
320
322
  function loadAuthKey(ctx) {
323
+ const configured = trim(ctx.provider && ctx.provider.apiKey) || env(ctx, "OPENCODE_GO_API_KEY");
324
+ if (configured) return configured;
321
325
  const inline = ctx.host.env.get("OPENCODE_AUTH_CONTENT");
322
326
  const path = inline ? null : dataPath(ctx, "auth.json");
323
327
  if (!inline && !ctx.host.fs.exists(path)) return null;
@@ -438,10 +442,9 @@
438
442
  text,
439
443
  new RegExp(name + "[^}]*?(?:resetInSec|resetInSeconds|resetSeconds|resetSec)\\s*[:=]\\s*([0-9]+)")
440
444
  ) || 0;
441
- const normalized = percent <= 1 ? percent * 100 : percent;
442
445
  return {
443
- percent: Math.max(0, Math.min(100, normalized)),
444
- resetsAt: toIso(Date.now() + Math.max(0, reset) * 1000),
446
+ percent: Math.max(0, Math.min(100, percent)),
447
+ resetsAt: reset > 0 ? toIso(Date.now() + reset * 1000) : null,
445
448
  };
446
449
  }
447
450
  return null;
@@ -560,11 +563,52 @@
560
563
  if (!parsed.lines.length) {
561
564
  throw "OpenCode Go parse error: missing usage and balance fields.";
562
565
  }
563
- return { plan: "Go", lines: parsed.lines };
566
+ return { plan: "Go", source: "web", lines: parsed.lines };
567
+ }
568
+
569
+ function fetchApiResult(ctx, key) {
570
+ const result = ctx.util.requestJson({
571
+ method: "GET", url: BASE_URL + "/zen/go/v1/usage",
572
+ headers: { Authorization: "Bearer " + key, Accept: "application/json" }, timeoutMs: 15000,
573
+ });
574
+ if (result.resp.status === 403 && result.json && result.json.error && result.json.error.type === "EntitlementError")
575
+ throw "No OpenCode Go subscription on this key.";
576
+ if (ctx.util.isAuthStatus(result.resp.status)) throw "OpenCode Go key was rejected. Sign into OpenCode Go again.";
577
+ if (result.resp.status < 200 || result.resp.status >= 300) throw "OpenCode Go usage API returned HTTP " + result.resp.status + ".";
578
+ const usage = result.json && result.json.usage;
579
+ const specs = [["rolling", "Session", FIVE_HOURS_MS], ["weekly", "Weekly", WEEK_MS], ["monthly", "Monthly", null]];
580
+ const lines = [];
581
+ for (const spec of specs) {
582
+ const window = usage && usage[spec[0]];
583
+ if (window == null && spec[0] !== "rolling") continue;
584
+ const percent = window && readNumber(window.percent);
585
+ if (!Number.isFinite(percent)) throw "OpenCode Go usage API returned an invalid quota.";
586
+ const resetInSec = readNumber(window.resetInSec);
587
+ const resetsAt = ctx.util.toIso(window.resetsAt) || (resetInSec !== null && resetInSec >= 0
588
+ ? ctx.util.toIso(Date.parse(ctx.nowIso) + resetInSec * 1000) : null);
589
+ lines.push(ctx.line.progress({ label: spec[1], used: Math.max(0, Math.min(100, percent)), limit: 100,
590
+ format: { kind: "percent" }, resetsAt, periodDurationMs: spec[2] }));
591
+ }
592
+ return { plan: "Go", source: "api", lines };
564
593
  }
565
594
 
566
595
  function probe(ctx) {
596
+ const source = ctx.sourceMode || "auto";
597
+ if (source === "web") {
598
+ const cookie = cookieHeader(ctx);
599
+ if (!cookie) throw "OpenCode Go session cookie is missing.";
600
+ return fetchWebResult(ctx, cookie);
601
+ }
567
602
  const authKey = loadAuthKey(ctx);
603
+ if (source === "api" && !authKey) throw "OpenCode Go API key missing. Set OPENCODE_GO_API_KEY.";
604
+ if (authKey && source !== "local") {
605
+ const result = fetchApiResult(ctx, authKey);
606
+ try {
607
+ const history = loadHistory(ctx);
608
+ if (history.ok) attachCostHistory(ctx, result.lines, history.rows);
609
+ } catch (_) { ctx.host.log.warn("OpenCode Go local cost history unavailable"); }
610
+ return result;
611
+ }
568
612
  const history = hasHistory(ctx);
569
613
  const cookie = cookieHeader(ctx);
570
614
  const detected = !!authKey || !!cookie || (history.ok && history.present);
@@ -574,13 +618,15 @@
574
618
  }
575
619
 
576
620
  if (!history.ok && !cookie) {
577
- return { plan: "Go", lines: buildSoftEmptyLines(ctx) };
621
+ return { plan: "Go", source: "local", lines: buildSoftEmptyLines(ctx) };
578
622
  }
579
623
 
580
624
  const rowsResult = loadHistory(ctx);
581
625
  if (rowsResult.ok && rowsResult.rows.length > 0) {
582
626
  const lines = buildProgressLines(ctx, rowsResult.rows, readNowMs());
583
- if (cookie) {
627
+ for (const line of lines) line.detail = "Estimated from local API-rate costs";
628
+ attachCostHistory(ctx, lines, rowsResult.rows);
629
+ if (cookie && source !== "local") {
584
630
  try {
585
631
  const webResult = fetchWebResult(ctx, cookie);
586
632
  for (let i = 0; i < webResult.lines.length; i += 1) {
@@ -592,10 +638,10 @@
592
638
  ctx.host.log.warn("OpenCode Go web enrichment failed: " + String(e));
593
639
  }
594
640
  }
595
- return { plan: "Go", lines };
641
+ return { plan: "Go", source: "local-estimate", lines };
596
642
  }
597
643
 
598
- if (cookie) {
644
+ if (cookie && source !== "local") {
599
645
  try {
600
646
  return fetchWebResult(ctx, cookie);
601
647
  } catch (e) {
@@ -604,14 +650,36 @@
604
650
  }
605
651
 
606
652
  if (!rowsResult.ok) {
607
- return { plan: "Go", lines: buildSoftEmptyLines(ctx) };
653
+ return { plan: "Go", source: "local", lines: buildSoftEmptyLines(ctx) };
608
654
  }
609
655
 
610
656
  return {
611
657
  plan: "Go",
612
- lines: buildProgressLines(ctx, rowsResult.rows, readNowMs()),
658
+ source: "local",
659
+ lines: buildSoftEmptyLines(ctx),
613
660
  };
614
661
  }
615
662
 
663
+ function attachCostHistory(ctx, lines, rows) {
664
+ const byDay = {};
665
+ const now = Date.parse(ctx.nowIso);
666
+ const since = Date.parse(ctx.nowIso.slice(0, 10)) - 29 * 86400000;
667
+ for (const row of rows) {
668
+ if (row.createdMs < since || row.createdMs > now) continue;
669
+ const date = toIso(row.createdMs);
670
+ if (!date) continue;
671
+ const day = date.slice(0, 10);
672
+ byDay[day] = (byDay[day] || 0) + row.cost;
673
+ }
674
+ const daily = Object.keys(byDay).sort().map((day) => ({ date: day, costUsd: byDay[day] }));
675
+ if (!daily.length) return;
676
+ lines.push(ctx.line.text({ label: "Local Cost", value: "$" + daily.reduce((n, day) => n + day.costUsd, 0).toFixed(2), subtitle: "Last 30 days; estimated API-rate cost" }));
677
+ lines.push(ctx.line.barChart({ label: "Cost History", points: daily.map((day) => ({ label: day.date, value: day.costUsd, valueLabel: "$" + day.costUsd.toFixed(2) })),
678
+ note: "Estimated from local OpenCode Go messages, not a subscription bill.", color: "#4d9f75" }));
679
+ try {
680
+ ctx.host.usageDaily.ingest({ displayName: "OpenCode Go", source: "opencode_go_local_estimated", daily });
681
+ } catch (_) { ctx.host.log.warn("Could not persist OpenCode Go daily costs"); }
682
+ }
683
+
616
684
  globalThis.__openusage_plugin = { id: PROVIDER_ID, probe };
617
685
  })();
@@ -17,9 +17,12 @@
17
17
  }
18
18
  ],
19
19
  "usageDashboardUrl": "https://opencode.ai/auth",
20
- "supportedModes": ["local", "web"],
21
- "autoMode": "local",
20
+ "envVars": ["OPENCODE_GO_API_KEY", "OPENCODE_GO_COOKIE", "OPENCODE_GO_WORKSPACE_ID"],
21
+ "supportedModes": ["api", "local", "web"],
22
+ "autoMode": "api",
22
23
  "lines": [
24
+ { "type": "text", "label": "Local Cost", "scope": "detail" },
25
+ { "type": "barChart", "label": "Cost History", "scope": "detail" },
23
26
  {
24
27
  "type": "progress",
25
28
  "label": "Session",
File without changes