@slkiser/opencode-quota 4.5.0 → 4.6.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 +1 -0
- package/dist/data/modelsdev-pricing.min.json +5 -0
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +51 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/maintainer-announcements.d.ts +3 -0
- package/dist/lib/maintainer-announcements.d.ts.map +1 -1
- package/dist/lib/maintainer-announcements.js +13 -0
- package/dist/lib/maintainer-announcements.js.map +1 -1
- package/dist/lib/quota-export.d.ts +1 -0
- package/dist/lib/quota-export.d.ts.map +1 -1
- package/dist/lib/quota-export.js +4 -0
- package/dist/lib/quota-export.js.map +1 -1
- package/dist/lib/quota-render-data.d.ts +2 -0
- package/dist/lib/quota-render-data.d.ts.map +1 -1
- package/dist/lib/quota-render-data.js +7 -0
- package/dist/lib/quota-render-data.js.map +1 -1
- package/dist/lib/quota-reset-notifications.d.ts +20 -0
- package/dist/lib/quota-reset-notifications.d.ts.map +1 -0
- package/dist/lib/quota-reset-notifications.js +328 -0
- package/dist/lib/quota-reset-notifications.js.map +1 -0
- package/dist/lib/quota-stats.d.ts.map +1 -1
- package/dist/lib/quota-stats.js +4 -0
- package/dist/lib/quota-stats.js.map +1 -1
- package/dist/lib/tui-refresh-lifecycle.d.ts.map +1 -1
- package/dist/lib/tui-refresh-lifecycle.js +0 -1
- package/dist/lib/tui-refresh-lifecycle.js.map +1 -1
- package/dist/lib/tui-runtime.d.ts +8 -1
- package/dist/lib/tui-runtime.d.ts.map +1 -1
- package/dist/lib/tui-runtime.js +36 -5
- package/dist/lib/tui-runtime.js.map +1 -1
- package/dist/lib/types.d.ts +9 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +4 -0
- package/dist/lib/types.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +38 -1
- package/dist/plugin.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +171 -70
- package/dist/tui.tsx +220 -69
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -23,6 +23,61 @@ const COMPACT_ORDER = 90;
|
|
|
23
23
|
const REFRESH_INTERVAL_MS = 60_000;
|
|
24
24
|
const EVENT_REFRESH_DELAYS_MS = [150, 600];
|
|
25
25
|
const MOUNT_RECOVERY_DELAYS_MS = [500, 1_500, 4_000];
|
|
26
|
+
const FALLBACK_SURFACE_REGISTRATION = {
|
|
27
|
+
commandDisplay: "inline",
|
|
28
|
+
sidebar: {
|
|
29
|
+
enabled: true
|
|
30
|
+
},
|
|
31
|
+
compact: {
|
|
32
|
+
enabled: false,
|
|
33
|
+
homeBottom: false,
|
|
34
|
+
sessionPrompt: false,
|
|
35
|
+
hasNativeProviderQuota: false,
|
|
36
|
+
suppressedByNativeProviderQuota: false
|
|
37
|
+
},
|
|
38
|
+
announcements: {
|
|
39
|
+
homeBottom: false
|
|
40
|
+
},
|
|
41
|
+
homeBottom: false
|
|
42
|
+
};
|
|
43
|
+
function createTuiInitialLoadCoordinator(seed) {
|
|
44
|
+
let sessionAvailable = true;
|
|
45
|
+
let homeAvailable = true;
|
|
46
|
+
return {
|
|
47
|
+
takeInitialSession() {
|
|
48
|
+
if (!sessionAvailable) return undefined;
|
|
49
|
+
sessionAvailable = false;
|
|
50
|
+
return seed;
|
|
51
|
+
},
|
|
52
|
+
takeInitialHome() {
|
|
53
|
+
if (!homeAvailable) return undefined;
|
|
54
|
+
homeAvailable = false;
|
|
55
|
+
return seed;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function createTuiRegistrationGate() {
|
|
60
|
+
const [current, setCurrent] = createSignal({
|
|
61
|
+
status: "pending"
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
current,
|
|
65
|
+
activate(registration, initialLoads) {
|
|
66
|
+
if (current().status !== "pending") return;
|
|
67
|
+
setCurrent({
|
|
68
|
+
status: "active",
|
|
69
|
+
registration,
|
|
70
|
+
initialLoads
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
dispose() {
|
|
74
|
+
if (current().status === "disposed") return;
|
|
75
|
+
setCurrent({
|
|
76
|
+
status: "disposed"
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
26
81
|
const sessionResources = new WeakMap();
|
|
27
82
|
const homeResources = new WeakMap();
|
|
28
83
|
function getSessionResourceMap(api) {
|
|
@@ -32,7 +87,7 @@ function getSessionResourceMap(api) {
|
|
|
32
87
|
sessionResources.set(api, next);
|
|
33
88
|
return next;
|
|
34
89
|
}
|
|
35
|
-
function createSessionQuotaResource(api, sessionID) {
|
|
90
|
+
function createSessionQuotaResource(api, sessionID, initialLoads) {
|
|
36
91
|
const [sidebar, setSidebar] = createSignal({
|
|
37
92
|
status: "loading",
|
|
38
93
|
lines: []
|
|
@@ -40,11 +95,19 @@ function createSessionQuotaResource(api, sessionID) {
|
|
|
40
95
|
const [compact, setCompact] = createSignal({
|
|
41
96
|
status: "loading"
|
|
42
97
|
});
|
|
98
|
+
let loadOrdinal = 0;
|
|
43
99
|
const lifecycle = createTuiRefreshLifecycle({
|
|
44
|
-
load: () =>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
100
|
+
load: () => {
|
|
101
|
+
const initialRuntimeSeed = loadOrdinal === 0 ? initialLoads?.takeInitialSession() : undefined;
|
|
102
|
+
loadOrdinal += 1;
|
|
103
|
+
return loadTuiSessionQuotaSurfaces({
|
|
104
|
+
api,
|
|
105
|
+
sessionID,
|
|
106
|
+
...(initialRuntimeSeed ? {
|
|
107
|
+
initialRuntimeSeed
|
|
108
|
+
} : {})
|
|
109
|
+
});
|
|
110
|
+
},
|
|
48
111
|
apply: next => {
|
|
49
112
|
setSidebar(next.sidebar);
|
|
50
113
|
setCompact(next.compact);
|
|
@@ -87,15 +150,15 @@ function createSessionQuotaResource(api, sessionID) {
|
|
|
87
150
|
};
|
|
88
151
|
return resource;
|
|
89
152
|
}
|
|
90
|
-
function acquireSessionQuotaResource(api, sessionID) {
|
|
153
|
+
function acquireSessionQuotaResource(api, sessionID, initialLoads) {
|
|
91
154
|
const resources = getSessionResourceMap(api);
|
|
92
155
|
const existing = resources.get(sessionID);
|
|
93
156
|
if (existing) return existing.retain();
|
|
94
|
-
const next = createSessionQuotaResource(api, sessionID).retain();
|
|
157
|
+
const next = createSessionQuotaResource(api, sessionID, initialLoads).retain();
|
|
95
158
|
resources.set(sessionID, next);
|
|
96
159
|
return next;
|
|
97
160
|
}
|
|
98
|
-
function createHomeBottomResource(api, compactHomeBottomEnabled) {
|
|
161
|
+
function createHomeBottomResource(api, compactHomeBottomEnabled, initialLoads) {
|
|
99
162
|
const [bottom, setBottom] = createSignal({
|
|
100
163
|
status: "loading",
|
|
101
164
|
compact: compactHomeBottomEnabled ? {
|
|
@@ -104,10 +167,18 @@ function createHomeBottomResource(api, compactHomeBottomEnabled) {
|
|
|
104
167
|
status: "disabled"
|
|
105
168
|
}
|
|
106
169
|
});
|
|
170
|
+
let loadOrdinal = 0;
|
|
107
171
|
const lifecycle = createTuiRefreshLifecycle({
|
|
108
|
-
load: () =>
|
|
109
|
-
|
|
110
|
-
|
|
172
|
+
load: () => {
|
|
173
|
+
const initialRuntimeSeed = loadOrdinal === 0 ? initialLoads?.takeInitialHome() : undefined;
|
|
174
|
+
loadOrdinal += 1;
|
|
175
|
+
return loadTuiHomeBottomStatus({
|
|
176
|
+
api,
|
|
177
|
+
...(initialRuntimeSeed ? {
|
|
178
|
+
initialRuntimeSeed
|
|
179
|
+
} : {})
|
|
180
|
+
});
|
|
181
|
+
},
|
|
111
182
|
apply: setBottom,
|
|
112
183
|
afterApply: () => {
|
|
113
184
|
// Fire-and-forget: write export file if enabled. A failed write must
|
|
@@ -135,21 +206,21 @@ function createHomeBottomResource(api, compactHomeBottomEnabled) {
|
|
|
135
206
|
};
|
|
136
207
|
return resource;
|
|
137
208
|
}
|
|
138
|
-
function acquireHomeBottomResource(api, compactHomeBottomEnabled) {
|
|
209
|
+
function acquireHomeBottomResource(api, compactHomeBottomEnabled, initialLoads) {
|
|
139
210
|
const existing = homeResources.get(api);
|
|
140
211
|
if (existing) return existing.retain();
|
|
141
|
-
const next = createHomeBottomResource(api, compactHomeBottomEnabled).retain();
|
|
212
|
+
const next = createHomeBottomResource(api, compactHomeBottomEnabled, initialLoads).retain();
|
|
142
213
|
homeResources.set(api, next);
|
|
143
214
|
return next;
|
|
144
215
|
}
|
|
145
|
-
function useSessionQuotaResource(api, sessionID) {
|
|
146
|
-
let current = acquireSessionQuotaResource(api, sessionID());
|
|
216
|
+
function useSessionQuotaResource(api, sessionID, initialLoads) {
|
|
217
|
+
let current = acquireSessionQuotaResource(api, sessionID(), initialLoads);
|
|
147
218
|
const [resource, setResource] = createSignal(current);
|
|
148
219
|
createEffect(() => {
|
|
149
220
|
const nextSessionID = sessionID();
|
|
150
221
|
if (current.sessionID === nextSessionID) return;
|
|
151
222
|
const previous = current;
|
|
152
|
-
current = acquireSessionQuotaResource(api, nextSessionID);
|
|
223
|
+
current = acquireSessionQuotaResource(api, nextSessionID, initialLoads);
|
|
153
224
|
setResource(current);
|
|
154
225
|
previous.release();
|
|
155
226
|
});
|
|
@@ -159,7 +230,7 @@ function useSessionQuotaResource(api, sessionID) {
|
|
|
159
230
|
return resource;
|
|
160
231
|
}
|
|
161
232
|
function SidebarContentView(props) {
|
|
162
|
-
const resource = useSessionQuotaResource(props.api, () => props.sessionID);
|
|
233
|
+
const resource = useSessionQuotaResource(props.api, () => props.sessionID, props.initialLoads);
|
|
163
234
|
const panel = () => resource().sidebar();
|
|
164
235
|
const lines = () => getSidebarPanelLines(panel());
|
|
165
236
|
const hasDetailLines = () => Boolean(panel().linesExpanded?.length);
|
|
@@ -276,7 +347,7 @@ function CompactStatusLine(props) {
|
|
|
276
347
|
});
|
|
277
348
|
}
|
|
278
349
|
function SessionPromptWithCompactStatus(props) {
|
|
279
|
-
const resource = useSessionQuotaResource(props.api, () => props.sessionID);
|
|
350
|
+
const resource = useSessionQuotaResource(props.api, () => props.sessionID, props.initialLoads);
|
|
280
351
|
const panel = () => resource().compact();
|
|
281
352
|
return (() => {
|
|
282
353
|
var _el$13 = _$createElement("box");
|
|
@@ -310,7 +381,7 @@ function SessionPromptWithCompactStatus(props) {
|
|
|
310
381
|
})();
|
|
311
382
|
}
|
|
312
383
|
function HomeBottomView(props) {
|
|
313
|
-
const resource = acquireHomeBottomResource(props.api, props.compactHomeBottomEnabled);
|
|
384
|
+
const resource = acquireHomeBottomResource(props.api, props.compactHomeBottomEnabled, props.initialLoads);
|
|
314
385
|
onCleanup(() => resource.release());
|
|
315
386
|
const announcement = () => getHomeBottomAnnouncementText(resource.bottom());
|
|
316
387
|
const compact = () => resource.bottom().compact;
|
|
@@ -629,7 +700,7 @@ async function runQuotaDialogCommandAsync(api, command, commandDisplay, rawInput
|
|
|
629
700
|
});
|
|
630
701
|
}
|
|
631
702
|
}
|
|
632
|
-
function registerQuotaDialogCommands(api,
|
|
703
|
+
function registerQuotaDialogCommands(api, gate) {
|
|
633
704
|
const commandState = {};
|
|
634
705
|
const dispose = api.keymap.registerLayer({
|
|
635
706
|
commands: QUOTA_DIALOG_COMMANDS.map(spec => ({
|
|
@@ -640,81 +711,111 @@ function registerQuotaDialogCommands(api, commandDisplay) {
|
|
|
640
711
|
category: "OpenCode Quota",
|
|
641
712
|
slashName: spec.slashName,
|
|
642
713
|
run(input) {
|
|
643
|
-
|
|
714
|
+
const state = gate.current();
|
|
715
|
+
if (state.status !== "active") return;
|
|
716
|
+
void runQuotaDialogCommandAsync(api, spec.id, state.registration.commandDisplay, input, commandState);
|
|
644
717
|
}
|
|
645
718
|
})),
|
|
646
719
|
bindings: []
|
|
647
720
|
});
|
|
648
721
|
api.lifecycle.onDispose(dispose);
|
|
649
722
|
}
|
|
650
|
-
function
|
|
723
|
+
function registerStableTuiSlots(api, current) {
|
|
651
724
|
api.slots.register({
|
|
652
725
|
order: SIDEBAR_ORDER,
|
|
653
726
|
slots: {
|
|
654
727
|
sidebar_content(_ctx, props) {
|
|
728
|
+
const state = current();
|
|
729
|
+
if (state.status !== "active" || !state.registration.sidebar.enabled) return null;
|
|
655
730
|
return _$createComponent(SidebarContentView, {
|
|
656
731
|
api: api,
|
|
657
732
|
get sessionID() {
|
|
658
733
|
return props.session_id;
|
|
734
|
+
},
|
|
735
|
+
get initialLoads() {
|
|
736
|
+
return state.initialLoads;
|
|
659
737
|
}
|
|
660
738
|
});
|
|
661
739
|
}
|
|
662
740
|
}
|
|
663
741
|
});
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
742
|
+
api.slots.register({
|
|
743
|
+
order: COMPACT_ORDER,
|
|
744
|
+
slots: {
|
|
745
|
+
session_prompt(_ctx, props) {
|
|
746
|
+
const state = current();
|
|
747
|
+
if (state.status !== "active" || !state.registration.compact.sessionPrompt) return null;
|
|
748
|
+
return _$createComponent(SessionPromptWithCompactStatus, {
|
|
749
|
+
api: api,
|
|
750
|
+
get sessionID() {
|
|
751
|
+
return props.session_id;
|
|
752
|
+
},
|
|
753
|
+
get initialLoads() {
|
|
754
|
+
return state.initialLoads;
|
|
755
|
+
},
|
|
756
|
+
get visible() {
|
|
757
|
+
return props.visible;
|
|
758
|
+
},
|
|
759
|
+
get disabled() {
|
|
760
|
+
return props.disabled;
|
|
761
|
+
},
|
|
762
|
+
get onSubmit() {
|
|
763
|
+
return props.on_submit;
|
|
764
|
+
},
|
|
765
|
+
get promptRef() {
|
|
766
|
+
return props.ref;
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
},
|
|
770
|
+
home_bottom() {
|
|
771
|
+
const state = current();
|
|
772
|
+
if (state.status !== "active" || !state.registration.homeBottom) return null;
|
|
773
|
+
return _$createComponent(HomeBottomView, {
|
|
774
|
+
api: api,
|
|
775
|
+
get compactHomeBottomEnabled() {
|
|
776
|
+
return state.registration.compact.homeBottom;
|
|
777
|
+
},
|
|
778
|
+
get initialLoads() {
|
|
779
|
+
return state.initialLoads;
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
}
|
|
668
784
|
});
|
|
785
|
+
}
|
|
786
|
+
async function initializeTuiRegistration(api, gate) {
|
|
787
|
+
let initialRuntimeSeed;
|
|
669
788
|
let surfaceRegistration;
|
|
670
789
|
try {
|
|
671
|
-
surfaceRegistration =
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
registerSidebarSlots(api);
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
registerQuotaDialogCommands(api, surfaceRegistration.commandDisplay);
|
|
678
|
-
if (surfaceRegistration.sidebar.enabled) {
|
|
679
|
-
registerSidebarSlots(api);
|
|
680
|
-
}
|
|
681
|
-
const compactRegistration = surfaceRegistration.compact;
|
|
682
|
-
if (!compactRegistration.enabled && !surfaceRegistration.homeBottom) return;
|
|
683
|
-
const compactSlots = {};
|
|
684
|
-
if (compactRegistration.sessionPrompt) {
|
|
685
|
-
compactSlots.session_prompt = (_ctx, props) => _$createComponent(SessionPromptWithCompactStatus, {
|
|
686
|
-
api: api,
|
|
687
|
-
get sessionID() {
|
|
688
|
-
return props.session_id;
|
|
689
|
-
},
|
|
690
|
-
get visible() {
|
|
691
|
-
return props.visible;
|
|
692
|
-
},
|
|
693
|
-
get disabled() {
|
|
694
|
-
return props.disabled;
|
|
695
|
-
},
|
|
696
|
-
get onSubmit() {
|
|
697
|
-
return props.on_submit;
|
|
698
|
-
},
|
|
699
|
-
get promptRef() {
|
|
700
|
-
return props.ref;
|
|
790
|
+
surfaceRegistration = resolveTuiSurfaceRegistration(api, {
|
|
791
|
+
captureInitialRuntime(seed) {
|
|
792
|
+
initialRuntimeSeed = seed;
|
|
701
793
|
}
|
|
794
|
+
}).then(registration => ({
|
|
795
|
+
registration,
|
|
796
|
+
initialRuntimeSeed
|
|
797
|
+
})).catch(() => ({
|
|
798
|
+
registration: FALLBACK_SURFACE_REGISTRATION
|
|
799
|
+
}));
|
|
800
|
+
} catch {
|
|
801
|
+
surfaceRegistration = Promise.resolve({
|
|
802
|
+
registration: FALLBACK_SURFACE_REGISTRATION
|
|
702
803
|
});
|
|
703
804
|
}
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
}
|
|
805
|
+
registerQuotaDialogCommands(api, gate);
|
|
806
|
+
void surfaceRegistration.then(({
|
|
807
|
+
registration,
|
|
808
|
+
initialRuntimeSeed
|
|
809
|
+
}) => gate.activate(registration, initialRuntimeSeed ? createTuiInitialLoadCoordinator(initialRuntimeSeed) : undefined));
|
|
810
|
+
registerStableTuiSlots(api, gate.current);
|
|
811
|
+
}
|
|
812
|
+
const tui = async api => {
|
|
813
|
+
const registrationGate = createTuiRegistrationGate();
|
|
814
|
+
api.lifecycle.onDispose(() => {
|
|
815
|
+
registrationGate.dispose();
|
|
816
|
+
disposeQuotaTelemetryOwner(createTuiQuotaClient(api));
|
|
817
|
+
});
|
|
818
|
+
void initializeTuiRegistration(api, registrationGate).catch(() => {});
|
|
718
819
|
};
|
|
719
820
|
const pluginModule = {
|
|
720
821
|
id,
|