reeboot 1.3.0 → 1.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 (91) hide show
  1. package/dist/channels/signal.d.ts +13 -0
  2. package/dist/channels/signal.d.ts.map +1 -1
  3. package/dist/channels/signal.js +54 -0
  4. package/dist/channels/signal.js.map +1 -1
  5. package/dist/channels/whatsapp.d.ts +14 -0
  6. package/dist/channels/whatsapp.d.ts.map +1 -1
  7. package/dist/channels/whatsapp.js +64 -0
  8. package/dist/channels/whatsapp.js.map +1 -1
  9. package/dist/config.d.ts +112 -0
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +18 -0
  12. package/dist/config.js.map +1 -1
  13. package/dist/db/schema.d.ts +96 -0
  14. package/dist/db/schema.d.ts.map +1 -1
  15. package/dist/db/schema.js +69 -0
  16. package/dist/db/schema.js.map +1 -1
  17. package/dist/extensions/loader.d.ts.map +1 -1
  18. package/dist/extensions/loader.js +16 -0
  19. package/dist/extensions/loader.js.map +1 -1
  20. package/dist/index.d.ts +30 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +132 -7
  23. package/dist/index.js.map +1 -1
  24. package/dist/orchestrator.d.ts +7 -0
  25. package/dist/orchestrator.d.ts.map +1 -1
  26. package/dist/orchestrator.js +30 -0
  27. package/dist/orchestrator.js.map +1 -1
  28. package/dist/scheduler/heartbeat.d.ts +27 -0
  29. package/dist/scheduler/heartbeat.d.ts.map +1 -0
  30. package/dist/scheduler/heartbeat.js +74 -0
  31. package/dist/scheduler/heartbeat.js.map +1 -0
  32. package/dist/scheduler/parse.d.ts +42 -0
  33. package/dist/scheduler/parse.d.ts.map +1 -0
  34. package/dist/scheduler/parse.js +119 -0
  35. package/dist/scheduler/parse.js.map +1 -0
  36. package/dist/scheduler-registry.d.ts +7 -3
  37. package/dist/scheduler-registry.d.ts.map +1 -1
  38. package/dist/scheduler-registry.js +3 -0
  39. package/dist/scheduler-registry.js.map +1 -1
  40. package/dist/scheduler.d.ts +71 -15
  41. package/dist/scheduler.d.ts.map +1 -1
  42. package/dist/scheduler.js +304 -64
  43. package/dist/scheduler.js.map +1 -1
  44. package/dist/server.d.ts.map +1 -1
  45. package/dist/server.js +18 -4
  46. package/dist/server.js.map +1 -1
  47. package/dist/setup-wizard.d.ts +5 -0
  48. package/dist/setup-wizard.d.ts.map +1 -1
  49. package/dist/setup-wizard.js +23 -69
  50. package/dist/setup-wizard.js.map +1 -1
  51. package/dist/skills-cli.d.ts +22 -0
  52. package/dist/skills-cli.d.ts.map +1 -0
  53. package/dist/skills-cli.js +56 -0
  54. package/dist/skills-cli.js.map +1 -0
  55. package/dist/utils/atomic-config.d.ts +7 -0
  56. package/dist/utils/atomic-config.d.ts.map +1 -0
  57. package/dist/utils/atomic-config.js +10 -0
  58. package/dist/utils/atomic-config.js.map +1 -0
  59. package/dist/utils/docker.d.ts +10 -0
  60. package/dist/utils/docker.d.ts.map +1 -0
  61. package/dist/utils/docker.js +27 -0
  62. package/dist/utils/docker.js.map +1 -0
  63. package/dist/wizard/index.d.ts +21 -0
  64. package/dist/wizard/index.d.ts.map +1 -0
  65. package/dist/wizard/index.js +101 -0
  66. package/dist/wizard/index.js.map +1 -0
  67. package/dist/wizard/prompter.d.ts +48 -0
  68. package/dist/wizard/prompter.d.ts.map +1 -0
  69. package/dist/wizard/prompter.js +62 -0
  70. package/dist/wizard/prompter.js.map +1 -0
  71. package/dist/wizard/steps/channels.d.ts +20 -0
  72. package/dist/wizard/steps/channels.d.ts.map +1 -0
  73. package/dist/wizard/steps/channels.js +215 -0
  74. package/dist/wizard/steps/channels.js.map +1 -0
  75. package/dist/wizard/steps/launch.d.ts +20 -0
  76. package/dist/wizard/steps/launch.d.ts.map +1 -0
  77. package/dist/wizard/steps/launch.js +82 -0
  78. package/dist/wizard/steps/launch.js.map +1 -0
  79. package/dist/wizard/steps/name.d.ts +9 -0
  80. package/dist/wizard/steps/name.d.ts.map +1 -0
  81. package/dist/wizard/steps/name.js +16 -0
  82. package/dist/wizard/steps/name.js.map +1 -0
  83. package/dist/wizard/steps/provider.d.ts +22 -0
  84. package/dist/wizard/steps/provider.d.ts.map +1 -0
  85. package/dist/wizard/steps/provider.js +134 -0
  86. package/dist/wizard/steps/provider.js.map +1 -0
  87. package/dist/wizard/steps/web-search.d.ts +10 -0
  88. package/dist/wizard/steps/web-search.d.ts.map +1 -0
  89. package/dist/wizard/steps/web-search.js +84 -0
  90. package/dist/wizard/steps/web-search.js.map +1 -0
  91. package/package.json +1 -1
@@ -0,0 +1,74 @@
1
+ /**
2
+ * System Heartbeat
3
+ *
4
+ * Runs at the server level (not per-session). Fires at a configurable interval,
5
+ * renders a live prompt with the current task snapshot, and dispatches it
6
+ * through the orchestrator. IDLE responses are silently suppressed.
7
+ */
8
+ import { parseHumanInterval } from './parse.js';
9
+ import { getTasksDue, formatTasksDue } from '../scheduler.js';
10
+ // ─── renderHeartbeatPrompt ────────────────────────────────────────────────────
11
+ /**
12
+ * Renders a fresh heartbeat prompt with:
13
+ * - Current timestamp
14
+ * - Overdue tasks
15
+ * - Upcoming tasks (next 24h)
16
+ * - IDLE instruction
17
+ */
18
+ export function renderHeartbeatPrompt(db) {
19
+ const now = new Date().toISOString();
20
+ const in24h = new Date(Date.now() + 86_400_000).toISOString();
21
+ const due = getTasksDue(db, now);
22
+ const upcoming = db
23
+ .prepare("SELECT * FROM tasks WHERE status='active' AND next_run > ? AND next_run <= ?")
24
+ .all(now, in24h);
25
+ const lines = [
26
+ `System heartbeat — ${new Date().toLocaleString()}`,
27
+ '',
28
+ due.length > 0
29
+ ? `Overdue tasks (${due.length}):\n${formatTasksDue(due)}`
30
+ : 'No overdue tasks.',
31
+ '',
32
+ upcoming.length > 0
33
+ ? `Upcoming tasks (next 24h, ${upcoming.length}):\n${upcoming
34
+ .map((t) => ` [${t.id}] ${t.prompt.slice(0, 60)} — due ${t.next_run}`)
35
+ .join('\n')}`
36
+ : 'No upcoming tasks in next 24h.',
37
+ '',
38
+ 'If nothing needs your attention, respond with a single word: IDLE',
39
+ ];
40
+ return lines.join('\n');
41
+ }
42
+ // ─── Singleton timer ──────────────────────────────────────────────────────────
43
+ let _heartbeatTimer = null;
44
+ // ─── startHeartbeat ───────────────────────────────────────────────────────────
45
+ export function startHeartbeat(config, db, orchestrator) {
46
+ if (!config.enabled)
47
+ return;
48
+ const intervalMs = parseHumanInterval(config.interval) ?? 300_000; // default 5 min
49
+ const tick = async () => {
50
+ try {
51
+ const prompt = renderHeartbeatPrompt(db);
52
+ const result = await orchestrator.handleHeartbeatTick({
53
+ contextId: config.contextId,
54
+ prompt,
55
+ });
56
+ if (result.trim().toUpperCase() !== 'IDLE') {
57
+ orchestrator.sendToDefaultChannel(config.contextId, result);
58
+ }
59
+ }
60
+ catch (err) {
61
+ console.warn(`[Heartbeat] tick failed: ${err}`);
62
+ }
63
+ _heartbeatTimer = setTimeout(tick, intervalMs);
64
+ };
65
+ _heartbeatTimer = setTimeout(tick, intervalMs);
66
+ }
67
+ // ─── stopHeartbeat ────────────────────────────────────────────────────────────
68
+ export function stopHeartbeat() {
69
+ if (_heartbeatTimer) {
70
+ clearTimeout(_heartbeatTimer);
71
+ _heartbeatTimer = null;
72
+ }
73
+ }
74
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/scheduler/heartbeat.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAS9D,iFAAiF;AAEjF;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAqB;IACzD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IAE9D,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,EAAE;SAChB,OAAO,CACN,8EAA8E,CAC/E;SACA,GAAG,CAAC,GAAG,EAAE,KAAK,CAA4D,CAAC;IAE9E,MAAM,KAAK,GAAG;QACZ,sBAAsB,IAAI,IAAI,EAAE,CAAC,cAAc,EAAE,EAAE;QACnD,EAAE;QACF,GAAG,CAAC,MAAM,GAAG,CAAC;YACZ,CAAC,CAAC,kBAAkB,GAAG,CAAC,MAAM,OAAO,cAAc,CAAC,GAAG,CAAC,EAAE;YAC1D,CAAC,CAAC,mBAAmB;QACvB,EAAE;QACF,QAAQ,CAAC,MAAM,GAAG,CAAC;YACjB,CAAC,CAAC,6BAA6B,QAAQ,CAAC,MAAM,OAAO,QAAQ;iBACxD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;iBACtE,IAAI,CAAC,IAAI,CAAC,EAAE;YACjB,CAAC,CAAC,gCAAgC;QACpC,EAAE;QACF,mEAAmE;KACpE,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,iFAAiF;AAEjF,IAAI,eAAe,GAAyC,IAAI,CAAC;AAEjE,iFAAiF;AAEjF,MAAM,UAAU,cAAc,CAC5B,MAAuB,EACvB,EAAqB,EACrB,YAAmC;IAEnC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO;IAE5B,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,CAAC,gBAAgB;IAEnF,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;QACtB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,mBAAmB,CAAC;gBACpD,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,MAAM;aACP,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;gBAC3C,YAAY,CAAC,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,eAAe,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,eAAe,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AACjD,CAAC;AAED,iFAAiF;AAEjF,MAAM,UAAU,aAAa;IAC3B,IAAI,eAAe,EAAE,CAAC;QACpB,YAAY,CAAC,eAAe,CAAC,CAAC;QAC9B,eAAe,GAAG,IAAI,CAAC;IACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Schedule parser
3
+ *
4
+ * Parses human-friendly schedule strings into typed schedule descriptors.
5
+ * Supports: ISO 8601 datetimes (once), human interval aliases + "every N unit"
6
+ * (interval), and cron expressions (cron).
7
+ */
8
+ export type ScheduleType = 'once' | 'interval' | 'cron';
9
+ export interface ScheduleDescriptor {
10
+ type: ScheduleType;
11
+ normalizedMs?: number;
12
+ }
13
+ export interface TaskForNextRun {
14
+ schedule_type: string;
15
+ schedule_value: string;
16
+ normalized_ms: number | null;
17
+ next_run: string | null;
18
+ }
19
+ /**
20
+ * Parses a human-friendly interval string into milliseconds.
21
+ * Returns null if the string is not a recognized interval.
22
+ *
23
+ * Supports:
24
+ * - Aliases: "hourly", "daily", "weekly"
25
+ * - "every N unit": "every 30m", "every 2h", "every 1d", "every 5 minutes"
26
+ */
27
+ export declare function parseHumanInterval(s: string): number | null;
28
+ /**
29
+ * Detects schedule type from a string value.
30
+ * - ISO 8601 datetime → once
31
+ * - Alias / "every N unit" → interval (with normalizedMs)
32
+ * - Anything else → cron (validated via cron-parser; throws on invalid)
33
+ */
34
+ export declare function detectScheduleType(value: string): ScheduleDescriptor;
35
+ /**
36
+ * Computes the next run time for a task.
37
+ * - once: returns null
38
+ * - cron: returns next occurrence after now via cron-parser
39
+ * - interval: advances stored next_run by normalizedMs, skipping past times (drift-free)
40
+ */
41
+ export declare function computeNextRun(task: TaskForNextRun): string | null;
42
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/scheduler/parse.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAExD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAoCD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoB3D;AAID;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAqBpE;AAID;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAqBlE"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Schedule parser
3
+ *
4
+ * Parses human-friendly schedule strings into typed schedule descriptors.
5
+ * Supports: ISO 8601 datetimes (once), human interval aliases + "every N unit"
6
+ * (interval), and cron expressions (cron).
7
+ */
8
+ import { createRequire } from 'module';
9
+ const _require = createRequire(import.meta.url);
10
+ const { parseExpression } = _require('cron-parser');
11
+ // ─── Constants ────────────────────────────────────────────────────────────────
12
+ const UNIT_MS = {
13
+ s: 1_000,
14
+ sec: 1_000,
15
+ secs: 1_000,
16
+ second: 1_000,
17
+ seconds: 1_000,
18
+ m: 60_000,
19
+ min: 60_000,
20
+ mins: 60_000,
21
+ minute: 60_000,
22
+ minutes: 60_000,
23
+ h: 3_600_000,
24
+ hr: 3_600_000,
25
+ hrs: 3_600_000,
26
+ hour: 3_600_000,
27
+ hours: 3_600_000,
28
+ d: 86_400_000,
29
+ day: 86_400_000,
30
+ days: 86_400_000,
31
+ w: 7 * 86_400_000,
32
+ week: 7 * 86_400_000,
33
+ weeks: 7 * 86_400_000,
34
+ };
35
+ const ALIASES = {
36
+ hourly: 3_600_000,
37
+ daily: 86_400_000,
38
+ weekly: 7 * 86_400_000,
39
+ };
40
+ // ─── parseHumanInterval ───────────────────────────────────────────────────────
41
+ /**
42
+ * Parses a human-friendly interval string into milliseconds.
43
+ * Returns null if the string is not a recognized interval.
44
+ *
45
+ * Supports:
46
+ * - Aliases: "hourly", "daily", "weekly"
47
+ * - "every N unit": "every 30m", "every 2h", "every 1d", "every 5 minutes"
48
+ */
49
+ export function parseHumanInterval(s) {
50
+ const lower = s.trim().toLowerCase();
51
+ // Aliases
52
+ if (ALIASES[lower] !== undefined) {
53
+ return ALIASES[lower];
54
+ }
55
+ // "every N unit"
56
+ const everyMatch = lower.match(/^every\s+(\d+(?:\.\d+)?)\s*([a-z]+)$/);
57
+ if (everyMatch) {
58
+ const n = parseFloat(everyMatch[1]);
59
+ const unit = everyMatch[2];
60
+ const ms = UNIT_MS[unit];
61
+ if (ms !== undefined && n > 0) {
62
+ return Math.round(n * ms);
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+ // ─── detectScheduleType ───────────────────────────────────────────────────────
68
+ /**
69
+ * Detects schedule type from a string value.
70
+ * - ISO 8601 datetime → once
71
+ * - Alias / "every N unit" → interval (with normalizedMs)
72
+ * - Anything else → cron (validated via cron-parser; throws on invalid)
73
+ */
74
+ export function detectScheduleType(value) {
75
+ const trimmed = value.trim();
76
+ // ISO 8601 datetime (starts with YYYY-)
77
+ if (/^\d{4}-\d{2}-\d{2}T/.test(trimmed)) {
78
+ return { type: 'once' };
79
+ }
80
+ // Human interval
81
+ const ms = parseHumanInterval(trimmed);
82
+ if (ms !== null) {
83
+ return { type: 'interval', normalizedMs: ms };
84
+ }
85
+ // Try cron — throws if invalid
86
+ try {
87
+ parseExpression(trimmed);
88
+ return { type: 'cron' };
89
+ }
90
+ catch {
91
+ throw new Error(`invalid schedule: "${trimmed}" is not a valid cron expression, ISO datetime, or interval`);
92
+ }
93
+ }
94
+ // ─── computeNextRun ───────────────────────────────────────────────────────────
95
+ /**
96
+ * Computes the next run time for a task.
97
+ * - once: returns null
98
+ * - cron: returns next occurrence after now via cron-parser
99
+ * - interval: advances stored next_run by normalizedMs, skipping past times (drift-free)
100
+ */
101
+ export function computeNextRun(task) {
102
+ if (task.schedule_type === 'once') {
103
+ return null;
104
+ }
105
+ if (task.schedule_type === 'cron') {
106
+ return parseExpression(task.schedule_value).next().toDate().toISOString();
107
+ }
108
+ // interval — drift-free advancement
109
+ const ms = task.normalized_ms;
110
+ const now = Date.now();
111
+ let next = task.next_run
112
+ ? new Date(task.next_run).getTime() + ms
113
+ : now + ms;
114
+ while (next <= now) {
115
+ next += ms;
116
+ }
117
+ return new Date(next).toISOString();
118
+ }
119
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/scheduler/parse.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,11 @@
2
2
  * Global Scheduler registry singleton.
3
3
  * Set by server.ts after the Scheduler is initialised.
4
4
  */
5
- import type { SchedulerToolsTarget } from './scheduler.js';
6
- export declare let globalScheduler: SchedulerToolsTarget;
7
- export declare function setGlobalScheduler(scheduler: SchedulerToolsTarget): void;
5
+ import type { SchedulerToolsTarget, Scheduler } from './scheduler.js';
6
+ export { startHeartbeat, stopHeartbeat } from './scheduler/heartbeat.js';
7
+ export declare let globalScheduler: SchedulerToolsTarget & {
8
+ start(): Promise<void>;
9
+ stop(): void;
10
+ };
11
+ export declare function setGlobalScheduler(scheduler: Scheduler): void;
8
12
  //# sourceMappingURL=scheduler-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler-registry.d.ts","sourceRoot":"","sources":["../src/scheduler-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAQ3D,eAAO,IAAI,eAAe,EAAE,oBAAoC,CAAC;AAEjE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAExE"}
1
+ {"version":3,"file":"scheduler-registry.d.ts","sourceRoot":"","sources":["../src/scheduler-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAUzE,eAAO,IAAI,eAAe,EAAE,oBAAoB,GAAG;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,IAAI,IAAI,IAAI,CAAA;CAC1E,CAAC;AAEhB,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAE7D"}
@@ -2,10 +2,13 @@
2
2
  * Global Scheduler registry singleton.
3
3
  * Set by server.ts after the Scheduler is initialised.
4
4
  */
5
+ export { startHeartbeat, stopHeartbeat } from './scheduler/heartbeat.js';
5
6
  // Stub scheduler that no-ops until a real one is registered
6
7
  const noopScheduler = {
7
8
  registerJob: () => { },
8
9
  cancelJob: () => { },
10
+ start: async () => { },
11
+ stop: () => { },
9
12
  };
10
13
  export let globalScheduler = noopScheduler;
11
14
  export function setGlobalScheduler(scheduler) {
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler-registry.js","sourceRoot":"","sources":["../src/scheduler-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,4DAA4D;AAC5D,MAAM,aAAa,GAAyB;IAC1C,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;IACrB,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC;CACpB,CAAC;AAEF,MAAM,CAAC,IAAI,eAAe,GAAyB,aAAa,CAAC;AAEjE,MAAM,UAAU,kBAAkB,CAAC,SAA+B;IAChE,eAAe,GAAG,SAAS,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"scheduler-registry.js","sourceRoot":"","sources":["../src/scheduler-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzE,4DAA4D;AAC5D,MAAM,aAAa,GAAoE;IACrF,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;IACrB,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC;IACnB,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;IACrB,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;CACf,CAAC;AAEF,MAAM,CAAC,IAAI,eAAe,GACxB,aAAa,CAAC;AAEhB,MAAM,UAAU,kBAAkB,CAAC,SAAoB;IACrD,eAAe,GAAG,SAAS,CAAC;AAC9B,CAAC"}
@@ -1,9 +1,12 @@
1
1
  /**
2
2
  * Scheduler
3
3
  *
4
- * Loads enabled tasks from the SQLite `tasks` table on startup,
5
- * registers node-cron jobs, and dispatches prompts to the orchestrator
6
- * when jobs fire. Updates `last_run` after each execution.
4
+ * Single poll-loop (default 60s) replacing per-task node-cron jobs.
5
+ * Queries the DB for due tasks, runs them concurrently, logs each run
6
+ * in task_runs, and updates next_run / last_result on the tasks row.
7
+ *
8
+ * Preserves the registerJob / cancelJob / stop API for back-compat with
9
+ * scheduler-registry.ts and orchestrator.ts.
7
10
  */
8
11
  import type Database from 'better-sqlite3';
9
12
  export interface ScheduledTaskRef {
@@ -12,23 +15,70 @@ export interface ScheduledTaskRef {
12
15
  prompt: string;
13
16
  }
14
17
  export interface SchedulerOrchestrator {
15
- handleScheduledTask(task: ScheduledTaskRef): Promise<void>;
18
+ handleScheduledTask(task: ScheduledTaskRef): Promise<string | void>;
19
+ }
20
+ export interface SchedulerOptions {
21
+ intervalMs?: number;
22
+ }
23
+ export interface ToolResult {
24
+ content: Array<{
25
+ type: 'text';
26
+ text: string;
27
+ }>;
28
+ details: Record<string, unknown>;
29
+ isError?: boolean;
30
+ }
31
+ interface TaskRow {
32
+ id: string;
33
+ context_id: string;
34
+ schedule: string;
35
+ prompt: string;
36
+ enabled: number;
37
+ last_run: string | null;
38
+ schedule_type: string;
39
+ schedule_value: string;
40
+ normalized_ms: number | null;
41
+ status: string;
42
+ next_run: string | null;
43
+ last_result: string | null;
44
+ context_mode: string;
16
45
  }
17
46
  export declare class Scheduler {
18
47
  private _db;
19
48
  private _orchestrator;
20
- private _jobs;
21
- constructor(db: Database.Database, orchestrator: SchedulerOrchestrator);
49
+ private _intervalMs;
50
+ private _timer;
51
+ private _inFlight;
52
+ constructor(db: Database.Database, orchestrator: SchedulerOrchestrator, options?: SchedulerOptions);
22
53
  start(): Promise<void>;
54
+ stop(): void;
55
+ private _poll;
56
+ private _runTask;
57
+ private _logError;
58
+ /**
59
+ * registerJob — back-compat shim.
60
+ * Ensures a DB row exists for this task. The poll loop will pick it up.
61
+ */
23
62
  registerJob(task: {
24
63
  id: string;
25
64
  contextId: string;
26
65
  schedule: string;
27
66
  prompt: string;
28
67
  }): void;
68
+ /**
69
+ * cancelJob — back-compat shim.
70
+ * Deletes the task from DB and removes from in-flight set.
71
+ */
29
72
  cancelJob(taskId: string): void;
30
- stop(): void;
31
73
  }
74
+ /**
75
+ * Returns all tasks that are currently overdue (status=active, next_run <= now).
76
+ */
77
+ export declare function getTasksDue(db: Database.Database, now?: string): TaskRow[];
78
+ /**
79
+ * Formats a list of overdue tasks as human-readable text.
80
+ */
81
+ export declare function formatTasksDue(tasks: TaskRow[]): string;
32
82
  export interface SchedulerToolsTarget {
33
83
  registerJob(task: {
34
84
  id: string;
@@ -38,23 +88,29 @@ export interface SchedulerToolsTarget {
38
88
  }): void;
39
89
  cancelJob(taskId: string): void;
40
90
  }
41
- export interface ToolResult {
42
- content: Array<{
43
- type: 'text';
44
- text: string;
45
- }>;
46
- details: Record<string, unknown>;
47
- isError?: boolean;
48
- }
49
91
  export declare function createSchedulerTools(db: Database.Database, scheduler: SchedulerToolsTarget): {
50
92
  schedule_task(params: {
51
93
  schedule: string;
52
94
  prompt: string;
53
95
  contextId?: string;
96
+ context_mode?: string;
97
+ }): Promise<ToolResult>;
98
+ pause_task(params: {
99
+ task_id: string;
100
+ }): Promise<ToolResult>;
101
+ resume_task(params: {
102
+ task_id: string;
103
+ }): Promise<ToolResult>;
104
+ update_task(params: {
105
+ task_id: string;
106
+ schedule?: string;
107
+ prompt?: string;
108
+ context_mode?: string;
54
109
  }): Promise<ToolResult>;
55
110
  list_tasks(_params: Record<string, never>): Promise<ToolResult>;
56
111
  cancel_task(params: {
57
112
  task_id: string;
58
113
  }): Promise<ToolResult>;
59
114
  };
115
+ export {};
60
116
  //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAaD,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAoB;IAC/B,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,KAAK,CAAuD;gBAExD,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,qBAAqB;IAKhE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB5B,WAAW,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IA2B5F,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B,IAAI,IAAI,IAAI;CAMb;AAID,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7F,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,oBAAoB;0BAE3D;QAC1B,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,UAAU,CAAC;wBAsCG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;wBAsB3C;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;EAsBtE"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}