




















@@ -1,5 +1,5 @@
11import { Command } from "commander";
2-import { describe, expect, it, vi } from "vitest";
2+import { afterEach, describe, expect, it, vi } from "vitest";
33import type { CronJob } from "../cron/types.js";
44import { registerCronCli } from "./cron-cli.js";
55@@ -39,6 +39,10 @@ const defaultGatewayMock = async (
3939};
4040callGatewayFromCli.mockImplementation(defaultGatewayMock);
414142+afterEach(() => {
43+vi.useRealTimers();
44+});
45+4246vi.mock("./gateway-rpc.js", async () => {
4347const actual = await vi.importActual<typeof import("./gateway-rpc.js")>("./gateway-rpc.js");
4448return {
@@ -75,7 +79,7 @@ type CronUpdatePatch = {
7579};
76807781type CronAddParams = {
78-schedule?: { kind?: string; staggerMs?: number };
82+schedule?: { kind?: string; at?: string; staggerMs?: number };
7983payload?: {
8084model?: string;
8185thinking?: string;
@@ -316,16 +320,7 @@ describe("cron cli", () => {
316320enqueued: true,
317321runId: "manual:job-1:123:0",
318322runStatus: status,
319-args: [
320-"cron",
321-"run",
322-"job-1",
323-"--wait",
324-"--wait-timeout",
325-"1s",
326-"--poll-interval",
327-"1ms",
328-],
323+args: ["cron", "run", "job-1", "--wait", "--wait-timeout", "1s", "--poll-interval", "1ms"],
329324});
330325331326expect(exitSpy).toHaveBeenCalledWith(expectedExitCode);
@@ -457,6 +452,24 @@ describe("cron cli", () => {
457452expect(params?.deleteAfterRun).toBe(false);
458453});
459454455+it("accepts leading plus relative durations for cron add --at", async () => {
456+vi.useFakeTimers();
457+vi.setSystemTime(new Date("2026-05-25T00:00:00.000Z"));
458+459+const params = await runCronAddAndGetParams([
460+"--name",
461+"Plus duration",
462+"--at",
463+"+30m",
464+"--session",
465+"main",
466+"--system-event",
467+"hello",
468+]);
469+470+expect(params?.schedule).toEqual({ kind: "at", at: "2026-05-25T00:30:00.000Z" });
471+});
472+460473it("includes --account on isolated cron add delivery", async () => {
461474const params = await runCronAddAndGetParams([
462475"--name",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。