/** * Cron / todo agent-tool family — `todo_add` / `todo_list` / `cron_schedule` * (T11950 · M7 · epic T11456 · SG-TOOLS). * * Surfaces the EXISTING task store to the agent loop as `agent`-toolset tools that * work daemon-OFF: * * - **`todo_add`** — create a task, DELEGATING to the existing * {@link import('../tasks/ops.js')}'s `tasksAddOp` (the same path `cleo add` * uses). No new table, no new schema. * - **`todo_list`** — list tasks, DELEGATING to `tasksListOp` (the same path * `cleo list` uses). * - **`cron_schedule`** — register a recurring schedule. The schedule store now * exists (the `schedules` table + leased Gate-3 accessor `store/schedule-store.ts`, * T11962 under T11679), so this tool DELEGATES to {@link ScheduleStore.add} and * persists a row daemon-OFF (a future daemon scheduler consumes the SAME table * as a separate reader). It stays REGISTERED-but-capability-gated: its * {@link AvailabilityCheck} hides it until a host advertises a schedule store * (`capabilities.scheduleStore === true`) so a host that has opted out of the * schedule domain does not surface it; invoking it without the store still * returns a typed `E_SCHEDULE_STORE_UNAVAILABLE` failure. `todo_*` are always * available daemon-OFF. * * ## Why a seam, not a hardcoded import (testing + Gate-11) * * The task ops are injected through the {@link TaskOps} seam, defaulting to the * real `ops` functions. The unit test injects a FAKE store and asserts delegation * + schema validation WITHOUT opening a real `tasks.db`. The tools are DEFINED * here under `packages/core/src/tools` and CONSUME the task subsystem — they * construct no new atomic primitive (Gate-11). * * ## Gate-13 * * No model/transport/provider client is constructed here — task CRUD is a local * SQLite operation. There is no chokepoint concern. * * @epic T11456 * @task T11950 * @see ../tasks/ops.js — `tasksAddOp` / `tasksListOp` (the ops this family delegates to) * @see ./exec-code-agent-tool.js — the injectable-seam + capability-gated availability pattern mirrored here */ import type { TaskPriority, TaskStatus, TaskType } from '@cleocode/contracts'; import type { AddTaskResult } from '../tasks/add.js'; import type { ListTasksResult } from '../tasks/list.js'; import { type AgentToolRegistry, type AvailabilityCheck } from './agent-registry.js'; /** * The task store operations the `todo_*` tools delegate to. Each member has the * SAME signature as the corresponding `ops` function. Injectable so the unit test * can supply a fake store; defaults to the real ops in production. */ export interface TaskOps { /** Create a task (→ `tasksAddOp`). */ readonly add: (projectRoot: string, params: { title: string; description?: string; parent?: string; priority?: TaskPriority; type?: TaskType; acceptance?: string[]; }) => Promise; /** List tasks (→ `tasksListOp`). */ readonly list: (projectRoot: string, params: { parent?: string; status?: TaskStatus; priority?: TaskPriority; type?: TaskType; limit?: number; }) => Promise; } /** * The result `cron_schedule` returns: on success the minted `scheduleId` of the * persisted row; on failure a typed, non-throwing error (e.g. when no schedule * store backs the host). The tool is registered (catalog-stable) and gated on the * `scheduleStore` host capability. */ export interface CronScheduleResult { /** Whether a schedule row was registered. */ readonly ok: boolean; /** The registered schedule's ID (present on success). */ readonly scheduleId?: string; /** A stable code + message for why scheduling failed (present on failure). */ readonly error?: { readonly code: string; readonly message: string; }; } /** * The schedule-store operation the `cron_schedule` tool delegates to. Injectable * so the unit test can supply a fake store; defaults to the real Gate-3 accessor * (`store/schedule-store.ts`) opened through the {@link openDualScopeDb} chokepoint. */ export interface ScheduleStore { /** * Register a recurring schedule and return its minted opaque handle. * * @param projectRoot - The project root whose `cleo.db` the schedule persists in. * @param params - The cron expression + task template (title / description). * @returns The minted `sched-` handle. */ readonly add: (projectRoot: string, params: { cron: string; title: string; description?: string; }) => Promise; } /** * Available only when the host advertises a schedule store * (`capabilities.scheduleStore === true`). The schedule store now EXISTS (the * `schedules` table + leased Gate-3 accessor, T11962 under T11679), so the gate is * a host POLICY/capability switch — a host that has opted out of the schedule * domain does not surface `cron_schedule`. Registration of a schedule row persists * WITHOUT a live daemon (the chokepoint serializes the single in-process writer); * a future daemon scheduler consumes the same table as a separate reader. */ export declare const scheduleStoreAvailable: AvailabilityCheck; /** Options for {@link registerScheduleAgentTools} — all injectable for testing. */ export interface ScheduleAgentToolOptions { /** The task ops seam. Defaults to the real `tasksAddOp` / `tasksListOp`. */ readonly tasks?: TaskOps; /** * The schedule-store seam `cron_schedule` delegates to. Defaults to the real * Gate-3 accessor (`store/schedule-store.ts`). Injected in tests with a fake * store so registration is asserted WITHOUT opening a real `cleo.db`. */ readonly schedule?: ScheduleStore; /** * The project root threaded into every op (defaults to the resolved project * root via {@link resolveOrCwd} — never a bare `process.cwd()` in core, T9584). */ readonly projectRoot?: string; } /** * Register the cron / todo agent-tool family into `registry`. Pure registration — * no `tasks.db` is opened, no row is written here; all of that happens later * inside each tool's `execute` through the injected (or lazily-resolved real) * ops. Import-time side-effect-free. * * @param registry - The registry to populate. * @param options - Injectable task ops / project root (for testing). */ export declare function registerScheduleAgentTools(registry: AgentToolRegistry, options?: ScheduleAgentToolOptions): void; /** * Self-registration marker (AC1) — the identifier the * {@link AgentToolRegistry.discover} bounded source scan greps for. Aliases * {@link registerScheduleAgentTools} so a future scan-dir discovery (or the * built-in aggregator) can call it uniformly with the other agent-tool modules. * * @param registry - The registry to populate. */ export declare function registerAgentTools(registry: AgentToolRegistry): void; //# sourceMappingURL=schedule-agent-tools.d.ts.map