Files
apes-sidebar/docs/wiki/03-功能说明.md
T
figmar 66ee3953c9 feat(apes): revive the task/message tabs in the info layer
C6 removed apes:tasks as a duplicate of the host session panel; in practice the two answer different questions (host panel = switch workspaces, plugin tab = who is running right now), so the tab is restored and the info layer goes back to five types.

tasks: live session list (current / running / subagent markers) + showInactive toggle via pluginSettings['apes:tasks']; messages: placeholder that states the host has no message feed yet; both get badge counters, and the whole layer now honours the visible gate (auto-collapse) so hidden tabs stop waking on session events.

zh/en/ja dictionaries in sync (AGENTS 5); wiki 02/03/07 reverted from three to five tabs; decision record in docs/plans/2026-10-11-apes-tab-revival.md.
2026-10-11 21:18:08 +08:00

7.4 KiB
Raw Blame History

03 · 功能说明

本篇是功能清单与行为契约:有哪些面板、数据从哪来、文案与配色怎么走、安全边界在哪、能配什么。

一、面板与标签页总表

「来源」列:上游 = 来自 dsh-better-sidebar;宿主 = DSH 自身提供并占用该槽位;本 fork = 本项目的增量。

id 名称 order 来源 数据 / 行为
editor 文件 10 上游 文件树 + 编辑器(CodeMirror 系,懒加载 client-editor)
git 文件变动 20 上游 工作区变更、单个 diff 视图
subagent 子代理 30 上游 会话的子代理视图
sidechat 侧边对话 35 上游 会话内旁路对话
terminal 终端 40 上游 PTY 终端(懒加载 client-terminal;v0.24.1 线起由宿主内置终端承担)
browser 浏览器 50 上游 内嵌浏览器/HTML 预览宿主
diff (内部) -1 上游 非用户可见,供内部打开 diff
apes:tasks 任务 55 本 fork 会话列表(当前 / 运行中 / 子智能体标记,showInactive 开关;角标 = 运行中会话数)
apes:agents 智能体 60 本 fork 主代理 + 直系子代理拓扑(角标 = 直系子代理数)
apes:apps 应用 65 本 fork 当前会话所属工作区(宿主暂无「应用」feed)
apes:messages 消息 67 本 fork 消息流占位(宿主暂无消息流 feed)
apes:profile 画像 70 本 fork 当前会话摘要(标题 / cwd / 运行态)

order 10–50 是上游/宿主既定带宽,apes 信息层取 55/60/65/67/70 留出余量,避免与原生面板抢占位置。

二、信息层五 tab(本 fork 的增量)

五个 tab 全部是单实例(single: true),且都按 DSH 标准 TabDescriptor 注册, 因此自动获得原生侧边栏的全部待遇:进入原生 guide、tab 芯片带图标、可开合与分栏。

tab 展示内容 数据来源 空态
apes:tasks 会话行;当前会话排首位,其次运行中、再次空闲;行上带「当前 / 运行中 / 子智能体」标记;点击切换会话 ctx.sessions.list 快照(byId + current) 「当前没有会话」提示
apes:agents 根(主代理)卡片 + 其直系子代理卡片;每行显示标签、one-shot/continuable、运行态圆点 ① ctx.sessions.list 的 byId(durable 会话摘要);② 宿主的会话投影 projectionsBySession[sessionId].values.subagentCatalog(直系子代理清单) 「当前会话没有子代理」提示
apes:apps 当前会话的工作区(cwd) byId[scope.sessionId].cwd,回退 scope.cwd 明确写出「宿主今日无应用 feed」
apes:messages 仅标题与说明(同 apes:apps 的占位策略) —— 明确写出「宿主今日无消息流 feed」
apes:profile 会话标题、运行/空闲、cwd byId[scope.sessionId] 「无 cwd」提示

行为契约:apes:tasks / apes:agents 声明 badge(运行中会话数 / 直系子代理数,为 0 时不渲染角标), 其余三个 tab 不发角标;apes:tasks 额外声明 showInactive 开关,读写落在 prefs.pluginSettings['apes:tasks'] (缺省显示全部,值非布尔时按缺省处理)。隐藏的 tab 不订阅会话 feed(visible 门控), 因此后台 tab 不会被会话事件唤醒。

实现要点:两个来源被归一化成同一种行形状 { id, label, mode },活动态统一从 byId 读, 于是「投影已就绪」与「仅有 durable 摘要」两种情况下渲染一致;这也是上游 0.1.6→0.1.7 会话 feed 迁移(subagentsByParent → projectionsBySession、list.current 删除)后的落地方式。

三、文件预览器

id 适用 说明
image 图片 走媒体路由,受 mediaLimit 限制
pdf PDF 内嵌查看
markdown Markdown 渲染(Mermaid 走懒加载 chunk,可手动刷新)
html HTML 不透明源沙箱 iframe,见下节
code 代码 高亮查看(编辑器懒加载)
binary-download 二进制 只提供下载

3.1 HTML 预览的交付方式(重要)

路由 /sidebar/html/<session>/<path>    ← 路径围栏 + 体积上限(readLimit)
        │
        ├─ 主框架 fetch(唯一同时被宿主围栏信任、又能带上 Electron 头的角色)
        │
        ├─ 注入 <base href="<该文件的路由目录>">   ← 让 ./style.css 等相对引用解析回本文件所在目录
        │
        └─ iframe srcDoc=<文档> + sandbox=HTML_IFRAME_SANDBOX
状态 自包含 HTML 多文件 HTML(外链 CSS/JS/图片)
沙箱态(默认) ✅ 完整可用 正文可用,相对资源不可用(iframe 源为 null,子请求同样被宿主围栏拒绝)
临时解锁(无 sandbox 属性) ✅ ✅ 相对资源可用(iframe 继承 GUI 源,成为普通同源请求)

设计取舍:沙箱令牌一个字符都不放宽。多文件 HTML 想要完整效果需用户显式点「临时解锁」—— 这是把「放宽边界」的决定权留给用户的显式动作,而不是插件默认降级。

四、安全边界(三层)

层 机制 说明
预览内容 sandbox="allow-scripts allow-popups allow-downloads allow-modals" 不含 allow-same-origin:预览文档运行在不透明源里。宿主路由另有 CSP sandbox 兜底
插件路由 请求信任围栏(src/trust-fence.ts) 校验 Host 头/令牌,拒绝跨站或非授权来源对 /sidebar/* 的访问
桌面壳 Electron 注入的 x-dsh-desktop-renderer 头 扩展模式下所有路由的前置围栏;只发给主框架与同源子框架。这正是「沙箱 iframe 发不出请求」的根源

五、i18n 与主题

  • 语言包:src/client/locales.ts + 19 个 src/client/locales-*.ts 覆盖文件;默认 zh,缺省回退 en。
  • 本 fork 文案:集中在 src/client/apes/locales.ts,每个 key 同时提供 zh / en。
  • 硬性约定:界面里不得出现裸字符串,一律 t('key')。
  • 配色:只用宿主设计令牌 --dsw-alias-*(bg / border / label / state / interactive 系列), 写法为 var(--dsw-alias-xxx, <字面回退>),保证在非 DSH 环境(单元测试)也能渲染。 无公开的 --ds-* 几何令牌,字号/间距/圆角内联即可。

六、配置面(挂载行 config)

配置写在插件挂载行上(profile 的 cordis.patch.yml 或 bundle patch 的 insert 行),设置页写的也是它:

字段 默认 含义
readLimit 512 KiB 单文件读取上限(超出截断并标记 truncated)
mediaLimit 20 MiB 媒体(图片等)读取上限
uploadLimit 128 MiB 上传上限
listLimit 1000 目录列举条目上限
terminalsPerSession 3 每会话终端数上限
shell / shellArgs 自动解析 终端 shell 与其启动参数(shellArgs 非空时替换默认 -l)

例:在挂载行里指定 shell

- insert:
    - id: better-sidebar
      name: 'dsh-apes-sidebar'
      config:
        shell: /bin/zsh
        shellArgs: ['--noprofile', '--no-rc']