@namzu/sdk 45.0.0 → 45.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.
- package/CHANGELOG.md +55 -0
- package/dist/authorization/gate.d.ts.map +1 -1
- package/dist/authorization/gate.js +12 -2
- package/dist/authorization/gate.js.map +1 -1
- package/dist/authorization/rules.d.ts.map +1 -1
- package/dist/authorization/rules.js +37 -6
- package/dist/authorization/rules.js.map +1 -1
- package/dist/authorization/shell-lexer.d.ts +14 -0
- package/dist/authorization/shell-lexer.d.ts.map +1 -1
- package/dist/authorization/shell-lexer.js +19 -6
- package/dist/authorization/shell-lexer.js.map +1 -1
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +2 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +1 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/directory/types.d.ts +2 -0
- package/dist/directory/types.d.ts.map +1 -1
- package/dist/directory/types.js.map +1 -1
- package/dist/manager/resident/outbox.d.ts +4 -4
- package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
- package/dist/prompt/coding-agent-doctrine.js +1 -0
- package/dist/prompt/coding-agent-doctrine.js.map +1 -1
- package/dist/public-runtime.d.ts +4 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +11 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +4 -0
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +10 -0
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +7 -1
- package/dist/public-types.d.ts.map +1 -1
- package/dist/runtime/query/declined.d.ts +12 -0
- package/dist/runtime/query/declined.d.ts.map +1 -0
- package/dist/runtime/query/declined.js +12 -0
- package/dist/runtime/query/declined.js.map +1 -0
- package/dist/runtime/query/executor.d.ts +3 -1
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +14 -2
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +1 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +7 -0
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +6 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/handoff.d.ts +22 -0
- package/dist/runtime/query/iteration/phases/handoff.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/handoff.js +65 -0
- package/dist/runtime/query/iteration/phases/handoff.js.map +1 -0
- package/dist/runtime/query/iteration/phases/index.d.ts +1 -0
- package/dist/runtime/query/iteration/phases/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/index.js +1 -0
- package/dist/runtime/query/iteration/phases/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +8 -3
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +3 -2
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +4 -3
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/schedules/cron.d.ts +21 -0
- package/dist/schedules/cron.d.ts.map +1 -0
- package/dist/schedules/cron.js +167 -0
- package/dist/schedules/cron.js.map +1 -0
- package/dist/schedules/describe.d.ts +14 -0
- package/dist/schedules/describe.d.ts.map +1 -0
- package/dist/schedules/describe.js +133 -0
- package/dist/schedules/describe.js.map +1 -0
- package/dist/schedules/errors.d.ts +11 -0
- package/dist/schedules/errors.d.ts.map +1 -0
- package/dist/schedules/errors.js +15 -0
- package/dist/schedules/errors.js.map +1 -0
- package/dist/schedules/evaluate.d.ts +35 -0
- package/dist/schedules/evaluate.d.ts.map +1 -0
- package/dist/schedules/evaluate.js +158 -0
- package/dist/schedules/evaluate.js.map +1 -0
- package/dist/schedules/index.d.ts +11 -0
- package/dist/schedules/index.d.ts.map +1 -0
- package/dist/schedules/index.js +8 -0
- package/dist/schedules/index.js.map +1 -0
- package/dist/schedules/next-fire.d.ts +50 -0
- package/dist/schedules/next-fire.d.ts.map +1 -0
- package/dist/schedules/next-fire.js +250 -0
- package/dist/schedules/next-fire.js.map +1 -0
- package/dist/schedules/spec.d.ts +30 -0
- package/dist/schedules/spec.d.ts.map +1 -0
- package/dist/schedules/spec.js +169 -0
- package/dist/schedules/spec.js.map +1 -0
- package/dist/schedules/types.d.ts +144 -0
- package/dist/schedules/types.d.ts.map +1 -0
- package/dist/schedules/types.js +11 -0
- package/dist/schedules/types.js.map +1 -0
- package/dist/schedules/tz.d.ts +44 -0
- package/dist/schedules/tz.d.ts.map +1 -0
- package/dist/schedules/tz.js +141 -0
- package/dist/schedules/tz.js.map +1 -0
- package/dist/skills/index.d.ts +1 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/loader.d.ts +16 -3
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +48 -4
- package/dist/skills/loader.js.map +1 -1
- package/dist/tools/builtins/browser-url.d.ts +83 -0
- package/dist/tools/builtins/browser-url.d.ts.map +1 -0
- package/dist/tools/builtins/browser-url.js +240 -0
- package/dist/tools/builtins/browser-url.js.map +1 -0
- package/dist/tools/builtins/browser.d.ts +367 -0
- package/dist/tools/builtins/browser.d.ts.map +1 -0
- package/dist/tools/builtins/browser.js +704 -0
- package/dist/tools/builtins/browser.js.map +1 -0
- package/dist/tools/builtins/skill.d.ts.map +1 -1
- package/dist/tools/builtins/skill.js +15 -0
- package/dist/tools/builtins/skill.js.map +1 -1
- package/dist/tools/defineTool.d.ts +2 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +1 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/schedules/index.d.ts +5 -0
- package/dist/tools/schedules/index.d.ts.map +1 -0
- package/dist/tools/schedules/index.js +4 -0
- package/dist/tools/schedules/index.js.map +1 -0
- package/dist/tools/schedules/loop-tool.d.ts +14 -0
- package/dist/tools/schedules/loop-tool.d.ts.map +1 -0
- package/dist/tools/schedules/loop-tool.js +81 -0
- package/dist/tools/schedules/loop-tool.js.map +1 -0
- package/dist/tools/schedules/present.d.ts +16 -0
- package/dist/tools/schedules/present.d.ts.map +1 -0
- package/dist/tools/schedules/present.js +69 -0
- package/dist/tools/schedules/present.js.map +1 -0
- package/dist/tools/schedules/prompt-scan.d.ts +17 -0
- package/dist/tools/schedules/prompt-scan.d.ts.map +1 -0
- package/dist/tools/schedules/prompt-scan.js +92 -0
- package/dist/tools/schedules/prompt-scan.js.map +1 -0
- package/dist/tools/schedules/schedule-tool.d.ts +16 -0
- package/dist/tools/schedules/schedule-tool.d.ts.map +1 -0
- package/dist/tools/schedules/schedule-tool.js +327 -0
- package/dist/tools/schedules/schedule-tool.js.map +1 -0
- package/dist/tools/schedules/types.d.ts +184 -0
- package/dist/tools/schedules/types.d.ts.map +1 -0
- package/dist/tools/schedules/types.js +11 -0
- package/dist/tools/schedules/types.js.map +1 -0
- package/dist/types/authorization/index.d.ts +86 -9
- package/dist/types/authorization/index.d.ts.map +1 -1
- package/dist/types/authorization/index.js +11 -1
- package/dist/types/authorization/index.js.map +1 -1
- package/dist/types/browser/index.d.ts +280 -0
- package/dist/types/browser/index.d.ts.map +1 -0
- package/dist/types/browser/index.js +12 -0
- package/dist/types/browser/index.js.map +1 -0
- package/dist/types/session/events.d.ts +6 -0
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/records.d.ts +23 -0
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +9 -0
- package/dist/types/session/records.js.map +1 -1
- package/dist/types/tool/index.d.ts +41 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/types/tool/presentation.d.ts +7 -0
- package/dist/types/tool/presentation.d.ts.map +1 -1
- package/dist/utils/frontmatter.d.ts +18 -2
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +13 -3
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/id.d.ts +8 -0
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +12 -0
- package/dist/utils/id.js.map +1 -1
- package/package.json +1 -1
- package/src/authorization/gate.ts +14 -2
- package/src/authorization/rules.ts +37 -7
- package/src/authorization/shell-lexer.ts +36 -6
- package/src/bridge/a2a/mapper.ts +2 -0
- package/src/bridge/sse/mapper.ts +1 -0
- package/src/directory/types.ts +2 -0
- package/src/prompt/coding-agent-doctrine.ts +1 -0
- package/src/public-runtime.ts +28 -0
- package/src/public-tools.ts +35 -0
- package/src/public-types.ts +50 -0
- package/src/runtime/query/declined.ts +12 -0
- package/src/runtime/query/executor.ts +17 -1
- package/src/runtime/query/index.ts +1 -0
- package/src/runtime/query/iteration/index.ts +8 -0
- package/src/runtime/query/iteration/phases/context.ts +6 -0
- package/src/runtime/query/iteration/phases/handoff.ts +74 -0
- package/src/runtime/query/iteration/phases/index.ts +1 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +11 -4
- package/src/runtime/query/resume-pending.ts +3 -2
- package/src/runtime/query/review-policy.ts +4 -3
- package/src/schedules/cron.ts +202 -0
- package/src/schedules/describe.ts +138 -0
- package/src/schedules/errors.ts +15 -0
- package/src/schedules/evaluate.ts +178 -0
- package/src/schedules/index.ts +18 -0
- package/src/schedules/next-fire.ts +257 -0
- package/src/schedules/spec.ts +210 -0
- package/src/schedules/types.ts +163 -0
- package/src/schedules/tz.ts +155 -0
- package/src/skills/index.ts +1 -1
- package/src/skills/loader.ts +55 -4
- package/src/tools/builtins/browser-url.ts +251 -0
- package/src/tools/builtins/browser.ts +817 -0
- package/src/tools/builtins/skill.ts +18 -0
- package/src/tools/defineTool.ts +3 -0
- package/src/tools/schedules/index.ts +4 -0
- package/src/tools/schedules/loop-tool.ts +85 -0
- package/src/tools/schedules/present.ts +86 -0
- package/src/tools/schedules/prompt-scan.ts +96 -0
- package/src/tools/schedules/schedule-tool.ts +376 -0
- package/src/tools/schedules/types.ts +197 -0
- package/src/types/authorization/index.ts +60 -2
- package/src/types/browser/index.ts +341 -0
- package/src/types/session/events.ts +6 -0
- package/src/types/session/records.ts +10 -0
- package/src/types/tool/index.ts +42 -0
- package/src/types/tool/presentation.ts +7 -0
- package/src/utils/frontmatter.ts +29 -3
- package/src/utils/id.ts +14 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A schedule in words, for a confirmation screen or a listing.
|
|
3
|
+
*
|
|
4
|
+
* Covers the common shapes exactly and falls back to the expression itself
|
|
5
|
+
* for anything else, rather than paraphrasing it wrongly.
|
|
6
|
+
*/
|
|
7
|
+
import { parseCronExpression } from './cron.js';
|
|
8
|
+
import { formatWall } from './tz.js';
|
|
9
|
+
const MINUTE = 60_000;
|
|
10
|
+
const DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
11
|
+
const MONTH_NAMES = [
|
|
12
|
+
'January',
|
|
13
|
+
'February',
|
|
14
|
+
'March',
|
|
15
|
+
'April',
|
|
16
|
+
'May',
|
|
17
|
+
'June',
|
|
18
|
+
'July',
|
|
19
|
+
'August',
|
|
20
|
+
'September',
|
|
21
|
+
'October',
|
|
22
|
+
'November',
|
|
23
|
+
'December',
|
|
24
|
+
];
|
|
25
|
+
function pad(n) {
|
|
26
|
+
return String(n).padStart(2, '0');
|
|
27
|
+
}
|
|
28
|
+
function plural(n, unit) {
|
|
29
|
+
return `${n} ${unit}${n === 1 ? '' : 's'}`;
|
|
30
|
+
}
|
|
31
|
+
function describeInterval(ms) {
|
|
32
|
+
if (ms % (7 * 24 * 60 * MINUTE) === 0) {
|
|
33
|
+
const w = ms / (7 * 24 * 60 * MINUTE);
|
|
34
|
+
return w === 1 ? 'every week' : `every ${plural(w, 'week')}`;
|
|
35
|
+
}
|
|
36
|
+
if (ms % (24 * 60 * MINUTE) === 0) {
|
|
37
|
+
const d = ms / (24 * 60 * MINUTE);
|
|
38
|
+
return d === 1 ? 'every 24 hours' : `every ${plural(d, 'day')}`;
|
|
39
|
+
}
|
|
40
|
+
if (ms % (60 * MINUTE) === 0) {
|
|
41
|
+
const h = ms / (60 * MINUTE);
|
|
42
|
+
return h === 1 ? 'every hour' : `every ${plural(h, 'hour')}`;
|
|
43
|
+
}
|
|
44
|
+
const m = ms / MINUTE;
|
|
45
|
+
return m === 1 ? 'every minute' : `every ${plural(m, 'minute')}`;
|
|
46
|
+
}
|
|
47
|
+
/** `1,2,3,5` → `1–3, 5`. */
|
|
48
|
+
function ranges(values, name) {
|
|
49
|
+
const out = [];
|
|
50
|
+
let i = 0;
|
|
51
|
+
while (i < values.length) {
|
|
52
|
+
let j = i;
|
|
53
|
+
while (j + 1 < values.length && values[j + 1] === values[j] + 1)
|
|
54
|
+
j++;
|
|
55
|
+
const a = values[i];
|
|
56
|
+
const b = values[j];
|
|
57
|
+
if (j - i >= 2)
|
|
58
|
+
out.push(`${name(a)} through ${name(b)}`);
|
|
59
|
+
else
|
|
60
|
+
for (let k = i; k <= j; k++)
|
|
61
|
+
out.push(name(values[k]));
|
|
62
|
+
i = j + 1;
|
|
63
|
+
}
|
|
64
|
+
return out.join(', ');
|
|
65
|
+
}
|
|
66
|
+
function isFull(values, min, max) {
|
|
67
|
+
return values.length === max - min + 1;
|
|
68
|
+
}
|
|
69
|
+
function describeDays(e) {
|
|
70
|
+
const allDom = !e.domRestricted;
|
|
71
|
+
const allDow = !e.dowRestricted;
|
|
72
|
+
const allMonths = isFull(e.months, 1, 12);
|
|
73
|
+
let days;
|
|
74
|
+
if (allDom && allDow)
|
|
75
|
+
days = 'every day';
|
|
76
|
+
else if (allDom)
|
|
77
|
+
days = `on ${ranges(e.daysOfWeek, (d) => DAY_NAMES[d] ?? String(d))}`;
|
|
78
|
+
else if (allDow)
|
|
79
|
+
days = `on day ${ranges(e.daysOfMonth, String)} of the month`;
|
|
80
|
+
else
|
|
81
|
+
days = `on day ${ranges(e.daysOfMonth, String)} of the month and on ${ranges(e.daysOfWeek, (d) => DAY_NAMES[d] ?? String(d))}`;
|
|
82
|
+
if (!allMonths)
|
|
83
|
+
days += ` in ${ranges(e.months, (m) => MONTH_NAMES[m - 1] ?? String(m))}`;
|
|
84
|
+
return days;
|
|
85
|
+
}
|
|
86
|
+
function describeTimes(e, source) {
|
|
87
|
+
const [mi = '', ho = ''] = source.split(' ');
|
|
88
|
+
const allMinutes = isFull(e.minutes, 0, 59);
|
|
89
|
+
const allHours = isFull(e.hours, 0, 23);
|
|
90
|
+
if (allMinutes && allHours)
|
|
91
|
+
return 'every minute';
|
|
92
|
+
const stepMinute = /^\*\/(\d+)$/.exec(mi);
|
|
93
|
+
if (stepMinute && allHours)
|
|
94
|
+
return `every ${plural(Number(stepMinute[1]), 'minute')}`;
|
|
95
|
+
if (allHours && e.minutes.length <= 4) {
|
|
96
|
+
return e.minutes.length === 1 && e.minutes[0] === 0
|
|
97
|
+
? 'every hour, on the hour'
|
|
98
|
+
: `every hour at minute ${e.minutes.join(', ')}`;
|
|
99
|
+
}
|
|
100
|
+
const stepHour = /^\*\/(\d+)$/.exec(ho);
|
|
101
|
+
if (stepHour && e.minutes.length === 1) {
|
|
102
|
+
return `every ${plural(Number(stepHour[1]), 'hour')} at minute ${e.minutes[0]}`;
|
|
103
|
+
}
|
|
104
|
+
if (e.hours.length * e.minutes.length <= 6) {
|
|
105
|
+
const times = [];
|
|
106
|
+
for (const h of e.hours)
|
|
107
|
+
for (const m of e.minutes)
|
|
108
|
+
times.push(`${pad(h)}:${pad(m)}`);
|
|
109
|
+
return `at ${times.join(', ')}`;
|
|
110
|
+
}
|
|
111
|
+
return `at minute ${ranges(e.minutes, String)} of hour ${ranges(e.hours, String)}`;
|
|
112
|
+
}
|
|
113
|
+
/** The schedule in words: `at 03:00 every day (Europe/Istanbul)`. */
|
|
114
|
+
export function describeSchedule(spec, options = {}) {
|
|
115
|
+
const tz = options.tz ?? 'UTC';
|
|
116
|
+
switch (spec.kind) {
|
|
117
|
+
case 'at':
|
|
118
|
+
return `once at ${formatWall(Date.parse(spec.at), tz)} (${tz})`;
|
|
119
|
+
case 'every':
|
|
120
|
+
return describeInterval(spec.everyMs);
|
|
121
|
+
case 'cron': {
|
|
122
|
+
let e;
|
|
123
|
+
try {
|
|
124
|
+
e = parseCronExpression(spec.expr);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return `cron "${spec.expr}" (${spec.tz})`;
|
|
128
|
+
}
|
|
129
|
+
return `${describeTimes(e, e.source)} ${describeDays(e)} (${spec.tz})`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=describe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../../src/schedules/describe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A schedule, cron expression or time zone that cannot be used.
|
|
3
|
+
*
|
|
4
|
+
* `token` names the piece of the input that was refused, so a caller can
|
|
5
|
+
* point at it instead of repeating the whole expression back.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ScheduleValidationError extends Error {
|
|
8
|
+
readonly token: string | undefined;
|
|
9
|
+
constructor(message: string, token?: string);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/schedules/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;gBAEtB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAK3C"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A schedule, cron expression or time zone that cannot be used.
|
|
3
|
+
*
|
|
4
|
+
* `token` names the piece of the input that was refused, so a caller can
|
|
5
|
+
* point at it instead of repeating the whole expression back.
|
|
6
|
+
*/
|
|
7
|
+
export class ScheduleValidationError extends Error {
|
|
8
|
+
token;
|
|
9
|
+
constructor(message, token) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = 'ScheduleValidationError';
|
|
12
|
+
this.token = token;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/schedules/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACxC,KAAK,CAAoB;IAElC,YAAY,OAAe,EAAE,KAAc;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACnB,CAAC;CACD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What to do about one job now: fire, skip, record a miss, or nothing.
|
|
3
|
+
*
|
|
4
|
+
* Pure: no clock, no I/O. The host passes the instant, the state it kept and
|
|
5
|
+
* whether an occurrence was already claimed, and applies the decision itself
|
|
6
|
+
* (append history, claim, dispatch). Evaluating the same `(state, now)` twice
|
|
7
|
+
* gives the same answer, so a host that lost its in-memory queue rebuilds it
|
|
8
|
+
* by evaluating again; an already-claimed key is never fired twice.
|
|
9
|
+
*
|
|
10
|
+
* Rules, in order:
|
|
11
|
+
*
|
|
12
|
+
* 1. Occurrences due are those in `(lastEvaluatedAt, now]`, counted with a
|
|
13
|
+
* cap and never enumerated. A new job counts from its creation. A changed
|
|
14
|
+
* revision counts from the change, so editing `0 3 * * *` into `0 4 * * *`
|
|
15
|
+
* does not invent catch-ups for 04:00s that never belonged to the job.
|
|
16
|
+
* 2. `lastEvaluatedAt` never moves backwards: after a backward clock jump
|
|
17
|
+
* nothing is due until the wall clock passes it again.
|
|
18
|
+
* 3. A job that is not active produces skip records only (paused and
|
|
19
|
+
* awaiting-confirmation are collapsed per evaluation). A one-shot whose
|
|
20
|
+
* time passed while inactive is expired.
|
|
21
|
+
* 4. The latest due occurrence fires on time (`scheduled`, or `late` once
|
|
22
|
+
* more than five seconds late) within the late grace; within the catch-up
|
|
23
|
+
* window it fires once as `catch-up` and everything earlier is one
|
|
24
|
+
* `missed` record; older than the window, nothing fires.
|
|
25
|
+
* 5. An unfinished run of the same job skips what came due meanwhile.
|
|
26
|
+
* 6. A provider quota hold skips what comes due before the hold ends.
|
|
27
|
+
*/
|
|
28
|
+
import type { ScheduleDecision, ScheduleEvaluationInput } from './types.js';
|
|
29
|
+
/** Default catch-up window: seven days. */
|
|
30
|
+
export declare const SCHEDULE_CATCH_UP_WINDOW_MS: number;
|
|
31
|
+
/** Default grace for a fire to still count as on time: two minutes. */
|
|
32
|
+
export declare const SCHEDULE_LATE_GRACE_MS = 120000;
|
|
33
|
+
/** Evaluate one job at `now`. */
|
|
34
|
+
export declare function evaluateJob(input: ScheduleEvaluationInput): ScheduleDecision;
|
|
35
|
+
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/schedules/evaluate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EACX,gBAAgB,EAChB,uBAAuB,EAGvB,MAAM,YAAY,CAAA;AAEnB,2CAA2C;AAC3C,eAAO,MAAM,2BAA2B,QAA0B,CAAA;AAClE,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,SAAU,CAAA;AAe7C,iCAAiC;AACjC,wBAAgB,WAAW,CAAC,KAAK,EAAE,uBAAuB,GAAG,gBAAgB,CA0H5E"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What to do about one job now: fire, skip, record a miss, or nothing.
|
|
3
|
+
*
|
|
4
|
+
* Pure: no clock, no I/O. The host passes the instant, the state it kept and
|
|
5
|
+
* whether an occurrence was already claimed, and applies the decision itself
|
|
6
|
+
* (append history, claim, dispatch). Evaluating the same `(state, now)` twice
|
|
7
|
+
* gives the same answer, so a host that lost its in-memory queue rebuilds it
|
|
8
|
+
* by evaluating again; an already-claimed key is never fired twice.
|
|
9
|
+
*
|
|
10
|
+
* Rules, in order:
|
|
11
|
+
*
|
|
12
|
+
* 1. Occurrences due are those in `(lastEvaluatedAt, now]`, counted with a
|
|
13
|
+
* cap and never enumerated. A new job counts from its creation. A changed
|
|
14
|
+
* revision counts from the change, so editing `0 3 * * *` into `0 4 * * *`
|
|
15
|
+
* does not invent catch-ups for 04:00s that never belonged to the job.
|
|
16
|
+
* 2. `lastEvaluatedAt` never moves backwards: after a backward clock jump
|
|
17
|
+
* nothing is due until the wall clock passes it again.
|
|
18
|
+
* 3. A job that is not active produces skip records only (paused and
|
|
19
|
+
* awaiting-confirmation are collapsed per evaluation). A one-shot whose
|
|
20
|
+
* time passed while inactive is expired.
|
|
21
|
+
* 4. The latest due occurrence fires on time (`scheduled`, or `late` once
|
|
22
|
+
* more than five seconds late) within the late grace; within the catch-up
|
|
23
|
+
* window it fires once as `catch-up` and everything earlier is one
|
|
24
|
+
* `missed` record; older than the window, nothing fires.
|
|
25
|
+
* 5. An unfinished run of the same job skips what came due meanwhile.
|
|
26
|
+
* 6. A provider quota hold skips what comes due before the hold ends.
|
|
27
|
+
*/
|
|
28
|
+
import { countOccurrences, nextFireTime, previousFireTime } from './next-fire.js';
|
|
29
|
+
/** Default catch-up window: seven days. */
|
|
30
|
+
export const SCHEDULE_CATCH_UP_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
|
|
31
|
+
/** Default grace for a fire to still count as on time: two minutes. */
|
|
32
|
+
export const SCHEDULE_LATE_GRACE_MS = 120_000;
|
|
33
|
+
/** A fire later than this is reported `late` rather than `scheduled`. */
|
|
34
|
+
const LATE_THRESHOLD_MS = 5_000;
|
|
35
|
+
function missedReason(input, firstMissed) {
|
|
36
|
+
const gap = input.daemon.observedGap;
|
|
37
|
+
if (gap && firstMissed.getTime() >= gap.from.getTime()) {
|
|
38
|
+
if (gap.kind === 'asleep')
|
|
39
|
+
return 'machine-asleep';
|
|
40
|
+
if (gap.kind === 'clock-forward')
|
|
41
|
+
return 'clock-jumped-forward';
|
|
42
|
+
}
|
|
43
|
+
return 'daemon-not-running';
|
|
44
|
+
}
|
|
45
|
+
/** Evaluate one job at `now`. */
|
|
46
|
+
export function evaluateJob(input) {
|
|
47
|
+
const { job, state, now } = input;
|
|
48
|
+
const nowMs = now.getTime();
|
|
49
|
+
const lateGrace = input.lateGraceMs ?? SCHEDULE_LATE_GRACE_MS;
|
|
50
|
+
const windowMs = job.catchUp?.windowMs ?? SCHEDULE_CATCH_UP_WINDOW_MS;
|
|
51
|
+
let baseMs = Date.parse(state.lastEvaluatedAt ?? job.createdAt);
|
|
52
|
+
if (!Number.isFinite(baseMs))
|
|
53
|
+
baseMs = Date.parse(job.createdAt);
|
|
54
|
+
if (state.jobRevision !== undefined && state.jobRevision !== job.revision) {
|
|
55
|
+
baseMs = Math.max(baseMs, Date.parse(job.updatedAt));
|
|
56
|
+
}
|
|
57
|
+
const nextState = (evaluatedMs) => {
|
|
58
|
+
const next = nextFireTime(job.spec, new Date(evaluatedMs));
|
|
59
|
+
return {
|
|
60
|
+
lastEvaluatedAt: new Date(evaluatedMs),
|
|
61
|
+
...(next ? { nextFireAt: next } : {}),
|
|
62
|
+
jobRevision: job.revision,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
if (job.state === 'completed' || job.state === 'expired') {
|
|
66
|
+
return {
|
|
67
|
+
skip: [],
|
|
68
|
+
nextState: { lastEvaluatedAt: new Date(Math.max(baseMs, nowMs)), jobRevision: job.revision },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Rule 2: a clock that went backwards decides nothing new.
|
|
72
|
+
if (nowMs <= baseMs)
|
|
73
|
+
return { skip: [], nextState: nextState(baseMs) };
|
|
74
|
+
const due = countOccurrences(job.spec, new Date(baseMs), now);
|
|
75
|
+
if (due.count === 0 || !due.latest) {
|
|
76
|
+
if (job.spec.kind === 'at' && Date.parse(job.spec.at) <= baseMs && job.state !== 'active') {
|
|
77
|
+
return { skip: [], jobTransition: 'expired', nextState: nextState(nowMs) };
|
|
78
|
+
}
|
|
79
|
+
return { skip: [], nextState: nextState(nowMs) };
|
|
80
|
+
}
|
|
81
|
+
const latest = due.latest;
|
|
82
|
+
const collapsed = (reason) => [
|
|
83
|
+
{ scheduledFor: latest, reason, count: due.count },
|
|
84
|
+
];
|
|
85
|
+
if (job.state === 'paused' || job.state === 'pending-confirmation') {
|
|
86
|
+
const reason = job.state === 'paused' ? 'paused' : 'awaiting-confirmation';
|
|
87
|
+
return {
|
|
88
|
+
skip: collapsed(reason),
|
|
89
|
+
...(job.spec.kind === 'at' ? { jobTransition: 'expired' } : {}),
|
|
90
|
+
nextState: nextState(nowMs),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const hold = state.quotaHoldUntil ? Date.parse(state.quotaHoldUntil) : Number.NaN;
|
|
94
|
+
if (Number.isFinite(hold) && hold > nowMs) {
|
|
95
|
+
return { skip: collapsed('quota-hold'), nextState: nextState(nowMs) };
|
|
96
|
+
}
|
|
97
|
+
if (state.activeRun) {
|
|
98
|
+
return {
|
|
99
|
+
skip: collapsed(state.activeRun.status === 'awaiting-approval'
|
|
100
|
+
? 'previous-run-awaiting-approval'
|
|
101
|
+
: 'previous-run-active'),
|
|
102
|
+
nextState: nextState(nowMs),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const key = String(latest.getTime());
|
|
106
|
+
const lateBy = nowMs - latest.getTime();
|
|
107
|
+
const earlier = due.count - 1;
|
|
108
|
+
const missedBefore = () => {
|
|
109
|
+
if (earlier <= 0 || !due.first)
|
|
110
|
+
return undefined;
|
|
111
|
+
// The occurrence just before the fired one.
|
|
112
|
+
const to = previousFireTime(job.spec, new Date(latest.getTime() - 1)) ?? due.first;
|
|
113
|
+
return {
|
|
114
|
+
from: due.first,
|
|
115
|
+
to,
|
|
116
|
+
count: earlier,
|
|
117
|
+
capped: due.capped,
|
|
118
|
+
reason: missedReason(input, due.first),
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
const transition = job.spec.kind === 'at' ? { jobTransition: 'completed' } : {};
|
|
122
|
+
if (input.isClaimed?.(key)) {
|
|
123
|
+
// Somebody already started it; nothing to fire, nothing missed.
|
|
124
|
+
return { skip: [], ...transition, nextState: nextState(nowMs) };
|
|
125
|
+
}
|
|
126
|
+
if (lateBy <= lateGrace || lateBy <= windowMs) {
|
|
127
|
+
const trigger = lateBy <= lateGrace ? (lateBy > LATE_THRESHOLD_MS ? 'late' : 'scheduled') : 'catch-up';
|
|
128
|
+
const missed = missedBefore();
|
|
129
|
+
return {
|
|
130
|
+
fire: { key, scheduledFor: latest, trigger },
|
|
131
|
+
skip: [],
|
|
132
|
+
...(missed ? { missed } : {}),
|
|
133
|
+
...transition,
|
|
134
|
+
nextState: nextState(nowMs),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Everything due is older than the window.
|
|
138
|
+
const first = due.first ?? latest;
|
|
139
|
+
return {
|
|
140
|
+
skip: [
|
|
141
|
+
{
|
|
142
|
+
scheduledFor: latest,
|
|
143
|
+
reason: job.spec.kind === 'at' ? 'one-shot-expired' : 'beyond-catch-up-window',
|
|
144
|
+
count: 1,
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
missed: {
|
|
148
|
+
from: first,
|
|
149
|
+
to: latest,
|
|
150
|
+
count: due.count,
|
|
151
|
+
capped: due.capped,
|
|
152
|
+
reason: missedReason(input, first),
|
|
153
|
+
},
|
|
154
|
+
...(job.spec.kind === 'at' ? { jobTransition: 'expired' } : {}),
|
|
155
|
+
nextState: nextState(nowMs),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=evaluate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/schedules/evaluate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { parseCronExpression } from './cron.js';
|
|
2
|
+
export { describeSchedule } from './describe.js';
|
|
3
|
+
export type { DescribeScheduleOptions } from './describe.js';
|
|
4
|
+
export { ScheduleValidationError } from './errors.js';
|
|
5
|
+
export { SCHEDULE_CATCH_UP_WINDOW_MS, SCHEDULE_LATE_GRACE_MS, evaluateJob, } from './evaluate.js';
|
|
6
|
+
export { countOccurrences, nextFireTime, previousFireTime, } from './next-fire.js';
|
|
7
|
+
export { parseDuration, parseScheduleSpec, upcomingFireTimes } from './spec.js';
|
|
8
|
+
export type { ParseScheduleOptions } from './spec.js';
|
|
9
|
+
export { hostTimeZone, validateTimeZone } from './tz.js';
|
|
10
|
+
export type * from './types.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schedules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,YAAY,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,WAAW,GACX,MAAM,eAAe,CAAA;AACtB,OAAO,EACN,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,GAChB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC/E,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AACxD,mBAAmB,YAAY,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { parseCronExpression } from './cron.js';
|
|
2
|
+
export { describeSchedule } from './describe.js';
|
|
3
|
+
export { ScheduleValidationError } from './errors.js';
|
|
4
|
+
export { SCHEDULE_CATCH_UP_WINDOW_MS, SCHEDULE_LATE_GRACE_MS, evaluateJob, } from './evaluate.js';
|
|
5
|
+
export { countOccurrences, nextFireTime, previousFireTime, } from './next-fire.js';
|
|
6
|
+
export { parseDuration, parseScheduleSpec, upcomingFireTimes } from './spec.js';
|
|
7
|
+
export { hostTimeZone, validateTimeZone } from './tz.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schedules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,WAAW,GACX,MAAM,eAAe,CAAA;AACtB,OAAO,EACN,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,GAChB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAE/E,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When a spec fires: the next instant, the previous one, and how many fall
|
|
3
|
+
* in a window.
|
|
4
|
+
*
|
|
5
|
+
* Cron is walked a local DAY at a time — never a minute at a time over years
|
|
6
|
+
* — and a day with no DST change is computed arithmetically from one offset.
|
|
7
|
+
* Only a day whose offset changes is examined slot by slot, and that is where
|
|
8
|
+
* cronie's rule is applied:
|
|
9
|
+
*
|
|
10
|
+
* - a fixed-time expression (`30 2 * * *`) whose time falls in a
|
|
11
|
+
* spring-forward gap fires once, at the first instant after the gap;
|
|
12
|
+
* whose time is repeated by a fall-back fires once, at the first of the two;
|
|
13
|
+
* - a wildcard or step expression (`0 * * * *`, `*\/15 * * * *`) fires at
|
|
14
|
+
* every instant whose wall time matches: the repeated hour runs twice and
|
|
15
|
+
* slots inside the gap do not exist.
|
|
16
|
+
*/
|
|
17
|
+
import type { CronExpression, OccurrenceCount, ScheduleSpec } from './types.js';
|
|
18
|
+
/** How far ahead a cron search looks before deciding the expression never fires. */
|
|
19
|
+
export declare const CRON_HORIZON_DAYS: number;
|
|
20
|
+
/**
|
|
21
|
+
* Occurrence counts stop here. Counting a day without a DST change costs one
|
|
22
|
+
* multiplication, so the cap bounds the pathological case (a years-long gap
|
|
23
|
+
* on a per-minute job) rather than the ordinary one.
|
|
24
|
+
*/
|
|
25
|
+
export declare const OCCURRENCE_COUNT_CAP = 100000;
|
|
26
|
+
/**
|
|
27
|
+
* Every instant the expression fires on one local day (`dayWall` is that
|
|
28
|
+
* day's midnight as a wall value), ascending.
|
|
29
|
+
*/
|
|
30
|
+
export declare function cronInstantsOnDay(expr: CronExpression, tz: string, dayWall: number): number[];
|
|
31
|
+
/**
|
|
32
|
+
* The first instant strictly after `afterExclusive` at which `spec` fires,
|
|
33
|
+
* or `null` when there is none (a past `at`, or a cron expression with no
|
|
34
|
+
* occurrence in the next five years).
|
|
35
|
+
*/
|
|
36
|
+
export declare function nextFireTime(spec: ScheduleSpec, afterExclusive: Date): Date | null;
|
|
37
|
+
/**
|
|
38
|
+
* The last instant at or before `atOrBefore` at which `spec` fired, or
|
|
39
|
+
* `null` if none within the horizon (or before the anchor / the `at`).
|
|
40
|
+
*/
|
|
41
|
+
export declare function previousFireTime(spec: ScheduleSpec, atOrBefore: Date): Date | null;
|
|
42
|
+
/**
|
|
43
|
+
* How many times `spec` fires in `(fromExclusive, toInclusive]`, with the
|
|
44
|
+
* first and latest of them. Stops counting at `cap` (default 100 000) and
|
|
45
|
+
* says so, without enumerating beyond it; the latest is exact either way.
|
|
46
|
+
*/
|
|
47
|
+
export declare function countOccurrences(spec: ScheduleSpec, fromExclusive: Date, toInclusive: Date, cap?: number): OccurrenceCount;
|
|
48
|
+
/** Validate a spec as a whole: its zone, its expression, and that it can ever fire after `now`. */
|
|
49
|
+
export declare function assertSpecFires(spec: ScheduleSpec, now: Date): void;
|
|
50
|
+
//# sourceMappingURL=next-fire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-fire.d.ts","sourceRoot":"","sources":["../../src/schedules/next-fire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAM/E,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,QAAc,CAAA;AAC5C;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,SAAU,CAAA;AAmB3C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAoC7F;AAgBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,cAAc,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAwBlF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CA0BlF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,YAAY,EAClB,aAAa,EAAE,IAAI,EACnB,WAAW,EAAE,IAAI,EACjB,GAAG,GAAE,MAA6B,GAChC,eAAe,CA4DjB;AAED,mGAAmG;AACnG,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAanE"}
|