refactor(cron): rename scheduler feature to cron

Rename the recurring-jobs feature scheduler->cron to disambiguate from the
legacy ScheduledRun system (/api/scheduled), which is left untouched:

- ScheduledJob->CronJob, SchedulerService->CronService
- /api/scheduler/jobs -> /api/cron/jobs; SSE scheduler:* -> cron:*
- state keys cronJobs/cronJobRuns
- files moved to src/cron/, cron-routes.ts, cron-port.ts, types/cron.ts
- frontend cron-ui.js, #cronModal, menu "Cron"
- docs moved to docs/cron-discovery.md + docs/cron-build-brief.md, README guides
- new tests: cron-service.test.ts, cron-time.test.ts

Green: tsc, lint, frontend-syntax, format, 30 cron + 9 legacy scheduled-runs tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmvZR12aX2v8K7YhqxPUAU
This commit is contained in:
Kris
2026-06-29 11:35:56 +05:30
co-authored by Claude Opus 4.8
parent 2d2f4e592b
commit 9feaa0d6e5
27 changed files with 1383 additions and 370 deletions
+13 -13
View File
@@ -152,10 +152,10 @@ import {
registerClipboardRoutes,
registerSearchRoutes,
registerOrchestratorRoutes,
registerSchedulerRoutes,
registerCronRoutes,
registerWsRoutes,
} from './routes/index.js';
import { SchedulerService } from '../scheduler/scheduler-service.js';
import { CronService } from '../cron/cron-service.js';
const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -177,7 +177,7 @@ import {
ITERATION_PAUSE_MS,
STATS_COLLECTION_INTERVAL_MS,
INACTIVITY_TIMEOUT_MS,
SCHEDULER_TICK_INTERVAL,
CRON_TICK_INTERVAL,
} from '../config/server-timing.js';
/**
@@ -226,8 +226,8 @@ export class WebServer extends EventEmitter {
// Store session listener references for explicit cleanup (prevents memory leaks)
private sessionListenerRefs: Map<string, SessionListenerRefs> = new Map();
private scheduledRuns: Map<string, ScheduledRun> = new Map();
/** Cron-style scheduler service (assigned in setupRoutes). */
private schedulerService!: SchedulerService;
/** Cron service (assigned in setupRoutes). */
private cronService!: CronService;
private sse: SseStreamManager;
private store = getStore();
private port: number;
@@ -879,11 +879,11 @@ export class WebServer extends EventEmitter {
registerSearchRoutes(this.app, ctx);
registerOrchestratorRoutes(this.app, ctx);
// Cron-style scheduler: build the service from the same context, recompute
// Cron: build the service from the same context, recompute
// due times for any persisted jobs, then expose it to its routes.
this.schedulerService = new SchedulerService(ctx);
this.schedulerService.init();
registerSchedulerRoutes(this.app, { ...ctx, scheduler: this.schedulerService });
this.cronService = new CronService(ctx);
this.cronService.init();
registerCronRoutes(this.app, { ...ctx, cron: this.cronService });
registerWsRoutes(this.app, ctx, () => this.getHostPolicy());
}
@@ -1959,14 +1959,14 @@ export class WebServer extends EventEmitter {
{ description: 'scheduled runs cleanup' }
);
// Start the cron-style scheduler loop (fires due ScheduledJobs).
// Start the cron loop (fires due CronJobs).
this.cleanup.setInterval(
() => {
this.schedulerService.tickDueJobs().catch((err) => {
console.error('[scheduler] tick failed:', getErrorMessage(err));
this.cronService.tickDueJobs().catch((err) => {
console.error('[cron] tick failed:', getErrorMessage(err));
});
},
SCHEDULER_TICK_INTERVAL,
CRON_TICK_INTERVAL,
{ description: 'scheduled jobs due-checker' }
);