Add bot schedules (routines), open Activity, add Help and a Desktop computer view

Bots create, list, update and delete schedules (cron_jobs, Bun.cron in UTC);
a per-minute cron queues due runs as tasks. Routines, Activity (super admins)
and Help get their own rail aside. Help covers familiar problems, starting
with signing in to Google through Cookie-Editor over the new Desktop (noVNC)
view.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-19 10:52:32 +01:00
co-authored by Claude Opus 5.5
parent f24c0d7e82
commit c44048dbab
62 changed files with 1904 additions and 78 deletions
+25
View File
@@ -0,0 +1,25 @@
import { describe, expect, test } from "bun:test";
import nextCronRun from "./next-cron-run";
const from = Date.UTC(2026, 9, 19, 8, 30);
describe("nextCronRun", () => {
test("finds the next run in UTC", () => {
expect(nextCronRun({ schedule: "0 9 * * *", from })).toBe(Date.UTC(2026, 9, 19, 9, 0));
expect(nextCronRun({ schedule: "@daily", from })).toBe(Date.UTC(2026, 9, 20, 0, 0));
});
test("is null when the schedule never runs", () => {
expect(nextCronRun({ schedule: "0 0 30 2 *", from })).toBeNull();
});
test("rejects invalid expressions", () => {
expect(() => nextCronRun({ schedule: "every morning", from })).toThrow("isn't a valid schedule");
});
test("rejects schedules that run too often when asked", () => {
expect(() => nextCronRun({ schedule: "* * * * *", from, check_interval: true })).toThrow("runs too often");
expect(nextCronRun({ schedule: "* * * * *", from })).toBe(Date.UTC(2026, 9, 19, 8, 31));
expect(nextCronRun({ schedule: "*/15 * * * *", from, check_interval: true })).toBe(Date.UTC(2026, 9, 19, 8, 45));
});
});