@rasensio/aidlc 1.2.0 → 1.3.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 (82) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cli.js +4 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/claim.d.ts +15 -0
  5. package/dist/commands/claim.d.ts.map +1 -0
  6. package/dist/commands/claim.js +122 -0
  7. package/dist/commands/claim.js.map +1 -0
  8. package/dist/commands/cost.d.ts +12 -0
  9. package/dist/commands/cost.d.ts.map +1 -0
  10. package/dist/commands/cost.js +409 -0
  11. package/dist/commands/cost.js.map +1 -0
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +38 -2
  14. package/dist/commands/init.js.map +1 -1
  15. package/dist/commands/status.d.ts.map +1 -1
  16. package/dist/commands/status.js +30 -1
  17. package/dist/commands/status.js.map +1 -1
  18. package/dist/commands/transition.js +9 -0
  19. package/dist/commands/transition.js.map +1 -1
  20. package/dist/core/types.d.ts +8 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/cost/config.d.ts +8 -0
  23. package/dist/cost/config.d.ts.map +1 -0
  24. package/dist/cost/config.js +37 -0
  25. package/dist/cost/config.js.map +1 -0
  26. package/dist/cost/hooks/claude-code.d.ts +29 -0
  27. package/dist/cost/hooks/claude-code.d.ts.map +1 -0
  28. package/dist/cost/hooks/claude-code.js +101 -0
  29. package/dist/cost/hooks/claude-code.js.map +1 -0
  30. package/dist/cost/hooks/kiro.d.ts +17 -0
  31. package/dist/cost/hooks/kiro.d.ts.map +1 -0
  32. package/dist/cost/hooks/kiro.js +66 -0
  33. package/dist/cost/hooks/kiro.js.map +1 -0
  34. package/dist/cost/ledger.d.ts +70 -0
  35. package/dist/cost/ledger.d.ts.map +1 -0
  36. package/dist/cost/ledger.js +314 -0
  37. package/dist/cost/ledger.js.map +1 -0
  38. package/dist/cost/providers/claude-code.d.ts +20 -0
  39. package/dist/cost/providers/claude-code.d.ts.map +1 -0
  40. package/dist/cost/providers/claude-code.js +116 -0
  41. package/dist/cost/providers/claude-code.js.map +1 -0
  42. package/dist/cost/providers/kiro.d.ts +19 -0
  43. package/dist/cost/providers/kiro.d.ts.map +1 -0
  44. package/dist/cost/providers/kiro.js +147 -0
  45. package/dist/cost/providers/kiro.js.map +1 -0
  46. package/dist/cost/providers/provider.d.ts +36 -0
  47. package/dist/cost/providers/provider.d.ts.map +1 -0
  48. package/dist/cost/providers/provider.js +21 -0
  49. package/dist/cost/providers/provider.js.map +1 -0
  50. package/dist/cost/rates-bundled.d.ts +11 -0
  51. package/dist/cost/rates-bundled.d.ts.map +1 -0
  52. package/dist/cost/rates-bundled.js +23 -0
  53. package/dist/cost/rates-bundled.js.map +1 -0
  54. package/dist/cost/rates.d.ts +42 -0
  55. package/dist/cost/rates.d.ts.map +1 -0
  56. package/dist/cost/rates.js +190 -0
  57. package/dist/cost/rates.js.map +1 -0
  58. package/dist/cost/recorder.d.ts +57 -0
  59. package/dist/cost/recorder.d.ts.map +1 -0
  60. package/dist/cost/recorder.js +339 -0
  61. package/dist/cost/recorder.js.map +1 -0
  62. package/dist/cost/report.d.ts +44 -0
  63. package/dist/cost/report.d.ts.map +1 -0
  64. package/dist/cost/report.js +164 -0
  65. package/dist/cost/report.js.map +1 -0
  66. package/dist/cost/sessions.d.ts +40 -0
  67. package/dist/cost/sessions.d.ts.map +1 -0
  68. package/dist/cost/sessions.js +200 -0
  69. package/dist/cost/sessions.js.map +1 -0
  70. package/dist/cost/sync.d.ts +24 -0
  71. package/dist/cost/sync.d.ts.map +1 -0
  72. package/dist/cost/sync.js +191 -0
  73. package/dist/cost/sync.js.map +1 -0
  74. package/dist/cost/types.d.ts +116 -0
  75. package/dist/cost/types.d.ts.map +1 -0
  76. package/dist/cost/types.js +13 -0
  77. package/dist/cost/types.js.map +1 -0
  78. package/dist/setup/setup-compute.d.ts +6 -0
  79. package/dist/setup/setup-compute.d.ts.map +1 -1
  80. package/dist/setup/setup-compute.js +3 -0
  81. package/dist/setup/setup-compute.js.map +1 -1
  82. package/package.json +11 -14
@@ -0,0 +1,147 @@
1
+ /**
2
+ * kiro cost provider: per-turn credit usage from local session files.
3
+ *
4
+ * Two on-disk shapes (both undocumented — fail-soft everywhere, D2):
5
+ * - IDE: ~/.kiro/sessions/<workspace-hash>/sess_<uuid>/messages.jsonl with
6
+ * usage_summary events: promptTurnSummaries[].usage (credits, fractional).
7
+ * session.json alongside carries workspacePaths for project matching.
8
+ * - CLI: ~/.kiro/sessions/cli/<uuid>.json with
9
+ * session_state.conversation_metadata.user_turn_metadatas[].metering_usage.
10
+ *
11
+ * Cursor: "<n>" — count of usage events already consumed from the file
12
+ * (files are append-only per session).
13
+ *
14
+ * Design: design.md §3, D2
15
+ */
16
+ import { readFileSync, existsSync, realpathSync } from 'node:fs';
17
+ import { homedir } from 'node:os';
18
+ import { join, resolve, sep } from 'node:path';
19
+ import { SESSION_ID_RE } from '../types.js';
20
+ export function kiroSessionsRoot(env) {
21
+ return join(env.home ?? homedir(), '.kiro', 'sessions');
22
+ }
23
+ function isCount(v) {
24
+ return typeof v === 'number' && Number.isFinite(v) && v >= 0;
25
+ }
26
+ /** Parse IDE messages.jsonl usage_summary events. Fail-soft per line. */
27
+ function parseIdeUsage(path) {
28
+ const events = [];
29
+ let raw;
30
+ try {
31
+ raw = readFileSync(path, 'utf8');
32
+ }
33
+ catch {
34
+ return events;
35
+ }
36
+ for (const line of raw.split('\n')) {
37
+ const t = line.trim();
38
+ if (t === '')
39
+ continue;
40
+ try {
41
+ const entry = JSON.parse(t);
42
+ if (entry.type !== 'usage_summary')
43
+ continue;
44
+ const at = typeof entry.timestamp === 'string' && !Number.isNaN(Date.parse(entry.timestamp))
45
+ ? entry.timestamp
46
+ : new Date(0).toISOString();
47
+ const summaries = entry.promptTurnSummaries;
48
+ if (!Array.isArray(summaries))
49
+ continue;
50
+ for (const s of summaries) {
51
+ const rec = s;
52
+ if (rec.unit === 'credit' && isCount(rec.usage)) {
53
+ events.push({ at, credits: rec.usage, model: null });
54
+ }
55
+ }
56
+ }
57
+ catch {
58
+ continue;
59
+ }
60
+ }
61
+ return events;
62
+ }
63
+ /** Parse CLI session JSON metering_usage entries. Fail-soft. */
64
+ function parseCliUsage(path) {
65
+ const events = [];
66
+ let root;
67
+ try {
68
+ root = JSON.parse(readFileSync(path, 'utf8'));
69
+ }
70
+ catch {
71
+ return events;
72
+ }
73
+ const state = root.session_state;
74
+ const meta = state?.conversation_metadata;
75
+ const turns = meta?.user_turn_metadatas;
76
+ if (!Array.isArray(turns))
77
+ return events;
78
+ for (const turn of turns) {
79
+ const t = turn;
80
+ const at = typeof t.end_timestamp === 'string' && !Number.isNaN(Date.parse(t.end_timestamp))
81
+ ? t.end_timestamp
82
+ : new Date(0).toISOString();
83
+ const model = typeof t.model === 'string' ? t.model : null;
84
+ const metering = t.metering_usage;
85
+ if (!Array.isArray(metering))
86
+ continue;
87
+ for (const m of metering) {
88
+ const rec = m;
89
+ if (rec.unit === 'credit' && isCount(rec.value)) {
90
+ events.push({ at, credits: rec.value, model });
91
+ }
92
+ }
93
+ }
94
+ return events;
95
+ }
96
+ export const kiroProvider = {
97
+ name: 'kiro',
98
+ detect(env) {
99
+ return existsSync(kiroSessionsRoot(env));
100
+ },
101
+ resolveSource(input, env) {
102
+ if (!SESSION_ID_RE.test(input.session_id))
103
+ return null;
104
+ const root = kiroSessionsRoot(env);
105
+ let realRoot;
106
+ try {
107
+ realRoot = realpathSync(root);
108
+ }
109
+ catch {
110
+ return null;
111
+ }
112
+ // CLI shape first: sessions/cli/<id>.json
113
+ const cliPath = join(realRoot, 'cli', `${input.session_id}.json`);
114
+ if (existsSync(cliPath)) {
115
+ return { provider: 'kiro', path: realpathSync(cliPath) };
116
+ }
117
+ // IDE shape: locate sess_<id> under a workspace-hash directory whose
118
+ // session.json workspacePaths includes the project root.
119
+ if (input.transcript_path) {
120
+ let real;
121
+ try {
122
+ real = realpathSync(resolve(input.transcript_path));
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ if (real !== realRoot && !real.startsWith(realRoot + sep))
128
+ return null;
129
+ return { provider: 'kiro', path: real };
130
+ }
131
+ return null;
132
+ },
133
+ async extract(source, since) {
134
+ const events = source.path.endsWith('.json')
135
+ ? parseCliUsage(source.path)
136
+ : parseIdeUsage(source.path);
137
+ const consumed = since !== null && /^\d+$/.test(since) ? Number(since) : 0;
138
+ const segments = [];
139
+ for (let i = consumed; i < events.length; i++) {
140
+ const e = events[i];
141
+ const units = { kind: 'credits', credits: e.credits, model: e.model };
142
+ segments.push({ at: e.at, units, cursor: String(i + 1) });
143
+ }
144
+ return segments;
145
+ },
146
+ };
147
+ //# sourceMappingURL=kiro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kiro.js","sourceRoot":"","sources":["../../../src/cost/providers/kiro.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Cost provider seam (FR3.1).
3
+ *
4
+ * A provider knows how to (a) detect its platform, (b) locate and validate
5
+ * its usage records for a session, and (c) extract usage segments since a
6
+ * cursor. Providers never touch ledgers or instances — attribution belongs
7
+ * to the recorder.
8
+ *
9
+ * Design: design.md §3
10
+ */
11
+ import type { RecordInput, SourceRef, UsageSegment } from '../types.js';
12
+ export interface ProviderEnv {
13
+ projectRoot: string;
14
+ /** Home directory override for tests. */
15
+ home?: string;
16
+ }
17
+ export interface CostProvider {
18
+ readonly name: string;
19
+ /** Is this platform present for the project/user? */
20
+ detect(env: ProviderEnv): boolean;
21
+ /**
22
+ * Validate hook input and resolve the usage-record source (FR3.9).
23
+ * Returns null (with a logged reason) when input is invalid or the
24
+ * source is outside the platform's known root.
25
+ */
26
+ resolveSource(input: RecordInput, env: ProviderEnv): SourceRef | null;
27
+ /**
28
+ * Extract usage segments after `since` (a cursor previously returned in
29
+ * a segment). Streaming and fail-soft: malformed records are skipped.
30
+ */
31
+ extract(source: SourceRef, since: string | null, env: ProviderEnv): Promise<UsageSegment[]>;
32
+ }
33
+ export declare function registerProvider(p: CostProvider): void;
34
+ export declare function getProvider(name: string): CostProvider | undefined;
35
+ export declare function allProviders(): CostProvider[];
36
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/cost/providers/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAExE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC;IAClC;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAAC;IACtE;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC7F;AAID,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI,CAEtD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAElE;AAED,wBAAgB,YAAY,IAAI,YAAY,EAAE,CAE7C"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Cost provider seam (FR3.1).
3
+ *
4
+ * A provider knows how to (a) detect its platform, (b) locate and validate
5
+ * its usage records for a session, and (c) extract usage segments since a
6
+ * cursor. Providers never touch ledgers or instances — attribution belongs
7
+ * to the recorder.
8
+ *
9
+ * Design: design.md §3
10
+ */
11
+ const registry = new Map();
12
+ export function registerProvider(p) {
13
+ registry.set(p.name, p);
14
+ }
15
+ export function getProvider(name) {
16
+ return registry.get(name);
17
+ }
18
+ export function allProviders() {
19
+ return [...registry.values()];
20
+ }
21
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/cost/providers/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2BH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEjD,MAAM,UAAU,gBAAgB,CAAC,CAAe;IAC9C,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Bundled rate table, versioned with the CLI (FR6.1).
3
+ *
4
+ * Anthropic list prices per MTok; kiro-credit at the standard overage rate.
5
+ * `aidlc cost rates update` refreshes token rates from the configured
6
+ * source; unit-priced entries (kiro-credit) have no public feed and are
7
+ * bundled/override only (D3).
8
+ */
9
+ import type { RateSnapshot } from './types.js';
10
+ export declare const BUNDLED_RATES: RateSnapshot;
11
+ //# sourceMappingURL=rates-bundled.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rates-bundled.d.ts","sourceRoot":"","sources":["../../src/cost/rates-bundled.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,eAAO,MAAM,aAAa,EAAE,YAa3B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Bundled rate table, versioned with the CLI (FR6.1).
3
+ *
4
+ * Anthropic list prices per MTok; kiro-credit at the standard overage rate.
5
+ * `aidlc cost rates update` refreshes token rates from the configured
6
+ * source; unit-priced entries (kiro-credit) have no public feed and are
7
+ * bundled/override only (D3).
8
+ */
9
+ export const BUNDLED_RATES = {
10
+ snapshot_version: 'bundled-2026-08-15',
11
+ effective_date: '2026-08-15',
12
+ rates: {
13
+ 'claude-fable-5': { input_per_mtok: 5.0, output_per_mtok: 25.0, cache_read_per_mtok: 0.5, cache_write_per_mtok: 6.25 },
14
+ 'claude-opus-5': { input_per_mtok: 5.0, output_per_mtok: 25.0, cache_read_per_mtok: 0.5, cache_write_per_mtok: 6.25 },
15
+ 'claude-opus-4-1': { input_per_mtok: 15.0, output_per_mtok: 75.0, cache_read_per_mtok: 1.5, cache_write_per_mtok: 18.75 },
16
+ 'claude-sonnet-5': { input_per_mtok: 3.0, output_per_mtok: 15.0, cache_read_per_mtok: 0.3, cache_write_per_mtok: 3.75 },
17
+ 'claude-sonnet-4-6': { input_per_mtok: 3.0, output_per_mtok: 15.0, cache_read_per_mtok: 0.3, cache_write_per_mtok: 3.75 },
18
+ 'claude-sonnet-4-5': { input_per_mtok: 3.0, output_per_mtok: 15.0, cache_read_per_mtok: 0.3, cache_write_per_mtok: 3.75 },
19
+ 'claude-haiku-4-5': { input_per_mtok: 1.0, output_per_mtok: 5.0, cache_read_per_mtok: 0.1, cache_write_per_mtok: 1.25 },
20
+ 'kiro-credit': { per_unit: 0.04 },
21
+ },
22
+ };
23
+ //# sourceMappingURL=rates-bundled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rates-bundled.js","sourceRoot":"","sources":["../../src/cost/rates-bundled.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,gBAAgB,EAAE,oBAAoB;IACtC,cAAc,EAAE,YAAY;IAC5B,KAAK,EAAE;QACL,gBAAgB,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE;QACtH,eAAe,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE;QACrH,iBAAiB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE;QACzH,iBAAiB,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE;QACvH,mBAAmB,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE;QACzH,mBAAmB,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE;QACzH,kBAAkB,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE;QACvH,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;KAClC;CACF,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Rate table: bundled defaults, on-demand cached updates, config overrides.
3
+ *
4
+ * Resolution precedence: config override > cached update > bundled (FR6.5).
5
+ * Model ids are normalized with a closed table-driven rule before lookup —
6
+ * additions are code changes with tests, never "etc.".
7
+ *
8
+ * Dollar math uses integer micro-dollars to avoid float drift (DD6).
9
+ *
10
+ * Design: design.md §4.5, D3
11
+ */
12
+ import type { RateEntry, RateSnapshot, CostConfig, CostUnits } from './types.js';
13
+ /** Normalization rule: applied in order; printed by `rates show --normalization`. */
14
+ export declare const NORMALIZATION_RULES: Array<{
15
+ kind: 'prefix' | 'suffix';
16
+ pattern: RegExp;
17
+ describe: string;
18
+ }>;
19
+ /** Normalize a raw model id for rate lookup (FR6.5). */
20
+ export declare function normalizeModelId(model: string): string;
21
+ export declare function cachedRatesPath(projectRoot: string): string;
22
+ export declare function loadBundled(): RateSnapshot;
23
+ export type RateOrigin = 'override' | 'cached' | 'bundled';
24
+ export interface EffectiveRates {
25
+ snapshot: string;
26
+ entries: Map<string, {
27
+ rate: RateEntry;
28
+ origin: RateOrigin;
29
+ }>;
30
+ }
31
+ /** Merge bundled < cached < overrides into the effective table. */
32
+ export declare function effectiveRates(projectRoot: string, config: CostConfig | null): EffectiveRates;
33
+ /** Cost of usage units in integer micro-dollars; null = unpriced. */
34
+ export declare function priceUnits(units: CostUnits, rates: EffectiveRates): number | null;
35
+ export declare function microToUsd(micro: number): string;
36
+ /**
37
+ * Fetch the LiteLLM pricing JSON and cache the models we know how to price.
38
+ * HTTPS only, redirects refused, 5MB cap, schema-validated, temp-then-rename.
39
+ * Throws with a user-safe message on any failure — callers keep the old table.
40
+ */
41
+ export declare function updateRates(projectRoot: string, config: CostConfig | null): Promise<RateSnapshot>;
42
+ //# sourceMappingURL=rates.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Rate table: bundled defaults, on-demand cached updates, config overrides.
3
+ *
4
+ * Resolution precedence: config override > cached update > bundled (FR6.5).
5
+ * Model ids are normalized with a closed table-driven rule before lookup —
6
+ * additions are code changes with tests, never "etc.".
7
+ *
8
+ * Dollar math uses integer micro-dollars to avoid float drift (DD6).
9
+ *
10
+ * Design: design.md §4.5, D3
11
+ */
12
+ import { readFileSync, writeFileSync, renameSync, mkdirSync, existsSync } from 'node:fs';
13
+ import { dirname, join } from 'node:path';
14
+ import { BUNDLED_RATES } from './rates-bundled.js';
15
+ const DEFAULT_RATES_URL = 'https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json';
16
+ const FETCH_SIZE_CAP = 5 * 1024 * 1024;
17
+ /** Normalization rule: applied in order; printed by `rates show --normalization`. */
18
+ export const NORMALIZATION_RULES = [
19
+ { kind: 'prefix', pattern: /^(us|eu|apac|global)\./, describe: 'strip region prefix (us./eu./apac./global.)' },
20
+ { kind: 'prefix', pattern: /^anthropic\./, describe: 'strip anthropic. prefix' },
21
+ { kind: 'prefix', pattern: /^aws\//, describe: 'strip aws/ prefix' },
22
+ { kind: 'prefix', pattern: /^bedrock\//, describe: 'strip bedrock/ prefix' },
23
+ { kind: 'prefix', pattern: /^vertex_ai\//, describe: 'strip vertex_ai/ prefix' },
24
+ { kind: 'suffix', pattern: /-v\d+(:\d+)?$/, describe: 'strip -vN / -vN:M version suffix' },
25
+ { kind: 'suffix', pattern: /@\d{8}$/, describe: 'strip @YYYYMMDD suffix' },
26
+ ];
27
+ /** Normalize a raw model id for rate lookup (FR6.5). */
28
+ export function normalizeModelId(model) {
29
+ let m = model.toLowerCase();
30
+ let changed = true;
31
+ while (changed) {
32
+ changed = false;
33
+ for (const rule of NORMALIZATION_RULES) {
34
+ const next = m.replace(rule.pattern, '');
35
+ if (next !== m) {
36
+ m = next;
37
+ changed = true;
38
+ }
39
+ }
40
+ }
41
+ return m;
42
+ }
43
+ export function cachedRatesPath(projectRoot) {
44
+ return join(projectRoot, '.aidlc', 'cost', 'rates.json');
45
+ }
46
+ function isRateEntry(v) {
47
+ if (typeof v !== 'object' || v === null)
48
+ return false;
49
+ const allowed = new Set([
50
+ 'input_per_mtok', 'output_per_mtok', 'cache_read_per_mtok', 'cache_write_per_mtok', 'per_unit',
51
+ ]);
52
+ return Object.entries(v).every(([k, val]) => allowed.has(k) && typeof val === 'number' && Number.isFinite(val) && val >= 0);
53
+ }
54
+ function validateSnapshot(data) {
55
+ if (typeof data !== 'object' || data === null)
56
+ return false;
57
+ const s = data;
58
+ return (typeof s.snapshot_version === 'string' &&
59
+ typeof s.effective_date === 'string' &&
60
+ typeof s.rates === 'object' &&
61
+ s.rates !== null &&
62
+ Object.values(s.rates).every(isRateEntry));
63
+ }
64
+ export function loadBundled() {
65
+ return BUNDLED_RATES;
66
+ }
67
+ function loadCached(projectRoot) {
68
+ const p = cachedRatesPath(projectRoot);
69
+ if (!existsSync(p))
70
+ return null;
71
+ try {
72
+ const parsed = JSON.parse(readFileSync(p, 'utf8'));
73
+ return validateSnapshot(parsed) ? parsed : null;
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ /** Merge bundled < cached < overrides into the effective table. */
80
+ export function effectiveRates(projectRoot, config) {
81
+ const bundled = loadBundled();
82
+ const cached = loadCached(projectRoot);
83
+ const entries = new Map();
84
+ for (const [model, rate] of Object.entries(bundled.rates)) {
85
+ entries.set(model, { rate, origin: 'bundled' });
86
+ }
87
+ if (cached) {
88
+ for (const [model, rate] of Object.entries(cached.rates)) {
89
+ entries.set(model, { rate, origin: 'cached' });
90
+ }
91
+ }
92
+ for (const [model, rate] of Object.entries(config?.rates ?? {})) {
93
+ if (isRateEntry(rate))
94
+ entries.set(normalizeModelId(model), { rate, origin: 'override' });
95
+ }
96
+ const snapshot = cached ? cached.snapshot_version : bundled.snapshot_version;
97
+ return { snapshot: config?.rates ? `${snapshot}+overrides` : snapshot, entries };
98
+ }
99
+ /** Cost of usage units in integer micro-dollars; null = unpriced. */
100
+ export function priceUnits(units, rates) {
101
+ if (units.kind === 'tokens') {
102
+ const entry = rates.entries.get(normalizeModelId(units.model));
103
+ if (!entry)
104
+ return null;
105
+ const r = entry.rate;
106
+ if (r.input_per_mtok === undefined || r.output_per_mtok === undefined)
107
+ return null;
108
+ const micro = (units.input_tokens * r.input_per_mtok) +
109
+ (units.output_tokens * r.output_per_mtok) +
110
+ (units.cache_read_tokens * (r.cache_read_per_mtok ?? 0)) +
111
+ (units.cache_write_tokens * (r.cache_write_per_mtok ?? 0));
112
+ // rate is $/MTok → micro-dollars = tokens * rate ($/MTok) * 1e6 / 1e6.
113
+ return Math.round(micro);
114
+ }
115
+ const entry = rates.entries.get('kiro-credit');
116
+ if (!entry || entry.rate.per_unit === undefined)
117
+ return null;
118
+ return Math.round(units.credits * entry.rate.per_unit * 1_000_000);
119
+ }
120
+ export function microToUsd(micro) {
121
+ return `$${(micro / 1_000_000).toFixed(2)}`;
122
+ }
123
+ /**
124
+ * Fetch the LiteLLM pricing JSON and cache the models we know how to price.
125
+ * HTTPS only, redirects refused, 5MB cap, schema-validated, temp-then-rename.
126
+ * Throws with a user-safe message on any failure — callers keep the old table.
127
+ */
128
+ export async function updateRates(projectRoot, config) {
129
+ const url = config?.rates_url ?? DEFAULT_RATES_URL;
130
+ if (!url.startsWith('https://'))
131
+ throw new Error('rates_url must be https://');
132
+ const res = await fetch(url, { redirect: 'error' });
133
+ if (!res.ok)
134
+ throw new Error(`rate source returned ${res.status}`);
135
+ const text = await res.text();
136
+ if (text.length > FETCH_SIZE_CAP)
137
+ throw new Error('rate source exceeds size cap');
138
+ let raw;
139
+ try {
140
+ raw = JSON.parse(text);
141
+ }
142
+ catch {
143
+ throw new Error('rate source is not valid JSON');
144
+ }
145
+ const bundled = loadBundled();
146
+ const rates = {};
147
+ // Extract only models present in the bundled table (extract-known-only, DD7):
148
+ // upstream keys are matched post-normalization.
149
+ const wanted = new Set(Object.keys(bundled.rates));
150
+ for (const [key, value] of Object.entries(raw)) {
151
+ const norm = normalizeModelId(key);
152
+ if (!wanted.has(norm))
153
+ continue;
154
+ const e = value;
155
+ if (typeof e.input_cost_per_token !== 'number' || typeof e.output_cost_per_token !== 'number')
156
+ continue;
157
+ const entry = {
158
+ input_per_mtok: e.input_cost_per_token * 1_000_000,
159
+ output_per_mtok: e.output_cost_per_token * 1_000_000,
160
+ };
161
+ if (typeof e.cache_read_input_token_cost === 'number') {
162
+ entry.cache_read_per_mtok = e.cache_read_input_token_cost * 1_000_000;
163
+ }
164
+ if (typeof e.cache_creation_input_token_cost === 'number') {
165
+ entry.cache_write_per_mtok = e.cache_creation_input_token_cost * 1_000_000;
166
+ }
167
+ if (isRateEntry(entry))
168
+ rates[norm] = entry;
169
+ }
170
+ if (Object.keys(rates).length === 0) {
171
+ throw new Error('rate source contained no known models');
172
+ }
173
+ // Unit-priced entries (kiro-credit) have no public feed — carry from bundled.
174
+ for (const [model, rate] of Object.entries(bundled.rates)) {
175
+ if (rate.per_unit !== undefined && !(model in rates))
176
+ rates[model] = rate;
177
+ }
178
+ const snapshot = {
179
+ snapshot_version: `litellm-${new Date().toISOString().slice(0, 10)}`,
180
+ effective_date: new Date().toISOString().slice(0, 10),
181
+ rates,
182
+ };
183
+ const target = cachedRatesPath(projectRoot);
184
+ mkdirSync(dirname(target), { recursive: true });
185
+ const tmp = target + '.tmp';
186
+ writeFileSync(tmp, JSON.stringify(snapshot, null, 2) + '\n');
187
+ renameSync(tmp, target);
188
+ return snapshot;
189
+ }
190
+ //# sourceMappingURL=rates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rates.js","sourceRoot":"","sources":["../../src/cost/rates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Cost recorder: orchestrates capture from provider extraction to ledger
3
+ * appends. Owns all attribution — providers stay platform-pure (DD3).
4
+ *
5
+ * Flow (design §4.1): validate input → acquire per-session lock → read
6
+ * newest cursor (instance ledgers + unattributed) → provider.extract →
7
+ * split segments by claim intervals × phase transitions → merge per
8
+ * (instance, phase, model) → validate + append. The ledger append is the
9
+ * atomic commit point (DD1); re-runs after a crash re-extract from the
10
+ * last committed cursor.
11
+ *
12
+ * Failures append structured lines to .aidlc/cost/capture.log — never raw
13
+ * transcript or ledger content (SR1).
14
+ */
15
+ import { type ProviderEnv } from './providers/provider.js';
16
+ import type { RecordInput } from './types.js';
17
+ export declare function captureLogPath(projectRoot: string): string;
18
+ export declare function logCapture(projectRoot: string, stage: string, errorCode: string, counts?: Record<string, number>): void;
19
+ /** Most recent capture-log line, for surfacing in `aidlc cost` (FR3.10). */
20
+ export declare function lastCaptureError(projectRoot: string): {
21
+ timestamp: string;
22
+ stage: string;
23
+ error_code: string;
24
+ } | null;
25
+ /** Try to take the per-session lock. Returns a release fn, or null if held. */
26
+ export declare function acquireLock(projectRoot: string, sessionId: string): (() => void) | null;
27
+ interface PhaseWindow {
28
+ phase: string;
29
+ from: number;
30
+ /** Exclusive upper bound; Infinity for the current phase. */
31
+ to: number;
32
+ }
33
+ /** Build phase windows for an instance from its transitions.log. */
34
+ export declare function phaseWindows(projectRoot: string, instance: string, initialPhase: string): PhaseWindow[];
35
+ /** All instances that have session events mentioning this session. */
36
+ export declare function instancesForSession(projectRoot: string, sessionId: string): string[];
37
+ export interface RecordResult {
38
+ appended: number;
39
+ unattributed: number;
40
+ instances: string[];
41
+ }
42
+ export interface RecordOptions {
43
+ projectRoot: string;
44
+ provider: string;
45
+ input: RecordInput;
46
+ claimTimeoutMinutes: number;
47
+ env?: ProviderEnv;
48
+ now?: Date;
49
+ }
50
+ /**
51
+ * Run one capture pass for a session. Returns counts, or null when the
52
+ * lock is held elsewhere (the holder re-checks before releasing, so a
53
+ * firing lost to the lock is still captured — design §4.2).
54
+ */
55
+ export declare function recordUsage(opts: RecordOptions): Promise<RecordResult | null>;
56
+ export {};
57
+ //# sourceMappingURL=recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/cost/recorder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAoBH,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS9C,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,UAAU,CACxB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,IAAI,CA+BN;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAarH;AAUD,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAqCvF;AAMD,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,WAAW,EAAE,CAiBvG;AASD,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CASpF;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkCnF"}