@xopcai/xopc 0.0.52 → 0.0.54

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.
Files changed (43) hide show
  1. package/dist/extensions/telegram/xopc.extension.json +1 -1
  2. package/dist/gateway/static/root/assets/{agents-CLNe-mJX.js → agents-Cccit5xQ.js} +2 -2
  3. package/dist/gateway/static/root/assets/{agents-CLNe-mJX.js.map → agents-Cccit5xQ.js.map} +1 -1
  4. package/dist/gateway/static/root/assets/{apps-page-c5XF02ek.js → apps-page-JMpsr3yK.js} +2 -2
  5. package/dist/gateway/static/root/assets/{apps-page-c5XF02ek.js.map → apps-page-JMpsr3yK.js.map} +1 -1
  6. package/dist/gateway/static/root/assets/{channels-settings-BTgdsBM4.js → channels-settings-jJX9xOyE.js} +2 -2
  7. package/dist/gateway/static/root/assets/{channels-settings-BTgdsBM4.js.map → channels-settings-jJX9xOyE.js.map} +1 -1
  8. package/dist/gateway/static/root/assets/{cron-dreaming-jobs-CiQJHx3s.js → cron-dreaming-jobs-DousYqF2.js} +2 -2
  9. package/dist/gateway/static/root/assets/{cron-dreaming-jobs-CiQJHx3s.js.map → cron-dreaming-jobs-DousYqF2.js.map} +1 -1
  10. package/dist/gateway/static/root/assets/{cron-page-DJOj7JWb.js → cron-page-CdYb690n.js} +2 -2
  11. package/dist/gateway/static/root/assets/{cron-page-DJOj7JWb.js.map → cron-page-CdYb690n.js.map} +1 -1
  12. package/dist/gateway/static/root/assets/{dist-BY3E71wk.js → dist-D8QibYZR.js} +2 -2
  13. package/dist/gateway/static/root/assets/{dist-BY3E71wk.js.map → dist-D8QibYZR.js.map} +1 -1
  14. package/dist/gateway/static/root/assets/{extension-debug-page-DzkYBiW-.js → extension-debug-page-DJ-puhUh.js} +2 -2
  15. package/dist/gateway/static/root/assets/{extension-debug-page-DzkYBiW-.js.map → extension-debug-page-DJ-puhUh.js.map} +1 -1
  16. package/dist/gateway/static/root/assets/{extension-page-yF0LIy5D.js → extension-page-DgDGH7uc.js} +2 -2
  17. package/dist/gateway/static/root/assets/{extension-page-yF0LIy5D.js.map → extension-page-DgDGH7uc.js.map} +1 -1
  18. package/dist/gateway/static/root/assets/{extension-settings-page-CS_Y4y3w.js → extension-settings-page-BnQ2f4Fq.js} +2 -2
  19. package/dist/gateway/static/root/assets/{extension-settings-page-CS_Y4y3w.js.map → extension-settings-page-BnQ2f4Fq.js.map} +1 -1
  20. package/dist/gateway/static/root/assets/{heartbeat-config-api-DD2LdM_Q.js → heartbeat-config-api-B9hxMalj.js} +2 -2
  21. package/dist/gateway/static/root/assets/{heartbeat-config-api-DD2LdM_Q.js.map → heartbeat-config-api-B9hxMalj.js.map} +1 -1
  22. package/dist/gateway/static/root/assets/{index-V5ZnG6RE.js → index-8IFT6i7x.js} +4 -4
  23. package/dist/gateway/static/root/assets/{index-V5ZnG6RE.js.map → index-8IFT6i7x.js.map} +1 -1
  24. package/dist/gateway/static/root/assets/{logs-page-D79WclZL.js → logs-page-DNHn8mTk.js} +2 -2
  25. package/dist/gateway/static/root/assets/{logs-page-D79WclZL.js.map → logs-page-DNHn8mTk.js.map} +1 -1
  26. package/dist/gateway/static/root/assets/{sessions-page-R_QJy3OK.js → sessions-page-D3kE1tob.js} +2 -2
  27. package/dist/gateway/static/root/assets/{sessions-page-R_QJy3OK.js.map → sessions-page-D3kE1tob.js.map} +1 -1
  28. package/dist/gateway/static/root/assets/{settings-page-CGaj_9Qb.js → settings-page-B4tuVOtd.js} +2 -2
  29. package/dist/gateway/static/root/assets/{settings-page-CGaj_9Qb.js.map → settings-page-B4tuVOtd.js.map} +1 -1
  30. package/dist/gateway/static/root/assets/{skills-page-UzbTgnVY.js → skills-page-Dgd20nUt.js} +2 -2
  31. package/dist/gateway/static/root/assets/{skills-page-UzbTgnVY.js.map → skills-page-Dgd20nUt.js.map} +1 -1
  32. package/dist/gateway/static/root/assets/{use-image-provider-credentials-DAx__u3a.js → use-image-provider-credentials-CqMkyIiU.js} +2 -2
  33. package/dist/gateway/static/root/assets/{use-image-provider-credentials-DAx__u3a.js.map → use-image-provider-credentials-CqMkyIiU.js.map} +1 -1
  34. package/dist/gateway/static/root/index.html +1 -1
  35. package/dist/package.js +1 -1
  36. package/dist/src/browser/providers/extension.js +37 -3
  37. package/dist/src/browser/providers/extension.js.map +1 -1
  38. package/dist/src/gateway/security/csp.d.ts +1 -0
  39. package/dist/src/gateway/security/csp.js +2 -0
  40. package/dist/src/gateway/security/csp.js.map +1 -1
  41. package/dist/src/gateway/service.js +13 -4
  42. package/dist/src/gateway/service.js.map +1 -1
  43. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cron-page-DJOj7JWb.js","names":[],"sources":["../../../../../web/src/features/cron/cron-confirm-action-dialog.tsx","../../../../../web/src/features/cron/cron-page-lib.ts","../../../../../web/src/features/cron/cron-job-detail-drawer.tsx","../../../../../web/src/features/cron/cron-schedule-form.tsx","../../../../../web/src/features/cron/cron-job-form-dialog.tsx","../../../../../web/src/features/cron/cron-main-toolbar.tsx","../../../../../web/src/features/cron/cron-page-header-actions.tsx","../../../../../web/src/features/cron/cron-run-history-section.tsx","../../../../../web/src/features/cron/cron-job-card.tsx","../../../../../web/src/features/cron/cron-system-tasks-panel.tsx","../../../../../web/src/features/cron/cron-template-i18n.ts","../../../../../web/src/features/cron/cron-templates.ts","../../../../../web/src/features/cron/cron-template-library.tsx","../../../../../web/src/features/cron/cron-tasks-panel.tsx","../../../../../web/src/features/cron/cron-template-picker-dialog.tsx","../../../../../web/src/features/cron/cron-page.tsx"],"sourcesContent":["import * as Dialog from '@radix-ui/react-dialog';\n\nimport { Button } from '@/components/ui/button';\nimport type { MessageBundle } from '@/i18n/messages';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronConfirmActionDialogProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n action: 'delete' | 'run' | null;\n c: CronCopy;\n onDismiss: () => void;\n onConfirm: () => void;\n};\n\nexport function CronConfirmActionDialog({\n open,\n onOpenChange,\n action,\n c,\n onDismiss,\n onConfirm,\n}: CronConfirmActionDialogProps) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[70] bg-scrim\" />\n <div className=\"fixed inset-0 z-[70] flex items-center justify-center p-4 pointer-events-none\">\n <Dialog.Content className=\"xopc-dialog-content-pane pointer-events-auto relative w-full max-w-md rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge\">\n <Dialog.Title className=\"text-base font-semibold text-fg\">\n {action === 'delete' ? c.delete : c.runNow}\n </Dialog.Title>\n <p className=\"mt-2 text-sm text-fg-muted\">\n {action === 'delete' ? c.confirmDelete : c.confirmRun}\n </p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button type=\"button\" variant=\"secondary\" onClick={onDismiss}>\n {c.cancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n className={action === 'delete' ? 'bg-red-600 hover:bg-red-700' : undefined}\n onClick={() => void onConfirm()}\n >\n {action === 'delete' ? c.delete : c.runNow}\n </Button>\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import {\n formControlBorderFocusClass,\n nativeSelectMaxWidthClass,\n selectControlBaseClass,\n} from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\n\nexport const RUN_HISTORY_FETCH_LIMIT = 400;\n\nexport const DEFAULT_SCHEDULE = '*/5 * * * *';\n\n/** Same storage key as chat composer so recent folders stay in sync. */\nexport const RECENT_WD_STORAGE_KEY = 'xopc.recentWorkspaceDirs.v1';\nexport const RECENT_WD_MAX = 10;\n\nexport function startOfLocalDay(d: Date): Date {\n const x = new Date(d);\n x.setHours(0, 0, 0, 0);\n return x;\n}\n\n/** Week starts on Monday (local). */\nexport function startOfLocalWeekMonday(d: Date): Date {\n const x = startOfLocalDay(d);\n const day = x.getDay();\n const diff = day === 0 ? -6 : 1 - day;\n x.setDate(x.getDate() + diff);\n return x;\n}\n\nexport function startOfLocalMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), 1, 0, 0, 0, 0);\n}\n\nexport function navigateToSessionChat(sessionKey: string | undefined | null): void {\n const sk = sessionKey?.trim();\n if (!sk) return;\n window.dispatchEvent(\n new CustomEvent('navigate-to-chat', { detail: { sessionKey: sk }, bubbles: true }),\n );\n}\n\nexport function pushRecentWorkspaceDirForCron(path: string): void {\n const t = path.trim();\n if (!t) return;\n try {\n const raw = localStorage.getItem(RECENT_WD_STORAGE_KEY);\n const parsed = raw ? (JSON.parse(raw) as unknown) : [];\n const prev = Array.isArray(parsed)\n ? parsed.filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n : [];\n const next = [t, ...prev.filter((p) => p !== t)].slice(0, RECENT_WD_MAX);\n localStorage.setItem(RECENT_WD_STORAGE_KEY, JSON.stringify(next));\n } catch {\n /* ignore */\n }\n}\n\nexport function inputClassName(disabled?: boolean): string {\n return cn(\n 'w-full rounded-md border border-edge bg-surface-base px-3 py-2 text-sm text-fg placeholder:text-fg-disabled',\n formControlBorderFocusClass,\n disabled && 'cursor-not-allowed opacity-60',\n );\n}\n\nexport function selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nexport const cronRecipientSelectClass = cn(\n selectControlBaseClass,\n 'w-full text-xs sm:w-auto sm:min-w-[11rem] sm:max-w-[17rem] sm:shrink-0',\n);\n\n/** Toolbar filters: avoid `w-full` from {@link nativeSelectMaxWidthClass} so Day/Week/Month + selects stay one row. */\nexport const cronToolbarSelectClass = cn(\n selectControlBaseClass,\n 'w-auto min-w-[9rem] max-w-[14rem] shrink-0 text-xs',\n);\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { Loader2, X } from 'lucide-react';\n\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { Button } from '@/components/ui/button';\nimport type { CronJob, CronJobExecution } from '@/features/cron/cron-api';\nimport { cronJobBodyText } from '@/features/cron/cron-api';\nimport { navigateToSessionChat } from '@/features/cron/cron-page-lib';\nimport {\n execStatusLabel,\n formatDeliveryToSummary,\n formatDuration,\n formatNextRun,\n formatTime,\n truncate,\n} from '@/features/cron/cron-utils';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronJobDetailDrawerProps = {\n open: boolean;\n onDismiss: () => void;\n detailJob: CronJob | null;\n detailLoading: boolean;\n detailHistory: CronJobExecution[];\n c: CronCopy;\n chatWorkingDirNotSet: string;\n statusLabels: {\n running: string;\n success: string;\n failed: string;\n cancelled: string;\n };\n};\n\nexport function CronJobDetailDrawer({\n open,\n onDismiss,\n detailJob,\n detailLoading,\n detailHistory,\n c,\n chatWorkingDirNotSet,\n statusLabels,\n}: CronJobDetailDrawerProps) {\n return (\n <Dialog.Root\n open={open}\n onOpenChange={(next) => {\n if (!next) onDismiss();\n }}\n >\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-drawer-right fixed right-0 top-0 z-[60] flex h-full w-full max-w-lg flex-col border-l border-edge bg-surface-panel shadow-popover outline-none',\n 'dark:border-edge',\n )}\n aria-describedby={undefined}\n >\n <div className=\"flex shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3\">\n <Dialog.Title className=\"min-w-0 truncate text-base font-semibold text-fg\">\n {detailJob?.name?.trim() || detailJob?.id || '—'}\n </Dialog.Title>\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"h-9 w-9 shrink-0 p-0\" aria-label={c.close}>\n <X className=\"size-5\" strokeWidth={1.75} />\n </Button>\n </Dialog.Close>\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-3\">\n {detailLoading ? (\n <div className=\"flex justify-center py-16\">\n <Loader2 className=\"size-8 animate-spin text-accent\" strokeWidth={1.75} />\n </div>\n ) : detailJob ? (\n <>\n <dl className=\"space-y-3 text-sm\">\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.scheduleLabel}</dt>\n <dd className=\"mt-1 font-mono text-fg\">\n <code>{detailJob.schedule}</code>\n </dd>\n </div>\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.messageLabel}</dt>\n <dd className=\"mt-1 min-w-0 break-words text-fg\">\n <MarkdownView content={cronJobBodyText(detailJob)} compact className=\"text-sm\" />\n </dd>\n </div>\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.mode}</dt>\n <dd className=\"mt-1 text-fg\">\n {detailJob.sessionTarget === 'isolated' ? c.modeAgentOption : c.modeDirectOption}\n </dd>\n </div>\n {detailJob.sessionTarget === 'isolated' ? (\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.agentProfile}</dt>\n <dd className=\"mt-1 font-mono text-sm text-fg\">\n {detailJob.agentId?.trim() ? detailJob.agentId.trim() : c.agentProfileDefault}\n </dd>\n </div>\n ) : null}\n {detailJob.sessionTarget === 'isolated' ? (\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.workingDirectoryLabel}</dt>\n <dd className=\"mt-1 break-all font-mono text-xs text-fg\">\n {detailJob.workingDirectory?.trim()\n ? detailJob.workingDirectory.trim()\n : chatWorkingDirNotSet}\n </dd>\n </div>\n ) : null}\n {detailJob.delivery?.channel === 'local' ||\n (detailJob.sessionTarget === 'isolated' && !detailJob.delivery?.to) ? (\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.deliveryTarget}</dt>\n <dd className=\"mt-1 text-fg\">\n {detailJob.delivery?.channel === 'local'\n ? c.deliveryTargetLocalChannel\n : c.deliveryLocalOnly}\n </dd>\n </div>\n ) : detailJob.delivery?.to ? (\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.deliveryTarget}</dt>\n <dd className=\"mt-1 break-words text-fg\">\n <code className=\"text-xs\">{detailJob.delivery?.channel ?? ''}</code>\n {' → '}\n {formatDeliveryToSummary(detailJob, c.channelLocal)}\n </dd>\n </div>\n ) : null}\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.status}</dt>\n <dd className=\"mt-1 text-fg\">{detailJob.enabled ? c.enabled : c.disabled}</dd>\n </div>\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.nextRun}</dt>\n <dd className=\"mt-1 text-fg\">\n {detailJob.next_run ? formatNextRun(detailJob.next_run, c.timeLabels) : '—'}\n </dd>\n </div>\n </dl>\n <h3 className=\"mt-6 text-sm font-semibold text-fg\">{c.detailRunHistory}</h3>\n {detailHistory.length === 0 ? (\n <p className=\"mt-2 text-sm text-fg-muted\">{c.noRunsYet}</p>\n ) : (\n <div className=\"mt-2 overflow-x-auto\">\n <table className=\"w-full border-collapse text-left text-xs\">\n <thead>\n <tr className=\"border-b border-edge text-fg-muted\">\n <th className=\"py-1.5 pr-2 font-medium\">{c.colStarted}</th>\n <th className=\"py-1.5 pr-2 font-medium\">{c.status}</th>\n <th className=\"py-1.5 pr-2 font-medium\">{c.colDuration}</th>\n <th className=\"py-1.5 pr-2 font-medium\">{c.colDetail}</th>\n <th className=\"py-1.5 font-medium\">{c.colChat}</th>\n </tr>\n </thead>\n <tbody>\n {detailHistory.map((row) => (\n <tr key={row.id} className=\"border-b border-edge/60\">\n <td className=\"whitespace-nowrap py-1.5 pr-2 text-fg\">\n <time dateTime={row.startedAt}>{formatTime(row.startedAt)}</time>\n </td>\n <td className=\"py-1.5 pr-2\">\n <span\n className={cn(\n 'inline-flex rounded px-1.5 py-0.5 font-medium',\n row.status === 'success' &&\n 'bg-emerald-500/15 text-emerald-800 dark:text-emerald-300',\n row.status === 'failed' && 'bg-red-500/15 text-red-800 dark:text-red-300',\n )}\n >\n {execStatusLabel(row.status, statusLabels)}\n </span>\n </td>\n <td className=\"py-1.5 pr-2 text-fg-muted\">{formatDuration(row.duration)}</td>\n <td\n className=\"max-w-[8rem] truncate py-1.5 pr-2 text-fg-muted\"\n title={row.summary || row.error || ''}\n >\n {truncate(row.summary || row.error, 120)}\n </td>\n <td className=\"whitespace-nowrap py-1.5\">\n {row.sessionKey?.trim() ? (\n <button\n type=\"button\"\n className=\"text-xs font-medium text-accent hover:underline\"\n title={c.openChatTitle}\n aria-label={c.openChatTitle}\n onClick={() => navigateToSessionChat(row.sessionKey)}\n >\n {c.openChat}\n </button>\n ) : (\n <span className=\"text-fg-disabled\">—</span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </>\n ) : null}\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import { CronExpressionParser } from 'cron-parser';\nimport { useCallback, useEffect, useMemo, useState, type ChangeEvent } from 'react';\n\nimport { cn } from '@/lib/cn';\nimport { formControlBorderFocusClass, selectControlBaseClass } from '@/lib/form-field-width';\n\n/** Matches design order: 不重复 → 间隔 → 每小时 → 每天 → 每周 → 每月 → 自定义 */\nexport type SchedulePickerMode =\n | 'no_repeat'\n | 'interval'\n | 'hourly'\n | 'daily'\n | 'weekly'\n | 'monthly'\n | 'custom';\n\nexport type IntervalKind = 'minutes' | 'hours';\n\nexport type CronSchedulePickerLabels = {\n scheduleTimeLabel: string;\n modeNoRepeat: string;\n modeInterval: string;\n intervalKindMinutes: string;\n intervalKindHours: string;\n modeHourly: string;\n modeDaily: string;\n modeWeekly: string;\n modeMonthly: string;\n modeCustom: string;\n minuteUnit: string;\n minuteAtHour: string;\n intervalMinutes: string;\n intervalHours: string;\n hourUnit: string;\n dayOfMonth: string;\n customCronHint: string;\n /** Seven labels (Sun–Sat); JSON locales use `string[]` at compile time. */\n weekdays: readonly string[];\n};\n\nconst pickerSelectClass = cn(\n selectControlBaseClass,\n 'min-w-0 shrink text-xs sm:min-w-[7rem] sm:max-w-[11rem]',\n);\n\nconst timeInputClass = cn(\n 'h-9 min-w-[6.5rem] shrink-0 rounded-lg border border-edge-subtle bg-surface-panel px-2 py-1.5 text-sm text-fg',\n formControlBorderFocusClass,\n 'dark:bg-surface-panel',\n);\n\nconst dateInputClass = cn(\n 'h-9 min-w-[9.5rem] shrink-0 rounded-lg border border-edge-subtle bg-surface-panel px-2 py-1.5 text-sm text-fg',\n formControlBorderFocusClass,\n);\n\nconst numberInputClass = cn(\n 'h-9 w-14 shrink-0 rounded-lg border border-edge-subtle bg-surface-panel px-2 py-1.5 text-center text-sm tabular-nums text-fg',\n formControlBorderFocusClass,\n);\n\nconst cronTextareaClass = cn(\n 'min-h-[2.5rem] w-full rounded-lg border border-edge-subtle bg-surface-base px-3 py-2 font-mono text-xs text-fg',\n formControlBorderFocusClass,\n);\n\nfunction defaultTodayYmd(): string {\n const d = new Date();\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;\n}\n\nfunction numericFieldValues(values: unknown): number[] {\n if (!Array.isArray(values)) return [];\n return values.filter((v): v is number => typeof v === 'number').sort((a, b) => a - b);\n}\n\nfunction uniformStep(sorted: number[]): number | null {\n if (sorted.length < 2) return null;\n const step = sorted[1] - sorted[0];\n if (step <= 0) return null;\n for (let i = 2; i < sorted.length; i++) {\n if (sorted[i] - sorted[i - 1] !== step) return null;\n }\n return step;\n}\n\n/** UI week: index 0=Mon … 6=Sun → cron 1–6,0 */\nfunction uiWeekDaysToCron(d: boolean[]): string {\n const parts: number[] = [];\n for (let i = 0; i < 7; i++) {\n if (!d[i]) continue;\n parts.push(i === 6 ? 0 : i + 1);\n }\n if (parts.length === 0) return '1';\n return parts.sort((a, b) => a - b).join(',');\n}\n\nfunction cronDowListToUiWeekDays(cronDows: number[]): boolean[] {\n const out = [false, false, false, false, false, false, false];\n for (const v of cronDows) {\n const js = v === 0 || v === 7 ? 6 : v - 1;\n if (js >= 0 && js <= 6) out[js] = true;\n }\n return out;\n}\n\nexport type PickerState = {\n mode: SchedulePickerMode;\n intervalKind: IntervalKind;\n onceDate: string;\n intervalMinutes: number;\n intervalHours: number;\n minute: number;\n hour: number;\n weekDays: boolean[];\n dayOfMonth: number;\n rawCron: string;\n};\n\nexport function cronExpressionToPickerState(expr: string): PickerState {\n const rawCron = expr.trim();\n const fallback: PickerState = {\n mode: 'custom',\n intervalKind: 'minutes',\n onceDate: defaultTodayYmd(),\n intervalMinutes: 5,\n intervalHours: 2,\n minute: 0,\n hour: 9,\n weekDays: [true, true, true, true, true, false, false],\n dayOfMonth: 1,\n rawCron,\n };\n\n if (!rawCron) return { ...fallback, mode: 'interval', rawCron: '*/5 * * * *' };\n\n try {\n const p = CronExpressionParser.parse(rawCron);\n const f = p.fields;\n const m = numericFieldValues(f.minute.values);\n const h = numericFieldValues(f.hour.values);\n const dom = numericFieldValues(f.dayOfMonth.values);\n const mon = numericFieldValues(f.month.values);\n const dow = numericFieldValues(f.dayOfWeek.values);\n\n if (m.length === 60 && f.hour.isWildcard && f.dayOfMonth.isWildcard && f.month.isWildcard && f.dayOfWeek.isWildcard) {\n return { ...fallback, mode: 'interval', intervalKind: 'minutes', intervalMinutes: 1, rawCron };\n }\n if (\n !f.minute.isWildcard &&\n f.hour.isWildcard &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard &&\n m.length > 1\n ) {\n const step = uniformStep(m);\n if (step != null && step > 0) {\n return { ...fallback, mode: 'interval', intervalKind: 'minutes', intervalMinutes: step, rawCron };\n }\n }\n if (\n !f.minute.isWildcard &&\n m.length === 1 &&\n !f.hour.isWildcard &&\n h.length > 1 &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard\n ) {\n const step = uniformStep(h);\n if (step != null && step > 0) {\n return { ...fallback, mode: 'interval', intervalKind: 'hours', intervalHours: step, minute: m[0], rawCron };\n }\n }\n if (\n !f.minute.isWildcard &&\n m.length === 1 &&\n f.hour.isWildcard &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard &&\n h.length === 24\n ) {\n return { ...fallback, mode: 'hourly', minute: m[0], rawCron };\n }\n\n /** Specific calendar day each year: minute hour dom mon * */\n if (\n m.length === 1 &&\n h.length === 1 &&\n dom.length === 1 &&\n mon.length === 1 &&\n !f.dayOfMonth.isWildcard &&\n !f.month.isWildcard &&\n f.dayOfWeek.isWildcard\n ) {\n const y = new Date().getFullYear();\n const mo = mon[0];\n const d = dom[0];\n const onceDate = `${y}-${String(mo).padStart(2, '0')}-${String(d).padStart(2, '0')}`;\n return {\n ...fallback,\n mode: 'no_repeat',\n minute: m[0],\n hour: h[0],\n onceDate,\n rawCron,\n };\n }\n\n if (\n m.length === 1 &&\n h.length === 1 &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard\n ) {\n return {\n ...fallback,\n mode: 'daily',\n minute: m[0],\n hour: h[0],\n rawCron,\n };\n }\n if (\n m.length === 1 &&\n h.length === 1 &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n !f.dayOfWeek.isWildcard &&\n dow.length > 0\n ) {\n return {\n ...fallback,\n mode: 'weekly',\n minute: m[0],\n hour: h[0],\n weekDays: cronDowListToUiWeekDays(dow),\n rawCron,\n };\n }\n if (\n m.length === 1 &&\n h.length === 1 &&\n !f.dayOfMonth.isWildcard &&\n dom.length === 1 &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard\n ) {\n return {\n ...fallback,\n mode: 'monthly',\n minute: m[0],\n hour: h[0],\n dayOfMonth: dom[0],\n rawCron,\n };\n }\n } catch {\n /* fall through */\n }\n return fallback;\n}\n\nexport function buildCronFromPickerState(s: PickerState): string {\n const clamp = (n: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, n));\n\n switch (s.mode) {\n case 'custom':\n return s.rawCron.trim() || '*/5 * * * *';\n case 'no_repeat': {\n const parts = s.onceDate.split('-');\n if (parts.length === 3) {\n const dom = clamp(parseInt(parts[2], 10), 1, 31);\n const mo = clamp(parseInt(parts[1], 10), 1, 12);\n const min = clamp(s.minute, 0, 59);\n const h = clamp(s.hour, 0, 23);\n return `${min} ${h} ${dom} ${mo} *`;\n }\n return '0 9 1 1 *';\n }\n case 'interval':\n if (s.intervalKind === 'hours') {\n const n = clamp(Math.round(s.intervalHours) || 1, 1, 23);\n const min = clamp(s.minute, 0, 59);\n return `${min} */${n} * * *`;\n }\n {\n const n = clamp(Math.round(s.intervalMinutes) || 5, 1, 59);\n return `*/${n} * * * *`;\n }\n case 'hourly': {\n const min = clamp(s.minute, 0, 59);\n return `${min} * * * *`;\n }\n case 'daily': {\n const min = clamp(s.minute, 0, 59);\n const h = clamp(s.hour, 0, 23);\n return `${min} ${h} * * *`;\n }\n case 'weekly': {\n const min = clamp(s.minute, 0, 59);\n const h = clamp(s.hour, 0, 23);\n const dow = uiWeekDaysToCron(s.weekDays);\n return `${min} ${h} * * ${dow}`;\n }\n case 'monthly': {\n const min = clamp(s.minute, 0, 59);\n const h = clamp(s.hour, 0, 23);\n const dom = clamp(Math.round(s.dayOfMonth) || 1, 1, 31);\n return `${min} ${h} ${dom} * *`;\n }\n default:\n return '*/5 * * * *';\n }\n}\n\ntype CronSchedulePickerProps = {\n value: string;\n onChange: (cron: string) => void;\n labels: CronSchedulePickerLabels;\n disabled?: boolean;\n};\n\nexport function CronSchedulePicker({ value, onChange, labels, disabled }: CronSchedulePickerProps) {\n const parsed = useMemo(() => cronExpressionToPickerState(value), [value]);\n\n const [mode, setMode] = useState<SchedulePickerMode>(parsed.mode);\n const [intervalKind, setIntervalKind] = useState<IntervalKind>(parsed.intervalKind);\n const [onceDate, setOnceDate] = useState(parsed.onceDate);\n const [intervalMinutes, setIntervalMinutes] = useState(parsed.intervalMinutes);\n const [intervalHours, setIntervalHours] = useState(parsed.intervalHours);\n const [minute, setMinute] = useState(parsed.minute);\n const [hour, setHour] = useState(parsed.hour);\n const [weekDays, setWeekDays] = useState<boolean[]>(parsed.weekDays);\n const [dayOfMonth, setDayOfMonth] = useState(parsed.dayOfMonth);\n const [rawCron, setRawCron] = useState(parsed.rawCron);\n const [intervalMinutesDraft, setIntervalMinutesDraft] = useState<string | null>(null);\n const [intervalHoursDraft, setIntervalHoursDraft] = useState<string | null>(null);\n\n useEffect(() => {\n const p = cronExpressionToPickerState(value);\n setMode(p.mode);\n setIntervalKind(p.intervalKind);\n setOnceDate(p.onceDate);\n setIntervalMinutes(p.intervalMinutes);\n setIntervalHours(p.intervalHours);\n setMinute(p.minute);\n setHour(p.hour);\n setWeekDays(p.weekDays);\n setDayOfMonth(p.dayOfMonth);\n setRawCron(p.rawCron);\n setIntervalMinutesDraft(null);\n setIntervalHoursDraft(null);\n }, [value]);\n\n const emit = useCallback(\n (patch: Partial<PickerState>) => {\n const next: PickerState = {\n mode,\n intervalKind,\n onceDate,\n intervalMinutes,\n intervalHours,\n minute,\n hour,\n weekDays,\n dayOfMonth,\n rawCron,\n ...patch,\n };\n onChange(buildCronFromPickerState(next));\n },\n [\n mode,\n intervalKind,\n onceDate,\n intervalMinutes,\n intervalHours,\n minute,\n hour,\n weekDays,\n dayOfMonth,\n rawCron,\n onChange,\n ],\n );\n\n const timeValue = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;\n\n const onTimeChange = (e: ChangeEvent<HTMLInputElement>) => {\n const v = e.target.value;\n if (!v) return;\n const [hh, mm] = v.split(':').map((x) => parseInt(x, 10));\n if (Number.isNaN(hh) || Number.isNaN(mm)) return;\n emit({ minute: mm, hour: hh });\n };\n\n const modeRow = (\n <div className=\"flex min-w-0 flex-nowrap items-center gap-2 overflow-x-auto pb-0.5\">\n <select\n className={pickerSelectClass}\n disabled={disabled}\n value={mode}\n onChange={(e) => {\n const next = e.target.value as SchedulePickerMode;\n setMode(next);\n emit({ mode: next });\n }}\n aria-label={labels.scheduleTimeLabel}\n >\n <option value=\"no_repeat\">{labels.modeNoRepeat}</option>\n <option value=\"interval\">{labels.modeInterval}</option>\n <option value=\"hourly\">{labels.modeHourly}</option>\n <option value=\"daily\">{labels.modeDaily}</option>\n <option value=\"weekly\">{labels.modeWeekly}</option>\n <option value=\"monthly\">{labels.modeMonthly}</option>\n <option value=\"custom\">{labels.modeCustom}</option>\n </select>\n\n {mode === 'no_repeat' && (\n <>\n <input\n type=\"date\"\n disabled={disabled}\n className={dateInputClass}\n value={onceDate}\n onChange={(e) => {\n const v = e.target.value;\n setOnceDate(v);\n emit({ onceDate: v });\n }}\n aria-label={labels.modeNoRepeat}\n />\n <input\n type=\"time\"\n step={60}\n disabled={disabled}\n className={timeInputClass}\n value={timeValue}\n onChange={onTimeChange}\n aria-label={labels.scheduleTimeLabel}\n />\n </>\n )}\n\n {mode === 'interval' && (\n <>\n <select\n className={cn(pickerSelectClass, 'w-auto min-w-[5rem]')}\n disabled={disabled}\n value={intervalKind}\n onChange={(e) => {\n const k = e.target.value as IntervalKind;\n setIntervalKind(k);\n setIntervalMinutesDraft(null);\n setIntervalHoursDraft(null);\n emit({ intervalKind: k });\n }}\n aria-label={labels.modeInterval}\n >\n <option value=\"minutes\">{labels.intervalKindMinutes}</option>\n <option value=\"hours\">{labels.intervalKindHours}</option>\n </select>\n {intervalKind === 'minutes' ? (\n <>\n <input\n type=\"number\"\n min={1}\n max={59}\n disabled={disabled}\n className={numberInputClass}\n value={intervalMinutesDraft ?? String(intervalMinutes)}\n onChange={(e) => {\n const next = e.target.value;\n setIntervalMinutesDraft(next);\n const raw = parseInt(next, 10);\n if (Number.isFinite(raw) && raw >= 1 && raw <= 59) {\n setIntervalMinutes(raw);\n emit({ intervalMinutes: raw });\n }\n }}\n onBlur={() => {\n if (intervalMinutesDraft === null) return;\n const raw = parseInt(intervalMinutesDraft, 10);\n const v =\n !Number.isFinite(raw) || raw < 1\n ? 5\n : Math.min(59, Math.max(1, Math.round(raw)));\n setIntervalMinutes(v);\n emit({ intervalMinutes: v });\n setIntervalMinutesDraft(null);\n }}\n aria-label={labels.intervalMinutes}\n />\n <span className=\"shrink-0 text-sm text-fg-muted\">{labels.minuteUnit}</span>\n </>\n ) : (\n <>\n <input\n type=\"number\"\n min={1}\n max={23}\n disabled={disabled}\n className={numberInputClass}\n value={intervalHoursDraft ?? String(intervalHours)}\n onChange={(e) => {\n const next = e.target.value;\n setIntervalHoursDraft(next);\n const raw = parseInt(next, 10);\n if (Number.isFinite(raw) && raw >= 1 && raw <= 23) {\n setIntervalHours(raw);\n emit({ intervalHours: raw });\n }\n }}\n onBlur={() => {\n if (intervalHoursDraft === null) return;\n const raw = parseInt(intervalHoursDraft, 10);\n const v =\n !Number.isFinite(raw) || raw < 1\n ? 2\n : Math.min(23, Math.max(1, Math.round(raw)));\n setIntervalHours(v);\n emit({ intervalHours: v });\n setIntervalHoursDraft(null);\n }}\n aria-label={labels.intervalHours}\n />\n <span className=\"shrink-0 text-sm text-fg-muted\">{labels.hourUnit}</span>\n <select\n className={cn(pickerSelectClass, 'w-auto min-w-[4rem]')}\n disabled={disabled}\n value={minute}\n onChange={(e) => {\n const mm = parseInt(e.target.value, 10);\n setMinute(mm);\n emit({ minute: mm });\n }}\n aria-label={labels.minuteAtHour}\n >\n {Array.from({ length: 60 }, (_, i) => (\n <option key={i} value={i}>\n {String(i).padStart(2, '0')}\n </option>\n ))}\n </select>\n <span className=\"shrink-0 text-sm text-fg-muted\">{labels.minuteUnit}</span>\n </>\n )}\n </>\n )}\n\n {mode === 'daily' && (\n <input\n type=\"time\"\n step={60}\n disabled={disabled}\n className={timeInputClass}\n value={timeValue}\n onChange={onTimeChange}\n aria-label={labels.scheduleTimeLabel}\n />\n )}\n\n {mode === 'weekly' && (\n <input\n type=\"time\"\n step={60}\n disabled={disabled}\n className={timeInputClass}\n value={timeValue}\n onChange={onTimeChange}\n aria-label={labels.scheduleTimeLabel}\n />\n )}\n\n {mode === 'monthly' && (\n <>\n <select\n className={cn(pickerSelectClass, 'w-auto min-w-[4.5rem]')}\n disabled={disabled}\n value={dayOfMonth}\n onChange={(e) => {\n const d = parseInt(e.target.value, 10);\n setDayOfMonth(d);\n emit({ dayOfMonth: d });\n }}\n aria-label={labels.dayOfMonth}\n >\n {Array.from({ length: 31 }, (_, i) => i + 1).map((d) => (\n <option key={d} value={d}>\n {d}\n </option>\n ))}\n </select>\n <input\n type=\"time\"\n step={60}\n disabled={disabled}\n className={timeInputClass}\n value={timeValue}\n onChange={onTimeChange}\n aria-label={labels.scheduleTimeLabel}\n />\n </>\n )}\n\n {mode === 'hourly' && (\n <>\n <select\n className={cn(pickerSelectClass, 'w-auto min-w-[4rem]')}\n disabled={disabled}\n value={minute}\n onChange={(e) => {\n const mm = parseInt(e.target.value, 10);\n setMinute(mm);\n emit({ minute: mm });\n }}\n aria-label={labels.minuteAtHour}\n >\n {Array.from({ length: 60 }, (_, i) => (\n <option key={i} value={i}>\n {String(i).padStart(2, '0')}\n </option>\n ))}\n </select>\n <span className=\"shrink-0 text-sm text-fg-muted\">{labels.minuteUnit}</span>\n </>\n )}\n </div>\n );\n\n const weekRow =\n mode === 'weekly' ? (\n <div className=\"flex flex-wrap gap-1.5 pt-1\" role=\"group\" aria-label={labels.modeWeekly}>\n {labels.weekdays.map((label, i) => {\n const on = weekDays[i];\n return (\n <button\n key={label}\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'flex size-9 select-none items-center justify-center rounded-full border text-xs font-medium transition-colors',\n on\n ? 'border-fg bg-fg text-surface-panel'\n : 'border-edge-subtle bg-surface-panel text-fg hover:border-edge',\n )}\n aria-pressed={on}\n onClick={() => {\n const next = [...weekDays];\n next[i] = !next[i];\n setWeekDays(next);\n emit({ weekDays: next });\n }}\n >\n {label}\n </button>\n );\n })}\n </div>\n ) : null;\n\n const customBlock =\n mode === 'custom' ? (\n <div className=\"pt-1\">\n <textarea\n disabled={disabled}\n className={cronTextareaClass}\n rows={2}\n spellCheck={false}\n value={rawCron}\n placeholder=\"*/5 * * * *\"\n onChange={(e) => {\n const v = e.target.value;\n setRawCron(v);\n onChange(v.trim() || '*/5 * * * *');\n }}\n aria-label={labels.modeCustom}\n />\n <p className=\"mt-1 text-xs text-fg-muted\">{labels.customCronHint}</p>\n </div>\n ) : null;\n\n return (\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium text-fg-muted\">{labels.scheduleTimeLabel}</span>\n {modeRow}\n {weekRow}\n {customBlock}\n </div>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { Eye, FolderInput, RefreshCw, SquarePen, X } from 'lucide-react';\n\nimport { MarkdownEditor } from '@/components/markdown/markdown-editor';\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { Button } from '@/components/ui/button';\nimport type { ChatAgentOption } from '@/features/chat/chat-agents-api';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { folderDisplayName } from '@/features/chat/session-working-directory-control';\nimport { WorkingDirectoryPickerModal } from '@/features/chat/working-directory-picker-modal';\nimport type { ChannelStatus, SessionChatId } from '@/features/cron/cron-api';\nimport { CronSchedulePicker } from '@/features/cron/cron-schedule-form';\nimport { formatRecipientOptionLabel } from '@/features/cron/cron-utils';\nimport {\n cronRecipientSelectClass,\n inputClassName,\n selectClassName,\n} from '@/features/cron/cron-page-lib';\nimport { agentListDisplayName } from '@/features/settings/agents/agent-display-names';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronJobFormDialogProps = {\n open: boolean;\n onRequestClose: () => void;\n c: CronCopy;\n chatM: MessageBundle['chat'];\n agentsMessages: MessageBundle['agentsSettings'];\n isDark: boolean;\n channels: ChannelStatus[];\n sessionChatIds: SessionChatId[];\n cronAgentSelectOptions: ChatAgentOption[];\n hasElectronFolderPicker: boolean;\n openNativeFolderPicker: () => Promise<string | null>;\n applyWorkingDirectory: (path: string) => Promise<void>;\n wdModalOpen: boolean;\n onWdModalOpenChange: (open: boolean) => void;\n defaultModelResolver: () => string;\n formMode: 'add' | 'edit';\n formJobId: string | null;\n formName: string;\n onFormNameChange: (v: string) => void;\n formSchedule: string;\n onFormScheduleChange: (v: string) => void;\n formSubmitting: boolean;\n formSessionTarget: 'main' | 'isolated';\n onFormSessionTargetChange: (\n target: 'main' | 'isolated',\n defaultModelFallback: () => string,\n currentModel: string,\n ) => void;\n formAgentLocalOnly: boolean;\n onFormAgentLocalOnlyChange: (v: boolean) => void;\n formModel: string;\n onFormModelUserChange: (id: string) => void;\n formAgentId: string;\n onFormAgentIdChange: (v: string) => void;\n formWorkingDirectory: string;\n onFormWorkingDirectoryChange: (v: string) => void;\n formChannel: string;\n onFormChannelChange: (channel: string) => void;\n formChatId: string;\n onFormChatIdChange: (v: string) => void;\n formMessage: string;\n onFormMessageChange: (v: string) => void;\n formMessageMdMode: 'edit' | 'preview';\n onSetMessageMdMode: (mode: 'edit' | 'preview') => void;\n messageEditorNonce: number;\n needsDeliveryChat: boolean;\n showChannelPicker: boolean;\n canSubmit: boolean;\n onSubmit: () => void;\n onRefreshRecipients: () => void;\n};\n\nexport function CronJobFormDialog(props: CronJobFormDialogProps) {\n const {\n open,\n onRequestClose,\n c,\n chatM,\n agentsMessages,\n isDark,\n channels,\n sessionChatIds,\n cronAgentSelectOptions,\n hasElectronFolderPicker,\n openNativeFolderPicker,\n applyWorkingDirectory,\n wdModalOpen,\n onWdModalOpenChange,\n defaultModelResolver,\n formMode,\n formJobId,\n formName,\n onFormNameChange,\n formSchedule,\n onFormScheduleChange,\n formSubmitting,\n formSessionTarget,\n onFormSessionTargetChange,\n formAgentLocalOnly,\n onFormAgentLocalOnlyChange,\n formModel,\n onFormModelUserChange,\n formAgentId,\n onFormAgentIdChange,\n formWorkingDirectory,\n onFormWorkingDirectoryChange,\n formChannel,\n onFormChannelChange,\n formChatId,\n onFormChatIdChange,\n formMessage,\n onFormMessageChange,\n formMessageMdMode,\n onSetMessageMdMode,\n messageEditorNonce,\n needsDeliveryChat,\n showChannelPicker,\n canSubmit,\n onSubmit,\n onRefreshRecipients,\n } = props;\n\n return (\n <>\n <Dialog.Root open={open} onOpenChange={(o) => !o && onRequestClose()}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <div className=\"fixed inset-0 z-[60] flex items-center justify-center p-4 pointer-events-none\">\n <Dialog.Content\n className=\"xopc-dialog-content-pane pointer-events-auto relative flex max-h-[min(90vh,800px)] w-full max-w-md flex-col rounded-xl border border-edge bg-surface-panel shadow-popover outline-none sm:max-w-lg lg:max-w-xl dark:border-edge\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"flex shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3\">\n <Dialog.Title className=\"text-base font-semibold text-fg\">\n {formMode === 'edit' ? c.editJob : c.addJob}\n </Dialog.Title>\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"h-9 w-9 shrink-0 p-0\" aria-label={c.close}>\n <X className=\"size-5\" strokeWidth={1.75} />\n </Button>\n </Dialog.Close>\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-3\">\n <div className=\"flex flex-col gap-3\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.name}</span>\n <input\n type=\"text\"\n className={inputClassName()}\n value={formName}\n onChange={(e) => onFormNameChange(e.target.value)}\n placeholder={c.namePlaceholder}\n />\n </label>\n <CronSchedulePicker\n value={formSchedule}\n onChange={onFormScheduleChange}\n disabled={formSubmitting}\n labels={c.schedulePicker}\n />\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.mode}</span>\n <select\n className={selectClassName()}\n value={formSessionTarget}\n onChange={(e) => {\n const v = e.target.value as 'main' | 'isolated';\n onFormSessionTargetChange(v, defaultModelResolver, formModel.trim());\n }}\n >\n <option value=\"main\">{c.modeDirectOption}</option>\n <option value=\"isolated\">{c.modeAgentOption}</option>\n </select>\n <p className=\"text-xs text-fg-muted\">\n {formSessionTarget === 'main' ? c.modeDirect : c.modeAgent}\n </p>\n </label>\n {formSessionTarget === 'isolated' ? (\n <>\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.model}</span>\n <ModelSelector\n value={formModel}\n placeholder={chatM.modelPlaceholder}\n searchPlaceholder={chatM.modelSearchPlaceholder}\n noMatches={chatM.modelNoMatches}\n className=\"w-full max-w-none min-w-0\"\n popoverContentClassName=\"z-[70]\"\n onChange={onFormModelUserChange}\n />\n </div>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.agentProfile}</span>\n <select\n className={selectClassName()}\n value={formAgentId}\n disabled={formSubmitting}\n onChange={(e) => onFormAgentIdChange(e.target.value)}\n >\n <option value=\"\">{c.agentProfileDefault}</option>\n {cronAgentSelectOptions.map((ag) => (\n <option key={ag.id} value={ag.id}>\n {`${ag.id} — ${agentListDisplayName(ag, agentsMessages)}`}\n </option>\n ))}\n </select>\n <p className=\"text-xs text-fg-muted\">{c.agentProfileHint}</p>\n </label>\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.workingDirectoryLabel}</span>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n disabled={formSubmitting}\n className={cn(\n 'inline-flex min-h-8 max-w-[min(16rem,48vw)] min-w-0 shrink-0 items-center gap-1 rounded-lg px-2 py-1 text-xs',\n 'border border-edge-subtle/80 bg-surface-hover/40 dark:border-edge-subtle',\n interaction.transition,\n interaction.focusRingPanel,\n 'cursor-pointer hover:bg-surface-hover/70 dark:hover:bg-surface-hover/50',\n formSubmitting && 'cursor-not-allowed opacity-60',\n )}\n title={\n formWorkingDirectory.trim()\n ? `${formWorkingDirectory.trim()}\\n${chatM.workingDirectory.chooseFolder}`\n : `${c.workingDirectoryHint}\\n${chatM.workingDirectory.selectWorkingDirectory}`\n }\n onClick={(e) => {\n e.stopPropagation();\n if (formSubmitting) return;\n if (hasElectronFolderPicker) {\n void (async () => {\n const picked = await openNativeFolderPicker();\n if (picked) void applyWorkingDirectory(picked);\n })();\n } else {\n onWdModalOpenChange(true);\n }\n }}\n >\n <FolderInput className=\"size-3.5 shrink-0 text-fg-muted\" aria-hidden />\n <span className=\"min-w-0 truncate text-left font-medium text-fg\">\n {formWorkingDirectory.trim()\n ? folderDisplayName(formWorkingDirectory.trim())\n : chatM.workingDirectory.notSet}\n </span>\n </button>\n {formWorkingDirectory.trim() ? (\n <button\n type=\"button\"\n disabled={formSubmitting}\n className=\"text-xs font-medium text-accent hover:underline disabled:opacity-50\"\n onClick={() => onFormWorkingDirectoryChange('')}\n >\n {c.workingDirectoryReset}\n </button>\n ) : null}\n </div>\n <p className=\"text-xs text-fg-muted\">{c.workingDirectoryHint}</p>\n </div>\n <label className=\"flex cursor-pointer items-start gap-2 rounded-md bg-surface-hover/45 px-3 py-2 dark:bg-surface-hover/30\">\n <input\n type=\"checkbox\"\n className={cn('ui-checkbox', 'mt-0.5')}\n checked={formAgentLocalOnly}\n onChange={(e) => onFormAgentLocalOnlyChange(e.target.checked)}\n />\n <span>\n <span className=\"text-sm font-medium text-fg\">{c.agentLocalOnly}</span>\n <p className=\"mt-1 text-xs text-fg-muted\">{c.agentLocalOnlyHint}</p>\n </span>\n </label>\n </>\n ) : null}\n {showChannelPicker ? (\n <>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.channel}</span>\n <select\n className={selectClassName()}\n value={formChannel}\n onChange={(e) => {\n const v = e.target.value;\n onFormChannelChange(v);\n }}\n >\n <option value=\"local\">{c.channelLocal}</option>\n {channels.map((ch) => (\n <option key={ch.name} value={ch.name} disabled={!ch.enabled}>\n {ch.name} {!ch.enabled ? '(disabled)' : ''}\n </option>\n ))}\n </select>\n </label>\n {needsDeliveryChat ? (\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.recipient}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-7 gap-1 px-2 text-xs\"\n title={c.refreshRecipientHint}\n onClick={() => void onRefreshRecipients()}\n >\n <RefreshCw className=\"size-3.5\" strokeWidth={1.75} />\n {c.refreshList}\n </Button>\n </div>\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-stretch sm:gap-2\">\n <input\n type=\"text\"\n className={cn(inputClassName(), 'min-w-0 w-full sm:flex-1')}\n value={formChatId}\n onChange={(e) => onFormChatIdChange(e.target.value)}\n placeholder={c.recipientPlaceholder}\n />\n <select\n className={cronRecipientSelectClass}\n value={formChatId}\n onChange={(e) => {\n const v = e.target.value;\n if (v) onFormChatIdChange(v);\n }}\n >\n <option value=\"\">{c.selectRecipient}</option>\n {sessionChatIds.length > 0 ? (\n sessionChatIds.map((item) => (\n <option key={`${item.channel}-${item.chatId}`} value={item.chatId}>\n {formatRecipientOptionLabel(item, c.lastActiveLabels)}\n </option>\n ))\n ) : (\n <option value=\"\" disabled>\n {c.noRecentChatsOption}\n </option>\n )}\n </select>\n </div>\n <p className=\"text-xs text-fg-muted\">\n {sessionChatIds.length > 0 ? c.enterManuallyOrSelect : c.noRecentChats}\n </p>\n </div>\n ) : null}\n </>\n ) : null}\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.message}</span>\n <div className=\"inline-flex rounded-lg border border-edge bg-surface-base p-0.5 dark:border-edge\">\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium',\n formMessageMdMode === 'edit'\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover',\n )}\n onClick={() => onSetMessageMdMode('edit')}\n >\n <SquarePen className=\"size-3.5 shrink-0\" strokeWidth={1.75} aria-hidden />\n {c.messageEdit}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium',\n formMessageMdMode === 'preview'\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover',\n )}\n onClick={() => onSetMessageMdMode('preview')}\n >\n <Eye className=\"size-3.5 shrink-0\" strokeWidth={1.75} aria-hidden />\n {c.messagePreview}\n </button>\n </div>\n </div>\n <div\n className={cn(\n 'overflow-hidden rounded-md border border-edge bg-surface-base dark:border-edge',\n formSubmitting && 'pointer-events-none opacity-60',\n )}\n >\n {formMessageMdMode === 'edit' ? (\n <MarkdownEditor\n key={`cron-msg-${formJobId ?? 'new'}-${messageEditorNonce}`}\n initialContent={formMessage}\n onChange={onFormMessageChange}\n isDark={isDark}\n className=\"h-[min(18rem,40vh)] min-h-[12rem]\"\n />\n ) : (\n <div className=\"h-[min(18rem,40vh)] min-h-[12rem] max-h-[min(24rem,50vh)] overflow-y-auto px-3 py-2\">\n {formMessage.trim() ? (\n <MarkdownView content={formMessage} compact className=\"text-sm\" />\n ) : (\n <p className=\"text-sm text-fg-muted\">{c.messagePlaceholder}</p>\n )}\n </div>\n )}\n </div>\n <p className=\"text-xs text-fg-muted\">{c.messageMarkdownHint}</p>\n </div>\n </div>\n </div>\n <div className=\"flex shrink-0 justify-end gap-2 border-t border-edge px-4 py-3\">\n <Button type=\"button\" variant=\"secondary\" onClick={onRequestClose}>\n {c.cancel}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={formSubmitting || !canSubmit} onClick={onSubmit}>\n {formSubmitting ? c.loading : formMode === 'edit' ? c.save : c.create}\n </Button>\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n\n {!hasElectronFolderPicker ? (\n <WorkingDirectoryPickerModal\n open={wdModalOpen}\n onOpenChange={onWdModalOpenChange}\n initialAbsolutePath={formWorkingDirectory.trim() || undefined}\n onConfirm={async (p) => {\n await applyWorkingDirectory(p);\n onWdModalOpenChange(false);\n }}\n wd={chatM.workingDirectory}\n />\n ) : null}\n </>\n );\n}\n","import {\n segmentedThumbActiveClassName,\n segmentedThumbBaseClassName,\n segmentedTrackClassName,\n} from '@/components/ui/segmented-styles';\nimport type { CronJob } from '@/features/cron/cron-api';\nimport { cronToolbarSelectClass } from '@/features/cron/cron-page-lib';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronMainToolbarProps = {\n c: CronCopy;\n mainTab: 'myTasks' | 'systemTasks' | 'history';\n onMainTabChange: (tab: 'myTasks' | 'systemTasks' | 'history') => void;\n jobSort: 'created_desc' | 'created_asc';\n onJobSortChange: (sort: 'created_desc' | 'created_asc') => void;\n historyRange: 'day' | 'week' | 'month';\n onHistoryRangeChange: (range: 'day' | 'week' | 'month') => void;\n historyJobFilter: string;\n onHistoryJobFilterChange: (jobId: string) => void;\n historyStatusFilter: string;\n onHistoryStatusFilterChange: (status: string) => void;\n jobs: CronJob[];\n};\n\nexport function CronMainToolbar({\n c,\n mainTab,\n onMainTabChange,\n jobSort,\n onJobSortChange,\n historyRange,\n onHistoryRangeChange,\n historyJobFilter,\n onHistoryJobFilterChange,\n historyStatusFilter,\n onHistoryStatusFilterChange,\n jobs,\n}: CronMainToolbarProps) {\n return (\n <div className=\"flex flex-col gap-3 border-b border-edge-subtle pb-3 sm:flex-row sm:items-center sm:justify-between dark:border-edge-subtle\">\n <div className=\"flex gap-1\" role=\"tablist\" aria-label={c.title}>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mainTab === 'myTasks'}\n className={cn(\n 'rounded-md px-3 py-2 text-sm font-medium transition-colors',\n mainTab === 'myTasks' ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n onClick={() => onMainTabChange('myTasks')}\n >\n {c.tabMyTasks}\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mainTab === 'systemTasks'}\n className={cn(\n 'rounded-md px-3 py-2 text-sm font-medium transition-colors',\n mainTab === 'systemTasks' ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n onClick={() => onMainTabChange('systemTasks')}\n >\n {c.tabSystemTasks}\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mainTab === 'history'}\n className={cn(\n 'rounded-md px-3 py-2 text-sm font-medium transition-colors',\n mainTab === 'history' ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n onClick={() => onMainTabChange('history')}\n >\n {c.tabRunHistory}\n </button>\n </div>\n <div\n className={cn(\n 'flex min-w-0 items-center gap-2',\n mainTab === 'history'\n ? 'flex-nowrap overflow-x-auto pb-0.5 sm:justify-end'\n : 'flex-wrap sm:justify-end',\n )}\n >\n {mainTab === 'myTasks' || mainTab === 'systemTasks' ? (\n <select\n className={cronToolbarSelectClass}\n value={jobSort}\n onChange={(e) => onJobSortChange(e.target.value as 'created_desc' | 'created_asc')}\n aria-label={c.sortCreatedDesc}\n >\n <option value=\"created_desc\">{c.sortCreatedDesc}</option>\n <option value=\"created_asc\">{c.sortCreatedAsc}</option>\n </select>\n ) : null}\n {mainTab === 'history' ? (\n <>\n <div className={cn(segmentedTrackClassName, 'shrink-0')} role=\"group\" aria-label={c.runHistoryTitle}>\n {(['day', 'week', 'month'] as const).map((r) => (\n <button\n key={r}\n type=\"button\"\n className={cn(\n segmentedThumbBaseClassName,\n 'px-2.5 py-1',\n historyRange === r && segmentedThumbActiveClassName,\n historyRange === r && 'text-fg',\n )}\n onClick={() => onHistoryRangeChange(r)}\n >\n {r === 'day' ? c.historyRangeDay : r === 'week' ? c.historyRangeWeek : c.historyRangeMonth}\n </button>\n ))}\n </div>\n <select\n className={cronToolbarSelectClass}\n value={historyJobFilter}\n onChange={(e) => onHistoryJobFilterChange(e.target.value)}\n aria-label={c.filterAllTasks}\n >\n <option value=\"\">{c.filterAllTasks}</option>\n {jobs.map((j) => (\n <option key={j.id} value={j.id}>\n {j.name || j.id}\n </option>\n ))}\n </select>\n <select\n className={cronToolbarSelectClass}\n value={historyStatusFilter}\n onChange={(e) => onHistoryStatusFilterChange(e.target.value)}\n aria-label={c.filterAllStatuses}\n >\n <option value=\"\">{c.filterAllStatuses}</option>\n <option value=\"success\">{c.execStatusSuccess}</option>\n <option value=\"failed\">{c.execStatusFailed}</option>\n <option value=\"cancelled\">{c.execStatusCancelled}</option>\n <option value=\"running\">{c.execStatusRunning}</option>\n </select>\n </>\n ) : null}\n </div>\n </div>\n );\n}\n","import { LayoutTemplate, Plus, RefreshCw } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronPageHeaderActionsProps = {\n c: CronCopy;\n loading: boolean;\n runHistoryLoading: boolean;\n onRefresh: () => void;\n onOpenTemplatePicker: () => void;\n onAddJob: () => void;\n};\n\nexport function CronPageHeaderActions({\n c,\n loading,\n runHistoryLoading,\n onRefresh,\n onOpenTemplatePicker,\n onAddJob,\n}: CronPageHeaderActionsProps) {\n const busy = loading || runHistoryLoading;\n return (\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 w-9 shrink-0 p-0\"\n disabled={busy}\n title={c.refresh}\n aria-label={c.refresh}\n onClick={() => void onRefresh()}\n >\n <RefreshCw className={cn('size-4', busy && 'animate-spin')} strokeWidth={1.75} />\n </Button>\n <Button type=\"button\" variant=\"secondary\" className=\"gap-2\" onClick={onOpenTemplatePicker}>\n <LayoutTemplate className=\"size-4\" strokeWidth={1.75} />\n {c.fromTemplate}\n </Button>\n <Button type=\"button\" variant=\"primary\" className=\"gap-2\" onClick={onAddJob}>\n <Plus className=\"size-4\" strokeWidth={1.75} />\n {c.addJob}\n </Button>\n </div>\n );\n}\n","import { Clock, Loader2, RefreshCw } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport type { CronJob, CronRunHistoryRow } from '@/features/cron/cron-api';\nimport { navigateToSessionChat } from '@/features/cron/cron-page-lib';\nimport {\n execStatusLabel,\n formatDuration,\n formatTime,\n truncate,\n} from '@/features/cron/cron-utils';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronRunHistorySectionProps = {\n c: CronCopy;\n runHistoryLoading: boolean;\n runHistory: CronRunHistoryRow[];\n filteredRunHistory: CronRunHistoryRow[];\n jobs: CronJob[];\n onRefreshHistory: () => void;\n onOpenJobDetail: (job: CronJob) => void;\n statusLabels: {\n running: string;\n success: string;\n failed: string;\n cancelled: string;\n };\n};\n\nexport function CronRunHistorySection({\n c,\n runHistoryLoading,\n runHistory,\n filteredRunHistory,\n jobs,\n onRefreshHistory,\n onOpenJobDetail,\n statusLabels,\n}: CronRunHistorySectionProps) {\n return (\n <section aria-labelledby=\"cron-history-panel\" className=\"flex flex-col gap-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div>\n <h2 id=\"cron-history-panel\" className=\"sr-only\">\n {c.tabRunHistory}\n </h2>\n <p className=\"text-xs text-fg-muted\">{c.runHistoryHint}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 w-9 shrink-0 p-0\"\n disabled={runHistoryLoading}\n title={c.refresh}\n aria-label={c.refresh}\n onClick={() => void onRefreshHistory()}\n >\n <RefreshCw className={cn('size-4', runHistoryLoading && 'animate-spin')} strokeWidth={1.75} />\n </Button>\n </div>\n {runHistoryLoading && runHistory.length === 0 ? (\n <div className=\"flex justify-center py-16\">\n <Loader2 className=\"size-8 animate-spin text-accent\" strokeWidth={1.75} />\n </div>\n ) : filteredRunHistory.length === 0 ? (\n <div className=\"flex flex-col items-center rounded-2xl border border-dashed border-edge-subtle px-6 py-16 text-center dark:border-edge-subtle\">\n <Clock className=\"mb-4 size-14 text-fg-disabled\" strokeWidth={1.1} aria-hidden />\n <h3 className=\"text-base font-semibold text-fg\">\n {runHistory.length === 0 ? c.emptyHistoryTitle : c.noRunsYet}\n </h3>\n <p className=\"mt-2 max-w-sm text-sm text-fg-muted\">\n {runHistory.length === 0 ? c.emptyHistoryHint : c.runHistoryHint}\n </p>\n </div>\n ) : (\n <div className=\"overflow-x-auto rounded-xl border border-edge-subtle bg-surface-base dark:border-edge-subtle\">\n <table className=\"w-full min-w-[700px] border-collapse text-left text-sm\">\n <thead>\n <tr className=\"border-b border-edge text-xs font-medium text-fg-muted\">\n <th className=\"px-3 py-2.5 font-medium\">{c.colStarted}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.colJob}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.status}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.colDuration}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.colDetail}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.colChat}</th>\n </tr>\n </thead>\n <tbody>\n {filteredRunHistory.map((row) => (\n <tr key={row.id} className=\"border-b border-edge/60 last:border-0\">\n <td className=\"whitespace-nowrap px-3 py-2.5 text-fg\">\n <time dateTime={row.startedAt}>{formatTime(row.startedAt)}</time>\n </td>\n <td className=\"max-w-[10rem] truncate px-3 py-2.5\">\n {jobs.some((j) => j.id === row.jobId) ? (\n <button\n type=\"button\"\n className=\"text-left text-accent hover:underline\"\n onClick={() => {\n const j = jobs.find((x) => x.id === row.jobId);\n if (j) void onOpenJobDetail(j);\n }}\n >\n {row.jobName || row.jobId}\n </button>\n ) : (\n <span className=\"text-fg-muted\">{row.jobName || row.jobId}</span>\n )}\n </td>\n <td className=\"px-3 py-2.5\">\n <span\n className={cn(\n 'inline-flex rounded-md px-2 py-0.5 text-xs font-medium',\n row.status === 'success' && 'bg-emerald-500/15 text-emerald-800 dark:text-emerald-300',\n row.status === 'failed' && 'bg-red-500/15 text-red-800 dark:text-red-300',\n row.status === 'running' && 'bg-accent/15 text-accent',\n row.status === 'cancelled' && 'bg-surface-hover text-fg-muted',\n )}\n >\n {execStatusLabel(row.status, statusLabels)}\n </span>\n </td>\n <td className=\"whitespace-nowrap px-3 py-2.5 text-fg-muted\">\n {formatDuration(row.duration)}\n </td>\n <td\n className=\"max-w-xs truncate px-3 py-2.5 text-fg-muted\"\n title={row.summary || row.error || ''}\n >\n {truncate(row.summary || row.error, 96)}\n </td>\n <td className=\"whitespace-nowrap px-3 py-2.5\">\n {row.sessionKey?.trim() ? (\n <button\n type=\"button\"\n className=\"text-xs font-medium text-accent hover:underline\"\n title={c.openChatTitle}\n aria-label={c.openChatTitle}\n onClick={() => navigateToSessionChat(row.sessionKey)}\n >\n {c.openChat}\n </button>\n ) : (\n <span className=\"text-fg-disabled\">—</span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n );\n}\n","import * as DropdownMenu from '@radix-ui/react-dropdown-menu';\nimport { Clock, MoreVertical } from 'lucide-react';\n\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { Button } from '@/components/ui/button';\nimport type { MutableRefObject } from 'react';\n\nimport type { CronJob } from '@/features/cron/cron-api';\nimport { cronJobBodyText } from '@/features/cron/cron-api';\nimport { formatScheduleBadge } from '@/features/cron/cron-utils';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronJobCardProps = {\n job: CronJob;\n c: CronCopy;\n localeTag: string;\n scheduleBadgeLabels: CronCopy['scheduleBadge'];\n absorbCardClickJobIdRef: MutableRefObject<string | null>;\n scheduleAbsorbNextMenuCardClick: (jobId: string) => void;\n onOpenDetail: (job: CronJob) => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onEdit: (job: CronJob) => void;\n onRunNow: (job: CronJob) => void;\n onDelete: (job: CronJob) => void;\n};\n\nexport function CronJobCard({\n job,\n c,\n localeTag,\n scheduleBadgeLabels,\n absorbCardClickJobIdRef,\n scheduleAbsorbNextMenuCardClick,\n onOpenDetail,\n onToggle,\n onEdit,\n onRunNow,\n onDelete,\n}: CronJobCardProps) {\n return (\n <article\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'flex cursor-pointer flex-col rounded-xl border border-edge-subtle bg-surface-base text-left transition-colors duration-150 ease-out dark:border-edge-subtle',\n 'hover:bg-surface-hover',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel',\n )}\n onClick={() => {\n if (absorbCardClickJobIdRef.current === job.id) {\n absorbCardClickJobIdRef.current = null;\n return;\n }\n void onOpenDetail(job);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (absorbCardClickJobIdRef.current === job.id) {\n absorbCardClickJobIdRef.current = null;\n return;\n }\n void onOpenDetail(job);\n }\n }}\n >\n <div className=\"flex items-start justify-between gap-2 px-4 pt-3\">\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={job.enabled}\n className={cn(\n 'inline-flex h-6 w-10 shrink-0 items-center rounded-full border border-edge p-0.5 transition-colors',\n job.enabled ? 'justify-end bg-accent' : 'justify-start bg-surface-hover',\n )}\n onClick={(e) => {\n e.stopPropagation();\n void onToggle(job, !job.enabled);\n }}\n >\n <span className=\"size-4 rounded-full bg-surface-panel shadow-surface ring-1 ring-edge/40 dark:ring-edge/55\" />\n </button>\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-8 w-8 shrink-0 p-0\"\n aria-label={c.jobCardMenuAria}\n onClick={(e) => e.stopPropagation()}\n >\n <MoreVertical className=\"size-4\" strokeWidth={1.75} />\n </Button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className=\"z-50 min-w-[10rem] rounded-xl border border-edge-subtle bg-surface-panel p-1 shadow-elevated dark:border-edge-subtle\"\n sideOffset={4}\n align=\"end\"\n onCloseAutoFocus={(e) => e.preventDefault()}\n >\n <DropdownMenu.Item\n className=\"cursor-pointer select-none rounded-lg px-2 py-1.5 text-sm text-fg outline-none data-highlighted:bg-surface-hover\"\n onSelect={() => {\n scheduleAbsorbNextMenuCardClick(job.id);\n onEdit(job);\n }}\n >\n {c.edit}\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className=\"cursor-pointer select-none rounded-lg px-2 py-1.5 text-sm text-fg outline-none data-highlighted:bg-surface-hover\"\n onSelect={() => {\n scheduleAbsorbNextMenuCardClick(job.id);\n onRunNow(job);\n }}\n >\n {c.runNow}\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className=\"cursor-pointer select-none rounded-lg px-2 py-1.5 text-sm text-red-600 outline-none data-highlighted:bg-red-500/10 dark:text-red-400\"\n onSelect={() => {\n scheduleAbsorbNextMenuCardClick(job.id);\n onDelete(job);\n }}\n >\n {c.delete}\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n </div>\n <div className=\"flex flex-1 flex-col gap-2 px-4 pb-3 pt-2\">\n <h3 className=\"line-clamp-2 font-semibold text-fg\">{job.name || job.id}</h3>\n <div\n className=\"max-h-[4.5rem] overflow-hidden text-sm text-fg-muted [&_.markdown-body]:text-sm [&_.markdown-body]:leading-snug\"\n title={cronJobBodyText(job)}\n >\n <MarkdownView content={cronJobBodyText(job)} compact />\n </div>\n </div>\n <div className=\"flex items-center gap-1.5 border-t border-edge-subtle/90 px-4 py-2.5 text-xs text-fg-muted dark:border-edge-subtle\">\n <Clock className=\"size-3.5 shrink-0\" strokeWidth={1.75} aria-hidden />\n <span className=\"min-w-0 truncate\">{formatScheduleBadge(job, localeTag, scheduleBadgeLabels)}</span>\n </div>\n </article>\n );\n}\n","import { ChevronRight, Info, Loader2 } from 'lucide-react';\nimport type { MutableRefObject } from 'react';\nimport { Link } from 'react-router-dom';\n\nimport { Button } from '@/components/ui/button';\nimport type { CronJob } from '@/features/cron/cron-api';\nimport { CronJobCard } from '@/features/cron/cron-job-card';\nimport type { HeartbeatSettingsState } from '@/features/settings/heartbeat-settings.types';\nimport type { MessageBundle } from '@/i18n/messages';\nimport type { StoredLanguage } from '@/lib/storage';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\n/** Localized duration phrase for interpolation into `c.systemHeartbeatEvery`. */\nfunction heartbeatIntervalValuePhrase(ms: number, lang: StoredLanguage): string {\n const sec = Math.max(1, Math.round(ms / 1000));\n if (sec < 120) return lang === 'zh' ? `${sec} 秒` : `${sec} seconds`;\n const min = Math.round(sec / 60);\n if (min < 120) return lang === 'zh' ? `${min} 分钟` : `${min} minutes`;\n const hr = Math.round(min / 60);\n return lang === 'zh' ? `${hr} 小时` : `${hr} hours`;\n}\n\nexport type CronSystemTasksPanelProps = {\n c: CronCopy;\n language: StoredLanguage;\n localeTag: string;\n scheduleBadgeLabels: CronCopy['scheduleBadge'];\n loading: boolean;\n sortedSystemJobs: CronJob[];\n heartbeat: HeartbeatSettingsState;\n keepAwake: boolean;\n wakeSupported: boolean;\n onWakeUnsupportedClick: () => void;\n onKeepAwakeToggle: () => void;\n absorbCardClickJobIdRef: MutableRefObject<string | null>;\n scheduleAbsorbNextMenuCardClick: (jobId: string) => void;\n onOpenDetail: (job: CronJob) => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onEdit: (job: CronJob) => void;\n onRunNow: (job: CronJob) => void;\n onDelete: (job: CronJob) => void;\n};\n\nexport function CronSystemTasksPanel({\n c,\n language,\n localeTag,\n scheduleBadgeLabels,\n loading,\n sortedSystemJobs,\n heartbeat,\n keepAwake,\n wakeSupported,\n onWakeUnsupportedClick,\n onKeepAwakeToggle,\n absorbCardClickJobIdRef,\n scheduleAbsorbNextMenuCardClick,\n onOpenDetail,\n onToggle,\n onEdit,\n onRunNow,\n onDelete,\n}: CronSystemTasksPanelProps) {\n const hbInterval = heartbeatIntervalValuePhrase(heartbeat.intervalMs, language);\n\n return (\n <section aria-labelledby=\"cron-system-tasks-panel\" className=\"flex flex-col gap-4\">\n <h2 id=\"cron-system-tasks-panel\" className=\"sr-only\">\n {c.tabSystemTasks}\n </h2>\n <p className=\"text-sm text-fg-muted\">{c.systemTasksIntro}</p>\n\n <div className=\"flex flex-col gap-3 rounded-xl border border-accent/25 bg-accent/5 px-4 py-3 dark:border-accent/30 dark:bg-accent/10 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex gap-3 text-sm text-fg\">\n <Info className=\"mt-0.5 size-4 shrink-0 text-accent\" strokeWidth={1.75} aria-hidden />\n <p className=\"text-pretty text-fg-muted\">{c.wakeBanner}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2 sm:pl-4\">\n <span className=\"text-sm text-fg\">{c.keepAwake}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={keepAwake}\n disabled={!wakeSupported}\n title={!wakeSupported ? c.wakeLockUnavailable : undefined}\n className={cn(\n 'inline-flex h-6 w-10 shrink-0 items-center rounded-full border border-edge p-0.5 transition-colors',\n keepAwake ? 'justify-end bg-accent' : 'justify-start bg-surface-hover',\n !wakeSupported && 'cursor-not-allowed opacity-50',\n )}\n onClick={() => {\n if (!wakeSupported) onWakeUnsupportedClick();\n else onKeepAwakeToggle();\n }}\n >\n <span className=\"size-4 rounded-full bg-surface-panel shadow-surface ring-1 ring-edge/40 dark:ring-edge/55\" />\n </button>\n </div>\n </div>\n\n <div className=\"rounded-xl border border-edge bg-surface-base p-4 dark:bg-surface-hover/20\">\n <div className=\"flex flex-col gap-1 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h3 className=\"text-sm font-semibold text-fg\">{c.systemHeartbeatTitle}</h3>\n <p className=\"mt-1 text-xs text-fg-muted\">{c.systemHeartbeatHint}</p>\n </div>\n <Button type=\"button\" variant=\"ghost\" className=\"shrink-0 gap-1 self-start px-2 py-1.5 text-xs\" asChild>\n <Link to=\"/settings/heartbeat\">\n {c.systemHeartbeatSettingsLink}\n <ChevronRight className=\"size-3.5 opacity-70\" aria-hidden />\n </Link>\n </Button>\n </div>\n <dl className=\"mt-3 grid gap-2 text-sm sm:grid-cols-2\">\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.systemHeartbeatStatus}</dt>\n <dd className=\"text-fg\">{heartbeat.enabled ? c.enabled : c.disabled}</dd>\n </div>\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.systemHeartbeatInterval}</dt>\n <dd className=\"text-fg\">{c.systemHeartbeatEvery.replace(/\\{\\{value\\}\\}/g, hbInterval)}</dd>\n </div>\n </dl>\n </div>\n\n <div>\n <div className=\"mb-2 flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between\">\n <h3 className=\"text-sm font-semibold text-fg\">{c.systemDreamingTitle}</h3>\n <Button type=\"button\" variant=\"ghost\" className=\"shrink-0 gap-1 self-start px-2 py-1.5 text-xs\" asChild>\n <Link to=\"/settings/dreams\">\n {c.systemDreamingSettingsLink}\n <ChevronRight className=\"size-3.5 opacity-70\" aria-hidden />\n </Link>\n </Button>\n </div>\n <p className=\"mb-3 text-xs text-fg-muted\">{c.systemDreamingHint}</p>\n {loading && sortedSystemJobs.length === 0 ? (\n <div className=\"flex justify-center py-12\" aria-busy=\"true\">\n <Loader2 className=\"size-8 animate-spin text-accent\" strokeWidth={1.75} />\n </div>\n ) : sortedSystemJobs.length === 0 ? (\n <p className=\"rounded-lg border border-edge-subtle bg-surface-hover/30 px-3 py-4 text-sm text-fg-muted dark:border-edge-subtle\">\n {c.systemDreamingEmpty}\n </p>\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {sortedSystemJobs.map((job) => (\n <CronJobCard\n key={job.id}\n job={job}\n c={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n absorbCardClickJobIdRef={absorbCardClickJobIdRef}\n scheduleAbsorbNextMenuCardClick={scheduleAbsorbNextMenuCardClick}\n onOpenDetail={onOpenDetail}\n onToggle={onToggle}\n onEdit={onEdit}\n onRunNow={onRunNow}\n onDelete={onDelete}\n />\n ))}\n </div>\n )}\n </div>\n </section>\n );\n}\n","import type { MessageBundle } from '@/i18n/messages';\n\nexport type CronTemplateCopy = {\n title: string;\n description: string;\n prompt: string;\n};\n\nexport function getCronTemplateCopy(\n cron: MessageBundle['cron'],\n templateId: string,\n): CronTemplateCopy | undefined {\n const raw = cron.templates;\n if (!raw || typeof raw !== 'object') return undefined;\n const row = (raw as Record<string, { title?: string; description?: string; prompt?: string } | undefined>)[\n templateId\n ];\n if (!row || typeof row !== 'object') return undefined;\n const title = row.title?.trim();\n const prompt = row.prompt?.trim();\n if (!title || !prompt) return undefined;\n return {\n title,\n description: (row.description ?? '').trim(),\n prompt,\n };\n}\n","/** Non-display fields for scheduled-task templates; copy lives in i18n `cron.templates`. */\n\nexport const CRON_TEMPLATE_CATEGORIES = ['daily', 'monitoring', 'reports', 'automation'] as const;\nexport type CronTemplateCategory = (typeof CRON_TEMPLATE_CATEGORIES)[number];\n\nexport interface CronJobTemplateDef {\n templateId: string;\n category: CronTemplateCategory;\n defaultSchedule: string;\n defaultSessionTarget: 'isolated';\n}\n\n/** Grouped like common scheduled-task UIs: daily rhythm, external monitoring, periodic reports, repo automation. */\nexport const CRON_JOB_TEMPLATES = [\n // Daily\n {\n templateId: 'morning_briefing',\n category: 'daily',\n defaultSchedule: '0 7 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'standup_prep',\n category: 'daily',\n defaultSchedule: '0 8 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'end_of_day_wrap_up',\n category: 'daily',\n defaultSchedule: '0 18 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'inbox_triage',\n category: 'daily',\n defaultSchedule: '30 8 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n // Monitoring\n {\n templateId: 'competitor_watch',\n category: 'monitoring',\n defaultSchedule: '0 9 * * 1',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'trending_topics_monitor',\n category: 'monitoring',\n defaultSchedule: '0 10 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'tech_radar_stack',\n category: 'monitoring',\n defaultSchedule: '0 11 * * 3',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'dependency_check_audit',\n category: 'monitoring',\n defaultSchedule: '0 9 * * 0',\n defaultSessionTarget: 'isolated',\n },\n // Reports\n {\n templateId: 'weekly_review',\n category: 'reports',\n defaultSchedule: '0 17 * * 5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'code_quality_report',\n category: 'reports',\n defaultSchedule: '0 14 * * 1',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'git_activity_summary',\n category: 'reports',\n defaultSchedule: '0 9 * * 1',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'user_feedback_digest',\n category: 'reports',\n defaultSchedule: '0 16 * * 5',\n defaultSessionTarget: 'isolated',\n },\n // Automation\n {\n templateId: 'stale_todo_or_issue_sweep',\n category: 'automation',\n defaultSchedule: '0 10 * * 2',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'release_notes_or_changelog_draft',\n category: 'automation',\n defaultSchedule: '0 10 * * 4',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'workspace_cleanup_suggestions',\n category: 'automation',\n defaultSchedule: '30 18 * * 5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'smoke_or_ci_health_reminder',\n category: 'automation',\n defaultSchedule: '0 8 * * 1',\n defaultSessionTarget: 'isolated',\n },\n] as const satisfies readonly CronJobTemplateDef[];\n\nexport type CronTemplateId = (typeof CRON_JOB_TEMPLATES)[number]['templateId'];\n\nexport function cronTemplateById(id: string): (typeof CRON_JOB_TEMPLATES)[number] | undefined {\n return CRON_JOB_TEMPLATES.find((t) => t.templateId === id);\n}\n","import { Button } from '@/components/ui/button';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\nimport { getCronTemplateCopy } from '@/features/cron/cron-template-i18n';\nimport { CRON_JOB_TEMPLATES, CRON_TEMPLATE_CATEGORIES, type CronTemplateCategory } from '@/features/cron/cron-templates';\nimport { formatScheduleBadge, type ScheduleBadgeLabels } from '@/features/cron/cron-utils';\n\nexport type CronTemplateFilter = 'all' | CronTemplateCategory;\n\ntype Props = {\n cron: MessageBundle['cron'];\n localeTag: string;\n scheduleBadgeLabels: ScheduleBadgeLabels;\n categoryFilter: CronTemplateFilter;\n onCategoryFilterChange: (next: CronTemplateFilter) => void;\n onSelectTemplate: (templateId: string) => void;\n};\n\nexport function CronTemplateLibrary(props: Props) {\n const { cron, localeTag, scheduleBadgeLabels, categoryFilter, onCategoryFilterChange, onSelectTemplate } = props;\n\n const filtered =\n categoryFilter === 'all'\n ? [...CRON_JOB_TEMPLATES]\n : CRON_JOB_TEMPLATES.filter((t) => t.category === categoryFilter);\n\n return (\n <div className=\"flex w-full flex-col gap-4\">\n <div className=\"flex flex-wrap gap-2\" role=\"group\" aria-label={cron.fromTemplate}>\n <Button\n type=\"button\"\n variant={categoryFilter === 'all' ? 'secondary' : 'ghost'}\n className=\"h-8 rounded-full px-3 py-1.5 text-xs\"\n onClick={() => onCategoryFilterChange('all')}\n >\n {cron.templateFilterAll}\n </Button>\n {CRON_TEMPLATE_CATEGORIES.map((cat) => (\n <Button\n key={cat}\n type=\"button\"\n variant={categoryFilter === cat ? 'secondary' : 'ghost'}\n className=\"h-8 rounded-full px-3 py-1.5 text-xs\"\n onClick={() => onCategoryFilterChange(cat)}\n >\n {cron.templateCategories[cat]}\n </Button>\n ))}\n </div>\n {filtered.length === 0 ? (\n <p className=\"text-center text-sm text-fg-muted\">{cron.templatesEmptyHint}</p>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {filtered.map((t) => {\n const copy = getCronTemplateCopy(cron, t.templateId);\n if (!copy) return null;\n const badge = formatScheduleBadge(\n { schedule: t.defaultSchedule, timezone: undefined, next_run: undefined },\n localeTag,\n scheduleBadgeLabels,\n );\n return (\n <button\n key={t.templateId}\n type=\"button\"\n className={cn(\n 'flex flex-col gap-1.5 rounded-xl border border-edge-subtle bg-surface-base p-4 text-left transition-colors',\n 'hover:border-accent/40 hover:bg-surface-hover',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel',\n )}\n onClick={() => onSelectTemplate(t.templateId)}\n aria-label={`${cron.templateCategories[t.category]} — ${copy.title}`}\n >\n <span className=\"font-semibold text-fg\">{copy.title}</span>\n <span className=\"line-clamp-2 text-sm text-fg-muted\">{copy.description}</span>\n <span className=\"mt-1 flex items-center gap-1 text-xs text-fg-muted\">\n <span className=\"tabular-nums\">{badge}</span>\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","import { Info, Loader2 } from 'lucide-react';\nimport type { MutableRefObject } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport type { CronJob } from '@/features/cron/cron-api';\nimport { CronJobCard } from '@/features/cron/cron-job-card';\nimport type { CronTemplateFilter } from '@/features/cron/cron-template-library';\nimport { CronTemplateLibrary } from '@/features/cron/cron-template-library';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronTasksPanelProps = {\n c: CronCopy;\n localeTag: string;\n scheduleBadgeLabels: CronCopy['scheduleBadge'];\n loading: boolean;\n jobsCount: number;\n sortedJobs: CronJob[];\n templateCategoryFilter: CronTemplateFilter;\n onTemplateCategoryFilterChange: (v: CronTemplateFilter) => void;\n onSelectTemplate: (templateId: string) => void;\n keepAwake: boolean;\n wakeSupported: boolean;\n onWakeUnsupportedClick: () => void;\n onKeepAwakeToggle: () => void;\n absorbCardClickJobIdRef: MutableRefObject<string | null>;\n scheduleAbsorbNextMenuCardClick: (jobId: string) => void;\n onOpenDetail: (job: CronJob) => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onEdit: (job: CronJob) => void;\n onAddJob: () => void;\n onRunNow: (job: CronJob) => void;\n onDelete: (job: CronJob) => void;\n};\n\nexport function CronTasksPanel({\n c,\n localeTag,\n scheduleBadgeLabels,\n loading,\n jobsCount,\n sortedJobs,\n templateCategoryFilter,\n onTemplateCategoryFilterChange,\n onSelectTemplate,\n keepAwake,\n wakeSupported,\n onWakeUnsupportedClick,\n onKeepAwakeToggle,\n absorbCardClickJobIdRef,\n scheduleAbsorbNextMenuCardClick,\n onOpenDetail,\n onToggle,\n onEdit,\n onAddJob,\n onRunNow,\n onDelete,\n}: CronTasksPanelProps) {\n return (\n <section aria-labelledby=\"cron-tasks-panel\" className=\"flex flex-col gap-4\">\n <h2 id=\"cron-tasks-panel\" className=\"sr-only\">\n {c.tabMyTasks}\n </h2>\n <div className=\"flex flex-col gap-3 rounded-xl border border-accent/25 bg-accent/5 px-4 py-3 dark:border-accent/30 dark:bg-accent/10 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex gap-3 text-sm text-fg\">\n <Info className=\"mt-0.5 size-4 shrink-0 text-accent\" strokeWidth={1.75} aria-hidden />\n <p className=\"text-pretty text-fg-muted\">{c.wakeBanner}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2 sm:pl-4\">\n <span className=\"text-sm text-fg\">{c.keepAwake}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={keepAwake}\n disabled={!wakeSupported}\n title={!wakeSupported ? c.wakeLockUnavailable : undefined}\n className={cn(\n 'inline-flex h-6 w-10 shrink-0 items-center rounded-full border border-edge p-0.5 transition-colors',\n keepAwake ? 'justify-end bg-accent' : 'justify-start bg-surface-hover',\n !wakeSupported && 'cursor-not-allowed opacity-50',\n )}\n onClick={() => {\n if (!wakeSupported) onWakeUnsupportedClick();\n else onKeepAwakeToggle();\n }}\n >\n <span className=\"size-4 rounded-full bg-surface-panel shadow-surface ring-1 ring-edge/40 dark:ring-edge/55\" />\n </button>\n </div>\n </div>\n\n {loading && jobsCount === 0 ? (\n <div className=\"flex justify-center py-16\" aria-busy=\"true\">\n <Loader2 className=\"size-8 animate-spin text-accent\" strokeWidth={1.75} />\n </div>\n ) : jobsCount === 0 ? (\n <div className=\"flex flex-col gap-6 rounded-2xl bg-surface-base px-4 py-8 dark:bg-surface-hover/25 sm:px-6 sm:py-10\">\n <div className=\"w-full max-w-3xl\">\n <CronTemplateLibrary\n cron={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n categoryFilter={templateCategoryFilter}\n onCategoryFilterChange={onTemplateCategoryFilterChange}\n onSelectTemplate={onSelectTemplate}\n />\n </div>\n <div className=\"flex justify-center\">\n <Button type=\"button\" variant=\"primary\" onClick={onAddJob}>\n {c.emptyStateCta}\n </Button>\n </div>\n </div>\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {sortedJobs.map((job) => (\n <CronJobCard\n key={job.id}\n job={job}\n c={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n absorbCardClickJobIdRef={absorbCardClickJobIdRef}\n scheduleAbsorbNextMenuCardClick={scheduleAbsorbNextMenuCardClick}\n onOpenDetail={(j) => void onOpenDetail(j)}\n onToggle={(j, en) => void onToggle(j, en)}\n onEdit={onEdit}\n onRunNow={onRunNow}\n onDelete={onDelete}\n />\n ))}\n </div>\n )}\n </section>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport type { CronTemplateFilter } from '@/features/cron/cron-template-library';\nimport { CronTemplateLibrary } from '@/features/cron/cron-template-library';\nimport type { MessageBundle } from '@/i18n/messages';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronTemplatePickerDialogProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n c: CronCopy;\n localeTag: string;\n scheduleBadgeLabels: CronCopy['scheduleBadge'];\n categoryFilter: CronTemplateFilter;\n onCategoryFilterChange: (v: CronTemplateFilter) => void;\n onSelectTemplate: (templateId: string) => void;\n};\n\nexport function CronTemplatePickerDialog({\n open,\n onOpenChange,\n c,\n localeTag,\n scheduleBadgeLabels,\n categoryFilter,\n onCategoryFilterChange,\n onSelectTemplate,\n}: CronTemplatePickerDialogProps) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[62] bg-scrim\" />\n <div className=\"fixed inset-0 z-[62] flex items-center justify-center p-4 pointer-events-none\">\n <Dialog.Content\n className=\"xopc-dialog-content-pane pointer-events-auto relative flex max-h-[min(90vh,840px)] w-full max-w-lg flex-col rounded-xl border border-edge bg-surface-panel shadow-popover outline-none sm:max-w-2xl dark:border-edge\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"flex shrink-0 items-center justify-end border-b border-edge px-4 py-3\">\n <Dialog.Title className=\"sr-only\">{c.fromTemplate}</Dialog.Title>\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"h-9 w-9 shrink-0 p-0\" aria-label={c.close}>\n <X className=\"size-5\" strokeWidth={1.75} />\n </Button>\n </Dialog.Close>\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-4\">\n <CronTemplateLibrary\n cron={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n categoryFilter={categoryFilter}\n onCategoryFilterChange={onCategoryFilterChange}\n onSelectTemplate={onSelectTemplate}\n />\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { fetchChatAgents, type ChatAgentOption } from '@/features/chat/chat-agents-api';\nimport type { CronDelivery, CronJob, CronJobExecution, CronPayload, CronRunHistoryRow } from '@/features/cron/cron-api';\nimport {\n addJob,\n cronJobBodyText,\n getAllRunsHistory,\n getChannels,\n getConfig,\n getHistory,\n getJob,\n getModels,\n getSessionChatIds,\n listJobs,\n removeJob,\n runJob,\n toggleJob,\n updateJob,\n type ChannelStatus,\n type SessionChatId,\n} from '@/features/cron/cron-api';\nimport { CronConfirmActionDialog } from '@/features/cron/cron-confirm-action-dialog';\nimport { CronJobDetailDrawer } from '@/features/cron/cron-job-detail-drawer';\nimport { CronJobFormDialog } from '@/features/cron/cron-job-form-dialog';\nimport { CronMainToolbar } from '@/features/cron/cron-main-toolbar';\nimport {\n DEFAULT_SCHEDULE,\n RUN_HISTORY_FETCH_LIMIT,\n pushRecentWorkspaceDirForCron,\n startOfLocalDay,\n startOfLocalMonth,\n startOfLocalWeekMonday,\n} from '@/features/cron/cron-page-lib';\nimport { CronPageHeaderActions } from '@/features/cron/cron-page-header-actions';\nimport { isDreamingManagedCronJob } from '@/features/cron/cron-dreaming-jobs';\nimport { CronRunHistorySection } from '@/features/cron/cron-run-history-section';\nimport { CronSystemTasksPanel } from '@/features/cron/cron-system-tasks-panel';\nimport { CronTasksPanel } from '@/features/cron/cron-tasks-panel';\nimport { getCronTemplateCopy } from '@/features/cron/cron-template-i18n';\nimport type { CronTemplateFilter } from '@/features/cron/cron-template-library';\nimport { CronTemplatePickerDialog } from '@/features/cron/cron-template-picker-dialog';\nimport { cronTemplateById } from '@/features/cron/cron-templates';\nimport { fetchGatewayConfigSwrResponse } from '@/features/gateway/gateway-config-swr';\nimport { normalizeHeartbeatFromConfig } from '@/features/settings/heartbeat-config-api';\nimport { messages } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { usePageHeaderStore } from '@/stores/page-header-store';\nimport { useThemeStore } from '@/stores/theme-store';\nimport { isElectronCronDisplayWakeAvailable } from '@/lib/electron-env';\n\nexport function CronPage() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const c = m.cron;\n const chatM = m.chat;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n const resolvedTheme = useThemeStore((s) => s.resolved);\n const isDark = resolvedTheme === 'dark';\n const localeTag = language === 'zh' ? 'zh-CN' : 'en-US';\n\n const [jobs, setJobs] = useState<CronJob[]>([]);\n const [mainTab, setMainTab] = useState<'myTasks' | 'systemTasks' | 'history'>('myTasks');\n const [jobSort, setJobSort] = useState<'created_desc' | 'created_asc'>('created_desc');\n const [historyRange, setHistoryRange] = useState<'day' | 'week' | 'month'>('day');\n const [historyJobFilter, setHistoryJobFilter] = useState('');\n const [historyStatusFilter, setHistoryStatusFilter] = useState('');\n const [keepAwake, setKeepAwake] = useState(false);\n const wakeLockRef = useRef<WakeLockSentinel | null>(null);\n const wakeModeRef = useRef<'none' | 'electron' | 'navigator'>('none');\n const keepAwakeRef = useRef(keepAwake);\n const wakeSupported = typeof navigator !== 'undefined' && 'wakeLock' in navigator;\n const keepAwakeFeatureAvailable = wakeSupported || isElectronCronDisplayWakeAvailable();\n\n const [channels, setChannels] = useState<ChannelStatus[]>([]);\n const [availableModels, setAvailableModels] = useState<{ id: string; name: string; provider: string }[]>([]);\n const [defaultModel, setDefaultModel] = useState('');\n const [sessionChatIds, setSessionChatIds] = useState<SessionChatId[]>([]);\n const [chatAgents, setChatAgents] = useState<ChatAgentOption[]>([]);\n const [loading, setLoading] = useState(false);\n const [gatewayConfigRaw, setGatewayConfigRaw] = useState<unknown>(null);\n const [error, setError] = useState<string | null>(null);\n const [runHistory, setRunHistory] = useState<CronRunHistoryRow[]>([]);\n const [runHistoryLoading, setRunHistoryLoading] = useState(false);\n\n const [formOpen, setFormOpen] = useState(false);\n const [formMode, setFormMode] = useState<'add' | 'edit'>('add');\n const [formJobId, setFormJobId] = useState<string | null>(null);\n const [formName, setFormName] = useState('');\n const [formSchedule, setFormSchedule] = useState(DEFAULT_SCHEDULE);\n const [formChannel, setFormChannel] = useState('local');\n const [formChatId, setFormChatId] = useState('');\n const [formMessage, setFormMessage] = useState('');\n const [formMessageMdMode, setFormMessageMdMode] = useState<'edit' | 'preview'>('edit');\n const [messageEditorNonce, setMessageEditorNonce] = useState(0);\n const [formSessionTarget, setFormSessionTarget] = useState<'main' | 'isolated'>('main');\n const [formAgentId, setFormAgentId] = useState('');\n const [formAgentLocalOnly, setFormAgentLocalOnly] = useState(false);\n const [formWorkingDirectory, setFormWorkingDirectory] = useState('');\n const [formWdModalOpen, setFormWdModalOpen] = useState(false);\n const [formModel, setFormModel] = useState('');\n const [formSubmitting, setFormSubmitting] = useState(false);\n const formModelUserTouched = useRef(false);\n\n const [detailOpen, setDetailOpen] = useState(false);\n const [detailJob, setDetailJob] = useState<CronJob | null>(null);\n const [detailHistory, setDetailHistory] = useState<CronJobExecution[]>([]);\n const [detailLoading, setDetailLoading] = useState(false);\n\n const [confirmOpen, setConfirmOpen] = useState(false);\n const [confirmAction, setConfirmAction] = useState<'delete' | 'run' | null>(null);\n const [confirmJobId, setConfirmJobId] = useState<string | null>(null);\n\n const [templatePickerOpen, setTemplatePickerOpen] = useState(false);\n const [templateCategoryFilter, setTemplateCategoryFilter] = useState<CronTemplateFilter>('all');\n\n const absorbCardClickJobIdRef = useRef<string | null>(null);\n\n const scheduleAbsorbNextMenuCardClick = useCallback((jobId: string) => {\n absorbCardClickJobIdRef.current = jobId;\n window.setTimeout(() => {\n if (absorbCardClickJobIdRef.current === jobId) {\n absorbCardClickJobIdRef.current = null;\n }\n }, 400);\n }, []);\n\n const defaultModelForForm = useCallback(() => {\n return defaultModel || (availableModels.length > 0 ? availableModels[0].id : '');\n }, [defaultModel, availableModels]);\n\n const hasElectronFolderPicker =\n typeof window !== 'undefined' && Boolean(window.electronAPI?.file?.openDirectory);\n\n const openNativeFolderPickerCron = useCallback(async (): Promise<string | null> => {\n const api = typeof window !== 'undefined' ? window.electronAPI?.file?.openDirectory : undefined;\n if (api) return api();\n return null;\n }, []);\n\n const applyCronWorkingDirectory = useCallback(async (path: string) => {\n const t = path.trim();\n if (!t) return;\n pushRecentWorkspaceDirForCron(t);\n setFormWorkingDirectory(t);\n }, []);\n\n const cronAgentSelectOptions = useMemo(() => {\n const ids = new Set(chatAgents.map((a) => a.id));\n const out: ChatAgentOption[] = [...chatAgents];\n const extra = formAgentId.trim().toLowerCase();\n if (extra && !ids.has(extra)) {\n out.push({ id: extra });\n }\n return out;\n }, [chatAgents, formAgentId]);\n\n const needsDeliveryChat =\n formChannel !== 'local' && (formSessionTarget === 'main' || (formSessionTarget === 'isolated' && !formAgentLocalOnly));\n\n const showChannelPicker =\n formSessionTarget === 'main' || (formSessionTarget === 'isolated' && !formAgentLocalOnly);\n\n const canSubmit =\n Boolean(formName.trim()) &&\n Boolean(formSchedule.trim()) &&\n Boolean(formMessage.trim()) &&\n (!needsDeliveryChat || Boolean(formChatId.trim()));\n\n const loadRunHistoryOnly = useCallback(async () => {\n setRunHistoryLoading(true);\n try {\n const rows = await getAllRunsHistory(RUN_HISTORY_FETCH_LIMIT);\n setRunHistory(rows);\n } catch {\n /* ignore */\n } finally {\n setRunHistoryLoading(false);\n }\n }, []);\n\n const loadJobs = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const list = await listJobs();\n setJobs(list);\n } catch (e) {\n setError(e instanceof Error ? e.message : c.failedToLoadJobs);\n } finally {\n setLoading(false);\n }\n }, [c.failedToLoadJobs]);\n\n const loadAux = useCallback(async () => {\n try {\n const [ch, mods, cfg, cfgFull, agentsPayload] = await Promise.all([\n getChannels(),\n getModels(),\n getConfig(),\n fetchGatewayConfigSwrResponse(),\n fetchChatAgents().catch(() => null),\n ]);\n setChannels(ch);\n setAvailableModels(mods);\n setDefaultModel(cfg.model || '');\n setGatewayConfigRaw(cfgFull.payload?.config ?? null);\n if (agentsPayload) {\n setChatAgents(agentsPayload.items);\n }\n } catch {\n /* non-fatal */\n }\n }, []);\n\n useEffect(() => {\n if (!hasToken) return;\n void loadJobs();\n void loadAux();\n }, [hasToken, loadJobs, loadAux]);\n\n useEffect(() => {\n if (!hasToken) return;\n const onReload = () => {\n void fetchGatewayConfigSwrResponse().then((r) => {\n setGatewayConfigRaw(r.payload?.config ?? null);\n });\n };\n window.addEventListener('config-reload', onReload);\n return () => window.removeEventListener('config-reload', onReload);\n }, [hasToken]);\n\n useEffect(() => {\n if (!hasToken || mainTab !== 'history') return;\n void loadRunHistoryOnly();\n }, [hasToken, mainTab, loadRunHistoryOnly]);\n\n const releaseWakeLock = useCallback(async () => {\n if (wakeModeRef.current === 'electron') {\n try {\n await window.electronAPI?.cron?.setDisplaySleepPrevented?.(false);\n } catch {\n /* ignore */\n }\n wakeModeRef.current = 'none';\n return;\n }\n try {\n await wakeLockRef.current?.release();\n } catch {\n /* ignore */\n }\n wakeLockRef.current = null;\n wakeModeRef.current = 'none';\n }, []);\n\n const acquireWakeLock = useCallback(async () => {\n const electronWake =\n typeof window !== 'undefined' ? window.electronAPI?.cron?.setDisplaySleepPrevented : undefined;\n if (electronWake) {\n try {\n await electronWake(true);\n wakeModeRef.current = 'electron';\n return;\n } catch {\n setError(c.wakeLockUnavailable);\n setKeepAwake(false);\n return;\n }\n }\n if (!wakeSupported) return;\n try {\n const sentinel = await navigator.wakeLock.request('screen');\n wakeLockRef.current = sentinel;\n wakeModeRef.current = 'navigator';\n sentinel.addEventListener('release', () => {\n wakeLockRef.current = null;\n wakeModeRef.current = 'none';\n });\n } catch {\n setError(c.wakeLockUnavailable);\n setKeepAwake(false);\n }\n }, [c.wakeLockUnavailable, wakeSupported]);\n\n keepAwakeRef.current = keepAwake;\n\n useEffect(() => {\n if (!keepAwake) {\n void releaseWakeLock();\n return;\n }\n void acquireWakeLock();\n const onVis = () => {\n if (document.visibilityState === 'visible' && keepAwakeRef.current) void acquireWakeLock();\n };\n document.addEventListener('visibilitychange', onVis);\n return () => {\n document.removeEventListener('visibilitychange', onVis);\n void releaseWakeLock();\n };\n }, [keepAwake, acquireWakeLock, releaseWakeLock]);\n\n useEffect(() => {\n if (!formOpen || formMode !== 'add' || formModelUserTouched.current) return;\n const next = defaultModelForForm();\n if (next) setFormModel(next);\n }, [formOpen, formMode, defaultModelForForm]);\n\n useEffect(() => {\n if (!formOpen || formMode !== 'add') return;\n const valid = new Set(['local', ...channels.map((x) => x.name)]);\n if (!valid.has(formChannel)) setFormChannel('local');\n }, [channels, formChannel, formMode, formOpen]);\n\n useEffect(() => {\n if (formChannel === 'local') {\n setSessionChatIds([]);\n return;\n }\n let cancelled = false;\n void getSessionChatIds(formChannel).then((ids) => {\n if (!cancelled) setSessionChatIds(ids);\n });\n return () => {\n cancelled = true;\n };\n }, [formChannel, formOpen]);\n\n const openForm = useCallback(\n (job?: CronJob) => {\n formModelUserTouched.current = false;\n setFormOpen(true);\n setFormMode(job ? 'edit' : 'add');\n setFormJobId(job?.id ?? null);\n\n if (job) {\n setFormName(job.name || '');\n setFormSchedule((job.schedule && String(job.schedule).trim()) || DEFAULT_SCHEDULE);\n const bodyText = cronJobBodyText(job);\n setFormMessage(bodyText ?? '');\n setFormSessionTarget(job.sessionTarget || 'main');\n setFormAgentId(\n (job.sessionTarget || 'main') === 'isolated' && job.agentId?.trim()\n ? job.agentId.trim().toLowerCase()\n : '',\n );\n setFormWorkingDirectory(\n (job.sessionTarget || 'main') === 'isolated' && job.workingDirectory?.trim()\n ? job.workingDirectory.trim()\n : '',\n );\n const fromPayload =\n job.payload?.kind === 'agentTurn' && job.payload.model?.trim() ? job.payload.model.trim() : '';\n const stored = job.model?.trim() || fromPayload;\n setFormModel(stored || defaultModelForForm());\n const hasLocalChannel = job.delivery?.channel === 'local';\n const agentLocalOnly =\n (job.sessionTarget || 'main') === 'isolated' &&\n !hasLocalChannel &&\n (!job.delivery?.to || job.delivery.mode === 'none');\n setFormAgentLocalOnly(agentLocalOnly);\n\n if (hasLocalChannel) {\n setFormChannel('local');\n setFormChatId('');\n } else if (job.delivery && job.delivery.mode !== 'none' && job.delivery.to) {\n setFormChannel(job.delivery.channel || 'telegram');\n setFormChatId(job.delivery.to || '');\n } else if (!agentLocalOnly) {\n const parts = bodyText.split(':');\n const knownChannels = ['telegram', 'cli', 'gateway', 'local'];\n if (parts.length >= 3 && knownChannels.includes(parts[0])) {\n setFormChannel(parts[0]);\n setFormChatId(parts[1]);\n setFormMessage(parts.slice(2).join(':'));\n } else {\n setFormChannel('telegram');\n setFormChatId('');\n }\n } else {\n setFormChannel('telegram');\n setFormChatId('');\n }\n } else {\n setFormName('');\n setFormSchedule(DEFAULT_SCHEDULE);\n setFormChannel('local');\n setFormChatId('');\n setFormMessage('');\n setFormSessionTarget('main');\n setFormAgentId('');\n setFormWorkingDirectory('');\n setFormAgentLocalOnly(false);\n setFormModel(defaultModelForForm());\n }\n setFormMessageMdMode('edit');\n setMessageEditorNonce((n) => n + 1);\n },\n [defaultModelForForm],\n );\n\n const setMessageMdMode = useCallback((mode: 'edit' | 'preview') => {\n setFormMessageMdMode(mode);\n if (mode === 'edit') {\n setMessageEditorNonce((n) => n + 1);\n }\n }, []);\n\n const applyCronTemplate = useCallback(\n (templateId: string) => {\n const def = cronTemplateById(templateId);\n const copy = def ? getCronTemplateCopy(m.cron, templateId) : undefined;\n if (!def || !copy) return;\n formModelUserTouched.current = false;\n setFormMode('add');\n setFormJobId(null);\n setFormName(copy.title);\n setFormSchedule(def.defaultSchedule);\n setFormMessage(copy.prompt);\n setFormSessionTarget(def.defaultSessionTarget);\n setFormChannel('local');\n setFormChatId('');\n setFormAgentLocalOnly(false);\n setFormAgentId('');\n setFormWorkingDirectory('');\n setFormModel(defaultModelForForm());\n setFormMessageMdMode('edit');\n setMessageEditorNonce((n) => n + 1);\n setTemplatePickerOpen(false);\n setFormOpen(true);\n },\n [defaultModelForForm, m.cron],\n );\n\n const closeForm = useCallback(() => {\n setFormOpen(false);\n setFormMode('add');\n setFormJobId(null);\n setFormName('');\n setFormSchedule(DEFAULT_SCHEDULE);\n setFormChannel('local');\n setFormChatId('');\n setFormMessage('');\n setFormSessionTarget('main');\n setFormAgentId('');\n setFormWorkingDirectory('');\n setFormWdModalOpen(false);\n setFormAgentLocalOnly(false);\n setFormModel('');\n setFormMessageMdMode('edit');\n formModelUserTouched.current = false;\n }, []);\n\n const submitForm = async () => {\n if (!formName.trim()) {\n setError(c.nameRequired);\n return;\n }\n if (!formSchedule.trim() || !formMessage.trim()) {\n setError(c.scheduleRequired);\n return;\n }\n if (needsDeliveryChat && !formChatId.trim()) {\n setError(c.chatIdRequired);\n return;\n }\n\n setFormSubmitting(true);\n setError(null);\n try {\n const message = formMessage.trim();\n let delivery: CronDelivery;\n if (formSessionTarget === 'isolated' && formAgentLocalOnly) {\n delivery = { mode: 'none' };\n } else if (formChannel === 'local') {\n delivery = { mode: 'direct', channel: 'local' };\n } else {\n delivery = { mode: 'direct', channel: formChannel, to: formChatId.trim() };\n }\n\n const payload: CronPayload =\n formSessionTarget === 'isolated'\n ? {\n kind: 'agentTurn',\n message,\n ...(formModel.trim() ? { model: formModel.trim() } : {}),\n }\n : { kind: 'systemEvent', text: message };\n\n const modelTrimmed = formModel.trim();\n const agentIdTrim = formAgentId.trim().toLowerCase();\n const agentIdForEdit = formSessionTarget === 'main' ? null : agentIdTrim || null;\n const wdTrim = formWorkingDirectory.trim();\n const jobData = {\n name: formName.trim(),\n schedule: formSchedule.trim(),\n sessionTarget: formSessionTarget,\n model: formSessionTarget === 'isolated' && modelTrimmed ? modelTrimmed : undefined,\n delivery,\n payload,\n ...(formMode === 'edit'\n ? {\n agentId: agentIdForEdit,\n workingDirectory: formSessionTarget === 'isolated' ? wdTrim || null : null,\n }\n : {\n ...(formSessionTarget === 'isolated' && agentIdTrim ? { agentId: agentIdTrim } : {}),\n ...(formSessionTarget === 'isolated' && wdTrim ? { workingDirectory: wdTrim } : {}),\n }),\n };\n\n if (formMode === 'edit' && formJobId) {\n await updateJob(formJobId, jobData);\n } else {\n const { schedule: sched, agentId, workingDirectory, ...rest } = jobData;\n await addJob(sched, {\n ...rest,\n ...(agentId != null ? { agentId } : {}),\n ...(workingDirectory ? { workingDirectory } : {}),\n });\n }\n closeForm();\n await loadJobs();\n await loadAux();\n } catch (e) {\n setError(\n e instanceof Error\n ? e.message\n : formMode === 'edit'\n ? c.failedToUpdateJob\n : c.failedToCreateJob,\n );\n } finally {\n setFormSubmitting(false);\n }\n };\n\n const openDetail = async (job: CronJob) => {\n setDetailOpen(true);\n setDetailJob(job);\n setDetailLoading(true);\n setDetailHistory([]);\n try {\n const full = await getJob(job.id);\n if (full) {\n setDetailJob(full);\n setDetailHistory(await getHistory(job.id, 20));\n }\n } catch {\n /* keep partial */\n } finally {\n setDetailLoading(false);\n }\n };\n\n const onToggle = async (job: CronJob, enabled: boolean) => {\n try {\n await toggleJob(job.id, enabled);\n await loadJobs();\n await loadAux();\n } catch (e) {\n setError(e instanceof Error ? e.message : c.failedToToggleJob);\n }\n };\n\n const runConfirm = async () => {\n if (!confirmJobId || !confirmAction) return;\n const id = confirmJobId;\n const action = confirmAction;\n setConfirmOpen(false);\n setConfirmJobId(null);\n setConfirmAction(null);\n try {\n if (action === 'run') {\n await runJob(id);\n } else {\n await removeJob(id);\n if (detailJob?.id === id) {\n setDetailOpen(false);\n setDetailJob(null);\n }\n }\n await loadJobs();\n await loadAux();\n await loadRunHistoryOnly();\n } catch (e) {\n setError(e instanceof Error ? e.message : c.actionFailed);\n }\n };\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n if (formOpen) closeForm();\n else if (detailOpen) {\n setDetailOpen(false);\n setDetailJob(null);\n }\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, [formOpen, detailOpen, closeForm]);\n\n const statusLabels = useMemo(\n () => ({\n running: c.execStatusRunning,\n success: c.execStatusSuccess,\n failed: c.execStatusFailed,\n cancelled: c.execStatusCancelled,\n }),\n [c.execStatusCancelled, c.execStatusFailed, c.execStatusRunning, c.execStatusSuccess],\n );\n\n const userCronJobs = useMemo(() => jobs.filter((j) => !isDreamingManagedCronJob(j)), [jobs]);\n const systemCronJobs = useMemo(() => jobs.filter((j) => isDreamingManagedCronJob(j)), [jobs]);\n\n const sortJobsByCreated = useCallback(\n (arr: CronJob[]) => {\n const next = [...arr];\n next.sort((a, b) => {\n const ta = new Date(a.created_at).getTime();\n const tb = new Date(b.created_at).getTime();\n return jobSort === 'created_desc' ? tb - ta : ta - tb;\n });\n return next;\n },\n [jobSort],\n );\n\n const sortedUserJobs = useMemo(() => sortJobsByCreated(userCronJobs), [sortJobsByCreated, userCronJobs]);\n const sortedSystemJobs = useMemo(() => sortJobsByCreated(systemCronJobs), [sortJobsByCreated, systemCronJobs]);\n\n const heartbeatFromConfig = useMemo(\n () => normalizeHeartbeatFromConfig(gatewayConfigRaw),\n [gatewayConfigRaw],\n );\n\n const filteredRunHistory = useMemo(() => {\n const now = new Date();\n const from =\n historyRange === 'day'\n ? startOfLocalDay(now)\n : historyRange === 'week'\n ? startOfLocalWeekMonday(now)\n : startOfLocalMonth(now);\n return runHistory.filter((row) => {\n if (new Date(row.startedAt) < from) return false;\n if (historyJobFilter && row.jobId !== historyJobFilter) return false;\n if (historyStatusFilter && row.status !== historyStatusFilter) return false;\n return true;\n });\n }, [runHistory, historyRange, historyJobFilter, historyStatusFilter]);\n\n const scheduleBadgeLabels = c.scheduleBadge;\n\n const refreshAll = useCallback(() => {\n void loadJobs();\n void loadAux();\n void loadRunHistoryOnly();\n }, [loadJobs, loadAux, loadRunHistoryOnly]);\n\n const setPageHeader = usePageHeaderStore((s) => s.setPageHeader);\n const clearPageHeader = usePageHeaderStore((s) => s.clearPageHeader);\n const { pathname } = useLocation();\n const inSettingsShell = pathname.startsWith('/settings/');\n\n const handleFormSessionTargetChange = useCallback(\n (target: 'main' | 'isolated', defaultModelFallback: () => string, currentModel: string) => {\n setFormSessionTarget(target);\n if (target === 'main') {\n setFormAgentLocalOnly(false);\n setFormAgentId('');\n setFormWorkingDirectory('');\n } else if (target === 'isolated' && !currentModel) setFormModel(defaultModelFallback());\n },\n [],\n );\n\n const refreshRecipientsList = useCallback(() => {\n void getSessionChatIds(formChannel).then(setSessionChatIds);\n }, [formChannel]);\n\n const cronHeaderEnd = useMemo(\n () => (\n <CronPageHeaderActions\n c={c}\n loading={loading}\n runHistoryLoading={runHistoryLoading}\n onRefresh={refreshAll}\n onOpenTemplatePicker={() => {\n setTemplateCategoryFilter('all');\n setTemplatePickerOpen(true);\n }}\n onAddJob={() => openForm()}\n />\n ),\n [c, loading, openForm, refreshAll, runHistoryLoading],\n );\n\n useLayoutEffect(() => {\n if (!hasToken || inSettingsShell) {\n clearPageHeader();\n return () => clearPageHeader();\n }\n setPageHeader({\n startExtra: null,\n main: null,\n end: cronHeaderEnd,\n });\n return () => clearPageHeader();\n }, [clearPageHeader, cronHeaderEnd, hasToken, inSettingsShell, setPageHeader]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto w-full max-w-app-main px-4 py-16 text-center text-sm text-fg-muted sm:px-8\">{c.needToken}</div>\n );\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col overflow-y-auto bg-surface-panel\">\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6 sm:px-8\">\n {error ? (\n <div\n className=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800 dark:border-red-900/50 dark:bg-red-950/40 dark:text-red-200\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : null}\n\n <header className=\"flex flex-col gap-4\">\n <div className=\"min-w-0\">\n <h1 className=\"text-xl font-semibold tracking-tight text-fg\">{c.title}</h1>\n <p className=\"mt-1 max-w-2xl text-sm text-fg-muted\">{c.subtitle}</p>\n </div>\n </header>\n\n {inSettingsShell ? (\n <div className=\"flex flex-wrap items-center justify-end gap-2 border-b border-edge-subtle pb-3 dark:border-edge-subtle\">\n {cronHeaderEnd}\n </div>\n ) : null}\n\n <CronMainToolbar\n c={c}\n mainTab={mainTab}\n onMainTabChange={setMainTab}\n jobSort={jobSort}\n onJobSortChange={setJobSort}\n historyRange={historyRange}\n onHistoryRangeChange={setHistoryRange}\n historyJobFilter={historyJobFilter}\n onHistoryJobFilterChange={setHistoryJobFilter}\n historyStatusFilter={historyStatusFilter}\n onHistoryStatusFilterChange={setHistoryStatusFilter}\n jobs={jobs}\n />\n\n {mainTab === 'myTasks' ? (\n <CronTasksPanel\n c={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n loading={loading}\n jobsCount={userCronJobs.length}\n sortedJobs={sortedUserJobs}\n templateCategoryFilter={templateCategoryFilter}\n onTemplateCategoryFilterChange={setTemplateCategoryFilter}\n onSelectTemplate={applyCronTemplate}\n keepAwake={keepAwake}\n wakeSupported={keepAwakeFeatureAvailable}\n onWakeUnsupportedClick={() => setError(c.wakeLockUnavailable)}\n onKeepAwakeToggle={() => setKeepAwake((v) => !v)}\n absorbCardClickJobIdRef={absorbCardClickJobIdRef}\n scheduleAbsorbNextMenuCardClick={scheduleAbsorbNextMenuCardClick}\n onOpenDetail={(j) => void openDetail(j)}\n onToggle={(j, en) => void onToggle(j, en)}\n onEdit={(j) => openForm(j)}\n onAddJob={() => openForm()}\n onRunNow={(j) => {\n setConfirmAction('run');\n setConfirmJobId(j.id);\n setConfirmOpen(true);\n }}\n onDelete={(j) => {\n setConfirmAction('delete');\n setConfirmJobId(j.id);\n setConfirmOpen(true);\n }}\n />\n ) : mainTab === 'systemTasks' ? (\n <CronSystemTasksPanel\n c={c}\n language={language}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n loading={loading}\n sortedSystemJobs={sortedSystemJobs}\n heartbeat={heartbeatFromConfig}\n keepAwake={keepAwake}\n wakeSupported={keepAwakeFeatureAvailable}\n onWakeUnsupportedClick={() => setError(c.wakeLockUnavailable)}\n onKeepAwakeToggle={() => setKeepAwake((v) => !v)}\n absorbCardClickJobIdRef={absorbCardClickJobIdRef}\n scheduleAbsorbNextMenuCardClick={scheduleAbsorbNextMenuCardClick}\n onOpenDetail={(j) => void openDetail(j)}\n onToggle={(j, en) => void onToggle(j, en)}\n onEdit={(j) => openForm(j)}\n onRunNow={(j) => {\n setConfirmAction('run');\n setConfirmJobId(j.id);\n setConfirmOpen(true);\n }}\n onDelete={(j) => {\n setConfirmAction('delete');\n setConfirmJobId(j.id);\n setConfirmOpen(true);\n }}\n />\n ) : (\n <CronRunHistorySection\n c={c}\n runHistoryLoading={runHistoryLoading}\n runHistory={runHistory}\n filteredRunHistory={filteredRunHistory}\n jobs={jobs}\n onRefreshHistory={() => void loadRunHistoryOnly()}\n onOpenJobDetail={(j) => void openDetail(j)}\n statusLabels={statusLabels}\n />\n )}\n </div>\n\n <CronJobFormDialog\n open={formOpen}\n onRequestClose={closeForm}\n c={c}\n chatM={chatM}\n agentsMessages={m.agentsSettings}\n isDark={isDark}\n channels={channels}\n sessionChatIds={sessionChatIds}\n cronAgentSelectOptions={cronAgentSelectOptions}\n hasElectronFolderPicker={hasElectronFolderPicker}\n openNativeFolderPicker={openNativeFolderPickerCron}\n applyWorkingDirectory={applyCronWorkingDirectory}\n wdModalOpen={formWdModalOpen}\n onWdModalOpenChange={setFormWdModalOpen}\n defaultModelResolver={defaultModelForForm}\n formMode={formMode}\n formJobId={formJobId}\n formName={formName}\n onFormNameChange={setFormName}\n formSchedule={formSchedule}\n onFormScheduleChange={setFormSchedule}\n formSubmitting={formSubmitting}\n formSessionTarget={formSessionTarget}\n onFormSessionTargetChange={handleFormSessionTargetChange}\n formAgentLocalOnly={formAgentLocalOnly}\n onFormAgentLocalOnlyChange={setFormAgentLocalOnly}\n formModel={formModel}\n onFormModelUserChange={(id) => {\n formModelUserTouched.current = true;\n setFormModel(id);\n }}\n formAgentId={formAgentId}\n onFormAgentIdChange={setFormAgentId}\n formWorkingDirectory={formWorkingDirectory}\n onFormWorkingDirectoryChange={setFormWorkingDirectory}\n formChannel={formChannel}\n onFormChannelChange={(v) => {\n setFormChannel(v);\n if (v === 'local') setFormAgentLocalOnly(false);\n setFormChatId('');\n }}\n formChatId={formChatId}\n onFormChatIdChange={setFormChatId}\n formMessage={formMessage}\n onFormMessageChange={setFormMessage}\n formMessageMdMode={formMessageMdMode}\n onSetMessageMdMode={setMessageMdMode}\n messageEditorNonce={messageEditorNonce}\n needsDeliveryChat={needsDeliveryChat}\n showChannelPicker={showChannelPicker}\n canSubmit={canSubmit}\n onSubmit={() => void submitForm()}\n onRefreshRecipients={refreshRecipientsList}\n />\n\n <CronTemplatePickerDialog\n open={templatePickerOpen}\n onOpenChange={(openNext) => {\n setTemplatePickerOpen(openNext);\n if (openNext) setTemplateCategoryFilter('all');\n }}\n c={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n categoryFilter={templateCategoryFilter}\n onCategoryFilterChange={setTemplateCategoryFilter}\n onSelectTemplate={applyCronTemplate}\n />\n\n <CronJobDetailDrawer\n open={detailOpen}\n onDismiss={() => {\n setDetailOpen(false);\n setDetailJob(null);\n }}\n detailJob={detailJob}\n detailLoading={detailLoading}\n detailHistory={detailHistory}\n c={c}\n chatWorkingDirNotSet={chatM.workingDirectory.notSet}\n statusLabels={statusLabels}\n />\n\n <CronConfirmActionDialog\n open={confirmOpen}\n onOpenChange={setConfirmOpen}\n action={confirmAction}\n c={c}\n onDismiss={() => {\n setConfirmOpen(false);\n setConfirmJobId(null);\n setConfirmAction(null);\n }}\n onConfirm={runConfirm}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cron-page-CdYb690n.js","names":[],"sources":["../../../../../web/src/features/cron/cron-confirm-action-dialog.tsx","../../../../../web/src/features/cron/cron-page-lib.ts","../../../../../web/src/features/cron/cron-job-detail-drawer.tsx","../../../../../web/src/features/cron/cron-schedule-form.tsx","../../../../../web/src/features/cron/cron-job-form-dialog.tsx","../../../../../web/src/features/cron/cron-main-toolbar.tsx","../../../../../web/src/features/cron/cron-page-header-actions.tsx","../../../../../web/src/features/cron/cron-run-history-section.tsx","../../../../../web/src/features/cron/cron-job-card.tsx","../../../../../web/src/features/cron/cron-system-tasks-panel.tsx","../../../../../web/src/features/cron/cron-template-i18n.ts","../../../../../web/src/features/cron/cron-templates.ts","../../../../../web/src/features/cron/cron-template-library.tsx","../../../../../web/src/features/cron/cron-tasks-panel.tsx","../../../../../web/src/features/cron/cron-template-picker-dialog.tsx","../../../../../web/src/features/cron/cron-page.tsx"],"sourcesContent":["import * as Dialog from '@radix-ui/react-dialog';\n\nimport { Button } from '@/components/ui/button';\nimport type { MessageBundle } from '@/i18n/messages';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronConfirmActionDialogProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n action: 'delete' | 'run' | null;\n c: CronCopy;\n onDismiss: () => void;\n onConfirm: () => void;\n};\n\nexport function CronConfirmActionDialog({\n open,\n onOpenChange,\n action,\n c,\n onDismiss,\n onConfirm,\n}: CronConfirmActionDialogProps) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[70] bg-scrim\" />\n <div className=\"fixed inset-0 z-[70] flex items-center justify-center p-4 pointer-events-none\">\n <Dialog.Content className=\"xopc-dialog-content-pane pointer-events-auto relative w-full max-w-md rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge\">\n <Dialog.Title className=\"text-base font-semibold text-fg\">\n {action === 'delete' ? c.delete : c.runNow}\n </Dialog.Title>\n <p className=\"mt-2 text-sm text-fg-muted\">\n {action === 'delete' ? c.confirmDelete : c.confirmRun}\n </p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button type=\"button\" variant=\"secondary\" onClick={onDismiss}>\n {c.cancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n className={action === 'delete' ? 'bg-red-600 hover:bg-red-700' : undefined}\n onClick={() => void onConfirm()}\n >\n {action === 'delete' ? c.delete : c.runNow}\n </Button>\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import {\n formControlBorderFocusClass,\n nativeSelectMaxWidthClass,\n selectControlBaseClass,\n} from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\n\nexport const RUN_HISTORY_FETCH_LIMIT = 400;\n\nexport const DEFAULT_SCHEDULE = '*/5 * * * *';\n\n/** Same storage key as chat composer so recent folders stay in sync. */\nexport const RECENT_WD_STORAGE_KEY = 'xopc.recentWorkspaceDirs.v1';\nexport const RECENT_WD_MAX = 10;\n\nexport function startOfLocalDay(d: Date): Date {\n const x = new Date(d);\n x.setHours(0, 0, 0, 0);\n return x;\n}\n\n/** Week starts on Monday (local). */\nexport function startOfLocalWeekMonday(d: Date): Date {\n const x = startOfLocalDay(d);\n const day = x.getDay();\n const diff = day === 0 ? -6 : 1 - day;\n x.setDate(x.getDate() + diff);\n return x;\n}\n\nexport function startOfLocalMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), 1, 0, 0, 0, 0);\n}\n\nexport function navigateToSessionChat(sessionKey: string | undefined | null): void {\n const sk = sessionKey?.trim();\n if (!sk) return;\n window.dispatchEvent(\n new CustomEvent('navigate-to-chat', { detail: { sessionKey: sk }, bubbles: true }),\n );\n}\n\nexport function pushRecentWorkspaceDirForCron(path: string): void {\n const t = path.trim();\n if (!t) return;\n try {\n const raw = localStorage.getItem(RECENT_WD_STORAGE_KEY);\n const parsed = raw ? (JSON.parse(raw) as unknown) : [];\n const prev = Array.isArray(parsed)\n ? parsed.filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n : [];\n const next = [t, ...prev.filter((p) => p !== t)].slice(0, RECENT_WD_MAX);\n localStorage.setItem(RECENT_WD_STORAGE_KEY, JSON.stringify(next));\n } catch {\n /* ignore */\n }\n}\n\nexport function inputClassName(disabled?: boolean): string {\n return cn(\n 'w-full rounded-md border border-edge bg-surface-base px-3 py-2 text-sm text-fg placeholder:text-fg-disabled',\n formControlBorderFocusClass,\n disabled && 'cursor-not-allowed opacity-60',\n );\n}\n\nexport function selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nexport const cronRecipientSelectClass = cn(\n selectControlBaseClass,\n 'w-full text-xs sm:w-auto sm:min-w-[11rem] sm:max-w-[17rem] sm:shrink-0',\n);\n\n/** Toolbar filters: avoid `w-full` from {@link nativeSelectMaxWidthClass} so Day/Week/Month + selects stay one row. */\nexport const cronToolbarSelectClass = cn(\n selectControlBaseClass,\n 'w-auto min-w-[9rem] max-w-[14rem] shrink-0 text-xs',\n);\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { Loader2, X } from 'lucide-react';\n\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { Button } from '@/components/ui/button';\nimport type { CronJob, CronJobExecution } from '@/features/cron/cron-api';\nimport { cronJobBodyText } from '@/features/cron/cron-api';\nimport { navigateToSessionChat } from '@/features/cron/cron-page-lib';\nimport {\n execStatusLabel,\n formatDeliveryToSummary,\n formatDuration,\n formatNextRun,\n formatTime,\n truncate,\n} from '@/features/cron/cron-utils';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronJobDetailDrawerProps = {\n open: boolean;\n onDismiss: () => void;\n detailJob: CronJob | null;\n detailLoading: boolean;\n detailHistory: CronJobExecution[];\n c: CronCopy;\n chatWorkingDirNotSet: string;\n statusLabels: {\n running: string;\n success: string;\n failed: string;\n cancelled: string;\n };\n};\n\nexport function CronJobDetailDrawer({\n open,\n onDismiss,\n detailJob,\n detailLoading,\n detailHistory,\n c,\n chatWorkingDirNotSet,\n statusLabels,\n}: CronJobDetailDrawerProps) {\n return (\n <Dialog.Root\n open={open}\n onOpenChange={(next) => {\n if (!next) onDismiss();\n }}\n >\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-drawer-right fixed right-0 top-0 z-[60] flex h-full w-full max-w-lg flex-col border-l border-edge bg-surface-panel shadow-popover outline-none',\n 'dark:border-edge',\n )}\n aria-describedby={undefined}\n >\n <div className=\"flex shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3\">\n <Dialog.Title className=\"min-w-0 truncate text-base font-semibold text-fg\">\n {detailJob?.name?.trim() || detailJob?.id || '—'}\n </Dialog.Title>\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"h-9 w-9 shrink-0 p-0\" aria-label={c.close}>\n <X className=\"size-5\" strokeWidth={1.75} />\n </Button>\n </Dialog.Close>\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-3\">\n {detailLoading ? (\n <div className=\"flex justify-center py-16\">\n <Loader2 className=\"size-8 animate-spin text-accent\" strokeWidth={1.75} />\n </div>\n ) : detailJob ? (\n <>\n <dl className=\"space-y-3 text-sm\">\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.scheduleLabel}</dt>\n <dd className=\"mt-1 font-mono text-fg\">\n <code>{detailJob.schedule}</code>\n </dd>\n </div>\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.messageLabel}</dt>\n <dd className=\"mt-1 min-w-0 break-words text-fg\">\n <MarkdownView content={cronJobBodyText(detailJob)} compact className=\"text-sm\" />\n </dd>\n </div>\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.mode}</dt>\n <dd className=\"mt-1 text-fg\">\n {detailJob.sessionTarget === 'isolated' ? c.modeAgentOption : c.modeDirectOption}\n </dd>\n </div>\n {detailJob.sessionTarget === 'isolated' ? (\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.agentProfile}</dt>\n <dd className=\"mt-1 font-mono text-sm text-fg\">\n {detailJob.agentId?.trim() ? detailJob.agentId.trim() : c.agentProfileDefault}\n </dd>\n </div>\n ) : null}\n {detailJob.sessionTarget === 'isolated' ? (\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.workingDirectoryLabel}</dt>\n <dd className=\"mt-1 break-all font-mono text-xs text-fg\">\n {detailJob.workingDirectory?.trim()\n ? detailJob.workingDirectory.trim()\n : chatWorkingDirNotSet}\n </dd>\n </div>\n ) : null}\n {detailJob.delivery?.channel === 'local' ||\n (detailJob.sessionTarget === 'isolated' && !detailJob.delivery?.to) ? (\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.deliveryTarget}</dt>\n <dd className=\"mt-1 text-fg\">\n {detailJob.delivery?.channel === 'local'\n ? c.deliveryTargetLocalChannel\n : c.deliveryLocalOnly}\n </dd>\n </div>\n ) : detailJob.delivery?.to ? (\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.deliveryTarget}</dt>\n <dd className=\"mt-1 break-words text-fg\">\n <code className=\"text-xs\">{detailJob.delivery?.channel ?? ''}</code>\n {' → '}\n {formatDeliveryToSummary(detailJob, c.channelLocal)}\n </dd>\n </div>\n ) : null}\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.status}</dt>\n <dd className=\"mt-1 text-fg\">{detailJob.enabled ? c.enabled : c.disabled}</dd>\n </div>\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.nextRun}</dt>\n <dd className=\"mt-1 text-fg\">\n {detailJob.next_run ? formatNextRun(detailJob.next_run, c.timeLabels) : '—'}\n </dd>\n </div>\n </dl>\n <h3 className=\"mt-6 text-sm font-semibold text-fg\">{c.detailRunHistory}</h3>\n {detailHistory.length === 0 ? (\n <p className=\"mt-2 text-sm text-fg-muted\">{c.noRunsYet}</p>\n ) : (\n <div className=\"mt-2 overflow-x-auto\">\n <table className=\"w-full border-collapse text-left text-xs\">\n <thead>\n <tr className=\"border-b border-edge text-fg-muted\">\n <th className=\"py-1.5 pr-2 font-medium\">{c.colStarted}</th>\n <th className=\"py-1.5 pr-2 font-medium\">{c.status}</th>\n <th className=\"py-1.5 pr-2 font-medium\">{c.colDuration}</th>\n <th className=\"py-1.5 pr-2 font-medium\">{c.colDetail}</th>\n <th className=\"py-1.5 font-medium\">{c.colChat}</th>\n </tr>\n </thead>\n <tbody>\n {detailHistory.map((row) => (\n <tr key={row.id} className=\"border-b border-edge/60\">\n <td className=\"whitespace-nowrap py-1.5 pr-2 text-fg\">\n <time dateTime={row.startedAt}>{formatTime(row.startedAt)}</time>\n </td>\n <td className=\"py-1.5 pr-2\">\n <span\n className={cn(\n 'inline-flex rounded px-1.5 py-0.5 font-medium',\n row.status === 'success' &&\n 'bg-emerald-500/15 text-emerald-800 dark:text-emerald-300',\n row.status === 'failed' && 'bg-red-500/15 text-red-800 dark:text-red-300',\n )}\n >\n {execStatusLabel(row.status, statusLabels)}\n </span>\n </td>\n <td className=\"py-1.5 pr-2 text-fg-muted\">{formatDuration(row.duration)}</td>\n <td\n className=\"max-w-[8rem] truncate py-1.5 pr-2 text-fg-muted\"\n title={row.summary || row.error || ''}\n >\n {truncate(row.summary || row.error, 120)}\n </td>\n <td className=\"whitespace-nowrap py-1.5\">\n {row.sessionKey?.trim() ? (\n <button\n type=\"button\"\n className=\"text-xs font-medium text-accent hover:underline\"\n title={c.openChatTitle}\n aria-label={c.openChatTitle}\n onClick={() => navigateToSessionChat(row.sessionKey)}\n >\n {c.openChat}\n </button>\n ) : (\n <span className=\"text-fg-disabled\">—</span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </>\n ) : null}\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import { CronExpressionParser } from 'cron-parser';\nimport { useCallback, useEffect, useMemo, useState, type ChangeEvent } from 'react';\n\nimport { cn } from '@/lib/cn';\nimport { formControlBorderFocusClass, selectControlBaseClass } from '@/lib/form-field-width';\n\n/** Matches design order: 不重复 → 间隔 → 每小时 → 每天 → 每周 → 每月 → 自定义 */\nexport type SchedulePickerMode =\n | 'no_repeat'\n | 'interval'\n | 'hourly'\n | 'daily'\n | 'weekly'\n | 'monthly'\n | 'custom';\n\nexport type IntervalKind = 'minutes' | 'hours';\n\nexport type CronSchedulePickerLabels = {\n scheduleTimeLabel: string;\n modeNoRepeat: string;\n modeInterval: string;\n intervalKindMinutes: string;\n intervalKindHours: string;\n modeHourly: string;\n modeDaily: string;\n modeWeekly: string;\n modeMonthly: string;\n modeCustom: string;\n minuteUnit: string;\n minuteAtHour: string;\n intervalMinutes: string;\n intervalHours: string;\n hourUnit: string;\n dayOfMonth: string;\n customCronHint: string;\n /** Seven labels (Sun–Sat); JSON locales use `string[]` at compile time. */\n weekdays: readonly string[];\n};\n\nconst pickerSelectClass = cn(\n selectControlBaseClass,\n 'min-w-0 shrink text-xs sm:min-w-[7rem] sm:max-w-[11rem]',\n);\n\nconst timeInputClass = cn(\n 'h-9 min-w-[6.5rem] shrink-0 rounded-lg border border-edge-subtle bg-surface-panel px-2 py-1.5 text-sm text-fg',\n formControlBorderFocusClass,\n 'dark:bg-surface-panel',\n);\n\nconst dateInputClass = cn(\n 'h-9 min-w-[9.5rem] shrink-0 rounded-lg border border-edge-subtle bg-surface-panel px-2 py-1.5 text-sm text-fg',\n formControlBorderFocusClass,\n);\n\nconst numberInputClass = cn(\n 'h-9 w-14 shrink-0 rounded-lg border border-edge-subtle bg-surface-panel px-2 py-1.5 text-center text-sm tabular-nums text-fg',\n formControlBorderFocusClass,\n);\n\nconst cronTextareaClass = cn(\n 'min-h-[2.5rem] w-full rounded-lg border border-edge-subtle bg-surface-base px-3 py-2 font-mono text-xs text-fg',\n formControlBorderFocusClass,\n);\n\nfunction defaultTodayYmd(): string {\n const d = new Date();\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;\n}\n\nfunction numericFieldValues(values: unknown): number[] {\n if (!Array.isArray(values)) return [];\n return values.filter((v): v is number => typeof v === 'number').sort((a, b) => a - b);\n}\n\nfunction uniformStep(sorted: number[]): number | null {\n if (sorted.length < 2) return null;\n const step = sorted[1] - sorted[0];\n if (step <= 0) return null;\n for (let i = 2; i < sorted.length; i++) {\n if (sorted[i] - sorted[i - 1] !== step) return null;\n }\n return step;\n}\n\n/** UI week: index 0=Mon … 6=Sun → cron 1–6,0 */\nfunction uiWeekDaysToCron(d: boolean[]): string {\n const parts: number[] = [];\n for (let i = 0; i < 7; i++) {\n if (!d[i]) continue;\n parts.push(i === 6 ? 0 : i + 1);\n }\n if (parts.length === 0) return '1';\n return parts.sort((a, b) => a - b).join(',');\n}\n\nfunction cronDowListToUiWeekDays(cronDows: number[]): boolean[] {\n const out = [false, false, false, false, false, false, false];\n for (const v of cronDows) {\n const js = v === 0 || v === 7 ? 6 : v - 1;\n if (js >= 0 && js <= 6) out[js] = true;\n }\n return out;\n}\n\nexport type PickerState = {\n mode: SchedulePickerMode;\n intervalKind: IntervalKind;\n onceDate: string;\n intervalMinutes: number;\n intervalHours: number;\n minute: number;\n hour: number;\n weekDays: boolean[];\n dayOfMonth: number;\n rawCron: string;\n};\n\nexport function cronExpressionToPickerState(expr: string): PickerState {\n const rawCron = expr.trim();\n const fallback: PickerState = {\n mode: 'custom',\n intervalKind: 'minutes',\n onceDate: defaultTodayYmd(),\n intervalMinutes: 5,\n intervalHours: 2,\n minute: 0,\n hour: 9,\n weekDays: [true, true, true, true, true, false, false],\n dayOfMonth: 1,\n rawCron,\n };\n\n if (!rawCron) return { ...fallback, mode: 'interval', rawCron: '*/5 * * * *' };\n\n try {\n const p = CronExpressionParser.parse(rawCron);\n const f = p.fields;\n const m = numericFieldValues(f.minute.values);\n const h = numericFieldValues(f.hour.values);\n const dom = numericFieldValues(f.dayOfMonth.values);\n const mon = numericFieldValues(f.month.values);\n const dow = numericFieldValues(f.dayOfWeek.values);\n\n if (m.length === 60 && f.hour.isWildcard && f.dayOfMonth.isWildcard && f.month.isWildcard && f.dayOfWeek.isWildcard) {\n return { ...fallback, mode: 'interval', intervalKind: 'minutes', intervalMinutes: 1, rawCron };\n }\n if (\n !f.minute.isWildcard &&\n f.hour.isWildcard &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard &&\n m.length > 1\n ) {\n const step = uniformStep(m);\n if (step != null && step > 0) {\n return { ...fallback, mode: 'interval', intervalKind: 'minutes', intervalMinutes: step, rawCron };\n }\n }\n if (\n !f.minute.isWildcard &&\n m.length === 1 &&\n !f.hour.isWildcard &&\n h.length > 1 &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard\n ) {\n const step = uniformStep(h);\n if (step != null && step > 0) {\n return { ...fallback, mode: 'interval', intervalKind: 'hours', intervalHours: step, minute: m[0], rawCron };\n }\n }\n if (\n !f.minute.isWildcard &&\n m.length === 1 &&\n f.hour.isWildcard &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard &&\n h.length === 24\n ) {\n return { ...fallback, mode: 'hourly', minute: m[0], rawCron };\n }\n\n /** Specific calendar day each year: minute hour dom mon * */\n if (\n m.length === 1 &&\n h.length === 1 &&\n dom.length === 1 &&\n mon.length === 1 &&\n !f.dayOfMonth.isWildcard &&\n !f.month.isWildcard &&\n f.dayOfWeek.isWildcard\n ) {\n const y = new Date().getFullYear();\n const mo = mon[0];\n const d = dom[0];\n const onceDate = `${y}-${String(mo).padStart(2, '0')}-${String(d).padStart(2, '0')}`;\n return {\n ...fallback,\n mode: 'no_repeat',\n minute: m[0],\n hour: h[0],\n onceDate,\n rawCron,\n };\n }\n\n if (\n m.length === 1 &&\n h.length === 1 &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard\n ) {\n return {\n ...fallback,\n mode: 'daily',\n minute: m[0],\n hour: h[0],\n rawCron,\n };\n }\n if (\n m.length === 1 &&\n h.length === 1 &&\n f.dayOfMonth.isWildcard &&\n f.month.isWildcard &&\n !f.dayOfWeek.isWildcard &&\n dow.length > 0\n ) {\n return {\n ...fallback,\n mode: 'weekly',\n minute: m[0],\n hour: h[0],\n weekDays: cronDowListToUiWeekDays(dow),\n rawCron,\n };\n }\n if (\n m.length === 1 &&\n h.length === 1 &&\n !f.dayOfMonth.isWildcard &&\n dom.length === 1 &&\n f.month.isWildcard &&\n f.dayOfWeek.isWildcard\n ) {\n return {\n ...fallback,\n mode: 'monthly',\n minute: m[0],\n hour: h[0],\n dayOfMonth: dom[0],\n rawCron,\n };\n }\n } catch {\n /* fall through */\n }\n return fallback;\n}\n\nexport function buildCronFromPickerState(s: PickerState): string {\n const clamp = (n: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, n));\n\n switch (s.mode) {\n case 'custom':\n return s.rawCron.trim() || '*/5 * * * *';\n case 'no_repeat': {\n const parts = s.onceDate.split('-');\n if (parts.length === 3) {\n const dom = clamp(parseInt(parts[2], 10), 1, 31);\n const mo = clamp(parseInt(parts[1], 10), 1, 12);\n const min = clamp(s.minute, 0, 59);\n const h = clamp(s.hour, 0, 23);\n return `${min} ${h} ${dom} ${mo} *`;\n }\n return '0 9 1 1 *';\n }\n case 'interval':\n if (s.intervalKind === 'hours') {\n const n = clamp(Math.round(s.intervalHours) || 1, 1, 23);\n const min = clamp(s.minute, 0, 59);\n return `${min} */${n} * * *`;\n }\n {\n const n = clamp(Math.round(s.intervalMinutes) || 5, 1, 59);\n return `*/${n} * * * *`;\n }\n case 'hourly': {\n const min = clamp(s.minute, 0, 59);\n return `${min} * * * *`;\n }\n case 'daily': {\n const min = clamp(s.minute, 0, 59);\n const h = clamp(s.hour, 0, 23);\n return `${min} ${h} * * *`;\n }\n case 'weekly': {\n const min = clamp(s.minute, 0, 59);\n const h = clamp(s.hour, 0, 23);\n const dow = uiWeekDaysToCron(s.weekDays);\n return `${min} ${h} * * ${dow}`;\n }\n case 'monthly': {\n const min = clamp(s.minute, 0, 59);\n const h = clamp(s.hour, 0, 23);\n const dom = clamp(Math.round(s.dayOfMonth) || 1, 1, 31);\n return `${min} ${h} ${dom} * *`;\n }\n default:\n return '*/5 * * * *';\n }\n}\n\ntype CronSchedulePickerProps = {\n value: string;\n onChange: (cron: string) => void;\n labels: CronSchedulePickerLabels;\n disabled?: boolean;\n};\n\nexport function CronSchedulePicker({ value, onChange, labels, disabled }: CronSchedulePickerProps) {\n const parsed = useMemo(() => cronExpressionToPickerState(value), [value]);\n\n const [mode, setMode] = useState<SchedulePickerMode>(parsed.mode);\n const [intervalKind, setIntervalKind] = useState<IntervalKind>(parsed.intervalKind);\n const [onceDate, setOnceDate] = useState(parsed.onceDate);\n const [intervalMinutes, setIntervalMinutes] = useState(parsed.intervalMinutes);\n const [intervalHours, setIntervalHours] = useState(parsed.intervalHours);\n const [minute, setMinute] = useState(parsed.minute);\n const [hour, setHour] = useState(parsed.hour);\n const [weekDays, setWeekDays] = useState<boolean[]>(parsed.weekDays);\n const [dayOfMonth, setDayOfMonth] = useState(parsed.dayOfMonth);\n const [rawCron, setRawCron] = useState(parsed.rawCron);\n const [intervalMinutesDraft, setIntervalMinutesDraft] = useState<string | null>(null);\n const [intervalHoursDraft, setIntervalHoursDraft] = useState<string | null>(null);\n\n useEffect(() => {\n const p = cronExpressionToPickerState(value);\n setMode(p.mode);\n setIntervalKind(p.intervalKind);\n setOnceDate(p.onceDate);\n setIntervalMinutes(p.intervalMinutes);\n setIntervalHours(p.intervalHours);\n setMinute(p.minute);\n setHour(p.hour);\n setWeekDays(p.weekDays);\n setDayOfMonth(p.dayOfMonth);\n setRawCron(p.rawCron);\n setIntervalMinutesDraft(null);\n setIntervalHoursDraft(null);\n }, [value]);\n\n const emit = useCallback(\n (patch: Partial<PickerState>) => {\n const next: PickerState = {\n mode,\n intervalKind,\n onceDate,\n intervalMinutes,\n intervalHours,\n minute,\n hour,\n weekDays,\n dayOfMonth,\n rawCron,\n ...patch,\n };\n onChange(buildCronFromPickerState(next));\n },\n [\n mode,\n intervalKind,\n onceDate,\n intervalMinutes,\n intervalHours,\n minute,\n hour,\n weekDays,\n dayOfMonth,\n rawCron,\n onChange,\n ],\n );\n\n const timeValue = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;\n\n const onTimeChange = (e: ChangeEvent<HTMLInputElement>) => {\n const v = e.target.value;\n if (!v) return;\n const [hh, mm] = v.split(':').map((x) => parseInt(x, 10));\n if (Number.isNaN(hh) || Number.isNaN(mm)) return;\n emit({ minute: mm, hour: hh });\n };\n\n const modeRow = (\n <div className=\"flex min-w-0 flex-nowrap items-center gap-2 overflow-x-auto pb-0.5\">\n <select\n className={pickerSelectClass}\n disabled={disabled}\n value={mode}\n onChange={(e) => {\n const next = e.target.value as SchedulePickerMode;\n setMode(next);\n emit({ mode: next });\n }}\n aria-label={labels.scheduleTimeLabel}\n >\n <option value=\"no_repeat\">{labels.modeNoRepeat}</option>\n <option value=\"interval\">{labels.modeInterval}</option>\n <option value=\"hourly\">{labels.modeHourly}</option>\n <option value=\"daily\">{labels.modeDaily}</option>\n <option value=\"weekly\">{labels.modeWeekly}</option>\n <option value=\"monthly\">{labels.modeMonthly}</option>\n <option value=\"custom\">{labels.modeCustom}</option>\n </select>\n\n {mode === 'no_repeat' && (\n <>\n <input\n type=\"date\"\n disabled={disabled}\n className={dateInputClass}\n value={onceDate}\n onChange={(e) => {\n const v = e.target.value;\n setOnceDate(v);\n emit({ onceDate: v });\n }}\n aria-label={labels.modeNoRepeat}\n />\n <input\n type=\"time\"\n step={60}\n disabled={disabled}\n className={timeInputClass}\n value={timeValue}\n onChange={onTimeChange}\n aria-label={labels.scheduleTimeLabel}\n />\n </>\n )}\n\n {mode === 'interval' && (\n <>\n <select\n className={cn(pickerSelectClass, 'w-auto min-w-[5rem]')}\n disabled={disabled}\n value={intervalKind}\n onChange={(e) => {\n const k = e.target.value as IntervalKind;\n setIntervalKind(k);\n setIntervalMinutesDraft(null);\n setIntervalHoursDraft(null);\n emit({ intervalKind: k });\n }}\n aria-label={labels.modeInterval}\n >\n <option value=\"minutes\">{labels.intervalKindMinutes}</option>\n <option value=\"hours\">{labels.intervalKindHours}</option>\n </select>\n {intervalKind === 'minutes' ? (\n <>\n <input\n type=\"number\"\n min={1}\n max={59}\n disabled={disabled}\n className={numberInputClass}\n value={intervalMinutesDraft ?? String(intervalMinutes)}\n onChange={(e) => {\n const next = e.target.value;\n setIntervalMinutesDraft(next);\n const raw = parseInt(next, 10);\n if (Number.isFinite(raw) && raw >= 1 && raw <= 59) {\n setIntervalMinutes(raw);\n emit({ intervalMinutes: raw });\n }\n }}\n onBlur={() => {\n if (intervalMinutesDraft === null) return;\n const raw = parseInt(intervalMinutesDraft, 10);\n const v =\n !Number.isFinite(raw) || raw < 1\n ? 5\n : Math.min(59, Math.max(1, Math.round(raw)));\n setIntervalMinutes(v);\n emit({ intervalMinutes: v });\n setIntervalMinutesDraft(null);\n }}\n aria-label={labels.intervalMinutes}\n />\n <span className=\"shrink-0 text-sm text-fg-muted\">{labels.minuteUnit}</span>\n </>\n ) : (\n <>\n <input\n type=\"number\"\n min={1}\n max={23}\n disabled={disabled}\n className={numberInputClass}\n value={intervalHoursDraft ?? String(intervalHours)}\n onChange={(e) => {\n const next = e.target.value;\n setIntervalHoursDraft(next);\n const raw = parseInt(next, 10);\n if (Number.isFinite(raw) && raw >= 1 && raw <= 23) {\n setIntervalHours(raw);\n emit({ intervalHours: raw });\n }\n }}\n onBlur={() => {\n if (intervalHoursDraft === null) return;\n const raw = parseInt(intervalHoursDraft, 10);\n const v =\n !Number.isFinite(raw) || raw < 1\n ? 2\n : Math.min(23, Math.max(1, Math.round(raw)));\n setIntervalHours(v);\n emit({ intervalHours: v });\n setIntervalHoursDraft(null);\n }}\n aria-label={labels.intervalHours}\n />\n <span className=\"shrink-0 text-sm text-fg-muted\">{labels.hourUnit}</span>\n <select\n className={cn(pickerSelectClass, 'w-auto min-w-[4rem]')}\n disabled={disabled}\n value={minute}\n onChange={(e) => {\n const mm = parseInt(e.target.value, 10);\n setMinute(mm);\n emit({ minute: mm });\n }}\n aria-label={labels.minuteAtHour}\n >\n {Array.from({ length: 60 }, (_, i) => (\n <option key={i} value={i}>\n {String(i).padStart(2, '0')}\n </option>\n ))}\n </select>\n <span className=\"shrink-0 text-sm text-fg-muted\">{labels.minuteUnit}</span>\n </>\n )}\n </>\n )}\n\n {mode === 'daily' && (\n <input\n type=\"time\"\n step={60}\n disabled={disabled}\n className={timeInputClass}\n value={timeValue}\n onChange={onTimeChange}\n aria-label={labels.scheduleTimeLabel}\n />\n )}\n\n {mode === 'weekly' && (\n <input\n type=\"time\"\n step={60}\n disabled={disabled}\n className={timeInputClass}\n value={timeValue}\n onChange={onTimeChange}\n aria-label={labels.scheduleTimeLabel}\n />\n )}\n\n {mode === 'monthly' && (\n <>\n <select\n className={cn(pickerSelectClass, 'w-auto min-w-[4.5rem]')}\n disabled={disabled}\n value={dayOfMonth}\n onChange={(e) => {\n const d = parseInt(e.target.value, 10);\n setDayOfMonth(d);\n emit({ dayOfMonth: d });\n }}\n aria-label={labels.dayOfMonth}\n >\n {Array.from({ length: 31 }, (_, i) => i + 1).map((d) => (\n <option key={d} value={d}>\n {d}\n </option>\n ))}\n </select>\n <input\n type=\"time\"\n step={60}\n disabled={disabled}\n className={timeInputClass}\n value={timeValue}\n onChange={onTimeChange}\n aria-label={labels.scheduleTimeLabel}\n />\n </>\n )}\n\n {mode === 'hourly' && (\n <>\n <select\n className={cn(pickerSelectClass, 'w-auto min-w-[4rem]')}\n disabled={disabled}\n value={minute}\n onChange={(e) => {\n const mm = parseInt(e.target.value, 10);\n setMinute(mm);\n emit({ minute: mm });\n }}\n aria-label={labels.minuteAtHour}\n >\n {Array.from({ length: 60 }, (_, i) => (\n <option key={i} value={i}>\n {String(i).padStart(2, '0')}\n </option>\n ))}\n </select>\n <span className=\"shrink-0 text-sm text-fg-muted\">{labels.minuteUnit}</span>\n </>\n )}\n </div>\n );\n\n const weekRow =\n mode === 'weekly' ? (\n <div className=\"flex flex-wrap gap-1.5 pt-1\" role=\"group\" aria-label={labels.modeWeekly}>\n {labels.weekdays.map((label, i) => {\n const on = weekDays[i];\n return (\n <button\n key={label}\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'flex size-9 select-none items-center justify-center rounded-full border text-xs font-medium transition-colors',\n on\n ? 'border-fg bg-fg text-surface-panel'\n : 'border-edge-subtle bg-surface-panel text-fg hover:border-edge',\n )}\n aria-pressed={on}\n onClick={() => {\n const next = [...weekDays];\n next[i] = !next[i];\n setWeekDays(next);\n emit({ weekDays: next });\n }}\n >\n {label}\n </button>\n );\n })}\n </div>\n ) : null;\n\n const customBlock =\n mode === 'custom' ? (\n <div className=\"pt-1\">\n <textarea\n disabled={disabled}\n className={cronTextareaClass}\n rows={2}\n spellCheck={false}\n value={rawCron}\n placeholder=\"*/5 * * * *\"\n onChange={(e) => {\n const v = e.target.value;\n setRawCron(v);\n onChange(v.trim() || '*/5 * * * *');\n }}\n aria-label={labels.modeCustom}\n />\n <p className=\"mt-1 text-xs text-fg-muted\">{labels.customCronHint}</p>\n </div>\n ) : null;\n\n return (\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium text-fg-muted\">{labels.scheduleTimeLabel}</span>\n {modeRow}\n {weekRow}\n {customBlock}\n </div>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { Eye, FolderInput, RefreshCw, SquarePen, X } from 'lucide-react';\n\nimport { MarkdownEditor } from '@/components/markdown/markdown-editor';\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { Button } from '@/components/ui/button';\nimport type { ChatAgentOption } from '@/features/chat/chat-agents-api';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { folderDisplayName } from '@/features/chat/session-working-directory-control';\nimport { WorkingDirectoryPickerModal } from '@/features/chat/working-directory-picker-modal';\nimport type { ChannelStatus, SessionChatId } from '@/features/cron/cron-api';\nimport { CronSchedulePicker } from '@/features/cron/cron-schedule-form';\nimport { formatRecipientOptionLabel } from '@/features/cron/cron-utils';\nimport {\n cronRecipientSelectClass,\n inputClassName,\n selectClassName,\n} from '@/features/cron/cron-page-lib';\nimport { agentListDisplayName } from '@/features/settings/agents/agent-display-names';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronJobFormDialogProps = {\n open: boolean;\n onRequestClose: () => void;\n c: CronCopy;\n chatM: MessageBundle['chat'];\n agentsMessages: MessageBundle['agentsSettings'];\n isDark: boolean;\n channels: ChannelStatus[];\n sessionChatIds: SessionChatId[];\n cronAgentSelectOptions: ChatAgentOption[];\n hasElectronFolderPicker: boolean;\n openNativeFolderPicker: () => Promise<string | null>;\n applyWorkingDirectory: (path: string) => Promise<void>;\n wdModalOpen: boolean;\n onWdModalOpenChange: (open: boolean) => void;\n defaultModelResolver: () => string;\n formMode: 'add' | 'edit';\n formJobId: string | null;\n formName: string;\n onFormNameChange: (v: string) => void;\n formSchedule: string;\n onFormScheduleChange: (v: string) => void;\n formSubmitting: boolean;\n formSessionTarget: 'main' | 'isolated';\n onFormSessionTargetChange: (\n target: 'main' | 'isolated',\n defaultModelFallback: () => string,\n currentModel: string,\n ) => void;\n formAgentLocalOnly: boolean;\n onFormAgentLocalOnlyChange: (v: boolean) => void;\n formModel: string;\n onFormModelUserChange: (id: string) => void;\n formAgentId: string;\n onFormAgentIdChange: (v: string) => void;\n formWorkingDirectory: string;\n onFormWorkingDirectoryChange: (v: string) => void;\n formChannel: string;\n onFormChannelChange: (channel: string) => void;\n formChatId: string;\n onFormChatIdChange: (v: string) => void;\n formMessage: string;\n onFormMessageChange: (v: string) => void;\n formMessageMdMode: 'edit' | 'preview';\n onSetMessageMdMode: (mode: 'edit' | 'preview') => void;\n messageEditorNonce: number;\n needsDeliveryChat: boolean;\n showChannelPicker: boolean;\n canSubmit: boolean;\n onSubmit: () => void;\n onRefreshRecipients: () => void;\n};\n\nexport function CronJobFormDialog(props: CronJobFormDialogProps) {\n const {\n open,\n onRequestClose,\n c,\n chatM,\n agentsMessages,\n isDark,\n channels,\n sessionChatIds,\n cronAgentSelectOptions,\n hasElectronFolderPicker,\n openNativeFolderPicker,\n applyWorkingDirectory,\n wdModalOpen,\n onWdModalOpenChange,\n defaultModelResolver,\n formMode,\n formJobId,\n formName,\n onFormNameChange,\n formSchedule,\n onFormScheduleChange,\n formSubmitting,\n formSessionTarget,\n onFormSessionTargetChange,\n formAgentLocalOnly,\n onFormAgentLocalOnlyChange,\n formModel,\n onFormModelUserChange,\n formAgentId,\n onFormAgentIdChange,\n formWorkingDirectory,\n onFormWorkingDirectoryChange,\n formChannel,\n onFormChannelChange,\n formChatId,\n onFormChatIdChange,\n formMessage,\n onFormMessageChange,\n formMessageMdMode,\n onSetMessageMdMode,\n messageEditorNonce,\n needsDeliveryChat,\n showChannelPicker,\n canSubmit,\n onSubmit,\n onRefreshRecipients,\n } = props;\n\n return (\n <>\n <Dialog.Root open={open} onOpenChange={(o) => !o && onRequestClose()}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <div className=\"fixed inset-0 z-[60] flex items-center justify-center p-4 pointer-events-none\">\n <Dialog.Content\n className=\"xopc-dialog-content-pane pointer-events-auto relative flex max-h-[min(90vh,800px)] w-full max-w-md flex-col rounded-xl border border-edge bg-surface-panel shadow-popover outline-none sm:max-w-lg lg:max-w-xl dark:border-edge\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"flex shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3\">\n <Dialog.Title className=\"text-base font-semibold text-fg\">\n {formMode === 'edit' ? c.editJob : c.addJob}\n </Dialog.Title>\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"h-9 w-9 shrink-0 p-0\" aria-label={c.close}>\n <X className=\"size-5\" strokeWidth={1.75} />\n </Button>\n </Dialog.Close>\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-3\">\n <div className=\"flex flex-col gap-3\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.name}</span>\n <input\n type=\"text\"\n className={inputClassName()}\n value={formName}\n onChange={(e) => onFormNameChange(e.target.value)}\n placeholder={c.namePlaceholder}\n />\n </label>\n <CronSchedulePicker\n value={formSchedule}\n onChange={onFormScheduleChange}\n disabled={formSubmitting}\n labels={c.schedulePicker}\n />\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.mode}</span>\n <select\n className={selectClassName()}\n value={formSessionTarget}\n onChange={(e) => {\n const v = e.target.value as 'main' | 'isolated';\n onFormSessionTargetChange(v, defaultModelResolver, formModel.trim());\n }}\n >\n <option value=\"main\">{c.modeDirectOption}</option>\n <option value=\"isolated\">{c.modeAgentOption}</option>\n </select>\n <p className=\"text-xs text-fg-muted\">\n {formSessionTarget === 'main' ? c.modeDirect : c.modeAgent}\n </p>\n </label>\n {formSessionTarget === 'isolated' ? (\n <>\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.model}</span>\n <ModelSelector\n value={formModel}\n placeholder={chatM.modelPlaceholder}\n searchPlaceholder={chatM.modelSearchPlaceholder}\n noMatches={chatM.modelNoMatches}\n className=\"w-full max-w-none min-w-0\"\n popoverContentClassName=\"z-[70]\"\n onChange={onFormModelUserChange}\n />\n </div>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.agentProfile}</span>\n <select\n className={selectClassName()}\n value={formAgentId}\n disabled={formSubmitting}\n onChange={(e) => onFormAgentIdChange(e.target.value)}\n >\n <option value=\"\">{c.agentProfileDefault}</option>\n {cronAgentSelectOptions.map((ag) => (\n <option key={ag.id} value={ag.id}>\n {`${ag.id} — ${agentListDisplayName(ag, agentsMessages)}`}\n </option>\n ))}\n </select>\n <p className=\"text-xs text-fg-muted\">{c.agentProfileHint}</p>\n </label>\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.workingDirectoryLabel}</span>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n disabled={formSubmitting}\n className={cn(\n 'inline-flex min-h-8 max-w-[min(16rem,48vw)] min-w-0 shrink-0 items-center gap-1 rounded-lg px-2 py-1 text-xs',\n 'border border-edge-subtle/80 bg-surface-hover/40 dark:border-edge-subtle',\n interaction.transition,\n interaction.focusRingPanel,\n 'cursor-pointer hover:bg-surface-hover/70 dark:hover:bg-surface-hover/50',\n formSubmitting && 'cursor-not-allowed opacity-60',\n )}\n title={\n formWorkingDirectory.trim()\n ? `${formWorkingDirectory.trim()}\\n${chatM.workingDirectory.chooseFolder}`\n : `${c.workingDirectoryHint}\\n${chatM.workingDirectory.selectWorkingDirectory}`\n }\n onClick={(e) => {\n e.stopPropagation();\n if (formSubmitting) return;\n if (hasElectronFolderPicker) {\n void (async () => {\n const picked = await openNativeFolderPicker();\n if (picked) void applyWorkingDirectory(picked);\n })();\n } else {\n onWdModalOpenChange(true);\n }\n }}\n >\n <FolderInput className=\"size-3.5 shrink-0 text-fg-muted\" aria-hidden />\n <span className=\"min-w-0 truncate text-left font-medium text-fg\">\n {formWorkingDirectory.trim()\n ? folderDisplayName(formWorkingDirectory.trim())\n : chatM.workingDirectory.notSet}\n </span>\n </button>\n {formWorkingDirectory.trim() ? (\n <button\n type=\"button\"\n disabled={formSubmitting}\n className=\"text-xs font-medium text-accent hover:underline disabled:opacity-50\"\n onClick={() => onFormWorkingDirectoryChange('')}\n >\n {c.workingDirectoryReset}\n </button>\n ) : null}\n </div>\n <p className=\"text-xs text-fg-muted\">{c.workingDirectoryHint}</p>\n </div>\n <label className=\"flex cursor-pointer items-start gap-2 rounded-md bg-surface-hover/45 px-3 py-2 dark:bg-surface-hover/30\">\n <input\n type=\"checkbox\"\n className={cn('ui-checkbox', 'mt-0.5')}\n checked={formAgentLocalOnly}\n onChange={(e) => onFormAgentLocalOnlyChange(e.target.checked)}\n />\n <span>\n <span className=\"text-sm font-medium text-fg\">{c.agentLocalOnly}</span>\n <p className=\"mt-1 text-xs text-fg-muted\">{c.agentLocalOnlyHint}</p>\n </span>\n </label>\n </>\n ) : null}\n {showChannelPicker ? (\n <>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.channel}</span>\n <select\n className={selectClassName()}\n value={formChannel}\n onChange={(e) => {\n const v = e.target.value;\n onFormChannelChange(v);\n }}\n >\n <option value=\"local\">{c.channelLocal}</option>\n {channels.map((ch) => (\n <option key={ch.name} value={ch.name} disabled={!ch.enabled}>\n {ch.name} {!ch.enabled ? '(disabled)' : ''}\n </option>\n ))}\n </select>\n </label>\n {needsDeliveryChat ? (\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.recipient}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-7 gap-1 px-2 text-xs\"\n title={c.refreshRecipientHint}\n onClick={() => void onRefreshRecipients()}\n >\n <RefreshCw className=\"size-3.5\" strokeWidth={1.75} />\n {c.refreshList}\n </Button>\n </div>\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-stretch sm:gap-2\">\n <input\n type=\"text\"\n className={cn(inputClassName(), 'min-w-0 w-full sm:flex-1')}\n value={formChatId}\n onChange={(e) => onFormChatIdChange(e.target.value)}\n placeholder={c.recipientPlaceholder}\n />\n <select\n className={cronRecipientSelectClass}\n value={formChatId}\n onChange={(e) => {\n const v = e.target.value;\n if (v) onFormChatIdChange(v);\n }}\n >\n <option value=\"\">{c.selectRecipient}</option>\n {sessionChatIds.length > 0 ? (\n sessionChatIds.map((item) => (\n <option key={`${item.channel}-${item.chatId}`} value={item.chatId}>\n {formatRecipientOptionLabel(item, c.lastActiveLabels)}\n </option>\n ))\n ) : (\n <option value=\"\" disabled>\n {c.noRecentChatsOption}\n </option>\n )}\n </select>\n </div>\n <p className=\"text-xs text-fg-muted\">\n {sessionChatIds.length > 0 ? c.enterManuallyOrSelect : c.noRecentChats}\n </p>\n </div>\n ) : null}\n </>\n ) : null}\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.message}</span>\n <div className=\"inline-flex rounded-lg border border-edge bg-surface-base p-0.5 dark:border-edge\">\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium',\n formMessageMdMode === 'edit'\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover',\n )}\n onClick={() => onSetMessageMdMode('edit')}\n >\n <SquarePen className=\"size-3.5 shrink-0\" strokeWidth={1.75} aria-hidden />\n {c.messageEdit}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium',\n formMessageMdMode === 'preview'\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover',\n )}\n onClick={() => onSetMessageMdMode('preview')}\n >\n <Eye className=\"size-3.5 shrink-0\" strokeWidth={1.75} aria-hidden />\n {c.messagePreview}\n </button>\n </div>\n </div>\n <div\n className={cn(\n 'overflow-hidden rounded-md border border-edge bg-surface-base dark:border-edge',\n formSubmitting && 'pointer-events-none opacity-60',\n )}\n >\n {formMessageMdMode === 'edit' ? (\n <MarkdownEditor\n key={`cron-msg-${formJobId ?? 'new'}-${messageEditorNonce}`}\n initialContent={formMessage}\n onChange={onFormMessageChange}\n isDark={isDark}\n className=\"h-[min(18rem,40vh)] min-h-[12rem]\"\n />\n ) : (\n <div className=\"h-[min(18rem,40vh)] min-h-[12rem] max-h-[min(24rem,50vh)] overflow-y-auto px-3 py-2\">\n {formMessage.trim() ? (\n <MarkdownView content={formMessage} compact className=\"text-sm\" />\n ) : (\n <p className=\"text-sm text-fg-muted\">{c.messagePlaceholder}</p>\n )}\n </div>\n )}\n </div>\n <p className=\"text-xs text-fg-muted\">{c.messageMarkdownHint}</p>\n </div>\n </div>\n </div>\n <div className=\"flex shrink-0 justify-end gap-2 border-t border-edge px-4 py-3\">\n <Button type=\"button\" variant=\"secondary\" onClick={onRequestClose}>\n {c.cancel}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={formSubmitting || !canSubmit} onClick={onSubmit}>\n {formSubmitting ? c.loading : formMode === 'edit' ? c.save : c.create}\n </Button>\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n\n {!hasElectronFolderPicker ? (\n <WorkingDirectoryPickerModal\n open={wdModalOpen}\n onOpenChange={onWdModalOpenChange}\n initialAbsolutePath={formWorkingDirectory.trim() || undefined}\n onConfirm={async (p) => {\n await applyWorkingDirectory(p);\n onWdModalOpenChange(false);\n }}\n wd={chatM.workingDirectory}\n />\n ) : null}\n </>\n );\n}\n","import {\n segmentedThumbActiveClassName,\n segmentedThumbBaseClassName,\n segmentedTrackClassName,\n} from '@/components/ui/segmented-styles';\nimport type { CronJob } from '@/features/cron/cron-api';\nimport { cronToolbarSelectClass } from '@/features/cron/cron-page-lib';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronMainToolbarProps = {\n c: CronCopy;\n mainTab: 'myTasks' | 'systemTasks' | 'history';\n onMainTabChange: (tab: 'myTasks' | 'systemTasks' | 'history') => void;\n jobSort: 'created_desc' | 'created_asc';\n onJobSortChange: (sort: 'created_desc' | 'created_asc') => void;\n historyRange: 'day' | 'week' | 'month';\n onHistoryRangeChange: (range: 'day' | 'week' | 'month') => void;\n historyJobFilter: string;\n onHistoryJobFilterChange: (jobId: string) => void;\n historyStatusFilter: string;\n onHistoryStatusFilterChange: (status: string) => void;\n jobs: CronJob[];\n};\n\nexport function CronMainToolbar({\n c,\n mainTab,\n onMainTabChange,\n jobSort,\n onJobSortChange,\n historyRange,\n onHistoryRangeChange,\n historyJobFilter,\n onHistoryJobFilterChange,\n historyStatusFilter,\n onHistoryStatusFilterChange,\n jobs,\n}: CronMainToolbarProps) {\n return (\n <div className=\"flex flex-col gap-3 border-b border-edge-subtle pb-3 sm:flex-row sm:items-center sm:justify-between dark:border-edge-subtle\">\n <div className=\"flex gap-1\" role=\"tablist\" aria-label={c.title}>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mainTab === 'myTasks'}\n className={cn(\n 'rounded-md px-3 py-2 text-sm font-medium transition-colors',\n mainTab === 'myTasks' ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n onClick={() => onMainTabChange('myTasks')}\n >\n {c.tabMyTasks}\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mainTab === 'systemTasks'}\n className={cn(\n 'rounded-md px-3 py-2 text-sm font-medium transition-colors',\n mainTab === 'systemTasks' ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n onClick={() => onMainTabChange('systemTasks')}\n >\n {c.tabSystemTasks}\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mainTab === 'history'}\n className={cn(\n 'rounded-md px-3 py-2 text-sm font-medium transition-colors',\n mainTab === 'history' ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n onClick={() => onMainTabChange('history')}\n >\n {c.tabRunHistory}\n </button>\n </div>\n <div\n className={cn(\n 'flex min-w-0 items-center gap-2',\n mainTab === 'history'\n ? 'flex-nowrap overflow-x-auto pb-0.5 sm:justify-end'\n : 'flex-wrap sm:justify-end',\n )}\n >\n {mainTab === 'myTasks' || mainTab === 'systemTasks' ? (\n <select\n className={cronToolbarSelectClass}\n value={jobSort}\n onChange={(e) => onJobSortChange(e.target.value as 'created_desc' | 'created_asc')}\n aria-label={c.sortCreatedDesc}\n >\n <option value=\"created_desc\">{c.sortCreatedDesc}</option>\n <option value=\"created_asc\">{c.sortCreatedAsc}</option>\n </select>\n ) : null}\n {mainTab === 'history' ? (\n <>\n <div className={cn(segmentedTrackClassName, 'shrink-0')} role=\"group\" aria-label={c.runHistoryTitle}>\n {(['day', 'week', 'month'] as const).map((r) => (\n <button\n key={r}\n type=\"button\"\n className={cn(\n segmentedThumbBaseClassName,\n 'px-2.5 py-1',\n historyRange === r && segmentedThumbActiveClassName,\n historyRange === r && 'text-fg',\n )}\n onClick={() => onHistoryRangeChange(r)}\n >\n {r === 'day' ? c.historyRangeDay : r === 'week' ? c.historyRangeWeek : c.historyRangeMonth}\n </button>\n ))}\n </div>\n <select\n className={cronToolbarSelectClass}\n value={historyJobFilter}\n onChange={(e) => onHistoryJobFilterChange(e.target.value)}\n aria-label={c.filterAllTasks}\n >\n <option value=\"\">{c.filterAllTasks}</option>\n {jobs.map((j) => (\n <option key={j.id} value={j.id}>\n {j.name || j.id}\n </option>\n ))}\n </select>\n <select\n className={cronToolbarSelectClass}\n value={historyStatusFilter}\n onChange={(e) => onHistoryStatusFilterChange(e.target.value)}\n aria-label={c.filterAllStatuses}\n >\n <option value=\"\">{c.filterAllStatuses}</option>\n <option value=\"success\">{c.execStatusSuccess}</option>\n <option value=\"failed\">{c.execStatusFailed}</option>\n <option value=\"cancelled\">{c.execStatusCancelled}</option>\n <option value=\"running\">{c.execStatusRunning}</option>\n </select>\n </>\n ) : null}\n </div>\n </div>\n );\n}\n","import { LayoutTemplate, Plus, RefreshCw } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronPageHeaderActionsProps = {\n c: CronCopy;\n loading: boolean;\n runHistoryLoading: boolean;\n onRefresh: () => void;\n onOpenTemplatePicker: () => void;\n onAddJob: () => void;\n};\n\nexport function CronPageHeaderActions({\n c,\n loading,\n runHistoryLoading,\n onRefresh,\n onOpenTemplatePicker,\n onAddJob,\n}: CronPageHeaderActionsProps) {\n const busy = loading || runHistoryLoading;\n return (\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 w-9 shrink-0 p-0\"\n disabled={busy}\n title={c.refresh}\n aria-label={c.refresh}\n onClick={() => void onRefresh()}\n >\n <RefreshCw className={cn('size-4', busy && 'animate-spin')} strokeWidth={1.75} />\n </Button>\n <Button type=\"button\" variant=\"secondary\" className=\"gap-2\" onClick={onOpenTemplatePicker}>\n <LayoutTemplate className=\"size-4\" strokeWidth={1.75} />\n {c.fromTemplate}\n </Button>\n <Button type=\"button\" variant=\"primary\" className=\"gap-2\" onClick={onAddJob}>\n <Plus className=\"size-4\" strokeWidth={1.75} />\n {c.addJob}\n </Button>\n </div>\n );\n}\n","import { Clock, Loader2, RefreshCw } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport type { CronJob, CronRunHistoryRow } from '@/features/cron/cron-api';\nimport { navigateToSessionChat } from '@/features/cron/cron-page-lib';\nimport {\n execStatusLabel,\n formatDuration,\n formatTime,\n truncate,\n} from '@/features/cron/cron-utils';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronRunHistorySectionProps = {\n c: CronCopy;\n runHistoryLoading: boolean;\n runHistory: CronRunHistoryRow[];\n filteredRunHistory: CronRunHistoryRow[];\n jobs: CronJob[];\n onRefreshHistory: () => void;\n onOpenJobDetail: (job: CronJob) => void;\n statusLabels: {\n running: string;\n success: string;\n failed: string;\n cancelled: string;\n };\n};\n\nexport function CronRunHistorySection({\n c,\n runHistoryLoading,\n runHistory,\n filteredRunHistory,\n jobs,\n onRefreshHistory,\n onOpenJobDetail,\n statusLabels,\n}: CronRunHistorySectionProps) {\n return (\n <section aria-labelledby=\"cron-history-panel\" className=\"flex flex-col gap-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div>\n <h2 id=\"cron-history-panel\" className=\"sr-only\">\n {c.tabRunHistory}\n </h2>\n <p className=\"text-xs text-fg-muted\">{c.runHistoryHint}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 w-9 shrink-0 p-0\"\n disabled={runHistoryLoading}\n title={c.refresh}\n aria-label={c.refresh}\n onClick={() => void onRefreshHistory()}\n >\n <RefreshCw className={cn('size-4', runHistoryLoading && 'animate-spin')} strokeWidth={1.75} />\n </Button>\n </div>\n {runHistoryLoading && runHistory.length === 0 ? (\n <div className=\"flex justify-center py-16\">\n <Loader2 className=\"size-8 animate-spin text-accent\" strokeWidth={1.75} />\n </div>\n ) : filteredRunHistory.length === 0 ? (\n <div className=\"flex flex-col items-center rounded-2xl border border-dashed border-edge-subtle px-6 py-16 text-center dark:border-edge-subtle\">\n <Clock className=\"mb-4 size-14 text-fg-disabled\" strokeWidth={1.1} aria-hidden />\n <h3 className=\"text-base font-semibold text-fg\">\n {runHistory.length === 0 ? c.emptyHistoryTitle : c.noRunsYet}\n </h3>\n <p className=\"mt-2 max-w-sm text-sm text-fg-muted\">\n {runHistory.length === 0 ? c.emptyHistoryHint : c.runHistoryHint}\n </p>\n </div>\n ) : (\n <div className=\"overflow-x-auto rounded-xl border border-edge-subtle bg-surface-base dark:border-edge-subtle\">\n <table className=\"w-full min-w-[700px] border-collapse text-left text-sm\">\n <thead>\n <tr className=\"border-b border-edge text-xs font-medium text-fg-muted\">\n <th className=\"px-3 py-2.5 font-medium\">{c.colStarted}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.colJob}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.status}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.colDuration}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.colDetail}</th>\n <th className=\"px-3 py-2.5 font-medium\">{c.colChat}</th>\n </tr>\n </thead>\n <tbody>\n {filteredRunHistory.map((row) => (\n <tr key={row.id} className=\"border-b border-edge/60 last:border-0\">\n <td className=\"whitespace-nowrap px-3 py-2.5 text-fg\">\n <time dateTime={row.startedAt}>{formatTime(row.startedAt)}</time>\n </td>\n <td className=\"max-w-[10rem] truncate px-3 py-2.5\">\n {jobs.some((j) => j.id === row.jobId) ? (\n <button\n type=\"button\"\n className=\"text-left text-accent hover:underline\"\n onClick={() => {\n const j = jobs.find((x) => x.id === row.jobId);\n if (j) void onOpenJobDetail(j);\n }}\n >\n {row.jobName || row.jobId}\n </button>\n ) : (\n <span className=\"text-fg-muted\">{row.jobName || row.jobId}</span>\n )}\n </td>\n <td className=\"px-3 py-2.5\">\n <span\n className={cn(\n 'inline-flex rounded-md px-2 py-0.5 text-xs font-medium',\n row.status === 'success' && 'bg-emerald-500/15 text-emerald-800 dark:text-emerald-300',\n row.status === 'failed' && 'bg-red-500/15 text-red-800 dark:text-red-300',\n row.status === 'running' && 'bg-accent/15 text-accent',\n row.status === 'cancelled' && 'bg-surface-hover text-fg-muted',\n )}\n >\n {execStatusLabel(row.status, statusLabels)}\n </span>\n </td>\n <td className=\"whitespace-nowrap px-3 py-2.5 text-fg-muted\">\n {formatDuration(row.duration)}\n </td>\n <td\n className=\"max-w-xs truncate px-3 py-2.5 text-fg-muted\"\n title={row.summary || row.error || ''}\n >\n {truncate(row.summary || row.error, 96)}\n </td>\n <td className=\"whitespace-nowrap px-3 py-2.5\">\n {row.sessionKey?.trim() ? (\n <button\n type=\"button\"\n className=\"text-xs font-medium text-accent hover:underline\"\n title={c.openChatTitle}\n aria-label={c.openChatTitle}\n onClick={() => navigateToSessionChat(row.sessionKey)}\n >\n {c.openChat}\n </button>\n ) : (\n <span className=\"text-fg-disabled\">—</span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n );\n}\n","import * as DropdownMenu from '@radix-ui/react-dropdown-menu';\nimport { Clock, MoreVertical } from 'lucide-react';\n\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { Button } from '@/components/ui/button';\nimport type { MutableRefObject } from 'react';\n\nimport type { CronJob } from '@/features/cron/cron-api';\nimport { cronJobBodyText } from '@/features/cron/cron-api';\nimport { formatScheduleBadge } from '@/features/cron/cron-utils';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronJobCardProps = {\n job: CronJob;\n c: CronCopy;\n localeTag: string;\n scheduleBadgeLabels: CronCopy['scheduleBadge'];\n absorbCardClickJobIdRef: MutableRefObject<string | null>;\n scheduleAbsorbNextMenuCardClick: (jobId: string) => void;\n onOpenDetail: (job: CronJob) => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onEdit: (job: CronJob) => void;\n onRunNow: (job: CronJob) => void;\n onDelete: (job: CronJob) => void;\n};\n\nexport function CronJobCard({\n job,\n c,\n localeTag,\n scheduleBadgeLabels,\n absorbCardClickJobIdRef,\n scheduleAbsorbNextMenuCardClick,\n onOpenDetail,\n onToggle,\n onEdit,\n onRunNow,\n onDelete,\n}: CronJobCardProps) {\n return (\n <article\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'flex cursor-pointer flex-col rounded-xl border border-edge-subtle bg-surface-base text-left transition-colors duration-150 ease-out dark:border-edge-subtle',\n 'hover:bg-surface-hover',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel',\n )}\n onClick={() => {\n if (absorbCardClickJobIdRef.current === job.id) {\n absorbCardClickJobIdRef.current = null;\n return;\n }\n void onOpenDetail(job);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (absorbCardClickJobIdRef.current === job.id) {\n absorbCardClickJobIdRef.current = null;\n return;\n }\n void onOpenDetail(job);\n }\n }}\n >\n <div className=\"flex items-start justify-between gap-2 px-4 pt-3\">\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={job.enabled}\n className={cn(\n 'inline-flex h-6 w-10 shrink-0 items-center rounded-full border border-edge p-0.5 transition-colors',\n job.enabled ? 'justify-end bg-accent' : 'justify-start bg-surface-hover',\n )}\n onClick={(e) => {\n e.stopPropagation();\n void onToggle(job, !job.enabled);\n }}\n >\n <span className=\"size-4 rounded-full bg-surface-panel shadow-surface ring-1 ring-edge/40 dark:ring-edge/55\" />\n </button>\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-8 w-8 shrink-0 p-0\"\n aria-label={c.jobCardMenuAria}\n onClick={(e) => e.stopPropagation()}\n >\n <MoreVertical className=\"size-4\" strokeWidth={1.75} />\n </Button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className=\"z-50 min-w-[10rem] rounded-xl border border-edge-subtle bg-surface-panel p-1 shadow-elevated dark:border-edge-subtle\"\n sideOffset={4}\n align=\"end\"\n onCloseAutoFocus={(e) => e.preventDefault()}\n >\n <DropdownMenu.Item\n className=\"cursor-pointer select-none rounded-lg px-2 py-1.5 text-sm text-fg outline-none data-highlighted:bg-surface-hover\"\n onSelect={() => {\n scheduleAbsorbNextMenuCardClick(job.id);\n onEdit(job);\n }}\n >\n {c.edit}\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className=\"cursor-pointer select-none rounded-lg px-2 py-1.5 text-sm text-fg outline-none data-highlighted:bg-surface-hover\"\n onSelect={() => {\n scheduleAbsorbNextMenuCardClick(job.id);\n onRunNow(job);\n }}\n >\n {c.runNow}\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className=\"cursor-pointer select-none rounded-lg px-2 py-1.5 text-sm text-red-600 outline-none data-highlighted:bg-red-500/10 dark:text-red-400\"\n onSelect={() => {\n scheduleAbsorbNextMenuCardClick(job.id);\n onDelete(job);\n }}\n >\n {c.delete}\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n </div>\n <div className=\"flex flex-1 flex-col gap-2 px-4 pb-3 pt-2\">\n <h3 className=\"line-clamp-2 font-semibold text-fg\">{job.name || job.id}</h3>\n <div\n className=\"max-h-[4.5rem] overflow-hidden text-sm text-fg-muted [&_.markdown-body]:text-sm [&_.markdown-body]:leading-snug\"\n title={cronJobBodyText(job)}\n >\n <MarkdownView content={cronJobBodyText(job)} compact />\n </div>\n </div>\n <div className=\"flex items-center gap-1.5 border-t border-edge-subtle/90 px-4 py-2.5 text-xs text-fg-muted dark:border-edge-subtle\">\n <Clock className=\"size-3.5 shrink-0\" strokeWidth={1.75} aria-hidden />\n <span className=\"min-w-0 truncate\">{formatScheduleBadge(job, localeTag, scheduleBadgeLabels)}</span>\n </div>\n </article>\n );\n}\n","import { ChevronRight, Info, Loader2 } from 'lucide-react';\nimport type { MutableRefObject } from 'react';\nimport { Link } from 'react-router-dom';\n\nimport { Button } from '@/components/ui/button';\nimport type { CronJob } from '@/features/cron/cron-api';\nimport { CronJobCard } from '@/features/cron/cron-job-card';\nimport type { HeartbeatSettingsState } from '@/features/settings/heartbeat-settings.types';\nimport type { MessageBundle } from '@/i18n/messages';\nimport type { StoredLanguage } from '@/lib/storage';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\n/** Localized duration phrase for interpolation into `c.systemHeartbeatEvery`. */\nfunction heartbeatIntervalValuePhrase(ms: number, lang: StoredLanguage): string {\n const sec = Math.max(1, Math.round(ms / 1000));\n if (sec < 120) return lang === 'zh' ? `${sec} 秒` : `${sec} seconds`;\n const min = Math.round(sec / 60);\n if (min < 120) return lang === 'zh' ? `${min} 分钟` : `${min} minutes`;\n const hr = Math.round(min / 60);\n return lang === 'zh' ? `${hr} 小时` : `${hr} hours`;\n}\n\nexport type CronSystemTasksPanelProps = {\n c: CronCopy;\n language: StoredLanguage;\n localeTag: string;\n scheduleBadgeLabels: CronCopy['scheduleBadge'];\n loading: boolean;\n sortedSystemJobs: CronJob[];\n heartbeat: HeartbeatSettingsState;\n keepAwake: boolean;\n wakeSupported: boolean;\n onWakeUnsupportedClick: () => void;\n onKeepAwakeToggle: () => void;\n absorbCardClickJobIdRef: MutableRefObject<string | null>;\n scheduleAbsorbNextMenuCardClick: (jobId: string) => void;\n onOpenDetail: (job: CronJob) => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onEdit: (job: CronJob) => void;\n onRunNow: (job: CronJob) => void;\n onDelete: (job: CronJob) => void;\n};\n\nexport function CronSystemTasksPanel({\n c,\n language,\n localeTag,\n scheduleBadgeLabels,\n loading,\n sortedSystemJobs,\n heartbeat,\n keepAwake,\n wakeSupported,\n onWakeUnsupportedClick,\n onKeepAwakeToggle,\n absorbCardClickJobIdRef,\n scheduleAbsorbNextMenuCardClick,\n onOpenDetail,\n onToggle,\n onEdit,\n onRunNow,\n onDelete,\n}: CronSystemTasksPanelProps) {\n const hbInterval = heartbeatIntervalValuePhrase(heartbeat.intervalMs, language);\n\n return (\n <section aria-labelledby=\"cron-system-tasks-panel\" className=\"flex flex-col gap-4\">\n <h2 id=\"cron-system-tasks-panel\" className=\"sr-only\">\n {c.tabSystemTasks}\n </h2>\n <p className=\"text-sm text-fg-muted\">{c.systemTasksIntro}</p>\n\n <div className=\"flex flex-col gap-3 rounded-xl border border-accent/25 bg-accent/5 px-4 py-3 dark:border-accent/30 dark:bg-accent/10 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex gap-3 text-sm text-fg\">\n <Info className=\"mt-0.5 size-4 shrink-0 text-accent\" strokeWidth={1.75} aria-hidden />\n <p className=\"text-pretty text-fg-muted\">{c.wakeBanner}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2 sm:pl-4\">\n <span className=\"text-sm text-fg\">{c.keepAwake}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={keepAwake}\n disabled={!wakeSupported}\n title={!wakeSupported ? c.wakeLockUnavailable : undefined}\n className={cn(\n 'inline-flex h-6 w-10 shrink-0 items-center rounded-full border border-edge p-0.5 transition-colors',\n keepAwake ? 'justify-end bg-accent' : 'justify-start bg-surface-hover',\n !wakeSupported && 'cursor-not-allowed opacity-50',\n )}\n onClick={() => {\n if (!wakeSupported) onWakeUnsupportedClick();\n else onKeepAwakeToggle();\n }}\n >\n <span className=\"size-4 rounded-full bg-surface-panel shadow-surface ring-1 ring-edge/40 dark:ring-edge/55\" />\n </button>\n </div>\n </div>\n\n <div className=\"rounded-xl border border-edge bg-surface-base p-4 dark:bg-surface-hover/20\">\n <div className=\"flex flex-col gap-1 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h3 className=\"text-sm font-semibold text-fg\">{c.systemHeartbeatTitle}</h3>\n <p className=\"mt-1 text-xs text-fg-muted\">{c.systemHeartbeatHint}</p>\n </div>\n <Button type=\"button\" variant=\"ghost\" className=\"shrink-0 gap-1 self-start px-2 py-1.5 text-xs\" asChild>\n <Link to=\"/settings/heartbeat\">\n {c.systemHeartbeatSettingsLink}\n <ChevronRight className=\"size-3.5 opacity-70\" aria-hidden />\n </Link>\n </Button>\n </div>\n <dl className=\"mt-3 grid gap-2 text-sm sm:grid-cols-2\">\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.systemHeartbeatStatus}</dt>\n <dd className=\"text-fg\">{heartbeat.enabled ? c.enabled : c.disabled}</dd>\n </div>\n <div>\n <dt className=\"text-xs font-medium text-fg-muted\">{c.systemHeartbeatInterval}</dt>\n <dd className=\"text-fg\">{c.systemHeartbeatEvery.replace(/\\{\\{value\\}\\}/g, hbInterval)}</dd>\n </div>\n </dl>\n </div>\n\n <div>\n <div className=\"mb-2 flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between\">\n <h3 className=\"text-sm font-semibold text-fg\">{c.systemDreamingTitle}</h3>\n <Button type=\"button\" variant=\"ghost\" className=\"shrink-0 gap-1 self-start px-2 py-1.5 text-xs\" asChild>\n <Link to=\"/settings/dreams\">\n {c.systemDreamingSettingsLink}\n <ChevronRight className=\"size-3.5 opacity-70\" aria-hidden />\n </Link>\n </Button>\n </div>\n <p className=\"mb-3 text-xs text-fg-muted\">{c.systemDreamingHint}</p>\n {loading && sortedSystemJobs.length === 0 ? (\n <div className=\"flex justify-center py-12\" aria-busy=\"true\">\n <Loader2 className=\"size-8 animate-spin text-accent\" strokeWidth={1.75} />\n </div>\n ) : sortedSystemJobs.length === 0 ? (\n <p className=\"rounded-lg border border-edge-subtle bg-surface-hover/30 px-3 py-4 text-sm text-fg-muted dark:border-edge-subtle\">\n {c.systemDreamingEmpty}\n </p>\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {sortedSystemJobs.map((job) => (\n <CronJobCard\n key={job.id}\n job={job}\n c={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n absorbCardClickJobIdRef={absorbCardClickJobIdRef}\n scheduleAbsorbNextMenuCardClick={scheduleAbsorbNextMenuCardClick}\n onOpenDetail={onOpenDetail}\n onToggle={onToggle}\n onEdit={onEdit}\n onRunNow={onRunNow}\n onDelete={onDelete}\n />\n ))}\n </div>\n )}\n </div>\n </section>\n );\n}\n","import type { MessageBundle } from '@/i18n/messages';\n\nexport type CronTemplateCopy = {\n title: string;\n description: string;\n prompt: string;\n};\n\nexport function getCronTemplateCopy(\n cron: MessageBundle['cron'],\n templateId: string,\n): CronTemplateCopy | undefined {\n const raw = cron.templates;\n if (!raw || typeof raw !== 'object') return undefined;\n const row = (raw as Record<string, { title?: string; description?: string; prompt?: string } | undefined>)[\n templateId\n ];\n if (!row || typeof row !== 'object') return undefined;\n const title = row.title?.trim();\n const prompt = row.prompt?.trim();\n if (!title || !prompt) return undefined;\n return {\n title,\n description: (row.description ?? '').trim(),\n prompt,\n };\n}\n","/** Non-display fields for scheduled-task templates; copy lives in i18n `cron.templates`. */\n\nexport const CRON_TEMPLATE_CATEGORIES = ['daily', 'monitoring', 'reports', 'automation'] as const;\nexport type CronTemplateCategory = (typeof CRON_TEMPLATE_CATEGORIES)[number];\n\nexport interface CronJobTemplateDef {\n templateId: string;\n category: CronTemplateCategory;\n defaultSchedule: string;\n defaultSessionTarget: 'isolated';\n}\n\n/** Grouped like common scheduled-task UIs: daily rhythm, external monitoring, periodic reports, repo automation. */\nexport const CRON_JOB_TEMPLATES = [\n // Daily\n {\n templateId: 'morning_briefing',\n category: 'daily',\n defaultSchedule: '0 7 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'standup_prep',\n category: 'daily',\n defaultSchedule: '0 8 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'end_of_day_wrap_up',\n category: 'daily',\n defaultSchedule: '0 18 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'inbox_triage',\n category: 'daily',\n defaultSchedule: '30 8 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n // Monitoring\n {\n templateId: 'competitor_watch',\n category: 'monitoring',\n defaultSchedule: '0 9 * * 1',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'trending_topics_monitor',\n category: 'monitoring',\n defaultSchedule: '0 10 * * 1-5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'tech_radar_stack',\n category: 'monitoring',\n defaultSchedule: '0 11 * * 3',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'dependency_check_audit',\n category: 'monitoring',\n defaultSchedule: '0 9 * * 0',\n defaultSessionTarget: 'isolated',\n },\n // Reports\n {\n templateId: 'weekly_review',\n category: 'reports',\n defaultSchedule: '0 17 * * 5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'code_quality_report',\n category: 'reports',\n defaultSchedule: '0 14 * * 1',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'git_activity_summary',\n category: 'reports',\n defaultSchedule: '0 9 * * 1',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'user_feedback_digest',\n category: 'reports',\n defaultSchedule: '0 16 * * 5',\n defaultSessionTarget: 'isolated',\n },\n // Automation\n {\n templateId: 'stale_todo_or_issue_sweep',\n category: 'automation',\n defaultSchedule: '0 10 * * 2',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'release_notes_or_changelog_draft',\n category: 'automation',\n defaultSchedule: '0 10 * * 4',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'workspace_cleanup_suggestions',\n category: 'automation',\n defaultSchedule: '30 18 * * 5',\n defaultSessionTarget: 'isolated',\n },\n {\n templateId: 'smoke_or_ci_health_reminder',\n category: 'automation',\n defaultSchedule: '0 8 * * 1',\n defaultSessionTarget: 'isolated',\n },\n] as const satisfies readonly CronJobTemplateDef[];\n\nexport type CronTemplateId = (typeof CRON_JOB_TEMPLATES)[number]['templateId'];\n\nexport function cronTemplateById(id: string): (typeof CRON_JOB_TEMPLATES)[number] | undefined {\n return CRON_JOB_TEMPLATES.find((t) => t.templateId === id);\n}\n","import { Button } from '@/components/ui/button';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\nimport { getCronTemplateCopy } from '@/features/cron/cron-template-i18n';\nimport { CRON_JOB_TEMPLATES, CRON_TEMPLATE_CATEGORIES, type CronTemplateCategory } from '@/features/cron/cron-templates';\nimport { formatScheduleBadge, type ScheduleBadgeLabels } from '@/features/cron/cron-utils';\n\nexport type CronTemplateFilter = 'all' | CronTemplateCategory;\n\ntype Props = {\n cron: MessageBundle['cron'];\n localeTag: string;\n scheduleBadgeLabels: ScheduleBadgeLabels;\n categoryFilter: CronTemplateFilter;\n onCategoryFilterChange: (next: CronTemplateFilter) => void;\n onSelectTemplate: (templateId: string) => void;\n};\n\nexport function CronTemplateLibrary(props: Props) {\n const { cron, localeTag, scheduleBadgeLabels, categoryFilter, onCategoryFilterChange, onSelectTemplate } = props;\n\n const filtered =\n categoryFilter === 'all'\n ? [...CRON_JOB_TEMPLATES]\n : CRON_JOB_TEMPLATES.filter((t) => t.category === categoryFilter);\n\n return (\n <div className=\"flex w-full flex-col gap-4\">\n <div className=\"flex flex-wrap gap-2\" role=\"group\" aria-label={cron.fromTemplate}>\n <Button\n type=\"button\"\n variant={categoryFilter === 'all' ? 'secondary' : 'ghost'}\n className=\"h-8 rounded-full px-3 py-1.5 text-xs\"\n onClick={() => onCategoryFilterChange('all')}\n >\n {cron.templateFilterAll}\n </Button>\n {CRON_TEMPLATE_CATEGORIES.map((cat) => (\n <Button\n key={cat}\n type=\"button\"\n variant={categoryFilter === cat ? 'secondary' : 'ghost'}\n className=\"h-8 rounded-full px-3 py-1.5 text-xs\"\n onClick={() => onCategoryFilterChange(cat)}\n >\n {cron.templateCategories[cat]}\n </Button>\n ))}\n </div>\n {filtered.length === 0 ? (\n <p className=\"text-center text-sm text-fg-muted\">{cron.templatesEmptyHint}</p>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {filtered.map((t) => {\n const copy = getCronTemplateCopy(cron, t.templateId);\n if (!copy) return null;\n const badge = formatScheduleBadge(\n { schedule: t.defaultSchedule, timezone: undefined, next_run: undefined },\n localeTag,\n scheduleBadgeLabels,\n );\n return (\n <button\n key={t.templateId}\n type=\"button\"\n className={cn(\n 'flex flex-col gap-1.5 rounded-xl border border-edge-subtle bg-surface-base p-4 text-left transition-colors',\n 'hover:border-accent/40 hover:bg-surface-hover',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel',\n )}\n onClick={() => onSelectTemplate(t.templateId)}\n aria-label={`${cron.templateCategories[t.category]} — ${copy.title}`}\n >\n <span className=\"font-semibold text-fg\">{copy.title}</span>\n <span className=\"line-clamp-2 text-sm text-fg-muted\">{copy.description}</span>\n <span className=\"mt-1 flex items-center gap-1 text-xs text-fg-muted\">\n <span className=\"tabular-nums\">{badge}</span>\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","import { Info, Loader2 } from 'lucide-react';\nimport type { MutableRefObject } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport type { CronJob } from '@/features/cron/cron-api';\nimport { CronJobCard } from '@/features/cron/cron-job-card';\nimport type { CronTemplateFilter } from '@/features/cron/cron-template-library';\nimport { CronTemplateLibrary } from '@/features/cron/cron-template-library';\nimport type { MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronTasksPanelProps = {\n c: CronCopy;\n localeTag: string;\n scheduleBadgeLabels: CronCopy['scheduleBadge'];\n loading: boolean;\n jobsCount: number;\n sortedJobs: CronJob[];\n templateCategoryFilter: CronTemplateFilter;\n onTemplateCategoryFilterChange: (v: CronTemplateFilter) => void;\n onSelectTemplate: (templateId: string) => void;\n keepAwake: boolean;\n wakeSupported: boolean;\n onWakeUnsupportedClick: () => void;\n onKeepAwakeToggle: () => void;\n absorbCardClickJobIdRef: MutableRefObject<string | null>;\n scheduleAbsorbNextMenuCardClick: (jobId: string) => void;\n onOpenDetail: (job: CronJob) => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onEdit: (job: CronJob) => void;\n onAddJob: () => void;\n onRunNow: (job: CronJob) => void;\n onDelete: (job: CronJob) => void;\n};\n\nexport function CronTasksPanel({\n c,\n localeTag,\n scheduleBadgeLabels,\n loading,\n jobsCount,\n sortedJobs,\n templateCategoryFilter,\n onTemplateCategoryFilterChange,\n onSelectTemplate,\n keepAwake,\n wakeSupported,\n onWakeUnsupportedClick,\n onKeepAwakeToggle,\n absorbCardClickJobIdRef,\n scheduleAbsorbNextMenuCardClick,\n onOpenDetail,\n onToggle,\n onEdit,\n onAddJob,\n onRunNow,\n onDelete,\n}: CronTasksPanelProps) {\n return (\n <section aria-labelledby=\"cron-tasks-panel\" className=\"flex flex-col gap-4\">\n <h2 id=\"cron-tasks-panel\" className=\"sr-only\">\n {c.tabMyTasks}\n </h2>\n <div className=\"flex flex-col gap-3 rounded-xl border border-accent/25 bg-accent/5 px-4 py-3 dark:border-accent/30 dark:bg-accent/10 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex gap-3 text-sm text-fg\">\n <Info className=\"mt-0.5 size-4 shrink-0 text-accent\" strokeWidth={1.75} aria-hidden />\n <p className=\"text-pretty text-fg-muted\">{c.wakeBanner}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2 sm:pl-4\">\n <span className=\"text-sm text-fg\">{c.keepAwake}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={keepAwake}\n disabled={!wakeSupported}\n title={!wakeSupported ? c.wakeLockUnavailable : undefined}\n className={cn(\n 'inline-flex h-6 w-10 shrink-0 items-center rounded-full border border-edge p-0.5 transition-colors',\n keepAwake ? 'justify-end bg-accent' : 'justify-start bg-surface-hover',\n !wakeSupported && 'cursor-not-allowed opacity-50',\n )}\n onClick={() => {\n if (!wakeSupported) onWakeUnsupportedClick();\n else onKeepAwakeToggle();\n }}\n >\n <span className=\"size-4 rounded-full bg-surface-panel shadow-surface ring-1 ring-edge/40 dark:ring-edge/55\" />\n </button>\n </div>\n </div>\n\n {loading && jobsCount === 0 ? (\n <div className=\"flex justify-center py-16\" aria-busy=\"true\">\n <Loader2 className=\"size-8 animate-spin text-accent\" strokeWidth={1.75} />\n </div>\n ) : jobsCount === 0 ? (\n <div className=\"flex flex-col gap-6 rounded-2xl bg-surface-base px-4 py-8 dark:bg-surface-hover/25 sm:px-6 sm:py-10\">\n <div className=\"w-full max-w-3xl\">\n <CronTemplateLibrary\n cron={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n categoryFilter={templateCategoryFilter}\n onCategoryFilterChange={onTemplateCategoryFilterChange}\n onSelectTemplate={onSelectTemplate}\n />\n </div>\n <div className=\"flex justify-center\">\n <Button type=\"button\" variant=\"primary\" onClick={onAddJob}>\n {c.emptyStateCta}\n </Button>\n </div>\n </div>\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {sortedJobs.map((job) => (\n <CronJobCard\n key={job.id}\n job={job}\n c={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n absorbCardClickJobIdRef={absorbCardClickJobIdRef}\n scheduleAbsorbNextMenuCardClick={scheduleAbsorbNextMenuCardClick}\n onOpenDetail={(j) => void onOpenDetail(j)}\n onToggle={(j, en) => void onToggle(j, en)}\n onEdit={onEdit}\n onRunNow={onRunNow}\n onDelete={onDelete}\n />\n ))}\n </div>\n )}\n </section>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport type { CronTemplateFilter } from '@/features/cron/cron-template-library';\nimport { CronTemplateLibrary } from '@/features/cron/cron-template-library';\nimport type { MessageBundle } from '@/i18n/messages';\n\ntype CronCopy = MessageBundle['cron'];\n\nexport type CronTemplatePickerDialogProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n c: CronCopy;\n localeTag: string;\n scheduleBadgeLabels: CronCopy['scheduleBadge'];\n categoryFilter: CronTemplateFilter;\n onCategoryFilterChange: (v: CronTemplateFilter) => void;\n onSelectTemplate: (templateId: string) => void;\n};\n\nexport function CronTemplatePickerDialog({\n open,\n onOpenChange,\n c,\n localeTag,\n scheduleBadgeLabels,\n categoryFilter,\n onCategoryFilterChange,\n onSelectTemplate,\n}: CronTemplatePickerDialogProps) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[62] bg-scrim\" />\n <div className=\"fixed inset-0 z-[62] flex items-center justify-center p-4 pointer-events-none\">\n <Dialog.Content\n className=\"xopc-dialog-content-pane pointer-events-auto relative flex max-h-[min(90vh,840px)] w-full max-w-lg flex-col rounded-xl border border-edge bg-surface-panel shadow-popover outline-none sm:max-w-2xl dark:border-edge\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"flex shrink-0 items-center justify-end border-b border-edge px-4 py-3\">\n <Dialog.Title className=\"sr-only\">{c.fromTemplate}</Dialog.Title>\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"h-9 w-9 shrink-0 p-0\" aria-label={c.close}>\n <X className=\"size-5\" strokeWidth={1.75} />\n </Button>\n </Dialog.Close>\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-4\">\n <CronTemplateLibrary\n cron={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n categoryFilter={categoryFilter}\n onCategoryFilterChange={onCategoryFilterChange}\n onSelectTemplate={onSelectTemplate}\n />\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { fetchChatAgents, type ChatAgentOption } from '@/features/chat/chat-agents-api';\nimport type { CronDelivery, CronJob, CronJobExecution, CronPayload, CronRunHistoryRow } from '@/features/cron/cron-api';\nimport {\n addJob,\n cronJobBodyText,\n getAllRunsHistory,\n getChannels,\n getConfig,\n getHistory,\n getJob,\n getModels,\n getSessionChatIds,\n listJobs,\n removeJob,\n runJob,\n toggleJob,\n updateJob,\n type ChannelStatus,\n type SessionChatId,\n} from '@/features/cron/cron-api';\nimport { CronConfirmActionDialog } from '@/features/cron/cron-confirm-action-dialog';\nimport { CronJobDetailDrawer } from '@/features/cron/cron-job-detail-drawer';\nimport { CronJobFormDialog } from '@/features/cron/cron-job-form-dialog';\nimport { CronMainToolbar } from '@/features/cron/cron-main-toolbar';\nimport {\n DEFAULT_SCHEDULE,\n RUN_HISTORY_FETCH_LIMIT,\n pushRecentWorkspaceDirForCron,\n startOfLocalDay,\n startOfLocalMonth,\n startOfLocalWeekMonday,\n} from '@/features/cron/cron-page-lib';\nimport { CronPageHeaderActions } from '@/features/cron/cron-page-header-actions';\nimport { isDreamingManagedCronJob } from '@/features/cron/cron-dreaming-jobs';\nimport { CronRunHistorySection } from '@/features/cron/cron-run-history-section';\nimport { CronSystemTasksPanel } from '@/features/cron/cron-system-tasks-panel';\nimport { CronTasksPanel } from '@/features/cron/cron-tasks-panel';\nimport { getCronTemplateCopy } from '@/features/cron/cron-template-i18n';\nimport type { CronTemplateFilter } from '@/features/cron/cron-template-library';\nimport { CronTemplatePickerDialog } from '@/features/cron/cron-template-picker-dialog';\nimport { cronTemplateById } from '@/features/cron/cron-templates';\nimport { fetchGatewayConfigSwrResponse } from '@/features/gateway/gateway-config-swr';\nimport { normalizeHeartbeatFromConfig } from '@/features/settings/heartbeat-config-api';\nimport { messages } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { usePageHeaderStore } from '@/stores/page-header-store';\nimport { useThemeStore } from '@/stores/theme-store';\nimport { isElectronCronDisplayWakeAvailable } from '@/lib/electron-env';\n\nexport function CronPage() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const c = m.cron;\n const chatM = m.chat;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n const resolvedTheme = useThemeStore((s) => s.resolved);\n const isDark = resolvedTheme === 'dark';\n const localeTag = language === 'zh' ? 'zh-CN' : 'en-US';\n\n const [jobs, setJobs] = useState<CronJob[]>([]);\n const [mainTab, setMainTab] = useState<'myTasks' | 'systemTasks' | 'history'>('myTasks');\n const [jobSort, setJobSort] = useState<'created_desc' | 'created_asc'>('created_desc');\n const [historyRange, setHistoryRange] = useState<'day' | 'week' | 'month'>('day');\n const [historyJobFilter, setHistoryJobFilter] = useState('');\n const [historyStatusFilter, setHistoryStatusFilter] = useState('');\n const [keepAwake, setKeepAwake] = useState(false);\n const wakeLockRef = useRef<WakeLockSentinel | null>(null);\n const wakeModeRef = useRef<'none' | 'electron' | 'navigator'>('none');\n const keepAwakeRef = useRef(keepAwake);\n const wakeSupported = typeof navigator !== 'undefined' && 'wakeLock' in navigator;\n const keepAwakeFeatureAvailable = wakeSupported || isElectronCronDisplayWakeAvailable();\n\n const [channels, setChannels] = useState<ChannelStatus[]>([]);\n const [availableModels, setAvailableModels] = useState<{ id: string; name: string; provider: string }[]>([]);\n const [defaultModel, setDefaultModel] = useState('');\n const [sessionChatIds, setSessionChatIds] = useState<SessionChatId[]>([]);\n const [chatAgents, setChatAgents] = useState<ChatAgentOption[]>([]);\n const [loading, setLoading] = useState(false);\n const [gatewayConfigRaw, setGatewayConfigRaw] = useState<unknown>(null);\n const [error, setError] = useState<string | null>(null);\n const [runHistory, setRunHistory] = useState<CronRunHistoryRow[]>([]);\n const [runHistoryLoading, setRunHistoryLoading] = useState(false);\n\n const [formOpen, setFormOpen] = useState(false);\n const [formMode, setFormMode] = useState<'add' | 'edit'>('add');\n const [formJobId, setFormJobId] = useState<string | null>(null);\n const [formName, setFormName] = useState('');\n const [formSchedule, setFormSchedule] = useState(DEFAULT_SCHEDULE);\n const [formChannel, setFormChannel] = useState('local');\n const [formChatId, setFormChatId] = useState('');\n const [formMessage, setFormMessage] = useState('');\n const [formMessageMdMode, setFormMessageMdMode] = useState<'edit' | 'preview'>('edit');\n const [messageEditorNonce, setMessageEditorNonce] = useState(0);\n const [formSessionTarget, setFormSessionTarget] = useState<'main' | 'isolated'>('main');\n const [formAgentId, setFormAgentId] = useState('');\n const [formAgentLocalOnly, setFormAgentLocalOnly] = useState(false);\n const [formWorkingDirectory, setFormWorkingDirectory] = useState('');\n const [formWdModalOpen, setFormWdModalOpen] = useState(false);\n const [formModel, setFormModel] = useState('');\n const [formSubmitting, setFormSubmitting] = useState(false);\n const formModelUserTouched = useRef(false);\n\n const [detailOpen, setDetailOpen] = useState(false);\n const [detailJob, setDetailJob] = useState<CronJob | null>(null);\n const [detailHistory, setDetailHistory] = useState<CronJobExecution[]>([]);\n const [detailLoading, setDetailLoading] = useState(false);\n\n const [confirmOpen, setConfirmOpen] = useState(false);\n const [confirmAction, setConfirmAction] = useState<'delete' | 'run' | null>(null);\n const [confirmJobId, setConfirmJobId] = useState<string | null>(null);\n\n const [templatePickerOpen, setTemplatePickerOpen] = useState(false);\n const [templateCategoryFilter, setTemplateCategoryFilter] = useState<CronTemplateFilter>('all');\n\n const absorbCardClickJobIdRef = useRef<string | null>(null);\n\n const scheduleAbsorbNextMenuCardClick = useCallback((jobId: string) => {\n absorbCardClickJobIdRef.current = jobId;\n window.setTimeout(() => {\n if (absorbCardClickJobIdRef.current === jobId) {\n absorbCardClickJobIdRef.current = null;\n }\n }, 400);\n }, []);\n\n const defaultModelForForm = useCallback(() => {\n return defaultModel || (availableModels.length > 0 ? availableModels[0].id : '');\n }, [defaultModel, availableModels]);\n\n const hasElectronFolderPicker =\n typeof window !== 'undefined' && Boolean(window.electronAPI?.file?.openDirectory);\n\n const openNativeFolderPickerCron = useCallback(async (): Promise<string | null> => {\n const api = typeof window !== 'undefined' ? window.electronAPI?.file?.openDirectory : undefined;\n if (api) return api();\n return null;\n }, []);\n\n const applyCronWorkingDirectory = useCallback(async (path: string) => {\n const t = path.trim();\n if (!t) return;\n pushRecentWorkspaceDirForCron(t);\n setFormWorkingDirectory(t);\n }, []);\n\n const cronAgentSelectOptions = useMemo(() => {\n const ids = new Set(chatAgents.map((a) => a.id));\n const out: ChatAgentOption[] = [...chatAgents];\n const extra = formAgentId.trim().toLowerCase();\n if (extra && !ids.has(extra)) {\n out.push({ id: extra });\n }\n return out;\n }, [chatAgents, formAgentId]);\n\n const needsDeliveryChat =\n formChannel !== 'local' && (formSessionTarget === 'main' || (formSessionTarget === 'isolated' && !formAgentLocalOnly));\n\n const showChannelPicker =\n formSessionTarget === 'main' || (formSessionTarget === 'isolated' && !formAgentLocalOnly);\n\n const canSubmit =\n Boolean(formName.trim()) &&\n Boolean(formSchedule.trim()) &&\n Boolean(formMessage.trim()) &&\n (!needsDeliveryChat || Boolean(formChatId.trim()));\n\n const loadRunHistoryOnly = useCallback(async () => {\n setRunHistoryLoading(true);\n try {\n const rows = await getAllRunsHistory(RUN_HISTORY_FETCH_LIMIT);\n setRunHistory(rows);\n } catch {\n /* ignore */\n } finally {\n setRunHistoryLoading(false);\n }\n }, []);\n\n const loadJobs = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const list = await listJobs();\n setJobs(list);\n } catch (e) {\n setError(e instanceof Error ? e.message : c.failedToLoadJobs);\n } finally {\n setLoading(false);\n }\n }, [c.failedToLoadJobs]);\n\n const loadAux = useCallback(async () => {\n try {\n const [ch, mods, cfg, cfgFull, agentsPayload] = await Promise.all([\n getChannels(),\n getModels(),\n getConfig(),\n fetchGatewayConfigSwrResponse(),\n fetchChatAgents().catch(() => null),\n ]);\n setChannels(ch);\n setAvailableModels(mods);\n setDefaultModel(cfg.model || '');\n setGatewayConfigRaw(cfgFull.payload?.config ?? null);\n if (agentsPayload) {\n setChatAgents(agentsPayload.items);\n }\n } catch {\n /* non-fatal */\n }\n }, []);\n\n useEffect(() => {\n if (!hasToken) return;\n void loadJobs();\n void loadAux();\n }, [hasToken, loadJobs, loadAux]);\n\n useEffect(() => {\n if (!hasToken) return;\n const onReload = () => {\n void fetchGatewayConfigSwrResponse().then((r) => {\n setGatewayConfigRaw(r.payload?.config ?? null);\n });\n };\n window.addEventListener('config-reload', onReload);\n return () => window.removeEventListener('config-reload', onReload);\n }, [hasToken]);\n\n useEffect(() => {\n if (!hasToken || mainTab !== 'history') return;\n void loadRunHistoryOnly();\n }, [hasToken, mainTab, loadRunHistoryOnly]);\n\n const releaseWakeLock = useCallback(async () => {\n if (wakeModeRef.current === 'electron') {\n try {\n await window.electronAPI?.cron?.setDisplaySleepPrevented?.(false);\n } catch {\n /* ignore */\n }\n wakeModeRef.current = 'none';\n return;\n }\n try {\n await wakeLockRef.current?.release();\n } catch {\n /* ignore */\n }\n wakeLockRef.current = null;\n wakeModeRef.current = 'none';\n }, []);\n\n const acquireWakeLock = useCallback(async () => {\n const electronWake =\n typeof window !== 'undefined' ? window.electronAPI?.cron?.setDisplaySleepPrevented : undefined;\n if (electronWake) {\n try {\n await electronWake(true);\n wakeModeRef.current = 'electron';\n return;\n } catch {\n setError(c.wakeLockUnavailable);\n setKeepAwake(false);\n return;\n }\n }\n if (!wakeSupported) return;\n try {\n const sentinel = await navigator.wakeLock.request('screen');\n wakeLockRef.current = sentinel;\n wakeModeRef.current = 'navigator';\n sentinel.addEventListener('release', () => {\n wakeLockRef.current = null;\n wakeModeRef.current = 'none';\n });\n } catch {\n setError(c.wakeLockUnavailable);\n setKeepAwake(false);\n }\n }, [c.wakeLockUnavailable, wakeSupported]);\n\n keepAwakeRef.current = keepAwake;\n\n useEffect(() => {\n if (!keepAwake) {\n void releaseWakeLock();\n return;\n }\n void acquireWakeLock();\n const onVis = () => {\n if (document.visibilityState === 'visible' && keepAwakeRef.current) void acquireWakeLock();\n };\n document.addEventListener('visibilitychange', onVis);\n return () => {\n document.removeEventListener('visibilitychange', onVis);\n void releaseWakeLock();\n };\n }, [keepAwake, acquireWakeLock, releaseWakeLock]);\n\n useEffect(() => {\n if (!formOpen || formMode !== 'add' || formModelUserTouched.current) return;\n const next = defaultModelForForm();\n if (next) setFormModel(next);\n }, [formOpen, formMode, defaultModelForForm]);\n\n useEffect(() => {\n if (!formOpen || formMode !== 'add') return;\n const valid = new Set(['local', ...channels.map((x) => x.name)]);\n if (!valid.has(formChannel)) setFormChannel('local');\n }, [channels, formChannel, formMode, formOpen]);\n\n useEffect(() => {\n if (formChannel === 'local') {\n setSessionChatIds([]);\n return;\n }\n let cancelled = false;\n void getSessionChatIds(formChannel).then((ids) => {\n if (!cancelled) setSessionChatIds(ids);\n });\n return () => {\n cancelled = true;\n };\n }, [formChannel, formOpen]);\n\n const openForm = useCallback(\n (job?: CronJob) => {\n formModelUserTouched.current = false;\n setFormOpen(true);\n setFormMode(job ? 'edit' : 'add');\n setFormJobId(job?.id ?? null);\n\n if (job) {\n setFormName(job.name || '');\n setFormSchedule((job.schedule && String(job.schedule).trim()) || DEFAULT_SCHEDULE);\n const bodyText = cronJobBodyText(job);\n setFormMessage(bodyText ?? '');\n setFormSessionTarget(job.sessionTarget || 'main');\n setFormAgentId(\n (job.sessionTarget || 'main') === 'isolated' && job.agentId?.trim()\n ? job.agentId.trim().toLowerCase()\n : '',\n );\n setFormWorkingDirectory(\n (job.sessionTarget || 'main') === 'isolated' && job.workingDirectory?.trim()\n ? job.workingDirectory.trim()\n : '',\n );\n const fromPayload =\n job.payload?.kind === 'agentTurn' && job.payload.model?.trim() ? job.payload.model.trim() : '';\n const stored = job.model?.trim() || fromPayload;\n setFormModel(stored || defaultModelForForm());\n const hasLocalChannel = job.delivery?.channel === 'local';\n const agentLocalOnly =\n (job.sessionTarget || 'main') === 'isolated' &&\n !hasLocalChannel &&\n (!job.delivery?.to || job.delivery.mode === 'none');\n setFormAgentLocalOnly(agentLocalOnly);\n\n if (hasLocalChannel) {\n setFormChannel('local');\n setFormChatId('');\n } else if (job.delivery && job.delivery.mode !== 'none' && job.delivery.to) {\n setFormChannel(job.delivery.channel || 'telegram');\n setFormChatId(job.delivery.to || '');\n } else if (!agentLocalOnly) {\n const parts = bodyText.split(':');\n const knownChannels = ['telegram', 'cli', 'gateway', 'local'];\n if (parts.length >= 3 && knownChannels.includes(parts[0])) {\n setFormChannel(parts[0]);\n setFormChatId(parts[1]);\n setFormMessage(parts.slice(2).join(':'));\n } else {\n setFormChannel('telegram');\n setFormChatId('');\n }\n } else {\n setFormChannel('telegram');\n setFormChatId('');\n }\n } else {\n setFormName('');\n setFormSchedule(DEFAULT_SCHEDULE);\n setFormChannel('local');\n setFormChatId('');\n setFormMessage('');\n setFormSessionTarget('main');\n setFormAgentId('');\n setFormWorkingDirectory('');\n setFormAgentLocalOnly(false);\n setFormModel(defaultModelForForm());\n }\n setFormMessageMdMode('edit');\n setMessageEditorNonce((n) => n + 1);\n },\n [defaultModelForForm],\n );\n\n const setMessageMdMode = useCallback((mode: 'edit' | 'preview') => {\n setFormMessageMdMode(mode);\n if (mode === 'edit') {\n setMessageEditorNonce((n) => n + 1);\n }\n }, []);\n\n const applyCronTemplate = useCallback(\n (templateId: string) => {\n const def = cronTemplateById(templateId);\n const copy = def ? getCronTemplateCopy(m.cron, templateId) : undefined;\n if (!def || !copy) return;\n formModelUserTouched.current = false;\n setFormMode('add');\n setFormJobId(null);\n setFormName(copy.title);\n setFormSchedule(def.defaultSchedule);\n setFormMessage(copy.prompt);\n setFormSessionTarget(def.defaultSessionTarget);\n setFormChannel('local');\n setFormChatId('');\n setFormAgentLocalOnly(false);\n setFormAgentId('');\n setFormWorkingDirectory('');\n setFormModel(defaultModelForForm());\n setFormMessageMdMode('edit');\n setMessageEditorNonce((n) => n + 1);\n setTemplatePickerOpen(false);\n setFormOpen(true);\n },\n [defaultModelForForm, m.cron],\n );\n\n const closeForm = useCallback(() => {\n setFormOpen(false);\n setFormMode('add');\n setFormJobId(null);\n setFormName('');\n setFormSchedule(DEFAULT_SCHEDULE);\n setFormChannel('local');\n setFormChatId('');\n setFormMessage('');\n setFormSessionTarget('main');\n setFormAgentId('');\n setFormWorkingDirectory('');\n setFormWdModalOpen(false);\n setFormAgentLocalOnly(false);\n setFormModel('');\n setFormMessageMdMode('edit');\n formModelUserTouched.current = false;\n }, []);\n\n const submitForm = async () => {\n if (!formName.trim()) {\n setError(c.nameRequired);\n return;\n }\n if (!formSchedule.trim() || !formMessage.trim()) {\n setError(c.scheduleRequired);\n return;\n }\n if (needsDeliveryChat && !formChatId.trim()) {\n setError(c.chatIdRequired);\n return;\n }\n\n setFormSubmitting(true);\n setError(null);\n try {\n const message = formMessage.trim();\n let delivery: CronDelivery;\n if (formSessionTarget === 'isolated' && formAgentLocalOnly) {\n delivery = { mode: 'none' };\n } else if (formChannel === 'local') {\n delivery = { mode: 'direct', channel: 'local' };\n } else {\n delivery = { mode: 'direct', channel: formChannel, to: formChatId.trim() };\n }\n\n const payload: CronPayload =\n formSessionTarget === 'isolated'\n ? {\n kind: 'agentTurn',\n message,\n ...(formModel.trim() ? { model: formModel.trim() } : {}),\n }\n : { kind: 'systemEvent', text: message };\n\n const modelTrimmed = formModel.trim();\n const agentIdTrim = formAgentId.trim().toLowerCase();\n const agentIdForEdit = formSessionTarget === 'main' ? null : agentIdTrim || null;\n const wdTrim = formWorkingDirectory.trim();\n const jobData = {\n name: formName.trim(),\n schedule: formSchedule.trim(),\n sessionTarget: formSessionTarget,\n model: formSessionTarget === 'isolated' && modelTrimmed ? modelTrimmed : undefined,\n delivery,\n payload,\n ...(formMode === 'edit'\n ? {\n agentId: agentIdForEdit,\n workingDirectory: formSessionTarget === 'isolated' ? wdTrim || null : null,\n }\n : {\n ...(formSessionTarget === 'isolated' && agentIdTrim ? { agentId: agentIdTrim } : {}),\n ...(formSessionTarget === 'isolated' && wdTrim ? { workingDirectory: wdTrim } : {}),\n }),\n };\n\n if (formMode === 'edit' && formJobId) {\n await updateJob(formJobId, jobData);\n } else {\n const { schedule: sched, agentId, workingDirectory, ...rest } = jobData;\n await addJob(sched, {\n ...rest,\n ...(agentId != null ? { agentId } : {}),\n ...(workingDirectory ? { workingDirectory } : {}),\n });\n }\n closeForm();\n await loadJobs();\n await loadAux();\n } catch (e) {\n setError(\n e instanceof Error\n ? e.message\n : formMode === 'edit'\n ? c.failedToUpdateJob\n : c.failedToCreateJob,\n );\n } finally {\n setFormSubmitting(false);\n }\n };\n\n const openDetail = async (job: CronJob) => {\n setDetailOpen(true);\n setDetailJob(job);\n setDetailLoading(true);\n setDetailHistory([]);\n try {\n const full = await getJob(job.id);\n if (full) {\n setDetailJob(full);\n setDetailHistory(await getHistory(job.id, 20));\n }\n } catch {\n /* keep partial */\n } finally {\n setDetailLoading(false);\n }\n };\n\n const onToggle = async (job: CronJob, enabled: boolean) => {\n try {\n await toggleJob(job.id, enabled);\n await loadJobs();\n await loadAux();\n } catch (e) {\n setError(e instanceof Error ? e.message : c.failedToToggleJob);\n }\n };\n\n const runConfirm = async () => {\n if (!confirmJobId || !confirmAction) return;\n const id = confirmJobId;\n const action = confirmAction;\n setConfirmOpen(false);\n setConfirmJobId(null);\n setConfirmAction(null);\n try {\n if (action === 'run') {\n await runJob(id);\n } else {\n await removeJob(id);\n if (detailJob?.id === id) {\n setDetailOpen(false);\n setDetailJob(null);\n }\n }\n await loadJobs();\n await loadAux();\n await loadRunHistoryOnly();\n } catch (e) {\n setError(e instanceof Error ? e.message : c.actionFailed);\n }\n };\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n if (formOpen) closeForm();\n else if (detailOpen) {\n setDetailOpen(false);\n setDetailJob(null);\n }\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, [formOpen, detailOpen, closeForm]);\n\n const statusLabels = useMemo(\n () => ({\n running: c.execStatusRunning,\n success: c.execStatusSuccess,\n failed: c.execStatusFailed,\n cancelled: c.execStatusCancelled,\n }),\n [c.execStatusCancelled, c.execStatusFailed, c.execStatusRunning, c.execStatusSuccess],\n );\n\n const userCronJobs = useMemo(() => jobs.filter((j) => !isDreamingManagedCronJob(j)), [jobs]);\n const systemCronJobs = useMemo(() => jobs.filter((j) => isDreamingManagedCronJob(j)), [jobs]);\n\n const sortJobsByCreated = useCallback(\n (arr: CronJob[]) => {\n const next = [...arr];\n next.sort((a, b) => {\n const ta = new Date(a.created_at).getTime();\n const tb = new Date(b.created_at).getTime();\n return jobSort === 'created_desc' ? tb - ta : ta - tb;\n });\n return next;\n },\n [jobSort],\n );\n\n const sortedUserJobs = useMemo(() => sortJobsByCreated(userCronJobs), [sortJobsByCreated, userCronJobs]);\n const sortedSystemJobs = useMemo(() => sortJobsByCreated(systemCronJobs), [sortJobsByCreated, systemCronJobs]);\n\n const heartbeatFromConfig = useMemo(\n () => normalizeHeartbeatFromConfig(gatewayConfigRaw),\n [gatewayConfigRaw],\n );\n\n const filteredRunHistory = useMemo(() => {\n const now = new Date();\n const from =\n historyRange === 'day'\n ? startOfLocalDay(now)\n : historyRange === 'week'\n ? startOfLocalWeekMonday(now)\n : startOfLocalMonth(now);\n return runHistory.filter((row) => {\n if (new Date(row.startedAt) < from) return false;\n if (historyJobFilter && row.jobId !== historyJobFilter) return false;\n if (historyStatusFilter && row.status !== historyStatusFilter) return false;\n return true;\n });\n }, [runHistory, historyRange, historyJobFilter, historyStatusFilter]);\n\n const scheduleBadgeLabels = c.scheduleBadge;\n\n const refreshAll = useCallback(() => {\n void loadJobs();\n void loadAux();\n void loadRunHistoryOnly();\n }, [loadJobs, loadAux, loadRunHistoryOnly]);\n\n const setPageHeader = usePageHeaderStore((s) => s.setPageHeader);\n const clearPageHeader = usePageHeaderStore((s) => s.clearPageHeader);\n const { pathname } = useLocation();\n const inSettingsShell = pathname.startsWith('/settings/');\n\n const handleFormSessionTargetChange = useCallback(\n (target: 'main' | 'isolated', defaultModelFallback: () => string, currentModel: string) => {\n setFormSessionTarget(target);\n if (target === 'main') {\n setFormAgentLocalOnly(false);\n setFormAgentId('');\n setFormWorkingDirectory('');\n } else if (target === 'isolated' && !currentModel) setFormModel(defaultModelFallback());\n },\n [],\n );\n\n const refreshRecipientsList = useCallback(() => {\n void getSessionChatIds(formChannel).then(setSessionChatIds);\n }, [formChannel]);\n\n const cronHeaderEnd = useMemo(\n () => (\n <CronPageHeaderActions\n c={c}\n loading={loading}\n runHistoryLoading={runHistoryLoading}\n onRefresh={refreshAll}\n onOpenTemplatePicker={() => {\n setTemplateCategoryFilter('all');\n setTemplatePickerOpen(true);\n }}\n onAddJob={() => openForm()}\n />\n ),\n [c, loading, openForm, refreshAll, runHistoryLoading],\n );\n\n useLayoutEffect(() => {\n if (!hasToken || inSettingsShell) {\n clearPageHeader();\n return () => clearPageHeader();\n }\n setPageHeader({\n startExtra: null,\n main: null,\n end: cronHeaderEnd,\n });\n return () => clearPageHeader();\n }, [clearPageHeader, cronHeaderEnd, hasToken, inSettingsShell, setPageHeader]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto w-full max-w-app-main px-4 py-16 text-center text-sm text-fg-muted sm:px-8\">{c.needToken}</div>\n );\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col overflow-y-auto bg-surface-panel\">\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6 sm:px-8\">\n {error ? (\n <div\n className=\"rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800 dark:border-red-900/50 dark:bg-red-950/40 dark:text-red-200\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : null}\n\n <header className=\"flex flex-col gap-4\">\n <div className=\"min-w-0\">\n <h1 className=\"text-xl font-semibold tracking-tight text-fg\">{c.title}</h1>\n <p className=\"mt-1 max-w-2xl text-sm text-fg-muted\">{c.subtitle}</p>\n </div>\n </header>\n\n {inSettingsShell ? (\n <div className=\"flex flex-wrap items-center justify-end gap-2 border-b border-edge-subtle pb-3 dark:border-edge-subtle\">\n {cronHeaderEnd}\n </div>\n ) : null}\n\n <CronMainToolbar\n c={c}\n mainTab={mainTab}\n onMainTabChange={setMainTab}\n jobSort={jobSort}\n onJobSortChange={setJobSort}\n historyRange={historyRange}\n onHistoryRangeChange={setHistoryRange}\n historyJobFilter={historyJobFilter}\n onHistoryJobFilterChange={setHistoryJobFilter}\n historyStatusFilter={historyStatusFilter}\n onHistoryStatusFilterChange={setHistoryStatusFilter}\n jobs={jobs}\n />\n\n {mainTab === 'myTasks' ? (\n <CronTasksPanel\n c={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n loading={loading}\n jobsCount={userCronJobs.length}\n sortedJobs={sortedUserJobs}\n templateCategoryFilter={templateCategoryFilter}\n onTemplateCategoryFilterChange={setTemplateCategoryFilter}\n onSelectTemplate={applyCronTemplate}\n keepAwake={keepAwake}\n wakeSupported={keepAwakeFeatureAvailable}\n onWakeUnsupportedClick={() => setError(c.wakeLockUnavailable)}\n onKeepAwakeToggle={() => setKeepAwake((v) => !v)}\n absorbCardClickJobIdRef={absorbCardClickJobIdRef}\n scheduleAbsorbNextMenuCardClick={scheduleAbsorbNextMenuCardClick}\n onOpenDetail={(j) => void openDetail(j)}\n onToggle={(j, en) => void onToggle(j, en)}\n onEdit={(j) => openForm(j)}\n onAddJob={() => openForm()}\n onRunNow={(j) => {\n setConfirmAction('run');\n setConfirmJobId(j.id);\n setConfirmOpen(true);\n }}\n onDelete={(j) => {\n setConfirmAction('delete');\n setConfirmJobId(j.id);\n setConfirmOpen(true);\n }}\n />\n ) : mainTab === 'systemTasks' ? (\n <CronSystemTasksPanel\n c={c}\n language={language}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n loading={loading}\n sortedSystemJobs={sortedSystemJobs}\n heartbeat={heartbeatFromConfig}\n keepAwake={keepAwake}\n wakeSupported={keepAwakeFeatureAvailable}\n onWakeUnsupportedClick={() => setError(c.wakeLockUnavailable)}\n onKeepAwakeToggle={() => setKeepAwake((v) => !v)}\n absorbCardClickJobIdRef={absorbCardClickJobIdRef}\n scheduleAbsorbNextMenuCardClick={scheduleAbsorbNextMenuCardClick}\n onOpenDetail={(j) => void openDetail(j)}\n onToggle={(j, en) => void onToggle(j, en)}\n onEdit={(j) => openForm(j)}\n onRunNow={(j) => {\n setConfirmAction('run');\n setConfirmJobId(j.id);\n setConfirmOpen(true);\n }}\n onDelete={(j) => {\n setConfirmAction('delete');\n setConfirmJobId(j.id);\n setConfirmOpen(true);\n }}\n />\n ) : (\n <CronRunHistorySection\n c={c}\n runHistoryLoading={runHistoryLoading}\n runHistory={runHistory}\n filteredRunHistory={filteredRunHistory}\n jobs={jobs}\n onRefreshHistory={() => void loadRunHistoryOnly()}\n onOpenJobDetail={(j) => void openDetail(j)}\n statusLabels={statusLabels}\n />\n )}\n </div>\n\n <CronJobFormDialog\n open={formOpen}\n onRequestClose={closeForm}\n c={c}\n chatM={chatM}\n agentsMessages={m.agentsSettings}\n isDark={isDark}\n channels={channels}\n sessionChatIds={sessionChatIds}\n cronAgentSelectOptions={cronAgentSelectOptions}\n hasElectronFolderPicker={hasElectronFolderPicker}\n openNativeFolderPicker={openNativeFolderPickerCron}\n applyWorkingDirectory={applyCronWorkingDirectory}\n wdModalOpen={formWdModalOpen}\n onWdModalOpenChange={setFormWdModalOpen}\n defaultModelResolver={defaultModelForForm}\n formMode={formMode}\n formJobId={formJobId}\n formName={formName}\n onFormNameChange={setFormName}\n formSchedule={formSchedule}\n onFormScheduleChange={setFormSchedule}\n formSubmitting={formSubmitting}\n formSessionTarget={formSessionTarget}\n onFormSessionTargetChange={handleFormSessionTargetChange}\n formAgentLocalOnly={formAgentLocalOnly}\n onFormAgentLocalOnlyChange={setFormAgentLocalOnly}\n formModel={formModel}\n onFormModelUserChange={(id) => {\n formModelUserTouched.current = true;\n setFormModel(id);\n }}\n formAgentId={formAgentId}\n onFormAgentIdChange={setFormAgentId}\n formWorkingDirectory={formWorkingDirectory}\n onFormWorkingDirectoryChange={setFormWorkingDirectory}\n formChannel={formChannel}\n onFormChannelChange={(v) => {\n setFormChannel(v);\n if (v === 'local') setFormAgentLocalOnly(false);\n setFormChatId('');\n }}\n formChatId={formChatId}\n onFormChatIdChange={setFormChatId}\n formMessage={formMessage}\n onFormMessageChange={setFormMessage}\n formMessageMdMode={formMessageMdMode}\n onSetMessageMdMode={setMessageMdMode}\n messageEditorNonce={messageEditorNonce}\n needsDeliveryChat={needsDeliveryChat}\n showChannelPicker={showChannelPicker}\n canSubmit={canSubmit}\n onSubmit={() => void submitForm()}\n onRefreshRecipients={refreshRecipientsList}\n />\n\n <CronTemplatePickerDialog\n open={templatePickerOpen}\n onOpenChange={(openNext) => {\n setTemplatePickerOpen(openNext);\n if (openNext) setTemplateCategoryFilter('all');\n }}\n c={c}\n localeTag={localeTag}\n scheduleBadgeLabels={scheduleBadgeLabels}\n categoryFilter={templateCategoryFilter}\n onCategoryFilterChange={setTemplateCategoryFilter}\n onSelectTemplate={applyCronTemplate}\n />\n\n <CronJobDetailDrawer\n open={detailOpen}\n onDismiss={() => {\n setDetailOpen(false);\n setDetailJob(null);\n }}\n detailJob={detailJob}\n detailLoading={detailLoading}\n detailHistory={detailHistory}\n c={c}\n chatWorkingDirNotSet={chatM.workingDirectory.notSet}\n statusLabels={statusLabels}\n />\n\n <CronConfirmActionDialog\n open={confirmOpen}\n onOpenChange={setConfirmOpen}\n action={confirmAction}\n c={c}\n onDismiss={() => {\n setConfirmOpen(false);\n setConfirmJobId(null);\n setConfirmAction(null);\n }}\n onConfirm={runConfirm}\n />\n </div>\n );\n}\n"],"mappings":"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"}