@subvalue/cli 0.1.3 → 0.1.4
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/PRE_RELEASE.md +6 -6
- package/README.md +5 -3
- package/dist/PRICING.md +15 -16
- package/dist/packages/cli/src/index.js +109 -20
- package/dist/packages/cli/src/protocol.js +13 -0
- package/dist/packages/cli/src/runtime.js +44 -14
- package/dist/packages/cli/src/server.js +306 -62
- package/dist/packages/core/src/calendar.js +41 -18
- package/dist/packages/core/src/coverage.js +12 -0
- package/dist/packages/core/src/demo.js +61 -9
- package/dist/packages/core/src/metadata.js +52 -9
- package/dist/packages/core/src/pricing/current.js +346 -297
- package/dist/packages/core/src/pricing/index.js +373 -73
- package/dist/packages/core/src/providers/claude/index.js +93 -21
- package/dist/packages/core/src/providers/codex/index.js +213 -46
- package/dist/packages/core/src/scanner.js +226 -46
- package/dist/packages/core/src/security.js +127 -34
- package/dist/packages/core/src/storage.js +215 -47
- package/dist/packages/core/src/subscriptions.js +146 -21
- package/dist/packages/core/src/summary.js +408 -59
- package/dist/packages/core/src/types.js +71 -17
- package/dist/packages/core/src/usage-json.js +166 -47
- package/dist/packages/receipt/src/index.js +386 -82
- package/dist/packages/ui/src/brand.js +42 -27
- package/dist/public/app.css +2280 -61
- package/dist/public/apps/web/src/landing.js +200 -8
- package/dist/public/apps/web/src/main.js +1143 -98
- package/dist/public/index.html +24 -1
- package/dist/public/landing.css +3235 -80
- package/dist/public/landing.html +21 -1
- package/dist/public/packages/core/src/calendar.js +41 -18
- package/dist/public/packages/core/src/coverage.js +12 -0
- package/dist/public/packages/core/src/subscriptions.js +146 -21
- package/dist/public/packages/receipt/src/index.js +386 -82
- package/dist/public/packages/ui/src/brand.js +42 -27
- package/dist/public/privacy.css +197 -9
- package/package.json +1 -1
|
@@ -1,73 +1,192 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
|
|
3
3
|
// These are the fields consumed by the provider adapters. Conversation text,
|
|
4
4
|
// instructions, working directories and tool content have no selected path.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const counters
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const counters = {
|
|
8
|
+
input_tokens: 'number',
|
|
9
|
+
cached_input_tokens: 'number',
|
|
10
|
+
cache_write_input_tokens: 'number',
|
|
11
|
+
output_tokens: 'number',
|
|
12
|
+
reasoning_output_tokens: 'number',
|
|
13
|
+
total_tokens: 'number',
|
|
14
|
+
};
|
|
15
|
+
const fields = {
|
|
16
|
+
codex: {
|
|
17
|
+
type: 'text',
|
|
18
|
+
timestamp: 'text',
|
|
19
|
+
ordinal: 'number',
|
|
20
|
+
payload: {
|
|
21
|
+
type: 'text',
|
|
22
|
+
id: 'text',
|
|
23
|
+
model: 'text',
|
|
24
|
+
subagent_history_start_ordinal: 'number',
|
|
25
|
+
info: { total_token_usage: counters, last_token_usage: counters },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
claude: {
|
|
29
|
+
type: 'text',
|
|
30
|
+
timestamp: 'text',
|
|
31
|
+
sessionId: 'text',
|
|
32
|
+
requestId: 'text',
|
|
33
|
+
message: {
|
|
34
|
+
id: 'text',
|
|
35
|
+
model: 'text',
|
|
36
|
+
usage: {
|
|
37
|
+
input_tokens: 'number',
|
|
38
|
+
cache_read_input_tokens: 'number',
|
|
39
|
+
cache_creation_input_tokens: 'number',
|
|
40
|
+
output_tokens: 'number',
|
|
41
|
+
cache_creation: {
|
|
42
|
+
ephemeral_5m_input_tokens: 'number',
|
|
43
|
+
ephemeral_1h_input_tokens: 'number',
|
|
44
|
+
},
|
|
45
|
+
service_tier: 'text',
|
|
46
|
+
speed: 'text',
|
|
47
|
+
server_tool_use: { web_search_requests: 'number', web_fetch_requests: 'number' },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
11
51
|
};
|
|
12
52
|
|
|
13
53
|
/** Validate one JSONL line and decode only whitelisted metadata scalars.
|
|
14
54
|
* Skipped strings remain bytes: no prompt/response strings or objects are built.
|
|
15
55
|
* The line's byte buffer is discarded by the scanner after processing.
|
|
16
56
|
*/
|
|
17
|
-
export function usageMetadata(bytes
|
|
18
|
-
let at=0;
|
|
19
|
-
const fail=()
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
57
|
+
export function usageMetadata(bytes , provider ) {
|
|
58
|
+
let at = 0;
|
|
59
|
+
const fail = () => {
|
|
60
|
+
throw new SyntaxError('Invalid usage JSON');
|
|
61
|
+
};
|
|
62
|
+
const space = () => {
|
|
63
|
+
while (
|
|
64
|
+
at < bytes.length &&
|
|
65
|
+
(bytes[at] === 32 || bytes[at] === 9 || bytes[at] === 10 || bytes[at] === 13)
|
|
66
|
+
)
|
|
67
|
+
at++;
|
|
68
|
+
};
|
|
69
|
+
const string = () => {
|
|
70
|
+
const buffer = bytes;
|
|
71
|
+
let i = at + 1;
|
|
72
|
+
for (; i < buffer.length; i++) {
|
|
73
|
+
const byte = buffer[i];
|
|
74
|
+
if (byte === 34) {
|
|
75
|
+
at = i + 1;
|
|
76
|
+
return at;
|
|
77
|
+
}
|
|
78
|
+
if (byte < 32) fail();
|
|
79
|
+
if (byte === 92) {
|
|
80
|
+
const escaped = buffer[++i];
|
|
81
|
+
if (escaped === 117) {
|
|
82
|
+
for (let j = 0; j < 4; j++) {
|
|
83
|
+
const hex = buffer[++i];
|
|
84
|
+
if (!(
|
|
85
|
+
(hex >= 48 && hex <= 57) ||
|
|
86
|
+
(hex >= 65 && hex <= 70) ||
|
|
87
|
+
(hex >= 97 && hex <= 102)
|
|
88
|
+
))
|
|
89
|
+
fail();
|
|
90
|
+
}
|
|
91
|
+
} else if (![34, 92, 47, 98, 102, 110, 114, 116].includes(escaped)) fail();
|
|
29
92
|
}
|
|
30
93
|
}
|
|
31
94
|
return fail();
|
|
32
95
|
};
|
|
33
|
-
const number=()=>{
|
|
34
|
-
if(bytes[at]===45)at++;
|
|
35
|
-
if(bytes[at]===48)at++;
|
|
36
|
-
else {
|
|
37
|
-
|
|
38
|
-
|
|
96
|
+
const number = () => {
|
|
97
|
+
if (bytes[at] === 45) at++;
|
|
98
|
+
if (bytes[at] === 48) at++;
|
|
99
|
+
else {
|
|
100
|
+
if (!(bytes[at] >= 49 && bytes[at] <= 57)) fail();
|
|
101
|
+
while (bytes[at] >= 48 && bytes[at] <= 57) at++;
|
|
102
|
+
}
|
|
103
|
+
if (bytes[at] === 46) {
|
|
104
|
+
at++;
|
|
105
|
+
if (!(bytes[at] >= 48 && bytes[at] <= 57)) fail();
|
|
106
|
+
while (bytes[at] >= 48 && bytes[at] <= 57) at++;
|
|
107
|
+
}
|
|
108
|
+
if (bytes[at] === 101 || bytes[at] === 69) {
|
|
109
|
+
at++;
|
|
110
|
+
if (bytes[at] === 43 || bytes[at] === 45) at++;
|
|
111
|
+
if (!(bytes[at] >= 48 && bytes[at] <= 57)) fail();
|
|
112
|
+
while (bytes[at] >= 48 && bytes[at] <= 57) at++;
|
|
113
|
+
}
|
|
39
114
|
};
|
|
40
|
-
const value=(selected
|
|
41
|
-
if(depth>512)fail();
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
115
|
+
const value = (selected , depth ) => {
|
|
116
|
+
if (depth > 512) fail();
|
|
117
|
+
space();
|
|
118
|
+
const start = at,
|
|
119
|
+
byte = bytes[at];
|
|
120
|
+
if (byte === 123) {
|
|
121
|
+
at++;
|
|
122
|
+
space();
|
|
123
|
+
const object =
|
|
124
|
+
selected && typeof selected === 'object' ? {} : undefined;
|
|
125
|
+
if (bytes[at] === 125) {
|
|
126
|
+
at++;
|
|
127
|
+
return object ?? (selected ? null : undefined);
|
|
128
|
+
}
|
|
129
|
+
while (at < bytes.length) {
|
|
130
|
+
if (bytes[at] !== 34) fail();
|
|
131
|
+
const keyStart = at;
|
|
132
|
+
string();
|
|
133
|
+
let child = undefined,
|
|
134
|
+
key = '';
|
|
47
135
|
// All selected keys are short ASCII names; escaped spellings are allowed.
|
|
48
|
-
if(object&&at-keyStart<=192){
|
|
49
|
-
|
|
50
|
-
|
|
136
|
+
if (object && at - keyStart <= 192) {
|
|
137
|
+
key = JSON.parse(bytes.toString('utf8', keyStart, at));
|
|
138
|
+
if (selected && typeof selected === 'object' && Object.hasOwn(selected, key))
|
|
139
|
+
child = selected[key];
|
|
140
|
+
}
|
|
141
|
+
space();
|
|
142
|
+
if (bytes[at++] !== 58) fail();
|
|
143
|
+
const result = value(child, depth + 1);
|
|
144
|
+
if (child) object [key] = result;
|
|
145
|
+
space();
|
|
146
|
+
const next = bytes[at++];
|
|
147
|
+
if (next === 125) return object ?? (selected ? null : undefined);
|
|
148
|
+
if (next !== 44) fail();
|
|
149
|
+
space();
|
|
51
150
|
}
|
|
52
151
|
return fail();
|
|
53
152
|
}
|
|
54
|
-
if(byte===91){
|
|
55
|
-
at++;
|
|
56
|
-
|
|
153
|
+
if (byte === 91) {
|
|
154
|
+
at++;
|
|
155
|
+
space();
|
|
156
|
+
if (bytes[at] === 93) {
|
|
157
|
+
at++;
|
|
158
|
+
return selected && typeof selected === 'object' ? [] : selected ? null : undefined;
|
|
159
|
+
}
|
|
160
|
+
while (at < bytes.length) {
|
|
161
|
+
value(undefined, depth + 1);
|
|
162
|
+
space();
|
|
163
|
+
const next = bytes[at++];
|
|
164
|
+
if (next === 93)
|
|
165
|
+
return selected && typeof selected === 'object' ? [] : selected ? null : undefined;
|
|
166
|
+
if (next !== 44) fail();
|
|
167
|
+
}
|
|
57
168
|
return fail();
|
|
58
169
|
}
|
|
59
|
-
if(byte===34)string();
|
|
60
|
-
else if(byte===45||(byte>=48&&byte<=57))number();
|
|
170
|
+
if (byte === 34) string();
|
|
171
|
+
else if (byte === 45 || (byte >= 48 && byte <= 57)) number();
|
|
61
172
|
else {
|
|
62
|
-
const literal=
|
|
63
|
-
|
|
173
|
+
const literal =
|
|
174
|
+
byte === 116 ? 'true' : byte === 102 ? 'false' : byte === 110 ? 'null' : fail();
|
|
175
|
+
for (let i = 0; i < literal.length; i++) if (bytes[at++] !== literal.charCodeAt(i)) fail();
|
|
64
176
|
}
|
|
65
|
-
if(!selected)return undefined;
|
|
66
|
-
if(!(
|
|
177
|
+
if (!selected) return undefined;
|
|
178
|
+
if (!(
|
|
179
|
+
(selected === 'text' && byte === 34) ||
|
|
180
|
+
(selected === 'number' && (byte === 45 || (byte >= 48 && byte <= 57)))
|
|
181
|
+
))
|
|
182
|
+
return null;
|
|
67
183
|
// Oversized metadata scalars cannot be valid identifiers/counters. Never
|
|
68
184
|
// materialize a conversation disguised as an allowed metadata value.
|
|
69
|
-
if(at-start>1024)return null;
|
|
70
|
-
return JSON.parse(bytes.toString('utf8',start,at));
|
|
185
|
+
if (at - start > 1024) return null;
|
|
186
|
+
return JSON.parse(bytes.toString('utf8', start, at));
|
|
71
187
|
};
|
|
72
|
-
const result=value(fields[provider],0);
|
|
188
|
+
const result = value(fields[provider], 0);
|
|
189
|
+
space();
|
|
190
|
+
if (at !== bytes.length) fail();
|
|
191
|
+
return result;
|
|
73
192
|
}
|