Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions openspec/changes/add-diff-command/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Add Diff Command to OpenSpec CLI

## Why

Developers need to easily view differences between proposed spec changes and current specs without manually comparing files.

## What Changes

- Add `openspec diff [change-name]` command that shows differences between change specs and current specs
- Compare files in `changes/[change-name]/specs/` with corresponding files in `specs/`
- Display unified diff output showing added/removed/modified lines
- Support colored output for better readability

## Impact

- Affected specs: New capability `cli-diff` will be added
- Affected code:
- `src/cli/index.ts` - Add diff command
- `src/core/diff.ts` - New file with diff logic (~80 lines)
77 changes: 77 additions & 0 deletions openspec/changes/add-diff-command/specs/cli-diff/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# CLI Diff Command Specification

## Purpose

The `openspec diff` command provides developers with a visual comparison between proposed spec changes and the current deployed specs.

## Command Syntax

```bash
openspec diff [change-name]
```

## Behavior

### Without Arguments

WHEN running `openspec diff` without arguments
THEN list all available changes in the `changes/` directory (excluding archive)
AND prompt user to select a change

### With Change Name

WHEN running `openspec diff <change-name>`
THEN compare all spec files in `changes/<change-name>/specs/` with corresponding files in `specs/`

### Diff Output

FOR each spec file in the change:
- IF file exists in both locations THEN show unified diff
- IF file only exists in change THEN show as new file (all lines with +)
- IF file only exists in current specs THEN show as deleted (all lines with -)

### Display Format

The diff SHALL use standard unified diff format:
- Lines prefixed with `-` for removed content
- Lines prefixed with `+` for added content
- Lines without prefix for unchanged context
- File headers showing the paths being compared

### Color Support

WHEN terminal supports colors:
- Removed lines displayed in red
- Added lines displayed in green
- File headers displayed in bold
- Context lines in default color

### Error Handling

WHEN specified change doesn't exist THEN display error "Change '<name>' not found"
WHEN no specs directory in change THEN display "No spec changes found for '<name>'"
WHEN changes directory doesn't exist THEN display "No OpenSpec changes directory found"

## Examples

```bash
# View diff for specific change
$ openspec diff add-auth-feature

--- specs/user-auth/spec.md
+++ changes/add-auth-feature/specs/user-auth/spec.md
@@ -10,6 +10,8 @@
Users SHALL authenticate with email and password.

+Users MAY authenticate with OAuth providers.
+
WHEN credentials are valid THEN issue JWT token.

# List all changes and select
$ openspec diff
Available changes:
1. add-auth-feature
2. update-payment-flow
3. add-status-command
Select a change (1-3):
```
23 changes: 23 additions & 0 deletions openspec/changes/add-diff-command/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Implementation Tasks

## 1. Core Implementation
- [x] 1.1 Create `src/core/diff.ts` with diff logic
- [x] 1.2 Implement change directory scanning
- [x] 1.3 Implement file comparison using unified diff format
- [x] 1.4 Add color support for terminal output

## 2. CLI Integration
- [x] 2.1 Add diff command to `src/cli/index.ts`
- [x] 2.2 Implement interactive change selection when no argument provided
- [x] 2.3 Add error handling for missing changes

## 3. Enhancements
- [x] 3.1 Replace with jest-diff for professional diff output
- [x] 3.2 Improve file headers with status and statistics
- [x] 3.3 Add summary view with file counts and line changes

## 4. Testing
- [ ] 4.1 Test diff generation for modified files
- [ ] 4.2 Test handling of new files
- [ ] 4.3 Test handling of deleted files
- [ ] 4.4 Test interactive mode
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@
},
"dependencies": {
"@inquirer/prompts": "^7.8.0",
"chalk": "^5.5.0",
"commander": "^14.0.0",
"jest-diff": "^30.0.5",
"ora": "^8.2.0"
}
}
86 changes: 86 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'path';
import { promises as fs } from 'fs';
import { InitCommand } from '../core/init.js';
import { UpdateCommand } from '../core/update.js';
import { DiffCommand } from '../core/diff.js';

const program = new Command();

Expand Down Expand Up @@ -60,4 +61,18 @@ program
}
});

program
.command('diff [change-name]')
.description('Show differences between proposed spec changes and current specs')
.action(async (changeName?: string) => {
try {
const diffCommand = new DiffCommand();
await diffCommand.execute(changeName);
} catch (error) {
console.log(); // Empty line for spacing
ora().fail(`Error: ${(error as Error).message}`);
process.exit(1);
}
});

program.parse();
Loading