From 55364835e98f18e620d87c641effb6632ceb8306 Mon Sep 17 00:00:00 2001 From: Dotta Date: Tue, 28 Apr 2026 07:21:31 -0500 Subject: [PATCH] Add {{timestamp}} built-in routine variable Renders as a human-readable date and time in UTC (e.g. "April 28, 2026 at 12:17 PM UTC"), complementing the existing {{date}} variable. Co-Authored-By: Paperclip --- packages/shared/src/routine-variables.test.ts | 18 ++++++++++++++---- packages/shared/src/routine-variables.ts | 18 ++++++++++++++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/packages/shared/src/routine-variables.test.ts b/packages/shared/src/routine-variables.test.ts index a079ae62185..a129ee489aa 100644 --- a/packages/shared/src/routine-variables.test.ts +++ b/packages/shared/src/routine-variables.test.ts @@ -46,8 +46,10 @@ describe("routine variable helpers", () => { it("identifies built-in variable names", () => { expect(isBuiltinRoutineVariable("date")).toBe(true); + expect(isBuiltinRoutineVariable("timestamp")).toBe(true); expect(isBuiltinRoutineVariable("repo")).toBe(false); expect(BUILTIN_ROUTINE_VARIABLE_NAMES.has("date")).toBe(true); + expect(BUILTIN_ROUTINE_VARIABLE_NAMES.has("timestamp")).toBe(true); }); it("getBuiltinRoutineVariableValues returns date in YYYY-MM-DD format", () => { @@ -56,9 +58,17 @@ describe("routine variable helpers", () => { expect(values.date).toBe(new Date().toISOString().slice(0, 10)); }); + it("getBuiltinRoutineVariableValues returns a human-readable timestamp with year, time, and UTC", () => { + const values = getBuiltinRoutineVariableValues(); + const year = String(new Date().getUTCFullYear()); + expect(values.timestamp).toContain(year); + expect(values.timestamp).toMatch(/\d{1,2}:\d{2}\s?(AM|PM)/); + expect(values.timestamp).toContain("UTC"); + }); + it("excludes built-in variables from syncRoutineVariablesWithTemplate", () => { const result = syncRoutineVariablesWithTemplate( - "Daily report for {{date}} — {{repo}}", + "Daily report for {{date}} at {{timestamp}} — {{repo}}", [], ); expect(result).toEqual([ @@ -66,11 +76,11 @@ describe("routine variable helpers", () => { ]); }); - it("interpolates built-in date variable alongside user variables", () => { + it("interpolates built-in variables alongside user variables", () => { const builtins = getBuiltinRoutineVariableValues(); const allVars = { ...builtins, repo: "paperclip" }; expect( - interpolateRoutineTemplate("Report for {{date}} on {{repo}}", allVars), - ).toBe(`Report for ${builtins.date} on paperclip`); + interpolateRoutineTemplate("Report for {{date}} ({{timestamp}}) on {{repo}}", allVars), + ).toBe(`Report for ${builtins.date} (${builtins.timestamp}) on paperclip`); }); }); diff --git a/packages/shared/src/routine-variables.ts b/packages/shared/src/routine-variables.ts index 610af48107f..b83148d46d5 100644 --- a/packages/shared/src/routine-variables.ts +++ b/packages/shared/src/routine-variables.ts @@ -7,19 +7,33 @@ type RoutineTemplateInput = string | null | undefined | Array { + const now = new Date(); return { - date: new Date().toISOString().slice(0, 10), + date: now.toISOString().slice(0, 10), + timestamp: HUMAN_TIMESTAMP_FORMATTER.format(now), }; }