@synergenius/flowweaver-pack-weaver 0.2.0 → 0.3.0

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 (82) hide show
  1. package/dist/bot/agent-provider.d.ts +6 -10
  2. package/dist/bot/agent-provider.d.ts.map +1 -1
  3. package/dist/bot/agent-provider.js +65 -18
  4. package/dist/bot/agent-provider.js.map +1 -1
  5. package/dist/bot/approvals.d.ts +6 -2
  6. package/dist/bot/approvals.d.ts.map +1 -1
  7. package/dist/bot/approvals.js +21 -0
  8. package/dist/bot/approvals.js.map +1 -1
  9. package/dist/bot/bot-agent-channel.d.ts +3 -0
  10. package/dist/bot/bot-agent-channel.d.ts.map +1 -1
  11. package/dist/bot/bot-agent-channel.js +2 -0
  12. package/dist/bot/bot-agent-channel.js.map +1 -1
  13. package/dist/bot/cost-store.d.ts +18 -0
  14. package/dist/bot/cost-store.d.ts.map +1 -0
  15. package/dist/bot/cost-store.js +81 -0
  16. package/dist/bot/cost-store.js.map +1 -0
  17. package/dist/bot/cost-tracker.d.ts +18 -0
  18. package/dist/bot/cost-tracker.d.ts.map +1 -0
  19. package/dist/bot/cost-tracker.js +60 -0
  20. package/dist/bot/cost-tracker.js.map +1 -0
  21. package/dist/bot/cron-parser.d.ts +5 -0
  22. package/dist/bot/cron-parser.d.ts.map +1 -0
  23. package/dist/bot/cron-parser.js +141 -0
  24. package/dist/bot/cron-parser.js.map +1 -0
  25. package/dist/bot/cron-scheduler.d.ts +12 -0
  26. package/dist/bot/cron-scheduler.d.ts.map +1 -0
  27. package/dist/bot/cron-scheduler.js +43 -0
  28. package/dist/bot/cron-scheduler.js.map +1 -0
  29. package/dist/bot/dashboard.d.ts +31 -0
  30. package/dist/bot/dashboard.d.ts.map +1 -0
  31. package/dist/bot/dashboard.js +461 -0
  32. package/dist/bot/dashboard.js.map +1 -0
  33. package/dist/bot/file-watcher.d.ts +24 -0
  34. package/dist/bot/file-watcher.d.ts.map +1 -0
  35. package/dist/bot/file-watcher.js +98 -0
  36. package/dist/bot/file-watcher.js.map +1 -0
  37. package/dist/bot/index.d.ts +14 -2
  38. package/dist/bot/index.d.ts.map +1 -1
  39. package/dist/bot/index.js +16 -0
  40. package/dist/bot/index.js.map +1 -1
  41. package/dist/bot/notifications.d.ts.map +1 -1
  42. package/dist/bot/notifications.js +23 -0
  43. package/dist/bot/notifications.js.map +1 -1
  44. package/dist/bot/pipeline-runner.d.ts +22 -0
  45. package/dist/bot/pipeline-runner.d.ts.map +1 -0
  46. package/dist/bot/pipeline-runner.js +263 -0
  47. package/dist/bot/pipeline-runner.js.map +1 -0
  48. package/dist/bot/provider-registry.d.ts +26 -0
  49. package/dist/bot/provider-registry.d.ts.map +1 -0
  50. package/dist/bot/provider-registry.js +175 -0
  51. package/dist/bot/provider-registry.js.map +1 -0
  52. package/dist/bot/run-store.d.ts +14 -0
  53. package/dist/bot/run-store.d.ts.map +1 -0
  54. package/dist/bot/run-store.js +105 -0
  55. package/dist/bot/run-store.js.map +1 -0
  56. package/dist/bot/runner.d.ts +1 -0
  57. package/dist/bot/runner.d.ts.map +1 -1
  58. package/dist/bot/runner.js +73 -4
  59. package/dist/bot/runner.js.map +1 -1
  60. package/dist/bot/types.d.ts +212 -4
  61. package/dist/bot/types.d.ts.map +1 -1
  62. package/dist/bot/utils.d.ts +2 -0
  63. package/dist/bot/utils.d.ts.map +1 -0
  64. package/dist/bot/utils.js +20 -0
  65. package/dist/bot/utils.js.map +1 -0
  66. package/dist/bot/watch-daemon.d.ts +19 -0
  67. package/dist/bot/watch-daemon.d.ts.map +1 -0
  68. package/dist/bot/watch-daemon.js +178 -0
  69. package/dist/bot/watch-daemon.js.map +1 -0
  70. package/dist/bot/web-approval.d.ts +19 -0
  71. package/dist/bot/web-approval.d.ts.map +1 -0
  72. package/dist/bot/web-approval.js +207 -0
  73. package/dist/bot/web-approval.js.map +1 -0
  74. package/dist/cli.js +555 -16
  75. package/dist/cli.js.map +1 -1
  76. package/dist/index.d.ts +15 -2
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +18 -0
  79. package/dist/index.js.map +1 -1
  80. package/dist/templates/weaver-template.js +2 -2
  81. package/flowweaver.manifest.json +1 -1
  82. package/package.json +1 -1
@@ -0,0 +1,461 @@
1
+ import * as http from 'node:http';
2
+ import * as crypto from 'node:crypto';
3
+ export class DashboardServer {
4
+ server;
5
+ clients = new Set();
6
+ state = {
7
+ workflowFile: '',
8
+ status: 'idle',
9
+ nodes: new Map(),
10
+ events: [],
11
+ };
12
+ heartbeatTimer = null;
13
+ pendingApprovals = new Map();
14
+ port;
15
+ actualPort = null;
16
+ constructor(options = {}) {
17
+ this.port = options.port ?? 4242;
18
+ this.server = http.createServer((req, res) => this.handleRequest(req, res));
19
+ }
20
+ async start() {
21
+ return new Promise((resolve, reject) => {
22
+ this.server.listen(this.port, '127.0.0.1', () => {
23
+ const addr = this.server.address();
24
+ this.actualPort = typeof addr === 'object' && addr ? addr.port : this.port;
25
+ this.heartbeatTimer = setInterval(() => this.heartbeat(), 30_000);
26
+ resolve(this.actualPort);
27
+ });
28
+ this.server.on('error', reject);
29
+ });
30
+ }
31
+ async stop() {
32
+ if (this.heartbeatTimer)
33
+ clearInterval(this.heartbeatTimer);
34
+ for (const client of this.clients) {
35
+ try {
36
+ client.end();
37
+ }
38
+ catch { /* ignore */ }
39
+ }
40
+ this.clients.clear();
41
+ return new Promise((resolve) => {
42
+ this.server.close(() => resolve());
43
+ });
44
+ }
45
+ getUrl() {
46
+ return `http://127.0.0.1:${this.actualPort ?? this.port}`;
47
+ }
48
+ broadcast(event) {
49
+ this.updateState(event);
50
+ if (this.state.events.length > 500) {
51
+ this.state.events = this.state.events.slice(-400);
52
+ }
53
+ const data = `event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`;
54
+ for (const client of this.clients) {
55
+ try {
56
+ client.write(data);
57
+ }
58
+ catch {
59
+ this.clients.delete(client);
60
+ }
61
+ }
62
+ }
63
+ broadcastExecution(event) {
64
+ this.broadcast({
65
+ type: event.type,
66
+ timestamp: event.timestamp,
67
+ nodeId: event.nodeId,
68
+ nodeType: event.nodeType,
69
+ error: event.error,
70
+ });
71
+ }
72
+ broadcastWorkflowStart(workflowFile) {
73
+ this.state.workflowFile = workflowFile;
74
+ this.state.status = 'running';
75
+ this.state.startedAt = Date.now();
76
+ this.state.completedAt = undefined;
77
+ this.state.nodes.clear();
78
+ this.state.events = [];
79
+ this.state.summary = undefined;
80
+ this.broadcast({
81
+ type: 'workflow-start',
82
+ timestamp: Date.now(),
83
+ });
84
+ }
85
+ broadcastWorkflowComplete(summary, success) {
86
+ this.state.status = success ? 'completed' : 'failed';
87
+ this.state.completedAt = Date.now();
88
+ this.state.summary = summary;
89
+ this.broadcast({
90
+ type: 'workflow-complete',
91
+ timestamp: Date.now(),
92
+ summary,
93
+ });
94
+ }
95
+ broadcastWorkflowError(error) {
96
+ this.state.status = 'error';
97
+ this.state.completedAt = Date.now();
98
+ this.broadcast({
99
+ type: 'workflow-error',
100
+ timestamp: Date.now(),
101
+ error,
102
+ });
103
+ }
104
+ registerApproval(request, resolve) {
105
+ const id = crypto.randomUUID().slice(0, 8);
106
+ this.pendingApprovals.set(id, { id, request, resolve });
107
+ this.broadcast({
108
+ type: 'approval-pending',
109
+ timestamp: Date.now(),
110
+ approval: { id, prompt: request.prompt, context: request.context },
111
+ });
112
+ return id;
113
+ }
114
+ removeApproval(id) {
115
+ this.pendingApprovals.delete(id);
116
+ this.broadcast({
117
+ type: 'approval-resolved',
118
+ timestamp: Date.now(),
119
+ });
120
+ }
121
+ hasPendingApprovals() {
122
+ return this.pendingApprovals.size > 0;
123
+ }
124
+ updateState(event) {
125
+ this.state.events.push(event);
126
+ if (!event.nodeId)
127
+ return;
128
+ const existing = this.state.nodes.get(event.nodeId);
129
+ const node = existing ?? {
130
+ nodeId: event.nodeId,
131
+ nodeType: event.nodeType,
132
+ status: 'pending',
133
+ };
134
+ const statusMap = {
135
+ 'node-start': 'running',
136
+ 'node-complete': 'succeeded',
137
+ 'node-error': 'failed',
138
+ };
139
+ const newStatus = statusMap[event.type];
140
+ if (newStatus) {
141
+ node.status = newStatus;
142
+ if (newStatus === 'running') {
143
+ node.startedAt = event.timestamp;
144
+ }
145
+ else {
146
+ node.completedAt = event.timestamp;
147
+ if (node.startedAt) {
148
+ node.durationMs = event.timestamp - node.startedAt;
149
+ }
150
+ }
151
+ }
152
+ if (event.error)
153
+ node.error = event.error;
154
+ if (event.nodeType)
155
+ node.nodeType = event.nodeType;
156
+ this.state.nodes.set(event.nodeId, node);
157
+ }
158
+ heartbeat() {
159
+ const data = ': heartbeat\n\n';
160
+ for (const client of this.clients) {
161
+ try {
162
+ client.write(data);
163
+ }
164
+ catch {
165
+ this.clients.delete(client);
166
+ }
167
+ }
168
+ }
169
+ handleRequest(req, res) {
170
+ const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
171
+ if (req.method === 'GET' && url.pathname === '/') {
172
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
173
+ res.end(getDashboardHtml());
174
+ return;
175
+ }
176
+ if (req.method === 'GET' && url.pathname === '/events') {
177
+ res.writeHead(200, {
178
+ 'Content-Type': 'text/event-stream',
179
+ 'Cache-Control': 'no-cache',
180
+ 'Connection': 'keep-alive',
181
+ });
182
+ this.clients.add(res);
183
+ req.on('close', () => this.clients.delete(res));
184
+ // Send init state
185
+ const initData = {
186
+ workflowFile: this.state.workflowFile,
187
+ status: this.state.status,
188
+ startedAt: this.state.startedAt,
189
+ completedAt: this.state.completedAt,
190
+ summary: this.state.summary,
191
+ nodes: Object.fromEntries(this.state.nodes),
192
+ events: this.state.events,
193
+ pendingApprovals: Array.from(this.pendingApprovals.values()).map((a) => ({
194
+ id: a.id,
195
+ prompt: a.request.prompt,
196
+ context: a.request.context,
197
+ })),
198
+ };
199
+ res.write(`event: init\ndata: ${JSON.stringify(initData)}\n\n`);
200
+ return;
201
+ }
202
+ if (req.method === 'GET' && url.pathname === '/api/status') {
203
+ res.writeHead(200, { 'Content-Type': 'application/json' });
204
+ res.end(JSON.stringify({
205
+ workflowFile: this.state.workflowFile,
206
+ status: this.state.status,
207
+ startedAt: this.state.startedAt,
208
+ completedAt: this.state.completedAt,
209
+ summary: this.state.summary,
210
+ nodeCount: this.state.nodes.size,
211
+ eventCount: this.state.events.length,
212
+ }));
213
+ return;
214
+ }
215
+ if (req.method === 'POST' && url.pathname.startsWith('/api/approve/')) {
216
+ const id = url.pathname.split('/').pop();
217
+ this.resolveApproval(id, true, req, res);
218
+ return;
219
+ }
220
+ if (req.method === 'POST' && url.pathname.startsWith('/api/reject/')) {
221
+ const id = url.pathname.split('/').pop();
222
+ this.resolveApproval(id, false, req, res);
223
+ return;
224
+ }
225
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
226
+ res.end('Not found');
227
+ }
228
+ resolveApproval(id, approved, req, res) {
229
+ const pending = this.pendingApprovals.get(id);
230
+ if (!pending) {
231
+ res.writeHead(404, { 'Content-Type': 'application/json' });
232
+ res.end(JSON.stringify({ error: 'Approval not found or already resolved' }));
233
+ return;
234
+ }
235
+ let body = '';
236
+ req.on('data', (chunk) => { body += chunk; });
237
+ req.on('end', () => {
238
+ let reason = approved ? 'approved via dashboard' : 'rejected via dashboard';
239
+ try {
240
+ const parsed = JSON.parse(body);
241
+ if (parsed.reason)
242
+ reason = parsed.reason;
243
+ }
244
+ catch { /* no body or invalid json, use default reason */ }
245
+ pending.resolve({ approved, reason });
246
+ this.removeApproval(id);
247
+ res.writeHead(200, { 'Content-Type': 'application/json' });
248
+ res.end(JSON.stringify({ ok: true, approved, reason }));
249
+ });
250
+ }
251
+ }
252
+ function getDashboardHtml() {
253
+ return `<!DOCTYPE html>
254
+ <html lang="en">
255
+ <head>
256
+ <meta charset="utf-8">
257
+ <meta name="viewport" content="width=device-width, initial-scale=1">
258
+ <title>Weaver Dashboard</title>
259
+ <style>
260
+ * { margin: 0; padding: 0; box-sizing: border-box; }
261
+ body { font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace; background: #0d1117; color: #c9d1d9; font-size: 14px; }
262
+ .header { padding: 16px 24px; border-bottom: 1px solid #21262d; display: flex; align-items: center; gap: 16px; }
263
+ .header h1 { font-size: 16px; font-weight: 600; color: #f0f6fc; }
264
+ .badge { padding: 2px 10px; border-radius: 12px; font-size: 12px; font-weight: 500; }
265
+ .badge.idle { background: #21262d; color: #8b949e; }
266
+ .badge.running { background: #1f3a5f; color: #58a6ff; animation: pulse 2s infinite; }
267
+ .badge.completed { background: #12261e; color: #3fb950; }
268
+ .badge.failed, .badge.error { background: #3d1214; color: #f85149; }
269
+ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }
270
+ .timer { color: #8b949e; margin-left: auto; }
271
+ .main { display: grid; grid-template-columns: 1fr 380px; height: calc(100vh - 53px); }
272
+ .nodes { padding: 16px; overflow-y: auto; }
273
+ .node-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
274
+ .node-card { background: #161b22; border: 1px solid #21262d; border-radius: 8px; padding: 12px; }
275
+ .node-card.running { border-color: #1f6feb; }
276
+ .node-card.succeeded { border-color: #238636; }
277
+ .node-card.failed { border-color: #da3633; }
278
+ .node-header { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
279
+ .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
280
+ .dot.pending { background: #484f58; }
281
+ .dot.running { background: #58a6ff; animation: pulse 1.5s infinite; }
282
+ .dot.succeeded { background: #3fb950; }
283
+ .dot.failed { background: #f85149; }
284
+ .node-id { font-weight: 600; color: #f0f6fc; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
285
+ .node-type { color: #8b949e; font-size: 11px; }
286
+ .node-time { color: #8b949e; font-size: 12px; margin-top: 4px; }
287
+ .node-error { color: #f85149; font-size: 12px; margin-top: 4px; word-break: break-word; }
288
+ .log-panel { background: #0d1117; border-left: 1px solid #21262d; display: flex; flex-direction: column; }
289
+ .log-header { padding: 12px 16px; font-weight: 600; font-size: 13px; border-bottom: 1px solid #21262d; color: #f0f6fc; }
290
+ .log-body { flex: 1; overflow-y: auto; padding: 8px 12px; font-size: 12px; line-height: 1.6; }
291
+ .log-entry { white-space: pre-wrap; word-break: break-word; }
292
+ .log-entry .ts { color: #484f58; }
293
+ .log-entry .icon-start { color: #58a6ff; }
294
+ .log-entry .icon-complete { color: #3fb950; }
295
+ .log-entry .icon-error { color: #f85149; }
296
+ .approval-card { background: #1c2128; border: 1px solid #d29922; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
297
+ .approval-card h3 { color: #d29922; font-size: 14px; margin-bottom: 8px; }
298
+ .approval-card pre { background: #0d1117; padding: 8px; border-radius: 4px; font-size: 11px; overflow-x: auto; margin-bottom: 12px; max-height: 200px; overflow-y: auto; color: #c9d1d9; }
299
+ .approval-buttons { display: flex; gap: 8px; }
300
+ .btn { padding: 6px 16px; border: none; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; font-family: inherit; }
301
+ .btn-approve { background: #238636; color: #fff; }
302
+ .btn-approve:hover { background: #2ea043; }
303
+ .btn-reject { background: #da3633; color: #fff; }
304
+ .btn-reject:hover { background: #e5534b; }
305
+ .empty { color: #484f58; padding: 40px; text-align: center; }
306
+ @media (max-width: 768px) { .main { grid-template-columns: 1fr; } .log-panel { border-left: none; border-top: 1px solid #21262d; max-height: 300px; } }
307
+ </style>
308
+ </head>
309
+ <body>
310
+ <div class="header">
311
+ <h1>Weaver</h1>
312
+ <span id="status" class="badge idle">idle</span>
313
+ <span id="workflow" style="color:#8b949e;font-size:13px"></span>
314
+ <span id="timer" class="timer"></span>
315
+ </div>
316
+ <div class="main">
317
+ <div class="nodes">
318
+ <div id="approvals"></div>
319
+ <div id="node-grid" class="node-grid"></div>
320
+ <div id="empty" class="empty">Waiting for workflow execution...</div>
321
+ </div>
322
+ <div class="log-panel">
323
+ <div class="log-header">Event Log</div>
324
+ <div id="log" class="log-body"></div>
325
+ </div>
326
+ </div>
327
+ <script>
328
+ (function() {
329
+ const state = { nodes: {}, events: [], status: 'idle', startedAt: null, approvals: [] };
330
+ const nodeGrid = document.getElementById('node-grid');
331
+ const logEl = document.getElementById('log');
332
+ const statusEl = document.getElementById('status');
333
+ const workflowEl = document.getElementById('workflow');
334
+ const timerEl = document.getElementById('timer');
335
+ const emptyEl = document.getElementById('empty');
336
+ const approvalsEl = document.getElementById('approvals');
337
+
338
+ function connect() {
339
+ const es = new EventSource('/events');
340
+ es.addEventListener('init', (e) => {
341
+ const d = JSON.parse(e.data);
342
+ state.status = d.status;
343
+ state.startedAt = d.startedAt;
344
+ state.nodes = d.nodes || {};
345
+ state.approvals = d.pendingApprovals || [];
346
+ if (d.workflowFile) workflowEl.textContent = d.workflowFile.split('/').pop();
347
+ for (const ev of d.events || []) addLog(ev);
348
+ render();
349
+ });
350
+ ['node-start','node-complete','node-error','workflow-start','workflow-complete','workflow-error','approval-pending','approval-resolved'].forEach(type => {
351
+ es.addEventListener(type, (e) => {
352
+ const ev = JSON.parse(e.data);
353
+ handleEvent(type, ev);
354
+ });
355
+ });
356
+ es.onerror = () => { es.close(); setTimeout(connect, 3000); };
357
+ }
358
+
359
+ function handleEvent(type, ev) {
360
+ if (type === 'workflow-start') {
361
+ state.status = 'running'; state.startedAt = ev.timestamp; state.nodes = {};
362
+ nodeGrid.innerHTML = ''; logEl.innerHTML = '';
363
+ } else if (type === 'workflow-complete') {
364
+ state.status = ev.summary && ev.summary.includes('fail') ? 'failed' : 'completed';
365
+ } else if (type === 'workflow-error') {
366
+ state.status = 'error';
367
+ } else if (type === 'approval-pending' && ev.approval) {
368
+ state.approvals.push(ev.approval);
369
+ } else if (type === 'approval-resolved') {
370
+ state.approvals = [];
371
+ }
372
+ if (ev.nodeId) {
373
+ const n = state.nodes[ev.nodeId] || { nodeId: ev.nodeId, status: 'pending' };
374
+ if (type === 'node-start') { n.status = 'running'; n.startedAt = ev.timestamp; n.nodeType = ev.nodeType; }
375
+ if (type === 'node-complete') { n.status = 'succeeded'; n.completedAt = ev.timestamp; if (n.startedAt) n.durationMs = ev.timestamp - n.startedAt; }
376
+ if (type === 'node-error') { n.status = 'failed'; n.error = ev.error; n.completedAt = ev.timestamp; }
377
+ state.nodes[ev.nodeId] = n;
378
+ }
379
+ addLog(ev);
380
+ render();
381
+ }
382
+
383
+ function addLog(ev) {
384
+ const t = ev.timestamp ? new Date(ev.timestamp).toLocaleTimeString() : '--:--:--';
385
+ const icons = { 'node-start': ['>', 'icon-start'], 'node-complete': ['+', 'icon-complete'], 'node-error': ['x', 'icon-error'] };
386
+ const [icon, cls] = icons[ev.type] || ['*', ''];
387
+ const id = ev.nodeId || ev.type;
388
+ const extra = ev.error ? ': ' + ev.error : (ev.summary ? ': ' + ev.summary : '');
389
+ const entry = document.createElement('div');
390
+ entry.className = 'log-entry';
391
+ entry.innerHTML = '<span class="ts">[' + t + ']</span> <span class="' + cls + '">' + icon + '</span> ' + esc(id) + esc(extra);
392
+ logEl.appendChild(entry);
393
+ logEl.scrollTop = logEl.scrollHeight;
394
+ }
395
+
396
+ function render() {
397
+ statusEl.className = 'badge ' + state.status;
398
+ statusEl.textContent = state.status;
399
+ emptyEl.style.display = Object.keys(state.nodes).length ? 'none' : 'block';
400
+
401
+ // Render nodes
402
+ for (const [id, n] of Object.entries(state.nodes)) {
403
+ let card = document.getElementById('node-' + id);
404
+ if (!card) {
405
+ card = document.createElement('div');
406
+ card.id = 'node-' + id;
407
+ card.className = 'node-card';
408
+ card.innerHTML = '<div class="node-header"><div class="dot"></div><div class="node-id"></div></div><div class="node-type"></div><div class="node-time"></div><div class="node-error"></div>';
409
+ nodeGrid.appendChild(card);
410
+ }
411
+ card.className = 'node-card ' + n.status;
412
+ card.querySelector('.dot').className = 'dot ' + n.status;
413
+ card.querySelector('.node-id').textContent = n.nodeId;
414
+ card.querySelector('.node-type').textContent = n.nodeType || '';
415
+ const timeEl = card.querySelector('.node-time');
416
+ if (n.durationMs != null) timeEl.textContent = (n.durationMs / 1000).toFixed(1) + 's';
417
+ else if (n.status === 'running' && n.startedAt) timeEl.setAttribute('data-start', n.startedAt);
418
+ const errEl = card.querySelector('.node-error');
419
+ errEl.textContent = n.error || '';
420
+ }
421
+
422
+ // Render approvals
423
+ approvalsEl.innerHTML = '';
424
+ for (const a of state.approvals) {
425
+ const card = document.createElement('div');
426
+ card.className = 'approval-card';
427
+ card.innerHTML = '<h3>Approval Required</h3><pre>' + esc(JSON.stringify(a.context, null, 2)) + '</pre><div class="approval-buttons"><button class="btn btn-approve" onclick="approve(\\'' + a.id + '\\')">Approve</button><button class="btn btn-reject" onclick="reject(\\'' + a.id + '\\')">Reject</button></div>';
428
+ approvalsEl.appendChild(card);
429
+ }
430
+ }
431
+
432
+ function esc(s) { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
433
+
434
+ window.approve = function(id) {
435
+ fetch('/api/approve/' + id, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' });
436
+ };
437
+ window.reject = function(id) {
438
+ const reason = prompt('Rejection reason (optional):') || '';
439
+ fetch('/api/reject/' + id, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ reason: reason || 'rejected via dashboard' }) });
440
+ };
441
+
442
+ // Running timer
443
+ setInterval(() => {
444
+ if (state.status === 'running' && state.startedAt) {
445
+ const s = ((Date.now() - state.startedAt) / 1000).toFixed(0);
446
+ timerEl.textContent = s + 's';
447
+ }
448
+ // Update running node timers
449
+ document.querySelectorAll('.node-time[data-start]').forEach(el => {
450
+ const s = ((Date.now() - parseInt(el.getAttribute('data-start'))) / 1000).toFixed(1);
451
+ el.textContent = s + 's';
452
+ });
453
+ }, 200);
454
+
455
+ connect();
456
+ })();
457
+ </script>
458
+ </body>
459
+ </html>`;
460
+ }
461
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/bot/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { EventEmitter } from 'node:events';
2
+ export interface FileWatcherOptions {
3
+ filePath: string;
4
+ debounceMs?: number;
5
+ pollingIntervalMs?: number;
6
+ }
7
+ export declare class FileWatcher extends EventEmitter {
8
+ private filePath;
9
+ private debounceMs;
10
+ private pollingIntervalMs;
11
+ private watcher;
12
+ private pollTimer;
13
+ private debounceTimer;
14
+ private lastMtime;
15
+ private stopped;
16
+ constructor(options: FileWatcherOptions);
17
+ start(): void;
18
+ stop(): void;
19
+ private attachFsWatch;
20
+ private switchToPolling;
21
+ private onFsEvent;
22
+ private getMtime;
23
+ }
24
+ //# sourceMappingURL=file-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-watcher.d.ts","sourceRoot":"","sources":["../../src/bot/file-watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,kBAAkB;IAOvC,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAUZ,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,eAAe;IAgCvB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,QAAQ;CAOjB"}
@@ -0,0 +1,98 @@
1
+ import * as fs from 'node:fs';
2
+ import { EventEmitter } from 'node:events';
3
+ export class FileWatcher extends EventEmitter {
4
+ filePath;
5
+ debounceMs;
6
+ pollingIntervalMs;
7
+ watcher = null;
8
+ pollTimer = null;
9
+ debounceTimer = null;
10
+ lastMtime = 0;
11
+ stopped = false;
12
+ constructor(options) {
13
+ super();
14
+ this.filePath = options.filePath;
15
+ this.debounceMs = options.debounceMs ?? 500;
16
+ this.pollingIntervalMs = options.pollingIntervalMs ?? 2000;
17
+ }
18
+ start() {
19
+ this.stopped = false;
20
+ this.lastMtime = this.getMtime();
21
+ this.attachFsWatch();
22
+ }
23
+ stop() {
24
+ this.stopped = true;
25
+ if (this.debounceTimer)
26
+ clearTimeout(this.debounceTimer);
27
+ if (this.pollTimer)
28
+ clearInterval(this.pollTimer);
29
+ if (this.watcher) {
30
+ this.watcher.close();
31
+ this.watcher = null;
32
+ }
33
+ }
34
+ attachFsWatch() {
35
+ try {
36
+ this.watcher = fs.watch(this.filePath, () => this.onFsEvent());
37
+ this.watcher.on('error', () => this.switchToPolling());
38
+ }
39
+ catch {
40
+ this.switchToPolling();
41
+ }
42
+ }
43
+ switchToPolling() {
44
+ if (this.stopped)
45
+ return;
46
+ if (this.watcher) {
47
+ this.watcher.close();
48
+ this.watcher = null;
49
+ }
50
+ if (this.pollTimer)
51
+ return;
52
+ this.pollTimer = setInterval(() => {
53
+ if (this.stopped)
54
+ return;
55
+ const mtime = this.getMtime();
56
+ if (mtime > this.lastMtime) {
57
+ this.lastMtime = mtime;
58
+ this.emit('change');
59
+ }
60
+ // Try to re-attach fs.watch
61
+ if (!this.watcher && fs.existsSync(this.filePath)) {
62
+ try {
63
+ this.watcher = fs.watch(this.filePath, () => this.onFsEvent());
64
+ this.watcher.on('error', () => this.switchToPolling());
65
+ if (this.pollTimer) {
66
+ clearInterval(this.pollTimer);
67
+ this.pollTimer = null;
68
+ }
69
+ }
70
+ catch {
71
+ // Stay in polling mode
72
+ }
73
+ }
74
+ }, this.pollingIntervalMs);
75
+ }
76
+ onFsEvent() {
77
+ if (this.stopped)
78
+ return;
79
+ if (this.debounceTimer)
80
+ clearTimeout(this.debounceTimer);
81
+ this.debounceTimer = setTimeout(() => {
82
+ const mtime = this.getMtime();
83
+ if (mtime > this.lastMtime) {
84
+ this.lastMtime = mtime;
85
+ this.emit('change');
86
+ }
87
+ }, this.debounceMs);
88
+ }
89
+ getMtime() {
90
+ try {
91
+ return fs.statSync(this.filePath).mtimeMs;
92
+ }
93
+ catch {
94
+ return 0;
95
+ }
96
+ }
97
+ }
98
+ //# sourceMappingURL=file-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-watcher.js","sourceRoot":"","sources":["../../src/bot/file-watcher.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- export type { BotConfig, BotProviderConfig, BotApprovalConfig, BotNotifyConfig, NotificationEvent, NotificationEventType, ExecutionEvent, ExecutionEventType, ApprovalMode, WeaverConfig, WorkflowResult, ProviderName, } from './types.js';
2
- export type { BotAgentProvider } from './agent-provider.js';
1
+ export type { BotConfig, BotProviderConfig, BotApprovalConfig, BotNotifyConfig, NotificationEvent, NotificationEventType, ExecutionEvent, ExecutionEventType, ApprovalMode, WeaverConfig, WorkflowResult, ProviderName, RunRecord, RunFilter, RetentionPolicy, RunOutcome, TokenUsage, OnUsageCallback, RunCostEntry, RunCostSummary, CostRecord, CostSummary, BotAgentProvider, ProviderMetadata, ProviderFactory, ProviderFactoryConfig, ProviderModule, CronExpression, ParsedCron, CronField, TriggerSource, WatchDaemonOptions, WatchDaemonState, StageCondition, StageStatus, PipelineStage, PipelineConfig, StageResult, PipelineResult, DashboardEventType, DashboardNodeStatus, DashboardEvent, DashboardNodeState, DashboardServerOptions, } from './types.js';
3
2
  export { AnthropicAgentProvider, resolveProviderConfig, createProvider, detectProvider, } from './agent-provider.js';
4
3
  export { CliAgentProvider } from './cli-provider.js';
4
+ export { ProviderRegistry, defaultRegistry, loadExternalProvider, discoverProviders } from './provider-registry.js';
5
5
  export { BotAgentChannel } from './bot-agent-channel.js';
6
6
  export type { BotChannelContext } from './bot-agent-channel.js';
7
7
  export { WebhookNotificationChannel, createNotifier, } from './notifications.js';
@@ -10,4 +10,16 @@ export { buildSystemPrompt } from './system-prompt.js';
10
10
  export { runWorkflow } from './runner.js';
11
11
  export { createApprovalHandler } from './approvals.js';
12
12
  export type { ApprovalHandler, ApprovalResult } from './approvals.js';
13
+ export { RunStore } from './run-store.js';
14
+ export { CostTracker, MODEL_PRICING } from './cost-tracker.js';
15
+ export { CostStore } from './cost-store.js';
16
+ export { parseCron, matches as cronMatches, nextMatch as cronNextMatch } from './cron-parser.js';
17
+ export { FileWatcher } from './file-watcher.js';
18
+ export { CronScheduler } from './cron-scheduler.js';
19
+ export { WatchDaemon } from './watch-daemon.js';
20
+ export { PipelineRunner } from './pipeline-runner.js';
21
+ export type { PipelineRunOptions } from './pipeline-runner.js';
22
+ export { DashboardServer } from './dashboard.js';
23
+ export { openBrowser } from './utils.js';
24
+ export { WebApprovalHandler } from './web-approval.js';
13
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bot/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,cAAc,EACd,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACL,0BAA0B,EAC1B,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bot/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,SAAS,EACT,SAAS,EACT,eAAe,EACf,UAAU,EACV,UAAU,EACV,eAAe,EACf,YAAY,EACZ,cAAc,EACd,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,UAAU,EACV,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,cAAc,EACd,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACL,0BAA0B,EAC1B,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,OAAO,IAAI,WAAW,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}