From 03c55046628a955dd25c0c6d1f1381bf7635c5da Mon Sep 17 00:00:00 2001 From: akarizo Date: Wed, 13 May 2026 12:19:20 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=94=B9=E9=80=A0=E4=B8=BA=20Claud?= =?UTF-8?q?e=20Code=20=E4=B8=93=E7=94=A8=E7=89=88=E6=9C=AC=EF=BC=8C?= =?UTF-8?q?=E5=8A=A0=20install.sh=20=E4=B8=80=E9=94=AE=E5=AE=89=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 把上游 OpenCode 模板迁移为 Claude Code 项目级安装器: - .opencode/commands/*.md → template/.claude/commands/ (9 个 opsx-*) - .opencode/skills/* → template/.claude/skills/ (9 个 openspec-*) - .agents/skills/* → template/.claude/skills/ (5 个共享 skill) - openspec/ → template/openspec/ (schema 内嵌可离线验证) - 新增 template/openspec/changes/.gitkeep 让 openspec list 直接可用 删除上游 OpenCode 专属文件: - opencode.json (Claude Code 不需要插件配置) - AGENTS.md (OpenCode 专用) - skills-lock.json (Claude Code 用户自行装 superpowers) 新增: - install.sh: 双模式安装器 (本地 ./install.sh / curl pipe | bash) - 幂等: 已存在文件 [skip] 不覆盖 - 自动建创目标目录 - openspec CLI 前置检查 - CLAUDE.md marker 块注入 (再装跳过, 已有 CLAUDE.md 安全追加) - BSD/GNU find 双兼容 (macOS / Linux 均可) - template/CLAUDE.md.snippet: 中文 workflow 简介, 9 命令速查, git 纪律 - README.md: 中文双安装入口, 与上游差异对照 - docs/WORKFLOW_zh.md: 5 阶段详解 + 端到端示例 - LICENSE: MIT, 保留上游归属 --- AGENTS.md | 3 - LICENSE | 24 ++ README.md | 172 ++++++++++---- docs/WORKFLOW_zh.md | 200 ++++++++++++++++ install.sh | 221 ++++++++++++++++++ opencode.json | 4 - skills-lock.json | 11 - .../.claude}/commands/opsx-apply.md | 0 .../.claude}/commands/opsx-archive.md | 0 .../.claude}/commands/opsx-bulk-apply.md | 0 .../.claude}/commands/opsx-continue.md | 0 .../.claude}/commands/opsx-explore.md | 0 .../.claude}/commands/opsx-new.md | 0 .../.claude}/commands/opsx-propose.md | 0 .../.claude}/commands/opsx-sync.md | 0 .../.claude}/commands/opsx-verify.md | 0 .../architectural-decision-records/SKILL.md | 0 .../preferences.md | 0 .../templates/custom.md | 0 .../templates/madr-full.md | 0 .../templates/madr-minimal.md | 0 .../templates/nygard.md | 0 .../templates/y-statement.md | 0 .../.claude}/skills/c4-diagrams/SKILL.md | 0 .../.claude}/skills/c4-diagrams/templates.md | 0 .../skills/gherkin-authoring/SKILL.md | 0 .../.claude}/skills/grill-me/SKILL.md | 0 .../skills/openspec-apply-change/SKILL.md | 0 .../skills/openspec-archive-change/SKILL.md | 0 .../openspec-bulk-apply-change/SKILL.md | 0 .../skills/openspec-continue-change/SKILL.md | 0 .../.claude}/skills/openspec-explore/SKILL.md | 0 .../skills/openspec-git-discipline/SKILL.md | 0 .../skills/openspec-new-change/SKILL.md | 0 .../.claude}/skills/openspec-propose/SKILL.md | 0 .../skills/openspec-sync-specs/SKILL.md | 0 .../skills/openspec-verify-change/SKILL.md | 0 template/CLAUDE.md.snippet | 58 +++++ template/adr/.gitkeep | 0 template/openspec/changes/.gitkeep | 0 {openspec => template/openspec}/config.yaml | 0 .../openspec}/schemas/intent-driven/README.md | 0 .../schemas/intent-driven/schema.yaml | 0 .../schemas/intent-driven/templates/adr.md | 0 .../schemas/intent-driven/templates/design.md | 0 .../intent-driven/templates/proposal.md | 0 .../schemas/intent-driven/templates/spec.md | 0 .../schemas/intent-driven/templates/tasks.md | 0 48 files changed, 629 insertions(+), 64 deletions(-) delete mode 100644 AGENTS.md create mode 100644 LICENSE create mode 100644 docs/WORKFLOW_zh.md create mode 100755 install.sh delete mode 100644 opencode.json delete mode 100644 skills-lock.json rename {.opencode => template/.claude}/commands/opsx-apply.md (100%) rename {.opencode => template/.claude}/commands/opsx-archive.md (100%) rename {.opencode => template/.claude}/commands/opsx-bulk-apply.md (100%) rename {.opencode => template/.claude}/commands/opsx-continue.md (100%) rename {.opencode => template/.claude}/commands/opsx-explore.md (100%) rename {.opencode => template/.claude}/commands/opsx-new.md (100%) rename {.opencode => template/.claude}/commands/opsx-propose.md (100%) rename {.opencode => template/.claude}/commands/opsx-sync.md (100%) rename {.opencode => template/.claude}/commands/opsx-verify.md (100%) rename {.agents => template/.claude}/skills/architectural-decision-records/SKILL.md (100%) rename {.agents => template/.claude}/skills/architectural-decision-records/preferences.md (100%) rename {.agents => template/.claude}/skills/architectural-decision-records/templates/custom.md (100%) rename {.agents => template/.claude}/skills/architectural-decision-records/templates/madr-full.md (100%) rename {.agents => template/.claude}/skills/architectural-decision-records/templates/madr-minimal.md (100%) rename {.agents => template/.claude}/skills/architectural-decision-records/templates/nygard.md (100%) rename {.agents => template/.claude}/skills/architectural-decision-records/templates/y-statement.md (100%) rename {.agents => template/.claude}/skills/c4-diagrams/SKILL.md (100%) rename {.agents => template/.claude}/skills/c4-diagrams/templates.md (100%) rename {.agents => template/.claude}/skills/gherkin-authoring/SKILL.md (100%) rename {.agents => template/.claude}/skills/grill-me/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-apply-change/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-archive-change/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-bulk-apply-change/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-continue-change/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-explore/SKILL.md (100%) rename {.agents => template/.claude}/skills/openspec-git-discipline/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-new-change/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-propose/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-sync-specs/SKILL.md (100%) rename {.opencode => template/.claude}/skills/openspec-verify-change/SKILL.md (100%) create mode 100644 template/CLAUDE.md.snippet create mode 100644 template/adr/.gitkeep create mode 100644 template/openspec/changes/.gitkeep rename {openspec => template/openspec}/config.yaml (100%) rename {openspec => template/openspec}/schemas/intent-driven/README.md (100%) rename {openspec => template/openspec}/schemas/intent-driven/schema.yaml (100%) rename {openspec => template/openspec}/schemas/intent-driven/templates/adr.md (100%) rename {openspec => template/openspec}/schemas/intent-driven/templates/design.md (100%) rename {openspec => template/openspec}/schemas/intent-driven/templates/proposal.md (100%) rename {openspec => template/openspec}/schemas/intent-driven/templates/spec.md (100%) rename {openspec => template/openspec}/schemas/intent-driven/templates/tasks.md (100%) diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 00d05f4..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,3 +0,0 @@ -# AGENTS.md - -- For OpenSpec propose/apply/verify/archive workflows, use the local `openspec-git-discipline` skill to enforce proposal commits before apply and merge-before-archive discipline. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5c9ab6a --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +MIT License + +Copyright (c) 2026 intent-driven-claude-code contributors +Portions copyright (c) 2026 intent-driven-dev (upstream intent-driven-template) +Portions copyright (c) 2025-2026 Fission AI (OpenSpec schema engine) +Portions copyright (c) Matt Pocock (grill-me skill prior art) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 85eb2d7..92f800c 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,149 @@ -# Intent-Driven Template +# intent-driven-claude-code -This is a template project for intent-driven software delivery with [OpenSpec](https://github.com/Fission-AI/OpenSpec), -[OpenCode](https://opencode.ai/), and reusable engineering skills. +> A Claude Code adaptation of the [intent-driven OpenSpec workflow](https://intent-driven.dev/). +> 上游 [intent-driven-dev/intent-driven-template](https://github.com/intent-driven-dev/intent-driven-template) 是为 OpenCode 设计的, +> 本仓库把它的命令、技能、schema 适配到 **Claude Code**(`.claude/commands` 和 `.claude/skills`),并提供一键安装脚本。 -It is intended for teams that want changes to start from clear intent, move -through explicit behaviour and design artifacts, and finish with implementation -tasks that preserve the reasoning behind the work. +``` +proposal → specs → design → adr → tasks +``` + +每个变更按这 5 个 artifact 顺序流转:先说清楚 _为什么_,再用 Gherkin 描述 _做什么_, +再讨论 _怎么做_,把不可逆的架构决策固化为 ADR,最后才落到 _按怎样的步骤实现_。 +所有 artifact 都是带版本的纯 Markdown,与 git 协作天然契合。 + +--- + +## 前置依赖 -## Walkthrough +| 工具 | 版本 | 安装 | +| --- | --- | --- | +| [Claude Code](https://claude.com/claude-code) | 最新即可 | 官方 CLI / Desktop / Web / IDE 任一即可 | +| Node.js | ≥ 18 | nvm / fnm / volta / brew | +| OpenSpec CLI | ≥ 1.3 | `npm install -g @fission-ai/openspec`(或 pnpm / bun add 全局) | -Read the full walkthrough: [Spec-Driven Development with OpenSpec and OpenCode](https://intent-driven.dev/blog/2026/05/10/spec-driven-development-openspec-opencode/). +可选:[Superpowers](https://github.com/obra/superpowers) 已被自动 reuse(若你 ~/.claude 装过)。 -[![Spec-Driven Development with OpenSpec and OpenCode](https://img.youtube.com/vi/M3dp9u1wZes/maxresdefault.jpg)](https://www.youtube.com/watch?v=M3dp9u1wZes) +--- -## What This Template Uses +## 一键安装 + +### 方式 A:克隆后运行(推荐 — 可审计) + +```bash +git clone https://github.com/akarizo/intent-driven-claude-code.git /tmp/idt +/tmp/idt/install.sh ~/path/to/your-project +``` -- OpenSpec for setup, proposal, specification, design, ADR, and task artifacts. -- Custom schemas from https://github.com/intent-driven-dev/openspec-schemas. -- A bundled local copy of the `intent-driven` custom schema from - https://github.com/intent-driven-dev/openspec-schemas/tree/main/openspec/schemas/intent-driven - for the full `proposal -> specs -> design -> adr -> tasks` lifecycle. -- OpenSpec git discipline so proposals land on `main` before apply, and - implementation lands on `main` before archive. -- OpenCode skills for repeatable collaboration and implementation workflows, - including C4 diagrams, ADR authoring, and OpenSpec lifecycle commands. -- Superpowers from https://github.com/obra/superpowers for guided practices such - as brainstorming, planning, debugging, TDD, verification, worktrees, and - subagent-driven parallel work. -- A `grill-me` style of rigorous design interrogation, inspired by - https://github.com/mattpocock/skills/blob/main/skills/productivity/grill-me/SKILL.md. -- ADRs for durable architectural decisions. -- C4 diagrams for communicating architecture boundaries and relationships. -- Gherkin-style requirements and scenarios for observable behaviour. +### 方式 B:curl 一行(极简) -The bundled OpenSpec schema is a local copy of the `intent-driven` schema from -https://github.com/intent-driven-dev/openspec-schemas/tree/main/openspec/schemas/intent-driven. +```bash +curl -fsSL https://raw.githubusercontent.com/akarizo/intent-driven-claude-code/main/install.sh \ + | bash -s -- ~/path/to/your-project +``` -## Workflow +> 把 `akarizo` 替换为你自己的 GitHub 用户名(你 fork 之后的)。 +> 也可以通过 `IDT_REPO_URL` 环境变量覆盖: +> `IDT_REPO_URL=https://github.com/YOUR/REPO bash -c 'curl -fsSL ... | bash -s -- '` -The intent-driven workflow moves through these artifacts in order: +**TARGET_DIR 缺省 `pwd`,所以也可以:** -```text -proposal -> specs -> design -> adr -> tasks +```bash +cd ~/your-project +curl -fsSL https://raw.githubusercontent.com/akarizo/intent-driven-claude-code/main/install.sh | bash ``` -- `proposal` captures why the change matters. -- `specs` describe observable behaviour with Gherkin-style scenarios. -- `design` explains the implementation approach and trade-offs. -- `adr` records durable architectural decisions. -- `tasks` turn the accepted intent, behaviour, design, and decisions into work. +安装器**幂等**:重复运行不会覆盖已有文件,全部 `[skip]`。 -## Schema +--- -This repository includes a bundled local copy of the `intent-driven` schema at -`openspec/schemas/intent-driven/`. The upstream schema lives in -https://github.com/intent-driven-dev/openspec-schemas/tree/main/openspec/schemas/intent-driven. +## 它装了什么 -To activate the schema, set this in `openspec/config.yaml`: +安装到目标项目根的内容: -```yaml -schema: intent-driven ``` +your-project/ +├── .claude/ +│ ├── commands/ # 9 个 /opsx-* slash 命令 +│ └── skills/ # 14 个 skill(9 个 openspec-*,5 个共享) +├── openspec/ +│ ├── config.yaml # schema: intent-driven + 4 条 rules +│ └── schemas/intent-driven/ # 离线 schema 副本 +├── adr/.gitkeep # ADR 工作流落地点 +└── CLAUDE.md # 追加一段「Intent-Driven 工作流」中文说明 + # (已存在则用 marker 块幂等追加;不存在则新建) +``` + +不写:`~/.claude`、系统配置、settings。所有改动严格限定在目标项目根。 -To validate it, run: +--- + +## 快速试用 ```bash +cd ~/path/to/your-project + +# 启动 Claude Code(CLI 或 Desktop) +# 输入: +/opsx-propose add-hello-world +``` + +Claude 会: +1. 调用 `openspec new change add-hello-world` 创建变更骨架 +2. 依次生成 `proposal.md` → `specs/.../spec.md` → `design.md` → `adr/NNNN-*.md` → `tasks.md` +3. 提示运行 `/opsx-apply` 进入实现阶段 + +CLI 验证: + +```bash +openspec list +openspec status --change add-hello-world openspec schema validate intent-driven ``` + +--- + +## 9 个 slash 命令速查 + +| 命令 | 一句话 | +| --- | --- | +| `/opsx-new ` | 创建变更,停在第一个 artifact 模板等用户确认 | +| `/opsx-propose ` | 一次性生成 apply 所需的所有 artifacts | +| `/opsx-continue [name]` | 推进下一个 artifact | +| `/opsx-apply [name]` | 按 tasks 执行实现,逐条勾选 | +| `/opsx-verify [name]` | 三维一致性检查(completeness / correctness / coherence) | +| `/opsx-archive [name]` | 归档已完成变更(要求 implementation 已合回 `main`) | +| `/opsx-sync [name]` | 把 delta specs 合入主 specs | +| `/opsx-explore [topic]` | 探索模式:只思考、不实现 | +| `/opsx-bulk-apply` | 多变更并行 worktree 实现 | + +详细工作流:[docs/WORKFLOW_zh.md](docs/WORKFLOW_zh.md) + +--- + +## 与上游的差异 + +| 项 | 上游(OpenCode) | 本仓库(Claude Code) | +| --- | --- | --- | +| 命令位置 | `.opencode/commands/` | `.claude/commands/` | +| 技能位置 | `.opencode/skills/` + `.agents/skills/` | `.claude/skills/`(合并后) | +| 插件机制 | `opencode.json` 声明 superpowers | 不需要:Claude Code 用户自行装 [Superpowers](https://github.com/obra/superpowers) | +| 安装方式 | 手动复制目录 | `install.sh` 一键,幂等 | +| 中文文档 | 无 | README + WORKFLOW_zh + CLAUDE.md snippet 全中文 | + +所有命令、技能和 schema **内容字节级一致**,仅迁移路径与添加安装器。 + +--- + +## 致谢 + +- [intent-driven-dev/intent-driven-template](https://github.com/intent-driven-dev/intent-driven-template) —— 上游模板与工作流设计 +- [Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec) —— OpenSpec CLI 与 schema 引擎 +- [obra/superpowers](https://github.com/obra/superpowers) —— brainstorming / planning / TDD 等技能集 +- [mattpocock/skills](https://github.com/mattpocock/skills) —— `grill-me` 风格来源 + +--- + +## License + +MIT。详见 [LICENSE](LICENSE)。 diff --git a/docs/WORKFLOW_zh.md b/docs/WORKFLOW_zh.md new file mode 100644 index 0000000..f925180 --- /dev/null +++ b/docs/WORKFLOW_zh.md @@ -0,0 +1,200 @@ +# Intent-Driven 工作流详解 + +> 把 _为什么_、_做什么_、_怎么做_、_长期决策_、_实现步骤_ 这五件事,**强制按顺序**写下来,让代码上线时仍然能解释自己。 + +``` +proposal → specs → design → adr → tasks +``` + +每一步都依赖前一步。`/opsx-apply` 在 `tasks` 完成前会拒绝运行。 +schema 把这套规则编码在 `openspec/schemas/intent-driven/schema.yaml` 里。 + +--- + +## 阶段总览 + +| 阶段 | 文件 | 关键问题 | 配套 skill | +| --- | --- | --- | --- | +| 1. proposal | `proposal.md` | 为什么现在做?影响什么 capability? | `grill-me` | +| 2. specs | `specs//spec.md` | 系统外部可观测的行为是什么? | `gherkin-authoring` | +| 3. design | `design.md` | 怎么实现?权衡了什么? | `c4-diagrams` | +| 4. adr | `/adr/NNNN-*.md` | 哪些是长期不可逆的架构决策? | `architectural-decision-records` | +| 5. tasks | `tasks.md` | 怎么落到逐条可勾选的步骤? | —— | + +--- + +## 1. proposal — 写"为什么" + +**目标**:让一个完全没上下文的同事/未来的自己,仅凭这份 proposal 就能判断这件事值不值得做。 + +**模板**(来自 schema): + +```markdown +## Why + + +## What Changes + + +## Capabilities +### New Capabilities +- `user-auth`: 简述这个能力的范围 +### Modified Capabilities +- `data-export`: 行为级的改动是什么 + +## Impact + +``` + +**`Capabilities` 是 proposal → specs 的契约**:每一个列出的 capability 都会在 specs 阶段 +对应一个 `specs//spec.md` 文件。 + +--- + +## 2. specs — 写"做什么" + +**目标**:用 Gherkin 句式描述行为,避免泄漏 UI/数据库/HTTP 细节。 + +```markdown +## ADDED Requirements + +### Requirement: User data export +Feature: User data export +Rule: Users can export their own data + +#### Scenario: Successful CSV export +- **GIVEN** a user has saved data +- **WHEN** the user exports their data as CSV +- **THEN** the system provides a CSV file containing the user's data +``` + +四种 delta header: + +| Header | 用途 | 注意事项 | +| --- | --- | --- | +| `## ADDED Requirements` | 新增 requirement | 直接写 | +| `## MODIFIED Requirements` | 修改已有 requirement | **必须粘贴完整的修改后内容**,不能只贴 diff | +| `## REMOVED Requirements` | 删除 requirement | 必须含 `**Reason**` 和 `**Migration**` | +| `## RENAMED Requirements` | 仅改名 | `FROM: / TO:` 格式 | + +`### Requirement: ` 和 `#### Scenario: ` 的标题层级是 OpenSpec archive 用来合并的契约,**不能改**。 + +--- + +## 3. design — 写"怎么做" + +**目标**:把会被后续 review 的关键决策(why X over Y)固化下来;预防"半年后看代码不知道为什么这么写"。 + +`design.md` 包含: + +- **Context**:现状、约束、相关人 +- **Goals / Non-Goals**:明确做什么 + **明确不做什么** +- **Decisions**:每个决策都附 _备选方案_ 和 _选择理由_ +- **Risks / Trade-offs**:`[Risk] → Mitigation` +- **Migration Plan**:上线 / 回滚步骤 +- **Open Questions**:尚未解决的问题;如果建议变更某个 in-force ADR,写在这里,由 adr 阶段处理 + +**铁律**:写 design 前先读 `adr/`,构建 supersession 图,识别**当前生效**的 ADR 集合。 +新 design 必须跟现行 ADR 一致;要推翻某个现行 ADR,只能在 Open Questions 提议并让 adr 阶段新建一个 supersede。 + +--- + +## 4. adr — 写"长期不可逆决策" + +**铁律**:**ADR 一经 accepted 就不可改**。任何字段都不可改:Status、Date、Decision、Consequences 全部冻结。 + +要变更一个旧决策?新建一个 ADR: + +```markdown +# 0042. 改用 Postgres 替代 MySQL 做目录服务 + +- Status: accepted, supersedes ADR-0017 +- Date: 2026-05-13 +- Supersedes: ADR-0017 + +## Context +...为什么要重新讨论 ADR-0017... +``` + +文件名:`NNNN-kebab-title.md`,NNNN 是仓库范围全局递增,**永不复用**。 + +何时建 ADR?满足三个条件全部: + +1. 是**长期架构承诺**(pattern / 技术选型 / 模块边界 / 契约),不是战术实现细节 +2. 会影响**当前变更之外**的未来工作 +3. 当前没有 in-force ADR 已经覆盖,或者**有意推翻**某个 in-force ADR + +不满足就别建 ADR,写在 design 里即可。 + +--- + +## 5. tasks — 写"怎么逐步实现" + +```markdown +## 1. 数据层 + +- [ ] 1.1 新建 user_exports 表(migration) +- [ ] 1.2 增加 ExportJob 模型 + +## 2. API 层 + +- [ ] 2.1 POST /v1/exports 创建任务 +- [ ] 2.2 GET /v1/exports/:id 查询状态 +``` + +**强制**:必须用 `- [ ]` checkbox 格式,否则 `/opsx-apply` 解析不到进度。 + +--- + +## Git 纪律 + +| 时机 | 规则 | +| --- | --- | +| propose 前 | 优先在 `main` 上;不在则警告并询问 | +| propose 后 | 提示用户 commit;可选建 PR 分支 | +| apply 前 | **proposal 必须已在 `main`**;之后可在 main / 分支 / worktree 实现 | +| archive 前 | **必须从 `main` 运行**;implementation 必须已合回 | +| archive 后 | 提示 commit archive 与 spec sync 改动 | + +完整规则见 `.claude/skills/openspec-git-discipline/SKILL.md`。 + +--- + +## 端到端示例 + +```bash +# 在某项目根 +cd ~/my-app + +# 1. 启动 Claude Code,输入: +/opsx-propose add-user-export + +# Claude 会: +# - openspec new change add-user-export +# - 生成 proposal.md, specs/user-export/spec.md, design.md, adr/0042-*.md, tasks.md + +# 2. 用户审阅,提交到 PR,合到 main +git add openspec adr +git commit -m "propose: add-user-export" +git push # 走 PR 合 main + +# 3. 在 main 或 worktree 实现 +git checkout -b feat/add-user-export +/opsx-apply add-user-export +# Claude 按 tasks 逐条实现,勾选 checkbox + +# 4. 实现合回 main 后归档 +git checkout main && git pull +/opsx-verify add-user-export # 一致性检查 +/opsx-archive add-user-export # 移到 openspec/changes/archive/YYYY-MM-DD-* +``` + +--- + +## 何时**不**用这个 schema + +- 文档单改、依赖升级、临时性 hotfix:太重,用 commit message 就够 +- 行为驱动但不涉及架构决策:考虑用 `behaviour-driven` schema 替代 +- 内部脚本 / 玩具项目:YAGNI + +参考:[schema 仓库](https://github.com/intent-driven-dev/openspec-schemas) 还提供 `spec-driven`、`behaviour-driven` 等更轻量 schema。 diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..679a988 --- /dev/null +++ b/install.sh @@ -0,0 +1,221 @@ +#!/usr/bin/env bash +# intent-driven-claude-code installer +# +# 用法 / Usage +# 本地 / Local : ./install.sh [TARGET_DIR] +# 管道 / Pipe : curl -fsSL /install.sh | bash -s -- [TARGET_DIR] +# +# TARGET_DIR 缺省为当前工作目录;不存在会自动创建。 +# 复制是幂等的:已存在的文件会被跳过,不会被覆盖。 +# +# 退出码: +# 0 成功 +# 2 参数错误 +# 3 缺少 openspec CLI +# 4 复制 / 写入 / 下载失败 + +set -euo pipefail + +# --------------------------------------------------------------------------- +# 可配置项:fork 后请把 REPO_URL 改为你自己的仓库地址, +# 这是 curl | bash 模式下载 tarball 的来源。 +# 也可在调用前设置环境变量 IDT_REPO_URL 覆盖。 +# --------------------------------------------------------------------------- +REPO_URL="${IDT_REPO_URL:-https://github.com/akarizo/intent-driven-claude-code}" +BRANCH="${IDT_BRANCH:-main}" + +# --------------------------------------------------------------------------- +# 颜色 & 日志 +# --------------------------------------------------------------------------- +if [[ -t 1 ]] && command -v tput >/dev/null 2>&1; then + C_GREEN=$(tput setaf 2 2>/dev/null || true) + C_YELLOW=$(tput setaf 3 2>/dev/null || true) + C_RED=$(tput setaf 1 2>/dev/null || true) + C_DIM=$(tput dim 2>/dev/null || true) + C_RESET=$(tput sgr0 2>/dev/null || true) +else + C_GREEN=""; C_YELLOW=""; C_RED=""; C_DIM=""; C_RESET="" +fi + +log_add() { printf '%s[add]%s %s\n' "$C_GREEN" "$C_RESET" "$1"; } +log_skip() { printf '%s[skip]%s %s\n' "$C_DIM" "$C_RESET" "$1"; } +log_app() { printf '%s[append]%s %s\n' "$C_YELLOW" "$C_RESET" "$1"; } +log_info() { printf '%s[info]%s %s\n' "$C_YELLOW" "$C_RESET" "$1"; } +log_err() { printf '%s[err]%s %s\n' "$C_RED" "$C_RESET" "$1" >&2; } + +# --------------------------------------------------------------------------- +# 参数解析 +# --------------------------------------------------------------------------- +usage() { + cat </install.sh | bash -s -- [TARGET_DIR] + +参数: + TARGET_DIR 目标项目根目录,缺省 \$PWD + +环境变量: + IDT_REPO_URL pipe 模式下载 tarball 的仓库地址 (默认 $REPO_URL) + IDT_BRANCH pipe 模式下载的分支 (默认 $BRANCH) + +选项: + -h, --help 显示本帮助 +EOF +} + +case "${1:-}" in + -h|--help) usage; exit 0 ;; +esac + +TARGET="${1:-$PWD}" +if [[ $# -gt 1 ]]; then + log_err "多余参数: ${*:2}"; usage; exit 2 +fi + +# --------------------------------------------------------------------------- +# 前置检查:openspec CLI 必须存在 +# --------------------------------------------------------------------------- +if ! command -v openspec >/dev/null 2>&1; then + log_err "未检测到 openspec CLI" + cat >&2 </dev/null 2>&1 || { log_err "pipe 模式需要 curl"; exit 4; } + command -v tar >/dev/null 2>&1 || { log_err "pipe 模式需要 tar"; exit 4; } + TMP=$(mktemp -d) + CLEANUP_TMP="$TMP" + trap 'rm -rf "$CLEANUP_TMP"' EXIT + log_info "pipe 模式:下载 $REPO_URL@$BRANCH" + if ! curl -fsSL "$REPO_URL/archive/refs/heads/$BRANCH.tar.gz" \ + | tar -xz -C "$TMP" --strip-components=1; then + log_err "下载或解压失败:$REPO_URL@$BRANCH" + exit 4 + fi + TEMPLATE_SRC="$TMP/template" +fi + +[[ -d "$TEMPLATE_SRC" ]] || { log_err "找不到模板目录: $TEMPLATE_SRC"; exit 4; } + +# --------------------------------------------------------------------------- +# 目标准备 +# --------------------------------------------------------------------------- +if [[ ! -e "$TARGET" ]]; then + log_info "目标不存在,自动创建: $TARGET" + mkdir -p "$TARGET" +fi +[[ -d "$TARGET" ]] || { log_err "目标不是目录: $TARGET"; exit 2; } +TARGET=$(cd "$TARGET" && pwd) + +log_info "模板来源: $TEMPLATE_SRC (模式: $MODE)" +log_info "安装到 : $TARGET" +echo + +# --------------------------------------------------------------------------- +# 幂等复制:BSD/GNU 双兼容;统计在循环外维护 +# 注意:用 process substitution 而非 pipe,以便 while 体里能修改外层变量 +# --------------------------------------------------------------------------- +ADD_COUNT=0 +SKIP_COUNT=0 + +copy_tree() { + local src="$1" dst="$2" rel out + [[ -d "$src" ]] || return 0 + while IFS= read -r -d '' rel; do + rel="${rel#./}" + [[ -z "$rel" || "$rel" == "." ]] && continue + out="$dst/$rel" + if [[ -d "$src/$rel" ]]; then + mkdir -p "$out" + else + if [[ -e "$out" ]]; then + log_skip "${out#$TARGET/}" + SKIP_COUNT=$((SKIP_COUNT+1)) + else + mkdir -p "$(dirname "$out")" + cp "$src/$rel" "$out" + log_add "${out#$TARGET/}" + ADD_COUNT=$((ADD_COUNT+1)) + fi + fi + done < <(cd "$src" && find . \( -type d -o -type f \) -print0) +} + +copy_tree "$TEMPLATE_SRC/.claude" "$TARGET/.claude" +copy_tree "$TEMPLATE_SRC/openspec" "$TARGET/openspec" +copy_tree "$TEMPLATE_SRC/adr" "$TARGET/adr" + +# --------------------------------------------------------------------------- +# CLAUDE.md 注入 (marker 包裹,幂等) +# --------------------------------------------------------------------------- +SNIPPET="$TEMPLATE_SRC/CLAUDE.md.snippet" +TARGET_CLAUDE="$TARGET/CLAUDE.md" +MARKER_BEGIN="" + +[[ -f "$SNIPPET" ]] || { log_err "缺失 CLAUDE.md.snippet: $SNIPPET"; exit 4; } + +if [[ ! -f "$TARGET_CLAUDE" ]]; then + cp "$SNIPPET" "$TARGET_CLAUDE" + log_add "CLAUDE.md" + ADD_COUNT=$((ADD_COUNT+1)) +elif grep -qF "$MARKER_BEGIN" "$TARGET_CLAUDE"; then + log_skip "CLAUDE.md (已含 intent-driven 段,跳过)" + SKIP_COUNT=$((SKIP_COUNT+1)) +else + { + printf '\n\n' + cat "$SNIPPET" + } >> "$TARGET_CLAUDE" + log_app "CLAUDE.md (追加 intent-driven 段)" +fi + +# --------------------------------------------------------------------------- +# 摘要 +# --------------------------------------------------------------------------- +echo +printf '%s✓ Intent-Driven 已就绪%s [add] %d [skip] %d\n' \ + "$C_GREEN" "$C_RESET" "$ADD_COUNT" "$SKIP_COUNT" +cat < # 一次性生成 proposal/design/tasks + /opsx-new # 或:逐 artifact 推进 + 3. CLI 验证: + openspec list + openspec schema validate intent-driven + +更多: + - 9 个 opsx-* slash command 见 .claude/commands/ + - 14 个 skill 见 .claude/skills/ + - schema 副本见 openspec/schemas/intent-driven/ +EOF diff --git a/opencode.json b/opencode.json deleted file mode 100644 index cc684f6..0000000 --- a/opencode.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://opencode.ai/config.json", - "plugin": ["superpowers@git+https://github.com/obra/superpowers.git"] -} diff --git a/skills-lock.json b/skills-lock.json deleted file mode 100644 index 2b4c26d..0000000 --- a/skills-lock.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "skills": { - "grill-me": { - "source": "mattpocock/skills", - "sourceType": "github", - "skillPath": "skills/productivity/grill-me/SKILL.md", - "computedHash": "784f0dbb7403b0f00324bce9a112f715342777a0daee7bbb7385f9c6f0a170ea" - } - } -} diff --git a/.opencode/commands/opsx-apply.md b/template/.claude/commands/opsx-apply.md similarity index 100% rename from .opencode/commands/opsx-apply.md rename to template/.claude/commands/opsx-apply.md diff --git a/.opencode/commands/opsx-archive.md b/template/.claude/commands/opsx-archive.md similarity index 100% rename from .opencode/commands/opsx-archive.md rename to template/.claude/commands/opsx-archive.md diff --git a/.opencode/commands/opsx-bulk-apply.md b/template/.claude/commands/opsx-bulk-apply.md similarity index 100% rename from .opencode/commands/opsx-bulk-apply.md rename to template/.claude/commands/opsx-bulk-apply.md diff --git a/.opencode/commands/opsx-continue.md b/template/.claude/commands/opsx-continue.md similarity index 100% rename from .opencode/commands/opsx-continue.md rename to template/.claude/commands/opsx-continue.md diff --git a/.opencode/commands/opsx-explore.md b/template/.claude/commands/opsx-explore.md similarity index 100% rename from .opencode/commands/opsx-explore.md rename to template/.claude/commands/opsx-explore.md diff --git a/.opencode/commands/opsx-new.md b/template/.claude/commands/opsx-new.md similarity index 100% rename from .opencode/commands/opsx-new.md rename to template/.claude/commands/opsx-new.md diff --git a/.opencode/commands/opsx-propose.md b/template/.claude/commands/opsx-propose.md similarity index 100% rename from .opencode/commands/opsx-propose.md rename to template/.claude/commands/opsx-propose.md diff --git a/.opencode/commands/opsx-sync.md b/template/.claude/commands/opsx-sync.md similarity index 100% rename from .opencode/commands/opsx-sync.md rename to template/.claude/commands/opsx-sync.md diff --git a/.opencode/commands/opsx-verify.md b/template/.claude/commands/opsx-verify.md similarity index 100% rename from .opencode/commands/opsx-verify.md rename to template/.claude/commands/opsx-verify.md diff --git a/.agents/skills/architectural-decision-records/SKILL.md b/template/.claude/skills/architectural-decision-records/SKILL.md similarity index 100% rename from .agents/skills/architectural-decision-records/SKILL.md rename to template/.claude/skills/architectural-decision-records/SKILL.md diff --git a/.agents/skills/architectural-decision-records/preferences.md b/template/.claude/skills/architectural-decision-records/preferences.md similarity index 100% rename from .agents/skills/architectural-decision-records/preferences.md rename to template/.claude/skills/architectural-decision-records/preferences.md diff --git a/.agents/skills/architectural-decision-records/templates/custom.md b/template/.claude/skills/architectural-decision-records/templates/custom.md similarity index 100% rename from .agents/skills/architectural-decision-records/templates/custom.md rename to template/.claude/skills/architectural-decision-records/templates/custom.md diff --git a/.agents/skills/architectural-decision-records/templates/madr-full.md b/template/.claude/skills/architectural-decision-records/templates/madr-full.md similarity index 100% rename from .agents/skills/architectural-decision-records/templates/madr-full.md rename to template/.claude/skills/architectural-decision-records/templates/madr-full.md diff --git a/.agents/skills/architectural-decision-records/templates/madr-minimal.md b/template/.claude/skills/architectural-decision-records/templates/madr-minimal.md similarity index 100% rename from .agents/skills/architectural-decision-records/templates/madr-minimal.md rename to template/.claude/skills/architectural-decision-records/templates/madr-minimal.md diff --git a/.agents/skills/architectural-decision-records/templates/nygard.md b/template/.claude/skills/architectural-decision-records/templates/nygard.md similarity index 100% rename from .agents/skills/architectural-decision-records/templates/nygard.md rename to template/.claude/skills/architectural-decision-records/templates/nygard.md diff --git a/.agents/skills/architectural-decision-records/templates/y-statement.md b/template/.claude/skills/architectural-decision-records/templates/y-statement.md similarity index 100% rename from .agents/skills/architectural-decision-records/templates/y-statement.md rename to template/.claude/skills/architectural-decision-records/templates/y-statement.md diff --git a/.agents/skills/c4-diagrams/SKILL.md b/template/.claude/skills/c4-diagrams/SKILL.md similarity index 100% rename from .agents/skills/c4-diagrams/SKILL.md rename to template/.claude/skills/c4-diagrams/SKILL.md diff --git a/.agents/skills/c4-diagrams/templates.md b/template/.claude/skills/c4-diagrams/templates.md similarity index 100% rename from .agents/skills/c4-diagrams/templates.md rename to template/.claude/skills/c4-diagrams/templates.md diff --git a/.agents/skills/gherkin-authoring/SKILL.md b/template/.claude/skills/gherkin-authoring/SKILL.md similarity index 100% rename from .agents/skills/gherkin-authoring/SKILL.md rename to template/.claude/skills/gherkin-authoring/SKILL.md diff --git a/.agents/skills/grill-me/SKILL.md b/template/.claude/skills/grill-me/SKILL.md similarity index 100% rename from .agents/skills/grill-me/SKILL.md rename to template/.claude/skills/grill-me/SKILL.md diff --git a/.opencode/skills/openspec-apply-change/SKILL.md b/template/.claude/skills/openspec-apply-change/SKILL.md similarity index 100% rename from .opencode/skills/openspec-apply-change/SKILL.md rename to template/.claude/skills/openspec-apply-change/SKILL.md diff --git a/.opencode/skills/openspec-archive-change/SKILL.md b/template/.claude/skills/openspec-archive-change/SKILL.md similarity index 100% rename from .opencode/skills/openspec-archive-change/SKILL.md rename to template/.claude/skills/openspec-archive-change/SKILL.md diff --git a/.opencode/skills/openspec-bulk-apply-change/SKILL.md b/template/.claude/skills/openspec-bulk-apply-change/SKILL.md similarity index 100% rename from .opencode/skills/openspec-bulk-apply-change/SKILL.md rename to template/.claude/skills/openspec-bulk-apply-change/SKILL.md diff --git a/.opencode/skills/openspec-continue-change/SKILL.md b/template/.claude/skills/openspec-continue-change/SKILL.md similarity index 100% rename from .opencode/skills/openspec-continue-change/SKILL.md rename to template/.claude/skills/openspec-continue-change/SKILL.md diff --git a/.opencode/skills/openspec-explore/SKILL.md b/template/.claude/skills/openspec-explore/SKILL.md similarity index 100% rename from .opencode/skills/openspec-explore/SKILL.md rename to template/.claude/skills/openspec-explore/SKILL.md diff --git a/.agents/skills/openspec-git-discipline/SKILL.md b/template/.claude/skills/openspec-git-discipline/SKILL.md similarity index 100% rename from .agents/skills/openspec-git-discipline/SKILL.md rename to template/.claude/skills/openspec-git-discipline/SKILL.md diff --git a/.opencode/skills/openspec-new-change/SKILL.md b/template/.claude/skills/openspec-new-change/SKILL.md similarity index 100% rename from .opencode/skills/openspec-new-change/SKILL.md rename to template/.claude/skills/openspec-new-change/SKILL.md diff --git a/.opencode/skills/openspec-propose/SKILL.md b/template/.claude/skills/openspec-propose/SKILL.md similarity index 100% rename from .opencode/skills/openspec-propose/SKILL.md rename to template/.claude/skills/openspec-propose/SKILL.md diff --git a/.opencode/skills/openspec-sync-specs/SKILL.md b/template/.claude/skills/openspec-sync-specs/SKILL.md similarity index 100% rename from .opencode/skills/openspec-sync-specs/SKILL.md rename to template/.claude/skills/openspec-sync-specs/SKILL.md diff --git a/.opencode/skills/openspec-verify-change/SKILL.md b/template/.claude/skills/openspec-verify-change/SKILL.md similarity index 100% rename from .opencode/skills/openspec-verify-change/SKILL.md rename to template/.claude/skills/openspec-verify-change/SKILL.md diff --git a/template/CLAUDE.md.snippet b/template/CLAUDE.md.snippet new file mode 100644 index 0000000..55465ea --- /dev/null +++ b/template/CLAUDE.md.snippet @@ -0,0 +1,58 @@ + +## Intent-Driven 工作流 + +本项目采用 intent-driven 规约驱动开发。每个变更按 5 个 artifact 顺序流转, +后续 artifact 必须建立在前置 artifact 之上: + +``` +proposal → specs → design → adr → tasks +``` + +- **proposal**:陈述"为什么要做",列出会创建或修改的 capabilities +- **specs**:用 Gherkin 风格(`GIVEN / WHEN / THEN`)描述可观测行为 +- **design**:技术方案、关键决策、权衡、迁移计划 +- **adr**:长期架构决策,写入仓库根的 `adr/`,**不可改**(需要变更则新建 ADR 并 supersede 旧的) +- **tasks**:可勾选的实现清单,按依赖排序 + +### Slash 命令 + +| 命令 | 用途 | +| --- | --- | +| `/opsx-new ` | 新建变更,仅展示第一个 artifact 模板,等用户确认 | +| `/opsx-propose ` | 一次性生成 apply 所需的全部 artifacts | +| `/opsx-continue [name]` | 继续推进当前变更的下一个 artifact | +| `/opsx-apply [name]` | 按 tasks 执行实现,逐条勾选 | +| `/opsx-verify [name]` | 核对实现与 specs/design 的一致性,输出三维报告 | +| `/opsx-archive [name]` | 归档已完成变更(必须先合回 `main`) | +| `/opsx-sync [name]` | 把 delta specs 合并到主 specs | +| `/opsx-explore [topic]` | 探索模式:只思考、不实现 | +| `/opsx-bulk-apply` | 多变更并行 worktree 实现 | + +### Git 纪律(关键) + +- **propose → apply**:proposal artifacts 必须先合入 `main`,apply 才能开始 +- **apply → archive**:implementation 必须先合回 `main`,archive 才能开始 +- 不会代你 commit / branch / merge,除非你显式要求 +- 完整规则见 `.claude/skills/openspec-git-discipline/SKILL.md` + +### Schema + +当前激活:`intent-driven`(见 `openspec/config.yaml`)。 +本仓库内嵌 schema 副本:`openspec/schemas/intent-driven/`,离线可验证。 + +```bash +openspec list # 列出所有变更 +openspec status --change # 查看某变更的 artifact 状态 +openspec schema validate intent-driven # 验证 schema +``` + +### 配套 skills + +`.claude/skills/` 内置: +- `architectural-decision-records` —— ADR 5 种模板(Nygard / MADR / Y-statement / 自定义) +- `c4-diagrams` —— C4 架构图(ASCII / Mermaid) +- `gherkin-authoring` —— Gherkin 行为规约最佳实践 +- `grill-me` —— 设计追问,逐分支澄清决策 +- `openspec-git-discipline` —— git 流转关卡 +- 9 个 `openspec-*` —— 对应 `/opsx-*` 命令的执行细节 + diff --git a/template/adr/.gitkeep b/template/adr/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/template/openspec/changes/.gitkeep b/template/openspec/changes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/openspec/config.yaml b/template/openspec/config.yaml similarity index 100% rename from openspec/config.yaml rename to template/openspec/config.yaml diff --git a/openspec/schemas/intent-driven/README.md b/template/openspec/schemas/intent-driven/README.md similarity index 100% rename from openspec/schemas/intent-driven/README.md rename to template/openspec/schemas/intent-driven/README.md diff --git a/openspec/schemas/intent-driven/schema.yaml b/template/openspec/schemas/intent-driven/schema.yaml similarity index 100% rename from openspec/schemas/intent-driven/schema.yaml rename to template/openspec/schemas/intent-driven/schema.yaml diff --git a/openspec/schemas/intent-driven/templates/adr.md b/template/openspec/schemas/intent-driven/templates/adr.md similarity index 100% rename from openspec/schemas/intent-driven/templates/adr.md rename to template/openspec/schemas/intent-driven/templates/adr.md diff --git a/openspec/schemas/intent-driven/templates/design.md b/template/openspec/schemas/intent-driven/templates/design.md similarity index 100% rename from openspec/schemas/intent-driven/templates/design.md rename to template/openspec/schemas/intent-driven/templates/design.md diff --git a/openspec/schemas/intent-driven/templates/proposal.md b/template/openspec/schemas/intent-driven/templates/proposal.md similarity index 100% rename from openspec/schemas/intent-driven/templates/proposal.md rename to template/openspec/schemas/intent-driven/templates/proposal.md diff --git a/openspec/schemas/intent-driven/templates/spec.md b/template/openspec/schemas/intent-driven/templates/spec.md similarity index 100% rename from openspec/schemas/intent-driven/templates/spec.md rename to template/openspec/schemas/intent-driven/templates/spec.md diff --git a/openspec/schemas/intent-driven/templates/tasks.md b/template/openspec/schemas/intent-driven/templates/tasks.md similarity index 100% rename from openspec/schemas/intent-driven/templates/tasks.md rename to template/openspec/schemas/intent-driven/templates/tasks.md From 1390bc89c2300b7ff16c54a94902cf0f4cd48363 Mon Sep 17 00:00:00 2001 From: akarizo Date: Thu, 14 May 2026 09:47:59 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E5=8E=8B=E7=BC=A9=20CLAUDE.md=20sn?= =?UTF-8?q?ippet=20=E5=B9=B6=E5=9C=A8=20apply=20=E5=89=8D=E5=BC=BA?= =?UTF-8?q?=E5=88=B6=E8=AF=A2=E9=97=AE=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CLAUDE.md.snippet 从 58 行压到 35 行,丢掉 CLI 详细命令、artifact 长描述、 skills 清单(这些在 .claude/skills/ 自查),保留 5-artifact 流程 + 命令表 + git 纪律。同时在 /opsx-apply 和 /opsx-bulk-apply 行标注开始前会确认。 - opsx-apply 命令与 openspec-apply-change skill 在 step 5(show progress)和 原 step 6(implement loop)之间插入新 step 6 MANDATORY confirm,用 AskUserQuestion 给 3 个选项:确认开始 / 先看完整 tasks / 取消。 guardrail 增加"必须先确认"。bulk-apply 派发的子 agent 显式 skip 此步。 - opsx-bulk-apply 命令与 skill 在创建 worktree 前加批量级一次性确认, 避免每个 subagent 单独问;子 agent 跳过自己的 per-change 确认。 --- template/.claude/commands/opsx-apply.md | 28 +++++++- template/.claude/commands/opsx-bulk-apply.md | 21 +++++- .../skills/openspec-apply-change/SKILL.md | 28 +++++++- .../openspec-bulk-apply-change/SKILL.md | 27 ++++++-- template/CLAUDE.md.snippet | 67 ++++++------------- 5 files changed, 116 insertions(+), 55 deletions(-) diff --git a/template/.claude/commands/opsx-apply.md b/template/.claude/commands/opsx-apply.md index 16d2ef3..e1300dd 100644 --- a/template/.claude/commands/opsx-apply.md +++ b/template/.claude/commands/opsx-apply.md @@ -57,7 +57,30 @@ Implement tasks from an OpenSpec change. - Remaining tasks overview - Dynamic instruction from CLI -6. **Implement tasks (loop until done or blocked)** +6. **MANDATORY: confirm with user before implementation** + + Before touching any code, you MUST stop and ask the user. + + Show a short preview: + - Change name and schema + - Progress: "N/M tasks complete, K remaining" + - First 3 pending task titles (titles only, no implementation detail) + - High-level scope: which capabilities or files will be touched (one line) + + Then call the **AskUserQuestion tool** with: + - question: `确认开始 apply 吗?接下来会按 tasks 顺序写入代码。` + - header: `开始 apply` + - options: + - `确认开始` — proceed to step 7 (implementation loop) + - `先看完整 tasks` — print the full task list, then re-ask this question + - `取消` — stop immediately, do not change any file + + Guardrails: + - Do NOT enter the implementation loop without an explicit `确认开始` answer. + - If the user picks `取消`, exit and report no changes were made. + - Skip this step ONLY when invoked as a delegated subagent from `/opsx-bulk-apply` (the parent already collected one batch-level confirmation). + +7. **Implement tasks (loop until done or blocked)** For each pending task: - Show which task is being worked on @@ -72,7 +95,7 @@ Implement tasks from an OpenSpec change. - Error or blocker encountered → report and wait for guidance - User interrupts -7. **On completion or pause, show status** +8. **On completion or pause, show status** Display: - Tasks completed this session @@ -132,6 +155,7 @@ What would you like to do? ``` **Guardrails** +- Always pause for explicit user confirmation in step 6 before any code change (except delegated bulk-apply subagent runs) - Keep going through tasks until done or blocked - Always read context files before starting (from the apply instructions output) - If task is ambiguous, pause and ask before implementing diff --git a/template/.claude/commands/opsx-bulk-apply.md b/template/.claude/commands/opsx-bulk-apply.md index 1612271..cfca1f7 100644 --- a/template/.claude/commands/opsx-bulk-apply.md +++ b/template/.claude/commands/opsx-bulk-apply.md @@ -25,14 +25,31 @@ Apply multiple active OpenSpec changes concurrently. - If fewer than 2 active candidate changes remain, stop and tell the user to use `/opsx-apply `. - If 2 or more candidates remain, continue with `openspec-bulk-apply-change`. -3. **Follow the bulk apply skill exactly** +3. **MANDATORY: confirm batch with user before dispatch** + + Before creating any worktree or dispatching any subagent, you MUST stop and ask the user. + + Show: + - Change list to be applied (names only) + - Worktree root that will be used (default `.worktrees/`) + + Call the **AskUserQuestion tool** with: + - question: `确认并行 apply 这 N 个变更吗?将创建独立 worktree 并派发子 agent。` + - header: `开始 bulk apply` + - options: + - `确认开始` — proceed to step 4 + - `取消` — abort, no worktree or subagent created + + The batch-level confirmation is collected ONCE here. Each dispatched subagent inherits this approval and skips its own per-change confirmation. + +4. **Follow the bulk apply skill exactly** The skill must: - Run OpenSpec git discipline checks before apply. - Create isolated worktrees under `.worktrees/` unless another root is requested. - Dispatch one subagent per change. - - Run `/opsx-apply ` and `/opsx-verify ` in each subagent. + - Run `/opsx-apply ` and `/opsx-verify ` in each subagent. Subagents MUST skip the per-change confirmation step (batch already approved). - Collect normalized apply and verify reports. - Report results without merging or archiving. diff --git a/template/.claude/skills/openspec-apply-change/SKILL.md b/template/.claude/skills/openspec-apply-change/SKILL.md index 86c881d..49e1c61 100644 --- a/template/.claude/skills/openspec-apply-change/SKILL.md +++ b/template/.claude/skills/openspec-apply-change/SKILL.md @@ -64,7 +64,30 @@ Implement tasks from an OpenSpec change. - Remaining tasks overview - Dynamic instruction from CLI -6. **Implement tasks (loop until done or blocked)** +6. **MANDATORY: confirm with user before implementation** + + Before touching any code, you MUST stop and ask the user. + + Show a short preview: + - Change name and schema + - Progress: "N/M tasks complete, K remaining" + - First 3 pending task titles (titles only) + - High-level scope: which capabilities or files will be touched (one line) + + Then call the **AskUserQuestion tool** with: + - question: `确认开始 apply 吗?接下来会按 tasks 顺序写入代码。` + - header: `开始 apply` + - options: + - `确认开始` — proceed to step 7 (implementation loop) + - `先看完整 tasks` — print the full task list, then re-ask this question + - `取消` — stop immediately, do not change any file + + Guardrails: + - Do NOT enter the implementation loop without an explicit `确认开始` answer. + - If the user picks `取消`, exit and report no changes were made. + - Skip this step ONLY when invoked as a delegated subagent from a bulk-apply parent (the parent already collected one batch-level confirmation). + +7. **Implement tasks (loop until done or blocked)** For each pending task: - Show which task is being worked on @@ -79,7 +102,7 @@ Implement tasks from an OpenSpec change. - Error or blocker encountered → report and wait for guidance - User interrupts -7. **On completion or pause, show status** +8. **On completion or pause, show status** Display: - Tasks completed this session @@ -139,6 +162,7 @@ What would you like to do? ``` **Guardrails** +- Always pause for explicit user confirmation in step 6 before any code change (except delegated bulk-apply subagent runs) - Keep going through tasks until done or blocked - Always read context files before starting (from the apply instructions output) - If task is ambiguous, pause and ask before implementing diff --git a/template/.claude/skills/openspec-bulk-apply-change/SKILL.md b/template/.claude/skills/openspec-bulk-apply-change/SKILL.md index f381be5..194c9c1 100644 --- a/template/.claude/skills/openspec-bulk-apply-change/SKILL.md +++ b/template/.claude/skills/openspec-bulk-apply-change/SKILL.md @@ -64,7 +64,24 @@ Do not use bulk mode when only one candidate change remains. Stop and tell the u - Note the implementation scope needed by the delegated apply flow. - Exclude blocked or all-done changes from execution and include them in the final report. -4. **Create isolated worktrees** +4. **MANDATORY: confirm batch with user before dispatch** + + Before creating any worktree or dispatching any subagent, you MUST stop and ask the user. + + Show: + - Change list to be applied (names only) + - Worktree root that will be used (default `.worktrees/`) + + Call the **AskUserQuestion tool** with: + - question: `确认并行 apply 这 N 个变更吗?将创建独立 worktree 并派发子 agent。` + - header: `开始 bulk apply` + - options: + - `确认开始` — proceed to step 5 + - `取消` — abort, no worktree or subagent created + + The batch-level confirmation is collected ONCE here. Each dispatched subagent inherits this approval and MUST skip its own per-change confirmation in `openspec-apply-change` step 6. + +5. **Create isolated worktrees** For each executable candidate change: @@ -72,7 +89,7 @@ Do not use bulk mode when only one candidate change remains. Stop and tell the u - Keep the parent agent out of direct implementation work in the main workspace. - Do not create commits, branches, or merges unless the user explicitly approved them. -5. **Dispatch subagents in parallel** +6. **Dispatch subagents in parallel** For each executable candidate change: @@ -89,8 +106,9 @@ Do not use bulk mode when only one candidate change remains. Stop and tell the u - Stop after verification. - Do not merge, archive, or commit unless explicitly instructed by the parent prompt. - Return implementation outcome, verification status, changed files, blockers, and unresolved warnings. + - Skip the `openspec-apply-change` step 6 per-change confirmation (batch was already approved by the parent in step 4). -6. **Collect and normalize reports** +7. **Collect and normalize reports** For each executed change, capture: @@ -100,7 +118,7 @@ Do not use bulk mode when only one candidate change remains. Stop and tell the u - Files changed summary - Blockers or unresolved warnings -7. **Report back without merging** +8. **Report back without merging** Present a final bulk-apply report: @@ -138,6 +156,7 @@ Do not use bulk mode when only one candidate change remains. Stop and tell the u ## Guardrails +- Always pause for explicit user confirmation in step 4 before creating worktrees or dispatching subagents. - Do not auto-merge. - Do not auto-archive. - Do not bulk-apply when only one candidate change remains. diff --git a/template/CLAUDE.md.snippet b/template/CLAUDE.md.snippet index 55465ea..b5e4756 100644 --- a/template/CLAUDE.md.snippet +++ b/template/CLAUDE.md.snippet @@ -1,58 +1,35 @@ ## Intent-Driven 工作流 -本项目采用 intent-driven 规约驱动开发。每个变更按 5 个 artifact 顺序流转, -后续 artifact 必须建立在前置 artifact 之上: +5 个 artifact 顺序流转,后者依赖前者: +`proposal → specs → design → adr → tasks` -``` -proposal → specs → design → adr → tasks -``` - -- **proposal**:陈述"为什么要做",列出会创建或修改的 capabilities -- **specs**:用 Gherkin 风格(`GIVEN / WHEN / THEN`)描述可观测行为 -- **design**:技术方案、关键决策、权衡、迁移计划 -- **adr**:长期架构决策,写入仓库根的 `adr/`,**不可改**(需要变更则新建 ADR 并 supersede 旧的) -- **tasks**:可勾选的实现清单,按依赖排序 +- **proposal** 为什么做 / **specs** Gherkin 行为 / **design** 方案权衡 +- **adr** 长期决策(写入 `adr/`,不可改,需变更则 supersede 旧版) +- **tasks** 可勾选清单,按依赖排序 ### Slash 命令 | 命令 | 用途 | | --- | --- | -| `/opsx-new ` | 新建变更,仅展示第一个 artifact 模板,等用户确认 | -| `/opsx-propose ` | 一次性生成 apply 所需的全部 artifacts | -| `/opsx-continue [name]` | 继续推进当前变更的下一个 artifact | -| `/opsx-apply [name]` | 按 tasks 执行实现,逐条勾选 | -| `/opsx-verify [name]` | 核对实现与 specs/design 的一致性,输出三维报告 | -| `/opsx-archive [name]` | 归档已完成变更(必须先合回 `main`) | -| `/opsx-sync [name]` | 把 delta specs 合并到主 specs | -| `/opsx-explore [topic]` | 探索模式:只思考、不实现 | -| `/opsx-bulk-apply` | 多变更并行 worktree 实现 | - -### Git 纪律(关键) - -- **propose → apply**:proposal artifacts 必须先合入 `main`,apply 才能开始 -- **apply → archive**:implementation 必须先合回 `main`,archive 才能开始 -- 不会代你 commit / branch / merge,除非你显式要求 -- 完整规则见 `.claude/skills/openspec-git-discipline/SKILL.md` +| `/opsx-new ` | 新建变更,逐 artifact 推进 | +| `/opsx-propose ` | 一次生成 apply 所需全部 artifacts | +| `/opsx-continue [name]` | 推进下一个 artifact | +| `/opsx-apply [name]` | 执行 tasks(**开始前会停下询问确认**) | +| `/opsx-verify [name]` | 核对实现与 specs/design 一致性 | +| `/opsx-archive [name]` | 归档(需先合回 `main`) | +| `/opsx-sync [name]` | 把 delta specs 合到主 specs | +| `/opsx-explore [topic]` | 探索模式,只思考不写代码 | +| `/opsx-bulk-apply` | 多变更并行 worktree 实现(**开始前会停下询问确认**) | + +### Git 纪律 + +- `propose → apply`:proposal 必须先合入 `main` +- `apply → archive`:implementation 必须先合回 `main` +- 不会代你 commit / branch / merge +- 详见 `.claude/skills/openspec-git-discipline/` ### Schema -当前激活:`intent-driven`(见 `openspec/config.yaml`)。 -本仓库内嵌 schema 副本:`openspec/schemas/intent-driven/`,离线可验证。 - -```bash -openspec list # 列出所有变更 -openspec status --change # 查看某变更的 artifact 状态 -openspec schema validate intent-driven # 验证 schema -``` - -### 配套 skills - -`.claude/skills/` 内置: -- `architectural-decision-records` —— ADR 5 种模板(Nygard / MADR / Y-statement / 自定义) -- `c4-diagrams` —— C4 架构图(ASCII / Mermaid) -- `gherkin-authoring` —— Gherkin 行为规约最佳实践 -- `grill-me` —— 设计追问,逐分支澄清决策 -- `openspec-git-discipline` —— git 流转关卡 -- 9 个 `openspec-*` —— 对应 `/opsx-*` 命令的执行细节 +当前 `intent-driven`(`openspec/config.yaml`),副本在 `openspec/schemas/intent-driven/`。配套 skills 见 `.claude/skills/`。