@goodandready/dsh-cron 0.3.12 → 0.3.14

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.
package/lib/client.js CHANGED
@@ -4,6 +4,7 @@ factory: (require) => {
4
4
  var module = { exports: {} }
5
5
  var exports = module.exports
6
6
  const React = window.React || require('react');
7
+ const h = (...args) => (React && React.createElement ? React.createElement(...args) : null);
7
8
  const ReactDOM = window.ReactDOM || require('react-dom/client');
8
9
  const PLUGIN_ID = '@goodandready/dsh-cron';
9
10
  const NS = 'dsh-cron';
@@ -42,7 +43,7 @@ CoreChevron = primitives && primitives.IconChevronDownOutline14;
42
43
  } catch (e) {
43
44
  /* Optional core chevron primitive not available; SVG fallback used */
44
45
  }
45
- const chevronNode = () => (CoreChevron ? React.createElement(CoreChevron) : React.createElement('span', { style: { display: 'flex', alignItems: 'center' }, dangerouslySetInnerHTML: { __html: ICON_CHEVRON_DOWN } }));
46
+ const chevronNode = () => (CoreChevron ? h(CoreChevron) : h('span', { style: { display: 'flex', alignItems: 'center' }, dangerouslySetInnerHTML: { __html: ICON_CHEVRON_DOWN } }));
46
47
  const STRINGS = {
47
48
  en: {
48
49
  'sidebar.label': 'Scheduled tasks', 'sidebar.jobsTitle': 'Active jobs',
@@ -280,7 +281,7 @@ en: {
280
281
  'approval.approved': 'Approved', 'approval.rejected': 'Rejected',
281
282
  'chainGraph.modalTitle': 'Visual Chain & Checkpoint Graph', 'chainGraph.viewGraph': 'Chain Graph',
282
283
  'chainGraph.noNodes': 'No chained steps found for this task or run.', 'chainGraph.retryStep': 'Retry Step',
283
- 'chainGraph.stepSuccess': 'Success', 'chainGraph.stepFailed': 'Failed', 'chainGraph.stepPending': 'Pending', 'chainGraph.close': 'Close',
284
+ 'chainGraph.stepSuccess': 'Success', 'chainGraph.stepFailed': 'Failed', 'chainGraph.stepPending': 'Pending', 'chainGraph.close': 'Close', 'chainGraph.decisionNode': 'Decision Node', 'chainGraph.stepSkipped': 'Skipped', 'history.doctorDiagnosis': 'Doctor Diagnosis & Suggested Fix', 'history.doctorApply': '1-Click Apply Fix', 'history.doctorRevert': 'Revert to Previous Code', 'history.autoHealed': 'Auto-Healed by Doctor', 'form.autoHealLabel': 'Autonomous Self-Healing Doctor', 'form.autoHealHint': 'Automatically diagnose and apply safe fixes upon failure (max 1 auto-patch/day)', 'form.elseTaskLabel': 'Default Fallback Task (elseTask)', 'form.elseTaskHint': 'Target task to trigger if no conditional branch rules matched', 'form.elseTaskPlaceholder': 'e.g. task-fallback',
284
285
  'adaptive.badge': 'Adaptive', 'adaptive.idle': 'idle', 'adaptive.backoff': 'backoff',
285
286
  'form.adaptiveEnabled': 'Adaptive Polling', 'form.adaptiveHint': 'Exponential backoff when no changes are detected',
286
287
  'liveLog.modalTitle': 'Real-Time Streaming Execution Logs', 'liveLog.viewLog': 'Live Stream',
@@ -462,7 +463,7 @@ zh: {
462
463
  'approval.approved': '已批准', 'approval.rejected': '已拒绝',
463
464
  'chainGraph.modalTitle': '任务链与检查点依赖图', 'chainGraph.viewGraph': '任务链图',
464
465
  'chainGraph.noNodes': '未找到该任务或运行的关联步骤。', 'chainGraph.retryStep': '重试此步骤',
465
- 'chainGraph.stepSuccess': '成功', 'chainGraph.stepFailed': '失败', 'chainGraph.stepPending': '等待中', 'chainGraph.close': '关闭',
466
+ 'chainGraph.stepSuccess': '成功', 'chainGraph.stepFailed': '失败', 'chainGraph.stepPending': '等待中', 'chainGraph.close': '关闭', 'chainGraph.decisionNode': '条件决策节点', 'chainGraph.stepSkipped': '已跳过', 'history.doctorDiagnosis': 'Doctor 诊断与建议修复', 'history.doctorApply': '一键应用修复', 'history.doctorRevert': '恢复上一版本代码', 'history.autoHealed': '已由 Doctor 自动修复', 'form.autoHealLabel': '自主 Self-Healing Doctor 自动修复', 'form.autoHealHint': '当任务失败时自动诊断并安全修复(每天上限 1 次)', 'form.elseTaskLabel': '默认后备任务 (elseTask)', 'form.elseTaskHint': '当没有分支条件匹配时触发的目标任务', 'form.elseTaskPlaceholder': '如 task-fallback',
466
467
  'adaptive.badge': '自适应', 'adaptive.idle': '空闲', 'adaptive.backoff': '避让中',
467
468
  'form.adaptiveEnabled': '自适应轮询 (Adaptive Polling)', 'form.adaptiveHint': '数据无变化时指数级延长执行间隔',
468
469
  'liveLog.modalTitle': '实时任务执行日志流', 'liveLog.viewLog': '实时日志',
@@ -781,10 +782,10 @@ console.error('[dsh-cron] React error:', error, errorInfo);
781
782
  }
782
783
  render() {
783
784
  if (this.state.hasError) {
784
- return React.createElement('div', { className: 'dsh-cron-status-banner', 'data-type': 'error', style: { margin: '12px 0' } },
785
- React.createElement('div', { style: { fontWeight: 600, marginBottom: '6px' } }, '⚠️ Cron UI error:'),
786
- React.createElement('div', { style: { fontSize: '12px', wordBreak: 'break-all' } }, String((this.state.error && this.state.error.message) || this.state.error)),
787
- React.createElement('button', {
785
+ return h('div', { className: 'dsh-cron-status-banner', 'data-type': 'error', style: { margin: '12px 0' } },
786
+ h('div', { style: { fontWeight: 600, marginBottom: '6px' } }, '⚠️ Cron UI error:'),
787
+ h('div', { style: { fontSize: '12px', wordBreak: 'break-all' } }, String((this.state.error && this.state.error.message) || this.state.error)),
788
+ h('button', {
788
789
  type: 'button',
789
790
  className: 'dsh-cron-btn-secondary',
790
791
  style: { marginTop: '10px', fontSize: '12px', padding: '4px 10px' },
@@ -979,9 +980,9 @@ return out;
979
980
  }
980
981
  function renderDeliverySettings({ T, values, onChange, onChannelTemplate, sections, onToggleSection }) {
981
982
  const val = (key) => (values[key] === undefined || values[key] === null ? '' : String(values[key]));
982
- const field = (f) => React.createElement('div', { className: 'dsh-cron-form-group', key: f.key, style: { marginBottom: '10px' } },
983
- React.createElement('label', null, T(f.labelKey)),
984
- React.createElement('input', f.numeric ? {
983
+ const field = (f) => h('div', { className: 'dsh-cron-form-group', key: f.key, style: { marginBottom: '10px' } },
984
+ h('label', null, T(f.labelKey)),
985
+ h('input', f.numeric ? {
985
986
  type: 'number',
986
987
  min: f.min !== undefined ? f.min : 1000,
987
988
  step: 1000,
@@ -999,49 +1000,49 @@ onChange: (e) => onChange(f.key, e.target.value)
999
1000
  );
1000
1001
  const section = (key, titleKey, children) => {
1001
1002
  const open = Boolean(sections[key]);
1002
- return React.createElement('div', { className: 'dsh-cron-section', key },
1003
- React.createElement('button', {
1003
+ return h('div', { className: 'dsh-cron-section', key },
1004
+ h('button', {
1004
1005
  type: 'button',
1005
1006
  className: 'dsh-cron-section-head',
1006
1007
  'aria-expanded': open ? 'true' : 'false',
1007
1008
  onClick: () => onToggleSection(key)
1008
1009
  },
1009
- React.createElement('span', null, T(titleKey)),
1010
- React.createElement('span', { className: 'dsh-cron-section-chevron', 'data-open': open ? 'true' : 'false' }, '▾')
1010
+ h('span', null, T(titleKey)),
1011
+ h('span', { className: 'dsh-cron-section-chevron', 'data-open': open ? 'true' : 'false' }, '▾')
1011
1012
  ),
1012
- open && React.createElement('div', { className: 'dsh-cron-section-body' }, children)
1013
+ open && h('div', { className: 'dsh-cron-section-body' }, children)
1013
1014
  );
1014
1015
  };
1015
1016
  return [
1016
1017
  section('secrets', 'settings.secretsSection', [
1017
- React.createElement('div', { className: 'dsh-cron-hint', key: 'hint', style: { marginBottom: '10px' } }, T('settings.secretsHint')),
1018
+ h('div', { className: 'dsh-cron-hint', key: 'hint', style: { marginBottom: '10px' } }, T('settings.secretsHint')),
1018
1019
  ...DELIVERY_SETTING_FIELDS.filter((f) => f.group === 'secrets').map(field),
1019
1020
  ]),
1020
1021
  section('channels', 'settings.deliverySection', [
1021
- React.createElement('div', { className: 'dsh-cron-form-row', key: 'row' },
1022
+ h('div', { className: 'dsh-cron-form-row', key: 'row' },
1022
1023
  ...DELIVERY_SETTING_FIELDS.filter((f) => f.group === 'channels').map(field)
1023
1024
  ),
1024
1025
  ]),
1025
1026
  section('automation', 'settings.automationSection', [
1026
- React.createElement('div', { className: 'dsh-cron-hint', key: 'hint', style: { marginBottom: '10px' } }, T('settings.automationHint')),
1027
- React.createElement('div', { className: 'dsh-cron-form-row', key: 'row' },
1027
+ h('div', { className: 'dsh-cron-hint', key: 'hint', style: { marginBottom: '10px' } }, T('settings.automationHint')),
1028
+ h('div', { className: 'dsh-cron-form-row', key: 'row' },
1028
1029
  ...DELIVERY_SETTING_FIELDS.filter((f) => f.group === 'automation').map(field)
1029
1030
  ),
1030
1031
  ]),
1031
1032
  section('templates', 'settings.templatesSection', [
1032
- React.createElement('div', { className: 'dsh-cron-form-group', key: 'global', style: { marginBottom: '10px' } },
1033
- React.createElement('label', null, T('settings.templateLabel')),
1034
- React.createElement('input', {
1033
+ h('div', { className: 'dsh-cron-form-group', key: 'global', style: { marginBottom: '10px' } },
1034
+ h('label', null, T('settings.templateLabel')),
1035
+ h('input', {
1035
1036
  type: 'text',
1036
1037
  value: val('template'),
1037
1038
  onChange: (e) => onChange('template', e.target.value)
1038
1039
  }),
1039
- React.createElement('div', { className: 'dsh-cron-hint' }, T('settings.templateHint'))
1040
+ h('div', { className: 'dsh-cron-hint' }, T('settings.templateHint'))
1040
1041
  ),
1041
- React.createElement('div', { className: 'dsh-cron-form-row', key: 'perchannel' },
1042
- ...DELIVERY_CHANNELS.map((id) => React.createElement('div', { className: 'dsh-cron-form-group', key: id, style: { marginBottom: '10px' } },
1043
- React.createElement('label', null, T('settings.channelTemplateLabel', { channel: T(CHANNEL_LABEL_KEYS[id]) })),
1044
- React.createElement('input', {
1042
+ h('div', { className: 'dsh-cron-form-row', key: 'perchannel' },
1043
+ ...DELIVERY_CHANNELS.map((id) => h('div', { className: 'dsh-cron-form-group', key: id, style: { marginBottom: '10px' } },
1044
+ h('label', null, T('settings.channelTemplateLabel', { channel: T(CHANNEL_LABEL_KEYS[id]) })),
1045
+ h('input', {
1045
1046
  type: 'text',
1046
1047
  value: (values.channelTemplates && values.channelTemplates[id]) || '',
1047
1048
  onChange: (e) => onChannelTemplate(id, e.target.value)
@@ -1079,9 +1080,49 @@ if (nodeStatus === 'failed') hasFailure = true;
1079
1080
  nodeStatus = 'running';
1080
1081
  }
1081
1082
  const deps = sanitizeDependsOn(task.dependsOn);
1082
- nodes.push({ id, title: task.title || id, type: task.type || 'prompt', status: nodeStatus, durationMs, retryCount, outputSnippet, isFocus: Boolean(focusTaskId && id === focusTaskId), isRetryable: nodeStatus === 'failed', dependsOn: deps, joinPolicy: sanitizeJoinPolicy(task.joinPolicy) });
1083
+ const hasBranches = Array.isArray(task.branchRules) && task.branchRules.length > 0;
1084
+ nodes.push({
1085
+ id,
1086
+ title: task.title || id,
1087
+ type: task.type || 'prompt',
1088
+ status: nodeStatus,
1089
+ durationMs,
1090
+ retryCount,
1091
+ outputSnippet,
1092
+ isFocus: Boolean(focusTaskId && id === focusTaskId),
1093
+ isRetryable: nodeStatus === 'failed',
1094
+ isDecisionNode: hasBranches,
1095
+ branchRulesCount: hasBranches ? task.branchRules.length : 0,
1096
+ elseTask: task.elseTask || null,
1097
+ dependsOn: deps,
1098
+ joinPolicy: sanitizeJoinPolicy(task.joinPolicy)
1099
+ });
1083
1100
  for (const d of deps) edges.push({ from: d, to: id, type: 'dependsOn', label: task.joinPolicy === 'any_success' ? 'join:any' : 'join:all' });
1101
+ if (hasBranches) {
1102
+ for (const rule of task.branchRules) {
1103
+ if (rule && rule.targetTask) {
1104
+ edges.push({
1105
+ from: id,
1106
+ to: String(rule.targetTask).trim(),
1107
+ type: 'branch',
1108
+ label: rule.label || ('[if: ' + rule.field + ' ' + rule.operator + ' ' + (rule.value != null ? rule.value : '') + ']').trim(),
1109
+ condition: { field: rule.field, operator: rule.operator, value: rule.value }
1110
+ });
1111
+ }
1112
+ }
1113
+ }
1114
+ if (task.elseTask) {
1115
+ edges.push({
1116
+ from: id,
1117
+ to: String(task.elseTask).trim(),
1118
+ type: 'branch_else',
1119
+ label: '[else]',
1120
+ isElse: true
1121
+ });
1122
+ }
1123
+ if (!hasBranches) {
1084
1124
  for (const t of parseChainTargets(task.onSuccess)) edges.push({ from: id, to: t, type: 'onSuccess', label: 'onSuccess' });
1125
+ }
1085
1126
  for (const f of parseChainTargets(task.onFailure)) edges.push({ from: id, to: f, type: 'onFailure', label: 'onFailure' });
1086
1127
  }
1087
1128
  return { nodes, edges, hasFailure };
@@ -1091,68 +1132,68 @@ if (!isOpen) return null;
1091
1132
  const graph = data?.graph || { nodes: [], edges: [], hasFailure: false };
1092
1133
  const chainRunId = data?.chainRunId || '';
1093
1134
  const nodes = graph.nodes || [];
1094
- return React.createElement('div', {
1135
+ return h('div', {
1095
1136
  className: 'dsh-cron-modal-overlay',
1096
1137
  onClick: onClose
1097
1138
  },
1098
- React.createElement('div', {
1139
+ h('div', {
1099
1140
  className: 'dsh-cron-modal',
1100
1141
  style: { maxWidth: '820px', width: '92vw', maxHeight: '88vh', display: 'flex', flexDirection: 'column' },
1101
1142
  role: 'dialog',
1102
1143
  'aria-modal': 'true',
1103
1144
  onClick: (e) => e.stopPropagation()
1104
1145
  },
1105
- React.createElement('div', {
1146
+ h('div', {
1106
1147
  className: 'dsh-cron-modal-head',
1107
1148
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid var(--dsw-alias-border-l2)', paddingBottom: '12px' }
1108
1149
  },
1109
- React.createElement('div', null,
1110
- React.createElement('div', {
1150
+ h('div', null,
1151
+ h('div', {
1111
1152
  className: 'dsh-cron-modal-title',
1112
1153
  style: { margin: 0, display: 'flex', alignItems: 'center', gap: '8px' }
1113
1154
  },
1114
- React.createElement('span', { style: { fontSize: '18px' } }, '🕸️'),
1155
+ h('span', { style: { fontSize: '18px' } }, '🕸️'),
1115
1156
  T_KEY(t, 'chainGraph.modalTitle')
1116
1157
  ),
1117
- chainRunId && React.createElement('div', {
1158
+ chainRunId && h('div', {
1118
1159
  style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '4px', fontFamily: 'monospace' }
1119
1160
  }, 'Run ID: ' + chainRunId)
1120
1161
  ),
1121
- React.createElement('button', {
1162
+ h('button', {
1122
1163
  type: 'button',
1123
1164
  className: 'dsh-cron-icon-btn',
1124
1165
  onClick: onClose
1125
1166
  }, '✕')
1126
1167
  ),
1127
- React.createElement('div', {
1168
+ h('div', {
1128
1169
  style: { flex: 1, overflowY: 'auto', padding: '16px 0', minHeight: '260px' }
1129
1170
  },
1130
- loading && React.createElement('div', {
1171
+ loading && h('div', {
1131
1172
  className: 'dsh-cron-history-empty'
1132
1173
  }, T_KEY(t, 'history.loading')),
1133
- !loading && nodes.length === 0 && React.createElement('div', {
1174
+ !loading && nodes.length === 0 && h('div', {
1134
1175
  className: 'dsh-cron-history-empty'
1135
1176
  }, T_KEY(t, 'chainGraph.noNodes')),
1136
- !loading && nodes.length > 0 && React.createElement('div', {
1177
+ !loading && nodes.length > 0 && h('div', {
1137
1178
  style: { display: 'flex', flexDirection: 'column', gap: '16px' }
1138
1179
  },
1139
- React.createElement('div', {
1180
+ h('div', {
1140
1181
  style: { display: 'flex', gap: '12px', fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)', padding: '0 4px' }
1141
1182
  },
1142
- React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
1143
- React.createElement('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsh-cron-success)' } }),
1183
+ h('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
1184
+ h('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsh-cron-success)' } }),
1144
1185
  T_KEY(t, 'chainGraph.stepSuccess')
1145
1186
  ),
1146
- React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
1147
- React.createElement('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsh-cron-danger)' } }),
1187
+ h('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
1188
+ h('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsh-cron-danger)' } }),
1148
1189
  T_KEY(t, 'chainGraph.stepFailed')
1149
1190
  ),
1150
- React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
1151
- React.createElement('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsw-alias-label-tertiary, #888)' } }),
1191
+ h('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
1192
+ h('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsw-alias-label-tertiary, #888)' } }),
1152
1193
  T_KEY(t, 'chainGraph.stepPending')
1153
1194
  )
1154
1195
  ),
1155
- React.createElement('div', {
1196
+ h('div', {
1156
1197
  style: {
1157
1198
  display: 'flex',
1158
1199
  flexWrap: 'wrap',
@@ -1172,7 +1213,7 @@ const borderColor = isOk
1172
1213
  : isFailed
1173
1214
  ? 'var(--dsh-cron-danger)'
1174
1215
  : 'var(--dsw-alias-border-l2)';
1175
- return React.createElement('div', {
1216
+ return h('div', {
1176
1217
  key: n.id || idx,
1177
1218
  style: {
1178
1219
  flex: '1 1 220px',
@@ -1187,13 +1228,13 @@ gap: '8px',
1187
1228
  boxShadow: isFailed ? '0 0 0 1px var(--dsh-cron-danger)' : 'none'
1188
1229
  }
1189
1230
  },
1190
- React.createElement('div', {
1231
+ h('div', {
1191
1232
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: '6px' }
1192
1233
  },
1193
- React.createElement('div', {
1234
+ h('div', {
1194
1235
  style: { fontWeight: '600', fontSize: '13px', color: 'var(--dsw-alias-label-primary)' }
1195
1236
  }, n.title || n.id),
1196
- React.createElement('span', {
1237
+ h('span', {
1197
1238
  style: {
1198
1239
  fontSize: '10px',
1199
1240
  padding: '2px 6px',
@@ -1204,19 +1245,22 @@ color: isOk ? 'var(--dsh-cron-success)' : isFailed ? 'var(--dsh-cron-danger)' :
1204
1245
  }
1205
1246
  }, isOk ? '✓ ' + T_KEY(t, 'chainGraph.stepSuccess') : isFailed ? '✗ ' + T_KEY(t, 'chainGraph.stepFailed') : '⏳ ' + T_KEY(t, 'chainGraph.stepPending'))
1206
1247
  ),
1207
- React.createElement('div', {
1248
+ h('div', {
1208
1249
  style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary)', display: 'flex', gap: '8px', flexWrap: 'wrap' }
1209
1250
  },
1210
- n.durationMs > 0 && React.createElement('span', null, n.durationMs + 'ms'),
1211
- n.retryCount > 0 && React.createElement('span', { style: { color: 'var(--dsh-cron-warning)' } }, '↻ ' + n.retryCount),
1212
- n.joinPolicy && n.dependsOn?.length > 0 && React.createElement('span', {
1251
+ n.durationMs > 0 && h('span', null, n.durationMs + 'ms'),
1252
+ n.retryCount > 0 && h('span', { style: { color: 'var(--dsh-cron-warning)' } }, '↻ ' + n.retryCount),
1253
+ n.joinPolicy && n.dependsOn?.length > 0 && h('span', {
1213
1254
  style: { background: 'var(--dsw-alias-bg-layer-3)', padding: '1px 4px', borderRadius: '4px' }
1214
1255
  }, n.joinPolicy === 'any_success' ? 'join:any' : 'join:all')
1215
1256
  ),
1216
- n.dependsOn?.length > 0 && React.createElement('div', {
1257
+ n.isDecisionNode && h('div', {
1258
+ style: { fontSize: '11px', color: 'var(--dsh-cron-warning)', fontWeight: '600', display: 'flex', alignItems: 'center', gap: '4px' }
1259
+ }, '🔀 ' + T_KEY(t, 'chainGraph.decisionNode') + ' (' + n.branchRulesCount + ')'),
1260
+ n.dependsOn?.length > 0 && h('div', {
1217
1261
  style: { fontSize: '11px', color: 'var(--dsw-alias-label-tertiary)' }
1218
1262
  }, '← ' + n.dependsOn.join(', ')),
1219
- n.outputSnippet && React.createElement('div', {
1263
+ n.outputSnippet && h('div', {
1220
1264
  style: {
1221
1265
  background: 'var(--dsw-alias-bg-layer-2)',
1222
1266
  border: '1px solid var(--dsw-alias-border-l2)',
@@ -1231,7 +1275,7 @@ maxHeight: '60px',
1231
1275
  overflowY: 'auto'
1232
1276
  }
1233
1277
  }, n.outputSnippet),
1234
- isFailed && chainRunId && React.createElement('button', {
1278
+ isFailed && chainRunId && h('button', {
1235
1279
  type: 'button',
1236
1280
  className: 'dsh-cron-btn-secondary',
1237
1281
  style: {
@@ -1252,11 +1296,11 @@ onClick: () => onRetry && onRetry(n.id)
1252
1296
  )
1253
1297
  )
1254
1298
  ),
1255
- React.createElement('div', {
1299
+ h('div', {
1256
1300
  className: 'dsh-cron-modal-foot',
1257
1301
  style: { borderTop: '1px solid var(--dsw-alias-border-l2)', paddingTop: '12px', marginTop: 'auto' }
1258
1302
  },
1259
- React.createElement('button', {
1303
+ h('button', {
1260
1304
  type: 'button',
1261
1305
  className: 'dsh-cron-btn-primary',
1262
1306
  onClick: onClose
@@ -1274,26 +1318,26 @@ el.scrollTop = el.scrollHeight;
1274
1318
  };
1275
1319
  const isLive = status === 'running' || status === 'connecting';
1276
1320
  const statusColor = isLive ? 'var(--dsh-cron-success, #2a2)' : (status === 'completed' ? 'var(--dsw-alias-label-secondary, #888)' : 'var(--dsh-cron-danger, #e33)');
1277
- return React.createElement('div', {
1321
+ return h('div', {
1278
1322
  className: 'dsh-cron-modal-overlay',
1279
1323
  onClick: onClose
1280
1324
  },
1281
- React.createElement('div', {
1325
+ h('div', {
1282
1326
  className: 'dsh-cron-modal',
1283
1327
  style: { maxWidth: '860px', width: '92vw', height: '80vh', display: 'flex', flexDirection: 'column', background: 'var(--dsw-alias-bg-base, #111)', color: 'var(--dsw-alias-label-primary, #ddd)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '8px' },
1284
1328
  role: 'dialog',
1285
1329
  'aria-modal': 'true',
1286
1330
  onClick: (e) => e.stopPropagation()
1287
1331
  },
1288
- React.createElement('div', {
1332
+ h('div', {
1289
1333
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 16px', borderBottom: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
1290
1334
  },
1291
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
1292
- React.createElement('span', { style: { fontSize: '18px' } }, '📺'),
1293
- React.createElement('div', null,
1294
- React.createElement('div', { style: { fontWeight: '600', fontSize: '14px', color: 'var(--dsw-alias-label-primary, #fff)', display: 'flex', alignItems: 'center', gap: '8px' } },
1335
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
1336
+ h('span', { style: { fontSize: '18px' } }, '📺'),
1337
+ h('div', null,
1338
+ h('div', { style: { fontWeight: '600', fontSize: '14px', color: 'var(--dsw-alias-label-primary, #fff)', display: 'flex', alignItems: 'center', gap: '8px' } },
1295
1339
  T_KEY(t, 'liveLog.modalTitle'),
1296
- React.createElement('span', {
1340
+ h('span', {
1297
1341
  style: {
1298
1342
  display: 'inline-block',
1299
1343
  width: '8px',
@@ -1304,14 +1348,14 @@ boxShadow: isLive ? '0 0 8px ' + statusColor : 'none'
1304
1348
  }
1305
1349
  })
1306
1350
  ),
1307
- React.createElement('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px', fontFamily: 'monospace' } },
1351
+ h('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px', fontFamily: 'monospace' } },
1308
1352
  (taskTitle || taskId) + ' · ' + (isLive ? T_KEY(t, 'liveLog.connecting') : (completed ? T_KEY(t, 'liveLog.completed') : status))
1309
1353
  )
1310
1354
  )
1311
1355
  ),
1312
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '12px' } },
1313
- React.createElement('label', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', alignItems: 'center', gap: '4px', cursor: 'pointer' } },
1314
- React.createElement('input', {
1356
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '12px' } },
1357
+ h('label', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', alignItems: 'center', gap: '4px', cursor: 'pointer' } },
1358
+ h('input', {
1315
1359
  type: 'checkbox',
1316
1360
  checked: Boolean(autoScroll),
1317
1361
  onChange: onToggleAutoScroll,
@@ -1319,7 +1363,7 @@ style: { cursor: 'pointer' }
1319
1363
  }),
1320
1364
  T_KEY(t, 'liveLog.autoScroll')
1321
1365
  ),
1322
- React.createElement('button', {
1366
+ h('button', {
1323
1367
  type: 'button',
1324
1368
  className: 'dsh-cron-icon-btn',
1325
1369
  style: { color: 'var(--dsw-alias-label-secondary, #888)', background: 'transparent', border: 'none', cursor: 'pointer', fontSize: '16px' },
@@ -1327,29 +1371,29 @@ onClick: onClose
1327
1371
  }, '✕')
1328
1372
  )
1329
1373
  ),
1330
- React.createElement('div', {
1374
+ h('div', {
1331
1375
  ref: terminalRef,
1332
1376
  style: { flex: 1, overflowY: 'auto', padding: '14px 16px', fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace', fontSize: '12px', lineHeight: '1.5', background: 'var(--dsw-alias-bg-base, #000)' }
1333
1377
  },
1334
- (!logs || logs.length === 0) && React.createElement('div', {
1378
+ (!logs || logs.length === 0) && h('div', {
1335
1379
  style: { color: 'var(--dsw-alias-label-secondary, #888)', fontStyle: 'italic', padding: '20px 0', textAlign: 'center' }
1336
1380
  }, isLive ? T_KEY(t, 'liveLog.waiting') : 'No output captured for this run.'),
1337
1381
  logs && logs.length > 0 && logs.map((item, idx) => {
1338
1382
  const isErr = item.stream === 'stderr';
1339
1383
  const timeStr = item.ts ? new Date(item.ts).toLocaleTimeString() : '';
1340
- return React.createElement('div', {
1384
+ return h('div', {
1341
1385
  key: idx,
1342
1386
  style: { display: 'flex', gap: '8px', color: isErr ? 'var(--dsh-cron-danger, #f55)' : 'var(--dsh-cron-success, #5f5)', wordBreak: 'break-all', whiteSpace: 'pre-wrap' }
1343
1387
  },
1344
- timeStr && React.createElement('span', { style: { color: 'var(--dsw-alias-label-secondary, #555)', userSelect: 'none', flexShrink: 0 } }, '[' + timeStr + ']'),
1345
- React.createElement('span', { style: { flex: 1 } }, item.chunk || item.text || String(item))
1388
+ timeStr && h('span', { style: { color: 'var(--dsw-alias-label-secondary, #555)', userSelect: 'none', flexShrink: 0 } }, '[' + timeStr + ']'),
1389
+ h('span', { style: { flex: 1 } }, item.chunk || item.text || String(item))
1346
1390
  );
1347
1391
  })
1348
1392
  ),
1349
- React.createElement('div', {
1393
+ h('div', {
1350
1394
  style: { display: 'flex', justifyContent: 'flex-end', padding: '10px 16px', borderTop: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
1351
1395
  },
1352
- React.createElement('button', {
1396
+ h('button', {
1353
1397
  type: 'button',
1354
1398
  className: 'dsh-cron-btn dsh-cron-btn-secondary',
1355
1399
  style: { padding: '6px 14px', fontSize: '12px' },
@@ -1385,117 +1429,117 @@ const text = [
1385
1429
  ].join(String.fromCharCode(10));
1386
1430
  navigator.clipboard.writeText(text).catch(() => {});
1387
1431
  };
1388
- return React.createElement('div', {
1432
+ return h('div', {
1389
1433
  className: 'dsh-cron-modal-overlay',
1390
1434
  onClick: onClose
1391
1435
  },
1392
- React.createElement('div', {
1436
+ h('div', {
1393
1437
  className: 'dsh-cron-modal',
1394
1438
  style: { maxWidth: '780px', width: '92vw', maxHeight: '86vh', display: 'flex', flexDirection: 'column', background: 'var(--dsw-alias-bg-base, #111)', color: 'var(--dsw-alias-label-primary, #ddd)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '8px' },
1395
1439
  role: 'dialog',
1396
1440
  'aria-modal': 'true',
1397
1441
  onClick: (e) => e.stopPropagation()
1398
1442
  },
1399
- React.createElement('div', {
1443
+ h('div', {
1400
1444
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '14px 18px', borderBottom: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
1401
1445
  },
1402
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
1403
- React.createElement('span', { style: { fontSize: '20px' } }, '📊'),
1404
- React.createElement('div', null,
1405
- React.createElement('div', { style: { fontWeight: '600', fontSize: '15px', color: 'var(--dsw-alias-label-primary, #fff)' } },
1446
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
1447
+ h('span', { style: { fontSize: '20px' } }, '📊'),
1448
+ h('div', null,
1449
+ h('div', { style: { fontWeight: '600', fontSize: '15px', color: 'var(--dsw-alias-label-primary, #fff)' } },
1406
1450
  T_KEY(t, 'digest.modalTitle')
1407
1451
  ),
1408
- React.createElement('div', { style: { fontSize: '11.5px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } },
1452
+ h('div', { style: { fontSize: '11.5px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } },
1409
1453
  (T_KEY(t, 'digest.buttonTitle')) + ' · ' + (periodDays || 7) + 'd'
1410
1454
  )
1411
1455
  )
1412
1456
  ),
1413
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
1414
- React.createElement('button', {
1457
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
1458
+ h('button', {
1415
1459
  type: 'button',
1416
1460
  className: 'dsh-cron-btn-secondary',
1417
1461
  style: { padding: '4px 10px', fontSize: '12px', fontWeight: periodDays === 7 ? '600' : '400', background: periodDays === 7 ? 'var(--dsw-alias-bg-layer-3, #222)' : 'transparent' },
1418
1462
  onClick: () => onSelectPeriod && onSelectPeriod(7)
1419
1463
  }, T_KEY(t, 'digest.period7')),
1420
- React.createElement('button', {
1464
+ h('button', {
1421
1465
  type: 'button',
1422
1466
  className: 'dsh-cron-btn-secondary',
1423
1467
  style: { padding: '4px 10px', fontSize: '12px', fontWeight: periodDays === 30 ? '600' : '400', background: periodDays === 30 ? 'var(--dsw-alias-bg-layer-3, #222)' : 'transparent' },
1424
1468
  onClick: () => onSelectPeriod && onSelectPeriod(30)
1425
1469
  }, T_KEY(t, 'digest.period30')),
1426
- React.createElement('button', {
1470
+ h('button', {
1427
1471
  type: 'button',
1428
1472
  className: 'dsh-cron-icon-btn',
1429
1473
  onClick: onClose,
1430
1474
  style: { marginLeft: '8px' }
1431
- }, React.createElement('span', null, '✕'))
1475
+ }, h('span', null, '✕'))
1432
1476
  )
1433
1477
  ),
1434
- React.createElement('div', {
1478
+ h('div', {
1435
1479
  style: { padding: '16px 18px', overflowY: 'auto', flex: 1, display: 'flex', flexDirection: 'column', gap: '16px' }
1436
1480
  },
1437
- isLoading ? React.createElement('div', { style: { padding: '30px', textAlign: 'center', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Loading digest metrics...') : React.createElement(React.Fragment, null,
1481
+ isLoading ? h('div', { style: { padding: '30px', textAlign: 'center', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Loading digest metrics...') : h(React.Fragment, null,
1438
1482
  (() => {
1439
- const renderKpi = (label, val, sub, subCol) => React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '10px 12px' } },
1440
- React.createElement('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)' } }, label),
1441
- React.createElement('div', { style: { fontSize: '18px', fontWeight: '700', color: 'var(--dsw-alias-label-primary, #fff)', marginTop: '4px' } }, val),
1442
- React.createElement('div', { style: { fontSize: '11px', color: subCol || 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } }, sub)
1483
+ const renderKpi = (label, val, sub, subCol) => h('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '10px 12px' } },
1484
+ h('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)' } }, label),
1485
+ h('div', { style: { fontSize: '18px', fontWeight: '700', color: 'var(--dsw-alias-label-primary, #fff)', marginTop: '4px' } }, val),
1486
+ h('div', { style: { fontSize: '11px', color: subCol || 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } }, sub)
1443
1487
  );
1444
- return React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '10px' } },
1488
+ return h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '10px' } },
1445
1489
  renderKpi(T_KEY(t, 'digest.executions'), digest.totalRuns, digest.successRate + '% SR', digest.successRate >= 90 ? 'var(--dsh-cron-success, #2a2)' : 'var(--dsh-cron-warning, #fa0)'),
1446
1490
  renderKpi(T_KEY(t, 'digest.tokens'), Number(digest.totalTokens || 0).toLocaleString(), 'LLM prompt+out'),
1447
1491
  renderKpi(T_KEY(t, 'digest.cost'), '$' + Number(digest.totalCostUsd || 0).toFixed(4), 'USD estimated'),
1448
1492
  renderKpi(T_KEY(t, 'digest.fleet'), digest.activeTasksCount, digest.pausedTasksCount + ' paused')
1449
1493
  );
1450
1494
  })(),
1451
- React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '12px' } },
1452
- React.createElement('div', { style: { fontWeight: '600', fontSize: '13px', color: 'var(--dsh-cron-warning, #fa0)', marginBottom: '8px' } },
1495
+ h('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '12px' } },
1496
+ h('div', { style: { fontWeight: '600', fontSize: '13px', color: 'var(--dsh-cron-warning, #fa0)', marginBottom: '8px' } },
1453
1497
  '⚠️ ' + (T_KEY(t, 'digest.unstableTitle'))
1454
1498
  ),
1455
- (digest.topUnstableTasks && digest.topUnstableTasks.length > 0) ? React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '6px' } },
1456
- digest.topUnstableTasks.map((tItem, idx) => React.createElement('div', {
1499
+ (digest.topUnstableTasks && digest.topUnstableTasks.length > 0) ? h('div', { style: { display: 'flex', flexDirection: 'column', gap: '6px' } },
1500
+ digest.topUnstableTasks.map((tItem, idx) => h('div', {
1457
1501
  key: tItem.id || idx,
1458
1502
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '12px', padding: '6px 8px', background: 'var(--dsw-alias-bg-base, #111)', borderRadius: '4px', border: '1px solid var(--dsw-alias-border-l2, #222)' }
1459
1503
  },
1460
- React.createElement('span', { style: { fontFamily: 'monospace' } }, (idx + 1) + '. ' + (tItem.name || tItem.id)),
1461
- React.createElement('span', { style: { color: 'var(--dsh-cron-danger, #e33)', fontWeight: '600' } },
1504
+ h('span', { style: { fontFamily: 'monospace' } }, (idx + 1) + '. ' + (tItem.name || tItem.id)),
1505
+ h('span', { style: { color: 'var(--dsh-cron-danger, #e33)', fontWeight: '600' } },
1462
1506
  tItem.failures + ' fail (' + tItem.successRate + '% SR)'
1463
1507
  )
1464
1508
  ))
1465
- ) : React.createElement('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } }, '✓ All tasks healthy — 0 failures in window!')
1509
+ ) : h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } }, '✓ All tasks healthy — 0 failures in window!')
1466
1510
  ),
1467
- React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '12px' } },
1468
- React.createElement('div', { style: { fontWeight: '600', fontSize: '13px', color: 'var(--dsh-cron-info, #4af)', marginBottom: '8px' } },
1511
+ h('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '12px' } },
1512
+ h('div', { style: { fontWeight: '600', fontSize: '13px', color: 'var(--dsh-cron-info, #4af)', marginBottom: '8px' } },
1469
1513
  '💰 ' + (T_KEY(t, 'digest.expensiveTitle'))
1470
1514
  ),
1471
- (digest.topExpensiveTasks && digest.topExpensiveTasks.length > 0) ? React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '6px' } },
1472
- digest.topExpensiveTasks.map((tItem, idx) => React.createElement('div', {
1515
+ (digest.topExpensiveTasks && digest.topExpensiveTasks.length > 0) ? h('div', { style: { display: 'flex', flexDirection: 'column', gap: '6px' } },
1516
+ digest.topExpensiveTasks.map((tItem, idx) => h('div', {
1473
1517
  key: tItem.id || idx,
1474
1518
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '12px', padding: '6px 8px', background: 'var(--dsw-alias-bg-base, #111)', borderRadius: '4px', border: '1px solid var(--dsw-alias-border-l2, #222)' }
1475
1519
  },
1476
- React.createElement('span', { style: { fontFamily: 'monospace' } }, (idx + 1) + '. ' + (tItem.name || tItem.id)),
1477
- React.createElement('span', { style: { color: 'var(--dsw-alias-label-primary, #ddd)' } },
1520
+ h('span', { style: { fontFamily: 'monospace' } }, (idx + 1) + '. ' + (tItem.name || tItem.id)),
1521
+ h('span', { style: { color: 'var(--dsw-alias-label-primary, #ddd)' } },
1478
1522
  Number(tItem.tokens || 0).toLocaleString() + ' tok ($' + Number(tItem.costUsd || 0).toFixed(4) + ')'
1479
1523
  )
1480
1524
  ))
1481
- ) : React.createElement('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'No significant token consumption recorded.')
1525
+ ) : h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'No significant token consumption recorded.')
1482
1526
  )
1483
1527
  )
1484
1528
  ),
1485
- React.createElement('div', {
1529
+ h('div', {
1486
1530
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 18px', borderTop: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
1487
1531
  },
1488
- React.createElement('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } },
1532
+ h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } },
1489
1533
  sendStatus || ''
1490
1534
  ),
1491
- React.createElement('div', { style: { display: 'flex', gap: '8px' } },
1492
- React.createElement('button', {
1535
+ h('div', { style: { display: 'flex', gap: '8px' } },
1536
+ h('button', {
1493
1537
  type: 'button',
1494
1538
  className: 'dsh-cron-btn-secondary',
1495
1539
  onClick: copyMarkdown,
1496
1540
  style: { padding: '6px 14px', fontSize: '12px' }
1497
1541
  }, T_KEY(t, 'digest.copyMarkdown')),
1498
- React.createElement('button', {
1542
+ h('button', {
1499
1543
  type: 'button',
1500
1544
  className: 'dsh-cron-btn-primary',
1501
1545
  onClick: onSendTelegram,
@@ -1520,70 +1564,70 @@ if (!isOpen) return null;
1520
1564
  const tab = activeTab || 'timeline';
1521
1565
  const timeline = timelineData || { buckets: [], totalRuns: 0, peakHoursCount: 0, maxConcurrent: 3 };
1522
1566
  const heatmap = heatmapData || { matrix: [], dayLabels: [], hourLabels: [], totalCostUsd: 0, totalTokens: 0, maxCostHour: 0 };
1523
- return React.createElement('div', {
1567
+ return h('div', {
1524
1568
  className: 'dsh-cron-modal-overlay',
1525
1569
  onClick: onClose
1526
1570
  },
1527
- React.createElement('div', {
1571
+ h('div', {
1528
1572
  className: 'dsh-cron-modal',
1529
1573
  style: { maxWidth: '960px', width: '94vw', maxHeight: '88vh', display: 'flex', flexDirection: 'column', background: 'var(--dsw-alias-bg-base, #111)', color: 'var(--dsw-alias-label-primary, #ddd)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '8px' },
1530
1574
  role: 'dialog',
1531
1575
  'aria-modal': 'true',
1532
1576
  onClick: (e) => e.stopPropagation()
1533
1577
  },
1534
- React.createElement('div', {
1578
+ h('div', {
1535
1579
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '14px 18px', borderBottom: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
1536
1580
  },
1537
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
1538
- React.createElement('span', { style: { fontSize: '20px' } }, tab === 'timeline' ? '⏱' : '🔥'),
1539
- React.createElement('div', null,
1540
- React.createElement('div', { style: { fontWeight: '600', fontSize: '15px', color: 'var(--dsw-alias-label-primary, #fff)' } },
1581
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
1582
+ h('span', { style: { fontSize: '20px' } }, tab === 'timeline' ? '⏱' : '🔥'),
1583
+ h('div', null,
1584
+ h('div', { style: { fontWeight: '600', fontSize: '15px', color: 'var(--dsw-alias-label-primary, #fff)' } },
1541
1585
  tab === 'timeline' ? (T_KEY(t, 'timeline.modalTitle')) : (T_KEY(t, 'heatmap.modalTitle'))
1542
1586
  ),
1543
- React.createElement('div', { style: { fontSize: '11.5px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } },
1587
+ h('div', { style: { fontSize: '11.5px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } },
1544
1588
  tab === 'timeline'
1545
1589
  ? (timeline.totalRuns + ' runs projected · ' + (timeline.peakHoursCount ? '⚠️ ' + timeline.peakHoursCount + ' peak hours' : '✓ balanced concurrency'))
1546
1590
  : ('$' + Number(heatmap.totalCostUsd || 0).toFixed(4) + ' USD · ' + Number(heatmap.totalTokens || 0).toLocaleString() + ' tokens')
1547
1591
  )
1548
1592
  )
1549
1593
  ),
1550
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
1551
- React.createElement('button', {
1594
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
1595
+ h('button', {
1552
1596
  type: 'button',
1553
1597
  className: 'dsh-cron-btn-secondary',
1554
1598
  style: { padding: '4px 12px', fontSize: '12px', fontWeight: tab === 'timeline' ? '600' : '400', background: tab === 'timeline' ? 'var(--dsw-alias-bg-layer-3, #222)' : 'transparent' },
1555
1599
  onClick: () => onSelectTab && onSelectTab('timeline')
1556
1600
  }, '⏱ ' + (T_KEY(t, 'timeline.tabTimeline'))),
1557
- React.createElement('button', {
1601
+ h('button', {
1558
1602
  type: 'button',
1559
1603
  className: 'dsh-cron-btn-secondary',
1560
1604
  style: { padding: '4px 12px', fontSize: '12px', fontWeight: tab === 'heatmap' ? '600' : '400', background: tab === 'heatmap' ? 'var(--dsw-alias-bg-layer-3, #222)' : 'transparent' },
1561
1605
  onClick: () => onSelectTab && onSelectTab('heatmap')
1562
1606
  }, '🔥 ' + (T_KEY(t, 'heatmap.tabHeatmap'))),
1563
- React.createElement('button', {
1607
+ h('button', {
1564
1608
  type: 'button',
1565
1609
  className: 'dsh-cron-icon-btn',
1566
1610
  onClick: onClose,
1567
1611
  style: { marginLeft: '8px' }
1568
- }, React.createElement('span', null, '✕'))
1612
+ }, h('span', null, '✕'))
1569
1613
  )
1570
1614
  ),
1571
- React.createElement('div', {
1615
+ h('div', {
1572
1616
  style: { padding: '16px 18px', overflowY: 'auto', flex: 1, display: 'flex', flexDirection: 'column', gap: '14px' }
1573
1617
  },
1574
- isLoading ? React.createElement('div', { style: { padding: '40px', textAlign: 'center', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Loading visualization data...') : (
1618
+ isLoading ? h('div', { style: { padding: '40px', textAlign: 'center', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Loading visualization data...') : (
1575
1619
  tab === 'timeline' ? (
1576
- React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px' } },
1577
- React.createElement('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', justifyContent: 'space-between' } },
1578
- React.createElement('span', null, T_KEY(t, 'timeline.legendDesc')),
1579
- React.createElement('span', { style: { color: 'var(--dsh-cron-warning, #fa0)' } }, '⚠️ ' + (T_KEY(t, 'timeline.peakWarning')) + ' (' + timeline.maxConcurrent + ')')
1620
+ h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px' } },
1621
+ h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', justifyContent: 'space-between' } },
1622
+ h('span', null, T_KEY(t, 'timeline.legendDesc')),
1623
+ h('span', { style: { color: 'var(--dsh-cron-warning, #fa0)' } }, '⚠️ ' + (T_KEY(t, 'timeline.peakWarning')) + ' (' + timeline.maxConcurrent + ')')
1580
1624
  ),
1581
- React.createElement('div', {
1625
+ h('div', {
1582
1626
  style: { display: 'grid', gridTemplateColumns: 'repeat(12, 1fr)', gap: '8px', marginTop: '6px' }
1583
1627
  },
1584
1628
  (timeline.buckets || []).map((b) => {
1585
1629
  const isPeak = b.isPeak, hasRuns = b.count > 0;
1586
- return React.createElement('div', {
1630
+ return h('div', {
1587
1631
  key: b.index,
1588
1632
  style: {
1589
1633
  background: isPeak ? 'color-mix(in srgb, var(--dsh-cron-danger, #e33) 12%, var(--dsw-alias-bg-layer-2, #111))' : (hasRuns ? 'var(--dsw-alias-bg-layer-2, #111)' : 'var(--dsw-alias-bg-base, #111)'),
@@ -1591,12 +1635,12 @@ border: isPeak ? '1px solid var(--dsh-cron-danger, #e33)' : (hasRuns ? '1px soli
1591
1635
  borderRadius: '6px', padding: '8px', minHeight: '75px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between'
1592
1636
  }
1593
1637
  },
1594
- React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '11px' } },
1595
- React.createElement('span', { style: { fontWeight: '600', color: isPeak ? 'var(--dsh-cron-danger, #e33)' : 'var(--dsw-alias-label-primary, #fff)' } }, b.label),
1596
- hasRuns ? React.createElement('span', { style: { fontSize: '10px', padding: '1px 5px', borderRadius: '8px', background: isPeak ? 'var(--dsh-cron-danger, #e33)' : 'var(--dsw-alias-bg-layer-3, #222)', color: '#fff' } }, b.count) : null
1638
+ h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '11px' } },
1639
+ h('span', { style: { fontWeight: '600', color: isPeak ? 'var(--dsh-cron-danger, #e33)' : 'var(--dsw-alias-label-primary, #fff)' } }, b.label),
1640
+ hasRuns ? h('span', { style: { fontSize: '10px', padding: '1px 5px', borderRadius: '8px', background: isPeak ? 'var(--dsh-cron-danger, #e33)' : 'var(--dsw-alias-bg-layer-3, #222)', color: '#fff' } }, b.count) : null
1597
1641
  ),
1598
- React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', gap: '3px', marginTop: '4px' } },
1599
- (b.runs || []).slice(0, 3).map((r, rIdx) => React.createElement('span', {
1642
+ h('div', { style: { display: 'flex', flexWrap: 'wrap', gap: '3px', marginTop: '4px' } },
1643
+ (b.runs || []).slice(0, 3).map((r, rIdx) => h('span', {
1600
1644
  key: rIdx, title: (r.title || r.taskId) + ' (' + r.time + ')',
1601
1645
  style: { fontSize: '9.5px', fontFamily: 'monospace', padding: '1px 4px', borderRadius: '3px', background: 'var(--dsw-alias-bg-base, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', maxWidth: '100%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }
1602
1646
  }, r.title || r.taskId))
@@ -1606,36 +1650,36 @@ style: { fontSize: '9.5px', fontFamily: 'monospace', padding: '1px 4px', borderR
1606
1650
  )
1607
1651
  )
1608
1652
  ) : (
1609
- React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '10px' } },
1610
- React.createElement('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', justifyContent: 'space-between' } },
1611
- React.createElement('span', null, T_KEY(t, 'heatmap.matrixDesc')),
1612
- React.createElement('span', null, 'Max hour spend: $' + Number(heatmap.maxCostHour || 0).toFixed(4))
1653
+ h('div', { style: { display: 'flex', flexDirection: 'column', gap: '10px' } },
1654
+ h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', justifyContent: 'space-between' } },
1655
+ h('span', null, T_KEY(t, 'heatmap.matrixDesc')),
1656
+ h('span', null, 'Max hour spend: $' + Number(heatmap.maxCostHour || 0).toFixed(4))
1613
1657
  ),
1614
- React.createElement('div', {
1658
+ h('div', {
1615
1659
  style: { overflowX: 'auto', paddingBottom: '8px' }
1616
1660
  },
1617
- React.createElement('table', {
1661
+ h('table', {
1618
1662
  style: { borderCollapse: 'collapse', width: '100%', minWidth: '700px', fontSize: '10.5px' }
1619
1663
  },
1620
- React.createElement('thead', null,
1621
- React.createElement('tr', null,
1622
- React.createElement('th', { style: { padding: '4px 6px', textAlign: 'left', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Day'),
1623
- Array.from({ length: 24 }, (_, h) => React.createElement('th', {
1664
+ h('thead', null,
1665
+ h('tr', null,
1666
+ h('th', { style: { padding: '4px 6px', textAlign: 'left', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Day'),
1667
+ Array.from({ length: 24 }, (_, h) => h('th', {
1624
1668
  key: h,
1625
1669
  style: { padding: '4px 2px', textAlign: 'center', color: 'var(--dsw-alias-label-secondary, #888)', fontWeight: '400' }
1626
1670
  }, String(h).padStart(2, '0')))
1627
1671
  )
1628
1672
  ),
1629
- React.createElement('tbody', null,
1630
- (heatmap.matrix || []).map((row, dIdx) => React.createElement('tr', { key: dIdx },
1631
- React.createElement('td', { style: { padding: '4px 6px', fontWeight: '600', color: 'var(--dsw-alias-label-primary, #ddd)' } }, (heatmap.dayLabels && heatmap.dayLabels[dIdx]) || 'Day'),
1673
+ h('tbody', null,
1674
+ (heatmap.matrix || []).map((row, dIdx) => h('tr', { key: dIdx },
1675
+ h('td', { style: { padding: '4px 6px', fontWeight: '600', color: 'var(--dsw-alias-label-primary, #ddd)' } }, (heatmap.dayLabels && heatmap.dayLabels[dIdx]) || 'Day'),
1632
1676
  row.map((cell, hIdx) => {
1633
1677
  const intensity = cell.costIntensity || 0;
1634
1678
  const hasSpend = cell.costUsd > 0;
1635
1679
  const bg = hasSpend
1636
1680
  ? 'color-mix(in srgb, var(--dsh-cron-primary, #4af) ' + Math.max(15, Math.round(intensity * 100)) + '%, transparent)'
1637
1681
  : 'transparent';
1638
- return React.createElement('td', {
1682
+ return h('td', {
1639
1683
  key: hIdx,
1640
1684
  title: cell.dayLabel + ' ' + cell.hourLabel + ': $' + cell.costUsd + ' (' + cell.tokens.toLocaleString() + ' tokens, ' + cell.runs + ' runs)',
1641
1685
  style: {
@@ -1645,7 +1689,7 @@ background: bg,
1645
1689
  border: '1px solid var(--dsw-alias-border-l2, #222)',
1646
1690
  cursor: hasSpend ? 'pointer' : 'default'
1647
1691
  }
1648
- }, hasSpend ? React.createElement('span', { style: { fontSize: '9px', color: intensity > 0.5 ? '#fff' : 'var(--dsw-alias-label-primary, #ddd)' } }, '$' + (cell.costUsd >= 0.01 ? cell.costUsd.toFixed(2) : cell.costUsd.toFixed(3).slice(1))) : '·');
1692
+ }, hasSpend ? h('span', { style: { fontSize: '9px', color: intensity > 0.5 ? '#fff' : 'var(--dsw-alias-label-primary, #ddd)' } }, '$' + (cell.costUsd >= 0.01 ? cell.costUsd.toFixed(2) : cell.costUsd.toFixed(3).slice(1))) : '·');
1649
1693
  })
1650
1694
  ))
1651
1695
  )
@@ -1655,10 +1699,10 @@ cursor: hasSpend ? 'pointer' : 'default'
1655
1699
  )
1656
1700
  )
1657
1701
  ),
1658
- React.createElement('div', {
1702
+ h('div', {
1659
1703
  style: { display: 'flex', justifyContent: 'flex-end', padding: '12px 18px', borderTop: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
1660
1704
  },
1661
- React.createElement('button', {
1705
+ h('button', {
1662
1706
  type: 'button',
1663
1707
  className: 'dsh-cron-btn-secondary',
1664
1708
  onClick: onClose,
@@ -1716,6 +1760,8 @@ const [formOnSuccess, setFormOnSuccess] = React.useState('');
1716
1760
  const [formOnFailure, setFormOnFailure] = React.useState('');
1717
1761
  const [formDependsOn, setFormDependsOn] = React.useState('');
1718
1762
  const [formJoinPolicy, setFormJoinPolicy] = React.useState('all_success');
1763
+ const [formElseTask, setFormElseTask] = React.useState('');
1764
+ const [formAutoHeal, setFormAutoHeal] = React.useState(false);
1719
1765
  const [formAdaptiveEnabled, setFormAdaptiveEnabled] = React.useState(false);
1720
1766
  const [formAdaptiveMinInterval, setFormAdaptiveMinInterval] = React.useState('5m');
1721
1767
  const [formAdaptiveMaxInterval, setFormAdaptiveMaxInterval] = React.useState('2h');
@@ -2580,6 +2626,24 @@ alert(e.message || 'Error retrying delivery');
2580
2626
  setRetryingDeliveryId(null);
2581
2627
  }
2582
2628
  };
2629
+ const handleApplyDoctorFix = async (taskId, fix) => {
2630
+ try {
2631
+ const { res, data } = await fetchJsonWithTimeout('/dsh-cron/tasks/' + encodeURIComponent(taskId) + '/doctor/apply', {
2632
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ fix }),
2633
+ });
2634
+ if (data && data.ok) { alert('Doctor fix applied successfully! Task code updated.'); await loadTaskHistory(taskId); await fetchTasks(); }
2635
+ else { alert(data?.error || 'Failed to apply doctor fix'); }
2636
+ } catch (e) { alert(e.message || 'Error applying doctor fix'); }
2637
+ };
2638
+ const handleRevertDoctorFix = async (taskId) => {
2639
+ try {
2640
+ const { res, data } = await fetchJsonWithTimeout('/dsh-cron/tasks/' + encodeURIComponent(taskId) + '/doctor/revert', {
2641
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}),
2642
+ });
2643
+ if (data && data.ok) { alert('Reverted to previous version successfully!'); await loadTaskHistory(taskId); await fetchTasks(); }
2644
+ else { alert(data?.error || 'Failed to revert doctor fix'); }
2645
+ } catch (e) { alert(e.message || 'Error reverting doctor fix'); }
2646
+ };
2583
2647
  const handleResolveUncertain = async (taskId, runId, resolution) => {
2584
2648
  try {
2585
2649
  const { res, data } = await fetchJsonWithTimeout('/dsh-cron/tasks/' + encodeURIComponent(taskId) + '/resolve-uncertain', {
@@ -2947,82 +3011,82 @@ setTimelineLoading(false);
2947
3011
  const onSelectTimelineTab = (tab) => {
2948
3012
  setTimelineTab(tab);
2949
3013
  };
2950
- return React.createElement('div', { className: 'dsh-cron-overlay' },
2951
- React.createElement('div', { className: 'dsh-cron-container' },
2952
- React.createElement('div', { className: 'dsh-cron-top-bar' },
2953
- React.createElement('button', {
3014
+ return h('div', { className: 'dsh-cron-overlay' },
3015
+ h('div', { className: 'dsh-cron-container' },
3016
+ h('div', { className: 'dsh-cron-top-bar' },
3017
+ h('button', {
2954
3018
  type: 'button',
2955
3019
  className: 'dsh-cron-back-btn',
2956
3020
  title: T_KEY(t, 'panel.back'),
2957
3021
  onClick: () => { if (onClose) onClose(); else toggle.set(false); }
2958
3022
  },
2959
- React.createElement('span', svgProps(BACK_ICON)),
2960
- React.createElement('span', null, T_KEY(t, 'panel.back'))
3023
+ h('span', svgProps(BACK_ICON)),
3024
+ h('span', null, T_KEY(t, 'panel.back'))
2961
3025
  )
2962
3026
  ),
2963
- React.createElement('div', { className: 'dsh-cron-header' },
2964
- React.createElement('div', null,
2965
- React.createElement('div', { className: 'dsh-cron-title' }, T_KEY(t, 'panel.title')),
2966
- React.createElement('div', { className: 'dsh-cron-subtitle' }, T_KEY(t, 'panel.subtitle'))
3027
+ h('div', { className: 'dsh-cron-header' },
3028
+ h('div', null,
3029
+ h('div', { className: 'dsh-cron-title' }, T_KEY(t, 'panel.title')),
3030
+ h('div', { className: 'dsh-cron-subtitle' }, T_KEY(t, 'panel.subtitle'))
2967
3031
  ),
2968
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
2969
- React.createElement('button', {
3032
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
3033
+ h('button', {
2970
3034
  type: 'button',
2971
3035
  className: 'dsh-cron-btn-secondary',
2972
3036
  style: { display: 'flex', alignItems: 'center', gap: '6px', height: '36px', padding: '0 12px' },
2973
3037
  title: T_KEY(t, 'timeline.buttonTitle'),
2974
3038
  onClick: () => openTimelineModal('timeline')
2975
3039
  },
2976
- React.createElement('span', { style: { fontSize: '14px' } }, '⏱'),
3040
+ h('span', { style: { fontSize: '14px' } }, '⏱'),
2977
3041
  T_KEY(t, 'timeline.buttonLabel')
2978
3042
  ),
2979
- React.createElement('button', {
3043
+ h('button', {
2980
3044
  type: 'button',
2981
3045
  className: 'dsh-cron-btn-secondary',
2982
3046
  style: { display: 'flex', alignItems: 'center', gap: '6px', height: '36px', padding: '0 12px' },
2983
3047
  title: T_KEY(t, 'digest.buttonTitle'),
2984
3048
  onClick: openAnalyticsDigest
2985
3049
  },
2986
- React.createElement('span', { style: { fontSize: '14px' } }, '📊'),
3050
+ h('span', { style: { fontSize: '14px' } }, '📊'),
2987
3051
  T_KEY(t, 'digest.buttonLabel')
2988
3052
  ),
2989
- React.createElement('button', {
3053
+ h('button', {
2990
3054
  type: 'button',
2991
3055
  className: 'dsh-cron-btn-secondary',
2992
3056
  style: { display: 'flex', alignItems: 'center', gap: '6px', height: '36px', padding: '0 14px' },
2993
3057
  title: T_KEY(t, 'actions.settings'),
2994
3058
  onClick: openSettingsModal
2995
3059
  },
2996
- React.createElement('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
3060
+ h('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
2997
3061
  T_KEY(t, 'actions.settings')
2998
3062
  ),
2999
- React.createElement('div', { style: { position: 'relative' } },
3000
- React.createElement('button', { className: 'dsh-cron-create-btn', onClick: () => setDropdownOpen(!dropdownOpen) },
3063
+ h('div', { style: { position: 'relative' } },
3064
+ h('button', { className: 'dsh-cron-create-btn', onClick: () => setDropdownOpen(!dropdownOpen) },
3001
3065
  T_KEY(t, 'actions.create'),
3002
- React.createElement('span', iconHtml(ICON_CHEVRON_DOWN))
3066
+ h('span', iconHtml(ICON_CHEVRON_DOWN))
3003
3067
  ),
3004
- dropdownOpen && React.createElement('div', { className: 'dsh-cron-dropdown' },
3005
- React.createElement('button', { className: 'dsh-cron-dropdown-item', onClick: openDshModal }, T_KEY(t, 'actions.createWithDsh')),
3006
- React.createElement('button', { className: 'dsh-cron-dropdown-item', onClick: () => openManualModal(null) }, T_KEY(t, 'actions.setupManually'))
3068
+ dropdownOpen && h('div', { className: 'dsh-cron-dropdown' },
3069
+ h('button', { className: 'dsh-cron-dropdown-item', onClick: openDshModal }, T_KEY(t, 'actions.createWithDsh')),
3070
+ h('button', { className: 'dsh-cron-dropdown-item', onClick: () => openManualModal(null) }, T_KEY(t, 'actions.setupManually'))
3007
3071
  )
3008
3072
  ),
3009
- React.createElement('button', {
3073
+ h('button', {
3010
3074
  type: 'button',
3011
3075
  className: 'dsh-cron-icon-btn',
3012
3076
  title: T_KEY(t, 'transfer.exportTitle'),
3013
3077
  'aria-label': T_KEY(t, 'transfer.exportTitle'),
3014
3078
  disabled: transferBusy,
3015
3079
  onClick: handleExport
3016
- }, React.createElement('span', svgProps(ICON_DOWNLOAD))),
3017
- React.createElement('button', {
3080
+ }, h('span', svgProps(ICON_DOWNLOAD))),
3081
+ h('button', {
3018
3082
  type: 'button',
3019
3083
  className: 'dsh-cron-icon-btn',
3020
3084
  title: T_KEY(t, 'transfer.importTitle'),
3021
3085
  'aria-label': T_KEY(t, 'transfer.importTitle'),
3022
3086
  disabled: transferBusy,
3023
3087
  onClick: () => { if (importFileRef.current) importFileRef.current.click(); }
3024
- }, React.createElement('span', svgProps(ICON_UPLOAD))),
3025
- React.createElement('input', {
3088
+ }, h('span', svgProps(ICON_UPLOAD))),
3089
+ h('input', {
3026
3090
  type: 'file',
3027
3091
  accept: '.json,application/json',
3028
3092
  ref: importFileRef,
@@ -3031,9 +3095,9 @@ onChange: handleImportFile
3031
3095
  })
3032
3096
  )
3033
3097
  ),
3034
- React.createElement('div', { className: 'dsh-cron-search-bar' },
3035
- React.createElement('span', { className: 'dsh-cron-search-icon', ...iconHtml(ICON_SEARCH) }),
3036
- React.createElement('input', {
3098
+ h('div', { className: 'dsh-cron-search-bar' },
3099
+ h('span', { className: 'dsh-cron-search-icon', ...iconHtml(ICON_SEARCH) }),
3100
+ h('input', {
3037
3101
  className: 'dsh-cron-search-input',
3038
3102
  type: 'search',
3039
3103
  'aria-label': T_KEY(t, 'search.placeholder'),
@@ -3042,27 +3106,27 @@ value: query,
3042
3106
  onChange: (e) => setQuery(e.target.value)
3043
3107
  })
3044
3108
  ),
3045
- stats && React.createElement('div', { className: 'dsh-cron-stats-bar' },
3046
- React.createElement('div', { className: 'dsh-cron-stat-card' },
3047
- React.createElement('div', { className: 'dsh-cron-stat-val' }, stats.activeTasks || 0),
3048
- React.createElement('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.activeTasks'))
3109
+ stats && h('div', { className: 'dsh-cron-stats-bar' },
3110
+ h('div', { className: 'dsh-cron-stat-card' },
3111
+ h('div', { className: 'dsh-cron-stat-val' }, stats.activeTasks || 0),
3112
+ h('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.activeTasks'))
3049
3113
  ),
3050
- React.createElement('div', { className: 'dsh-cron-stat-card' },
3051
- React.createElement('div', { className: 'dsh-cron-stat-val' }, stats.totalRuns || 0),
3052
- React.createElement('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalRuns'))
3114
+ h('div', { className: 'dsh-cron-stat-card' },
3115
+ h('div', { className: 'dsh-cron-stat-val' }, stats.totalRuns || 0),
3116
+ h('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalRuns'))
3053
3117
  ),
3054
- React.createElement('div', { className: 'dsh-cron-stat-card' },
3055
- React.createElement('div', { className: 'dsh-cron-stat-val' }, (stats.totalTokens || 0).toLocaleString()),
3056
- React.createElement('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalTokens'))
3118
+ h('div', { className: 'dsh-cron-stat-card' },
3119
+ h('div', { className: 'dsh-cron-stat-val' }, (stats.totalTokens || 0).toLocaleString()),
3120
+ h('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalTokens'))
3057
3121
  ),
3058
- React.createElement('div', { className: 'dsh-cron-stat-card' },
3059
- React.createElement('div', { className: 'dsh-cron-stat-val', style: { color: 'var(--dsh-cron-success)' } }, '$' + (stats.totalCostUsd || 0).toFixed(4)),
3060
- React.createElement('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalCost'))
3122
+ h('div', { className: 'dsh-cron-stat-card' },
3123
+ h('div', { className: 'dsh-cron-stat-val', style: { color: 'var(--dsh-cron-success)' } }, '$' + (stats.totalCostUsd || 0).toFixed(4)),
3124
+ h('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalCost'))
3061
3125
  )
3062
3126
  ),
3063
- React.createElement('div', { className: 'dsh-cron-tabs' },
3127
+ h('div', { className: 'dsh-cron-tabs' },
3064
3128
  ['all', 'active', 'paused', 'completed'].map((tabName) =>
3065
- React.createElement('button', {
3129
+ h('button', {
3066
3130
  key: tabName,
3067
3131
  className: 'dsh-cron-tab',
3068
3132
  'data-active': tab === tabName ? 'true' : undefined,
@@ -3074,8 +3138,8 @@ tabName === 'all' ? T_KEY(t, 'tabs.all')
3074
3138
  : T_KEY(t, 'tabs.completed'))
3075
3139
  )
3076
3140
  ),
3077
- React.createElement('div', { className: 'dsh-cron-filters' },
3078
- React.createElement('button', {
3141
+ h('div', { className: 'dsh-cron-filters' },
3142
+ h('button', {
3079
3143
  type: 'button',
3080
3144
  className: 'dsh-cron-filter-toggle',
3081
3145
  'aria-expanded': filtersOpen ? 'true' : 'false',
@@ -3084,73 +3148,73 @@ onClick: () => setFiltersOpen(!filtersOpen)
3084
3148
  T_KEY(t, 'filters.title'),
3085
3149
  (filterType || filterModel || filterChannel) ? ' •' : ''
3086
3150
  ),
3087
- filtersOpen && React.createElement('div', { className: 'dsh-cron-filter-panel' },
3088
- React.createElement('label', { className: 'dsh-cron-filter-field' },
3089
- React.createElement('span', null, T_KEY(t, 'filters.type')),
3090
- React.createElement('select', {
3151
+ filtersOpen && h('div', { className: 'dsh-cron-filter-panel' },
3152
+ h('label', { className: 'dsh-cron-filter-field' },
3153
+ h('span', null, T_KEY(t, 'filters.type')),
3154
+ h('select', {
3091
3155
  value: filterType,
3092
3156
  onChange: (e) => setFilterType(e.target.value)
3093
3157
  },
3094
- React.createElement('option', { value: '' }, T_KEY(t, 'filters.any')),
3095
- ...filterTypeOptions.map((value) => React.createElement('option', { key: value, value }, value))
3158
+ h('option', { value: '' }, T_KEY(t, 'filters.any')),
3159
+ ...filterTypeOptions.map((value) => h('option', { key: value, value }, value))
3096
3160
  )
3097
3161
  ),
3098
- React.createElement('label', { className: 'dsh-cron-filter-field' },
3099
- React.createElement('span', null, T_KEY(t, 'filters.model')),
3100
- React.createElement('select', {
3162
+ h('label', { className: 'dsh-cron-filter-field' },
3163
+ h('span', null, T_KEY(t, 'filters.model')),
3164
+ h('select', {
3101
3165
  value: filterModel,
3102
3166
  onChange: (e) => setFilterModel(e.target.value)
3103
3167
  },
3104
- React.createElement('option', { value: '' }, T_KEY(t, 'filters.any')),
3105
- ...filterModelOptions.map((value) => React.createElement('option', { key: value, value }, value))
3168
+ h('option', { value: '' }, T_KEY(t, 'filters.any')),
3169
+ ...filterModelOptions.map((value) => h('option', { key: value, value }, value))
3106
3170
  )
3107
3171
  ),
3108
- React.createElement('label', { className: 'dsh-cron-filter-field' },
3109
- React.createElement('span', null, T_KEY(t, 'filters.channel')),
3110
- React.createElement('select', {
3172
+ h('label', { className: 'dsh-cron-filter-field' },
3173
+ h('span', null, T_KEY(t, 'filters.channel')),
3174
+ h('select', {
3111
3175
  value: filterChannel,
3112
3176
  onChange: (e) => setFilterChannel(e.target.value)
3113
3177
  },
3114
- React.createElement('option', { value: '' }, T_KEY(t, 'filters.any')),
3115
- ...DELIVERY_CHANNELS.map((id) => React.createElement('option', { key: id, value: id }, T_KEY(t, CHANNEL_LABEL_KEYS[id])))
3178
+ h('option', { value: '' }, T_KEY(t, 'filters.any')),
3179
+ ...DELIVERY_CHANNELS.map((id) => h('option', { key: id, value: id }, T_KEY(t, CHANNEL_LABEL_KEYS[id])))
3116
3180
  )
3117
3181
  )
3118
3182
  )
3119
3183
  ),
3120
- fetchError ? React.createElement('div', {
3184
+ fetchError ? h('div', {
3121
3185
  className: 'dsh-cron-status-banner',
3122
3186
  'data-type': 'error',
3123
3187
  style: { margin: '8px 0', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }
3124
3188
  },
3125
- React.createElement('span', null, T_KEY(t, 'banner.loadError', { error: fetchError })),
3126
- React.createElement('button', {
3189
+ h('span', null, T_KEY(t, 'banner.loadError', { error: fetchError })),
3190
+ h('button', {
3127
3191
  type: 'button',
3128
3192
  className: 'dsh-cron-btn-secondary',
3129
3193
  style: { marginLeft: '8px', padding: '2px 8px', fontSize: '12px' },
3130
3194
  onClick: () => fetchTasks()
3131
3195
  }, T_KEY(t, 'banner.retry'))
3132
3196
  ) : null,
3133
- (filterType || filterModel || filterChannel) ? React.createElement('div', {
3197
+ (filterType || filterModel || filterChannel) ? h('div', {
3134
3198
  className: 'dsh-cron-filter-summary',
3135
3199
  style: { fontSize: '12px', color: 'var(--dsw-alias-label-tertiary, #888)', marginBottom: '8px', display: 'flex', gap: '8px', alignItems: 'center' }
3136
3200
  },
3137
- React.createElement('span', null, T_KEY(t, 'filters.showing', { shown: visibleTasks.length, total: tasks.length })),
3138
- React.createElement('button', {
3201
+ h('span', null, T_KEY(t, 'filters.showing', { shown: visibleTasks.length, total: tasks.length })),
3202
+ h('button', {
3139
3203
  type: 'button',
3140
3204
  className: 'dsh-cron-btn-secondary',
3141
3205
  style: { padding: '2px 8px', fontSize: '11px' },
3142
3206
  onClick: resetFilters
3143
3207
  }, T_KEY(t, 'filters.reset'))
3144
3208
  ) : null,
3145
- React.createElement('div', { className: 'dsh-cron-task-list' },
3209
+ h('div', { className: 'dsh-cron-task-list' },
3146
3210
  loading && tasks.length === 0
3147
- ? React.createElement('div', { style: { color: 'var(--dsw-alias-label-tertiary, #888)', padding: '16px 0', fontSize: '14px' } }, T_KEY(t, 'list.loading'))
3211
+ ? h('div', { style: { color: 'var(--dsw-alias-label-tertiary, #888)', padding: '16px 0', fontSize: '14px' } }, T_KEY(t, 'list.loading'))
3148
3212
  : tasks.length === 0
3149
- ? React.createElement('div', { style: { color: 'var(--dsw-alias-label-tertiary, #777)', padding: '16px 0', fontSize: '14px' } }, T_KEY(t, 'list.empty'))
3213
+ ? h('div', { style: { color: 'var(--dsw-alias-label-tertiary, #777)', padding: '16px 0', fontSize: '14px' } }, T_KEY(t, 'list.empty'))
3150
3214
  : visibleTasks.length === 0
3151
- ? React.createElement('div', { style: { color: 'var(--dsw-alias-label-tertiary, #777)', padding: '16px 0', fontSize: '14px', display: 'flex', gap: '10px', alignItems: 'center' } },
3152
- React.createElement('span', null, T_KEY(t, 'filters.empty')),
3153
- React.createElement('button', {
3215
+ ? h('div', { style: { color: 'var(--dsw-alias-label-tertiary, #777)', padding: '16px 0', fontSize: '14px', display: 'flex', gap: '10px', alignItems: 'center' } },
3216
+ h('span', null, T_KEY(t, 'filters.empty')),
3217
+ h('button', {
3154
3218
  type: 'button',
3155
3219
  className: 'dsh-cron-btn-secondary',
3156
3220
  style: { padding: '2px 8px', fontSize: '12px' },
@@ -3158,7 +3222,7 @@ onClick: resetFilters
3158
3222
  }, T_KEY(t, 'filters.reset'))
3159
3223
  )
3160
3224
  : visibleTasks.map((task) =>
3161
- React.createElement('div', {
3225
+ h('div', {
3162
3226
  key: task.id,
3163
3227
  className: 'dsh-cron-task-item',
3164
3228
  'data-task-id': task.id,
@@ -3174,127 +3238,127 @@ openEditModal(task);
3174
3238
  }
3175
3239
  }
3176
3240
  },
3177
- isConfigManaged(task) ? null : React.createElement('button', {
3241
+ isConfigManaged(task) ? null : h('button', {
3178
3242
  type: 'button',
3179
3243
  className: 'dsh-cron-task-status-btn' + (task.running ? ' dsh-cron-pulse' : ''),
3180
3244
  'data-active': task.status === 'active' ? 'true' : undefined,
3181
3245
  title: task.status === 'active' ? T_KEY(t, 'actions.pause') : T_KEY(t, 'actions.resume'),
3182
3246
  'aria-label': task.status === 'active' ? T_KEY(t, 'actions.pause') : T_KEY(t, 'actions.resume'),
3183
3247
  onClick: (e) => { e.stopPropagation(); handleToggleTask(task.id); }
3184
- }, React.createElement('span', svgProps(task.status === 'active' ? ICON_PAUSE : ICON_PLAY))),
3185
- React.createElement('div', { className: 'dsh-cron-task-info' },
3186
- React.createElement('div', { className: 'dsh-cron-task-title' },
3248
+ }, h('span', svgProps(task.status === 'active' ? ICON_PAUSE : ICON_PLAY))),
3249
+ h('div', { className: 'dsh-cron-task-info' },
3250
+ h('div', { className: 'dsh-cron-task-title' },
3187
3251
  task.title,
3188
- React.createElement('span', {
3252
+ h('span', {
3189
3253
  className: 'dsh-cron-type-tag',
3190
3254
  style: task.type === 'script'
3191
3255
  ? { background: 'var(--dsh-cron-info-bg)', color: 'var(--dsh-cron-info)' }
3192
3256
  : { background: 'var(--dsh-cron-success-bg)', color: 'var(--dsh-cron-success)' }
3193
3257
  }, task.type === 'script' ? T_KEY(t, 'list.typeShell') : T_KEY(t, 'list.typeLlm')),
3194
- task.model ? React.createElement('span', { className: 'dsh-cron-task-model-tag' }, task.model.split('/').pop()) : null,
3195
- task.oneShot ? React.createElement('span', { className: 'dsh-cron-oneshot-tag' }, T_KEY(t, 'list.oneShot')) : null,
3196
- isConfigManaged(task) ? React.createElement('span', {
3258
+ task.model ? h('span', { className: 'dsh-cron-task-model-tag' }, task.model.split('/').pop()) : null,
3259
+ task.oneShot ? h('span', { className: 'dsh-cron-oneshot-tag' }, T_KEY(t, 'list.oneShot')) : null,
3260
+ isConfigManaged(task) ? h('span', {
3197
3261
  className: 'dsh-cron-config-tag',
3198
3262
  title: T_KEY(t, 'list.configManagedHint')
3199
3263
  }, T_KEY(t, 'list.configManaged')) : null,
3200
- task.lastDurationMs > 0 ? React.createElement('span', { className: 'dsh-cron-cost-tag', title: 'Last execution duration' }, task.lastDurationMs + 'ms') : null,
3201
- task.onSuccess ? React.createElement('span', { className: 'dsh-cron-type-tag dsh-cron-tag-success', title: 'On success: triggers ' + task.onSuccess }, '➜ ' + task.onSuccess) : null,
3202
- task.onFailure ? React.createElement('span', { className: 'dsh-cron-type-tag dsh-cron-tag-failure', title: 'On failure: triggers ' + task.onFailure }, '↳ ' + task.onFailure) : null,
3203
- (task.dependsOn && (Array.isArray(task.dependsOn) ? task.dependsOn.length > 0 : Boolean(task.dependsOn))) ? React.createElement('span', { className: 'dsh-cron-type-tag dsh-cron-tag-heartbeat', title: 'Depends on: ' + (Array.isArray(task.dependsOn) ? task.dependsOn.join(', ') : task.dependsOn) }, '⛓️ ' + (Array.isArray(task.dependsOn) ? task.dependsOn.join(', ') : task.dependsOn)) : null,
3204
- task.adaptive?.enabled ? React.createElement('span', {
3264
+ task.lastDurationMs > 0 ? h('span', { className: 'dsh-cron-cost-tag', title: 'Last execution duration' }, task.lastDurationMs + 'ms') : null,
3265
+ task.onSuccess ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-success', title: 'On success: triggers ' + task.onSuccess }, '➜ ' + task.onSuccess) : null,
3266
+ task.onFailure ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-failure', title: 'On failure: triggers ' + task.onFailure }, '↳ ' + task.onFailure) : null,
3267
+ (task.dependsOn && (Array.isArray(task.dependsOn) ? task.dependsOn.length > 0 : Boolean(task.dependsOn))) ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-heartbeat', title: 'Depends on: ' + (Array.isArray(task.dependsOn) ? task.dependsOn.join(', ') : task.dependsOn) }, '⛓️ ' + (Array.isArray(task.dependsOn) ? task.dependsOn.join(', ') : task.dependsOn)) : null,
3268
+ task.adaptive?.enabled ? h('span', {
3205
3269
  className: 'dsh-cron-type-tag' + (task.adaptiveState?.backedOff ? ' dsh-cron-tag-failure' : ' dsh-cron-tag-success'),
3206
3270
  title: 'Adaptive: ' + (task.adaptiveState?.effectiveIntervalStr || task.adaptive.minInterval || '5m') + ' (idle: ' + (task.adaptiveState?.idleCount || 0) + ')'
3207
3271
  }, (task.adaptiveState?.backedOff ? '⏳ ' : '⚡ ') + (task.adaptiveState?.effectiveIntervalStr || task.adaptive.minInterval || '5m')) : null,
3208
- task.heartbeatIntervalSeconds > 0 ? React.createElement('span', { className: 'dsh-cron-type-tag dsh-cron-tag-heartbeat', title: 'Heartbeat: every ' + task.heartbeatIntervalSeconds + 's' }, '💓 ' + task.heartbeatIntervalSeconds + 's') : null,
3209
- task.targetSessionId ? React.createElement('span', { className: 'dsh-cron-type-tag dsh-cron-tag-session', title: 'Target session: ' + task.targetSessionId + (task.targetSessionReset && task.targetSessionReset !== 'never' ? ' (' + task.targetSessionReset + ')' : '') }, '🧵 ' + task.targetSessionId) : null,
3210
- task.preflightType && task.preflightType !== 'none' ? React.createElement('span', { className: 'dsh-cron-type-tag dsh-cron-tag-preflight', title: 'Preflight: ' + task.preflightType }, '🛡️ ' + task.preflightType) : null,
3211
- task.totalCostUsd > 0 ? React.createElement('span', { className: 'dsh-cron-cost-tag' }, '$' + task.totalCostUsd.toFixed(4)) : null,
3212
- task.totalTokens > 0 ? React.createElement('span', { className: 'dsh-cron-tokens-tag' }, (task.totalTokens > 1000 ? Math.round(task.totalTokens / 1000) + 'k' : task.totalTokens) + ' tok') : null,
3213
- task.status === 'paused' && task.pausedReason ? React.createElement('span', { className: 'dsh-cron-type-tag dsh-cron-tag-failure', title: task.pausedReason }, '🛑 ' + task.pausedReason) : null
3214
- ),
3215
- React.createElement('div', { className: 'dsh-cron-task-sched' },
3272
+ task.heartbeatIntervalSeconds > 0 ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-heartbeat', title: 'Heartbeat: every ' + task.heartbeatIntervalSeconds + 's' }, '💓 ' + task.heartbeatIntervalSeconds + 's') : null,
3273
+ task.targetSessionId ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-session', title: 'Target session: ' + task.targetSessionId + (task.targetSessionReset && task.targetSessionReset !== 'never' ? ' (' + task.targetSessionReset + ')' : '') }, '🧵 ' + task.targetSessionId) : null,
3274
+ task.preflightType && task.preflightType !== 'none' ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-preflight', title: 'Preflight: ' + task.preflightType }, '🛡️ ' + task.preflightType) : null,
3275
+ task.totalCostUsd > 0 ? h('span', { className: 'dsh-cron-cost-tag' }, '$' + task.totalCostUsd.toFixed(4)) : null,
3276
+ task.totalTokens > 0 ? h('span', { className: 'dsh-cron-tokens-tag' }, (task.totalTokens > 1000 ? Math.round(task.totalTokens / 1000) + 'k' : task.totalTokens) + ' tok') : null,
3277
+ task.status === 'paused' && task.pausedReason ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-failure', title: task.pausedReason }, '🛑 ' + task.pausedReason) : null
3278
+ ),
3279
+ h('div', { className: 'dsh-cron-task-sched' },
3216
3280
  task.scheduleText || task.schedule,
3217
3281
  task.nextRunAt ? T_KEY(t, 'list.next', { time: new Date(task.nextRunAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }) : '',
3218
3282
  task.running && task.runningSince
3219
3283
  ? ' · ' + T_KEY(t, 'list.runningNow') + ' ' + Math.max(0, Math.round((Date.now() - task.runningSince) / 1000)) + 's'
3220
3284
  : ''
3221
3285
  ),
3222
- task.prompt ? React.createElement('div', {
3286
+ task.prompt ? h('div', {
3223
3287
  className: 'dsh-cron-task-prompt-preview',
3224
3288
  title: task.prompt
3225
3289
  }, task.prompt.slice(0, 140) + (task.prompt.length > 140 ? '…' : '')) : null
3226
3290
  ),
3227
- React.createElement('div', {
3291
+ h('div', {
3228
3292
  className: 'dsh-cron-task-actions',
3229
3293
  onClick: (e) => e.stopPropagation()
3230
3294
  },
3231
- React.createElement('button', {
3295
+ h('button', {
3232
3296
  type: 'button',
3233
3297
  className: 'dsh-cron-icon-btn',
3234
3298
  title: T_KEY(t, 'actions.dryRunTitle'),
3235
3299
  onClick: () => handleDryRun(task.id)
3236
3300
  }, '🧪'),
3237
- React.createElement('button', {
3301
+ h('button', {
3238
3302
  type: 'button',
3239
3303
  className: 'dsh-cron-icon-btn' + (task.running ? ' dsh-cron-pulse' : ''),
3240
3304
  title: T_KEY(t, 'liveLog.viewLog'),
3241
3305
  onClick: () => handleOpenLiveLogs(task)
3242
3306
  }, '📺'),
3243
- React.createElement('button', {
3307
+ h('button', {
3244
3308
  type: 'button',
3245
3309
  className: 'dsh-cron-icon-btn',
3246
3310
  title: T_KEY(t, 'actions.archiveTitle'),
3247
3311
  onClick: () => openArchiveModal(task, 0)
3248
3312
  }, '📜'),
3249
- (task.onSuccess || task.onFailure || (task.dependsOn && (Array.isArray(task.dependsOn) ? task.dependsOn.length > 0 : Boolean(task.dependsOn)))) ? React.createElement('button', {
3313
+ (task.onSuccess || task.onFailure || (task.dependsOn && (Array.isArray(task.dependsOn) ? task.dependsOn.length > 0 : Boolean(task.dependsOn)))) ? h('button', {
3250
3314
  type: 'button',
3251
3315
  className: 'dsh-cron-icon-btn',
3252
3316
  title: T_KEY(t, 'chainGraph.viewGraph'),
3253
3317
  onClick: () => openChainGraphModal(task)
3254
3318
  }, '🕸️') : null,
3255
- React.createElement('button', {
3319
+ h('button', {
3256
3320
  type: 'button',
3257
3321
  className: 'dsh-cron-icon-btn',
3258
3322
  title: T_KEY(t, 'actions.runNow'),
3259
3323
  onClick: () => handleRunNow(task.id)
3260
3324
  }, T_KEY(t, 'actions.runNowShort')),
3261
- isConfigManaged(task) ? null : React.createElement('button', {
3325
+ isConfigManaged(task) ? null : h('button', {
3262
3326
  type: 'button',
3263
3327
  className: 'dsh-cron-icon-btn',
3264
3328
  title: T_KEY(t, 'actions.edit'),
3265
3329
  'aria-label': T_KEY(t, 'actions.edit'),
3266
3330
  onClick: () => openEditModal(task)
3267
- }, React.createElement('span', svgProps(ICON_EDIT))),
3268
- isConfigManaged(task) ? null : React.createElement('button', {
3331
+ }, h('span', svgProps(ICON_EDIT))),
3332
+ isConfigManaged(task) ? null : h('button', {
3269
3333
  type: 'button',
3270
3334
  className: 'dsh-cron-icon-btn',
3271
3335
  title: T_KEY(t, 'actions.tuneWithDsh'),
3272
3336
  'aria-label': T_KEY(t, 'actions.tuneWithDsh'),
3273
3337
  onClick: () => handleTuneWithDsh(task)
3274
- }, React.createElement('span', svgProps(ICON_TUNE))),
3275
- isConfigManaged(task) ? null : React.createElement('button', {
3338
+ }, h('span', svgProps(ICON_TUNE))),
3339
+ isConfigManaged(task) ? null : h('button', {
3276
3340
  type: 'button',
3277
3341
  className: 'dsh-cron-icon-btn',
3278
3342
  title: T_KEY(t, 'actions.duplicate'),
3279
3343
  'aria-label': T_KEY(t, 'actions.duplicate'),
3280
3344
  onClick: () => handleDuplicate(task)
3281
- }, React.createElement('span', svgProps(ICON_COPY))),
3282
- isConfigManaged(task) ? null : React.createElement('button', {
3345
+ }, h('span', svgProps(ICON_COPY))),
3346
+ isConfigManaged(task) ? null : h('button', {
3283
3347
  type: 'button',
3284
3348
  className: 'dsh-cron-icon-btn dsh-cron-danger',
3285
3349
  title: T_KEY(t, 'actions.delete'),
3286
3350
  'aria-label': T_KEY(t, 'actions.delete'),
3287
3351
  onClick: () => handleDelete(task.id)
3288
- }, React.createElement('span', svgProps(ICON_TRASH)))
3352
+ }, h('span', svgProps(ICON_TRASH)))
3289
3353
  )
3290
3354
  )
3291
3355
  )
3292
3356
  ),
3293
- React.createElement('div', { className: 'dsh-cron-recs-title' }, T_KEY(t, 'recs.title')),
3294
- React.createElement('div', { className: 'dsh-cron-hint', style: { marginBottom: '8px' } }, T_KEY(t, 'recs.hint')),
3295
- React.createElement('div', { className: 'dsh-cron-recs-list' },
3357
+ h('div', { className: 'dsh-cron-recs-title' }, T_KEY(t, 'recs.title')),
3358
+ h('div', { className: 'dsh-cron-hint', style: { marginBottom: '8px' } }, T_KEY(t, 'recs.hint')),
3359
+ h('div', { className: 'dsh-cron-recs-list' },
3296
3360
  recs.map((rec) =>
3297
- React.createElement('div', {
3361
+ h('div', {
3298
3362
  key: rec.id,
3299
3363
  className: 'dsh-cron-rec-card',
3300
3364
  role: 'button',
@@ -3307,36 +3371,36 @@ openManualModal(rec);
3307
3371
  }
3308
3372
  }
3309
3373
  },
3310
- React.createElement('div', { className: 'dsh-cron-rec-icon' },
3311
- React.createElement('span', iconHtml(rec.icon === 'bell' ? ICON_BELL : rec.icon === 'clipboard' ? ICON_CLIPBOARD : ICON_ACTIVITY))
3374
+ h('div', { className: 'dsh-cron-rec-icon' },
3375
+ h('span', iconHtml(rec.icon === 'bell' ? ICON_BELL : rec.icon === 'clipboard' ? ICON_CLIPBOARD : ICON_ACTIVITY))
3312
3376
  ),
3313
- React.createElement('div', { className: 'dsh-cron-rec-content' },
3314
- React.createElement('div', { className: 'dsh-cron-rec-title' },
3377
+ h('div', { className: 'dsh-cron-rec-content' },
3378
+ h('div', { className: 'dsh-cron-rec-title' },
3315
3379
  rec.title,
3316
- React.createElement('span', { className: 'dsh-cron-rec-time' }, rec.scheduleText)
3380
+ h('span', { className: 'dsh-cron-rec-time' }, rec.scheduleText)
3317
3381
  ),
3318
- React.createElement('div', { className: 'dsh-cron-rec-desc' }, rec.description)
3382
+ h('div', { className: 'dsh-cron-rec-desc' }, rec.description)
3319
3383
  )
3320
3384
  )
3321
3385
  )
3322
3386
  )
3323
3387
  ),
3324
- manualModalOpen && React.createElement('div', {
3388
+ manualModalOpen && h('div', {
3325
3389
  className: 'dsh-cron-modal-overlay',
3326
3390
  onClick: (e) => {
3327
3391
  if (e.target === e.currentTarget) closeManualModalWithConfirm();
3328
3392
  }
3329
3393
  },
3330
- React.createElement('div', {
3394
+ h('div', {
3331
3395
  className: 'dsh-cron-modal dsh-cron-modal-scroll',
3332
3396
  style: { maxWidth: '640px' },
3333
3397
  role: 'dialog',
3334
3398
  'aria-modal': 'true',
3335
3399
  onClick: (e) => e.stopPropagation()
3336
3400
  },
3337
- React.createElement('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: formId ? '12px' : '18px' } },
3338
- React.createElement('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, formId ? T_KEY(t, 'modal.editTitle') : T_KEY(t, 'modal.newTitle')),
3339
- selectedTaskMeta && React.createElement('span', {
3401
+ h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: formId ? '12px' : '18px' } },
3402
+ h('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, formId ? T_KEY(t, 'modal.editTitle') : T_KEY(t, 'modal.newTitle')),
3403
+ selectedTaskMeta && h('span', {
3340
3404
  style: {
3341
3405
  fontSize: '12px',
3342
3406
  padding: '3px 8px',
@@ -3346,65 +3410,65 @@ color: selectedTaskMeta.status === 'active' ? 'var(--dsh-cron-success)' : 'var(-
3346
3410
  }
3347
3411
  }, selectedTaskMeta.status === 'active' ? T_KEY(t, 'modal.statusActive') : T_KEY(t, 'modal.statusPaused'))
3348
3412
  ),
3349
- formId && React.createElement('div', { className: 'dsh-cron-modal-nav' },
3350
- React.createElement('button', {
3413
+ formId && h('div', { className: 'dsh-cron-modal-nav' },
3414
+ h('button', {
3351
3415
  type: 'button',
3352
3416
  className: 'dsh-cron-modal-tab',
3353
3417
  'data-active': modalTab === 'params' ? 'true' : undefined,
3354
3418
  onClick: () => setModalTab('params')
3355
3419
  }, T_KEY(t, 'modal.params')),
3356
- React.createElement('button', {
3420
+ h('button', {
3357
3421
  type: 'button',
3358
3422
  className: 'dsh-cron-modal-tab',
3359
3423
  'data-active': modalTab === 'history' ? 'true' : undefined,
3360
3424
  onClick: () => { setModalTab('history'); if (formId) loadTaskHistory(formId); }
3361
3425
  }, T_KEY(t, 'modal.history', { count: taskHistory.length || 0 }))
3362
3426
  ),
3363
- modalTab === 'history' && formId ? React.createElement('div', null,
3364
- historyLoading ? React.createElement('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.loading')) :
3365
- taskHistory.length === 0 ? React.createElement('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.empty')) :
3366
- React.createElement('div', { className: 'dsh-cron-history-list' },
3367
- taskHistory.map((run) => React.createElement('div', { key: run.id, className: 'dsh-cron-history-item' },
3368
- React.createElement('div', { className: 'dsh-cron-history-head' },
3369
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
3370
- React.createElement('span', {
3427
+ modalTab === 'history' && formId ? h('div', null,
3428
+ historyLoading ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.loading')) :
3429
+ taskHistory.length === 0 ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.empty')) :
3430
+ h('div', { className: 'dsh-cron-history-list' },
3431
+ taskHistory.map((run) => h('div', { key: run.id, className: 'dsh-cron-history-item' },
3432
+ h('div', { className: 'dsh-cron-history-head' },
3433
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
3434
+ h('span', {
3371
3435
  className: 'dsh-cron-history-status',
3372
3436
  'data-status': run.status
3373
3437
  }, statusLabel(t, run.status)),
3374
- React.createElement('span', { className: 'dsh-cron-history-time' }, run.at ? new Date(run.at).toLocaleString() : '')
3438
+ h('span', { className: 'dsh-cron-history-time' }, run.at ? new Date(run.at).toLocaleString() : '')
3375
3439
  ),
3376
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
3377
- run.costUsd > 0 && React.createElement('span', { className: 'dsh-cron-cost-tag' }, '$' + run.costUsd.toFixed(5)),
3378
- run.usage && (run.usage.inputTokens > 0 || run.usage.outputTokens > 0) && React.createElement('span', { className: 'dsh-cron-tokens-tag' }, (run.usage.inputTokens + run.usage.outputTokens) + ' tok'),
3379
- React.createElement('span', { style: { color: 'var(--dsw-alias-label-tertiary, #888)', fontSize: '11.5px' } }, (run.durationMs || 0) + ' ms')
3440
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
3441
+ run.costUsd > 0 && h('span', { className: 'dsh-cron-cost-tag' }, '$' + run.costUsd.toFixed(5)),
3442
+ run.usage && (run.usage.inputTokens > 0 || run.usage.outputTokens > 0) && h('span', { className: 'dsh-cron-tokens-tag' }, (run.usage.inputTokens + run.usage.outputTokens) + ' tok'),
3443
+ h('span', { style: { color: 'var(--dsw-alias-label-tertiary, #888)', fontSize: '11.5px' } }, (run.durationMs || 0) + ' ms')
3380
3444
  )
3381
3445
  ),
3382
- run.stoppedReason && React.createElement('div', {
3446
+ run.stoppedReason && h('div', {
3383
3447
  className: 'dsh-cron-hint',
3384
3448
  style: { display: 'flex', gap: '6px', alignItems: 'center', marginTop: '6px' }
3385
3449
  },
3386
- React.createElement('span', { className: 'dsh-cron-badge-ref' }, T_KEY(t, 'history.stoppedReasonTitle')),
3387
- React.createElement('span', null, run.stoppedReason)
3450
+ h('span', { className: 'dsh-cron-badge-ref' }, T_KEY(t, 'history.stoppedReasonTitle')),
3451
+ h('span', null, run.stoppedReason)
3388
3452
  ),
3389
- Array.isArray(run.stages) && run.stages.length > 0 && React.createElement('div', {
3453
+ Array.isArray(run.stages) && run.stages.length > 0 && h('div', {
3390
3454
  className: 'dsh-cron-stages-flow',
3391
3455
  style: { display: 'flex', gap: '6px', flexWrap: 'wrap', marginTop: '6px' }
3392
3456
  },
3393
- run.stages.map((st) => React.createElement('span', {
3457
+ run.stages.map((st) => h('span', {
3394
3458
  key: st.name,
3395
3459
  className: 'dsh-cron-stage-pill',
3396
3460
  'data-status': st.status || 'unknown',
3397
3461
  title: st.error ? (st.name + ': ' + st.error) : (st.name + (st.durationMs !== undefined ? ' (' + st.durationMs + 'ms)' : ''))
3398
3462
  }, (T_KEY(t, 'history.stage_' + st.name) || st.name) + (st.durationMs !== undefined ? ' ' + st.durationMs + 'ms' : '')))
3399
3463
  ),
3400
- run.delivery && React.createElement('div', {
3464
+ run.delivery && h('div', {
3401
3465
  style: { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '6px' }
3402
3466
  },
3403
- React.createElement('span', {
3467
+ h('span', {
3404
3468
  className: 'dsh-cron-badge-ref',
3405
3469
  'data-status': run.delivery.status
3406
3470
  }, 'Delivery: ' + run.delivery.status),
3407
- (run.delivery.status === 'failed' || run.delivery.status === 'partial') && React.createElement('button', {
3471
+ (run.delivery.status === 'failed' || run.delivery.status === 'partial') && h('button', {
3408
3472
  type: 'button',
3409
3473
  className: 'dsh-cron-btn-secondary',
3410
3474
  style: { padding: '2px 8px', fontSize: '11px' },
@@ -3412,11 +3476,11 @@ disabled: retryingDeliveryId === run.id,
3412
3476
  onClick: () => handleRetryDelivery(formId, run.id)
3413
3477
  }, retryingDeliveryId === run.id ? T_KEY(t, 'history.retryingDelivery') : T_KEY(t, 'history.retryDelivery'))
3414
3478
  ),
3415
- run.artifacts && run.artifacts.length > 0 && React.createElement('div', {
3479
+ run.artifacts && run.artifacts.length > 0 && h('div', {
3416
3480
  style: { display: 'flex', flexWrap: 'wrap', gap: '6px', marginTop: '6px', alignItems: 'center' }
3417
3481
  },
3418
- React.createElement('span', { className: 'dsh-cron-hint', style: { fontSize: '11px' } }, '📦 ' + T_KEY(t, 'history.artifacts') + ':'),
3419
- run.artifacts.map((art) => React.createElement('a', {
3482
+ h('span', { className: 'dsh-cron-hint', style: { fontSize: '11px' } }, '📦 ' + T_KEY(t, 'history.artifacts') + ':'),
3483
+ run.artifacts.map((art) => h('a', {
3420
3484
  key: art.name || art.id,
3421
3485
  href: '/dsh-cron/runs/' + encodeURIComponent(run.id) + '/artifacts/' + encodeURIComponent(art.name) + '/preview',
3422
3486
  target: '_blank',
@@ -3426,20 +3490,20 @@ style: { padding: '2px 8px', fontSize: '11px', textDecoration: 'none' },
3426
3490
  title: art.name + ' (' + Math.round((art.size || 0) / 1024 * 10) / 10 + ' KB)'
3427
3491
  }, art.name))
3428
3492
  ),
3429
- run.status === 'uncertain' && React.createElement('div', {
3493
+ run.status === 'uncertain' && h('div', {
3430
3494
  className: 'dsh-cron-status-banner',
3431
3495
  'data-type': 'warning',
3432
3496
  style: { marginTop: '8px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '8px' }
3433
3497
  },
3434
- React.createElement('span', null, '⚠️ ' + T_KEY(t, 'history.statusUncertainHint')),
3435
- React.createElement('div', { style: { display: 'flex', gap: '6px' } },
3436
- React.createElement('button', {
3498
+ h('span', null, '⚠️ ' + T_KEY(t, 'history.statusUncertainHint')),
3499
+ h('div', { style: { display: 'flex', gap: '6px' } },
3500
+ h('button', {
3437
3501
  type: 'button',
3438
3502
  className: 'dsh-cron-btn-secondary',
3439
3503
  style: { padding: '2px 8px', fontSize: '11px' },
3440
3504
  onClick: () => handleResolveUncertain(formId, run.id, 'completed')
3441
3505
  }, '✓ ' + T_KEY(t, 'history.resolveCompleted')),
3442
- React.createElement('button', {
3506
+ h('button', {
3443
3507
  type: 'button',
3444
3508
  className: 'dsh-cron-btn-secondary',
3445
3509
  style: { padding: '2px 8px', fontSize: '11px' },
@@ -3447,35 +3511,141 @@ onClick: () => handleResolveUncertain(formId, run.id, 'failed')
3447
3511
  }, '✕ ' + T_KEY(t, 'history.resolveFailed'))
3448
3512
  )
3449
3513
  ),
3450
- run.diagnosis && React.createElement('div', {
3514
+ (run.diagnosis || run.doctorReport) && h('div', {
3451
3515
  className: 'dsh-cron-status-banner',
3452
3516
  'data-type': 'info',
3453
3517
  style: { marginTop: '8px', display: 'flex', flexDirection: 'column', gap: '6px' }
3454
3518
  },
3455
- React.createElement('div', null,
3456
- React.createElement('strong', null, T_KEY(t, 'history.diagnosis')),
3457
- run.confidence ? ` (${run.confidence})` : ''
3519
+ h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
3520
+ h('strong', null, '🩺 ' + T_KEY(t, run.doctorReport ? 'history.doctorDiagnosis' : 'history.diagnosis')),
3521
+ h('div', { style: { display: 'flex', gap: '6px', alignItems: 'center' } },
3522
+ (run.autoHealed || run.doctorReport?.autoHealed) && h('span', {
3523
+ style: { fontSize: '10px', background: 'var(--dsh-cron-success-bg)', color: 'var(--dsh-cron-success)', padding: '1px 6px', borderRadius: '8px', fontWeight: '600' }
3524
+ }, '✨ ' + T_KEY(t, 'history.autoHealed')),
3525
+ (run.doctorReport?.category || run.category) && h('span', {
3526
+ style: { fontSize: '10px', background: 'var(--dsw-alias-bg-layer-3)', padding: '1px 6px', borderRadius: '4px' }
3527
+ }, run.doctorReport?.category || run.category),
3528
+ run.confidence ? h('span', { style: { fontSize: '10px', color: 'var(--dsw-alias-label-secondary)' } }, '(' + run.confidence + ')') : null
3529
+ )
3458
3530
  ),
3459
- React.createElement('div', null, run.diagnosis),
3460
- run.suggestion && React.createElement('div', null,
3461
- React.createElement('button', {
3531
+ h('div', null, run.doctorReport?.cause || run.diagnosis),
3532
+ run.doctorReport?.diff && h('div', {
3533
+ style: {
3534
+ background: 'var(--dsw-alias-bg-layer-2)',
3535
+ border: '1px solid var(--dsw-alias-border-l2)',
3536
+ borderRadius: '4px',
3537
+ padding: '6px',
3538
+ fontFamily: 'monospace',
3539
+ fontSize: '11px',
3540
+ maxHeight: '120px',
3541
+ overflowY: 'auto',
3542
+ whiteSpace: 'pre'
3543
+ }
3544
+ }, run.doctorReport.diff),
3545
+ (run.doctorReport?.suggestedFix || run.suggestion) && h('div', { style: { display: 'flex', gap: '8px', marginTop: '4px' } },
3546
+ typeof handleApplyDoctorFix === 'function' && h('button', {
3547
+ type: 'button',
3548
+ className: 'dsh-cron-btn-primary',
3549
+ style: { padding: '3px 10px', fontSize: '12px' },
3550
+ onClick: () => handleApplyDoctorFix(formId, run.doctorReport || { suggestedFix: run.suggestion })
3551
+ }, '⚡ ' + T_KEY(t, 'history.doctorApply')),
3552
+ h('button', {
3462
3553
  type: 'button',
3463
3554
  className: 'dsh-cron-btn-secondary',
3464
- style: { padding: '2px 8px', fontSize: '12px' },
3555
+ style: { padding: '3px 10px', fontSize: '12px' },
3465
3556
  onClick: () => openEditModal(selectedTaskMeta, { prompt: run.suggestion })
3466
3557
  }, T_KEY(t, 'history.applySuggestion'))
3467
3558
  )
3468
3559
  ),
3469
- run.silentSkip && React.createElement('div', {
3560
+ run.subtaskRuns && Array.isArray(run.subtaskRuns) && run.subtaskRuns.length > 0 && h('div', {
3561
+ style: { marginTop: '8px', padding: '8px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: '6px', fontSize: '12px' }
3562
+ },
3563
+ h('div', { style: { fontWeight: '600', marginBottom: '4px' } }, '🐝 ' + T_KEY(t, 'history.swarmBadge') + ' (' + run.subtaskRuns.filter(r => r.status === 'success').length + '/' + run.subtaskRuns.length + ')'),
3564
+ h('div', { style: { display: 'flex', flexDirection: 'column', gap: '4px' } },
3565
+ run.subtaskRuns.map((st, sidx) => h('div', {
3566
+ key: sidx,
3567
+ style: { display: 'flex', justifyContent: 'space-between', padding: '2px 6px', background: 'var(--dsw-alias-bg-layer-3)', borderRadius: '4px' }
3568
+ },
3569
+ h('span', null, (st.status === 'success' ? '✅ ' : '❌ ') + st.title),
3570
+ h('span', { style: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '11px' } }, (st.durationMs || 0) + 'ms')
3571
+ ))
3572
+ )
3573
+ ),
3574
+ run.gitDiff && run.gitDiff.hasChanges && h('div', {
3575
+ className: 'dsh-cron-status-banner',
3576
+ style: { marginTop: '8px', display: 'flex', flexDirection: 'column', gap: '6px' }
3577
+ },
3578
+ h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
3579
+ h('strong', null, '📝 ' + T_KEY(t, 'history.gitDiff')),
3580
+ h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary)' } }, run.gitDiff.stat || '')
3581
+ ),
3582
+ run.gitDiff.diff && h('div', {
3583
+ style: {
3584
+ background: 'var(--dsw-alias-bg-layer-2)',
3585
+ border: '1px solid var(--dsw-alias-border-l2)',
3586
+ borderRadius: '4px',
3587
+ padding: '6px',
3588
+ fontFamily: 'monospace',
3589
+ fontSize: '11px',
3590
+ maxHeight: '140px',
3591
+ overflowY: 'auto',
3592
+ whiteSpace: 'pre'
3593
+ }
3594
+ }, run.gitDiff.diff),
3595
+ h('div', { style: { display: 'flex', gap: '8px', marginTop: '4px' } },
3596
+ h('button', {
3597
+ type: 'button',
3598
+ className: 'dsh-cron-btn-secondary',
3599
+ style: { padding: '2px 8px', fontSize: '12px' },
3600
+ onClick: async () => {
3601
+ if (!confirm('Discard all uncommitted changes in task directory?')) return;
3602
+ const c = typeof AbortController !== 'undefined' ? new AbortController() : null;
3603
+ const tId = c ? setTimeout(() => c.abort(), 15000) : null;
3604
+ try {
3605
+ const res = await fetch('/dsh-cron/tasks/' + encodeURIComponent(formId) + '/git-diff/discard', {
3606
+ method: 'POST',
3607
+ signal: c ? c.signal : undefined
3608
+ });
3609
+ const d = await res.json();
3610
+ if (d.ok) { alert('Working directory reset successfully.'); if (formId) loadTaskHistory(formId); }
3611
+ else alert(d.error || 'Failed to discard changes');
3612
+ } catch (e) { alert(e.message); }
3613
+ finally { if (tId) clearTimeout(tId); }
3614
+ }
3615
+ }, '🗑️ ' + T_KEY(t, 'history.discardDiff')),
3616
+ h('button', {
3617
+ type: 'button',
3618
+ className: 'dsh-cron-btn-primary',
3619
+ style: { padding: '2px 8px', fontSize: '12px' },
3620
+ onClick: async () => {
3621
+ const c = typeof AbortController !== 'undefined' ? new AbortController() : null;
3622
+ const tId = c ? setTimeout(() => c.abort(), 15000) : null;
3623
+ try {
3624
+ const res = await fetch('/dsh-cron/tasks/' + encodeURIComponent(formId) + '/git-diff/apply', {
3625
+ method: 'POST',
3626
+ headers: { 'Content-Type': 'application/json' },
3627
+ signal: c ? c.signal : undefined,
3628
+ body: JSON.stringify({ diff: run.gitDiff.diff })
3629
+ });
3630
+ const d = await res.json();
3631
+ if (d.ok) { alert('Patch applied successfully.'); if (formId) loadTaskHistory(formId); }
3632
+ else alert(d.error || 'Failed to apply patch');
3633
+ } catch (e) { alert(e.message); }
3634
+ finally { if (tId) clearTimeout(tId); }
3635
+ }
3636
+ }, '✅ ' + T_KEY(t, 'history.applyDiff'))
3637
+ )
3638
+ ),
3639
+ run.silentSkip && h('div', {
3470
3640
  className: 'dsh-cron-hint',
3471
3641
  style: { display: 'flex', gap: '6px', alignItems: 'center' }
3472
3642
  },
3473
- React.createElement('span', { className: 'dsh-cron-badge-ref' }, T_KEY(t, 'history.silentSkip')),
3474
- React.createElement('span', null, run.silentReason || '')
3643
+ h('span', { className: 'dsh-cron-badge-ref' }, T_KEY(t, 'history.silentSkip')),
3644
+ h('span', null, run.silentReason || '')
3475
3645
  ),
3476
- run.output && React.createElement('div', { className: 'dsh-cron-history-output' }, run.output),
3477
- run.error && React.createElement('div', { className: 'dsh-cron-history-output', style: { color: 'var(--dsh-cron-danger)', borderColor: 'var(--dsh-cron-danger-bg)' } }, run.error),
3478
- run.sessionId && React.createElement('button', {
3646
+ run.output && h('div', { className: 'dsh-cron-history-output' }, run.output),
3647
+ run.error && h('div', { className: 'dsh-cron-history-output', style: { color: 'var(--dsh-cron-danger)', borderColor: 'var(--dsh-cron-danger-bg)' } }, run.error),
3648
+ run.sessionId && h('button', {
3479
3649
  type: 'button',
3480
3650
  className: 'dsh-cron-btn-secondary',
3481
3651
  style: { marginTop: '8px', fontSize: '12px', padding: '4px 10px' },
@@ -3483,23 +3653,23 @@ onClick: () => openSession(ctx, run.sessionId)
3483
3653
  }, T_KEY(t, 'history.openSession'))
3484
3654
  ))
3485
3655
  ),
3486
- React.createElement('div', { className: 'dsh-cron-modal-foot', style: { marginTop: '18px' } },
3487
- React.createElement('button', {
3656
+ h('div', { className: 'dsh-cron-modal-foot', style: { marginTop: '18px' } },
3657
+ h('button', {
3488
3658
  type: 'button',
3489
3659
  className: 'dsh-cron-btn-secondary',
3490
3660
  onClick: () => { if (formId) loadTaskHistory(formId); }
3491
3661
  }, T_KEY(t, 'history.refresh')),
3492
- React.createElement('button', {
3662
+ h('button', {
3493
3663
  type: 'button',
3494
3664
  className: 'dsh-cron-btn-primary',
3495
3665
  onClick: closeManualModalWithConfirm
3496
3666
  }, T_KEY(t, 'modal.close'))
3497
3667
  )
3498
3668
  ) :
3499
- React.createElement('form', { onSubmit: handleSaveManual },
3500
- React.createElement('div', { className: 'dsh-cron-form-group' },
3501
- React.createElement('label', null, T_KEY(t, 'form.nameLabel')),
3502
- React.createElement('input', {
3669
+ h('form', { onSubmit: handleSaveManual },
3670
+ h('div', { className: 'dsh-cron-form-group' },
3671
+ h('label', null, T_KEY(t, 'form.nameLabel')),
3672
+ h('input', {
3503
3673
  required: true,
3504
3674
  autoFocus: true,
3505
3675
  value: formTitle,
@@ -3507,40 +3677,40 @@ placeholder: T_KEY(t, 'form.namePlaceholder'),
3507
3677
  onChange: (e) => setFormTitle(e.target.value)
3508
3678
  })
3509
3679
  ),
3510
- React.createElement('div', { className: 'dsh-cron-form-row' },
3511
- React.createElement('div', { className: 'dsh-cron-form-group' },
3512
- React.createElement('label', null, T_KEY(t, 'form.typeLabel')),
3513
- React.createElement('select', {
3680
+ h('div', { className: 'dsh-cron-form-row' },
3681
+ h('div', { className: 'dsh-cron-form-group' },
3682
+ h('label', null, T_KEY(t, 'form.typeLabel')),
3683
+ h('select', {
3514
3684
  value: formType,
3515
3685
  onChange: (e) => setFormType(e.target.value)
3516
3686
  },
3517
- React.createElement('option', { value: 'llm' }, T_KEY(t, 'form.typeLlm')),
3518
- React.createElement('option', { value: 'script' }, T_KEY(t, 'form.typeScript')),
3519
- React.createElement('option', { value: 'node' }, T_KEY(t, 'form.typeNode')),
3520
- React.createElement('option', { value: 'python' }, T_KEY(t, 'form.typePython')),
3521
- React.createElement('option', { value: 'http' }, T_KEY(t, 'form.typeHttp')),
3522
- React.createElement('option', { value: 'ssh' }, T_KEY(t, 'form.typeSsh')),
3523
- React.createElement('option', { value: 'docker' }, T_KEY(t, 'form.typeDocker')),
3524
- React.createElement('option', { value: 'skill' }, T_KEY(t, 'form.typeSkill')),
3525
- React.createElement('option', { value: 'workflow' }, T_KEY(t, 'form.typeWorkflow'))
3687
+ h('option', { value: 'llm' }, T_KEY(t, 'form.typeLlm')),
3688
+ h('option', { value: 'script' }, T_KEY(t, 'form.typeScript')),
3689
+ h('option', { value: 'node' }, T_KEY(t, 'form.typeNode')),
3690
+ h('option', { value: 'python' }, T_KEY(t, 'form.typePython')),
3691
+ h('option', { value: 'http' }, T_KEY(t, 'form.typeHttp')),
3692
+ h('option', { value: 'ssh' }, T_KEY(t, 'form.typeSsh')),
3693
+ h('option', { value: 'docker' }, T_KEY(t, 'form.typeDocker')),
3694
+ h('option', { value: 'skill' }, T_KEY(t, 'form.typeSkill')),
3695
+ h('option', { value: 'workflow' }, T_KEY(t, 'form.typeWorkflow'))
3526
3696
  )
3527
3697
  ),
3528
- React.createElement('div', { className: 'dsh-cron-form-group' },
3529
- React.createElement('label', null, T_KEY(t, 'form.scheduleLabel')),
3530
- React.createElement('input', {
3698
+ h('div', { className: 'dsh-cron-form-group' },
3699
+ h('label', null, T_KEY(t, 'form.scheduleLabel')),
3700
+ h('input', {
3531
3701
  required: true,
3532
3702
  value: formSchedule,
3533
3703
  placeholder: T_KEY(t, 'form.schedulePlaceholder'),
3534
3704
  onChange: (e) => setFormSchedule(e.target.value)
3535
3705
  }),
3536
- React.createElement('div', { style: { display: 'flex', gap: '5px', flexWrap: 'wrap', marginTop: '5px' } },
3706
+ h('div', { style: { display: 'flex', gap: '5px', flexWrap: 'wrap', marginTop: '5px' } },
3537
3707
  [
3538
3708
  { label: '15m', expr: '*/15 * * * *' },
3539
3709
  { label: '1h', expr: '0 * * * *' },
3540
3710
  { label: 'Daily 09:00', expr: '0 9 * * *' },
3541
3711
  { label: 'Weekdays', expr: '0 9 * * 1-5' },
3542
3712
  { label: 'Weekly Mon', expr: '0 9 * * 1' },
3543
- ].map((p) => React.createElement('button', {
3713
+ ].map((p) => h('button', {
3544
3714
  key: p.label,
3545
3715
  type: 'button',
3546
3716
  className: 'dsh-cron-btn-secondary',
@@ -3548,23 +3718,23 @@ style: { padding: '2px 7px', fontSize: '11px', borderRadius: '4px' },
3548
3718
  onClick: () => { setFormSchedule(p.expr); handlePreviewSchedule(p.expr); }
3549
3719
  }, p.label))
3550
3720
  ),
3551
- React.createElement('div', { style: { display: 'flex', gap: '8px', alignItems: 'center', marginTop: '6px' } },
3552
- React.createElement('button', {
3721
+ h('div', { style: { display: 'flex', gap: '8px', alignItems: 'center', marginTop: '6px' } },
3722
+ h('button', {
3553
3723
  type: 'button',
3554
3724
  className: 'dsh-cron-btn-secondary',
3555
3725
  style: { padding: '3px 8px', fontSize: '11.5px' },
3556
3726
  onClick: () => handlePreviewSchedule(formSchedule)
3557
3727
  }, T_KEY(t, 'form.previewSchedule')),
3558
- schedulePreviewRuns && schedulePreviewRuns.length > 0 && React.createElement('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #999)' } },
3728
+ schedulePreviewRuns && schedulePreviewRuns.length > 0 && h('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #999)' } },
3559
3729
  T_KEY(t, 'form.previewScheduleTitle') + ' ' + schedulePreviewRuns.slice(0, 3).map(r => new Date(r).toLocaleTimeString()).join(', ')
3560
3730
  )
3561
3731
  )
3562
3732
  )
3563
3733
  ),
3564
- React.createElement('div', { className: 'dsh-cron-form-row' },
3565
- React.createElement('div', { className: 'dsh-cron-form-group' },
3566
- React.createElement('label', null, T_KEY(t, 'form.timeoutLabel')),
3567
- React.createElement('input', {
3734
+ h('div', { className: 'dsh-cron-form-row' },
3735
+ h('div', { className: 'dsh-cron-form-group' },
3736
+ h('label', null, T_KEY(t, 'form.timeoutLabel')),
3737
+ h('input', {
3568
3738
  type: 'number',
3569
3739
  min: 1,
3570
3740
  value: formTimeoutSeconds,
@@ -3572,44 +3742,44 @@ placeholder: '1800',
3572
3742
  onChange: (e) => setFormTimeoutSeconds(e.target.value)
3573
3743
  })
3574
3744
  ),
3575
- React.createElement('div', { className: 'dsh-cron-form-group' },
3576
- React.createElement('label', null, T_KEY(t, 'form.overlapLabel')),
3577
- React.createElement('select', {
3745
+ h('div', { className: 'dsh-cron-form-group' },
3746
+ h('label', null, T_KEY(t, 'form.overlapLabel')),
3747
+ h('select', {
3578
3748
  value: formOverlapPolicy,
3579
3749
  onChange: (e) => setFormOverlapPolicy(e.target.value)
3580
3750
  },
3581
- React.createElement('option', { value: 'skip' }, T_KEY(t, 'form.overlapSkip')),
3582
- React.createElement('option', { value: 'queue' }, T_KEY(t, 'form.overlapQueue')),
3583
- React.createElement('option', { value: 'replace' }, T_KEY(t, 'form.overlapReplace'))
3751
+ h('option', { value: 'skip' }, T_KEY(t, 'form.overlapSkip')),
3752
+ h('option', { value: 'queue' }, T_KEY(t, 'form.overlapQueue')),
3753
+ h('option', { value: 'replace' }, T_KEY(t, 'form.overlapReplace'))
3584
3754
  )
3585
3755
  )
3586
3756
  ),
3587
- React.createElement('div', { className: 'dsh-cron-form-row' },
3588
- React.createElement('div', { className: 'dsh-cron-form-group' },
3589
- React.createElement('label', null, T_KEY(t, 'form.timezoneLabel')),
3590
- React.createElement('input', {
3757
+ h('div', { className: 'dsh-cron-form-row' },
3758
+ h('div', { className: 'dsh-cron-form-group' },
3759
+ h('label', null, T_KEY(t, 'form.timezoneLabel')),
3760
+ h('input', {
3591
3761
  value: formTimezone,
3592
3762
  placeholder: T_KEY(t, 'form.timezonePlaceholder'),
3593
3763
  onChange: (e) => setFormTimezone(e.target.value)
3594
3764
  })
3595
3765
  ),
3596
- React.createElement('div', { className: 'dsh-cron-form-group' },
3597
- React.createElement('label', null, T_KEY(t, 'form.misfireLabel')),
3598
- React.createElement('select', {
3766
+ h('div', { className: 'dsh-cron-form-group' },
3767
+ h('label', null, T_KEY(t, 'form.misfireLabel')),
3768
+ h('select', {
3599
3769
  value: formMisfirePolicy,
3600
3770
  onChange: (e) => setFormMisfirePolicy(e.target.value)
3601
3771
  },
3602
- React.createElement('option', { value: 'skip' }, T_KEY(t, 'form.misfireSkip')),
3603
- React.createElement('option', { value: 'runOnce' }, T_KEY(t, 'form.misfireRunOnce')),
3604
- React.createElement('option', { value: 'catchUpAll' }, T_KEY(t, 'form.misfireCatchUp'))
3772
+ h('option', { value: 'skip' }, T_KEY(t, 'form.misfireSkip')),
3773
+ h('option', { value: 'runOnce' }, T_KEY(t, 'form.misfireRunOnce')),
3774
+ h('option', { value: 'catchUpAll' }, T_KEY(t, 'form.misfireCatchUp'))
3605
3775
  )
3606
3776
  )
3607
3777
  ),
3608
3778
  AGENT_FORM_TYPES.includes(formType) ? (
3609
- React.createElement('div', { className: 'dsh-cron-form-row' },
3610
- React.createElement('div', { className: 'dsh-cron-form-group' },
3611
- React.createElement('label', null, T_KEY(t, 'form.retriesLabel')),
3612
- React.createElement('input', {
3779
+ h('div', { className: 'dsh-cron-form-row' },
3780
+ h('div', { className: 'dsh-cron-form-group' },
3781
+ h('label', null, T_KEY(t, 'form.retriesLabel')),
3782
+ h('input', {
3613
3783
  type: 'number',
3614
3784
  min: 0,
3615
3785
  value: formMaxRetries,
@@ -3617,23 +3787,23 @@ placeholder: '0',
3617
3787
  onChange: (e) => setFormMaxRetries(e.target.value)
3618
3788
  })
3619
3789
  ),
3620
- React.createElement('div', { className: 'dsh-cron-form-group' },
3621
- React.createElement('label', null, T_KEY(t, 'form.permissionLabel')),
3622
- React.createElement('select', {
3790
+ h('div', { className: 'dsh-cron-form-group' },
3791
+ h('label', null, T_KEY(t, 'form.permissionLabel')),
3792
+ h('select', {
3623
3793
  value: formPermissionPreset,
3624
3794
  onChange: (e) => setFormPermissionPreset(e.target.value)
3625
3795
  },
3626
- React.createElement('option', { value: 'default' }, T_KEY(t, 'form.permissionDefault')),
3627
- React.createElement('option', { value: 'read-only' }, T_KEY(t, 'form.permissionReadonly')),
3628
- React.createElement('option', { value: 'workspace-write' }, T_KEY(t, 'form.permissionWrite')),
3629
- React.createElement('option', { value: 'full' }, T_KEY(t, 'form.permissionFull'))
3796
+ h('option', { value: 'default' }, T_KEY(t, 'form.permissionDefault')),
3797
+ h('option', { value: 'read-only' }, T_KEY(t, 'form.permissionReadonly')),
3798
+ h('option', { value: 'workspace-write' }, T_KEY(t, 'form.permissionWrite')),
3799
+ h('option', { value: 'full' }, T_KEY(t, 'form.permissionFull'))
3630
3800
  )
3631
3801
  )
3632
3802
  )
3633
3803
  ) : (
3634
- React.createElement('div', { className: 'dsh-cron-form-group' },
3635
- React.createElement('label', null, T_KEY(t, 'form.retriesLabel')),
3636
- React.createElement('input', {
3804
+ h('div', { className: 'dsh-cron-form-group' },
3805
+ h('label', null, T_KEY(t, 'form.retriesLabel')),
3806
+ h('input', {
3637
3807
  type: 'number',
3638
3808
  min: 0,
3639
3809
  value: formMaxRetries,
@@ -3642,114 +3812,114 @@ onChange: (e) => setFormMaxRetries(e.target.value)
3642
3812
  })
3643
3813
  )
3644
3814
  ),
3645
- React.createElement('div', { className: 'dsh-cron-form-group' },
3646
- React.createElement('label', null, T_KEY(t, 'form.kanbanLabel')),
3647
- React.createElement('select', {
3815
+ h('div', { className: 'dsh-cron-form-group' },
3816
+ h('label', null, T_KEY(t, 'form.kanbanLabel')),
3817
+ h('select', {
3648
3818
  value: formKanbanMode,
3649
3819
  onChange: (e) => setFormKanbanMode(e.target.value)
3650
3820
  },
3651
- React.createElement('option', { value: 'none' }, T_KEY(t, 'form.kanbanNone')),
3652
- React.createElement('option', { value: 'on_failure' }, T_KEY(t, 'form.kanbanOnFailure')),
3653
- React.createElement('option', { value: 'always' }, T_KEY(t, 'form.kanbanAlways'))
3821
+ h('option', { value: 'none' }, T_KEY(t, 'form.kanbanNone')),
3822
+ h('option', { value: 'on_failure' }, T_KEY(t, 'form.kanbanOnFailure')),
3823
+ h('option', { value: 'always' }, T_KEY(t, 'form.kanbanAlways'))
3654
3824
  )
3655
3825
  ),
3656
- AGENT_FORM_TYPES.includes(formType) && React.createElement('div', { className: 'dsh-cron-form-group' },
3657
- React.createElement('label', null, T_KEY(t, 'form.agentPresetLabel')),
3658
- React.createElement('input', {
3826
+ AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
3827
+ h('label', null, T_KEY(t, 'form.agentPresetLabel')),
3828
+ h('input', {
3659
3829
  type: 'text',
3660
3830
  value: formAgentPreset,
3661
3831
  placeholder: T_KEY(t, 'form.agentPresetPlaceholder'),
3662
3832
  onChange: (e) => setFormAgentPreset(e.target.value)
3663
3833
  }),
3664
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.agentPresetHint'))
3834
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.agentPresetHint'))
3665
3835
  ),
3666
- AGENT_FORM_TYPES.includes(formType) && React.createElement('div', { className: 'dsh-cron-form-row' },
3667
- React.createElement('div', { className: 'dsh-cron-form-group' },
3668
- React.createElement('label', null, T_KEY(t, 'form.targetSessionIdLabel')),
3669
- React.createElement('input', {
3836
+ AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-row' },
3837
+ h('div', { className: 'dsh-cron-form-group' },
3838
+ h('label', null, T_KEY(t, 'form.targetSessionIdLabel')),
3839
+ h('input', {
3670
3840
  type: 'text',
3671
3841
  value: formTargetSessionId,
3672
3842
  placeholder: T_KEY(t, 'form.targetSessionIdPlaceholder'),
3673
3843
  onChange: (e) => setFormTargetSessionId(e.target.value)
3674
3844
  }),
3675
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.targetSessionIdHint'))
3845
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.targetSessionIdHint'))
3676
3846
  ),
3677
- React.createElement('div', { className: 'dsh-cron-form-group' },
3678
- React.createElement('label', null, T_KEY(t, 'form.targetSessionResetLabel')),
3679
- React.createElement('select', {
3847
+ h('div', { className: 'dsh-cron-form-group' },
3848
+ h('label', null, T_KEY(t, 'form.targetSessionResetLabel')),
3849
+ h('select', {
3680
3850
  value: formTargetSessionReset,
3681
3851
  onChange: (e) => setFormTargetSessionReset(e.target.value)
3682
3852
  },
3683
- React.createElement('option', { value: 'never' }, T_KEY(t, 'form.targetSessionResetNever')),
3684
- React.createElement('option', { value: 'daily' }, T_KEY(t, 'form.targetSessionResetDaily')),
3685
- React.createElement('option', { value: 'weekly' }, T_KEY(t, 'form.targetSessionResetWeekly'))
3853
+ h('option', { value: 'never' }, T_KEY(t, 'form.targetSessionResetNever')),
3854
+ h('option', { value: 'daily' }, T_KEY(t, 'form.targetSessionResetDaily')),
3855
+ h('option', { value: 'weekly' }, T_KEY(t, 'form.targetSessionResetWeekly'))
3686
3856
  ),
3687
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.targetSessionResetHint'))
3857
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.targetSessionResetHint'))
3688
3858
  )
3689
3859
  ),
3690
- AGENT_FORM_TYPES.includes(formType) && React.createElement('div', { className: 'dsh-cron-form-row' },
3691
- React.createElement('div', { className: 'dsh-cron-form-group' },
3692
- React.createElement('label', null, T_KEY(t, 'form.providerLabel')),
3693
- React.createElement('select', {
3860
+ AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-row' },
3861
+ h('div', { className: 'dsh-cron-form-group' },
3862
+ h('label', null, T_KEY(t, 'form.providerLabel')),
3863
+ h('select', {
3694
3864
  value: formProvider,
3695
3865
  onChange: handleProviderChange
3696
3866
  },
3697
- React.createElement('option', { value: '' }, T_KEY(t, 'form.providerDefault')),
3698
- providers.map((p) => React.createElement('option', { key: p.id, value: p.id }, p.name || p.id))
3867
+ h('option', { value: '' }, T_KEY(t, 'form.providerDefault')),
3868
+ providers.map((p) => h('option', { key: p.id, value: p.id }, p.name || p.id))
3699
3869
  )
3700
3870
  ),
3701
- React.createElement('div', { className: 'dsh-cron-form-group' },
3702
- React.createElement('label', null, T_KEY(t, 'form.modelLabel')),
3703
- React.createElement('select', {
3871
+ h('div', { className: 'dsh-cron-form-group' },
3872
+ h('label', null, T_KEY(t, 'form.modelLabel')),
3873
+ h('select', {
3704
3874
  value: formModel,
3705
3875
  onChange: (e) => setFormModel(e.target.value)
3706
3876
  },
3707
- React.createElement('option', { value: '' }, T_KEY(t, 'form.modelDefault')),
3708
- models.map((m) => React.createElement('option', { key: m.id, value: m.id }, m.name || m.id))
3877
+ h('option', { value: '' }, T_KEY(t, 'form.modelDefault')),
3878
+ models.map((m) => h('option', { key: m.id, value: m.id }, m.name || m.id))
3709
3879
  )
3710
3880
  ),
3711
- React.createElement('div', { className: 'dsh-cron-form-group' },
3712
- React.createElement('label', null, T_KEY(t, 'form.fallbackModelLabel')),
3713
- React.createElement('input', {
3881
+ h('div', { className: 'dsh-cron-form-group' },
3882
+ h('label', null, T_KEY(t, 'form.fallbackModelLabel')),
3883
+ h('input', {
3714
3884
  type: 'text',
3715
3885
  value: formFallbackModel,
3716
3886
  placeholder: T_KEY(t, 'form.fallbackModelPlaceholder'),
3717
3887
  onChange: (e) => setFormFallbackModel(e.target.value)
3718
3888
  }),
3719
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.fallbackModelHint'))
3889
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.fallbackModelHint'))
3720
3890
  ),
3721
- React.createElement('label', { className: 'dsh-cron-checkbox-row', style: { marginTop: '4px' } },
3722
- React.createElement('input', {
3891
+ h('label', { className: 'dsh-cron-checkbox-row', style: { marginTop: '4px' } },
3892
+ h('input', {
3723
3893
  type: 'checkbox',
3724
3894
  checked: formInspectOnFailure,
3725
3895
  onChange: (e) => setFormInspectOnFailure(e.target.checked)
3726
3896
  }),
3727
- React.createElement('span', null, T_KEY(t, 'form.inspectOnFailureLabel'))
3897
+ h('span', null, T_KEY(t, 'form.inspectOnFailureLabel'))
3728
3898
  ),
3729
- formInspectOnFailure && React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.inspectOnFailureHint')),
3730
- React.createElement('label', { className: 'dsh-cron-checkbox-row', style: { marginTop: '8px' } },
3731
- React.createElement('input', {
3899
+ formInspectOnFailure && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.inspectOnFailureHint')),
3900
+ h('label', { className: 'dsh-cron-checkbox-row', style: { marginTop: '8px' } },
3901
+ h('input', {
3732
3902
  type: 'checkbox',
3733
3903
  checked: formRequireApproval,
3734
3904
  onChange: (e) => setFormRequireApproval(e.target.checked)
3735
3905
  }),
3736
- React.createElement('span', null, T_KEY(t, 'form.requireApprovalLabel'))
3906
+ h('span', null, T_KEY(t, 'form.requireApprovalLabel'))
3737
3907
  ),
3738
- formRequireApproval && React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.requireApprovalHint'))
3908
+ formRequireApproval && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.requireApprovalHint'))
3739
3909
  ),
3740
- formType === 'http' && React.createElement('div', { className: 'dsh-cron-form-row' },
3741
- React.createElement('div', { className: 'dsh-cron-form-group' },
3742
- React.createElement('label', null, T_KEY(t, 'form.httpMethodLabel')),
3743
- React.createElement('select', {
3910
+ formType === 'http' && h('div', { className: 'dsh-cron-form-row' },
3911
+ h('div', { className: 'dsh-cron-form-group' },
3912
+ h('label', null, T_KEY(t, 'form.httpMethodLabel')),
3913
+ h('select', {
3744
3914
  value: formHttpMethod,
3745
3915
  onChange: (e) => setFormHttpMethod(e.target.value)
3746
3916
  },
3747
- ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'].map((m) => React.createElement('option', { key: m, value: m }, m))
3917
+ ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'].map((m) => h('option', { key: m, value: m }, m))
3748
3918
  )
3749
3919
  ),
3750
- React.createElement('div', { className: 'dsh-cron-form-group' },
3751
- React.createElement('label', null, T_KEY(t, 'form.httpUrlLabel')),
3752
- React.createElement('input', {
3920
+ h('div', { className: 'dsh-cron-form-group' },
3921
+ h('label', null, T_KEY(t, 'form.httpUrlLabel')),
3922
+ h('input', {
3753
3923
  required: true,
3754
3924
  value: formHttpUrl,
3755
3925
  placeholder: 'https://example.test/webhook',
@@ -3757,41 +3927,41 @@ onChange: (e) => setFormHttpUrl(e.target.value)
3757
3927
  })
3758
3928
  )
3759
3929
  ),
3760
- formType === 'http' && React.createElement('div', { className: 'dsh-cron-form-row' },
3761
- React.createElement('div', { className: 'dsh-cron-form-group' },
3762
- React.createElement('label', null, T_KEY(t, 'form.httpHeadersLabel')),
3763
- React.createElement('input', {
3930
+ formType === 'http' && h('div', { className: 'dsh-cron-form-row' },
3931
+ h('div', { className: 'dsh-cron-form-group' },
3932
+ h('label', null, T_KEY(t, 'form.httpHeadersLabel')),
3933
+ h('input', {
3764
3934
  value: formHttpHeaders,
3765
3935
  placeholder: '{"Authorization":"Bearer ..."}',
3766
3936
  onChange: (e) => setFormHttpHeaders(e.target.value)
3767
3937
  })
3768
3938
  ),
3769
- React.createElement('div', { className: 'dsh-cron-form-group' },
3770
- React.createElement('label', null, T_KEY(t, 'form.httpBodyLabel')),
3771
- React.createElement('input', {
3939
+ h('div', { className: 'dsh-cron-form-group' },
3940
+ h('label', null, T_KEY(t, 'form.httpBodyLabel')),
3941
+ h('input', {
3772
3942
  value: formHttpBody,
3773
3943
  onChange: (e) => setFormHttpBody(e.target.value)
3774
3944
  })
3775
3945
  )
3776
3946
  ),
3777
- formType === 'ssh' && React.createElement('div', { className: 'dsh-cron-form-row' },
3778
- React.createElement('div', { className: 'dsh-cron-form-group' },
3779
- React.createElement('label', null, T_KEY(t, 'form.sshProfileLabel')),
3780
- React.createElement('input', {
3947
+ formType === 'ssh' && h('div', { className: 'dsh-cron-form-row' },
3948
+ h('div', { className: 'dsh-cron-form-group' },
3949
+ h('label', null, T_KEY(t, 'form.sshProfileLabel')),
3950
+ h('input', {
3781
3951
  value: formSshProfileId,
3782
3952
  placeholder: 'prod-web',
3783
3953
  onChange: (e) => setFormSshProfileId(e.target.value)
3784
3954
  }),
3785
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.sshProfileHint'))
3955
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.sshProfileHint'))
3786
3956
  ),
3787
- React.createElement('div', { className: 'dsh-cron-form-group' },
3788
- React.createElement('label', null, T_KEY(t, 'form.sshTargetLabel')),
3789
- React.createElement('input', {
3957
+ h('div', { className: 'dsh-cron-form-group' },
3958
+ h('label', null, T_KEY(t, 'form.sshTargetLabel')),
3959
+ h('input', {
3790
3960
  value: formSshTarget,
3791
3961
  placeholder: 'user@example.com',
3792
3962
  onChange: (e) => setFormSshTarget(e.target.value)
3793
3963
  }),
3794
- React.createElement('input', {
3964
+ h('input', {
3795
3965
  style: { marginTop: '6px' },
3796
3966
  value: formSshKeyPath,
3797
3967
  placeholder: '~/.ssh/id_ed25519',
@@ -3799,93 +3969,93 @@ onChange: (e) => setFormSshKeyPath(e.target.value)
3799
3969
  })
3800
3970
  )
3801
3971
  ),
3802
- formType === 'docker' && React.createElement('div', { className: 'dsh-cron-form-group' },
3803
- React.createElement('label', null, T_KEY(t, 'form.dockerImageLabel')),
3804
- React.createElement('input', {
3972
+ formType === 'docker' && h('div', { className: 'dsh-cron-form-group' },
3973
+ h('label', null, T_KEY(t, 'form.dockerImageLabel')),
3974
+ h('input', {
3805
3975
  required: true,
3806
3976
  value: formDockerImage,
3807
3977
  placeholder: 'alpine:3.20',
3808
3978
  onChange: (e) => setFormDockerImage(e.target.value)
3809
3979
  })
3810
3980
  ),
3811
- formType === 'skill' && React.createElement('div', { className: 'dsh-cron-form-group' },
3812
- React.createElement('label', null, T_KEY(t, 'form.skillNameLabel')),
3813
- React.createElement('input', {
3981
+ formType === 'skill' && h('div', { className: 'dsh-cron-form-group' },
3982
+ h('label', null, T_KEY(t, 'form.skillNameLabel')),
3983
+ h('input', {
3814
3984
  value: formSkillName,
3815
3985
  placeholder: 'gitea',
3816
3986
  onChange: (e) => setFormSkillName(e.target.value)
3817
3987
  })
3818
3988
  ),
3819
- formType === 'workflow' && React.createElement('div', { className: 'dsh-cron-form-group' },
3820
- React.createElement('label', null, T_KEY(t, 'form.workflowNameLabel')),
3821
- React.createElement('input', {
3989
+ formType === 'workflow' && h('div', { className: 'dsh-cron-form-group' },
3990
+ h('label', null, T_KEY(t, 'form.workflowNameLabel')),
3991
+ h('input', {
3822
3992
  value: formWorkflowName,
3823
3993
  placeholder: 'nightly-release',
3824
3994
  onChange: (e) => setFormWorkflowName(e.target.value)
3825
3995
  })
3826
3996
  ),
3827
- (formType === 'node' || formType === 'python') && React.createElement('div', { className: 'dsh-cron-form-group' },
3828
- React.createElement('label', null, formType === 'node' ? 'Node.js binary (optional)' : 'Python interpreter (optional)'),
3829
- React.createElement('input', {
3997
+ (formType === 'node' || formType === 'python') && h('div', { className: 'dsh-cron-form-group' },
3998
+ h('label', null, formType === 'node' ? 'Node.js binary (optional)' : 'Python interpreter (optional)'),
3999
+ h('input', {
3830
4000
  value: formType === 'node' ? formNodePath : formPythonPath,
3831
4001
  placeholder: formType === 'node' ? 'auto' : '.venv/bin/python',
3832
4002
  onChange: (e) => (formType === 'node' ? setFormNodePath(e.target.value) : setFormPythonPath(e.target.value))
3833
4003
  })
3834
4004
  ),
3835
- !AGENT_FORM_TYPES.includes(formType) && React.createElement('div', { className: 'dsh-cron-form-group' },
3836
- React.createElement('label', null, T_KEY(t, 'form.envLabel')),
3837
- React.createElement('textarea', {
4005
+ !AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
4006
+ h('label', null, T_KEY(t, 'form.envLabel')),
4007
+ h('textarea', {
3838
4008
  rows: 3,
3839
4009
  style: { fontFamily: 'monospace', fontSize: '12.5px' },
3840
4010
  value: formEnv,
3841
4011
  placeholder: T_KEY(t, 'form.envPlaceholder'),
3842
4012
  onChange: (e) => setFormEnv(e.target.value)
3843
4013
  }),
3844
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.envHint'))
4014
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.envHint'))
3845
4015
  ),
3846
- React.createElement('div', { className: 'dsh-cron-form-row' },
3847
- React.createElement('div', { className: 'dsh-cron-form-group' },
3848
- React.createElement('label', null, T_KEY(t, 'form.cwdLabel')),
3849
- React.createElement('input', {
4016
+ h('div', { className: 'dsh-cron-form-row' },
4017
+ h('div', { className: 'dsh-cron-form-group' },
4018
+ h('label', null, T_KEY(t, 'form.cwdLabel')),
4019
+ h('input', {
3850
4020
  value: formCwd,
3851
4021
  placeholder: '/srv/app',
3852
4022
  onChange: (e) => setFormCwd(e.target.value)
3853
4023
  })
3854
4024
  ),
3855
- React.createElement('div', { className: 'dsh-cron-form-group' },
3856
- React.createElement('label', null, T_KEY(t, 'form.workspaceLabel')),
3857
- React.createElement('input', {
4025
+ h('div', { className: 'dsh-cron-form-group' },
4026
+ h('label', null, T_KEY(t, 'form.workspaceLabel')),
4027
+ h('input', {
3858
4028
  value: formWorkspaceId,
3859
4029
  onChange: (e) => setFormWorkspaceId(e.target.value)
3860
4030
  })
3861
4031
  )
3862
4032
  ),
3863
- AGENT_FORM_TYPES.includes(formType) && React.createElement('div', { className: 'dsh-cron-form-group' },
3864
- React.createElement('label', { className: 'dsh-cron-checkbox-row' },
3865
- React.createElement('input', {
4033
+ AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
4034
+ h('label', { className: 'dsh-cron-checkbox-row' },
4035
+ h('input', {
3866
4036
  type: 'checkbox',
3867
4037
  checked: formWorktree,
3868
4038
  onChange: (e) => setFormWorktree(e.target.checked)
3869
4039
  }),
3870
- React.createElement('span', null, T_KEY(t, 'form.worktreeLabel'))
4040
+ h('span', null, T_KEY(t, 'form.worktreeLabel'))
3871
4041
  ),
3872
- formWorktree && React.createElement('label', { className: 'dsh-cron-checkbox-row', style: { marginLeft: '24px', marginTop: '6px' } },
3873
- React.createElement('input', {
4042
+ formWorktree && h('label', { className: 'dsh-cron-checkbox-row', style: { marginLeft: '24px', marginTop: '6px' } },
4043
+ h('input', {
3874
4044
  type: 'checkbox',
3875
4045
  checked: formKeepWorktree,
3876
4046
  onChange: (e) => setFormKeepWorktree(e.target.checked)
3877
4047
  }),
3878
- React.createElement('span', null, T_KEY(t, 'form.keepWorktreeLabel'))
4048
+ h('span', null, T_KEY(t, 'form.keepWorktreeLabel'))
3879
4049
  )
3880
4050
  ),
3881
- formType !== 'http' && React.createElement('div', { className: 'dsh-cron-form-group' },
3882
- React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '4px' } },
3883
- React.createElement('label', { style: { margin: 0 } }, AGENT_FORM_TYPES.includes(formType) ? T_KEY(t, 'form.promptLabelLlm') : T_KEY(t, 'form.promptLabelScript')),
3884
- (selectedTaskMeta && selectedTaskMeta.promptHistory && selectedTaskMeta.promptHistory.length > 0) ? React.createElement('div', { style: { display: 'flex', gap: '6px', alignItems: 'center' } },
3885
- React.createElement('span', {
4051
+ formType !== 'http' && h('div', { className: 'dsh-cron-form-group' },
4052
+ h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '4px' } },
4053
+ h('label', { style: { margin: 0 } }, AGENT_FORM_TYPES.includes(formType) ? T_KEY(t, 'form.promptLabelLlm') : T_KEY(t, 'form.promptLabelScript')),
4054
+ (selectedTaskMeta && selectedTaskMeta.promptHistory && selectedTaskMeta.promptHistory.length > 0) ? h('div', { style: { display: 'flex', gap: '6px', alignItems: 'center' } },
4055
+ h('span', {
3886
4056
  style: { fontSize: '11px', padding: '1px 6px', borderRadius: '4px', background: 'var(--dsw-alias-bg-layer-3, #222)', color: 'var(--dsh-cron-info, #4af)', border: '1px solid var(--dsw-alias-border-l2, #333)' }
3887
4057
  }, 'v' + (selectedTaskMeta.promptVersion || 1) + ' (' + (selectedTaskMeta.promptHistory[selectedTaskMeta.promptHistory.length - 1]?.successRate !== undefined ? Math.round(selectedTaskMeta.promptHistory[selectedTaskMeta.promptHistory.length - 1].successRate * 100) : 100) + '% SR)'),
3888
- React.createElement('select', {
4058
+ h('select', {
3889
4059
  style: { fontSize: '11px', padding: '1px 4px', background: 'var(--dsw-alias-bg-base, #111)', color: 'var(--dsw-alias-label-primary, #ddd)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '4px' },
3890
4060
  onChange: (e) => {
3891
4061
  const targetV = Number(e.target.value);
@@ -3895,11 +4065,11 @@ setFormPrompt(entry.prompt);
3895
4065
  }
3896
4066
  }
3897
4067
  },
3898
- selectedTaskMeta.promptHistory.map((h) => React.createElement('option', { key: h.version, value: h.version }, 'v' + h.version + ' (' + Math.round((h.successRate || 1) * 100) + '%)'))
4068
+ selectedTaskMeta.promptHistory.map((h) => h('option', { key: h.version, value: h.version }, 'v' + h.version + ' (' + Math.round((h.successRate || 1) * 100) + '%)'))
3899
4069
  )
3900
4070
  ) : null
3901
4071
  ),
3902
- React.createElement('textarea', {
4072
+ h('textarea', {
3903
4073
  required: true,
3904
4074
  rows: 9,
3905
4075
  style: { fontFamily: 'monospace', fontSize: '12.5px', lineHeight: '1.45' },
@@ -3918,7 +4088,7 @@ placeholder: AGENT_FORM_TYPES.includes(formType)
3918
4088
  onChange: (e) => setFormPrompt(e.target.value)
3919
4089
  })
3920
4090
  ),
3921
- React.createElement('div', {
4091
+ h('div', {
3922
4092
  style: {
3923
4093
  background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))',
3924
4094
  border: '1px solid var(--dsw-alias-border-l2)',
@@ -3927,31 +4097,31 @@ padding: '12px 14px',
3927
4097
  marginBottom: '16px'
3928
4098
  }
3929
4099
  },
3930
- React.createElement('div', { style: { fontWeight: 500, fontSize: '13px', color: 'var(--dsw-alias-label-primary, #eee)', marginBottom: '8px', display: 'flex', alignItems: 'center', gap: '6px' } },
3931
- React.createElement('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
4100
+ h('div', { style: { fontWeight: 500, fontSize: '13px', color: 'var(--dsw-alias-label-primary, #eee)', marginBottom: '8px', display: 'flex', alignItems: 'center', gap: '6px' } },
4101
+ h('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
3932
4102
  T_KEY(t, 'form.notifyTitle')
3933
4103
  ),
3934
- React.createElement('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: formNotifyTelegram ? '8px' : '0' } },
3935
- React.createElement('input', {
4104
+ h('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: formNotifyTelegram ? '8px' : '0' } },
4105
+ h('input', {
3936
4106
  type: 'checkbox',
3937
4107
  checked: formNotifyTelegram,
3938
4108
  onChange: (e) => setFormNotifyTelegram(e.target.checked)
3939
4109
  }),
3940
- React.createElement('span', null, T_KEY(t, 'form.notifyTelegram'))
4110
+ h('span', null, T_KEY(t, 'form.notifyTelegram'))
3941
4111
  ),
3942
- (formNotifyTelegram || formChannels.length > 0) && React.createElement('label', { className: 'dsh-cron-checkbox-row', style: { marginLeft: '24px', marginTop: '6px' } },
3943
- React.createElement('input', {
4112
+ (formNotifyTelegram || formChannels.length > 0) && h('label', { className: 'dsh-cron-checkbox-row', style: { marginLeft: '24px', marginTop: '6px' } },
4113
+ h('input', {
3944
4114
  type: 'checkbox',
3945
4115
  checked: formOnlyOnFailure,
3946
4116
  onChange: (e) => setFormOnlyOnFailure(e.target.checked)
3947
4117
  }),
3948
- React.createElement('span', null, T_KEY(t, 'form.notifyOnlyFailure'))
4118
+ h('span', null, T_KEY(t, 'form.notifyOnlyFailure'))
3949
4119
  ),
3950
- React.createElement('div', { style: { marginTop: '12px', paddingTop: '10px', borderTop: '1px solid var(--dsw-alias-border-l2)' } },
3951
- React.createElement('div', { style: { fontWeight: 500, fontSize: '12.5px', color: 'var(--dsw-alias-label-secondary, #aaa)', marginBottom: '8px' } }, T_KEY(t, 'form.channelsTitle')),
3952
- React.createElement('div', { className: 'dsh-cron-channel-grid' },
3953
- ...DELIVERY_CHANNELS.map((id) => React.createElement('label', { key: id, className: 'dsh-cron-checkbox-row' },
3954
- React.createElement('input', {
4120
+ h('div', { style: { marginTop: '12px', paddingTop: '10px', borderTop: '1px solid var(--dsw-alias-border-l2)' } },
4121
+ h('div', { style: { fontWeight: 500, fontSize: '12.5px', color: 'var(--dsw-alias-label-secondary, #aaa)', marginBottom: '8px' } }, T_KEY(t, 'form.channelsTitle')),
4122
+ h('div', { className: 'dsh-cron-channel-grid' },
4123
+ ...DELIVERY_CHANNELS.map((id) => h('label', { key: id, className: 'dsh-cron-checkbox-row' },
4124
+ h('input', {
3955
4125
  type: 'checkbox',
3956
4126
  checked: formChannels.indexOf(id) >= 0,
3957
4127
  onChange: (e) => {
@@ -3962,56 +4132,56 @@ return DELIVERY_CHANNELS.filter((c) => set.has(c));
3962
4132
  });
3963
4133
  }
3964
4134
  }),
3965
- React.createElement('span', null, T_KEY(t, CHANNEL_LABEL_KEYS[id]))
4135
+ h('span', null, T_KEY(t, CHANNEL_LABEL_KEYS[id]))
3966
4136
  ))
3967
4137
  ),
3968
- React.createElement('div', { className: 'dsh-cron-hint', style: { marginTop: '6px' } }, T_KEY(t, 'form.channelsHint'))
4138
+ h('div', { className: 'dsh-cron-hint', style: { marginTop: '6px' } }, T_KEY(t, 'form.channelsHint'))
3969
4139
  ),
3970
- React.createElement('div', { className: 'dsh-cron-form-group', style: { marginTop: '12px', marginBottom: 0 } },
3971
- React.createElement('label', null, T_KEY(t, 'form.templateLabel')),
3972
- React.createElement('input', {
4140
+ h('div', { className: 'dsh-cron-form-group', style: { marginTop: '12px', marginBottom: 0 } },
4141
+ h('label', null, T_KEY(t, 'form.templateLabel')),
4142
+ h('input', {
3973
4143
  type: 'text',
3974
4144
  value: formTemplate,
3975
4145
  placeholder: T_KEY(t, 'form.templatePlaceholder'),
3976
4146
  onChange: (e) => setFormTemplate(e.target.value)
3977
4147
  }),
3978
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.templateHint'))
4148
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.templateHint'))
3979
4149
  ),
3980
- !AGENT_FORM_TYPES.includes(formType) && React.createElement('div', { className: 'dsh-cron-form-group', style: { marginTop: '12px', marginBottom: 0 } },
3981
- React.createElement('label', null, T_KEY(t, 'form.silentRuleLabel')),
3982
- React.createElement('input', {
4150
+ !AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group', style: { marginTop: '12px', marginBottom: 0 } },
4151
+ h('label', null, T_KEY(t, 'form.silentRuleLabel')),
4152
+ h('input', {
3983
4153
  type: 'text',
3984
4154
  value: formSilentRule,
3985
4155
  placeholder: T_KEY(t, 'form.silentRulePlaceholder'),
3986
4156
  onChange: (e) => setFormSilentRule(e.target.value)
3987
4157
  }),
3988
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.silentRuleHint'))
4158
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.silentRuleHint'))
3989
4159
  )
3990
4160
  ),
3991
- React.createElement('div', {
4161
+ h('div', {
3992
4162
  style: {
3993
4163
  marginTop: '16px',
3994
4164
  paddingTop: '14px',
3995
4165
  borderTop: '1px solid var(--dsw-alias-border-l2)'
3996
4166
  }
3997
4167
  },
3998
- React.createElement('div', { style: { fontWeight: '600', fontSize: '13px', marginBottom: '10px' } }, T_KEY(t, 'form.reliabilityTitle')),
3999
- React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
4000
- React.createElement('div', { className: 'dsh-cron-form-group' },
4001
- React.createElement('label', null, T_KEY(t, 'form.preflightLabel')),
4002
- React.createElement('select', {
4168
+ h('div', { style: { fontWeight: '600', fontSize: '13px', marginBottom: '10px' } }, T_KEY(t, 'form.reliabilityTitle')),
4169
+ h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
4170
+ h('div', { className: 'dsh-cron-form-group' },
4171
+ h('label', null, T_KEY(t, 'form.preflightLabel')),
4172
+ h('select', {
4003
4173
  value: formPreflightType,
4004
4174
  onChange: (e) => setFormPreflightType(e.target.value)
4005
4175
  },
4006
- React.createElement('option', { value: 'none' }, T_KEY(t, 'form.preflightNone')),
4007
- React.createElement('option', { value: 'http' }, T_KEY(t, 'form.preflightHttp')),
4008
- React.createElement('option', { value: 'shell' }, T_KEY(t, 'form.preflightShell')),
4009
- React.createElement('option', { value: 'disk' }, T_KEY(t, 'form.preflightDisk'))
4176
+ h('option', { value: 'none' }, T_KEY(t, 'form.preflightNone')),
4177
+ h('option', { value: 'http' }, T_KEY(t, 'form.preflightHttp')),
4178
+ h('option', { value: 'shell' }, T_KEY(t, 'form.preflightShell')),
4179
+ h('option', { value: 'disk' }, T_KEY(t, 'form.preflightDisk'))
4010
4180
  )
4011
4181
  ),
4012
- formPreflightType !== 'none' && React.createElement('div', { className: 'dsh-cron-form-group' },
4013
- React.createElement('label', null, T_KEY(t, 'form.preflightTargetLabel')),
4014
- React.createElement('input', {
4182
+ formPreflightType !== 'none' && h('div', { className: 'dsh-cron-form-group' },
4183
+ h('label', null, T_KEY(t, 'form.preflightTargetLabel')),
4184
+ h('input', {
4015
4185
  type: 'text',
4016
4186
  value: formPreflightTarget,
4017
4187
  placeholder: T_KEY(t, 'form.preflightTargetPlaceholder'),
@@ -4019,19 +4189,19 @@ onChange: (e) => setFormPreflightTarget(e.target.value)
4019
4189
  })
4020
4190
  )
4021
4191
  ),
4022
- React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
4023
- React.createElement('div', { className: 'dsh-cron-form-group' },
4024
- React.createElement('label', null, T_KEY(t, 'form.heartbeatIntervalLabel')),
4025
- React.createElement('input', {
4192
+ h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
4193
+ h('div', { className: 'dsh-cron-form-group' },
4194
+ h('label', null, T_KEY(t, 'form.heartbeatIntervalLabel')),
4195
+ h('input', {
4026
4196
  type: 'number',
4027
4197
  value: formHeartbeatIntervalSeconds,
4028
4198
  min: 0,
4029
4199
  onChange: (e) => setFormHeartbeatIntervalSeconds(Number(e.target.value))
4030
4200
  })
4031
4201
  ),
4032
- formHeartbeatIntervalSeconds > 0 && React.createElement('div', { className: 'dsh-cron-form-group' },
4033
- React.createElement('label', null, T_KEY(t, 'form.gracePeriodLabel')),
4034
- React.createElement('input', {
4202
+ formHeartbeatIntervalSeconds > 0 && h('div', { className: 'dsh-cron-form-group' },
4203
+ h('label', null, T_KEY(t, 'form.gracePeriodLabel')),
4204
+ h('input', {
4035
4205
  type: 'number',
4036
4206
  value: formGracePeriodSeconds,
4037
4207
  min: 1,
@@ -4039,10 +4209,10 @@ onChange: (e) => setFormGracePeriodSeconds(Number(e.target.value))
4039
4209
  })
4040
4210
  )
4041
4211
  ),
4042
- React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
4043
- React.createElement('div', { className: 'dsh-cron-form-group' },
4044
- React.createElement('label', null, T_KEY(t, 'form.priorityLabel')),
4045
- React.createElement('input', {
4212
+ h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
4213
+ h('div', { className: 'dsh-cron-form-group' },
4214
+ h('label', null, T_KEY(t, 'form.priorityLabel')),
4215
+ h('input', {
4046
4216
  type: 'number',
4047
4217
  value: formPriority,
4048
4218
  min: 1,
@@ -4050,117 +4220,138 @@ max: 10,
4050
4220
  onChange: (e) => setFormPriority(Number(e.target.value))
4051
4221
  })
4052
4222
  ),
4053
- React.createElement('div', { className: 'dsh-cron-form-group' },
4054
- React.createElement('label', null, T_KEY(t, 'form.concurrencyGroupLabel')),
4055
- React.createElement('input', {
4223
+ h('div', { className: 'dsh-cron-form-group' },
4224
+ h('label', null, T_KEY(t, 'form.concurrencyGroupLabel')),
4225
+ h('input', {
4056
4226
  type: 'text',
4057
4227
  value: formConcurrencyGroup,
4058
4228
  onChange: (e) => setFormConcurrencyGroup(e.target.value)
4059
4229
  })
4060
4230
  )
4061
4231
  ),
4062
- React.createElement('div', { className: 'dsh-cron-form-group' },
4063
- React.createElement('label', null, T_KEY(t, 'form.selfHealingLabel')),
4064
- React.createElement('input', {
4232
+ h('div', { className: 'dsh-cron-form-group' },
4233
+ h('label', null, T_KEY(t, 'form.selfHealingLabel')),
4234
+ h('input', {
4065
4235
  type: 'text',
4066
4236
  value: formSelfHealingCommand,
4067
4237
  placeholder: T_KEY(t, 'form.selfHealingPlaceholder'),
4068
4238
  onChange: (e) => setFormSelfHealingCommand(e.target.value)
4069
4239
  })
4070
4240
  ),
4071
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '6px' } },
4072
- React.createElement('input', {
4241
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '6px' } },
4242
+ h('input', {
4073
4243
  type: 'checkbox',
4074
4244
  id: 'formAutoDiagnoseCheckbox',
4075
4245
  checked: formAutoDiagnose,
4076
4246
  onChange: (e) => setFormAutoDiagnose(e.target.checked)
4077
4247
  }),
4078
- React.createElement('label', { htmlFor: 'formAutoDiagnoseCheckbox', style: { margin: 0, fontSize: '12.5px', cursor: 'pointer' } }, T_KEY(t, 'form.autoDiagnoseLabel'))
4248
+ h('label', { htmlFor: 'formAutoDiagnoseCheckbox', style: { margin: 0, fontSize: '12.5px', cursor: 'pointer' } }, T_KEY(t, 'form.autoDiagnoseLabel'))
4079
4249
  )
4080
4250
  ),
4081
- React.createElement('div', {
4251
+ h('div', {
4082
4252
  style: {
4083
4253
  marginTop: '16px',
4084
4254
  paddingTop: '14px',
4085
4255
  borderTop: '1px solid var(--dsw-alias-border-l2)'
4086
4256
  }
4087
4257
  },
4088
- React.createElement('div', { style: { fontWeight: '600', fontSize: '13px', marginBottom: '10px' } }, '⛓️ ' + T_KEY(t, 'form.chainingTitle')),
4089
- React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
4090
- React.createElement('div', { className: 'dsh-cron-form-group' },
4091
- React.createElement('label', null, T_KEY(t, 'form.onSuccessLabel')),
4092
- React.createElement('input', {
4258
+ h('div', { style: { fontWeight: '600', fontSize: '13px', marginBottom: '10px' } }, '⛓️ ' + T_KEY(t, 'form.chainingTitle')),
4259
+ h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
4260
+ h('div', { className: 'dsh-cron-form-group' },
4261
+ h('label', null, T_KEY(t, 'form.onSuccessLabel')),
4262
+ h('input', {
4093
4263
  type: 'text',
4094
4264
  value: formOnSuccess,
4095
4265
  placeholder: 'task-build, task-test',
4096
4266
  onChange: (e) => setFormOnSuccess(e.target.value)
4097
4267
  }),
4098
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.onSuccessHint'))
4268
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.onSuccessHint'))
4099
4269
  ),
4100
- React.createElement('div', { className: 'dsh-cron-form-group' },
4101
- React.createElement('label', null, T_KEY(t, 'form.onFailureLabel')),
4102
- React.createElement('input', {
4270
+ h('div', { className: 'dsh-cron-form-group' },
4271
+ h('label', null, T_KEY(t, 'form.onFailureLabel')),
4272
+ h('input', {
4103
4273
  type: 'text',
4104
4274
  value: formOnFailure,
4105
4275
  placeholder: 'task-alert',
4106
4276
  onChange: (e) => setFormOnFailure(e.target.value)
4107
4277
  }),
4108
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.onFailureHint'))
4278
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.onFailureHint'))
4109
4279
  )
4110
4280
  ),
4111
- React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '2fr 1fr', gap: '10px', marginTop: '8px' } },
4112
- React.createElement('div', { className: 'dsh-cron-form-group' },
4113
- React.createElement('label', null, T_KEY(t, 'form.dependsOnLabel')),
4114
- React.createElement('input', {
4281
+ h('div', { style: { display: 'grid', gridTemplateColumns: '2fr 1fr', gap: '10px', marginTop: '8px' } },
4282
+ h('div', { className: 'dsh-cron-form-group' },
4283
+ h('label', null, T_KEY(t, 'form.dependsOnLabel')),
4284
+ h('input', {
4115
4285
  type: 'text',
4116
4286
  value: formDependsOn,
4117
4287
  placeholder: 'task-build, task-lint',
4118
4288
  onChange: (e) => setFormDependsOn(e.target.value)
4119
4289
  }),
4120
- React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.dependsOnHint'))
4290
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.dependsOnHint'))
4121
4291
  ),
4122
- React.createElement('div', { className: 'dsh-cron-form-group' },
4123
- React.createElement('label', null, T_KEY(t, 'form.joinPolicyLabel')),
4124
- React.createElement('select', {
4292
+ h('div', { className: 'dsh-cron-form-group' },
4293
+ h('label', null, T_KEY(t, 'form.joinPolicyLabel')),
4294
+ h('select', {
4125
4295
  value: formJoinPolicy,
4126
4296
  onChange: (e) => setFormJoinPolicy(e.target.value)
4127
4297
  },
4128
- React.createElement('option', { value: 'all_success' }, T_KEY(t, 'form.joinPolicyAll')),
4129
- React.createElement('option', { value: 'any_success' }, T_KEY(t, 'form.joinPolicyAny'))
4298
+ h('option', { value: 'all_success' }, T_KEY(t, 'form.joinPolicyAll')),
4299
+ h('option', { value: 'any_success' }, T_KEY(t, 'form.joinPolicyAny'))
4130
4300
  )
4131
4301
  )
4132
4302
  ),
4133
- React.createElement('div', { style: { marginTop: '12px', padding: '10px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: '6px' } },
4134
- React.createElement('label', { style: { display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer', fontWeight: '500' } },
4135
- React.createElement('input', {
4303
+ h('div', { className: 'dsh-cron-form-group', style: { marginTop: '8px' } },
4304
+ h('label', null, T_KEY(t, 'form.elseTaskLabel')),
4305
+ h('input', {
4306
+ type: 'text',
4307
+ value: formElseTask || '',
4308
+ placeholder: T_KEY(t, 'form.elseTaskPlaceholder'),
4309
+ onChange: (e) => setFormElseTask(e.target.value)
4310
+ }),
4311
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.elseTaskHint'))
4312
+ ),
4313
+ h('div', { className: 'dsh-cron-form-group', style: { marginTop: '8px' } },
4314
+ h('label', { style: { display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' } },
4315
+ h('input', {
4316
+ type: 'checkbox',
4317
+ checked: Boolean(formAutoHeal),
4318
+ onChange: (e) => setFormAutoHeal(e.target.checked)
4319
+ }),
4320
+ h('span', { style: { fontWeight: '600' } }, '🩺 ' + T_KEY(t, 'form.autoHealLabel'))
4321
+ ),
4322
+ h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.autoHealHint'))
4323
+ ),
4324
+ h('div', { style: { marginTop: '12px', padding: '10px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: '6px' } },
4325
+ h('label', { style: { display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer', fontWeight: '500' } },
4326
+ h('input', {
4136
4327
  type: 'checkbox',
4137
4328
  checked: formAdaptiveEnabled,
4138
4329
  onChange: (e) => setFormAdaptiveEnabled(e.target.checked)
4139
4330
  }),
4140
4331
  T_KEY(t, 'form.adaptiveEnabled')
4141
4332
  ),
4142
- React.createElement('div', { className: 'dsh-cron-hint', style: { marginLeft: '24px' } }, T_KEY(t, 'form.adaptiveHint')),
4143
- formAdaptiveEnabled && React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: '8px', marginTop: '8px', marginLeft: '24px' } },
4144
- React.createElement('div', null,
4145
- React.createElement('label', { style: { fontSize: '11px' } }, 'Min'),
4146
- React.createElement('input', { type: 'text', value: formAdaptiveMinInterval, placeholder: '5m', onChange: (e) => setFormAdaptiveMinInterval(e.target.value) })
4333
+ h('div', { className: 'dsh-cron-hint', style: { marginLeft: '24px' } }, T_KEY(t, 'form.adaptiveHint')),
4334
+ formAdaptiveEnabled && h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: '8px', marginTop: '8px', marginLeft: '24px' } },
4335
+ h('div', null,
4336
+ h('label', { style: { fontSize: '11px' } }, 'Min'),
4337
+ h('input', { type: 'text', value: formAdaptiveMinInterval, placeholder: '5m', onChange: (e) => setFormAdaptiveMinInterval(e.target.value) })
4147
4338
  ),
4148
- React.createElement('div', null,
4149
- React.createElement('label', { style: { fontSize: '11px' } }, 'Max'),
4150
- React.createElement('input', { type: 'text', value: formAdaptiveMaxInterval, placeholder: '2h', onChange: (e) => setFormAdaptiveMaxInterval(e.target.value) })
4339
+ h('div', null,
4340
+ h('label', { style: { fontSize: '11px' } }, 'Max'),
4341
+ h('input', { type: 'text', value: formAdaptiveMaxInterval, placeholder: '2h', onChange: (e) => setFormAdaptiveMaxInterval(e.target.value) })
4151
4342
  ),
4152
- React.createElement('div', null,
4153
- React.createElement('label', { style: { fontSize: '11px' } }, 'Factor'),
4154
- React.createElement('input', { type: 'number', step: '0.1', value: formAdaptiveBackoffFactor, placeholder: '1.5', onChange: (e) => setFormAdaptiveBackoffFactor(e.target.value) })
4343
+ h('div', null,
4344
+ h('label', { style: { fontSize: '11px' } }, 'Factor'),
4345
+ h('input', { type: 'number', step: '0.1', value: formAdaptiveBackoffFactor, placeholder: '1.5', onChange: (e) => setFormAdaptiveBackoffFactor(e.target.value) })
4155
4346
  ),
4156
- React.createElement('div', null,
4157
- React.createElement('label', { style: { fontSize: '11px' } }, 'Idle Runs'),
4158
- React.createElement('input', { type: 'number', value: formAdaptiveIdleThreshold, placeholder: '3', onChange: (e) => setFormAdaptiveIdleThreshold(e.target.value) })
4347
+ h('div', null,
4348
+ h('label', { style: { fontSize: '11px' } }, 'Idle Runs'),
4349
+ h('input', { type: 'number', value: formAdaptiveIdleThreshold, placeholder: '3', onChange: (e) => setFormAdaptiveIdleThreshold(e.target.value) })
4159
4350
  )
4160
4351
  )
4161
4352
  )
4162
4353
  ),
4163
- selectedTaskMeta && React.createElement('div', {
4354
+ selectedTaskMeta && h('div', {
4164
4355
  style: {
4165
4356
  background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent))',
4166
4357
  border: '1px solid var(--dsw-alias-border-l2)',
@@ -4174,11 +4365,11 @@ justifyContent: 'space-between',
4174
4365
  alignItems: 'center'
4175
4366
  }
4176
4367
  },
4177
- React.createElement('div', null,
4178
- React.createElement('span', null, T_KEY(t, 'form.nextRunLabel')),
4179
- React.createElement('strong', { style: { color: 'var(--dsw-alias-label-primary, #eee)' } }, selectedTaskMeta.nextRunAt ? new Date(selectedTaskMeta.nextRunAt).toLocaleString() : T_KEY(t, 'form.notScheduled'))
4368
+ h('div', null,
4369
+ h('span', null, T_KEY(t, 'form.nextRunLabel')),
4370
+ h('strong', { style: { color: 'var(--dsw-alias-label-primary, #eee)' } }, selectedTaskMeta.nextRunAt ? new Date(selectedTaskMeta.nextRunAt).toLocaleString() : T_KEY(t, 'form.notScheduled'))
4180
4371
  ),
4181
- React.createElement('button', {
4372
+ h('button', {
4182
4373
  type: 'button',
4183
4374
  className: 'dsh-cron-btn-secondary',
4184
4375
  style: { padding: '4px 10px', fontSize: '12px' },
@@ -4188,13 +4379,13 @@ if (formId) loadTaskHistory(formId);
4188
4379
  }
4189
4380
  }, T_KEY(t, 'actions.runNow'))
4190
4381
  ),
4191
- React.createElement('div', { className: 'dsh-cron-modal-foot' },
4192
- React.createElement('button', {
4382
+ h('div', { className: 'dsh-cron-modal-foot' },
4383
+ h('button', {
4193
4384
  type: 'button',
4194
4385
  className: 'dsh-cron-btn-secondary',
4195
4386
  onClick: closeManualModalWithConfirm
4196
4387
  }, T_KEY(t, 'modal.cancel')),
4197
- React.createElement('button', {
4388
+ h('button', {
4198
4389
  type: 'submit',
4199
4390
  className: 'dsh-cron-btn-primary'
4200
4391
  }, formId ? T_KEY(t, 'modal.save') : T_KEY(t, 'modal.create'))
@@ -4202,28 +4393,28 @@ className: 'dsh-cron-btn-primary'
4202
4393
  )
4203
4394
  )
4204
4395
  ),
4205
- dryRunResult && React.createElement('div', { className: 'dsh-cron-modal-overlay', onClick: () => setDryRunResult(null) },
4206
- React.createElement('div', {
4396
+ dryRunResult && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setDryRunResult(null) },
4397
+ h('div', {
4207
4398
  className: 'dsh-cron-modal',
4208
4399
  style: { maxWidth: '580px' },
4209
4400
  role: 'dialog',
4210
4401
  'aria-modal': 'true',
4211
4402
  onClick: (e) => e.stopPropagation()
4212
4403
  },
4213
- React.createElement('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
4214
- React.createElement('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, T_KEY(t, 'dryRun.title')),
4215
- React.createElement('button', {
4404
+ h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
4405
+ h('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, T_KEY(t, 'dryRun.title')),
4406
+ h('button', {
4216
4407
  type: 'button',
4217
4408
  className: 'dsh-cron-icon-btn',
4218
4409
  onClick: () => setDryRunResult(null)
4219
4410
  }, '✕')
4220
4411
  ),
4221
- React.createElement('div', { style: { marginTop: '12px', display: 'flex', flexDirection: 'column', gap: '8px', fontSize: '13px' } },
4222
- React.createElement('div', null, React.createElement('strong', null, T_KEY(t, 'dryRun.status') + ': '), React.createElement('span', { style: { color: dryRunResult.ok ? 'var(--dsh-cron-success)' : 'var(--dsh-cron-danger)' } }, dryRunResult.ok ? ((dryRunResult.result && dryRunResult.result.status) || dryRunResult.status || 'success') : 'failed')),
4223
- ((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight) && React.createElement('div', null, React.createElement('strong', null, T_KEY(t, 'dryRun.preflight') + ': '), React.createElement('span', null, (((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight).passed) ? '✓ Passed' : '✗ Failed (' + ((((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight).reason) || '') + ')')),
4224
- React.createElement('div', null, React.createElement('strong', null, T_KEY(t, 'dryRun.duration') + ': '), React.createElement('span', null, (((dryRunResult.result && dryRunResult.result.durationMs) !== undefined ? dryRunResult.result.durationMs : dryRunResult.durationMs) || 0) + 'ms')),
4225
- React.createElement('div', { style: { marginTop: '6px' } }, React.createElement('strong', null, T_KEY(t, 'dryRun.output') + ':')),
4226
- React.createElement('pre', {
4412
+ h('div', { style: { marginTop: '12px', display: 'flex', flexDirection: 'column', gap: '8px', fontSize: '13px' } },
4413
+ h('div', null, h('strong', null, T_KEY(t, 'dryRun.status') + ': '), h('span', { style: { color: dryRunResult.ok ? 'var(--dsh-cron-success)' : 'var(--dsh-cron-danger)' } }, dryRunResult.ok ? ((dryRunResult.result && dryRunResult.result.status) || dryRunResult.status || 'success') : 'failed')),
4414
+ ((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight) && h('div', null, h('strong', null, T_KEY(t, 'dryRun.preflight') + ': '), h('span', null, (((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight).passed) ? '✓ Passed' : '✗ Failed (' + ((((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight).reason) || '') + ')')),
4415
+ h('div', null, h('strong', null, T_KEY(t, 'dryRun.duration') + ': '), h('span', null, (((dryRunResult.result && dryRunResult.result.durationMs) !== undefined ? dryRunResult.result.durationMs : dryRunResult.durationMs) || 0) + 'ms')),
4416
+ h('div', { style: { marginTop: '6px' } }, h('strong', null, T_KEY(t, 'dryRun.output') + ':')),
4417
+ h('pre', {
4227
4418
  style: {
4228
4419
  background: 'var(--dsw-alias-bg-layer-2)',
4229
4420
  border: '1px solid var(--dsw-alias-border-l2)',
@@ -4238,8 +4429,8 @@ color: 'var(--dsw-alias-label-primary)'
4238
4429
  }
4239
4430
  }, ((dryRunResult.result && dryRunResult.result.output) !== undefined ? dryRunResult.result.output : (dryRunResult.output !== undefined ? dryRunResult.output : ((dryRunResult.result && dryRunResult.result.error) || dryRunResult.error || '(no output)'))))
4240
4431
  ),
4241
- React.createElement('div', { className: 'dsh-cron-modal-foot', style: { marginTop: '16px' } },
4242
- React.createElement('button', {
4432
+ h('div', { className: 'dsh-cron-modal-foot', style: { marginTop: '16px' } },
4433
+ h('button', {
4243
4434
  type: 'button',
4244
4435
  className: 'dsh-cron-btn-primary',
4245
4436
  onClick: () => setDryRunResult(null)
@@ -4247,29 +4438,29 @@ onClick: () => setDryRunResult(null)
4247
4438
  )
4248
4439
  )
4249
4440
  ),
4250
- archiveModalOpen && React.createElement('div', { className: 'dsh-cron-modal-overlay', onClick: () => setArchiveModalOpen(false) },
4251
- React.createElement('div', {
4441
+ archiveModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setArchiveModalOpen(false) },
4442
+ h('div', {
4252
4443
  className: 'dsh-cron-modal',
4253
4444
  style: { maxWidth: '700px' },
4254
4445
  role: 'dialog',
4255
4446
  'aria-modal': 'true',
4256
4447
  onClick: (e) => e.stopPropagation()
4257
4448
  },
4258
- React.createElement('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
4259
- React.createElement('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, T_KEY(t, 'archive.title') + (archiveTask ? ' - ' + archiveTask.title : '')),
4260
- React.createElement('button', {
4449
+ h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
4450
+ h('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, T_KEY(t, 'archive.title') + (archiveTask ? ' - ' + archiveTask.title : '')),
4451
+ h('button', {
4261
4452
  type: 'button',
4262
4453
  className: 'dsh-cron-icon-btn',
4263
4454
  onClick: () => setArchiveModalOpen(false)
4264
4455
  }, '✕')
4265
4456
  ),
4266
- React.createElement('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #999)', margin: '4px 0 12px 0' } },
4457
+ h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #999)', margin: '4px 0 12px 0' } },
4267
4458
  T_KEY(t, 'archive.totalRuns', { total: archiveTotal })
4268
4459
  ),
4269
- archiveLoading ? React.createElement('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.loading')) :
4270
- archiveRuns.length === 0 ? React.createElement('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'archive.empty')) :
4271
- React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', maxHeight: '380px', overflowY: 'auto' } },
4272
- archiveRuns.map((r, idx) => React.createElement('div', {
4460
+ archiveLoading ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.loading')) :
4461
+ archiveRuns.length === 0 ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'archive.empty')) :
4462
+ h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', maxHeight: '380px', overflowY: 'auto' } },
4463
+ archiveRuns.map((r, idx) => h('div', {
4273
4464
  key: idx,
4274
4465
  style: {
4275
4466
  background: 'var(--dsw-alias-bg-layer-2)',
@@ -4279,21 +4470,21 @@ padding: '8px 12px',
4279
4470
  fontSize: '12px'
4280
4471
  }
4281
4472
  },
4282
- React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', marginBottom: '4px' } },
4283
- React.createElement('span', { style: { fontWeight: '600', color: r.status === 'success' ? 'var(--dsh-cron-success)' : 'var(--dsh-cron-danger)' } }, (r.status || 'unknown').toUpperCase()),
4284
- React.createElement('span', { style: { color: 'var(--dsw-alias-label-secondary, #888)' } }, (r.at || r.timestamp || r.startedAt) ? new Date(r.at || r.timestamp || r.startedAt).toLocaleString() : "")
4473
+ h('div', { style: { display: 'flex', justifyContent: 'space-between', marginBottom: '4px' } },
4474
+ h('span', { style: { fontWeight: '600', color: r.status === 'success' ? 'var(--dsh-cron-success)' : 'var(--dsh-cron-danger)' } }, (r.status || 'unknown').toUpperCase()),
4475
+ h('span', { style: { color: 'var(--dsw-alias-label-secondary, #888)' } }, (r.at || r.timestamp || r.startedAt) ? new Date(r.at || r.timestamp || r.startedAt).toLocaleString() : "")
4285
4476
  ),
4286
- r.durationMs > 0 && React.createElement('div', { style: { color: 'var(--dsw-alias-label-secondary, #888)', marginBottom: '4px' } }, 'Duration: ' + r.durationMs + 'ms'),
4287
- r.chainRunId && React.createElement('div', { style: { marginBottom: '4px' } },
4288
- React.createElement('button', {
4477
+ r.durationMs > 0 && h('div', { style: { color: 'var(--dsw-alias-label-secondary, #888)', marginBottom: '4px' } }, 'Duration: ' + r.durationMs + 'ms'),
4478
+ r.chainRunId && h('div', { style: { marginBottom: '4px' } },
4479
+ h('button', {
4289
4480
  type: 'button',
4290
4481
  className: 'dsh-cron-btn-secondary',
4291
4482
  style: { padding: '2px 8px', fontSize: '11px', display: 'inline-flex', alignItems: 'center', gap: '4px' },
4292
4483
  onClick: () => openChainGraphModal(null, r.chainRunId)
4293
4484
  }, '🕸️ ' + T_KEY(t, 'chainGraph.viewGraph'))
4294
4485
  ),
4295
- r.error && React.createElement('div', { style: { color: 'var(--dsh-cron-danger)', marginBottom: '4px' } }, 'Error: ' + r.error),
4296
- r.output && React.createElement('div', {
4486
+ r.error && h('div', { style: { color: 'var(--dsh-cron-danger)', marginBottom: '4px' } }, 'Error: ' + r.error),
4487
+ r.output && h('div', {
4297
4488
  style: {
4298
4489
  color: 'var(--dsw-alias-label-primary, #ccc)',
4299
4490
  whiteSpace: 'pre-wrap',
@@ -4304,16 +4495,16 @@ overflowY: 'auto'
4304
4495
  }, r.output.slice(0, 300) + (r.output.length > 300 ? '...' : ''))
4305
4496
  ))
4306
4497
  ),
4307
- React.createElement('div', { className: 'dsh-cron-modal-foot', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '16px' } },
4308
- archiveRuns.length < archiveTotal ? React.createElement('button', {
4498
+ h('div', { className: 'dsh-cron-modal-foot', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '16px' } },
4499
+ archiveRuns.length < archiveTotal ? h('button', {
4309
4500
  type: 'button',
4310
4501
  className: 'dsh-cron-btn-secondary',
4311
4502
  onClick: () => {
4312
4503
  const nextOffset = archiveRuns.length;
4313
4504
  if (archiveTask) openArchiveModal(archiveTask, nextOffset);
4314
4505
  }
4315
- }, T_KEY(t, 'archive.loadMore', { shown: archiveRuns.length, total: archiveTotal })) : React.createElement('div', null),
4316
- React.createElement('button', {
4506
+ }, T_KEY(t, 'archive.loadMore', { shown: archiveRuns.length, total: archiveTotal })) : h('div', null),
4507
+ h('button', {
4317
4508
  type: 'button',
4318
4509
  className: 'dsh-cron-btn-primary',
4319
4510
  onClick: () => setArchiveModalOpen(false)
@@ -4321,54 +4512,54 @@ onClick: () => setArchiveModalOpen(false)
4321
4512
  )
4322
4513
  )
4323
4514
  ),
4324
- settingsModalOpen && React.createElement('div', { className: 'dsh-cron-modal-overlay', onClick: () => setSettingsModalOpen(false) },
4325
- React.createElement('div', { className: 'dsh-cron-modal dsh-cron-modal-scroll', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
4326
- React.createElement('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '18px' } },
4327
- React.createElement('div', { className: 'dsh-cron-modal-title', style: { margin: 0, display: 'flex', alignItems: 'center', gap: '8px' } },
4328
- React.createElement('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
4515
+ settingsModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setSettingsModalOpen(false) },
4516
+ h('div', { className: 'dsh-cron-modal dsh-cron-modal-scroll', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
4517
+ h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '18px' } },
4518
+ h('div', { className: 'dsh-cron-modal-title', style: { margin: 0, display: 'flex', alignItems: 'center', gap: '8px' } },
4519
+ h('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
4329
4520
  T_KEY(t, 'settings.modalTitle')
4330
4521
  ),
4331
- React.createElement('button', {
4522
+ h('button', {
4332
4523
  type: 'button',
4333
4524
  style: { background: 'none', border: 'none', color: 'var(--dsw-alias-label-tertiary, #888)', cursor: 'pointer', fontSize: '18px' },
4334
4525
  onClick: () => setSettingsModalOpen(false)
4335
4526
  }, '✕')
4336
4527
  ),
4337
- React.createElement('form', { onSubmit: handleSaveSettings },
4338
- React.createElement('div', { className: 'dsh-cron-form-group' },
4339
- React.createElement('label', null, T_KEY(t, 'settings.tokenLabel')),
4340
- React.createElement('input', {
4528
+ h('form', { onSubmit: handleSaveSettings },
4529
+ h('div', { className: 'dsh-cron-form-group' },
4530
+ h('label', null, T_KEY(t, 'settings.tokenLabel')),
4531
+ h('input', {
4341
4532
  type: 'password',
4342
4533
  value: settingsBotToken,
4343
4534
  placeholder: settingsHasDefault ? T_KEY(t, 'settings.tokenPlaceholderDefault') : T_KEY(t, 'settings.tokenPlaceholder'),
4344
4535
  onChange: (e) => setSettingsBotToken(e.target.value)
4345
4536
  }),
4346
- settingsHasDefault && React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'settings.defaultHint'))
4537
+ settingsHasDefault && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'settings.defaultHint'))
4347
4538
  ),
4348
- React.createElement('div', { className: 'dsh-cron-form-group' },
4349
- React.createElement('label', null, T_KEY(t, 'settings.chatIdLabel')),
4350
- React.createElement('input', {
4539
+ h('div', { className: 'dsh-cron-form-group' },
4540
+ h('label', null, T_KEY(t, 'settings.chatIdLabel')),
4541
+ h('input', {
4351
4542
  value: settingsChatId,
4352
4543
  placeholder: T_KEY(t, 'settings.chatIdPlaceholder'),
4353
4544
  onChange: (e) => setSettingsChatId(e.target.value)
4354
4545
  })
4355
4546
  ),
4356
- React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: '8px', padding: '12px 14px', marginBottom: '16px' } },
4357
- React.createElement('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: '8px' } },
4358
- React.createElement('input', {
4547
+ h('div', { style: { background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: '8px', padding: '12px 14px', marginBottom: '16px' } },
4548
+ h('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: '8px' } },
4549
+ h('input', {
4359
4550
  type: 'checkbox',
4360
4551
  checked: settingsNotifyGlobal,
4361
4552
  onChange: (e) => setSettingsNotifyGlobal(e.target.checked)
4362
4553
  }),
4363
- React.createElement('span', null, T_KEY(t, 'settings.globalNotify'))
4554
+ h('span', null, T_KEY(t, 'settings.globalNotify'))
4364
4555
  ),
4365
- React.createElement('label', { className: 'dsh-cron-checkbox-row' },
4366
- React.createElement('input', {
4556
+ h('label', { className: 'dsh-cron-checkbox-row' },
4557
+ h('input', {
4367
4558
  type: 'checkbox',
4368
4559
  checked: settingsOnlyOnFailureGlobal,
4369
4560
  onChange: (e) => setSettingsOnlyOnFailureGlobal(e.target.checked)
4370
4561
  }),
4371
- React.createElement('span', null, T_KEY(t, 'settings.globalOnlyFailure'))
4562
+ h('span', null, T_KEY(t, 'settings.globalOnlyFailure'))
4372
4563
  )
4373
4564
  ),
4374
4565
  ...renderDeliverySettings({
@@ -4379,8 +4570,8 @@ onChannelTemplate: updateChannelTemplate,
4379
4570
  sections: settingsSections,
4380
4571
  onToggleSection: toggleDeliverySection,
4381
4572
  }),
4382
- React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '14px' } },
4383
- React.createElement('button', {
4573
+ h('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '14px' } },
4574
+ h('button', {
4384
4575
  type: 'button',
4385
4576
  className: 'dsh-cron-btn-secondary',
4386
4577
  style: { display: 'inline-flex', alignItems: 'center', gap: '6px' },
@@ -4388,17 +4579,17 @@ disabled: testStatus?.loading,
4388
4579
  onClick: handleTestTelegram
4389
4580
  }, testStatus?.loading ? T_KEY(t, 'settings.sending') : T_KEY(t, 'settings.testTelegram'))
4390
4581
  ),
4391
- testStatus && testStatus.message && React.createElement('div', {
4582
+ testStatus && testStatus.message && h('div', {
4392
4583
  className: 'dsh-cron-status-banner',
4393
4584
  'data-type': testStatus.success ? 'success' : 'error'
4394
4585
  }, testStatus.message),
4395
- React.createElement('div', { className: 'dsh-cron-modal-foot' },
4396
- React.createElement('button', {
4586
+ h('div', { className: 'dsh-cron-modal-foot' },
4587
+ h('button', {
4397
4588
  type: 'button',
4398
4589
  className: 'dsh-cron-btn-secondary',
4399
4590
  onClick: () => setSettingsModalOpen(false)
4400
4591
  }, T_KEY(t, 'modal.cancel')),
4401
- React.createElement('button', {
4592
+ h('button', {
4402
4593
  type: 'submit',
4403
4594
  className: 'dsh-cron-btn-primary'
4404
4595
  }, T_KEY(t, 'settings.save'))
@@ -4406,12 +4597,12 @@ className: 'dsh-cron-btn-primary'
4406
4597
  )
4407
4598
  )
4408
4599
  ),
4409
- importDoc && React.createElement('div', { className: 'dsh-cron-modal-overlay', onClick: () => !transferBusy && setImportDoc(null) },
4410
- React.createElement('div', { className: 'dsh-cron-modal', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
4411
- React.createElement('div', { className: 'dsh-cron-modal-title' }, T_KEY(t, 'transfer.importTitleModal')),
4412
- React.createElement('div', { className: 'dsh-cron-hint', style: { marginBottom: '10px' } }, T_KEY(t, 'transfer.importHint')),
4413
- importSummary && React.createElement('div', null,
4414
- React.createElement('div', { style: { fontSize: '13px', marginBottom: '12px' } },
4600
+ importDoc && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => !transferBusy && setImportDoc(null) },
4601
+ h('div', { className: 'dsh-cron-modal', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
4602
+ h('div', { className: 'dsh-cron-modal-title' }, T_KEY(t, 'transfer.importTitleModal')),
4603
+ h('div', { className: 'dsh-cron-hint', style: { marginBottom: '10px' } }, T_KEY(t, 'transfer.importHint')),
4604
+ importSummary && h('div', null,
4605
+ h('div', { style: { fontSize: '13px', marginBottom: '12px' } },
4415
4606
  T_KEY(t, 'transfer.summary', {
4416
4607
  total: (importSummary.add || 0) + (importSummary.replace || 0) + (importSummary.skip || 0),
4417
4608
  add: importSummary.add || 0,
@@ -4419,26 +4610,26 @@ replace: importSummary.replace || 0,
4419
4610
  skip: importSummary.skip || 0
4420
4611
  })
4421
4612
  ),
4422
- React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', marginBottom: '14px' } },
4423
- ...['add', 'replace', 'skip'].map((mode) => React.createElement('label', { key: mode, className: 'dsh-cron-checkbox-row' },
4424
- React.createElement('input', {
4613
+ h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', marginBottom: '14px' } },
4614
+ ...['add', 'replace', 'skip'].map((mode) => h('label', { key: mode, className: 'dsh-cron-checkbox-row' },
4615
+ h('input', {
4425
4616
  type: 'radio',
4426
4617
  name: 'dsh-cron-import-strategy',
4427
4618
  checked: importStrategy === mode,
4428
4619
  onChange: () => setImportStrategy(mode)
4429
4620
  }),
4430
- React.createElement('span', null, T_KEY(t, mode === 'add' ? 'transfer.strategyAdd' : mode === 'replace' ? 'transfer.strategyReplace' : 'transfer.strategySkip'))
4621
+ h('span', null, T_KEY(t, mode === 'add' ? 'transfer.strategyAdd' : mode === 'replace' ? 'transfer.strategyReplace' : 'transfer.strategySkip'))
4431
4622
  ))
4432
4623
  )
4433
4624
  ),
4434
- React.createElement('div', { className: 'dsh-cron-modal-foot' },
4435
- React.createElement('button', {
4625
+ h('div', { className: 'dsh-cron-modal-foot' },
4626
+ h('button', {
4436
4627
  type: 'button',
4437
4628
  className: 'dsh-cron-btn-secondary',
4438
4629
  disabled: transferBusy,
4439
4630
  onClick: () => setImportDoc(null)
4440
4631
  }, T_KEY(t, 'modal.cancel')),
4441
- React.createElement('button', {
4632
+ h('button', {
4442
4633
  type: 'button',
4443
4634
  className: 'dsh-cron-btn-primary',
4444
4635
  disabled: transferBusy || !importSummary,
@@ -4447,13 +4638,13 @@ onClick: handleImportConfirm
4447
4638
  )
4448
4639
  )
4449
4640
  ),
4450
- dshModalOpen && React.createElement('div', { className: 'dsh-cron-modal-overlay', onClick: () => !dshLoading && setDshModalOpen(false) },
4451
- React.createElement('div', { className: 'dsh-cron-modal', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
4452
- React.createElement('div', { className: 'dsh-cron-modal-title' }, T_KEY(t, 'dsh.modalTitle')),
4453
- React.createElement('div', { className: 'dsh-cron-form-group' },
4454
- React.createElement('label', null, T_KEY(t, 'dsh.descLabel')),
4455
- React.createElement('div', { className: 'dsh-cron-chat-box' },
4456
- React.createElement('textarea', {
4641
+ dshModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => !dshLoading && setDshModalOpen(false) },
4642
+ h('div', { className: 'dsh-cron-modal', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
4643
+ h('div', { className: 'dsh-cron-modal-title' }, T_KEY(t, 'dsh.modalTitle')),
4644
+ h('div', { className: 'dsh-cron-form-group' },
4645
+ h('label', null, T_KEY(t, 'dsh.descLabel')),
4646
+ h('div', { className: 'dsh-cron-chat-box' },
4647
+ h('textarea', {
4457
4648
  className: 'dsh-cron-chat-input',
4458
4649
  rows: 4,
4459
4650
  autoFocus: true,
@@ -4468,22 +4659,22 @@ handleStartWithDSH();
4468
4659
  },
4469
4660
  onChange: (e) => setDshPrompt(e.target.value)
4470
4661
  }),
4471
- React.createElement('div', { className: 'dsh-cron-chat-foot' },
4472
- React.createElement('span', { className: 'dsh-cron-chat-hint' }, T_KEY(t, 'dsh.sendHint')),
4473
- React.createElement('button', {
4662
+ h('div', { className: 'dsh-cron-chat-foot' },
4663
+ h('span', { className: 'dsh-cron-chat-hint' }, T_KEY(t, 'dsh.sendHint')),
4664
+ h('button', {
4474
4665
  type: 'button',
4475
4666
  className: 'dsh-cron-send-btn',
4476
4667
  disabled: dshLoading || !dshPrompt.trim(),
4477
4668
  title: T_KEY(t, 'dsh.sendTitle'),
4478
4669
  onClick: handleStartWithDSH
4479
4670
  },
4480
- React.createElement('span', svgProps(ICON_SEND))
4671
+ h('span', svgProps(ICON_SEND))
4481
4672
  )
4482
4673
  )
4483
4674
  )
4484
4675
  ),
4485
- React.createElement('div', { className: 'dsh-cron-modal-foot' },
4486
- React.createElement('button', {
4676
+ h('div', { className: 'dsh-cron-modal-foot' },
4677
+ h('button', {
4487
4678
  type: 'button',
4488
4679
  className: 'dsh-cron-btn-secondary',
4489
4680
  disabled: dshLoading,
@@ -4694,15 +4885,15 @@ setTestInfo({ success: false, message: T_KEY(t, 'settings.kanbanFail', { error:
4694
4885
  }
4695
4886
  };
4696
4887
  if (loadState !== 'ready') {
4697
- return React.createElement('div', { className: 'dsh-cron-card' },
4698
- React.createElement('div', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
4699
- React.createElement('div', {
4888
+ return h('div', { className: 'dsh-cron-card' },
4889
+ h('div', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
4890
+ h('div', {
4700
4891
  className: 'dsh-cron-status-banner',
4701
4892
  'data-type': loadState === 'error' ? 'error' : 'info',
4702
4893
  style: { marginTop: '10px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '10px' }
4703
4894
  },
4704
- React.createElement('span', null, loadState === 'error' ? T_KEY(t, 'settings.unavailable') : T_KEY(t, 'settings.loading')),
4705
- loadState === 'error' && React.createElement('button', {
4895
+ h('span', null, loadState === 'error' ? T_KEY(t, 'settings.unavailable') : T_KEY(t, 'settings.loading')),
4896
+ loadState === 'error' && h('button', {
4706
4897
  type: 'button',
4707
4898
  className: 'dsh-cron-btn-secondary',
4708
4899
  onClick: () => setReloadTick(x => x + 1)
@@ -4711,88 +4902,88 @@ onClick: () => setReloadTick(x => x + 1)
4711
4902
  );
4712
4903
  }
4713
4904
  if (props && props.view === 'summary') {
4714
- return React.createElement('span', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc'));
4905
+ return h('span', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc'));
4715
4906
  }
4716
4907
  const page = !!(props && props.view === 'page');
4717
- return React.createElement('div', { className: page ? 'dsh-cron-page' : 'dsh-cron-card' },
4718
- React.createElement('button', {
4908
+ return h('div', { className: page ? 'dsh-cron-page' : 'dsh-cron-card' },
4909
+ h('button', {
4719
4910
  type: 'button',
4720
4911
  className: 'dsh-cron-card-head-btn',
4721
4912
  style: page ? { display: 'none' } : undefined,
4722
4913
  'aria-expanded': (page || cardOpen) ? 'true' : 'false',
4723
4914
  onClick: () => setCardOpen(!cardOpen)
4724
4915
  },
4725
- React.createElement('span', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
4726
- React.createElement('span', { className: 'dsh-cron-chev' + (cardOpen ? ' dsh-cron-chev-open' : '') }, chevronNode())
4916
+ h('span', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
4917
+ h('span', { className: 'dsh-cron-chev' + (cardOpen ? ' dsh-cron-chev-open' : '') }, chevronNode())
4727
4918
  ),
4728
- (page || cardOpen) && React.createElement('div', { className: 'dsh-cron-card-body' },
4729
- React.createElement('div', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc')),
4730
- React.createElement('div', { style: { display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' } },
4731
- React.createElement('button', {
4919
+ (page || cardOpen) && h('div', { className: 'dsh-cron-card-body' },
4920
+ h('div', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc')),
4921
+ h('div', { style: { display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' } },
4922
+ h('button', {
4732
4923
  type: 'button',
4733
4924
  className: 'dsh-cron-btn-primary',
4734
4925
  onClick: () => { if (toggle) toggle.set(true); }
4735
4926
  }, T_KEY(t, 'settings.openPanel'))
4736
4927
  ),
4737
- React.createElement('form', { onSubmit: saveSettings, style: { display: 'flex', flexDirection: 'column', gap: '12px' } },
4738
- React.createElement('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
4739
- React.createElement('label', null, T_KEY(t, 'settings.tokenLabel')),
4740
- React.createElement('input', {
4928
+ h('form', { onSubmit: saveSettings, style: { display: 'flex', flexDirection: 'column', gap: '12px' } },
4929
+ h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
4930
+ h('label', null, T_KEY(t, 'settings.tokenLabel')),
4931
+ h('input', {
4741
4932
  type: 'password',
4742
4933
  value: token,
4743
4934
  placeholder: hasDefault ? T_KEY(t, 'settings.tokenPlaceholderDefault') : T_KEY(t, 'settings.tokenPlaceholder'),
4744
4935
  onChange: (e) => setToken(e.target.value)
4745
4936
  }),
4746
- hasDefault && React.createElement('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'settings.defaultHint'))
4937
+ hasDefault && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'settings.defaultHint'))
4747
4938
  ),
4748
- React.createElement('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
4749
- React.createElement('label', null, T_KEY(t, 'settings.chatIdLabel')),
4750
- React.createElement('input', {
4939
+ h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
4940
+ h('label', null, T_KEY(t, 'settings.chatIdLabel')),
4941
+ h('input', {
4751
4942
  value: chatId,
4752
4943
  placeholder: T_KEY(t, 'settings.chatIdPlaceholder'),
4753
4944
  onChange: (e) => setChatId(e.target.value)
4754
4945
  })
4755
4946
  ),
4756
- React.createElement('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
4757
- React.createElement('label', null, T_KEY(t, 'settings.kanbanUrlLabel')),
4758
- React.createElement('input', {
4947
+ h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
4948
+ h('label', null, T_KEY(t, 'settings.kanbanUrlLabel')),
4949
+ h('input', {
4759
4950
  value: kanbanUrl,
4760
4951
  placeholder: 'http://127.0.0.1:3000',
4761
4952
  onChange: (e) => setKanbanUrl(e.target.value)
4762
4953
  })
4763
4954
  ),
4764
- React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: '6px', padding: '10px 12px', display: 'flex', flexDirection: 'column', gap: '8px' } },
4765
- React.createElement('label', { className: 'dsh-cron-checkbox-row' },
4766
- React.createElement('input', {
4955
+ h('div', { style: { background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: '6px', padding: '10px 12px', display: 'flex', flexDirection: 'column', gap: '8px' } },
4956
+ h('label', { className: 'dsh-cron-checkbox-row' },
4957
+ h('input', {
4767
4958
  type: 'checkbox',
4768
4959
  checked: notify,
4769
4960
  onChange: (e) => setNotify(e.target.checked)
4770
4961
  }),
4771
- React.createElement('span', null, T_KEY(t, 'settings.globalNotify'))
4962
+ h('span', null, T_KEY(t, 'settings.globalNotify'))
4772
4963
  ),
4773
- React.createElement('label', { className: 'dsh-cron-checkbox-row' },
4774
- React.createElement('input', {
4964
+ h('label', { className: 'dsh-cron-checkbox-row' },
4965
+ h('input', {
4775
4966
  type: 'checkbox',
4776
4967
  checked: onlyFailure,
4777
4968
  onChange: (e) => setOnlyFailure(e.target.checked)
4778
4969
  }),
4779
- React.createElement('span', null, T_KEY(t, 'settings.globalOnlyFailure'))
4970
+ h('span', null, T_KEY(t, 'settings.globalOnlyFailure'))
4780
4971
  ),
4781
- React.createElement('label', { className: 'dsh-cron-checkbox-row' },
4782
- React.createElement('input', {
4972
+ h('label', { className: 'dsh-cron-checkbox-row' },
4973
+ h('input', {
4783
4974
  type: 'checkbox',
4784
4975
  checked: llmActionsEnabled,
4785
4976
  onChange: (e) => setLlmActionsEnabled(e.target.checked)
4786
4977
  }),
4787
- React.createElement('span', null, 'Enable Structured LLM Actions (trigger tasks, notify, create issues)')
4978
+ h('span', null, 'Enable Structured LLM Actions (trigger tasks, notify, create issues)')
4788
4979
  ),
4789
- React.createElement('label', { className: 'dsh-cron-checkbox-row' },
4790
- React.createElement('input', {
4980
+ h('label', { className: 'dsh-cron-checkbox-row' },
4981
+ h('input', {
4791
4982
  type: 'checkbox',
4792
4983
  checked: enableDynamicCredentials,
4793
4984
  onChange: (e) => setEnableDynamicCredentials(e.target.checked)
4794
4985
  }),
4795
- React.createElement('span', null, T_KEY(t, 'settings.dynamicCredentials'))
4986
+ h('span', null, T_KEY(t, 'settings.dynamicCredentials'))
4796
4987
  )
4797
4988
  ),
4798
4989
  ...renderDeliverySettings({
@@ -4813,12 +5004,12 @@ return Object.assign({}, prev, { channelTemplates: templates });
4813
5004
  sections,
4814
5005
  onToggleSection: (key) => setSections((prev) => Object.assign({}, prev, { [key]: !prev[key] })),
4815
5006
  }),
4816
- testInfo && testInfo.message && React.createElement('div', {
5007
+ testInfo && testInfo.message && h('div', {
4817
5008
  className: 'dsh-cron-status-banner',
4818
5009
  'data-type': testInfo.success ? 'success' : 'error',
4819
5010
  style: { margin: 0, padding: '8px 12px' }
4820
5011
  }, testInfo.message),
4821
- React.createElement('div', {
5012
+ h('div', {
4822
5013
  className: 'dsh-cron-form-group',
4823
5014
  style: {
4824
5015
  background: 'var(--dsw-alias-bg-layer-2, color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent))',
@@ -4828,19 +5019,19 @@ padding: '14px',
4828
5019
  marginBottom: '16px'
4829
5020
  }
4830
5021
  },
4831
- React.createElement('div', {
5022
+ h('div', {
4832
5023
  style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }
4833
5024
  },
4834
- React.createElement('div', { style: { fontWeight: '600', fontSize: '14px' } }, `🚀 ${T_KEY(t, 'updater.title')}`),
4835
- React.createElement('div', { style: { display: 'flex', gap: '8px' } },
4836
- React.createElement('button', {
5025
+ h('div', { style: { fontWeight: '600', fontSize: '14px' } }, `🚀 ${T_KEY(t, 'updater.title')}`),
5026
+ h('div', { style: { display: 'flex', gap: '8px' } },
5027
+ h('button', {
4837
5028
  type: 'button',
4838
5029
  className: 'dsh-cron-btn-secondary',
4839
5030
  style: { padding: '4px 10px', fontSize: '12px' },
4840
5031
  disabled: updateState.checking || updateState.updating,
4841
5032
  onClick: checkUpdates
4842
5033
  }, updateState.checking ? T_KEY(t, 'updater.checking') : T_KEY(t, 'updater.btnCheck')),
4843
- updateState.updateAvailable ? React.createElement('button', {
5034
+ updateState.updateAvailable ? h('button', {
4844
5035
  type: 'button',
4845
5036
  className: 'dsh-cron-btn-primary',
4846
5037
  style: { padding: '4px 10px', fontSize: '12px' },
@@ -4849,39 +5040,39 @@ onClick: runUpdate
4849
5040
  }, updateState.updating ? T_KEY(t, 'updater.updating') : T_KEY(t, 'updater.btnUpdate', { version: updateState.latestVersion })) : null
4850
5041
  )
4851
5042
  ),
4852
- React.createElement('div', {
5043
+ h('div', {
4853
5044
  style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #999)', marginBottom: '8px' }
4854
5045
  }, T_KEY(t, 'updater.desc')),
4855
- React.createElement('div', {
5046
+ h('div', {
4856
5047
  style: { display: 'flex', alignItems: 'center', gap: '12px', fontSize: '13px' }
4857
5048
  },
4858
- React.createElement('span', { style: { color: 'var(--dsw-alias-label-secondary, #aaa)' } },
5049
+ h('span', { style: { color: 'var(--dsw-alias-label-secondary, #aaa)' } },
4859
5050
  updateState.currentVersion ? T_KEY(t, 'updater.current', { version: updateState.currentVersion }) : ''
4860
5051
  ),
4861
- updateState.checking ? React.createElement('span', { className: 'dsh-cron-badge dsh-cron-badge-info' }, T_KEY(t, 'updater.checking')) :
4862
- updateState.updateAvailable ? React.createElement('span', { className: 'dsh-cron-badge dsh-cron-badge-warn' }, T_KEY(t, 'updater.available', { version: updateState.latestVersion })) :
4863
- updateState.currentVersion && !updateState.error && !updateState.checking ? React.createElement('span', { className: 'dsh-cron-badge dsh-cron-badge-ok' }, `✓ ${T_KEY(t, 'updater.upToDate')}`) : null
5052
+ updateState.checking ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-info' }, T_KEY(t, 'updater.checking')) :
5053
+ updateState.updateAvailable ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-warn' }, T_KEY(t, 'updater.available', { version: updateState.latestVersion })) :
5054
+ updateState.currentVersion && !updateState.error && !updateState.checking ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-ok' }, `✓ ${T_KEY(t, 'updater.upToDate')}`) : null
4864
5055
  ),
4865
- updateState.notice ? React.createElement('div', {
5056
+ updateState.notice ? h('div', {
4866
5057
  style: { marginTop: '8px', color: 'var(--dsw-alias-success)', fontSize: '12px' }
4867
5058
  }, updateState.notice) : null,
4868
- updateState.error ? React.createElement('div', {
5059
+ updateState.error ? h('div', {
4869
5060
  style: { marginTop: '8px', color: 'var(--dsw-alias-error)', fontSize: '12px' }
4870
5061
  }, updateState.error) : null
4871
5062
  ),
4872
- React.createElement('div', { style: { display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap', marginTop: '4px' } },
4873
- React.createElement('button', {
5063
+ h('div', { style: { display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap', marginTop: '4px' } },
5064
+ h('button', {
4874
5065
  type: 'submit',
4875
5066
  className: 'dsh-cron-btn-primary',
4876
5067
  style: { minWidth: '140px' }
4877
5068
  }, saved ? T_KEY(t, 'settings.saved') : T_KEY(t, 'settings.save')),
4878
- React.createElement('button', {
5069
+ h('button', {
4879
5070
  type: 'button',
4880
5071
  className: 'dsh-cron-btn-secondary',
4881
5072
  onClick: testTelegram,
4882
5073
  disabled: testInfo?.loading
4883
5074
  }, T_KEY(t, 'settings.testTelegram')),
4884
- React.createElement('button', {
5075
+ h('button', {
4885
5076
  type: 'button',
4886
5077
  className: 'dsh-cron-btn-secondary',
4887
5078
  onClick: testKanban,
@@ -5106,9 +5297,9 @@ container.setAttribute('data-dsh-plugin', 'dsh-cron');
5106
5297
  column.appendChild(container);
5107
5298
  if (ReactDOM && typeof ReactDOM.createRoot === 'function') {
5108
5299
  root = ReactDOM.createRoot(container);
5109
- root.render(React.createElement(ErrorBoundary, null, React.createElement(CronScreen, { ctx, toggle, onClose: () => toggle.set(false), t: translate })));
5300
+ root.render(h(ErrorBoundary, null, h(CronScreen, { ctx, toggle, onClose: () => toggle.set(false), t: translate })));
5110
5301
  } else if (ReactDOM && typeof ReactDOM.render === 'function') {
5111
- ReactDOM.render(React.createElement(CronScreen, { ctx, toggle, onClose: () => toggle.set(false), t: translate }), container);
5302
+ ReactDOM.render(h(CronScreen, { ctx, toggle, onClose: () => toggle.set(false), t: translate }), container);
5112
5303
  }
5113
5304
  };
5114
5305
  const applyActive = () => {
@@ -5176,7 +5367,7 @@ translate = ctx.locale.bind(NS);
5176
5367
  }
5177
5368
  const toggle = createToggle();
5178
5369
  function SettingsCardWithBoundary(props) {
5179
- return React.createElement(ErrorBoundary, null, CronSettingsCard(props));
5370
+ return h(ErrorBoundary, null, CronSettingsCard(props));
5180
5371
  }
5181
5372
  const itemOk = registerIntoMount(ctx, 'plugins.item', {
5182
5373
  name: 'plugins.item',
@@ -5215,7 +5406,7 @@ const cardSlot = cardOk ? 'settings.plugin.item' : undefined;
5215
5406
  const chipSlot = chipOk ? 'conversation.session.header.utilities' : undefined;
5216
5407
  function CronChip(props) {
5217
5408
  const chipT = props.t || translate;
5218
- return React.createElement('button', {
5409
+ return h('button', {
5219
5410
  type: 'button',
5220
5411
  style: { background: 'none', border: 'none', color: 'var(--dsw-alias-label-secondary, #999)', cursor: 'pointer', padding: '4px', display: 'inline-flex', alignItems: 'center' },
5221
5412
  title: T_KEY(chipT, 'chip.title'),