@adongguo/yxdash
v1.1.1
Published
Terminal dashboard and automation-friendly CLI for Alibaba Cloud Yunxiao work items
Maintainers
Readme
yxdash
终端里的云效工作项看板(命令名
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唤起,中文/拼音/英文模糊搜索并执行任意操作,同一文档) - ✅ M9:焦点视图(
f将当前项或标记批次加入/移出本地焦点集合,按需求/缺陷/任务分组,不写云效字段) - ✅ M13:单行标题优先与横向滚动(看板卡片分隔 + 列表每项一行 + 标题列前置 +
H/L^/$与鼠标横向滚轮,详见docs/20260828-104159-M13-单行标题优先与横向滚动技术方案.md) - ✅ M2 完整过滤:
/本地模糊筛、Tab升级为服务端主题查询、F结构化过滤表单(状态/标签多选,负责人、优先级、严重程度、类型/模块、时间窗全 select;仅在当前进程内生效) - ✅ M3 多 project/profile:单 YAML 可声明多个完整 profile,通过
--profile/YXDASH_PROFILE选择,默认 profile 可配置且严格隔离组织、项目与令牌来源
安装与分发
正式包名为 @adongguo/yxdash,安装后的命令名保持为 yxdash,通过公共 npm registry(npmjs)分发。此前的 @adongguo/[email protected] 是旧品牌下的预览包;未加 scope 的 yxdash 因 npm 相似名称保护未曾发布。正式版从 @adongguo/[email protected] 开始。
联网安装无需额外 registry 配置:
npm install --global @adongguo/yxdash
yxdash --version也可以从 tag 流水线下载离线产物及 SHA256SUMS,校验后安装同一份已验证 tarball:
(cd release && shasum -a 256 -c SHA256SUMS)
npm install --global ./release/yxdash-v1.1.1.tgz
yxdash --helptarball 会捆绑经锁文件验证的完整运行时依赖树,可在没有 registry 网络的环境中离线安装。自有 TypeScript 代码会先合并为单个 Node ESM 入口,再以固定 seed 做 minify 与混淆;公网包的自有代码区域不包含 src/、.ts、.tsx、source map 或 sourceMappingURL。第三方运行时依赖保持原样,不参与混淆,因此依赖自身可能包含类型声明或源码文件。混淆只提高逆向成本,并不构成加密或秘密保护边界。
每个正式 tag 同时生成与运行时依赖树对应的 CycloneDX SBOM,以及记录源码 commit、构建工具精确版本、混淆状态和产物摘要的 manifest。本项目从 1.1.0 起使用 GPL-3.0-or-later 许可证,完整条款见 LICENSE;此前已发布版本继续适用其随版本提供的 MIT 许可证。
源码开发
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,再生成 npm 与 GitHub Release 产物。已推送 tag 不得移动:如果发布失败后又修改了产物,必须递增版本并创建新 tag。
release:bundle 会拒绝脏工作区、非稳定 SemVer、tag/版本不一致、原始业务源码或 source map 入包,以及无法证明混淆状态的产物。发布凭据只通过 npm 登录态或短期 granular access token 提供,禁止写入仓库、配置示例或日志。
启动落地行为由配置决定:defaultView(默认 sprint)决定打开哪个视图;迭代视图的 views.sprint.groupBy(默认 statusStage 按阶段分组,运行时 g 键可循环切换)与 defaultAssignee(默认 self 只看自己,可设 all 或具体用户 id)决定初始分组与过滤。命令行显式指定视图(yxdash bugs)优先于配置;管道模式不受 defaultView 影响,未指定视图时始终是 bugs,保证 agent 拿到的输出结构稳定。
令牌解析顺序:YUNXIAO_ACCESS_TOKEN 环境变量 → 配置中的 token_cmd(例如从系统 keychain 或密码管理器读取)。令牌永不明文落盘。
配置查找顺序:$YXDASH_CONFIG → ./.yxdash.yaml → ~/.config/yxdash/config.yaml。
多 profile 配置中的每个 profile 都是完整配置,互不继承,避免跨组织复用 project、baseUrl 或令牌命令。显式 --profile 优先于 YXDASH_PROFILE,其次使用 defaultProfile;只有一个 profile 时可自动选择。旧的单配置 YAML 继续兼容,但不能再附加 profile 选择参数。
defaultProfile: flow
profiles:
flow:
organizationId: <组织 id>
project: <项目 id>
baseUrl: https://yunxiaopro-cn-beijing.devops.aliyuncs.com
token_cmd: <安全令牌命令>
another-project:
organizationId: <另一组织 id>
project: <另一项目 id>
baseUrl: https://yunxiaopro-cn-beijing.devops.aliyuncs.com
token_cmd: <另一安全令牌命令>yxdash --profile flow
YXDASH_PROFILE=another-project yxdash reqs安全边界:工作目录的 ./.yxdash.yaml 可能随任意 clone 的仓库而来,因此其中的 token_cmd 会被拒绝执行(token_cmd 只在用户级配置生效),加载工作目录配置时会在 stderr 提示确认。确实需要仓库级配置带 token_cmd 时,用 --config ./.yxdash.yaml 或 $YXDASH_CONFIG 显式指定(显式指定 = 显式信任)。
视觉与 UI 配置
默认视觉系统为 Dracula Pro:背景基准 #22212C、交互焦点紫 #9580FF、多选标记粉 #FF80BF、信息青 #80FFEA、警告黄 #FFFF80、错误红 #FF9580。紫色只编码“当前可操作焦点”,粉色只编码“已持有的多选项”,严重度颜色不复用,避免同一种颜色同时表达两个状态。光标仍使用终端反显通道,因此在彩色能力受限时也能辨认。
品牌采用母版中的绿 → 青 → 蓝 → 紫工作流色谱。交互模式在首次数据真实加载期间显示终端原生品牌启动态,数据到达后立即进入看板,不附加固定等待时间;顶部根据宽度常驻 yxdash(≥80 列)或 yx(52–79 列),更窄时把全部空间留给工作项。--json / --plain 管道输出不包含任何品牌装饰,数据契约保持不变。
仓库内品牌资产均由同一母版保真拆分:完整横版 assets/brand/yxdash-lockup.png、图形标 assets/brand/yxdash-symbol.png、文字标 assets/brand/yxdash-wordmark.png。
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 | 列表密度与完整标题提示行;density: compact = 每个工作项恒占一行 |
| boardCardGap | true | 看板卡片之间留一行空行(列高不足 16 行时自动降级为关闭) |
| titleFirst | false | 把「标题」提到第一列(表格视图与迭代/焦点视图同时生效) |
| rowScroll | true | 窄屏保留全部列并支持横向滚动;关闭则回到「按宽度丢列」。宽屏下两者渲染一致 |
| breakpoints | 52/80/120 | sm / md / lg 响应式断点 |
| mouse | true | 鼠标滚动、点击与双击 |
一次性覆盖可用 YXDASH_THEME=terminal 或 YXDASH_MARK_COLOR=<受支持的 ANSI 颜色名|#RRGGBB>;环境变量优先于配置,适合排查不支持 truecolor 的远程终端。
键位
| 键 | 作用 | 键 | 作用 |
|---|---|---|---|
| 1 2 3 4 | 切换视图:缺陷 / 需求 / 迭代 / 焦点(四个视图内含义完全一致) | s / S | 循环切换视图(同 1-4,前进/后退) |
| 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 | 命令面板:模糊搜索(中文/拼音/英文)并执行任意操作 |
| / | 本地模糊筛(Tab 将关键词升级为服务端主题过滤;Esc 清除) | F | 结构化服务端过滤(Esc 取消,x 重置) |
| r / R | 刷新当前 / 全部 | f | 当前项或标记批次加入/移出焦点集合 |
| e | 编辑(状态/负责人/优先级/描述/评论) | m | 状态流转直达 |
| C | 查看评论 | ? / q | 帮助 / 退出 |
| H / L | 行内左右滚动(窄屏保留全部列时用;看板下不生效) | ^ / $ | 回到行首 / 行尾 |
鼠标(默认开启):
| 操作 | 作用 |
|---|---|
| 滚轮 | 指针所在区域滚动:列表移光标(卡片行 1 条/格,普通行 3 行/格)、预览/评论面板滚 3 行/格、弹层列表移 1 项/格 |
| 横向滚轮 | 指针在列表上时左右移动行窗口(4 格/格);终端需上报 SGR 66/67,不支持时用 H/L |
| 单击 | 表格行/迭代条目=选中;迭代组头=折叠展开;顶部 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 ←/→ | 切换迭代(也可点左栏) | 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 列)
yxdash focus --json # 本地焦点集合,按需求/缺陷/任务分组
yxdash bugs --json --profile flow # 从多 profile 配置选择目标项目- 退出码:
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。 - 运行时可观测性(M10):常驻日志落
~/.local/state/yxdash/yxdash.log(XDG_STATE_HOME生效时随之;log.level/YXDASH_LOG_LEVEL调级,off关闭;log.file/YXDASH_LOG_FILE改路径;超 512KB 轮转一代)。记录启动、退出原因、未捕获异常堆栈与输入看门狗告警;令牌、请求体、响应体一律不入日志。 - 不会再静默消失(M10):全屏 TUI 的堆栈会被 alternate screen 一并抹掉,而本应用所有定时器都是
unref的,一旦 stdin 失去引用事件循环就空、Ink 自行卸载、退出码 0。交互模式因此全程持有一个 ref 的 keepalive 句柄,并用同一个 tick 监测 stdin 是否意外丢失 raw 模式(去抖两拍后自愈,最多 3 次)。异常退出会在主屏留一行并指向日志。 - 逃生舱:
YXDASH_NO_ALTSCREEN=1禁全屏;YXDASH_FULL_REPAINT=1关增量渲染(tmux/ConPTY 残影时用);YXDASH_NO_MOUSE=1关鼠标上报;YXDASH_THEME=terminal临时沿用终端配色;YXDASH_MARK_COLOR=blueBright(或其他受支持的 ANSI 颜色名/#rrggbb)改多选标记色,非法值回落当前主题默认值。 - 窄屏不再丢列(M13):
ui.rowScroll默认开启后,列不再按宽度丢弃,而是按自然宽度排开、由H/L/^/$或鼠标横向滚轮移动窗口;行首 2 格色轨固定不滚,所以标记与状态色块永远可见。宽屏下自然宽度本就装得下,渲染与之前逐字节一致。状态栏在可滚动时显示H/L 横滚 n/max,这是「右边还有内容」的唯一信号。 - 看板卡片分隔(M13):卡片之间加一行空行、色轨在卡片最后一行断开、编号行降一档亮度,让标题成为视觉重心。空行不带色轨也不吃光标高亮,否则它就只是高亮块上的一个缺口而非分隔。
- 鼠标:SGR 编码(
?1000h+?1006h,不开移动上报);渲染与命中测试共用ui/layout/lists.ts的同一份视口算术,所见即可点;解析失败的序列原样落回键盘路径,终端不支持时零影响。tmux 需set -g mouse on才会转发。
读写边界
读为主:看板/管道查询全部只读。写操作(M3:字段修改、描述编辑、新增评论)仅在 TUI 中由显式选择/保存触发,agent 管道面(--json/--plain)不提供任何写入。令牌只经环境变量或 token_cmd 获取,永不落盘。
