@haseebuchiha/silvr 2026.3.20 → 2026.3.21

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.
@@ -1 +1 @@
1
- {"version":3,"file":"cron-SRhGYXwl.js","names":["t"],"sources":["../../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directives/if-defined.js","../../../ui/src/ui/views/cron.ts"],"sourcesContent":["import{nothing as t}from\"../lit-html.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o=o=>o??t;export{o as ifDefined};\n//# sourceMappingURL=if-defined.js.map\n","import { html, nothing } from \"lit\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { t } from \"../../i18n/index.ts\";\nimport type {\n CronFieldErrors,\n CronFieldKey,\n CronJobsLastStatusFilter,\n CronJobsScheduleKindFilter,\n} from \"../controllers/cron.ts\";\nimport { formatRelativeTimestamp, formatMs } from \"../format.ts\";\nimport { pathForTab } from \"../navigation.ts\";\nimport { formatCronSchedule, formatNextRun } from \"../presenter.ts\";\nimport type { ChannelUiMetaEntry, CronJob, CronRunLogEntry, CronStatus } from \"../types.ts\";\nimport type {\n CronDeliveryStatus,\n CronJobsEnabledFilter,\n CronRunScope,\n CronRunsStatusValue,\n CronJobsSortBy,\n CronRunsStatusFilter,\n CronSortDir,\n} from \"../types.ts\";\nimport type { CronFormState } from \"../ui-types.ts\";\n\nexport type CronProps = {\n basePath: string;\n loading: boolean;\n jobsLoadingMore: boolean;\n status: CronStatus | null;\n jobs: CronJob[];\n jobsTotal: number;\n jobsHasMore: boolean;\n jobsQuery: string;\n jobsEnabledFilter: CronJobsEnabledFilter;\n jobsScheduleKindFilter: CronJobsScheduleKindFilter;\n jobsLastStatusFilter: CronJobsLastStatusFilter;\n jobsSortBy: CronJobsSortBy;\n jobsSortDir: CronSortDir;\n error: string | null;\n busy: boolean;\n form: CronFormState;\n fieldErrors: CronFieldErrors;\n canSubmit: boolean;\n editingJobId: string | null;\n channels: string[];\n channelLabels?: Record<string, string>;\n channelMeta?: ChannelUiMetaEntry[];\n runsJobId: string | null;\n runs: CronRunLogEntry[];\n runsTotal: number;\n runsHasMore: boolean;\n runsLoadingMore: boolean;\n runsScope: CronRunScope;\n runsStatuses: CronRunsStatusValue[];\n runsDeliveryStatuses: CronDeliveryStatus[];\n runsStatusFilter: CronRunsStatusFilter;\n runsQuery: string;\n runsSortDir: CronSortDir;\n agentSuggestions: string[];\n modelSuggestions: string[];\n thinkingSuggestions: string[];\n timezoneSuggestions: string[];\n deliveryToSuggestions: string[];\n accountSuggestions: string[];\n onFormChange: (patch: Partial<CronFormState>) => void;\n onRefresh: () => void;\n onAdd: () => void;\n onEdit: (job: CronJob) => void;\n onClone: (job: CronJob) => void;\n onCancelEdit: () => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onRun: (job: CronJob, mode?: \"force\" | \"due\") => void;\n onRemove: (job: CronJob) => void;\n onLoadRuns: (jobId: string) => void;\n onLoadMoreJobs: () => void;\n onJobsFiltersChange: (patch: {\n cronJobsQuery?: string;\n cronJobsEnabledFilter?: CronJobsEnabledFilter;\n cronJobsScheduleKindFilter?: CronJobsScheduleKindFilter;\n cronJobsLastStatusFilter?: CronJobsLastStatusFilter;\n cronJobsSortBy?: CronJobsSortBy;\n cronJobsSortDir?: CronSortDir;\n }) => void | Promise<void>;\n onJobsFiltersReset: () => void | Promise<void>;\n onLoadMoreRuns: () => void;\n onRunsFiltersChange: (patch: {\n cronRunsScope?: CronRunScope;\n cronRunsStatuses?: CronRunsStatusValue[];\n cronRunsDeliveryStatuses?: CronDeliveryStatus[];\n cronRunsStatusFilter?: CronRunsStatusFilter;\n cronRunsQuery?: string;\n cronRunsSortDir?: CronSortDir;\n }) => void | Promise<void>;\n};\n\nfunction getRunStatusOptions(): Array<{ value: CronRunsStatusValue; label: string }> {\n return [\n { value: \"ok\", label: t(\"cron.runs.runStatusOk\") },\n { value: \"error\", label: t(\"cron.runs.runStatusError\") },\n { value: \"skipped\", label: t(\"cron.runs.runStatusSkipped\") },\n ];\n}\n\nfunction getRunDeliveryOptions(): Array<{ value: CronDeliveryStatus; label: string }> {\n return [\n { value: \"delivered\", label: t(\"cron.runs.deliveryDelivered\") },\n { value: \"not-delivered\", label: t(\"cron.runs.deliveryNotDelivered\") },\n { value: \"unknown\", label: t(\"cron.runs.deliveryUnknown\") },\n { value: \"not-requested\", label: t(\"cron.runs.deliveryNotRequested\") },\n ];\n}\n\nfunction toggleSelection<T extends string>(selected: T[], value: T, checked: boolean): T[] {\n const set = new Set(selected);\n if (checked) {\n set.add(value);\n } else {\n set.delete(value);\n }\n return Array.from(set);\n}\n\nfunction summarizeSelection(selectedLabels: string[], allLabel: string) {\n if (selectedLabels.length === 0) {\n return allLabel;\n }\n if (selectedLabels.length <= 2) {\n return selectedLabels.join(\", \");\n }\n return `${selectedLabels[0]} +${selectedLabels.length - 1}`;\n}\n\nfunction buildChannelOptions(props: CronProps): string[] {\n const options = [\"last\", ...props.channels.filter(Boolean)];\n const current = props.form.deliveryChannel?.trim();\n if (current && !options.includes(current)) {\n options.push(current);\n }\n const seen = new Set<string>();\n return options.filter((value) => {\n if (seen.has(value)) {\n return false;\n }\n seen.add(value);\n return true;\n });\n}\n\nfunction resolveChannelLabel(props: CronProps, channel: string): string {\n if (channel === \"last\") {\n return \"last\";\n }\n const meta = props.channelMeta?.find((entry) => entry.id === channel);\n if (meta?.label) {\n return meta.label;\n }\n return props.channelLabels?.[channel] ?? channel;\n}\n\nfunction renderRunFilterDropdown(params: {\n id: string;\n title: string;\n summary: string;\n options: Array<{ value: string; label: string }>;\n selected: string[];\n onToggle: (value: string, checked: boolean) => void;\n onClear: () => void;\n}) {\n return html`\n <div class=\"field cron-filter-dropdown\" data-filter=${params.id}>\n <span>${params.title}</span>\n <details class=\"cron-filter-dropdown__details\">\n <summary class=\"btn cron-filter-dropdown__trigger\">\n <span>${params.summary}</span>\n </summary>\n <div class=\"cron-filter-dropdown__panel\">\n <div class=\"cron-filter-dropdown__list\">\n ${params.options.map(\n (option) => html`\n <label class=\"cron-filter-dropdown__option\">\n <input\n type=\"checkbox\"\n value=${option.value}\n .checked=${params.selected.includes(option.value)}\n @change=${(event: Event) => {\n const target = event.target as HTMLInputElement;\n params.onToggle(option.value, target.checked);\n }}\n />\n <span>${option.label}</span>\n </label>\n `,\n )}\n </div>\n <div class=\"row\">\n <button class=\"btn\" type=\"button\" @click=${params.onClear}>${t(\"cron.runs.clear\")}</button>\n </div>\n </div>\n </details>\n </div>\n `;\n}\n\nfunction renderSuggestionList(id: string, options: string[]) {\n const clean = Array.from(new Set(options.map((option) => option.trim()).filter(Boolean)));\n if (clean.length === 0) {\n return nothing;\n }\n return html`<datalist id=${id}>\n ${clean.map((value) => html`<option value=${value}></option> `)}\n </datalist>`;\n}\n\ntype BlockingField = {\n key: CronFieldKey;\n label: string;\n message: string;\n inputId: string;\n};\n\nfunction errorIdForField(key: CronFieldKey) {\n return `cron-error-${key}`;\n}\n\nfunction inputIdForField(key: CronFieldKey) {\n if (key === \"name\") {\n return \"cron-name\";\n }\n if (key === \"scheduleAt\") {\n return \"cron-schedule-at\";\n }\n if (key === \"everyAmount\") {\n return \"cron-every-amount\";\n }\n if (key === \"cronExpr\") {\n return \"cron-cron-expr\";\n }\n if (key === \"staggerAmount\") {\n return \"cron-stagger-amount\";\n }\n if (key === \"payloadText\") {\n return \"cron-payload-text\";\n }\n if (key === \"payloadModel\") {\n return \"cron-payload-model\";\n }\n if (key === \"payloadThinking\") {\n return \"cron-payload-thinking\";\n }\n if (key === \"timeoutSeconds\") {\n return \"cron-timeout-seconds\";\n }\n if (key === \"failureAlertAfter\") {\n return \"cron-failure-alert-after\";\n }\n if (key === \"failureAlertCooldownSeconds\") {\n return \"cron-failure-alert-cooldown-seconds\";\n }\n return \"cron-delivery-to\";\n}\n\nfunction fieldLabelForKey(\n key: CronFieldKey,\n form: CronFormState,\n deliveryMode: CronFormState[\"deliveryMode\"],\n) {\n if (key === \"payloadText\") {\n return form.payloadKind === \"systemEvent\"\n ? t(\"cron.form.mainTimelineMessage\")\n : t(\"cron.form.assistantTaskPrompt\");\n }\n if (key === \"deliveryTo\") {\n return deliveryMode === \"webhook\" ? t(\"cron.form.webhookUrl\") : t(\"cron.form.to\");\n }\n const labels: Record<CronFieldKey, string> = {\n name: t(\"cron.form.fieldName\"),\n scheduleAt: t(\"cron.form.runAt\"),\n everyAmount: t(\"cron.form.every\"),\n cronExpr: t(\"cron.form.expression\"),\n staggerAmount: t(\"cron.form.staggerWindow\"),\n payloadText: t(\"cron.form.assistantTaskPrompt\"),\n payloadModel: t(\"cron.form.model\"),\n payloadThinking: t(\"cron.form.thinking\"),\n timeoutSeconds: t(\"cron.form.timeoutSeconds\"),\n deliveryTo: t(\"cron.form.to\"),\n failureAlertAfter: \"Failure alert after\",\n failureAlertCooldownSeconds: \"Failure alert cooldown\",\n };\n return labels[key];\n}\n\nfunction collectBlockingFields(\n errors: CronFieldErrors,\n form: CronFormState,\n deliveryMode: CronFormState[\"deliveryMode\"],\n): BlockingField[] {\n const orderedKeys: CronFieldKey[] = [\n \"name\",\n \"scheduleAt\",\n \"everyAmount\",\n \"cronExpr\",\n \"staggerAmount\",\n \"payloadText\",\n \"payloadModel\",\n \"payloadThinking\",\n \"timeoutSeconds\",\n \"deliveryTo\",\n \"failureAlertAfter\",\n \"failureAlertCooldownSeconds\",\n ];\n const fields: BlockingField[] = [];\n for (const key of orderedKeys) {\n const message = errors[key];\n if (!message) {\n continue;\n }\n fields.push({\n key,\n label: fieldLabelForKey(key, form, deliveryMode),\n message,\n inputId: inputIdForField(key),\n });\n }\n return fields;\n}\n\nfunction focusFormField(id: string) {\n const el = document.getElementById(id);\n if (!(el instanceof HTMLElement)) {\n return;\n }\n if (typeof el.scrollIntoView === \"function\") {\n el.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n }\n el.focus();\n}\n\nfunction renderFieldLabel(text: string, required = false) {\n return html`<span>\n ${text}\n ${\n required\n ? html`\n <span class=\"cron-required-marker\" aria-hidden=\"true\">*</span>\n <span class=\"cron-required-sr\">${t(\"cron.form.requiredSr\")}</span>\n `\n : nothing\n }\n </span>`;\n}\n\nexport function renderCron(props: CronProps) {\n const isEditing = Boolean(props.editingJobId);\n const isAgentTurn = props.form.payloadKind === \"agentTurn\";\n const isCronSchedule = props.form.scheduleKind === \"cron\";\n const channelOptions = buildChannelOptions(props);\n const selectedJob =\n props.runsJobId == null ? undefined : props.jobs.find((job) => job.id === props.runsJobId);\n const selectedRunTitle =\n props.runsScope === \"all\"\n ? t(\"cron.jobList.allJobs\")\n : (selectedJob?.name ?? props.runsJobId ?? t(\"cron.jobList.selectJob\"));\n const runs = props.runs.toSorted((a, b) =>\n props.runsSortDir === \"asc\" ? a.ts - b.ts : b.ts - a.ts,\n );\n const runStatusOptions = getRunStatusOptions();\n const runDeliveryOptions = getRunDeliveryOptions();\n const selectedStatusLabels = runStatusOptions\n .filter((option) => props.runsStatuses.includes(option.value))\n .map((option) => option.label);\n const selectedDeliveryLabels = runDeliveryOptions\n .filter((option) => props.runsDeliveryStatuses.includes(option.value))\n .map((option) => option.label);\n const statusSummary = summarizeSelection(selectedStatusLabels, t(\"cron.runs.allStatuses\"));\n const deliverySummary = summarizeSelection(selectedDeliveryLabels, t(\"cron.runs.allDelivery\"));\n const supportsAnnounce =\n props.form.sessionTarget !== \"main\" && props.form.payloadKind === \"agentTurn\";\n const selectedDeliveryMode =\n props.form.deliveryMode === \"announce\" && !supportsAnnounce ? \"none\" : props.form.deliveryMode;\n const blockingFields = collectBlockingFields(props.fieldErrors, props.form, selectedDeliveryMode);\n const blockedByValidation = !props.busy && blockingFields.length > 0;\n const hasActiveJobsFilters =\n props.jobsQuery.trim().length > 0 ||\n props.jobsEnabledFilter !== \"all\" ||\n props.jobsScheduleKindFilter !== \"all\" ||\n props.jobsLastStatusFilter !== \"all\" ||\n props.jobsSortBy !== \"nextRunAtMs\" ||\n props.jobsSortDir !== \"asc\";\n const submitDisabledReason =\n blockedByValidation && !props.canSubmit\n ? blockingFields.length === 1\n ? t(\"cron.form.fixFields\", { count: String(blockingFields.length) })\n : t(\"cron.form.fixFieldsPlural\", { count: String(blockingFields.length) })\n : \"\";\n return html`\n <section class=\"card cron-summary-strip\">\n <div class=\"cron-summary-strip__left\">\n <div class=\"cron-summary-item\">\n <div class=\"cron-summary-label\">${t(\"cron.summary.enabled\")}</div>\n <div class=\"cron-summary-value\">\n <span class=${`chip ${props.status?.enabled ? \"chip-ok\" : \"chip-danger\"}`}>\n ${\n props.status\n ? props.status.enabled\n ? t(\"cron.summary.yes\")\n : t(\"cron.summary.no\")\n : t(\"common.na\")\n }\n </span>\n </div>\n </div>\n <div class=\"cron-summary-item\">\n <div class=\"cron-summary-label\">${t(\"cron.summary.jobs\")}</div>\n <div class=\"cron-summary-value\">${props.status?.jobs ?? t(\"common.na\")}</div>\n </div>\n <div class=\"cron-summary-item cron-summary-item--wide\">\n <div class=\"cron-summary-label\">${t(\"cron.summary.nextWake\")}</div>\n <div class=\"cron-summary-value\">${formatNextRun(props.status?.nextWakeAtMs ?? null)}</div>\n </div>\n </div>\n <div class=\"cron-summary-strip__actions\">\n <button class=\"btn\" ?disabled=${props.loading} @click=${props.onRefresh}>\n ${props.loading ? t(\"cron.summary.refreshing\") : t(\"cron.summary.refresh\")}\n </button>\n ${props.error ? html`<span class=\"muted\">${props.error}</span>` : nothing}\n </div>\n </section>\n\n <section class=\"cron-workspace\">\n <div class=\"cron-workspace-main\">\n <section class=\"card\">\n <div class=\"row\" style=\"justify-content: space-between; align-items: flex-start; gap: 12px;\">\n <div>\n <div class=\"card-title\">${t(\"cron.jobs.title\")}</div>\n <div class=\"card-sub\">${t(\"cron.jobs.subtitle\")}</div>\n </div>\n <div class=\"muted\">${t(\"cron.jobs.shownOf\", {\n shown: String(props.jobs.length),\n total: String(props.jobsTotal),\n })}</div>\n </div>\n <div class=\"filters\" style=\"margin-top: 12px;\">\n <label class=\"field cron-filter-search\">\n <span>${t(\"cron.jobs.searchJobs\")}</span>\n <input\n .value=${props.jobsQuery}\n placeholder=${t(\"cron.jobs.searchPlaceholder\")}\n @input=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsQuery: (e.target as HTMLInputElement).value,\n })}\n />\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.enabled\")}</span>\n <select\n .value=${props.jobsEnabledFilter}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsEnabledFilter: (e.target as HTMLSelectElement)\n .value as CronJobsEnabledFilter,\n })}\n >\n <option value=\"all\">${t(\"cron.jobs.all\")}</option>\n <option value=\"enabled\">${t(\"common.enabled\")}</option>\n <option value=\"disabled\">${t(\"common.disabled\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.schedule\")}</span>\n <select\n data-test-id=\"cron-jobs-schedule-filter\"\n .value=${props.jobsScheduleKindFilter}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsScheduleKindFilter: (e.target as HTMLSelectElement)\n .value as CronJobsScheduleKindFilter,\n })}\n >\n <option value=\"all\">${t(\"cron.jobs.all\")}</option>\n <option value=\"at\">${t(\"cron.form.at\")}</option>\n <option value=\"every\">${t(\"cron.form.every\")}</option>\n <option value=\"cron\">${t(\"cron.form.cronOption\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.lastRun\")}</span>\n <select\n data-test-id=\"cron-jobs-last-status-filter\"\n .value=${props.jobsLastStatusFilter}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsLastStatusFilter: (e.target as HTMLSelectElement)\n .value as CronJobsLastStatusFilter,\n })}\n >\n <option value=\"all\">${t(\"cron.jobs.all\")}</option>\n <option value=\"ok\">${t(\"cron.runs.runStatusOk\")}</option>\n <option value=\"error\">${t(\"cron.runs.runStatusError\")}</option>\n <option value=\"skipped\">${t(\"cron.runs.runStatusSkipped\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.sort\")}</span>\n <select\n .value=${props.jobsSortBy}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsSortBy: (e.target as HTMLSelectElement).value as CronJobsSortBy,\n })}\n >\n <option value=\"nextRunAtMs\">${t(\"cron.jobs.nextRun\")}</option>\n <option value=\"updatedAtMs\">${t(\"cron.jobs.recentlyUpdated\")}</option>\n <option value=\"name\">${t(\"cron.jobs.name\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.direction\")}</span>\n <select\n .value=${props.jobsSortDir}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsSortDir: (e.target as HTMLSelectElement).value as CronSortDir,\n })}\n >\n <option value=\"asc\">${t(\"cron.jobs.ascending\")}</option>\n <option value=\"desc\">${t(\"cron.jobs.descending\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.reset\")}</span>\n <button\n class=\"btn\"\n data-test-id=\"cron-jobs-filters-reset\"\n ?disabled=${!hasActiveJobsFilters}\n @click=${props.onJobsFiltersReset}\n >\n ${t(\"cron.jobs.reset\")}\n </button>\n </label>\n </div>\n ${\n props.jobs.length === 0\n ? html`\n <div class=\"muted\" style=\"margin-top: 12px\">${t(\"cron.jobs.noMatching\")}</div>\n `\n : html`\n <div class=\"list\" style=\"margin-top: 12px;\">\n ${props.jobs.map((job) => renderJob(job, props))}\n </div>\n `\n }\n ${\n props.jobsHasMore\n ? html`\n <div class=\"row\" style=\"margin-top: 12px\">\n <button\n class=\"btn\"\n ?disabled=${props.loading || props.jobsLoadingMore}\n @click=${props.onLoadMoreJobs}\n >\n ${props.jobsLoadingMore ? t(\"cron.jobs.loading\") : t(\"cron.jobs.loadMore\")}\n </button>\n </div>\n `\n : nothing\n }\n </section>\n\n <section class=\"card\">\n <div class=\"row\" style=\"justify-content: space-between; align-items: flex-start; gap: 12px;\">\n <div>\n <div class=\"card-title\">${t(\"cron.runs.title\")}</div>\n <div class=\"card-sub\">\n ${\n props.runsScope === \"all\"\n ? t(\"cron.runs.subtitleAll\")\n : t(\"cron.runs.subtitleJob\", { title: selectedRunTitle })\n }\n </div>\n </div>\n <div class=\"muted\">${t(\"cron.jobs.shownOf\", {\n shown: String(runs.length),\n total: String(props.runsTotal),\n })}</div>\n </div>\n <div class=\"cron-run-filters\">\n <div class=\"cron-run-filters__row cron-run-filters__row--primary\">\n <label class=\"field\">\n <span>${t(\"cron.runs.scope\")}</span>\n <select\n .value=${props.runsScope}\n @change=${(e: Event) =>\n props.onRunsFiltersChange({\n cronRunsScope: (e.target as HTMLSelectElement).value as CronRunScope,\n })}\n >\n <option value=\"all\">${t(\"cron.runs.allJobs\")}</option>\n <option value=\"job\" ?disabled=${props.runsJobId == null}>${t(\"cron.runs.selectedJob\")}</option>\n </select>\n </label>\n <label class=\"field cron-run-filter-search\">\n <span>${t(\"cron.runs.searchRuns\")}</span>\n <input\n .value=${props.runsQuery}\n placeholder=${t(\"cron.runs.searchPlaceholder\")}\n @input=${(e: Event) =>\n props.onRunsFiltersChange({\n cronRunsQuery: (e.target as HTMLInputElement).value,\n })}\n />\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.sort\")}</span>\n <select\n .value=${props.runsSortDir}\n @change=${(e: Event) =>\n props.onRunsFiltersChange({\n cronRunsSortDir: (e.target as HTMLSelectElement).value as CronSortDir,\n })}\n >\n <option value=\"desc\">${t(\"cron.runs.newestFirst\")}</option>\n <option value=\"asc\">${t(\"cron.runs.oldestFirst\")}</option>\n </select>\n </label>\n </div>\n <div class=\"cron-run-filters__row cron-run-filters__row--secondary\">\n ${renderRunFilterDropdown({\n id: \"status\",\n title: t(\"cron.runs.status\"),\n summary: statusSummary,\n options: runStatusOptions,\n selected: props.runsStatuses,\n onToggle: (value, checked) => {\n const next = toggleSelection(\n props.runsStatuses,\n value as CronRunsStatusValue,\n checked,\n );\n void props.onRunsFiltersChange({ cronRunsStatuses: next });\n },\n onClear: () => {\n void props.onRunsFiltersChange({ cronRunsStatuses: [] });\n },\n })}\n ${renderRunFilterDropdown({\n id: \"delivery\",\n title: t(\"cron.runs.delivery\"),\n summary: deliverySummary,\n options: runDeliveryOptions,\n selected: props.runsDeliveryStatuses,\n onToggle: (value, checked) => {\n const next = toggleSelection(\n props.runsDeliveryStatuses,\n value as CronDeliveryStatus,\n checked,\n );\n void props.onRunsFiltersChange({ cronRunsDeliveryStatuses: next });\n },\n onClear: () => {\n void props.onRunsFiltersChange({ cronRunsDeliveryStatuses: [] });\n },\n })}\n </div>\n </div>\n ${\n props.runsScope === \"job\" && props.runsJobId == null\n ? html`\n <div class=\"muted\" style=\"margin-top: 12px\">${t(\"cron.runs.selectJobHint\")}</div>\n `\n : runs.length === 0\n ? html`\n <div class=\"muted\" style=\"margin-top: 12px\">${t(\"cron.runs.noMatching\")}</div>\n `\n : html`\n <div class=\"list\" style=\"margin-top: 12px;\">\n ${runs.map((entry) => renderRun(entry, props.basePath))}\n </div>\n `\n }\n ${\n (props.runsScope === \"all\" || props.runsJobId != null) && props.runsHasMore\n ? html`\n <div class=\"row\" style=\"margin-top: 12px\">\n <button\n class=\"btn\"\n ?disabled=${props.runsLoadingMore}\n @click=${props.onLoadMoreRuns}\n >\n ${props.runsLoadingMore ? t(\"cron.jobs.loading\") : t(\"cron.runs.loadMore\")}\n </button>\n </div>\n `\n : nothing\n }\n </section>\n </div>\n\n <section class=\"card cron-workspace-form\">\n <div class=\"card-title\">${isEditing ? t(\"cron.form.editJob\") : t(\"cron.form.newJob\")}</div>\n <div class=\"card-sub\">\n ${isEditing ? t(\"cron.form.updateSubtitle\") : t(\"cron.form.createSubtitle\")}\n </div>\n <div class=\"cron-form\">\n <div class=\"cron-required-legend\">\n <span class=\"cron-required-marker\" aria-hidden=\"true\">*</span> ${t(\"cron.form.required\")}\n </div>\n <section class=\"cron-form-section\">\n <div class=\"cron-form-section__title\">${t(\"cron.form.basics\")}</div>\n <div class=\"cron-form-section__sub\">${t(\"cron.form.basicsSub\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.fieldName\"), true)}\n <input\n id=\"cron-name\"\n .value=${props.form.name}\n placeholder=${t(\"cron.form.namePlaceholder\")}\n aria-invalid=${props.fieldErrors.name ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.name ? errorIdForField(\"name\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({ name: (e.target as HTMLInputElement).value })}\n />\n ${renderFieldError(props.fieldErrors.name, errorIdForField(\"name\"))}\n </label>\n <label class=\"field\">\n <span>${t(\"cron.form.description\")}</span>\n <input\n .value=${props.form.description}\n placeholder=${t(\"cron.form.descriptionPlaceholder\")}\n @input=${(e: Event) =>\n props.onFormChange({ description: (e.target as HTMLInputElement).value })}\n />\n </label>\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.agentId\"))}\n <input\n id=\"cron-agent-id\"\n .value=${props.form.agentId}\n list=\"cron-agent-suggestions\"\n ?disabled=${props.form.clearAgent}\n @input=${(e: Event) =>\n props.onFormChange({ agentId: (e.target as HTMLInputElement).value })}\n placeholder=${t(\"cron.form.agentPlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.agentHelp\")}</div>\n </label>\n <label class=\"field checkbox cron-checkbox cron-checkbox-inline\">\n <input\n type=\"checkbox\"\n .checked=${props.form.enabled}\n @change=${(e: Event) =>\n props.onFormChange({ enabled: (e.target as HTMLInputElement).checked })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.summary.enabled\")}</span>\n </label>\n </div>\n </section>\n\n <section class=\"cron-form-section\">\n <div class=\"cron-form-section__title\">${t(\"cron.form.schedule\")}</div>\n <div class=\"cron-form-section__sub\">${t(\"cron.form.scheduleSub\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(t(\"cron.form.schedule\"))}\n <select\n id=\"cron-schedule-kind\"\n .value=${props.form.scheduleKind}\n @change=${(e: Event) =>\n props.onFormChange({\n scheduleKind: (e.target as HTMLSelectElement)\n .value as CronFormState[\"scheduleKind\"],\n })}\n >\n <option value=\"every\">${t(\"cron.form.every\")}</option>\n <option value=\"at\">${t(\"cron.form.at\")}</option>\n <option value=\"cron\">${t(\"cron.form.cronOption\")}</option>\n </select>\n </label>\n </div>\n ${renderScheduleFields(props)}\n </section>\n\n <section class=\"cron-form-section\">\n <div class=\"cron-form-section__title\">${t(\"cron.form.execution\")}</div>\n <div class=\"cron-form-section__sub\">${t(\"cron.form.executionSub\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.session\"))}\n <select\n id=\"cron-session-target\"\n .value=${props.form.sessionTarget}\n @change=${(e: Event) =>\n props.onFormChange({\n sessionTarget: (e.target as HTMLSelectElement)\n .value as CronFormState[\"sessionTarget\"],\n })}\n >\n <option value=\"main\">${t(\"cron.form.main\")}</option>\n <option value=\"isolated\">${t(\"cron.form.isolated\")}</option>\n </select>\n <div class=\"cron-help\">${t(\"cron.form.sessionHelp\")}</div>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.wakeMode\"))}\n <select\n id=\"cron-wake-mode\"\n .value=${props.form.wakeMode}\n @change=${(e: Event) =>\n props.onFormChange({\n wakeMode: (e.target as HTMLSelectElement).value as CronFormState[\"wakeMode\"],\n })}\n >\n <option value=\"now\">${t(\"cron.form.now\")}</option>\n <option value=\"next-heartbeat\">${t(\"cron.form.nextHeartbeat\")}</option>\n </select>\n <div class=\"cron-help\">${t(\"cron.form.wakeModeHelp\")}</div>\n </label>\n <label class=\"field ${isAgentTurn ? \"\" : \"cron-span-2\"}\">\n ${renderFieldLabel(t(\"cron.form.payloadKind\"))}\n <select\n id=\"cron-payload-kind\"\n .value=${props.form.payloadKind}\n @change=${(e: Event) =>\n props.onFormChange({\n payloadKind: (e.target as HTMLSelectElement)\n .value as CronFormState[\"payloadKind\"],\n })}\n >\n <option value=\"systemEvent\">${t(\"cron.form.systemEvent\")}</option>\n <option value=\"agentTurn\">${t(\"cron.form.agentTurn\")}</option>\n </select>\n <div class=\"cron-help\">\n ${\n props.form.payloadKind === \"systemEvent\"\n ? t(\"cron.form.systemEventHelp\")\n : t(\"cron.form.agentTurnHelp\")\n }\n </div>\n </label>\n ${\n isAgentTurn\n ? html`\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.timeoutSeconds\"))}\n <input\n id=\"cron-timeout-seconds\"\n .value=${props.form.timeoutSeconds}\n placeholder=${t(\"cron.form.timeoutPlaceholder\")}\n aria-invalid=${props.fieldErrors.timeoutSeconds ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.timeoutSeconds\n ? errorIdForField(\"timeoutSeconds\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n timeoutSeconds: (e.target as HTMLInputElement).value,\n })}\n />\n <div class=\"cron-help\">${t(\"cron.form.timeoutHelp\")}</div>\n ${renderFieldError(\n props.fieldErrors.timeoutSeconds,\n errorIdForField(\"timeoutSeconds\"),\n )}\n </label>\n `\n : nothing\n }\n </div>\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(\n props.form.payloadKind === \"systemEvent\"\n ? t(\"cron.form.mainTimelineMessage\")\n : t(\"cron.form.assistantTaskPrompt\"),\n true,\n )}\n <textarea\n id=\"cron-payload-text\"\n .value=${props.form.payloadText}\n aria-invalid=${props.fieldErrors.payloadText ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.payloadText ? errorIdForField(\"payloadText\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n payloadText: (e.target as HTMLTextAreaElement).value,\n })}\n rows=\"4\"\n ></textarea>\n ${renderFieldError(props.fieldErrors.payloadText, errorIdForField(\"payloadText\"))}\n </label>\n </section>\n\n <section class=\"cron-form-section\">\n <div class=\"cron-form-section__title\">${t(\"cron.form.deliverySection\")}</div>\n <div class=\"cron-form-section__sub\">${t(\"cron.form.deliverySub\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field ${selectedDeliveryMode === \"none\" ? \"cron-span-2\" : \"\"}\">\n ${renderFieldLabel(t(\"cron.form.resultDelivery\"))}\n <select\n id=\"cron-delivery-mode\"\n .value=${selectedDeliveryMode}\n @change=${(e: Event) =>\n props.onFormChange({\n deliveryMode: (e.target as HTMLSelectElement)\n .value as CronFormState[\"deliveryMode\"],\n })}\n >\n ${\n supportsAnnounce\n ? html`\n <option value=\"announce\">${t(\"cron.form.announceDefault\")}</option>\n `\n : nothing\n }\n <option value=\"webhook\">${t(\"cron.form.webhookPost\")}</option>\n <option value=\"none\">${t(\"cron.form.noneInternal\")}</option>\n </select>\n <div class=\"cron-help\">${t(\"cron.form.deliveryHelp\")}</div>\n </label>\n ${\n selectedDeliveryMode !== \"none\"\n ? html`\n <label class=\"field ${selectedDeliveryMode === \"webhook\" ? \"cron-span-2\" : \"\"}\">\n ${renderFieldLabel(\n selectedDeliveryMode === \"webhook\"\n ? t(\"cron.form.webhookUrl\")\n : t(\"cron.form.channel\"),\n selectedDeliveryMode === \"webhook\",\n )}\n ${\n selectedDeliveryMode === \"webhook\"\n ? html`\n <input\n id=\"cron-delivery-to\"\n .value=${props.form.deliveryTo}\n list=\"cron-delivery-to-suggestions\"\n aria-invalid=${props.fieldErrors.deliveryTo ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.deliveryTo\n ? errorIdForField(\"deliveryTo\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n deliveryTo: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.webhookPlaceholder\")}\n />\n `\n : html`\n <select\n id=\"cron-delivery-channel\"\n .value=${props.form.deliveryChannel || \"last\"}\n @change=${(e: Event) =>\n props.onFormChange({\n deliveryChannel: (e.target as HTMLSelectElement).value,\n })}\n >\n ${channelOptions.map(\n (channel) =>\n html`<option value=${channel}>\n ${resolveChannelLabel(props, channel)}\n </option>`,\n )}\n </select>\n `\n }\n ${\n selectedDeliveryMode === \"announce\"\n ? html`\n <div class=\"cron-help\">${t(\"cron.form.channelHelp\")}</div>\n `\n : html`\n <div class=\"cron-help\">${t(\"cron.form.webhookHelp\")}</div>\n `\n }\n </label>\n ${\n selectedDeliveryMode === \"announce\"\n ? html`\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(t(\"cron.form.to\"))}\n <input\n id=\"cron-delivery-to\"\n .value=${props.form.deliveryTo}\n list=\"cron-delivery-to-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({\n deliveryTo: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.toPlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.toHelp\")}</div>\n </label>\n `\n : nothing\n }\n ${\n selectedDeliveryMode === \"webhook\"\n ? renderFieldError(\n props.fieldErrors.deliveryTo,\n errorIdForField(\"deliveryTo\"),\n )\n : nothing\n }\n `\n : nothing\n }\n </div>\n </section>\n\n <details class=\"cron-advanced\">\n <summary class=\"cron-advanced__summary\">${t(\"cron.form.advanced\")}</summary>\n <div class=\"cron-help\">${t(\"cron.form.advancedHelp\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field checkbox cron-checkbox\">\n <input\n type=\"checkbox\"\n .checked=${props.form.deleteAfterRun}\n @change=${(e: Event) =>\n props.onFormChange({\n deleteAfterRun: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.form.deleteAfterRun\")}</span>\n <div class=\"cron-help\">${t(\"cron.form.deleteAfterRunHelp\")}</div>\n </label>\n <label class=\"field checkbox cron-checkbox\">\n <input\n type=\"checkbox\"\n .checked=${props.form.clearAgent}\n @change=${(e: Event) =>\n props.onFormChange({\n clearAgent: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.form.clearAgentOverride\")}</span>\n <div class=\"cron-help\">${t(\"cron.form.clearAgentHelp\")}</div>\n </label>\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(\"Session key\")}\n <input\n id=\"cron-session-key\"\n .value=${props.form.sessionKey}\n @input=${(e: Event) =>\n props.onFormChange({\n sessionKey: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"agent:main:main\"\n />\n <div class=\"cron-help\">\n Optional routing key for job delivery and wake routing.\n </div>\n </label>\n ${\n isCronSchedule\n ? html`\n <label class=\"field checkbox cron-checkbox cron-span-2\">\n <input\n type=\"checkbox\"\n .checked=${props.form.scheduleExact}\n @change=${(e: Event) =>\n props.onFormChange({\n scheduleExact: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.form.exactTiming\")}</span>\n <div class=\"cron-help\">${t(\"cron.form.exactTimingHelp\")}</div>\n </label>\n <div class=\"cron-stagger-group cron-span-2\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.staggerWindow\"))}\n <input\n id=\"cron-stagger-amount\"\n .value=${props.form.staggerAmount}\n ?disabled=${props.form.scheduleExact}\n aria-invalid=${props.fieldErrors.staggerAmount ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.staggerAmount\n ? errorIdForField(\"staggerAmount\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n staggerAmount: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.staggerPlaceholder\")}\n />\n ${renderFieldError(\n props.fieldErrors.staggerAmount,\n errorIdForField(\"staggerAmount\"),\n )}\n </label>\n <label class=\"field\">\n <span>${t(\"cron.form.staggerUnit\")}</span>\n <select\n .value=${props.form.staggerUnit}\n ?disabled=${props.form.scheduleExact}\n @change=${(e: Event) =>\n props.onFormChange({\n staggerUnit: (e.target as HTMLSelectElement)\n .value as CronFormState[\"staggerUnit\"],\n })}\n >\n <option value=\"seconds\">${t(\"cron.form.seconds\")}</option>\n <option value=\"minutes\">${t(\"cron.form.minutes\")}</option>\n </select>\n </label>\n </div>\n `\n : nothing\n }\n ${\n isAgentTurn\n ? html`\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(\"Account ID\")}\n <input\n id=\"cron-delivery-account-id\"\n .value=${props.form.deliveryAccountId}\n list=\"cron-delivery-account-suggestions\"\n ?disabled=${selectedDeliveryMode !== \"announce\"}\n @input=${(e: Event) =>\n props.onFormChange({\n deliveryAccountId: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"default\"\n />\n <div class=\"cron-help\">\n Optional channel account ID for multi-account setups.\n </div>\n </label>\n <label class=\"field checkbox cron-checkbox cron-span-2\">\n <input\n type=\"checkbox\"\n .checked=${props.form.payloadLightContext}\n @change=${(e: Event) =>\n props.onFormChange({\n payloadLightContext: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">Light context</span>\n <div class=\"cron-help\">\n Use lightweight bootstrap context for this agent job.\n </div>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.model\"))}\n <input\n id=\"cron-payload-model\"\n .value=${props.form.payloadModel}\n list=\"cron-model-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({\n payloadModel: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.modelPlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.modelHelp\")}</div>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.thinking\"))}\n <input\n id=\"cron-payload-thinking\"\n .value=${props.form.payloadThinking}\n list=\"cron-thinking-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({\n payloadThinking: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.thinkingPlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.thinkingHelp\")}</div>\n </label>\n `\n : nothing\n }\n ${\n isAgentTurn\n ? html`\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(\"Failure alerts\")}\n <select\n .value=${props.form.failureAlertMode}\n @change=${(e: Event) =>\n props.onFormChange({\n failureAlertMode: (e.target as HTMLSelectElement)\n .value as CronFormState[\"failureAlertMode\"],\n })}\n >\n <option value=\"inherit\">Inherit global setting</option>\n <option value=\"disabled\">Disable for this job</option>\n <option value=\"custom\">Custom per-job settings</option>\n </select>\n <div class=\"cron-help\">\n Control when this job sends repeated-failure alerts.\n </div>\n </label>\n ${\n props.form.failureAlertMode === \"custom\"\n ? html`\n <label class=\"field\">\n ${renderFieldLabel(\"Alert after\")}\n <input\n id=\"cron-failure-alert-after\"\n .value=${props.form.failureAlertAfter}\n aria-invalid=${props.fieldErrors.failureAlertAfter ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.failureAlertAfter\n ? errorIdForField(\"failureAlertAfter\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n failureAlertAfter: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"2\"\n />\n <div class=\"cron-help\">Consecutive errors before alerting.</div>\n ${renderFieldError(\n props.fieldErrors.failureAlertAfter,\n errorIdForField(\"failureAlertAfter\"),\n )}\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Cooldown (seconds)\")}\n <input\n id=\"cron-failure-alert-cooldown-seconds\"\n .value=${props.form.failureAlertCooldownSeconds}\n aria-invalid=${props.fieldErrors.failureAlertCooldownSeconds ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.failureAlertCooldownSeconds\n ? errorIdForField(\"failureAlertCooldownSeconds\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n failureAlertCooldownSeconds: (e.target as HTMLInputElement)\n .value,\n })}\n placeholder=\"3600\"\n />\n <div class=\"cron-help\">Minimum seconds between alerts.</div>\n ${renderFieldError(\n props.fieldErrors.failureAlertCooldownSeconds,\n errorIdForField(\"failureAlertCooldownSeconds\"),\n )}\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Alert channel\")}\n <select\n .value=${props.form.failureAlertChannel || \"last\"}\n @change=${(e: Event) =>\n props.onFormChange({\n failureAlertChannel: (e.target as HTMLSelectElement).value,\n })}\n >\n ${channelOptions.map(\n (channel) =>\n html`<option value=${channel}>\n ${resolveChannelLabel(props, channel)}\n </option>`,\n )}\n </select>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Alert to\")}\n <input\n .value=${props.form.failureAlertTo}\n list=\"cron-delivery-to-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({\n failureAlertTo: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"+1555... or chat id\"\n />\n <div class=\"cron-help\">\n Optional recipient override for failure alerts.\n </div>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Alert mode\")}\n <select\n .value=${props.form.failureAlertDeliveryMode || \"announce\"}\n @change=${(e: Event) =>\n props.onFormChange({\n failureAlertDeliveryMode: (e.target as HTMLSelectElement)\n .value as CronFormState[\"failureAlertDeliveryMode\"],\n })}\n >\n <option value=\"announce\">Announce (via channel)</option>\n <option value=\"webhook\">Webhook (HTTP POST)</option>\n </select>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Alert account ID\")}\n <input\n .value=${props.form.failureAlertAccountId}\n @input=${(e: Event) =>\n props.onFormChange({\n failureAlertAccountId: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"Account ID for multi-account setups\"\n />\n </label>\n `\n : nothing\n }\n `\n : nothing\n }\n ${\n selectedDeliveryMode !== \"none\"\n ? html`\n <label class=\"field checkbox cron-checkbox cron-span-2\">\n <input\n type=\"checkbox\"\n .checked=${props.form.deliveryBestEffort}\n @change=${(e: Event) =>\n props.onFormChange({\n deliveryBestEffort: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.form.bestEffortDelivery\")}</span>\n <div class=\"cron-help\">${t(\"cron.form.bestEffortHelp\")}</div>\n </label>\n `\n : nothing\n }\n </div>\n </details>\n </div>\n ${\n blockedByValidation\n ? html`\n <div class=\"cron-form-status\" role=\"status\" aria-live=\"polite\">\n <div class=\"cron-form-status__title\">${t(\"cron.form.cantAddYet\")}</div>\n <div class=\"cron-help\">${t(\"cron.form.fillRequired\")}</div>\n <ul class=\"cron-form-status__list\">\n ${blockingFields.map(\n (field) => html`\n <li>\n <button\n type=\"button\"\n class=\"cron-form-status__link\"\n @click=${() => focusFormField(field.inputId)}\n >\n ${field.label}: ${t(field.message)}\n </button>\n </li>\n `,\n )}\n </ul>\n </div>\n `\n : nothing\n }\n <div class=\"row cron-form-actions\">\n <button class=\"btn primary\" ?disabled=${props.busy || !props.canSubmit} @click=${props.onAdd}>\n ${props.busy ? t(\"cron.form.saving\") : isEditing ? t(\"cron.form.saveChanges\") : t(\"cron.form.addJob\")}\n </button>\n ${\n submitDisabledReason\n ? html`<div class=\"cron-submit-reason\" aria-live=\"polite\">${submitDisabledReason}</div>`\n : nothing\n }\n ${\n isEditing\n ? html`\n <button class=\"btn\" ?disabled=${props.busy} @click=${props.onCancelEdit}>\n ${t(\"cron.form.cancel\")}\n </button>\n `\n : nothing\n }\n </div>\n </section>\n </section>\n\n ${renderSuggestionList(\"cron-agent-suggestions\", props.agentSuggestions)}\n ${renderSuggestionList(\"cron-model-suggestions\", props.modelSuggestions)}\n ${renderSuggestionList(\"cron-thinking-suggestions\", props.thinkingSuggestions)}\n ${renderSuggestionList(\"cron-tz-suggestions\", props.timezoneSuggestions)}\n ${renderSuggestionList(\"cron-delivery-to-suggestions\", props.deliveryToSuggestions)}\n ${renderSuggestionList(\"cron-delivery-account-suggestions\", props.accountSuggestions)}\n `;\n}\n\nfunction renderScheduleFields(props: CronProps) {\n const form = props.form;\n if (form.scheduleKind === \"at\") {\n return html`\n <label class=\"field cron-span-2\" style=\"margin-top: 12px;\">\n ${renderFieldLabel(t(\"cron.form.runAt\"), true)}\n <input\n id=\"cron-schedule-at\"\n type=\"datetime-local\"\n .value=${form.scheduleAt}\n aria-invalid=${props.fieldErrors.scheduleAt ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.scheduleAt ? errorIdForField(\"scheduleAt\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n scheduleAt: (e.target as HTMLInputElement).value,\n })}\n />\n ${renderFieldError(props.fieldErrors.scheduleAt, errorIdForField(\"scheduleAt\"))}\n </label>\n `;\n }\n if (form.scheduleKind === \"every\") {\n return html`\n <div class=\"form-grid cron-form-grid\" style=\"margin-top: 12px;\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.every\"), true)}\n <input\n id=\"cron-every-amount\"\n .value=${form.everyAmount}\n aria-invalid=${props.fieldErrors.everyAmount ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.everyAmount ? errorIdForField(\"everyAmount\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n everyAmount: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.everyAmountPlaceholder\")}\n />\n ${renderFieldError(props.fieldErrors.everyAmount, errorIdForField(\"everyAmount\"))}\n </label>\n <label class=\"field\">\n <span>${t(\"cron.form.unit\")}</span>\n <select\n .value=${form.everyUnit}\n @change=${(e: Event) =>\n props.onFormChange({\n everyUnit: (e.target as HTMLSelectElement).value as CronFormState[\"everyUnit\"],\n })}\n >\n <option value=\"minutes\">${t(\"cron.form.minutes\")}</option>\n <option value=\"hours\">${t(\"cron.form.hours\")}</option>\n <option value=\"days\">${t(\"cron.form.days\")}</option>\n </select>\n </label>\n </div>\n `;\n }\n return html`\n <div class=\"form-grid cron-form-grid\" style=\"margin-top: 12px;\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.expression\"), true)}\n <input\n id=\"cron-cron-expr\"\n .value=${form.cronExpr}\n aria-invalid=${props.fieldErrors.cronExpr ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.cronExpr ? errorIdForField(\"cronExpr\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({ cronExpr: (e.target as HTMLInputElement).value })}\n placeholder=${t(\"cron.form.expressionPlaceholder\")}\n />\n ${renderFieldError(props.fieldErrors.cronExpr, errorIdForField(\"cronExpr\"))}\n </label>\n <label class=\"field\">\n <span>${t(\"cron.form.timezoneOptional\")}</span>\n <input\n .value=${form.cronTz}\n list=\"cron-tz-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({ cronTz: (e.target as HTMLInputElement).value })}\n placeholder=${t(\"cron.form.timezonePlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.timezoneHelp\")}</div>\n </label>\n <div class=\"cron-help cron-span-2\">${t(\"cron.form.jitterHelp\")}</div>\n </div>\n `;\n}\n\nfunction renderFieldError(message?: string, id?: string) {\n if (!message) {\n return nothing;\n }\n return html`<div id=${ifDefined(id)} class=\"cron-help cron-error\">${t(message)}</div>`;\n}\n\nfunction renderJob(job: CronJob, props: CronProps) {\n const isSelected = props.runsJobId === job.id;\n const itemClass = `list-item list-item-clickable cron-job${isSelected ? \" list-item-selected\" : \"\"}`;\n const selectAnd = (action: () => void) => {\n props.onLoadRuns(job.id);\n action();\n };\n return html`\n <div class=${itemClass} @click=${() => props.onLoadRuns(job.id)}>\n <div class=\"list-main\">\n <div class=\"list-title\">${job.name}</div>\n <div class=\"list-sub\">${formatCronSchedule(job)}</div>\n ${renderJobPayload(job)}\n ${job.agentId ? html`<div class=\"muted cron-job-agent\">${t(\"cron.jobDetail.agent\")}: ${job.agentId}</div>` : nothing}\n </div>\n <div class=\"list-meta\">\n ${renderJobState(job)}\n </div>\n <div class=\"cron-job-footer\">\n <div class=\"chip-row cron-job-chips\">\n <span class=${`chip ${job.enabled ? \"chip-ok\" : \"chip-danger\"}`}>\n ${job.enabled ? t(\"cron.jobList.enabled\") : t(\"cron.jobList.disabled\")}\n </span>\n <span class=\"chip\">${job.sessionTarget}</span>\n <span class=\"chip\">${job.wakeMode}</span>\n </div>\n <div class=\"row cron-job-actions\">\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onEdit(job));\n }}\n >\n ${t(\"cron.jobList.edit\")}\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onClone(job));\n }}\n >\n ${t(\"cron.jobList.clone\")}\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onToggle(job, !job.enabled));\n }}\n >\n ${job.enabled ? t(\"cron.jobList.disable\") : t(\"cron.jobList.enable\")}\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onRun(job, \"force\"));\n }}\n >\n ${t(\"cron.jobList.run\")}\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onRun(job, \"due\"));\n }}\n >\n Run if due\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n props.onLoadRuns(job.id);\n }}\n >\n ${t(\"cron.jobList.history\")}\n </button>\n <button\n class=\"btn danger\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onRemove(job));\n }}\n >\n ${t(\"cron.jobList.remove\")}\n </button>\n </div>\n </div>\n </div>\n `;\n}\n\nfunction renderJobPayload(job: CronJob) {\n if (job.payload.kind === \"systemEvent\") {\n return html`<div class=\"cron-job-detail\">\n <span class=\"cron-job-detail-label\">${t(\"cron.jobDetail.system\")}</span>\n <span class=\"muted cron-job-detail-value\">${job.payload.text}</span>\n </div>`;\n }\n\n const delivery = job.delivery;\n const deliveryTarget =\n delivery?.mode === \"webhook\"\n ? delivery.to\n ? ` (${delivery.to})`\n : \"\"\n : delivery?.channel || delivery?.to\n ? ` (${delivery.channel ?? \"last\"}${delivery.to ? ` -> ${delivery.to}` : \"\"})`\n : \"\";\n\n return html`\n <div class=\"cron-job-detail\">\n <span class=\"cron-job-detail-label\">${t(\"cron.jobDetail.prompt\")}</span>\n <span class=\"muted cron-job-detail-value\">${job.payload.message}</span>\n </div>\n ${\n delivery\n ? html`<div class=\"cron-job-detail\">\n <span class=\"cron-job-detail-label\">${t(\"cron.jobDetail.delivery\")}</span>\n <span class=\"muted cron-job-detail-value\">${delivery.mode}${deliveryTarget}</span>\n </div>`\n : nothing\n }\n `;\n}\n\nfunction formatStateRelative(ms?: number) {\n if (typeof ms !== \"number\" || !Number.isFinite(ms)) {\n return t(\"common.na\");\n }\n return formatRelativeTimestamp(ms);\n}\n\nfunction formatRunNextLabel(nextRunAtMs: number, nowMs = Date.now()) {\n const rel = formatRelativeTimestamp(nextRunAtMs);\n return nextRunAtMs > nowMs ? t(\"cron.runEntry.next\", { rel }) : t(\"cron.runEntry.due\", { rel });\n}\n\nfunction renderJobState(job: CronJob) {\n const rawStatus = job.state?.lastStatus;\n const statusClass =\n rawStatus === \"ok\"\n ? \"cron-job-status-ok\"\n : rawStatus === \"error\"\n ? \"cron-job-status-error\"\n : rawStatus === \"skipped\"\n ? \"cron-job-status-skipped\"\n : \"cron-job-status-na\";\n const statusLabel =\n rawStatus === \"ok\"\n ? t(\"cron.runs.runStatusOk\")\n : rawStatus === \"error\"\n ? t(\"cron.runs.runStatusError\")\n : rawStatus === \"skipped\"\n ? t(\"cron.runs.runStatusSkipped\")\n : t(\"common.na\");\n const nextRunAtMs = job.state?.nextRunAtMs;\n const lastRunAtMs = job.state?.lastRunAtMs;\n\n return html`\n <div class=\"cron-job-state\">\n <div class=\"cron-job-state-row\">\n <span class=\"cron-job-state-key\">${t(\"cron.jobState.status\")}</span>\n <span class=${`cron-job-status-pill ${statusClass}`}>${statusLabel}</span>\n </div>\n <div class=\"cron-job-state-row\">\n <span class=\"cron-job-state-key\">${t(\"cron.jobState.next\")}</span>\n <span class=\"cron-job-state-value\" title=${formatMs(nextRunAtMs)}>\n ${formatStateRelative(nextRunAtMs)}\n </span>\n </div>\n <div class=\"cron-job-state-row\">\n <span class=\"cron-job-state-key\">${t(\"cron.jobState.last\")}</span>\n <span class=\"cron-job-state-value\" title=${formatMs(lastRunAtMs)}>\n ${formatStateRelative(lastRunAtMs)}\n </span>\n </div>\n </div>\n `;\n}\n\nfunction runStatusLabel(value: string): string {\n switch (value) {\n case \"ok\":\n return t(\"cron.runs.runStatusOk\");\n case \"error\":\n return t(\"cron.runs.runStatusError\");\n case \"skipped\":\n return t(\"cron.runs.runStatusSkipped\");\n default:\n return t(\"cron.runs.runStatusUnknown\");\n }\n}\n\nfunction runDeliveryLabel(value: string): string {\n switch (value) {\n case \"delivered\":\n return t(\"cron.runs.deliveryDelivered\");\n case \"not-delivered\":\n return t(\"cron.runs.deliveryNotDelivered\");\n case \"not-requested\":\n return t(\"cron.runs.deliveryNotRequested\");\n case \"unknown\":\n return t(\"cron.runs.deliveryUnknown\");\n default:\n return t(\"cron.runs.deliveryUnknown\");\n }\n}\n\nfunction renderRun(entry: CronRunLogEntry, basePath: string) {\n const chatUrl =\n typeof entry.sessionKey === \"string\" && entry.sessionKey.trim().length > 0\n ? `${pathForTab(\"chat\", basePath)}?session=${encodeURIComponent(entry.sessionKey)}`\n : null;\n const status = runStatusLabel(entry.status ?? \"unknown\");\n const delivery = runDeliveryLabel(entry.deliveryStatus ?? \"not-requested\");\n const usage = entry.usage;\n const usageSummary =\n usage && typeof usage.total_tokens === \"number\"\n ? `${usage.total_tokens} tokens`\n : usage && typeof usage.input_tokens === \"number\" && typeof usage.output_tokens === \"number\"\n ? `${usage.input_tokens} in / ${usage.output_tokens} out`\n : null;\n return html`\n <div class=\"list-item cron-run-entry\">\n <div class=\"list-main cron-run-entry__main\">\n <div class=\"list-title cron-run-entry__title\">\n ${entry.jobName ?? entry.jobId}\n <span class=\"muted\"> · ${status}</span>\n </div>\n <div class=\"list-sub cron-run-entry__summary\">${entry.summary ?? entry.error ?? t(\"cron.runEntry.noSummary\")}</div>\n <div class=\"chip-row\" style=\"margin-top: 6px;\">\n <span class=\"chip\">${delivery}</span>\n ${entry.model ? html`<span class=\"chip\">${entry.model}</span>` : nothing}\n ${entry.provider ? html`<span class=\"chip\">${entry.provider}</span>` : nothing}\n ${usageSummary ? html`<span class=\"chip\">${usageSummary}</span>` : nothing}\n </div>\n </div>\n <div class=\"list-meta cron-run-entry__meta\">\n <div>${formatMs(entry.ts)}</div>\n ${typeof entry.runAtMs === \"number\" ? html`<div class=\"muted\">${t(\"cron.runEntry.runAt\")} ${formatMs(entry.runAtMs)}</div>` : nothing}\n <div class=\"muted\">${entry.durationMs ?? 0}ms</div>\n ${\n typeof entry.nextRunAtMs === \"number\"\n ? html`<div class=\"muted\">${formatRunNextLabel(entry.nextRunAtMs)}</div>`\n : nothing\n }\n ${\n chatUrl\n ? html`<div><a class=\"session-link\" href=${chatUrl}>${t(\"cron.runEntry.openRunChat\")}</a></div>`\n : nothing\n }\n ${entry.error ? html`<div class=\"muted\">${entry.error}</div>` : nothing}\n ${entry.deliveryError ? html`<div class=\"muted\">${entry.deliveryError}</div>` : nothing}\n </div>\n </div>\n `;\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
1
+ {"version":3,"file":"cron-B6kPzumc.js","names":["t"],"sources":["../../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directives/if-defined.js","../../../ui/src/ui/views/cron.ts"],"sourcesContent":["import{nothing as t}from\"../lit-html.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o=o=>o??t;export{o as ifDefined};\n//# sourceMappingURL=if-defined.js.map\n","import { html, nothing } from \"lit\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { t } from \"../../i18n/index.ts\";\nimport type {\n CronFieldErrors,\n CronFieldKey,\n CronJobsLastStatusFilter,\n CronJobsScheduleKindFilter,\n} from \"../controllers/cron.ts\";\nimport { formatRelativeTimestamp, formatMs } from \"../format.ts\";\nimport { pathForTab } from \"../navigation.ts\";\nimport { formatCronSchedule, formatNextRun } from \"../presenter.ts\";\nimport type { ChannelUiMetaEntry, CronJob, CronRunLogEntry, CronStatus } from \"../types.ts\";\nimport type {\n CronDeliveryStatus,\n CronJobsEnabledFilter,\n CronRunScope,\n CronRunsStatusValue,\n CronJobsSortBy,\n CronRunsStatusFilter,\n CronSortDir,\n} from \"../types.ts\";\nimport type { CronFormState } from \"../ui-types.ts\";\n\nexport type CronProps = {\n basePath: string;\n loading: boolean;\n jobsLoadingMore: boolean;\n status: CronStatus | null;\n jobs: CronJob[];\n jobsTotal: number;\n jobsHasMore: boolean;\n jobsQuery: string;\n jobsEnabledFilter: CronJobsEnabledFilter;\n jobsScheduleKindFilter: CronJobsScheduleKindFilter;\n jobsLastStatusFilter: CronJobsLastStatusFilter;\n jobsSortBy: CronJobsSortBy;\n jobsSortDir: CronSortDir;\n error: string | null;\n busy: boolean;\n form: CronFormState;\n fieldErrors: CronFieldErrors;\n canSubmit: boolean;\n editingJobId: string | null;\n channels: string[];\n channelLabels?: Record<string, string>;\n channelMeta?: ChannelUiMetaEntry[];\n runsJobId: string | null;\n runs: CronRunLogEntry[];\n runsTotal: number;\n runsHasMore: boolean;\n runsLoadingMore: boolean;\n runsScope: CronRunScope;\n runsStatuses: CronRunsStatusValue[];\n runsDeliveryStatuses: CronDeliveryStatus[];\n runsStatusFilter: CronRunsStatusFilter;\n runsQuery: string;\n runsSortDir: CronSortDir;\n agentSuggestions: string[];\n modelSuggestions: string[];\n thinkingSuggestions: string[];\n timezoneSuggestions: string[];\n deliveryToSuggestions: string[];\n accountSuggestions: string[];\n onFormChange: (patch: Partial<CronFormState>) => void;\n onRefresh: () => void;\n onAdd: () => void;\n onEdit: (job: CronJob) => void;\n onClone: (job: CronJob) => void;\n onCancelEdit: () => void;\n onToggle: (job: CronJob, enabled: boolean) => void;\n onRun: (job: CronJob, mode?: \"force\" | \"due\") => void;\n onRemove: (job: CronJob) => void;\n onLoadRuns: (jobId: string) => void;\n onLoadMoreJobs: () => void;\n onJobsFiltersChange: (patch: {\n cronJobsQuery?: string;\n cronJobsEnabledFilter?: CronJobsEnabledFilter;\n cronJobsScheduleKindFilter?: CronJobsScheduleKindFilter;\n cronJobsLastStatusFilter?: CronJobsLastStatusFilter;\n cronJobsSortBy?: CronJobsSortBy;\n cronJobsSortDir?: CronSortDir;\n }) => void | Promise<void>;\n onJobsFiltersReset: () => void | Promise<void>;\n onLoadMoreRuns: () => void;\n onRunsFiltersChange: (patch: {\n cronRunsScope?: CronRunScope;\n cronRunsStatuses?: CronRunsStatusValue[];\n cronRunsDeliveryStatuses?: CronDeliveryStatus[];\n cronRunsStatusFilter?: CronRunsStatusFilter;\n cronRunsQuery?: string;\n cronRunsSortDir?: CronSortDir;\n }) => void | Promise<void>;\n};\n\nfunction getRunStatusOptions(): Array<{ value: CronRunsStatusValue; label: string }> {\n return [\n { value: \"ok\", label: t(\"cron.runs.runStatusOk\") },\n { value: \"error\", label: t(\"cron.runs.runStatusError\") },\n { value: \"skipped\", label: t(\"cron.runs.runStatusSkipped\") },\n ];\n}\n\nfunction getRunDeliveryOptions(): Array<{ value: CronDeliveryStatus; label: string }> {\n return [\n { value: \"delivered\", label: t(\"cron.runs.deliveryDelivered\") },\n { value: \"not-delivered\", label: t(\"cron.runs.deliveryNotDelivered\") },\n { value: \"unknown\", label: t(\"cron.runs.deliveryUnknown\") },\n { value: \"not-requested\", label: t(\"cron.runs.deliveryNotRequested\") },\n ];\n}\n\nfunction toggleSelection<T extends string>(selected: T[], value: T, checked: boolean): T[] {\n const set = new Set(selected);\n if (checked) {\n set.add(value);\n } else {\n set.delete(value);\n }\n return Array.from(set);\n}\n\nfunction summarizeSelection(selectedLabels: string[], allLabel: string) {\n if (selectedLabels.length === 0) {\n return allLabel;\n }\n if (selectedLabels.length <= 2) {\n return selectedLabels.join(\", \");\n }\n return `${selectedLabels[0]} +${selectedLabels.length - 1}`;\n}\n\nfunction buildChannelOptions(props: CronProps): string[] {\n const options = [\"last\", ...props.channels.filter(Boolean)];\n const current = props.form.deliveryChannel?.trim();\n if (current && !options.includes(current)) {\n options.push(current);\n }\n const seen = new Set<string>();\n return options.filter((value) => {\n if (seen.has(value)) {\n return false;\n }\n seen.add(value);\n return true;\n });\n}\n\nfunction resolveChannelLabel(props: CronProps, channel: string): string {\n if (channel === \"last\") {\n return \"last\";\n }\n const meta = props.channelMeta?.find((entry) => entry.id === channel);\n if (meta?.label) {\n return meta.label;\n }\n return props.channelLabels?.[channel] ?? channel;\n}\n\nfunction renderRunFilterDropdown(params: {\n id: string;\n title: string;\n summary: string;\n options: Array<{ value: string; label: string }>;\n selected: string[];\n onToggle: (value: string, checked: boolean) => void;\n onClear: () => void;\n}) {\n return html`\n <div class=\"field cron-filter-dropdown\" data-filter=${params.id}>\n <span>${params.title}</span>\n <details class=\"cron-filter-dropdown__details\">\n <summary class=\"btn cron-filter-dropdown__trigger\">\n <span>${params.summary}</span>\n </summary>\n <div class=\"cron-filter-dropdown__panel\">\n <div class=\"cron-filter-dropdown__list\">\n ${params.options.map(\n (option) => html`\n <label class=\"cron-filter-dropdown__option\">\n <input\n type=\"checkbox\"\n value=${option.value}\n .checked=${params.selected.includes(option.value)}\n @change=${(event: Event) => {\n const target = event.target as HTMLInputElement;\n params.onToggle(option.value, target.checked);\n }}\n />\n <span>${option.label}</span>\n </label>\n `,\n )}\n </div>\n <div class=\"row\">\n <button class=\"btn\" type=\"button\" @click=${params.onClear}>${t(\"cron.runs.clear\")}</button>\n </div>\n </div>\n </details>\n </div>\n `;\n}\n\nfunction renderSuggestionList(id: string, options: string[]) {\n const clean = Array.from(new Set(options.map((option) => option.trim()).filter(Boolean)));\n if (clean.length === 0) {\n return nothing;\n }\n return html`<datalist id=${id}>\n ${clean.map((value) => html`<option value=${value}></option> `)}\n </datalist>`;\n}\n\ntype BlockingField = {\n key: CronFieldKey;\n label: string;\n message: string;\n inputId: string;\n};\n\nfunction errorIdForField(key: CronFieldKey) {\n return `cron-error-${key}`;\n}\n\nfunction inputIdForField(key: CronFieldKey) {\n if (key === \"name\") {\n return \"cron-name\";\n }\n if (key === \"scheduleAt\") {\n return \"cron-schedule-at\";\n }\n if (key === \"everyAmount\") {\n return \"cron-every-amount\";\n }\n if (key === \"cronExpr\") {\n return \"cron-cron-expr\";\n }\n if (key === \"staggerAmount\") {\n return \"cron-stagger-amount\";\n }\n if (key === \"payloadText\") {\n return \"cron-payload-text\";\n }\n if (key === \"payloadModel\") {\n return \"cron-payload-model\";\n }\n if (key === \"payloadThinking\") {\n return \"cron-payload-thinking\";\n }\n if (key === \"timeoutSeconds\") {\n return \"cron-timeout-seconds\";\n }\n if (key === \"failureAlertAfter\") {\n return \"cron-failure-alert-after\";\n }\n if (key === \"failureAlertCooldownSeconds\") {\n return \"cron-failure-alert-cooldown-seconds\";\n }\n return \"cron-delivery-to\";\n}\n\nfunction fieldLabelForKey(\n key: CronFieldKey,\n form: CronFormState,\n deliveryMode: CronFormState[\"deliveryMode\"],\n) {\n if (key === \"payloadText\") {\n return form.payloadKind === \"systemEvent\"\n ? t(\"cron.form.mainTimelineMessage\")\n : t(\"cron.form.assistantTaskPrompt\");\n }\n if (key === \"deliveryTo\") {\n return deliveryMode === \"webhook\" ? t(\"cron.form.webhookUrl\") : t(\"cron.form.to\");\n }\n const labels: Record<CronFieldKey, string> = {\n name: t(\"cron.form.fieldName\"),\n scheduleAt: t(\"cron.form.runAt\"),\n everyAmount: t(\"cron.form.every\"),\n cronExpr: t(\"cron.form.expression\"),\n staggerAmount: t(\"cron.form.staggerWindow\"),\n payloadText: t(\"cron.form.assistantTaskPrompt\"),\n payloadModel: t(\"cron.form.model\"),\n payloadThinking: t(\"cron.form.thinking\"),\n timeoutSeconds: t(\"cron.form.timeoutSeconds\"),\n deliveryTo: t(\"cron.form.to\"),\n failureAlertAfter: \"Failure alert after\",\n failureAlertCooldownSeconds: \"Failure alert cooldown\",\n };\n return labels[key];\n}\n\nfunction collectBlockingFields(\n errors: CronFieldErrors,\n form: CronFormState,\n deliveryMode: CronFormState[\"deliveryMode\"],\n): BlockingField[] {\n const orderedKeys: CronFieldKey[] = [\n \"name\",\n \"scheduleAt\",\n \"everyAmount\",\n \"cronExpr\",\n \"staggerAmount\",\n \"payloadText\",\n \"payloadModel\",\n \"payloadThinking\",\n \"timeoutSeconds\",\n \"deliveryTo\",\n \"failureAlertAfter\",\n \"failureAlertCooldownSeconds\",\n ];\n const fields: BlockingField[] = [];\n for (const key of orderedKeys) {\n const message = errors[key];\n if (!message) {\n continue;\n }\n fields.push({\n key,\n label: fieldLabelForKey(key, form, deliveryMode),\n message,\n inputId: inputIdForField(key),\n });\n }\n return fields;\n}\n\nfunction focusFormField(id: string) {\n const el = document.getElementById(id);\n if (!(el instanceof HTMLElement)) {\n return;\n }\n if (typeof el.scrollIntoView === \"function\") {\n el.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n }\n el.focus();\n}\n\nfunction renderFieldLabel(text: string, required = false) {\n return html`<span>\n ${text}\n ${\n required\n ? html`\n <span class=\"cron-required-marker\" aria-hidden=\"true\">*</span>\n <span class=\"cron-required-sr\">${t(\"cron.form.requiredSr\")}</span>\n `\n : nothing\n }\n </span>`;\n}\n\nexport function renderCron(props: CronProps) {\n const isEditing = Boolean(props.editingJobId);\n const isAgentTurn = props.form.payloadKind === \"agentTurn\";\n const isCronSchedule = props.form.scheduleKind === \"cron\";\n const channelOptions = buildChannelOptions(props);\n const selectedJob =\n props.runsJobId == null ? undefined : props.jobs.find((job) => job.id === props.runsJobId);\n const selectedRunTitle =\n props.runsScope === \"all\"\n ? t(\"cron.jobList.allJobs\")\n : (selectedJob?.name ?? props.runsJobId ?? t(\"cron.jobList.selectJob\"));\n const runs = props.runs.toSorted((a, b) =>\n props.runsSortDir === \"asc\" ? a.ts - b.ts : b.ts - a.ts,\n );\n const runStatusOptions = getRunStatusOptions();\n const runDeliveryOptions = getRunDeliveryOptions();\n const selectedStatusLabels = runStatusOptions\n .filter((option) => props.runsStatuses.includes(option.value))\n .map((option) => option.label);\n const selectedDeliveryLabels = runDeliveryOptions\n .filter((option) => props.runsDeliveryStatuses.includes(option.value))\n .map((option) => option.label);\n const statusSummary = summarizeSelection(selectedStatusLabels, t(\"cron.runs.allStatuses\"));\n const deliverySummary = summarizeSelection(selectedDeliveryLabels, t(\"cron.runs.allDelivery\"));\n const supportsAnnounce =\n props.form.sessionTarget !== \"main\" && props.form.payloadKind === \"agentTurn\";\n const selectedDeliveryMode =\n props.form.deliveryMode === \"announce\" && !supportsAnnounce ? \"none\" : props.form.deliveryMode;\n const blockingFields = collectBlockingFields(props.fieldErrors, props.form, selectedDeliveryMode);\n const blockedByValidation = !props.busy && blockingFields.length > 0;\n const hasActiveJobsFilters =\n props.jobsQuery.trim().length > 0 ||\n props.jobsEnabledFilter !== \"all\" ||\n props.jobsScheduleKindFilter !== \"all\" ||\n props.jobsLastStatusFilter !== \"all\" ||\n props.jobsSortBy !== \"nextRunAtMs\" ||\n props.jobsSortDir !== \"asc\";\n const submitDisabledReason =\n blockedByValidation && !props.canSubmit\n ? blockingFields.length === 1\n ? t(\"cron.form.fixFields\", { count: String(blockingFields.length) })\n : t(\"cron.form.fixFieldsPlural\", { count: String(blockingFields.length) })\n : \"\";\n return html`\n <section class=\"card cron-summary-strip\">\n <div class=\"cron-summary-strip__left\">\n <div class=\"cron-summary-item\">\n <div class=\"cron-summary-label\">${t(\"cron.summary.enabled\")}</div>\n <div class=\"cron-summary-value\">\n <span class=${`chip ${props.status?.enabled ? \"chip-ok\" : \"chip-danger\"}`}>\n ${\n props.status\n ? props.status.enabled\n ? t(\"cron.summary.yes\")\n : t(\"cron.summary.no\")\n : t(\"common.na\")\n }\n </span>\n </div>\n </div>\n <div class=\"cron-summary-item\">\n <div class=\"cron-summary-label\">${t(\"cron.summary.jobs\")}</div>\n <div class=\"cron-summary-value\">${props.status?.jobs ?? t(\"common.na\")}</div>\n </div>\n <div class=\"cron-summary-item cron-summary-item--wide\">\n <div class=\"cron-summary-label\">${t(\"cron.summary.nextWake\")}</div>\n <div class=\"cron-summary-value\">${formatNextRun(props.status?.nextWakeAtMs ?? null)}</div>\n </div>\n </div>\n <div class=\"cron-summary-strip__actions\">\n <button class=\"btn\" ?disabled=${props.loading} @click=${props.onRefresh}>\n ${props.loading ? t(\"cron.summary.refreshing\") : t(\"cron.summary.refresh\")}\n </button>\n ${props.error ? html`<span class=\"muted\">${props.error}</span>` : nothing}\n </div>\n </section>\n\n <section class=\"cron-workspace\">\n <div class=\"cron-workspace-main\">\n <section class=\"card\">\n <div class=\"row\" style=\"justify-content: space-between; align-items: flex-start; gap: 12px;\">\n <div>\n <div class=\"card-title\">${t(\"cron.jobs.title\")}</div>\n <div class=\"card-sub\">${t(\"cron.jobs.subtitle\")}</div>\n </div>\n <div class=\"muted\">${t(\"cron.jobs.shownOf\", {\n shown: String(props.jobs.length),\n total: String(props.jobsTotal),\n })}</div>\n </div>\n <div class=\"filters\" style=\"margin-top: 12px;\">\n <label class=\"field cron-filter-search\">\n <span>${t(\"cron.jobs.searchJobs\")}</span>\n <input\n .value=${props.jobsQuery}\n placeholder=${t(\"cron.jobs.searchPlaceholder\")}\n @input=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsQuery: (e.target as HTMLInputElement).value,\n })}\n />\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.enabled\")}</span>\n <select\n .value=${props.jobsEnabledFilter}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsEnabledFilter: (e.target as HTMLSelectElement)\n .value as CronJobsEnabledFilter,\n })}\n >\n <option value=\"all\">${t(\"cron.jobs.all\")}</option>\n <option value=\"enabled\">${t(\"common.enabled\")}</option>\n <option value=\"disabled\">${t(\"common.disabled\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.schedule\")}</span>\n <select\n data-test-id=\"cron-jobs-schedule-filter\"\n .value=${props.jobsScheduleKindFilter}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsScheduleKindFilter: (e.target as HTMLSelectElement)\n .value as CronJobsScheduleKindFilter,\n })}\n >\n <option value=\"all\">${t(\"cron.jobs.all\")}</option>\n <option value=\"at\">${t(\"cron.form.at\")}</option>\n <option value=\"every\">${t(\"cron.form.every\")}</option>\n <option value=\"cron\">${t(\"cron.form.cronOption\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.lastRun\")}</span>\n <select\n data-test-id=\"cron-jobs-last-status-filter\"\n .value=${props.jobsLastStatusFilter}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsLastStatusFilter: (e.target as HTMLSelectElement)\n .value as CronJobsLastStatusFilter,\n })}\n >\n <option value=\"all\">${t(\"cron.jobs.all\")}</option>\n <option value=\"ok\">${t(\"cron.runs.runStatusOk\")}</option>\n <option value=\"error\">${t(\"cron.runs.runStatusError\")}</option>\n <option value=\"skipped\">${t(\"cron.runs.runStatusSkipped\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.sort\")}</span>\n <select\n .value=${props.jobsSortBy}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsSortBy: (e.target as HTMLSelectElement).value as CronJobsSortBy,\n })}\n >\n <option value=\"nextRunAtMs\">${t(\"cron.jobs.nextRun\")}</option>\n <option value=\"updatedAtMs\">${t(\"cron.jobs.recentlyUpdated\")}</option>\n <option value=\"name\">${t(\"cron.jobs.name\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.direction\")}</span>\n <select\n .value=${props.jobsSortDir}\n @change=${(e: Event) =>\n props.onJobsFiltersChange({\n cronJobsSortDir: (e.target as HTMLSelectElement).value as CronSortDir,\n })}\n >\n <option value=\"asc\">${t(\"cron.jobs.ascending\")}</option>\n <option value=\"desc\">${t(\"cron.jobs.descending\")}</option>\n </select>\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.reset\")}</span>\n <button\n class=\"btn\"\n data-test-id=\"cron-jobs-filters-reset\"\n ?disabled=${!hasActiveJobsFilters}\n @click=${props.onJobsFiltersReset}\n >\n ${t(\"cron.jobs.reset\")}\n </button>\n </label>\n </div>\n ${\n props.jobs.length === 0\n ? html`\n <div class=\"muted\" style=\"margin-top: 12px\">${t(\"cron.jobs.noMatching\")}</div>\n `\n : html`\n <div class=\"list\" style=\"margin-top: 12px;\">\n ${props.jobs.map((job) => renderJob(job, props))}\n </div>\n `\n }\n ${\n props.jobsHasMore\n ? html`\n <div class=\"row\" style=\"margin-top: 12px\">\n <button\n class=\"btn\"\n ?disabled=${props.loading || props.jobsLoadingMore}\n @click=${props.onLoadMoreJobs}\n >\n ${props.jobsLoadingMore ? t(\"cron.jobs.loading\") : t(\"cron.jobs.loadMore\")}\n </button>\n </div>\n `\n : nothing\n }\n </section>\n\n <section class=\"card\">\n <div class=\"row\" style=\"justify-content: space-between; align-items: flex-start; gap: 12px;\">\n <div>\n <div class=\"card-title\">${t(\"cron.runs.title\")}</div>\n <div class=\"card-sub\">\n ${\n props.runsScope === \"all\"\n ? t(\"cron.runs.subtitleAll\")\n : t(\"cron.runs.subtitleJob\", { title: selectedRunTitle })\n }\n </div>\n </div>\n <div class=\"muted\">${t(\"cron.jobs.shownOf\", {\n shown: String(runs.length),\n total: String(props.runsTotal),\n })}</div>\n </div>\n <div class=\"cron-run-filters\">\n <div class=\"cron-run-filters__row cron-run-filters__row--primary\">\n <label class=\"field\">\n <span>${t(\"cron.runs.scope\")}</span>\n <select\n .value=${props.runsScope}\n @change=${(e: Event) =>\n props.onRunsFiltersChange({\n cronRunsScope: (e.target as HTMLSelectElement).value as CronRunScope,\n })}\n >\n <option value=\"all\">${t(\"cron.runs.allJobs\")}</option>\n <option value=\"job\" ?disabled=${props.runsJobId == null}>${t(\"cron.runs.selectedJob\")}</option>\n </select>\n </label>\n <label class=\"field cron-run-filter-search\">\n <span>${t(\"cron.runs.searchRuns\")}</span>\n <input\n .value=${props.runsQuery}\n placeholder=${t(\"cron.runs.searchPlaceholder\")}\n @input=${(e: Event) =>\n props.onRunsFiltersChange({\n cronRunsQuery: (e.target as HTMLInputElement).value,\n })}\n />\n </label>\n <label class=\"field\">\n <span>${t(\"cron.jobs.sort\")}</span>\n <select\n .value=${props.runsSortDir}\n @change=${(e: Event) =>\n props.onRunsFiltersChange({\n cronRunsSortDir: (e.target as HTMLSelectElement).value as CronSortDir,\n })}\n >\n <option value=\"desc\">${t(\"cron.runs.newestFirst\")}</option>\n <option value=\"asc\">${t(\"cron.runs.oldestFirst\")}</option>\n </select>\n </label>\n </div>\n <div class=\"cron-run-filters__row cron-run-filters__row--secondary\">\n ${renderRunFilterDropdown({\n id: \"status\",\n title: t(\"cron.runs.status\"),\n summary: statusSummary,\n options: runStatusOptions,\n selected: props.runsStatuses,\n onToggle: (value, checked) => {\n const next = toggleSelection(\n props.runsStatuses,\n value as CronRunsStatusValue,\n checked,\n );\n void props.onRunsFiltersChange({ cronRunsStatuses: next });\n },\n onClear: () => {\n void props.onRunsFiltersChange({ cronRunsStatuses: [] });\n },\n })}\n ${renderRunFilterDropdown({\n id: \"delivery\",\n title: t(\"cron.runs.delivery\"),\n summary: deliverySummary,\n options: runDeliveryOptions,\n selected: props.runsDeliveryStatuses,\n onToggle: (value, checked) => {\n const next = toggleSelection(\n props.runsDeliveryStatuses,\n value as CronDeliveryStatus,\n checked,\n );\n void props.onRunsFiltersChange({ cronRunsDeliveryStatuses: next });\n },\n onClear: () => {\n void props.onRunsFiltersChange({ cronRunsDeliveryStatuses: [] });\n },\n })}\n </div>\n </div>\n ${\n props.runsScope === \"job\" && props.runsJobId == null\n ? html`\n <div class=\"muted\" style=\"margin-top: 12px\">${t(\"cron.runs.selectJobHint\")}</div>\n `\n : runs.length === 0\n ? html`\n <div class=\"muted\" style=\"margin-top: 12px\">${t(\"cron.runs.noMatching\")}</div>\n `\n : html`\n <div class=\"list\" style=\"margin-top: 12px;\">\n ${runs.map((entry) => renderRun(entry, props.basePath))}\n </div>\n `\n }\n ${\n (props.runsScope === \"all\" || props.runsJobId != null) && props.runsHasMore\n ? html`\n <div class=\"row\" style=\"margin-top: 12px\">\n <button\n class=\"btn\"\n ?disabled=${props.runsLoadingMore}\n @click=${props.onLoadMoreRuns}\n >\n ${props.runsLoadingMore ? t(\"cron.jobs.loading\") : t(\"cron.runs.loadMore\")}\n </button>\n </div>\n `\n : nothing\n }\n </section>\n </div>\n\n <section class=\"card cron-workspace-form\">\n <div class=\"card-title\">${isEditing ? t(\"cron.form.editJob\") : t(\"cron.form.newJob\")}</div>\n <div class=\"card-sub\">\n ${isEditing ? t(\"cron.form.updateSubtitle\") : t(\"cron.form.createSubtitle\")}\n </div>\n <div class=\"cron-form\">\n <div class=\"cron-required-legend\">\n <span class=\"cron-required-marker\" aria-hidden=\"true\">*</span> ${t(\"cron.form.required\")}\n </div>\n <section class=\"cron-form-section\">\n <div class=\"cron-form-section__title\">${t(\"cron.form.basics\")}</div>\n <div class=\"cron-form-section__sub\">${t(\"cron.form.basicsSub\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.fieldName\"), true)}\n <input\n id=\"cron-name\"\n .value=${props.form.name}\n placeholder=${t(\"cron.form.namePlaceholder\")}\n aria-invalid=${props.fieldErrors.name ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.name ? errorIdForField(\"name\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({ name: (e.target as HTMLInputElement).value })}\n />\n ${renderFieldError(props.fieldErrors.name, errorIdForField(\"name\"))}\n </label>\n <label class=\"field\">\n <span>${t(\"cron.form.description\")}</span>\n <input\n .value=${props.form.description}\n placeholder=${t(\"cron.form.descriptionPlaceholder\")}\n @input=${(e: Event) =>\n props.onFormChange({ description: (e.target as HTMLInputElement).value })}\n />\n </label>\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.agentId\"))}\n <input\n id=\"cron-agent-id\"\n .value=${props.form.agentId}\n list=\"cron-agent-suggestions\"\n ?disabled=${props.form.clearAgent}\n @input=${(e: Event) =>\n props.onFormChange({ agentId: (e.target as HTMLInputElement).value })}\n placeholder=${t(\"cron.form.agentPlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.agentHelp\")}</div>\n </label>\n <label class=\"field checkbox cron-checkbox cron-checkbox-inline\">\n <input\n type=\"checkbox\"\n .checked=${props.form.enabled}\n @change=${(e: Event) =>\n props.onFormChange({ enabled: (e.target as HTMLInputElement).checked })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.summary.enabled\")}</span>\n </label>\n </div>\n </section>\n\n <section class=\"cron-form-section\">\n <div class=\"cron-form-section__title\">${t(\"cron.form.schedule\")}</div>\n <div class=\"cron-form-section__sub\">${t(\"cron.form.scheduleSub\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(t(\"cron.form.schedule\"))}\n <select\n id=\"cron-schedule-kind\"\n .value=${props.form.scheduleKind}\n @change=${(e: Event) =>\n props.onFormChange({\n scheduleKind: (e.target as HTMLSelectElement)\n .value as CronFormState[\"scheduleKind\"],\n })}\n >\n <option value=\"every\">${t(\"cron.form.every\")}</option>\n <option value=\"at\">${t(\"cron.form.at\")}</option>\n <option value=\"cron\">${t(\"cron.form.cronOption\")}</option>\n </select>\n </label>\n </div>\n ${renderScheduleFields(props)}\n </section>\n\n <section class=\"cron-form-section\">\n <div class=\"cron-form-section__title\">${t(\"cron.form.execution\")}</div>\n <div class=\"cron-form-section__sub\">${t(\"cron.form.executionSub\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.session\"))}\n <select\n id=\"cron-session-target\"\n .value=${props.form.sessionTarget}\n @change=${(e: Event) =>\n props.onFormChange({\n sessionTarget: (e.target as HTMLSelectElement)\n .value as CronFormState[\"sessionTarget\"],\n })}\n >\n <option value=\"main\">${t(\"cron.form.main\")}</option>\n <option value=\"isolated\">${t(\"cron.form.isolated\")}</option>\n </select>\n <div class=\"cron-help\">${t(\"cron.form.sessionHelp\")}</div>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.wakeMode\"))}\n <select\n id=\"cron-wake-mode\"\n .value=${props.form.wakeMode}\n @change=${(e: Event) =>\n props.onFormChange({\n wakeMode: (e.target as HTMLSelectElement).value as CronFormState[\"wakeMode\"],\n })}\n >\n <option value=\"now\">${t(\"cron.form.now\")}</option>\n <option value=\"next-heartbeat\">${t(\"cron.form.nextHeartbeat\")}</option>\n </select>\n <div class=\"cron-help\">${t(\"cron.form.wakeModeHelp\")}</div>\n </label>\n <label class=\"field ${isAgentTurn ? \"\" : \"cron-span-2\"}\">\n ${renderFieldLabel(t(\"cron.form.payloadKind\"))}\n <select\n id=\"cron-payload-kind\"\n .value=${props.form.payloadKind}\n @change=${(e: Event) =>\n props.onFormChange({\n payloadKind: (e.target as HTMLSelectElement)\n .value as CronFormState[\"payloadKind\"],\n })}\n >\n <option value=\"systemEvent\">${t(\"cron.form.systemEvent\")}</option>\n <option value=\"agentTurn\">${t(\"cron.form.agentTurn\")}</option>\n </select>\n <div class=\"cron-help\">\n ${\n props.form.payloadKind === \"systemEvent\"\n ? t(\"cron.form.systemEventHelp\")\n : t(\"cron.form.agentTurnHelp\")\n }\n </div>\n </label>\n ${\n isAgentTurn\n ? html`\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.timeoutSeconds\"))}\n <input\n id=\"cron-timeout-seconds\"\n .value=${props.form.timeoutSeconds}\n placeholder=${t(\"cron.form.timeoutPlaceholder\")}\n aria-invalid=${props.fieldErrors.timeoutSeconds ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.timeoutSeconds\n ? errorIdForField(\"timeoutSeconds\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n timeoutSeconds: (e.target as HTMLInputElement).value,\n })}\n />\n <div class=\"cron-help\">${t(\"cron.form.timeoutHelp\")}</div>\n ${renderFieldError(\n props.fieldErrors.timeoutSeconds,\n errorIdForField(\"timeoutSeconds\"),\n )}\n </label>\n `\n : nothing\n }\n </div>\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(\n props.form.payloadKind === \"systemEvent\"\n ? t(\"cron.form.mainTimelineMessage\")\n : t(\"cron.form.assistantTaskPrompt\"),\n true,\n )}\n <textarea\n id=\"cron-payload-text\"\n .value=${props.form.payloadText}\n aria-invalid=${props.fieldErrors.payloadText ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.payloadText ? errorIdForField(\"payloadText\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n payloadText: (e.target as HTMLTextAreaElement).value,\n })}\n rows=\"4\"\n ></textarea>\n ${renderFieldError(props.fieldErrors.payloadText, errorIdForField(\"payloadText\"))}\n </label>\n </section>\n\n <section class=\"cron-form-section\">\n <div class=\"cron-form-section__title\">${t(\"cron.form.deliverySection\")}</div>\n <div class=\"cron-form-section__sub\">${t(\"cron.form.deliverySub\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field ${selectedDeliveryMode === \"none\" ? \"cron-span-2\" : \"\"}\">\n ${renderFieldLabel(t(\"cron.form.resultDelivery\"))}\n <select\n id=\"cron-delivery-mode\"\n .value=${selectedDeliveryMode}\n @change=${(e: Event) =>\n props.onFormChange({\n deliveryMode: (e.target as HTMLSelectElement)\n .value as CronFormState[\"deliveryMode\"],\n })}\n >\n ${\n supportsAnnounce\n ? html`\n <option value=\"announce\">${t(\"cron.form.announceDefault\")}</option>\n `\n : nothing\n }\n <option value=\"webhook\">${t(\"cron.form.webhookPost\")}</option>\n <option value=\"none\">${t(\"cron.form.noneInternal\")}</option>\n </select>\n <div class=\"cron-help\">${t(\"cron.form.deliveryHelp\")}</div>\n </label>\n ${\n selectedDeliveryMode !== \"none\"\n ? html`\n <label class=\"field ${selectedDeliveryMode === \"webhook\" ? \"cron-span-2\" : \"\"}\">\n ${renderFieldLabel(\n selectedDeliveryMode === \"webhook\"\n ? t(\"cron.form.webhookUrl\")\n : t(\"cron.form.channel\"),\n selectedDeliveryMode === \"webhook\",\n )}\n ${\n selectedDeliveryMode === \"webhook\"\n ? html`\n <input\n id=\"cron-delivery-to\"\n .value=${props.form.deliveryTo}\n list=\"cron-delivery-to-suggestions\"\n aria-invalid=${props.fieldErrors.deliveryTo ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.deliveryTo\n ? errorIdForField(\"deliveryTo\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n deliveryTo: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.webhookPlaceholder\")}\n />\n `\n : html`\n <select\n id=\"cron-delivery-channel\"\n .value=${props.form.deliveryChannel || \"last\"}\n @change=${(e: Event) =>\n props.onFormChange({\n deliveryChannel: (e.target as HTMLSelectElement).value,\n })}\n >\n ${channelOptions.map(\n (channel) =>\n html`<option value=${channel}>\n ${resolveChannelLabel(props, channel)}\n </option>`,\n )}\n </select>\n `\n }\n ${\n selectedDeliveryMode === \"announce\"\n ? html`\n <div class=\"cron-help\">${t(\"cron.form.channelHelp\")}</div>\n `\n : html`\n <div class=\"cron-help\">${t(\"cron.form.webhookHelp\")}</div>\n `\n }\n </label>\n ${\n selectedDeliveryMode === \"announce\"\n ? html`\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(t(\"cron.form.to\"))}\n <input\n id=\"cron-delivery-to\"\n .value=${props.form.deliveryTo}\n list=\"cron-delivery-to-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({\n deliveryTo: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.toPlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.toHelp\")}</div>\n </label>\n `\n : nothing\n }\n ${\n selectedDeliveryMode === \"webhook\"\n ? renderFieldError(\n props.fieldErrors.deliveryTo,\n errorIdForField(\"deliveryTo\"),\n )\n : nothing\n }\n `\n : nothing\n }\n </div>\n </section>\n\n <details class=\"cron-advanced\">\n <summary class=\"cron-advanced__summary\">${t(\"cron.form.advanced\")}</summary>\n <div class=\"cron-help\">${t(\"cron.form.advancedHelp\")}</div>\n <div class=\"form-grid cron-form-grid\">\n <label class=\"field checkbox cron-checkbox\">\n <input\n type=\"checkbox\"\n .checked=${props.form.deleteAfterRun}\n @change=${(e: Event) =>\n props.onFormChange({\n deleteAfterRun: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.form.deleteAfterRun\")}</span>\n <div class=\"cron-help\">${t(\"cron.form.deleteAfterRunHelp\")}</div>\n </label>\n <label class=\"field checkbox cron-checkbox\">\n <input\n type=\"checkbox\"\n .checked=${props.form.clearAgent}\n @change=${(e: Event) =>\n props.onFormChange({\n clearAgent: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.form.clearAgentOverride\")}</span>\n <div class=\"cron-help\">${t(\"cron.form.clearAgentHelp\")}</div>\n </label>\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(\"Session key\")}\n <input\n id=\"cron-session-key\"\n .value=${props.form.sessionKey}\n @input=${(e: Event) =>\n props.onFormChange({\n sessionKey: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"agent:main:main\"\n />\n <div class=\"cron-help\">\n Optional routing key for job delivery and wake routing.\n </div>\n </label>\n ${\n isCronSchedule\n ? html`\n <label class=\"field checkbox cron-checkbox cron-span-2\">\n <input\n type=\"checkbox\"\n .checked=${props.form.scheduleExact}\n @change=${(e: Event) =>\n props.onFormChange({\n scheduleExact: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.form.exactTiming\")}</span>\n <div class=\"cron-help\">${t(\"cron.form.exactTimingHelp\")}</div>\n </label>\n <div class=\"cron-stagger-group cron-span-2\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.staggerWindow\"))}\n <input\n id=\"cron-stagger-amount\"\n .value=${props.form.staggerAmount}\n ?disabled=${props.form.scheduleExact}\n aria-invalid=${props.fieldErrors.staggerAmount ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.staggerAmount\n ? errorIdForField(\"staggerAmount\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n staggerAmount: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.staggerPlaceholder\")}\n />\n ${renderFieldError(\n props.fieldErrors.staggerAmount,\n errorIdForField(\"staggerAmount\"),\n )}\n </label>\n <label class=\"field\">\n <span>${t(\"cron.form.staggerUnit\")}</span>\n <select\n .value=${props.form.staggerUnit}\n ?disabled=${props.form.scheduleExact}\n @change=${(e: Event) =>\n props.onFormChange({\n staggerUnit: (e.target as HTMLSelectElement)\n .value as CronFormState[\"staggerUnit\"],\n })}\n >\n <option value=\"seconds\">${t(\"cron.form.seconds\")}</option>\n <option value=\"minutes\">${t(\"cron.form.minutes\")}</option>\n </select>\n </label>\n </div>\n `\n : nothing\n }\n ${\n isAgentTurn\n ? html`\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(\"Account ID\")}\n <input\n id=\"cron-delivery-account-id\"\n .value=${props.form.deliveryAccountId}\n list=\"cron-delivery-account-suggestions\"\n ?disabled=${selectedDeliveryMode !== \"announce\"}\n @input=${(e: Event) =>\n props.onFormChange({\n deliveryAccountId: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"default\"\n />\n <div class=\"cron-help\">\n Optional channel account ID for multi-account setups.\n </div>\n </label>\n <label class=\"field checkbox cron-checkbox cron-span-2\">\n <input\n type=\"checkbox\"\n .checked=${props.form.payloadLightContext}\n @change=${(e: Event) =>\n props.onFormChange({\n payloadLightContext: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">Light context</span>\n <div class=\"cron-help\">\n Use lightweight bootstrap context for this agent job.\n </div>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.model\"))}\n <input\n id=\"cron-payload-model\"\n .value=${props.form.payloadModel}\n list=\"cron-model-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({\n payloadModel: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.modelPlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.modelHelp\")}</div>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.thinking\"))}\n <input\n id=\"cron-payload-thinking\"\n .value=${props.form.payloadThinking}\n list=\"cron-thinking-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({\n payloadThinking: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.thinkingPlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.thinkingHelp\")}</div>\n </label>\n `\n : nothing\n }\n ${\n isAgentTurn\n ? html`\n <label class=\"field cron-span-2\">\n ${renderFieldLabel(\"Failure alerts\")}\n <select\n .value=${props.form.failureAlertMode}\n @change=${(e: Event) =>\n props.onFormChange({\n failureAlertMode: (e.target as HTMLSelectElement)\n .value as CronFormState[\"failureAlertMode\"],\n })}\n >\n <option value=\"inherit\">Inherit global setting</option>\n <option value=\"disabled\">Disable for this job</option>\n <option value=\"custom\">Custom per-job settings</option>\n </select>\n <div class=\"cron-help\">\n Control when this job sends repeated-failure alerts.\n </div>\n </label>\n ${\n props.form.failureAlertMode === \"custom\"\n ? html`\n <label class=\"field\">\n ${renderFieldLabel(\"Alert after\")}\n <input\n id=\"cron-failure-alert-after\"\n .value=${props.form.failureAlertAfter}\n aria-invalid=${props.fieldErrors.failureAlertAfter ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.failureAlertAfter\n ? errorIdForField(\"failureAlertAfter\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n failureAlertAfter: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"2\"\n />\n <div class=\"cron-help\">Consecutive errors before alerting.</div>\n ${renderFieldError(\n props.fieldErrors.failureAlertAfter,\n errorIdForField(\"failureAlertAfter\"),\n )}\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Cooldown (seconds)\")}\n <input\n id=\"cron-failure-alert-cooldown-seconds\"\n .value=${props.form.failureAlertCooldownSeconds}\n aria-invalid=${props.fieldErrors.failureAlertCooldownSeconds ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.failureAlertCooldownSeconds\n ? errorIdForField(\"failureAlertCooldownSeconds\")\n : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n failureAlertCooldownSeconds: (e.target as HTMLInputElement)\n .value,\n })}\n placeholder=\"3600\"\n />\n <div class=\"cron-help\">Minimum seconds between alerts.</div>\n ${renderFieldError(\n props.fieldErrors.failureAlertCooldownSeconds,\n errorIdForField(\"failureAlertCooldownSeconds\"),\n )}\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Alert channel\")}\n <select\n .value=${props.form.failureAlertChannel || \"last\"}\n @change=${(e: Event) =>\n props.onFormChange({\n failureAlertChannel: (e.target as HTMLSelectElement).value,\n })}\n >\n ${channelOptions.map(\n (channel) =>\n html`<option value=${channel}>\n ${resolveChannelLabel(props, channel)}\n </option>`,\n )}\n </select>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Alert to\")}\n <input\n .value=${props.form.failureAlertTo}\n list=\"cron-delivery-to-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({\n failureAlertTo: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"+1555... or chat id\"\n />\n <div class=\"cron-help\">\n Optional recipient override for failure alerts.\n </div>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Alert mode\")}\n <select\n .value=${props.form.failureAlertDeliveryMode || \"announce\"}\n @change=${(e: Event) =>\n props.onFormChange({\n failureAlertDeliveryMode: (e.target as HTMLSelectElement)\n .value as CronFormState[\"failureAlertDeliveryMode\"],\n })}\n >\n <option value=\"announce\">Announce (via channel)</option>\n <option value=\"webhook\">Webhook (HTTP POST)</option>\n </select>\n </label>\n <label class=\"field\">\n ${renderFieldLabel(\"Alert account ID\")}\n <input\n .value=${props.form.failureAlertAccountId}\n @input=${(e: Event) =>\n props.onFormChange({\n failureAlertAccountId: (e.target as HTMLInputElement).value,\n })}\n placeholder=\"Account ID for multi-account setups\"\n />\n </label>\n `\n : nothing\n }\n `\n : nothing\n }\n ${\n selectedDeliveryMode !== \"none\"\n ? html`\n <label class=\"field checkbox cron-checkbox cron-span-2\">\n <input\n type=\"checkbox\"\n .checked=${props.form.deliveryBestEffort}\n @change=${(e: Event) =>\n props.onFormChange({\n deliveryBestEffort: (e.target as HTMLInputElement).checked,\n })}\n />\n <span class=\"field-checkbox__label\">${t(\"cron.form.bestEffortDelivery\")}</span>\n <div class=\"cron-help\">${t(\"cron.form.bestEffortHelp\")}</div>\n </label>\n `\n : nothing\n }\n </div>\n </details>\n </div>\n ${\n blockedByValidation\n ? html`\n <div class=\"cron-form-status\" role=\"status\" aria-live=\"polite\">\n <div class=\"cron-form-status__title\">${t(\"cron.form.cantAddYet\")}</div>\n <div class=\"cron-help\">${t(\"cron.form.fillRequired\")}</div>\n <ul class=\"cron-form-status__list\">\n ${blockingFields.map(\n (field) => html`\n <li>\n <button\n type=\"button\"\n class=\"cron-form-status__link\"\n @click=${() => focusFormField(field.inputId)}\n >\n ${field.label}: ${t(field.message)}\n </button>\n </li>\n `,\n )}\n </ul>\n </div>\n `\n : nothing\n }\n <div class=\"row cron-form-actions\">\n <button class=\"btn primary\" ?disabled=${props.busy || !props.canSubmit} @click=${props.onAdd}>\n ${props.busy ? t(\"cron.form.saving\") : isEditing ? t(\"cron.form.saveChanges\") : t(\"cron.form.addJob\")}\n </button>\n ${\n submitDisabledReason\n ? html`<div class=\"cron-submit-reason\" aria-live=\"polite\">${submitDisabledReason}</div>`\n : nothing\n }\n ${\n isEditing\n ? html`\n <button class=\"btn\" ?disabled=${props.busy} @click=${props.onCancelEdit}>\n ${t(\"cron.form.cancel\")}\n </button>\n `\n : nothing\n }\n </div>\n </section>\n </section>\n\n ${renderSuggestionList(\"cron-agent-suggestions\", props.agentSuggestions)}\n ${renderSuggestionList(\"cron-model-suggestions\", props.modelSuggestions)}\n ${renderSuggestionList(\"cron-thinking-suggestions\", props.thinkingSuggestions)}\n ${renderSuggestionList(\"cron-tz-suggestions\", props.timezoneSuggestions)}\n ${renderSuggestionList(\"cron-delivery-to-suggestions\", props.deliveryToSuggestions)}\n ${renderSuggestionList(\"cron-delivery-account-suggestions\", props.accountSuggestions)}\n `;\n}\n\nfunction renderScheduleFields(props: CronProps) {\n const form = props.form;\n if (form.scheduleKind === \"at\") {\n return html`\n <label class=\"field cron-span-2\" style=\"margin-top: 12px;\">\n ${renderFieldLabel(t(\"cron.form.runAt\"), true)}\n <input\n id=\"cron-schedule-at\"\n type=\"datetime-local\"\n .value=${form.scheduleAt}\n aria-invalid=${props.fieldErrors.scheduleAt ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.scheduleAt ? errorIdForField(\"scheduleAt\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n scheduleAt: (e.target as HTMLInputElement).value,\n })}\n />\n ${renderFieldError(props.fieldErrors.scheduleAt, errorIdForField(\"scheduleAt\"))}\n </label>\n `;\n }\n if (form.scheduleKind === \"every\") {\n return html`\n <div class=\"form-grid cron-form-grid\" style=\"margin-top: 12px;\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.every\"), true)}\n <input\n id=\"cron-every-amount\"\n .value=${form.everyAmount}\n aria-invalid=${props.fieldErrors.everyAmount ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.everyAmount ? errorIdForField(\"everyAmount\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({\n everyAmount: (e.target as HTMLInputElement).value,\n })}\n placeholder=${t(\"cron.form.everyAmountPlaceholder\")}\n />\n ${renderFieldError(props.fieldErrors.everyAmount, errorIdForField(\"everyAmount\"))}\n </label>\n <label class=\"field\">\n <span>${t(\"cron.form.unit\")}</span>\n <select\n .value=${form.everyUnit}\n @change=${(e: Event) =>\n props.onFormChange({\n everyUnit: (e.target as HTMLSelectElement).value as CronFormState[\"everyUnit\"],\n })}\n >\n <option value=\"minutes\">${t(\"cron.form.minutes\")}</option>\n <option value=\"hours\">${t(\"cron.form.hours\")}</option>\n <option value=\"days\">${t(\"cron.form.days\")}</option>\n </select>\n </label>\n </div>\n `;\n }\n return html`\n <div class=\"form-grid cron-form-grid\" style=\"margin-top: 12px;\">\n <label class=\"field\">\n ${renderFieldLabel(t(\"cron.form.expression\"), true)}\n <input\n id=\"cron-cron-expr\"\n .value=${form.cronExpr}\n aria-invalid=${props.fieldErrors.cronExpr ? \"true\" : \"false\"}\n aria-describedby=${ifDefined(\n props.fieldErrors.cronExpr ? errorIdForField(\"cronExpr\") : undefined,\n )}\n @input=${(e: Event) =>\n props.onFormChange({ cronExpr: (e.target as HTMLInputElement).value })}\n placeholder=${t(\"cron.form.expressionPlaceholder\")}\n />\n ${renderFieldError(props.fieldErrors.cronExpr, errorIdForField(\"cronExpr\"))}\n </label>\n <label class=\"field\">\n <span>${t(\"cron.form.timezoneOptional\")}</span>\n <input\n .value=${form.cronTz}\n list=\"cron-tz-suggestions\"\n @input=${(e: Event) =>\n props.onFormChange({ cronTz: (e.target as HTMLInputElement).value })}\n placeholder=${t(\"cron.form.timezonePlaceholder\")}\n />\n <div class=\"cron-help\">${t(\"cron.form.timezoneHelp\")}</div>\n </label>\n <div class=\"cron-help cron-span-2\">${t(\"cron.form.jitterHelp\")}</div>\n </div>\n `;\n}\n\nfunction renderFieldError(message?: string, id?: string) {\n if (!message) {\n return nothing;\n }\n return html`<div id=${ifDefined(id)} class=\"cron-help cron-error\">${t(message)}</div>`;\n}\n\nfunction renderJob(job: CronJob, props: CronProps) {\n const isSelected = props.runsJobId === job.id;\n const itemClass = `list-item list-item-clickable cron-job${isSelected ? \" list-item-selected\" : \"\"}`;\n const selectAnd = (action: () => void) => {\n props.onLoadRuns(job.id);\n action();\n };\n return html`\n <div class=${itemClass} @click=${() => props.onLoadRuns(job.id)}>\n <div class=\"list-main\">\n <div class=\"list-title\">${job.name}</div>\n <div class=\"list-sub\">${formatCronSchedule(job)}</div>\n ${renderJobPayload(job)}\n ${job.agentId ? html`<div class=\"muted cron-job-agent\">${t(\"cron.jobDetail.agent\")}: ${job.agentId}</div>` : nothing}\n </div>\n <div class=\"list-meta\">\n ${renderJobState(job)}\n </div>\n <div class=\"cron-job-footer\">\n <div class=\"chip-row cron-job-chips\">\n <span class=${`chip ${job.enabled ? \"chip-ok\" : \"chip-danger\"}`}>\n ${job.enabled ? t(\"cron.jobList.enabled\") : t(\"cron.jobList.disabled\")}\n </span>\n <span class=\"chip\">${job.sessionTarget}</span>\n <span class=\"chip\">${job.wakeMode}</span>\n </div>\n <div class=\"row cron-job-actions\">\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onEdit(job));\n }}\n >\n ${t(\"cron.jobList.edit\")}\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onClone(job));\n }}\n >\n ${t(\"cron.jobList.clone\")}\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onToggle(job, !job.enabled));\n }}\n >\n ${job.enabled ? t(\"cron.jobList.disable\") : t(\"cron.jobList.enable\")}\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onRun(job, \"force\"));\n }}\n >\n ${t(\"cron.jobList.run\")}\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onRun(job, \"due\"));\n }}\n >\n Run if due\n </button>\n <button\n class=\"btn\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n props.onLoadRuns(job.id);\n }}\n >\n ${t(\"cron.jobList.history\")}\n </button>\n <button\n class=\"btn danger\"\n ?disabled=${props.busy}\n @click=${(event: Event) => {\n event.stopPropagation();\n selectAnd(() => props.onRemove(job));\n }}\n >\n ${t(\"cron.jobList.remove\")}\n </button>\n </div>\n </div>\n </div>\n `;\n}\n\nfunction renderJobPayload(job: CronJob) {\n if (job.payload.kind === \"systemEvent\") {\n return html`<div class=\"cron-job-detail\">\n <span class=\"cron-job-detail-label\">${t(\"cron.jobDetail.system\")}</span>\n <span class=\"muted cron-job-detail-value\">${job.payload.text}</span>\n </div>`;\n }\n\n const delivery = job.delivery;\n const deliveryTarget =\n delivery?.mode === \"webhook\"\n ? delivery.to\n ? ` (${delivery.to})`\n : \"\"\n : delivery?.channel || delivery?.to\n ? ` (${delivery.channel ?? \"last\"}${delivery.to ? ` -> ${delivery.to}` : \"\"})`\n : \"\";\n\n return html`\n <div class=\"cron-job-detail\">\n <span class=\"cron-job-detail-label\">${t(\"cron.jobDetail.prompt\")}</span>\n <span class=\"muted cron-job-detail-value\">${job.payload.message}</span>\n </div>\n ${\n delivery\n ? html`<div class=\"cron-job-detail\">\n <span class=\"cron-job-detail-label\">${t(\"cron.jobDetail.delivery\")}</span>\n <span class=\"muted cron-job-detail-value\">${delivery.mode}${deliveryTarget}</span>\n </div>`\n : nothing\n }\n `;\n}\n\nfunction formatStateRelative(ms?: number) {\n if (typeof ms !== \"number\" || !Number.isFinite(ms)) {\n return t(\"common.na\");\n }\n return formatRelativeTimestamp(ms);\n}\n\nfunction formatRunNextLabel(nextRunAtMs: number, nowMs = Date.now()) {\n const rel = formatRelativeTimestamp(nextRunAtMs);\n return nextRunAtMs > nowMs ? t(\"cron.runEntry.next\", { rel }) : t(\"cron.runEntry.due\", { rel });\n}\n\nfunction renderJobState(job: CronJob) {\n const rawStatus = job.state?.lastStatus;\n const statusClass =\n rawStatus === \"ok\"\n ? \"cron-job-status-ok\"\n : rawStatus === \"error\"\n ? \"cron-job-status-error\"\n : rawStatus === \"skipped\"\n ? \"cron-job-status-skipped\"\n : \"cron-job-status-na\";\n const statusLabel =\n rawStatus === \"ok\"\n ? t(\"cron.runs.runStatusOk\")\n : rawStatus === \"error\"\n ? t(\"cron.runs.runStatusError\")\n : rawStatus === \"skipped\"\n ? t(\"cron.runs.runStatusSkipped\")\n : t(\"common.na\");\n const nextRunAtMs = job.state?.nextRunAtMs;\n const lastRunAtMs = job.state?.lastRunAtMs;\n\n return html`\n <div class=\"cron-job-state\">\n <div class=\"cron-job-state-row\">\n <span class=\"cron-job-state-key\">${t(\"cron.jobState.status\")}</span>\n <span class=${`cron-job-status-pill ${statusClass}`}>${statusLabel}</span>\n </div>\n <div class=\"cron-job-state-row\">\n <span class=\"cron-job-state-key\">${t(\"cron.jobState.next\")}</span>\n <span class=\"cron-job-state-value\" title=${formatMs(nextRunAtMs)}>\n ${formatStateRelative(nextRunAtMs)}\n </span>\n </div>\n <div class=\"cron-job-state-row\">\n <span class=\"cron-job-state-key\">${t(\"cron.jobState.last\")}</span>\n <span class=\"cron-job-state-value\" title=${formatMs(lastRunAtMs)}>\n ${formatStateRelative(lastRunAtMs)}\n </span>\n </div>\n </div>\n `;\n}\n\nfunction runStatusLabel(value: string): string {\n switch (value) {\n case \"ok\":\n return t(\"cron.runs.runStatusOk\");\n case \"error\":\n return t(\"cron.runs.runStatusError\");\n case \"skipped\":\n return t(\"cron.runs.runStatusSkipped\");\n default:\n return t(\"cron.runs.runStatusUnknown\");\n }\n}\n\nfunction runDeliveryLabel(value: string): string {\n switch (value) {\n case \"delivered\":\n return t(\"cron.runs.deliveryDelivered\");\n case \"not-delivered\":\n return t(\"cron.runs.deliveryNotDelivered\");\n case \"not-requested\":\n return t(\"cron.runs.deliveryNotRequested\");\n case \"unknown\":\n return t(\"cron.runs.deliveryUnknown\");\n default:\n return t(\"cron.runs.deliveryUnknown\");\n }\n}\n\nfunction renderRun(entry: CronRunLogEntry, basePath: string) {\n const chatUrl =\n typeof entry.sessionKey === \"string\" && entry.sessionKey.trim().length > 0\n ? `${pathForTab(\"chat\", basePath)}?session=${encodeURIComponent(entry.sessionKey)}`\n : null;\n const status = runStatusLabel(entry.status ?? \"unknown\");\n const delivery = runDeliveryLabel(entry.deliveryStatus ?? \"not-requested\");\n const usage = entry.usage;\n const usageSummary =\n usage && typeof usage.total_tokens === \"number\"\n ? `${usage.total_tokens} tokens`\n : usage && typeof usage.input_tokens === \"number\" && typeof usage.output_tokens === \"number\"\n ? `${usage.input_tokens} in / ${usage.output_tokens} out`\n : null;\n return html`\n <div class=\"list-item cron-run-entry\">\n <div class=\"list-main cron-run-entry__main\">\n <div class=\"list-title cron-run-entry__title\">\n ${entry.jobName ?? entry.jobId}\n <span class=\"muted\"> · ${status}</span>\n </div>\n <div class=\"list-sub cron-run-entry__summary\">${entry.summary ?? entry.error ?? t(\"cron.runEntry.noSummary\")}</div>\n <div class=\"chip-row\" style=\"margin-top: 6px;\">\n <span class=\"chip\">${delivery}</span>\n ${entry.model ? html`<span class=\"chip\">${entry.model}</span>` : nothing}\n ${entry.provider ? html`<span class=\"chip\">${entry.provider}</span>` : nothing}\n ${usageSummary ? html`<span class=\"chip\">${usageSummary}</span>` : nothing}\n </div>\n </div>\n <div class=\"list-meta cron-run-entry__meta\">\n <div>${formatMs(entry.ts)}</div>\n ${typeof entry.runAtMs === \"number\" ? html`<div class=\"muted\">${t(\"cron.runEntry.runAt\")} ${formatMs(entry.runAtMs)}</div>` : nothing}\n <div class=\"muted\">${entry.durationMs ?? 0}ms</div>\n ${\n typeof entry.nextRunAtMs === \"number\"\n ? html`<div class=\"muted\">${formatRunNextLabel(entry.nextRunAtMs)}</div>`\n : nothing\n }\n ${\n chatUrl\n ? html`<div><a class=\"session-link\" href=${chatUrl}>${t(\"cron.runEntry.openRunChat\")}</a></div>`\n : nothing\n }\n ${entry.error ? html`<div class=\"muted\">${entry.error}</div>` : nothing}\n ${entry.deliveryError ? html`<div class=\"muted\">${entry.deliveryError}</div>` : nothing}\n </div>\n </div>\n `;\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import{i as e,n as t}from"./lit-BZwq2xLD.js";import{i as n}from"./index-5bbJdGkA.js";function r(r){let i=(r.status&&typeof r.status==`object`?r.status.securityAudit:null)?.summary??null,a=i?.critical??0,o=i?.warn??0,s=i?.info??0,c=a>0?`danger`:o>0?`warn`:`success`,l=a>0?`${a} critical`:o>0?`${o} warnings`:`No critical issues`;return e`
1
+ import{i as e,n as t}from"./lit-BZwq2xLD.js";import{i as n}from"./index-UVvtebBp.js";function r(r){let i=(r.status&&typeof r.status==`object`?r.status.securityAudit:null)?.summary??null,a=i?.critical??0,o=i?.warn??0,s=i?.info??0,c=a>0?`danger`:o>0?`warn`:`success`,l=a>0?`${a} critical`:o>0?`${o} warnings`:`No critical issues`;return e`
2
2
  <section class="grid">
3
3
  <div class="card">
4
4
  <div class="row" style="justify-content: space-between;">
@@ -93,4 +93,4 @@ import{i as e,n as t}from"./lit-BZwq2xLD.js";import{i as n}from"./index-5bbJdGkA
93
93
  `}
94
94
  </section>
95
95
  `}export{r as renderDebug};
96
- //# sourceMappingURL=debug-DHAgRpkQ.js.map
96
+ //# sourceMappingURL=debug-Bh_xMppa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug-DHAgRpkQ.js","names":[],"sources":["../../../ui/src/ui/views/debug.ts"],"sourcesContent":["import { html, nothing } from \"lit\";\nimport type { EventLogEntry } from \"../app-events.ts\";\nimport { formatEventPayload } from \"../presenter.ts\";\n\nexport type DebugProps = {\n loading: boolean;\n status: Record<string, unknown> | null;\n health: Record<string, unknown> | null;\n models: unknown[];\n heartbeat: unknown;\n eventLog: EventLogEntry[];\n methods: string[];\n callMethod: string;\n callParams: string;\n callResult: string | null;\n callError: string | null;\n onCallMethodChange: (next: string) => void;\n onCallParamsChange: (next: string) => void;\n onRefresh: () => void;\n onCall: () => void;\n};\n\nexport function renderDebug(props: DebugProps) {\n const securityAudit =\n props.status && typeof props.status === \"object\"\n ? (props.status as { securityAudit?: { summary?: Record<string, number> } }).securityAudit\n : null;\n const securitySummary = securityAudit?.summary ?? null;\n const critical = securitySummary?.critical ?? 0;\n const warn = securitySummary?.warn ?? 0;\n const info = securitySummary?.info ?? 0;\n const securityTone = critical > 0 ? \"danger\" : warn > 0 ? \"warn\" : \"success\";\n const securityLabel =\n critical > 0 ? `${critical} critical` : warn > 0 ? `${warn} warnings` : \"No critical issues\";\n\n return html`\n <section class=\"grid\">\n <div class=\"card\">\n <div class=\"row\" style=\"justify-content: space-between;\">\n <div>\n <div class=\"card-title\">Snapshots</div>\n <div class=\"card-sub\">Status, health, and heartbeat data.</div>\n </div>\n <button class=\"btn\" ?disabled=${props.loading} @click=${props.onRefresh}>\n ${props.loading ? \"Refreshing…\" : \"Refresh\"}\n </button>\n </div>\n <div class=\"stack\" style=\"margin-top: 12px;\">\n <div>\n <div class=\"muted\">Status</div>\n ${\n securitySummary\n ? html`<div class=\"callout ${securityTone}\" style=\"margin-top: 8px;\">\n Security audit: ${securityLabel}${info > 0 ? ` · ${info} info` : \"\"}. Run\n <span class=\"mono\">openclaw security audit --deep</span> for details.\n </div>`\n : nothing\n }\n <pre class=\"code-block\">${JSON.stringify(props.status ?? {}, null, 2)}</pre>\n </div>\n <div>\n <div class=\"muted\">Health</div>\n <pre class=\"code-block\">${JSON.stringify(props.health ?? {}, null, 2)}</pre>\n </div>\n <div>\n <div class=\"muted\">Last heartbeat</div>\n <pre class=\"code-block\">${JSON.stringify(props.heartbeat ?? {}, null, 2)}</pre>\n </div>\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Manual RPC</div>\n <div class=\"card-sub\">Send a raw gateway method with JSON params.</div>\n <div class=\"stack\" style=\"margin-top: 16px;\">\n <label class=\"field\">\n <span>Method</span>\n <select\n .value=${props.callMethod}\n @change=${(e: Event) => props.onCallMethodChange((e.target as HTMLSelectElement).value)}\n >\n ${\n !props.callMethod\n ? html`\n <option value=\"\" disabled>Select a method…</option>\n `\n : nothing\n }\n ${props.methods.map((m) => html`<option value=${m}>${m}</option>`)}\n </select>\n </label>\n <label class=\"field\">\n <span>Params (JSON)</span>\n <textarea\n .value=${props.callParams}\n @input=${(e: Event) =>\n props.onCallParamsChange((e.target as HTMLTextAreaElement).value)}\n rows=\"6\"\n ></textarea>\n </label>\n </div>\n <div class=\"row\" style=\"margin-top: 12px;\">\n <button class=\"btn primary\" @click=${props.onCall}>Call</button>\n </div>\n ${\n props.callError\n ? html`<div class=\"callout danger\" style=\"margin-top: 12px;\">\n ${props.callError}\n </div>`\n : nothing\n }\n ${\n props.callResult\n ? html`<pre class=\"code-block\" style=\"margin-top: 12px;\">${props.callResult}</pre>`\n : nothing\n }\n </div>\n </section>\n\n <section class=\"card\" style=\"margin-top: 18px;\">\n <div class=\"card-title\">Models</div>\n <div class=\"card-sub\">Catalog from models.list.</div>\n <pre class=\"code-block\" style=\"margin-top: 12px;\">${JSON.stringify(\n props.models ?? [],\n null,\n 2,\n )}</pre>\n </section>\n\n <section class=\"card\" style=\"margin-top: 18px;\">\n <div class=\"card-title\">Event Log</div>\n <div class=\"card-sub\">Latest gateway events.</div>\n ${\n props.eventLog.length === 0\n ? html`\n <div class=\"muted\" style=\"margin-top: 12px\">No events yet.</div>\n `\n : html`\n <div class=\"list debug-event-log\" style=\"margin-top: 12px;\">\n ${props.eventLog.map(\n (evt) => html`\n <div class=\"list-item debug-event-log__item\">\n <div class=\"list-main\">\n <div class=\"list-title\">${evt.event}</div>\n <div class=\"list-sub\">${new Date(evt.ts).toLocaleTimeString()}</div>\n </div>\n <div class=\"list-meta debug-event-log__meta\">\n <pre class=\"code-block debug-event-log__payload\">${formatEventPayload(\n evt.payload,\n )}</pre>\n </div>\n </div>\n `,\n )}\n </div>\n `\n }\n </section>\n `;\n}\n"],"mappings":"qFAsBA,SAAgB,EAAY,EAAmB,CAK7C,IAAM,GAHJ,EAAM,QAAU,OAAO,EAAM,QAAW,SACnC,EAAM,OAAoE,cAC3E,OACiC,SAAW,KAC5C,EAAW,GAAiB,UAAY,EACxC,EAAO,GAAiB,MAAQ,EAChC,EAAO,GAAiB,MAAQ,EAChC,EAAe,EAAW,EAAI,SAAW,EAAO,EAAI,OAAS,UAC7D,EACJ,EAAW,EAAI,GAAG,EAAS,WAAa,EAAO,EAAI,GAAG,EAAK,WAAa,qBAE1E,MAAO,EAAI;;;;;;;;0CAQ6B,EAAM,QAAQ,UAAU,EAAM,UAAU;cACpE,EAAM,QAAU,cAAgB,UAAU;;;;;;cAO1C,EACI,CAAI,uBAAuB,EAAa;oCACtB,IAAgB,EAAO,EAAI,MAAM,EAAK,OAAS,GAAG;;wBAGpE,EACL;sCACyB,KAAK,UAAU,EAAM,QAAU,EAAE,CAAE,KAAM,EAAE,CAAC;;;;sCAI5C,KAAK,UAAU,EAAM,QAAU,EAAE,CAAE,KAAM,EAAE,CAAC;;;;sCAI5C,KAAK,UAAU,EAAM,WAAa,EAAE,CAAE,KAAM,EAAE,CAAC;;;;;;;;;;;;uBAY9D,EAAM,WAAW;wBACf,GAAa,EAAM,mBAAoB,EAAE,OAA6B,MAAM,CAAC;;gBAGrF,EAAM,WAIH,EAHA,CAAI;;sBAIT;gBACC,EAAM,QAAQ,IAAK,GAAM,CAAI,iBAAiB,EAAE,GAAG,EAAE,WAAW,CAAC;;;;;;uBAM1D,EAAM,WAAW;uBAChB,GACR,EAAM,mBAAoB,EAAE,OAA+B,MAAM,CAAC;;;;;;+CAMnC,EAAM,OAAO;;UAGlD,EAAM,UACF,CAAI;gBACF,EAAM,UAAU;oBAElB,EACL;UAEC,EAAM,WACF,CAAI,qDAAqD,EAAM,WAAW,QAC1E,EACL;;;;;;;0DAOiD,KAAK,UACvD,EAAM,QAAU,EAAE,CAClB,KACA,EACD,CAAC;;;;;;QAOA,EAAM,SAAS,SAAW,EACtB,CAAI;;cAGJ,CAAI;;gBAEA,EAAM,SAAS,IACd,GAAQ,CAAI;;;gDAGmB,EAAI,MAAM;8CACZ,IAAI,KAAK,EAAI,GAAG,CAAC,oBAAoB,CAAC;;;yEAGX,EACjD,EAAI,QACL,CAAC;;;kBAIT,CAAC;;YAGT"}
1
+ {"version":3,"file":"debug-Bh_xMppa.js","names":[],"sources":["../../../ui/src/ui/views/debug.ts"],"sourcesContent":["import { html, nothing } from \"lit\";\nimport type { EventLogEntry } from \"../app-events.ts\";\nimport { formatEventPayload } from \"../presenter.ts\";\n\nexport type DebugProps = {\n loading: boolean;\n status: Record<string, unknown> | null;\n health: Record<string, unknown> | null;\n models: unknown[];\n heartbeat: unknown;\n eventLog: EventLogEntry[];\n methods: string[];\n callMethod: string;\n callParams: string;\n callResult: string | null;\n callError: string | null;\n onCallMethodChange: (next: string) => void;\n onCallParamsChange: (next: string) => void;\n onRefresh: () => void;\n onCall: () => void;\n};\n\nexport function renderDebug(props: DebugProps) {\n const securityAudit =\n props.status && typeof props.status === \"object\"\n ? (props.status as { securityAudit?: { summary?: Record<string, number> } }).securityAudit\n : null;\n const securitySummary = securityAudit?.summary ?? null;\n const critical = securitySummary?.critical ?? 0;\n const warn = securitySummary?.warn ?? 0;\n const info = securitySummary?.info ?? 0;\n const securityTone = critical > 0 ? \"danger\" : warn > 0 ? \"warn\" : \"success\";\n const securityLabel =\n critical > 0 ? `${critical} critical` : warn > 0 ? `${warn} warnings` : \"No critical issues\";\n\n return html`\n <section class=\"grid\">\n <div class=\"card\">\n <div class=\"row\" style=\"justify-content: space-between;\">\n <div>\n <div class=\"card-title\">Snapshots</div>\n <div class=\"card-sub\">Status, health, and heartbeat data.</div>\n </div>\n <button class=\"btn\" ?disabled=${props.loading} @click=${props.onRefresh}>\n ${props.loading ? \"Refreshing…\" : \"Refresh\"}\n </button>\n </div>\n <div class=\"stack\" style=\"margin-top: 12px;\">\n <div>\n <div class=\"muted\">Status</div>\n ${\n securitySummary\n ? html`<div class=\"callout ${securityTone}\" style=\"margin-top: 8px;\">\n Security audit: ${securityLabel}${info > 0 ? ` · ${info} info` : \"\"}. Run\n <span class=\"mono\">openclaw security audit --deep</span> for details.\n </div>`\n : nothing\n }\n <pre class=\"code-block\">${JSON.stringify(props.status ?? {}, null, 2)}</pre>\n </div>\n <div>\n <div class=\"muted\">Health</div>\n <pre class=\"code-block\">${JSON.stringify(props.health ?? {}, null, 2)}</pre>\n </div>\n <div>\n <div class=\"muted\">Last heartbeat</div>\n <pre class=\"code-block\">${JSON.stringify(props.heartbeat ?? {}, null, 2)}</pre>\n </div>\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Manual RPC</div>\n <div class=\"card-sub\">Send a raw gateway method with JSON params.</div>\n <div class=\"stack\" style=\"margin-top: 16px;\">\n <label class=\"field\">\n <span>Method</span>\n <select\n .value=${props.callMethod}\n @change=${(e: Event) => props.onCallMethodChange((e.target as HTMLSelectElement).value)}\n >\n ${\n !props.callMethod\n ? html`\n <option value=\"\" disabled>Select a method…</option>\n `\n : nothing\n }\n ${props.methods.map((m) => html`<option value=${m}>${m}</option>`)}\n </select>\n </label>\n <label class=\"field\">\n <span>Params (JSON)</span>\n <textarea\n .value=${props.callParams}\n @input=${(e: Event) =>\n props.onCallParamsChange((e.target as HTMLTextAreaElement).value)}\n rows=\"6\"\n ></textarea>\n </label>\n </div>\n <div class=\"row\" style=\"margin-top: 12px;\">\n <button class=\"btn primary\" @click=${props.onCall}>Call</button>\n </div>\n ${\n props.callError\n ? html`<div class=\"callout danger\" style=\"margin-top: 12px;\">\n ${props.callError}\n </div>`\n : nothing\n }\n ${\n props.callResult\n ? html`<pre class=\"code-block\" style=\"margin-top: 12px;\">${props.callResult}</pre>`\n : nothing\n }\n </div>\n </section>\n\n <section class=\"card\" style=\"margin-top: 18px;\">\n <div class=\"card-title\">Models</div>\n <div class=\"card-sub\">Catalog from models.list.</div>\n <pre class=\"code-block\" style=\"margin-top: 12px;\">${JSON.stringify(\n props.models ?? [],\n null,\n 2,\n )}</pre>\n </section>\n\n <section class=\"card\" style=\"margin-top: 18px;\">\n <div class=\"card-title\">Event Log</div>\n <div class=\"card-sub\">Latest gateway events.</div>\n ${\n props.eventLog.length === 0\n ? html`\n <div class=\"muted\" style=\"margin-top: 12px\">No events yet.</div>\n `\n : html`\n <div class=\"list debug-event-log\" style=\"margin-top: 12px;\">\n ${props.eventLog.map(\n (evt) => html`\n <div class=\"list-item debug-event-log__item\">\n <div class=\"list-main\">\n <div class=\"list-title\">${evt.event}</div>\n <div class=\"list-sub\">${new Date(evt.ts).toLocaleTimeString()}</div>\n </div>\n <div class=\"list-meta debug-event-log__meta\">\n <pre class=\"code-block debug-event-log__payload\">${formatEventPayload(\n evt.payload,\n )}</pre>\n </div>\n </div>\n `,\n )}\n </div>\n `\n }\n </section>\n `;\n}\n"],"mappings":"qFAsBA,SAAgB,EAAY,EAAmB,CAK7C,IAAM,GAHJ,EAAM,QAAU,OAAO,EAAM,QAAW,SACnC,EAAM,OAAoE,cAC3E,OACiC,SAAW,KAC5C,EAAW,GAAiB,UAAY,EACxC,EAAO,GAAiB,MAAQ,EAChC,EAAO,GAAiB,MAAQ,EAChC,EAAe,EAAW,EAAI,SAAW,EAAO,EAAI,OAAS,UAC7D,EACJ,EAAW,EAAI,GAAG,EAAS,WAAa,EAAO,EAAI,GAAG,EAAK,WAAa,qBAE1E,MAAO,EAAI;;;;;;;;0CAQ6B,EAAM,QAAQ,UAAU,EAAM,UAAU;cACpE,EAAM,QAAU,cAAgB,UAAU;;;;;;cAO1C,EACI,CAAI,uBAAuB,EAAa;oCACtB,IAAgB,EAAO,EAAI,MAAM,EAAK,OAAS,GAAG;;wBAGpE,EACL;sCACyB,KAAK,UAAU,EAAM,QAAU,EAAE,CAAE,KAAM,EAAE,CAAC;;;;sCAI5C,KAAK,UAAU,EAAM,QAAU,EAAE,CAAE,KAAM,EAAE,CAAC;;;;sCAI5C,KAAK,UAAU,EAAM,WAAa,EAAE,CAAE,KAAM,EAAE,CAAC;;;;;;;;;;;;uBAY9D,EAAM,WAAW;wBACf,GAAa,EAAM,mBAAoB,EAAE,OAA6B,MAAM,CAAC;;gBAGrF,EAAM,WAIH,EAHA,CAAI;;sBAIT;gBACC,EAAM,QAAQ,IAAK,GAAM,CAAI,iBAAiB,EAAE,GAAG,EAAE,WAAW,CAAC;;;;;;uBAM1D,EAAM,WAAW;uBAChB,GACR,EAAM,mBAAoB,EAAE,OAA+B,MAAM,CAAC;;;;;;+CAMnC,EAAM,OAAO;;UAGlD,EAAM,UACF,CAAI;gBACF,EAAM,UAAU;oBAElB,EACL;UAEC,EAAM,WACF,CAAI,qDAAqD,EAAM,WAAW,QAC1E,EACL;;;;;;;0DAOiD,KAAK,UACvD,EAAM,QAAU,EAAE,CAClB,KACA,EACD,CAAC;;;;;;QAOA,EAAM,SAAS,SAAW,EACtB,CAAI;;cAGJ,CAAI;;gBAEA,EAAM,SAAS,IACd,GAAQ,CAAI;;;gDAGmB,EAAI,MAAM;8CACZ,IAAI,KAAK,EAAI,GAAG,CAAC,oBAAoB,CAAC;;;yEAGX,EACjD,EAAI,QACL,CAAC;;;kBAIT,CAAC;;YAGT"}