ai-heatmap 1.6.0 → 1.7.1

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/bin/init.mjs CHANGED
@@ -85,8 +85,25 @@ copyFileSync(
85
85
  resolve(targetDir, "api/heatmap.ts"),
86
86
  );
87
87
 
88
- // Create public/
88
+ // Create public/ with config
89
89
  mkdirSync(resolve(targetDir, "public"), { recursive: true });
90
+ const defaultConfig = {
91
+ colorScheme: "light",
92
+ theme: "",
93
+ blockSize: 16,
94
+ blockMargin: 4,
95
+ blockRadius: 3,
96
+ bg: "",
97
+ textColor: "",
98
+ start: "",
99
+ end: "",
100
+ stats: true,
101
+ weekday: true,
102
+ };
103
+ writeFileSync(
104
+ resolve(targetDir, "public/heatmap.config.json"),
105
+ JSON.stringify(defaultConfig, null, 2),
106
+ );
90
107
 
91
108
  // GitHub Actions workflow
92
109
  const workflowDir = resolve(targetDir, ".github/workflows");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-heatmap",
3
- "version": "1.6.0",
3
+ "version": "1.7.1",
4
4
  "description": "AI usage cost heatmap powered by ccusage + react-activity-calendar",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,18 @@
1
+ {
2
+ "colorScheme": "light",
3
+ "theme": "",
4
+ "blockSize": 16,
5
+ "blockMargin": 4,
6
+ "blockRadius": 3,
7
+ "bg": "",
8
+ "textColor": "",
9
+ "start": "",
10
+ "end": "",
11
+ "stats": {
12
+ "dailyAvg": true,
13
+ "weeklyAvg": true,
14
+ "peak": true,
15
+ "activeDays": true
16
+ },
17
+ "weekday": true
18
+ }
package/src/App.tsx CHANGED
@@ -46,9 +46,24 @@ const DEFAULT_OPTIONS: CalendarOptions = {
46
46
  colorScheme: "light",
47
47
  };
48
48
 
49
- function parseOptions(): CalendarOptions {
49
+ interface HeatmapConfig {
50
+ colorScheme?: string;
51
+ blockSize?: number;
52
+ blockMargin?: number;
53
+ blockRadius?: number;
54
+ start?: string;
55
+ end?: string;
56
+ }
57
+
58
+ function parseOptions(config: HeatmapConfig = {}): CalendarOptions {
50
59
  const params = new URLSearchParams(window.location.search);
51
- const opts = { ...DEFAULT_OPTIONS };
60
+ const opts: CalendarOptions = {
61
+ ...DEFAULT_OPTIONS,
62
+ ...(config.blockSize != null && { blockSize: config.blockSize }),
63
+ ...(config.blockMargin != null && { blockMargin: config.blockMargin }),
64
+ ...(config.blockRadius != null && { blockRadius: config.blockRadius }),
65
+ ...((config.colorScheme === "light" || config.colorScheme === "dark") && { colorScheme: config.colorScheme }),
66
+ };
52
67
 
53
68
  const bool = (key: keyof CalendarOptions) => {
54
69
  const v = params.get(key);
@@ -100,12 +115,13 @@ function shortModel(name: string) {
100
115
 
101
116
  export default function App() {
102
117
  const [data, setData] = useState<Activity[]>([]);
103
- const [options] = useState(parseOptions);
118
+ const [options, setOptions] = useState(() => parseOptions());
104
119
  const [error, setError] = useState<string | null>(null);
120
+ const [configDates, setConfigDates] = useState<{ start?: string; end?: string }>({});
105
121
 
106
122
  const params = new URLSearchParams(window.location.search);
107
- const startDate = params.get("start");
108
- const endDate = params.get("end");
123
+ const startDate = params.get("start") || configDates.start || null;
124
+ const endDate = params.get("end") || configDates.end || null;
109
125
 
110
126
  useEffect(() => {
111
127
  fetch("./data.json")
@@ -115,6 +131,17 @@ export default function App() {
115
131
  })
116
132
  .then(setData)
117
133
  .catch((e) => setError(`Failed to load data.json: ${e.message}`));
134
+
135
+ fetch("./heatmap.config.json")
136
+ .then((r) => r.ok ? r.json() : null)
137
+ .then((config: HeatmapConfig | null) => {
138
+ if (!config) return;
139
+ setOptions(parseOptions(config));
140
+ if (config.start || config.end) {
141
+ setConfigDates({ start: config.start, end: config.end });
142
+ }
143
+ })
144
+ .catch(() => {});
118
145
  }, []);
119
146
 
120
147
  if (error) {