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.
- package/README.md +251 -174
- package/dist/cli/index.js +947 -87
- package/dist/cli/index.js.map +1 -1
- package/dist/core/atp.d.ts +31 -0
- package/dist/core/atp.d.ts.map +1 -0
- package/dist/core/atp.js +96 -0
- package/dist/core/atp.js.map +1 -0
- package/dist/core/benchmarks.d.ts +20 -0
- package/dist/core/benchmarks.d.ts.map +1 -0
- package/dist/core/benchmarks.js +86 -0
- package/dist/core/benchmarks.js.map +1 -0
- package/dist/core/clawck.d.ts +39 -3
- package/dist/core/clawck.d.ts.map +1 -1
- package/dist/core/clawck.js +140 -18
- package/dist/core/clawck.js.map +1 -1
- package/dist/core/database.d.ts +16 -1
- package/dist/core/database.d.ts.map +1 -1
- package/dist/core/database.js +177 -8
- package/dist/core/database.js.map +1 -1
- package/dist/core/patterns.d.ts +7 -0
- package/dist/core/patterns.d.ts.map +1 -0
- package/dist/core/patterns.js +36 -0
- package/dist/core/patterns.js.map +1 -0
- package/dist/core/personal.d.ts +26 -0
- package/dist/core/personal.d.ts.map +1 -0
- package/dist/core/personal.js +60 -0
- package/dist/core/personal.js.map +1 -0
- package/dist/core/runtime.d.ts +17 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +43 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/types.d.ts +93 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +9 -2
- package/dist/core/types.js.map +1 -1
- package/dist/core/webhooks.d.ts +22 -0
- package/dist/core/webhooks.d.ts.map +1 -0
- package/dist/core/webhooks.js +70 -0
- package/dist/core/webhooks.js.map +1 -0
- package/dist/hooks/adapters.d.ts +8 -0
- package/dist/hooks/adapters.d.ts.map +1 -0
- package/dist/hooks/adapters.js +152 -0
- package/dist/hooks/adapters.js.map +1 -0
- package/dist/hooks/handler.d.ts +9 -0
- package/dist/hooks/handler.d.ts.map +1 -0
- package/dist/hooks/handler.js +93 -0
- package/dist/hooks/handler.js.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +23 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/install.d.ts +16 -0
- package/dist/hooks/install.d.ts.map +1 -0
- package/dist/hooks/install.js +247 -0
- package/dist/hooks/install.js.map +1 -0
- package/dist/hooks/session.d.ts +10 -0
- package/dist/hooks/session.d.ts.map +1 -0
- package/dist/hooks/session.js +72 -0
- package/dist/hooks/session.js.map +1 -0
- package/dist/hooks/stdin.d.ts +6 -0
- package/dist/hooks/stdin.d.ts.map +1 -0
- package/dist/hooks/stdin.js +38 -0
- package/dist/hooks/stdin.js.map +1 -0
- package/dist/hooks/types.d.ts +26 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +7 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/dist/reports/html.d.ts +14 -0
- package/dist/reports/html.d.ts.map +1 -0
- package/dist/reports/html.js +353 -0
- package/dist/reports/html.js.map +1 -0
- package/dist/reports/pdf.d.ts +14 -0
- package/dist/reports/pdf.d.ts.map +1 -0
- package/dist/reports/pdf.js +177 -0
- package/dist/reports/pdf.js.map +1 -0
- package/dist/reports/periods.d.ts +18 -0
- package/dist/reports/periods.d.ts.map +1 -0
- package/dist/reports/periods.js +55 -0
- package/dist/reports/periods.js.map +1 -0
- package/dist/server/api.d.ts.map +1 -1
- package/dist/server/api.js +156 -2
- package/dist/server/api.js.map +1 -1
- package/dist/server/mcp.d.ts.map +1 -1
- package/dist/server/mcp.js +31 -10
- package/dist/server/mcp.js.map +1 -1
- package/docs/atp-schema.json +298 -0
- package/docs/atp-spec-v0.2.md +216 -0
- package/docs/benchmarks-sources.md +202 -0
- package/docs/platform-testing-guide.md +423 -0
- package/docs/skills/clawck-setup.md +131 -0
- package/docs/skills/clawck-usage.md +148 -0
- package/docs/snippets/claude-md.txt +33 -0
- package/docs/snippets/hooks-claude.json +24 -0
- package/docs/snippets/hooks-cline.txt +10 -0
- package/docs/snippets/hooks-codex.json +16 -0
- package/docs/snippets/hooks-cursor.json +16 -0
- package/docs/snippets/hooks-gemini.json +16 -0
- package/docs/snippets/hooks-windsurf.json +16 -0
- package/docs/snippets/mcp-config.json +7 -0
- package/docs/snippets/openclaw-agent-md.txt +18 -0
- package/docs/snippets/openclaw-heartbeat-md.txt +17 -0
- package/package.json +4 -2
package/dist/core/clawck.js
CHANGED
|
@@ -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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
|
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:
|
|
131
|
+
tokens_out: tokensOut,
|
|
81
132
|
cost_usd: input.cost_usd || 0,
|
|
82
|
-
tool_calls:
|
|
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
|
}
|
package/dist/core/clawck.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clawck.js","sourceRoot":"","sources":["../../src/core/clawck.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAAkC;AAClC,
|
|
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"}
|
package/dist/core/database.d.ts
CHANGED
|
@@ -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,
|
|
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,EAAgB,YAAY,EAA2D,MAAM,SAAS,CAAC;AAC7Q,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,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;IA0DT,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;IA4BrE,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;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;KAAO,GAAG,WAAW,EAAE;IAc/M,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;IAuC7H,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;IAa/B,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB;IAO5D,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,GAAG,IAAI;IAgBvF,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAKnC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAKpD,YAAY,IAAI,gBAAgB,EAAE;IAKlC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE;IAK5D,OAAO,CAAC,aAAa;IAcrB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY;IAQhD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAK9C,WAAW,CAAC,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,YAAY,EAAE;IAKnE,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAajD,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAKjC,OAAO,CAAC,WAAW;IAenB,KAAK,IAAI,IAAI;CACd"}
|
package/dist/core/database.js
CHANGED
|
@@ -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 (
|
|
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
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
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;
|