@gehennawu/dsh-service 1.5.1 → 1.6.1

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 CHANGED
@@ -9,7 +9,7 @@
9
9
  <em>DeepSeek Harness (DSH) Web 服务控制与运维插件。</em>
10
10
  </p>
11
11
 
12
- [![Version](https://img.shields.io/badge/version-1.5.1-3b82f6.svg?style=flat-square)](package.json)
12
+ [![Version](https://img.shields.io/badge/version-1.6.1-3b82f6.svg?style=flat-square)](package.json)
13
13
  [![License: MIT](https://img.shields.io/badge/License-MIT-10b981.svg?style=flat-square)](LICENSE)
14
14
  [![DSH Compatibility](https://img.shields.io/badge/DSH-%E2%89%A50.1.1--rc.2%20%C2%B7%20compatible%20with%200.1.5--rc.1-6366f1.svg?style=flat-square)](https://github.com/deepseek-ai/deepseek-harness)
15
15
  [![Cordis](https://img.shields.io/badge/Cordis-v4.x-f59e0b.svg?style=flat-square)](https://cordis.moe/)
@@ -42,7 +42,7 @@ 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) · [External liveness probe](#external-liveness-probe)
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)
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)
@@ -51,14 +51,14 @@ A service-control and operations plugin for DSH Web: safe restart, version manag
51
51
 
52
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).
53
53
 
54
- 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.
54
+ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health diagnostics, Model statistics, Quota lookup, Backup maintenance, Task notifications, Skill manager, Subagent model, Session manager, Mobile adaptation, 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
  ![Plugin configuration](./screenshots/plugin-config_en.png)
57
57
 
58
58
  ### Overview (six sections)
59
59
 
60
60
  - Status summary (error → warning → info → normal aggregation with a status dot) → actionable items (only when present) → version and runtime → metrics grid → fixed core actions (health check / quota lookup / create backup, gated by feature switches) → recent errors (rendered only when non-empty, collapsed by default)
61
- - Aggregation rules: any health/diagnostics/backup/statistics/quota/restart failure is error; permission issues and non-advisory diagnostic warnings are warning; available updates, manual-start runtime, and no backups yet are info (high quota-window usage only shows as a progress bar on the quota page and no longer surfaces as an overview reminder)
61
+ - Aggregation rules: any health/diagnostics/backup/statistics/quota/restart failure is error; permission issues and non-advisory diagnostic warnings are warning; available updates and no backups yet are info (high quota-window usage only shows as a progress bar on the quota page, and a likely manual terminal launch — a standing environment fact — appears only in the health checks and in the restart/upgrade confirmations; neither surfaces as an overview reminder)
62
62
 
63
63
  ### Maintenance and Configuration pages
64
64
 
@@ -74,6 +74,7 @@ Under **Plugins → Plugin configuration**, ten host-level switches: **Health di
74
74
  - Shows the current DSH and plugin versions, linking to GitHub Releases
75
75
  - 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
76
76
  - One-click upgrade with automatic restart; when no process manager is detected, it confirms the consequences first, keeps running, and shows manual-restart instructions
77
+ - Between the upgrade landing and the process restart (common in a manual-launch environment) the version row reads "Installed X — restart to take effect" and the upgrade button is withdrawn; reopening the panel or refreshing the page keeps that state until the process is restarted
77
78
 
78
79
  ### Safe restart
79
80
 
@@ -128,6 +129,7 @@ Under **Plugins → Plugin configuration**, ten host-level switches: **Health di
128
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)
129
130
  - 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
130
131
  - 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
131
133
  - API keys are resolved only inside the host process; the browser receives normalized window data only; unadapted providers are never requested
132
134
 
133
135
  ### Backup management
@@ -180,7 +182,9 @@ Under **Plugins → Plugin configuration**, ten host-level switches: **Health di
180
182
 
181
183
  - Off by default; active only below a 1024 px viewport (phones / narrow windows), desktops unaffected
182
184
  - Sidebar becomes a drawer, details column is hidden on mobile (matching the official narrow-screen behavior), modals become full-screen panels, settings left nav a horizontal top strip
183
- - Scroll immersion: inside a conversation, swiping down auto-hides the header and composer for full-screen reading; swipe up, reaching the bottom, or focusing the composer brings them back, with a resident bottom handle as a manual toggle. Programmatic scrolling (streaming pinning, anchor jumps) never triggers it
185
+ - The model picker collapses to an icon on phones (≤480 px, mirroring the official narrow-container form; from 481 px up it still shows the model name and reasoning effort) — the plugin's mobile layout widens the composer column, so the official `@container (width<=360px)` collapse rule never fires on 428~440 px devices; this aligns with the official narrow-container form explicitly
186
+ - The stats line under the composer ("turns/steps · tok/s | tok · cache hit") **stays on one line and uses the full width** on phones: this row's own horizontal padding is tightened (official 32 px → 2 px) along with its gaps, and both chips share the whole row — zero truncation from ~420 px up, proportionally less text cut than the official fixed truncation below that, with no wrapping and no horizontal scrolling (desktops unaffected)
187
+ - Scroll immersion: inside a conversation, swiping down auto-hides the header and composer for full-screen reading (the composer also yields its layout space so the transcript really fills the screen; on reveal, if you are still at the end of the conversation it re-aligns to the bottom). Swipe up, tapping the official "Back to bottom" button, or focusing the composer brings them back (no extra floating button); already sitting at the end of the conversation, a single small backward nudge reveals it right away (no full threshold needed), and after a back-to-bottom tap the resting position gets one extra bottom snap. Programmatic scrolling (streaming pinning, anchor jumps) never triggers it
184
188
  - Swipeable drawers: with both drawers closed, a horizontally dominant swipe rightward anywhere opens the sidebar drawer and a swipe leftward anywhere opens the official right sidebar (DSH 0.1.5+; stays inert when unavailable); once open, a swipe in the reverse direction anywhere closes them. Swipes starting at the screen edge additionally benefit from stolen-gesture completion for browser edge navigation, and horizontal scrolling inside editors never misfires
185
189
  - The "Back to bottom" button is shifted flush right on mobile (no more large empty strip); a matching circular up-arrow now sits above it on all platforms, jumping to the previous user message on each click for step-by-step back navigation. Targets outside the loaded history auto-trigger the official "load earlier" action; the button hides once you reach the very top and reappears when you scroll back down
186
190
  - Transparent large-JSON compression (≥4KB auto gzip/brotli per `Accept-Encoding`) speeds up long session histories
@@ -191,7 +195,7 @@ Under **Plugins → Plugin configuration**, ten host-level switches: **Health di
191
195
 
192
196
  ![Session manager](./screenshots/session-manager_en.png)
193
197
 
194
- - **View**: one unified list for sessions (running / cold / archived) with status badges, workspace, event count, and size; the list sorts by creation time (newest/oldest first) or by title, or **by project** — grouped into one section per workspace (each section header shows the path and session count; newest first within a project; sections are **collapsed by default** and expand/collapse on header click); **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; normal lists also provide a “Select multiple” button; in that mode, clicking anywhere on a session row selects or clears it without requiring a precise checkbox click, while one-click select-all / clear-all remains available for the current filtered result, and selected rows use a slim brand-colored edge without replacing their background; the toolbar shows eligible counts and runs batch export / archive / delete actions (changing filters, searching, or opening details exits selection mode automatically); 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)
198
+ - **View**: one unified list for sessions (running / cold / archived) with status badges, workspace, event count, and size; the list sorts by creation time (newest/oldest first) or by title, or **by project** — grouped into one section per workspace (each section header shows the path and session count; newest first within a project; sections are **collapsed by default** and expand/collapse on header click); **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; normal lists also provide a “Select multiple” button; in that mode, clicking anywhere on a session row selects or clears it without requiring a precise checkbox click, while one-click select-all / clear-all remains available for the current filtered result, and selected rows use a slim brand-colored edge without replacing their background; the toolbar shows eligible counts and runs batch export / archive / delete actions (changing filters, searching, or opening details exits selection mode automatically); 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 **and tool messages each collapse into their own countable block by default** (tool messages = `tool/call`, `tool/result` and the other `tool/*` events, plus assistant messages that carry nothing but tool calls — those dominate real long sessions, so tool arguments no longer flood the detail page); click a collapsed line to expand the details and click again to collapse; when a search hit falls inside a collapsed block that block opens automatically and keeps the hit highlighted; **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)
195
199
  - **Export**: one-click or batch download through the official export path (one full ZIP per session, including subagents and attachments) — the host never assembles a package itself
196
200
  - **Archive**: archive one or many non-running sessions; archived sessions disappear from the official sidebar (official behavior), and the official UI cannot unarchive
197
201
  - **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
@@ -199,6 +203,18 @@ Under **Plugins → Plugin configuration**, ten host-level switches: **Health di
199
203
  - Entry: the “Sessions” subpage under “Maintenance” (on by default); the optional settings-sidebar entry is off by default
200
204
  - Delete records live at `$DSH_HOME/dsh-service-sessions-deleted.json` (atomic write, `0600`, title/time only — no content, not recoverable)
201
205
 
206
+ ### Right-Sidebar file editing
207
+
208
+ - 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
209
+ - Two equivalent extra routes: the original **renderer dropdown**, and **right-click the tab → ⋯ menu → “Edit”** (the latter uses an official menu seat with no DOM injection at all, as the fallback if the header button ever stops working); while the editor tier is active the header button retracts itself
210
+ - **The official renderers keep their default status**: suffixes they own (`.md`, `.js`, …) still open as Markdown / code previews; only suffixes with no official renderer — the ones that used to fall back to plain text, such as `.txt`, `.log`, `.conf` — default to the editor. When the official preview is absent (older DSH), the whole block stays silent
211
+ - **Writes go through the session's own file service and sandbox policy**: the browser only sends a `dsh-resource://file/session/<session>/<path>` resource address, and the host resolves the session and workspace root itself — free-form paths are refused. Saving carries the version read earlier, so **a file changed by an Agent or another window is never overwritten silently**; you choose “Reload (discard edits)” or “Overwrite with mine”. Read-only sandbox sessions stay preview-only
212
+ - **Keep typing while saving**: a save response acknowledges only the submitted text; any newer typing stays in the editor as unsaved changes. The status distinguishes saving, unsaved changes, and saved. You can keep editing after a conflict, and overwrite uses the latest draft shown in the editor
213
+ - **Protect drafts before leaving**: the editor's own “Preview” and “Reload” buttons show an inline confirmation when changes are unsaved, with a cancel action to keep editing. “Undo save” also requires confirmation and retains its version guard rather than silently overwriting newer disk changes
214
+ - One 2 MiB cap per file (larger files are read-only); editing is unavailable when the session is inactive or the sandbox policy service is missing (the official preview remains available)
215
+ - Not in this first version: syntax highlighting, multi-cursor, find/replace (the plugin half has no bundler to borrow an editor component), and no unsaved-changes prompt when a tab closes
216
+ - The switch lives under Plugins → Plugin configuration → Interaction (on by default, live)
217
+
202
218
  ### External liveness probe
203
219
 
204
220
  - `GET` / `HEAD /healthz` returns an empty 200; other methods return 405
@@ -310,7 +326,7 @@ Requirements: Node.js `>=22`, and a DSH Web installation capable of loading both
310
326
 
311
327
  | Area | Boundary |
312
328
  | --- | --- |
313
- | Input | The browser cannot supply URLs, package names, commands, or file paths |
329
+ | Input | The browser cannot supply URLs, package names, commands, or file paths. **One exception**: right-Sidebar file editing accepts only a `dsh-resource://file/session/<session>/<path>` resource address (decoded per segment; every other shape is refused); the session and workspace root are always resolved host-side, and writes are fenced by the session's sandbox policy |
314
330
  | Network | Update checks only access fixed npm registry endpoints |
315
331
  | RPC | Loopback-only; data never leaves the machine |
316
332
  | Data | The usage index stores no messages, prompts, tool arguments, or credentials; API keys are used inside the host process only |
@@ -338,7 +354,7 @@ Use the inline form on the card: an API key for regular adaptations, the managem
338
354
  </details>
339
355
 
340
356
  <details>
341
- <summary><strong>Xiaomi shows "console cookie expired"?</strong></summary>
357
+ <summary><strong>Xiaomi shows "credential rejected by upstream"?</strong></summary>
342
358
 
343
359
  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".
344
360
  </details>
@@ -350,7 +366,7 @@ Step Plan has no API-key query endpoint — it needs a web session token. Log in
350
366
  </details>
351
367
 
352
368
  <details>
353
- <summary><strong>StepFun Step Plan card shows "console session expired"?</strong></summary>
369
+ <summary><strong>StepFun Step Plan card shows "credential rejected by upstream"?</strong></summary>
354
370
 
355
371
  The token expired (the official `oasis-token is embezzled` error means the token and web_id no longer match). Log back in at platform.stepfun.com, copy the full new `Oasis-Token` from Cookies and paste it again; if the copied value carries an `Oasis-Token=` or `Cookie: ` prefix it is stripped automatically.
356
372
  </details>
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  <em>A service-control &amp; operations plugin for DeepSeek Harness (DSH) Web.</em>
10
10
  </p>
11
11
 
12
- [![Version](https://img.shields.io/badge/version-1.5.1-3b82f6.svg?style=flat-square)](package.json)
12
+ [![Version](https://img.shields.io/badge/version-1.6.1-3b82f6.svg?style=flat-square)](package.json)
13
13
  [![License: MIT](https://img.shields.io/badge/License-MIT-10b981.svg?style=flat-square)](LICENSE)
14
14
  [![DSH Compatibility](https://img.shields.io/badge/DSH-%E2%89%A50.1.1--rc.2%20%C2%B7%20%E5%B7%B2%E9%80%82%E9%85%8D%200.1.5--rc.1-6366f1.svg?style=flat-square)](https://github.com/deepseek-ai/deepseek-harness)
15
15
  [![Cordis](https://img.shields.io/badge/Cordis-v4.x-f59e0b.svg?style=flat-square)](https://cordis.moe/)
@@ -42,7 +42,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
42
42
  - [🚀 功能](#-功能)
43
43
  - [版本与更新](#版本与更新) · [安全重启](#安全重启) · [健康诊断](#健康诊断) · [模型统计](#模型统计)
44
44
  - [额度查询](#额度查询) · [备份管理](#备份管理) · [技能管理](#技能管理) · [子代理模型](#子代理模型)
45
- - [任务通知](#任务通知) · [会话管理](#会话管理) · [移动端适配](#移动端适配) · [外部探活](#外部探活)
45
+ - [任务通知](#任务通知) · [会话管理](#会话管理) · [移动端适配](#移动端适配) · [右栏文件编辑](#右栏文件编辑) · [外部探活](#外部探活)
46
46
  - [🏗️ 架构](#-架构)
47
47
  - [⚡ 安装](#-安装) · [🔄 自动重启配置](#-自动重启配置) · [🖥️ 平台支持](#-平台支持)
48
48
  - [🔒 安全设计](#-安全设计) · [❓ 常见问题 FAQ](#-常见问题-faq) · [🤝 参与贡献](#-参与贡献) · [📄 许可证](#-许可证)
@@ -51,14 +51,14 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
51
51
 
52
52
  设置页「服务控制」面板六页导航:**概览 · 模型统计 · 额度查询 · 健康诊断 · 维护 · 配置**;其中「维护」聚合 会话管理 · 技能 · 子代理 · 备份维护 · 重启 五个子页,「配置」聚合 功能开关 · 任务通知 两个子页。重启、额度查询、会话管理可另行开启**设置页左列快捷入口**(默认关闭;技能与子代理的左列入口已撤销)。
53
53
 
54
- 「插件 → 插件配置」提供十个宿主级开关:**健康诊断、模型统计、额度查询、备份维护、任务通知、技能管理、子代理模型、会话管理、移动端适配、`/healthz` 探活**(除移动端适配外默认开启)。全部热生效:关闭即隐藏界面、停止轮询并让宿主拒绝对应能力;概览与重启固定保留。
54
+ 「插件 → 插件配置」提供十一个宿主级开关:**健康诊断、模型统计、额度查询、备份维护、任务通知、技能管理、子代理模型、会话管理、移动端适配、右栏文件编辑、`/healthz` 探活**(除移动端适配外默认开启)。全部热生效:关闭即隐藏界面、停止轮询并让宿主拒绝对应能力;概览与重启固定保留。
55
55
 
56
56
  ![插件配置](./screenshots/plugin-config.png)
57
57
 
58
58
  ### 概览(六段式)
59
59
 
60
60
  - 状态摘要(error → warning → info → normal 聚合,带状态点)→ 可行动项(仅在存在时)→ 版本与运行环境 → 指标格 → 固定核心操作(健康检查 / 额度查询 / 创建备份,随功能开关门控)→ 近期报错(仅非空时渲染,默认折叠)
61
- - 状态聚合规则:健康/诊断/备份/统计/额度/重启任一失败即 error;权限异常、非咨询性诊断警告为 warning;可更新、手动启动环境、尚无备份为 info(额度窗口高占用只在额度查询页内以进度条呈现,不再进概览提醒)
61
+ - 状态聚合规则:健康/诊断/备份/统计/额度/重启任一失败即 error;权限异常、非咨询性诊断警告为 warning;可更新、尚无备份为 info(额度窗口高占用只在额度查询页内以进度条呈现;疑似终端手动启动属常驻环境事实,也只在健康诊断检查项与重启/升级确认中呈现——两者都不再进概览提醒)
62
62
 
63
63
  ### 维护与配置聚合页
64
64
 
@@ -74,6 +74,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
74
74
  - 显示当前 DSH 与插件版本,链接 GitHub Releases
75
75
  - 自动检查 npm **正式版 + 预览版**(latest / next 双 tag);有新版本时行内展开对比,版本号附 npmjs 与 npmmirror 双链接
76
76
  - 一键升级,完成后自动重启;未检测到进程管理器时先确认后果,保持运行并提示手动重启
77
+ - 升级落地但进程尚未重启期间(手动启动环境尤为常见),版本行改示「已安装 X,重启后生效」并收起升级按钮,重开面板或刷新页面状态依旧;重启进程后恢复常态
77
78
 
78
79
  ### 安全重启
79
80
 
@@ -130,6 +131,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
130
131
  - 凭据写入 DSH 凭据库(`$DSH_HOME/.credentials.yaml`,热生效):普通适配填 API key,CLIProxyAPI 填管理密钥,小米填控制台 Cookie,StepFun Step Plan 填控制台令牌(Oasis-Token,`Oasis-Webid` 由令牌自动派生无需手填)
131
132
  - 防风控:结果缓存 60 秒、失败指数退避(30 秒 ×2、封顶 15 分钟);自动查询可调为仅手动 / 1 / 2 / 5 / 10 分钟
132
133
  - CLIProxyAPI 某账号实时查询失败时,回退显示其上次缓存的快照窗口并标注「缓存」徽标;重置时间已过的快照窗口(快照描述的窗口已结束)直接丢弃,避免「额度停在昨天」的错觉
134
+ - 失败原因如实呈现:卡片与圆环显示「错误文案(HTTP 状态 · 失败端点 · 失败账号 · 上游原话)· 下次自动重试时刻」——错 key、欠费、限流、路径变更各有各的上游原话与状态码,不再只有一个笼统提示;上游 401/403 判为「凭据被上游拒绝」,卡片同时保留凭据填写入口
133
135
  - API key 只在宿主进程内解析,浏览器仅收到归一化窗口数据;未适配的供应商绝不发起请求
134
136
 
135
137
  ### 备份管理
@@ -180,7 +182,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
180
182
 
181
183
  ![会话管理](./screenshots/session-manager.png)
182
184
 
183
- - **查看**:统一列表展示会话(运行中 / 冷会话 / 已归档),行内标状态徽章、工作区、事件数、文件体积;列表支持按创建时间正/倒序、按标题排序或**按项目分区显示**(每个工作区一个分区头:路径 + 会话数,同项目内最新在前;分区**默认折叠**,点击分区头展开 / 收起);**默认停在「仅归档」视图**,全部 / 仅归档 / 已删除三个筛选各自**首次**按需向宿主拉取对应子集并缓存(模块级缓存:切换筛选零请求、**关掉面板再打开秒显缓存 + 后台静默刷新一次保鲜**,页面刷新才清零),「刷新」按钮可强制重拉当前视图;普通列表提供「批量选择」按钮,进入后可直接点击整条会话(无需精确点复选框)进行选择 / 取消选择,也可一键全选 / 取消全选当前筛选结果,选中行以左侧品牌色标记而不改变背景;工具栏按资格显示可执行数量并支持批量导出 / 归档 / 删除(切换筛选、搜索或进入详情会自动退出批量态);文件体积不随列表下发、行内按需懒加载(模块级 + 宿主进程内存双层缓存:刷新浏览器 / 重开面板直接复用,删除时失效);**进详情记住列表滚动位置,返回列表原地不动**(沿用官方面板滚动容器,详情期间切筛选 / 改搜索则放弃恢复);详情按事件卡片分页浏览(宿主单槽位快照缓存:翻页/重进详情零重复读取,live 会话 30 秒内保鲜),**正文按官方 Markdown 富文本渲染**(复用平台官方渲染器 `MarkdownText`,与聊天界面观感一致:代码块/列表/表格/数学公式、默认拒原始 HTML 与危险链接;老版本 DSH 未提供该渲染器时自动回落纯文本),连续系统事件默认折叠为计数块、点击展开明细
185
+ - **查看**:统一列表展示会话(运行中 / 冷会话 / 已归档),行内标状态徽章、工作区、事件数、文件体积;列表支持按创建时间正/倒序、按标题排序或**按项目分区显示**(每个工作区一个分区头:路径 + 会话数,同项目内最新在前;分区**默认折叠**,点击分区头展开 / 收起);**默认停在「仅归档」视图**,全部 / 仅归档 / 已删除三个筛选各自**首次**按需向宿主拉取对应子集并缓存(模块级缓存:切换筛选零请求、**关掉面板再打开秒显缓存 + 后台静默刷新一次保鲜**,页面刷新才清零),「刷新」按钮可强制重拉当前视图;普通列表提供「批量选择」按钮,进入后可直接点击整条会话(无需精确点复选框)进行选择 / 取消选择,也可一键全选 / 取消全选当前筛选结果,选中行以左侧品牌色标记而不改变背景;工具栏按资格显示可执行数量并支持批量导出 / 归档 / 删除(切换筛选、搜索或进入详情会自动退出批量态);文件体积不随列表下发、行内按需懒加载(模块级 + 宿主进程内存双层缓存:刷新浏览器 / 重开面板直接复用,删除时失效);**进详情记住列表滚动位置,返回列表原地不动**(沿用官方面板滚动容器,详情期间切筛选 / 改搜索则放弃恢复);详情按事件卡片分页浏览(宿主单槽位快照缓存:翻页/重进详情零重复读取,live 会话 30 秒内保鲜),**正文按官方 Markdown 富文本渲染**(复用平台官方渲染器 `MarkdownText`,与聊天界面观感一致:代码块/列表/表格/数学公式、默认拒原始 HTML 与危险链接;老版本 DSH 未提供该渲染器时自动回落纯文本),连续系统事件与**工具消息各自默认折叠为计数块**(工具消息 = `tool/call`、`tool/result` 等 `tool/*` 事件,以及通篇只有工具调用的 assistant 消息——这类消息占真实长会话的多数,工具参数不会再铺满详情页),点击折叠行展开明细、再点收起;搜索命中落在折叠块内时该块自动展开并保持命中高亮
184
186
  - **导出**:一键或批量下载官方完整 ZIP(每个会话一个 ZIP,含子代理与附件),复用官方导出链路,宿主不自己拼包
185
187
  - **归档**:单项或批量归档非运行中会话;归档后从官方侧栏隐藏(官方行为),官方不支持恢复
186
188
  - **内容搜索**:对话全文语义搜索(大小写不敏感、空白灵活),跨会话命中列表(匹配文本高亮;多命中显示 seq 位置芯片、可一键直达)→ **命中窗口视图**:打开即以命中 seq 为中心展示上下文窗口(命中前后各 15 条事件;命中行标「命中」徽章高亮、**自动滚动定位并闪烁 2 秒**),支持**上一个 / 下一个命中**翻跳与导航条 seq 芯片直达(参考 dsh-session-kb 的 Locate 交互);窗口可继续加载后续事件;可限定仅搜归档区
@@ -194,13 +196,27 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
194
196
 
195
197
  - 默认关闭;仅在视口 <1024px(手机竖屏 / 窄窗口)生效,桌面完全无感
196
198
  - 侧栏变抽屉、详情列移动端隐藏(对齐官方窄屏语义)、模态变全屏面板、设置左列导航变顶部横滑
197
- - 滑动沉浸:会话内下滑自动收起头部与输入框全屏阅读,上滑 / 回到底部 / 聚焦输入框即恢复,底部常驻小把手可随时点开合;流式贴底、锚点跳转等程序化滚动绝不误触发
199
+ - 模型选择按钮在手机上收成图标(≤480px,与官方窄容器同形态;481px 以上仍显示模型名与推理等级)——插件移动端把中列拉宽,官方 `@container (width<=360px)` 那条收起规则在 428~440px 机型上永远不会触发,故显式对齐官方窄容器形态
200
+ - 统计条(输入框下方「轮/步/tok/s | tok/缓存命中」)在手机上**保持一行并把宽度用满**:收紧这一行自身的左右内边距(官方 32px→2px)与列间距,两枚统计按需分宽、共占满整行——≥~420px 视口零截断,更窄视口按比例各让一点(远少于官方的固定截断),不换行、不横向滚动(桌面不受影响)
201
+ - 滑动沉浸:会话内下滑自动收起头部与输入框全屏阅读(收起时让出输入框占位,正文真正铺满整屏;回显时若仍停在会话末尾会自动对齐到底),上滑 / 点「回到底部」浮钮 / 聚焦输入框即恢复(无额外悬浮钮);已经停在会话末尾时往回一点即回显(不再等满阈值),点回底后停留位置会补一次贴底对齐;流式贴底、锚点跳转等程序化滚动绝不误触发
198
202
  - 滑动开合抽屉:双抽屉关闭时,横移主导的右滑任意位置打开侧栏抽屉、左滑任意位置打开官方右侧栏(DSH 0.1.5+,未就绪时该方向无效);开启后反向横滑任意位置关闭;从屏幕边缘起滑额外享有浏览器手势接管的补完加成,编辑器等真横滚区内的滑动不误触发
199
203
  - 「回到底部」浮钮右移贴边(不再空出大片右侧留白);其上方新增同款圆形上箭头(全平台生效,不含移动端),点击逐条跳转上一条用户回复、可连续向上回溯,目标在未加载历史时会自动点「加载更早」补齐,跳到最顶部后按钮自动隐藏、下滑即复现
200
204
  - 大 JSON 响应透明压缩(≥4KB 按 `Accept-Encoding` 自动 gzip/brotli),长会话历史首屏提速
201
205
  - 自动补 `viewport-fit=cover` 避让刘海、禁双击缩放、输入框 ≥16px 防 iOS 聚焦放大
202
206
  - `?dshsvc-mobile-debug=1` 显示浮动诊断条(仅调试)
203
207
 
208
+ ### 右栏文件编辑
209
+
210
+ - 官方右侧栏的文件预览头部**右上角多一个「编辑」按钮**(紧邻渲染器名),点一下就进编辑模式:等宽编辑器,带脏标记、`Ctrl/Cmd + S` 保存、「重新加载」「撤销保存」,以及一键「预览」返回官方渲染器
211
+ - 另外两条等价入口:原来的**渲染器下拉**里选「编辑」,以及**右键标签 → ⋯ 菜单 →「编辑」**(后者走官方菜单座、不做任何 DOM 注入,是头部按钮失效时的兜底路径);处于编辑档位时头部按钮自动收起,不会重复
212
+ - **不改变官方渲染器的默认地位**:`.md`、`.js` 等官方有专属渲染器的后缀默认仍是官方预览(Markdown / 代码…);只有官方没有专属渲染器、本来落到「纯文本」的后缀(如 `.txt`、`.log`、`.conf`)才默认进编辑器。官方预览未挂载(旧版 DSH)时整块静默不出现
213
+ - **写盘走会话自己的文件服务与沙箱策略**:浏览器只送 `dsh-resource://file/session/<会话>/<路径>` 资源地址,会话与工作区根由宿主解析,不接受自由路径;保存携带读取时的版本号,**磁盘已被 Agent 或其他窗口改过就拒绝覆盖**,由你选「重新加载(丢弃修改)」或「用我的内容覆盖」;只读沙箱会话只能预览
214
+ - **保存不中断输入**:保存期间仍可继续编辑,响应只确认本次提交的内容,后续输入保留为「未保存」;状态区分「保存中 / 未保存 / 已保存」。冲突出现后仍可修改,覆盖保存使用编辑器里的最新草稿
215
+ - **离开前保护草稿**:通过编辑器自己的「预览」「重新加载」按钮离开或重读时,若有未保存内容先显示内联确认,可取消继续编辑;「撤销保存」也先确认,且保留版本守卫,不静默覆盖磁盘上的新改动
216
+ - 单文件上限 2 MiB(超过只读);会话未激活或沙箱策略服务不可用时不可编辑(仍可使用官方预览)
217
+ - 首版**不做**:语法高亮、多光标、查找替换(插件半没有打包器,借不到编辑器组件),关闭标签不弹未保存确认
218
+ - 开关在 插件 → 插件配置 → 交互(默认开,热生效)
219
+
204
220
  ### 外部探活
205
221
 
206
222
  - `GET` / `HEAD /healthz` 返回空 200,其他方法返回 405
@@ -312,7 +328,7 @@ pm2 start "dsh web --host 127.0.0.1" --name dsh-web
312
328
 
313
329
  | 领域 | 边界 |
314
330
  | --- | --- |
315
- | 输入 | 浏览器不能传入 URL、包名、命令或文件路径 |
331
+ | 输入 | 浏览器不能传入 URL、包名、命令或文件路径。**唯一例外**:右栏文件编辑只接受 `dsh-resource://file/session/<会话>/<路径>` 资源地址(逐段解码、拒绝其他形态),会话与工作区根一律宿主侧解析,写盘再经会话沙箱策略围栏 |
316
332
  | 网络 | 更新检查只访问固定 npm registry 地址 |
317
333
  | RPC | 仅接受 loopback 调用,数据不出本机 |
318
334
  | 数据 | 用量索引不保存消息、Prompt、工具参数或凭据;API key 只在宿主进程内使用 |
@@ -340,7 +356,7 @@ pm2 start "dsh web --host 127.0.0.1" --name dsh-web
340
356
  </details>
341
357
 
342
358
  <details>
343
- <summary><strong>小米卡片显示「控制台 Cookie 已失效」?</strong></summary>
359
+ <summary><strong>小米卡片显示「凭据被上游拒绝」?</strong></summary>
344
360
 
345
361
  网页登录态过期了。重新登录 platform.xiaomimimo.com,从任意 `/api/v1/tokenPlan/` 请求复制 `Cookie:` 头,点卡片「填写控制台 Cookie」重新粘贴。
346
362
  </details>
@@ -352,7 +368,7 @@ Step Plan 订阅没有 API-key 形态的查询接口,需要网页登录态令
352
368
  </details>
353
369
 
354
370
  <details>
355
- <summary><strong>StepFun Step Plan 卡片显示「控制台登录态已失效」?</strong></summary>
371
+ <summary><strong>StepFun Step Plan 卡片显示「凭据被上游拒绝」?</strong></summary>
356
372
 
357
373
  令牌过期了(官方常见报错 `oasis-token is embezzled` 即令牌与 web_id 不匹配)。重新登录 platform.stepfun.com 后从 Cookies 复制新的 `Oasis-Token` 完整值再粘贴;从控制台复制时若自带 `Oasis-Token=` 或 `Cookie: ` 前缀会被自动剥离,不影响。
358
374
  </details>