mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-04 06:18:24 +08:00
Compare commits
468
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37686944a9 | ||
|
|
53081fb2a2 | ||
|
|
5e2e02c090 | ||
|
|
a3cee3c2f2 | ||
|
|
f27e5e809a | ||
|
|
6b545f6ebb | ||
|
|
661059b54f | ||
|
|
ddbfa529f4 | ||
|
|
d3c3d66e67 | ||
|
|
277be194ef | ||
|
|
f45ba73a5f | ||
|
|
41305753b4 | ||
|
|
86d2e04cae | ||
|
|
f6b415cb9b | ||
|
|
e91568deb9 | ||
|
|
fc0d798f93 | ||
|
|
d155126235 | ||
|
|
943e0d4102 | ||
|
|
12a7224dc6 | ||
|
|
c773ef6feb | ||
|
|
0bfe1d4426 | ||
|
|
0e6f42c81c | ||
|
|
0cc9d9025a | ||
|
|
3261ccf6dc | ||
|
|
26ed336a16 | ||
|
|
847aa81c0f | ||
|
|
39bebefcc4 | ||
|
|
cf8b6212c8 | ||
|
|
c157483685 | ||
|
|
f90c7c3354 | ||
|
|
9381bd3b24 | ||
|
|
ae83b4e16d | ||
|
|
d48528134b | ||
|
|
54bd3f1ccd | ||
|
|
675e870bf1 | ||
|
|
07eaf7b691 | ||
|
|
153721d14a | ||
|
|
70c2e17525 | ||
|
|
e2c333e493 | ||
|
|
e137dd3981 | ||
|
|
2beb8e77e8 | ||
|
|
3b16b13613 | ||
|
|
c4cfdc7c49 | ||
|
|
e0736807b4 | ||
|
|
fdb05a723e | ||
|
|
8332a09811 | ||
|
|
d61a49f6d5 | ||
|
|
7d1237f00d | ||
|
|
33466b1e2a | ||
|
|
6c8c778043 | ||
|
|
43b01ad374 | ||
|
|
3cdcdfca8e | ||
|
|
32fc19a60d | ||
|
|
84f372517f | ||
|
|
adda63e17a | ||
|
|
90d05b7115 | ||
|
|
20714c1c28 | ||
|
|
2e51ae26d3 | ||
|
|
dbd4ed7bfb | ||
|
|
473093f885 | ||
|
|
b5a884748b | ||
|
|
690c75225c | ||
|
|
dd53fb7736 | ||
|
|
2a441c472d | ||
|
|
ed4d965208 | ||
|
|
c86985d6ec | ||
|
|
bf4bc2426f | ||
|
|
c57e421cc2 | ||
|
|
ed2e832066 | ||
|
|
9db74aa5ac | ||
|
|
b5b7248610 | ||
|
|
322bfd455a | ||
|
|
08c349369a | ||
|
|
40afee643e | ||
|
|
05023dab43 | ||
|
|
d7a928b4e9 | ||
|
|
07dd634986 | ||
|
|
36078b1947 | ||
|
|
d0e1b076c2 | ||
|
|
2fbda520de | ||
|
|
5633556b6d | ||
|
|
2bb0ed36c5 | ||
|
|
06097f9cb7 | ||
|
|
8f5a526396 | ||
|
|
eb152eb2ca | ||
|
|
e987a5a327 | ||
|
|
4971cda812 | ||
|
|
4715138927 | ||
|
|
940898c1c5 | ||
|
|
d49a88c3bb | ||
|
|
bb9f6ce0ea | ||
|
|
ae85a7229d | ||
|
|
504c93bdf1 | ||
|
|
c4a54a8d54 | ||
|
|
38d2356836 | ||
|
|
3f67debf65 | ||
|
|
533cb0fa87 | ||
|
|
8dfd824477 | ||
|
|
3ed1270316 | ||
|
|
eb15cdb983 | ||
|
|
cd172a4427 | ||
|
|
b7f5a429de | ||
|
|
a5c10ed5e7 | ||
|
|
1bc849554c | ||
|
|
d73705736f | ||
|
|
ed924ffcff | ||
|
|
1786684af6 | ||
|
|
51fb10db5e | ||
|
|
cac54042ce | ||
|
|
c47cdaafe2 | ||
|
|
ea5aa0e562 | ||
|
|
48b5ed9657 | ||
|
|
fb7ff527a6 | ||
|
|
11e195575f | ||
|
|
ab47cc6b00 | ||
|
|
8dcd1707ee | ||
|
|
4f4af5708d | ||
|
|
9822576770 | ||
|
|
af273b8e0b | ||
|
|
3ceef2db72 | ||
|
|
2c2599b1f0 | ||
|
|
c08a53cb21 | ||
|
|
455c65f3c4 | ||
|
|
9ac6330430 | ||
|
|
fb264bcbcd | ||
|
|
a2757e7856 | ||
|
|
6d84924c18 | ||
|
|
6de04f3b2b | ||
|
|
c2a1a4c807 | ||
|
|
2e71835d23 | ||
|
|
971f8ca4a3 | ||
|
|
68e0a7e68e | ||
|
|
f39cc5c1fb | ||
|
|
5129a8cf96 | ||
|
|
4ff893048d | ||
|
|
cefb4719aa | ||
|
|
5e1cef3b3b | ||
|
|
1adf3cea88 | ||
|
|
6d3cfe0443 | ||
|
|
17d1e5db3f | ||
|
|
3f5a66d3e4 | ||
|
|
c08fbc1ba0 | ||
|
|
938d03be9a | ||
|
|
19ccaabfc7 | ||
|
|
2e382b9898 | ||
|
|
b5a7d096f0 | ||
|
|
c54079a0cd | ||
|
|
1050e57ae4 | ||
|
|
17d7e59343 | ||
|
|
4758c5c68d | ||
|
|
c4b0826da7 | ||
|
|
537e6078b7 | ||
|
|
5439ab0833 | ||
|
|
9b6a763eb8 | ||
|
|
d32e50fe36 | ||
|
|
8386b91a71 | ||
|
|
8f9c3c7d0b | ||
|
|
9cdb0743f2 | ||
|
|
4e93d7a881 | ||
|
|
c4b6be41c1 | ||
|
|
a66580735c | ||
|
|
fb1d37e56e | ||
|
|
cf0de5e569 | ||
|
|
92b45462c6 | ||
|
|
5ab438f5fd | ||
|
|
5855fa2353 | ||
|
|
668a125d4d | ||
|
|
fef961f6e3 | ||
|
|
3677e0175f | ||
|
|
3ddf2586b4 | ||
|
|
ece61a6d68 | ||
|
|
ecddffc22e | ||
|
|
822464ec44 | ||
|
|
67ab683105 | ||
|
|
f82e243551 | ||
|
|
88b260d51f | ||
|
|
ce7422209f | ||
|
|
63b8a3e9f9 | ||
|
|
4cf7bf863d | ||
|
|
b30882b579 | ||
|
|
082abb4795 | ||
|
|
b81fa1e6cc | ||
|
|
4a863285b0 | ||
|
|
fe83be5d61 | ||
|
|
345f9dbb45 | ||
|
|
cc9d5402ff | ||
|
|
108bcd66d8 | ||
|
|
a50105e03c | ||
|
|
312e1d6d7c | ||
|
|
56d57da119 | ||
|
|
f56189a8f7 | ||
|
|
d7e0ce85e5 | ||
|
|
eb0d50c094 | ||
|
|
c482f1b47a | ||
|
|
2ae0484ac7 | ||
|
|
8c65b47abe | ||
|
|
9c9e57daa1 | ||
|
|
c7ca76cb4f | ||
|
|
06bd3999bf | ||
|
|
821097079a | ||
|
|
42e3118b0c | ||
|
|
a785c2a99a | ||
|
|
af513191eb | ||
|
|
efbbf3b9f1 | ||
|
|
6105211163 | ||
|
|
b3d31d224d | ||
|
|
9ae6141eb1 | ||
|
|
d84069a3ae | ||
|
|
8c974f8a80 | ||
|
|
25289b510d | ||
|
|
d070d08aa8 | ||
|
|
6539ceb54a | ||
|
|
c29b06da42 | ||
|
|
4a2b23942c | ||
|
|
807b9d32a6 | ||
|
|
b3d05d2f78 | ||
|
|
9848242587 | ||
|
|
5e0d21d1ed | ||
|
|
31d85d0e8b | ||
|
|
bc3666d702 | ||
|
|
970b9f6e2d | ||
|
|
5cb84a775e | ||
|
|
adc63069a9 | ||
|
|
f8eca37796 | ||
|
|
a908dc5a05 | ||
|
|
b46f99b9bc | ||
|
|
6f7cc2abd2 | ||
|
|
4867bfade5 | ||
|
|
7359b4846a | ||
|
|
88526e6b93 | ||
|
|
367aa12892 | ||
|
|
dcfb6afe0c | ||
|
|
86925b2b2d | ||
|
|
604ecb8bd1 | ||
|
|
5a4837c37d | ||
|
|
9d9539aaa2 | ||
|
|
c3fecf0619 | ||
|
|
6469593495 | ||
|
|
157936cf68 | ||
|
|
fef33df753 | ||
|
|
78b61e8466 | ||
|
|
5fa0fa68a7 | ||
|
|
fe9eb44ec2 | ||
|
|
ee78f21b08 | ||
|
|
e3ae2ceaf0 | ||
|
|
20b2fee749 | ||
|
|
e7fff31df2 | ||
|
|
fdf9a30f0b | ||
|
|
161aa41cb3 | ||
|
|
9e092a185b | ||
|
|
38454bb2a6 | ||
|
|
b04f1cc923 | ||
|
|
ae86e9be9e | ||
|
|
f955e87fd9 | ||
|
|
55efd19953 | ||
|
|
dab5d93b85 | ||
|
|
7b0f494754 | ||
|
|
dd7ba71fe5 | ||
|
|
66ad5658f9 | ||
|
|
21a0e74b74 | ||
|
|
485ef07ec7 | ||
|
|
ce5ceadbe7 | ||
|
|
9a173b917c | ||
|
|
79baabbed1 | ||
|
|
818a5922ce | ||
|
|
d8d2930182 | ||
|
|
6af6e0ccb6 | ||
|
|
50e6660018 | ||
|
|
4bbb52dda4 | ||
|
|
4a0ae49b6e | ||
|
|
5b2049aedf | ||
|
|
332020ac6b | ||
|
|
646c516b0d | ||
|
|
8c1b580f03 | ||
|
|
17e6f7166b | ||
|
|
931d10477e | ||
|
|
e4548bcc58 | ||
|
|
68fc049955 | ||
|
|
4874a16495 | ||
|
|
3caabf86cf | ||
|
|
d4593e4a54 | ||
|
|
0144ec2b1b | ||
|
|
98d90cc00d | ||
|
|
ccaa5ad0b0 | ||
|
|
8eb7ebd7cd | ||
|
|
be395d9d74 | ||
|
|
a09b87e391 | ||
|
|
9d7b44b722 | ||
|
|
44c06cc40e | ||
|
|
b33f435812 | ||
|
|
b62b57caf3 | ||
|
|
758d91613d | ||
|
|
47180e5120 | ||
|
|
8dde1d55fc | ||
|
|
3cef6f0925 | ||
|
|
82ba1f504e | ||
|
|
d54fcc97f2 | ||
|
|
ebff738860 | ||
|
|
1bdaeef4da | ||
|
|
2921676e93 | ||
|
|
792129bfe3 | ||
|
|
715ff513e3 | ||
|
|
f6913b7661 | ||
|
|
730bbc00af | ||
|
|
adfcc65b9f | ||
|
|
590541277d | ||
|
|
14e2cc628a | ||
|
|
299171c5cb | ||
|
|
bb6aae0205 | ||
|
|
23c0ab6358 | ||
|
|
02fe5b3547 | ||
|
|
57216a7824 | ||
|
|
6e210cf084 | ||
|
|
5c6ae8e407 | ||
|
|
5376030421 | ||
|
|
7d735eb2d8 | ||
|
|
4d55e9ac6d | ||
|
|
9d674b22a3 | ||
|
|
96458ced1f | ||
|
|
3d8f2a5974 | ||
|
|
006676c973 | ||
|
|
63f45c0fcf | ||
|
|
522126a6ee | ||
|
|
23b8030494 | ||
|
|
f70df96656 | ||
|
|
df12368f11 | ||
|
|
acd1ca28f3 | ||
|
|
aedf4a34af | ||
|
|
f0c52ac7e8 | ||
|
|
f933e9b144 | ||
|
|
24b4866426 | ||
|
|
b7899602b4 | ||
|
|
b66d914198 | ||
|
|
9926103505 | ||
|
|
873e45a996 | ||
|
|
573afa0c65 | ||
|
|
665d740adb | ||
|
|
c35dd38567 | ||
|
|
aa9e49612b | ||
|
|
36eb0bbbf5 | ||
|
|
d549cec121 | ||
|
|
1a3bfae784 | ||
|
|
fae08072a9 | ||
|
|
07df6c97c9 | ||
|
|
7b13a2de03 | ||
|
|
41fc14d360 | ||
|
|
7c0face31b | ||
|
|
332816cc35 | ||
|
|
7ced2a8791 | ||
|
|
a79b8b5c03 | ||
|
|
52d620e40e | ||
|
|
22082338fd | ||
|
|
6458b6ed39 | ||
|
|
01a2f5d600 | ||
|
|
95d855d641 | ||
|
|
562530dfa8 | ||
|
|
1e17cfdd0b | ||
|
|
5d185ba3a8 | ||
|
|
08b41c7bea | ||
|
|
8ac50289f0 | ||
|
|
1f295cec52 | ||
|
|
ad8e213cf9 | ||
|
|
a6c1a90165 | ||
|
|
21b5a3e680 | ||
|
|
1bda5be96c | ||
|
|
0faf44807e | ||
|
|
f9c1d07edb | ||
|
|
2bd1a4417c | ||
|
|
1db19ac3d8 | ||
|
|
25018786e4 | ||
|
|
5fd9173ad9 | ||
|
|
0a611747bc | ||
|
|
49e422724f | ||
|
|
c22d6bce1c | ||
|
|
1c0dc09dc9 | ||
|
|
f0b1e00c65 | ||
|
|
5fe72ddc5d | ||
|
|
c18f3b2b2e | ||
|
|
33344727a8 | ||
|
|
828e5ba316 | ||
|
|
31c57f5c0f | ||
|
|
767a0053e8 | ||
|
|
fd65b99c91 | ||
|
|
e170df9f41 | ||
|
|
b91040e8c2 | ||
|
|
8824bd2a42 | ||
|
|
1d3c292d94 | ||
|
|
cfe6da96ac | ||
|
|
c3c78551d0 | ||
|
|
f1fabc5f18 | ||
|
|
166b960428 | ||
|
|
ef1a6c0f0b | ||
|
|
9b3944bd09 | ||
|
|
7917d08a50 | ||
|
|
4a8e5986f0 | ||
|
|
103838f371 | ||
|
|
0a26c686f9 | ||
|
|
efcf766193 | ||
|
|
151eddb759 | ||
|
|
cb0d6f3189 | ||
|
|
a897c697a5 | ||
|
|
3bedf6b23e | ||
|
|
9ff0e85693 | ||
|
|
1ca407fa2f | ||
|
|
46c927af06 | ||
|
|
87cb206e88 | ||
|
|
6806a2fc5a | ||
|
|
4ab65d75dd | ||
|
|
2a3294dbfb | ||
|
|
8334006f2b | ||
|
|
8a559e0d00 | ||
|
|
a3924f17b2 | ||
|
|
b11e862b0f | ||
|
|
099585afcb | ||
|
|
f023fc317e | ||
|
|
38a1463af0 | ||
|
|
f2399d3280 | ||
|
|
f699e10778 | ||
|
|
c824d8927f | ||
|
|
5821b24ab3 | ||
|
|
e812eb9e78 | ||
|
|
abfe13c5a7 | ||
|
|
0d5a75d3a0 | ||
|
|
b30c0ad27e | ||
|
|
1cada18186 | ||
|
|
fa50b07938 | ||
|
|
b6cad1631c | ||
|
|
2497e81e4d | ||
|
|
d8cba03840 | ||
|
|
0b1be19302 | ||
|
|
d7ebee4555 | ||
|
|
8f45a6f6ee | ||
|
|
6da77f01ce | ||
|
|
d90eccf959 | ||
|
|
f192a97aeb | ||
|
|
7781bbadd3 | ||
|
|
aeaa1d50cc | ||
|
|
fa5df9a329 | ||
|
|
f94f396c99 | ||
|
|
1f670f71d4 | ||
|
|
32b2901d13 | ||
|
|
2ad0b1d306 | ||
|
|
279d327899 | ||
|
|
5d848cf005 | ||
|
|
5607fd3ccb | ||
|
|
6a0d862258 | ||
|
|
1fe5f84fbc | ||
|
|
80e78ecd1e | ||
|
|
564135a530 | ||
|
|
b9e80641a0 | ||
|
|
0755994eaa | ||
|
|
dcabd6de31 | ||
|
|
aef6ce01ff | ||
|
|
441f9f444b | ||
|
|
b322829091 | ||
|
|
5167e65a5c | ||
|
|
5c6b4113a7 | ||
|
|
a8b76c3e69 | ||
|
|
d3237cac7b | ||
|
|
e395eb4eeb | ||
|
|
76e1ec2a1f | ||
|
|
27eaccc024 | ||
|
|
b288f2fc88 | ||
|
|
22134a603b | ||
|
|
3b5fd11cb9 | ||
|
|
e9417fc147 | ||
|
|
8bcf2c6905 | ||
|
|
9a03ba1853 |
@@ -0,0 +1,95 @@
|
||||
# Changesets
|
||||
|
||||
This directory is managed by [Changesets](https://github.com/changesets/changesets).
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
pnpm changeset
|
||||
```
|
||||
|
||||
Follow the prompts to select version bump type and describe your changes.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Add a changeset** — Run `pnpm changeset` locally before or after your PR
|
||||
2. **Version PR** — CI opens/updates a "Version Packages" PR when changesets merge to main
|
||||
3. **Release** — Merging the Version PR triggers npm publish and GitHub Release
|
||||
|
||||
> **Note:** Contributors only need to run `pnpm changeset`. Versioning (`changeset version`) and publishing happen automatically in CI.
|
||||
|
||||
## Template
|
||||
|
||||
Use this structure for your changeset content:
|
||||
|
||||
```markdown
|
||||
---
|
||||
"@fission-ai/openspec": patch
|
||||
---
|
||||
|
||||
### New Features
|
||||
|
||||
- **Feature name** — What users can now do
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed issue where X happened when Y
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- `oldMethod()` has been removed, use `newMethod()` instead
|
||||
|
||||
### Deprecations
|
||||
|
||||
- `legacyOption` is deprecated and will be removed in v2.0
|
||||
|
||||
### Other
|
||||
|
||||
- Internal refactoring of X for better performance
|
||||
```
|
||||
|
||||
Include only the sections relevant to your change.
|
||||
|
||||
## Version Bump Guide
|
||||
|
||||
| Type | When to use | Example |
|
||||
|------|-------------|---------|
|
||||
| `patch` | Bug fixes, small improvements | Fixed crash when config missing |
|
||||
| `minor` | New features, non-breaking additions | Added `--verbose` flag |
|
||||
| `major` | Breaking changes, removed features | Renamed `init` to `setup` |
|
||||
|
||||
## When to Create a Changeset
|
||||
|
||||
**Create one for:**
|
||||
- New features or commands
|
||||
- Bug fixes that affect users
|
||||
- Breaking changes or deprecations
|
||||
- Performance improvements users would notice
|
||||
|
||||
**Skip for:**
|
||||
- Documentation-only changes
|
||||
- Test additions/fixes
|
||||
- Internal refactoring with no user impact
|
||||
- CI/tooling changes
|
||||
|
||||
## Writing Good Descriptions
|
||||
|
||||
**Do:** Write for users, not developers
|
||||
```markdown
|
||||
- **Shell completions** — Tab completion now available for Bash, Fish, and PowerShell
|
||||
```
|
||||
|
||||
**Don't:** Write implementation details
|
||||
```markdown
|
||||
- Added ShellCompletionGenerator class with Bash/Fish/PowerShell subclasses
|
||||
```
|
||||
|
||||
**Do:** Explain the impact
|
||||
```markdown
|
||||
- Fixed config loading to respect `XDG_CONFIG_HOME` on Linux
|
||||
```
|
||||
|
||||
**Don't:** Just reference the fix
|
||||
```markdown
|
||||
- Fixed #123
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config/schema.json",
|
||||
"changelog": [
|
||||
"@changesets/changelog-github",
|
||||
{ "repo": "Fission-AI/OpenSpec" }
|
||||
],
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": []
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
||||
# Minimal configuration for getting started
|
||||
language: "en-US"
|
||||
reviews:
|
||||
profile: "chill"
|
||||
high_level_summary: true
|
||||
auto_review:
|
||||
enabled: true
|
||||
drafts: false
|
||||
base_branches:
|
||||
- ".*"
|
||||
@@ -0,0 +1,92 @@
|
||||
# Dev Container Setup
|
||||
|
||||
This directory contains the VS Code dev container configuration for OpenSpec development.
|
||||
|
||||
## What's Included
|
||||
|
||||
- **Node.js 20 LTS** (>=20.19.0) - TypeScript/JavaScript runtime
|
||||
- **pnpm** - Fast, disk space efficient package manager
|
||||
- **Git + GitHub CLI** - Version control tools
|
||||
- **VS Code Extensions**:
|
||||
- ESLint & Prettier for code quality
|
||||
- Vitest Explorer for running tests
|
||||
- GitLens for enhanced git integration
|
||||
- Error Lens for inline error highlighting
|
||||
- Code Spell Checker
|
||||
- Path IntelliSense
|
||||
|
||||
## How to Use
|
||||
|
||||
### First Time Setup
|
||||
|
||||
1. **Install Prerequisites** (on your local machine):
|
||||
- [VS Code](https://code.visualstudio.com/)
|
||||
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
|
||||
- [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
|
||||
|
||||
2. **Open in Container**:
|
||||
- Open this project in VS Code
|
||||
- You'll see a notification: "Folder contains a Dev Container configuration file"
|
||||
- Click "Reopen in Container"
|
||||
|
||||
OR
|
||||
|
||||
- Open Command Palette (`Cmd/Ctrl+Shift+P`)
|
||||
- Type "Dev Containers: Reopen in Container"
|
||||
- Press Enter
|
||||
|
||||
3. **Wait for Setup**:
|
||||
- The container will build (first time takes a few minutes)
|
||||
- `pnpm install` runs automatically via `postCreateCommand`
|
||||
- All extensions install automatically
|
||||
|
||||
### Daily Development
|
||||
|
||||
Once set up, the container preserves your development environment:
|
||||
|
||||
```bash
|
||||
# Run development build
|
||||
pnpm run dev
|
||||
|
||||
# Run CLI in development
|
||||
pnpm run dev:cli
|
||||
|
||||
# Run tests
|
||||
pnpm test
|
||||
|
||||
# Run tests in watch mode
|
||||
pnpm test:watch
|
||||
|
||||
# Build the project
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
### SSH Keys
|
||||
|
||||
Your SSH keys are mounted read-only from `~/.ssh`, so git operations work seamlessly with GitHub/GitLab.
|
||||
|
||||
### Rebuilding the Container
|
||||
|
||||
If you modify `.devcontainer/devcontainer.json`:
|
||||
- Command Palette → "Dev Containers: Rebuild Container"
|
||||
|
||||
## Benefits
|
||||
|
||||
- No need to install Node.js or pnpm on your local machine
|
||||
- Consistent development environment across team members
|
||||
- Isolated from other Node.js projects on your machine
|
||||
- All dependencies and tools containerized
|
||||
- Easy onboarding for new developers
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Container won't build:**
|
||||
- Ensure Docker Desktop is running
|
||||
- Check Docker has enough memory allocated (recommend 4GB+)
|
||||
|
||||
**Extensions not appearing:**
|
||||
- Rebuild the container: "Dev Containers: Rebuild Container"
|
||||
|
||||
**Permission issues:**
|
||||
- The container runs as the `node` user (non-root)
|
||||
- Files created in the container are owned by this user
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "OpenSpec Development",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm",
|
||||
|
||||
// Additional tools and features
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/git:1": {
|
||||
"version": "latest",
|
||||
"ppa": true
|
||||
},
|
||||
"ghcr.io/devcontainers/features/github-cli:1": {
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
|
||||
// Configure tool-specific properties
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
// Set default container specific settings
|
||||
"settings": {
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit"
|
||||
},
|
||||
"files.eol": "\n",
|
||||
"terminal.integrated.defaultProfile.linux": "bash"
|
||||
},
|
||||
|
||||
// Add extensions you want installed when the container is created
|
||||
"extensions": [
|
||||
// TypeScript/JavaScript essentials
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
|
||||
// Testing
|
||||
"vitest.explorer",
|
||||
|
||||
// Git
|
||||
"eamodio.gitlens",
|
||||
|
||||
// Utilities
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"usernamehw.errorlens",
|
||||
"christian-kohler.path-intellisense"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created
|
||||
"postCreateCommand": "corepack enable && corepack prepare pnpm@latest --activate && pnpm install",
|
||||
|
||||
// Configure mounts to preserve SSH keys for git operations
|
||||
"mounts": [
|
||||
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,readonly,type=bind,consistency=cached"
|
||||
],
|
||||
|
||||
// Set the default user to 'node' (non-root user)
|
||||
"remoteUser": "node",
|
||||
|
||||
// Ensure git is properly configured
|
||||
"initializeCommand": "echo 'Initializing dev container...'"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# Default code ownership
|
||||
* @TabishB
|
||||
@@ -0,0 +1,20 @@
|
||||
# Github Workflows
|
||||
|
||||
## Testing CI Locally
|
||||
|
||||
Test GitHub Actions workflows locally using [act](https://nektosact.com/):
|
||||
|
||||
```bash
|
||||
# Test all PR checks
|
||||
act pull_request
|
||||
|
||||
# Test specific job
|
||||
act pull_request -j nix-flake-validate
|
||||
|
||||
# Dry run to see what would execute
|
||||
act pull_request --dryrun
|
||||
```
|
||||
|
||||
The `.actrc` file configures act to use the appropriate Docker image.
|
||||
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Detect which files changed to enable path-based filtering
|
||||
changes:
|
||||
name: Detect changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
nix: ${{ steps.filter.outputs.nix }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check for Nix-related changes
|
||||
uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
nix:
|
||||
- 'flake.nix'
|
||||
- 'flake.lock'
|
||||
- 'package.json'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'scripts/update-flake.sh'
|
||||
- '.github/workflows/ci.yml'
|
||||
|
||||
test_pr:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm test
|
||||
|
||||
- name: Upload test coverage
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report-pr
|
||||
path: coverage/
|
||||
retention-days: 7
|
||||
|
||||
test_matrix:
|
||||
name: Test (${{ matrix.label }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 15
|
||||
if: github.event_name != 'pull_request'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
shell: bash
|
||||
label: linux-bash
|
||||
- os: macos-latest
|
||||
shell: bash
|
||||
label: macos-bash
|
||||
- os: windows-latest
|
||||
shell: pwsh
|
||||
label: windows-pwsh
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Print environment diagnostics
|
||||
run: |
|
||||
node -p "JSON.stringify({ platform: process.platform, arch: process.arch, shell: process.env.SHELL || process.env.ComSpec || '' })"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm test
|
||||
|
||||
- name: Upload test coverage
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report-main
|
||||
path: coverage/
|
||||
retention-days: 7
|
||||
|
||||
lint:
|
||||
name: Lint & Type Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Type check
|
||||
run: pnpm exec tsc --noEmit
|
||||
|
||||
- name: Lint
|
||||
run: pnpm lint
|
||||
|
||||
- name: Check for build artifacts
|
||||
run: |
|
||||
if [ ! -d "dist" ]; then
|
||||
echo "Error: dist directory not found after build"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "dist/cli/index.js" ]; then
|
||||
echo "Error: CLI entry point not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
nix-flake-validate:
|
||||
name: Nix Flake Validation
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: changes
|
||||
if: needs.changes.outputs.nix == 'true'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@v21
|
||||
|
||||
- name: Setup Nix cache
|
||||
uses: DeterminateSystems/magic-nix-cache-action@v13
|
||||
|
||||
- name: Build with Nix
|
||||
run: nix build
|
||||
|
||||
- name: Verify build output
|
||||
run: |
|
||||
if [ ! -e "result" ]; then
|
||||
echo "Error: Nix build output 'result' symlink not found"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "result/bin/openspec" ]; then
|
||||
echo "Error: openspec binary not found in build output"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Build output verified"
|
||||
|
||||
- name: Test binary execution
|
||||
run: |
|
||||
VERSION=$(nix run . -- --version)
|
||||
echo "OpenSpec version: $VERSION"
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "Error: Version command returned empty output"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Binary execution successful"
|
||||
|
||||
- name: Validate update script
|
||||
run: |
|
||||
echo "Testing update-flake.sh script..."
|
||||
bash scripts/update-flake.sh
|
||||
echo "✅ Update script executed successfully"
|
||||
|
||||
- name: Check flake.nix modifications
|
||||
run: |
|
||||
if git diff --quiet flake.nix; then
|
||||
echo "ℹ️ flake.nix unchanged (hash already up-to-date)"
|
||||
else
|
||||
echo "✅ flake.nix was updated by script"
|
||||
git diff flake.nix
|
||||
fi
|
||||
|
||||
- name: Restore flake.nix
|
||||
if: always()
|
||||
run: git checkout -- flake.nix || true
|
||||
|
||||
validate-changesets:
|
||||
name: Validate Changesets
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Validate changesets
|
||||
run: |
|
||||
if command -v changeset &> /dev/null; then
|
||||
pnpm exec changeset status --since=origin/main
|
||||
else
|
||||
echo "Changesets not configured, skipping validation"
|
||||
fi
|
||||
|
||||
required-checks-pr:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_pr, lint, nix-flake-validate]
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
if [[ "${{ needs.test_pr.result }}" != "success" ]]; then
|
||||
echo "Test job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.lint.result }}" != "success" ]]; then
|
||||
echo "Lint job failed"
|
||||
exit 1
|
||||
fi
|
||||
# Nix validation may be skipped if no Nix-related files changed
|
||||
if [[ "${{ needs.nix-flake-validate.result }}" != "success" && "${{ needs.nix-flake-validate.result }}" != "skipped" ]]; then
|
||||
echo "Nix flake validation job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.nix-flake-validate.result }}" == "skipped" ]]; then
|
||||
echo "Nix flake validation skipped (no Nix-related changes)"
|
||||
fi
|
||||
echo "All required checks passed!"
|
||||
|
||||
required-checks-main:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_matrix, lint, nix-flake-validate]
|
||||
if: always() && github.event_name != 'pull_request'
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
if [[ "${{ needs.test_matrix.result }}" != "success" ]]; then
|
||||
echo "Matrix test job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.lint.result }}" != "success" ]]; then
|
||||
echo "Lint job failed"
|
||||
exit 1
|
||||
fi
|
||||
# Nix validation may be skipped if no Nix-related files changed
|
||||
if [[ "${{ needs.nix-flake-validate.result }}" != "success" && "${{ needs.nix-flake-validate.result }}" != "skipped" ]]; then
|
||||
echo "Nix flake validation job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.nix-flake-validate.result }}" == "skipped" ]]; then
|
||||
echo "Nix flake validation skipped (no Nix-related changes)"
|
||||
fi
|
||||
echo "All required checks passed!"
|
||||
@@ -0,0 +1,60 @@
|
||||
name: Release (prepare)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write # Required for npm OIDC trusted publishing
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
if: github.repository == 'Fission-AI/OpenSpec'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Generate GitHub App token first - used for checkout and changesets
|
||||
# This allows git operations to trigger CI workflows on the version PR
|
||||
# (GITHUB_TOKEN cannot trigger workflows by design)
|
||||
- name: Generate GitHub App Token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
app-id: ${{ vars.APP_ID }}
|
||||
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24' # Node 24 includes npm 11.5.1+ required for OIDC
|
||||
cache: 'pnpm'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
# Opens/updates the Version Packages PR; publishes when the Version PR merges
|
||||
- name: Create/Update Version PR
|
||||
id: changesets
|
||||
uses: changesets/action@v1
|
||||
with:
|
||||
title: 'chore(release): version packages'
|
||||
createGithubReleases: true
|
||||
# Use CI-specific release script: relies on version PR having been merged
|
||||
# so package.json already contains the bumped version.
|
||||
publish: pnpm run release:ci
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
# npm authentication handled via OIDC trusted publishing (no token needed)
|
||||
+6
-3
@@ -140,9 +140,12 @@ dist/
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
|
||||
# Internal Docs
|
||||
docs/
|
||||
|
||||
# Claude
|
||||
.claude/
|
||||
CLAUDE.md
|
||||
CLAUDE.md
|
||||
.DS_Store
|
||||
|
||||
# Pnpm
|
||||
.pnpm-store/
|
||||
result
|
||||
|
||||
+490
@@ -0,0 +1,490 @@
|
||||
# @fission-ai/openspec
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#625](https://github.com/Fission-AI/OpenSpec/pull/625) [`53081fb`](https://github.com/Fission-AI/OpenSpec/commit/53081fb2a26ec66d2950ae0474b9a56cbc5b5a76) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- **Codex global path support** — Codex adapter now resolves global paths correctly, fixing workflow file generation when run outside the project directory (#622)
|
||||
- **Archive operations on cross-device or restricted paths** — Archive now falls back to copy+remove when rename fails with EPERM or EXDEV errors, fixing failures on networked/external drives (#605)
|
||||
- **Slash command hints in workflow messages** — Workflow completion messages now display helpful slash command hints for next steps (#603)
|
||||
- **Windsurf workflow file path** — Updated Windsurf adapter to use the correct `workflows` directory instead of the legacy `commands` path (#610)
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#550](https://github.com/Fission-AI/OpenSpec/pull/550) [`86d2e04`](https://github.com/Fission-AI/OpenSpec/commit/86d2e04cae76a999dbd1b4571f52fa720036be0c) Thanks [@jerome-benoit](https://github.com/jerome-benoit)! - ### Improvements
|
||||
|
||||
- **Nix flake maintenance** — Version now read dynamically from package.json, reducing manual sync issues
|
||||
- **Nix build optimization** — Source filtering excludes node_modules and artifacts, improving build times
|
||||
- **update-flake.sh script** — Detects when hash is already correct, skipping unnecessary rebuilds
|
||||
|
||||
### Other
|
||||
|
||||
- Updated Nix CI actions to latest versions (nix-installer v21, magic-nix-cache v13)
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#596](https://github.com/Fission-AI/OpenSpec/pull/596) [`e91568d`](https://github.com/Fission-AI/OpenSpec/commit/e91568deb948073f3e9d9bb2d2ab5bf8080d6cf4) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- Clarified spec naming convention — Specs should be named after capabilities (`specs/<capability>/spec.md`), not changes
|
||||
- Fixed task checkbox format guidance — Tasks now clearly require `- [ ]` checkbox format for apply phase tracking
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#587](https://github.com/Fission-AI/OpenSpec/pull/587) [`943e0d4`](https://github.com/Fission-AI/OpenSpec/commit/943e0d41026d034de66b9442d1276c01b293eb2b) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- Fixed incorrect archive path in onboarding documentation — the template now shows the correct path `openspec/changes/archive/YYYY-MM-DD-<name>/` instead of the incorrect `openspec/archive/YYYY-MM-DD--<name>/`
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#578](https://github.com/Fission-AI/OpenSpec/pull/578) [`0cc9d90`](https://github.com/Fission-AI/OpenSpec/commit/0cc9d9025af367faa1688a7b2606a2549053cd3f) Thanks [@TabishB](https://github.com/TabishB)! - ## OpenSpec 1.0 — The OPSX Release
|
||||
|
||||
The workflow has been rebuilt from the ground up. OPSX replaces the old phase-locked `/openspec:*` commands with an action-based system where AI understands what artifacts exist, what's ready to create, and what each action unlocks.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- **Old commands removed** — `/openspec:proposal`, `/openspec:apply`, and `/openspec:archive` no longer exist
|
||||
- **Config files removed** — Tool-specific instruction files (`CLAUDE.md`, `.cursorrules`, `AGENTS.md`, `project.md`) are no longer generated
|
||||
- **Migration** — Run `openspec init` to upgrade. Legacy artifacts are detected and cleaned up with confirmation.
|
||||
|
||||
### From Static Prompts to Dynamic Instructions
|
||||
|
||||
**Before:** AI received the same static instructions every time, regardless of project state.
|
||||
|
||||
**Now:** Instructions are dynamically assembled from three layers:
|
||||
|
||||
1. **Context** — Project background from `config.yaml` (tech stack, conventions)
|
||||
2. **Rules** — Artifact-specific constraints (e.g., "propose spike tasks for unknowns")
|
||||
3. **Template** — The actual structure for the output file
|
||||
|
||||
AI queries the CLI for real-time state: which artifacts exist, what's ready to create, what dependencies are satisfied, and what each action unlocks.
|
||||
|
||||
### From Phase-Locked to Action-Based
|
||||
|
||||
**Before:** Linear workflow — proposal → apply → archive. Couldn't easily go back or iterate.
|
||||
|
||||
**Now:** Flexible actions on a change. Edit any artifact anytime. The artifact graph tracks state automatically.
|
||||
|
||||
| Command | What it does |
|
||||
| -------------------- | ---------------------------------------------------- |
|
||||
| `/opsx:explore` | Think through ideas before committing to a change |
|
||||
| `/opsx:new` | Start a new change |
|
||||
| `/opsx:continue` | Create one artifact at a time (step-through) |
|
||||
| `/opsx:ff` | Create all planning artifacts at once (fast-forward) |
|
||||
| `/opsx:apply` | Implement tasks |
|
||||
| `/opsx:verify` | Validate implementation matches artifacts |
|
||||
| `/opsx:sync` | Sync delta specs to main specs |
|
||||
| `/opsx:archive` | Archive completed change |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes with conflict detection |
|
||||
| `/opsx:onboard` | Guided 15-minute walkthrough of complete workflow |
|
||||
|
||||
### From Text Merging to Semantic Spec Syncing
|
||||
|
||||
**Before:** Spec updates required manual merging or wholesale file replacement.
|
||||
|
||||
**Now:** Delta specs use semantic markers that AI understands:
|
||||
|
||||
- `## ADDED Requirements` — New requirements to add
|
||||
- `## MODIFIED Requirements` — Partial updates (add scenario without copying existing ones)
|
||||
- `## REMOVED Requirements` — Delete with reason and migration notes
|
||||
- `## RENAMED Requirements` — Rename preserving content
|
||||
|
||||
Archive parses these at the requirement level, not brittle header matching.
|
||||
|
||||
### From Scattered Files to Agent Skills
|
||||
|
||||
**Before:** 8+ config files at project root + slash commands scattered across 21 tool-specific locations with different formats.
|
||||
|
||||
**Now:** Single `.claude/skills/` directory with YAML-fronted markdown files. Auto-detected by Claude Code, Cursor, Windsurf. Cross-editor compatible.
|
||||
|
||||
### New Features
|
||||
|
||||
- **Onboarding skill** — `/opsx:onboard` walks new users through their first complete change with codebase-aware task suggestions and step-by-step narration (11 phases, ~15 minutes)
|
||||
|
||||
- **21 AI tools supported** — Claude Code, Cursor, Windsurf, Continue, Gemini CLI, GitHub Copilot, Amazon Q, Cline, RooCode, Kilo Code, Auggie, CodeBuddy, Qoder, Qwen, CoStrict, Crush, Factory, OpenCode, Antigravity, iFlow, and Codex
|
||||
|
||||
- **Interactive setup** — `openspec init` shows animated welcome screen and searchable multi-select for choosing tools. Pre-selects already-configured tools for easy refresh.
|
||||
|
||||
- **Customizable schemas** — Define custom artifact workflows in `openspec/schemas/` without touching package code. Teams can share workflows via version control.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed Claude Code YAML parsing failure when command names contained colons
|
||||
- Fixed task file parsing to handle trailing whitespace on checkbox lines
|
||||
- Fixed JSON instruction output to separate context/rules from template — AI was copying constraint blocks into artifact files
|
||||
|
||||
### Documentation
|
||||
|
||||
- New getting-started guide, CLI reference, concepts documentation
|
||||
- Removed misleading "edit mid-flight and continue" claims that weren't implemented
|
||||
- Added migration guide for upgrading from pre-OPSX versions
|
||||
|
||||
## 0.23.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#540](https://github.com/Fission-AI/OpenSpec/pull/540) [`c4cfdc7`](https://github.com/Fission-AI/OpenSpec/commit/c4cfdc7c499daef30d8a218f5f59b8d9e5adb754) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
|
||||
|
||||
- **Bulk archive skill** — Archive multiple completed changes in a single operation with `/opsx:bulk-archive`. Includes batch validation, spec conflict detection, and consolidated confirmation
|
||||
|
||||
### Other
|
||||
|
||||
- **Simplified setup** — Config creation now uses sensible defaults with helpful comments instead of interactive prompts
|
||||
|
||||
## 0.22.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#530](https://github.com/Fission-AI/OpenSpec/pull/530) [`33466b1`](https://github.com/Fission-AI/OpenSpec/commit/33466b1e2a6798bdd6d0e19149173585b0612e6f) Thanks [@TabishB](https://github.com/TabishB)! - Add project-level configuration, project-local schemas, and schema management commands
|
||||
|
||||
**New Features**
|
||||
|
||||
- **Project-level configuration** — Configure OpenSpec behavior per-project via `openspec/config.yaml`, including custom rules injection, context files, and schema resolution settings
|
||||
- **Project-local schemas** — Define custom artifact schemas within your project's `openspec/schemas/` directory for project-specific workflows
|
||||
- **Schema management commands** — New `openspec schema` commands (`list`, `show`, `export`, `validate`) for inspecting and managing artifact schemas (experimental)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fixed config loading to handle null `rules` field in project configuration
|
||||
|
||||
## 0.21.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#516](https://github.com/Fission-AI/OpenSpec/pull/516) [`b5a8847`](https://github.com/Fission-AI/OpenSpec/commit/b5a884748be6156a7bb140b4941cfec4f20a9fc8) Thanks [@TabishB](https://github.com/TabishB)! - Add feedback command and Nix flake support
|
||||
|
||||
**New Features**
|
||||
|
||||
- **Feedback command** — Submit feedback directly from the CLI with `openspec feedback`, which creates GitHub Issues with automatic metadata inclusion and graceful fallback for manual submission
|
||||
- **Nix flake support** — Install and develop openspec using Nix with the new `flake.nix`, including automated flake maintenance and CI validation
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- **Explore mode guardrails** — Explore mode now explicitly prevents implementation, keeping the focus on thinking and discovery while still allowing artifact creation
|
||||
|
||||
**Other**
|
||||
|
||||
- Improved change inference in `opsx apply` — automatically detects the target change from conversation context or prompts when ambiguous
|
||||
- Streamlined archive sync assessment with clearer delta spec location guidance
|
||||
|
||||
## 0.20.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#502](https://github.com/Fission-AI/OpenSpec/pull/502) [`9db74aa`](https://github.com/Fission-AI/OpenSpec/commit/9db74aa5ac6547efadaed795217cfa17444f2004) Thanks [@TabishB](https://github.com/TabishB)! - Add `/opsx:verify` command and fix vitest process storms
|
||||
|
||||
**New Features**
|
||||
|
||||
- **`/opsx:verify` command** — Validate that change implementations match their specifications
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fixed vitest process storms by capping worker parallelism
|
||||
- Fixed agent workflows to use non-interactive mode for validation commands
|
||||
- Fixed PowerShell completions generator to remove trailing commas
|
||||
|
||||
## 0.19.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- eb152eb: Add Continue IDE support, shell completions, and `/opsx:explore` command
|
||||
|
||||
**New Features**
|
||||
|
||||
- **Continue IDE support** – OpenSpec now generates slash commands for [Continue](https://continue.dev/), expanding editor integration options alongside Cursor, Windsurf, Claude Code, and others
|
||||
- **Shell completions for Bash, Fish, and PowerShell** – Run `openspec completion install` to set up tab completion in your preferred shell
|
||||
- **`/opsx:explore` command** – A new thinking partner mode for exploring ideas and investigating problems before committing to changes
|
||||
- **Codebuddy slash command improvements** – Updated frontmatter format for better compatibility
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Shell completions now correctly offer parent-level flags (like `--help`) when a command has subcommands
|
||||
- Fixed Windows compatibility issues in tests
|
||||
|
||||
**Other**
|
||||
|
||||
- Added optional anonymous usage statistics to help understand how OpenSpec is used. This is **opt-out** by default – set `OPENSPEC_TELEMETRY=0` or `DO_NOT_TRACK=1` to disable. Only command names and version are collected; no arguments, file paths, or content. Automatically disabled in CI environments.
|
||||
|
||||
## 0.18.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 8dfd824: Add OPSX experimental workflow commands and enhanced artifact system
|
||||
|
||||
**New Commands:**
|
||||
|
||||
- `/opsx:ff` - Fast-forward through artifact creation, generating all needed artifacts in one go
|
||||
- `/opsx:sync` - Sync delta specs from a change to main specs
|
||||
- `/opsx:archive` - Archive completed changes with smart sync check
|
||||
|
||||
**Artifact Workflow Enhancements:**
|
||||
|
||||
- Schema-aware apply instructions with inline guidance and XML output
|
||||
- Agent schema selection for experimental artifact workflow
|
||||
- Per-change schema metadata via `.openspec.yaml` files
|
||||
- Agent Skills for experimental artifact workflow
|
||||
- Instruction loader for template loading and change context
|
||||
- Restructured schemas as directories with templates
|
||||
|
||||
**Improvements:**
|
||||
|
||||
- Enhanced list command with last modified timestamps and sorting
|
||||
- Change creation utilities for better workflow support
|
||||
|
||||
**Fixes:**
|
||||
|
||||
- Normalize paths for cross-platform glob compatibility
|
||||
- Allow REMOVED requirements when creating new spec files
|
||||
|
||||
## 0.17.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 455c65f: Fix `--no-interactive` flag in validate command to properly disable spinner, preventing hangs in pre-commit hooks and CI environments
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a2757e7: Fix pre-commit hook hang issue in config command by using dynamic import for @inquirer/prompts
|
||||
|
||||
The config command was causing pre-commit hooks to hang indefinitely due to stdin event listeners being registered at module load time. This fix converts the static import to a dynamic import that only loads inquirer when the `config reset` command is actually used interactively.
|
||||
|
||||
Also adds ESLint with a rule to prevent static @inquirer imports, avoiding future regressions.
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 2e71835: Add `openspec config` command and Oh-my-zsh completions
|
||||
|
||||
**New Features**
|
||||
|
||||
- Add `openspec config` command for managing global configuration settings
|
||||
- Implement global config directory with XDG Base Directory specification support
|
||||
- Add Oh-my-zsh shell completions support for enhanced CLI experience
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix hang in pre-commit hooks by using dynamic imports
|
||||
- Respect XDG_CONFIG_HOME environment variable on all platforms
|
||||
- Resolve Windows compatibility issues in zsh-installer tests
|
||||
- Align cli-completion spec with implementation
|
||||
- Remove hardcoded agent field from slash commands
|
||||
|
||||
**Documentation**
|
||||
|
||||
- Alphabetize AI tools list in README and make it collapsible
|
||||
|
||||
## 0.16.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c08fbc1: Add new AI tool integrations and enhancements:
|
||||
|
||||
- **feat(iflow-cli)**: Add iFlow-cli integration with slash command support and documentation
|
||||
- **feat(init)**: Add IDE restart instruction after init to inform users about slash command availability
|
||||
**feat(antigravity)**: Add Antigravity slash command support
|
||||
- **fix**: Generate TOML commands for Qwen Code (fixes #293)
|
||||
- Clarify scaffold proposal documentation and enhance proposal guidelines
|
||||
- Update proposal guidelines to emphasize design-first approach before implementation
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add Continue slash command support so `openspec init` can generate `.continue/prompts/openspec-*.prompt` files with MARKDOWN frontmatter and `$ARGUMENTS` placeholder, and refresh them on `openspec update`.
|
||||
|
||||
- Add Antigravity slash command support so `openspec init` can generate `.agent/workflows/openspec-*.md` files with description-only frontmatter and `openspec update` refreshes existing workflows alongside Windsurf.
|
||||
|
||||
## 0.15.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 4758c5c: Add support for new AI tools with native slash command integration
|
||||
|
||||
- **Gemini CLI**: Add native TOML-based slash command support for Gemini CLI with `.gemini/commands/openspec/` integration
|
||||
- **RooCode**: Add RooCode integration with configurator, slash commands, and templates
|
||||
- **Cline**: Fix Cline to use workflows instead of rules for slash commands (`.clinerules/workflows/` paths)
|
||||
- **Documentation**: Update documentation to reflect new integrations and workflow changes
|
||||
|
||||
## 0.14.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 8386b91: Add support for new AI assistants and configuration improvements
|
||||
|
||||
- feat: add Qwen Code support with slash command integration
|
||||
- feat: add $ARGUMENTS support to apply slash command for dynamic variable passing
|
||||
- feat: add Qoder CLI support to configuration and documentation
|
||||
- feat: add CoStrict AI assistant support
|
||||
- fix: recreate missing openspec template files in extend mode
|
||||
- fix: prevent false 'already configured' detection for tools
|
||||
- fix: use change-id as fallback title instead of "Untitled Change"
|
||||
- docs: add guidance for populating project-level context
|
||||
- docs: add Crush to supported AI tools in README
|
||||
|
||||
## 0.13.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 668a125: Add support for multiple AI assistants and improve validation
|
||||
|
||||
This release adds support for several new AI coding assistants:
|
||||
|
||||
- CodeBuddy Code - AI-powered coding assistant
|
||||
- CodeRabbit - AI code review assistant
|
||||
- Cline - Claude-powered CLI assistant
|
||||
- Crush AI - AI assistant platform
|
||||
- Auggie (Augment CLI) - Code augmentation tool
|
||||
|
||||
New features:
|
||||
|
||||
- Archive slash command now supports arguments for more flexible workflows
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Delta spec validation now handles case-insensitive headers and properly detects empty sections
|
||||
- Archive validation now correctly honors --no-validate flag and ignores metadata
|
||||
|
||||
Documentation improvements:
|
||||
|
||||
- Added VS Code dev container configuration for easier development setup
|
||||
- Updated AGENTS.md with explicit change-id notation
|
||||
- Enhanced slash commands documentation with restart notes
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 082abb4: Add factory function support for slash commands and non-interactive init options
|
||||
|
||||
This release includes two new features:
|
||||
|
||||
- **Factory function support for slash commands**: Slash commands can now be defined as functions that return command objects, enabling dynamic command configuration
|
||||
- **Non-interactive init options**: Added `--tools`, `--all-tools`, and `--skip-tools` CLI flags to `openspec init` for automated initialization in CI/CD pipelines while maintaining backward compatibility with interactive mode
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 312e1d6: Add Amazon Q Developer CLI integration. OpenSpec now supports Amazon Q Developer with automatic prompt generation in `.amazonq/prompts/` directory, allowing you to use OpenSpec slash commands with Amazon Q's @-syntax.
|
||||
|
||||
## 0.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- d7e0ce8: Improve init wizard Enter key behavior to allow proceeding through prompts more naturally
|
||||
|
||||
## 0.9.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2ae0484: Fix cross-platform path handling issues. This release includes fixes for joinPath behavior and slash command path resolution to ensure OpenSpec works correctly across all platforms.
|
||||
|
||||
## 0.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 8210970: Fix OpenSpec not working on Windows when Codex integration is selected. This release includes fixes for cross-platform path handling and normalization to ensure OpenSpec works correctly on Windows systems.
|
||||
|
||||
## 0.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- efbbf3b: Add support for Codex and GitHub Copilot slash commands with YAML frontmatter and $ARGUMENTS
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add GitHub Copilot slash command support. OpenSpec now writes prompts to `.github/prompts/openspec-{proposal,apply,archive}.prompt.md` with YAML frontmatter and `$ARGUMENTS` placeholder, and refreshes them on `openspec update`.
|
||||
|
||||
## 0.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- d070d08: Fix CLI version mismatch and add a release guard that validates the packed tarball prints the same version as package.json via `openspec --version`.
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c29b06d: Add Windsurf support.
|
||||
- Add Codex slash command support. OpenSpec now writes prompts directly to Codex's global directory (`~/.codex/prompts` or `$CODEX_HOME/prompts`) and refreshes them on `openspec update`.
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add native Kilo Code workflow integration so `openspec init` and `openspec update` manage `.kilocode/workflows/openspec-*.md` files.
|
||||
- Always scaffold the managed root `AGENTS.md` hand-off stub and regroup the AI tool prompts during init/update to keep instructions consistent.
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Slim the generated root agent instructions down to a managed hand-off stub and update the init/update flows to refresh it safely.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- feat: implement Phase 1 E2E testing with cross-platform CI matrix
|
||||
|
||||
- Add shared runCLI helper in test/helpers/run-cli.ts for spawn testing
|
||||
- Create test/cli-e2e/basic.test.ts covering help, version, validate flows
|
||||
- Migrate existing CLI exec tests to use runCLI helper
|
||||
- Extend CI matrix to bash (Linux/macOS) and pwsh (Windows)
|
||||
- Split PR and main workflows for optimized feedback
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Make apply instructions more specific
|
||||
|
||||
Improve agent templates and slash command templates with more specific and actionable apply instructions.
|
||||
|
||||
- docs: improve documentation and cleanup
|
||||
|
||||
- Document non-interactive flag for archive command
|
||||
- Replace discord badge in README
|
||||
- Archive completed changes for better organization
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add OpenSpec change proposals for CLI improvements and enhanced user experience
|
||||
- Add Opencode slash commands support for AI-driven development workflows
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Add documentation improvements including --yes flag for archive command template and Discord badge
|
||||
- Fix normalize line endings in markdown parser to handle CRLF files properly
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Enhance `openspec init` with extend mode, multi-tool selection, and an interactive `AGENTS.md` configurator.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- ce5cead: - Add an `openspec view` dashboard that rolls up spec counts and change progress at a glance
|
||||
- Generate and update AI slash commands alongside the renamed `openspec/AGENTS.md` instructions file
|
||||
- Remove the deprecated `openspec diff` command and direct users to `openspec show`
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 24b4866: Initial release
|
||||
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 OpenSpec Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Maintainers
|
||||
|
||||
People who maintain and guide OpenSpec.
|
||||
|
||||
## Core Maintainers
|
||||
|
||||
| Name | GitHub | Role |
|
||||
|------|--------|------|
|
||||
| Tabish Bidiwale | [@TabishB](https://github.com/TabishB) | Lead maintainer |
|
||||
|
||||
## Advisors
|
||||
|
||||
Advisors help shape technical direction and provide guidance to the project.
|
||||
|
||||
| Name | GitHub | Focus |
|
||||
|------|--------|-------|
|
||||
| Hari Krishnan | [@harikrishnan83](https://github.com/harikrishnan83) | Technical direction |
|
||||
@@ -0,0 +1,204 @@
|
||||
<p align="center">
|
||||
<a href="https://github.com/Fission-AI/OpenSpec">
|
||||
<picture>
|
||||
<source srcset="assets/openspec_bg.png">
|
||||
<img src="assets/openspec_bg.png" alt="OpenSpec logo">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
|
||||
<a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
|
||||
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
|
||||
<a href="https://discord.gg/YctCnvvshC"><img alt="Discord" src="https://img.shields.io/discord/1411657095639601154?style=flat-square&logo=discord&logoColor=white&label=Discord&suffix=%20online" /></a>
|
||||
</p>
|
||||
|
||||
<details>
|
||||
<summary><strong>The most loved spec framework.</strong></summary>
|
||||
|
||||
[](https://github.com/Fission-AI/OpenSpec/stargazers)
|
||||
[](https://www.npmjs.com/package/@fission-ai/openspec)
|
||||
[](https://github.com/Fission-AI/OpenSpec/graphs/contributors)
|
||||
|
||||
</details>
|
||||
<p></p>
|
||||
Our philosophy:
|
||||
|
||||
```text
|
||||
→ fluid not rigid
|
||||
→ iterative not waterfall
|
||||
→ easy not complex
|
||||
→ built for brownfield not just greenfield
|
||||
→ scalable from personal projects to enterprises
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> **New workflow now available!** We've rebuilt OpenSpec with a new artifact-guided workflow.
|
||||
>
|
||||
> Run `/opsx:onboard` to get started. → [Learn more here](docs/opsx.md)
|
||||
|
||||
<p align="center">
|
||||
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
|
||||
</p>
|
||||
|
||||
### Teams
|
||||
|
||||
Using OpenSpec in a team? [Email here](mailto:teams@openspec.dev) for access to our Slack channel.
|
||||
|
||||
<!-- TODO: Add GIF demo of /opsx:new → /opsx:archive workflow -->
|
||||
|
||||
## See it in action
|
||||
|
||||
```text
|
||||
You: /opsx:new add-dark-mode
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
Ready to create: proposal
|
||||
|
||||
You: /opsx:ff # "fast-forward" - generate all planning docs
|
||||
AI: ✓ proposal.md — why we're doing this, what's changing
|
||||
✓ specs/ — requirements and scenarios
|
||||
✓ design.md — technical approach
|
||||
✓ tasks.md — implementation checklist
|
||||
Ready for implementation!
|
||||
|
||||
You: /opsx:apply
|
||||
AI: Implementing tasks...
|
||||
✓ 1.1 Add theme context provider
|
||||
✓ 1.2 Create toggle component
|
||||
✓ 2.1 Add CSS variables
|
||||
✓ 2.2 Wire up localStorage
|
||||
All tasks complete!
|
||||
|
||||
You: /opsx:archive
|
||||
AI: Archived to openspec/changes/archive/2025-01-23-add-dark-mode/
|
||||
Specs updated. Ready for the next feature.
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><strong>OpenSpec Dashboard</strong></summary>
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
|
||||
</p>
|
||||
|
||||
</details>
|
||||
|
||||
## Quick Start
|
||||
|
||||
**Requires Node.js 20.19.0 or higher.**
|
||||
|
||||
Install OpenSpec globally:
|
||||
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
Then navigate to your project directory and initialize:
|
||||
|
||||
```bash
|
||||
cd your-project
|
||||
openspec init
|
||||
```
|
||||
|
||||
Now tell your AI: `/opsx:new <what-you-want-to-build>`
|
||||
|
||||
> [!NOTE]
|
||||
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 20+ tools and growing.
|
||||
>
|
||||
> Also works with pnpm, yarn, bun, and nix. [See installation options](docs/installation.md).
|
||||
|
||||
## Docs
|
||||
|
||||
→ **[Getting Started](docs/getting-started.md)**: first steps<br>
|
||||
→ **[Workflows](docs/workflows.md)**: combos and patterns<br>
|
||||
→ **[Commands](docs/commands.md)**: slash commands & skills<br>
|
||||
→ **[CLI](docs/cli.md)**: terminal reference<br>
|
||||
→ **[Supported Tools](docs/supported-tools.md)**: tool integrations & install paths<br>
|
||||
→ **[Concepts](docs/concepts.md)**: how it all fits<br>
|
||||
→ **[Multi-Language](docs/multi-language.md)**: multi-language support<br>
|
||||
→ **[Customization](docs/customization.md)**: make it yours
|
||||
|
||||
|
||||
## Why OpenSpec?
|
||||
|
||||
AI coding assistants are powerful but unpredictable when requirements live only in chat history. OpenSpec adds a lightweight spec layer so you agree on what to build before any code is written.
|
||||
|
||||
- **Agree before you build** — human and AI align on specs before code gets written
|
||||
- **Stay organized** — each change gets its own folder with proposal, specs, design, and tasks
|
||||
- **Work fluidly** — update any artifact anytime, no rigid phase gates
|
||||
- **Use your tools** — works with 20+ AI assistants via slash commands
|
||||
|
||||
### How we compare
|
||||
|
||||
**vs. [Spec Kit](https://github.com/github/spec-kit)** (GitHub) — Thorough but heavyweight. Rigid phase gates, lots of Markdown, Python setup. OpenSpec is lighter and lets you iterate freely.
|
||||
|
||||
**vs. [Kiro](https://kiro.dev)** (AWS) — Powerful but you're locked into their IDE and limited to Claude models. OpenSpec works with the tools you already use.
|
||||
|
||||
**vs. nothing** — AI coding without specs means vague prompts and unpredictable results. OpenSpec brings predictability without the ceremony.
|
||||
|
||||
## Updating OpenSpec
|
||||
|
||||
**Upgrade the package**
|
||||
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
**Refresh agent instructions**
|
||||
|
||||
Run this inside each project to regenerate AI guidance and ensure the latest slash commands are active:
|
||||
|
||||
```bash
|
||||
openspec update
|
||||
```
|
||||
|
||||
## Usage Notes
|
||||
|
||||
**Model selection**: OpenSpec works best with high-reasoning models. We recommend Opus 4.5 and GPT 5.2 for both planning and implementation.
|
||||
|
||||
**Context hygiene**: OpenSpec benefits from a clean context window. Clear your context before starting implementation and maintain good context hygiene throughout your session.
|
||||
|
||||
## Contributing
|
||||
|
||||
**Small fixes** — Bug fixes, typo corrections, and minor improvements can be submitted directly as PRs.
|
||||
|
||||
**Larger changes** — For new features, significant refactors, or architectural changes, please submit an OpenSpec change proposal first so we can align on intent and goals before implementation begins.
|
||||
|
||||
When writing proposals, keep the OpenSpec philosophy in mind: we serve a wide variety of users across different coding agents, models, and use cases. Changes should work well for everyone.
|
||||
|
||||
**AI-generated code is welcome** — as long as it's been tested and verified. PRs containing AI-generated code should mention the coding agent and model used (e.g., "Generated with Claude Code using claude-opus-4-5-20251101").
|
||||
|
||||
### Development
|
||||
|
||||
- Install dependencies: `pnpm install`
|
||||
- Build: `pnpm run build`
|
||||
- Test: `pnpm test`
|
||||
- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
|
||||
- Conventional commits (one-line): `type(scope): subject`
|
||||
|
||||
## Other
|
||||
|
||||
<details>
|
||||
<summary><strong>Telemetry</strong></summary>
|
||||
|
||||
OpenSpec collects anonymous usage stats.
|
||||
|
||||
We collect only command names and version to understand usage patterns. No arguments, paths, content, or PII. Automatically disabled in CI.
|
||||
|
||||
**Opt-out:** `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Maintainers & Advisors</strong></summary>
|
||||
|
||||
See [MAINTAINERS.md](MAINTAINERS.md) for the list of core maintainers and advisors who help guide the project.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
+475
@@ -0,0 +1,475 @@
|
||||
<p align="center">
|
||||
<a href="https://github.com/Fission-AI/OpenSpec">
|
||||
<picture>
|
||||
<source srcset="assets/openspec_pixel_dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<source srcset="assets/openspec_pixel_light.svg" media="(prefers-color-scheme: light)">
|
||||
<img src="assets/openspec_pixel_light.svg" alt="OpenSpec logo" height="64">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
</p>
|
||||
<p align="center">Spec-driven development for AI coding assistants.</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
|
||||
<a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
|
||||
<a href="https://nodejs.org/"><img alt="node version" src="https://img.shields.io/node/v/@fission-ai/openspec?style=flat-square" /></a>
|
||||
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
|
||||
<a href="https://conventionalcommits.org"><img alt="Conventional Commits" src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square" /></a>
|
||||
<a href="https://discord.gg/YctCnvvshC"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join%20the%20community-5865F2?logo=discord&logoColor=white&style=flat-square" /></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<sub>🧪 <strong>New:</strong> <a href="docs/opsx.md">OPSX Workflow</a> — schema-driven, hackable, fluid. Iterate on workflows without code changes.</sub>
|
||||
</p>
|
||||
|
||||
# OpenSpec
|
||||
|
||||
OpenSpec aligns humans and AI coding assistants with spec-driven development so you agree on what to build before any code is written. **No API keys required.**
|
||||
|
||||
## Why OpenSpec?
|
||||
|
||||
AI coding assistants are powerful but unpredictable when requirements live in chat history. OpenSpec adds a lightweight specification workflow that locks intent before implementation, giving you deterministic, reviewable outputs.
|
||||
|
||||
Key outcomes:
|
||||
- Human and AI stakeholders agree on specs before work begins.
|
||||
- Structured change folders (proposals, tasks, and spec updates) keep scope explicit and auditable.
|
||||
- Shared visibility into what's proposed, active, or archived.
|
||||
- Works with the AI tools you already use: custom slash commands where supported, context rules everywhere else.
|
||||
|
||||
## How OpenSpec compares (at a glance)
|
||||
|
||||
- **Lightweight**: simple workflow, no API keys, minimal setup.
|
||||
- **Brownfield-first**: works great beyond 0→1. OpenSpec separates the source of truth from proposals: `openspec/specs/` (current truth) and `openspec/changes/` (proposed updates). This keeps diffs explicit and manageable across features.
|
||||
- **Change tracking**: proposals, tasks, and spec deltas live together; archiving merges the approved updates back into specs.
|
||||
- **Compared to spec-kit & Kiro**: those shine for brand-new features (0→1). OpenSpec also excels when modifying existing behavior (1→n), especially when updates span multiple specs.
|
||||
|
||||
See the full comparison in [How OpenSpec Compares](#how-openspec-compares).
|
||||
|
||||
## How It Works
|
||||
|
||||
```
|
||||
┌────────────────────┐
|
||||
│ Draft Change │
|
||||
│ Proposal │
|
||||
└────────┬───────────┘
|
||||
│ share intent with your AI
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Review & Align │
|
||||
│ (edit specs/tasks) │◀──── feedback loop ──────┐
|
||||
└────────┬───────────┘ │
|
||||
│ approved plan │
|
||||
▼ │
|
||||
┌────────────────────┐ │
|
||||
│ Implement Tasks │──────────────────────────┘
|
||||
│ (AI writes code) │
|
||||
└────────┬───────────┘
|
||||
│ ship the change
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Archive & Update │
|
||||
│ Specs (source) │
|
||||
└────────────────────┘
|
||||
|
||||
1. Draft a change proposal that captures the spec updates you want.
|
||||
2. Review the proposal with your AI assistant until everyone agrees.
|
||||
3. Implement tasks that reference the agreed specs.
|
||||
4. Archive the change to merge the approved updates back into the source-of-truth specs.
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Supported AI Tools
|
||||
|
||||
<details>
|
||||
<summary><strong>Native Slash Commands</strong> (click to expand)</summary>
|
||||
|
||||
These tools have built-in OpenSpec commands. Select the OpenSpec integration when prompted.
|
||||
|
||||
| Tool | Commands |
|
||||
|------|----------|
|
||||
| **Amazon Q Developer** | `@openspec-proposal`, `@openspec-apply`, `@openspec-archive` (`.amazonq/prompts/`) |
|
||||
| **Antigravity** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.agent/workflows/`) |
|
||||
| **Auggie (Augment CLI)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.augment/commands/`) |
|
||||
| **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` |
|
||||
| **Cline** | Workflows in `.clinerules/workflows/` directory (`.clinerules/workflows/openspec-*.md`) |
|
||||
| **CodeBuddy Code (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.codebuddy/commands/`) — see [docs](https://www.codebuddy.ai/cli) |
|
||||
| **Codex** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (global: `~/.codex/prompts`, auto-installed) |
|
||||
| **Continue** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.continue/prompts/`) |
|
||||
| **CoStrict** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.cospec/openspec/commands/`) — see [docs](https://costrict.ai)|
|
||||
| **Crush** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.crush/commands/openspec/`) |
|
||||
| **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
|
||||
| **Factory Droid** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.factory/commands/`) |
|
||||
| **Gemini CLI** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.gemini/commands/openspec/`) |
|
||||
| **GitHub Copilot** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.github/prompts/`) |
|
||||
| **iFlow (iflow-cli)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.iflow/commands/`) |
|
||||
| **Kilo Code** | `/openspec-proposal.md`, `/openspec-apply.md`, `/openspec-archive.md` (`.kilocode/workflows/`) |
|
||||
| **OpenCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
|
||||
| **Qoder** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.qoder/commands/openspec/`) — see [docs](https://qoder.com) |
|
||||
| **Qwen Code** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.qwen/commands/`) |
|
||||
| **RooCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.roo/commands/`) |
|
||||
| **Windsurf** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.windsurf/workflows/`) |
|
||||
|
||||
Kilo Code discovers team workflows automatically. Save the generated files under `.kilocode/workflows/` and trigger them from the command palette with `/openspec-proposal.md`, `/openspec-apply.md`, or `/openspec-archive.md`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>AGENTS.md Compatible</strong> (click to expand)</summary>
|
||||
|
||||
These tools automatically read workflow instructions from `openspec/AGENTS.md`. Ask them to follow the OpenSpec workflow if they need a reminder. Learn more about the [AGENTS.md convention](https://agents.md/).
|
||||
|
||||
| Tools |
|
||||
|-------|
|
||||
| Amp • Jules • Others |
|
||||
|
||||
</details>
|
||||
|
||||
### Install & Initialize
|
||||
|
||||
#### Prerequisites
|
||||
- **Node.js >= 20.19.0** - Check your version with `node --version`
|
||||
|
||||
#### Step 1: Install the CLI globally
|
||||
|
||||
**Option A: Using npm**
|
||||
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
Verify installation:
|
||||
```bash
|
||||
openspec --version
|
||||
```
|
||||
|
||||
**Option B: Using Nix (NixOS and Nix package manager)**
|
||||
|
||||
Run OpenSpec directly without installation:
|
||||
```bash
|
||||
nix run github:Fission-AI/OpenSpec -- init
|
||||
```
|
||||
|
||||
Or install to your profile:
|
||||
```bash
|
||||
nix profile install github:Fission-AI/OpenSpec
|
||||
```
|
||||
|
||||
Or add to your development environment in `flake.nix`:
|
||||
```nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
openspec.url = "github:Fission-AI/OpenSpec";
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, openspec, ... }: {
|
||||
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
|
||||
buildInputs = [ openspec.packages.x86_64-linux.default ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Verify installation:
|
||||
```bash
|
||||
openspec --version
|
||||
```
|
||||
|
||||
#### Step 2: Initialize OpenSpec in your project
|
||||
|
||||
Navigate to your project directory:
|
||||
```bash
|
||||
cd my-project
|
||||
```
|
||||
|
||||
Run the initialization:
|
||||
```bash
|
||||
openspec init
|
||||
```
|
||||
|
||||
**What happens during initialization:**
|
||||
- You'll be prompted to pick any natively supported AI tools (Claude Code, CodeBuddy, Cursor, OpenCode, Qoder,etc.); other assistants always rely on the shared `AGENTS.md` stub
|
||||
- OpenSpec automatically configures slash commands for the tools you choose and always writes a managed `AGENTS.md` hand-off at the project root
|
||||
- A new `openspec/` directory structure is created in your project
|
||||
|
||||
**After setup:**
|
||||
- Primary AI tools can trigger `/openspec` workflows without additional configuration
|
||||
- Run `openspec list` to verify the setup and view any active changes
|
||||
- If your coding assistant doesn't surface the new slash commands right away, restart it. Slash commands are loaded at startup,
|
||||
so a fresh launch ensures they appear
|
||||
|
||||
### Optional: Populate Project Context
|
||||
|
||||
After `openspec init` completes, you'll receive a suggested prompt to help populate your project context:
|
||||
|
||||
```text
|
||||
Populate your project context:
|
||||
"Please read openspec/project.md and help me fill it out with details about my project, tech stack, and conventions"
|
||||
```
|
||||
|
||||
Use `openspec/project.md` to define project-level conventions, standards, architectural patterns, and other guidelines that should be followed across all changes.
|
||||
|
||||
### Create Your First Change
|
||||
|
||||
Here's a real example showing the complete OpenSpec workflow. This works with any AI tool. Those with native slash commands will recognize the shortcuts automatically.
|
||||
|
||||
#### 1. Draft the Proposal
|
||||
Start by asking your AI to create a change proposal:
|
||||
|
||||
```text
|
||||
You: Create an OpenSpec change proposal for adding profile search filters by role and team
|
||||
(Shortcut for tools with slash commands: /openspec:proposal Add profile search filters)
|
||||
|
||||
AI: I'll create an OpenSpec change proposal for profile filters.
|
||||
*Scaffolds openspec/changes/add-profile-filters/ with proposal.md, tasks.md, spec deltas.*
|
||||
```
|
||||
|
||||
#### 2. Verify & Review
|
||||
Check that the change was created correctly and review the proposal:
|
||||
|
||||
```bash
|
||||
$ openspec list # Confirm the change folder exists
|
||||
$ openspec validate add-profile-filters # Validate spec formatting
|
||||
$ openspec show add-profile-filters # Review proposal, tasks, and spec delta
|
||||
```
|
||||
|
||||
#### 3. Refine the Specs
|
||||
Iterate on the specifications until they match your needs:
|
||||
|
||||
```text
|
||||
You: Can you add acceptance criteria for the role and team filters?
|
||||
|
||||
AI: I'll update the spec delta with scenarios for role and team filters.
|
||||
*Edits openspec/changes/add-profile-filters/specs/profile/spec.md and tasks.md.*
|
||||
```
|
||||
|
||||
#### 4. Implement the Change
|
||||
Once specs look good, start implementation:
|
||||
|
||||
```text
|
||||
You: The specs look good. Let's implement this change.
|
||||
(Shortcut for tools with slash commands: /openspec:apply add-profile-filters)
|
||||
|
||||
AI: I'll work through the tasks in the add-profile-filters change.
|
||||
*Implements tasks from openspec/changes/add-profile-filters/tasks.md*
|
||||
*Marks tasks complete: Task 1.1 ✓, Task 1.2 ✓, Task 2.1 ✓...*
|
||||
```
|
||||
|
||||
#### 5. Archive the Completed Change
|
||||
After implementation is complete, archive the change:
|
||||
|
||||
```text
|
||||
AI: All tasks are complete. The implementation is ready.
|
||||
|
||||
You: Please archive the change
|
||||
(Shortcut for tools with slash commands: /openspec:archive add-profile-filters)
|
||||
|
||||
AI: I'll archive the add-profile-filters change.
|
||||
*Runs: openspec archive add-profile-filters --yes*
|
||||
✓ Change archived successfully. Specs updated. Ready for the next feature!
|
||||
```
|
||||
|
||||
Or run the command yourself in terminal:
|
||||
```bash
|
||||
$ openspec archive add-profile-filters --yes # Archive the completed change without prompts
|
||||
```
|
||||
|
||||
**Note:** Tools with native slash commands (Claude Code, CodeBuddy, Cursor, Codex, Qoder, RooCode) can use the shortcuts shown. All other tools work with natural language requests to "create an OpenSpec proposal", "apply the OpenSpec change", or "archive the change".
|
||||
|
||||
## Command Reference
|
||||
|
||||
```bash
|
||||
openspec list # View active change folders
|
||||
openspec view # Interactive dashboard of specs and changes
|
||||
openspec show <change> # Display change details (proposal, tasks, spec updates)
|
||||
openspec validate <change> # Check spec formatting and structure
|
||||
openspec archive <change> [--yes|-y] # Move a completed change into archive/ (non-interactive with --yes)
|
||||
```
|
||||
|
||||
## Example: How AI Creates OpenSpec Files
|
||||
|
||||
When you ask your AI assistant to "add two-factor authentication", it creates:
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── specs/
|
||||
│ └── auth/
|
||||
│ └── spec.md # Current auth spec (if exists)
|
||||
└── changes/
|
||||
└── add-2fa/ # AI creates this entire structure
|
||||
├── proposal.md # Why and what changes
|
||||
├── tasks.md # Implementation checklist
|
||||
├── design.md # Technical decisions (optional)
|
||||
└── specs/
|
||||
└── auth/
|
||||
└── spec.md # Delta showing additions
|
||||
```
|
||||
|
||||
### AI-Generated Spec (created in `openspec/specs/auth/spec.md`):
|
||||
|
||||
```markdown
|
||||
# Auth Specification
|
||||
|
||||
## Purpose
|
||||
Authentication and session management.
|
||||
|
||||
## Requirements
|
||||
### Requirement: User Authentication
|
||||
The system SHALL issue a JWT on successful login.
|
||||
|
||||
#### Scenario: Valid credentials
|
||||
- WHEN a user submits valid credentials
|
||||
- THEN a JWT is returned
|
||||
```
|
||||
|
||||
### AI-Generated Change Delta (created in `openspec/changes/add-2fa/specs/auth/spec.md`):
|
||||
|
||||
```markdown
|
||||
# Delta for Auth
|
||||
|
||||
## ADDED Requirements
|
||||
### Requirement: Two-Factor Authentication
|
||||
The system MUST require a second factor during login.
|
||||
|
||||
#### Scenario: OTP required
|
||||
- WHEN a user submits valid credentials
|
||||
- THEN an OTP challenge is required
|
||||
```
|
||||
|
||||
### AI-Generated Tasks (created in `openspec/changes/add-2fa/tasks.md`):
|
||||
|
||||
```markdown
|
||||
## 1. Database Setup
|
||||
- [ ] 1.1 Add OTP secret column to users table
|
||||
- [ ] 1.2 Create OTP verification logs table
|
||||
|
||||
## 2. Backend Implementation
|
||||
- [ ] 2.1 Add OTP generation endpoint
|
||||
- [ ] 2.2 Modify login flow to require OTP
|
||||
- [ ] 2.3 Add OTP verification endpoint
|
||||
|
||||
## 3. Frontend Updates
|
||||
- [ ] 3.1 Create OTP input component
|
||||
- [ ] 3.2 Update login flow UI
|
||||
```
|
||||
|
||||
**Important:** You don't create these files manually. Your AI assistant generates them based on your requirements and the existing codebase.
|
||||
|
||||
## Understanding OpenSpec Files
|
||||
|
||||
### Delta Format
|
||||
|
||||
Deltas are "patches" that show how specs change:
|
||||
|
||||
- **`## ADDED Requirements`** - New capabilities
|
||||
- **`## MODIFIED Requirements`** - Changed behavior (include complete updated text)
|
||||
- **`## REMOVED Requirements`** - Deprecated features
|
||||
|
||||
**Format requirements:**
|
||||
- Use `### Requirement: <name>` for headers
|
||||
- Every requirement needs at least one `#### Scenario:` block
|
||||
- Use SHALL/MUST in requirement text
|
||||
|
||||
## How OpenSpec Compares
|
||||
|
||||
### vs. spec-kit
|
||||
OpenSpec’s two-folder model (`openspec/specs/` for the current truth, `openspec/changes/` for proposed updates) keeps state and diffs separate. This scales when you modify existing features or touch multiple specs. spec-kit is strong for greenfield/0→1 but provides less structure for cross-spec updates and evolving features.
|
||||
|
||||
### vs. Kiro.dev
|
||||
OpenSpec groups every change for a feature in one folder (`openspec/changes/feature-name/`), making it easy to track related specs, tasks, and designs together. Kiro spreads updates across multiple spec folders, which can make feature tracking harder.
|
||||
|
||||
### vs. No Specs
|
||||
Without specs, AI coding assistants generate code from vague prompts, often missing requirements or adding unwanted features. OpenSpec brings predictability by agreeing on the desired behavior before any code is written.
|
||||
|
||||
## Team Adoption
|
||||
|
||||
1. **Initialize OpenSpec** – Run `openspec init` in your repo.
|
||||
2. **Start with new features** – Ask your AI to capture upcoming work as change proposals.
|
||||
3. **Grow incrementally** – Each change archives into living specs that document your system.
|
||||
4. **Stay flexible** – Different teammates can use Claude Code, CodeBuddy, Cursor, or any AGENTS.md-compatible tool while sharing the same specs.
|
||||
|
||||
Run `openspec update` whenever someone switches tools so your agents pick up the latest instructions and slash-command bindings.
|
||||
|
||||
## Updating OpenSpec
|
||||
|
||||
1. **Upgrade the package**
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
2. **Refresh agent instructions**
|
||||
- Run `openspec update` inside each project to regenerate AI guidance and ensure the latest slash commands are active.
|
||||
|
||||
## Experimental Features
|
||||
|
||||
<details>
|
||||
<summary><strong>🧪 OPSX: Fluid, Iterative Workflow</strong> (Claude Code only)</summary>
|
||||
|
||||
**Why this exists:**
|
||||
- Standard workflow is locked down — you can't tweak instructions or customize
|
||||
- When AI output is bad, you can't improve the prompts yourself
|
||||
- Same workflow for everyone, no way to match how your team works
|
||||
|
||||
**What's different:**
|
||||
- **Hackable** — edit templates and schemas yourself, test immediately, no rebuild
|
||||
- **Granular** — each artifact has its own instructions, test and tweak individually
|
||||
- **Customizable** — define your own workflows, artifacts, and dependencies
|
||||
- **Fluid** — no phase gates, update any artifact anytime
|
||||
|
||||
```
|
||||
You can always go back:
|
||||
|
||||
proposal ──→ specs ──→ design ──→ tasks ──→ implement
|
||||
▲ ▲ ▲ │
|
||||
└───────────┴──────────┴────────────────────┘
|
||||
```
|
||||
|
||||
| Command | What it does |
|
||||
|---------|--------------|
|
||||
| `/opsx:new` | Start a new change |
|
||||
| `/opsx:continue` | Create the next artifact (based on what's ready) |
|
||||
| `/opsx:ff` | Fast-forward (all planning artifacts at once) |
|
||||
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
|
||||
| `/opsx:archive` | Archive when done |
|
||||
|
||||
**Setup:** `openspec experimental`
|
||||
|
||||
[Full documentation →](docs/opsx.md)
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Telemetry</strong> – OpenSpec collects anonymous usage stats (opt-out: <code>OPENSPEC_TELEMETRY=0</code>)</summary>
|
||||
|
||||
We collect only command names and version to understand usage patterns. No arguments, paths, content, or PII. Automatically disabled in CI.
|
||||
|
||||
**Opt-out:** `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`
|
||||
|
||||
</details>
|
||||
|
||||
## Contributing
|
||||
|
||||
- Install dependencies: `pnpm install`
|
||||
- Build: `pnpm run build`
|
||||
- Test: `pnpm test`
|
||||
- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
|
||||
- Conventional commits (one-line): `type(scope): subject`
|
||||
|
||||
<details>
|
||||
<summary><strong>Maintainers & Advisors</strong></summary>
|
||||
|
||||
See [MAINTAINERS.md](MAINTAINERS.md) for the list of core maintainers and advisors who help guide the project.
|
||||
|
||||
</details>
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 450 KiB |
@@ -0,0 +1,89 @@
|
||||
<svg width="640" height="80" viewBox="0 0 640 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M32 0H16V16H32V0Z" fill="white"/>
|
||||
<path d="M48 0H32V16H48V0Z" fill="white"/>
|
||||
<path d="M16 16H0V32H16V16Z" fill="white"/>
|
||||
<path d="M64 16H48V32H64V16Z" fill="white"/>
|
||||
<path d="M16 32H0V48H16V32Z" fill="white"/>
|
||||
<path d="M64 32H48V48H64V32Z" fill="white"/>
|
||||
<path d="M16 48H0V64H16V48Z" fill="white"/>
|
||||
<path d="M64 48H48V64H64V48Z" fill="white"/>
|
||||
<path d="M32 64H16V80H32V64Z" fill="white"/>
|
||||
<path d="M48 64H32V80H48V64Z" fill="white"/>
|
||||
<path d="M96 0H80V16H96V0Z" fill="white"/>
|
||||
<path d="M112 0H96V16H112V0Z" fill="white"/>
|
||||
<path d="M128 0H112V16H128V0Z" fill="white"/>
|
||||
<path d="M96 16H80V32H96V16Z" fill="white"/>
|
||||
<path d="M144 16H128V32H144V16Z" fill="white"/>
|
||||
<path d="M96 32H80V48H96V32Z" fill="white"/>
|
||||
<path d="M112 32H96V48H112V32Z" fill="white"/>
|
||||
<path d="M128 32H112V48H128V32Z" fill="white"/>
|
||||
<path d="M144 32H128V48H144V32Z" fill="white"/>
|
||||
<path d="M96 48H80V64H96V48Z" fill="white"/>
|
||||
<path d="M96 64H80V80H96V64Z" fill="white"/>
|
||||
<path d="M176 0H160V16H176V0Z" fill="white"/>
|
||||
<path d="M192 0H176V16H192V0Z" fill="white"/>
|
||||
<path d="M208 0H192V16H208V0Z" fill="white"/>
|
||||
<path d="M224 0H208V16H224V0Z" fill="white"/>
|
||||
<path d="M176 16H160V32H176V16Z" fill="white"/>
|
||||
<path d="M176 32H160V48H176V32Z" fill="white"/>
|
||||
<path d="M192 32H176V48H192V32Z" fill="white"/>
|
||||
<path d="M208 32H192V48H208V32Z" fill="white"/>
|
||||
<path d="M176 48H160V64H176V48Z" fill="white"/>
|
||||
<path d="M176 64H160V80H176V64Z" fill="white"/>
|
||||
<path d="M192 64H176V80H192V64Z" fill="white"/>
|
||||
<path d="M208 64H192V80H208V64Z" fill="white"/>
|
||||
<path d="M224 64H208V80H224V64Z" fill="white"/>
|
||||
<path d="M256 0H240V16H256V0Z" fill="white"/>
|
||||
<path d="M304 0H288V16H304V0Z" fill="white"/>
|
||||
<path d="M256 16H240V32H256V16Z" fill="white"/>
|
||||
<path d="M272 16H256V32H272V16Z" fill="white"/>
|
||||
<path d="M304 16H288V32H304V16Z" fill="white"/>
|
||||
<path d="M256 32H240V48H256V32Z" fill="white"/>
|
||||
<path d="M288 32H272V48H288V32Z" fill="white"/>
|
||||
<path d="M304 32H288V48H304V32Z" fill="white"/>
|
||||
<path d="M256 48H240V64H256V48Z" fill="white"/>
|
||||
<path d="M304 48H288V64H304V48Z" fill="white"/>
|
||||
<path d="M256 64H240V80H256V64Z" fill="white"/>
|
||||
<path d="M304 64H288V80H304V64Z" fill="white"/>
|
||||
<path d="M352 0H336V16H352V0Z" fill="white"/>
|
||||
<path d="M368 0H352V16H368V0Z" fill="white"/>
|
||||
<path d="M384 0H368V16H384V0Z" fill="white"/>
|
||||
<path d="M336 16H320V32H336V16Z" fill="white"/>
|
||||
<path d="M352 32H336V48H352V32Z" fill="white"/>
|
||||
<path d="M368 32H352V48H368V32Z" fill="white"/>
|
||||
<path d="M384 48H368V64H384V48Z" fill="white"/>
|
||||
<path d="M336 64H320V80H336V64Z" fill="white"/>
|
||||
<path d="M352 64H336V80H352V64Z" fill="white"/>
|
||||
<path d="M368 64H352V80H368V64Z" fill="white"/>
|
||||
<path d="M416 0H400V16H416V0Z" fill="white"/>
|
||||
<path d="M432 0H416V16H432V0Z" fill="white"/>
|
||||
<path d="M448 0H432V16H448V0Z" fill="white"/>
|
||||
<path d="M416 16H400V32H416V16Z" fill="white"/>
|
||||
<path d="M464 16H448V32H464V16Z" fill="white"/>
|
||||
<path d="M416 32H400V48H416V32Z" fill="white"/>
|
||||
<path d="M432 32H416V48H432V32Z" fill="white"/>
|
||||
<path d="M448 32H432V48H448V32Z" fill="white"/>
|
||||
<path d="M464 32H448V48H464V32Z" fill="white"/>
|
||||
<path d="M416 48H400V64H416V48Z" fill="white"/>
|
||||
<path d="M416 64H400V80H416V64Z" fill="white"/>
|
||||
<path d="M496 0H480V16H496V0Z" fill="white"/>
|
||||
<path d="M512 0H496V16H512V0Z" fill="white"/>
|
||||
<path d="M528 0H512V16H528V0Z" fill="white"/>
|
||||
<path d="M544 0H528V16H544V0Z" fill="white"/>
|
||||
<path d="M496 16H480V32H496V16Z" fill="white"/>
|
||||
<path d="M496 32H480V48H496V32Z" fill="white"/>
|
||||
<path d="M512 32H496V48H512V32Z" fill="white"/>
|
||||
<path d="M528 32H512V48H528V32Z" fill="white"/>
|
||||
<path d="M496 48H480V64H496V48Z" fill="white"/>
|
||||
<path d="M496 64H480V80H496V64Z" fill="white"/>
|
||||
<path d="M512 64H496V80H512V64Z" fill="white"/>
|
||||
<path d="M528 64H512V80H528V64Z" fill="white"/>
|
||||
<path d="M544 64H528V80H544V64Z" fill="white"/>
|
||||
<path d="M592 0H576V16H592V0Z" fill="white"/>
|
||||
<path d="M608 0H592V16H608V0Z" fill="white"/>
|
||||
<path d="M576 16H560V32H576V16Z" fill="white"/>
|
||||
<path d="M576 32H560V48H576V32Z" fill="white"/>
|
||||
<path d="M576 48H560V64H576V48Z" fill="white"/>
|
||||
<path d="M592 64H576V80H592V64Z" fill="white"/>
|
||||
<path d="M608 64H592V80H608V64Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,89 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="80" viewBox="0 0 640 80">
|
||||
<rect x="16" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="32" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="0" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="48" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="0" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="48" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="0" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="48" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="16" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="32" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="96" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="112" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="128" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="96" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="112" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="128" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="80" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="176" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="192" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="208" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="176" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="192" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="160" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="176" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="192" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="208" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="256" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="272" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="240" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="288" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="336" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="352" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="368" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="320" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="336" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="352" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="368" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="320" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="336" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="352" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="416" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="432" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="448" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="416" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="432" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="448" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="400" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="496" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="512" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="528" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="496" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="512" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="480" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="496" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="512" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="528" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="576" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="592" y="0" width="16" height="16" fill="black" />
|
||||
<rect x="560" y="16" width="16" height="16" fill="black" />
|
||||
<rect x="560" y="32" width="16" height="16" fill="black" />
|
||||
<rect x="560" y="48" width="16" height="16" fill="black" />
|
||||
<rect x="576" y="64" width="16" height="16" fill="black" />
|
||||
<rect x="592" y="64" width="16" height="16" fill="black" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
@@ -1,7 +1,15 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { execSync } from 'child_process';
|
||||
import { execFileSync } from 'child_process';
|
||||
import { existsSync, rmSync } from 'fs';
|
||||
import { createRequire } from 'module';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const runTsc = (args = []) => {
|
||||
const tscPath = require.resolve('typescript/bin/tsc');
|
||||
execFileSync(process.execPath, [tscPath, ...args], { stdio: 'inherit' });
|
||||
};
|
||||
|
||||
console.log('🔨 Building OpenSpec...\n');
|
||||
|
||||
@@ -11,12 +19,13 @@ if (existsSync('dist')) {
|
||||
rmSync('dist', { recursive: true, force: true });
|
||||
}
|
||||
|
||||
// Run TypeScript compiler
|
||||
// Run TypeScript compiler (use local version explicitly)
|
||||
console.log('Compiling TypeScript...');
|
||||
try {
|
||||
execSync('tsc', { stdio: 'inherit' });
|
||||
runTsc(['--version']);
|
||||
runTsc();
|
||||
console.log('\n✅ Build completed successfully!');
|
||||
} catch (error) {
|
||||
console.error('\n❌ Build failed!');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
+894
@@ -0,0 +1,894 @@
|
||||
# CLI Reference
|
||||
|
||||
The OpenSpec CLI (`openspec`) provides terminal commands for project setup, validation, status inspection, and management. These commands complement the AI slash commands (like `/opsx:new`) documented in [Commands](commands.md).
|
||||
|
||||
## Summary
|
||||
|
||||
| Category | Commands | Purpose |
|
||||
|----------|----------|---------|
|
||||
| **Setup** | `init`, `update` | Initialize and update OpenSpec in your project |
|
||||
| **Browsing** | `list`, `view`, `show` | Explore changes and specs |
|
||||
| **Validation** | `validate` | Check changes and specs for issues |
|
||||
| **Lifecycle** | `archive` | Finalize completed changes |
|
||||
| **Workflow** | `status`, `instructions`, `templates`, `schemas` | Artifact-driven workflow support |
|
||||
| **Schemas** | `schema init`, `schema fork`, `schema validate`, `schema which` | Create and manage custom workflows |
|
||||
| **Config** | `config` | View and modify settings |
|
||||
| **Utility** | `feedback`, `completion` | Feedback and shell integration |
|
||||
|
||||
---
|
||||
|
||||
## Human vs Agent Commands
|
||||
|
||||
Most CLI commands are designed for **human use** in a terminal. Some commands also support **agent/script use** via JSON output.
|
||||
|
||||
### Human-Only Commands
|
||||
|
||||
These commands are interactive and designed for terminal use:
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `openspec init` | Initialize project (interactive prompts) |
|
||||
| `openspec view` | Interactive dashboard |
|
||||
| `openspec config edit` | Open config in editor |
|
||||
| `openspec feedback` | Submit feedback via GitHub |
|
||||
| `openspec completion install` | Install shell completions |
|
||||
|
||||
### Agent-Compatible Commands
|
||||
|
||||
These commands support `--json` output for programmatic use by AI agents and scripts:
|
||||
|
||||
| Command | Human Use | Agent Use |
|
||||
|---------|-----------|-----------|
|
||||
| `openspec list` | Browse changes/specs | `--json` for structured data |
|
||||
| `openspec show <item>` | Read content | `--json` for parsing |
|
||||
| `openspec validate` | Check for issues | `--all --json` for bulk validation |
|
||||
| `openspec status` | See artifact progress | `--json` for structured status |
|
||||
| `openspec instructions` | Get next steps | `--json` for agent instructions |
|
||||
| `openspec templates` | Find template paths | `--json` for path resolution |
|
||||
| `openspec schemas` | List available schemas | `--json` for schema discovery |
|
||||
|
||||
---
|
||||
|
||||
## Global Options
|
||||
|
||||
These options work with all commands:
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--version`, `-V` | Show version number |
|
||||
| `--no-color` | Disable color output |
|
||||
| `--help`, `-h` | Display help for command |
|
||||
|
||||
---
|
||||
|
||||
## Setup Commands
|
||||
|
||||
### `openspec init`
|
||||
|
||||
Initialize OpenSpec in your project. Creates the folder structure and configures AI tool integrations.
|
||||
|
||||
```
|
||||
openspec init [path] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `path` | No | Target directory (default: current directory) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--tools <list>` | Configure AI tools non-interactively. Use `all`, `none`, or comma-separated list |
|
||||
| `--force` | Auto-cleanup legacy files without prompting |
|
||||
|
||||
**Supported tools:** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `opencode`, `qoder`, `qwen`, `roocode`, `windsurf`
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive initialization
|
||||
openspec init
|
||||
|
||||
# Initialize in a specific directory
|
||||
openspec init ./my-project
|
||||
|
||||
# Non-interactive: configure for Claude and Cursor
|
||||
openspec init --tools claude,cursor
|
||||
|
||||
# Configure for all supported tools
|
||||
openspec init --tools all
|
||||
|
||||
# Skip prompts and auto-cleanup legacy files
|
||||
openspec init --force
|
||||
```
|
||||
|
||||
**What it creates:**
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── specs/ # Your specifications (source of truth)
|
||||
├── changes/ # Proposed changes
|
||||
└── config.yaml # Project configuration
|
||||
|
||||
.claude/skills/ # Claude Code skill files (if claude selected)
|
||||
.cursor/rules/ # Cursor rules (if cursor selected)
|
||||
... (other tool configs)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec update`
|
||||
|
||||
Update OpenSpec instruction files after upgrading the CLI. Re-generates AI tool configuration files.
|
||||
|
||||
```
|
||||
openspec update [path] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `path` | No | Target directory (default: current directory) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--force` | Force update even when files are up to date |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
# Update instruction files after npm upgrade
|
||||
npm update @fission-ai/openspec
|
||||
openspec update
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Browsing Commands
|
||||
|
||||
### `openspec list`
|
||||
|
||||
List changes or specs in your project.
|
||||
|
||||
```
|
||||
openspec list [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--specs` | List specs instead of changes |
|
||||
| `--changes` | List changes (default) |
|
||||
| `--sort <order>` | Sort by `recent` (default) or `name` |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# List all active changes
|
||||
openspec list
|
||||
|
||||
# List all specs
|
||||
openspec list --specs
|
||||
|
||||
# JSON output for scripts
|
||||
openspec list --json
|
||||
```
|
||||
|
||||
**Output (text):**
|
||||
|
||||
```
|
||||
Active changes:
|
||||
add-dark-mode UI theme switching support
|
||||
fix-login-bug Session timeout handling
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec view`
|
||||
|
||||
Display an interactive dashboard for exploring specs and changes.
|
||||
|
||||
```
|
||||
openspec view
|
||||
```
|
||||
|
||||
Opens a terminal-based interface for navigating your project's specifications and changes.
|
||||
|
||||
---
|
||||
|
||||
### `openspec show`
|
||||
|
||||
Display details of a change or spec.
|
||||
|
||||
```
|
||||
openspec show [item-name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `item-name` | No | Name of change or spec (prompts if omitted) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--type <type>` | Specify type: `change` or `spec` (auto-detected if unambiguous) |
|
||||
| `--json` | Output as JSON |
|
||||
| `--no-interactive` | Disable prompts |
|
||||
|
||||
**Change-specific options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--deltas-only` | Show only delta specs (JSON mode) |
|
||||
|
||||
**Spec-specific options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--requirements` | Show only requirements, exclude scenarios (JSON mode) |
|
||||
| `--no-scenarios` | Exclude scenario content (JSON mode) |
|
||||
| `-r, --requirement <id>` | Show specific requirement by 1-based index (JSON mode) |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive selection
|
||||
openspec show
|
||||
|
||||
# Show a specific change
|
||||
openspec show add-dark-mode
|
||||
|
||||
# Show a specific spec
|
||||
openspec show auth --type spec
|
||||
|
||||
# JSON output for parsing
|
||||
openspec show add-dark-mode --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Commands
|
||||
|
||||
### `openspec validate`
|
||||
|
||||
Validate changes and specs for structural issues.
|
||||
|
||||
```
|
||||
openspec validate [item-name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `item-name` | No | Specific item to validate (prompts if omitted) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--all` | Validate all changes and specs |
|
||||
| `--changes` | Validate all changes |
|
||||
| `--specs` | Validate all specs |
|
||||
| `--type <type>` | Specify type when name is ambiguous: `change` or `spec` |
|
||||
| `--strict` | Enable strict validation mode |
|
||||
| `--json` | Output as JSON |
|
||||
| `--concurrency <n>` | Max parallel validations (default: 6, or `OPENSPEC_CONCURRENCY` env) |
|
||||
| `--no-interactive` | Disable prompts |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive validation
|
||||
openspec validate
|
||||
|
||||
# Validate a specific change
|
||||
openspec validate add-dark-mode
|
||||
|
||||
# Validate all changes
|
||||
openspec validate --changes
|
||||
|
||||
# Validate everything with JSON output (for CI/scripts)
|
||||
openspec validate --all --json
|
||||
|
||||
# Strict validation with increased parallelism
|
||||
openspec validate --all --strict --concurrency 12
|
||||
```
|
||||
|
||||
**Output (text):**
|
||||
|
||||
```
|
||||
Validating add-dark-mode...
|
||||
✓ proposal.md valid
|
||||
✓ specs/ui/spec.md valid
|
||||
⚠ design.md: missing "Technical Approach" section
|
||||
|
||||
1 warning found
|
||||
```
|
||||
|
||||
**Output (JSON):**
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"results": {
|
||||
"changes": [
|
||||
{
|
||||
"name": "add-dark-mode",
|
||||
"valid": true,
|
||||
"warnings": ["design.md: missing 'Technical Approach' section"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"total": 1,
|
||||
"valid": 1,
|
||||
"invalid": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lifecycle Commands
|
||||
|
||||
### `openspec archive`
|
||||
|
||||
Archive a completed change and merge delta specs into main specs.
|
||||
|
||||
```
|
||||
openspec archive [change-name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Change to archive (prompts if omitted) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `-y, --yes` | Skip confirmation prompts |
|
||||
| `--skip-specs` | Skip spec updates (for infrastructure/tooling/doc-only changes) |
|
||||
| `--no-validate` | Skip validation (requires confirmation) |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive archive
|
||||
openspec archive
|
||||
|
||||
# Archive specific change
|
||||
openspec archive add-dark-mode
|
||||
|
||||
# Archive without prompts (CI/scripts)
|
||||
openspec archive add-dark-mode --yes
|
||||
|
||||
# Archive a tooling change that doesn't affect specs
|
||||
openspec archive update-ci-config --skip-specs
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
|
||||
1. Validates the change (unless `--no-validate`)
|
||||
2. Prompts for confirmation (unless `--yes`)
|
||||
3. Merges delta specs into `openspec/specs/`
|
||||
4. Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`
|
||||
|
||||
---
|
||||
|
||||
## Workflow Commands
|
||||
|
||||
These commands support the artifact-driven OPSX workflow. They're useful for both humans checking progress and agents determining next steps.
|
||||
|
||||
### `openspec status`
|
||||
|
||||
Display artifact completion status for a change.
|
||||
|
||||
```
|
||||
openspec status [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--change <id>` | Change name (prompts if omitted) |
|
||||
| `--schema <name>` | Schema override (auto-detected from change's config) |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive status check
|
||||
openspec status
|
||||
|
||||
# Status for specific change
|
||||
openspec status --change add-dark-mode
|
||||
|
||||
# JSON for agent use
|
||||
openspec status --change add-dark-mode --json
|
||||
```
|
||||
|
||||
**Output (text):**
|
||||
|
||||
```
|
||||
Change: add-dark-mode
|
||||
Schema: spec-driven
|
||||
|
||||
Artifacts:
|
||||
✓ proposal proposal.md exists
|
||||
✓ specs specs/ exists
|
||||
◆ design ready (requires: specs)
|
||||
○ tasks blocked (requires: design)
|
||||
|
||||
Next: Create design using /opsx:continue
|
||||
```
|
||||
|
||||
**Output (JSON):**
|
||||
|
||||
```json
|
||||
{
|
||||
"change": "add-dark-mode",
|
||||
"schema": "spec-driven",
|
||||
"artifacts": [
|
||||
{"id": "proposal", "status": "complete", "path": "proposal.md"},
|
||||
{"id": "specs", "status": "complete", "path": "specs/"},
|
||||
{"id": "design", "status": "ready", "requires": ["specs"]},
|
||||
{"id": "tasks", "status": "blocked", "requires": ["design"]}
|
||||
],
|
||||
"next": "design"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec instructions`
|
||||
|
||||
Get enriched instructions for creating an artifact or applying tasks. Used by AI agents to understand what to create next.
|
||||
|
||||
```
|
||||
openspec instructions [artifact] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `artifact` | No | Artifact ID: `proposal`, `specs`, `design`, `tasks`, or `apply` |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--change <id>` | Change name (required in non-interactive mode) |
|
||||
| `--schema <name>` | Schema override |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Special case:** Use `apply` as the artifact to get task implementation instructions.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Get instructions for next artifact
|
||||
openspec instructions --change add-dark-mode
|
||||
|
||||
# Get specific artifact instructions
|
||||
openspec instructions design --change add-dark-mode
|
||||
|
||||
# Get apply/implementation instructions
|
||||
openspec instructions apply --change add-dark-mode
|
||||
|
||||
# JSON for agent consumption
|
||||
openspec instructions design --change add-dark-mode --json
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
|
||||
- Template content for the artifact
|
||||
- Project context from config
|
||||
- Content from dependency artifacts
|
||||
- Per-artifact rules from config
|
||||
|
||||
---
|
||||
|
||||
### `openspec templates`
|
||||
|
||||
Show resolved template paths for all artifacts in a schema.
|
||||
|
||||
```
|
||||
openspec templates [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--schema <name>` | Schema to inspect (default: `spec-driven`) |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Show template paths for default schema
|
||||
openspec templates
|
||||
|
||||
# Show templates for custom schema
|
||||
openspec templates --schema my-workflow
|
||||
|
||||
# JSON for programmatic use
|
||||
openspec templates --json
|
||||
```
|
||||
|
||||
**Output (text):**
|
||||
|
||||
```
|
||||
Schema: spec-driven
|
||||
|
||||
Templates:
|
||||
proposal → ~/.openspec/schemas/spec-driven/templates/proposal.md
|
||||
specs → ~/.openspec/schemas/spec-driven/templates/specs.md
|
||||
design → ~/.openspec/schemas/spec-driven/templates/design.md
|
||||
tasks → ~/.openspec/schemas/spec-driven/templates/tasks.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec schemas`
|
||||
|
||||
List available workflow schemas with their descriptions and artifact flows.
|
||||
|
||||
```
|
||||
openspec schemas [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
openspec schemas
|
||||
```
|
||||
|
||||
**Output:**
|
||||
|
||||
```
|
||||
Available schemas:
|
||||
|
||||
spec-driven (package)
|
||||
The default spec-driven development workflow
|
||||
Flow: proposal → specs → design → tasks
|
||||
|
||||
my-custom (project)
|
||||
Custom workflow for this project
|
||||
Flow: research → proposal → tasks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Schema Commands
|
||||
|
||||
Commands for creating and managing custom workflow schemas.
|
||||
|
||||
### `openspec schema init`
|
||||
|
||||
Create a new project-local schema.
|
||||
|
||||
```
|
||||
openspec schema init <name> [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `name` | Yes | Schema name (kebab-case) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--description <text>` | Schema description |
|
||||
| `--artifacts <list>` | Comma-separated artifact IDs (default: `proposal,specs,design,tasks`) |
|
||||
| `--default` | Set as project default schema |
|
||||
| `--no-default` | Don't prompt to set as default |
|
||||
| `--force` | Overwrite existing schema |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Interactive schema creation
|
||||
openspec schema init research-first
|
||||
|
||||
# Non-interactive with specific artifacts
|
||||
openspec schema init rapid \
|
||||
--description "Rapid iteration workflow" \
|
||||
--artifacts "proposal,tasks" \
|
||||
--default
|
||||
```
|
||||
|
||||
**What it creates:**
|
||||
|
||||
```
|
||||
openspec/schemas/<name>/
|
||||
├── schema.yaml # Schema definition
|
||||
└── templates/
|
||||
├── proposal.md # Template for each artifact
|
||||
├── specs.md
|
||||
├── design.md
|
||||
└── tasks.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec schema fork`
|
||||
|
||||
Copy an existing schema to your project for customization.
|
||||
|
||||
```
|
||||
openspec schema fork <source> [name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `source` | Yes | Schema to copy |
|
||||
| `name` | No | New schema name (default: `<source>-custom`) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--force` | Overwrite existing destination |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
# Fork the built-in spec-driven schema
|
||||
openspec schema fork spec-driven my-workflow
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec schema validate`
|
||||
|
||||
Validate a schema's structure and templates.
|
||||
|
||||
```
|
||||
openspec schema validate [name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `name` | No | Schema to validate (validates all if omitted) |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--verbose` | Show detailed validation steps |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
# Validate a specific schema
|
||||
openspec schema validate my-workflow
|
||||
|
||||
# Validate all schemas
|
||||
openspec schema validate
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec schema which`
|
||||
|
||||
Show where a schema resolves from (useful for debugging precedence).
|
||||
|
||||
```
|
||||
openspec schema which [name] [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `name` | No | Schema name |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--all` | List all schemas with their sources |
|
||||
| `--json` | Output as JSON |
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
# Check where a schema comes from
|
||||
openspec schema which spec-driven
|
||||
```
|
||||
|
||||
**Output:**
|
||||
|
||||
```
|
||||
spec-driven resolves from: package
|
||||
Source: /usr/local/lib/node_modules/@fission-ai/openspec/schemas/spec-driven
|
||||
```
|
||||
|
||||
**Schema precedence:**
|
||||
|
||||
1. Project: `openspec/schemas/<name>/`
|
||||
2. User: `~/.local/share/openspec/schemas/<name>/`
|
||||
3. Package: Built-in schemas
|
||||
|
||||
---
|
||||
|
||||
## Configuration Commands
|
||||
|
||||
### `openspec config`
|
||||
|
||||
View and modify global OpenSpec configuration.
|
||||
|
||||
```
|
||||
openspec config <subcommand> [options]
|
||||
```
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|-------------|
|
||||
| `path` | Show config file location |
|
||||
| `list` | Show all current settings |
|
||||
| `get <key>` | Get a specific value |
|
||||
| `set <key> <value>` | Set a value |
|
||||
| `unset <key>` | Remove a key |
|
||||
| `reset` | Reset to defaults |
|
||||
| `edit` | Open in `$EDITOR` |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Show config file path
|
||||
openspec config path
|
||||
|
||||
# List all settings
|
||||
openspec config list
|
||||
|
||||
# Get a specific value
|
||||
openspec config get telemetry.enabled
|
||||
|
||||
# Set a value
|
||||
openspec config set telemetry.enabled false
|
||||
|
||||
# Set a string value explicitly
|
||||
openspec config set user.name "My Name" --string
|
||||
|
||||
# Remove a custom setting
|
||||
openspec config unset user.name
|
||||
|
||||
# Reset all configuration
|
||||
openspec config reset --all --yes
|
||||
|
||||
# Edit config in your editor
|
||||
openspec config edit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Utility Commands
|
||||
|
||||
### `openspec feedback`
|
||||
|
||||
Submit feedback about OpenSpec. Creates a GitHub issue.
|
||||
|
||||
```
|
||||
openspec feedback <message> [options]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `message` | Yes | Feedback message |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--body <text>` | Detailed description |
|
||||
|
||||
**Requirements:** GitHub CLI (`gh`) must be installed and authenticated.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
openspec feedback "Add support for custom artifact types" \
|
||||
--body "I'd like to define my own artifact types beyond the built-in ones."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `openspec completion`
|
||||
|
||||
Manage shell completions for the OpenSpec CLI.
|
||||
|
||||
```
|
||||
openspec completion <subcommand> [shell]
|
||||
```
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|-------------|
|
||||
| `generate [shell]` | Output completion script to stdout |
|
||||
| `install [shell]` | Install completion for your shell |
|
||||
| `uninstall [shell]` | Remove installed completions |
|
||||
|
||||
**Supported shells:** `bash`, `zsh`, `fish`, `powershell`
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Install completions (auto-detects shell)
|
||||
openspec completion install
|
||||
|
||||
# Install for specific shell
|
||||
openspec completion install zsh
|
||||
|
||||
# Generate script for manual installation
|
||||
openspec completion generate bash > ~/.bash_completion.d/openspec
|
||||
|
||||
# Uninstall
|
||||
openspec completion uninstall
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exit Codes
|
||||
|
||||
| Code | Meaning |
|
||||
|------|---------|
|
||||
| `0` | Success |
|
||||
| `1` | Error (validation failure, missing files, etc.) |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `OPENSPEC_CONCURRENCY` | Default concurrency for bulk validation (default: 6) |
|
||||
| `EDITOR` or `VISUAL` | Editor for `openspec config edit` |
|
||||
| `NO_COLOR` | Disable color output when set |
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Commands](commands.md) - AI slash commands (`/opsx:new`, `/opsx:apply`, etc.)
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each command
|
||||
- [Customization](customization.md) - Create custom schemas and templates
|
||||
- [Getting Started](getting-started.md) - First-time setup guide
|
||||
@@ -0,0 +1,653 @@
|
||||
# Commands
|
||||
|
||||
This is the reference for OpenSpec's slash commands. These commands are invoked in your AI coding assistant's chat interface (e.g., Claude Code, Cursor, Windsurf).
|
||||
|
||||
For workflow patterns and when to use each command, see [Workflows](workflows.md). For CLI commands, see [CLI](cli.md).
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:explore` | Think through ideas before committing to a change |
|
||||
| `/opsx:new` | Start a new change |
|
||||
| `/opsx:continue` | Create the next artifact based on dependencies |
|
||||
| `/opsx:ff` | Fast-forward: create all planning artifacts at once |
|
||||
| `/opsx:apply` | Implement tasks from the change |
|
||||
| `/opsx:verify` | Validate implementation matches artifacts |
|
||||
| `/opsx:sync` | Merge delta specs into main specs |
|
||||
| `/opsx:archive` | Archive a completed change |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes at once |
|
||||
| `/opsx:onboard` | Guided tutorial through the complete workflow |
|
||||
|
||||
---
|
||||
|
||||
## Command Reference
|
||||
|
||||
### `/opsx:explore`
|
||||
|
||||
Think through ideas, investigate problems, and clarify requirements before committing to a change.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:explore [topic]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `topic` | No | What you want to explore or investigate |
|
||||
|
||||
**What it does:**
|
||||
- Opens an exploratory conversation with no structure required
|
||||
- Investigates the codebase to answer questions
|
||||
- Compares options and approaches
|
||||
- Creates visual diagrams to clarify thinking
|
||||
- Can transition to `/opsx:new` when insights crystallize
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
You: /opsx:explore
|
||||
|
||||
AI: What would you like to explore?
|
||||
|
||||
You: How should we handle authentication for the mobile app?
|
||||
|
||||
AI: Let me investigate your current auth setup...
|
||||
[Analyzes codebase]
|
||||
|
||||
I see you're using session-based auth for the web app.
|
||||
For mobile, we have three main options:
|
||||
|
||||
1. JWT tokens (stateless, works offline)
|
||||
2. OAuth2 (if you need third-party login)
|
||||
3. Extend current sessions (simpler, but requires connectivity)
|
||||
|
||||
Your API already has CORS configured. Which direction interests you?
|
||||
|
||||
You: Let's go with JWT. Can we start a change for that?
|
||||
|
||||
AI: Ready when you are. Run /opsx:new add-jwt-auth to begin.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use when requirements are unclear or you need to investigate
|
||||
- No artifacts are created during exploration
|
||||
- Good for comparing multiple approaches before deciding
|
||||
- Can read files and search the codebase
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:new`
|
||||
|
||||
Start a new change. Creates the change folder structure and scaffolds it with the selected schema.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:new [change-name] [--schema <schema-name>]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Name for the change folder (prompted if not provided) |
|
||||
| `--schema` | No | Workflow schema to use (default: from config or `spec-driven`) |
|
||||
|
||||
**What it does:**
|
||||
- Creates `openspec/changes/<change-name>/` directory
|
||||
- Creates `.openspec.yaml` metadata file in the change folder
|
||||
- Shows the first artifact template ready for creation
|
||||
- Prompts for change name and schema if not provided
|
||||
|
||||
**What it creates:**
|
||||
```
|
||||
openspec/changes/<change-name>/
|
||||
└── .openspec.yaml # Change metadata (schema, created date)
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:new add-dark-mode
|
||||
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
Schema: spec-driven
|
||||
|
||||
Ready to create: proposal
|
||||
Use /opsx:continue to create it, or /opsx:ff to create all artifacts.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use descriptive names: `add-feature`, `fix-bug`, `refactor-module`
|
||||
- Avoid generic names like `update`, `changes`, `wip`
|
||||
- Schema can also be set in project config (`openspec/config.yaml`)
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:continue`
|
||||
|
||||
Create the next artifact in the dependency chain. Creates one artifact at a time for incremental progress.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:continue [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to continue (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Queries the artifact dependency graph
|
||||
- Shows which artifacts are ready vs blocked
|
||||
- Creates the first ready artifact
|
||||
- Reads dependency files for context
|
||||
- Shows what becomes available after creation
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:continue
|
||||
|
||||
AI: Change: add-dark-mode
|
||||
|
||||
Artifact status:
|
||||
✓ proposal (done)
|
||||
◆ specs (ready)
|
||||
◆ design (ready)
|
||||
○ tasks (blocked - needs: specs)
|
||||
|
||||
Creating specs...
|
||||
|
||||
[Reads proposal.md, creates specs based on requirements]
|
||||
|
||||
✓ Created openspec/changes/add-dark-mode/specs/ui/spec.md
|
||||
|
||||
Now available: tasks
|
||||
Run /opsx:continue to create the next artifact.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use when you want to review each artifact before proceeding
|
||||
- Good for complex changes where you want control
|
||||
- Multiple artifacts may become ready simultaneously
|
||||
- You can edit created artifacts before continuing
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:ff`
|
||||
|
||||
Fast-forward through artifact creation. Creates all planning artifacts at once.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:ff [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to fast-forward (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Creates all artifacts in dependency order
|
||||
- Tracks progress via todo list
|
||||
- Stops when all `apply-required` artifacts are complete
|
||||
- Reads each dependency before creating the next artifact
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:ff add-dark-mode
|
||||
|
||||
AI: Fast-forwarding add-dark-mode...
|
||||
|
||||
✓ Creating proposal.md
|
||||
✓ Creating specs/ui/spec.md
|
||||
✓ Creating design.md
|
||||
✓ Creating tasks.md
|
||||
|
||||
All planning artifacts complete!
|
||||
Ready for implementation. Run /opsx:apply to begin.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use when you have a clear picture of what you're building
|
||||
- Faster than `/opsx:continue` for straightforward changes
|
||||
- You can still edit artifacts afterward
|
||||
- Good for small to medium features
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:apply`
|
||||
|
||||
Implement tasks from the change. Works through the task list, writing code and checking off items.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:apply [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to implement (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Reads `tasks.md` and identifies incomplete tasks
|
||||
- Works through tasks one by one
|
||||
- Writes code, creates files, runs tests as needed
|
||||
- Marks tasks complete with checkboxes `[x]`
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Implementing add-dark-mode...
|
||||
|
||||
Reading tasks.md:
|
||||
- [ ] 1.1 Create ThemeContext
|
||||
- [ ] 1.2 Add CSS custom properties
|
||||
- [ ] 1.3 Implement localStorage persistence
|
||||
|
||||
Working on 1.1: Create ThemeContext...
|
||||
[Creates src/context/ThemeContext.tsx]
|
||||
|
||||
✓ 1.1 Complete
|
||||
|
||||
Working on 1.2: Add CSS custom properties...
|
||||
[Updates src/styles/globals.css]
|
||||
|
||||
✓ 1.2 Complete
|
||||
...
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Can resume where you left off if interrupted
|
||||
- Use for parallel changes by specifying the change name
|
||||
- Completion state is tracked in `tasks.md` checkboxes
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:verify`
|
||||
|
||||
Validate that implementation matches your change artifacts. Checks completeness, correctness, and coherence.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:verify [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to verify (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Checks three dimensions of implementation quality
|
||||
- Searches codebase for implementation evidence
|
||||
- Reports issues categorized as CRITICAL, WARNING, or SUGGESTION
|
||||
- Does not block archive, but surfaces issues
|
||||
|
||||
**Verification dimensions:**
|
||||
|
||||
| Dimension | What it validates |
|
||||
|-----------|-------------------|
|
||||
| **Completeness** | All tasks done, all requirements implemented, scenarios covered |
|
||||
| **Correctness** | Implementation matches spec intent, edge cases handled |
|
||||
| **Coherence** | Design decisions reflected in code, patterns consistent |
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:verify
|
||||
|
||||
AI: Verifying add-dark-mode...
|
||||
|
||||
COMPLETENESS
|
||||
✓ All 8 tasks in tasks.md are checked
|
||||
✓ All requirements in specs have corresponding code
|
||||
⚠ Scenario "System preference detection" has no test coverage
|
||||
|
||||
CORRECTNESS
|
||||
✓ Implementation matches spec intent
|
||||
✓ Edge cases from scenarios are handled
|
||||
✓ Error states match spec definitions
|
||||
|
||||
COHERENCE
|
||||
✓ Design decisions reflected in code structure
|
||||
✓ Naming conventions consistent with design.md
|
||||
⚠ Design mentions "CSS variables" but implementation uses Tailwind classes
|
||||
|
||||
SUMMARY
|
||||
─────────────────────────────
|
||||
Critical issues: 0
|
||||
Warnings: 2
|
||||
Ready to archive: Yes (with warnings)
|
||||
|
||||
Recommendations:
|
||||
1. Add test for system preference detection
|
||||
2. Update design.md to reflect Tailwind usage, or refactor to use CSS variables
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Run before archiving to catch mismatches early
|
||||
- Warnings don't block archive but indicate potential issues
|
||||
- Good for reviewing AI's work before committing
|
||||
- Can reveal drift between artifacts and implementation
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:sync`
|
||||
|
||||
**Optional command.** Merge delta specs from a change into main specs. Archive will prompt to sync if needed, so you typically don't need to run this manually.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:sync [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to sync (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Reads delta specs from change folder
|
||||
- Parses ADDED/MODIFIED/REMOVED/RENAMED sections
|
||||
- Merges changes into main `openspec/specs/` directory
|
||||
- Preserves existing content not mentioned in delta
|
||||
- Does not archive the change (remains active)
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
You: /opsx:sync
|
||||
|
||||
AI: Syncing add-dark-mode delta specs...
|
||||
|
||||
Reading: openspec/changes/add-dark-mode/specs/ui/spec.md
|
||||
Target: openspec/specs/ui/spec.md
|
||||
|
||||
Changes to apply:
|
||||
✓ ADDED: Theme Selection requirement (2 scenarios)
|
||||
✓ ADDED: Accessibility requirement (1 scenario)
|
||||
|
||||
Merging...
|
||||
✓ openspec/specs/ui/spec.md updated
|
||||
|
||||
Change remains active. Run /opsx:archive when ready to complete.
|
||||
```
|
||||
|
||||
**When to use manually:**
|
||||
|
||||
| Scenario | Use sync? |
|
||||
|----------|-----------|
|
||||
| Long-running change, want specs in main before archiving | Yes |
|
||||
| Multiple parallel changes need the updated base specs | Yes |
|
||||
| Want to preview/review the merge separately | Yes |
|
||||
| Quick change, going straight to archive | No (archive handles it) |
|
||||
|
||||
**Tips:**
|
||||
- Sync is intelligent, not copy-paste
|
||||
- Can add scenarios to existing requirements without duplicating
|
||||
- Change stays active after sync (not archived)
|
||||
- Most users will never need to call this directly—archive prompts if needed
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:archive`
|
||||
|
||||
Archive a completed change. Finalizes the change and moves it to the archive folder.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:archive [change-name]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name` | No | Which change to archive (inferred from context if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Checks artifact completion status
|
||||
- Checks task completion (warns if incomplete)
|
||||
- Offers to sync delta specs if not already synced
|
||||
- Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`
|
||||
- Preserves all artifacts for audit trail
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
You: /opsx:archive
|
||||
|
||||
AI: Archiving add-dark-mode...
|
||||
|
||||
Artifact status:
|
||||
✓ proposal.md exists
|
||||
✓ specs/ exists
|
||||
✓ design.md exists
|
||||
✓ tasks.md exists (8/8 tasks complete)
|
||||
|
||||
Delta specs: Not yet synced
|
||||
→ Sync now? (recommended)
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: ✓ Synced specs to openspec/specs/ui/spec.md
|
||||
✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/
|
||||
|
||||
Change archived successfully.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Archive won't block on incomplete tasks, but will warn
|
||||
- Delta specs can be synced during archive or beforehand
|
||||
- Archived changes are preserved for history
|
||||
- Use `/opsx:verify` first to catch issues
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:bulk-archive`
|
||||
|
||||
Archive multiple completed changes at once. Handles spec conflicts between changes.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:bulk-archive [change-names...]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-names` | No | Specific changes to archive (prompts to select if not provided) |
|
||||
|
||||
**What it does:**
|
||||
- Lists all completed changes
|
||||
- Validates each change before archiving
|
||||
- Detects spec conflicts across changes
|
||||
- Resolves conflicts by checking what's actually implemented
|
||||
- Archives in chronological order
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:bulk-archive
|
||||
|
||||
AI: Found 3 completed changes:
|
||||
- add-dark-mode (8/8 tasks complete)
|
||||
- fix-login-bug (3/3 tasks complete)
|
||||
- update-footer (2/2 tasks complete)
|
||||
|
||||
Checking for spec conflicts...
|
||||
⚠ add-dark-mode and update-footer both touch specs/ui/
|
||||
|
||||
Inspecting codebase to resolve...
|
||||
Both changes are implemented. Will merge in chronological order:
|
||||
1. add-dark-mode (created Jan 20)
|
||||
2. update-footer (created Jan 22)
|
||||
|
||||
Archive all 3 changes?
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: ✓ Archived add-dark-mode
|
||||
✓ Archived fix-login-bug
|
||||
✓ Archived update-footer
|
||||
Specs merged: add-dark-mode → update-footer
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Good for parallel work streams
|
||||
- Conflict resolution is agentic (checks codebase)
|
||||
- Changes are archived in order of creation
|
||||
- Prompts before overwriting spec content
|
||||
|
||||
---
|
||||
|
||||
### `/opsx:onboard`
|
||||
|
||||
Guided onboarding through the complete OpenSpec workflow. An interactive tutorial using your actual codebase.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
/opsx:onboard
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
- Walks through a complete workflow cycle with narration
|
||||
- Scans your codebase for real improvement opportunities
|
||||
- Creates an actual change with real artifacts
|
||||
- Implements actual work (small, safe changes)
|
||||
- Archives the completed change
|
||||
- Explains each step as it happens
|
||||
|
||||
**Phases:**
|
||||
1. Welcome and codebase analysis
|
||||
2. Finding an improvement opportunity
|
||||
3. Creating a change (`/opsx:new`)
|
||||
4. Writing the proposal
|
||||
5. Creating specs
|
||||
6. Writing the design
|
||||
7. Creating tasks
|
||||
8. Implementing tasks (`/opsx:apply`)
|
||||
9. Verifying implementation
|
||||
10. Archiving the change
|
||||
11. Summary and next steps
|
||||
|
||||
**Example:**
|
||||
```
|
||||
You: /opsx:onboard
|
||||
|
||||
AI: Welcome to OpenSpec!
|
||||
|
||||
I'll walk you through the complete workflow using your actual codebase.
|
||||
We'll find something small to improve, create a proper change for it,
|
||||
implement it, and archive it.
|
||||
|
||||
Let me scan your codebase for opportunities...
|
||||
|
||||
[Analyzes codebase]
|
||||
|
||||
I found a few things we could work on:
|
||||
1. Add input validation to the contact form
|
||||
2. Improve error messages in the auth flow
|
||||
3. Add loading states to async buttons
|
||||
|
||||
Which interests you? (or suggest something else)
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Best for new users learning the workflow
|
||||
- Uses real code, not toy examples
|
||||
- Creates a real change you can keep or discard
|
||||
- Takes 15-30 minutes to complete
|
||||
|
||||
---
|
||||
|
||||
## Command Syntax by AI Tool
|
||||
|
||||
Different AI tools use slightly different command syntax. Use the format that matches your tool:
|
||||
|
||||
| Tool | Syntax Example |
|
||||
|------|----------------|
|
||||
| Claude Code | `/opsx:new`, `/opsx:apply` |
|
||||
| Cursor | `/opsx-new`, `/opsx-apply` |
|
||||
| Windsurf | `/opsx-new`, `/opsx-apply` |
|
||||
| Copilot | `/opsx-new`, `/opsx-apply` |
|
||||
| Trae | `/openspec-new-change`, `/openspec-apply-change` |
|
||||
|
||||
The functionality is identical regardless of syntax.
|
||||
|
||||
---
|
||||
|
||||
## Legacy Commands
|
||||
|
||||
These commands use the older "all-at-once" workflow. They still work but OPSX commands are recommended.
|
||||
|
||||
| Command | What it does |
|
||||
|---------|--------------|
|
||||
| `/openspec:proposal` | Create all artifacts at once (proposal, specs, design, tasks) |
|
||||
| `/openspec:apply` | Implement the change |
|
||||
| `/openspec:archive` | Archive the change |
|
||||
|
||||
**When to use legacy commands:**
|
||||
- Existing projects using the old workflow
|
||||
- Simple changes where you don't need incremental artifact creation
|
||||
- Preference for the all-or-nothing approach
|
||||
|
||||
**Migrating to OPSX:**
|
||||
Legacy changes can be continued with OPSX commands. The artifact structure is compatible.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Change not found"
|
||||
|
||||
The command couldn't identify which change to work on.
|
||||
|
||||
**Solutions:**
|
||||
- Specify the change name explicitly: `/opsx:apply add-dark-mode`
|
||||
- Check that the change folder exists: `openspec list`
|
||||
- Verify you're in the right project directory
|
||||
|
||||
### "No artifacts ready"
|
||||
|
||||
All artifacts are either complete or blocked by missing dependencies.
|
||||
|
||||
**Solutions:**
|
||||
- Run `openspec status --change <name>` to see what's blocking
|
||||
- Check if required artifacts exist
|
||||
- Create missing dependency artifacts first
|
||||
|
||||
### "Schema not found"
|
||||
|
||||
The specified schema doesn't exist.
|
||||
|
||||
**Solutions:**
|
||||
- List available schemas: `openspec schemas`
|
||||
- Check spelling of schema name
|
||||
- Create the schema if it's custom: `openspec schema init <name>`
|
||||
|
||||
### Commands not recognized
|
||||
|
||||
The AI tool doesn't recognize OpenSpec commands.
|
||||
|
||||
**Solutions:**
|
||||
- Ensure OpenSpec is initialized: `openspec init`
|
||||
- Regenerate skills: `openspec update`
|
||||
- Check that `.claude/skills/` directory exists (for Claude Code)
|
||||
- Restart your AI tool to pick up new skills
|
||||
|
||||
### Artifacts not generating properly
|
||||
|
||||
The AI creates incomplete or incorrect artifacts.
|
||||
|
||||
**Solutions:**
|
||||
- Add project context in `openspec/config.yaml`
|
||||
- Add per-artifact rules for specific guidance
|
||||
- Provide more detail in your change description
|
||||
- Use `/opsx:continue` instead of `/opsx:ff` for more control
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each command
|
||||
- [CLI](cli.md) - Terminal commands for management and validation
|
||||
- [Customization](customization.md) - Create custom schemas and workflows
|
||||
@@ -0,0 +1,582 @@
|
||||
# Concepts
|
||||
|
||||
This guide explains the core ideas behind OpenSpec and how they fit together. For practical usage, see [Getting Started](getting-started.md) and [Workflows](workflows.md).
|
||||
|
||||
## Philosophy
|
||||
|
||||
OpenSpec is built around four principles:
|
||||
|
||||
```
|
||||
fluid not rigid — no phase gates, work on what makes sense
|
||||
iterative not waterfall — learn as you build, refine as you go
|
||||
easy not complex — lightweight setup, minimal ceremony
|
||||
brownfield-first — works with existing codebases, not just greenfield
|
||||
```
|
||||
|
||||
### Why These Principles Matter
|
||||
|
||||
**Fluid not rigid.** Traditional spec systems lock you into phases: first you plan, then you implement, then you're done. OpenSpec is more flexible — you can create artifacts in any order that makes sense for your work.
|
||||
|
||||
**Iterative not waterfall.** Requirements change. Understanding deepens. What seemed like a good approach at the start might not hold up after you see the codebase. OpenSpec embraces this reality.
|
||||
|
||||
**Easy not complex.** Some spec frameworks require extensive setup, rigid formats, or heavyweight processes. OpenSpec stays out of your way. Initialize in seconds, start working immediately, customize only if you need to.
|
||||
|
||||
**Brownfield-first.** Most software work isn't building from scratch — it's modifying existing systems. OpenSpec's delta-based approach makes it easy to specify changes to existing behavior, not just describe new systems.
|
||||
|
||||
## The Big Picture
|
||||
|
||||
OpenSpec organizes your work into two main areas:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ openspec/ │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌──────────────────────────────┐ │
|
||||
│ │ specs/ │ │ changes/ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ Source of truth │◄─────│ Proposed modifications │ │
|
||||
│ │ How your system │ merge│ Each change = one folder │ │
|
||||
│ │ currently works │ │ Contains artifacts + deltas │ │
|
||||
│ │ │ │ │ │
|
||||
│ └─────────────────────┘ └──────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Specs** are the source of truth — they describe how your system currently behaves.
|
||||
|
||||
**Changes** are proposed modifications — they live in separate folders until you're ready to merge them.
|
||||
|
||||
This separation is key. You can work on multiple changes in parallel without conflicts. You can review a change before it affects the main specs. And when you archive a change, its deltas merge cleanly into the source of truth.
|
||||
|
||||
## Specs
|
||||
|
||||
Specs describe your system's behavior using structured requirements and scenarios.
|
||||
|
||||
### Structure
|
||||
|
||||
```
|
||||
openspec/specs/
|
||||
├── auth/
|
||||
│ └── spec.md # Authentication behavior
|
||||
├── payments/
|
||||
│ └── spec.md # Payment processing
|
||||
├── notifications/
|
||||
│ └── spec.md # Notification system
|
||||
└── ui/
|
||||
└── spec.md # UI behavior and themes
|
||||
```
|
||||
|
||||
Organize specs by domain — logical groupings that make sense for your system. Common patterns:
|
||||
|
||||
- **By feature area**: `auth/`, `payments/`, `search/`
|
||||
- **By component**: `api/`, `frontend/`, `workers/`
|
||||
- **By bounded context**: `ordering/`, `fulfillment/`, `inventory/`
|
||||
|
||||
### Spec Format
|
||||
|
||||
A spec contains requirements, and each requirement has scenarios:
|
||||
|
||||
```markdown
|
||||
# Auth Specification
|
||||
|
||||
## Purpose
|
||||
Authentication and session management for the application.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: User Authentication
|
||||
The system SHALL issue a JWT token upon successful login.
|
||||
|
||||
#### Scenario: Valid credentials
|
||||
- GIVEN a user with valid credentials
|
||||
- WHEN the user submits login form
|
||||
- THEN a JWT token is returned
|
||||
- AND the user is redirected to dashboard
|
||||
|
||||
#### Scenario: Invalid credentials
|
||||
- GIVEN invalid credentials
|
||||
- WHEN the user submits login form
|
||||
- THEN an error message is displayed
|
||||
- AND no token is issued
|
||||
|
||||
### Requirement: Session Expiration
|
||||
The system MUST expire sessions after 30 minutes of inactivity.
|
||||
|
||||
#### Scenario: Idle timeout
|
||||
- GIVEN an authenticated session
|
||||
- WHEN 30 minutes pass without activity
|
||||
- THEN the session is invalidated
|
||||
- AND the user must re-authenticate
|
||||
```
|
||||
|
||||
**Key elements:**
|
||||
|
||||
| Element | Purpose |
|
||||
|---------|---------|
|
||||
| `## Purpose` | High-level description of this spec's domain |
|
||||
| `### Requirement:` | A specific behavior the system must have |
|
||||
| `#### Scenario:` | A concrete example of the requirement in action |
|
||||
| SHALL/MUST/SHOULD | RFC 2119 keywords indicating requirement strength |
|
||||
|
||||
### Why Structure Specs This Way
|
||||
|
||||
**Requirements are the "what"** — they state what the system should do without specifying implementation.
|
||||
|
||||
**Scenarios are the "when"** — they provide concrete examples that can be verified. Good scenarios:
|
||||
- Are testable (you could write an automated test for them)
|
||||
- Cover both happy path and edge cases
|
||||
- Use Given/When/Then or similar structured format
|
||||
|
||||
**RFC 2119 keywords** (SHALL, MUST, SHOULD, MAY) communicate intent:
|
||||
- **MUST/SHALL** — absolute requirement
|
||||
- **SHOULD** — recommended, but exceptions exist
|
||||
- **MAY** — optional
|
||||
|
||||
## Changes
|
||||
|
||||
A change is a proposed modification to your system, packaged as a folder with everything needed to understand and implement it.
|
||||
|
||||
### Change Structure
|
||||
|
||||
```
|
||||
openspec/changes/add-dark-mode/
|
||||
├── proposal.md # Why and what
|
||||
├── design.md # How (technical approach)
|
||||
├── tasks.md # Implementation checklist
|
||||
├── .openspec.yaml # Change metadata (optional)
|
||||
└── specs/ # Delta specs
|
||||
└── ui/
|
||||
└── spec.md # What's changing in ui/spec.md
|
||||
```
|
||||
|
||||
Each change is self-contained. It has:
|
||||
- **Artifacts** — documents that capture intent, design, and tasks
|
||||
- **Delta specs** — specifications for what's being added, modified, or removed
|
||||
- **Metadata** — optional configuration for this specific change
|
||||
|
||||
### Why Changes Are Folders
|
||||
|
||||
Packaging a change as a folder has several benefits:
|
||||
|
||||
1. **Everything together.** Proposal, design, tasks, and specs live in one place. No hunting through different locations.
|
||||
|
||||
2. **Parallel work.** Multiple changes can exist simultaneously without conflicting. Work on `add-dark-mode` while `fix-auth-bug` is also in progress.
|
||||
|
||||
3. **Clean history.** When archived, changes move to `changes/archive/` with their full context preserved. You can look back and understand not just what changed, but why.
|
||||
|
||||
4. **Review-friendly.** A change folder is easy to review — open it, read the proposal, check the design, see the spec deltas.
|
||||
|
||||
## Artifacts
|
||||
|
||||
Artifacts are the documents within a change that guide the work.
|
||||
|
||||
### The Artifact Flow
|
||||
|
||||
```
|
||||
proposal ──────► specs ──────► design ──────► tasks ──────► implement
|
||||
│ │ │ │
|
||||
why what how steps
|
||||
+ scope changes approach to take
|
||||
```
|
||||
|
||||
Artifacts build on each other. Each artifact provides context for the next.
|
||||
|
||||
### Artifact Types
|
||||
|
||||
#### Proposal (`proposal.md`)
|
||||
|
||||
The proposal captures **intent**, **scope**, and **approach** at a high level.
|
||||
|
||||
```markdown
|
||||
# Proposal: Add Dark Mode
|
||||
|
||||
## Intent
|
||||
Users have requested a dark mode option to reduce eye strain
|
||||
during nighttime usage and match system preferences.
|
||||
|
||||
## Scope
|
||||
In scope:
|
||||
- Theme toggle in settings
|
||||
- System preference detection
|
||||
- Persist preference in localStorage
|
||||
|
||||
Out of scope:
|
||||
- Custom color themes (future work)
|
||||
- Per-page theme overrides
|
||||
|
||||
## Approach
|
||||
Use CSS custom properties for theming with a React context
|
||||
for state management. Detect system preference on first load,
|
||||
allow manual override.
|
||||
```
|
||||
|
||||
**When to update the proposal:**
|
||||
- Scope changes (narrowing or expanding)
|
||||
- Intent clarifies (better understanding of the problem)
|
||||
- Approach fundamentally shifts
|
||||
|
||||
#### Specs (delta specs in `specs/`)
|
||||
|
||||
Delta specs describe **what's changing** relative to the current specs. See [Delta Specs](#delta-specs) below.
|
||||
|
||||
#### Design (`design.md`)
|
||||
|
||||
The design captures **technical approach** and **architecture decisions**.
|
||||
|
||||
```markdown
|
||||
# Design: Add Dark Mode
|
||||
|
||||
## Technical Approach
|
||||
Theme state managed via React Context to avoid prop drilling.
|
||||
CSS custom properties enable runtime switching without class toggling.
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### Decision: Context over Redux
|
||||
Using React Context for theme state because:
|
||||
- Simple binary state (light/dark)
|
||||
- No complex state transitions
|
||||
- Avoids adding Redux dependency
|
||||
|
||||
### Decision: CSS Custom Properties
|
||||
Using CSS variables instead of CSS-in-JS because:
|
||||
- Works with existing stylesheet
|
||||
- No runtime overhead
|
||||
- Browser-native solution
|
||||
|
||||
## Data Flow
|
||||
```
|
||||
ThemeProvider (context)
|
||||
│
|
||||
▼
|
||||
ThemeToggle ◄──► localStorage
|
||||
│
|
||||
▼
|
||||
CSS Variables (applied to :root)
|
||||
```
|
||||
|
||||
## File Changes
|
||||
- `src/contexts/ThemeContext.tsx` (new)
|
||||
- `src/components/ThemeToggle.tsx` (new)
|
||||
- `src/styles/globals.css` (modified)
|
||||
```
|
||||
|
||||
**When to update the design:**
|
||||
- Implementation reveals the approach won't work
|
||||
- Better solution discovered
|
||||
- Dependencies or constraints change
|
||||
|
||||
#### Tasks (`tasks.md`)
|
||||
|
||||
Tasks are the **implementation checklist** — concrete steps with checkboxes.
|
||||
|
||||
```markdown
|
||||
# Tasks
|
||||
|
||||
## 1. Theme Infrastructure
|
||||
- [ ] 1.1 Create ThemeContext with light/dark state
|
||||
- [ ] 1.2 Add CSS custom properties for colors
|
||||
- [ ] 1.3 Implement localStorage persistence
|
||||
- [ ] 1.4 Add system preference detection
|
||||
|
||||
## 2. UI Components
|
||||
- [ ] 2.1 Create ThemeToggle component
|
||||
- [ ] 2.2 Add toggle to settings page
|
||||
- [ ] 2.3 Update Header to include quick toggle
|
||||
|
||||
## 3. Styling
|
||||
- [ ] 3.1 Define dark theme color palette
|
||||
- [ ] 3.2 Update components to use CSS variables
|
||||
- [ ] 3.3 Test contrast ratios for accessibility
|
||||
```
|
||||
|
||||
**Task best practices:**
|
||||
- Group related tasks under headings
|
||||
- Use hierarchical numbering (1.1, 1.2, etc.)
|
||||
- Keep tasks small enough to complete in one session
|
||||
- Check tasks off as you complete them
|
||||
|
||||
## Delta Specs
|
||||
|
||||
Delta specs are the key concept that makes OpenSpec work for brownfield development. They describe **what's changing** rather than restating the entire spec.
|
||||
|
||||
### The Format
|
||||
|
||||
```markdown
|
||||
# Delta for Auth
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Two-Factor Authentication
|
||||
The system MUST support TOTP-based two-factor authentication.
|
||||
|
||||
#### Scenario: 2FA enrollment
|
||||
- GIVEN a user without 2FA enabled
|
||||
- WHEN the user enables 2FA in settings
|
||||
- THEN a QR code is displayed for authenticator app setup
|
||||
- AND the user must verify with a code before activation
|
||||
|
||||
#### Scenario: 2FA login
|
||||
- GIVEN a user with 2FA enabled
|
||||
- WHEN the user submits valid credentials
|
||||
- THEN an OTP challenge is presented
|
||||
- AND login completes only after valid OTP
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Session Expiration
|
||||
The system MUST expire sessions after 15 minutes of inactivity.
|
||||
(Previously: 30 minutes)
|
||||
|
||||
#### Scenario: Idle timeout
|
||||
- GIVEN an authenticated session
|
||||
- WHEN 15 minutes pass without activity
|
||||
- THEN the session is invalidated
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Remember Me
|
||||
(Deprecated in favor of 2FA. Users should re-authenticate each session.)
|
||||
```
|
||||
|
||||
### Delta Sections
|
||||
|
||||
| Section | Meaning | What Happens on Archive |
|
||||
|---------|---------|------------------------|
|
||||
| `## ADDED Requirements` | New behavior | Appended to main spec |
|
||||
| `## MODIFIED Requirements` | Changed behavior | Replaces existing requirement |
|
||||
| `## REMOVED Requirements` | Deprecated behavior | Deleted from main spec |
|
||||
|
||||
### Why Deltas Instead of Full Specs
|
||||
|
||||
**Clarity.** A delta shows exactly what's changing. Reading a full spec, you'd have to diff it mentally against the current version.
|
||||
|
||||
**Conflict avoidance.** Two changes can touch the same spec file without conflicting, as long as they modify different requirements.
|
||||
|
||||
**Review efficiency.** Reviewers see the change, not the unchanged context. Focus on what matters.
|
||||
|
||||
**Brownfield fit.** Most work modifies existing behavior. Deltas make modifications first-class, not an afterthought.
|
||||
|
||||
## Schemas
|
||||
|
||||
Schemas define the artifact types and their dependencies for a workflow.
|
||||
|
||||
### How Schemas Work
|
||||
|
||||
```yaml
|
||||
# openspec/schemas/spec-driven/schema.yaml
|
||||
name: spec-driven
|
||||
artifacts:
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
requires: [] # No dependencies, can create first
|
||||
|
||||
- id: specs
|
||||
generates: specs/**/*.md
|
||||
requires: [proposal] # Needs proposal before creating
|
||||
|
||||
- id: design
|
||||
generates: design.md
|
||||
requires: [proposal] # Can create in parallel with specs
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
requires: [specs, design] # Needs both specs and design first
|
||||
```
|
||||
|
||||
**Artifacts form a dependency graph:**
|
||||
|
||||
```
|
||||
proposal
|
||||
(root node)
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
specs design
|
||||
(requires: (requires:
|
||||
proposal) proposal)
|
||||
│ │
|
||||
└─────────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
tasks
|
||||
(requires:
|
||||
specs, design)
|
||||
```
|
||||
|
||||
**Dependencies are enablers, not gates.** They show what's possible to create, not what you must create next. You can skip design if you don't need it. You can create specs before or after design — both depend only on proposal.
|
||||
|
||||
### Built-in Schemas
|
||||
|
||||
**spec-driven** (default)
|
||||
|
||||
The standard workflow for spec-driven development:
|
||||
|
||||
```
|
||||
proposal → specs → design → tasks → implement
|
||||
```
|
||||
|
||||
Best for: Most feature work where you want to agree on specs before implementation.
|
||||
|
||||
### Custom Schemas
|
||||
|
||||
Create custom schemas for your team's workflow:
|
||||
|
||||
```bash
|
||||
# Create from scratch
|
||||
openspec schema init research-first
|
||||
|
||||
# Or fork an existing one
|
||||
openspec schema fork spec-driven research-first
|
||||
```
|
||||
|
||||
**Example custom schema:**
|
||||
|
||||
```yaml
|
||||
# openspec/schemas/research-first/schema.yaml
|
||||
name: research-first
|
||||
artifacts:
|
||||
- id: research
|
||||
generates: research.md
|
||||
requires: [] # Do research first
|
||||
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
requires: [research] # Proposal informed by research
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
requires: [proposal] # Skip specs/design, go straight to tasks
|
||||
```
|
||||
|
||||
See [Customization](customization.md) for full details on creating and using custom schemas.
|
||||
|
||||
## Archive
|
||||
|
||||
Archiving completes a change by merging its delta specs into the main specs and preserving the change for history.
|
||||
|
||||
### What Happens When You Archive
|
||||
|
||||
```
|
||||
Before archive:
|
||||
|
||||
openspec/
|
||||
├── specs/
|
||||
│ └── auth/
|
||||
│ └── spec.md ◄────────────────┐
|
||||
└── changes/ │
|
||||
└── add-2fa/ │
|
||||
├── proposal.md │
|
||||
├── design.md │ merge
|
||||
├── tasks.md │
|
||||
└── specs/ │
|
||||
└── auth/ │
|
||||
└── spec.md ─────────┘
|
||||
|
||||
|
||||
After archive:
|
||||
|
||||
openspec/
|
||||
├── specs/
|
||||
│ └── auth/
|
||||
│ └── spec.md # Now includes 2FA requirements
|
||||
└── changes/
|
||||
└── archive/
|
||||
└── 2025-01-24-add-2fa/ # Preserved for history
|
||||
├── proposal.md
|
||||
├── design.md
|
||||
├── tasks.md
|
||||
└── specs/
|
||||
└── auth/
|
||||
└── spec.md
|
||||
```
|
||||
|
||||
### The Archive Process
|
||||
|
||||
1. **Merge deltas.** Each delta spec section (ADDED/MODIFIED/REMOVED) is applied to the corresponding main spec.
|
||||
|
||||
2. **Move to archive.** The change folder moves to `changes/archive/` with a date prefix for chronological ordering.
|
||||
|
||||
3. **Preserve context.** All artifacts remain intact in the archive. You can always look back to understand why a change was made.
|
||||
|
||||
### Why Archive Matters
|
||||
|
||||
**Clean state.** Active changes (`changes/`) shows only work in progress. Completed work moves out of the way.
|
||||
|
||||
**Audit trail.** The archive preserves the full context of every change — not just what changed, but the proposal explaining why, the design explaining how, and the tasks showing the work done.
|
||||
|
||||
**Spec evolution.** Specs grow organically as changes are archived. Each archive merges its deltas, building up a comprehensive specification over time.
|
||||
|
||||
## How It All Fits Together
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ OPENSPEC FLOW │
|
||||
│ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 1. START │ /opsx:new creates a change folder │
|
||||
│ │ CHANGE │ │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 2. CREATE │ /opsx:ff or /opsx:continue │
|
||||
│ │ ARTIFACTS │ Creates proposal → specs → design → tasks │
|
||||
│ │ │ (based on schema dependencies) │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 3. IMPLEMENT │ /opsx:apply │
|
||||
│ │ TASKS │ Work through tasks, checking them off │
|
||||
│ │ │◄──── Update artifacts as you learn │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 4. VERIFY │ /opsx:verify (optional) │
|
||||
│ │ WORK │ Check implementation matches specs │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ 5. ARCHIVE │────►│ Delta specs merge into main specs │ │
|
||||
│ │ CHANGE │ │ Change folder moves to archive/ │ │
|
||||
│ └────────────────┘ │ Specs are now the updated source of truth │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**The virtuous cycle:**
|
||||
|
||||
1. Specs describe current behavior
|
||||
2. Changes propose modifications (as deltas)
|
||||
3. Implementation makes the changes real
|
||||
4. Archive merges deltas into specs
|
||||
5. Specs now describe the new behavior
|
||||
6. Next change builds on updated specs
|
||||
|
||||
## Glossary
|
||||
|
||||
| Term | Definition |
|
||||
|------|------------|
|
||||
| **Artifact** | A document within a change (proposal, design, tasks, or delta specs) |
|
||||
| **Archive** | The process of completing a change and merging its deltas into main specs |
|
||||
| **Change** | A proposed modification to the system, packaged as a folder with artifacts |
|
||||
| **Delta spec** | A spec that describes changes (ADDED/MODIFIED/REMOVED) relative to current specs |
|
||||
| **Domain** | A logical grouping for specs (e.g., `auth/`, `payments/`) |
|
||||
| **Requirement** | A specific behavior the system must have |
|
||||
| **Scenario** | A concrete example of a requirement, typically in Given/When/Then format |
|
||||
| **Schema** | A definition of artifact types and their dependencies |
|
||||
| **Spec** | A specification describing system behavior, containing requirements and scenarios |
|
||||
| **Source of truth** | The `openspec/specs/` directory, containing the current agreed-upon behavior |
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Getting Started](getting-started.md) - Practical first steps
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each
|
||||
- [Commands](commands.md) - Full command reference
|
||||
- [Customization](customization.md) - Create custom schemas and configure your project
|
||||
@@ -0,0 +1,342 @@
|
||||
# Customization
|
||||
|
||||
OpenSpec provides three levels of customization:
|
||||
|
||||
| Level | What it does | Best for |
|
||||
|-------|--------------|----------|
|
||||
| **Project Config** | Set defaults, inject context/rules | Most teams |
|
||||
| **Custom Schemas** | Define your own workflow artifacts | Teams with unique processes |
|
||||
| **Global Overrides** | Share schemas across all projects | Power users |
|
||||
|
||||
---
|
||||
|
||||
## Project Configuration
|
||||
|
||||
The `openspec/config.yaml` file is the easiest way to customize OpenSpec for your team. It lets you:
|
||||
|
||||
- **Set a default schema** - Skip `--schema` on every command
|
||||
- **Inject project context** - AI sees your tech stack, conventions, etc.
|
||||
- **Add per-artifact rules** - Custom rules for specific artifacts
|
||||
|
||||
### Quick Setup
|
||||
|
||||
```bash
|
||||
openspec init
|
||||
```
|
||||
|
||||
This walks you through creating a config interactively. Or create one manually:
|
||||
|
||||
```yaml
|
||||
# openspec/config.yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Tech stack: TypeScript, React, Node.js, PostgreSQL
|
||||
API style: RESTful, documented in docs/api.md
|
||||
Testing: Jest + React Testing Library
|
||||
We value backwards compatibility for all public APIs
|
||||
|
||||
rules:
|
||||
proposal:
|
||||
- Include rollback plan
|
||||
- Identify affected teams
|
||||
specs:
|
||||
- Use Given/When/Then format
|
||||
- Reference existing patterns before inventing new ones
|
||||
```
|
||||
|
||||
### How It Works
|
||||
|
||||
**Default schema:**
|
||||
|
||||
```bash
|
||||
# Without config
|
||||
openspec new change my-feature --schema spec-driven
|
||||
|
||||
# With config - schema is automatic
|
||||
openspec new change my-feature
|
||||
```
|
||||
|
||||
**Context and rules injection:**
|
||||
|
||||
When generating any artifact, your context and rules are injected into the AI prompt:
|
||||
|
||||
```xml
|
||||
<context>
|
||||
Tech stack: TypeScript, React, Node.js, PostgreSQL
|
||||
...
|
||||
</context>
|
||||
|
||||
<rules>
|
||||
- Include rollback plan
|
||||
- Identify affected teams
|
||||
</rules>
|
||||
|
||||
<template>
|
||||
[Schema's built-in template]
|
||||
</template>
|
||||
```
|
||||
|
||||
- **Context** appears in ALL artifacts
|
||||
- **Rules** ONLY appear for the matching artifact
|
||||
|
||||
### Schema Resolution Order
|
||||
|
||||
When OpenSpec needs a schema, it checks in this order:
|
||||
|
||||
1. CLI flag: `--schema <name>`
|
||||
2. Change metadata (`.openspec.yaml` in the change folder)
|
||||
3. Project config (`openspec/config.yaml`)
|
||||
4. Default (`spec-driven`)
|
||||
|
||||
---
|
||||
|
||||
## Custom Schemas
|
||||
|
||||
When project config isn't enough, create your own schema with a completely custom workflow. Custom schemas live in your project's `openspec/schemas/` directory and are version-controlled with your code.
|
||||
|
||||
```text
|
||||
your-project/
|
||||
├── openspec/
|
||||
│ ├── config.yaml # Project config
|
||||
│ ├── schemas/ # Custom schemas live here
|
||||
│ │ └── my-workflow/
|
||||
│ │ ├── schema.yaml
|
||||
│ │ └── templates/
|
||||
│ └── changes/ # Your changes
|
||||
└── src/
|
||||
```
|
||||
|
||||
### Fork an Existing Schema
|
||||
|
||||
The fastest way to customize is to fork a built-in schema:
|
||||
|
||||
```bash
|
||||
openspec schema fork spec-driven my-workflow
|
||||
```
|
||||
|
||||
This copies the entire `spec-driven` schema to `openspec/schemas/my-workflow/` where you can edit it freely.
|
||||
|
||||
**What you get:**
|
||||
|
||||
```text
|
||||
openspec/schemas/my-workflow/
|
||||
├── schema.yaml # Workflow definition
|
||||
└── templates/
|
||||
├── proposal.md # Template for proposal artifact
|
||||
├── spec.md # Template for specs
|
||||
├── design.md # Template for design
|
||||
└── tasks.md # Template for tasks
|
||||
```
|
||||
|
||||
Now edit `schema.yaml` to change the workflow, or edit templates to change what AI generates.
|
||||
|
||||
### Create a Schema from Scratch
|
||||
|
||||
For a completely fresh workflow:
|
||||
|
||||
```bash
|
||||
# Interactive
|
||||
openspec schema init research-first
|
||||
|
||||
# Non-interactive
|
||||
openspec schema init rapid \
|
||||
--description "Rapid iteration workflow" \
|
||||
--artifacts "proposal,tasks" \
|
||||
--default
|
||||
```
|
||||
|
||||
### Schema Structure
|
||||
|
||||
A schema defines the artifacts in your workflow and how they depend on each other:
|
||||
|
||||
```yaml
|
||||
# openspec/schemas/my-workflow/schema.yaml
|
||||
name: my-workflow
|
||||
version: 1
|
||||
description: My team's custom workflow
|
||||
|
||||
artifacts:
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
description: Initial proposal document
|
||||
template: proposal.md
|
||||
instruction: |
|
||||
Create a proposal that explains WHY this change is needed.
|
||||
Focus on the problem, not the solution.
|
||||
requires: []
|
||||
|
||||
- id: design
|
||||
generates: design.md
|
||||
description: Technical design
|
||||
template: design.md
|
||||
instruction: |
|
||||
Create a design document explaining HOW to implement.
|
||||
requires:
|
||||
- proposal # Can't create design until proposal exists
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
description: Implementation checklist
|
||||
template: tasks.md
|
||||
requires:
|
||||
- design
|
||||
|
||||
apply:
|
||||
requires: [tasks]
|
||||
tracks: tasks.md
|
||||
```
|
||||
|
||||
**Key fields:**
|
||||
|
||||
| Field | Purpose |
|
||||
|-------|---------|
|
||||
| `id` | Unique identifier, used in commands and rules |
|
||||
| `generates` | Output filename (supports globs like `specs/**/*.md`) |
|
||||
| `template` | Template file in `templates/` directory |
|
||||
| `instruction` | AI instructions for creating this artifact |
|
||||
| `requires` | Dependencies - which artifacts must exist first |
|
||||
|
||||
### Templates
|
||||
|
||||
Templates are markdown files that guide the AI. They're injected into the prompt when creating that artifact.
|
||||
|
||||
```markdown
|
||||
<!-- templates/proposal.md -->
|
||||
## Why
|
||||
|
||||
<!-- Explain the motivation for this change. What problem does this solve? -->
|
||||
|
||||
## What Changes
|
||||
|
||||
<!-- Describe what will change. Be specific about new capabilities or modifications. -->
|
||||
|
||||
## Impact
|
||||
|
||||
<!-- Affected code, APIs, dependencies, systems -->
|
||||
```
|
||||
|
||||
Templates can include:
|
||||
- Section headers the AI should fill in
|
||||
- HTML comments with guidance for the AI
|
||||
- Example formats showing expected structure
|
||||
|
||||
### Validate Your Schema
|
||||
|
||||
Before using a custom schema, validate it:
|
||||
|
||||
```bash
|
||||
openspec schema validate my-workflow
|
||||
```
|
||||
|
||||
This checks:
|
||||
- `schema.yaml` syntax is correct
|
||||
- All referenced templates exist
|
||||
- No circular dependencies
|
||||
- Artifact IDs are valid
|
||||
|
||||
### Use Your Custom Schema
|
||||
|
||||
Once created, use your schema with:
|
||||
|
||||
```bash
|
||||
# Specify on command
|
||||
openspec new change feature --schema my-workflow
|
||||
|
||||
# Or set as default in config.yaml
|
||||
schema: my-workflow
|
||||
```
|
||||
|
||||
### Debug Schema Resolution
|
||||
|
||||
Not sure which schema is being used? Check with:
|
||||
|
||||
```bash
|
||||
# See where a specific schema resolves from
|
||||
openspec schema which my-workflow
|
||||
|
||||
# List all available schemas
|
||||
openspec schema which --all
|
||||
```
|
||||
|
||||
Output shows whether it's from your project, user directory, or the package:
|
||||
|
||||
```text
|
||||
Schema: my-workflow
|
||||
Source: project
|
||||
Path: /path/to/project/openspec/schemas/my-workflow
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Note:** OpenSpec also supports user-level schemas at `~/.local/share/openspec/schemas/` for sharing across projects, but project-level schemas in `openspec/schemas/` are recommended since they're version-controlled with your code.
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Rapid Iteration Workflow
|
||||
|
||||
A minimal workflow for quick iterations:
|
||||
|
||||
```yaml
|
||||
# openspec/schemas/rapid/schema.yaml
|
||||
name: rapid
|
||||
version: 1
|
||||
description: Fast iteration with minimal overhead
|
||||
|
||||
artifacts:
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
description: Quick proposal
|
||||
template: proposal.md
|
||||
instruction: |
|
||||
Create a brief proposal for this change.
|
||||
Focus on what and why, skip detailed specs.
|
||||
requires: []
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
description: Implementation checklist
|
||||
template: tasks.md
|
||||
requires: [proposal]
|
||||
|
||||
apply:
|
||||
requires: [tasks]
|
||||
tracks: tasks.md
|
||||
```
|
||||
|
||||
### Adding a Review Artifact
|
||||
|
||||
Fork the default and add a review step:
|
||||
|
||||
```bash
|
||||
openspec schema fork spec-driven with-review
|
||||
```
|
||||
|
||||
Then edit `schema.yaml` to add:
|
||||
|
||||
```yaml
|
||||
- id: review
|
||||
generates: review.md
|
||||
description: Pre-implementation review checklist
|
||||
template: review.md
|
||||
instruction: |
|
||||
Create a review checklist based on the design.
|
||||
Include security, performance, and testing considerations.
|
||||
requires:
|
||||
- design
|
||||
|
||||
- id: tasks
|
||||
# ... existing tasks config ...
|
||||
requires:
|
||||
- specs
|
||||
- design
|
||||
- review # Now tasks require review too
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [CLI Reference: Schema Commands](cli.md#schema-commands) - Full command documentation
|
||||
@@ -0,0 +1,273 @@
|
||||
# Getting Started
|
||||
|
||||
This guide explains how OpenSpec works after you've installed and initialized it. For installation instructions, see the [main README](../README.md#quick-start).
|
||||
|
||||
## How It Works
|
||||
|
||||
OpenSpec helps you and your AI coding assistant agree on what to build before any code is written. The workflow follows a simple pattern:
|
||||
|
||||
```
|
||||
┌────────────────────┐
|
||||
│ Start a Change │ /opsx:new
|
||||
└────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Create Artifacts │ /opsx:ff or /opsx:continue
|
||||
│ (proposal, specs, │
|
||||
│ design, tasks) │
|
||||
└────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Implement Tasks │ /opsx:apply
|
||||
│ (AI writes code) │
|
||||
└────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Archive & Merge │ /opsx:archive
|
||||
│ Specs │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
## What OpenSpec Creates
|
||||
|
||||
After running `openspec init`, your project has this structure:
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── specs/ # Source of truth (your system's behavior)
|
||||
│ └── <domain>/
|
||||
│ └── spec.md
|
||||
├── changes/ # Proposed updates (one folder per change)
|
||||
│ └── <change-name>/
|
||||
│ ├── proposal.md
|
||||
│ ├── design.md
|
||||
│ ├── tasks.md
|
||||
│ └── specs/ # Delta specs (what's changing)
|
||||
│ └── <domain>/
|
||||
│ └── spec.md
|
||||
└── config.yaml # Project configuration (optional)
|
||||
```
|
||||
|
||||
**Two key directories:**
|
||||
|
||||
- **`specs/`** - The source of truth. These specs describe how your system currently behaves. Organized by domain (e.g., `specs/auth/`, `specs/payments/`).
|
||||
|
||||
- **`changes/`** - Proposed modifications. Each change gets its own folder with all related artifacts. When a change is complete, its specs merge into the main `specs/` directory.
|
||||
|
||||
## Understanding Artifacts
|
||||
|
||||
Each change folder contains artifacts that guide the work:
|
||||
|
||||
| Artifact | Purpose |
|
||||
|----------|---------|
|
||||
| `proposal.md` | The "why" and "what" - captures intent, scope, and approach |
|
||||
| `specs/` | Delta specs showing ADDED/MODIFIED/REMOVED requirements |
|
||||
| `design.md` | The "how" - technical approach and architecture decisions |
|
||||
| `tasks.md` | Implementation checklist with checkboxes |
|
||||
|
||||
**Artifacts build on each other:**
|
||||
|
||||
```
|
||||
proposal ──► specs ──► design ──► tasks ──► implement
|
||||
▲ ▲ ▲ │
|
||||
└───────────┴──────────┴────────────────────┘
|
||||
update as you learn
|
||||
```
|
||||
|
||||
You can always go back and refine earlier artifacts as you learn more during implementation.
|
||||
|
||||
## How Delta Specs Work
|
||||
|
||||
Delta specs are the key concept in OpenSpec. They show what's changing relative to your current specs.
|
||||
|
||||
### The Format
|
||||
|
||||
Delta specs use sections to indicate the type of change:
|
||||
|
||||
```markdown
|
||||
# Delta for Auth
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Two-Factor Authentication
|
||||
The system MUST require a second factor during login.
|
||||
|
||||
#### Scenario: OTP required
|
||||
- GIVEN a user with 2FA enabled
|
||||
- WHEN the user submits valid credentials
|
||||
- THEN an OTP challenge is presented
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Session Timeout
|
||||
The system SHALL expire sessions after 30 minutes of inactivity.
|
||||
(Previously: 60 minutes)
|
||||
|
||||
#### Scenario: Idle timeout
|
||||
- GIVEN an authenticated session
|
||||
- WHEN 30 minutes pass without activity
|
||||
- THEN the session is invalidated
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Remember Me
|
||||
(Deprecated in favor of 2FA)
|
||||
```
|
||||
|
||||
### What Happens on Archive
|
||||
|
||||
When you archive a change:
|
||||
|
||||
1. **ADDED** requirements are appended to the main spec
|
||||
2. **MODIFIED** requirements replace the existing version
|
||||
3. **REMOVED** requirements are deleted from the main spec
|
||||
|
||||
The change folder moves to `openspec/changes/archive/` for audit history.
|
||||
|
||||
## Example: Your First Change
|
||||
|
||||
Let's walk through adding dark mode to an application.
|
||||
|
||||
### 1. Start the Change
|
||||
|
||||
```
|
||||
You: /opsx:new add-dark-mode
|
||||
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
Ready to create: proposal
|
||||
```
|
||||
|
||||
### 2. Create Artifacts
|
||||
|
||||
Use `/opsx:ff` (fast-forward) to create all planning artifacts at once:
|
||||
|
||||
```
|
||||
You: /opsx:ff
|
||||
|
||||
AI: Creating artifacts for add-dark-mode...
|
||||
✓ proposal.md — why we're doing this, what's changing
|
||||
✓ specs/ — requirements and scenarios
|
||||
✓ design.md — technical approach
|
||||
✓ tasks.md — implementation checklist
|
||||
Ready for implementation!
|
||||
```
|
||||
|
||||
### 3. What Gets Created
|
||||
|
||||
**proposal.md** - Captures the intent:
|
||||
|
||||
```markdown
|
||||
# Proposal: Add Dark Mode
|
||||
|
||||
## Intent
|
||||
Users have requested a dark mode option to reduce eye strain
|
||||
during nighttime usage.
|
||||
|
||||
## Scope
|
||||
- Add theme toggle in settings
|
||||
- Support system preference detection
|
||||
- Persist preference in localStorage
|
||||
|
||||
## Approach
|
||||
Use CSS custom properties for theming with a React context
|
||||
for state management.
|
||||
```
|
||||
|
||||
**specs/ui/spec.md** - Delta showing new requirements:
|
||||
|
||||
```markdown
|
||||
# Delta for UI
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Theme Selection
|
||||
The system SHALL allow users to choose between light and dark themes.
|
||||
|
||||
#### Scenario: Manual toggle
|
||||
- GIVEN a user on any page
|
||||
- WHEN the user clicks the theme toggle
|
||||
- THEN the theme switches immediately
|
||||
- AND the preference persists across sessions
|
||||
|
||||
#### Scenario: System preference
|
||||
- GIVEN a user with no saved preference
|
||||
- WHEN the application loads
|
||||
- THEN the system's preferred color scheme is used
|
||||
```
|
||||
|
||||
**tasks.md** - Implementation checklist:
|
||||
|
||||
```markdown
|
||||
# Tasks
|
||||
|
||||
## 1. Theme Infrastructure
|
||||
- [ ] 1.1 Create ThemeContext with light/dark state
|
||||
- [ ] 1.2 Add CSS custom properties for colors
|
||||
- [ ] 1.3 Implement localStorage persistence
|
||||
|
||||
## 2. UI Components
|
||||
- [ ] 2.1 Create ThemeToggle component
|
||||
- [ ] 2.2 Add toggle to settings page
|
||||
- [ ] 2.3 Update Header to include quick toggle
|
||||
|
||||
## 3. Styling
|
||||
- [ ] 3.1 Define dark theme color palette
|
||||
- [ ] 3.2 Update components to use CSS variables
|
||||
```
|
||||
|
||||
### 4. Implement
|
||||
|
||||
```
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Working through tasks...
|
||||
✓ 1.1 Created ThemeContext with light/dark state
|
||||
✓ 1.2 Added CSS custom properties to globals.css
|
||||
✓ 1.3 Implemented localStorage persistence
|
||||
✓ 2.1 Created ThemeToggle component
|
||||
...
|
||||
All tasks complete!
|
||||
```
|
||||
|
||||
During implementation, if you discover the design needs adjustment, just update the artifact and continue.
|
||||
|
||||
### 5. Archive
|
||||
|
||||
```
|
||||
You: /opsx:archive
|
||||
|
||||
AI: Archiving add-dark-mode...
|
||||
✓ Merged specs into openspec/specs/ui/spec.md
|
||||
✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/
|
||||
Done! Ready for the next feature.
|
||||
```
|
||||
|
||||
Your delta specs are now part of the main specs, documenting how your system works.
|
||||
|
||||
## Verifying and Reviewing
|
||||
|
||||
Use the CLI to check on your changes:
|
||||
|
||||
```bash
|
||||
# List active changes
|
||||
openspec list
|
||||
|
||||
# View change details
|
||||
openspec show add-dark-mode
|
||||
|
||||
# Validate spec formatting
|
||||
openspec validate add-dark-mode
|
||||
|
||||
# Interactive dashboard
|
||||
openspec view
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each command
|
||||
- [Commands](commands.md) - Full reference for all slash commands
|
||||
- [Concepts](concepts.md) - Deeper understanding of specs, changes, and schemas
|
||||
- [Customization](customization.md) - Make OpenSpec work your way
|
||||
@@ -0,0 +1,79 @@
|
||||
# Installation
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js 20.19.0 or higher** — Check your version: `node --version`
|
||||
|
||||
## Package Managers
|
||||
|
||||
### npm
|
||||
|
||||
```bash
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
### pnpm
|
||||
|
||||
```bash
|
||||
pnpm add -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
### yarn
|
||||
|
||||
```bash
|
||||
yarn global add @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
### bun
|
||||
|
||||
```bash
|
||||
bun add -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
## Nix
|
||||
|
||||
Run OpenSpec directly without installation:
|
||||
|
||||
```bash
|
||||
nix run github:Fission-AI/OpenSpec -- init
|
||||
```
|
||||
|
||||
Or install to your profile:
|
||||
|
||||
```bash
|
||||
nix profile install github:Fission-AI/OpenSpec
|
||||
```
|
||||
|
||||
Or add to your development environment in `flake.nix`:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
openspec.url = "github:Fission-AI/OpenSpec";
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, openspec, ... }: {
|
||||
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
|
||||
buildInputs = [ openspec.packages.x86_64-linux.default ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Verify Installation
|
||||
|
||||
```bash
|
||||
openspec --version
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
After installing, initialize OpenSpec in your project:
|
||||
|
||||
```bash
|
||||
cd your-project
|
||||
openspec init
|
||||
```
|
||||
|
||||
See [Getting Started](getting-started.md) for a full walkthrough.
|
||||
@@ -0,0 +1,575 @@
|
||||
# Migrating to OPSX
|
||||
|
||||
This guide helps you transition from the legacy OpenSpec workflow to OPSX. The migration is designed to be smooth—your existing work is preserved, and the new system offers more flexibility.
|
||||
|
||||
## What's Changing?
|
||||
|
||||
OPSX replaces the old phase-locked workflow with a fluid, action-based approach. Here's the key shift:
|
||||
|
||||
| Aspect | Legacy | OPSX |
|
||||
|--------|--------|------|
|
||||
| **Commands** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` | `/opsx:new`, `/opsx:continue`, `/opsx:apply`, and more |
|
||||
| **Workflow** | Create all artifacts at once | Create incrementally or all at once—your choice |
|
||||
| **Going back** | Awkward phase gates | Natural—update any artifact anytime |
|
||||
| **Customization** | Fixed structure | Schema-driven, fully hackable |
|
||||
| **Configuration** | `CLAUDE.md` with markers + `project.md` | Clean config in `openspec/config.yaml` |
|
||||
|
||||
**The philosophy change:** Work isn't linear. OPSX stops pretending it is.
|
||||
|
||||
---
|
||||
|
||||
## Before You Begin
|
||||
|
||||
### Your Existing Work Is Safe
|
||||
|
||||
The migration process is designed with preservation in mind:
|
||||
|
||||
- **Active changes in `openspec/changes/`** — Completely preserved. You can continue them with OPSX commands.
|
||||
- **Archived changes** — Untouched. Your history remains intact.
|
||||
- **Main specs in `openspec/specs/`** — Untouched. These are your source of truth.
|
||||
- **Your content in CLAUDE.md, AGENTS.md, etc.** — Preserved. Only the OpenSpec marker blocks are removed; everything you wrote stays.
|
||||
|
||||
### What Gets Removed
|
||||
|
||||
Only OpenSpec-managed files that are being replaced:
|
||||
|
||||
| What | Why |
|
||||
|------|-----|
|
||||
| Legacy slash command directories/files | Replaced by the new skills system |
|
||||
| `openspec/AGENTS.md` | Obsolete workflow trigger |
|
||||
| OpenSpec markers in `CLAUDE.md`, `AGENTS.md`, etc. | No longer needed |
|
||||
|
||||
**Legacy command locations by tool** (examples—your tool may vary):
|
||||
|
||||
- Claude Code: `.claude/commands/openspec/`
|
||||
- Cursor: `.cursor/commands/openspec-*.md`
|
||||
- Windsurf: `.windsurf/workflows/openspec-*.md`
|
||||
- Cline: `.clinerules/workflows/openspec-*.md`
|
||||
- Roo: `.roo/commands/openspec-*.md`
|
||||
- GitHub Copilot: `.github/prompts/openspec-*.prompt.md`
|
||||
- And others (Augment, Continue, Amazon Q, etc.)
|
||||
|
||||
The migration detects whichever tools you have configured and cleans up their legacy files.
|
||||
|
||||
The removal list may seem long, but these are all files that OpenSpec originally created. Your own content is never deleted.
|
||||
|
||||
### What Needs Your Attention
|
||||
|
||||
One file requires manual migration:
|
||||
|
||||
**`openspec/project.md`** — This file isn't deleted automatically because it may contain project context you've written. You'll need to:
|
||||
|
||||
1. Review its contents
|
||||
2. Move useful context to `openspec/config.yaml` (see guidance below)
|
||||
3. Delete the file when ready
|
||||
|
||||
**Why we made this change:**
|
||||
|
||||
The old `project.md` was passive—agents might read it, might not, might forget what they read. We found reliability was inconsistent.
|
||||
|
||||
The new `config.yaml` context is **actively injected into every OpenSpec planning request**. This means your project conventions, tech stack, and rules are always present when the AI is creating artifacts. Higher reliability.
|
||||
|
||||
**The tradeoff:**
|
||||
|
||||
Because context is injected into every request, you'll want to be concise. Focus on what really matters:
|
||||
- Tech stack and key conventions
|
||||
- Non-obvious constraints the AI needs to know
|
||||
- Rules that frequently got ignored before
|
||||
|
||||
Don't worry about getting it perfect. We're still learning what works best here, and we'll be improving how context injection works as we experiment.
|
||||
|
||||
---
|
||||
|
||||
## Running the Migration
|
||||
|
||||
Both `openspec init` and `openspec update` detect legacy files and guide you through the same cleanup process. Use whichever fits your situation:
|
||||
|
||||
### Using `openspec init`
|
||||
|
||||
Run this if you want to add new tools or reconfigure which tools are set up:
|
||||
|
||||
```bash
|
||||
openspec init
|
||||
```
|
||||
|
||||
The init command detects legacy files and guides you through cleanup:
|
||||
|
||||
```
|
||||
Upgrading to the new OpenSpec
|
||||
|
||||
OpenSpec now uses agent skills, the emerging standard across coding
|
||||
agents. This simplifies your setup while keeping everything working
|
||||
as before.
|
||||
|
||||
Files to remove
|
||||
No user content to preserve:
|
||||
• .claude/commands/openspec/
|
||||
• openspec/AGENTS.md
|
||||
|
||||
Files to update
|
||||
OpenSpec markers will be removed, your content preserved:
|
||||
• CLAUDE.md
|
||||
• AGENTS.md
|
||||
|
||||
Needs your attention
|
||||
• openspec/project.md
|
||||
We won't delete this file. It may contain useful project context.
|
||||
|
||||
The new openspec/config.yaml has a "context:" section for planning
|
||||
context. This is included in every OpenSpec request and works more
|
||||
reliably than the old project.md approach.
|
||||
|
||||
Review project.md, move any useful content to config.yaml's context
|
||||
section, then delete the file when ready.
|
||||
|
||||
? Upgrade and clean up legacy files? (Y/n)
|
||||
```
|
||||
|
||||
**What happens when you say yes:**
|
||||
|
||||
1. Legacy slash command directories are removed
|
||||
2. OpenSpec markers are stripped from `CLAUDE.md`, `AGENTS.md`, etc. (your content stays)
|
||||
3. `openspec/AGENTS.md` is deleted
|
||||
4. New skills are installed in `.claude/skills/`
|
||||
5. `openspec/config.yaml` is created with a default schema
|
||||
|
||||
### Using `openspec update`
|
||||
|
||||
Run this if you just want to migrate and refresh your existing tools to the latest version:
|
||||
|
||||
```bash
|
||||
openspec update
|
||||
```
|
||||
|
||||
The update command also detects and cleans up legacy artifacts, then refreshes your skills to the latest version.
|
||||
|
||||
### Non-Interactive / CI Environments
|
||||
|
||||
For scripted migrations:
|
||||
|
||||
```bash
|
||||
openspec init --force --tools claude
|
||||
```
|
||||
|
||||
The `--force` flag skips prompts and auto-accepts cleanup.
|
||||
|
||||
---
|
||||
|
||||
## Migrating project.md to config.yaml
|
||||
|
||||
The old `openspec/project.md` was a freeform markdown file for project context. The new `openspec/config.yaml` is structured and—critically—**injected into every planning request** so your conventions are always present when the AI works.
|
||||
|
||||
### Before (project.md)
|
||||
|
||||
```markdown
|
||||
# Project Context
|
||||
|
||||
This is a TypeScript monorepo using React and Node.js.
|
||||
We use Jest for testing and follow strict ESLint rules.
|
||||
Our API is RESTful and documented in docs/api.md.
|
||||
|
||||
## Conventions
|
||||
|
||||
- All public APIs must maintain backwards compatibility
|
||||
- New features should include tests
|
||||
- Use Given/When/Then format for specifications
|
||||
```
|
||||
|
||||
### After (config.yaml)
|
||||
|
||||
```yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Tech stack: TypeScript, React, Node.js
|
||||
Testing: Jest with React Testing Library
|
||||
API: RESTful, documented in docs/api.md
|
||||
We maintain backwards compatibility for all public APIs
|
||||
|
||||
rules:
|
||||
proposal:
|
||||
- Include rollback plan for risky changes
|
||||
specs:
|
||||
- Use Given/When/Then format for scenarios
|
||||
- Reference existing patterns before inventing new ones
|
||||
design:
|
||||
- Include sequence diagrams for complex flows
|
||||
```
|
||||
|
||||
### Key Differences
|
||||
|
||||
| project.md | config.yaml |
|
||||
|------------|-------------|
|
||||
| Freeform markdown | Structured YAML |
|
||||
| One blob of text | Separate context and per-artifact rules |
|
||||
| Unclear when it's used | Context appears in ALL artifacts; rules appear in matching artifacts only |
|
||||
| No schema selection | Explicit `schema:` field sets default workflow |
|
||||
|
||||
### What to Keep, What to Drop
|
||||
|
||||
When migrating, be selective. Ask yourself: "Does the AI need this for *every* planning request?"
|
||||
|
||||
**Good candidates for `context:`**
|
||||
- Tech stack (languages, frameworks, databases)
|
||||
- Key architectural patterns (monorepo, microservices, etc.)
|
||||
- Non-obvious constraints ("we can't use library X because...")
|
||||
- Critical conventions that often get ignored
|
||||
|
||||
**Move to `rules:` instead**
|
||||
- Artifact-specific formatting ("use Given/When/Then in specs")
|
||||
- Review criteria ("proposals must include rollback plans")
|
||||
- These only appear for the matching artifact, keeping other requests lighter
|
||||
|
||||
**Leave out entirely**
|
||||
- General best practices the AI already knows
|
||||
- Verbose explanations that could be summarized
|
||||
- Historical context that doesn't affect current work
|
||||
|
||||
### Migration Steps
|
||||
|
||||
1. **Create config.yaml** (if not already created by init):
|
||||
```yaml
|
||||
schema: spec-driven
|
||||
```
|
||||
|
||||
2. **Add your context** (be concise—this goes into every request):
|
||||
```yaml
|
||||
context: |
|
||||
Your project background goes here.
|
||||
Focus on what the AI genuinely needs to know.
|
||||
```
|
||||
|
||||
3. **Add per-artifact rules** (optional):
|
||||
```yaml
|
||||
rules:
|
||||
proposal:
|
||||
- Your proposal-specific guidance
|
||||
specs:
|
||||
- Your spec-writing rules
|
||||
```
|
||||
|
||||
4. **Delete project.md** once you've moved everything useful.
|
||||
|
||||
**Don't overthink it.** Start with the essentials and iterate. If you notice the AI missing something important, add it. If context feels bloated, trim it. This is a living document.
|
||||
|
||||
### Need Help? Use This Prompt
|
||||
|
||||
If you're unsure how to distill your project.md, ask your AI assistant:
|
||||
|
||||
```
|
||||
I'm migrating from OpenSpec's old project.md to the new config.yaml format.
|
||||
|
||||
Here's my current project.md:
|
||||
[paste your project.md content]
|
||||
|
||||
Please help me create a config.yaml with:
|
||||
1. A concise `context:` section (this gets injected into every planning request, so keep it tight—focus on tech stack, key constraints, and conventions that often get ignored)
|
||||
2. `rules:` for specific artifacts if any content is artifact-specific (e.g., "use Given/When/Then" belongs in specs rules, not global context)
|
||||
|
||||
Leave out anything generic that AI models already know. Be ruthless about brevity.
|
||||
```
|
||||
|
||||
The AI will help you identify what's essential vs. what can be trimmed.
|
||||
|
||||
---
|
||||
|
||||
## The New Commands
|
||||
|
||||
After migration, you have 9 OPSX commands instead of 3:
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:explore` | Think through ideas with no structure |
|
||||
| `/opsx:new` | Start a new change |
|
||||
| `/opsx:continue` | Create the next artifact (one at a time) |
|
||||
| `/opsx:ff` | Fast-forward—create all planning artifacts at once |
|
||||
| `/opsx:apply` | Implement tasks from tasks.md |
|
||||
| `/opsx:verify` | Validate implementation matches specs |
|
||||
| `/opsx:sync` | Preview spec merge (optional—archive prompts if needed) |
|
||||
| `/opsx:archive` | Finalize and archive the change |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes at once |
|
||||
|
||||
### Command Mapping from Legacy
|
||||
|
||||
| Legacy | OPSX Equivalent |
|
||||
|--------|-----------------|
|
||||
| `/openspec:proposal` | `/opsx:new` then `/opsx:ff` |
|
||||
| `/openspec:apply` | `/opsx:apply` |
|
||||
| `/openspec:archive` | `/opsx:archive` |
|
||||
|
||||
### New Capabilities
|
||||
|
||||
**Granular artifact creation:**
|
||||
```
|
||||
/opsx:continue
|
||||
```
|
||||
Creates one artifact at a time based on dependencies. Use this when you want to review each step.
|
||||
|
||||
**Exploration mode:**
|
||||
```
|
||||
/opsx:explore
|
||||
```
|
||||
Think through ideas with a partner before committing to a change.
|
||||
|
||||
---
|
||||
|
||||
## Understanding the New Architecture
|
||||
|
||||
### From Phase-Locked to Fluid
|
||||
|
||||
The legacy workflow forced linear progression:
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ PLANNING │ ───► │ IMPLEMENTING │ ───► │ ARCHIVING │
|
||||
│ PHASE │ │ PHASE │ │ PHASE │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
|
||||
If you're in implementation and realize the design is wrong?
|
||||
Too bad. Phase gates don't let you go back easily.
|
||||
```
|
||||
|
||||
OPSX uses actions, not phases:
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────┐
|
||||
│ ACTIONS (not phases) │
|
||||
│ │
|
||||
│ new ◄──► continue ◄──► apply ◄──► archive │
|
||||
│ │ │ │ │ │
|
||||
│ └──────────┴───────────┴───────────┘ │
|
||||
│ any order │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Dependency Graph
|
||||
|
||||
Artifacts form a directed graph. Dependencies are enablers, not gates:
|
||||
|
||||
```
|
||||
proposal
|
||||
(root node)
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
specs design
|
||||
(requires: (requires:
|
||||
proposal) proposal)
|
||||
│ │
|
||||
└─────────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
tasks
|
||||
(requires:
|
||||
specs, design)
|
||||
```
|
||||
|
||||
When you run `/opsx:continue`, it checks what's ready and offers the next artifact. You can also create multiple ready artifacts in any order.
|
||||
|
||||
### Skills vs Commands
|
||||
|
||||
The legacy system used tool-specific command files:
|
||||
|
||||
```
|
||||
.claude/commands/openspec/
|
||||
├── proposal.md
|
||||
├── apply.md
|
||||
└── archive.md
|
||||
```
|
||||
|
||||
OPSX uses the emerging **skills** standard:
|
||||
|
||||
```
|
||||
.claude/skills/
|
||||
├── openspec-explore/SKILL.md
|
||||
├── openspec-new-change/SKILL.md
|
||||
├── openspec-continue-change/SKILL.md
|
||||
├── openspec-apply-change/SKILL.md
|
||||
└── ...
|
||||
```
|
||||
|
||||
Skills are recognized across multiple AI coding tools and provide richer metadata.
|
||||
|
||||
---
|
||||
|
||||
## Continuing Existing Changes
|
||||
|
||||
Your in-progress changes work seamlessly with OPSX commands.
|
||||
|
||||
**Have an active change from the legacy workflow?**
|
||||
|
||||
```
|
||||
/opsx:apply add-my-feature
|
||||
```
|
||||
|
||||
OPSX reads the existing artifacts and continues from where you left off.
|
||||
|
||||
**Want to add more artifacts to an existing change?**
|
||||
|
||||
```
|
||||
/opsx:continue add-my-feature
|
||||
```
|
||||
|
||||
Shows what's ready to create based on what already exists.
|
||||
|
||||
**Need to see status?**
|
||||
|
||||
```bash
|
||||
openspec status --change add-my-feature
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## The New Config System
|
||||
|
||||
### config.yaml Structure
|
||||
|
||||
```yaml
|
||||
# Required: Default schema for new changes
|
||||
schema: spec-driven
|
||||
|
||||
# Optional: Project context (max 50KB)
|
||||
# Injected into ALL artifact instructions
|
||||
context: |
|
||||
Your project background, tech stack,
|
||||
conventions, and constraints.
|
||||
|
||||
# Optional: Per-artifact rules
|
||||
# Only injected into matching artifacts
|
||||
rules:
|
||||
proposal:
|
||||
- Include rollback plan
|
||||
specs:
|
||||
- Use Given/When/Then format
|
||||
design:
|
||||
- Document fallback strategies
|
||||
tasks:
|
||||
- Break into 2-hour maximum chunks
|
||||
```
|
||||
|
||||
### Schema Resolution
|
||||
|
||||
When determining which schema to use, OPSX checks in order:
|
||||
|
||||
1. **CLI flag**: `--schema <name>` (highest priority)
|
||||
2. **Change metadata**: `.openspec.yaml` in the change directory
|
||||
3. **Project config**: `openspec/config.yaml`
|
||||
4. **Default**: `spec-driven`
|
||||
|
||||
### Available Schemas
|
||||
|
||||
| Schema | Artifacts | Best For |
|
||||
|--------|-----------|----------|
|
||||
| `spec-driven` | proposal → specs → design → tasks | Most projects |
|
||||
|
||||
List all available schemas:
|
||||
|
||||
```bash
|
||||
openspec schemas
|
||||
```
|
||||
|
||||
### Custom Schemas
|
||||
|
||||
Create your own workflow:
|
||||
|
||||
```bash
|
||||
openspec schema init my-workflow
|
||||
```
|
||||
|
||||
Or fork an existing one:
|
||||
|
||||
```bash
|
||||
openspec schema fork spec-driven my-workflow
|
||||
```
|
||||
|
||||
See [Customization](customization.md) for details.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Legacy files detected in non-interactive mode"
|
||||
|
||||
You're running in a CI or non-interactive environment. Use:
|
||||
|
||||
```bash
|
||||
openspec init --force
|
||||
```
|
||||
|
||||
### Commands not appearing after migration
|
||||
|
||||
Restart your IDE. Skills are detected at startup.
|
||||
|
||||
### "Unknown artifact ID in rules"
|
||||
|
||||
Check that your `rules:` keys match your schema's artifact IDs:
|
||||
|
||||
- **spec-driven**: `proposal`, `specs`, `design`, `tasks`
|
||||
|
||||
Run this to see valid artifact IDs:
|
||||
|
||||
```bash
|
||||
openspec schemas --json
|
||||
```
|
||||
|
||||
### Config not being applied
|
||||
|
||||
1. Ensure the file is at `openspec/config.yaml` (not `.yml`)
|
||||
2. Validate YAML syntax
|
||||
3. Config changes take effect immediately—no restart needed
|
||||
|
||||
### project.md not migrated
|
||||
|
||||
The system intentionally preserves `project.md` because it may contain your custom content. Review it manually, move useful parts to `config.yaml`, then delete it.
|
||||
|
||||
### Want to see what would be cleaned up?
|
||||
|
||||
Run init and decline the cleanup prompt—you'll see the full detection summary without any changes being made.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Files After Migration
|
||||
|
||||
```
|
||||
project/
|
||||
├── openspec/
|
||||
│ ├── specs/ # Unchanged
|
||||
│ ├── changes/ # Unchanged
|
||||
│ │ └── archive/ # Unchanged
|
||||
│ └── config.yaml # NEW: Project configuration
|
||||
├── .claude/
|
||||
│ └── skills/ # NEW: OPSX skills
|
||||
│ ├── openspec-explore/
|
||||
│ ├── openspec-new-change/
|
||||
│ └── ...
|
||||
├── CLAUDE.md # OpenSpec markers removed, your content preserved
|
||||
└── AGENTS.md # OpenSpec markers removed, your content preserved
|
||||
```
|
||||
|
||||
### What's Gone
|
||||
|
||||
- `.claude/commands/openspec/` — replaced by `.claude/skills/`
|
||||
- `openspec/AGENTS.md` — obsolete
|
||||
- `openspec/project.md` — migrate to `config.yaml`, then delete
|
||||
- OpenSpec marker blocks in `CLAUDE.md`, `AGENTS.md`, etc.
|
||||
|
||||
### Command Cheatsheet
|
||||
|
||||
```
|
||||
/opsx:new Start a change
|
||||
/opsx:continue Create next artifact
|
||||
/opsx:ff Create all planning artifacts
|
||||
/opsx:apply Implement tasks
|
||||
/opsx:archive Finish and archive
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
- **Discord**: [discord.gg/YctCnvvshC](https://discord.gg/YctCnvvshC)
|
||||
- **GitHub Issues**: [github.com/Fission-AI/OpenSpec/issues](https://github.com/Fission-AI/OpenSpec/issues)
|
||||
- **Documentation**: [docs/opsx.md](opsx.md) for the full OPSX reference
|
||||
@@ -0,0 +1,115 @@
|
||||
# Multi-Language Guide
|
||||
|
||||
Configure OpenSpec to generate artifacts in languages other than English.
|
||||
|
||||
## Quick Setup
|
||||
|
||||
Add a language instruction to your `openspec/config.yaml`:
|
||||
|
||||
```yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Language: Portuguese (pt-BR)
|
||||
All artifacts must be written in Brazilian Portuguese.
|
||||
|
||||
# Your other project context below...
|
||||
Tech stack: TypeScript, React, Node.js
|
||||
```
|
||||
|
||||
That's it. All generated artifacts will now be in Portuguese.
|
||||
|
||||
## Language Examples
|
||||
|
||||
### Portuguese (Brazil)
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Language: Portuguese (pt-BR)
|
||||
All artifacts must be written in Brazilian Portuguese.
|
||||
```
|
||||
|
||||
### Spanish
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Idioma: Español
|
||||
Todos los artefactos deben escribirse en español.
|
||||
```
|
||||
|
||||
### Chinese (Simplified)
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
语言:中文(简体)
|
||||
所有产出物必须用简体中文撰写。
|
||||
```
|
||||
|
||||
### Japanese
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
言語:日本語
|
||||
すべての成果物は日本語で作成してください。
|
||||
```
|
||||
|
||||
### French
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Langue : Français
|
||||
Tous les artefacts doivent être rédigés en français.
|
||||
```
|
||||
|
||||
### German
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Sprache: Deutsch
|
||||
Alle Artefakte müssen auf Deutsch verfasst werden.
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
### Handle Technical Terms
|
||||
|
||||
Decide how to handle technical terminology:
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
Language: Japanese
|
||||
Write in Japanese, but:
|
||||
- Keep technical terms like "API", "REST", "GraphQL" in English
|
||||
- Code examples and file paths remain in English
|
||||
```
|
||||
|
||||
### Combine with Other Context
|
||||
|
||||
Language settings work alongside your other project context:
|
||||
|
||||
```yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Language: Portuguese (pt-BR)
|
||||
All artifacts must be written in Brazilian Portuguese.
|
||||
|
||||
Tech stack: TypeScript, React 18, Node.js 20
|
||||
Database: PostgreSQL with Prisma ORM
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
To verify your language config is working:
|
||||
|
||||
```bash
|
||||
# Check the instructions - should show your language context
|
||||
openspec instructions proposal --change my-change
|
||||
|
||||
# Output will include your language context
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Customization Guide](./customization.md) - Project configuration options
|
||||
- [Workflows Guide](./workflows.md) - Full workflow documentation
|
||||
+644
@@ -0,0 +1,644 @@
|
||||
# OPSX Workflow
|
||||
|
||||
> Feedback welcome on [Discord](https://discord.gg/YctCnvvshC).
|
||||
|
||||
## What Is It?
|
||||
|
||||
OPSX is now the standard workflow for OpenSpec.
|
||||
|
||||
It's a **fluid, iterative workflow** for OpenSpec changes. No more rigid phases — just actions you can take anytime.
|
||||
|
||||
## Why This Exists
|
||||
|
||||
The legacy OpenSpec workflow works, but it's **locked down**:
|
||||
|
||||
- **Instructions are hardcoded** — buried in TypeScript, you can't change them
|
||||
- **All-or-nothing** — one big command creates everything, can't test individual pieces
|
||||
- **Fixed structure** — same workflow for everyone, no customization
|
||||
- **Black box** — when AI output is bad, you can't tweak the prompts
|
||||
|
||||
**OPSX opens it up.** Now anyone can:
|
||||
|
||||
1. **Experiment with instructions** — edit a template, see if the AI does better
|
||||
2. **Test granularly** — validate each artifact's instructions independently
|
||||
3. **Customize workflows** — define your own artifacts and dependencies
|
||||
4. **Iterate quickly** — change a template, test immediately, no rebuild
|
||||
|
||||
```
|
||||
Legacy workflow: OPSX:
|
||||
┌────────────────────────┐ ┌────────────────────────┐
|
||||
│ Hardcoded in package │ │ schema.yaml │◄── You edit this
|
||||
│ (can't change) │ │ templates/*.md │◄── Or this
|
||||
│ ↓ │ │ ↓ │
|
||||
│ Wait for new release │ │ Instant effect │
|
||||
│ ↓ │ │ ↓ │
|
||||
│ Hope it's better │ │ Test it yourself │
|
||||
└────────────────────────┘ └────────────────────────┘
|
||||
```
|
||||
|
||||
**This is for everyone:**
|
||||
- **Teams** — create workflows that match how you actually work
|
||||
- **Power users** — tweak prompts to get better AI outputs for your codebase
|
||||
- **OpenSpec contributors** — experiment with new approaches without releases
|
||||
|
||||
We're all still learning what works best. OPSX lets us learn together.
|
||||
|
||||
## The User Experience
|
||||
|
||||
**The problem with linear workflows:**
|
||||
You're "in planning phase", then "in implementation phase", then "done". But real work doesn't work that way. You implement something, realize your design was wrong, need to update specs, continue implementing. Linear phases fight against how work actually happens.
|
||||
|
||||
**OPSX approach:**
|
||||
- **Actions, not phases** — create, implement, update, archive — do any of them anytime
|
||||
- **Dependencies are enablers** — they show what's possible, not what's required next
|
||||
|
||||
```
|
||||
proposal ──→ specs ──→ design ──→ tasks ──→ implement
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
# Make sure you have openspec installed — skills are automatically generated
|
||||
openspec init
|
||||
```
|
||||
|
||||
This creates skills in `.claude/skills/` (or equivalent) that AI coding assistants auto-detect.
|
||||
|
||||
During setup, you'll be prompted to create a **project config** (`openspec/config.yaml`). This is optional but recommended.
|
||||
|
||||
## Project Configuration
|
||||
|
||||
Project config lets you set defaults and inject project-specific context into all artifacts.
|
||||
|
||||
### Creating Config
|
||||
|
||||
Config is created during `openspec init`, or manually:
|
||||
|
||||
```yaml
|
||||
# openspec/config.yaml
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Tech stack: TypeScript, React, Node.js
|
||||
API conventions: RESTful, JSON responses
|
||||
Testing: Vitest for unit tests, Playwright for e2e
|
||||
Style: ESLint with Prettier, strict TypeScript
|
||||
|
||||
rules:
|
||||
proposal:
|
||||
- Include rollback plan
|
||||
- Identify affected teams
|
||||
specs:
|
||||
- Use Given/When/Then format for scenarios
|
||||
design:
|
||||
- Include sequence diagrams for complex flows
|
||||
```
|
||||
|
||||
### Config Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `schema` | string | Default schema for new changes (e.g., `spec-driven`) |
|
||||
| `context` | string | Project context injected into all artifact instructions |
|
||||
| `rules` | object | Per-artifact rules, keyed by artifact ID |
|
||||
|
||||
### How It Works
|
||||
|
||||
**Schema precedence** (highest to lowest):
|
||||
1. CLI flag (`--schema <name>`)
|
||||
2. Change metadata (`.openspec.yaml` in change directory)
|
||||
3. Project config (`openspec/config.yaml`)
|
||||
4. Default (`spec-driven`)
|
||||
|
||||
**Context injection:**
|
||||
- Context is prepended to every artifact's instructions
|
||||
- Wrapped in `<context>...</context>` tags
|
||||
- Helps AI understand your project's conventions
|
||||
|
||||
**Rules injection:**
|
||||
- Rules are only injected for matching artifacts
|
||||
- Wrapped in `<rules>...</rules>` tags
|
||||
- Appear after context, before the template
|
||||
|
||||
### Artifact IDs by Schema
|
||||
|
||||
**spec-driven** (default):
|
||||
- `proposal` — Change proposal
|
||||
- `specs` — Specifications
|
||||
- `design` — Technical design
|
||||
- `tasks` — Implementation tasks
|
||||
|
||||
### Config Validation
|
||||
|
||||
- Unknown artifact IDs in `rules` generate warnings
|
||||
- Schema names are validated against available schemas
|
||||
- Context has a 50KB size limit
|
||||
- Invalid YAML is reported with line numbers
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
**"Unknown artifact ID in rules: X"**
|
||||
- Check artifact IDs match your schema (see list above)
|
||||
- Run `openspec schemas --json` to see artifact IDs for each schema
|
||||
|
||||
**Config not being applied:**
|
||||
- Ensure file is at `openspec/config.yaml` (not `.yml`)
|
||||
- Check YAML syntax with a validator
|
||||
- Config changes take effect immediately (no restart needed)
|
||||
|
||||
**Context too large:**
|
||||
- Context is limited to 50KB
|
||||
- Summarize or link to external docs instead
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | What it does |
|
||||
|---------|--------------|
|
||||
| `/opsx:explore` | Think through ideas, investigate problems, clarify requirements |
|
||||
| `/opsx:new` | Start a new change |
|
||||
| `/opsx:continue` | Create the next artifact (based on what's ready) |
|
||||
| `/opsx:ff` | Fast-forward — create all planning artifacts at once |
|
||||
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
|
||||
| `/opsx:sync` | Sync delta specs to main (optional—archive prompts if needed) |
|
||||
| `/opsx:archive` | Archive when done |
|
||||
|
||||
## Usage
|
||||
|
||||
### Explore an idea
|
||||
```
|
||||
/opsx:explore
|
||||
```
|
||||
Think through ideas, investigate problems, compare options. No structure required - just a thinking partner. When insights crystallize, transition to `/opsx:new` or `/opsx:ff`.
|
||||
|
||||
### Start a new change
|
||||
```
|
||||
/opsx:new
|
||||
```
|
||||
You'll be asked what you want to build and which workflow schema to use.
|
||||
|
||||
### Create artifacts
|
||||
```
|
||||
/opsx:continue
|
||||
```
|
||||
Shows what's ready to create based on dependencies, then creates one artifact. Use repeatedly to build up your change incrementally.
|
||||
|
||||
```
|
||||
/opsx:ff add-dark-mode
|
||||
```
|
||||
Creates all planning artifacts at once. Use when you have a clear picture of what you're building.
|
||||
|
||||
### Implement (the fluid part)
|
||||
```
|
||||
/opsx:apply
|
||||
```
|
||||
Works through tasks, checking them off as you go. If you're juggling multiple changes, you can run `/opsx:apply <name>`; otherwise it should infer from the conversation and prompt you to choose if it can't tell.
|
||||
|
||||
### Finish up
|
||||
```
|
||||
/opsx:archive # Move to archive when done (prompts to sync specs if needed)
|
||||
```
|
||||
|
||||
## When to Update vs. Start Fresh
|
||||
|
||||
You can always edit your proposal or specs before implementation. But when does refining become "this is different work"?
|
||||
|
||||
### What a Proposal Captures
|
||||
|
||||
A proposal defines three things:
|
||||
1. **Intent** — What problem are you solving?
|
||||
2. **Scope** — What's in/out of bounds?
|
||||
3. **Approach** — How will you solve it?
|
||||
|
||||
The question is: which changed, and by how much?
|
||||
|
||||
### Update the Existing Change When:
|
||||
|
||||
**Same intent, refined execution**
|
||||
- You discover edge cases you didn't consider
|
||||
- The approach needs tweaking but the goal is unchanged
|
||||
- Implementation reveals the design was slightly off
|
||||
|
||||
**Scope narrows**
|
||||
- You realize full scope is too big, want to ship MVP first
|
||||
- "Add dark mode" → "Add dark mode toggle (system preference in v2)"
|
||||
|
||||
**Learning-driven corrections**
|
||||
- Codebase isn't structured how you thought
|
||||
- A dependency doesn't work as expected
|
||||
- "Use CSS variables" → "Use Tailwind's dark: prefix instead"
|
||||
|
||||
### Start a New Change When:
|
||||
|
||||
**Intent fundamentally changed**
|
||||
- The problem itself is different now
|
||||
- "Add dark mode" → "Add comprehensive theme system with custom colors, fonts, spacing"
|
||||
|
||||
**Scope exploded**
|
||||
- Change grew so much it's essentially different work
|
||||
- Original proposal would be unrecognizable after updates
|
||||
- "Fix login bug" → "Rewrite auth system"
|
||||
|
||||
**Original is completable**
|
||||
- The original change can be marked "done"
|
||||
- New work stands alone, not a refinement
|
||||
- Complete "Add dark mode MVP" → Archive → New change "Enhance dark mode"
|
||||
|
||||
### The Heuristics
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Is this the same work? │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────────────────┼──────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
Same intent? >50% overlap? Can original
|
||||
Same problem? Same scope? be "done" without
|
||||
│ │ these changes?
|
||||
│ │ │
|
||||
┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
|
||||
│ │ │ │ │ │
|
||||
YES NO YES NO NO YES
|
||||
│ │ │ │ │ │
|
||||
▼ ▼ ▼ ▼ ▼ ▼
|
||||
UPDATE NEW UPDATE NEW UPDATE NEW
|
||||
```
|
||||
|
||||
| Test | Update | New Change |
|
||||
|------|--------|------------|
|
||||
| **Identity** | "Same thing, refined" | "Different work" |
|
||||
| **Scope overlap** | >50% overlaps | <50% overlaps |
|
||||
| **Completion** | Can't be "done" without changes | Can finish original, new work stands alone |
|
||||
| **Story** | Update chain tells coherent story | Patches would confuse more than clarify |
|
||||
|
||||
### The Principle
|
||||
|
||||
> **Update preserves context. New change provides clarity.**
|
||||
>
|
||||
> Choose update when the history of your thinking is valuable.
|
||||
> Choose new when starting fresh would be clearer than patching.
|
||||
|
||||
Think of it like git branches:
|
||||
- Keep committing while working on the same feature
|
||||
- Start a new branch when it's genuinely new work
|
||||
- Sometimes merge a partial feature and start fresh for phase 2
|
||||
|
||||
## What's Different?
|
||||
|
||||
| | Legacy (`/openspec:proposal`) | OPSX (`/opsx:*`) |
|
||||
|---|---|---|
|
||||
| **Structure** | One big proposal document | Discrete artifacts with dependencies |
|
||||
| **Workflow** | Linear phases: plan → implement → archive | Fluid actions — do anything anytime |
|
||||
| **Iteration** | Awkward to go back | Update artifacts as you learn |
|
||||
| **Customization** | Fixed structure | Schema-driven (define your own artifacts) |
|
||||
|
||||
**The key insight:** work isn't linear. OPSX stops pretending it is.
|
||||
|
||||
## Architecture Deep Dive
|
||||
|
||||
This section explains how OPSX works under the hood and how it compares to the legacy workflow.
|
||||
|
||||
### Philosophy: Phases vs Actions
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ LEGACY WORKFLOW │
|
||||
│ (Phase-Locked, All-or-Nothing) │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ PLANNING │ ───► │ IMPLEMENTING │ ───► │ ARCHIVING │ │
|
||||
│ │ PHASE │ │ PHASE │ │ PHASE │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ /openspec:proposal /openspec:apply /openspec:archive │
|
||||
│ │
|
||||
│ • Creates ALL artifacts at once │
|
||||
│ • Can't go back to update specs during implementation │
|
||||
│ • Phase gates enforce linear progression │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ OPSX WORKFLOW │
|
||||
│ (Fluid Actions, Iterative) │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────┐ │
|
||||
│ │ ACTIONS (not phases) │ │
|
||||
│ │ │ │
|
||||
│ │ new ◄──► continue ◄──► apply ◄──► archive │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ └──────────┴───────────┴───────────┘ │ │
|
||||
│ │ any order │ │
|
||||
│ └────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ • Create artifacts one at a time OR fast-forward │
|
||||
│ • Update specs/design/tasks during implementation │
|
||||
│ • Dependencies enable progress, phases don't exist │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Component Architecture
|
||||
|
||||
**Legacy workflow** uses hardcoded templates in TypeScript:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ LEGACY WORKFLOW COMPONENTS │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Hardcoded Templates (TypeScript strings) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Configurators (18+ classes, one per editor) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Generated Command Files (.claude/commands/openspec/*.md) │
|
||||
│ │
|
||||
│ • Fixed structure, no artifact awareness │
|
||||
│ • Change requires code modification + rebuild │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**OPSX** uses external schemas and a dependency graph engine:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ OPSX COMPONENTS │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Schema Definitions (YAML) │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ name: spec-driven │ │
|
||||
│ │ artifacts: │ │
|
||||
│ │ - id: proposal │ │
|
||||
│ │ generates: proposal.md │ │
|
||||
│ │ requires: [] ◄── Dependencies │ │
|
||||
│ │ - id: specs │ │
|
||||
│ │ generates: specs/**/*.md ◄── Glob patterns │ │
|
||||
│ │ requires: [proposal] ◄── Enables after proposal │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Artifact Graph Engine │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ • Topological sort (dependency ordering) │ │
|
||||
│ │ • State detection (filesystem existence) │ │
|
||||
│ │ • Rich instruction generation (templates + context) │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Skill Files (.claude/skills/openspec-*/SKILL.md) │
|
||||
│ │
|
||||
│ • Cross-editor compatible (Claude Code, Cursor, Windsurf) │
|
||||
│ • Skills query CLI for structured data │
|
||||
│ • Fully customizable via schema files │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Dependency Graph Model
|
||||
|
||||
Artifacts form a directed acyclic graph (DAG). Dependencies are **enablers**, not gates:
|
||||
|
||||
```
|
||||
proposal
|
||||
(root node)
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
specs design
|
||||
(requires: (requires:
|
||||
proposal) proposal)
|
||||
│ │
|
||||
└─────────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
tasks
|
||||
(requires:
|
||||
specs, design)
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ APPLY PHASE │
|
||||
│ (requires: │
|
||||
│ tasks) │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
**State transitions:**
|
||||
|
||||
```
|
||||
BLOCKED ────────────────► READY ────────────────► DONE
|
||||
│ │ │
|
||||
Missing All deps File exists
|
||||
dependencies are DONE on filesystem
|
||||
```
|
||||
|
||||
### Information Flow
|
||||
|
||||
**Legacy workflow** — agent receives static instructions:
|
||||
|
||||
```
|
||||
User: "/openspec:proposal"
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Static instructions: │
|
||||
│ • Create proposal.md │
|
||||
│ • Create tasks.md │
|
||||
│ • Create design.md │
|
||||
│ • Create specs/<capability>/spec.md │
|
||||
│ │
|
||||
│ No awareness of what exists or │
|
||||
│ dependencies between artifacts │
|
||||
└─────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
Agent creates ALL artifacts in one go
|
||||
```
|
||||
|
||||
**OPSX** — agent queries for rich context:
|
||||
|
||||
```
|
||||
User: "/opsx:continue"
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────────────────┐
|
||||
│ Step 1: Query current state │
|
||||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ $ openspec status --change "add-auth" --json │ │
|
||||
│ │ │ │
|
||||
│ │ { │ │
|
||||
│ │ "artifacts": [ │ │
|
||||
│ │ {"id": "proposal", "status": "done"}, │ │
|
||||
│ │ {"id": "specs", "status": "ready"}, ◄── First ready │ │
|
||||
│ │ {"id": "design", "status": "ready"}, │ │
|
||||
│ │ {"id": "tasks", "status": "blocked", "missingDeps": ["specs"]}│ │
|
||||
│ │ ] │ │
|
||||
│ │ } │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Step 2: Get rich instructions for ready artifact │
|
||||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ $ openspec instructions specs --change "add-auth" --json │ │
|
||||
│ │ │ │
|
||||
│ │ { │ │
|
||||
│ │ "template": "# Specification\n\n## ADDED Requirements...", │ │
|
||||
│ │ "dependencies": [{"id": "proposal", "path": "...", "done": true}│ │
|
||||
│ │ "unlocks": ["tasks"] │ │
|
||||
│ │ } │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Step 3: Read dependencies → Create ONE artifact → Show what's unlocked │
|
||||
└──────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Iteration Model
|
||||
|
||||
**Legacy workflow** — awkward to iterate:
|
||||
|
||||
```
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
│/proposal│ ──► │ /apply │ ──► │/archive │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
│ │
|
||||
│ ├── "Wait, the design is wrong"
|
||||
│ │
|
||||
│ ├── Options:
|
||||
│ │ • Edit files manually (breaks context)
|
||||
│ │ • Abandon and start over
|
||||
│ │ • Push through and fix later
|
||||
│ │
|
||||
│ └── No official "go back" mechanism
|
||||
│
|
||||
└── Creates ALL artifacts at once
|
||||
```
|
||||
|
||||
**OPSX** — natural iteration:
|
||||
|
||||
```
|
||||
/opsx:new ───► /opsx:continue ───► /opsx:apply ───► /opsx:archive
|
||||
│ │ │
|
||||
│ │ ├── "The design is wrong"
|
||||
│ │ │
|
||||
│ │ ▼
|
||||
│ │ Just edit design.md
|
||||
│ │ and continue!
|
||||
│ │ │
|
||||
│ │ ▼
|
||||
│ │ /opsx:apply picks up
|
||||
│ │ where you left off
|
||||
│ │
|
||||
│ └── Creates ONE artifact, shows what's unlocked
|
||||
│
|
||||
└── Scaffolds change, waits for direction
|
||||
```
|
||||
|
||||
### Custom Schemas
|
||||
|
||||
Create custom workflows using the schema management commands:
|
||||
|
||||
```bash
|
||||
# Create a new schema from scratch (interactive)
|
||||
openspec schema init my-workflow
|
||||
|
||||
# Or fork an existing schema as a starting point
|
||||
openspec schema fork spec-driven my-workflow
|
||||
|
||||
# Validate your schema structure
|
||||
openspec schema validate my-workflow
|
||||
|
||||
# See where a schema resolves from (useful for debugging)
|
||||
openspec schema which my-workflow
|
||||
```
|
||||
|
||||
Schemas are stored in `openspec/schemas/` (project-local, version controlled) or `~/.local/share/openspec/schemas/` (user global).
|
||||
|
||||
**Schema structure:**
|
||||
```
|
||||
openspec/schemas/research-first/
|
||||
├── schema.yaml
|
||||
└── templates/
|
||||
├── research.md
|
||||
├── proposal.md
|
||||
└── tasks.md
|
||||
```
|
||||
|
||||
**Example schema.yaml:**
|
||||
```yaml
|
||||
name: research-first
|
||||
artifacts:
|
||||
- id: research # Added before proposal
|
||||
generates: research.md
|
||||
requires: []
|
||||
|
||||
- id: proposal
|
||||
generates: proposal.md
|
||||
requires: [research] # Now depends on research
|
||||
|
||||
- id: tasks
|
||||
generates: tasks.md
|
||||
requires: [proposal]
|
||||
```
|
||||
|
||||
**Dependency Graph:**
|
||||
```
|
||||
research ──► proposal ──► tasks
|
||||
```
|
||||
|
||||
### Summary
|
||||
|
||||
| Aspect | Legacy | OPSX |
|
||||
|--------|----------|------|
|
||||
| **Templates** | Hardcoded TypeScript | External YAML + Markdown |
|
||||
| **Dependencies** | None (all at once) | DAG with topological sort |
|
||||
| **State** | Phase-based mental model | Filesystem existence |
|
||||
| **Customization** | Edit source, rebuild | Create schema.yaml |
|
||||
| **Iteration** | Phase-locked | Fluid, edit anything |
|
||||
| **Editor Support** | 18+ configurator classes | Single skills directory |
|
||||
|
||||
## Schemas
|
||||
|
||||
Schemas define what artifacts exist and their dependencies. Currently available:
|
||||
|
||||
- **spec-driven** (default): proposal → specs → design → tasks
|
||||
|
||||
```bash
|
||||
# List available schemas
|
||||
openspec schemas
|
||||
|
||||
# See all schemas with their resolution sources
|
||||
openspec schema which --all
|
||||
|
||||
# Create a new schema interactively
|
||||
openspec schema init my-workflow
|
||||
|
||||
# Fork an existing schema for customization
|
||||
openspec schema fork spec-driven my-workflow
|
||||
|
||||
# Validate schema structure before use
|
||||
openspec schema validate my-workflow
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Use `/opsx:explore` to think through an idea before committing to a change
|
||||
- `/opsx:ff` when you know what you want, `/opsx:continue` when exploring
|
||||
- During `/opsx:apply`, if something's wrong — fix the artifact, then continue
|
||||
- Tasks track progress via checkboxes in `tasks.md`
|
||||
- Check status anytime: `openspec status --change "name"`
|
||||
|
||||
## Feedback
|
||||
|
||||
This is rough. That's intentional — we're learning what works.
|
||||
|
||||
Found a bug? Have ideas? Join us on [Discord](https://discord.gg/YctCnvvshC) or open an issue on [GitHub](https://github.com/Fission-AI/openspec/issues).
|
||||
@@ -0,0 +1,87 @@
|
||||
# Supported Tools
|
||||
|
||||
OpenSpec works with 20+ AI coding assistants. When you run `openspec init`, you'll be prompted to select which tools you use, and OpenSpec will configure the appropriate integrations.
|
||||
|
||||
## How It Works
|
||||
|
||||
For each tool you select, OpenSpec installs:
|
||||
|
||||
1. **Skills** — Reusable instruction files that power the `/opsx:*` workflow commands
|
||||
2. **Commands** — Tool-specific slash command bindings
|
||||
|
||||
## Tool Directory Reference
|
||||
|
||||
| Tool | Skills Location | Commands Location |
|
||||
|------|-----------------|-------------------|
|
||||
| Amazon Q Developer | `.amazonq/skills/` | `.amazonq/prompts/` |
|
||||
| Antigravity | `.agent/skills/` | `.agent/workflows/` |
|
||||
| Auggie (Augment CLI) | `.augment/skills/` | `.augment/commands/` |
|
||||
| Claude Code | `.claude/skills/` | `.claude/commands/opsx/` |
|
||||
| Cline | `.cline/skills/` | `.clinerules/workflows/` |
|
||||
| CodeBuddy | `.codebuddy/skills/` | `.codebuddy/commands/opsx/` |
|
||||
| Codex | `.codex/skills/` | `~/.codex/prompts/`* |
|
||||
| Continue | `.continue/skills/` | `.continue/prompts/` |
|
||||
| CoStrict | `.cospec/skills/` | `.cospec/openspec/commands/` |
|
||||
| Crush | `.crush/skills/` | `.crush/commands/opsx/` |
|
||||
| Cursor | `.cursor/skills/` | `.cursor/commands/` |
|
||||
| Factory Droid | `.factory/skills/` | `.factory/commands/` |
|
||||
| Gemini CLI | `.gemini/skills/` | `.gemini/commands/opsx/` |
|
||||
| GitHub Copilot | `.github/skills/` | `.github/prompts/` |
|
||||
| iFlow | `.iflow/skills/` | `.iflow/commands/` |
|
||||
| Kilo Code | `.kilocode/skills/` | `.kilocode/workflows/` |
|
||||
| OpenCode | `.opencode/skills/` | `.opencode/command/` |
|
||||
| Qoder | `.qoder/skills/` | `.qoder/commands/opsx/` |
|
||||
| Qwen Code | `.qwen/skills/` | `.qwen/commands/` |
|
||||
| RooCode | `.roo/skills/` | `.roo/commands/` |
|
||||
| Trae | `.trae/skills/` | `.trae/skills/` (via `/openspec-*`) |
|
||||
| Windsurf | `.windsurf/skills/` | `.windsurf/workflows/` |
|
||||
|
||||
\* Codex commands are installed to the global home directory (`~/.codex/prompts/` or `$CODEX_HOME/prompts/`), not the project directory.
|
||||
|
||||
## Non-Interactive Setup
|
||||
|
||||
For CI/CD or scripted setup, use the `--tools` flag:
|
||||
|
||||
```bash
|
||||
# Configure specific tools
|
||||
openspec init --tools claude,cursor
|
||||
|
||||
# Configure all supported tools
|
||||
openspec init --tools all
|
||||
|
||||
# Skip tool configuration
|
||||
openspec init --tools none
|
||||
```
|
||||
|
||||
**Available tool IDs:** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codebuddy`, `codex`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `opencode`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
|
||||
|
||||
## What Gets Installed
|
||||
|
||||
For each tool, OpenSpec generates 10 skill files that power the OPSX workflow:
|
||||
|
||||
| Skill | Purpose |
|
||||
|-------|---------|
|
||||
| `openspec-explore` | Thinking partner for exploring ideas |
|
||||
| `openspec-new-change` | Start a new change |
|
||||
| `openspec-continue-change` | Create the next artifact |
|
||||
| `openspec-ff-change` | Fast-forward through all planning artifacts |
|
||||
| `openspec-apply-change` | Implement tasks |
|
||||
| `openspec-verify-change` | Verify implementation completeness |
|
||||
| `openspec-sync-specs` | Sync delta specs to main (optional—archive prompts if needed) |
|
||||
| `openspec-archive-change` | Archive a completed change |
|
||||
| `openspec-bulk-archive-change` | Archive multiple changes at once |
|
||||
| `openspec-onboard` | Guided onboarding through a complete workflow cycle |
|
||||
|
||||
These skills are invoked via slash commands like `/opsx:new`, `/opsx:apply`, etc. See [Commands](commands.md) for the full list.
|
||||
|
||||
## Adding a New Tool
|
||||
|
||||
Want to add support for another AI coding assistant? Check out the [command adapter pattern](../CONTRIBUTING.md) or open an issue on GitHub.
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI Reference](cli.md) — Terminal commands
|
||||
- [Commands](commands.md) — Slash commands and skills
|
||||
- [Getting Started](getting-started.md) — First-time setup
|
||||
@@ -0,0 +1,425 @@
|
||||
# Workflows
|
||||
|
||||
This guide covers common workflow patterns for OpenSpec and when to use each one. For basic setup, see [Getting Started](getting-started.md). For command reference, see [Commands](commands.md).
|
||||
|
||||
## Philosophy: Actions, Not Phases
|
||||
|
||||
Traditional workflows force you through phases: planning, then implementation, then done. But real work doesn't fit neatly into boxes.
|
||||
|
||||
OPSX takes a different approach:
|
||||
|
||||
```text
|
||||
Traditional (phase-locked):
|
||||
|
||||
PLANNING ────────► IMPLEMENTING ────────► DONE
|
||||
│ │
|
||||
│ "Can't go back" │
|
||||
└────────────────────┘
|
||||
|
||||
OPSX (fluid actions):
|
||||
|
||||
proposal ──► specs ──► design ──► tasks ──► implement
|
||||
```
|
||||
|
||||
**Key principles:**
|
||||
|
||||
- **Actions, not phases** - Commands are things you can do, not stages you're stuck in
|
||||
- **Dependencies are enablers** - They show what's possible, not what's required next
|
||||
|
||||
> **Customization:** OPSX workflows are driven by schemas that define artifact sequences. See [Customization](customization.md) for details on creating custom schemas.
|
||||
|
||||
## Workflow Patterns
|
||||
|
||||
### Quick Feature
|
||||
|
||||
When you know what you want to build and just need to execute:
|
||||
|
||||
```text
|
||||
/opsx:new ──► /opsx:ff ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
|
||||
```
|
||||
|
||||
**Example conversation:**
|
||||
|
||||
```text
|
||||
You: /opsx:new add-logout-button
|
||||
|
||||
AI: Created openspec/changes/add-logout-button/
|
||||
Ready to create: proposal
|
||||
|
||||
You: /opsx:ff
|
||||
|
||||
AI: Creating all planning artifacts...
|
||||
✓ proposal.md
|
||||
✓ specs/
|
||||
✓ design.md
|
||||
✓ tasks.md
|
||||
Ready for implementation!
|
||||
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Working through tasks...
|
||||
✓ Added logout button to header
|
||||
✓ Implemented session clearing
|
||||
✓ Added confirmation dialog
|
||||
All tasks complete!
|
||||
|
||||
You: /opsx:archive
|
||||
|
||||
AI: ✓ Merged specs
|
||||
✓ Archived change
|
||||
```
|
||||
|
||||
**Best for:** Small to medium features, bug fixes, straightforward changes.
|
||||
|
||||
### Exploratory
|
||||
|
||||
When requirements are unclear or you need to investigate first:
|
||||
|
||||
```text
|
||||
/opsx:explore ──► /opsx:new ──► /opsx:continue ──► ... ──► /opsx:apply
|
||||
```
|
||||
|
||||
**Example conversation:**
|
||||
|
||||
```text
|
||||
You: /opsx:explore
|
||||
|
||||
AI: What would you like to explore?
|
||||
|
||||
You: I want to improve page load performance but I'm not sure
|
||||
where the bottlenecks are.
|
||||
|
||||
AI: Let me help investigate...
|
||||
[Analyzes bundle sizes, identifies slow queries, reviews
|
||||
component render patterns]
|
||||
|
||||
I found three main bottlenecks:
|
||||
1. Large unoptimized images
|
||||
2. Synchronous data fetching in ProductList
|
||||
3. Re-renders from context changes
|
||||
|
||||
Which would you like to address first?
|
||||
|
||||
You: Let's tackle the data fetching issue.
|
||||
|
||||
You: /opsx:new optimize-product-list-fetching
|
||||
|
||||
AI: Created change. Ready to create: proposal
|
||||
|
||||
You: /opsx:continue
|
||||
|
||||
AI: Creating proposal based on our exploration...
|
||||
[Writes proposal incorporating investigation insights]
|
||||
|
||||
Ready to create: specs, design
|
||||
Which would you like next?
|
||||
|
||||
You: /opsx:continue
|
||||
|
||||
AI: Creating specs...
|
||||
```
|
||||
|
||||
**Best for:** Performance optimization, debugging, architectural decisions, unclear requirements.
|
||||
|
||||
### Parallel Changes
|
||||
|
||||
Work on multiple changes at once:
|
||||
|
||||
```text
|
||||
Change A: /opsx:new ──► /opsx:ff ──► /opsx:apply (in progress)
|
||||
│
|
||||
context switch
|
||||
│
|
||||
Change B: /opsx:new ──► /opsx:ff ──────► /opsx:apply
|
||||
```
|
||||
|
||||
**Example conversation:**
|
||||
|
||||
```text
|
||||
You: I'm working on add-dark-mode but got pulled into a bug fix
|
||||
|
||||
You: /opsx:new fix-login-redirect
|
||||
|
||||
AI: Created openspec/changes/fix-login-redirect/
|
||||
|
||||
You: /opsx:ff
|
||||
|
||||
AI: ✓ Created planning artifacts
|
||||
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Working on fix-login-redirect...
|
||||
[Implements the fix]
|
||||
All tasks complete!
|
||||
|
||||
You: /opsx:archive
|
||||
|
||||
AI: ✓ Archived fix-login-redirect
|
||||
|
||||
You: Let's get back to dark mode
|
||||
|
||||
You: /opsx:apply add-dark-mode
|
||||
|
||||
AI: Resuming add-dark-mode...
|
||||
Picking up at task 2.3: Update Header...
|
||||
```
|
||||
|
||||
**Best for:** Parallel work streams, urgent interrupts, team collaboration.
|
||||
|
||||
When you have multiple completed changes, use `/opsx:bulk-archive`:
|
||||
|
||||
```text
|
||||
You: /opsx:bulk-archive
|
||||
|
||||
AI: Found 3 completed changes:
|
||||
- add-dark-mode (all tasks done)
|
||||
- fix-login-redirect (all tasks done)
|
||||
- update-footer (all tasks done)
|
||||
|
||||
Checking for spec conflicts...
|
||||
⚠ add-dark-mode and update-footer both touch specs/ui/
|
||||
|
||||
Inspecting codebase to resolve...
|
||||
Both changes are implemented. Will apply in chronological order.
|
||||
|
||||
Archive all 3 changes?
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: ✓ Archived add-dark-mode
|
||||
✓ Archived fix-login-redirect
|
||||
✓ Archived update-footer
|
||||
Specs merged in order: add-dark-mode → update-footer
|
||||
```
|
||||
|
||||
Bulk archive detects when multiple changes touch the same specs and resolves conflicts by checking what's actually implemented.
|
||||
|
||||
### Completing a Change
|
||||
|
||||
The recommended completion flow:
|
||||
|
||||
```text
|
||||
/opsx:apply ──► /opsx:verify ──► /opsx:archive
|
||||
│ │
|
||||
validates prompts to sync
|
||||
implementation if needed
|
||||
```
|
||||
|
||||
#### Verify: Check Your Work
|
||||
|
||||
`/opsx:verify` validates implementation against your artifacts across three dimensions:
|
||||
|
||||
```text
|
||||
You: /opsx:verify
|
||||
|
||||
AI: Verifying add-auth...
|
||||
|
||||
COMPLETENESS
|
||||
✓ All 12 tasks in tasks.md are checked
|
||||
✓ All requirements in specs have corresponding code
|
||||
⚠ Scenario "Session timeout after inactivity" not tested
|
||||
|
||||
CORRECTNESS
|
||||
✓ Implementation matches spec intent
|
||||
✓ Edge cases from scenarios are handled
|
||||
✓ Error states match spec definitions
|
||||
|
||||
COHERENCE
|
||||
✓ Design decisions reflected in code structure
|
||||
✓ Naming conventions consistent with design.md
|
||||
⚠ Design mentions "event-driven" but implementation uses polling
|
||||
|
||||
SUMMARY
|
||||
─────────────────────────────
|
||||
Critical issues: 0
|
||||
Warnings: 2
|
||||
Ready to archive: Yes (with warnings)
|
||||
|
||||
Recommendations:
|
||||
1. Add test for session timeout scenario
|
||||
2. Consider refactoring to event-driven as designed, or update design.md
|
||||
```
|
||||
|
||||
**What verify checks:**
|
||||
|
||||
| Dimension | What it validates |
|
||||
|-----------|------------------|
|
||||
| Completeness | All tasks done, all requirements implemented, scenarios covered |
|
||||
| Correctness | Implementation matches spec intent, edge cases handled |
|
||||
| Coherence | Design decisions reflected in code, patterns consistent |
|
||||
|
||||
Verify won't block archive, but it surfaces issues you might want to address first.
|
||||
|
||||
#### Archive: Finalize the Change
|
||||
|
||||
`/opsx:archive` completes the change and moves it to the archive:
|
||||
|
||||
```text
|
||||
You: /opsx:archive
|
||||
|
||||
AI: Archiving add-auth...
|
||||
|
||||
Artifact status:
|
||||
✓ proposal.md exists
|
||||
✓ specs/ exists
|
||||
✓ design.md exists
|
||||
✓ tasks.md exists (12/12 tasks complete)
|
||||
|
||||
Delta specs: Not yet synced to main
|
||||
→ Would you like to sync now?
|
||||
|
||||
You: Yes
|
||||
|
||||
AI: ✓ Synced specs to openspec/specs/auth/spec.md
|
||||
✓ Moved to openspec/changes/archive/2025-01-24-add-auth/
|
||||
|
||||
Change archived successfully.
|
||||
```
|
||||
|
||||
Archive will prompt if specs aren't synced. It won't block on incomplete tasks, but it will warn you.
|
||||
|
||||
## When to Use What
|
||||
|
||||
### `/opsx:ff` vs `/opsx:continue`
|
||||
|
||||
| Situation | Use |
|
||||
|-----------|-----|
|
||||
| Clear requirements, ready to build | `/opsx:ff` |
|
||||
| Exploring, want to review each step | `/opsx:continue` |
|
||||
| Want to iterate on proposal before specs | `/opsx:continue` |
|
||||
| Time pressure, need to move fast | `/opsx:ff` |
|
||||
| Complex change, want control | `/opsx:continue` |
|
||||
|
||||
**Rule of thumb:** If you can describe the full scope upfront, use `/opsx:ff`. If you're figuring it out as you go, use `/opsx:continue`.
|
||||
|
||||
### When to Update vs Start Fresh
|
||||
|
||||
A common question: when is updating an existing change okay, and when should you start a new one?
|
||||
|
||||
**Update the existing change when:**
|
||||
|
||||
- Same intent, refined execution
|
||||
- Scope narrows (MVP first, rest later)
|
||||
- Learning-driven corrections (codebase isn't what you expected)
|
||||
- Design tweaks based on implementation discoveries
|
||||
|
||||
**Start a new change when:**
|
||||
|
||||
- Intent fundamentally changed
|
||||
- Scope exploded to different work entirely
|
||||
- Original change can be marked "done" standalone
|
||||
- Patches would confuse more than clarify
|
||||
|
||||
```text
|
||||
┌─────────────────────────────────────┐
|
||||
│ Is this the same work? │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────────────────┼──────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
Same intent? >50% overlap? Can original
|
||||
Same problem? Same scope? be "done" without
|
||||
│ │ these changes?
|
||||
│ │ │
|
||||
┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
|
||||
│ │ │ │ │ │
|
||||
YES NO YES NO NO YES
|
||||
│ │ │ │ │ │
|
||||
▼ ▼ ▼ ▼ ▼ ▼
|
||||
UPDATE NEW UPDATE NEW UPDATE NEW
|
||||
```
|
||||
|
||||
**Example: "Add dark mode"**
|
||||
|
||||
- "Need to also support custom themes" → New change (scope exploded)
|
||||
- "System preference detection is harder than expected" → Update (same intent)
|
||||
- "Let's ship toggle first, add preferences later" → Update then archive, then new change
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Keep Changes Focused
|
||||
|
||||
One logical unit of work per change. If you're doing "add feature X and also refactor Y", consider two separate changes.
|
||||
|
||||
**Why it matters:**
|
||||
- Easier to review and understand
|
||||
- Cleaner archive history
|
||||
- Can ship independently
|
||||
- Simpler rollback if needed
|
||||
|
||||
### Use `/opsx:explore` for Unclear Requirements
|
||||
|
||||
Before committing to a change, explore the problem space:
|
||||
|
||||
```text
|
||||
You: /opsx:explore
|
||||
|
||||
AI: What would you like to explore?
|
||||
|
||||
You: How should we handle rate limiting for our API?
|
||||
|
||||
AI: Let me investigate your current setup and options...
|
||||
[Researches codebase, considers patterns]
|
||||
|
||||
I see three approaches we could take:
|
||||
1. Middleware-based (simple, per-endpoint)
|
||||
2. Redis-backed (scalable, shared state)
|
||||
3. Token bucket per user (fair, complex)
|
||||
|
||||
Your current stack suggests #1 or #2. What's your scale?
|
||||
```
|
||||
|
||||
Exploration clarifies thinking before you create artifacts.
|
||||
|
||||
### Verify Before Archiving
|
||||
|
||||
Use `/opsx:verify` to check implementation matches artifacts:
|
||||
|
||||
```text
|
||||
You: /opsx:verify
|
||||
|
||||
AI: Verifying add-dark-mode...
|
||||
|
||||
✓ All tasks in tasks.md are checked
|
||||
✓ Requirements in specs have corresponding code
|
||||
✓ Design decisions are reflected in implementation
|
||||
|
||||
Ready to archive!
|
||||
```
|
||||
|
||||
Catches mismatches before you close out the change.
|
||||
|
||||
### Name Changes Clearly
|
||||
|
||||
Good names make `openspec list` useful:
|
||||
|
||||
```text
|
||||
Good: Avoid:
|
||||
add-dark-mode feature-1
|
||||
fix-login-redirect update
|
||||
optimize-product-query changes
|
||||
implement-2fa wip
|
||||
```
|
||||
|
||||
## Command Quick Reference
|
||||
|
||||
For full command details and options, see [Commands](commands.md).
|
||||
|
||||
| Command | Purpose | When to Use |
|
||||
|---------|---------|-------------|
|
||||
| `/opsx:explore` | Think through ideas | Unclear requirements, investigation |
|
||||
| `/opsx:new` | Start a change | Beginning any new work |
|
||||
| `/opsx:continue` | Create next artifact | Step-by-step artifact creation |
|
||||
| `/opsx:ff` | Create all planning artifacts | Clear scope, ready to build |
|
||||
| `/opsx:apply` | Implement tasks | Ready to write code |
|
||||
| `/opsx:verify` | Validate implementation | Before archiving, catch mismatches |
|
||||
| `/opsx:sync` | Merge delta specs | Optional—archive prompts if needed |
|
||||
| `/opsx:archive` | Complete the change | All work finished |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes | Parallel work, batch completion |
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Commands](commands.md) - Full command reference with options
|
||||
- [Concepts](concepts.md) - Deep dive into specs, artifacts, and schemas
|
||||
- [Customization](customization.md) - Create custom workflows
|
||||
@@ -0,0 +1,42 @@
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default tseslint.config(
|
||||
{
|
||||
files: ['src/**/*.ts'],
|
||||
extends: [...tseslint.configs.recommended],
|
||||
rules: {
|
||||
// Prevent static imports of @inquirer modules to avoid pre-commit hook hangs.
|
||||
// These modules have side effects that can keep the Node.js event loop alive
|
||||
// when stdin is piped. Use dynamic import() instead.
|
||||
// See: https://github.com/Fission-AI/OpenSpec/issues/367
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
patterns: [
|
||||
{
|
||||
group: ['@inquirer/*'],
|
||||
message:
|
||||
'Use dynamic import() for @inquirer modules to prevent pre-commit hook hangs. See #367.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// Disable rules that need broader cleanup - focus on critical issues only
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'no-empty': 'off',
|
||||
'prefer-const': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
// init.ts is dynamically imported from cli/index.ts, so static @inquirer
|
||||
// imports there are safe - they won't be loaded at CLI startup
|
||||
files: ['src/core/init.ts'],
|
||||
rules: {
|
||||
'no-restricted-imports': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
ignores: ['dist/**', 'node_modules/**', '*.js', '*.mjs'],
|
||||
}
|
||||
);
|
||||
Generated
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1767640445,
|
||||
"narHash": "sha256-UWYqmD7JFBEDBHWYcqE6s6c77pWdcU/i+bwD6XxMb8A=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9f0c42f8bc7151b8e7e5840fb3bd454ad850d8c5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
{
|
||||
description = "OpenSpec - AI-native system for spec-driven development";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ self, nixpkgs }:
|
||||
let
|
||||
supportedSystems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
"x86_64-darwin"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
|
||||
forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system);
|
||||
in
|
||||
{
|
||||
packages = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
in
|
||||
{
|
||||
default = pkgs.stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "openspec";
|
||||
version = (builtins.fromJSON (builtins.readFile ./package.json)).version;
|
||||
|
||||
src = lib.fileset.toSource {
|
||||
root = ./.;
|
||||
fileset = lib.fileset.unions [
|
||||
./src
|
||||
./bin
|
||||
./schemas
|
||||
./scripts
|
||||
./test
|
||||
./package.json
|
||||
./pnpm-lock.yaml
|
||||
./tsconfig.json
|
||||
./build.js
|
||||
./vitest.config.ts
|
||||
./vitest.setup.ts
|
||||
./eslint.config.js
|
||||
];
|
||||
};
|
||||
|
||||
pnpmDeps = pkgs.fetchPnpmDeps {
|
||||
inherit (finalAttrs) pname version src;
|
||||
pnpm = pkgs.pnpm_9;
|
||||
fetcherVersion = 3;
|
||||
hash = "sha256-9s2kdvd7svK4hofnD66HkDc86WTQeayfF5y7L2dmjNg=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
nodejs_20
|
||||
npmHooks.npmInstallHook
|
||||
pnpmConfigHook
|
||||
pnpm_9
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
pnpm run build
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
dontNpmPrune = true;
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "AI-native system for spec-driven development";
|
||||
homepage = "https://github.com/Fission-AI/OpenSpec";
|
||||
license = licenses.mit;
|
||||
maintainers = [ ];
|
||||
mainProgram = "openspec";
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
apps = forAllSystems (system: {
|
||||
default = {
|
||||
type = "app";
|
||||
program = "${self.packages.${system}.default}/bin/openspec";
|
||||
};
|
||||
});
|
||||
|
||||
devShells = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
nodejs_20
|
||||
pnpm_9
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
echo "OpenSpec development environment"
|
||||
echo "Node version: $(node --version)"
|
||||
echo "pnpm version: $(pnpm --version)"
|
||||
echo "Run 'pnpm install' to install dependencies"
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
# OpenSpec Parallel Delta Remediation Plan
|
||||
|
||||
## Problem Summary
|
||||
- Active changes apply requirement-level replacements when archiving. When two changes touch the same requirement, the second archive overwrites the first and silently drops scenarios (e.g., Windsurf vs. Kilo Code slash command updates).
|
||||
- The archive workflow (`src/core/archive.ts:191` and `src/core/archive.ts:501`) rebuilds main specs by replacing entire requirement blocks with the content contained in the change delta. The delta format (`src/core/parsers/requirement-blocks.ts:113`) has no notion of base versions or scenario-level operations.
|
||||
- The tooling cannot detect divergence between the change author’s starting point and the live spec, so parallel development corrupts the source of truth without warning.
|
||||
|
||||
## Observed Failure Mode
|
||||
- Change A (`add-windsurf-workflows`) adds a Windsurf scenario under `Slash Command Configuration`.
|
||||
- Change B (`add-kilocode-workflows`) adds a Kilo Code scenario to the same requirement, starting from the pre-Windsurf spec.
|
||||
- After Change A archives, the main spec contains both scenarios.
|
||||
- When Change B archives, `buildUpdatedSpec` sees a `MODIFIED` block for `Slash Command Configuration` and replaces the requirement with the four-scenario variant shipped in that change. Because that file never learned about Windsurf, the Windsurf scenario disappears.
|
||||
- There is no warning, diff, or conflict indicator—the archive completes successfully, and the source-of-truth spec now omits a shipped scenario.
|
||||
|
||||
## Root Causes
|
||||
1. **Replace-only semantics.** `buildUpdatedSpec` performs hash-map substitution of requirement blocks and cannot merge or compare individual scenarios (`src/core/archive.ts:455`-`src/core/archive.ts:526`).
|
||||
2. **Missing base fingerprint.** Changes do not persist the requirement content they were authored against, so the archive step cannot tell if the live spec diverged.
|
||||
3. **Single-level granularity.** The delta language only understands requirements. Even if we introduced scenario-level parsing, we would still lose sibling edits without an accompanying merge strategy.
|
||||
4. **Lack of conflict UX.** The CLI never forces contributors to reconcile parallel updates. There is no equivalent of `git merge`, `git rebase`, or conflict markers.
|
||||
|
||||
## Design Objectives
|
||||
- Preserve every approved scenario regardless of archive order.
|
||||
- Detect and block speculative archives when the live spec diverges from the author’s base.
|
||||
- Provide a deterministic, reviewable conflict resolution flow that mirrors source-control best practices.
|
||||
- Keep the authoring experience ergonomic: deltas should remain human-editable markdown.
|
||||
- Support incremental adoption so existing repositories can roll forward without breaking active work.
|
||||
|
||||
## Proposed Fix: Layered Remediation
|
||||
|
||||
### Phase 0 – Stop the Bleeding (Detection & Guardrails)
|
||||
1. **Persist requirement fingerprints alongside each change.**
|
||||
- When scaffolding or validating a change, capture the current requirement body for every `MODIFIED`/`REMOVED`/`RENAMED` entry and write it to `changes/<id>/meta.json`.
|
||||
- Store a stable hash (e.g., SHA-256) of the base requirement content and the raw text itself for later merges.
|
||||
2. **Validate fingerprints during archive.**
|
||||
- Before `buildUpdatedSpec` mutates specs, recompute the requirement hash from the live spec.
|
||||
- If the hash differs from the stored base, abort and instruct the user to rebase. This makes the destructive path impossible.
|
||||
3. **Surface intent in CLI output.**
|
||||
- Show which requirements are stale, when they diverged, and which change last touched them.
|
||||
4. **Document interim manual mitigation.**
|
||||
- Update `openspec/AGENTS.md` and docs so contributors know to rerun `openspec change sync` (see Phase 1) whenever another change lands.
|
||||
|
||||
_Outcome:_ We prevent data loss immediately while we work on a richer merge story.
|
||||
|
||||
### Phase 1 – Add a Rebase Workflow (Author-Side Merge)
|
||||
1. **Introduce `openspec change sync <id>` (or `rebase`).**
|
||||
- Reads the stored base snapshot, the current spec, and the author’s delta.
|
||||
- Performs a 3-way merge per requirement. A naive diff3 on markdown lines is acceptable initially because we already operate on requirement-sized chunks.
|
||||
- If the merge is clean, rewrite the `MODIFIED` block with the merged text and refresh the stored fingerprint.
|
||||
- On conflict, write conflict markers inside the change delta (similar to Git) and require the author to hand-edit before re-running validation.
|
||||
2. **Enrich validator messages.**
|
||||
- `openspec validate` should flag unresolved conflict markers or fingerprint mismatches so errors appear early in the workflow.
|
||||
3. **Optional:** Offer a `--rewrite-scenarios` helper that merges bullet lists of scenarios to reduce manual editing noise.
|
||||
|
||||
_Outcome:_ Contributors can safely reconcile their work with the latest spec before archiving, restoring true parallel development.
|
||||
|
||||
### Phase 2 – Increase Delta Granularity
|
||||
1. **Extend the delta language with scenario-level directives.**
|
||||
- Allow `## MODIFIED Requirements` + `## ADDED Scenarios` / `## MODIFIED Scenarios` sections nested under the requirement header.
|
||||
- Backed by stable scenario identifiers (explicit IDs or generated hashes) stored in `meta.json`. This lets the system reason about individual scenarios.
|
||||
2. **Teach the parser to understand nested operations.**
|
||||
- Update `parseDeltaSpec` to emit scenario-level operations in addition to requirement blocks.
|
||||
- Update `buildUpdatedSpec` (or its replacement) to merge scenario lists, preserving order while inserting new entries in a deterministic fashion.
|
||||
3. **Automate migration.**
|
||||
- Provide a one-time command that inspects each existing spec, injects scenario IDs, and rewrites in-flight change deltas into the richer format.
|
||||
4. **Continue to rely on the Phase 1 rebase flow for conflicts when two changes edit the same scenario body or description.**
|
||||
|
||||
_Outcome:_ Most concurrent updates become commutative, drastically reducing the odds of human merges.
|
||||
|
||||
### Phase 3 – Structured Spec Graph (Long-Term)
|
||||
1. **Define stable requirement IDs.**
|
||||
- Embed `Requirement ID: <uuid>` markers in specs so renames and moves are trackable.
|
||||
- This enables future features like cross-capability references and better diff visualizations.
|
||||
2. **Model spec edits as operations over an AST.**
|
||||
- Build an intermediate representation (IR) for requirements/scenarios/metadata.
|
||||
- Use operational transforms or CRDT-like techniques to guarantee merge associativity.
|
||||
3. **Integrate with Git directly.**
|
||||
- Offer optional `openspec branch` scaffolding that aligns spec changes with Git branches, letting teams leverage Git’s conflict editor for the markdown IR.
|
||||
|
||||
_Outcome:_ OpenSpec graduates from replace-based updates to a resilient, intent-preserving spec management platform.
|
||||
|
||||
## Migration & Product Impacts
|
||||
- **Backfill metadata:** add hashes for all active changes and the current main specs during the initial rollout.
|
||||
- **CLI UX:** new commands (`change sync`, enhanced `archive`) require documentation, help text, and release notes.
|
||||
- **Docs & AGENTS updates:** reinforce the rebase workflow and explain conflict resolution to AI assistants.
|
||||
- **Testing:** introduce fixtures covering divergent requirement fingerprints and merge resolution logic.
|
||||
- **Telemetry (optional):** log fingerprint mismatches so we can see how often teams hit conflicts after the rollout.
|
||||
|
||||
## Open Questions / Risks
|
||||
- How should we order scenarios when multiple changes insert at different points? (Consider optional `position` metadata or deterministic alphabetical fallbacks.)
|
||||
- What is the graceful failure mode if contributors delete the `meta.json` file? (CLI should recreate fingerprints on demand.)
|
||||
- Do we need to support offline authors who cannot easily re-run the sync command before archiving? (Potential `--accept-outdated` escape hatch for emergencies.)
|
||||
- How will archived historical changes be handled? We may need a migration script to embed fingerprints retroactively so re-validation succeeds.
|
||||
|
||||
## Immediate Next Steps
|
||||
1. Prototype fingerprint capture during `openspec change validate` and block archive on mismatches.
|
||||
2. Ship `openspec change sync` with line-based diff3 merging and conflict markers.
|
||||
3. Update contributor docs and AI instructions to mandate running `sync` before archiving.
|
||||
4. Plan the scenario-level delta extension and migration path as a follow-up RFC.
|
||||
@@ -1,472 +0,0 @@
|
||||
# OpenSpec Instructions
|
||||
|
||||
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.
|
||||
|
||||
## Core Principle
|
||||
|
||||
OpenSpec is an AI-native system for change-driven development where:
|
||||
- **Specs** (`specs/`) reflect what IS currently built and deployed
|
||||
- **Changes** (`changes/`) contain proposals for what SHOULD be changed
|
||||
- **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
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── project.md # Project-specific context (tech stack, conventions)
|
||||
├── README.md # This file - OpenSpec instructions
|
||||
├── specs/ # Current truth - what IS built
|
||||
│ ├── [capability]/ # Single, focused capability
|
||||
│ │ ├── spec.md # WHAT the capability does and WHY
|
||||
│ │ └── design.md # HOW it's built (established patterns)
|
||||
│ └── ...
|
||||
├── changes/ # Proposed changes - what we're CHANGING
|
||||
│ ├── [change-name]/
|
||||
│ │ ├── proposal.md # Why, what, impact (consolidated)
|
||||
│ │ ├── tasks.md # Implementation checklist
|
||||
│ │ ├── design.md # Technical decisions (optional, for complex changes)
|
||||
│ │ └── specs/ # Future state of affected specs
|
||||
│ │ └── [capability]/
|
||||
│ │ └── spec.md # Clean markdown (no diff syntax)
|
||||
│ └── archive/ # Completed changes (dated)
|
||||
```
|
||||
|
||||
### Capability Organization
|
||||
|
||||
**Use capabilities, not features** - Each directory under `specs/` represents a single, focused responsibility:
|
||||
- **Verb-noun naming**: `user-auth`, `payment-capture`, `order-checkout`
|
||||
- **10-minute rule**: Each capability should be understandable in <10 minutes
|
||||
- **Single purpose**: If it needs "AND" to describe it, split it
|
||||
|
||||
Examples:
|
||||
```
|
||||
✅ GOOD: user-auth, user-sessions, payment-capture, payment-refunds
|
||||
❌ BAD: users, payments, core, misc
|
||||
```
|
||||
|
||||
## Key Behavioral Rules
|
||||
|
||||
### 1. Always Start by Reading
|
||||
|
||||
Before any task:
|
||||
1. **Read relevant specs** in `specs/[capability]/spec.md` to understand current state
|
||||
2. **Check pending changes** in `changes/` directory for potential conflicts
|
||||
3. **Read project.md** for project-specific conventions
|
||||
|
||||
### 2. When to Create Change Proposals
|
||||
|
||||
**ALWAYS create a change proposal for:**
|
||||
- New features or functionality
|
||||
- Breaking changes (API changes, schema updates)
|
||||
- Architecture changes or new patterns
|
||||
- Performance optimizations that change behavior
|
||||
- Security updates affecting auth/access patterns
|
||||
- Any change requiring multiple steps or affecting multiple systems
|
||||
|
||||
**SKIP proposals for:**
|
||||
- Bug fixes that restore intended behavior
|
||||
- Typos, formatting, or comment updates
|
||||
- Dependency updates (unless breaking)
|
||||
- Configuration or environment variable changes
|
||||
- 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:
|
||||
|
||||
```bash
|
||||
# 1. Create the change directory
|
||||
openspec/changes/[descriptive-name]/
|
||||
|
||||
# 2. Generate proposal.md with all context
|
||||
## Why
|
||||
[1-2 sentences on the problem/opportunity]
|
||||
|
||||
## What Changes
|
||||
[Bullet list of changes, including breaking changes]
|
||||
|
||||
## Impact
|
||||
- Affected specs: [list capabilities that will change]
|
||||
- Affected code: [list key files/systems]
|
||||
|
||||
# 3. Create future state specs for ALL affected capabilities
|
||||
# - Store complete spec files as they will exist after the change
|
||||
# - Use clean markdown without diff syntax (+/- prefixes)
|
||||
# - Include all formatting and structure of the final intended state
|
||||
specs/
|
||||
└── [capability]/
|
||||
└── spec.md
|
||||
|
||||
# 4. Create tasks.md with implementation steps
|
||||
## 1. [Task Group]
|
||||
- [ ] 1.1 [Specific task]
|
||||
- [ ] 1.2 [Specific task]
|
||||
|
||||
# 5. For complex changes, add design.md
|
||||
[Technical decisions and trade-offs]
|
||||
```
|
||||
|
||||
### 4. The Change Lifecycle
|
||||
|
||||
1. **Propose** → Create change directory with all documentation
|
||||
2. **Review** → User reviews and approves the proposal
|
||||
3. **Implement** → Follow the approved tasks.md (can be multiple PRs)
|
||||
4. **Deploy** → User confirms deployment
|
||||
5. **Update Specs** → Sync specs/ with new reality (IF the change affects system capabilities)
|
||||
6. **Archive** → Move to `changes/archive/YYYY-MM-DD-[name]/`
|
||||
|
||||
### 5. Implementing Changes
|
||||
|
||||
When implementing an approved change:
|
||||
1. Follow the tasks.md checklist exactly
|
||||
2. **Mark completed tasks** in tasks.md as you finish them (e.g., `- [x] 1.1 Task completed`)
|
||||
3. Ensure code matches the proposed behavior
|
||||
4. Update any affected tests
|
||||
5. **Keep change in `changes/` directory** - do NOT archive in implementation PR
|
||||
|
||||
**Multiple Implementation PRs:**
|
||||
- Changes can be implemented across multiple PRs
|
||||
- Each PR should update tasks.md to mark what was completed
|
||||
- Different developers can work on different task groups
|
||||
- Example: PR #1 completes tasks 1.1-1.3, PR #2 completes tasks 2.1-2.4
|
||||
|
||||
### 6. Updating Specs and Archiving After Deployment
|
||||
|
||||
**Create a separate PR after deployment** that:
|
||||
1. Moves change to `changes/archive/YYYY-MM-DD-[name]/`
|
||||
2. Updates relevant files in `specs/` to reflect new reality (if needed)
|
||||
3. If design.md exists, incorporates proven patterns into `specs/[capability]/design.md`
|
||||
|
||||
This ensures changes are only archived when truly complete and deployed.
|
||||
|
||||
### 7. Types of Changes That Don't Require Specs
|
||||
|
||||
Some changes only affect development infrastructure and don't need specs:
|
||||
- Initial project setup (package.json, tsconfig.json, etc.)
|
||||
- Development tooling changes (linters, formatters, build tools)
|
||||
- CI/CD configuration
|
||||
- Development dependencies
|
||||
|
||||
For these changes:
|
||||
1. Implement → Deploy → Mark tasks complete → Archive
|
||||
2. Skip the "Update Specs" step entirely
|
||||
|
||||
### What Deserves a Spec?
|
||||
|
||||
Ask yourself:
|
||||
- Is this a system capability that users or other systems interact with?
|
||||
- Does it have ongoing behavior that needs documentation?
|
||||
- Would a new developer need to understand this to work with the system?
|
||||
|
||||
If NO to all → No spec needed (likely just tooling/infrastructure)
|
||||
|
||||
## Understanding Specs vs Code
|
||||
|
||||
### Specs Document WHAT and WHY
|
||||
```markdown
|
||||
# Authentication Spec
|
||||
|
||||
Users SHALL authenticate with email and password.
|
||||
|
||||
WHEN credentials are valid THEN issue JWT token.
|
||||
WHEN credentials are invalid THEN return generic error.
|
||||
|
||||
WHY: Prevent user enumeration attacks.
|
||||
```
|
||||
|
||||
### Code Documents HOW
|
||||
```javascript
|
||||
// Implementation details
|
||||
const user = await db.users.findOne({ email });
|
||||
const valid = await bcrypt.compare(password, user.hashedPassword);
|
||||
```
|
||||
|
||||
**Key Distinction**: Specs capture intent, constraints, and decisions that aren't obvious from code.
|
||||
|
||||
## Common Scenarios
|
||||
|
||||
### New Feature Request
|
||||
```
|
||||
User: "Add password reset functionality"
|
||||
|
||||
You should:
|
||||
1. Read specs/user-auth/spec.md
|
||||
2. Check changes/ for pending auth changes
|
||||
3. Create changes/add-password-reset/ with proposal
|
||||
4. Wait for approval before implementing
|
||||
```
|
||||
|
||||
### Bug Fix
|
||||
```
|
||||
User: "Getting null pointer error when bio is empty"
|
||||
|
||||
You should:
|
||||
1. Check if spec says bios are optional
|
||||
2. If yes → Fix directly (it's a bug)
|
||||
3. If no → Create change proposal (it's a behavior change)
|
||||
```
|
||||
|
||||
### Infrastructure Setup
|
||||
```
|
||||
User: "Initialize TypeScript project"
|
||||
|
||||
You should:
|
||||
1. Create change proposal for TypeScript setup
|
||||
2. Implement configuration files (PR #1)
|
||||
3. Mark tasks complete in tasks.md
|
||||
4. After deployment, create separate PR to archive
|
||||
(no specs update needed - this is tooling, not a capability)
|
||||
```
|
||||
|
||||
## Summary Workflow
|
||||
|
||||
1. **Receive request** → Determine if it needs a change proposal
|
||||
2. **Read current state** → Check specs and pending changes
|
||||
3. **Create proposal** → Generate complete change documentation
|
||||
4. **Get approval** → User reviews the proposal
|
||||
5. **Implement** → Follow approved tasks, mark completed items in tasks.md
|
||||
6. **Deploy** → User deploys the implementation
|
||||
7. **Archive PR** → Create separate PR to:
|
||||
- Move change to archive
|
||||
- Update specs if needed
|
||||
- Mark change as complete
|
||||
|
||||
## PR Workflow Examples
|
||||
|
||||
### Single Developer, Simple Change
|
||||
```
|
||||
PR #1: Implementation
|
||||
- Implement all tasks
|
||||
- Update tasks.md marking items complete
|
||||
- Get merged and deployed
|
||||
|
||||
PR #2: Archive (after deployment)
|
||||
- Move changes/feature-x/ → changes/archive/2025-01-15-feature-x/
|
||||
- Update specs if needed
|
||||
```
|
||||
|
||||
### Multiple Developers, Complex Change
|
||||
```
|
||||
PR #1: Alice implements auth components
|
||||
- Complete tasks 1.1, 1.2, 1.3
|
||||
- Update tasks.md marking these complete
|
||||
|
||||
PR #2: Bob implements UI components
|
||||
- Complete tasks 2.1, 2.2
|
||||
- Update tasks.md marking these complete
|
||||
|
||||
PR #3: Alice fixes integration issues
|
||||
- Complete remaining task 1.4
|
||||
- Update tasks.md
|
||||
|
||||
[Deploy all changes]
|
||||
|
||||
PR #4: Archive
|
||||
- Move to archive with deployment date
|
||||
- Update specs to reflect new auth flow
|
||||
```
|
||||
|
||||
### Key Rules
|
||||
- **Never archive in implementation PRs** - changes aren't done until deployed
|
||||
- **Always update tasks.md** - shows accurate progress
|
||||
- **One archive PR per change** - clear completion boundary
|
||||
- **Archive PR includes spec updates** - keeps specs current
|
||||
|
||||
## Capability Organization Best Practices
|
||||
|
||||
### Naming Capabilities
|
||||
- Use **verb-noun** patterns: `user-auth`, `payment-capture`, `order-checkout`
|
||||
- Be specific: `payment-capture` not just `payments`
|
||||
- Keep flat: Avoid nesting capabilities within capabilities
|
||||
- Singular focus: If you need "AND" to describe it, split it
|
||||
|
||||
### When to Split Capabilities
|
||||
Split when you have:
|
||||
- Multiple unrelated API endpoints
|
||||
- Different user personas or actors
|
||||
- Separate deployment considerations
|
||||
- Independent evolution paths
|
||||
|
||||
#### Capability Boundary Guidelines
|
||||
- Would you import these separately? → Separate capabilities
|
||||
- Different deployment cadence? → Separate capabilities
|
||||
- Different teams own them? → Separate capabilities
|
||||
- Shared data models are OK, shared business logic means combine
|
||||
|
||||
Examples:
|
||||
- user-auth (login/logout) vs user-sessions (token management) → SEPARATE
|
||||
- payment-capture vs payment-refunds → SEPARATE (different workflows)
|
||||
- user-profile vs user-settings → COMBINE (same data model, same owner)
|
||||
|
||||
### Cross-Cutting Concerns
|
||||
For system-wide policies (rate limiting, error handling, security), document them in:
|
||||
- `project.md` for project-wide conventions
|
||||
- Within relevant capability specs where they apply
|
||||
- Or create a dedicated capability if complex enough (e.g., `api-rate-limiting/`)
|
||||
|
||||
### Examples of Well-Organized Capabilities
|
||||
```
|
||||
specs/
|
||||
├── user-auth/ # Login, logout, password reset
|
||||
├── user-sessions/ # Token management, refresh
|
||||
├── user-profile/ # Profile CRUD operations
|
||||
├── payment-capture/ # Processing payments
|
||||
├── payment-refunds/ # Handling refunds
|
||||
└── order-checkout/ # Checkout workflow
|
||||
```
|
||||
|
||||
For detailed guidance, see the [Capability Organization Guide](../docs/capability-organization.md).
|
||||
|
||||
## Common Scenarios and Clarifications
|
||||
|
||||
### Decision Ambiguity: Bug vs Behavior Change
|
||||
|
||||
When specs are missing or ambiguous:
|
||||
- If NO spec exists → Treat current code behavior as implicit spec, require proposal
|
||||
- If spec is VAGUE → Require proposal to clarify spec alongside fix
|
||||
- If code and spec DISAGREE → Spec is truth, code is buggy (fix without proposal)
|
||||
- If unsure → Default to creating a proposal (safer option)
|
||||
|
||||
Example:
|
||||
```
|
||||
User: "The API returns 404 for missing users but should return 400"
|
||||
AI: Is this a bug (spec says 400) or behavior change (spec says 404)?
|
||||
```
|
||||
|
||||
### When You Don't Know the Scope
|
||||
It's OK to explore first! Tell the user you need to investigate, then create an informed proposal.
|
||||
|
||||
### Exploration Phase (When Needed)
|
||||
|
||||
BEFORE creating proposal, you may need exploration when:
|
||||
- User request is vague or high-level
|
||||
- Multiple implementation approaches exist
|
||||
- Scope is unclear without seeing code
|
||||
|
||||
Exploration checklist:
|
||||
1. Tell user you need to explore first
|
||||
2. Use Grep/Read to understand current state
|
||||
3. Create initial proposal based on findings
|
||||
4. Refine with user feedback
|
||||
|
||||
Example:
|
||||
```
|
||||
User: "Add caching to improve performance"
|
||||
AI: "Let me explore the codebase to understand the current architecture and identify caching opportunities."
|
||||
[After exploration]
|
||||
AI: "Based on my analysis, I've identified three areas where caching would help. Here's my proposal..."
|
||||
```
|
||||
|
||||
### When No Specs Exist
|
||||
Treat current code as implicit spec. Your proposal should document current state AND proposed changes.
|
||||
|
||||
### When in Doubt
|
||||
Default to creating a proposal. It's easier to skip an unnecessary proposal than fix an undocumented change.
|
||||
|
||||
### AI Workflow Adaptations
|
||||
|
||||
Task tracking with OpenSpec:
|
||||
- Track exploration tasks separately from implementation
|
||||
- Document proposal creation steps as you go
|
||||
- Keep implementation tasks separate until proposal approved
|
||||
|
||||
Parallel operations encouraged:
|
||||
- Read multiple specs simultaneously
|
||||
- Check multiple pending changes at once
|
||||
- Batch related searches for efficiency
|
||||
|
||||
Progress communication:
|
||||
- "Exploring codebase to understand scope..."
|
||||
- "Creating proposal based on findings..."
|
||||
- "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
|
||||
|
||||
### Multi-Capability Changes
|
||||
Create ONE proposal that:
|
||||
- Lists all affected capabilities
|
||||
- Shows changes per capability
|
||||
- Has unified task list
|
||||
- Gets approved as a whole
|
||||
|
||||
### Outdated Specs
|
||||
If specs clearly outdated:
|
||||
1. Create proposal to update specs to match reality
|
||||
2. Implement new feature in separate proposal
|
||||
3. OR combine both in one proposal with clear sections
|
||||
|
||||
### Emergency Hotfixes
|
||||
For critical production issues:
|
||||
1. Announce: "This is an emergency fix"
|
||||
2. Implement fix immediately
|
||||
3. Create retroactive proposal
|
||||
4. Update specs after deployment
|
||||
5. Tag with [EMERGENCY] in archive
|
||||
|
||||
### Pure Refactoring
|
||||
No proposal needed for:
|
||||
- Code formatting/style
|
||||
- Internal refactoring (same API)
|
||||
- Performance optimization (same behavior)
|
||||
- Adding types to untyped code
|
||||
|
||||
Proposal REQUIRED for:
|
||||
- API changes (even if compatible)
|
||||
- Database schema changes
|
||||
- Architecture changes
|
||||
- New dependencies
|
||||
|
||||
### Observability Additions
|
||||
No proposal needed for:
|
||||
- Adding log statements
|
||||
- New metrics/traces
|
||||
- Debugging additions
|
||||
- Error tracking
|
||||
|
||||
Proposal REQUIRED if:
|
||||
- Changes log format/structure
|
||||
- Adds new monitoring service
|
||||
- Changes what's logged (privacy)
|
||||
|
||||
## Remember
|
||||
|
||||
- You are the process driver - automate documentation burden
|
||||
- Specs must always reflect deployed reality
|
||||
- Changes are proposed, not imposed
|
||||
- Impact analysis prevents surprises
|
||||
- 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,68 @@
|
||||
# Implementation Order and Dependencies
|
||||
|
||||
## Required Implementation Sequence
|
||||
|
||||
The following changes must be implemented in this specific order due to dependencies:
|
||||
|
||||
### Phase 1: Foundation
|
||||
**1. add-zod-validation** (No dependencies)
|
||||
- Creates all core schemas (RequirementSchema, ScenarioSchema, SpecSchema, ChangeSchema, DeltaSchema)
|
||||
- Implements markdown parser utilities
|
||||
- Implements validation infrastructure and rules
|
||||
- Establishes validation patterns used by all commands
|
||||
- Must be completed first
|
||||
|
||||
### Phase 2: Change Commands
|
||||
**2. add-change-commands** (Depends on: add-zod-validation)
|
||||
- Imports ChangeSchema and DeltaSchema from zod validation
|
||||
- Reuses markdown parsing utilities
|
||||
- Implements change command with built-in validation
|
||||
- Uses validation infrastructure for change validate subcommand
|
||||
- Cannot start until schemas and validation exist
|
||||
|
||||
### Phase 3: Spec Commands
|
||||
**3. add-spec-commands** (Depends on: add-zod-validation, add-change-commands)
|
||||
- Imports RequirementSchema, ScenarioSchema, SpecSchema from zod validation
|
||||
- Reuses markdown parsing utilities
|
||||
- Implements spec command with built-in validation
|
||||
- Uses validation infrastructure for spec validate subcommand
|
||||
- Builds on patterns established by change commands
|
||||
|
||||
## Dependency Graph
|
||||
```
|
||||
add-zod-validation
|
||||
↓
|
||||
add-change-commands
|
||||
↓
|
||||
add-spec-commands
|
||||
```
|
||||
|
||||
## Key Dependencies
|
||||
|
||||
### Shared Code Dependencies
|
||||
1. **Schemas**: All schemas created in add-zod-validation, used by both command implementations
|
||||
2. **Validation**: Infrastructure created in add-zod-validation, integrated into both commands
|
||||
3. **Parsers**: Markdown parsing utilities created in add-zod-validation, used by both commands
|
||||
|
||||
### File Dependencies
|
||||
- `src/core/schemas/*.schema.ts` (created by add-zod-validation) → imported by both commands
|
||||
- `src/core/validation/validator.ts` (created by add-zod-validation) → used by both commands
|
||||
- `src/core/parsers/markdown-parser.ts` (created by add-zod-validation) → used by both commands
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### For Developers
|
||||
1. Complete each phase fully before moving to the next
|
||||
2. Run tests after each phase to ensure stability
|
||||
3. The legacy `list` command remains functional throughout
|
||||
|
||||
### For CI/CD
|
||||
1. Each change can be validated independently
|
||||
2. Integration tests should run after each phase
|
||||
3. Full system tests required after Phase 3
|
||||
|
||||
### Parallel Work Opportunities
|
||||
Within each phase, the following can be done in parallel:
|
||||
- **Phase 1**: Schema design, validation rules, and parser implementation
|
||||
- **Phase 2**: Change command features and legacy compatibility work
|
||||
- **Phase 3**: Spec command features and final integration
|
||||
@@ -0,0 +1,136 @@
|
||||
# Add Artifact Regeneration Support
|
||||
|
||||
## Problem
|
||||
|
||||
Currently, there is **no way to regenerate artifacts** in the OPSX workflow:
|
||||
|
||||
- `/opsx:apply` just reads whatever's on disk
|
||||
- `/opsx:continue` only creates the NEXT artifact - won't touch existing ones
|
||||
|
||||
If you edit `design.md` after `tasks.md` exists, your only options are:
|
||||
1. Delete tasks.md manually, then run `/opsx:continue`
|
||||
2. Edit tasks.md manually
|
||||
|
||||
The documentation claims you can "update artifacts mid-flight and continue" but there's no mechanism that actually supports this.
|
||||
|
||||
## Proposed Solution
|
||||
|
||||
Two parts:
|
||||
|
||||
### Part 1: Staleness Detection
|
||||
Add artifact staleness detection to `/opsx:apply`:
|
||||
|
||||
1. **Track modification times**: When generating an artifact, record the mtime of its dependencies
|
||||
2. **Detect staleness**: When `/opsx:apply` runs, check if upstream artifacts (design.md, specs) have been modified since tasks.md was generated
|
||||
3. **Prompt user**: If stale, ask: "Design was modified after tasks were generated. Would you like to regenerate tasks with `/opsx:continue`?"
|
||||
|
||||
## User Experience
|
||||
|
||||
### Vision: Seamless Mid-Flight Correction
|
||||
|
||||
This is the workflow we want to enable (currently documented but not supported):
|
||||
|
||||
```
|
||||
You: /opsx:apply
|
||||
|
||||
AI: Working through tasks...
|
||||
✓ Task 1.1: Created caching layer
|
||||
✓ Task 1.2: Added cache invalidation
|
||||
|
||||
Working on 1.3: Implement TTL...
|
||||
I noticed the design assumes Redis, but your project uses
|
||||
in-memory caching. Should I update the design?
|
||||
|
||||
You: Yes, update it to use the existing cache module.
|
||||
|
||||
AI: Updated design.md to use CacheManager from src/cache/
|
||||
Updated tasks.md with revised implementation steps
|
||||
Continuing implementation...
|
||||
✓ Task 1.3: Implemented TTL using CacheManager
|
||||
...
|
||||
```
|
||||
|
||||
**No restart needed.** Just update the artifact and continue.
|
||||
|
||||
### Staleness Warning UX
|
||||
|
||||
When user manually edits an upstream artifact:
|
||||
|
||||
```
|
||||
$ /opsx:apply
|
||||
|
||||
⚠️ Detected changes to upstream artifacts:
|
||||
- design.md modified 5 minutes ago (after tasks.md was generated)
|
||||
|
||||
Options:
|
||||
1. Regenerate tasks (recommended)
|
||||
2. Continue anyway with current tasks
|
||||
3. Cancel
|
||||
|
||||
>
|
||||
```
|
||||
|
||||
### Part 2: Regeneration Capability
|
||||
|
||||
Add a way to regenerate specific artifacts:
|
||||
|
||||
```bash
|
||||
# Option A: Flag on continue
|
||||
/opsx:continue --regenerate tasks
|
||||
|
||||
# Option B: Separate command
|
||||
/opsx:regenerate tasks
|
||||
|
||||
# Option C: Interactive prompt when staleness detected
|
||||
/opsx:apply
|
||||
# "Design changed. Regenerate tasks? [y/N]"
|
||||
```
|
||||
|
||||
## Technical Approach
|
||||
|
||||
### Option A: Metadata File
|
||||
Store `.openspec-meta.json` in change directory:
|
||||
```json
|
||||
{
|
||||
"tasks.md": {
|
||||
"generated_at": "2025-01-24T10:00:00Z",
|
||||
"dependencies": {
|
||||
"design.md": "2025-01-24T09:55:00Z",
|
||||
"specs/feature/spec.md": "2025-01-24T09:50:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Option B: Frontmatter
|
||||
Add YAML frontmatter to generated artifacts:
|
||||
```markdown
|
||||
---
|
||||
generated_at: 2025-01-24T10:00:00Z
|
||||
depends_on:
|
||||
- design.md@2025-01-24T09:55:00Z
|
||||
---
|
||||
# Tasks
|
||||
...
|
||||
```
|
||||
|
||||
### Option C: Git-based
|
||||
Use git to detect if upstream files changed since downstream was last modified. No extra metadata needed but requires git.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Automatic regeneration (user should always choose)
|
||||
- Blocking apply entirely (just warn)
|
||||
- Tracking code file changes (only artifact dependencies)
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Should be implemented after `fix-midflight-update-docs` so docs are accurate first
|
||||
- Could be combined with that change if desired
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- User is warned when applying with stale artifacts
|
||||
- Clear path to regenerate if needed
|
||||
- No false positives (only warn when genuinely stale)
|
||||
- Documentation claims become actually true
|
||||
@@ -0,0 +1,20 @@
|
||||
## Why
|
||||
|
||||
Users and agents need a simple way to submit feedback about OpenSpec directly from the CLI. Currently there's no mechanism to collect user feedback, feature requests, or bug reports in a way that enables follow-up conversation. Using GitHub Issues allows us to track feedback, prevent spam via GitHub auth, and enables outreach to users.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add `openspec feedback <message>` CLI command
|
||||
- Leverage `gh` CLI for GitHub authentication and issue creation
|
||||
- Add `/feedback` skill for agent-assisted feedback with context enrichment
|
||||
- Ensure cross-platform compatibility (macOS, Linux, Windows)
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: New `cli-feedback` capability
|
||||
- Affected code:
|
||||
- `src/cli/index.ts` - Register feedback command
|
||||
- `src/commands/feedback.ts` - Command implementation using `gh` CLI
|
||||
- `src/core/templates/skill-templates.ts` - Feedback skill template
|
||||
- `src/core/completions/command-registry.ts` - Shell completions
|
||||
- External dependency: Requires `gh` CLI installed and authenticated
|
||||
@@ -0,0 +1,188 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Feedback command
|
||||
|
||||
The system SHALL provide an `openspec feedback` command that creates a GitHub Issue in the openspec repository using the `gh` CLI. The system SHALL use `execFileSync` with argument arrays to prevent shell injection vulnerabilities.
|
||||
|
||||
#### Scenario: Simple feedback submission
|
||||
|
||||
- **WHEN** user executes `openspec feedback "Great tool!"`
|
||||
- **THEN** the system executes `gh issue create` with title "Feedback: Great tool!"
|
||||
- **AND** the issue is created in the openspec repository
|
||||
- **AND** the issue has the `feedback` label
|
||||
- **AND** the system displays the created issue URL
|
||||
|
||||
#### Scenario: Safe command execution
|
||||
|
||||
- **WHEN** submitting feedback via `gh` CLI
|
||||
- **THEN** the system uses `execFileSync` with separate arguments array
|
||||
- **AND** user input is NOT passed through a shell
|
||||
- **AND** shell metacharacters (quotes, backticks, $(), etc.) are treated as literal text
|
||||
|
||||
#### Scenario: Feedback with body
|
||||
|
||||
- **WHEN** user executes `openspec feedback "Title here" --body "Detailed description..."`
|
||||
- **THEN** the system creates a GitHub Issue with the specified title
|
||||
- **AND** the issue body contains the detailed description
|
||||
- **AND** the issue body includes metadata (OpenSpec version, platform, timestamp)
|
||||
|
||||
### Requirement: GitHub CLI dependency
|
||||
|
||||
The system SHALL use `gh` CLI for automatic feedback submission when available, and provide a manual submission fallback when `gh` is not installed or not authenticated. The system SHALL use platform-appropriate commands to detect `gh` CLI availability.
|
||||
|
||||
#### Scenario: Missing gh CLI with fallback
|
||||
|
||||
- **WHEN** user runs `openspec feedback "message"`
|
||||
- **AND** `gh` CLI is not installed (not found in PATH)
|
||||
- **THEN** the system displays warning: "GitHub CLI not found. Manual submission required."
|
||||
- **AND** outputs structured feedback content with delimiters:
|
||||
- "--- FORMATTED FEEDBACK ---"
|
||||
- Title line
|
||||
- Labels line
|
||||
- Body content with metadata
|
||||
- "--- END FEEDBACK ---"
|
||||
- **AND** displays pre-filled GitHub issue URL for manual submission
|
||||
- **AND** exits with zero code (successful fallback)
|
||||
|
||||
#### Scenario: Cross-platform gh CLI detection on Unix
|
||||
|
||||
- **WHEN** system is running on macOS or Linux (platform is 'darwin' or 'linux')
|
||||
- **AND** checking if `gh` CLI is installed
|
||||
- **THEN** the system executes `which gh` command
|
||||
|
||||
#### Scenario: Cross-platform gh CLI detection on Windows
|
||||
|
||||
- **WHEN** system is running on Windows (platform is 'win32')
|
||||
- **AND** checking if `gh` CLI is installed
|
||||
- **THEN** the system executes `where gh` command
|
||||
|
||||
#### Scenario: Unauthenticated gh CLI with fallback
|
||||
|
||||
- **WHEN** user runs `openspec feedback "message"`
|
||||
- **AND** `gh` CLI is installed but not authenticated
|
||||
- **THEN** the system displays warning: "GitHub authentication required. Manual submission required."
|
||||
- **AND** outputs structured feedback content (same format as missing gh CLI scenario)
|
||||
- **AND** displays pre-filled GitHub issue URL for manual submission
|
||||
- **AND** displays authentication instructions: "To auto-submit in the future: gh auth login"
|
||||
- **AND** exits with zero code (successful fallback)
|
||||
|
||||
#### Scenario: Authenticated gh CLI
|
||||
|
||||
- **WHEN** user runs `openspec feedback "message"`
|
||||
- **AND** `gh auth status` returns success (authenticated)
|
||||
- **THEN** the system proceeds with feedback submission
|
||||
|
||||
### Requirement: Issue metadata
|
||||
|
||||
The system SHALL include relevant metadata in the GitHub Issue body.
|
||||
|
||||
#### Scenario: Standard metadata
|
||||
|
||||
- **WHEN** creating a GitHub Issue for feedback
|
||||
- **THEN** the issue body includes:
|
||||
- OpenSpec CLI version
|
||||
- Platform (darwin, linux, win32)
|
||||
- Submission timestamp
|
||||
- Separator line: "---\nSubmitted via OpenSpec CLI"
|
||||
|
||||
#### Scenario: Windows platform metadata
|
||||
|
||||
- **WHEN** creating a GitHub Issue for feedback on Windows
|
||||
- **THEN** the issue body includes "Platform: win32"
|
||||
- **AND** all platform detection uses Node.js `os.platform()` API
|
||||
|
||||
#### Scenario: No sensitive metadata
|
||||
|
||||
- **WHEN** creating a GitHub Issue for feedback
|
||||
- **THEN** the issue body does NOT include:
|
||||
- File paths from user's system
|
||||
- Project names or directory names
|
||||
- Environment variables
|
||||
- IP addresses
|
||||
|
||||
### Requirement: Feedback always works
|
||||
|
||||
The system SHALL allow feedback submission regardless of telemetry settings.
|
||||
|
||||
#### Scenario: Feedback with telemetry disabled
|
||||
|
||||
- **WHEN** user has disabled telemetry via `OPENSPEC_TELEMETRY=0`
|
||||
- **AND** user runs `openspec feedback "message"`
|
||||
- **THEN** the feedback is still submitted via `gh` CLI
|
||||
- **AND** telemetry events are not sent
|
||||
|
||||
#### Scenario: Feedback in CI environment
|
||||
|
||||
- **WHEN** `CI=true` is set in the environment
|
||||
- **AND** user runs `openspec feedback "message"`
|
||||
- **THEN** the feedback submission proceeds normally (if `gh` is available and authenticated)
|
||||
|
||||
### Requirement: Error handling
|
||||
|
||||
The system SHALL handle feedback submission errors gracefully.
|
||||
|
||||
#### Scenario: gh CLI execution failure
|
||||
|
||||
- **WHEN** `gh issue create` command fails
|
||||
- **THEN** the system displays the error output from `gh` CLI
|
||||
- **AND** exits with the same exit code as `gh`
|
||||
|
||||
#### Scenario: Network failure
|
||||
|
||||
- **WHEN** `gh` CLI reports network connectivity issues
|
||||
- **THEN** the system displays the error message from `gh`
|
||||
- **AND** suggests checking network connectivity
|
||||
- **AND** exits with non-zero code
|
||||
|
||||
### Requirement: Feedback skill for agents
|
||||
|
||||
The system SHALL provide a `/feedback` skill that guides agents through collecting and submitting user feedback.
|
||||
|
||||
#### Scenario: Agent-initiated feedback
|
||||
|
||||
- **WHEN** user invokes `/feedback` in an agent conversation
|
||||
- **THEN** the agent gathers context from the conversation
|
||||
- **AND** drafts a feedback issue with enriched content
|
||||
- **AND** anonymizes sensitive information
|
||||
- **AND** presents the draft to the user for approval
|
||||
- **AND** submits via `openspec feedback` command on user confirmation
|
||||
|
||||
#### Scenario: Context enrichment
|
||||
|
||||
- **WHEN** agent drafts feedback
|
||||
- **THEN** the agent includes relevant context such as:
|
||||
- What task was being performed
|
||||
- What worked well or poorly
|
||||
- Specific friction points or praise
|
||||
|
||||
#### Scenario: Anonymization
|
||||
|
||||
- **WHEN** agent drafts feedback
|
||||
- **THEN** the agent removes or replaces:
|
||||
- File paths with `<path>` or generic descriptions
|
||||
- API keys, tokens, secrets with `<redacted>`
|
||||
- Company/organization names with `<company>`
|
||||
- Personal names with `<user>`
|
||||
- Specific URLs with `<url>` unless public/relevant
|
||||
|
||||
#### Scenario: User confirmation required
|
||||
|
||||
- **WHEN** agent has drafted feedback
|
||||
- **THEN** the agent MUST show the complete draft to the user
|
||||
- **AND** ask for explicit approval before submitting
|
||||
- **AND** allow the user to request modifications
|
||||
- **AND** only submit after user confirms
|
||||
|
||||
### Requirement: Shell completions
|
||||
|
||||
The system SHALL provide shell completions for the feedback command.
|
||||
|
||||
#### Scenario: Command completion
|
||||
|
||||
- **WHEN** user types `openspec fee<TAB>`
|
||||
- **THEN** the shell completes to `openspec feedback`
|
||||
|
||||
#### Scenario: Flag completion
|
||||
|
||||
- **WHEN** user types `openspec feedback "msg" --<TAB>`
|
||||
- **THEN** the shell suggests available flags (`--body`)
|
||||
@@ -0,0 +1,30 @@
|
||||
## 1. Feedback Command
|
||||
|
||||
- [x] 1.1 Create `src/commands/feedback.ts` with command implementation
|
||||
- [x] 1.2 Check `gh` CLI availability using platform-appropriate command (`which` on Unix/macOS, `where` on Windows)
|
||||
- [x] 1.3 Check GitHub auth status with `gh auth status`
|
||||
- [x] 1.4 Execute `gh issue create` with formatted title and body using `execFileSync` to prevent shell injection
|
||||
- [x] 1.5 Display issue URL returned by `gh` CLI
|
||||
- [x] 1.6 Register `feedback <message>` command in `src/cli/index.ts`
|
||||
- [x] 1.7 Ensure cross-platform compatibility (macOS, Linux, Windows)
|
||||
|
||||
## 2. Shell Completions
|
||||
|
||||
- [x] 2.1 Add `feedback` command to command registry
|
||||
- [x] 2.2 Regenerate completion scripts for all shells
|
||||
|
||||
## 3. Feedback Skill
|
||||
|
||||
- [x] 3.1 Create feedback skill template in `skill-templates.ts`
|
||||
- [x] 3.2 Document context gathering workflow
|
||||
- [x] 3.3 Document anonymization rules
|
||||
- [x] 3.4 Document user confirmation flow
|
||||
|
||||
## 4. Testing
|
||||
|
||||
- [x] 4.1 Add unit tests for feedback command (mock `gh` subprocess calls)
|
||||
- [x] 4.2 Add integration test for full feedback flow with mocked `gh` CLI
|
||||
- [x] 4.3 Test error handling for missing `gh` CLI
|
||||
- [x] 4.4 Test error handling for unauthenticated `gh` session
|
||||
- [x] 4.5 Test cross-platform `gh` CLI detection (verify `which` on Unix, `where` on Windows)
|
||||
- [x] 4.6 Test platform metadata includes correct value for Windows (win32)
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-01-24
|
||||
@@ -0,0 +1,115 @@
|
||||
## Context
|
||||
|
||||
OpenSpec has a complete skill and slash command generation system. Skills are defined in `src/core/templates/skill-templates.ts` as functions that return `SkillTemplate` objects (for Agent Skills) and `CommandTemplate` objects (for slash commands). These are registered in `src/core/shared/skill-generation.ts` and generated during `openspec init` and `openspec update`.
|
||||
|
||||
Existing skills follow a consistent pattern:
|
||||
- `getXxxSkillTemplate()` returns the skill with name, description, instructions
|
||||
- `getOpsxXxxCommandTemplate()` returns the slash command with name, description, category, tags, content
|
||||
- Both are registered in their respective arrays in `skill-generation.ts`
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Add `/opsx:onboard` skill that teaches the OpenSpec workflow through guided practice
|
||||
- Follow existing patterns for skill/command template generation
|
||||
- Provide comprehensive narration that explains each step
|
||||
- Include codebase analysis to suggest real, appropriately-scoped tasks
|
||||
|
||||
**Non-Goals:**
|
||||
- Creating a separate "demo mode" or simulated workflow (we do real work)
|
||||
- Adding new CLI commands (this is purely agent instructions)
|
||||
- Modifying the init/update flow (just adding to the template arrays)
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Single Monolithic Skill
|
||||
|
||||
The onboard skill will be a single comprehensive instruction set rather than composing existing skills with flags.
|
||||
|
||||
**Rationale:**
|
||||
- Slash commands don't support flags (they're just prompts)
|
||||
- A monolithic skill gives complete control over narration and pacing
|
||||
- Easier to maintain a single cohesive experience
|
||||
- Users learn the real commands by seeing them mentioned in narration
|
||||
|
||||
### Decision 2: Codebase Analysis Patterns
|
||||
|
||||
The skill instructions will direct the agent to look for specific patterns when suggesting starter tasks:
|
||||
|
||||
1. TODO/FIXME comments in code
|
||||
2. Missing error handling (`catch` blocks that swallow errors, no try-catch around risky operations)
|
||||
3. Functions without tests (cross-reference src/ with test files)
|
||||
4. Type: `any` in TypeScript files
|
||||
5. Console.log statements in non-debug code
|
||||
6. Missing input validation on user-facing inputs
|
||||
7. Recent git commits (for context on what user is working on)
|
||||
|
||||
**Rationale:** These are universally applicable, easy to detect, and produce well-scoped tasks.
|
||||
|
||||
### Decision 3: Narration Integration Style
|
||||
|
||||
Each phase will follow a pattern:
|
||||
1. **EXPLAIN** what we're about to do and why (1-2 sentences)
|
||||
2. **DO** the action (run command, create artifact)
|
||||
3. **SHOW** what happened
|
||||
4. **PAUSE** at key transitions (not every step)
|
||||
|
||||
Pauses occur at:
|
||||
- After task selection (before creating change)
|
||||
- After drafting proposal (before saving)
|
||||
- After tasks are generated (before implementation)
|
||||
- After archive (final recap)
|
||||
|
||||
**Rationale:** Too many pauses becomes tedious. Too few loses the teaching opportunity. These are the natural "chapter breaks."
|
||||
|
||||
### Decision 4: Scope Guardrail Approach
|
||||
|
||||
When user selects a task that's too large, the skill will:
|
||||
1. Acknowledge the task is valuable
|
||||
2. Explain why smaller is better for first time
|
||||
3. Suggest a smaller slice or alternative
|
||||
4. Let user override if they insist
|
||||
|
||||
**Rationale:** Soft guardrails teach without frustrating. Users learn scope calibration as part of the experience.
|
||||
|
||||
### Decision 5: Template Structure
|
||||
|
||||
The skill template will be ~400-600 lines of instruction text, structured as:
|
||||
|
||||
```
|
||||
- Preflight checks (init status)
|
||||
- Phase 1: Welcome & Setup
|
||||
- Phase 2: Task Selection (with codebase analysis instructions)
|
||||
- Phase 3: Explore Demo (brief)
|
||||
- Phase 4: Change Creation
|
||||
- Phase 5: Proposal
|
||||
- Phase 6: Specs
|
||||
- Phase 7: Design
|
||||
- Phase 8: Tasks
|
||||
- Phase 9: Apply (Implementation)
|
||||
- Phase 10: Archive
|
||||
- Phase 11: Recap & Next Steps
|
||||
- Edge cases & graceful exits
|
||||
```
|
||||
|
||||
The command template will be identical to the skill template (same content, different wrapper).
|
||||
|
||||
**Rationale:** Following the established pattern where skill and command share the same core instructions.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
**Risk: Instruction length**
|
||||
The skill will be significantly longer than existing skills (~500 lines vs ~100-200).
|
||||
→ Mitigation: This is acceptable since onboarding is inherently comprehensive. Token cost is one-time per session.
|
||||
|
||||
**Risk: Codebase analysis may find nothing**
|
||||
Some codebases (new projects, very clean code) may not have obvious improvement opportunities.
|
||||
→ Mitigation: Fall back to asking user what they want to build. Include "add a new feature" as an option.
|
||||
|
||||
**Risk: Task suggestions may be inappropriate**
|
||||
Agent might suggest tasks that touch sensitive code or have hidden complexity.
|
||||
→ Mitigation: User always chooses; agent just suggests. Scope estimates help set expectations.
|
||||
|
||||
**Risk: User abandons mid-way**
|
||||
Onboarding takes ~15 minutes; users may not complete it.
|
||||
→ Mitigation: Graceful exit handling - note the change is saved, explain how to continue later.
|
||||
@@ -0,0 +1,27 @@
|
||||
## Why
|
||||
|
||||
Users who run `openspec init` are left with files but no clear path to actually using the system. There's a gap between "I have OpenSpec set up" and "I understand the workflow." An onboarding skill would guide users through their first complete change cycle on a real task in their codebase, teaching the workflow by doing it.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add new `/opsx:onboard` skill that guides users through their first OpenSpec change
|
||||
- Add corresponding slash command template for editor integrations
|
||||
- The skill will:
|
||||
- Analyze the user's codebase to suggest appropriately-scoped starter tasks
|
||||
- Walk through the full workflow (explore → new → proposal → specs → design → tasks → apply → archive)
|
||||
- Provide narration explaining each step as it happens
|
||||
- Result in a real, implemented change in the user's codebase
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `opsx-onboard-skill`: The onboarding skill that guides users through their first complete OpenSpec workflow cycle with narration and codebase-aware task suggestions
|
||||
|
||||
### Modified Capabilities
|
||||
<!-- No existing specs are being modified - this is purely additive -->
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/templates/skill-templates.ts`: Add `getOnboardSkillTemplate()` and `getOpsxOnboardCommandTemplate()` functions
|
||||
- `src/core/shared/skill-generation.ts`: Register the new skill and command templates in `getSkillTemplates()` and `getCommandTemplates()`
|
||||
- Users running `openspec init` or `openspec update` will get the new skill/command files generated
|
||||
@@ -0,0 +1,162 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: OPSX Onboard Skill
|
||||
|
||||
The system SHALL provide an `/opsx:onboard` skill that guides users through their first complete OpenSpec workflow cycle with narration and real codebase work.
|
||||
|
||||
#### Scenario: Skill invocation
|
||||
|
||||
- **WHEN** user invokes `/opsx:onboard`
|
||||
- **THEN** agent checks if OpenSpec is initialized
|
||||
- **AND** if not initialized, prompts user to run `openspec init` first
|
||||
- **AND** if initialized, proceeds with onboarding flow
|
||||
|
||||
#### Scenario: Welcome and expectations
|
||||
|
||||
- **WHEN** onboarding begins
|
||||
- **THEN** agent displays welcome message explaining what will happen
|
||||
- **AND** sets expectation of ~15 minute duration
|
||||
- **AND** explains the workflow phases: explore → new → artifacts → apply → archive
|
||||
|
||||
### Requirement: Codebase Analysis for Task Suggestions
|
||||
|
||||
The skill SHALL analyze the user's codebase to suggest appropriately-scoped starter tasks.
|
||||
|
||||
#### Scenario: Codebase scanning
|
||||
|
||||
- **WHEN** onboarding reaches task selection phase
|
||||
- **THEN** agent scans codebase for small improvement opportunities
|
||||
- **AND** looks for: TODO/FIXME comments, missing error handling, functions without tests, outdated dependencies, type: any in TypeScript, console.log in production code, missing input validation
|
||||
- **AND** checks recent git commits for context on current work
|
||||
|
||||
#### Scenario: Task suggestion presentation
|
||||
|
||||
- **WHEN** agent has analyzed codebase
|
||||
- **THEN** agent presents 3-4 specific task suggestions with scope estimates
|
||||
- **AND** each suggestion includes: task description, estimated scope (files/lines), why it's a good starter
|
||||
- **AND** offers option for user to specify their own task
|
||||
|
||||
#### Scenario: Scope guardrail
|
||||
|
||||
- **WHEN** user selects or describes a task that is too large
|
||||
- **THEN** agent gently redirects toward smaller scope
|
||||
- **AND** suggests breaking down or deferring the large task
|
||||
- **AND** offers appropriately-sized alternatives
|
||||
|
||||
### Requirement: Explore Phase Demo
|
||||
|
||||
The skill SHALL briefly demonstrate explore mode before creating a change.
|
||||
|
||||
#### Scenario: Brief explore demonstration
|
||||
|
||||
- **WHEN** task is selected
|
||||
- **THEN** agent briefly demonstrates `/opsx:explore` by investigating relevant code
|
||||
- **AND** explains explore mode is for thinking before doing
|
||||
- **AND** keeps this phase short (not a full exploration session)
|
||||
- **AND** transitions to change creation
|
||||
|
||||
### Requirement: Guided Artifact Creation
|
||||
|
||||
The skill SHALL guide users through each artifact with narration explaining the purpose.
|
||||
|
||||
#### Scenario: Change creation with narration
|
||||
|
||||
- **WHEN** creating the change directory
|
||||
- **THEN** agent runs `openspec new change "<name>"` with derived kebab-case name
|
||||
- **AND** explains what a "change" is (container for thinking and planning)
|
||||
- **AND** shows the folder structure that was created
|
||||
- **AND** pauses for user acknowledgment before proceeding
|
||||
|
||||
#### Scenario: Proposal creation with narration
|
||||
|
||||
- **WHEN** creating proposal.md
|
||||
- **THEN** agent explains proposals capture WHY we're making this change
|
||||
- **AND** drafts proposal based on selected task
|
||||
- **AND** shows draft to user for approval before saving
|
||||
- **AND** explains the sections (Why, What Changes, Capabilities, Impact)
|
||||
|
||||
#### Scenario: Specs creation with narration
|
||||
|
||||
- **WHEN** creating spec files
|
||||
- **THEN** agent explains specs define WHAT we're building in detail
|
||||
- **AND** explains the requirement/scenario format
|
||||
- **AND** creates spec file(s) based on proposal capabilities
|
||||
- **AND** notes that specs become documentation that stays in sync
|
||||
|
||||
#### Scenario: Design creation with narration
|
||||
|
||||
- **WHEN** creating design.md
|
||||
- **THEN** agent explains design captures HOW we'll build it
|
||||
- **AND** notes this is where technical decisions and tradeoffs live
|
||||
- **AND** for small changes, acknowledges design may be brief
|
||||
- **AND** creates design based on proposal and specs
|
||||
|
||||
#### Scenario: Tasks creation with narration
|
||||
|
||||
- **WHEN** creating tasks.md
|
||||
- **THEN** agent explains tasks break work into checkboxes
|
||||
- **AND** explains these drive the apply phase
|
||||
- **AND** generates task list from design and specs
|
||||
- **AND** shows tasks and asks if ready to implement
|
||||
|
||||
### Requirement: Guided Implementation
|
||||
|
||||
The skill SHALL implement tasks with narration connecting back to artifacts.
|
||||
|
||||
#### Scenario: Implementation with narration
|
||||
|
||||
- **WHEN** implementing tasks
|
||||
- **THEN** agent announces each task before working on it
|
||||
- **AND** implements the change in the codebase
|
||||
- **AND** occasionally references how specs/design informed decisions
|
||||
- **AND** marks each task complete as it finishes
|
||||
- **AND** keeps narration light (not over-explaining)
|
||||
|
||||
#### Scenario: Implementation completion
|
||||
|
||||
- **WHEN** all tasks are complete
|
||||
- **THEN** agent announces completion
|
||||
- **AND** summarizes what was done
|
||||
- **AND** transitions to archive phase
|
||||
|
||||
### Requirement: Archive with Explanation
|
||||
|
||||
The skill SHALL archive the completed change and explain what happened.
|
||||
|
||||
#### Scenario: Archive with narration
|
||||
|
||||
- **WHEN** archiving the change
|
||||
- **THEN** agent explains archive moves change to dated folder
|
||||
- **AND** runs archive process
|
||||
- **AND** shows where archived change lives
|
||||
- **AND** explains the long-term value (finding decisions later)
|
||||
|
||||
### Requirement: Recap and Next Steps
|
||||
|
||||
The skill SHALL conclude with a recap and command reference.
|
||||
|
||||
#### Scenario: Final recap
|
||||
|
||||
- **WHEN** onboarding is complete
|
||||
- **THEN** agent summarizes the workflow phases completed
|
||||
- **AND** emphasizes this rhythm works for any size change
|
||||
- **AND** provides command reference table (/opsx:explore, /opsx:new, /opsx:ff, /opsx:continue, /opsx:apply, /opsx:verify, /opsx:archive)
|
||||
- **AND** suggests next actions (try /opsx:new or /opsx:ff on something)
|
||||
|
||||
### Requirement: Graceful Exit Handling
|
||||
|
||||
The skill SHALL handle users who want to stop mid-way.
|
||||
|
||||
#### Scenario: User wants to stop
|
||||
|
||||
- **WHEN** user indicates they want to stop during onboarding
|
||||
- **THEN** agent acknowledges gracefully
|
||||
- **AND** notes that the in-progress change is saved
|
||||
- **AND** explains how to continue later with `/opsx:continue <name>`
|
||||
- **AND** exits without pressure
|
||||
|
||||
#### Scenario: User wants quick reference only
|
||||
|
||||
- **WHEN** user says they just want to see the commands
|
||||
- **THEN** agent provides command cheat sheet
|
||||
- **AND** exits gracefully with encouragement to try `/opsx:new`
|
||||
@@ -0,0 +1,21 @@
|
||||
## 1. Add Skill Template
|
||||
|
||||
- [x] 1.1 Add `getOnboardSkillTemplate()` function to `src/core/templates/skill-templates.ts` with full onboarding instruction text covering all phases (preflight, welcome, task selection, explore demo, change creation, proposal, specs, design, tasks, apply, archive, recap)
|
||||
- [x] 1.2 Include codebase analysis instructions for suggesting starter tasks (TODO/FIXME, missing error handling, missing tests, type:any, console.log, missing validation)
|
||||
- [x] 1.3 Include narration pattern instructions (EXPLAIN → DO → SHOW → PAUSE at key transitions)
|
||||
- [x] 1.4 Include scope guardrail instructions for redirecting users away from overly large tasks
|
||||
- [x] 1.5 Include graceful exit handling instructions (user stops mid-way, user just wants command reference)
|
||||
|
||||
## 2. Add Command Template
|
||||
|
||||
- [x] 2.1 Add `getOpsxOnboardCommandTemplate()` function to `src/core/templates/skill-templates.ts` returning CommandTemplate with same instruction content as skill
|
||||
|
||||
## 3. Register Templates
|
||||
|
||||
- [x] 3.1 Add onboard skill to `getSkillTemplates()` array in `src/core/shared/skill-generation.ts` with dirName `openspec-onboard`
|
||||
- [x] 3.2 Add onboard command to `getCommandTemplates()` array in `src/core/shared/skill-generation.ts` with id `onboard`
|
||||
|
||||
## 4. Verify
|
||||
|
||||
- [x] 4.1 Run `pnpm run build` to ensure TypeScript compiles
|
||||
- [x] 4.2 Test skill generation by running `openspec init` in a test directory and verifying onboard skill/command files are created
|
||||
@@ -1,19 +0,0 @@
|
||||
# Add Status Command to OpenSpec CLI
|
||||
|
||||
## Why
|
||||
|
||||
Developers need to know which changes have all tasks completed and are ready to archive.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add `openspec status` command that scans the changes/ directory
|
||||
- Parse each tasks.md file to count `[x]` (complete) and `[ ]` (incomplete) tasks
|
||||
- Display each change with its completion status (e.g., "auth-feature: 5/5" or "auth-feature: ✓")
|
||||
- Skip the archive/ subdirectory
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: New capability `cli-status` will be added
|
||||
- Affected code:
|
||||
- `src/cli/index.ts` - Add status command
|
||||
- `src/core/status.ts` - New file with simple scanning and parsing logic (~50 lines)
|
||||
@@ -1,58 +0,0 @@
|
||||
# CLI Status Command Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
The status command shows which OpenSpec changes are ready to archive by displaying task completion status for each change.
|
||||
|
||||
## Command Interface
|
||||
|
||||
```bash
|
||||
# Show status of all changes
|
||||
openspec status
|
||||
```
|
||||
|
||||
## Behavior
|
||||
|
||||
WHEN the status command runs:
|
||||
1. Scan the `openspec/changes/` directory
|
||||
2. Skip the `archive/` subdirectory
|
||||
3. For each change directory with a `tasks.md` file:
|
||||
- Count tasks marked with `[x]` (case-insensitive)
|
||||
- Count tasks marked with `[ ]`
|
||||
- Display the change name and completion status
|
||||
|
||||
## Output Format
|
||||
|
||||
```
|
||||
add-auth-feature: 15/15
|
||||
fix-payment-bug: 8/8
|
||||
refactor-api: 3/10
|
||||
update-docs: 0/5
|
||||
```
|
||||
|
||||
Or with checkmark for fully complete:
|
||||
|
||||
```
|
||||
add-auth-feature: ✓
|
||||
fix-payment-bug: ✓
|
||||
refactor-api: 3/10
|
||||
update-docs: 0/5
|
||||
```
|
||||
|
||||
## Task Detection
|
||||
|
||||
The command recognizes these patterns as tasks:
|
||||
- `- [ ]` Incomplete task
|
||||
- `- [x]` Complete task (lowercase)
|
||||
- `- [X]` Complete task (uppercase)
|
||||
|
||||
## Error Handling
|
||||
|
||||
- If no `tasks.md` exists, skip that change
|
||||
- If `tasks.md` is empty or has no tasks, skip that change
|
||||
- Continue scanning even if individual files have errors
|
||||
|
||||
## Exit Codes
|
||||
|
||||
- `0`: Success - status displayed
|
||||
- `1`: Error - unable to scan changes directory
|
||||
@@ -1,8 +0,0 @@
|
||||
# Implementation Tasks for Status Command
|
||||
|
||||
## Core Implementation
|
||||
- [ ] Add status command to `src/cli/index.ts`
|
||||
- [ ] Create `src/core/status.ts` with directory scanning logic
|
||||
- [ ] Parse tasks.md files to count `[x]` and `[ ]` patterns
|
||||
- [ ] Display each change with completion status (name: complete/total)
|
||||
- [ ] Skip the archive/ subdirectory when scanning
|
||||
@@ -0,0 +1,96 @@
|
||||
# Design: Add /opsx:verify Skill
|
||||
|
||||
## Architecture Decision: Dynamic Generation via Setup Command
|
||||
|
||||
### Context
|
||||
|
||||
All existing opsx experimental skills (explore, new, continue, apply, ff, sync, archive) are dynamically generated when users run `openspec artifact-experimental-setup`. They are not manually created files checked into the repository.
|
||||
|
||||
### Decision
|
||||
|
||||
**Integrate verify into the existing artifact-experimental-setup system rather than creating static skill files.**
|
||||
|
||||
### Rationale
|
||||
|
||||
1. **Consistency**: All 7 existing opsx skills follow this pattern. Adding verify as the 8th skill should follow the same architecture.
|
||||
|
||||
2. **Maintainability**: Template functions in `skill-templates.ts` are the single source of truth. Changes to skill definitions automatically propagate to all users when they re-run setup.
|
||||
|
||||
3. **Distribution**: Users get the verify skill automatically when running `openspec artifact-experimental-setup`, just like all other opsx skills. No special installation steps needed.
|
||||
|
||||
4. **Versioning**: Skills are generated from the installed npm package version, ensuring consistency between CLI version and skill behavior.
|
||||
|
||||
### Implementation Approach
|
||||
|
||||
#### 1. Template Functions
|
||||
|
||||
Add two template functions to `src/core/templates/skill-templates.ts`:
|
||||
|
||||
```typescript
|
||||
export function getVerifyChangeSkillTemplate(): SkillTemplate
|
||||
export function getOpsxVerifyCommandTemplate(): CommandTemplate
|
||||
```
|
||||
|
||||
These return the skill definition (for Agent Skills) and slash command definition (for explicit invocation).
|
||||
|
||||
#### 2. Setup Integration
|
||||
|
||||
Update `artifactExperimentalSetupCommand()` in `src/commands/artifact-workflow.ts`:
|
||||
|
||||
- Import both template functions
|
||||
- Add verify to the `skills` array (position 8)
|
||||
- Add verify to the `commands` array (position 8)
|
||||
- Update help text to list `/opsx:verify`
|
||||
|
||||
#### 3. Generated Artifacts
|
||||
|
||||
When users run `openspec artifact-experimental-setup`, the command creates:
|
||||
|
||||
- `.claude/skills/openspec-verify-change/SKILL.md` - Agent Skills format
|
||||
- `.claude/commands/opsx/verify.md` - Slash command format
|
||||
|
||||
Both are generated from the template functions, with YAML frontmatter automatically added.
|
||||
|
||||
### Alternatives Considered
|
||||
|
||||
**Alternative 1: Static skill files in repository**
|
||||
|
||||
Create `.claude/skills/openspec-verify-change/SKILL.md` as a static file in the OpenSpec repository.
|
||||
|
||||
**Rejected because:**
|
||||
- Inconsistent with all other opsx skills
|
||||
- Requires users to manually copy/update files
|
||||
- Versioning becomes complicated (repo version vs installed package version)
|
||||
- Breaks the established pattern
|
||||
|
||||
**Alternative 2: Separate verify setup command**
|
||||
|
||||
Add `openspec setup-verify` as a separate command.
|
||||
|
||||
**Rejected because:**
|
||||
- Fragments the setup experience
|
||||
- Users would need to run multiple commands
|
||||
- Doesn't scale if we add more skills in the future
|
||||
- Goes against the "setup once, get everything" philosophy
|
||||
|
||||
### Trade-offs
|
||||
|
||||
**Advantages:**
|
||||
- Consistent with existing architecture
|
||||
- Zero additional setup burden for users
|
||||
- Easy to update and maintain
|
||||
- Automatic version compatibility
|
||||
|
||||
**Disadvantages:**
|
||||
- Slightly more complex initial implementation (template functions + integration)
|
||||
- Requires understanding the setup system (but that's already documented)
|
||||
|
||||
### Verification
|
||||
|
||||
The implementation correctly follows this design if:
|
||||
|
||||
1. Both template functions exist in `skill-templates.ts`
|
||||
2. Verify appears in both skills and commands arrays in `artifact-workflow.ts`
|
||||
3. Help text mentions `/opsx:verify`
|
||||
4. Running `openspec artifact-experimental-setup` generates both skill and command files
|
||||
5. Build succeeds with no TypeScript errors
|
||||
@@ -0,0 +1,48 @@
|
||||
# Change: Add /opsx:verify Skill
|
||||
|
||||
## Why
|
||||
|
||||
Users need a way to validate that their implementation actually matches what was requested before archiving a change. Currently, there's no systematic way to check:
|
||||
- Whether all tasks are truly complete
|
||||
- Whether the implementation covers all spec requirements and scenarios
|
||||
- Whether the implementation follows the design decisions
|
||||
- Whether the code is coherent and makes sense
|
||||
|
||||
A user requested: "Can we get a :verify that will ensure that the implementation matches what was requested?"
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add `getVerifyChangeSkillTemplate()` function to `skill-templates.ts`
|
||||
- Add `getOpsxVerifyCommandTemplate()` function to `skill-templates.ts`
|
||||
- Integrate verify skill into `artifactExperimentalSetupCommand` in `artifact-workflow.ts`
|
||||
- Add verify to the skills and commands arrays in the setup command
|
||||
- Update help text to include `/opsx:verify` in the list of available commands
|
||||
- Create `opsx-verify-skill` capability spec
|
||||
|
||||
## Verification Dimensions
|
||||
|
||||
The skill verifies across three dimensions:
|
||||
|
||||
1. **Completeness** - Are all tasks done? Are all specs addressed?
|
||||
2. **Correctness** - Does the implementation match specs? Are scenarios covered?
|
||||
3. **Coherence** - Does the implementation make sense? Does it follow design.md?
|
||||
|
||||
## Output Format
|
||||
|
||||
Produces a prioritized report with:
|
||||
- Summary scorecard (tasks, specs, design adherence)
|
||||
- Critical issues first (must fix before archive)
|
||||
- Warnings second (should fix)
|
||||
- Suggestions third (nice to have)
|
||||
- Actionable fix recommendations for each issue
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: New `opsx-verify-skill` spec
|
||||
- Affected code:
|
||||
- `src/core/templates/skill-templates.ts` - Added 2 new template functions
|
||||
- `src/commands/artifact-workflow.ts` - Integrated verify into experimental setup
|
||||
- Generated artifacts: When users run `openspec artifact-experimental-setup`:
|
||||
- Creates `.claude/skills/openspec-verify-change/SKILL.md`
|
||||
- Creates `.claude/commands/opsx/verify.md`
|
||||
- Related skills: Works alongside `/opsx:apply` and before `/opsx:archive`
|
||||
@@ -0,0 +1,190 @@
|
||||
# opsx-verify-skill Specification
|
||||
|
||||
## Purpose
|
||||
Defines the agent skill for verifying that implementation matches change artifacts (specs, tasks, design).
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Verify Skill Invocation
|
||||
The system SHALL provide an `/opsx:verify` skill that validates implementation against change artifacts.
|
||||
|
||||
#### Scenario: Verify with change name provided
|
||||
- **WHEN** agent executes `/opsx:verify <change-name>`
|
||||
- **THEN** the agent verifies implementation for that specific change
|
||||
- **AND** produces a verification report
|
||||
|
||||
#### Scenario: Verify without change name
|
||||
- **WHEN** agent executes `/opsx:verify` without a change name
|
||||
- **THEN** the agent prompts user to select from available changes
|
||||
- **AND** shows only changes that have implementation tasks
|
||||
|
||||
#### Scenario: Change has no tasks
|
||||
- **WHEN** selected change has no tasks.md or tasks are empty
|
||||
- **THEN** the agent reports "No tasks to verify"
|
||||
- **AND** suggests running `/opsx:continue` to create tasks
|
||||
|
||||
### Requirement: Completeness Verification
|
||||
The agent SHALL verify that all required work has been completed.
|
||||
|
||||
#### Scenario: Task completion check
|
||||
- **WHEN** verifying completeness
|
||||
- **THEN** the agent reads tasks.md
|
||||
- **AND** counts tasks marked `- [x]` (complete) vs `- [ ]` (incomplete)
|
||||
- **AND** reports completion status with specific incomplete tasks listed
|
||||
|
||||
#### Scenario: Spec coverage check
|
||||
- **WHEN** verifying completeness
|
||||
- **AND** delta specs exist in `openspec/changes/<name>/specs/`
|
||||
- **THEN** the agent extracts all requirements from delta specs
|
||||
- **AND** searches codebase for implementation of each requirement
|
||||
- **AND** reports which requirements appear to have implementation vs which are missing
|
||||
|
||||
#### Scenario: All tasks complete
|
||||
- **WHEN** all tasks are marked complete
|
||||
- **THEN** report "Tasks: N/N complete"
|
||||
- **AND** mark completeness dimension as passed
|
||||
|
||||
#### Scenario: Incomplete tasks found
|
||||
- **WHEN** some tasks are incomplete
|
||||
- **THEN** report "Tasks: X/N complete"
|
||||
- **AND** list each incomplete task
|
||||
- **AND** mark as CRITICAL issue
|
||||
- **AND** suggest: "Complete remaining tasks or mark as done if already implemented"
|
||||
|
||||
### Requirement: Correctness Verification
|
||||
The agent SHALL verify that implementation matches the specifications.
|
||||
|
||||
#### Scenario: Requirement implementation mapping
|
||||
- **WHEN** verifying correctness
|
||||
- **THEN** for each requirement in delta specs:
|
||||
- Search codebase for implementation
|
||||
- Identify relevant files and line numbers
|
||||
- Assess whether implementation satisfies the requirement
|
||||
|
||||
#### Scenario: Scenario coverage check
|
||||
- **WHEN** verifying correctness
|
||||
- **THEN** for each scenario in delta specs:
|
||||
- Check if the scenario's conditions are handled in code
|
||||
- Check if tests exist that cover the scenario
|
||||
- Report coverage status
|
||||
|
||||
#### Scenario: Implementation matches spec
|
||||
- **WHEN** implementation appears to satisfy a requirement
|
||||
- **THEN** report which files/lines implement it
|
||||
- **AND** mark requirement as covered
|
||||
|
||||
#### Scenario: Implementation diverges from spec
|
||||
- **WHEN** implementation exists but doesn't match spec intent
|
||||
- **THEN** report the divergence as WARNING
|
||||
- **AND** explain what differs
|
||||
- **AND** suggest: either update implementation or update spec to match reality
|
||||
|
||||
#### Scenario: Missing implementation
|
||||
- **WHEN** no implementation found for a requirement
|
||||
- **THEN** report as CRITICAL issue
|
||||
- **AND** suggest: "Implement requirement X" with guidance on what's needed
|
||||
|
||||
### Requirement: Coherence Verification
|
||||
The agent SHALL verify that implementation is sensible and follows design decisions.
|
||||
|
||||
#### Scenario: Design.md adherence check
|
||||
- **WHEN** verifying coherence
|
||||
- **AND** design.md exists for the change
|
||||
- **THEN** extract key decisions from design.md
|
||||
- **AND** verify implementation follows those decisions
|
||||
- **AND** report any deviations
|
||||
|
||||
#### Scenario: No design.md
|
||||
- **WHEN** verifying coherence
|
||||
- **AND** no design.md exists
|
||||
- **THEN** skip design adherence check
|
||||
- **AND** note "No design.md to verify against"
|
||||
|
||||
#### Scenario: Design decision followed
|
||||
- **WHEN** implementation follows a design decision
|
||||
- **THEN** report as confirmed
|
||||
- **AND** cite evidence from code
|
||||
|
||||
#### Scenario: Design decision violated
|
||||
- **WHEN** implementation contradicts a design decision
|
||||
- **THEN** report as WARNING
|
||||
- **AND** explain the contradiction
|
||||
- **AND** suggest: either update implementation or update design.md
|
||||
|
||||
#### Scenario: Code pattern consistency
|
||||
- **WHEN** verifying coherence
|
||||
- **THEN** check if new code follows existing project patterns
|
||||
- **AND** flag any significant deviations as suggestions
|
||||
|
||||
### Requirement: Verification Report Format
|
||||
The agent SHALL produce a structured, prioritized report.
|
||||
|
||||
#### Scenario: Report summary
|
||||
- **WHEN** verification completes
|
||||
- **THEN** display summary scorecard:
|
||||
```
|
||||
## Verification Report: <change-name>
|
||||
|
||||
### Summary
|
||||
| Dimension | Status |
|
||||
|--------------|----------|
|
||||
| Completeness | X/Y |
|
||||
| Correctness | X/Y |
|
||||
| Coherence | Followed |
|
||||
```
|
||||
|
||||
#### Scenario: Issue prioritization
|
||||
- **WHEN** issues are found
|
||||
- **THEN** group and display in priority order:
|
||||
1. CRITICAL - Must fix before archive (missing implementation, incomplete tasks)
|
||||
2. WARNING - Should fix (divergence from spec/design, missing tests)
|
||||
3. SUGGESTION - Nice to fix (pattern inconsistencies, minor improvements)
|
||||
|
||||
#### Scenario: Actionable recommendations
|
||||
- **WHEN** reporting an issue
|
||||
- **THEN** include specific, actionable fix recommendation
|
||||
- **AND** reference relevant files and line numbers where applicable
|
||||
- **AND** avoid vague suggestions like "consider reviewing"
|
||||
|
||||
#### Scenario: All checks pass
|
||||
- **WHEN** no issues found across all dimensions
|
||||
- **THEN** display:
|
||||
```
|
||||
All checks passed. Ready for archive.
|
||||
```
|
||||
|
||||
#### Scenario: Critical issues found
|
||||
- **WHEN** CRITICAL issues exist
|
||||
- **THEN** display:
|
||||
```
|
||||
X critical issue(s) found. Fix before archiving.
|
||||
```
|
||||
- **AND** do NOT suggest running archive
|
||||
|
||||
#### Scenario: Only warnings/suggestions
|
||||
- **WHEN** no CRITICAL issues but warnings exist
|
||||
- **THEN** display:
|
||||
```
|
||||
No critical issues. Y warning(s) to consider.
|
||||
Ready for archive (with noted improvements).
|
||||
```
|
||||
|
||||
### Requirement: Flexible Artifact Handling
|
||||
The agent SHALL gracefully handle changes with varying artifact completeness.
|
||||
|
||||
#### Scenario: Minimal change (tasks only)
|
||||
- **WHEN** change has only tasks.md
|
||||
- **THEN** verify task completion only
|
||||
- **AND** skip spec and design checks
|
||||
- **AND** note which checks were skipped
|
||||
|
||||
#### Scenario: Change with specs but no design
|
||||
- **WHEN** change has tasks.md and delta specs but no design.md
|
||||
- **THEN** verify completeness and correctness
|
||||
- **AND** skip design adherence
|
||||
- **AND** still check code coherence against project patterns
|
||||
|
||||
#### Scenario: Full change (all artifacts)
|
||||
- **WHEN** change has proposal, design, specs, and tasks
|
||||
- **THEN** perform all verification checks
|
||||
- **AND** cross-reference artifacts for consistency
|
||||
@@ -0,0 +1,15 @@
|
||||
# Tasks: Add /opsx:verify Skill
|
||||
|
||||
## 1. Skill Template Functions
|
||||
- [x] 1.1 Add `getVerifyChangeSkillTemplate()` to skill-templates.ts
|
||||
- [x] 1.2 Add `getOpsxVerifyCommandTemplate()` to skill-templates.ts
|
||||
|
||||
## 2. Integration with artifact-experimental-setup
|
||||
- [x] 2.1 Import verify template functions in artifact-workflow.ts
|
||||
- [x] 2.2 Add verify to skills array in artifactExperimentalSetupCommand
|
||||
- [x] 2.3 Add verify to commands array in artifactExperimentalSetupCommand
|
||||
- [x] 2.4 Add verify to help text output
|
||||
|
||||
## 3. Verification (Build & Test)
|
||||
- [x] 3.1 Verify TypeScript compilation succeeds
|
||||
- [x] 3.2 Verify all 8 skills are now included (was 7, now 8)
|
||||
@@ -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
|
||||
- [x] 1.1 Create `src/core/list.ts` with list logic
|
||||
- [x] 1.1.1 Implement directory scanning (exclude archive/)
|
||||
- [x] 1.1.2 Implement task counting from tasks.md files
|
||||
- [x] 1.1.3 Format output as simple table
|
||||
- [x] 1.2 Add list command to CLI in `src/cli/index.ts`
|
||||
- [x] 1.2.1 Register `openspec list` command
|
||||
- [x] 1.2.2 Connect to list.ts implementation
|
||||
|
||||
## 2. Error Handling
|
||||
- [x] 2.1 Handle missing openspec/changes/ directory
|
||||
- [x] 2.2 Handle changes without tasks.md files
|
||||
- [x] 2.3 Handle empty changes directory
|
||||
|
||||
## 3. Testing
|
||||
- [x] 3.1 Add tests for list functionality
|
||||
- [x] 3.1.1 Test with multiple changes
|
||||
- [x] 3.1.2 Test with completed changes
|
||||
- [x] 3.1.3 Test with no changes
|
||||
- [x] 3.1.4 Test error conditions
|
||||
|
||||
## 4. Documentation
|
||||
- [x] 4.1 Update CLI help text with list command
|
||||
- [x] 4.2 Add list command to README if applicable
|
||||
@@ -0,0 +1,15 @@
|
||||
## Why
|
||||
Need a command to archive completed changes to the archive folder with proper date prefixing, following OpenSpec conventions. Currently changes must be manually moved and renamed.
|
||||
|
||||
## What Changes
|
||||
- Add new `archive` command to CLI that moves changes to `changes/archive/YYYY-MM-DD-[change-name]/`
|
||||
- Check for incomplete tasks before archiving and warn user
|
||||
- Allow interactive selection of change to archive
|
||||
- Prevent archiving if target directory already exists
|
||||
- Update main specs from the change's future state specs (copy from `changes/[name]/specs/` to `openspec/specs/`)
|
||||
- Show confirmation prompt before updating specs, displaying which specs will be created/updated
|
||||
- Support `--yes` flag to skip confirmations for automation
|
||||
|
||||
## Impact
|
||||
- Affected specs: cli-archive (new)
|
||||
- Affected code: src/cli/index.ts, src/core/archive.ts (new)
|
||||
@@ -0,0 +1,111 @@
|
||||
# CLI Archive Command Specification
|
||||
|
||||
## Purpose
|
||||
The archive command moves completed changes from the active changes directory to the archive folder with date-based naming, following OpenSpec conventions.
|
||||
|
||||
## Command Syntax
|
||||
```bash
|
||||
openspec archive [change-name] [--yes|-y]
|
||||
```
|
||||
|
||||
Options:
|
||||
- `--yes`, `-y`: Skip confirmation prompts (for automation)
|
||||
|
||||
## Behavior
|
||||
|
||||
### Change Selection
|
||||
WHEN no change-name is provided
|
||||
THEN display interactive list of available changes (excluding archive/)
|
||||
AND allow user to select one
|
||||
|
||||
WHEN change-name is provided
|
||||
THEN use that change directly
|
||||
AND validate it exists
|
||||
|
||||
### Task Completion Check
|
||||
The command SHALL scan the change's tasks.md file for incomplete tasks (marked with `- [ ]`)
|
||||
|
||||
WHEN incomplete tasks are found
|
||||
THEN display all incomplete tasks to the user
|
||||
AND prompt for confirmation to continue
|
||||
AND default to "No" for safety
|
||||
|
||||
WHEN all tasks are complete OR no tasks.md exists
|
||||
THEN proceed with archiving without prompting
|
||||
|
||||
### Archive Process
|
||||
The archive operation SHALL:
|
||||
1. Create archive/ directory if it doesn't exist
|
||||
2. Generate target name as `YYYY-MM-DD-[change-name]` using current date
|
||||
3. Check if target directory already exists
|
||||
4. Update main specs from the change's future state specs (see Spec Update Process below)
|
||||
5. Move the entire change directory to the archive location
|
||||
|
||||
WHEN target archive already exists
|
||||
THEN fail with error message
|
||||
AND do not overwrite existing archive
|
||||
|
||||
WHEN move succeeds
|
||||
THEN display success message with archived name and list of updated specs
|
||||
|
||||
### Spec Update Process
|
||||
Before moving the change to archive, the command SHALL update main specs to reflect the deployed reality:
|
||||
|
||||
WHEN the change contains specs in `changes/[name]/specs/`
|
||||
THEN:
|
||||
1. Analyze which specs will be affected by comparing with existing specs
|
||||
2. Display a summary of spec updates to the user (see Confirmation Behavior below)
|
||||
3. Prompt for confirmation unless `--yes` flag is provided
|
||||
4. If confirmed, for each capability spec in the change directory:
|
||||
- Copy the spec from `changes/[name]/specs/[capability]/spec.md` to `openspec/specs/[capability]/spec.md`
|
||||
- Create the target directory structure if it doesn't exist
|
||||
- Overwrite existing spec files (specs represent current reality, change specs are the new reality)
|
||||
- Track which specs were updated for the success message
|
||||
|
||||
WHEN no specs exist in the change
|
||||
THEN skip the spec update step
|
||||
AND proceed with archiving
|
||||
|
||||
### Confirmation Behavior
|
||||
The spec update confirmation SHALL:
|
||||
- Display a clear summary showing:
|
||||
- Which specs will be created (new capabilities)
|
||||
- Which specs will be updated (existing capabilities)
|
||||
- The source path for each spec
|
||||
- Format the confirmation prompt as:
|
||||
```
|
||||
The following specs will be updated:
|
||||
|
||||
NEW specs to be created:
|
||||
- cli-archive (from changes/add-archive-command/specs/cli-archive/spec.md)
|
||||
|
||||
EXISTING specs to be updated:
|
||||
- cli-init (from changes/update-init-command/specs/cli-init/spec.md)
|
||||
|
||||
Update 2 specs and archive 'add-archive-command'? [y/N]:
|
||||
```
|
||||
- Default to "No" for safety (require explicit "y" or "yes")
|
||||
- Skip confirmation when `--yes` or `-y` flag is provided
|
||||
|
||||
WHEN user declines the confirmation
|
||||
THEN abort the entire archive operation
|
||||
AND display message: "Archive cancelled. No changes were made."
|
||||
AND exit with non-zero status code
|
||||
|
||||
## Error Handling
|
||||
|
||||
SHALL handle the following error conditions:
|
||||
- Missing openspec/changes/ directory
|
||||
- Change not found
|
||||
- Archive target already exists
|
||||
- File system permissions issues
|
||||
|
||||
## Why These Decisions
|
||||
|
||||
**Interactive selection**: Reduces typing and helps users see available changes
|
||||
**Task checking**: Prevents accidental archiving of incomplete work
|
||||
**Date prefixing**: Maintains chronological order and prevents naming conflicts
|
||||
**No overwrite**: Preserves historical archives and prevents data loss
|
||||
**Spec updates before archiving**: Specs in the main directory represent current reality; when a change is deployed and archived, its future state specs become the new reality and must replace the main specs
|
||||
**Confirmation for spec updates**: Provides visibility into what will change, prevents accidental overwrites, and ensures users understand the impact before specs are modified
|
||||
**--yes flag for automation**: Allows CI/CD pipelines to archive without interactive prompts while maintaining safety by default for manual use
|
||||
@@ -0,0 +1,44 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Core Implementation
|
||||
- [ ] 1.1 Create `src/core/archive.ts` with ArchiveCommand class
|
||||
- [ ] 1.1.1 Implement change selection (interactive if not provided)
|
||||
- [ ] 1.1.2 Implement incomplete task checking from tasks.md
|
||||
- [ ] 1.1.3 Implement confirmation prompt for incomplete tasks
|
||||
- [ ] 1.1.4 Implement spec update functionality
|
||||
- [ ] 1.1.4.1 Detect specs in change directory
|
||||
- [ ] 1.1.4.2 Compare with existing main specs
|
||||
- [ ] 1.1.4.3 Display summary of new vs updated specs
|
||||
- [ ] 1.1.4.4 Show confirmation prompt for spec updates
|
||||
- [ ] 1.1.4.5 Copy specs to main spec directory
|
||||
- [ ] 1.1.5 Implement archive move with date prefixing
|
||||
- [ ] 1.1.6 Support --yes flag to skip confirmations
|
||||
|
||||
## 2. CLI Integration
|
||||
- [ ] 2.1 Add archive command to `src/cli/index.ts`
|
||||
- [ ] 2.1.1 Import ArchiveCommand
|
||||
- [ ] 2.1.2 Register command with commander
|
||||
- [ ] 2.1.3 Add --yes/-y flag option
|
||||
- [ ] 2.1.4 Add proper error handling
|
||||
|
||||
## 3. Error Handling
|
||||
- [ ] 3.1 Handle missing openspec/changes/ directory
|
||||
- [ ] 3.2 Handle change not found
|
||||
- [ ] 3.3 Handle archive target already exists
|
||||
- [ ] 3.4 Handle user cancellation
|
||||
|
||||
## 4. Testing
|
||||
- [ ] 4.1 Test with fully completed change
|
||||
- [ ] 4.2 Test with incomplete tasks (warning shown)
|
||||
- [ ] 4.3 Test interactive selection mode
|
||||
- [ ] 4.4 Test duplicate archive prevention
|
||||
- [ ] 4.5 Test spec update functionality
|
||||
- [ ] 4.5.1 Test creating new specs
|
||||
- [ ] 4.5.2 Test updating existing specs
|
||||
- [ ] 4.5.3 Test confirmation prompt display
|
||||
- [ ] 4.5.4 Test declining confirmation (no changes made)
|
||||
- [ ] 4.5.5 Test --yes flag skips confirmation
|
||||
|
||||
## 5. Build and Validation
|
||||
- [ ] 5.1 Ensure TypeScript compilation succeeds
|
||||
- [ ] 5.2 Test command execution
|
||||
@@ -0,0 +1,56 @@
|
||||
# Design: Change Commands
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### Command Structure
|
||||
Similar to spec commands, we use subcommands (`change show`, `change list`, `change validate`) for:
|
||||
- Consistency with spec command pattern
|
||||
- Clear separation of concerns
|
||||
- Future extensibility for change management features
|
||||
|
||||
### JSON Schema for Changes
|
||||
```typescript
|
||||
{
|
||||
version: string, // Schema version
|
||||
format: "change", // Identifies as change document
|
||||
sourcePath: string, // Original markdown file path
|
||||
id: string, // Change identifier
|
||||
title: string, // Change title
|
||||
why: string, // Motivation section
|
||||
whatChanges: Array<{
|
||||
type: "ADDED" | "MODIFIED" | "REMOVED" | "RENAMED",
|
||||
deltas: Array<{
|
||||
specId: string,
|
||||
description: string,
|
||||
requirements?: Array<Requirement> // Only for ADDED/MODIFIED
|
||||
}>
|
||||
}>
|
||||
}
|
||||
```
|
||||
|
||||
**Rationale:**
|
||||
- Group deltas by operation type for clearer organization
|
||||
- Optional requirements field (only relevant for ADDED/MODIFIED)
|
||||
- Reuse RequirementSchema from spec commands for consistency
|
||||
|
||||
### Delta Operations
|
||||
**Four operation types:**
|
||||
1. **ADDED**: New requirements added to specs
|
||||
2. **MODIFIED**: Changes to existing requirements
|
||||
3. **REMOVED**: Requirements being deleted
|
||||
4. **RENAMED**: Spec identifier changes
|
||||
|
||||
**Design choice:** Explicit operation types rather than diff-based approach for:
|
||||
- Human readability in markdown
|
||||
- Clear intent communication
|
||||
- Easier validation and tooling
|
||||
|
||||
### Dependency on Spec Commands
|
||||
- **Shared schemas**: RequirementSchema and ScenarioSchema reused
|
||||
- **Implementation order**: spec commands must be implemented first
|
||||
- **Common parser utilities**: Share markdown parsing logic
|
||||
|
||||
### Legacy Compatibility
|
||||
- Keep existing `list` command functional with deprecation warning
|
||||
- Migration path: `list` → `change list` with same functionality
|
||||
- Gradual transition to avoid breaking existing workflows
|
||||
@@ -0,0 +1,17 @@
|
||||
# Change: Add Change Commands with JSON Output
|
||||
|
||||
## Why
|
||||
|
||||
OpenSpec change proposals currently can only be viewed as markdown files, creating the same programmatic access limitations as specs. Additionally, the current `openspec list` command only lists changes, which is inconsistent with the new resource-based command structure.
|
||||
|
||||
## What Changes
|
||||
|
||||
- **cli-change:** Add new command for managing change proposals with show, list, and validate subcommands
|
||||
- **cli-list:** Add deprecation notice for legacy list command to guide users to the new change list command
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected specs**: cli-list (modify to add deprecation notice)
|
||||
- **Affected code**:
|
||||
- src/cli/index.ts (register new command)
|
||||
- src/core/list.ts (add deprecation notice)
|
||||
@@ -0,0 +1,48 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Change Command
|
||||
|
||||
The system SHALL provide a `change` command with subcommands for displaying, listing, and validating change proposals.
|
||||
|
||||
#### Scenario: Show change as JSON
|
||||
|
||||
- **WHEN** executing `openspec change show update-error --json`
|
||||
- **THEN** parse the markdown change file
|
||||
- **AND** extract change structure and deltas
|
||||
- **AND** output valid JSON to stdout
|
||||
|
||||
#### Scenario: List all changes
|
||||
|
||||
- **WHEN** executing `openspec change list`
|
||||
- **THEN** scan the openspec/changes directory
|
||||
- **AND** return list of all pending changes
|
||||
- **AND** support JSON output with `--json` flag
|
||||
|
||||
#### Scenario: Show only requirement changes
|
||||
|
||||
- **WHEN** executing `openspec change show update-error --requirements-only`
|
||||
- **THEN** display only the requirement changes (ADDED/MODIFIED/REMOVED/RENAMED)
|
||||
- **AND** exclude why and what changes sections
|
||||
|
||||
#### Scenario: Validate change structure
|
||||
|
||||
- **WHEN** executing `openspec change validate update-error`
|
||||
- **THEN** parse the change file
|
||||
- **AND** validate against Zod schema
|
||||
- **AND** ensure deltas are well-formed
|
||||
|
||||
### Requirement: Legacy Compatibility
|
||||
|
||||
The system SHALL maintain backward compatibility with the existing `list` command while showing deprecation notices.
|
||||
|
||||
#### Scenario: Legacy list command
|
||||
|
||||
- **WHEN** executing `openspec list`
|
||||
- **THEN** display current list of changes (existing behavior)
|
||||
- **AND** show deprecation notice: "Note: 'openspec list' is deprecated. Use 'openspec change list' instead."
|
||||
|
||||
#### Scenario: Legacy list with --all flag
|
||||
|
||||
- **WHEN** executing `openspec list --all`
|
||||
- **THEN** display all changes (existing behavior)
|
||||
- **AND** show same deprecation notice
|
||||
@@ -0,0 +1,12 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Command Execution
|
||||
|
||||
The current `list` command behavior SHALL be preserved but marked as deprecated.
|
||||
|
||||
#### Scenario: Deprecation notice
|
||||
|
||||
- **WHEN** using the legacy `list` command
|
||||
- **THEN** continue to work as before
|
||||
- **AND** display deprecation notice
|
||||
- **AND** suggest using `openspec change list` instead
|
||||
@@ -0,0 +1,34 @@
|
||||
# Implementation Tasks (Phase 2: Builds on add-zod-validation)
|
||||
|
||||
## 1. Command Implementation
|
||||
- [x] 1.1 Create src/commands/change.ts
|
||||
- [x] 1.2 Import ChangeSchema and DeltaSchema from src/core/schemas/change.schema.ts
|
||||
- [x] 1.3 Import markdown parser from src/core/parsers/markdown-parser.ts
|
||||
- [x] 1.4 Import ChangeValidator from src/core/validation/validator.ts
|
||||
- [x] 1.5 Import JSON converter from src/core/converters/json-converter.ts
|
||||
- [x] 1.6 Implement show subcommand with JSON output using existing converter
|
||||
- [x] 1.7 Implement list subcommand
|
||||
- [x] 1.8 Implement validate subcommand using existing ChangeValidator
|
||||
- [x] 1.9 Add --requirements-only filtering option
|
||||
- [x] 1.10 Add --strict mode support (leveraging existing validation infrastructure)
|
||||
- [x] 1.11 Add --json flag for validation reports
|
||||
|
||||
## 2. Change-Specific Parser Extensions
|
||||
- [x] 2.1 Create src/core/parsers/change-parser.ts (extends base markdown parser)
|
||||
- [x] 2.2 Parse proposal structure (Why, What Changes sections)
|
||||
- [x] 2.3 Extract ADDED/MODIFIED/REMOVED/RENAMED sections
|
||||
- [x] 2.4 Parse delta operations within each section
|
||||
- [x] 2.5 Add tests for change parser
|
||||
|
||||
## 3. Legacy Compatibility
|
||||
- [x] 3.1 Update src/core/list.ts to add deprecation notice
|
||||
- [x] 3.2 Ensure existing list command continues to work
|
||||
- [x] 3.3 Add console warning for deprecated command usage
|
||||
|
||||
## 4. Integration
|
||||
- [x] 4.1 Register change command in src/cli/index.ts
|
||||
- [ ] 4.2 Add integration tests for all subcommands
|
||||
- [x] 4.3 Test JSON output for changes
|
||||
- [x] 4.4 Test legacy compatibility
|
||||
- [x] 4.5 Test validation with strict mode
|
||||
- [x] 4.6 Update CLI help documentation (add 'change' command to main help, document subcommands: show, list, validate)
|
||||
@@ -0,0 +1,20 @@
|
||||
## Why
|
||||
|
||||
Users frequently need to view changes and specs but must know in advance whether they're looking at a change or spec. The current subcommand structure (`change show`, `spec show`) creates friction when:
|
||||
- Users want to quickly view an item without remembering its type
|
||||
- Exploring the codebase requires switching between different show commands
|
||||
- Show commands without arguments return errors instead of helpful guidance
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add new top-level `show` command for displaying changes or specs with intelligent selection
|
||||
- Support direct item display: `openspec show <item>` with automatic type detection
|
||||
- Interactive selection when no arguments provided
|
||||
- Enhance existing `change show` and `spec show` to support interactive selection (backwards compatibility)
|
||||
- Maintain all existing format options (--json, --deltas-only, --requirements, etc.)
|
||||
|
||||
## Impact
|
||||
|
||||
- New specs to create: cli-show
|
||||
- Specs to enhance: cli-change, cli-spec (for backwards compatibility)
|
||||
- Affected code: src/cli/index.ts, src/commands/show.ts (new), src/commands/spec.ts, src/commands/change.ts
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# CLI Change Command Spec
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Interactive show selection
|
||||
|
||||
The change show command SHALL support interactive selection when no change name is provided.
|
||||
|
||||
#### Scenario: Interactive change selection for show
|
||||
|
||||
- **WHEN** executing `openspec change show` without arguments
|
||||
- **THEN** display an interactive list of available changes
|
||||
- **AND** allow the user to select a change to show
|
||||
- **AND** display the selected change content
|
||||
- **AND** maintain all existing show options (--json, --deltas-only)
|
||||
|
||||
#### Scenario: Non-interactive fallback keeps current behavior
|
||||
|
||||
- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
|
||||
- **WHEN** executing `openspec change show` without a change name
|
||||
- **THEN** do not prompt interactively
|
||||
- **AND** print the existing hint including available change IDs
|
||||
- **AND** set `process.exitCode = 1`
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# CLI Show Command Spec
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Top-level show command
|
||||
|
||||
The CLI SHALL provide a top-level `show` command for displaying changes and specs with intelligent selection.
|
||||
|
||||
#### Scenario: Interactive show selection
|
||||
|
||||
- **WHEN** executing `openspec show` without arguments
|
||||
- **THEN** prompt user to select type (change or spec)
|
||||
- **AND** display list of available items for selected type
|
||||
- **AND** show the selected item's content
|
||||
|
||||
#### Scenario: Non-interactive environments do not prompt
|
||||
|
||||
- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
|
||||
- **WHEN** executing `openspec show` without arguments
|
||||
- **THEN** do not prompt
|
||||
- **AND** print a helpful hint with examples for `openspec show <item>` or `openspec change/spec show`
|
||||
- **AND** exit with code 1
|
||||
|
||||
#### Scenario: Direct item display
|
||||
|
||||
- **WHEN** executing `openspec show <item-name>`
|
||||
- **THEN** automatically detect if item is a change or spec
|
||||
- **AND** display the item's content
|
||||
- **AND** use appropriate formatting based on item type
|
||||
|
||||
#### Scenario: Type detection and ambiguity handling
|
||||
|
||||
- **WHEN** executing `openspec show <item-name>`
|
||||
- **THEN** if `<item-name>` uniquely matches a change or a spec, show that item
|
||||
- **AND** if it matches both, print an ambiguity error and suggest `--type change|spec` or using `openspec change show`/`openspec spec show`
|
||||
- **AND** if it matches neither, print not-found with nearest-match suggestions
|
||||
|
||||
#### Scenario: Explicit type override
|
||||
|
||||
- **WHEN** executing `openspec show --type change <item>`
|
||||
- **THEN** treat `<item>` as a change ID and show it (skipping auto-detection)
|
||||
|
||||
- **WHEN** executing `openspec show --type spec <item>`
|
||||
- **THEN** treat `<item>` as a spec ID and show it (skipping auto-detection)
|
||||
|
||||
### Requirement: Output format options
|
||||
|
||||
The show command SHALL support various output formats consistent with existing commands.
|
||||
|
||||
#### Scenario: JSON output
|
||||
|
||||
- **WHEN** executing `openspec show <item> --json`
|
||||
- **THEN** output the item in JSON format
|
||||
- **AND** include parsed metadata and structure
|
||||
- **AND** maintain format consistency with existing change/spec show commands
|
||||
|
||||
#### Scenario: Flag scoping and delegation
|
||||
|
||||
- **WHEN** showing a change or a spec via the top-level command
|
||||
- **THEN** accept common flags such as `--json`
|
||||
- **AND** pass through type-specific flags to the corresponding implementation
|
||||
- Change-only flags: `--deltas-only` (alias `--requirements-only` deprecated)
|
||||
- Spec-only flags: `--requirements`, `--no-scenarios`, `-r/--requirement`
|
||||
- **AND** ignore irrelevant flags for the detected type with a warning
|
||||
|
||||
### Requirement: Interactivity controls
|
||||
|
||||
- The CLI SHALL respect `--no-interactive` to disable prompts.
|
||||
- The CLI SHALL respect `OPEN_SPEC_INTERACTIVE=0` to disable prompts globally.
|
||||
- Interactive prompts SHALL only be shown when stdin is a TTY and interactivity is not disabled.
|
||||
|
||||
#### Scenario: Change-specific options
|
||||
|
||||
- **WHEN** showing a change with `openspec show <change-name> --deltas-only`
|
||||
- **THEN** display only the deltas in JSON format
|
||||
- **AND** maintain compatibility with existing change show options
|
||||
|
||||
#### Scenario: Spec-specific options
|
||||
|
||||
- **WHEN** showing a spec with `openspec show <spec-id> --requirements`
|
||||
- **THEN** display only requirements in JSON format
|
||||
- **AND** support other spec options (--no-scenarios, -r)
|
||||
- **AND** maintain compatibility with existing spec show options
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# CLI Spec Command Spec
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Interactive spec show
|
||||
|
||||
The spec show command SHALL support interactive selection when no spec-id is provided.
|
||||
|
||||
#### Scenario: Interactive spec selection for show
|
||||
|
||||
- **WHEN** executing `openspec spec show` without arguments
|
||||
- **THEN** display an interactive list of available specs
|
||||
- **AND** allow the user to select a spec to show
|
||||
- **AND** display the selected spec content
|
||||
- **AND** maintain all existing show options (--json, --requirements, --no-scenarios, -r)
|
||||
|
||||
#### Scenario: Non-interactive fallback keeps current behavior
|
||||
|
||||
- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
|
||||
- **WHEN** executing `openspec spec show` without a spec-id
|
||||
- **THEN** do not prompt interactively
|
||||
- **AND** print the existing error message for missing spec-id
|
||||
- **AND** set non-zero exit code
|
||||
@@ -0,0 +1,142 @@
|
||||
# Implementation Tasks — Add Interactive Show Command
|
||||
|
||||
## Goals
|
||||
- Add a top-level `show` command with intelligent selection and type detection.
|
||||
- Add interactive selection to `change show` and `spec show` when no ID is provided.
|
||||
- Preserve raw-first output behavior and existing JSON formats/filters.
|
||||
- Respect `--no-interactive` and `OPEN_SPEC_INTERACTIVE=0` consistently.
|
||||
|
||||
---
|
||||
|
||||
## 1) CLI wiring
|
||||
- [x] In `src/cli/index.ts` add a top-level command: `program.command('show [item-name]')`
|
||||
- Options:
|
||||
- `--json`
|
||||
- `--type <type>` where `<type>` is `change|spec`
|
||||
- `--no-interactive`
|
||||
- Allow passing-through type-specific flags using `.allowUnknownOption(true)` so the top-level can forward flags to the underlying type handler.
|
||||
- Action: instantiate `new ShowCommand().execute(itemName, options)`.
|
||||
- [x] Update `change show` subcommand to accept `--no-interactive` and pass it to `ChangeCommand.show(...)`.
|
||||
- [x] Change `spec show` subcommand to accept optional ID (`show [spec-id]`), add `--no-interactive`, and pass to spec show implementation.
|
||||
|
||||
Acceptance:
|
||||
- `openspec show` exists and prints a helpful hint in non-interactive contexts when no args.
|
||||
- Unknown flags for other types do not crash parsing; they are warned/ignored appropriately.
|
||||
|
||||
---
|
||||
|
||||
## 2) New module: `src/commands/show.ts`
|
||||
- [x] Create `ShowCommand` with:
|
||||
- `execute(itemName?: string, options?: { json?: boolean; type?: string; noInteractive?: boolean; [k: string]: any })`
|
||||
- Interactive path when `!itemName` and interactive is enabled:
|
||||
- Prompt: "What would you like to show?" → `change` or `spec`.
|
||||
- Load available IDs for the chosen type and prompt selection.
|
||||
- Delegate to type-specific show implementation.
|
||||
- Non-interactive path when `!itemName`:
|
||||
- Print hint with examples:
|
||||
- `openspec show <item>`
|
||||
- `openspec change show`
|
||||
- `openspec spec show`
|
||||
- Exit with code 1.
|
||||
- Direct item path when `itemName` is provided:
|
||||
- Type override via `--type` takes precedence.
|
||||
- Otherwise detect using `getActiveChangeIds()` and `getSpecIds()`.
|
||||
- If ambiguous and no override: print error + suggestion to pass `--type` or use subcommands; exit code 1.
|
||||
- If unknown: print not-found with nearest-match suggestions; exit code 1.
|
||||
- On success: delegate to type-specific show.
|
||||
- [x] Flag scoping and pass-through:
|
||||
- Common: `--json` → forwarded to both types.
|
||||
- Change-only: `--deltas-only`, `--requirements-only` (deprecated alias).
|
||||
- Spec-only: `--requirements`, `--no-scenarios`, `-r/--requirement`.
|
||||
- Warn and ignore irrelevant flags for the resolved type.
|
||||
|
||||
Acceptance:
|
||||
- `openspec show <change-id> --json --deltas-only` matches `openspec change show <id> --json --deltas-only` output.
|
||||
- `openspec show <spec-id> --json --requirements` matches `openspec spec show <id> --json --requirements` output.
|
||||
- Ambiguity and not-found behaviors match the `cli-show` spec.
|
||||
|
||||
---
|
||||
|
||||
## 3) Refactor spec show into reusable API
|
||||
- [x] In `src/commands/spec.ts`, extract show logic into an exported `SpecCommand` with `show(specId?: string, options?: { json?: boolean; requirements?: boolean; scenarios?: boolean; requirement?: string; noInteractive?: boolean })`.
|
||||
- Reuse current helpers (`parseSpecFromFile`, `filterSpec`, raw-first printing).
|
||||
- Keep `registerSpecCommand` but delegate to `new SpecCommand().show(...)`.
|
||||
- [x] Update CLI spec show subcommand to optional arg and interactive behavior (see section 4).
|
||||
|
||||
Acceptance:
|
||||
- Existing `spec show` tests continue to pass.
|
||||
- New `SpecCommand.show` can be called from `ShowCommand`.
|
||||
|
||||
---
|
||||
|
||||
## 4) Backwards-compatible interactive in subcommands
|
||||
- [x] `src/commands/change.ts` → extend `show(changeName?: string, options?: { json?: boolean; requirementsOnly?: boolean; deltasOnly?: boolean; noInteractive?: boolean })`:
|
||||
- When `!changeName` and interactive enabled: prompt from `getActiveChangeIds()` and show the selected change.
|
||||
- Non-interactive fallback: keep current behavior (print available IDs + `openspec change list` hint, set `process.exitCode = 1`).
|
||||
- [x] `src/commands/spec.ts` → `SpecCommand.show` as above:
|
||||
- When `!specId` and interactive enabled: prompt from `getSpecIds()` and show the selected spec.
|
||||
- Non-interactive fallback: print the same error as existing behavior for missing `<spec-id>` and set non-zero exit code.
|
||||
|
||||
Acceptance:
|
||||
- `openspec change show` in non-interactive prints list hint and exits non-zero.
|
||||
- `openspec spec show` in non-interactive prints missing-arg error and exits non-zero.
|
||||
|
||||
---
|
||||
|
||||
## 5) Shared utilities
|
||||
- [x] Extract `nearestMatches` and `levenshtein` from `src/commands/validate.ts` into `src/utils/match.ts` (exported helpers).
|
||||
- [x] Update `ValidateCommand` and new `ShowCommand` to import from `utils/match`.
|
||||
|
||||
Acceptance:
|
||||
- Build succeeds with shared helpers and no duplication.
|
||||
|
||||
---
|
||||
|
||||
## 6) Hints, warnings, and messages
|
||||
- [x] Top-level `show` hint (non-interactive no-arg):
|
||||
- Lines include: `openspec show <item>`, `openspec change show`, `openspec spec show`, and "Or run in an interactive terminal.".
|
||||
- [x] Ambiguity message suggests `--type change|spec` and the subcommands.
|
||||
- [x] Not-found suggests nearest matches (up to 5).
|
||||
- [x] Irrelevant flag warnings for the resolved type (printed to stderr, no crash).
|
||||
|
||||
Acceptance:
|
||||
- Messages match the `cli-show` spec wording intent and style used elsewhere.
|
||||
|
||||
---
|
||||
|
||||
## 7) Tests
|
||||
Add tests mirroring existing patterns (non-TTY simulation via `OPEN_SPEC_INTERACTIVE=0`).
|
||||
|
||||
- [x] `test/commands/show.test.ts`
|
||||
- Non-interactive, no arg → prints hint and exits non-zero.
|
||||
- Direct item detection for change and for spec.
|
||||
- Ambiguity case when both exist → error and suggestion for `--type`.
|
||||
- Not-found case → nearest-match suggestions.
|
||||
- Pass-through flags: change `--json --deltas-only`, spec `--json --requirements`.
|
||||
- [x] `test/commands/change.interactive-show.test.ts` (non-interactive fallback)
|
||||
- Ensure `openspec change show` without args prints available IDs + list hint and non-zero exit.
|
||||
- [x] `test/commands/spec.interactive-show.test.ts` (non-interactive fallback)
|
||||
- Ensure `openspec spec show` without args prints missing-arg error and non-zero exit.
|
||||
|
||||
Acceptance:
|
||||
- All new tests pass after build; no regressions in existing tests.
|
||||
|
||||
---
|
||||
|
||||
## 8) Documentation (optional but recommended)
|
||||
- [x] Update `openspec/README.md` usage examples to include the new `show` command with type detection and flags.
|
||||
|
||||
---
|
||||
|
||||
## 9) Non-functional checks
|
||||
- [x] Run `pnpm build` and all tests (`pnpm test`).
|
||||
- [x] Ensure no linter/type errors and messages are consistent with existing style.
|
||||
|
||||
---
|
||||
|
||||
## Notes on consistency
|
||||
- Follow raw-first behavior for text output: passthrough file content with no formatting, mirroring current `change show` and `spec show`.
|
||||
- Reuse `isInteractive` and `item-discovery` helpers for consistent prompting behavior.
|
||||
- Keep JSON output shapes identical to current `ChangeCommand.show` and `spec show` outputs.
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
## Why
|
||||
The archive command currently forces users to either accept spec updates or cancel the entire archive operation. Users need flexibility to archive changes without updating specs, either through explicit flags or by declining the confirmation prompt. This is especially important for changes that don't modify specs (like tooling, documentation, or infrastructure updates).
|
||||
|
||||
## What Changes
|
||||
- Add new `--skip-specs` flag to the archive command that bypasses all spec update operations
|
||||
- Fix confirmation behavior: when users decline spec updates interactively, proceed with archiving instead of cancelling the entire operation
|
||||
- When `--skip-specs` flag is used, skip both the spec discovery and update confirmation steps entirely
|
||||
- Display clear message when specs are skipped (either via flag or user choice)
|
||||
- Flag can be combined with existing `--yes` flag for fully automated archiving without spec updates
|
||||
|
||||
## Impact
|
||||
- Affected specs: cli-archive
|
||||
- Affected code: src/core/archive.ts, src/cli/index.ts
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
# CLI Archive Command Specification
|
||||
|
||||
## Purpose
|
||||
The archive command moves completed changes from the active changes directory to the archive folder with date-based naming, following OpenSpec conventions.
|
||||
|
||||
## Command Syntax
|
||||
```bash
|
||||
openspec archive [change-name] [--yes|-y] [--skip-specs]
|
||||
```
|
||||
|
||||
Options:
|
||||
- `--yes`, `-y`: Skip confirmation prompts (for automation)
|
||||
- `--skip-specs`: Skip spec update operations entirely (for changes without spec modifications)
|
||||
|
||||
## Behavior
|
||||
|
||||
### Requirement: Change Selection
|
||||
|
||||
The command SHALL support both interactive and direct change selection methods.
|
||||
|
||||
#### Scenario: Interactive selection
|
||||
|
||||
- **WHEN** no change-name is provided
|
||||
- **THEN** display interactive list of available changes (excluding archive/)
|
||||
- **AND** allow user to select one
|
||||
|
||||
#### Scenario: Direct selection
|
||||
|
||||
- **WHEN** change-name is provided
|
||||
- **THEN** use that change directly
|
||||
- **AND** validate it exists
|
||||
|
||||
### Requirement: Task Completion Check
|
||||
|
||||
The command SHALL verify task completion status before archiving to prevent premature archival.
|
||||
|
||||
#### Scenario: Incomplete tasks found
|
||||
|
||||
- **WHEN** incomplete tasks are found (marked with `- [ ]`)
|
||||
- **THEN** display all incomplete tasks to the user
|
||||
- **AND** prompt for confirmation to continue
|
||||
- **AND** default to "No" for safety
|
||||
|
||||
#### Scenario: All tasks complete
|
||||
|
||||
- **WHEN** all tasks are complete OR no tasks.md exists
|
||||
- **THEN** proceed with archiving without prompting
|
||||
|
||||
### Requirement: Archive Process
|
||||
|
||||
The archive operation SHALL follow a structured process to safely move changes to the archive.
|
||||
|
||||
#### Scenario: Performing archive
|
||||
|
||||
- **WHEN** archiving a change
|
||||
- **THEN** execute these steps:
|
||||
1. Create archive/ directory if it doesn't exist
|
||||
2. Generate target name as `YYYY-MM-DD-[change-name]` using current date
|
||||
3. Check if target directory already exists
|
||||
4. Update main specs from the change's future state specs unless `--skip-specs` is provided (see Spec Update Process below)
|
||||
5. Move the entire change directory to the archive location
|
||||
|
||||
#### Scenario: Archive already exists
|
||||
|
||||
- **WHEN** target archive already exists
|
||||
- **THEN** fail with error message
|
||||
- **AND** do not overwrite existing archive
|
||||
|
||||
#### Scenario: Successful archive
|
||||
|
||||
- **WHEN** move succeeds
|
||||
- **THEN** display success message with archived name and list of updated specs (if any)
|
||||
|
||||
### Requirement: Spec Update Process
|
||||
|
||||
Before moving the change to archive, the command SHALL update main specs to reflect the deployed reality unless the `--skip-specs` flag is provided.
|
||||
|
||||
#### Scenario: Skipping spec updates
|
||||
|
||||
- **WHEN** the `--skip-specs` flag is provided
|
||||
- **THEN** skip all spec discovery and update operations
|
||||
- **AND** proceed directly to moving the change to archive
|
||||
- **AND** display message indicating specs were skipped
|
||||
|
||||
#### Scenario: Updating specs from change
|
||||
|
||||
- **WHEN** the change contains specs in `changes/[name]/specs/` AND `--skip-specs` is NOT provided
|
||||
- **THEN** execute these steps:
|
||||
1. Analyze which specs will be affected by comparing with existing specs
|
||||
2. Display a summary of spec updates to the user (see Confirmation Behavior below)
|
||||
3. Prompt for confirmation unless `--yes` flag is provided
|
||||
4. If confirmed, for each capability spec in the change directory:
|
||||
- Copy the spec from `changes/[name]/specs/[capability]/spec.md` to `openspec/specs/[capability]/spec.md`
|
||||
- Create the target directory structure if it doesn't exist
|
||||
- Overwrite existing spec files (specs represent current reality, change specs are the new reality)
|
||||
- Track which specs were updated for the success message
|
||||
|
||||
#### Scenario: No specs in change
|
||||
|
||||
- **WHEN** no specs exist in the change AND `--skip-specs` is NOT provided
|
||||
- **THEN** skip the spec update step
|
||||
- **AND** proceed with archiving
|
||||
|
||||
### Requirement: Confirmation Behavior
|
||||
|
||||
The spec update confirmation SHALL provide clear visibility into changes before they are applied.
|
||||
|
||||
#### Scenario: Displaying confirmation
|
||||
|
||||
- **WHEN** prompting for confirmation AND `--skip-specs` is NOT provided
|
||||
- **THEN** display a clear summary showing:
|
||||
- Which specs will be created (new capabilities)
|
||||
- Which specs will be updated (existing capabilities)
|
||||
- The source path for each spec
|
||||
- **AND** format the confirmation prompt as:
|
||||
```
|
||||
The following specs will be updated:
|
||||
|
||||
NEW specs to be created:
|
||||
- cli-archive (from changes/add-archive-command/specs/cli-archive/spec.md)
|
||||
|
||||
EXISTING specs to be updated:
|
||||
- cli-init (from changes/update-init-command/specs/cli-init/spec.md)
|
||||
|
||||
Update 2 specs and archive 'add-archive-command'? [y/N]:
|
||||
```
|
||||
#### Scenario: Handling confirmation response
|
||||
|
||||
- **WHEN** waiting for user confirmation
|
||||
- **THEN** default to "No" for safety (require explicit "y" or "yes")
|
||||
- **AND** skip confirmation when `--yes` or `-y` flag is provided
|
||||
- **AND** skip entire spec confirmation when `--skip-specs` flag is provided
|
||||
|
||||
#### Scenario: User declines spec update confirmation
|
||||
|
||||
- **WHEN** user declines the spec update confirmation
|
||||
- **THEN** skip the spec update operations
|
||||
- **AND** display message: "Skipping spec updates. Proceeding with archive."
|
||||
- **AND** continue with the archive operation
|
||||
- **AND** display success message indicating specs were not updated
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Requirement: Error Conditions
|
||||
|
||||
The command SHALL handle various error conditions gracefully.
|
||||
|
||||
#### Scenario: Handling errors
|
||||
|
||||
- **WHEN** errors occur
|
||||
- **THEN** handle the following conditions:
|
||||
- Missing openspec/changes/ directory
|
||||
- Change not found
|
||||
- Archive target already exists
|
||||
- File system permissions issues
|
||||
|
||||
## Why These Decisions
|
||||
|
||||
**Interactive selection**: Reduces typing and helps users see available changes
|
||||
**Task checking**: Prevents accidental archiving of incomplete work
|
||||
**Date prefixing**: Maintains chronological order and prevents naming conflicts
|
||||
**No overwrite**: Preserves historical archives and prevents data loss
|
||||
**Spec updates before archiving**: Specs in the main directory represent current reality; when a change is deployed and archived, its future state specs become the new reality and must replace the main specs
|
||||
**Confirmation for spec updates**: Provides visibility into what will change, prevents accidental overwrites, and ensures users understand the impact before specs are modified
|
||||
**Non-blocking confirmation**: Declining spec updates doesn't cancel archiving - users can review specs and choose to update them separately if needed
|
||||
**--yes flag for automation**: Allows CI/CD pipelines to archive without interactive prompts while maintaining safety by default for manual use
|
||||
**--skip-specs flag**: Enables archiving of changes that don't modify specs (like infrastructure, tooling, or documentation changes) without unnecessary spec update prompts or operations
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Skip Specs Option
|
||||
|
||||
The archive command SHALL support a `--skip-specs` flag that skips all spec update operations and proceeds directly to archiving.
|
||||
|
||||
#### Scenario: Skipping spec updates with flag
|
||||
|
||||
- **WHEN** executing `openspec archive <change> --skip-specs`
|
||||
- **THEN** skip spec discovery and update confirmation
|
||||
- **AND** proceed directly to moving the change to archive
|
||||
- **AND** display a message indicating specs were skipped
|
||||
|
||||
### Requirement: Non-blocking confirmation
|
||||
|
||||
The archive operation SHALL proceed when the user declines spec updates instead of cancelling the entire operation.
|
||||
|
||||
#### Scenario: User declines spec update confirmation
|
||||
|
||||
- **WHEN** the user declines spec update confirmation
|
||||
- **THEN** skip spec updates
|
||||
- **AND** continue with the archive operation
|
||||
- **AND** display a success message indicating specs were not updated
|
||||
@@ -0,0 +1,57 @@
|
||||
## 1. Update Archive Command Implementation
|
||||
- [x] 1.1 Add `skipSpecs` option to the archive command options interface
|
||||
- [x] 1.2 Modify the execute method to skip spec operations when flag is set
|
||||
- [x] 1.3 Fix confirmation behavior: when user declines spec updates, proceed with archiving instead of cancelling
|
||||
- [x] 1.4 Update console output to indicate when specs are being skipped (via flag or user choice)
|
||||
- [x] 1.5 Ensure archive continues after declining spec updates
|
||||
|
||||
## 2. Update CLI Interface
|
||||
- [x] 2.1 Add `--skip-specs` flag to the archive command definition
|
||||
- [x] 2.2 Pass the flag value to the archive command execute method
|
||||
|
||||
## 3. Update Tests
|
||||
- [x] 3.1 Add test case for archiving with --skip-specs flag
|
||||
- [x] 3.2 Add test case for declining spec updates but continuing with archive
|
||||
- [x] 3.3 Verify that spec updates are skipped when flag is used
|
||||
- [x] 3.4 Verify that archive proceeds when user declines spec updates
|
||||
- [x] 3.5 Ensure existing behavior remains unchanged when flag is not used
|
||||
|
||||
## 4. Update Documentation
|
||||
- [x] 4.1 Update the cli-archive spec to document the new --skip-specs flag
|
||||
- [x] 4.2 Document the new behavior when declining spec updates interactively
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Key Design Decisions
|
||||
|
||||
1. **Non-blocking Confirmation Behavior**: When users decline spec updates interactively, the archive operation continues rather than cancelling entirely. This was a critical UX improvement because:
|
||||
- Users may want to review specs separately before updating them
|
||||
- Archiving work shouldn't be blocked by spec review decisions
|
||||
- Maintains flexibility in the deployment workflow
|
||||
|
||||
2. **Flag Naming Convention**: Chose `--skip-specs` for clarity and consistency:
|
||||
- Clearly indicates the action (skipping) and target (specs)
|
||||
- Follows kebab-case convention for CLI flags
|
||||
- Converts naturally to `skipSpecs` camelCase in code
|
||||
|
||||
3. **Console Messaging Strategy**: Added explicit messages for all spec-skipping scenarios:
|
||||
- When flag is used: "Skipping spec updates (--skip-specs flag provided)."
|
||||
- When user declines: "Skipping spec updates. Proceeding with archive."
|
||||
- Ensures users always understand what's happening with their specs
|
||||
|
||||
4. **Test Coverage Approach**: Created separate test cases for:
|
||||
- Flag-based skipping (explicit user choice via CLI)
|
||||
- Interactive declining (runtime user decision)
|
||||
- Both verify the same outcome but test different code paths
|
||||
|
||||
### Use Cases Addressed
|
||||
|
||||
- **Infrastructure Changes**: Changes to build tools, CI/CD, dependencies
|
||||
- **Documentation Updates**: README updates, comment improvements
|
||||
- **Tooling Modifications**: Developer tools, scripts, configuration files
|
||||
- **Refactoring**: Code improvements that don't change functionality/specs
|
||||
|
||||
### Future Considerations
|
||||
|
||||
- Could potentially auto-detect when changes don't include specs and suggest using the flag
|
||||
- May want to track which archives skipped spec updates for audit purposes
|
||||
@@ -0,0 +1,45 @@
|
||||
# Design: Spec Commands
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### Command Hierarchy
|
||||
We chose a subcommand pattern (`spec show`, `spec list`, `spec validate`) to:
|
||||
- Group related functionality under a common namespace
|
||||
- Enable future extensibility without polluting the top-level CLI
|
||||
- Maintain consistency with the planned `change` command structure
|
||||
|
||||
### JSON Schema Structure
|
||||
The spec JSON schema follows this structure:
|
||||
```typescript
|
||||
{
|
||||
version: string, // Schema version for compatibility
|
||||
format: "spec", // Identifies this as a spec document
|
||||
sourcePath: string, // Original markdown file path
|
||||
id: string, // Spec identifier from filename
|
||||
title: string, // Human-readable title
|
||||
overview?: string, // Optional overview section
|
||||
requirements: Array<{
|
||||
id: string,
|
||||
text: string,
|
||||
scenarios: Array<{
|
||||
id: string,
|
||||
text: string
|
||||
}>
|
||||
}>
|
||||
}
|
||||
```
|
||||
|
||||
**Rationale:**
|
||||
- Flat structure for requirements array (vs nested objects) for easier iteration
|
||||
- Scenarios nested within requirements to maintain relationship
|
||||
- Metadata fields (version, format, sourcePath) for tooling integration
|
||||
|
||||
### Parser Architecture
|
||||
- **Markdown-first approach**: Parse markdown headings rather than custom syntax
|
||||
- **Streaming parser**: Process line-by-line to handle large files efficiently
|
||||
- **Strict heading hierarchy**: Enforce ##/###/#### structure for consistency
|
||||
|
||||
### Validation Strategy
|
||||
- **Parse-time validation**: Catch structural issues during parsing
|
||||
- **Schema validation**: Use Zod for runtime type checking of parsed data
|
||||
- **Separate validation command**: Allow validation without full parsing/conversion
|
||||
@@ -0,0 +1,19 @@
|
||||
# Change: Add Spec Commands with JSON Output
|
||||
|
||||
## Why
|
||||
|
||||
Currently, OpenSpec specs can only be viewed as markdown files. This makes programmatic access difficult and prevents integration with CI/CD pipelines, external tools, and automated processing.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add new `openspec spec` command with three subcommands: `show`, `list`, and `validate`
|
||||
- Implement JSON output capability for specs using heading-based parsing
|
||||
- Add Zod schemas for spec structure validation
|
||||
- Enable content filtering options (requirements only, no scenarios, specific requirement)
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected specs**: None (new capability)
|
||||
- **Affected code**:
|
||||
- src/cli/index.ts (register new command)
|
||||
- package.json (add zod dependency)
|
||||
@@ -0,0 +1,43 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Spec Command
|
||||
|
||||
The system SHALL provide a `spec` command with subcommands for displaying, listing, and validating specifications.
|
||||
|
||||
#### Scenario: Show spec as JSON
|
||||
|
||||
- **WHEN** executing `openspec spec show init --json`
|
||||
- **THEN** parse the markdown spec file
|
||||
- **AND** extract headings and content hierarchically
|
||||
- **AND** output valid JSON to stdout
|
||||
|
||||
#### Scenario: List all specs
|
||||
|
||||
- **WHEN** executing `openspec spec list`
|
||||
- **THEN** scan the openspec/specs directory
|
||||
- **AND** return list of all available capabilities
|
||||
- **AND** support JSON output with `--json` flag
|
||||
|
||||
#### Scenario: Filter spec content
|
||||
|
||||
- **WHEN** executing `openspec spec show init --requirements`
|
||||
- **THEN** display only requirement names and SHALL statements
|
||||
- **AND** exclude scenario content
|
||||
|
||||
#### Scenario: Validate spec structure
|
||||
|
||||
- **WHEN** executing `openspec spec validate init`
|
||||
- **THEN** parse the spec file
|
||||
- **AND** validate against Zod schema
|
||||
- **AND** report any structural issues
|
||||
|
||||
### Requirement: JSON Schema Definition
|
||||
|
||||
The system SHALL define Zod schemas that accurately represent the spec structure for runtime validation.
|
||||
|
||||
#### Scenario: Schema validation
|
||||
|
||||
- **WHEN** parsing a spec into JSON
|
||||
- **THEN** validate the structure using Zod schemas
|
||||
- **AND** ensure all required fields are present
|
||||
- **AND** provide clear error messages for validation failures
|
||||
@@ -0,0 +1,22 @@
|
||||
# Implementation Tasks (Phase 3: Builds on add-zod-validation and add-change-commands)
|
||||
|
||||
## 1. Command Implementation
|
||||
- [x] 1.1 Create src/commands/spec.ts
|
||||
- [x] 1.2 Import RequirementSchema, ScenarioSchema, SpecSchema from src/core/schemas/
|
||||
- [x] 1.3 Import markdown parser from src/core/parsers/markdown-parser.ts
|
||||
- [x] 1.4 Import SpecValidator from src/core/validation/validator.ts
|
||||
- [x] 1.5 Import JSON converter from src/core/converters/json-converter.ts
|
||||
- [x] 1.6 Implement show subcommand with JSON output using existing converter
|
||||
- [x] 1.7 Implement list subcommand
|
||||
- [x] 1.8 Implement validate subcommand using existing SpecValidator
|
||||
- [x] 1.9 Add filtering options (--requirements, --no-scenarios, -r)
|
||||
- [x] 1.10 Add --strict mode support (leveraging existing validation infrastructure)
|
||||
- [x] 1.11 Add --json flag for validation reports
|
||||
|
||||
## 2. Integration
|
||||
- [x] 2.1 Register spec command in src/cli/index.ts
|
||||
- [x] 2.2 Add integration tests for all subcommands
|
||||
- [x] 2.3 Test JSON output validation
|
||||
- [x] 2.4 Test filtering options
|
||||
- [x] 2.5 Test validation with strict mode
|
||||
- [x] 2.6 Update CLI help documentation (add 'spec' command to main help, document subcommands: show, list, validate)
|
||||
@@ -0,0 +1,104 @@
|
||||
# Design: Zod Validation Framework
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### Validation Levels
|
||||
Three-tier validation system:
|
||||
1. **ERROR**: Structural issues that prevent parsing (must fix)
|
||||
2. **WARNING**: Quality issues that should be addressed (recommended fix)
|
||||
3. **INFO**: Suggestions for improvement (optional)
|
||||
|
||||
**Rationale:**
|
||||
- Gradual enforcement allows teams to adopt validation incrementally
|
||||
- CI/CD can fail on errors but allow warnings initially
|
||||
- Info level provides guidance without blocking
|
||||
|
||||
### Validation Rules Hierarchy
|
||||
|
||||
#### Spec Validation Rules
|
||||
```
|
||||
ERROR level:
|
||||
- Missing ## Overview or ## Requirements sections
|
||||
- Invalid heading hierarchy
|
||||
- Malformed requirement/scenario structure
|
||||
|
||||
WARNING level:
|
||||
- Requirements without scenarios
|
||||
- Requirements missing SHALL keyword
|
||||
- Empty overview section
|
||||
|
||||
INFO level:
|
||||
- Very long requirement text (>500 chars)
|
||||
- Scenarios without Given/When/Then structure
|
||||
```
|
||||
|
||||
#### Change Validation Rules
|
||||
```
|
||||
ERROR level:
|
||||
- Missing ## Why or ## What Changes sections
|
||||
- Invalid delta operation types
|
||||
- Malformed delta structure
|
||||
|
||||
WARNING level:
|
||||
- Why section too brief (<50 chars)
|
||||
- Deltas without clear descriptions
|
||||
- Missing requirements in ADDED/MODIFIED
|
||||
|
||||
INFO level:
|
||||
- Very long why section (>1000 chars)
|
||||
- Too many deltas in single change (>10)
|
||||
```
|
||||
|
||||
### Strict Mode
|
||||
- **Default**: Show all levels, fail on ERROR only
|
||||
- **--strict flag**: Fail on both ERROR and WARNING
|
||||
- **Use case**: Gradual quality improvement in CI/CD pipelines
|
||||
|
||||
### Archive Command Safety
|
||||
**Problem:** Invalid specs could be archived, polluting the archive.
|
||||
|
||||
**Solution:**
|
||||
1. Pre-archive validation (default behavior)
|
||||
2. --no-validate flag with safeguards:
|
||||
- Interactive confirmation prompt
|
||||
- Prominent warning message
|
||||
- Console logging with timestamp
|
||||
- Not recommended for CI/CD usage
|
||||
|
||||
**Rationale:**
|
||||
- Protect archive integrity by default
|
||||
- Allow emergency overrides with accountability
|
||||
- Clear audit trail for validation bypasses
|
||||
|
||||
### Validation Report Format
|
||||
```json
|
||||
{
|
||||
"valid": boolean,
|
||||
"issues": [
|
||||
{
|
||||
"level": "ERROR" | "WARNING" | "INFO",
|
||||
"path": "requirements[0].scenarios",
|
||||
"message": "Requirement must have at least one scenario",
|
||||
"line": 15,
|
||||
"column": 0
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"errors": 2,
|
||||
"warnings": 5,
|
||||
"info": 3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Machine-readable for tooling integration
|
||||
- Human-friendly messages
|
||||
- Line/column info for IDE integration
|
||||
- Summary for quick assessment
|
||||
|
||||
### Implementation Strategy
|
||||
1. **Zod schemas with refinements**: Built-in validation in type definitions
|
||||
2. **Custom validators**: Additional business logic validation
|
||||
3. **Composable rules**: Mix and match for different contexts
|
||||
4. **Extensible framework**: Easy to add new rules without refactoring
|
||||
@@ -0,0 +1,22 @@
|
||||
# Change: Add Zod Runtime Validation
|
||||
|
||||
## Why
|
||||
|
||||
While the spec and change commands can output JSON, they currently don't perform strict runtime validation beyond basic structure checking. This can lead to invalid specs or changes being processed, silent failures when required fields are missing, and poor error messages.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Enhance existing `spec validate` and `change validate` commands with strict Zod validation
|
||||
- Add validation to the archive command to ensure changes are valid before applying
|
||||
- Add validation to the diff command to ensure changes are well-formed
|
||||
- Provide detailed validation reports in JSON format
|
||||
- Add `--strict` mode that fails on warnings
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected specs**: cli-spec, cli-change, cli-archive, cli-diff
|
||||
- **Affected code**:
|
||||
- src/commands/spec.ts (enhance validate subcommand)
|
||||
- src/commands/change.ts (enhance validate subcommand)
|
||||
- src/core/archive.ts (add pre-archive validation)
|
||||
- src/core/diff.ts (add validation check)
|
||||
@@ -0,0 +1,18 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Archive Validation
|
||||
|
||||
The archive command SHALL validate changes before applying them to ensure data integrity.
|
||||
|
||||
#### Scenario: Pre-archive validation
|
||||
|
||||
- **WHEN** executing `openspec archive change-name`
|
||||
- **THEN** validate the change structure first
|
||||
- **AND** only proceed if validation passes
|
||||
- **AND** show validation errors if it fails
|
||||
|
||||
#### Scenario: Force archive without validation
|
||||
|
||||
- **WHEN** executing `openspec archive change-name --no-validate`
|
||||
- **THEN** skip validation (unsafe mode)
|
||||
- **AND** show warning about skipping validation
|
||||
@@ -0,0 +1,12 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Diff Command Enhancement
|
||||
|
||||
The diff command SHALL validate change structure before displaying differences.
|
||||
|
||||
#### Scenario: Validate before diff
|
||||
|
||||
- **WHEN** executing `openspec diff change-name`
|
||||
- **THEN** validate change structure
|
||||
- **AND** show validation warnings if present
|
||||
- **AND** continue with diff display
|
||||
@@ -0,0 +1,59 @@
|
||||
# Implementation Tasks (Foundation Phase)
|
||||
|
||||
## 1. Core Schemas
|
||||
- [x] 1.1 Add zod dependency to package.json
|
||||
- [x] 1.2 Create src/core/schemas/base.schema.ts with ScenarioSchema and RequirementSchema
|
||||
- [x] 1.3 Create src/core/schemas/spec.schema.ts with SpecSchema
|
||||
- [x] 1.4 Create src/core/schemas/change.schema.ts with DeltaSchema and ChangeSchema
|
||||
- [x] 1.5 Create src/core/schemas/index.ts to export all schemas
|
||||
|
||||
## 2. Parser Implementation
|
||||
- [x] 2.1 Create src/core/parsers/markdown-parser.ts
|
||||
- [x] 2.2 Implement heading extraction (##, ###, ####)
|
||||
- [x] 2.3 Implement content capture between headings
|
||||
- [x] 2.4 Add tests for parser edge cases
|
||||
|
||||
## 3. Validation Infrastructure
|
||||
- [x] 3.1 Create src/core/validation/types.ts with ValidationLevel, ValidationIssue, ValidationReport types
|
||||
- [x] 3.2 Create src/core/validation/constants.ts with validation rules and thresholds
|
||||
- [x] 3.3 Create src/core/validation/validator.ts with SpecValidator and ChangeValidator classes
|
||||
|
||||
## 4. Enhanced Validation Rules
|
||||
- [x] 4.1 Add RequirementValidation refinements (must have scenarios, must contain SHALL)
|
||||
- [x] 4.2 Add SpecValidation refinements (must have requirements)
|
||||
- [x] 4.3 Add ChangeValidation refinements (must have deltas, why section length)
|
||||
- [x] 4.4 Implement custom error messages for each rule
|
||||
|
||||
## 5. JSON Converter
|
||||
- [x] 5.1 Create src/core/converters/json-converter.ts
|
||||
- [x] 5.2 Implement spec-to-JSON conversion
|
||||
- [x] 5.3 Implement change-to-JSON conversion
|
||||
- [x] 5.4 Add metadata fields (version, format, sourcePath)
|
||||
|
||||
## 6. Archive Command Enhancement
|
||||
- [x] 6.1 Add pre-archive validation check using new validators
|
||||
- [x] 6.2 Add --no-validate flag with required confirmation prompt and warning message: "⚠️ WARNING: Skipping validation may archive invalid specs. Continue? (y/N)"
|
||||
- [x] 6.3 Display validation errors before aborting
|
||||
- [x] 6.4 Log all --no-validate usages to console with timestamp and affected files
|
||||
- [x] 6.5 Add tests for validation scenarios including --no-validate confirmation flow
|
||||
|
||||
## 7. Diff Command Enhancement
|
||||
- [x] 7.1 Add validation check before diff using new validators
|
||||
- [x] 7.2 Show validation warnings (non-blocking)
|
||||
- [x] 7.3 Continue with diff even if warnings present
|
||||
|
||||
## 8. Testing
|
||||
- [x] 8.1 Unit tests for all schemas
|
||||
- [x] 8.2 Unit tests for parser
|
||||
- [x] 8.3 Unit tests for validation rules
|
||||
- [x] 8.4 Integration tests for validation reports
|
||||
- [x] 8.5 Test various invalid spec/change formats
|
||||
- [x] 8.6 Test strict mode behavior
|
||||
- [x] 8.7 Test pre-archive validation
|
||||
- [x] 8.8 Test validation report JSON output
|
||||
|
||||
## 9. Documentation
|
||||
- [x] 9.1 Document schema structure and validation rules (openspec/VALIDATION.md)
|
||||
- [x] 9.2 Update CLI help for archive (document --no-validate flag and its warnings)
|
||||
- [x] 9.3 Update CLI help for diff (document validation warnings behavior)
|
||||
- [x] 9.4 Create migration guide for future command integration (openspec/MIGRATION.md)
|
||||
@@ -0,0 +1,93 @@
|
||||
# Adopt Delta-Based Changes for Specifications
|
||||
|
||||
## Why
|
||||
|
||||
The current approach of storing complete future states in change proposals creates a poor review experience. When reviewing changes on GitHub, reviewers see entire spec files (often 100+ lines) as "added" in green, making it impossible to identify what actually changed. With the recent structured format adoption, we now have clear section boundaries that enable a better approach: storing only additions and modifications.
|
||||
|
||||
## What Changes
|
||||
|
||||
Store only the requirements that actually change, not complete future states:
|
||||
|
||||
- **ADDED Requirements**: New capabilities being introduced
|
||||
- **MODIFIED Requirements**: Existing requirements being changed (must match current header)
|
||||
- **REMOVED Requirements**: Deprecated capabilities
|
||||
- **RENAMED Requirements**: Explicit header changes (e.g., `FROM: Old Name` → `TO: New Name`)
|
||||
|
||||
The archive command will programmatically apply these deltas using normalized header matching (trim leading/trailing whitespace) instead of manually copying entire files.
|
||||
|
||||
## Impact
|
||||
|
||||
**Affected specs**: openspec-conventions, cli-archive, cli-diff
|
||||
|
||||
**Benefits**:
|
||||
- GitHub diffs show only actual changes (25 lines instead of 150+)
|
||||
- Reviewers immediately see what's being added, modified, or removed
|
||||
- Conflicts are more apparent when two changes modify the same requirement
|
||||
- Archive command can programmatically apply changes
|
||||
|
||||
**Format**: Delta format only - all changes must use ADDED/MODIFIED/REMOVED sections.
|
||||
|
||||
## Example
|
||||
|
||||
Instead of storing a 150-line complete future spec, store only:
|
||||
|
||||
```markdown
|
||||
# User Authentication - Changes
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: OAuth Support
|
||||
Users SHALL authenticate via OAuth providers including Google and GitHub.
|
||||
|
||||
#### Scenario: OAuth login flow
|
||||
- **WHEN** user selects OAuth provider
|
||||
- **THEN** redirect to provider authorization
|
||||
- **AND** exchange authorization code for tokens
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Session Management
|
||||
Sessions SHALL expire after 30 minutes of inactivity.
|
||||
|
||||
#### Scenario: Inactive session timeout
|
||||
- **WHEN** no activity for 30 minutes ← (was 60 minutes)
|
||||
- **THEN** invalidate session token
|
||||
- **AND** require re-authentication
|
||||
|
||||
## RENAMED Requirements
|
||||
- FROM: `### Requirement: Basic Authentication`
|
||||
- TO: `### Requirement: Email Authentication`
|
||||
```
|
||||
|
||||
This makes reviews focused and changes explicit.
|
||||
|
||||
## Conflict Resolution
|
||||
|
||||
Git naturally detects conflicts when two changes modify the same requirement header. This is actually better than full-state storage where Git might silently merge incompatible changes.
|
||||
|
||||
## Decisions and Product Guidelines
|
||||
|
||||
To keep the archive flow lean and predictable, the following decisions apply:
|
||||
|
||||
- New spec creation: When a target spec does not exist, auto-generate a minimal skeleton and insert ADDED requirements only. Skeleton format:
|
||||
- `# [Spec Name] Specification`
|
||||
- `## Purpose` with placeholder: "TBD — created by archiving change [change-name]. Update Purpose after archive."
|
||||
- `## Requirements`
|
||||
- If a non-existent spec includes MODIFIED/REMOVED/RENAMED, abort with guidance to create via ADDED-only first.
|
||||
|
||||
- Requirement identification: Match requirements by exact header `### Requirement: [Name]` with trim-only normalization and case-sensitive comparison. Use a requirement-block extractor that preserves the exact header and captures full content (including scenarios) for both main specs and delta files.
|
||||
|
||||
- Application order and atomicity: Apply deltas in order RENAMED → REMOVED → MODIFIED → ADDED. Validate all operations first, apply in-memory, and write each spec once. On any validation failure, abort without writing partial results. An aggregated totals line is displayed across all specs: `Totals: + A, ~ M, - R, → N`.
|
||||
|
||||
- Validation matrix: Enforce that MODIFIED/REMOVED exist; ADDED do not exist; RENAMED FROM exists and TO does not; no duplicates after all operations; and no cross-section conflicts (e.g., same item in MODIFIED and REMOVED). When a rename and modify apply to the same item, MODIFIED must reference the NEW header.
|
||||
|
||||
- Idempotency: Keep v1 simple. Abort on precondition failures (e.g., ADDED already exists) with clear errors. Do not implement no-op detection in v1.
|
||||
|
||||
- Output and UX: For each spec, display operation counts using standard symbols `+ ~ - →`. Optionally include a short aggregated totals line at the end. Keep messages concise and actionable.
|
||||
|
||||
- Error messaging: Standardize messages as `[spec] [operation] failed for header "### Requirement: X" — reason`. On abort, explicitly state: `Aborted. No files were changed.`
|
||||
- Subsections: Any subsections under a requirement (e.g., `#### Scenario: ...`) are preserved verbatim during parsing and application.
|
||||
|
||||
- Backward compatibility: Reject full future-state spec copies for existing specs with guidance to convert to deltas. Allow brand-new specs to be created via ADDED-only deltas using the skeleton above.
|
||||
|
||||
- Dry-run: Deferred for v1 to keep scope minimal.
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# CLI Archive Command - Changes
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Spec Update Process
|
||||
|
||||
Before moving the change to archive, the command SHALL apply delta changes to main specs to reflect the deployed reality.
|
||||
|
||||
#### Scenario: Applying delta changes
|
||||
|
||||
- **WHEN** archiving a change with delta-based specs
|
||||
- **THEN** parse and apply delta changes as defined in openspec-conventions
|
||||
- **AND** validate all operations before applying
|
||||
|
||||
#### Scenario: Validating delta changes
|
||||
|
||||
- **WHEN** processing delta changes
|
||||
- **THEN** perform validations as specified in openspec-conventions
|
||||
- **AND** if validation fails, show specific errors and abort
|
||||
|
||||
#### Scenario: Conflict detection
|
||||
|
||||
- **WHEN** applying deltas would create duplicate requirement headers
|
||||
- **THEN** abort with error message showing the conflict
|
||||
- **AND** suggest manual resolution
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Display Output
|
||||
|
||||
The command SHALL provide clear feedback about delta operations.
|
||||
|
||||
#### Scenario: Showing delta application
|
||||
|
||||
- **WHEN** applying delta changes
|
||||
- **THEN** display for each spec:
|
||||
- Number of requirements added
|
||||
- Number of requirements modified
|
||||
- Number of requirements removed
|
||||
- Number of requirements renamed
|
||||
- **AND** use standard output symbols (+ ~ - →) as defined in openspec-conventions:
|
||||
```
|
||||
Applying changes to specs/user-auth/spec.md:
|
||||
+ 2 added
|
||||
~ 3 modified
|
||||
- 1 removed
|
||||
→ 1 renamed
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
# CLI Diff Command - Changes
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Display Format
|
||||
|
||||
The diff command SHALL display unified diff output in text format.
|
||||
|
||||
**Reason for removal**: The standard unified diff format is replaced by requirement-level side-by-side comparison that better shows semantic changes rather than line-by-line text differences.
|
||||
|
||||
#### Scenario: Unified diff output (deprecated)
|
||||
|
||||
- **WHEN** running `openspec diff <change>`
|
||||
- **THEN** show a unified text diff of files
|
||||
- **AND** include `+`/`-` prefixed lines representing additions and removals
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Diff Output
|
||||
|
||||
The command SHALL show a requirement-level comparison displaying only changed requirements.
|
||||
|
||||
#### Scenario: Side-by-side comparison of changes
|
||||
|
||||
- **WHEN** running `openspec diff <change>`
|
||||
- **THEN** display only requirements that have changed
|
||||
- **AND** show them in a side-by-side format that:
|
||||
- Clearly shows the current version on the left
|
||||
- Shows the future version on the right
|
||||
- Indicates new requirements (not in current)
|
||||
- Indicates removed requirements (not in future)
|
||||
- Aligns modified requirements for easy comparison
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Validation
|
||||
|
||||
The command SHALL validate that changes can be applied successfully.
|
||||
|
||||
#### Scenario: Invalid delta references
|
||||
|
||||
- **WHEN** delta references non-existent requirement
|
||||
- **THEN** show error message with specific requirement
|
||||
- **AND** continue showing other valid changes
|
||||
- **AND** clearly mark failed changes in the output
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
# OpenSpec Conventions - Changes
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Header-Based Requirement Identification
|
||||
|
||||
Requirement headers SHALL serve as unique identifiers for programmatic matching between current specs and proposed changes.
|
||||
|
||||
#### Scenario: Matching requirements programmatically
|
||||
|
||||
- **WHEN** processing delta changes
|
||||
- **THEN** use the `### Requirement: [Name]` header as the unique identifier
|
||||
- **AND** match using normalized headers: `normalize(header) = trim(header)`
|
||||
- **AND** compare headers with case-sensitive equality after normalization
|
||||
|
||||
#### Scenario: Handling requirement renames
|
||||
|
||||
- **WHEN** renaming a requirement
|
||||
- **THEN** use a special `## RENAMED Requirements` section
|
||||
- **AND** specify both old and new names explicitly:
|
||||
```markdown
|
||||
## RENAMED Requirements
|
||||
- FROM: `### Requirement: Old Name`
|
||||
- TO: `### Requirement: New Name`
|
||||
```
|
||||
- **AND** if content also changes, include under MODIFIED using the NEW header
|
||||
|
||||
#### Scenario: Validating header uniqueness
|
||||
|
||||
- **WHEN** creating or modifying requirements
|
||||
- **THEN** ensure no duplicate headers exist within a spec
|
||||
- **AND** validation tools SHALL flag duplicate headers as errors
|
||||
|
||||
### Requirement: Change Storage Convention
|
||||
|
||||
Change proposals SHALL store only the additions, modifications, and removals to specifications, not complete future states.
|
||||
|
||||
#### Scenario: Creating change proposals with additions
|
||||
|
||||
- **WHEN** creating a change proposal that adds new requirements
|
||||
- **THEN** include only the new requirements under `## ADDED Requirements`
|
||||
- **AND** each requirement SHALL include its complete content
|
||||
- **AND** use the standard structured format for requirements and scenarios
|
||||
|
||||
#### Scenario: Creating change proposals with modifications
|
||||
|
||||
- **WHEN** creating a change proposal that modifies existing requirements
|
||||
- **THEN** include the modified requirements under `## MODIFIED Requirements`
|
||||
- **AND** use the same header text as in the current spec (normalized)
|
||||
- **AND** include the complete modified requirement (not a diff)
|
||||
- **AND** optionally annotate what changed with inline comments like `← (was X)`
|
||||
|
||||
#### Scenario: Creating change proposals with removals
|
||||
|
||||
- **WHEN** creating a change proposal that removes requirements
|
||||
- **THEN** list them under `## REMOVED Requirements`
|
||||
- **AND** use the normalized header text for identification
|
||||
- **AND** include reason for removal
|
||||
- **AND** document any migration path if applicable
|
||||
|
||||
|
||||
The `changes/[name]/specs/` directory SHALL contain:
|
||||
- Delta files showing only what changes
|
||||
- Sections for ADDED, MODIFIED, REMOVED, and RENAMED requirements
|
||||
- Normalized header matching for requirement identification
|
||||
- Complete requirements using the structured format
|
||||
- Clear indication of change type for each requirement
|
||||
|
||||
#### Scenario: Using standard output symbols
|
||||
|
||||
- **WHEN** displaying delta operations in CLI output
|
||||
- **THEN** use these standard symbols:
|
||||
- `+` for ADDED (green)
|
||||
- `~` for MODIFIED (yellow)
|
||||
- `-` for REMOVED (red)
|
||||
- `→` for RENAMED (cyan)
|
||||
|
||||
### Requirement: Archive Process Enhancement
|
||||
|
||||
The archive process SHALL programmatically apply delta changes to current specifications using header-based matching.
|
||||
|
||||
#### Scenario: Archiving changes with deltas
|
||||
|
||||
- **WHEN** archiving a completed change
|
||||
- **THEN** the archive command SHALL:
|
||||
1. Parse RENAMED sections first and apply renames
|
||||
2. Parse REMOVED sections and remove by normalized header match
|
||||
3. Parse MODIFIED sections and replace by normalized header match (using new names if renamed)
|
||||
4. Parse ADDED sections and append new requirements
|
||||
- **AND** validate that all MODIFIED/REMOVED headers exist in current spec
|
||||
- **AND** validate that ADDED headers don't already exist
|
||||
- **AND** generate the updated spec in the main specs/ directory
|
||||
|
||||
#### Scenario: Handling conflicts during archive
|
||||
|
||||
- **WHEN** delta changes conflict with current spec state
|
||||
- **THEN** the archive command SHALL report specific conflicts
|
||||
- **AND** require manual resolution before proceeding
|
||||
- **AND** provide clear guidance on resolving conflicts
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Update Conventions
|
||||
- [x] 1.1 Update openspec-conventions spec with delta-based approach
|
||||
- [x] 1.2 Add Header-Based Requirement Identification
|
||||
- [x] 1.3 Define ADDED/MODIFIED/REMOVED/RENAMED sections
|
||||
- [x] 1.4 Document standard output symbols (+ ~ - →)
|
||||
- [x] 1.5 Update openspec/README.md with delta-based conventions
|
||||
- [x] 1.6 Update examples to use delta format
|
||||
|
||||
## 2. Update Diff Command
|
||||
- [ ] 2.1 Update cli-diff spec with requirement-level comparison
|
||||
- [ ] 2.2 Parse specs into requirement-level structures
|
||||
- [ ] 2.3 Apply deltas to generate future state
|
||||
- [ ] 2.4 Implement side-by-side comparison view (changes only)
|
||||
- [ ] 2.5 Add tests for requirement-level comparison
|
||||
- [ ] 2.6 Add tests for side-by-side view formatting
|
||||
|
||||
## 3. Update Archive Command
|
||||
- [x] 3.1 Update cli-archive spec with delta processing behavior
|
||||
- [x] 3.2 Implement requirement-block extractor that preserves exact headers (`### Requirement: [Name]`) and captures full content (including scenarios)
|
||||
- [x] 3.3 Implement normalized header matching (trim-only, case-sensitive)
|
||||
- [x] 3.4 Parse delta sections (ADDED/MODIFIED/REMOVED/RENAMED)
|
||||
- [x] 3.5 New spec creation when target spec does not exist
|
||||
- [x] 3.5.1 Auto-generate minimal skeleton: `# [Spec Name] Specification`, `## Purpose` placeholder, `## Requirements`
|
||||
- [x] 3.5.2 Allow only ADDED operations for non-existent specs; abort if MODIFIED/REMOVED/RENAMED present
|
||||
- [x] 3.6 Apply changes in order: RENAMED → REMOVED → MODIFIED → ADDED
|
||||
- [x] 3.7 Validation and conflict checks
|
||||
- [x] 3.7.1 MODIFIED/REMOVED requirements exist (after applying rename mappings)
|
||||
- [x] 3.7.2 ADDED requirements don't already exist (consider post-rename state)
|
||||
- [x] 3.7.3 RENAMED FROM headers exist; TO headers don't (including collisions with ADDED)
|
||||
- [x] 3.7.4 No duplicate headers within specs after all operations
|
||||
- [x] 3.7.5 Detect cross-section conflicts (e.g., same requirement in MODIFIED and REMOVED)
|
||||
- [x] 3.7.6 When a rename exists, require MODIFIED to reference the NEW header
|
||||
- [x] 3.8 Atomic updates
|
||||
- [x] 3.8.1 Validate all deltas first; stage updates in-memory per spec
|
||||
- [x] 3.8.2 Single write per spec; abort entire archive on any validation failure (no partial writes)
|
||||
- [x] 3.9 Output and error messaging
|
||||
- [x] 3.9.1 Display per-spec operation counts with symbols: `+` added, `~` modified, `-` removed, `→` renamed
|
||||
- [x] 3.9.2 Optionally display an aggregated totals line across all specs
|
||||
- [x] 3.9.3 Standardize error message format: `[spec] [operation] failed for header "### Requirement: X" — reason`; end with `Aborted. No files were changed.` on failure
|
||||
- [x] 3.10 Idempotency behavior (v1): abort on precondition failures (e.g., ADDED already exists); do not implement no-op detection
|
||||
- [x] 3.11 Tests
|
||||
- [x] 3.11.1 Header normalization (trim-only) matching
|
||||
- [x] 3.11.2 Apply in correct order (RENAMED → REMOVED → MODIFIED → ADDED)
|
||||
- [x] 3.11.3 Validation edge cases (missing headers, duplicates, rename collisions, conflicting sections)
|
||||
- [x] 3.11.4 Rename + modify interplay (MODIFIED uses new header)
|
||||
- [x] 3.11.5 New spec creation via skeleton
|
||||
- [x] 3.11.6 Multi-spec mixed operations with independent validation and write
|
||||
|
||||
## Notes
|
||||
- Archive command is critical path - must work reliably
|
||||
- All new changes must use delta format
|
||||
- Header normalization: normalize(header) = trim(header)
|
||||
- Diff command shows only changed requirements in side-by-side comparison
|
||||
@@ -0,0 +1,19 @@
|
||||
# Design: Verb–Noun CLI Structure Adoption
|
||||
|
||||
## Overview
|
||||
We will make verb commands (`list`, `show`, `validate`, `diff`, `archive`) the primary interface and keep noun commands (`spec`, `change`) as deprecated aliases for one release.
|
||||
|
||||
## Decisions
|
||||
|
||||
1. Keep routing centralized in `src/cli/index.ts`.
|
||||
2. Add `--specs`/`--changes` to `openspec list`, with `--changes` as default.
|
||||
3. Show deprecation warnings for `openspec change list` and, more generally, for any `openspec change ...` and `openspec spec ...` subcommands.
|
||||
4. Do not change `show`/`validate` behavior beyond help text; they already support `--type` for disambiguation.
|
||||
|
||||
## Backward Compatibility
|
||||
All noun-based commands continue to work with clear deprecation warnings directing users to verb-first equivalents.
|
||||
|
||||
## Out of Scope
|
||||
JSON output parity for `openspec list` across modes and `show --specs/--changes` discovery are follow-ups.
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Change: Adopt Verb–Noun CLI Structure (Deprecate Noun-Based Commands)
|
||||
|
||||
## Why
|
||||
|
||||
Most widely used CLIs (git, docker, kubectl) start with an action (verb) followed by the object (noun). This matches how users think: “do X to Y”. Using verbs as top-level commands improves clarity, discoverability, and extensibility.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Promote top-level verb commands as primary entry points: `list`, `show`, `validate`, `diff`, `archive`.
|
||||
- Deprecate noun-based top-level commands: `openspec spec ...` and `openspec change ...`.
|
||||
- Introduce consistent noun scoping via flags where applicable (e.g., `--changes`, `--specs`) and keep smart defaults.
|
||||
- Clarify disambiguation for `show` and `validate` when names collide.
|
||||
|
||||
### Mappings (From → To)
|
||||
|
||||
- **List**
|
||||
- From: `openspec change list`
|
||||
- To: `openspec list --changes` (default), or `openspec list --specs`
|
||||
|
||||
- **Show**
|
||||
- From: `openspec spec show <spec-id>` / `openspec change show <change-id>`
|
||||
- To: `openspec show <item-id>` with auto-detect, use `--type spec|change` if ambiguous
|
||||
|
||||
- **Validate**
|
||||
- From: `openspec spec validate <spec-id>` / `openspec change validate <change-id>`
|
||||
- To: `openspec validate <item-id> --type spec|change`, or bulk: `openspec validate --specs` / `--changes` / `--all`
|
||||
|
||||
### Backward Compatibility
|
||||
|
||||
- Keep `openspec spec` and `openspec change` available with deprecation warnings for one release cycle.
|
||||
- Update help text to point users to the verb–noun alternatives.
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected specs**:
|
||||
- `cli-list`: Add support for `--specs` and explicit `--changes` (default remains changes)
|
||||
- `openspec-conventions`: Add explicit requirement establishing verb–noun CLI design and deprecation guidance
|
||||
- **Affected code**:
|
||||
- `src/cli/index.ts`: Un-deprecate top-level `list`; mark `change list` as deprecated; ensure help text and warnings align
|
||||
- `src/core/list.ts`: Support listing specs via `--specs` and default to changes; shared output shape
|
||||
- Optional follow-ups: tighten `show`/`validate` help and ambiguity handling
|
||||
|
||||
## Explicit Changes
|
||||
|
||||
**CLI Design**
|
||||
- From: Mixed model with nouns (`spec`, `change`) and some top-level verbs; `openspec list` currently deprecated
|
||||
- To: Verbs as primary: `openspec list|show|validate|diff|archive`; nouns scoped via flags or item ids; noun commands deprecated
|
||||
- Reason: Align with common CLIs; improve UX; simpler mental model
|
||||
- Impact: Non-breaking with deprecation period; users migrate incrementally
|
||||
|
||||
**Listing Behavior**
|
||||
- From: `openspec change list` (primary), `openspec list` (deprecated)
|
||||
- To: `openspec list` as primary, defaulting to `--changes`; add `--specs` to list specs
|
||||
- Reason: Consistent verb–noun style; better discoverability
|
||||
- Impact: New option; preserves existing behavior via default
|
||||
|
||||
## Rollout and Deprecation Policy
|
||||
|
||||
- Show deprecation warnings on noun-based commands for one release.
|
||||
- Document new usage in `openspec/README.md` and CLI help.
|
||||
- After one release, consider removing noun-based commands, or keep as thin aliases without warnings.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should `show` also accept `--changes`/`--specs` for discovery without an id? (Out of scope here; current auto-detect and `--type` remain.)
|
||||
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
# Delta: CLI List Command
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Command Execution
|
||||
The command SHALL scan and analyze either active changes or specs based on the selected mode.
|
||||
|
||||
#### Scenario: Scanning for changes (default)
|
||||
- **WHEN** `openspec list` is executed without flags
|
||||
- **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
|
||||
|
||||
#### Scenario: Scanning for specs
|
||||
- **WHEN** `openspec list --specs` is executed
|
||||
- **THEN** scan the `openspec/specs/` directory for capabilities
|
||||
- **AND** read each capability's `spec.md`
|
||||
- **AND** parse requirements to compute requirement counts
|
||||
|
||||
### Requirement: Output Format
|
||||
The command SHALL display items in a clear, readable table format with mode-appropriate progress or counts.
|
||||
|
||||
#### Scenario: Displaying change list (default)
|
||||
- **WHEN** displaying the list of changes
|
||||
- **THEN** show a table with columns:
|
||||
- Change name (directory name)
|
||||
- Task progress (e.g., "3/5 tasks" or "✓ Complete")
|
||||
|
||||
#### Scenario: Displaying spec list
|
||||
- **WHEN** displaying the list of specs
|
||||
- **THEN** show a table with columns:
|
||||
- Spec id (directory name)
|
||||
- Requirement count (e.g., "requirements 12")
|
||||
|
||||
### Requirement: Empty State
|
||||
The command SHALL provide clear feedback when no items are present for the selected mode.
|
||||
|
||||
#### Scenario: Handling empty state (changes)
|
||||
- **WHEN** no active changes exist (only archive/ or empty changes/)
|
||||
- **THEN** display: "No active changes found."
|
||||
|
||||
#### Scenario: Handling empty state (specs)
|
||||
- **WHEN** no specs directory exists or contains no capabilities
|
||||
- **THEN** display: "No specs found."
|
||||
|
||||
### Requirement: Flags
|
||||
The command SHALL accept flags to select the noun being listed.
|
||||
|
||||
#### Scenario: Selecting specs
|
||||
- **WHEN** `--specs` is provided
|
||||
- **THEN** list specs instead of changes
|
||||
|
||||
#### Scenario: Selecting changes
|
||||
- **WHEN** `--changes` is provided
|
||||
- **THEN** list changes explicitly (same as default behavior)
|
||||
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# Delta: OpenSpec Conventions — Verb–Noun CLI Design
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Verb–Noun CLI Command Structure
|
||||
OpenSpec CLI design SHALL use verbs as top-level commands with nouns provided as arguments or flags for scoping.
|
||||
|
||||
#### Scenario: Verb-first command discovery
|
||||
- **WHEN** a user runs a command like `openspec list`
|
||||
- **THEN** the verb communicates the action clearly
|
||||
- **AND** nouns refine scope via flags or arguments (e.g., `--changes`, `--specs`)
|
||||
|
||||
#### Scenario: Backward compatibility for noun commands
|
||||
- **WHEN** users run noun-prefixed commands such as `openspec spec ...` or `openspec change ...`
|
||||
- **THEN** the CLI SHALL continue to support them for at least one release
|
||||
- **AND** display a deprecation warning that points to verb-first alternatives
|
||||
|
||||
#### Scenario: Disambiguation guidance
|
||||
- **WHEN** item names are ambiguous between changes and specs
|
||||
- **THEN** `openspec show` and `openspec validate` SHALL accept `--type spec|change`
|
||||
- **AND** the help text SHALL document this clearly
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. CLI Behavior and Help
|
||||
- [x] 1.1 Un-deprecate top-level `openspec list`; mark `change list` as deprecated with warning that points to `openspec list`
|
||||
- [x] 1.2 Add support to list specs via `openspec list --specs` and keep `--changes` as default
|
||||
- [x] 1.3 Update command descriptions and `--help` output to emphasize verb–noun pattern
|
||||
- [x] 1.4 Keep `openspec spec ...` and `openspec change ...` commands working but print deprecation notices
|
||||
|
||||
## 2. Core List Logic
|
||||
- [x] 2.1 Extend `src/core/list.ts` to accept a mode: `changes` (default) or `specs`
|
||||
- [x] 2.2 Implement `specs` listing: scan `openspec/specs/*/spec.md`, compute requirement count via parser, format output consistently
|
||||
- [x] 2.3 Share output structure for both modes; preserve current text table; ensure JSON parity in future change
|
||||
|
||||
## 3. Specs and Conventions
|
||||
- [x] 3.1 Update `openspec/specs/cli-list/spec.md` to document `--specs` (and default to changes)
|
||||
- [x] 3.2 Update `openspec/specs/openspec-conventions/spec.md` with a requirement for verb–noun CLI design and deprecation guidance
|
||||
|
||||
## 4. Tests and Docs
|
||||
- [x] 4.1 Update tests: ensure `openspec list` works for changes and specs; keep `change list` tests but assert warning
|
||||
- [ ] 4.2 Update README and any usage docs to show new primary commands
|
||||
- [ ] 4.3 Add migration notes in repo CHANGELOG or README
|
||||
|
||||
## 5. Follow-ups (Optional, not in this change)
|
||||
- [ ] 5.1 Consider `openspec show --specs/--changes` for discovery without ids
|
||||
- [ ] 5.2 Consider JSON output for `openspec list` with `--json` for both modes
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
## Why
|
||||
|
||||
Currently, users must validate changes and specs individually by specifying each ID. This creates friction when:
|
||||
- Teams want to validate all changes/specs before a release
|
||||
- Developers need to ensure consistency across multiple related changes
|
||||
- Users run validation commands without arguments and receive errors instead of helpful guidance
|
||||
- The subcommand structure requires users to know in advance whether they're validating a change or spec
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add new top-level `validate` command with intuitive flags (--all, --changes, --specs)
|
||||
- Enhance existing `change validate` and `spec validate` to support interactive selection (backwards compatibility)
|
||||
- Interactive selection by default when no arguments provided
|
||||
- Support direct item validation: `openspec validate <item>` with automatic type detection
|
||||
|
||||
## Impact
|
||||
|
||||
- New specs to create: cli-validate
|
||||
- Specs to enhance: cli-change, cli-spec (for backwards compatibility)
|
||||
- Affected code: src/cli/index.ts, src/commands/validate.ts (new), src/commands/spec.ts, src/commands/change.ts
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
# CLI Change Command Spec
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Interactive validation selection
|
||||
|
||||
The change validate command SHALL support interactive selection when no change name is provided.
|
||||
|
||||
#### Scenario: Interactive change selection for validation
|
||||
|
||||
- **WHEN** executing `openspec change validate` without arguments
|
||||
- **THEN** display an interactive list of available changes
|
||||
- **AND** allow the user to select a change to validate
|
||||
- **AND** validate the selected change
|
||||
|
||||
#### Scenario: Non-interactive fallback keeps current behavior
|
||||
|
||||
- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
|
||||
- **WHEN** executing `openspec change validate` without a change name
|
||||
- **THEN** do not prompt interactively
|
||||
- **AND** print the existing hint including available change IDs
|
||||
- **AND** set `process.exitCode = 1`
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# CLI Spec Command Spec
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Interactive spec validation
|
||||
|
||||
The spec validate command SHALL support interactive selection when no spec-id is provided.
|
||||
|
||||
#### Scenario: Interactive spec selection for validation
|
||||
|
||||
- **WHEN** executing `openspec spec validate` without arguments
|
||||
- **THEN** display an interactive list of available specs
|
||||
- **AND** allow the user to select a spec to validate
|
||||
- **AND** validate the selected spec
|
||||
- **AND** maintain all existing validation options (--strict, --json)
|
||||
|
||||
#### Scenario: Non-interactive fallback keeps current behavior
|
||||
|
||||
- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
|
||||
- **WHEN** executing `openspec spec validate` without a spec-id
|
||||
- **THEN** do not prompt interactively
|
||||
- **AND** print the existing error message for missing spec-id
|
||||
- **AND** set non-zero exit code
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
# CLI Validate Command Spec
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Top-level validate command
|
||||
|
||||
The CLI SHALL provide a top-level `validate` command for validating changes and specs with flexible selection options.
|
||||
|
||||
#### Scenario: Interactive validation selection
|
||||
|
||||
- **WHEN** executing `openspec validate` without arguments
|
||||
- **THEN** prompt user to select what to validate (all, changes, specs, or specific item)
|
||||
- **AND** perform validation based on selection
|
||||
- **AND** display results with appropriate formatting
|
||||
|
||||
#### Scenario: Non-interactive environments do not prompt
|
||||
|
||||
- **GIVEN** stdin is not a TTY or `--no-interactive` is provided or environment variable `OPEN_SPEC_INTERACTIVE=0`
|
||||
- **WHEN** executing `openspec validate` without arguments
|
||||
- **THEN** do not prompt interactively
|
||||
- **AND** print a helpful hint listing available commands/flags and exit with code 1
|
||||
|
||||
#### Scenario: Direct item validation
|
||||
|
||||
- **WHEN** executing `openspec validate <item-name>`
|
||||
- **THEN** automatically detect if item is a change or spec
|
||||
- **AND** validate the specified item
|
||||
- **AND** display validation results
|
||||
|
||||
### Requirement: Bulk and filtered validation
|
||||
|
||||
The validate command SHALL support flags for bulk validation (--all) and filtered validation by type (--changes, --specs).
|
||||
|
||||
#### Scenario: Validate everything
|
||||
|
||||
- **WHEN** executing `openspec validate --all`
|
||||
- **THEN** validate all changes in openspec/changes/ (excluding archive)
|
||||
- **AND** validate all specs in openspec/specs/
|
||||
- **AND** display a summary showing passed/failed items
|
||||
- **AND** exit with code 1 if any validation fails
|
||||
|
||||
#### Scenario: Scope of bulk validation
|
||||
|
||||
- **WHEN** validating with `--all` or `--changes`
|
||||
- **THEN** include all change proposals under `openspec/changes/`
|
||||
- **AND** exclude the `openspec/changes/archive/` directory
|
||||
|
||||
- **WHEN** validating with `--specs`
|
||||
- **THEN** include all specs that have a `spec.md` under `openspec/specs/<id>/spec.md`
|
||||
|
||||
#### Scenario: Validate all changes
|
||||
|
||||
- **WHEN** executing `openspec validate --changes`
|
||||
- **THEN** validate all changes in openspec/changes/ (excluding archive)
|
||||
- **AND** display results for each change
|
||||
- **AND** show summary statistics
|
||||
|
||||
#### Scenario: Validate all specs
|
||||
|
||||
- **WHEN** executing `openspec validate --specs`
|
||||
- **THEN** validate all specs in openspec/specs/
|
||||
- **AND** display results for each spec
|
||||
- **AND** show summary statistics
|
||||
|
||||
### Requirement: Validation options and progress indication
|
||||
|
||||
The validate command SHALL support standard validation options (--strict, --json) and display progress during bulk operations.
|
||||
|
||||
#### Scenario: Strict validation
|
||||
|
||||
- **WHEN** executing `openspec validate --all --strict`
|
||||
- **THEN** apply strict validation to all items
|
||||
- **AND** treat warnings as errors
|
||||
- **AND** fail if any item has warnings or errors
|
||||
|
||||
#### Scenario: JSON output
|
||||
|
||||
- **WHEN** executing `openspec validate --all --json`
|
||||
- **THEN** output validation results as JSON
|
||||
- **AND** include detailed issues for each item
|
||||
- **AND** include summary statistics
|
||||
|
||||
#### Scenario: JSON output schema for bulk validation
|
||||
|
||||
- **WHEN** executing `openspec validate --all --json` (or `--changes` / `--specs`)
|
||||
- **THEN** output a JSON object with the following shape:
|
||||
- `items`: Array of objects with fields `{ id: string, type: "change"|"spec", valid: boolean, issues: Issue[], durationMs: number }`
|
||||
- `summary`: Object `{ totals: { items: number, passed: number, failed: number }, byType: { change?: { items: number, passed: number, failed: number }, spec?: { items: number, passed: number, failed: number } } }`
|
||||
- `version`: String identifier for the schema (e.g., `"1.0"`)
|
||||
- **AND** exit with code 1 if any `items[].valid === false`
|
||||
|
||||
Where `Issue` follows the existing per-item validation report shape `{ level: "ERROR"|"WARNING"|"INFO", path: string, message: string }`.
|
||||
|
||||
#### Scenario: Show validation progress
|
||||
|
||||
- **WHEN** validating multiple items (--all, --changes, or --specs)
|
||||
- **THEN** show progress indicator or status updates
|
||||
- **AND** indicate which item is currently being validated
|
||||
- **AND** display running count of passed/failed items
|
||||
|
||||
#### Scenario: Concurrency limits for performance
|
||||
|
||||
- **WHEN** validating multiple items
|
||||
- **THEN** run validations with a bounded concurrency (e.g., 4–8 in parallel)
|
||||
- **AND** ensure progress indicators remain responsive
|
||||
|
||||
### Requirement: Item type detection and ambiguity handling
|
||||
|
||||
The validate command SHALL handle ambiguous names and explicit type overrides to ensure clear, deterministic behavior.
|
||||
|
||||
#### Scenario: Direct item validation with automatic type detection
|
||||
|
||||
- **WHEN** executing `openspec validate <item-name>`
|
||||
- **THEN** if `<item-name>` uniquely matches a change or a spec, validate that item
|
||||
|
||||
#### Scenario: Ambiguity between change and spec names
|
||||
|
||||
- **GIVEN** `<item-name>` exists both as a change and as a spec
|
||||
- **WHEN** executing `openspec validate <item-name>`
|
||||
- **THEN** print an ambiguity error explaining both matches
|
||||
- **AND** suggest passing `--type change` or `--type spec`, or using `openspec change validate` / `openspec spec validate`
|
||||
- **AND** exit with code 1 without performing validation
|
||||
|
||||
#### Scenario: Unknown item name
|
||||
|
||||
- **WHEN** the `<item-name>` matches neither a change nor a spec
|
||||
- **THEN** print a not-found error
|
||||
- **AND** show nearest-match suggestions when available
|
||||
- **AND** exit with code 1
|
||||
|
||||
#### Scenario: Explicit type override
|
||||
|
||||
- **WHEN** executing `openspec validate --type change <item>`
|
||||
- **THEN** treat `<item>` as a change ID and validate it (skipping auto-detection)
|
||||
|
||||
- **WHEN** executing `openspec validate --type spec <item>`
|
||||
- **THEN** treat `<item>` as a spec ID and validate it (skipping auto-detection)
|
||||
|
||||
### Requirement: Interactivity controls
|
||||
|
||||
- The CLI SHALL respect `--no-interactive` to disable prompts.
|
||||
- The CLI SHALL respect `OPEN_SPEC_INTERACTIVE=0` to disable prompts globally.
|
||||
- Interactive prompts SHALL only be shown when stdin is a TTY and interactivity is not disabled.
|
||||
|
||||
#### Scenario: Disabling prompts via flags or environment
|
||||
|
||||
- **WHEN** `openspec validate` is executed with `--no-interactive` or with environment `OPEN_SPEC_INTERACTIVE=0`
|
||||
- **THEN** the CLI SHALL not display interactive prompts
|
||||
- **AND** SHALL print non-interactive hints or chosen outputs as appropriate
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user