@hybrd/scheduler 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/store.ts","../src/tools.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\"\nimport cronParser from \"cron-parser\"\nconst { parseExpression } = cronParser\n\nimport type {\n\tChannelDispatcher,\n\tCronJob,\n\tCronJobCreate,\n\tCronJobPatch,\n\tCronRunStatus,\n\tCronSchedule,\n\tListPageOptions,\n\tPaginatedResult,\n\tSchedulerConfig,\n\tSchedulerEvent,\n\tSchedulerStatus,\n\tTriggerResponse\n} from \"@hybrd/types\"\n\nimport { SqliteSchedulerStore } from \"./store.js\"\n\nexport { SqliteSchedulerStore, createSqliteStore } from \"./store.js\"\nexport type { SqliteSchedulerStoreOptions } from \"./store.js\"\n\nexport { createSchedulerTools } from \"./tools.js\"\nexport type { SchedulerTool } from \"./tools.js\"\n\nconst MAX_TIMER_DELAY_MS = 60_000\nconst MIN_REFIRE_GAP_MS = 2_000\nconst STUCK_RUN_MS = 2 * 60 * 60 * 1000\nconst MAX_SCHEDULE_ERRORS = 3\n\nconst ERROR_BACKOFF_SCHEDULE_MS = [\n\t30_000,\n\t60_000,\n\t5 * 60_000,\n\t15 * 60_000,\n\t60 * 60_000\n]\n\nfunction errorBackoffMs(consecutiveErrors: number): number {\n\tconst idx = Math.min(\n\t\tconsecutiveErrors - 1,\n\t\tERROR_BACKOFF_SCHEDULE_MS.length - 1\n\t)\n\treturn ERROR_BACKOFF_SCHEDULE_MS[Math.max(0, idx)] ?? 60_000\n}\n\nexport interface ExecutorResult {\n\tstatus: CronRunStatus\n\terror?: string\n\tsummary?: string\n\toutputText?: string\n\tdelivered?: boolean\n}\n\nexport interface SchedulerExecutor {\n\trunAgentTurn(job: CronJob): Promise<ExecutorResult>\n\trunSystemEvent(job: CronJob): Promise<ExecutorResult>\n}\n\nexport interface SchedulerServiceConfig extends SchedulerConfig {\n\tstore: SqliteSchedulerStore\n\tdispatcher: ChannelDispatcher\n\texecutor: SchedulerExecutor\n\tenabled?: boolean\n}\n\ninterface SchedulerState {\n\trunning: boolean\n\ttimer: ReturnType<typeof setTimeout> | null\n\top: Promise<unknown>\n}\n\nexport class SchedulerService {\n\tprivate store: SqliteSchedulerStore\n\tprivate dispatcher: ChannelDispatcher\n\tprivate executor: SchedulerExecutor\n\tprivate state: SchedulerState\n\tprivate timezone: string\n\tprivate enabled: boolean\n\tprivate eventCallback?: (event: SchedulerEvent) => void\n\n\tconstructor(config: SchedulerServiceConfig) {\n\t\tthis.store = config.store\n\t\tthis.dispatcher = config.dispatcher\n\t\tthis.executor = config.executor\n\t\tthis.timezone =\n\t\t\tconfig.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone\n\t\tthis.enabled = config.enabled ?? true\n\t\tthis.state = {\n\t\t\trunning: false,\n\t\t\ttimer: null,\n\t\t\top: Promise.resolve()\n\t\t}\n\t}\n\n\tonEvent(callback: (event: SchedulerEvent) => void): void {\n\t\tthis.eventCallback = callback\n\t}\n\n\tprivate emit(event: SchedulerEvent): void {\n\t\tthis.eventCallback?.(event)\n\t}\n\n\tprivate locked<T>(fn: () => Promise<T>): Promise<T> {\n\t\t// Chain onto the previous operation. We use .then() with a no-op\n\t\t// rejection handler so that a failure in a prior operation doesn't\n\t\t// prevent subsequent operations from running. Each fn's own errors\n\t\t// propagate to its caller via the returned promise.\n\t\tconst next = this.state.op.then(fn, () => fn())\n\t\t// Keep the chain alive even if fn rejects — the next queued\n\t\t// operation should still run after this one settles.\n\t\tthis.state.op = next.catch(() => {})\n\t\treturn next\n\t}\n\n\tprivate computeNextRunAtMs(\n\t\tschedule: CronSchedule,\n\t\tnowMs: number\n\t): number | undefined {\n\t\ttry {\n\t\t\tswitch (schedule.kind) {\n\t\t\t\tcase \"at\": {\n\t\t\t\t\tconst atMs = new Date(schedule.at).getTime()\n\t\t\t\t\tif (Number.isNaN(atMs)) return undefined\n\t\t\t\t\treturn atMs > nowMs ? atMs : undefined\n\t\t\t\t}\n\t\t\t\tcase \"every\": {\n\t\t\t\t\tconst everyMs = Math.max(1, Math.floor(schedule.everyMs))\n\t\t\t\t\tconst anchorMs = schedule.anchorMs ?? nowMs\n\t\t\t\t\tconst elapsed = Math.max(0, nowMs - anchorMs)\n\t\t\t\t\tconst steps = Math.max(\n\t\t\t\t\t\t1,\n\t\t\t\t\t\tMath.floor((elapsed + everyMs - 1) / everyMs)\n\t\t\t\t\t)\n\t\t\t\t\treturn anchorMs + steps * everyMs\n\t\t\t\t}\n\t\t\t\tcase \"cron\": {\n\t\t\t\t\tconst interval = parseExpression(schedule.expr, {\n\t\t\t\t\t\ttz: schedule.tz ?? this.timezone\n\t\t\t\t\t})\n\t\t\t\t\tconst next = interval.next()\n\t\t\t\t\treturn next ? next.getTime() : undefined\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tprivate computeJobNextRunAtMs(\n\t\tjob: CronJob,\n\t\tnowMs: number\n\t): number | undefined {\n\t\tif (!job.enabled) return undefined\n\n\t\tif (job.schedule.kind === \"every\") {\n\t\t\tconst lastRunAtMs = job.state.lastRunAtMs\n\t\t\tif (typeof lastRunAtMs === \"number\" && Number.isFinite(lastRunAtMs)) {\n\t\t\t\tconst nextFromLastRun = Math.floor(lastRunAtMs) + job.schedule.everyMs\n\t\t\t\tif (nextFromLastRun > nowMs) {\n\t\t\t\t\treturn nextFromLastRun\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (job.schedule.kind === \"at\") {\n\t\t\tif (job.state.lastRunStatus === \"ok\") {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\n\t\treturn this.computeNextRunAtMs(job.schedule, nowMs)\n\t}\n\n\tprivate isRunnableJob(job: CronJob, nowMs: number): boolean {\n\t\tif (!job.enabled) return false\n\n\t\tif (typeof job.state.runningAtMs === \"number\") {\n\t\t\tif (nowMs - job.state.runningAtMs > STUCK_RUN_MS) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\n\t\tconst next = job.state.nextRunAtMs\n\t\treturn typeof next === \"number\" && nowMs >= next\n\t}\n\n\tprivate findDueJobs(nowMs: number): CronJob[] {\n\t\tconst jobs = this.store.getAllJobsSync()\n\t\treturn jobs.filter((job) => this.isRunnableJob(job, nowMs))\n\t}\n\n\tprivate nextWakeAtMs(): number | undefined {\n\t\tconst jobs = this.store.getAllJobsSync()\n\t\tlet min: number | undefined\n\n\t\tfor (const job of jobs) {\n\t\t\tif (!job.enabled) continue\n\t\t\tif (job.state.runningAtMs !== undefined) continue\n\t\t\tconst next = job.state.nextRunAtMs\n\t\t\tif (typeof next !== \"number\") continue\n\t\t\tif (min === undefined || next < min) {\n\t\t\t\tmin = next\n\t\t\t}\n\t\t}\n\n\t\treturn min\n\t}\n\n\tprivate armTimer(): void {\n\t\tthis.stopTimer()\n\n\t\tif (!this.enabled) return\n\n\t\tconst nextAt = this.nextWakeAtMs()\n\t\tif (!nextAt) return\n\n\t\tconst now = Date.now()\n\t\tconst delay = Math.max(0, nextAt - now)\n\t\tconst clampedDelay = Math.min(delay, MAX_TIMER_DELAY_MS)\n\n\t\tthis.state.timer = setTimeout(() => {\n\t\t\tvoid this.onTimer()\n\t\t}, clampedDelay)\n\t}\n\n\tprivate stopTimer(): void {\n\t\tif (this.state.timer) {\n\t\t\tclearTimeout(this.state.timer)\n\t\t\tthis.state.timer = null\n\t\t}\n\t}\n\n\tprivate async onTimer(): Promise<void> {\n\t\tif (this.state.running) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.state.running = true\n\t\tthis.stopTimer()\n\n\t\ttry {\n\t\t\tconst dueJobs = await this.locked(async () => {\n\t\t\t\tconst now = Date.now()\n\t\t\t\tconst due = this.findDueJobs(now)\n\n\t\t\t\tif (due.length === 0) {\n\t\t\t\t\tthis.recomputeNextRunsForMaintenance()\n\t\t\t\t\treturn []\n\t\t\t\t}\n\n\t\t\t\tfor (const job of due) {\n\t\t\t\t\tjob.state.runningAtMs = now\n\t\t\t\t\tjob.state.lastError = undefined\n\t\t\t\t}\n\t\t\t\tthis.store.saveAllJobsSync()\n\n\t\t\t\treturn due\n\t\t\t})\n\n\t\t\tfor (const job of dueJobs) {\n\t\t\t\tawait this.executeJob(job)\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.state.running = false\n\t\t\tthis.armTimer()\n\t\t}\n\t}\n\n\tprivate recomputeNextRunsForMaintenance(): boolean {\n\t\tconst jobs = this.store.getAllJobsSync()\n\t\tconst now = Date.now()\n\t\tlet changed = false\n\n\t\tfor (const job of jobs) {\n\t\t\tif (!job.enabled) {\n\t\t\t\tif (job.state.nextRunAtMs !== undefined) {\n\t\t\t\t\tjob.state.nextRunAtMs = undefined\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t\tif (job.state.runningAtMs !== undefined) {\n\t\t\t\t\tjob.state.runningAtMs = undefined\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst runningAt = job.state.runningAtMs\n\t\t\tif (typeof runningAt === \"number\" && now - runningAt > STUCK_RUN_MS) {\n\t\t\t\tjob.state.runningAtMs = undefined\n\t\t\t\tchanged = true\n\t\t\t}\n\n\t\t\tif (job.state.nextRunAtMs === undefined) {\n\t\t\t\tjob.state.nextRunAtMs = this.computeJobNextRunAtMs(job, now)\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t}\n\n\t\tif (changed) {\n\t\t\tthis.store.saveAllJobsSync()\n\t\t}\n\n\t\treturn changed\n\t}\n\n\tprivate applyJobResult(\n\t\tjob: CronJob,\n\t\tresult: {\n\t\t\tstatus: CronRunStatus\n\t\t\terror?: string\n\t\t\tdelivered?: boolean\n\t\t\tstartedAt: number\n\t\t\tendedAt: number\n\t\t}\n\t): boolean {\n\t\tjob.state.runningAtMs = undefined\n\t\tjob.state.lastRunAtMs = result.startedAt\n\t\tjob.state.lastRunStatus = result.status\n\t\tjob.state.lastDurationMs = result.endedAt - result.startedAt\n\t\tjob.state.lastError = result.error\n\n\t\tif (result.status === \"error\") {\n\t\t\tjob.state.consecutiveErrors = (job.state.consecutiveErrors ?? 0) + 1\n\t\t} else {\n\t\t\tjob.state.consecutiveErrors = 0\n\t\t}\n\n\t\tconst shouldDelete =\n\t\t\tjob.schedule.kind === \"at\" &&\n\t\t\tjob.deleteAfterRun === true &&\n\t\t\tresult.status === \"ok\"\n\n\t\tif (!shouldDelete) {\n\t\t\tif (job.schedule.kind === \"at\") {\n\t\t\t\tjob.enabled = false\n\t\t\t\tjob.state.nextRunAtMs = undefined\n\t\t\t} else if (result.status === \"error\" && job.enabled) {\n\t\t\t\tconst backoff = errorBackoffMs(job.state.consecutiveErrors ?? 1)\n\t\t\t\tconst normalNext = this.computeJobNextRunAtMs(job, result.endedAt)\n\t\t\t\tconst backoffNext = result.endedAt + backoff\n\t\t\t\tjob.state.nextRunAtMs = normalNext\n\t\t\t\t\t? Math.max(normalNext, backoffNext)\n\t\t\t\t\t: backoffNext\n\t\t\t} else if (job.enabled) {\n\t\t\t\tconst naturalNext = this.computeJobNextRunAtMs(job, result.endedAt)\n\t\t\t\tif (job.schedule.kind === \"cron\") {\n\t\t\t\t\tconst minNext = result.endedAt + MIN_REFIRE_GAP_MS\n\t\t\t\t\tjob.state.nextRunAtMs = naturalNext\n\t\t\t\t\t\t? Math.max(naturalNext, minNext)\n\t\t\t\t\t\t: minNext\n\t\t\t\t} else {\n\t\t\t\t\tjob.state.nextRunAtMs = naturalNext\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn shouldDelete\n\t}\n\n\tprivate async executeJob(job: CronJob): Promise<void> {\n\t\tconst startedAt = Date.now()\n\t\tthis.emit({ jobId: job.id, action: \"started\", runAtMs: startedAt })\n\n\t\tlet result: ExecutorResult\n\t\ttry {\n\t\t\tif (job.sessionTarget === \"main\") {\n\t\t\t\tresult = await this.executor.runSystemEvent(job)\n\t\t\t} else {\n\t\t\t\tresult = await this.executor.runAgentTurn(job)\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tresult = {\n\t\t\t\tstatus: \"error\",\n\t\t\t\terror: err instanceof Error ? err.message : String(err)\n\t\t\t}\n\t\t}\n\n\t\tconst endedAt = Date.now()\n\n\t\tif (\n\t\t\tjob.delivery?.mode === \"announce\" &&\n\t\t\tresult.summary &&\n\t\t\tjob.delivery.channel &&\n\t\t\tjob.delivery.to\n\t\t) {\n\t\t\tconst deliveryResult: TriggerResponse = await this.dispatcher.dispatch({\n\t\t\t\tchannel: job.delivery.channel,\n\t\t\t\tto: job.delivery.to,\n\t\t\t\tmessage: result.summary\n\t\t\t})\n\t\t\tresult.delivered = deliveryResult.delivered\n\t\t}\n\n\t\tawait this.locked(async () => {\n\t\t\tconst currentJob = this.store.getJobSync(job.id)\n\t\t\tif (!currentJob) return\n\n\t\t\tconst shouldDelete = this.applyJobResult(currentJob, {\n\t\t\t\tstatus: result.status,\n\t\t\t\terror: result.error,\n\t\t\t\tdelivered: result.delivered,\n\t\t\t\tstartedAt,\n\t\t\t\tendedAt\n\t\t\t})\n\n\t\t\tthis.emit({\n\t\t\t\tjobId: currentJob.id,\n\t\t\t\taction: \"finished\",\n\t\t\t\tstatus: result.status,\n\t\t\t\terror: result.error,\n\t\t\t\tdelivered: result.delivered,\n\t\t\t\trunAtMs: startedAt,\n\t\t\t\tdurationMs: currentJob.state.lastDurationMs,\n\t\t\t\tnextRunAtMs: currentJob.state.nextRunAtMs\n\t\t\t})\n\n\t\t\tif (shouldDelete) {\n\t\t\t\tthis.store.deleteJobSync(currentJob.id)\n\t\t\t\tthis.emit({ jobId: currentJob.id, action: \"removed\" })\n\t\t\t} else {\n\t\t\t\tthis.store.saveJobSync(currentJob)\n\t\t\t}\n\t\t})\n\t}\n\n\tasync start(): Promise<void> {\n\t\tif (!this.enabled) {\n\t\t\tconsole.log(\"[scheduler] disabled\")\n\t\t\treturn\n\t\t}\n\n\t\tawait this.locked(async () => {\n\t\t\tconst jobs = this.store.getAllJobsSync()\n\t\t\tfor (const job of jobs) {\n\t\t\t\tif (typeof job.state.runningAtMs === \"number\") {\n\t\t\t\t\tjob.state.runningAtMs = undefined\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.store.saveAllJobsSync()\n\n\t\t\tthis.recomputeNextRunsForMaintenance()\n\t\t})\n\n\t\tthis.armTimer()\n\t\tconsole.log(\"[scheduler] started\")\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tthis.stopTimer()\n\t\tthis.state.running = false\n\t\t// Flush any pending writes to disk before shutting down.\n\t\t// The store uses a 1-second debounced save, so without this\n\t\t// the last batch of job state updates could be lost on exit.\n\t\tawait this.store.close()\n\t}\n\n\tasync status(): Promise<SchedulerStatus> {\n\t\treturn this.locked(async () => {\n\t\t\tconst jobs = this.store.getAllJobsSync()\n\t\t\treturn {\n\t\t\t\tenabled: this.enabled,\n\t\t\t\tjobs: jobs.length,\n\t\t\t\tnextWakeAtMs: this.nextWakeAtMs() ?? null\n\t\t\t}\n\t\t})\n\t}\n\n\tasync add(input: CronJobCreate): Promise<CronJob> {\n\t\treturn this.locked(async () => {\n\t\t\tconst now = Date.now()\n\t\t\tconst id = input.id ?? randomUUID()\n\n\t\t\tconst job: CronJob = {\n\t\t\t\tid,\n\t\t\t\tagentId: input.agentId,\n\t\t\t\tsessionKey: input.sessionKey,\n\t\t\t\tname: input.name,\n\t\t\t\tdescription: input.description,\n\t\t\t\tenabled: input.enabled ?? true,\n\t\t\t\tdeleteAfterRun: input.deleteAfterRun,\n\t\t\t\tcreatedAtMs: now,\n\t\t\t\tupdatedAtMs: now,\n\t\t\t\tschedule: input.schedule,\n\t\t\t\tsessionTarget: input.sessionTarget ?? \"isolated\",\n\t\t\t\twakeMode: input.wakeMode ?? \"now\",\n\t\t\t\tpayload: input.payload,\n\t\t\t\tdelivery: input.delivery,\n\t\t\t\tstate: {\n\t\t\t\t\t...input.state,\n\t\t\t\t\tnextRunAtMs: undefined\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tjob.state.nextRunAtMs = this.computeJobNextRunAtMs(job, now)\n\n\t\t\tthis.store.saveJobSync(job)\n\t\t\tthis.armTimer()\n\n\t\t\tthis.emit({\n\t\t\t\tjobId: job.id,\n\t\t\t\taction: \"added\",\n\t\t\t\tnextRunAtMs: job.state.nextRunAtMs\n\t\t\t})\n\n\t\t\treturn job\n\t\t})\n\t}\n\n\tasync get(id: string): Promise<CronJob | undefined> {\n\t\treturn this.store.getJobSync(id)\n\t}\n\n\tasync list(opts?: { includeDisabled?: boolean }): Promise<CronJob[]> {\n\t\tconst jobs = this.store.getAllJobsSync()\n\t\tconst includeDisabled = opts?.includeDisabled === true\n\t\tconst filtered = jobs.filter((j) => includeDisabled || j.enabled)\n\t\treturn filtered.sort(\n\t\t\t(a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0)\n\t\t)\n\t}\n\n\tasync listPage(opts?: ListPageOptions): Promise<PaginatedResult<CronJob>> {\n\t\tconst jobs = this.store.getAllJobsSync()\n\n\t\tconst includeDisabled =\n\t\t\topts?.enabled === \"all\" || opts?.enabled === \"disabled\"\n\t\tconst includeEnabled = opts?.enabled !== \"disabled\"\n\t\tconst query = opts?.query?.trim().toLowerCase() ?? \"\"\n\n\t\tconst filtered = jobs.filter((job) => {\n\t\t\tif (!includeDisabled && !job.enabled) return false\n\t\t\tif (!includeEnabled && job.enabled) return false\n\t\t\tif (query) {\n\t\t\t\tconst haystack = [job.name, job.description ?? \"\"]\n\t\t\t\t\t.join(\" \")\n\t\t\t\t\t.toLowerCase()\n\t\t\t\treturn haystack.includes(query)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\n\t\tconst sortBy = opts?.sortBy ?? \"nextRunAtMs\"\n\t\tconst sortDir = opts?.sortDir ?? \"asc\"\n\t\tconst dir = sortDir === \"desc\" ? -1 : 1\n\n\t\tfiltered.sort((a, b) => {\n\t\t\tlet cmp = 0\n\t\t\tif (sortBy === \"name\") {\n\t\t\t\tcmp = a.name.localeCompare(b.name)\n\t\t\t} else if (sortBy === \"updatedAtMs\") {\n\t\t\t\tcmp = a.updatedAtMs - b.updatedAtMs\n\t\t\t} else {\n\t\t\t\tconst aNext = a.state.nextRunAtMs\n\t\t\t\tconst bNext = b.state.nextRunAtMs\n\t\t\t\tif (typeof aNext === \"number\" && typeof bNext === \"number\") {\n\t\t\t\t\tcmp = aNext - bNext\n\t\t\t\t} else if (typeof aNext === \"number\") {\n\t\t\t\t\tcmp = -1\n\t\t\t\t} else if (typeof bNext === \"number\") {\n\t\t\t\t\tcmp = 1\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cmp * dir\n\t\t})\n\n\t\tconst total = filtered.length\n\t\tconst offset = Math.max(0, Math.min(total, opts?.offset ?? 0))\n\t\tconst limit = Math.max(1, Math.min(200, opts?.limit ?? 50))\n\t\tconst items = filtered.slice(offset, offset + limit)\n\t\tconst nextOffset = offset + items.length\n\n\t\treturn {\n\t\t\titems,\n\t\t\ttotal,\n\t\t\toffset,\n\t\t\tlimit,\n\t\t\thasMore: nextOffset < total,\n\t\t\tnextOffset: nextOffset < total ? nextOffset : null\n\t\t}\n\t}\n\n\tasync update(id: string, patch: CronJobPatch): Promise<CronJob> {\n\t\treturn this.locked(async () => {\n\t\t\tconst job = this.store.getJobSync(id)\n\t\t\tif (!job) {\n\t\t\t\tthrow new Error(`Job not found: ${id}`)\n\t\t\t}\n\n\t\t\tif (patch.name !== undefined) job.name = patch.name\n\t\t\tif (patch.description !== undefined) job.description = patch.description\n\t\t\tif (patch.enabled !== undefined) job.enabled = patch.enabled\n\t\t\tif (patch.deleteAfterRun !== undefined)\n\t\t\t\tjob.deleteAfterRun = patch.deleteAfterRun\n\t\t\tif (patch.schedule !== undefined) job.schedule = patch.schedule\n\t\t\tif (patch.sessionTarget !== undefined)\n\t\t\t\tjob.sessionTarget = patch.sessionTarget\n\t\t\tif (patch.wakeMode !== undefined) job.wakeMode = patch.wakeMode\n\t\t\tif (patch.payload !== undefined) job.payload = patch.payload\n\t\t\tif (patch.delivery !== undefined) job.delivery = patch.delivery\n\n\t\t\tjob.updatedAtMs = Date.now()\n\n\t\t\tif (job.enabled) {\n\t\t\t\tjob.state.nextRunAtMs = this.computeJobNextRunAtMs(job, job.updatedAtMs)\n\t\t\t} else {\n\t\t\t\tjob.state.nextRunAtMs = undefined\n\t\t\t\tjob.state.runningAtMs = undefined\n\t\t\t}\n\n\t\t\tthis.store.saveJobSync(job)\n\t\t\tthis.armTimer()\n\n\t\t\tthis.emit({\n\t\t\t\tjobId: job.id,\n\t\t\t\taction: \"updated\",\n\t\t\t\tnextRunAtMs: job.state.nextRunAtMs\n\t\t\t})\n\n\t\t\treturn job\n\t\t})\n\t}\n\n\tasync remove(id: string): Promise<{ ok: boolean; removed: boolean }> {\n\t\treturn this.locked(async () => {\n\t\t\tconst existed = this.store.getJobSync(id) !== undefined\n\t\t\tif (existed) {\n\t\t\t\tthis.store.deleteJobSync(id)\n\t\t\t\tthis.armTimer()\n\t\t\t\tthis.emit({ jobId: id, action: \"removed\" })\n\t\t\t}\n\t\t\treturn { ok: true, removed: existed }\n\t\t})\n\t}\n\n\tasync run(\n\t\tid: string,\n\t\tmode?: \"due\" | \"force\"\n\t): Promise<{ ok: boolean; ran: boolean; reason?: string }> {\n\t\tconst job = this.store.getJobSync(id)\n\t\tif (!job) {\n\t\t\treturn { ok: false, ran: false }\n\t\t}\n\n\t\tif (typeof job.state.runningAtMs === \"number\") {\n\t\t\treturn { ok: true, ran: false, reason: \"already-running\" }\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tconst due =\n\t\t\tmode === \"force\" ||\n\t\t\t(job.enabled &&\n\t\t\t\ttypeof job.state.nextRunAtMs === \"number\" &&\n\t\t\t\tnow >= job.state.nextRunAtMs)\n\t\tif (!due) {\n\t\t\treturn { ok: true, ran: false, reason: \"not-due\" }\n\t\t}\n\n\t\tawait this.executeJob(job)\n\t\treturn { ok: true, ran: true }\n\t}\n}\n\nexport async function createSchedulerService(\n\tconfig: SchedulerServiceConfig\n): Promise<SchedulerService> {\n\tawait config.store.init()\n\treturn new SchedulerService(config)\n}\n","import { readFileSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { dirname, join } from \"node:path\"\nimport initSqlJs from \"sql.js\"\n\nimport type {\n\tCronJob,\n\tCronJobState,\n\tCronPayload,\n\tCronSchedule,\n\tSessionTarget,\n\tWakeMode\n} from \"@hybrd/types\"\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS cron_jobs (\n id TEXT PRIMARY KEY,\n agent_id TEXT,\n session_key TEXT,\n name TEXT NOT NULL,\n description TEXT,\n enabled INTEGER NOT NULL DEFAULT 1,\n delete_after_run INTEGER,\n created_at_ms INTEGER NOT NULL,\n updated_at_ms INTEGER NOT NULL,\n schedule TEXT NOT NULL,\n session_target TEXT NOT NULL DEFAULT 'isolated',\n wake_mode TEXT NOT NULL DEFAULT 'now',\n payload TEXT NOT NULL,\n delivery TEXT,\n state TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_cron_jobs_next_run ON cron_jobs(id);\nCREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled ON cron_jobs(enabled);\n`\n\nexport interface SqliteSchedulerStoreOptions {\n\tdbPath?: string\n\tonSave?: (data: Uint8Array) => void | Promise<void>\n\tloadOnInit?: boolean\n}\n\ntype SqlJsStatic = Awaited<ReturnType<typeof initSqlJs>>\ntype SqlJsDatabase = InstanceType<SqlJsStatic[\"Database\"]>\n\nexport class SqliteSchedulerStore {\n\tprivate db: SqlJsDatabase | null = null\n\tprivate dbPath: string\n\tprivate onSave?: (data: Uint8Array) => void | Promise<void>\n\tprivate loadOnInit: boolean\n\tprivate initPromise: Promise<void> | null = null\n\tprivate dirty = false\n\tprivate saveTimer?: ReturnType<typeof setTimeout>\n\tprivate jobsCache: Map<string, CronJob> | null = null\n\n\tconstructor(options: SqliteSchedulerStoreOptions = {}) {\n\t\tthis.dbPath = options.dbPath ?? \":memory:\"\n\t\tthis.onSave = options.onSave\n\t\tthis.loadOnInit = options.loadOnInit ?? true\n\t}\n\n\tasync init(): Promise<void> {\n\t\tif (this.initPromise) {\n\t\t\treturn this.initPromise\n\t\t}\n\n\t\tthis.initPromise = this._init()\n\t\treturn this.initPromise\n\t}\n\n\tprivate async _init(): Promise<void> {\n\t\tlet SQL: SqlJsStatic\n\t\ttry {\n\t\t\tconst req = createRequire(process.cwd())\n\t\t\tconst sqlJsPath = dirname(req.resolve(\"sql.js\"))\n\t\t\tconst wasmPath = join(sqlJsPath, \"sql-wasm.wasm\")\n\t\t\tconst wasmBinary = readFileSync(wasmPath)\n\t\t\tSQL = await initSqlJs({ wasmBinary } as any)\n\t\t} catch {\n\t\t\tSQL = await initSqlJs()\n\t\t}\n\n\t\tif (this.dbPath === \":memory:\" || !this.loadOnInit) {\n\t\t\tthis.db = new SQL.Database()\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tconst buffer = readFileSync(this.dbPath)\n\t\t\t\tthis.db = new SQL.Database(new Uint8Array(buffer))\n\t\t\t} catch {\n\t\t\t\tthis.db = new SQL.Database()\n\t\t\t}\n\t\t}\n\n\t\tthis.db.run(SCHEMA)\n\t\tthis.loadCache()\n\t\tthis.scheduleSave()\n\t}\n\n\tprivate loadCache(): void {\n\t\tif (!this.db) return\n\t\tconst cache = new Map<string, CronJob>()\n\n\t\tconst result = this.db.exec(\n\t\t\t\"SELECT id, agent_id, session_key, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms, schedule, session_target, wake_mode, payload, delivery, state FROM cron_jobs\"\n\t\t)\n\n\t\tconst firstResult = result[0]\n\t\tif (firstResult) {\n\t\t\tfor (const row of firstResult.values) {\n\t\t\t\tconst job = this.rowToJob(row as unknown[])\n\t\t\t\tif (job) {\n\t\t\t\t\tcache.set(job.id, job)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.jobsCache = cache\n\t}\n\n\tprivate scheduleSave(): void {\n\t\tif (this.saveTimer) {\n\t\t\tclearTimeout(this.saveTimer)\n\t\t}\n\n\t\tthis.saveTimer = setTimeout(() => {\n\t\t\tvoid this.save()\n\t\t}, 1000)\n\t}\n\n\tasync save(): Promise<void> {\n\t\tif (!this.db || !this.dirty) return\n\n\t\tconst data = this.db.export()\n\t\tthis.dirty = false\n\n\t\tif (this.onSave) {\n\t\t\tawait this.onSave(data)\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.saveTimer) {\n\t\t\tclearTimeout(this.saveTimer)\n\t\t}\n\t\tawait this.save()\n\t\tthis.db?.close()\n\t\tthis.db = null\n\t\tthis.jobsCache = null\n\t}\n\n\tprivate rowToJob(row: unknown[]): CronJob | null {\n\t\ttry {\n\t\t\tconst schedule = JSON.parse(String(row[9])) as CronSchedule\n\t\t\tconst payload = JSON.parse(String(row[12])) as CronPayload\n\t\t\tconst delivery = row[13] ? JSON.parse(String(row[13])) : undefined\n\t\t\tconst state = JSON.parse(String(row[14])) as CronJobState\n\n\t\t\treturn {\n\t\t\t\tid: String(row[0]),\n\t\t\t\tagentId: row[1] ? String(row[1]) : undefined,\n\t\t\t\tsessionKey: row[2] ? String(row[2]) : undefined,\n\t\t\t\tname: String(row[3]),\n\t\t\t\tdescription: row[4] ? String(row[4]) : undefined,\n\t\t\t\tenabled: Boolean(row[5]),\n\t\t\t\tdeleteAfterRun: row[6] ? Boolean(row[6]) : undefined,\n\t\t\t\tcreatedAtMs: Number(row[7]),\n\t\t\t\tupdatedAtMs: Number(row[8]),\n\t\t\t\tschedule,\n\t\t\t\tsessionTarget: (row[10] as SessionTarget) ?? \"isolated\",\n\t\t\t\twakeMode: (row[11] as WakeMode) ?? \"now\",\n\t\t\t\tpayload,\n\t\t\t\tdelivery,\n\t\t\t\tstate\n\t\t\t}\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t}\n\n\tprivate jobToRow(job: CronJob): unknown[] {\n\t\treturn [\n\t\t\tjob.id,\n\t\t\tjob.agentId ?? null,\n\t\t\tjob.sessionKey ?? null,\n\t\t\tjob.name,\n\t\t\tjob.description ?? null,\n\t\t\tjob.enabled ? 1 : 0,\n\t\t\tjob.deleteAfterRun ? 1 : null,\n\t\t\tjob.createdAtMs,\n\t\t\tjob.updatedAtMs,\n\t\t\tJSON.stringify(job.schedule),\n\t\t\tjob.sessionTarget,\n\t\t\tjob.wakeMode,\n\t\t\tJSON.stringify(job.payload),\n\t\t\tjob.delivery ? JSON.stringify(job.delivery) : null,\n\t\t\tJSON.stringify(job.state)\n\t\t]\n\t}\n\n\tprivate ensureDb(): SqlJsDatabase {\n\t\tif (!this.db) {\n\t\t\tthrow new Error(\"Store not initialized. Call init() first.\")\n\t\t}\n\t\treturn this.db\n\t}\n\n\tprivate ensureCache(): Map<string, CronJob> {\n\t\tif (!this.jobsCache) {\n\t\t\tthrow new Error(\"Cache not initialized. Call init() first.\")\n\t\t}\n\t\treturn this.jobsCache\n\t}\n\n\tgetJobSync(id: string): CronJob | undefined {\n\t\tconst cache = this.ensureCache()\n\t\treturn cache.get(id)\n\t}\n\n\tgetAllJobsSync(): CronJob[] {\n\t\tconst cache = this.ensureCache()\n\t\treturn Array.from(cache.values())\n\t}\n\n\tsaveJobSync(job: CronJob): void {\n\t\tconst db = this.ensureDb()\n\t\tconst cache = this.ensureCache()\n\n\t\tdb.run(\n\t\t\t`INSERT OR REPLACE INTO cron_jobs \n (id, agent_id, session_key, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms, schedule, session_target, wake_mode, payload, delivery, state) \n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\tthis.jobToRow(job)\n\t\t)\n\n\t\tcache.set(job.id, job)\n\t\tthis.dirty = true\n\t\tthis.scheduleSave()\n\t}\n\n\tsaveAllJobsSync(): void {\n\t\tconst db = this.ensureDb()\n\t\tconst cache = this.ensureCache()\n\n\t\tfor (const job of cache.values()) {\n\t\t\tdb.run(\n\t\t\t\t`INSERT OR REPLACE INTO cron_jobs \n (id, agent_id, session_key, name, description, enabled, delete_after_run, created_at_ms, updated_at_ms, schedule, session_target, wake_mode, payload, delivery, state) \n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t\tthis.jobToRow(job)\n\t\t\t)\n\t\t}\n\n\t\tthis.dirty = true\n\t\tthis.scheduleSave()\n\t}\n\n\tdeleteJobSync(id: string): void {\n\t\tconst db = this.ensureDb()\n\t\tconst cache = this.ensureCache()\n\n\t\tdb.run(\"DELETE FROM cron_jobs WHERE id = ?\", [id])\n\t\tcache.delete(id)\n\t\tthis.dirty = true\n\t\tthis.scheduleSave()\n\t}\n\n\tasync getTask(id: string): Promise<CronJob | undefined> {\n\t\treturn this.getJobSync(id)\n\t}\n\n\tasync getAllTasks(): Promise<CronJob[]> {\n\t\treturn this.getAllJobsSync()\n\t}\n\n\tasync saveTask(task: CronJob): Promise<void> {\n\t\tthis.saveJobSync(task)\n\t}\n\n\tasync deleteTask(id: string): Promise<void> {\n\t\tthis.deleteJobSync(id)\n\t}\n}\n\nexport async function createSqliteStore(\n\toptions?: SqliteSchedulerStoreOptions\n): Promise<SqliteSchedulerStore> {\n\tconst resolvedOptions = { ...options }\n\n\t// If a real dbPath is provided but no onSave callback, add a default\n\t// file-write callback so that changes are actually persisted to disk.\n\tif (\n\t\tresolvedOptions.dbPath &&\n\t\tresolvedOptions.dbPath !== \":memory:\" &&\n\t\t!resolvedOptions.onSave\n\t) {\n\t\tconst { writeFileSync } = await import(\"node:fs\")\n\t\tconst { dirname } = await import(\"node:path\")\n\t\tconst { mkdirSync, existsSync } = await import(\"node:fs\")\n\t\tconst dbPath = resolvedOptions.dbPath\n\n\t\t// Ensure the parent directory exists\n\t\tconst dir = dirname(dbPath)\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true })\n\t\t}\n\n\t\tresolvedOptions.onSave = (data: Uint8Array) => {\n\t\t\twriteFileSync(dbPath, data)\n\t\t}\n\t}\n\n\tconst store = new SqliteSchedulerStore(resolvedOptions)\n\tawait store.init()\n\treturn store\n}\n","import type {\n\tCronJob,\n\tCronJobCreate,\n\tCronPayload,\n\tCronSchedule,\n\tSessionTarget,\n\tWakeMode\n} from \"@hybrd/types\"\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\"\nimport { z } from \"zod\"\nimport type { SchedulerService } from \"./index.js\"\n\nconst ScheduleSchema = z.discriminatedUnion(\"kind\", [\n\tz.object({\n\t\tkind: z.literal(\"at\"),\n\t\tat: z.string()\n\t}),\n\tz.object({\n\t\tkind: z.literal(\"every\"),\n\t\teveryMs: z.number().positive(),\n\t\tanchorMs: z.number().optional()\n\t}),\n\tz.object({\n\t\tkind: z.literal(\"cron\"),\n\t\texpr: z.string(),\n\t\ttz: z.string().optional(),\n\t\tstaggerMs: z.number().optional()\n\t})\n])\n\nconst PayloadSchema = z.discriminatedUnion(\"kind\", [\n\tz.object({\n\t\tkind: z.literal(\"systemEvent\"),\n\t\ttext: z.string()\n\t}),\n\tz.object({\n\t\tkind: z.literal(\"agentTurn\"),\n\t\tmessage: z.string(),\n\t\tmodel: z.string().optional(),\n\t\tthinking: z.string().optional(),\n\t\ttimeoutSeconds: z.number().optional(),\n\t\tallowUnsafeExternalContent: z.boolean().optional()\n\t})\n])\n\nconst ScheduleTaskSchema = z.object({\n\tid: z.string().optional(),\n\tagentId: z.string().optional(),\n\tsessionKey: z.string().optional(),\n\tname: z.string(),\n\tdescription: z.string().optional(),\n\tenabled: z.boolean().optional(),\n\tdeleteAfterRun: z.boolean().optional(),\n\tschedule: ScheduleSchema,\n\tsessionTarget: z.enum([\"main\", \"isolated\"]).optional(),\n\twakeMode: z.enum([\"now\", \"next-heartbeat\"]).optional(),\n\tpayload: PayloadSchema,\n\tdelivery: z\n\t\t.object({\n\t\t\tmode: z.enum([\"none\", \"announce\"]),\n\t\t\tchannel: z.string().optional(),\n\t\t\tto: z.string().optional(),\n\t\t\taccountId: z.string().optional(),\n\t\t\tbestEffort: z.boolean().optional()\n\t\t})\n\t\t.optional()\n})\n\nconst ListTasksSchema = z\n\t.object({\n\t\tincludeDisabled: z.boolean().optional(),\n\t\tlimit: z.number().optional(),\n\t\toffset: z.number().optional(),\n\t\tquery: z.string().optional(),\n\t\tenabled: z.enum([\"all\", \"enabled\", \"disabled\"]).optional(),\n\t\tsortBy: z.enum([\"nextRunAtMs\", \"updatedAtMs\", \"name\"]).optional(),\n\t\tsortDir: z.enum([\"asc\", \"desc\"]).optional()\n\t})\n\t.optional()\n\nconst CancelTaskSchema = z.object({\n\ttaskId: z.string()\n})\n\nconst GetTaskSchema = z.object({\n\ttaskId: z.string()\n})\n\nconst RunTaskSchema = z.object({\n\ttaskId: z.string(),\n\tmode: z.enum([\"due\", \"force\"]).optional()\n})\n\ninterface SchedulerTool {\n\tname: string\n\tdescription: string\n\tinputSchema: z.ZodTypeAny\n\thandler: (args: unknown) => Promise<CallToolResult>\n}\n\nfunction formatSchedule(schedule: CronSchedule): string {\n\tswitch (schedule.kind) {\n\t\tcase \"at\":\n\t\t\treturn `at ${schedule.at}`\n\t\tcase \"every\":\n\t\t\treturn `every ${schedule.everyMs}ms`\n\t\tcase \"cron\":\n\t\t\treturn `cron ${schedule.expr}${schedule.tz ? ` (${schedule.tz})` : \"\"}`\n\t}\n}\n\nfunction formatJob(job: CronJob): Record<string, unknown> {\n\treturn {\n\t\tid: job.id,\n\t\tname: job.name,\n\t\tdescription: job.description,\n\t\tenabled: job.enabled,\n\t\tschedule: formatSchedule(job.schedule),\n\t\tsessionTarget: job.sessionTarget,\n\t\twakeMode: job.wakeMode,\n\t\tpayload: job.payload,\n\t\tdelivery: job.delivery,\n\t\tstate: {\n\t\t\tnextRunAtMs: job.state.nextRunAtMs,\n\t\t\tlastRunAtMs: job.state.lastRunAtMs,\n\t\t\tlastRunStatus: job.state.lastRunStatus,\n\t\t\tlastError: job.state.lastError,\n\t\t\tconsecutiveErrors: job.state.consecutiveErrors\n\t\t}\n\t}\n}\n\nexport function createSchedulerTools(\n\tscheduler: SchedulerService\n): SchedulerTool[] {\n\treturn [\n\t\t{\n\t\t\tname: \"schedule_task\",\n\t\t\tdescription: `Schedule a task to run at a specific time or interval.\n\nExamples:\n- One-time: { schedule: { kind: \"at\", at: \"2026-03-01T09:00:00Z\" }, payload: { kind: \"agentTurn\", message: \"Check on the project\" } }\n- Interval: { schedule: { kind: \"every\", everyMs: 300000 }, payload: { kind: \"agentTurn\", message: \"Status check\" } }\n- Cron: { schedule: { kind: \"cron\", expr: \"0 9 * * 1-5\" }, payload: { kind: \"agentTurn\", message: \"Daily standup reminder\" } }`,\n\t\t\tinputSchema: ScheduleTaskSchema,\n\t\t\thandler: async (args): Promise<CallToolResult> => {\n\t\t\t\tconst parsed = ScheduleTaskSchema.safeParse(args)\n\t\t\t\tif (!parsed.success) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t\terror: parsed.error.message\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst input: CronJobCreate = {\n\t\t\t\t\t\tid: parsed.data.id,\n\t\t\t\t\t\tagentId: parsed.data.agentId,\n\t\t\t\t\t\tsessionKey: parsed.data.sessionKey,\n\t\t\t\t\t\tname: parsed.data.name,\n\t\t\t\t\t\tdescription: parsed.data.description,\n\t\t\t\t\t\tenabled: parsed.data.enabled,\n\t\t\t\t\t\tdeleteAfterRun: parsed.data.deleteAfterRun,\n\t\t\t\t\t\tschedule: parsed.data.schedule as CronSchedule,\n\t\t\t\t\t\tsessionTarget: parsed.data.sessionTarget as\n\t\t\t\t\t\t\t| SessionTarget\n\t\t\t\t\t\t\t| undefined,\n\t\t\t\t\t\twakeMode: parsed.data.wakeMode as WakeMode | undefined,\n\t\t\t\t\t\tpayload: parsed.data.payload as CronPayload,\n\t\t\t\t\t\tdelivery: parsed.data.delivery\n\t\t\t\t\t}\n\t\t\t\t\tconst job = await scheduler.add(input)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\t\tjobId: job.id,\n\t\t\t\t\t\t\t\t\tname: job.name,\n\t\t\t\t\t\t\t\t\tnextRunAtMs: job.state.nextRunAtMs\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\t\t\terr instanceof Error\n\t\t\t\t\t\t\t\t\t\t\t? err.message\n\t\t\t\t\t\t\t\t\t\t\t: \"Failed to schedule task\"\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname: \"list_scheduled_tasks\",\n\t\t\tdescription:\n\t\t\t\t\"List all scheduled tasks with optional filtering and pagination\",\n\t\t\tinputSchema: ListTasksSchema,\n\t\t\thandler: async (args): Promise<CallToolResult> => {\n\t\t\t\tconst parsed = ListTasksSchema.safeParse(args)\n\t\t\t\tif (!parsed.success) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({ error: parsed.error.message })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst result = await scheduler.listPage(parsed.data)\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\titems: result.items.map(formatJob),\n\t\t\t\t\t\t\t\ttotal: result.total,\n\t\t\t\t\t\t\t\toffset: result.offset,\n\t\t\t\t\t\t\t\tlimit: result.limit,\n\t\t\t\t\t\t\t\thasMore: result.hasMore\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname: \"get_scheduled_task\",\n\t\t\tdescription: \"Get details of a specific scheduled task\",\n\t\t\tinputSchema: GetTaskSchema,\n\t\t\thandler: async (args): Promise<CallToolResult> => {\n\t\t\t\tconst parsed = GetTaskSchema.safeParse(args)\n\t\t\t\tif (!parsed.success) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({ error: parsed.error.message })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst job = await scheduler.get(parsed.data.taskId)\n\t\t\t\tif (!job) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({ error: \"Task not found\" })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: JSON.stringify(formatJob(job), null, 2)\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname: \"cancel_scheduled_task\",\n\t\t\tdescription: \"Cancel and remove a scheduled task\",\n\t\t\tinputSchema: CancelTaskSchema,\n\t\t\thandler: async (args): Promise<CallToolResult> => {\n\t\t\t\tconst parsed = CancelTaskSchema.safeParse(args)\n\t\t\t\tif (!parsed.success) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t\terror: parsed.error.message\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await scheduler.remove(parsed.data.taskId)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\t\tremoved: result.removed\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\t\t\terr instanceof Error ? err.message : \"Failed to cancel task\"\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tname: \"run_scheduled_task\",\n\t\t\tdescription: \"Manually trigger a scheduled task to run now\",\n\t\t\tinputSchema: RunTaskSchema,\n\t\t\thandler: async (args): Promise<CallToolResult> => {\n\t\t\t\tconst parsed = RunTaskSchema.safeParse(args)\n\t\t\t\tif (!parsed.success) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t\terror: parsed.error.message\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await scheduler.run(\n\t\t\t\t\t\tparsed.data.taskId,\n\t\t\t\t\t\tparsed.data.mode\n\t\t\t\t\t)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify(result)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\t\t\terr instanceof Error ? err.message : \"Failed to run task\"\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n\nexport type { SchedulerTool }\n"],"mappings":"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","names":["dirname"]}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@hybrd/scheduler",
3
+ "version": "2.0.0",
4
+ "keywords": [
5
+ "scheduler",
6
+ "cron",
7
+ "agent",
8
+ "tasks",
9
+ "hybrid"
10
+ ],
11
+ "type": "module",
12
+ "files": [
13
+ "dist",
14
+ "src"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js",
20
+ "require": "./dist/index.cjs"
21
+ }
22
+ },
23
+ "dependencies": {
24
+ "cron-parser": "^4.9.0",
25
+ "sql.js": "^1.11.0",
26
+ "@hybrd/types": "2.0.0"
27
+ },
28
+ "peerDependencies": {
29
+ "@anthropic-ai/claude-agent-sdk": ">=0.2.38",
30
+ "@modelcontextprotocol/sdk": ">=1.0.0",
31
+ "zod": ">=3.0.0 || >=4.0.0"
32
+ },
33
+ "peerDependenciesMeta": {
34
+ "@anthropic-ai/claude-agent-sdk": {
35
+ "optional": true
36
+ },
37
+ "@modelcontextprotocol/sdk": {
38
+ "optional": true
39
+ },
40
+ "zod": {
41
+ "optional": true
42
+ }
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "22.8.6",
46
+ "tsup": "^8.5.0",
47
+ "vitest": "^3.2.4",
48
+ "@config/biome": "0.0.0",
49
+ "@config/tsconfig": "0.0.0"
50
+ },
51
+ "scripts": {
52
+ "build": "tsup",
53
+ "build:watch": "tsup --watch",
54
+ "clean": "rm -rf .turbo dist",
55
+ "test": "vitest run",
56
+ "test:watch": "vitest",
57
+ "typecheck": "tsc --noEmit",
58
+ "lint": "biome lint --unsafe",
59
+ "lint:fix": "biome lint --write --unsafe",
60
+ "format": "biome format --write"
61
+ }
62
+ }