Skip to content

Commit fb7ff52

Browse files
authored
proposal: add artifact workflow CLI commands (Slice 4) (#415)
* proposal: add artifact workflow CLI commands (Slice 4) Add CLI commands for artifact workflow operations: - `openspec status --change <id>` - Show artifact completion state - `openspec next --change <id>` - Show ready artifacts - `openspec instructions <artifact> --change <id>` - Get enriched template - `openspec templates --change <id>` - Show template paths - `openspec new change <name>` - Create new change Commands are top-level for fluid UX and implemented in isolation for easy removal (experimental feature). * fix: remove --change from templates command Templates are schema-level, not change-level. The command now uses --schema instead of --change for consistency with how templates are actually resolved. * rename: cli-workflow -> cli-artifact-workflow More specific capability name that clarifies which workflow the CLI commands are for. * feat: implement artifact workflow CLI commands (Slice 4) Add experimental CLI commands for artifact-based workflow management: - `openspec status --change <id>` - display artifact completion status - `openspec next --change <id>` - show artifacts ready to create - `openspec instructions <artifact> --change <id>` - output enriched template - `openspec templates [--schema <name>]` - show resolved template paths - `openspec new change <name>` - create new change directory Features: - JSON output support (--json flag) for all commands - Color-coded status indicators (green/yellow/red) - Progress spinners during loading - --no-color and NO_COLOR env support - --schema option for custom schema selection - Comprehensive error handling with helpful messages All commands are isolated in src/commands/artifact-workflow.ts for easy removal if the feature doesn't work out. Help text marks them as experimental. * fix: update specs glob to match nested directory structure The schema used specs/*.md but specs are stored as specs/<capability>/spec.md. Updated to specs/**/*.md so openspec status/next correctly detect spec completion. * test: update test to match new specs glob pattern * chore: archive add-artifact-workflow-cli change - Move change to archive/2025-12-28-add-artifact-workflow-cli - Create cli-artifact-workflow spec * feat: unify change state model for scaffolded changes - Update artifact workflow commands to work with scaffolded changes - Add draft changes section to dashboard view - Fix completed changes to require tasks.total > 0 - Archive unify-change-state-model change * fix: validate change name format to prevent path traversal Add validation in validateChangeExists() to ensure --change parameter is a valid kebab-case ID before constructing file paths. This prevents path traversal attacks like --change "../foo" or --change "/etc/passwd". - Reuses existing validateChangeName() from change-utils.ts - Adds 3 tests for path traversal, absolute paths, and slashes
1 parent 11e1955 commit fb7ff52

File tree

18 files changed

+2102
-28
lines changed

18 files changed

+2102
-28
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
## Context
2+
3+
Slice 4 of the artifact workflow POC. The core functionality (ArtifactGraph, InstructionLoader, change-utils) is complete. This slice adds CLI commands to expose the artifact workflow to users.
4+
5+
**Key constraint**: This is experimental. Commands must be isolated for easy removal if the feature doesn't work out.
6+
7+
## Goals / Non-Goals
8+
9+
- **Goals:**
10+
- Expose artifact workflow status and instructions via CLI
11+
- Provide fluid UX with top-level verb commands
12+
- Support both human-readable and JSON output
13+
- Enable agents to programmatically query workflow state
14+
- Keep implementation isolated for easy removal
15+
16+
- **Non-Goals:**
17+
- Interactive artifact creation wizards (future work)
18+
- Schema management commands (deferred)
19+
- Auto-detection of active change (CLI is deterministic, agents infer)
20+
21+
## Decisions
22+
23+
### Command Structure: Top-Level Verbs
24+
25+
Commands are top-level for maximum fluidity:
26+
27+
```
28+
openspec status --change <id>
29+
openspec next --change <id>
30+
openspec instructions <artifact> --change <id>
31+
openspec templates [--schema <name>]
32+
openspec new change <name>
33+
```
34+
35+
**Rationale:**
36+
- Most fluid UX - fewest keystrokes
37+
- Commands are unique enough to avoid conflicts
38+
- Simple mental model for users
39+
40+
**Trade-off accepted:** Slight namespace pollution, but commands are distinct and can be removed cleanly.
41+
42+
### Experimental Isolation
43+
44+
All artifact workflow commands are implemented in a single file:
45+
46+
```
47+
src/commands/artifact-workflow.ts
48+
```
49+
50+
**To remove the feature:**
51+
1. Delete `src/commands/artifact-workflow.ts`
52+
2. Remove ~5 lines from `src/cli/index.ts`
53+
54+
No other files touched, no risk to stable functionality.
55+
56+
### Deterministic CLI with Explicit `--change`
57+
58+
All change-specific commands require `--change <id>`:
59+
60+
```bash
61+
openspec status --change add-auth # explicit, works
62+
openspec status # error: missing --change
63+
```
64+
65+
**Rationale:**
66+
- CLI is pure, testable, no hidden state
67+
- Agents infer change from conversation and pass explicitly
68+
- No config file tracking "active change"
69+
- Consistent with POC design philosophy
70+
71+
### New Change Command Structure
72+
73+
Creating changes uses explicit subcommand:
74+
75+
```bash
76+
openspec new change add-feature
77+
```
78+
79+
**Rationale:**
80+
- `openspec new <name>` is ambiguous (new what?)
81+
- `openspec new change <name>` is clear and extensible
82+
- Can add `openspec new spec <name>` later if needed
83+
84+
### Output Formats
85+
86+
- **Default**: Human-readable text with visual indicators
87+
- Status: `[x]` done, `[ ]` ready, `[-]` blocked
88+
- Colors: green (done), yellow (ready), red (blocked)
89+
- **JSON** (`--json`): Machine-readable for scripts and agents
90+
91+
### Error Handling
92+
93+
- Missing `--change`: Error listing available changes
94+
- Unknown change: Error with suggestion
95+
- Unknown artifact: Error listing valid artifacts
96+
- Missing schema: Error with schema resolution details
97+
98+
## Risks / Trade-offs
99+
100+
| Risk | Mitigation |
101+
|------|------------|
102+
| Top-level commands pollute namespace | Commands are distinct; isolated for easy removal |
103+
| `status` confused with git | Context (`--change`) makes it clear |
104+
| Feature doesn't work out | Single file deletion removes everything |
105+
106+
## Implementation Notes
107+
108+
- All commands in `src/commands/artifact-workflow.ts`
109+
- Imports from `src/core/artifact-graph/` for all operations
110+
- Uses `getActiveChangeIds()` from `item-discovery.ts` for change listing
111+
- Follows existing CLI patterns (ora spinners, commander.js options)
112+
- Help text marks commands as "Experimental"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
## Why
2+
3+
The ArtifactGraph (Slice 1) and InstructionLoader (Slice 3) provide programmatic APIs for artifact-based workflow management. Users currently have no CLI interface to:
4+
- See artifact completion status for a change
5+
- Discover what artifacts are ready to create
6+
- Get enriched instructions for creating artifacts
7+
- Create new changes with proper validation
8+
9+
This proposal adds CLI commands that expose the artifact workflow functionality to users and agents.
10+
11+
## What Changes
12+
13+
- **NEW**: `openspec status --change <id>` shows artifact completion state
14+
- **NEW**: `openspec next --change <id>` shows artifacts ready to create
15+
- **NEW**: `openspec instructions <artifact> --change <id>` outputs enriched template
16+
- **NEW**: `openspec templates [--schema <name>]` shows resolved template paths
17+
- **NEW**: `openspec new change <name>` creates a new change directory
18+
19+
All commands are top-level for fluid UX. They integrate with existing core modules:
20+
- Uses `loadChangeContext()`, `formatChangeStatus()`, `generateInstructions()` from instruction-loader
21+
- Uses `ArtifactGraph`, `detectCompleted()` from artifact-graph
22+
- Uses `createChange()`, `validateChangeName()` from change-utils
23+
24+
**Experimental isolation**: All commands are implemented in a single file (`src/commands/artifact-workflow.ts`) for easy removal if the feature doesn't work out. Help text marks them as experimental.
25+
26+
## Impact
27+
28+
- Affected specs: NEW `cli-artifact-workflow` capability
29+
- Affected code:
30+
- `src/cli/index.ts` - register new commands
31+
- `src/commands/artifact-workflow.ts` - new command implementations
32+
- No changes to existing commands or specs
33+
- Builds on completed Slice 1, 2, and 3 implementations
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# cli-artifact-workflow Specification
2+
3+
## Purpose
4+
CLI commands for artifact workflow operations, exposing the artifact graph and instruction loader functionality to users and agents. Commands are top-level for fluid UX and implemented in isolation for easy removal.
5+
6+
## ADDED Requirements
7+
8+
### Requirement: Status Command
9+
The system SHALL display artifact completion status for a change.
10+
11+
#### Scenario: Show status with all states
12+
- **WHEN** user runs `openspec status --change <id>`
13+
- **THEN** the system displays each artifact with status indicator:
14+
- `[x]` for completed artifacts
15+
- `[ ]` for ready artifacts
16+
- `[-]` for blocked artifacts (with missing dependencies listed)
17+
18+
#### Scenario: Status shows completion summary
19+
- **WHEN** user runs `openspec status --change <id>`
20+
- **THEN** output includes completion percentage and count (e.g., "2/4 artifacts complete")
21+
22+
#### Scenario: Status JSON output
23+
- **WHEN** user runs `openspec status --change <id> --json`
24+
- **THEN** the system outputs JSON with changeName, schemaName, isComplete, and artifacts array
25+
26+
#### Scenario: Missing change parameter
27+
- **WHEN** user runs `openspec status` without `--change`
28+
- **THEN** the system displays an error with list of available changes
29+
30+
#### Scenario: Unknown change
31+
- **WHEN** user runs `openspec status --change unknown-id`
32+
- **THEN** the system displays an error indicating the change does not exist
33+
34+
### Requirement: Next Command
35+
The system SHALL show which artifacts are ready to be created.
36+
37+
#### Scenario: Show ready artifacts
38+
- **WHEN** user runs `openspec next --change <id>`
39+
- **THEN** the system lists artifacts whose dependencies are all satisfied
40+
41+
#### Scenario: No artifacts ready
42+
- **WHEN** all artifacts are either completed or blocked
43+
- **THEN** the system indicates no artifacts are ready (with explanation)
44+
45+
#### Scenario: All artifacts complete
46+
- **WHEN** all artifacts in the change are completed
47+
- **THEN** the system indicates the change is complete
48+
49+
#### Scenario: Next JSON output
50+
- **WHEN** user runs `openspec next --change <id> --json`
51+
- **THEN** the system outputs JSON array of ready artifact IDs
52+
53+
### Requirement: Instructions Command
54+
The system SHALL output enriched instructions for creating an artifact.
55+
56+
#### Scenario: Show enriched instructions
57+
- **WHEN** user runs `openspec instructions <artifact> --change <id>`
58+
- **THEN** the system outputs:
59+
- Artifact metadata (ID, output path, description)
60+
- Template content
61+
- Dependency status (done/missing)
62+
- Unlocked artifacts (what becomes available after completion)
63+
64+
#### Scenario: Instructions JSON output
65+
- **WHEN** user runs `openspec instructions <artifact> --change <id> --json`
66+
- **THEN** the system outputs JSON matching ArtifactInstructions interface
67+
68+
#### Scenario: Unknown artifact
69+
- **WHEN** user runs `openspec instructions unknown-artifact --change <id>`
70+
- **THEN** the system displays an error listing valid artifact IDs for the schema
71+
72+
#### Scenario: Artifact with unmet dependencies
73+
- **WHEN** user requests instructions for a blocked artifact
74+
- **THEN** the system displays instructions with a warning about missing dependencies
75+
76+
### Requirement: Templates Command
77+
The system SHALL show resolved template paths for all artifacts in a schema.
78+
79+
#### Scenario: List template paths with default schema
80+
- **WHEN** user runs `openspec templates`
81+
- **THEN** the system displays each artifact with its resolved template path using the default schema
82+
83+
#### Scenario: List template paths with custom schema
84+
- **WHEN** user runs `openspec templates --schema tdd`
85+
- **THEN** the system displays template paths for the specified schema
86+
87+
#### Scenario: Templates JSON output
88+
- **WHEN** user runs `openspec templates --json`
89+
- **THEN** the system outputs JSON mapping artifact IDs to template paths
90+
91+
#### Scenario: Template resolution source
92+
- **WHEN** displaying template paths
93+
- **THEN** the system indicates whether each template is from user override or package built-in
94+
95+
### Requirement: New Change Command
96+
The system SHALL create new change directories with validation.
97+
98+
#### Scenario: Create valid change
99+
- **WHEN** user runs `openspec new change add-feature`
100+
- **THEN** the system creates `openspec/changes/add-feature/` directory
101+
102+
#### Scenario: Invalid change name
103+
- **WHEN** user runs `openspec new change "Add Feature"` with invalid name
104+
- **THEN** the system displays validation error with guidance
105+
106+
#### Scenario: Duplicate change name
107+
- **WHEN** user runs `openspec new change existing-change` for an existing change
108+
- **THEN** the system displays an error indicating the change already exists
109+
110+
#### Scenario: Create with description
111+
- **WHEN** user runs `openspec new change add-feature --description "Add new feature"`
112+
- **THEN** the system creates the change directory with description in README.md
113+
114+
### Requirement: Schema Selection
115+
The system SHALL support custom schema selection for workflow commands.
116+
117+
#### Scenario: Default schema
118+
- **WHEN** user runs workflow commands without `--schema`
119+
- **THEN** the system uses the "spec-driven" schema
120+
121+
#### Scenario: Custom schema
122+
- **WHEN** user runs `openspec status --change <id> --schema tdd`
123+
- **THEN** the system uses the specified schema for artifact graph
124+
125+
#### Scenario: Unknown schema
126+
- **WHEN** user specifies an unknown schema
127+
- **THEN** the system displays an error listing available schemas
128+
129+
### Requirement: Output Formatting
130+
The system SHALL provide consistent output formatting.
131+
132+
#### Scenario: Color output
133+
- **WHEN** terminal supports colors
134+
- **THEN** status indicators use colors: green (done), yellow (ready), red (blocked)
135+
136+
#### Scenario: No color output
137+
- **WHEN** `--no-color` flag is used or NO_COLOR environment variable is set
138+
- **THEN** output uses text-only indicators without ANSI colors
139+
140+
#### Scenario: Progress indication
141+
- **WHEN** loading change state takes time
142+
- **THEN** the system displays a spinner during loading
143+
144+
### Requirement: Experimental Isolation
145+
The system SHALL implement artifact workflow commands in isolation for easy removal.
146+
147+
#### Scenario: Single file implementation
148+
- **WHEN** artifact workflow feature is implemented
149+
- **THEN** all commands are in `src/commands/artifact-workflow.ts`
150+
151+
#### Scenario: Help text marking
152+
- **WHEN** user runs `--help` on any artifact workflow command
153+
- **THEN** help text indicates the command is experimental
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
## 1. Core Command Implementation
2+
3+
- [x] 1.1 Create `src/commands/artifact-workflow.ts` with all commands
4+
- [x] 1.2 Implement `status` command with text output
5+
- [x] 1.3 Implement `next` command with text output
6+
- [x] 1.4 Implement `instructions` command with text output
7+
- [x] 1.5 Implement `templates` command with text output
8+
- [x] 1.6 Implement `new change` subcommand using createChange()
9+
10+
## 2. CLI Registration
11+
12+
- [x] 2.1 Register `status` command in `src/cli/index.ts`
13+
- [x] 2.2 Register `next` command in `src/cli/index.ts`
14+
- [x] 2.3 Register `instructions` command in `src/cli/index.ts`
15+
- [x] 2.4 Register `templates` command in `src/cli/index.ts`
16+
- [x] 2.5 Register `new` command group with `change` subcommand
17+
18+
## 3. Output Formatting
19+
20+
- [x] 3.1 Add `--json` flag support to all commands
21+
- [x] 3.2 Add color-coded status indicators (done/ready/blocked)
22+
- [x] 3.3 Add progress spinner for loading operations
23+
- [x] 3.4 Support `--no-color` flag
24+
25+
## 4. Error Handling
26+
27+
- [x] 4.1 Handle missing `--change` parameter with helpful error
28+
- [x] 4.2 Handle unknown change names with list of available changes
29+
- [x] 4.3 Handle unknown artifact names with valid options
30+
- [x] 4.4 Handle schema resolution errors
31+
32+
## 5. Options and Flags
33+
34+
- [x] 5.1 Add `--schema` option for custom schema selection
35+
- [x] 5.2 Add `--description` option to `new change` command
36+
- [x] 5.3 Ensure options follow existing CLI patterns
37+
38+
## 6. Testing
39+
40+
- [x] 6.1 Add smoke tests for each command
41+
- [x] 6.2 Test error cases (missing change, unknown artifact)
42+
- [x] 6.3 Test JSON output format
43+
- [x] 6.4 Test with different schemas
44+
45+
## 7. Documentation
46+
47+
- [x] 7.1 Add help text for all commands marked as "Experimental"
48+
- [ ] 7.2 Update AGENTS.md with new commands (post-archive)

0 commit comments

Comments
 (0)