opencode-go-usage-tui 1.0.1 → 1.2.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 +24 -1
- package/README_EN.md +117 -0
- package/build.tui.mjs +5 -1
- package/dist/tui.js +406 -114
- package/package.json +3 -2
- package/src/i18n.ts +108 -0
- package/src/index.tsx +210 -74
package/dist/tui.js
CHANGED
|
@@ -9,44 +9,245 @@ import { insertNode as _$insertNode } from "@opentui/solid";
|
|
|
9
9
|
import { insert as _$insert } from "@opentui/solid";
|
|
10
10
|
import { createElement as _$createElement } from "@opentui/solid";
|
|
11
11
|
import { createSignal, createEffect, onMount, onCleanup, Show } from "solid-js";
|
|
12
|
-
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
12
|
+
import { readFileSync, writeFileSync, mkdirSync, renameSync, existsSync } from "node:fs";
|
|
13
13
|
import { join, dirname } from "node:path";
|
|
14
|
+
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
15
|
+
|
|
16
|
+
// src/i18n.ts
|
|
17
|
+
var ZH_T = {
|
|
18
|
+
panelTitle: "Go \u7528\u91CF",
|
|
19
|
+
rowRolling: "5\u5C0F\u65F6\u7528\u91CF",
|
|
20
|
+
rowWeekly: "\u6BCF\u5468\u7528\u91CF",
|
|
21
|
+
rowMonthly: "\u6BCF\u6708\u7528\u91CF",
|
|
22
|
+
weeklyShort: "\u5468",
|
|
23
|
+
updatedAt: "\u6700\u8FD1\u66F4\u65B0",
|
|
24
|
+
notConfigured: "\u672A\u914D\u7F6E\u8D26\u53F7",
|
|
25
|
+
notConfiguredHint: "\u8F93\u5165 /go-config \u8BBE\u7F6E",
|
|
26
|
+
loading: "\u52A0\u8F7D\u4E2D...",
|
|
27
|
+
queryFailed: "\u67E5\u8BE2\u5931\u8D25",
|
|
28
|
+
cookieExpired: "cookie \u5DF2\u8FC7\u671F",
|
|
29
|
+
reconfigureHint: "\u8F93\u5165 /go-config \u91CD\u65B0\u914D\u7F6E",
|
|
30
|
+
resetDone: "\u5DF2\u91CD\u7F6E",
|
|
31
|
+
dayHour: "{d}\u5929{h}\u5C0F\u65F6",
|
|
32
|
+
hourMin: "{h}\u5C0F\u65F6{m}\u5206\u949F",
|
|
33
|
+
minute: "{m}\u5206\u949F",
|
|
34
|
+
cmdTitle: "Go Usage: Configure",
|
|
35
|
+
cmdDesc: "\u8BBE\u7F6E OpenCode Go workspace ID \u548C auth cookie",
|
|
36
|
+
wsPromptTitle: "\u8F93\u5165 workspace_id",
|
|
37
|
+
wsPromptDesc: "\u5728 opencode.ai \u63A7\u5236\u53F0 URL \u4E2D\u83B7\u53D6\uFF08wrk_ \u5F00\u5934\uFF09",
|
|
38
|
+
wsPlaceholder: "wrk_xxxxxxxxxxxx",
|
|
39
|
+
cookiePromptTitle: "\u8F93\u5165 auth cookie",
|
|
40
|
+
cookiePromptDesc: "\u767B\u5F55 opencode.ai \u540E\uFF0C\u6D4F\u89C8\u5668 F12 \u2192 Application \u2192 Cookies \u2192 opencode.ai \u2192 \u590D\u5236 auth \u7684\u503C",
|
|
41
|
+
cookiePlaceholder: "Fe26.2*...",
|
|
42
|
+
configSaved: "Go \u7528\u91CF\u914D\u7F6E\u5DF2\u4FDD\u5B58",
|
|
43
|
+
langTitle: "\u663E\u793A\u8BED\u8A00",
|
|
44
|
+
langCmdTitle: "Go Usage: Language",
|
|
45
|
+
langCmdDesc: "\u5207\u6362\u663E\u793A\u8BED\u8A00 | Switch display language",
|
|
46
|
+
langSwitchedZh: "\u5DF2\u5207\u6362\u4E3A\u4E2D\u6587",
|
|
47
|
+
langSwitchedEn: "Switched to English",
|
|
48
|
+
onboardLangTitle: "Welcome to Go Usage / \u6B22\u8FCE\u4F7F\u7528 Go \u7528\u91CF",
|
|
49
|
+
onboardLangDesc: "Choose display language / \u9009\u62E9\u663E\u793A\u8BED\u8A00",
|
|
50
|
+
onboardConfigTitle: "Welcome to Go Usage / \u6B22\u8FCE\u4F7F\u7528 Go \u7528\u91CF",
|
|
51
|
+
onboardConfigDesc: "First-time setup / \u9996\u6B21\u4F7F\u7528\u9700\u914D\u7F6E\u8D26\u53F7",
|
|
52
|
+
setupCanceled: "\u5DF2\u53D6\u6D88\u914D\u7F6E\uFF0C\u8F93\u5165 /go-config \u53EF\u91CD\u65B0\u8BBE\u7F6E"
|
|
53
|
+
};
|
|
54
|
+
var EN_T = {
|
|
55
|
+
panelTitle: "Go Usage",
|
|
56
|
+
rowRolling: "5h usage",
|
|
57
|
+
rowWeekly: "Weekly",
|
|
58
|
+
rowMonthly: "Monthly",
|
|
59
|
+
weeklyShort: "Wk",
|
|
60
|
+
updatedAt: "Updated",
|
|
61
|
+
notConfigured: "Not configured",
|
|
62
|
+
notConfiguredHint: "Run /go-config to set up",
|
|
63
|
+
loading: "Loading...",
|
|
64
|
+
queryFailed: "Query failed",
|
|
65
|
+
cookieExpired: "Cookie expired",
|
|
66
|
+
reconfigureHint: "Run /go-config to reconfigure",
|
|
67
|
+
resetDone: "Reset",
|
|
68
|
+
dayHour: "{d}d {h}h",
|
|
69
|
+
hourMin: "{h}h {m}m",
|
|
70
|
+
minute: "{m}m",
|
|
71
|
+
cmdTitle: "Go Usage: Configure",
|
|
72
|
+
cmdDesc: "Set OpenCode Go workspace ID and auth cookie",
|
|
73
|
+
wsPromptTitle: "Enter workspace_id",
|
|
74
|
+
wsPromptDesc: "Get it from the opencode.ai console URL (starts with wrk_)",
|
|
75
|
+
wsPlaceholder: "wrk_xxxxxxxxxxxx",
|
|
76
|
+
cookiePromptTitle: "Enter auth cookie",
|
|
77
|
+
cookiePromptDesc: "After logging into opencode.ai, press F12 \u2192 Application \u2192 Cookies \u2192 opencode.ai \u2192 copy the auth value",
|
|
78
|
+
cookiePlaceholder: "Fe26.2*...",
|
|
79
|
+
configSaved: "Go usage config saved",
|
|
80
|
+
langTitle: "Display language",
|
|
81
|
+
langCmdTitle: "Go Usage: Language",
|
|
82
|
+
langCmdDesc: "\u5207\u6362\u663E\u793A\u8BED\u8A00 | Switch display language",
|
|
83
|
+
langSwitchedZh: "\u5DF2\u5207\u6362\u4E3A\u4E2D\u6587",
|
|
84
|
+
langSwitchedEn: "Switched to English",
|
|
85
|
+
onboardLangTitle: "Welcome to Go Usage / \u6B22\u8FCE\u4F7F\u7528 Go \u7528\u91CF",
|
|
86
|
+
onboardLangDesc: "Choose display language / \u9009\u62E9\u663E\u793A\u8BED\u8A00",
|
|
87
|
+
onboardConfigTitle: "Welcome to Go Usage / \u6B22\u8FCE\u4F7F\u7528 Go \u7528\u91CF",
|
|
88
|
+
onboardConfigDesc: "First-time setup / \u9996\u6B21\u4F7F\u7528\u9700\u914D\u7F6E\u8D26\u53F7",
|
|
89
|
+
setupCanceled: "Setup canceled, run /go-config to reconfigure"
|
|
90
|
+
};
|
|
91
|
+
var LANGS = { zh: ZH_T, en: EN_T };
|
|
92
|
+
var LANG_META = [
|
|
93
|
+
{ code: "zh", label: "\u4E2D\u6587" },
|
|
94
|
+
{ code: "en", label: "English" }
|
|
95
|
+
];
|
|
96
|
+
function applyParams(tpl, params) {
|
|
97
|
+
if (!params) return tpl;
|
|
98
|
+
return tpl.replace(
|
|
99
|
+
/\{(\w+)\}/g,
|
|
100
|
+
(m, k) => k in params ? String(params[k]) : m
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
function createT(getCode) {
|
|
104
|
+
return (key, params) => applyParams(LANGS[getCode()][key], params);
|
|
105
|
+
}
|
|
106
|
+
function detectLang() {
|
|
107
|
+
try {
|
|
108
|
+
const loc = Intl.DateTimeFormat().resolvedOptions().locale.toLowerCase();
|
|
109
|
+
if (loc.startsWith("zh")) return "zh";
|
|
110
|
+
return "en";
|
|
111
|
+
} catch {
|
|
112
|
+
return "en";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/index.tsx
|
|
117
|
+
var VERSION = "1.2.0";
|
|
14
118
|
var CHECK_INTERVAL = Number(process?.env?.OPENCODE_GO_CHECK_INTERVAL ?? 6e4);
|
|
15
119
|
var WARN_THRESHOLD = Number(process?.env?.OPENCODE_GO_WARN_THRESHOLD ?? 0.8);
|
|
16
120
|
var CONFIG_DIR = process?.env?.OPENCODE_CONFIG_DIR || (process?.env?.USERPROFILE ? `${process.env.USERPROFILE}\\.config\\opencode` : "") || process?.env?.HOME + "/.config/opencode";
|
|
17
121
|
var CONFIG_FILE = join(CONFIG_DIR, "go-usage-config.json");
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
122
|
+
var COOKIE_ENC_FILE = join(CONFIG_DIR, "go-auth-cookie.enc");
|
|
123
|
+
var KEY_FILE = join(CONFIG_DIR, ".encryption-key");
|
|
124
|
+
var COOKIE_PLAIN_FILE = `${CONFIG_DIR}\\go-auth-cookie.txt`;
|
|
125
|
+
var KV_PREFIX = "go-usage";
|
|
126
|
+
function loadEncryptionKey() {
|
|
127
|
+
try {
|
|
128
|
+
const hex2 = readFileSync(KEY_FILE, "utf8").trim();
|
|
129
|
+
if (hex2) return Buffer.from(hex2, "hex");
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
const key = randomBytes(32);
|
|
133
|
+
mkdirSync(dirname(KEY_FILE), {
|
|
134
|
+
recursive: true
|
|
135
|
+
});
|
|
136
|
+
writeFileSync(KEY_FILE, key.toString("hex"), {
|
|
137
|
+
encoding: "utf8",
|
|
138
|
+
mode: 384
|
|
139
|
+
});
|
|
140
|
+
return key;
|
|
141
|
+
}
|
|
142
|
+
function encryptText(text) {
|
|
143
|
+
const key = loadEncryptionKey();
|
|
144
|
+
const iv = randomBytes(16);
|
|
145
|
+
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
146
|
+
const data = cipher.update(text, "utf8", "hex") + cipher.final("hex");
|
|
147
|
+
return JSON.stringify({
|
|
148
|
+
v: 1,
|
|
149
|
+
iv: iv.toString("hex"),
|
|
150
|
+
data,
|
|
151
|
+
tag: cipher.getAuthTag().toString("hex")
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
function decryptText(encJson) {
|
|
155
|
+
const {
|
|
156
|
+
iv,
|
|
157
|
+
data,
|
|
158
|
+
tag
|
|
159
|
+
} = JSON.parse(encJson);
|
|
160
|
+
const key = loadEncryptionKey();
|
|
161
|
+
const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(iv, "hex"));
|
|
162
|
+
decipher.setAuthTag(Buffer.from(tag, "hex"));
|
|
163
|
+
return decipher.update(data, "hex", "utf8") + decipher.final("utf8");
|
|
164
|
+
}
|
|
165
|
+
function readJsonFile(file) {
|
|
21
166
|
try {
|
|
22
|
-
|
|
167
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
23
168
|
} catch {
|
|
24
|
-
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function loadConfig() {
|
|
173
|
+
const env = process?.env ?? {};
|
|
174
|
+
const fileCfg = readJsonFile(CONFIG_FILE) ?? {};
|
|
175
|
+
if (env.OPENCODE_GO_AUTH_COOKIE) {
|
|
176
|
+
return {
|
|
177
|
+
workspaceId: env.OPENCODE_GO_WORKSPACE_ID || fileCfg.workspace_id || "",
|
|
178
|
+
authCookie: env.OPENCODE_GO_AUTH_COOKIE
|
|
179
|
+
};
|
|
25
180
|
}
|
|
26
|
-
const cookieFile = env.OPENCODE_GO_COOKIE_FILE || fileCfg.cookie_file || `${CONFIG_DIR}\\go-auth-cookie.txt`;
|
|
27
|
-
let fileCookie = "";
|
|
28
181
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
182
|
+
if (existsSync(COOKIE_ENC_FILE)) {
|
|
183
|
+
const cookie = decryptText(readFileSync(COOKIE_ENC_FILE, "utf8"));
|
|
184
|
+
if (cookie) {
|
|
185
|
+
return {
|
|
186
|
+
workspaceId: env.OPENCODE_GO_WORKSPACE_ID || fileCfg.workspace_id || "",
|
|
187
|
+
authCookie: cookie
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
33
191
|
} catch {
|
|
34
|
-
|
|
192
|
+
}
|
|
193
|
+
const legacyCookie = fileCfg.auth_cookie || fileCfg.cookie || (() => {
|
|
194
|
+
try {
|
|
195
|
+
return readFileSync(COOKIE_PLAIN_FILE, "utf8").trim();
|
|
196
|
+
} catch {
|
|
197
|
+
return "";
|
|
198
|
+
}
|
|
199
|
+
})();
|
|
200
|
+
if (legacyCookie) {
|
|
201
|
+
const enc = encryptText(legacyCookie);
|
|
202
|
+
mkdirSync(CONFIG_DIR, {
|
|
203
|
+
recursive: true
|
|
204
|
+
});
|
|
205
|
+
writeFileSync(COOKIE_ENC_FILE, enc, "utf8");
|
|
206
|
+
const cleanCfg = {
|
|
207
|
+
...fileCfg
|
|
208
|
+
};
|
|
209
|
+
delete cleanCfg.cookie;
|
|
210
|
+
delete cleanCfg.auth_cookie;
|
|
211
|
+
try {
|
|
212
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(cleanCfg, null, 2), "utf8");
|
|
213
|
+
} catch {
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
if (existsSync(COOKIE_PLAIN_FILE)) renameSync(COOKIE_PLAIN_FILE, COOKIE_PLAIN_FILE + ".bak");
|
|
217
|
+
} catch {
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
workspaceId: env.OPENCODE_GO_WORKSPACE_ID || fileCfg.workspace_id || "",
|
|
221
|
+
authCookie: legacyCookie
|
|
222
|
+
};
|
|
35
223
|
}
|
|
36
224
|
return {
|
|
37
225
|
workspaceId: env.OPENCODE_GO_WORKSPACE_ID || fileCfg.workspace_id || "",
|
|
38
|
-
authCookie:
|
|
226
|
+
authCookie: ""
|
|
39
227
|
};
|
|
40
228
|
}
|
|
41
229
|
function saveConfig(patch) {
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
fileCfg = JSON.parse(readFileSync(CONFIG_FILE, "utf8"));
|
|
45
|
-
} catch {
|
|
46
|
-
fileCfg = {};
|
|
47
|
-
}
|
|
230
|
+
const fileCfg = readJsonFile(CONFIG_FILE) ?? {};
|
|
48
231
|
if (patch.workspace_id !== void 0) fileCfg.workspace_id = patch.workspace_id;
|
|
49
|
-
if (patch.cookie !== void 0)
|
|
232
|
+
if (patch.cookie !== void 0) {
|
|
233
|
+
if (patch.cookie) {
|
|
234
|
+
mkdirSync(CONFIG_DIR, {
|
|
235
|
+
recursive: true
|
|
236
|
+
});
|
|
237
|
+
writeFileSync(COOKIE_ENC_FILE, encryptText(patch.cookie), "utf8");
|
|
238
|
+
delete fileCfg.cookie;
|
|
239
|
+
delete fileCfg.auth_cookie;
|
|
240
|
+
try {
|
|
241
|
+
if (existsSync(COOKIE_PLAIN_FILE)) renameSync(COOKIE_PLAIN_FILE, COOKIE_PLAIN_FILE + ".bak");
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
try {
|
|
246
|
+
if (existsSync(COOKIE_ENC_FILE)) renameSync(COOKIE_ENC_FILE, COOKIE_ENC_FILE + ".bak");
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
50
251
|
try {
|
|
51
252
|
mkdirSync(dirname(CONFIG_FILE), {
|
|
52
253
|
recursive: true
|
|
@@ -56,6 +257,21 @@ function saveConfig(patch) {
|
|
|
56
257
|
}
|
|
57
258
|
}
|
|
58
259
|
var [configTick, setConfigTick] = createSignal(0);
|
|
260
|
+
var [langCode, setLangCode] = createSignal(detectLang());
|
|
261
|
+
var t = createT(() => langCode());
|
|
262
|
+
function kvTryGet(api, key) {
|
|
263
|
+
try {
|
|
264
|
+
return api.kv.get(key);
|
|
265
|
+
} catch {
|
|
266
|
+
return void 0;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function kvTrySet(api, key, val) {
|
|
270
|
+
try {
|
|
271
|
+
api.kv.set(key, val);
|
|
272
|
+
} catch {
|
|
273
|
+
}
|
|
274
|
+
}
|
|
59
275
|
async function fetchUsage(workspaceId, authCookie) {
|
|
60
276
|
if (!workspaceId || !authCookie) return {
|
|
61
277
|
error: "not_configured"
|
|
@@ -119,13 +335,21 @@ async function fetchUsage(workspaceId, authCookie) {
|
|
|
119
335
|
}
|
|
120
336
|
}
|
|
121
337
|
function formatReset(sec) {
|
|
122
|
-
if (sec <= 0) return "
|
|
338
|
+
if (sec <= 0) return t("resetDone");
|
|
123
339
|
const d = Math.floor(sec / 86400);
|
|
124
340
|
const h = Math.floor(sec % 86400 / 3600);
|
|
125
341
|
const m = Math.floor(sec % 3600 / 60);
|
|
126
|
-
if (d > 0) return
|
|
127
|
-
|
|
128
|
-
|
|
342
|
+
if (d > 0) return t("dayHour", {
|
|
343
|
+
d,
|
|
344
|
+
h
|
|
345
|
+
});
|
|
346
|
+
if (h > 0) return t("hourMin", {
|
|
347
|
+
h,
|
|
348
|
+
m
|
|
349
|
+
});
|
|
350
|
+
return t("minute", {
|
|
351
|
+
m
|
|
352
|
+
});
|
|
129
353
|
}
|
|
130
354
|
function progressBar(percent, width) {
|
|
131
355
|
const clamped = Math.max(0, Math.min(100, percent));
|
|
@@ -177,11 +401,11 @@ function GoUsagePanel(props) {
|
|
|
177
401
|
setConfigured(true);
|
|
178
402
|
const u = await fetchUsage(cfg.workspaceId, cfg.authCookie);
|
|
179
403
|
if (u === null) {
|
|
180
|
-
setError("
|
|
404
|
+
setError(t("queryFailed"));
|
|
181
405
|
return;
|
|
182
406
|
}
|
|
183
407
|
if (u.error === "cookie_expired") {
|
|
184
|
-
setError("
|
|
408
|
+
setError(t("cookieExpired"));
|
|
185
409
|
return;
|
|
186
410
|
}
|
|
187
411
|
if (u.error === "not_configured") {
|
|
@@ -208,12 +432,12 @@ function GoUsagePanel(props) {
|
|
|
208
432
|
...FALLBACK
|
|
209
433
|
});
|
|
210
434
|
createEffect(() => {
|
|
211
|
-
const
|
|
435
|
+
const th = props.theme;
|
|
212
436
|
const p = {
|
|
213
437
|
...FALLBACK
|
|
214
438
|
};
|
|
215
439
|
for (const k of Object.keys(FALLBACK)) {
|
|
216
|
-
const h = hex(
|
|
440
|
+
const h = hex(th?.[k]);
|
|
217
441
|
if (h) p[k] = h;
|
|
218
442
|
}
|
|
219
443
|
setPal(p);
|
|
@@ -271,7 +495,7 @@ function GoUsagePanel(props) {
|
|
|
271
495
|
};
|
|
272
496
|
const sep = () => "\u2500".repeat(Math.max(1, panelWidth() - 4));
|
|
273
497
|
return (() => {
|
|
274
|
-
var _el$1 = _$createElement("box"), _el$10 = _$createElement("text"), _el$11 = _$createElement("span"), _el$12 = _$createElement("span"), _el$13 = _$createElement("b");
|
|
498
|
+
var _el$1 = _$createElement("box"), _el$10 = _$createElement("text"), _el$11 = _$createElement("span"), _el$12 = _$createElement("span"), _el$13 = _$createElement("b"), _el$14 = _$createElement("span"), _el$15 = _$createTextNode(` v`);
|
|
275
499
|
_$insertNode(_el$1, _el$10);
|
|
276
500
|
var _ref$ = boxEl;
|
|
277
501
|
typeof _ref$ === "function" ? _$use(_ref$, _el$1) : boxEl = _el$1;
|
|
@@ -286,23 +510,28 @@ function GoUsagePanel(props) {
|
|
|
286
510
|
});
|
|
287
511
|
_$insertNode(_el$10, _el$11);
|
|
288
512
|
_$insertNode(_el$10, _el$12);
|
|
513
|
+
_$insertNode(_el$10, _el$14);
|
|
289
514
|
_$setProp(_el$10, "onMouseUp", () => setOpen((o) => !o));
|
|
290
515
|
_$insert(_el$11, () => open() ? "\u25BC " : "\u25B6 ");
|
|
291
516
|
_$insertNode(_el$12, _el$13);
|
|
292
|
-
_$
|
|
517
|
+
_$insert(_el$13, () => t("panelTitle"));
|
|
518
|
+
_$insertNode(_el$14, _el$15);
|
|
519
|
+
_$insert(_el$14, VERSION, null);
|
|
293
520
|
_$insert(_el$10, _$createComponent(Show, {
|
|
294
521
|
get when() {
|
|
295
522
|
return _$memo(() => !!!open())() && usage();
|
|
296
523
|
},
|
|
297
524
|
get children() {
|
|
298
|
-
var _el$
|
|
299
|
-
_$insertNode(_el$
|
|
300
|
-
_$insertNode(_el$
|
|
301
|
-
_$
|
|
302
|
-
_$
|
|
525
|
+
var _el$16 = _$createElement("span"), _el$17 = _$createTextNode(` `), _el$18 = _$createTextNode(` `), _el$19 = _$createTextNode(`%`);
|
|
526
|
+
_$insertNode(_el$16, _el$17);
|
|
527
|
+
_$insertNode(_el$16, _el$18);
|
|
528
|
+
_$insertNode(_el$16, _el$19);
|
|
529
|
+
_$insert(_el$16, () => t("weeklyShort"), _el$18);
|
|
530
|
+
_$insert(_el$16, () => usage().weeklyUsage.usagePercent, _el$19);
|
|
531
|
+
_$effect((_$p) => _$setProp(_el$16, "style", {
|
|
303
532
|
fg: colorFor(usage().weeklyUsage.usagePercent)
|
|
304
533
|
}, _$p));
|
|
305
|
-
return _el$
|
|
534
|
+
return _el$16;
|
|
306
535
|
}
|
|
307
536
|
}), null);
|
|
308
537
|
_$insert(_el$1, _$createComponent(Show, {
|
|
@@ -311,23 +540,23 @@ function GoUsagePanel(props) {
|
|
|
311
540
|
},
|
|
312
541
|
get children() {
|
|
313
542
|
return [(() => {
|
|
314
|
-
var _el$
|
|
315
|
-
_$insert(_el$
|
|
316
|
-
_$effect((_$p) => _$setProp(_el$
|
|
317
|
-
return _el$
|
|
543
|
+
var _el$20 = _$createElement("text");
|
|
544
|
+
_$insert(_el$20, sep);
|
|
545
|
+
_$effect((_$p) => _$setProp(_el$20, "fg", colors().muted, _$p));
|
|
546
|
+
return _el$20;
|
|
318
547
|
})(), _$createComponent(Show, {
|
|
319
548
|
get when() {
|
|
320
549
|
return !configured();
|
|
321
550
|
},
|
|
322
551
|
get children() {
|
|
323
552
|
return [(() => {
|
|
324
|
-
var _el$
|
|
325
|
-
_$
|
|
326
|
-
_$effect((_$p) => _$setProp(_el$
|
|
327
|
-
return _el$
|
|
553
|
+
var _el$21 = _$createElement("text");
|
|
554
|
+
_$insert(_el$21, () => t("notConfigured"));
|
|
555
|
+
_$effect((_$p) => _$setProp(_el$21, "fg", colors().warning, _$p));
|
|
556
|
+
return _el$21;
|
|
328
557
|
})(), (() => {
|
|
329
558
|
var _el$22 = _$createElement("text");
|
|
330
|
-
_$
|
|
559
|
+
_$insert(_el$22, () => t("notConfiguredHint"));
|
|
331
560
|
_$effect((_$p) => _$setProp(_el$22, "fg", colors().muted, _$p));
|
|
332
561
|
return _el$22;
|
|
333
562
|
})()];
|
|
@@ -347,49 +576,50 @@ function GoUsagePanel(props) {
|
|
|
347
576
|
return configured();
|
|
348
577
|
},
|
|
349
578
|
get children() {
|
|
350
|
-
var _el$
|
|
351
|
-
_$
|
|
352
|
-
_$effect((_$p) => _$setProp(_el$
|
|
353
|
-
return _el$
|
|
579
|
+
var _el$29 = _$createElement("text");
|
|
580
|
+
_$insert(_el$29, () => t("loading"));
|
|
581
|
+
_$effect((_$p) => _$setProp(_el$29, "fg", colors().muted, _$p));
|
|
582
|
+
return _el$29;
|
|
354
583
|
}
|
|
355
584
|
});
|
|
356
585
|
},
|
|
357
586
|
get children() {
|
|
358
|
-
return [_$memo(() => renderRow("
|
|
359
|
-
var _el$
|
|
360
|
-
_$insertNode(_el$
|
|
361
|
-
_$insertNode(_el$
|
|
362
|
-
_$insertNode(_el$
|
|
363
|
-
_$insert(_el$
|
|
587
|
+
return [_$memo(() => renderRow(t("rowRolling"), usage().rollingUsage)), _$memo(() => renderRow(t("rowWeekly"), usage().weeklyUsage)), _$memo(() => renderRow(t("rowMonthly"), usage().monthlyUsage)), (() => {
|
|
588
|
+
var _el$25 = _$createElement("text"), _el$26 = _$createElement("span"), _el$27 = _$createTextNode(` `), _el$28 = _$createElement("span");
|
|
589
|
+
_$insertNode(_el$25, _el$26);
|
|
590
|
+
_$insertNode(_el$25, _el$28);
|
|
591
|
+
_$insertNode(_el$26, _el$27);
|
|
592
|
+
_$insert(_el$26, () => t("updatedAt"), _el$27);
|
|
593
|
+
_$insert(_el$28, lastUpdated);
|
|
364
594
|
_$effect((_p$) => {
|
|
365
|
-
var _v$
|
|
595
|
+
var _v$9 = {
|
|
366
596
|
fg: colors().muted
|
|
367
|
-
}, _v$
|
|
597
|
+
}, _v$0 = {
|
|
368
598
|
fg: colors().muted
|
|
369
599
|
};
|
|
370
|
-
_v$
|
|
371
|
-
_v$
|
|
600
|
+
_v$9 !== _p$.e && (_p$.e = _$setProp(_el$26, "style", _v$9, _p$.e));
|
|
601
|
+
_v$0 !== _p$.t && (_p$.t = _$setProp(_el$28, "style", _v$0, _p$.t));
|
|
372
602
|
return _p$;
|
|
373
603
|
}, {
|
|
374
604
|
e: void 0,
|
|
375
605
|
t: void 0
|
|
376
606
|
});
|
|
377
|
-
return _el$
|
|
607
|
+
return _el$25;
|
|
378
608
|
})()];
|
|
379
609
|
}
|
|
380
610
|
});
|
|
381
611
|
},
|
|
382
612
|
get children() {
|
|
383
613
|
return [(() => {
|
|
614
|
+
var _el$23 = _$createElement("text");
|
|
615
|
+
_$insert(_el$23, error);
|
|
616
|
+
_$effect((_$p) => _$setProp(_el$23, "fg", colors().error, _$p));
|
|
617
|
+
return _el$23;
|
|
618
|
+
})(), (() => {
|
|
384
619
|
var _el$24 = _$createElement("text");
|
|
385
|
-
_$insert(_el$24,
|
|
386
|
-
_$effect((_$p) => _$setProp(_el$24, "fg", colors().
|
|
620
|
+
_$insert(_el$24, () => t("reconfigureHint"));
|
|
621
|
+
_$effect((_$p) => _$setProp(_el$24, "fg", colors().muted, _$p));
|
|
387
622
|
return _el$24;
|
|
388
|
-
})(), (() => {
|
|
389
|
-
var _el$25 = _$createElement("text");
|
|
390
|
-
_$insertNode(_el$25, _$createTextNode(`\u8F93\u5165 /go-config \u91CD\u65B0\u914D\u7F6E`));
|
|
391
|
-
_$effect((_$p) => _$setProp(_el$25, "fg", colors().muted, _$p));
|
|
392
|
-
return _el$25;
|
|
393
623
|
})()];
|
|
394
624
|
}
|
|
395
625
|
})];
|
|
@@ -400,15 +630,19 @@ function GoUsagePanel(props) {
|
|
|
400
630
|
fg: colors().muted
|
|
401
631
|
}, _v$7 = {
|
|
402
632
|
fg: colors().primary
|
|
633
|
+
}, _v$8 = {
|
|
634
|
+
fg: colors().muted
|
|
403
635
|
};
|
|
404
636
|
_v$5 !== _p$.e && (_p$.e = _$setProp(_el$1, "borderColor", _v$5, _p$.e));
|
|
405
637
|
_v$6 !== _p$.t && (_p$.t = _$setProp(_el$11, "style", _v$6, _p$.t));
|
|
406
638
|
_v$7 !== _p$.a && (_p$.a = _$setProp(_el$12, "style", _v$7, _p$.a));
|
|
639
|
+
_v$8 !== _p$.o && (_p$.o = _$setProp(_el$14, "style", _v$8, _p$.o));
|
|
407
640
|
return _p$;
|
|
408
641
|
}, {
|
|
409
642
|
e: void 0,
|
|
410
643
|
t: void 0,
|
|
411
|
-
a: void 0
|
|
644
|
+
a: void 0,
|
|
645
|
+
o: void 0
|
|
412
646
|
});
|
|
413
647
|
return _el$1;
|
|
414
648
|
})();
|
|
@@ -428,63 +662,121 @@ function createSidebarSlot(api) {
|
|
|
428
662
|
}
|
|
429
663
|
};
|
|
430
664
|
}
|
|
431
|
-
|
|
432
|
-
api.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
description:
|
|
437
|
-
|
|
438
|
-
|
|
665
|
+
function runConfigDialog(api, dialog) {
|
|
666
|
+
dialog?.replace(() => _$createComponent(api.ui.DialogPrompt, {
|
|
667
|
+
get title() {
|
|
668
|
+
return t("wsPromptTitle");
|
|
669
|
+
},
|
|
670
|
+
description: () => (() => {
|
|
671
|
+
var _el$30 = _$createElement("text");
|
|
672
|
+
_$insert(_el$30, () => t("wsPromptDesc"));
|
|
673
|
+
return _el$30;
|
|
674
|
+
})(),
|
|
675
|
+
get placeholder() {
|
|
676
|
+
return t("wsPlaceholder");
|
|
439
677
|
},
|
|
440
|
-
|
|
678
|
+
onConfirm: (value) => {
|
|
679
|
+
const wsId = value.trim();
|
|
680
|
+
if (!wsId) {
|
|
681
|
+
dialog?.clear();
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
saveConfig({
|
|
685
|
+
workspace_id: wsId
|
|
686
|
+
});
|
|
441
687
|
dialog?.replace(() => _$createComponent(api.ui.DialogPrompt, {
|
|
442
|
-
title
|
|
688
|
+
get title() {
|
|
689
|
+
return t("cookiePromptTitle");
|
|
690
|
+
},
|
|
443
691
|
description: () => (() => {
|
|
444
|
-
var _el$
|
|
445
|
-
_$
|
|
446
|
-
return _el$
|
|
692
|
+
var _el$31 = _$createElement("text");
|
|
693
|
+
_$insert(_el$31, () => t("cookiePromptDesc"));
|
|
694
|
+
return _el$31;
|
|
447
695
|
})(),
|
|
448
|
-
placeholder
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
696
|
+
get placeholder() {
|
|
697
|
+
return t("cookiePlaceholder");
|
|
698
|
+
},
|
|
699
|
+
onConfirm: (val) => {
|
|
700
|
+
const cookie = val.trim();
|
|
701
|
+
if (!cookie) {
|
|
452
702
|
dialog?.clear();
|
|
453
703
|
return;
|
|
454
704
|
}
|
|
455
705
|
saveConfig({
|
|
456
|
-
|
|
706
|
+
cookie
|
|
457
707
|
});
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
})(),
|
|
465
|
-
placeholder: "Fe26.2*...",
|
|
466
|
-
onConfirm: (val) => {
|
|
467
|
-
const cookie = val.trim();
|
|
468
|
-
if (!cookie) {
|
|
469
|
-
dialog?.clear();
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
saveConfig({
|
|
473
|
-
cookie
|
|
474
|
-
});
|
|
475
|
-
setConfigTick((v) => v + 1);
|
|
476
|
-
api.ui.toast({
|
|
477
|
-
variant: "success",
|
|
478
|
-
message: "Go \u7528\u91CF\u914D\u7F6E\u5DF2\u4FDD\u5B58"
|
|
479
|
-
});
|
|
480
|
-
dialog?.clear();
|
|
481
|
-
},
|
|
482
|
-
onCancel: () => dialog?.clear()
|
|
483
|
-
}));
|
|
708
|
+
setConfigTick((v) => v + 1);
|
|
709
|
+
api.ui.toast({
|
|
710
|
+
variant: "success",
|
|
711
|
+
message: t("configSaved")
|
|
712
|
+
});
|
|
713
|
+
dialog?.clear();
|
|
484
714
|
},
|
|
485
715
|
onCancel: () => dialog?.clear()
|
|
486
716
|
}));
|
|
487
|
-
}
|
|
717
|
+
},
|
|
718
|
+
onCancel: () => dialog?.clear()
|
|
719
|
+
}));
|
|
720
|
+
}
|
|
721
|
+
function runLangDialog(api, dialog) {
|
|
722
|
+
dialog?.replace(() => _$createComponent(api.ui.DialogSelect, {
|
|
723
|
+
get title() {
|
|
724
|
+
return t("langTitle");
|
|
725
|
+
},
|
|
726
|
+
get options() {
|
|
727
|
+
return LANG_META.map((m) => ({
|
|
728
|
+
title: `${m.label}${langCode() === m.code ? " \u2713" : ""}`,
|
|
729
|
+
value: m.code
|
|
730
|
+
}));
|
|
731
|
+
},
|
|
732
|
+
onSelect: (opt) => {
|
|
733
|
+
const code = opt.value;
|
|
734
|
+
setLangCode(code);
|
|
735
|
+
kvTrySet(api, `${KV_PREFIX}.lang`, code);
|
|
736
|
+
api.ui.toast({
|
|
737
|
+
message: code === "zh" ? t("langSwitchedZh") : t("langSwitchedEn")
|
|
738
|
+
});
|
|
739
|
+
const cfg = loadConfig();
|
|
740
|
+
if (!cfg.workspaceId || !cfg.authCookie) {
|
|
741
|
+
runConfigDialog(api, dialog);
|
|
742
|
+
} else {
|
|
743
|
+
dialog?.clear();
|
|
744
|
+
}
|
|
745
|
+
},
|
|
746
|
+
onCancel: () => dialog?.clear()
|
|
747
|
+
}));
|
|
748
|
+
}
|
|
749
|
+
var tui = async (api) => {
|
|
750
|
+
api.slots.register(createSidebarSlot(api));
|
|
751
|
+
const savedLang = kvTryGet(api, `${KV_PREFIX}.lang`);
|
|
752
|
+
if (savedLang === "zh" || savedLang === "en") setLangCode(savedLang);
|
|
753
|
+
else setLangCode(detectLang());
|
|
754
|
+
const onboarded = kvTryGet(api, `${KV_PREFIX}.onboarded`);
|
|
755
|
+
if (!onboarded) {
|
|
756
|
+
kvTrySet(api, `${KV_PREFIX}.onboarded`, "1");
|
|
757
|
+
setTimeout(() => {
|
|
758
|
+
try {
|
|
759
|
+
api.command.trigger("go-usage.lang");
|
|
760
|
+
} catch {
|
|
761
|
+
}
|
|
762
|
+
}, 1500);
|
|
763
|
+
}
|
|
764
|
+
api.command?.register(() => [{
|
|
765
|
+
title: t("cmdTitle"),
|
|
766
|
+
value: "go-usage.config",
|
|
767
|
+
description: t("cmdDesc"),
|
|
768
|
+
slash: {
|
|
769
|
+
name: "go-config"
|
|
770
|
+
},
|
|
771
|
+
onSelect: (dialog) => runConfigDialog(api, dialog)
|
|
772
|
+
}, {
|
|
773
|
+
title: t("langCmdTitle"),
|
|
774
|
+
value: "go-usage.lang",
|
|
775
|
+
description: t("langCmdDesc"),
|
|
776
|
+
slash: {
|
|
777
|
+
name: "go-lang"
|
|
778
|
+
},
|
|
779
|
+
onSelect: (dialog) => runLangDialog(api, dialog)
|
|
488
780
|
}]);
|
|
489
781
|
};
|
|
490
782
|
var mod = {
|