@gehennawu/dsh-service 0.31.0 → 0.32.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/README.en.md +228 -92
- package/README.md +227 -91
- package/client.js +1164 -17
- package/index.js +810 -18
- package/package.json +2 -1
- package/screenshots/.gitkeep +0 -0
- package/screenshots/README.md +16 -0
- package/screenshots/model-usage.png +0 -0
- package/screenshots/model-usage_en.png +0 -0
- package/screenshots/overview.png +0 -0
- package/screenshots/overview_en.png +0 -0
- package/screenshots/quota-lookup.png +0 -0
- package/screenshots/quota-lookup_en.png +0 -0
- package/screenshots/skill-manager.png +0 -0
- package/screenshots/skill-manager_en.png +0 -0
- package/screenshots/subagent-model.png +0 -0
- package/screenshots/subagent-model_en.png +0 -0
- package/screenshots/task-notifications.png +0 -0
- package/screenshots/task-notifications_en.png +0 -0
package/README.en.md
CHANGED
|
@@ -1,132 +1,219 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
3
|
[中文](./README.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# 🛠️ dsh-service
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>A service-control & operations plugin for self-hosted DeepSeek Harness (DSH) Web.</strong><br>
|
|
9
|
+
<em>面向自托管 DeepSeek Harness (DSH) Web 的服务控制与运维插件。</em>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
[](package.json)
|
|
13
|
+
[](LICENSE)
|
|
14
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
|
+
[](https://cordis.moe/)
|
|
16
|
+
[](https://github.com/gehennawu/dsh-service)
|
|
17
|
+
[](https://github.com/gehennawu/dsh-service/issues)
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<a href="#-features">Features</a> •
|
|
21
|
+
<a href="#-architecture">Architecture</a> •
|
|
22
|
+
<a href="#-installation">Installation</a> •
|
|
23
|
+
<a href="#-automatic-restart">Automatic restart</a> •
|
|
24
|
+
<a href="#-platform-support">Platform support</a> •
|
|
25
|
+
<a href="#-security-design">Security design</a> •
|
|
26
|
+
<a href="#-faq">FAQ</a> •
|
|
27
|
+
<a href="#-contributing">Contributing</a> •
|
|
28
|
+
<a href="#-license">License</a>
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
A service-control and operations plugin for self-hosted DSH Web: safe restart, version management and one-click upgrade, health diagnostics, model-usage statistics, quota lookup, backup management, task notifications, skills management, session management, and Linux file-permission maintenance.
|
|
6
36
|
|
|
7
37
|

|
|
8
38
|
|
|
9
|
-
##
|
|
39
|
+
## 📑 Contents
|
|
10
40
|
|
|
11
|
-
|
|
41
|
+
- [🚀 Features](#-features)
|
|
42
|
+
- [Version and updates](#version-and-updates) · [Safe restart](#safe-restart) · [Health diagnostics](#health-diagnostics) · [Model statistics](#model-statistics)
|
|
43
|
+
- [Quota lookup](#quota-lookup) · [Backup management](#backup-management) · [Skills management](#skills-management) · [Subagent model](#subagent-model)
|
|
44
|
+
- [Task notifications](#task-notifications) · [Session manager](#session-manager) · [Mobile adaptation](#mobile-adaptation) · [External liveness probe](#external-liveness-probe)
|
|
45
|
+
- [🏗️ Architecture](#-architecture)
|
|
46
|
+
- [⚡ Installation](#-installation) · [🔄 Automatic restart](#-automatic-restart) · [🖥️ Platform support](#-platform-support)
|
|
47
|
+
- [🔒 Security design](#-security-design) · [❓ FAQ](#-faq) · [🤝 Contributing](#-contributing) · [📄 License](#-license)
|
|
12
48
|
|
|
13
|
-
|
|
49
|
+
## 🚀 Features
|
|
50
|
+
|
|
51
|
+
The Settings "Service Control" panel has ten tabs: **Overview · Notifications · Health · Model stats · Quota lookup · Backups · Skills · Subagents · Sessions · Restart**; Restart, Quota lookup, Skills, Subagents, and Sessions can each enable a **quick entry in the settings left navigation** (off by default).
|
|
52
|
+
|
|
53
|
+
Under **Plugins → Plugin configuration**, ten host-level switches: **Health diagnostics, Model statistics, Quota lookup, Backup maintenance, Task notifications, Skill manager, Subagent model, Session manager, Mobile adaptation, `/healthz` liveness endpoint** (all on by default except Mobile adaptation). All are live settings: disabling hides the UI, stops polling/subscriptions, and makes the host reject that capability; Overview and Restart stay available.
|
|
14
54
|
|
|
15
55
|
### Version and updates
|
|
16
56
|
|
|
17
|
-
-
|
|
18
|
-
- Automatically checks npm
|
|
19
|
-
- One-click
|
|
57
|
+
- Shows the current DSH and plugin versions, linking to GitHub Releases
|
|
58
|
+
- Automatically checks npm **stable + preview** (latest / next dist-tags); when a new version exists, an inline expandable compares them, each with npmjs and npmmirror links
|
|
59
|
+
- One-click upgrade with automatic restart; when no process manager is detected, it confirms the consequences first, keeps running, and shows manual-restart instructions
|
|
20
60
|
|
|
21
61
|
### Safe restart
|
|
22
62
|
|
|
23
63
|
- Detects active agents, background jobs, and terminals before restart; lists them and requires explicit confirmation
|
|
24
|
-
- `/restart`
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
64
|
+
- `/restart` also works in conversations; automatically refuses while work is running
|
|
65
|
+
- Probes the new process after restart and reloads the page; manual reload offered after 60 seconds
|
|
66
|
+
- Optional "Restart" entry in the settings left navigation (off by default), sharing the same confirmation flow
|
|
67
|
+
- A suspected manual terminal launch warns that nothing will bring the process back and gets a yellow caution in Health
|
|
28
68
|
|
|
29
69
|
### Health diagnostics
|
|
30
70
|
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
- File-permission deep scan and repair: checks whether the Agent can read/write DSH_HOME and workspaces; repair requires two-step confirmation
|
|
36
|
-
- The **Health diagnostics** switch under Plugins → Plugin configuration hides this whole tab: full diagnostics and file-permission requests stop immediately and the Host rejects the corresponding RPCs; the overview metrics (5-second polling) are unaffected
|
|
71
|
+
- Uptime, memory, session count, active agents, and background jobs; a "Process and runtime" card shows platform, architecture, and Node version
|
|
72
|
+
- Full diagnostics: session storage, workspace registry, backup storage, tar availability, file permissions, runtime environment, and Node version
|
|
73
|
+
- File-permission deep scan and repair (two-step confirmation)
|
|
74
|
+
- Suspected manual launch → yellow "no restart assurance" caution; no backups is informational only and never lights the ⚠
|
|
37
75
|
|
|
38
76
|
### Model statistics
|
|
39
77
|
|
|
40
78
|

|
|
41
79
|
|
|
42
|
-
- 7-day stacked bar chart of input/output/cache tokens
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
- Steps whose provider reports no token usage are excluded
|
|
46
|
-
- Last-24-hour model/tool error statistics, collapsed by default
|
|
80
|
+
- 7-day stacked bar chart of input / output / cache tokens; filter by project, hover for exact values
|
|
81
|
+
- Per-model horizontal bars with a "Today / Last 7 days / All time" toggle
|
|
82
|
+
- Last-24-hour model/tool errors (collapsed by default)
|
|
83
|
+
- Steps whose provider reports no token usage are excluded
|
|
47
84
|
|
|
48
85
|
### Quota lookup
|
|
49
86
|
|
|
50
87
|

|
|
51
88
|
|
|
52
|
-
-
|
|
53
|
-
- A quota ring
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
89
|
+
- Provider cards: per-window percentage, independent bar, and reset countdown; force refresh, official usage-page links, and card reordering
|
|
90
|
+
- A **quota ring** in the conversation composer follows the current session's model provider and shows the tightest budget window (<80% green, ≥80% amber); clicking opens a detail panel that becomes a centered overlay on narrow screens
|
|
91
|
+
- Built-in adaptations:
|
|
92
|
+
|
|
93
|
+
| Provider | Data source |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| DeepSeek Platform | Official balance + peak/off-peak ribbon and countdown |
|
|
96
|
+
| Zhipu GLM Coding Plan | Official endpoint: 5-hour rolling / weekly / monthly MCP windows |
|
|
97
|
+
| OpenCode Go | `{baseURL}/usage` |
|
|
98
|
+
| OpenRouter | Credits used % |
|
|
99
|
+
| Kimi / SiliconFlow | CNY balance |
|
|
100
|
+
| Xiaomi MiMo Token Plan | Console-origin plan quota (web session cookie) |
|
|
101
|
+
| CLIProxyAPI deployment | Official remaining quota of each OAuth upstream account |
|
|
102
|
+
|
|
103
|
+
- Credentials go into the DSH credential store (`$DSH_HOME/.credentials.yaml`, hot-effective): an API key, the CPA management key, or the Xiaomi console cookie
|
|
104
|
+
- Anti-rate-limit pacing: 60 s result cache, exponential backoff (30 s doubling, capped at 15 min); auto-query can be set to manual-only / 1 / 2 / 5 / 10 minutes
|
|
105
|
+
- API keys are resolved only inside the host process; the browser receives normalized window data only; unadapted providers are never requested
|
|
62
106
|
|
|
63
107
|
### Backup management
|
|
64
108
|
|
|
65
|
-
- Creates `.tar.gz` archives of sessions, configuration, and plugin
|
|
66
|
-
- Export
|
|
67
|
-
- Restore: extract and overwrite to corresponding paths,
|
|
68
|
-
- Import: upload a `.tar.gz` file to the backup directory
|
|
69
|
-
- Delete requires two-step confirmation; backups are unlimited and never auto-pruned
|
|
109
|
+
- Creates `.tar.gz` archives of sessions, configuration, and plugin-profile manifests
|
|
110
|
+
- Export download / import upload / delete (two-step confirmation); unlimited, never auto-pruned
|
|
111
|
+
- Restore: extract and overwrite to the corresponding paths, then restarts automatically after confirmation
|
|
70
112
|
|
|
71
113
|
### Skills management
|
|
72
114
|
|
|
73
115
|

|
|
74
116
|
|
|
75
|
-
-
|
|
76
|
-
- Two
|
|
77
|
-
- Entries
|
|
78
|
-
-
|
|
79
|
-
- One-click batch fill: automatically collects unannotated skills or ones whose body changed (read-only roots included; invalid entries and shadowed copies are skipped), shows candidate count / estimated payload and an expandable per-entry skip list first, then runs sequentially with live progress; individual failures never block the batch, and cancelling immediately interrupts the in-flight model call. Zero file modifications throughout, and the plugin never issues model calls autonomously
|
|
80
|
-
- Batch runs in the Host background: switching tabs, closing the settings panel, or even refreshing the page never interrupts it; returning to the Skills tab restores progress and the cancel button, the Skills tab title shows a live `⟳done/total` badge while running, and planning a second batch mid-run is explicitly rejected
|
|
117
|
+
- Lists local skills in three sections — **auto-loaded / manual-only / fully disabled**; same-name shadowing marks both copies, bundled directories are read-only
|
|
118
|
+
- Two switches edit the SKILL.md frontmatter directly (`disable-model-invocation` / `user-invocable`); changes go live within ~200 ms
|
|
119
|
+
- Entries with legacy camelCase keys are dropped by the official parser: ⚠ warning + one-click canonical fix
|
|
120
|
+
- ✨ Fill with AI: pick a model to draft a description (follows the UI language), saved to a plugin sidecar index — **SKILL.md is never modified**; one-click batch fill runs in the host background and can be cancelled
|
|
81
121
|
|
|
82
122
|
### Subagent model
|
|
83
123
|
|
|
84
124
|

|
|
85
125
|
|
|
86
|
-
-
|
|
87
|
-
- A provider
|
|
88
|
-
-
|
|
126
|
+
- Three modes: **Default** (no override) / **Follow main model** (the provider/model actually used by the latest main-conversation request) / **Custom** (pin every unspecified subagent)
|
|
127
|
+
- A provider/model explicitly carried by the delegation always wins; pinned presets are never overridden
|
|
128
|
+
- Custom mode optionally selects a **reasoning effort**: the dropdown appears only for the exact provider/model when its adapter declares selectable levels; leaving it empty means "use the target model default", materialized by the adapter
|
|
129
|
+
- Values come from adapter metadata (`reasoning.efforts[].id`); effort ids are opaque to the host. Models with no declared levels disable the dropdown and show a hint
|
|
130
|
+
- **inherit / follow / feature gate off** inject no provider, model, or reasoning effort at all; subagents that carry an explicit provider/model are unaffected
|
|
131
|
+
- Config stored in `$DSH_HOME/dsh-service-subagent-route.json` (atomic writes, `0600`); one-click reset
|
|
89
132
|
|
|
90
133
|
### Task notifications
|
|
91
134
|
|
|
92
135
|

|
|
93
136
|
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
- Bell icon in the conversation input bar toggles the master switch quickly; a "Show composer bell icon" capsule switch on the Notifications tab hides it entirely (notification behavior is unaffected, and the choice persists across reloads)
|
|
98
|
-
- All toggles persist across page reloads
|
|
137
|
+
- Browser notification when a session finishes its turn or your approval / plan review / answer is needed; clicking focuses the page
|
|
138
|
+
- Four independent toggles: master, task completion, approvals & questions, composer-bell visibility
|
|
139
|
+
- The composer bell toggles the master switch quickly; all toggles persist across reloads
|
|
99
140
|
|
|
100
141
|
### Mobile adaptation
|
|
101
142
|
|
|
102
|
-
- Off by default
|
|
103
|
-
- Sidebar becomes a drawer
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
- The "Mobile adaptation" switch in "Plugins → Plugin configuration" turns everything off: the host compression patch is restored and all UI enhancements unmount, returning to the native layout immediately without a restart
|
|
108
|
-
- Debug mode: append `?dshsvc-mobile-debug=1` to the URL to show a floating diagnostics chip (viewport size / breakpoint state / drawer & details state / JS error count). For debugging only
|
|
143
|
+
- Off by default; active only below a 1024 px viewport (phones / narrow windows), desktops unaffected
|
|
144
|
+
- Sidebar becomes a drawer, details column an overlay, modals bottom sheets, settings left nav a horizontal top strip
|
|
145
|
+
- Transparent large-JSON compression (≥4KB auto gzip/brotli per `Accept-Encoding`) speeds up long session histories
|
|
146
|
+
- Adds `viewport-fit=cover` with safe-area avoidance, disables double-tap zoom, keeps inputs ≥16px against iOS focus zoom
|
|
147
|
+
- `?dshsvc-mobile-debug=1` shows a floating diagnostics chip (debugging only)
|
|
109
148
|
|
|
110
|
-
###
|
|
149
|
+
### Session manager
|
|
111
150
|
|
|
112
|
-
-
|
|
113
|
-
-
|
|
151
|
+
- **View**: one unified list for sessions (running / cold / archived) with status badges, workspace, event count, and size; **starts on the “Archived” view by default**, and each of the All / Archived / Deleted filters fetches its own subset from the host **once,** then keeps it in a **module-level cache** — switching filters sends no requests, and **closing and reopening the panel renders the cache instantly while quietly refreshing the current view once in the background** (only a page reload clears the cache), with a “Refresh” button for a forced refetch of the current view; sizes are never shipped with the list — each row fetches its size lazily (double-cached in the module and in host memory: reopened panels and refreshed pages reuse it, cleared on delete); the detail page walks events as paged cards (single-slot host snapshot cache: paging and reopening the same session never re-reads the log, live sessions stay fresh within 30 seconds), with **event bodies rendered as official Markdown** (reusing the platform renderer `MarkdownText`, same look as the chat UI: code blocks, lists, tables, math — raw HTML and unsafe links are rejected by default; older DSH shells without the renderer automatically fall back to plain text), and consecutive system events collapse into a countable block by default — click to expand the details; **entering a detail remembers the list scroll position and returning to the list drops you back exactly where you were** (reusing the official panel's scroll container; changing the filter or search while in the detail discards the restore)
|
|
152
|
+
- **Export**: one-click download of the official full ZIP (including subagents and attachments) via the official export path — the host never assembles a package itself
|
|
153
|
+
- **Archive**: archived sessions disappear from the official sidebar (official behavior); the panel marks “archiving is one-way”, and the official UI cannot unarchive
|
|
154
|
+
- **Content search**: full-text semantic search over conversations (case-insensitive, whitespace-flexible) with cross-session hits (matched text is highlighted; multiple matches show seq chips for one-click jumps) → **hit-window view**: opening a result centers a context window on the matched seq (15 events on each side; the matched event gets a HIT badge, is highlighted, **auto-scrolled into view and flashes for 2 seconds**), with **previous / next match** navigation and navigator seq chips for direct jumps (mirroring dsh-session-kb's Locate interaction); the window can keep loading later events; optionally restricted to the archived zone
|
|
155
|
+
- **Delete**: Only archived sessions can be deleted, and a session that becomes live is rejected again immediately before execution; the two-phase confirmation shows its id / title / workspace / size, persists the deletion record atomically first, and only then removes the log directory; deleted records stay visible (read-only) under the Deleted filter
|
|
156
|
+
- Entry: “Sessions” chip in the top “Maintenance” tab group (on by default); the optional settings-sidebar entry is off by default
|
|
157
|
+
- Delete records live at `$DSH_HOME/dsh-service-sessions-deleted.json` (atomic write, `0600`, title/time only — no content, not recoverable)
|
|
114
158
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
### Install from npm (recommended)
|
|
159
|
+
### External liveness probe
|
|
118
160
|
|
|
119
|
-
|
|
120
|
-
|
|
161
|
+
- `GET` / `HEAD /healthz` returns an empty 200; other methods return 405
|
|
162
|
+
- Suitable for Uptime Kuma, Docker, Kubernetes, and other external monitors
|
|
163
|
+
|
|
164
|
+
## 🏗️ Architecture
|
|
165
|
+
|
|
166
|
+
The plugin is a Cordis two-half structure: the **Host half (`index.js`)** owns all capabilities and data access, while the **Client half (`client.js`)** only renders UI in the browser; the two sides communicate over Typert JSON-RPC on a single-layer absolute path channel `/dsh-service`, with `loopback` authority throughout.
|
|
167
|
+
|
|
168
|
+
```mermaid
|
|
169
|
+
flowchart TB
|
|
170
|
+
subgraph Client["🌐 Client browser half (client.js)"]
|
|
171
|
+
UI["Settings : Service Control panel (9 tabs + quick entries)<br/>quota ring · notification bell · mobile adaptation"]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
subgraph Host["⚙️ Host half (index.js)"]
|
|
175
|
+
RPC["Loopback RPC · /dsh-service<br/>version / check-update / restart / quota / skills / backup"]
|
|
176
|
+
SPAWN["Controlled spawn<br/>chmod / chown / npm upgrade"]
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
subgraph DSH["🚀 DSH core runtime (read-only consumption)"]
|
|
180
|
+
CORE["agents · jobs · terminals · sessions<br/>sessionQuery · skills · credentials"]
|
|
181
|
+
WEB["webServer routes<br/>GET/HEAD /healthz"]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
subgraph OS["💾 Host machine & external"]
|
|
185
|
+
PM["Process manager<br/>Docker / systemd / pm2"]
|
|
186
|
+
FS["$DSH_HOME<br/>config / backups / credentials / skills index"]
|
|
187
|
+
REG["npm registry"]
|
|
188
|
+
QUOTA["Upstream quota APIs"]
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
UI -- "Typert JSON-RPC (loopback)" --> RPC
|
|
192
|
+
RPC --> CORE
|
|
193
|
+
RPC --> SPAWN
|
|
194
|
+
RPC --> REG
|
|
195
|
+
RPC --> QUOTA
|
|
196
|
+
RPC -- "process.exit(42)" --> PM
|
|
197
|
+
SPAWN --> FS
|
|
198
|
+
MON["External monitors<br/>Uptime Kuma / Docker / K8s"] -- "GET /healthz" --> WEB
|
|
121
199
|
```
|
|
122
200
|
|
|
123
|
-
|
|
201
|
+
Key contracts:
|
|
124
202
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
203
|
+
- **Loopback only**: capabilities are exposed solely through the `/dsh-service` loopback channel; webServer routes return only information-free status codes
|
|
204
|
+
- **Restart = `process.exit(42)`**: the plugin only sends an exit signal; an external process manager brings it back — no manager, no restart guarantee
|
|
205
|
+
- **Zero input concatenation**: the browser side never supplies URLs, package names, commands, or paths; all commands go through a host-side whitelist
|
|
206
|
+
- **Credentials never leave the host**: API keys are resolved only inside the host process; the browser receives only normalized window data
|
|
128
207
|
|
|
129
|
-
|
|
208
|
+
## ⚡ Installation
|
|
209
|
+
|
|
210
|
+
| Method | Command |
|
|
211
|
+
| --- | --- |
|
|
212
|
+
| npm (recommended) | `dsh plugin --profile web add @gehennawu/dsh-service` |
|
|
213
|
+
| GitHub | `dsh plugin --profile web add github:gehennawu/dsh-service` |
|
|
214
|
+
| Local development | `dsh plugin --profile web add link:/path/to/dsh-service` |
|
|
215
|
+
|
|
216
|
+
Restart DSH Web after installing or updating:
|
|
130
217
|
|
|
131
218
|
```sh
|
|
132
219
|
dsh web
|
|
@@ -134,17 +221,11 @@ dsh web
|
|
|
134
221
|
|
|
135
222
|
Open DSH Web Settings and select **Service Control**.
|
|
136
223
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
```sh
|
|
140
|
-
dsh plugin --profile web add link:/path/to/dsh-service
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## Automatic restart configuration
|
|
224
|
+
## 🔄 Automatic restart
|
|
144
225
|
|
|
145
|
-
The plugin only sends an exit signal; it does not start the process again. Without a process manager,
|
|
226
|
+
The plugin only sends an exit signal; it does not start the process again. Without a process manager, restart stops DSH Web.
|
|
146
227
|
|
|
147
|
-
The plugin passively detects
|
|
228
|
+
The plugin passively detects a process manager (environment variables, `/.dockerenv`, `/proc/1/cgroup`, terminal TTY): with Docker/systemd/pm2/supervisord/Kubernetes detected it restarts as usual; when nothing is detected and stdin/stdout are an interactive terminal, it treats the launch as manual — flagged in Health diagnostics and switching one-click upgrade to keep running with manual-restart instructions. Heuristics cannot cover redirected output or wrappers such as NSSM/WinSW; declare `DSH_SERVICE_RUNTIME_ENV=managed|manual` explicitly.
|
|
148
229
|
|
|
149
230
|
### Docker Compose
|
|
150
231
|
|
|
@@ -169,7 +250,7 @@ RestartSec=2
|
|
|
169
250
|
pm2 start "dsh web --host 127.0.0.1" --name dsh-web
|
|
170
251
|
```
|
|
171
252
|
|
|
172
|
-
## Platform support
|
|
253
|
+
## 🖥️ Platform support
|
|
173
254
|
|
|
174
255
|
| Environment | Plugin features | Automatic recovery | Verification |
|
|
175
256
|
| --- | --- | --- | --- |
|
|
@@ -178,18 +259,73 @@ pm2 start "dsh web --host 127.0.0.1" --name dsh-web
|
|
|
178
259
|
| macOS / Windows + pm2 or similar | Not blocked by the code | Managed externally | Not tested |
|
|
179
260
|
| Direct `dsh web` execution | Supported | Not supported | Expected behavior |
|
|
180
261
|
|
|
181
|
-
When launched directly from a terminal (PowerShell/CMD/bash), the panel labels the environment as a likely manual launch and the one-click upgrade no longer exits the process automatically.
|
|
182
|
-
|
|
183
262
|
Requirements: Node.js `>=22`, and a DSH Web installation capable of loading both Host and Client plugin halves. Update checks require access to `registry.npmjs.org`; network failures do not affect other features.
|
|
184
263
|
|
|
185
|
-
## Security design
|
|
264
|
+
## 🔒 Security design
|
|
265
|
+
|
|
266
|
+
| Area | Boundary |
|
|
267
|
+
| --- | --- |
|
|
268
|
+
| Input | The browser cannot supply URLs, package names, commands, or file paths |
|
|
269
|
+
| Network | Update checks only access fixed npm registry endpoints |
|
|
270
|
+
| RPC | Loopback-only; data never leaves the machine |
|
|
271
|
+
| Data | The usage index stores no messages, prompts, tool arguments, or credentials; API keys are used inside the host process only |
|
|
272
|
+
| Actions | Destructive operations (restart, delete, permission repair) all require two-step confirmation |
|
|
273
|
+
| Credentials | Stored in the DSH credential store (`$DSH_HOME/.credentials.yaml`), sent to fixed endpoints only |
|
|
274
|
+
|
|
275
|
+
## ❓ FAQ
|
|
276
|
+
|
|
277
|
+
<details>
|
|
278
|
+
<summary><strong>It does not come back after restart?</strong></summary>
|
|
279
|
+
|
|
280
|
+
The plugin only sends an exit signal; a process manager brings it back (see "Automatic restart"). When the panel flags a manual launch, a plain `dsh web` terminal process exits for good — run it under Docker Compose / systemd / pm2 instead.
|
|
281
|
+
</details>
|
|
282
|
+
|
|
283
|
+
<details>
|
|
284
|
+
<summary><strong>What is the yellow "no restart assurance" caution in Health?</strong></summary>
|
|
285
|
+
|
|
286
|
+
It is the "likely manual terminal launch" detection — no process manager found. If it is actually managed by NSSM/WinSW or output redirection, declare `DSH_SERVICE_RUNTIME_ENV=managed` to clear it.
|
|
287
|
+
</details>
|
|
288
|
+
|
|
289
|
+
<details>
|
|
290
|
+
<summary><strong>A quota card shows "credential missing"?</strong></summary>
|
|
291
|
+
|
|
292
|
+
Use the inline form on the card: an API key for regular adaptations, the management key for CLIProxyAPI (not the proxy key), and the console cookie for Xiaomi Token Plan. The value goes into the DSH credential store and the provider refreshes automatically; if a process environment variable shadows the name, the host refuses the write — change the variable itself.
|
|
293
|
+
</details>
|
|
294
|
+
|
|
295
|
+
<details>
|
|
296
|
+
<summary><strong>Xiaomi shows "console cookie expired"?</strong></summary>
|
|
297
|
+
|
|
298
|
+
The web session expired. Log back in at platform.xiaomimimo.com, copy the `Cookie:` header from any `/api/v1/tokenPlan/` request, and paste it again via "Set console cookie".
|
|
299
|
+
</details>
|
|
300
|
+
|
|
301
|
+
<details>
|
|
302
|
+
<summary><strong>What does restoring a backup do?</strong></summary>
|
|
303
|
+
|
|
304
|
+
It extracts and overwrites the corresponding paths (sessions, config, plugin profiles) and restarts automatically after the two-step confirmation. Deleting a backup also requires two-step confirmation.
|
|
305
|
+
</details>
|
|
306
|
+
|
|
307
|
+
<details>
|
|
308
|
+
<summary><strong>Why is a skill switch greyed out?</strong></summary>
|
|
309
|
+
|
|
310
|
+
That skill lives in a read-only bundled directory. Only `project-*` and `user-*` sources support the two-way switches.
|
|
311
|
+
</details>
|
|
312
|
+
|
|
313
|
+
<details>
|
|
314
|
+
<summary><strong>Saving a skill switch says "the skill file just changed"?</strong></summary>
|
|
315
|
+
|
|
316
|
+
Concurrency protection kicked in: SKILL.md was just modified by an external editor (version mismatch). Refresh to get the latest state and retry.
|
|
317
|
+
</details>
|
|
318
|
+
|
|
319
|
+
<details>
|
|
320
|
+
<summary><strong>Does a failed update check affect other features?</strong></summary>
|
|
321
|
+
|
|
322
|
+
No. It is a read-only request to the npm registry and fails silently; everything else keeps working.
|
|
323
|
+
</details>
|
|
324
|
+
|
|
325
|
+
## 🤝 Contributing
|
|
186
326
|
|
|
187
|
-
|
|
188
|
-
- Update checks only access fixed npm registry endpoints
|
|
189
|
-
- The RPC channel is loopback-only
|
|
190
|
-
- The model-usage index stores no messages, prompts, tool arguments, or credentials
|
|
191
|
-
- Destructive operations (restart, delete, permission repair) all require two-step confirmation
|
|
327
|
+
Issues and pull requests are welcome. See AGENTS.md in the repository for the development roadmap and conventions, and its "Release" section for publishing rules.
|
|
192
328
|
|
|
193
|
-
## License
|
|
329
|
+
## 📄 License
|
|
194
330
|
|
|
195
|
-
[MIT](./LICENSE)
|
|
331
|
+
[MIT](./LICENSE)
|