@autohq/cli 0.1.229 → 0.1.231

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.
@@ -19474,6 +19474,21 @@ var RuntimeTurnStatusSchema = external_exports.enum([
19474
19474
  "completed",
19475
19475
  "failed"
19476
19476
  ]);
19477
+ var RuntimeBridgeUsageHarnessSchema = external_exports.enum(["claude-code", "codex"]);
19478
+ var RuntimeBridgeModelUsageSchema = external_exports.object({
19479
+ model: external_exports.string().trim().min(1),
19480
+ inputTokens: external_exports.number().int().nonnegative(),
19481
+ outputTokens: external_exports.number().int().nonnegative(),
19482
+ cacheCreationTokens: external_exports.number().int().nonnegative(),
19483
+ cacheReadTokens: external_exports.number().int().nonnegative(),
19484
+ // The harness provider's own per-model cost, for reconciliation only; null
19485
+ // when the harness reports none. Never the billed figure.
19486
+ providerCostUsd: external_exports.number().nonnegative().nullable()
19487
+ }).strict();
19488
+ var RuntimeBridgeTurnUsageSchema = external_exports.object({
19489
+ harness: RuntimeBridgeUsageHarnessSchema,
19490
+ models: external_exports.array(RuntimeBridgeModelUsageSchema)
19491
+ }).strict();
19477
19492
  var ConversationTextContentPartSchema = external_exports.object({
19478
19493
  type: external_exports.literal("text"),
19479
19494
  text: external_exports.string()
@@ -19656,7 +19671,10 @@ var RuntimeBridgeOutputEntryEnvelopeWireSchema = external_exports.object({
19656
19671
  content: ConversationEntryContentSchema,
19657
19672
  createdAt: external_exports.string().datetime(),
19658
19673
  completedAt: external_exports.string().datetime().nullable(),
19659
- turnStatus: RuntimeTurnStatusSchema.optional()
19674
+ turnStatus: RuntimeTurnStatusSchema.optional(),
19675
+ // Present only on a turn's terminal result entry; carries the captured
19676
+ // token/cost usage the persisting side turns into ledger rows.
19677
+ usage: RuntimeBridgeTurnUsageSchema.optional()
19660
19678
  }).strict();
19661
19679
  var LegacyRuntimeBridgeOutputEntryEnvelopeSchema = RuntimeBridgeOutputEntryEnvelopeWireSchema.omit({ turnStatus: true }).extend({
19662
19680
  sessionStatusAfter: external_exports.enum(["awaiting", "failed"])
@@ -23322,7 +23340,7 @@ Object.assign(lookup, {
23322
23340
  // package.json
23323
23341
  var package_default = {
23324
23342
  name: "@autohq/cli",
23325
- version: "0.1.229",
23343
+ version: "0.1.231",
23326
23344
  license: "SEE LICENSE IN README.md",
23327
23345
  publishConfig: {
23328
23346
  access: "public"
@@ -24565,13 +24583,29 @@ var ClaudeCodeUserRecordSchema = external_exports.object({
24565
24583
  type: external_exports.literal("user"),
24566
24584
  message: ClaudeCodeUserMessageSchema
24567
24585
  }).passthrough();
24586
+ var ClaudeCodeAggregateUsageSchema = external_exports.object({
24587
+ input_tokens: external_exports.number().optional(),
24588
+ output_tokens: external_exports.number().optional(),
24589
+ cache_creation_input_tokens: external_exports.number().optional(),
24590
+ cache_read_input_tokens: external_exports.number().optional()
24591
+ }).passthrough();
24592
+ var ClaudeCodeModelUsageSchema = external_exports.object({
24593
+ inputTokens: external_exports.number().optional(),
24594
+ outputTokens: external_exports.number().optional(),
24595
+ cacheCreationInputTokens: external_exports.number().optional(),
24596
+ cacheReadInputTokens: external_exports.number().optional(),
24597
+ costUSD: external_exports.number().optional()
24598
+ }).passthrough();
24568
24599
  var ClaudeCodeResultRecordSchema = external_exports.object({
24569
24600
  type: external_exports.literal("result"),
24570
24601
  subtype: external_exports.string().optional(),
24571
24602
  is_error: external_exports.boolean().optional(),
24572
24603
  error: external_exports.string().optional(),
24573
24604
  errors: external_exports.array(external_exports.string()).optional(),
24574
- result: external_exports.string().optional()
24605
+ result: external_exports.string().optional(),
24606
+ total_cost_usd: external_exports.number().optional(),
24607
+ usage: ClaudeCodeAggregateUsageSchema.optional(),
24608
+ modelUsage: external_exports.record(external_exports.string(), ClaudeCodeModelUsageSchema).optional()
24575
24609
  }).passthrough();
24576
24610
  var ClaudeCodeSessionRecordSchema = external_exports.object({
24577
24611
  session_id: external_exports.string().trim().min(1)
@@ -24601,11 +24635,13 @@ function parseClaudeCodeStreamRecord(parsed) {
24601
24635
  const isError = record2.is_error === true || record2.subtype === "error";
24602
24636
  const sdkErrorMessage = record2.errors?.map((error51) => error51.trim()).filter(Boolean).join("\n");
24603
24637
  const errorMessage4 = isError ? record2.error ?? record2.result ?? (sdkErrorMessage || void 0) ?? "claude-code reported an error" : void 0;
24638
+ const usage = claudeCodeUsageFromRecord(record2);
24604
24639
  return {
24605
24640
  projections: [],
24606
24641
  result: {
24607
24642
  isError,
24608
- errorMessage: errorMessage4
24643
+ errorMessage: errorMessage4,
24644
+ ...usage ? { usage } : {}
24609
24645
  }
24610
24646
  };
24611
24647
  }
@@ -24742,6 +24778,43 @@ function userContentProjections(message) {
24742
24778
  }
24743
24779
  return projections;
24744
24780
  }
24781
+ function claudeCodeUsageFromRecord(record2) {
24782
+ const aggregate = record2.usage;
24783
+ const modelUsage = record2.modelUsage;
24784
+ if (!aggregate && !modelUsage) {
24785
+ return void 0;
24786
+ }
24787
+ const perModel = Object.entries(modelUsage ?? {}).map(
24788
+ ([model, usage]) => ({
24789
+ model,
24790
+ inputTokens: tokenCount(usage.inputTokens),
24791
+ outputTokens: tokenCount(usage.outputTokens),
24792
+ cacheCreationTokens: tokenCount(usage.cacheCreationInputTokens),
24793
+ cacheReadTokens: tokenCount(usage.cacheReadInputTokens),
24794
+ providerCostUsd: usdAmount(usage.costUSD)
24795
+ })
24796
+ );
24797
+ return {
24798
+ inputTokens: tokenCount(aggregate?.input_tokens),
24799
+ outputTokens: tokenCount(aggregate?.output_tokens),
24800
+ cacheCreationTokens: tokenCount(aggregate?.cache_creation_input_tokens),
24801
+ cacheReadTokens: tokenCount(aggregate?.cache_read_input_tokens),
24802
+ totalCostUsd: usdAmount(record2.total_cost_usd),
24803
+ perModel
24804
+ };
24805
+ }
24806
+ function tokenCount(value2) {
24807
+ if (typeof value2 !== "number" || !Number.isFinite(value2) || value2 < 0) {
24808
+ return 0;
24809
+ }
24810
+ return Math.trunc(value2);
24811
+ }
24812
+ function usdAmount(value2) {
24813
+ if (typeof value2 !== "number" || !Number.isFinite(value2) || value2 < 0) {
24814
+ return 0;
24815
+ }
24816
+ return value2;
24817
+ }
24745
24818
 
24746
24819
  // ../../packages/schemas/src/codex.ts
24747
24820
  var CodexRequestIdSchema = external_exports.union([external_exports.string(), external_exports.number()]);
@@ -24812,6 +24885,21 @@ var CodexTurnEnvelopeSchema = external_exports.object({
24812
24885
  error: external_exports.object({ message: external_exports.string() }).passthrough().nullish()
24813
24886
  }).passthrough()
24814
24887
  }).passthrough();
24888
+ var CodexTokenUsageSchema = external_exports.object({
24889
+ totalTokens: external_exports.number().int().nonnegative(),
24890
+ inputTokens: external_exports.number().int().nonnegative(),
24891
+ cachedInputTokens: external_exports.number().int().nonnegative(),
24892
+ outputTokens: external_exports.number().int().nonnegative(),
24893
+ reasoningOutputTokens: external_exports.number().int().nonnegative()
24894
+ }).passthrough();
24895
+ var CodexTokenUsageEnvelopeSchema = external_exports.object({
24896
+ threadId: external_exports.string(),
24897
+ turnId: external_exports.string(),
24898
+ tokenUsage: external_exports.object({
24899
+ total: CodexTokenUsageSchema,
24900
+ last: CodexTokenUsageSchema
24901
+ }).passthrough()
24902
+ }).passthrough();
24815
24903
  var CodexFrameSchema = external_exports.object({
24816
24904
  id: CodexRequestIdSchema.optional(),
24817
24905
  method: external_exports.string().optional(),
@@ -24951,6 +25039,16 @@ function parseNotification(method, params) {
24951
25039
  item: parsed.data.item
24952
25040
  };
24953
25041
  }
25042
+ case "thread/tokenUsage/updated": {
25043
+ const parsed = CodexTokenUsageEnvelopeSchema.safeParse(params);
25044
+ return parsed.success ? {
25045
+ type: "tokenUsage",
25046
+ threadId: parsed.data.threadId,
25047
+ turnId: parsed.data.turnId,
25048
+ total: parsed.data.tokenUsage.total,
25049
+ last: parsed.data.tokenUsage.last
25050
+ } : null;
25051
+ }
24954
25052
  case "item/agentMessage/delta": {
24955
25053
  const parsed = external_exports.object({ itemId: external_exports.string(), delta: external_exports.string() }).passthrough().safeParse(params);
24956
25054
  return parsed.success ? {
@@ -27873,7 +27971,8 @@ function buildOutputEnvelope(context, outputSeq, projection) {
27873
27971
  content: entry.content,
27874
27972
  createdAt,
27875
27973
  completedAt: entry.status === "in_progress" ? null : createdAt,
27876
- ...entry.turnStatus ? { turnStatus: entry.turnStatus } : {}
27974
+ ...entry.turnStatus ? { turnStatus: entry.turnStatus } : {},
27975
+ ...entry.usage ? { usage: entry.usage } : {}
27877
27976
  });
27878
27977
  }
27879
27978
  function buildDeltaOutputEnvelope(input) {
@@ -27934,6 +28033,7 @@ var ClaudeCodeProjector = class {
27934
28033
  }
27935
28034
  };
27936
28035
  function projectClaudeCodeResult(result) {
28036
+ const usage = claudeCodeTurnUsage(result.usage);
27937
28037
  return {
27938
28038
  type: "entry",
27939
28039
  entry: {
@@ -27948,10 +28048,27 @@ function projectClaudeCodeResult(result) {
27948
28048
  text: result.isError ? `claude-code failed: ${result.errorMessage ?? "unknown error"}` : "claude-code completed"
27949
28049
  }
27950
28050
  ]
27951
- }
28051
+ },
28052
+ ...usage ? { usage } : {}
27952
28053
  }
27953
28054
  };
27954
28055
  }
28056
+ function claudeCodeTurnUsage(usage) {
28057
+ if (!usage || usage.perModel.length === 0) {
28058
+ return void 0;
28059
+ }
28060
+ return {
28061
+ harness: "claude-code",
28062
+ models: usage.perModel.map((model) => ({
28063
+ model: model.model,
28064
+ inputTokens: model.inputTokens,
28065
+ outputTokens: model.outputTokens,
28066
+ cacheCreationTokens: model.cacheCreationTokens,
28067
+ cacheReadTokens: model.cacheReadTokens,
28068
+ providerCostUsd: model.providerCostUsd
28069
+ }))
28070
+ };
28071
+ }
27955
28072
  function anthropicMessageIdFromStreamStart(message) {
27956
28073
  const event = message.event;
27957
28074
  if (event.type !== "message_start") {
@@ -49496,6 +49613,40 @@ function errorMessage2(error51) {
49496
49613
  return error51 instanceof Error ? error51.message : String(error51);
49497
49614
  }
49498
49615
 
49616
+ // src/commands/agent-bridge/harness/codex/usage.ts
49617
+ function addCodexUsage(accumulated, next) {
49618
+ if (!accumulated) {
49619
+ return next;
49620
+ }
49621
+ return {
49622
+ totalTokens: accumulated.totalTokens + next.totalTokens,
49623
+ inputTokens: accumulated.inputTokens + next.inputTokens,
49624
+ cachedInputTokens: accumulated.cachedInputTokens + next.cachedInputTokens,
49625
+ outputTokens: accumulated.outputTokens + next.outputTokens,
49626
+ reasoningOutputTokens: accumulated.reasoningOutputTokens + next.reasoningOutputTokens
49627
+ };
49628
+ }
49629
+ function codexTurnUsage(usage) {
49630
+ if (usage.totalTokens === 0) {
49631
+ return void 0;
49632
+ }
49633
+ const cacheReadTokens = usage.cachedInputTokens;
49634
+ const inputTokens = Math.max(0, usage.inputTokens - cacheReadTokens);
49635
+ return {
49636
+ harness: "codex",
49637
+ models: [
49638
+ {
49639
+ model: CODEX_DEFAULT_MODEL,
49640
+ inputTokens,
49641
+ outputTokens: usage.outputTokens,
49642
+ cacheCreationTokens: 0,
49643
+ cacheReadTokens,
49644
+ providerCostUsd: null
49645
+ }
49646
+ ]
49647
+ };
49648
+ }
49649
+
49499
49650
  // src/commands/agent-bridge/harness/codex/index.ts
49500
49651
  function createCodexCommandHandler(input) {
49501
49652
  return new CodexCommandHandler({
@@ -49517,6 +49668,11 @@ var CodexCommandHandler = class {
49517
49668
  pendingApprovals = /* @__PURE__ */ new Map();
49518
49669
  outputBuffer;
49519
49670
  projector = new CodexProjector();
49671
+ // The active turn's running usage sum. codex emits one
49672
+ // `thread/tokenUsage/updated` per model request; their `last` breakdowns are
49673
+ // summed here and ride the turn-completion entry. Reset at each turn boundary
49674
+ // so usage never leaks across turns.
49675
+ turnTokenUsage = null;
49520
49676
  // ---------------------------------------------------------------------------
49521
49677
  // Lifecycle (public API)
49522
49678
  // ---------------------------------------------------------------------------
@@ -49533,6 +49689,7 @@ var CodexCommandHandler = class {
49533
49689
  this.session?.close();
49534
49690
  this.session = null;
49535
49691
  this.pendingApprovals.clear();
49692
+ this.turnTokenUsage = null;
49536
49693
  }
49537
49694
  async handleCommand(rawDelivery) {
49538
49695
  const delivery = RuntimeBridgeCommandDeliverySchema.parse(rawDelivery);
@@ -49658,8 +49815,25 @@ var CodexCommandHandler = class {
49658
49815
  if (!activeContext) {
49659
49816
  return;
49660
49817
  }
49818
+ if (notification.type === "tokenUsage") {
49819
+ this.turnTokenUsage = addCodexUsage(
49820
+ this.turnTokenUsage,
49821
+ notification.last
49822
+ );
49823
+ return;
49824
+ }
49825
+ if (notification.type === "turnStarted") {
49826
+ this.turnTokenUsage = null;
49827
+ }
49828
+ const turnUsage = notification.type === "turnCompleted" && this.turnTokenUsage ? codexTurnUsage(this.turnTokenUsage) : void 0;
49661
49829
  for (const projection of this.projector.project(notification)) {
49662
- await this.emit(activeContext, projection);
49830
+ await this.emit(
49831
+ activeContext,
49832
+ attachTurnUsage(notification, projection, turnUsage)
49833
+ );
49834
+ }
49835
+ if (notification.type === "turnCompleted") {
49836
+ this.turnTokenUsage = null;
49663
49837
  }
49664
49838
  }
49665
49839
  async handleServerRequest(request) {
@@ -49777,6 +49951,15 @@ function deliveryMode2(delivery) {
49777
49951
  function errorMessage3(error51) {
49778
49952
  return error51 instanceof Error ? error51.message : String(error51);
49779
49953
  }
49954
+ function attachTurnUsage(notification, projection, turnUsage) {
49955
+ if (notification.type !== "turnCompleted" || projection.type !== "entry" || !turnUsage) {
49956
+ return projection;
49957
+ }
49958
+ return {
49959
+ type: "entry",
49960
+ entry: { ...projection.entry, usage: turnUsage }
49961
+ };
49962
+ }
49780
49963
 
49781
49964
  // src/commands/agent-bridge/harness/index.ts
49782
49965
  async function runAgentBridgeHarness(options) {
package/dist/index.js CHANGED
@@ -15967,11 +15967,13 @@ function parseClaudeCodeStreamRecord(parsed) {
15967
15967
  const isError = record2.is_error === true || record2.subtype === "error";
15968
15968
  const sdkErrorMessage = record2.errors?.map((error51) => error51.trim()).filter(Boolean).join("\n");
15969
15969
  const errorMessage6 = isError ? record2.error ?? record2.result ?? (sdkErrorMessage || void 0) ?? "claude-code reported an error" : void 0;
15970
+ const usage = claudeCodeUsageFromRecord(record2);
15970
15971
  return {
15971
15972
  projections: [],
15972
15973
  result: {
15973
15974
  isError,
15974
- errorMessage: errorMessage6
15975
+ errorMessage: errorMessage6,
15976
+ ...usage ? { usage } : {}
15975
15977
  }
15976
15978
  };
15977
15979
  }
@@ -16105,7 +16107,44 @@ function userContentProjections(message) {
16105
16107
  }
16106
16108
  return projections;
16107
16109
  }
16108
- var ASK_USER_QUESTION_TOOL_NAME, ClaudeCodeTextBlockSchema, ClaudeCodeToolUseBlockSchema, ClaudeCodeToolResultBlockSchema, ClaudeCodeAssistantContentBlockSchema, OptionalClaudeCodeAssistantContentBlockSchema, ClaudeCodeAssistantContentSchema, OptionalClaudeCodeToolResultBlockSchema, ClaudeCodeToolResultContentSchema, ClaudeCodeUserContentSchema, ClaudeCodeAssistantMessageSchema, ClaudeCodeUserMessageSchema, ClaudeCodeSystemRecordSchema, ClaudeCodeAssistantRecordSchema, ClaudeCodeUserRecordSchema, ClaudeCodeResultRecordSchema, ClaudeCodeSessionRecordSchema, ClaudeCodeStreamRecordSchema, AskUserQuestionInputSchema;
16110
+ function claudeCodeUsageFromRecord(record2) {
16111
+ const aggregate = record2.usage;
16112
+ const modelUsage = record2.modelUsage;
16113
+ if (!aggregate && !modelUsage) {
16114
+ return void 0;
16115
+ }
16116
+ const perModel = Object.entries(modelUsage ?? {}).map(
16117
+ ([model, usage]) => ({
16118
+ model,
16119
+ inputTokens: tokenCount(usage.inputTokens),
16120
+ outputTokens: tokenCount(usage.outputTokens),
16121
+ cacheCreationTokens: tokenCount(usage.cacheCreationInputTokens),
16122
+ cacheReadTokens: tokenCount(usage.cacheReadInputTokens),
16123
+ providerCostUsd: usdAmount(usage.costUSD)
16124
+ })
16125
+ );
16126
+ return {
16127
+ inputTokens: tokenCount(aggregate?.input_tokens),
16128
+ outputTokens: tokenCount(aggregate?.output_tokens),
16129
+ cacheCreationTokens: tokenCount(aggregate?.cache_creation_input_tokens),
16130
+ cacheReadTokens: tokenCount(aggregate?.cache_read_input_tokens),
16131
+ totalCostUsd: usdAmount(record2.total_cost_usd),
16132
+ perModel
16133
+ };
16134
+ }
16135
+ function tokenCount(value) {
16136
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
16137
+ return 0;
16138
+ }
16139
+ return Math.trunc(value);
16140
+ }
16141
+ function usdAmount(value) {
16142
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
16143
+ return 0;
16144
+ }
16145
+ return value;
16146
+ }
16147
+ var ASK_USER_QUESTION_TOOL_NAME, ClaudeCodeTextBlockSchema, ClaudeCodeToolUseBlockSchema, ClaudeCodeToolResultBlockSchema, ClaudeCodeAssistantContentBlockSchema, OptionalClaudeCodeAssistantContentBlockSchema, ClaudeCodeAssistantContentSchema, OptionalClaudeCodeToolResultBlockSchema, ClaudeCodeToolResultContentSchema, ClaudeCodeUserContentSchema, ClaudeCodeAssistantMessageSchema, ClaudeCodeUserMessageSchema, ClaudeCodeSystemRecordSchema, ClaudeCodeAssistantRecordSchema, ClaudeCodeUserRecordSchema, ClaudeCodeAggregateUsageSchema, ClaudeCodeModelUsageSchema, ClaudeCodeResultRecordSchema, ClaudeCodeSessionRecordSchema, ClaudeCodeStreamRecordSchema, AskUserQuestionInputSchema;
16109
16148
  var init_claude_code = __esm({
16110
16149
  "../../packages/schemas/src/claude-code.ts"() {
16111
16150
  "use strict";
@@ -16176,13 +16215,29 @@ var init_claude_code = __esm({
16176
16215
  type: external_exports.literal("user"),
16177
16216
  message: ClaudeCodeUserMessageSchema
16178
16217
  }).passthrough();
16218
+ ClaudeCodeAggregateUsageSchema = external_exports.object({
16219
+ input_tokens: external_exports.number().optional(),
16220
+ output_tokens: external_exports.number().optional(),
16221
+ cache_creation_input_tokens: external_exports.number().optional(),
16222
+ cache_read_input_tokens: external_exports.number().optional()
16223
+ }).passthrough();
16224
+ ClaudeCodeModelUsageSchema = external_exports.object({
16225
+ inputTokens: external_exports.number().optional(),
16226
+ outputTokens: external_exports.number().optional(),
16227
+ cacheCreationInputTokens: external_exports.number().optional(),
16228
+ cacheReadInputTokens: external_exports.number().optional(),
16229
+ costUSD: external_exports.number().optional()
16230
+ }).passthrough();
16179
16231
  ClaudeCodeResultRecordSchema = external_exports.object({
16180
16232
  type: external_exports.literal("result"),
16181
16233
  subtype: external_exports.string().optional(),
16182
16234
  is_error: external_exports.boolean().optional(),
16183
16235
  error: external_exports.string().optional(),
16184
16236
  errors: external_exports.array(external_exports.string()).optional(),
16185
- result: external_exports.string().optional()
16237
+ result: external_exports.string().optional(),
16238
+ total_cost_usd: external_exports.number().optional(),
16239
+ usage: ClaudeCodeAggregateUsageSchema.optional(),
16240
+ modelUsage: external_exports.record(external_exports.string(), ClaudeCodeModelUsageSchema).optional()
16186
16241
  }).passthrough();
16187
16242
  ClaudeCodeSessionRecordSchema = external_exports.object({
16188
16243
  session_id: external_exports.string().trim().min(1)
@@ -16330,6 +16385,16 @@ function parseNotification(method, params) {
16330
16385
  item: parsed.data.item
16331
16386
  };
16332
16387
  }
16388
+ case "thread/tokenUsage/updated": {
16389
+ const parsed = CodexTokenUsageEnvelopeSchema.safeParse(params);
16390
+ return parsed.success ? {
16391
+ type: "tokenUsage",
16392
+ threadId: parsed.data.threadId,
16393
+ turnId: parsed.data.turnId,
16394
+ total: parsed.data.tokenUsage.total,
16395
+ last: parsed.data.tokenUsage.last
16396
+ } : null;
16397
+ }
16333
16398
  case "item/agentMessage/delta": {
16334
16399
  const parsed = external_exports.object({ itemId: external_exports.string(), delta: external_exports.string() }).passthrough().safeParse(params);
16335
16400
  return parsed.success ? {
@@ -16442,7 +16507,7 @@ function textContent2(text) {
16442
16507
  function isFailedStatus(status) {
16443
16508
  return status === "failed" || status === "declined";
16444
16509
  }
16445
- var CodexRequestIdSchema, CodexTurnStatusSchema, CodexUserMessageItemSchema, CodexAgentMessageItemSchema, CodexReasoningItemSchema, CodexCommandExecutionItemSchema, CodexFileChangeItemSchema, CodexMcpToolCallItemSchema, CodexItemSchema, OptionalCodexItemSchema, CodexItemEnvelopeSchema, CodexTurnEnvelopeSchema, CodexFrameSchema, APPROVE_OPTION_LABEL, DECLINE_OPTION_LABEL;
16510
+ var CodexRequestIdSchema, CodexTurnStatusSchema, CodexUserMessageItemSchema, CodexAgentMessageItemSchema, CodexReasoningItemSchema, CodexCommandExecutionItemSchema, CodexFileChangeItemSchema, CodexMcpToolCallItemSchema, CodexItemSchema, OptionalCodexItemSchema, CodexItemEnvelopeSchema, CodexTurnEnvelopeSchema, CodexTokenUsageSchema, CodexTokenUsageEnvelopeSchema, CodexFrameSchema, APPROVE_OPTION_LABEL, DECLINE_OPTION_LABEL;
16446
16511
  var init_codex = __esm({
16447
16512
  "../../packages/schemas/src/codex.ts"() {
16448
16513
  "use strict";
@@ -16516,6 +16581,21 @@ var init_codex = __esm({
16516
16581
  error: external_exports.object({ message: external_exports.string() }).passthrough().nullish()
16517
16582
  }).passthrough()
16518
16583
  }).passthrough();
16584
+ CodexTokenUsageSchema = external_exports.object({
16585
+ totalTokens: external_exports.number().int().nonnegative(),
16586
+ inputTokens: external_exports.number().int().nonnegative(),
16587
+ cachedInputTokens: external_exports.number().int().nonnegative(),
16588
+ outputTokens: external_exports.number().int().nonnegative(),
16589
+ reasoningOutputTokens: external_exports.number().int().nonnegative()
16590
+ }).passthrough();
16591
+ CodexTokenUsageEnvelopeSchema = external_exports.object({
16592
+ threadId: external_exports.string(),
16593
+ turnId: external_exports.string(),
16594
+ tokenUsage: external_exports.object({
16595
+ total: CodexTokenUsageSchema,
16596
+ last: CodexTokenUsageSchema
16597
+ }).passthrough()
16598
+ }).passthrough();
16519
16599
  CodexFrameSchema = external_exports.object({
16520
16600
  id: CodexRequestIdSchema.optional(),
16521
16601
  method: external_exports.string().optional(),
@@ -22241,7 +22321,7 @@ var init_package = __esm({
22241
22321
  "package.json"() {
22242
22322
  package_default = {
22243
22323
  name: "@autohq/cli",
22244
- version: "0.1.229",
22324
+ version: "0.1.231",
22245
22325
  license: "SEE LICENSE IN README.md",
22246
22326
  publishConfig: {
22247
22327
  access: "public"
@@ -26882,7 +26962,7 @@ function conversationEscapeAction(input) {
26882
26962
  function WorkingIndicator({
26883
26963
  word,
26884
26964
  startedAt,
26885
- tokenCount
26965
+ tokenCount: tokenCount2
26886
26966
  }) {
26887
26967
  const [tick, setTick] = useState2(0);
26888
26968
  useEffect2(() => {
@@ -26910,7 +26990,7 @@ function WorkingIndicator({
26910
26990
  /* @__PURE__ */ jsx4(Text4, { color: TRANSCRIPT_COLORS.spinner, children: "\u2026 " }),
26911
26991
  /* @__PURE__ */ jsx4(Text4, { color: TRANSCRIPT_COLORS.dim, children: formatWorkingSuffix({
26912
26992
  elapsedSeconds: elapsedSeconds(startedAt),
26913
- tokenCount
26993
+ tokenCount: tokenCount2
26914
26994
  }) })
26915
26995
  ] })
26916
26996
  ] });
@@ -31666,6 +31746,21 @@ var RuntimeTurnStatusSchema = external_exports.enum([
31666
31746
  "completed",
31667
31747
  "failed"
31668
31748
  ]);
31749
+ var RuntimeBridgeUsageHarnessSchema = external_exports.enum(["claude-code", "codex"]);
31750
+ var RuntimeBridgeModelUsageSchema = external_exports.object({
31751
+ model: external_exports.string().trim().min(1),
31752
+ inputTokens: external_exports.number().int().nonnegative(),
31753
+ outputTokens: external_exports.number().int().nonnegative(),
31754
+ cacheCreationTokens: external_exports.number().int().nonnegative(),
31755
+ cacheReadTokens: external_exports.number().int().nonnegative(),
31756
+ // The harness provider's own per-model cost, for reconciliation only; null
31757
+ // when the harness reports none. Never the billed figure.
31758
+ providerCostUsd: external_exports.number().nonnegative().nullable()
31759
+ }).strict();
31760
+ var RuntimeBridgeTurnUsageSchema = external_exports.object({
31761
+ harness: RuntimeBridgeUsageHarnessSchema,
31762
+ models: external_exports.array(RuntimeBridgeModelUsageSchema)
31763
+ }).strict();
31669
31764
  var ConversationTextContentPartSchema2 = external_exports.object({
31670
31765
  type: external_exports.literal("text"),
31671
31766
  text: external_exports.string()
@@ -31848,7 +31943,10 @@ var RuntimeBridgeOutputEntryEnvelopeWireSchema = external_exports.object({
31848
31943
  content: ConversationEntryContentSchema2,
31849
31944
  createdAt: external_exports.string().datetime(),
31850
31945
  completedAt: external_exports.string().datetime().nullable(),
31851
- turnStatus: RuntimeTurnStatusSchema.optional()
31946
+ turnStatus: RuntimeTurnStatusSchema.optional(),
31947
+ // Present only on a turn's terminal result entry; carries the captured
31948
+ // token/cost usage the persisting side turns into ledger rows.
31949
+ usage: RuntimeBridgeTurnUsageSchema.optional()
31852
31950
  }).strict();
31853
31951
  var LegacyRuntimeBridgeOutputEntryEnvelopeSchema = RuntimeBridgeOutputEntryEnvelopeWireSchema.omit({ turnStatus: true }).extend({
31854
31952
  sessionStatusAfter: external_exports.enum(["awaiting", "failed"])
@@ -32592,7 +32690,8 @@ function buildOutputEnvelope(context, outputSeq, projection) {
32592
32690
  content: entry.content,
32593
32691
  createdAt,
32594
32692
  completedAt: entry.status === "in_progress" ? null : createdAt,
32595
- ...entry.turnStatus ? { turnStatus: entry.turnStatus } : {}
32693
+ ...entry.turnStatus ? { turnStatus: entry.turnStatus } : {},
32694
+ ...entry.usage ? { usage: entry.usage } : {}
32596
32695
  });
32597
32696
  }
32598
32697
  function buildDeltaOutputEnvelope(input) {
@@ -32654,6 +32753,7 @@ var ClaudeCodeProjector = class {
32654
32753
  }
32655
32754
  };
32656
32755
  function projectClaudeCodeResult(result) {
32756
+ const usage = claudeCodeTurnUsage(result.usage);
32657
32757
  return {
32658
32758
  type: "entry",
32659
32759
  entry: {
@@ -32668,10 +32768,27 @@ function projectClaudeCodeResult(result) {
32668
32768
  text: result.isError ? `claude-code failed: ${result.errorMessage ?? "unknown error"}` : "claude-code completed"
32669
32769
  }
32670
32770
  ]
32671
- }
32771
+ },
32772
+ ...usage ? { usage } : {}
32672
32773
  }
32673
32774
  };
32674
32775
  }
32776
+ function claudeCodeTurnUsage(usage) {
32777
+ if (!usage || usage.perModel.length === 0) {
32778
+ return void 0;
32779
+ }
32780
+ return {
32781
+ harness: "claude-code",
32782
+ models: usage.perModel.map((model) => ({
32783
+ model: model.model,
32784
+ inputTokens: model.inputTokens,
32785
+ outputTokens: model.outputTokens,
32786
+ cacheCreationTokens: model.cacheCreationTokens,
32787
+ cacheReadTokens: model.cacheReadTokens,
32788
+ providerCostUsd: model.providerCostUsd
32789
+ }))
32790
+ };
32791
+ }
32675
32792
  function anthropicMessageIdFromStreamStart(message) {
32676
32793
  const event = message.event;
32677
32794
  if (event.type !== "message_start") {
@@ -34649,6 +34766,40 @@ function errorMessage2(error51) {
34649
34766
  return error51 instanceof Error ? error51.message : String(error51);
34650
34767
  }
34651
34768
 
34769
+ // src/commands/agent-bridge/harness/codex/usage.ts
34770
+ function addCodexUsage(accumulated, next) {
34771
+ if (!accumulated) {
34772
+ return next;
34773
+ }
34774
+ return {
34775
+ totalTokens: accumulated.totalTokens + next.totalTokens,
34776
+ inputTokens: accumulated.inputTokens + next.inputTokens,
34777
+ cachedInputTokens: accumulated.cachedInputTokens + next.cachedInputTokens,
34778
+ outputTokens: accumulated.outputTokens + next.outputTokens,
34779
+ reasoningOutputTokens: accumulated.reasoningOutputTokens + next.reasoningOutputTokens
34780
+ };
34781
+ }
34782
+ function codexTurnUsage(usage) {
34783
+ if (usage.totalTokens === 0) {
34784
+ return void 0;
34785
+ }
34786
+ const cacheReadTokens = usage.cachedInputTokens;
34787
+ const inputTokens = Math.max(0, usage.inputTokens - cacheReadTokens);
34788
+ return {
34789
+ harness: "codex",
34790
+ models: [
34791
+ {
34792
+ model: CODEX_DEFAULT_MODEL,
34793
+ inputTokens,
34794
+ outputTokens: usage.outputTokens,
34795
+ cacheCreationTokens: 0,
34796
+ cacheReadTokens,
34797
+ providerCostUsd: null
34798
+ }
34799
+ ]
34800
+ };
34801
+ }
34802
+
34652
34803
  // src/commands/agent-bridge/harness/codex/index.ts
34653
34804
  function createCodexCommandHandler(input) {
34654
34805
  return new CodexCommandHandler({
@@ -34670,6 +34821,11 @@ var CodexCommandHandler = class {
34670
34821
  pendingApprovals = /* @__PURE__ */ new Map();
34671
34822
  outputBuffer;
34672
34823
  projector = new CodexProjector();
34824
+ // The active turn's running usage sum. codex emits one
34825
+ // `thread/tokenUsage/updated` per model request; their `last` breakdowns are
34826
+ // summed here and ride the turn-completion entry. Reset at each turn boundary
34827
+ // so usage never leaks across turns.
34828
+ turnTokenUsage = null;
34673
34829
  // ---------------------------------------------------------------------------
34674
34830
  // Lifecycle (public API)
34675
34831
  // ---------------------------------------------------------------------------
@@ -34686,6 +34842,7 @@ var CodexCommandHandler = class {
34686
34842
  this.session?.close();
34687
34843
  this.session = null;
34688
34844
  this.pendingApprovals.clear();
34845
+ this.turnTokenUsage = null;
34689
34846
  }
34690
34847
  async handleCommand(rawDelivery) {
34691
34848
  const delivery = RuntimeBridgeCommandDeliverySchema.parse(rawDelivery);
@@ -34811,8 +34968,25 @@ var CodexCommandHandler = class {
34811
34968
  if (!activeContext) {
34812
34969
  return;
34813
34970
  }
34971
+ if (notification.type === "tokenUsage") {
34972
+ this.turnTokenUsage = addCodexUsage(
34973
+ this.turnTokenUsage,
34974
+ notification.last
34975
+ );
34976
+ return;
34977
+ }
34978
+ if (notification.type === "turnStarted") {
34979
+ this.turnTokenUsage = null;
34980
+ }
34981
+ const turnUsage = notification.type === "turnCompleted" && this.turnTokenUsage ? codexTurnUsage(this.turnTokenUsage) : void 0;
34814
34982
  for (const projection of this.projector.project(notification)) {
34815
- await this.emit(activeContext, projection);
34983
+ await this.emit(
34984
+ activeContext,
34985
+ attachTurnUsage(notification, projection, turnUsage)
34986
+ );
34987
+ }
34988
+ if (notification.type === "turnCompleted") {
34989
+ this.turnTokenUsage = null;
34816
34990
  }
34817
34991
  }
34818
34992
  async handleServerRequest(request) {
@@ -34930,6 +35104,15 @@ function deliveryMode2(delivery) {
34930
35104
  function errorMessage3(error51) {
34931
35105
  return error51 instanceof Error ? error51.message : String(error51);
34932
35106
  }
35107
+ function attachTurnUsage(notification, projection, turnUsage) {
35108
+ if (notification.type !== "turnCompleted" || projection.type !== "entry" || !turnUsage) {
35109
+ return projection;
35110
+ }
35111
+ return {
35112
+ type: "entry",
35113
+ entry: { ...projection.entry, usage: turnUsage }
35114
+ };
35115
+ }
34933
35116
 
34934
35117
  // src/commands/agent-bridge/harness/index.ts
34935
35118
  async function runAgentBridgeHarness(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.229",
3
+ "version": "0.1.231",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"