@praeviso/code-env-switch 0.1.4 → 0.1.6
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 +57 -0
- package/README_zh.md +57 -0
- package/bin/cli/args.js +13 -0
- package/bin/cli/help.js +5 -0
- package/bin/cli/index.js +2 -1
- package/bin/commands/index.js +3 -1
- package/bin/commands/list.js +44 -2
- package/bin/commands/usage.js +41 -0
- package/bin/index.js +7 -0
- package/bin/statusline/debug.js +1 -0
- package/bin/statusline/format.js +6 -9
- package/bin/statusline/index.js +46 -8
- package/bin/statusline/input.js +9 -91
- package/bin/statusline/usage/claude.js +181 -0
- package/bin/statusline/usage/codex.js +177 -0
- package/bin/statusline/usage.js +20 -76
- package/bin/usage/index.js +647 -50
- package/bin/usage/pricing.js +303 -0
- package/code-env.example.json +55 -0
- package/package.json +1 -1
- package/src/cli/args.ts +14 -0
- package/src/cli/help.ts +5 -0
- package/src/cli/index.ts +7 -1
- package/src/commands/index.ts +1 -0
- package/src/commands/list.ts +74 -4
- package/src/commands/usage.ts +53 -0
- package/src/index.ts +11 -0
- package/src/statusline/debug.ts +1 -1
- package/src/statusline/format.ts +9 -10
- package/src/statusline/index.ts +74 -24
- package/src/statusline/input.ts +13 -154
- package/src/statusline/types.ts +6 -0
- package/src/statusline/usage/claude.ts +299 -0
- package/src/statusline/usage/codex.ts +258 -0
- package/src/statusline/usage.ts +24 -119
- package/src/types.ts +27 -0
- package/src/usage/index.ts +779 -44
- package/src/usage/pricing.ts +323 -0
- package/PLAN.md +0 -33
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
StatuslineInput,
|
|
3
|
+
StatuslineInputUsage,
|
|
4
|
+
StatuslineUsageTotals,
|
|
5
|
+
} from "../types";
|
|
6
|
+
import { coerceNumber, firstNumber, isRecord } from "../utils";
|
|
7
|
+
|
|
8
|
+
function resolveOutputTokens(record: Record<string, unknown>): number | null {
|
|
9
|
+
const outputTokens =
|
|
10
|
+
firstNumber(
|
|
11
|
+
record.outputTokens,
|
|
12
|
+
record.output,
|
|
13
|
+
record.output_tokens
|
|
14
|
+
) ?? null;
|
|
15
|
+
const reasoningTokens =
|
|
16
|
+
firstNumber(
|
|
17
|
+
record.reasoning_output_tokens,
|
|
18
|
+
record.reasoningOutputTokens,
|
|
19
|
+
record.reasoning_output
|
|
20
|
+
) ?? null;
|
|
21
|
+
if (outputTokens !== null) return outputTokens;
|
|
22
|
+
if (reasoningTokens !== null) return reasoningTokens;
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function splitInputTokens(
|
|
27
|
+
record: Record<string, unknown>
|
|
28
|
+
): { inputTokens: number | null; cacheReadTokens: number | null } {
|
|
29
|
+
const rawInput =
|
|
30
|
+
firstNumber(
|
|
31
|
+
record.inputTokens,
|
|
32
|
+
record.input,
|
|
33
|
+
record.input_tokens
|
|
34
|
+
) ?? null;
|
|
35
|
+
const cacheRead =
|
|
36
|
+
firstNumber(
|
|
37
|
+
record.cached_input_tokens,
|
|
38
|
+
record.cachedInputTokens,
|
|
39
|
+
record.cache_read_input_tokens,
|
|
40
|
+
record.cacheReadInputTokens,
|
|
41
|
+
record.cache_read,
|
|
42
|
+
record.cacheRead
|
|
43
|
+
) ?? null;
|
|
44
|
+
if (rawInput === null) {
|
|
45
|
+
return { inputTokens: null, cacheReadTokens: cacheRead };
|
|
46
|
+
}
|
|
47
|
+
if (cacheRead === null) {
|
|
48
|
+
return { inputTokens: rawInput, cacheReadTokens: null };
|
|
49
|
+
}
|
|
50
|
+
const nonCachedInput = Math.max(0, rawInput - cacheRead);
|
|
51
|
+
return { inputTokens: nonCachedInput, cacheReadTokens: cacheRead };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function parseCodexUsageTotalsRecord(
|
|
55
|
+
record: Record<string, unknown>
|
|
56
|
+
): StatuslineUsageTotals | null {
|
|
57
|
+
const split = splitInputTokens(record);
|
|
58
|
+
const inputTokens = split.inputTokens;
|
|
59
|
+
const outputTokens = resolveOutputTokens(record);
|
|
60
|
+
const cacheRead = split.cacheReadTokens;
|
|
61
|
+
const cacheWrite =
|
|
62
|
+
firstNumber(
|
|
63
|
+
record.cache_creation_input_tokens,
|
|
64
|
+
record.cacheCreationInputTokens,
|
|
65
|
+
record.cache_write_input_tokens,
|
|
66
|
+
record.cacheWriteInputTokens,
|
|
67
|
+
record.cache_write,
|
|
68
|
+
record.cacheWrite
|
|
69
|
+
) ?? null;
|
|
70
|
+
const totalTokens =
|
|
71
|
+
firstNumber(
|
|
72
|
+
record.totalTokens,
|
|
73
|
+
record.total,
|
|
74
|
+
record.total_tokens
|
|
75
|
+
) ?? null;
|
|
76
|
+
let computedTotal: number | null = null;
|
|
77
|
+
if (
|
|
78
|
+
inputTokens !== null ||
|
|
79
|
+
outputTokens !== null ||
|
|
80
|
+
cacheRead !== null ||
|
|
81
|
+
cacheWrite !== null
|
|
82
|
+
) {
|
|
83
|
+
computedTotal =
|
|
84
|
+
(inputTokens || 0) +
|
|
85
|
+
(outputTokens || 0) +
|
|
86
|
+
(cacheRead || 0) +
|
|
87
|
+
(cacheWrite || 0);
|
|
88
|
+
}
|
|
89
|
+
const resolvedTotal = totalTokens ?? computedTotal;
|
|
90
|
+
if (
|
|
91
|
+
inputTokens === null &&
|
|
92
|
+
outputTokens === null &&
|
|
93
|
+
cacheRead === null &&
|
|
94
|
+
cacheWrite === null &&
|
|
95
|
+
resolvedTotal === null
|
|
96
|
+
) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
inputTokens,
|
|
101
|
+
outputTokens,
|
|
102
|
+
cacheReadTokens: cacheRead,
|
|
103
|
+
cacheWriteTokens: cacheWrite,
|
|
104
|
+
totalTokens: resolvedTotal,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function parseCodexInputUsageRecord(
|
|
109
|
+
record: Record<string, unknown>
|
|
110
|
+
): StatuslineInputUsage | null {
|
|
111
|
+
const todayTokens =
|
|
112
|
+
firstNumber(
|
|
113
|
+
record.todayTokens,
|
|
114
|
+
record.today,
|
|
115
|
+
record.today_tokens,
|
|
116
|
+
record.daily,
|
|
117
|
+
record.daily_tokens
|
|
118
|
+
) ?? null;
|
|
119
|
+
const totalTokens =
|
|
120
|
+
firstNumber(
|
|
121
|
+
record.totalTokens,
|
|
122
|
+
record.total,
|
|
123
|
+
record.total_tokens
|
|
124
|
+
) ?? null;
|
|
125
|
+
const split = splitInputTokens(record);
|
|
126
|
+
const inputTokens = split.inputTokens;
|
|
127
|
+
const outputTokens = resolveOutputTokens(record);
|
|
128
|
+
const cacheRead = split.cacheReadTokens;
|
|
129
|
+
const cacheWrite =
|
|
130
|
+
firstNumber(
|
|
131
|
+
record.cache_creation_input_tokens,
|
|
132
|
+
record.cacheCreationInputTokens,
|
|
133
|
+
record.cache_write_input_tokens,
|
|
134
|
+
record.cacheWriteInputTokens,
|
|
135
|
+
record.cache_write,
|
|
136
|
+
record.cacheWrite
|
|
137
|
+
) ?? null;
|
|
138
|
+
if (
|
|
139
|
+
todayTokens === null &&
|
|
140
|
+
totalTokens === null &&
|
|
141
|
+
inputTokens === null &&
|
|
142
|
+
outputTokens === null &&
|
|
143
|
+
cacheRead === null &&
|
|
144
|
+
cacheWrite === null
|
|
145
|
+
) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
const hasCacheTokens = cacheRead !== null || cacheWrite !== null;
|
|
149
|
+
const computedTotal = hasCacheTokens
|
|
150
|
+
? (inputTokens || 0) +
|
|
151
|
+
(outputTokens || 0) +
|
|
152
|
+
(cacheRead || 0) +
|
|
153
|
+
(cacheWrite || 0)
|
|
154
|
+
: null;
|
|
155
|
+
const resolvedTodayTokens = hasCacheTokens
|
|
156
|
+
? todayTokens ?? totalTokens ?? computedTotal
|
|
157
|
+
: todayTokens;
|
|
158
|
+
return {
|
|
159
|
+
todayTokens: resolvedTodayTokens,
|
|
160
|
+
totalTokens: totalTokens ?? null,
|
|
161
|
+
inputTokens,
|
|
162
|
+
outputTokens,
|
|
163
|
+
cacheReadTokens: cacheRead,
|
|
164
|
+
cacheWriteTokens: cacheWrite,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function resolveNestedRecord(
|
|
169
|
+
record: Record<string, unknown>,
|
|
170
|
+
...keys: string[]
|
|
171
|
+
): Record<string, unknown> | null {
|
|
172
|
+
for (const key of keys) {
|
|
173
|
+
if (isRecord(record[key])) {
|
|
174
|
+
return record[key] as Record<string, unknown>;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function getCodexUsageTotalsFromInput(
|
|
181
|
+
input: StatuslineInput | null
|
|
182
|
+
): StatuslineUsageTotals | null {
|
|
183
|
+
if (!input) return null;
|
|
184
|
+
const tokenUsage = input.token_usage;
|
|
185
|
+
if (typeof tokenUsage === "number") {
|
|
186
|
+
return {
|
|
187
|
+
inputTokens: null,
|
|
188
|
+
outputTokens: null,
|
|
189
|
+
cacheReadTokens: null,
|
|
190
|
+
cacheWriteTokens: null,
|
|
191
|
+
totalTokens: coerceNumber(tokenUsage),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (isRecord(tokenUsage)) {
|
|
195
|
+
const totalUsage = resolveNestedRecord(
|
|
196
|
+
tokenUsage,
|
|
197
|
+
"total_token_usage",
|
|
198
|
+
"totalTokenUsage"
|
|
199
|
+
);
|
|
200
|
+
if (totalUsage) {
|
|
201
|
+
const parsed = parseCodexUsageTotalsRecord(totalUsage);
|
|
202
|
+
if (parsed) return parsed;
|
|
203
|
+
}
|
|
204
|
+
const parsed = parseCodexUsageTotalsRecord(tokenUsage as Record<string, unknown>);
|
|
205
|
+
if (parsed) return parsed;
|
|
206
|
+
}
|
|
207
|
+
if (isRecord(input.usage)) {
|
|
208
|
+
return parseCodexUsageTotalsRecord(input.usage as Record<string, unknown>);
|
|
209
|
+
}
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function getCodexInputUsage(
|
|
214
|
+
input: StatuslineInput | null
|
|
215
|
+
): StatuslineInputUsage | null {
|
|
216
|
+
if (!input) return null;
|
|
217
|
+
if (isRecord(input.usage)) {
|
|
218
|
+
const parsed = parseCodexInputUsageRecord(input.usage as Record<string, unknown>);
|
|
219
|
+
if (parsed) return parsed;
|
|
220
|
+
return input.usage as StatuslineInputUsage;
|
|
221
|
+
}
|
|
222
|
+
const tokenUsage = input.token_usage;
|
|
223
|
+
if (tokenUsage !== null && tokenUsage !== undefined) {
|
|
224
|
+
if (typeof tokenUsage === "number") {
|
|
225
|
+
return {
|
|
226
|
+
todayTokens: null,
|
|
227
|
+
totalTokens: coerceNumber(tokenUsage),
|
|
228
|
+
inputTokens: null,
|
|
229
|
+
outputTokens: null,
|
|
230
|
+
cacheReadTokens: null,
|
|
231
|
+
cacheWriteTokens: null,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
if (isRecord(tokenUsage)) {
|
|
235
|
+
const totalUsage = resolveNestedRecord(
|
|
236
|
+
tokenUsage,
|
|
237
|
+
"total_token_usage",
|
|
238
|
+
"totalTokenUsage"
|
|
239
|
+
);
|
|
240
|
+
if (totalUsage) {
|
|
241
|
+
const parsed = parseCodexInputUsageRecord(totalUsage);
|
|
242
|
+
if (parsed) return parsed;
|
|
243
|
+
}
|
|
244
|
+
const lastUsage = resolveNestedRecord(
|
|
245
|
+
tokenUsage,
|
|
246
|
+
"last_token_usage",
|
|
247
|
+
"lastTokenUsage"
|
|
248
|
+
);
|
|
249
|
+
if (lastUsage) {
|
|
250
|
+
const parsed = parseCodexInputUsageRecord(lastUsage);
|
|
251
|
+
if (parsed) return parsed;
|
|
252
|
+
}
|
|
253
|
+
const parsed = parseCodexInputUsageRecord(tokenUsage as Record<string, unknown>);
|
|
254
|
+
if (parsed) return parsed;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
package/src/statusline/usage.ts
CHANGED
|
@@ -2,127 +2,26 @@ import type { Config } from "../types";
|
|
|
2
2
|
import { normalizeType } from "../profile/type";
|
|
3
3
|
import { readUsageTotalsIndex, resolveUsageTotalsForProfile } from "../usage";
|
|
4
4
|
import type { StatuslineInput, StatuslineInputUsage, StatuslineUsage, StatuslineUsageTotals } from "./types";
|
|
5
|
-
import { coerceNumber
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
record: Record<string, unknown>
|
|
9
|
-
): StatuslineUsageTotals | null {
|
|
10
|
-
const inputTokens =
|
|
11
|
-
firstNumber(
|
|
12
|
-
record.inputTokens,
|
|
13
|
-
record.input,
|
|
14
|
-
record.input_tokens
|
|
15
|
-
) ?? null;
|
|
16
|
-
const outputTokens =
|
|
17
|
-
firstNumber(
|
|
18
|
-
record.outputTokens,
|
|
19
|
-
record.output,
|
|
20
|
-
record.output_tokens
|
|
21
|
-
) ?? null;
|
|
22
|
-
const totalTokens =
|
|
23
|
-
firstNumber(
|
|
24
|
-
record.totalTokens,
|
|
25
|
-
record.total,
|
|
26
|
-
record.total_tokens
|
|
27
|
-
) ?? null;
|
|
28
|
-
const cacheRead =
|
|
29
|
-
firstNumber(
|
|
30
|
-
record.cache_read_input_tokens,
|
|
31
|
-
record.cacheReadInputTokens,
|
|
32
|
-
record.cache_read,
|
|
33
|
-
record.cacheRead
|
|
34
|
-
) ?? null;
|
|
35
|
-
const cacheWrite =
|
|
36
|
-
firstNumber(
|
|
37
|
-
record.cache_creation_input_tokens,
|
|
38
|
-
record.cacheCreationInputTokens,
|
|
39
|
-
record.cache_write_input_tokens,
|
|
40
|
-
record.cacheWriteInputTokens,
|
|
41
|
-
record.cache_write,
|
|
42
|
-
record.cacheWrite
|
|
43
|
-
) ?? null;
|
|
44
|
-
let computedTotal: number | null = null;
|
|
45
|
-
if (
|
|
46
|
-
inputTokens !== null ||
|
|
47
|
-
outputTokens !== null ||
|
|
48
|
-
cacheRead !== null ||
|
|
49
|
-
cacheWrite !== null
|
|
50
|
-
) {
|
|
51
|
-
computedTotal =
|
|
52
|
-
(inputTokens || 0) +
|
|
53
|
-
(outputTokens || 0) +
|
|
54
|
-
(cacheRead || 0) +
|
|
55
|
-
(cacheWrite || 0);
|
|
56
|
-
}
|
|
57
|
-
const resolvedTotal = totalTokens ?? computedTotal;
|
|
58
|
-
if (
|
|
59
|
-
inputTokens === null &&
|
|
60
|
-
outputTokens === null &&
|
|
61
|
-
resolvedTotal === null
|
|
62
|
-
) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
return {
|
|
66
|
-
inputTokens,
|
|
67
|
-
outputTokens,
|
|
68
|
-
totalTokens: resolvedTotal,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
5
|
+
import { coerceNumber } from "./utils";
|
|
6
|
+
import { getClaudeUsageTotalsFromInput } from "./usage/claude";
|
|
7
|
+
import { getCodexUsageTotalsFromInput } from "./usage/codex";
|
|
71
8
|
|
|
72
9
|
export function getUsageTotalsFromInput(
|
|
73
|
-
input: StatuslineInput | null
|
|
10
|
+
input: StatuslineInput | null,
|
|
11
|
+
type: string | null
|
|
74
12
|
): StatuslineUsageTotals | null {
|
|
75
13
|
if (!input) return null;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
? (input.contextWindow as Record<string, unknown>)
|
|
80
|
-
: null;
|
|
81
|
-
if (contextWindow) {
|
|
82
|
-
const totalInputTokens =
|
|
83
|
-
firstNumber(
|
|
84
|
-
contextWindow.total_input_tokens,
|
|
85
|
-
contextWindow.totalInputTokens
|
|
86
|
-
) ?? null;
|
|
87
|
-
const totalOutputTokens =
|
|
88
|
-
firstNumber(
|
|
89
|
-
contextWindow.total_output_tokens,
|
|
90
|
-
contextWindow.totalOutputTokens
|
|
91
|
-
) ?? null;
|
|
92
|
-
if (totalInputTokens !== null || totalOutputTokens !== null) {
|
|
93
|
-
return {
|
|
94
|
-
inputTokens: totalInputTokens,
|
|
95
|
-
outputTokens: totalOutputTokens,
|
|
96
|
-
totalTokens: (totalInputTokens || 0) + (totalOutputTokens || 0),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
if (typeof input.token_usage === "number") {
|
|
101
|
-
return {
|
|
102
|
-
inputTokens: null,
|
|
103
|
-
outputTokens: null,
|
|
104
|
-
totalTokens: coerceNumber(input.token_usage),
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
if (isRecord(input.token_usage)) {
|
|
108
|
-
const tokenUsage = input.token_usage as Record<string, unknown>;
|
|
109
|
-
const totalUsage =
|
|
110
|
-
(isRecord(tokenUsage.total_token_usage)
|
|
111
|
-
? (tokenUsage.total_token_usage as Record<string, unknown>)
|
|
112
|
-
: null) ||
|
|
113
|
-
(isRecord(tokenUsage.totalTokenUsage)
|
|
114
|
-
? (tokenUsage.totalTokenUsage as Record<string, unknown>)
|
|
115
|
-
: null);
|
|
116
|
-
if (totalUsage) {
|
|
117
|
-
const parsed = parseUsageTotalsRecord(totalUsage);
|
|
118
|
-
if (parsed) return parsed;
|
|
119
|
-
}
|
|
120
|
-
return parseUsageTotalsRecord(tokenUsage);
|
|
14
|
+
const normalized = normalizeType(type || "");
|
|
15
|
+
if (normalized === "codex") {
|
|
16
|
+
return getCodexUsageTotalsFromInput(input);
|
|
121
17
|
}
|
|
122
|
-
if (
|
|
123
|
-
return
|
|
18
|
+
if (normalized === "claude") {
|
|
19
|
+
return getClaudeUsageTotalsFromInput(input);
|
|
124
20
|
}
|
|
125
|
-
return
|
|
21
|
+
return (
|
|
22
|
+
getCodexUsageTotalsFromInput(input) ||
|
|
23
|
+
getClaudeUsageTotalsFromInput(input)
|
|
24
|
+
);
|
|
126
25
|
}
|
|
127
26
|
|
|
128
27
|
export function normalizeInputUsage(
|
|
@@ -131,15 +30,19 @@ export function normalizeInputUsage(
|
|
|
131
30
|
if (!inputUsage) return null;
|
|
132
31
|
const usage: StatuslineUsage = {
|
|
133
32
|
todayTokens: coerceNumber(inputUsage.todayTokens),
|
|
134
|
-
totalTokens: coerceNumber(inputUsage.totalTokens),
|
|
33
|
+
totalTokens: coerceNumber(inputUsage.totalTokens),
|
|
135
34
|
inputTokens: coerceNumber(inputUsage.inputTokens),
|
|
136
35
|
outputTokens: coerceNumber(inputUsage.outputTokens),
|
|
36
|
+
cacheReadTokens: coerceNumber(inputUsage.cacheReadTokens),
|
|
37
|
+
cacheWriteTokens: coerceNumber(inputUsage.cacheWriteTokens),
|
|
137
38
|
};
|
|
138
39
|
const hasUsage =
|
|
139
40
|
usage.todayTokens !== null ||
|
|
140
41
|
usage.totalTokens !== null ||
|
|
141
42
|
usage.inputTokens !== null ||
|
|
142
|
-
usage.outputTokens !== null
|
|
43
|
+
usage.outputTokens !== null ||
|
|
44
|
+
usage.cacheReadTokens !== null ||
|
|
45
|
+
usage.cacheWriteTokens !== null;
|
|
143
46
|
return hasUsage ? usage : null;
|
|
144
47
|
}
|
|
145
48
|
|
|
@@ -166,8 +69,10 @@ export function resolveUsageFromRecords(
|
|
|
166
69
|
return {
|
|
167
70
|
todayTokens: usage.today,
|
|
168
71
|
totalTokens: usage.total,
|
|
169
|
-
inputTokens: null,
|
|
170
|
-
outputTokens: null,
|
|
72
|
+
inputTokens: usage.todayInput ?? null,
|
|
73
|
+
outputTokens: usage.todayOutput ?? null,
|
|
74
|
+
cacheReadTokens: usage.todayCacheRead ?? null,
|
|
75
|
+
cacheWriteTokens: usage.todayCacheWrite ?? null,
|
|
171
76
|
};
|
|
172
77
|
} catch {
|
|
173
78
|
return null;
|
package/src/types.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface Profile {
|
|
|
15
15
|
env?: Record<string, EnvValue>;
|
|
16
16
|
removeFiles?: string[];
|
|
17
17
|
commands?: string[];
|
|
18
|
+
pricing?: ProfilePricing;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export interface CodexStatuslineConfig {
|
|
@@ -43,6 +44,24 @@ export interface Config {
|
|
|
43
44
|
claudeSessionsPath?: string;
|
|
44
45
|
codexStatusline?: CodexStatuslineConfig;
|
|
45
46
|
claudeStatusline?: ClaudeStatuslineConfig;
|
|
47
|
+
pricing?: PricingConfig;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface TokenPricing {
|
|
51
|
+
input?: number;
|
|
52
|
+
output?: number;
|
|
53
|
+
cacheRead?: number;
|
|
54
|
+
cacheWrite?: number;
|
|
55
|
+
description?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface PricingConfig {
|
|
59
|
+
models?: Record<string, TokenPricing>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface ProfilePricing extends TokenPricing {
|
|
63
|
+
model?: string;
|
|
64
|
+
multiplier?: number;
|
|
46
65
|
}
|
|
47
66
|
|
|
48
67
|
export interface ListRow {
|
|
@@ -54,6 +73,10 @@ export interface ListRow {
|
|
|
54
73
|
usageType?: ProfileType | null;
|
|
55
74
|
todayTokens?: number;
|
|
56
75
|
totalTokens?: number;
|
|
76
|
+
todayCost?: number;
|
|
77
|
+
totalCost?: number;
|
|
78
|
+
todayBilledTokens?: number;
|
|
79
|
+
totalBilledTokens?: number;
|
|
57
80
|
}
|
|
58
81
|
|
|
59
82
|
export interface ParsedArgs {
|
|
@@ -78,6 +101,10 @@ export interface AddArgs {
|
|
|
78
101
|
type: ProfileType | null;
|
|
79
102
|
}
|
|
80
103
|
|
|
104
|
+
export interface UsageResetArgs {
|
|
105
|
+
yes: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
81
108
|
export type StatuslineFormat = "text" | "json";
|
|
82
109
|
|
|
83
110
|
export interface StatuslineArgs {
|