@xopcai/xopc 0.0.17 → 0.0.18

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 (32) hide show
  1. package/dist/extensions/telegram/xopc.extension.json +1 -1
  2. package/dist/gateway/static/root/assets/{agents-DouPaDd1.js → agents-D1c5jt8x.js} +2 -2
  3. package/dist/gateway/static/root/assets/{agents-DouPaDd1.js.map → agents-D1c5jt8x.js.map} +1 -1
  4. package/dist/gateway/static/root/assets/{apps-page-NiD-_oC4.js → apps-page-bi53w_qy.js} +2 -2
  5. package/dist/gateway/static/root/assets/{apps-page-NiD-_oC4.js.map → apps-page-bi53w_qy.js.map} +1 -1
  6. package/dist/gateway/static/root/assets/{channels-settings-BdNb4uD6.js → channels-settings-CPWWa4rf.js} +2 -2
  7. package/dist/gateway/static/root/assets/{channels-settings-BdNb4uD6.js.map → channels-settings-CPWWa4rf.js.map} +1 -1
  8. package/dist/gateway/static/root/assets/{cron-page-VjRx7Jtc.js → cron-page-CFuU6V8l.js} +2 -2
  9. package/dist/gateway/static/root/assets/{cron-page-VjRx7Jtc.js.map → cron-page-CFuU6V8l.js.map} +1 -1
  10. package/dist/gateway/static/root/assets/{cron-utils-CMkZdWey.js → cron-utils-D7qRCgCo.js} +2 -2
  11. package/dist/gateway/static/root/assets/{cron-utils-CMkZdWey.js.map → cron-utils-D7qRCgCo.js.map} +1 -1
  12. package/dist/gateway/static/root/assets/{dist-D-p_Xi_b.js → dist-CS--Aojm.js} +2 -2
  13. package/dist/gateway/static/root/assets/{dist-D-p_Xi_b.js.map → dist-CS--Aojm.js.map} +1 -1
  14. package/dist/gateway/static/root/assets/{extension-debug-page-B5jGnQgG.js → extension-debug-page-DkaqKijm.js} +2 -2
  15. package/dist/gateway/static/root/assets/{extension-debug-page-B5jGnQgG.js.map → extension-debug-page-DkaqKijm.js.map} +1 -1
  16. package/dist/gateway/static/root/assets/{extension-page-CSA88lpx.js → extension-page-5WNq5ZxE.js} +2 -2
  17. package/dist/gateway/static/root/assets/{extension-page-CSA88lpx.js.map → extension-page-5WNq5ZxE.js.map} +1 -1
  18. package/dist/gateway/static/root/assets/{extension-settings-page-C9HfcH28.js → extension-settings-page-BM4emw9B.js} +2 -2
  19. package/dist/gateway/static/root/assets/{extension-settings-page-C9HfcH28.js.map → extension-settings-page-BM4emw9B.js.map} +1 -1
  20. package/dist/gateway/static/root/assets/{index-C5pFj5w6.js → index-DJnBAhem.js} +4 -4
  21. package/dist/gateway/static/root/assets/{index-C5pFj5w6.js.map → index-DJnBAhem.js.map} +1 -1
  22. package/dist/gateway/static/root/assets/{logs-page-CrJ87O5K.js → logs-page-Du6UoHCK.js} +2 -2
  23. package/dist/gateway/static/root/assets/{logs-page-CrJ87O5K.js.map → logs-page-Du6UoHCK.js.map} +1 -1
  24. package/dist/gateway/static/root/assets/{sessions-page-DJfnuATX.js → sessions-page-CzTpNrb3.js} +2 -2
  25. package/dist/gateway/static/root/assets/{sessions-page-DJfnuATX.js.map → sessions-page-CzTpNrb3.js.map} +1 -1
  26. package/dist/gateway/static/root/assets/{settings-page-CBcPUTF-.js → settings-page-jqrVlTkQ.js} +2 -2
  27. package/dist/gateway/static/root/assets/{settings-page-CBcPUTF-.js.map → settings-page-jqrVlTkQ.js.map} +1 -1
  28. package/dist/gateway/static/root/assets/{skills-page-DVSS_5id.js → skills-page-Dg_Uk_jM.js} +2 -2
  29. package/dist/gateway/static/root/assets/{skills-page-DVSS_5id.js.map → skills-page-Dg_Uk_jM.js.map} +1 -1
  30. package/dist/gateway/static/root/index.html +1 -1
  31. package/dist/package.js +1 -1
  32. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cron-page-VjRx7Jtc.js","names":[],"sources":["../../../../../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-schedule-form.tsx","../../../../../web/src/features/cron/cron-page.tsx"],"sourcesContent":["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 { 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 * as DropdownMenu from '@radix-ui/react-dropdown-menu';\nimport {\n Clock,\n Eye,\n FolderInput,\n Info,\n LayoutTemplate,\n Loader2,\n MoreVertical,\n Plus,\n RefreshCw,\n SquarePen,\n X,\n} from 'lucide-react';\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { MarkdownEditor } from '@/components/markdown/markdown-editor';\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { Button } from '@/components/ui/button';\nimport {\n segmentedThumbActiveClassName,\n segmentedThumbBaseClassName,\n segmentedTrackClassName,\n} from '@/components/ui/segmented-styles';\nimport { fetchChatAgents, 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 { CronDelivery, CronJob, CronJobExecution, 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 CronPayload,\n type SessionChatId,\n} from '@/features/cron/cron-api';\nimport { getCronTemplateCopy } from '@/features/cron/cron-template-i18n';\nimport { CronTemplateLibrary, type CronTemplateFilter } from '@/features/cron/cron-template-library';\nimport { cronTemplateById } from '@/features/cron/cron-templates';\nimport { CronSchedulePicker } from '@/features/cron/cron-schedule-form';\nimport {\n execStatusLabel,\n formatDeliveryToSummary,\n formatDuration,\n formatNextRun,\n formatRecipientOptionLabel,\n formatScheduleBadge,\n formatTime,\n truncate,\n} from '@/features/cron/cron-utils';\nimport {\n formControlBorderFocusClass,\n nativeSelectMaxWidthClass,\n selectControlBaseClass,\n} from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\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';\n\nconst RUN_HISTORY_FETCH_LIMIT = 400;\n\nfunction 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). */\nfunction 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\nfunction startOfLocalMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), 1, 0, 0, 0, 0);\n}\n\nconst DEFAULT_SCHEDULE = '*/5 * * * *';\n\n/** Same storage key as chat composer so recent folders stay in sync. */\nconst RECENT_WD_STORAGE_KEY = 'xopc.recentWorkspaceDirs.v1';\nconst RECENT_WD_MAX = 10;\n\nfunction 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\nfunction 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\nfunction 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\nfunction selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nconst 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. */\nconst cronToolbarSelectClass = cn(\n selectControlBaseClass,\n 'w-auto min-w-[9rem] max-w-[14rem] shrink-0 text-xs',\n);\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<'tasks' | 'history'>('tasks');\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 keepAwakeRef = useRef(keepAwake);\n const wakeSupported = typeof navigator !== 'undefined' && 'wakeLock' in navigator;\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 [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 /** Radix menu is portaled; after selecting an item the same pointer `click` can hit the card underneath. */\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(\n async (path: string) => {\n const t = path.trim();\n if (!t) return;\n pushRecentWorkspaceDirForCron(t);\n setFormWorkingDirectory(t);\n },\n [],\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, agentsPayload] = await Promise.all([\n getChannels(),\n getModels(),\n getConfig(),\n fetchChatAgents().catch(() => null),\n ]);\n setChannels(ch);\n setAvailableModels(mods);\n setDefaultModel(cfg.model || '');\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 || mainTab !== 'history') return;\n void loadRunHistoryOnly();\n }, [hasToken, mainTab, loadRunHistoryOnly]);\n\n const releaseWakeLock = useCallback(async () => {\n try {\n await wakeLockRef.current?.release();\n } catch {\n /* ignore */\n }\n wakeLockRef.current = null;\n }, []);\n\n const acquireWakeLock = useCallback(async () => {\n if (!wakeSupported) return;\n try {\n const sentinel = await navigator.wakeLock.request('screen');\n wakeLockRef.current = sentinel;\n sentinel.addEventListener('release', () => {\n wakeLockRef.current = null;\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 =\n 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 = {\n running: c.execStatusRunning,\n success: c.execStatusSuccess,\n failed: c.execStatusFailed,\n cancelled: c.execStatusCancelled,\n };\n\n const sortedJobs = useMemo(() => {\n const arr = [...jobs];\n arr.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 arr;\n }, [jobs, jobSort]);\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 cronHeaderEnd = useMemo(\n () => (\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={loading || runHistoryLoading}\n title={c.refresh}\n aria-label={c.refresh}\n onClick={() => void refreshAll()}\n >\n <RefreshCw\n className={cn('size-4', (loading || runHistoryLoading) && 'animate-spin')}\n strokeWidth={1.75}\n />\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-2\"\n onClick={() => {\n setTemplateCategoryFilter('all');\n setTemplatePickerOpen(true);\n }}\n >\n <LayoutTemplate className=\"size-4\" strokeWidth={1.75} />\n {c.fromTemplate}\n </Button>\n <Button type=\"button\" variant=\"primary\" className=\"gap-2\" onClick={() => openForm()}>\n <Plus className=\"size-4\" strokeWidth={1.75} />\n {c.addJob}\n </Button>\n </div>\n ),\n [c.addJob, c.fromTemplate, c.refresh, 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 <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 === 'tasks'}\n className={cn(\n 'rounded-md px-3 py-2 text-sm font-medium transition-colors',\n mainTab === 'tasks' ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n onClick={() => setMainTab('tasks')}\n >\n {c.tabMyTasks}\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={() => setMainTab('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 === 'tasks' ? (\n <select\n className={cronToolbarSelectClass}\n value={jobSort}\n onChange={(e) => setJobSort(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 ) : (\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={() => setHistoryRange(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) => setHistoryJobFilter(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) => setHistoryStatusFilter(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 )}\n </div>\n </div>\n\n {mainTab === 'tasks' ? (\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) setError(c.wakeLockUnavailable);\n else setKeepAwake((v) => !v);\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 && jobs.length === 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 ) : jobs.length === 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={setTemplateCategoryFilter}\n onSelectTemplate={applyCronTemplate}\n />\n </div>\n <div className=\"flex justify-center\">\n <Button type=\"button\" variant=\"primary\" onClick={() => openForm()}>\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 <article\n key={job.id}\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 openDetail(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 openDetail(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 openForm(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 setConfirmAction('run');\n setConfirmJobId(job.id);\n setConfirmOpen(true);\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 setConfirmAction('delete');\n setConfirmJobId(job.id);\n setConfirmOpen(true);\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 </div>\n )}\n </section>\n ) : (\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 loadRunHistoryOnly()}\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 openDetail(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 </div>\n\n {/* Form dialog */}\n <Dialog.Root open={formOpen} onOpenChange={(o) => !o && closeForm()}>\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) => setFormName(e.target.value)}\n placeholder={c.namePlaceholder}\n />\n </label>\n <CronSchedulePicker\n value={formSchedule}\n onChange={setFormSchedule}\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 setFormSessionTarget(v);\n if (v === 'main') {\n setFormAgentLocalOnly(false);\n setFormAgentId('');\n setFormWorkingDirectory('');\n } else if (v === 'isolated' && !formModel.trim()) setFormModel(defaultModelForForm());\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={(id) => {\n formModelUserTouched.current = true;\n setFormModel(id);\n }}\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) => setFormAgentId(e.target.value)}\n >\n <option value=\"\">{c.agentProfileDefault}</option>\n {cronAgentSelectOptions.map((ag) => (\n <option key={ag.id} value={ag.id}>\n {ag.name ? `${ag.id} — ${ag.name}` : ag.id}\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 openNativeFolderPickerCron();\n if (picked) void applyCronWorkingDirectory(picked);\n })();\n } else {\n setFormWdModalOpen(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={() => setFormWorkingDirectory('')}\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) => setFormAgentLocalOnly(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 setFormChannel(v);\n if (v === 'local') setFormAgentLocalOnly(false);\n setFormChatId('');\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 getSessionChatIds(formChannel).then(setSessionChatIds)}\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) => setFormChatId(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) setFormChatId(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={() => setMessageMdMode('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={() => setMessageMdMode('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={setFormMessage}\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={closeForm}>\n {c.cancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n disabled={formSubmitting || !canSubmit}\n onClick={() => void submitForm()}\n >\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={formWdModalOpen}\n onOpenChange={setFormWdModalOpen}\n initialAbsolutePath={formWorkingDirectory.trim() || undefined}\n onConfirm={async (p) => {\n await applyCronWorkingDirectory(p);\n setFormWdModalOpen(false);\n }}\n wd={chatM.workingDirectory}\n />\n ) : null}\n\n {/* Template picker (when jobs already exist) */}\n <Dialog.Root\n open={templatePickerOpen}\n onOpenChange={(o) => {\n setTemplatePickerOpen(o);\n if (o) setTemplateCategoryFilter('all');\n }}\n >\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={templateCategoryFilter}\n onCategoryFilterChange={setTemplateCategoryFilter}\n onSelectTemplate={applyCronTemplate}\n />\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n\n {/* Detail drawer */}\n <Dialog.Root\n open={detailOpen}\n onOpenChange={(o) => {\n if (!o) {\n setDetailOpen(false);\n setDetailJob(null);\n }\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 : chatM.workingDirectory.notSet}\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 {/* Confirm run/delete */}\n <Dialog.Root open={confirmOpen} onOpenChange={setConfirmOpen}>\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 {confirmAction === 'delete' ? c.delete : c.runNow}\n </Dialog.Title>\n <p className=\"mt-2 text-sm text-fg-muted\">\n {confirmAction === 'delete' ? c.confirmDelete : c.confirmRun}\n </p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n setConfirmOpen(false);\n setConfirmJobId(null);\n setConfirmAction(null);\n }}\n >\n {c.cancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n className={confirmAction === 'delete' ? 'bg-red-600 hover:bg-red-700' : undefined}\n onClick={() => void runConfirm()}\n >\n {confirmAction === 'delete' ? c.delete : c.runNow}\n </Button>\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cron-page-CFuU6V8l.js","names":[],"sources":["../../../../../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-schedule-form.tsx","../../../../../web/src/features/cron/cron-page.tsx"],"sourcesContent":["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 { 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 * as DropdownMenu from '@radix-ui/react-dropdown-menu';\nimport {\n Clock,\n Eye,\n FolderInput,\n Info,\n LayoutTemplate,\n Loader2,\n MoreVertical,\n Plus,\n RefreshCw,\n SquarePen,\n X,\n} from 'lucide-react';\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { MarkdownEditor } from '@/components/markdown/markdown-editor';\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { Button } from '@/components/ui/button';\nimport {\n segmentedThumbActiveClassName,\n segmentedThumbBaseClassName,\n segmentedTrackClassName,\n} from '@/components/ui/segmented-styles';\nimport { fetchChatAgents, 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 { CronDelivery, CronJob, CronJobExecution, 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 CronPayload,\n type SessionChatId,\n} from '@/features/cron/cron-api';\nimport { getCronTemplateCopy } from '@/features/cron/cron-template-i18n';\nimport { CronTemplateLibrary, type CronTemplateFilter } from '@/features/cron/cron-template-library';\nimport { cronTemplateById } from '@/features/cron/cron-templates';\nimport { CronSchedulePicker } from '@/features/cron/cron-schedule-form';\nimport {\n execStatusLabel,\n formatDeliveryToSummary,\n formatDuration,\n formatNextRun,\n formatRecipientOptionLabel,\n formatScheduleBadge,\n formatTime,\n truncate,\n} from '@/features/cron/cron-utils';\nimport {\n formControlBorderFocusClass,\n nativeSelectMaxWidthClass,\n selectControlBaseClass,\n} from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\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';\n\nconst RUN_HISTORY_FETCH_LIMIT = 400;\n\nfunction 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). */\nfunction 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\nfunction startOfLocalMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), 1, 0, 0, 0, 0);\n}\n\nconst DEFAULT_SCHEDULE = '*/5 * * * *';\n\n/** Same storage key as chat composer so recent folders stay in sync. */\nconst RECENT_WD_STORAGE_KEY = 'xopc.recentWorkspaceDirs.v1';\nconst RECENT_WD_MAX = 10;\n\nfunction 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\nfunction 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\nfunction 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\nfunction selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nconst 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. */\nconst cronToolbarSelectClass = cn(\n selectControlBaseClass,\n 'w-auto min-w-[9rem] max-w-[14rem] shrink-0 text-xs',\n);\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<'tasks' | 'history'>('tasks');\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 keepAwakeRef = useRef(keepAwake);\n const wakeSupported = typeof navigator !== 'undefined' && 'wakeLock' in navigator;\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 [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 /** Radix menu is portaled; after selecting an item the same pointer `click` can hit the card underneath. */\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(\n async (path: string) => {\n const t = path.trim();\n if (!t) return;\n pushRecentWorkspaceDirForCron(t);\n setFormWorkingDirectory(t);\n },\n [],\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, agentsPayload] = await Promise.all([\n getChannels(),\n getModels(),\n getConfig(),\n fetchChatAgents().catch(() => null),\n ]);\n setChannels(ch);\n setAvailableModels(mods);\n setDefaultModel(cfg.model || '');\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 || mainTab !== 'history') return;\n void loadRunHistoryOnly();\n }, [hasToken, mainTab, loadRunHistoryOnly]);\n\n const releaseWakeLock = useCallback(async () => {\n try {\n await wakeLockRef.current?.release();\n } catch {\n /* ignore */\n }\n wakeLockRef.current = null;\n }, []);\n\n const acquireWakeLock = useCallback(async () => {\n if (!wakeSupported) return;\n try {\n const sentinel = await navigator.wakeLock.request('screen');\n wakeLockRef.current = sentinel;\n sentinel.addEventListener('release', () => {\n wakeLockRef.current = null;\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 =\n 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 = {\n running: c.execStatusRunning,\n success: c.execStatusSuccess,\n failed: c.execStatusFailed,\n cancelled: c.execStatusCancelled,\n };\n\n const sortedJobs = useMemo(() => {\n const arr = [...jobs];\n arr.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 arr;\n }, [jobs, jobSort]);\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 cronHeaderEnd = useMemo(\n () => (\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={loading || runHistoryLoading}\n title={c.refresh}\n aria-label={c.refresh}\n onClick={() => void refreshAll()}\n >\n <RefreshCw\n className={cn('size-4', (loading || runHistoryLoading) && 'animate-spin')}\n strokeWidth={1.75}\n />\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-2\"\n onClick={() => {\n setTemplateCategoryFilter('all');\n setTemplatePickerOpen(true);\n }}\n >\n <LayoutTemplate className=\"size-4\" strokeWidth={1.75} />\n {c.fromTemplate}\n </Button>\n <Button type=\"button\" variant=\"primary\" className=\"gap-2\" onClick={() => openForm()}>\n <Plus className=\"size-4\" strokeWidth={1.75} />\n {c.addJob}\n </Button>\n </div>\n ),\n [c.addJob, c.fromTemplate, c.refresh, 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 <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 === 'tasks'}\n className={cn(\n 'rounded-md px-3 py-2 text-sm font-medium transition-colors',\n mainTab === 'tasks' ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n onClick={() => setMainTab('tasks')}\n >\n {c.tabMyTasks}\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={() => setMainTab('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 === 'tasks' ? (\n <select\n className={cronToolbarSelectClass}\n value={jobSort}\n onChange={(e) => setJobSort(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 ) : (\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={() => setHistoryRange(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) => setHistoryJobFilter(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) => setHistoryStatusFilter(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 )}\n </div>\n </div>\n\n {mainTab === 'tasks' ? (\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) setError(c.wakeLockUnavailable);\n else setKeepAwake((v) => !v);\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 && jobs.length === 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 ) : jobs.length === 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={setTemplateCategoryFilter}\n onSelectTemplate={applyCronTemplate}\n />\n </div>\n <div className=\"flex justify-center\">\n <Button type=\"button\" variant=\"primary\" onClick={() => openForm()}>\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 <article\n key={job.id}\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 openDetail(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 openDetail(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 openForm(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 setConfirmAction('run');\n setConfirmJobId(job.id);\n setConfirmOpen(true);\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 setConfirmAction('delete');\n setConfirmJobId(job.id);\n setConfirmOpen(true);\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 </div>\n )}\n </section>\n ) : (\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 loadRunHistoryOnly()}\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 openDetail(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 </div>\n\n {/* Form dialog */}\n <Dialog.Root open={formOpen} onOpenChange={(o) => !o && closeForm()}>\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) => setFormName(e.target.value)}\n placeholder={c.namePlaceholder}\n />\n </label>\n <CronSchedulePicker\n value={formSchedule}\n onChange={setFormSchedule}\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 setFormSessionTarget(v);\n if (v === 'main') {\n setFormAgentLocalOnly(false);\n setFormAgentId('');\n setFormWorkingDirectory('');\n } else if (v === 'isolated' && !formModel.trim()) setFormModel(defaultModelForForm());\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={(id) => {\n formModelUserTouched.current = true;\n setFormModel(id);\n }}\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) => setFormAgentId(e.target.value)}\n >\n <option value=\"\">{c.agentProfileDefault}</option>\n {cronAgentSelectOptions.map((ag) => (\n <option key={ag.id} value={ag.id}>\n {ag.name ? `${ag.id} — ${ag.name}` : ag.id}\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 openNativeFolderPickerCron();\n if (picked) void applyCronWorkingDirectory(picked);\n })();\n } else {\n setFormWdModalOpen(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={() => setFormWorkingDirectory('')}\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) => setFormAgentLocalOnly(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 setFormChannel(v);\n if (v === 'local') setFormAgentLocalOnly(false);\n setFormChatId('');\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 getSessionChatIds(formChannel).then(setSessionChatIds)}\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) => setFormChatId(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) setFormChatId(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={() => setMessageMdMode('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={() => setMessageMdMode('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={setFormMessage}\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={closeForm}>\n {c.cancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n disabled={formSubmitting || !canSubmit}\n onClick={() => void submitForm()}\n >\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={formWdModalOpen}\n onOpenChange={setFormWdModalOpen}\n initialAbsolutePath={formWorkingDirectory.trim() || undefined}\n onConfirm={async (p) => {\n await applyCronWorkingDirectory(p);\n setFormWdModalOpen(false);\n }}\n wd={chatM.workingDirectory}\n />\n ) : null}\n\n {/* Template picker (when jobs already exist) */}\n <Dialog.Root\n open={templatePickerOpen}\n onOpenChange={(o) => {\n setTemplatePickerOpen(o);\n if (o) setTemplateCategoryFilter('all');\n }}\n >\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={templateCategoryFilter}\n onCategoryFilterChange={setTemplateCategoryFilter}\n onSelectTemplate={applyCronTemplate}\n />\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n\n {/* Detail drawer */}\n <Dialog.Root\n open={detailOpen}\n onOpenChange={(o) => {\n if (!o) {\n setDetailOpen(false);\n setDetailJob(null);\n }\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 : chatM.workingDirectory.notSet}\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 {/* Confirm run/delete */}\n <Dialog.Root open={confirmOpen} onOpenChange={setConfirmOpen}>\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 {confirmAction === 'delete' ? c.delete : c.runNow}\n </Dialog.Title>\n <p className=\"mt-2 text-sm text-fg-muted\">\n {confirmAction === 'delete' ? c.confirmDelete : c.confirmRun}\n </p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n setConfirmOpen(false);\n setConfirmJobId(null);\n setConfirmAction(null);\n }}\n >\n {c.cancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n className={confirmAction === 'delete' ? 'bg-red-600 hover:bg-red-700' : undefined}\n onClick={() => void runConfirm()}\n >\n {confirmAction === 'delete' ? c.delete : c.runNow}\n </Button>\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n </div>\n );\n}\n"],"mappings":"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"}