Scheduled and loop agents get workspaces; schedules UI speaks the user's timezone (#1909)
* fix(app): schedules UI speaks the user's timezone * refactor(server): require explicit agent placement and bind create-agent command * fix(server): scheduled agents get a workspace and show in the sidebar * fix(server): loop agents get a workspace and show in the sidebar * fix(server): preserve scheduled and loop run semantics through the create command * fix(server): serialize all schedule record writes through the per-schedule queue * fix(server): tighten create-agent dependency contracts * fix(server): handle schedule restamps and loop cancellations * fix(server): preserve scheduled and loop create semantics * refactor(server): schedule store owns atomic mutations * fix(server): keep schedule stamp reuse deterministic * fix(server): handle loop workspace stamp rejection * refactor(server): schedule store owns typed identity upsert * fix(server): keep schedule workspace stamps server-owned * fix(server): preserve scheduled run semantics * refactor: required nullable workspaceId replaces placement union; pure cadence policy * fix(server): tighten scheduled and loop agent edges * fix(server): fail canceled scheduled runs * fix(server): close schedule and loop cwd edges * fix(server): refresh schedule workspace stamps * fix(server): preserve schedule timezone on replace * fix(server): close loop stop and cadence reset edges
This commit is contained in:
@@ -85,17 +85,38 @@ describe("interval formatting", () => {
|
||||
|
||||
describe("describeCron", () => {
|
||||
it("humanizes common fixed-time cron shapes", () => {
|
||||
expect(describeCron("0 * * * *")).toBe("Every hour");
|
||||
expect(describeCron("15 * * * *")).toBe("Every hour at :15");
|
||||
expect(describeCron("0 9 * * *")).toBe("Daily at 09:00 UTC");
|
||||
expect(describeCron("0 9 * * 1-5")).toBe("Weekdays at 09:00 UTC");
|
||||
expect(describeCron("0 9 * * 0,6")).toBe("Weekends at 09:00 UTC");
|
||||
expect(describeCron("0 9 * * 1")).toBe("Mondays at 09:00 UTC");
|
||||
expect(describeCron({ type: "cron", expression: "0 * * * *" })).toBe("Every hour");
|
||||
expect(describeCron({ type: "cron", expression: "15 * * * *" })).toBe("Every hour at :15");
|
||||
expect(describeCron({ type: "cron", expression: "0 9 * * *" })).toBe("Daily at 09:00 UTC");
|
||||
expect(describeCron({ type: "cron", expression: "0 9 * * 1-5" })).toBe("Weekdays at 09:00 UTC");
|
||||
expect(describeCron({ type: "cron", expression: "0 9 * * 0,6" })).toBe("Weekends at 09:00 UTC");
|
||||
expect(describeCron({ type: "cron", expression: "0 9 * * 1" })).toBe("Mondays at 09:00 UTC");
|
||||
});
|
||||
|
||||
it("labels fixed-time cron cadences with their stored timezone", () => {
|
||||
expect(
|
||||
describeCron({
|
||||
type: "cron",
|
||||
expression: "0 9 * * *",
|
||||
timezone: "America/New_York",
|
||||
}),
|
||||
).toBe("Daily at 09:00 America/New_York");
|
||||
expect(
|
||||
formatCadence({
|
||||
type: "cron",
|
||||
expression: "0 9 * * 1-5",
|
||||
timezone: "Europe/Madrid",
|
||||
}),
|
||||
).toBe("Weekdays at 09:00 Europe/Madrid");
|
||||
});
|
||||
|
||||
it("keeps timezone-less fixed-time cron cadences labeled as UTC", () => {
|
||||
expect(formatCadence({ type: "cron", expression: "0 9 * * *" })).toBe("Daily at 09:00 UTC");
|
||||
});
|
||||
|
||||
it("returns null for invalid or unrecognized valid cron expressions", () => {
|
||||
expect(describeCron("not a cron")).toBeNull();
|
||||
expect(describeCron("*/5 * * * *")).toBeNull();
|
||||
expect(describeCron({ type: "cron", expression: "not a cron" })).toBeNull();
|
||||
expect(describeCron({ type: "cron", expression: "*/5 * * * *" })).toBeNull();
|
||||
expect(formatCadence({ type: "cron", expression: "0 9 * * *" })).toBe("Daily at 09:00 UTC");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user