@linxin666/dsh-client-ui-task-board 0.4.2 → 0.4.3

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
@@ -6,7 +6,6 @@ window.__ModuleLoader__.load({
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  let react = require("react");
8
8
  let react_jsx_runtime = require("react/jsx-runtime");
9
- let react_dom_client = require("react-dom/client");
10
9
  /**
11
10
  * Repair a persisted tag list: keep the well-formed entries, trim, drop
12
11
  * blanks and repeats, cap the count, and collapse a blank prompt line to
@@ -880,6 +879,8 @@ window.__ModuleLoader__.load({
880
879
  function currentOf(sessions) {
881
880
  return sessions?.current();
882
881
  }
882
+ /** Stable id shared by the board's sidebar panel row and its main-slot page. */
883
+ const TASK_BOARD_PANEL_ID = "task-board";
883
884
  /** The selected task (resolved from the ledger), or undefined. */
884
885
  function selectedTaskOf(snapshot) {
885
886
  if (snapshot.selectedTaskId === void 0) return void 0;
@@ -977,20 +978,55 @@ window.__ModuleLoader__.load({
977
978
  async retryHostSync() {
978
979
  return await this.initializeRemote();
979
980
  }
981
+ /**
982
+ * Show the board. The layout owns which panel the center column renders, so
983
+ * the state flip and the panel selection travel together here; a composition
984
+ * with no layout face (tests, a shell-less host) still flips the state.
985
+ *
986
+ * The selection is requested AFTER the snapshot flips so a subscriber
987
+ * rendering against `boardOpen` never observes "open" while the shell still
988
+ * shows the conversation.
989
+ */
980
990
  openBoard() {
981
991
  if (this.boardOpen) return;
982
992
  this.boardOpen = true;
983
993
  this.notify();
994
+ this.selectPanel(TASK_BOARD_PANEL_ID);
984
995
  }
996
+ /**
997
+ * Return the center column to the conversation. The layout's own selection is
998
+ * the source of truth for what the column renders, so this asks for the
999
+ * conversation explicitly rather than only clearing local state.
1000
+ */
985
1001
  closeBoard() {
986
1002
  this.boardOpen = false;
987
1003
  this.notify();
1004
+ this.selectPanel(null);
988
1005
  }
989
1006
  toggleBoard() {
990
1007
  if (this.boardOpen) this.closeBoard();
991
1008
  else this.openBoard();
992
1009
  }
993
1010
  /**
1011
+ * Reflect a panel selection that came from OUTSIDE this controller (the user
1012
+ * clicked another sidebar row, or the layout dropped the panel id). Keeps
1013
+ * `boardOpen` aligned with what the column actually shows without asking the
1014
+ * layout to select anything back.
1015
+ * @param panelId - the layout's current panel id, or null for the conversation.
1016
+ */
1017
+ syncPanelSelection(panelId) {
1018
+ const open = panelId === TASK_BOARD_PANEL_ID;
1019
+ if (open === this.boardOpen) return;
1020
+ this.boardOpen = open;
1021
+ this.notify();
1022
+ }
1023
+ /** Ask the layout to select a panel; a shell that serves no layout face is a no-op. */
1024
+ selectPanel(panelId) {
1025
+ try {
1026
+ this.deps.panel?.select(panelId);
1027
+ } catch {}
1028
+ }
1029
+ /**
994
1030
  * Switch between the kanban columns and the archive view. Leaving the
995
1031
  * archive view with an archived task still selected closes the selection —
996
1032
  * the detail overlay must not linger over a task that is off-board.
@@ -1270,8 +1306,8 @@ window.__ModuleLoader__.load({
1270
1306
  * (background navigation, the Host runner creating and selecting a fresh
1271
1307
  * execution session, settlement, other plugins), so closing on `current`
1272
1308
  * changes would evict the board without the user asking. The board closes
1273
- * only on explicit user navigation: a sidebar session/workspace row click
1274
- * (board-mount onClickSidebarRow) or the board's own actions
1309
+ * only on explicit user navigation: selecting another panel (the layout owns
1310
+ * selection, and `syncPanelSelection` follows it) or the board's own actions
1275
1311
  * (openSession / close). Keeping the hook preserves the subscription
1276
1312
  * contract for future listeners.
1277
1313
  */
@@ -2387,7 +2423,7 @@ window.__ModuleLoader__.load({
2387
2423
  }
2388
2424
  //#endregion
2389
2425
  //#region \0dsh-css:packages/dsh-task-board/src/client/board.module.css.mjs
2390
- const css$1 = "[data-pane=conversation],[class*=centerCol]{position:relative}[data-dsh-taskboard-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0;container:_7D6uKa_task-board-view/inline-size}html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [data-dsh-taskboard-view]{display:block}html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-taskboard-view]),html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-taskboard-view]){display:none!important}._7D6uKa_entry{box-sizing:border-box;min-height:36px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;text-align:left;white-space:nowrap;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;margin:0 2px;padding:7px 8px;font-size:14px;line-height:22px;display:flex}._7D6uKa_entry:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_entry[data-active]{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);font-weight:600}._7D6uKa_entryIcon{flex:none;justify-content:center;align-items:center;width:16px;height:16px;display:inline-flex}._7D6uKa_entryIcon svg{width:16px;height:16px;display:block}._7D6uKa_entryLabel{text-overflow:ellipsis;overflow:hidden}[data-dsh-frame][data-sidebar-collapsed] ._7D6uKa_entry,[data-sidebar-collapsed] ._7D6uKa_entry{border-radius:12px;justify-content:center;width:36px;height:36px;margin:0 auto 12px;padding:0}[data-dsh-frame][data-sidebar-collapsed] ._7D6uKa_entryIcon,[data-sidebar-collapsed] ._7D6uKa_entryIcon,[data-dsh-frame][data-sidebar-collapsed] ._7D6uKa_entryIcon svg,[data-sidebar-collapsed] ._7D6uKa_entryIcon svg{width:18px;height:18px}[data-dsh-frame][data-sidebar-collapsed] ._7D6uKa_entryLabel,[data-sidebar-collapsed] ._7D6uKa_entryLabel{display:none}._7D6uKa_board{box-sizing:border-box;background:var(--dsw-alias-bg-base);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex-direction:column;gap:12px;padding:14px 16px 16px;display:flex}._7D6uKa_boardHeader{flex:none;align-items:center;gap:10px;display:flex}._7D6uKa_boardTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700}._7D6uKa_backButton{align-items:center;gap:4px;display:inline-flex}._7D6uKa_search{min-width:120px;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:0 260px;padding:6px 10px;font-size:13px}._7D6uKa_search::placeholder{color:var(--dsw-alias-label-tertiary)}._7D6uKa_columns{overscroll-behavior-inline:contain;scrollbar-color:var(--dsw-alias-border-l3) var(--dsw-alias-interactive-bg-hover);scrollbar-width:thin;flex:1;grid-auto-columns:minmax(220px,1fr);grid-auto-flow:column;gap:12px;min-height:0;padding-bottom:6px;display:grid;overflow:auto hidden}._7D6uKa_columns::-webkit-scrollbar{height:10px}._7D6uKa_columns::-webkit-scrollbar-track{background:var(--dsw-alias-interactive-bg-hover);border-radius:999px}._7D6uKa_columns::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);background-clip:content-box;border:2px solid #0000;border-radius:999px}._7D6uKa_columns::-webkit-scrollbar-thumb:hover{background:var(--dsw-alias-border-l4);background-clip:content-box}._7D6uKa_column{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;min-height:0;display:flex;overflow:hidden}._7D6uKa_columnHeader{flex:none;align-items:center;gap:6px;padding:10px 12px;display:flex}._7D6uKa_columnTitle{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:13px;font-weight:700;overflow:hidden}._7D6uKa_columnCount{min-width:0;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;flex:none;padding:1px 8px;font-size:12px}._7D6uKa_statusDot{border-radius:50%;flex:none;width:8px;height:8px}._7D6uKa_statusDot[data-status=backlog]{background:var(--dsw-alias-label-tertiary)}._7D6uKa_statusDot[data-status=todo]{background:var(--dsw-alias-state-business-primary)}._7D6uKa_statusDot[data-status=running]{background:var(--dsw-alias-state-warn-primary)}._7D6uKa_statusDot[data-status=done]{background:var(--dsw-alias-state-success-primary)}._7D6uKa_statusDot[data-status=failed]{background:var(--dsw-alias-state-error-primary)}._7D6uKa_cards{flex-direction:column;flex:1;gap:8px;min-height:0;padding:2px 8px 10px;display:flex;overflow-y:auto}._7D6uKa_columnEmpty{text-align:center;color:var(--dsw-alias-label-tertiary);padding:24px 8px;font-size:12px}._7D6uKa_card{text-align:left;background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;color:var(--dsw-alias-label-primary);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-family:inherit;transition:box-shadow .12s,border-color .12s,transform .12s;display:flex}._7D6uKa_card:hover{box-shadow:var(--dsw-shadow-lv2);border-color:var(--dsw-alias-border-l3);transform:translateY(-1px)}._7D6uKa_card[data-status=running]{border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_cardTitle{-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:13px;font-weight:600;line-height:1.35;display:-webkit-box;overflow:hidden}._7D6uKa_cardExcerpt{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12px;line-height:1.4;display:-webkit-box;overflow:hidden}._7D6uKa_cardMeta{color:var(--dsw-alias-label-tertiary);align-items:center;gap:8px;font-size:11px;display:flex}._7D6uKa_cardTime{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}._7D6uKa_cardSchedule{white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;flex:none;padding:2px 6px;font-size:12px;line-height:1}._7D6uKa_cardRun{flex:none}._7D6uKa_cardRun[data-result=failed]{color:var(--dsw-alias-state-error-primary)}._7D6uKa_cardRun[data-result=succeeded]{color:var(--dsw-alias-state-success-primary)}._7D6uKa_cardSession{color:var(--dsw-alias-state-business-primary);flex:none}._7D6uKa_cardRunningLabel{color:var(--dsw-alias-state-warn-primary);font-size:11px}._7D6uKa_cardSpinner{border:2px solid var(--dsw-alias-state-warn-primary);border-top-color:#0000;border-radius:50%;flex:none;width:10px;height:10px;animation:.8s linear infinite _7D6uKa_dshTbSpin}@keyframes _7D6uKa_dshTbSpin{to{transform:rotate(360deg)}}._7D6uKa_primaryButton{color:var(--dsw-alias-label-primary-foreground);background:var(--dsw-alias-button-info-fill);cursor:pointer;white-space:nowrap;border:none;border-radius:8px;padding:6px 14px;font-size:13px;font-weight:600}._7D6uKa_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-info-hover)}._7D6uKa_primaryButton:disabled{opacity:.5;cursor:default}._7D6uKa_ghostButton{color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;white-space:nowrap;background:0 0;border-radius:8px;padding:5px 12px;font-size:12px}._7D6uKa_ghostButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7D6uKa_ghostButton:disabled{opacity:.45;cursor:default}._7D6uKa_dangerButton{color:#fff;background:var(--dsw-alias-state-error-primary);cursor:pointer;white-space:nowrap;border:none;border-radius:8px;padding:6px 14px;font-size:13px;font-weight:600}._7D6uKa_dangerButton:hover:not(:disabled){filter:brightness(1.08)}._7D6uKa_dangerButton:active:not(:disabled){filter:brightness(.94)}._7D6uKa_dangerButton:disabled{opacity:.5;cursor:default}._7D6uKa_iconButton{width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0;font-size:13px;display:inline-flex}._7D6uKa_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_linkButton{color:var(--dsw-alias-state-business-primary);cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:0;font-size:12px}._7D6uKa_linkButton:hover{text-decoration:underline}._7D6uKa_modalBackdrop{z-index:1300;background:var(--dsw-alias-bg-mask-1);justify-content:center;align-items:center;display:flex;position:fixed;inset:0}._7D6uKa_modal{background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);width:min(520px,100vw - 48px);max-height:calc(100vh - 96px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:14px;flex-direction:column;gap:12px;padding:18px;display:flex;overflow-y:auto}._7D6uKa_modalTitle{margin:0;font-size:15px;font-weight:700}._7D6uKa_confirmMessage{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:1.5}._7D6uKa_modalFooter{justify-content:flex-end;gap:10px;margin-top:4px;display:flex}._7D6uKa_field{flex-direction:column;gap:5px;display:flex}._7D6uKa_fieldLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}._7D6uKa_input{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);resize:vertical;border-radius:8px;outline:none;padding:7px 10px;font-family:inherit;font-size:13px}._7D6uKa_input:focus{border-color:var(--dsw-alias-state-business-primary)}._7D6uKa_select{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;max-width:100%;padding:7px 10px;font-family:inherit;font-size:13px}._7D6uKa_input::placeholder{color:var(--dsw-alias-label-tertiary)}._7D6uKa_formError{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px}._7D6uKa_detail{background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);width:min(640px,100vw - 48px);max-height:calc(100vh - 80px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:14px;flex-direction:column;display:flex;overflow:hidden}._7D6uKa_detailHeader{border-bottom:1px solid var(--dsw-alias-separator-primary);flex:none;align-items:center;gap:10px;padding:14px 18px;display:flex}._7D6uKa_detailTitle{overflow-wrap:anywhere;flex:1;margin:0;font-size:15px;font-weight:700}._7D6uKa_statusBadge{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:2px 10px;font-size:12px}._7D6uKa_statusBadge[data-status=running]{color:var(--dsw-alias-state-warn-primary);border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_statusBadge[data-status=done]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}._7D6uKa_statusBadge[data-status=failed]{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_detailBody{flex-direction:column;flex:1;gap:16px;padding:14px 18px;display:flex;overflow-y:auto}._7D6uKa_detailSection{flex-direction:column;gap:6px;display:flex}._7D6uKa_detailSection h4{color:var(--dsw-alias-label-tertiary);text-transform:none;margin:0;font-size:12px;font-weight:700}._7D6uKa_detailText{color:var(--dsw-alias-label-primary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:1.55}._7D6uKa_scheduleToggle{color:var(--dsw-alias-label-primary);cursor:pointer;user-select:none;align-items:center;gap:8px;font-size:13px;display:flex}._7D6uKa_scheduleToggle input{accent-color:var(--dsw-alias-state-business-primary)}._7D6uKa_scheduleRow{align-items:center;gap:8px;display:flex}._7D6uKa_scheduleInput{min-width:0;font-family:var(--dsw-font-markdown-code-block-small);flex:1;font-size:12.5px}._7D6uKa_scheduleInputInvalid,._7D6uKa_scheduleInputInvalid:focus{border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_schedulePreset{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:none;padding:7px 8px;font-size:12.5px}._7D6uKa_scheduleMeta{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;margin:0;font-size:12px}._7D6uKa_promptBlock{font-size:12.5px;line-height:1.5;font-family:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-markdown-code-block);border:1px solid var(--dsw-alias-border-l1);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:8px;max-height:240px;margin:0;padding:10px 12px;overflow-y:auto}._7D6uKa_executionList{flex-direction:column;gap:8px;margin:0;padding:0;list-style:none;display:flex}._7D6uKa_executionRow{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-wrap:wrap;align-items:center;gap:10px;padding:8px 10px;display:flex}._7D6uKa_executionBadge{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-state-warn-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:600}._7D6uKa_executionBadge[data-result=succeeded]{color:var(--dsw-alias-state-success-primary);background:0 0}._7D6uKa_executionBadge[data-result=failed]{color:var(--dsw-alias-state-error-primary);background:0 0}._7D6uKa_executionBadge[data-result=cancelled]{color:var(--dsw-alias-label-tertiary);background:0 0}._7D6uKa_executionTimes{color:var(--dsw-alias-label-secondary);font-size:12px}._7D6uKa_executionError{width:100%;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;font-size:12px}._7D6uKa_moveRow{flex-wrap:wrap;gap:8px;display:flex}._7D6uKa_detailFooter{border-top:1px solid var(--dsw-alias-separator-primary);flex:none;align-items:center;gap:10px;padding:12px 18px;display:flex}._7D6uKa_detailMeta{color:var(--dsw-alias-label-tertiary);margin-left:auto;font-size:11px}@container _7D6uKa_task-board-view (width<=768px){._7D6uKa_board{gap:10px;padding:10px}._7D6uKa_boardHeader{flex-wrap:wrap;align-items:center;gap:8px}._7D6uKa_backButton{flex:none;order:1}._7D6uKa_boardTitle{flex:auto;order:2}._7D6uKa_boardHeader>._7D6uKa_detailMeta{flex:1 0 100%;order:3;margin-left:0}._7D6uKa_search{flex:1 0 100%;order:4;min-width:0}._7D6uKa_boardHeader>button:not(._7D6uKa_backButton){flex:1 1 0;order:5;min-width:0}._7D6uKa_columns{scroll-snap-type:inline mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch;grid-auto-columns:86cqw;gap:10px;padding-inline:2px 14cqw;scroll-padding-inline:2px}._7D6uKa_columns::-webkit-scrollbar{display:none}._7D6uKa_column{scroll-snap-align:start;scroll-snap-stop:always}}@container _7D6uKa_task-board-view (width<=720px){._7D6uKa_boardHeader>._7D6uKa_detailMeta{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}}@container _7D6uKa_task-board-view (width<=600px){._7D6uKa_board{padding-inline:8px}}@media (width<=768px){[data-dsh-taskboard-view]{height:100dvh}._7D6uKa_entry,._7D6uKa_card,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle{min-height:44px}._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset{box-sizing:border-box;font-size:16px}._7D6uKa_modalBackdrop{justify-content:stretch;align-items:stretch;width:100vw;height:100dvh}._7D6uKa_modal,._7D6uKa_detail{box-sizing:border-box;border:0;border-radius:0;width:100vw;height:100dvh;max-height:none}._7D6uKa_modal{padding-top:max(16px, env(safe-area-inset-top));padding-right:max(16px, env(safe-area-inset-right));padding-bottom:max(16px, env(safe-area-inset-bottom));padding-left:max(16px, env(safe-area-inset-left))}._7D6uKa_modalFooter{z-index:1;background:var(--dsw-alias-bg-base);flex-wrap:wrap;padding-top:8px;position:sticky;bottom:0}._7D6uKa_modalFooter>button{flex:120px}._7D6uKa_detailHeader{padding-top:max(12px, env(safe-area-inset-top));padding-right:max(14px, env(safe-area-inset-right));padding-left:max(14px, env(safe-area-inset-left));flex-wrap:wrap}._7D6uKa_detailTitle{min-width:0}._7D6uKa_detailBody{overscroll-behavior-y:contain;padding-right:max(14px, env(safe-area-inset-right));padding-left:max(14px, env(safe-area-inset-left))}._7D6uKa_detailFooter{padding-right:max(14px, env(safe-area-inset-right));padding-bottom:max(12px, env(safe-area-inset-bottom));padding-left:max(14px, env(safe-area-inset-left));flex-wrap:wrap}._7D6uKa_detailFooter>button{flex:96px}._7D6uKa_detailFooter>._7D6uKa_detailMeta{text-align:end;flex:1 0 100%;margin-left:0}._7D6uKa_scheduleRow{flex-direction:column;align-items:stretch}._7D6uKa_schedulePreset{width:100%}}._7D6uKa_entry:focus-visible,._7D6uKa_card:focus-visible,._7D6uKa_primaryButton:focus-visible,._7D6uKa_ghostButton:focus-visible,._7D6uKa_dangerButton:focus-visible,._7D6uKa_iconButton:focus-visible,._7D6uKa_linkButton:focus-visible,._7D6uKa_search:focus-visible,._7D6uKa_input:focus-visible,._7D6uKa_select:focus-visible,._7D6uKa_schedulePreset:focus-visible,._7D6uKa_scheduleToggle input:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}._7D6uKa_entry,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle input{transition:background-color .12s,color .12s,border-color .12s,outline-color .12s,box-shadow .12s,transform .12s}._7D6uKa_card:active{box-shadow:var(--dsw-shadow-lv1);transform:translateY(0)}._7D6uKa_entry:active,._7D6uKa_primaryButton:active:not(:disabled),._7D6uKa_ghostButton:active:not(:disabled),._7D6uKa_dangerButton:active:not(:disabled),._7D6uKa_iconButton:active:not(:disabled),._7D6uKa_linkButton:active:not(:disabled){transform:translateY(1px)}._7D6uKa_entry[data-active]:hover{background:var(--dsw-specific-sidebar-nav-item-active)}._7D6uKa_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_linkButton:hover:not(:disabled){text-decoration:underline}._7D6uKa_iconButton:disabled,._7D6uKa_linkButton:disabled{opacity:.45;cursor:default}._7D6uKa_search:focus,._7D6uKa_select:focus,._7D6uKa_schedulePreset:focus{border-color:var(--dsw-alias-state-business-primary)}._7D6uKa_scheduleToggle input{margin:0}@media (prefers-reduced-motion:reduce){._7D6uKa_entry,._7D6uKa_card,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle input{transition:none}._7D6uKa_cardSpinner{animation:none}}._7D6uKa_cardTags{flex-wrap:wrap;gap:4px;display:flex}._7D6uKa_cardTag{border:1px solid var(--dsh-task-tag-border);background:var(--dsh-task-tag-fill);max-width:100%;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;border-radius:999px;padding:0 7px;font-size:10px;line-height:16px;overflow:hidden}._7D6uKa_tagFilter{flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 10px;display:flex}._7D6uKa_tagFilterLabel{color:var(--dsw-alias-label-tertiary);font-size:11px}._7D6uKa_tagChip{border:1px solid var(--dsh-task-tag-border);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:999px;padding:1px 9px;font-family:inherit;font-size:11px;line-height:18px}._7D6uKa_tagChip[data-active=true]{background:var(--dsh-task-tag-fill);color:var(--dsw-alias-label-primary)}._7D6uKa_cardTag[data-tag-tone=\"0\"],._7D6uKa_tagChip[data-tag-tone=\"0\"]{--dsh-task-tag-fill:#4e93e82e;--dsh-task-tag-border:#4e93e866}._7D6uKa_cardTag[data-tag-tone=\"1\"],._7D6uKa_tagChip[data-tag-tone=\"1\"]{--dsh-task-tag-fill:#2ea36a2e;--dsh-task-tag-border:#2ea36a66}._7D6uKa_cardTag[data-tag-tone=\"2\"],._7D6uKa_tagChip[data-tag-tone=\"2\"]{--dsh-task-tag-fill:#d08a2a2e;--dsh-task-tag-border:#d08a2a66}._7D6uKa_cardTag[data-tag-tone=\"3\"],._7D6uKa_tagChip[data-tag-tone=\"3\"]{--dsh-task-tag-fill:#b456c82e;--dsh-task-tag-border:#b456c866}._7D6uKa_cardTag[data-tag-tone=\"4\"],._7D6uKa_tagChip[data-tag-tone=\"4\"]{--dsh-task-tag-fill:#cf5f7a2e;--dsh-task-tag-border:#cf5f7a66}._7D6uKa_cardTag[data-tag-tone=\"5\"],._7D6uKa_tagChip[data-tag-tone=\"5\"]{--dsh-task-tag-fill:#4a9fb52e;--dsh-task-tag-border:#4a9fb566}._7D6uKa_fieldHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.4}._7D6uKa_tagRow{align-items:center;gap:6px;display:flex}._7D6uKa_tagRow ._7D6uKa_input{flex:1 1 0;min-width:0}._7D6uKa_tagRow ._7D6uKa_ghostButton{flex:none}._7D6uKa_tagAddButton{align-self:flex-start}._7D6uKa_projectFilter{flex:none;align-items:center;gap:6px;display:flex}._7D6uKa_projectFilterLabel{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}._7D6uKa_projectDialog{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;flex-direction:column;flex:none;gap:8px;margin-bottom:8px;padding:10px 12px;display:flex}._7D6uKa_projectDialogActions{justify-content:flex-end;gap:8px;display:flex}._7D6uKa_aiParse{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;display:flex}._7D6uKa_aiParseRow{align-items:center;gap:8px;display:flex}._7D6uKa_aiParseRow ._7D6uKa_select{flex:1 1 0;min-width:0}._7D6uKa_aiParseRow ._7D6uKa_ghostButton,._7D6uKa_aiParseRow ._7D6uKa_primaryButton{flex:none}._7D6uKa_cardSubtask{border:1px solid var(--dsw-alias-border-l2);max-width:100%;color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;background:0 0;border-radius:999px;padding:0 7px;font-size:10px;line-height:16px;overflow:hidden}._7D6uKa_cardSubtask[data-tone=failed]{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_cardSubtask[data-tone=running]{color:var(--dsw-alias-state-warn-primary);border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_cardSubtask[data-tone=done]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}._7D6uKa_subtaskList{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}._7D6uKa_subtaskRow{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-wrap:wrap;align-items:center;gap:10px;padding:6px 10px;display:flex}._7D6uKa_subtaskRow ._7D6uKa_linkButton:first-child{text-align:left;overflow-wrap:anywhere;flex:auto;min-width:0}._7D6uKa_subtaskAddRow{flex-wrap:wrap;gap:8px;display:flex}._7D6uKa_pickList{flex-direction:column;gap:6px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}._7D6uKa_pickRow{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;align-items:center;gap:10px;padding:6px 10px;display:flex}._7D6uKa_pickTitle{min-width:0;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;flex:auto;font-size:13px}";
2426
+ const css$1 = "[data-dsh-taskboard-view]{box-sizing:border-box;background:var(--dsw-alias-bg-base);flex-direction:column;width:100%;min-width:0;height:100%;min-height:0;display:flex;container:_7D6uKa_task-board-view/inline-size}._7D6uKa_board{box-sizing:border-box;background:var(--dsw-alias-bg-base);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex-direction:column;gap:12px;padding:14px 16px 16px;display:flex}._7D6uKa_boardHeader{flex:none;align-items:center;gap:10px;display:flex}._7D6uKa_boardTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700}._7D6uKa_backButton{align-items:center;gap:4px;display:inline-flex}._7D6uKa_search{min-width:120px;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:0 260px;padding:6px 10px;font-size:13px}._7D6uKa_search::placeholder{color:var(--dsw-alias-label-tertiary)}._7D6uKa_columns{overscroll-behavior-inline:contain;scrollbar-color:var(--dsw-alias-border-l3) var(--dsw-alias-interactive-bg-hover);scrollbar-width:thin;flex:1;grid-auto-columns:minmax(220px,1fr);grid-auto-flow:column;gap:12px;min-height:0;padding-bottom:6px;display:grid;overflow:auto hidden}._7D6uKa_columns::-webkit-scrollbar{height:10px}._7D6uKa_columns::-webkit-scrollbar-track{background:var(--dsw-alias-interactive-bg-hover);border-radius:999px}._7D6uKa_columns::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);background-clip:content-box;border:2px solid #0000;border-radius:999px}._7D6uKa_columns::-webkit-scrollbar-thumb:hover{background:var(--dsw-alias-border-l4);background-clip:content-box}._7D6uKa_column{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;min-height:0;display:flex;overflow:hidden}._7D6uKa_columnHeader{flex:none;align-items:center;gap:6px;padding:10px 12px;display:flex}._7D6uKa_columnTitle{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:13px;font-weight:700;overflow:hidden}._7D6uKa_columnCount{min-width:0;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;flex:none;padding:1px 8px;font-size:12px}._7D6uKa_statusDot{border-radius:50%;flex:none;width:8px;height:8px}._7D6uKa_statusDot[data-status=backlog]{background:var(--dsw-alias-label-tertiary)}._7D6uKa_statusDot[data-status=todo]{background:var(--dsw-alias-state-business-primary)}._7D6uKa_statusDot[data-status=running]{background:var(--dsw-alias-state-warn-primary)}._7D6uKa_statusDot[data-status=done]{background:var(--dsw-alias-state-success-primary)}._7D6uKa_statusDot[data-status=failed]{background:var(--dsw-alias-state-error-primary)}._7D6uKa_cards{flex-direction:column;flex:1;gap:8px;min-height:0;padding:2px 8px 10px;display:flex;overflow-y:auto}._7D6uKa_columnEmpty{text-align:center;color:var(--dsw-alias-label-tertiary);padding:24px 8px;font-size:12px}._7D6uKa_card{text-align:left;background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;color:var(--dsw-alias-label-primary);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-family:inherit;transition:box-shadow .12s,border-color .12s,transform .12s;display:flex}._7D6uKa_card:hover{box-shadow:var(--dsw-shadow-lv2);border-color:var(--dsw-alias-border-l3);transform:translateY(-1px)}._7D6uKa_card[data-status=running]{border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_cardTitle{-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:13px;font-weight:600;line-height:1.35;display:-webkit-box;overflow:hidden}._7D6uKa_cardExcerpt{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12px;line-height:1.4;display:-webkit-box;overflow:hidden}._7D6uKa_cardMeta{color:var(--dsw-alias-label-tertiary);align-items:center;gap:8px;font-size:11px;display:flex}._7D6uKa_cardTime{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}._7D6uKa_cardSchedule{white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;flex:none;padding:2px 6px;font-size:12px;line-height:1}._7D6uKa_cardRun{flex:none}._7D6uKa_cardRun[data-result=failed]{color:var(--dsw-alias-state-error-primary)}._7D6uKa_cardRun[data-result=succeeded]{color:var(--dsw-alias-state-success-primary)}._7D6uKa_cardSession{color:var(--dsw-alias-state-business-primary);flex:none}._7D6uKa_cardRunningLabel{color:var(--dsw-alias-state-warn-primary);font-size:11px}._7D6uKa_cardSpinner{border:2px solid var(--dsw-alias-state-warn-primary);border-top-color:#0000;border-radius:50%;flex:none;width:10px;height:10px;animation:.8s linear infinite _7D6uKa_dshTbSpin}@keyframes _7D6uKa_dshTbSpin{to{transform:rotate(360deg)}}._7D6uKa_primaryButton{color:var(--dsw-alias-label-primary-foreground);background:var(--dsw-alias-button-info-fill);cursor:pointer;white-space:nowrap;border:none;border-radius:8px;padding:6px 14px;font-size:13px;font-weight:600}._7D6uKa_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-info-hover)}._7D6uKa_primaryButton:disabled{opacity:.5;cursor:default}._7D6uKa_ghostButton{color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;white-space:nowrap;background:0 0;border-radius:8px;padding:5px 12px;font-size:12px}._7D6uKa_ghostButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7D6uKa_ghostButton:disabled{opacity:.45;cursor:default}._7D6uKa_dangerButton{color:#fff;background:var(--dsw-alias-state-error-primary);cursor:pointer;white-space:nowrap;border:none;border-radius:8px;padding:6px 14px;font-size:13px;font-weight:600}._7D6uKa_dangerButton:hover:not(:disabled){filter:brightness(1.08)}._7D6uKa_dangerButton:active:not(:disabled){filter:brightness(.94)}._7D6uKa_dangerButton:disabled{opacity:.5;cursor:default}._7D6uKa_iconButton{width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0;font-size:13px;display:inline-flex}._7D6uKa_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_linkButton{color:var(--dsw-alias-state-business-primary);cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:0;font-size:12px}._7D6uKa_linkButton:hover{text-decoration:underline}._7D6uKa_modalBackdrop{z-index:1300;background:var(--dsw-alias-bg-mask-1);justify-content:center;align-items:center;display:flex;position:fixed;inset:0}._7D6uKa_modal{background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);width:min(520px,100vw - 48px);max-height:calc(100vh - 96px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:14px;flex-direction:column;gap:12px;padding:18px;display:flex;overflow-y:auto}._7D6uKa_modalTitle{margin:0;font-size:15px;font-weight:700}._7D6uKa_confirmMessage{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:1.5}._7D6uKa_modalFooter{justify-content:flex-end;gap:10px;margin-top:4px;display:flex}._7D6uKa_field{flex-direction:column;gap:5px;display:flex}._7D6uKa_fieldLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}._7D6uKa_input{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);resize:vertical;border-radius:8px;outline:none;padding:7px 10px;font-family:inherit;font-size:13px}._7D6uKa_input:focus{border-color:var(--dsw-alias-state-business-primary)}._7D6uKa_select{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;max-width:100%;padding:7px 10px;font-family:inherit;font-size:13px}._7D6uKa_input::placeholder{color:var(--dsw-alias-label-tertiary)}._7D6uKa_formError{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px}._7D6uKa_detail{background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);width:min(640px,100vw - 48px);max-height:calc(100vh - 80px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:14px;flex-direction:column;display:flex;overflow:hidden}._7D6uKa_detailHeader{border-bottom:1px solid var(--dsw-alias-separator-primary);flex:none;align-items:center;gap:10px;padding:14px 18px;display:flex}._7D6uKa_detailTitle{overflow-wrap:anywhere;flex:1;margin:0;font-size:15px;font-weight:700}._7D6uKa_statusBadge{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:2px 10px;font-size:12px}._7D6uKa_statusBadge[data-status=running]{color:var(--dsw-alias-state-warn-primary);border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_statusBadge[data-status=done]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}._7D6uKa_statusBadge[data-status=failed]{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_detailBody{flex-direction:column;flex:1;gap:16px;padding:14px 18px;display:flex;overflow-y:auto}._7D6uKa_detailSection{flex-direction:column;gap:6px;display:flex}._7D6uKa_detailSection h4{color:var(--dsw-alias-label-tertiary);text-transform:none;margin:0;font-size:12px;font-weight:700}._7D6uKa_detailText{color:var(--dsw-alias-label-primary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:1.55}._7D6uKa_scheduleToggle{color:var(--dsw-alias-label-primary);cursor:pointer;user-select:none;align-items:center;gap:8px;font-size:13px;display:flex}._7D6uKa_scheduleToggle input{accent-color:var(--dsw-alias-state-business-primary)}._7D6uKa_scheduleRow{align-items:center;gap:8px;display:flex}._7D6uKa_scheduleInput{min-width:0;font-family:var(--dsw-font-markdown-code-block-small);flex:1;font-size:12.5px}._7D6uKa_scheduleInputInvalid,._7D6uKa_scheduleInputInvalid:focus{border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_schedulePreset{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:none;padding:7px 8px;font-size:12.5px}._7D6uKa_scheduleMeta{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;margin:0;font-size:12px}._7D6uKa_promptBlock{font-size:12.5px;line-height:1.5;font-family:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-markdown-code-block);border:1px solid var(--dsw-alias-border-l1);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:8px;max-height:240px;margin:0;padding:10px 12px;overflow-y:auto}._7D6uKa_executionList{flex-direction:column;gap:8px;margin:0;padding:0;list-style:none;display:flex}._7D6uKa_executionRow{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-wrap:wrap;align-items:center;gap:10px;padding:8px 10px;display:flex}._7D6uKa_executionBadge{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-state-warn-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:600}._7D6uKa_executionBadge[data-result=succeeded]{color:var(--dsw-alias-state-success-primary);background:0 0}._7D6uKa_executionBadge[data-result=failed]{color:var(--dsw-alias-state-error-primary);background:0 0}._7D6uKa_executionBadge[data-result=cancelled]{color:var(--dsw-alias-label-tertiary);background:0 0}._7D6uKa_executionTimes{color:var(--dsw-alias-label-secondary);font-size:12px}._7D6uKa_executionError{width:100%;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;font-size:12px}._7D6uKa_moveRow{flex-wrap:wrap;gap:8px;display:flex}._7D6uKa_detailFooter{border-top:1px solid var(--dsw-alias-separator-primary);flex:none;align-items:center;gap:10px;padding:12px 18px;display:flex}._7D6uKa_detailMeta{color:var(--dsw-alias-label-tertiary);margin-left:auto;font-size:11px}@container _7D6uKa_task-board-view (width<=768px){._7D6uKa_board{gap:10px;padding:10px}._7D6uKa_boardHeader{flex-wrap:wrap;align-items:center;gap:8px}._7D6uKa_backButton{flex:none;order:1}._7D6uKa_boardTitle{flex:auto;order:2}._7D6uKa_boardHeader>._7D6uKa_detailMeta{flex:1 0 100%;order:3;margin-left:0}._7D6uKa_search{flex:1 0 100%;order:4;min-width:0}._7D6uKa_boardHeader>button:not(._7D6uKa_backButton){flex:1 1 0;order:5;min-width:0}._7D6uKa_columns{scroll-snap-type:inline mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch;grid-auto-columns:86cqw;gap:10px;padding-inline:2px 14cqw;scroll-padding-inline:2px}._7D6uKa_columns::-webkit-scrollbar{display:none}._7D6uKa_column{scroll-snap-align:start;scroll-snap-stop:always}}@container _7D6uKa_task-board-view (width<=720px){._7D6uKa_boardHeader>._7D6uKa_detailMeta{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}}@container _7D6uKa_task-board-view (width<=600px){._7D6uKa_board{padding-inline:8px}}@media (width<=768px){[data-dsh-taskboard-view]{height:100dvh}._7D6uKa_card,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle{min-height:44px}._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset{box-sizing:border-box;font-size:16px}._7D6uKa_modalBackdrop{justify-content:stretch;align-items:stretch;width:100vw;height:100dvh}._7D6uKa_modal,._7D6uKa_detail{box-sizing:border-box;border:0;border-radius:0;width:100vw;height:100dvh;max-height:none}._7D6uKa_modal{padding-top:max(16px, env(safe-area-inset-top));padding-right:max(16px, env(safe-area-inset-right));padding-bottom:max(16px, env(safe-area-inset-bottom));padding-left:max(16px, env(safe-area-inset-left))}._7D6uKa_modalFooter{z-index:1;background:var(--dsw-alias-bg-base);flex-wrap:wrap;padding-top:8px;position:sticky;bottom:0}._7D6uKa_modalFooter>button{flex:120px}._7D6uKa_detailHeader{padding-top:max(12px, env(safe-area-inset-top));padding-right:max(14px, env(safe-area-inset-right));padding-left:max(14px, env(safe-area-inset-left));flex-wrap:wrap}._7D6uKa_detailTitle{min-width:0}._7D6uKa_detailBody{overscroll-behavior-y:contain;padding-right:max(14px, env(safe-area-inset-right));padding-left:max(14px, env(safe-area-inset-left))}._7D6uKa_detailFooter{padding-right:max(14px, env(safe-area-inset-right));padding-bottom:max(12px, env(safe-area-inset-bottom));padding-left:max(14px, env(safe-area-inset-left));flex-wrap:wrap}._7D6uKa_detailFooter>button{flex:96px}._7D6uKa_detailFooter>._7D6uKa_detailMeta{text-align:end;flex:1 0 100%;margin-left:0}._7D6uKa_scheduleRow{flex-direction:column;align-items:stretch}._7D6uKa_schedulePreset{width:100%}}._7D6uKa_card:focus-visible,._7D6uKa_primaryButton:focus-visible,._7D6uKa_ghostButton:focus-visible,._7D6uKa_dangerButton:focus-visible,._7D6uKa_iconButton:focus-visible,._7D6uKa_linkButton:focus-visible,._7D6uKa_search:focus-visible,._7D6uKa_input:focus-visible,._7D6uKa_select:focus-visible,._7D6uKa_schedulePreset:focus-visible,._7D6uKa_scheduleToggle input:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle input{transition:background-color .12s,color .12s,border-color .12s,outline-color .12s,box-shadow .12s,transform .12s}._7D6uKa_card:active{box-shadow:var(--dsw-shadow-lv1);transform:translateY(0)}._7D6uKa_primaryButton:active:not(:disabled),._7D6uKa_ghostButton:active:not(:disabled),._7D6uKa_dangerButton:active:not(:disabled),._7D6uKa_iconButton:active:not(:disabled),._7D6uKa_linkButton:active:not(:disabled){transform:translateY(1px)}._7D6uKa_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_linkButton:hover:not(:disabled){text-decoration:underline}._7D6uKa_iconButton:disabled,._7D6uKa_linkButton:disabled{opacity:.45;cursor:default}._7D6uKa_search:focus,._7D6uKa_select:focus,._7D6uKa_schedulePreset:focus{border-color:var(--dsw-alias-state-business-primary)}._7D6uKa_scheduleToggle input{margin:0}@media (prefers-reduced-motion:reduce){._7D6uKa_card,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle input{transition:none}._7D6uKa_cardSpinner{animation:none}}._7D6uKa_cardTags{flex-wrap:wrap;gap:4px;display:flex}._7D6uKa_cardTag{border:1px solid var(--dsh-task-tag-border);background:var(--dsh-task-tag-fill);max-width:100%;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;border-radius:999px;padding:0 7px;font-size:10px;line-height:16px;overflow:hidden}._7D6uKa_tagFilter{flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 10px;display:flex}._7D6uKa_tagFilterLabel{color:var(--dsw-alias-label-tertiary);font-size:11px}._7D6uKa_tagChip{border:1px solid var(--dsh-task-tag-border);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:999px;padding:1px 9px;font-family:inherit;font-size:11px;line-height:18px}._7D6uKa_tagChip[data-active=true]{background:var(--dsh-task-tag-fill);color:var(--dsw-alias-label-primary)}._7D6uKa_cardTag[data-tag-tone=\"0\"],._7D6uKa_tagChip[data-tag-tone=\"0\"]{--dsh-task-tag-fill:#4e93e82e;--dsh-task-tag-border:#4e93e866}._7D6uKa_cardTag[data-tag-tone=\"1\"],._7D6uKa_tagChip[data-tag-tone=\"1\"]{--dsh-task-tag-fill:#2ea36a2e;--dsh-task-tag-border:#2ea36a66}._7D6uKa_cardTag[data-tag-tone=\"2\"],._7D6uKa_tagChip[data-tag-tone=\"2\"]{--dsh-task-tag-fill:#d08a2a2e;--dsh-task-tag-border:#d08a2a66}._7D6uKa_cardTag[data-tag-tone=\"3\"],._7D6uKa_tagChip[data-tag-tone=\"3\"]{--dsh-task-tag-fill:#b456c82e;--dsh-task-tag-border:#b456c866}._7D6uKa_cardTag[data-tag-tone=\"4\"],._7D6uKa_tagChip[data-tag-tone=\"4\"]{--dsh-task-tag-fill:#cf5f7a2e;--dsh-task-tag-border:#cf5f7a66}._7D6uKa_cardTag[data-tag-tone=\"5\"],._7D6uKa_tagChip[data-tag-tone=\"5\"]{--dsh-task-tag-fill:#4a9fb52e;--dsh-task-tag-border:#4a9fb566}._7D6uKa_fieldHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.4}._7D6uKa_tagRow{align-items:center;gap:6px;display:flex}._7D6uKa_tagRow ._7D6uKa_input{flex:1 1 0;min-width:0}._7D6uKa_tagRow ._7D6uKa_ghostButton{flex:none}._7D6uKa_tagAddButton{align-self:flex-start}._7D6uKa_projectFilter{flex:none;align-items:center;gap:6px;display:flex}._7D6uKa_projectFilterLabel{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}._7D6uKa_projectDialog{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;flex-direction:column;flex:none;gap:8px;margin-bottom:8px;padding:10px 12px;display:flex}._7D6uKa_projectDialogActions{justify-content:flex-end;gap:8px;display:flex}._7D6uKa_aiParse{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;display:flex}._7D6uKa_aiParseRow{align-items:center;gap:8px;display:flex}._7D6uKa_aiParseRow ._7D6uKa_select{flex:1 1 0;min-width:0}._7D6uKa_aiParseRow ._7D6uKa_ghostButton,._7D6uKa_aiParseRow ._7D6uKa_primaryButton{flex:none}._7D6uKa_cardSubtask{border:1px solid var(--dsw-alias-border-l2);max-width:100%;color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;background:0 0;border-radius:999px;padding:0 7px;font-size:10px;line-height:16px;overflow:hidden}._7D6uKa_cardSubtask[data-tone=failed]{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_cardSubtask[data-tone=running]{color:var(--dsw-alias-state-warn-primary);border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_cardSubtask[data-tone=done]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}._7D6uKa_subtaskList{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}._7D6uKa_subtaskRow{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-wrap:wrap;align-items:center;gap:10px;padding:6px 10px;display:flex}._7D6uKa_subtaskRow ._7D6uKa_linkButton:first-child{text-align:left;overflow-wrap:anywhere;flex:auto;min-width:0}._7D6uKa_subtaskAddRow{flex-wrap:wrap;gap:8px;display:flex}._7D6uKa_pickList{flex-direction:column;gap:6px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}._7D6uKa_pickRow{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;align-items:center;gap:10px;padding:6px 10px;display:flex}._7D6uKa_pickTitle{min-width:0;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;flex:auto;font-size:13px}";
2391
2427
  const tagId$1 = "@linxin666/dsh-client-ui-task-board/packages/dsh-task-board/src/client/board.module.css";
2392
2428
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
2393
2429
  const tag = document.createElement("style");
@@ -2434,9 +2470,6 @@ window.__ModuleLoader__.load({
2434
2470
  "detailText": "_7D6uKa_detailText",
2435
2471
  "detailTitle": "_7D6uKa_detailTitle",
2436
2472
  "dshTbSpin": "_7D6uKa_dshTbSpin",
2437
- "entry": "_7D6uKa_entry",
2438
- "entryIcon": "_7D6uKa_entryIcon",
2439
- "entryLabel": "_7D6uKa_entryLabel",
2440
2473
  "executionBadge": "_7D6uKa_executionBadge",
2441
2474
  "executionError": "_7D6uKa_executionError",
2442
2475
  "executionList": "_7D6uKa_executionList",
@@ -4842,390 +4875,89 @@ window.__ModuleLoader__.load({
4842
4875
  });
4843
4876
  }
4844
4877
  //#endregion
4845
- //#region src/client/body-mutations.ts
4846
- /** Cross-bundle registry key; `Symbol.for` so every module copy agrees. */
4847
- const HUB_KEY = Symbol.for("dsh-web.body-mutation-hub");
4848
- const INVALIDATION_ONLY = Symbol.for("dsh-web.body-mutation-invalidation");
4849
- function needsRecords(subscribers) {
4850
- for (const listener of subscribers) if (!listener[INVALIDATION_ONLY]) return true;
4851
- return false;
4852
- }
4853
- /**
4854
- * Subscribe to a coalesced DOM re-check without retaining mutation records.
4855
- * The marked wrapper also works with an older hub, which delivers records
4856
- * that it simply ignores until a page reload picks up the updated hub.
4857
- */
4858
- function subscribeBodyInvalidations(subscriber) {
4859
- const listener = () => {
4860
- subscriber();
4861
- };
4862
- listener[INVALIDATION_ONLY] = true;
4863
- return subscribeBodyMutations(listener);
4864
- }
4865
- /**
4866
- * Subscribe to body-level childList mutations.
4867
- * @param subscriber - called at most once per animation frame with the records
4868
- * collected since the previous flush; must be safe to run repeatedly.
4869
- * @returns the disposer removing this subscriber (and the observer when it was
4870
- * the last one).
4871
- */
4872
- function subscribeBodyMutations(subscriber) {
4873
- if (typeof globalThis === "undefined" || typeof document === "undefined") return () => {};
4874
- if (typeof MutationObserver !== "function") return () => {};
4875
- const registry = globalThis;
4876
- let hub = registry[HUB_KEY];
4877
- if (hub === void 0) {
4878
- const subscribers = /* @__PURE__ */ new Set();
4879
- const created = {
4880
- observer: void 0,
4881
- subscribers,
4882
- pending: [],
4883
- scheduled: false
4884
- };
4885
- const flush = () => {
4886
- created.frame = void 0;
4887
- created.scheduled = false;
4888
- const batch = created.pending;
4889
- created.pending = [];
4890
- for (const listener of [...subscribers]) {
4891
- if (!subscribers.has(listener)) continue;
4892
- try {
4893
- listener(batch);
4894
- } catch {}
4895
- }
4896
- };
4897
- const schedule = () => {
4898
- if (created.scheduled) return;
4899
- created.scheduled = true;
4900
- if (typeof requestAnimationFrame === "function") created.frame = requestAnimationFrame(flush);
4901
- else flush();
4902
- };
4903
- created.observer = new MutationObserver((records) => {
4904
- if (needsRecords(subscribers)) for (const record of records) created.pending.push(record);
4905
- schedule();
4906
- });
4907
- created.observer.observe(document.body ?? document.documentElement, {
4908
- childList: true,
4909
- subtree: true
4910
- });
4911
- registry[HUB_KEY] = created;
4912
- hub = created;
4913
- }
4914
- const active = hub;
4915
- active.subscribers.add(subscriber);
4916
- let subscribed = true;
4917
- return () => {
4918
- if (!subscribed) return;
4919
- subscribed = false;
4920
- active.subscribers.delete(subscriber);
4921
- if (!needsRecords(active.subscribers)) active.pending = [];
4922
- if (active.subscribers.size === 0 && registry[HUB_KEY] === active) {
4923
- active.observer.disconnect();
4924
- if (active.frame !== void 0 && typeof cancelAnimationFrame === "function") cancelAnimationFrame(active.frame);
4925
- active.frame = void 0;
4926
- active.pending = [];
4927
- active.scheduled = false;
4928
- delete registry[HUB_KEY];
4929
- }
4930
- };
4931
- }
4932
- //#endregion
4933
- //#region src/client/panel-mount-core.ts
4878
+ //#region src/client/native-panel.tsx
4879
+ /** Row order among the shell's global panel rows (Plugins is 0, Schedule 10). */
4880
+ const PANEL_ORDER = 20;
4934
4881
  /**
4935
- * Center-column panel takeover lifecycle.
4882
+ * The sidebar row glyph the shell asks for at its own size and active state.
4883
+ * The shell owns the button, label, tooltip and rail geometry; this component
4884
+ * draws only the glyph, like every other panel row.
4936
4885
  *
4937
- * The `conversation` slot is single-occupant (ui-conversation) and external
4938
- * plugins cannot declare slots, so a family panel takes over the center
4939
- * column at the DOM level: a container is appended inside the center column
4940
- * (`[class*="centerCol"]`, the 0.1.0-rc.6+ AppFrame layout; previously
4941
- * `[data-pane="conversation"]` on older shells — the mount selector keeps
4942
- * both, ssh #243 / task-board #107) as an extra trailing child React never
4943
- * manages, and a stylesheet rule hides the conversation content while the
4944
- * panel is active. Toggling is a data attribute on <html> — no React
4945
- * involvement, so the conversation subtree underneath stays mounted and
4946
- * stateful.
4947
- *
4948
- * Consuming plugins keep a thin wrapper that supplies the panel tree,
4949
- * container attribute names, and stylesheet class; those names are pinned by
4950
- * each package's CSS, skins, and the semantic-attributes contract. The
4951
- * sidebar row toggling the panel shares its core the same way
4952
- * (shared/client/sidebar-entry-core.ts, synced copy).
4953
- */
4954
- const CONVERSATION_COLUMN_SELECTOR = "[data-pane=\"conversation\"], [class*=\"centerCol\"]";
4955
- /** Cross-plugin activation event; detail is the activating panel name. */
4956
- const ACTIVATE_EVENT = "dsh-panel-activate";
4957
- const SIDEBAR_ROW_SELECTOR = "[class*=\"sessionRow\"], [class*=\"projectRow\"], [class*=\"searchResultRow\"], [class*=\"searchResultWorkspace\"], [class*=\"newSession\"]";
4958
- /** Find the center column, or undefined while the frame is not mounted. */
4959
- function conversationColumn() {
4960
- return document.querySelector(CONVERSATION_COLUMN_SELECTOR) ?? void 0;
4961
- }
4962
- /**
4963
- * Mount a family panel into the center column and bind its visibility to the
4964
- * owning controller's open state.
4965
- * @returns disposer unmounting the tree and restoring the column.
4886
+ * The glyph carries `data-dsh-panel-entry` because it is the only DOM the
4887
+ * panel's own code owns inside that shell-owned row: the L2 contract (skins)
4888
+ * resolves which row belongs to which plugin through it, since the shell
4889
+ * stamps no per-entry hook of its own (see contracts/semantic-attrs-v1.md).
4890
+ * @param props - the shell's icon share: square edge and selection state.
4891
+ * @returns the decorative board glyph.
4966
4892
  */
4967
- function mountCenterPanel(options) {
4968
- let root;
4969
- let container;
4970
- let unsubscribeLocale;
4971
- try {
4972
- unsubscribeLocale = options.locale?.subscribe(() => {
4973
- if (root !== void 0) options.render(root);
4974
- });
4975
- } catch {}
4976
- const ensure = () => {
4977
- if (container !== void 0 && !container.isConnected) {
4978
- root?.unmount();
4979
- root = void 0;
4980
- container.remove();
4981
- container = void 0;
4982
- }
4983
- if (container === void 0) {
4984
- const column = conversationColumn();
4985
- if (column === void 0) return;
4986
- container = document.createElement("div");
4987
- container.dataset[options.viewDatasetKey] = "";
4988
- container.dataset.dshPlugin = options.pluginName;
4989
- container.className = options.viewClassName;
4990
- column.appendChild(container);
4991
- }
4992
- if (root !== void 0 || !options.isOpen()) return;
4993
- root = (0, react_dom_client.createRoot)(container);
4994
- options.render(root);
4995
- };
4996
- const unsubscribeBody = subscribeBodyInvalidations(() => {
4997
- ensure();
4893
+ function TaskBoardPanelIcon({ size }) {
4894
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
4895
+ "data-dsh-panel-entry": TASK_BOARD_PANEL_ID,
4896
+ viewBox: "0 0 16 16",
4897
+ width: size,
4898
+ height: size,
4899
+ fill: "none",
4900
+ stroke: "currentColor",
4901
+ strokeWidth: "1.3",
4902
+ strokeLinecap: "round",
4903
+ strokeLinejoin: "round",
4904
+ "aria-hidden": "true",
4905
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
4906
+ x: "2",
4907
+ y: "2.5",
4908
+ width: "12",
4909
+ height: "11",
4910
+ rx: "1.5"
4911
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2 6.5h12M6.5 6.5v7" })]
4998
4912
  });
4999
- const applyActive = () => {
5000
- if (options.isOpen()) {
5001
- ensure();
5002
- document.documentElement.removeAttribute(options.siblingActiveAttribute);
5003
- document.documentElement.setAttribute(options.activeAttribute, "");
5004
- document.dispatchEvent(new CustomEvent(ACTIVATE_EVENT, { detail: options.panelName }));
5005
- } else document.documentElement.removeAttribute(options.activeAttribute);
5006
- };
5007
- const onOtherActivate = (event) => {
5008
- if (event.detail === options.siblingPanelName && options.isOpen()) options.close();
5009
- };
5010
- const onClickSidebarRow = (event) => {
5011
- if (!options.isOpen()) return;
5012
- const target = event.target;
5013
- if (target === null) return;
5014
- if (target.closest(SIDEBAR_ROW_SELECTOR) !== null) options.close();
5015
- };
5016
- document.addEventListener("click", onClickSidebarRow, true);
5017
- document.addEventListener(ACTIVATE_EVENT, onOtherActivate);
5018
- const unsubscribe = options.subscribe(applyActive);
5019
- applyActive();
5020
- ensure();
5021
- return () => {
5022
- document.removeEventListener("click", onClickSidebarRow, true);
5023
- document.removeEventListener(ACTIVATE_EVENT, onOtherActivate);
5024
- unsubscribeBody();
5025
- unsubscribe();
5026
- unsubscribeLocale?.();
5027
- document.documentElement.removeAttribute(options.activeAttribute);
5028
- root?.unmount();
5029
- root = void 0;
5030
- container?.remove();
5031
- container = void 0;
5032
- };
5033
4913
  }
5034
- //#endregion
5035
- //#region src/client/board-mount.tsx
5036
4914
  /**
5037
- * Mount the board React tree into the center column and bind its visibility
5038
- * to the controller's boardOpen state.
5039
- * @param controller - the board controller driving the view.
5040
- * @param locale - locale-change source; when given, re-renders a mounted board
5041
- * on a Language switch.
5042
- * @returns disposer unmounting the tree and restoring the column.
4915
+ * The main-slot page. The layout mounts it only while the board is the selected
4916
+ * panel, so the conversation keeps the center column untouched the rest of the
4917
+ * time; the wrapper carries the pinned `data-dsh-taskboard-view` semantic
4918
+ * anchor (L2 contract, skins) and the container query context the board's
4919
+ * responsive rules read.
4920
+ * @param props - the framework main-slot share plus this entry's injected face.
4921
+ * @returns the board page.
5043
4922
  */
5044
- function mountBoard(controller, locale) {
5045
- return mountCenterPanel({
5046
- render: (root) => root.render(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TaskBoard, { controller })),
5047
- viewDatasetKey: "dshTaskboardView",
5048
- pluginName: "task-board",
5049
- viewClassName: board_module_css_default.boardView,
5050
- activeAttribute: "data-dsh-taskboard-active",
5051
- siblingActiveAttribute: "data-dsh-ssh-active",
5052
- panelName: "taskboard",
5053
- siblingPanelName: "ssh",
5054
- isOpen: () => controller.getSnapshot().boardOpen,
5055
- close: () => controller.closeBoard(),
5056
- subscribe: (listener) => controller.subscribe(listener),
5057
- locale
4923
+ function TaskBoardPanel({ controller }) {
4924
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4925
+ className: board_module_css_default.panel,
4926
+ "data-dsh-taskboard-view": "",
4927
+ "data-dsh-plugin": "task-board",
4928
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TaskBoard, { controller })
5058
4929
  });
5059
4930
  }
5060
- //#endregion
5061
- //#region src/client/sidebar-entry-core.ts
5062
4931
  /**
5063
- * Shared sidebar entry injection core.
5064
- *
5065
- * dsh's sidebar shell exposes no slot an external plugin can register into,
5066
- * so the entry row is injected between the shell's New Session button and the
5067
- * workspace browser. The injection self-heals: a MutationObserver watches the
5068
- * sidebar root and re-inserts the row whenever a React re-render displaces it
5069
- * (re-insertion happens in the same frame, before paint, so no flicker).
5070
- *
5071
- * The row is plain DOM (no React tree) so it can never disturb the shell's
5072
- * reconciliation; the view it toggles is a separate root owned by the caller.
4932
+ * Register the board's sidebar row and center-column page.
5073
4933
  *
5074
- * Packages receive this file as a generated copy via scripts/sync-shared.mjs;
5075
- * edit the shared source and re-run the sync instead of editing a copy.
5076
- */
5077
- /** Find the sidebar shell root element, or undefined while not yet mounted. */
5078
- function sidebarRoot() {
5079
- const column = document.querySelector("[data-pane=\"sidebar\"], [class*=\"sidebarCol\"]");
5080
- if (column === null) return void 0;
5081
- return column.querySelector("[class*=\"logoRow\"]")?.parentElement ?? column.firstElementChild;
5082
- }
5083
- /** The New Session button: nested in the logo row on current shells, a direct child on legacy shells. */
5084
- function newSessionButton(root) {
5085
- const nested = root.querySelector("button[class*=\"newSession\"]");
5086
- if (nested !== null) return nested;
5087
- for (const child of root.children) if (child.tagName === "BUTTON") return child;
5088
- }
5089
- /** Build the entry row (detached; inserted once the shell is up). */
5090
- function createEntry(options) {
5091
- const entry = document.createElement("button");
5092
- entry.type = "button";
5093
- entry.setAttribute(options.rowAttribute, "");
5094
- if (options.plugin !== void 0) {
5095
- entry.setAttribute("data-dsh-plugin", options.plugin);
5096
- entry.setAttribute("data-dsh-part", "sidebar-entry");
5097
- }
5098
- entry.className = options.css["entry"] ?? "";
5099
- const labelSpan = document.createElement("span");
5100
- labelSpan.className = options.css["entryLabel"] ?? "";
5101
- const iconSpan = document.createElement("span");
5102
- iconSpan.className = options.css["entryIcon"] ?? "";
5103
- iconSpan.innerHTML = options.icon;
5104
- entry.append(iconSpan, labelSpan);
5105
- const applyLabel = () => {
5106
- entry.setAttribute("aria-label", options.label());
5107
- if (options.tooltip !== void 0) entry.setAttribute("title", options.tooltip());
5108
- labelSpan.textContent = options.label();
5109
- };
5110
- applyLabel();
5111
- entry.addEventListener("click", options.onToggle);
5112
- return {
5113
- entry,
5114
- applyLabel
5115
- };
5116
- }
5117
- /** Re-insert the entry after the New Session row (before the browser region). */
5118
- function placeEntry(root, entry, options) {
5119
- const button = newSessionButton(root);
5120
- if (button === void 0) return false;
5121
- if (entry.parentElement !== root) {
5122
- const row = button.closest("[class*=\"logoRow\"]");
5123
- const base = row !== null && row.parentElement === root ? row : button;
5124
- const family = Array.from(root.children).filter((el) => el instanceof HTMLElement && el.matches(options.familySelectors.join(", ")));
5125
- const anchor = options.position === "before" ? family.length > 0 ? family[0] : base.nextElementSibling : family.length > 0 ? family[family.length - 1].nextElementSibling : base.nextElementSibling;
5126
- root.insertBefore(entry, anchor);
5127
- }
5128
- return true;
5129
- }
5130
- /**
5131
- * Mount the sidebar entry, waiting for the shell to render and self-healing
5132
- * on later React re-renders.
5133
- * @param options - the row's attribute/icon/copy/action/ordering configuration.
5134
- * @returns disposer removing the entry and its observers.
4934
+ * Both seats are declared by shell plugins this package does not depend on at
4935
+ * runtime, so each registration is wrapped in `ctx.slots.inject`: the callback
4936
+ * runs only after the owning entry declares the seat, and a shell that never
4937
+ * declares it leaves the board simply absent instead of failing boot.
4938
+ * @param ctx - client root context (services: slots).
4939
+ * @param controller - the board controller the page and the row drive.
4940
+ * @returns disposer releasing both registrations.
5135
4941
  */
5136
- function mountSidebarEntry$1(options) {
5137
- if (typeof document !== "undefined" && document.querySelector(options.rowSelector) !== null) return () => {};
5138
- const { entry, applyLabel } = createEntry(options);
5139
- let root;
5140
- let placed = false;
5141
- let unsubscribeRefresh;
5142
- if (options.refresh !== void 0) try {
5143
- unsubscribeRefresh = options.refresh.subscribe(applyLabel);
5144
- } catch {}
5145
- const tryPlace = () => {
5146
- if (root !== void 0 && !root.isConnected) {
5147
- rootObserver.disconnect();
5148
- root = void 0;
5149
- placed = false;
5150
- }
5151
- if (placed) {
5152
- if (document.body.contains(entry)) return;
5153
- rootObserver.disconnect();
5154
- root = void 0;
5155
- placed = false;
5156
- }
5157
- root ??= sidebarRoot();
5158
- if (root === void 0) return;
5159
- placed = placeEntry(root, entry, options);
5160
- if (placed) rootObserver.observe(root, {
5161
- childList: true,
5162
- subtree: true
5163
- });
5164
- };
5165
- const unsubscribeBody = subscribeBodyInvalidations(() => {
5166
- tryPlace();
5167
- });
5168
- const rootObserver = new MutationObserver(() => {
5169
- if (root === void 0 || !root.isConnected) {
5170
- placed = false;
5171
- tryPlace();
5172
- return;
5173
- }
5174
- if (!root.contains(entry)) placed = placeEntry(root, entry, options);
5175
- });
5176
- const unsubscribeActive = options.active === void 0 ? void 0 : (() => {
5177
- const syncActive = () => {
5178
- if (options.active.isOpen()) entry.dataset.active = "true";
5179
- else delete entry.dataset.active;
5180
- };
5181
- const unsubscribe = options.active.subscribe(syncActive);
5182
- syncActive();
5183
- return unsubscribe;
5184
- })();
5185
- tryPlace();
4942
+ function registerTaskBoardPanel(ctx, controller) {
4943
+ const slots = ctx.slots;
4944
+ const disposers = [];
4945
+ disposers.push(slots.inject("sidebar.panellist", () => slots.register({
4946
+ name: "sidebar.panellist",
4947
+ id: TASK_BOARD_PANEL_ID,
4948
+ order: PANEL_ORDER,
4949
+ label: () => t("entry.label")
4950
+ }, TaskBoardPanelIcon)));
4951
+ disposers.push(slots.inject("main", () => slots.register({
4952
+ name: "main",
4953
+ key: TASK_BOARD_PANEL_ID,
4954
+ inject: () => ({ controller })
4955
+ }, TaskBoardPanel)));
5186
4956
  return () => {
5187
- unsubscribeBody();
5188
- rootObserver.disconnect();
5189
- unsubscribeRefresh?.();
5190
- unsubscribeActive?.();
5191
- entry.remove();
4957
+ for (const dispose of disposers.splice(0)) dispose();
5192
4958
  };
5193
4959
  }
5194
4960
  //#endregion
5195
- //#region src/client/sidebar-entry.ts
5196
- /** Stable data attribute identifying the injected entry row. */
5197
- const ENTRY_SELECTOR = "[data-dsh-taskboard-entry]";
5198
- /** Inline icon normalized to the shell's 16px navigation glyph size. */
5199
- const ICON = "<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"2.5\" width=\"12\" height=\"11\" rx=\"1.5\"/><path d=\"M2 6.5h12M6.5 6.5v7\"/></svg>";
5200
- /**
5201
- * Mount the sidebar entry, waiting for the shell to render and self-healing
5202
- * on later React re-renders.
5203
- * @param controller - the board controller the entry toggles.
5204
- * @param locale - locale-change source; when given, re-applies the label on
5205
- * a Language switch (the plain-DOM row otherwise keeps the mount-time copy).
5206
- * @returns disposer removing the entry and its observers.
5207
- */
5208
- function mountSidebarEntry(controller, locale) {
5209
- return mountSidebarEntry$1({
5210
- rowAttribute: "data-dsh-taskboard-entry",
5211
- rowSelector: ENTRY_SELECTOR,
5212
- plugin: "task-board",
5213
- icon: ICON,
5214
- css: board_module_css_default,
5215
- label: () => t("entry.label"),
5216
- refresh: locale === void 0 ? void 0 : { subscribe: (listener) => locale.subscribe(listener) },
5217
- onToggle: () => {
5218
- controller.toggleBoard();
5219
- },
5220
- position: "before",
5221
- familySelectors: ["[data-dsh-taskboard-entry]", "[data-dsh-ssh-entry]"],
5222
- active: {
5223
- subscribe: (listener) => controller.subscribe(listener),
5224
- isOpen: () => controller.getSnapshot().boardOpen
5225
- }
5226
- });
5227
- }
5228
- //#endregion
5229
4961
  //#region \0dsh-css:packages/dsh-task-board/src/client/settings-card.module.css.mjs
5230
4962
  const css = ".Jh0q7G_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.Jh0q7G_card:hover{border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_header{appearance:none;box-sizing:border-box;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.Jh0q7G_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Jh0q7G_headerStatic{box-sizing:border-box;border-radius:12px;align-items:center;gap:12px;width:100%;padding:14px 16px;display:flex}.Jh0q7G_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Jh0q7G_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.Jh0q7G_description{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}.Jh0q7G_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Jh0q7G_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.Jh0q7G_chevronOpen{transform:rotate(180deg)}.Jh0q7G_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.Jh0q7G_readOnly{color:var(--dsw-alias-label-secondary);margin:12px 0 0;font-size:12px;line-height:1.5}.Jh0q7G_notExposed{color:var(--dsw-alias-state-warn-primary);margin:12px 0 0;font-size:12px;line-height:1.5}.Jh0q7G_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.Jh0q7G_failed{min-width:0;color:var(--dsw-alias-state-error-primary,#b42318);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:12px;line-height:1.5;overflow:hidden}.Jh0q7G_discard,.Jh0q7G_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.Jh0q7G_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.Jh0q7G_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.Jh0q7G_discard:disabled,.Jh0q7G_save:disabled{opacity:.4;cursor:default}.Jh0q7G_discard:focus-visible,.Jh0q7G_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Jh0q7G_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.Jh0q7G_field+.Jh0q7G_field{border-top:1px solid var(--dsw-alias-border-l2)}.Jh0q7G_head{align-items:center;gap:8px;display:flex}.Jh0q7G_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.Jh0q7G_badges{align-items:center;gap:8px;display:inline-flex}.Jh0q7G_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Jh0q7G_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.Jh0q7G_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.Jh0q7G_reset:disabled{cursor:default}.Jh0q7G_reset:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.Jh0q7G_input,.Jh0q7G_select{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Jh0q7G_input:focus-visible,.Jh0q7G_select:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.Jh0q7G_input:disabled,.Jh0q7G_select:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.Jh0q7G_inputInvalid{border:1px solid var(--dsw-alias-state-error-primary,#b42318);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Jh0q7G_inputInvalid:focus-visible{outline:2px solid var(--dsw-alias-state-error-primary,#b42318);outline-offset:1px;border-color:var(--dsw-alias-state-error-primary,#b42318)}.Jh0q7G_selectWrap{position:relative}.Jh0q7G_selectButton{appearance:none;text-align:left;cursor:pointer;justify-content:space-between;align-items:center;gap:8px;width:100%;display:flex}.Jh0q7G_selectLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.Jh0q7G_selectChevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.Jh0q7G_selectChevronOpen{transform:rotate(180deg)}.Jh0q7G_selectPopup{z-index:40;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);max-height:240px;box-shadow:0 8px 24px var(--dsw-alias-bg-mask-2);opacity:0;border-radius:8px;flex-direction:column;padding:4px;transition:opacity .1s,transform .1s;display:flex;position:absolute;top:calc(100% + 4px);left:0;right:0;overflow-y:auto;transform:translateY(-4px)}.Jh0q7G_selectPopupOpen{opacity:1;transform:none}.Jh0q7G_selectPopupClose{opacity:0;pointer-events:none;transform:translateY(-4px)}.Jh0q7G_selectOption{color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;text-overflow:ellipsis;border-radius:6px;flex-shrink:0;padding:6px 10px;font-size:13px;line-height:1.5;overflow:hidden}.Jh0q7G_selectOption:hover,.Jh0q7G_selectOptionActive{background:var(--dsw-alias-interactive-bg-hover)}.Jh0q7G_selectOptionSelected{color:var(--dsw-alias-brand-primary);background:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 10%, transparent);font-weight:500}.Jh0q7G_invalid{color:var(--dsw-alias-state-error-primary,#b42318);margin:0;font-size:12px;line-height:1.5}.Jh0q7G_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:1.5}@media (prefers-reduced-motion:reduce){.Jh0q7G_card,.Jh0q7G_header,.Jh0q7G_chevron,.Jh0q7G_chevronOpen,.Jh0q7G_discard,.Jh0q7G_save,.Jh0q7G_selectChevron,.Jh0q7G_selectChevronOpen,.Jh0q7G_selectPopup{transition:none}}";
5231
4963
  const tagId = "@linxin666/dsh-client-ui-task-board/packages/dsh-task-board/src/client/settings-card.module.css";
@@ -6353,7 +6085,7 @@ window.__ModuleLoader__.load({
6353
6085
  /** The building package's version, when the bundle carries it. */
6354
6086
  function bakedVersion() {
6355
6087
  try {
6356
- return "0.4.2";
6088
+ return "0.4.3";
6357
6089
  } catch {
6358
6090
  return;
6359
6091
  }
@@ -6541,6 +6273,96 @@ window.__ModuleLoader__.load({
6541
6273
  reconcile();
6542
6274
  }
6543
6275
  //#endregion
6276
+ //#region src/client/settings-entry-form.ts
6277
+ /** The snapshot a form reports before the Host has answered with this entry. */
6278
+ function pendingSnapshot() {
6279
+ return {
6280
+ status: "loading",
6281
+ value: void 0,
6282
+ base: void 0,
6283
+ user: void 0,
6284
+ revision: void 0,
6285
+ writable: false,
6286
+ mode: "host"
6287
+ };
6288
+ }
6289
+ /**
6290
+ * Create a settings form bound to the profile entry id this Host serves, and
6291
+ * rebound whenever the shared describe mirror names a different one of this
6292
+ * package's rows.
6293
+ * @param options - the shared forms service and this package's candidate row ids.
6294
+ * @returns a form delegating to the currently resolved entry's own form.
6295
+ */
6296
+ function createServedEntryForm(options) {
6297
+ const { forms, entryIds } = options;
6298
+ const fallbackId = entryIds[0];
6299
+ const namespaceId = entryIds[entryIds.length - 1];
6300
+ const listeners = /* @__PURE__ */ new Set();
6301
+ let boundId;
6302
+ let bound;
6303
+ let offBound;
6304
+ let snapshot = pendingSnapshot();
6305
+ /** Republish: the delegated snapshot when one is bound, the pending one otherwise. */
6306
+ const publish = () => {
6307
+ if (bound !== void 0) snapshot = bound.getSnapshot();
6308
+ for (const listener of [...listeners]) listener();
6309
+ };
6310
+ /**
6311
+ * The entry id the mirror currently justifies. An unanswered or empty mirror
6312
+ * is not evidence of absence, so it keeps the first candidate; a mirror that
6313
+ * answers without any of this package's rows leaves the namespace itself.
6314
+ * @returns the entry id to bind.
6315
+ */
6316
+ const resolve = () => {
6317
+ let served;
6318
+ try {
6319
+ served = forms.describe().getSnapshot().view?.namespaces.map((row) => row.ns);
6320
+ } catch {
6321
+ served = void 0;
6322
+ }
6323
+ if (served === void 0 || served.length === 0) return fallbackId;
6324
+ return entryIds.find((id) => served.includes(id)) ?? namespaceId;
6325
+ };
6326
+ /** Bind (or rebind) the resolved entry's form; a no-op while it is unchanged. */
6327
+ const bind = () => {
6328
+ const target = resolve();
6329
+ if (target === boundId) return;
6330
+ offBound?.();
6331
+ offBound = void 0;
6332
+ let form;
6333
+ try {
6334
+ form = forms.get(target);
6335
+ } catch {
6336
+ boundId = void 0;
6337
+ return;
6338
+ }
6339
+ boundId = target;
6340
+ bound = form;
6341
+ offBound = form.subscribe(() => {
6342
+ publish();
6343
+ });
6344
+ publish();
6345
+ };
6346
+ try {
6347
+ forms.describe().subscribe(() => {
6348
+ bind();
6349
+ });
6350
+ } catch {}
6351
+ bind();
6352
+ return {
6353
+ getSnapshot: () => snapshot,
6354
+ subscribe: (listener) => {
6355
+ listeners.add(listener);
6356
+ return () => {
6357
+ listeners.delete(listener);
6358
+ };
6359
+ },
6360
+ set: (field, value) => bound?.set(field, value) ?? Promise.resolve(false),
6361
+ unset: (field) => bound?.unset(field) ?? Promise.resolve(false),
6362
+ mutate: (ops, expectedRevision) => bound?.mutate(ops, expectedRevision) ?? Promise.resolve(false)
6363
+ };
6364
+ }
6365
+ //#endregion
6544
6366
  //#region src/client/index.ts
6545
6367
  /** Locale namespace this plugin owns. */
6546
6368
  const NS = "task-board";
@@ -6581,7 +6403,8 @@ window.__ModuleLoader__.load({
6581
6403
  "locale",
6582
6404
  "remote",
6583
6405
  "remote.session",
6584
- "uiWorkspace"
6406
+ "uiWorkspace",
6407
+ "layout"
6585
6408
  ];
6586
6409
  /**
6587
6410
  * Mount the task board.
@@ -6626,6 +6449,9 @@ window.__ModuleLoader__.load({
6626
6449
  const controller = new BoardController({
6627
6450
  store: new LocalStorageTaskStore(),
6628
6451
  transport: new HttpTaskBoardHostTransport(),
6452
+ panel: { select: (panelId) => {
6453
+ ctx.get("layout")?.selectPanel?.(panelId);
6454
+ } },
6629
6455
  sessions: {
6630
6456
  current: () => mainViewSessionId(sessions.list.getSnapshot().byId),
6631
6457
  open: (id) => ctx.uiWorkspace.openSession(id),
@@ -6706,10 +6532,18 @@ window.__ModuleLoader__.load({
6706
6532
  pushModelOptions();
6707
6533
  }));
6708
6534
  try {
6709
- disposers.push(mountSidebarEntry(controller, ctx.locale));
6710
- disposers.push(mountBoard(controller, ctx.locale));
6535
+ disposers.push(registerTaskBoardPanel(ctx, controller));
6536
+ const layoutFace = ctx.get("layout");
6537
+ if (layoutFace?.panelInfo !== void 0) {
6538
+ const sync = () => {
6539
+ const active = layoutFace.panelInfo.getSnapshot().activePanelId;
6540
+ controller.syncPanelSelection(active === "task-board" ? TASK_BOARD_PANEL_ID : null);
6541
+ };
6542
+ sync();
6543
+ disposers.push(layoutFace.panelInfo.subscribe(sync));
6544
+ }
6711
6545
  } catch (error) {
6712
- console.error("[dsh-task-board] mount failed:", error);
6546
+ console.error("[dsh-task-board] panel registration failed:", error);
6713
6547
  }
6714
6548
  uiDisposer = () => {
6715
6549
  for (const dispose of disposers.splice(0)) dispose();
@@ -6744,19 +6578,23 @@ window.__ModuleLoader__.load({
6744
6578
  function bindSettingsForm(ctx) {
6745
6579
  const binder = ctx.get("webUiSettings");
6746
6580
  if (binder !== void 0 && typeof binder.bind === "function") return binder.bind({ namespace: TASK_BOARD_NS });
6747
- return ctx.configForms.get(servedEntryId(ctx.configForms));
6581
+ return createServedEntryForm({
6582
+ forms: ctx.configForms,
6583
+ entryIds: TASK_BOARD_ENTRY_IDS
6584
+ });
6748
6585
  }
6749
6586
  /**
6750
- * The profile entry id this package's own row carries.
6587
+ * The profile entry id this package's own row carries, for a page that serves
6588
+ * no family binder.
6751
6589
  *
6752
6590
  * The shared describe mirror is the only local evidence of which row id this
6753
- * profile actually serves, but it answers asynchronously: at plugin
6754
- * activation it usually holds nothing yet. An unanswered mirror therefore
6755
- * binds the aggregate row id rather than guessing among the candidates —
6756
- * the form is bound once for the session, so a wrong guess would leave the
6757
- * card reporting an unserved namespace even after the mirror settles.
6591
+ * profile actually serves, but it answers asynchronously: at plugin activation
6592
+ * it usually holds nothing yet. An unanswered mirror therefore binds the
6593
+ * aggregate row id rather than guessing among the candidates, and the binding
6594
+ * is re-resolved once the mirror answers — see
6595
+ * {@link createServedEntryForm}, which owns that rebinding.
6758
6596
  * @param forms - the shared configuration forms service.
6759
- * @returns the entry id to bind.
6597
+ * @returns the entry id to bind before the mirror answers.
6760
6598
  */
6761
6599
  function servedEntryId(forms) {
6762
6600
  let served;
@@ -6772,6 +6610,7 @@ window.__ModuleLoader__.load({
6772
6610
  exports.apply = apply;
6773
6611
  exports.bindSettingsForm = bindSettingsForm;
6774
6612
  exports.inject = inject;
6613
+ exports.servedEntryId = servedEntryId;
6775
6614
  return module.exports;
6776
6615
  }
6777
6616
  });