clawck 0.1.3 → 0.4.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.
Files changed (106) hide show
  1. package/README.md +251 -174
  2. package/dist/cli/index.js +947 -87
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/core/atp.d.ts +31 -0
  5. package/dist/core/atp.d.ts.map +1 -0
  6. package/dist/core/atp.js +96 -0
  7. package/dist/core/atp.js.map +1 -0
  8. package/dist/core/benchmarks.d.ts +20 -0
  9. package/dist/core/benchmarks.d.ts.map +1 -0
  10. package/dist/core/benchmarks.js +86 -0
  11. package/dist/core/benchmarks.js.map +1 -0
  12. package/dist/core/clawck.d.ts +39 -3
  13. package/dist/core/clawck.d.ts.map +1 -1
  14. package/dist/core/clawck.js +140 -18
  15. package/dist/core/clawck.js.map +1 -1
  16. package/dist/core/database.d.ts +16 -1
  17. package/dist/core/database.d.ts.map +1 -1
  18. package/dist/core/database.js +177 -8
  19. package/dist/core/database.js.map +1 -1
  20. package/dist/core/patterns.d.ts +7 -0
  21. package/dist/core/patterns.d.ts.map +1 -0
  22. package/dist/core/patterns.js +36 -0
  23. package/dist/core/patterns.js.map +1 -0
  24. package/dist/core/personal.d.ts +26 -0
  25. package/dist/core/personal.d.ts.map +1 -0
  26. package/dist/core/personal.js +60 -0
  27. package/dist/core/personal.js.map +1 -0
  28. package/dist/core/runtime.d.ts +17 -0
  29. package/dist/core/runtime.d.ts.map +1 -0
  30. package/dist/core/runtime.js +43 -0
  31. package/dist/core/runtime.js.map +1 -0
  32. package/dist/core/types.d.ts +93 -2
  33. package/dist/core/types.d.ts.map +1 -1
  34. package/dist/core/types.js +9 -2
  35. package/dist/core/types.js.map +1 -1
  36. package/dist/core/webhooks.d.ts +22 -0
  37. package/dist/core/webhooks.d.ts.map +1 -0
  38. package/dist/core/webhooks.js +70 -0
  39. package/dist/core/webhooks.js.map +1 -0
  40. package/dist/hooks/adapters.d.ts +8 -0
  41. package/dist/hooks/adapters.d.ts.map +1 -0
  42. package/dist/hooks/adapters.js +152 -0
  43. package/dist/hooks/adapters.js.map +1 -0
  44. package/dist/hooks/handler.d.ts +9 -0
  45. package/dist/hooks/handler.d.ts.map +1 -0
  46. package/dist/hooks/handler.js +93 -0
  47. package/dist/hooks/handler.js.map +1 -0
  48. package/dist/hooks/index.d.ts +10 -0
  49. package/dist/hooks/index.d.ts.map +1 -0
  50. package/dist/hooks/index.js +23 -0
  51. package/dist/hooks/index.js.map +1 -0
  52. package/dist/hooks/install.d.ts +16 -0
  53. package/dist/hooks/install.d.ts.map +1 -0
  54. package/dist/hooks/install.js +247 -0
  55. package/dist/hooks/install.js.map +1 -0
  56. package/dist/hooks/session.d.ts +10 -0
  57. package/dist/hooks/session.d.ts.map +1 -0
  58. package/dist/hooks/session.js +72 -0
  59. package/dist/hooks/session.js.map +1 -0
  60. package/dist/hooks/stdin.d.ts +6 -0
  61. package/dist/hooks/stdin.d.ts.map +1 -0
  62. package/dist/hooks/stdin.js +38 -0
  63. package/dist/hooks/stdin.js.map +1 -0
  64. package/dist/hooks/types.d.ts +26 -0
  65. package/dist/hooks/types.d.ts.map +1 -0
  66. package/dist/hooks/types.js +7 -0
  67. package/dist/hooks/types.js.map +1 -0
  68. package/dist/index.d.ts +10 -0
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +19 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/reports/html.d.ts +14 -0
  73. package/dist/reports/html.d.ts.map +1 -0
  74. package/dist/reports/html.js +353 -0
  75. package/dist/reports/html.js.map +1 -0
  76. package/dist/reports/pdf.d.ts +14 -0
  77. package/dist/reports/pdf.d.ts.map +1 -0
  78. package/dist/reports/pdf.js +177 -0
  79. package/dist/reports/pdf.js.map +1 -0
  80. package/dist/reports/periods.d.ts +18 -0
  81. package/dist/reports/periods.d.ts.map +1 -0
  82. package/dist/reports/periods.js +55 -0
  83. package/dist/reports/periods.js.map +1 -0
  84. package/dist/server/api.d.ts.map +1 -1
  85. package/dist/server/api.js +156 -2
  86. package/dist/server/api.js.map +1 -1
  87. package/dist/server/mcp.d.ts.map +1 -1
  88. package/dist/server/mcp.js +31 -10
  89. package/dist/server/mcp.js.map +1 -1
  90. package/docs/atp-schema.json +298 -0
  91. package/docs/atp-spec-v0.2.md +216 -0
  92. package/docs/benchmarks-sources.md +202 -0
  93. package/docs/platform-testing-guide.md +423 -0
  94. package/docs/skills/clawck-setup.md +131 -0
  95. package/docs/skills/clawck-usage.md +148 -0
  96. package/docs/snippets/claude-md.txt +33 -0
  97. package/docs/snippets/hooks-claude.json +24 -0
  98. package/docs/snippets/hooks-cline.txt +10 -0
  99. package/docs/snippets/hooks-codex.json +16 -0
  100. package/docs/snippets/hooks-cursor.json +16 -0
  101. package/docs/snippets/hooks-gemini.json +16 -0
  102. package/docs/snippets/hooks-windsurf.json +16 -0
  103. package/docs/snippets/mcp-config.json +7 -0
  104. package/docs/snippets/openclaw-agent-md.txt +18 -0
  105. package/docs/snippets/openclaw-heartbeat-md.txt +17 -0
  106. package/package.json +4 -2
@@ -8,12 +8,20 @@ exports.Clawck = void 0;
8
8
  const uuid_1 = require("uuid");
9
9
  const types_1 = require("./types");
10
10
  const database_1 = require("./database");
11
+ const webhooks_1 = require("./webhooks");
12
+ const patterns_1 = require("./patterns");
13
+ const runtime_1 = require("./runtime");
14
+ const personal_1 = require("./personal");
15
+ const benchmarks_1 = require("./benchmarks");
16
+ const uuid_2 = require("uuid");
11
17
  class Clawck {
12
18
  _db;
13
19
  config;
20
+ webhookManager;
14
21
  constructor(config = {}) {
15
22
  this.config = { ...types_1.DEFAULT_CONFIG, ...config };
16
23
  this._db = new database_1.ClawckDB(this.config);
24
+ this.webhookManager = new webhooks_1.WebhookManager(this.config);
17
25
  }
18
26
  /** Wait for the database to be ready (call once before first operation) */
19
27
  async ready() {
@@ -25,16 +33,28 @@ class Clawck {
25
33
  upsert(entry) {
26
34
  return this._db.upsert(entry);
27
35
  }
36
+ // ─── Patterns ────────────────────────────────────────────
37
+ getPatterns() {
38
+ return this.config.patterns || patterns_1.DEFAULT_PATTERNS;
39
+ }
40
+ getPattern(name) {
41
+ return this.getPatterns().find(p => p.name === name);
42
+ }
43
+ // ─── Approve ────────────────────────────────────────────
44
+ approve(id) {
45
+ return this._db.update(id, { approved: true });
46
+ }
28
47
  // ─── Start a Task ──────────────────────────────────────
29
48
  start(input) {
49
+ const pat = input.pattern ? this.getPattern(input.pattern) : (this.config.default_pattern ? this.getPattern(this.config.default_pattern) : undefined);
30
50
  const entry = {
31
51
  id: (0, uuid_1.v4)(),
32
- agent: input.agent || this.config.default_agent || 'unknown-agent',
33
- model: input.model || this.config.default_model || 'unknown',
34
- client: input.client || this.config.default_client || 'default',
35
- project: input.project || this.config.default_project || 'default',
52
+ agent: input.agent || pat?.agent || this.config.default_agent || 'unknown-agent',
53
+ model: input.model || pat?.model || this.config.default_model || 'unknown',
54
+ client: input.client || pat?.client || this.config.default_client || 'default',
55
+ project: input.project || pat?.project || this.config.default_project || 'default',
36
56
  task: input.task,
37
- category: input.category || 'other',
57
+ category: input.category || pat?.category || 'other',
38
58
  start: new Date().toISOString(),
39
59
  end: null,
40
60
  status: 'running',
@@ -43,47 +63,81 @@ class Clawck {
43
63
  cost_usd: 0,
44
64
  tool_calls: 0,
45
65
  summary: '',
46
- tags: input.tags || [],
66
+ tags: input.tags || pat?.tags || [],
47
67
  source: this.config.default_source || 'clawck',
48
68
  spec_version: types_1.SPEC_VERSION,
69
+ approved: false,
49
70
  };
50
71
  return this._db.insert(entry);
51
72
  }
52
73
  // ─── Stop a Task ───────────────────────────────────────
53
74
  stop(input) {
54
- return this._db.update(input.id, {
55
- end: new Date().toISOString(),
56
- status: input.status || 'completed',
75
+ const status = input.status || 'completed';
76
+ const endTime = new Date().toISOString();
77
+ // Build updates
78
+ const updates = {
79
+ end: endTime,
80
+ status,
57
81
  summary: input.summary || '',
58
82
  tokens_in: input.tokens_in,
59
83
  tokens_out: input.tokens_out,
60
84
  cost_usd: input.cost_usd,
61
85
  tool_calls: input.tool_calls,
62
- });
86
+ };
87
+ // Calculate wall clock and agent runtime
88
+ const existing = this._db.getById(input.id);
89
+ if (existing) {
90
+ updates.wall_clock_ms = (0, runtime_1.calculateWallClock)(existing.start, endTime);
91
+ const tokensOut = input.tokens_out ?? existing.tokens_out ?? 0;
92
+ const toolCalls = input.tool_calls ?? existing.tool_calls ?? 0;
93
+ const model = existing.model || 'unknown';
94
+ if (tokensOut > 0 || toolCalls > 0) {
95
+ const runtimeConfig = this.getRuntimeConfig();
96
+ updates.agent_runtime_ms = (0, runtime_1.estimateAgentRuntime)({ tokens_out: tokensOut, model, tool_calls: toolCalls }, runtimeConfig);
97
+ }
98
+ }
99
+ const entry = this._db.update(input.id, updates);
100
+ if (entry) {
101
+ const event = status === 'failed' ? 'task_failed' : 'task_completed';
102
+ this.webhookManager.fire(event, { entry });
103
+ }
104
+ return entry;
63
105
  }
64
106
  // ─── Log a Completed Task (retroactive) ─────────────────
65
107
  log(input) {
66
108
  const end = new Date();
67
109
  const start = new Date(end.getTime() - (input.duration_minutes * 60000));
110
+ const pat = input.pattern ? this.getPattern(input.pattern) : (this.config.default_pattern ? this.getPattern(this.config.default_pattern) : undefined);
111
+ const tokensOut = input.tokens_out || 0;
112
+ const toolCalls = input.tool_calls || 0;
113
+ const model = input.model || pat?.model || this.config.default_model || 'unknown';
114
+ let agentRuntimeMs = input.agent_runtime_ms ?? null;
115
+ if (agentRuntimeMs === null && (tokensOut > 0 || toolCalls > 0)) {
116
+ const runtimeConfig = this.getRuntimeConfig();
117
+ agentRuntimeMs = (0, runtime_1.estimateAgentRuntime)({ tokens_out: tokensOut, model, tool_calls: toolCalls }, runtimeConfig);
118
+ }
68
119
  const entry = {
69
120
  id: (0, uuid_1.v4)(),
70
- agent: input.agent || this.config.default_agent || 'unknown-agent',
71
- model: input.model || this.config.default_model || 'unknown',
72
- client: input.client || this.config.default_client || 'default',
73
- project: input.project || this.config.default_project || 'default',
121
+ agent: input.agent || pat?.agent || this.config.default_agent || 'unknown-agent',
122
+ model,
123
+ client: input.client || pat?.client || this.config.default_client || 'default',
124
+ project: input.project || pat?.project || this.config.default_project || 'default',
74
125
  task: input.task,
75
- category: input.category || 'other',
126
+ category: input.category || pat?.category || 'other',
76
127
  start: start.toISOString(),
77
128
  end: end.toISOString(),
78
129
  status: 'completed',
79
130
  tokens_in: input.tokens_in || 0,
80
- tokens_out: input.tokens_out || 0,
131
+ tokens_out: tokensOut,
81
132
  cost_usd: input.cost_usd || 0,
82
- tool_calls: input.tool_calls || 0,
133
+ tool_calls: toolCalls,
83
134
  summary: input.summary || '',
84
- tags: input.tags || [],
135
+ tags: input.tags || pat?.tags || [],
85
136
  source: this.config.default_source || 'clawck',
86
137
  spec_version: types_1.SPEC_VERSION,
138
+ approved: false,
139
+ agent_runtime_ms: agentRuntimeMs,
140
+ wall_clock_ms: input.duration_minutes * 60000,
87
141
  };
88
142
  return this._db.insert(entry);
89
143
  }
@@ -117,8 +171,76 @@ class Clawck {
117
171
  projects() { return this._db.getProjects(); }
118
172
  agents() { return this._db.getAgents(); }
119
173
  stats() { return this._db.getStats(); }
174
+ // ─── Personal Baselines ──────────────────────────────
175
+ addBaseline(input) {
176
+ const baseline = {
177
+ id: (0, uuid_2.v4)(),
178
+ category: input.category,
179
+ task_type: input.task_type,
180
+ description: input.description || '',
181
+ my_minutes: input.my_minutes,
182
+ created_at: new Date().toISOString(),
183
+ updated_at: new Date().toISOString(),
184
+ };
185
+ return this._db.insertBaseline(baseline);
186
+ }
187
+ removeBaseline(id) {
188
+ return this._db.deleteBaseline(id);
189
+ }
190
+ getBaselines() {
191
+ return this._db.getBaselines();
192
+ }
193
+ compareEntryById(entryId) {
194
+ const entry = this._db.getById(entryId);
195
+ if (!entry)
196
+ return null;
197
+ const baselines = this._db.getBaselines();
198
+ const personalRate = this.config.personal_rate_usd || 50;
199
+ return (0, personal_1.compareEntry)(entry, baselines, benchmarks_1.INDUSTRY_BENCHMARKS, personalRate);
200
+ }
201
+ // ─── Report Persistence ──────────────────────────────
202
+ saveReport(opts) {
203
+ const report = {
204
+ id: (0, uuid_2.v4)(),
205
+ name: opts.name,
206
+ period: opts.period,
207
+ period_start: opts.period_start,
208
+ period_end: opts.period_end,
209
+ style: opts.style,
210
+ format: opts.format,
211
+ content: opts.content,
212
+ metadata: opts.metadata,
213
+ created_at: new Date().toISOString(),
214
+ };
215
+ return this._db.insertReport(report);
216
+ }
217
+ listReports(limit, offset) {
218
+ return this._db.listReports(limit, offset);
219
+ }
220
+ getReport(id) {
221
+ return this._db.getReportContent(id);
222
+ }
223
+ deleteReport(id) {
224
+ return this._db.deleteReport(id);
225
+ }
226
+ // ─── Runtime Config ──────────────────────────────────
227
+ getRuntimeConfig() {
228
+ const overrides = this.config.runtime_estimation;
229
+ if (!overrides)
230
+ return runtime_1.DEFAULT_RUNTIME_CONFIG;
231
+ return {
232
+ model_tokens_per_second: {
233
+ ...runtime_1.DEFAULT_RUNTIME_CONFIG.model_tokens_per_second,
234
+ ...(overrides.model_tokens_per_second || {}),
235
+ },
236
+ default_tokens_per_second: overrides.default_tokens_per_second ?? runtime_1.DEFAULT_RUNTIME_CONFIG.default_tokens_per_second,
237
+ avg_tool_duration_ms: overrides.avg_tool_duration_ms ?? runtime_1.DEFAULT_RUNTIME_CONFIG.avg_tool_duration_ms,
238
+ };
239
+ }
120
240
  // ─── Cleanup ───────────────────────────────────────────
241
+ get webhooks() { return this.webhookManager; }
121
242
  close() {
243
+ this.webhookManager.stopIdleMonitor();
122
244
  this._db.close();
123
245
  }
124
246
  }
@@ -1 +1 @@
1
- {"version":3,"file":"clawck.js","sourceRoot":"","sources":["../../src/core/clawck.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clawck.js","sourceRoot":"","sources":["../../src/core/clawck.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAAkC;AAClC,mCAIiB;AACjB,yCAAsC;AACtC,yCAA4C;AAC5C,yCAA8C;AAC9C,uCAAqH;AACrH,yCAAsF;AACtF,6CAAsE;AACtE,+BAAoC;AAEpC,MAAa,MAAM;IACT,GAAG,CAAW;IACd,MAAM,CAAe;IACrB,cAAc,CAAiB;IAEvC,YAAY,SAAgC,EAAE;QAC5C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,sBAAc,EAAE,GAAG,MAAM,EAAE,CAAC;QAC/C,IAAI,CAAC,GAAG,GAAG,IAAI,mBAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,IAAI,yBAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,QAAQ,KAAe,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAE7C,yDAAyD;IAEzD,MAAM,CAAC,KAAkB;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,4DAA4D;IAE5D,WAAW;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,2BAAgB,CAAC;IAClD,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,2DAA2D;IAE3D,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,0DAA0D;IAE1D,KAAK,CAAC,KAA8C;QAClD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAEtJ,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,IAAA,SAAI,GAAE;YACV,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,eAAe;YAChF,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS;YAC1E,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,SAAS;YAC9E,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,GAAG,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,SAAS;YAClF,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,GAAG,EAAE,QAAQ,IAAI,OAAO;YACpD,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC/B,GAAG,EAAE,IAAI;YACT,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,QAAQ;YAC9C,YAAY,EAAE,oBAAY;YAC1B,QAAQ,EAAE,KAAK;SAChB,CAAC;QAEF,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,0DAA0D;IAE1D,IAAI,CAAC,KAAsB;QACzB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,WAAW,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAEzC,gBAAgB;QAChB,MAAM,OAAO,GAAyB;YACpC,GAAG,EAAE,OAAO;YACZ,MAAM;YACN,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;YAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC;QAEF,yCAAyC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,aAAa,GAAG,IAAA,4BAAkB,EAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAEpE,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC;YAC/D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,SAAS,CAAC;YAC1C,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBACnC,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC9C,OAAO,CAAC,gBAAgB,GAAG,IAAA,8BAAoB,EAC7C,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,EACvD,aAAa,CACd,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAEjD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC;YACrE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2DAA2D;IAE3D,GAAG,CAAC,KAAuE;QACzE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,CAAC,CAAC;QACzE,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAEtJ,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;QAElF,IAAI,cAAc,GAAkB,KAAK,CAAC,gBAAgB,IAAI,IAAI,CAAC;QACnE,IAAI,cAAc,KAAK,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC;YAChE,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9C,cAAc,GAAG,IAAA,8BAAoB,EACnC,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,EACvD,aAAa,CACd,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,IAAA,SAAI,GAAE;YACV,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,eAAe;YAChF,KAAK;YACL,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,SAAS;YAC9E,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,GAAG,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,SAAS;YAClF,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,GAAG,EAAE,QAAQ,IAAI,OAAO;YACpD,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE;YAC1B,GAAG,EAAE,GAAG,CAAC,WAAW,EAAE;YACtB,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC;YAC/B,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC;YAC7B,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;YAC5B,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,QAAQ;YAC9C,YAAY,EAAE,oBAAY;YAC1B,QAAQ,EAAE,KAAK;YACf,gBAAgB,EAAE,cAAc;YAChC,aAAa,EAAE,KAAK,CAAC,gBAAgB,GAAG,KAAK;SAC9C,CAAC;QAEF,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,0DAA0D;IAE1D,MAAM,CAAC,EAAU,EAAE,OAA6B;QAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,0DAA0D;IAE1D,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,0DAA0D;IAE1D,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,UAUF,EAAE;QACJ,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,0DAA0D;IAE1D,SAAS,CAAC,IAAY,EAAE,EAAU,EAAE,OAA+D;QACjG,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,0DAA0D;IAE1D,OAAO,KAAe,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACrD,QAAQ,KAAe,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACvD,MAAM,KAAe,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACnD,KAAK,KAAK,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAEvC,wDAAwD;IAExD,WAAW,CAAC,KAA8F;QACxG,MAAM,QAAQ,GAAqB;YACjC,EAAE,EAAE,IAAA,SAAM,GAAE;YACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;YACpC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,cAAc,CAAC,EAAU;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IACjC,CAAC;IAED,gBAAgB,CAAC,OAAe;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC;QACzD,OAAO,IAAA,uBAAY,EAAC,KAAK,EAAE,SAAS,EAAE,gCAAmB,EAAE,YAAY,CAAC,CAAC;IAC3E,CAAC;IAED,wDAAwD;IAExD,UAAU,CAAC,IASV;QACC,MAAM,MAAM,GAAiB;YAC3B,EAAE,EAAE,IAAA,SAAM,GAAE;YACZ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,WAAW,CAAC,KAAc,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,SAAS,CAAC,EAAU;QAClB,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,YAAY,CAAC,EAAU;QACrB,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,wDAAwD;IAEhD,gBAAgB;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;QACjD,IAAI,CAAC,SAAS;YAAE,OAAO,gCAAsB,CAAC;QAC9C,OAAO;YACL,uBAAuB,EAAE;gBACvB,GAAG,gCAAsB,CAAC,uBAAuB;gBACjD,GAAG,CAAC,SAAS,CAAC,uBAAuB,IAAI,EAAE,CAAC;aAC7C;YACD,yBAAyB,EAAE,SAAS,CAAC,yBAAyB,IAAI,gCAAsB,CAAC,yBAAyB;YAClH,oBAAoB,EAAE,SAAS,CAAC,oBAAoB,IAAI,gCAAsB,CAAC,oBAAoB;SACpG,CAAC;IACJ,CAAC;IAED,0DAA0D;IAE1D,IAAI,QAAQ,KAAqB,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IAE9D,KAAK;QACH,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;CACF;AApTD,wBAoTC"}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Clawck Database Layer - SQLite via better-sqlite3 (native, zero-copy)
3
3
  */
4
- import { ClawckEntry, TimesheetSummary, ClawckConfig, SyncState } from './types';
4
+ import { ClawckEntry, TimesheetSummary, ClawckConfig, SyncState, StoredReport } from './types';
5
+ import { PersonalBaseline } from './personal';
5
6
  export declare class ClawckDB {
6
7
  private db;
7
8
  private config;
@@ -25,6 +26,7 @@ export declare class ClawckDB {
25
26
  to?: string;
26
27
  limit?: number;
27
28
  offset?: number;
29
+ approved?: boolean;
28
30
  }): ClawckEntry[];
29
31
  private queryRows;
30
32
  getTimesheet(from: string, to: string, filters?: {
@@ -49,6 +51,19 @@ export declare class ClawckDB {
49
51
  getSyncState(sourceName: string): SyncState | null;
50
52
  setSyncState(state: SyncState): void;
51
53
  getAllSyncStates(): SyncState[];
54
+ insertBaseline(baseline: PersonalBaseline): PersonalBaseline;
55
+ updateBaseline(id: string, updates: Partial<PersonalBaseline>): PersonalBaseline | null;
56
+ deleteBaseline(id: string): boolean;
57
+ getBaselineById(id: string): PersonalBaseline | null;
58
+ getBaselines(): PersonalBaseline[];
59
+ getBaselinesByCategory(category: string): PersonalBaseline[];
60
+ private rowToBaseline;
61
+ insertReport(report: StoredReport): StoredReport;
62
+ getReportById(id: string): StoredReport | null;
63
+ listReports(limit?: number, offset?: number): StoredReport[];
64
+ getReportContent(id: string): StoredReport | null;
65
+ deleteReport(id: string): boolean;
66
+ private rowToReport;
52
67
  close(): void;
53
68
  }
54
69
  //# sourceMappingURL=database.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAgB,YAAY,EAA2F,SAAS,EAAE,MAAM,SAAS,CAAC;AAExL,qBAAa,QAAQ;IACnB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,YAAY;IAShC,OAAO,CAAC,OAAO;IA6BT,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAElC,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW;IAOvC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,IAAI;IAyBrE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAKvC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK/B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE;IAI3C,UAAU,IAAI,WAAW,EAAE;IAI3B,KAAK,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAAO,GAAG,WAAW,EAAE;IAa3L,OAAO,CAAC,SAAS;IAKjB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,gBAAgB;IA+B7H,UAAU,IAAI,MAAM,EAAE;IACtB,WAAW,IAAI,MAAM,EAAE;IACvB,SAAS,IAAI,MAAM,EAAE;IAErB,OAAO,CAAC,WAAW;IAKnB,QAAQ;;;;;;;IAQR,OAAO,CAAC,UAAU;IAIlB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW;IAOvC,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM;IAa1C,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAMlD,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAMpC,gBAAgB,IAAI,SAAS,EAAE;IAW/B,KAAK,IAAI,IAAI;CACd"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"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"}
@@ -51,10 +51,48 @@ class ClawckDB {
51
51
  last_error TEXT,
52
52
  entries_synced INTEGER NOT NULL DEFAULT 0
53
53
  )`);
54
+ // Migration: add approved column
55
+ try {
56
+ this.db.exec(`ALTER TABLE entries ADD COLUMN approved INTEGER NOT NULL DEFAULT 0`);
57
+ }
58
+ catch { }
59
+ // Migration: add agent_runtime_ms and wall_clock_ms columns
60
+ try {
61
+ this.db.exec(`ALTER TABLE entries ADD COLUMN agent_runtime_ms INTEGER`);
62
+ }
63
+ catch { }
64
+ try {
65
+ this.db.exec(`ALTER TABLE entries ADD COLUMN wall_clock_ms INTEGER`);
66
+ }
67
+ catch { }
68
+ // Migration: personal baselines table
69
+ this.db.exec(`CREATE TABLE IF NOT EXISTS personal_baselines (
70
+ id TEXT PRIMARY KEY,
71
+ category TEXT NOT NULL,
72
+ task_type TEXT NOT NULL,
73
+ description TEXT NOT NULL DEFAULT '',
74
+ my_minutes REAL NOT NULL,
75
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
76
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
77
+ )`);
78
+ // Migration: reports table
79
+ this.db.exec(`CREATE TABLE IF NOT EXISTS reports (
80
+ id TEXT PRIMARY KEY,
81
+ name TEXT NOT NULL DEFAULT '',
82
+ period TEXT NOT NULL,
83
+ period_start TEXT NOT NULL,
84
+ period_end TEXT NOT NULL,
85
+ style TEXT NOT NULL DEFAULT 'full',
86
+ format TEXT NOT NULL DEFAULT 'terminal',
87
+ content BLOB,
88
+ metadata TEXT NOT NULL DEFAULT '{}',
89
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
90
+ )`);
91
+ this.db.exec(`CREATE INDEX IF NOT EXISTS idx_reports_created ON reports(created_at)`);
54
92
  }
55
93
  async ensureReady() { }
56
94
  insert(entry) {
57
- this.db.prepare(`INSERT INTO entries (id, agent, model, client, project, task, category, start, end_, status, tokens_in, tokens_out, cost_usd, tool_calls, summary, tags, source, spec_version) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`).run(entry.id, entry.agent, entry.model, entry.client, entry.project, entry.task, entry.category, entry.start, entry.end, entry.status, entry.tokens_in, entry.tokens_out, entry.cost_usd, entry.tool_calls, entry.summary, JSON.stringify(entry.tags), entry.source, entry.spec_version);
95
+ this.db.prepare(`INSERT INTO entries (id, agent, model, client, project, task, category, start, end_, status, tokens_in, tokens_out, cost_usd, tool_calls, summary, tags, source, spec_version, approved, agent_runtime_ms, wall_clock_ms) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`).run(entry.id, entry.agent, entry.model, entry.client, entry.project, entry.task, entry.category, entry.start, entry.end, entry.status, entry.tokens_in, entry.tokens_out, entry.cost_usd, entry.tool_calls, entry.summary, JSON.stringify(entry.tags), entry.source, entry.spec_version, entry.approved ? 1 : 0, entry.agent_runtime_ms ?? null, entry.wall_clock_ms ?? null);
58
96
  return entry;
59
97
  }
60
98
  update(id, updates) {
@@ -115,6 +153,18 @@ class ClawckDB {
115
153
  fields.push('agent = ?');
116
154
  values.push(updates.agent);
117
155
  }
156
+ if (updates.approved !== undefined) {
157
+ fields.push('approved = ?');
158
+ values.push(updates.approved ? 1 : 0);
159
+ }
160
+ if (updates.agent_runtime_ms !== undefined) {
161
+ fields.push('agent_runtime_ms = ?');
162
+ values.push(updates.agent_runtime_ms);
163
+ }
164
+ if (updates.wall_clock_ms !== undefined) {
165
+ fields.push('wall_clock_ms = ?');
166
+ values.push(updates.wall_clock_ms);
167
+ }
118
168
  fields.push("updated_at = datetime('now')");
119
169
  if (fields.length === 1)
120
170
  return existing;
@@ -167,6 +217,10 @@ class ClawckDB {
167
217
  conds.push('start <= ?');
168
218
  params.push(filters.to);
169
219
  }
220
+ if (filters.approved !== undefined) {
221
+ conds.push('approved = ?');
222
+ params.push(filters.approved ? 1 : 0);
223
+ }
170
224
  const where = conds.length > 0 ? `WHERE ${conds.join(' AND ')}` : '';
171
225
  return this.queryRows(`SELECT * FROM entries ${where} ORDER BY start DESC LIMIT ${filters.limit || 500} OFFSET ${filters.offset || 0}`, params);
172
226
  }
@@ -178,11 +232,13 @@ class ClawckDB {
178
232
  const entries = this.query({ ...filters, from, to, limit: 10000 });
179
233
  const equivs = this.config.human_equivalents || types_1.DEFAULT_HUMAN_EQUIVALENTS;
180
234
  const rows = entries.map(e => {
181
- const durationMin = e.end ? (new Date(e.end).getTime() - new Date(e.start).getTime()) / 60000 : (Date.now() - new Date(e.start).getTime()) / 60000;
235
+ const wallClockMs = e.wall_clock_ms ?? (e.end ? (new Date(e.end).getTime() - new Date(e.start).getTime()) : (Date.now() - new Date(e.start).getTime()));
236
+ const durationMin = wallClockMs / 60000;
237
+ const agentRuntimeMin = e.agent_runtime_ms != null ? e.agent_runtime_ms / 60000 : undefined;
182
238
  const equiv = equivs[e.category] || equivs.other;
183
239
  const agentHours = durationMin / 60;
184
240
  const humanEquivHours = agentHours * equiv.multiplier;
185
- return { date: e.start.split('T')[0], agent: e.agent, client: e.client, project: e.project, task: e.task, category: e.category, duration_minutes: Math.round(durationMin * 100) / 100, tokens_total: e.tokens_in + e.tokens_out, cost_usd: e.cost_usd, human_equiv_hours: Math.round(humanEquivHours * 100) / 100, human_equiv_cost_saved: Math.round(humanEquivHours * equiv.human_rate_usd * 100) / 100, status: e.status };
241
+ return { date: e.start.split('T')[0], agent: e.agent, client: e.client, project: e.project, task: e.task, category: e.category, duration_minutes: Math.round(durationMin * 100) / 100, tokens_total: e.tokens_in + e.tokens_out, cost_usd: e.cost_usd, human_equiv_hours: Math.round(humanEquivHours * 100) / 100, human_equiv_cost_saved: Math.round(humanEquivHours * equiv.human_rate_usd * 100) / 100, status: e.status, approved: e.approved ?? false, agent_runtime_minutes: agentRuntimeMin != null ? Math.round(agentRuntimeMin * 100) / 100 : undefined, wall_clock_minutes: Math.round(durationMin * 100) / 100 };
186
242
  });
187
243
  const totalAgentHours = rows.reduce((s, r) => s + r.duration_minutes / 60, 0);
188
244
  const totalHumanEquiv = rows.reduce((s, r) => s + r.human_equiv_hours, 0);
@@ -233,7 +289,13 @@ class ClawckDB {
233
289
  c.entries += 1;
234
290
  catMap.set(r.category, c);
235
291
  }
236
- return { period_start: from, period_end: to, total_entries: entries.length, total_agent_hours: Math.round(totalAgentHours * 100) / 100, total_human_equiv_hours: Math.round(totalHumanEquiv * 100) / 100, total_cost_usd: Math.round(totalCost * 100) / 100, total_savings_usd: Math.round(totalSavings * 100) / 100, total_tokens: totalTokens, by_client: [...clientMap.values()], by_agent: [...agentMap.values()].map(a => ({ ...a, success_rate: a.entries > 0 ? Math.round((a.completed / a.entries) * 100) : 0 })), by_project: [...projMap.values()], by_category: [...catMap.values()], entries: rows };
292
+ const round2 = (n) => Math.round(n * 100) / 100;
293
+ return { period_start: from, period_end: to, total_entries: entries.length, total_agent_hours: round2(totalAgentHours), total_human_equiv_hours: round2(totalHumanEquiv), total_cost_usd: round2(totalCost), total_savings_usd: round2(totalSavings), total_tokens: totalTokens,
294
+ by_client: [...clientMap.values()].map(c => ({ ...c, agent_hours: round2(c.agent_hours), human_equiv_hours: round2(c.human_equiv_hours), cost_usd: round2(c.cost_usd), savings_usd: round2(c.savings_usd) })),
295
+ by_agent: [...agentMap.values()].map(a => ({ ...a, agent_hours: round2(a.agent_hours), human_equiv_hours: round2(a.human_equiv_hours), cost_usd: round2(a.cost_usd), success_rate: a.entries > 0 ? Math.round((a.completed / a.entries) * 100) : 0 })),
296
+ by_project: [...projMap.values()].map(p => ({ ...p, agent_hours: round2(p.agent_hours), human_equiv_hours: round2(p.human_equiv_hours), cost_usd: round2(p.cost_usd) })),
297
+ by_category: [...catMap.values()].map(c => ({ ...c, agent_hours: round2(c.agent_hours), human_equiv_hours: round2(c.human_equiv_hours), cost_usd: round2(c.cost_usd), savings_usd: round2(c.savings_usd) })),
298
+ entries: rows };
237
299
  }
238
300
  getClients() { return this.getDistinct('client'); }
239
301
  getProjects() { return this.getDistinct('project'); }
@@ -250,17 +312,17 @@ class ClawckDB {
250
312
  return { total_entries: count('SELECT COUNT(*) as c FROM entries'), running: count("SELECT COUNT(*) as c FROM entries WHERE status = 'running'"), clients: count('SELECT COUNT(DISTINCT client) as c FROM entries'), projects: count('SELECT COUNT(DISTINCT project) as c FROM entries'), agents: count('SELECT COUNT(DISTINCT agent) as c FROM entries') };
251
313
  }
252
314
  rowToEntry(row) {
253
- return { id: row.id, agent: row.agent, model: row.model, client: row.client, project: row.project, task: row.task, category: row.category, start: row.start, end: row.end_, status: row.status, tokens_in: row.tokens_in, tokens_out: row.tokens_out, cost_usd: row.cost_usd, tool_calls: row.tool_calls, summary: row.summary, tags: JSON.parse(row.tags || '[]'), source: row.source, spec_version: row.spec_version };
315
+ return { id: row.id, agent: row.agent, model: row.model, client: row.client, project: row.project, task: row.task, category: row.category, start: row.start, end: row.end_, status: row.status, tokens_in: row.tokens_in, tokens_out: row.tokens_out, cost_usd: row.cost_usd, tool_calls: row.tool_calls, summary: row.summary, tags: JSON.parse(row.tags || '[]'), source: row.source, spec_version: row.spec_version, created_at: row.created_at, updated_at: row.updated_at, approved: !!row.approved, agent_runtime_ms: row.agent_runtime_ms ?? null, wall_clock_ms: row.wall_clock_ms ?? null };
254
316
  }
255
317
  upsert(entry) {
256
- this.db.prepare(`INSERT OR REPLACE INTO entries (id, agent, model, client, project, task, category, start, end_, status, tokens_in, tokens_out, cost_usd, tool_calls, summary, tags, source, spec_version, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'))`).run(entry.id, entry.agent, entry.model, entry.client, entry.project, entry.task, entry.category, entry.start, entry.end, entry.status, entry.tokens_in, entry.tokens_out, entry.cost_usd, entry.tool_calls, entry.summary, JSON.stringify(entry.tags), entry.source, entry.spec_version);
318
+ this.db.prepare(`INSERT OR REPLACE INTO entries (id, agent, model, client, project, task, category, start, end_, status, tokens_in, tokens_out, cost_usd, tool_calls, summary, tags, source, spec_version, approved, agent_runtime_ms, wall_clock_ms, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'))`).run(entry.id, entry.agent, entry.model, entry.client, entry.project, entry.task, entry.category, entry.start, entry.end, entry.status, entry.tokens_in, entry.tokens_out, entry.cost_usd, entry.tool_calls, entry.summary, JSON.stringify(entry.tags), entry.source, entry.spec_version, entry.approved ? 1 : 0, entry.agent_runtime_ms ?? null, entry.wall_clock_ms ?? null);
257
319
  return this.getById(entry.id);
258
320
  }
259
321
  bulkUpsert(entries) {
260
- const upsertStmt = this.db.prepare(`INSERT OR REPLACE INTO entries (id, agent, model, client, project, task, category, start, end_, status, tokens_in, tokens_out, cost_usd, tool_calls, summary, tags, source, spec_version, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'))`);
322
+ const upsertStmt = this.db.prepare(`INSERT OR REPLACE INTO entries (id, agent, model, client, project, task, category, start, end_, status, tokens_in, tokens_out, cost_usd, tool_calls, summary, tags, source, spec_version, approved, agent_runtime_ms, wall_clock_ms, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'))`);
261
323
  const runMany = this.db.transaction((items) => {
262
324
  for (const entry of items) {
263
- upsertStmt.run(entry.id, entry.agent, entry.model, entry.client, entry.project, entry.task, entry.category, entry.start, entry.end, entry.status, entry.tokens_in, entry.tokens_out, entry.cost_usd, entry.tool_calls, entry.summary, JSON.stringify(entry.tags), entry.source, entry.spec_version);
325
+ upsertStmt.run(entry.id, entry.agent, entry.model, entry.client, entry.project, entry.task, entry.category, entry.start, entry.end, entry.status, entry.tokens_in, entry.tokens_out, entry.cost_usd, entry.tool_calls, entry.summary, JSON.stringify(entry.tags), entry.source, entry.spec_version, entry.approved ? 1 : 0, entry.agent_runtime_ms ?? null, entry.wall_clock_ms ?? null);
264
326
  }
265
327
  });
266
328
  runMany(entries);
@@ -285,6 +347,113 @@ class ClawckDB {
285
347
  entries_synced: row.entries_synced,
286
348
  }));
287
349
  }
350
+ // ─── Personal Baselines ─────────────────────────────────
351
+ insertBaseline(baseline) {
352
+ this.db.prepare(`INSERT INTO personal_baselines (id, category, task_type, description, my_minutes, created_at, updated_at) VALUES (?,?,?,?,?,?,?)`).run(baseline.id, baseline.category, baseline.task_type, baseline.description, baseline.my_minutes, baseline.created_at, baseline.updated_at);
353
+ return baseline;
354
+ }
355
+ updateBaseline(id, updates) {
356
+ const existing = this.getBaselineById(id);
357
+ if (!existing)
358
+ return null;
359
+ const fields = [];
360
+ const values = [];
361
+ if (updates.category !== undefined) {
362
+ fields.push('category = ?');
363
+ values.push(updates.category);
364
+ }
365
+ if (updates.task_type !== undefined) {
366
+ fields.push('task_type = ?');
367
+ values.push(updates.task_type);
368
+ }
369
+ if (updates.description !== undefined) {
370
+ fields.push('description = ?');
371
+ values.push(updates.description);
372
+ }
373
+ if (updates.my_minutes !== undefined) {
374
+ fields.push('my_minutes = ?');
375
+ values.push(updates.my_minutes);
376
+ }
377
+ fields.push("updated_at = datetime('now')");
378
+ if (fields.length === 1)
379
+ return existing;
380
+ values.push(id);
381
+ this.db.prepare(`UPDATE personal_baselines SET ${fields.join(', ')} WHERE id = ?`).run(...values);
382
+ return this.getBaselineById(id);
383
+ }
384
+ deleteBaseline(id) {
385
+ const result = this.db.prepare('DELETE FROM personal_baselines WHERE id = ?').run(id);
386
+ return result.changes > 0;
387
+ }
388
+ getBaselineById(id) {
389
+ const row = this.db.prepare('SELECT * FROM personal_baselines WHERE id = ?').get(id);
390
+ return row ? this.rowToBaseline(row) : null;
391
+ }
392
+ getBaselines() {
393
+ const rows = this.db.prepare('SELECT * FROM personal_baselines ORDER BY category, task_type').all();
394
+ return rows.map(r => this.rowToBaseline(r));
395
+ }
396
+ getBaselinesByCategory(category) {
397
+ const rows = this.db.prepare('SELECT * FROM personal_baselines WHERE category = ? ORDER BY task_type').all(category);
398
+ return rows.map(r => this.rowToBaseline(r));
399
+ }
400
+ rowToBaseline(row) {
401
+ return {
402
+ id: row.id,
403
+ category: row.category,
404
+ task_type: row.task_type,
405
+ description: row.description,
406
+ my_minutes: row.my_minutes,
407
+ created_at: row.created_at,
408
+ updated_at: row.updated_at,
409
+ };
410
+ }
411
+ // ─── Reports ───────────────────────────────────────────
412
+ insertReport(report) {
413
+ const content = typeof report.content === 'string' ? Buffer.from(report.content, 'utf-8') : report.content;
414
+ this.db.prepare(`INSERT INTO reports (id, name, period, period_start, period_end, style, format, content, metadata, created_at) VALUES (?,?,?,?,?,?,?,?,?,?)`).run(report.id, report.name, report.period, report.period_start, report.period_end, report.style, report.format, content, JSON.stringify(report.metadata), report.created_at);
415
+ return report;
416
+ }
417
+ getReportById(id) {
418
+ const row = this.db.prepare('SELECT id, name, period, period_start, period_end, style, format, metadata, created_at FROM reports WHERE id = ?').get(id);
419
+ return row ? this.rowToReport(row) : null;
420
+ }
421
+ listReports(limit = 50, offset = 0) {
422
+ const rows = this.db.prepare('SELECT id, name, period, period_start, period_end, style, format, metadata, created_at FROM reports ORDER BY created_at DESC LIMIT ? OFFSET ?').all(limit, offset);
423
+ return rows.map(r => this.rowToReport(r));
424
+ }
425
+ getReportContent(id) {
426
+ const row = this.db.prepare('SELECT * FROM reports WHERE id = ?').get(id);
427
+ if (!row)
428
+ return null;
429
+ const report = this.rowToReport(row);
430
+ if (row.content) {
431
+ const buf = Buffer.isBuffer(row.content) ? row.content : Buffer.from(row.content);
432
+ report.content = report.format === 'pdf' ? buf : buf.toString('utf-8');
433
+ }
434
+ else {
435
+ report.content = '';
436
+ }
437
+ return report;
438
+ }
439
+ deleteReport(id) {
440
+ const result = this.db.prepare('DELETE FROM reports WHERE id = ?').run(id);
441
+ return result.changes > 0;
442
+ }
443
+ rowToReport(row) {
444
+ return {
445
+ id: row.id,
446
+ name: row.name,
447
+ period: row.period,
448
+ period_start: row.period_start,
449
+ period_end: row.period_end,
450
+ style: row.style,
451
+ format: row.format,
452
+ content: '',
453
+ metadata: JSON.parse(row.metadata || '{}'),
454
+ created_at: row.created_at,
455
+ };
456
+ }
288
457
  close() { this.db.close(); }
289
458
  }
290
459
  exports.ClawckDB = ClawckDB;