@furayoshi/dsh-widechat 0.7.0 → 0.7.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.
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin that widens the conversation column past the shipped 748px cap, right-aligns the session stats strip, and caps the composer card so long inputs do not hide the conversation above. Adds a settings row to the General page so all of these can be tuned without restarting DSH.
4
4
 
5
+ **NOTE**: as at the current state, this packages has been heavily vibecoded, including most of this README. I might rewrite it at the later date, but you have been warned :)
6
+
5
7
  ![widechat ui](media/widechat-ui.webp)
6
8
 
7
9
  ![widechat settings](media/widechat-settings.webp)
@@ -23,7 +25,7 @@ If a saved value is out of range or of the wrong type, the plugin falls back to
23
25
 
24
26
  DSH's `plugin` subcommand forwards pnpm commands into the profile directory and reconciles the profile's `dsh.profile.bundles` array against the installed packages. So `dsh plugin --profile web add <spec>` is the canonical install path: it runs `pnpm add <spec>`, then automatically appends the package to `bundles` if (and only if) the installed `package.json` declares a `dsh.bundle.patch` — which this package does.
25
27
 
26
- ### From npm (after this repo is published)
28
+ ### From npmjs
27
29
 
28
30
  ```sh
29
31
  dsh plugin --profile web add @furayoshi/dsh-widechat
@@ -105,7 +107,7 @@ The plugin is two halves:
105
107
  - **Host** (`lib/index.js`) registers a settings namespace `dsh-widechat` with a `z.object` schema (`chatGutterPct`, `statsAlign`, `userBubblePct`, `composerMaxHeightPct`). The schema's bounds match the slider ranges exactly.
106
108
  - **Client** (`lib/client/index.js`) binds a `SettingsScope` to that namespace, re-injects a small CSS override on every scope change, and registers a row in the `settings.general.item` slot.
107
109
 
108
- The CSS override is intentionally minimal — it touches four things, one per setting:
110
+ The CSS override is intentionally minimal — it touches three things, one per setting:
109
111
 
110
112
  ```css
111
113
  :root, .wSkVaW_root, [data-phase] {
@@ -113,16 +115,20 @@ The CSS override is intentionally minimal — it touches four things, one per se
113
115
  --dsh-composer-card-max-width: calc(100% - 2 × <chatGutterPct>%) !important;
114
116
  }
115
117
  .gdEzaW_userStack { max-width: <userBubblePct>% !important; }
116
- .uV2eYG_card { max-height: <composerMaxHeightPct>vh !important; overflow: hidden !important; }
117
- .uV2eYG_scroll { max-height: calc(<composerMaxHeightPct>vh - 64px) !important; }
118
+ .uV2eYG_scroll {
119
+ min-height: 52px !important; /* floor, see below */
120
+ max-height: calc(<composerMaxHeightPct>vh - 64px) !important; /* ceiling on the textarea */
121
+ }
118
122
  .FJxK0a_root { text-align: <statsAlign> !important; }
119
123
  ```
120
124
 
121
125
  `chatGutterPct` and `userBubblePct` are **percentages of the cell**; `composerMaxHeightPct` is a **percentage of the viewport**. The cell grows when the sidebar collapses to the rail (56px from 280px), so the column and the bubble grow with it — and the gutter stays at the same percentage. The composer cap, in contrast, is absolute to the viewport so the conversation above is always visible regardless of the sidebar state.
122
126
 
123
- The reason there are two rules for the composer (`uV2eYG_card` and `uV2eYG_scroll`) is that the shipped card has *no* max-height and the shipped inner scroll has `max-height: var(--dsh-composer-text-max-height)` (336px by default). Without overriding the inner scroll too, the user's `composerMaxHeightPct` slider would only take effect at values that allow the inner 336px cap to grow, which is values 19% on a 1914px viewport the slider would feel broken above 20% on smaller viewports. The inner override (`- 64px` leaves room for the card's padding and accessory row) makes the slider's effect span the full 20–80 range.
127
+ The composer card itself has **no** `max-height` and **no** `overflow: hidden` override. The card grows naturally to fit its inner scroll (capped above) plus the card's chrome (accessory row, trigger row, padding, gaps). Earlier versions did enforce `max-height: <cap>vh; overflow: hidden;` on the card — but the popover menus (model picker, permission presets, …) open upward from the trigger row inside the card via `bottom: calc(100% + 8px)`, and the card's `overflow: hidden` clipped any portion of the menu that extended above the card top. With the card free to overflow, the menus extend above the card into the conversation area and are fully visible. The conversation scroll above the composer shrinks to make room for the taller card.
128
+
129
+ The `min-height: 52px` on `.uV2eYG_scroll` mirrors the shipped hero variant's mirror floor. Without it, on a small viewport with a low cap, the scroll collapses to ~28 px and the trigger row below it ends up visually overlapping the typing area. The 52 px floor keeps the textarea usable in that case; below it, the slider value is a no-op for the cap (the scroll holds at 52 px and does not get any smaller).
124
130
 
125
- DSH's shipped rules are left untouched. The column is still `width: 100%`, `max-width: var(--dsh-chat-content-width)`, `margin: 0 auto`. Toggle, scroll, resize — all the DSH default behavior. The plugin only changes the values of variables (and a few hard caps on the composer) that DSH's CSS already reads.
131
+ DSH's shipped rules are left untouched. The column is still `width: 100%`, `max-width: var(--dsh-chat-content-width)`, `margin: 0 auto`. Toggle, scroll, resize — all the DSH default behavior. The plugin only changes the values of variables (and a few caps on the composer's inner scroll) that DSH's CSS already reads.
126
132
 
127
133
  ## Configuration
128
134
 
@@ -145,7 +151,7 @@ Invalid values are dropped to the defaults and a `console.warn` is logged with t
145
151
 
146
152
  `.wSkVaW_root`, `.Md3f7G_column`, `.uV2eYG_card`, `.uV2eYG_scroll`, `.gdEzaW_userStack`, `.FJxK0a_root` are CSS-Modules-generated class names from `@deepseek-ai/dsh-client-ui-conversation`. Their hashes (the part after the underscore) are recomputed every time that package is rebuilt. Any release of `dsh-client-ui-conversation` can therefore silently break this plugin — specifically, if the shipped rule that reads the variable or has the matching class name changes shape, our override no longer reaches it.
147
153
 
148
- After upgrading `@deepseek-ai/dsh-client-ui-conversation`, check whether the chat column widens, the user bubble stays right-aligned at the configured width, the composer is capped at the configured height, and the stats line still aligns. If any of those regress, the upstream CSS-module hashes changed; see "Updating" below.
154
+ After upgrading `@deepseek-ai/dsh-client-ui-conversation`, check whether the chat column widens, the user bubble stays right-aligned at the configured width, the composer's inner scroll caps at the configured height (and never gets smaller than 52 px), and the stats line still aligns. If any of those regress, the upstream CSS-module hashes changed; see "Updating" below.
149
155
 
150
156
  ### The `chatGutterPct` is interpreted against the cell, not the viewport
151
157
 
@@ -165,8 +171,8 @@ When the upstream hashes change, the fix is mechanical but unavoidable until DSH
165
171
 
166
172
  - `.wSkVaW_root` — the conversation root (defines the chat-content-width variable)
167
173
  - `.Md3f7G_column` — the chat column (reads the variable as max-width)
168
- - `.uV2eYG_card` — the composer card (we cap its max-height)
169
- - `.uV2eYG_scroll` — the composer's inner textarea scroll (we cap its max-height)
174
+ - `.uV2eYG_card` — the composer card (no override see "How it works" for why)
175
+ - `.uV2eYG_scroll` — the composer's inner textarea scroll (we cap its max-height; we floor it at 52px so the trigger row stays below the typing area)
170
176
  - `.gdEzaW_userStack` — the user-message bubble stack (we set its max-width)
171
177
  - `.FJxK0a_root` — the session-stats line (we set its text-align)
172
178
 
@@ -416,26 +416,35 @@ function buildStylesheet(config) {
416
416
  max-width: ${ub} !important;
417
417
  }
418
418
 
419
- /* Composer card max height. The shipped card has no max-height, so on
420
- * long inputs the textarea + accessory row can grow to eat most of
421
- * the screen and hide the conversation above. We cap the card at the
422
- * configured percentage of the viewport; the inner scroll keeps the
423
- * textarea usable, and the user always sees the rest of the conversation.
419
+ /* Composer card height. The shipped card has no max-height, so on long
420
+ * inputs the textarea + accessory row grow until they eat most of the
421
+ * screen and hide the conversation above. We cap the inner textarea
422
+ * scroll at the configured percentage of the viewport (minus the card's
423
+ * chrome accessory row, trigger row, padding, gaps) so the textarea
424
+ * itself stops growing. The card's natural height follows the inner
425
+ * scroll's cap; the conversation scroll above the composer shrinks to
426
+ * make room.
424
427
  *
425
- * The shipped .uV2eYG_scroll inside the card has its own
426
- * max-height (--dsh-composer-text-max-height, 336px by default) that
427
- * silently limits the textarea. We override that too so the user's
428
- * outer cap actually takes effect: the inner scroll gets the card's
429
- * cap minus the card's chrome (padding, accessory row, border
430
- * roughly 64px) so the textarea can grow with the rest of the card. */
431
- .uV2eYG_card {
432
- max-height: ${cmh} !important;
433
- overflow: hidden !important;
434
- }
428
+ * Note: we deliberately do NOT set overflow:hidden on the card.
429
+ * Earlier versions did, to enforce a hard cap on the card's visible
430
+ * box, but that clipped the popover menus (model picker, permission
431
+ * presets, …) which open upward from the trigger row inside the card.
432
+ * The menus are absolutely positioned descendants of an element inside
433
+ * the card, so the card's overflow clipping killed them. With the card
434
+ * free to overflow, the menus extend above the card into the
435
+ * conversation area and are fully visible. */
435
436
  .uV2eYG_scroll {
437
+ /* min-height mirrors the shipped hero variant's mirror floor (52px),
438
+ * so the textarea stays usable even when the cap falls below the
439
+ * natural height of the mirror element below it. Without this, on
440
+ * a small viewport with a low cap, the scroll collapses to ~28px
441
+ * and the trigger row below it visually sits on top of the typing
442
+ * area. */
443
+ min-height: 52px !important;
436
444
  max-height: calc(${cmh} - 64px) !important;
437
445
  }
438
446
  .uV2eYG_hero .uV2eYG_scroll {
447
+ min-height: 52px !important;
439
448
  max-height: calc(${cmh} - 132px) !important;
440
449
  }
441
450
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@furayoshi/dsh-widechat",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "DeepSeek Harness plugin: widens the conversation column, sets the user-bubble width and composer max height, and right-aligns the session stats strip, with a settings-row UI to tune all four. Built for the DSH client plugin slot `settings.general.item`.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",