tokmon 0.27.0 → 0.28.1
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 -1
- package/dist/{bootstrap-ink-3YNJFKCW.js → bootstrap-ink-L7QSJBMS.js} +142 -12
- package/dist/{chunk-4CY725NY.js → chunk-3RTWFGGD.js} +1 -1
- package/dist/{chunk-AMD4PXDG.js → chunk-4HU4EI5T.js} +1 -1
- package/dist/{chunk-RTGMDE7U.js → chunk-CVKCVHS7.js} +143 -81
- package/dist/{chunk-VGYBQH5I.js → chunk-FMP3P2WV.js} +2 -2
- package/dist/{chunk-E2YXYU73.js → chunk-HP5UZCXP.js} +29 -0
- package/dist/{chunk-OWPJUG4C.js → chunk-S33XIUAW.js} +11 -11
- package/dist/{chunk-QM5E5RJZ.js → chunk-XDA5RJST.js} +1 -1
- package/dist/{cli-command-U7RZ2GTD.js → cli-command-75LP4IDS.js} +5 -5
- package/dist/cli.js +6 -6
- package/dist/{config-2PXUENQL.js → config-HXFJTNLM.js} +5 -1
- package/dist/{daemon-PQWKWRC6.js → daemon-CL4FJW26.js} +5 -5
- package/dist/{daemon-handle-2GVZT55B.js → daemon-handle-QQLJE46Y.js} +3 -3
- package/dist/server-EUO7CWYH.js +11 -0
- package/dist/web/assets/{Area-Tx1mUuqM.js → Area-CMXvOw33.js} +1 -1
- package/dist/web/assets/{analytics-CAzklhXc.js → analytics-DqdZXOJL.js} +2 -2
- package/dist/web/assets/{breakdown-BoPnOv7Y.js → breakdown-kOSSJ3mI.js} +1 -1
- package/dist/web/assets/{chart-jK7A9m7R.js → chart-cZoLgpmG.js} +1 -1
- package/dist/web/assets/{explore-e8wtwk7s.js → explore-vcsM8K9I.js} +1 -1
- package/dist/web/assets/index-BErCXT7f.css +1 -0
- package/dist/web/assets/index-DH3dOnbg.js +83 -0
- package/dist/web/assets/{models-_4IZNDxW.js → models-B5ikm83_.js} +2 -2
- package/dist/web/assets/{overview-BBOfd_Fd.js → overview-DD1kP8CP.js} +2 -2
- package/dist/web/assets/{panel-CstB4hPm.js → panel-DTQBwExW.js} +1 -1
- package/dist/web/assets/{primitives-G9ALG7ih.js → primitives-C36qJlA2.js} +1 -1
- package/dist/web/assets/settings-sheet-_i2zTQjf.js +1 -0
- package/dist/web/assets/{share-sheet-BwmnebRB.js → share-sheet-BLHmrFbm.js} +2 -2
- package/dist/web/assets/{timeline-DkYWH6XW.js → timeline-B4uG-Emo.js} +1 -1
- package/dist/web/assets/{use-dialog-trap-Jci2xaMX.js → use-dialog-trap-bfaXEMz9.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/server-5WIWS27N.js +0 -11
- package/dist/web/assets/index-C8oe6EfM.js +0 -83
- package/dist/web/assets/index-NnKaHxPO.css +0 -1
- package/dist/web/assets/settings-sheet-rq6vbYXM.js +0 -1
package/README.md
CHANGED
|
@@ -105,7 +105,7 @@ tokmon serve --port 8080
|
|
|
105
105
|
tokmon serve --no-open # don't auto-open the browser
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
It binds to `127.0.0.1` by default and reads the same local daemon state — nothing leaves your machine. The browser connects directly over a same-origin WebSocket; dashboard URLs have no token or login step. Optional LAN access can be enabled in settings, with an explicit unsafe-access warning, and takes effect after the daemon restarts. The dashboard renders instantly from a cached snapshot, then streams live updates and goes idle when no tab is open. Press `R` or use the visible **Refresh** control to update it. Filter by provider, model, account, and period, flip between dark and light, and export any panel — or a summary card — as a PNG with the **Share** button.
|
|
108
|
+
It binds to `127.0.0.1` by default and reads the same local daemon state — nothing leaves your machine. The browser connects directly over a same-origin WebSocket; dashboard URLs have no token or login step. Optional LAN access can be enabled in settings, with an explicit unsafe-access warning, and takes effect after the daemon restarts. When publishing the dashboard through an ingress or reverse proxy, add each exact DNS name to **Allowed hosts** in settings (for example, `tokmon.example.com`); IP hosts remain allowed in LAN mode. The dashboard renders instantly from a cached snapshot, then streams live updates and goes idle when no tab is open. Press `R` or use the visible **Refresh** control to update it. Filter by provider, model, account, and period, flip between dark and light, and export any panel — or a summary card — as a PNG with the **Share** button.
|
|
109
109
|
|
|
110
110
|
### Overview
|
|
111
111
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createDaemonRpcClient
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3RTWFGGD.js";
|
|
5
5
|
import {
|
|
6
6
|
accountsByProvider,
|
|
7
7
|
buildAccounts,
|
|
8
8
|
fetchPeak,
|
|
9
9
|
modelColor
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FMP3P2WV.js";
|
|
11
11
|
import {
|
|
12
12
|
PROVIDERS,
|
|
13
13
|
PROVIDER_ORDER,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
col,
|
|
16
16
|
currency,
|
|
17
17
|
detectProviders,
|
|
18
|
+
formatAgo,
|
|
18
19
|
formatResetAt,
|
|
19
20
|
resetAt,
|
|
20
21
|
resolveTimezone,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
time,
|
|
24
25
|
tokens,
|
|
25
26
|
withTimeout
|
|
26
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-CVKCVHS7.js";
|
|
27
28
|
import {
|
|
28
29
|
COLOR_PALETTE,
|
|
29
30
|
DEFAULTS,
|
|
@@ -32,13 +33,14 @@ import {
|
|
|
32
33
|
getTrackedAccountRows,
|
|
33
34
|
isValidTimezone,
|
|
34
35
|
loadConfig,
|
|
36
|
+
normalizeAllowedHost,
|
|
35
37
|
normalizeConfig,
|
|
36
38
|
pickAccentColor,
|
|
37
39
|
redactEmail,
|
|
38
40
|
sanitizeTyped,
|
|
39
41
|
saveConfigSync,
|
|
40
42
|
snapshotCacheFile
|
|
41
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-HP5UZCXP.js";
|
|
42
44
|
import {
|
|
43
45
|
glyphs
|
|
44
46
|
} from "./chunk-RF4GGQGM.js";
|
|
@@ -219,6 +221,12 @@ import { memo as memo2 } from "react";
|
|
|
219
221
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
220
222
|
|
|
221
223
|
// src/ui/provider-card.logic.ts
|
|
224
|
+
var BILLING_STALE_AFTER_MS = 30 * 6e4;
|
|
225
|
+
function billingStaleLabel(billingUpdatedAt, now) {
|
|
226
|
+
if (billingUpdatedAt == null || billingUpdatedAt <= 0) return null;
|
|
227
|
+
if (now - billingUpdatedAt < BILLING_STALE_AFTER_MS) return null;
|
|
228
|
+
return `as of ${formatAgo(billingUpdatedAt, now)}`;
|
|
229
|
+
}
|
|
222
230
|
function normalizePlan(plan) {
|
|
223
231
|
if (plan == null) return null;
|
|
224
232
|
const t = plan.trim();
|
|
@@ -253,7 +261,9 @@ function estimateCardHeights(groups, stats) {
|
|
|
253
261
|
if (meta.hasUsage) h += 1;
|
|
254
262
|
const multi = g.accounts.length > 1;
|
|
255
263
|
g.accounts.forEach((a, i) => {
|
|
256
|
-
const
|
|
264
|
+
const s = stats.get(a.id);
|
|
265
|
+
const staleRow = s?.billing && !s.billing.error && s.billing.metrics.length > 0 && billingStaleLabel(s.billing.asOfMs ?? s.billingUpdatedAt, Date.now()) ? 1 : 0;
|
|
266
|
+
const metricRows = (s?.billing?.metrics.length || 1) + staleRow;
|
|
257
267
|
h += metricRows + (multi ? 1 : 0) + (multi && i > 0 ? 1 : 0);
|
|
258
268
|
});
|
|
259
269
|
}
|
|
@@ -460,6 +470,7 @@ function LimitsBlock({ items, inner, showRowPlans, privacyMode, resetDisplay, tz
|
|
|
460
470
|
const barW = Math.max(10, Math.min(46, inner - labelW - resetW - 5));
|
|
461
471
|
return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: items.map(({ account, s }, idx) => {
|
|
462
472
|
const billing = s?.billing;
|
|
473
|
+
const staleLabel = billing && !billing.error && billing.metrics.length > 0 ? billingStaleLabel(billing.asOfMs ?? s?.billingUpdatedAt, Date.now()) : null;
|
|
463
474
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginTop: showName && idx > 0 ? 1 : 0, children: [
|
|
464
475
|
showName && (() => {
|
|
465
476
|
const rowPlan = showRowPlans ? normalizePlan(billing?.plan) : null;
|
|
@@ -482,7 +493,16 @@ function LimitsBlock({ items, inner, showRowPlans, privacyMode, resetDisplay, tz
|
|
|
482
493
|
!billing ? /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
483
494
|
"Fetching",
|
|
484
495
|
glyphs().ellipsis
|
|
485
|
-
] }) : billing.error ? /* @__PURE__ */ jsx2(Text2, { color: "red", wrap: "truncate-end", children: privacyMode ? redactEmail(billing.error) : billing.error }) : billing.metrics.length === 0 ? /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "No data" }) : billing.metrics.map((m, i) => /* @__PURE__ */ jsx2(MetricRow, { m, color: account.color, barW, labelW, resetW, resetDisplay, tz }, `${m.label}${i}`))
|
|
496
|
+
] }) : billing.error ? /* @__PURE__ */ jsx2(Text2, { color: "red", wrap: "truncate-end", children: privacyMode ? redactEmail(billing.error) : billing.error }) : billing.metrics.length === 0 ? /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "No data" }) : billing.metrics.map((m, i) => /* @__PURE__ */ jsx2(MetricRow, { m, color: account.color, barW, labelW, resetW, resetDisplay, tz }, `${m.label}${i}`)),
|
|
497
|
+
staleLabel && /* @__PURE__ */ jsxs2(Text2, { color: "yellow", dimColor: true, children: [
|
|
498
|
+
glyphs().warn,
|
|
499
|
+
" ",
|
|
500
|
+
staleLabel,
|
|
501
|
+
" ",
|
|
502
|
+
glyphs().middot,
|
|
503
|
+
" refreshing",
|
|
504
|
+
glyphs().ellipsis
|
|
505
|
+
] })
|
|
486
506
|
] }, account.id);
|
|
487
507
|
}) });
|
|
488
508
|
}
|
|
@@ -570,7 +590,7 @@ import { Box as Box4, Text as Text4 } from "ink";
|
|
|
570
590
|
import { memo as memo3 } from "react";
|
|
571
591
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
572
592
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
573
|
-
var GENERAL_ROWS =
|
|
593
|
+
var GENERAL_ROWS = 11;
|
|
574
594
|
var SETTINGS_TABS = ["general", "providers", "accounts"];
|
|
575
595
|
var SETTINGS_TAB_LABELS = {
|
|
576
596
|
general: "General",
|
|
@@ -585,6 +605,9 @@ var SettingsView = memo3(function SettingsView2({
|
|
|
585
605
|
tzEdit,
|
|
586
606
|
tzCaret,
|
|
587
607
|
tzError,
|
|
608
|
+
allowedHostsEdit,
|
|
609
|
+
allowedHostsCaret,
|
|
610
|
+
allowedHostsError,
|
|
588
611
|
resolvedTz,
|
|
589
612
|
accountForm,
|
|
590
613
|
activeAccountId,
|
|
@@ -593,6 +616,7 @@ var SettingsView = memo3(function SettingsView2({
|
|
|
593
616
|
}) {
|
|
594
617
|
if (accountForm) return /* @__PURE__ */ jsx3(AccountFormView, { form: accountForm, accounts: config.accounts });
|
|
595
618
|
const editingTz = tzEdit !== null;
|
|
619
|
+
const editingAllowedHosts = allowedHostsEdit !== null;
|
|
596
620
|
const tzDisplay = config.timezone === null ? `System (${resolvedTz})` : config.timezone;
|
|
597
621
|
const tabFocused = cursor < 0;
|
|
598
622
|
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, children: [
|
|
@@ -666,8 +690,17 @@ var SettingsView = memo3(function SettingsView2({
|
|
|
666
690
|
] })
|
|
667
691
|
] }),
|
|
668
692
|
/* @__PURE__ */ jsx3(Row, { cursor, idx: 8, label: "Network access", children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: config.allowNetworkAccess ? "red" : "green", children: config.allowNetworkAccess ? "LAN (unsafe)" : "local only" }) }),
|
|
693
|
+
/* @__PURE__ */ jsx3(Row, { cursor, idx: 9, label: "Allowed hosts", children: editingAllowedHosts ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
694
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "[" }),
|
|
695
|
+
/* @__PURE__ */ jsx3(CaretText, { value: allowedHostsEdit ?? "", caret: allowedHostsCaret, color: "cyan" }),
|
|
696
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "]" })
|
|
697
|
+
] }) : /* @__PURE__ */ jsx3(Text3, { bold: true, color: "yellow", children: config.allowedHosts.join(", ") || "none" }) }),
|
|
698
|
+
cursor === 9 && allowedHostsError && /* @__PURE__ */ jsxs3(Text3, { color: "red", children: [
|
|
699
|
+
" ",
|
|
700
|
+
allowedHostsError
|
|
701
|
+
] }),
|
|
669
702
|
config.allowNetworkAccess && /* @__PURE__ */ jsx3(Text3, { color: "red", children: " Warning: dashboard data and settings will be exposed to your local network after daemon restart." }),
|
|
670
|
-
/* @__PURE__ */ jsxs3(Row, { cursor, idx:
|
|
703
|
+
/* @__PURE__ */ jsxs3(Row, { cursor, idx: 10, label: "Reset times", children: [
|
|
671
704
|
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
672
705
|
glyphs().caretL,
|
|
673
706
|
" "
|
|
@@ -760,6 +793,12 @@ var SettingsView = memo3(function SettingsView2({
|
|
|
760
793
|
" Enter save ",
|
|
761
794
|
glyphs().middot,
|
|
762
795
|
" Esc cancel"
|
|
796
|
+
] }) : editingAllowedHosts ? /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
797
|
+
"comma-separated exact DNS names ",
|
|
798
|
+
glyphs().middot,
|
|
799
|
+
" Enter save ",
|
|
800
|
+
glyphs().middot,
|
|
801
|
+
" Esc cancel"
|
|
763
802
|
] }) : activeTab === "providers" ? /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
764
803
|
glyphs().arrowU,
|
|
765
804
|
glyphs().arrowD,
|
|
@@ -1711,7 +1750,8 @@ function toStatsMap(snapshot, accounts) {
|
|
|
1711
1750
|
out.set(account.id, {
|
|
1712
1751
|
account,
|
|
1713
1752
|
dashboard: wa?.dashboard ?? null,
|
|
1714
|
-
billing: wa?.billing ?? null
|
|
1753
|
+
billing: wa?.billing ?? null,
|
|
1754
|
+
billingUpdatedAt: wa?.billingUpdatedAt ?? null
|
|
1715
1755
|
});
|
|
1716
1756
|
}
|
|
1717
1757
|
return out;
|
|
@@ -1972,6 +2012,56 @@ function handleTimezoneEditor(input, key, editor, text, updateConfig) {
|
|
|
1972
2012
|
if (clean) text.insert(clean);
|
|
1973
2013
|
}
|
|
1974
2014
|
}
|
|
2015
|
+
function handleAllowedHostsEditor(input, key, editor, text, updateConfig) {
|
|
2016
|
+
const { value, setValue, setError, setCaret, valueRef, caretRef } = editor;
|
|
2017
|
+
if (value === null) return;
|
|
2018
|
+
if (key.escape) {
|
|
2019
|
+
setValue(null);
|
|
2020
|
+
setError(null);
|
|
2021
|
+
return;
|
|
2022
|
+
}
|
|
2023
|
+
if (key.return) {
|
|
2024
|
+
const parts = value.split(",").map((part) => part.trim()).filter(Boolean);
|
|
2025
|
+
const normalized = parts.map(normalizeAllowedHost);
|
|
2026
|
+
if (normalized.some((host) => host === null)) {
|
|
2027
|
+
setError("Use exact DNS names without a scheme, port, path, or wildcard");
|
|
2028
|
+
return;
|
|
2029
|
+
}
|
|
2030
|
+
updateConfig((config) => ({ ...config, allowedHosts: [...new Set(normalized)] }));
|
|
2031
|
+
setValue(null);
|
|
2032
|
+
setError(null);
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
2035
|
+
if (key.leftArrow) {
|
|
2036
|
+
setCaret((caret) => clampCaret(caret - 1, value.length));
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
if (key.rightArrow) {
|
|
2040
|
+
setCaret((caret) => clampCaret(caret + 1, value.length));
|
|
2041
|
+
return;
|
|
2042
|
+
}
|
|
2043
|
+
if (key.ctrl && input === "a") {
|
|
2044
|
+
setCaret(0);
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
if (key.ctrl && input === "e") {
|
|
2048
|
+
setCaret(value.length);
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
if (key.backspace || key.delete) {
|
|
2052
|
+
const result = spliceBackspace(valueRef.current, caretRef.current);
|
|
2053
|
+
valueRef.current = result.value;
|
|
2054
|
+
caretRef.current = result.caret;
|
|
2055
|
+
setValue(result.value);
|
|
2056
|
+
setCaret(result.caret);
|
|
2057
|
+
setError(null);
|
|
2058
|
+
return;
|
|
2059
|
+
}
|
|
2060
|
+
if (text.isPrintable(input, key)) {
|
|
2061
|
+
const clean = sanitizeTyped(input);
|
|
2062
|
+
if (clean) text.insert(clean);
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
1975
2065
|
function handleSearchEditor(input, key, table, text) {
|
|
1976
2066
|
const { search, setSearch, setSearchMode, setSearchCaret, searchValueRef, searchCaretRef } = table;
|
|
1977
2067
|
if (key.return || key.escape) {
|
|
@@ -2044,6 +2134,8 @@ function handleSettings(input, key, ctx) {
|
|
|
2044
2134
|
setCursor(-1);
|
|
2045
2135
|
timezoneEditor.setValue(null);
|
|
2046
2136
|
timezoneEditor.setError(null);
|
|
2137
|
+
ctx.allowedHostsEditor.setValue(null);
|
|
2138
|
+
ctx.allowedHostsEditor.setError(null);
|
|
2047
2139
|
};
|
|
2048
2140
|
const rowCount = tab === "general" ? GENERAL_ROWS : tab === "providers" ? PROVIDER_ORDER.length : trackedAccounts.length + 1;
|
|
2049
2141
|
if (key.tab) {
|
|
@@ -2174,7 +2266,14 @@ function handleSettings(input, key, ctx) {
|
|
|
2174
2266
|
updateConfig((current) => ({ ...current, allowNetworkAccess: !current.allowNetworkAccess }));
|
|
2175
2267
|
return;
|
|
2176
2268
|
}
|
|
2177
|
-
if (index === 9 &&
|
|
2269
|
+
if (index === 9 && inputKey.return) {
|
|
2270
|
+
const initial = config.allowedHosts.join(", ");
|
|
2271
|
+
context.allowedHostsEditor.setValue(initial);
|
|
2272
|
+
context.allowedHostsEditor.setCaret(initial.length);
|
|
2273
|
+
context.allowedHostsEditor.setError(null);
|
|
2274
|
+
return;
|
|
2275
|
+
}
|
|
2276
|
+
if (index === 10 && (inputKey.leftArrow || inputKey.rightArrow || inputKey.return)) {
|
|
2178
2277
|
updateConfig((current) => ({ ...current, resetDisplay: current.resetDisplay === "relative" ? "absolute" : "relative" }));
|
|
2179
2278
|
}
|
|
2180
2279
|
}
|
|
@@ -2337,7 +2436,7 @@ function handleTerminalFocusInput(input) {
|
|
|
2337
2436
|
return true;
|
|
2338
2437
|
}
|
|
2339
2438
|
function isRefreshAllShortcut(input, mode) {
|
|
2340
|
-
return (input === "r" || input === "R") && !mode.unavailable && !mode.showPicker && !mode.editingAccount && !mode.editingTimezone && !mode.editingSearch;
|
|
2439
|
+
return (input === "r" || input === "R") && !mode.unavailable && !mode.showPicker && !mode.editingAccount && !mode.editingTimezone && !mode.editingAllowedHosts && !mode.editingSearch;
|
|
2341
2440
|
}
|
|
2342
2441
|
function handleOnboarding(input, key, ctx) {
|
|
2343
2442
|
const { onboarding, global } = ctx;
|
|
@@ -2366,11 +2465,13 @@ function handleOnboarding(input, key, ctx) {
|
|
|
2366
2465
|
function handleKey(input, key, ctx) {
|
|
2367
2466
|
const editingAccount = ctx.settings.show && ctx.accountEditor.form !== null;
|
|
2368
2467
|
const editingTimezone = ctx.settings.show && ctx.timezoneEditor.value !== null;
|
|
2468
|
+
const editingAllowedHosts = ctx.settings.show && ctx.allowedHostsEditor.value !== null;
|
|
2369
2469
|
const editingSearch = ctx.table.tab === 1 && ctx.table.searchMode;
|
|
2370
2470
|
if (isRefreshAllShortcut(input, {
|
|
2371
2471
|
showPicker: ctx.onboarding.show,
|
|
2372
2472
|
editingAccount,
|
|
2373
2473
|
editingTimezone,
|
|
2474
|
+
editingAllowedHosts,
|
|
2374
2475
|
editingSearch,
|
|
2375
2476
|
unavailable: !ctx.global.configReady
|
|
2376
2477
|
})) {
|
|
@@ -2389,6 +2490,10 @@ function handleKey(input, key, ctx) {
|
|
|
2389
2490
|
handleTimezoneEditor(input, key, ctx.timezoneEditor, ctx.textInput, ctx.global.updateConfig);
|
|
2390
2491
|
return;
|
|
2391
2492
|
}
|
|
2493
|
+
if (editingAllowedHosts) {
|
|
2494
|
+
handleAllowedHostsEditor(input, key, ctx.allowedHostsEditor, ctx.textInput, ctx.global.updateConfig);
|
|
2495
|
+
return;
|
|
2496
|
+
}
|
|
2392
2497
|
if (editingSearch) {
|
|
2393
2498
|
handleSearchEditor(input, key, ctx.table, ctx.textInput);
|
|
2394
2499
|
return;
|
|
@@ -3122,6 +3227,9 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, mode = "deg
|
|
|
3122
3227
|
const [tzEdit, setTzEdit] = useState10(null);
|
|
3123
3228
|
const [tzError, setTzError] = useState10(null);
|
|
3124
3229
|
const [tzCaret, setTzCaret] = useState10(0);
|
|
3230
|
+
const [allowedHostsEdit, setAllowedHostsEdit] = useState10(null);
|
|
3231
|
+
const [allowedHostsError, setAllowedHostsError] = useState10(null);
|
|
3232
|
+
const [allowedHostsCaret, setAllowedHostsCaret] = useState10(0);
|
|
3125
3233
|
const [searchCaret, setSearchCaret] = useState10(0);
|
|
3126
3234
|
const [onboardSel, setOnboardSel] = useState10(null);
|
|
3127
3235
|
const [onboardCursor, setOnboardCursor] = useState10(0);
|
|
@@ -3149,6 +3257,8 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, mode = "deg
|
|
|
3149
3257
|
const dashPageCountRef = useRef8(1);
|
|
3150
3258
|
const tzValueRef = useRef8("");
|
|
3151
3259
|
const tzCaretRef = useRef8(0);
|
|
3260
|
+
const allowedHostsValueRef = useRef8("");
|
|
3261
|
+
const allowedHostsCaretRef = useRef8(0);
|
|
3152
3262
|
const searchValueRef = useRef8("");
|
|
3153
3263
|
const searchCaretRef = useRef8(0);
|
|
3154
3264
|
const accountsKey = useMemo2(() => accounts.map(acctKey).join("|"), [accounts]);
|
|
@@ -3254,6 +3364,8 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, mode = "deg
|
|
|
3254
3364
|
dashPageCountRef.current = dashPageCount;
|
|
3255
3365
|
tzValueRef.current = tzEdit ?? "";
|
|
3256
3366
|
tzCaretRef.current = clampCaret(tzCaret, (tzEdit ?? "").length);
|
|
3367
|
+
allowedHostsValueRef.current = allowedHostsEdit ?? "";
|
|
3368
|
+
allowedHostsCaretRef.current = clampCaret(allowedHostsCaret, (allowedHostsEdit ?? "").length);
|
|
3257
3369
|
searchValueRef.current = search;
|
|
3258
3370
|
searchCaretRef.current = clampCaret(searchCaret, search.length);
|
|
3259
3371
|
const isPrintable = (input, key) => !!input && !key.ctrl && !key.meta && !isPasteInput(input);
|
|
@@ -3271,6 +3383,13 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, mode = "deg
|
|
|
3271
3383
|
setTzEdit(r.value);
|
|
3272
3384
|
setTzCaret(r.caret);
|
|
3273
3385
|
setTzError(null);
|
|
3386
|
+
} else if (showSettings && allowedHostsEdit !== null) {
|
|
3387
|
+
const r = spliceInsert(allowedHostsValueRef.current, allowedHostsCaretRef.current, text);
|
|
3388
|
+
allowedHostsValueRef.current = r.value;
|
|
3389
|
+
allowedHostsCaretRef.current = r.caret;
|
|
3390
|
+
setAllowedHostsEdit(r.value);
|
|
3391
|
+
setAllowedHostsCaret(r.caret);
|
|
3392
|
+
setAllowedHostsError(null);
|
|
3274
3393
|
} else if (tab === 1 && searchMode) {
|
|
3275
3394
|
const r = spliceInsert(searchValueRef.current, searchCaretRef.current, text);
|
|
3276
3395
|
searchValueRef.current = r.value;
|
|
@@ -3441,7 +3560,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, mode = "deg
|
|
|
3441
3560
|
if (webStartingRef.current) return;
|
|
3442
3561
|
webStartingRef.current = true;
|
|
3443
3562
|
try {
|
|
3444
|
-
const { startWebServer } = await import("./server-
|
|
3563
|
+
const { startWebServer } = await import("./server-EUO7CWYH.js");
|
|
3445
3564
|
const ctrl = await startWebServer({ config: cfg, log: false });
|
|
3446
3565
|
webRef.current = ctrl;
|
|
3447
3566
|
openUrl(ctrl.url);
|
|
@@ -3515,6 +3634,14 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, mode = "deg
|
|
|
3515
3634
|
valueRef: tzValueRef,
|
|
3516
3635
|
caretRef: tzCaretRef
|
|
3517
3636
|
},
|
|
3637
|
+
allowedHostsEditor: {
|
|
3638
|
+
value: allowedHostsEdit,
|
|
3639
|
+
setValue: setAllowedHostsEdit,
|
|
3640
|
+
setError: setAllowedHostsError,
|
|
3641
|
+
setCaret: setAllowedHostsCaret,
|
|
3642
|
+
valueRef: allowedHostsValueRef,
|
|
3643
|
+
caretRef: allowedHostsCaretRef
|
|
3644
|
+
},
|
|
3518
3645
|
textInput: { isPrintable, insert: insertText },
|
|
3519
3646
|
settings: {
|
|
3520
3647
|
show: showSettings,
|
|
@@ -3654,6 +3781,9 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, mode = "deg
|
|
|
3654
3781
|
tzEdit,
|
|
3655
3782
|
tzCaret,
|
|
3656
3783
|
tzError,
|
|
3784
|
+
allowedHostsEdit,
|
|
3785
|
+
allowedHostsCaret,
|
|
3786
|
+
allowedHostsError,
|
|
3657
3787
|
resolvedTz: tz,
|
|
3658
3788
|
accountForm,
|
|
3659
3789
|
activeAccountId: cfg.activeAccountId,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
TOKMON_WS_METHODS,
|
|
4
4
|
TOKMON_WS_PATH,
|
|
5
5
|
TokmonRpcGroup
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CVKCVHS7.js";
|
|
7
7
|
|
|
8
8
|
// src/client/daemon-rpc-client.ts
|
|
9
9
|
import { Cause, Context, Duration, Effect, Exit, Fiber, Layer, ManagedRuntime, Schedule, Stream } from "effect";
|