Skip to content

5.4 OpenSpec + Cursor 工作流

概述

Cursor 是一款基于 VS Code 的 AI 编程 IDE,以其强大的代码补全和智能编辑能力著称。本章将详细介绍如何在 Cursor 中使用 OpenSpec 进行规格驱动开发。

Cursor 与 OpenSpec 的集成

集成架构

┌───────────────────────────────────────────────────────────┐
│                        Cursor IDE                          │
├───────────────────────────────────────────────────────────┤
│                                                            │
│  ┌─────────────────────────────────────────────────────┐  │
│  │  .cursor/prompts/openspec/                          │  │
│  │  ├── openspec-proposal.md  → 创建变更提案            │  │
│  │  ├── openspec-apply.md     → 实现变更               │  │
│  │  └── openspec-archive.md   → 归档变更               │  │
│  └─────────────────────────────────────────────────────┘  │
│                           +                                │
│  ┌─────────────────────────────────────────────────────┐  │
│  │  .cursorrules                                       │  │
│  │  全局 AI 行为配置,包含 OpenSpec 工作流指令           │  │
│  └─────────────────────────────────────────────────────┘  │
│                           ↓                                │
│  ┌─────────────────────────────────────────────────────┐  │
│  │  Cursor AI (Claude/GPT) 执行 OpenSpec 工作流         │  │
│  └─────────────────────────────────────────────────────┘  │
│                                                            │
└───────────────────────────────────────────────────────────┘

命令格式

命令功能触发方式
/openspec-proposal创建变更提案Cmd+K 或 Chat
/openspec-apply实现变更Cmd+K 或 Chat
/openspec-archive归档变更Cmd+K 或 Chat

配置 Cursor 集成

方式 1:通过 OpenSpec 初始化

bash
cd my-project
openspec init
# 选择 Cursor 作为 AI 工具

这会自动创建以下文件结构:

.cursor/
└── prompts/
    └── openspec/
        ├── openspec-proposal.md
        ├── openspec-apply.md
        └── openspec-archive.md

方式 2:手动配置

bash
# 创建目录
mkdir -p .cursor/prompts/openspec

# 运行更新以生成 Cursor 配置
openspec update

配置 .cursorrules

创建 .cursorrules 文件以增强 AI 行为:

markdown
# Cursor Rules for OpenSpec Project

## OpenSpec Workflow
This project uses OpenSpec for spec-driven development.

### Before Any Feature Work
1. Check existing specs: `openspec list --specs`
2. Check active changes: `openspec list`
3. Review project conventions: `openspec/project.md`

### Creating Changes
Use `/openspec-proposal` command or natural language.

### Implementing Changes
Use `/openspec-apply [change-id]` command.

### Spec Format Requirements
- Requirements: `### Requirement:` (3 hashtags)
- Scenarios: `#### Scenario:` (4 hashtags)
- Keywords: **WHEN/THEN/AND/GIVEN** in bold

### Code Conventions
- Follow TypeScript strict mode
- Use async/await for async operations
- Add error handling for all API calls

Cursor 特有功能

1. Composer 模式 (Cmd+I)

Composer 模式适合创建和实现 OpenSpec 变更:

[Cmd+I 打开 Composer]

输入: 创建 OpenSpec 提案,添加用户通知功能

Cursor 响应:
正在分析项目...
发现现有规格: user, product, order

创建变更提案 add-notifications:
┌─ proposal.md ─────────────────────┐
│ ## Why                            │
│ 用户需要实时了解订单状态变化...     │
└───────────────────────────────────┘

┌─ tasks.md ────────────────────────┐
│ ## 1. Backend                     │
│ - [ ] 1.1 创建 Notification 模型  │
│ ...                               │
└───────────────────────────────────┘

[Apply] [Edit] [Cancel]

2. 内联编辑 (Cmd+K)

选中规格后快速生成代码或测试:

[选中 spec.md 中的 Requirement]

[Cmd+K] 输入: 根据这个需求生成测试代码

Cursor 生成测试:
describe('User Login', () => {
  it('should return JWT on valid credentials', async () => {
    const response = await request(app)
      .post('/api/auth/login')
      .send({ email: 'test@example.com', password: 'valid' });

    expect(response.status).toBe(200);
    expect(response.body).toHaveProperty('token');
  });
});

3. 上下文引用 (@符号)

Chat: @openspec/specs/auth/spec.md 需要添加 OAuth 登录

Cursor: 我已阅读 auth 规格。建议创建变更提案:

openspec/changes/add-oauth/
├── proposal.md
├── tasks.md
└── specs/auth/spec.md  # Delta

需要我创建吗?

4. 多文件编辑

Chat: 根据 add-2fa 提案实现所有代码

Cursor 响应:
我将修改以下文件:

1. src/models/User.ts
   + otpSecret: string
   + otpEnabled: boolean

2. src/routes/auth.ts
   + POST /auth/2fa/enable
   + POST /auth/2fa/verify

3. src/services/OtpService.ts
   [新文件]

[显示 diff 预览]
[Apply All] [Review Each]

完整工作流演示

场景:为博客系统添加评论功能

Step 1: 创建提案

[Cmd+I 打开 Composer]

输入: /openspec-proposal 为博客文章添加评论功能

Cursor:
正在创建变更提案 add-comments...

已创建:
openspec/changes/add-comments/
├── proposal.md
├── tasks.md
└── specs/
    └── comments/
        └── spec.md

生成的 proposal.md:

markdown
## Why
博客文章需要评论功能以促进读者互动和讨论。

## What Changes
- 添加评论数据模型
- 实现评论 CRUD API
- 添加评论 UI 组件
- 支持嵌套回复

## Impact
- **New spec**: comments
- **Related specs**: post, user
- **Breaking changes**: None

生成的 spec.md:

markdown
# Comments Specification

## Purpose
Enable readers to comment on blog posts.

## Requirements

### Requirement: Add Comment
The system SHALL allow authenticated users to add comments.

#### Scenario: Add top-level comment
- **GIVEN** user is logged in
- **WHEN** user submits comment on a post
- **THEN** comment is saved
- **AND** displayed under the post
- **AND** author is notified

#### Scenario: Reply to comment
- **GIVEN** user is logged in
- **WHEN** user replies to existing comment
- **THEN** reply is nested under parent
- **AND** parent author is notified

### Requirement: Edit Comment
The system SHALL allow users to edit their own comments.

#### Scenario: Edit within time limit
- **GIVEN** comment was posted within 15 minutes
- **WHEN** author edits comment
- **THEN** content is updated
- **AND** "edited" label is shown

#### Scenario: Edit after time limit
- **GIVEN** comment was posted over 15 minutes ago
- **WHEN** author tries to edit
- **THEN** edit is rejected
- **AND** error message is shown

### Requirement: Delete Comment
The system SHALL allow comment deletion.

#### Scenario: Author deletes comment
- **WHEN** author deletes their comment
- **THEN** comment content shows "[deleted]"
- **AND** replies are preserved

#### Scenario: Admin deletes comment
- **GIVEN** user is admin
- **WHEN** admin deletes any comment
- **THEN** comment is removed
- **AND** action is logged

Step 2: 审核和完善

Chat: @openspec/changes/add-comments/specs/comments/spec.md
      需要添加评论审核功能

Cursor: 我将添加审核需求到规格中:

### Requirement: Comment Moderation
The system SHALL support comment moderation.

#### Scenario: Flag inappropriate comment
- **WHEN** user flags a comment
- **THEN** comment is queued for review
- **AND** admin is notified

#### Scenario: Approve flagged comment
- **GIVEN** comment is flagged
- **WHEN** admin approves it
- **THEN** flag is removed
- **AND** comment remains visible

#### Scenario: Remove flagged comment
- **GIVEN** comment is flagged
- **WHEN** admin removes it
- **THEN** comment is deleted
- **AND** author receives warning

[Apply changes?]

Step 3: 验证规格

bash
# 在终端运行
openspec validate add-comments --strict

或在 Cursor 中:

Chat: 验证 add-comments 变更规格

Cursor: [执行 openspec validate add-comments --strict]

✓ 验证通过
- 4 个需求
- 10 个场景
- 格式正确

Step 4: 实现变更

[Cmd+I 打开 Composer]

输入: /openspec-apply add-comments

Cursor:
读取变更提案...

任务列表:
1. [ ] 创建 Comment 模型
2. [ ] 创建评论 API
3. [ ] 添加评论组件
4. [ ] 实现嵌套回复
5. [ ] 添加审核功能
6. [ ] 编写测试

开始实现任务 1: 创建 Comment 模型

生成的代码示例:

typescript
// src/models/Comment.ts
import { prisma } from '../lib/prisma';

export interface Comment {
  id: string;
  postId: string;
  authorId: string;
  parentId: string | null;
  content: string;
  createdAt: Date;
  updatedAt: Date;
  isEdited: boolean;
  isDeleted: boolean;
}

export async function createComment(
  postId: string,
  authorId: string,
  content: string,
  parentId?: string
): Promise<Comment> {
  return prisma.comment.create({
    data: {
      postId,
      authorId,
      content,
      parentId: parentId || null,
    },
  });
}

export async function getCommentsByPost(
  postId: string
): Promise<Comment[]> {
  return prisma.comment.findMany({
    where: { postId, isDeleted: false },
    include: {
      author: { select: { id: true, name: true, avatar: true } },
      replies: {
        where: { isDeleted: false },
        include: { author: { select: { id: true, name: true, avatar: true } } },
      },
    },
    orderBy: { createdAt: 'desc' },
  });
}

export async function updateComment(
  commentId: string,
  authorId: string,
  content: string
): Promise<Comment | null> {
  const comment = await prisma.comment.findUnique({
    where: { id: commentId },
  });

  if (!comment || comment.authorId !== authorId) {
    return null;
  }

  // Check 15-minute edit window
  const fifteenMinutesAgo = new Date(Date.now() - 15 * 60 * 1000);
  if (comment.createdAt < fifteenMinutesAgo) {
    throw new Error('EDIT_WINDOW_EXPIRED');
  }

  return prisma.comment.update({
    where: { id: commentId },
    data: { content, isEdited: true, updatedAt: new Date() },
  });
}

export async function deleteComment(
  commentId: string,
  userId: string,
  isAdmin: boolean
): Promise<void> {
  const comment = await prisma.comment.findUnique({
    where: { id: commentId },
  });

  if (!comment) {
    throw new Error('COMMENT_NOT_FOUND');
  }

  if (comment.authorId !== userId && !isAdmin) {
    throw new Error('UNAUTHORIZED');
  }

  if (isAdmin) {
    // Admin: hard delete
    await prisma.comment.delete({ where: { id: commentId } });
  } else {
    // Author: soft delete
    await prisma.comment.update({
      where: { id: commentId },
      data: { isDeleted: true, content: '[deleted]' },
    });
  }
}

Step 5: 归档变更

Chat: 评论功能已完成并部署,归档变更

Cursor: [执行 openspec archive add-comments --yes]

✓ 归档完成
- 规格已合并到 openspec/specs/comments/
- 变更已移至 archive/2024-12-05-add-comments/

Cursor 高级技巧

1. 使用 Tab 补全

在编写规格时,Cursor 会根据上下文提供补全建议:

markdown
### Requirement: Password Re[Tab]
→ ### Requirement: Password Reset

#### Scenario: [Tab]
→ #### Scenario: Successful reset

2. 规格到代码的快速转换

[选中整个 spec.md]

[Cmd+K] 输入: 根据这些规格生成完整的 API 路由代码

Cursor: 生成 routes/comments.ts...

3. 批量更新任务状态

Chat: 标记 add-comments 的任务 1-3 为完成

Cursor: 更新 tasks.md:
- [x] 1.1 创建 Comment 模型
- [x] 1.2 创建 CommentReply 关联
- [x] 2.1 GET /api/posts/:id/comments
- [x] 2.2 POST /api/posts/:id/comments
- [x] 2.3 PUT /api/comments/:id
- [x] 2.4 DELETE /api/comments/:id
- [ ] 3.1 CommentList 组件
...

4. 与 Git 集成

Chat: 为 add-comments 变更创建功能分支并提交提案

Cursor: 执行:
1. git checkout -b feature/add-comments
2. git add openspec/changes/add-comments/
3. git commit -m "spec: add comments feature proposal"

完成!当前在 feature/add-comments 分支。

常见问题

问题 1: 命令不识别

解决: 确保 .cursor/prompts/openspec/ 目录存在,重启 Cursor。

问题 2: 规格格式错误

解决: 使用 Cursor 的 lint 功能或运行 openspec validate --strict

问题 3: 多人协作冲突

解决: 使用 Git 分支,每个变更对应一个分支:

bash
git checkout -b feature/add-comments
# 工作...
git merge main

本章小结

Cursor 与 OpenSpec 的集成提供了流畅的开发体验:

  1. Composer 模式:适合创建完整的变更提案
  2. 内联编辑:快速生成代码和测试
  3. 多文件编辑:一次性修改多个相关文件
  4. 上下文引用:@ 符号引用规格文件

完整示例代码

以下是 Cursor + OpenSpec 的完整配置和工作流脚本:

bash
#!/bin/bash
# Cursor + OpenSpec 配置和演示脚本

set -e

GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'

log() { echo -e "${BLUE}[Cursor+OpenSpec]${NC} $1"; }
success() { echo -e "${GREEN}[✓]${NC} $1"; }

# 项目设置
PROJECT_DIR="cursor-openspec-demo"
log "创建演示项目: $PROJECT_DIR"
rm -rf "$PROJECT_DIR"
mkdir -p "$PROJECT_DIR"
cd "$PROJECT_DIR"

# 初始化
git init -q

# ============================================
# 1. OpenSpec 初始化
# ============================================
log "初始化 OpenSpec..."

mkdir -p openspec/{specs,changes/archive}
mkdir -p .cursor/prompts/openspec

# 项目配置
cat > openspec/project.md << 'EOF'
# Project Context

## Overview
Blog platform with comments system.

## Tech Stack
- TypeScript + Node.js
- Express + Prisma
- React + TailwindCSS

## Conventions
- RESTful API design
- Async/await for all async code
- Comprehensive error handling
EOF

# AGENTS.md
cat > openspec/AGENTS.md << 'EOF'
# OpenSpec Instructions

## Workflow
1. Create proposal with `/openspec-proposal`
2. Implement with `/openspec-apply`
3. Archive with `/openspec-archive`

## Spec Format
- `### Requirement:` for requirements
- `#### Scenario:` for scenarios
- **WHEN/THEN/AND** keywords
EOF

cat > AGENTS.md << 'EOF'
<!-- OPENSPEC:START -->
This project uses OpenSpec. See `openspec/AGENTS.md`.
<!-- OPENSPEC:END -->
EOF

success "OpenSpec 已初始化"

# ============================================
# 2. Cursor 命令配置
# ============================================
log "配置 Cursor 命令..."

# proposal 命令
cat > .cursor/prompts/openspec/openspec-proposal.md << 'EOF'
# OpenSpec Proposal

Create a new OpenSpec change proposal based on the user's request.

## Instructions
1. Run `openspec list --specs` to see existing specs
2. Create change directory: `openspec/changes/<change-id>/`
3. Generate:
   - proposal.md (Why, What Changes, Impact)
   - tasks.md (Implementation checklist)
   - specs/<capability>/spec.md (Delta specs)

## Format
- Change ID: kebab-case, verb-led
- Requirements: `### Requirement:` (3 #)
- Scenarios: `#### Scenario:` (4 #)
- Keywords: **WHEN/THEN/AND/GIVEN**

User request: {input}
EOF

# apply 命令
cat > .cursor/prompts/openspec/openspec-apply.md << 'EOF'
# OpenSpec Apply

Implement an OpenSpec change.

## Instructions
1. Read proposal.md and tasks.md
2. Execute tasks in order
3. Mark completed: `- [x]`
4. Follow project conventions

Change ID: {input}
EOF

# archive 命令
cat > .cursor/prompts/openspec/openspec-archive.md << 'EOF'
# OpenSpec Archive

Archive a completed change.

## Instructions
1. Verify all tasks are complete
2. Run: `openspec archive {input} --yes`
3. Commit changes

Change ID: {input}
EOF

success "Cursor 命令已配置"

# ============================================
# 3. .cursorrules 配置
# ============================================
log "创建 .cursorrules..."

cat > .cursorrules << 'EOF'
# Cursor Rules for OpenSpec Project

## OpenSpec Integration
This project uses OpenSpec for spec-driven development.

### Available Commands
- `/openspec-proposal` - Create change proposal
- `/openspec-apply` - Implement change
- `/openspec-archive` - Archive completed change

### Before Starting Work
1. Check `openspec list` for active changes
2. Check `openspec list --specs` for existing specs
3. Read `openspec/project.md` for conventions

### Spec Format (CRITICAL)
- Requirements: `### Requirement: Name` (exactly 3 hashtags)
- Scenarios: `#### Scenario: Name` (exactly 4 hashtags)
- Keywords in bold: **WHEN**, **THEN**, **AND**, **GIVEN**

### Code Conventions
- TypeScript strict mode
- Async/await (no .then chains)
- Comprehensive error handling
- JSDoc for public APIs

### File Locations
- Specs: openspec/specs/
- Changes: openspec/changes/
- Project context: openspec/project.md
EOF

success ".cursorrules 已创建"

# ============================================
# 4. 创建示例规格
# ============================================
log "创建示例规格..."

mkdir -p openspec/specs/{post,user}

cat > openspec/specs/post/spec.md << 'EOF'
# Post Specification

## Purpose
Manage blog posts.

## Requirements

### Requirement: Create Post
The system SHALL allow authors to create posts.

#### Scenario: Create draft
- **GIVEN** user is logged in
- **WHEN** user creates a post
- **THEN** post is saved as draft
- **AND** preview is available

### Requirement: Publish Post
The system SHALL allow publishing posts.

#### Scenario: Publish draft
- **GIVEN** post is in draft status
- **WHEN** author publishes post
- **THEN** post becomes public
- **AND** RSS feed is updated
EOF

cat > openspec/specs/user/spec.md << 'EOF'
# User Specification

## Purpose
Handle user accounts.

## Requirements

### Requirement: User Registration
The system SHALL allow registration.

#### Scenario: Register with email
- **WHEN** user submits valid email and password
- **THEN** account is created
- **AND** verification email is sent
EOF

success "示例规格已创建"

# ============================================
# 5. 创建评论变更提案
# ============================================
log "创建评论变更提案..."

CHANGE_ID="add-comments"
mkdir -p "openspec/changes/$CHANGE_ID/specs/comments"

cat > "openspec/changes/$CHANGE_ID/proposal.md" << 'EOF'
## Why
博客需要评论功能以促进读者互动。

## What Changes
- 新增评论数据模型
- 实现评论 CRUD API
- 支持嵌套回复

## Impact
- **New spec**: comments
- **Related**: post, user
- **Breaking**: None
EOF

cat > "openspec/changes/$CHANGE_ID/tasks.md" << 'EOF'
# Tasks: Add Comments

## 1. Database
- [ ] 1.1 Create Comment model (Prisma)
- [ ] 1.2 Run migration

## 2. API
- [ ] 2.1 GET /api/posts/:id/comments
- [ ] 2.2 POST /api/posts/:id/comments
- [ ] 2.3 PUT /api/comments/:id
- [ ] 2.4 DELETE /api/comments/:id

## 3. Frontend
- [ ] 3.1 CommentList component
- [ ] 3.2 CommentForm component
- [ ] 3.3 ReplyThread component

## 4. Testing
- [ ] 4.1 API unit tests
- [ ] 4.2 Integration tests
EOF

cat > "openspec/changes/$CHANGE_ID/specs/comments/spec.md" << 'EOF'
# Comments Specification

## Purpose
Enable readers to comment on blog posts.

## Requirements

### Requirement: Add Comment
The system SHALL allow authenticated users to add comments.

#### Scenario: Add top-level comment
- **GIVEN** user is logged in
- **WHEN** user submits comment on post
- **THEN** comment is saved and displayed

#### Scenario: Reply to comment
- **GIVEN** user is logged in
- **WHEN** user replies to existing comment
- **THEN** reply is nested under parent

### Requirement: Edit Comment
The system SHALL allow users to edit own comments within 15 minutes.

#### Scenario: Edit within time limit
- **GIVEN** comment was posted within 15 minutes
- **WHEN** author edits comment
- **THEN** content is updated with "edited" label

#### Scenario: Edit after time limit
- **GIVEN** comment was posted over 15 minutes ago
- **WHEN** author tries to edit
- **THEN** edit is rejected with error

### Requirement: Delete Comment
The system SHALL allow comment deletion.

#### Scenario: Author soft-deletes
- **WHEN** author deletes their comment
- **THEN** content shows "[deleted]"
- **AND** replies are preserved

#### Scenario: Admin hard-deletes
- **GIVEN** user is admin
- **WHEN** admin deletes comment
- **THEN** comment is removed completely
EOF

success "评论变更提案已创建"

# ============================================
# 6. 验证
# ============================================
log "验证变更..."

if command -v openspec &> /dev/null; then
    openspec validate "$CHANGE_ID" --strict 2>/dev/null || echo "验证完成"
else
    echo "(openspec 未安装,跳过验证)"
fi

# ============================================
# 7. 显示结构
# ============================================
echo ""
echo "========================================"
echo "  Cursor + OpenSpec 配置完成!"
echo "========================================"
echo ""
echo "项目结构:"
find . -type f \( -name "*.md" -o -name ".cursorrules" \) | sort

echo ""
echo "使用方法:"
echo "1. 用 Cursor 打开项目: cursor $PROJECT_DIR"
echo "2. 创建提案: Cmd+I 输入 /openspec-proposal 你的功能描述"
echo "3. 实现变更: Cmd+I 输入 /openspec-apply add-comments"
echo "4. 归档: Cmd+I 输入 /openspec-archive add-comments"
echo ""
echo "快捷键:"
echo "- Cmd+I: 打开 Composer(多文件编辑)"
echo "- Cmd+K: 内联编辑"
echo "- @文件名: 引用文件上下文"

将此脚本保存为 cursor-openspec-setup.sh,然后执行:

bash
chmod +x cursor-openspec-setup.sh
./cursor-openspec-setup.sh

这个脚本会创建一个完整配置的 Cursor + OpenSpec 项目,包括:

  1. OpenSpec 目录结构和配置
  2. Cursor 斜杠命令模板
  3. .cursorrules 全局规则
  4. 示例规格和变更提案

用 Cursor 打开生成的项目目录即可开始使用 OpenSpec 工作流。

基于 MIT 许可证发布。内容版权归作者所有。