/** * * Persistent scheduled-task system. Stores a JSON schedule at * `.peaks/cron/schedule.json` and lets the LLM-side runner * trigger tasks synchronously (`peaks cron run `) or * register a built-in periodic lease gc that the runbook * (`skills/peaks-code/`) checks on every session start. * * Built-in tasks (the only ones auto-registered today): * - `lease-gc-daily` — runs `peaks worktree list` once every 24h. This is a * daily lease LISTING that refreshes the alive-lease set; operators prune * a specific stale lease on demand with `peaks worktree gc --lease-id * `. (Fixed in rid 2026-10-01-cron-exec-timeout-01 §2.22: this header * previously claimed the task ran `peaks worktree gc --all-sessions`, * which is not what `cron-commands-schedule.ts` registers — the code and * the entry's own name say `list`.) * * Why a JSON file (not a real cron daemon): peaks-loop is a CLI * tool, not a service. The schedule is best-effort: the runbook * checks it on session start and surfaces overdue tasks. A * proper system cron / systemd timer is the production * deployment story; this CLI is the portable fallback. * * File layout: * .peaks/cron/schedule.json — registered tasks with their * interval + lastRunAt * .peaks/cron/history.jsonl — append-only run history * * Module layout (wave 3 split, job strict-remediation-abc, slice * c1-eslint-family-sweep): the schedule model lives in * `cron-commands-schedule.ts` and the three action handlers in * `cron-commands-actions.ts`. Every name exported from this path before the * split is still importable from here. `runTask` stays here together with * its exec-timeout constant (that constant carries this file's baseline * `no-magic-numbers` warning; new siblings must be clean outright). */ import type { Command } from 'commander'; import { type ProgramIO } from '../cli-helpers.js'; import { type RunRecord, type ScheduleEntry } from './cron-commands-schedule.js'; export { readSchedule, appendHistory, listDueTasks } from './cron-commands-schedule.js'; export type { ScheduleEntry, ScheduleFile, RunRecord } from './cron-commands-schedule.js'; /** * PRD-002b slice 2 — cron-orchestration magic numbers, exec half. The * interval/truncation constants live with the code that renders them * (`cron-commands-schedule.ts` / `cron-commands-actions.ts`). * * Per-task exec timeout — FIVE MINUTES (300,000 ms). `runTask` hands this to * `spawnSync(…, { timeout })`, which — with no shell in the way, see * `resolveTaskEntry` — kills THE TASK PROCESS itself, so a task child that * stalls is reaped within five minutes rather than inherited. Fixed in rid * 2026-10-01-cron-exec-timeout-01: this constant previously read `5 * * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND`, and `MINUTES_PER_HOUR * * SECONDS_PER_MINUTE * MS_PER_SECOND` is one HOUR, so the value was 18,000,000 * ms (5 h) — five times too long, contradicting the name and the intent. See * backlog §2.21. */ export declare const EXEC_TIMEOUT_MS: number; export declare function runTask(projectRoot: string, task: ScheduleEntry, timeoutMs?: number): RunRecord; export declare function registerCronCommand(program: Command, io: ProgramIO): void;