@code-insights/cli 1.1.0 → 2.0.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 (173) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +101 -9
  3. package/dist/commands/config.d.ts +3 -0
  4. package/dist/commands/config.d.ts.map +1 -0
  5. package/dist/commands/config.js +130 -0
  6. package/dist/commands/config.js.map +1 -0
  7. package/dist/commands/connect.d.ts.map +1 -1
  8. package/dist/commands/connect.js +7 -1
  9. package/dist/commands/connect.js.map +1 -1
  10. package/dist/commands/init.d.ts.map +1 -1
  11. package/dist/commands/init.js +52 -0
  12. package/dist/commands/init.js.map +1 -1
  13. package/dist/commands/install-hook.d.ts.map +1 -1
  14. package/dist/commands/install-hook.js +16 -3
  15. package/dist/commands/install-hook.js.map +1 -1
  16. package/dist/commands/open.d.ts +9 -0
  17. package/dist/commands/open.d.ts.map +1 -0
  18. package/dist/commands/open.js +59 -0
  19. package/dist/commands/open.js.map +1 -0
  20. package/dist/commands/reset.d.ts.map +1 -1
  21. package/dist/commands/reset.js +16 -2
  22. package/dist/commands/reset.js.map +1 -1
  23. package/dist/commands/stats/actions/cost.d.ts +3 -0
  24. package/dist/commands/stats/actions/cost.d.ts.map +1 -0
  25. package/dist/commands/stats/actions/cost.js +139 -0
  26. package/dist/commands/stats/actions/cost.js.map +1 -0
  27. package/dist/commands/stats/actions/error-handler.d.ts +6 -0
  28. package/dist/commands/stats/actions/error-handler.d.ts.map +1 -0
  29. package/dist/commands/stats/actions/error-handler.js +42 -0
  30. package/dist/commands/stats/actions/error-handler.js.map +1 -0
  31. package/dist/commands/stats/actions/models.d.ts +3 -0
  32. package/dist/commands/stats/actions/models.d.ts.map +1 -0
  33. package/dist/commands/stats/actions/models.js +101 -0
  34. package/dist/commands/stats/actions/models.js.map +1 -0
  35. package/dist/commands/stats/actions/overview.d.ts +3 -0
  36. package/dist/commands/stats/actions/overview.d.ts.map +1 -0
  37. package/dist/commands/stats/actions/overview.js +147 -0
  38. package/dist/commands/stats/actions/overview.js.map +1 -0
  39. package/dist/commands/stats/actions/projects.d.ts +3 -0
  40. package/dist/commands/stats/actions/projects.d.ts.map +1 -0
  41. package/dist/commands/stats/actions/projects.js +90 -0
  42. package/dist/commands/stats/actions/projects.js.map +1 -0
  43. package/dist/commands/stats/actions/today.d.ts +3 -0
  44. package/dist/commands/stats/actions/today.d.ts.map +1 -0
  45. package/dist/commands/stats/actions/today.js +118 -0
  46. package/dist/commands/stats/actions/today.js.map +1 -0
  47. package/dist/commands/stats/data/aggregation.d.ts +60 -0
  48. package/dist/commands/stats/data/aggregation.d.ts.map +1 -0
  49. package/dist/commands/stats/data/aggregation.js +614 -0
  50. package/dist/commands/stats/data/aggregation.js.map +1 -0
  51. package/dist/commands/stats/data/cache.d.ts +29 -0
  52. package/dist/commands/stats/data/cache.d.ts.map +1 -0
  53. package/dist/commands/stats/data/cache.js +197 -0
  54. package/dist/commands/stats/data/cache.js.map +1 -0
  55. package/dist/commands/stats/data/firestore.d.ts +13 -0
  56. package/dist/commands/stats/data/firestore.d.ts.map +1 -0
  57. package/dist/commands/stats/data/firestore.js +155 -0
  58. package/dist/commands/stats/data/firestore.js.map +1 -0
  59. package/dist/commands/stats/data/fuzzy-match.d.ts +5 -0
  60. package/dist/commands/stats/data/fuzzy-match.d.ts.map +1 -0
  61. package/dist/commands/stats/data/fuzzy-match.js +36 -0
  62. package/dist/commands/stats/data/fuzzy-match.js.map +1 -0
  63. package/dist/commands/stats/data/local.d.ts +12 -0
  64. package/dist/commands/stats/data/local.d.ts.map +1 -0
  65. package/dist/commands/stats/data/local.js +77 -0
  66. package/dist/commands/stats/data/local.js.map +1 -0
  67. package/dist/commands/stats/data/source.d.ts +13 -0
  68. package/dist/commands/stats/data/source.d.ts.map +1 -0
  69. package/dist/commands/stats/data/source.js +41 -0
  70. package/dist/commands/stats/data/source.js.map +1 -0
  71. package/dist/commands/stats/data/types.d.ts +229 -0
  72. package/dist/commands/stats/data/types.d.ts.map +1 -0
  73. package/dist/commands/stats/data/types.js +50 -0
  74. package/dist/commands/stats/data/types.js.map +1 -0
  75. package/dist/commands/stats/index.d.ts +3 -0
  76. package/dist/commands/stats/index.d.ts.map +1 -0
  77. package/dist/commands/stats/index.js +41 -0
  78. package/dist/commands/stats/index.js.map +1 -0
  79. package/dist/commands/stats/render/charts.d.ts +9 -0
  80. package/dist/commands/stats/render/charts.d.ts.map +1 -0
  81. package/dist/commands/stats/render/charts.js +45 -0
  82. package/dist/commands/stats/render/charts.js.map +1 -0
  83. package/dist/commands/stats/render/colors.d.ts +21 -0
  84. package/dist/commands/stats/render/colors.d.ts.map +1 -0
  85. package/dist/commands/stats/render/colors.js +47 -0
  86. package/dist/commands/stats/render/colors.js.map +1 -0
  87. package/dist/commands/stats/render/format.d.ts +10 -0
  88. package/dist/commands/stats/render/format.d.ts.map +1 -0
  89. package/dist/commands/stats/render/format.js +57 -0
  90. package/dist/commands/stats/render/format.js.map +1 -0
  91. package/dist/commands/stats/render/layout.d.ts +10 -0
  92. package/dist/commands/stats/render/layout.d.ts.map +1 -0
  93. package/dist/commands/stats/render/layout.js +48 -0
  94. package/dist/commands/stats/render/layout.js.map +1 -0
  95. package/dist/commands/stats/shared.d.ts +6 -0
  96. package/dist/commands/stats/shared.d.ts.map +1 -0
  97. package/dist/commands/stats/shared.js +26 -0
  98. package/dist/commands/stats/shared.js.map +1 -0
  99. package/dist/commands/status.d.ts.map +1 -1
  100. package/dist/commands/status.js +50 -37
  101. package/dist/commands/status.js.map +1 -1
  102. package/dist/commands/sync.d.ts +16 -1
  103. package/dist/commands/sync.d.ts.map +1 -1
  104. package/dist/commands/sync.js +167 -117
  105. package/dist/commands/sync.js.map +1 -1
  106. package/dist/commands/telemetry.d.ts +3 -0
  107. package/dist/commands/telemetry.d.ts.map +1 -0
  108. package/dist/commands/telemetry.js +106 -0
  109. package/dist/commands/telemetry.js.map +1 -0
  110. package/dist/firebase/client.d.ts +5 -0
  111. package/dist/firebase/client.d.ts.map +1 -1
  112. package/dist/firebase/client.js +5 -2
  113. package/dist/firebase/client.js.map +1 -1
  114. package/dist/index.js +21 -4
  115. package/dist/index.js.map +1 -1
  116. package/dist/parser/jsonl.d.ts.map +1 -1
  117. package/dist/parser/jsonl.js +8 -4
  118. package/dist/parser/jsonl.js.map +1 -1
  119. package/dist/parser/titles.d.ts.map +1 -1
  120. package/dist/parser/titles.js +2 -1
  121. package/dist/parser/titles.js.map +1 -1
  122. package/dist/providers/claude-code.d.ts +14 -0
  123. package/dist/providers/claude-code.d.ts.map +1 -0
  124. package/dist/providers/claude-code.js +66 -0
  125. package/dist/providers/claude-code.js.map +1 -0
  126. package/dist/providers/codex.d.ts +14 -0
  127. package/dist/providers/codex.d.ts.map +1 -0
  128. package/dist/providers/codex.js +364 -0
  129. package/dist/providers/codex.js.map +1 -0
  130. package/dist/providers/copilot-cli.d.ts +14 -0
  131. package/dist/providers/copilot-cli.d.ts.map +1 -0
  132. package/dist/providers/copilot-cli.js +363 -0
  133. package/dist/providers/copilot-cli.js.map +1 -0
  134. package/dist/providers/cursor.d.ts +27 -0
  135. package/dist/providers/cursor.d.ts.map +1 -0
  136. package/dist/providers/cursor.js +356 -0
  137. package/dist/providers/cursor.js.map +1 -0
  138. package/dist/providers/registry.d.ts +10 -0
  139. package/dist/providers/registry.d.ts.map +1 -0
  140. package/dist/providers/registry.js +31 -0
  141. package/dist/providers/registry.js.map +1 -0
  142. package/dist/providers/types.d.ts +15 -0
  143. package/dist/providers/types.d.ts.map +1 -0
  144. package/dist/providers/types.js +2 -0
  145. package/dist/providers/types.js.map +1 -0
  146. package/dist/types.d.ts +5 -1
  147. package/dist/types.d.ts.map +1 -1
  148. package/dist/utils/config.d.ts +10 -1
  149. package/dist/utils/config.d.ts.map +1 -1
  150. package/dist/utils/config.js +21 -0
  151. package/dist/utils/config.js.map +1 -1
  152. package/dist/utils/device.js +2 -2
  153. package/dist/utils/device.js.map +1 -1
  154. package/dist/utils/firebase-json.d.ts.map +1 -1
  155. package/dist/utils/firebase-json.js +2 -1
  156. package/dist/utils/firebase-json.js.map +1 -1
  157. package/dist/utils/paths.d.ts +10 -0
  158. package/dist/utils/paths.d.ts.map +1 -0
  159. package/dist/utils/paths.js +16 -0
  160. package/dist/utils/paths.js.map +1 -0
  161. package/dist/utils/telemetry.d.ts +52 -0
  162. package/dist/utils/telemetry.d.ts.map +1 -0
  163. package/dist/utils/telemetry.js +304 -0
  164. package/dist/utils/telemetry.js.map +1 -0
  165. package/dist/utils/tips.d.ts +11 -0
  166. package/dist/utils/tips.d.ts.map +1 -0
  167. package/dist/utils/tips.js +106 -0
  168. package/dist/utils/tips.js.map +1 -0
  169. package/dist/utils/welcome.d.ts +11 -0
  170. package/dist/utils/welcome.d.ts.map +1 -0
  171. package/dist/utils/welcome.js +101 -0
  172. package/dist/utils/welcome.js.map +1 -0
  173. package/package.json +9 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../../../../src/commands/stats/data/source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAiB;IACvD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QACvD,OAAO,IAAI,eAAe,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,mBAAmB,CAC3B,uGAAuG,CACxG,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC/D,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QACvD,OAAO,IAAI,eAAe,EAAE,CAAC;IAC/B,CAAC;IAED,8DAA8D;IAC9D,MAAM,WAAW,GACf,MAAM,CAAC,UAAU,KAAK,UAAU;QAChC,CAAC,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAErD,IAAI,WAAW,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC/D,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IACvD,OAAO,IAAI,eAAe,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,229 @@
1
+ /** Time period for filtering sessions */
2
+ export type Period = '7d' | '30d' | '90d' | 'all';
3
+ /** Options passed to data source query methods */
4
+ export interface SessionQueryOptions {
5
+ periodStart?: Date;
6
+ projectId?: string;
7
+ sourceTool?: string;
8
+ }
9
+ /**
10
+ * Universal session representation.
11
+ *
12
+ * Both Firestore and local data sources produce this shape.
13
+ * Required fields are guaranteed; optional fields depend on
14
+ * whether usage/cost data was captured during the session.
15
+ */
16
+ export interface SessionRow {
17
+ id: string;
18
+ projectId: string;
19
+ projectName: string;
20
+ startedAt: Date;
21
+ endedAt: Date;
22
+ messageCount: number;
23
+ userMessageCount: number;
24
+ assistantMessageCount: number;
25
+ toolCallCount: number;
26
+ estimatedCostUsd?: number;
27
+ totalInputTokens?: number;
28
+ totalOutputTokens?: number;
29
+ cacheCreationTokens?: number;
30
+ cacheReadTokens?: number;
31
+ primaryModel?: string;
32
+ modelsUsed?: string[];
33
+ generatedTitle?: string;
34
+ customTitle?: string;
35
+ summary?: string;
36
+ sessionCharacter?: string;
37
+ sourceTool?: string;
38
+ usageSource?: string;
39
+ }
40
+ /** Resolved project identity */
41
+ export interface ProjectResolution {
42
+ projectId: string;
43
+ projectName: string;
44
+ }
45
+ /** Result of a data source prepare step */
46
+ export interface PrepareResult {
47
+ message: string;
48
+ dataChanged: boolean;
49
+ }
50
+ /** Aggregated usage statistics document */
51
+ export interface UsageStatsDoc {
52
+ totalInputTokens: number;
53
+ totalOutputTokens: number;
54
+ cacheCreationTokens: number;
55
+ cacheReadTokens: number;
56
+ estimatedCostUsd: number;
57
+ sessionsWithUsage: number;
58
+ lastUpdatedAt: Date;
59
+ }
60
+ /**
61
+ * CLI flags for the stats command.
62
+ *
63
+ * Defined here (not in shared.ts) to avoid circular imports —
64
+ * shared.ts re-exports this type.
65
+ */
66
+ export interface StatsFlags {
67
+ period: Period;
68
+ project?: string;
69
+ source?: string;
70
+ noSync: boolean;
71
+ local: boolean;
72
+ remote: boolean;
73
+ }
74
+ /**
75
+ * Contract that every data source must implement.
76
+ *
77
+ * Both FirestoreDataSource and LocalDataSource satisfy this
78
+ * interface, allowing the stats commands to be data-source agnostic.
79
+ */
80
+ export interface StatsDataSource {
81
+ readonly name: string;
82
+ getSessions(opts: SessionQueryOptions): Promise<SessionRow[]>;
83
+ getUsageStats(): Promise<UsageStatsDoc | null>;
84
+ resolveProjectId(name: string): Promise<ProjectResolution>;
85
+ getLastSession(): Promise<SessionRow | null>;
86
+ prepare(flags: StatsFlags): Promise<PrepareResult>;
87
+ }
88
+ /** Single point on a time-series chart */
89
+ export interface TimeSeriesPoint {
90
+ date: string;
91
+ value: number;
92
+ }
93
+ /** A named metric with count, cost, and percentage */
94
+ export interface GroupedMetric {
95
+ name: string;
96
+ count: number;
97
+ cost: number;
98
+ percent: number;
99
+ }
100
+ /** Stats for a single calendar day */
101
+ export interface DayStats {
102
+ sessionCount: number;
103
+ totalCost: number;
104
+ totalMinutes: number;
105
+ }
106
+ /** High-level overview across all sessions in the period */
107
+ export interface StatsOverview {
108
+ sessionCount: number;
109
+ totalCost: number;
110
+ totalTimeMinutes: number;
111
+ messageCount: number;
112
+ totalTokens: number;
113
+ projectCount: number;
114
+ sessionsWithCostCount: number;
115
+ activityByDay: TimeSeriesPoint[];
116
+ todayStats: DayStats;
117
+ yesterdayStats: DayStats;
118
+ weekStats: DayStats;
119
+ topProjects: GroupedMetric[];
120
+ sourceTools: GroupedMetric[];
121
+ }
122
+ /** Detailed cost breakdown */
123
+ export interface CostBreakdown {
124
+ totalCost: number;
125
+ avgPerDay: number;
126
+ avgPerSession: number;
127
+ sessionCount: number;
128
+ sessionsWithCostCount: number;
129
+ dailyTrend: TimeSeriesPoint[];
130
+ peakDay: {
131
+ date: string;
132
+ cost: number;
133
+ sessions: number;
134
+ } | null;
135
+ byProject: GroupedMetric[];
136
+ byModel: GroupedMetric[];
137
+ tokenBreakdown: {
138
+ inputTokens: number;
139
+ outputTokens: number;
140
+ cacheCreation: number;
141
+ cacheReads: number;
142
+ inputCost: number;
143
+ outputCost: number;
144
+ cacheCreationCost: number;
145
+ cacheReadCost: number;
146
+ cacheHitRate: number;
147
+ };
148
+ }
149
+ /** Per-project stats row */
150
+ export interface ProjectStatsEntry {
151
+ projectId: string;
152
+ projectName: string;
153
+ sessionCount: number;
154
+ totalCost: number;
155
+ totalTimeMinutes: number;
156
+ messageCount: number;
157
+ totalTokens: number;
158
+ primaryModel?: string;
159
+ lastActive: Date;
160
+ sourceTool?: string;
161
+ activityByDay: TimeSeriesPoint[];
162
+ }
163
+ /** A single session within the "today" view */
164
+ export interface TodaySession {
165
+ id: string;
166
+ projectName: string;
167
+ title: string;
168
+ startedAt: Date;
169
+ endedAt: Date;
170
+ durationMinutes: number;
171
+ cost?: number;
172
+ model?: string;
173
+ messageCount: number;
174
+ sessionCharacter?: string;
175
+ }
176
+ /** Aggregated stats for today */
177
+ export interface TodayStats {
178
+ date: Date;
179
+ sessionCount: number;
180
+ totalCost: number;
181
+ totalTimeMinutes: number;
182
+ messageCount: number;
183
+ totalTokens: number;
184
+ sessions: TodaySession[];
185
+ }
186
+ /** Per-model stats row */
187
+ export interface ModelStatsEntry {
188
+ model: string;
189
+ displayName: string;
190
+ sessionCount: number;
191
+ sessionPercent: number;
192
+ totalCost: number;
193
+ costPercent: number;
194
+ avgCostPerSession: number;
195
+ totalTokens: number;
196
+ inputCost: number;
197
+ outputCost: number;
198
+ cacheCost: number;
199
+ trend: TimeSeriesPoint[];
200
+ }
201
+ /** Base error for all stats-related failures */
202
+ export declare class StatsError extends Error {
203
+ constructor(message: string);
204
+ }
205
+ /** Thrown when required configuration is missing */
206
+ export declare class ConfigNotFoundError extends StatsError {
207
+ constructor(message: string);
208
+ }
209
+ /** Thrown when a project name cannot be resolved */
210
+ export declare class ProjectNotFoundError extends StatsError {
211
+ readonly projectName: string;
212
+ readonly availableProjects: {
213
+ name: string;
214
+ }[];
215
+ readonly suggestions: string[];
216
+ constructor(message: string, projectName: string, availableProjects: {
217
+ name: string;
218
+ }[], suggestions: string[]);
219
+ }
220
+ /** Thrown when a Firestore composite index is required but missing */
221
+ export declare class FirestoreIndexError extends StatsError {
222
+ readonly indexUrl: string;
223
+ constructor(message: string, indexUrl: string);
224
+ }
225
+ /** Thrown when an invalid period value is provided */
226
+ export declare class InvalidPeriodError extends StatsError {
227
+ constructor(message: string);
228
+ }
229
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/commands/stats/data/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ // ──────────────────────────────────────────────────────
2
+ // Stats command — Foundation types
3
+ // ──────────────────────────────────────────────────────
4
+ // ──────────────────────────────────────────────────────
5
+ // Error classes
6
+ // ──────────────────────────────────────────────────────
7
+ /** Base error for all stats-related failures */
8
+ export class StatsError extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = 'StatsError';
12
+ }
13
+ }
14
+ /** Thrown when required configuration is missing */
15
+ export class ConfigNotFoundError extends StatsError {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = 'ConfigNotFoundError';
19
+ }
20
+ }
21
+ /** Thrown when a project name cannot be resolved */
22
+ export class ProjectNotFoundError extends StatsError {
23
+ projectName;
24
+ availableProjects;
25
+ suggestions;
26
+ constructor(message, projectName, availableProjects, suggestions) {
27
+ super(message);
28
+ this.name = 'ProjectNotFoundError';
29
+ this.projectName = projectName;
30
+ this.availableProjects = availableProjects;
31
+ this.suggestions = suggestions;
32
+ }
33
+ }
34
+ /** Thrown when a Firestore composite index is required but missing */
35
+ export class FirestoreIndexError extends StatsError {
36
+ indexUrl;
37
+ constructor(message, indexUrl) {
38
+ super(message);
39
+ this.name = 'FirestoreIndexError';
40
+ this.indexUrl = indexUrl;
41
+ }
42
+ }
43
+ /** Thrown when an invalid period value is provided */
44
+ export class InvalidPeriodError extends StatsError {
45
+ constructor(message) {
46
+ super(message);
47
+ this.name = 'InvalidPeriodError';
48
+ }
49
+ }
50
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/commands/stats/data/types.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,mCAAmC;AACnC,yDAAyD;AA0OzD,yDAAyD;AACzD,gBAAgB;AAChB,yDAAyD;AAEzD,gDAAgD;AAChD,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,oDAAoD;AACpD,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IACjD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,oDAAoD;AACpD,MAAM,OAAO,oBAAqB,SAAQ,UAAU;IAClC,WAAW,CAAS;IACpB,iBAAiB,CAAqB;IACtC,WAAW,CAAW;IAEtC,YACE,OAAe,EACf,WAAmB,EACnB,iBAAqC,EACrC,WAAqB;QAErB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;CACF;AAED,sEAAsE;AACtE,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IACjC,QAAQ,CAAS;IAEjC,YAAY,OAAe,EAAE,QAAgB;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED,sDAAsD;AACtD,MAAM,OAAO,kBAAmB,SAAQ,UAAU;IAChD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const statsCommand: Command;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/stats/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsDpC,eAAO,MAAM,YAAY,SAOW,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { Command } from 'commander';
2
+ import { applySharedFlags, parseFlags } from './shared.js';
3
+ // Wrapper that parses flags before calling the action
4
+ function wrapAction(actionFn) {
5
+ return async (options) => {
6
+ const flags = parseFlags(options);
7
+ await actionFn(flags);
8
+ };
9
+ }
10
+ // Lazy import actions to avoid loading everything at module load time
11
+ async function overviewAction(flags) {
12
+ const { overviewAction: action } = await import('./actions/overview.js');
13
+ return action(flags);
14
+ }
15
+ async function costAction(flags) {
16
+ const { costAction: action } = await import('./actions/cost.js');
17
+ return action(flags);
18
+ }
19
+ async function projectsAction(flags) {
20
+ const { projectsAction: action } = await import('./actions/projects.js');
21
+ return action(flags);
22
+ }
23
+ async function todayAction(flags) {
24
+ const { todayAction: action } = await import('./actions/today.js');
25
+ return action(flags);
26
+ }
27
+ async function modelsAction(flags) {
28
+ const { modelsAction: action } = await import('./actions/models.js');
29
+ return action(flags);
30
+ }
31
+ const costCommand = applySharedFlags(new Command('cost').description('Cost breakdown by project, model, and time period')).action(wrapAction(costAction));
32
+ const projectsCommand = applySharedFlags(new Command('projects').description('Per-project detail — sessions, time, cost, models')).action(wrapAction(projectsAction));
33
+ const todayCommand = applySharedFlags(new Command('today').description("Today's sessions with titles, duration, cost")).action(wrapAction(todayAction));
34
+ const modelsCommand = applySharedFlags(new Command('models').description('Model usage distribution, cost per model, trends')).action(wrapAction(modelsAction));
35
+ export const statsCommand = applySharedFlags(new Command('stats')
36
+ .description('View usage statistics and analytics')
37
+ .addCommand(costCommand)
38
+ .addCommand(projectsCommand)
39
+ .addCommand(todayCommand)
40
+ .addCommand(modelsCommand)).action(wrapAction(overviewAction));
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/stats/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG3D,sDAAsD;AACtD,SAAS,UAAU,CAAC,QAA8C;IAChE,OAAO,KAAK,EAAE,OAAgC,EAAE,EAAE;QAChD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,KAAK,UAAU,cAAc,CAAC,KAAiB;IAC7C,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;IACzE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,KAAiB;IACzC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACjE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,KAAiB;IAC7C,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;IACzE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,KAAiB;IAC1C,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,KAAiB;IAC3C,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,WAAW,GAAG,gBAAgB,CAClC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,mDAAmD,CAAC,CACrF,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;AAEjC,MAAM,eAAe,GAAG,gBAAgB,CACtC,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,mDAAmD,CAAC,CACzF,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;AAErC,MAAM,YAAY,GAAG,gBAAgB,CACnC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,8CAA8C,CAAC,CACjF,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;AAElC,MAAM,aAAa,GAAG,gBAAgB,CACpC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,kDAAkD,CAAC,CACtF,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAC1C,IAAI,OAAO,CAAC,OAAO,CAAC;KACjB,WAAW,CAAC,qCAAqC,CAAC;KAClD,UAAU,CAAC,WAAW,CAAC;KACvB,UAAU,CAAC,eAAe,CAAC;KAC3B,UAAU,CAAC,YAAY,CAAC;KACxB,UAAU,CAAC,aAAa,CAAC,CAC7B,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Period } from '../data/types.js';
2
+ export declare function sparkline(values: number[]): string;
3
+ export declare function sparklineLabels(period: Period): string;
4
+ export declare function barChart(items: {
5
+ label: string;
6
+ value: number;
7
+ suffix: string;
8
+ }[], barWidth: number): string[];
9
+ //# sourceMappingURL=charts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"charts.d.ts","sourceRoot":"","sources":["../../../../src/commands/stats/render/charts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI/C,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAWlD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,EACzD,QAAQ,EAAE,MAAM,GACf,MAAM,EAAE,CA2BV"}
@@ -0,0 +1,45 @@
1
+ import { colors } from './colors.js';
2
+ const SPARK_CHARS = ['▁', '▂', '▃', '▅', '▇'];
3
+ export function sparkline(values) {
4
+ if (values.length === 0)
5
+ return '';
6
+ const max = Math.max(...values);
7
+ return values
8
+ .map(v => {
9
+ if (max === 0)
10
+ return SPARK_CHARS[0];
11
+ const idx = Math.round((v / max) * 4);
12
+ return SPARK_CHARS[idx];
13
+ })
14
+ .map(char => colors.sparkChar(char))
15
+ .join('');
16
+ }
17
+ export function sparklineLabels(period) {
18
+ if (period === '7d')
19
+ return 'M T W T F S S';
20
+ if (period === '30d')
21
+ return ''; // Too many daily labels
22
+ return '';
23
+ }
24
+ export function barChart(items, barWidth) {
25
+ if (items.length === 0)
26
+ return [];
27
+ if (barWidth === 0) {
28
+ // Narrow terminal: simple list format
29
+ return items.map(item => ` ${colors.project(item.label.padEnd(20))} ${item.suffix}`);
30
+ }
31
+ const maxValue = Math.max(...items.map(i => i.value));
32
+ const maxLabelLen = Math.min(20, Math.max(...items.map(i => i.label.length)));
33
+ return items.map(item => {
34
+ const label = item.label.length > 20
35
+ ? item.label.slice(0, 17) + '...'
36
+ : item.label;
37
+ const paddedLabel = label.padEnd(maxLabelLen);
38
+ const filled = maxValue === 0 ? 0 : Math.round((item.value / maxValue) * barWidth);
39
+ const empty = barWidth - filled;
40
+ const bar = colors.barFilled('█'.repeat(filled))
41
+ + colors.barEmpty('░'.repeat(empty));
42
+ return ` ${colors.project(paddedLabel)} ${bar} ${item.suffix}`;
43
+ });
44
+ }
45
+ //# sourceMappingURL=charts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"charts.js","sourceRoot":"","sources":["../../../../src/commands/stats/render/charts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAE9C,MAAM,UAAU,SAAS,CAAC,MAAgB;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAChC,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,CAAC,EAAE;QACP,IAAI,GAAG,KAAK,CAAC;YAAE,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC,CAAC;SACD,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;SACnC,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,eAAe,CAAC;IAC5C,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC,CAAE,wBAAwB;IAC1D,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,KAAyD,EACzD,QAAgB;IAEhB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,sCAAsC;QACtC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACtB,KAAK,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAC7D,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAE9E,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE;YAClC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;YACjC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACf,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAE9C,MAAM,MAAM,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC;QACnF,MAAM,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;cACpC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAE/C,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,21 @@
1
+ export declare const colors: {
2
+ header: (text: string) => string;
3
+ label: (text: string) => string;
4
+ value: (text: string) => string;
5
+ divider: (width: number) => string;
6
+ hint: (text: string) => string;
7
+ money: (amount: number) => string;
8
+ moneyNeutral: (amount: number) => string;
9
+ project: (name: string) => string;
10
+ model: (name: string) => string;
11
+ source: (name: string) => string;
12
+ timestamp: (text: string) => string;
13
+ success: (text: string) => string;
14
+ warning: (text: string) => string;
15
+ error: (text: string) => string;
16
+ sparkChar: (char: string) => string;
17
+ barFilled: (chars: string) => string;
18
+ barEmpty: (chars: string) => string;
19
+ character: (char: string) => string;
20
+ };
21
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../../../src/commands/stats/render/colors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;mBAEE,MAAM;kBACN,MAAM;kBACN,MAAM;qBACL,MAAM;iBACP,MAAM;oBAGJ,MAAM;2BAMJ,MAAM;oBAGV,MAAM;kBACN,MAAM;mBACN,MAAM;sBACN,MAAM;oBAGN,MAAM;oBACN,MAAM;kBACN,MAAM;sBAGN,MAAM;uBACL,MAAM;sBACN,MAAM;sBAGR,MAAM,KAAG,MAAM;CAalC,CAAC"}
@@ -0,0 +1,47 @@
1
+ import chalk from 'chalk';
2
+ export const colors = {
3
+ // Structural
4
+ header: (text) => chalk.cyan.bold(text),
5
+ label: (text) => chalk.gray(text),
6
+ value: (text) => chalk.white.bold(text),
7
+ divider: (width) => chalk.gray('─'.repeat(width)),
8
+ hint: (text) => chalk.gray.italic(` → ${text}`),
9
+ // Money — color-coded by amount
10
+ money: (amount) => {
11
+ const formatted = `$${amount.toFixed(2)}`;
12
+ if (amount >= 20)
13
+ return chalk.red.bold(formatted);
14
+ if (amount >= 5)
15
+ return chalk.yellow.bold(formatted);
16
+ return chalk.green.bold(formatted);
17
+ },
18
+ moneyNeutral: (amount) => chalk.green.bold(`$${amount.toFixed(2)}`),
19
+ // Data types
20
+ project: (name) => chalk.white(name),
21
+ model: (name) => chalk.magenta(name),
22
+ source: (name) => chalk.blue(name),
23
+ timestamp: (text) => chalk.gray(text),
24
+ // States
25
+ success: (text) => chalk.green(text),
26
+ warning: (text) => chalk.yellow(text),
27
+ error: (text) => chalk.red(text),
28
+ // Charts
29
+ sparkChar: (char) => chalk.cyan(char),
30
+ barFilled: (chars) => chalk.cyan(chars),
31
+ barEmpty: (chars) => chalk.gray(chars),
32
+ // Session characters — color-coded by type
33
+ character: (char) => {
34
+ const map = {
35
+ deep_focus: chalk.blue,
36
+ bug_hunt: chalk.red,
37
+ feature_build: chalk.green,
38
+ exploration: chalk.yellow,
39
+ refactor: chalk.magenta,
40
+ learning: chalk.cyan,
41
+ quick_task: chalk.gray,
42
+ };
43
+ const display = char.replace(/_/g, ' ');
44
+ return (map[char] ?? chalk.gray)(`[${display}]`);
45
+ },
46
+ };
47
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../../../src/commands/stats/render/colors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,aAAa;IACb,MAAM,EAAM,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACnD,KAAK,EAAO,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9C,KAAK,EAAO,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IACpD,OAAO,EAAK,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,EAAQ,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IAE9D,gCAAgC;IAChC,KAAK,EAAO,CAAC,MAAc,EAAE,EAAE;QAC7B,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,IAAI,MAAM,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IACD,YAAY,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3E,aAAa;IACb,OAAO,EAAK,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;IAC/C,KAAK,EAAO,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;IACjD,MAAM,EAAM,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9C,SAAS,EAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IAE9C,SAAS;IACT,OAAO,EAAK,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;IAC/C,OAAO,EAAK,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;IAChD,KAAK,EAAO,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;IAE7C,SAAS;IACT,SAAS,EAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9C,SAAS,EAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;IAChD,QAAQ,EAAI,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;IAEhD,2CAA2C;IAC3C,SAAS,EAAE,CAAC,IAAY,EAAU,EAAE;QAClC,MAAM,GAAG,GAA0C;YACjD,UAAU,EAAK,KAAK,CAAC,IAAI;YACzB,QAAQ,EAAO,KAAK,CAAC,GAAG;YACxB,aAAa,EAAE,KAAK,CAAC,KAAK;YAC1B,WAAW,EAAI,KAAK,CAAC,MAAM;YAC3B,QAAQ,EAAO,KAAK,CAAC,OAAO;YAC5B,QAAQ,EAAO,KAAK,CAAC,IAAI;YACzB,UAAU,EAAK,KAAK,CAAC,IAAI;SAC1B,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;IACnD,CAAC;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Period } from '../data/types.js';
2
+ export declare function formatMoney(amount: number): string;
3
+ export declare function formatTokens(count: number): string;
4
+ export declare function formatDuration(minutes: number): string;
5
+ export declare function formatRelativeDate(date: Date): string;
6
+ export declare function formatTime(date: Date): string;
7
+ export declare function formatPercent(value: number): string;
8
+ export declare function formatCount(count: number): string;
9
+ export declare function formatPeriodLabel(period: Period): string;
10
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../../src/commands/stats/render/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAWrD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOxD"}
@@ -0,0 +1,57 @@
1
+ export function formatMoney(amount) {
2
+ if (amount >= 1000) {
3
+ return '$' + amount.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
4
+ }
5
+ return '$' + amount.toFixed(2);
6
+ }
7
+ export function formatTokens(count) {
8
+ if (count >= 1_000_000)
9
+ return (count / 1_000_000).toFixed(1) + 'M';
10
+ if (count >= 1_000)
11
+ return Math.round(count / 1_000) + 'K';
12
+ return count.toLocaleString();
13
+ }
14
+ export function formatDuration(minutes) {
15
+ if (minutes < 1)
16
+ return '< 1m';
17
+ if (minutes < 60)
18
+ return `${Math.round(minutes)}m`;
19
+ const h = Math.floor(minutes / 60);
20
+ const m = Math.round(minutes % 60);
21
+ return m > 0 ? `${h}h ${m}m` : `${h}h`;
22
+ }
23
+ export function formatRelativeDate(date) {
24
+ const now = new Date();
25
+ const diffMs = now.getTime() - date.getTime();
26
+ const diffHours = diffMs / (1000 * 60 * 60);
27
+ const diffDays = diffMs / (1000 * 60 * 60 * 24);
28
+ if (diffHours < 1)
29
+ return `${Math.max(1, Math.round(diffMs / 60000))}m ago`;
30
+ if (diffHours < 24)
31
+ return `${Math.round(diffHours)}h ago`;
32
+ if (diffDays < 2)
33
+ return 'yesterday';
34
+ if (diffDays < 7)
35
+ return `${Math.round(diffDays)}d ago`;
36
+ return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
37
+ }
38
+ export function formatTime(date) {
39
+ return date.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true });
40
+ }
41
+ export function formatPercent(value) {
42
+ if (value >= 10)
43
+ return `${Math.round(value)}%`;
44
+ return `${value.toFixed(1)}%`;
45
+ }
46
+ export function formatCount(count) {
47
+ return count.toLocaleString();
48
+ }
49
+ export function formatPeriodLabel(period) {
50
+ switch (period) {
51
+ case '7d': return 'Last 7 days';
52
+ case '30d': return 'Last 30 days';
53
+ case '90d': return 'Last 90 days';
54
+ case 'all': return 'All time';
55
+ }
56
+ }
57
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../src/commands/stats/render/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare function getTerminalWidth(): number;
2
+ export declare function getBarWidth(): number;
3
+ export declare function getGridColumns(): number;
4
+ export declare function sectionHeader(title: string, rightText?: string): string;
5
+ export declare function metricGrid(metrics: {
6
+ label: string;
7
+ value: string;
8
+ }[]): string;
9
+ export declare function projectCardHeader(name: string): string;
10
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/commands/stats/render/layout.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAKvC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAMvE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAc9E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtD"}
@@ -0,0 +1,48 @@
1
+ import chalk from 'chalk';
2
+ import { colors } from './colors.js';
3
+ export function getTerminalWidth() {
4
+ return process.stdout.columns || 80;
5
+ }
6
+ export function getBarWidth() {
7
+ const width = getTerminalWidth();
8
+ if (width >= 100)
9
+ return 20;
10
+ if (width >= 80)
11
+ return 16;
12
+ if (width >= 60)
13
+ return 12;
14
+ return 0;
15
+ }
16
+ export function getGridColumns() {
17
+ const width = getTerminalWidth();
18
+ if (width >= 80)
19
+ return 3;
20
+ if (width >= 60)
21
+ return 2;
22
+ return 1;
23
+ }
24
+ export function sectionHeader(title, rightText) {
25
+ const width = getTerminalWidth() - 4;
26
+ const header = colors.header(title.toUpperCase());
27
+ const right = rightText ? colors.label(rightText) : '';
28
+ const gap = width - title.length - (rightText?.length ?? 0);
29
+ return `\n ${header}${' '.repeat(Math.max(1, gap))}${right}\n ${colors.divider(width)}`;
30
+ }
31
+ export function metricGrid(metrics) {
32
+ const cols = getGridColumns();
33
+ const colWidth = cols === 3 ? 22 : cols === 2 ? 30 : 40;
34
+ const lines = [];
35
+ for (let i = 0; i < metrics.length; i += cols) {
36
+ const row = metrics.slice(i, i + cols);
37
+ const formatted = row.map(m => `${colors.label(m.label.padEnd(10))} ${colors.value(m.value.padStart(colWidth - 12))}`);
38
+ lines.push(' ' + formatted.join(' '));
39
+ }
40
+ return lines.join('\n');
41
+ }
42
+ export function projectCardHeader(name) {
43
+ const width = getTerminalWidth() - 4;
44
+ const nameSection = `${chalk.gray('─ ')}${chalk.white.bold(name)} `;
45
+ const remaining = width - name.length - 3;
46
+ return `\n ${nameSection}${chalk.gray('─'.repeat(Math.max(0, remaining)))}`;
47
+ }
48
+ //# sourceMappingURL=layout.js.map