mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-09-14 20:16:53 +08:00
3.0 KiB
3.0 KiB
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
readmeTemplatefromsrc/core/templates/readme-template.tsforopenspec/README.mdTemplateManager.getClaudeTemplate()forCLAUDE.md
- Directory name is fixed to
openspec(fromOPENSPEC_DIR_NAME)
File Operations
- Use async utilities for consistency
FileSystemUtils.writeFileforopenspec/README.mdFileSystemUtils.updateFileWithMarkersforCLAUDE.md
- No atomic operations needed - users have git
- Check directory existence before proceeding
Implementation
Update Command (src/core/update.ts)
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
openspecdirectory → 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:
- Run
openspec initin a test project - Modify both files (including custom content around markers in
CLAUDE.md) - Run
openspec update - Verify
openspec/README.mdfully replaced;CLAUDE.mdOpenSpec block updated without altering user content outside markers - Run the command twice to verify idempotency and no duplicate markers
- Test with missing
openspecdirectory (expect failure)