Skip to content
Open
161 changes: 161 additions & 0 deletions openspec/changes/add-multi-editor-support/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
## Context

OpenSpec Part 1 establishes the SkillDefinition pattern for Claude Code. However, many developers use other AI code editors like Cursor, Windsurf, and Cline. Each has its own configuration format for AI instructions. We need a unified approach to generate equivalent configurations for all supported editors.

## Goals / Non-Goals

**Goals:**
- Detect existing editor configurations automatically
- Pre-select detected editors during init
- Generate equivalent instruction files for all selected editors
- Use adapter pattern for easy addition of new editors
- Smart recommendations based on project state

**Non-Goals:**
- Supporting every AI editor (focus on popular ones)
- Runtime editor switching (generation-time only)
- Editor-specific features that don't map across editors
- Automatic detection of which editor user is currently using

## Decisions

### 1. Detection Approach

**Decision**: Scan for known directory markers at init time.

```typescript
interface DetectionResult {
editors: {
claudeCode: boolean; // .claude/ exists
cursor: boolean; // .cursor/ exists
windsurf: boolean; // .windsurf/ exists
cline: boolean; // .cline/ exists
};
openspecState: 'uninitialized' | 'old' | 'new' | 'mixed';
}

function detectEditorConfigs(projectPath: string): DetectionResult
```

**Rationale**: Simple, fast, no false positives. Directory existence is a reliable signal.

**Alternative considered**: Parse editor config files to confirm they're actually configured. Rejected - adds complexity, directories are sufficient signal.

### 2. Editor Adapter Interface

**Decision**: Use adapter pattern for editor-specific generation.

```typescript
interface EditorAdapter {
id: string; // "claude-code", "cursor", "windsurf", "cline"
name: string; // "Claude Code", "Cursor", etc.
configDir: string; // ".claude", ".cursor", etc.

generateSkills(skills: SkillDefinition[], outputDir: string): void;
generateCommands(skills: SkillDefinition[], outputDir: string): void;
}

const ADAPTERS: EditorAdapter[] = [
new ClaudeCodeAdapter(),
new CursorAdapter(),
new WindsurfAdapter(),
new ClineAdapter(),
];
```

**Rationale**: Encapsulates editor-specific logic. Adding a new editor = adding one adapter class.

### 3. Editor-Specific Formats

**Claude Code:**
- Skills: `.claude/skills/openspec-*/SKILL.md`
- Commands: `.claude/commands/opsx/*.md`

**Cursor:**
- Rules: `.cursor/rules/openspec-*.mdc` (MDC format)
- All skills combined into rule files with frontmatter

**Windsurf:**
- Rules: `.windsurf/rules/openspec-*.md`
- Similar to Cursor but standard markdown

**Cline:**
- Rules: `.cline/rules/openspec-*.md`
- Standard markdown format

Comment on lines +82 to +85
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Capitalize “Markdown”.

Use the proper noun capitalization in that sentence.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~103-~103: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ....cline/rules/openspec-*.md - Standard markdown format Rationale: Each editor has ...

(MARKDOWN_NNP)

🤖 Prompt for AI Agents
In `@openspec/changes/add-multi-editor-support/design.md` around lines 101 - 104,
The sentence under "**Cline:**" that reads "- Standard markdown format" should
use the proper noun capitalization by changing "markdown" to "Markdown"; update
the text in the design.md entry (the line containing "Standard markdown format")
to read "Standard Markdown format" so the noun is capitalized correctly.

**Rationale**: Each editor has documented conventions. We follow them.

### 4. Smart Init Flow

**Decision**: Detection → Summary → Selection → Generation

```
$ openspec init

Detecting project configuration...

Found:
Editors: Claude Code, Cursor
OpenSpec: Old system (AGENTS.md exists)

Recommendation: Migrate to new skills-based system

Select editors to configure: (detected editors pre-selected)
[x] Claude Code
[x] Cursor
[ ] Windsurf
[ ] Cline

Generating files for Claude Code...
Created .claude/skills/openspec-*/ (9 skills)
Created .claude/commands/opsx/* (9 commands)

Generating files for Cursor...
Created .cursor/rules/openspec-*.mdc (9 rules)

Done! Run `openspec cleanup` to remove old artifacts.
```
Comment on lines +92 to +117
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a fenced code language tag.

The block should specify a language (e.g., text) to satisfy markdownlint.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

111-111: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@openspec/changes/add-multi-editor-support/design.md` around lines 111 - 136,
The fenced code block in design.md around the sample output from "$ openspec
init" lacks a language tag and triggers markdownlint; update the triple-backtick
opening fence to include a language like "text" (i.e., change ``` to ```text)
for the block that starts with "$ openspec init" so the example output is
properly labeled and lint-cleaned.


**Rationale**: Users see what's detected, can adjust, understand what's happening.

### 5. Content Equivalence

**Decision**: Same SkillDefinition content, different file format per editor.

All editors receive:
- Same skill names (openspec-new-change, etc.)
- Same instruction content
- Same invocation patterns documented

Format differs:
- Claude Code: SKILL.md + pointer commands
- Others: Combined rule files with metadata

**Rationale**: Consistent experience regardless of editor. Skills work the same way.

## Risks / Trade-offs

**[Risk] Editor formats may change**
→ Mitigation: Adapters isolate changes. Only one adapter needs updating per editor.

**[Risk] Some editors may not support skill references**
→ Mitigation: Adapters can include full instructions if needed (no pointer pattern).

**[Risk] Detection may have false positives (empty .cursor/ directory)**
→ Mitigation: Acceptable - pre-selection is a suggestion, user can deselect.

**[Trade-off] More complexity in generation code**
→ Acceptable: Adapter pattern keeps it manageable. Each adapter is self-contained.

## Migration Plan

This is Part 3 of 3:
- **Part 1**: Foundation - SkillDefinition pattern (required first)
- **Part 2**: Migration - Update/cleanup commands (can run in parallel)
- **Part 3 (this change)**: Multi-editor - Detection and adapters

## Open Questions

- Should we support custom adapters (user-defined editors)?
- How do we handle editor-specific features that don't map?
- Should detection also check for editor binaries in PATH?
32 changes: 32 additions & 0 deletions openspec/changes/add-multi-editor-support/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Why

After Parts 1 and 2 establish the skills-only architecture and migration path for Claude Code users, we need to expand support to other AI code editors. Many developers use Cursor, Windsurf, or Cline alongside or instead of Claude Code. Each editor has its own configuration format, but they can all benefit from OpenSpec's structured approach.

This is Part 3 of the skills-only migration, focusing on multi-editor support.

## What Changes

- **Smart init detection**: `openspec init` detects existing editor configs and OpenSpec state
- **Editor adapters**: Unified generation for Claude Code, Cursor, Windsurf, and Cline
- **Pre-selection**: Detected editors are pre-selected in the init wizard
- **State awareness**: Init recommends actions based on detected OpenSpec state (uninitialized, old system, new system, mixed)

## Capabilities

### New Capabilities
- `smart-init`: Enhanced initialization with editor detection and state-aware recommendations

### Modified Capabilities
- `skill-generation`: Multi-editor generation with adapter pattern

## Impact

- **Init flow**: Significant enhancement with detection and smart defaults
- **New editor formats**: Support for Cursor, Windsurf, Cline rule formats
- **User experience**: Better onboarding with pre-selected options
- **Future extensibility**: Adapter pattern allows adding more editors

## Dependencies

- Requires Part 1 (add-skill-foundation) to be completed first
Comment on lines +7 to +31
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add direct file/spec references for traceability.

Please add references like path/to/file.ts:42 and specs/.../spec.md where relevant to align with proposal formatting rules. As per coding guidelines, include direct file references for proposals.

🤖 Prompt for AI Agents
In `@openspec/changes/add-multi-editor-support/proposal.md` around lines 21 - 45,
Update the proposal sections ("What Changes", "Capabilities", "Impact",
"Dependencies") to include direct file and spec references for traceability:
insert concrete source-file references and spec links next to each listed
change/capability (for example add entries like `path/to/file.ts:LINE` and
`specs/.../spec.md` adjacent to the Smart init detection item and the editor
adapter bullets), ensure the `smart-init` capability mentions the initialization
entrypoint and config files it touches and ensure the `skill-generation`
modification points to the adapter implementations, and add a short mapping
table under "Dependencies" that lists the required Part 1 artifacts and their
spec files so reviewers can trace proposals to implementation.

- Can run in parallel with Part 2 (add-skill-migration) after Part 1 merges
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## ADDED Requirements

### Requirement: Multi-editor skill generation via adapters
The system SHALL use an adapter pattern to generate appropriate files for each supported editor.

Supported editors:
- Claude Code: `.claude/skills/` and `.claude/commands/opsx/`
- Cursor: `.cursor/rules/`
- Windsurf: `.windsurf/rules/`
- Cline: `.cline/rules/`

#### Scenario: Generate for Claude Code
- **WHEN** Claude Code is selected during generation
- **THEN** system creates .claude/skills/openspec-*/ directories with SKILL.md
- **AND** system creates .claude/commands/opsx/*.md pointer commands

#### Scenario: Generate for Cursor
- **WHEN** Cursor is selected during generation
- **THEN** system creates .cursor/rules/openspec-*.mdc rule files
- **AND** rule files contain equivalent skill instructions

#### Scenario: Generate for Windsurf
- **WHEN** Windsurf is selected during generation
- **THEN** system creates .windsurf/rules/openspec-*.md rule files
- **AND** rule files contain equivalent skill instructions

#### Scenario: Generate for Cline
- **WHEN** Cline is selected during generation
- **THEN** system creates .cline/rules/openspec-*.md rule files
- **AND** rule files contain equivalent skill instructions

### Requirement: Generate for multiple editors simultaneously
The system SHALL generate files for all selected editors in a single operation.

#### Scenario: Generate for multiple editors
- **WHEN** multiple editors are selected (e.g., Claude Code and Cursor)
- **THEN** system generates files for Claude Code
- **AND** system generates files for Cursor
- **AND** skill content is equivalent across editors

### Requirement: Editor adapters use cross-platform paths
Each editor adapter SHALL use path.join() for all file path construction.

#### Scenario: Multi-editor generation on Windows
- **WHEN** generation runs for multiple editors on Windows
- **THEN** all adapters create files with correct paths
- **AND** all files are accessible and valid

#### Scenario: Multi-editor generation on Unix-like systems
- **WHEN** generation runs for multiple editors on macOS or Linux
- **THEN** all adapters create files with correct paths
- **AND** all files are accessible and valid

### Requirement: Adapters transform content appropriately
Each editor adapter SHALL transform the SkillDefinition content into the editor's expected format.

#### Scenario: Content equivalence across editors
- **WHEN** skills are generated for multiple editors
- **THEN** all editors receive the same skill names
- **AND** all editors receive equivalent instruction content
- **AND** format differs per editor conventions (SKILL.md vs .mdc vs .md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
## ADDED Requirements

### Requirement: Init detects existing editor configurations
The system SHALL scan for existing editor configuration directories to inform setup recommendations. Detection targets:
- `.claude/` - Claude Code
- `.cursor/` - Cursor
- `.windsurf/` - Windsurf
- `.cline/` - Cline

#### Scenario: Detect Claude Code configuration
- **WHEN** user runs `openspec init` in a project with `.claude/` directory
- **THEN** system detects Claude Code as a configured editor
- **AND** system pre-selects Claude Code in the editor selection

#### Scenario: Detect multiple editor configurations
- **WHEN** user runs `openspec init` in a project with both `.claude/` and `.cursor/` directories
- **THEN** system detects both Claude Code and Cursor as configured editors
- **AND** system pre-selects both in the editor selection

#### Scenario: No editor configurations detected
- **WHEN** user runs `openspec init` in a project with no editor config directories
- **THEN** system shows all available editors without pre-selection
- **AND** system informs user that no existing editor configs were detected

Comment on lines +3 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a Windows path scenario for editor config detection.

These requirements deal with filesystem paths/directories but don’t include a Windows-specific scenario or cross-platform behavior callout. Please add a #### Scenario: that covers Windows path handling (e.g., detection on Windows with path.join/path.resolve semantics). As per coding guidelines.

🤖 Prompt for AI Agents
In `@openspec/changes/add-multi-editor-support/specs/smart-init/spec.md` around
lines 22 - 43, Add a new "Scenario: Detect editor configurations on Windows
paths" section under "Requirement: Init detects existing editor configurations"
that describes running `openspec init` in a project where editor config
directories exist using Windows-style paths (e.g., backslashes, drive letters)
and notes that detection should work with path.resolve/path.join semantics;
reference the command `openspec init`, the listed editor dirs (`.claude/`,
`.cursor/`, `.windsurf/`, `.cline/`), and state expected outcomes: detection of
editors, appropriate pre-selection, and that behavior matches POSIX detection
semantics on Windows.

### Requirement: Init detects existing OpenSpec state
The system SHALL detect the current OpenSpec setup state to provide appropriate recommendations:
- Not initialized: No `openspec/` directory
- Old system: `openspec/AGENTS.md` exists
- New system: `.claude/skills/openspec-*` exists
- Mixed: Both old and new artifacts present

#### Scenario: Detect uninitialized project
- **WHEN** user runs `openspec init` in a project without `openspec/` directory
- **THEN** system detects project as uninitialized
- **AND** system offers full initialization

#### Scenario: Detect old system
- **WHEN** user runs `openspec init` in a project with `openspec/AGENTS.md` but no skills
- **THEN** system detects old OpenSpec system
- **AND** system recommends migration to new skills-based system

#### Scenario: Detect new system already in place
- **WHEN** user runs `openspec init` in a project with `.claude/skills/openspec-*`
- **THEN** system detects new system is already set up
- **AND** system informs user that OpenSpec is already configured

#### Scenario: Detect mixed state (both old and new artifacts)
- **WHEN** user runs `openspec init` in a project with both `openspec/AGENTS.md` and `.claude/skills/openspec-*`
- **THEN** system detects mixed state
- **AND** system informs user that both old and new systems exist
- **AND** system recommends running `openspec cleanup` to remove old artifacts

### Requirement: Init shows detection results to user
The system SHALL display detection results before proceeding with setup.

#### Scenario: Display detection summary
- **WHEN** user runs `openspec init` in interactive mode
- **THEN** system displays detected editor configurations
- **AND** system displays detected OpenSpec state
- **AND** system shows recommendations based on detection

### Requirement: Init allows user to override detected selections
The system SHALL allow users to modify the pre-selected editors based on detection.

#### Scenario: User deselects detected editor
- **WHEN** Claude Code is detected and pre-selected
- **AND** user deselects Claude Code during init
- **THEN** system does not generate Claude Code files

#### Scenario: User selects non-detected editor
- **WHEN** Cursor is not detected (no .cursor/ directory)
- **AND** user selects Cursor during init
- **THEN** system generates Cursor files anyway

### Requirement: Init uses detected editors with --yes flag
The system SHALL use detected editors as defaults when running with --yes flag.

#### Scenario: Non-interactive init with detection
- **WHEN** user runs `openspec init --yes` in a project with .claude/ and .cursor/
- **THEN** system initializes for Claude Code and Cursor automatically
- **AND** system does not prompt for editor selection
53 changes: 53 additions & 0 deletions openspec/changes/add-multi-editor-support/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
## 1. Detection Functions

- [ ] 1.1 Create `detectEditorConfigs()` function to scan for .claude/, .cursor/, .windsurf/, .cline/
- [ ] 1.2 Create `detectOpenSpecState()` function to detect: uninitialized, old system, new system, mixed
- [ ] 1.3 Define `DetectionResult` interface for typed detection output
- [ ] 1.4 Add detection for each editor's configuration markers
- [ ] 1.5 Handle edge cases (empty directories, partial configs)

## 2. Smart Init Enhancement

- [ ] 2.1 Update init wizard to run detection before showing options
- [ ] 2.2 Display detection summary showing what was found
- [ ] 2.3 Pre-select detected editors in the selection UI
- [ ] 2.4 Allow user to override detected selections
- [ ] 2.5 Show state-aware recommendations (e.g., "Old system detected, recommend migration")
- [ ] 2.6 Handle already-initialized projects gracefully (detect and advise)
- [ ] 2.7 Ensure --yes flag uses detected editors as defaults

## 3. Editor Adapters

- [ ] 3.1 Create `EditorAdapter` interface for unified generation
- [ ] 3.2 Implement Claude Code adapter (skills + opsx commands)
- [ ] 3.3 Implement Cursor adapter (rules format in .cursor/rules/)
- [ ] 3.4 Implement Windsurf adapter (rules format in .windsurf/rules/)
- [ ] 3.5 Implement Cline adapter (rules format in .cline/rules/)
- [ ] 3.6 Define content transformation for each adapter (skill content → editor format)

## 4. Multi-Editor Generation

- [ ] 4.1 Update init to accept multiple editor selections
- [ ] 4.2 Generate files for all selected editors
- [ ] 4.3 Handle conflicts if multiple editors share a directory (unlikely but check)
- [ ] 4.4 Ensure skill content is equivalent across editors (format may differ)
- [ ] 4.5 Support adding editors to existing setup

## 5. Testing

- [ ] 5.1 Add unit tests for detectEditorConfigs()
- [ ] 5.2 Add unit tests for detectOpenSpecState() (including mixed state)
- [ ] 5.3 Add unit tests for each editor adapter
- [ ] 5.4 Add integration tests for multi-editor init
- [ ] 5.5 Test detection on projects with various configurations (uninitialized, old, new, mixed)
- [ ] 5.6 Test pre-selection behavior in init wizard
- [ ] 5.7 Test mixed state handling (recommends cleanup)
- [ ] 5.8 Verify Windows CI passes (cross-platform path handling)
- [ ] 5.9 Manual testing with actual editors (Claude Code, Cursor, etc.)

## 6. Documentation

- [ ] 6.1 Update README with multi-editor support
- [ ] 6.2 Document each supported editor and its configuration format
- [ ] 6.3 Add troubleshooting guide for editor-specific issues
- [ ] 6.4 Document how to add additional editors (adapter pattern)
Loading
Loading