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 77% rename from .opencode/commands/opsx-apply.md rename to template/.claude/commands/opsx-apply.md index 16d2ef3..e1300dd 100644 --- a/.opencode/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/.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 68% rename from .opencode/commands/opsx-bulk-apply.md rename to template/.claude/commands/opsx-bulk-apply.md index 1612271..cfca1f7 100644 --- a/.opencode/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/.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 78% rename from .opencode/skills/openspec-apply-change/SKILL.md rename to template/.claude/skills/openspec-apply-change/SKILL.md index 86c881d..49e1c61 100644 --- a/.opencode/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/.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 83% rename from .opencode/skills/openspec-bulk-apply-change/SKILL.md rename to template/.claude/skills/openspec-bulk-apply-change/SKILL.md index f381be5..194c9c1 100644 --- a/.opencode/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/.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..b5e4756 --- /dev/null +++ b/template/CLAUDE.md.snippet @@ -0,0 +1,35 @@ + +## Intent-Driven 工作流 + +5 个 artifact 顺序流转,后者依赖前者: +`proposal → specs → design → adr → 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 必须先合入 `main` +- `apply → archive`:implementation 必须先合回 `main` +- 不会代你 commit / branch / merge +- 详见 `.claude/skills/openspec-git-discipline/` + +### Schema + +当前 `intent-driven`(`openspec/config.yaml`),副本在 `openspec/schemas/intent-driven/`。配套 skills 见 `.claude/skills/`。 + 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