@gehennawu/dsh-service 1.6.3 → 1.8.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 +35 -9
- package/README.md +36 -10
- package/backup-integrity.js +1 -1
- package/client.js +1 -1
- package/index.js +217 -16
- package/package.json +2 -2
- package/quota-adapters.js +214 -2
package/README.en.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<em>DeepSeek Harness (DSH) Web 服务控制与运维插件。</em>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
[](package.json)
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
15
|
[](https://cordis.moe/)
|
|
@@ -42,16 +42,16 @@ A service-control and operations plugin for DSH Web: safe restart, version manag
|
|
|
42
42
|
- [🚀 Features](#-features)
|
|
43
43
|
- [Version and updates](#version-and-updates) · [Safe restart](#safe-restart) · [Health diagnostics](#health-diagnostics) · [Model statistics](#model-statistics)
|
|
44
44
|
- [Quota lookup](#quota-lookup) · [Backup management](#backup-management) · [Skills management](#skills-management) · [Subagent model](#subagent-model)
|
|
45
|
-
- [Task notifications](#task-notifications) · [Session manager](#session-manager) · [Mobile adaptation](#mobile-adaptation) · [Right-Sidebar file editing](#right-sidebar-file-editing) · [External liveness probe](#external-liveness-probe)
|
|
45
|
+
- [Task notifications](#task-notifications) · [Session manager](#session-manager) · [Mobile adaptation](#mobile-adaptation) · [Model provider icons](#model-provider-icons) · [Right-Sidebar file editing](#right-sidebar-file-editing) · [External liveness probe](#external-liveness-probe)
|
|
46
46
|
- [🏗️ Architecture](#-architecture)
|
|
47
47
|
- [⚡ Installation](#-installation) · [🔄 Automatic restart](#-automatic-restart) · [🖥️ Platform support](#-platform-support)
|
|
48
48
|
- [🔒 Security design](#-security-design) · [❓ FAQ](#-faq) · [🤝 Contributing](#-contributing) · [📄 License](#-license)
|
|
49
49
|
|
|
50
50
|
## 🚀 Features
|
|
51
51
|
|
|
52
|
-
The Settings "Service Control" panel has a six-page navigation: **Overview · Model stats · Quota lookup · Health · Maintenance · Configuration**; "Maintenance" aggregates five subpages — Sessions · Skills · Subagents · Backups · Restart — and "Configuration" aggregates Features · Task notifications. Restart, Quota lookup, and Sessions can each enable a **quick entry in the settings left navigation** (off by default; the Skills and Subagents sidebar entries were removed).
|
|
52
|
+
The Settings "Service Control" panel has a six-page navigation: **Overview · Model stats · Quota lookup · Health · Maintenance · Configuration**; "Maintenance" aggregates five subpages — Sessions · Skills · Subagents · Backups · Restart — and "Configuration" aggregates Features · Task notifications · Settings Nav. Restart, Quota lookup, and Sessions can each enable a **quick entry in the settings left navigation** (off by default; the Skills and Subagents sidebar entries were removed).
|
|
53
53
|
|
|
54
|
-
Under **Plugins → Plugin configuration**,
|
|
54
|
+
Under **Plugins → Plugin configuration**, twelve host-level switches: **Health diagnostics, Model statistics, Quota lookup, Backup maintenance, Task notifications, Skill manager, Subagent model, Session manager, Mobile adaptation, Model provider icons, Right-Sidebar file editing, `/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.
|
|
55
55
|
|
|
56
56
|

|
|
57
57
|
|
|
@@ -67,7 +67,8 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
67
67
|

|
|
68
68
|
|
|
69
69
|
- Maintenance groups Sessions, Skills, Subagents, Backups, and Restart; it remembers the most recent subpage and falls back to an available item when a feature is disabled
|
|
70
|
-
- Configuration groups feature switches and
|
|
70
|
+
- Configuration groups feature switches, task notifications, and settings nav tabs; switches are grouped and apply live, Notifications stays visible but disabled when that feature is off, and Settings Nav supports manual reordering (drag / arrows) and visibility management of all tabs in the settings dialog sidebar, persisted to the server-side unified config file `$DSH_HOME/dsh-service-config.json` (cross-device sync, auto-fetched on startup with a local-cache fallback), applying live (the Service Control tab is permanently locked visible to prevent lockout); quota card order and visibility use the same config (the `quotaCards` section, fetched when the quota page opens)
|
|
71
|
+
- Unified plugin config file: lightweight per-feature preferences converge into a single `$DSH_HOME/dsh-service-config.json` (atomic write, `0600`), partitioned by feature section — updating or clearing one section never touches others; large caches (usage index etc.) and encrypted credentials stay out of this file
|
|
71
72
|
|
|
72
73
|
### Version and updates
|
|
73
74
|
|
|
@@ -82,7 +83,7 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
82
83
|
|
|
83
84
|
- Detects active agents, background jobs, and terminals before restart; lists them and requires explicit confirmation
|
|
84
85
|
- `/restart` also works in conversations; automatically refuses while work is running
|
|
85
|
-
- Probes the new process after restart and reloads the page; manual reload offered after 60 seconds
|
|
86
|
+
- Probes the new process after restart and reloads the page; manual reload offered after 60 seconds. A restart triggered by `/restart` in a conversation reloads the same way: the page records the process identity at load time and compares `instanceId` on reconnect, reloading as soon as the new process is up
|
|
86
87
|
- Optional "Restart" entry in the settings left navigation (off by default), sharing the same confirmation flow as the "Maintenance → Restart" subpage
|
|
87
88
|
- A suspected manual terminal launch warns that nothing will bring the process back and gets a yellow caution in Health
|
|
88
89
|
|
|
@@ -111,6 +112,7 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
111
112
|

|
|
112
113
|
|
|
113
114
|
- Provider cards keep the existing window presentation (label + percent / independent bar / reset countdown); **advanced configuration** (credentials, kind switching, manual reset entries) is collapsed per card by default
|
|
115
|
+
- Card **order and visibility**: "Reorder & visibility" on the quota page expands a management list where cards can be dragged or nudged with ↑/↓, and a toggle hides cards you rarely need (hiding only affects display, not querying or polling); the config shares one backend with the Settings Nav tabs, stored in the `quotaCards` section of the unified server-side config `$DSH_HOME/dsh-service-config.json` (cross-device sync with a local-cache fallback, sections never affect each other)
|
|
114
116
|
- 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
|
|
115
117
|
- Built-in adaptations:
|
|
116
118
|
|
|
@@ -124,12 +126,13 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
124
126
|
| StepFun Balance | Official `GET /v1/accounts` (API key, com/ai dual domains) |
|
|
125
127
|
| StepFun Step Plan | Console BFF subscription quota (Oasis-Token console session; 5-hour/weekly windows vs Credit pool auto-detected) |
|
|
126
128
|
| Xiaomi MiMo Token Plan | Console-origin plan quota (web session cookie) |
|
|
129
|
+
| Command Code (command-goat) | Official account quota plane `api.commandcode.ai/alpha/*` (same key reused: balance + period spend + plan + 5-hour/weekly windows) |
|
|
127
130
|
| CLIProxyAPI deployment | Official remaining quota of each OAuth upstream account |
|
|
128
131
|
|
|
129
|
-
- Credentials go into the DSH credential store (`$DSH_HOME/.credentials.yaml`, hot-effective): an API key, the CPA management key, the Xiaomi console cookie, or the StepFun Step Plan console token (Oasis-Token; the `Oasis-Webid` is derived from the token automatically — no manual entry)
|
|
132
|
+
- Credentials go into the DSH credential store (`$DSH_HOME/.credentials.yaml`, hot-effective): an API key, the CPA management key, the Xiaomi console cookie, or the StepFun Step Plan console token (Oasis-Token; the `Oasis-Webid` is derived from the token automatically — no manual entry); the Command Code quota plane reuses the inference key, so no extra credential is needed
|
|
130
133
|
- 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
|
|
131
134
|
- CLIProxyAPI: when an account's live query fails, its last cached snapshot windows are shown with a "cached" badge; snapshot windows whose reset time has already passed (the window they described has ended) are dropped, avoiding the illusion of quota stuck on yesterday
|
|
132
|
-
- Failures state their real reason: cards and the ring show "error copy (HTTP status · failing endpoint · failing account · upstream message) · next automatic retry" — a wrong key, an unpaid balance, rate limiting, and a moved endpoint each read differently instead of one generic notice; an upstream 401/403 is classified as "credential rejected by upstream" and the card keeps its credential form available
|
|
135
|
+
- Failures state their real reason: cards and the ring show "error copy (HTTP status · failing endpoint · failing account · upstream message) · next automatic retry" — a wrong key, an unpaid balance, rate limiting, and a moved endpoint each read differently instead of one generic notice; an upstream 401/403 is classified as "credential rejected by upstream" and the card keeps its credential form available, and business error codes inside an HTTP 200 envelope are classified the same way (auth failure → credential rejected, expired plan → no active subscription, vendor-side failure → upstream service error) instead of being reported as "unexpected response format"
|
|
133
136
|
- API keys are resolved only inside the host process; the browser receives normalized window data only; unadapted providers are never requested
|
|
134
137
|
|
|
135
138
|
### Backup management
|
|
@@ -149,6 +152,7 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
149
152
|

|
|
150
153
|
|
|
151
154
|
- Lists local skills in three sections — **auto-loaded / manual-only / fully disabled**; same-name shadowing marks both copies, bundled directories are read-only
|
|
155
|
+
- Entries start collapsed into one row (name plus source / read-only / annotated badges); the top button expands or collapses every visible entry at once, and clicking an entry's name row toggles that entry alone; an invalid entry keeps its ⚠ and one-click fix visible while collapsed
|
|
152
156
|
- Two switches edit the SKILL.md frontmatter directly (`disable-model-invocation` / `user-invocable`); changes go live within ~200 ms
|
|
153
157
|
- Entries with legacy camelCase keys are dropped by the official parser: ⚠ warning + one-click canonical fix
|
|
154
158
|
- ✨ 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. Already-annotated skills are listed separately in the plan and are only overwritten after a "Confirm forced refill" second confirmation (annotating no longer blocks future batch fills forever); completion-log timestamps use your local timezone
|
|
@@ -163,6 +167,7 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
163
167
|
- 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
|
|
164
168
|
- **inherit / follow / feature gate off** inject no provider, model, or reasoning effort at all; subagents that carry an explicit provider/model are unaffected
|
|
165
169
|
- **Mode switching keeps the config** — the saved custom model (including its reasoning effort) and the fallback list survive switching between the three modes; a mode only decides whether the route applies, so switching back to "Custom" needs no re-selection (provider/model missing from the runtime catalog fall back to the first catalog entry)
|
|
170
|
+
- **No shift on entry** — the page seeds its first frame from the most recent successful read, so it lands directly on the real mode instead of showing "Default" and then jumping to "Custom"; on a fresh install or a different browser (no cache) it briefly shows "Reading configuration…"
|
|
166
171
|
- **Fallback models (in order)** — both Follow and Custom modes accept an ordered fallback list: when the primary route is unavailable (channel unloaded, or quota state marks it unserviceable), the next model is tried in order; if none works, delegations fall back to native inheritance instead of failing. Fallback entries pass the same allow-list check as the primary route, with an optional reasoning effort per entry
|
|
167
172
|
- **Conversation-page visibility** — every turn that spawned subagents shows a small line under its last message listing the models those subagents actually ran on, e.g. `Subagent models: cpa/gpt-5.6-luna (xhigh) · opencode-go/deepseek-v4-flash (max)` — covering fallback hits, explicit routes, and inherited sources, so you can verify the custom route at a glance; a session-level aggregate line also sits under the composer (20s refresh, independent of turn data — when compaction folds the delegation tool calls the official counter and the per-turn line vanish together, and the aggregate line covers from the host dispatch records, visible in any view; switch it off independently from Maintenance → Subagent, keeping only the per-turn line); records live in host memory (survive page reloads, cleared on process restart). Works regardless of the official "assign subagent models" switch
|
|
168
173
|
- Config stored in `$DSH_HOME/dsh-service-subagent-route.json` (atomic writes, `0600`); one-click reset
|
|
@@ -204,6 +209,21 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
|
|
|
204
209
|
- Entry: the “Sessions” subpage under “Maintenance” (on by default); the optional settings-sidebar entry is off by default
|
|
205
210
|
- Delete records live at `$DSH_HOME/dsh-service-sessions-deleted.json` (atomic write, `0600`, title/time only — no content, not recoverable)
|
|
206
211
|
|
|
212
|
+
### Model provider icons
|
|
213
|
+
|
|
214
|
+
- The **model button in the composer shows the current provider's brand icon**: on wide screens (>480px) it is **prepended to the model name**; on phones (≤480px, where the official UI collapses the name into an icon) it **replaces** the official generic icon
|
|
215
|
+
- **Providers with no matching icon keep the official default icon untouched** (nothing prepended on wide screens, official icon unchanged on phones) — never a blank or a wrong logo
|
|
216
|
+
- Covers **38 of pi-ai's 40 built-in providers** (`ant-ling` and `radius` have no matching brand mark, so they fall back), plus commonly used routes: Ollama, vLLM, LM Studio, Perplexity, Cohere, Volcengine, Doubao, Hunyuan, Yuanbao, StepFun, SenseNova, Baichuan, 01.AI, Fal, Replicate, Midjourney and more — 62 marks across 76 provider mappings; regional and billing variants (e.g. `xiaomi-token-plan-*`, `qwen-token-plan-*`) share one brand mark
|
|
217
|
+
- **Custom route names are recognised by prefix/alias**: `opencode-goo` → opencode, `openrouter-f` → openrouter, `zai-coding-cn` → Zhipu, `xiaomi-token-plan-cn` → Xiaomi, `command-goat` → Command Code; anything unrecognised (such as the `cpa` relay, which publishes no brand mark) falls back to the official default icon
|
|
218
|
+
- **The CLIProxyAPI icon appears on demand**: the hand-drawn "concave diamond + mirrored swirl" mark shows on the model button **only after you have manually adapted some provider as CLIProxyAPI in the quota page** (regardless of the provider's name — `cpa` or a custom one alike); un-adapting immediately falls back to the official default icon
|
|
219
|
+
- **Quota cards carry the icons too**: adapted provider cards show the same brand mark before the channel name (14px; colour tiers keep their brand colour, mono tiers follow the theme text colour). The CLIProxyAPI "show only when adapted" gate applies here as well — the card list is exactly where you adapt, so the mark appears immediately
|
|
220
|
+
- **Legible in both light and dark themes**: a brand colour is kept only when its contrast is adequate against **both** a light and a dark background; otherwise the icon automatically switches to a monochrome variant that follows the theme's text colour — so you never get a black logo on a dark background, or a nearly invisible one in light mode
|
|
221
|
+
- **Zero runtime network requests**: icons are inlined into the client bundle at build time, so it works offline, needs no CSP exceptions, and never leaks your provider names to a third party
|
|
222
|
+
- The icon is sized to match the **quota ring** beside the composer (each mark's viewBox is tightened to its real drawn extent and squared at build time, so every brand reads at the same visual size instead of some filling the box and others shrinking)
|
|
223
|
+
- Toggle under Plugins → Plugin configuration → Interaction (on by default, applied live)
|
|
224
|
+
- Icons come from the MIT-licensed [LobeHub Icons](https://github.com/lobehub/lobe-icons) (pinned to `@1.95.0`); the Xiaomi icon uses the plain "mi" mark from CC0 [Simple Icons](https://github.com/simple-icons/simple-icons) (LobeHub's version is a two-line "Xiaomi / MIMO" wordmark that turns to mush at 15px). **Brand marks remain the property of their owners**, so review each vendor's brand guidelines before public-facing use
|
|
225
|
+
- **Every icon is browsable in one page**: [icon catalog](docs/model-icons.html) — 62 marks, 76 provider mappings, the matching rules, and a light/dark comparison; a single offline file, generated from the very data inlined into the client bundle
|
|
226
|
+
|
|
207
227
|
### Right-Sidebar file editing
|
|
208
228
|
|
|
209
229
|
- The official right-Sidebar preview header gains an **“Edit” button in its top-right corner** (next to the renderer name): one click enters editing — a monospaced editor with a dirty marker, `Ctrl/Cmd + S` saving, “Reload”, “Undo save”, and a one-click “Preview” back to the official renderer
|
|
@@ -321,7 +341,7 @@ pm2 start "dsh web --host 127.0.0.1" --name dsh-web
|
|
|
321
341
|
|
|
322
342
|
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.
|
|
323
343
|
|
|
324
|
-
**DSH compatibility statement**: adapted to DSH `0.1.6-alpha.
|
|
344
|
+
**DSH compatibility statement**: adapted to DSH `0.1.6-alpha.2` — session format V3 (`system/message` events in history, renamed PTC vocabulary; the detail view automatically archives system events), the handle-based sessionPersistence (usage refresh, title cache, and diagnostics counts all ride the new public surface `list`/`open`/`read`/`close`), the official right sidebar replacing the Detail column (the mobile right-edge gesture drives `ctx.layout.openRightbar/closeRightbar` directly), the object-shaped official turn-process (subagent turn claiming supports both shapes), dual-hash compatibility for mobile bottom-row triggers, subagent turn-tail list-slot adaptive compatibility, `plugins.bundle.config` slot injection for the new Plugins page, and session-detail open fallback through `uiWorkspace`. Older DSH releases (`>=0.1.1-rc.2`) remain supported: persistence and layout seams run in dual shapes detected from runtime capabilities, and adaptation items that target newer structures are naturally inert on older hosts (cosmetic only, no functional loss). Note: sessions written in the V3 format after upgrading cannot be read by older DSH releases — **backups do not restore across a version downgrade**. The version card shows a standing notice "Adapted for DSH 0.1.1-rc.2 ~ 0.1.6-alpha.2", and turns red when running on unverified releases (`≥0.1.6-alpha.3`).
|
|
325
345
|
|
|
326
346
|
## 🔒 Security design
|
|
327
347
|
|
|
@@ -354,6 +374,12 @@ It is the "likely manual terminal launch" detection — no process manager found
|
|
|
354
374
|
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.
|
|
355
375
|
</details>
|
|
356
376
|
|
|
377
|
+
<details>
|
|
378
|
+
<summary><strong>Command Code shows "credential rejected by upstream"?</strong></summary>
|
|
379
|
+
|
|
380
|
+
The inference and quota planes share one key (`user_*` prefix, created in Studio's API keys page). This error means the upstream rejected the key: regenerate or copy it in Studio at commandcode.ai, then paste it via "Set API credential". If the channel's baseURL points at a self-hosted relay rather than `api.commandcode.ai`, note the quota plane always queries the official account plane — a relay key cannot read official quota.
|
|
381
|
+
</details>
|
|
382
|
+
|
|
357
383
|
<details>
|
|
358
384
|
<summary><strong>Xiaomi shows "credential rejected by upstream"?</strong></summary>
|
|
359
385
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<em>A service-control & operations plugin for DeepSeek Harness (DSH) Web.</em>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
[](package.json)
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
15
|
[](https://cordis.moe/)
|
|
@@ -42,16 +42,16 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
42
42
|
- [🚀 功能](#-功能)
|
|
43
43
|
- [版本与更新](#版本与更新) · [安全重启](#安全重启) · [健康诊断](#健康诊断) · [模型统计](#模型统计)
|
|
44
44
|
- [额度查询](#额度查询) · [备份管理](#备份管理) · [技能管理](#技能管理) · [子代理模型](#子代理模型)
|
|
45
|
-
- [任务通知](#任务通知) · [会话管理](#会话管理) · [移动端适配](#移动端适配) · [右栏文件编辑](#右栏文件编辑) · [外部探活](#外部探活)
|
|
45
|
+
- [任务通知](#任务通知) · [会话管理](#会话管理) · [移动端适配](#移动端适配) · [模型厂家图标](#模型厂家图标) · [右栏文件编辑](#右栏文件编辑) · [外部探活](#外部探活)
|
|
46
46
|
- [🏗️ 架构](#-架构)
|
|
47
47
|
- [⚡ 安装](#-安装) · [🔄 自动重启配置](#-自动重启配置) · [🖥️ 平台支持](#-平台支持)
|
|
48
48
|
- [🔒 安全设计](#-安全设计) · [❓ 常见问题 FAQ](#-常见问题-faq) · [🤝 参与贡献](#-参与贡献) · [📄 许可证](#-许可证)
|
|
49
49
|
|
|
50
50
|
## 🚀 功能
|
|
51
51
|
|
|
52
|
-
设置页「服务控制」面板六页导航:**概览 · 模型统计 · 额度查询 · 健康诊断 · 维护 · 配置**;其中「维护」聚合 会话管理 · 技能 · 子代理 · 备份维护 · 重启 五个子页,「配置」聚合 功能开关 · 任务通知
|
|
52
|
+
设置页「服务控制」面板六页导航:**概览 · 模型统计 · 额度查询 · 健康诊断 · 维护 · 配置**;其中「维护」聚合 会话管理 · 技能 · 子代理 · 备份维护 · 重启 五个子页,「配置」聚合 功能开关 · 任务通知 · 设置栏标签 三个子页。重启、额度查询、会话管理可另行开启**设置页左列快捷入口**(默认关闭;技能与子代理的左列入口已撤销)。
|
|
53
53
|
|
|
54
|
-
「插件 →
|
|
54
|
+
「插件 → 插件配置」提供十二个宿主级开关:**健康诊断、模型统计、额度查询、备份维护、任务通知、技能管理、子代理模型、会话管理、移动端适配、模型厂家图标、右栏文件编辑、`/healthz` 探活**(除移动端适配外默认开启)。全部热生效:关闭即隐藏界面、停止轮询并让宿主拒绝对应能力;概览与重启固定保留。
|
|
55
55
|
|
|
56
56
|

|
|
57
57
|
|
|
@@ -67,7 +67,8 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
67
67
|

|
|
68
68
|
|
|
69
69
|
- 「维护」集中会话管理、技能、子代理、备份维护与重启;记住最近使用的子页,关闭对应功能后自动回退到仍可用的项目
|
|
70
|
-
-
|
|
70
|
+
- 「配置」集中功能开关、任务通知与设置栏标签;开关按功能组展示并热生效,任务通知关闭时保留入口但显示置灰状态,设置栏标签支持对设置弹窗左侧全部导航标签进行手动排序(拖拽/上下箭头换位)与显隐管理,配置持久化到服务端统一配置文件 `$DSH_HOME/dsh-service-config.json`(多设备同步、启动自动拉取,本地缓存兜底),即时生效(服务控制面板永久锁定显示防锁死);额度卡的排序与显隐走同一份配置(`quotaCards` 区块,进入额度页时拉取)
|
|
71
|
+
- 插件统一配置文件:各功能的轻量偏好收敛在 `$DSH_HOME/dsh-service-config.json` 单一文件(原子写入、`0600`),按功能分区块隔离——修改或清除某一区块绝不影响其他区块;大缓存(使用统计索引等)与加密凭据不在此文件内
|
|
71
72
|
|
|
72
73
|
### 版本与更新
|
|
73
74
|
|
|
@@ -82,7 +83,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
82
83
|
|
|
83
84
|
- 重启前检测活跃 Agent、后台任务与终端,展示清单并要求显式确认
|
|
84
85
|
- 对话输入 `/restart` 也可触发;检测到运行中工作时自动拒绝
|
|
85
|
-
- 重启后自动探测新进程并刷新页面,60
|
|
86
|
+
- 重启后自动探测新进程并刷新页面,60 秒未恢复提供手动刷新;对话里用 `/restart` 触发的重启同样自动刷新(页面加载时记下进程身份,重连后比对 `instanceId`,新进程上线即刷新)
|
|
86
87
|
- 可开启「设置页左列显示入口」(默认关闭),与「维护 → 重启」子页共用同一确认流程
|
|
87
88
|
- 疑似终端手动启动时提示「退出后不会自动拉起」,健康诊断以黄色警示标注
|
|
88
89
|
|
|
@@ -112,7 +113,8 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
112
113
|
|
|
113
114
|

|
|
114
115
|
|
|
115
|
-
-
|
|
116
|
+
- 卡片分区展示各供应商:窗口百分比、独立进度条、重置时间;支持强制刷新与官网用量页链接
|
|
117
|
+
- 卡片**排序与显隐**:额度页「调整排序与显隐」展开管理列表,可拖拽或点 ↑↓ 调整卡片顺序,开关可隐藏不常用卡片(隐藏只影响展示,不影响查询与轮询);配置与设置栏标签同源,写入服务端统一配置文件 `$DSH_HOME/dsh-service-config.json` 的 `quotaCards` 区块(多设备同步、本地缓存兜底,区块间互不影响)
|
|
116
118
|
- 对话输入框**额度圆环**:跟随当前会话模型所属供应商,显示最紧预算窗口用量(<80% 绿、≥80% 黄);点击弹出详情面板,窄屏自动切换为居中浮层
|
|
117
119
|
- 内置适配:
|
|
118
120
|
|
|
@@ -126,12 +128,13 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
126
128
|
| StepFun 余额 | 官方 `GET /v1/accounts`(API key,com/ai 双域) |
|
|
127
129
|
| StepFun Step Plan | 控制台 BFF 订阅额度(Oasis-Token 登录令牌;5 小时/周窗口与 Credit 月池自动识别) |
|
|
128
130
|
| 小米 MiMo Token Plan | 控制台同源套餐额度(网页登录态 Cookie) |
|
|
131
|
+
| Command Code(command-goat) | 官方账号额度面 `api.commandcode.ai/alpha/*`(同 key 复用:余额 + 本周期花费 + 套餐 + 5 小时/周窗口) |
|
|
129
132
|
| CLIProxyAPI 部署 | 各 OAuth 上游账号官方剩余额度 |
|
|
130
133
|
|
|
131
|
-
- 凭据写入 DSH 凭据库(`$DSH_HOME/.credentials.yaml`,热生效):普通适配填 API key,CLIProxyAPI 填管理密钥,小米填控制台 Cookie,StepFun Step Plan 填控制台令牌(Oasis-Token,`Oasis-Webid`
|
|
134
|
+
- 凭据写入 DSH 凭据库(`$DSH_HOME/.credentials.yaml`,热生效):普通适配填 API key,CLIProxyAPI 填管理密钥,小米填控制台 Cookie,StepFun Step Plan 填控制台令牌(Oasis-Token,`Oasis-Webid` 由令牌自动派生无需手填);Command Code 额度面与推理面同一把 key,无需另配
|
|
132
135
|
- 防风控:结果缓存 60 秒、失败指数退避(30 秒 ×2、封顶 15 分钟);自动查询可调为仅手动 / 1 / 2 / 5 / 10 分钟
|
|
133
136
|
- CLIProxyAPI 某账号实时查询失败时,回退显示其上次缓存的快照窗口并标注「缓存」徽标;重置时间已过的快照窗口(快照描述的窗口已结束)直接丢弃,避免「额度停在昨天」的错觉
|
|
134
|
-
- 失败原因如实呈现:卡片与圆环显示「错误文案(HTTP 状态 · 失败端点 · 失败账号 · 上游原话)· 下次自动重试时刻」——错 key、欠费、限流、路径变更各有各的上游原话与状态码,不再只有一个笼统提示;上游 401/403
|
|
137
|
+
- 失败原因如实呈现:卡片与圆环显示「错误文案(HTTP 状态 · 失败端点 · 失败账号 · 上游原话)· 下次自动重试时刻」——错 key、欠费、限流、路径变更各有各的上游原话与状态码,不再只有一个笼统提示;上游 401/403 判为「凭据被上游拒绝」,卡片同时保留凭据填写入口;HTTP 200 业务信封里的错误码同样定族——鉴权失败判凭据被拒(保留填写入口)、套餐到期判无生效订阅、上游自身故障判「上游服务故障」,不再一律报「响应格式异常」
|
|
135
138
|
- API key 只在宿主进程内解析,浏览器仅收到归一化窗口数据;未适配的供应商绝不发起请求
|
|
136
139
|
|
|
137
140
|
### 备份管理
|
|
@@ -151,6 +154,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
151
154
|

|
|
152
155
|
|
|
153
156
|
- 按 **自动加载 / 仅手动调用 / 完全停用** 三区展示本地技能;同名遮蔽与被遮蔽副本均有标注,内置目录只读
|
|
157
|
+
- 条目默认全部折叠成一行(名称 + 来源/只读/已注释徽标);顶部按钮对当前可见条目一键「全部展开 / 全部折叠」,点单条名称行可独立开合;无效条目的 ⚠ 与一键修复折叠态也保留
|
|
154
158
|
- 双开关直接改写 SKILL.md frontmatter(`disable-model-invocation` / `user-invocable`),约 200ms 热生效
|
|
155
159
|
- 带 camelCase 旧版键的条目会被官方解析器剔除:⚠ 提示 + 一键修复
|
|
156
160
|
- ✨ AI 补全说明:选模型生成描述草稿(跟随界面语言),确认后存入插件侧车索引——**绝不改写 SKILL.md**;支持一键批量补全(宿主后台运行、可取消)。已注释技能会在计划中单列,经「确认强制补全」二次确认后才会被覆盖(不再是一旦注释就永远无法再次补全);补全日志时间按本机时区显示
|
|
@@ -165,6 +169,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
165
169
|
- 该字段来自适配器 metadata(`reasoning.efforts[].id`),等级 ID 对宿主不透明;无等级声明的模型禁用下拉并提示
|
|
166
170
|
- **inherit / follow / 功能开关关闭** 均不注入任何 provider、model 或思考等级;显式指定 provider/model 的子代理不受影响
|
|
167
171
|
- **模式切换保留配置**:已保存的自定义模型(含思考等级)与回退列表在三种模式间切换时不会被清除——模式只决定是否生效,切回「自定义」无需重新选择(供应商/模型已不在运行时清单时自动回落到清单首项)
|
|
172
|
+
- **进入无位移**:本页以最近一次成功读取的配置作为首帧缓存,进入即直接落在真实模式上,不会先显示「初始」再跳到「自定义」;首次安装或换浏览器(无缓存)时先显示一行「读取配置…」
|
|
168
173
|
- **回退模型(按顺序)**:跟随与自定义模式都可配置回退列表——第一路由不可用时(渠道已卸载、额度查询判定其不可服务)依次尝试后续模型;全部不可用则回落原生继承,不让派生失败。回退条目与主路由同一道白名单校验,思考等级逐条可选
|
|
169
174
|
- **对话页可见性**:每个派生了子代理的回合,最后一条消息下方会显示一行小字列出该回合子代理实际使用的模型,如 `子代理模型:cpa/gpt-5.6-luna (xhigh) · opencode-go/deepseek-v4-flash (max)`——含回退命中、显式路由与继承来源,可直接核对自定义路由是否生效;**同时输入框下方常驻一行本会话累计模型行**(20s 刷新,不依赖回合数据——会话发生 compaction 折叠工具调用后官方计数会消失、回合尾行随之缺席,累计行由宿主派发记录兜底,任何视图都能看到;可在 维护 → 子代理 页用独立开关关闭,仅保留回合尾行);记录存宿主内存(页面刷新不丢、进程重启即清),官方「指派子代理模型」开关关闭与否都不影响本功能
|
|
170
175
|
- 配置存 `$DSH_HOME/dsh-service-subagent-route.json`(原子写入、`0600`),可一键重置
|
|
@@ -206,6 +211,21 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
206
211
|
- 自动补 `viewport-fit=cover` 避让刘海、禁双击缩放、输入框 ≥16px 防 iOS 聚焦放大
|
|
207
212
|
- `?dshsvc-mobile-debug=1` 显示浮动诊断条(仅调试)
|
|
208
213
|
|
|
214
|
+
### 模型厂家图标
|
|
215
|
+
|
|
216
|
+
- 输入框里那颗**模型按钮会显示当前渠道的厂家图标**:宽屏(>480px)加在模型名**前面**;手机上(≤480px,官方把名称收成图标的形态)**替换**掉官方那枚通用图标
|
|
217
|
+
- **没适配的渠道保持官方默认图标不变**(宽屏不加、手机照旧显示官方图标),不会出现空缺或错图
|
|
218
|
+
- 覆盖 **pi-ai 内置 40 个 provider 中的 38 个**(`ant-ling`、`radius` 无对应品牌图形,走默认图标),并补充 ollama、vLLM、LM Studio、Perplexity、Cohere、火山引擎、豆包、混元、元宝、阶跃、商汤、百川、零一万物、Fal、Replicate、Midjourney 等常用渠道,共 62 张图形 / 76 条渠道映射;区域与计费变体(如 `xiaomi-token-plan-*`、`qwen-token-plan-*`)共用同一品牌图形
|
|
219
|
+
- **自定义渠道名按前缀/别名自动识别**:`opencode-goo` → opencode、`openrouter-f` → openrouter、`zai-coding-cn` → 智谱、`xiaomi-token-plan-cn` → 小米、`command-goat` → Command Code 等;识别不到的(如 `cpa` 这类没有公开品牌图形的中转)自动回落官方默认图标
|
|
220
|
+
- **CLIProxyAPI 图标按需出现**:手绘的「内凹菱形 + 镜像漩涡」品牌标**只在你在余额查询里把某个渠道手动适配成 CLIProxyAPI 后**才显示在模型按钮上(渠道名不限,叫 `cpa` 还是自定义名都一样);撤销适配立即回落官方默认图标
|
|
221
|
+
- **余额查询的渠道卡片同样带图标**:已适配卡片的渠道名前显示同一套厂家小图标(14px;彩色档原样上品牌色、单色档跟随主题文字色)。CPA 的「手动适配才显示」门在这里同样生效——卡片区正是你做适配的地方,适配后立即出现
|
|
222
|
+
- **浅色 / 深色都清晰**:品牌色对浅底与深底**两侧**对比度都达标才保留原色,否则自动改用跟随主题文字色的单色版——不会出现深色模式下「黑图标糊在黑底上」或浅色模式下近乎隐形
|
|
223
|
+
- **零运行期网络请求**:图标在构建期内联进客户端产物,离线可用、不影响 CSP,也不向第三方暴露你的渠道名称
|
|
224
|
+
- 图标尺寸与输入框旁的**额度圆环**一致(生成期把每个图标的 viewBox 收紧到真实绘制范围并正方形化,所以各品牌「看起来一样大」,不会有的满格有的缩成一团)
|
|
225
|
+
- 开关在 插件 → 插件配置 → 交互(默认开,热生效)
|
|
226
|
+
- 图标来自 MIT 许可的 [LobeHub Icons](https://github.com/lobehub/lobe-icons)(版本钉死 `@1.95.0`);小米图标取自 CC0 的 [Simple Icons](https://github.com/simple-icons/simple-icons) 纯 mi 标(LobeHub 那份是「Xiaomi / MIMO」两行文字组合标,15px 下糊成一团)。**品牌图形版权归各厂商**,正式对外使用前请查阅对应厂商的品牌条款
|
|
227
|
+
- **全部图标可在一页里查看**:[图标目录](docs/model-icons.html)——62 张图形、76 条渠道映射、匹配规则与深浅色对照;离线单文件,与构建期内联进客户端的数据同源生成
|
|
228
|
+
|
|
209
229
|
### 右栏文件编辑
|
|
210
230
|
|
|
211
231
|
- 官方右侧栏的文件预览头部**右上角多一个「编辑」按钮**(紧邻渲染器名),点一下就进编辑模式:等宽编辑器,带脏标记、`Ctrl/Cmd + S` 保存、「重新加载」「撤销保存」,以及一键「预览」返回官方渲染器
|
|
@@ -323,7 +343,7 @@ pm2 start "dsh web --host 127.0.0.1" --name dsh-web
|
|
|
323
343
|
|
|
324
344
|
运行要求:Node.js `>=22`,DSH Web 能加载 Host 与 Client 两半插件。更新检查需访问 `registry.npmjs.org`;网络失败不影响其他功能。
|
|
325
345
|
|
|
326
|
-
**DSH 适配口径**:已适配 DSH `0.1.6-alpha.
|
|
346
|
+
**DSH 适配口径**:已适配 DSH `0.1.6-alpha.2`——会话格式 V3(`system/message` 入史、旧 PTC 词汇更名,详情视图自动归档系统事件)、sessionPersistence handle 化(用量增量、标题缓存、诊断计数全部按新公共面 `list`/`open`/`read`/`close` 走)、官方右栏替代详情列(移动端右缘手势直接驱动 `ctx.layout.openRightbar/closeRightbar`)、官方 turn-process 对象化(子代理回合认领双形态兼容)、移动端底行触发钮双哈希兼容、子代理回合尾模型行 list 槽位自适应兼容、新插件管理页 `plugins.bundle.config` 槽位注入、会话详情打开接入 `uiWorkspace` 降级链路。旧版 DSH(`>=0.1.1-rc.2`)保持兼容:新旧两套 persistence/布局 seam 按运行时能力探测双形态走,旧宿主上针对新结构的适配项天然不生效(纯展示,无功能损失)。注意:升级后以 V3 格式写入的会话日志无法被旧版 DSH 读取——**备份不可跨版本降级恢复**。版本卡常驻显示「适配 DSH 0.1.1-rc.2 ~ 0.1.6-alpha.2」,越界运行版本(`≥0.1.6-alpha.3`)标红警示。
|
|
327
347
|
|
|
328
348
|
## 🔒 安全设计
|
|
329
349
|
|
|
@@ -356,6 +376,12 @@ pm2 start "dsh web --host 127.0.0.1" --name dsh-web
|
|
|
356
376
|
点击卡片上的内联表单写入凭据:普通适配填 API key,CLIProxyAPI 填管理密钥(不是代理 key),小米 Token Plan 填控制台 Cookie。写入 DSH 凭据库后自动强制刷新;被进程环境变量遮蔽时宿主会拒绝写入,需改环境变量本身。
|
|
357
377
|
</details>
|
|
358
378
|
|
|
379
|
+
<details>
|
|
380
|
+
<summary><strong>Command Code 卡片显示「凭据被上游拒绝」?</strong></summary>
|
|
381
|
+
|
|
382
|
+
推理面和额度面共用同一把 key(`user_*` 前缀,Studio 的 API keys 页生成)。卡片显示该错误说明 key 被上游判为无效:到 commandcode.ai 的 Studio 重新生成或复制 key,点卡片「填写 API 密钥」粘贴即可。若渠道 baseURL 指向的是自建中转而非 `api.commandcode.ai`,额度面仍固定查官方账号面——中转 key 查不到官方额度。
|
|
383
|
+
</details>
|
|
384
|
+
|
|
359
385
|
<details>
|
|
360
386
|
<summary><strong>小米卡片显示「凭据被上游拒绝」?</strong></summary>
|
|
361
387
|
|
package/backup-integrity.js
CHANGED
|
@@ -5,7 +5,7 @@ import { dirname, join, resolve, sep } from 'node:path'
|
|
|
5
5
|
import { promisify } from 'node:util'
|
|
6
6
|
import { gunzip } from 'node:zlib'
|
|
7
7
|
|
|
8
|
-
const CONFIG_FILES = Object.freeze(['settings.yaml', 'cordis.patch.yml', 'AGENTS.md'])
|
|
8
|
+
const CONFIG_FILES = Object.freeze(['settings.yaml', 'cordis.patch.yml', 'AGENTS.md', 'dsh-service-config.json'])
|
|
9
9
|
const PLAN_TTL_MS = 5 * 60 * 1000
|
|
10
10
|
const MAX_COMPRESSED_BYTES = 512 * 1024 * 1024
|
|
11
11
|
const MAX_EXPANDED_BYTES = 1024 * 1024 * 1024
|