beecork 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/cli/commands.d.ts.map +1 -1
  2. package/dist/cli/commands.js +30 -10
  3. package/dist/cli/commands.js.map +1 -1
  4. package/dist/cli/helpers.d.ts +1 -2
  5. package/dist/cli/helpers.d.ts.map +1 -1
  6. package/dist/cli/helpers.js +1 -25
  7. package/dist/cli/helpers.js.map +1 -1
  8. package/dist/config.d.ts +0 -1
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +12 -6
  11. package/dist/config.js.map +1 -1
  12. package/dist/cron/scheduler.d.ts +3 -4
  13. package/dist/cron/scheduler.d.ts.map +1 -1
  14. package/dist/cron/scheduler.js +20 -14
  15. package/dist/cron/scheduler.js.map +1 -1
  16. package/dist/daemon.js +63 -21
  17. package/dist/daemon.js.map +1 -1
  18. package/dist/dashboard/html.d.ts +2 -0
  19. package/dist/dashboard/html.d.ts.map +1 -0
  20. package/dist/dashboard/html.js +357 -0
  21. package/dist/dashboard/html.js.map +1 -0
  22. package/dist/dashboard/server.d.ts +2 -0
  23. package/dist/dashboard/server.d.ts.map +1 -0
  24. package/dist/dashboard/server.js +129 -0
  25. package/dist/dashboard/server.js.map +1 -0
  26. package/dist/db/index.d.ts.map +1 -1
  27. package/dist/db/index.js +1 -0
  28. package/dist/db/index.js.map +1 -1
  29. package/dist/index.js +10 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/mcp/server.js +81 -80
  32. package/dist/mcp/server.js.map +1 -1
  33. package/dist/memory/extractor.d.ts.map +1 -1
  34. package/dist/memory/extractor.js +28 -8
  35. package/dist/memory/extractor.js.map +1 -1
  36. package/dist/pipe/anthropic-client.d.ts +3 -1
  37. package/dist/pipe/anthropic-client.d.ts.map +1 -1
  38. package/dist/pipe/anthropic-client.js +7 -5
  39. package/dist/pipe/anthropic-client.js.map +1 -1
  40. package/dist/pipe/brain.d.ts.map +1 -1
  41. package/dist/pipe/brain.js +7 -8
  42. package/dist/pipe/brain.js.map +1 -1
  43. package/dist/pipe/memory-store.d.ts.map +1 -1
  44. package/dist/pipe/types.d.ts +0 -9
  45. package/dist/pipe/types.d.ts.map +1 -1
  46. package/dist/session/manager.d.ts +1 -0
  47. package/dist/session/manager.d.ts.map +1 -1
  48. package/dist/session/manager.js +21 -8
  49. package/dist/session/manager.js.map +1 -1
  50. package/dist/session/subprocess.d.ts +0 -2
  51. package/dist/session/subprocess.d.ts.map +1 -1
  52. package/dist/session/subprocess.js +0 -10
  53. package/dist/session/subprocess.js.map +1 -1
  54. package/dist/telegram/bot.d.ts.map +1 -1
  55. package/dist/telegram/bot.js +15 -17
  56. package/dist/telegram/bot.js.map +1 -1
  57. package/dist/telegram/formatter.d.ts +2 -4
  58. package/dist/telegram/formatter.d.ts.map +1 -1
  59. package/dist/telegram/formatter.js +3 -44
  60. package/dist/telegram/formatter.js.map +1 -1
  61. package/dist/types.d.ts +0 -11
  62. package/dist/types.d.ts.map +1 -1
  63. package/dist/types.js +3 -0
  64. package/dist/types.js.map +1 -1
  65. package/dist/util/text.d.ts +10 -0
  66. package/dist/util/text.d.ts.map +1 -0
  67. package/dist/util/text.js +53 -0
  68. package/dist/util/text.js.map +1 -0
  69. package/dist/version.d.ts +2 -0
  70. package/dist/version.d.ts.map +1 -0
  71. package/dist/version.js +5 -0
  72. package/dist/version.js.map +1 -0
  73. package/dist/whatsapp/client.d.ts +3 -0
  74. package/dist/whatsapp/client.d.ts.map +1 -1
  75. package/dist/whatsapp/client.js +32 -12
  76. package/dist/whatsapp/client.js.map +1 -1
  77. package/dist/whatsapp/formatter.d.ts +2 -2
  78. package/dist/whatsapp/formatter.d.ts.map +1 -1
  79. package/dist/whatsapp/formatter.js +5 -23
  80. package/dist/whatsapp/formatter.js.map +1 -1
  81. package/package.json +2 -5
  82. package/templates/CLAUDE.md +0 -25
@@ -0,0 +1,357 @@
1
+ export function getDashboardHtml() {
2
+ return `<!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Beecork Dashboard</title>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script>
10
+ tailwind.config = {
11
+ theme: {
12
+ extend: {
13
+ colors: {
14
+ honey: { 50: '#fefce8', 100: '#fef9c3', 200: '#fef08a', 300: '#fde047', 400: '#facc15', 500: '#eab308', 600: '#ca8a04', 700: '#a16207' },
15
+ bee: { 900: '#1a1a1a', 800: '#262626', 700: '#333333', 600: '#444444' }
16
+ }
17
+ }
18
+ }
19
+ }
20
+ </script>
21
+ <style>
22
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
23
+ .msg-user { background: #2d2d2d; border-left: 3px solid #facc15; }
24
+ .msg-assistant { background: #1f1f1f; border-left: 3px solid #666; }
25
+ .tab-active { background: #facc1520; border-left: 3px solid #facc15; }
26
+ .cost-bar { background: linear-gradient(to top, #facc15, #eab308); border-radius: 2px 2px 0 0; }
27
+ ::-webkit-scrollbar { width: 6px; }
28
+ ::-webkit-scrollbar-track { background: #1a1a1a; }
29
+ ::-webkit-scrollbar-thumb { background: #444; border-radius: 3px; }
30
+ </style>
31
+ </head>
32
+ <body class="bg-bee-900 text-gray-200 min-h-screen">
33
+
34
+ <!-- Header -->
35
+ <header class="bg-bee-800 border-b border-bee-600 px-6 py-3 flex items-center justify-between">
36
+ <div class="flex items-center gap-3">
37
+ <span class="text-2xl">🐝</span>
38
+ <h1 class="text-lg font-semibold text-white">Beecork</h1>
39
+ <span id="version" class="text-xs text-gray-500 font-mono"></span>
40
+ <span id="update-badge" class="hidden text-xs bg-honey-500 text-black px-2 py-0.5 rounded-full font-medium"></span>
41
+ </div>
42
+ <div class="flex items-center gap-4">
43
+ <div class="flex items-center gap-2">
44
+ <span id="daemon-dot" class="w-2.5 h-2.5 rounded-full bg-gray-600"></span>
45
+ <span id="daemon-status" class="text-sm text-gray-400">checking...</span>
46
+ </div>
47
+ <div class="text-xs text-gray-500 font-mono" id="stats"></div>
48
+ </div>
49
+ </header>
50
+
51
+ <!-- Navigation -->
52
+ <nav class="bg-bee-800 border-b border-bee-700 px-6">
53
+ <div class="flex gap-1">
54
+ <button onclick="showPanel('tabs')" data-panel="tabs" class="nav-btn px-4 py-2 text-sm rounded-t border-b-2 border-transparent hover:text-white text-gray-400">Tabs</button>
55
+ <button onclick="showPanel('memories')" data-panel="memories" class="nav-btn px-4 py-2 text-sm rounded-t border-b-2 border-transparent hover:text-white text-gray-400">Memories</button>
56
+ <button onclick="showPanel('crons')" data-panel="crons" class="nav-btn px-4 py-2 text-sm rounded-t border-b-2 border-transparent hover:text-white text-gray-400">Cron Jobs</button>
57
+ <button onclick="showPanel('costs')" data-panel="costs" class="nav-btn px-4 py-2 text-sm rounded-t border-b-2 border-transparent hover:text-white text-gray-400">Costs</button>
58
+ </div>
59
+ </nav>
60
+
61
+ <!-- Main content -->
62
+ <main class="p-6">
63
+
64
+ <!-- Tabs Panel -->
65
+ <div id="panel-tabs" class="panel">
66
+ <div class="grid grid-cols-12 gap-6">
67
+ <!-- Tab list -->
68
+ <div class="col-span-4 bg-bee-800 rounded-lg border border-bee-700 overflow-hidden">
69
+ <div class="px-4 py-3 border-b border-bee-700 flex items-center justify-between">
70
+ <h2 class="text-sm font-semibold text-gray-300">Tabs</h2>
71
+ <span id="tab-count" class="text-xs text-gray-500"></span>
72
+ </div>
73
+ <div id="tab-list" class="max-h-[calc(100vh-220px)] overflow-y-auto"></div>
74
+ </div>
75
+ <!-- Messages -->
76
+ <div class="col-span-8 bg-bee-800 rounded-lg border border-bee-700 overflow-hidden">
77
+ <div class="px-4 py-3 border-b border-bee-700 flex items-center justify-between">
78
+ <h2 class="text-sm font-semibold text-gray-300" id="msg-title">Select a tab</h2>
79
+ <span id="msg-count" class="text-xs text-gray-500"></span>
80
+ </div>
81
+ <div id="msg-list" class="max-h-[calc(100vh-220px)] overflow-y-auto p-4 space-y-3">
82
+ <p class="text-gray-500 text-sm text-center py-8">Click a tab to view messages</p>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+
88
+ <!-- Memories Panel -->
89
+ <div id="panel-memories" class="panel hidden">
90
+ <div class="bg-bee-800 rounded-lg border border-bee-700 overflow-hidden">
91
+ <div class="px-4 py-3 border-b border-bee-700 flex items-center justify-between">
92
+ <h2 class="text-sm font-semibold text-gray-300">Memories</h2>
93
+ <div class="flex items-center gap-3">
94
+ <input id="memory-search" type="text" placeholder="Search memories..."
95
+ class="bg-bee-900 border border-bee-600 rounded px-3 py-1 text-sm text-gray-300 w-64 focus:outline-none focus:border-honey-500"
96
+ oninput="debounceMemorySearch()">
97
+ <span id="memory-count" class="text-xs text-gray-500"></span>
98
+ </div>
99
+ </div>
100
+ <div id="memory-list" class="max-h-[calc(100vh-220px)] overflow-y-auto"></div>
101
+ </div>
102
+ </div>
103
+
104
+ <!-- Cron Panel -->
105
+ <div id="panel-crons" class="panel hidden">
106
+ <div class="bg-bee-800 rounded-lg border border-bee-700 overflow-hidden">
107
+ <div class="px-4 py-3 border-b border-bee-700">
108
+ <h2 class="text-sm font-semibold text-gray-300">Cron Jobs</h2>
109
+ </div>
110
+ <div id="cron-list" class="max-h-[calc(100vh-220px)] overflow-y-auto"></div>
111
+ </div>
112
+ </div>
113
+
114
+ <!-- Costs Panel -->
115
+ <div id="panel-costs" class="panel hidden">
116
+ <div class="bg-bee-800 rounded-lg border border-bee-700 overflow-hidden">
117
+ <div class="px-4 py-3 border-b border-bee-700 flex items-center justify-between">
118
+ <h2 class="text-sm font-semibold text-gray-300">API Costs (Last 30 Days)</h2>
119
+ <span id="total-cost" class="text-sm font-mono text-honey-400"></span>
120
+ </div>
121
+ <div id="cost-chart" class="p-6"></div>
122
+ </div>
123
+ </div>
124
+
125
+ </main>
126
+
127
+ <script>
128
+ // State
129
+ let selectedTab = null;
130
+ let memorySearchTimer = null;
131
+
132
+ // API helper
133
+ async function api(path) {
134
+ const res = await fetch(path);
135
+ return res.json();
136
+ }
137
+
138
+ // Time formatting
139
+ function timeAgo(iso) {
140
+ if (!iso) return 'never';
141
+ const diff = Date.now() - new Date(iso).getTime();
142
+ const mins = Math.floor(diff / 60000);
143
+ if (mins < 1) return 'just now';
144
+ if (mins < 60) return mins + 'm ago';
145
+ const hours = Math.floor(mins / 60);
146
+ if (hours < 24) return hours + 'h ago';
147
+ return Math.floor(hours / 24) + 'd ago';
148
+ }
149
+
150
+ // Panel switching
151
+ function showPanel(name) {
152
+ document.querySelectorAll('.panel').forEach(p => p.classList.add('hidden'));
153
+ document.getElementById('panel-' + name).classList.remove('hidden');
154
+ document.querySelectorAll('.nav-btn').forEach(b => {
155
+ b.classList.remove('border-honey-500', 'text-white');
156
+ b.classList.add('border-transparent', 'text-gray-400');
157
+ });
158
+ const btn = document.querySelector('[data-panel="' + name + '"]');
159
+ btn.classList.add('border-honey-500', 'text-white');
160
+ btn.classList.remove('border-transparent', 'text-gray-400');
161
+
162
+ if (name === 'memories') loadMemories();
163
+ if (name === 'crons') loadCrons();
164
+ if (name === 'costs') loadCosts();
165
+ }
166
+
167
+ // Status polling
168
+ async function loadStatus() {
169
+ try {
170
+ const s = await api('/api/status');
171
+ document.getElementById('version').textContent = 'v' + s.version;
172
+ const dot = document.getElementById('daemon-dot');
173
+ const status = document.getElementById('daemon-status');
174
+ if (s.daemonPid) {
175
+ dot.className = 'w-2.5 h-2.5 rounded-full bg-green-500';
176
+ status.textContent = 'running (PID ' + s.daemonPid + ')';
177
+ } else {
178
+ dot.className = 'w-2.5 h-2.5 rounded-full bg-red-500';
179
+ status.textContent = 'stopped';
180
+ }
181
+ document.getElementById('stats').textContent =
182
+ s.tabs + ' tabs | ' + s.cronJobs + ' crons | ' + s.memories + ' memories';
183
+ } catch {}
184
+ }
185
+
186
+ // Tabs
187
+ async function loadTabs() {
188
+ const tabs = await api('/api/tabs');
189
+ const list = document.getElementById('tab-list');
190
+ document.getElementById('tab-count').textContent = tabs.length + ' tabs';
191
+
192
+ if (tabs.length === 0) {
193
+ list.innerHTML = '<p class="text-gray-500 text-sm text-center py-8">No tabs</p>';
194
+ return;
195
+ }
196
+
197
+ list.innerHTML = tabs.map(t => {
198
+ const statusColors = { idle: 'text-gray-500', running: 'text-green-400', error: 'text-red-400', stopped: 'text-gray-600' };
199
+ const isActive = selectedTab === t.name ? 'tab-active' : '';
200
+ const cost = t.total_cost > 0 ? '$' + t.total_cost.toFixed(4) : '';
201
+ return '<div class="px-4 py-3 border-b border-bee-700 cursor-pointer hover:bg-bee-700 ' + isActive + '" onclick="selectTab(\\''+t.name+'\\')">' +
202
+ '<div class="flex items-center justify-between">' +
203
+ '<span class="text-sm font-medium text-white">' + esc(t.name) + '</span>' +
204
+ '<span class="text-xs ' + (statusColors[t.status] || 'text-gray-500') + '">' + t.status + '</span>' +
205
+ '</div>' +
206
+ '<div class="flex items-center justify-between mt-1">' +
207
+ '<span class="text-xs text-gray-500">' + t.message_count + ' msgs' + (cost ? ' | ' + cost : '') + '</span>' +
208
+ '<span class="text-xs text-gray-600">' + timeAgo(t.last_activity_at) + '</span>' +
209
+ '</div>' +
210
+ '</div>';
211
+ }).join('');
212
+ }
213
+
214
+ async function selectTab(name) {
215
+ selectedTab = name;
216
+ document.getElementById('msg-title').textContent = name;
217
+ loadTabs(); // refresh active highlight
218
+
219
+ const data = await api('/api/tabs/' + encodeURIComponent(name) + '/messages?limit=100');
220
+ const list = document.getElementById('msg-list');
221
+ document.getElementById('msg-count').textContent = data.total + ' messages';
222
+
223
+ if (data.messages.length === 0) {
224
+ list.innerHTML = '<p class="text-gray-500 text-sm text-center py-8">No messages in this tab</p>';
225
+ return;
226
+ }
227
+
228
+ list.innerHTML = data.messages.map(m => {
229
+ const cls = m.role === 'user' ? 'msg-user' : 'msg-assistant';
230
+ const label = m.role === 'user' ? 'You' : 'Claude';
231
+ const meta = [];
232
+ if (m.cost_usd > 0) meta.push('$' + m.cost_usd.toFixed(4));
233
+ if (m.tokens_in) meta.push(m.tokens_in.toLocaleString() + ' in');
234
+ if (m.tokens_out) meta.push(m.tokens_out.toLocaleString() + ' out');
235
+ const metaStr = meta.length ? '<span class="text-xs text-gray-600 ml-2">' + meta.join(' | ') + '</span>' : '';
236
+
237
+ // Truncate very long messages
238
+ const content = m.content.length > 2000 ? m.content.slice(0, 2000) + '\\n\\n... (' + m.content.length.toLocaleString() + ' chars total)' : m.content;
239
+
240
+ return '<div class="' + cls + ' rounded p-3">' +
241
+ '<div class="flex items-center justify-between mb-1">' +
242
+ '<span class="text-xs font-semibold ' + (m.role === 'user' ? 'text-honey-400' : 'text-gray-400') + '">' + label + metaStr + '</span>' +
243
+ '<span class="text-xs text-gray-600">' + timeAgo(m.created_at) + '</span>' +
244
+ '</div>' +
245
+ '<pre class="text-sm text-gray-300 whitespace-pre-wrap break-words font-sans">' + esc(content) + '</pre>' +
246
+ '</div>';
247
+ }).join('');
248
+
249
+ list.scrollTop = list.scrollHeight;
250
+ }
251
+
252
+ // Memories
253
+ async function loadMemories(query) {
254
+ const q = query || document.getElementById('memory-search').value || '';
255
+ const data = await api('/api/memories?limit=100&q=' + encodeURIComponent(q));
256
+ const list = document.getElementById('memory-list');
257
+ document.getElementById('memory-count').textContent = data.total + ' memories';
258
+
259
+ if (data.memories.length === 0) {
260
+ list.innerHTML = '<p class="text-gray-500 text-sm text-center py-8">No memories' + (q ? ' matching "' + esc(q) + '"' : '') + '</p>';
261
+ return;
262
+ }
263
+
264
+ list.innerHTML = data.memories.map(m => {
265
+ const scope = m.tab_name ? 'tab:' + m.tab_name : 'global';
266
+ return '<div class="px-4 py-3 border-b border-bee-700">' +
267
+ '<div class="flex items-center justify-between mb-1">' +
268
+ '<div class="flex items-center gap-2">' +
269
+ '<span class="text-xs px-1.5 py-0.5 rounded ' + (m.source === 'auto' ? 'bg-blue-900 text-blue-300' : 'bg-purple-900 text-purple-300') + '">' + m.source + '</span>' +
270
+ '<span class="text-xs text-gray-500">' + scope + '</span>' +
271
+ '</div>' +
272
+ '<span class="text-xs text-gray-600">' + timeAgo(m.created_at) + '</span>' +
273
+ '</div>' +
274
+ '<p class="text-sm text-gray-300">' + esc(m.content) + '</p>' +
275
+ '</div>';
276
+ }).join('');
277
+ }
278
+
279
+ function debounceMemorySearch() {
280
+ clearTimeout(memorySearchTimer);
281
+ memorySearchTimer = setTimeout(() => loadMemories(), 300);
282
+ }
283
+
284
+ // Crons
285
+ async function loadCrons() {
286
+ const crons = await api('/api/crons');
287
+ const list = document.getElementById('cron-list');
288
+
289
+ if (crons.length === 0) {
290
+ list.innerHTML = '<p class="text-gray-500 text-sm text-center py-8">No cron jobs</p>';
291
+ return;
292
+ }
293
+
294
+ list.innerHTML = crons.map(c => {
295
+ const enabled = c.enabled === 1;
296
+ return '<div class="px-4 py-3 border-b border-bee-700">' +
297
+ '<div class="flex items-center justify-between">' +
298
+ '<div class="flex items-center gap-2">' +
299
+ '<span class="w-2 h-2 rounded-full ' + (enabled ? 'bg-green-500' : 'bg-gray-600') + '"></span>' +
300
+ '<span class="text-sm font-medium text-white">' + esc(c.name) + '</span>' +
301
+ '</div>' +
302
+ '<span class="text-xs font-mono text-gray-400">' + c.schedule_type + ': ' + esc(c.schedule) + '</span>' +
303
+ '</div>' +
304
+ '<div class="flex items-center justify-between mt-1 pl-4">' +
305
+ '<span class="text-xs text-gray-500">tab: ' + esc(c.tab_name) + ' | message: ' + esc((c.message || '').slice(0, 60)) + '</span>' +
306
+ '<span class="text-xs text-gray-600">last: ' + timeAgo(c.last_run_at) + '</span>' +
307
+ '</div>' +
308
+ '</div>';
309
+ }).join('');
310
+ }
311
+
312
+ // Costs
313
+ async function loadCosts() {
314
+ const costs = await api('/api/costs');
315
+ const chart = document.getElementById('cost-chart');
316
+
317
+ if (costs.length === 0) {
318
+ chart.innerHTML = '<p class="text-gray-500 text-sm text-center py-8">No cost data yet</p>';
319
+ document.getElementById('total-cost').textContent = '';
320
+ return;
321
+ }
322
+
323
+ const total = costs.reduce((s, c) => s + c.total_cost, 0);
324
+ document.getElementById('total-cost').textContent = 'Total: $' + total.toFixed(4);
325
+
326
+ const maxCost = Math.max(...costs.map(c => c.total_cost));
327
+
328
+ chart.innerHTML =
329
+ '<div class="flex items-end gap-1 h-48">' +
330
+ costs.map(c => {
331
+ const pct = maxCost > 0 ? (c.total_cost / maxCost * 100) : 0;
332
+ const day = c.day.slice(5); // MM-DD
333
+ return '<div class="flex-1 flex flex-col items-center gap-1">' +
334
+ '<span class="text-xs text-gray-500 font-mono">$' + c.total_cost.toFixed(3) + '</span>' +
335
+ '<div class="w-full cost-bar" style="height:' + Math.max(pct, 2) + '%" title="' + c.day + ': $' + c.total_cost.toFixed(4) + ' (' + c.message_count + ' msgs)"></div>' +
336
+ '<span class="text-xs text-gray-600 font-mono">' + day + '</span>' +
337
+ '</div>';
338
+ }).join('') +
339
+ '</div>';
340
+ }
341
+
342
+ // HTML escaping
343
+ function esc(s) {
344
+ if (!s) return '';
345
+ return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
346
+ }
347
+
348
+ // Init
349
+ showPanel('tabs');
350
+ loadStatus();
351
+ loadTabs();
352
+ setInterval(loadStatus, 5000);
353
+ </script>
354
+ </body>
355
+ </html>`;
356
+ }
357
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB;IAC9B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiWD,CAAC;AACT,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function startDashboardServer(port?: number): void;
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AAyBA,wBAAgB,oBAAoB,CAAC,IAAI,SAAI,GAAG,IAAI,CAwHnD"}
@@ -0,0 +1,129 @@
1
+ import http from 'node:http';
2
+ import { exec } from 'node:child_process';
3
+ import { platform } from 'node:os';
4
+ import Database from 'better-sqlite3';
5
+ import { getDbPath } from '../util/paths.js';
6
+ import { getDashboardHtml } from './html.js';
7
+ import { VERSION } from '../version.js';
8
+ import { getDaemonPid } from '../cli/helpers.js';
9
+ function getDb() {
10
+ const db = new Database(getDbPath(), { readonly: true });
11
+ db.pragma('journal_mode = WAL');
12
+ return db;
13
+ }
14
+ function json(res, data, status = 200) {
15
+ res.writeHead(status, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
16
+ res.end(JSON.stringify(data));
17
+ }
18
+ function openBrowser(url) {
19
+ const cmd = platform() === 'darwin' ? 'open' : 'xdg-open';
20
+ exec(`${cmd} ${url}`);
21
+ }
22
+ export function startDashboardServer(port = 0) {
23
+ const server = http.createServer((req, res) => {
24
+ const url = new URL(req.url || '/', `http://localhost`);
25
+ const path = url.pathname;
26
+ // Serve HTML
27
+ if (path === '/' || path === '/index.html') {
28
+ res.writeHead(200, { 'Content-Type': 'text/html' });
29
+ res.end(getDashboardHtml());
30
+ return;
31
+ }
32
+ // API routes
33
+ let db = null;
34
+ try {
35
+ db = getDb();
36
+ if (path === '/api/status') {
37
+ const pid = getDaemonPid();
38
+ const tabCount = db.prepare('SELECT COUNT(*) as c FROM tabs').get().c;
39
+ const activeCount = db.prepare("SELECT COUNT(*) as c FROM tabs WHERE status = 'running'").get().c;
40
+ const cronCount = db.prepare("SELECT COUNT(*) as c FROM cron_jobs WHERE enabled = 1").get().c;
41
+ const memoryCount = db.prepare('SELECT COUNT(*) as c FROM memories').get().c;
42
+ json(res, { version: VERSION, daemonPid: pid, tabs: tabCount, activeTabs: activeCount, cronJobs: cronCount, memories: memoryCount });
43
+ return;
44
+ }
45
+ if (path === '/api/tabs') {
46
+ const tabs = db.prepare(`
47
+ SELECT t.*,
48
+ (SELECT COUNT(*) FROM messages WHERE tab_id = t.id) as message_count,
49
+ (SELECT COALESCE(SUM(cost_usd), 0) FROM messages WHERE tab_id = t.id) as total_cost
50
+ FROM tabs t ORDER BY t.last_activity_at DESC
51
+ `).all();
52
+ json(res, tabs);
53
+ return;
54
+ }
55
+ const tabMsgMatch = path.match(/^\/api\/tabs\/([^/]+)\/messages$/);
56
+ if (tabMsgMatch) {
57
+ const tabName = decodeURIComponent(tabMsgMatch[1]);
58
+ const limit = Math.min(parseInt(url.searchParams.get('limit') || '50'), 200);
59
+ const offset = parseInt(url.searchParams.get('offset') || '0');
60
+ const tab = db.prepare('SELECT id FROM tabs WHERE name = ?').get(tabName);
61
+ if (!tab) {
62
+ json(res, { error: 'Tab not found' }, 404);
63
+ return;
64
+ }
65
+ const messages = db.prepare('SELECT role, content, cost_usd, tokens_in, tokens_out, created_at FROM messages WHERE tab_id = ? ORDER BY created_at DESC LIMIT ? OFFSET ?').all(tab.id, limit, offset);
66
+ const total = db.prepare('SELECT COUNT(*) as c FROM messages WHERE tab_id = ?').get(tab.id).c;
67
+ json(res, { messages: messages.reverse(), total, limit, offset });
68
+ return;
69
+ }
70
+ if (path === '/api/memories') {
71
+ const limit = Math.min(parseInt(url.searchParams.get('limit') || '50'), 200);
72
+ const offset = parseInt(url.searchParams.get('offset') || '0');
73
+ const q = url.searchParams.get('q') || '';
74
+ let memories, total;
75
+ if (q) {
76
+ memories = db.prepare('SELECT id, content, tab_name, source, created_at FROM memories WHERE content LIKE ? ORDER BY created_at DESC LIMIT ? OFFSET ?').all(`%${q}%`, limit, offset);
77
+ total = db.prepare('SELECT COUNT(*) as c FROM memories WHERE content LIKE ?').get(`%${q}%`).c;
78
+ }
79
+ else {
80
+ memories = db.prepare('SELECT id, content, tab_name, source, created_at FROM memories ORDER BY created_at DESC LIMIT ? OFFSET ?').all(limit, offset);
81
+ total = db.prepare('SELECT COUNT(*) as c FROM memories').get().c;
82
+ }
83
+ json(res, { memories, total, limit, offset });
84
+ return;
85
+ }
86
+ if (path === '/api/crons') {
87
+ const crons = db.prepare('SELECT * FROM cron_jobs ORDER BY created_at').all();
88
+ json(res, crons);
89
+ return;
90
+ }
91
+ if (path === '/api/costs') {
92
+ const costs = db.prepare(`
93
+ SELECT date(created_at) as day,
94
+ SUM(cost_usd) as total_cost,
95
+ COUNT(*) as message_count
96
+ FROM messages
97
+ WHERE role = 'assistant' AND cost_usd > 0
98
+ AND created_at > datetime('now', '-30 days')
99
+ GROUP BY date(created_at)
100
+ ORDER BY day
101
+ `).all();
102
+ json(res, costs);
103
+ return;
104
+ }
105
+ // 404
106
+ json(res, { error: 'Not found' }, 404);
107
+ }
108
+ catch (err) {
109
+ json(res, { error: err instanceof Error ? err.message : String(err) }, 500);
110
+ }
111
+ finally {
112
+ db?.close();
113
+ }
114
+ });
115
+ server.listen(port, '127.0.0.1', () => {
116
+ const addr = server.address();
117
+ if (addr && typeof addr === 'object') {
118
+ const url = `http://localhost:${addr.port}`;
119
+ console.log(`\nBeecork Dashboard: ${url}\n`);
120
+ console.log('Press Ctrl+C to stop.\n');
121
+ openBrowser(url);
122
+ }
123
+ });
124
+ process.on('SIGINT', () => {
125
+ server.close();
126
+ process.exit(0);
127
+ });
128
+ }
129
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,SAAS,KAAK;IACZ,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,IAAI,CAAC,GAAwB,EAAE,IAAa,EAAE,MAAM,GAAG,GAAG;IACjE,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,GAAG,EAAE,CAAC,CAAC;IAClG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,GAAG,GAAG,QAAQ,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;IAC1D,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAI,GAAG,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;QAE1B,aAAa;QACb,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YAC3C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,aAAa;QACb,IAAI,EAAE,GAA6B,IAAI,CAAC;QACxC,IAAI,CAAC;YACH,EAAE,GAAG,KAAK,EAAE,CAAC;YAEb,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GAAI,EAAE,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;gBACzF,MAAM,WAAW,GAAI,EAAE,CAAC,OAAO,CAAC,yDAAyD,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;gBACrH,MAAM,SAAS,GAAI,EAAE,CAAC,OAAO,CAAC,uDAAuD,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;gBACjH,MAAM,WAAW,GAAI,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;gBAChG,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;gBACrI,OAAO;YACT,CAAC;YAED,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;SAKvB,CAAC,CAAC,GAAG,EAAE,CAAC;gBACT,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACnE,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC7E,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;gBAC/D,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,OAAO,CAA+B,CAAC;gBACxG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAC;oBAC3C,OAAO;gBACT,CAAC;gBACD,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CACzB,4IAA4I,CAC7I,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC7B,MAAM,KAAK,GAAI,EAAE,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAmB,CAAC,CAAC,CAAC;gBACjH,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAG,QAA2C,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBACtG,OAAO;YACT,CAAC;YAED,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;gBAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC7E,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;gBAC/D,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC1C,IAAI,QAAQ,EAAE,KAAa,CAAC;gBAC5B,IAAI,CAAC,EAAE,CAAC;oBACN,QAAQ,GAAG,EAAE,CAAC,OAAO,CACnB,+HAA+H,CAChI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;oBAC/B,KAAK,GAAI,EAAE,CAAC,OAAO,CAAC,yDAAyD,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAmB,CAAC,CAAC,CAAC;gBACnH,CAAC;qBAAM,CAAC;oBACN,QAAQ,GAAG,EAAE,CAAC,OAAO,CACnB,0GAA0G,CAC3G,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;oBACrB,KAAK,GAAI,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;gBACtF,CAAC;gBACD,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC9C,OAAO;YACT,CAAC;YAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC,GAAG,EAAE,CAAC;gBAC9E,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;SASxB,CAAC,CAAC,GAAG,EAAE,CAAC;gBACT,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,MAAM;YACN,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9E,CAAC;gBAAS,CAAC;YACT,EAAE,EAAE,KAAK,EAAE,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YACvC,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAkDtC,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAYzC;AAED,wBAAgB,OAAO,IAAI,IAAI,CAK9B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAkDtC,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAazC;AAED,wBAAgB,OAAO,IAAI,IAAI,CAK9B"}
package/dist/db/index.js CHANGED
@@ -53,6 +53,7 @@ export function getDb() {
53
53
  db = new Database(dbPath);
54
54
  db.pragma('journal_mode = WAL');
55
55
  db.pragma('foreign_keys = ON');
56
+ db.pragma('busy_timeout = 5000');
56
57
  db.exec(SCHEMA);
57
58
  runMigrations(db);
58
59
  return db;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Cd,CAAC;AAEF,IAAI,EAAE,GAA6B,IAAI,CAAC;AAExC,MAAM,UAAU,KAAK;IACnB,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAElB,iBAAiB,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChB,aAAa,CAAC,EAAE,CAAC,CAAC;IAElB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,EAAE,GAAG,IAAI,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Cd,CAAC;AAEF,IAAI,EAAE,GAA6B,IAAI,CAAC;AAExC,MAAM,UAAU,KAAK;IACnB,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAElB,iBAAiB,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACjC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChB,aAAa,CAAC,EAAE,CAAC,CAAC;IAElB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,EAAE,GAAG,IAAI,CAAC;IACZ,CAAC;AACH,CAAC"}
package/dist/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
+ import { VERSION } from './version.js';
3
4
  import { setupWizard } from './cli/setup.js';
4
5
  import { startDaemon, stopDaemon, showStatus, listTabs, tailLogs, listCrons, deleteCron, listMemories, deleteMemory, sendMessage, updateBeecork, } from './cli/commands.js';
5
6
  const program = new Command();
6
7
  program
7
8
  .name('beecork')
8
- .version('0.1.0')
9
+ .version(VERSION)
9
10
  .description('Claude Code always-on infrastructure — a phone number, a memory, and an alarm clock');
10
11
  program
11
12
  .command('setup')
@@ -62,5 +63,13 @@ program
62
63
  .description('Update beecork to the latest version')
63
64
  .option('--check', 'Check for updates without installing')
64
65
  .action(updateBeecork);
66
+ program
67
+ .command('dashboard')
68
+ .description('Open the Beecork dashboard in your browser')
69
+ .option('-p, --port <port>', 'Port to listen on (default: random)')
70
+ .action(async (options) => {
71
+ const { startDashboardServer } = await import('./dashboard/server.js');
72
+ startDashboardServer(options.port ? parseInt(options.port) : 0);
73
+ });
65
74
  program.parse();
66
75
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,UAAU,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,qFAAqF,CAAC,CAAC;AAEtG,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,0BAA0B,CAAC;KACvC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEpB,MAAM,OAAO,GAAG,OAAO;KACpB,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kBAAkB,CAAC,CAAC;AAEnC,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,SAAS,CAAC,CAAC;AAErB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,MAAM,SAAS,GAAG,OAAO;KACtB,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2BAA2B,CAAC,CAAC;AAE5C,SAAS;KACN,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,SAAS;KACN,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,SAAS,EAAE,sCAAsC,CAAC;KACzD,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}