dsh-ui-tweaks 0.1.0
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/LICENSE +21 -0
- package/README.en.md +75 -0
- package/README.md +65 -0
- package/cordis.patch.yml +12 -0
- package/lib/client.js +393 -0
- package/lib/client.js.map +1 -0
- package/lib/config.js +38 -0
- package/lib/config.js.map +1 -0
- package/lib/index.js +27 -0
- package/lib/index.js.map +1 -0
- package/lib/types/client/index.d.ts +40 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/config.d.ts +41 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/index.d.ts +18 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/web.d.ts +38 -0
- package/lib/types/web.d.ts.map +1 -0
- package/lib/web.js +168 -0
- package/lib/web.js.map +1 -0
- package/package.json +101 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-ui-tweaks contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# dsh-ui-tweaks
|
|
2
|
+
|
|
3
|
+
A [DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/) (DSH) web plugin that live-tunes the conversation UI from the Settings panel.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Message font size (px)** — type any value (10–32); applies to message text, headings, tables and code.
|
|
8
|
+
- **Table style** — choose `Default` or the **Claude Desktop** look (light-gray rounded cell cards with small gaps, no borders; cells share the inline-code background; header not bold).
|
|
9
|
+
- **Dialog width (px)** — type any value (600–1600); the message column, the composer input and the stats line below it widen together.
|
|
10
|
+
|
|
11
|
+
All changes apply **live** — no reload needed. The same values can be hand-edited in the settings document:
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
ui-tweaks:
|
|
15
|
+
fontSize: 16
|
|
16
|
+
tableStyle: claude
|
|
17
|
+
dialogWidth: 880
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Settings entry: **Settings → UI Tweaks**.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# from npm (recommended, prebuilt)
|
|
26
|
+
npx -y @deepseek-ai/dsh plugin --profile web add dsh-ui-tweaks
|
|
27
|
+
|
|
28
|
+
# from GitHub (source; runs the self-contained prepare build)
|
|
29
|
+
npx -y @deepseek-ai/dsh plugin --profile web add github:wlj521/dsh-ui-tweaks
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For GitHub installs, pnpm may ask you to approve the package's build script —
|
|
33
|
+
add the exact key it prints to the profile's `pnpm-workspace.yaml`:
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
allowBuilds:
|
|
37
|
+
dsh-ui-tweaks: true
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
…then run `add` again. Restart DSH web once after installing (bundle plugins
|
|
41
|
+
are scanned at process start).
|
|
42
|
+
|
|
43
|
+
> If pnpm reports symlink/hoist errors, set `nodeLinker: hoisted` in the
|
|
44
|
+
> profile's `pnpm-workspace.yaml`.
|
|
45
|
+
|
|
46
|
+
## Development
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm install
|
|
50
|
+
pnpm build # tsc (server) + tsc (client) + bundle lib/client.js
|
|
51
|
+
pnpm typecheck
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Load against a running DSH with an overlay, or install as a bundle:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx -y @deepseek-ai/dsh web --patch ./cordis.patch.yml # dev overlay
|
|
58
|
+
npx -y @deepseek-ai/dsh plugin --profile web add . # bundle install from this checkout
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## How it works
|
|
62
|
+
|
|
63
|
+
- **Server** (`src/index.ts`) registers the `ui-tweaks` settings namespace and
|
|
64
|
+
mounts a same-origin route (`/_dsh/ui-tweaks/settings`) — the Web settings
|
|
65
|
+
RPC only exposes a fixed allowlist of namespaces in rc.6, so a custom route
|
|
66
|
+
is how a plugin owns a configuration page.
|
|
67
|
+
- **Browser** (`src/client/index.tsx`) reads/writes that route, renders the
|
|
68
|
+
Settings section, and applies the values live via a runtime `<style>` element
|
|
69
|
+
that overrides stable DSH anchors (`[data-chat-flow]`,
|
|
70
|
+
`[data-composer-card]`, `body` markdown font tokens, markdown tables inside
|
|
71
|
+
`[data-slot="conversation.chat.node"]`).
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT
|
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# dsh-ui-tweaks
|
|
2
|
+
|
|
3
|
+
[DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/)(DSH)Web UI 插件:在设置面板中实时调整对话界面——字体大小、表格样式、对话框宽度。
|
|
4
|
+
|
|
5
|
+
## 功能
|
|
6
|
+
|
|
7
|
+
- **消息字体大小(px)**:直接输入数字(10–32),作用于消息正文、标题、表格与代码。
|
|
8
|
+
- **表格样式**:可选 `默认` 或 **Claude Desktop** 风格(浅灰圆角单元格卡片、单元格间有间隙、无边框、单元格与行内代码同底色、表头不加粗)。
|
|
9
|
+
- **对话框宽度(px)**:直接输入数字(600–1600);消息列、输入框、输入框下方的统计栏(轮数/步数/耗时/tok/s)**三者同步变宽**。
|
|
10
|
+
|
|
11
|
+
所有修改**即时生效**,无需刷新。同一份配置也可以直接在设置文档里手改:
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
ui-tweaks:
|
|
15
|
+
fontSize: 16
|
|
16
|
+
tableStyle: claude
|
|
17
|
+
dialogWidth: 880
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
设置入口:**设置 → 界面调整**。
|
|
21
|
+
|
|
22
|
+
## 安装
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# 方式一:从 npm 安装(推荐,预构建产物,一条命令装好)
|
|
26
|
+
npx -y @deepseek-ai/dsh plugin --profile web add dsh-ui-tweaks
|
|
27
|
+
|
|
28
|
+
# 方式二:从 GitHub 仓库安装(源码,会运行自包含的 prepare 构建)
|
|
29
|
+
npx -y @deepseek-ai/dsh plugin --profile web add github:wlj521/dsh-ui-tweaks
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
从 GitHub 安装时,pnpm 可能要求批准该包的构建脚本——把提示的包键加进该 profile 的 `pnpm-workspace.yaml`:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
allowBuilds:
|
|
36
|
+
dsh-ui-tweaks: true
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
然后重新执行 `add`。安装完成后**重启一次 `dsh web`**(bundle 插件在进程启动时扫描)。
|
|
40
|
+
|
|
41
|
+
> 若 pnpm 报符号链接/hoist 相关错误,可在 profile 的 `pnpm-workspace.yaml` 中设置 `nodeLinker: hoisted`。
|
|
42
|
+
|
|
43
|
+
## 开发
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pnpm install
|
|
47
|
+
pnpm build # tsc(服务端)+ tsc(客户端)+ 打包 lib/client.js
|
|
48
|
+
pnpm typecheck
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
本地加载(覆盖层)或作为 bundle 安装:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx -y @deepseek-ai/dsh web --patch ./cordis.patch.yml # 开发覆盖层
|
|
55
|
+
npx -y @deepseek-ai/dsh plugin --profile web add . # 从本目录作为 bundle 安装
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 工作原理
|
|
59
|
+
|
|
60
|
+
- **服务端**(`src/index.ts`):注册 `ui-tweaks` 设置命名空间,并挂载同源路由 `/_dsh/ui-tweaks/settings`——rc.6 的 Web 设置 RPC 只暴露固定白名单命名空间,因此自定义路由是插件拥有配置页的方式。
|
|
61
|
+
- **浏览器端**(`src/client/index.tsx`):读写该路由、渲染设置页,并通过运行时 `<style>` 元素实时应用样式,覆盖稳定的 DSH 锚点(`[data-chat-flow]`、`[data-composer-card]`、`body` 上的 markdown 字体 token、`[data-slot="conversation.chat.node"]` 内的 markdown 表格)。
|
|
62
|
+
|
|
63
|
+
## 协议
|
|
64
|
+
|
|
65
|
+
MIT
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# dsh-ui-tweaks bundle patch
|
|
2
|
+
#
|
|
3
|
+
# Declared by `dsh.bundle.patch` in package.json: when the plugin is installed
|
|
4
|
+
# through the official CLI —
|
|
5
|
+
#
|
|
6
|
+
# dsh plugin --profile <name> add dsh-ui-tweaks
|
|
7
|
+
#
|
|
8
|
+
# — the command appends `dsh-ui-tweaks` to the profile's bundle stack and this
|
|
9
|
+
# patch mounts the server-side plugin row.
|
|
10
|
+
- insert:
|
|
11
|
+
- id: ui-tweaks
|
|
12
|
+
name: 'dsh-ui-tweaks'
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({ id: "dsh-ui-tweaks", factory: (require) => {
|
|
2
|
+
var __modules = Object.create(null); var __cache = Object.create(null);
|
|
3
|
+
__modules["./index.js"] = function(module, exports, require, __load_) {
|
|
4
|
+
"use strict";
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.inject = void 0;
|
|
7
|
+
exports.apply = apply;
|
|
8
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
9
|
+
/**
|
|
10
|
+
* dsh-ui-tweaks — browser half.
|
|
11
|
+
*
|
|
12
|
+
* Reads and writes the `ui-tweaks` settings namespace through the same-origin
|
|
13
|
+
* route served by the server half, applies the chosen font size / table style /
|
|
14
|
+
* dialog width live via a runtime `<style>` element, and renders the Settings
|
|
15
|
+
* panel section that edits them.
|
|
16
|
+
*/
|
|
17
|
+
const react_1 = require("react");
|
|
18
|
+
const NS = 'ui-tweaks';
|
|
19
|
+
const SETTINGS_ROUTE = '/_dsh/ui-tweaks/settings';
|
|
20
|
+
const DEFAULT_FONT_SIZE = 16;
|
|
21
|
+
const MIN_FONT_SIZE = 10;
|
|
22
|
+
const MAX_FONT_SIZE = 32;
|
|
23
|
+
/** Dialog width in px. Keep in sync with src/config.ts. */
|
|
24
|
+
const DEFAULT_DIALOG_WIDTH = 748;
|
|
25
|
+
const MIN_DIALOG_WIDTH = 600;
|
|
26
|
+
const MAX_DIALOG_WIDTH = 1600;
|
|
27
|
+
const en = {
|
|
28
|
+
nav: 'UI Tweaks',
|
|
29
|
+
settingsTitle: 'UI Tweaks',
|
|
30
|
+
settingsIntro: 'Tune the conversation UI: message font size (px), markdown table style, and dialog width. Changes apply live.',
|
|
31
|
+
fontSize: 'Message font size (px)',
|
|
32
|
+
fontSizeHint: `Number between ${MIN_FONT_SIZE} and ${MAX_FONT_SIZE}; applies to message text, headings, tables and code.`,
|
|
33
|
+
tableStyle: 'Table style',
|
|
34
|
+
tableStyleDefault: 'Default',
|
|
35
|
+
tableStyleClaude: 'Claude Desktop',
|
|
36
|
+
dialogWidth: 'Dialog width (px)',
|
|
37
|
+
dialogWidthHint: `Number between ${MIN_DIALOG_WIDTH} and ${MAX_DIALOG_WIDTH}px; 748 is DSH's default column width, larger values widen it.`,
|
|
38
|
+
reset: 'Reset',
|
|
39
|
+
resetDone: 'Reset to default.',
|
|
40
|
+
applied: 'Applied',
|
|
41
|
+
unavailable: 'Settings unavailable.',
|
|
42
|
+
loading: 'Loading…',
|
|
43
|
+
readOnly: 'The active Settings provider is read-only.',
|
|
44
|
+
saved: 'Saved.',
|
|
45
|
+
};
|
|
46
|
+
const zh = {
|
|
47
|
+
nav: '界面调整',
|
|
48
|
+
settingsTitle: '界面调整',
|
|
49
|
+
settingsIntro: '调整对话界面:消息字体大小(像素)、Markdown 表格样式、对话框宽度。修改即时生效。',
|
|
50
|
+
fontSize: '消息字体大小(px)',
|
|
51
|
+
fontSizeHint: `取值 ${MIN_FONT_SIZE}–${MAX_FONT_SIZE},作用于消息正文、标题、表格与代码。`,
|
|
52
|
+
tableStyle: '表格样式',
|
|
53
|
+
tableStyleDefault: '默认',
|
|
54
|
+
tableStyleClaude: 'Claude Desktop',
|
|
55
|
+
dialogWidth: '对话框宽度(px)',
|
|
56
|
+
dialogWidthHint: `取值 ${MIN_DIALOG_WIDTH}–${MAX_DIALOG_WIDTH}px;748 为 DSH 默认列宽,数字越大越宽。`,
|
|
57
|
+
reset: '重置',
|
|
58
|
+
resetDone: '已重置为默认。',
|
|
59
|
+
applied: '已应用',
|
|
60
|
+
unavailable: '设置暂不可用。',
|
|
61
|
+
loading: '加载中…',
|
|
62
|
+
readOnly: '当前设置提供方为只读。',
|
|
63
|
+
saved: '已保存。',
|
|
64
|
+
};
|
|
65
|
+
function resolveDialogWidth(value) {
|
|
66
|
+
if (value === 'wide')
|
|
67
|
+
return 880;
|
|
68
|
+
if (typeof value === 'number')
|
|
69
|
+
return value;
|
|
70
|
+
return DEFAULT_DIALOG_WIDTH;
|
|
71
|
+
}
|
|
72
|
+
function resolveValue(value) {
|
|
73
|
+
return {
|
|
74
|
+
fontSize: typeof value?.fontSize === 'number' ? value.fontSize : DEFAULT_FONT_SIZE,
|
|
75
|
+
tableStyle: value?.tableStyle === 'claude' ? 'claude' : 'default',
|
|
76
|
+
dialogWidth: resolveDialogWidth(value?.dialogWidth),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** Scale one theme px value proportionally to the chosen base size. */
|
|
80
|
+
function rel(base, fontSize) {
|
|
81
|
+
return Math.max(8, Math.round((base / DEFAULT_FONT_SIZE) * fontSize));
|
|
82
|
+
}
|
|
83
|
+
/** Rebuild the markdown font tokens for the chosen base size, keeping the theme faces. */
|
|
84
|
+
function buildFontCss(fontSize) {
|
|
85
|
+
const cs = getComputedStyle(document.body);
|
|
86
|
+
const fam = (name, fallback) => {
|
|
87
|
+
const value = cs.getPropertyValue(name).trim();
|
|
88
|
+
return value.length > 0 ? value : fallback;
|
|
89
|
+
};
|
|
90
|
+
const base = fam('--dsw-font-markdown-base-font-family', '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif');
|
|
91
|
+
const code = fam('--dsw-font-markdown-code-font-family', '"SF Mono", Consolas, monospace');
|
|
92
|
+
const codeBlock = fam('--dsw-font-markdown-code-block-font-family', '"SF Mono", Consolas, monospace');
|
|
93
|
+
const parts = [];
|
|
94
|
+
const token = (shorthand, size, line, family) => {
|
|
95
|
+
parts.push(`--${shorthand}:${size}px/${line}px ${family}`);
|
|
96
|
+
parts.push(`--${shorthand}-font-size:${size}px`);
|
|
97
|
+
parts.push(`--${shorthand}-line-height:${line}px`);
|
|
98
|
+
};
|
|
99
|
+
token('dsw-font-markdown-base', fontSize, rel(28, fontSize), base);
|
|
100
|
+
token('dsw-font-markdown-base-strong', fontSize, rel(28, fontSize), base);
|
|
101
|
+
token('dsw-font-markdown-base-italic', fontSize, rel(28, fontSize), base);
|
|
102
|
+
token('dsw-font-markdown-base-strong-italic', fontSize, rel(28, fontSize), base);
|
|
103
|
+
token('dsw-font-markdown-h1', rel(24, fontSize), rel(34, fontSize), base);
|
|
104
|
+
token('dsw-font-markdown-h2', rel(22, fontSize), rel(32, fontSize), base);
|
|
105
|
+
token('dsw-font-markdown-h3', rel(20, fontSize), rel(30, fontSize), base);
|
|
106
|
+
token('dsw-font-markdown-h4', fontSize, rel(28, fontSize), base);
|
|
107
|
+
token('dsw-font-markdown-code', rel(14, fontSize), rel(22, fontSize), code);
|
|
108
|
+
token('dsw-font-markdown-code-block', rel(13, fontSize), rel(22, fontSize), codeBlock);
|
|
109
|
+
token('dsw-font-markdown-code-block-small', rel(12, fontSize), rel(18, fontSize), codeBlock);
|
|
110
|
+
return `body{${parts.join(';')}}`;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Claude Desktop-ish markdown table look: light-gray rounded cell cards with
|
|
114
|
+
* small gaps, no borders. Cells share the theme's inline-code background and
|
|
115
|
+
* follow the message font-size setting. Alignment is left to the markdown
|
|
116
|
+
* renderer, so headers and cells always match.
|
|
117
|
+
*/
|
|
118
|
+
const CLAUDE_TABLE_CSS = `
|
|
119
|
+
div[data-slot="conversation.chat.node"] table{
|
|
120
|
+
border-collapse:separate !important;
|
|
121
|
+
border-spacing:3px !important;
|
|
122
|
+
width:100% !important;
|
|
123
|
+
border:none !important;
|
|
124
|
+
font-size:var(--dsw-font-markdown-base-font-size) !important;
|
|
125
|
+
}
|
|
126
|
+
div[data-slot="conversation.chat.node"] table thead th{
|
|
127
|
+
background:var(--dsw-alias-markdown-inline-code) !important;
|
|
128
|
+
color:inherit !important;
|
|
129
|
+
font-weight:400 !important;
|
|
130
|
+
font-size:inherit !important;
|
|
131
|
+
padding:7px 10px !important;
|
|
132
|
+
border:none !important;
|
|
133
|
+
border-radius:6px !important;
|
|
134
|
+
}
|
|
135
|
+
div[data-slot="conversation.chat.node"] table tbody td{
|
|
136
|
+
background:var(--dsw-alias-markdown-inline-code) !important;
|
|
137
|
+
color:inherit !important;
|
|
138
|
+
font-size:inherit !important;
|
|
139
|
+
padding:7px 10px !important;
|
|
140
|
+
vertical-align:top !important;
|
|
141
|
+
border:none !important;
|
|
142
|
+
border-radius:6px !important;
|
|
143
|
+
}
|
|
144
|
+
div[data-slot="conversation.chat.node"] table code,
|
|
145
|
+
div[data-slot="conversation.chat.node"] table pre{
|
|
146
|
+
background:transparent !important;
|
|
147
|
+
border:none !important;
|
|
148
|
+
box-shadow:none !important;
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
function buildRuntimeCss(value) {
|
|
152
|
+
const rules = [];
|
|
153
|
+
rules.push(buildFontCss(value.fontSize));
|
|
154
|
+
// User-sent messages use their own fixed font-size (not the markdown tokens);
|
|
155
|
+
// route them through the same base so they follow the fontSize setting too.
|
|
156
|
+
// `steering` messages are sent while the agent is busy (busyEnter: steer);
|
|
157
|
+
// `[data-pending-steering]` is their in-flight bubble before it becomes durable.
|
|
158
|
+
rules.push(`[data-chat-flow-kind="user"] [class^="_text_"],[data-chat-flow-kind="steering"] [class^="_text_"],[data-pending-steering] [class^="_text_"]{font-size:var(--dsw-font-markdown-base-font-size) !important}`);
|
|
159
|
+
// Composer input follows the same base size. The visible text is rendered by
|
|
160
|
+
// the hidden-textarea + backdrop/mirror pattern: the textarea is transparent,
|
|
161
|
+
// the `data-input-backdrop` paints the text you see, and `data-input-mirror`
|
|
162
|
+
// drives auto-grow. All three (plus the placeholder) must share the size.
|
|
163
|
+
// Only font-size is touched: line-height is part of the auto-grow/caret
|
|
164
|
+
// metrics, so overriding it misplaces the caret.
|
|
165
|
+
rules.push(`[data-composer-card="true"] textarea,[data-composer-card="true"] [data-input-backdrop],[data-composer-card="true"] [data-input-mirror]{font-size:var(--dsw-font-markdown-base-font-size) !important}`);
|
|
166
|
+
rules.push(`[data-composer-card="true"] textarea::placeholder{font-size:var(--dsw-font-markdown-base-font-size) !important}`);
|
|
167
|
+
// Markdown table cells are pinned by DSH (15px); let every table style follow
|
|
168
|
+
// the fontSize setting as well.
|
|
169
|
+
rules.push(`div[data-slot="conversation.chat.node"] table th,div[data-slot="conversation.chat.node"] table td{font-size:var(--dsw-font-markdown-base-font-size) !important}`);
|
|
170
|
+
if (value.dialogWidth !== DEFAULT_DIALOG_WIDTH) {
|
|
171
|
+
const width = value.dialogWidth;
|
|
172
|
+
rules.push(`[data-chat-flow]{max-width:${width}px !important}`);
|
|
173
|
+
// The composer card carries the same column + 32px padding (748→780);
|
|
174
|
+
// widen it through its stable data attribute so the input bar matches.
|
|
175
|
+
rules.push(`[data-composer-card="true"]{max-width:${width + 32}px !important}`);
|
|
176
|
+
// The conversation stats line under the composer (conversation.composer.dock)
|
|
177
|
+
// keeps its own 748px column; widen it together with the dialog.
|
|
178
|
+
rules.push(`[data-slot="conversation.composer.dock"] > div{max-width:${width + 32}px !important}`);
|
|
179
|
+
rules.push(`:root{--dsh-composer-card-max-width:${width + 32}px}`);
|
|
180
|
+
}
|
|
181
|
+
if (value.tableStyle === 'claude') {
|
|
182
|
+
rules.push(CLAUDE_TABLE_CSS);
|
|
183
|
+
}
|
|
184
|
+
return rules.join('\n');
|
|
185
|
+
}
|
|
186
|
+
function runtimeStyleElement() {
|
|
187
|
+
const id = 'dsh-ui-tweaks-runtime';
|
|
188
|
+
let style = document.querySelector(`style[data-plugin-css="${id}"]`);
|
|
189
|
+
if (style === null) {
|
|
190
|
+
style = document.createElement('style');
|
|
191
|
+
style.dataset.plugin = 'dsh-ui-tweaks';
|
|
192
|
+
style.dataset.pluginCss = id;
|
|
193
|
+
document.head.appendChild(style);
|
|
194
|
+
}
|
|
195
|
+
return style;
|
|
196
|
+
}
|
|
197
|
+
const BASE_CSS = `
|
|
198
|
+
.dut-settings{display:grid;gap:14px;max-width:720px;padding:8px 2px 32px;color:var(--dsw-alias-label-primary)}
|
|
199
|
+
.dut-settings-header{padding:8px 2px}
|
|
200
|
+
.dut-settings-header h2{font-size:22px;letter-spacing:-.02em;margin:3px 0 6px}
|
|
201
|
+
.dut-settings-header p{max-width:620px;margin:0;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55}
|
|
202
|
+
.dut-panel{display:grid;gap:14px;padding:15px;border:1px solid var(--dsw-alias-border-l1);border-radius:14px;background:var(--dsw-alias-bg-layer-1);box-shadow:var(--dsw-shadow-lv1)}
|
|
203
|
+
.dut-field{display:grid;gap:7px}
|
|
204
|
+
.dut-field>span{font-size:13px;font-weight:600}
|
|
205
|
+
.dut-field small{font-size:11px;line-height:1.45;color:var(--dsw-alias-label-secondary)}
|
|
206
|
+
.dut-row{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
|
|
207
|
+
.dut-controls{display:flex;align-items:center;gap:8px}
|
|
208
|
+
.dut-input{box-sizing:border-box;height:32px;padding:0 10px;border-radius:8px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:inherit;font:inherit;font-size:13px;width:110px}
|
|
209
|
+
.dut-input:focus{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
|
|
210
|
+
.dut-select{box-sizing:border-box;height:32px;padding:0 8px;border-radius:8px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:inherit;font:inherit;font-size:13px}
|
|
211
|
+
.dut-btn{display:inline-flex;align-items:center;height:30px;padding:0 12px;border-radius:8px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:inherit;font:inherit;font-size:12px;cursor:pointer}
|
|
212
|
+
.dut-btn:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
213
|
+
.dut-btn:disabled{opacity:.45;cursor:default}
|
|
214
|
+
.dut-status{font-size:11px;color:var(--dsw-alias-state-success-primary)}
|
|
215
|
+
.dut-loading{padding:24px;border-radius:12px;background:var(--dsw-alias-bg-layer-2);font-size:12px;color:var(--dsw-alias-label-secondary)}
|
|
216
|
+
.dut-alert{padding:10px 12px;border-radius:10px;font-size:12px;line-height:1.5}
|
|
217
|
+
.dut-alert.warning{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 12%,transparent);color:var(--dsw-alias-state-warn-label)}
|
|
218
|
+
.dut-alert.error{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
|
|
219
|
+
`;
|
|
220
|
+
function installBaseStyles() {
|
|
221
|
+
const id = 'dsh-ui-tweaks-base';
|
|
222
|
+
const existing = document.querySelector(`style[data-plugin-css="${id}"]`);
|
|
223
|
+
if (existing !== null)
|
|
224
|
+
return () => { };
|
|
225
|
+
const style = document.createElement('style');
|
|
226
|
+
style.dataset.plugin = 'dsh-ui-tweaks';
|
|
227
|
+
style.dataset.pluginCss = id;
|
|
228
|
+
style.textContent = BASE_CSS;
|
|
229
|
+
document.head.appendChild(style);
|
|
230
|
+
return () => { style.remove(); };
|
|
231
|
+
}
|
|
232
|
+
async function apiRequest(init) {
|
|
233
|
+
const response = await fetch(SETTINGS_ROUTE, { credentials: 'same-origin', ...init });
|
|
234
|
+
const body = await response.json();
|
|
235
|
+
if (!response.ok || !body.ok) {
|
|
236
|
+
const failure = body;
|
|
237
|
+
throw new Error(failure.error?.message ?? `UI Tweaks request failed with HTTP ${response.status}`);
|
|
238
|
+
}
|
|
239
|
+
return body.value;
|
|
240
|
+
}
|
|
241
|
+
/** Small external store shared by the Settings route and the CSS engine. */
|
|
242
|
+
class SettingsClient {
|
|
243
|
+
state = { status: 'loading', writable: false, value: undefined, revision: undefined };
|
|
244
|
+
listeners = new Set();
|
|
245
|
+
generation = 0;
|
|
246
|
+
subscribe = (listener) => {
|
|
247
|
+
this.listeners.add(listener);
|
|
248
|
+
return () => { this.listeners.delete(listener); };
|
|
249
|
+
};
|
|
250
|
+
getSnapshot = () => this.state;
|
|
251
|
+
publish(next) {
|
|
252
|
+
this.state = next;
|
|
253
|
+
for (const listener of this.listeners)
|
|
254
|
+
listener();
|
|
255
|
+
}
|
|
256
|
+
async load() {
|
|
257
|
+
const generation = ++this.generation;
|
|
258
|
+
if (this.state.status === 'loading')
|
|
259
|
+
this.publish({ ...this.state, status: 'loading' });
|
|
260
|
+
try {
|
|
261
|
+
const snapshot = await apiRequest();
|
|
262
|
+
if (generation !== this.generation)
|
|
263
|
+
return;
|
|
264
|
+
this.publish({
|
|
265
|
+
status: 'ready',
|
|
266
|
+
writable: snapshot.writable,
|
|
267
|
+
value: snapshot.value,
|
|
268
|
+
revision: snapshot.revision,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
if (generation !== this.generation)
|
|
273
|
+
return;
|
|
274
|
+
this.publish({ ...this.state, status: 'error', error: error instanceof Error ? error.message : String(error) });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async post(payload) {
|
|
278
|
+
const generation = ++this.generation;
|
|
279
|
+
const snapshot = await apiRequest({
|
|
280
|
+
method: 'POST',
|
|
281
|
+
headers: { 'Content-Type': 'application/json' },
|
|
282
|
+
body: JSON.stringify(payload),
|
|
283
|
+
});
|
|
284
|
+
if (generation !== this.generation)
|
|
285
|
+
return;
|
|
286
|
+
this.publish({
|
|
287
|
+
status: 'ready',
|
|
288
|
+
writable: snapshot.writable,
|
|
289
|
+
value: snapshot.value,
|
|
290
|
+
revision: snapshot.revision,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
async set(field, value) {
|
|
294
|
+
await this.post({ action: 'set', field, value, expectedRevision: this.state.revision ?? 0 });
|
|
295
|
+
}
|
|
296
|
+
async unset(field) {
|
|
297
|
+
await this.post({ action: 'unset', field, expectedRevision: this.state.revision ?? 0 });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/** Required client services: slots (settings.section) and locale. */
|
|
301
|
+
exports.inject = ['slots', 'locale'];
|
|
302
|
+
function SettingsSection({ controller, t }) {
|
|
303
|
+
const state = (0, react_1.useSyncExternalStore)(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
|
|
304
|
+
const resolved = resolveValue(state.value);
|
|
305
|
+
const writable = state.writable;
|
|
306
|
+
const [draft, setDraft] = (0, react_1.useState)(String(resolved.fontSize));
|
|
307
|
+
const [widthDraft, setWidthDraft] = (0, react_1.useState)(String(resolved.dialogWidth));
|
|
308
|
+
const [status, setStatus] = (0, react_1.useState)(undefined);
|
|
309
|
+
(0, react_1.useEffect)(() => { if (state.status === 'loading' && state.value === undefined)
|
|
310
|
+
void controller.load(); }, [controller, state.status, state.value]);
|
|
311
|
+
(0, react_1.useEffect)(() => { setDraft(String(resolved.fontSize)); }, [resolved.fontSize]);
|
|
312
|
+
(0, react_1.useEffect)(() => { setWidthDraft(String(resolved.dialogWidth)); }, [resolved.dialogWidth]);
|
|
313
|
+
(0, react_1.useEffect)(() => {
|
|
314
|
+
if (status === undefined)
|
|
315
|
+
return;
|
|
316
|
+
const timer = setTimeout(() => { setStatus(undefined); }, 1800);
|
|
317
|
+
return () => { clearTimeout(timer); };
|
|
318
|
+
}, [status]);
|
|
319
|
+
const commitFontSize = (raw) => {
|
|
320
|
+
setDraft(raw);
|
|
321
|
+
const parsed = Number(raw);
|
|
322
|
+
if (!Number.isFinite(parsed))
|
|
323
|
+
return;
|
|
324
|
+
const clamped = Math.min(MAX_FONT_SIZE, Math.max(MIN_FONT_SIZE, Math.round(parsed)));
|
|
325
|
+
setDraft(String(clamped));
|
|
326
|
+
void controller.set('fontSize', clamped).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
|
|
327
|
+
};
|
|
328
|
+
const pickTableStyle = (raw) => {
|
|
329
|
+
void controller.set('tableStyle', raw === 'claude' ? 'claude' : 'default').then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
|
|
330
|
+
};
|
|
331
|
+
const commitDialogWidth = (raw) => {
|
|
332
|
+
setWidthDraft(raw);
|
|
333
|
+
const parsed = Number(raw);
|
|
334
|
+
if (!Number.isFinite(parsed))
|
|
335
|
+
return;
|
|
336
|
+
const clamped = Math.min(MAX_DIALOG_WIDTH, Math.max(MIN_DIALOG_WIDTH, Math.round(parsed)));
|
|
337
|
+
setWidthDraft(String(clamped));
|
|
338
|
+
void controller.set('dialogWidth', clamped).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
|
|
339
|
+
};
|
|
340
|
+
const reset = (field) => {
|
|
341
|
+
void controller.unset(field).then(() => { setStatus('resetDone'); }).catch(() => { setStatus('unavailable'); });
|
|
342
|
+
};
|
|
343
|
+
if (state.status === 'loading' && state.value === undefined) {
|
|
344
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "dut-settings", children: (0, jsx_runtime_1.jsx)("div", { className: "dut-loading", children: t('loading') }) });
|
|
345
|
+
}
|
|
346
|
+
if (state.status === 'error') {
|
|
347
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "dut-settings", children: (0, jsx_runtime_1.jsx)("div", { className: "dut-alert error", children: t('unavailable') }) });
|
|
348
|
+
}
|
|
349
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "dut-settings", children: [(0, jsx_runtime_1.jsxs)("header", { className: "dut-settings-header", children: [(0, jsx_runtime_1.jsx)("h2", { children: t('settingsTitle') }), (0, jsx_runtime_1.jsx)("p", { children: t('settingsIntro') })] }), !writable ? (0, jsx_runtime_1.jsx)("div", { className: "dut-alert warning", children: t('readOnly') }) : null, status === undefined ? null : (0, jsx_runtime_1.jsx)("div", { className: "dut-status", children: t(status) }), (0, jsx_runtime_1.jsx)("section", { className: "dut-panel", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field", children: [(0, jsx_runtime_1.jsx)("span", { children: t('fontSize') }), (0, jsx_runtime_1.jsxs)("div", { className: "dut-row", children: [(0, jsx_runtime_1.jsx)("small", { children: t('fontSizeHint') }), (0, jsx_runtime_1.jsxs)("div", { className: "dut-controls", children: [(0, jsx_runtime_1.jsx)("input", { className: "dut-input", type: "number", min: MIN_FONT_SIZE, max: MAX_FONT_SIZE, step: 1, value: draft, disabled: !writable, onChange: (event) => { setDraft(event.target.value); }, onBlur: (event) => { commitFontSize(event.target.value); }, onKeyDown: (event) => { if (event.key === 'Enter')
|
|
350
|
+
commitFontSize(event.target.value); } }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "dut-btn", disabled: !writable, onClick: () => { reset('fontSize'); }, children: t('reset') })] })] })] }) }), (0, jsx_runtime_1.jsx)("section", { className: "dut-panel", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field", children: [(0, jsx_runtime_1.jsx)("span", { children: t('tableStyle') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-row", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-controls", children: [(0, jsx_runtime_1.jsxs)("select", { className: "dut-select", value: resolved.tableStyle, disabled: !writable, onChange: (event) => { pickTableStyle(event.target.value); }, children: [(0, jsx_runtime_1.jsx)("option", { value: "default", children: t('tableStyleDefault') }), (0, jsx_runtime_1.jsx)("option", { value: "claude", children: t('tableStyleClaude') })] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "dut-btn", disabled: !writable, onClick: () => { reset('tableStyle'); }, children: t('reset') })] }) })] }) }), (0, jsx_runtime_1.jsx)("section", { className: "dut-panel", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field", children: [(0, jsx_runtime_1.jsx)("span", { children: t('dialogWidth') }), (0, jsx_runtime_1.jsxs)("div", { className: "dut-row", children: [(0, jsx_runtime_1.jsx)("small", { children: t('dialogWidthHint') }), (0, jsx_runtime_1.jsxs)("div", { className: "dut-controls", children: [(0, jsx_runtime_1.jsx)("input", { className: "dut-input", type: "number", min: MIN_DIALOG_WIDTH, max: MAX_DIALOG_WIDTH, step: 1, value: widthDraft, disabled: !writable, onChange: (event) => { setWidthDraft(event.target.value); }, onBlur: (event) => { commitDialogWidth(event.target.value); }, onKeyDown: (event) => { if (event.key === 'Enter')
|
|
351
|
+
commitDialogWidth(event.target.value); } }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "dut-btn", disabled: !writable, onClick: () => { reset('dialogWidth'); }, children: t('reset') })] })] })] }) })] }));
|
|
352
|
+
}
|
|
353
|
+
function apply(ctx) {
|
|
354
|
+
ctx.effect(installBaseStyles, 'dsh-ui-tweaks: base styles');
|
|
355
|
+
ctx.effect(() => ctx.locale.register(NS, { en, zh }), 'dsh-ui-tweaks: locale');
|
|
356
|
+
const t = ctx.locale.bind(NS);
|
|
357
|
+
const controller = new SettingsClient();
|
|
358
|
+
ctx.effect(() => {
|
|
359
|
+
const applyCss = () => {
|
|
360
|
+
const state = controller.getSnapshot();
|
|
361
|
+
if (state.status === 'ready') {
|
|
362
|
+
runtimeStyleElement().textContent = buildRuntimeCss(resolveValue(state.value));
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
applyCss();
|
|
366
|
+
const dispose = controller.subscribe(applyCss);
|
|
367
|
+
void controller.load();
|
|
368
|
+
return dispose;
|
|
369
|
+
}, 'dsh-ui-tweaks: runtime css');
|
|
370
|
+
ctx.slots.inject('settings.section', () => ctx.slots.register({
|
|
371
|
+
name: 'settings.section',
|
|
372
|
+
id: NS,
|
|
373
|
+
order: 40,
|
|
374
|
+
label: () => t('nav'),
|
|
375
|
+
inject: () => ({ controller, t }),
|
|
376
|
+
}, SettingsSection));
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
function __resolve(from, request) {
|
|
380
|
+
if (!request.startsWith(".")) return request;
|
|
381
|
+
var parts = from.slice(2).split("/"); parts.pop();
|
|
382
|
+
for (var part of request.split("/")) { if (part === "." || part === "") continue; if (part === "..") parts.pop(); else parts.push(part); }
|
|
383
|
+
return "./" + parts.join("/");
|
|
384
|
+
}
|
|
385
|
+
function __load(id) {
|
|
386
|
+
if (__modules[id] === undefined) return require(id);
|
|
387
|
+
if (__cache[id] !== undefined) return __cache[id].exports;
|
|
388
|
+
var module = __cache[id] = { exports: {} };
|
|
389
|
+
__modules[id](module, module.exports, require, function(request) { var resolved = __resolve(id, request); return __modules[resolved] === undefined ? require(request) : __load(resolved); });
|
|
390
|
+
return module.exports;
|
|
391
|
+
}
|
|
392
|
+
return __load("./index.js"); } });
|
|
393
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sections":[{"offset":{"line":3,"column":0},"map":{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client/index.tsx"],"names":[],"mappings":"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"}}]}
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ui-tweaks configuration: conversation font size (px), markdown table
|
|
3
|
+
* style, and dialog width. Every field defaults at the schema boundary, so a
|
|
4
|
+
* hand-edited settings document and the Settings panel stay consistent.
|
|
5
|
+
* @module dsh-ui-tweaks/config
|
|
6
|
+
*/
|
|
7
|
+
import z from '@deepseek-ai/schemastery';
|
|
8
|
+
import { settingsNamespace } from '@deepseek-ai/dsh-settings';
|
|
9
|
+
/** Settings document namespace owned by this plugin. */
|
|
10
|
+
export const UI_TWEAKS_SETTINGS_NAMESPACE = settingsNamespace('ui-tweaks');
|
|
11
|
+
export const MIN_DIALOG_WIDTH = 600;
|
|
12
|
+
export const MAX_DIALOG_WIDTH = 1600;
|
|
13
|
+
export const DEFAULT_DIALOG_WIDTH = 748;
|
|
14
|
+
export const MIN_FONT_SIZE = 10;
|
|
15
|
+
export const MAX_FONT_SIZE = 32;
|
|
16
|
+
export const DEFAULT_FONT_SIZE = 16;
|
|
17
|
+
/** Configuration schema with documented defaults. */
|
|
18
|
+
export const Config = z.object({
|
|
19
|
+
fontSize: z.number().min(10).max(32).default(16),
|
|
20
|
+
tableStyle: z.union(['default', 'claude']).default('default'),
|
|
21
|
+
dialogWidth: z.union([z.number().min(MIN_DIALOG_WIDTH).max(MAX_DIALOG_WIDTH), z.const('default'), z.const('wide')]).default(DEFAULT_DIALOG_WIDTH),
|
|
22
|
+
});
|
|
23
|
+
/** Normalize a dialog width value (legacy strings included) to px. */
|
|
24
|
+
export function resolveDialogWidth(value) {
|
|
25
|
+
if (value === 'wide')
|
|
26
|
+
return 880;
|
|
27
|
+
if (typeof value === 'number')
|
|
28
|
+
return value;
|
|
29
|
+
return DEFAULT_DIALOG_WIDTH;
|
|
30
|
+
}
|
|
31
|
+
/** Resolve a partial config into a fully defaulted value. */
|
|
32
|
+
export function resolveConfig(config = {}) {
|
|
33
|
+
const fontSize = config.fontSize ?? DEFAULT_FONT_SIZE;
|
|
34
|
+
const tableStyle = config.tableStyle ?? 'default';
|
|
35
|
+
const dialogWidth = resolveDialogWidth(config.dialogWidth);
|
|
36
|
+
return { fontSize, tableStyle, dialogWidth };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAExC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAE7D,wDAAwD;AACxD,MAAM,CAAC,MAAM,4BAA4B,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;AAe1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;AACnC,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAA;AACpC,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAEvC,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAA;AAC/B,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAA;AAC/B,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAEnC,qDAAqD;AACrD,MAAM,CAAC,MAAM,MAAM,GAA2B,CAAC,CAAC,MAAM,CAAC;IACrD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAChD,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAU,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IACtE,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC;CAClJ,CAAC,CAAA;AAUF,sEAAsE;AACtE,MAAM,UAAU,kBAAkB,CAAC,KAAgD;IACjF,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,GAAG,CAAA;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,OAAO,oBAAoB,CAAA;AAC7B,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,aAAa,CAAC,SAAyB,EAAE;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,iBAAiB,CAAA;IACrD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,SAAS,CAAA;IACjD,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAC1D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,CAAA;AAC9C,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ui-tweaks — server half.
|
|
3
|
+
*
|
|
4
|
+
* Registers the `ui-tweaks` settings namespace so users can tune the
|
|
5
|
+
* conversation UI either from the Settings panel or by editing the settings
|
|
6
|
+
* document directly (settings.yaml `ui-tweaks:` section). All rendering work
|
|
7
|
+
* happens in the browser bundle (`src/client`), which reads and writes this
|
|
8
|
+
* namespace through the same-origin route mounted here — the Web settings RPC
|
|
9
|
+
* only exposes a fixed allowlist of namespaces in rc.6, so a custom route is
|
|
10
|
+
* the supported way for a plugin to own a configuration page.
|
|
11
|
+
* @module dsh-ui-tweaks
|
|
12
|
+
*/
|
|
13
|
+
import { UI_TWEAKS_SETTINGS_NAMESPACE, Config, } from "./config.js";
|
|
14
|
+
import { UITweaksWebBackend, installUITweaksWeb } from "./web.js";
|
|
15
|
+
export const name = 'dsh-ui-tweaks';
|
|
16
|
+
/** Required services: the settings seam is the whole server-side surface. */
|
|
17
|
+
export const inject = ['settings'];
|
|
18
|
+
export function apply(ctx) {
|
|
19
|
+
ctx.settings.register(UI_TWEAKS_SETTINGS_NAMESPACE, Config, {
|
|
20
|
+
applies: 'live',
|
|
21
|
+
});
|
|
22
|
+
// The browser Settings panel talks to the namespace through this same-origin
|
|
23
|
+
// route (the Web settings RPC only exposes a fixed allowlist in rc.6).
|
|
24
|
+
installUITweaksWeb(ctx, new UITweaksWebBackend(ctx));
|
|
25
|
+
ctx.logger.info('[dsh-ui-tweaks] settings namespace registered and Web route mounted');
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,4BAA4B,EAC5B,MAAM,GACP,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAEjE,MAAM,CAAC,MAAM,IAAI,GAAG,eAAe,CAAA;AAEnC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,CAAA;AAElC,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,4BAA4B,EAAE,MAAM,EAAE;QAC1D,OAAO,EAAE,MAAM;KAChB,CAAC,CAAA;IAEF,6EAA6E;IAC7E,uEAAuE;IACvE,kBAAkB,CAAC,GAAG,EAAE,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAA;IAEpD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAA;AACxF,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ui-tweaks — browser half.
|
|
3
|
+
*
|
|
4
|
+
* Reads and writes the `ui-tweaks` settings namespace through the same-origin
|
|
5
|
+
* route served by the server half, applies the chosen font size / table style /
|
|
6
|
+
* dialog width live via a runtime `<style>` element, and renders the Settings
|
|
7
|
+
* panel section that edits them.
|
|
8
|
+
*/
|
|
9
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
10
|
+
declare const en: {
|
|
11
|
+
readonly nav: "UI Tweaks";
|
|
12
|
+
readonly settingsTitle: "UI Tweaks";
|
|
13
|
+
readonly settingsIntro: "Tune the conversation UI: message font size (px), markdown table style, and dialog width. Changes apply live.";
|
|
14
|
+
readonly fontSize: "Message font size (px)";
|
|
15
|
+
readonly fontSizeHint: "Number between 10 and 32; applies to message text, headings, tables and code.";
|
|
16
|
+
readonly tableStyle: "Table style";
|
|
17
|
+
readonly tableStyleDefault: "Default";
|
|
18
|
+
readonly tableStyleClaude: "Claude Desktop";
|
|
19
|
+
readonly dialogWidth: "Dialog width (px)";
|
|
20
|
+
readonly dialogWidthHint: "Number between 600 and 1600px; 748 is DSH's default column width, larger values widen it.";
|
|
21
|
+
readonly reset: "Reset";
|
|
22
|
+
readonly resetDone: "Reset to default.";
|
|
23
|
+
readonly applied: "Applied";
|
|
24
|
+
readonly unavailable: "Settings unavailable.";
|
|
25
|
+
readonly loading: "Loading…";
|
|
26
|
+
readonly readOnly: "The active Settings provider is read-only.";
|
|
27
|
+
readonly saved: "Saved.";
|
|
28
|
+
};
|
|
29
|
+
type LocaleKey = keyof typeof en;
|
|
30
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
31
|
+
interface LocaleNamespaceMap {
|
|
32
|
+
/** dsh-ui-tweaks Settings copy. */
|
|
33
|
+
'ui-tweaks': LocaleKey;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Required client services: slots (settings.section) and locale. */
|
|
37
|
+
export declare const inject: string[];
|
|
38
|
+
export declare function apply(ctx: ClientContext): void;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAwC3E,QAAA,MAAM,EAAE;;;;;;;;;;;;;;;;;;CAkBE,CAAA;AAEV,KAAK,SAAS,GAAG,MAAM,OAAO,EAAE,CAAA;AAwBhC,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,mCAAmC;QACnC,WAAW,EAAE,SAAS,CAAA;KACvB;CACF;AAgQD,qEAAqE;AACrE,eAAO,MAAM,MAAM,UAAsB,CAAA;AAoIzC,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA2B9C"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ui-tweaks configuration: conversation font size (px), markdown table
|
|
3
|
+
* style, and dialog width. Every field defaults at the schema boundary, so a
|
|
4
|
+
* hand-edited settings document and the Settings panel stay consistent.
|
|
5
|
+
* @module dsh-ui-tweaks/config
|
|
6
|
+
*/
|
|
7
|
+
import type Schema from '@deepseek-ai/schemastery';
|
|
8
|
+
/** Settings document namespace owned by this plugin. */
|
|
9
|
+
export declare const UI_TWEAKS_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
|
|
10
|
+
/** Raw user-facing configuration (partial inputs receive schema defaults). */
|
|
11
|
+
export interface UITweaksConfig {
|
|
12
|
+
/** Message content font size in px. */
|
|
13
|
+
fontSize?: number;
|
|
14
|
+
/** Markdown table presentation style. */
|
|
15
|
+
tableStyle?: 'default' | 'claude';
|
|
16
|
+
/**
|
|
17
|
+
* Conversation column width in px. Legacy preset strings are still
|
|
18
|
+
* accepted: `'default'` = 748, `'wide'` = 880.
|
|
19
|
+
*/
|
|
20
|
+
dialogWidth?: number | 'default' | 'wide';
|
|
21
|
+
}
|
|
22
|
+
export declare const MIN_DIALOG_WIDTH = 600;
|
|
23
|
+
export declare const MAX_DIALOG_WIDTH = 1600;
|
|
24
|
+
export declare const DEFAULT_DIALOG_WIDTH = 748;
|
|
25
|
+
export declare const MIN_FONT_SIZE = 10;
|
|
26
|
+
export declare const MAX_FONT_SIZE = 32;
|
|
27
|
+
export declare const DEFAULT_FONT_SIZE = 16;
|
|
28
|
+
/** Configuration schema with documented defaults. */
|
|
29
|
+
export declare const Config: Schema<UITweaksConfig>;
|
|
30
|
+
/** Configuration after static validation, with every default materialized. */
|
|
31
|
+
export interface ResolvedUITweaksConfig {
|
|
32
|
+
fontSize: number;
|
|
33
|
+
tableStyle: 'default' | 'claude';
|
|
34
|
+
/** Dialog width in px (748 = the stock DSH column). */
|
|
35
|
+
dialogWidth: number;
|
|
36
|
+
}
|
|
37
|
+
/** Normalize a dialog width value (legacy strings included) to px. */
|
|
38
|
+
export declare function resolveDialogWidth(value: UITweaksConfig['dialogWidth'] | undefined): number;
|
|
39
|
+
/** Resolve a partial config into a fully defaulted value. */
|
|
40
|
+
export declare function resolveConfig(config?: UITweaksConfig): ResolvedUITweaksConfig;
|
|
41
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAA;AAGlD,wDAAwD;AACxD,eAAO,MAAM,4BAA4B,uDAAiC,CAAA;AAE1E,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yCAAyC;IACzC,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;IACjC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAA;CAC1C;AAED,eAAO,MAAM,gBAAgB,MAAM,CAAA;AACnC,eAAO,MAAM,gBAAgB,OAAO,CAAA;AACpC,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAEvC,eAAO,MAAM,aAAa,KAAK,CAAA;AAC/B,eAAO,MAAM,aAAa,KAAK,CAAA;AAC/B,eAAO,MAAM,iBAAiB,KAAK,CAAA;AAEnC,qDAAqD;AACrD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,cAAc,CAIxC,CAAA;AAEF,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,SAAS,GAAG,QAAQ,CAAA;IAChC,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC,aAAa,CAAC,GAAG,SAAS,GAAG,MAAM,CAI3F;AAED,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,MAAM,GAAE,cAAmB,GAAG,sBAAsB,CAKjF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ui-tweaks — server half.
|
|
3
|
+
*
|
|
4
|
+
* Registers the `ui-tweaks` settings namespace so users can tune the
|
|
5
|
+
* conversation UI either from the Settings panel or by editing the settings
|
|
6
|
+
* document directly (settings.yaml `ui-tweaks:` section). All rendering work
|
|
7
|
+
* happens in the browser bundle (`src/client`), which reads and writes this
|
|
8
|
+
* namespace through the same-origin route mounted here — the Web settings RPC
|
|
9
|
+
* only exposes a fixed allowlist of namespaces in rc.6, so a custom route is
|
|
10
|
+
* the supported way for a plugin to own a configuration page.
|
|
11
|
+
* @module dsh-ui-tweaks
|
|
12
|
+
*/
|
|
13
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
14
|
+
export declare const name = "dsh-ui-tweaks";
|
|
15
|
+
/** Required services: the settings seam is the whole server-side surface. */
|
|
16
|
+
export declare const inject: string[];
|
|
17
|
+
export declare function apply(ctx: Context): void;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOlD,eAAO,MAAM,IAAI,kBAAkB,CAAA;AAEnC,6EAA6E;AAC7E,eAAO,MAAM,MAAM,UAAe,CAAA;AAElC,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAUxC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ui-tweaks — optional Web routes.
|
|
3
|
+
*
|
|
4
|
+
* The browser Settings panel reads and writes the `ui-tweaks` namespace through
|
|
5
|
+
* this same-origin route, because the Web settings RPC only exposes a fixed
|
|
6
|
+
* allowlist of namespaces (hardcoded in dsh-host-apiproxy in rc.6). The route
|
|
7
|
+
* proxies to the real `ctx.settings` service, so the settings document
|
|
8
|
+
* (settings.yaml) stays the single source of truth and hand edits keep working.
|
|
9
|
+
* @module dsh-ui-tweaks/web
|
|
10
|
+
*/
|
|
11
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
+
/** Exact route used by the browser Settings page. */
|
|
14
|
+
export declare const SETTINGS_ROUTE = "/_dsh/ui-tweaks/settings";
|
|
15
|
+
/** Public Settings snapshot; no secrets exist in this namespace. */
|
|
16
|
+
export interface UITweaksSnapshot {
|
|
17
|
+
writable: boolean;
|
|
18
|
+
value: unknown;
|
|
19
|
+
revision: number;
|
|
20
|
+
}
|
|
21
|
+
/** Accept state-changing requests only from the DSH Web application's origin. */
|
|
22
|
+
export declare function sameOriginPost(req: IncomingMessage): boolean;
|
|
23
|
+
/** Same-origin Settings read/write handler. */
|
|
24
|
+
export declare class UITweaksWebBackend {
|
|
25
|
+
private readonly ctx;
|
|
26
|
+
constructor(ctx: Context);
|
|
27
|
+
private descriptor;
|
|
28
|
+
private snapshot;
|
|
29
|
+
/** Handle the exact Settings route. */
|
|
30
|
+
handle(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Attach the Settings route whenever a webServer service is present.
|
|
34
|
+
* @param ctx - plugin context owning route effects.
|
|
35
|
+
* @param backend - Settings handler.
|
|
36
|
+
*/
|
|
37
|
+
export declare function installUITweaksWeb(ctx: Context, backend: UITweaksWebBackend): void;
|
|
38
|
+
//# sourceMappingURL=web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,qDAAqD;AACrD,eAAO,MAAM,cAAc,6BAA6B,CAAA;AAExD,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAqBD,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAa5D;AAwDD,+CAA+C;AAC/C,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,OAAO;IAEzC,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,QAAQ;IAShB,uCAAuC;IACjC,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CA2CvE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAUlF"}
|
package/lib/web.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ui-tweaks — optional Web routes.
|
|
3
|
+
*
|
|
4
|
+
* The browser Settings panel reads and writes the `ui-tweaks` namespace through
|
|
5
|
+
* this same-origin route, because the Web settings RPC only exposes a fixed
|
|
6
|
+
* allowlist of namespaces (hardcoded in dsh-host-apiproxy in rc.6). The route
|
|
7
|
+
* proxies to the real `ctx.settings` service, so the settings document
|
|
8
|
+
* (settings.yaml) stays the single source of truth and hand edits keep working.
|
|
9
|
+
* @module dsh-ui-tweaks/web
|
|
10
|
+
*/
|
|
11
|
+
import { SettingsConflictError } from '@deepseek-ai/dsh-settings';
|
|
12
|
+
import { UI_TWEAKS_SETTINGS_NAMESPACE } from "./config.js";
|
|
13
|
+
/** Exact route used by the browser Settings page. */
|
|
14
|
+
export const SETTINGS_ROUTE = '/_dsh/ui-tweaks/settings';
|
|
15
|
+
/** Accept state-changing requests only from the DSH Web application's origin. */
|
|
16
|
+
export function sameOriginPost(req) {
|
|
17
|
+
const fetchSite = req.headers['sec-fetch-site'];
|
|
18
|
+
if (fetchSite === 'cross-site')
|
|
19
|
+
return false;
|
|
20
|
+
const origin = req.headers.origin;
|
|
21
|
+
if (origin === undefined)
|
|
22
|
+
return fetchSite === 'same-origin' || fetchSite === 'same-site' || fetchSite === 'none';
|
|
23
|
+
const host = req.headers.host;
|
|
24
|
+
if (host === undefined)
|
|
25
|
+
return false;
|
|
26
|
+
try {
|
|
27
|
+
const parsed = new URL(origin);
|
|
28
|
+
return (parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.host === host;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function isRecord(value) {
|
|
35
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
36
|
+
}
|
|
37
|
+
function json(res, status, body) {
|
|
38
|
+
const bytes = Buffer.from(JSON.stringify(body));
|
|
39
|
+
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
40
|
+
res.setHeader('Content-Length', String(bytes.length));
|
|
41
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
42
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
43
|
+
res.writeHead(status);
|
|
44
|
+
res.end(bytes);
|
|
45
|
+
}
|
|
46
|
+
function requestError(res, status, code, message) {
|
|
47
|
+
json(res, status, { ok: false, error: { code, message } });
|
|
48
|
+
}
|
|
49
|
+
async function readJson(req, maxBytes = 16 * 1024) {
|
|
50
|
+
const contentType = req.headers['content-type']?.split(';', 1)[0]?.trim().toLowerCase();
|
|
51
|
+
if (contentType !== 'application/json')
|
|
52
|
+
throw new TypeError('Content-Type must be application/json');
|
|
53
|
+
const chunks = [];
|
|
54
|
+
let bytes = 0;
|
|
55
|
+
for await (const chunk of req) {
|
|
56
|
+
const part = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
57
|
+
bytes += part.length;
|
|
58
|
+
if (bytes > maxBytes)
|
|
59
|
+
throw new RangeError(`request body exceeds ${maxBytes} bytes`);
|
|
60
|
+
chunks.push(part);
|
|
61
|
+
}
|
|
62
|
+
if (chunks.length === 0)
|
|
63
|
+
throw new TypeError('request body is empty');
|
|
64
|
+
return JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
65
|
+
}
|
|
66
|
+
function parseRequest(value) {
|
|
67
|
+
if (!isRecord(value) || typeof value.action !== 'string')
|
|
68
|
+
throw new TypeError('action is required');
|
|
69
|
+
if (typeof value.expectedRevision !== 'number' || !Number.isSafeInteger(value.expectedRevision) || value.expectedRevision < 0) {
|
|
70
|
+
throw new TypeError('expectedRevision must be a non-negative integer');
|
|
71
|
+
}
|
|
72
|
+
const field = value.field;
|
|
73
|
+
if (typeof field !== 'string' || field.length === 0)
|
|
74
|
+
throw new TypeError('field must be a non-empty string');
|
|
75
|
+
if (value.action === 'unset') {
|
|
76
|
+
return { action: 'unset', field, expectedRevision: value.expectedRevision };
|
|
77
|
+
}
|
|
78
|
+
if (value.action === 'set') {
|
|
79
|
+
return { action: 'set', field, value: value.value, expectedRevision: value.expectedRevision };
|
|
80
|
+
}
|
|
81
|
+
throw new TypeError(`unsupported action: ${value.action}`);
|
|
82
|
+
}
|
|
83
|
+
function messageOf(error) {
|
|
84
|
+
if (error instanceof Error)
|
|
85
|
+
return error.message;
|
|
86
|
+
return String(error);
|
|
87
|
+
}
|
|
88
|
+
/** Same-origin Settings read/write handler. */
|
|
89
|
+
export class UITweaksWebBackend {
|
|
90
|
+
ctx;
|
|
91
|
+
constructor(ctx) {
|
|
92
|
+
this.ctx = ctx;
|
|
93
|
+
}
|
|
94
|
+
descriptor() {
|
|
95
|
+
const row = this.ctx.settings.describe().find(candidate => candidate.ns === UI_TWEAKS_SETTINGS_NAMESPACE);
|
|
96
|
+
if (row === undefined)
|
|
97
|
+
throw new Error('ui-tweaks settings namespace is not registered');
|
|
98
|
+
return row;
|
|
99
|
+
}
|
|
100
|
+
snapshot() {
|
|
101
|
+
const descriptor = this.descriptor();
|
|
102
|
+
return {
|
|
103
|
+
writable: this.ctx.settings.writable,
|
|
104
|
+
value: descriptor.value,
|
|
105
|
+
revision: descriptor.revision,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/** Handle the exact Settings route. */
|
|
109
|
+
async handle(req, res) {
|
|
110
|
+
if (req.method === 'GET') {
|
|
111
|
+
try {
|
|
112
|
+
json(res, 200, { ok: true, value: this.snapshot() });
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
this.ctx.logger.warn('dsh-ui-tweaks Settings snapshot failed: %s', messageOf(error));
|
|
116
|
+
requestError(res, 503, 'settings-unavailable', 'UI Tweaks settings are unavailable');
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (req.method !== 'POST') {
|
|
121
|
+
res.setHeader('Allow', 'GET, POST');
|
|
122
|
+
requestError(res, 405, 'method-not-allowed', 'Use GET or POST');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!sameOriginPost(req)) {
|
|
126
|
+
requestError(res, 403, 'origin-rejected', 'The request must originate from this DSH Web application');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
let parsed;
|
|
130
|
+
try {
|
|
131
|
+
parsed = parseRequest(await readJson(req));
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
requestError(res, error instanceof RangeError ? 413 : 400, 'invalid-request', messageOf(error));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
if (parsed.action === 'set') {
|
|
139
|
+
await this.ctx.settings.update(UI_TWEAKS_SETTINGS_NAMESPACE, { [parsed.field]: parsed.value }, parsed.expectedRevision);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
await this.ctx.settings.mutate(UI_TWEAKS_SETTINGS_NAMESPACE, [{ op: 'unset', path: [parsed.field] }], parsed.expectedRevision);
|
|
143
|
+
}
|
|
144
|
+
json(res, 200, { ok: true, value: this.snapshot() });
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
const conflict = error instanceof SettingsConflictError;
|
|
148
|
+
requestError(res, conflict ? 409 : 400, conflict ? 'settings-conflict' : 'settings-rejected', messageOf(error));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Attach the Settings route whenever a webServer service is present.
|
|
154
|
+
* @param ctx - plugin context owning route effects.
|
|
155
|
+
* @param backend - Settings handler.
|
|
156
|
+
*/
|
|
157
|
+
export function installUITweaksWeb(ctx, backend) {
|
|
158
|
+
ctx.inject(['webServer'], (webCtx) => {
|
|
159
|
+
webCtx.effect(() => {
|
|
160
|
+
return webCtx.webServer.register({
|
|
161
|
+
kind: 'exact',
|
|
162
|
+
path: SETTINGS_ROUTE,
|
|
163
|
+
handler: (req, res) => backend.handle(req, res),
|
|
164
|
+
});
|
|
165
|
+
}, 'dsh-ui-tweaks: Web routes');
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=web.js.map
|
package/lib/web.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-ui-tweaks",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "DSH web plugin: live-tune the conversation UI — message font size (px input), markdown table style (Claude Desktop look), and dialog width (default / wide) — from the Settings panel.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"dsh",
|
|
7
|
+
"deepseek-harness",
|
|
8
|
+
"deepseek",
|
|
9
|
+
"deepseek-ai",
|
|
10
|
+
"cordis",
|
|
11
|
+
"plugin",
|
|
12
|
+
"ui-tweaks",
|
|
13
|
+
"chat-ui"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/wlj521/dsh-ui-tweaks"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"main": "lib/index.js",
|
|
24
|
+
"types": "lib/types/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./lib/types/index.d.ts",
|
|
28
|
+
"default": "./lib/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./client": {
|
|
31
|
+
"types": "./lib/types/client/index.d.ts",
|
|
32
|
+
"default": "./lib/client.js"
|
|
33
|
+
},
|
|
34
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"lib",
|
|
39
|
+
"cordis.patch.yml",
|
|
40
|
+
"README.md",
|
|
41
|
+
"README.en.md",
|
|
42
|
+
"LICENSE"
|
|
43
|
+
],
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -p tsconfig.json && tsc -p tsconfig.client.json && node scripts/build-client.mjs",
|
|
49
|
+
"prepublishOnly": "pnpm build",
|
|
50
|
+
"prepare": "tsc -p tsconfig.json && tsc -p tsconfig.client.json && node scripts/build-client.mjs",
|
|
51
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.public.json",
|
|
52
|
+
"watch": "node scripts/watch-client.mjs"
|
|
53
|
+
},
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"dsh": {
|
|
56
|
+
"bundle": {
|
|
57
|
+
"patch": "./cordis.patch.yml"
|
|
58
|
+
},
|
|
59
|
+
"client": {
|
|
60
|
+
"inject": [
|
|
61
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
62
|
+
"@deepseek-ai/dsh-client-locale",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-slots",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-settings"
|
|
65
|
+
],
|
|
66
|
+
"platform": "web"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
71
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
|
|
72
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
75
|
+
"@deepseek-ai/dsh-settings": "^0.1.0-rc.6",
|
|
76
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
|
|
77
|
+
"@deepseek-ai/schemastery": "^3.18.0",
|
|
78
|
+
"react": "^18.2.0"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"cordis": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"devDependencies": {
|
|
86
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
87
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
|
|
88
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
89
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
|
|
90
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
91
|
+
"@deepseek-ai/dsh-settings": "^0.1.0-rc.6",
|
|
92
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
|
|
93
|
+
"@deepseek-ai/schemastery": "^3.18.0",
|
|
94
|
+
"@types/node": "^24.0.0",
|
|
95
|
+
"@types/react": "~18.3.1",
|
|
96
|
+
"@types/react-dom": "~18.3.1",
|
|
97
|
+
"react": "^18.2.0",
|
|
98
|
+
"react-dom": "^18.2.0",
|
|
99
|
+
"typescript": "^5.7.0"
|
|
100
|
+
}
|
|
101
|
+
}
|