@slkiser/opencode-quota 4.9.0 → 4.10.1

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 (190) hide show
  1. package/README.md +18 -16
  2. package/dist/lib/alibaba-token-plan.d.ts +88 -0
  3. package/dist/lib/alibaba-token-plan.d.ts.map +1 -0
  4. package/dist/lib/alibaba-token-plan.js +505 -0
  5. package/dist/lib/alibaba-token-plan.js.map +1 -0
  6. package/dist/lib/anthropic.d.ts +19 -2
  7. package/dist/lib/anthropic.d.ts.map +1 -1
  8. package/dist/lib/anthropic.js +62 -3
  9. package/dist/lib/anthropic.js.map +1 -1
  10. package/dist/lib/atomic-json.d.ts +3 -0
  11. package/dist/lib/atomic-json.d.ts.map +1 -1
  12. package/dist/lib/atomic-json.js +16 -4
  13. package/dist/lib/atomic-json.js.map +1 -1
  14. package/dist/lib/cli-show.d.ts.map +1 -1
  15. package/dist/lib/cli-show.js +6 -1
  16. package/dist/lib/cli-show.js.map +1 -1
  17. package/dist/lib/config-write-target.d.ts +28 -0
  18. package/dist/lib/config-write-target.d.ts.map +1 -0
  19. package/dist/lib/config-write-target.js +159 -0
  20. package/dist/lib/config-write-target.js.map +1 -0
  21. package/dist/lib/config.d.ts +1 -1
  22. package/dist/lib/config.d.ts.map +1 -1
  23. package/dist/lib/config.js +34 -0
  24. package/dist/lib/config.js.map +1 -1
  25. package/dist/lib/cursor-usage.d.ts +1 -0
  26. package/dist/lib/cursor-usage.d.ts.map +1 -1
  27. package/dist/lib/cursor-usage.js +1 -0
  28. package/dist/lib/cursor-usage.js.map +1 -1
  29. package/dist/lib/entries.d.ts +17 -0
  30. package/dist/lib/entries.d.ts.map +1 -1
  31. package/dist/lib/entries.js +4 -0
  32. package/dist/lib/entries.js.map +1 -1
  33. package/dist/lib/format-utils.d.ts +11 -8
  34. package/dist/lib/format-utils.d.ts.map +1 -1
  35. package/dist/lib/format-utils.js +47 -6
  36. package/dist/lib/format-utils.js.map +1 -1
  37. package/dist/lib/format.d.ts +3 -0
  38. package/dist/lib/format.d.ts.map +1 -1
  39. package/dist/lib/format.js +66 -29
  40. package/dist/lib/format.js.map +1 -1
  41. package/dist/lib/glm-coding-plan.d.ts.map +1 -1
  42. package/dist/lib/glm-coding-plan.js +12 -3
  43. package/dist/lib/glm-coding-plan.js.map +1 -1
  44. package/dist/lib/init-installer.d.ts.map +1 -1
  45. package/dist/lib/init-installer.js +2 -2
  46. package/dist/lib/init-installer.js.map +1 -1
  47. package/dist/lib/ollama-cloud.d.ts +2 -2
  48. package/dist/lib/ollama-cloud.d.ts.map +1 -1
  49. package/dist/lib/ollama-cloud.js +3 -45
  50. package/dist/lib/ollama-cloud.js.map +1 -1
  51. package/dist/lib/openai.d.ts +2 -0
  52. package/dist/lib/openai.d.ts.map +1 -1
  53. package/dist/lib/openai.js +29 -13
  54. package/dist/lib/openai.js.map +1 -1
  55. package/dist/lib/opencode-config-editor.d.ts +3 -0
  56. package/dist/lib/opencode-config-editor.d.ts.map +1 -1
  57. package/dist/lib/opencode-config-editor.js +71 -10
  58. package/dist/lib/opencode-config-editor.js.map +1 -1
  59. package/dist/lib/opencode-go.d.ts.map +1 -1
  60. package/dist/lib/opencode-go.js +25 -4
  61. package/dist/lib/opencode-go.js.map +1 -1
  62. package/dist/lib/openrouter.d.ts +2 -1
  63. package/dist/lib/openrouter.d.ts.map +1 -1
  64. package/dist/lib/openrouter.js +3 -4
  65. package/dist/lib/openrouter.js.map +1 -1
  66. package/dist/lib/provider-registration.d.ts +12 -1
  67. package/dist/lib/provider-registration.d.ts.map +1 -1
  68. package/dist/lib/provider-registration.js +13 -1
  69. package/dist/lib/provider-registration.js.map +1 -1
  70. package/dist/lib/quota-accounting-projection.d.ts +2 -0
  71. package/dist/lib/quota-accounting-projection.d.ts.map +1 -1
  72. package/dist/lib/quota-accounting-projection.js +16 -1
  73. package/dist/lib/quota-accounting-projection.js.map +1 -1
  74. package/dist/lib/quota-command-format.d.ts +2 -0
  75. package/dist/lib/quota-command-format.d.ts.map +1 -1
  76. package/dist/lib/quota-command-format.js +32 -36
  77. package/dist/lib/quota-command-format.js.map +1 -1
  78. package/dist/lib/quota-dialog-commands.d.ts.map +1 -1
  79. package/dist/lib/quota-dialog-commands.js +2 -0
  80. package/dist/lib/quota-dialog-commands.js.map +1 -1
  81. package/dist/lib/quota-exhaustion-projection.d.ts +11 -0
  82. package/dist/lib/quota-exhaustion-projection.d.ts.map +1 -0
  83. package/dist/lib/quota-exhaustion-projection.js +105 -0
  84. package/dist/lib/quota-exhaustion-projection.js.map +1 -0
  85. package/dist/lib/quota-providers-local.d.ts.map +1 -1
  86. package/dist/lib/quota-providers-local.js +14 -0
  87. package/dist/lib/quota-providers-local.js.map +1 -1
  88. package/dist/lib/quota-providers-remote.d.ts.map +1 -1
  89. package/dist/lib/quota-providers-remote.js +6 -2
  90. package/dist/lib/quota-providers-remote.js.map +1 -1
  91. package/dist/lib/quota-render-data.d.ts.map +1 -1
  92. package/dist/lib/quota-render-data.js +7 -3
  93. package/dist/lib/quota-render-data.js.map +1 -1
  94. package/dist/lib/quota-state-codec.d.ts +1 -1
  95. package/dist/lib/quota-state-codec.d.ts.map +1 -1
  96. package/dist/lib/quota-state-codec.js +6 -3
  97. package/dist/lib/quota-state-codec.js.map +1 -1
  98. package/dist/lib/quota-status.d.ts.map +1 -1
  99. package/dist/lib/quota-status.js +19 -0
  100. package/dist/lib/quota-status.js.map +1 -1
  101. package/dist/lib/quota-toast-runtime.d.ts.map +1 -1
  102. package/dist/lib/quota-toast-runtime.js +9 -0
  103. package/dist/lib/quota-toast-runtime.js.map +1 -1
  104. package/dist/lib/qwen-local-quota.d.ts +2 -0
  105. package/dist/lib/qwen-local-quota.d.ts.map +1 -1
  106. package/dist/lib/qwen-local-quota.js +17 -1
  107. package/dist/lib/qwen-local-quota.js.map +1 -1
  108. package/dist/lib/scoped-update.d.ts +2 -0
  109. package/dist/lib/scoped-update.d.ts.map +1 -1
  110. package/dist/lib/scoped-update.js +43 -7
  111. package/dist/lib/scoped-update.js.map +1 -1
  112. package/dist/lib/synthetic.d.ts.map +1 -1
  113. package/dist/lib/synthetic.js +9 -0
  114. package/dist/lib/synthetic.js.map +1 -1
  115. package/dist/lib/toast-format-grouped.d.ts +3 -0
  116. package/dist/lib/toast-format-grouped.d.ts.map +1 -1
  117. package/dist/lib/toast-format-grouped.js +34 -20
  118. package/dist/lib/toast-format-grouped.js.map +1 -1
  119. package/dist/lib/tui-compact-format.d.ts +1 -0
  120. package/dist/lib/tui-compact-format.d.ts.map +1 -1
  121. package/dist/lib/tui-compact-format.js +176 -20
  122. package/dist/lib/tui-compact-format.js.map +1 -1
  123. package/dist/lib/tui-panel-state.d.ts +8 -0
  124. package/dist/lib/tui-panel-state.d.ts.map +1 -1
  125. package/dist/lib/tui-panel-state.js.map +1 -1
  126. package/dist/lib/tui-prompt-bar-format.d.ts +25 -0
  127. package/dist/lib/tui-prompt-bar-format.d.ts.map +1 -0
  128. package/dist/lib/tui-prompt-bar-format.js +206 -0
  129. package/dist/lib/tui-prompt-bar-format.js.map +1 -0
  130. package/dist/lib/tui-runtime.d.ts.map +1 -1
  131. package/dist/lib/tui-runtime.js +18 -81
  132. package/dist/lib/tui-runtime.js.map +1 -1
  133. package/dist/lib/tui-sidebar-content.d.ts +32 -0
  134. package/dist/lib/tui-sidebar-content.d.ts.map +1 -0
  135. package/dist/lib/tui-sidebar-content.js +52 -0
  136. package/dist/lib/tui-sidebar-content.js.map +1 -0
  137. package/dist/lib/tui-sidebar-format.d.ts +1 -1
  138. package/dist/lib/tui-sidebar-format.d.ts.map +1 -1
  139. package/dist/lib/tui-sidebar-format.js +3 -0
  140. package/dist/lib/tui-sidebar-format.js.map +1 -1
  141. package/dist/lib/types.d.ts +14 -12
  142. package/dist/lib/types.d.ts.map +1 -1
  143. package/dist/lib/types.js +1 -0
  144. package/dist/lib/types.js.map +1 -1
  145. package/dist/lib/xai.d.ts +2 -0
  146. package/dist/lib/xai.d.ts.map +1 -1
  147. package/dist/lib/xai.js +19 -3
  148. package/dist/lib/xai.js.map +1 -1
  149. package/dist/providers/alibaba-token-plan.d.ts +3 -0
  150. package/dist/providers/alibaba-token-plan.d.ts.map +1 -0
  151. package/dist/providers/alibaba-token-plan.js +89 -0
  152. package/dist/providers/alibaba-token-plan.js.map +1 -0
  153. package/dist/providers/anthropic.d.ts.map +1 -1
  154. package/dist/providers/anthropic.js +36 -0
  155. package/dist/providers/anthropic.js.map +1 -1
  156. package/dist/providers/cache-policies.d.ts +3 -0
  157. package/dist/providers/cache-policies.d.ts.map +1 -1
  158. package/dist/providers/cache-policies.js +1 -0
  159. package/dist/providers/cache-policies.js.map +1 -1
  160. package/dist/providers/cursor.d.ts.map +1 -1
  161. package/dist/providers/cursor.js +12 -0
  162. package/dist/providers/cursor.js.map +1 -1
  163. package/dist/providers/ollama-cloud.d.ts +1 -2
  164. package/dist/providers/ollama-cloud.d.ts.map +1 -1
  165. package/dist/providers/ollama-cloud.js +1 -20
  166. package/dist/providers/ollama-cloud.js.map +1 -1
  167. package/dist/providers/opencode-go.d.ts +1 -0
  168. package/dist/providers/opencode-go.d.ts.map +1 -1
  169. package/dist/providers/opencode-go.js +29 -1
  170. package/dist/providers/opencode-go.js.map +1 -1
  171. package/dist/providers/openrouter.d.ts.map +1 -1
  172. package/dist/providers/openrouter.js +11 -4
  173. package/dist/providers/openrouter.js.map +1 -1
  174. package/dist/providers/qwen-code.d.ts.map +1 -1
  175. package/dist/providers/qwen-code.js +1 -0
  176. package/dist/providers/qwen-code.js.map +1 -1
  177. package/dist/providers/registry.d.ts.map +1 -1
  178. package/dist/providers/registry.js +2 -0
  179. package/dist/providers/registry.js.map +1 -1
  180. package/dist/providers/result-helpers.d.ts +2 -1
  181. package/dist/providers/result-helpers.d.ts.map +1 -1
  182. package/dist/providers/result-helpers.js +1 -0
  183. package/dist/providers/result-helpers.js.map +1 -1
  184. package/dist/providers/xai.d.ts.map +1 -1
  185. package/dist/providers/xai.js +3 -0
  186. package/dist/providers/xai.js.map +1 -1
  187. package/dist/tui.d.ts.map +1 -1
  188. package/dist/tui.js +229 -217
  189. package/dist/tui.tsx +70 -42
  190. package/package.json +5 -1
package/dist/tui.js CHANGED
@@ -1,22 +1,23 @@
1
- import { createComponent as _$createComponent } from "@opentui/solid";
2
- import { effect as _$effect } from "@opentui/solid";
3
1
  import { createTextNode as _$createTextNode } from "@opentui/solid";
4
2
  import { insertNode as _$insertNode } from "@opentui/solid";
5
- import { insert as _$insert } from "@opentui/solid";
3
+ import { effect as _$effect } from "@opentui/solid";
6
4
  import { memo as _$memo } from "@opentui/solid";
5
+ import { insert as _$insert } from "@opentui/solid";
6
+ import { createComponent as _$createComponent } from "@opentui/solid";
7
7
  import { setProp as _$setProp } from "@opentui/solid";
8
8
  import { createElement as _$createElement } from "@opentui/solid";
9
9
  /** @jsxImportSource @opentui/solid */
10
10
 
11
- import { createEffect, createSignal, onCleanup, Show } from "solid-js";
12
- import { formatDisplayedPercentLabel, formatResetCountdown } from "./lib/format-utils.js";
11
+ import { createEffect, createSignal, Index, onCleanup, Show } from "solid-js";
12
+ import { formatQuotaModeHeading, formatResetCountdown, isResetTimeDecimals, resolveDisplayedPercent } from "./lib/format-utils.js";
13
13
  import { buildQuotaDialogCommandOutput, QUOTA_DIALOG_COMMANDS } from "./lib/quota-dialog-commands.js";
14
- import { extractSingleWindowWindowLabel } from "./lib/quota-entry-display.js";
15
14
  import { disposeQuotaTelemetryOwner } from "./lib/quota-telemetry.js";
16
15
  import { getSidebarBodyLineColor } from "./lib/tui-line-style.js";
17
16
  import { getCompactStatusText, getHomeBottomAnnouncementText, getSidebarPanelLines, getSidebarPanelLinesExpanded, shouldRenderCompactStatus, shouldRenderHomeBottom, shouldRenderSidebarPanel } from "./lib/tui-panel-state.js";
17
+ import { formatPromptBarPercentMeta, PROMPT_BAR_WIDTH, resolvePromptBarLabel } from "./lib/tui-prompt-bar-format.js";
18
18
  import { createTuiRefreshLifecycle } from "./lib/tui-refresh-lifecycle.js";
19
19
  import { createTuiQuotaClient, getTuiRuntimeRootHints, getTuiSessionModelMeta, loadTuiHomeBottomStatus, loadTuiSessionQuotaSurfaces, normalizeTuiSessionID, resolveTuiSurfaceRegistration, writeTuiQuotaExportIfEnabled } from "./lib/tui-runtime.js";
20
+ import { buildSidebarContentRows } from "./lib/tui-sidebar-content.js";
20
21
  const id = "@slkiser/opencode-quota";
21
22
  // Place Quota near the top so variable-height built-in sections
22
23
  // (MCP/LSP/Todo/Files) do not push it below the visible fold.
@@ -257,53 +258,58 @@ function SidebarContentView(props) {
257
258
  if (!hasDetailLines()) return lines();
258
259
  return collapsed() ? lines() : getSidebarPanelLinesExpanded(panel());
259
260
  };
260
- const toggleIcon = () => collapsed() ? "▶" : "▼";
261
- const providerCount = () => panel().providerCount ?? 0;
261
+ const contentRows = () => {
262
+ const heading = panel().headerPercentMode ? formatQuotaModeHeading(panel().headerPercentMode) : "Quota";
263
+ return buildSidebarContentRows({
264
+ collapsed: collapsed(),
265
+ heading,
266
+ hasDetailLines: hasDetailLines(),
267
+ providerCount: panel().providerCount ?? 0,
268
+ lines: displayLines()
269
+ });
270
+ };
262
271
  return _$createComponent(Show, {
263
272
  get when() {
264
273
  return shouldRenderSidebarPanel(panel());
265
274
  },
266
275
  get children() {
267
- var _el$ = _$createElement("box"),
268
- _el$2 = _$createElement("box"),
269
- _el$3 = _$createElement("text"),
270
- _el$4 = _$createElement("b"),
271
- _el$8 = _$createElement("box");
272
- _$insertNode(_el$, _el$2);
273
- _$insertNode(_el$, _el$8);
276
+ var _el$ = _$createElement("box");
274
277
  _$setProp(_el$, "gap", 0);
275
- _$insertNode(_el$2, _el$3);
276
- _$setProp(_el$2, "flexDirection", "row");
277
- _$insertNode(_el$3, _el$4);
278
- _$setProp(_el$3, "onMouseDown", toggleCollapsed);
279
- _$insert(_el$4, (() => {
280
- var _c$ = _$memo(() => !!hasDetailLines());
281
- return () => _c$() ? `${toggleIcon()} Quota` : "Quota";
282
- })());
283
- _$insert(_el$2, _$createComponent(Show, {
284
- get when() {
285
- return _$memo(() => !!collapsed())() && providerCount() > 0;
278
+ _$setProp(_el$, "width", "100%");
279
+ _$insert(_el$, _$createComponent(Index, {
280
+ get each() {
281
+ return contentRows();
286
282
  },
287
- get children() {
288
- var _el$5 = _$createElement("text"),
289
- _el$6 = _$createTextNode(` (`),
290
- _el$7 = _$createTextNode(` providers)`);
291
- _$insertNode(_el$5, _el$6);
292
- _$insertNode(_el$5, _el$7);
293
- _$insert(_el$5, providerCount, _el$7);
294
- _$effect(_$p => _$setProp(_el$5, "fg", props.api.theme.current.textMuted, _$p));
295
- return _el$5;
296
- }
297
- }), null);
298
- _$setProp(_el$8, "gap", 0);
299
- _$insert(_el$8, () => displayLines().map(line => (() => {
300
- var _el$9 = _$createElement("text");
301
- _$setProp(_el$9, "wrapMode", "none");
302
- _$insert(_el$9, line || " ");
303
- _$effect(_$p => _$setProp(_el$9, "fg", getSidebarBodyLineColor(line, props.api.theme.current), _$p));
304
- return _el$9;
305
- })()));
306
- _$effect(_$p => _$setProp(_el$3, "fg", props.api.theme.current.text, _$p));
283
+ children: row => (() => {
284
+ var _el$2 = _$createElement("text");
285
+ _$setProp(_el$2, "wrapMode", "none");
286
+ _$setProp(_el$2, "width", "100%");
287
+ _$insert(_el$2, (() => {
288
+ var _c$ = _$memo(() => row().kind === "header");
289
+ return () => _c$() ? row().segments.map(segment => segment.style === "muted" ? (() => {
290
+ var _el$3 = _$createElement("span");
291
+ _$insert(_el$3, () => segment.text);
292
+ _$effect(_$p => _$setProp(_el$3, "fg", props.api.theme.current.textMuted, _$p));
293
+ return _el$3;
294
+ })() : (() => {
295
+ var _el$4 = _$createElement("b");
296
+ _$insert(_el$4, () => segment.text);
297
+ return _el$4;
298
+ })()) : row().text || " ";
299
+ })());
300
+ _$effect(_p$ => {
301
+ var _v$ = row().kind === "header" ? props.api.theme.current.text : getSidebarBodyLineColor(row().text, props.api.theme.current),
302
+ _v$2 = row().kind === "header" ? toggleCollapsed : undefined;
303
+ _v$ !== _p$.e && (_p$.e = _$setProp(_el$2, "fg", _v$, _p$.e));
304
+ _v$2 !== _p$.t && (_p$.t = _$setProp(_el$2, "onMouseDown", _v$2, _p$.t));
305
+ return _p$;
306
+ }, {
307
+ e: undefined,
308
+ t: undefined
309
+ });
310
+ return _el$2;
311
+ })()
312
+ }));
307
313
  return _el$;
308
314
  }
309
315
  });
@@ -315,23 +321,23 @@ function CompactStatusLine(props) {
315
321
  return getCompactStatusText(panel);
316
322
  };
317
323
  const line = () => (() => {
318
- var _el$0 = _$createElement("box"),
319
- _el$1 = _$createElement("text");
320
- _$insertNode(_el$0, _el$1);
321
- _$setProp(_el$0, "flexDirection", "row");
322
- _$setProp(_el$1, "wrapMode", "none");
323
- _$insert(_el$1, text);
324
+ var _el$5 = _$createElement("box"),
325
+ _el$6 = _$createElement("text");
326
+ _$insertNode(_el$5, _el$6);
327
+ _$setProp(_el$5, "flexDirection", "row");
328
+ _$setProp(_el$6, "wrapMode", "none");
329
+ _$insert(_el$6, text);
324
330
  _$effect(_p$ => {
325
- var _v$ = props.justifyContent,
326
- _v$2 = props.api.theme.current.textMuted;
327
- _v$ !== _p$.e && (_p$.e = _$setProp(_el$0, "justifyContent", _v$, _p$.e));
328
- _v$2 !== _p$.t && (_p$.t = _$setProp(_el$1, "fg", _v$2, _p$.t));
331
+ var _v$3 = props.justifyContent,
332
+ _v$4 = props.api.theme.current.textMuted;
333
+ _v$3 !== _p$.e && (_p$.e = _$setProp(_el$5, "justifyContent", _v$3, _p$.e));
334
+ _v$4 !== _p$.t && (_p$.t = _$setProp(_el$6, "fg", _v$4, _p$.t));
329
335
  return _p$;
330
336
  }, {
331
337
  e: undefined,
332
338
  t: undefined
333
339
  });
334
- return _el$0;
340
+ return _el$5;
335
341
  })();
336
342
  return _$createComponent(Show, {
337
343
  get when() {
@@ -346,13 +352,13 @@ function CompactStatusLine(props) {
346
352
  return line();
347
353
  },
348
354
  get children() {
349
- var _el$10 = _$createElement("box"),
350
- _el$11 = _$createElement("text");
351
- _$insertNode(_el$10, _el$11);
352
- _$setProp(_el$10, "gap", 0);
353
- _$insertNode(_el$11, _$createTextNode(` `));
354
- _$insert(_el$10, line, null);
355
- return _el$10;
355
+ var _el$7 = _$createElement("box"),
356
+ _el$8 = _$createElement("text");
357
+ _$insertNode(_el$7, _el$8);
358
+ _$setProp(_el$7, "gap", 0);
359
+ _$insertNode(_el$8, _$createTextNode(` `));
360
+ _$insert(_el$7, line, null);
361
+ return _el$7;
356
362
  }
357
363
  });
358
364
  }
@@ -362,9 +368,9 @@ function SessionPromptWithCompactStatus(props) {
362
368
  const resource = useSessionQuotaResource(props.api, () => props.sessionID, props.initialLoads);
363
369
  const panel = () => resource().compact();
364
370
  return (() => {
365
- var _el$13 = _$createElement("box");
366
- _$setProp(_el$13, "gap", 0);
367
- _$insert(_el$13, _$createComponent(props.api.ui.Prompt, {
371
+ var _el$0 = _$createElement("box");
372
+ _$setProp(_el$0, "gap", 0);
373
+ _$insert(_el$0, _$createComponent(props.api.ui.Prompt, {
368
374
  get sessionID() {
369
375
  return props.sessionID;
370
376
  },
@@ -382,17 +388,16 @@ function SessionPromptWithCompactStatus(props) {
382
388
  typeof _ref$ === "function" ? _ref$(r$) : props.promptRef = r$;
383
389
  }
384
390
  }), null);
385
- _$insert(_el$13, _$createComponent(CompactStatusLine, {
391
+ _$insert(_el$0, _$createComponent(CompactStatusLine, {
386
392
  get api() {
387
393
  return props.api;
388
394
  },
389
395
  panel: panel,
390
396
  justifyContent: "flex-end"
391
397
  }), null);
392
- return _el$13;
398
+ return _el$0;
393
399
  })();
394
400
  }
395
- const PROMPT_BAR_WIDTH = 12;
396
401
  function shouldRenderPromptBar(bar) {
397
402
  return bar.status === "ready" && Boolean(bar.entry);
398
403
  }
@@ -438,21 +443,21 @@ function buildPromptBarParts(params) {
438
443
  if (!shouldRenderPromptBar(bar)) return undefined;
439
444
  const entry = bar.entry;
440
445
  if (!entry) return undefined;
441
- const reset = entry.resetTimeIso ? formatResetCountdown(entry.resetTimeIso, {
442
- compactRounded: true,
443
- decimals: bar.resetTimeDecimals
444
- }) : "";
445
446
  const hasPercent = Number.isFinite(entry.percentRemaining);
446
447
  if (entry.semanticSegment && !hasPercent) {
448
+ const reset = entry.resetTimeIso ? formatResetCountdown(entry.resetTimeIso, isResetTimeDecimals(bar.resetTimeDecimals) ? {
449
+ compactRounded: true,
450
+ decimals: bar.resetTimeDecimals
451
+ } : {
452
+ spaced: bar.resetTimeSpaced
453
+ }) : "";
447
454
  return {
448
- label: entry.semanticSegment,
455
+ label: resolvePromptBarLabel(entry),
449
456
  barText: "",
450
457
  meta: reset
451
458
  };
452
459
  }
453
- const windowLabel = entry.semanticSegment ?? extractSingleWindowWindowLabel(entry.label ?? "") ?? extractSingleWindowWindowLabel(entry.name ?? "") ?? "Quota";
454
- const percent = formatDisplayedPercentLabel(entry.percentRemaining ?? 0, bar.percentDisplayMode ?? "remaining");
455
- const p = Math.max(0, Math.min(100, Math.round(entry.percentRemaining ?? 0)));
460
+ const p = Math.min(100, resolveDisplayedPercent(entry.percentRemaining ?? 0, bar.percentDisplayMode ?? "remaining"));
456
461
  const filled = Math.round(p / 100 * PROMPT_BAR_WIDTH);
457
462
  const empty = PROMPT_BAR_WIDTH - filled;
458
463
  let barText = "█".repeat(filled) + "░".repeat(empty);
@@ -467,9 +472,16 @@ function buildPromptBarParts(params) {
467
472
  barText = cells.join("") + "░".repeat(empty);
468
473
  }
469
474
  return {
470
- label: windowLabel,
475
+ label: resolvePromptBarLabel(entry),
471
476
  barText,
472
- meta: entry.semanticSegment ? reset : [percent.replace(/\s+left$/u, ""), reset].filter(Boolean).join(" | ")
477
+ meta: formatPromptBarPercentMeta({
478
+ percentRemaining: entry.percentRemaining ?? 0,
479
+ percentDisplayMode: bar.percentDisplayMode,
480
+ resetTimeIso: entry.resetTimeIso,
481
+ resetTimeDecimals: bar.resetTimeDecimals,
482
+ resetTimeSpaced: bar.resetTimeSpaced,
483
+ runway: entry.runway
484
+ })
473
485
  };
474
486
  }
475
487
  function PromptQuotaHint(props) {
@@ -483,36 +495,36 @@ function PromptQuotaHint(props) {
483
495
  return parts();
484
496
  },
485
497
  get children() {
486
- var _el$14 = _$createElement("box"),
487
- _el$15 = _$createElement("text"),
488
- _el$16 = _$createElement("text"),
489
- _el$17 = _$createElement("text");
490
- _$insertNode(_el$14, _el$15);
491
- _$insertNode(_el$14, _el$16);
492
- _$insertNode(_el$14, _el$17);
493
- _$setProp(_el$14, "flexDirection", "row");
494
- _$setProp(_el$14, "justifyContent", "flex-end");
495
- _$setProp(_el$14, "gap", 1);
496
- _$setProp(_el$15, "wrapMode", "none");
497
- _$insert(_el$15, label);
498
- _$setProp(_el$16, "wrapMode", "none");
499
- _$insert(_el$16, bar);
500
- _$setProp(_el$17, "wrapMode", "none");
501
- _$insert(_el$17, meta);
498
+ var _el$1 = _$createElement("box"),
499
+ _el$10 = _$createElement("text"),
500
+ _el$11 = _$createElement("text"),
501
+ _el$12 = _$createElement("text");
502
+ _$insertNode(_el$1, _el$10);
503
+ _$insertNode(_el$1, _el$11);
504
+ _$insertNode(_el$1, _el$12);
505
+ _$setProp(_el$1, "flexDirection", "row");
506
+ _$setProp(_el$1, "justifyContent", "flex-end");
507
+ _$setProp(_el$1, "gap", 1);
508
+ _$setProp(_el$10, "wrapMode", "none");
509
+ _$insert(_el$10, label);
510
+ _$setProp(_el$11, "wrapMode", "none");
511
+ _$insert(_el$11, bar);
512
+ _$setProp(_el$12, "wrapMode", "none");
513
+ _$insert(_el$12, meta);
502
514
  _$effect(_p$ => {
503
- var _v$3 = props.api.theme.current.textMuted,
504
- _v$4 = barColor(),
505
- _v$5 = props.api.theme.current.textMuted;
506
- _v$3 !== _p$.e && (_p$.e = _$setProp(_el$15, "fg", _v$3, _p$.e));
507
- _v$4 !== _p$.t && (_p$.t = _$setProp(_el$16, "fg", _v$4, _p$.t));
508
- _v$5 !== _p$.a && (_p$.a = _$setProp(_el$17, "fg", _v$5, _p$.a));
515
+ var _v$5 = props.api.theme.current.textMuted,
516
+ _v$6 = barColor(),
517
+ _v$7 = props.api.theme.current.textMuted;
518
+ _v$5 !== _p$.e && (_p$.e = _$setProp(_el$10, "fg", _v$5, _p$.e));
519
+ _v$6 !== _p$.t && (_p$.t = _$setProp(_el$11, "fg", _v$6, _p$.t));
520
+ _v$7 !== _p$.a && (_p$.a = _$setProp(_el$12, "fg", _v$7, _p$.a));
509
521
  return _p$;
510
522
  }, {
511
523
  e: undefined,
512
524
  t: undefined,
513
525
  a: undefined
514
526
  });
515
- return _el$14;
527
+ return _el$1;
516
528
  }
517
529
  });
518
530
  }
@@ -530,9 +542,9 @@ function SessionQuotaPromptBar(props) {
530
542
  onCleanup(() => clearInterval(interval));
531
543
  });
532
544
  return (() => {
533
- var _el$18 = _$createElement("box");
534
- _$setProp(_el$18, "gap", 0);
535
- _$insert(_el$18, _$createComponent(props.api.ui.Prompt, {
545
+ var _el$13 = _$createElement("box");
546
+ _$setProp(_el$13, "gap", 0);
547
+ _$insert(_el$13, _$createComponent(props.api.ui.Prompt, {
536
548
  get sessionID() {
537
549
  return props.sessionID;
538
550
  },
@@ -550,7 +562,7 @@ function SessionQuotaPromptBar(props) {
550
562
  typeof _ref$2 === "function" ? _ref$2(r$) : props.promptRef = r$;
551
563
  }
552
564
  }), null);
553
- _$insert(_el$18, _$createComponent(PromptQuotaHint, {
565
+ _$insert(_el$13, _$createComponent(PromptQuotaHint, {
554
566
  get api() {
555
567
  return props.api;
556
568
  },
@@ -558,7 +570,7 @@ function SessionQuotaPromptBar(props) {
558
570
  running: running,
559
571
  phase: phase
560
572
  }), null);
561
- return _el$18;
573
+ return _el$13;
562
574
  })();
563
575
  }
564
576
  function HomeBottomView(props) {
@@ -568,35 +580,35 @@ function HomeBottomView(props) {
568
580
  const compact = () => resource.bottom().compact;
569
581
  const visible = () => shouldRenderHomeBottom(resource.bottom());
570
582
  return (() => {
571
- var _el$19 = _$createElement("box");
572
- _$setProp(_el$19, "gap", 0);
573
- _$insert(_el$19, _$createComponent(Show, {
583
+ var _el$14 = _$createElement("box");
584
+ _$setProp(_el$14, "gap", 0);
585
+ _$insert(_el$14, _$createComponent(Show, {
574
586
  get when() {
575
587
  return visible();
576
588
  },
577
589
  get children() {
578
- var _el$20 = _$createElement("text");
579
- _$insertNode(_el$20, _$createTextNode(` `));
580
- return _el$20;
590
+ var _el$15 = _$createElement("text");
591
+ _$insertNode(_el$15, _$createTextNode(` `));
592
+ return _el$15;
581
593
  }
582
594
  }), null);
583
- _$insert(_el$19, _$createComponent(Show, {
595
+ _$insert(_el$14, _$createComponent(Show, {
584
596
  get when() {
585
597
  return _$memo(() => !!visible())() && announcement();
586
598
  },
587
599
  get children() {
588
- var _el$22 = _$createElement("box"),
589
- _el$23 = _$createElement("text");
590
- _$insertNode(_el$22, _el$23);
591
- _$setProp(_el$22, "flexDirection", "row");
592
- _$setProp(_el$22, "justifyContent", "center");
593
- _$setProp(_el$23, "wrapMode", "none");
594
- _$insert(_el$23, announcement);
595
- _$effect(_$p => _$setProp(_el$23, "fg", props.api.theme.current.textMuted, _$p));
596
- return _el$22;
600
+ var _el$17 = _$createElement("box"),
601
+ _el$18 = _$createElement("text");
602
+ _$insertNode(_el$17, _el$18);
603
+ _$setProp(_el$17, "flexDirection", "row");
604
+ _$setProp(_el$17, "justifyContent", "center");
605
+ _$setProp(_el$18, "wrapMode", "none");
606
+ _$insert(_el$18, announcement);
607
+ _$effect(_$p => _$setProp(_el$18, "fg", props.api.theme.current.textMuted, _$p));
608
+ return _el$17;
597
609
  }
598
610
  }), null);
599
- _$insert(_el$19, _$createComponent(Show, {
611
+ _$insert(_el$14, _$createComponent(Show, {
600
612
  get when() {
601
613
  return visible();
602
614
  },
@@ -610,7 +622,7 @@ function HomeBottomView(props) {
610
622
  });
611
623
  }
612
624
  }), null);
613
- return _el$19;
625
+ return _el$14;
614
626
  })();
615
627
  }
616
628
  function getActiveTuiSessionID(api) {
@@ -628,117 +640,117 @@ function getTuiCommandArguments(input) {
628
640
  }
629
641
  function CommandLoadingDialog(props) {
630
642
  return (() => {
631
- var _el$24 = _$createElement("box"),
632
- _el$25 = _$createElement("text"),
633
- _el$26 = _$createElement("b"),
634
- _el$27 = _$createElement("text");
635
- _$insertNode(_el$24, _el$25);
636
- _$insertNode(_el$24, _el$27);
637
- _$setProp(_el$24, "gap", 1);
638
- _$setProp(_el$24, "paddingLeft", 2);
639
- _$setProp(_el$24, "paddingRight", 2);
640
- _$setProp(_el$24, "paddingBottom", 1);
641
- _$insertNode(_el$25, _el$26);
642
- _$insert(_el$26, () => props.title);
643
- _$insertNode(_el$27, _$createTextNode(`Loading deterministic local output…`));
643
+ var _el$19 = _$createElement("box"),
644
+ _el$20 = _$createElement("text"),
645
+ _el$21 = _$createElement("b"),
646
+ _el$22 = _$createElement("text");
647
+ _$insertNode(_el$19, _el$20);
648
+ _$insertNode(_el$19, _el$22);
649
+ _$setProp(_el$19, "gap", 1);
650
+ _$setProp(_el$19, "paddingLeft", 2);
651
+ _$setProp(_el$19, "paddingRight", 2);
652
+ _$setProp(_el$19, "paddingBottom", 1);
653
+ _$insertNode(_el$20, _el$21);
654
+ _$insert(_el$21, () => props.title);
655
+ _$insertNode(_el$22, _$createTextNode(`Loading deterministic local output…`));
644
656
  _$effect(_p$ => {
645
- var _v$6 = props.api.theme.current.text,
646
- _v$7 = props.api.theme.current.textMuted;
647
- _v$6 !== _p$.e && (_p$.e = _$setProp(_el$25, "fg", _v$6, _p$.e));
648
- _v$7 !== _p$.t && (_p$.t = _$setProp(_el$27, "fg", _v$7, _p$.t));
657
+ var _v$8 = props.api.theme.current.text,
658
+ _v$9 = props.api.theme.current.textMuted;
659
+ _v$8 !== _p$.e && (_p$.e = _$setProp(_el$20, "fg", _v$8, _p$.e));
660
+ _v$9 !== _p$.t && (_p$.t = _$setProp(_el$22, "fg", _v$9, _p$.t));
649
661
  return _p$;
650
662
  }, {
651
663
  e: undefined,
652
664
  t: undefined
653
665
  });
654
- return _el$24;
666
+ return _el$19;
655
667
  })();
656
668
  }
657
669
  function CommandOutputDialog(props) {
658
670
  const lines = () => props.output.split("\n");
659
671
  const bodyHeight = () => Math.min(28, Math.max(6, lines().length));
660
672
  return (() => {
661
- var _el$29 = _$createElement("box"),
662
- _el$30 = _$createElement("text"),
663
- _el$31 = _$createElement("b"),
664
- _el$32 = _$createElement("scrollbox"),
665
- _el$33 = _$createElement("box"),
666
- _el$34 = _$createElement("text");
667
- _$insertNode(_el$29, _el$30);
668
- _$insertNode(_el$29, _el$32);
669
- _$insertNode(_el$29, _el$34);
670
- _$setProp(_el$29, "gap", 1);
671
- _$setProp(_el$29, "width", "100%");
672
- _$setProp(_el$29, "flexGrow", 1);
673
- _$setProp(_el$29, "paddingLeft", 2);
674
- _$setProp(_el$29, "paddingRight", 2);
675
- _$setProp(_el$29, "paddingBottom", 1);
676
- _$insertNode(_el$30, _el$31);
677
- _$insert(_el$31, () => props.title);
678
- _$insertNode(_el$32, _el$33);
679
- _$setProp(_el$32, "width", "100%");
680
- _$setProp(_el$32, "flexGrow", 1);
681
- _$setProp(_el$32, "maxHeight", 28);
682
- _$setProp(_el$33, "gap", 0);
683
- _$setProp(_el$33, "width", "100%");
684
- _$setProp(_el$33, "minWidth", 0);
685
- _$insert(_el$33, () => lines().map(line => (() => {
686
- var _el$36 = _$createElement("text");
687
- _$setProp(_el$36, "wrapMode", "word");
688
- _$setProp(_el$36, "width", "100%");
689
- _$insert(_el$36, line || " ");
690
- _$effect(_$p => _$setProp(_el$36, "fg", props.api.theme.current.text, _$p));
691
- return _el$36;
673
+ var _el$24 = _$createElement("box"),
674
+ _el$25 = _$createElement("text"),
675
+ _el$26 = _$createElement("b"),
676
+ _el$27 = _$createElement("scrollbox"),
677
+ _el$28 = _$createElement("box"),
678
+ _el$29 = _$createElement("text");
679
+ _$insertNode(_el$24, _el$25);
680
+ _$insertNode(_el$24, _el$27);
681
+ _$insertNode(_el$24, _el$29);
682
+ _$setProp(_el$24, "gap", 1);
683
+ _$setProp(_el$24, "width", "100%");
684
+ _$setProp(_el$24, "flexGrow", 1);
685
+ _$setProp(_el$24, "paddingLeft", 2);
686
+ _$setProp(_el$24, "paddingRight", 2);
687
+ _$setProp(_el$24, "paddingBottom", 1);
688
+ _$insertNode(_el$25, _el$26);
689
+ _$insert(_el$26, () => props.title);
690
+ _$insertNode(_el$27, _el$28);
691
+ _$setProp(_el$27, "width", "100%");
692
+ _$setProp(_el$27, "flexGrow", 1);
693
+ _$setProp(_el$27, "maxHeight", 28);
694
+ _$setProp(_el$28, "gap", 0);
695
+ _$setProp(_el$28, "width", "100%");
696
+ _$setProp(_el$28, "minWidth", 0);
697
+ _$insert(_el$28, () => lines().map(line => (() => {
698
+ var _el$31 = _$createElement("text");
699
+ _$setProp(_el$31, "wrapMode", "word");
700
+ _$setProp(_el$31, "width", "100%");
701
+ _$insert(_el$31, line || " ");
702
+ _$effect(_$p => _$setProp(_el$31, "fg", props.api.theme.current.text, _$p));
703
+ return _el$31;
692
704
  })()));
693
- _$insertNode(_el$34, _$createTextNode(`esc closes`));
705
+ _$insertNode(_el$29, _$createTextNode(`esc closes`));
694
706
  _$effect(_p$ => {
695
- var _v$8 = props.api.theme.current.text,
696
- _v$9 = bodyHeight(),
697
- _v$0 = props.api.theme.current.textMuted;
698
- _v$8 !== _p$.e && (_p$.e = _$setProp(_el$30, "fg", _v$8, _p$.e));
699
- _v$9 !== _p$.t && (_p$.t = _$setProp(_el$32, "minHeight", _v$9, _p$.t));
700
- _v$0 !== _p$.a && (_p$.a = _$setProp(_el$34, "fg", _v$0, _p$.a));
707
+ var _v$0 = props.api.theme.current.text,
708
+ _v$1 = bodyHeight(),
709
+ _v$10 = props.api.theme.current.textMuted;
710
+ _v$0 !== _p$.e && (_p$.e = _$setProp(_el$25, "fg", _v$0, _p$.e));
711
+ _v$1 !== _p$.t && (_p$.t = _$setProp(_el$27, "minHeight", _v$1, _p$.t));
712
+ _v$10 !== _p$.a && (_p$.a = _$setProp(_el$29, "fg", _v$10, _p$.a));
701
713
  return _p$;
702
714
  }, {
703
715
  e: undefined,
704
716
  t: undefined,
705
717
  a: undefined
706
718
  });
707
- return _el$29;
719
+ return _el$24;
708
720
  })();
709
721
  }
710
722
  function CommandErrorDialog(props) {
711
723
  const message = props.error instanceof Error ? props.error.message : String(props.error);
712
724
  return (() => {
713
- var _el$37 = _$createElement("box"),
714
- _el$38 = _$createElement("text"),
715
- _el$39 = _$createElement("b"),
716
- _el$40 = _$createElement("text"),
717
- _el$42 = _$createElement("text"),
718
- _el$43 = _$createElement("text");
719
- _$insertNode(_el$37, _el$38);
720
- _$insertNode(_el$37, _el$40);
721
- _$insertNode(_el$37, _el$42);
722
- _$insertNode(_el$37, _el$43);
723
- _$setProp(_el$37, "gap", 1);
724
- _$setProp(_el$37, "paddingLeft", 2);
725
- _$setProp(_el$37, "paddingRight", 2);
726
- _$setProp(_el$37, "paddingBottom", 1);
727
- _$insertNode(_el$38, _el$39);
728
- _$insert(_el$39, () => props.title);
729
- _$insertNode(_el$40, _$createTextNode(`OpenCode Quota command failed.`));
730
- _$setProp(_el$42, "wrapMode", "none");
731
- _$insert(_el$42, message || "Unknown error");
732
- _$insertNode(_el$43, _$createTextNode(`esc closes`));
725
+ var _el$32 = _$createElement("box"),
726
+ _el$33 = _$createElement("text"),
727
+ _el$34 = _$createElement("b"),
728
+ _el$35 = _$createElement("text"),
729
+ _el$37 = _$createElement("text"),
730
+ _el$38 = _$createElement("text");
731
+ _$insertNode(_el$32, _el$33);
732
+ _$insertNode(_el$32, _el$35);
733
+ _$insertNode(_el$32, _el$37);
734
+ _$insertNode(_el$32, _el$38);
735
+ _$setProp(_el$32, "gap", 1);
736
+ _$setProp(_el$32, "paddingLeft", 2);
737
+ _$setProp(_el$32, "paddingRight", 2);
738
+ _$setProp(_el$32, "paddingBottom", 1);
739
+ _$insertNode(_el$33, _el$34);
740
+ _$insert(_el$34, () => props.title);
741
+ _$insertNode(_el$35, _$createTextNode(`OpenCode Quota command failed.`));
742
+ _$setProp(_el$37, "wrapMode", "none");
743
+ _$insert(_el$37, message || "Unknown error");
744
+ _$insertNode(_el$38, _$createTextNode(`esc closes`));
733
745
  _$effect(_p$ => {
734
- var _v$1 = props.api.theme.current.text,
735
- _v$10 = props.api.theme.current.text,
736
- _v$11 = props.api.theme.current.textMuted,
737
- _v$12 = props.api.theme.current.textMuted;
738
- _v$1 !== _p$.e && (_p$.e = _$setProp(_el$38, "fg", _v$1, _p$.e));
739
- _v$10 !== _p$.t && (_p$.t = _$setProp(_el$40, "fg", _v$10, _p$.t));
740
- _v$11 !== _p$.a && (_p$.a = _$setProp(_el$42, "fg", _v$11, _p$.a));
741
- _v$12 !== _p$.o && (_p$.o = _$setProp(_el$43, "fg", _v$12, _p$.o));
746
+ var _v$11 = props.api.theme.current.text,
747
+ _v$12 = props.api.theme.current.text,
748
+ _v$13 = props.api.theme.current.textMuted,
749
+ _v$14 = props.api.theme.current.textMuted;
750
+ _v$11 !== _p$.e && (_p$.e = _$setProp(_el$33, "fg", _v$11, _p$.e));
751
+ _v$12 !== _p$.t && (_p$.t = _$setProp(_el$35, "fg", _v$12, _p$.t));
752
+ _v$13 !== _p$.a && (_p$.a = _$setProp(_el$37, "fg", _v$13, _p$.a));
753
+ _v$14 !== _p$.o && (_p$.o = _$setProp(_el$38, "fg", _v$14, _p$.o));
742
754
  return _p$;
743
755
  }, {
744
756
  e: undefined,
@@ -746,7 +758,7 @@ function CommandErrorDialog(props) {
746
758
  a: undefined,
747
759
  o: undefined
748
760
  });
749
- return _el$37;
761
+ return _el$32;
750
762
  })();
751
763
  }
752
764
  function getCommandPromptCopy(spec) {
@@ -790,11 +802,11 @@ async function runQuotaDialogCommandAsync(api, command, commandDisplay, rawInput
790
802
  return prompt.placeholder;
791
803
  },
792
804
  description: () => (() => {
793
- var _el$45 = _$createElement("text");
794
- _$setProp(_el$45, "wrapMode", "word");
795
- _$insert(_el$45, () => prompt.description);
796
- _$effect(_$p => _$setProp(_el$45, "fg", api.theme.current.textMuted, _$p));
797
- return _el$45;
805
+ var _el$40 = _$createElement("text");
806
+ _$setProp(_el$40, "wrapMode", "word");
807
+ _$insert(_el$40, () => prompt.description);
808
+ _$effect(_$p => _$setProp(_el$40, "fg", api.theme.current.textMuted, _$p));
809
+ return _el$40;
798
810
  })(),
799
811
  onCancel: () => api.ui.dialog.clear(),
800
812
  onConfirm: value => {