feat: task scheduling, CLI commands, and task resumption (v0.4.0)#48
feat: task scheduling, CLI commands, and task resumption (v0.4.0)#48
Conversation
Phase 1 of task scheduling implementation (GitHub issue #45). Establishes all shared types, interfaces, and event contracts. Domain types (domain.ts): - ScheduleId branded type - ScheduleStatus enum: ACTIVE, PAUSED, COMPLETED, CANCELLED, EXPIRED - ScheduleType enum: CRON, ONE_TIME - MissedRunPolicy enum: SKIP, CATCHUP, FAIL - Schedule interface with immutable fields - ScheduleRequest for creation - ScheduleUpdate for modifications - createSchedule() factory returning frozen object - updateSchedule() immutable update helper - isScheduleActive() status check helper Events (events.ts): - ScheduleCreatedEvent, ScheduleTriggeredEvent, ScheduleExecutedEvent - ScheduleMissedEvent, ScheduleCancelledEvent, SchedulePausedEvent - ScheduleResumedEvent, ScheduleExpiredEvent, ScheduleUpdatedEvent - ScheduleQueryEvent, ScheduleQueryResponseEvent for event-driven reads - All events added to ClaudineEvent union type Interfaces (interfaces.ts): - ScheduleExecution for execution history tracking - ScheduleRepository with save, update, findById, findAll, findByStatus - findDue() for scheduler tick, delete, count - recordExecution() and getExecutionHistory() for audit trail Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…scheduling Add SQLite persistence layer for task scheduling feature (Phase 2): - Migration v4: Creates schedules and schedule_executions tables with indexes - SQLiteScheduleRepository: Full CRUD + findDue + execution history tracking - Prepared statements for all queries (performance) - Zod validation at database boundary (type safety) - Result pattern for all operations (no throws) Part of GitHub issue #45 - Task Scheduling feature. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 3 of task scheduling feature (issue #45): - Add cron-parser dependency for cron expression parsing - Create src/utils/cron.ts with validateCronExpression, getNextRunTime, getNextRunTimes, isValidTimezone, validateTimezone, parseCronExpression - Create src/utils/index.ts barrel export for utilities - Create ScheduleHandler with factory pattern (like DependencyHandler): - Subscribes to ScheduleCreated, ScheduleTriggered, ScheduleCancelled, SchedulePaused, ScheduleResumed, ScheduleUpdated, ScheduleQuery - Validates cron expressions and timezones at schedule creation - Creates tasks when schedules trigger, updates execution history - Handles TaskCompleted/TaskFailed for execution tracking - Create ScheduleExecutor timer-based service: - Uses setInterval with .unref() for non-blocking tick loop - Default 60-second check interval (configurable) - Finds due schedules via findDue() repository method - Implements missed run policies: SKIP, CATCHUP, FAIL - Exposes triggerTick() for testing All code follows Result type patterns, no exceptions in business logic. Build passes: npm run build Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 4 of task scheduling feature implementation: - Integrate ScheduleHandler in handler-setup.ts using factory pattern - Register scheduleRepository and scheduleExecutor in bootstrap - Add 6 MCP tools: ScheduleTask, ListSchedules, GetSchedule, CancelSchedule, PauseSchedule, ResumeSchedule - All tools have proper Zod validation at boundary Part of GitHub issue #45 - Task Scheduling feature Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
|||||||||||||||||||||||||||||||||||||||||||||||||||
PR Code Suggestions ✨Explore these optional code suggestions:
|
|||||||||||||||||||
Add comprehensive test coverage for the new task scheduling feature: - tests/unit/utils/cron.test.ts: Tests for cron expression validation, next run time calculation, timezone validation, and parsing utilities - tests/unit/implementations/schedule-repository.test.ts: Tests for SQLiteScheduleRepository including save, update, findById, findAll, findByStatus, findDue, delete, count, recordExecution, and getExecutionHistory operations Self-review found P1 issue (missing tests for new functionality) and added 48 test cases covering core scheduling behaviors. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
P0 Design Fix: - Change useWorktree default from true to false in MCP adapter - Safer default: workers don't create worktrees by default (opt-in) P2 Improvements: - Use type-only imports for Schedule type in schedule-handler.ts - Use type-only imports for Schedule type in schedule-executor.ts - Use type-only imports for CronExpression type in cron.ts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Track running schedules in ScheduleExecutor via Map<scheduleId, taskId> - Listen for ScheduleExecuted events to mark schedule as running - Listen for task completion events to clear running state - Skip triggering schedule if previous task is still running This addresses acceptance criterion: "Concurrent execution prevented (skip if previous still running)" Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
cron-parser@4.9.0 is CommonJS. Node.js ESM cannot use named imports from CJS modules — only default imports. TypeScript compiles fine due to esModuleInterop, but runtime crashes under Node.js. Vitest masks this because it uses Vite/esbuild for module resolution.
Code Review: Scheduling Feature ImplementationReview Summary: 8 perspectives (Security, Architecture, Performance, Quality, TypeScript, Database, Dependencies, Documentation) Overall AssessmentThis PR implements a comprehensive scheduling feature (cron and one-time schedules) with solid code quality overall: proper Zod validation at boundaries, immutable types, Result types consistently used, event-driven architecture alignment. However, multiple reviewers independently identified 4 critical architectural issues that must be resolved before merge. Key Consensus Issues (found by 3+ reviewers):
BLOCKING Findings (Must Fix Before Merge)CRITICAL / HIGH SEVERITY (9 total)1. Dual-save on schedule creation — Status: BLOCKING | Consensus: 4 reviewers independently
2. Non-null assertion on potentially undefined Status: BLOCKING | Consensus: TypeScript + Quality reviewers
3. Infinite retrigger when Status: BLOCKING | Consensus: Quality + Architecture + Performance
4. Unsafe type casts in Status: BLOCKING | Consensus: TypeScript + Architecture + Quality
5. Unsafe type assertions for enums — Status: BLOCKING | Severity: HIGH
6. Read-Modify-Write TOCTOU race in Status: BLOCKING | Consensus: Database + Architecture + Performance (3 reviewers)
7. Missing Status: BLOCKING | Severity: HIGH (Security)
8. Unsafe JSON deserialization of Status: BLOCKING | Severity: HIGH (Security)
9. Silent enum defaults masking data corruption — Status: BLOCKING | Consensus: Security + Database + TypeScript + Quality (4 reviewers)
SHOULD-FIX Findings (Strongly Recommended)HIGH SEVERITY (5 total)S1. ScheduleExecutor not stopped during graceful shutdown —
S2. Event subscription leak in ScheduleExecutor —
S3. Dead event subscriptions in ScheduleHandler —
S4. Missing
S5.
S6. MCPAdapter optional parameters should be required —
MEDIUM SEVERITY (5 total)S7. Unsafe
S8.
S9. Sequential schedule processing could be parallelized —
S10. Concurrent execution prevention not persisted —
S11. High cyclomatic complexity in
PRE-EXISTING Issues (Not Blocking)These were found by reviewers but already exist in the codebase:
Documentation (Critical Gaps)The implementation code quality is solid, but documentation layer not updated:
These must be updated for release. See documentation review report for detailed fixes. Summary Table
Total: 9 BLOCKING findings (must resolve before merge) Merge RecommendationStatus: ❌ CHANGES_REQUESTED Blocking Issues: 9 (all HIGH or CRITICAL severity) Key Priority Fixes (in order):
All 9 must be resolved before this PR is merge-ready. Review compiled by Claude Code reviewing scheduling feature implementation across 8 perspectives. Consensus findings (3+ reviewers) marked with indicator. |
…de in schedule-handler - Fix infinite retrigger when getNextRunTime fails for CRON schedules: always include nextRunAt in update (even if undefined) so stale past nextRunAt is cleared and findDue stops returning the schedule every tick. On failure, pause the schedule defensively. - Add exhaustive never check for schedule.scheduleType in handleScheduleCreated so new ScheduleType enum values cause compile-time errors instead of silent fall-through. - Remove no-op TaskCompleted/TaskFailed subscriptions and handlers that only logged debug messages. ScheduleExecutor already handles task completion tracking via runningSchedules.
- Add ScheduleExecutor.stop() to container dispose and signal shutdown handlers to prevent timer firing against closed resources - Convert constructor to factory pattern (ScheduleExecutor.create()) to eliminate constructor side effects, matching ScheduleHandler's pattern - Store subscription IDs and unsubscribe in stop() to prevent event handler leaks on repeated start/stop cycles - Replace unsafe `as` casts with generic type parameters on EventBus subscribe calls for proper type inference
- FEATURES.md: add Task Scheduling section, remove from NOT Implemented, update date - CLAUDE.md: add ScheduleHandler/ScheduleExecutor to architecture, scheduling MCP tools, file locations, database tables - README.md: add 6 scheduling tools to MCP Tools table, add Scheduling usage section - ROADMAP.md: mark Task Scheduling as implemented, update timeline and success criteria
- Extract MCPToolResponse type to reduce inline type duplication - Replace nested ternary with toMissedRunPolicy helper function - Hoist DelegateRequestSchema to module level (avoid per-call allocation) - Consolidate duplicate imports in schedule-executor - Complete stubScheduleRepository interface in tests - Remove spurious blank lines in handler methods
…tion - Extract fetchScheduleOrError() to deduplicate schedule validation across 4 MCP handlers - Extract respondWithError() to deduplicate EventBus error response casts in schedule query handler - Fix runCount reference inconsistency in log message
Add explicit error handling for unchecked repository results in schedule-handler and schedule-executor. All scheduleRepo.update() and scheduleRepo.recordExecution() calls now check results and log errors instead of silently dropping failures.
…cade fix Schedule Service Extraction: - Extract schedule business logic from MCP adapter into ScheduleManagerService - MCP adapter now delegates to service (thin protocol wrapper) - Wire service through bootstrap with proper DI CLI Commands: - Add `schedule create|list|get|cancel|pause|resume` subcommands - Add `pipeline` command for chained sequential task execution - Add `resume` command for failed/completed task resumption - Add `withServices()` helper to eliminate CLI bootstrap boilerplate Task Resumption: - Add TaskCheckpoint domain type and CheckpointRepository - Add CheckpointHandler (auto-checkpoint on task completion/failure) - Add git-state capture utility for checkpoint context - Add TaskManagerService.resume() with enriched prompt construction - Database migration v5: task_checkpoints table FK Cascade Fix: - Change task-repository save() from INSERT OR REPLACE to INSERT OR IGNORE - Add proper UPDATE statement for task-repository update() - Add proper UPDATE statement for schedule-repository update() - Refactor PersistenceHandler to use update() instead of save() for status changes - Prevents ON DELETE CASCADE/SET NULL from destroying child rows (schedule_executions, task_checkpoints) during task/schedule updates
New test files: - schedule-manager.test.ts: service method validation and error handling - schedule-handler.test.ts: event handler lifecycle (create, trigger, cancel, pause, resume) - schedule-executor.test.ts: tick engine, missed run policies, concurrent execution prevention - checkpoint-repository.test.ts: CRUD operations, boundary validation - checkpoint-handler.test.ts: auto-checkpoint on task completion/failure - task-scheduling.test.ts: end-to-end schedule lifecycle with real DB - task-resumption.test.ts: end-to-end resume with enriched prompts and retry chains Updated tests: - query-handler.test.ts: use repository.update() instead of save() for status changes - cli.test.ts: add schedule, pipeline, and resume command coverage - test-doubles.ts: add NoOpProcessSpawner for integration tests Fixes applied: - Set WORKER_MIN_SPAWN_DELAY_MS=10 in integration tests (production default is 10s)
- Bump version from 0.3.3 to 0.4.0 - Add release notes covering task scheduling, task resumption, FK cascade fix, and comprehensive test coverage
- Add ResumeTask to MCP tools table and Task Resumption section in README - Add schedule/resume/pipeline CLI commands to README and FEATURES - Fix testing section: document grouped test commands, note npm test is blocked - Update roadmap: mark v0.4.0 as implemented (scheduling + resumption) - Add Task Resumption section to FEATURES with auto-checkpoints, retry chains - Add "What's New in v0.4.0" section to FEATURES - Update version timeline and success criteria in ROADMAP - Make FEATURES title version-neutral
…ains When a task specifies continueFrom (a dependency task ID), the DependencyHandler enriches the task's prompt with checkpoint context from that dependency before the task runs. This enables chained task workflows where downstream tasks receive context about what their prerequisite accomplished. Implementation: - Added continueFrom field to DelegateRequest, Task, and createTask() - Added migration v6 for continue_from column in tasks table - Created CheckpointLookup interface (ISP) for narrow dependency - Built continuation-prompt.ts pure function for prompt enrichment - DependencyHandler uses subscribe-first pattern to wait for checkpoint - TaskManager auto-adds continueFrom to dependsOn if not present - MCP adapter and CLI support --continue-from flag Tests: 6 continuation-prompt, 3 dependency-handler enrichment, 4 task-repository, 2 domain, 2 MCP adapter, 3 CLI, 2 integration
- Early existence validation: continueFrom referencing a nonexistent task now returns TASK_NOT_FOUND immediately instead of failing silently later - A→B→C chain test: verifies nested continuation context flows through multi-level dependency chains with checkpoint enrichment at each step - Integration test: validates nonexistent continueFrom is rejected - Documentation: continueFrom usage in README, FEATURES, and ROADMAP
- Add RetryTask to MCP tools list in FEATURES.md and README.md (was registered in adapter but undocumented) - Add continueFrom section to TASK-DEPENDENCIES.md and release notes - Fix migration version references (v4-v6, not v3-v5) in release notes - Fix pipeline command race: first step scheduled at "now" became past during validation; add 2-second buffer
- @modelcontextprotocol/sdk 1.24.3 → 1.26.0 (ReDoS, cross-client data leak) - ajv 8.17.1 → 8.18.0 (ReDoS with $data option) - qs transitive update (DoS via memory exhaustion)
…n in v0.4.0 tests v0.4.0 integration tests (task-scheduling, task-resumption) reintroduced 14 setTimeout calls that PR #44 had eliminated from the existing tests. Replace with waitForEvent() from event-helpers.ts for deterministic waits. Also fixes broken EventBus type import in event-helpers.ts (referenced non-existent export after EventBus was moved to event-bus.ts).
Summary
pipelinefor chained sequential tasks +resumefor failed task resumptionScheduleManagerServicefor CLI reuseINSERT OR REPLACEwith properINSERT OR IGNORE+UPDATEto prevent child row destruction during task/schedule updatesNew MCP Tools
ScheduleTask,ListSchedules,GetSchedule,CancelSchedule,PauseSchedule,ResumeScheduleResumeTaskNew CLI Commands
claudine schedule create|list|get|cancel|pause|resumeclaudine pipelineclaudine resumeDatabase Migrations
schedulestableschedule_executionstabletask_checkpointstableTest plan
npm run test:core(273 tests)npm run test:handlers(76 tests)npm run test:repositories(105 tests)npm run test:implementations(218 tests)npm run test:adapters(38 tests)npm run test:cli(83 tests)npm run test:integration(51 tests)npm run buildcleandocs/releases/RELEASE_NOTES_v0.4.0.md