@goodandready/dsh-cron 0.2.18 → 0.2.20

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
@@ -11,6 +11,9 @@ window.__ModuleLoader__.load({
11
11
  // namespace registered on the server ('dsh-cron', Issue #85).
12
12
  const PLUGIN_ID = '@goodandready/dsh-cron';
13
13
  const NS = 'dsh-cron';
14
+ // Plugins page row seat (DSH 0.1.6-alpha.2): key = '<package name>#<row id>'.
15
+ const ROW_ID = 'dsh-cron';
16
+ const ROW_CONFIG_KEY = PLUGIN_ID + '#' + ROW_ID;
14
17
  const PANEL = 'cron';
15
18
  const ACTIVATE_EVENT = 'dsh-panel-activate';
16
19
  const ACTIVE_ATTR = 'data-dsh-cron-active';
@@ -49,7 +52,9 @@ window.__ModuleLoader__.load({
49
52
  try {
50
53
  const primitives = require('@deepseek-ai/dsh-client-ui-primitives');
51
54
  CoreChevron = primitives && primitives.IconChevronDownOutline14;
52
- } catch (e) {}
55
+ } catch (e) {
56
+ /* Optional core chevron primitive not available; SVG fallback used */
57
+ }
53
58
  const chevronNode = () => (CoreChevron ? React.createElement(CoreChevron) : React.createElement('span', { style: { display: 'flex', alignItems: 'center' }, dangerouslySetInnerHTML: { __html: ICON_CHEVRON_DOWN } }));
54
59
 
55
60
  // Own React error boundary (#106): the core's SlotErrorBoundary renders an
@@ -622,15 +627,15 @@ window.__ModuleLoader__.load({
622
627
  const STYLES = `
623
628
  :root {
624
629
  --dsh-cron-success: var(--dsw-alias-state-success-primary, #10b981);
625
- --dsh-cron-success-bg: rgba(16, 185, 129, 0.1);
630
+ --dsh-cron-success-bg: color-mix(in srgb, var(--dsh-cron-success, #10b981) 10%, transparent);
626
631
  --dsh-cron-danger: var(--dsw-alias-state-error-primary, #ef4444);
627
- --dsh-cron-danger-bg: rgba(239, 68, 68, 0.1);
632
+ --dsh-cron-danger-bg: color-mix(in srgb, var(--dsh-cron-danger, #ef4444) 10%, transparent);
628
633
  --dsh-cron-info: var(--dsw-alias-state-brand-primary, #60a5fa);
629
- --dsh-cron-info-bg: rgba(96, 165, 250, 0.12);
634
+ --dsh-cron-info-bg: color-mix(in srgb, var(--dsh-cron-info, #60a5fa) 12%, transparent);
630
635
  --dsh-cron-accent: var(--dsw-alias-state-info-primary, #c084fc);
631
- --dsh-cron-accent-bg: rgba(168, 85, 247, 0.12);
636
+ --dsh-cron-accent-bg: color-mix(in srgb, var(--dsh-cron-accent, #a855f7) 12%, transparent);
632
637
  --dsh-cron-warning: var(--dsw-alias-state-warning-primary, #eab308);
633
- --dsh-cron-warning-bg: rgba(234, 179, 8, 0.12);
638
+ --dsh-cron-warning-bg: color-mix(in srgb, var(--dsh-cron-warning, #eab308) 12%, transparent);
634
639
  }
635
640
  [data-pane=conversation], [class*=centerCol] {
636
641
  position: relative !important;
@@ -660,14 +665,14 @@ window.__ModuleLoader__.load({
660
665
 
661
666
  .dsh-cron-top-bar { display: flex; align-items: center; gap: 12px; }
662
667
  .dsh-cron-back-btn { appearance: none; font: inherit; cursor: pointer; color: var(--dsw-alias-label-secondary, #9ca3af); background: 0 0; border: 1px solid var(--dsw-alias-border-l2, #383838); border-radius: 8px; align-items: center; gap: 6px; padding: 4px 12px; font-size: 13px; display: inline-flex; flex: none; height: 32px; box-sizing: border-box; }
663
- .dsh-cron-back-btn:hover { color: var(--dsw-alias-label-primary, #ededed); background: var(--dsw-alias-bg-layer-4, var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,0.06))); }
668
+ .dsh-cron-back-btn:hover { color: var(--dsw-alias-label-primary, #ededed); background: var(--dsw-alias-bg-layer-4, var(--dsw-alias-interactive-bg-hover, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 6%, transparent))); }
664
669
 
665
670
  .dsh-cron-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding-bottom: 16px; border-bottom: 1px solid var(--dsw-alias-border-l2, #383838); }
666
671
  .dsh-cron-title { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 6px; }
667
672
  .dsh-cron-subtitle { font-size: 14px; color: var(--dsw-alias-label-secondary, #9ca3af); line-height: 1.5; }
668
673
  .dsh-cron-create-btn { appearance: none; display: inline-flex; align-items: center; gap: 6px; background: var(--dsw-alias-bg-layer-2, #262626); color: var(--dsw-alias-label-primary, #fff); border: 1px solid var(--dsw-alias-border-l2, #383838); border-radius: 9999px; padding: 8px 16px; font-size: 14px; font-weight: 500; cursor: pointer; position: relative; }
669
674
  .dsh-cron-create-btn:hover { background: var(--dsw-alias-bg-layer-hover, var(--dsw-alias-interactive-bg-hover, #333)); }
670
- .dsh-cron-dropdown { position: absolute; top: calc(100% + 6px); right: 0; width: 200px; background: var(--dsw-alias-bg-layer-3, #212121); border: 1px solid var(--dsw-alias-border-l2, #383838); border-radius: 12px; padding: 6px; box-shadow: 0 10px 25px rgba(0,0,0,0.5); z-index: 200; }
675
+ .dsh-cron-dropdown { position: absolute; top: calc(100% + 6px); right: 0; width: 200px; background: var(--dsw-alias-bg-layer-3, #212121); border: 1px solid var(--dsw-alias-border-l2, #383838); border-radius: 12px; padding: 6px; box-shadow: 0 10px 25px color-mix(in srgb, var(--dsw-alias-bg-mask, #000) 50%, transparent); z-index: 200; }
671
676
  .dsh-cron-dropdown-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px 12px; background: transparent; border: none; border-radius: 8px; color: var(--dsw-alias-label-primary, #ededed); font-size: 13.5px; text-align: left; cursor: pointer; }
672
677
  .dsh-cron-dropdown-item:hover { background: var(--dsw-alias-interactive-bg-hover, #2a2a2a); }
673
678
  .dsh-cron-search-bar { position: relative; margin-bottom: 0; }
@@ -677,7 +682,7 @@ window.__ModuleLoader__.load({
677
682
  .dsh-cron-filters { margin-top: 8px; }
678
683
  .dsh-cron-filter-toggle { background: none; border: 1px solid var(--dsw-alias-border-l2, #333); color: var(--dsw-alias-label-secondary, #aaa); border-radius: 8px; padding: 4px 10px; font-size: 12px; cursor: pointer; }
679
684
  .dsh-cron-filter-toggle:hover { color: var(--dsw-alias-label-primary, #eee); border-color: var(--dsh-cron-info); }
680
- .dsh-cron-filter-panel { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin-top: 10px; padding: 10px 12px; border: 1px solid var(--dsw-alias-border-l2, #2e2e2e); border-radius: 8px; background: var(--dsw-alias-bg-layer-3, rgba(255,255,255,0.02)); }
685
+ .dsh-cron-filter-panel { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin-top: 10px; padding: 10px 12px; border: 1px solid var(--dsw-alias-border-l2, #2e2e2e); border-radius: 8px; background: var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 2%, transparent)); }
681
686
  .dsh-cron-filter-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #888); }
682
687
  .dsh-cron-filter-field select { background: var(--dsw-alias-bg-layer-2, #1f1f1f); border: 1px solid var(--dsw-alias-border-l2, #333); color: var(--dsw-alias-label-primary, inherit); border-radius: 6px; padding: 5px 8px; font-size: 12.5px; }
683
688
  .dsh-cron-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
@@ -694,7 +699,7 @@ window.__ModuleLoader__.load({
694
699
  .dsh-cron-tag-session { background: var(--dsh-cron-info-bg); color: var(--dsh-cron-info); border-color: var(--dsh-cron-info); }
695
700
  .dsh-cron-tag-preflight { background: var(--dsh-cron-warning-bg); color: var(--dsh-cron-warning); border-color: var(--dsh-cron-warning); }
696
701
 
697
- .dsh-cron-task-model-tag { display: inline-flex; align-items: center; font-size: 11px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--dsw-alias-border-l2, #383838); background: var(--dsw-alias-bg-layer-2, rgba(255,255,255,0.06)); color: var(--dsw-alias-label-secondary, #aaa); margin-left: 8px; vertical-align: middle; }
702
+ .dsh-cron-task-model-tag { display: inline-flex; align-items: center; font-size: 11px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--dsw-alias-border-l2, #383838); background: var(--dsw-alias-bg-layer-2, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 6%, transparent)); color: var(--dsw-alias-label-secondary, #aaa); margin-left: 8px; vertical-align: middle; }
698
703
  .dsh-cron-task-actions { display: flex; gap: 8px; }
699
704
  .dsh-cron-icon-btn { appearance: none; font: inherit; background: var(--dsw-alias-bg-layer-2, transparent); border: 1px solid var(--dsw-alias-border-l2, #333); border-radius: 8px; padding: 6px 12px; font-size: 12.5px; font-weight: 500; color: var(--dsw-alias-label-primary, #aaa); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: all 0.15s ease; }
700
705
  .dsh-cron-icon-btn:hover { background: var(--dsw-alias-bg-layer-4, #2a2a2a); border-color: var(--dsw-alias-label-dimmed, var(--dsw-alias-border-l2, #444)); }
@@ -706,14 +711,14 @@ window.__ModuleLoader__.load({
706
711
  .dsh-cron-recs-list { display: flex; flex-direction: column; gap: 10px; }
707
712
  .dsh-cron-rec-card { display: flex; align-items: center; gap: 16px; padding: 14px 18px; background: var(--dsw-alias-bg-layer-3, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #282828); border-radius: 12px; cursor: pointer; transition: background 0.15s; }
708
713
  .dsh-cron-rec-card:hover, .dsh-cron-rec-card:focus-visible { background: var(--dsw-alias-bg-layer-4, #242424); border-color: var(--dsw-alias-label-dimmed, var(--dsw-alias-border-l2, #383838)); outline: none; }
709
- .dsh-cron-rec-icon { width: 36px; height: 36px; border-radius: 10px; background: var(--dsw-alias-bg-layer-2, rgba(255,255,255,0.03)); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
714
+ .dsh-cron-rec-icon { width: 36px; height: 36px; border-radius: 10px; background: var(--dsw-alias-bg-layer-2, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 3%, transparent)); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
710
715
  .dsh-cron-rec-content { flex: 1; min-width: 0; }
711
716
  .dsh-cron-rec-title { font-size: 14.5px; font-weight: 500; margin-bottom: 4px; }
712
717
  .dsh-cron-rec-time { font-size: 13px; color: var(--dsw-alias-label-secondary, #9ca3af); font-weight: normal; margin-left: 8px; }
713
718
  .dsh-cron-rec-desc { font-size: 13px; color: var(--dsw-alias-label-tertiary, #71717a); }
714
719
 
715
- .dsh-cron-modal-overlay { position: fixed; inset: 0; background: var(--dsw-alias-bg-mask, rgba(0, 0, 0, 0.75)); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 16px; box-sizing: border-box; overflow-y: auto; }
716
- .dsh-cron-modal { background: var(--dsw-alias-bg-layer-2, #1f1f1f); border: 1px solid var(--dsw-alias-border-l2, #333); border-radius: 16px; width: 100%; max-width: 540px; max-height: min(90vh, calc(100vh - 36px)); overflow-y: auto; padding: 24px; box-shadow: 0 20px 40px rgba(0,0,0,0.6); box-sizing: border-box; }
720
+ .dsh-cron-modal-overlay { position: fixed; inset: 0; background: var(--dsw-alias-bg-mask, color-mix(in srgb, #000 75%, transparent)); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 16px; box-sizing: border-box; overflow-y: auto; }
721
+ .dsh-cron-modal { background: var(--dsw-alias-bg-layer-2, #1f1f1f); border: 1px solid var(--dsw-alias-border-l2, #333); border-radius: 16px; width: 100%; max-width: 540px; max-height: min(90vh, calc(100vh - 36px)); overflow-y: auto; padding: 24px; box-shadow: 0 20px 40px color-mix(in srgb, var(--dsw-alias-bg-mask, #000) 60%, transparent); box-sizing: border-box; }
717
722
  .dsh-cron-modal-scroll { max-width: 640px; max-height: min(90vh, calc(100vh - 36px)); overflow-y: auto; }
718
723
  .dsh-cron-modal::-webkit-scrollbar { width: 6px; }
719
724
  .dsh-cron-modal::-webkit-scrollbar-track { background: transparent; }
@@ -772,7 +777,7 @@ window.__ModuleLoader__.load({
772
777
  .dsh-cron-history-empty { text-align: center; padding: 36px 0; color: var(--dsw-alias-label-tertiary, #666); font-size: 13.5px; }
773
778
 
774
779
  .dsh-cron-stats-bar { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 0; }
775
- .dsh-cron-stat-card { background: var(--dsw-alias-bg-layer-2, rgba(255, 255, 255, 0.02)); border: 1px solid var(--dsw-alias-border-l2, #222); border-radius: 8px; padding: 12px 14px; display: flex; flex-direction: column; gap: 4px; }
780
+ .dsh-cron-stat-card { background: var(--dsw-alias-bg-layer-2, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 2%, transparent)); border: 1px solid var(--dsw-alias-border-l2, #222); border-radius: 8px; padding: 12px 14px; display: flex; flex-direction: column; gap: 4px; }
776
781
  .dsh-cron-stat-val { font-size: 18px; font-weight: 700; color: var(--dsw-alias-label-primary, #fff); }
777
782
  .dsh-cron-stat-lbl { font-size: 12px; color: var(--dsw-alias-label-secondary, #777); margin-top: 0; }
778
783
  .dsh-cron-oneshot-tag { display: inline-flex; align-items: center; font-size: 11px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--dsh-cron-accent); background: var(--dsh-cron-accent-bg); color: var(--dsh-cron-accent); font-weight: 500; }
@@ -787,7 +792,7 @@ window.__ModuleLoader__.load({
787
792
  .dsh-cron-section-title { font-weight: 500; font-size: 12.5px; color: var(--dsw-alias-label-secondary, #aaa); margin-bottom: 10px; }
788
793
  .dsh-cron-secret-row { display: flex; align-items: center; gap: 8px; }
789
794
  .dsh-cron-secret-row input { flex: 1; }
790
- .dsh-cron-badge-ref { font-size: 11px; padding: 2px 6px; border-radius: 4px; background: var(--dsw-alias-bg-layer-3, rgba(255,255,255,0.06)); color: var(--dsw-alias-label-tertiary, #888); white-space: nowrap; }
795
+ .dsh-cron-badge-ref { font-size: 11px; padding: 2px 6px; border-radius: 4px; background: var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 6%, transparent)); color: var(--dsw-alias-label-tertiary, #888); white-space: nowrap; }
791
796
  .dsh-cron-status-banner { padding: 10px 14px; border-radius: 8px; font-size: 13px; margin-top: 12px; }
792
797
  .dsh-cron-status-banner[data-type="success"] { background: var(--dsh-cron-success-bg); border: 1px solid var(--dsh-cron-success); color: var(--dsh-cron-success); }
793
798
  .dsh-cron-status-banner[data-type="error"] { background: var(--dsh-cron-danger-bg); border: 1px solid var(--dsh-cron-danger); color: var(--dsh-cron-danger); }
@@ -798,13 +803,13 @@ window.__ModuleLoader__.load({
798
803
  /* #34: sidebar job list */
799
804
  .dsh-cron-sidebar-jobs { display: flex; flex-direction: column; gap: 2px; margin: 2px 0 6px 0; }
800
805
  .dsh-cron-sidebar-jobs-head { display: flex; align-items: center; justify-content: space-between; width: 100%; background: none; border: none; padding: 4px 8px; font: inherit; font-size: 12px; color: var(--dsw-alias-label-tertiary, #888); cursor: pointer; border-radius: 6px; text-align: left; }
801
- .dsh-cron-sidebar-jobs-head:hover { color: var(--dsw-alias-label-primary, #eee); background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,0.04)); }
806
+ .dsh-cron-sidebar-jobs-head:hover { color: var(--dsw-alias-label-primary, #eee); background: var(--dsw-alias-interactive-bg-hover, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 4%, transparent)); }
802
807
  .dsh-cron-sidebar-jobs-head::after { content: '▾'; font-size: 10px; transition: transform 0.15s ease; }
803
808
  .dsh-cron-sidebar-jobs[data-open="false"] .dsh-cron-sidebar-jobs-head::after { transform: rotate(-90deg); }
804
809
  .dsh-cron-sidebar-jobs[data-open="false"] .dsh-cron-sidebar-jobs-list { display: none; }
805
810
  .dsh-cron-sidebar-jobs-list { display: flex; flex-direction: column; gap: 2px; padding-left: 10px; }
806
811
  .dsh-cron-sidebar-job { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; width: 100%; background: none; border: none; border-left: 2px solid transparent; padding: 3px 8px; font: inherit; cursor: pointer; border-radius: 0 6px 6px 0; text-align: left; }
807
- .dsh-cron-sidebar-job:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,0.04)); border-left-color: var(--dsh-cron-info); }
812
+ .dsh-cron-sidebar-job:hover { background: var(--dsw-alias-interactive-bg-hover, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 4%, transparent)); border-left-color: var(--dsh-cron-info); }
808
813
  .dsh-cron-sidebar-job-title { font-size: 12px; color: var(--dsw-alias-label-secondary, #ccc); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
809
814
  .dsh-cron-sidebar-job-meta { font-size: 11px; color: var(--dsw-alias-label-tertiary, #777); }
810
815
  .dsh-cron-sidebar-empty, .dsh-cron-sidebar-more { font-size: 11px; color: var(--dsw-alias-label-tertiary, #777); padding: 2px 8px; }
@@ -987,7 +992,9 @@ window.__ModuleLoader__.load({
987
992
  try {
988
993
  sessions.open(sessionId);
989
994
  return true;
990
- } catch (e) {}
995
+ } catch (err) {
996
+ /* sessions.open threw synchronously */
997
+ }
991
998
  }
992
999
 
993
1000
  // 2. If the session is not in manager.summaries yet, refresh from the backend
@@ -996,7 +1003,9 @@ window.__ModuleLoader__.load({
996
1003
  await sessions.refresh();
997
1004
  sessions.open(sessionId);
998
1005
  return true;
999
- } catch (e) {}
1006
+ } catch (err) {
1007
+ /* sessions.refresh threw */
1008
+ }
1000
1009
  }
1001
1010
 
1002
1011
  // 3. Async retries until the WebSocket/SSE event adds the session to the list
@@ -1007,7 +1016,9 @@ window.__ModuleLoader__.load({
1007
1016
  try {
1008
1017
  sessions.open(sessionId);
1009
1018
  return true;
1010
- } catch (e) {}
1019
+ } catch (err) {
1020
+ /* retry polling sessions.open threw */
1021
+ }
1011
1022
  }
1012
1023
  // DOM fallback: click the session in the sidebar if it has rendered
1013
1024
  if (typeof document !== 'undefined') {
@@ -1323,7 +1334,7 @@ window.__ModuleLoader__.load({
1323
1334
  if (!node) return;
1324
1335
  if (typeof node.scrollIntoView === 'function') node.scrollIntoView({ block: 'center' });
1325
1336
  node.classList.add('dsh-cron-task-highlight');
1326
- setTimeout(() => { try { node.classList.remove('dsh-cron-task-highlight'); } catch (_) {} }, 2500);
1337
+ setTimeout(() => { try { node.classList.remove('dsh-cron-task-highlight'); } catch (err) { /* node unmounted */ } }, 2500);
1327
1338
  }, [tasks]);
1328
1339
 
1329
1340
  const fetchTasks = async () => {
@@ -1435,7 +1446,9 @@ window.__ModuleLoader__.load({
1435
1446
  try {
1436
1447
  await fetch('/dsh-cron/tasks/' + encodeURIComponent(id) + '/toggle', { method: 'POST' });
1437
1448
  fetchTasks();
1438
- } catch (err) {}
1449
+ } catch (err) {
1450
+ console.debug('[dsh-cron] toggle failed', err);
1451
+ }
1439
1452
  };
1440
1453
 
1441
1454
  const handleRunNow = async (id) => {
@@ -1650,7 +1663,10 @@ window.__ModuleLoader__.load({
1650
1663
  try {
1651
1664
  await fetch('/dsh-cron/tasks/' + encodeURIComponent(id), { method: 'DELETE' });
1652
1665
  fetchTasks();
1653
- } catch (err) {} };
1666
+ } catch (err) {
1667
+ console.debug('[dsh-cron] delete failed', err);
1668
+ }
1669
+ };
1654
1670
 
1655
1671
  const openSettingsModal = async () => {
1656
1672
  setTestStatus(null);
@@ -1668,7 +1684,9 @@ window.__ModuleLoader__.load({
1668
1684
  setSettingsHasDefault(Boolean(data.settings.hasDefaultCredentials));
1669
1685
  setSettingsHasCustomBotToken(Boolean(data.settings.hasCustomBotToken));
1670
1686
  }
1671
- } catch (e) {}
1687
+ } catch (err) {
1688
+ console.debug('[dsh-cron] settings fetch failed', err);
1689
+ }
1672
1690
  };
1673
1691
 
1674
1692
  const handleSaveSettings = async (e) => {
@@ -2715,7 +2733,7 @@ window.__ModuleLoader__.load({
2715
2733
  React.createElement('label', null, T_KEY(t, 'form.sshTargetLabel')),
2716
2734
  React.createElement('input', {
2717
2735
  value: formSshTarget,
2718
- placeholder: 'root@10.0.0.5',
2736
+ placeholder: 'user@example.com',
2719
2737
  onChange: (e) => setFormSshTarget(e.target.value)
2720
2738
  }),
2721
2739
  React.createElement('input', {
@@ -2828,7 +2846,7 @@ window.__ModuleLoader__.load({
2828
2846
  ),
2829
2847
  React.createElement('div', {
2830
2848
  style: {
2831
- background: 'var(--dsw-alias-bg-layer-3, rgba(255,255,255,0.02))',
2849
+ background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 2%, transparent))',
2832
2850
  border: '1px solid var(--dsw-alias-border-l2, #2e2e2e)',
2833
2851
  borderRadius: '8px',
2834
2852
  padding: '12px 14px',
@@ -2991,7 +3009,7 @@ window.__ModuleLoader__.load({
2991
3009
  ),
2992
3010
  selectedTaskMeta && React.createElement('div', {
2993
3011
  style: {
2994
- background: 'var(--dsw-alias-bg-layer-3, rgba(255,255,255,0.03))',
3012
+ background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 3%, transparent))',
2995
3013
  border: '1px solid var(--dsw-alias-border-l2, #2e2e2e)',
2996
3014
  borderRadius: '8px',
2997
3015
  padding: '10px 14px',
@@ -3181,7 +3199,7 @@ window.__ModuleLoader__.load({
3181
3199
  onChange: (e) => setSettingsChatId(e.target.value)
3182
3200
  })
3183
3201
  ),
3184
- React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-3, rgba(255,255,255,0.02))', border: '1px solid var(--dsw-alias-border-l2, #2e2e2e)', borderRadius: '8px', padding: '12px 14px', marginBottom: '16px' } },
3202
+ React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 2%, transparent))', border: '1px solid var(--dsw-alias-border-l2, #2e2e2e)', borderRadius: '8px', padding: '12px 14px', marginBottom: '16px' } },
3185
3203
  React.createElement('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: '8px' } },
3186
3204
  React.createElement('input', {
3187
3205
  type: 'checkbox',
@@ -3346,7 +3364,7 @@ window.__ModuleLoader__.load({
3346
3364
  const [updateState, setUpdateState] = React.useState({
3347
3365
  checking: false,
3348
3366
  updating: false,
3349
- currentVersion: '0.2.18',
3367
+ currentVersion: '0.2.19',
3350
3368
  latestVersion: undefined,
3351
3369
  updateAvailable: false,
3352
3370
  notice: null,
@@ -3453,7 +3471,9 @@ window.__ModuleLoader__.load({
3453
3471
  setSaved(true);
3454
3472
  setTimeout(() => setSaved(false), 2500);
3455
3473
  }
3456
- } catch (err) {}
3474
+ } catch (err) {
3475
+ console.debug('[dsh-cron] save settings failed', err);
3476
+ }
3457
3477
  };
3458
3478
 
3459
3479
  const testTelegram = async () => {
@@ -3512,17 +3532,24 @@ window.__ModuleLoader__.load({
3512
3532
  );
3513
3533
  }
3514
3534
 
3515
- return React.createElement('div', { className: 'dsh-cron-card' },
3535
+ // Row seat (plugins.row.config): the host page draws title/icon/crumb and the
3536
+ // padding, so the summary is a one-liner and the page drops our card chrome.
3537
+ if (props && props.view === 'summary') {
3538
+ return React.createElement('span', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc'));
3539
+ }
3540
+ const page = !!(props && props.view === 'page');
3541
+ return React.createElement('div', { className: page ? 'dsh-cron-page' : 'dsh-cron-card' },
3516
3542
  React.createElement('button', {
3517
3543
  type: 'button',
3518
3544
  className: 'dsh-cron-card-head-btn',
3519
- 'aria-expanded': cardOpen ? 'true' : 'false',
3545
+ style: page ? { display: 'none' } : undefined,
3546
+ 'aria-expanded': (page || cardOpen) ? 'true' : 'false',
3520
3547
  onClick: () => setCardOpen(!cardOpen)
3521
3548
  },
3522
3549
  React.createElement('span', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
3523
3550
  React.createElement('span', { className: 'dsh-cron-chev' + (cardOpen ? ' dsh-cron-chev-open' : '') }, chevronNode())
3524
3551
  ),
3525
- cardOpen && React.createElement('div', { className: 'dsh-cron-card-body' },
3552
+ (page || cardOpen) && React.createElement('div', { className: 'dsh-cron-card-body' },
3526
3553
  React.createElement('div', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc')),
3527
3554
  React.createElement('div', { style: { display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' } },
3528
3555
  React.createElement('button', {
@@ -3558,7 +3585,7 @@ window.__ModuleLoader__.load({
3558
3585
  onChange: (e) => setKanbanUrl(e.target.value)
3559
3586
  })
3560
3587
  ),
3561
- React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-3, rgba(255,255,255,0.02))', border: '1px solid var(--dsw-alias-border-l2, #2e2e2e)', borderRadius: '6px', padding: '10px 12px', display: 'flex', flexDirection: 'column', gap: '8px' } },
3588
+ React.createElement('div', { style: { background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 2%, transparent))', border: '1px solid var(--dsw-alias-border-l2, #2e2e2e)', borderRadius: '6px', padding: '10px 12px', display: 'flex', flexDirection: 'column', gap: '8px' } },
3562
3589
  React.createElement('label', { className: 'dsh-cron-checkbox-row' },
3563
3590
  React.createElement('input', {
3564
3591
  type: 'checkbox',
@@ -3610,8 +3637,8 @@ window.__ModuleLoader__.load({
3610
3637
  React.createElement('div', {
3611
3638
  className: 'dsh-cron-form-group',
3612
3639
  style: {
3613
- background: 'var(--dsw-alias-bg-layer-2, rgba(255,255,255,0.03))',
3614
- border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,0.08))',
3640
+ background: 'var(--dsw-alias-bg-layer-2, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 3%, transparent))',
3641
+ border: '1px solid var(--dsw-alias-border-l2, color-mix(in srgb, var(--dsw-alias-label-primary, #fff) 8%, transparent))',
3615
3642
  borderRadius: '8px',
3616
3643
  padding: '14px',
3617
3644
  marginBottom: '16px'
@@ -3786,7 +3813,9 @@ window.__ModuleLoader__.load({
3786
3813
  const res = await fetch('/dsh-cron/tasks?status=active');
3787
3814
  const data = await res.json();
3788
3815
  if (data && data.ok) renderSidebarJobs(state, data.tasks || []);
3789
- } catch (_) {}
3816
+ } catch (err) {
3817
+ console.debug('[dsh-cron] load sidebar jobs failed', err);
3818
+ }
3790
3819
  }
3791
3820
 
3792
3821
  function applySidebarJobsOpen(state) {
@@ -3811,7 +3840,7 @@ window.__ModuleLoader__.load({
3811
3840
  event.preventDefault();
3812
3841
  event.stopPropagation();
3813
3842
  state.open = !state.open;
3814
- try { window.localStorage.setItem(SIDEBAR_JOBS_KEY, state.open ? '1' : '0'); } catch (_) {}
3843
+ try { window.localStorage.setItem(SIDEBAR_JOBS_KEY, state.open ? '1' : '0'); } catch (err) { /* localStorage write failed */ }
3815
3844
  applySidebarJobsOpen(state);
3816
3845
  });
3817
3846
  root.appendChild(headEl);
@@ -3854,7 +3883,7 @@ window.__ModuleLoader__.load({
3854
3883
  function mountSidebarJobs(toggle, label, openTaskSignal) {
3855
3884
  if (typeof document === 'undefined') return () => {};
3856
3885
  const state = { toggle, openTaskSignal, root: undefined, listEl: undefined, headEl: undefined, open: false };
3857
- try { state.open = window.localStorage.getItem(SIDEBAR_JOBS_KEY) === '1'; } catch (_) {}
3886
+ try { state.open = window.localStorage.getItem(SIDEBAR_JOBS_KEY) === '1'; } catch (err) { /* localStorage read failed */ }
3858
3887
 
3859
3888
  const observer = new MutationObserver(() => placeSidebarJobs(state, label));
3860
3889
  observer.observe(document.body, { childList: true, subtree: true });
@@ -3862,7 +3891,7 @@ window.__ModuleLoader__.load({
3862
3891
  loadSidebarJobs(state);
3863
3892
  const fetchTimer = setInterval(() => {
3864
3893
  let isOpen = false;
3865
- try { isOpen = window.localStorage.getItem(SIDEBAR_JOBS_KEY) === '1'; } catch (_) {}
3894
+ try { isOpen = window.localStorage.getItem(SIDEBAR_JOBS_KEY) === '1'; } catch (err) { /* localStorage poll failed */ }
3866
3895
  if (isOpen) loadSidebarJobs(state);
3867
3896
  }, 30000);
3868
3897
 
@@ -4011,7 +4040,9 @@ window.__ModuleLoader__.load({
4011
4040
  if (ctx.locale && typeof ctx.locale.bind === 'function') {
4012
4041
  translate = ctx.locale.bind(NS);
4013
4042
  }
4014
- } catch (e) {}
4043
+ } catch (err) {
4044
+ /* locale bind unavailable, fallback to default translate */
4045
+ }
4015
4046
 
4016
4047
  const toggle = createToggle();
4017
4048
 
@@ -4021,6 +4052,14 @@ window.__ModuleLoader__.load({
4021
4052
  function SettingsCardWithBoundary(props) {
4022
4053
  return React.createElement(ErrorBoundary, null, CronSettingsCard(props));
4023
4054
  }
4055
+ // Row seat first (the seat the current core renders), legacy settings.plugin.item
4056
+ // after it as a fallback (#102: still no top-level section fallback).
4057
+ const rowOk = registerIntoMount(ctx, 'plugins.row.config', {
4058
+ name: 'plugins.row.config',
4059
+ key: ROW_CONFIG_KEY,
4060
+ locale: NS,
4061
+ inject: () => ({ ctx, toggle }),
4062
+ }, SettingsCardWithBoundary);
4024
4063
  const cardOk = registerIntoMount(ctx, 'settings.plugin.item', {
4025
4064
  name: 'settings.plugin.item',
4026
4065
  key: NS,