Chancel's blog

1863 字 7 分钟阅读

Status Sidebar 设计

  • opencode

OpenCode 通用状态侧边栏 产品说明

1. 目标与交付

  • 定位:在 OpenCode 原生 sidebar 上补充缺失信息,不重做原生面板。
  • 展示内容:当前订阅/API Key 的真实额度、余额或使用量;当前 Sub-agent 执行状态;当前会话实际调用过的 Skills;本机 Hostname。
  • 降级策略:Provider 无可靠额度信息则隐藏该 Provider;全部不可得则隐藏 USAGE 整块。
  • 交付形式:单文件 status-sidebar.tsx;若当前机制要求 .ts 则按实际处理。
  • 约束:不建独立项目、不加 daemon/server、不执行 npm/bun/pnpm add、不引入第三方 runtime dependency。仅用 OpenCode Plugin/TUI runtime、已暴露 UI/runtime、Node/Bun builtin、原生 fetchAbortController
  • 实现前检查:当前 OpenCode 文档、Plugin/TUI API、sidebar 扩展、session/message/part/task 结构、原生已显示信息、auth 与 provider 结构;基于当前实际 API,已有插件已实现则不重复。

2. 核心设计原则

  • 数据真实:Provider 返回什么就显示什么。不造 5h/Weekly/Balance/百分比;UI 不假设某 Provider“理论上应有什么”。
  • 动态 metric:实际返回 5 hours 才显示 5h,返回 weekly 才显示 Weekly,只有 Monthly AI Credits 就显示 Monthly
  • Usage 类型区分
    • Quota:可显示进度条。
    • Balance:直接显示,无总额不画 bar。
    • Budget:可显示 remaining/limit。
    • Spend:只显示 Spent,除非确定 budget,不转百分比。
    • Credits:按 Provider 单位展示。
  • 认证分开:Subscription/OAuth、API Key、Admin/Org credential 不共用 quota 逻辑。无法确认 credential/plan 不猜,只显示 OpenAIOpenAI · Subscription
  • 只补缺失:不重复原生 sidebar 已做好的功能。

3. 功能需求

USAGE

显示 Provider 实际提供的 quota/balance/budget/spend/credits/rate limit 等,动态生成。

每个 adapter 必须验证:认证方式、credential 类型、endpoint 有效性、response schema、字段语义、reset/window 含义、权限、Subscription/API 差异、plan/account 差异。能真实请求就验证;否则官方文档 + 当前 OpenCode 实现 + 参考插件三方交叉验证。

明确区分:

  • 已验证可获取
  • 条件可获取
  • 暂时失败
  • 认证不足
  • 尚未验证
  • 已验证无法获得

“尚未验证”不等于“不支持”。

第一阶段优先:

  • OpenAI / Codex Subscription
  • OpenAI API
  • Anthropic / Claude Subscription
  • Anthropic API
  • OpenCode Go
  • OpenRouter
  • DeepSeek
  • GitHub Copilot
  • xAI
  • Kimi
  • MiniMax
  • Z.ai
  • Google 相关 Coding Provider

原则:验证清楚一个,实现一个。

AGENTS

显示当前真正执行的 sub-agent,不是配置列表。

优先用原生 Task/Session 数据:task ToolPart、child/parent session、task metadata、message part status;不做名称或文本模糊匹配。

显示:name/type、状态、activity、elapsed。

状态只用 OpenCode 明确的 pending/running/completed/error,不推断 waiting/stuck/paused。

Activity 只显示 tool 类型:read、grep、glob、bash、edit、skill、task;不显示内容、参数、命令、路径、输出。

保留策略:

  • running / pending:全显
  • error:少量
  • completed:最近 2~3 个

SKILLS

显示当前工作 session 实际调用过的 skills,不是安装/可用/Prompt 中提到。

必须来自 structured tool invocation,如 tool = skillinput.name,不搜文本、日志、项目文件。

范围含 root session 与工作流 sub-agent sessions。

展示规则:去重、最近优先、可显示 ×N、最多 4~6 个、剩余 +N

首次 render 从当前 session 结构化数据重建 Agents/Skills,再通过 event 增量更新;session data 是 source of truth。

HOSTNAME

新增一级节点 HOST,仅显示本机 hostname。

来源仅 Node/Bun builtin os.hostname()

不显示 username、IP、完整 cwd、OS、uptime、网络信息;不写日志、不落盘、不进入 Telemetry。hostname 不可得时隐藏该节点。

默认展开,可折叠。

折叠交互

  • 一级节点 HOST / AGENTS / USAGE / SKILLS 均可折叠。
  • USAGE 下每个 Provider 可折叠。
  • AGENTS 下每个 Agent 可折叠。
  • SKILLS 条目为叶子,不可折叠。
  • 折叠只影响渲染,不停止数据采集。
  • 折叠后保留标题与计数/摘要。
  • 折叠状态仅保存在进程内存,不落盘。
  • 交互优先支持点击标题或键盘 Enter/Space;若当前 TUI API 不支持,至少支持配置默认展开/折叠,并保留折叠符号。

4. UI 规范与样式示例

样式是规范:section 顺序、缩进、符号、进度条宽度、计数格式、折叠标记均固定;除宽度截断外不得自由发挥。

展开示例

AGENTS · 3 ▾
  ● explore       grep · 1m24s
  ● reviewer      read · 42s
  ✓ test                18s

USAGE ▾
  OpenAI · Subscription ▾
    5h       ███████░░ 72%
              ↻ 2h14m
    Weekly   █████░░░░ 48%
              ↻ 3d8h
  DeepSeek · API ▾
    Balance   CNY 108.42
  OpenRouter · API ▾
    Monthly   ███████░░ 74%
    $74.50 / $100 left

SKILLS · 4 ▾
  debugging · code-review
  browser-testing · +1

HOST · mbp-14 ▾

折叠示例

AGENTS · 3 ▸
USAGE · 2 ▸
SKILLS · 4 ▸
HOST · mbp-14 ▸

部分折叠

AGENTS · 3 ▾
  ● explore       grep · 1m24s
  ● reviewer      read · 42s
  ✓ test                18s
USAGE · 2 ▸
SKILLS · 4 ▾
  debugging · code-review
  browser-testing · +1
HOST · mbp-14 ▾

格式约定

  • 一级:NAME · N ▾/▸;无计数则 NAME ▾/▸。折叠符号 展开、 折叠。
  • 子项缩进 2 空格;Provider 缩进 2 空格;metric 缩进 4 空格;reset 行与 metric 值对齐。
  • 进度条固定 9 格,,统一表示 remaining;百分比整数。
  • 颜色用 OpenCode 主题:默认、muted、accent、success、warning、error。Quota 剩余 >50% 正常,20~50% warning,<20% error;不整行染色。
  • 长 provider/model/agent 名截断加 ,不换行。
  • 空 section 隐藏。
  • section 间空一行。
  • 不显示 CPU、RAM、IP、当前时间、完整 cwd、uptime、网速等低价值信息。

5. 安全、网络、错误与缓存

  • Credential 安全:只在本机内存到官方服务之间流动;禁止进入日志、UI、异常、缓存、临时文件、KV、Telemetry、第三方 API。不显示 key 后四位、email、account/org ID。来源仅 OpenCode auth store、runtime、明确环境变量;不扫描 .env、源码、shell/git history、项目文件。
  • 网络安全:仅访问代码内固定、已验证的 Provider endpoint;HTTPS、timeout、AbortController、限制响应大小、校验 schema、禁止任意 redirect 与第三方 proxy;credential 不离开 Provider 可信域名。
  • 错误处理:401/403/429/500/timeout/schema changed 等静默失败,sidebar 继续运行,不弹 toast,不显示错误。
  • 缓存:内存缓存 + TTL + in-flight dedupe + failure backoff;正常 25 分钟请求一次,失败 3060 秒后重试;不落盘。
  • 安全审查:完成后检查 console.log credential、raw headers/Error、完整 response、cache 文件、token 写 KV、扫描 .env、非官方 endpoint、自动 redirect、UI 泄露 account 信息;重点检查异常路径,如 JSON.stringify(response)console.error(error)

6. 验证、测试、交付与优先级

参考与 Provider 报告

参考 Joaquinvesapa/sub-agent-statuslineslkiser/opencode-quota,学习 quota 获取、归一化、sub-agent 跟踪、缓存、降级、信息密度;不引入依赖,不运行其 npm 包,不机械复制 Provider 假设,endpoint 必须重新验证。

Provider 报告状态:

  • ✓ 已验证并实现
  • △ 尚未完成验证
  • ○ API 存在但 credential/plan 无法读取
  • — 已验证确实无法取得

禁止“可能/应该/理论支持”。

测试覆盖

  • Quota:正常、缺 window、单/多 window、balance、budget、limit=null、reset 缺失、401/403/429/500/timeout/invalid JSON/schema changed,UI 不崩。
  • Sub-agent:无/单/多并发、pending/running/completed/error、子 agent 内继续 tool,状态与 OpenCode 一致。
  • Skills:主 session/子 agent 调用、同 skill 多次、多 skill、打开已有 session,均正确重建。
  • 折叠/展开:不改变数据,首次 render 正确重建。
  • Security:真实 credential 后检查 stdout/stderr、OpenCode logs、插件缓存、临时目录、UI、错误输出,不得出现 API key/OAuth token。

交付物

  1. status-sidebar.tsx 完整可运行代码。
  2. 当前 OpenCode 最小加载配置。
  3. 安装路径。
  4. 已验证 Provider 清单。
  5. 各 Provider 实际显示数据。
  6. 尚未验证 Provider 清单。
  7. 已验证无法取得对应数据的清单。
  8. 安全审查结果。
  9. 实际运行验证结果。

要求:不给伪代码,不只凭文档“认为可以”,能运行验证必须运行。

优先级

Credential 安全 > 数据真实性 > 兼容当前 OpenCode > 视觉效果 > Graceful degradation > 低运行开销 > 信息密度。

铁律

  • 不知道不等于拿不到。
  • Provider 返回什么就显示什么。
  • 只补充 OpenCode 原生缺失的信息。