tokmon 0.23.4 → 0.24.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 +23 -5
- package/dist/{bootstrap-ink-BIOLTP7F.js → bootstrap-ink-HL2BYNW3.js} +37 -292
- package/dist/{chunk-RM3ZE44Z.js → chunk-3TJVFKXV.js} +1 -1
- package/dist/chunk-42H7R376.js +298 -0
- package/dist/chunk-45ZP755H.js +275 -0
- package/dist/{chunk-DJPUYMZM.js → chunk-5CWOJMAH.js} +2 -0
- package/dist/{chunk-2AFQKH5O.js → chunk-O27I2XFN.js} +278 -539
- package/dist/{chunk-2K4L4QQK.js → chunk-REO4O5VE.js} +68 -79
- package/dist/{chunk-Q2DSDWO2.js → chunk-SMPY52EV.js} +1 -30
- package/dist/{daemon-handle-6F2IB6CU.js → chunk-W2WGBXZG.js} +8 -9
- package/dist/cli-command-TLGIGF63.js +526 -0
- package/dist/cli.js +30 -5
- package/dist/{config-5CNJN3P7.js → config-QC5QSP3G.js} +1 -1
- package/dist/{daemon-PP3QAT6E.js → daemon-F4EGY77J.js} +43 -17
- package/dist/daemon-handle-NLCLYWFU.js +10 -0
- package/dist/server-X63FGHIZ.js +11 -0
- package/dist/web/assets/{Area-BALPhJJp.js → Area-DCES17aZ.js} +1 -1
- package/dist/web/assets/{analytics-uHVeOhLh.js → analytics-DDW6zcnj.js} +2 -2
- package/dist/web/assets/{breakdown-CR5dNNSG.js → breakdown-D5LPPtqh.js} +1 -1
- package/dist/web/assets/{chart-DRkqw0fm.js → chart-bHY7MQV0.js} +1 -1
- package/dist/web/assets/{explore-C-bHaX-I.js → explore-DdWB-Pu7.js} +1 -1
- package/dist/web/assets/index-C9jxb2o3.js +83 -0
- package/dist/web/assets/index-m0KfWnN2.css +1 -0
- package/dist/web/assets/{models-Qc2daHCo.js → models-o1wJnG6w.js} +2 -2
- package/dist/web/assets/{overview-D4VG2awg.js → overview-wq2uAEk4.js} +2 -2
- package/dist/web/assets/{panel-C1CsBs1H.js → panel-DBnK1oy0.js} +1 -1
- package/dist/web/assets/{primitives-S4UDgnZq.js → primitives-CBmteetD.js} +1 -1
- package/dist/web/assets/settings-sheet-CZ6GEPl3.js +1 -0
- package/dist/web/assets/{share-sheet-BpZBju-k.js → share-sheet-DUee3FlK.js} +1 -1
- package/dist/web/assets/{timeline-Cp-fyeuK.js → timeline-BxHwOJA_.js} +1 -1
- package/dist/web/assets/{use-dialog-trap-DaKbCG1Z.js → use-dialog-trap-30EqxYF-.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/server-UHQEOVQH.js +0 -10
- package/dist/web/assets/index-C1jQdagn.js +0 -83
- package/dist/web/assets/index-DSj-Bxov.css +0 -1
- package/dist/web/assets/settings-sheet-DHi4Dt2z.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-5CWOJMAH.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,238 @@ 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
|
+
knownProviders: Schema.Array(ProviderIdSchema)
|
|
790
|
+
});
|
|
791
|
+
var ProtocolInfoSchema = Schema.Struct({
|
|
792
|
+
version: Schema.Literal(TOKMON_PROTOCOL_VERSION),
|
|
793
|
+
// Capabilities are additive within a protocol version. Older clients must
|
|
794
|
+
// preserve forward compatibility when a newer daemon advertises one they do
|
|
795
|
+
// not understand yet.
|
|
796
|
+
capabilities: Schema.Array(Schema.String)
|
|
797
|
+
});
|
|
798
|
+
var ConfigStateSchema = Schema.Struct({
|
|
799
|
+
protocol: ProtocolInfoSchema,
|
|
800
|
+
config: ConfigSchema
|
|
801
|
+
});
|
|
802
|
+
var ConfigUpdateRequestSchema = Schema.Struct({
|
|
803
|
+
expectedRevision: NonNegativeIntegerSchema,
|
|
804
|
+
config: ConfigSchema
|
|
805
|
+
});
|
|
806
|
+
var ConfigUpdateConflictSchema = Schema.Struct({
|
|
807
|
+
kind: Schema.Literal("conflict"),
|
|
808
|
+
state: ConfigStateSchema
|
|
809
|
+
});
|
|
810
|
+
var ConfigPersistenceFailureSchema = Schema.Struct({
|
|
811
|
+
kind: Schema.Literal("persistence"),
|
|
812
|
+
message: Schema.String
|
|
813
|
+
});
|
|
814
|
+
var FsEntrySchema = Schema.Struct({
|
|
815
|
+
name: Schema.String,
|
|
816
|
+
path: Schema.String,
|
|
817
|
+
dir: Schema.Boolean
|
|
818
|
+
});
|
|
819
|
+
var FsListingSchema = Schema.Struct({
|
|
820
|
+
path: Schema.String,
|
|
821
|
+
parent: Schema.NullOr(Schema.String),
|
|
822
|
+
entries: Schema.Array(FsEntrySchema)
|
|
823
|
+
});
|
|
824
|
+
var UsageSummarySchema = Schema.Struct({
|
|
825
|
+
cost: Schema.Finite,
|
|
826
|
+
tokens: Schema.Finite,
|
|
827
|
+
cacheRead: Schema.Finite,
|
|
828
|
+
cacheSavings: Schema.Finite
|
|
829
|
+
});
|
|
830
|
+
var ModelDetailSchema = Schema.Struct({
|
|
831
|
+
name: Schema.String,
|
|
832
|
+
input: Schema.Finite,
|
|
833
|
+
output: Schema.Finite,
|
|
834
|
+
cacheCreate: Schema.Finite,
|
|
835
|
+
cacheRead: Schema.Finite,
|
|
836
|
+
cacheSavings: Schema.Finite,
|
|
837
|
+
cost: Schema.Finite,
|
|
838
|
+
count: Schema.Finite
|
|
839
|
+
});
|
|
840
|
+
var TableRowSchema = Schema.Struct({
|
|
841
|
+
label: Schema.String,
|
|
842
|
+
models: Schema.Array(Schema.String),
|
|
843
|
+
input: Schema.Finite,
|
|
844
|
+
output: Schema.Finite,
|
|
845
|
+
cacheCreate: Schema.Finite,
|
|
846
|
+
cacheRead: Schema.Finite,
|
|
847
|
+
cacheSavings: Schema.Finite,
|
|
848
|
+
total: Schema.Finite,
|
|
849
|
+
cost: Schema.Finite,
|
|
850
|
+
count: Schema.Finite,
|
|
851
|
+
breakdown: Schema.Array(ModelDetailSchema)
|
|
852
|
+
});
|
|
853
|
+
var DashboardDataSchema = Schema.Struct({
|
|
854
|
+
today: UsageSummarySchema,
|
|
855
|
+
week: UsageSummarySchema,
|
|
856
|
+
month: UsageSummarySchema,
|
|
857
|
+
burnRate: Schema.Finite,
|
|
858
|
+
series: Schema.Array(Schema.Finite)
|
|
859
|
+
});
|
|
860
|
+
var TableDataSchema = Schema.Struct({
|
|
861
|
+
daily: Schema.Array(TableRowSchema),
|
|
862
|
+
weekly: Schema.Array(TableRowSchema),
|
|
863
|
+
monthly: Schema.Array(TableRowSchema)
|
|
864
|
+
});
|
|
865
|
+
var MetricFormatSchema = Schema.Union([
|
|
866
|
+
Schema.Struct({ kind: Schema.Literal("percent") }),
|
|
867
|
+
Schema.Struct({ kind: Schema.Literal("dollars"), currency: Schema.optionalKey(Schema.String) }),
|
|
868
|
+
Schema.Struct({ kind: Schema.Literal("count"), suffix: Schema.optionalKey(Schema.String) })
|
|
869
|
+
]);
|
|
870
|
+
var MetricSchema = Schema.Struct({
|
|
871
|
+
label: Schema.String,
|
|
872
|
+
used: Schema.Finite,
|
|
873
|
+
limit: Schema.NullOr(Schema.Finite),
|
|
874
|
+
format: MetricFormatSchema,
|
|
875
|
+
resetsAt: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
876
|
+
primary: Schema.optionalKey(Schema.Boolean)
|
|
877
|
+
});
|
|
878
|
+
var BillingResultSchema = Schema.Struct({
|
|
879
|
+
plan: Schema.NullOr(Schema.String),
|
|
880
|
+
metrics: Schema.Array(MetricSchema),
|
|
881
|
+
error: Schema.NullOr(Schema.String),
|
|
882
|
+
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
883
|
+
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
884
|
+
activity: Schema.optionalKey(Schema.NullOr(Schema.Struct({
|
|
885
|
+
series: Schema.Array(Schema.Finite),
|
|
886
|
+
summary: Schema.String
|
|
887
|
+
}))),
|
|
888
|
+
modelSpend: Schema.optionalKey(Schema.NullOr(Schema.Array(Schema.Struct({
|
|
889
|
+
name: Schema.String,
|
|
890
|
+
usd: Schema.Finite,
|
|
891
|
+
requests: Schema.Finite
|
|
892
|
+
}))))
|
|
893
|
+
});
|
|
894
|
+
var WebAccountSchema = Schema.Struct({
|
|
895
|
+
id: Schema.String,
|
|
896
|
+
providerId: ProviderIdSchema,
|
|
897
|
+
name: Schema.String,
|
|
898
|
+
color: Schema.String,
|
|
899
|
+
homeDir: Schema.NullOr(Schema.String),
|
|
900
|
+
hasUsage: Schema.Boolean,
|
|
901
|
+
hasBilling: Schema.Boolean,
|
|
902
|
+
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
903
|
+
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
904
|
+
plan: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
905
|
+
dashboard: Schema.NullOr(DashboardDataSchema),
|
|
906
|
+
table: Schema.NullOr(TableDataSchema),
|
|
907
|
+
billing: Schema.NullOr(BillingResultSchema),
|
|
908
|
+
summaryState: Schema.Literals(["pending", "ready", "error"]),
|
|
909
|
+
billingState: Schema.Literals(["pending", "ready", "error"]),
|
|
910
|
+
tableState: Schema.Literals(["pending", "ready", "error"]),
|
|
911
|
+
summaryUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
912
|
+
billingUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
913
|
+
tableUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema))
|
|
914
|
+
});
|
|
915
|
+
var WebSnapshotSchema = Schema.Struct({
|
|
916
|
+
version: Schema.String,
|
|
917
|
+
generatedAt: NonNegativeIntegerSchema,
|
|
918
|
+
tz: Schema.String,
|
|
919
|
+
intervalMs: PositiveFiniteSchema,
|
|
920
|
+
billingIntervalMs: Schema.optionalKey(PositiveFiniteSchema),
|
|
921
|
+
providers: Schema.Array(Schema.Struct({
|
|
922
|
+
id: ProviderIdSchema,
|
|
923
|
+
name: Schema.String,
|
|
924
|
+
color: Schema.String
|
|
925
|
+
})),
|
|
926
|
+
accounts: Schema.Array(WebAccountSchema),
|
|
927
|
+
seeded: Schema.Boolean,
|
|
928
|
+
peak: Schema.NullOr(Schema.Struct({
|
|
929
|
+
state: Schema.Literals(["peak", "off-peak", "weekend"]),
|
|
930
|
+
label: Schema.String,
|
|
931
|
+
// The upstream clock is only normalized to a finite number; do not make
|
|
932
|
+
// the wire contract narrower than the producer's declared type.
|
|
933
|
+
minutesUntilChange: Schema.NullOr(Schema.Finite)
|
|
934
|
+
}))
|
|
935
|
+
});
|
|
936
|
+
var EmptyPayloadSchema = Schema.Struct({});
|
|
937
|
+
var GetConfigRpc = Rpc.make(TOKMON_WS_METHODS.getConfig, {
|
|
938
|
+
payload: EmptyPayloadSchema,
|
|
939
|
+
success: ConfigStateSchema
|
|
940
|
+
});
|
|
941
|
+
var SetConfigRpc = Rpc.make(TOKMON_WS_METHODS.setConfig, {
|
|
942
|
+
payload: ConfigUpdateRequestSchema,
|
|
943
|
+
success: ConfigStateSchema,
|
|
944
|
+
error: Schema.Union([ConfigUpdateConflictSchema, ConfigPersistenceFailureSchema])
|
|
945
|
+
});
|
|
946
|
+
var RefreshRpc = Rpc.make(TOKMON_WS_METHODS.refresh, {
|
|
947
|
+
payload: Schema.Struct({ scope: RefreshScopeSchema }),
|
|
948
|
+
success: Schema.Void
|
|
949
|
+
});
|
|
950
|
+
var BrowseFsRpc = Rpc.make(TOKMON_WS_METHODS.browseFs, {
|
|
951
|
+
payload: Schema.Struct({ path: Schema.String }),
|
|
952
|
+
success: FsListingSchema
|
|
953
|
+
});
|
|
954
|
+
var SnapshotRpc = Rpc.make(TOKMON_WS_METHODS.snapshot, {
|
|
955
|
+
payload: EmptyPayloadSchema,
|
|
956
|
+
success: WebSnapshotSchema,
|
|
957
|
+
stream: true
|
|
958
|
+
});
|
|
959
|
+
var ConfigRpc = Rpc.make(TOKMON_WS_METHODS.config, {
|
|
960
|
+
payload: EmptyPayloadSchema,
|
|
961
|
+
success: ConfigStateSchema,
|
|
962
|
+
stream: true
|
|
963
|
+
});
|
|
964
|
+
var TokmonRpcGroup = RpcGroup.make(
|
|
965
|
+
GetConfigRpc,
|
|
966
|
+
SetConfigRpc,
|
|
967
|
+
RefreshRpc,
|
|
968
|
+
BrowseFsRpc,
|
|
969
|
+
SnapshotRpc,
|
|
970
|
+
ConfigRpc
|
|
971
|
+
);
|
|
972
|
+
|
|
729
973
|
// src/shared/format.ts
|
|
730
974
|
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
731
975
|
function formatCurrency(value, opts = {}) {
|
|
@@ -2758,7 +3002,7 @@ function ghConfigDir(homeDir) {
|
|
|
2758
3002
|
function ghHostsPath(homeDir) {
|
|
2759
3003
|
return join13(ghConfigDir(homeDir), "hosts.yml");
|
|
2760
3004
|
}
|
|
2761
|
-
|
|
3005
|
+
function copilotStateDirs(homeDir) {
|
|
2762
3006
|
const home = homeDir ?? homedir9();
|
|
2763
3007
|
const candidates = [
|
|
2764
3008
|
join13(home, ".config", "github-copilot"),
|
|
@@ -2769,7 +3013,10 @@ async function detectCopilot(homeDir) {
|
|
|
2769
3013
|
if (process.platform === "win32") {
|
|
2770
3014
|
candidates.push(join13(envDir("LOCALAPPDATA") ?? join13(home, "AppData", "Local"), "github-copilot"));
|
|
2771
3015
|
}
|
|
2772
|
-
|
|
3016
|
+
return candidates;
|
|
3017
|
+
}
|
|
3018
|
+
async function detectCopilot(homeDir) {
|
|
3019
|
+
for (const path of copilotStateDirs(homeDir)) {
|
|
2773
3020
|
try {
|
|
2774
3021
|
await access7(path);
|
|
2775
3022
|
return true;
|
|
@@ -4294,550 +4541,42 @@ async function detectProviders() {
|
|
|
4294
4541
|
return found.filter((id) => id !== null);
|
|
4295
4542
|
}
|
|
4296
4543
|
|
|
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
|
-
knownProviders: Schema.Array(ProviderIdSchema)
|
|
4635
|
-
});
|
|
4636
|
-
var ProtocolInfoSchema = Schema.Struct({
|
|
4637
|
-
version: Schema.Literal(TOKMON_PROTOCOL_VERSION),
|
|
4638
|
-
// Capabilities are additive within a protocol version. Older clients must
|
|
4639
|
-
// preserve forward compatibility when a newer daemon advertises one they do
|
|
4640
|
-
// not understand yet.
|
|
4641
|
-
capabilities: Schema.Array(Schema.String)
|
|
4642
|
-
});
|
|
4643
|
-
var ConfigStateSchema = Schema.Struct({
|
|
4644
|
-
protocol: ProtocolInfoSchema,
|
|
4645
|
-
config: ConfigSchema
|
|
4646
|
-
});
|
|
4647
|
-
var ConfigUpdateRequestSchema = Schema.Struct({
|
|
4648
|
-
expectedRevision: NonNegativeIntegerSchema,
|
|
4649
|
-
config: ConfigSchema
|
|
4650
|
-
});
|
|
4651
|
-
var ConfigUpdateConflictSchema = Schema.Struct({
|
|
4652
|
-
kind: Schema.Literal("conflict"),
|
|
4653
|
-
state: ConfigStateSchema
|
|
4654
|
-
});
|
|
4655
|
-
var ConfigPersistenceFailureSchema = Schema.Struct({
|
|
4656
|
-
kind: Schema.Literal("persistence"),
|
|
4657
|
-
message: Schema.String
|
|
4658
|
-
});
|
|
4659
|
-
var FsEntrySchema = Schema.Struct({
|
|
4660
|
-
name: Schema.String,
|
|
4661
|
-
path: Schema.String,
|
|
4662
|
-
dir: Schema.Boolean
|
|
4663
|
-
});
|
|
4664
|
-
var FsListingSchema = Schema.Struct({
|
|
4665
|
-
path: Schema.String,
|
|
4666
|
-
parent: Schema.NullOr(Schema.String),
|
|
4667
|
-
entries: Schema.Array(FsEntrySchema)
|
|
4668
|
-
});
|
|
4669
|
-
var UsageSummarySchema = Schema.Struct({
|
|
4670
|
-
cost: Schema.Finite,
|
|
4671
|
-
tokens: Schema.Finite,
|
|
4672
|
-
cacheRead: Schema.Finite,
|
|
4673
|
-
cacheSavings: Schema.Finite
|
|
4674
|
-
});
|
|
4675
|
-
var ModelDetailSchema = Schema.Struct({
|
|
4676
|
-
name: Schema.String,
|
|
4677
|
-
input: Schema.Finite,
|
|
4678
|
-
output: Schema.Finite,
|
|
4679
|
-
cacheCreate: Schema.Finite,
|
|
4680
|
-
cacheRead: Schema.Finite,
|
|
4681
|
-
cacheSavings: Schema.Finite,
|
|
4682
|
-
cost: Schema.Finite,
|
|
4683
|
-
count: Schema.Finite
|
|
4684
|
-
});
|
|
4685
|
-
var TableRowSchema = Schema.Struct({
|
|
4686
|
-
label: Schema.String,
|
|
4687
|
-
models: Schema.Array(Schema.String),
|
|
4688
|
-
input: Schema.Finite,
|
|
4689
|
-
output: Schema.Finite,
|
|
4690
|
-
cacheCreate: Schema.Finite,
|
|
4691
|
-
cacheRead: Schema.Finite,
|
|
4692
|
-
cacheSavings: Schema.Finite,
|
|
4693
|
-
total: Schema.Finite,
|
|
4694
|
-
cost: Schema.Finite,
|
|
4695
|
-
count: Schema.Finite,
|
|
4696
|
-
breakdown: Schema.Array(ModelDetailSchema)
|
|
4697
|
-
});
|
|
4698
|
-
var DashboardDataSchema = Schema.Struct({
|
|
4699
|
-
today: UsageSummarySchema,
|
|
4700
|
-
week: UsageSummarySchema,
|
|
4701
|
-
month: UsageSummarySchema,
|
|
4702
|
-
burnRate: Schema.Finite,
|
|
4703
|
-
series: Schema.Array(Schema.Finite)
|
|
4704
|
-
});
|
|
4705
|
-
var TableDataSchema = Schema.Struct({
|
|
4706
|
-
daily: Schema.Array(TableRowSchema),
|
|
4707
|
-
weekly: Schema.Array(TableRowSchema),
|
|
4708
|
-
monthly: Schema.Array(TableRowSchema)
|
|
4709
|
-
});
|
|
4710
|
-
var MetricFormatSchema = Schema.Union([
|
|
4711
|
-
Schema.Struct({ kind: Schema.Literal("percent") }),
|
|
4712
|
-
Schema.Struct({ kind: Schema.Literal("dollars"), currency: Schema.optionalKey(Schema.String) }),
|
|
4713
|
-
Schema.Struct({ kind: Schema.Literal("count"), suffix: Schema.optionalKey(Schema.String) })
|
|
4714
|
-
]);
|
|
4715
|
-
var MetricSchema = Schema.Struct({
|
|
4716
|
-
label: Schema.String,
|
|
4717
|
-
used: Schema.Finite,
|
|
4718
|
-
limit: Schema.NullOr(Schema.Finite),
|
|
4719
|
-
format: MetricFormatSchema,
|
|
4720
|
-
resetsAt: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4721
|
-
primary: Schema.optionalKey(Schema.Boolean)
|
|
4722
|
-
});
|
|
4723
|
-
var BillingResultSchema = Schema.Struct({
|
|
4724
|
-
plan: Schema.NullOr(Schema.String),
|
|
4725
|
-
metrics: Schema.Array(MetricSchema),
|
|
4726
|
-
error: Schema.NullOr(Schema.String),
|
|
4727
|
-
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4728
|
-
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4729
|
-
activity: Schema.optionalKey(Schema.NullOr(Schema.Struct({
|
|
4730
|
-
series: Schema.Array(Schema.Finite),
|
|
4731
|
-
summary: Schema.String
|
|
4732
|
-
}))),
|
|
4733
|
-
modelSpend: Schema.optionalKey(Schema.NullOr(Schema.Array(Schema.Struct({
|
|
4734
|
-
name: Schema.String,
|
|
4735
|
-
usd: Schema.Finite,
|
|
4736
|
-
requests: Schema.Finite
|
|
4737
|
-
}))))
|
|
4738
|
-
});
|
|
4739
|
-
var WebAccountSchema = Schema.Struct({
|
|
4740
|
-
id: Schema.String,
|
|
4741
|
-
providerId: ProviderIdSchema,
|
|
4742
|
-
name: Schema.String,
|
|
4743
|
-
color: Schema.String,
|
|
4744
|
-
homeDir: Schema.NullOr(Schema.String),
|
|
4745
|
-
hasUsage: Schema.Boolean,
|
|
4746
|
-
hasBilling: Schema.Boolean,
|
|
4747
|
-
email: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4748
|
-
displayName: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4749
|
-
plan: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
4750
|
-
dashboard: Schema.NullOr(DashboardDataSchema),
|
|
4751
|
-
table: Schema.NullOr(TableDataSchema),
|
|
4752
|
-
billing: Schema.NullOr(BillingResultSchema),
|
|
4753
|
-
summaryState: Schema.Literals(["pending", "ready", "error"]),
|
|
4754
|
-
billingState: Schema.Literals(["pending", "ready", "error"]),
|
|
4755
|
-
tableState: Schema.Literals(["pending", "ready", "error"]),
|
|
4756
|
-
summaryUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
4757
|
-
billingUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema)),
|
|
4758
|
-
tableUpdatedAt: Schema.optionalKey(Schema.NullOr(NonNegativeIntegerSchema))
|
|
4759
|
-
});
|
|
4760
|
-
var WebSnapshotSchema = Schema.Struct({
|
|
4761
|
-
version: Schema.String,
|
|
4762
|
-
generatedAt: NonNegativeIntegerSchema,
|
|
4763
|
-
tz: Schema.String,
|
|
4764
|
-
intervalMs: PositiveFiniteSchema,
|
|
4765
|
-
billingIntervalMs: Schema.optionalKey(PositiveFiniteSchema),
|
|
4766
|
-
providers: Schema.Array(Schema.Struct({
|
|
4767
|
-
id: ProviderIdSchema,
|
|
4768
|
-
name: Schema.String,
|
|
4769
|
-
color: Schema.String
|
|
4770
|
-
})),
|
|
4771
|
-
accounts: Schema.Array(WebAccountSchema),
|
|
4772
|
-
seeded: Schema.Boolean,
|
|
4773
|
-
peak: Schema.NullOr(Schema.Struct({
|
|
4774
|
-
state: Schema.Literals(["peak", "off-peak", "weekend"]),
|
|
4775
|
-
label: Schema.String,
|
|
4776
|
-
// The upstream clock is only normalized to a finite number; do not make
|
|
4777
|
-
// the wire contract narrower than the producer's declared type.
|
|
4778
|
-
minutesUntilChange: Schema.NullOr(Schema.Finite)
|
|
4779
|
-
}))
|
|
4780
|
-
});
|
|
4781
|
-
var EmptyPayloadSchema = Schema.Struct({});
|
|
4782
|
-
var GetConfigRpc = Rpc.make(TOKMON_WS_METHODS.getConfig, {
|
|
4783
|
-
payload: EmptyPayloadSchema,
|
|
4784
|
-
success: ConfigStateSchema
|
|
4785
|
-
});
|
|
4786
|
-
var SetConfigRpc = Rpc.make(TOKMON_WS_METHODS.setConfig, {
|
|
4787
|
-
payload: ConfigUpdateRequestSchema,
|
|
4788
|
-
success: ConfigStateSchema,
|
|
4789
|
-
error: Schema.Union([ConfigUpdateConflictSchema, ConfigPersistenceFailureSchema])
|
|
4790
|
-
});
|
|
4791
|
-
var RefreshRpc = Rpc.make(TOKMON_WS_METHODS.refresh, {
|
|
4792
|
-
payload: Schema.Struct({ scope: RefreshScopeSchema }),
|
|
4793
|
-
success: Schema.Void
|
|
4794
|
-
});
|
|
4795
|
-
var BrowseFsRpc = Rpc.make(TOKMON_WS_METHODS.browseFs, {
|
|
4796
|
-
payload: Schema.Struct({ path: Schema.String }),
|
|
4797
|
-
success: FsListingSchema
|
|
4798
|
-
});
|
|
4799
|
-
var SnapshotRpc = Rpc.make(TOKMON_WS_METHODS.snapshot, {
|
|
4800
|
-
payload: EmptyPayloadSchema,
|
|
4801
|
-
success: WebSnapshotSchema,
|
|
4802
|
-
stream: true
|
|
4803
|
-
});
|
|
4804
|
-
var ConfigRpc = Rpc.make(TOKMON_WS_METHODS.config, {
|
|
4805
|
-
payload: EmptyPayloadSchema,
|
|
4806
|
-
success: ConfigStateSchema,
|
|
4807
|
-
stream: true
|
|
4808
|
-
});
|
|
4809
|
-
var TokmonRpcGroup = RpcGroup.make(
|
|
4810
|
-
GetConfigRpc,
|
|
4811
|
-
SetConfigRpc,
|
|
4812
|
-
RefreshRpc,
|
|
4813
|
-
BrowseFsRpc,
|
|
4814
|
-
SnapshotRpc,
|
|
4815
|
-
ConfigRpc
|
|
4816
|
-
);
|
|
4817
|
-
|
|
4818
4544
|
export {
|
|
4545
|
+
TOKMON_WS_PATH,
|
|
4546
|
+
TOKMON_PROTOCOL_VERSION,
|
|
4547
|
+
TOKMON_CAPABILITIES,
|
|
4548
|
+
TOKMON_WS_METHODS,
|
|
4549
|
+
TokmonRpcGroup,
|
|
4550
|
+
withTimeout,
|
|
4819
4551
|
systemTimezone,
|
|
4820
4552
|
resolveTimezone,
|
|
4553
|
+
dayKey,
|
|
4554
|
+
startOfMonth,
|
|
4555
|
+
startOfWeek,
|
|
4821
4556
|
flushDisk,
|
|
4822
4557
|
coalesceTables,
|
|
4558
|
+
claudeConfigDirs,
|
|
4823
4559
|
currency,
|
|
4824
4560
|
tokens,
|
|
4825
4561
|
time,
|
|
4826
4562
|
shortDate,
|
|
4827
4563
|
col,
|
|
4564
|
+
readJson,
|
|
4565
|
+
readClaudeIdentity,
|
|
4566
|
+
codexHomes,
|
|
4567
|
+
identityFromIdToken,
|
|
4568
|
+
cursorStateDb,
|
|
4569
|
+
piSessionsDir,
|
|
4570
|
+
opencodeDbPaths,
|
|
4571
|
+
ghHostsPath,
|
|
4572
|
+
copilotStateDirs,
|
|
4573
|
+
antigravityStateDb,
|
|
4574
|
+
geminiTmpDir,
|
|
4575
|
+
geminiCredsPath,
|
|
4576
|
+
geminiDir,
|
|
4577
|
+
grokHomes,
|
|
4578
|
+
grokAuthPaths,
|
|
4828
4579
|
PROVIDER_ORDER,
|
|
4829
4580
|
PROVIDERS,
|
|
4830
|
-
detectProviders
|
|
4831
|
-
buildAccounts,
|
|
4832
|
-
accountsByProvider,
|
|
4833
|
-
namedHex,
|
|
4834
|
-
colorHex,
|
|
4835
|
-
modelColor,
|
|
4836
|
-
withTimeout,
|
|
4837
|
-
fetchPeak,
|
|
4838
|
-
TOKMON_WS_PATH,
|
|
4839
|
-
TOKMON_PROTOCOL_VERSION,
|
|
4840
|
-
TOKMON_CAPABILITIES,
|
|
4841
|
-
TOKMON_WS_METHODS,
|
|
4842
|
-
TokmonRpcGroup
|
|
4581
|
+
detectProviders
|
|
4843
4582
|
};
|