{"_id":"@adongguo/yxdash","_rev":"2-7d136d14850842ca7c7b2104d3ab295b","name":"@adongguo/yxdash","dist-tags":{"latest":"1.1.1"},"versions":{"1.0.1":{"name":"@adongguo/yxdash","version":"1.0.1","keywords":["yxdash","yunxiao","projex","tui","cli","ink"],"license":"MIT","_id":"@adongguo/yxdash@1.0.1","maintainers":[{"name":"adongguo","email":"adongguo666@gmail.com"}],"homepage":"https://gitlab.alibaba-inc.com/zhuoyue.gxd/yunxiao-tui#readme","bugs":{"url":"https://gitlab.alibaba-inc.com/zhuoyue.gxd/yunxiao-tui/issues"},"os":["darwin","linux","win32"],"bin":{"yxdash":"dist/cli.js"},"dist":{"shasum":"484090268ba64995a85e58af7835f8550d67b1a8","tarball":"https://registry.npmjs.org/@adongguo/yxdash/-/yxdash-1.0.1.tgz","fileCount":5618,"integrity":"sha512-qdM7vafyaRZkHE8QZ+bX2CliwI7D0D1uFSzRlsb/R8aADevw/+c/F9KtO8WFgqgeNTSIJYpcN5nV25G1Dal21g==","signatures":[{"sig":"MEUCICWMiYtNO7UrqvazTx34KHnSBSbLyGeY+7d2FwonA7OjAiEAuScguYnWBg1oxfDDs63WuenImm/YahH5Znuj6RrJnCg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":13867303},"type":"module","_from":"file:release/yxdash-v1.0.1.tgz","engines":{"node":">=22.14.0"},"scripts":{"dev":"tsx src/cli.tsx","test":"vitest run","build":"npm run clean && tsc -p tsconfig.build.json && node scripts/mark-executable.mjs","clean":"node scripts/clean.mjs","smoke":"tsx scripts/smoke.ts","prepack":"npm run check:runtime-deps && npm run build:release","audit:all":"npm audit --audit-level=high","typecheck":"tsc --noEmit","audit:prod":"npm audit --omit=dev --audit-level=high","build:release":"node scripts/build-release.mjs","release:check":"npm run typecheck && npm run test:coverage && npm run audit:all && npm run audit:signatures && npm run package:verify","test:coverage":"vitest run --coverage","package:verify":"npm run check:runtime-deps && npm run build:release && node scripts/verify-package.mjs","prepublishOnly":"npm run release:source-check && npm run release:check","release:bundle":"npm run release:source-check && npm run release:check && node scripts/create-release.mjs","audit:signatures":"npm audit signatures","check:runtime-deps":"node scripts/check-runtime-dependencies.mjs","release:source-check":"node scripts/create-release.mjs --check-only"},"_npmUser":{"name":"adongguo","email":"adongguo666@gmail.com"},"_resolved":"/Users/adongguo/workspace/work/gitlab.alibaba-inc.com/zhuoyue.gxd/yunxiao-tui/release/yxdash-v1.0.1.tgz","_integrity":"sha512-qdM7vafyaRZkHE8QZ+bX2CliwI7D0D1uFSzRlsb/R8aADevw/+c/F9KtO8WFgqgeNTSIJYpcN5nV25G1Dal21g==","devEngines":{"runtime":{"name":"node","onFail":"error","version":">=22.14.0"},"packageManager":{"name":"npm","onFail":"error","version":">=11.5.1"}},"repository":{"url":"git+ssh://git@gitlab.alibaba-inc.com/zhuoyue.gxd/yunxiao-tui.git","type":"git"},"_npmVersion":"11.18.0","description":"Terminal dashboard and automation-friendly CLI for Alibaba Cloud Yunxiao work items","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ink":"^7.1.1","zod":"^4.4.3","yaml":"^2.5.0","react":"^19.2.0","string-width":"^8.2.2","supports-hyperlinks":"^4.5.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"packageManager":"npm@11.18.0","devDependencies":{"tsx":"^4.20.0","vitest":"^4.0.0","esbuild":"0.28.2","typescript":"^5.6.0","@types/node":"^22.0.0","@types/react":"^19.2.0","@vitest/coverage-v8":"^4.1.10","ink-testing-library":"^4.0.0","react-devtools-core":"^6.1.2","javascript-obfuscator":"5.6.0"},"bundleDependencies":["ink","react","string-width","supports-hyperlinks","yaml","zod"],"_npmOperationalInternal":{"tmp":"tmp/yxdash_1.0.1_1787671703784_0.5151041001844141","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@adongguo/yxdash","version":"1.1.1","description":"Terminal dashboard and automation-friendly CLI for Alibaba Cloud Yunxiao work items","license":"GPL-3.0-or-later","keywords":["yxdash","yunxiao","projex","tui","cli","ink"],"repository":{"type":"git","url":"git+https://github.com/adongguo/yxdash.git"},"bugs":{"url":"https://github.com/adongguo/yxdash/issues"},"homepage":"https://github.com/adongguo/yxdash#readme","type":"module","bin":{"yxdash":"dist/cli.js"},"engines":{"node":">=22.14.0"},"devEngines":{"runtime":{"name":"node","version":">=22.14.0","onFail":"error"},"packageManager":{"name":"npm","version":">=11.5.1","onFail":"error"}},"os":["darwin","linux","win32"],"packageManager":"npm@11.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"dev":"tsx src/cli.tsx","clean":"node scripts/clean.mjs","build":"npm run clean && tsc -p tsconfig.build.json && node scripts/mark-executable.mjs","build:release":"node scripts/build-release.mjs","typecheck":"tsc --noEmit","test":"vitest run","test:coverage":"vitest run --coverage","smoke":"tsx scripts/smoke.ts","audit:prod":"npm audit --omit=dev --audit-level=high","audit:all":"npm audit --audit-level=high","audit:signatures":"npm audit signatures","check:runtime-deps":"node scripts/check-runtime-dependencies.mjs","package:verify":"npm run check:runtime-deps && npm run build:release && node scripts/verify-package.mjs","release:source-check":"node scripts/create-release.mjs --check-only","release:check":"npm run typecheck && npm run test:coverage && npm run audit:all && npm run audit:signatures && npm run package:verify","release:bundle":"npm run release:source-check && npm run release:check && node scripts/create-release.mjs","prepack":"npm run check:runtime-deps && npm run build:release","prepublishOnly":"npm run release:source-check && npm run release:check"},"dependencies":{"ink":"^7.1.1","react":"^19.2.0","string-width":"^8.2.2","supports-hyperlinks":"^4.5.0","yaml":"^2.5.0","zod":"^4.4.3"},"bundleDependencies":["ink","react","string-width","supports-hyperlinks","yaml","zod"],"devDependencies":{"@types/node":"^22.0.0","@types/react":"^19.2.0","@vitest/coverage-v8":"^4.1.10","esbuild":"0.28.2","ink-testing-library":"^4.0.0","javascript-obfuscator":"5.6.0","react-devtools-core":"^6.1.2","tsx":"^4.20.0","typescript":"^5.6.0","vitest":"^4.0.0"},"_id":"@adongguo/yxdash@1.1.1","_integrity":"sha512-WHT50MNlYnCJkVWaIi6rb22RnLcbqhOllQ3/lm9SkWeZWrgnduvME4u4aBZiPzHIYTP+vPmLQfUxbRYGf6IKxA==","_resolved":"/Users/adongguo/workspace/work/gitlab.alibaba-inc.com/zhuoyue.gxd/yunxiao-tui/release/yxdash-v1.1.1.tgz","_from":"file:/Users/adongguo/workspace/work/gitlab.alibaba-inc.com/zhuoyue.gxd/yunxiao-tui/release/yxdash-v1.1.1.tgz","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-WHT50MNlYnCJkVWaIi6rb22RnLcbqhOllQ3/lm9SkWeZWrgnduvME4u4aBZiPzHIYTP+vPmLQfUxbRYGf6IKxA==","shasum":"1597fe06bc1a9b709a8d8db87f7cb7263933659c","tarball":"https://registry.npmjs.org/@adongguo/yxdash/-/yxdash-1.1.1.tgz","fileCount":5618,"unpackedSize":14356527,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDJQiS9YdzZWQONeaZOe6H/O5lvUIoCsorjf+DhLeAnvgIgIh/UG2PrO7vCb9Mu/r0EjOjKegpjTcg4ito2t/ccoUM="}]},"_npmUser":{"name":"adongguo","email":"adongguo666@gmail.com"},"directories":{},"maintainers":[{"name":"adongguo","email":"adongguo666@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/yxdash_1.1.1_1788181348745_0.2057919751203232"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-25T15:28:23.509Z","modified":"2026-08-31T13:02:29.183Z","1.0.1":"2026-08-25T15:28:24.028Z","1.1.1":"2026-08-31T13:02:29.023Z"},"bugs":{"url":"https://github.com/adongguo/yxdash/issues"},"license":"GPL-3.0-or-later","homepage":"https://github.com/adongguo/yxdash#readme","keywords":["yxdash","yunxiao","projex","tui","cli","ink"],"repository":{"type":"git","url":"git+https://github.com/adongguo/yxdash.git"},"description":"Terminal dashboard and automation-friendly CLI for Alibaba Cloud Yunxiao work items","maintainers":[{"name":"adongguo","email":"adongguo666@gmail.com"}],"readme":"<p align=\"center\">\n  <img src=\"./assets/brand/yxdash-lockup.png\" alt=\"yxdash：终端中的云效工作流\" width=\"960\">\n</p>\n\n# yxdash\n\n> 终端里的云效工作项看板（命令名 `yxdash`）：缺陷 / 需求 / 迭代 / 焦点四视图，默认只看与我相关，链接可点击，自动刷新，同时是 Claude Code 等 agent 的结构化数据源。技术栈与 Claude Code 一致：TypeScript + React Ink 7 + Node ≥ 22（纯 ESM）。\n\n## 状态\n\n- ✅ 产品与方案调研（`docs/20260815-170653-云效TUI看板-产品与方案调研.md`）\n- ✅ 技术方案 v1.0（`docs/20260815-183843-yunxiao-tui技术方案.md`）\n- ✅ M1：缺陷/需求表格视图（自绘表格 + sections tab + 预览面板 + 键位全集 + YAML 配置 + 状态名动态解析 + 限流保护），替代 `/mybugs` `/mywork` 日常使用\n- ✅ M2 主体：迭代 master-detail 视图（需求默认三类全含、按阶段分组、`a` 按负责人过滤、`b` 缺陷开关、`g` 分组维度切换）\n- ✅ M3 提前项：`--json` / `--plain` 管道输出（agent / 脚本消费，含 sprint 视图）\n- ✅ M3 编辑能力：`e` 字段编辑（状态/负责人/优先级/严重程度，全 select 化）、`m` 状态流转直达、`d/c` 经 nvim($EDITOR) 编辑描述与新增评论、`C` 查看评论（详见 `docs/20260816-215451-M3编辑能力技术方案.md`）\n- ✅ M4：响应式布局（测量式列宽、断点行/卡片形态、长文本软换行，详见 `docs/20260818-202956-响应式布局技术方案.md`）\n- ✅ M5：迭代视图 vim 式分组折叠（空格 / `z` chord / `zs` solo，详见 `docs/20260819-105343-分组折叠vim化技术方案.md`）\n- ✅ M6：鼠标交互（滚轮滚动、单击选中/切换 section 与视图、双击预览、组头点击折叠；`ui.mouse: false` 或 `YXDASH_NO_MOUSE=1` 关闭，详见 `docs/20260820-000232-鼠标交互技术方案.md`）\n- ✅ M7：多选标记与批量复制（`v` 标记、`y`/`Y` 批量复制编号/链接、Esc 清除，详见 `docs/20260824-193458-多选复制与命令面板技术方案.md`）\n- ✅ M8：命令面板（`Ctrl+k` 唤起，中文/拼音/英文模糊搜索并执行任意操作，同一文档）\n- ✅ M9：焦点视图（`f` 将当前项或标记批次加入/移出本地焦点集合，按需求/缺陷/任务分组，不写云效字段）\n- ✅ M13：单行标题优先与横向滚动（看板卡片分隔 + 列表每项一行 + 标题列前置 + `H/L` `^/$` 与鼠标横向滚轮，详见 `docs/20260828-104159-M13-单行标题优先与横向滚动技术方案.md`）\n- ✅ M2 完整过滤：`/` 本地模糊筛、`Tab` 升级为服务端主题查询、`F` 结构化过滤表单（状态/标签多选，负责人、优先级、严重程度、类型/模块、时间窗全 select；仅在当前进程内生效）\n- ✅ M3 多 project/profile：单 YAML 可声明多个完整 profile，通过 `--profile` / `YXDASH_PROFILE` 选择，默认 profile 可配置且严格隔离组织、项目与令牌来源\n\n## 安装与分发\n\n正式包名为 `@adongguo/yxdash`，安装后的命令名保持为 `yxdash`，通过公共 npm registry（npmjs）分发。此前的 `@adongguo/yunxiao-tui@0.1.1` 是旧品牌下的预览包；未加 scope 的 `yxdash` 因 npm 相似名称保护未曾发布。正式版从 `@adongguo/yxdash@1.0.1` 开始。\n\n联网安装无需额外 registry 配置：\n\n```bash\nnpm install --global @adongguo/yxdash\nyxdash --version\n```\n\n也可以从 tag 流水线下载离线产物及 `SHA256SUMS`，校验后安装同一份已验证 tarball：\n\n```bash\n(cd release && shasum -a 256 -c SHA256SUMS)\nnpm install --global ./release/yxdash-v1.1.1.tgz\nyxdash --help\n```\n\ntarball 会捆绑经锁文件验证的完整运行时依赖树，可在没有 registry 网络的环境中离线安装。自有 TypeScript 代码会先合并为单个 Node ESM 入口，再以固定 seed 做 minify 与混淆；公网包的自有代码区域不包含 `src/`、`.ts`、`.tsx`、source map 或 `sourceMappingURL`。第三方运行时依赖保持原样，不参与混淆，因此依赖自身可能包含类型声明或源码文件。混淆只提高逆向成本，并不构成加密或秘密保护边界。\n\n每个正式 tag 同时生成与运行时依赖树对应的 CycloneDX SBOM，以及记录源码 commit、构建工具精确版本、混淆状态和产物摘要的 manifest。本项目从 `1.1.0` 起使用 `GPL-3.0-or-later` 许可证，完整条款见 `LICENSE`；此前已发布版本继续适用其随版本提供的 MIT 许可证。\n\n## 源码开发\n\n```bash\nnpm install\ncp config.example.yaml ~/.config/yxdash/config.yaml   # 按需修改\nexport YUNXIAO_ACCESS_TOKEN=<云效个人访问令牌>          # 或在配置中用 token_cmd\nnpm run dev            # 交互式 TUI（默认落在迭代视图）\n```\n\n发布前本地验证：\n\n```bash\nnpm ci\nnpm run release:check  # 类型、覆盖率、全依赖审计、registry 签名、混淆构建、包内容与安装后黑盒验证\n```\n\n正式发布采用 SemVer tag，tag 必须与 `package.json` 版本完全一致且指向干净提交。推荐用 `npm version patch|minor|major` 同步修改包清单与锁文件并创建 `v<version>` tag，再生成 npm 与 GitHub Release 产物。已推送 tag 不得移动：如果发布失败后又修改了产物，必须递增版本并创建新 tag。\n\n`release:bundle` 会拒绝脏工作区、非稳定 SemVer、tag/版本不一致、原始业务源码或 source map 入包，以及无法证明混淆状态的产物。发布凭据只通过 npm 登录态或短期 granular access token 提供，禁止写入仓库、配置示例或日志。\n\n启动落地行为由配置决定：`defaultView`（默认 `sprint`）决定打开哪个视图；迭代视图的 `views.sprint.groupBy`（默认 `statusStage` 按阶段分组，运行时 `g` 键可循环切换）与 `defaultAssignee`（默认 `self` 只看自己，可设 `all` 或具体用户 id）决定初始分组与过滤。命令行显式指定视图（`yxdash bugs`）优先于配置；**管道模式不受 `defaultView` 影响**，未指定视图时始终是 `bugs`，保证 agent 拿到的输出结构稳定。\n\n令牌解析顺序：`YUNXIAO_ACCESS_TOKEN` 环境变量 → 配置中的 `token_cmd`（例如从系统 keychain 或密码管理器读取）。令牌永不明文落盘。\n\n配置查找顺序：`$YXDASH_CONFIG` → `./.yxdash.yaml` → `~/.config/yxdash/config.yaml`。\n\n多 profile 配置中的每个 profile 都是完整配置，互不继承，避免跨组织复用 `project`、`baseUrl` 或令牌命令。显式 `--profile` 优先于 `YXDASH_PROFILE`，其次使用 `defaultProfile`；只有一个 profile 时可自动选择。旧的单配置 YAML 继续兼容，但不能再附加 profile 选择参数。\n\n```yaml\ndefaultProfile: flow\nprofiles:\n  flow:\n    organizationId: <组织 id>\n    project: <项目 id>\n    baseUrl: https://yunxiaopro-cn-beijing.devops.aliyuncs.com\n    token_cmd: <安全令牌命令>\n  another-project:\n    organizationId: <另一组织 id>\n    project: <另一项目 id>\n    baseUrl: https://yunxiaopro-cn-beijing.devops.aliyuncs.com\n    token_cmd: <另一安全令牌命令>\n```\n\n```bash\nyxdash --profile flow\nYXDASH_PROFILE=another-project yxdash reqs\n```\n\n安全边界：工作目录的 `./.yxdash.yaml` 可能随任意 clone 的仓库而来，因此**其中的 `token_cmd` 会被拒绝执行**（`token_cmd` 只在用户级配置生效），加载工作目录配置时会在 stderr 提示确认。确实需要仓库级配置带 `token_cmd` 时，用 `--config ./.yxdash.yaml` 或 `$YXDASH_CONFIG` 显式指定（显式指定 = 显式信任）。\n\n## 视觉与 UI 配置\n\n默认视觉系统为 Dracula Pro：背景基准 `#22212C`、交互焦点紫 `#9580FF`、多选标记粉 `#FF80BF`、信息青 `#80FFEA`、警告黄 `#FFFF80`、错误红 `#FF9580`。紫色只编码“当前可操作焦点”，粉色只编码“已持有的多选项”，严重度颜色不复用，避免同一种颜色同时表达两个状态。光标仍使用终端反显通道，因此在彩色能力受限时也能辨认。\n\n品牌采用母版中的绿 → 青 → 蓝 → 紫工作流色谱。交互模式在首次数据真实加载期间显示终端原生品牌启动态，数据到达后立即进入看板，不附加固定等待时间；顶部根据宽度常驻 `yxdash`（≥80 列）或 `yx`（52–79 列），更窄时把全部空间留给工作项。`--json` / `--plain` 管道输出不包含任何品牌装饰，数据契约保持不变。\n\n仓库内品牌资产均由同一母版保真拆分：完整横版 [`assets/brand/yxdash-lockup.png`](./assets/brand/yxdash-lockup.png)、图形标 [`assets/brand/yxdash-symbol.png`](./assets/brand/yxdash-symbol.png)、文字标 [`assets/brand/yxdash-wordmark.png`](./assets/brand/yxdash-wordmark.png)。\n\n`ui` 段可按终端和工作习惯精调：\n\n| 配置 | 默认 | 作用 |\n|---|---|---|\n| `theme` | `dracula-pro` | `dracula-pro` 使用紫色视觉系统；`terminal` 沿用终端调色板 |\n| `accentColor` / `markColor` | 主题值 | 用 `#RRGGBB` 覆盖焦点色 / 多选色 |\n| `borderStyle` | `round` | 弹层边框：`round` / `single` / `double` / `classic` |\n| `animations` | `true` | `false` 后用静态点替代 spinner 动画 |\n| `previewPosition` | `auto` | 初始预览位置：`auto` / `right` / `bottom` |\n| `footer` | `auto` | `minimal` 只保留视图切换与帮助/退出 |\n| `density` / `detailBar` | `auto` | 列表密度与完整标题提示行；`density: compact` = 每个工作项恒占一行 |\n| `boardCardGap` | `true` | 看板卡片之间留一行空行（列高不足 16 行时自动降级为关闭） |\n| `titleFirst` | `false` | 把「标题」提到第一列（表格视图与迭代/焦点视图同时生效） |\n| `rowScroll` | `true` | 窄屏保留全部列并支持横向滚动；关闭则回到「按宽度丢列」。宽屏下两者渲染一致 |\n| `breakpoints` | `52/80/120` | `sm` / `md` / `lg` 响应式断点 |\n| `mouse` | `true` | 鼠标滚动、点击与双击 |\n\n一次性覆盖可用 `YXDASH_THEME=terminal` 或 `YXDASH_MARK_COLOR=<受支持的 ANSI 颜色名|#RRGGBB>`；环境变量优先于配置，适合排查不支持 truecolor 的远程终端。\n\n## 键位\n\n| 键 | 作用 | 键 | 作用 |\n|---|---|---|---|\n| `1` `2` `3` `4` | 切换视图：缺陷 / 需求 / 迭代 / 焦点（四个视图内含义完全一致） | `s` / `S` | 循环切换视图（同 1-4，前进/后退） |\n| `j/k` `↓/↑` `Ctrl+n/p` | 行移动（三套等价，弹层内通用） | `h/l` `←/→` | 相邻 section |\n| `g` / `G` | 首行 / 末行 | `Enter` / `p` | 预览开关 |\n| `P` | 预览位置（自动→右→底） | `Ctrl+d/u` | 预览翻页 |\n| `o` | 浏览器打开 | `y` / `Y` | 复制编号 / URL（有标记时复制全部标记项，一行一项） |\n| `v` | 标记/取消标记当前行并下移（多选，行首 2 格色轨 + 整行 accent；Esc 清除全部标记） | `Ctrl+k` | 命令面板：模糊搜索（中文/拼音/英文）并执行任意操作 |\n| `/` | 本地模糊筛（`Tab` 将关键词升级为服务端主题过滤；Esc 清除） | `F` | 结构化服务端过滤（Esc 取消，`x` 重置） |\n| `r` / `R` | 刷新当前 / 全部 | `f` | 当前项或标记批次加入/移出焦点集合 |\n| `e` | 编辑（状态/负责人/优先级/描述/评论） | `m` | 状态流转直达 |\n| `C` | 查看评论 | `?` / `q` | 帮助 / 退出 |\n| `H` / `L` | 行内左右滚动（窄屏保留全部列时用；看板下不生效） | `^` / `$` | 回到行首 / 行尾 |\n\n鼠标（默认开启）：\n\n| 操作 | 作用 |\n|---|---|\n| 滚轮 | 指针所在区域滚动：列表移光标（卡片行 1 条/格，普通行 3 行/格）、预览/评论面板滚 3 行/格、弹层列表移 1 项/格 |\n| 横向滚轮 | 指针在列表上时左右移动行窗口（4 格/格）；终端需上报 SGR 66/67，不支持时用 `H`/`L` |\n| 单击 | 表格行/迭代条目=选中；迭代组头=折叠展开；顶部 tab=切 section；底部视图名=切视图；左栏=切迭代；弹层条目=移动选中 |\n| 双击 | 条目=开关预览（等价 `Enter`）；弹层条目=确认（等价 `Enter`）；组头双击不抖动 |\n| Shift+点击/拖选 | 交回终端：原生拖选复制、编号 OSC 8 超链接 |\n\n滚轮**只滚动内容，不切换数据源**——切 section 和切迭代都要发请求，一次滚轮动作会连发好几格，与限流预算冲突。右键/中键不接管，留给终端。关闭鼠标：配置 `ui.mouse: false`，或临时 `YXDASH_NO_MOUSE=1`；关闭后行为与未引入该特性时逐字节一致。\n\n编辑说明：\n\n- **字段编辑**：`e` 打开菜单（当前值一览）→ 选字段 → 选择式弹层（光标预置在当前值、`●` 标记、Enter 提交、Esc 返回；选中当前值 Enter 视为「未变更」不发请求）。候选严格取自**该工作项自身类型**的工作流/字段配置，负责人候选来自当前视图人员（自己标 ★）。\n- **富文本编辑**：`e→d`（描述）/ `e→c`（新增评论）挂起 TUI，把终端交给外部编辑器（解析链 `$YXDASH_EDITOR → $VISUAL → $EDITOR → nvim → vim → vi`），编辑临时 markdown 文件；**保存退出即提交**，清空正文或未修改即取消——与 Claude Code 的 vim 编辑对话框同款方案。描述基线每次现拉服务端最新（避免覆盖他人改动）；RICHTEXT 原文会作为注释块附在缓冲区末尾备份（提交时自动剥离）；提交失败保留草稿，下次同一工作项编辑时自动恢复。\n- 写操作仅在 TUI 中由显式操作触发；`--json/--plain` 管道面保持只读。\n\n迭代视图专属（master-detail：左栏迭代列表，右侧按分组折叠展示；默认只看需求——产品类/技术类/AR 三类全含，缺陷隐藏）：\n\n| 键 | 作用 | 键 | 作用 |\n|---|---|---|---|\n| `h/l` `←/→` | 切换迭代（也可点左栏） | `g` | 分组维度：阶段→负责人→类型 |\n| `a` | 按负责人过滤（★=自己，含计数） | `b` | 显示/隐藏迭代内缺陷 |\n| `空格` | 折叠/展开光标所在分组 | `Enter` | 组头=折叠该组；条目=预览 |\n| `za` `zo` `zc` | 切换 / 展开 / 折叠当前分组 | `zs` | **只展开当前分组**（其余全折叠） |\n| `zR` `zM` | 全部展开 / 全部折叠（`c` 在两者间切换） | `zj` `zk` | 跳到下 / 上一个分组头 |\n\n折叠说明（vim 式 fold）：\n\n- **按单个阶段展开**：`zM` 全折叠 → `zj` 逐个跳分组（或 `j/k`）→ `空格`/`zo` 展开要看的那个；已经站在某条目上时，`zs` 一键变成「只展开这一个分组」。\n- 条目行上按 `空格`/`zc` 折的是**它所属的分组**，光标随即回到组头——不必先移到组头再折。\n- 折叠不丢阅读位置：任何折叠动作后光标都会锚回原来那条（条目被折起时退到它的组头）。\n- 按下 `z` 后提示行变成折叠键速查（`z… a切换 o展开 …`），此时任意非折叠键（含 `Esc`）都只是取消，不会触发原本的功能——`zq` 不会退出。\n- 「全折叠」是基线而非一次性动作：切换迭代后仍然保持折叠状态，刷新后新出现的分组也跟随基线；切换分组维度只清掉单组的例外。\n\n## Agent / 管道模式（Claude Code 等）\n\nTUI 之外，`yxdash` 同时是结构化数据源——stdout 只输出数据，警告与错误走 stderr：\n\n```bash\nyxdash bugs --json                  # 缺陷视图全部 sections，JSON（每条含 url）\nyxdash bugs --json --section 1      # 只要「我的未解」\nyxdash reqs --plain | column -t -s$'\\t'   # TSV，grep/awk 友好\nyxdash sprint --json                # 当前迭代需求按阶段分组 + 每人计数\nyxdash sprint --json --assignee 张三 --group-by assignee\nyxdash sprint --plain --with-bugs   # 连同缺陷（TSV 带 group 列）\nyxdash focus --json                 # 本地焦点集合，按需求/缺陷/任务分组\nyxdash bugs --json --profile flow   # 从多 profile 配置选择目标项目\n```\n\n- 退出码：`0` 成功 · `1` 有 section 失败 · `2` 参数/配置错误。\n- stdout 非 TTY 时自动进入 `--plain` 模式（管道安全，绝不渲染交互界面）。\n- 开发期等价形式：`npm run dev -- bugs --json` 或 `tsx src/cli.tsx bugs --json`。\n\n## 常用命令\n\n```bash\nnpm run dev              # tsx 直跑 TUI\nnpm run typecheck        # 严格类型检查（含测试）\nnpm test                 # vitest 全量单测\nnpm run test:coverage    # 覆盖率（阈值 90%）\nnpm run build            # tsc 产出 dist/\nnpm run smoke            # 真实 API 冒烟（需令牌，不进 CI）\n```\n\n## 设计要点（详见 docs/）\n\n- 需求/缺陷视图 = gh-dash 骨架（自绘表格 + sections tab + 预览面板）；不做多列 kanban 主视图。\n- 数据层直连 Yunxiao OpenAPI（`x-yunxiao-token`；专有云 Region 版与中心版路径分叉自动判定，可用 `edition` 显式覆盖）。\n- 防漂移：配置写状态名，启动时经 workflow 接口解析成 ID；全部解析失败时回退「全量拉取 + 本地过滤」。`sprint: current` 运行时解析（排除 backlog 伪迭代）。\n- 限流保护：令牌桶（容量 5、2/s）+ 429/5xx 指数退避 + 只刷可见 section + 元数据 TTL 缓存。\n- 刷新三重机制：自动轮询（默认 5 分钟，`intervalSeconds: 0` 关闭）+ `r/R` 手动 + 终端焦点回归触发；刷新失败保留旧数据（stale-while-revalidate）。\n- 链接：`o` 键 `execFile` 打开为主路径；OSC 8 超链接为增强（tmux 需 `set -ga terminal-features \"*:hyperlinks\"`）；复制经系统剪贴板，SSH 场景回退 OSC 52。\n- 运行时可观测性（M10）：常驻日志落 `~/.local/state/yxdash/yxdash.log`（`XDG_STATE_HOME` 生效时随之；`log.level` / `YXDASH_LOG_LEVEL` 调级，`off` 关闭；`log.file` / `YXDASH_LOG_FILE` 改路径；超 512KB 轮转一代）。记录启动、退出原因、未捕获异常堆栈与输入看门狗告警；**令牌、请求体、响应体一律不入日志**。\n- 不会再静默消失（M10）：全屏 TUI 的堆栈会被 alternate screen 一并抹掉，而本应用所有定时器都是 `unref` 的，一旦 stdin 失去引用事件循环就空、Ink 自行卸载、退出码 0。交互模式因此全程持有一个 **ref 的 keepalive 句柄**，并用同一个 tick 监测 stdin 是否意外丢失 raw 模式（去抖两拍后自愈，最多 3 次）。异常退出会在**主屏**留一行并指向日志。\n- 逃生舱：`YXDASH_NO_ALTSCREEN=1` 禁全屏；`YXDASH_FULL_REPAINT=1` 关增量渲染（tmux/ConPTY 残影时用）；`YXDASH_NO_MOUSE=1` 关鼠标上报；`YXDASH_THEME=terminal` 临时沿用终端配色；`YXDASH_MARK_COLOR=blueBright`（或其他受支持的 ANSI 颜色名/`#rrggbb`）改多选标记色，非法值回落当前主题默认值。\n- 窄屏不再丢列（M13）：`ui.rowScroll` 默认开启后，列不再按宽度丢弃，而是按自然宽度排开、由 `H`/`L`/`^`/`$` 或鼠标横向滚轮移动窗口；行首 2 格色轨固定不滚，所以标记与状态色块永远可见。宽屏下自然宽度本就装得下，渲染与之前逐字节一致。状态栏在可滚动时显示 `H/L 横滚 n/max`，这是「右边还有内容」的唯一信号。\n- 看板卡片分隔（M13）：卡片之间加一行空行、色轨在卡片最后一行断开、编号行降一档亮度，让标题成为视觉重心。空行不带色轨也不吃光标高亮，否则它就只是高亮块上的一个缺口而非分隔。\n- 鼠标：SGR 编码（`?1000h`+`?1006h`，不开移动上报）；渲染与命中测试共用 `ui/layout/lists.ts` 的同一份视口算术，所见即可点；解析失败的序列原样落回键盘路径，终端不支持时零影响。tmux 需 `set -g mouse on` 才会转发。\n\n## 读写边界\n\n读为主：看板/管道查询全部只读。写操作（M3：字段修改、描述编辑、新增评论）仅在 TUI 中由显式选择/保存触发，agent 管道面（`--json/--plain`）不提供任何写入。令牌只经环境变量或 `token_cmd` 获取，永不落盘。\n","readmeFilename":"README.md"}