
Nx monitor-ci 技能深度解析Agent 确定性脚本构建的 CI 自愈监控闭环【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx本文以 Nx 仓库中的monitor-ci技能文档为核心完整拆解其监控 Nx Cloud CI 流水线并处理自愈self-healing修复的全套机制从连接校验、配置参数、MCP 字段集到轮询主循环、确定性决策脚本、预算门控与修复流程。读完后你能掌握一个可落地的“编排器 Agent 一次性子代理 无状态决策脚本”三层架构设计并理解其中背压backoff、熔断circuit breaker、预算闸门等关键工程细节的实现依据。一、技能定位为什么不用 gh / glab 直接盯 CImonitor-ci是 Nx 仓库.opencode/skills/monitor-ci/SKILL.md内置的一个 OpenCode 技能其元信息声明了明确的触发时机当用户说 monitor ci、watch ci、check ci status 等意图时激活并且优先于 CI 提供方原生工具gh、glab等用于 CI 监控——因为它是唯一能接入 Nx Cloud 自愈能力的监控入口见 SKILL.md 的 frontmatter description。技能的角色被定义为编排器orchestrator它本身不直接调用 CI API而是派生子代理与 Nx Cloud 交互、运行确定性脚本做决策、并根据结果执行本地编码工作。仓库中还存在一个同名命令入口 .opencode/commands/monitor-ci.md内容与技能文件互为镜像含同样的参数提示argument-hint供/monitor-ci斜杠命令调用。二、架构总览四个组件各司其职文档 “Architecture Overview” 一节明确了四层分工这一分工在仓库文件结构中可一一对应验证组件职责仓库位置技能本体编排器派生spawn子代理、运行脚本、打印状态、做本地编码工作SKILL.mdci-monitor-subagent每次调用只执行一个 MCP 工具ci_information或update_self_healing_fix返回结构化结果后即退出ci-monitor-subagent.mdci-poll-decide.mjs确定性脚本输入ci_information结果 状态参数输出 action 状态消息ci-poll-decide.mjsci-state-update.mjs确定性脚本管理预算门控、动作后状态迁移、周期分类ci-state-update.mjs这种设计的核心思想值得注意“判断”与“执行”分离。子代理被明确约束“Do not loop, poll, or sleep”见 ci-monitor-subagent.md只执行四类命令之一——FETCH_STATUS按指定字段集拉状态、FETCH_HEAVY拉取修复详情并摘要化返回禁止回传原始 diff 或原始任务输出、UPDATE_FIX对修复执行 APPLY/REJECT/RERUN_ENVIRONMENT_STATE、FETCH_THROTTLE_INFO返回shortLink与cipeUrl。而状态比较、超时判定、预算计数等容易出错的逻辑全部下沉到两个无状态的.mjs脚本中主代理只负责按脚本输出的 JSON 行事。从源码结构看这是为了避免 LLM 在多轮轮询中累积状态漂移和上下文污染。三、前置条件Nx Cloud 连接校验监控循环启动前必须验证工作区已连接 Nx Cloud否则没有任何 CI 数据可用技能整体不可运行。文档的 Step 0 定义了校验流程检查工作区根目录的nx.json是否包含nxCloudId或nxCloudAccessToken若nx.json缺失或两个属性都不存在直接退出并输出标准引导消息引导用户连接 Nx Cloud已连接则进入主循环。技能文件头部还通过 OpenCode 的上下文占位符在激活时自动注入三个环境事实供后续决策使用Current Branch: !git branch --show-current Current Commit: !git rev-parse --short HEAD Remote Status: !git status -sb | head -1四、配置参数完整默认值与覆盖机制用户参数通过$ARGUMENTS传入解析后与下表默认值合并用户指令优先于默认行为参数默认值说明--max-cycles10代理主动触发的 CI Attempt 周期数上限超过则超时--timeout120监控总时长上限分钟--verbositymedium输出级别minimal/medium/verbose--branch(自动检测)要监控的分支--freshfalse忽略本会话先前的状态从头开始--auto-fix-workflowfalse对 CI Attempt 生成前的失败尝试常见修复如 lockfile 更新--new-cipe-timeout10动作执行后等待新 CI Attempt 的分钟数--local-verify-attempts3推送 CI 之前允许的本地验证 增强enhance轮数上限这些参数并非“纸面默认值”在脚本源码中都有对应落点--timeout分钟在 ci-poll-decide.mjs 中被乘以 60 转为秒--elapsed-seconds从start_time起的墙钟秒数是总预算的权威信号因为--timeout约束的是整个监控生命周期跨越多次 Attempt而不是单次调用。isTimedOut()优先使用墙钟值缺失时才回退到基于轮询节奏的估算。--new-cipe-timeout同样以分钟传入、内部转秒等待模式下每次轮询延迟固定 30 秒超时判定为pollCount * 30 newCipeTimeoutSeconds见 isWaitTimedOut。--local-verify-attempts的默认值 3 直接硬编码在gate命令的 fallback 中parseInt(getArg(--local-verify-attempts) || 3, 10)见 ci-state-update.mjs。五、MCP 工具参考三档字段集控制轮询开销文档定义了三个字段集原则是“用最轻的集拿你需要的东西”WAIT_FIELDS: cipeUrl,commitSha,cipeStatus LIGHT_FIELDS: cipeStatus,cipeUrl,branch,commitSha,selfHealingStatus,verificationStatus,userAction,failedTaskIds,verifiedTaskIds,selfHealingEnabled,failureClassification,couldAutoApplyTasks,autoApplySkipped,autoApplySkipReason,shortLink,confidence,confidenceReasoning,hints,selfHealingSkippedReason,selfHealingSkipMessage HEAVY_FIELDS: taskOutputSummary,suggestedFix,suggestedFixReasoning,suggestedFixDescription两个 MCP 工具的参数约定ci_information接受branch可选缺省取当前 git 分支、select逗号分隔字段名、pageToken长字符串从 0 起的分页。update_self_healing_fix接受shortLink与动作APPLY/REJECT/RERUN_ENVIRONMENT_STATE。字段集的选择逻辑在轮询循环中等待模式用WAIT_FIELDS普通模式首次轮询或检测到新 CI Attempt 后用LIGHT_FIELDS只有需要分析修复内容时才升级到HEAVY_FIELDS。六、主循环轮询、决策与状态回写Step 1初始化追踪状态进入主循环前初始化一组追踪变量完整继承自 SKILL.mdcycle_count 0 # 仅统计代理主动触发的周期计入 --max-cycles start_time now() # 每次轮询以 --elapsed-seconds 传给决策脚本跨 Attempt 强制执行 --timeout no_progress_count 0 local_verify_count 0 env_rerun_count 0 last_cipe_url null expected_commit_sha null agent_triggered false # 监控动作触发新 CI Attempt 后置 true poll_count 0 wait_mode false prev_status / prev_cipe_status / prev_sh_status / prev_verification_status / prev_failure_classification nullStep 2轮询循环每次迭代三步走2a. 派生子代理FETCH_STATUS——按模式选定字段集后调用ci_information等待结果再继续。2b. 运行决策脚本node skill_dir/scripts/ci-poll-decide.mjs subagent_result_json poll_count verbosity \ [--wait-mode] \ [--prev-cipe-url last_cipe_url] \ [--expected-sha expected_commit_sha] \ [--prev-status prev_status] \ [--timeout timeout_minutes] \ [--new-cipe-timeout new_cipe_timeout_minutes] \ [--elapsed-seconds seconds_since_start_time] \ [--env-rerun-count env_rerun_count] \ [--no-progress-count no_progress_count] \ [--prev-cipe-status prev_cipe_status] \ [--prev-sh-status prev_sh_status] \ [--prev-verification-status prev_verification_status] \ [--prev-failure-classification prev_failure_classification]--timeout与--new-cipe-timeout以分钟传入脚本内部转秒--elapsed-seconds是自start_time起的整秒数一旦开始监控就必须每次调用都传这是--timeout作为总预算生效的前提。脚本输出单行 JSON{ action, code, message, delay?, noProgressCount, envRerunCount, fields?, newCipeDetected?, verifiableTaskIds? }。2c. 处理脚本输出——回写追踪状态no_progress_count output.noProgressCountenv_rerun_count output.envRerunCountprev_*四个状态取自子代理结果prev_status output.action : (output.code || subagent_result.cipeStatus)poll_count然后按action分支poll打印消息、睡delay秒、回到 2a若newCipeDetected则退出等待模式、wait打印消息、睡delay秒、回到 2a、done携带output.code进入 Step 3。决策脚本内部一棵 24 级优先级的纯函数决策树ci-poll-decide.mjs 头部的注释把整个决策优先级完整列出classify()是纯决策树buildOutput()负责映射到带消息、延迟、计数器的完整输出。关键机制都有源码可查等待模式优先检测到新 CI Attempt →pollnew_cipe_detected否则总--timeout预算优先于--new-cipe-timeout防止“apply→wait”多轮循环绕过总超时→polling_timeout再否则no_new_cipe/ 继续等待。熔断器noProgressCount 13判定为circuit_breakerL208。文档对“进展”的定义是cipeStatus、selfHealingStatus、verificationStatus、failureClassification任一发生变化对应源码hasStateChanged()L124-L135此外“真实进展”码如ci_success、fix_apply_ready也会把noProgressCount归零L374-L382。退避策略backoff()使用固定延迟序列[60, 90, 120, 180]秒按noProgressCount递增取用L119-L122等待模式延迟固定 30 秒检测到新 CI Attempt 时延迟 60 秒。新 CI Attempt 检测isNewCipe()有两条判据——cipeUrl变化或commitSha等于动作前记录的expected_shaL153-L158。前者覆盖 MCP 触发的新 Attempt后者覆盖本地 push 触发的场景。任务分类categorizeTasks()把失败任务按projectName:target中是否含e2e切分为all_verified/e2e_only/needs_local_verify三类L101-L117直接决定修复走哪条路。自愈状态机selfHealingStatus COMPLETED时按verificationStatus与任务分类分流到fix_needs_review/fix_apply_ready/fix_needs_local_verifyuserAction APPLIED_AUTOMATICALLY说明自愈已自动应用只需继续轮询selfHealingStatus FAILED或“CI 失败且自愈禁用/不可执行”分别落到fix_failed与no_fixL252-L302。消息格式由--verbosity控制minimal只在状态串${cipeStatus}|${selfHealingStatus}|${verificationStatus}变化时输出medium输出Poll #N | msgverbose额外输出完整状态行。所有面向用户的消息含编排器自发的动作消息统一加[monitor-ci]前缀。七、状态管理脚本预算门控、动作后迁移与周期分类ci-state-update.mjs 提供三个子命令全部输出单行 JSONgate动作前的预算闸门门类型上限超限行为local-fix--local-verify-attempts默认 3返回allowed: false与“Local fix budget exhausted (n/max)”消息env-rerun硬编码 2返回allowed: false提示“环境重跑 2 次后问题仍在需人工介入”门控通过时会顺带递增计数器并返回新值“counter already incremented by gate”防止代理重复消费预算。典型调用node ci-state-update.mjs gate --gate-type local-fix --local-verify-count 1 --local-verify-attempts 3。post-action动作后的状态迁移在“应该会触发新 CI Attempt”的动作之后运行node skill_dir/scripts/ci-state-update.mjs post-action \ --action type \ --cipe-url current_cipe_url \ --commit-sha git_rev_parse_HEAD动作类型共 8 种fix-auto-applying、apply-mcp、apply-local-push、reject-fix-push、local-fix-push、env-rerun、auto-fix-push、empty-commit-push。源码按追踪方式分成两组postActionfix-auto-applying/apply-mcp/env-rerun—— MCP 触发按cipeUrl追踪lastCipeUrl有值expectedCommitSha为 nullapply-local-push/reject-fix-push/local-fix-push/auto-fix-push/empty-commit-push—— 本地 push 触发按commitSha追踪。注意agentTriggered的判定fix-auto-applying意味着是自愈系统而非监控器触发的新 Attempt不计入--max-cycles预算。输出{ waitMode: true, pollCount: 0, lastCipeUrl, expectedCommitSha, agentTriggered }编排器据此重置轮询状态并回到 Step 2。cycle-check周期分类与上限闸门决策脚本返回done时必须在处理 code 之前先跑周期检查node skill_dir/scripts/ci-state-update.mjs cycle-check \ --code code \ [--agent-triggered] \ --cycle-count cycle_count --max-cycles max_cycles \ --env-rerun-count env_rerun_countcycleCheck 的规则上一周期若为代理触发则cycleCountcode 非environment_issue时envRerunCount归零limitReachedcycleCount maxCycles是硬性停止——打印消息并结束监控不再处理 codeapproachingLimit距上限不足 2 个周期是建议性警告——询问用户继续加 5 或 10 个周期还是停止。若上一周期非代理触发则记录“检测到人工 push”。八、按状态定义的默认行为完整继承决策脚本返回的每个 code 都有默认行为用户指令可覆盖其中任意一条。简单退出类——报告并退出状态默认行为ci_success成功退出cipe_canceled退出CI 被取消cipe_timed_out退出CI 超时polling_timeout退出轮询总时长超时circuit_breaker退出连续 13 次轮询无进展environment_rerun_cap退出环境重跑次数耗尽fix_auto_applying自愈正在处理——只记录last_cipe_url进入等待模式无需 MCP 调用或本地 git 操作error等 60 秒后继续循环需要动作类——处理时需查阅 references/fix-flows.md 的详细流程状态概要fix_auto_apply_skipped修复已验证但自动应用被跳过如防循环。告知用户提供手动应用选项fix_apply_ready修复已验证全部任务或仅 e2e。经 MCP 应用fix_needs_local_verify修复含未验证的非 e2e 任务。本地运行后再应用或增强fix_needs_review修复验证失败或未执行。分析后决策fix_failed自愈失败。拉取 heavy 数据尝试本地修复先过门控no_fix无可用修复。拉取 heavy 数据尝试本地修复先过门控或退出environment_issue经 MCP 请求环境重跑先过门控self_healing_throttled拒绝旧修复尝试本地修复no_new_cipe新 CI Attempt 始终未生成。走 auto-fix 流程或带指引退出cipe_no_tasksCI 失败但未记录任何任务。用空提交重试一次三条始终适用的关键规则Git 安全按文件名列名暂存——git add -A或git add .可能把用户无关的 WIP 或密钥提交进去环境类失败OOM、command not found、permission denied立即放弃——这不是代码 bug消耗本地修复预算是浪费门控检查尝试本地修复前先跑ci-state-update.mjs gate预算耗尽则打印消息退出。Step 3动作类状态处理与工具调用约定action done时的处理顺序先跑 cycle-checkStep 4→ 检查 code → 查默认行为表 → 检查用户指令覆盖 → 执行动作 → 若动作会触发新 CI Attempt 则执行 Step 3a → 若形成循环则回到 Step 2。各状态需要的工具调用fix_apply_ready→update_self_healing_fixAPPLYfix_needs_local_verify→ 先以HEAVY_FIELDS调ci_information拿修复详情再本地验证fix_needs_review→HEAVY_FIELDS→ 取suggestedFixDescription、suggestedFixSummary、taskFailureSummariesfix_failed/no_fix→HEAVY_FIELDS→ 取taskFailureSummaries作为本地修复上下文environment_issue→update_self_healing_fixRERUN_ENVIRONMENT_STATEself_healing_throttled→HEAVY_FIELDS取selfHealingSkipMessage再对每个旧修复调用update_self_healing_fix九、修复流程详解fix-flows.md 全量展开fix-flows.md 给出了每个动作类状态的完整执行流要点如下fix_needs_local_verify脚本输出verifiableTaskIds按锁文件检测包管理器pnpm-lock.yaml→pnpm nx、yarn.lock→yarn nx、否则npx nx为每个可验证任务派生general子代理并行本地运行全部通过则APPLY并进入等待模式任一失败则走“本地应用 增强”流程。fix_needs_review派生FETCH_HEAVY子代理后分析修复内容——修复看起来正确 → 经 MCP 应用需要增强 → Apply Locally Enhance 流程修复错误 → 先跑gate --gate-type local-fix允许则走 Reject Fix From Scratch 流程不允许则打印消息退出。fix_failed/no_fix拉取taskFailureSummaries→ 门控检查计数器由 gate 递增→ 本地修复成功则提交、push、进入等待模式失败则退出。environment_issuegate --gate-type env-rerun→RERUN_ENVIRONMENT_STATE→ 带last_cipe_url进入等待模式。self_healing_throttled解析限流消息中的 CI Attempt URL正则/cipes/{id}→ 对每个 URL 取shortLink并REJECT→ 门控允许的本地修复都不行则兜底git commit --allow-empty -m ci: rerun after rejecting throttled fixes后 push进入等待模式。no_new_cipe报告“未找到 CI attempt”建议检查 CI 提供方若开启--auto-fix-workflow则检测包管理器、执行安装、lockfile 有变更则提交进入等待模式。cipe_no_tasksgit commit --allow-empty -m chore: retry ci [monitor-ci] push 重试一次重试后仍是cipe_no_tasks则退出。三条修复动作流Fix Action FlowsApply via MCPAPPLY后新 CI Attempt 自动产生无任何本地 git 操作。Apply Locally Enhancenx-cloud apply-locally shortLink状态置为APPLIED_LOCALLY→ 增强代码修复失败任务 → 本地复跑验证 → 仍失败则再过一次local-fix门控不允许则把当前状态提交 push让 CI 做最终裁判允许则回到增强循环→ 通过则提交、push、等待。Reject Fix From Scratch门控 →REJECT→ 本地从零修复 → 提交、push、等待。文档还专门区分环境/工具类失败与代码类失败command not found、OOM/堆分配失败、permission denied、网络/DNS 失败、缺失系统库、Docker 容器问题、磁盘满等属于环境问题检测到即立即退出、不消耗门控预算而编译错误、测试断言失败、lint 违规、类型错误才是本地修复的真正候选。提交信息有固定格式git commit -m fix(projects): brief description Failed tasks: taskId1, taskId2 Local verification: passed|enhanced|failed-pushing-to-ci十、反模式清单与错误处理文档以表格形式列出了五种反模式及其危害这是理解该技能设计约束的关键反模式危害用 CI 提供方 CLI 的--watch标志如gh pr checks --watch、glab ci status -w完全绕过 Nx Cloud 自愈自己写 CI 轮询脚本不可靠、污染上下文、无自愈取消 CI workflow/pipeline破坏性丢失 CI 进度在主代理上跑 CI 检查浪费主代理上下文 token轮询期间独立分析/修复 CI 失败与自愈抢跑造成重复修复与状态混乱若技能未能激活降级路径为用 CI 提供方 CLI 做一次性只读状态查询单次调用不带 watch/polling 标志→ 带着收集到的上下文立即委托给本技能 → 绝不在主代理上继续轮询。错误处理表错误处理git rebase 冲突报告用户退出nx-cloud apply-locally失败经 MCPREJECT该修复再尝试手动补丁Reject Fix From Scratch 流程或退出MCP 工具错误重试一次仍失败则报告用户子代理派生失败重试一次仍失败则带错误退出决策脚本错误视为error状态no_progress_count递增未检测到新 CI Attempt开启--auto-fix-workflow则尝试 lockfile 更新否则带指引报告用户lockfile 自动修复失败报告用户退出并给出查看 CI 日志的指引十一、用户指令覆盖与会话状态技能强调用户指令可覆盖任意默认行为文档给出的示例指令与效果指令效果never auto-apply应用任何修复前总是询问always ask before git push每次 push 前询问reject any fix for e2e tasksfailedTaskIds含 e2e 时自动拒绝apply all fixes regardless of verification跳过验证检查全部应用if confidence 70, reject应用前检查confidence字段run nx affected -t typecheck before applying增加本地验证步骤auto-fix workflow failures对 pre-CI-Attempt 失败尝试 lockfile 更新wait 45 min for new CI Attempt覆盖新 CI Attempt 等待超时默认 10 分钟会话层面若本会话此前已运行过/monitor-ci可能存在先前状态轮询计数、上次 CI Attempt URL 等除非设置--fresh丢弃旧状态从 Step 1 重新开始否则从该状态恢复继续。十二、小结这套设计的可借鉴之处从.opencode/skills/monitor-ci/目录的整体结构看这个技能把“不确定性”压缩到了最小面子代理只做一次工具调用、决策与状态迁移全部由两个可独立执行的 Node 脚本承担脚本头注释即为完整的 CLI 用法说明可直接node ci-poll-decide.mjs ...调试LLM 只在“分析修复内容”和“本地编码”这类真正需要智能的环节介入。配合固定退避序列60/90/120/180 秒、13 轮无进展熔断、总墙钟超时--elapsed-seconds跨 Attempt 携带、--max-cycles硬停 逼近 2 周期预警、以及 local-fix / env-rerun 双预算门控形成了一套有明确边界、可审计、可预算控制的 CI 监控与自愈闭环——这正是文档在 frontmatter 中宣称“优先于原生 CI 工具”的工程底气所在。【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考