* feat: show routines the bot sets up from chat as one quiet line
When someone mentions something recurring in passing ("every Sunday I plan the
week"), the bot now creates the routine right away and the conversation shows a
single line with the schedule, Edit and Undo, on web and mobile.
- New `event` message block for routine lines, kept in history so later turns
know what was set up or removed.
- schedule_create reuses an active repeating routine of the same name instead
of adding a duplicate, caps a bot at 50 active schedules, and falls back to
default times when none was given.
- Removing a routine (Undo, the editor, or schedule_cancel) marks its lines
removed via the new routines.noticeMessageId column.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UmSCnoCgXqBp2fU3vwz4o1
* test: give the routine notice test a complete job publisher
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UmSCnoCgXqBp2fU3vwz4o1
---------
Co-authored-by: Claude <noreply@anthropic.com>
36 lines
1.6 KiB
TypeScript
36 lines
1.6 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { routineLineSchedule } from "./routine-line";
|
|
|
|
// The macros compile at build time; here the English source comes back with its values filled in.
|
|
vi.mock("@lingui/core/macro", () => ({
|
|
t: (parts: TemplateStringsArray, ...values: unknown[]) =>
|
|
parts.reduce((out, part, index) => `${out}${String(values[index - 1])}${part}`),
|
|
}));
|
|
|
|
const at = (crons: string[], nextRunAt: string | null = null) => ({
|
|
crons,
|
|
nextRunAt,
|
|
timezone: "Europe/Berlin",
|
|
});
|
|
|
|
describe("routineLineSchedule", () => {
|
|
it("words the common schedules with the locale's clock", () => {
|
|
expect(routineLineSchedule(at(["0 18 * * 0"]), "de-DE")).toBe("Every Sonntag, 18:00");
|
|
expect(routineLineSchedule(at(["0 18 * * 0"]), "en-US")).toBe("Every Sunday, 6:00 PM");
|
|
expect(routineLineSchedule(at(["30 7 * * *"]), "en-US")).toBe("Daily, 7:30 AM");
|
|
expect(routineLineSchedule(at(["0 8 * * 1-5"]), "de-DE")).toBe("Weekdays, 8:00");
|
|
expect(routineLineSchedule(at(["0 9 1 * *"]), "en-US")).toBe("Monthly on day 1, 9:00 AM");
|
|
expect(routineLineSchedule(at(["*/30 * * * *"]), "en-US")).toBe("Every 30 min");
|
|
});
|
|
|
|
it("shows a reminder's time in the routine's zone, and the next run for other schedules", () => {
|
|
expect(routineLineSchedule(at(["@once"], "2026-10-05T07:00:00.000Z"), "de-DE")).toBe(
|
|
"Mo., 5. Okt., 9:00",
|
|
);
|
|
expect(routineLineSchedule(at(["0 9 * * 1,3"], "2026-10-05T07:00:00.000Z"), "en-US")).toBe(
|
|
"Next Mon, Oct 5, 9:00 AM",
|
|
);
|
|
expect(routineLineSchedule(at(["0 9 * * 1,3"]), "en-US")).toBe("");
|
|
});
|
|
});
|