@adongguo/yunxiao-tui
v0.1.1
Published
Terminal dashboard and automation-friendly CLI for Alibaba Cloud Yunxiao work items
Readme
yunxiao-tui
终端里的云效工作项看板(命令名
yxdash):缺陷 / 需求 / 迭代三视图,默认只看与我相关,链接可点击,自动刷新,同时是 Claude Code 等 agent 的结构化数据源。技术栈与 Claude Code 一致:TypeScript + React Ink 7 + Node ≥ 22(纯 ESM)。
状态
- ✅ 产品与方案调研(
docs/20260815-170653-云效TUI看板-产品与方案调研.md) - ✅ 技术方案 v1.0(
docs/20260815-183843-yunxiao-tui技术方案.md) - ✅ M1:缺陷/需求表格视图(自绘表格 + sections tab + 预览面板 + 键位全集 + YAML 配置 + 状态名动态解析 + 限流保护),替代
/mybugs/mywork日常使用 - ✅ M2 主体:迭代 master-detail 视图(需求默认三类全含、按阶段分组、
a按负责人过滤、b缺陷开关、g分组维度切换) - ✅ M3 提前项:
--json/--plain管道输出(agent / 脚本消费,含 sprint 视图) - ✅ M3 编辑能力:
e字段编辑(状态/负责人/优先级/严重程度,全 select 化)、m状态流转直达、d/c经 nvim($EDITOR) 编辑描述与新增评论、C查看评论(详见docs/20260816-215451-M3编辑能力技术方案.md) - ✅ M4:响应式布局(测量式列宽、断点行/卡片形态、长文本软换行,详见
docs/20260818-202956-响应式布局技术方案.md) - ✅ M5:迭代视图 vim 式分组折叠(空格 /
zchord /zssolo,详见docs/20260819-105343-分组折叠vim化技术方案.md) - ✅ M6:鼠标交互(滚轮滚动、单击选中/切换 section 与视图、双击预览、组头点击折叠;
ui.mouse: false或YXDASH_NO_MOUSE=1关闭,详见docs/20260820-000232-鼠标交互技术方案.md) - ✅ M7:多选标记与批量复制(
v标记、y/Y批量复制编号/链接、Esc 清除,详见docs/20260824-193458-多选复制与命令面板技术方案.md) - ✅ M8:命令面板(
Ctrl+k唤起,中文/拼音/英文模糊搜索并执行任意操作,同一文档) - ⬜ M2 其余:
f过滤表单;M3 其余:多 profile
安装与分发
正式包名为 @adongguo/yunxiao-tui,安装后的命令保持为 yxdash,通过公共 npm registry(npmjs)分发。
联网安装无需额外 registry 配置:
npm install --global @adongguo/yunxiao-tui
yxdash --version也可以从 tag 流水线下载离线产物及 SHA256SUMS,校验后安装同一份已验证 tarball:
(cd release && shasum -a 256 -c SHA256SUMS)
npm install --global ./release/yunxiao-tui-v0.1.1.tgz
yxdash --helptarball 会捆绑经锁文件验证的完整运行时依赖树,可在没有 registry 网络的环境中离线安装。自有 TypeScript 代码会先合并为单个 Node ESM 入口,再以固定 seed 做 minify 与混淆;公网包的自有代码区域不包含 src/、.ts、.tsx、source map 或 sourceMappingURL。第三方运行时依赖保持原样,不参与混淆,因此依赖自身可能包含类型声明或源码文件。混淆只提高逆向成本,并不构成加密或秘密保护边界。
每个正式 tag 同时生成与运行时依赖树对应的 CycloneDX SBOM,以及记录源码 commit、构建工具精确版本、混淆状态和产物摘要的 manifest。本项目使用 MIT 许可证,完整条款见 LICENSE。
源码开发
npm install
cp config.example.yaml ~/.config/yxdash/config.yaml # 按需修改
export YUNXIAO_ACCESS_TOKEN=<云效个人访问令牌> # 或在配置中用 token_cmd
npm run dev # 交互式 TUI(默认落在迭代视图)发布前本地验证:
npm ci
npm run release:check # 类型、覆盖率、全依赖审计、registry 签名、混淆构建、包内容与安装后黑盒验证正式发布采用 SemVer tag,tag 必须与 package.json 版本完全一致且指向干净提交。推荐用 npm version patch|minor|major 同步修改包清单与锁文件并创建 v<version> tag,推送 tag 后由 GitLab 流水线生成产物;npmjs 发布是受保护 tag 上的人工批准步骤。已推送 tag 不得移动:如果发布失败后又修改了产物,必须递增版本并创建新 tag。
当前自托管 GitLab runner 不满足 npm Trusted Publishing 的云托管 runner 条件,因此 CI 使用项目级 protected + masked NPM_TOKEN:令牌必须是仅允许目标包/Scope 读写、允许发布绕过 2FA、具有最短可用期限的 npm granular access token,禁止写入仓库或日志。release:bundle 会拒绝脏工作区、非稳定 SemVer、tag/版本不一致、原始业务源码或 source map 入包,以及无法证明混淆状态的产物。
启动落地行为由配置决定:defaultView(默认 sprint)决定打开哪个视图;迭代视图的 views.sprint.groupBy(默认 statusStage 按阶段分组,运行时 g 键可循环切换)与 defaultAssignee(默认 self 只看自己,可设 all 或具体用户 id)决定初始分组与过滤。命令行显式指定视图(yxdash bugs)优先于配置;管道模式不受 defaultView 影响,未指定视图时始终是 bugs,保证 agent 拿到的输出结构稳定。
令牌解析顺序:YUNXIAO_ACCESS_TOKEN 环境变量 → 配置中的 token_cmd(例如从 ~/.claude.json 的 MCP 配置读取)。令牌永不明文落盘。
配置查找顺序:$YXDASH_CONFIG → ./.yxdash.yaml → ~/.config/yxdash/config.yaml。
安全边界:工作目录的 ./.yxdash.yaml 可能随任意 clone 的仓库而来,因此其中的 token_cmd 会被拒绝执行(token_cmd 只在用户级配置生效),加载工作目录配置时会在 stderr 提示确认。确实需要仓库级配置带 token_cmd 时,用 --config ./.yxdash.yaml 或 $YXDASH_CONFIG 显式指定(显式指定 = 显式信任)。
视觉与 UI 配置
默认视觉系统为 Dracula Pro:背景基准 #22212C、交互焦点紫 #9580FF、多选标记粉 #FF80BF、信息青 #80FFEA、警告黄 #FFFF80、错误红 #FF9580。紫色只编码“当前可操作焦点”,粉色只编码“已持有的多选项”,严重度颜色不复用,避免同一种颜色同时表达两个状态。光标仍使用终端反显通道,因此在彩色能力受限时也能辨认。
ui 段可按终端和工作习惯精调:
| 配置 | 默认 | 作用 |
|---|---|---|
| theme | dracula-pro | dracula-pro 使用紫色视觉系统;terminal 沿用终端调色板 |
| accentColor / markColor | 主题值 | 用 #RRGGBB 覆盖焦点色 / 多选色 |
| borderStyle | round | 弹层边框:round / single / double / classic |
| animations | true | false 后用静态点替代 spinner 动画 |
| previewPosition | auto | 初始预览位置:auto / right / bottom |
| footer | auto | minimal 只保留视图切换与帮助/退出 |
| density / detailBar | auto | 列表密度与完整标题提示行 |
| breakpoints | 52/80/120 | sm / md / lg 响应式断点 |
| mouse | true | 鼠标滚动、点击与双击 |
一次性覆盖可用 YXDASH_THEME=terminal 或 YXDASH_MARK_COLOR=<受支持的 ANSI 颜色名|#RRGGBB>;环境变量优先于配置,适合排查不支持 truecolor 的远程终端。
键位
| 键 | 作用 | 键 | 作用 |
|---|---|---|---|
| 1-9 | 直达 section | s / S | 循环切换视图 |
| j/k ↓/↑ Ctrl+n/p | 行移动(三套等价,弹层内通用) | h/l ←/→ | 相邻 section |
| g / G | 首行 / 末行 | Enter / p | 预览开关 |
| P | 预览位置(自动→右→底) | Ctrl+d/u | 预览翻页 |
| o | 浏览器打开 | y / Y | 复制编号 / URL(有标记时复制全部标记项,一行一项) |
| v | 标记/取消标记当前行并下移(多选,行首 2 格色轨 + 整行 accent;Esc 清除全部标记) | Ctrl+k | 命令面板:模糊搜索(中文/拼音/英文)并执行任意操作 |
| / | 本地模糊筛(Esc 清除) | r / R | 刷新当前 / 全部 |
| e | 编辑(状态/负责人/优先级/描述/评论) | m | 状态流转直达 |
| C | 查看评论 | ? / q | 帮助 / 退出 |
鼠标(默认开启):
| 操作 | 作用 |
|---|---|
| 滚轮 | 指针所在区域滚动:列表移光标(卡片行 1 条/格,普通行 3 行/格)、预览/评论面板滚 3 行/格、弹层列表移 1 项/格 |
| 单击 | 表格行/迭代条目=选中;迭代组头=折叠展开;顶部 tab=切 section;底部视图名=切视图;左栏=切迭代;弹层条目=移动选中 |
| 双击 | 条目=开关预览(等价 Enter);弹层条目=确认(等价 Enter);组头双击不抖动 |
| Shift+点击/拖选 | 交回终端:原生拖选复制、编号 OSC 8 超链接 |
滚轮只滚动内容,不切换数据源——切 section 和切迭代都要发请求,一次滚轮动作会连发好几格,与限流预算冲突。右键/中键不接管,留给终端。关闭鼠标:配置 ui.mouse: false,或临时 YXDASH_NO_MOUSE=1;关闭后行为与未引入该特性时逐字节一致。
编辑说明:
- 字段编辑:
e打开菜单(当前值一览)→ 选字段 → 选择式弹层(光标预置在当前值、●标记、Enter 提交、Esc 返回;选中当前值 Enter 视为「未变更」不发请求)。候选严格取自该工作项自身类型的工作流/字段配置,负责人候选来自当前视图人员(自己标 ★)。 - 富文本编辑:
e→d(描述)/e→c(新增评论)挂起 TUI,把终端交给外部编辑器(解析链$YXDASH_EDITOR → $VISUAL → $EDITOR → nvim → vim → vi),编辑临时 markdown 文件;保存退出即提交,清空正文或未修改即取消——与 Claude Code 的 vim 编辑对话框同款方案。描述基线每次现拉服务端最新(避免覆盖他人改动);RICHTEXT 原文会作为注释块附在缓冲区末尾备份(提交时自动剥离);提交失败保留草稿,下次同一工作项编辑时自动恢复。 - 写操作仅在 TUI 中由显式操作触发;
--json/--plain管道面保持只读。
迭代视图专属(master-detail:左栏迭代列表,右侧按分组折叠展示;默认只看需求——产品类/技术类/AR 三类全含,缺陷隐藏):
| 键 | 作用 | 键 | 作用 |
|---|---|---|---|
| h/l 1-9 | 切换迭代 | g | 分组维度:阶段→负责人→类型 |
| a | 按负责人过滤(★=自己,含计数) | b | 显示/隐藏迭代内缺陷 |
| 空格 | 折叠/展开光标所在分组 | Enter | 组头=折叠该组;条目=预览 |
| za zo zc | 切换 / 展开 / 折叠当前分组 | zs | 只展开当前分组(其余全折叠) |
| zR zM | 全部展开 / 全部折叠(c 在两者间切换) | zj zk | 跳到下 / 上一个分组头 |
折叠说明(vim 式 fold):
- 按单个阶段展开:
zM全折叠 →zj逐个跳分组(或j/k)→空格/zo展开要看的那个;已经站在某条目上时,zs一键变成「只展开这一个分组」。 - 条目行上按
空格/zc折的是它所属的分组,光标随即回到组头——不必先移到组头再折。 - 折叠不丢阅读位置:任何折叠动作后光标都会锚回原来那条(条目被折起时退到它的组头)。
- 按下
z后提示行变成折叠键速查(z… a切换 o展开 …),此时任意非折叠键(含Esc)都只是取消,不会触发原本的功能——zq不会退出。 - 「全折叠」是基线而非一次性动作:切换迭代后仍然保持折叠状态,刷新后新出现的分组也跟随基线;切换分组维度只清掉单组的例外。
Agent / 管道模式(Claude Code 等)
TUI 之外,yxdash 同时是结构化数据源——stdout 只输出数据,警告与错误走 stderr:
yxdash bugs --json # 缺陷视图全部 sections,JSON(每条含 url)
yxdash bugs --json --section 1 # 只要「我的未解」
yxdash reqs --plain | column -t -s$'\t' # TSV,grep/awk 友好
yxdash sprint --json # 当前迭代需求按阶段分组 + 每人计数
yxdash sprint --json --assignee 卓越 --group-by assignee
yxdash sprint --plain --with-bugs # 连同缺陷(TSV 带 group 列)- 退出码:
0成功 ·1有 section 失败 ·2参数/配置错误。 - stdout 非 TTY 时自动进入
--plain模式(管道安全,绝不渲染交互界面)。 - 开发期等价形式:
npm run dev -- bugs --json或tsx src/cli.tsx bugs --json。
常用命令
npm run dev # tsx 直跑 TUI
npm run typecheck # 严格类型检查(含测试)
npm test # vitest 全量单测
npm run test:coverage # 覆盖率(阈值 90%)
npm run build # tsc 产出 dist/
npm run smoke # 真实 API 冒烟(需令牌,不进 CI)设计要点(详见 docs/)
- 需求/缺陷视图 = gh-dash 骨架(自绘表格 + sections tab + 预览面板);不做多列 kanban 主视图。
- 数据层直连 Yunxiao OpenAPI(
x-yunxiao-token;专有云 Region 版与中心版路径分叉自动判定,可用edition显式覆盖)。 - 防漂移:配置写状态名,启动时经 workflow 接口解析成 ID;全部解析失败时回退「全量拉取 + 本地过滤」。
sprint: current运行时解析(排除 backlog 伪迭代)。 - 限流保护:令牌桶(容量 5、2/s)+ 429/5xx 指数退避 + 只刷可见 section + 元数据 TTL 缓存。
- 刷新三重机制:自动轮询(默认 5 分钟,
intervalSeconds: 0关闭)+r/R手动 + 终端焦点回归触发;刷新失败保留旧数据(stale-while-revalidate)。 - 链接:
o键execFile打开为主路径;OSC 8 超链接为增强(tmux 需set -ga terminal-features "*:hyperlinks");复制经系统剪贴板,SSH 场景回退 OSC 52。 - 逃生舱:
YXDASH_NO_ALTSCREEN=1禁全屏;YXDASH_FULL_REPAINT=1关增量渲染(tmux/ConPTY 残影时用);YXDASH_NO_MOUSE=1关鼠标上报;YXDASH_THEME=terminal临时沿用终端配色;YXDASH_MARK_COLOR=blueBright(或其他受支持的 ANSI 颜色名/#rrggbb)改多选标记色,非法值回落当前主题默认值。 - 鼠标:SGR 编码(
?1000h+?1006h,不开移动上报);渲染与命中测试共用ui/layout/lists.ts的同一份视口算术,所见即可点;解析失败的序列原样落回键盘路径,终端不支持时零影响。tmux 需set -g mouse on才会转发。
读写边界
读为主:看板/管道查询全部只读。写操作(M3:字段修改、描述编辑、新增评论)仅在 TUI 中由显式选择/保存触发,agent 管道面(--json/--plain)不提供任何写入。令牌只经环境变量或 token_cmd 获取,永不落盘。
