@git-snitch/renderer 0.0.10 → 0.0.12

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.
package/dist/charts.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CommitRecord, ContributorSummary, RepoReportData, ScanProjectReport, ScanReportData } from "@git-snitch/core";
1
+ import type { AiUsageBreakdownItem, CommitRecord, ContributorSummary, RepoReportData, ReportAiUsageProjectSummary, ScanProjectReport, ScanReportData } from "@git-snitch/core";
2
2
  export type CommitActivityPoint = {
3
3
  readonly period: string;
4
4
  readonly commits: number;
@@ -55,6 +55,32 @@ export type ActivityHeatmapCell = {
55
55
  readonly hour: string;
56
56
  readonly commits: number;
57
57
  };
58
+ export type AiUsageBreakdownPoint = {
59
+ readonly name: string;
60
+ readonly messages: number;
61
+ readonly tokens: number;
62
+ readonly cost: number;
63
+ };
64
+ export type ScanCommitSlice = {
65
+ readonly name: string;
66
+ readonly commits: number;
67
+ };
68
+ export type ScanChurnSlice = {
69
+ readonly name: string;
70
+ readonly additions: number;
71
+ readonly deletions: number;
72
+ readonly churn: number;
73
+ };
74
+ export type ScanAiProjectSlice = {
75
+ readonly name: string;
76
+ readonly messages: number;
77
+ readonly tokens: number;
78
+ };
79
+ export type ScanAiModelSlice = {
80
+ readonly name: string;
81
+ readonly messages: number;
82
+ readonly tokens: number;
83
+ };
58
84
  export declare function deriveCommitActivityData(report: Pick<RepoReportData, "analysis">): readonly CommitActivityPoint[];
59
85
  export declare function deriveContributorPieData(contributors: readonly ContributorSummary[]): readonly ContributorPieSlice[];
60
86
  export declare function deriveLanguageDistributionData(report: Pick<RepoReportData | ScanReportData, "analysis">): readonly LanguageDistributionSlice[];
@@ -66,6 +92,7 @@ export declare function deriveContributionCalendarData(commits: readonly CommitR
66
92
  export declare function deriveVelocityData(report: Pick<RepoReportData, "analysis">): readonly VelocityPoint[];
67
93
  export declare function deriveCodeOwnershipData(contributors: readonly ContributorSummary[]): readonly CodeOwnershipPoint[];
68
94
  export declare function deriveProjectsComparisonData(projects: readonly ScanProjectReport[]): readonly ProjectComparisonPoint[];
95
+ export declare function deriveAiUsageBreakdownData(rows: readonly AiUsageBreakdownItem[]): readonly AiUsageBreakdownPoint[];
69
96
  export declare function deriveActivityHeatmapData(commits: readonly CommitRecord[]): readonly ActivityHeatmapCell[];
70
97
  export declare function CommitActivityChart({ data }: {
71
98
  readonly data: readonly CommitActivityPoint[];
@@ -100,7 +127,31 @@ export declare function CodeOwnershipChart({ data }: {
100
127
  export declare function ProjectsComparisonChart({ data }: {
101
128
  readonly data: readonly ProjectComparisonPoint[];
102
129
  }): import("react/jsx-runtime").JSX.Element;
130
+ export declare function AiUsageBreakdownChart({ title, description, data }: {
131
+ readonly title: string;
132
+ readonly description: string;
133
+ readonly data: readonly AiUsageBreakdownPoint[];
134
+ }): import("react/jsx-runtime").JSX.Element;
103
135
  export declare function ActivityHeatmap({ data }: {
104
136
  readonly data: readonly ActivityHeatmapCell[];
105
137
  }): import("react/jsx-runtime").JSX.Element;
138
+ export declare function ScanCommitBarChart({ data }: {
139
+ readonly data: readonly ScanCommitSlice[];
140
+ }): import("react/jsx-runtime").JSX.Element;
141
+ export declare function ScanChurnPieChart({ data }: {
142
+ readonly data: readonly ScanChurnSlice[];
143
+ }): import("react/jsx-runtime").JSX.Element;
144
+ export declare function ScanAiMessagesPieChart({ data }: {
145
+ readonly data: readonly ScanAiProjectSlice[];
146
+ }): import("react/jsx-runtime").JSX.Element;
147
+ export declare function ScanAiTokensBarChart({ data }: {
148
+ readonly data: readonly ScanAiProjectSlice[];
149
+ }): import("react/jsx-runtime").JSX.Element;
150
+ export declare function ScanAiModelsPieChart({ data }: {
151
+ readonly data: readonly ScanAiModelSlice[];
152
+ }): import("react/jsx-runtime").JSX.Element;
153
+ export declare function deriveScanCommitData(projects: readonly ScanProjectReport[]): readonly ScanCommitSlice[];
154
+ export declare function deriveScanChurnData(projects: readonly ScanProjectReport[]): readonly ScanChurnSlice[];
155
+ export declare function deriveScanAiPerProjectData(projects: readonly ScanProjectReport[]): readonly ScanAiProjectSlice[];
156
+ export declare function deriveScanAiModelsData(aiUsage: ReportAiUsageProjectSummary): readonly ScanAiModelSlice[];
106
157
  //# sourceMappingURL=charts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"charts.d.ts","sourceRoot":"","sources":["../src/charts.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAS5H,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACxF,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACtF,MAAM,MAAM,yBAAyB,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACtH,MAAM,MAAM,yBAAyB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAC5H,MAAM,MAAM,gBAAgB,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACpF,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACrF,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACjF,MAAM,MAAM,uBAAuB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC1F,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC5G,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AACnJ,MAAM,MAAM,sBAAsB,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAC1J,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AA4C5G,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,GAAG,SAAS,mBAAmB,EAAE,CAEjH;AAED,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,GAAG,SAAS,mBAAmB,EAAE,CAKpH;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,GAAG,cAAc,EAAE,UAAU,CAAC,GAAG,SAAS,yBAAyB,EAAE,CAK9I;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,yBAAyB,EAAE,CAUrH;AAED,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,gBAAgB,EAAE,CAgB9G;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,mBAAmB,EAAE,CAUzG;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,cAAc,EAAE,CAU/F;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,uBAAuB,EAAE,CAsBnH;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,GAAG,SAAS,aAAa,EAAE,CAOrG;AAED,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,GAAG,SAAS,kBAAkB,EAAE,CAUlH;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,sBAAsB,EAAE,CAStH;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,mBAAmB,EAAE,CAe1G;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,2CAoB9F;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,2CAqB9F;AAED,wBAAgB,yBAAyB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,yBAAyB,EAAE,CAAA;CAAE,2CAoB1G;AAED,wBAAgB,yBAAyB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,yBAAyB,EAAE,CAAA;CAAE,2CAqB1G;AAED,wBAAgB,2BAA2B,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAAE,2CAoBnG;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,2CAc9F;AAED,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,2CAcpF;AAED,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,uBAAuB,EAAE,CAAA;CAAE,2CA6BnG;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAA;CAAE,2CAelF;AAED,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAAE,2CAa5F;AAED,wBAAgB,uBAAuB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,sBAAsB,EAAE,CAAA;CAAE,2CAerG;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,2CAY1F"}
1
+ {"version":3,"file":"charts.d.ts","sourceRoot":"","sources":["../src/charts.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAS/K,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACxF,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACtF,MAAM,MAAM,yBAAyB,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACtH,MAAM,MAAM,yBAAyB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAC5H,MAAM,MAAM,gBAAgB,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACpF,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACrF,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACjF,MAAM,MAAM,uBAAuB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC1F,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC5G,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AACnJ,MAAM,MAAM,sBAAsB,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAC1J,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC5G,MAAM,MAAM,qBAAqB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AACzI,MAAM,MAAM,eAAe,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClF,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACvI,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/G,MAAM,MAAM,gBAAgB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AA4C7G,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,GAAG,SAAS,mBAAmB,EAAE,CAEjH;AAED,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,GAAG,SAAS,mBAAmB,EAAE,CAKpH;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,GAAG,cAAc,EAAE,UAAU,CAAC,GAAG,SAAS,yBAAyB,EAAE,CAK9I;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,yBAAyB,EAAE,CAUrH;AAED,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,gBAAgB,EAAE,CAgB9G;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,mBAAmB,EAAE,CAUzG;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,cAAc,EAAE,CAU/F;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,uBAAuB,EAAE,CAsBnH;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,GAAG,SAAS,aAAa,EAAE,CAOrG;AAED,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,GAAG,SAAS,kBAAkB,EAAE,CAUlH;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,sBAAsB,EAAE,CAStH;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,oBAAoB,EAAE,GAAG,SAAS,qBAAqB,EAAE,CAMlH;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,mBAAmB,EAAE,CAe1G;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,2CAoB9F;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,2CAqB9F;AAED,wBAAgB,yBAAyB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,yBAAyB,EAAE,CAAA;CAAE,2CAoB1G;AAED,wBAAgB,yBAAyB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,yBAAyB,EAAE,CAAA;CAAE,2CAqB1G;AAED,wBAAgB,2BAA2B,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAAE,2CAoBnG;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,2CAc9F;AAED,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,2CAcpF;AAED,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,uBAAuB,EAAE,CAAA;CAAE,2CA6BnG;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAA;CAAE,2CAelF;AAED,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAAE,2CAa5F;AAED,wBAAgB,uBAAuB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,sBAAsB,EAAE,CAAA;CAAE,2CAerG;AAED,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAAE,2CAe5K;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAAE,2CAY1F;AAED,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,eAAe,EAAE,CAAA;CAAE,2CAoBzF;AAED,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,2CAqBvF;AAED,wBAAgB,sBAAsB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAAE,2CAqBhG;AAED,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAAE,2CAoB9F;AAED,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAAE,2CAqB5F;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,eAAe,EAAE,CAOvG;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,cAAc,EAAE,CAerG;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,kBAAkB,EAAE,CAShH;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,2BAA2B,GAAG,SAAS,gBAAgB,EAAE,CASxG"}
package/dist/charts.js CHANGED
@@ -144,6 +144,13 @@ export function deriveProjectsComparisonData(projects) {
144
144
  }))
145
145
  .sort((left, right) => right.commits - left.commits || left.project.localeCompare(right.project));
146
146
  }
147
+ export function deriveAiUsageBreakdownData(rows) {
148
+ return rows
149
+ .filter((row) => row.records > 0 || row.tokens.total > 0 || row.cost > 0)
150
+ .map((row) => ({ name: row.key, messages: row.records, tokens: row.tokens.total, cost: row.cost }))
151
+ .sort((left, right) => right.tokens - left.tokens || right.messages - left.messages || left.name.localeCompare(right.name))
152
+ .slice(0, 8);
153
+ }
147
154
  export function deriveActivityHeatmapData(commits) {
148
155
  const counts = new Map();
149
156
  for (const commit of commits) {
@@ -195,9 +202,71 @@ export function CodeOwnershipChart({ data }) {
195
202
  export function ProjectsComparisonChart({ data }) {
196
203
  return (_jsx(ChartPanel, { title: "Projects comparison", description: "Repository activity across a scan.", isEmpty: !hasPositiveValue(data, (item) => [item.commits, item.contributors, item.filesChanged]), emptyTitle: "No projects to compare", emptyDescription: "Project comparison needs at least one scanned repository with activity.", children: _jsx(ChartContainer, { config: { commits: { label: "Commits", color: chartPalette[1] }, contributors: { label: "Contributors", color: chartPalette[3] } }, className: "h-72 w-full", children: _jsxs(BarChart, { data: data, layout: "vertical", margin: { left: 8, right: 16, top: 8, bottom: 0 }, children: [_jsx(CartesianGrid, { horizontal: false }), _jsx(XAxis, { type: "number", hide: true }), _jsx(YAxis, { dataKey: "project", type: "category", width: 112, tickLine: false, axisLine: false }), _jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, {}) }), _jsx(Bar, { dataKey: "commits", fill: "var(--color-commits)", radius: [0, 3, 3, 0], ...staticChartProps }), _jsx(Bar, { dataKey: "contributors", fill: "var(--color-contributors)", radius: [0, 3, 3, 0], ...staticChartProps })] }) }) }));
197
204
  }
205
+ export function AiUsageBreakdownChart({ title, description, data }) {
206
+ return (_jsx(ChartPanel, { title: title, description: description, isEmpty: !hasPositiveValue(data, (item) => [item.messages, item.tokens]), emptyTitle: `No ${title.toLowerCase()} to chart`, emptyDescription: "AI usage charts need matched local assistant records with model or harness metadata.", children: _jsx(ChartContainer, { config: { tokens: { label: "Tokens", color: chartPalette[2] }, messages: { label: "Messages", color: chartPalette[4] } }, className: "h-72 w-full", children: _jsxs(BarChart, { data: data, layout: "vertical", margin: { left: 8, right: 16, top: 8, bottom: 0 }, children: [_jsx(CartesianGrid, { horizontal: false }), _jsx(XAxis, { type: "number", hide: true }), _jsx(YAxis, { dataKey: "name", type: "category", width: 124, tickLine: false, axisLine: false }), _jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, {}) }), _jsx(Bar, { dataKey: "tokens", fill: "var(--color-tokens)", radius: [0, 3, 3, 0], ...staticChartProps }), _jsx(Bar, { dataKey: "messages", fill: "var(--color-messages)", radius: [0, 3, 3, 0], ...staticChartProps })] }) }) }));
207
+ }
198
208
  export function ActivityHeatmap({ data }) {
199
209
  return (_jsx(ChartPanel, { title: "Activity heatmap", description: "UTC weekday and hour density.", isEmpty: !hasPositiveValue(data, (item) => [item.commits]), emptyTitle: "No activity heatmap to show", emptyDescription: "The heatmap needs at least one dated commit.", children: _jsx("div", { className: "grid grid-flow-dense grid-cols-[repeat(24,minmax(0,1fr))] gap-1", "aria-label": "Activity heatmap by day and hour", children: data.map((cell) => (_jsx("div", { title: `${cell.day} ${cell.hour}: ${cell.commits} commits`, className: cn("h-4 rounded-[2px] border", heatClass(cell.commits)), children: _jsx("span", { className: "sr-only", children: `${cell.day} ${cell.hour}: ${cell.commits} commits` }) }, `${cell.day}-${cell.hour}`))) }) }));
200
210
  }
211
+ export function ScanCommitBarChart({ data }) {
212
+ return (_jsx(ChartPanel, { title: "Commits per project", description: "Commit count across scanned repositories.", isEmpty: !hasPositiveValue(data, (item) => [item.commits]), emptyTitle: "No commits to chart", emptyDescription: "Commit comparison needs at least one scanned project with commits.", children: _jsx(ChartContainer, { config: { commits: { label: "Commits", color: chartPalette[1] } }, className: "h-64 w-full", children: _jsxs(BarChart, { data: data, layout: "vertical", margin: { left: 8, right: 16, top: 8, bottom: 0 }, children: [_jsx(CartesianGrid, { horizontal: false }), _jsx(XAxis, { type: "number", hide: true }), _jsx(YAxis, { dataKey: "name", type: "category", width: 112, tickLine: false, axisLine: false }), _jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, {}) }), _jsx(Bar, { dataKey: "commits", fill: "var(--color-commits)", radius: [0, 3, 3, 0], ...staticChartProps })] }) }) }));
213
+ }
214
+ export function ScanChurnPieChart({ data }) {
215
+ return (_jsx(ChartPanel, { title: "Churn per project", description: "Lines changed (additions + deletions) by project.", isEmpty: !hasPositiveValue(data, (item) => [item.churn]), emptyTitle: "No churn to chart", emptyDescription: "Churn data appears after file-level additions or deletions exist.", children: _jsx(ChartContainer, { config: { churn: { label: "Churn" } }, className: "h-64 w-full", children: _jsxs(PieChart, { children: [_jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { nameKey: "name" }) }), _jsx(Pie, { data: data, dataKey: "churn", nameKey: "name", innerRadius: 56, outerRadius: 88, paddingAngle: 2, ...staticChartProps, children: data.map((slice, index) => (_jsx(Cell, { fill: chartPalette[index % chartPalette.length] }, slice.name))) })] }) }) }));
216
+ }
217
+ export function ScanAiMessagesPieChart({ data }) {
218
+ return (_jsx(ChartPanel, { title: "AI messages per project", description: "Message share across scanned repositories.", isEmpty: !hasPositiveValue(data, (item) => [item.messages]), emptyTitle: "No AI messages to chart", emptyDescription: "AI message data appears after local assistant records are matched to projects.", children: _jsx(ChartContainer, { config: { messages: { label: "Messages" } }, className: "h-64 w-full", children: _jsxs(PieChart, { children: [_jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { nameKey: "name" }) }), _jsx(Pie, { data: data, dataKey: "messages", nameKey: "name", innerRadius: 56, outerRadius: 88, paddingAngle: 2, ...staticChartProps, children: data.map((slice, index) => (_jsx(Cell, { fill: chartPalette[index % chartPalette.length] }, slice.name))) })] }) }) }));
219
+ }
220
+ export function ScanAiTokensBarChart({ data }) {
221
+ return (_jsx(ChartPanel, { title: "AI tokens per project", description: "Token usage across scanned repositories.", isEmpty: !hasPositiveValue(data, (item) => [item.tokens]), emptyTitle: "No AI tokens to chart", emptyDescription: "AI token data appears after local assistant records are matched to projects.", children: _jsx(ChartContainer, { config: { tokens: { label: "Tokens", color: chartPalette[2] } }, className: "h-64 w-full", children: _jsxs(BarChart, { data: data, layout: "vertical", margin: { left: 8, right: 16, top: 8, bottom: 0 }, children: [_jsx(CartesianGrid, { horizontal: false }), _jsx(XAxis, { type: "number", hide: true }), _jsx(YAxis, { dataKey: "name", type: "category", width: 112, tickLine: false, axisLine: false }), _jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, {}) }), _jsx(Bar, { dataKey: "tokens", fill: "var(--color-tokens)", radius: [0, 3, 3, 0], ...staticChartProps })] }) }) }));
222
+ }
223
+ export function ScanAiModelsPieChart({ data }) {
224
+ return (_jsx(ChartPanel, { title: "AI usage by model", description: "Message share across all models used in the scan.", isEmpty: !hasPositiveValue(data, (item) => [item.messages]), emptyTitle: "No AI model data to chart", emptyDescription: "AI model data appears after local assistant records with model metadata are matched.", children: _jsx(ChartContainer, { config: { messages: { label: "Messages" } }, className: "h-64 w-full", children: _jsxs(PieChart, { children: [_jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { nameKey: "name" }) }), _jsx(Pie, { data: data, dataKey: "messages", nameKey: "name", innerRadius: 56, outerRadius: 88, paddingAngle: 2, ...staticChartProps, children: data.map((slice, index) => (_jsx(Cell, { fill: chartPalette[index % chartPalette.length] }, slice.name))) })] }) }) }));
225
+ }
226
+ export function deriveScanCommitData(projects) {
227
+ return projects
228
+ .map((project) => ({
229
+ name: project.repository.name,
230
+ commits: project.report.commits.length,
231
+ }))
232
+ .sort((left, right) => right.commits - left.commits || left.name.localeCompare(right.name));
233
+ }
234
+ export function deriveScanChurnData(projects) {
235
+ return projects
236
+ .map((project) => {
237
+ let additions = 0;
238
+ let deletions = 0;
239
+ for (const commit of project.report.commits) {
240
+ for (const file of commit.files) {
241
+ additions += file.additions;
242
+ deletions += file.deletions;
243
+ }
244
+ }
245
+ return { name: project.repository.name, additions, deletions, churn: additions + deletions };
246
+ })
247
+ .filter((item) => item.churn > 0)
248
+ .sort((left, right) => right.churn - left.churn || left.name.localeCompare(right.name));
249
+ }
250
+ export function deriveScanAiPerProjectData(projects) {
251
+ return projects
252
+ .filter((project) => project.report.aiUsage !== undefined && project.report.aiUsage.records > 0)
253
+ .map((project) => ({
254
+ name: project.repository.name,
255
+ messages: project.report.aiUsage.records,
256
+ tokens: project.report.aiUsage.tokens.total,
257
+ }))
258
+ .sort((left, right) => right.messages - left.messages || left.name.localeCompare(right.name));
259
+ }
260
+ export function deriveScanAiModelsData(aiUsage) {
261
+ return aiUsage.breakdowns.byModel
262
+ .filter((item) => item.records > 0 || item.tokens.total > 0)
263
+ .map((item) => ({
264
+ name: item.key,
265
+ messages: item.records,
266
+ tokens: item.tokens.total,
267
+ }))
268
+ .sort((left, right) => right.messages - left.messages || left.name.localeCompare(right.name));
269
+ }
201
270
  function heatClass(commits) {
202
271
  if (commits >= 8) {
203
272
  return "border-chart-4/40 bg-chart-4";
package/dist/layout.js CHANGED
@@ -6,13 +6,13 @@ import { EmptyState } from "./empty-state.js";
6
6
  import { ThemeToggle } from "./theme-toggle.js";
7
7
  export function Header({ title, titleHref, eyebrow, description, actions }) {
8
8
  const titleContent = _jsx("h1", { className: "mt-3 text-3xl font-semibold tracking-tight text-foreground sm:text-4xl", children: title });
9
- return (_jsx("header", { className: "border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/75", children: _jsxs("div", { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 px-5 py-8 sm:px-8 lg:flex-row lg:items-end lg:justify-between", children: [_jsxs("div", { className: "max-w-4xl", children: [eyebrow ? _jsx("p", { className: "text-xs font-medium uppercase tracking-[0.24em] text-muted-foreground", children: eyebrow }) : null, titleHref ? (_jsx("a", { href: titleHref, target: "_blank", rel: "noopener noreferrer", className: "hover:underline", children: titleContent })) : (titleContent), description ? _jsx("p", { className: "mt-3 max-w-2xl text-sm leading-6 text-muted-foreground", children: description }) : null] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [actions, _jsx(ThemeToggle, {})] })] }) }));
9
+ return (_jsx("header", { className: "border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/75", children: _jsxs("div", { className: "mx-auto flex w-full flex-col gap-6 px-6 py-8 sm:px-10 lg:flex-row lg:items-end lg:justify-between", children: [_jsxs("div", { className: "max-w-4xl", children: [eyebrow ? _jsx("p", { className: "text-xs font-medium uppercase tracking-[0.24em] text-muted-foreground", children: eyebrow }) : null, titleHref ? (_jsx("a", { href: titleHref, target: "_blank", rel: "noopener noreferrer", className: "hover:underline", children: titleContent })) : (titleContent), description ? _jsx("p", { className: "mt-3 max-w-2xl text-sm leading-6 text-muted-foreground", children: description }) : null] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [actions, _jsx(ThemeToggle, {})] })] }) }));
10
10
  }
11
11
  export function Navigation({ items, label = "Report sections" }) {
12
12
  if (items.length === 0) {
13
13
  return null;
14
14
  }
15
- return (_jsx("nav", { "aria-label": label, className: "border-b bg-background/80", children: _jsx("div", { className: "mx-auto flex w-full max-w-7xl gap-2 overflow-x-auto px-5 py-3 sm:px-8", children: items.map((item) => item.disabled ? (_jsx("span", { "aria-disabled": "true", className: "inline-flex h-8 shrink-0 items-center border border-transparent px-3 text-xs font-medium text-muted-foreground/60", children: item.label }, item.href)) : (_jsx("a", { href: item.href, "aria-current": item.current ? "page" : undefined, className: buttonVariants({ variant: item.current ? "secondary" : "ghost", size: "sm", className: "shrink-0" }), children: item.label }, item.href))) }) }));
15
+ return (_jsx("nav", { "aria-label": label, className: "border-b bg-background/80", children: _jsx("div", { className: "mx-auto flex w-full gap-2 overflow-x-auto px-6 py-3 sm:px-10", children: items.map((item) => item.disabled ? (_jsx("span", { "aria-disabled": "true", className: "inline-flex h-8 shrink-0 items-center border border-transparent px-3 text-xs font-medium text-muted-foreground/60", children: item.label }, item.href)) : (_jsx("a", { href: item.href, "aria-current": item.current ? "page" : undefined, className: buttonVariants({ variant: item.current ? "secondary" : "ghost", size: "sm", className: "shrink-0" }), children: item.label }, item.href))) }) }));
16
16
  }
17
17
  export function StatsGrid({ stats, emptyTitle = "No report statistics yet", emptyDescription = "This report does not include enough data for summary statistics.", }) {
18
18
  if (stats.length === 0) {
@@ -21,5 +21,5 @@ export function StatsGrid({ stats, emptyTitle = "No report statistics yet", empt
21
21
  return (_jsx("section", { "aria-label": "Report summary statistics", className: "grid grid-flow-dense gap-3 sm:grid-cols-2 lg:grid-cols-4", children: stats.map((stat) => (_jsxs(Card, { className: "min-h-32 shadow-none", children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: stat.label }) }), _jsxs(CardContent, { children: [_jsx("p", { className: "text-3xl font-semibold tracking-tight text-foreground", children: stat.value }), stat.description ? _jsx("p", { className: "mt-2 text-xs leading-5 text-muted-foreground", children: stat.description }) : null] })] }, stat.label))) }));
22
22
  }
23
23
  export function AppShell({ title, titleHref, eyebrow, description, navigationItems = [], headerActions, children, }) {
24
- return (_jsxs("main", { className: "min-h-screen w-full max-w-full overflow-x-hidden bg-background text-foreground transition-colors", children: [_jsx(Header, { title: title, titleHref: titleHref, eyebrow: eyebrow, description: description, actions: headerActions }), _jsx(Navigation, { items: navigationItems }), _jsx("div", { className: cn("mx-auto flex w-full max-w-7xl flex-col gap-8 px-5 py-8 sm:px-8 sm:py-10"), children: children })] }));
24
+ return (_jsxs("main", { className: "min-h-screen w-full max-w-full overflow-x-hidden bg-background text-foreground transition-colors", children: [_jsx(Header, { title: title, titleHref: titleHref, eyebrow: eyebrow, description: description, actions: headerActions }), _jsx(Navigation, { items: navigationItems }), _jsx("div", { className: cn("mx-auto flex w-full flex-col gap-8 px-6 py-8 sm:px-10 sm:py-10"), children: children })] }));
25
25
  }