mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-04 06:18:24 +08:00
Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bcf2c6905 | ||
|
|
581a681a47 | ||
|
|
3093ca6ae6 | ||
|
|
9d425865c1 | ||
|
|
a490dbbc78 | ||
|
|
fc0e2319b1 | ||
|
|
edf6873afa | ||
|
|
c0ce4adc0a | ||
|
|
e40abe1f20 | ||
|
|
e752b3200f | ||
|
|
a59284839b | ||
|
|
fa824fac95 | ||
|
|
7bc54b2cd3 |
+26
-1
@@ -10,6 +10,23 @@ OpenSpec is an AI-native system for change-driven development where:
|
||||
- **AI drives the process** - You generate proposals, humans review and approve
|
||||
- **Specs are living documentation** - Always kept in sync with deployed code
|
||||
|
||||
## Start Simple
|
||||
|
||||
**Default to minimal implementations:**
|
||||
- New features should be <100 lines of code initially
|
||||
- Use the simplest solution that works
|
||||
- Avoid premature optimization (no caching, parallelization, or complex patterns without proven need)
|
||||
- Choose boring technology over cutting-edge solutions
|
||||
|
||||
**Complexity triggers** - Only add complexity when you have:
|
||||
- **Performance data** showing current solution is too slow
|
||||
- **Scale requirements** with specific numbers (>1000 users, >100MB data)
|
||||
- **Multiple use cases** requiring the same abstraction
|
||||
- **Regulatory compliance** mandating specific patterns
|
||||
- **Security threats** that simple solutions cannot address
|
||||
|
||||
When triggered, document the specific justification in your change proposal.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
@@ -72,6 +89,11 @@ Before any task:
|
||||
- Adding tests for existing behavior
|
||||
- Documentation fixes
|
||||
|
||||
**Complexity assessment:**
|
||||
- If your solution requires >100 lines of new code, justify the complexity
|
||||
- If adding dependencies, frameworks, or architectural patterns, document why simpler alternatives won't work
|
||||
- Default to single-file implementations until proven insufficient
|
||||
|
||||
### 3. Creating a Change Proposal
|
||||
|
||||
When a user requests a significant change:
|
||||
@@ -383,10 +405,12 @@ Progress communication:
|
||||
- "Implementing approved changes..."
|
||||
|
||||
### For AI Assistants
|
||||
- **Bias toward simplicity** - Propose the minimal solution that works
|
||||
- Use your exploration tools liberally before proposing
|
||||
- Batch operations for efficiency
|
||||
- Communicate your progress
|
||||
- It's OK to revise proposals based on discoveries
|
||||
- **Question complexity** - If your solution feels complex, simplify first
|
||||
|
||||
## Edge Case Handling
|
||||
|
||||
@@ -442,6 +466,7 @@ Proposal REQUIRED if:
|
||||
- Specs must always reflect deployed reality
|
||||
- Changes are proposed, not imposed
|
||||
- Impact analysis prevents surprises
|
||||
- The simplicity is the power - just markdown files
|
||||
- Simplicity is the power - just markdown files, minimal solutions
|
||||
- Start simple, add complexity only when justified
|
||||
|
||||
By following these conventions, you enable true spec-driven development where documentation stays current, changes are traceable, and evolution is intentional.
|
||||
@@ -1,9 +0,0 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Update OpenSpec README
|
||||
- [ ] 1.1 Add "Start Simple" section after Core Principle
|
||||
- [ ] 1.2 Add complexity triggers to "When to Create Change Proposals" section
|
||||
- [ ] 1.3 Update AI workflow guidance to emphasize minimal implementations
|
||||
|
||||
## 2. Update CLAUDE.md
|
||||
- [ ] 2.1 Add complexity management rules to project instructions
|
||||
@@ -0,0 +1,20 @@
|
||||
# Add List Command to OpenSpec CLI
|
||||
|
||||
## Why
|
||||
|
||||
Developers need visibility into available changes and their status to understand the project's evolution and pending work.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add `openspec list` command that displays all changes in the changes/ directory
|
||||
- Show each change name with task completion count (e.g., "add-auth: 3/5 tasks")
|
||||
- Display completion status indicator (✓ for fully complete, progress for partial)
|
||||
- Skip the archive/ subdirectory to focus on active changes
|
||||
- Simple table output for easy scanning
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: New capability `cli-list` will be added
|
||||
- Affected code:
|
||||
- `src/cli/index.ts` - Add list command
|
||||
- `src/core/list.ts` - New file with directory scanning and task parsing (~60 lines)
|
||||
@@ -0,0 +1,69 @@
|
||||
# List Command Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
The `openspec list` command SHALL provide developers with a quick overview of all active changes in the project, showing their names and task completion status.
|
||||
|
||||
## Behavior
|
||||
|
||||
### Command Execution
|
||||
|
||||
WHEN `openspec list` is executed
|
||||
THEN scan the `openspec/changes/` directory for change directories
|
||||
AND exclude the `archive/` subdirectory from results
|
||||
AND parse each change's `tasks.md` file to count task completion
|
||||
|
||||
### Task Counting
|
||||
|
||||
WHEN parsing a `tasks.md` file
|
||||
THEN count tasks matching these patterns:
|
||||
- Completed: Lines containing `- [x]`
|
||||
- Incomplete: Lines containing `- [ ]`
|
||||
AND calculate total tasks as the sum of completed and incomplete
|
||||
|
||||
### Output Format
|
||||
|
||||
WHEN displaying the list
|
||||
THEN show a table with columns:
|
||||
- Change name (directory name)
|
||||
- Task progress (e.g., "3/5 tasks" or "✓ Complete")
|
||||
- Status indicator:
|
||||
- `✓` for fully completed changes (all tasks done)
|
||||
- Progress fraction for partial completion
|
||||
|
||||
Example output:
|
||||
```
|
||||
Changes:
|
||||
add-auth-feature 3/5 tasks
|
||||
update-api-docs ✓ Complete
|
||||
fix-validation 0/2 tasks
|
||||
add-list-command 1/4 tasks
|
||||
```
|
||||
|
||||
### Empty State
|
||||
|
||||
WHEN no active changes exist (only archive/ or empty changes/)
|
||||
THEN display: "No active changes found."
|
||||
|
||||
### Error Handling
|
||||
|
||||
IF a change directory has no `tasks.md` file
|
||||
THEN display the change with "No tasks" status
|
||||
|
||||
IF `openspec/changes/` directory doesn't exist
|
||||
THEN display error: "No OpenSpec changes directory found. Run 'openspec init' first."
|
||||
AND exit with code 1
|
||||
|
||||
### Sorting
|
||||
|
||||
Changes SHALL be displayed in alphabetical order by change name for consistency.
|
||||
|
||||
## Why
|
||||
|
||||
Developers need a quick way to:
|
||||
- See what changes are in progress
|
||||
- Identify which changes are ready to archive
|
||||
- Understand the overall project evolution status
|
||||
- Get a bird's-eye view without opening multiple files
|
||||
|
||||
This command provides that visibility with minimal effort, following OpenSpec's philosophy of simplicity and clarity.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Core Implementation
|
||||
- [ ] 1.1 Create `src/core/list.ts` with list logic
|
||||
- [ ] 1.1.1 Implement directory scanning (exclude archive/)
|
||||
- [ ] 1.1.2 Implement task counting from tasks.md files
|
||||
- [ ] 1.1.3 Format output as simple table
|
||||
- [ ] 1.2 Add list command to CLI in `src/cli/index.ts`
|
||||
- [ ] 1.2.1 Register `openspec list` command
|
||||
- [ ] 1.2.2 Connect to list.ts implementation
|
||||
|
||||
## 2. Error Handling
|
||||
- [ ] 2.1 Handle missing openspec/changes/ directory
|
||||
- [ ] 2.2 Handle changes without tasks.md files
|
||||
- [ ] 2.3 Handle empty changes directory
|
||||
|
||||
## 3. Testing
|
||||
- [ ] 3.1 Add tests for list functionality
|
||||
- [ ] 3.1.1 Test with multiple changes
|
||||
- [ ] 3.1.2 Test with completed changes
|
||||
- [ ] 3.1.3 Test with no changes
|
||||
- [ ] 3.1.4 Test error conditions
|
||||
|
||||
## 4. Documentation
|
||||
- [ ] 4.1 Update CLI help text with list command
|
||||
- [ ] 4.2 Add list command to README if applicable
|
||||
@@ -0,0 +1,86 @@
|
||||
# Technical Design
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### Simplicity First
|
||||
- No version tracking - always update when commanded
|
||||
- Full replacement for OpenSpec-managed files only (e.g., `openspec/README.md`)
|
||||
- Marker-based updates for user-owned files (e.g., `CLAUDE.md`)
|
||||
- Templates bundled with package - no network required
|
||||
- Minimal error handling - only check prerequisites
|
||||
|
||||
### Template Strategy
|
||||
- Use existing template utilities
|
||||
- `readmeTemplate` from `src/core/templates/readme-template.ts` for `openspec/README.md`
|
||||
- `TemplateManager.getClaudeTemplate()` for `CLAUDE.md`
|
||||
- Directory name is fixed to `openspec` (from `OPENSPEC_DIR_NAME`)
|
||||
|
||||
### File Operations
|
||||
- Use async utilities for consistency
|
||||
- `FileSystemUtils.writeFile` for `openspec/README.md`
|
||||
- `FileSystemUtils.updateFileWithMarkers` for `CLAUDE.md`
|
||||
- No atomic operations needed - users have git
|
||||
- Check directory existence before proceeding
|
||||
|
||||
## Implementation
|
||||
|
||||
### Update Command (`src/core/update.ts`)
|
||||
```typescript
|
||||
export class UpdateCommand {
|
||||
async execute(projectPath: string): Promise<void> {
|
||||
const openspecDirName = OPENSPEC_DIR_NAME;
|
||||
const openspecPath = path.join(projectPath, openspecDirName);
|
||||
|
||||
// 1. Check openspec directory exists
|
||||
if (!await FileSystemUtils.directoryExists(openspecPath)) {
|
||||
throw new Error(`No OpenSpec directory found. Run 'openspec init' first.`);
|
||||
}
|
||||
|
||||
// 2. Update README.md (full replacement)
|
||||
const readmePath = path.join(openspecPath, 'README.md');
|
||||
await FileSystemUtils.writeFile(readmePath, readmeTemplate);
|
||||
|
||||
// 3. Update CLAUDE.md (marker-based)
|
||||
const claudePath = path.join(projectPath, 'CLAUDE.md');
|
||||
const claudeContent = TemplateManager.getClaudeTemplate();
|
||||
await FileSystemUtils.updateFileWithMarkers(
|
||||
claudePath,
|
||||
claudeContent,
|
||||
OPENSPEC_MARKERS.start,
|
||||
OPENSPEC_MARKERS.end
|
||||
);
|
||||
|
||||
// 4. Success message (ASCII-safe, checkmark optional by terminal)
|
||||
console.log('Updated OpenSpec instructions');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Why This Approach
|
||||
|
||||
### Benefits
|
||||
- **Dead simple**: ~40 lines of code total
|
||||
- **Fast**: No version checks, minimal parsing
|
||||
- **Predictable**: Same result every time; idempotent
|
||||
- **Maintainable**: Reuses existing utilities
|
||||
|
||||
### Trade-offs Accepted
|
||||
- No version tracking (unnecessary complexity)
|
||||
- Full overwrite only for OpenSpec-managed files
|
||||
- Marker-managed updates for user-owned files
|
||||
|
||||
## Error Handling
|
||||
|
||||
Only handle critical errors:
|
||||
- Missing `openspec` directory → throw error handled by CLI to present a friendly message
|
||||
- File write failures → let errors bubble up to CLI
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
Manual smoke tests are sufficient initially:
|
||||
1. Run `openspec init` in a test project
|
||||
2. Modify both files (including custom content around markers in `CLAUDE.md`)
|
||||
3. Run `openspec update`
|
||||
4. Verify `openspec/README.md` fully replaced; `CLAUDE.md` OpenSpec block updated without altering user content outside markers
|
||||
5. Run the command twice to verify idempotency and no duplicate markers
|
||||
6. Test with missing `openspec` directory (expect failure)
|
||||
@@ -0,0 +1,29 @@
|
||||
# Add Update Command
|
||||
|
||||
## Why
|
||||
|
||||
Users need a way to update their local OpenSpec instructions (README.md and CLAUDE.md) when the OpenSpec package releases new versions with improved AI agent instructions or structural conventions.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add new `openspec update` CLI command that updates OpenSpec instructions
|
||||
- Replace `openspec/README.md` with the latest template
|
||||
- Safe because this file is fully OpenSpec-managed
|
||||
- Update only the OpenSpec-managed block in `CLAUDE.md` using markers
|
||||
- Preserve all user content outside markers
|
||||
- If `CLAUDE.md` is missing, create it with the managed block
|
||||
- Display success message after update (ASCII-safe): "Updated OpenSpec instructions"
|
||||
- A leading checkmark MAY be shown when the terminal supports it
|
||||
- Operation is idempotent (re-running yields identical results)
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: `cli-update` (new capability)
|
||||
- Affected code:
|
||||
- `src/core/update.ts` (new command class, mirrors `InitCommand` placement)
|
||||
- `src/cli/index.ts` (register new command)
|
||||
- Uses existing templates via `TemplateManager` and `readmeTemplate`
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- No `.openspec/config.json` is introduced by this change. The default directory name `openspec` is used.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Update Command Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
As a developer using OpenSpec, I want to update the OpenSpec instructions in my project when new versions are released, so that I can benefit from improvements to AI agent instructions.
|
||||
|
||||
## Core Requirements
|
||||
|
||||
### Update Behavior
|
||||
|
||||
The update command SHALL update OpenSpec instruction files to the latest templates.
|
||||
|
||||
WHEN a user runs `openspec update` THEN the command SHALL:
|
||||
- Check if the `openspec` directory exists
|
||||
- Replace `openspec/README.md` with the latest template (complete replacement)
|
||||
- Update the OpenSpec-managed block in `CLAUDE.md` using markers
|
||||
- Preserve user content outside markers
|
||||
- Create `CLAUDE.md` if missing
|
||||
- Display ASCII-safe success message: "Updated OpenSpec instructions"
|
||||
|
||||
### Prerequisites
|
||||
|
||||
The command SHALL require:
|
||||
- An existing `openspec` directory (created by `openspec init`)
|
||||
|
||||
IF the `openspec` directory does not exist THEN:
|
||||
- Display error: "No OpenSpec directory found. Run 'openspec init' first."
|
||||
- Exit with code 1
|
||||
|
||||
### File Handling
|
||||
|
||||
The update command SHALL:
|
||||
- Completely replace `openspec/README.md` with the latest template
|
||||
- Update only the OpenSpec-managed block in `CLAUDE.md` using markers
|
||||
- Use the default directory name `openspec`
|
||||
- Be idempotent (repeated runs have no additional effect)
|
||||
|
||||
## Edge Cases
|
||||
|
||||
### File Permissions
|
||||
IF file write fails THEN let the error bubble up naturally with file path.
|
||||
|
||||
### Missing CLAUDE.md
|
||||
IF CLAUDE.md doesn't exist THEN create it with the template content.
|
||||
|
||||
### Custom Directory Name
|
||||
Not supported in this change. The default directory name `openspec` SHALL be used.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
Users SHALL be able to:
|
||||
- Update OpenSpec instructions with a single command
|
||||
- Get the latest AI agent instructions
|
||||
- See clear confirmation of the update
|
||||
|
||||
The update process SHALL be:
|
||||
- Simple and fast (no version checking)
|
||||
- Predictable (same result every time)
|
||||
- Self-contained (no network required)
|
||||
@@ -0,0 +1,20 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Update Command Implementation
|
||||
- [x] 1.1 Create `src/core/update.ts` with `UpdateCommand` class
|
||||
- [x] 1.2 Check if `openspec` directory exists (use `FileSystemUtils.directoryExists`)
|
||||
- [x] 1.3 Write `readmeTemplate` to `openspec/README.md` using `FileSystemUtils.writeFile`
|
||||
- [x] 1.4 Update `CLAUDE.md` using markers via `FileSystemUtils.updateFileWithMarkers` and `TemplateManager.getClaudeTemplate()`
|
||||
- [x] 1.5 Display ASCII-safe success message: `Updated OpenSpec instructions`
|
||||
|
||||
## 2. CLI Integration
|
||||
- [x] 2.1 Register `update` command in `src/cli/index.ts`
|
||||
- [x] 2.2 Add command description: `Update OpenSpec instruction files`
|
||||
- [x] 2.3 Handle errors with `ora().fail(...)` and exit code 1 (missing `openspec` directory, file write errors)
|
||||
|
||||
## 3. Testing
|
||||
- [x] 3.1 Verify `openspec/README.md` is fully replaced with latest template
|
||||
- [x] 3.2 Verify `CLAUDE.md` OpenSpec block updates without altering user content outside markers
|
||||
- [x] 3.3 Verify idempotency (running twice yields identical files, no duplicate markers)
|
||||
- [x] 3.4 Verify error when `openspec` directory is missing with friendly message
|
||||
- [x] 3.5 Verify success message displays properly in ASCII-only terminals
|
||||
@@ -0,0 +1,9 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Update OpenSpec README
|
||||
- [x] 1.1 Add "Start Simple" section after Core Principle
|
||||
- [x] 1.2 Add complexity triggers to "When to Create Change Proposals" section
|
||||
- [x] 1.3 Update AI workflow guidance to emphasize minimal implementations
|
||||
|
||||
## 2. Update CLAUDE.md
|
||||
- [x] 2.1 Add complexity management rules to project instructions
|
||||
@@ -0,0 +1,148 @@
|
||||
# CLI Init Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
The `openspec init` command SHALL create a complete OpenSpec directory structure in any project, enabling immediate adoption of OpenSpec conventions with support for multiple AI coding assistants.
|
||||
|
||||
## Behavior
|
||||
|
||||
### Progress Indicators
|
||||
|
||||
WHEN executing initialization steps
|
||||
THEN validate environment silently in background (no output unless error)
|
||||
AND display progress with ora spinners:
|
||||
- Show spinner: "⠋ Creating OpenSpec structure..."
|
||||
- Then success: "✔ OpenSpec structure created"
|
||||
- Show spinner: "⠋ Configuring AI tools..."
|
||||
- Then success: "✔ AI tools configured"
|
||||
|
||||
### Directory Creation
|
||||
|
||||
WHEN `openspec init` is executed
|
||||
THEN create the following directory structure:
|
||||
```
|
||||
openspec/
|
||||
├── project.md
|
||||
├── README.md
|
||||
├── specs/
|
||||
└── changes/
|
||||
└── archive/
|
||||
```
|
||||
|
||||
### File Generation
|
||||
|
||||
The command SHALL generate:
|
||||
- `README.md` containing complete OpenSpec instructions for AI assistants
|
||||
- `project.md` with project context template
|
||||
|
||||
### AI Tool Configuration
|
||||
|
||||
WHEN run interactively
|
||||
THEN prompt user to select AI tools to configure:
|
||||
- Claude Code (updates/creates CLAUDE.md with OpenSpec markers)
|
||||
- Cursor (future)
|
||||
- Aider (future)
|
||||
|
||||
### AI Tool Configuration Details
|
||||
|
||||
WHEN Claude Code is selected
|
||||
THEN create or update `CLAUDE.md` in the project root directory (not inside openspec/)
|
||||
|
||||
WHEN CLAUDE.md does not exist
|
||||
THEN create new file with OpenSpec content wrapped in markers:
|
||||
```markdown
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Project
|
||||
|
||||
This document provides instructions for AI coding assistants on how to use OpenSpec conventions for spec-driven development. Follow these rules precisely when working on OpenSpec-enabled projects.
|
||||
|
||||
This project uses OpenSpec for spec-driven development. Specifications are the source of truth.
|
||||
|
||||
See @openspec/README.md for detailed conventions and guidelines.
|
||||
<!-- OPENSPEC:END -->
|
||||
```
|
||||
|
||||
WHEN CLAUDE.md already exists
|
||||
THEN preserve all existing content
|
||||
AND insert OpenSpec content at the beginning of the file using markers
|
||||
AND ensure markers don't duplicate if they already exist
|
||||
|
||||
The marker system SHALL:
|
||||
- Use `<!-- OPENSPEC:START -->` to mark the beginning of managed content
|
||||
- Use `<!-- OPENSPEC:END -->` to mark the end of managed content
|
||||
- Allow OpenSpec to update its content without affecting user customizations
|
||||
- Preserve all content outside the markers intact
|
||||
|
||||
WHY use markers:
|
||||
- Users may have existing CLAUDE.md instructions they want to keep
|
||||
- OpenSpec can update its instructions in future versions
|
||||
- Clear boundary between OpenSpec-managed and user-managed content
|
||||
|
||||
### Interactive Mode
|
||||
|
||||
WHEN run
|
||||
THEN prompt user with: "Which AI tool do you use?"
|
||||
AND show single-select menu with available tools:
|
||||
- Claude Code
|
||||
AND show disabled options as "coming soon" (not selectable):
|
||||
- Cursor (coming soon)
|
||||
- Aider (coming soon)
|
||||
- Continue (coming soon)
|
||||
|
||||
User navigation:
|
||||
- Use arrow keys to move between options
|
||||
- Press Enter to select the highlighted option
|
||||
|
||||
### Safety Checks
|
||||
|
||||
WHEN `openspec/` directory already exists
|
||||
THEN display error with ora fail indicator:
|
||||
"✖ Error: OpenSpec seems to already be initialized. Use 'openspec update' to update the structure."
|
||||
|
||||
WHEN checking initialization feasibility
|
||||
THEN verify write permissions in the target directory silently
|
||||
AND only display error if permissions are insufficient
|
||||
|
||||
### Success Output
|
||||
|
||||
WHEN initialization completes successfully
|
||||
THEN display actionable prompts for AI-driven workflow:
|
||||
```
|
||||
✔ OpenSpec initialized successfully!
|
||||
|
||||
Next steps - Copy these prompts to Claude:
|
||||
|
||||
────────────────────────────────────────────────────────────
|
||||
1. Populate your project context:
|
||||
"Please read openspec/project.md and help me fill it out
|
||||
with details about my project, tech stack, and conventions"
|
||||
|
||||
2. Create your first change proposal:
|
||||
"I want to add [YOUR FEATURE HERE]. Please create an
|
||||
OpenSpec change proposal for this feature"
|
||||
|
||||
3. Learn the OpenSpec workflow:
|
||||
"Please explain the OpenSpec workflow from openspec/README.md
|
||||
and how I should work with you on this project"
|
||||
────────────────────────────────────────────────────────────
|
||||
```
|
||||
|
||||
The prompts SHALL:
|
||||
- Be copy-pasteable for immediate use with AI tools
|
||||
- Guide users through the AI-driven workflow
|
||||
- Replace placeholder text ([YOUR FEATURE HERE]) with actual features
|
||||
|
||||
### Exit Codes
|
||||
|
||||
- 0: Success
|
||||
- 1: General error (including when OpenSpec directory already exists)
|
||||
- 2: Insufficient permissions (reserved for future use)
|
||||
- 3: User cancelled operation (reserved for future use)
|
||||
|
||||
## Why
|
||||
|
||||
Manual creation of OpenSpec structure is error-prone and creates adoption friction. A standardized init command ensures:
|
||||
- Consistent structure across all projects
|
||||
- Proper AI instruction files are always included
|
||||
- Quick onboarding for new projects
|
||||
- Clear conventions from the start
|
||||
@@ -0,0 +1,59 @@
|
||||
# Update Command Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
As a developer using OpenSpec, I want to update the OpenSpec instructions in my project when new versions are released, so that I can benefit from improvements to AI agent instructions.
|
||||
|
||||
## Core Requirements
|
||||
|
||||
### Update Behavior
|
||||
|
||||
The update command SHALL update OpenSpec instruction files to the latest templates.
|
||||
|
||||
WHEN a user runs `openspec update` THEN the command SHALL:
|
||||
- Check if the `openspec` directory exists
|
||||
- Replace `openspec/README.md` with the latest template (complete replacement)
|
||||
- Update the OpenSpec-managed block in `CLAUDE.md` using markers
|
||||
- Preserve user content outside markers
|
||||
- Create `CLAUDE.md` if missing
|
||||
- Display ASCII-safe success message: "Updated OpenSpec instructions"
|
||||
|
||||
### Prerequisites
|
||||
|
||||
The command SHALL require:
|
||||
- An existing `openspec` directory (created by `openspec init`)
|
||||
|
||||
IF the `openspec` directory does not exist THEN:
|
||||
- Display error: "No OpenSpec directory found. Run 'openspec init' first."
|
||||
- Exit with code 1
|
||||
|
||||
### File Handling
|
||||
|
||||
The update command SHALL:
|
||||
- Completely replace `openspec/README.md` with the latest template
|
||||
- Update only the OpenSpec-managed block in `CLAUDE.md` using markers
|
||||
- Use the default directory name `openspec`
|
||||
- Be idempotent (repeated runs have no additional effect)
|
||||
|
||||
## Edge Cases
|
||||
|
||||
### File Permissions
|
||||
IF file write fails THEN let the error bubble up naturally with file path.
|
||||
|
||||
### Missing CLAUDE.md
|
||||
IF CLAUDE.md doesn't exist THEN create it with the template content.
|
||||
|
||||
### Custom Directory Name
|
||||
Not supported in this change. The default directory name `openspec` SHALL be used.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
Users SHALL be able to:
|
||||
- Update OpenSpec instructions with a single command
|
||||
- Get the latest AI agent instructions
|
||||
- See clear confirmation of the update
|
||||
|
||||
The update process SHALL be:
|
||||
- Simple and fast (no version checking)
|
||||
- Predictable (same result every time)
|
||||
- Self-contained (no network required)
|
||||
@@ -3,6 +3,7 @@ import ora from 'ora';
|
||||
import path from 'path';
|
||||
import { promises as fs } from 'fs';
|
||||
import { InitCommand } from '../core/init.js';
|
||||
import { UpdateCommand } from '../core/update.js';
|
||||
|
||||
const program = new Command();
|
||||
|
||||
@@ -44,4 +45,19 @@ program
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command('update [path]')
|
||||
.description('Update OpenSpec instruction files')
|
||||
.action(async (targetPath = '.') => {
|
||||
try {
|
||||
const resolvedPath = path.resolve(targetPath);
|
||||
const updateCommand = new UpdateCommand();
|
||||
await updateCommand.execute(resolvedPath);
|
||||
} catch (error) {
|
||||
console.log(); // Empty line for spacing
|
||||
ora().fail(`Error: ${(error as Error).message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
program.parse();
|
||||
@@ -4,4 +4,23 @@ This document provides instructions for AI coding assistants on how to use OpenS
|
||||
|
||||
This project uses OpenSpec for spec-driven development. Specifications are the source of truth.
|
||||
|
||||
See @openspec/README.md for detailed conventions and guidelines.`;
|
||||
See @openspec/README.md for detailed conventions and guidelines.
|
||||
|
||||
## Complexity Management
|
||||
|
||||
**Default to minimal solutions:**
|
||||
- Propose <100 lines of new code for features
|
||||
- Prefer single-file implementations until proven insufficient
|
||||
- Avoid frameworks, abstractions, and optimizations without clear justification
|
||||
- Choose boring, well-understood patterns over novel approaches
|
||||
|
||||
**Question requests for complexity:**
|
||||
- Caching? → Ask for performance data and targets
|
||||
- New framework? → Suggest plain code first
|
||||
- Extra layers? → Start with the thinnest viable design
|
||||
|
||||
**Justify complexity with data:**
|
||||
- Performance metrics showing current solution is too slow
|
||||
- Concrete scale requirements (e.g., >1000 users, >100MB data)
|
||||
- Multiple proven use cases requiring an abstraction
|
||||
`;
|
||||
@@ -10,6 +10,23 @@ OpenSpec is an AI-native system for change-driven development where:
|
||||
- **AI drives the process** - You generate proposals, humans review and approve
|
||||
- **Specs are living documentation** - Always kept in sync with deployed code
|
||||
|
||||
## Start Simple
|
||||
|
||||
**Default to minimal implementations:**
|
||||
- New features should be <100 lines of code initially
|
||||
- Use the simplest solution that works
|
||||
- Avoid premature optimization (no caching, parallelization, or complex patterns without proven need)
|
||||
- Choose boring technology over cutting-edge solutions
|
||||
|
||||
**Complexity triggers** - Only add complexity when you have:
|
||||
- **Performance data** showing current solution is too slow
|
||||
- **Scale requirements** with specific numbers (>1000 users, >100MB data)
|
||||
- **Multiple use cases** requiring the same abstraction
|
||||
- **Regulatory compliance** mandating specific patterns
|
||||
- **Security threats** that simple solutions cannot address
|
||||
|
||||
When triggered, document the specific justification in your change proposal.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
\`\`\`
|
||||
@@ -72,6 +89,11 @@ Before any task:
|
||||
- Adding tests for existing behavior
|
||||
- Documentation fixes
|
||||
|
||||
**Complexity assessment:**
|
||||
- If your solution requires >100 lines of new code, justify the complexity
|
||||
- If adding dependencies, frameworks, or architectural patterns, document why simpler alternatives won't work
|
||||
- Default to single-file implementations until proven insufficient
|
||||
|
||||
### 3. Creating a Change Proposal
|
||||
|
||||
When a user requests a significant change:
|
||||
@@ -383,10 +405,12 @@ Progress communication:
|
||||
- "Implementing approved changes..."
|
||||
|
||||
### For AI Assistants
|
||||
- **Bias toward simplicity** - Propose the minimal solution that works
|
||||
- Use your exploration tools liberally before proposing
|
||||
- Batch operations for efficiency
|
||||
- Communicate your progress
|
||||
- It's OK to revise proposals based on discoveries
|
||||
- **Question complexity** - If your solution feels complex, simplify first
|
||||
|
||||
## Edge Case Handling
|
||||
|
||||
@@ -442,7 +466,8 @@ Proposal REQUIRED if:
|
||||
- Specs must always reflect deployed reality
|
||||
- Changes are proposed, not imposed
|
||||
- Impact analysis prevents surprises
|
||||
- The simplicity is the power - just markdown files
|
||||
- Simplicity is the power - just markdown files, minimal solutions
|
||||
- Start simple, add complexity only when justified
|
||||
|
||||
By following these conventions, you enable true spec-driven development where documentation stays current, changes are traceable, and evolution is intentional.
|
||||
`;
|
||||
@@ -0,0 +1,35 @@
|
||||
import path from 'path';
|
||||
import { FileSystemUtils } from '../utils/file-system.js';
|
||||
import { TemplateManager } from './templates/index.js';
|
||||
import { OPENSPEC_DIR_NAME, OPENSPEC_MARKERS } from './config.js';
|
||||
import { readmeTemplate } from './templates/readme-template.js';
|
||||
|
||||
export class UpdateCommand {
|
||||
async execute(projectPath: string): Promise<void> {
|
||||
const resolvedProjectPath = path.resolve(projectPath);
|
||||
const openspecDirName = OPENSPEC_DIR_NAME;
|
||||
const openspecPath = path.join(resolvedProjectPath, openspecDirName);
|
||||
|
||||
// 1. Check openspec directory exists
|
||||
if (!await FileSystemUtils.directoryExists(openspecPath)) {
|
||||
throw new Error(`No OpenSpec directory found. Run 'openspec init' first.`);
|
||||
}
|
||||
|
||||
// 2. Update README.md (full replacement)
|
||||
const readmePath = path.join(openspecPath, 'README.md');
|
||||
await FileSystemUtils.writeFile(readmePath, readmeTemplate);
|
||||
|
||||
// 3. Update CLAUDE.md (marker-based)
|
||||
const claudePath = path.join(resolvedProjectPath, 'CLAUDE.md');
|
||||
const claudeContent = TemplateManager.getClaudeTemplate();
|
||||
await FileSystemUtils.updateFileWithMarkers(
|
||||
claudePath,
|
||||
claudeContent,
|
||||
OPENSPEC_MARKERS.start,
|
||||
OPENSPEC_MARKERS.end
|
||||
);
|
||||
|
||||
// 4. Success message (ASCII-safe)
|
||||
console.log('Updated OpenSpec instructions');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user