@rasensio/aidlc 1.15.2 → 1.17.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 (209) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +4 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/compliance.d.ts +36 -0
  6. package/dist/commands/compliance.d.ts.map +1 -0
  7. package/dist/commands/compliance.js +275 -0
  8. package/dist/commands/compliance.js.map +1 -0
  9. package/dist/commands/constitution.d.ts +26 -0
  10. package/dist/commands/constitution.d.ts.map +1 -0
  11. package/dist/commands/constitution.js +145 -0
  12. package/dist/commands/constitution.js.map +1 -0
  13. package/dist/commands/cost.d.ts.map +1 -1
  14. package/dist/commands/cost.js +54 -35
  15. package/dist/commands/cost.js.map +1 -1
  16. package/dist/commands/doctor.js +7 -0
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/gate.d.ts.map +1 -1
  19. package/dist/commands/gate.js +13 -0
  20. package/dist/commands/gate.js.map +1 -1
  21. package/dist/commands/init.d.ts.map +1 -1
  22. package/dist/commands/init.js +119 -10
  23. package/dist/commands/init.js.map +1 -1
  24. package/dist/commands/metrics.d.ts.map +1 -1
  25. package/dist/commands/metrics.js +6 -1
  26. package/dist/commands/metrics.js.map +1 -1
  27. package/dist/commands/review.d.ts +2 -27
  28. package/dist/commands/review.d.ts.map +1 -1
  29. package/dist/commands/review.js +10 -166
  30. package/dist/commands/review.js.map +1 -1
  31. package/dist/commands/status.d.ts.map +1 -1
  32. package/dist/commands/status.js +7 -0
  33. package/dist/commands/status.js.map +1 -1
  34. package/dist/commands/transition.d.ts.map +1 -1
  35. package/dist/commands/transition.js +24 -1
  36. package/dist/commands/transition.js.map +1 -1
  37. package/dist/compile/adapters/claude-code.d.ts.map +1 -1
  38. package/dist/compile/adapters/claude-code.js +2 -1
  39. package/dist/compile/adapters/claude-code.js.map +1 -1
  40. package/dist/compile/adapters/codex.d.ts +22 -1
  41. package/dist/compile/adapters/codex.d.ts.map +1 -1
  42. package/dist/compile/adapters/codex.js +61 -27
  43. package/dist/compile/adapters/codex.js.map +1 -1
  44. package/dist/compile/adapters/cursor.d.ts.map +1 -1
  45. package/dist/compile/adapters/cursor.js +2 -19
  46. package/dist/compile/adapters/cursor.js.map +1 -1
  47. package/dist/compile/adapters/kiro.d.ts.map +1 -1
  48. package/dist/compile/adapters/kiro.js +1 -19
  49. package/dist/compile/adapters/kiro.js.map +1 -1
  50. package/dist/compile/adapters/windsurf.d.ts.map +1 -1
  51. package/dist/compile/adapters/windsurf.js +2 -1
  52. package/dist/compile/adapters/windsurf.js.map +1 -1
  53. package/dist/compile/guidance-install.d.ts +16 -19
  54. package/dist/compile/guidance-install.d.ts.map +1 -1
  55. package/dist/compile/guidance-install.js +26 -111
  56. package/dist/compile/guidance-install.js.map +1 -1
  57. package/dist/compile/layer-install.d.ts +122 -0
  58. package/dist/compile/layer-install.d.ts.map +1 -0
  59. package/dist/compile/layer-install.js +195 -0
  60. package/dist/compile/layer-install.js.map +1 -0
  61. package/dist/compile/loaders.d.ts +14 -0
  62. package/dist/compile/loaders.d.ts.map +1 -1
  63. package/dist/compile/loaders.js +23 -18
  64. package/dist/compile/loaders.js.map +1 -1
  65. package/dist/compile/skill-format.d.ts +39 -0
  66. package/dist/compile/skill-format.d.ts.map +1 -0
  67. package/dist/compile/skill-format.js +50 -0
  68. package/dist/compile/skill-format.js.map +1 -0
  69. package/dist/compliance/check.d.ts +79 -0
  70. package/dist/compliance/check.d.ts.map +1 -0
  71. package/dist/compliance/check.js +224 -0
  72. package/dist/compliance/check.js.map +1 -0
  73. package/dist/compliance/config.d.ts +91 -0
  74. package/dist/compliance/config.d.ts.map +1 -0
  75. package/dist/compliance/config.js +173 -0
  76. package/dist/compliance/config.js.map +1 -0
  77. package/dist/compliance/findings.d.ts +70 -0
  78. package/dist/compliance/findings.d.ts.map +1 -0
  79. package/dist/compliance/findings.js +132 -0
  80. package/dist/compliance/findings.js.map +1 -0
  81. package/dist/compliance/gate-criterion.d.ts +87 -0
  82. package/dist/compliance/gate-criterion.d.ts.map +1 -0
  83. package/dist/compliance/gate-criterion.js +168 -0
  84. package/dist/compliance/gate-criterion.js.map +1 -0
  85. package/dist/compliance/install.d.ts +135 -0
  86. package/dist/compliance/install.d.ts.map +1 -0
  87. package/dist/compliance/install.js +291 -0
  88. package/dist/compliance/install.js.map +1 -0
  89. package/dist/compliance/report.d.ts +144 -0
  90. package/dist/compliance/report.d.ts.map +1 -0
  91. package/dist/compliance/report.js +347 -0
  92. package/dist/compliance/report.js.map +1 -0
  93. package/dist/compliance/resolver.d.ts +65 -0
  94. package/dist/compliance/resolver.d.ts.map +1 -0
  95. package/dist/compliance/resolver.js +176 -0
  96. package/dist/compliance/resolver.js.map +1 -0
  97. package/dist/compliance/schema.d.ts +74 -0
  98. package/dist/compliance/schema.d.ts.map +1 -0
  99. package/dist/compliance/schema.js +474 -0
  100. package/dist/compliance/schema.js.map +1 -0
  101. package/dist/compliance/types.d.ts +140 -0
  102. package/dist/compliance/types.d.ts.map +1 -0
  103. package/dist/compliance/types.js +29 -0
  104. package/dist/compliance/types.js.map +1 -0
  105. package/dist/constitution/check.d.ts +22 -0
  106. package/dist/constitution/check.d.ts.map +1 -0
  107. package/dist/constitution/check.js +89 -0
  108. package/dist/constitution/check.js.map +1 -0
  109. package/dist/constitution/docx.d.ts +51 -0
  110. package/dist/constitution/docx.d.ts.map +1 -0
  111. package/dist/constitution/docx.js +157 -0
  112. package/dist/constitution/docx.js.map +1 -0
  113. package/dist/constitution/entries.d.ts +27 -0
  114. package/dist/constitution/entries.d.ts.map +1 -0
  115. package/dist/constitution/entries.js +65 -0
  116. package/dist/constitution/entries.js.map +1 -0
  117. package/dist/constitution/extract.d.ts +34 -0
  118. package/dist/constitution/extract.d.ts.map +1 -0
  119. package/dist/constitution/extract.js +117 -0
  120. package/dist/constitution/extract.js.map +1 -0
  121. package/dist/constitution/snapshot.d.ts +47 -0
  122. package/dist/constitution/snapshot.d.ts.map +1 -0
  123. package/dist/constitution/snapshot.js +159 -0
  124. package/dist/constitution/snapshot.js.map +1 -0
  125. package/dist/constitution/statements.d.ts +37 -0
  126. package/dist/constitution/statements.d.ts.map +1 -0
  127. package/dist/constitution/statements.js +64 -0
  128. package/dist/constitution/statements.js.map +1 -0
  129. package/dist/constitution/types.d.ts +80 -0
  130. package/dist/constitution/types.d.ts.map +1 -0
  131. package/dist/constitution/types.js +9 -0
  132. package/dist/constitution/types.js.map +1 -0
  133. package/dist/core/gate.d.ts +10 -0
  134. package/dist/core/gate.d.ts.map +1 -1
  135. package/dist/core/gate.js.map +1 -1
  136. package/dist/core/paths.d.ts +48 -0
  137. package/dist/core/paths.d.ts.map +1 -0
  138. package/dist/core/paths.js +57 -0
  139. package/dist/core/paths.js.map +1 -0
  140. package/dist/core/types.d.ts +12 -1
  141. package/dist/core/types.d.ts.map +1 -1
  142. package/dist/cost/hooks/registry.d.ts +44 -0
  143. package/dist/cost/hooks/registry.d.ts.map +1 -0
  144. package/dist/cost/hooks/registry.js +66 -0
  145. package/dist/cost/hooks/registry.js.map +1 -0
  146. package/dist/cost/pin.d.ts +63 -0
  147. package/dist/cost/pin.d.ts.map +1 -0
  148. package/dist/cost/pin.js +95 -0
  149. package/dist/cost/pin.js.map +1 -0
  150. package/dist/cost/providers/claude-code.d.ts +9 -2
  151. package/dist/cost/providers/claude-code.d.ts.map +1 -1
  152. package/dist/cost/providers/claude-code.js +10 -5
  153. package/dist/cost/providers/claude-code.js.map +1 -1
  154. package/dist/cost/providers/codex.d.ts +107 -0
  155. package/dist/cost/providers/codex.d.ts.map +1 -0
  156. package/dist/cost/providers/codex.js +283 -0
  157. package/dist/cost/providers/codex.js.map +1 -0
  158. package/dist/cost/providers/index.d.ts.map +1 -1
  159. package/dist/cost/providers/index.js +6 -0
  160. package/dist/cost/providers/index.js.map +1 -1
  161. package/dist/cost/rates.d.ts.map +1 -1
  162. package/dist/cost/rates.js +14 -0
  163. package/dist/cost/rates.js.map +1 -1
  164. package/dist/cost/report.d.ts +23 -1
  165. package/dist/cost/report.d.ts.map +1 -1
  166. package/dist/cost/report.js +26 -5
  167. package/dist/cost/report.js.map +1 -1
  168. package/dist/cost/sessions.d.ts +10 -1
  169. package/dist/cost/sessions.d.ts.map +1 -1
  170. package/dist/cost/sessions.js +10 -2
  171. package/dist/cost/sessions.js.map +1 -1
  172. package/dist/cost/sync.d.ts.map +1 -1
  173. package/dist/cost/sync.js +190 -5
  174. package/dist/cost/sync.js.map +1 -1
  175. package/dist/doctor/migrations/compliance-pack-drift.d.ts +62 -0
  176. package/dist/doctor/migrations/compliance-pack-drift.d.ts.map +1 -0
  177. package/dist/doctor/migrations/compliance-pack-drift.js +255 -0
  178. package/dist/doctor/migrations/compliance-pack-drift.js.map +1 -0
  179. package/dist/doctor/migrations/index.d.ts.map +1 -1
  180. package/dist/doctor/migrations/index.js +11 -0
  181. package/dist/doctor/migrations/index.js.map +1 -1
  182. package/dist/doctor/migrations/legacy-cost-hooks.d.ts.map +1 -1
  183. package/dist/doctor/migrations/legacy-cost-hooks.js +7 -4
  184. package/dist/doctor/migrations/legacy-cost-hooks.js.map +1 -1
  185. package/dist/doctor/migrations/missing-cost-shim.d.ts.map +1 -1
  186. package/dist/doctor/migrations/missing-cost-shim.js +5 -4
  187. package/dist/doctor/migrations/missing-cost-shim.js.map +1 -1
  188. package/dist/doctor/migrations/outdated-cost-hooks.d.ts.map +1 -1
  189. package/dist/doctor/migrations/outdated-cost-hooks.js +7 -4
  190. package/dist/doctor/migrations/outdated-cost-hooks.js.map +1 -1
  191. package/dist/doctor/runner.js +14 -0
  192. package/dist/doctor/runner.js.map +1 -1
  193. package/dist/doctor/types.d.ts +35 -3
  194. package/dist/doctor/types.d.ts.map +1 -1
  195. package/dist/menu/roster.d.ts.map +1 -1
  196. package/dist/menu/roster.js +5 -0
  197. package/dist/menu/roster.js.map +1 -1
  198. package/dist/metrics/report.d.ts.map +1 -1
  199. package/dist/metrics/report.js +11 -2
  200. package/dist/metrics/report.js.map +1 -1
  201. package/dist/review/findings-parser.d.ts +92 -0
  202. package/dist/review/findings-parser.d.ts.map +1 -0
  203. package/dist/review/findings-parser.js +196 -0
  204. package/dist/review/findings-parser.js.map +1 -0
  205. package/dist/setup/setup-compute.d.ts +10 -15
  206. package/dist/setup/setup-compute.d.ts.map +1 -1
  207. package/dist/setup/setup-compute.js +39 -0
  208. package/dist/setup/setup-compute.js.map +1 -1
  209. package/package.json +2 -2
@@ -0,0 +1,107 @@
1
+ /**
2
+ * codex cost provider: rollout JSONL parsing since a cursor.
3
+ *
4
+ * Rollouts live at `$CODEX_HOME/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl`,
5
+ * defaulting to `~/.codex`. `CODEX_HOME` is a real user-facing variable — it is
6
+ * what `codex-rs/rollout/src/config.rs` reads — so hardcoding `~/.codex` would
7
+ * give every user who moves it `detect() === false` and silent zero capture.
8
+ * `ProviderEnv.home` stays a *test* override and is a different thing.
9
+ *
10
+ * Three properties of the format drive everything here, all measured against real
11
+ * rollouts rather than inferred:
12
+ *
13
+ * 1. **Two token blocks per record.** Each `token_count` event carries both
14
+ * `total_token_usage` (cumulative for the session) and `last_token_usage` (that
15
+ * turn). Only the latter may be summed: the former overcounts 2.86x on real
16
+ * data, and `total == input + output` holds for *both*, so an invariant test
17
+ * alone cannot tell you which was read.
18
+ * 2. **The counters overlap.** `cached_input_tokens` is *inside* `input_tokens`
19
+ * and `reasoning_output_tokens` is *inside* `output_tokens` — the inverse of
20
+ * Anthropic's shape, where the four counters are disjoint and the claude-code
21
+ * provider maps them straight through. Mapping Codex straight through prices
22
+ * cached input twice: 206,483 input-side tokens against a true 122,167 on one
23
+ * observed turn.
24
+ * 3. **No record carries an id.** A `token_count` line has only `payload`,
25
+ * `timestamp`, `type`; its payload only `info`, `rate_limits`, `type`. The
26
+ * claude-code provider resumes on a transcript entry's `uuid` and there is no
27
+ * equivalent, so the cursor is synthesised — see CURSOR below.
28
+ *
29
+ * `model` and `cwd` are not on the usage record either. Both are carried forward
30
+ * from the most recent preceding `turn_context` / `session_meta` line, because one
31
+ * of those covers many usage records (measured: one `turn_context` covering five).
32
+ *
33
+ * Requirements: agent-portability/AC-14, AC-15, AC-17, AC-50, AC-54, AC-55
34
+ * Design: design.md A4
35
+ *
36
+ * @module
37
+ */
38
+ import type { UsageSegment, TokenUnits } from '../types.js';
39
+ import type { CostProvider, ProviderEnv } from './provider.js';
40
+ /** Root directory that rollouts must live under (AC-14, AC-17). */
41
+ export declare function sessionsRoot(env: ProviderEnv): string;
42
+ /** The per-turn token block, as Codex writes it. */
43
+ interface LastTokenUsage {
44
+ input_tokens: number;
45
+ cached_input_tokens: number;
46
+ cache_write_input_tokens: number;
47
+ output_tokens: number;
48
+ reasoning_output_tokens: number;
49
+ total_tokens: number;
50
+ }
51
+ /**
52
+ * Map Codex's overlapping counters onto the ledger's disjoint ones (AC-15).
53
+ *
54
+ * The subtraction is the whole point. `cached_input_tokens` and
55
+ * `cache_write_input_tokens` are already inside `input_tokens`, and cached input
56
+ * is around two thirds of observed Codex input — so a straight-through mapping
57
+ * bills it once at the full input rate and again at the cache-read rate.
58
+ * `reasoning_output_tokens` is inside `output_tokens` and is therefore *not*
59
+ * added; adding it double-counts reasoning.
60
+ *
61
+ * Clamped at zero rather than trusted: the containment relation is measured, not
62
+ * guaranteed by the format, and a negative token count would flow into money.
63
+ */
64
+ export declare function mapUnits(last: LastTokenUsage, model: string): TokenUnits;
65
+ /**
66
+ * Does this record satisfy the identity the mapping rests on? (AC-55, NFR-6)
67
+ *
68
+ * `total == input + output` is what establishes that cached and reasoning tokens
69
+ * are *inside* those two figures. If it ever stops holding, the de-overlap above
70
+ * is wrong and every Codex figure is wrong with it. This is the detector NFR-6's
71
+ * re-derivation trigger needed in order to be able to fire at all —
72
+ * `cache_write_input_tokens` was 0 in all 12 observed records, so nothing else
73
+ * would notice it becoming non-zero.
74
+ */
75
+ export declare function usageIdentityHolds(last: LastTokenUsage): boolean;
76
+ /**
77
+ * CURSOR: `<rollout-basename>#<ordinal>`.
78
+ *
79
+ * Codex records carry no id, so there is nothing to resume *on*. Rollout files
80
+ * are append-only, which makes a record's ordinal within its file stable across
81
+ * re-reads, and the basename identifies the file without leaking an absolute path
82
+ * into the ledger.
83
+ *
84
+ * Crucially this names **the record**, not the session. A `session_id`-keyed
85
+ * duplicate check once passed 1,752 tests on this project while producing 4,388
86
+ * phantom records, because the ledger's id and the transcript's were two names for
87
+ * the same work. A cursor that identifies the record is checkable across sessions.
88
+ */
89
+ export declare function codexCursor(path: string, ordinal: number): string;
90
+ /** Git identity of a directory, for repository scoping. Null when it has none. */
91
+ type IdentityOf = (cwd: string) => string | null;
92
+ export declare const codexProvider: CostProvider;
93
+ /**
94
+ * Stream a rollout into usage segments.
95
+ *
96
+ * One pass, carrying three pieces of context forward: `model` from the most recent
97
+ * `turn_context`, `cwd` from the most recent `session_meta`, and the ordinal used
98
+ * for the cursor. Fail-soft throughout — a line that does not match the expected
99
+ * shape is skipped, never fatal, because the format is internal to Codex.
100
+ *
101
+ * `identityOf` enables per-segment repository scoping (AC-50). It is injected so
102
+ * the scoping can be tested without a git repository, and passing `null` disables
103
+ * scoping for callers that have already scoped by file.
104
+ */
105
+ export declare function extractFrom(path: string, since: string | null, env: ProviderEnv, identityOf: IdentityOf | null, onIdentityMismatch?: (reason: string) => void): Promise<UsageSegment[]>;
106
+ export {};
107
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/cost/providers/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAMH,OAAO,KAAK,EAAyC,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEnG,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG/D,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAOrD;AAMD,oDAAoD;AACpD,UAAU,cAAc;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB;AAwBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAUxE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAEhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjE;AAWD,kFAAkF;AAClF,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,YA+C3B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,UAAU,GAAG,IAAI,EAC7B,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAC5C,OAAO,CAAC,YAAY,EAAE,CAAC,CAuFzB"}
@@ -0,0 +1,283 @@
1
+ /**
2
+ * codex cost provider: rollout JSONL parsing since a cursor.
3
+ *
4
+ * Rollouts live at `$CODEX_HOME/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl`,
5
+ * defaulting to `~/.codex`. `CODEX_HOME` is a real user-facing variable — it is
6
+ * what `codex-rs/rollout/src/config.rs` reads — so hardcoding `~/.codex` would
7
+ * give every user who moves it `detect() === false` and silent zero capture.
8
+ * `ProviderEnv.home` stays a *test* override and is a different thing.
9
+ *
10
+ * Three properties of the format drive everything here, all measured against real
11
+ * rollouts rather than inferred:
12
+ *
13
+ * 1. **Two token blocks per record.** Each `token_count` event carries both
14
+ * `total_token_usage` (cumulative for the session) and `last_token_usage` (that
15
+ * turn). Only the latter may be summed: the former overcounts 2.86x on real
16
+ * data, and `total == input + output` holds for *both*, so an invariant test
17
+ * alone cannot tell you which was read.
18
+ * 2. **The counters overlap.** `cached_input_tokens` is *inside* `input_tokens`
19
+ * and `reasoning_output_tokens` is *inside* `output_tokens` — the inverse of
20
+ * Anthropic's shape, where the four counters are disjoint and the claude-code
21
+ * provider maps them straight through. Mapping Codex straight through prices
22
+ * cached input twice: 206,483 input-side tokens against a true 122,167 on one
23
+ * observed turn.
24
+ * 3. **No record carries an id.** A `token_count` line has only `payload`,
25
+ * `timestamp`, `type`; its payload only `info`, `rate_limits`, `type`. The
26
+ * claude-code provider resumes on a transcript entry's `uuid` and there is no
27
+ * equivalent, so the cursor is synthesised — see CURSOR below.
28
+ *
29
+ * `model` and `cwd` are not on the usage record either. Both are carried forward
30
+ * from the most recent preceding `turn_context` / `session_meta` line, because one
31
+ * of those covers many usage records (measured: one `turn_context` covering five).
32
+ *
33
+ * Requirements: agent-portability/AC-14, AC-15, AC-17, AC-50, AC-54, AC-55
34
+ * Design: design.md A4
35
+ *
36
+ * @module
37
+ */
38
+ import { createReadStream, existsSync, realpathSync } from 'node:fs';
39
+ import { createInterface } from 'node:readline';
40
+ import { homedir } from 'node:os';
41
+ import { basename, join, resolve } from 'node:path';
42
+ import { SESSION_ID_RE, MODEL_ID_RE } from '../types.js';
43
+ import { isWithin } from '../../core/paths.js';
44
+ /** Root directory that rollouts must live under (AC-14, AC-17). */
45
+ export function sessionsRoot(env) {
46
+ const codexHome = process.env.CODEX_HOME;
47
+ const base = codexHome !== undefined && codexHome.trim() !== ''
48
+ ? codexHome
49
+ : join(env.home ?? homedir(), '.codex');
50
+ return join(base, 'sessions');
51
+ }
52
+ function isCount(v) {
53
+ return typeof v === 'number' && Number.isFinite(v) && v >= 0;
54
+ }
55
+ function readLastUsage(v) {
56
+ if (typeof v !== 'object' || v === null)
57
+ return null;
58
+ const r = v;
59
+ // `cache_write_input_tokens` and `reasoning_output_tokens` carry serde defaults
60
+ // upstream, so an absent field is 0 rather than malformed.
61
+ const input = r.input_tokens;
62
+ const output = r.output_tokens;
63
+ const total = r.total_tokens;
64
+ if (!isCount(input) || !isCount(output) || !isCount(total))
65
+ return null;
66
+ const cached = isCount(r.cached_input_tokens) ? r.cached_input_tokens : 0;
67
+ const cacheWrite = isCount(r.cache_write_input_tokens) ? r.cache_write_input_tokens : 0;
68
+ const reasoning = isCount(r.reasoning_output_tokens) ? r.reasoning_output_tokens : 0;
69
+ return {
70
+ input_tokens: input,
71
+ cached_input_tokens: cached,
72
+ cache_write_input_tokens: cacheWrite,
73
+ output_tokens: output,
74
+ reasoning_output_tokens: reasoning,
75
+ total_tokens: total,
76
+ };
77
+ }
78
+ /**
79
+ * Map Codex's overlapping counters onto the ledger's disjoint ones (AC-15).
80
+ *
81
+ * The subtraction is the whole point. `cached_input_tokens` and
82
+ * `cache_write_input_tokens` are already inside `input_tokens`, and cached input
83
+ * is around two thirds of observed Codex input — so a straight-through mapping
84
+ * bills it once at the full input rate and again at the cache-read rate.
85
+ * `reasoning_output_tokens` is inside `output_tokens` and is therefore *not*
86
+ * added; adding it double-counts reasoning.
87
+ *
88
+ * Clamped at zero rather than trusted: the containment relation is measured, not
89
+ * guaranteed by the format, and a negative token count would flow into money.
90
+ */
91
+ export function mapUnits(last, model) {
92
+ const uncached = last.input_tokens - last.cached_input_tokens - last.cache_write_input_tokens;
93
+ return {
94
+ kind: 'tokens',
95
+ model,
96
+ input_tokens: Math.max(0, uncached),
97
+ output_tokens: last.output_tokens,
98
+ cache_read_tokens: last.cached_input_tokens,
99
+ cache_write_tokens: last.cache_write_input_tokens,
100
+ };
101
+ }
102
+ /**
103
+ * Does this record satisfy the identity the mapping rests on? (AC-55, NFR-6)
104
+ *
105
+ * `total == input + output` is what establishes that cached and reasoning tokens
106
+ * are *inside* those two figures. If it ever stops holding, the de-overlap above
107
+ * is wrong and every Codex figure is wrong with it. This is the detector NFR-6's
108
+ * re-derivation trigger needed in order to be able to fire at all —
109
+ * `cache_write_input_tokens` was 0 in all 12 observed records, so nothing else
110
+ * would notice it becoming non-zero.
111
+ */
112
+ export function usageIdentityHolds(last) {
113
+ return last.total_tokens === last.input_tokens + last.output_tokens;
114
+ }
115
+ /**
116
+ * CURSOR: `<rollout-basename>#<ordinal>`.
117
+ *
118
+ * Codex records carry no id, so there is nothing to resume *on*. Rollout files
119
+ * are append-only, which makes a record's ordinal within its file stable across
120
+ * re-reads, and the basename identifies the file without leaking an absolute path
121
+ * into the ledger.
122
+ *
123
+ * Crucially this names **the record**, not the session. A `session_id`-keyed
124
+ * duplicate check once passed 1,752 tests on this project while producing 4,388
125
+ * phantom records, because the ledger's id and the transcript's were two names for
126
+ * the same work. A cursor that identifies the record is checkable across sessions.
127
+ */
128
+ export function codexCursor(path, ordinal) {
129
+ return `${basename(path)}#${ordinal}`;
130
+ }
131
+ /** Ordinal already consumed, from a cursor of ours. Unrecognised → start over. */
132
+ function consumedFrom(since) {
133
+ if (since === null)
134
+ return 0;
135
+ const hash = since.lastIndexOf('#');
136
+ if (hash === -1)
137
+ return 0;
138
+ const n = Number(since.slice(hash + 1));
139
+ return Number.isInteger(n) && n >= 0 ? n : 0;
140
+ }
141
+ export const codexProvider = {
142
+ name: 'codex',
143
+ detect(env) {
144
+ return existsSync(sessionsRoot(env));
145
+ },
146
+ resolveSource(input, env) {
147
+ if (!SESSION_ID_RE.test(input.session_id))
148
+ return { ok: false, reason: 'invalid-input' };
149
+ // A null or absent path is `invalid-input`, NOT `source-missing`. The benign
150
+ // codes are suppressed by `lastCaptureError`, so mapping this to a benign miss
151
+ // would let total capture failure print nothing while hook status still read
152
+ // `installed` — the 41-hour blackout shape. The claude-code provider makes the
153
+ // same choice on the same input.
154
+ if (input.transcript_path === undefined || input.transcript_path === null) {
155
+ return { ok: false, reason: 'invalid-input' };
156
+ }
157
+ const requested = resolve(input.transcript_path);
158
+ // Bounds before existence, always. Checking whether the root exists first once
159
+ // let an out-of-bounds path fall through to the benign branch, turning an error
160
+ // code into an existence oracle for files outside the root.
161
+ const rawRoot = sessionsRoot(env);
162
+ let realRoot = null;
163
+ try {
164
+ realRoot = realpathSync(rawRoot);
165
+ }
166
+ catch {
167
+ realRoot = null;
168
+ }
169
+ const inBounds = isWithin(rawRoot, requested) || (realRoot !== null && isWithin(realRoot, requested));
170
+ if (!inBounds)
171
+ return { ok: false, reason: 'invalid-input' };
172
+ // A rollout is a .jsonl file. A directory, the session index, or anything else
173
+ // under the root is a rejection rather than a benign miss.
174
+ if (!requested.endsWith('.jsonl'))
175
+ return { ok: false, reason: 'invalid-input' };
176
+ if (basename(requested) === 'session_index.jsonl')
177
+ return { ok: false, reason: 'invalid-input' };
178
+ if (!existsSync(requested))
179
+ return { ok: false, reason: 'source-missing' };
180
+ return { ok: true, source: { provider: 'codex', path: requested } };
181
+ },
182
+ async extract(source, since, env) {
183
+ return extractFrom(source.path, since, env, null);
184
+ },
185
+ };
186
+ /**
187
+ * Stream a rollout into usage segments.
188
+ *
189
+ * One pass, carrying three pieces of context forward: `model` from the most recent
190
+ * `turn_context`, `cwd` from the most recent `session_meta`, and the ordinal used
191
+ * for the cursor. Fail-soft throughout — a line that does not match the expected
192
+ * shape is skipped, never fatal, because the format is internal to Codex.
193
+ *
194
+ * `identityOf` enables per-segment repository scoping (AC-50). It is injected so
195
+ * the scoping can be tested without a git repository, and passing `null` disables
196
+ * scoping for callers that have already scoped by file.
197
+ */
198
+ export async function extractFrom(path, since, env, identityOf, onIdentityMismatch) {
199
+ const consumed = consumedFrom(since);
200
+ const here = identityOf === null ? null : identityOf(env.projectRoot);
201
+ const segments = [];
202
+ let model = null;
203
+ let cwd = null;
204
+ let ordinal = 0;
205
+ const rl = createInterface({
206
+ input: createReadStream(path, { encoding: 'utf8' }),
207
+ crlfDelay: Infinity,
208
+ });
209
+ for await (const line of rl) {
210
+ const t = line.trim();
211
+ if (t === '')
212
+ continue;
213
+ let rec;
214
+ try {
215
+ rec = JSON.parse(t);
216
+ }
217
+ catch {
218
+ continue;
219
+ }
220
+ const payload = (rec.payload ?? {});
221
+ const kind = typeof payload.type === 'string' ? payload.type : rec.type;
222
+ if (kind === 'session_meta') {
223
+ const c = payload.cwd ?? (payload.payload ?? {}).cwd;
224
+ if (typeof c === 'string')
225
+ cwd = c;
226
+ continue;
227
+ }
228
+ if (kind === 'turn_context') {
229
+ if (typeof payload.model === 'string')
230
+ model = payload.model;
231
+ // turn_context carries cwd too; session_meta is preferred because it is the
232
+ // record that anchors a segment, but this keeps a rollout usable when the
233
+ // meta line is absent from the tail we are reading.
234
+ if (cwd === null && typeof payload.cwd === 'string')
235
+ cwd = payload.cwd;
236
+ continue;
237
+ }
238
+ if (kind !== 'token_count')
239
+ continue;
240
+ ordinal++;
241
+ if (ordinal <= consumed)
242
+ continue;
243
+ const info = (payload.info ?? {});
244
+ const last = readLastUsage(info.last_token_usage);
245
+ if (last === null)
246
+ continue;
247
+ // The identity that justifies the de-overlap. Reported, not silently skipped:
248
+ // a systematic parser failure must be visible (AC-55).
249
+ if (!usageIdentityHolds(last)) {
250
+ onIdentityMismatch?.(`${basename(path)}#${ordinal}: total_tokens ${last.total_tokens} != input ${last.input_tokens} + output ${last.output_tokens}`);
251
+ continue;
252
+ }
253
+ // Per-segment repository scoping (AC-50). The comparison is the git common
254
+ // dir, with path equality only when neither side has a git identity — that
255
+ // fallback is what makes worktrees count as this repository, and three are
256
+ // live on this repo. A segment we cannot place is skipped: under-recovering is
257
+ // the safe direction, because a wrong total is indistinguishable from truth.
258
+ if (identityOf !== null) {
259
+ if (cwd === null)
260
+ continue;
261
+ const theirs = identityOf(cwd);
262
+ const same = here !== null && theirs !== null ? here === theirs : resolve(cwd) === resolve(env.projectRoot);
263
+ if (!same)
264
+ continue;
265
+ }
266
+ if (model === null || !MODEL_ID_RE.test(model))
267
+ continue;
268
+ const at = typeof rec.timestamp === 'string' ? rec.timestamp : null;
269
+ if (at === null || Number.isNaN(Date.parse(at)))
270
+ continue;
271
+ segments.push({
272
+ at,
273
+ units: mapUnits(last, model),
274
+ cursor: codexCursor(path, ordinal),
275
+ // Codex gives no parent chain, so there is no interval to report. Null
276
+ // rather than a zero-width span: a missing span must not read as zero
277
+ // active time.
278
+ span: null,
279
+ });
280
+ }
281
+ return segments;
282
+ }
283
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/cost/providers/codex.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cost/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,qFAAqF;AACrF,wBAAgB,wBAAwB,IAAI,IAAI,CAK/C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cost/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,qFAAqF;AACrF,wBAAgB,wBAAwB,IAAI,IAAI,CAU/C"}
@@ -11,6 +11,7 @@
11
11
  import { registerProvider } from './provider.js';
12
12
  import { claudeCodeProvider } from './claude-code.js';
13
13
  import { kiroProvider } from './kiro.js';
14
+ import { codexProvider } from './codex.js';
14
15
  let registered = false;
15
16
  /** Register the bundled providers. Idempotent; safe to call from any entry point. */
16
17
  export function registerBuiltinProviders() {
@@ -19,5 +20,10 @@ export function registerBuiltinProviders() {
19
20
  registered = true;
20
21
  registerProvider(claudeCodeProvider);
21
22
  registerProvider(kiroProvider);
23
+ // Registered only after the hook registry (T23) and pin-narrowed sync selection
24
+ // (T34) landed: registration alone would otherwise have made `aidlc cost
25
+ // providers` print Kiro's hook status labelled `codex`, and widened sync's
26
+ // candidate set for every unknown-agent session.
27
+ registerProvider(codexProvider);
22
28
  }
23
29
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cost/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB,qFAAqF;AACrF,MAAM,UAAU,wBAAwB;IACtC,IAAI,UAAU;QAAE,OAAO;IACvB,UAAU,GAAG,IAAI,CAAC;IAClB,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IACrC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cost/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB,qFAAqF;AACrF,MAAM,UAAU,wBAAwB;IACtC,IAAI,UAAU;QAAE,OAAO;IACvB,UAAU,GAAG,IAAI,CAAC;IAClB,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IACrC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC/B,gFAAgF;IAChF,yEAAyE;IACzE,2EAA2E;IAC3E,iDAAiD;IACjD,gBAAgB,CAAC,aAAa,CAAC,CAAC;AAClC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"rates.d.ts","sourceRoot":"","sources":["../../src/cost/rates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAOjF,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAQvG,CAAC;AAEF,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CActD;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAwBD,wBAAgB,WAAW,IAAI,YAAY,CAE1C;AAaD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,cAAc,CAiB7F;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAiBjF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAcD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CA4DvG"}
1
+ {"version":3,"file":"rates.d.ts","sourceRoot":"","sources":["../../src/cost/rates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAOjF,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAWvG,CAAC;AAEF,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CActD;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAwBD,wBAAgB,WAAW,IAAI,YAAY,CAE1C;AAaD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,cAAc,CAiB7F;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CA0BjF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAcD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CA4DvG"}
@@ -18,6 +18,9 @@ const FETCH_SIZE_CAP = 5 * 1024 * 1024;
18
18
  export const NORMALIZATION_RULES = [
19
19
  { kind: 'prefix', pattern: /^(us|eu|apac|global)\./, describe: 'strip region prefix (us./eu./apac./global.)' },
20
20
  { kind: 'prefix', pattern: /^anthropic\./, describe: 'strip anthropic. prefix' },
21
+ // Codex reports `openai.<model>` (observed: openai.gpt-5.4) with
22
+ // model_provider "amazon-bedrock" (agent-portability/AC-40).
23
+ { kind: 'prefix', pattern: /^openai\./, describe: 'strip openai. prefix' },
21
24
  { kind: 'prefix', pattern: /^aws\//, describe: 'strip aws/ prefix' },
22
25
  { kind: 'prefix', pattern: /^bedrock\//, describe: 'strip bedrock/ prefix' },
23
26
  { kind: 'prefix', pattern: /^vertex_ai\//, describe: 'strip vertex_ai/ prefix' },
@@ -105,6 +108,17 @@ export function priceUnits(units, rates) {
105
108
  const r = entry.rate;
106
109
  if (r.input_per_mtok === undefined || r.output_per_mtok === undefined)
107
110
  return null;
111
+ // A missing cache rate must not price real cache tokens at zero.
112
+ // `?? 0` read as "this model has no cache pricing", which is true for some
113
+ // models and false for any whose rate entry is merely incomplete — and cached
114
+ // input is around two thirds of observed Codex input, so the difference is
115
+ // most of the bill. An entry that omits a rate for a class with non-zero
116
+ // tokens is an incomplete rate, and an incomplete rate is `null`: unpriced,
117
+ // visibly, rather than understated invisibly (agent-portability/AC-52).
118
+ if (units.cache_read_tokens > 0 && r.cache_read_per_mtok === undefined)
119
+ return null;
120
+ if (units.cache_write_tokens > 0 && r.cache_write_per_mtok === undefined)
121
+ return null;
108
122
  const micro = (units.input_tokens * r.input_per_mtok) +
109
123
  (units.output_tokens * r.output_per_mtok) +
110
124
  (units.cache_read_tokens * (r.cache_read_per_mtok ?? 0)) +
@@ -1 +1 @@
1
- {"version":3,"file":"rates.js","sourceRoot":"","sources":["../../src/cost/rates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rates.js","sourceRoot":"","sources":["../../src/cost/rates.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,18 @@ export interface InstanceCost {
44
44
  fidelityMix: Record<CostFidelity, number>;
45
45
  phases: PhaseCost[];
46
46
  snapshot: string;
47
+ /**
48
+ * Why this instance has no cost figure, when the reason is that two platforms
49
+ * worked it.
50
+ *
51
+ * Set here rather than in each printer so all five cost readers agree from one
52
+ * seam. Patching the printers alone would have left `aidlc metrics --json` and
53
+ * the published blog frontmatter carrying a figure that `aidlc cost` and
54
+ * `aidlc status` describe as unmeasured (agent-portability/AC-9, AC-11, AC-35).
55
+ */
56
+ costSkipped: {
57
+ platforms: string[];
58
+ } | null;
47
59
  }
48
60
  /** Compute the full cost view of one instance. */
49
61
  export declare function instanceCost(projectRoot: string, instance: string, config: CostConfig | null): InstanceCost;
@@ -51,8 +63,18 @@ export declare function instanceCost(projectRoot: string, instance: string, conf
51
63
  export declare function listInstances(projectRoot: string): string[];
52
64
  export interface TemplateRollup {
53
65
  template: string;
66
+ /** Instances in this group. */
54
67
  count: number;
55
- avgMicroUsd: number;
68
+ /**
69
+ * Instances in this group that have a cost figure.
70
+ *
71
+ * Reported beside the average so a group is never presented as complete when it
72
+ * is not. `measuredCount < count` means the average describes a subset, which is
73
+ * the honest reading — and `avgMicroUsd` is `null` when nothing is measured
74
+ * rather than a zero that reads as free.
75
+ */
76
+ measuredCount: number;
77
+ avgMicroUsd: number | null;
56
78
  avgElapsedSeconds: number;
57
79
  }
58
80
  export declare function byTemplate(projectRoot: string, config: CostConfig | null): TemplateRollup[];
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/cost/report.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;OAUG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gFAAgF;IAChF,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwGD,kDAAkD;AAClD,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,GAAG,IAAI,GACxB,YAAY,CA8Ed;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAO3D;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,cAAc,EAAE,CAoB3F;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAEpE"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/cost/report.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGtE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;OAUG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gFAAgF;IAChF,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,WAAW,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;CAC7C;AAwGD,kDAAkD;AAClD,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,GAAG,IAAI,GACxB,YAAY,CAqFd;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAO3D;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,cAAc,EAAE,CAkC3F;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAEpE"}
@@ -12,6 +12,7 @@ import { join } from 'node:path';
12
12
  import { loadYaml } from '../state/yaml-helpers.js';
13
13
  import { readEntries, applyPrecedence, ledgerPath, unattributedPath } from './ledger.js';
14
14
  import { priceUnits, effectiveRates } from './rates.js';
15
+ import { resolvePin } from './pin.js';
15
16
  function sumWeighted(weighted, rates) {
16
17
  let micro = 0;
17
18
  let anyPriced = false;
@@ -169,10 +170,16 @@ export function instanceCost(projectRoot, instance, config) {
169
170
  let totalElapsed = 0;
170
171
  for (const secs of elapsed.values())
171
172
  totalElapsed += secs;
173
+ // Two platforms worked this instance, so no single set of rates applies and any
174
+ // figure would be confidently wrong. Null with a stated reason, never a number
175
+ // and never a zero.
176
+ const pin = resolvePin(projectRoot, instance);
177
+ const costSkipped = pin.kind === 'skipped' ? { platforms: pin.platforms } : null;
172
178
  return {
173
179
  instance,
174
180
  template: instanceTemplate(projectRoot, instance),
175
- microUsd: total.microUsd,
181
+ microUsd: costSkipped !== null ? null : total.microUsd,
182
+ costSkipped,
176
183
  unpricedModels: [...total.unpriced],
177
184
  tokens: Math.round(total.tokens),
178
185
  credits: total.credits,
@@ -195,21 +202,35 @@ export function listInstances(projectRoot) {
195
202
  .sort();
196
203
  }
197
204
  export function byTemplate(projectRoot, config) {
205
+ // Members with no cost figure are counted but NOT averaged as zero.
206
+ //
207
+ // `?? 0` made an unmeasured instance look free, which drags every average down
208
+ // silently — 7 of 40 instances on this repo have no figure, across three of the
209
+ // four templates. Nulling the whole group instead would blank three rows of four,
210
+ // so the average is taken over the members that have a figure and the count of
211
+ // those members is reported beside it. Two other readers in this project already
212
+ // do exactly this, one marking `unpriced` and one `approximate`
213
+ // (agent-portability/AC-49).
198
214
  const groups = new Map();
199
215
  for (const name of listInstances(projectRoot)) {
200
216
  const cost = instanceCost(projectRoot, name, config);
201
217
  const template = cost.template ?? '(unknown)';
202
- const g = groups.get(template) ?? { micro: [], secs: [] };
203
- g.micro.push(cost.microUsd ?? 0);
218
+ const g = groups.get(template) ?? { micro: [], secs: [], total: 0 };
219
+ if (cost.microUsd !== null)
220
+ g.micro.push(cost.microUsd);
204
221
  g.secs.push(cost.elapsedSeconds);
222
+ g.total++;
205
223
  groups.set(template, g);
206
224
  }
207
225
  const out = [];
208
226
  for (const [template, g] of groups) {
209
227
  out.push({
210
228
  template,
211
- count: g.micro.length,
212
- avgMicroUsd: Math.round(g.micro.reduce((a, b) => a + b, 0) / g.micro.length),
229
+ count: g.total,
230
+ measuredCount: g.micro.length,
231
+ avgMicroUsd: g.micro.length === 0
232
+ ? null
233
+ : Math.round(g.micro.reduce((a, b) => a + b, 0) / g.micro.length),
213
234
  avgElapsedSeconds: Math.round(g.secs.reduce((a, b) => a + b, 0) / g.secs.length),
214
235
  });
215
236
  }