@slkiser/opencode-quota 3.11.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +103 -57
  2. package/dist/bin/opencode-quota.d.ts.map +1 -1
  3. package/dist/bin/opencode-quota.js +24 -7
  4. package/dist/bin/opencode-quota.js.map +1 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/anthropic.d.ts.map +1 -1
  10. package/dist/lib/anthropic.js +106 -3
  11. package/dist/lib/anthropic.js.map +1 -1
  12. package/dist/lib/atomic-json.d.ts +1 -0
  13. package/dist/lib/atomic-json.d.ts.map +1 -1
  14. package/dist/lib/atomic-json.js +5 -2
  15. package/dist/lib/atomic-json.js.map +1 -1
  16. package/dist/lib/cli-show.d.ts.map +1 -1
  17. package/dist/lib/cli-show.js +11 -7
  18. package/dist/lib/cli-show.js.map +1 -1
  19. package/dist/lib/command-surfaces.d.ts +10 -0
  20. package/dist/lib/command-surfaces.d.ts.map +1 -0
  21. package/dist/lib/command-surfaces.js +9 -0
  22. package/dist/lib/command-surfaces.js.map +1 -0
  23. package/dist/lib/config-file-utils.d.ts +5 -0
  24. package/dist/lib/config-file-utils.d.ts.map +1 -1
  25. package/dist/lib/config-file-utils.js +20 -3
  26. package/dist/lib/config-file-utils.js.map +1 -1
  27. package/dist/lib/config.d.ts +5 -3
  28. package/dist/lib/config.d.ts.map +1 -1
  29. package/dist/lib/config.js +124 -32
  30. package/dist/lib/config.js.map +1 -1
  31. package/dist/lib/copilot.d.ts +19 -12
  32. package/dist/lib/copilot.d.ts.map +1 -1
  33. package/dist/lib/copilot.js +462 -566
  34. package/dist/lib/copilot.js.map +1 -1
  35. package/dist/lib/display-sanitize.d.ts.map +1 -1
  36. package/dist/lib/display-sanitize.js +13 -0
  37. package/dist/lib/display-sanitize.js.map +1 -1
  38. package/dist/lib/entries.d.ts +53 -4
  39. package/dist/lib/entries.d.ts.map +1 -1
  40. package/dist/lib/entries.js.map +1 -1
  41. package/dist/lib/init-installer.d.ts +11 -1
  42. package/dist/lib/init-installer.d.ts.map +1 -1
  43. package/dist/lib/init-installer.js +542 -154
  44. package/dist/lib/init-installer.js.map +1 -1
  45. package/dist/lib/openai.d.ts +9 -12
  46. package/dist/lib/openai.d.ts.map +1 -1
  47. package/dist/lib/openai.js +69 -40
  48. package/dist/lib/openai.js.map +1 -1
  49. package/dist/lib/opencode-config-editor.d.ts +53 -0
  50. package/dist/lib/opencode-config-editor.d.ts.map +1 -0
  51. package/dist/lib/opencode-config-editor.js +274 -0
  52. package/dist/lib/opencode-config-editor.js.map +1 -0
  53. package/dist/lib/opencode-config-providers.d.ts +18 -0
  54. package/dist/lib/opencode-config-providers.d.ts.map +1 -1
  55. package/dist/lib/opencode-config-providers.js +75 -4
  56. package/dist/lib/opencode-config-providers.js.map +1 -1
  57. package/dist/lib/opencode-runtime-paths.d.ts.map +1 -1
  58. package/dist/lib/opencode-runtime-paths.js +10 -3
  59. package/dist/lib/opencode-runtime-paths.js.map +1 -1
  60. package/dist/lib/opencode-storage.d.ts +10 -0
  61. package/dist/lib/opencode-storage.d.ts.map +1 -1
  62. package/dist/lib/opencode-storage.js +75 -0
  63. package/dist/lib/opencode-storage.js.map +1 -1
  64. package/dist/lib/provider-add-command.d.ts +35 -0
  65. package/dist/lib/provider-add-command.d.ts.map +1 -0
  66. package/dist/lib/provider-add-command.js +185 -0
  67. package/dist/lib/provider-add-command.js.map +1 -0
  68. package/dist/lib/provider-add.d.ts +21 -0
  69. package/dist/lib/provider-add.d.ts.map +1 -0
  70. package/dist/lib/provider-add.js +210 -0
  71. package/dist/lib/provider-add.js.map +1 -0
  72. package/dist/lib/provider-metadata.d.ts +1 -1
  73. package/dist/lib/provider-metadata.d.ts.map +1 -1
  74. package/dist/lib/provider-metadata.js +11 -5
  75. package/dist/lib/provider-metadata.js.map +1 -1
  76. package/dist/lib/quota-command-format.d.ts +2 -0
  77. package/dist/lib/quota-command-format.d.ts.map +1 -1
  78. package/dist/lib/quota-command-format.js +94 -26
  79. package/dist/lib/quota-command-format.js.map +1 -1
  80. package/dist/lib/quota-dialog-commands.d.ts.map +1 -1
  81. package/dist/lib/quota-dialog-commands.js +8 -4
  82. package/dist/lib/quota-dialog-commands.js.map +1 -1
  83. package/dist/lib/quota-export-types.d.ts +48 -27
  84. package/dist/lib/quota-export-types.d.ts.map +1 -1
  85. package/dist/lib/quota-export-types.js +0 -7
  86. package/dist/lib/quota-export-types.js.map +1 -1
  87. package/dist/lib/quota-export.d.ts.map +1 -1
  88. package/dist/lib/quota-export.js +63 -16
  89. package/dist/lib/quota-export.js.map +1 -1
  90. package/dist/lib/quota-providers-local.d.ts +55 -0
  91. package/dist/lib/quota-providers-local.d.ts.map +1 -0
  92. package/dist/lib/quota-providers-local.js +313 -0
  93. package/dist/lib/quota-providers-local.js.map +1 -0
  94. package/dist/lib/quota-providers-remote.d.ts +23 -0
  95. package/dist/lib/quota-providers-remote.d.ts.map +1 -0
  96. package/dist/lib/quota-providers-remote.js +318 -0
  97. package/dist/lib/quota-providers-remote.js.map +1 -0
  98. package/dist/lib/quota-providers.d.ts +77 -0
  99. package/dist/lib/quota-providers.d.ts.map +1 -0
  100. package/dist/lib/quota-providers.js +630 -0
  101. package/dist/lib/quota-providers.js.map +1 -0
  102. package/dist/lib/quota-render-data.d.ts +1 -0
  103. package/dist/lib/quota-render-data.d.ts.map +1 -1
  104. package/dist/lib/quota-render-data.js +35 -16
  105. package/dist/lib/quota-render-data.js.map +1 -1
  106. package/dist/lib/quota-runtime-context.d.ts.map +1 -1
  107. package/dist/lib/quota-runtime-context.js +3 -4
  108. package/dist/lib/quota-runtime-context.js.map +1 -1
  109. package/dist/lib/quota-state.d.ts +5 -2
  110. package/dist/lib/quota-state.d.ts.map +1 -1
  111. package/dist/lib/quota-state.js +268 -51
  112. package/dist/lib/quota-state.js.map +1 -1
  113. package/dist/lib/quota-status.d.ts +2 -1
  114. package/dist/lib/quota-status.d.ts.map +1 -1
  115. package/dist/lib/quota-status.js +247 -69
  116. package/dist/lib/quota-status.js.map +1 -1
  117. package/dist/lib/qwen-local-quota.d.ts +12 -11
  118. package/dist/lib/qwen-local-quota.d.ts.map +1 -1
  119. package/dist/lib/qwen-local-quota.js +82 -87
  120. package/dist/lib/qwen-local-quota.js.map +1 -1
  121. package/dist/lib/scoped-update.d.ts +63 -0
  122. package/dist/lib/scoped-update.d.ts.map +1 -0
  123. package/dist/lib/scoped-update.js +311 -0
  124. package/dist/lib/scoped-update.js.map +1 -0
  125. package/dist/lib/tui-runtime.d.ts +2 -0
  126. package/dist/lib/tui-runtime.d.ts.map +1 -1
  127. package/dist/lib/tui-runtime.js +33 -9
  128. package/dist/lib/tui-runtime.js.map +1 -1
  129. package/dist/lib/types.d.ts +51 -15
  130. package/dist/lib/types.d.ts.map +1 -1
  131. package/dist/lib/types.js +2 -1
  132. package/dist/lib/types.js.map +1 -1
  133. package/dist/plugin.d.ts.map +1 -1
  134. package/dist/plugin.js +75 -100
  135. package/dist/plugin.js.map +1 -1
  136. package/dist/providers/alibaba-coding-plan.d.ts.map +1 -1
  137. package/dist/providers/alibaba-coding-plan.js +35 -4
  138. package/dist/providers/alibaba-coding-plan.js.map +1 -1
  139. package/dist/providers/anthropic.d.ts.map +1 -1
  140. package/dist/providers/anthropic.js +13 -1
  141. package/dist/providers/anthropic.js.map +1 -1
  142. package/dist/providers/chutes.d.ts.map +1 -1
  143. package/dist/providers/chutes.js +6 -0
  144. package/dist/providers/chutes.js.map +1 -1
  145. package/dist/providers/copilot.d.ts +2 -1
  146. package/dist/providers/copilot.d.ts.map +1 -1
  147. package/dist/providers/copilot.js +143 -60
  148. package/dist/providers/copilot.js.map +1 -1
  149. package/dist/providers/cursor.d.ts.map +1 -1
  150. package/dist/providers/cursor.js +30 -1
  151. package/dist/providers/cursor.js.map +1 -1
  152. package/dist/providers/deepseek.d.ts.map +1 -1
  153. package/dist/providers/deepseek.js +13 -1
  154. package/dist/providers/deepseek.js.map +1 -1
  155. package/dist/providers/google-agy.d.ts.map +1 -1
  156. package/dist/providers/google-agy.js +7 -1
  157. package/dist/providers/google-agy.js.map +1 -1
  158. package/dist/providers/google-antigravity.d.ts.map +1 -1
  159. package/dist/providers/google-antigravity.js +10 -2
  160. package/dist/providers/google-antigravity.js.map +1 -1
  161. package/dist/providers/google-gemini-cli.d.ts.map +1 -1
  162. package/dist/providers/google-gemini-cli.js +8 -2
  163. package/dist/providers/google-gemini-cli.js.map +1 -1
  164. package/dist/providers/kimi-code.d.ts.map +1 -1
  165. package/dist/providers/kimi-code.js +6 -0
  166. package/dist/providers/kimi-code.js.map +1 -1
  167. package/dist/providers/minimax-coding-plan.d.ts.map +1 -1
  168. package/dist/providers/minimax-coding-plan.js +12 -4
  169. package/dist/providers/minimax-coding-plan.js.map +1 -1
  170. package/dist/providers/nanogpt.d.ts.map +1 -1
  171. package/dist/providers/nanogpt.js +19 -1
  172. package/dist/providers/nanogpt.js.map +1 -1
  173. package/dist/providers/ollama-cloud.d.ts.map +1 -1
  174. package/dist/providers/ollama-cloud.js +12 -0
  175. package/dist/providers/ollama-cloud.js.map +1 -1
  176. package/dist/providers/openai.d.ts.map +1 -1
  177. package/dist/providers/openai.js +7 -0
  178. package/dist/providers/openai.js.map +1 -1
  179. package/dist/providers/opencode-go.d.ts.map +1 -1
  180. package/dist/providers/opencode-go.js +9 -1
  181. package/dist/providers/opencode-go.js.map +1 -1
  182. package/dist/providers/quota-providers.d.ts +6 -0
  183. package/dist/providers/quota-providers.d.ts.map +1 -0
  184. package/dist/providers/quota-providers.js +276 -0
  185. package/dist/providers/quota-providers.js.map +1 -0
  186. package/dist/providers/qwen-code.d.ts.map +1 -1
  187. package/dist/providers/qwen-code.js +29 -3
  188. package/dist/providers/qwen-code.js.map +1 -1
  189. package/dist/providers/registry.d.ts.map +1 -1
  190. package/dist/providers/registry.js +2 -0
  191. package/dist/providers/registry.js.map +1 -1
  192. package/dist/providers/result-helpers.d.ts +2 -1
  193. package/dist/providers/result-helpers.d.ts.map +1 -1
  194. package/dist/providers/result-helpers.js +6 -1
  195. package/dist/providers/result-helpers.js.map +1 -1
  196. package/dist/providers/synthetic.d.ts.map +1 -1
  197. package/dist/providers/synthetic.js +7 -1
  198. package/dist/providers/synthetic.js.map +1 -1
  199. package/dist/providers/zai.d.ts.map +1 -1
  200. package/dist/providers/zai.js +7 -1
  201. package/dist/providers/zai.js.map +1 -1
  202. package/dist/providers/zhipu.d.ts.map +1 -1
  203. package/dist/providers/zhipu.js +7 -1
  204. package/dist/providers/zhipu.js.map +1 -1
  205. package/dist/tui.d.ts.map +1 -1
  206. package/dist/tui.js +148 -122
  207. package/dist/tui.tsx +122 -114
  208. package/package.json +29 -21
package/dist/tui.js CHANGED
@@ -11,7 +11,7 @@ import { createElement as _$createElement } from "@opentui/solid";
11
11
  import { Show, createEffect, createSignal, onCleanup } from "solid-js";
12
12
  import { getCompactStatusText, getHomeBottomAnnouncementText, getSidebarPanelLines, getSidebarPanelLinesExpanded, shouldRenderCompactStatus, shouldRenderHomeBottom, shouldRenderSidebarPanel } from "./lib/tui-panel-state.js";
13
13
  import { getSidebarBodyLineColor } from "./lib/tui-line-style.js";
14
- import { createTuiQuotaClient, getTuiRuntimeRootHints, getTuiSessionModelMeta, loadTuiHomeBottomStatus, normalizeTuiSessionID, loadTuiSessionQuotaSurfaces, resolveTuiSurfaceRegistration, writeTuiQuotaExportIfEnabled } from "./lib/tui-runtime.js";
14
+ import { createTuiQuotaClient, getTuiRuntimeRootHints, getTuiSessionModelMeta, loadTuiHomeBottomStatus, loadTuiSessionQuotaSurfaces, normalizeTuiSessionID, resolveTuiSurfaceRegistration, writeTuiQuotaExportIfEnabled } from "./lib/tui-runtime.js";
15
15
  import { QUOTA_DIALOG_COMMANDS, buildQuotaDialogCommandOutput } from "./lib/quota-dialog-commands.js";
16
16
  const id = "@slkiser/opencode-quota";
17
17
  // Place Quota near the top so variable-height built-in sections
@@ -140,11 +140,13 @@ function acquireSessionQuotaResource(api, sessionID) {
140
140
  resources.set(sessionID, next);
141
141
  return next;
142
142
  }
143
- function createHomeBottomResource(api) {
143
+ function createHomeBottomResource(api, compactHomeBottomEnabled) {
144
144
  const [bottom, setBottom] = createSignal({
145
145
  status: "loading",
146
- compact: {
146
+ compact: compactHomeBottomEnabled ? {
147
147
  status: "loading"
148
+ } : {
149
+ status: "disabled"
148
150
  }
149
151
  });
150
152
  let refCount = 0;
@@ -221,10 +223,10 @@ function createHomeBottomResource(api) {
221
223
  reload();
222
224
  return resource;
223
225
  }
224
- function acquireHomeBottomResource(api) {
226
+ function acquireHomeBottomResource(api, compactHomeBottomEnabled) {
225
227
  const existing = homeResources.get(api);
226
228
  if (existing) return existing.retain();
227
- const next = createHomeBottomResource(api).retain();
229
+ const next = createHomeBottomResource(api, compactHomeBottomEnabled).retain();
228
230
  homeResources.set(api, next);
229
231
  return next;
230
232
  }
@@ -396,51 +398,60 @@ function SessionPromptWithCompactStatus(props) {
396
398
  })();
397
399
  }
398
400
  function HomeBottomView(props) {
399
- const resource = acquireHomeBottomResource(props.api);
401
+ const resource = acquireHomeBottomResource(props.api, props.compactHomeBottomEnabled);
400
402
  onCleanup(() => resource.release());
401
403
  const announcement = () => getHomeBottomAnnouncementText(resource.bottom());
402
404
  const compact = () => resource.bottom().compact;
403
- return _$createComponent(Show, {
404
- get when() {
405
- return shouldRenderHomeBottom(resource.bottom());
406
- },
407
- get children() {
408
- var _el$14 = _$createElement("box"),
409
- _el$15 = _$createElement("text");
410
- _$insertNode(_el$14, _el$15);
411
- _$setProp(_el$14, "gap", 0);
412
- _$insertNode(_el$15, _$createTextNode(` `));
413
- _$insert(_el$14, _$createComponent(Show, {
414
- get when() {
415
- return announcement();
416
- },
417
- get children() {
418
- var _el$17 = _$createElement("box"),
419
- _el$18 = _$createElement("text");
420
- _$insertNode(_el$17, _el$18);
421
- _$setProp(_el$17, "flexDirection", "row");
422
- _$setProp(_el$17, "justifyContent", "center");
423
- _$setProp(_el$18, "wrapMode", "none");
424
- _$insert(_el$18, announcement);
425
- _$effect(_$p => _$setProp(_el$18, "fg", props.api.theme.current.textMuted, _$p));
426
- return _el$17;
427
- }
428
- }), null);
429
- _$insert(_el$14, _$createComponent(CompactStatusLine, {
430
- get api() {
431
- return props.api;
432
- },
433
- panel: compact,
434
- justifyContent: "center"
435
- }), null);
436
- return _el$14;
437
- }
438
- });
405
+ const visible = () => shouldRenderHomeBottom(resource.bottom());
406
+ return (() => {
407
+ var _el$14 = _$createElement("box");
408
+ _$setProp(_el$14, "gap", 0);
409
+ _$insert(_el$14, _$createComponent(Show, {
410
+ get when() {
411
+ return visible();
412
+ },
413
+ get children() {
414
+ var _el$15 = _$createElement("text");
415
+ _$insertNode(_el$15, _$createTextNode(` `));
416
+ return _el$15;
417
+ }
418
+ }), null);
419
+ _$insert(_el$14, _$createComponent(Show, {
420
+ get when() {
421
+ return _$memo(() => !!visible())() && announcement();
422
+ },
423
+ get children() {
424
+ var _el$17 = _$createElement("box"),
425
+ _el$18 = _$createElement("text");
426
+ _$insertNode(_el$17, _el$18);
427
+ _$setProp(_el$17, "flexDirection", "row");
428
+ _$setProp(_el$17, "justifyContent", "center");
429
+ _$setProp(_el$18, "wrapMode", "none");
430
+ _$insert(_el$18, announcement);
431
+ _$effect(_$p => _$setProp(_el$18, "fg", props.api.theme.current.textMuted, _$p));
432
+ return _el$17;
433
+ }
434
+ }), null);
435
+ _$insert(_el$14, _$createComponent(Show, {
436
+ get when() {
437
+ return visible();
438
+ },
439
+ get children() {
440
+ return _$createComponent(CompactStatusLine, {
441
+ get api() {
442
+ return props.api;
443
+ },
444
+ panel: compact,
445
+ justifyContent: "center"
446
+ });
447
+ }
448
+ }), null);
449
+ return _el$14;
450
+ })();
439
451
  }
440
452
  function getActiveTuiSessionID(api) {
441
- const route = api.route?.current;
442
- if (route?.name !== "session" && route?.type !== "session") return undefined;
443
- return normalizeTuiSessionID(route.params?.sessionID ?? route.params?.session_id ?? route.params?.id ?? route.sessionID);
453
+ if (api.route.current.name !== "session") return undefined;
454
+ return normalizeTuiSessionID(api.route.current.params?.sessionID);
444
455
  }
445
456
  function getTuiCommandArguments(input) {
446
457
  if (!input || typeof input !== "object") return undefined;
@@ -460,6 +471,9 @@ function CommandLoadingDialog(props) {
460
471
  _$insertNode(_el$19, _el$20);
461
472
  _$insertNode(_el$19, _el$22);
462
473
  _$setProp(_el$19, "gap", 1);
474
+ _$setProp(_el$19, "paddingLeft", 2);
475
+ _$setProp(_el$19, "paddingRight", 2);
476
+ _$setProp(_el$19, "paddingBottom", 1);
463
477
  _$insertNode(_el$20, _el$21);
464
478
  _$insert(_el$21, () => props.title);
465
479
  _$insertNode(_el$22, _$createTextNode(`Loading deterministic local output…`));
@@ -543,6 +557,9 @@ function CommandErrorDialog(props) {
543
557
  _$insertNode(_el$32, _el$37);
544
558
  _$insertNode(_el$32, _el$38);
545
559
  _$setProp(_el$32, "gap", 1);
560
+ _$setProp(_el$32, "paddingLeft", 2);
561
+ _$setProp(_el$32, "paddingRight", 2);
562
+ _$setProp(_el$32, "paddingBottom", 1);
546
563
  _$insertNode(_el$33, _el$34);
547
564
  _$insert(_el$34, () => props.title);
548
565
  _$insertNode(_el$35, _$createTextNode(`OpenCode Quota command failed.`));
@@ -568,81 +585,80 @@ function CommandErrorDialog(props) {
568
585
  return _el$32;
569
586
  })();
570
587
  }
571
- function TokensBetweenPromptDialog(props) {
572
- const DialogPrompt = props.api.ui?.DialogPrompt;
573
- if (DialogPrompt) {
574
- return _$createComponent(DialogPrompt, {
575
- title: "OpenCode Quota Token Range",
576
- placeholder: "YYYY-MM-DD YYYY-MM-DD",
577
- description: () => (() => {
578
- var _el$40 = _$createElement("text");
579
- _$insertNode(_el$40, _$createTextNode(`Enter start and end dates, for example: 2026-01-01 2026-01-15`));
580
- _$setProp(_el$40, "wrapMode", "none");
581
- _$effect(_$p => _$setProp(_el$40, "fg", props.api.theme.current.textMuted, _$p));
582
- return _el$40;
583
- })(),
584
- get onConfirm() {
585
- return props.onConfirm;
586
- },
587
- get onCancel() {
588
- return props.onCancel;
589
- }
590
- });
588
+ function getCommandPromptCopy(spec) {
589
+ switch (spec.id) {
590
+ case "tokens_between":
591
+ return {
592
+ title: "OpenCode Quota Token Range",
593
+ placeholder: "YYYY-MM-DD YYYY-MM-DD",
594
+ description: "Enter start and end dates, for example: 2026-01-01 2026-01-15"
595
+ };
596
+ case "quota_status":
597
+ return {
598
+ title: "OpenCode Quota Status Options",
599
+ placeholder: 'Optional JSON, e.g. {"refreshGoogleTokens":true}',
600
+ description: "Leave blank for normal diagnostics, or enter one JSON options object."
601
+ };
602
+ default:
603
+ return {
604
+ title: spec.title,
605
+ placeholder: "Optional arguments",
606
+ description: "Leave blank to run with no arguments."
607
+ };
591
608
  }
592
- return _$createComponent(CommandOutputDialog, {
593
- get api() {
594
- return props.api;
595
- },
596
- title: "OpenCode Quota Token Range",
597
- output: "Missing arguments for /tokens_between\n\nExpected: /tokens_between YYYY-MM-DD YYYY-MM-DD\nExample: /tokens_between 2026-01-01 2026-01-15"
598
- });
599
609
  }
600
610
  function replaceDialog(api, size, render) {
601
- const dialog = api.ui?.dialog;
602
- dialog?.replace?.(render);
603
- // OpenCode's dialog.replace() resets size to medium; xlarge is the widest supported dialog.
604
- dialog?.setSize?.(size);
611
+ api.ui.dialog.replace(render);
612
+ // OpenCode dialog.replace() resets size to medium.
613
+ api.ui.dialog.setSize(size);
605
614
  }
606
- function clearDialog(api) {
607
- api.ui?.dialog?.clear?.();
608
- }
609
- async function runQuotaDialogCommandAsync(api, command, rawInput, state) {
615
+ async function runQuotaDialogCommandAsync(api, command, commandDisplay, rawInput, state) {
610
616
  const spec = QUOTA_DIALOG_COMMANDS.find(item => item.id === command);
611
- const args = getTuiCommandArguments(rawInput);
617
+ const argumentsText = getTuiCommandArguments(rawInput);
612
618
  const sessionID = getActiveTuiSessionID(api);
613
- if (command === "tokens_between" && !args) {
614
- replaceDialog(api, "medium", () => _$createComponent(TokensBetweenPromptDialog, {
615
- api: api,
616
- onCancel: () => clearDialog(api),
619
+ if (spec.acceptsArguments && rawInput === undefined) {
620
+ const prompt = getCommandPromptCopy(spec);
621
+ replaceDialog(api, "medium", () => _$createComponent(api.ui.DialogPrompt, {
622
+ get title() {
623
+ return prompt.title;
624
+ },
625
+ get placeholder() {
626
+ return prompt.placeholder;
627
+ },
628
+ description: () => (() => {
629
+ var _el$40 = _$createElement("text");
630
+ _$setProp(_el$40, "wrapMode", "word");
631
+ _$insert(_el$40, () => prompt.description);
632
+ _$effect(_$p => _$setProp(_el$40, "fg", api.theme.current.textMuted, _$p));
633
+ return _el$40;
634
+ })(),
635
+ onCancel: () => api.ui.dialog.clear(),
617
636
  onConfirm: value => {
618
- const nextArgs = value.trim();
619
- if (!nextArgs) {
620
- replaceDialog(api, "large", () => _$createComponent(CommandOutputDialog, {
621
- api: api,
622
- get title() {
623
- return spec.title;
624
- },
625
- output: "Missing arguments for /tokens_between\n\nExpected: /tokens_between YYYY-MM-DD YYYY-MM-DD\nExample: /tokens_between 2026-01-01 2026-01-15"
626
- }));
627
- return;
628
- }
629
- runQuotaDialogCommand(api, command, {
630
- arguments: nextArgs
637
+ void runQuotaDialogCommandAsync(api, command, commandDisplay, {
638
+ arguments: value.trim()
631
639
  }, state);
632
640
  }
633
641
  }));
634
642
  return;
635
643
  }
636
- replaceDialog(api, spec.dialogSize, () => _$createComponent(CommandLoadingDialog, {
637
- api: api,
638
- get title() {
639
- return spec.title;
640
- }
641
- }));
644
+ const destination = commandDisplay === "inline" && sessionID ? {
645
+ type: "inline",
646
+ sessionID
647
+ } : {
648
+ type: "dialog"
649
+ };
650
+ if (destination.type === "dialog") {
651
+ replaceDialog(api, spec.dialogSize, () => _$createComponent(CommandLoadingDialog, {
652
+ api: api,
653
+ get title() {
654
+ return spec.title;
655
+ }
656
+ }));
657
+ }
642
658
  try {
643
659
  const result = await buildQuotaDialogCommandOutput({
644
660
  command,
645
- arguments: args,
661
+ arguments: argumentsText,
646
662
  client: createTuiQuotaClient(api),
647
663
  roots: getTuiRuntimeRootHints(api),
648
664
  sessionID,
@@ -652,7 +668,7 @@ async function runQuotaDialogCommandAsync(api, command, rawInput, state) {
652
668
  state.lastSessionTokenError = error;
653
669
  } : undefined,
654
670
  log: async (message, extra) => {
655
- await api.client?.app?.log?.({
671
+ await api.client.app.log({
656
672
  body: {
657
673
  service: "quota-toast",
658
674
  level: "debug",
@@ -663,7 +679,19 @@ async function runQuotaDialogCommandAsync(api, command, rawInput, state) {
663
679
  }
664
680
  });
665
681
  if (result.state === "noop") {
666
- clearDialog(api);
682
+ if (destination.type === "dialog") api.ui.dialog.clear();
683
+ return;
684
+ }
685
+ if (destination.type === "inline") {
686
+ await api.client.session.prompt({
687
+ sessionID: destination.sessionID,
688
+ noReply: true,
689
+ parts: [{
690
+ type: "text",
691
+ text: result.output,
692
+ ignored: true
693
+ }]
694
+ });
667
695
  return;
668
696
  }
669
697
  replaceDialog(api, result.dialogSize, () => _$createComponent(CommandOutputDialog, {
@@ -683,20 +711,15 @@ async function runQuotaDialogCommandAsync(api, command, rawInput, state) {
683
711
  },
684
712
  error: error
685
713
  }));
686
- api.ui?.toast?.({
714
+ api.ui.toast({
687
715
  variant: "error",
688
716
  message: "OpenCode Quota command failed"
689
717
  });
690
718
  }
691
719
  }
692
- function runQuotaDialogCommand(api, command, rawInput, state) {
693
- void runQuotaDialogCommandAsync(api, command, rawInput, state);
694
- }
695
- function registerQuotaDialogCommands(api) {
696
- const keymap = api.keymap;
697
- if (!keymap?.registerLayer) return;
720
+ function registerQuotaDialogCommands(api, commandDisplay) {
698
721
  const commandState = {};
699
- const dispose = keymap.registerLayer({
722
+ const dispose = api.keymap.registerLayer({
700
723
  commands: QUOTA_DIALOG_COMMANDS.map(spec => ({
701
724
  namespace: "palette",
702
725
  name: `opencode-quota.${spec.id}`,
@@ -705,13 +728,12 @@ function registerQuotaDialogCommands(api) {
705
728
  category: "OpenCode Quota",
706
729
  slashName: spec.slashName,
707
730
  run(input) {
708
- runQuotaDialogCommand(api, spec.id, input, commandState);
731
+ void runQuotaDialogCommandAsync(api, spec.id, commandDisplay, input, commandState);
709
732
  }
710
- }))
733
+ })),
734
+ bindings: []
711
735
  });
712
- if (typeof dispose === "function") {
713
- api.lifecycle.onDispose(dispose);
714
- }
736
+ api.lifecycle.onDispose(dispose);
715
737
  }
716
738
  function registerSidebarSlots(api) {
717
739
  api.slots.register({
@@ -729,14 +751,15 @@ function registerSidebarSlots(api) {
729
751
  });
730
752
  }
731
753
  const tui = async api => {
732
- registerQuotaDialogCommands(api);
733
754
  let surfaceRegistration;
734
755
  try {
735
756
  surfaceRegistration = await resolveTuiSurfaceRegistration(api);
736
757
  } catch {
758
+ registerQuotaDialogCommands(api, "inline");
737
759
  registerSidebarSlots(api);
738
760
  return;
739
761
  }
762
+ registerQuotaDialogCommands(api, surfaceRegistration.commandDisplay);
740
763
  if (surfaceRegistration.sidebar.enabled) {
741
764
  registerSidebarSlots(api);
742
765
  }
@@ -765,7 +788,10 @@ const tui = async api => {
765
788
  }
766
789
  if (surfaceRegistration.homeBottom) {
767
790
  compactSlots.home_bottom = () => _$createComponent(HomeBottomView, {
768
- api: api
791
+ api: api,
792
+ get compactHomeBottomEnabled() {
793
+ return surfaceRegistration.compact.homeBottom;
794
+ }
769
795
  });
770
796
  }
771
797
  if (Object.keys(compactSlots).length > 0) {