@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.
- package/README.md +103 -57
- package/dist/bin/opencode-quota.d.ts.map +1 -1
- package/dist/bin/opencode-quota.js +24 -7
- package/dist/bin/opencode-quota.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/anthropic.d.ts.map +1 -1
- package/dist/lib/anthropic.js +106 -3
- package/dist/lib/anthropic.js.map +1 -1
- package/dist/lib/atomic-json.d.ts +1 -0
- package/dist/lib/atomic-json.d.ts.map +1 -1
- package/dist/lib/atomic-json.js +5 -2
- package/dist/lib/atomic-json.js.map +1 -1
- package/dist/lib/cli-show.d.ts.map +1 -1
- package/dist/lib/cli-show.js +11 -7
- package/dist/lib/cli-show.js.map +1 -1
- package/dist/lib/command-surfaces.d.ts +10 -0
- package/dist/lib/command-surfaces.d.ts.map +1 -0
- package/dist/lib/command-surfaces.js +9 -0
- package/dist/lib/command-surfaces.js.map +1 -0
- package/dist/lib/config-file-utils.d.ts +5 -0
- package/dist/lib/config-file-utils.d.ts.map +1 -1
- package/dist/lib/config-file-utils.js +20 -3
- package/dist/lib/config-file-utils.js.map +1 -1
- package/dist/lib/config.d.ts +5 -3
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +124 -32
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/copilot.d.ts +19 -12
- package/dist/lib/copilot.d.ts.map +1 -1
- package/dist/lib/copilot.js +462 -566
- package/dist/lib/copilot.js.map +1 -1
- package/dist/lib/display-sanitize.d.ts.map +1 -1
- package/dist/lib/display-sanitize.js +13 -0
- package/dist/lib/display-sanitize.js.map +1 -1
- package/dist/lib/entries.d.ts +53 -4
- package/dist/lib/entries.d.ts.map +1 -1
- package/dist/lib/entries.js.map +1 -1
- package/dist/lib/init-installer.d.ts +11 -1
- package/dist/lib/init-installer.d.ts.map +1 -1
- package/dist/lib/init-installer.js +542 -154
- package/dist/lib/init-installer.js.map +1 -1
- package/dist/lib/openai.d.ts +9 -12
- package/dist/lib/openai.d.ts.map +1 -1
- package/dist/lib/openai.js +69 -40
- package/dist/lib/openai.js.map +1 -1
- package/dist/lib/opencode-config-editor.d.ts +53 -0
- package/dist/lib/opencode-config-editor.d.ts.map +1 -0
- package/dist/lib/opencode-config-editor.js +274 -0
- package/dist/lib/opencode-config-editor.js.map +1 -0
- package/dist/lib/opencode-config-providers.d.ts +18 -0
- package/dist/lib/opencode-config-providers.d.ts.map +1 -1
- package/dist/lib/opencode-config-providers.js +75 -4
- package/dist/lib/opencode-config-providers.js.map +1 -1
- package/dist/lib/opencode-runtime-paths.d.ts.map +1 -1
- package/dist/lib/opencode-runtime-paths.js +10 -3
- package/dist/lib/opencode-runtime-paths.js.map +1 -1
- package/dist/lib/opencode-storage.d.ts +10 -0
- package/dist/lib/opencode-storage.d.ts.map +1 -1
- package/dist/lib/opencode-storage.js +75 -0
- package/dist/lib/opencode-storage.js.map +1 -1
- package/dist/lib/provider-add-command.d.ts +35 -0
- package/dist/lib/provider-add-command.d.ts.map +1 -0
- package/dist/lib/provider-add-command.js +185 -0
- package/dist/lib/provider-add-command.js.map +1 -0
- package/dist/lib/provider-add.d.ts +21 -0
- package/dist/lib/provider-add.d.ts.map +1 -0
- package/dist/lib/provider-add.js +210 -0
- package/dist/lib/provider-add.js.map +1 -0
- package/dist/lib/provider-metadata.d.ts +1 -1
- package/dist/lib/provider-metadata.d.ts.map +1 -1
- package/dist/lib/provider-metadata.js +11 -5
- package/dist/lib/provider-metadata.js.map +1 -1
- package/dist/lib/quota-command-format.d.ts +2 -0
- package/dist/lib/quota-command-format.d.ts.map +1 -1
- package/dist/lib/quota-command-format.js +94 -26
- package/dist/lib/quota-command-format.js.map +1 -1
- package/dist/lib/quota-dialog-commands.d.ts.map +1 -1
- package/dist/lib/quota-dialog-commands.js +8 -4
- package/dist/lib/quota-dialog-commands.js.map +1 -1
- package/dist/lib/quota-export-types.d.ts +48 -27
- package/dist/lib/quota-export-types.d.ts.map +1 -1
- package/dist/lib/quota-export-types.js +0 -7
- package/dist/lib/quota-export-types.js.map +1 -1
- package/dist/lib/quota-export.d.ts.map +1 -1
- package/dist/lib/quota-export.js +63 -16
- package/dist/lib/quota-export.js.map +1 -1
- package/dist/lib/quota-providers-local.d.ts +55 -0
- package/dist/lib/quota-providers-local.d.ts.map +1 -0
- package/dist/lib/quota-providers-local.js +313 -0
- package/dist/lib/quota-providers-local.js.map +1 -0
- package/dist/lib/quota-providers-remote.d.ts +23 -0
- package/dist/lib/quota-providers-remote.d.ts.map +1 -0
- package/dist/lib/quota-providers-remote.js +318 -0
- package/dist/lib/quota-providers-remote.js.map +1 -0
- package/dist/lib/quota-providers.d.ts +77 -0
- package/dist/lib/quota-providers.d.ts.map +1 -0
- package/dist/lib/quota-providers.js +630 -0
- package/dist/lib/quota-providers.js.map +1 -0
- package/dist/lib/quota-render-data.d.ts +1 -0
- package/dist/lib/quota-render-data.d.ts.map +1 -1
- package/dist/lib/quota-render-data.js +35 -16
- package/dist/lib/quota-render-data.js.map +1 -1
- package/dist/lib/quota-runtime-context.d.ts.map +1 -1
- package/dist/lib/quota-runtime-context.js +3 -4
- package/dist/lib/quota-runtime-context.js.map +1 -1
- package/dist/lib/quota-state.d.ts +5 -2
- package/dist/lib/quota-state.d.ts.map +1 -1
- package/dist/lib/quota-state.js +268 -51
- package/dist/lib/quota-state.js.map +1 -1
- package/dist/lib/quota-status.d.ts +2 -1
- package/dist/lib/quota-status.d.ts.map +1 -1
- package/dist/lib/quota-status.js +247 -69
- package/dist/lib/quota-status.js.map +1 -1
- package/dist/lib/qwen-local-quota.d.ts +12 -11
- package/dist/lib/qwen-local-quota.d.ts.map +1 -1
- package/dist/lib/qwen-local-quota.js +82 -87
- package/dist/lib/qwen-local-quota.js.map +1 -1
- package/dist/lib/scoped-update.d.ts +63 -0
- package/dist/lib/scoped-update.d.ts.map +1 -0
- package/dist/lib/scoped-update.js +311 -0
- package/dist/lib/scoped-update.js.map +1 -0
- package/dist/lib/tui-runtime.d.ts +2 -0
- package/dist/lib/tui-runtime.d.ts.map +1 -1
- package/dist/lib/tui-runtime.js +33 -9
- package/dist/lib/tui-runtime.js.map +1 -1
- package/dist/lib/types.d.ts +51 -15
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +2 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +75 -100
- package/dist/plugin.js.map +1 -1
- package/dist/providers/alibaba-coding-plan.d.ts.map +1 -1
- package/dist/providers/alibaba-coding-plan.js +35 -4
- package/dist/providers/alibaba-coding-plan.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +13 -1
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/chutes.d.ts.map +1 -1
- package/dist/providers/chutes.js +6 -0
- package/dist/providers/chutes.js.map +1 -1
- package/dist/providers/copilot.d.ts +2 -1
- package/dist/providers/copilot.d.ts.map +1 -1
- package/dist/providers/copilot.js +143 -60
- package/dist/providers/copilot.js.map +1 -1
- package/dist/providers/cursor.d.ts.map +1 -1
- package/dist/providers/cursor.js +30 -1
- package/dist/providers/cursor.js.map +1 -1
- package/dist/providers/deepseek.d.ts.map +1 -1
- package/dist/providers/deepseek.js +13 -1
- package/dist/providers/deepseek.js.map +1 -1
- package/dist/providers/google-agy.d.ts.map +1 -1
- package/dist/providers/google-agy.js +7 -1
- package/dist/providers/google-agy.js.map +1 -1
- package/dist/providers/google-antigravity.d.ts.map +1 -1
- package/dist/providers/google-antigravity.js +10 -2
- package/dist/providers/google-antigravity.js.map +1 -1
- package/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/dist/providers/google-gemini-cli.js +8 -2
- package/dist/providers/google-gemini-cli.js.map +1 -1
- package/dist/providers/kimi-code.d.ts.map +1 -1
- package/dist/providers/kimi-code.js +6 -0
- package/dist/providers/kimi-code.js.map +1 -1
- package/dist/providers/minimax-coding-plan.d.ts.map +1 -1
- package/dist/providers/minimax-coding-plan.js +12 -4
- package/dist/providers/minimax-coding-plan.js.map +1 -1
- package/dist/providers/nanogpt.d.ts.map +1 -1
- package/dist/providers/nanogpt.js +19 -1
- package/dist/providers/nanogpt.js.map +1 -1
- package/dist/providers/ollama-cloud.d.ts.map +1 -1
- package/dist/providers/ollama-cloud.js +12 -0
- package/dist/providers/ollama-cloud.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +7 -0
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/opencode-go.d.ts.map +1 -1
- package/dist/providers/opencode-go.js +9 -1
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/providers/quota-providers.d.ts +6 -0
- package/dist/providers/quota-providers.d.ts.map +1 -0
- package/dist/providers/quota-providers.js +276 -0
- package/dist/providers/quota-providers.js.map +1 -0
- package/dist/providers/qwen-code.d.ts.map +1 -1
- package/dist/providers/qwen-code.js +29 -3
- package/dist/providers/qwen-code.js.map +1 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +2 -0
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/result-helpers.d.ts +2 -1
- package/dist/providers/result-helpers.d.ts.map +1 -1
- package/dist/providers/result-helpers.js +6 -1
- package/dist/providers/result-helpers.js.map +1 -1
- package/dist/providers/synthetic.d.ts.map +1 -1
- package/dist/providers/synthetic.js +7 -1
- package/dist/providers/synthetic.js.map +1 -1
- package/dist/providers/zai.d.ts.map +1 -1
- package/dist/providers/zai.js +7 -1
- package/dist/providers/zai.js.map +1 -1
- package/dist/providers/zhipu.d.ts.map +1 -1
- package/dist/providers/zhipu.js +7 -1
- package/dist/providers/zhipu.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +148 -122
- package/dist/tui.tsx +122 -114
- package/package.json +29 -21
package/dist/tui.tsx
CHANGED
|
@@ -9,7 +9,12 @@ import type {
|
|
|
9
9
|
import { Show, createEffect, createSignal, onCleanup } from "solid-js";
|
|
10
10
|
|
|
11
11
|
import type { SessionTokenError } from "./lib/quota-status.js";
|
|
12
|
-
import type {
|
|
12
|
+
import type { TuiCommandDisplay } from "./lib/types.js";
|
|
13
|
+
import type {
|
|
14
|
+
CompactStatusState,
|
|
15
|
+
HomeBottomState,
|
|
16
|
+
SidebarPanelState,
|
|
17
|
+
} from "./lib/tui-panel-state.js";
|
|
13
18
|
|
|
14
19
|
import {
|
|
15
20
|
getCompactStatusText,
|
|
@@ -26,8 +31,8 @@ import {
|
|
|
26
31
|
getTuiRuntimeRootHints,
|
|
27
32
|
getTuiSessionModelMeta,
|
|
28
33
|
loadTuiHomeBottomStatus,
|
|
29
|
-
normalizeTuiSessionID,
|
|
30
34
|
loadTuiSessionQuotaSurfaces,
|
|
35
|
+
normalizeTuiSessionID,
|
|
31
36
|
resolveTuiSurfaceRegistration,
|
|
32
37
|
writeTuiQuotaExportIfEnabled,
|
|
33
38
|
} from "./lib/tui-runtime.js";
|
|
@@ -35,6 +40,7 @@ import {
|
|
|
35
40
|
QUOTA_DIALOG_COMMANDS,
|
|
36
41
|
buildQuotaDialogCommandOutput,
|
|
37
42
|
type QuotaDialogCommandId,
|
|
43
|
+
type QuotaDialogCommandSpec,
|
|
38
44
|
} from "./lib/quota-dialog-commands.js";
|
|
39
45
|
|
|
40
46
|
const id = "@slkiser/opencode-quota";
|
|
@@ -52,7 +58,6 @@ type DialogSize = "medium" | "large" | "xlarge";
|
|
|
52
58
|
type QuotaDialogCommandState = {
|
|
53
59
|
lastSessionTokenError?: SessionTokenError;
|
|
54
60
|
};
|
|
55
|
-
|
|
56
61
|
type SessionQuotaResource = {
|
|
57
62
|
sessionID: string;
|
|
58
63
|
sidebar: () => SidebarPanelState;
|
|
@@ -209,10 +214,13 @@ function acquireSessionQuotaResource(api: TuiPluginApi, sessionID: string): Sess
|
|
|
209
214
|
return next;
|
|
210
215
|
}
|
|
211
216
|
|
|
212
|
-
function createHomeBottomResource(
|
|
217
|
+
function createHomeBottomResource(
|
|
218
|
+
api: TuiPluginApi,
|
|
219
|
+
compactHomeBottomEnabled: boolean,
|
|
220
|
+
): HomeBottomResource {
|
|
213
221
|
const [bottom, setBottom] = createSignal<HomeBottomState>({
|
|
214
222
|
status: "loading",
|
|
215
|
-
compact: { status: "loading" },
|
|
223
|
+
compact: compactHomeBottomEnabled ? { status: "loading" } : { status: "disabled" },
|
|
216
224
|
});
|
|
217
225
|
|
|
218
226
|
let refCount = 0;
|
|
@@ -307,11 +315,14 @@ function createHomeBottomResource(api: TuiPluginApi): HomeBottomResource {
|
|
|
307
315
|
return resource;
|
|
308
316
|
}
|
|
309
317
|
|
|
310
|
-
function acquireHomeBottomResource(
|
|
318
|
+
function acquireHomeBottomResource(
|
|
319
|
+
api: TuiPluginApi,
|
|
320
|
+
compactHomeBottomEnabled: boolean,
|
|
321
|
+
): HomeBottomResource {
|
|
311
322
|
const existing = homeResources.get(api);
|
|
312
323
|
if (existing) return existing.retain();
|
|
313
324
|
|
|
314
|
-
const next = createHomeBottomResource(api).retain();
|
|
325
|
+
const next = createHomeBottomResource(api, compactHomeBottomEnabled).retain();
|
|
315
326
|
homeResources.set(api, next);
|
|
316
327
|
return next;
|
|
317
328
|
}
|
|
@@ -447,37 +458,36 @@ function SessionPromptWithCompactStatus(props: {
|
|
|
447
458
|
);
|
|
448
459
|
}
|
|
449
460
|
|
|
450
|
-
function HomeBottomView(props: { api: TuiPluginApi }) {
|
|
451
|
-
const resource = acquireHomeBottomResource(props.api);
|
|
461
|
+
function HomeBottomView(props: { api: TuiPluginApi; compactHomeBottomEnabled: boolean }) {
|
|
462
|
+
const resource = acquireHomeBottomResource(props.api, props.compactHomeBottomEnabled);
|
|
452
463
|
onCleanup(() => resource.release());
|
|
453
464
|
|
|
454
465
|
const announcement = () => getHomeBottomAnnouncementText(resource.bottom());
|
|
455
466
|
const compact = () => resource.bottom().compact;
|
|
467
|
+
const visible = () => shouldRenderHomeBottom(resource.bottom());
|
|
456
468
|
|
|
457
469
|
return (
|
|
458
|
-
<
|
|
459
|
-
<
|
|
470
|
+
<box gap={0}>
|
|
471
|
+
<Show when={visible()}>
|
|
460
472
|
<text> </text>
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
</
|
|
467
|
-
</
|
|
473
|
+
</Show>
|
|
474
|
+
<Show when={visible() && announcement()}>
|
|
475
|
+
<box flexDirection="row" justifyContent="center">
|
|
476
|
+
<text fg={props.api.theme.current.textMuted} wrapMode="none">
|
|
477
|
+
{announcement()}
|
|
478
|
+
</text>
|
|
479
|
+
</box>
|
|
480
|
+
</Show>
|
|
481
|
+
<Show when={visible()}>
|
|
468
482
|
<CompactStatusLine api={props.api} panel={compact} justifyContent="center" />
|
|
469
|
-
</
|
|
470
|
-
</
|
|
483
|
+
</Show>
|
|
484
|
+
</box>
|
|
471
485
|
);
|
|
472
486
|
}
|
|
473
487
|
|
|
474
488
|
function getActiveTuiSessionID(api: TuiPluginApi): string | undefined {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
return normalizeTuiSessionID(
|
|
479
|
-
route.params?.sessionID ?? route.params?.session_id ?? route.params?.id ?? route.sessionID,
|
|
480
|
-
);
|
|
489
|
+
if (api.route.current.name !== "session") return undefined;
|
|
490
|
+
return normalizeTuiSessionID(api.route.current.params?.sessionID);
|
|
481
491
|
}
|
|
482
492
|
|
|
483
493
|
function getTuiCommandArguments(input: unknown): string | undefined {
|
|
@@ -492,7 +502,7 @@ function getTuiCommandArguments(input: unknown): string | undefined {
|
|
|
492
502
|
|
|
493
503
|
function CommandLoadingDialog(props: { api: TuiPluginApi; title: string }) {
|
|
494
504
|
return (
|
|
495
|
-
<box gap={1}>
|
|
505
|
+
<box gap={1} paddingLeft={2} paddingRight={2} paddingBottom={1}>
|
|
496
506
|
<text fg={props.api.theme.current.text}>
|
|
497
507
|
<b>{props.title}</b>
|
|
498
508
|
</text>
|
|
@@ -526,7 +536,7 @@ function CommandOutputDialog(props: { api: TuiPluginApi; title: string; output:
|
|
|
526
536
|
function CommandErrorDialog(props: { api: TuiPluginApi; title: string; error: unknown }) {
|
|
527
537
|
const message = props.error instanceof Error ? props.error.message : String(props.error);
|
|
528
538
|
return (
|
|
529
|
-
<box gap={1}>
|
|
539
|
+
<box gap={1} paddingLeft={2} paddingRight={2} paddingBottom={1}>
|
|
530
540
|
<text fg={props.api.theme.current.text}>
|
|
531
541
|
<b>{props.title}</b>
|
|
532
542
|
</text>
|
|
@@ -539,93 +549,90 @@ function CommandErrorDialog(props: { api: TuiPluginApi; title: string; error: un
|
|
|
539
549
|
);
|
|
540
550
|
}
|
|
541
551
|
|
|
542
|
-
function
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
552
|
+
function getCommandPromptCopy(spec: QuotaDialogCommandSpec): {
|
|
553
|
+
title: string;
|
|
554
|
+
placeholder: string;
|
|
555
|
+
description: string;
|
|
556
|
+
} {
|
|
557
|
+
switch (spec.id) {
|
|
558
|
+
case "tokens_between":
|
|
559
|
+
return {
|
|
560
|
+
title: "OpenCode Quota Token Range",
|
|
561
|
+
placeholder: "YYYY-MM-DD YYYY-MM-DD",
|
|
562
|
+
description: "Enter start and end dates, for example: 2026-01-01 2026-01-15",
|
|
563
|
+
};
|
|
564
|
+
case "quota_status":
|
|
565
|
+
return {
|
|
566
|
+
title: "OpenCode Quota Status Options",
|
|
567
|
+
placeholder: 'Optional JSON, e.g. {"refreshGoogleTokens":true}',
|
|
568
|
+
description: "Leave blank for normal diagnostics, or enter one JSON options object.",
|
|
569
|
+
};
|
|
570
|
+
default:
|
|
571
|
+
return {
|
|
572
|
+
title: spec.title,
|
|
573
|
+
placeholder: "Optional arguments",
|
|
574
|
+
description: "Leave blank to run with no arguments.",
|
|
575
|
+
};
|
|
562
576
|
}
|
|
563
|
-
|
|
564
|
-
return (
|
|
565
|
-
<CommandOutputDialog
|
|
566
|
-
api={props.api}
|
|
567
|
-
title="OpenCode Quota Token Range"
|
|
568
|
-
output={
|
|
569
|
-
"Missing arguments for /tokens_between\n\nExpected: /tokens_between YYYY-MM-DD YYYY-MM-DD\nExample: /tokens_between 2026-01-01 2026-01-15"
|
|
570
|
-
}
|
|
571
|
-
/>
|
|
572
|
-
);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
function replaceDialog(api: TuiPluginApi, size: DialogSize, render: () => JSX.Element) {
|
|
576
|
-
const dialog = (api as any).ui?.dialog;
|
|
577
|
-
dialog?.replace?.(render);
|
|
578
|
-
// OpenCode's dialog.replace() resets size to medium; xlarge is the widest supported dialog.
|
|
579
|
-
dialog?.setSize?.(size);
|
|
580
577
|
}
|
|
581
578
|
|
|
582
|
-
function
|
|
583
|
-
|
|
579
|
+
function replaceDialog(api: TuiPluginApi, size: DialogSize, render: () => JSX.Element): void {
|
|
580
|
+
api.ui.dialog.replace(render);
|
|
581
|
+
// OpenCode dialog.replace() resets size to medium.
|
|
582
|
+
api.ui.dialog.setSize(size);
|
|
584
583
|
}
|
|
585
584
|
|
|
586
585
|
async function runQuotaDialogCommandAsync(
|
|
587
586
|
api: TuiPluginApi,
|
|
588
587
|
command: QuotaDialogCommandId,
|
|
588
|
+
commandDisplay: TuiCommandDisplay,
|
|
589
589
|
rawInput?: unknown,
|
|
590
590
|
state?: QuotaDialogCommandState,
|
|
591
591
|
): Promise<void> {
|
|
592
592
|
const spec = QUOTA_DIALOG_COMMANDS.find((item) => item.id === command)!;
|
|
593
|
-
const
|
|
593
|
+
const argumentsText = getTuiCommandArguments(rawInput);
|
|
594
594
|
const sessionID = getActiveTuiSessionID(api);
|
|
595
595
|
|
|
596
|
-
if (
|
|
596
|
+
if (spec.acceptsArguments && rawInput === undefined) {
|
|
597
|
+
const prompt = getCommandPromptCopy(spec);
|
|
597
598
|
replaceDialog(api, "medium", () => (
|
|
598
|
-
<
|
|
599
|
-
|
|
600
|
-
|
|
599
|
+
<api.ui.DialogPrompt
|
|
600
|
+
title={prompt.title}
|
|
601
|
+
placeholder={prompt.placeholder}
|
|
602
|
+
description={() => (
|
|
603
|
+
<text fg={api.theme.current.textMuted} wrapMode="word">
|
|
604
|
+
{prompt.description}
|
|
605
|
+
</text>
|
|
606
|
+
)}
|
|
607
|
+
onCancel={() => api.ui.dialog.clear()}
|
|
601
608
|
onConfirm={(value) => {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
"Missing arguments for /tokens_between\n\nExpected: /tokens_between YYYY-MM-DD YYYY-MM-DD\nExample: /tokens_between 2026-01-01 2026-01-15"
|
|
610
|
-
}
|
|
611
|
-
/>
|
|
612
|
-
));
|
|
613
|
-
return;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
runQuotaDialogCommand(api, command, { arguments: nextArgs }, state);
|
|
609
|
+
void runQuotaDialogCommandAsync(
|
|
610
|
+
api,
|
|
611
|
+
command,
|
|
612
|
+
commandDisplay,
|
|
613
|
+
{ arguments: value.trim() },
|
|
614
|
+
state,
|
|
615
|
+
);
|
|
617
616
|
}}
|
|
618
617
|
/>
|
|
619
618
|
));
|
|
620
619
|
return;
|
|
621
620
|
}
|
|
622
621
|
|
|
623
|
-
|
|
622
|
+
const destination =
|
|
623
|
+
commandDisplay === "inline" && sessionID
|
|
624
|
+
? { type: "inline" as const, sessionID }
|
|
625
|
+
: { type: "dialog" as const };
|
|
626
|
+
if (destination.type === "dialog") {
|
|
627
|
+
replaceDialog(api, spec.dialogSize, () => (
|
|
628
|
+
<CommandLoadingDialog api={api} title={spec.title} />
|
|
629
|
+
));
|
|
630
|
+
}
|
|
624
631
|
|
|
625
632
|
try {
|
|
626
633
|
const result = await buildQuotaDialogCommandOutput({
|
|
627
634
|
command,
|
|
628
|
-
arguments:
|
|
635
|
+
arguments: argumentsText,
|
|
629
636
|
client: createTuiQuotaClient(api),
|
|
630
637
|
roots: getTuiRuntimeRootHints(api),
|
|
631
638
|
sessionID,
|
|
@@ -637,7 +644,7 @@ async function runQuotaDialogCommandAsync(
|
|
|
637
644
|
}
|
|
638
645
|
: undefined,
|
|
639
646
|
log: async (message, extra) => {
|
|
640
|
-
await
|
|
647
|
+
await api.client.app.log({
|
|
641
648
|
body: {
|
|
642
649
|
service: "quota-toast",
|
|
643
650
|
level: "debug",
|
|
@@ -649,7 +656,16 @@ async function runQuotaDialogCommandAsync(
|
|
|
649
656
|
});
|
|
650
657
|
|
|
651
658
|
if (result.state === "noop") {
|
|
652
|
-
|
|
659
|
+
if (destination.type === "dialog") api.ui.dialog.clear();
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
if (destination.type === "inline") {
|
|
664
|
+
await api.client.session.prompt({
|
|
665
|
+
sessionID: destination.sessionID,
|
|
666
|
+
noReply: true,
|
|
667
|
+
parts: [{ type: "text", text: result.output, ignored: true }],
|
|
668
|
+
});
|
|
653
669
|
return;
|
|
654
670
|
}
|
|
655
671
|
|
|
@@ -657,29 +673,19 @@ async function runQuotaDialogCommandAsync(
|
|
|
657
673
|
<CommandOutputDialog api={api} title={result.title} output={result.output} />
|
|
658
674
|
));
|
|
659
675
|
} catch (error) {
|
|
660
|
-
replaceDialog(api, "large", () =>
|
|
661
|
-
|
|
676
|
+
replaceDialog(api, "large", () => (
|
|
677
|
+
<CommandErrorDialog api={api} title={spec.title} error={error} />
|
|
678
|
+
));
|
|
679
|
+
api.ui.toast({
|
|
662
680
|
variant: "error",
|
|
663
681
|
message: "OpenCode Quota command failed",
|
|
664
682
|
});
|
|
665
683
|
}
|
|
666
684
|
}
|
|
667
685
|
|
|
668
|
-
function
|
|
669
|
-
api: TuiPluginApi,
|
|
670
|
-
command: QuotaDialogCommandId,
|
|
671
|
-
rawInput?: unknown,
|
|
672
|
-
state?: QuotaDialogCommandState,
|
|
673
|
-
): void {
|
|
674
|
-
void runQuotaDialogCommandAsync(api, command, rawInput, state);
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
function registerQuotaDialogCommands(api: TuiPluginApi): void {
|
|
678
|
-
const keymap = (api as any).keymap;
|
|
679
|
-
if (!keymap?.registerLayer) return;
|
|
680
|
-
|
|
686
|
+
function registerQuotaDialogCommands(api: TuiPluginApi, commandDisplay: TuiCommandDisplay): void {
|
|
681
687
|
const commandState: QuotaDialogCommandState = {};
|
|
682
|
-
const dispose = keymap.registerLayer({
|
|
688
|
+
const dispose = api.keymap.registerLayer({
|
|
683
689
|
commands: QUOTA_DIALOG_COMMANDS.map((spec) => ({
|
|
684
690
|
namespace: "palette",
|
|
685
691
|
name: `opencode-quota.${spec.id}`,
|
|
@@ -688,14 +694,13 @@ function registerQuotaDialogCommands(api: TuiPluginApi): void {
|
|
|
688
694
|
category: "OpenCode Quota",
|
|
689
695
|
slashName: spec.slashName,
|
|
690
696
|
run(input?: unknown) {
|
|
691
|
-
|
|
697
|
+
void runQuotaDialogCommandAsync(api, spec.id, commandDisplay, input, commandState);
|
|
692
698
|
},
|
|
693
699
|
})),
|
|
700
|
+
bindings: [],
|
|
694
701
|
});
|
|
695
702
|
|
|
696
|
-
|
|
697
|
-
api.lifecycle.onDispose(dispose);
|
|
698
|
-
}
|
|
703
|
+
api.lifecycle.onDispose(dispose);
|
|
699
704
|
}
|
|
700
705
|
|
|
701
706
|
function registerSidebarSlots(api: TuiPluginApi): void {
|
|
@@ -710,16 +715,17 @@ function registerSidebarSlots(api: TuiPluginApi): void {
|
|
|
710
715
|
}
|
|
711
716
|
|
|
712
717
|
const tui: TuiPlugin = async (api) => {
|
|
713
|
-
registerQuotaDialogCommands(api);
|
|
714
|
-
|
|
715
718
|
let surfaceRegistration;
|
|
716
719
|
try {
|
|
717
720
|
surfaceRegistration = await resolveTuiSurfaceRegistration(api);
|
|
718
721
|
} catch {
|
|
722
|
+
registerQuotaDialogCommands(api, "inline");
|
|
719
723
|
registerSidebarSlots(api);
|
|
720
724
|
return;
|
|
721
725
|
}
|
|
722
726
|
|
|
727
|
+
registerQuotaDialogCommands(api, surfaceRegistration.commandDisplay);
|
|
728
|
+
|
|
723
729
|
if (surfaceRegistration.sidebar.enabled) {
|
|
724
730
|
registerSidebarSlots(api);
|
|
725
731
|
}
|
|
@@ -752,7 +758,9 @@ const tui: TuiPlugin = async (api) => {
|
|
|
752
758
|
}
|
|
753
759
|
|
|
754
760
|
if (surfaceRegistration.homeBottom) {
|
|
755
|
-
compactSlots.home_bottom = () =>
|
|
761
|
+
compactSlots.home_bottom = () => (
|
|
762
|
+
<HomeBottomView api={api} compactHomeBottomEnabled={surfaceRegistration.compact.homeBottom} />
|
|
763
|
+
);
|
|
756
764
|
}
|
|
757
765
|
|
|
758
766
|
if (Object.keys(compactSlots).length > 0) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slkiser/opencode-quota",
|
|
3
|
-
"version": "
|
|
4
|
-
"packageManager": "pnpm@11.0.0",
|
|
3
|
+
"version": "4.0.0",
|
|
5
4
|
"description": "OpenCode quota & tokens usage with zero context window pollution. Supports GitHub Copilot, OpenAI (Plus/Pro), Qwen Code, Chutes AI, Synthetic, Google Antigravity, Z.ai coding plan and more.",
|
|
6
5
|
"type": "module",
|
|
7
6
|
"main": "./dist/index.js",
|
|
@@ -32,21 +31,6 @@
|
|
|
32
31
|
"README.md",
|
|
33
32
|
"LICENSE"
|
|
34
33
|
],
|
|
35
|
-
"scripts": {
|
|
36
|
-
"build": "node scripts/clean-dist.mjs && tsc && node scripts/copy-data.mjs && node scripts/prepare-tui-dist.mjs",
|
|
37
|
-
"build:check": "pnpm run build && pnpm pack --dry-run",
|
|
38
|
-
"pricing:refresh": "node scripts/refresh-modelsdev-pricing.mjs",
|
|
39
|
-
"pricing:refresh:if-stale": "node scripts/refresh-modelsdev-pricing-if-stale.mjs",
|
|
40
|
-
"upstream:check": "node scripts/check-upstream-plugin-updates.mjs",
|
|
41
|
-
"upstream:prepare-review": "node scripts/prepare-upstream-plugin-review.mjs",
|
|
42
|
-
"upstream:sync": "node scripts/sync-upstream-plugin-references.mjs",
|
|
43
|
-
"verify:release-version": "node scripts/verify-release-version.mjs",
|
|
44
|
-
"typecheck": "tsc --noEmit",
|
|
45
|
-
"test": "vitest run",
|
|
46
|
-
"test:watch": "vitest",
|
|
47
|
-
"prepublishOnly": "pnpm run build",
|
|
48
|
-
"prepare": "husky"
|
|
49
|
-
},
|
|
50
34
|
"keywords": [
|
|
51
35
|
"opencode",
|
|
52
36
|
"plugin",
|
|
@@ -72,20 +56,22 @@
|
|
|
72
56
|
"devDependencies": {
|
|
73
57
|
"@babel/core": "^7.28.0",
|
|
74
58
|
"@babel/preset-typescript": "^7.27.1",
|
|
75
|
-
"@opencode-ai/plugin": "
|
|
59
|
+
"@opencode-ai/plugin": "1.18.1",
|
|
76
60
|
"@types/node": "^22.0.0",
|
|
77
61
|
"babel-preset-solid": "^1.9.12",
|
|
78
62
|
"husky": "^9.1.7",
|
|
79
63
|
"lint-staged": "^16.2.7",
|
|
80
64
|
"prettier": "^3.8.0",
|
|
81
65
|
"typescript": "^5.9.3",
|
|
82
|
-
"vitest": "^4.0.17"
|
|
66
|
+
"vitest": "^4.0.17",
|
|
67
|
+
"yaml": "^2.8.3"
|
|
83
68
|
},
|
|
84
69
|
"dependencies": {
|
|
85
70
|
"@clack/prompts": "^1.2.0",
|
|
86
71
|
"@opentui/core": "^0.4.3",
|
|
87
72
|
"@opentui/solid": "^0.4.3",
|
|
88
73
|
"comment-json": "^5.0.0",
|
|
74
|
+
"jsonc-parser": "^3.3.1",
|
|
89
75
|
"solid-js": "^1.9.12",
|
|
90
76
|
"xdg-basedir": "^5.1.0"
|
|
91
77
|
},
|
|
@@ -96,6 +82,28 @@
|
|
|
96
82
|
"@opencode-ai/plugin": "^1.4.3"
|
|
97
83
|
},
|
|
98
84
|
"engines": {
|
|
99
|
-
"node": ">=
|
|
85
|
+
"node": ">=22.0.0"
|
|
86
|
+
},
|
|
87
|
+
"scripts": {
|
|
88
|
+
"build": "node scripts/clean-dist.mjs && tsc && node scripts/copy-data.mjs && node scripts/prepare-tui-dist.mjs",
|
|
89
|
+
"build:check": "pnpm run build && pnpm pack --dry-run",
|
|
90
|
+
"pack:release-package": "node scripts/pack-release-package.mjs",
|
|
91
|
+
"format:check": "node scripts/verify-v4-formatting.mjs",
|
|
92
|
+
"pricing:refresh": "node scripts/refresh-modelsdev-pricing.mjs",
|
|
93
|
+
"pricing:refresh:if-stale": "node scripts/refresh-modelsdev-pricing-if-stale.mjs",
|
|
94
|
+
"upstream:check": "node scripts/check-upstream-plugin-updates.mjs",
|
|
95
|
+
"upstream:prepare-review": "node scripts/prepare-upstream-plugin-review.mjs",
|
|
96
|
+
"upstream:sync": "node scripts/sync-upstream-plugin-references.mjs",
|
|
97
|
+
"release:check": "pnpm run format:check && pnpm run verify:typescript-version && pnpm run verify:v4-history && pnpm run typecheck && pnpm run build && pnpm test && pnpm run test:four-surfaces && pnpm run verify:release-package && pnpm run verify:release-version",
|
|
98
|
+
"smoke:package": "node scripts/smoke-packed-package.mjs",
|
|
99
|
+
"test:four-surfaces": "vitest run tests/v4-phase5-cross-surface.test.ts",
|
|
100
|
+
"verify:package-contents": "node scripts/verify-package-contents.mjs",
|
|
101
|
+
"verify:release-package": "node scripts/verify-release-package.mjs",
|
|
102
|
+
"verify:release-version": "node scripts/verify-release-version.mjs",
|
|
103
|
+
"verify:typescript-version": "node scripts/verify-typescript-version.mjs",
|
|
104
|
+
"verify:v4-history": "node scripts/verify-v4-history.mjs",
|
|
105
|
+
"typecheck": "tsc --noEmit",
|
|
106
|
+
"test": "vitest run",
|
|
107
|
+
"test:watch": "vitest"
|
|
100
108
|
}
|
|
101
|
-
}
|
|
109
|
+
}
|