claude-code-watch 0.2.1 → 0.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-watch",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Web-based real-time monitor for Claude Code.",
5
5
  "main": "./src/server/server.js",
6
6
  "bin": {
@@ -204,7 +204,7 @@ body {
204
204
  .tp-refresh-bar { display: flex; align-items: center; justify-content: flex-end; gap: 12px; padding-bottom: 4px; }
205
205
  .tp-refresh-info { font-size: 11px; color: var(--dim); }
206
206
  .tp-top { display: grid; grid-template-columns: 1fr 1.5fr 1fr; gap: 16px; }
207
- .tp-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 16px; }
207
+ .tp-row2 { display: grid; grid-template-columns: 1fr; gap: 16px; margin-top: 16px; }
208
208
  .tp-box { background: var(--bg2); border: 1px solid var(--border); border-radius: 8px; padding: 14px 16px; }
209
209
  .tp-total-label { font-size: 11px; color: var(--dim); text-transform: uppercase; margin-bottom: 2px; }
210
210
  .tp-total-value { font-size: 22px; font-weight: 700; color: var(--white); font-family: monospace; }
@@ -224,7 +224,7 @@ body {
224
224
  .tp-h3 { font-size: 12px; color: var(--dim); font-weight: 600; text-transform: uppercase; margin-bottom: 8px; }
225
225
 
226
226
  /* ── Heatmap ── */
227
- .tp-heatmap { overflow-x: auto; }
227
+ .tp-heatmap { overflow-x: auto; text-align: center; }
228
228
  .tp-heatmap-inner { display: inline-flex; flex-direction: column; gap: 2px; }
229
229
  .tp-hm-months { display: flex; gap: 0; font-size: 10px; color: var(--dim); margin-bottom: 2px; padding-left: 28px; }
230
230
  .tp-hm-row { display: flex; align-items: center; gap: 2px; }
@@ -232,17 +232,18 @@ body {
232
232
  .tp-hm-cell { width: 12px; height: 12px; border-radius: 2px; transition: transform 0.15s; cursor: pointer; position: relative; }
233
233
  .tp-hm-cell:hover { transform: scale(1.6); z-index: 10; }
234
234
  .tp-hm-cell[title]:hover::after { content: attr(title); position: absolute; bottom: calc(100% + 4px); left: 50%; transform: translateX(-50%); background: var(--bg2); color: var(--white); padding: 2px 8px; border-radius: 4px; font-size: 10px; white-space: nowrap; z-index: 100; border: 1px solid var(--border); pointer-events: none; }
235
- .tp-hm-legend { display: flex; align-items: center; gap: 4px; font-size: 10px; color: var(--dim); margin-top: 6px; justify-content: flex-end; }
235
+ .tp-hm-legend { display: flex; align-items: center; gap: 4px; font-size: 10px; color: var(--dim); margin-top: 6px; justify-content: center; }
236
236
  .tp-hm-legend-cell { width: 12px; height: 12px; border-radius: 2px; }
237
237
 
238
238
  /* ── Trend bars ── */
239
- .tp-trend-bars { display: flex; align-items: flex-end; gap: 3px; height: 140px; position: relative; padding-bottom: 20px; }
240
- .tp-trend-bar-wrap { flex: 1; display: flex; flex-direction: column; position: relative; min-width: 0; }
241
- .tp-trend-bar { position: relative; border-radius: 3px 3px 0 0; transition: all 0.15s; cursor: pointer; min-height: 4px; }
239
+ .tp-trend-bars { display: flex; align-items: stretch; gap: 3px; height: 140px; position: relative; }
240
+ .tp-trend-bar-wrap { flex: 1; display: flex; flex-direction: column; min-width: 0; }
241
+ .tp-trend-bar-area { flex: 1; display: flex; flex-direction: column; align-items: stretch; justify-content: flex-end; }
242
+ .tp-trend-bar { position: relative; border-radius: 3px 3px 0 0; transition: all 0.15s; cursor: pointer; min-height: 4px; width: 100%; }
242
243
  .tp-trend-bar:hover { filter: brightness(1.3); }
243
244
  .tp-trend-bar:hover::after { content: attr(data-tip); position: absolute; bottom: calc(100% + 4px); left: 50%; transform: translateX(-50%); background: var(--bg2); color: var(--white); padding: 2px 8px; border-radius: 4px; font-size: 10px; white-space: nowrap; z-index: 100; border: 1px solid var(--border); pointer-events: none; }
244
- .tp-trend-label { font-size: 9px; color: var(--dim); text-align: center; position: absolute; bottom: 0; width: 100%; white-space: nowrap; overflow: hidden; }
245
- .tp-trend-grid-lines { position: absolute; inset: 0 0 20px 0; display: flex; flex-direction: column; justify-content: space-between; pointer-events: none; }
245
+ .tp-trend-label { font-size: 11px; color: var(--text); text-align: center; padding-top: 6px; white-space: nowrap; }
246
+ .tp-trend-grid-lines { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: space-between; pointer-events: none; }
246
247
  .tp-trend-grid-line { width: 100%; border-top: 1px dashed var(--border); opacity: 0.4; }
247
248
 
248
249
  /* ── Detail table ── */
package/public/index.html CHANGED
@@ -75,8 +75,8 @@
75
75
  <div class="tp-chart-box" id="tp-hourly-chart" role="img" aria-label="Active time distribution chart"></div>
76
76
  </div>
77
77
  <div class="tp-row2">
78
- <div class="tp-box" id="tp-trend-card"></div>
79
78
  <div class="tp-box" id="tp-heatmap-card"></div>
79
+ <div class="tp-box" id="tp-trend-card"></div>
80
80
  </div>
81
81
  <div class="tp-box">
82
82
  <div class="tp-tabs" id="tp-detail-tabs"></div>
@@ -203,7 +203,7 @@ function aggregateWeekly(dailyKeys, daily) {
203
203
  const d = new Date(k);
204
204
  const wk = getWeekKey(d);
205
205
  if (!result[wk]) result[wk] = { messages: 0, input: 0, output: 0, cacheCreation: 0, cacheRead: 0, models: {}, dateRange: k };
206
- else result[wk].dateRange += ' ~ ' + k;
206
+ else result[wk].dateRange = result[wk].dateRange.split(' ~ ')[0] + ' ~ ' + k;
207
207
  const day = daily[k];
208
208
  result[wk].messages += day.messages;
209
209
  result[wk].input += day.input;
@@ -167,14 +167,14 @@ function buildTrend(daily) {
167
167
  const label = k.slice(5);
168
168
  const tip = `${k}: ${fmtTS(v)}`;
169
169
  const color = pct < 30 ? '#0e6b5a' : pct < 60 ? '#12b886' : pct < 80 ? '#34d399' : '#6ee7b7';
170
- barsHTML += `<div class="tp-trend-bar-wrap"><div class="tp-trend-bar" style="height:${Math.max(pct, 3)}%;background:${color}" data-tip="${esc(tip)}"></div><span class="tp-trend-label">${esc(label)}</span></div>`;
170
+ barsHTML += `<div class="tp-trend-bar-wrap"><div class="tp-trend-bar-area"><div class="tp-trend-bar" style="height:${Math.max(pct, 3)}%;background:${color}" data-tip="${esc(tip)}"></div></div><span class="tp-trend-label">${esc(label)}</span></div>`;
171
171
  }
172
172
 
173
173
  const gridLines = `<div class="tp-trend-grid-lines">
174
174
  <span style="font-size:9px;color:var(--dim);align-self:flex-start">${fmtTS(maxVal)}</span>
175
175
  <div class="tp-trend-grid-line"></div>
176
176
  <div class="tp-trend-grid-line"></div>
177
- <span style="font-size:9px;color:var(--dim);align-self:center">${fmtTS(maxVal * 0.5)}</span>
177
+ <span style="font-size:9px;color:var(--dim);align-self:center">${fmtTS(Math.round(maxVal * 0.5))}</span>
178
178
  <div class="tp-trend-grid-line"></div>
179
179
  <span style="font-size:9px;color:var(--dim);align-self:flex-end">0</span>
180
180
  </div>`;
@@ -344,7 +344,7 @@ function renderPeriodTable(keys, data, type) {
344
344
  const k = sorted[i];
345
345
  const d = data[k];
346
346
  const total = d.input + d.output + d.cacheCreation + d.cacheRead;
347
- const label = type === 'daily' ? k : k + '<br><small style="color:var(--dim)">' + esc(d.dateRange || '') + '</small>';
347
+ const label = type === 'daily' ? k : type === 'monthly' ? k : k + '<br><small style="color:var(--dim)">' + esc(d.dateRange || '') + '</small>';
348
348
  const modelsHtml = Object.entries(d.models).sort((a, b) => {
349
349
  const sA = a[1].input + a[1].output + a[1].cacheCreation + a[1].cacheRead;
350
350
  const sB = b[1].input + b[1].output + b[1].cacheCreation + b[1].cacheRead;