mcpField
S
script-builder

script-builder

github.com/desplega-ai测试与质量36143 次安装今天更新
代码仓库

关于 script-builder

script-builder 是一项将测试或验证需求转化为可重复运行脚本的技能,面向需要持久化项目检查流程的开发者。它还会为脚本生成文档入口,并按自主模式安排确认与执行步骤。

主要功能

  1. 01生成可重复运行的验证脚本
  2. 02检测现有脚本并处理重复需求
  3. 03按项目语言选择脚本模板
  4. 04执行语法检查并迭代修复
  5. 05在 CLAUDE.md 或 AGENTS.md 中记录脚本

适用场景

  1. 01将临时 API 检查保存为脚本
  2. 02为部署前验证建立可复用流程
  3. 03把重复测试探查整理成项目脚本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/desplega-ai/ai-toolbox --skill script-builder

安装后在 Claude Code 中输入/script-builder确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

templates/
bash.sh.tmpl
python.py.tmpl
README.md
typescript.ts.tmpl

详细介绍

script-builder

将测试/验证意图转化为持久、可重复运行的脚本,并提交到目标项目的 scripts/ 目录。输出采用上下文最优形式:成功时仅输出一行 PASS/FAIL 和 /tmp 日志路径;完整的详细输出重定向到带时间戳的日志文件;并在 CLAUDE.md/AGENTS.md 中添加 <important if> 块,以便未来的 Agent 在再次遇到相关测试意图时发现该脚本。

工作约定

这些说明确立了你与用户之间的工作约定。核心原则如下:

  1. AskUserQuestion 是主要沟通工具——每当你需要询问用户任何事项(澄清、偏好、决策、确认)时,都使用 AskUserQuestion 工具。不要以纯文本提问——始终使用结构化工具,以便用户高效作答。

  2. 提前了解偏好——在工作流开始时询问用户偏好,而不是等到最后才问,以免用户已经想结束。

  3. 自主模式决定互动频率——用户选择的自主级别决定你需要多久确认一次,但所有问题仍须通过 AskUserQuestion 提出。

适用场景

出现以下情况时,此技能会启用:

  • 用户调用 /script-builder 命令
  • 其他技能引用 **OPTIONAL SUB-SKILL:** desplega:script-builder
  • planning、qa 或 verifying 流程需要一个尚不存在的、可重复运行的验证脚本
  • 用户表达了“将 X 转成脚本”“把这个验证封装成可复用的工具”或“我想端到端测试 X”的意图,但现有脚本无法满足需求

自主模式

根据自主模式调整行为:

模式行为
Autopilot检测模式、起草、进行语法检查、编写文档,并在升级层级时运行和迭代,无需中途确认。仅在遇到硬性阻碍或破坏性副作用时暂停。
Critical(默认)在每个层级边界确认(起草后、编辑文档前、运行前)。在迭代循环中,使用 AskUserQuestion 询问是否应用修复。
Verbose每一步都先确认。展示每处差异。逐步说明检测推理。

自主模式由调用命令传入。如果未指定,默认为 Critical。

流程步骤

Step 1:检测模式(回顾式或预先声明式)

自行决定——不要询问用户“选择哪种模式?”。使用以下启发式规则:

  1. 扫描近期会话中的工具使用历史(当前对话中最近约 20 次工具调用),查找测试/验证相关活动:curl/fetch 调用、bun run/python/pytest、数据库查询、qa-use 浏览器操作,或针对单个端点或表反复执行的 grep/日志检查。如果有 ≥2 次此类操作针对同一区域 → 回顾式模式。
  2. 解析用户的调用消息,查找以下线索:
    • 叙述性线索 → 回顾式:“我们刚刚查明了”、“把这个转成脚本”、“把那个封装起来”、“我们刚才做的那个”。
    • 意图线索 → 预先声明式:“我想测试”、“验证一下”、“冒烟检查”、“部署前检查”。
  3. 兜底规则:如果无法确定,默认使用预先声明式。

回顾式模式的第一步:用纯文本向用户概述观察到的活动(不超过 6 行:探查了什么、针对什么、成功信号是什么),然后进入 Step 3,并改为请求确认,而不是进行问答。

预先声明式模式的第一步:直接跳到 Step 3 的问答环节。

步骤 2:扫描现有脚本,查找重叠

按以下顺序解析 scripts 目录:

  1. 检查 CLAUDE.md 中是否有 `` 标记。如果有,使用其中的路径。
  2. 如果仓库根目录下存在 scripts/,则使用它。
  3. 使用 AskUserQuestion,选项为:scripts/(推荐)| 自定义路径 | 本次运行跳过目录持久化。

边缘情况 — 目录不存在:如果解析出的路径不存在,则跳过查重扫描,打印一行说明(No existing scripts directory at <path> — proceeding to intent gathering),并记住可在步骤 5 之前选择提供创建该目录的选项。

目录存在时:

  1. 列出 scripts 目录中的文件(v1 仅列出顶层文件)。
  2. 对每个文件,读取文件开头(头部注释)并提取文件名中的词元。
  3. 读取 CLAUDE.md/AGENTS.md,查找指向此目录中脚本的 <important if="..."> 块,并提取触发短语。
  4. 将当前意图字符串与(文件名词元 ∪ 头部关键词 ∪ 触发短语)进行模糊匹配。“合理匹配”指共享关键词且属于同一领域名词(例如,auth、health、webhook)。
  5. 如果存在 ≥1 个合理匹配,则使用 AskUserQuestion,选项为:按原样复用 <name> | 扩展 <name> | 仍然生成新脚本。

对于边界匹配,绝不要默默跳过查重——应展示匹配结果并让用户决定。扩展分支会在现有脚本中追加子命令/标志(不要创建新文件);并在脚本的头部注释和现有 <important if> 块中说明新标志。

步骤 3:收集意图

两种模式都会汇总到相同的内部意图结构:{ what, success_signal, failure_signal, inputs, env, side_effects }。

前向模式 — 使用 AskUserQuestion(提一到两个问题,而不是五个):

问题选项
“我们要验证什么,成功信号是什么?”[自由文本 — 在一个回答中收集 what + success signal]
“是否有需要标记的必需环境变量、输入或副作用(例如,写入生产环境、产生费用)?”[自由文本 — 可选;如果前向意图已说明这些内容,则跳过]

回顾模式 — 展示步骤 1 中的摘要,并使用 AskUserQuestion,选项为:流程没问题 | 接近了,但要修正 X | 重新开始。选择 接近了,但要修正 X 时,直接询问具体修正内容;选择 重新开始 时,转入前向模式问答。

将已确定的意图保存在工作记忆中(暂不写入磁盘)。

步骤 4:检测语言

优先顺序 — 命中第一个条件即采用,同时可通过覆盖路径调整:

  1. TypeScript — 存在 package.json + tsconfig.json。
    • 如果存在 bun.lock 或 bunfig.toml,则使用 Bun。
    • 否则,如果 package.json 的 devDependencies 中出现 tsx,则使用 tsx。
    • 否则,使用 已编译的 Node(在脚本头部注明:需要运行 tsc 构建)。
  2. Python — 存在 pyproject.toml 或 uv.lock 或 requirements.txt。
    • 如果存在 uv.lock,或 pyproject.toml 中配置了 [tool.uv],则使用 uv(设置 {{UV_METADATA}})。
    • 否则,使用 原生 python3(将 {{UV_METADATA}} 替换为空字符串)。
  3. 同时检测到 TS 和 Python — 统计 src//顶层目录中的源文件数量,并使用 AskUserQuestion 询问优先选择哪种语言,文件较多的一方标记为“推荐”。
  4. 仅有 Cargo.toml / go.mod → 回退到 bash(注意:v1 仅支持 TS/Python/Bash)。
  5. 未匹配到任何内容 → bash。

任务驱动的覆盖:如果收集到的意图明显适合 shell(“验证三个 docker 容器是否有响应”、“监视此日志文件并查找错误”),即使项目使用 TS/Python,也建议采用 bash。

使用 AskUserQuestion 确认,检测到的语言作为第一个选项(推荐)。Autopilot 中跳过。

步骤 5:起草脚本
  1. 选择模板:cc-plugin/base/skills/script-builder/templates/{typescript.ts.tmpl|python.py.tmpl|bash.sh.tmpl}。
  2. 根据收集到的意图解析替换标记:
    • {{SCRIPT_NAME}} ← 建议的文件名主体(参见命名表)。
    • {{WHAT}} / {{WHEN}} / {{ENV}} / {{EXAMPLE}} ← 意图字段。
    • {{UV_METADATA}} ← 按照步骤 4 处理。
  3. 根据意图生成 {{TEST_BODY}}。保持精简:只包含一个具体探测和断言,不要编写一组测试。重新阅读模板的 README(templates/README.md),了解约定——主体必须遵循 PASS/FAIL 的表现形式。失败时抛出异常、使用 raise 或执行 exit 1;由模板外层的 try/trap 转换为 FAIL 行。
  4. 提出一个符合意图类型的文件名——参见下方的前缀表。先用 AskUserQuestion 提出建议的名称(Recommended),并将 custom name 作为备选项。

命名约定(仅供参考——技能会提出建议,用户可以覆盖):

前缀适用情况示例
e2e-*跨多个组件的端到端流程e2e-auth-flow.ts
check-*幂等的单一探测验证check-db-boundary.sh
smoke-*部署后的最小可行检查smoke-prod-api.ts
measure-*性能 / 大小 / token 测量measure-tool-tokens.ts
seed-* / generate-*数据填充或生成产物(用于验证的情况较少)seed-api-keys.sh

如果意图与任何前缀都不完全匹配,请提出一个自由格式的名称,例如 validate-<area>.<ext>。

  1. 将文件写入解析后的脚本目录。使其具有可执行权限(chmod +x)。
步骤 6:语法 / 类型检查

运行相应的检查器:

语言检查器(按优先顺序)
TypeScript如果存在 Bun,使用 bunx tsc --noEmit <file>;否则使用 npx tsc --noEmit <file>
Python始终运行 python3 -m py_compile <file>;如果 ruff 位于 PATH 中,再运行 ruff check <file>
Bash如果可用,运行 shellcheck <file>;否则运行 bash -n <file>

成功时:记录一行(syntax check OK),然后继续步骤 7。

失败时:

  1. 打印错误(不超过 10 行,不要打印完整输出)。
  2. 提出一个具体的单处修改修复方案(即将应用的确切 Edit)。
  3. 使用 AskUserQuestion 提供 Apply fix | Investigate | Stop 选项。
    • Apply fix → 编辑脚本并重新运行检查器(循环执行,不设硬性次数上限)。
    • Investigate → 与用户讨论;不要自动应用任何修改。
    • Stop → 将脚本保留在原路径;打印路径;不要删除。
步骤 7:记录脚本

自动编辑目标项目的 CLAUDE.md 和/或 AGENTS.md,以便未来的 Agent 在再次遇到匹配意图时发现此脚本。

区块模板(技能输出的 Markdown 原文):

<important if="[TRIGGER: e.g., you are testing the auth flow]">

## [Area] validation

Run `scripts/<name>` to [one-liner]. Requires [env/deps]. Example: `<cmd>`. Full log at `/tmp/<name>-*.log`.

Generated/maintained via `/script-builder`.

</important>

行为:

  1. 目标文件选择:如果 CLAUDE.md 和 AGENTS.md 都存在,则编辑两者;只编辑实际存在的文件。绝不从头创建任一文件——如果两者都不存在,则打印一行说明(No CLAUDE.md or AGENTS.md found — script generated but not documented)并跳过此步骤。
  2. 放置启发式规则:在文件中搜索第一个匹配 Test|Testing|Validation|Scripts 的标题(不区分大小写)。如果找到,则在该章节内或其后追加新区块。否则,在文件末尾附近新增 ## Scripts for testing & validation 章节,但要放在任何匹配 License|Acknowledg|Maintain|Contributors 的标题之前。
  3. 幂等性:如果已存在引用 scripts/<name> 的区块(即之前针对同一脚本名称运行过 /script-builder),则在原位置更新该区块——替换整个 <important if=...>...</important> 区块,不要追加重复内容。
  4. scripts 目录标记:如果步骤 2 是由用户选择(而非现有标记)确定 scripts 目录,则在 CLAUDE.md 顶部附近(标题之后)插入 ``,以便后续运行不再显示提示。如果标记已存在,则跳过。
  5. 显示差异:运行相当于 git diff CLAUDE.md AGENTS.md 的命令,并打印 5 行摘要,说明更改内容。绝不自动暂存——由用户提交。
步骤 8:提供升级选项

编辑文档后,决定是否继续进入运行并迭代阶段。

自主级别行为
自动驾驶自动升级至步骤 9,除非意图标记了副作用(写入生产环境、发送真实资金、修改共享资源)。如果标记了副作用,则按关键模式处理。
关键(默认)使用 AskUserQuestion:`现在运行以确认其正常工作
详细与关键模式相同,此外在执行前提供拟运行命令供用户审核。

如果用户选择“我稍后自行运行”或“只生成,不运行”→ 直接跳至步骤 10。

步骤 9:迭代修复失败(仅限升级阶段)

由人工设定边界的循环。除自动驾驶模式外,绝不自动应用修复。

  1. 使用拟定的示例调用运行脚本(不带 --verbose,不带 --json)。捕获退出代码,并获取 /tmp 日志末尾的 40 行(tail -n 40)。
  2. 如果退出代码为 0 → 报告 PASS(回显脚本的 PASS 行),然后继续步骤 10。
  3. 如果退出代码非 0:
    • 用 1–3 行总结失败情况:错误类别(超时 / 4xx / 5xx / 断言 / 缺少依赖等)+ 可能原因(在日志中搜索已知特征:ECONNREFUSED、Traceback、non-zero exit、command not found 等)。
    • 提出具体差异——说明你会对脚本应用的确切 Edit。展示旧内容 → 新内容。
    • 使用 AskUserQuestion:应用修复 | 换一种方式调查 | 停止。
      • 应用修复 → 编辑脚本,记录更改,然后返回 (1)。
      • 换一种方式调查 → 转入讨论;不要自动应用更改。
      • 停止 → 保留脚本,打印其路径;不要还原。

不设硬编码重试上限——由人工隐式设定上限。

副作用标记:如果意图声明了副作用(步骤 3),且当前为自动驾驶模式,则在首次运行前显示一行 WARNING: this script <does X> against <target>,并要求通过 AskUserQuestion 明确确认,即使处于自动驾驶模式也不例外。

步骤 10:交接

技能如何退出取决于调用方式:

作为子技能调用(来自 planning、qa、verifying): 向父技能返回控制权,并提供结构化摘要:{ script_path, status: "pass"|"fail"|"unrun", log_path?, doc_files_edited: [...] }。

直接调用(/script-builder): 使用 AskUserQuestion:Run it with /qa | Run /verify-plan | Commit the script and doc changes | Done。

  • Run with /qa → 调用 desplega:qa,并将脚本路径作为来源。
  • Run /verify-plan → 如果当前上下文中有计划路径,则调用 desplega:verifying。
  • Commit → 提议提交消息(feat(scripts): add scripts/<name> for <area> validation),并且仅暂存生成的脚本和对 CLAUDE.md/AGENTS.md 的编辑。不要自动提交;显示提议的 git add 和 git commit 命令,并要求用户确认。
  • Done → 打印脚本路径 + 日志路径(如果运行了升级流程),然后退出。

中止路径(在之前任一关卡选择 Stop):保留生成的脚本;如果步骤 7 已运行,则保留对 CLAUDE.md/AGENTS.md 的任何编辑;并打印一行:Aborted. Script: <path>. Doc edits: <files or "none">. Re-run /script-builder or git checkout to discard. 不要代替用户运行 git restore。

学习记录

可选子技能: 如果此工作流中出现了重要见解、模式、注意事项或决策,可考虑使用 desplega:learning 通过 /learning capture 记录下来。重点记录有助于他人在未来会话中受益的经验。

评论

支持 Markdown