@wjmmyz/dsh-plugin-hide-ui 0.0.0-stage → 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wjmmyz
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.md CHANGED
@@ -1,3 +1,73 @@
1
- # Temporary Holding Version
1
+ # @wjmmyz/dsh-plugin-hide-ui
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ English | [中文](README.zh.md)
4
+
5
+ A DeepSeek Harness bundle that removes two kinds of clutter from the Web GUI:
6
+
7
+ - the **Plugins** entry in the left sidebar's global panel list;
8
+ - the **built-in agent presets** (Standard mode, PTC mode, Minimal mode, Creator
9
+ mode) from the new-session preset chip, the Settings → Agent presets section,
10
+ and the session header label.
11
+
12
+ Custom presets you add yourself stay visible. Sessions that already run a
13
+ built-in preset keep running it — the plugin filters what the pickers offer, it
14
+ does not remove declarations from the Host.
15
+
16
+ ## What it changes
17
+
18
+ | Surface | Effect |
19
+ |---|---|
20
+ | Left sidebar → global panel rows | The Plugins row is gone. The other panel rows, the Workspaces/Sessions browser, New Session and Settings are untouched. |
21
+ | New-session preset chip | Lists only presets that are not built-in. Hidden when no custom preset is left. |
22
+ | Settings → Agent presets | The Built-in group disappears; the Custom group and its Creator entry are unchanged. |
23
+ | Session header preset label | Stops rendering when the session runs a built-in preset. |
24
+
25
+ The Plugins page itself is not disabled. Any other entry point continues to
26
+ work, and you can still reach it — for example the More menu lists only
27
+ unpinnable panels, so with this bundle installed the sidebar simply has no
28
+ Plugins row.
29
+
30
+ ## Why these two mechanisms
31
+
32
+ The Plugins row is the one panel row the sidebar pins unconditionally: it never
33
+ enters the More menu's pin list, so it cannot be unpinned from the UI. This
34
+ bundle registers its own occupant into the same `sidebar.panellist` cell, which
35
+ replaces that row's icon renderer with one that draws nothing.
36
+
37
+ The preset roster is served to the browser by `remote.agentPresets.list()`.
38
+ Every preset surface reads it through one shared helper, so wrapping that method
39
+ while the plugin is enabled hides the built-in entries everywhere at once,
40
+ without a reload and without touching the Host's declarations.
41
+
42
+ ## Install
43
+
44
+ Install the bundle into your DSH profile, then enable it:
45
+
46
+ ```sh
47
+ dsh plugin install @wjmmyz/dsh-plugin-hide-ui
48
+ ```
49
+
50
+ Or, in the Web GUI, open **Plugins** → **Add plugin** and give the package name
51
+ or a local directory. Restart the app once so the browser bundle is loaded, then
52
+ open a new session.
53
+
54
+ ## Disable
55
+
56
+ Turn the bundle off in **Plugins**, or remove it. Both hiding rules are
57
+ registered as plugin effects, so disabling restores the shipped behavior; no
58
+ Host restart and no clearing of stored state is needed.
59
+
60
+ ## Limitations
61
+
62
+ - The sidebar rule is keyed to the shipped panel id `plugins`. If a future DSH
63
+ release renames that panel, the row reappears until this bundle is updated.
64
+ - A preset counts as built-in when its id is `standard`, `ptc`, `minimal` or
65
+ `cordis` **and** the declaration publishes no name. That is how the shipped
66
+ packages mark their own presets; a user declaration that reuses one of those
67
+ ids and names itself is treated as custom and stays visible.
68
+ - The plugin only affects the browser UI. `dsh --dump-config`, the CLI, and
69
+ sessions started by other means are unaffected.
70
+
71
+ ## License
72
+
73
+ MIT
package/README.zh.md ADDED
@@ -0,0 +1,63 @@
1
+ # @wjmmyz/dsh-plugin-hide-ui
2
+
3
+ [English](README.md) | 中文
4
+
5
+ 一个 DeepSeek Harness 插件包(bundle),用来清掉 Web 界面上的两类干扰项:
6
+
7
+ - 左侧边栏全局面板列表里的 **插件(Plugins)** 入口;
8
+ - **内置 Agent 预设**(标准模式、PTC 模式、最小模式、创作者模式):新会话的预设
9
+ 选择器、设置里的「Agent 预设」页面,以及会话标题旁的预设标签都不再显示它们。
10
+
11
+ 你自己添加的自定义预设仍然可见。已经在运行内置预设的会话不受影响——插件只过滤
12
+ 选择器显示的内容,不会从 Host 里删除预设声明。
13
+
14
+ ## 改变了什么
15
+
16
+ | 位置 | 效果 |
17
+ |---|---|
18
+ | 左侧边栏 → 全局面板行 | 插件行消失。其他面板行、工作区/会话列表、新建会话、设置都不变。 |
19
+ | 新会话预设选择器 | 只列出非内置预设;没有自定义预设时整个控件不显示。 |
20
+ | 设置 → Agent 预设 | 「内置」分组消失;「自定义」分组及其创作者入口不变。 |
21
+ | 会话标题旁的预设标签 | 会话运行内置预设时不再渲染。 |
22
+
23
+ 插件页面本身没有禁用,其他入口仍可打开它。只是安装了本插件后,侧边栏里不会有
24
+ 插件这一行。
25
+
26
+ ## 为什么用这两个机制
27
+
28
+ 插件行是侧边栏唯一强制固定、不进「更多」菜单的可固定列表的面板行,所以无法通过
29
+ 界面取消固定。本插件往同一个 `sidebar.panellist` 单元格注册自己的占用者,用一个
30
+ 什么都不画的组件替换掉那一行的图标渲染。
31
+
32
+ 预设名单由 Host 通过 `remote.agentPresets.list()` 提供给浏览器,所有预设界面都
33
+ 通过同一个共享函数读取它。因此在插件启用期间包装这个方法,就能一次性在所有界面
34
+ 隐藏内置条目,既不用刷新,也不会改动 Host 的预设声明。
35
+
36
+ ## 安装
37
+
38
+ 把插件包装进 DSH profile 后启用:
39
+
40
+ ```sh
41
+ dsh plugin install @wjmmyz/dsh-plugin-hide-ui
42
+ ```
43
+
44
+ 或者在 Web 界面打开 **插件** → **添加插件**,填入包名或本地目录。重启一次应用以
45
+ 加载浏览器端资源,然后新建会话查看效果。
46
+
47
+ ## 关闭
48
+
49
+ 在 **插件** 页面关掉开关或卸载即可。两条隐藏规则都注册为插件副作用,关闭后立即
50
+ 恢复原生行为,不需要重启 Host,也不残留状态。
51
+
52
+ ## 已知限制
53
+
54
+ - 侧边栏这条规则绑定的是内置面板 id `plugins`。如果未来的 DSH 版本给这个面板改了
55
+ 名字,该行会重新出现,需要更新本插件。
56
+ - 判定「内置预设」的条件是:id 为 `standard`、`ptc`、`minimal` 或 `cordis`,并且
57
+ 该声明没有自带 name。这正是内置预设的标记方式;用户自己声明、复用了这些 id 但
58
+ 写了自己 name 的预设会被当作自定义预设保留。
59
+ - 插件只影响浏览器界面。`dsh --dump-config`、命令行以及其他方式启动的会话不受影响。
60
+
61
+ ## 许可
62
+
63
+ MIT
package/client.js ADDED
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Hide UI — browser half.
3
+ *
4
+ * Two independent hiding rules, each owned by a different shipped surface:
5
+ *
6
+ * 1. The **Plugins** row of the left sidebar. Its row list is derived from the
7
+ * `sidebar.panellist` slot, and the sidebar deliberately keeps that one
8
+ * panel fixed: `FIXED_PANEL_ID` bypasses the unpin list and the More menu,
9
+ * so no UI path removes it. We register into the same `sidebar.panellist`
10
+ * cell (a re-registration wins the cell), render a marker instead of an
11
+ * icon, and carry one scoped style rule that collapses the row that
12
+ * contains the marker. The rule lives inside our own component, so React
13
+ * removes it with the row and nothing leaks into the page.
14
+ *
15
+ * 2. The **built-in agent presets** of the new-session chip, the session
16
+ * header label and Settings → Agent presets. All three read one roster from
17
+ * the Host through `remote.agentPresets.list`; wrapping that method for our
18
+ * lifetime hides the built-in entries everywhere at once, without touching
19
+ * the Host's declarations, so sessions already running a built-in preset
20
+ * keep working.
21
+ */
22
+ window.__ModuleLoader__.load({
23
+ id: '@wjmmyz/dsh-plugin-hide-ui',
24
+ factory(require) {
25
+ const React = require('react')
26
+ const h = React.createElement
27
+
28
+ /**
29
+ * Built-in presets shipped by the DSH deployment. A roster row counts as
30
+ * built-in when its id matches AND it published no name — exactly how the
31
+ * shipped packages mark their own presets. A user declaration that reuses
32
+ * one of these ids and names itself is custom and stays visible.
33
+ */
34
+ const BUILT_IN_PRESETS = new Set(['standard', 'ptc', 'minimal', 'cordis'])
35
+
36
+ /** Marks the panel row this plugin hides; the rule below keys on it. */
37
+ const ROW_MARK = 'data-hide-ui-panel-row'
38
+
39
+ /**
40
+ * Collapses the sidebar row that contains our marker.
41
+ *
42
+ * The sidebar renders each panel as `div > button > span(icon)`, and our
43
+ * marker replaces the icon, so the row is the only `div` with a direct
44
+ * `button` child that carries the marker. Anchoring on our own node keeps
45
+ * the rule independent of generated class names and of the row's label.
46
+ */
47
+ const ROW_STYLE = `div:has(> button [${ROW_MARK}]){display:none !important}`
48
+
49
+ /**
50
+ * The hidden Plugins cell: draws no icon and carries the rule above.
51
+ * @returns the marker element plus its scoped style.
52
+ */
53
+ function HiddenPanelIcon() {
54
+ return h(React.Fragment, null,
55
+ h('span', { [ROW_MARK]: '', hidden: true }),
56
+ h('style', null, ROW_STYLE))
57
+ }
58
+
59
+ /** Restores one replaced descriptor; used for every patch we install. */
60
+ const restorers = new WeakMap()
61
+
62
+ /**
63
+ * Wrap `remote.agentPresets.list` so callers receive the roster without the
64
+ * built-in presets.
65
+ *
66
+ * `list` is an own accessor property of the namespace service (the gateway
67
+ * installs one getter per Remote method), so the wrapper replaces that
68
+ * descriptor instead of assigning: a plain assignment would hit a
69
+ * getter-only property. The original descriptor is kept and put back on
70
+ * disposal, which restores the shipped method exactly.
71
+ * @param remote - the Client `ctx.remote` service.
72
+ * @returns a disposer restoring the replaced descriptor.
73
+ */
74
+ function filterAgentPresets(remote) {
75
+ const namespace = remote?.agentPresets
76
+ if (namespace === undefined) return () => {}
77
+ if (restorers.has(namespace)) return restorers.get(namespace)
78
+ const descriptor = Object.getOwnPropertyDescriptor(namespace, 'list')
79
+ if (descriptor === undefined || typeof descriptor.get !== 'function') return () => {}
80
+
81
+ const original = (...args) => descriptor.get.call(namespace)(...args)
82
+ const wrapped = async (...args) => {
83
+ const result = await original(...args)
84
+ if (result === null || typeof result !== 'object' || result.ok !== true) return result
85
+ const value = result.value
86
+ if (value === null || typeof value !== 'object' || !Array.isArray(value.presets)) return result
87
+ const presets = value.presets.filter((row) => {
88
+ if (typeof row?.id !== 'string' || !BUILT_IN_PRESETS.has(row.id)) return true
89
+ return row.name !== undefined
90
+ })
91
+ if (presets.length === value.presets.length) return result
92
+ return { ...result, value: { ...value, presets } }
93
+ }
94
+
95
+ const dispose = () => {
96
+ restorers.delete(namespace)
97
+ if (Object.getOwnPropertyDescriptor(namespace, 'list') !== undefined) {
98
+ Object.defineProperty(namespace, 'list', descriptor)
99
+ }
100
+ }
101
+ restorers.set(namespace, dispose)
102
+ Object.defineProperty(namespace, 'list', {
103
+ configurable: true, enumerable: true, writable: true, value: wrapped,
104
+ })
105
+ return dispose
106
+ }
107
+
108
+ return {
109
+ inject: ['slots', 'remote'],
110
+ apply(ctx) {
111
+ ctx.effect(() => ctx.slots.inject('sidebar.panellist', () => ctx.slots.register({
112
+ name: 'sidebar.panellist',
113
+ id: 'plugins',
114
+ order: 0,
115
+ }, HiddenPanelIcon)), 'hide-ui: hide the Plugins sidebar row')
116
+
117
+ ctx.effect(() => filterAgentPresets(ctx.remote), 'hide-ui: hide built-in agent presets')
118
+ },
119
+ }
120
+ },
121
+ })
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: hide-ui
3
+ name: '@wjmmyz/dsh-plugin-hide-ui'
package/docs/DETAIL.md ADDED
@@ -0,0 +1 @@
1
+ ![A sidebar whose plugin row has been removed, beside a preset list showing only custom presets](preview.svg)
@@ -0,0 +1 @@
1
+ ![左侧边栏已去掉插件入口,右侧预设列表只剩自定义预设](preview.svg)
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="640" height="300" viewBox="0 0 640 300" role="img" aria-label="A sidebar with its plugin row removed, beside a preset menu that lists only custom presets">
2
+ <rect width="640" height="300" fill="#f5f6f8"/>
3
+ <rect x="32" y="32" width="168" height="236" rx="12" fill="#ffffff" stroke="#d8dbe0" stroke-width="2"/>
4
+ <rect x="52" y="56" width="96" height="12" rx="6" fill="#c7ccd3"/>
5
+ <rect x="52" y="96" width="128" height="26" rx="8" fill="#e8ebef"/>
6
+ <rect x="64" y="104" width="64" height="10" rx="5" fill="#aeb5be"/>
7
+ <rect x="52" y="136" width="128" height="26" rx="8" fill="#e8ebef"/>
8
+ <rect x="64" y="144" width="80" height="10" rx="5" fill="#aeb5be"/>
9
+ <path d="M52 186 L180 186" stroke="#e2e5e9" stroke-width="2" stroke-dasharray="6 6"/>
10
+ <circle cx="66" cy="186" r="12" fill="#eef0f3"/>
11
+ <path d="M60 186 L72 186" stroke="#8d959f" stroke-width="3" stroke-linecap="round"/>
12
+ <rect x="88" y="181" width="60" height="10" rx="5" fill="#d2d6dc"/>
13
+ <rect x="232" y="64" width="376" height="204" rx="14" fill="#ffffff" stroke="#d8dbe0" stroke-width="2"/>
14
+ <rect x="256" y="88" width="120" height="12" rx="6" fill="#c7ccd3"/>
15
+ <rect x="256" y="120" width="328" height="52" rx="10" fill="#eef4fb" stroke="#bcd4ec" stroke-width="2"/>
16
+ <rect x="274" y="134" width="112" height="10" rx="5" fill="#7c98b3"/>
17
+ <rect x="274" y="150" width="196" height="8" rx="4" fill="#c3d3e2"/>
18
+ <rect x="256" y="184" width="328" height="52" rx="10" fill="#f2f4f7" stroke="#dde1e6" stroke-width="2"/>
19
+ <rect x="274" y="198" width="88" height="10" rx="5" fill="#9aa3ad"/>
20
+ <rect x="274" y="214" width="168" height="8" rx="4" fill="#d6dae0"/>
21
+ </svg>
package/icon.svg ADDED
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-label="Hide UI entries">
2
+ <rect x="2" y="2" width="60" height="60" rx="14" fill="#247bbf"/>
3
+ <rect x="15" y="17" width="34" height="30" rx="4" fill="none" stroke="#ffffff" stroke-width="3" opacity="0.55"/>
4
+ <rect x="15" y="17" width="12" height="30" rx="4" fill="#ffffff" opacity="0.28"/>
5
+ <path d="M20 37 L44 23" stroke="#ffffff" stroke-width="4.5" stroke-linecap="round"/>
6
+ <circle cx="20" cy="37" r="2.6" fill="#ffffff"/>
7
+ <circle cx="44" cy="23" r="2.6" fill="#ffffff"/>
8
+ </svg>
package/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Host half of the Hide UI bundle.
3
+ *
4
+ * All behavior lives in the browser half: hiding a navigation row and the
5
+ * built-in preset cards are Client-side rendering decisions, and the Host
6
+ * mutation surface (`sidebar.panellist`, the preset roster) belongs to the
7
+ * shipped packages. This entry exists so the bundle occupies a Loader row and
8
+ * can be enabled, disabled, and configured like any other plugin.
9
+ */
10
+ export function apply() {}
package/locale/en.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "meta": {
3
+ "title": "Hide UI entries",
4
+ "description": "Hides the Plugins entry in the left sidebar and the built-in agent presets in the preset pickers. Custom presets you add yourself stay visible, and sessions already running a built-in preset keep working.",
5
+ "detail": "docs/DETAIL.md"
6
+ }
7
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "meta": {
3
+ "title": "隐藏界面入口",
4
+ "description": "隐藏左侧边栏里的插件入口,以及预设选择器中的内置 Agent 预设。你自己添加的自定义预设仍然可见,已经在运行内置预设的会话也不受影响。",
5
+ "detail": "docs/DETAIL.zh.md"
6
+ }
7
+ }
package/package.json CHANGED
@@ -1,6 +1,49 @@
1
1
  {
2
2
  "name": "@wjmmyz/dsh-plugin-hide-ui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Hide the Plugins entry in the DSH sidebar and the built-in agent presets in the preset pickers.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "dsh",
9
+ "deepseek-harness",
10
+ "dsh-plugin",
11
+ "dsh-bundle"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/wjmmyz/dsh-plugin-hide-ui.git"
16
+ },
17
+ "homepage": "https://github.com/wjmmyz/dsh-plugin-hide-ui#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/wjmmyz/dsh-plugin-hide-ui/issues"
20
+ },
21
+ "exports": {
22
+ ".": "./index.js",
23
+ "./client": "./client.js",
24
+ "./locale/*.json": "./locale/*.json",
25
+ "./icon": "./icon.svg"
26
+ },
27
+ "files": [
28
+ "index.js",
29
+ "client.js",
30
+ "cordis.patch.yml",
31
+ "locale/*.json",
32
+ "docs",
33
+ "icon.svg",
34
+ "README.md",
35
+ "README.zh.md",
36
+ "LICENSE"
37
+ ],
38
+ "dsh": {
39
+ "bundle": { "patch": "./cordis.patch.yml" },
40
+ "client": {
41
+ "platform": "web",
42
+ "immediately": true,
43
+ "inject": [
44
+ "@deepseek-ai/dsh-client-ui-sidebar",
45
+ "@deepseek-ai/dsh-client-ui-agent-preset"
46
+ ]
47
+ }
48
+ }
49
+ }