@keith9681/dsh-sidebar 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/README_EN.md +0 -0
  4. package/cordis.patch.yml +49 -0
  5. package/lib/client-editor.js +34651 -0
  6. package/lib/client-mermaid.js +200629 -0
  7. package/lib/client-registry.js +13388 -0
  8. package/lib/client-terminal.js +8904 -0
  9. package/lib/client.js +13388 -0
  10. package/lib/index.js +3959 -0
  11. package/lib/invariant.js +22 -0
  12. package/lib/types/agent-pty.d.ts +226 -0
  13. package/lib/types/browser-probe.d.ts +15 -0
  14. package/lib/types/bundle-route.d.ts +12 -0
  15. package/lib/types/client/BrowserView.d.ts +22 -0
  16. package/lib/types/client/DiffTab.d.ts +6 -0
  17. package/lib/types/client/DiffView.d.ts +51 -0
  18. package/lib/types/client/EditorHost.d.ts +12 -0
  19. package/lib/types/client/FileTree.d.ts +36 -0
  20. package/lib/types/client/GitView.d.ts +8 -0
  21. package/lib/types/client/OrphanedTab.d.ts +11 -0
  22. package/lib/types/client/PdfView.d.ts +6 -0
  23. package/lib/types/client/RenderBoundary.d.ts +32 -0
  24. package/lib/types/client/SandboxStatusBar.d.ts +10 -0
  25. package/lib/types/client/SideCardSection.d.ts +74 -0
  26. package/lib/types/client/SideChatView.d.ts +16 -0
  27. package/lib/types/client/Sidebar.d.ts +6 -0
  28. package/lib/types/client/SubagentView.d.ts +16 -0
  29. package/lib/types/client/TabBar.d.ts +43 -0
  30. package/lib/types/client/TerminalView.d.ts +24 -0
  31. package/lib/types/client/TextEditor.d.ts +10 -0
  32. package/lib/types/client/TreePanel.d.ts +23 -0
  33. package/lib/types/client/UploadOverlay.d.ts +20 -0
  34. package/lib/types/client/add-plugin-modal.d.ts +15 -0
  35. package/lib/types/client/api.d.ts +268 -0
  36. package/lib/types/client/binary-download.d.ts +12 -0
  37. package/lib/types/client/breakpoints.d.ts +12 -0
  38. package/lib/types/client/browser.d.ts +50 -0
  39. package/lib/types/client/builtins/index.d.ts +18 -0
  40. package/lib/types/client/builtins/tabs.d.ts +11 -0
  41. package/lib/types/client/builtins/viewers.d.ts +3 -0
  42. package/lib/types/client/chunk-loader.d.ts +124 -0
  43. package/lib/types/client/chunks/editor.d.ts +9 -0
  44. package/lib/types/client/chunks/mermaid.d.ts +10 -0
  45. package/lib/types/client/chunks/terminal.d.ts +9 -0
  46. package/lib/types/client/cm-themes.d.ts +24 -0
  47. package/lib/types/client/conversation-draft.d.ts +14 -0
  48. package/lib/types/client/desktop-env.d.ts +35 -0
  49. package/lib/types/client/editable-state.d.ts +27 -0
  50. package/lib/types/client/editor-load.d.ts +66 -0
  51. package/lib/types/client/frame-batcher.d.ts +24 -0
  52. package/lib/types/client/icons.d.ts +57 -0
  53. package/lib/types/client/image-types.d.ts +3 -0
  54. package/lib/types/client/ime-guard.d.ts +36 -0
  55. package/lib/types/client/index.d.ts +19 -0
  56. package/lib/types/client/intercept.d.ts +33 -0
  57. package/lib/types/client/lang.d.ts +12 -0
  58. package/lib/types/client/lazy-chunk.d.ts +25 -0
  59. package/lib/types/client/link-intercept.d.ts +42 -0
  60. package/lib/types/client/locales.d.ts +366 -0
  61. package/lib/types/client/mermaid-blocks.d.ts +41 -0
  62. package/lib/types/client/mermaid-sanitize.d.ts +2 -0
  63. package/lib/types/client/mermaid.d.ts +12 -0
  64. package/lib/types/client/open-when-sized.d.ts +20 -0
  65. package/lib/types/client/open-with-settings.d.ts +4 -0
  66. package/lib/types/client/open-with.d.ts +87 -0
  67. package/lib/types/client/openpath-intercept.d.ts +41 -0
  68. package/lib/types/client/paths.d.ts +35 -0
  69. package/lib/types/client/pdf-types.d.ts +2 -0
  70. package/lib/types/client/plugin-settings.d.ts +8 -0
  71. package/lib/types/client/plugins-shared.d.ts +27 -0
  72. package/lib/types/client/plugins-tabs.d.ts +3 -0
  73. package/lib/types/client/plugins-viewers.d.ts +3 -0
  74. package/lib/types/client/prefs.d.ts +41 -0
  75. package/lib/types/client/produced-files.d.ts +23 -0
  76. package/lib/types/client/selection-payload.d.ts +27 -0
  77. package/lib/types/client/service.d.ts +440 -0
  78. package/lib/types/client/settings-nav-icon.d.ts +19 -0
  79. package/lib/types/client/shell-presets.d.ts +48 -0
  80. package/lib/types/client/sidechat-transcript.d.ts +103 -0
  81. package/lib/types/client/split-pane.d.ts +30 -0
  82. package/lib/types/client/state.d.ts +359 -0
  83. package/lib/types/client/subagent-detect.d.ts +54 -0
  84. package/lib/types/client/subagent-jobs.d.ts +63 -0
  85. package/lib/types/client/tab-content-memo.d.ts +33 -0
  86. package/lib/types/client/terminal-font.d.ts +20 -0
  87. package/lib/types/client/theme.d.ts +45 -0
  88. package/lib/types/client/titlebar-strip.d.ts +23 -0
  89. package/lib/types/client/upload.d.ts +69 -0
  90. package/lib/types/client/wco.d.ts +47 -0
  91. package/lib/types/config.d.ts +64 -0
  92. package/lib/types/context-types.d.ts +603 -0
  93. package/lib/types/fs-operations.d.ts +28 -0
  94. package/lib/types/fs-search.d.ts +24 -0
  95. package/lib/types/fs-tree.d.ts +51 -0
  96. package/lib/types/git.d.ts +82 -0
  97. package/lib/types/html-route.d.ts +59 -0
  98. package/lib/types/index.d.ts +47 -0
  99. package/lib/types/invariant.d.ts +15 -0
  100. package/lib/types/jobs-routes.d.ts +45 -0
  101. package/lib/types/open-external.d.ts +24 -0
  102. package/lib/types/prefs-shared.d.ts +225 -0
  103. package/lib/types/pty-deps.d.ts +78 -0
  104. package/lib/types/pty-manager.d.ts +168 -0
  105. package/lib/types/sidechat-core.d.ts +172 -0
  106. package/lib/types/sidechat-routes.d.ts +30 -0
  107. package/lib/types/subagent-activity.d.ts +44 -0
  108. package/lib/types/subagent-live-route.d.ts +44 -0
  109. package/lib/types/tools.d.ts +31 -0
  110. package/lib/types/trust-fence.d.ts +24 -0
  111. package/lib/types/wire.d.ts +38 -0
  112. package/package.json +173 -0
  113. package/scripts/install.ps1 +289 -0
  114. package/scripts/install.sh +287 -0
  115. package/src/agent-pty.ts +527 -0
  116. package/src/browser-probe.ts +26 -0
  117. package/src/bundle-route.ts +129 -0
  118. package/src/client/BrowserView.tsx +253 -0
  119. package/src/client/DiffTab.tsx +110 -0
  120. package/src/client/DiffView.tsx +305 -0
  121. package/src/client/EditorHost.tsx +525 -0
  122. package/src/client/FileTree.tsx +653 -0
  123. package/src/client/GitView.tsx +558 -0
  124. package/src/client/OrphanedTab.tsx +27 -0
  125. package/src/client/PdfView.tsx +110 -0
  126. package/src/client/RenderBoundary.tsx +49 -0
  127. package/src/client/SandboxStatusBar.tsx +60 -0
  128. package/src/client/SideCardSection.module.css +960 -0
  129. package/src/client/SideCardSection.tsx +1152 -0
  130. package/src/client/SideChatView.module.css +437 -0
  131. package/src/client/SideChatView.tsx +644 -0
  132. package/src/client/Sidebar.tsx +1148 -0
  133. package/src/client/SubagentView.module.css +547 -0
  134. package/src/client/SubagentView.tsx +883 -0
  135. package/src/client/TabBar.tsx +305 -0
  136. package/src/client/TerminalView.tsx +383 -0
  137. package/src/client/TextEditor.tsx +500 -0
  138. package/src/client/TreePanel.tsx +273 -0
  139. package/src/client/UploadOverlay.tsx +62 -0
  140. package/src/client/add-plugin-modal.tsx +199 -0
  141. package/src/client/api.ts +335 -0
  142. package/src/client/binary-download.tsx +23 -0
  143. package/src/client/breakpoints.ts +51 -0
  144. package/src/client/browser.ts +119 -0
  145. package/src/client/builtins/index.ts +37 -0
  146. package/src/client/builtins/tabs.tsx +331 -0
  147. package/src/client/builtins/viewers.tsx +125 -0
  148. package/src/client/chunk-loader.ts +351 -0
  149. package/src/client/chunks/editor.tsx +9 -0
  150. package/src/client/chunks/mermaid.tsx +10 -0
  151. package/src/client/chunks/terminal.tsx +9 -0
  152. package/src/client/cm-themes.ts +129 -0
  153. package/src/client/conversation-draft.ts +29 -0
  154. package/src/client/css-modules.d.ts +5 -0
  155. package/src/client/desktop-env.ts +72 -0
  156. package/src/client/editable-state.ts +70 -0
  157. package/src/client/editor-load.ts +92 -0
  158. package/src/client/frame-batcher.ts +56 -0
  159. package/src/client/icons.tsx +161 -0
  160. package/src/client/image-types.ts +8 -0
  161. package/src/client/ime-guard.ts +47 -0
  162. package/src/client/index.tsx +369 -0
  163. package/src/client/intercept.tsx +110 -0
  164. package/src/client/lang.ts +103 -0
  165. package/src/client/layout.css +94 -0
  166. package/src/client/lazy-chunk.tsx +89 -0
  167. package/src/client/link-intercept.ts +73 -0
  168. package/src/client/locales.ts +734 -0
  169. package/src/client/mermaid-blocks.ts +110 -0
  170. package/src/client/mermaid-sanitize.ts +93 -0
  171. package/src/client/mermaid.tsx +401 -0
  172. package/src/client/open-when-sized.ts +43 -0
  173. package/src/client/open-with-settings.tsx +135 -0
  174. package/src/client/open-with.ts +221 -0
  175. package/src/client/openpath-intercept.ts +62 -0
  176. package/src/client/paths.ts +47 -0
  177. package/src/client/pdf-types.ts +4 -0
  178. package/src/client/plugin-settings.ts +43 -0
  179. package/src/client/plugins-shared.ts +29 -0
  180. package/src/client/plugins-tabs.ts +87 -0
  181. package/src/client/plugins-viewers.ts +30 -0
  182. package/src/client/prefs.ts +207 -0
  183. package/src/client/produced-files.ts +91 -0
  184. package/src/client/selection-payload.ts +86 -0
  185. package/src/client/service.ts +838 -0
  186. package/src/client/settings-nav-icon.ts +45 -0
  187. package/src/client/shell-presets.ts +83 -0
  188. package/src/client/sidebar.module.css +2577 -0
  189. package/src/client/sidechat-transcript.ts +321 -0
  190. package/src/client/split-pane.tsx +322 -0
  191. package/src/client/state.ts +1175 -0
  192. package/src/client/subagent-detect.ts +137 -0
  193. package/src/client/subagent-jobs.ts +161 -0
  194. package/src/client/tab-content-memo.ts +46 -0
  195. package/src/client/terminal-font.ts +28 -0
  196. package/src/client/theme.ts +110 -0
  197. package/src/client/titlebar-strip.ts +37 -0
  198. package/src/client/upload.ts +187 -0
  199. package/src/client/wco.ts +120 -0
  200. package/src/config.ts +155 -0
  201. package/src/context-types.ts +610 -0
  202. package/src/fs-operations.ts +99 -0
  203. package/src/fs-search.ts +86 -0
  204. package/src/fs-tree.ts +158 -0
  205. package/src/git.ts +244 -0
  206. package/src/html-route.ts +106 -0
  207. package/src/index.ts +1132 -0
  208. package/src/invariant.ts +32 -0
  209. package/src/jobs-routes.ts +257 -0
  210. package/src/open-external.ts +90 -0
  211. package/src/prefs-shared.ts +268 -0
  212. package/src/pty-deps.ts +240 -0
  213. package/src/pty-manager.ts +376 -0
  214. package/src/sidechat-core.ts +468 -0
  215. package/src/sidechat-routes.ts +344 -0
  216. package/src/subagent-activity.ts +91 -0
  217. package/src/subagent-live-route.ts +93 -0
  218. package/src/tools.ts +479 -0
  219. package/src/trust-fence.ts +77 -0
  220. package/src/wire.ts +100 -0
@@ -0,0 +1,960 @@
1
+ /**
2
+ * Side card settings section chrome (DSH-native tokens throughout):
3
+ * - the section is a column of GROUP CONTAINER cards (the PluginCard recipe:
4
+ * l2 hairline, 16px radius, layer-3 fill) with a heading + inventory count
5
+ * badge (the settings catalogHeading recipe), opening with a one-line
6
+ * intro (the DSH section heading+intro recipe);
7
+ * - 常规 holds full-width settings rows (the DSH settings-row recipe:
8
+ * title/desc left + control right, hairline separators) whose toggles are
9
+ * custom switches — a real checkbox (native semantics and focus) driving
10
+ * a styled track/thumb;
11
+ * - the feature inventories are responsive GRIDS of small toggle cards
12
+ * (auto-fill columns — several cards per row, wrapping): icon chip +
13
+ * title + type id, the card's on/off state IS its visual state
14
+ * (enabled = softened brand border + tinted fill + a compact brand
15
+ * switch knob at the far right — the card itself is the toggle;
16
+ * disabled = neutral hairline + dimmed, no knob); every card shares a
17
+ * uniform min-height so rows stay equal whether or not they carry a
18
+ * settings strip;
19
+ * - features that declare related settings carry a labeled SETTINGS STRIP
20
+ * across the card's bottom edge (gear icon + text, hairline-separated)
21
+ * opening a native Modal (wider than the primitive default) whose rows
22
+ * follow the same row recipe with switch controls and a Done footer;
23
+ * - the width input stays a native settings row (a value, not a switch).
24
+ */
25
+
26
+ .section {
27
+ display: flex;
28
+ flex-direction: column;
29
+ gap: 16px;
30
+ width: 100%;
31
+ max-width: 760px;
32
+ /* The DSH settings shell's `.options` area owns vertical scrolling. Keep
33
+ this page a plain content column like Plugins → Plugin list so its
34
+ scrollbar stays at the shell edge instead of being inset by the options
35
+ area's right padding. */
36
+ }
37
+
38
+ /* One-line section intro (the DSH section heading+intro recipe). */
39
+ .intro {
40
+ margin: 0;
41
+ padding: 0 2px;
42
+ font-size: 13px;
43
+ line-height: 20px;
44
+ color: var(--dsw-alias-label-tertiary);
45
+ }
46
+
47
+ /* Group container: the DSH card recipe (PluginCard) — l2 hairline, r16,
48
+ layer-3 fill; holds its own heading + stacked rows / card grid. */
49
+ .group {
50
+ flex: none;
51
+ display: flex;
52
+ flex-direction: column;
53
+ gap: 8px;
54
+ padding: 20px;
55
+ box-sizing: border-box;
56
+ border: 1px solid var(--dsw-alias-border-l2);
57
+ border-radius: 16px;
58
+ background: var(--dsw-alias-bg-layer-3);
59
+ }
60
+
61
+ /* Group heading: 13/600 + the inventory count badge (the settings
62
+ catalogHeading recipe: count in tabular-nums, tertiary). */
63
+ .groupHeading {
64
+ display: flex;
65
+ align-items: baseline;
66
+ gap: 7px;
67
+ padding: 0 2px 6px;
68
+ font-size: 13px;
69
+ line-height: 20px;
70
+ font-weight: 600;
71
+ color: var(--dsw-alias-label-primary);
72
+ }
73
+
74
+ /* The inventory count: a soft-accent pill (the versionBadgeTag token recipe)
75
+ so the count reads as metadata, not as part of the heading text. */
76
+ .count {
77
+ padding: 1px 8px;
78
+ border-radius: 999px;
79
+ background: var(--dsw-alias-accent-soft, var(--dsw-alias-bg-layer-2));
80
+ font-size: 11px;
81
+ line-height: 16px;
82
+ font-weight: 500;
83
+ color: var(--dsw-alias-label-secondary);
84
+ font-variant-numeric: tabular-nums;
85
+ }
86
+
87
+ /* Responsive inventory: as many small cards per row as the width allows. */
88
+ .grid {
89
+ display: grid;
90
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
91
+ gap: 12px;
92
+ }
93
+
94
+ /* One small toggle card (visual chrome; the interactive part is .cardMain).
95
+ A uniform min-height keeps every inventory card the same height across
96
+ rows whether or not it carries a settings strip (strip cards are
97
+ naturally taller); overflow:hidden clips the strip to the card's radius. */
98
+ .card {
99
+ position: relative;
100
+ display: flex;
101
+ flex-direction: column;
102
+ min-height: 106px;
103
+ overflow: hidden;
104
+ border-radius: 12px;
105
+ border: 1px solid var(--dsw-alias-border-l2);
106
+ background: transparent;
107
+ font: inherit;
108
+ color: inherit;
109
+ cursor: pointer;
110
+ transition: background 0.12s ease, border-color 0.12s ease;
111
+ }
112
+
113
+ /* Hover affordance on disabled cards only (enabled cards are already lit). */
114
+ .card:not(.cardOn):hover {
115
+ background: var(--dsw-alias-interactive-bg-hover);
116
+ border-color: var(--dsw-alias-label-dimmed);
117
+ }
118
+
119
+ /* Enabled = highlighted: a SOFTENED brand border (color-mix, the icon-chip
120
+ precedent) + tinted fill — full-strength brand reads harsh at card scale. */
121
+ .cardOn {
122
+ border-color: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 45%, transparent);
123
+ background: var(--dsw-alias-interactive-bg-active);
124
+ }
125
+
126
+ /* The card's switch: the whole main area (top row + desc) flips the feature.
127
+ flex:1 lets the main area absorb the extra height of the uniform card
128
+ (cards without a settings strip stretch to match the strip cards). */
129
+ .cardMain {
130
+ display: flex;
131
+ flex: 1;
132
+ flex-direction: column;
133
+ gap: 6px;
134
+ width: 100%;
135
+ padding: 12px;
136
+ border: 0;
137
+ border-radius: inherit;
138
+ background: transparent;
139
+ font: inherit;
140
+ color: inherit;
141
+ text-align: left;
142
+ cursor: pointer;
143
+ }
144
+
145
+ .cardMain:focus-visible,
146
+ .cardSettings:focus-visible,
147
+ .rowGear:focus-visible {
148
+ outline: 2px solid var(--dsw-alias-border-l4);
149
+ outline-offset: 2px;
150
+ }
151
+
152
+ .cardTop {
153
+ display: flex;
154
+ align-items: center;
155
+ gap: 8px;
156
+ min-width: 0;
157
+ min-height: 28px;
158
+ }
159
+
160
+ /* The icon sits in a rounded chip: brand-tinted while the card is on,
161
+ neutral (layer-2 fill + hairline) while off. */
162
+ .cardIconChip {
163
+ display: inline-flex;
164
+ align-items: center;
165
+ justify-content: center;
166
+ flex: none;
167
+ width: 28px;
168
+ height: 28px;
169
+ border-radius: 8px;
170
+ border: 1px solid var(--dsw-alias-border-l2);
171
+ background: var(--dsw-alias-bg-layer-2);
172
+ color: var(--dsw-alias-label-tertiary);
173
+ }
174
+
175
+ .cardOn .cardIconChip {
176
+ border-color: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 35%, transparent);
177
+ background: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 12%, transparent);
178
+ color: var(--dsw-alias-button-primary-fill);
179
+ }
180
+
181
+ .cardTitle {
182
+ flex: 1;
183
+ min-width: 0;
184
+ font-size: 13px;
185
+ line-height: 20px;
186
+ font-weight: 600;
187
+ color: var(--dsw-alias-label-secondary);
188
+ white-space: nowrap;
189
+ overflow: hidden;
190
+ text-overflow: ellipsis;
191
+ }
192
+
193
+ .cardOn .cardTitle {
194
+ color: var(--dsw-alias-label-primary);
195
+ }
196
+
197
+ /* The compact on/off switch knob at the card's far right (enabled only):
198
+ the card itself is the toggle (aria-pressed on .cardMain), so this is a
199
+ PURELY VISUAL switch — same track/thumb geometry as the row switches,
200
+ one size down. Off cards show no knob (neutral card = off). */
201
+ .cardSwitch {
202
+ display: inline-flex;
203
+ align-items: center;
204
+ flex: none;
205
+ }
206
+
207
+ .cardSwitchTrack {
208
+ display: inline-flex;
209
+ align-items: center;
210
+ width: 30px;
211
+ height: 16px;
212
+ padding: 2px;
213
+ box-sizing: border-box;
214
+ border-radius: 8px;
215
+ background: var(--dsw-alias-bg-layer-2);
216
+ border: 1px solid var(--dsw-alias-border-l2);
217
+ transition: background 0.15s ease, border-color 0.15s ease;
218
+ }
219
+
220
+ .cardSwitchThumb {
221
+ display: block;
222
+ width: 10px;
223
+ height: 10px;
224
+ border-radius: 50%;
225
+ background: var(--dsw-alias-label-tertiary);
226
+ transition: transform 0.15s ease, background 0.15s ease;
227
+ }
228
+
229
+ .cardOn .cardSwitchTrack {
230
+ border-color: var(--dsw-alias-button-primary-fill);
231
+ background: var(--dsw-alias-button-primary-fill);
232
+ }
233
+
234
+ .cardOn .cardSwitchThumb {
235
+ transform: translateX(14px);
236
+ background: var(--dsw-alias-bg-layer-3);
237
+ }
238
+
239
+ .cardDesc {
240
+ font-size: 11px;
241
+ line-height: 16px;
242
+ color: var(--dsw-alias-label-tertiary);
243
+ white-space: nowrap;
244
+ overflow: hidden;
245
+ text-overflow: ellipsis;
246
+ }
247
+
248
+ /* The "add plugin" card: same grid cell / chrome as the inventory cards
249
+ (it shares .card), but a DASHED border — the repo's first dashed surface;
250
+ the hover accent follows the existing drag-drop dashed outlines
251
+ (sidebar.module.css .dropCenter / .tabBarDrop). */
252
+ .addCard {
253
+ align-items: flex-start;
254
+ padding: 12px;
255
+ border-style: dashed;
256
+ border-color: var(--dsw-alias-border-l2);
257
+ text-align: left;
258
+ }
259
+
260
+ .addCard:hover {
261
+ background: var(--dsw-alias-interactive-bg-hover);
262
+ border-color: var(--dsw-alias-interactive-bg-hover-accent);
263
+ color: var(--dsw-alias-label-primary);
264
+ }
265
+
266
+ .addCard:hover .cardTitle {
267
+ color: var(--dsw-alias-label-primary);
268
+ }
269
+
270
+ .addCard:hover .cardIconChip {
271
+ border-color: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 35%, transparent);
272
+ color: var(--dsw-alias-button-primary-fill);
273
+ }
274
+
275
+ .addCard:focus-visible {
276
+ outline: 2px solid var(--dsw-alias-border-l4);
277
+ outline-offset: 2px;
278
+ }
279
+
280
+ .cardOn .cardDesc {
281
+ color: var(--dsw-alias-label-secondary);
282
+ }
283
+
284
+ /* The settings strip: a labeled full-width footer across the card's bottom
285
+ edge (gear icon + "功能设置" text), hairline-separated from the toggle
286
+ area. This is the SECONDARY settings entry — it must be discoverable at
287
+ rest (not a hover-only ghost), so it keeps a steady secondary-ink label
288
+ and answers hover with the brand-accent tint + brand ink. */
289
+ .cardSettings {
290
+ display: flex;
291
+ align-items: center;
292
+ gap: 6px;
293
+ width: 100%;
294
+ padding: 6px 12px;
295
+ border: 0;
296
+ border-top: 1px solid var(--dsw-alias-border-l1);
297
+ background: transparent;
298
+ color: var(--dsw-alias-label-secondary);
299
+ font: inherit;
300
+ font-size: 11px;
301
+ line-height: 16px;
302
+ font-weight: 500;
303
+ text-align: left;
304
+ cursor: pointer;
305
+ transition: background 0.12s ease, color 0.12s ease;
306
+ }
307
+
308
+ .cardOn .cardSettings {
309
+ border-top-color: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 18%, transparent);
310
+ }
311
+
312
+ .cardSettings:hover {
313
+ background: var(--dsw-alias-interactive-bg-hover-accent);
314
+ color: var(--dsw-alias-brand-primary);
315
+ }
316
+
317
+ /* The gear icon button on a general settings ROW (the position-compat
318
+ row's "customize the strip height" entry): a bordered chip (not a ghost)
319
+ so it reads as a control at rest; hover answers with the accent tint. */
320
+ .rowGear {
321
+ display: inline-flex;
322
+ align-items: center;
323
+ justify-content: center;
324
+ width: 22px;
325
+ height: 22px;
326
+ padding: 0;
327
+ border: 1px solid var(--dsw-alias-border-l2);
328
+ border-radius: 6px;
329
+ background: transparent;
330
+ color: var(--dsw-alias-label-secondary);
331
+ cursor: pointer;
332
+ flex: none;
333
+ transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
334
+ }
335
+
336
+ .rowGear:hover {
337
+ border-color: var(--dsw-alias-interactive-bg-hover-accent);
338
+ background: var(--dsw-alias-interactive-bg-hover-accent);
339
+ color: var(--dsw-alias-brand-primary);
340
+ }
341
+
342
+ /* Settings-row recipe (the DSH General section rows): title/desc left,
343
+ control right, hairline separators (stripped on the last row). */
344
+ .row {
345
+ display: flex;
346
+ align-items: center;
347
+ justify-content: space-between;
348
+ gap: 16px;
349
+ padding: 12px 2px;
350
+ border-bottom: 1px solid var(--dsw-alias-border-l2);
351
+ }
352
+
353
+ .row:last-child {
354
+ border-bottom: none;
355
+ }
356
+
357
+ .rowText {
358
+ display: flex;
359
+ flex-direction: column;
360
+ gap: 4px;
361
+ min-width: 0;
362
+ }
363
+
364
+ .title {
365
+ font-size: 14px;
366
+ line-height: 22px;
367
+ color: var(--dsw-alias-label-primary);
368
+ }
369
+
370
+ .desc {
371
+ font-size: 12px;
372
+ line-height: 18px;
373
+ color: var(--dsw-alias-label-tertiary);
374
+ }
375
+
376
+ /* Custom switch: a real checkbox (native semantics + focus, visually
377
+ hidden) driving a styled 36x20 track with a sliding thumb. */
378
+ .switch {
379
+ position: relative;
380
+ display: inline-flex;
381
+ flex: none;
382
+ cursor: pointer;
383
+ }
384
+
385
+ .switchInput {
386
+ position: absolute;
387
+ width: 1px;
388
+ height: 1px;
389
+ margin: 0;
390
+ opacity: 0;
391
+ }
392
+
393
+ .switchTrack {
394
+ display: inline-flex;
395
+ align-items: center;
396
+ width: 36px;
397
+ height: 20px;
398
+ padding: 2px;
399
+ box-sizing: border-box;
400
+ border-radius: 10px;
401
+ border: 1px solid var(--dsw-alias-border-l2);
402
+ background: var(--dsw-alias-bg-layer-2);
403
+ transition: background 0.15s ease, border-color 0.15s ease;
404
+ }
405
+
406
+ .switchThumb {
407
+ display: block;
408
+ width: 14px;
409
+ height: 14px;
410
+ border-radius: 50%;
411
+ background: var(--dsw-alias-label-tertiary);
412
+ transition: transform 0.15s ease, background 0.15s ease;
413
+ }
414
+
415
+ .switch:hover .switchTrack {
416
+ border-color: var(--dsw-alias-label-dimmed);
417
+ }
418
+
419
+ .switchInput:checked + .switchTrack {
420
+ border-color: var(--dsw-alias-button-primary-fill);
421
+ background: var(--dsw-alias-button-primary-fill);
422
+ }
423
+
424
+ .switchInput:checked + .switchTrack .switchThumb {
425
+ transform: translateX(16px);
426
+ background: var(--dsw-alias-bg-layer-3);
427
+ }
428
+
429
+ .switchInput:focus-visible + .switchTrack {
430
+ outline: 2px solid var(--dsw-alias-state-business-primary);
431
+ outline-offset: 2px;
432
+ }
433
+
434
+ .control {
435
+ flex: none;
436
+ display: flex;
437
+ align-items: center;
438
+ gap: 6px;
439
+ }
440
+
441
+ .percentInput {
442
+ width: 76px;
443
+ }
444
+
445
+ /* Text/number rows in the settings popup: the free-form input (e.g. the
446
+ terminal font family) gets a generous width; numeric rows (font size)
447
+ keep the compact width of the general number inputs. */
448
+ .typedInput {
449
+ width: 200px;
450
+ }
451
+
452
+ .typedInputNumber {
453
+ width: 76px;
454
+ }
455
+
456
+ /* Select rows: the closed anchor is a compact button (selected option's
457
+ icon when the options carry icons, plus title and a chevron); the dropdown
458
+ itself is the primitives Menu (portal). */
459
+ .selectAnchor {
460
+ display: flex;
461
+ align-items: center;
462
+ gap: 6px;
463
+ max-width: 220px;
464
+ padding: 4px 8px;
465
+ border: 1px solid var(--dsw-alias-border-l2);
466
+ border-radius: 8px;
467
+ background: var(--dsw-alias-bg-layer-3);
468
+ color: var(--dsw-alias-label-primary);
469
+ font-size: 13px;
470
+ line-height: 20px;
471
+ cursor: pointer;
472
+ }
473
+
474
+ .selectAnchor:hover {
475
+ border-color: var(--dsw-alias-label-dimmed);
476
+ }
477
+
478
+ .selectAnchorIcon {
479
+ display: inline-flex;
480
+ flex: none;
481
+ }
482
+
483
+ .selectAnchorText {
484
+ overflow: hidden;
485
+ text-overflow: ellipsis;
486
+ white-space: nowrap;
487
+ }
488
+
489
+ /* One big-icon option card inside the select dropdown. */
490
+ .selectOption {
491
+ display: flex;
492
+ align-items: center;
493
+ gap: 10px;
494
+ min-width: 200px;
495
+ }
496
+
497
+ .selectOptionIcon {
498
+ display: inline-flex;
499
+ flex: none;
500
+ color: var(--dsw-alias-label-secondary);
501
+ }
502
+
503
+ .selectOptionText {
504
+ display: flex;
505
+ flex-direction: column;
506
+ min-width: 0;
507
+ }
508
+
509
+ .suffix {
510
+ font-size: 14px;
511
+ line-height: 22px;
512
+ color: var(--dsw-alias-label-secondary);
513
+ }
514
+
515
+ /* The multi-line custom-CSS input (scheme `custom`): monospace, generous
516
+ height, resizable — same surface tokens as the typed inputs. */
517
+ .cssTextArea {
518
+ width: 100%;
519
+ box-sizing: border-box;
520
+ min-height: 120px;
521
+ padding: 8px 10px;
522
+ border: 1px solid var(--dsw-alias-border-l2);
523
+ border-radius: 8px;
524
+ background: var(--dsw-alias-bg-layer-3);
525
+ color: var(--dsw-alias-label-primary);
526
+ font-family: var(--ds-font-family-code, monospace);
527
+ font-size: 12px;
528
+ line-height: 1.6;
529
+ resize: vertical;
530
+ }
531
+
532
+ .cssTextArea:focus-visible {
533
+ outline: 2px solid var(--dsw-alias-state-business-primary);
534
+ outline-offset: 2px;
535
+ }
536
+
537
+ /* Secondary settings popup: a wider dialog than the primitive default (the
538
+ dialog portals to document.body; the doubled class keeps the width rule
539
+ above the primitive's .dialog regardless of stylesheet order). */
540
+ .popupDialog.popupDialog {
541
+ width: min(460px, 100%);
542
+ }
543
+
544
+ /* Popup rows: each setting gets the same outer chrome as a plugin-list
545
+ PluginCard (l2 hairline, 12px radius, layer-3 fill). The row's title,
546
+ description and control geometry stay unchanged inside that frame.
547
+ The body scrolls INTERNALLY once a feature declares many rows (e.g.
548
+ Terminal's six) — the dialog shell and its Done footer stay put; a thin
549
+ token-driven scrollbar makes the scrollable region discoverable.
550
+ box-sizing:border-box keeps width:100% + the scrollbar gutter from
551
+ overflowing horizontally (a content-box width would add the 4px pad and
552
+ show a horizontal scrollbar); overflow-x:hidden is the belt-and-braces
553
+ guarantee that rows always FILL the width and never slide sideways. */
554
+ .popupRows {
555
+ display: flex;
556
+ flex-direction: column;
557
+ gap: 8px;
558
+ width: 100%;
559
+ box-sizing: border-box;
560
+ max-height: min(52vh, 440px);
561
+ overflow-y: auto;
562
+ overflow-x: hidden;
563
+ padding-right: 4px;
564
+ scrollbar-width: thin;
565
+ scrollbar-color: var(--dsw-alias-scrollbar-bg-l2, transparent) transparent;
566
+ }
567
+
568
+ .popupRows::-webkit-scrollbar {
569
+ width: 6px;
570
+ }
571
+
572
+ .popupRows::-webkit-scrollbar-thumb {
573
+ border-radius: 3px;
574
+ background: var(--dsw-alias-scrollbar-bg-l2, var(--dsw-alias-border-l2));
575
+ }
576
+
577
+ .popupRows::-webkit-scrollbar-thumb:hover {
578
+ background: var(--dsw-alias-scrollbar-hover-l2, var(--dsw-alias-label-dimmed));
579
+ }
580
+
581
+ .popupRow {
582
+ flex: none;
583
+ display: flex;
584
+ align-items: center;
585
+ justify-content: space-between;
586
+ gap: 16px;
587
+ min-width: 0;
588
+ padding: 12px 14px;
589
+ border: 1px solid var(--dsw-alias-border-l2);
590
+ border-radius: 12px;
591
+ background: var(--dsw-alias-bg-layer-3);
592
+ transition: border-color 0.16s, background 0.16s;
593
+ }
594
+
595
+ .popupRow:hover {
596
+ border-color: var(--dsw-alias-label-dimmed);
597
+ }
598
+
599
+ /* The popup's Done button: the settings primary-button recipe
600
+ (PluginCard .save: label-primary fill, inverted surface text). */
601
+ .done {
602
+ appearance: none;
603
+ border: 1px solid transparent;
604
+ border-radius: 8px;
605
+ padding: 5px 14px;
606
+ font: inherit;
607
+ font-size: 13px;
608
+ line-height: 1.5;
609
+ cursor: pointer;
610
+ background: var(--dsw-alias-label-primary);
611
+ color: var(--dsw-alias-bg-layer-3);
612
+ }
613
+
614
+ .done:focus-visible {
615
+ outline: 2px solid var(--dsw-alias-brand-primary);
616
+ outline-offset: 1px;
617
+ }
618
+
619
+ .error {
620
+ padding: 10px 0 2px;
621
+ font-size: 12px;
622
+ line-height: 17px;
623
+ color: var(--dsw-alias-state-error-primary);
624
+ }
625
+
626
+ /* ── "Add plugin" modal ──────────────────────────────────────────────── */
627
+
628
+ /* A wide dialog like the settings popup (doubled class keeps the width
629
+ rule above the primitive's .dialog regardless of stylesheet order). */
630
+ .pluginModal.pluginModal {
631
+ width: min(560px, 100%);
632
+ }
633
+
634
+ .pluginList {
635
+ display: flex;
636
+ flex-direction: column;
637
+ gap: 12px;
638
+ width: 100%;
639
+ }
640
+
641
+ /* The GitHub topic entry: a full-width secondary BUTTON (not a link — it
642
+ opens a real new browser tab via window.open, bypassing the sidebar
643
+ link takeover). */
644
+ .pluginTopicBtn {
645
+ width: 100%;
646
+ appearance: none;
647
+ border: 1px solid var(--dsw-alias-border-l2);
648
+ border-radius: 8px;
649
+ padding: 6px 12px;
650
+ font: inherit;
651
+ font-size: 12px;
652
+ line-height: 18px;
653
+ color: var(--dsw-alias-label-secondary);
654
+ background: var(--dsw-alias-bg-layer-1);
655
+ cursor: pointer;
656
+ }
657
+
658
+ .pluginTopicBtn:hover {
659
+ background: var(--dsw-alias-interactive-bg-hover);
660
+ border-color: var(--dsw-alias-interactive-bg-hover-accent);
661
+ color: var(--dsw-alias-label-primary);
662
+ }
663
+
664
+ .pluginTopicBtn:focus-visible {
665
+ outline: 2px solid var(--dsw-alias-border-l4);
666
+ outline-offset: 1px;
667
+ }
668
+
669
+ .pluginEmpty {
670
+ padding: 20px 2px;
671
+ font-size: 12px;
672
+ line-height: 18px;
673
+ color: var(--dsw-alias-label-tertiary);
674
+ }
675
+
676
+ /* One catalog entry: name + install button on the head row, description,
677
+ then the install command in a mono block (the exact script that gets
678
+ pre-typed into the terminal — review it here before installing). */
679
+ .pluginEntry {
680
+ display: flex;
681
+ flex-direction: column;
682
+ gap: 4px;
683
+ padding: 12px;
684
+ border: 1px solid var(--dsw-alias-border-l2);
685
+ border-radius: 12px;
686
+ background: var(--dsw-alias-bg-layer-1);
687
+ }
688
+
689
+ .pluginEntryHead {
690
+ display: flex;
691
+ align-items: center;
692
+ justify-content: space-between;
693
+ gap: 12px;
694
+ }
695
+
696
+ .pluginEntryActions {
697
+ display: inline-flex;
698
+ align-items: center;
699
+ gap: 6px;
700
+ flex: none;
701
+ }
702
+
703
+ /* The per-entry "jump" button: opens the plugin repo in a REAL new browser
704
+ tab (window.open — a button, so the sidebar link takeover cannot reroute
705
+ it). Secondary style, quieter than the Install button. */
706
+ .pluginJumpBtn {
707
+ flex: none;
708
+ appearance: none;
709
+ border: 1px solid var(--dsw-alias-border-l2);
710
+ border-radius: 8px;
711
+ padding: 3px 12px;
712
+ font: inherit;
713
+ font-size: 12px;
714
+ line-height: 1.5;
715
+ cursor: pointer;
716
+ background: transparent;
717
+ color: var(--dsw-alias-label-secondary);
718
+ }
719
+
720
+ .pluginJumpBtn:hover {
721
+ background: var(--dsw-alias-interactive-bg-hover);
722
+ border-color: var(--dsw-alias-interactive-bg-hover-accent);
723
+ color: var(--dsw-alias-label-primary);
724
+ }
725
+
726
+ .pluginJumpBtn:focus-visible {
727
+ outline: 2px solid var(--dsw-alias-border-l4);
728
+ outline-offset: 1px;
729
+ }
730
+
731
+ /* The plugin name: a BUTTON (not an anchor — an anchor would be caught by
732
+ the sidebar link takeover at document capture, ignoring target=_blank)
733
+ styled like a link; opens the repo in a real new browser tab. */
734
+ .pluginName {
735
+ appearance: none;
736
+ min-width: 0;
737
+ padding: 0;
738
+ border: 0;
739
+ background: transparent;
740
+ font: inherit;
741
+ font-size: 13px;
742
+ line-height: 20px;
743
+ font-weight: 600;
744
+ color: var(--dsw-alias-label-primary);
745
+ text-align: left;
746
+ text-decoration: none;
747
+ overflow: hidden;
748
+ text-overflow: ellipsis;
749
+ white-space: nowrap;
750
+ cursor: pointer;
751
+ }
752
+
753
+ .pluginName:hover {
754
+ text-decoration: underline;
755
+ color: var(--dsw-alias-button-primary-fill);
756
+ }
757
+
758
+ .pluginDesc {
759
+ font-size: 12px;
760
+ line-height: 18px;
761
+ color: var(--dsw-alias-label-secondary);
762
+ }
763
+
764
+ .pluginInstall {
765
+ display: block;
766
+ padding: 6px 10px;
767
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
768
+ font-size: 11px;
769
+ line-height: 16px;
770
+ color: var(--dsw-alias-label-secondary);
771
+ background: var(--dsw-alias-bg-layer-2);
772
+ border: 1px solid var(--dsw-alias-border-l1);
773
+ border-radius: 8px;
774
+ overflow-x: auto;
775
+ white-space: nowrap;
776
+ }
777
+
778
+ /* The per-entry copy button: copies the install script to the
779
+ clipboard (the settings primary-button recipe, smaller than .done). */
780
+ .pluginCopyBtn {
781
+ flex: none;
782
+ appearance: none;
783
+ border: 1px solid transparent;
784
+ border-radius: 8px;
785
+ padding: 3px 12px;
786
+ font: inherit;
787
+ font-size: 12px;
788
+ line-height: 1.5;
789
+ cursor: pointer;
790
+ background: var(--dsw-alias-label-primary);
791
+ color: var(--dsw-alias-bg-layer-3);
792
+ }
793
+
794
+ .pluginCopyBtn:hover {
795
+ background: var(--dsw-alias-button-primary-hover);
796
+ }
797
+
798
+ .pluginCopyBtn:focus-visible {
799
+ outline: 2px solid var(--dsw-alias-brand-primary);
800
+ outline-offset: 1px;
801
+ }
802
+
803
+ @media (prefers-reduced-motion: reduce) {
804
+ .card,
805
+ .cardSettings,
806
+ .cardSwitchTrack,
807
+ .cardSwitchThumb,
808
+ .rowGear,
809
+ .popupRow,
810
+ .switchTrack,
811
+ .switchThumb {
812
+ transition: none;
813
+ }
814
+ }
815
+
816
+ /* The managing plugin's identity badge: name + version pill, token-driven
817
+ (labels via --dsw-alias-label-*, surface via --dsw-alias-bg-layer-2). */
818
+ .versionBadge {
819
+ display: inline-flex;
820
+ align-items: center;
821
+ gap: 8px;
822
+ align-self: flex-start;
823
+ padding: 4px 12px 4px 14px;
824
+ border-radius: 999px;
825
+ border: 1px solid var(--dsw-alias-border-l2);
826
+ background: var(--dsw-alias-bg-layer-2);
827
+ font-size: 12px;
828
+ line-height: 18px;
829
+ }
830
+
831
+ .versionBadgeName {
832
+ color: var(--dsw-alias-label-primary);
833
+ font-weight: 600;
834
+ }
835
+
836
+ .versionBadgeTag {
837
+ padding: 1px 8px;
838
+ border-radius: 999px;
839
+ background: var(--dsw-alias-accent-soft, var(--dsw-alias-border-l2));
840
+ color: var(--dsw-alias-label-secondary);
841
+ font-variant-numeric: tabular-nums;
842
+ }
843
+
844
+ /* Catalog search input: a compact text field above the list (token-driven).
845
+ The entries list below it scrolls INDEPENDENTLY — with many plugins the
846
+ modal stays navigable instead of growing unbounded. */
847
+ .pluginSearch {
848
+ width: 100%;
849
+ box-sizing: border-box;
850
+ appearance: none;
851
+ border: 1px solid var(--dsw-alias-border-l2);
852
+ border-radius: 8px;
853
+ padding: 6px 10px;
854
+ font: inherit;
855
+ font-size: 12px;
856
+ line-height: 18px;
857
+ color: var(--dsw-alias-label-primary);
858
+ background: var(--dsw-alias-bg-layer-1);
859
+ }
860
+
861
+ .pluginSearch::placeholder {
862
+ color: var(--dsw-alias-label-tertiary);
863
+ }
864
+
865
+ .pluginSearch:focus-visible {
866
+ outline: 2px solid var(--dsw-alias-border-l4);
867
+ outline-offset: 1px;
868
+ }
869
+
870
+ /* The entries area scrolls within the modal once the catalog grows past
871
+ the viewport (max-height + own scrollbar keeps the modal shell fixed). */
872
+ .pluginEntries {
873
+ display: flex;
874
+ flex-direction: column;
875
+ gap: 10px;
876
+ max-height: 46vh;
877
+ overflow-y: auto;
878
+ overflow-x: hidden;
879
+ padding-right: 2px;
880
+ }
881
+
882
+ /* One catalog group: optional category heading above its stacked entries. */
883
+ .pluginGroup {
884
+ display: flex;
885
+ flex-direction: column;
886
+ gap: 8px;
887
+ }
888
+
889
+ .pluginGroupHeading {
890
+ font-size: 12px;
891
+ line-height: 18px;
892
+ font-weight: 600;
893
+ color: var(--dsw-alias-label-secondary);
894
+ padding: 2px 2px 0;
895
+ }
896
+
897
+ /* Open-with settings panel: one custom editor row (name + URL template +
898
+ VSCode-family checkbox + remove) and the row-validity hint. */
899
+ .openWithEditorRow {
900
+ display: grid;
901
+ grid-template-columns: 1fr 1.5fr auto auto;
902
+ gap: 8px;
903
+ align-items: center;
904
+ min-width: 0;
905
+ }
906
+
907
+ .openWithEditorInput,
908
+ .openWithEditorTemplate {
909
+ width: 100%;
910
+ min-width: 0;
911
+ box-sizing: border-box;
912
+ padding: 5px 8px;
913
+ border: 1px solid var(--dsw-alias-border-l2);
914
+ border-radius: 8px;
915
+ background: var(--dsw-alias-bg-layer-3);
916
+ color: var(--dsw-alias-label-primary);
917
+ font: inherit;
918
+ font-size: 13px;
919
+ line-height: 20px;
920
+ }
921
+
922
+ .openWithEditorInput:focus-visible,
923
+ .openWithEditorTemplate:focus-visible {
924
+ outline: 2px solid var(--dsw-alias-state-business-primary);
925
+ outline-offset: 1px;
926
+ }
927
+
928
+ .openWithFamily {
929
+ display: inline-flex;
930
+ align-items: center;
931
+ gap: 5px;
932
+ font-size: 12px;
933
+ color: var(--dsw-alias-label-secondary);
934
+ white-space: nowrap;
935
+ cursor: pointer;
936
+ }
937
+
938
+ .openWithRemove {
939
+ display: inline-flex;
940
+ align-items: center;
941
+ justify-content: center;
942
+ padding: 4px;
943
+ border: none;
944
+ border-radius: 8px;
945
+ background: none;
946
+ color: var(--dsw-alias-label-tertiary);
947
+ cursor: pointer;
948
+ }
949
+
950
+ .openWithRemove:hover {
951
+ color: var(--dsw-alias-state-error-primary);
952
+ background: var(--dsw-alias-bg-layer-2);
953
+ }
954
+
955
+ .openWithHint {
956
+ font-size: 12px;
957
+ line-height: 17px;
958
+ color: var(--dsw-alias-state-error-primary);
959
+ padding: 0 2px;
960
+ }