0xkobold 0.3.2 → 0.4.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.
@@ -0,0 +1,512 @@
1
+ /**
2
+ * Cron Scheduler - 0xKobold
3
+ *
4
+ * Core scheduler for cron jobs with SQLite persistence.
5
+ * Supports both recurring (cron expressions) and one-shot jobs.
6
+ */
7
+ import { EventEmitter } from "events";
8
+ import { Database } from "bun:sqlite";
9
+ import { join } from "node:path";
10
+ import { homedir } from "node:os";
11
+ import { randomInt } from "node:crypto";
12
+ import { parseExpression, getNextRun, parseAt, } from "./parser.js";
13
+ const DEFAULT_CONFIG = {
14
+ defaultTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
15
+ maxConcurrent: 5,
16
+ defaultModel: "kimi-k2.5:cloud",
17
+ enabled: true,
18
+ checkInterval: 60000, // 1 minute
19
+ };
20
+ export class CronScheduler extends EventEmitter {
21
+ db;
22
+ config;
23
+ checkTimer;
24
+ running = false;
25
+ activeJobs = new Map();
26
+ constructor(dbPath, config) {
27
+ super();
28
+ this.config = { ...DEFAULT_CONFIG, ...config };
29
+ // Default to ~/.0xkobold/cron.db
30
+ const path = dbPath || join(homedir(), ".0xkobold", "cron.db");
31
+ this.db = new Database(path);
32
+ this.initSchema();
33
+ }
34
+ /**
35
+ * Initialize database schema
36
+ */
37
+ initSchema() {
38
+ // Execute schema inline to avoid async loading issues
39
+ // The schema.sql file path resolution can be tricky, so we inline the critical tables
40
+ this.db.exec(`
41
+ -- Cron jobs table
42
+ CREATE TABLE IF NOT EXISTS cron_jobs (
43
+ id TEXT PRIMARY KEY,
44
+ name TEXT NOT NULL,
45
+ cron_expression TEXT,
46
+ at INTEGER,
47
+ at_duration INTEGER,
48
+ timezone TEXT DEFAULT 'UTC',
49
+ session_type TEXT DEFAULT 'isolated',
50
+ message TEXT NOT NULL,
51
+ model TEXT,
52
+ thinking_level TEXT,
53
+ working_dir TEXT,
54
+ token_limit INTEGER,
55
+ enabled INTEGER DEFAULT 1,
56
+ created_at INTEGER DEFAULT (unixepoch()),
57
+ updated_at INTEGER DEFAULT (unixepoch()),
58
+ last_run_at INTEGER,
59
+ next_run_at INTEGER NOT NULL,
60
+ run_count INTEGER DEFAULT 0,
61
+ error_count INTEGER DEFAULT 0,
62
+ last_error TEXT,
63
+ last_output TEXT,
64
+ delete_after_run INTEGER DEFAULT 0,
65
+ wake_after_run INTEGER DEFAULT 0,
66
+ stagger INTEGER DEFAULT 0,
67
+ exact INTEGER DEFAULT 0
68
+ );
69
+
70
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_next_run
71
+ ON cron_jobs(next_run_at)
72
+ WHERE enabled = 1;
73
+
74
+ CREATE INDEX IF NOT EXISTS idx_cron_jobs_last_run
75
+ ON cron_jobs(last_run_at);
76
+
77
+ CREATE TABLE IF NOT EXISTS cron_runs (
78
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
79
+ job_id TEXT NOT NULL,
80
+ started_at INTEGER NOT NULL,
81
+ completed_at INTEGER,
82
+ success INTEGER,
83
+ output TEXT,
84
+ tokens_used INTEGER DEFAULT 0,
85
+ cost REAL,
86
+ error TEXT,
87
+ exit_code INTEGER
88
+ );
89
+
90
+ CREATE INDEX IF NOT EXISTS idx_cron_runs_job_id
91
+ ON cron_runs(job_id);
92
+
93
+ CREATE INDEX IF NOT EXISTS idx_cron_runs_started
94
+ ON cron_runs(started_at DESC);
95
+ `);
96
+ this.emit("schema:initialized");
97
+ }
98
+ /**
99
+ * Start the scheduler
100
+ */
101
+ start() {
102
+ if (this.running)
103
+ return;
104
+ this.running = true;
105
+ this.emit("started");
106
+ // Initial check
107
+ this.checkAndRunJobs();
108
+ // Schedule periodic checks
109
+ this.checkTimer = setInterval(() => {
110
+ this.checkAndRunJobs();
111
+ }, this.config.checkInterval);
112
+ console.log(`[CronScheduler] Started (check interval: ${this.config.checkInterval}ms)`);
113
+ }
114
+ /**
115
+ * Stop the scheduler
116
+ */
117
+ stop() {
118
+ this.running = false;
119
+ if (this.checkTimer) {
120
+ clearInterval(this.checkTimer);
121
+ this.checkTimer = undefined;
122
+ }
123
+ this.emit("stopped");
124
+ console.log("[CronScheduler] Stopped");
125
+ }
126
+ /**
127
+ * Check for and run due jobs
128
+ */
129
+ async checkAndRunJobs() {
130
+ if (!this.running)
131
+ return;
132
+ const now = Date.now();
133
+ // Get jobs that should run now (respecting concurrency limit)
134
+ const availableSlots = this.config.maxConcurrent - this.activeJobs.size;
135
+ if (availableSlots <= 0) {
136
+ console.log("[CronScheduler] Max concurrent jobs reached, skipping check");
137
+ return;
138
+ }
139
+ const jobs = this.db
140
+ .query(`SELECT * FROM cron_jobs
141
+ WHERE enabled = true
142
+ AND next_run_at <= ?
143
+ AND (last_run_at IS NULL OR last_run_at < next_run_at)
144
+ ORDER BY next_run_at ASC
145
+ LIMIT ?`)
146
+ .all(now, availableSlots);
147
+ for (const job of jobs) {
148
+ if (this.activeJobs.has(job.id))
149
+ continue;
150
+ // Add stagger for load distribution
151
+ const staggerMs = this.calculateStagger(job);
152
+ if (staggerMs > 0) {
153
+ // Job has stagger, update next_run_at but don't run yet
154
+ this.db.run(`UPDATE cron_jobs
155
+ SET next_run_at = next_run_at + ?
156
+ WHERE id = ?`, [staggerMs, job.id]);
157
+ continue;
158
+ }
159
+ // Run the job
160
+ const jobPromise = this.executeJob(job);
161
+ this.activeJobs.set(job.id, jobPromise);
162
+ jobPromise
163
+ .then(() => {
164
+ this.activeJobs.delete(job.id);
165
+ this.emit("job:completed", job.id);
166
+ })
167
+ .catch((error) => {
168
+ this.activeJobs.delete(job.id);
169
+ console.error(`[CronScheduler] Job ${job.id} failed:`, error);
170
+ this.emit("job:failed", job.id, error);
171
+ });
172
+ }
173
+ }
174
+ /**
175
+ * Calculate stagger delay for a job
176
+ */
177
+ calculateStagger(job) {
178
+ if (job.exact || !job.stagger || job.stagger <= 0) {
179
+ return 0;
180
+ }
181
+ // Random delay between 0 and stagger minutes (converted to ms)
182
+ return randomInt(0, job.stagger * 60 * 1000);
183
+ }
184
+ /**
185
+ * Execute a single job
186
+ */
187
+ async executeJob(job) {
188
+ const runId = this.logJobStart(job.id);
189
+ const startTime = Date.now();
190
+ try {
191
+ // Import runner dynamically to avoid circular deps
192
+ const { runJobRunner } = await import("./runner.js");
193
+ const result = await runJobRunner(job);
194
+ const duration = Date.now() - startTime;
195
+ // Log completion
196
+ this.logJobComplete(runId, result, duration);
197
+ // Update job stats
198
+ this.updateJobAfterRun(job, result, duration);
199
+ // Handle wake
200
+ if (job.wakeAfterRun && result.success) {
201
+ this.emit("job:wake", job.id, result.output);
202
+ }
203
+ // Handle delete for one-shots
204
+ if (job.deleteAfterRun) {
205
+ this.removeJob(job.id, false);
206
+ this.emit("job:deleted", job.id);
207
+ }
208
+ this.emit("job:success", job.id, result);
209
+ }
210
+ catch (error) {
211
+ const duration = Date.now() - startTime;
212
+ const errorMsg = error instanceof Error ? error.message : String(error);
213
+ this.logJobError(runId, errorMsg);
214
+ this.updateJobError(job, errorMsg);
215
+ this.emit("job:error", job.id, error);
216
+ throw error;
217
+ }
218
+ }
219
+ /**
220
+ * Add a new job
221
+ */
222
+ addJob(options) {
223
+ const id = `cron:${Date.now()}:${randomInt(1000, 9999)}`;
224
+ const session = options.session || "isolated";
225
+ const timezone = options.timezone || this.config.defaultTimezone;
226
+ let nextRunAt;
227
+ let cronExpression;
228
+ let at;
229
+ let atDuration;
230
+ if (options.cron) {
231
+ // Recurring job
232
+ cronExpression = options.cron;
233
+ const expr = parseExpression(options.cron, timezone);
234
+ nextRunAt = getNextRun(expr).getTime();
235
+ }
236
+ else if (options.at) {
237
+ // One-shot job
238
+ const atTime = parseAt(options.at);
239
+ if (atTime > Date.now() + 365 * 24 * 60 * 60 * 1000) {
240
+ // Likely an absolute timestamp
241
+ at = atTime;
242
+ }
243
+ else {
244
+ // Relative duration
245
+ atDuration = atTime - Date.now();
246
+ at = atTime;
247
+ }
248
+ nextRunAt = atTime;
249
+ }
250
+ else {
251
+ throw new Error("Either --cron or --at is required");
252
+ }
253
+ const job = {
254
+ id,
255
+ name: options.name,
256
+ cronExpression,
257
+ at,
258
+ atDuration,
259
+ session,
260
+ message: options.message,
261
+ model: options.model,
262
+ thinkingLevel: options.thinkingLevel,
263
+ timezone,
264
+ enabled: true,
265
+ createdAt: Date.now(),
266
+ nextRunAt,
267
+ runCount: 0,
268
+ errorCount: 0,
269
+ deleteAfterRun: options.deleteAfterRun,
270
+ wakeAfterRun: options.wake,
271
+ workingDir: options.workingDir,
272
+ };
273
+ // Insert into database
274
+ this.db.run(`INSERT INTO cron_jobs (
275
+ id, name, cron_expression, at, at_duration, timezone,
276
+ session_type, message, model, thinking_level, working_dir, token_limit,
277
+ enabled, created_at, next_run_at, run_count, error_count,
278
+ delete_after_run, wake_after_run
279
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
280
+ job.id,
281
+ job.name,
282
+ job.cronExpression || null,
283
+ job.at || null,
284
+ job.atDuration || null,
285
+ job.timezone,
286
+ job.session,
287
+ job.message,
288
+ job.model || null,
289
+ job.thinkingLevel || null,
290
+ job.workingDir || null,
291
+ job.tokenLimit || null,
292
+ job.enabled ? 1 : 0,
293
+ job.createdAt,
294
+ job.nextRunAt,
295
+ job.runCount,
296
+ job.errorCount,
297
+ job.deleteAfterRun ? 1 : 0,
298
+ job.wakeAfterRun ? 1 : 0,
299
+ ]);
300
+ this.emit("job:added", job);
301
+ console.log(`[CronScheduler] Added job: ${job.name} (${job.id})`);
302
+ return job;
303
+ }
304
+ /**
305
+ * Remove a job
306
+ */
307
+ removeJob(id, log = true) {
308
+ const result = this.db.run("DELETE FROM cron_jobs WHERE id = ?", [id]);
309
+ if (result.changes > 0) {
310
+ if (log) {
311
+ this.emit("job:removed", id);
312
+ console.log(`[CronScheduler] Removed job: ${id}`);
313
+ }
314
+ return true;
315
+ }
316
+ return false;
317
+ }
318
+ /**
319
+ * Enable a job
320
+ */
321
+ enableJob(id) {
322
+ const result = this.db.run("UPDATE cron_jobs SET enabled = 1 WHERE id = ?", [id]);
323
+ if (result.changes > 0) {
324
+ this.emit("job:enabled", id);
325
+ return true;
326
+ }
327
+ return false;
328
+ }
329
+ /**
330
+ * Disable a job
331
+ */
332
+ disableJob(id) {
333
+ const result = this.db.run("UPDATE cron_jobs SET enabled = 0 WHERE id = ?", [id]);
334
+ if (result.changes > 0) {
335
+ this.emit("job:disabled", id);
336
+ return true;
337
+ }
338
+ return false;
339
+ }
340
+ /**
341
+ * Get a job by ID
342
+ */
343
+ getJob(id) {
344
+ return this.db.query("SELECT * FROM cron_jobs WHERE id = ?").get(id);
345
+ }
346
+ /**
347
+ * List all jobs
348
+ */
349
+ listJobs() {
350
+ return this.db.query("SELECT * FROM cron_jobs ORDER BY created_at DESC").all();
351
+ }
352
+ /**
353
+ * Get job status for CLI display
354
+ */
355
+ getJobStatus() {
356
+ return this.db.query(`
357
+ SELECT
358
+ id,
359
+ name,
360
+ CASE
361
+ WHEN cron_expression IS NOT NULL THEN cron_expression
362
+ ELSE 'one-shot'
363
+ END as schedule,
364
+ datetime(next_run_at / 1000, 'unixepoch') as nextRun,
365
+ session_type as session,
366
+ CASE
367
+ WHEN enabled = 0 THEN 'disabled'
368
+ ELSE 'enabled'
369
+ END as status,
370
+ datetime(last_run_at / 1000, 'unixepoch') as lastRun,
371
+ run_count as runCount
372
+ FROM cron_jobs
373
+ ORDER BY next_run_at ASC
374
+ `).all();
375
+ }
376
+ /**
377
+ * Get upcoming jobs
378
+ */
379
+ getUpcoming(limit = 10) {
380
+ return this.db.query(`
381
+ SELECT * FROM cron_jobs
382
+ WHERE enabled = true
383
+ AND next_run_at > ?
384
+ ORDER BY next_run_at ASC
385
+ LIMIT ${limit}
386
+ `).all(Date.now());
387
+ }
388
+ /**
389
+ * Get job run history
390
+ */
391
+ getJobHistory(jobId, limit = 10) {
392
+ return this.db.query(`
393
+ SELECT * FROM cron_runs
394
+ WHERE job_id = ?
395
+ ORDER BY started_at DESC
396
+ LIMIT ?
397
+ `).all(jobId, limit);
398
+ }
399
+ /**
400
+ * Log job start
401
+ */
402
+ logJobStart(jobId) {
403
+ const result = this.db.run("INSERT INTO cron_runs (job_id, started_at) VALUES (?, ?)", [jobId, Date.now()]);
404
+ return result.lastInsertRowid;
405
+ }
406
+ /**
407
+ * Log job completion
408
+ */
409
+ logJobComplete(runId, result, duration) {
410
+ this.db.run(`UPDATE cron_runs
411
+ SET completed_at = ?, success = ?, output = ?, tokens_used = ?, cost = ?
412
+ WHERE id = ?`, [
413
+ Date.now(),
414
+ result.success ? 1 : 0,
415
+ result.output,
416
+ result.tokensUsed,
417
+ result.cost || null,
418
+ runId,
419
+ ]);
420
+ }
421
+ /**
422
+ * Log job error
423
+ */
424
+ logJobError(runId, error) {
425
+ this.db.run(`UPDATE cron_runs
426
+ SET completed_at = ?, success = 0, error = ?
427
+ WHERE id = ?`, [Date.now(), error, runId]);
428
+ }
429
+ /**
430
+ * Update job after successful run
431
+ */
432
+ updateJobAfterRun(job, result, duration) {
433
+ // Calculate next run for recurring jobs
434
+ let nextRunAt = null;
435
+ if (job.cronExpression) {
436
+ // Recurring: calculate next run from cron
437
+ const expr = parseExpression(job.cronExpression, job.timezone);
438
+ nextRunAt = getNextRun(expr, new Date()).getTime();
439
+ }
440
+ else if (!job.deleteAfterRun) {
441
+ // One-shot that shouldn't delete - disable it
442
+ this.disableJob(job.id);
443
+ return;
444
+ }
445
+ this.db.run(`UPDATE cron_jobs
446
+ SET last_run_at = ?,
447
+ next_run_at = ?,
448
+ run_count = run_count + 1,
449
+ last_output = ?
450
+ WHERE id = ?`, [
451
+ Date.now(),
452
+ nextRunAt,
453
+ result.output.substring(0, 1000), // Truncate for storage
454
+ job.id,
455
+ ]);
456
+ }
457
+ /**
458
+ * Update job after error
459
+ */
460
+ updateJobError(job, error) {
461
+ // For recurring jobs, calculate next run
462
+ let nextRunAt = null;
463
+ if (job.cronExpression) {
464
+ const expr = parseExpression(job.cronExpression, job.timezone);
465
+ nextRunAt = getNextRun(expr, new Date()).getTime();
466
+ }
467
+ this.db.run(`UPDATE cron_jobs
468
+ SET error_count = error_count + 1,
469
+ last_error = ?,
470
+ next_run_at = COALESCE(?, next_run_at)
471
+ WHERE id = ?`, [error.substring(0, 500), nextRunAt, job.id]);
472
+ }
473
+ /**
474
+ * Get scheduler statistics
475
+ */
476
+ getStats() {
477
+ const totalJobs = this.db.query("SELECT COUNT(*) as count FROM cron_jobs").get().count;
478
+ const enabledJobs = this.db.query("SELECT COUNT(*) as count FROM cron_jobs WHERE enabled = 1").get().count;
479
+ const totalRuns = this.db.query("SELECT COUNT(*) as count FROM cron_runs").get().count;
480
+ const successfulRuns = this.db.query("SELECT COUNT(*) as count FROM cron_runs WHERE success = 1").get().count;
481
+ return {
482
+ totalJobs,
483
+ enabledJobs,
484
+ activeJobs: this.activeJobs.size,
485
+ totalRuns,
486
+ successfulRuns,
487
+ failedRuns: totalRuns - successfulRuns,
488
+ };
489
+ }
490
+ /**
491
+ * Close database connection
492
+ */
493
+ close() {
494
+ this.stop();
495
+ this.db.close();
496
+ }
497
+ }
498
+ // Singleton instance
499
+ let schedulerInstance = null;
500
+ export function getCronScheduler(dbPath, config) {
501
+ if (!schedulerInstance) {
502
+ schedulerInstance = new CronScheduler(dbPath, config);
503
+ }
504
+ return schedulerInstance;
505
+ }
506
+ export function resetCronScheduler() {
507
+ if (schedulerInstance) {
508
+ schedulerInstance.close();
509
+ schedulerInstance = null;
510
+ }
511
+ }
512
+ //# 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,8 @@
1
+ /**
2
+ * Cron Types - 0xKobold
3
+ *
4
+ * TypeScript interfaces for cron job scheduling.
5
+ * Based on OpenClaw cron specifications.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/cron/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0xkobold",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Your digital familiar - a personal AI assistant that learns and evolves (v0.3.0 - Multi-Channel, Security, Media Support)",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",