{"version":3,"sources":["../src/tools/scheduler.ts"],"names":["get","set","tool","z","j"],"mappings":"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","file":"chunk-OA4KE5BQ.cjs","sourcesContent":["/**\n * Scheduler — cron-like recurring tasks + notification support.\n * Simpler than full cron: supports interval_ms (recurring) + run_at (one-shot).\n * Inspired by devduck scheduler + tasks tools.\n */\nimport { tool } from '@strands-agents/sdk'\nimport { z } from 'zod'\nimport { get, set, del } from 'idb-keyval'\n\nconst SCHED_KEY = 'careless-scheduler'\n\nexport interface ScheduledJob {\n  id: string\n  name: string\n  prompt: string\n  createdAt: number\n  /** One-shot timestamp (ms) */\n  runAt?: number\n  /** Recurring interval */\n  intervalMs?: number\n  /** Last fire time */\n  lastFiredAt?: number\n  /** Fire count */\n  fireCount: number\n  enabled: boolean\n  /** If true, also trigger system notification when firing */\n  notify?: boolean\n}\n\nasync function loadJobs(): Promise<ScheduledJob[]> {\n  const j = await get<ScheduledJob[]>(SCHED_KEY)\n  return Array.isArray(j) ? j : []\n}\nasync function saveJobs(jobs: ScheduledJob[]) { await set(SCHED_KEY, jobs) }\n\n/** Start the scheduler loop. Called once on app boot. */\nlet schedulerIntervalId: number | null = null\nexport function startScheduler() {\n  if (schedulerIntervalId) return\n  const tick = async () => {\n    const now = Date.now()\n    const jobs = await loadJobs()\n    let dirty = false\n    for (const job of jobs) {\n      if (!job.enabled) continue\n      let shouldFire = false\n      if (job.runAt && now >= job.runAt && !job.lastFiredAt) shouldFire = true\n      else if (job.intervalMs) {\n        const since = job.lastFiredAt ? now - job.lastFiredAt : now - job.createdAt\n        if (since >= job.intervalMs) shouldFire = true\n      }\n      if (shouldFire) {\n        job.lastFiredAt = now\n        job.fireCount = (job.fireCount || 0) + 1\n        dirty = true\n        window.dispatchEvent(new CustomEvent('careless:task-fire', { detail: job }))\n        if (job.notify && 'Notification' in window && Notification.permission === 'granted') {\n          try { new Notification('careless', { body: job.name + ': ' + job.prompt.slice(0, 140) }) } catch {}\n        }\n        // One-shot jobs disable themselves\n        if (job.runAt && !job.intervalMs) job.enabled = false\n      }\n    }\n    if (dirty) await saveJobs(jobs)\n  }\n  schedulerIntervalId = window.setInterval(tick, 5000) as any\n  tick()\n}\n\nexport const scheduleJobTool = tool({\n  name: 'scheduler_create',\n  description: 'Schedule a recurring or one-shot task. Provide interval_ms for recurring, run_at (unix ms) for one-shot. The task prompt fires the agent when its time comes.',\n  inputSchema: z.object({\n    name: z.string(),\n    prompt: z.string(),\n    interval_ms: z.number().optional(),\n    run_at: z.number().optional(),\n    notify: z.boolean().optional(),\n  }),\n  callback: async (input) => {\n    if (!input.interval_ms && !input.run_at) {\n      return JSON.stringify({ status: 'error', error: 'Must provide interval_ms or run_at' })\n    }\n    const jobs = await loadJobs()\n    const job: ScheduledJob = {\n      id: 'job-' + Math.random().toString(36).slice(2, 10),\n      name: input.name,\n      prompt: input.prompt,\n      createdAt: Date.now(),\n      runAt: input.run_at,\n      intervalMs: input.interval_ms,\n      fireCount: 0,\n      enabled: true,\n      notify: input.notify,\n    }\n    jobs.push(job)\n    await saveJobs(jobs)\n    if (input.notify && 'Notification' in window && Notification.permission === 'default') {\n      Notification.requestPermission()\n    }\n    return JSON.stringify({ status: 'created', job })\n  },\n})\n\nexport const listJobsTool = tool({\n  name: 'scheduler_list',\n  description: 'List all scheduled jobs.',\n  inputSchema: z.object({}),\n  callback: async () => {\n    const jobs = await loadJobs()\n    return JSON.stringify({ status: 'success', count: jobs.length, jobs })\n  },\n})\n\nexport const deleteJobTool = tool({\n  name: 'scheduler_delete',\n  description: 'Delete a scheduled job by ID.',\n  inputSchema: z.object({ id: z.string() }),\n  callback: async (input) => {\n    const jobs = await loadJobs()\n    const filtered = jobs.filter(j => j.id !== input.id)\n    await saveJobs(filtered)\n    return JSON.stringify({ status: 'deleted', remaining: filtered.length })\n  },\n})\n\nexport const toggleJobTool = tool({\n  name: 'scheduler_toggle',\n  description: 'Enable or disable a scheduled job.',\n  inputSchema: z.object({ id: z.string(), enabled: z.boolean() }),\n  callback: async (input) => {\n    const jobs = await loadJobs()\n    const j = jobs.find(j => j.id === input.id)\n    if (!j) return JSON.stringify({ status: 'error', error: 'not found' })\n    j.enabled = input.enabled\n    await saveJobs(jobs)\n    return JSON.stringify({ status: 'updated', job: j })\n  },\n})\n\nexport const notifyTool = tool({\n  name: 'notify_push',\n  description: 'Send a push notification (uses Notification API). Requests permission if needed.',\n  inputSchema: z.object({\n    title: z.string(),\n    body: z.string().optional(),\n    icon: z.string().optional(),\n    vibrate: z.boolean().optional(),\n  }),\n  callback: async (input) => {\n    if (!('Notification' in window)) return JSON.stringify({ status: 'unsupported' })\n    if (Notification.permission === 'default') {\n      const perm = await Notification.requestPermission()\n      if (perm !== 'granted') return JSON.stringify({ status: 'permission_denied', perm })\n    }\n    if (Notification.permission !== 'granted') return JSON.stringify({ status: 'permission_denied' })\n    try {\n      new Notification(input.title, { body: input.body, icon: input.icon })\n      if (input.vibrate && (navigator as any).vibrate) (navigator as any).vibrate([100, 50, 100])\n      return JSON.stringify({ status: 'sent' })\n    } catch (err: unknown) {\n      return JSON.stringify({ status: 'error', error: (err as Error).message })\n    }\n  },\n})\n\nexport const SCHEDULER_TOOLS = [scheduleJobTool, listJobsTool, deleteJobTool, toggleJobTool, notifyTool]\n"]}