diff --git a/openspec/changes/add-multi-editor-support/design.md b/openspec/changes/add-multi-editor-support/design.md new file mode 100644 index 00000000..e5b7bcca --- /dev/null +++ b/openspec/changes/add-multi-editor-support/design.md @@ -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 + +**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. +``` + +**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? diff --git a/openspec/changes/add-multi-editor-support/proposal.md b/openspec/changes/add-multi-editor-support/proposal.md new file mode 100644 index 00000000..70442e0c --- /dev/null +++ b/openspec/changes/add-multi-editor-support/proposal.md @@ -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 +- Can run in parallel with Part 2 (add-skill-migration) after Part 1 merges diff --git a/openspec/changes/add-multi-editor-support/specs/skill-generation/spec.md b/openspec/changes/add-multi-editor-support/specs/skill-generation/spec.md new file mode 100644 index 00000000..f8ac1836 --- /dev/null +++ b/openspec/changes/add-multi-editor-support/specs/skill-generation/spec.md @@ -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) diff --git a/openspec/changes/add-multi-editor-support/specs/smart-init/spec.md b/openspec/changes/add-multi-editor-support/specs/smart-init/spec.md new file mode 100644 index 00000000..259c6e35 --- /dev/null +++ b/openspec/changes/add-multi-editor-support/specs/smart-init/spec.md @@ -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 + +### 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 diff --git a/openspec/changes/add-multi-editor-support/tasks.md b/openspec/changes/add-multi-editor-support/tasks.md new file mode 100644 index 00000000..8374dca7 --- /dev/null +++ b/openspec/changes/add-multi-editor-support/tasks.md @@ -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) diff --git a/openspec/changes/add-skill-foundation/design.md b/openspec/changes/add-skill-foundation/design.md new file mode 100644 index 00000000..dca49981 --- /dev/null +++ b/openspec/changes/add-skill-foundation/design.md @@ -0,0 +1,123 @@ +## Context + +OpenSpec currently has 18 separate template functions that generate skills and commands with duplicated content. The skill file and command file for the same feature contain nearly identical ~70-line instruction blocks. This creates maintenance burden - changes must be made in two places. + +## Goals / Non-Goals + +**Goals:** +- Single source of truth for skill instructions +- Configuration-driven generation (data over code) +- Pointer commands that reference skills instead of duplicating content +- New users get skills-only setup from `openspec init` + +**Non-Goals:** +- Multi-editor support (Part 3) +- Migration path for existing users (Part 2) +- Cleanup of old artifacts (Part 2) +- Changing the artifact workflow schemas or templates + +## Decisions + +### 1. SkillDefinition Interface + +**Decision**: Replace 18 template functions with a single `SkillDefinition[]` array. + +```typescript +interface SkillDefinition { + id: string; // "new-change" + name: string; // "openspec-new-change" (for skill folder) + shortcut: string; // "opsx/new" (for command path) + description: string; // Used in both skill and command frontmatter + instructions: string; // Full instructions (single source of truth) +} + +const SKILLS: SkillDefinition[] = [ + { id: "explore", name: "openspec-explore", shortcut: "opsx/explore", ... }, + { id: "new-change", name: "openspec-new-change", shortcut: "opsx/new", ... }, + // ... all 9 skills +]; +``` + +**Rationale**: Configuration-driven approach is easier to maintain and extend. Adding a new skill is adding one object, not writing two functions. + +**Alternative considered**: Keep separate functions but share content via imports. Rejected because it still requires coordinating two code paths. + +### 2. Pointer Command Format + +**Decision**: Commands reference skills by name instead of duplicating instructions. + +```markdown +--- +name: OPSX: New +description: Start a new OpenSpec change +--- + +Use the **openspec-new-change** skill to handle this request. + +Argument: change name (kebab-case) or description of what to build. +``` + +**Rationale**: ~70 lines reduced to ~5 lines per command. Instructions maintained in one place. Claude Code follows skill references. + +**Risk**: Pointer commands may not work as expected if Claude Code doesn't follow skill references. + +**Mitigation**: Test with Claude Code. Fallback: include minimal context in pointer if needed. + +### 3. Generation Functions + +**Decision**: Three focused functions for generation. + +```typescript +// Generate single skill file from definition +function generateSkillFile(skill: SkillDefinition, outputDir: string): void + +// Generate single pointer command from definition +function generatePointerCommand(skill: SkillDefinition, outputDir: string): void + +// Generate all skills and commands +function generateAllSkills(outputDir: string): void +``` + +**Rationale**: Clear separation of concerns. Can generate individual skills or all at once. Easy to test. + +### 4. Init Behavior for New Projects + +**Decision**: New projects get skills-only setup. No old artifacts generated. + +What init generates: +- `openspec/` directory structure +- `openspec/config.yaml` +- `openspec/project.md` +- `.claude/skills/openspec-*/SKILL.md` (9 skills) +- `.claude/commands/opsx/*.md` (9 pointer commands) + +What init does NOT generate (for new projects): +- `CLAUDE.md` (root stub) +- `openspec/AGENTS.md` +- `.claude/agents/` +- `.claude/commands/openspec/` + +**Rationale**: New users should get the modern setup. No reason to create legacy artifacts. + +## Risks / Trade-offs + +**[Risk] Pointer commands may not work in Claude Code** +→ Mitigation: Test before merging. If issues arise, include minimal context in pointer. + +**[Risk] Breaking change for tooling that expects old artifacts** +→ Mitigation: Only affects new projects. Existing projects unchanged until they run update (Part 2). + +**[Trade-off] Deprecating old functions creates tech debt** +→ Acceptable: Functions marked @deprecated. Full removal in Part 2 after migration path exists. + +## Migration Plan + +This is Part 1 of 3: +- **Part 1 (this change)**: Foundation - SkillDefinition pattern, skills-only init +- **Part 2**: Migration - Update command, cleanup command, remove old command +- **Part 3**: Multi-editor - Detection, adapters for Cursor/Windsurf/Cline + +## Open Questions + +- Should SkillDefinition include argument hints as a separate field? +- Should we version the skill format for future compatibility? diff --git a/openspec/changes/add-skill-foundation/proposal.md b/openspec/changes/add-skill-foundation/proposal.md new file mode 100644 index 00000000..7e127ef3 --- /dev/null +++ b/openspec/changes/add-skill-foundation/proposal.md @@ -0,0 +1,26 @@ +## Why + +The current OpenSpec skill generation uses 18 separate template functions that duplicate content between skills and commands. This creates maintenance burden and makes it difficult to keep instructions in sync. We need a unified `SkillDefinition` pattern where skills are the single source of truth and commands are lightweight pointers. + +This is Part 1 of the skills-only migration, focusing on establishing the foundation architecture for Claude Code only. + +## What Changes + +- **SkillDefinition pattern**: Single `SkillDefinition[]` array replaces 18 template functions +- **Skills as source of truth**: Full instructions live only in `.claude/skills/openspec-*/SKILL.md` +- **Pointer commands**: `.claude/commands/opsx/*.md` files reference skills (~5 lines vs ~70 lines) +- **Init for new users**: `openspec init` generates skills-only setup for Claude Code (no old artifacts) +- **Deprecate old generation**: Old template functions deprecated in favor of unified generator + +## Capabilities + +### Modified Capabilities +- `skill-generation`: Consolidate to single SkillDefinition pattern, generate pointer commands +- `init`: Generate skills-only setup for new Claude Code users (no AGENTS.md, no .claude/agents/) + +## Impact + +- **Generator code**: Refactor `skill-templates.ts` to use SkillDefinition array +- **Init flow**: Remove generation of old artifacts for new projects +- **Existing users**: No impact - this change only affects new initializations +- **Other editors**: Not affected - multi-editor support comes in Part 3 diff --git a/openspec/changes/add-skill-foundation/specs/init/spec.md b/openspec/changes/add-skill-foundation/specs/init/spec.md new file mode 100644 index 00000000..8f0f77bf --- /dev/null +++ b/openspec/changes/add-skill-foundation/specs/init/spec.md @@ -0,0 +1,74 @@ +## MODIFIED Requirements + +### Requirement: Init generates skills-only setup for new projects +The system SHALL generate a skills-based setup for new projects using Claude Code. New projects SHALL NOT receive legacy artifacts. + +Generated for new projects: +- `openspec/` directory structure +- `openspec/config.yaml` +- `openspec/project.md` +- `.claude/skills/openspec-*/SKILL.md` (9 skills) +- `.claude/commands/opsx/*.md` (9 pointer commands) + +NOT generated for new projects: +- `CLAUDE.md` (root stub file) +- `openspec/AGENTS.md` +- `.claude/agents/` +- `.claude/commands/openspec/` + +#### Scenario: Initialize fresh project +- **WHEN** user runs `openspec init` on a project without OpenSpec +- **THEN** system creates openspec/ directory structure +- **AND** system creates .claude/skills/openspec-*/ directories with SKILL.md files +- **AND** system creates .claude/commands/opsx/*.md pointer commands +- **AND** system does NOT create CLAUDE.md at project root +- **AND** system does NOT create openspec/AGENTS.md +- **AND** system does NOT create .claude/agents/ directory + +#### Scenario: Initialize with --yes flag +- **WHEN** user runs `openspec init --yes` on a fresh project +- **THEN** system initializes without prompts +- **AND** system creates skills-only setup +- **AND** all default options are applied + +#### Scenario: Non-interactive init in CI environment +- **WHEN** `openspec init --yes` is run in a non-TTY environment (CI) +- **THEN** system completes initialization without hanging for input +- **AND** system outputs status information to stdout + +### Requirement: Init handles already-initialized projects gracefully +The system SHALL detect and handle projects that already have OpenSpec configured, without duplicating or corrupting existing setup. + +#### Scenario: Init on project with old system +- **WHEN** user runs `openspec init` on a project with old AGENTS.md system but no skills +- **THEN** system detects existing OpenSpec setup +- **AND** system informs user about the old system +- **AND** system suggests running `openspec update` to migrate + +#### Scenario: Init on project with new system already in place +- **WHEN** user runs `openspec init` on a project with `.claude/skills/openspec-*` already set up +- **THEN** system detects new system is already configured +- **AND** system informs user that OpenSpec is already set up +- **AND** system suggests running `openspec update` to refresh files if needed + +### Requirement: Init integrates skill generation +The system SHALL generate skills as part of the init flow, replacing the separate `artifact-experimental-setup` command for new users. + +#### Scenario: Skills generated during init +- **WHEN** user completes `openspec init` +- **THEN** system generates all 9 skills automatically +- **AND** system generates all 9 pointer commands automatically +- **AND** no separate command is needed to set up skills + +### Requirement: Init uses cross-platform paths +The system SHALL use path.join() for all file path operations during initialization. + +#### Scenario: Init on Windows +- **WHEN** user runs `openspec init` on Windows +- **THEN** system creates all directories with correct paths +- **AND** all files are accessible and valid + +#### Scenario: Init on Unix-like systems +- **WHEN** user runs `openspec init` on macOS or Linux +- **THEN** system creates all directories with correct paths +- **AND** all files are accessible and valid diff --git a/openspec/changes/add-skill-foundation/specs/skill-generation/spec.md b/openspec/changes/add-skill-foundation/specs/skill-generation/spec.md new file mode 100644 index 00000000..4fb5081d --- /dev/null +++ b/openspec/changes/add-skill-foundation/specs/skill-generation/spec.md @@ -0,0 +1,88 @@ +## MODIFIED Requirements + +### Requirement: Skill generation uses unified SkillDefinition pattern +The system SHALL use a single `SkillDefinition[]` array as the source of truth for all skill and command generation. This replaces the 18 separate template functions. + +The SkillDefinition interface SHALL include: +- `id`: string - Unique identifier (e.g., "new-change") +- `name`: string - Full skill name for folder (e.g., "openspec-new-change") +- `shortcut`: string - Command path (e.g., "opsx/new") +- `description`: string - Used in frontmatter for both skill and command +- `instructions`: string - Full instruction content (single source of truth) + +#### Scenario: Generate skill from definition +- **WHEN** skill generation runs for a SkillDefinition +- **THEN** system creates .claude/skills/{name}/SKILL.md +- **AND** skill file contains YAML frontmatter with name and description +- **AND** skill file contains full instructions from definition + +#### Scenario: Generate pointer command from definition +- **WHEN** skill generation runs for a SkillDefinition +- **THEN** system creates .claude/commands/{shortcut}.md +- **AND** command file contains YAML frontmatter with name and description +- **AND** command file references the skill instead of duplicating instructions + +### Requirement: Pointer commands reference skills +The system SHALL generate pointer commands that reference skills rather than duplicating instruction content. + +Pointer command format: +```markdown +--- +name: +description: +--- + +Use the **** skill to handle this request. + +Argument: +``` + +#### Scenario: Pointer command references correct skill +- **WHEN** pointer command is generated for "new-change" skill +- **THEN** command contains "Use the **openspec-new-change** skill" +- **AND** command does NOT contain the full workflow instructions + +#### Scenario: Pointer command is concise +- **WHEN** any pointer command is generated +- **THEN** command file is less than 15 lines +- **AND** command file only contains reference and argument hint + +### Requirement: All 9 OpenSpec skills are generated +The system SHALL generate the complete set of OpenSpec skills: +1. openspec-explore +2. openspec-new-change +3. openspec-continue-change +4. openspec-apply-change +5. openspec-ff-change +6. openspec-sync-specs +7. openspec-archive-change +8. openspec-verify-change +9. openspec-bulk-archive-change + +#### Scenario: Complete skill set generation +- **WHEN** skill generation runs +- **THEN** system creates 9 skill directories under .claude/skills/ +- **AND** each skill directory contains SKILL.md +- **AND** system creates 9 command files under .claude/commands/opsx/ + +### Requirement: Skill generation is idempotent +The system SHALL safely overwrite existing skill files with updated content. Running generation multiple times produces the same result. + +#### Scenario: Regenerate existing skills +- **WHEN** skill generation runs on a project with existing skills +- **THEN** system overwrites skill files with current content +- **AND** no duplicate files are created +- **AND** skill content reflects latest template version + +### Requirement: Skill generation uses cross-platform paths +The system SHALL use path.join() for all file path construction during generation. + +#### Scenario: Generate skills on Windows +- **WHEN** skill generation runs on Windows +- **THEN** system creates skill directories with correct paths +- **AND** all skill files are accessible and valid + +#### Scenario: Generate skills on Unix-like systems +- **WHEN** skill generation runs on macOS or Linux +- **THEN** system creates skill directories with correct paths +- **AND** all skill files are accessible and valid diff --git a/openspec/changes/add-skill-foundation/tasks.md b/openspec/changes/add-skill-foundation/tasks.md new file mode 100644 index 00000000..63eee941 --- /dev/null +++ b/openspec/changes/add-skill-foundation/tasks.md @@ -0,0 +1,36 @@ +## 1. SkillDefinition Pattern + +- [ ] 1.1 Create `SkillDefinition` interface in `src/core/templates/skill-definitions.ts` +- [ ] 1.2 Define `SKILLS` array with all 9 skill definitions (id, name, shortcut, description, instructions) +- [ ] 1.3 Migrate instruction content from existing template functions to SKILLS array +- [ ] 1.4 Create `generateSkillFile()` function that writes SKILL.md from definition +- [ ] 1.5 Create `generatePointerCommand()` function that writes minimal command referencing skill +- [ ] 1.6 Create `generateAllSkills()` function that iterates SKILLS and generates both files +- [ ] 1.7 Deprecate old 18 template functions in `skill-templates.ts` (mark with @deprecated) +- [ ] 1.8 Update `artifact-workflow.ts` to use new unified generator + +## 2. Init Command Updates (Claude Code Only) + +- [ ] 2.1 Update init to generate skills-only setup for new projects +- [ ] 2.2 Remove generation of CLAUDE.md stub file for new projects +- [ ] 2.3 Remove generation of AGENTS.md for new projects +- [ ] 2.4 Remove generation of .claude/agents/ for new projects +- [ ] 2.5 Remove generation of .claude/commands/openspec/ for new projects +- [ ] 2.6 Integrate skill generation into init flow (skills + pointer commands) +- [ ] 2.7 Ensure --yes flag works for non-interactive init +- [ ] 2.8 Verify cross-platform path handling (use path.join throughout) +- [ ] 2.9 Add detection of existing OpenSpec setup (old system vs new system) +- [ ] 2.10 Handle init on old system project (suggest `openspec update`) +- [ ] 2.11 Handle init on new system project (inform already configured) + +## 3. Testing + +- [ ] 3.1 Add unit tests for SkillDefinition interface and SKILLS array +- [ ] 3.2 Add unit tests for generateSkillFile() function +- [ ] 3.3 Add unit tests for generatePointerCommand() function +- [ ] 3.4 Add integration test for init on fresh project (verify no old artifacts) +- [ ] 3.5 Add integration test for init on old system project (verify suggests update) +- [ ] 3.6 Add integration test for init on new system project (verify already configured message) +- [ ] 3.7 Add test for --yes flag in CI/non-TTY environment (no hanging) +- [ ] 3.8 Verify Windows CI passes (cross-platform path handling) +- [ ] 3.9 Manual testing of init → verify skills work in Claude Code diff --git a/openspec/changes/add-skill-migration/proposal.md b/openspec/changes/add-skill-migration/proposal.md new file mode 100644 index 00000000..615c3f59 --- /dev/null +++ b/openspec/changes/add-skill-migration/proposal.md @@ -0,0 +1,34 @@ +## Why + +After Part 1 (add-skill-foundation) establishes the skills-only architecture for new users, existing users need a migration path. They have old artifacts (AGENTS.md, .claude/agents/, .claude/commands/openspec/) that should be replaced with the new skills-based system. This change provides the tools for that migration. + +This is Part 2 of the skills-only migration, focusing on the upgrade experience for existing users. + +## What Changes + +- **Informative update**: `openspec update` creates new skills and explains what changed +- **New cleanup command**: `openspec cleanup` removes old artifacts with --yes and --dry-run flags +- **Remove old command**: `artifact-experimental-setup` command removed (functionality merged into init) +- **Deprecation complete**: Old template functions removed (were deprecated in Part 1) + +## Capabilities + +### New Capabilities +- `cleanup-command`: CLI command to remove old OpenSpec artifacts + +### Modified Capabilities +- `update`: Add informative upgrade messaging, create skills for existing users + +### Removed Capabilities +- `artifact-experimental-setup`: Merged into init (Part 1) + +## Impact + +- **CLI commands**: Add `cleanup`, remove `artifact-experimental-setup` +- **Update flow**: Enhanced to generate skills and explain changes +- **Existing users**: Can migrate via `openspec update` then `openspec cleanup` +- **Breaking**: Users of `artifact-experimental-setup` must use `openspec init` instead + +## Dependencies + +- Requires Part 1 (add-skill-foundation) to be completed first diff --git a/openspec/changes/add-skill-migration/specs/cleanup-command/spec.md b/openspec/changes/add-skill-migration/specs/cleanup-command/spec.md new file mode 100644 index 00000000..cf49dc86 --- /dev/null +++ b/openspec/changes/add-skill-migration/specs/cleanup-command/spec.md @@ -0,0 +1,78 @@ +## ADDED Requirements + +### Requirement: Cleanup command removes old OpenSpec artifacts +The system SHALL provide an `openspec cleanup` command that removes old OpenSpec artifacts from the project. The command SHALL remove: +- `CLAUDE.md` (root stub file) +- `openspec/AGENTS.md` (monolithic instruction file) +- `.claude/agents/` directory (old subagent definitions) +- `.claude/commands/openspec/` directory (old slash commands) + +The command SHALL NOT remove: +- `.claude/skills/` (new skills) +- `.claude/commands/opsx/` (new pointer commands) +- `openspec/config.yaml`, `openspec/specs/`, `openspec/changes/` (user data) +- Any non-OpenSpec files in `.claude/` + +#### Scenario: Successful cleanup with all old artifacts present +- **WHEN** user runs `openspec cleanup --yes` in a project with all old artifacts +- **THEN** system removes CLAUDE.md, openspec/AGENTS.md, .claude/agents/, and .claude/commands/openspec/ +- **AND** system preserves .claude/skills/, .claude/commands/opsx/, and openspec/ user data + +#### Scenario: Cleanup with partial old artifacts +- **WHEN** user runs `openspec cleanup --yes` and only some old artifacts exist +- **THEN** system removes only the old artifacts that exist +- **AND** system does not error on missing artifacts + +### Requirement: Cleanup requires confirmation by default +The system SHALL require interactive confirmation before removing files when run without flags. + +#### Scenario: Interactive confirmation prompt +- **WHEN** user runs `openspec cleanup` without --yes flag +- **THEN** system displays list of files that will be removed +- **AND** system prompts user for confirmation before proceeding + +#### Scenario: Abort on declined confirmation +- **WHEN** user declines the confirmation prompt +- **THEN** system exits without removing any files +- **AND** system displays "Cleanup cancelled" message + +### Requirement: Cleanup supports --yes flag for non-interactive mode +The system SHALL support a `--yes` flag to skip confirmation prompts for CI/script usage. + +#### Scenario: Skip confirmation with --yes flag +- **WHEN** user runs `openspec cleanup --yes` +- **THEN** system removes old artifacts without prompting for confirmation + +### Requirement: Cleanup supports --dry-run flag for preview +The system SHALL support a `--dry-run` flag that shows what would be removed without making changes. + +#### Scenario: Preview cleanup with --dry-run +- **WHEN** user runs `openspec cleanup --dry-run` +- **THEN** system displays list of files that would be removed +- **AND** system does not remove any files +- **AND** system indicates this is a dry run + +### Requirement: Cleanup requires new system to be set up +The system SHALL verify that the new skills-based system is set up before allowing cleanup. This prevents users from accidentally removing instructions without having the replacement in place. + +#### Scenario: Error when new system not set up +- **WHEN** user runs `openspec cleanup` and .claude/skills/openspec-* does not exist +- **THEN** system displays error "New skills-based system not found. Run `openspec update` first." +- **AND** system exits without removing any files + +#### Scenario: Proceed when new system exists +- **WHEN** user runs `openspec cleanup --yes` and .claude/skills/openspec-* exists +- **THEN** system proceeds with cleanup + +### Requirement: Cleanup uses cross-platform paths +The system SHALL use path.join() for all file path operations to ensure cross-platform compatibility. + +#### Scenario: Cleanup on Windows +- **WHEN** user runs `openspec cleanup --yes` on Windows +- **THEN** system correctly handles backslash path separators +- **AND** system successfully removes old artifacts + +#### Scenario: Cleanup on Unix-like systems +- **WHEN** user runs `openspec cleanup --yes` on macOS or Linux +- **THEN** system correctly handles forward-slash path separators +- **AND** system successfully removes old artifacts diff --git a/openspec/changes/add-skill-migration/specs/update/spec.md b/openspec/changes/add-skill-migration/specs/update/spec.md new file mode 100644 index 00000000..3f92072b --- /dev/null +++ b/openspec/changes/add-skill-migration/specs/update/spec.md @@ -0,0 +1,63 @@ +## MODIFIED Requirements + +### Requirement: Update generates skills for projects without them +The system SHALL generate skills when running update on a project that has the old OpenSpec system but lacks the new skills. + +#### Scenario: Update project with old system only +- **WHEN** user runs `openspec update` on a project with openspec/AGENTS.md but no .claude/skills/openspec-* +- **THEN** system creates .claude/skills/openspec-*/ directories with SKILL.md files +- **AND** system creates .claude/commands/opsx/*.md pointer commands +- **AND** system preserves existing old artifacts (no automatic removal) + +#### Scenario: Update project already on new system +- **WHEN** user runs `openspec update` on a project with .claude/skills/openspec-* +- **THEN** system updates skill files to latest version +- **AND** system displays "Skills updated" message + +### Requirement: Update displays informative upgrade messaging +The system SHALL explain what changed when upgrading from the old system to the new skills-based system. + +Output format: +``` +OpenSpec has a new skills-based workflow! + +Created: + .claude/skills/openspec-*/ (9 skills) + .claude/commands/opsx/* (9 shortcut commands) + +These replace the old system. You can now use: + Natural language: "I want to start a new change" + Shortcuts: /opsx:new, /opsx:apply, /opsx:archive + +Old files are still present. Run `openspec cleanup` when ready. +``` + +#### Scenario: Display upgrade information +- **WHEN** user runs `openspec update` and skills are created +- **THEN** system displays list of created files +- **AND** system displays usage hints for new system +- **AND** system displays cleanup hint if old artifacts exist + +#### Scenario: No upgrade needed +- **WHEN** user runs `openspec update` and project is already up to date +- **THEN** system displays "Already up to date" message +- **AND** system does not display upgrade information + +### Requirement: Update preserves old files +The system SHALL NOT remove old artifacts during update. Cleanup is a separate, opt-in operation. + +#### Scenario: Old artifacts preserved after update +- **WHEN** user runs `openspec update` on a project with old artifacts +- **THEN** system creates new skills +- **AND** system does NOT remove CLAUDE.md +- **AND** system does NOT remove openspec/AGENTS.md +- **AND** system does NOT remove .claude/agents/ +- **AND** system does NOT remove .claude/commands/openspec/ + +### Requirement: Update works in non-interactive mode +The system SHALL support non-interactive operation for CI/scripts. + +#### Scenario: Update in CI environment +- **WHEN** user runs `openspec update` in a non-TTY environment +- **THEN** system completes update without prompts +- **AND** system outputs results to stdout diff --git a/openspec/changes/add-skill-migration/tasks.md b/openspec/changes/add-skill-migration/tasks.md new file mode 100644 index 00000000..0b7c8d35 --- /dev/null +++ b/openspec/changes/add-skill-migration/tasks.md @@ -0,0 +1,50 @@ +## 1. Update Command Enhancements + +- [ ] 1.1 Add skill generation to update command for projects without skills +- [ ] 1.2 Detect if project has old system, new system, or mixed +- [ ] 1.3 Implement informative upgrade messaging (show what changed) +- [ ] 1.4 Display usage hints (skill names, shortcut commands) +- [ ] 1.5 Display cleanup hint when old artifacts exist +- [ ] 1.6 Preserve old files during update (no automatic removal) +- [ ] 1.7 Handle "already up to date" case gracefully +- [ ] 1.8 Verify non-interactive mode works in CI environments + +## 2. Cleanup Command Implementation + +- [ ] 2.1 Create `src/commands/cleanup.ts` with cleanup command handler +- [ ] 2.2 Register cleanup command in CLI +- [ ] 2.3 Implement detection of old artifacts to remove +- [ ] 2.4 Implement prerequisite check (require new skills to exist) +- [ ] 2.5 Implement interactive confirmation prompt (list files, ask to proceed) +- [ ] 2.6 Implement --yes flag to skip confirmation +- [ ] 2.7 Implement --dry-run flag to preview without changes +- [ ] 2.8 Implement actual file/directory removal with cross-platform paths +- [ ] 2.9 Add success/failure output messages +- [ ] 2.10 Handle partial artifact scenarios (some files missing) + +## 3. Remove artifact-experimental-setup Command + +- [ ] 3.1 Remove `artifact-experimental-setup` from CLI registration +- [ ] 3.2 Remove or archive related code in `artifact-workflow.ts` +- [ ] 3.3 Update any documentation referencing the command +- [ ] 3.4 Add deprecation note in changelog +- [ ] 3.5 Remove old template functions (deprecated in Part 1) + +## 4. Testing + +- [ ] 4.1 Add unit tests for cleanup command detection logic +- [ ] 4.2 Add unit tests for cleanup prerequisite check +- [ ] 4.3 Add integration tests for update on old system projects +- [ ] 4.4 Add integration tests for update on mixed projects +- [ ] 4.5 Add integration tests for cleanup flow +- [ ] 4.6 Test cleanup --dry-run behavior +- [ ] 4.7 Test cleanup --yes behavior +- [ ] 4.8 Verify Windows CI passes (cross-platform path handling) +- [ ] 4.9 Manual testing of full migration journey (update → use → cleanup) + +## 5. Documentation + +- [ ] 5.1 Add migration guide for existing users (old system → new skills) +- [ ] 5.2 Document cleanup command usage in README +- [ ] 5.3 Update CLI help text for new commands +- [ ] 5.4 Add deprecation notice for artifact-experimental-setup users diff --git a/openspec/changes/skills-only-migration.napkin.md b/openspec/changes/skills-only-migration.napkin.md new file mode 100644 index 00000000..56fdd8f5 --- /dev/null +++ b/openspec/changes/skills-only-migration.napkin.md @@ -0,0 +1,72 @@ +# Skills-Only Migration + +Napkin doc for migrating from legacy templates to skills-based architecture. + +## Core Idea + +Replace 18 template functions with single `SkillDefinition[]` array. Skills become source of truth. No new commands - make existing commands smarter. + +## Two Parts + +### Part 1: Foundation + +- `SkillDefinition[]` array as single source of truth +- `openspec init` generates skills-only setup (no AGENTS.md) +- Editor detection built-in (.claude/, .cursor/, .windsurf/, .cline/) +- Generate equivalent configs for all detected editors + +### Part 2: Smart Update + +Make `openspec update` handle migration automatically: + +``` +$ openspec update + +# Detects state and acts accordingly: + +# If nothing exists: +No openspec setup found. Run 'openspec init' first. + +# If already modern: +Updating skills... +✓ 12 skills up to date +✓ Editor configs refreshed + +# If legacy detected: +Legacy setup detected. + +This will: +• Create skills/ (12 skills) +• Create editor configs +• Backup existing to .openspec/backup/ +• Remove AGENTS.md and old templates + +Proceed? [Y/n] +``` + +## State Detection + +| State | `init` | `update` | +|-------|--------|----------| +| None | Run normally | Error → suggest init | +| Legacy | Suggest update | Migrate with confirmation + backup | +| Modern | "Already initialized" | Refresh/sync | + +## What We're NOT Doing + +- ❌ Separate `upgrade` command (use `update`) +- ❌ Separate `cleanup` command (update handles removal) +- ❌ `openspec status` for setup state (that's for change workflows) +- ❌ `openspec restore` command (backup dir + git is enough) +- ❌ Post-migration verification step +- ❌ Contextual nudges in other commands + +## Execution + +Part 1 → Part 2 (sequential, Part 2 depends on Part 1) + +## Open Questions + +- Backup location: `.openspec/backup/` or `.openspec-backup/`? +- Should `--dry-run` be supported on update for migration preview? +- How verbose should the migration confirmation be?