opencode-deepseek-peak 0.1.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/dist/tui.js ADDED
@@ -0,0 +1,760 @@
1
+ // src/tui.tsx
2
+ import { createComponent as _$createComponent3 } from "@opentui/solid";
3
+ import { createSignal } from "solid-js";
4
+
5
+ // src/core/display.ts
6
+ var INITIAL_SETTINGS = {
7
+ toast: true,
8
+ indicator: true,
9
+ sidebarIndicator: true,
10
+ sidebarEvidence: true,
11
+ toastEveryRequest: false,
12
+ lang: "en"
13
+ };
14
+ function statusLabel(status, t) {
15
+ const period = t(status.period === "peak" ? "period.peak" : "period.offPeak");
16
+ const correction = status.mismatch ? ` \xB7 API \u2260 ${t("evidence.schedule")}` : "";
17
+ return `DeepSeek ${period}${correction}`;
18
+ }
19
+ var HOLIDAY_KEYS = {
20
+ "Mid-Autumn Festival": "holiday.midAutumn",
21
+ "National Day": "holiday.nationalDay",
22
+ "Spring Festival": "holiday.springFestival",
23
+ "Qingming Festival": "holiday.qingming",
24
+ "Dragon Boat Festival": "holiday.dragonBoat",
25
+ "Labour Day": "holiday.labourDay"
26
+ };
27
+ function evidenceLabel(status, t) {
28
+ let label;
29
+ if (status.source === "api-header") {
30
+ label = t("evidence.apiHeader", { header: status.evidence.split(":")[0] });
31
+ } else if (status.holiday) {
32
+ const key = HOLIDAY_KEYS[status.holiday];
33
+ label = t("evidence.holiday", { name: key ? t(key) : status.holiday });
34
+ } else {
35
+ label = t("evidence.schedule");
36
+ }
37
+ if (status.evidence.endsWith("(cached)")) label += ` ${t("evidence.cached")}`;
38
+ if (status.evidence.includes("no request observed yet")) label += ` ${t("evidence.preview")}`;
39
+ return label;
40
+ }
41
+ function themeColors(theme) {
42
+ const text = theme.text;
43
+ const warning = text.feedback.warning;
44
+ return {
45
+ normal: text.base ?? text.default,
46
+ muted: text.muted ?? text.subdued,
47
+ warning: warning.base ?? warning.default
48
+ };
49
+ }
50
+
51
+ // src/i18n.ts
52
+ var EN_T = {
53
+ "period.peak": "PEAK",
54
+ "period.offPeak": "OFF-PEAK",
55
+ "evidence.schedule": "official schedule",
56
+ "evidence.apiHeader": "via {header}",
57
+ "evidence.cached": "(cached)",
58
+ "evidence.preview": "(no request yet)",
59
+ "evidence.holiday": "Holiday: {name}",
60
+ "label.mismatch": "mismatch",
61
+ "toast.title": "DeepSeek pricing",
62
+ "status.title": "DeepSeek Peak",
63
+ "status.noSession": "Open a session first.",
64
+ "status.noRequest": "No DeepSeek request observed in this session yet.",
65
+ "status.source": "Source",
66
+ "status.evidence": "Evidence",
67
+ "status.unavailable": "DeepSeek Peak server plugin is unavailable.",
68
+ "command.status.title": "DeepSeek Peak: Show Status",
69
+ "command.status.description": "Show the last observed DeepSeek pricing period",
70
+ "command.sections.title": "DeepSeek Peak: Sections",
71
+ "command.sections.description": "Open the interactive sections menu (Esc to close)",
72
+ "command.lang.title": "DeepSeek Peak: Language",
73
+ "command.lang.description": "Switch display language",
74
+ "settings.title": "DeepSeek Peak sections",
75
+ "settings.toast": "Toast",
76
+ "settings.footer": "Footer indicator",
77
+ "settings.sidebar": "Sidebar indicator",
78
+ "settings.evidence": "Sidebar evidence",
79
+ "settings.frequency": "Toast frequency",
80
+ "settings.lang": "Language",
81
+ "settings.on": "on",
82
+ "settings.off": "off",
83
+ "frequency.change": "on change",
84
+ "frequency.every": "every request",
85
+ "holiday.midAutumn": "Mid-Autumn Festival",
86
+ "holiday.nationalDay": "National Day",
87
+ "holiday.springFestival": "Spring Festival",
88
+ "holiday.qingming": "Qingming Festival",
89
+ "holiday.dragonBoat": "Dragon Boat Festival",
90
+ "holiday.labourDay": "Labour Day"
91
+ };
92
+ var PT_T = {
93
+ "period.peak": "PICO",
94
+ "period.offPeak": "FORA DE PICO",
95
+ "evidence.schedule": "hor\xE1rio oficial",
96
+ "evidence.apiHeader": "via {header}",
97
+ "evidence.cached": "(cache)",
98
+ "evidence.preview": "(sem requisi\xE7\xE3o ainda)",
99
+ "evidence.holiday": "Feriado: {name}",
100
+ "label.mismatch": "divergente",
101
+ "toast.title": "Pre\xE7o DeepSeek",
102
+ "status.title": "DeepSeek Peak",
103
+ "status.noSession": "Abra uma sess\xE3o primeiro.",
104
+ "status.noRequest": "Nenhuma requisi\xE7\xE3o DeepSeek observada nesta sess\xE3o ainda.",
105
+ "status.source": "Fonte",
106
+ "status.evidence": "Evid\xEAncia",
107
+ "status.unavailable": "O plugin de servidor do DeepSeek Peak est\xE1 indispon\xEDvel.",
108
+ "command.status.title": "DeepSeek Peak: Mostrar status",
109
+ "command.status.description": "Mostra o \xFAltimo per\xEDodo de pre\xE7o observado da DeepSeek",
110
+ "command.sections.title": "DeepSeek Peak: Se\xE7\xF5es",
111
+ "command.sections.description": "Abre o menu interativo de se\xE7\xF5es (Esc para fechar)",
112
+ "command.lang.title": "DeepSeek Peak: Idioma",
113
+ "command.lang.description": "Troca o idioma da interface",
114
+ "settings.title": "Se\xE7\xF5es do DeepSeek Peak",
115
+ "settings.toast": "Toast",
116
+ "settings.footer": "Indicador no rodap\xE9",
117
+ "settings.sidebar": "Indicador na barra lateral",
118
+ "settings.evidence": "Evid\xEAncia na barra lateral",
119
+ "settings.frequency": "Frequ\xEAncia do toast",
120
+ "settings.lang": "Idioma",
121
+ "settings.on": "ativado",
122
+ "settings.off": "desativado",
123
+ "frequency.change": "ao mudar",
124
+ "frequency.every": "a cada requisi\xE7\xE3o",
125
+ "holiday.midAutumn": "Festival do Meio do Outono",
126
+ "holiday.nationalDay": "Dia Nacional",
127
+ "holiday.springFestival": "Festival da Primavera",
128
+ "holiday.qingming": "Festival Qingming",
129
+ "holiday.dragonBoat": "Festival do Barco Drag\xE3o",
130
+ "holiday.labourDay": "Dia do Trabalho"
131
+ };
132
+ var ZH_T = {
133
+ "period.peak": "\u9AD8\u5CF0",
134
+ "period.offPeak": "\u4F4E\u8C37",
135
+ "evidence.schedule": "\u5B98\u65B9\u65F6\u6BB5",
136
+ "evidence.apiHeader": "\u6765\u81EA {header}",
137
+ "evidence.cached": "\uFF08\u7F13\u5B58\uFF09",
138
+ "evidence.preview": "\uFF08\u5C1A\u65E0\u8BF7\u6C42\uFF09",
139
+ "evidence.holiday": "\u8282\u5047\u65E5\uFF1A{name}",
140
+ "label.mismatch": "\u4E0D\u4E00\u81F4",
141
+ "toast.title": "DeepSeek \u4EF7\u683C",
142
+ "status.title": "DeepSeek Peak",
143
+ "status.noSession": "\u8BF7\u5148\u6253\u5F00\u4E00\u4E2A\u4F1A\u8BDD\u3002",
144
+ "status.noRequest": "\u6B64\u4F1A\u8BDD\u5C1A\u672A\u89C2\u5BDF\u5230 DeepSeek \u8BF7\u6C42\u3002",
145
+ "status.source": "\u6765\u6E90",
146
+ "status.evidence": "\u8BC1\u636E",
147
+ "status.unavailable": "DeepSeek Peak \u670D\u52A1\u7AEF\u63D2\u4EF6\u4E0D\u53EF\u7528\u3002",
148
+ "command.status.title": "DeepSeek Peak\uFF1A\u663E\u793A\u72B6\u6001",
149
+ "command.status.description": "\u663E\u793A\u6700\u8FD1\u89C2\u5BDF\u5230\u7684 DeepSeek \u4EF7\u683C\u65F6\u6BB5",
150
+ "command.sections.title": "DeepSeek Peak\uFF1A\u677F\u5757",
151
+ "command.sections.description": "\u6253\u5F00\u4EA4\u4E92\u5F0F\u677F\u5757\u83DC\u5355\uFF08Esc \u5173\u95ED\uFF09",
152
+ "command.lang.title": "DeepSeek Peak\uFF1A\u8BED\u8A00",
153
+ "command.lang.description": "\u5207\u6362\u754C\u9762\u8BED\u8A00",
154
+ "settings.title": "DeepSeek Peak \u677F\u5757",
155
+ "settings.toast": "\u901A\u77E5",
156
+ "settings.footer": "\u5E95\u90E8\u6307\u793A\u5668",
157
+ "settings.sidebar": "\u4FA7\u8FB9\u680F\u6307\u793A\u5668",
158
+ "settings.evidence": "\u4FA7\u8FB9\u680F\u8BC1\u636E",
159
+ "settings.frequency": "\u901A\u77E5\u9891\u7387",
160
+ "settings.lang": "\u8BED\u8A00",
161
+ "settings.on": "\u5F00",
162
+ "settings.off": "\u5173",
163
+ "frequency.change": "\u53D8\u5316\u65F6",
164
+ "frequency.every": "\u6BCF\u6B21\u8BF7\u6C42",
165
+ "holiday.midAutumn": "\u4E2D\u79CB\u8282",
166
+ "holiday.nationalDay": "\u56FD\u5E86\u8282",
167
+ "holiday.springFestival": "\u6625\u8282",
168
+ "holiday.qingming": "\u6E05\u660E\u8282",
169
+ "holiday.dragonBoat": "\u7AEF\u5348\u8282",
170
+ "holiday.labourDay": "\u52B3\u52A8\u8282"
171
+ };
172
+ var JA_T = {
173
+ "period.peak": "\u30D4\u30FC\u30AF",
174
+ "period.offPeak": "\u30AA\u30D5\u30D4\u30FC\u30AF",
175
+ "evidence.schedule": "\u516C\u5F0F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB",
176
+ "evidence.apiHeader": "{header} \u7D4C\u7531",
177
+ "evidence.cached": "\uFF08\u30AD\u30E3\u30C3\u30B7\u30E5\uFF09",
178
+ "evidence.preview": "\uFF08\u307E\u3060\u30EA\u30AF\u30A8\u30B9\u30C8\u306A\u3057\uFF09",
179
+ "evidence.holiday": "\u795D\u65E5\uFF1A{name}",
180
+ "label.mismatch": "\u4E0D\u4E00\u81F4",
181
+ "toast.title": "DeepSeek \u6599\u91D1",
182
+ "status.title": "DeepSeek Peak",
183
+ "status.noSession": "\u5148\u306B\u30BB\u30C3\u30B7\u30E7\u30F3\u3092\u958B\u3044\u3066\u304F\u3060\u3055\u3044\u3002",
184
+ "status.noRequest": "\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067\u306F\u307E\u3060 DeepSeek \u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u3042\u308A\u307E\u305B\u3093\u3002",
185
+ "status.source": "\u30BD\u30FC\u30B9",
186
+ "status.evidence": "\u30A8\u30D3\u30C7\u30F3\u30B9",
187
+ "status.unavailable": "DeepSeek Peak \u30B5\u30FC\u30D0\u30FC\u30D7\u30E9\u30B0\u30A4\u30F3\u304C\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002",
188
+ "command.status.title": "DeepSeek Peak\uFF1A\u30B9\u30C6\u30FC\u30BF\u30B9\u8868\u793A",
189
+ "command.status.description": "\u6700\u5F8C\u306B\u89B3\u6E2C\u3057\u305F DeepSeek \u6599\u91D1\u671F\u9593\u3092\u8868\u793A",
190
+ "command.sections.title": "DeepSeek Peak\uFF1A\u30BB\u30AF\u30B7\u30E7\u30F3",
191
+ "command.sections.description": "\u5BFE\u8A71\u5F0F\u30BB\u30AF\u30B7\u30E7\u30F3\u30E1\u30CB\u30E5\u30FC\u3092\u958B\u304F\uFF08Esc \u3067\u9589\u3058\u308B\uFF09",
192
+ "command.lang.title": "DeepSeek Peak\uFF1A\u8A00\u8A9E",
193
+ "command.lang.description": "\u8868\u793A\u8A00\u8A9E\u3092\u5207\u308A\u66FF\u3048",
194
+ "settings.title": "DeepSeek Peak \u30BB\u30AF\u30B7\u30E7\u30F3",
195
+ "settings.toast": "\u30C8\u30FC\u30B9\u30C8",
196
+ "settings.footer": "\u30D5\u30C3\u30BF\u30FC\u8868\u793A",
197
+ "settings.sidebar": "\u30B5\u30A4\u30C9\u30D0\u30FC\u8868\u793A",
198
+ "settings.evidence": "\u30B5\u30A4\u30C9\u30D0\u30FC\u306E\u30A8\u30D3\u30C7\u30F3\u30B9",
199
+ "settings.frequency": "\u30C8\u30FC\u30B9\u30C8\u983B\u5EA6",
200
+ "settings.lang": "\u8A00\u8A9E",
201
+ "settings.on": "\u30AA\u30F3",
202
+ "settings.off": "\u30AA\u30D5",
203
+ "frequency.change": "\u5909\u66F4\u6642",
204
+ "frequency.every": "\u6BCE\u30EA\u30AF\u30A8\u30B9\u30C8",
205
+ "holiday.midAutumn": "\u4E2D\u79CB\u7BC0",
206
+ "holiday.nationalDay": "\u56FD\u6176\u7BC0",
207
+ "holiday.springFestival": "\u6625\u7BC0",
208
+ "holiday.qingming": "\u6E05\u660E\u7BC0",
209
+ "holiday.dragonBoat": "\u7AEF\u5348\u7BC0",
210
+ "holiday.labourDay": "\u52B4\u50CD\u7BC0"
211
+ };
212
+ var KO_T = {
213
+ "period.peak": "\uD53C\uD06C",
214
+ "period.offPeak": "\uBE44\uD53C\uD06C",
215
+ "evidence.schedule": "\uACF5\uC2DD \uC77C\uC815",
216
+ "evidence.apiHeader": "{header} \uAE30\uC900",
217
+ "evidence.cached": "(\uCE90\uC2DC)",
218
+ "evidence.preview": "(\uC544\uC9C1 \uC694\uCCAD \uC5C6\uC74C)",
219
+ "evidence.holiday": "\uACF5\uD734\uC77C: {name}",
220
+ "label.mismatch": "\uBD88\uC77C\uCE58",
221
+ "toast.title": "DeepSeek \uC694\uAE08",
222
+ "status.title": "DeepSeek Peak",
223
+ "status.noSession": "\uBA3C\uC800 \uC138\uC158\uC744 \uC5EC\uC138\uC694.",
224
+ "status.noRequest": "\uC774 \uC138\uC158\uC5D0\uB294 \uC544\uC9C1 DeepSeek \uC694\uCCAD\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
225
+ "status.source": "\uCD9C\uCC98",
226
+ "status.evidence": "\uADFC\uAC70",
227
+ "status.unavailable": "DeepSeek Peak \uC11C\uBC84 \uD50C\uB7EC\uADF8\uC778\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
228
+ "command.status.title": "DeepSeek Peak: \uC0C1\uD0DC \uD45C\uC2DC",
229
+ "command.status.description": "\uB9C8\uC9C0\uB9C9\uC73C\uB85C \uAD00\uCE21\uB41C DeepSeek \uC694\uAE08 \uAE30\uAC04 \uD45C\uC2DC",
230
+ "command.sections.title": "DeepSeek Peak: \uC139\uC158",
231
+ "command.sections.description": "\uB300\uD654\uD615 \uC139\uC158 \uBA54\uB274 \uC5F4\uAE30 (Esc \uB2EB\uAE30)",
232
+ "command.lang.title": "DeepSeek Peak: \uC5B8\uC5B4",
233
+ "command.lang.description": "\uD45C\uC2DC \uC5B8\uC5B4 \uC804\uD658",
234
+ "settings.title": "DeepSeek Peak \uC139\uC158",
235
+ "settings.toast": "\uD1A0\uC2A4\uD2B8",
236
+ "settings.footer": "\uD558\uB2E8 \uD45C\uC2DC",
237
+ "settings.sidebar": "\uC0AC\uC774\uB4DC\uBC14 \uD45C\uC2DC",
238
+ "settings.evidence": "\uC0AC\uC774\uB4DC\uBC14 \uADFC\uAC70",
239
+ "settings.frequency": "\uD1A0\uC2A4\uD2B8 \uBE48\uB3C4",
240
+ "settings.lang": "\uC5B8\uC5B4",
241
+ "settings.on": "\uCF1C\uC9D0",
242
+ "settings.off": "\uAEBC\uC9D0",
243
+ "frequency.change": "\uBCC0\uACBD \uC2DC",
244
+ "frequency.every": "\uB9E4 \uC694\uCCAD",
245
+ "holiday.midAutumn": "\uCD94\uC11D",
246
+ "holiday.nationalDay": "\uAD6D\uACBD\uC77C",
247
+ "holiday.springFestival": "\uCD98\uC81C",
248
+ "holiday.qingming": "\uCCAD\uBA85\uC808",
249
+ "holiday.dragonBoat": "\uB2E8\uC624\uC808",
250
+ "holiday.labourDay": "\uB178\uB3D9\uC808"
251
+ };
252
+ var TRANSLATIONS = { en: EN_T, pt: PT_T, zh: ZH_T, ja: JA_T, ko: KO_T };
253
+ var LANG_META = [
254
+ { code: "en", label: "English" },
255
+ { code: "pt", label: "Portugu\xEAs" },
256
+ { code: "zh", label: "\u4E2D\u6587" },
257
+ { code: "ja", label: "\u65E5\u672C\u8A9E" },
258
+ { code: "ko", label: "\uD55C\uAD6D\uC5B4" }
259
+ ];
260
+ function detectLang() {
261
+ const raw = String(process.env.LANG ?? process.env.LC_ALL ?? "").toLowerCase();
262
+ if (raw.includes("zh")) return "zh";
263
+ if (raw.includes("ja")) return "ja";
264
+ if (raw.includes("ko")) return "ko";
265
+ if (raw.includes("pt")) return "pt";
266
+ return "en";
267
+ }
268
+ function createT(getLang) {
269
+ return (key, params) => {
270
+ const table = TRANSLATIONS[getLang()] ?? EN_T;
271
+ const template = table[key] ?? EN_T[key] ?? String(key);
272
+ if (!params) return template;
273
+ return template.replace(/\{(\w+)\}/g, (match, name) => params[name] ?? match);
274
+ };
275
+ }
276
+
277
+ // src/panel/FooterStatus.tsx
278
+ import { setProp as _$setProp } from "@opentui/solid";
279
+ import { effect as _$effect } from "@opentui/solid";
280
+ import { insert as _$insert } from "@opentui/solid";
281
+ import { createComponent as _$createComponent } from "@opentui/solid";
282
+ import { createElement as _$createElement } from "@opentui/solid";
283
+ import { memo as _$memo } from "@opentui/solid";
284
+ import { createMemo, For, Show } from "solid-js";
285
+ function FooterStatus(props) {
286
+ const t = createT(() => props.lang());
287
+ const segments = createMemo(() => {
288
+ const status = props.status();
289
+ if (!status) return [];
290
+ const {
291
+ normal,
292
+ muted,
293
+ warning
294
+ } = themeColors(props.context.theme);
295
+ const peak = status.period === "peak";
296
+ const label = peak ? t("period.peak") : t("period.offPeak");
297
+ const out = [{
298
+ text: `DS ${label}`,
299
+ color: peak ? normal : muted
300
+ }];
301
+ if (status.source === "api-header") out.push({
302
+ text: " API",
303
+ color: muted
304
+ });
305
+ if (status.mismatch) out.push({
306
+ text: " \u26A0",
307
+ color: warning
308
+ });
309
+ out.push({
310
+ text: " \xB7",
311
+ color: muted
312
+ });
313
+ return out;
314
+ });
315
+ return _$createComponent(Show, {
316
+ get when() {
317
+ return _$memo(() => !!props.enabled())() && props.status();
318
+ },
319
+ get children() {
320
+ var _el$ = _$createElement("text");
321
+ _$insert(_el$, _$createComponent(For, {
322
+ get each() {
323
+ return segments();
324
+ },
325
+ children: (segment) => (() => {
326
+ var _el$2 = _$createElement("span");
327
+ _$insert(_el$2, () => segment.text);
328
+ _$effect((_$p) => _$setProp(_el$2, "style", {
329
+ fg: segment.color
330
+ }, _$p));
331
+ return _el$2;
332
+ })()
333
+ }));
334
+ return _el$;
335
+ }
336
+ });
337
+ }
338
+
339
+ // src/panel/PeakPanel.tsx
340
+ import { effect as _$effect2 } from "@opentui/solid";
341
+ import { insertNode as _$insertNode } from "@opentui/solid";
342
+ import { insert as _$insert2 } from "@opentui/solid";
343
+ import { createComponent as _$createComponent2 } from "@opentui/solid";
344
+ import { setProp as _$setProp2 } from "@opentui/solid";
345
+ import { createElement as _$createElement2 } from "@opentui/solid";
346
+ import { memo as _$memo2 } from "@opentui/solid";
347
+ import { createEffect, createMemo as createMemo2, For as For2, Show as Show2 } from "solid-js";
348
+ function PeakPanel(props) {
349
+ const t = createT(() => props.lang());
350
+ createEffect(() => {
351
+ const sessionID = props.sessionID;
352
+ if (sessionID) props.refresh(sessionID);
353
+ });
354
+ const segments = createMemo2(() => {
355
+ const status = props.status();
356
+ if (!status) return [];
357
+ const {
358
+ normal,
359
+ muted,
360
+ warning
361
+ } = themeColors(props.context.theme);
362
+ const peak = status.period === "peak";
363
+ const out = [{
364
+ text: "DeepSeek ",
365
+ color: muted
366
+ }, {
367
+ text: `\u25CF ${t(peak ? "period.peak" : "period.offPeak")}`,
368
+ color: peak ? normal : muted
369
+ }];
370
+ if (status.source === "api-header") out.push({
371
+ text: " \xB7 API",
372
+ color: muted
373
+ });
374
+ if (status.mismatch) out.push({
375
+ text: ` \xB7 ${t("label.mismatch")} \u26A0`,
376
+ color: warning
377
+ });
378
+ return out;
379
+ });
380
+ return _$createComponent2(Show2, {
381
+ get when() {
382
+ return _$memo2(() => !!props.enabled())() && props.status();
383
+ },
384
+ get children() {
385
+ var _el$ = _$createElement2("box"), _el$2 = _$createElement2("text");
386
+ _$insertNode(_el$, _el$2);
387
+ _$setProp2(_el$, "flexDirection", "column");
388
+ _$setProp2(_el$, "alignItems", "flex-start");
389
+ _$setProp2(_el$, "alignSelf", "flex-start");
390
+ _$insert2(_el$2, _$createComponent2(For2, {
391
+ get each() {
392
+ return segments();
393
+ },
394
+ children: (segment) => (() => {
395
+ var _el$3 = _$createElement2("span");
396
+ _$insert2(_el$3, () => segment.text);
397
+ _$effect2((_$p) => _$setProp2(_el$3, "style", {
398
+ fg: segment.color
399
+ }, _$p));
400
+ return _el$3;
401
+ })()
402
+ }));
403
+ _$insert2(_el$, _$createComponent2(Show2, {
404
+ get when() {
405
+ return _$memo2(() => !!props.evidence())() ? props.status() : void 0;
406
+ },
407
+ children: (status) => (() => {
408
+ var _el$4 = _$createElement2("text");
409
+ _$insert2(_el$4, () => evidenceLabel(status(), t));
410
+ _$effect2((_$p) => _$setProp2(_el$4, "fg", themeColors(props.context.theme).muted, _$p));
411
+ return _el$4;
412
+ })()
413
+ }), null);
414
+ return _el$;
415
+ }
416
+ });
417
+ }
418
+
419
+ // src/rpc.ts
420
+ import { Rpc } from "@opencode/plugin/rpc";
421
+ var statusSchema = {
422
+ type: "object",
423
+ properties: {
424
+ sessionID: { type: "string" },
425
+ providerID: { type: "string" },
426
+ modelID: { type: "string" },
427
+ period: { type: "string", enum: ["peak", "off-peak"] },
428
+ scheduledPeriod: { type: "string", enum: ["peak", "off-peak"] },
429
+ source: { type: "string", enum: ["official-schedule", "api-header"] },
430
+ phase: { type: "string", enum: ["request", "response"] },
431
+ mismatch: { type: "boolean" },
432
+ observedAt: { type: "number" },
433
+ evidence: { type: "string" },
434
+ holiday: { type: "string" }
435
+ },
436
+ required: [
437
+ "sessionID",
438
+ "providerID",
439
+ "modelID",
440
+ "period",
441
+ "scheduledPeriod",
442
+ "source",
443
+ "phase",
444
+ "mismatch",
445
+ "observedAt",
446
+ "evidence"
447
+ ],
448
+ additionalProperties: false
449
+ };
450
+ var DeepSeekPeakRpc = Rpc.define({
451
+ id: "deepseek-peak",
452
+ methods: {
453
+ status: {
454
+ input: {
455
+ type: "object",
456
+ properties: { sessionID: { type: "string" } },
457
+ required: ["sessionID"],
458
+ additionalProperties: false
459
+ },
460
+ output: {
461
+ type: "object",
462
+ properties: {
463
+ found: { type: "boolean" },
464
+ status: statusSchema
465
+ },
466
+ required: ["found"],
467
+ additionalProperties: false
468
+ }
469
+ },
470
+ preview: {
471
+ input: {
472
+ type: "object",
473
+ properties: { sessionID: { type: "string" } },
474
+ required: ["sessionID"],
475
+ additionalProperties: false
476
+ },
477
+ output: {
478
+ type: "object",
479
+ properties: {
480
+ found: { type: "boolean" },
481
+ status: statusSchema
482
+ },
483
+ required: ["found"],
484
+ additionalProperties: false
485
+ }
486
+ }
487
+ },
488
+ events: {
489
+ updated: { schema: statusSchema }
490
+ }
491
+ });
492
+
493
+ // src/v2/settings-menu.ts
494
+ var nextTick = () => new Promise((resolve) => setTimeout(resolve, 0));
495
+ function openSettingsMenu(context, settings, update, lang) {
496
+ const t = createT(lang);
497
+ const onOff = (value) => value ? t("settings.on") : t("settings.off");
498
+ const pickBool = (title, current) => context.ui.dialog.select({
499
+ title,
500
+ options: [
501
+ { title: t("settings.on"), value: true },
502
+ { title: t("settings.off"), value: false }
503
+ ],
504
+ current
505
+ });
506
+ void (async () => {
507
+ while (true) {
508
+ const choice = await context.ui.dialog.select({
509
+ title: t("settings.title"),
510
+ options: [
511
+ { title: `${t("settings.toast")}: ${onOff(settings.toast)}`, value: "toast" },
512
+ { title: `${t("settings.footer")}: ${onOff(settings.indicator)}`, value: "indicator" },
513
+ { title: `${t("settings.sidebar")}: ${onOff(settings.sidebarIndicator !== false)}`, value: "sidebar" },
514
+ { title: `${t("settings.evidence")}: ${onOff(settings.sidebarEvidence !== false)}`, value: "evidence" },
515
+ {
516
+ title: `${t("settings.frequency")}: ${settings.toastEveryRequest ? t("frequency.every") : t("frequency.change")}`,
517
+ value: "frequency"
518
+ },
519
+ {
520
+ title: `${t("settings.lang")}: ${LANG_META.find((meta) => meta.code === lang())?.label ?? lang()}`,
521
+ value: "lang"
522
+ }
523
+ ]
524
+ });
525
+ if (choice === void 0) return;
526
+ if (choice === "toast") {
527
+ const picked = await pickBool(t("settings.toast"), settings.toast);
528
+ if (picked !== void 0) {
529
+ await update((draft) => {
530
+ draft.toast = picked;
531
+ });
532
+ }
533
+ } else if (choice === "indicator") {
534
+ const picked = await pickBool(t("settings.footer"), settings.indicator);
535
+ if (picked !== void 0) {
536
+ await update((draft) => {
537
+ draft.indicator = picked;
538
+ });
539
+ }
540
+ } else if (choice === "sidebar") {
541
+ const picked = await pickBool(t("settings.sidebar"), settings.sidebarIndicator !== false);
542
+ if (picked !== void 0) {
543
+ await update((draft) => {
544
+ draft.sidebarIndicator = picked;
545
+ });
546
+ }
547
+ } else if (choice === "evidence") {
548
+ const picked = await pickBool(t("settings.evidence"), settings.sidebarEvidence !== false);
549
+ if (picked !== void 0) {
550
+ await update((draft) => {
551
+ draft.sidebarEvidence = picked;
552
+ });
553
+ }
554
+ } else if (choice === "frequency") {
555
+ const picked = await context.ui.dialog.select({
556
+ title: t("settings.frequency"),
557
+ options: [
558
+ { title: t("frequency.change"), value: "change" },
559
+ { title: t("frequency.every"), value: "every" }
560
+ ],
561
+ current: settings.toastEveryRequest ? "every" : "change"
562
+ });
563
+ if (picked !== void 0) {
564
+ await update((draft) => {
565
+ draft.toastEveryRequest = picked === "every";
566
+ });
567
+ }
568
+ } else if (choice === "lang") {
569
+ const picked = await context.ui.dialog.select({
570
+ title: t("settings.lang"),
571
+ options: LANG_META.map((meta) => ({ title: meta.label, value: meta.code })),
572
+ current: lang()
573
+ });
574
+ if (picked !== void 0) {
575
+ await update((draft) => {
576
+ draft.lang = picked;
577
+ });
578
+ }
579
+ }
580
+ await nextTick();
581
+ }
582
+ })();
583
+ }
584
+
585
+ // src/v2/commands.ts
586
+ function CommandRoot(props) {
587
+ const { context } = props;
588
+ const t = createT(() => props.lang());
589
+ context.keymap.layer(() => ({
590
+ mode: "global",
591
+ commands: [
592
+ {
593
+ id: "opencode-deepseek-peak.peak.status",
594
+ title: t("command.status.title"),
595
+ description: t("command.status.description"),
596
+ group: "DeepSeek",
597
+ palette: true,
598
+ slash: { name: "deepseek-peak" },
599
+ run: async () => {
600
+ const route = context.ui.router.current();
601
+ if (route.type !== "session") {
602
+ await context.ui.dialog.alert({ title: t("status.title"), message: t("status.noSession") });
603
+ return;
604
+ }
605
+ try {
606
+ const status = await props.readStatus(route.sessionID);
607
+ await context.ui.dialog.alert({
608
+ title: t("status.title"),
609
+ message: status ? `${statusLabel(status, t)}
610
+ ${t("status.source")}: ${status.source}
611
+ ${t("status.evidence")}: ${status.evidence}` : t("status.noRequest")
612
+ });
613
+ } catch {
614
+ context.ui.toast.show({ message: t("status.unavailable"), variant: "error" });
615
+ }
616
+ }
617
+ },
618
+ {
619
+ id: "opencode-deepseek-peak.peak.sections",
620
+ title: t("command.sections.title"),
621
+ description: t("command.sections.description"),
622
+ group: "DeepSeek",
623
+ palette: true,
624
+ slash: { name: "deepseek-peak-sections" },
625
+ run: () => {
626
+ openSettingsMenu(context, props.settings, props.update, props.lang);
627
+ }
628
+ },
629
+ {
630
+ id: "opencode-deepseek-peak.peak.lang",
631
+ title: t("command.lang.title"),
632
+ description: t("command.lang.description"),
633
+ group: "DeepSeek",
634
+ palette: true,
635
+ slash: { name: "deepseek-peak-lang" },
636
+ run: async () => {
637
+ const picked = await context.ui.dialog.select({
638
+ title: t("settings.lang"),
639
+ options: LANG_META.map((meta) => ({ title: meta.label, value: meta.code })),
640
+ current: props.lang()
641
+ });
642
+ if (picked !== void 0) {
643
+ await props.update((draft) => {
644
+ draft.lang = picked;
645
+ });
646
+ }
647
+ }
648
+ }
649
+ ]
650
+ }));
651
+ return null;
652
+ }
653
+
654
+ // src/tui.tsx
655
+ var mod = {
656
+ id: "opencode-deepseek-peak-tui",
657
+ setup(context) {
658
+ const client = context.client.rpc(DeepSeekPeakRpc);
659
+ const [settings, update] = context.storage.store("opencode-deepseek-peak.settings", {
660
+ initial: {
661
+ ...INITIAL_SETTINGS,
662
+ lang: detectLang()
663
+ }
664
+ });
665
+ const lang = () => settings.lang ?? detectLang();
666
+ const t = createT(lang);
667
+ const [statuses, setStatuses] = createSignal({});
668
+ const lastToast = /* @__PURE__ */ new Map();
669
+ const unsubscribe = client.events.on("updated", (event) => {
670
+ const status = event.data;
671
+ setStatuses((current) => ({
672
+ ...current,
673
+ [status.sessionID]: status
674
+ }));
675
+ if (!settings.toast) return;
676
+ const fingerprint = `${status.period}:${status.mismatch}`;
677
+ if (!settings.toastEveryRequest && lastToast.get(status.sessionID) === fingerprint) return;
678
+ lastToast.set(status.sessionID, fingerprint);
679
+ context.ui.toast.show({
680
+ title: t("toast.title"),
681
+ message: statusLabel(status, t),
682
+ variant: status.period === "peak" ? "warning" : "success",
683
+ duration: 4500
684
+ });
685
+ });
686
+ const readStatus = async (sessionID) => {
687
+ const result = await client.status({
688
+ sessionID
689
+ });
690
+ if (result.found && result.status) return result.status;
691
+ try {
692
+ const preview = await client.preview({
693
+ sessionID
694
+ });
695
+ return preview.found ? preview.status : void 0;
696
+ } catch {
697
+ return void 0;
698
+ }
699
+ };
700
+ const refresh = (sessionID) => {
701
+ void readStatus(sessionID).then((status) => {
702
+ if (status) setStatuses((current) => ({
703
+ ...current,
704
+ [status.sessionID]: status
705
+ }));
706
+ }).catch(() => {
707
+ });
708
+ };
709
+ const unregisterCommands = context.ui.slot({
710
+ append: "app",
711
+ render: () => _$createComponent3(CommandRoot, {
712
+ context,
713
+ settings,
714
+ update,
715
+ readStatus,
716
+ lang
717
+ })
718
+ });
719
+ const unregisterSidebar = context.ui.slot({
720
+ append: "sidebar.content",
721
+ render: (props) => {
722
+ const sessionID = String(props.sessionID ?? "");
723
+ return _$createComponent3(PeakPanel, {
724
+ context,
725
+ status: () => statuses()[sessionID],
726
+ enabled: () => settings.sidebarIndicator !== false,
727
+ evidence: () => settings.sidebarEvidence !== false,
728
+ lang,
729
+ sessionID,
730
+ refresh
731
+ });
732
+ }
733
+ });
734
+ const unregisterFooter = context.ui.slot({
735
+ append: "prompt.footer.status",
736
+ render: (props) => {
737
+ const sessionID = String(props.sessionID ?? "");
738
+ return _$createComponent3(FooterStatus, {
739
+ context,
740
+ status: () => statuses()[sessionID],
741
+ enabled: () => settings.indicator,
742
+ lang,
743
+ sessionID,
744
+ refresh
745
+ });
746
+ }
747
+ });
748
+ return () => {
749
+ unsubscribe();
750
+ unregisterCommands();
751
+ unregisterSidebar();
752
+ unregisterFooter();
753
+ };
754
+ }
755
+ };
756
+ var tui_default = mod;
757
+ export {
758
+ tui_default as default
759
+ };
760
+ //# sourceMappingURL=tui.js.map