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/LICENSE +21 -0
- package/README.md +79 -0
- package/dist/index.js +47817 -0
- package/dist/index.js.map +7 -0
- package/dist/rpc.js +77 -0
- package/dist/rpc.js.map +7 -0
- package/dist/tui.js +760 -0
- package/dist/tui.js.map +7 -0
- package/index.js +1 -0
- package/install.mjs +63 -0
- package/package.json +70 -0
- package/src/api-signal.ts +32 -0
- package/src/core/display.ts +59 -0
- package/src/i18n.ts +248 -0
- package/src/index.ts +131 -0
- package/src/panel/FooterStatus.tsx +32 -0
- package/src/panel/PeakPanel.tsx +59 -0
- package/src/rpc.ts +74 -0
- package/src/schedule.ts +66 -0
- package/src/tui.tsx +112 -0
- package/src/types.ts +29 -0
- package/src/v2/commands.ts +83 -0
- package/src/v2/settings-menu.ts +110 -0
- package/tui/index.js +6 -0
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
|