@swarmdo/cli 1.29.0 → 1.37.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 (169) hide show
  1. package/.claude/helpers/auto-memory-hook.mjs +65 -32
  2. package/README.md +6 -3
  3. package/dist/src/affected/affected.d.ts +6 -1
  4. package/dist/src/affected/affected.d.ts.map +1 -1
  5. package/dist/src/affected/affected.js +7 -2
  6. package/dist/src/affected/affected.js.map +1 -1
  7. package/dist/src/apply/apply.d.ts.map +1 -1
  8. package/dist/src/apply/apply.js +18 -7
  9. package/dist/src/apply/apply.js.map +1 -1
  10. package/dist/src/changelog/changelog.d.ts.map +1 -1
  11. package/dist/src/changelog/changelog.js +4 -1
  12. package/dist/src/changelog/changelog.js.map +1 -1
  13. package/dist/src/codegraph/codegraph.d.ts.map +1 -1
  14. package/dist/src/codegraph/codegraph.js +11 -1
  15. package/dist/src/codegraph/codegraph.js.map +1 -1
  16. package/dist/src/commands/comms.d.ts +16 -0
  17. package/dist/src/commands/comms.d.ts.map +1 -0
  18. package/dist/src/commands/comms.js +280 -0
  19. package/dist/src/commands/comms.js.map +1 -0
  20. package/dist/src/commands/compact.d.ts.map +1 -1
  21. package/dist/src/commands/compact.js +6 -2
  22. package/dist/src/commands/compact.js.map +1 -1
  23. package/dist/src/commands/config.d.ts.map +1 -1
  24. package/dist/src/commands/config.js +1 -0
  25. package/dist/src/commands/config.js.map +1 -1
  26. package/dist/src/commands/hooks.d.ts.map +1 -1
  27. package/dist/src/commands/hooks.js +121 -1
  28. package/dist/src/commands/hooks.js.map +1 -1
  29. package/dist/src/commands/hotspots.d.ts.map +1 -1
  30. package/dist/src/commands/hotspots.js +8 -2
  31. package/dist/src/commands/hotspots.js.map +1 -1
  32. package/dist/src/commands/index.d.ts.map +1 -1
  33. package/dist/src/commands/index.js +6 -0
  34. package/dist/src/commands/index.js.map +1 -1
  35. package/dist/src/commands/permissions.d.ts +14 -0
  36. package/dist/src/commands/permissions.d.ts.map +1 -0
  37. package/dist/src/commands/permissions.js +92 -0
  38. package/dist/src/commands/permissions.js.map +1 -0
  39. package/dist/src/commands/usage.d.ts.map +1 -1
  40. package/dist/src/commands/usage.js +208 -3
  41. package/dist/src/commands/usage.js.map +1 -1
  42. package/dist/src/comms/mailbox.d.ts +88 -0
  43. package/dist/src/comms/mailbox.d.ts.map +1 -0
  44. package/dist/src/comms/mailbox.js +138 -0
  45. package/dist/src/comms/mailbox.js.map +1 -0
  46. package/dist/src/comms/store.d.ts +21 -0
  47. package/dist/src/comms/store.d.ts.map +1 -0
  48. package/dist/src/comms/store.js +44 -0
  49. package/dist/src/comms/store.js.map +1 -0
  50. package/dist/src/compact/compact.d.ts.map +1 -1
  51. package/dist/src/compact/compact.js +4 -1
  52. package/dist/src/compact/compact.js.map +1 -1
  53. package/dist/src/compact-snapshot/compact-snapshot.d.ts.map +1 -1
  54. package/dist/src/compact-snapshot/compact-snapshot.js +8 -3
  55. package/dist/src/compact-snapshot/compact-snapshot.js.map +1 -1
  56. package/dist/src/config-lint/lint.d.ts +3 -1
  57. package/dist/src/config-lint/lint.d.ts.map +1 -1
  58. package/dist/src/config-lint/lint.js +11 -4
  59. package/dist/src/config-lint/lint.js.map +1 -1
  60. package/dist/src/env/env.d.ts.map +1 -1
  61. package/dist/src/env/env.js +40 -14
  62. package/dist/src/env/env.js.map +1 -1
  63. package/dist/src/hooks-recipe/recipe.d.ts.map +1 -1
  64. package/dist/src/hooks-recipe/recipe.js +20 -1
  65. package/dist/src/hooks-recipe/recipe.js.map +1 -1
  66. package/dist/src/hotspots/hotspots.d.ts +3 -0
  67. package/dist/src/hotspots/hotspots.d.ts.map +1 -1
  68. package/dist/src/hotspots/hotspots.js +9 -0
  69. package/dist/src/hotspots/hotspots.js.map +1 -1
  70. package/dist/src/index.d.ts.map +1 -1
  71. package/dist/src/index.js +8 -0
  72. package/dist/src/index.js.map +1 -1
  73. package/dist/src/license/license.d.ts.map +1 -1
  74. package/dist/src/license/license.js +4 -1
  75. package/dist/src/license/license.js.map +1 -1
  76. package/dist/src/mcp-client.d.ts.map +1 -1
  77. package/dist/src/mcp-client.js +2 -0
  78. package/dist/src/mcp-client.js.map +1 -1
  79. package/dist/src/mcp-tools/comms-tools.d.ts +11 -0
  80. package/dist/src/mcp-tools/comms-tools.d.ts.map +1 -0
  81. package/dist/src/mcp-tools/comms-tools.js +93 -0
  82. package/dist/src/mcp-tools/comms-tools.js.map +1 -0
  83. package/dist/src/mcp-tools/index.d.ts +1 -0
  84. package/dist/src/mcp-tools/index.d.ts.map +1 -1
  85. package/dist/src/mcp-tools/index.js +1 -0
  86. package/dist/src/mcp-tools/index.js.map +1 -1
  87. package/dist/src/mcp-tools/task-tools.d.ts.map +1 -1
  88. package/dist/src/mcp-tools/task-tools.js +4 -0
  89. package/dist/src/mcp-tools/task-tools.js.map +1 -1
  90. package/dist/src/memory/memory-bridge.d.ts +2 -0
  91. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  92. package/dist/src/memory/memory-bridge.js +4 -2
  93. package/dist/src/memory/memory-bridge.js.map +1 -1
  94. package/dist/src/memory-inject/select.d.ts +82 -0
  95. package/dist/src/memory-inject/select.d.ts.map +1 -0
  96. package/dist/src/memory-inject/select.js +164 -0
  97. package/dist/src/memory-inject/select.js.map +1 -0
  98. package/dist/src/memory-vault/import.d.ts.map +1 -1
  99. package/dist/src/memory-vault/import.js +11 -1
  100. package/dist/src/memory-vault/import.js.map +1 -1
  101. package/dist/src/pack/pack.d.ts.map +1 -1
  102. package/dist/src/pack/pack.js +6 -2
  103. package/dist/src/pack/pack.js.map +1 -1
  104. package/dist/src/permissions/audit.d.ts +50 -0
  105. package/dist/src/permissions/audit.d.ts.map +1 -0
  106. package/dist/src/permissions/audit.js +127 -0
  107. package/dist/src/permissions/audit.js.map +1 -0
  108. package/dist/src/plugins/store/search.js +1 -1
  109. package/dist/src/plugins/store/search.js.map +1 -1
  110. package/dist/src/redact/redact.d.ts.map +1 -1
  111. package/dist/src/redact/redact.js +7 -2
  112. package/dist/src/redact/redact.js.map +1 -1
  113. package/dist/src/release/release.js +1 -1
  114. package/dist/src/release/release.js.map +1 -1
  115. package/dist/src/sbom/sbom.d.ts +2 -0
  116. package/dist/src/sbom/sbom.d.ts.map +1 -1
  117. package/dist/src/sbom/sbom.js +5 -0
  118. package/dist/src/sbom/sbom.js.map +1 -1
  119. package/dist/src/swarmvector/semantic-router.d.ts.map +1 -1
  120. package/dist/src/swarmvector/semantic-router.js +8 -3
  121. package/dist/src/swarmvector/semantic-router.js.map +1 -1
  122. package/dist/src/testreport/testreport.d.ts.map +1 -1
  123. package/dist/src/testreport/testreport.js +9 -2
  124. package/dist/src/testreport/testreport.js.map +1 -1
  125. package/dist/src/transcript/export.d.ts.map +1 -1
  126. package/dist/src/transcript/export.js +8 -4
  127. package/dist/src/transcript/export.js.map +1 -1
  128. package/dist/src/update/checker.d.ts +1 -0
  129. package/dist/src/update/checker.d.ts.map +1 -1
  130. package/dist/src/update/checker.js +7 -2
  131. package/dist/src/update/checker.js.map +1 -1
  132. package/dist/src/usage/limits.d.ts +77 -0
  133. package/dist/src/usage/limits.d.ts.map +1 -0
  134. package/dist/src/usage/limits.js +134 -0
  135. package/dist/src/usage/limits.js.map +1 -0
  136. package/dist/src/usage/model-efficiency.d.ts +29 -0
  137. package/dist/src/usage/model-efficiency.d.ts.map +1 -0
  138. package/dist/src/usage/model-efficiency.js +28 -0
  139. package/dist/src/usage/model-efficiency.js.map +1 -0
  140. package/dist/src/usage/reflect-html.d.ts +23 -0
  141. package/dist/src/usage/reflect-html.d.ts.map +1 -0
  142. package/dist/src/usage/reflect-html.js +95 -0
  143. package/dist/src/usage/reflect-html.js.map +1 -0
  144. package/dist/src/usage/reflect.d.ts +131 -0
  145. package/dist/src/usage/reflect.d.ts.map +1 -0
  146. package/dist/src/usage/reflect.js +209 -0
  147. package/dist/src/usage/reflect.js.map +1 -0
  148. package/dist/src/usage/spend-forecast.d.ts +28 -0
  149. package/dist/src/usage/spend-forecast.d.ts.map +1 -0
  150. package/dist/src/usage/spend-forecast.js +33 -0
  151. package/dist/src/usage/spend-forecast.js.map +1 -0
  152. package/dist/src/usage/transcript-errors.d.ts +14 -0
  153. package/dist/src/usage/transcript-errors.d.ts.map +1 -1
  154. package/dist/src/usage/transcript-errors.js +10 -0
  155. package/dist/src/usage/transcript-errors.js.map +1 -1
  156. package/dist/src/usage/transcript-usage.d.ts +8 -1
  157. package/dist/src/usage/transcript-usage.d.ts.map +1 -1
  158. package/dist/src/usage/transcript-usage.js +21 -1
  159. package/dist/src/usage/transcript-usage.js.map +1 -1
  160. package/dist/src/util/csv.d.ts +14 -0
  161. package/dist/src/util/csv.d.ts.map +1 -0
  162. package/dist/src/util/csv.js +20 -0
  163. package/dist/src/util/csv.js.map +1 -0
  164. package/dist/src/util/stdout.d.ts +23 -1
  165. package/dist/src/util/stdout.d.ts.map +1 -1
  166. package/dist/src/util/stdout.js +34 -2
  167. package/dist/src/util/stdout.js.map +1 -1
  168. package/dist/tsconfig.tsbuildinfo +1 -1
  169. package/package.json +1 -1
@@ -0,0 +1,95 @@
1
+ /**
2
+ * reflect-html.ts — render a Reflection (see reflect.ts) into a self-contained,
3
+ * shareable HTML dashboard for `swarmdo usage reflect --html`.
4
+ *
5
+ * Pure + deterministic: it takes an already-computed Reflection and returns a
6
+ * complete HTML document string with all CSS inlined (no external requests, no
7
+ * clock — any timestamp is passed in), so it unit-tests without a browser or a
8
+ * network. Every user-controlled string (model ids, project paths) is HTML-
9
+ * escaped. See #47.
10
+ */
11
+ /** HTML-escape a string for safe interpolation into text or attributes. */
12
+ export function escapeHtml(s) {
13
+ return String(s).replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
14
+ }
15
+ const usd = (n) => `$${n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
16
+ const num = (n) => n.toLocaleString('en-US');
17
+ const pct = (x) => `${Math.round(x * 100)}%`;
18
+ /** A labelled proportional bar (width is % of the largest value in its group). */
19
+ function bar(label, valueText, fillPct) {
20
+ const w = Math.max(0, Math.min(100, fillPct));
21
+ return `<div class="bar"><div class="bar-label" title="${escapeHtml(label)}">${escapeHtml(label)}</div>`
22
+ + `<div class="bar-track"><div class="bar-fill" style="width:${w.toFixed(1)}%"></div></div>`
23
+ + `<div class="bar-val">${escapeHtml(valueText)}</div></div>`;
24
+ }
25
+ function shareBars(rows) {
26
+ if (!rows.length)
27
+ return '<p class="empty">—</p>';
28
+ const max = Math.max(...rows.map((r) => r.costUsd), 0) || 1;
29
+ return rows.map((r) => bar(r.model, `${usd(r.costUsd)} · ${pct(r.pct)}`, (r.costUsd / max) * 100)).join('');
30
+ }
31
+ function hourBars(hist) {
32
+ if (!hist.some((v) => v > 0))
33
+ return '<p class="empty">—</p>';
34
+ const max = Math.max(...hist) || 1;
35
+ const cells = hist.map((v, h) => {
36
+ const hpct = (v / max) * 100;
37
+ return `<div class="hour" title="${String(h).padStart(2, '0')}:00 — ${usd(v)}">`
38
+ + `<div class="hour-bar" style="height:${hpct.toFixed(1)}%"></div>`
39
+ + `<div class="hour-tick">${h % 6 === 0 ? String(h).padStart(2, '0') : ''}</div></div>`;
40
+ }).join('');
41
+ return `<div class="hours">${cells}</div>`;
42
+ }
43
+ function stat(label, value) {
44
+ return `<div class="stat"><div class="stat-val">${escapeHtml(value)}</div><div class="stat-label">${escapeHtml(label)}</div></div>`;
45
+ }
46
+ /** Render the retrospective to a complete self-contained HTML document. Pure. */
47
+ export function renderReflectionHtml(r, opts = {}) {
48
+ const arrow = r.trend.direction === 'up' ? '↑' : r.trend.direction === 'down' ? '↓' : '→';
49
+ const peak = r.peakHour ? `${String(r.peakHour.hour).padStart(2, '0')}:00` : '—';
50
+ const busiest = r.busiestDay ? `${r.busiestDay.day} (${usd(r.busiestDay.costUsd)})` : '—';
51
+ const gen = opts.generatedAt ? `<p class="gen">generated ${escapeHtml(opts.generatedAt)}</p>` : '';
52
+ return `<!doctype html>
53
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
54
+ <title>Claude Code Reflect — ${escapeHtml(r.period.from)}..${escapeHtml(r.period.to)}</title>
55
+ <style>
56
+ :root{--bg:#0f1117;--card:#181b24;--fg:#e6e8ee;--muted:#8b90a0;--accent:#7c9cff;--track:#262a36}
57
+ *{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--fg);font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;padding:32px}
58
+ .wrap{max-width:840px;margin:0 auto}
59
+ h1{font-size:22px;margin:0 0 2px}.sub{color:var(--muted);margin:0 0 24px}.gen{color:var(--muted);font-size:12px;margin:24px 0 0}
60
+ .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:28px}
61
+ .stat{background:var(--card);border-radius:12px;padding:16px}
62
+ .stat-val{font-size:22px;font-weight:600}.stat-label{color:var(--muted);font-size:12px;margin-top:4px}
63
+ h2{font-size:14px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:28px 0 12px}
64
+ .bar{display:grid;grid-template-columns:minmax(0,1fr) 3fr minmax(0,auto);align-items:center;gap:10px;margin:6px 0}
65
+ .bar-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}
66
+ .bar-track{background:var(--track);border-radius:6px;height:14px;overflow:hidden}
67
+ .bar-fill{background:var(--accent);height:100%;border-radius:6px}
68
+ .bar-val{font-size:12px;color:var(--muted);white-space:nowrap}
69
+ .hours{display:flex;align-items:flex-end;gap:3px;height:90px}
70
+ .hour{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;height:100%}
71
+ .hour-bar{width:100%;background:var(--accent);border-radius:3px 3px 0 0;min-height:1px}
72
+ .hour-tick{font-size:9px;color:var(--muted);margin-top:4px;height:12px}
73
+ .empty{color:var(--muted)}
74
+ </style></head><body><div class="wrap">
75
+ <h1>Claude Code Reflect ${escapeHtml(arrow)}</h1>
76
+ <p class="sub">${escapeHtml(r.period.from)} .. ${escapeHtml(r.period.to)} · ${r.period.spanDays} days · ${r.totals.activeDays} active</p>
77
+ <div class="grid">
78
+ ${stat('Total spend', usd(r.totals.costUsd))}
79
+ ${stat('Total tokens', num(r.totals.totalTokens))}
80
+ ${stat('Avg / active day', usd(r.avgCostPerActiveDay))}
81
+ ${stat('Longest streak', `${r.longestStreak} day${r.longestStreak === 1 ? '' : 's'}`)}
82
+ ${stat('Peak hour', peak)}
83
+ ${stat('Cache read', pct(r.cacheReadPct))}
84
+ ${r.cacheSavingsUsd > 0 ? stat('Cache saved', usd(r.cacheSavingsUsd)) : ''}
85
+ ${stat('Busiest day', busiest)}
86
+ ${stat('Trend', `${arrow} ${pct(r.trend.firstHalfCost > 0 ? (r.trend.secondHalfCost - r.trend.firstHalfCost) / r.trend.firstHalfCost : 0)}`)}
87
+ ${opts.delegation && opts.delegation.toolCalls > 0 ? stat('Delegation', pct(opts.delegation.ratio)) : ''}
88
+ </div>
89
+ <h2>Cost by hour of day</h2>${hourBars(r.hourHistogram)}
90
+ <h2>Top models</h2>${shareBars(r.topModels)}
91
+ <h2>Top projects</h2>${shareBars(r.topProjects)}
92
+ ${gen}
93
+ </div></body></html>`;
94
+ }
95
+ //# sourceMappingURL=reflect-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflect-html.js","sourceRoot":"","sources":["../../../src/usage/reflect-html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * reflect.ts — a "wrapped"-style retrospective over Claude Code usage.
3
+ *
4
+ * Anthropic's Reflect (2026-07-09) summarizes claude.ai *chats*; it doesn't
5
+ * touch Claude Code terminal work. swarmdo already parses the local transcripts
6
+ * for `usage daily/monthly/blocks/errors/cache`, so this is the retrospective
7
+ * layer on top: fold the existing per-day and per-(model,day) aggregation rows
8
+ * into headline stats — totals, the busiest day, the top models, the longest
9
+ * active-day streak, the cost trend, and cache efficiency.
10
+ *
11
+ * Pure + deterministic: it takes already-aggregated rows (no transcripts, no
12
+ * clock — the period bounds are passed in), so the whole thing is unit-tested
13
+ * without touching disk. The command layer in ../commands/usage.ts feeds it the
14
+ * rows the parser already produces. See #47.
15
+ */
16
+ import type { DayRow, ModelRow } from './diff.js';
17
+ import { type TranscriptModelPrice } from './claude-pricing.js';
18
+ export interface ModelShare {
19
+ model: string;
20
+ costUsd: number;
21
+ totalTokens: number;
22
+ /** share of total cost, 0..1 (0 when the period cost is 0) */
23
+ pct: number;
24
+ }
25
+ export interface ReflectionTotals {
26
+ costUsd: number;
27
+ totalTokens: number;
28
+ inputTokens: number;
29
+ outputTokens: number;
30
+ cacheReadTokens: number;
31
+ cacheWriteTokens: number;
32
+ entries: number;
33
+ /** days in [from,to] with any token activity */
34
+ activeDays: number;
35
+ }
36
+ export interface Reflection {
37
+ period: {
38
+ from: string;
39
+ to: string; /** inclusive calendar span in days */
40
+ spanDays: number;
41
+ };
42
+ totals: ReflectionTotals;
43
+ /** highest-cost active day in the period, or null if the period is empty */
44
+ busiestDay: {
45
+ day: string;
46
+ costUsd: number;
47
+ totalTokens: number;
48
+ } | null;
49
+ /** active days whose cost is an outlier vs the median (possible runaways) */
50
+ spikeDays: SpikeDay[];
51
+ /** models ranked by cost desc (capped to opts.topModels) */
52
+ topModels: ModelShare[];
53
+ /** projects ranked by cost desc (ModelShare.model holds the project path) */
54
+ topProjects: ModelShare[];
55
+ /** busiest local hour-of-day by cost (0..23), or null if no activity */
56
+ peakHour: {
57
+ hour: number;
58
+ value: number;
59
+ } | null;
60
+ /** cost per local hour-of-day, as supplied by the caller (length 24 when set) */
61
+ hourHistogram: number[];
62
+ /** longest run of consecutive active calendar days */
63
+ longestStreak: number;
64
+ /** cacheRead / (input + cacheWrite + cacheRead), 0..1 */
65
+ cacheReadPct: number;
66
+ /** total cost / active days (0 when no active days) */
67
+ avgCostPerActiveDay: number;
68
+ /** first-half vs second-half spend across the period */
69
+ trend: {
70
+ firstHalfCost: number;
71
+ secondHalfCost: number;
72
+ direction: 'up' | 'down' | 'flat';
73
+ };
74
+ /** $ prompt-caching saved this period (vs paying full input rate); 0 if no priced models */
75
+ cacheSavingsUsd: number;
76
+ }
77
+ export interface ReflectOptions {
78
+ /** how many models to keep in topModels (default 5) */
79
+ topModels?: number;
80
+ /** relative change below which the trend reads 'flat' (default 0.05 = 5%) */
81
+ flatThreshold?: number;
82
+ /** price resolver for cache-savings (injected for tests; default = the real table) */
83
+ resolvePrice?: (model: string) => TranscriptModelPrice | undefined;
84
+ }
85
+ /** The calendar day after an ISO date (handles month/year rollover). Pure. */
86
+ export declare function nextDay(iso: string): string;
87
+ /**
88
+ * The ISO date `n` whole months before `iso`, clamping the day to the target
89
+ * month's length so "Mar 31 − 1 month" is Feb 28/29 (not a rolled-over Mar 3).
90
+ * Pure. Used to derive a `--period 1m|3m|…` window start from today.
91
+ */
92
+ export declare function monthsBefore(iso: string, n: number): string;
93
+ /** Inclusive whole-day span between two ISO dates (from <= to). Pure. */
94
+ export declare function spanDays(from: string, to: string): number;
95
+ /** Longest run of consecutive calendar days present in the set. Pure. */
96
+ export declare function longestStreakOf(days: string[]): number;
97
+ export interface SpikeDay {
98
+ day: string;
99
+ costUsd: number;
100
+ /** costUsd / median active-day cost */
101
+ ratioToMedian: number;
102
+ }
103
+ /**
104
+ * Days whose cost is an outlier vs the median active-day cost — a heads-up for
105
+ * runaway sessions. Median (not mean) so the spikes don't inflate the baseline.
106
+ * Needs ≥3 active days for a meaningful median; a floor keeps trivially-cheap
107
+ * days from tripping the ratio. Sorted by cost desc. Pure.
108
+ */
109
+ export declare function detectSpikeDays(days: Array<{
110
+ day: string;
111
+ costUsd: number;
112
+ }>, opts?: {
113
+ minRatio?: number;
114
+ minCostUsd?: number;
115
+ }): SpikeDay[];
116
+ /** Render a numeric series as a Unicode block sparkline (one char per bucket).
117
+ * Zero buckets are blank; the rest scale ▁..█ against the max. Pure — used for
118
+ * the terminal cost-by-hour view (the HTML dashboard draws the same data). */
119
+ export declare function hourSparkline(hist: number[]): string;
120
+ /** Window + aggregate `{key, day, totals}` rows into cost-ranked shares. Pure.
121
+ * Reused for both models and projects (ModelShare.model carries whichever key). */
122
+ export declare function rankShares(rows: ModelRow[], from: string, to: string, totalCost: number, topN: number): ModelShare[];
123
+ /** Busiest bucket in a per-hour cost histogram (argmax; earliest hour wins ties),
124
+ * or null when every bucket is empty. Pure. */
125
+ export declare function peakHourOf(hourHistogram: number[]): {
126
+ hour: number;
127
+ value: number;
128
+ } | null;
129
+ /** Fold pre-aggregated usage rows into a retrospective. Pure. */
130
+ export declare function computeReflection(dayRows: DayRow[], modelRows: ModelRow[], from: string, to: string, opts?: ReflectOptions, projectRows?: ModelRow[], hourHistogram?: number[]): Reflection;
131
+ //# sourceMappingURL=reflect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflect.d.ts","sourceRoot":"","sources":["../../../src/usage/reflect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * reflect.ts — a "wrapped"-style retrospective over Claude Code usage.
3
+ *
4
+ * Anthropic's Reflect (2026-07-09) summarizes claude.ai *chats*; it doesn't
5
+ * touch Claude Code terminal work. swarmdo already parses the local transcripts
6
+ * for `usage daily/monthly/blocks/errors/cache`, so this is the retrospective
7
+ * layer on top: fold the existing per-day and per-(model,day) aggregation rows
8
+ * into headline stats — totals, the busiest day, the top models, the longest
9
+ * active-day streak, the cost trend, and cache efficiency.
10
+ *
11
+ * Pure + deterministic: it takes already-aggregated rows (no transcripts, no
12
+ * clock — the period bounds are passed in), so the whole thing is unit-tested
13
+ * without touching disk. The command layer in ../commands/usage.ts feeds it the
14
+ * rows the parser already produces. See #47.
15
+ */
16
+ import { modelCacheSavings } from './cache-stats.js';
17
+ import { resolveTranscriptPrice } from './claude-pricing.js';
18
+ const DATE = /^\d{4}-\d{2}-\d{2}$/;
19
+ /** The calendar day after an ISO date (handles month/year rollover). Pure. */
20
+ export function nextDay(iso) {
21
+ const [y, m, d] = iso.split('-').map(Number);
22
+ const dt = new Date(y, m - 1, d + 1);
23
+ const yy = dt.getFullYear();
24
+ const mm = String(dt.getMonth() + 1).padStart(2, '0');
25
+ const dd = String(dt.getDate()).padStart(2, '0');
26
+ return `${yy}-${mm}-${dd}`;
27
+ }
28
+ /**
29
+ * The ISO date `n` whole months before `iso`, clamping the day to the target
30
+ * month's length so "Mar 31 − 1 month" is Feb 28/29 (not a rolled-over Mar 3).
31
+ * Pure. Used to derive a `--period 1m|3m|…` window start from today.
32
+ */
33
+ export function monthsBefore(iso, n) {
34
+ const [y, m, d] = iso.split('-').map(Number);
35
+ const monthIndex = m - 1 - n; // may be negative — Date normalizes the year
36
+ const lastDay = new Date(y, monthIndex + 1, 0).getDate();
37
+ const dt = new Date(y, monthIndex, Math.min(d, lastDay));
38
+ const yy = dt.getFullYear();
39
+ const mm = String(dt.getMonth() + 1).padStart(2, '0');
40
+ const dd = String(dt.getDate()).padStart(2, '0');
41
+ return `${yy}-${mm}-${dd}`;
42
+ }
43
+ /** Inclusive whole-day span between two ISO dates (from <= to). Pure. */
44
+ export function spanDays(from, to) {
45
+ const a = new Date(from + 'T00:00:00');
46
+ const b = new Date(to + 'T00:00:00');
47
+ return Math.floor((b.getTime() - a.getTime()) / 86_400_000) + 1;
48
+ }
49
+ /** Longest run of consecutive calendar days present in the set. Pure. */
50
+ export function longestStreakOf(days) {
51
+ const uniq = [...new Set(days)].sort();
52
+ let best = 0;
53
+ let run = 0;
54
+ let prev = null;
55
+ for (const d of uniq) {
56
+ run = prev !== null && nextDay(prev) === d ? run + 1 : 1;
57
+ if (run > best)
58
+ best = run;
59
+ prev = d;
60
+ }
61
+ return best;
62
+ }
63
+ /**
64
+ * Days whose cost is an outlier vs the median active-day cost — a heads-up for
65
+ * runaway sessions. Median (not mean) so the spikes don't inflate the baseline.
66
+ * Needs ≥3 active days for a meaningful median; a floor keeps trivially-cheap
67
+ * days from tripping the ratio. Sorted by cost desc. Pure.
68
+ */
69
+ export function detectSpikeDays(days, opts = {}) {
70
+ const minRatio = opts.minRatio ?? 2.5;
71
+ const minCostUsd = opts.minCostUsd ?? 0.5;
72
+ const costs = days.map((d) => d.costUsd).filter((c) => c > 0).sort((a, b) => a - b);
73
+ if (costs.length < 3)
74
+ return [];
75
+ const mid = costs.length >> 1;
76
+ const median = costs.length % 2 ? costs[mid] : (costs[mid - 1] + costs[mid]) / 2;
77
+ if (median <= 0)
78
+ return [];
79
+ return days
80
+ .filter((d) => d.costUsd >= minCostUsd && d.costUsd >= minRatio * median)
81
+ .map((d) => ({ day: d.day, costUsd: d.costUsd, ratioToMedian: d.costUsd / median }))
82
+ .sort((a, b) => b.costUsd - a.costUsd);
83
+ }
84
+ const within = (key, from, to) => key >= from && key <= to;
85
+ const SPARK_BLOCKS = ' ▁▂▃▄▅▆▇█'; // index 0 = empty (zero), 1..8 = ▁..█ scaled to max
86
+ /** Render a numeric series as a Unicode block sparkline (one char per bucket).
87
+ * Zero buckets are blank; the rest scale ▁..█ against the max. Pure — used for
88
+ * the terminal cost-by-hour view (the HTML dashboard draws the same data). */
89
+ export function hourSparkline(hist) {
90
+ const max = Math.max(0, ...hist);
91
+ if (max <= 0)
92
+ return ' '.repeat(hist.length);
93
+ return hist.map((v) => SPARK_BLOCKS[v <= 0 ? 0 : Math.min(8, 1 + Math.floor((v / max) * 7))]).join('');
94
+ }
95
+ /** Window + aggregate `{key, day, totals}` rows into cost-ranked shares. Pure.
96
+ * Reused for both models and projects (ModelShare.model carries whichever key). */
97
+ export function rankShares(rows, from, to, totalCost, topN) {
98
+ const per = new Map();
99
+ for (const r of rows) {
100
+ if (!within(r.day, from, to))
101
+ continue;
102
+ const slot = per.get(r.key) ?? { costUsd: 0, totalTokens: 0 };
103
+ slot.costUsd += r.totals.costUsd;
104
+ slot.totalTokens += r.totals.totalTokens;
105
+ per.set(r.key, slot);
106
+ }
107
+ return [...per.entries()]
108
+ .map(([key, v]) => ({ model: key, costUsd: v.costUsd, totalTokens: v.totalTokens, pct: totalCost > 0 ? v.costUsd / totalCost : 0 }))
109
+ .filter((m) => m.costUsd > 0 || m.totalTokens > 0)
110
+ .sort((a, b) => b.costUsd - a.costUsd || b.totalTokens - a.totalTokens || (a.model < b.model ? -1 : 1))
111
+ .slice(0, topN);
112
+ }
113
+ /** Busiest bucket in a per-hour cost histogram (argmax; earliest hour wins ties),
114
+ * or null when every bucket is empty. Pure. */
115
+ export function peakHourOf(hourHistogram) {
116
+ let best = -1;
117
+ let bestVal = 0;
118
+ for (let h = 0; h < hourHistogram.length; h++) {
119
+ if (hourHistogram[h] > bestVal) {
120
+ bestVal = hourHistogram[h];
121
+ best = h;
122
+ }
123
+ }
124
+ return best < 0 ? null : { hour: best, value: bestVal };
125
+ }
126
+ /** Fold pre-aggregated usage rows into a retrospective. Pure. */
127
+ export function computeReflection(dayRows, modelRows, from, to, opts = {}, projectRows = [], hourHistogram = []) {
128
+ if (!DATE.test(from) || !DATE.test(to))
129
+ throw new Error(`bad period bounds: ${from}..${to}`);
130
+ if (from > to)
131
+ throw new Error(`period "${from}..${to}" is reversed (from > to)`);
132
+ const topN = opts.topModels ?? 5;
133
+ const flat = opts.flatThreshold ?? 0.05;
134
+ const days = dayRows.filter((r) => within(r.key, from, to));
135
+ const totals = {
136
+ costUsd: 0, totalTokens: 0, inputTokens: 0, outputTokens: 0,
137
+ cacheReadTokens: 0, cacheWriteTokens: 0, entries: 0, activeDays: 0,
138
+ };
139
+ let busiestDay = null;
140
+ const activeDayKeys = [];
141
+ const mid = spanDays(from, to) / 2;
142
+ let firstHalfCost = 0;
143
+ let secondHalfCost = 0;
144
+ for (const r of days) {
145
+ const t = r.totals;
146
+ totals.costUsd += t.costUsd;
147
+ totals.totalTokens += t.totalTokens;
148
+ totals.inputTokens += t.inputTokens;
149
+ totals.outputTokens += t.outputTokens;
150
+ totals.cacheReadTokens += t.cacheReadTokens;
151
+ totals.cacheWriteTokens += t.cacheWriteTokens;
152
+ if (t.totalTokens > 0) {
153
+ totals.activeDays += 1;
154
+ activeDayKeys.push(r.key);
155
+ }
156
+ if (!busiestDay || t.costUsd > busiestDay.costUsd) {
157
+ busiestDay = { day: r.key, costUsd: t.costUsd, totalTokens: t.totalTokens };
158
+ }
159
+ // Trend: which half of the period does this day fall in?
160
+ if (spanDays(from, r.key) <= mid)
161
+ firstHalfCost += t.costUsd;
162
+ else
163
+ secondHalfCost += t.costUsd;
164
+ }
165
+ // A period with zero active days has no meaningful busiest day.
166
+ if (totals.activeDays === 0)
167
+ busiestDay = null;
168
+ // Cost-ranked shares over the same window, for both models and projects.
169
+ const topModels = rankShares(modelRows, from, to, totals.costUsd, topN);
170
+ const topProjects = rankShares(projectRows, from, to, totals.costUsd, topN);
171
+ // $ saved by prompt caching this period: fold windowed per-model token counts,
172
+ // then price each via the (injected) resolver. Unpriced models contribute 0.
173
+ const resolvePrice = opts.resolvePrice ?? resolveTranscriptPrice;
174
+ const cacheTokens = new Map();
175
+ for (const r of modelRows) {
176
+ if (!within(r.day, from, to))
177
+ continue;
178
+ const s = cacheTokens.get(r.key) ?? { inputTokens: 0, cacheWriteTokens: 0, cacheReadTokens: 0 };
179
+ s.inputTokens += r.totals.inputTokens;
180
+ s.cacheWriteTokens += r.totals.cacheWriteTokens;
181
+ s.cacheReadTokens += r.totals.cacheReadTokens;
182
+ cacheTokens.set(r.key, s);
183
+ }
184
+ let cacheSavingsUsd = 0;
185
+ for (const [model, tok] of cacheTokens) {
186
+ const sv = modelCacheSavings(tok, resolvePrice(model));
187
+ if (sv !== null)
188
+ cacheSavingsUsd += sv;
189
+ }
190
+ const inputSide = totals.inputTokens + totals.cacheWriteTokens + totals.cacheReadTokens;
191
+ const relChange = firstHalfCost > 0 ? (secondHalfCost - firstHalfCost) / firstHalfCost : (secondHalfCost > 0 ? 1 : 0);
192
+ const direction = Math.abs(relChange) < flat ? 'flat' : relChange > 0 ? 'up' : 'down';
193
+ return {
194
+ period: { from, to, spanDays: spanDays(from, to) },
195
+ totals,
196
+ busiestDay,
197
+ spikeDays: detectSpikeDays(days.map((r) => ({ day: r.key, costUsd: r.totals.costUsd }))),
198
+ topModels,
199
+ topProjects,
200
+ peakHour: peakHourOf(hourHistogram),
201
+ hourHistogram,
202
+ longestStreak: longestStreakOf(activeDayKeys),
203
+ cacheReadPct: inputSide > 0 ? totals.cacheReadTokens / inputSide : 0,
204
+ avgCostPerActiveDay: totals.activeDays > 0 ? totals.costUsd / totals.activeDays : 0,
205
+ trend: { firstHalfCost, secondHalfCost, direction },
206
+ cacheSavingsUsd,
207
+ };
208
+ }
209
+ //# sourceMappingURL=reflect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflect.js","sourceRoot":"","sources":["../../../src/usage/reflect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAA6B,MAAM,qBAAqB,CAAC;AA0DxF,MAAM,IAAI,GAAG,qBAAqB,CAAC;AAEnC,8EAA8E;AAC9E,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,CAAS;IACjD,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,6CAA6C;IAC3E,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACzD,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7B,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,EAAU;IAC/C,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;AAClE,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,eAAe,CAAC,IAAc;IAC5C,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,GAAG,GAAG,IAAI;YAAE,IAAI,GAAG,GAAG,CAAC;QAC3B,IAAI,GAAG,CAAC,CAAC;IACX,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AASD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,IAA6C,EAC7C,OAAmD,EAAE;IAErD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;IACtC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACjF,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3B,OAAO,IAAI;SACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,UAAU,IAAI,CAAC,CAAC,OAAO,IAAI,QAAQ,GAAG,MAAM,CAAC;SACxE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC;SACnF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,IAAY,EAAE,EAAU,EAAW,EAAE,CAAC,GAAG,IAAI,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;AAE5F,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,oDAAoD;AAEtF;;8EAE8E;AAC9E,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACjC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzG,CAAC;AAED;mFACmF;AACnF,MAAM,UAAU,UAAU,CAAC,IAAgB,EAAE,IAAY,EAAE,EAAU,EAAE,SAAiB,EAAE,IAAY;IACpG,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoD,CAAC;IACxE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;YAAE,SAAS;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACjC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;QACzC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;SACtB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SACnI,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;SACjD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACtG,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACpB,CAAC;AAED;+CAC+C;AAC/C,MAAM,UAAU,UAAU,CAAC,aAAuB;IAChD,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC;YAAC,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAAC,IAAI,GAAG,CAAC,CAAC;QAAC,CAAC;IAC3E,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC1D,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,iBAAiB,CAC/B,OAAiB,EACjB,SAAqB,EACrB,IAAY,EACZ,EAAU,EACV,OAAuB,EAAE,EACzB,cAA0B,EAAE,EAC5B,gBAA0B,EAAE;IAE5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7F,IAAI,IAAI,GAAG,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,EAAE,2BAA2B,CAAC,CAAC;IAClF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC;IAExC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAqB;QAC/B,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC;QAC3D,eAAe,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC;KACnE,CAAC;IACF,IAAI,UAAU,GAA6B,IAAI,CAAC;IAChD,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,cAAc,GAAG,CAAC,CAAC;IAEvB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACnB,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC;QAC5B,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC;QACpC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC;QACpC,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC;QACtC,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC,eAAe,CAAC;QAC5C,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC,gBAAgB,CAAC;QAC9C,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;YAClD,UAAU,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9E,CAAC;QACD,yDAAyD;QACzD,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG;YAAE,aAAa,IAAI,CAAC,CAAC,OAAO,CAAC;;YACxD,cAAc,IAAI,CAAC,CAAC,OAAO,CAAC;IACnC,CAAC;IACD,gEAAgE;IAChE,IAAI,MAAM,CAAC,UAAU,KAAK,CAAC;QAAE,UAAU,GAAG,IAAI,CAAC;IAE/C,yEAAyE;IACzE,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACxE,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAE5E,+EAA+E;IAC/E,6EAA6E;IAC7E,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,sBAAsB,CAAC;IACjE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsF,CAAC;IAClH,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;YAAE,SAAS;QACvC,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;QAChG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;QACtC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;QAChD,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC;QAC9C,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,WAAW,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,iBAAiB,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,IAAI,EAAE,KAAK,IAAI;YAAE,eAAe,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,eAAe,CAAC;IACxF,MAAM,SAAS,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,aAAa,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtH,MAAM,SAAS,GAA2B,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IAE9G,OAAO;QACL,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;QAClD,MAAM;QACN,UAAU;QACV,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACxF,SAAS;QACT,WAAW;QACX,QAAQ,EAAE,UAAU,CAAC,aAAa,CAAC;QACnC,aAAa;QACb,aAAa,EAAE,eAAe,CAAC,aAAa,CAAC;QAC7C,YAAY,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QACpE,mBAAmB,EAAE,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACnF,KAAK,EAAE,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE;QACnD,eAAe;KAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * spend-forecast.ts — project month-end Claude Code spend from month-to-date
3
+ * burn, for budgeting ("on pace for ~$420 this month").
4
+ *
5
+ * The quota forecaster (limits.ts) answers "will I hit the rolling cap"; this
6
+ * answers "what will the calendar month cost at the current daily average".
7
+ * Pure + deterministic: month-to-date total, the day-of-month, and the days in
8
+ * the month are passed in, so it's unit-tested without a clock.
9
+ */
10
+ export interface SpendProjection {
11
+ monthToDateUsd: number;
12
+ dayOfMonth: number;
13
+ daysInMonth: number;
14
+ /** month-to-date / day-of-month */
15
+ dailyAverageUsd: number;
16
+ /** dailyAverage × daysInMonth — projected month-end total */
17
+ projectedUsd: number;
18
+ /** projectedUsd − monthToDateUsd — the remaining projected spend */
19
+ remainingUsd: number;
20
+ }
21
+ /** Days in the calendar month of an ISO `YYYY-MM` (or `YYYY-MM-DD`). Pure. */
22
+ export declare function daysInMonthOf(iso: string): number;
23
+ /**
24
+ * Project month-end spend at the current daily average. `dayOfMonth` is how many
25
+ * days (inclusive of today) have accrued the month-to-date total. Pure.
26
+ */
27
+ export declare function projectMonthEnd(monthToDateUsd: number, dayOfMonth: number, daysInMonth: number): SpendProjection;
28
+ //# sourceMappingURL=spend-forecast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spend-forecast.d.ts","sourceRoot":"","sources":["../../../src/usage/spend-forecast.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe,CAWhH"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * spend-forecast.ts — project month-end Claude Code spend from month-to-date
3
+ * burn, for budgeting ("on pace for ~$420 this month").
4
+ *
5
+ * The quota forecaster (limits.ts) answers "will I hit the rolling cap"; this
6
+ * answers "what will the calendar month cost at the current daily average".
7
+ * Pure + deterministic: month-to-date total, the day-of-month, and the days in
8
+ * the month are passed in, so it's unit-tested without a clock.
9
+ */
10
+ /** Days in the calendar month of an ISO `YYYY-MM` (or `YYYY-MM-DD`). Pure. */
11
+ export function daysInMonthOf(iso) {
12
+ const [y, m] = iso.split('-').map(Number);
13
+ if (!Number.isFinite(y) || !Number.isFinite(m) || m < 1 || m > 12)
14
+ return NaN;
15
+ return new Date(y, m, 0).getDate(); // day 0 of the next month = last day of this one
16
+ }
17
+ /**
18
+ * Project month-end spend at the current daily average. `dayOfMonth` is how many
19
+ * days (inclusive of today) have accrued the month-to-date total. Pure.
20
+ */
21
+ export function projectMonthEnd(monthToDateUsd, dayOfMonth, daysInMonth) {
22
+ const dailyAverageUsd = dayOfMonth > 0 ? monthToDateUsd / dayOfMonth : 0;
23
+ const projectedUsd = dailyAverageUsd * daysInMonth;
24
+ return {
25
+ monthToDateUsd,
26
+ dayOfMonth,
27
+ daysInMonth,
28
+ dailyAverageUsd,
29
+ projectedUsd,
30
+ remainingUsd: Math.max(0, projectedUsd - monthToDateUsd),
31
+ };
32
+ }
33
+ //# sourceMappingURL=spend-forecast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spend-forecast.js","sourceRoot":"","sources":["../../../src/usage/spend-forecast.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC;IAC9E,OAAO,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,iDAAiD;AACvF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,cAAsB,EAAE,UAAkB,EAAE,WAAmB;IAC7F,MAAM,eAAe,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,YAAY,GAAG,eAAe,GAAG,WAAW,CAAC;IACnD,OAAO;QACL,cAAc;QACd,UAAU;QACV,WAAW;QACX,eAAe;QACf,YAAY;QACZ,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC;KACzD,CAAC;AACJ,CAAC"}
@@ -31,6 +31,20 @@ export interface ToolErrorReport {
31
31
  filesScanned: number;
32
32
  sessionsWithErrors: number;
33
33
  }
34
+ export interface Delegation {
35
+ /** tool_use calls to the `Task` tool (subagent spawns) */
36
+ taskCalls: number;
37
+ /** all tool_use calls */
38
+ toolCalls: number;
39
+ /** taskCalls / toolCalls, 0..1 (0 when no tool calls) */
40
+ ratio: number;
41
+ }
42
+ /**
43
+ * Delegation ratio: what fraction of tool calls spawned a subagent (the `Task`
44
+ * tool), from an already-collected tool report. The report's parsing/counting
45
+ * is the tested collectToolErrors path — this just extracts the Task share. Pure.
46
+ */
47
+ export declare function delegationFromReport(report: Pick<ToolErrorReport, 'tools' | 'totalCalls'>): Delegation;
34
48
  export interface ParsedLine {
35
49
  type?: string;
36
50
  timestamp?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"transcript-errors.d.ts","sourceRoot":"","sources":["../../../src/usage/transcript-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAUD,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAChD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnE,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACjC;AAED,wBAAgB,QAAQ,IAAI,UAAU,CAErC;AAED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CASlD;AAED;;;8DAG8D;AAC9D,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED,+DAA+D;AAC/D,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAsBhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,eAAe,CAchG;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;kFACkF;AAClF,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,oBAAyB,GAAG,eAAe,CAoClF"}
1
+ {"version":3,"file":"transcript-errors.d.ts","sourceRoot":"","sources":["../../../src/usage/transcript-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,YAAY,CAAC,GAAG,UAAU,CAItG;AAUD,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAChD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnE,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACjC;AAED,wBAAgB,QAAQ,IAAI,UAAU,CAErC;AAED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CASlD;AAED;;;8DAG8D;AAC9D,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED,+DAA+D;AAC/D,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAsBhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,eAAe,CAchG;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;kFACkF;AAClF,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,oBAAyB,GAAG,eAAe,CAoClF"}
@@ -12,6 +12,16 @@
12
12
  */
13
13
  import * as fs from 'node:fs';
14
14
  import { defaultClaudeProjectDirs, findTranscriptFiles, normalizeDateBound } from './transcript-usage.js';
15
+ /**
16
+ * Delegation ratio: what fraction of tool calls spawned a subagent (the `Task`
17
+ * tool), from an already-collected tool report. The report's parsing/counting
18
+ * is the tested collectToolErrors path — this just extracts the Task share. Pure.
19
+ */
20
+ export function delegationFromReport(report) {
21
+ const taskCalls = report.tools.find((t) => t.tool === 'Task')?.calls ?? 0;
22
+ const toolCalls = report.totalCalls;
23
+ return { taskCalls, toolCalls, ratio: toolCalls > 0 ? taskCalls / toolCalls : 0 };
24
+ }
15
25
  export function newAccum() {
16
26
  return { idToTool: new Map(), calls: new Map(), errors: new Map(), sigs: new Map(), sessionsWithErrors: new Set() };
17
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transcript-errors.js","sourceRoot":"","sources":["../../../src/usage/transcript-errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transcript-errors.js","sourceRoot":"","sources":["../../../src/usage/transcript-errors.ts"],"names":[],"mappings":"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"}