svharness
v0.14.7
Published
CLI scaffolder for SDD-Driven Agent-Agnostic Coding Framework (harness)
Maintainers
Readme
svharness
v0.8 重命名说明:CLI 包名由
svharnessbuild→svharness,子命令init→build,参数--name→--harness-name。 旧名svharnessbuild/init/--name作为兼容别名保留至下一个 minor 版本,使用时会打印 deprecation 提示。
SDD-Driven Agent-Agnostic Coding Framework 的脚手架命令行工具。
为任何 Agent IDE(Qoder / Cursor / Claude Code 等)生成项目本地的 harness —— 一个规格驱动的知识层骨架,让 AI 协作开发有章可循。
快速开始
安装
# 从 npm 安装(发布后)
npm install -g svharness
# 或从源码安装
cd svharnessbuild && npm install && npm run build && npm link要求 Node.js ≥ 18。
30 秒上手
# 最简 —— 只填名字,其余取默认(arch=android-compose, agent=codechat)
svharness build --harness-name my-app
# 交互式向导(推荐新手)—— 可填路径 + 文字说明,保存配置或立即执行
svharness wizard
# 配置文件驱动(团队模板 / CI)
svharness build --config svharness.config.yaml --yes
# 一行式 —— 跳过交互,直接生成
svharness build --harness-name my-app --arch android-compose --agent qoder --yes
# 把构建完成的 harness 应用到其它项目(绑定式,不拷贝)
svharness apply --harness ./my-app-harness --target ../other-project --yes配置文件与向导(v0.10+)
优先级:CLI 参数 > svharness.config.yaml > 代码默认值
- 复制示例配置:
templates/svharness.config.example.yaml→ 项目根svharness.config.yaml - 编辑
build/apply/convert各节参数 - 执行:
svharness build --yes(自动读取当前目录下的svharness.config.yaml)
也可显式指定:svharness build --config ./team/android-compose.yaml --yes
build 成功后落盘当前参数:svharness build --harness-name my-app --save-config
svharness wizard:分步 TUI,支持同时填写文件路径与说明文字(如 requirementsNote),结束时可选「立即执行 / 仅保存配置 / 保存并执行」。
生成完成后,在你的 Agent IDE 中说:
- "运行 harness-build-skills-main"或"harness-build-skill-orchestrator"即可开始逐步填充内容;
- 构建完成后在目标项目中说"应用 harness-apply-skills-main 完成 xxx 功能开发"即可调用 harness。
演示数据集(demo_project)
仓库自带 demo_project/(Python 计算器主题),可一次性验证 --baseline / --requirements / --references / --extra-skills 四类输入及 intake 分类。详见 demo_project/README.md。
cd svharnessbuild
svharness build --harness-name demo-py --arch python --agent codechat `
--baseline ./demo_project/baseline `
--requirements ./demo_project/requirements `
--references ./demo_project/references `
--extra-skills ./demo_project/extra-skills `
--yes --force核心概念
Harness 是什么?
Harness 是一个 项目本地的知识层,由两大部分组成:
| 部分 | 位置 | 生命周期 | 说明 |
|------|------|----------|------|
| Agent 注入目录 | .qoder/ / .codechat/ / .cursor/ 等 | build 时创建,Agent 自动加载 | rules + build-skills |
| Harness 目录 | <harness-name>-harness/ | build 创建骨架 → Agent 逐步填充 | specs / requirements / references / baseline / agent-env / tasks |
目录结构
执行 svharness build 后生成:
<harness-name>-harness/
├── harness.yaml # 入口清单(架构 / agent / schema 引用)
├── AGENTS_BUILD.md # 面向 Agent 的使用指南
├── README.md # 面向人的项目概览
├── VERSION
├── CHANGELOG.md
├── .harness-build-state.yaml # 构建进度追踪(S10 … S90)
│
├── specs/ # 契约层
│ ├── signals/schema.json
│ ├── ui/schema.json
│ ├── behavior/schema.json
│ └── interfaces/schema.json
│
├── requirements/ # 正式需求(参与条目化)
│ ├── raw/ # S20_collect_inputs 用户入口
│ ├── md/ # convert 产物
│ └── yaml/ # S40 条目化产出(含 schema.json)
├── references/ # 参考资料(不参与条目化)
│ ├── raw/
│ ├── md/
│ └── yaml/
└── baseline/
├── code/ # 参考代码快照
├── repomix/ # 可选:`--repomix` 时生成的单文件 XML 快照
└── wiki/ # 架构 wiki
│
├── agent-env/ # Agent 运行期环境
│ ├── rules/ # 编码规则(.mdc,`alwaysApply: true` 为硬约束)
│ ├── skills/ # 运行期技能(SKILL.md + references/ + scripts/)
│ ├── tools/ # 项目本地脚本
│ └── memory/ # Agent 长期记忆
│
├── commands/ # 项目安装 / 升级命令
└── tasks/ # 可复用的开发者工作流同时,CLI 会在项目根写入 CLAUDE.md(--agent codechat 或 claude-code)或 AGENTS.md(qoder / cursor / opencode / generic),并向 Agent IDE 的 skill 目录注入 7 个构建辅助 skill:
| Skill | 职责 |
|-------|------|
| harness-build-skills-main | 总清单:解析内联绑定元数据 → 装载构建规则 → 路由到各子 skill |
| harness-build-skill-orchestrator | 读取构建状态,路由到下一阶段 |
| harness-build-skill-spec-builder | raw → requirements → specs 管线 |
| harness-build-skill-references-intake | S60 references 转换 + 结构化索引 |
| harness-build-skill-agent-env-merge | S61 baseline 自动提取确认 + S65 合并写入 |
| harness-build-skill-knowledge-builder | S10 baseline 样本 + S70 skills/tasks 索引 |
| harness-build-skill-wiki-writer | 按 TASKS.md 逐页撰写 wiki 正文 |
简短阶段对照(阶段 → skill):
S10_wiki -> harness-build-skill-wiki-writer(正文)/ harness-build-skill-knowledge-builder(样本子任务)
S20_collect_inputs -> harness-build-skill-orchestrator
S30_convert_docs -> harness-build-skill-orchestrator
S40/S50 -> harness-build-skill-spec-builder
S60 -> harness-build-skill-references-intake
S61/S65 -> harness-build-skill-agent-env-merge
S70 -> harness-build-skill-knowledge-builder
S80/S85/S90 -> harness-build-skill-orchestrator (+ S85 委派 pre-seal-review).harness-build-state.yaml 跟踪进度,任何阶段可中断再续。
构建辅助 skill / rule 命名规范
注入到 Agent IDE 的构建辅助资源遵循 三段式 命名,区别于项目自建的运行期 skill(harness-<domain>-<topic>):
harness-build-{skill|rule}-<semantic-name>
└──────┬──────┘ └───┬───┘ └──────┬──────┘
上下文前缀 资源类型 语义名称| 资源类型 | 目录 | 命名模式 | 现有成员 |
|----------|------|----------|----------|
| Build skill | templates/_shared/build-skills/ | harness-build-skill-<name>.md | skills-main / orchestrator / spec-builder / references-intake / agent-env-merge / knowledge-builder / wiki-writer |
| Build rule | templates/_shared/build-rules/ | harness-build-rule-<name>.md | agent-agnostic / chinese-only / memory-write / orchestrator-flow / requirements-extraction / skills-tasks-output / specs-schema / user-interaction |
约束:
- 前缀
harness-build-专属于 构建期(build/ orchestrator 驱动 harness 骨架填充),与运行期 skill(harness-<domain>-<topic>、如harness-compose-ui)及apply注入的harness-apply-skills-maindispatcher 明确区分。 - 文件内部 frontmatter
name、一级 heading、交叉引用必须与文件名保持一致。 - 新增同类资源时沿用此三段式,禁止回退到两段式(如旧名
harness-orchestrator/harness-build-orchestrator-flow已废弃)。
构建阶段
build 只生成骨架。各阶段的实际内容由 Agent 借助注入的 skill 逐步填充:
| 阶段 | 动作 | 产物 |
|------|------|------|
| S10_wiki | 构建 baseline wiki(仅当有 baseline 时出现,项目经验底座) | baseline/wiki/ |
| S20_collect_inputs | 添加相关文件:需求/参考文档 + 额外运行期资源征询(--extra-skills 单入口,可混放 skills/rules) | requirements/raw/ + references/raw/ + agent-env/_incoming/skills/ + task_list.md |
| S30_convert_docs | 非 Markdown 原始文档转 Markdown | requirements/md/ + references/md/ |
| S40_extract_requirements | 条目化需求 + 覆盖率门禁 + 保真门禁(title/source_excerpt/description) | requirements/yaml/*.yaml + requirements/yaml/schema.json + requirements/coverage-report.yaml |
| S50_generate_specs | 生成规格 + REQ→spec 覆盖 + 深度门禁(非 index-only) | specs/<layer>/<module>.<layer>.yaml + schema 校验 + 覆盖率结果 |
| S60_process_references | references 处理(svharness convert + 结构化索引 + 用户确认落地) | references/md/ |
| S61_confirm_baseline_extraction | 确认是否自动从 baseline 提取 skills/rules(表单确认) | .harness-build-state.yaml(phases.S61_confirm_baseline_extraction.baseline_auto_extract) |
| S65_customize_agent_env | agent-env 定制(extra-skills/extra-rules 冲突建议与重命名建议 → 用户确认 → 写入) | agent-env/rules/ + agent-env/skills/ |
| S70_runtime_assets | 运行期 Skills & tasks 索引(skill 执行 task) | agent-env/skills/ + tasks/templates/ |
| S80_seed_memory | Memory 初始化 | agent-env/memory/categories/ |
| S85_pre_seal_validation | 封存前校验 | svharness doctor + 全面审查报告 |
| S90_finalize | 封板 | 版本 bump + CHANGELOG + bootstrap_mode: false |
反复调用 orchestrator 总是从"第一个非 DONE 的阶段"继续。 S10_wiki 仅在有 baseline 时出现;无 baseline 则不构建 wiki,流程从 S20_collect_inputs 开始。 S20_collect_inputs 必须等待用户放入需求文档,且需显式征询 references 与额外运行期资源输入(
--extra-skills,可混放 skills/rules);Agent 不得自行生成占位文件。若 build 传入了--requirements/--references,CLI 会在拷贝到 raw 后自动尝试 convert 到 md。 S60_process_references 专注 references:必须执行svharness convert,并产出结构化索引(规制约束 / skills 候选 / signals / manuals),经表单确认后再进入后续阶段。 S61_confirm_baseline_extraction 必须显式确认是否启用 baseline 自动提取 skills/rules;未经确认不得在 S65 自动提取。 S65_customize_agent_env 专注 extra-skills/extra-rules:来源可来自--extra-skills导入后的_incoming/manifest.yaml,先冲突识别与重命名建议,再表单确认写入;推荐命名:harness-apply-skills-<topic>与harness-apply-rules-<topic>.md/.mdc。 S40/S50/S85 的 DONE 都带覆盖率门禁:未闭环 gap(或未备案 waiver)不得推进。
命令参考
wizard —— 交互式向导(v0.10+)
svharness wizard分步选择 build / apply / convert,填写路径与可选说明,最后保存到 svharness.config.yaml 和/或立即执行对应命令。
配置文件 svharness.config.yaml(v0.10+)
| 顶层字段 | 说明 |
|----------|------|
| version | 固定为 1 |
| defaults | 各命令共享默认(arch / agent / yes 等) |
| build | 对应 svharness build |
| apply | 对应 svharness apply |
| convert | 对应 svharness convert |
| doctor | 对应 svharness doctor |
build 节除路径外,可写人类可读说明(仅写入配置文件,供团队阅读):
| 字段 | 说明 |
|------|------|
| requirementsNote | 需求文档业务说明 |
| referencesNote | 参考资料说明 |
| extraSkillsNote | 额外 skills/rules 说明 |
完整示例见 templates/svharness.config.example.yaml。
build —— 构建 harness(v0.8 起的主命令)
旧名
svharness init(以及svharness build)作为兼容别名保留,调用时会打印 deprecation 警告。
交互式
svharness build --harness-name my-app
# 仅 --harness-name 必填;其余参数采用默认值,结束前会有一次确认提示非交互(CI / 脚本)
svharness build \
--harness-name my-app \
--arch android-compose \
--agent codechat \
--baseline ../my-baseline-repo \
--yes全部参数
| 参数 | 是否必填 | 说明 | 默认值 |
|------|----------|------|--------|
| --config <path> | 可选 | 读取 YAML/JSON 配置;省略时在 cwd 查找 svharness.config.yaml | — |
| --save-config [path] | 可选 | build 成功后把参数写入配置文件 | — |
| --harness-name <name> | ✅ 必填* | harness 名称;可在 build.harnessName 中提供 | — |
| --name <name> | ⚠️ 已废弃别名 | 等同 --harness-name,下个 minor 版本移除 | — |
| --arch <arch> | 可选 | 架构模板:android-compose / android-xml / cpp / web-react / python | android-compose |
| --agent <agent> | 可选 | 目标 Agent IDE:codechat / qoder / cursor / claude-code / opencode / generic | codechat |
| --baseline <path\|url> | 可选 | 基线来源:本地目录 或 git 仓库 URL | — |
| --requirements <path> | 可选 | 需求输入路径(文件或目录);build 阶段扁平拷贝到 requirements/raw/(不保留源目录里的 assets/raw/converted_md 等嵌套),随后自动 convert 到 requirements/md/(失败仅告警,不中断 build) | — |
| --references <path> | 可选 | 参考资料输入路径(文件或目录);build 阶段扁平拷贝到 references/raw/,随后自动 convert 到 references/md/(失败仅告警,不中断 build) | — |
| --extra-skills <path...> | 可选 | 额外运行期资源输入(文件/目录/glob,可混放 skills/rules);build 阶段先拷贝到 agent-env/_incoming/skills/ 并生成 agent-env/_incoming/manifest.yaml,S65 再分流写入 skills/ 与 rules/ | — |
| --baseline-branch <name> | 可选 | git 基线的分支名(仅 git 模式有效) | main |
| --baseline-max-file-kb <kb> | 可选 | 基线拷贝单文件大小上限(KB) | 1024 |
| --repomix | 可选 flag | 将 baseline/code 打成单文件 Repomix XML;须同时提供 --baseline。适用场景见下文 Repomix | false |
| --convert-endpoint <url> | 可选 | build 自动 convert 使用的 markitdown 服务基址;省略时读环境变量 SVHARNESS_MARKITDOWN_ENDPOINT | http://markitdown.desaysz.site |
| --convert-concurrency <n> | 可选 | build 自动 convert 并发上传数 | 3 |
| --convert-max-file-mb <n> | 可选 | build 自动 convert 单文件大小上限(MB) | 50 |
| --convert-timeout-sec <n> | 可选 | build 自动 convert 请求超时秒数 | 120 |
| --convert-force | 可选 flag | build 自动 convert 覆盖同名 .md(否则按 -1/-2 追加) | false |
| --force | 可选 flag | 覆写已存在的 harness 目录;同时允许覆盖已注入的 build skills/rules 与项目根 AGENTS.md / CLAUDE.md(默认遇到已存在文件会跳过) | false |
| -y, --yes | 可选 flag | 跳过所有提示,采用默认值 | false |
| --verbose | 可选 flag | 打印每个生成文件 | false |
Wiki 参数
| 参数 | 说明 | 默认值 |
|------|------|--------|
| --generate-wiki | build 时直接逐页生成完整 wiki(与 --wiki-tasks-only 互斥) | false |
| --wiki-tasks-only | 仅生成 wiki outline + TASKS.md(兼容保留) | false(但有 --baseline 时为隐式默认行为) |
| --wiki-lang <zh\|en> | wiki 语言 | zh |
| --wiki-model <name> | LLM 模型名 | Qwen3.6-27B(来自内置 wiki 配置链) |
| --wiki-base-url <url> | OpenAI 兼容 API 地址 | http://model-api.desaysv.com/v1 |
| --wiki-api-key <key> | API Key | 环境变量 OPENAI_API_KEY → .env → 内置默认 |
| --wiki-source <path> | wiki 扫描的仓库根路径 | <target>/baseline/code/(无 baseline 时为 cwd) |
Wiki 配置优先级:CLI 参数 > 环境变量 > .env 文件 > 内置默认值
Wiki 模式总览:
| 组合 | 行为 | S10_wiki 状态 |
|------|------|---------|
| 无 --baseline | 不生成 wiki | phase 不存在 |
| --baseline(默认) | 一次 LLM 拿 outline,写 TASKS.md | PENDING + requires_agent: true |
| --baseline + --generate-wiki | 逐页调用 LLM 生成完整 wiki | 初始 DONE;失败降级为 PENDING |
Wiki 生成失败不会回滚 harness 骨架,仅输出警告。
Repomix(--repomix){#repomix-repomix}
产物:baseline/repomix/repomix-pack.xml —— 用 Repomix 把 baseline/code/ 目录树压缩成一份带行号的 XML,便于整包喂给上下文窗口有限的模型,或离线归档/比对。
默认关闭的原因:harness 主流程已依赖 baseline/code/(逐文件引用、wiki-writer、knowledge-builder、S61 自动提取等)。Repomix 是辅助快照,不是 specs / requirements 的契约来源,且大仓库打包耗时长、产物体积大。
建议开启 --repomix 的场景:
| 场景 | 说明 |
|------|------|
| 基线体量较大,需要「整库一览」 | 希望 Agent 一次 attach 单文件 做架构鸟瞰、模块边界梳理、依赖关系初扫,而不是在对话里反复 @ 上百个路径 |
| 外部工具只吃单文件上下文 | 使用只支持粘贴/上传单个上下文文件的分析器、审计脚本或二次 LLM 流水线 |
| 离线交付或版本留档 | 需要把某次 --baseline 快照固化为可 diff 的单文件(例如随 harness 封存、发给评审方) |
| 与 baseline/wiki/ 互补 | wiki 偏「说明文档」;Repomix 偏「源码字面快照」。做反向提取前的代码面快速摸底时可同时保留两者 |
通常不必开启的场景:
- 基线很小,或 Agent 已能稳定按路径阅读
baseline/code/(默认路径即可) - 只关心 harness-build 标准阶段(S40/S50/S85):规格与审查以
requirements/、specs/、baseline/code为准,不依赖 Repomix XML - 基线含大量二进制/生成物:Repomix 对图片等帮助有限,且会拉长 build 时间(失败仅告警,不回滚骨架)
用法:
svharness build --harness-name my-app --baseline ./src --repomix
# 或配置:build.repomix: true(须同时配置 build.baseline)Repomix 步骤在 baseline 拷贝之后执行;打包失败不会回滚 harness 骨架。已构建的 harness 可带
--force重新build并补上--repomix。
Agent 适配器
| Agent | skill 目录 | 扩展名 | 额外处理 |
|-------|-----------|--------|----------|
| codechat(默认) | .codechat/skills/ | .md | — |
| qoder | .qoder/skills/ | .md | — |
| cursor | .cursor/rules/ | .mdc | 自动注入 frontmatter |
| claude-code | .claude/skills/ | .md | — |
| generic | .agent/skills/ | .md | 中立回退 |
apply —— 把已构建好的 harness 绑定到目标项目
把 <name>-harness/(通过 build 完成的知识层)应用到目标项目时,apply 现采用默认复制模式:始终把 harness 拷贝到 <target>/<name>-harness/,然后注入 runtime skills/rules,并生成项目根 AI 入口。
# 默认复制模式(无需 --clone)
svharness apply --harness ../my-app-harness --target ./to-apply-project
# --clone 仍可传入,但仅兼容:行为与默认一致(都会拷贝)
svharness apply --harness ../my-app-harness --target ./to-apply-project --clone --yes在 Agent IDE 中触发:对话框输入 应用 harness-apply-skills-main 完成 xxx 功能开发,薄入口会提示并优先使用已注入的 harness-apply-skills-* 子 skill。
同时,CLI 会在目标项目根写入 CLAUDE.md(--agent codechat 或 claude-code)或 AGENTS.md(qoder / cursor / opencode / generic)。该入口由 <harness>/AGENTS_APPLY.md 拷贝并重命名生成(与 build 写入项目根入口的规则一致,不再单独落地 AGENTS_APPLY.md)。
此外,apply 会同步注入运行期资产:
<harness>/agent-env/rules/→<target>/<adapter.rulesDir>/(若该 agent 声明了rulesDir)<harness>/agent-env/skills/→<target>/<adapter.skillsDir>/(默认跳过同名已存在文件;--force才覆盖。harness-apply-skills-main由模板写入为薄入口)--include-build-assets开启时:同步生成<target>/build-agent-env/skills与<target>/build-agent-env/rules,用于二次 agent 驱动修改--inject-build-main-bridge开启时:在<target>/<adapter.skillsDir>/harness-build-skills-bridge/写入桥接 skill(仅用于构建流二次改造)- 目标
.gitignore会在文件尾部 append 注入路径(幂等去重)
Repomix 与 apply:若 build 时启用了 --repomix 且产物存在,CLI 会回写 harness.yaml → baseline.repomix_pack,并在 apply 时向 harness-apply-skills-main 与项目根 AGENTS.md/CLAUDE.md 注入 Repomix 路径与用法(权威参考实现仍为 baseline/code/)。详见上文 Repomix(--repomix)。
references 内容引用 → apply_skill_registry(S60,由 Agent 写入)
S60(harness-build-skill-references-intake)属于 build 阶段。若某份 references 属于内容引用(apply 时要按 references/md/ 原文指导开发),Agent 应:
- 登记
references/apply-skills-registry.yaml(skill_name、reference_md、description,可选entry/source_id) - 执行
svharness apply时,运行期 skill 将按引用原文执行,且相关路径会改写到<target>/<name>-harness/下可达位置
无单独 CLI;规制约束、纯手册类 references 不登记 registry。
build / apply 分工
- build 阶段:生成 harness 本体资产(
AGENTS_APPLY.md、agent-env/skills、agent-env/rules、specs、baseline等) - apply 阶段:复制 harness 到目标项目、注入 skills/rules、(可选)拷贝构建期 assets、生成入口文件、写
.gitignore、输出一致性检查报告
全部参数
| 参数 | 是否必填 | 说明 | 默认值 |
|------|----------|------|--------|
| --harness <path> | ✅ 必填 | 已构建好的 harness 目录(形如 ./my-app-harness) | — |
| --target <path> | 可选 | 目标项目根目录 | 当前工作目录(cwd) |
| --agent <agent> | 可选 | 目标 Agent:codechat / qoder / cursor / claude-code / opencode / generic | codechat |
| --clone | 可选 flag | 兼容参数;当前实现下行为与默认一致(都会拷贝 harness) | false |
| --include-build-assets | 可选 flag | 显式拷贝构建期 skills/rules 到 build-agent-env/(用于二次改造) | false |
| --inject-build-main-bridge | 可选 flag | 向运行期 skills 注入 harness-build-skills-bridge(需 --include-build-assets) | false |
| --consistency <mode> | 可选 | 一致性检查级别:basic / strict(strict 当前为预留模式) | basic |
| --force | 可选 flag | 覆盖已存在注入目录与入口文件;同时允许重拷贝 harness | false |
| -y, --yes | 可选 flag | 跳过交互确认 | false |
| --verbose | 可选 flag | 显示详细日志 | false |
产物
<target>/
├── CLAUDE.md | AGENTS.md # apply 工作流入口(由 harness/AGENTS_APPLY.md 重命名)
├── <adapter.rulesDir>/... # 运行期 rules 注入(若 adapter 声明 rulesDir)
├── <adapter.skillsDir>/<runtime-skill>/SKILL.{md|mdc} # 运行期 skills 注入
├── <adapter.skillsDir>/harness-apply-skills-main/
│ └── SKILL.{md|mdc} # 薄入口 skill(仅提示/索引,不做二级调度)
├── <adapter.skillsDir>/harness-build-skills-bridge/
│ └── SKILL.{md|mdc} # 可选:--inject-build-main-bridge(build 流桥接,不是默认入口)
├── build-agent-env/ # 可选:--include-build-assets 时生成
│ ├── skills/ # 构建期 skills 镜像(可二次改造)
│ └── rules/ # 构建期 rules 镜像(可二次改造)
└── <name>-harness/ # apply 默认复制后的 harness注入完成后,CLI 会输出一致性检查摘要(目录/文件存在性、frontmatter 关键字段、引用可达性),发现问题会给出警告或错误明细供修复。
回滚(bridge 最小清理)
- 软回滚:后续
apply不再传--inject-build-main-bridge。 - 硬回滚:删除
<adapter.skillsDir>/harness-build-skills-bridge/即可;build-agent-env/可保留用于后续构建流改造。
doctor —— harness 健康度与封存前硬检查(S85)
在 Agent 进入 S85_pre_seal_validation / 封板前,对 harness 目录执行可重复的硬检查:
# 封存前全量(要求 S00–S80 均为 DONE)
svharness doctor --harness ./my-app-harness --mode pre-seal
# 日常巡检(不强制所有阶段 DONE)
svharness doctor --harness ./my-app-harness --mode health
# Agent 友好:JSON 报告
svharness doctor --harness ./my-app-harness --mode pre-seal --format json --report ./my-app-harness/doctor-report.json| 选项 | 说明 |
|------|------|
| --harness | harness 根目录(必填;可写在 svharness.config.yaml 的 doctor.harness) |
| --mode | pre-seal(默认)或 health |
| --format | text(默认)或 json |
| --report | JSON 报告路径(默认 <harness>/doctor-report.json) |
| --strict | 将 warning 视为 error |
退出码:0 通过,1 存在 error。
S85 Agent 审查(合并 skill):doctor 通过后,由 harness-build-skill-pre-seal-review(v2,已吸收 harness-build-harness-data-review)产出 HARNESS-REVIEW-REPORT.md:
- Part A:从
harness.yaml发现 assets,完整性清单(arch-agnostic) - Part B:按
specs.layers与agent-env/review-profiles/<arch>.yaml做深度评分 - 门禁:
overall_score >= 5.0(C 级)、critical_count == 0、报告 frontmattergate_pass: true、用户表单确认
doctor 另含 check-review-report(warning):S85 已 DONE 时校验报告 frontmatter 与 state 中 review_gate_pass 一致。数量覆盖率阻断仍由 S40/S50 表单门禁负责。
同时新增:
check-requirements-fidelity:检查source_excerpt缺失、description缩略与占位语义。check-specs-depth:检查 index-only 信号、enum 缺失enum_values、behavior 空guard/action。
convert —— 文档 → Markdown 预处理(对接 S20_collect_inputs)
把本地原始需求文档(.pdf / .docx / .pptx / .xlsx / .html / .epub / .txt / .csv / .json / ...)通过云端部署的 markitdown_serve(FastAPI + Microsoft MarkItDown)批量转为 Markdown,产物统一落到 <harness>/<type>/md/(type 为 requirements 或 references),直接喂给下游 S40_extract_requirements 条目化流程,显著提升 specs 生成质量的稳定性。
表格清洗(xlsx/xls/csv):源文件为
.xlsx、.xls或.csv时,转换完成后自动清理 Markdown 表格中的NaN、全空行、以及数据全空且表头为Unnamed: N的列(CLI 与服务端双端生效)。对已存在的产物 md 可执行:node scripts/cleanup-spreadsheet-md.js <dirOrFile>。
Sheet 拆分(xlsx/xls):多 sheet 工作簿转换后,MarkItDown 以
## SheetName分隔各 sheet。CLI 默认在保留合并 md 的同时,将各 sheet 写入<basename>_split/(含README.md索引);--no-split-sheets可关闭。已有合并 md 可执行:node scripts/split-spreadsheet-md.js <dirOrFile>。
架构约束:CLI 只是 HTTP 客户端,不 spawn / 不装 Python / 不管进程。服务端代码集中在
svharnessbuild/markitdown_serve/便于仓内维护,但不随 npm 包分发,部署方式详见 markitdown_serve/README.md。
# 最简 —— 所有参数均可省略,默认扫描当前目录
svharness convert
# 独立模式:md 直接写入 ./docs/md
svharness convert --input ./docs/*.pdf --output ./docs/md --yes
# harness 模式:md 写入 ./my-app-harness/requirements/md/
svharness convert --input ./my-app-harness/requirements/raw --output ./my-app-harness --yes
# 显示处理日志
svharness convert --verbose全部参数
| 参数 | 说明 | 默认值 |
|------|------|--------|
| --input <path...> | 一个或多个源文件 / 目录 / glob,支持 ./a/*.pdf、./docs/**/*.docx、./{a,b}/*.md | .(当前目录) |
| --harness <path> | harness 根目录(需 harness.yaml);单独使用时写入 <harness>/<type>/md/;与 --output 同用时 --output 为最终 md 目录 | — |
| --output <path> | 独立模式:最终 md 输出目录;harness 模式:path 含 harness.yaml 时写入 <path>/<type>/md/ | .(当前目录) |
| --endpoint <url> | 云端 markitdown_serve 基址,省略时读环境变量 SVHARNESS_MARKITDOWN_ENDPOINT | http://markitdown.desaysz.site |
| --concurrency <n> | 并发上传数 | 3 |
| --max-file-mb <n> | 单文件大小上限(MB),本地 + 服务端双重限流 | 50 |
| --timeout-sec <n> | 单请求超时秒数 | 120(2 分钟) |
| --type <type> | 目标子目录:requirements(正式需求)| references(参考资料) | requirements |
| --force | flag,覆盖已存在同名 .md(默认自动追加 -1、-2 后缀) | false |
| --split-sheets-suffix <suffix> | xlsx/xls 按 sheet 拆分的子目录后缀 | _split |
| --no-split-sheets | flag,不将 xlsx/xls 合并 md 按 ## 拆分为多文件 | false(默认拆分) |
| -y, --yes | flag,跳过交互确认 | false |
| --verbose | flag,显示详细日志 | false |
行为要点
- 健康探针前置:上传前先
GET /healthz,不通直接退出并打印清晰定位指引(endpoint / 环境变量 / 服务端目录三条线索)。 - 单文件失败不中断:失败单文件计入汇总,其它文件照常完成。结束时打印
ok / skipped / failed计数。 - 本地白名单预过滤:客户端与服务端的扩展名白名单保持一致,非白名单文件本地直接跳过,避免无意义往返。
- 两种输出模式:
- 独立:
--output即最终 md 目录(路径下无harness.yaml),例如--output ./docs/md。 - harness:
--output或--harness指向含harness.yaml的目录时,写入<harness>/<type>/md/(build / Agent 模板沿用此约定)。
- 独立:
- harness 模式收尾:扫描
raw/时跳过converted_md/、md/等;结束后将误落在raw/**/converted_md/下的.md迁回<type>/md/。 - 源文件不改动:只生成 md,不移动或删除原始文档。
产物
<harness>/
└── requirements/ # --type requirements(默认)
│ └── md/
│ ├── 需求.md
│ └── ...
└── references/ # --type references
└── md/
├── 参考文档.md
└── ...接口契约(CLI ⇄ markitdown_serve)
| 端点 | 方法 | 约定 |
|---|---|---|
| /healthz | GET | 200 {status, markitdown_version} |
| /convert | POST | multipart/form-data,字段 file;200 返回 {markdown, source_name, mime};413/415/500 带结构化 error 字段 |
完整契约与部署说明见 markitdown_serve/README.md。
架构模板
支持的架构
| --arch | 语言 | 规则 | 说明 |
|----------|------|------|------|
| android-compose(默认) | Kotlin + Compose | 4 条 harness-*.mdc | MVI + UDF + Hilt + 协程 |
| android-xml | Java + XML | 5 条 seed-*.md | MVC + ViewBinding |
| cpp | C++17 + CMake | 5 条 seed-*.md | 现代 C++ + CMake 规范 |
| web-react | TypeScript + React | 5 条 seed-*.md | Hooks + 状态管理规范 |
| python | Python | — | 通用 Python 模板 |
两层叠拷合并:
_shared/先落盘,<arch>/随后覆盖同名文件。 新增架构只需在templates/<new-arch>/skeleton/agent-env/rules/下放 3-5 条规则文件, 并在types.ts与validate-args.ts各加一处枚举。
android-compose 模板详述
此模板自带 4 条刚性规则和 8 个运行时技能。
Rules —— 刚性约束层
位于 agent-env/rules/,.mdc 格式,alwaysApply: true,Agent 会话全程加载。
| 规则 | 约束域 | 核心条目 |
|------|--------|----------|
| harness-compose-mandatory | Compose 铁律 | Composable 无状态、Modifier 首参、禁组合内副作用、LazyColumn key、remember+derivedStateOf、禁 unstable 参数 |
| harness-mvi-layering | MVI 分层 | 依赖方向向内、Feature 禁直达 Foundation、Reducer 纯函数、State 不可变 data class |
| harness-hilt-injection | Hilt 注入 | @HiltViewModel+@Inject、hiltViewModel()、禁 UseCase 包装接口、Repository 接口在 Domain |
| harness-coroutines-scope | 协程作用域 | 禁 GlobalScope、viewModelScope、Dispatchers.IO、collectAsStateWithLifecycle、SharedFlow replay=0 |
每条规则遵循 "正例 → 反例 → 检测方法" 三段式,保持 < 30 行。
Skills —— 知识参考层
位于 agent-env/skills/,按需触发。每个 skill 是一个目录,至少含 SKILL.md,可选 references/、scripts/。
| Skill | 定位 | 覆盖领域 |
|-------|------|----------|
| harness-android-architecture | 合并 5 层架构 | MVI+UDF 模板、ViewModel/UseCase/Repository、多 UseCase 组合 |
| harness-compose-ui | 合并 2 个 Compose UI | 状态提升、槽 API、性能优化、列表/网格 |
| harness-compose-state | 新拆出 | 侧效 API 选型、StateFlow/SharedFlow 陷阱 |
| harness-kotlin-coroutines | 改名适配 | 结构化并发、Flow 算子、异常处理 |
| harness-compose-audit | 改名自 compose_skill-main | 9 步审计 + 评分 + 编译报告 |
| harness-xml-to-compose | 改名自 migrate-xml-views | XML → Compose 10 步迁移 |
| harness-android-cli | 改名自 android-cli | Android CLI 命令速查 |
| harness-r8-analyzer | 改名自 r8-analyzer | R8 keep 规则冗余分析 |
Skill 与 Rule 的引用约定
每个 SKILL.md 末尾必须包含「必须遵守的约束规则」段落:
## 必须遵守的约束规则
> rules 引用路径:`../rules/<rule-name>.mdc`
- harness-compose-mandatory
- harness-mvi-layering- 代码生成型 skill:只引用相关规则,不硬凑
- 工具操作型 skill(CLI / R8):写
无(本技能为 XXX 操作,不涉及代码生成) - 引用使用中立文件名(不带扩展名、不带路径),路径提示单独用 blockquote
命名规范
| 实体 | 命名模式 | 示例 |
|------|----------|------|
| Rule 文件 | harness-<domain>-<constraint>.mdc | harness-compose-mandatory.mdc |
| Skill 目录 | harness-<domain>-<topic>/ | harness-compose-state/ |
| Skill 文件 | 固定 SKILL.md | — |
| harness- 前缀 | 标识模板提供,与用户自建区分 | — |
常用示例
# 最简 —— 无基线,纯骨架(arch/agent 均使用默认值)
svharness build --harness-name my-app --yes
# 显式指定全部参数
svharness build --harness-name my-app --arch android-compose --agent qoder --yes
# 额外运行期资源(单入口,可混放 skills/rules,先入 _incoming)
svharness build \
--harness-name my-app --arch android-compose --agent codechat \
--extra-skills ./extras ./rules/*.mdc --yes
# 本地基线 + wiki 生成
svharness build \
--harness-name my-app --arch android-compose --agent codechat \
--baseline . --generate-wiki --verbose --force
# Git 远程仓库 + wiki(指定分支和文件大小限制)
svharness build \
--harness-name my-app --arch android-compose --agent codechat \
--baseline [email protected]:user/repo.git --baseline-branch main \
--baseline-max-file-kb 1024 --generate-wiki --verbose --force
# 内部 Git 仓库 + 自定义 API
svharness build \
--harness-name my-app --arch android-compose --agent codechat \
--baseline [email protected]:org/repo.git --baseline-branch main \
--generate-wiki --wiki-base-url http://your-api.com/v1 --wiki-api-key sk-xxx \
--verbose --force
# 仅 wiki 任务清单(默认行为,由 agent 后续撰写)
svharness build \
--harness-name my-app --arch android-xml --agent qoder \
--baseline . --wiki-lang zh --yes开发指南(贡献者)
源码目录
svharnessbuild/ # 源码目录名沿用旧名(历史包名),CLI 名称已迁至 svharness
├── bin/cli.js # npm bin 入口 → dist/index.js
├── src/
│ ├── index.ts # CLI 入口(commander)
│ ├── types.ts # SupportedArch 枚举
│ ├── commands/init.ts # 4 步主管线(双模板根:_shared + <arch>)
│ ├── core/
│ │ ├── scaffold.ts # scaffoldLayered: 先 _shared 再 <arch>
│ │ ├── render-meta.ts # renderMetaLayered: 同名 .ejs 以 <arch> 为准
│ │ ├── state.ts # 写 .harness-build-state.yaml
│ │ ├── agent-injector.ts # injectSkillsLayered
│ │ └── next-steps.ts # 初始化完成后的引导
│ ├── wiki/ # repowiki 核心模块(15 个文件)
│ ├── adapters/ # 各 Agent 的 skill 目录规则
│ └── utils/ # logger / 参数校验 / 版本读取
├── templates/
│ ├── _shared/ # 跨架构公共
│ ├── android-compose/ # Compose 规则 + 技能
│ ├── android-xml/ # XML 规则
│ ├── cpp/ # C++ 规则
│ └── web-react/ # React 规则
└── scripts/smoke-test.ps1版本升级
⚠ 不要手改
package-lock.json的version。用npm version同步更新两个文件:
npm version patch # bugfix
npm version minor # 向后兼容新功能
npm version 0.9.0 # 显式指定
npm version 0.9.0 --no-git-tag-version # 不打 git tag
# 验证同步
npm run build # 首行应显示 svharness@<新版本>
node -p "require('./package.json').version"
node -p "require('./package-lock.json').version" # 两者必须相等
# 不同步时修复
npm install # 按 package.json 刷新 package-lock.json本地验证
npm run build && npm pack --dry-run # 预览包内文件
npm pack # 生成 .tgz验证 tgz:
# 方式 A:npm link(开发期推荐)
cd svharnessbuild; npm link; svharness --help
# 删除
npm unlink -g svharness
# 或等价写法
npm rm -g svharness
# 方式 B:全局安装 tgz
npm install -g "d:\...\svharness-<version>.tgz"; svharness --help
# 方式 C:临时目录模拟
cd $env:TEMP; mkdir test; cd test; npm init -y
npm install -g .\svharness-<version>.tgz
npx svharness --help
# 方式 D:直接跑 CLI
cd svharnessbuild; npm run build
node bin\cli.js build --harness-name demo --arch android-compose --agent codechat --yes --force --verbose⚠ Windows:
npx d:\...\xxx.tgz会被文件关联拦截,请用上述替代方式。
发布
npm version 0.14.6
npm run build
npm login
npm publish --access public # prepublishOnly 自动执行 build| 分发方式 | 适用场景 | 用法 |
|----------|----------|------|
| npm | 公开发布 | npx svharness build |
| Tarball | 小团队 / 内部试用 | npx ./svharness-x.y.z.tgz build |
| Git 仓库 | 有内网 Git | npx github:yourorg/svharness build |
| 私有 Registry | Verdaccio / Nexus | npm publish --registry=http://内网:4873 |
冒烟测试
pwsh -File .\scripts\smoke-test.ps1构建 TS → 临时目录 build → 校验文件 → --force 覆写验证。
演示与 --extra-skills 验收
端到端演示(requirements + references + baseline + extra-skills 混放)见 demo_project/README.md。在 svharnessbuild/ 下:
svharness build --harness-name demo-py --arch python --agent codechat `
--baseline ./demo_project/baseline `
--requirements ./demo_project/requirements `
--references ./demo_project/references `
--extra-skills ./demo_project/extra-skills `
--yes --forcedemo_project/extra-skills/ 布局:
| 路径 | intake detected_type |
|------|------------------------|
| harness-apply-skills-test-generator/SKILL.md | skill |
| harness-apply-skills-python-code-review/SKILL.md | skill |
| harness-apply-rules-demo-calculator.mdc | rule |
| unknown-sample/readme.txt | unknown(S65 需人工确认) |
分项验收(仅测 extra-skills 某一类时):
# 1) 纯 skills(两个目录,可重复 --extra-skills)
svharness build --harness-name demo-skills --arch python --agent codechat `
--extra-skills ./demo_project/extra-skills/harness-apply-skills-test-generator `
--extra-skills ./demo_project/extra-skills/harness-apply-skills-python-code-review `
--yes --force
# 2) 纯 rule
svharness build --harness-name demo-rules --arch python --agent codechat `
--extra-skills ./demo_project/extra-skills/harness-apply-rules-demo-calculator.mdc `
--yes --force
# 3) skills + rules 混放(与端到端相同目录)
svharness build --harness-name demo-mixed --arch python --agent codechat `
--extra-skills ./demo_project/extra-skills --yes --force
# 4) unknown 资源(需 S65 人工确认类型)
svharness build --harness-name demo-unknown --arch python --agent codechat `
--extra-skills ./demo_project/extra-skills/unknown-sample/readme.txt `
--yes --force验收观察点:
agent-env/_incoming/skills/已导入输入资源;agent-env/_incoming/manifest.yaml包含detected_type与suggested_name;.harness-build-state.yaml的S65_customize_agent_env已回填incoming_total/skills_count/rules_count/unknown_count;- unknown 或冲突资源仅在 S65 表单确认后落入
agent-env/skills/或agent-env/rules/。
历史
fixtures/目录已移除,统一由demo_project/承担演示与 intake 验收。
注意事项
- shebang:
bin/cli.js首行必须为#!/usr/bin/env node - 行尾符:建议
.gitattributes设置bin/*.js eol=lf - Node 版本:
engines.node >= 18,兼容 18 / 20 / 22 prepare脚本:已配置,Git 仓库直装时自动编译dist/
路线图
v0.8 —— 当前版本
- [x] 包名
svharnessbuild→svharness(保留旧 bin 别名一版本) - [x] 子命令
init→build(保留init隐藏别名一版本) - [x] 参数
--name→--harness-name(保留--name别名一版本) - [x]
--arch默认android-compose、--agent默认codechat - [x]
build—— 骨架 + 元文件 + 状态文件 + skill 注入 - [x] 多架构模板(
android-compose/android-xml/cpp/web-react/python) - [x]
_shared/+<arch>/两层叠拷合并 - [x] 每个架构自带 3-5 条规则文件(
.mdc格式,alwaysApply: true默认启用) - [x]
apply—— 把已构建好的 harness 绑定到目标项目(默认复制模式,--clone兼容保留) - [x] 构建辅助资源统一命名(
build-skills/harness-build-skill-*、build-rules/harness-build-rule-*) - [ ]
detach—— 从目标项目解绑并清理 dispatcher skill - [x]
doctor—— 检查既有 harness 的健康度(svharness doctor) - [ ]
phase—— 从 CLI 直接运行某个构建阶段 - [ ]
--arch auto—— 根据--baseline自动推断架构 - [ ] 更多架构模板(
ios-swiftui/service-kotlin/python-fastapi等)
欢迎对适配器与架构模板做贡献。
License
MIT
