diff --git a/.ua/add-entry.mjs b/.ua/add-entry.mjs deleted file mode 100644 index b6bae6d..0000000 --- a/.ua/add-entry.mjs +++ /dev/null @@ -1,10 +0,0 @@ -import { readFileSync, writeFileSync } from 'node:fs'; - -// 用法:node .ua/add-entry.mjs <条目json文件>:把自补条目追加进 backlog(按 id 升序插到末尾) -const [src] = process.argv.slice(2); -const b = JSON.parse(readFileSync('.ua/backlog.json', 'utf8')); -const entry = JSON.parse(readFileSync(src, 'utf8')); -if (b.items.some((i) => i.id === entry.id)) throw new Error(`id 已存在:${entry.id}`); -b.items.push(entry); -writeFileSync('.ua/backlog.json', JSON.stringify(b, null, 2) + '\n', 'utf8'); -console.log('added', entry.id, entry.title); diff --git a/.ua/backlog.json b/.ua/backlog.json index a932a3f..c4b9e92 100644 --- a/.ua/backlog.json +++ b/.ua/backlog.json @@ -3167,6 +3167,15 @@ "motivation": "文档里写明「拖到边缘不会自动滚动,条目超过一屏就别用」,这等于把最常见的场景(几十条检查单)挡在门外:拖到容器下沿不动,用户只能反复滚动重来。", "acceptance": "① dragstart 里一次算好最近的纵向滚动祖先(overflow-y auto/scroll 且确已溢出),dragover 每帧只在贴边 48px 感应带内按帧滚 12px;② 离开感应带或 dragend 立即取消帧并清状态,不留后台 rAF;③ 找不到滚动祖先(整页滚动)时不接管;④ manifest 步骤与配方 19 要点同步改写,npm run check 全绿。", "notes": "dragstart 用 scrollHost() 一次算最近纵向滚动祖先(overflow-y auto/scroll 且已溢出),dragover 在上下 48px 感应带内按帧滚 12px(EDGE_BAND/EDGE_STEP 常量),离开感应带或 dragend 取消 rAF 并清 scroller/edgeDir;找不到祖先不接管;manifest 步骤与配方 19 要点同步" + }, + { + "id": "g309", + "domain": "tooling", + "status": "open", + "title": "把每轮迭代的手工留痕脚本收成 ua iter done / add", + "motivation": "每轮收尾都要临时写 node 脚本改 backlog、手拼 iterations.log 的 JSON——历史踩过 ts 手写缺时区、字段顺序自创、状态忘记改、哈希抄错,lint-iterations 事后才拦。这条流程本该由 CLI 保证,不该每轮靠人记。", + "acceptance": "① 新增 ua iter done [notes]:backlog 置 done、追加 {ts,id,result,commit,summary} 固定字段行,ts 由本机时钟生成带 +08:00 偏移,commit 校验 7-40 位哈希,条目不存在直接报错;② ua iter add :五字段齐全 + id 唯一校验后追加;③ usage 串、dispatch、CLI 清单三处同步(doctor 通过);④ 临时脚本 .ua/log-one.mjs 与 .ua/add-entry.mjs 删除;⑤ npm run check 全绿。", + "notes": "" } ] } diff --git a/.ua/index.json b/.ua/index.json index bd64d89..08e58d1 100644 --- a/.ua/index.json +++ b/.ua/index.json @@ -1,6 +1,6 @@ { "$schema": "ui-arch-registry-index/0.1", - "generatedAt": "2026-10-26T16:37:31.858Z", + "generatedAt": "2026-10-26T16:38:55.415Z", "repoRoot": ".", "packages": [ { @@ -4769,9 +4769,10 @@ "ua audit:visual [--json|--baseline]:视觉漂移门禁,统计皮肤包里各类硬编码视觉字面量(字号/动效时长/阴影/圆角/焦点环/内距/控件高度/字重/行高/层级/边框色)并与 .ua/visual-baseline.json 棘轮比对,超基线退出码 1;--baseline 重写基线,--json 出机器可读计数与每类命中行号(line / prop / value / hint,Agent 可直接定位)", "ua audit:contrast [--json|--list]:对比度门禁,把令牌里 18 组「前景色 × 底色」配对按 WCAG 公式算成对比度(求值支持 var() 与 color-mix,半透明底先压到页面底色),亮/暗 × 常规/高对比四套分算,低于阈值(正文 7 / 常规 4.5 / 禁用 2.6 / 非文本 3)退出码 1;--json 出逐对明细,--list 只列配对表", "ua audit:motion [--json]:动效兜底门禁,两类必查——① 带 infinite 的动画逐个核对是否在 prefers-reduced-motion 块里 animation: none;② 悬停 / 按压的位移(translate)是否在减少动效下归零(认 ua- 类通配的全局规则)。缺兜底退出码 1(--json 出逐条明细)", - "ua audit:surface [--json|--list]:表面阶梯门禁,逐档核对底色对底色的亮度比(页面底 → 表面 → 悬停底 → 按下底 ≥1.04、凹陷底 ≥1.02),亮/暗 × 常规/高对比四套主题各算一遍,不达标退出码 1;对比度只管文字读不读得清,管不到「悬停有没有反馈」(实测过 1.008 的悬停底)", + "ua audit:surface [--json|--list]:表面阶梯门禁,逐档核对底色对底色的亮度比(页面底 → 表面 → 悬停底 → 按下底 ≥1.04、凹陷底 ≥1.02),外加两档半透明淡底压在表面上的可见度(选中底 ≥1.04、悬停底 ≥1.04),亮/暗 × 常规/高对比四套主题各算一遍,不达标退出码 1;对比度只管文字读不读得清,管不到「悬停有没有反馈」(实测过 1.008 的悬停底)", "ua mcp:零依赖 stdio MCP server,暴露 list_components / get_component / search_components / get_tokens / list_recipes / get_recipe;get_component 支持 format: md 直接取可粘贴的 Markdown 片段", - "ua loop [--json]:迭代循环诊断,一眼看清锁心跳(是否 15 分钟内)、上次留痕、backlog 待办与视觉欠账数,并给出本轮该不该抢锁、下一条该选谁;多实例错位接力时不必翻调度器数据库" + "ua loop [--json]:迭代循环诊断,一眼看清锁心跳(是否 15 分钟内)、上次留痕、backlog 待办与视觉欠账数,并给出本轮该不该抢锁、下一条该选谁;多实例错位接力时不必翻调度器数据库", + "ua iter done [notes]:一轮迭代收尾——backlog 条目置 done、按固定字段顺序追加 .ua/iterations.log 一行(ts 由本机时钟生成带 +08:00,commit 校验 7-40 位哈希);ua iter add <条目json文件> 补一条自选题(id 唯一 + 五字段齐全校验)" ], "keyTypes": [ "ua.manifest.json 清单结构", diff --git a/.ua/log-one.mjs b/.ua/log-one.mjs deleted file mode 100644 index dbdc859..0000000 --- a/.ua/log-one.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import { readFileSync, writeFileSync, appendFileSync } from 'node:fs'; - -// 用法:node .ua/log-one.mjs -const [id, commit, result, summary, ts] = process.argv.slice(2); - -const b = JSON.parse(readFileSync('.ua/backlog.json', 'utf8')); -const item = b.items.find((i) => i.id === id); -if (item) item.status = result === 'done' ? 'done' : 'open'; // 失败保持 open -writeFileSync('.ua/backlog.json', JSON.stringify(b, null, 2) + '\n', 'utf8'); - -// 留痕行:字段顺序固定 ts/id/result/commit/summary,ts 由 date 命令实测传入 -appendFileSync('.ua/iterations.log', JSON.stringify({ ts, id, result, commit, summary }) + '\n', 'utf8'); -console.log('logged', id, result, commit, ts); diff --git a/AGENTS.md b/AGENTS.md index 3d90c2e..a75828f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -52,7 +52,7 @@ 可用工具:`list_components` / `get_component`(传 `format: "md"` 直接拿 Markdown 片段,等同 `ua info --md`)/ `search_components` / `get_tokens`(返回 --ua-* 令牌清单,避免硬编码颜色间距)/ `list_recipes` / `get_recipe`(取跨组件组合配方:骨架代码 + 要点 + 用到的组件 id,配好再逐个 `get_component` 查参数)。 -2. **CLI**:`node packages/tools/cli/bin/ua.js loop [--json](迭代循环诊断:锁心跳 / 上次留痕 / 待办数) | list [--json|--components] | search <关键词> | info [--json|--md](--md 出可粘贴的 Markdown 片段:标题 + 参数表 + 用法 + 示例) | recipes [编号] [--json] | index | docs | style | verify | changelog`(`--json` 给脚本与 Agent 用,不必解析文本);`search` 覆盖 id / 标题 / 参数名 / 参数说明 / 步骤五层 + 配方三层(标题 / 配方组件 / 要点,命中行直接给 `ua recipes <编号>` 指路),命中非 id 标题时会标出命中字段(如「← 参数说明含『处理中』」),`--json` 输出 `{ components, recipes }` 两数组、各项带 `matched` 字段 +2. **CLI**:`node packages/tools/cli/bin/ua.js loop [--json](迭代循环诊断:锁心跳 / 上次留痕 / 待办数) | iter done (迭代收尾:置 done + 写留痕,ts 由本机时钟生成) | iter add <条目json>(补自选题) | list [--json|--components] | search <关键词> | info [--json|--md](--md 出可粘贴的 Markdown 片段:标题 + 参数表 + 用法 + 示例) | recipes [编号] [--json] | index | docs | style | verify | changelog`(`--json` 给脚本与 Agent 用,不必解析文本);`search` 覆盖 id / 标题 / 参数名 / 参数说明 / 步骤五层 + 配方三层(标题 / 配方组件 / 要点,命中行直接给 `ua recipes <编号>` 指路),命中非 id 标题时会标出命中字段(如「← 参数说明含『处理中』」),`--json` 输出 `{ components, recipes }` 两数组、各项带 `matched` 字段 3. **静态索引**:`.ua/index.json`(机器可读索引)、`llms.txt`(速览)或 **`llms-full.txt`(全量 Agent 文档:逐组件参数 / 回调 / 手把手步骤 / 令牌 / 组合配方,无图形纯文本,喂给 Agent 首选)**。 diff --git a/llms-full.txt b/llms-full.txt index 54f19ce..a018f11 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,6 +1,6 @@ # @ui-arch 组件库 Agent 文档(无图形版) -> 自动生成于 2026-10-26T16:37:31.858Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 +> 自动生成于 2026-10-26T16:38:55.415Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 > 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。 ## 快速上手 @@ -2747,9 +2747,10 @@ API 速览: - ua audit:visual [--json|--baseline]:视觉漂移门禁,统计皮肤包里各类硬编码视觉字面量(字号/动效时长/阴影/圆角/焦点环/内距/控件高度/字重/行高/层级/边框色)并与 .ua/visual-baseline.json 棘轮比对,超基线退出码 1;--baseline 重写基线,--json 出机器可读计数与每类命中行号(line / prop / value / hint,Agent 可直接定位) - ua audit:contrast [--json|--list]:对比度门禁,把令牌里 18 组「前景色 × 底色」配对按 WCAG 公式算成对比度(求值支持 var() 与 color-mix,半透明底先压到页面底色),亮/暗 × 常规/高对比四套分算,低于阈值(正文 7 / 常规 4.5 / 禁用 2.6 / 非文本 3)退出码 1;--json 出逐对明细,--list 只列配对表 - ua audit:motion [--json]:动效兜底门禁,两类必查——① 带 infinite 的动画逐个核对是否在 prefers-reduced-motion 块里 animation: none;② 悬停 / 按压的位移(translate)是否在减少动效下归零(认 ua- 类通配的全局规则)。缺兜底退出码 1(--json 出逐条明细) -- ua audit:surface [--json|--list]:表面阶梯门禁,逐档核对底色对底色的亮度比(页面底 → 表面 → 悬停底 → 按下底 ≥1.04、凹陷底 ≥1.02),亮/暗 × 常规/高对比四套主题各算一遍,不达标退出码 1;对比度只管文字读不读得清,管不到「悬停有没有反馈」(实测过 1.008 的悬停底) +- ua audit:surface [--json|--list]:表面阶梯门禁,逐档核对底色对底色的亮度比(页面底 → 表面 → 悬停底 → 按下底 ≥1.04、凹陷底 ≥1.02),外加两档半透明淡底压在表面上的可见度(选中底 ≥1.04、悬停底 ≥1.04),亮/暗 × 常规/高对比四套主题各算一遍,不达标退出码 1;对比度只管文字读不读得清,管不到「悬停有没有反馈」(实测过 1.008 的悬停底) - ua mcp:零依赖 stdio MCP server,暴露 list_components / get_component / search_components / get_tokens / list_recipes / get_recipe;get_component 支持 format: md 直接取可粘贴的 Markdown 片段 - ua loop [--json]:迭代循环诊断,一眼看清锁心跳(是否 15 分钟内)、上次留痕、backlog 待办与视觉欠账数,并给出本轮该不该抢锁、下一条该选谁;多实例错位接力时不必翻调度器数据库 +- ua iter done [notes]:一轮迭代收尾——backlog 条目置 done、按固定字段顺序追加 .ua/iterations.log 一行(ts 由本机时钟生成带 +08:00,commit 校验 7-40 位哈希);ua iter add <条目json文件> 补一条自选题(id 唯一 + 五字段齐全校验) 一行用法: diff --git a/llms.txt b/llms.txt index 8bc73da..27ff2cf 100644 --- a/llms.txt +++ b/llms.txt @@ -161,9 +161,10 @@ - ua audit:visual [--json|--baseline]:视觉漂移门禁,统计皮肤包里各类硬编码视觉字面量(字号/动效时长/阴影/圆角/焦点环/内距/控件高度/字重/行高/层级/边框色)并与 .ua/visual-baseline.json 棘轮比对,超基线退出码 1;--baseline 重写基线,--json 出机器可读计数与每类命中行号(line / prop / value / hint,Agent 可直接定位) - ua audit:contrast [--json|--list]:对比度门禁,把令牌里 18 组「前景色 × 底色」配对按 WCAG 公式算成对比度(求值支持 var() 与 color-mix,半透明底先压到页面底色),亮/暗 × 常规/高对比四套分算,低于阈值(正文 7 / 常规 4.5 / 禁用 2.6 / 非文本 3)退出码 1;--json 出逐对明细,--list 只列配对表 - ua audit:motion [--json]:动效兜底门禁,两类必查——① 带 infinite 的动画逐个核对是否在 prefers-reduced-motion 块里 animation: none;② 悬停 / 按压的位移(translate)是否在减少动效下归零(认 ua- 类通配的全局规则)。缺兜底退出码 1(--json 出逐条明细) - - ua audit:surface [--json|--list]:表面阶梯门禁,逐档核对底色对底色的亮度比(页面底 → 表面 → 悬停底 → 按下底 ≥1.04、凹陷底 ≥1.02),亮/暗 × 常规/高对比四套主题各算一遍,不达标退出码 1;对比度只管文字读不读得清,管不到「悬停有没有反馈」(实测过 1.008 的悬停底) + - ua audit:surface [--json|--list]:表面阶梯门禁,逐档核对底色对底色的亮度比(页面底 → 表面 → 悬停底 → 按下底 ≥1.04、凹陷底 ≥1.02),外加两档半透明淡底压在表面上的可见度(选中底 ≥1.04、悬停底 ≥1.04),亮/暗 × 常规/高对比四套主题各算一遍,不达标退出码 1;对比度只管文字读不读得清,管不到「悬停有没有反馈」(实测过 1.008 的悬停底) - ua mcp:零依赖 stdio MCP server,暴露 list_components / get_component / search_components / get_tokens / list_recipes / get_recipe;get_component 支持 format: md 直接取可粘贴的 Markdown 片段 - ua loop [--json]:迭代循环诊断,一眼看清锁心跳(是否 15 分钟内)、上次留痕、backlog 待办与视觉欠账数,并给出本轮该不该抢锁、下一条该选谁;多实例错位接力时不必翻调度器数据库 + - ua iter done [notes]:一轮迭代收尾——backlog 条目置 done、按固定字段顺序追加 .ua/iterations.log 一行(ts 由本机时钟生成带 +08:00,commit 校验 7-40 位哈希);ua iter add <条目json文件> 补一条自选题(id 唯一 + 五字段齐全校验) - 用法: `node packages/tools/cli/bin/ua.js [--json|--md]|docs|tokens [--json|--unused]|style|verify|commit-lint|audit:visual|audit:contrast|audit:motion|doctor|mcp>;仓库内等价于 npm run index / docs / style / verify / audit:visual / audit:contrast / audit:motion / doctor` - 约定: 零依赖:只用 node 标准库,Node >= 18 - 约定: 清单是单一来源:代码注释、文档站、llms-full.txt、MCP 全部从 ua.manifest.json 派生 diff --git a/packages/tools/cli/bin/ua.js b/packages/tools/cli/bin/ua.js index bca7750..ceaa534 100644 --- a/packages/tools/cli/bin/ua.js +++ b/packages/tools/cli/bin/ua.js @@ -1902,6 +1902,64 @@ function cmdDoctor() { console.log(`doctor OK(${checks.length} 项全过)`); } +/*** 作用:把「改 backlog + 追加 iterations.log」收成一条命令——字段顺序与 +08:00 时间格式由代码保证, + * 省掉每轮手搓临时脚本(历史踩过:ts 手写、字段顺序自创、状态忘了改、哈希抄错)。 ***/ +const localStamp = () => { + const d = new Date(); + const pad = (n) => String(n).padStart(2, '0'); + const off = -d.getTimezoneOffset(); // 时区偏移(分钟),东八区为 +480 + const sign = off >= 0 ? '+' : '-'; + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}${sign}${pad(Math.floor(Math.abs(off) / 60))}:${pad(Math.abs(off) % 60)}`; +}; + +function cmdIter(args) { + const [sub, ...rest] = args; + const backlogFile = path.join(INDEX_DIR, 'backlog.json'); + const logFile = path.join(INDEX_DIR, 'iterations.log'); + const load = () => JSON.parse(fs.readFileSync(backlogFile, 'utf8')); + const itemsOf = (data) => (Array.isArray(data) ? data : data.items); + const save = (data, items) => { + if (Array.isArray(data)) fs.writeFileSync(backlogFile, JSON.stringify(items, null, 2) + '\n', 'utf8'); + else { data.items = items; fs.writeFileSync(backlogFile, JSON.stringify(data, null, 2) + '\n', 'utf8'); } + }; + if (sub === 'done') { + const [id, commit, summary, notes] = rest; + if (!id || !commit || !summary) { + console.error('usage: ua iter done [notes]'); + process.exit(2); + } + if (!/^[0-9a-f]{7,40}$/.test(commit)) { console.error(`commit 须为 7-40 位短哈希:${commit}`); process.exit(2); } + const data = load(); + const items = itemsOf(data); + const item = items.find((i) => i.id === id); + if (!item) { console.error(`backlog 里没有 ${id}(自补条目先用 ua iter add)`); process.exit(2); } + item.status = 'done'; + if (notes) item.notes = notes; // 备注缺省保留原值:只有显式传了才覆盖 + save(data, items); + const line = { ts: localStamp(), id, result: 'done', commit, summary }; // 字段顺序与 ITERATION.md 一致 + fs.appendFileSync(logFile, JSON.stringify(line) + '\n', 'utf8'); + console.log(`iter done ${id} → backlog 置 done,留痕 ${line.ts}(${commit})`); + console.log('接着提交元数据:git add -A && git commit -m "chore(backlog): 记录 ' + id + ' 完成"'); + return; + } + if (sub === 'add') { + const [file] = rest; + if (!file) { console.error('usage: ua iter add <条目json文件>'); process.exit(2); } + const entry = JSON.parse(fs.readFileSync(file, 'utf8')); + const missing = ['id', 'domain', 'title', 'motivation', 'acceptance'].filter((k) => !entry[k]); // 选题规则要求三件套齐全 + if (missing.length) { console.error(`条目缺字段:${missing.join(' / ')}`); process.exit(2); } + const data = load(); + const items = itemsOf(data); + if (items.some((i) => i.id === entry.id)) { console.error(`id 已存在:${entry.id}`); process.exit(2); } + items.push({ ...entry, status: entry.status ?? 'open', notes: entry.notes ?? '' }); + save(data, items); + console.log(`iter add ${entry.id}(${entry.domain}):${entry.title}`); + return; + } + console.error('usage: ua iter [notes] | add <条目json文件>>'); + process.exit(2); +} + // ---- 入口 ---- const [cmd, ...args] = process.argv.slice(2); @@ -1967,10 +2025,13 @@ switch (cmd) { case 'loop': cmdLoop(args); break; + case 'iter': + cmdIter(args); + break; case 'mcp': cmdMcp(); break; default: - console.log('usage: ua |info [--json|--md]|recipes [编号] [--json]|docs|tokens [--json|--unused]|style|sync-counts|verify|doctor|commit-lint|lint-iterations|audit:visual [--json|--baseline]|audit:contrast [--json|--list]|audit:motion [--json]|audit:surface [--json|--list]|loop [--json]|changelog|mcp>'); + console.log('usage: ua |info [--json|--md]|recipes [编号] [--json]|docs|tokens [--json|--unused]|style|sync-counts|verify|doctor|commit-lint|lint-iterations|iter|audit:visual [--json|--baseline]|audit:contrast [--json|--list]|audit:motion [--json]|audit:surface [--json|--list]|loop [--json]|changelog|mcp>'); process.exit(cmd ? 1 : 0); } diff --git a/packages/tools/cli/ua.manifest.json b/packages/tools/cli/ua.manifest.json index 1a4e9c4..138fd4f 100644 --- a/packages/tools/cli/ua.manifest.json +++ b/packages/tools/cli/ua.manifest.json @@ -24,9 +24,10 @@ "ua audit:visual [--json|--baseline]:视觉漂移门禁,统计皮肤包里各类硬编码视觉字面量(字号/动效时长/阴影/圆角/焦点环/内距/控件高度/字重/行高/层级/边框色)并与 .ua/visual-baseline.json 棘轮比对,超基线退出码 1;--baseline 重写基线,--json 出机器可读计数与每类命中行号(line / prop / value / hint,Agent 可直接定位)", "ua audit:contrast [--json|--list]:对比度门禁,把令牌里 18 组「前景色 × 底色」配对按 WCAG 公式算成对比度(求值支持 var() 与 color-mix,半透明底先压到页面底色),亮/暗 × 常规/高对比四套分算,低于阈值(正文 7 / 常规 4.5 / 禁用 2.6 / 非文本 3)退出码 1;--json 出逐对明细,--list 只列配对表", "ua audit:motion [--json]:动效兜底门禁,两类必查——① 带 infinite 的动画逐个核对是否在 prefers-reduced-motion 块里 animation: none;② 悬停 / 按压的位移(translate)是否在减少动效下归零(认 ua- 类通配的全局规则)。缺兜底退出码 1(--json 出逐条明细)", - "ua audit:surface [--json|--list]:表面阶梯门禁,逐档核对底色对底色的亮度比(页面底 → 表面 → 悬停底 → 按下底 ≥1.04、凹陷底 ≥1.02),亮/暗 × 常规/高对比四套主题各算一遍,不达标退出码 1;对比度只管文字读不读得清,管不到「悬停有没有反馈」(实测过 1.008 的悬停底)", + "ua audit:surface [--json|--list]:表面阶梯门禁,逐档核对底色对底色的亮度比(页面底 → 表面 → 悬停底 → 按下底 ≥1.04、凹陷底 ≥1.02),外加两档半透明淡底压在表面上的可见度(选中底 ≥1.04、悬停底 ≥1.04),亮/暗 × 常规/高对比四套主题各算一遍,不达标退出码 1;对比度只管文字读不读得清,管不到「悬停有没有反馈」(实测过 1.008 的悬停底)", "ua mcp:零依赖 stdio MCP server,暴露 list_components / get_component / search_components / get_tokens / list_recipes / get_recipe;get_component 支持 format: md 直接取可粘贴的 Markdown 片段", - "ua loop [--json]:迭代循环诊断,一眼看清锁心跳(是否 15 分钟内)、上次留痕、backlog 待办与视觉欠账数,并给出本轮该不该抢锁、下一条该选谁;多实例错位接力时不必翻调度器数据库" + "ua loop [--json]:迭代循环诊断,一眼看清锁心跳(是否 15 分钟内)、上次留痕、backlog 待办与视觉欠账数,并给出本轮该不该抢锁、下一条该选谁;多实例错位接力时不必翻调度器数据库", + "ua iter done [notes]:一轮迭代收尾——backlog 条目置 done、按固定字段顺序追加 .ua/iterations.log 一行(ts 由本机时钟生成带 +08:00,commit 校验 7-40 位哈希);ua iter add <条目json文件> 补一条自选题(id 唯一 + 五字段齐全校验)" ], "keyTypes": [ "ua.manifest.json 清单结构", @@ -55,4 +56,4 @@ ], "components": [] } -} \ No newline at end of file +}