@usevalt/cli 0.4.0 → 0.5.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.
Files changed (2) hide show
  1. package/dist/index.js +42 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1010,7 +1010,7 @@ async function readStdin() {
1010
1010
  process.stdin.setEncoding("utf-8");
1011
1011
  process.stdin.on("data", (chunk) => chunks.push(String(chunk)));
1012
1012
  process.stdin.on("end", () => resolve4(chunks.join("")));
1013
- setTimeout(() => resolve4(chunks.join("")), 2e3);
1013
+ setTimeout(() => resolve4(chunks.join("")), 500);
1014
1014
  });
1015
1015
  return data.trim() ? JSON.parse(data) : {};
1016
1016
  } catch {
@@ -1067,13 +1067,28 @@ async function sendEvents(endpoint, apiKey, events) {
1067
1067
  return false;
1068
1068
  }
1069
1069
  }
1070
+ var MODEL_PRICING = {
1071
+ "claude-opus-4-6": { input: 15, output: 75, cacheRead: 1.5 },
1072
+ "claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3 },
1073
+ "claude-haiku-4-5": { input: 0.8, output: 4, cacheRead: 0.08 },
1074
+ // Legacy model names
1075
+ "claude-3-5-sonnet": { input: 3, output: 15, cacheRead: 0.3 },
1076
+ "claude-3-5-haiku": { input: 0.8, output: 4, cacheRead: 0.08 },
1077
+ "claude-3-opus": { input: 15, output: 75, cacheRead: 1.5 }
1078
+ };
1079
+ function calculateCost(model, promptTokens, completionTokens, cacheReadTokens) {
1080
+ const pricing = MODEL_PRICING[model] ?? Object.entries(MODEL_PRICING).find(([key]) => model.startsWith(key))?.[1];
1081
+ if (!pricing) return 0;
1082
+ return promptTokens / 1e6 * pricing.input + completionTokens / 1e6 * pricing.output + cacheReadTokens / 1e6 * pricing.cacheRead;
1083
+ }
1070
1084
  async function parseTranscript(transcriptPath) {
1071
1085
  const result = {
1072
1086
  totalCostUsd: 0,
1073
1087
  promptTokens: 0,
1074
1088
  completionTokens: 0,
1075
1089
  cacheReadTokens: 0,
1076
- cacheCreationTokens: 0
1090
+ cacheCreationTokens: 0,
1091
+ model: "unknown"
1077
1092
  };
1078
1093
  if (!existsSync3(transcriptPath)) return result;
1079
1094
  try {
@@ -1085,11 +1100,16 @@ async function parseTranscript(transcriptPath) {
1085
1100
  if (!line.trim()) continue;
1086
1101
  try {
1087
1102
  const entry = JSON.parse(line);
1088
- if (entry.usage) {
1089
- result.promptTokens += entry.usage.input_tokens ?? 0;
1090
- result.completionTokens += entry.usage.output_tokens ?? 0;
1091
- result.cacheReadTokens += entry.usage.cache_read_input_tokens ?? 0;
1092
- result.cacheCreationTokens += entry.usage.cache_creation_input_tokens ?? 0;
1103
+ const usage = entry.message?.usage ?? entry.usage;
1104
+ if (usage) {
1105
+ result.promptTokens += usage.input_tokens ?? 0;
1106
+ result.completionTokens += usage.output_tokens ?? 0;
1107
+ result.cacheReadTokens += usage.cache_read_input_tokens ?? 0;
1108
+ result.cacheCreationTokens += usage.cache_creation_input_tokens ?? 0;
1109
+ }
1110
+ const model = entry.message?.model ?? entry.model;
1111
+ if (model && result.model === "unknown") {
1112
+ result.model = model;
1093
1113
  }
1094
1114
  if (typeof entry.costUSD === "number") {
1095
1115
  result.totalCostUsd += entry.costUSD;
@@ -1099,6 +1119,14 @@ async function parseTranscript(transcriptPath) {
1099
1119
  }
1100
1120
  } catch {
1101
1121
  }
1122
+ if (result.totalCostUsd === 0 && result.promptTokens > 0) {
1123
+ result.totalCostUsd = calculateCost(
1124
+ result.model,
1125
+ result.promptTokens,
1126
+ result.completionTokens,
1127
+ result.cacheReadTokens
1128
+ );
1129
+ }
1102
1130
  return result;
1103
1131
  }
1104
1132
  var sessionStartCommand = new Command13("session-start").description("Hook: called when a Claude Code session starts").action(async () => {
@@ -1178,6 +1206,7 @@ var sessionEndCommand = new Command13("session-end").description("Hook: called w
1178
1206
  timestamp: now.toISOString(),
1179
1207
  duration_ms: durationMs,
1180
1208
  tool: "claude-code",
1209
+ model: metrics?.model ?? session.model,
1181
1210
  metadata: {
1182
1211
  started_at: session.startedAt,
1183
1212
  ended_at: now.toISOString(),
@@ -1202,22 +1231,21 @@ var sessionEndCommand = new Command13("session-end").description("Hook: called w
1202
1231
  tokens_completion: metrics.completionTokens,
1203
1232
  cost_usd: metrics.totalCostUsd,
1204
1233
  metadata: {
1234
+ model: metrics.model,
1205
1235
  cache_read_tokens: metrics.cacheReadTokens,
1206
1236
  cache_creation_tokens: metrics.cacheCreationTokens
1207
1237
  }
1208
1238
  });
1209
1239
  }
1210
- const sent = await sendEvents(session.endpoint, session.apiKey, events);
1240
+ sendEvents(session.endpoint, session.apiKey, events).catch(() => {
1241
+ });
1211
1242
  try {
1212
1243
  unlinkSync2(SESSION_FILE);
1213
1244
  } catch {
1214
1245
  }
1215
- if (sent) {
1216
- const costStr = metrics?.totalCostUsd ? ` $${metrics.totalCostUsd.toFixed(4)}` : "";
1217
- success(`Valt session ended: ${session.sessionId.slice(0, 8)} (${Math.round(durationMs / 1e3)}s${costStr})`);
1218
- } else {
1219
- warn("Session ended locally but failed to send to Valt.");
1220
- }
1246
+ const costStr = metrics?.totalCostUsd ? ` $${metrics.totalCostUsd.toFixed(4)}` : "";
1247
+ const tokenStr = metrics?.promptTokens ? ` ${metrics.promptTokens + metrics.completionTokens} tokens` : "";
1248
+ success(`Valt session ended: ${session.sessionId.slice(0, 8)} (${Math.round(durationMs / 1e3)}s${costStr}${tokenStr})`);
1221
1249
  } catch {
1222
1250
  }
1223
1251
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usevalt/cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Valt CLI — trust layer for AI-assisted development",
5
5
  "license": "MIT",
6
6
  "repository": {