clawck 0.4.3 → 0.5.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.
Files changed (77) hide show
  1. package/README.md +81 -9
  2. package/dist/cli/index.js +29 -44
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/core/atp.d.ts +1 -1
  5. package/dist/core/atp.d.ts.map +1 -1
  6. package/dist/core/atp.js +1 -1
  7. package/dist/core/atp.js.map +1 -1
  8. package/dist/core/clawck.d.ts.map +1 -1
  9. package/dist/core/clawck.js +14 -0
  10. package/dist/core/clawck.js.map +1 -1
  11. package/dist/core/config.d.ts +10 -0
  12. package/dist/core/config.d.ts.map +1 -0
  13. package/dist/core/config.js +58 -0
  14. package/dist/core/config.js.map +1 -0
  15. package/dist/core/database.d.ts +13 -0
  16. package/dist/core/database.d.ts.map +1 -1
  17. package/dist/core/database.js +151 -65
  18. package/dist/core/database.js.map +1 -1
  19. package/dist/core/errors.d.ts +19 -0
  20. package/dist/core/errors.d.ts.map +1 -0
  21. package/dist/core/errors.js +40 -0
  22. package/dist/core/errors.js.map +1 -0
  23. package/dist/core/logger.d.ts +14 -0
  24. package/dist/core/logger.d.ts.map +1 -0
  25. package/dist/core/logger.js +39 -0
  26. package/dist/core/logger.js.map +1 -0
  27. package/dist/core/pricing.d.ts +28 -0
  28. package/dist/core/pricing.d.ts.map +1 -0
  29. package/dist/core/pricing.js +48 -0
  30. package/dist/core/pricing.js.map +1 -0
  31. package/dist/core/runtime.d.ts +9 -0
  32. package/dist/core/runtime.d.ts.map +1 -1
  33. package/dist/core/runtime.js +33 -0
  34. package/dist/core/runtime.js.map +1 -1
  35. package/dist/core/sync.d.ts.map +1 -1
  36. package/dist/core/sync.js +3 -0
  37. package/dist/core/sync.js.map +1 -1
  38. package/dist/core/types.d.ts +14 -3
  39. package/dist/core/types.d.ts.map +1 -1
  40. package/dist/core/types.js +1 -1
  41. package/dist/core/types.js.map +1 -1
  42. package/dist/core/webhooks.d.ts.map +1 -1
  43. package/dist/core/webhooks.js +5 -2
  44. package/dist/core/webhooks.js.map +1 -1
  45. package/dist/dashboard/index.js +3 -3
  46. package/dist/hooks/adapters.d.ts.map +1 -1
  47. package/dist/hooks/adapters.js +3 -2
  48. package/dist/hooks/adapters.js.map +1 -1
  49. package/dist/hooks/handler.d.ts.map +1 -1
  50. package/dist/hooks/handler.js +7 -5
  51. package/dist/hooks/handler.js.map +1 -1
  52. package/dist/hooks/types.d.ts +1 -0
  53. package/dist/hooks/types.d.ts.map +1 -1
  54. package/dist/index.d.ts +5 -0
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +12 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/reports/html.d.ts +2 -2
  59. package/dist/reports/html.d.ts.map +1 -1
  60. package/dist/reports/html.js +238 -84
  61. package/dist/reports/html.js.map +1 -1
  62. package/dist/reports/pdf.d.ts.map +1 -1
  63. package/dist/reports/pdf.js +5 -4
  64. package/dist/reports/pdf.js.map +1 -1
  65. package/dist/server/api.d.ts.map +1 -1
  66. package/dist/server/api.js +57 -18
  67. package/dist/server/api.js.map +1 -1
  68. package/dist/server/mcp.d.ts.map +1 -1
  69. package/dist/server/mcp.js +3 -3
  70. package/dist/server/mcp.js.map +1 -1
  71. package/docs/api-reference.md +380 -0
  72. package/docs/deployment.md +140 -0
  73. package/docs/deprecation-policy.md +32 -0
  74. package/docs/migration-guide.md +78 -0
  75. package/docs/security.md +70 -0
  76. package/docs/versioning.md +49 -0
  77. package/package.json +6 -3
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
- * ⏱️🦀 Clawck — HTML Report Generation
4
- * Generates interactive timesheet HTML reports.
3
+ * Clawck — HTML Report Generation
4
+ * Generates interactive timesheet HTML reports with light/dark theme support.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.generateTimesheetHTML = generateTimesheetHTML;
@@ -14,9 +14,9 @@ function generateTimesheetHTML(summary, options) {
14
14
  const showCards = style !== 'table' && style !== 'calendar' && style !== 'visual';
15
15
  const showCalendar = style === 'full' || style === 'visual' || style === 'calendar';
16
16
  const showTable = style === 'full' || style === 'table';
17
- const showGantt = style === 'full' || style === 'visual';
17
+ const showTimeline = style === 'full' || style === 'visual';
18
18
  const showCSV = style === 'full';
19
- const showTabs = [showCalendar, showTable, showGantt, showCSV].filter(Boolean).length > 1;
19
+ const showTabs = [showCalendar, showTable, showTimeline, showCSV].filter(Boolean).length > 1;
20
20
  const isShort = style === 'short';
21
21
  const isText = style === 'text';
22
22
  // Group entries by date for calendar
@@ -27,15 +27,15 @@ function generateTimesheetHTML(summary, options) {
27
27
  d.hours += e.duration_minutes / 60;
28
28
  byDate.set(e.date, d);
29
29
  }
30
- // Build CSV string
31
- const csvHeader = 'Date,Agent,Client,Project,Task,Category,Duration (min),Tokens,Cost,Human Equiv Hrs,Status,Approved';
30
+ // Build CSV string (no wall clock)
31
+ const csvHeader = 'Date,Time,Agent,Client,Project,Task,Category,Total Runtime (min),Tokens In,Tokens Out,Cost,Human Equiv Hrs,Time Saved (hrs),Status,Approved';
32
32
  const csvRows = entries.map(e => {
33
33
  const esc = (s) => `"${s.replace(/"/g, '""')}"`;
34
- return [e.date, esc(e.agent), esc(e.client), esc(e.project), esc(e.task), e.category,
35
- e.duration_minutes.toFixed(2), e.tokens_total, e.cost_usd.toFixed(4),
36
- e.human_equiv_hours.toFixed(2), e.status, e.approved ? 'yes' : 'no'].join(',');
34
+ const time = formatTime(e.start_time);
35
+ return [e.date, time, esc(e.agent), esc(e.client), esc(e.project), esc(e.task), e.category,
36
+ e.duration_minutes.toFixed(2), e.tokens_in, e.tokens_out, e.cost_usd.toFixed(4),
37
+ e.human_equiv_hours.toFixed(2), e.time_saved_hours.toFixed(2), e.status, e.approved ? 'yes' : 'no'].join(',');
37
38
  });
38
- const csvContent = [csvHeader, ...csvRows].join('\\n');
39
39
  // Calendar range
40
40
  const startDate = summary.period_start.split('T')[0];
41
41
  const endDate = summary.period_end.split('T')[0];
@@ -43,8 +43,27 @@ function generateTimesheetHTML(summary, options) {
43
43
  const maxHours = Math.max(...[...byDate.values()].map(d => d.hours), 1);
44
44
  // Build calendar HTML
45
45
  const calendarDays = buildCalendarDays(startDate, endDate, byDate, maxHours);
46
- // Build Gantt data from raw entries
47
- const ganttHTML = buildGanttChart(rawEntries);
46
+ // Build Timeline from raw entries
47
+ const timelineHTML = buildTimeline(rawEntries);
48
+ // Human-friendly generated timestamp
49
+ const generatedAt = new Intl.DateTimeFormat('en-US', { dateStyle: 'long', timeStyle: 'short' }).format(new Date());
50
+ // Total runtime
51
+ const totalRuntimeMin = entries.reduce((s, e) => s + e.duration_minutes, 0);
52
+ // Entries as JSON for calendar click filtering
53
+ const entriesJSON = JSON.stringify(entries.map(e => ({
54
+ date: e.date,
55
+ time: formatTime(e.start_time),
56
+ agent: e.agent,
57
+ client: e.client,
58
+ project: e.project,
59
+ task: e.task,
60
+ category: e.category,
61
+ duration: formatMins(e.duration_minutes),
62
+ tokens_in: e.tokens_in,
63
+ tokens_out: e.tokens_out,
64
+ cost: e.cost_usd.toFixed(4),
65
+ status: e.status,
66
+ })));
48
67
  return `<!DOCTYPE html>
49
68
  <html lang="en">
50
69
  <head>
@@ -55,13 +74,29 @@ function generateTimesheetHTML(summary, options) {
55
74
  <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
56
75
  <style>
57
76
  :root {
77
+ --bg: #ffffff;
78
+ --surface: #f5f5f7;
79
+ --surface2: #eaeaed;
80
+ --border: #d1d5db;
81
+ --text: #1a1a2e;
82
+ --text-dim: #6b7280;
83
+ --accent: #36a2eb;
84
+ --green: #16a34a;
85
+ --red: #dc2626;
86
+ --orange: #ea580c;
87
+ --blue: #2563eb;
88
+ --cyan: #0891b2;
89
+ --purple: #7c3aed;
90
+ --pink: #db2777;
91
+ }
92
+ [data-theme="dark"] {
58
93
  --bg: #0f1117;
59
94
  --surface: #1a1d27;
60
95
  --surface2: #242836;
61
96
  --border: #2d3348;
62
97
  --text: #e4e6ed;
63
98
  --text-dim: #8b8fa3;
64
- --accent: #6c63ff;
99
+ --accent: #36a2eb;
65
100
  --green: #4ade80;
66
101
  --red: #f87171;
67
102
  --orange: #fb923c;
@@ -71,12 +106,17 @@ function generateTimesheetHTML(summary, options) {
71
106
  --pink: #f472b6;
72
107
  }
73
108
  * { margin: 0; padding: 0; box-sizing: border-box; }
74
- body { background: var(--bg); color: var(--text); font-family: 'DM Sans', sans-serif; padding: 2rem; }
109
+ body { background: var(--bg); color: var(--text); font-family: 'DM Sans', sans-serif; padding: 2rem; transition: background 0.3s, color 0.3s; }
75
110
  .mono { font-family: 'JetBrains Mono', monospace; }
76
- h1 { font-size: 1.8rem; font-weight: 700; margin-bottom: 0.25rem; }
111
+ .header-row { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 0.25rem; }
112
+ h1 { font-size: 1.8rem; font-weight: 700; }
77
113
  .subtitle { color: var(--text-dim); font-size: 0.95rem; margin-bottom: 0.5rem; }
78
114
  .meta { color: var(--text-dim); font-size: 0.8rem; margin-bottom: 1.5rem; }
79
115
 
116
+ /* Theme toggle */
117
+ .theme-toggle { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; width: 40px; height: 40px; cursor: pointer; font-size: 1.2rem; display: flex; align-items: center; justify-content: center; transition: background 0.3s; }
118
+ .theme-toggle:hover { background: var(--surface2); }
119
+
80
120
  /* Summary Cards */
81
121
  .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
82
122
  .card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 1.2rem; }
@@ -98,11 +138,18 @@ function generateTimesheetHTML(summary, options) {
98
138
  /* Calendar */
99
139
  .calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
100
140
  .cal-header { font-size: 0.7rem; color: var(--text-dim); text-align: center; padding: 4px; font-weight: 600; }
101
- .cal-day { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 6px; min-height: 60px; font-size: 0.75rem; }
141
+ .cal-day { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 6px; min-height: 60px; font-size: 0.75rem; cursor: default; transition: border-color 0.2s; }
102
142
  .cal-day.empty { background: transparent; border-color: transparent; }
103
143
  .cal-day .day-num { font-weight: 600; margin-bottom: 2px; }
104
144
  .cal-day .day-info { font-family: 'JetBrains Mono', monospace; font-size: 0.65rem; color: var(--text-dim); }
105
- .cal-day.has-entries { border-color: var(--accent); }
145
+ .cal-day.has-entries { border-color: var(--accent); cursor: pointer; }
146
+ .cal-day.has-entries:hover { border-color: var(--blue); background: color-mix(in srgb, var(--accent) 10%, var(--surface)); }
147
+ .cal-day.selected { border-color: var(--blue); border-width: 2px; }
148
+
149
+ /* Calendar detail panel */
150
+ .cal-detail { margin-top: 1rem; padding: 1rem; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; display: none; }
151
+ .cal-detail.active { display: block; }
152
+ .cal-detail h3 { font-size: 0.95rem; margin-bottom: 0.75rem; color: var(--accent); }
106
153
 
107
154
  /* Table */
108
155
  .data-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
@@ -115,23 +162,35 @@ function generateTimesheetHTML(summary, options) {
115
162
  .status-running { color: var(--orange); }
116
163
  .status-failed { color: var(--red); }
117
164
 
118
- /* Gantt */
119
- .gantt-container { overflow-x: auto; }
120
- .gantt-row { display: flex; align-items: center; margin-bottom: 4px; min-height: 28px; }
121
- .gantt-label { width: 120px; flex-shrink: 0; font-size: 0.75rem; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
122
- .gantt-bars { flex: 1; position: relative; height: 22px; background: var(--surface); border-radius: 4px; }
123
- .gantt-bar { position: absolute; height: 18px; top: 2px; border-radius: 3px; opacity: 0.85; min-width: 3px; }
124
- .gantt-bar[title]:hover { opacity: 1; }
125
- .gantt-axis { display: flex; margin-left: 120px; margin-bottom: 8px; }
126
- .gantt-tick { flex: 1; font-size: 0.65rem; color: var(--text-dim); font-family: 'JetBrains Mono', monospace; }
165
+ /* Timeline */
166
+ .timeline { max-width: 800px; }
167
+ .timeline-date { position: sticky; top: 0; z-index: 2; background: var(--bg); padding: 0.75rem 0 0.5rem; font-weight: 700; font-size: 0.95rem; border-bottom: 1px solid var(--border); margin-bottom: 0.5rem; }
168
+ .timeline-card { display: flex; align-items: flex-start; gap: 1rem; padding: 0.75rem 1rem; margin-bottom: 0.5rem; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; border-left: 4px solid var(--accent); }
169
+ .timeline-card .tl-time { font-family: 'JetBrains Mono', monospace; font-size: 0.8rem; color: var(--text-dim); white-space: nowrap; min-width: 110px; }
170
+ .timeline-card .tl-body { flex: 1; min-width: 0; }
171
+ .timeline-card .tl-task { font-weight: 600; font-size: 0.88rem; margin-bottom: 0.25rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
172
+ .timeline-card .tl-meta { font-size: 0.75rem; color: var(--text-dim); display: flex; gap: 0.75rem; flex-wrap: wrap; }
173
+ .timeline-card .tl-pill { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 0.7rem; font-weight: 600; color: #fff; }
174
+ .timeline-card .tl-duration { font-family: 'JetBrains Mono', monospace; font-size: 0.78rem; font-weight: 600; white-space: nowrap; color: var(--accent); }
175
+ .tl-status { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 4px; }
176
+ .tl-status.completed { background: var(--green); }
177
+ .tl-status.running { background: var(--orange); }
178
+ .tl-status.failed { background: var(--red); }
179
+ .tl-status.paused { background: var(--text-dim); }
127
180
 
128
- /* CSV */
129
- .csv-container { position: relative; }
130
- .csv-pre { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; overflow-x: auto; font-family: 'JetBrains Mono', monospace; font-size: 0.75rem; line-height: 1.6; white-space: pre; max-height: 500px; }
131
- .copy-btn { position: absolute; top: 8px; right: 8px; background: var(--accent); color: #fff; border: none; border-radius: 6px; padding: 6px 14px; cursor: pointer; font-size: 0.78rem; font-weight: 500; }
132
- .copy-btn:hover { opacity: 0.9; }
181
+ /* Category pill colors */
182
+ .pill-research { background: var(--blue); }
183
+ .pill-content { background: var(--purple); }
184
+ .pill-code { background: var(--green); }
185
+ .pill-data_entry { background: var(--cyan); }
186
+ .pill-design { background: var(--pink); }
187
+ .pill-communication { background: var(--orange); }
188
+ .pill-analysis { background: #818cf8; }
189
+ .pill-testing { background: #d97706; }
190
+ .pill-planning { background: #059669; }
191
+ .pill-other { background: var(--text-dim); }
133
192
 
134
- /* Category colors */
193
+ /* Category colors for calendar (backwards compat) */
135
194
  .cat-research { background: var(--blue); }
136
195
  .cat-content { background: var(--purple); }
137
196
  .cat-code { background: var(--green); }
@@ -139,33 +198,44 @@ function generateTimesheetHTML(summary, options) {
139
198
  .cat-design { background: var(--pink); }
140
199
  .cat-communication { background: var(--orange); }
141
200
  .cat-analysis { background: #818cf8; }
142
- .cat-testing { background: #fbbf24; }
143
- .cat-planning { background: #34d399; }
201
+ .cat-testing { background: #d97706; }
202
+ .cat-planning { background: #059669; }
144
203
  .cat-other { background: var(--text-dim); }
204
+
205
+ /* CSV */
206
+ .csv-container { position: relative; }
207
+ .csv-pre { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; overflow-x: auto; font-family: 'JetBrains Mono', monospace; font-size: 0.75rem; line-height: 1.6; white-space: pre; max-height: 500px; }
208
+ .csv-btns { position: absolute; top: 8px; right: 8px; display: flex; gap: 6px; }
209
+ .csv-btn { background: var(--accent); color: #fff; border: none; border-radius: 6px; padding: 6px 14px; cursor: pointer; font-size: 0.78rem; font-weight: 500; }
210
+ .csv-btn:hover { opacity: 0.9; }
145
211
  </style>
146
212
  </head>
147
213
  <body>
148
- <h1>${escapeHtml(title)}</h1>
214
+ <div class="header-row">
215
+ <h1>${escapeHtml(title)}</h1>
216
+ <button class="theme-toggle" id="theme-toggle" title="Toggle dark mode">&#9790;</button>
217
+ </div>
149
218
  ${options.clientName ? `<div class="subtitle">Client: ${escapeHtml(options.clientName)}</div>` : ''}
150
219
  <div class="subtitle">Period: ${escapeHtml(options.dateRange)}</div>
151
- <div class="meta">Generated ${new Date().toISOString()}</div>
220
+ <div class="meta">Generated ${escapeHtml(generatedAt)}</div>
152
221
 
153
222
  ${isText ? `<pre class="csv-pre" style="margin-top:1.5rem">${escapeHtml(buildTextReport(summary))}</pre>` : `
154
223
  ${showCards ? `<div class="cards">
155
- <div class="card"><div class="card-label">Wall-Clock Hours</div><div class="card-value mono blue">${summary.total_agent_hours.toFixed(2)}</div></div>
156
- <div class="card"><div class="card-label">Agent Runtime (est.)</div><div class="card-value mono" style="color:#22d3ee">${formatMins(entries.reduce((s, e) => s + (e.agent_runtime_minutes || 0), 0))}</div></div>
157
- <div class="card"><div class="card-label">Human Equiv</div><div class="card-value mono accent">${summary.total_human_equiv_hours.toFixed(2)} hrs</div></div>
224
+ <div class="card"><div class="card-label">Total Runtime</div><div class="card-value mono accent">${formatMins(totalRuntimeMin)}</div></div>
225
+ <div class="card"><div class="card-label">Merged Runtime</div><div class="card-value mono accent">${summary.total_agent_merged_runtime_hours.toFixed(2)} hrs${summary.total_agent_merged_runtime_hours > 0 && summary.total_agent_merged_runtime_hours < summary.total_agent_hours ? ` (${(summary.total_agent_hours / summary.total_agent_merged_runtime_hours).toFixed(1)}x)` : ''}</div></div>
226
+ <div class="card"><div class="card-label">Human Equiv</div><div class="card-value mono blue">${summary.total_human_equiv_hours.toFixed(2)} hrs</div></div>
158
227
  <div class="card"><div class="card-label">Cost</div><div class="card-value mono orange">$${summary.total_cost_usd.toFixed(2)}</div></div>
159
228
  <div class="card"><div class="card-label">Savings</div><div class="card-value mono green">$${summary.total_savings_usd.toFixed(0)}</div></div>
229
+ <div class="card"><div class="card-label">Time Saved</div><div class="card-value mono green">${summary.total_time_saved_hours.toFixed(1)} hrs</div></div>
160
230
  <div class="card"><div class="card-label">Entries</div><div class="card-value mono">${summary.total_entries}</div></div>
161
- <div class="card"><div class="card-label">Tokens</div><div class="card-value mono">${summary.total_tokens.toLocaleString()}</div></div>
231
+ <div class="card"><div class="card-label">Tokens</div><div class="card-value mono">${summary.total_tokens.toLocaleString()} (${summary.total_tokens_in.toLocaleString()} in / ${summary.total_tokens_out.toLocaleString()} out)</div></div>
162
232
  </div>` : ''}
163
233
 
164
234
  ${isShort ? '' : `
165
235
  ${showTabs ? `<div class="tabs">
166
236
  ${showCalendar ? `<div class="tab${showCalendar && !showTable ? ' active' : (showCalendar ? ' active' : '')}" data-tab="calendar">Calendar</div>` : ''}
167
237
  ${showTable ? `<div class="tab${!showCalendar ? ' active' : ''}" data-tab="table">Table</div>` : ''}
168
- ${showGantt ? `<div class="tab" data-tab="gantt">Gantt</div>` : ''}
238
+ ${showTimeline ? `<div class="tab" data-tab="timeline">Timeline</div>` : ''}
169
239
  ${showCSV ? `<div class="tab" data-tab="csv">CSV</div>` : ''}
170
240
  </div>` : ''}
171
241
 
@@ -175,37 +245,47 @@ ${showCalendar ? `<div id="tab-calendar" class="tab-content${showCalendar ? ' ac
175
245
  <div class="cal-header">Wed</div><div class="cal-header">Thu</div><div class="cal-header">Fri</div><div class="cal-header">Sat</div>
176
246
  ${calendarDays}
177
247
  </div>
248
+ <div class="cal-detail" id="cal-detail">
249
+ <h3 id="cal-detail-title"></h3>
250
+ <table class="data-table" id="cal-detail-table">
251
+ <thead><tr><th>Time</th><th>Task</th><th>Category</th><th>Runtime</th><th>Status</th></tr></thead>
252
+ <tbody id="cal-detail-body"></tbody>
253
+ </table>
254
+ </div>
178
255
  </div>` : ''}
179
256
 
180
257
  ${showTable ? `<div id="tab-table" class="tab-content${!showCalendar ? ' active' : ''}">
181
258
  <table class="data-table" id="entries-table">
182
259
  <thead>
183
260
  <tr>
184
- <th data-col="0">Date</th><th data-col="1">Agent</th><th data-col="2">Client</th>
185
- <th data-col="3">Project</th><th data-col="4">Task</th><th data-col="5">Category</th>
186
- <th data-col="6">Wall Clock</th><th data-col="7">Agent Runtime</th><th data-col="8">Tokens</th><th data-col="9">Cost</th>
187
- <th data-col="10">Human Equiv</th><th data-col="11">Status</th><th data-col="12">Approved</th>
261
+ <th data-col="0">Date</th><th data-col="1">Time</th><th data-col="2">Agent</th><th data-col="3">Client</th>
262
+ <th data-col="4">Project</th><th data-col="5">Task</th><th data-col="6">Category</th>
263
+ <th data-col="7">Runtime</th><th data-col="8">Tokens In</th><th data-col="9">Tokens Out</th><th data-col="10">Cost</th>
264
+ <th data-col="11">Human Equiv</th><th data-col="12">Time Saved</th><th data-col="13">Status</th><th data-col="14">Approved</th>
188
265
  </tr>
189
266
  </thead>
190
267
  <tbody>
191
268
  ${entries.map(e => `<tr>
192
- <td class="mono">${e.date}</td><td>${escapeHtml(e.agent)}</td><td>${escapeHtml(e.client)}</td>
269
+ <td class="mono">${e.date}</td><td class="mono">${formatTime(e.start_time)}</td><td>${escapeHtml(e.agent)}</td><td>${escapeHtml(e.client)}</td>
193
270
  <td>${escapeHtml(e.project)}</td><td title="${escapeHtml(e.task)}">${escapeHtml(e.task)}</td><td>${e.category}</td>
194
- <td class="mono">${formatMins(e.duration_minutes)}</td><td class="mono">${e.agent_runtime_minutes != null ? formatMins(e.agent_runtime_minutes) : '-'}</td><td class="mono">${e.tokens_total.toLocaleString()}</td>
195
- <td class="mono">$${e.cost_usd.toFixed(4)}</td><td class="mono">${e.human_equiv_hours.toFixed(2)}h</td>
271
+ <td class="mono">${formatMins(e.duration_minutes)}</td><td class="mono">${e.tokens_in.toLocaleString()}</td><td class="mono">${e.tokens_out.toLocaleString()}</td>
272
+ <td class="mono">$${e.cost_usd.toFixed(4)}</td><td class="mono">${e.human_equiv_hours.toFixed(2)}h</td><td class="mono">${e.time_saved_hours.toFixed(2)}h</td>
196
273
  <td class="status-${e.status}">${e.status}</td><td>${e.approved ? 'Yes' : '-'}</td>
197
274
  </tr>`).join('\n')}
198
275
  </tbody>
199
276
  </table>
200
277
  </div>` : ''}
201
278
 
202
- ${showGantt ? `<div id="tab-gantt" class="tab-content">
203
- ${ganttHTML}
279
+ ${showTimeline ? `<div id="tab-timeline" class="tab-content">
280
+ ${timelineHTML}
204
281
  </div>` : ''}
205
282
 
206
283
  ${showCSV ? `<div id="tab-csv" class="tab-content">
207
284
  <div class="csv-container">
208
- <button class="copy-btn" onclick="copyCSV()">Copy</button>
285
+ <div class="csv-btns">
286
+ <button class="csv-btn" onclick="copyCSV()">Copy</button>
287
+ <button class="csv-btn" onclick="downloadCSV()">Download</button>
288
+ </div>
209
289
  <pre class="csv-pre" id="csv-data">${escapeHtml([csvHeader, ...csvRows].join('\n'))}</pre>
210
290
  </div>
211
291
  </div>` : ''}
@@ -213,13 +293,27 @@ ${showCSV ? `<div id="tab-csv" class="tab-content">
213
293
  `}
214
294
 
215
295
  <script>
296
+ // Theme toggle
297
+ (function() {
298
+ const toggle = document.getElementById('theme-toggle');
299
+ const html = document.documentElement;
300
+ const saved = localStorage.getItem('clawck-theme');
301
+ if (saved === 'dark') { html.dataset.theme = 'dark'; toggle.textContent = '\\u2600'; }
302
+ toggle.addEventListener('click', () => {
303
+ const isDark = html.dataset.theme === 'dark';
304
+ if (isDark) { delete html.dataset.theme; localStorage.setItem('clawck-theme', 'light'); toggle.textContent = '\\u263E'; }
305
+ else { html.dataset.theme = 'dark'; localStorage.setItem('clawck-theme', 'dark'); toggle.textContent = '\\u2600'; }
306
+ });
307
+ })();
308
+
216
309
  // Tab switching
217
310
  document.querySelectorAll('.tab').forEach(tab => {
218
311
  tab.addEventListener('click', () => {
219
312
  document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
220
313
  document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
221
314
  tab.classList.add('active');
222
- document.getElementById('tab-' + tab.dataset.tab).classList.add('active');
315
+ const el = document.getElementById('tab-' + tab.dataset.tab);
316
+ if (el) el.classList.add('active');
223
317
  });
224
318
  });
225
319
 
@@ -229,6 +323,7 @@ document.querySelectorAll('#entries-table th').forEach(th => {
229
323
  th.addEventListener('click', () => {
230
324
  const col = parseInt(th.dataset.col);
231
325
  const tbody = document.querySelector('#entries-table tbody');
326
+ if (!tbody) return;
232
327
  const rows = Array.from(tbody.querySelectorAll('tr'));
233
328
  rows.sort((a, b) => {
234
329
  const av = a.children[col].textContent.trim();
@@ -243,34 +338,70 @@ document.querySelectorAll('#entries-table th').forEach(th => {
243
338
  });
244
339
  });
245
340
 
341
+ // Calendar click — show detail panel
342
+ (function() {
343
+ const entries = ${entriesJSON};
344
+ document.querySelectorAll('.cal-day.has-entries').forEach(day => {
345
+ day.addEventListener('click', () => {
346
+ const date = day.dataset.date;
347
+ if (!date) return;
348
+ document.querySelectorAll('.cal-day.selected').forEach(d => d.classList.remove('selected'));
349
+ day.classList.add('selected');
350
+ const detail = document.getElementById('cal-detail');
351
+ const title = document.getElementById('cal-detail-title');
352
+ const tbody = document.getElementById('cal-detail-body');
353
+ if (!detail || !title || !tbody) return;
354
+ const filtered = entries.filter(e => e.date === date);
355
+ title.textContent = new Date(date + 'T00:00:00').toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
356
+ tbody.innerHTML = filtered.map(e =>
357
+ '<tr><td class="mono">' + e.time + '</td><td>' + e.task + '</td><td>' + e.category + '</td><td class="mono">' + e.duration + '</td><td class="status-' + e.status + '">' + e.status + '</td></tr>'
358
+ ).join('');
359
+ detail.classList.add('active');
360
+ });
361
+ });
362
+ })();
363
+
246
364
  // Copy CSV
247
365
  function copyCSV() {
248
366
  const el = document.getElementById('csv-data');
249
367
  if (!el) return;
250
- const text = el.textContent;
251
- navigator.clipboard.writeText(text).then(() => {
252
- const btn = document.querySelector('.copy-btn');
368
+ navigator.clipboard.writeText(el.textContent).then(() => {
369
+ const btn = event.target;
253
370
  btn.textContent = 'Copied!';
254
371
  setTimeout(() => btn.textContent = 'Copy', 2000);
255
372
  });
256
373
  }
374
+
375
+ // Download CSV
376
+ function downloadCSV() {
377
+ const el = document.getElementById('csv-data');
378
+ if (!el) return;
379
+ const blob = new Blob([el.textContent], { type: 'text/csv' });
380
+ const url = URL.createObjectURL(blob);
381
+ const a = document.createElement('a');
382
+ a.href = url;
383
+ a.download = 'clawck-report.csv';
384
+ a.click();
385
+ URL.revokeObjectURL(url);
386
+ }
257
387
  </script>
258
388
  </body>
259
389
  </html>`;
260
390
  }
261
391
  function buildTextReport(summary) {
262
- const totalAgentRuntimeMin = summary.entries.reduce((s, e) => s + (e.agent_runtime_minutes || 0), 0);
392
+ const totalRuntimeMin = summary.entries.reduce((s, e) => s + e.duration_minutes, 0);
263
393
  const lines = [
264
394
  `Clawck Timesheet Report`,
265
395
  `${'─'.repeat(50)}`,
266
- `Wall-clock hours: ${summary.total_agent_hours.toFixed(2)} hrs`,
267
- totalAgentRuntimeMin > 0 ? `Agent runtime: ${formatMins(totalAgentRuntimeMin)} (estimated)` : null,
396
+ `Total runtime: ${formatMins(totalRuntimeMin)}`,
397
+ `Merged runtime: ${summary.total_agent_merged_runtime_hours.toFixed(2)} hrs${summary.total_agent_merged_runtime_hours > 0 && summary.total_agent_merged_runtime_hours < summary.total_agent_hours ? ` (${(summary.total_agent_hours / summary.total_agent_merged_runtime_hours).toFixed(1)}x parallelization)` : ''}`,
268
398
  `Human equiv: ${summary.total_human_equiv_hours.toFixed(2)} hrs`,
269
399
  `Agent cost: $${summary.total_cost_usd.toFixed(2)}`,
270
400
  `Est. savings: $${summary.total_savings_usd.toFixed(0)}`,
401
+ `Time saved: ${summary.total_time_saved_hours.toFixed(1)} hrs`,
271
402
  `Total entries: ${summary.total_entries}`,
272
- `Total tokens: ${summary.total_tokens.toLocaleString()}`,
273
- ].filter(Boolean);
403
+ `Total tokens: ${summary.total_tokens.toLocaleString()} (${summary.total_tokens_in.toLocaleString()} in / ${summary.total_tokens_out.toLocaleString()} out)`,
404
+ ];
274
405
  return lines.join('\n');
275
406
  }
276
407
  function escapeHtml(str) {
@@ -285,6 +416,15 @@ function formatMins(mins) {
285
416
  const m = Math.round(mins % 60);
286
417
  return m > 0 ? `${h}h ${m}m` : `${h}h`;
287
418
  }
419
+ function formatTime(isoStr) {
420
+ try {
421
+ const d = new Date(isoStr);
422
+ return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
423
+ }
424
+ catch {
425
+ return '--:--';
426
+ }
427
+ }
288
428
  function buildCalendarDays(startStr, endStr, byDate, maxHours) {
289
429
  const start = new Date(startStr + 'T00:00:00');
290
430
  const end = new Date(endStr + 'T00:00:00');
@@ -303,8 +443,8 @@ function buildCalendarDays(startStr, endStr, byDate, maxHours) {
303
443
  else {
304
444
  const hasEntries = data && data.count > 0;
305
445
  const intensity = hasEntries ? Math.min(data.hours / maxHours, 1) : 0;
306
- const bgStyle = hasEntries ? `background: rgba(108,99,255,${0.1 + intensity * 0.5})` : '';
307
- days.push(`<div class="cal-day${hasEntries ? ' has-entries' : ''}" style="${bgStyle}">
446
+ const bgStyle = hasEntries ? `background: rgba(54,162,235,${0.08 + intensity * 0.3})` : '';
447
+ days.push(`<div class="cal-day${hasEntries ? ' has-entries' : ''}" data-date="${dateStr}" style="${bgStyle}">
308
448
  <div class="day-num">${current.getDate()}</div>
309
449
  ${hasEntries ? `<div class="day-info">${data.count} entries<br>${data.hours.toFixed(1)}h</div>` : ''}
310
450
  </div>`);
@@ -315,7 +455,7 @@ function buildCalendarDays(startStr, endStr, byDate, maxHours) {
315
455
  }
316
456
  return days.join('\n');
317
457
  }
318
- function buildGanttChart(rawEntries) {
458
+ function buildTimeline(rawEntries) {
319
459
  if (rawEntries.length === 0)
320
460
  return '<p style="color:var(--text-dim)">No entries to display.</p>';
321
461
  // Group by date
@@ -326,28 +466,42 @@ function buildGanttChart(rawEntries) {
326
466
  arr.push(e);
327
467
  byDate.set(date, arr);
328
468
  }
329
- const categoryColors = {
330
- research: 'cat-research', content: 'cat-content', code: 'cat-code',
331
- data_entry: 'cat-data_entry', design: 'cat-design', communication: 'cat-communication',
332
- analysis: 'cat-analysis', testing: 'cat-testing', planning: 'cat-planning', other: 'cat-other',
333
- };
334
- const sortedDates = [...byDate.keys()].sort();
335
- const rows = [];
336
- // Axis
337
- rows.push(`<div class="gantt-axis">${Array.from({ length: 24 }, (_, i) => `<div class="gantt-tick">${String(i).padStart(2, '0')}</div>`).join('')}</div>`);
338
- for (const date of sortedDates.slice(-14)) { // Limit to last 14 days
469
+ const sortedDates = [...byDate.keys()].sort().reverse();
470
+ const sections = [];
471
+ for (const date of sortedDates) {
339
472
  const dateEntries = byDate.get(date);
340
- const bars = dateEntries.map(e => {
341
- const startHour = new Date(e.start).getHours() + new Date(e.start).getMinutes() / 60;
342
- const endTime = e.end ? new Date(e.end) : new Date();
343
- const durHours = (endTime.getTime() - new Date(e.start).getTime()) / 3600000;
344
- const left = (startHour / 24) * 100;
345
- const width = Math.max((durHours / 24) * 100, 0.5);
346
- const cls = categoryColors[e.category] || 'cat-other';
347
- return `<div class="gantt-bar ${cls}" style="left:${left}%;width:${width}%" title="${escapeHtml(e.task)} (${e.category}, ${formatMins(durHours * 60)})"></div>`;
348
- }).join('');
349
- rows.push(`<div class="gantt-row"><div class="gantt-label">${date}</div><div class="gantt-bars">${bars}</div></div>`);
473
+ // Sort by start time
474
+ dateEntries.sort((a, b) => b.start.localeCompare(a.start));
475
+ const dateLabel = new Date(date + 'T00:00:00').toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' });
476
+ const cards = dateEntries.map(e => {
477
+ const startTime = formatTime(e.start);
478
+ const endTime = e.end ? formatTime(e.end) : 'now';
479
+ const durMs = e.agent_runtime_ms ?? e.wall_clock_ms ?? (e.end ? new Date(e.end).getTime() - new Date(e.start).getTime() : Date.now() - new Date(e.start).getTime());
480
+ const durMin = durMs / 60000;
481
+ const pillCls = `pill-${e.category}`;
482
+ return `<div class="timeline-card" style="border-left-color:var(--${getCategoryColor(e.category)})">
483
+ <div class="tl-time">${startTime} - ${endTime}</div>
484
+ <div class="tl-body">
485
+ <div class="tl-task"><span class="tl-status ${e.status}"></span>${escapeHtml(e.task)}</div>
486
+ <div class="tl-meta">
487
+ <span class="tl-pill ${pillCls}">${e.category}</span>
488
+ ${e.project !== 'default' ? `<span>${escapeHtml(e.project)}</span>` : ''}
489
+ ${e.client !== 'default' ? `<span>${escapeHtml(e.client)}</span>` : ''}
490
+ </div>
491
+ </div>
492
+ <div class="tl-duration">${formatMins(durMin)}</div>
493
+ </div>`;
494
+ }).join('\n');
495
+ sections.push(`<div class="timeline-date">${dateLabel}</div>\n${cards}`);
350
496
  }
351
- return `<div class="gantt-container">${rows.join('\n')}</div>`;
497
+ return `<div class="timeline">${sections.join('\n')}</div>`;
498
+ }
499
+ function getCategoryColor(category) {
500
+ const map = {
501
+ research: 'blue', content: 'purple', code: 'green', data_entry: 'cyan',
502
+ design: 'pink', communication: 'orange', analysis: 'purple',
503
+ testing: 'orange', planning: 'green', other: 'text-dim',
504
+ };
505
+ return map[category] || 'accent';
352
506
  }
353
507
  //# sourceMappingURL=html.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/reports/html.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/reports/html.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pdf.d.ts","sourceRoot":"","sources":["../../src/reports/pdf.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAsJf"}
1
+ {"version":3,"file":"pdf.d.ts","sourceRoot":"","sources":["../../src/reports/pdf.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAuJf"}
@@ -40,15 +40,16 @@ function generateTimesheetPDF(summary, options) {
40
40
  doc.fontSize(14).font('Helvetica-Bold').text('Summary');
41
41
  doc.moveDown(0.3);
42
42
  doc.fontSize(10).font('Helvetica');
43
- const totalAgentRuntimeMin = summary.entries.reduce((s, e) => s + (e.agent_runtime_minutes || 0), 0);
43
+ const totalRuntimeMin = summary.entries.reduce((s, e) => s + e.duration_minutes, 0);
44
44
  const stats = [
45
- ['Wall-Clock Hours', `${summary.total_agent_hours.toFixed(2)} hrs`],
46
- ['Agent Runtime (est.)', totalAgentRuntimeMin > 0 ? `${(totalAgentRuntimeMin / 60).toFixed(2)} hrs` : 'N/A'],
45
+ ['Total Runtime', `${(totalRuntimeMin / 60).toFixed(2)} hrs`],
46
+ ['Merged Runtime', `${summary.total_agent_merged_runtime_hours.toFixed(2)} hrs${summary.total_agent_merged_runtime_hours > 0 && summary.total_agent_merged_runtime_hours < summary.total_agent_hours ? ` (${(summary.total_agent_hours / summary.total_agent_merged_runtime_hours).toFixed(1)}x parallelization)` : ''}`],
47
47
  ['Human Equiv Hours', `${summary.total_human_equiv_hours.toFixed(2)} hrs`],
48
48
  ['Agent Cost', `$${summary.total_cost_usd.toFixed(2)}`],
49
49
  ['Est. Savings', `$${summary.total_savings_usd.toFixed(0)}`],
50
+ ['Time Saved', `${summary.total_time_saved_hours.toFixed(1)} hrs`],
50
51
  ['Total Entries', String(summary.total_entries)],
51
- ['Total Tokens', summary.total_tokens.toLocaleString()],
52
+ ['Total Tokens', `${summary.total_tokens.toLocaleString()} (${summary.total_tokens_in.toLocaleString()} in / ${summary.total_tokens_out.toLocaleString()} out)`],
52
53
  ];
53
54
  for (const [label, value] of stats) {
54
55
  doc.text(`${label}: ${value}`);