beecork 0.1.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 (118) hide show
  1. package/dist/cli/commands.d.ts +14 -0
  2. package/dist/cli/commands.d.ts.map +1 -0
  3. package/dist/cli/commands.js +215 -0
  4. package/dist/cli/commands.js.map +1 -0
  5. package/dist/cli/helpers.d.ts +4 -0
  6. package/dist/cli/helpers.d.ts.map +1 -0
  7. package/dist/cli/helpers.js +46 -0
  8. package/dist/cli/helpers.js.map +1 -0
  9. package/dist/cli/setup.d.ts +2 -0
  10. package/dist/cli/setup.d.ts.map +1 -0
  11. package/dist/cli/setup.js +145 -0
  12. package/dist/cli/setup.js.map +1 -0
  13. package/dist/config.d.ts +9 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +97 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/cron/scheduler.d.ts +20 -0
  18. package/dist/cron/scheduler.d.ts.map +1 -0
  19. package/dist/cron/scheduler.js +151 -0
  20. package/dist/cron/scheduler.js.map +1 -0
  21. package/dist/cron/store.d.ts +12 -0
  22. package/dist/cron/store.d.ts.map +1 -0
  23. package/dist/cron/store.js +82 -0
  24. package/dist/cron/store.js.map +1 -0
  25. package/dist/daemon.d.ts +2 -0
  26. package/dist/daemon.d.ts.map +1 -0
  27. package/dist/daemon.js +140 -0
  28. package/dist/daemon.js.map +1 -0
  29. package/dist/db/index.d.ts +4 -0
  30. package/dist/db/index.d.ts.map +1 -0
  31. package/dist/db/index.js +66 -0
  32. package/dist/db/index.js.map +1 -0
  33. package/dist/db/migrations.d.ts +3 -0
  34. package/dist/db/migrations.d.ts.map +1 -0
  35. package/dist/db/migrations.js +85 -0
  36. package/dist/db/migrations.js.map +1 -0
  37. package/dist/index.d.ts +3 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +66 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/mcp/server.d.ts +3 -0
  42. package/dist/mcp/server.d.ts.map +1 -0
  43. package/dist/mcp/server.js +304 -0
  44. package/dist/mcp/server.js.map +1 -0
  45. package/dist/memory/extractor.d.ts +6 -0
  46. package/dist/memory/extractor.d.ts.map +1 -0
  47. package/dist/memory/extractor.js +105 -0
  48. package/dist/memory/extractor.js.map +1 -0
  49. package/dist/service/install.d.ts +5 -0
  50. package/dist/service/install.d.ts.map +1 -0
  51. package/dist/service/install.js +118 -0
  52. package/dist/service/install.js.map +1 -0
  53. package/dist/service/templates.d.ts +5 -0
  54. package/dist/service/templates.d.ts.map +1 -0
  55. package/dist/service/templates.js +53 -0
  56. package/dist/service/templates.js.map +1 -0
  57. package/dist/session/approval.d.ts +20 -0
  58. package/dist/session/approval.d.ts.map +1 -0
  59. package/dist/session/approval.js +59 -0
  60. package/dist/session/approval.js.map +1 -0
  61. package/dist/session/circuit-breaker.d.ts +18 -0
  62. package/dist/session/circuit-breaker.d.ts.map +1 -0
  63. package/dist/session/circuit-breaker.js +67 -0
  64. package/dist/session/circuit-breaker.js.map +1 -0
  65. package/dist/session/context-monitor.d.ts +16 -0
  66. package/dist/session/context-monitor.d.ts.map +1 -0
  67. package/dist/session/context-monitor.js +44 -0
  68. package/dist/session/context-monitor.js.map +1 -0
  69. package/dist/session/manager.d.ts +42 -0
  70. package/dist/session/manager.d.ts.map +1 -0
  71. package/dist/session/manager.js +291 -0
  72. package/dist/session/manager.js.map +1 -0
  73. package/dist/session/subprocess.d.ts +23 -0
  74. package/dist/session/subprocess.d.ts.map +1 -0
  75. package/dist/session/subprocess.js +119 -0
  76. package/dist/session/subprocess.js.map +1 -0
  77. package/dist/session/tool-classifier.d.ts +4 -0
  78. package/dist/session/tool-classifier.d.ts.map +1 -0
  79. package/dist/session/tool-classifier.js +57 -0
  80. package/dist/session/tool-classifier.js.map +1 -0
  81. package/dist/telegram/bot.d.ts +25 -0
  82. package/dist/telegram/bot.d.ts.map +1 -0
  83. package/dist/telegram/bot.js +293 -0
  84. package/dist/telegram/bot.js.map +1 -0
  85. package/dist/telegram/formatter.d.ts +11 -0
  86. package/dist/telegram/formatter.d.ts.map +1 -0
  87. package/dist/telegram/formatter.js +54 -0
  88. package/dist/telegram/formatter.js.map +1 -0
  89. package/dist/types.d.ts +131 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +3 -0
  92. package/dist/types.js.map +1 -0
  93. package/dist/util/logger.d.ts +17 -0
  94. package/dist/util/logger.d.ts.map +1 -0
  95. package/dist/util/logger.js +56 -0
  96. package/dist/util/logger.js.map +1 -0
  97. package/dist/util/paths.d.ts +11 -0
  98. package/dist/util/paths.d.ts.map +1 -0
  99. package/dist/util/paths.js +40 -0
  100. package/dist/util/paths.js.map +1 -0
  101. package/dist/util/platform.d.ts +3 -0
  102. package/dist/util/platform.d.ts.map +1 -0
  103. package/dist/util/platform.js +10 -0
  104. package/dist/util/platform.js.map +1 -0
  105. package/dist/util/retry.d.ts +3 -0
  106. package/dist/util/retry.d.ts.map +1 -0
  107. package/dist/util/retry.js +19 -0
  108. package/dist/util/retry.js.map +1 -0
  109. package/dist/whatsapp/client.d.ts +23 -0
  110. package/dist/whatsapp/client.d.ts.map +1 -0
  111. package/dist/whatsapp/client.js +125 -0
  112. package/dist/whatsapp/client.js.map +1 -0
  113. package/dist/whatsapp/formatter.d.ts +3 -0
  114. package/dist/whatsapp/formatter.d.ts.map +1 -0
  115. package/dist/whatsapp/formatter.js +25 -0
  116. package/dist/whatsapp/formatter.js.map +1 -0
  117. package/package.json +53 -0
  118. package/templates/CLAUDE.md +25 -0
@@ -0,0 +1,151 @@
1
+ import cron from 'node-cron';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { CronStore } from './store.js';
5
+ import { getCronReloadSignalPath, getLogsDir } from '../util/paths.js';
6
+ import { logger } from '../util/logger.js';
7
+ export class CronScheduler {
8
+ tabManager;
9
+ telegramBot;
10
+ scheduledJobs = new Map();
11
+ store = new CronStore();
12
+ constructor(tabManager, telegramBot) {
13
+ this.tabManager = tabManager;
14
+ this.telegramBot = telegramBot;
15
+ }
16
+ /** Load all cron jobs from store and schedule them */
17
+ loadAndSchedule() {
18
+ // Cancel existing
19
+ for (const [, task] of this.scheduledJobs) {
20
+ task.stop();
21
+ }
22
+ this.scheduledJobs.clear();
23
+ const jobs = this.store.list();
24
+ let scheduled = 0;
25
+ for (const job of jobs) {
26
+ if (!job.enabled)
27
+ continue;
28
+ this.scheduleJob(job);
29
+ scheduled++;
30
+ }
31
+ logger.info(`Cron: loaded ${scheduled} active jobs (${jobs.length} total)`);
32
+ }
33
+ /** Check for the reload signal file and reload if present */
34
+ checkForReload() {
35
+ const signalPath = getCronReloadSignalPath();
36
+ if (fs.existsSync(signalPath)) {
37
+ try {
38
+ fs.unlinkSync(signalPath);
39
+ }
40
+ catch { /* race condition, ok */ }
41
+ logger.info('Cron: reload signal detected, reloading schedules');
42
+ this.loadAndSchedule();
43
+ }
44
+ }
45
+ /** Stop all scheduled jobs */
46
+ stopAll() {
47
+ for (const [, task] of this.scheduledJobs) {
48
+ task.stop();
49
+ }
50
+ this.scheduledJobs.clear();
51
+ }
52
+ scheduleJob(job) {
53
+ switch (job.scheduleType) {
54
+ case 'cron': {
55
+ if (!cron.validate(job.schedule)) {
56
+ logger.error(`Cron: invalid expression for "${job.name}": ${job.schedule}`);
57
+ return;
58
+ }
59
+ const task = cron.schedule(job.schedule, () => this.fireJob(job));
60
+ this.scheduledJobs.set(job.id, task);
61
+ break;
62
+ }
63
+ case 'every': {
64
+ const cronExpr = intervalToCron(job.schedule);
65
+ if (!cronExpr || !cron.validate(cronExpr)) {
66
+ logger.error(`Cron: invalid interval for "${job.name}": ${job.schedule}`);
67
+ return;
68
+ }
69
+ const task = cron.schedule(cronExpr, () => this.fireJob(job));
70
+ this.scheduledJobs.set(job.id, task);
71
+ break;
72
+ }
73
+ case 'at': {
74
+ const targetTime = new Date(job.schedule).getTime();
75
+ const delay = targetTime - Date.now();
76
+ if (delay <= 0) {
77
+ logger.warn(`Cron: one-time job "${job.name}" is in the past, skipping`);
78
+ return;
79
+ }
80
+ const timer = setTimeout(() => {
81
+ this.fireJob(job);
82
+ this.store.update(job.id, { enabled: false });
83
+ }, delay);
84
+ this.scheduledJobs.set(job.id, { stop: () => clearTimeout(timer) });
85
+ break;
86
+ }
87
+ }
88
+ }
89
+ async fireJob(job) {
90
+ logger.info(`Cron firing: "${job.name}" → tab:${job.tabName}`);
91
+ const logFile = path.join(getLogsDir(), `cron-${job.name}.log`);
92
+ try {
93
+ this.tabManager.ensureTab(job.tabName);
94
+ const result = await this.tabManager.sendMessage(job.tabName, job.message);
95
+ this.store.update(job.id, { lastRunAt: new Date().toISOString() });
96
+ const firstLine = result.text.split('\n')[0]?.slice(0, 200) || '(no output)';
97
+ // Log result
98
+ fs.appendFileSync(logFile, `[${new Date().toISOString()}] SUCCESS: ${firstLine}\n`);
99
+ // Notify via Telegram
100
+ if (this.telegramBot) {
101
+ if (result.error) {
102
+ await this.telegramBot.sendNotification(`❌ [${job.name}] Failed — ${firstLine}`);
103
+ }
104
+ else {
105
+ await this.telegramBot.sendNotification(`✅ [${job.name}] Done — ${firstLine}`);
106
+ }
107
+ }
108
+ }
109
+ catch (err) {
110
+ const errMsg = err instanceof Error ? err.message : String(err);
111
+ logger.error(`Cron job "${job.name}" failed:`, err);
112
+ fs.appendFileSync(logFile, `[${new Date().toISOString()}] ERROR: ${errMsg}\n`);
113
+ if (this.telegramBot) {
114
+ await this.telegramBot.sendNotification(`❌ [${job.name}] Failed — ${errMsg}`);
115
+ }
116
+ }
117
+ }
118
+ }
119
+ /** Convert human interval (30m, 2h, 1d, 1h30m, 2w) to cron expression */
120
+ export function intervalToCron(interval) {
121
+ // Try combined format: 1h30m, 2h, 30m, 1d, 2w
122
+ const match = interval.match(/^(?:(\d+)w)?(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?$/);
123
+ if (!match || match.slice(1).every(g => g === undefined))
124
+ return null;
125
+ const weeks = parseInt(match[1] || '0', 10);
126
+ const days = parseInt(match[2] || '0', 10);
127
+ const hours = parseInt(match[3] || '0', 10);
128
+ const mins = parseInt(match[4] || '0', 10);
129
+ // Convert to total minutes for simple intervals
130
+ const totalMins = weeks * 7 * 24 * 60 + days * 24 * 60 + hours * 60 + mins;
131
+ if (totalMins <= 0)
132
+ return null;
133
+ // Simple minute interval
134
+ if (totalMins <= 59)
135
+ return `*/${totalMins} * * * *`;
136
+ // Hourly intervals
137
+ if (mins === 0 && days === 0 && weeks === 0 && hours > 0 && hours <= 23)
138
+ return `0 */${hours} * * *`;
139
+ // Daily intervals
140
+ if (mins === 0 && hours === 0 && weeks === 0 && days > 0)
141
+ return `0 0 */${days} * *`;
142
+ // Weekly intervals
143
+ if (mins === 0 && hours === 0 && days === 0 && weeks > 0)
144
+ return `0 0 * * 0`;
145
+ // Combined intervals (e.g., 1h30m = every 90 minutes)
146
+ if (totalMins <= 1440)
147
+ return `*/${totalMins} * * * *`; // up to 24h as minutes
148
+ // Fallback for very large intervals: daily
149
+ return `0 0 */${Math.ceil(totalMins / 1440)} * *`;
150
+ }
151
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/cron/scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { CronJob } from '../types.js';
2
+ export declare class CronStore {
3
+ constructor();
4
+ list(): CronJob[];
5
+ get(id: string): CronJob | undefined;
6
+ add(job: CronJob): void;
7
+ update(id: string, updates: Partial<CronJob>): boolean;
8
+ delete(id: string): boolean;
9
+ /** One-time migration from crontab.json to SQLite */
10
+ private migrateFromJson;
11
+ }
12
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/cron/store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAmB3C,qBAAa,SAAS;;IAKpB,IAAI,IAAI,OAAO,EAAE;IAKjB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAMpC,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IASvB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO;IAatD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAM3B,qDAAqD;IACrD,OAAO,CAAC,eAAe;CAkCxB"}
@@ -0,0 +1,82 @@
1
+ import fs from 'node:fs';
2
+ import { getDb } from '../db/index.js';
3
+ import { getCrontabPath } from '../util/paths.js';
4
+ import { logger } from '../util/logger.js';
5
+ function rowToJob(row) {
6
+ return {
7
+ id: row.id, name: row.name,
8
+ scheduleType: row.schedule_type,
9
+ schedule: row.schedule, tabName: row.tab_name, message: row.message,
10
+ enabled: row.enabled === 1, createdAt: row.created_at,
11
+ lastRunAt: row.last_run_at, nextRunAt: row.next_run_at,
12
+ };
13
+ }
14
+ export class CronStore {
15
+ constructor() {
16
+ this.migrateFromJson();
17
+ }
18
+ list() {
19
+ const db = getDb();
20
+ return db.prepare('SELECT * FROM cron_jobs WHERE user_id = ? ORDER BY created_at').all('local').map(rowToJob);
21
+ }
22
+ get(id) {
23
+ const db = getDb();
24
+ const row = db.prepare('SELECT * FROM cron_jobs WHERE id = ?').get(id);
25
+ return row ? rowToJob(row) : undefined;
26
+ }
27
+ add(job) {
28
+ const db = getDb();
29
+ db.prepare(`INSERT INTO cron_jobs (id, name, schedule_type, schedule, tab_name, message, enabled, user_id, created_at, last_run_at, next_run_at)
30
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(job.id, job.name, job.scheduleType, job.schedule, job.tabName, job.message, job.enabled ? 1 : 0, 'local', job.createdAt, job.lastRunAt, job.nextRunAt);
31
+ }
32
+ update(id, updates) {
33
+ const db = getDb();
34
+ const existing = this.get(id);
35
+ if (!existing)
36
+ return false;
37
+ const merged = { ...existing, ...updates };
38
+ db.prepare(`UPDATE cron_jobs SET name=?, schedule_type=?, schedule=?, tab_name=?, message=?, enabled=?, last_run_at=?, next_run_at=? WHERE id=?`).run(merged.name, merged.scheduleType, merged.schedule, merged.tabName, merged.message, merged.enabled ? 1 : 0, merged.lastRunAt, merged.nextRunAt, id);
39
+ return true;
40
+ }
41
+ delete(id) {
42
+ const db = getDb();
43
+ const result = db.prepare('DELETE FROM cron_jobs WHERE id = ?').run(id);
44
+ return result.changes > 0;
45
+ }
46
+ /** One-time migration from crontab.json to SQLite */
47
+ migrateFromJson() {
48
+ const jsonPath = getCrontabPath();
49
+ if (!fs.existsSync(jsonPath))
50
+ return;
51
+ const db = getDb();
52
+ const count = db.prepare('SELECT COUNT(*) as count FROM cron_jobs').get();
53
+ if (count.count > 0) {
54
+ // Already migrated, clean up JSON
55
+ try {
56
+ fs.renameSync(jsonPath, jsonPath + '.bak');
57
+ }
58
+ catch { /* ok */ }
59
+ return;
60
+ }
61
+ try {
62
+ const data = JSON.parse(fs.readFileSync(jsonPath, 'utf-8'));
63
+ const jobs = data.jobs || [];
64
+ if (jobs.length === 0)
65
+ return;
66
+ const insert = db.prepare(`INSERT OR IGNORE INTO cron_jobs (id, name, schedule_type, schedule, tab_name, message, enabled, user_id, created_at, last_run_at, next_run_at)
67
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
68
+ const tx = db.transaction(() => {
69
+ for (const j of jobs) {
70
+ insert.run(j.id, j.name, j.scheduleType, j.schedule, j.tabName || 'default', j.message, j.enabled ? 1 : 0, 'local', j.createdAt, j.lastRunAt, j.nextRunAt);
71
+ }
72
+ });
73
+ tx();
74
+ fs.renameSync(jsonPath, jsonPath + '.bak');
75
+ logger.info(`Migrated ${jobs.length} cron jobs from JSON to SQLite`);
76
+ }
77
+ catch (err) {
78
+ logger.error('Failed to migrate cron jobs from JSON:', err);
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/cron/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAU3C,SAAS,QAAQ,CAAC,GAAe;IAC/B,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI;QAC1B,YAAY,EAAE,GAAG,CAAC,aAAwC;QAC1D,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO;QACnE,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,UAAU;QACrD,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,GAAG,CAAC,WAAW;KACvD,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,SAAS;IACpB;QACE,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,IAAI;QACF,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,OAAQ,EAAE,CAAC,OAAO,CAAC,+DAA+D,CAAC,CAAC,GAAG,CAAC,OAAO,CAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClI,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,EAAE,CAA2B,CAAC;QACjG,OAAO,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzC,CAAC;IAED,GAAG,CAAC,GAAY;QACd,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,EAAE,CAAC,OAAO,CAAC;+CACgC,CAAC,CAAC,GAAG,CAC9C,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAC1E,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,CAC1E,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,EAAU,EAAE,OAAyB;QAC1C,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE5B,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;QAC3C,EAAE,CAAC,OAAO,CAAC,qIAAqI,CAAC,CAAC,GAAG,CACnJ,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EACjF,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,CAC/D,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,EAAU;QACf,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,qDAAqD;IAC7C,eAAe;QACrB,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO;QAErC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,EAAuB,CAAC;QAC/F,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACpB,kCAAkC;YAClC,IAAI,CAAC;gBAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAE9B,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;iDACiB,CAAC,CAAC;YAE7C,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;gBAC7B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;oBACrB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC,CAAC,OAAO,EACpF,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC,CAAC,CAAC;YACH,EAAE,EAAE,CAAC;YAEL,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,MAAM,gCAAgC,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":""}
package/dist/daemon.js ADDED
@@ -0,0 +1,140 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import { getConfig } from './config.js';
5
+ import { getDb, closeDb } from './db/index.js';
6
+ import { TabManager } from './session/manager.js';
7
+ import { BeecorkTelegramBot } from './telegram/bot.js';
8
+ import { CronScheduler } from './cron/scheduler.js';
9
+ import { ensureBeecorkDirs, getPidPath, getBeecorkHome } from './util/paths.js';
10
+ import { logger } from './util/logger.js';
11
+ let tabManager;
12
+ let telegramBot = null;
13
+ let cronScheduler;
14
+ let pollInterval;
15
+ /** Migrate data from old ~/.clawd to ~/.beecork if needed */
16
+ function migrateFromClawd() {
17
+ const oldHome = path.join(os.homedir(), '.clawd');
18
+ const newHome = getBeecorkHome();
19
+ if (fs.existsSync(oldHome) && !fs.existsSync(newHome)) {
20
+ // Copy old data to new location
21
+ fs.cpSync(oldHome, newHome, { recursive: true });
22
+ logger.info(`Migrated data directory from ${oldHome} to ${newHome}`);
23
+ }
24
+ }
25
+ async function main() {
26
+ migrateFromClawd();
27
+ ensureBeecorkDirs();
28
+ logger.setLogFile('daemon.log');
29
+ logger.info('Beecork daemon starting...');
30
+ // 1. Load config
31
+ const config = getConfig();
32
+ // 2. Initialize database
33
+ getDb();
34
+ // 3. Write PID file
35
+ fs.writeFileSync(getPidPath(), String(process.pid));
36
+ logger.info(`PID file written: ${process.pid}`);
37
+ // 4. Create TabManager
38
+ tabManager = new TabManager(config);
39
+ // 5. Ensure default tab
40
+ tabManager.ensureTab('default');
41
+ // 6. Recover crashed tabs
42
+ await recoverCrashedTabs();
43
+ // 7. Start Telegram bot
44
+ if (config.telegram?.token) {
45
+ try {
46
+ telegramBot = new BeecorkTelegramBot(config, tabManager);
47
+ // Wire up notifications so TabManager can send Telegram alerts (loop detection, etc.)
48
+ tabManager.setNotifyCallback((text) => telegramBot.sendNotification(text));
49
+ }
50
+ catch (err) {
51
+ logger.error('Failed to start Telegram bot:', err);
52
+ }
53
+ }
54
+ else {
55
+ logger.warn('No Telegram token configured. Bot not started.');
56
+ }
57
+ // 8. Start cron scheduler
58
+ cronScheduler = new CronScheduler(tabManager, telegramBot);
59
+ cronScheduler.loadAndSchedule();
60
+ // 9. Start IPC polling
61
+ pollInterval = setInterval(() => {
62
+ try {
63
+ cronScheduler.checkForReload();
64
+ tabManager.processPendingMessages();
65
+ }
66
+ catch (err) {
67
+ logger.error('Poll error:', err);
68
+ }
69
+ }, 5000);
70
+ // 10. Handle shutdown
71
+ const shutdown = async () => {
72
+ logger.info('Beecork daemon shutting down...');
73
+ // Send shutdown notification before stopping
74
+ if (telegramBot) {
75
+ try {
76
+ await telegramBot.sendNotification('🔴 Beecork stopping');
77
+ }
78
+ catch { /* ok */ }
79
+ }
80
+ clearInterval(pollInterval);
81
+ tabManager.stopAll();
82
+ if (telegramBot)
83
+ telegramBot.stop();
84
+ cronScheduler.stopAll();
85
+ closeDb();
86
+ const pidPath = getPidPath();
87
+ if (fs.existsSync(pidPath))
88
+ fs.unlinkSync(pidPath);
89
+ logger.info('Beecork daemon stopped.');
90
+ logger.close();
91
+ process.exit(0);
92
+ };
93
+ process.on('SIGTERM', shutdown);
94
+ process.on('SIGINT', shutdown);
95
+ logger.info(`Beecork daemon ready (home: ${getBeecorkHome()})`);
96
+ // Send detailed startup notification
97
+ if (telegramBot) {
98
+ const tabs = tabManager.listTabs();
99
+ const cronJobs = new (await import('./cron/store.js')).CronStore().list().filter(j => j.enabled);
100
+ await telegramBot.sendNotification(`🟢 Beecork started — ${cronJobs.length} cron job${cronJobs.length !== 1 ? 's' : ''}, ${tabs.length} tab${tabs.length !== 1 ? 's' : ''}`);
101
+ }
102
+ }
103
+ async function recoverCrashedTabs() {
104
+ const db = getDb();
105
+ const crashedRows = db.prepare(`SELECT * FROM tabs WHERE status = 'running'`).all();
106
+ if (crashedRows.length === 0)
107
+ return;
108
+ logger.info(`Found ${crashedRows.length} tabs that were running when daemon stopped`);
109
+ for (const row of crashedRows) {
110
+ logger.info(`Recovering tab: ${row.name} (session: ${row.session_id})`);
111
+ // Get last few messages for context
112
+ const recentMessages = db.prepare(`SELECT role, content FROM messages
113
+ WHERE tab_id = ? ORDER BY created_at DESC LIMIT 5`).all(row.id);
114
+ // Build recovery prompt
115
+ const contextSummary = recentMessages
116
+ .reverse()
117
+ .map(m => `${m.role}: ${m.content.slice(0, 200)}`)
118
+ .join('\n');
119
+ const recoveryPrompt = [
120
+ `[SYSTEM: Session recovered after restart. Here is your recent conversation context:]`,
121
+ contextSummary,
122
+ `[SYSTEM: Please acknowledge you are back and ready for new instructions.]`,
123
+ ].join('\n');
124
+ // Reset status so TabManager can use it
125
+ db.prepare(`UPDATE tabs SET status = 'idle', pid = NULL WHERE id = ?`).run(row.id);
126
+ // Resume the session
127
+ tabManager.sendMessage(row.name, recoveryPrompt, { resume: true }).catch(err => {
128
+ logger.error(`Failed to recover tab ${row.name}:`, err);
129
+ });
130
+ // Notify via Telegram
131
+ if (telegramBot) {
132
+ await telegramBot.sendNotification(`Beecork restarted. Recovered tab "${row.name}" — session resumed.`);
133
+ }
134
+ }
135
+ }
136
+ main().catch(err => {
137
+ logger.error('Fatal error:', err);
138
+ process.exit(1);
139
+ });
140
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import Database from 'better-sqlite3';
2
+ export declare function getDb(): Database.Database;
3
+ export declare function closeDb(): void;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,66 @@
1
+ import Database from 'better-sqlite3';
2
+ import { getDbPath, ensureBeecorkDirs } from '../util/paths.js';
3
+ import { runMigrations } from './migrations.js';
4
+ const SCHEMA = `
5
+ CREATE TABLE IF NOT EXISTS tabs (
6
+ id TEXT PRIMARY KEY,
7
+ name TEXT UNIQUE NOT NULL,
8
+ session_id TEXT NOT NULL,
9
+ status TEXT NOT NULL DEFAULT 'idle',
10
+ working_dir TEXT NOT NULL,
11
+ pid INTEGER,
12
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
13
+ last_activity_at TEXT NOT NULL DEFAULT (datetime('now'))
14
+ );
15
+
16
+ CREATE TABLE IF NOT EXISTS messages (
17
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
18
+ tab_id TEXT NOT NULL REFERENCES tabs(id),
19
+ role TEXT NOT NULL,
20
+ content TEXT NOT NULL,
21
+ cost_usd REAL,
22
+ tokens_in INTEGER,
23
+ tokens_out INTEGER,
24
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
25
+ );
26
+
27
+ CREATE INDEX IF NOT EXISTS idx_messages_tab ON messages(tab_id, created_at);
28
+
29
+ CREATE TABLE IF NOT EXISTS memories (
30
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
31
+ content TEXT NOT NULL,
32
+ tab_name TEXT,
33
+ source TEXT NOT NULL DEFAULT 'tool',
34
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
35
+ );
36
+
37
+ CREATE TABLE IF NOT EXISTS pending_messages (
38
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
39
+ tab_name TEXT NOT NULL,
40
+ message TEXT NOT NULL,
41
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
42
+ processed INTEGER NOT NULL DEFAULT 0
43
+ );
44
+
45
+ CREATE INDEX IF NOT EXISTS idx_pending_unprocessed ON pending_messages(processed, created_at);
46
+ `;
47
+ let db = null;
48
+ export function getDb() {
49
+ if (db)
50
+ return db;
51
+ ensureBeecorkDirs();
52
+ const dbPath = getDbPath();
53
+ db = new Database(dbPath);
54
+ db.pragma('journal_mode = WAL');
55
+ db.pragma('foreign_keys = ON');
56
+ db.exec(SCHEMA);
57
+ runMigrations(db);
58
+ return db;
59
+ }
60
+ export function closeDb() {
61
+ if (db) {
62
+ db.close();
63
+ db = null;
64
+ }
65
+ }
66
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"}
@@ -0,0 +1,3 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function runMigrations(db: Database.Database): void;
3
+ //# sourceMappingURL=migrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAqD3C,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAwCzD"}
@@ -0,0 +1,85 @@
1
+ import { logger } from '../util/logger.js';
2
+ const MIGRATIONS = [
3
+ {
4
+ version: 2,
5
+ description: 'Add user_id column for multi-user support',
6
+ up: `
7
+ ALTER TABLE tabs ADD COLUMN user_id TEXT NOT NULL DEFAULT 'local';
8
+ ALTER TABLE memories ADD COLUMN user_id TEXT NOT NULL DEFAULT 'local';
9
+ `,
10
+ },
11
+ {
12
+ version: 3,
13
+ description: 'Add schema_version table',
14
+ up: '', // Already handled by bootstrap
15
+ },
16
+ {
17
+ version: 4,
18
+ description: 'Add cron_jobs table in SQLite',
19
+ up: `
20
+ CREATE TABLE IF NOT EXISTS cron_jobs (
21
+ id TEXT PRIMARY KEY,
22
+ name TEXT NOT NULL,
23
+ schedule_type TEXT NOT NULL,
24
+ schedule TEXT NOT NULL,
25
+ tab_name TEXT NOT NULL DEFAULT 'default',
26
+ message TEXT NOT NULL,
27
+ enabled INTEGER NOT NULL DEFAULT 1,
28
+ user_id TEXT NOT NULL DEFAULT 'local',
29
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
30
+ last_run_at TEXT,
31
+ next_run_at TEXT
32
+ );
33
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_user ON cron_jobs(user_id, enabled);
34
+ `,
35
+ },
36
+ {
37
+ version: 5,
38
+ description: 'Add type column to pending_messages for notifications',
39
+ up: `
40
+ ALTER TABLE pending_messages ADD COLUMN type TEXT NOT NULL DEFAULT 'message';
41
+ ALTER TABLE pending_messages ADD COLUMN user_id TEXT NOT NULL DEFAULT 'local';
42
+ `,
43
+ },
44
+ ];
45
+ export function runMigrations(db) {
46
+ // Ensure schema_version table exists
47
+ db.exec(`
48
+ CREATE TABLE IF NOT EXISTS schema_version (
49
+ version INTEGER NOT NULL DEFAULT 1
50
+ );
51
+ `);
52
+ // Get current version
53
+ let row = db.prepare('SELECT version FROM schema_version').get();
54
+ if (!row) {
55
+ db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(1);
56
+ row = { version: 1 };
57
+ }
58
+ const currentVersion = row.version;
59
+ // Apply pending migrations
60
+ for (const migration of MIGRATIONS) {
61
+ if (migration.version <= currentVersion)
62
+ continue;
63
+ if (!migration.up) {
64
+ db.prepare('UPDATE schema_version SET version = ?').run(migration.version);
65
+ continue;
66
+ }
67
+ logger.info(`DB migration v${migration.version}: ${migration.description}`);
68
+ try {
69
+ db.exec(migration.up);
70
+ db.prepare('UPDATE schema_version SET version = ?').run(migration.version);
71
+ }
72
+ catch (err) {
73
+ // Column might already exist from a previous partial migration
74
+ const msg = err instanceof Error ? err.message : String(err);
75
+ if (msg.includes('duplicate column name')) {
76
+ logger.info(`Migration v${migration.version}: columns already exist, skipping`);
77
+ db.prepare('UPDATE schema_version SET version = ?').run(migration.version);
78
+ }
79
+ else {
80
+ throw err;
81
+ }
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAQ3C,MAAM,UAAU,GAAgB;IAC9B;QACE,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,2CAA2C;QACxD,EAAE,EAAE;;;KAGH;KACF;IACD;QACE,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,0BAA0B;QACvC,EAAE,EAAE,EAAE,EAAE,+BAA+B;KACxC;IACD;QACE,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,+BAA+B;QAC5C,EAAE,EAAE;;;;;;;;;;;;;;;KAeH;KACF;IACD;QACE,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,uDAAuD;QACpE,EAAE,EAAE;;;KAGH;KACF;CACF,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,EAAqB;IACjD,qCAAqC;IACrC,EAAE,CAAC,IAAI,CAAC;;;;GAIP,CAAC,CAAC;IAEH,sBAAsB;IACtB,IAAI,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,EAAqC,CAAC;IACpG,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrE,GAAG,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACvB,CAAC;IAED,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC;IAEnC,2BAA2B;IAC3B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,OAAO,IAAI,cAAc;YAAE,SAAS;QAClD,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;YAClB,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAC3E,SAAS;QACX,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,iBAAiB,SAAS,CAAC,OAAO,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC;YACH,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACtB,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC7E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,+DAA+D;YAC/D,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;gBAC1C,MAAM,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,OAAO,mCAAmC,CAAC,CAAC;gBAChF,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAC7E,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}