@gehennawu/dsh-service 1.6.2 → 1.7.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 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.6.2-3b82f6.svg?style=flat-square)](package.json)
12
+ [![Version](https://img.shields.io/badge/version-1.7.0-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.6--alpha.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/)
@@ -49,15 +49,15 @@ A service-control and operations plugin for DSH Web: safe restart, version manag
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
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
- ### Overview (six sections)
58
+ ### Overview
59
59
 
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)
60
+ - Status summary (error → warning → info → normal aggregation with a status dot) → actionable items (only when present) → version and runtime → metrics grid → recent errors (rendered only when non-empty, collapsed by default)
61
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
@@ -67,7 +67,8 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
67
67
  ![Configuration page](./screenshots/configuration_en.png)
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 task notifications; switches are grouped and apply live, while the Notifications entry stays visible but disabled when that feature is off
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, with every label shown in the active interface language only (a third-party plugin registering a static `中文 / English` string contributes just its current-language half, so narrow mobile viewports no longer truncate it), 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)
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
 
@@ -124,12 +125,13 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
124
125
  | StepFun Balance | Official `GET /v1/accounts` (API key, com/ai dual domains) |
125
126
  | StepFun Step Plan | Console BFF subscription quota (Oasis-Token console session; 5-hour/weekly windows vs Credit pool auto-detected) |
126
127
  | Xiaomi MiMo Token Plan | Console-origin plan quota (web session cookie) |
128
+ | Command Code (command-goat) | Official account quota plane `api.commandcode.ai/alpha/*` (same key reused: balance + period spend + plan + 5-hour/weekly windows) |
127
129
  | CLIProxyAPI deployment | Official remaining quota of each OAuth upstream account |
128
130
 
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)
131
+ - 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
132
  - 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
133
  - 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
134
+ - 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
135
  - API keys are resolved only inside the host process; the browser receives normalized window data only; unadapted providers are never requested
134
136
 
135
137
  ### Backup management
@@ -149,6 +151,7 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
149
151
  ![Skills management](./screenshots/skill-manager_en.png)
150
152
 
151
153
  - Lists local skills in three sections — **auto-loaded / manual-only / fully disabled**; same-name shadowing marks both copies, bundled directories are read-only
154
+ - 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
155
  - Two switches edit the SKILL.md frontmatter directly (`disable-model-invocation` / `user-invocable`); changes go live within ~200 ms
153
156
  - Entries with legacy camelCase keys are dropped by the official parser: ⚠ warning + one-click canonical fix
154
157
  - ✨ 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
@@ -196,6 +199,7 @@ Under **Plugins → Plugin configuration**, eleven host-level switches: **Health
196
199
  ![Session manager](./screenshots/session-manager_en.png)
197
200
 
198
201
  - **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)
202
+ - **Subagent recognition**: sessions delegated to subagents carry a “Subagent” badge (the marker comes from official session header fields: `origin=subagent` is the product classification, with `delegationDepth` as the fallback for older logs; a plain fork lineage carrying only `parentSession` does not count); a “Subagents only” checkbox in the search row focuses the list (same row and widget language as “search archived only”; an orthogonal qualifier layered on top of All / Archived — hidden in the Deleted view, and its state survives view switches), and batch mode offers “Select subagents” to fold every visible subagent session into the selection (without clearing existing picks; the button stays hidden when no subagent rows are visible) for quick batch archive / delete cleanups; on older plugin hosts that do not ship the flag the list behaves as before, and enabling the qualifier explains that the host is outdated and carries no subagent flags instead of showing an unexplained empty list
199
203
  - **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
200
204
  - **Archive & unarchive**: archive one or many non-running sessions, hiding them from the official sidebar; hosts running DSH ≥0.1.6 support unarchiving individually or in batches, while older DSH hosts keep the one-way notice
201
205
  - **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
@@ -353,6 +357,12 @@ It is the "likely manual terminal launch" detection — no process manager found
353
357
  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.
354
358
  </details>
355
359
 
360
+ <details>
361
+ <summary><strong>Command Code shows "credential rejected by upstream"?</strong></summary>
362
+
363
+ 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.
364
+ </details>
365
+
356
366
  <details>
357
367
  <summary><strong>Xiaomi shows "credential rejected by upstream"?</strong></summary>
358
368
 
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.6.2-3b82f6.svg?style=flat-square)](package.json)
12
+ [![Version](https://img.shields.io/badge/version-1.7.0-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.6--alpha.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/)
@@ -49,15 +49,15 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
49
49
 
50
50
  ## 🚀 功能
51
51
 
52
- 设置页「服务控制」面板六页导航:**概览 · 模型统计 · 额度查询 · 健康诊断 · 维护 · 配置**;其中「维护」聚合 会话管理 · 技能 · 子代理 · 备份维护 · 重启 五个子页,「配置」聚合 功能开关 · 任务通知 两个子页。重启、额度查询、会话管理可另行开启**设置页左列快捷入口**(默认关闭;技能与子代理的左列入口已撤销)。
52
+ 设置页「服务控制」面板六页导航:**概览 · 模型统计 · 额度查询 · 健康诊断 · 维护 · 配置**;其中「维护」聚合 会话管理 · 技能 · 子代理 · 备份维护 · 重启 五个子页,「配置」聚合 功能开关 · 任务通知 · 设置栏标签 三个子页。重启、额度查询、会话管理可另行开启**设置页左列快捷入口**(默认关闭;技能与子代理的左列入口已撤销)。
53
53
 
54
54
  「插件 → 插件配置」提供十一个宿主级开关:**健康诊断、模型统计、额度查询、备份维护、任务通知、技能管理、子代理模型、会话管理、移动端适配、右栏文件编辑、`/healthz` 探活**(除移动端适配外默认开启)。全部热生效:关闭即隐藏界面、停止轮询并让宿主拒绝对应能力;概览与重启固定保留。
55
55
 
56
56
  ![插件配置](./screenshots/plugin-config.png)
57
57
 
58
- ### 概览(六段式)
58
+ ### 概览
59
59
 
60
- - 状态摘要(error → warning → info → normal 聚合,带状态点)→ 可行动项(仅在存在时)→ 版本与运行环境 → 指标格 → 固定核心操作(健康检查 / 额度查询 / 创建备份,随功能开关门控)→ 近期报错(仅非空时渲染,默认折叠)
60
+ - 状态摘要(error → warning → info → normal 聚合,带状态点)→ 可行动项(仅在存在时)→ 版本与运行环境 → 指标格 → 近期报错(仅非空时渲染,默认折叠)
61
61
  - 状态聚合规则:健康/诊断/备份/统计/额度/重启任一失败即 error;权限异常、非咨询性诊断警告为 warning;可更新、尚无备份为 info(额度窗口高占用只在额度查询页内以进度条呈现;疑似终端手动启动属常驻环境事实,也只在健康诊断检查项与重启/升级确认中呈现——两者都不再进概览提醒)
62
62
 
63
63
  ### 维护与配置聚合页
@@ -67,7 +67,8 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
67
67
  ![配置页](./screenshots/configuration.png)
68
68
 
69
69
  - 「维护」集中会话管理、技能、子代理、备份维护与重启;记住最近使用的子页,关闭对应功能后自动回退到仍可用的项目
70
- - 「配置」集中功能开关与任务通知;开关按功能组展示并热生效,任务通知关闭时保留入口但显示置灰状态
70
+ - 「配置」集中功能开关、任务通知与设置栏标签;开关按功能组展示并热生效,任务通知关闭时保留入口但显示置灰状态,设置栏标签支持对设置弹窗左侧全部导航标签进行手动排序(拖拽/上下箭头换位)与显隐管理,标签按当前界面语言单语显示(外部插件注册成 `中文 / English` 静态双语串时只取当前语言一侧,移动端窄屏不再被截断),配置持久化到服务端统一配置文件 `$DSH_HOME/dsh-service-config.json`(多设备同步、启动自动拉取,本地缓存兜底),即时生效(服务控制面板永久锁定显示防锁死)
71
+ - 插件统一配置文件:各功能的轻量偏好收敛在 `$DSH_HOME/dsh-service-config.json` 单一文件(原子写入、`0600`),按功能分区块隔离——修改或清除某一区块绝不影响其他区块;大缓存(使用统计索引等)与加密凭据不在此文件内
71
72
 
72
73
  ### 版本与更新
73
74
 
@@ -126,12 +127,13 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
126
127
  | StepFun 余额 | 官方 `GET /v1/accounts`(API key,com/ai 双域) |
127
128
  | StepFun Step Plan | 控制台 BFF 订阅额度(Oasis-Token 登录令牌;5 小时/周窗口与 Credit 月池自动识别) |
128
129
  | 小米 MiMo Token Plan | 控制台同源套餐额度(网页登录态 Cookie) |
130
+ | Command Code(command-goat) | 官方账号额度面 `api.commandcode.ai/alpha/*`(同 key 复用:余额 + 本周期花费 + 套餐 + 5 小时/周窗口) |
129
131
  | CLIProxyAPI 部署 | 各 OAuth 上游账号官方剩余额度 |
130
132
 
131
- - 凭据写入 DSH 凭据库(`$DSH_HOME/.credentials.yaml`,热生效):普通适配填 API key,CLIProxyAPI 填管理密钥,小米填控制台 Cookie,StepFun Step Plan 填控制台令牌(Oasis-Token,`Oasis-Webid` 由令牌自动派生无需手填)
133
+ - 凭据写入 DSH 凭据库(`$DSH_HOME/.credentials.yaml`,热生效):普通适配填 API key,CLIProxyAPI 填管理密钥,小米填控制台 Cookie,StepFun Step Plan 填控制台令牌(Oasis-Token,`Oasis-Webid` 由令牌自动派生无需手填);Command Code 额度面与推理面同一把 key,无需另配
132
134
  - 防风控:结果缓存 60 秒、失败指数退避(30 秒 ×2、封顶 15 分钟);自动查询可调为仅手动 / 1 / 2 / 5 / 10 分钟
133
135
  - CLIProxyAPI 某账号实时查询失败时,回退显示其上次缓存的快照窗口并标注「缓存」徽标;重置时间已过的快照窗口(快照描述的窗口已结束)直接丢弃,避免「额度停在昨天」的错觉
134
- - 失败原因如实呈现:卡片与圆环显示「错误文案(HTTP 状态 · 失败端点 · 失败账号 · 上游原话)· 下次自动重试时刻」——错 key、欠费、限流、路径变更各有各的上游原话与状态码,不再只有一个笼统提示;上游 401/403 判为「凭据被上游拒绝」,卡片同时保留凭据填写入口
136
+ - 失败原因如实呈现:卡片与圆环显示「错误文案(HTTP 状态 · 失败端点 · 失败账号 · 上游原话)· 下次自动重试时刻」——错 key、欠费、限流、路径变更各有各的上游原话与状态码,不再只有一个笼统提示;上游 401/403 判为「凭据被上游拒绝」,卡片同时保留凭据填写入口;HTTP 200 业务信封里的错误码同样定族——鉴权失败判凭据被拒(保留填写入口)、套餐到期判无生效订阅、上游自身故障判「上游服务故障」,不再一律报「响应格式异常」
135
137
  - API key 只在宿主进程内解析,浏览器仅收到归一化窗口数据;未适配的供应商绝不发起请求
136
138
 
137
139
  ### 备份管理
@@ -151,6 +153,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
151
153
  ![技能管理](./screenshots/skill-manager.png)
152
154
 
153
155
  - 按 **自动加载 / 仅手动调用 / 完全停用** 三区展示本地技能;同名遮蔽与被遮蔽副本均有标注,内置目录只读
156
+ - 条目默认全部折叠成一行(名称 + 来源/只读/已注释徽标);顶部按钮对当前可见条目一键「全部展开 / 全部折叠」,点单条名称行可独立开合;无效条目的 ⚠ 与一键修复折叠态也保留
154
157
  - 双开关直接改写 SKILL.md frontmatter(`disable-model-invocation` / `user-invocable`),约 200ms 热生效
155
158
  - 带 camelCase 旧版键的条目会被官方解析器剔除:⚠ 提示 + 一键修复
156
159
  - ✨ AI 补全说明:选模型生成描述草稿(跟随界面语言),确认后存入插件侧车索引——**绝不改写 SKILL.md**;支持一键批量补全(宿主后台运行、可取消)。已注释技能会在计划中单列,经「确认强制补全」二次确认后才会被覆盖(不再是一旦注释就永远无法再次补全);补全日志时间按本机时区显示
@@ -183,6 +186,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
183
186
  ![会话管理](./screenshots/session-manager.png)
184
187
 
185
188
  - **查看**:统一列表展示会话(运行中 / 冷会话 / 已归档),行内标状态徽章、工作区、事件数、文件体积;列表支持按创建时间正/倒序、按标题排序或**按项目分区显示**(每个工作区一个分区头:路径 + 会话数,同项目内最新在前;分区**默认折叠**,点击分区头展开 / 收起);**默认停在「仅归档」视图**,全部 / 仅归档 / 已删除三个筛选各自**首次**按需向宿主拉取对应子集并缓存(模块级缓存:切换筛选零请求、**关掉面板再打开秒显缓存 + 后台静默刷新一次保鲜**,页面刷新才清零),「刷新」按钮可强制重拉当前视图;普通列表提供「批量选择」按钮,进入后可直接点击整条会话(无需精确点复选框)进行选择 / 取消选择,也可一键全选 / 取消全选当前筛选结果,选中行以左侧品牌色标记而不改变背景;工具栏按资格显示可执行数量并支持批量导出 / 归档 / 删除(切换筛选、搜索或进入详情会自动退出批量态);文件体积不随列表下发、行内按需懒加载(模块级 + 宿主进程内存双层缓存:刷新浏览器 / 重开面板直接复用,删除时失效);**进详情记住列表滚动位置,返回列表原地不动**(沿用官方面板滚动容器,详情期间切筛选 / 改搜索则放弃恢复);详情按事件卡片分页浏览(宿主单槽位快照缓存:翻页/重进详情零重复读取,live 会话 30 秒内保鲜),**正文按官方 Markdown 富文本渲染**(复用平台官方渲染器 `MarkdownText`,与聊天界面观感一致:代码块/列表/表格/数学公式、默认拒原始 HTML 与危险链接;老版本 DSH 未提供该渲染器时自动回落纯文本),连续系统事件与**工具消息各自默认折叠为计数块**(工具消息 = `tool/call`、`tool/result` 等 `tool/*` 事件,以及通篇只有工具调用的 assistant 消息——这类消息占真实长会话的多数,工具参数不会再铺满详情页),点击折叠行展开明细、再点收起;搜索命中落在折叠块内时该块自动展开并保持命中高亮
189
+ - **子代理识别**:派生的子代理会话行内标「子代理」徽章(判定取自官方会话头字段:`origin=subagent` 产品分类为准,`delegationDepth` 派生深度兜底老日志;仅 `parentSession` 的普通 fork 血统不算子代理);搜索行「仅子代理」复选框聚焦(与「仅搜归档」同行同款控件;正交于全部 / 仅归档叠加过滤,已删除视图不显示、切换视图时状态保留),批量选择态提供「选中子代理」一键把当前可见的子代理会话并入选择集(不清既有选择;视图里没有子代理行时该按钮隐藏),配合批量归档 / 删除快速清理;老版本插件宿主不下发该标志时列表照常,勾选筛选会明示「宿主较旧、未携带子代理标志」而非留一份无解释的空列表
186
190
  - **导出**:一键或批量下载官方完整 ZIP(每个会话一个 ZIP,含子代理与附件),复用官方导出链路,宿主不自己拼包
187
191
  - **归档与恢复**:单项或批量归档非运行中会话,归档后从官方侧栏隐藏;DSH ≥0.1.6 宿主支持单项或批量恢复(取消归档),老版本 DSH 保持单向归档提示
188
192
  - **内容搜索**:对话全文语义搜索(大小写不敏感、空白灵活),跨会话命中列表(匹配文本高亮;多命中显示 seq 位置芯片、可一键直达)→ **命中窗口视图**:打开即以命中 seq 为中心展示上下文窗口(命中前后各 15 条事件;命中行标「命中」徽章高亮、**自动滚动定位并闪烁 2 秒**),支持**上一个 / 下一个命中**翻跳与导航条 seq 芯片直达(参考 dsh-session-kb 的 Locate 交互);窗口可继续加载后续事件;可限定仅搜归档区
@@ -355,6 +359,12 @@ pm2 start "dsh web --host 127.0.0.1" --name dsh-web
355
359
  点击卡片上的内联表单写入凭据:普通适配填 API key,CLIProxyAPI 填管理密钥(不是代理 key),小米 Token Plan 填控制台 Cookie。写入 DSH 凭据库后自动强制刷新;被进程环境变量遮蔽时宿主会拒绝写入,需改环境变量本身。
356
360
  </details>
357
361
 
362
+ <details>
363
+ <summary><strong>Command Code 卡片显示「凭据被上游拒绝」?</strong></summary>
364
+
365
+ 推理面和额度面共用同一把 key(`user_*` 前缀,Studio 的 API keys 页生成)。卡片显示该错误说明 key 被上游判为无效:到 commandcode.ai 的 Studio 重新生成或复制 key,点卡片「填写 API 密钥」粘贴即可。若渠道 baseURL 指向的是自建中转而非 `api.commandcode.ai`,额度面仍固定查官方账号面——中转 key 查不到官方额度。
366
+ </details>
367
+
358
368
  <details>
359
369
  <summary><strong>小米卡片显示「凭据被上游拒绝」?</strong></summary>
360
370
 
@@ -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