0xkobold 0.3.3 → 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,294 @@
1
+ /**
2
+ * Cron Expression Parser - 0xKobold
3
+ *
4
+ * Parses standard cron expressions and calculates next run times.
5
+ * Supports: standard cron, L (last), W (weekday), # (nth)
6
+ */
7
+ // Standard cron ranges
8
+ const RANGES = {
9
+ minute: { min: 0, max: 59 },
10
+ hour: { min: 0, max: 23 },
11
+ dayOfMonth: { min: 1, max: 31 },
12
+ month: { min: 1, max: 12 },
13
+ dayOfWeek: { min: 0, max: 6 }, // 0 = Sunday
14
+ };
15
+ const MONTH_NAMES = {
16
+ jan: 1, feb: 2, mar: 3, apr: 4, may: 5, jun: 6,
17
+ jul: 7, aug: 8, sep: 9, oct: 10, nov: 11, dec: 12,
18
+ };
19
+ const DAY_NAMES = {
20
+ sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6,
21
+ };
22
+ /**
23
+ * Parse a cron expression into structured components
24
+ */
25
+ export function parseCron(expression, timezone = 'UTC') {
26
+ const parts = expression.trim().split(/\s+/);
27
+ if (parts.length !== 5 && parts.length !== 6) {
28
+ throw new Error(`Invalid cron expression "${expression}". Expected 5 fields (min hour day month dow) or 6 fields (with seconds).`);
29
+ }
30
+ // Handle 6-field format (with seconds)
31
+ let [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
32
+ if (parts.length === 6) {
33
+ // Skip seconds, use rest
34
+ [, minute, hour, dayOfMonth, month, dayOfWeek] = parts;
35
+ }
36
+ return {
37
+ minute: parseField(minute, 'minute'),
38
+ hour: parseField(hour, 'hour'),
39
+ dayOfMonth: parseField(dayOfMonth, 'dayOfMonth'),
40
+ month: parseField(month, 'month'),
41
+ dayOfWeek: parseField(dayOfWeek, 'dayOfWeek'),
42
+ timezone,
43
+ };
44
+ }
45
+ /**
46
+ * Parse a single cron field
47
+ */
48
+ function parseField(field, type) {
49
+ const range = RANGES[type];
50
+ // Wildcard
51
+ if (field === '*')
52
+ return '*';
53
+ // Step syntax (*/5 = every 5)
54
+ if (field.startsWith('*/')) {
55
+ const step = parseInt(field.slice(2), 10);
56
+ if (isNaN(step) || step <= 0) {
57
+ throw new Error(`Invalid step value in "${field}"`);
58
+ }
59
+ const values = [];
60
+ for (let i = range.min; i <= range.max; i += step) {
61
+ values.push(i);
62
+ }
63
+ return values;
64
+ }
65
+ // Range with step (1-10/2)
66
+ if (field.includes('/')) {
67
+ const [rangePart, stepStr] = field.split('/');
68
+ const step = parseInt(stepStr, 10);
69
+ if (isNaN(step) || step <= 0) {
70
+ throw new Error(`Invalid step in "${field}"`);
71
+ }
72
+ const [start, end] = parseRange(rangePart, type);
73
+ const values = [];
74
+ for (let i = start; i <= end; i += step) {
75
+ values.push(i);
76
+ }
77
+ return values;
78
+ }
79
+ // Simple range (1-5)
80
+ if (field.includes('-')) {
81
+ const [start, end] = parseRange(field, type);
82
+ const values = [];
83
+ for (let i = start; i <= end; i++) {
84
+ values.push(i);
85
+ }
86
+ return values;
87
+ }
88
+ // List (1,2,3 or MON,WED,FRI)
89
+ if (field.includes(',')) {
90
+ const values = [];
91
+ for (const part of field.split(',')) {
92
+ const val = parseValue(part.trim(), type);
93
+ values.push(val);
94
+ }
95
+ return [...new Set(values)].sort((a, b) => a - b);
96
+ }
97
+ // Single value
98
+ return [parseValue(field, type)];
99
+ }
100
+ /**
101
+ * Parse a range like "1-5" or "MON-FRI"
102
+ */
103
+ function parseRange(rangeStr, type) {
104
+ const [startStr, endStr] = rangeStr.split('-');
105
+ return [
106
+ parseValue(startStr.trim(), type),
107
+ parseValue(endStr.trim(), type),
108
+ ];
109
+ }
110
+ /**
111
+ * Parse a single value (number or name)
112
+ */
113
+ function parseValue(value, type) {
114
+ const lower = value.toLowerCase();
115
+ // Handle month names
116
+ if (type === 'month' && MONTH_NAMES[lower] !== undefined) {
117
+ return MONTH_NAMES[lower];
118
+ }
119
+ // Handle day names
120
+ if (type === 'dayOfWeek' && DAY_NAMES[lower] !== undefined) {
121
+ return DAY_NAMES[lower];
122
+ }
123
+ // Special: L (last day of month)
124
+ if (type === 'dayOfMonth' && lower === 'l') {
125
+ return -1; // Special marker for last day
126
+ }
127
+ const num = parseInt(value, 10);
128
+ const range = RANGES[type];
129
+ if (isNaN(num)) {
130
+ throw new Error(`Invalid value "${value}" for ${type}`);
131
+ }
132
+ if (num < range.min || num > range.max) {
133
+ throw new Error(`Value ${num} out of range [${range.min}-${range.max}] for ${type}`);
134
+ }
135
+ return num;
136
+ }
137
+ /**
138
+ * Calculate the next run time for a cron expression
139
+ */
140
+ export function getNextRun(expression, from = new Date()) {
141
+ const { minute, hour, dayOfMonth, month, dayOfWeek } = expression;
142
+ // Start from the next minute
143
+ let candidate = new Date(from);
144
+ candidate.setSeconds(0, 0);
145
+ candidate.setMinutes(candidate.getMinutes() + 1);
146
+ // Limit search to prevent infinite loops
147
+ const maxIterations = 366 * 24 * 60; // ~1 year in minutes
148
+ for (let i = 0; i < maxIterations; i++) {
149
+ if (matches(candidate, expression)) {
150
+ return candidate;
151
+ }
152
+ candidate.setMinutes(candidate.getMinutes() + 1);
153
+ }
154
+ throw new Error('Could not find next run time within 1 year');
155
+ }
156
+ /**
157
+ * Check if a date matches the cron expression
158
+ */
159
+ function matches(date, expression) {
160
+ const { minute, hour, dayOfMonth, month, dayOfWeek } = expression;
161
+ if (!matchesField(date.getMinutes(), minute))
162
+ return false;
163
+ if (!matchesField(date.getHours(), hour))
164
+ return false;
165
+ if (!matchesMonth(date.getMonth() + 1, month))
166
+ return false;
167
+ if (!matchesDayOfMonth(date.getDate(), dayOfMonth, date))
168
+ return false;
169
+ if (!matchesField(date.getDay(), dayOfWeek))
170
+ return false;
171
+ return true;
172
+ }
173
+ function matchesField(value, pattern) {
174
+ if (pattern === '*')
175
+ return true;
176
+ return pattern.includes(value);
177
+ }
178
+ function matchesMonth(value, pattern) {
179
+ if (pattern === '*')
180
+ return true;
181
+ return pattern.includes(value);
182
+ }
183
+ function matchesDayOfMonth(value, pattern, date) {
184
+ if (pattern === '*')
185
+ return true;
186
+ // Handle L (last day of month)
187
+ if (pattern.includes(-1)) {
188
+ const lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
189
+ if (value === lastDay)
190
+ return true;
191
+ }
192
+ return pattern.includes(value);
193
+ }
194
+ /**
195
+ * Parse duration strings like "20m", "2h", "1h30m", "1d"
196
+ */
197
+ export function parseDuration(duration) {
198
+ const regex = /^(?:(\d+)d)?\s*(?:(\d+)h)?\s*(?:(\d+)m)?\s*(?:(\d+)s?)?$/i;
199
+ const match = duration.trim().match(regex);
200
+ if (!match) {
201
+ throw new Error(`Invalid duration "${duration}". Use format: 1d, 2h, 30m, 1h30m`);
202
+ }
203
+ const days = parseInt(match[1] || '0', 10);
204
+ const hours = parseInt(match[2] || '0', 10);
205
+ const minutes = parseInt(match[3] || '0', 10);
206
+ const seconds = parseInt(match[4] || '0', 10);
207
+ const milliseconds = days * 24 * 60 * 60 * 1000 +
208
+ hours * 60 * 60 * 1000 +
209
+ minutes * 60 * 1000 +
210
+ seconds * 1000;
211
+ return {
212
+ milliseconds,
213
+ hours: days * 24 + hours,
214
+ minutes,
215
+ seconds,
216
+ };
217
+ }
218
+ /**
219
+ * Parse absolute time like "2025-01-10T09:00:00" or ISO string
220
+ */
221
+ export function parseAt(at) {
222
+ // Try parsing as ISO date
223
+ const date = new Date(at);
224
+ if (!isNaN(date.getTime())) {
225
+ return date.getTime();
226
+ }
227
+ // Try parsing relative (e.g., "20m" shorthand for duration)
228
+ try {
229
+ const duration = parseDuration(at);
230
+ return Date.now() + duration.milliseconds;
231
+ }
232
+ catch {
233
+ // Not a valid duration either
234
+ }
235
+ throw new Error(`Invalid time "${at}". Use ISO date (2025-01-10T09:00:00) or duration (20m)`);
236
+ }
237
+ /**
238
+ * Format a cron expression in human-readable form
239
+ */
240
+ export function formatCron(expression) {
241
+ const parts = [];
242
+ if (expression.minute !== '*') {
243
+ parts.push(`minute(s): ${Array.isArray(expression.minute) ? expression.minute.join(', ') : expression.minute}`);
244
+ }
245
+ if (expression.hour !== '*') {
246
+ parts.push(`hour(s): ${Array.isArray(expression.hour) ? expression.hour.join(', ') : expression.hour}`);
247
+ }
248
+ if (expression.dayOfMonth !== '*') {
249
+ parts.push(`day(s): ${Array.isArray(expression.dayOfMonth) ? expression.dayOfMonth.join(', ') : expression.dayOfMonth}`);
250
+ }
251
+ if (expression.month !== '*') {
252
+ parts.push(`month(s): ${Array.isArray(expression.month) ? expression.month.join(', ') : expression.month}`);
253
+ }
254
+ if (expression.dayOfWeek !== '*') {
255
+ parts.push(`weekday(s): ${Array.isArray(expression.dayOfWeek) ? expression.dayOfWeek.join(', ') : expression.dayOfWeek}`);
256
+ }
257
+ return parts.length > 0 ? parts.join(', ') : 'every minute';
258
+ }
259
+ /**
260
+ * Validate a cron expression
261
+ */
262
+ export function validateCron(expression) {
263
+ try {
264
+ parseCron(expression);
265
+ return { valid: true };
266
+ }
267
+ catch (error) {
268
+ return { valid: false, error: error.message };
269
+ }
270
+ }
271
+ /**
272
+ * Common cron presets
273
+ */
274
+ export const CRON_PRESETS = {
275
+ '@yearly': '0 0 1 1 *',
276
+ '@annually': '0 0 1 1 *',
277
+ '@monthly': '0 0 1 * *',
278
+ '@weekly': '0 0 * * 0',
279
+ '@daily': '0 0 * * *',
280
+ '@midnight': '0 0 * * *',
281
+ '@hourly': '0 * * * *',
282
+ };
283
+ /**
284
+ * Parse preset or standard expression
285
+ */
286
+ export function parseExpression(expression, timezone) {
287
+ const normalized = expression.trim();
288
+ // Check for presets
289
+ if (normalized in CRON_PRESETS) {
290
+ return parseCron(CRON_PRESETS[normalized], timezone);
291
+ }
292
+ return parseCron(normalized, timezone);
293
+ }
294
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/cron/parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,uBAAuB;AACvB,MAAM,MAAM,GAAG;IACb,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IAC3B,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACzB,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IAC/B,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IAC1B,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,aAAa;CAC7C,CAAC;AAEF,MAAM,WAAW,GAA2B;IAC1C,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;IAC9C,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;CAClD,CAAC;AAEF,MAAM,SAAS,GAA2B;IACxC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;CACvD,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAE,WAAmB,KAAK;IACpE,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE7C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,4BAA4B,UAAU,2EAA2E,CAClH,CAAC;IACJ,CAAC;IAED,uCAAuC;IACvC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;IAEzD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,yBAAyB;QACzB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;IACzD,CAAC;IAED,OAAO;QACL,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC;QACpC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QAC9B,UAAU,EAAE,UAAU,CAAC,UAAU,EAAE,YAAY,CAAC;QAChD,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC;QACjC,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,WAAW,CAAC;QAC7C,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,KAAa,EAAE,IAAyB;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAE3B,WAAW;IACX,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,GAAG,CAAC;IAE9B,8BAA8B;IAC9B,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,GAAG,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,2BAA2B;IAC3B,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,oBAAoB,KAAK,GAAG,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,qBAAqB;IACrB,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,8BAA8B;IAC9B,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QACD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,eAAe;IACf,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,QAAgB,EAAE,IAAyB;IAC7D,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO;QACL,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC;QACjC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC;KAChC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,KAAa,EAAE,IAAyB;IAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAElC,qBAAqB;IACrB,IAAI,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;QACzD,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,mBAAmB;IACnB,IAAI,IAAI,KAAK,WAAW,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;QAC3D,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,iCAAiC;IACjC,IAAI,IAAI,KAAK,YAAY,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;QAC3C,OAAO,CAAC,CAAC,CAAC,CAAC,8BAA8B;IAC3C,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAE3B,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,SAAS,GAAG,kBAAkB,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,SAAS,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,UAA0B,EAC1B,OAAa,IAAI,IAAI,EAAE;IAEvB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;IAElE,6BAA6B;IAC7B,IAAI,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;IAEjD,yCAAyC;IACzC,MAAM,aAAa,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,qBAAqB;IAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;YACnC,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;AAChE,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,IAAU,EAAE,UAA0B;IACrD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;IAElE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IAE1D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,OAAuB;IAC1D,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,OAAuB;IAC1D,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAa,EACb,OAAuB,EACvB,IAAU;IAEV,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEjC,+BAA+B;IAC/B,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAC/E,IAAI,KAAK,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;IACrC,CAAC;IAED,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,KAAK,GAAG,2DAA2D,CAAC;IAC1E,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,mCAAmC,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IAE9C,MAAM,YAAY,GAChB,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;QAC1B,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;QACtB,OAAO,GAAG,EAAE,GAAG,IAAI;QACnB,OAAO,GAAG,IAAI,CAAC;IAEjB,OAAO;QACL,YAAY;QACZ,KAAK,EAAE,IAAI,GAAG,EAAE,GAAG,KAAK;QACxB,OAAO;QACP,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,0BAA0B;IAC1B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IAE1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED,4DAA4D;IAC5D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,iBAAiB,EAAE,yDAAyD,CAAC,CAAC;AAChG,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,UAA0B;IACnD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,UAAU,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IAClH,CAAC;IACD,IAAI,UAAU,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1G,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3H,CAAC;IACD,IAAI,UAAU,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9G,CAAC;IACD,IAAI,UAAU,CAAC,SAAS,KAAK,GAAG,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;IAC5H,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,IAAI,CAAC;QACH,SAAS,CAAC,UAAU,CAAC,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,CAAC;IAC3D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,WAAW;IACxB,UAAU,EAAE,WAAW;IACvB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,WAAW;IACrB,WAAW,EAAE,WAAW;IACxB,SAAS,EAAE,WAAW;CACd,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,QAAiB;IACnE,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAErC,oBAAoB;IACpB,IAAI,UAAU,IAAI,YAAY,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC,YAAY,CAAC,UAAuC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Cron Job Runner - 0xKobold
3
+ *
4
+ * Executes cron jobs in isolated or main sessions.
5
+ * Isolated = fresh context, Main = shares conversation history
6
+ */
7
+ import { OllamaProvider, AnthropicProvider } from "../llm/index.js";
8
+ // Provider cache
9
+ const providers = new Map();
10
+ /**
11
+ * Get or create provider for a model
12
+ */
13
+ function getProvider(model) {
14
+ // Extract provider prefix (e.g., "ollama/", "claude/", "openai/")
15
+ const [providerName] = model.split('/');
16
+ if (providers.has(providerName)) {
17
+ return providers.get(providerName);
18
+ }
19
+ let provider;
20
+ switch (providerName) {
21
+ case 'ollama':
22
+ provider = new OllamaProvider();
23
+ break;
24
+ case 'claude':
25
+ provider = new AnthropicProvider();
26
+ break;
27
+ default:
28
+ // Default to Ollama for unknown providers
29
+ provider = new OllamaProvider();
30
+ }
31
+ providers.set(providerName, provider);
32
+ return provider;
33
+ }
34
+ /**
35
+ * Run a job based on its session type
36
+ */
37
+ export async function runJobRunner(job) {
38
+ console.log(`[CronRunner] Starting job "${job.name}" (${job.session} session)`);
39
+ const startTime = Date.now();
40
+ try {
41
+ if (job.session === "isolated") {
42
+ return await runIsolatedSession(job);
43
+ }
44
+ else {
45
+ return await runMainSession(job);
46
+ }
47
+ }
48
+ catch (error) {
49
+ const duration = Date.now() - startTime;
50
+ return {
51
+ success: false,
52
+ output: "",
53
+ tokensUsed: 0,
54
+ duration,
55
+ error: error instanceof Error ? error.message : String(error),
56
+ };
57
+ }
58
+ }
59
+ /**
60
+ * Run job in isolated session (separate context)
61
+ *
62
+ * Creates a fresh conversation with just the job message.
63
+ * No history pollution, different model possible.
64
+ */
65
+ async function runIsolatedSession(job) {
66
+ const sessionId = `cron:${job.id}`;
67
+ const model = job.model || "kimi-k2.5:cloud";
68
+ console.log(`[CronRunner] Isolated session: ${sessionId}, model: ${model}`);
69
+ const startTime = Date.now();
70
+ try {
71
+ const provider = getProvider(model);
72
+ // Build system prompt with persona context if available
73
+ const systemPrompt = buildSystemPrompt(job);
74
+ // Build messages
75
+ const messages = [
76
+ { role: "system", content: systemPrompt },
77
+ { role: "user", content: job.message },
78
+ ];
79
+ // Determine temperature and max tokens based on thinking level
80
+ const temperature = getTemperature(job.thinkingLevel);
81
+ const maxTokens = getMaxTokens(job.thinkingLevel);
82
+ // Call LLM
83
+ const response = await provider.chat({
84
+ model,
85
+ messages,
86
+ temperature,
87
+ maxTokens,
88
+ stream: false,
89
+ });
90
+ const duration = Date.now() - startTime;
91
+ return {
92
+ success: true,
93
+ output: response.content,
94
+ tokensUsed: response.usage?.inputTokens || 0 + (response.usage?.outputTokens || 0),
95
+ duration,
96
+ };
97
+ }
98
+ catch (error) {
99
+ const duration = Date.now() - startTime;
100
+ const errorMsg = error instanceof Error ? error.message : String(error);
101
+ console.error(`[CronRunner] Isolated session error: ${errorMsg}`);
102
+ return {
103
+ success: false,
104
+ output: "",
105
+ tokensUsed: 0,
106
+ duration,
107
+ error: errorMsg,
108
+ };
109
+ }
110
+ }
111
+ /**
112
+ * Run job in main session (shared context)
113
+ *
114
+ * Injects job into main session as a system event.
115
+ * Has full conversation context but may be delayed.
116
+ */
117
+ async function runMainSession(job) {
118
+ console.log(`[CronRunner] Main session: injecting event`);
119
+ const startTime = Date.now();
120
+ try {
121
+ // For now, treat main session as isolated but flag it
122
+ // TODO: Integrate with actual main session context
123
+ const result = await runIsolatedSession(job);
124
+ // Mark as main session in output
125
+ return {
126
+ ...result,
127
+ output: `[Scheduled Task]\n${result.output}`,
128
+ };
129
+ }
130
+ catch (error) {
131
+ const duration = Date.now() - startTime;
132
+ return {
133
+ success: false,
134
+ output: "",
135
+ tokensUsed: 0,
136
+ duration,
137
+ error: error instanceof Error ? error.message : String(error),
138
+ };
139
+ }
140
+ }
141
+ /**
142
+ * Build system prompt for isolated sessions
143
+ */
144
+ function buildSystemPrompt(job) {
145
+ const parts = [
146
+ `You are 0xKobold, an AI coding assistant running as a scheduled task.`,
147
+ ``,
148
+ `Task: ${job.name}`,
149
+ `Session Type: ${job.session}`,
150
+ `Model: ${job.model || "default"}`,
151
+ ];
152
+ if (job.thinkingLevel) {
153
+ parts.push(`Thinking Level: ${job.thinkingLevel}`);
154
+ }
155
+ parts.push(`
156
+ Guidelines:
157
+ - Be concise but complete
158
+ - Focus on the specific task requested
159
+ - If you need tools, use them appropriately
160
+ - Report any errors clearly
161
+ `);
162
+ return parts.join('\n');
163
+ }
164
+ /**
165
+ * Get temperature based on thinking level
166
+ */
167
+ function getTemperature(level) {
168
+ switch (level) {
169
+ case 'fast':
170
+ return 0.3; // More deterministic
171
+ case 'deep':
172
+ return 0.8; // More creative
173
+ case 'normal':
174
+ default:
175
+ return 0.7;
176
+ }
177
+ }
178
+ /**
179
+ * Get max tokens based on thinking level
180
+ */
181
+ function getMaxTokens(level) {
182
+ switch (level) {
183
+ case 'fast':
184
+ return 1024;
185
+ case 'deep':
186
+ return 4096;
187
+ case 'normal':
188
+ default:
189
+ return 2048;
190
+ }
191
+ }
192
+ /**
193
+ * Execute a system event job (no LLM)
194
+ *
195
+ * For jobs that just need to trigger something in the main session
196
+ * without LLM processing.
197
+ */
198
+ export async function runSystemEvent(job) {
199
+ console.log(`[CronRunner] System event: ${job.message}`);
200
+ const startTime = Date.now();
201
+ try {
202
+ // TODO: Emit event to main session
203
+ // This should trigger a system event in the agent
204
+ return {
205
+ success: true,
206
+ output: job.message,
207
+ tokensUsed: 0,
208
+ duration: Date.now() - startTime,
209
+ };
210
+ }
211
+ catch (error) {
212
+ return {
213
+ success: false,
214
+ output: "",
215
+ tokensUsed: 0,
216
+ duration: Date.now() - startTime,
217
+ error: error instanceof Error ? error.message : String(error),
218
+ };
219
+ }
220
+ }
221
+ /**
222
+ * Pre-job validation
223
+ */
224
+ export function validateJob(job) {
225
+ const errors = [];
226
+ if (!job.name || job.name.trim().length === 0) {
227
+ errors.push("Job name is required");
228
+ }
229
+ if (!job.message || job.message.trim().length === 0) {
230
+ errors.push("Job message is required");
231
+ }
232
+ if (!job.cronExpression && !job.at) {
233
+ errors.push("Either cron expression or at timestamp is required");
234
+ }
235
+ if (job.nextRunAt <= 0) {
236
+ errors.push("Next run time must be in the future");
237
+ }
238
+ return {
239
+ valid: errors.length === 0,
240
+ errors,
241
+ };
242
+ }
243
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/cron/runner.ts"],"names":[],"mappings":"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"}