@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.
Files changed (37) hide show
  1. package/PRE_RELEASE.md +6 -6
  2. package/README.md +5 -3
  3. package/dist/PRICING.md +15 -16
  4. package/dist/packages/cli/src/index.js +109 -20
  5. package/dist/packages/cli/src/protocol.js +13 -0
  6. package/dist/packages/cli/src/runtime.js +44 -14
  7. package/dist/packages/cli/src/server.js +306 -62
  8. package/dist/packages/core/src/calendar.js +41 -18
  9. package/dist/packages/core/src/coverage.js +12 -0
  10. package/dist/packages/core/src/demo.js +61 -9
  11. package/dist/packages/core/src/metadata.js +52 -9
  12. package/dist/packages/core/src/pricing/current.js +346 -297
  13. package/dist/packages/core/src/pricing/index.js +373 -73
  14. package/dist/packages/core/src/providers/claude/index.js +93 -21
  15. package/dist/packages/core/src/providers/codex/index.js +213 -46
  16. package/dist/packages/core/src/scanner.js +226 -46
  17. package/dist/packages/core/src/security.js +127 -34
  18. package/dist/packages/core/src/storage.js +215 -47
  19. package/dist/packages/core/src/subscriptions.js +146 -21
  20. package/dist/packages/core/src/summary.js +408 -59
  21. package/dist/packages/core/src/types.js +71 -17
  22. package/dist/packages/core/src/usage-json.js +166 -47
  23. package/dist/packages/receipt/src/index.js +386 -82
  24. package/dist/packages/ui/src/brand.js +42 -27
  25. package/dist/public/app.css +2280 -61
  26. package/dist/public/apps/web/src/landing.js +200 -8
  27. package/dist/public/apps/web/src/main.js +1143 -98
  28. package/dist/public/index.html +24 -1
  29. package/dist/public/landing.css +3235 -80
  30. package/dist/public/landing.html +21 -1
  31. package/dist/public/packages/core/src/calendar.js +41 -18
  32. package/dist/public/packages/core/src/coverage.js +12 -0
  33. package/dist/public/packages/core/src/subscriptions.js +146 -21
  34. package/dist/public/packages/receipt/src/index.js +386 -82
  35. package/dist/public/packages/ui/src/brand.js +42 -27
  36. package/dist/public/privacy.css +197 -9
  37. 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 ={input_tokens:'number',cached_input_tokens:'number',cache_write_input_tokens:'number',output_tokens:'number',reasoning_output_tokens:'number',total_tokens:'number'};
8
- const fields ={
9
- codex:{type:'text',timestamp:'text',ordinal:'number',payload:{type:'text',id:'text',model:'text',subagent_history_start_ordinal:'number',info:{total_token_usage:counters,last_token_usage:counters}}},
10
- claude:{type:'text',timestamp:'text',sessionId:'text',requestId:'text',message:{id:'text',model:'text',usage:{input_tokens:'number',cache_read_input_tokens:'number',cache_creation_input_tokens:'number',output_tokens:'number',cache_creation:{ephemeral_5m_input_tokens:'number',ephemeral_1h_input_tokens:'number'},service_tier:'text',speed:'text',server_tool_use:{web_search_requests:'number',web_fetch_requests:'number'}}}}
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 ,provider ) {
18
- let at=0;
19
- const fail=() =>{throw new SyntaxError('Invalid usage JSON');};
20
- const space=()=>{while(at<bytes.length&&(bytes[at]===32||bytes[at]===9||bytes[at]===10||bytes[at]===13))at++;};
21
- const string=() =>{
22
- const buffer=bytes;let i=at+1;
23
- for(;i<buffer.length;i++){
24
- const byte=buffer[i];if(byte===34){at=i+1;return at;}
25
- if(byte<32)fail();
26
- if(byte===92){const escaped=buffer[++i];
27
- if(escaped===117){for(let j=0;j<4;j++){const hex=buffer[++i];if(!((hex>=48&&hex<=57)||(hex>=65&&hex<=70)||(hex>=97&&hex<=102)))fail();}}
28
- else if(![34,92,47,98,102,110,114,116].includes(escaped))fail();
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 {if(!(bytes[at]>=49&&bytes[at]<=57))fail();while(bytes[at]>=48&&bytes[at]<=57)at++;}
37
- if(bytes[at]===46){at++;if(!(bytes[at]>=48&&bytes[at]<=57))fail();while(bytes[at]>=48&&bytes[at]<=57)at++;}
38
- if(bytes[at]===101||bytes[at]===69){at++;if(bytes[at]===43||bytes[at]===45)at++;if(!(bytes[at]>=48&&bytes[at]<=57))fail();while(bytes[at]>=48&&bytes[at]<=57)at++;}
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 ,depth ) =>{
41
- if(depth>512)fail();space();const start=at,byte=bytes[at];
42
- if(byte===123){
43
- at++;space();const object =selected&&typeof selected==='object'?{}:undefined;
44
- if(bytes[at]===125){at++;return object??(selected?null:undefined);}
45
- while(at<bytes.length){
46
- if(bytes[at]!==34)fail();const keyStart=at;string();let child =undefined,key='';
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){key=JSON.parse(bytes.toString('utf8',keyStart,at));if(selected&&typeof selected==='object'&&Object.hasOwn(selected,key))child=selected[key];}
49
- space();if(bytes[at++]!==58)fail();const result=value(child,depth+1);if(child)object [key]=result;
50
- space();const next=bytes[at++];if(next===125)return object??(selected?null:undefined);if(next!==44)fail();space();
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++;space();if(bytes[at]===93){at++;return selected&&typeof selected==='object'?[]:selected?null:undefined;}
56
- while(at<bytes.length){value(undefined,depth+1);space();const next=bytes[at++];if(next===93)return selected&&typeof selected==='object'?[]:selected?null:undefined;if(next!==44)fail();}
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=byte===116?'true':byte===102?'false':byte===110?'null':fail();
63
- for(let i=0;i<literal.length;i++)if(bytes[at++]!==literal.charCodeAt(i))fail();
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(!((selected==='text'&&byte===34)||(selected==='number'&&(byte===45||(byte>=48&&byte<=57)))))return null;
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);space();if(at!==bytes.length)fail();return result;
188
+ const result = value(fields[provider], 0);
189
+ space();
190
+ if (at !== bytes.length) fail();
191
+ return result;
73
192
  }