tokmon 0.23.5 → 0.25.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 +25 -3
- package/dist/{bootstrap-ink-WA3ENW2M.js → bootstrap-ink-O55MPGXJ.js} +52 -314
- package/dist/chunk-45YYP2FJ.js +299 -0
- package/dist/{daemon-handle-Y2N2NA6D.js → chunk-AMD4PXDG.js} +2 -2
- package/dist/{chunk-5CWOJMAH.js → chunk-E2YXYU73.js} +2 -0
- package/dist/{chunk-IELQ5EY3.js → chunk-INBZLHJQ.js} +306 -549
- package/dist/{chunk-MJWFCDBB.js → chunk-IOIAXKW2.js} +38 -16
- package/dist/{chunk-3TJVFKXV.js → chunk-QM5E5RJZ.js} +1 -1
- package/dist/chunk-QUGH2XA6.js +275 -0
- package/dist/cli-command-YQ5T4R73.js +526 -0
- package/dist/cli.js +30 -5
- package/dist/{config-QC5QSP3G.js → config-2PXUENQL.js} +1 -1
- package/dist/{daemon-PVYTXJMS.js → daemon-QBOXJFRA.js} +7 -6
- package/dist/daemon-handle-2GVZT55B.js +10 -0
- package/dist/server-23ERUOJ7.js +11 -0
- package/dist/web/assets/{Area-DCES17aZ.js → Area-DbVPPS7M.js} +1 -1
- package/dist/web/assets/{analytics-DDW6zcnj.js → analytics-DS5p9Duq.js} +2 -2
- package/dist/web/assets/{breakdown-D5LPPtqh.js → breakdown-zYF0TXN5.js} +1 -1
- package/dist/web/assets/{chart-bHY7MQV0.js → chart-BZHliIXk.js} +1 -1
- package/dist/web/assets/{explore-DdWB-Pu7.js → explore-DYv8bb2r.js} +1 -1
- package/dist/web/assets/{index-C9jxb2o3.js → index-BO8m4dq1.js} +24 -24
- package/dist/web/assets/index-NnKaHxPO.css +1 -0
- package/dist/web/assets/{models-o1wJnG6w.js → models-P3OwakgO.js} +2 -2
- package/dist/web/assets/overview-5WswYjWK.js +2 -0
- package/dist/web/assets/{panel-DBnK1oy0.js → panel-CpwRWsNg.js} +1 -1
- package/dist/web/assets/{primitives-CBmteetD.js → primitives-Do0zWLZ4.js} +1 -1
- package/dist/web/assets/settings-sheet-uD6-A3tV.js +1 -0
- package/dist/web/assets/{share-sheet-DUee3FlK.js → share-sheet-CimegH2K.js} +2 -2
- package/dist/web/assets/{timeline-BxHwOJA_.js → timeline-Ch94Yv4z.js} +1 -1
- package/dist/web/assets/{use-dialog-trap-30EqxYF-.js → use-dialog-trap-LxEFLutK.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/server-XUCQWX6N.js +0 -10
- package/dist/web/assets/index-m0KfWnN2.css +0 -1
- package/dist/web/assets/overview-wq2uAEk4.js +0 -2
- package/dist/web/assets/settings-sheet-CZ6GEPl3.js +0 -1
|
@@ -4,9 +4,21 @@ import {
|
|
|
4
4
|
cacheDir,
|
|
5
5
|
envDir,
|
|
6
6
|
expandHome,
|
|
7
|
-
isValidTimezone
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
isValidTimezone
|
|
8
|
+
} from "./chunk-E2YXYU73.js";
|
|
9
|
+
|
|
10
|
+
// src/async.ts
|
|
11
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
12
|
+
function withTimeout(promise, ms = DEFAULT_TIMEOUT_MS) {
|
|
13
|
+
let timer;
|
|
14
|
+
const timeout = new Promise((_, reject) => {
|
|
15
|
+
timer = setTimeout(() => reject(new Error("operation timeout")), ms);
|
|
16
|
+
timer.unref?.();
|
|
17
|
+
});
|
|
18
|
+
return Promise.race([promise, timeout]).finally(() => {
|
|
19
|
+
if (timer) clearTimeout(timer);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
10
22
|
|
|
11
23
|
// src/providers/usage-core.ts
|
|
12
24
|
import { readFileSync, readdirSync } from "fs";
|
|
@@ -726,6 +738,240 @@ function coalesceTables(list) {
|
|
|
726
738
|
return mergeTables(list);
|
|
727
739
|
}
|
|
728
740
|
|
|
741
|
+
// src/rpc/contract.ts
|
|
742
|
+
import { Schema } from "effect";
|
|
743
|
+
import * as Rpc from "effect/unstable/rpc/Rpc";
|
|
744
|
+
import * as RpcGroup from "effect/unstable/rpc/RpcGroup";
|
|
745
|
+
var TOKMON_WS_PATH = "/ws";
|
|
746
|
+
var TOKMON_PROTOCOL_VERSION = 2;
|
|
747
|
+
var TOKMON_CAPABILITIES = ["config-cas", "config-revision"];
|
|
748
|
+
var TOKMON_WS_METHODS = {
|
|
749
|
+
getConfig: "tokmon.getConfig",
|
|
750
|
+
setConfig: "tokmon.setConfig",
|
|
751
|
+
refresh: "tokmon.refresh",
|
|
752
|
+
browseFs: "tokmon.browseFs",
|
|
753
|
+
snapshot: "tokmon.snapshot",
|
|
754
|
+
config: "tokmon.config"
|
|
755
|
+
};
|
|
756
|
+
var RefreshScopeSchema = Schema.Literals([
|
|
757
|
+
"all",
|
|
758
|
+
"summary",
|
|
759
|
+
"table",
|
|
760
|
+
"billing",
|
|
761
|
+
"peak"
|
|
762
|
+
]);
|
|
763
|
+
var ProviderIdSchema = Schema.Literals(PROVIDER_IDS);
|
|
764
|
+
var NonNegativeIntegerSchema = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
765
|
+
var PositiveFiniteSchema = Schema.Finite.check(Schema.isGreaterThanOrEqualTo(1));
|
|
766
|
+
var AccountSchema = Schema.Struct({
|
|
767
|
+
id: Schema.String,
|
|
768
|
+
providerId: ProviderIdSchema,
|
|
769
|
+
name: Schema.String,
|
|
770
|
+
homeDir: Schema.String,
|
|
771
|
+
color: Schema.optionalKey(Schema.String)
|
|
772
|
+
});
|
|
773
|
+
var ConfigSchema = Schema.Struct({
|
|
774
|
+
revision: NonNegativeIntegerSchema,
|
|
775
|
+
interval: PositiveFiniteSchema,
|
|
776
|
+
billingInterval: PositiveFiniteSchema,
|
|
777
|
+
clearScreen: Schema.Boolean,
|
|
778
|
+
privacyMode: Schema.Boolean,
|
|
779
|
+
privacyToggleKey: Schema.String,
|
|
780
|
+
timezone: Schema.NullOr(Schema.String),
|
|
781
|
+
accounts: Schema.Array(AccountSchema),
|
|
782
|
+
activeAccountId: Schema.NullOr(Schema.String),
|
|
783
|
+
disabledProviders: Schema.Array(ProviderIdSchema),
|
|
784
|
+
onboarded: Schema.Boolean,
|
|
785
|
+
dashboardLayout: Schema.Literals(["grid", "single"]),
|
|
786
|
+
defaultFocus: Schema.Literals(["all", "last"]),
|
|
787
|
+
ascii: Schema.Literals(["auto", "on", "off"]),
|
|
788
|
+
allowNetworkAccess: Schema.Boolean,
|
|
789
|
+
resetDisplay: Schema.Literals(["relative", "absolute"]),
|
|
790
|
+
knownProviders: Schema.Array(ProviderIdSchema)
|
|
791
|
+
});
|
|
792
|
+
var ProtocolInfoSchema = Schema.Struct({
|
|
793
|
+
version: Schema.Literal(TOKMON_PROTOCOL_VERSION),
|
|
794
|
+
// Capabilities are additive within a protocol version. Older clients must
|
|
795
|
+
// preserve forward compatibility when a newer daemon advertises one they do
|
|
796
|
+
// not understand yet.
|
|
797
|
+
capabilities: Schema.Array(Schema.String)
|
|
798
|
+
});
|
|
799
|
+
var ConfigStateSchema = Schema.Struct({
|
|
800
|
+
protocol: ProtocolInfoSchema,
|
|
801
|
+
config: ConfigSchema
|
|
802
|
+
});
|
|
803
|
+
var ConfigUpdateRequestSchema = Schema.Struct({
|
|
804
|
+
expectedRevision: NonNegativeIntegerSchema,
|
|
805
|
+
config: ConfigSchema
|
|
806
|
+
});
|
|
807
|
+
var ConfigUpdateConflictSchema = Schema.Struct({
|
|
808
|
+
kind: Schema.Literal("conflict"),
|
|
809
|
+
state: ConfigStateSchema
|
|
810
|
+
});
|
|
811
|
+
var ConfigPersistenceFailureSchema = Schema.Struct({
|
|
812
|
+
kind: Schema.Literal("persistence"),
|
|
813
|
+
message: Schema.String
|
|
814
|
+
});
|
|
815
|
+
var FsEntrySchema = Schema.Struct({
|
|
816
|
+
name: Schema.String,
|
|
817
|
+
path: Schema.String,
|
|
818
|
+
dir: Schema.Boolean
|
|
819
|
+
});
|
|
820
|
+
var FsListingSchema = Schema.Struct({
|
|
821
|
+
path: Schema.String,
|
|
822
|
+
parent: Schema.NullOr(Schema.String),
|
|
823
|
+
entries: Schema.Array(FsEntrySchema)
|
|
824
|
+
});
|
|
825
|
+
var UsageSummarySchema = Schema.Struct({
|
|
826
|
+
cost: Schema.Finite,
|
|
827
|
+
tokens: Schema.Finite,
|
|
828
|
+
cacheRead: Schema.Finite,
|
|
829
|
+
cacheSavings: Schema.Finite
|
|
830
|
+
});
|
|
831
|
+
var ModelDetailSchema = Schema.Struct({
|
|
832
|
+
name: Schema.String,
|
|
833
|
+
input: Schema.Finite,
|
|
834
|
+
output: Schema.Finite,
|
|
835
|
+
cacheCreate: Schema.Finite,
|
|
836
|
+
cacheRead: Schema.Finite,
|
|
837
|
+
cacheSavings: Schema.Finite,
|
|
838
|
+
cost: Schema.Finite,
|
|
839
|
+
count: Schema.Finite
|
|
840
|
+
});
|
|
841
|
+
var TableRowSchema = Schema.Struct({
|
|
842
|
+
label: Schema.String,
|
|
843
|
+
models: Schema.Array(Schema.String),
|
|
844
|
+
input: Schema.Finite,
|
|
845
|
+
output: Schema.Finite,
|
|
846
|
+
cacheCreate: Schema.Finite,
|
|
847
|
+
cacheRead: Schema.Finite,
|
|
848
|
+
cacheSavings: Schema.Finite,
|
|
849
|
+
total: Schema.Finite,
|
|
850
|
+
cost: Schema.Finite,
|
|
851
|
+
count: Schema.Finite,
|
|
852
|
+
breakdown: Schema.Array(ModelDetailSchema)
|
|
853
|
+
});
|
|
854
|
+
var DashboardDataSchema = Schema.Struct({
|
|
855
|
+
today: UsageSummarySchema,
|
|
856
|
+
week: UsageSummarySchema,
|
|
857
|
+
month: UsageSummarySchema,
|
|
858
|
+
burnRate: Schema.Finite,
|
|
859
|
+
series: Schema.Array(Schema.Finite)
|
|
860
|
+
});
|
|
861
|
+
var TableDataSchema = Schema.Struct({
|
|
862
|
+
daily: Schema.Array(TableRowSchema),
|
|
863
|
+
weekly: Schema.Array(TableRowSchema),
|
|
864
|
+
monthly: Schema.Array(TableRowSchema)
|
|
865
|
+
});
|
|
866
|
+
var MetricFormatSchema = Schema.Union([
|
|
867
|
+
Schema.Struct({ kind: Schema.Literal("percent") }),
|
|
868
|
+
Schema.Struct({ kind: Schema.Literal("dollars"), currency: Schema.optionalKey(Schema.String) }),
|
|
869
|
+
Schema.Struct({ kind: Schema.Literal("count"), suffix: Schema.optionalKey(Schema.String) })
|
|
870
|
+
]);
|
|
871
|
+
var MetricSchema = Schema.Struct({
|
|
872
|
+
label: Schema.String,
|
|
873
|
+
used: Schema.Finite,
|
|
874
|
+
limit: Schema.NullOr(Schema.Finite),
|
|
875
|
+
format: MetricFormatSchema,
|
|
876
|
+
resetsAt: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
877
|
+
primary: Schema.optionalKey(Schema.Boolean)
|
|
878
|
+
});
|
|
879
|
+
var BillingResultSchema = Schema.Struct({
|
|
880
|
+
plan: Schema.NullOr(Schema.String),
|
|
881
|
+
metrics: Schema.Array(MetricSchema),
|
|
882
|
+
error: Schema.NullOr(Schema.String),
|
|
883
|
+
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
884
|
+
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
885
|
+
activity: Schema.optionalKey(Schema.NullOr(Schema.Struct({
|
|
886
|
+
series: Schema.Array(Schema.Finite),
|
|
887
|
+
summary: Schema.String
|
|
888
|
+
}))),
|
|
889
|
+
modelSpend: Schema.optionalKey(Schema.NullOr(Schema.Array(Schema.Struct({
|
|
890
|
+
name: Schema.String,
|
|
891
|
+
usd: Schema.Finite,
|
|
892
|
+
requests: Schema.Finite
|
|
893
|
+
}))))
|
|
894
|
+
});
|
|
895
|
+
var WebAccountSchema = Schema.Struct({
|
|
896
|
+
id: Schema.String,
|
|
897
|
+
providerId: ProviderIdSchema,
|
|
898
|
+
name: Schema.String,
|
|
899
|
+
color: Schema.String,
|
|
900
|
+
homeDir: Schema.NullOr(Schema.String),
|
|
901
|
+
hasUsage: Schema.Boolean,
|
|
902
|
+
hasBilling: Schema.Boolean,
|
|
903
|
+
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
904
|
+
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
905
|
+
plan: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
906
|
+
dashboard: Schema.NullOr(DashboardDataSchema),
|
|
907
|
+
table: Schema.NullOr(TableDataSchema),
|
|
908
|
+
billing: Schema.NullOr(BillingResultSchema),
|
|
909
|
+
summaryState: Schema.Literals(["pending", "ready", "error"]),
|
|
910
|
+
billingState: Schema.Literals(["pending", "ready", "error"]),
|
|
911
|
+
tableState: Schema.Literals(["pending", "ready", "error"]),
|
|
912
|
+
summaryUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
913
|
+
billingUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
914
|
+
tableUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema))
|
|
915
|
+
});
|
|
916
|
+
var WebSnapshotSchema = Schema.Struct({
|
|
917
|
+
version: Schema.String,
|
|
918
|
+
generatedAt: NonNegativeIntegerSchema,
|
|
919
|
+
tz: Schema.String,
|
|
920
|
+
intervalMs: PositiveFiniteSchema,
|
|
921
|
+
billingIntervalMs: Schema.optionalKey(PositiveFiniteSchema),
|
|
922
|
+
providers: Schema.Array(Schema.Struct({
|
|
923
|
+
id: ProviderIdSchema,
|
|
924
|
+
name: Schema.String,
|
|
925
|
+
color: Schema.String
|
|
926
|
+
})),
|
|
927
|
+
accounts: Schema.Array(WebAccountSchema),
|
|
928
|
+
seeded: Schema.Boolean,
|
|
929
|
+
peak: Schema.NullOr(Schema.Struct({
|
|
930
|
+
state: Schema.Literals(["peak", "off-peak", "weekend"]),
|
|
931
|
+
label: Schema.String,
|
|
932
|
+
// The upstream clock is only normalized to a finite number; do not make
|
|
933
|
+
// the wire contract narrower than the producer's declared type.
|
|
934
|
+
minutesUntilChange: Schema.NullOr(Schema.Finite),
|
|
935
|
+
changesAt: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
936
|
+
}))
|
|
937
|
+
});
|
|
938
|
+
var EmptyPayloadSchema = Schema.Struct({});
|
|
939
|
+
var GetConfigRpc = Rpc.make(TOKMON_WS_METHODS.getConfig, {
|
|
940
|
+
payload: EmptyPayloadSchema,
|
|
941
|
+
success: ConfigStateSchema
|
|
942
|
+
});
|
|
943
|
+
var SetConfigRpc = Rpc.make(TOKMON_WS_METHODS.setConfig, {
|
|
944
|
+
payload: ConfigUpdateRequestSchema,
|
|
945
|
+
success: ConfigStateSchema,
|
|
946
|
+
error: Schema.Union([ConfigUpdateConflictSchema, ConfigPersistenceFailureSchema])
|
|
947
|
+
});
|
|
948
|
+
var RefreshRpc = Rpc.make(TOKMON_WS_METHODS.refresh, {
|
|
949
|
+
payload: Schema.Struct({ scope: RefreshScopeSchema }),
|
|
950
|
+
success: Schema.Void
|
|
951
|
+
});
|
|
952
|
+
var BrowseFsRpc = Rpc.make(TOKMON_WS_METHODS.browseFs, {
|
|
953
|
+
payload: Schema.Struct({ path: Schema.String }),
|
|
954
|
+
success: FsListingSchema
|
|
955
|
+
});
|
|
956
|
+
var SnapshotRpc = Rpc.make(TOKMON_WS_METHODS.snapshot, {
|
|
957
|
+
payload: EmptyPayloadSchema,
|
|
958
|
+
success: WebSnapshotSchema,
|
|
959
|
+
stream: true
|
|
960
|
+
});
|
|
961
|
+
var ConfigRpc = Rpc.make(TOKMON_WS_METHODS.config, {
|
|
962
|
+
payload: EmptyPayloadSchema,
|
|
963
|
+
success: ConfigStateSchema,
|
|
964
|
+
stream: true
|
|
965
|
+
});
|
|
966
|
+
var TokmonRpcGroup = RpcGroup.make(
|
|
967
|
+
GetConfigRpc,
|
|
968
|
+
SetConfigRpc,
|
|
969
|
+
RefreshRpc,
|
|
970
|
+
BrowseFsRpc,
|
|
971
|
+
SnapshotRpc,
|
|
972
|
+
ConfigRpc
|
|
973
|
+
);
|
|
974
|
+
|
|
729
975
|
// src/shared/format.ts
|
|
730
976
|
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
731
977
|
function formatCurrency(value, opts = {}) {
|
|
@@ -773,6 +1019,18 @@ function formatResetIn(iso, now = Date.now()) {
|
|
|
773
1019
|
const hrs = hours % 24;
|
|
774
1020
|
return `${days}d ${hrs}h`;
|
|
775
1021
|
}
|
|
1022
|
+
function formatResetAt(iso, display, now = Date.now(), tz) {
|
|
1023
|
+
const timestamp = Date.parse(iso);
|
|
1024
|
+
if (!Number.isFinite(timestamp)) return iso;
|
|
1025
|
+
if (display === "relative") return formatResetIn(iso, now);
|
|
1026
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
1027
|
+
month: "short",
|
|
1028
|
+
day: "numeric",
|
|
1029
|
+
hour: "numeric",
|
|
1030
|
+
minute: "2-digit",
|
|
1031
|
+
timeZone: tz
|
|
1032
|
+
}).format(new Date(timestamp));
|
|
1033
|
+
}
|
|
776
1034
|
|
|
777
1035
|
// src/format.ts
|
|
778
1036
|
var currency = formatCurrency;
|
|
@@ -786,7 +1044,7 @@ function col(s, w, align = "right") {
|
|
|
786
1044
|
const spaces = " ".repeat(w - s.length);
|
|
787
1045
|
return align === "right" ? spaces + s : s + spaces;
|
|
788
1046
|
}
|
|
789
|
-
var
|
|
1047
|
+
var resetAt = formatResetAt;
|
|
790
1048
|
|
|
791
1049
|
// src/providers/claude/usage.ts
|
|
792
1050
|
import { stat as fsStat, access } from "fs/promises";
|
|
@@ -1188,11 +1446,13 @@ function boolValue(value) {
|
|
|
1188
1446
|
return false;
|
|
1189
1447
|
}
|
|
1190
1448
|
function resetFrom(value) {
|
|
1191
|
-
if (typeof value === "string" && value.trim())
|
|
1449
|
+
if (typeof value === "string" && value.trim()) {
|
|
1450
|
+
const timestamp = Date.parse(value);
|
|
1451
|
+
return Number.isFinite(timestamp) ? new Date(timestamp).toISOString() : null;
|
|
1452
|
+
}
|
|
1192
1453
|
const n = numberValue(value);
|
|
1193
1454
|
if (n === void 0) return null;
|
|
1194
|
-
|
|
1195
|
-
return iso ? resetIn(iso) : null;
|
|
1455
|
+
return msToIso(Math.abs(n) < 1e10 ? n * 1e3 : n);
|
|
1196
1456
|
}
|
|
1197
1457
|
function usageMetric(label, window, primary) {
|
|
1198
1458
|
const used = numberValue(window?.utilization);
|
|
@@ -1745,8 +2005,7 @@ function resetDateMs(window) {
|
|
|
1745
2005
|
}
|
|
1746
2006
|
function resetFrom2(window) {
|
|
1747
2007
|
const ms = resetDateMs(window);
|
|
1748
|
-
|
|
1749
|
-
return iso ? resetIn(iso) : null;
|
|
2008
|
+
return ms === null ? null : msToIso(ms);
|
|
1750
2009
|
}
|
|
1751
2010
|
function windowSeconds(window) {
|
|
1752
2011
|
const seconds = numberValue(window?.limit_window_seconds ?? window?.period_seconds ?? window?.window_seconds);
|
|
@@ -2325,7 +2584,7 @@ async function cursorBillingCore(account) {
|
|
|
2325
2584
|
const rawEnd = usage.billingCycleEnd;
|
|
2326
2585
|
const endMs = timestampMs(rawEnd);
|
|
2327
2586
|
const iso = endMs === null ? null : msToIso(endMs);
|
|
2328
|
-
const resets = iso
|
|
2587
|
+
const resets = iso;
|
|
2329
2588
|
const limit = numberValue(pu.limit);
|
|
2330
2589
|
const planUsedCents = numberValue(pu.totalSpend) ?? (limit !== void 0 && numberValue(pu.remaining) !== void 0 ? limit - numberValue(pu.remaining) : void 0);
|
|
2331
2590
|
const computedPercent = limit !== void 0 && limit > 0 && planUsedCents !== void 0 ? planUsedCents / limit * 100 : void 0;
|
|
@@ -2758,7 +3017,7 @@ function ghConfigDir(homeDir) {
|
|
|
2758
3017
|
function ghHostsPath(homeDir) {
|
|
2759
3018
|
return join13(ghConfigDir(homeDir), "hosts.yml");
|
|
2760
3019
|
}
|
|
2761
|
-
|
|
3020
|
+
function copilotStateDirs(homeDir) {
|
|
2762
3021
|
const home = homeDir ?? homedir9();
|
|
2763
3022
|
const candidates = [
|
|
2764
3023
|
join13(home, ".config", "github-copilot"),
|
|
@@ -2769,7 +3028,10 @@ async function detectCopilot(homeDir) {
|
|
|
2769
3028
|
if (process.platform === "win32") {
|
|
2770
3029
|
candidates.push(join13(envDir("LOCALAPPDATA") ?? join13(home, "AppData", "Local"), "github-copilot"));
|
|
2771
3030
|
}
|
|
2772
|
-
|
|
3031
|
+
return candidates;
|
|
3032
|
+
}
|
|
3033
|
+
async function detectCopilot(homeDir) {
|
|
3034
|
+
for (const path of copilotStateDirs(homeDir)) {
|
|
2773
3035
|
try {
|
|
2774
3036
|
await access7(path);
|
|
2775
3037
|
return true;
|
|
@@ -2871,7 +3133,9 @@ function redactToken(token) {
|
|
|
2871
3133
|
return token.length <= 4 ? "****" : `****${token.slice(-4)}`;
|
|
2872
3134
|
}
|
|
2873
3135
|
function resetDate(value) {
|
|
2874
|
-
|
|
3136
|
+
if (typeof value !== "string" || !value.trim()) return null;
|
|
3137
|
+
const timestamp = Date.parse(value);
|
|
3138
|
+
return Number.isFinite(timestamp) ? new Date(timestamp).toISOString() : null;
|
|
2875
3139
|
}
|
|
2876
3140
|
function boolValue2(value) {
|
|
2877
3141
|
if (typeof value === "boolean") return value;
|
|
@@ -3378,7 +3642,7 @@ function cloudCodeBucketsToMetrics(buckets, options = {}) {
|
|
|
3378
3642
|
used: Math.round((1 - clamped) * 100),
|
|
3379
3643
|
limit: 100,
|
|
3380
3644
|
format: { kind: "percent" },
|
|
3381
|
-
resetsAt: bucket.resetTime && Number.isFinite(Date.parse(bucket.resetTime)) ?
|
|
3645
|
+
resetsAt: bucket.resetTime && Number.isFinite(Date.parse(bucket.resetTime)) ? new Date(bucket.resetTime).toISOString() : null,
|
|
3382
3646
|
primary: i === 0
|
|
3383
3647
|
};
|
|
3384
3648
|
});
|
|
@@ -4294,551 +4558,44 @@ async function detectProviders() {
|
|
|
4294
4558
|
return found.filter((id) => id !== null);
|
|
4295
4559
|
}
|
|
4296
4560
|
|
|
4297
|
-
// src/accounts.ts
|
|
4298
|
-
import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync } from "fs";
|
|
4299
|
-
import { homedir as homedir16 } from "os";
|
|
4300
|
-
import { basename, join as join22, resolve } from "path";
|
|
4301
|
-
|
|
4302
|
-
// src/providers/codex/identity.ts
|
|
4303
|
-
import { readFileSync as readFileSync4 } from "fs";
|
|
4304
|
-
import { join as join21 } from "path";
|
|
4305
|
-
function codexAuthPaths(homeDir) {
|
|
4306
|
-
return [join21(homeDir, ".codex", "auth.json"), join21(homeDir, "auth.json")];
|
|
4307
|
-
}
|
|
4308
|
-
function readCodexIdentity(homeDir) {
|
|
4309
|
-
for (const path of codexAuthPaths(homeDir)) {
|
|
4310
|
-
try {
|
|
4311
|
-
const parsed = JSON.parse(readFileSync4(path, "utf-8"));
|
|
4312
|
-
const { email, displayName, payload } = identityFromIdToken(parsed?.tokens?.id_token);
|
|
4313
|
-
if (!payload) continue;
|
|
4314
|
-
return { email, displayName };
|
|
4315
|
-
} catch {
|
|
4316
|
-
}
|
|
4317
|
-
}
|
|
4318
|
-
return {};
|
|
4319
|
-
}
|
|
4320
|
-
|
|
4321
|
-
// src/accounts.ts
|
|
4322
|
-
function accountKey(providerId, homeDir) {
|
|
4323
|
-
return `${providerId}:${homeDir ? resolve(expandHome(homeDir)) : homedir16()}`;
|
|
4324
|
-
}
|
|
4325
|
-
function uniqueId(base, used) {
|
|
4326
|
-
let id = slugify(base) || "account";
|
|
4327
|
-
if (!used.has(id)) {
|
|
4328
|
-
used.add(id);
|
|
4329
|
-
return id;
|
|
4330
|
-
}
|
|
4331
|
-
for (let i = 2; i < 1e3; i++) {
|
|
4332
|
-
const next = `${id}_${i}`;
|
|
4333
|
-
if (!used.has(next)) {
|
|
4334
|
-
used.add(next);
|
|
4335
|
-
return next;
|
|
4336
|
-
}
|
|
4337
|
-
}
|
|
4338
|
-
id = `${id}_${Date.now()}`;
|
|
4339
|
-
used.add(id);
|
|
4340
|
-
return id;
|
|
4341
|
-
}
|
|
4342
|
-
function hasClaudeState(homeDir) {
|
|
4343
|
-
return existsSync2(join22(homeDir, ".claude.json")) || existsSync2(join22(homeDir, ".claude", ".credentials.json")) || existsSync2(join22(homeDir, ".claude", "projects")) || existsSync2(join22(homeDir, ".config", "claude", ".credentials.json")) || existsSync2(join22(homeDir, ".config", "claude", "projects"));
|
|
4344
|
-
}
|
|
4345
|
-
function candidateAlternateHomes(prefix) {
|
|
4346
|
-
const home = homedir16();
|
|
4347
|
-
let entries;
|
|
4348
|
-
try {
|
|
4349
|
-
entries = readdirSync2(home);
|
|
4350
|
-
} catch {
|
|
4351
|
-
return [];
|
|
4352
|
-
}
|
|
4353
|
-
const out = [];
|
|
4354
|
-
const pattern = new RegExp(`^\\.${prefix}[_-]`);
|
|
4355
|
-
for (const name of entries) {
|
|
4356
|
-
if (!pattern.test(name)) continue;
|
|
4357
|
-
const path = join22(home, name);
|
|
4358
|
-
try {
|
|
4359
|
-
if (!statSync(path).isDirectory()) continue;
|
|
4360
|
-
out.push(path);
|
|
4361
|
-
} catch {
|
|
4362
|
-
}
|
|
4363
|
-
}
|
|
4364
|
-
return out.sort();
|
|
4365
|
-
}
|
|
4366
|
-
function labelForClaudeHome(homeDir) {
|
|
4367
|
-
const identity = readClaudeIdentity(homeDir);
|
|
4368
|
-
if (identity.email) return `Claude ${identity.email}`;
|
|
4369
|
-
if (identity.displayName) return `Claude ${identity.displayName}`;
|
|
4370
|
-
const raw = basename(homeDir).replace(/^\.claude[_-]?/, "").replace(/[_-]+/g, " ").trim();
|
|
4371
|
-
return raw ? `Claude ${raw}` : "Claude";
|
|
4372
|
-
}
|
|
4373
|
-
function hasCodexAuth(homeDir) {
|
|
4374
|
-
for (const path of codexAuthPaths(homeDir)) {
|
|
4375
|
-
try {
|
|
4376
|
-
const parsed = JSON.parse(readFileSync5(path, "utf-8"));
|
|
4377
|
-
const accessToken = parsed?.tokens?.access_token;
|
|
4378
|
-
if (typeof accessToken === "string" && accessToken.trim()) return true;
|
|
4379
|
-
} catch {
|
|
4380
|
-
}
|
|
4381
|
-
}
|
|
4382
|
-
return false;
|
|
4383
|
-
}
|
|
4384
|
-
function labelForCodexHome(homeDir) {
|
|
4385
|
-
const identity = readCodexIdentity(homeDir);
|
|
4386
|
-
if (identity.email) return `Codex ${identity.email}`;
|
|
4387
|
-
if (identity.displayName) return `Codex ${identity.displayName}`;
|
|
4388
|
-
const raw = basename(homeDir).replace(/^\.codex[_-]?/, "").replace(/[_-]+/g, " ").trim();
|
|
4389
|
-
return raw ? `Codex ${raw}` : "Codex";
|
|
4390
|
-
}
|
|
4391
|
-
function discoverClaudeAccounts(usedIds) {
|
|
4392
|
-
const provider = PROVIDERS.claude;
|
|
4393
|
-
const out = [];
|
|
4394
|
-
for (const homeDir of candidateAlternateHomes("claude")) {
|
|
4395
|
-
if (!hasClaudeState(homeDir)) continue;
|
|
4396
|
-
const suffix = basename(homeDir).replace(/^\.claude[_-]?/, "") || basename(homeDir);
|
|
4397
|
-
out.push({
|
|
4398
|
-
id: uniqueId(`claude_${suffix}`, usedIds),
|
|
4399
|
-
providerId: "claude",
|
|
4400
|
-
name: labelForClaudeHome(homeDir),
|
|
4401
|
-
color: provider.color,
|
|
4402
|
-
homeDir
|
|
4403
|
-
});
|
|
4404
|
-
}
|
|
4405
|
-
return out;
|
|
4406
|
-
}
|
|
4407
|
-
function discoverCodexAccounts(usedIds) {
|
|
4408
|
-
const provider = PROVIDERS.codex;
|
|
4409
|
-
const out = [];
|
|
4410
|
-
for (const homeDir of candidateAlternateHomes("codex")) {
|
|
4411
|
-
if (!hasCodexAuth(homeDir)) continue;
|
|
4412
|
-
const suffix = basename(homeDir).replace(/^\.codex[_-]?/, "") || basename(homeDir);
|
|
4413
|
-
out.push({
|
|
4414
|
-
id: uniqueId(`codex_${suffix}`, usedIds),
|
|
4415
|
-
providerId: "codex",
|
|
4416
|
-
name: labelForCodexHome(homeDir),
|
|
4417
|
-
color: provider.color,
|
|
4418
|
-
homeDir
|
|
4419
|
-
});
|
|
4420
|
-
}
|
|
4421
|
-
return out;
|
|
4422
|
-
}
|
|
4423
|
-
function discoverProviderAccounts(providerId, usedIds) {
|
|
4424
|
-
if (providerId === "claude") return discoverClaudeAccounts(usedIds);
|
|
4425
|
-
if (providerId === "codex") return discoverCodexAccounts(usedIds);
|
|
4426
|
-
return [];
|
|
4427
|
-
}
|
|
4428
|
-
function buildAccounts(config, detected) {
|
|
4429
|
-
const out = [];
|
|
4430
|
-
const usedIds = new Set(config.accounts.map((a) => a.id));
|
|
4431
|
-
const seenKeys = /* @__PURE__ */ new Set();
|
|
4432
|
-
const add = (account) => {
|
|
4433
|
-
const key = accountKey(account.providerId, account.homeDir);
|
|
4434
|
-
if (seenKeys.has(key)) return;
|
|
4435
|
-
seenKeys.add(key);
|
|
4436
|
-
out.push(account);
|
|
4437
|
-
};
|
|
4438
|
-
for (const pid of PROVIDER_ORDER) {
|
|
4439
|
-
if (config.disabledProviders.includes(pid)) continue;
|
|
4440
|
-
const provider = PROVIDERS[pid];
|
|
4441
|
-
const configured = config.accounts.filter((a) => a.providerId === pid);
|
|
4442
|
-
for (const a of configured) {
|
|
4443
|
-
add({
|
|
4444
|
-
id: a.id,
|
|
4445
|
-
providerId: pid,
|
|
4446
|
-
name: a.name,
|
|
4447
|
-
color: a.color || provider.color,
|
|
4448
|
-
homeDir: a.homeDir && a.homeDir !== "~" ? expandHome(a.homeDir) : void 0
|
|
4449
|
-
});
|
|
4450
|
-
}
|
|
4451
|
-
const discovered = discoverProviderAccounts(pid, usedIds);
|
|
4452
|
-
if (detected.includes(pid)) {
|
|
4453
|
-
add({ id: pid, providerId: pid, name: provider.name, color: provider.color, homeDir: void 0 });
|
|
4454
|
-
}
|
|
4455
|
-
for (const account of discovered) {
|
|
4456
|
-
add(account);
|
|
4457
|
-
}
|
|
4458
|
-
}
|
|
4459
|
-
return out;
|
|
4460
|
-
}
|
|
4461
|
-
function accountsByProvider(accounts) {
|
|
4462
|
-
const groups = [];
|
|
4463
|
-
for (const pid of PROVIDER_ORDER) {
|
|
4464
|
-
const list = accounts.filter((a) => a.providerId === pid);
|
|
4465
|
-
if (list.length > 0) groups.push({ provider: pid, accounts: list });
|
|
4466
|
-
}
|
|
4467
|
-
return groups;
|
|
4468
|
-
}
|
|
4469
|
-
|
|
4470
|
-
// src/shared/colors.ts
|
|
4471
|
-
var FALLBACK_HEX = "#8d9090";
|
|
4472
|
-
var NAMED_HEX = {
|
|
4473
|
-
green: "#6caa71",
|
|
4474
|
-
greenBright: "#79be7e",
|
|
4475
|
-
cyan: "#7ccbcd",
|
|
4476
|
-
cyanBright: "#84dde0",
|
|
4477
|
-
blue: "#6d96b4",
|
|
4478
|
-
blueBright: "#67b5ed",
|
|
4479
|
-
magenta: "#bd7bcd",
|
|
4480
|
-
magentaBright: "#d389e5",
|
|
4481
|
-
yellow: "#c4ac62",
|
|
4482
|
-
yellowBright: "#d9c074",
|
|
4483
|
-
red: "#b45648",
|
|
4484
|
-
redBright: "#cf6a5a",
|
|
4485
|
-
white: "#dee5eb",
|
|
4486
|
-
whiteBright: "#f3f5f5",
|
|
4487
|
-
gray: FALLBACK_HEX,
|
|
4488
|
-
grey: FALLBACK_HEX
|
|
4489
|
-
};
|
|
4490
|
-
var PROVIDER_HEX = {
|
|
4491
|
-
claude: NAMED_HEX.green,
|
|
4492
|
-
codex: NAMED_HEX.cyan,
|
|
4493
|
-
cursor: NAMED_HEX.magenta,
|
|
4494
|
-
copilot: NAMED_HEX.white,
|
|
4495
|
-
pi: NAMED_HEX.blue,
|
|
4496
|
-
opencode: NAMED_HEX.yellow,
|
|
4497
|
-
antigravity: NAMED_HEX.red,
|
|
4498
|
-
gemini: NAMED_HEX.greenBright,
|
|
4499
|
-
grok: NAMED_HEX.yellowBright
|
|
4500
|
-
};
|
|
4501
|
-
function namedHex(name) {
|
|
4502
|
-
if (!name) return FALLBACK_HEX;
|
|
4503
|
-
if (name.startsWith("#")) return name;
|
|
4504
|
-
return NAMED_HEX[name] ?? FALLBACK_HEX;
|
|
4505
|
-
}
|
|
4506
|
-
function colorHex(accountColor, providerColorName) {
|
|
4507
|
-
if (accountColor) {
|
|
4508
|
-
if (accountColor.startsWith("#")) return accountColor;
|
|
4509
|
-
const named = NAMED_HEX[accountColor];
|
|
4510
|
-
if (named) return named;
|
|
4511
|
-
}
|
|
4512
|
-
return namedHex(providerColorName);
|
|
4513
|
-
}
|
|
4514
|
-
var MODEL_PALETTE = [
|
|
4515
|
-
"#00d7ff",
|
|
4516
|
-
"#00d787",
|
|
4517
|
-
"#e6b450",
|
|
4518
|
-
"#d75f87",
|
|
4519
|
-
"#5f87ff",
|
|
4520
|
-
"#af87ff",
|
|
4521
|
-
"#5fd7a7",
|
|
4522
|
-
"#ff8787",
|
|
4523
|
-
"#d7af5f",
|
|
4524
|
-
"#87d7ff",
|
|
4525
|
-
"#d787d7",
|
|
4526
|
-
"#9ee493",
|
|
4527
|
-
"#ffb454",
|
|
4528
|
-
"#7aa2f7",
|
|
4529
|
-
"#bb9af7"
|
|
4530
|
-
];
|
|
4531
|
-
var modelColorCache = /* @__PURE__ */ new Map();
|
|
4532
|
-
function modelColor(name) {
|
|
4533
|
-
const cached = modelColorCache.get(name);
|
|
4534
|
-
if (cached) return cached;
|
|
4535
|
-
let hash2 = 0;
|
|
4536
|
-
for (let i = 0; i < name.length; i++) hash2 = hash2 * 31 + name.charCodeAt(i) >>> 0;
|
|
4537
|
-
const color = MODEL_PALETTE[hash2 % MODEL_PALETTE.length];
|
|
4538
|
-
modelColorCache.set(name, color);
|
|
4539
|
-
return color;
|
|
4540
|
-
}
|
|
4541
|
-
var TOKEN_BUCKET = {
|
|
4542
|
-
input: NAMED_HEX.blue,
|
|
4543
|
-
output: NAMED_HEX.green,
|
|
4544
|
-
cacheCreate: NAMED_HEX.yellow,
|
|
4545
|
-
cacheRead: NAMED_HEX.cyan
|
|
4546
|
-
};
|
|
4547
|
-
|
|
4548
|
-
// src/async.ts
|
|
4549
|
-
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
4550
|
-
function withTimeout(promise, ms = DEFAULT_TIMEOUT_MS) {
|
|
4551
|
-
let timer;
|
|
4552
|
-
const timeout = new Promise((_, reject) => {
|
|
4553
|
-
timer = setTimeout(() => reject(new Error("operation timeout")), ms);
|
|
4554
|
-
timer.unref?.();
|
|
4555
|
-
});
|
|
4556
|
-
return Promise.race([promise, timeout]).finally(() => {
|
|
4557
|
-
if (timer) clearTimeout(timer);
|
|
4558
|
-
});
|
|
4559
|
-
}
|
|
4560
|
-
|
|
4561
|
-
// src/peak.ts
|
|
4562
|
-
async function fetchPeak() {
|
|
4563
|
-
try {
|
|
4564
|
-
const res = await fetch("https://promoclock.co/api/status", {
|
|
4565
|
-
headers: { "Accept": "application/json", "User-Agent": "tokmon" },
|
|
4566
|
-
signal: AbortSignal.timeout(3e3)
|
|
4567
|
-
});
|
|
4568
|
-
if (!res.ok) return null;
|
|
4569
|
-
const data = await readJson(res);
|
|
4570
|
-
if (!data) return null;
|
|
4571
|
-
let state;
|
|
4572
|
-
if (data.isPeak === true || data.status === "peak") state = "peak";
|
|
4573
|
-
else if (data.isWeekend === true || data.status === "weekend") state = "weekend";
|
|
4574
|
-
else if (data.isOffPeak === true || data.status === "off_peak" || data.status === "off-peak") state = "off-peak";
|
|
4575
|
-
else return null;
|
|
4576
|
-
const minutesUntilChange = typeof data.minutesUntilChange === "number" && Number.isFinite(data.minutesUntilChange) ? data.minutesUntilChange : null;
|
|
4577
|
-
return {
|
|
4578
|
-
state,
|
|
4579
|
-
label: state === "peak" ? "Peak" : state === "weekend" ? "Weekend" : "Off-Peak",
|
|
4580
|
-
minutesUntilChange
|
|
4581
|
-
};
|
|
4582
|
-
} catch {
|
|
4583
|
-
return null;
|
|
4584
|
-
}
|
|
4585
|
-
}
|
|
4586
|
-
|
|
4587
|
-
// src/rpc/contract.ts
|
|
4588
|
-
import { Schema } from "effect";
|
|
4589
|
-
import * as Rpc from "effect/unstable/rpc/Rpc";
|
|
4590
|
-
import * as RpcGroup from "effect/unstable/rpc/RpcGroup";
|
|
4591
|
-
var TOKMON_WS_PATH = "/ws";
|
|
4592
|
-
var TOKMON_PROTOCOL_VERSION = 2;
|
|
4593
|
-
var TOKMON_CAPABILITIES = ["config-cas", "config-revision"];
|
|
4594
|
-
var TOKMON_WS_METHODS = {
|
|
4595
|
-
getConfig: "tokmon.getConfig",
|
|
4596
|
-
setConfig: "tokmon.setConfig",
|
|
4597
|
-
refresh: "tokmon.refresh",
|
|
4598
|
-
browseFs: "tokmon.browseFs",
|
|
4599
|
-
snapshot: "tokmon.snapshot",
|
|
4600
|
-
config: "tokmon.config"
|
|
4601
|
-
};
|
|
4602
|
-
var RefreshScopeSchema = Schema.Literals([
|
|
4603
|
-
"all",
|
|
4604
|
-
"summary",
|
|
4605
|
-
"table",
|
|
4606
|
-
"billing",
|
|
4607
|
-
"peak"
|
|
4608
|
-
]);
|
|
4609
|
-
var ProviderIdSchema = Schema.Literals(PROVIDER_IDS);
|
|
4610
|
-
var NonNegativeIntegerSchema = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
4611
|
-
var PositiveFiniteSchema = Schema.Finite.check(Schema.isGreaterThanOrEqualTo(1));
|
|
4612
|
-
var AccountSchema = Schema.Struct({
|
|
4613
|
-
id: Schema.String,
|
|
4614
|
-
providerId: ProviderIdSchema,
|
|
4615
|
-
name: Schema.String,
|
|
4616
|
-
homeDir: Schema.String,
|
|
4617
|
-
color: Schema.optionalKey(Schema.String)
|
|
4618
|
-
});
|
|
4619
|
-
var ConfigSchema = Schema.Struct({
|
|
4620
|
-
revision: NonNegativeIntegerSchema,
|
|
4621
|
-
interval: PositiveFiniteSchema,
|
|
4622
|
-
billingInterval: PositiveFiniteSchema,
|
|
4623
|
-
clearScreen: Schema.Boolean,
|
|
4624
|
-
privacyMode: Schema.Boolean,
|
|
4625
|
-
privacyToggleKey: Schema.String,
|
|
4626
|
-
timezone: Schema.NullOr(Schema.String),
|
|
4627
|
-
accounts: Schema.Array(AccountSchema),
|
|
4628
|
-
activeAccountId: Schema.NullOr(Schema.String),
|
|
4629
|
-
disabledProviders: Schema.Array(ProviderIdSchema),
|
|
4630
|
-
onboarded: Schema.Boolean,
|
|
4631
|
-
dashboardLayout: Schema.Literals(["grid", "single"]),
|
|
4632
|
-
defaultFocus: Schema.Literals(["all", "last"]),
|
|
4633
|
-
ascii: Schema.Literals(["auto", "on", "off"]),
|
|
4634
|
-
allowNetworkAccess: Schema.Boolean,
|
|
4635
|
-
knownProviders: Schema.Array(ProviderIdSchema)
|
|
4636
|
-
});
|
|
4637
|
-
var ProtocolInfoSchema = Schema.Struct({
|
|
4638
|
-
version: Schema.Literal(TOKMON_PROTOCOL_VERSION),
|
|
4639
|
-
// Capabilities are additive within a protocol version. Older clients must
|
|
4640
|
-
// preserve forward compatibility when a newer daemon advertises one they do
|
|
4641
|
-
// not understand yet.
|
|
4642
|
-
capabilities: Schema.Array(Schema.String)
|
|
4643
|
-
});
|
|
4644
|
-
var ConfigStateSchema = Schema.Struct({
|
|
4645
|
-
protocol: ProtocolInfoSchema,
|
|
4646
|
-
config: ConfigSchema
|
|
4647
|
-
});
|
|
4648
|
-
var ConfigUpdateRequestSchema = Schema.Struct({
|
|
4649
|
-
expectedRevision: NonNegativeIntegerSchema,
|
|
4650
|
-
config: ConfigSchema
|
|
4651
|
-
});
|
|
4652
|
-
var ConfigUpdateConflictSchema = Schema.Struct({
|
|
4653
|
-
kind: Schema.Literal("conflict"),
|
|
4654
|
-
state: ConfigStateSchema
|
|
4655
|
-
});
|
|
4656
|
-
var ConfigPersistenceFailureSchema = Schema.Struct({
|
|
4657
|
-
kind: Schema.Literal("persistence"),
|
|
4658
|
-
message: Schema.String
|
|
4659
|
-
});
|
|
4660
|
-
var FsEntrySchema = Schema.Struct({
|
|
4661
|
-
name: Schema.String,
|
|
4662
|
-
path: Schema.String,
|
|
4663
|
-
dir: Schema.Boolean
|
|
4664
|
-
});
|
|
4665
|
-
var FsListingSchema = Schema.Struct({
|
|
4666
|
-
path: Schema.String,
|
|
4667
|
-
parent: Schema.NullOr(Schema.String),
|
|
4668
|
-
entries: Schema.Array(FsEntrySchema)
|
|
4669
|
-
});
|
|
4670
|
-
var UsageSummarySchema = Schema.Struct({
|
|
4671
|
-
cost: Schema.Finite,
|
|
4672
|
-
tokens: Schema.Finite,
|
|
4673
|
-
cacheRead: Schema.Finite,
|
|
4674
|
-
cacheSavings: Schema.Finite
|
|
4675
|
-
});
|
|
4676
|
-
var ModelDetailSchema = Schema.Struct({
|
|
4677
|
-
name: Schema.String,
|
|
4678
|
-
input: Schema.Finite,
|
|
4679
|
-
output: Schema.Finite,
|
|
4680
|
-
cacheCreate: Schema.Finite,
|
|
4681
|
-
cacheRead: Schema.Finite,
|
|
4682
|
-
cacheSavings: Schema.Finite,
|
|
4683
|
-
cost: Schema.Finite,
|
|
4684
|
-
count: Schema.Finite
|
|
4685
|
-
});
|
|
4686
|
-
var TableRowSchema = Schema.Struct({
|
|
4687
|
-
label: Schema.String,
|
|
4688
|
-
models: Schema.Array(Schema.String),
|
|
4689
|
-
input: Schema.Finite,
|
|
4690
|
-
output: Schema.Finite,
|
|
4691
|
-
cacheCreate: Schema.Finite,
|
|
4692
|
-
cacheRead: Schema.Finite,
|
|
4693
|
-
cacheSavings: Schema.Finite,
|
|
4694
|
-
total: Schema.Finite,
|
|
4695
|
-
cost: Schema.Finite,
|
|
4696
|
-
count: Schema.Finite,
|
|
4697
|
-
breakdown: Schema.Array(ModelDetailSchema)
|
|
4698
|
-
});
|
|
4699
|
-
var DashboardDataSchema = Schema.Struct({
|
|
4700
|
-
today: UsageSummarySchema,
|
|
4701
|
-
week: UsageSummarySchema,
|
|
4702
|
-
month: UsageSummarySchema,
|
|
4703
|
-
burnRate: Schema.Finite,
|
|
4704
|
-
series: Schema.Array(Schema.Finite)
|
|
4705
|
-
});
|
|
4706
|
-
var TableDataSchema = Schema.Struct({
|
|
4707
|
-
daily: Schema.Array(TableRowSchema),
|
|
4708
|
-
weekly: Schema.Array(TableRowSchema),
|
|
4709
|
-
monthly: Schema.Array(TableRowSchema)
|
|
4710
|
-
});
|
|
4711
|
-
var MetricFormatSchema = Schema.Union([
|
|
4712
|
-
Schema.Struct({ kind: Schema.Literal("percent") }),
|
|
4713
|
-
Schema.Struct({ kind: Schema.Literal("dollars"), currency: Schema.optionalKey(Schema.String) }),
|
|
4714
|
-
Schema.Struct({ kind: Schema.Literal("count"), suffix: Schema.optionalKey(Schema.String) })
|
|
4715
|
-
]);
|
|
4716
|
-
var MetricSchema = Schema.Struct({
|
|
4717
|
-
label: Schema.String,
|
|
4718
|
-
used: Schema.Finite,
|
|
4719
|
-
limit: Schema.NullOr(Schema.Finite),
|
|
4720
|
-
format: MetricFormatSchema,
|
|
4721
|
-
resetsAt: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4722
|
-
primary: Schema.optionalKey(Schema.Boolean)
|
|
4723
|
-
});
|
|
4724
|
-
var BillingResultSchema = Schema.Struct({
|
|
4725
|
-
plan: Schema.NullOr(Schema.String),
|
|
4726
|
-
metrics: Schema.Array(MetricSchema),
|
|
4727
|
-
error: Schema.NullOr(Schema.String),
|
|
4728
|
-
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4729
|
-
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4730
|
-
activity: Schema.optionalKey(Schema.NullOr(Schema.Struct({
|
|
4731
|
-
series: Schema.Array(Schema.Finite),
|
|
4732
|
-
summary: Schema.String
|
|
4733
|
-
}))),
|
|
4734
|
-
modelSpend: Schema.optionalKey(Schema.NullOr(Schema.Array(Schema.Struct({
|
|
4735
|
-
name: Schema.String,
|
|
4736
|
-
usd: Schema.Finite,
|
|
4737
|
-
requests: Schema.Finite
|
|
4738
|
-
}))))
|
|
4739
|
-
});
|
|
4740
|
-
var WebAccountSchema = Schema.Struct({
|
|
4741
|
-
id: Schema.String,
|
|
4742
|
-
providerId: ProviderIdSchema,
|
|
4743
|
-
name: Schema.String,
|
|
4744
|
-
color: Schema.String,
|
|
4745
|
-
homeDir: Schema.NullOr(Schema.String),
|
|
4746
|
-
hasUsage: Schema.Boolean,
|
|
4747
|
-
hasBilling: Schema.Boolean,
|
|
4748
|
-
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4749
|
-
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4750
|
-
plan: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4751
|
-
dashboard: Schema.NullOr(DashboardDataSchema),
|
|
4752
|
-
table: Schema.NullOr(TableDataSchema),
|
|
4753
|
-
billing: Schema.NullOr(BillingResultSchema),
|
|
4754
|
-
summaryState: Schema.Literals(["pending", "ready", "error"]),
|
|
4755
|
-
billingState: Schema.Literals(["pending", "ready", "error"]),
|
|
4756
|
-
tableState: Schema.Literals(["pending", "ready", "error"]),
|
|
4757
|
-
summaryUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
4758
|
-
billingUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
4759
|
-
tableUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema))
|
|
4760
|
-
});
|
|
4761
|
-
var WebSnapshotSchema = Schema.Struct({
|
|
4762
|
-
version: Schema.String,
|
|
4763
|
-
generatedAt: NonNegativeIntegerSchema,
|
|
4764
|
-
tz: Schema.String,
|
|
4765
|
-
intervalMs: PositiveFiniteSchema,
|
|
4766
|
-
billingIntervalMs: Schema.optionalKey(PositiveFiniteSchema),
|
|
4767
|
-
providers: Schema.Array(Schema.Struct({
|
|
4768
|
-
id: ProviderIdSchema,
|
|
4769
|
-
name: Schema.String,
|
|
4770
|
-
color: Schema.String
|
|
4771
|
-
})),
|
|
4772
|
-
accounts: Schema.Array(WebAccountSchema),
|
|
4773
|
-
seeded: Schema.Boolean,
|
|
4774
|
-
peak: Schema.NullOr(Schema.Struct({
|
|
4775
|
-
state: Schema.Literals(["peak", "off-peak", "weekend"]),
|
|
4776
|
-
label: Schema.String,
|
|
4777
|
-
// The upstream clock is only normalized to a finite number; do not make
|
|
4778
|
-
// the wire contract narrower than the producer's declared type.
|
|
4779
|
-
minutesUntilChange: Schema.NullOr(Schema.Finite)
|
|
4780
|
-
}))
|
|
4781
|
-
});
|
|
4782
|
-
var EmptyPayloadSchema = Schema.Struct({});
|
|
4783
|
-
var GetConfigRpc = Rpc.make(TOKMON_WS_METHODS.getConfig, {
|
|
4784
|
-
payload: EmptyPayloadSchema,
|
|
4785
|
-
success: ConfigStateSchema
|
|
4786
|
-
});
|
|
4787
|
-
var SetConfigRpc = Rpc.make(TOKMON_WS_METHODS.setConfig, {
|
|
4788
|
-
payload: ConfigUpdateRequestSchema,
|
|
4789
|
-
success: ConfigStateSchema,
|
|
4790
|
-
error: Schema.Union([ConfigUpdateConflictSchema, ConfigPersistenceFailureSchema])
|
|
4791
|
-
});
|
|
4792
|
-
var RefreshRpc = Rpc.make(TOKMON_WS_METHODS.refresh, {
|
|
4793
|
-
payload: Schema.Struct({ scope: RefreshScopeSchema }),
|
|
4794
|
-
success: Schema.Void
|
|
4795
|
-
});
|
|
4796
|
-
var BrowseFsRpc = Rpc.make(TOKMON_WS_METHODS.browseFs, {
|
|
4797
|
-
payload: Schema.Struct({ path: Schema.String }),
|
|
4798
|
-
success: FsListingSchema
|
|
4799
|
-
});
|
|
4800
|
-
var SnapshotRpc = Rpc.make(TOKMON_WS_METHODS.snapshot, {
|
|
4801
|
-
payload: EmptyPayloadSchema,
|
|
4802
|
-
success: WebSnapshotSchema,
|
|
4803
|
-
stream: true
|
|
4804
|
-
});
|
|
4805
|
-
var ConfigRpc = Rpc.make(TOKMON_WS_METHODS.config, {
|
|
4806
|
-
payload: EmptyPayloadSchema,
|
|
4807
|
-
success: ConfigStateSchema,
|
|
4808
|
-
stream: true
|
|
4809
|
-
});
|
|
4810
|
-
var TokmonRpcGroup = RpcGroup.make(
|
|
4811
|
-
GetConfigRpc,
|
|
4812
|
-
SetConfigRpc,
|
|
4813
|
-
RefreshRpc,
|
|
4814
|
-
BrowseFsRpc,
|
|
4815
|
-
SnapshotRpc,
|
|
4816
|
-
ConfigRpc
|
|
4817
|
-
);
|
|
4818
|
-
|
|
4819
4561
|
export {
|
|
4562
|
+
TOKMON_WS_PATH,
|
|
4563
|
+
TOKMON_PROTOCOL_VERSION,
|
|
4564
|
+
TOKMON_CAPABILITIES,
|
|
4565
|
+
TOKMON_WS_METHODS,
|
|
4566
|
+
TokmonRpcGroup,
|
|
4567
|
+
withTimeout,
|
|
4820
4568
|
systemTimezone,
|
|
4821
4569
|
resolveTimezone,
|
|
4570
|
+
dayKey,
|
|
4571
|
+
startOfMonth,
|
|
4572
|
+
startOfWeek,
|
|
4822
4573
|
flushDisk,
|
|
4823
4574
|
coalesceTables,
|
|
4575
|
+
claudeConfigDirs,
|
|
4576
|
+
readJson,
|
|
4577
|
+
readClaudeIdentity,
|
|
4578
|
+
codexHomes,
|
|
4579
|
+
identityFromIdToken,
|
|
4580
|
+
formatResetAt,
|
|
4824
4581
|
currency,
|
|
4825
4582
|
tokens,
|
|
4826
4583
|
time,
|
|
4827
4584
|
shortDate,
|
|
4828
4585
|
col,
|
|
4586
|
+
resetAt,
|
|
4587
|
+
cursorStateDb,
|
|
4588
|
+
piSessionsDir,
|
|
4589
|
+
opencodeDbPaths,
|
|
4590
|
+
ghHostsPath,
|
|
4591
|
+
copilotStateDirs,
|
|
4592
|
+
antigravityStateDb,
|
|
4593
|
+
geminiTmpDir,
|
|
4594
|
+
geminiCredsPath,
|
|
4595
|
+
geminiDir,
|
|
4596
|
+
grokHomes,
|
|
4597
|
+
grokAuthPaths,
|
|
4829
4598
|
PROVIDER_ORDER,
|
|
4830
4599
|
PROVIDERS,
|
|
4831
|
-
detectProviders
|
|
4832
|
-
buildAccounts,
|
|
4833
|
-
accountsByProvider,
|
|
4834
|
-
namedHex,
|
|
4835
|
-
colorHex,
|
|
4836
|
-
modelColor,
|
|
4837
|
-
withTimeout,
|
|
4838
|
-
fetchPeak,
|
|
4839
|
-
TOKMON_WS_PATH,
|
|
4840
|
-
TOKMON_PROTOCOL_VERSION,
|
|
4841
|
-
TOKMON_CAPABILITIES,
|
|
4842
|
-
TOKMON_WS_METHODS,
|
|
4843
|
-
TokmonRpcGroup
|
|
4600
|
+
detectProviders
|
|
4844
4601
|
};
|