import type { ScheduledTask, ParsedSchedule, ScheduleExecutionPosition } from '../types.js'; export declare function setExecuteCallback(cb: (task: ScheduledTask) => Promise): void; /** * Bind the scheduler to a specific bot (larkAppId). In multi-bot setups every * daemon process runs its own scheduler; this filter prevents double-execution * by ensuring each task is only handled by the daemon whose bot is actually * a member of the task's origin chat. * * @param larkAppId — this daemon's bot app id * @param isPrimary — true only for bot-0; legacy tasks without larkAppId are * routed here as a compatibility fallback */ export declare function setOwnerFilter(larkAppId: string, isPrimary: boolean): void; /** Public ownership check — used by dashboard IPC to filter list-by-owner. */ export declare function belongsToOwner(task: ScheduledTask): boolean; /** * Parse a bare schedule string (no prompt). Supports: * - Chinese NL: "每日17:50" / "每周一10:00" / "30分钟后" / "明天9:00" * - English duration: "30m", "2h", "1d" (one-shot from now) * - English interval: "every 30m", "every 2h" * - Cron expression: "0 9 * * *" (5 space-separated fields) * - ISO timestamp: "2026-05-01T10:00:00" (one-shot at time) */ export declare function parseSchedule(input: string): ParsedSchedule; interface ParseNLResult { parsed: ParsedSchedule; prompt: string; name: string; } /** * Parse a natural-language /schedule command, splitting the schedule portion * from the prompt (the task instruction). Used by the /schedule command * handler where user types e.g. "/schedule 每日17:50 帮我看看AI新闻". */ export declare function parseNaturalSchedule(input: string): ParseNLResult | null; /** Backward-compatible parser; `deliver:new-topic` means a routing modifier * was present. New callers should also read extractScheduleModifiers.position. */ export declare function extractDeliveryMode(prompt: string): { deliver: 'origin' | 'new-topic'; prompt: string; }; /** * Detect a leading "silent" keyword in a /schedule prompt and strip it. Lets * users write `/schedule 每30分钟 静默 检查服务,挂了才报警` so fires post no * "🕐 task started" banner and the model decides whether to `botmux send`. * The keyword must be followed by whitespace/punctuation — a prompt that * merely *starts with* 静默 as part of a longer word (静默模式…) is left * untouched only when nothing separates it, so document the spaced form. */ export declare function extractSilentMode(prompt: string): { silent: boolean; prompt: string; }; /** * Extract both /schedule prompt modifiers regardless of their order. * `deliver:new-topic` remains a compatibility token indicating that a position * modifier was present. `executionPosition` carries the unambiguous modern * value: group top level or a fresh topic on every run. */ export declare function extractScheduleModifiers(prompt: string): { deliver: 'origin' | 'new-topic'; executionPosition?: Extract; silent: boolean; prompt: string; }; /** Compute the next run time for a parsed schedule. Returns ISO string, or null if exhausted. */ export declare function computeNextRun(parsed: ParsedSchedule, lastRunAt?: string): string | null; /** * Plan which enabled CRON tasks need their `nextRunAt` recomputed after the * effective schedule timezone changed. CRON is the only tz-dependent kind * (wall-clock); `interval` is a relative period and `once` is a fixed instant, * so both are skipped. `computeNextRun()` returns the next FUTURE occurrence, * so applying these updates never causes an immediate or duplicate fire. * Pure (no store writes) → unit-testable; tick() applies the returned plan. */ export declare function planCronRealign(tasks: ScheduledTask[], belongs?: (t: ScheduledTask) => boolean): Array<{ id: string; nextRunAt: string; }>; export declare function startScheduler(): void; export declare function stopScheduler(): void; export declare function addTask(params: { name: string; schedule: string; prompt: string; workingDir: string; chatId: string; rootMessageId?: string; scope?: 'thread' | 'chat'; executionPosition?: ScheduleExecutionPosition; topicTitle?: string; chatType?: 'group' | 'p2p' | 'topic_group'; larkAppId?: string; creatorChatId?: string; creatorRootMessageId?: string; creatorLarkAppId?: string; parsed?: ParsedSchedule; repeat?: { times: number | null; completed: number; }; deliver?: 'origin' | 'local' | 'new-topic'; silent?: boolean; }): ScheduledTask; export declare function normalizeTopicTitle(value: string | undefined): string | undefined; export declare function resolveTaskExecutionPosition(task: Pick): ScheduleExecutionPosition; export declare function removeTask(id: string): boolean; export declare function enableTask(id: string): boolean; export declare function disableTask(id: string): boolean; export declare function runTaskNow(id: string): boolean; export declare function getNextRun(id: string): Date | null; /** * Fire a scheduled task immediately. Returns ok=false if id not found or the * scheduler hasn't been initialised with an executeCallback yet. Emits a * `schedule.fired` event on completion (success or error). */ export declare function runNow(id: string): { ok: boolean; error?: string; }; /** * Toggle a task's `enabled` flag and persist. When enabling a task we also * recompute `nextRunAt` so the next tick can pick it up. Emits a * `schedule.updated` event. */ export declare function setEnabled(id: string, enabled: boolean): { ok: boolean; error?: string; }; /** * Cycle a task's execution position: retained topic → group top level → fresh * topic per run → retained topic (or group top level when no root is retained). * Silent tasks skip the fresh-topic state because that state needs a visible * seed message. The `deliver` response remains for cached clients. */ export declare function toggleDelivery(id: string): { ok: boolean; error?: string; deliver?: 'origin' | 'new-topic'; executionPosition?: ScheduleExecutionPosition; }; /** * Update editable fields of a scheduled task (name, prompt, schedule, silent, * execution position and retained topic root). * Re-parses the schedule expression and recomputes nextRunAt when the schedule * string changes. A legacy `deliver` input is accepted and normalized to * `origin` for normal writes. Legacy `deliver:new-topic` still maps to the * explicit fresh-topic position for cached clients. * Emits a `schedule.updated` event so the dashboard reflects changes live. */ export declare function updateTask(id: string, updates: { name?: string; prompt?: string; schedule?: string; deliver?: 'origin' | 'new-topic'; silent?: boolean; executionPosition?: ScheduleExecutionPosition; rootMessageId?: string; topicTitle?: string; }): { ok: boolean; error?: string; }; /** * Delete a scheduled task. Emits a `schedule.deleted` event so the dashboard * drops the row immediately without waiting for the next poll. */ export declare function removeTaskForDashboard(id: string): { ok: boolean; error?: string; }; export {}; //# sourceMappingURL=scheduler.d.ts.map