mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-04 06:18:24 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a079c4b483 | ||
|
|
344b87a18f | ||
|
|
b642398bf3 | ||
|
|
ff506c347a | ||
|
|
1cdf0410df | ||
|
|
d5c824d4cd | ||
|
|
849ae2a976 | ||
|
|
f510581b6c | ||
|
|
7c3acccaf7 | ||
|
|
435458be56 | ||
|
|
76c80f80f3 | ||
|
|
0ca74762dc | ||
|
|
e6d81ba0f6 | ||
|
|
2d189ce5e0 | ||
|
|
44e4beeee8 | ||
|
|
a974c67986 | ||
|
|
485c97e97d | ||
|
|
347f0277e3 | ||
|
|
cb9641a450 | ||
|
|
342ed43e69 | ||
|
|
3c7a05c5dc | ||
|
|
d1f3861d9e | ||
|
|
7a39e887bb | ||
|
|
18c445a48d | ||
|
|
900174000b | ||
|
|
f529b25968 | ||
|
|
93f7b797cf | ||
|
|
7d07101363 | ||
|
|
c0f29044f9 | ||
|
|
7fe45ca330 | ||
|
|
c8e2072e3a | ||
|
|
cd5e49346f | ||
|
|
a18d992fa1 | ||
|
|
4df6a4889b | ||
|
|
9b5007dbc3 | ||
|
|
cce787ec40 | ||
|
|
94d651de8c | ||
|
|
040e382d64 | ||
|
|
caafd7c9bf | ||
|
|
144528257d | ||
|
|
af0b3418d0 | ||
|
|
7fd5417ed0 | ||
|
|
5ac1e12b83 | ||
|
|
fd7ad273c7 | ||
|
|
ea6f380fea | ||
|
|
765df47ad3 | ||
|
|
64d476f8b9 | ||
|
|
afdca0d5da | ||
|
|
61eb999f7c | ||
|
|
3d3bf96061 | ||
|
|
d199dfa407 | ||
|
|
d7d186088e | ||
|
|
6a3a1263fe | ||
|
|
1e94443a35 | ||
|
|
a0608d0bab | ||
|
|
e4c32dbe07 | ||
|
|
2d4c98e196 | ||
|
|
be6659cd39 | ||
|
|
4ba26902df | ||
|
|
5fd8e9d66c | ||
|
|
4108563731 | ||
|
|
fbef555041 | ||
|
|
92731e2263 | ||
|
|
c574e7992d | ||
|
|
62d4391268 | ||
|
|
4573c28048 | ||
|
|
0541f93ddd | ||
|
|
be51bcbc6a | ||
|
|
1d34e72f10 | ||
|
|
36fbc898da | ||
|
|
afb73cf9ec | ||
|
|
697738bc9b | ||
|
|
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 |
@@ -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,2 @@
|
||||
---
|
||||
---
|
||||
@@ -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 @@
|
||||
---
|
||||
"@fission-ai/openspec": minor
|
||||
---
|
||||
|
||||
### New Features
|
||||
|
||||
- **Kimi CLI support** — OpenSpec can now initialize Kimi CLI as a supported skills-only tool using `.kimi/skills/`
|
||||
|
||||
### Other
|
||||
|
||||
- Added Kimi-specific docs and init coverage aligned with skill-based `/skill:openspec-*` usage
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@fission-ai/openspec": minor
|
||||
---
|
||||
|
||||
### New Features
|
||||
|
||||
- Include the sync workflow in the default core profile so new installs generate `/opsx:sync` skills and commands by default.
|
||||
@@ -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,326 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
merge_group:
|
||||
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' || github.event_name == 'merge_group'
|
||||
|
||||
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 == 'push'
|
||||
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' || github.event_name == 'merge_group'
|
||||
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' || github.event_name == 'merge_group')
|
||||
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 == 'push'
|
||||
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)
|
||||
+16
-3
@@ -140,9 +140,22 @@ dist/
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
|
||||
# Internal Docs
|
||||
docs/
|
||||
|
||||
# Claude
|
||||
.claude/
|
||||
CLAUDE.md
|
||||
CLAUDE.md
|
||||
.DS_Store
|
||||
|
||||
# Pnpm
|
||||
.pnpm-store/
|
||||
result
|
||||
|
||||
# OpenCode
|
||||
.opencode/
|
||||
opencode.json
|
||||
|
||||
# Codex
|
||||
.codex/
|
||||
|
||||
# Bob
|
||||
.bob/
|
||||
|
||||
+553
@@ -0,0 +1,553 @@
|
||||
# @fission-ai/openspec
|
||||
|
||||
## 1.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#995](https://github.com/Fission-AI/OpenSpec/pull/995) [`d1f3861`](https://github.com/Fission-AI/OpenSpec/commit/d1f3861d9ec694cc924b042b5da01963dcf93137) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- **Canonical artifact paths** — Workflow artifact paths are now resolved via the native `realpath`, so symlinks and case-insensitive filesystems no longer cause path mismatches during apply and archive.
|
||||
- **Glob apply instructions** — Apply instructions with glob artifact outputs now resolve correctly, and literal artifact outputs are enforced to be file paths.
|
||||
- **Hidden main spec requirements** — Requirements nested inside fenced code blocks or otherwise hidden in main specs are now detected during validation.
|
||||
- **Clean `--json` output** — Spinner progress text no longer leaks into stderr when `--json` is passed, so AI agents that combine stdout and stderr can parse the JSON reliably.
|
||||
- **Silent telemetry in firewalled environments** — PostHog network errors are now swallowed with a 1s timeout and retries/remote config disabled, so OpenSpec no longer surfaces `PostHogFetchNetworkError` in locked-down networks. Telemetry opt-out is documented earlier in the README, installation guide, and CLI reference.
|
||||
|
||||
## 1.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#952](https://github.com/Fission-AI/OpenSpec/pull/952) [`cce787e`](https://github.com/Fission-AI/OpenSpec/commit/cce787ec4083da2b27781f6786f5ce0002909a7b) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
|
||||
|
||||
- **Junie support** — Added tool and command generation for JetBrains Junie
|
||||
- **Lingma IDE support** — Added configuration support for Lingma IDE
|
||||
- **ForgeCode support** — Added tool support for ForgeCode
|
||||
- **IBM Bob support** — Added support for IBM Bob coding assistant
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **Shell completions opt-in** — Completion install is now opt-in, fixing PowerShell encoding corruption
|
||||
- **Copilot auto-detection** — Prevented false GitHub Copilot detection from a bare `.github/` directory
|
||||
- **pi.dev command generation** — Fixed command reference transforms and template argument passing
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#760](https://github.com/Fission-AI/OpenSpec/pull/760) [`61eb999`](https://github.com/Fission-AI/OpenSpec/commit/61eb999f7c6c0fc98d2e7f3678756fce6a3f4378) Thanks [@fsilvaortiz](https://github.com/fsilvaortiz)! - fix: OpenCode adapter now uses `.opencode/commands/` (plural) to match OpenCode's official directory convention. Fixes #748.
|
||||
|
||||
- [#759](https://github.com/Fission-AI/OpenSpec/pull/759) [`afdca0d`](https://github.com/Fission-AI/OpenSpec/commit/afdca0d5dab1aa109cfd8848b2512333ccad60c3) Thanks [@fsilvaortiz](https://github.com/fsilvaortiz)! - fix: `openspec status` now exits gracefully when no changes exist instead of throwing a fatal error. Fixes #714.
|
||||
|
||||
## 1.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#747](https://github.com/Fission-AI/OpenSpec/pull/747) [`1e94443`](https://github.com/Fission-AI/OpenSpec/commit/1e94443a3551b228eecbc89e95d96d3b9600a192) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
|
||||
|
||||
- **Profile system** — Choose between `core` (4 essential workflows) and `custom` (pick any subset) profiles to control which skills get installed. Manage profiles with the new `openspec config profile` command
|
||||
- **Propose workflow** — New one-step workflow creates a complete change proposal with design, specs, and tasks from a single request — no need to run `new` then `ff` separately
|
||||
- **AI tool auto-detection** — `openspec init` now scans your project for existing tool directories (`.claude/`, `.cursor/`, etc.) and pre-selects detected tools
|
||||
- **Pi (pi.dev) support** — Pi coding agent is now a supported tool with prompt and skill generation
|
||||
- **Kiro support** — AWS Kiro IDE is now a supported tool with prompt and skill generation
|
||||
- **Sync prunes deselected workflows** — `openspec update` now removes command files and skill directories for workflows you've deselected, keeping your project clean
|
||||
- **Config drift warning** — `openspec config list` warns when global config is out of sync with the current project
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed onboard preflight giving a false "not initialized" error on freshly initialized projects
|
||||
- Fixed archive workflow stopping mid-way when syncing — it now properly resumes after sync completes
|
||||
- Added Windows PowerShell alternatives for onboard shell commands
|
||||
|
||||
## 1.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#627](https://github.com/Fission-AI/OpenSpec/pull/627) [`afb73cf`](https://github.com/Fission-AI/OpenSpec/commit/afb73cf9ec59c6f8b26d0c538c0218c203ba3c56) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- **OpenCode command references** — Command references in generated files now use the correct `/opsx-` hyphen format instead of `/opsx:` colon format, ensuring commands work properly in OpenCode
|
||||
|
||||
## 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 |
|
||||
@@ -1,343 +0,0 @@
|
||||
# Comprehensive Retrospective: Creating an OpenSpec Change Proposal
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document consolidates learnings from creating the `bulk-validation-interactive-selection` change proposal for OpenSpec. The process revealed critical gaps in documentation, unhelpful error messages, and areas where the system could be more user-friendly. While OpenSpec's core functionality works correctly, the user experience for creating changes needs significant improvement.
|
||||
|
||||
## Table of Contents
|
||||
1. [Errors Encountered](#errors-encountered)
|
||||
2. [System Issues vs User Errors](#system-issues-vs-user-errors)
|
||||
3. [Documentation Gaps Analysis](#documentation-gaps-analysis)
|
||||
4. [Key Learnings](#key-learnings)
|
||||
5. [Recommendations](#recommendations)
|
||||
6. [Conclusion](#conclusion)
|
||||
|
||||
---
|
||||
|
||||
## Errors Encountered
|
||||
|
||||
### Error 1: Misunderstanding Delta Structure
|
||||
**Error Message:** `✗ [ERROR] deltas: Change must have at least one delta`
|
||||
|
||||
**What Happened:**
|
||||
Initially attempted to define deltas directly in the `proposal.md` file using markdown sections like:
|
||||
```markdown
|
||||
### Delta: Add validate-all command
|
||||
**Type**: Feature addition
|
||||
**Effort**: Small (< 100 lines)
|
||||
```
|
||||
|
||||
**Root Cause:**
|
||||
Fundamental misunderstanding of how OpenSpec processes deltas. Deltas are derived from spec files in the change's `specs/` directory, not from the proposal itself.
|
||||
|
||||
**Discovery Process:**
|
||||
- Examined `ChangeParser` class in `/src/core/parsers/change-parser.ts`
|
||||
- Found that `parseDeltaSpecs()` method looks for spec files in `specs/` subdirectory
|
||||
- Learned that deltas are extracted by comparing spec files against existing specs
|
||||
|
||||
### Error 2: Missing Operation Prefix in Section Headers
|
||||
**Error Message:** `✗ [ERROR] deltas: Change must have at least one delta`
|
||||
|
||||
**What Happened:**
|
||||
Created new spec files with standard `## Requirements` headers instead of operation-prefixed headers.
|
||||
|
||||
**Root Cause:**
|
||||
Failed to understand that ALL spec files in a change need operation prefixes (`ADDED`, `MODIFIED`, etc.) in their section headers, regardless of whether they're new specs or modifications.
|
||||
|
||||
**Discovery Process:**
|
||||
- Created new specs with `## Requirements` → No deltas detected
|
||||
- Changed to `## ADDED Requirements` → Deltas detected successfully!
|
||||
- Realized creating new specs works perfectly fine once properly formatted
|
||||
|
||||
**Important Clarification:**
|
||||
OpenSpec fully supports creating new specs. They appear as ADDED operations in the deltas. My initial analysis incorrectly suggested this was a limitation, but it was actually just a formatting issue.
|
||||
|
||||
### Error 3: Improper Scenario Formatting
|
||||
**Error Message:**
|
||||
```
|
||||
✗ [ERROR] deltas.0.requirements.0.scenarios: Requirement must have at least one scenario
|
||||
✗ [ERROR] deltas.1.requirements.0.scenarios: Requirement must have at least one scenario
|
||||
```
|
||||
|
||||
**What Happened:**
|
||||
Formatted scenarios as bullet lists under a bold "Scenarios:" label:
|
||||
```markdown
|
||||
**Scenarios:**
|
||||
- **WHEN** executing command
|
||||
- **THEN** expected behavior
|
||||
```
|
||||
|
||||
**Root Cause:**
|
||||
OpenSpec's parser expects scenarios to be defined as level 4 headers (`####`) with specific formatting:
|
||||
```markdown
|
||||
#### Scenario: Descriptive scenario name
|
||||
|
||||
- **WHEN** executing command
|
||||
- **THEN** expected behavior
|
||||
```
|
||||
|
||||
**Discovery Process:**
|
||||
- Checked parsed JSON output: `npx openspec change show bulk-validation-interactive-selection --json`
|
||||
- Saw `"scenarios": []` empty array despite having scenario content
|
||||
- Examined working spec files and found the `#### Scenario:` header pattern
|
||||
|
||||
### Error 4: File Path Confusion
|
||||
**Initial Confusion:**
|
||||
Wasn't clear whether to create specs that would become part of the main `openspec/specs/` or just define them in the change.
|
||||
|
||||
**Resolution:**
|
||||
Learned that changes can:
|
||||
1. Create new specs (they start in `changes/{change-name}/specs/` and move to `openspec/specs/` when archived)
|
||||
2. Modify existing specs (by creating a spec file with the same name as one in `openspec/specs/`)
|
||||
3. The validation system detects both patterns and creates appropriate deltas
|
||||
|
||||
---
|
||||
|
||||
## System Issues vs User Errors
|
||||
|
||||
### System Issues / Bugs
|
||||
|
||||
#### 1. Unhelpful Error Messages ⚠️
|
||||
**Issue:** `✗ [ERROR] deltas: Change must have at least one delta`
|
||||
|
||||
**Why This Is a System Problem:**
|
||||
- Error message provides no guidance on HOW to create deltas
|
||||
- Doesn't mention that deltas come from `specs/` subdirectory
|
||||
- Doesn't explain the required section headers
|
||||
- A better error would be: "No deltas found. Ensure your change has a specs/ directory with .md files containing sections like '## ADDED Requirements'"
|
||||
|
||||
#### 2. Silent Scenario Parsing Failures ⚠️
|
||||
**Issue:** When scenarios were formatted incorrectly, they were silently ignored
|
||||
|
||||
**Why This Is a System Problem:**
|
||||
- Parser silently returns empty scenarios array instead of warning
|
||||
- No validation error explaining the format issue
|
||||
- User gets "Requirement must have at least one scenario" without knowing their scenarios exist but aren't parsed
|
||||
|
||||
**Evidence:**
|
||||
```json
|
||||
{
|
||||
"text": "The CLI SHALL provide a top-level `show` command with interactive selection.",
|
||||
"scenarios": [] // Silent failure - scenarios existed but weren't parsed
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. No Validation for Proposal Structure During Creation
|
||||
**Issue:** System allows creating invalid proposals without early feedback
|
||||
|
||||
**Why This Is a System Problem:**
|
||||
- No scaffolding or template commands
|
||||
- No incremental validation as you build
|
||||
- Must fully create the change before discovering structural issues
|
||||
|
||||
### User Errors (My Mistakes)
|
||||
|
||||
#### 1. Trying to Define Deltas in Proposal.md
|
||||
- Incorrectly assumed deltas could be inline in the proposal
|
||||
- System correctly expects deltas in separate spec files
|
||||
|
||||
#### 2. Using Wrong Section Headers
|
||||
- Used `## Requirements` instead of `## ADDED Requirements`
|
||||
- Convention is documented in existing changes, but I didn't examine carefully
|
||||
|
||||
#### 3. Wrong Scenario Format
|
||||
- Used bullet lists instead of `#### Scenario:` headers
|
||||
- Made assumptions instead of checking existing patterns
|
||||
|
||||
### Gray Areas
|
||||
|
||||
1. **Documentation gaps** - While examples exist, there's no comprehensive "How to Create a Change" guide
|
||||
2. **Lack of tooling** - No scaffolding commands to create properly structured changes
|
||||
|
||||
---
|
||||
|
||||
## Documentation Gaps Analysis
|
||||
|
||||
### Critical Gaps in openspec/README.md
|
||||
|
||||
#### 1. Scenario Format - COMPLETELY MISSING ⚠️
|
||||
**What README Shows:** No scenario examples at all
|
||||
|
||||
**What's Actually Required:**
|
||||
```markdown
|
||||
#### Scenario: Descriptive name
|
||||
- **WHEN** condition
|
||||
- **THEN** expected outcome
|
||||
- **AND** additional outcomes
|
||||
```
|
||||
|
||||
**Impact:** This was the biggest struggle. The README mentions requirements but never shows how to write scenarios. Without this, requirements fail validation.
|
||||
|
||||
#### 2. Complete Spec File Example - MISSING
|
||||
**What README Shows:** Only fragments
|
||||
|
||||
**What's Actually Needed:** A complete working example showing:
|
||||
- Full spec file structure
|
||||
- Proper requirement format
|
||||
- Scenario formatting
|
||||
- All required elements
|
||||
|
||||
#### 3. Validation Commands - NOT MENTIONED
|
||||
**Missing from README:**
|
||||
- `npx openspec change validate <change-name>`
|
||||
- `npx openspec change show <change-name> --json`
|
||||
- The `--strict` flag for catching warnings
|
||||
|
||||
#### 4. Delta Detection Explanation - INCOMPLETE
|
||||
**What's Missing:**
|
||||
- WHERE the system looks for specs (specs/ subdirectory)
|
||||
- THAT deltas are automatically extracted
|
||||
- HOW to debug when deltas aren't detected
|
||||
- WHAT error messages mean
|
||||
|
||||
### Misleading Documentation
|
||||
|
||||
#### "Store only the changes" - MISLEADING
|
||||
**Line 145:** `# - Store only the changes (not complete future state)`
|
||||
|
||||
**Problem:** This suggests storing diffs or partial content. In reality, you need:
|
||||
- Complete requirements in their final form
|
||||
- Full scenario definitions
|
||||
- The entire requirement text
|
||||
|
||||
### Documentation That Was Helpful
|
||||
1. Delta section headers (`## ADDED Requirements`) - clearly documented
|
||||
2. Directory structure - excellent visualization
|
||||
3. When to create proposals - well defined
|
||||
|
||||
---
|
||||
|
||||
## Key Learnings
|
||||
|
||||
### 1. OpenSpec's Delta Detection Algorithm
|
||||
The system follows this process:
|
||||
1. Scans `openspec/changes/{change-name}/specs/` directory
|
||||
2. For each spec file found, parses for delta sections (`ADDED`, `MODIFIED`, `REMOVED`, `RENAMED`)
|
||||
3. Creates delta objects with operation type, affected spec, and requirements
|
||||
4. Validates that at least one delta exists for the change to be valid
|
||||
|
||||
**Important:** Creating entirely new specs is fully supported! New specs use `## ADDED Requirements` and appear as ADDED operations in the deltas.
|
||||
|
||||
### 2. Spec File Structure Requirements
|
||||
Valid spec files must follow this structure:
|
||||
```markdown
|
||||
# Spec Title
|
||||
|
||||
## [ADDED|MODIFIED|REMOVED|RENAMED] Requirements
|
||||
|
||||
### Requirement: Clear requirement statement
|
||||
|
||||
The requirement description using SHALL/SHOULD/MAY.
|
||||
|
||||
#### Scenario: Scenario name
|
||||
|
||||
- **WHEN** condition
|
||||
- **THEN** expected outcome
|
||||
- **AND** additional outcomes
|
||||
```
|
||||
|
||||
### 3. Change Proposal Structure
|
||||
A valid change must have:
|
||||
- `## Why` section - explaining the motivation
|
||||
- `## What Changes` section - summarizing the changes
|
||||
- `specs/` directory with properly formatted spec files containing deltas
|
||||
- Each delta must have at least one requirement with at least one scenario
|
||||
|
||||
### 4. Validation Commands Are Essential
|
||||
```bash
|
||||
# Basic validation
|
||||
npx openspec change validate {change-name}
|
||||
|
||||
# Strict validation (recommended)
|
||||
npx openspec change validate {change-name} --strict
|
||||
|
||||
# Debug delta detection
|
||||
npx openspec change show {change-name} --json | jq '.deltas'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
### High Priority (System Bugs to Fix)
|
||||
|
||||
1. **Improve Error Messages**
|
||||
- Add actionable guidance to error messages
|
||||
- Example: "No deltas found. Check: 1) specs/ directory exists, 2) Files use ## ADDED Requirements headers, 3) Each requirement has #### Scenario: sections"
|
||||
|
||||
2. **Add Warnings for Malformed Content**
|
||||
- Warn when scenarios exist but aren't properly formatted
|
||||
- Show which line/file has the issue
|
||||
|
||||
3. **Add Delta Detection Debugging**
|
||||
- Command like `openspec change debug-deltas {change-name}`
|
||||
- Show which files were scanned, what was found, what was rejected
|
||||
|
||||
### Medium Priority (Documentation Improvements)
|
||||
|
||||
1. **Add Complete Working Example to README**
|
||||
- Full change proposal with all files
|
||||
- Properly formatted specs with scenarios
|
||||
- Show the validation output
|
||||
|
||||
2. **Add Troubleshooting Section**
|
||||
- Common errors and their solutions
|
||||
- How to debug delta detection
|
||||
- Scenario formatting requirements
|
||||
|
||||
3. **Add Validation Best Practices**
|
||||
- When to use `--strict`
|
||||
- How to use JSON output for debugging
|
||||
- Common validation patterns
|
||||
|
||||
### Low Priority (Developer Experience)
|
||||
|
||||
1. **Add Scaffolding Command**
|
||||
```bash
|
||||
openspec change scaffold {change-name}
|
||||
```
|
||||
- Creates proper directory structure
|
||||
- Includes template files with correct formatting
|
||||
- Adds example scenarios
|
||||
|
||||
2. **Add Interactive Creation Wizard**
|
||||
- Guide users through change creation
|
||||
- Validate as they go
|
||||
- Suggest fixes for common issues
|
||||
|
||||
3. **Add Auto-fix Capability**
|
||||
- `--fix` flag to correct common formatting issues
|
||||
- Convert bullet list scenarios to proper headers
|
||||
- Add missing operation prefixes
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
The OpenSpec system works correctly for its intended design, but the user experience for creating changes needs significant improvement. The core issues stem from:
|
||||
|
||||
### System Issues
|
||||
- **Unhelpful error messages** that don't guide users to solutions
|
||||
- **Silent parsing failures** that provide no feedback about malformed content
|
||||
- **Lack of debugging tools** to understand what went wrong
|
||||
|
||||
### Documentation Issues
|
||||
- **Critical formatting requirements missing** (especially scenario format)
|
||||
- **No complete working examples** showing all required elements
|
||||
- **Validation commands not documented** despite being essential
|
||||
|
||||
### User Issues
|
||||
- **Incorrect assumptions** about how the system works
|
||||
- **Not examining existing patterns** carefully enough
|
||||
- **Trying to shortcut** instead of following established conventions
|
||||
|
||||
### The Path Forward
|
||||
|
||||
With better error messages, complete documentation, and basic tooling support, most of the errors encountered could be prevented. The system's delta-centric approach is powerful and ensures changes are atomic and trackable, but it needs to be more discoverable and user-friendly.
|
||||
|
||||
The most impactful improvements would be:
|
||||
1. Adding scenario format documentation to the README
|
||||
2. Improving error messages with actionable guidance
|
||||
3. Creating a scaffolding command for new changes
|
||||
|
||||
These changes would transform OpenSpec from a system that works correctly but is hard to use, into one that actively helps developers succeed.
|
||||
@@ -1,119 +1,206 @@
|
||||
# OpenSpec
|
||||
<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>
|
||||
|
||||
A specification-driven development system for maintaining living documentation alongside your code.
|
||||
<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>
|
||||
|
||||
## Installation
|
||||
<details>
|
||||
<summary><strong>The most loved spec framework.</strong></summary>
|
||||
|
||||
```bash
|
||||
npm install -g openspec
|
||||
[](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:propose "your idea"` 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>
|
||||
|
||||
<!-- TODO: Add GIF demo of /opsx:propose → /opsx:archive workflow -->
|
||||
|
||||
## See it in action
|
||||
|
||||
```text
|
||||
You: /opsx:propose add-dark-mode
|
||||
AI: Created openspec/changes/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!
|
||||
|
||||
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
|
||||
# Initialize OpenSpec in your project
|
||||
openspec init
|
||||
|
||||
# Update existing OpenSpec instructions (team-friendly)
|
||||
openspec update
|
||||
|
||||
# List specs or changes
|
||||
openspec spec list # specs (IDs by default; use --long for details)
|
||||
openspec change list # changes (IDs by default; use --long for details)
|
||||
|
||||
# Show differences between specs and proposed changes
|
||||
openspec diff [change-name]
|
||||
|
||||
# Archive completed changes
|
||||
openspec archive [change-name]
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
## Commands
|
||||
Then navigate to your project directory and initialize:
|
||||
|
||||
### `openspec init`
|
||||
```bash
|
||||
cd your-project
|
||||
openspec init
|
||||
```
|
||||
|
||||
Initializes OpenSpec in your project by creating:
|
||||
- `openspec/` directory structure
|
||||
- `openspec/README.md` with OpenSpec instructions
|
||||
- AI tool configuration files (based on your selection)
|
||||
Now tell your AI: `/opsx:propose <what-you-want-to-build>`
|
||||
|
||||
### `openspec update`
|
||||
If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`.
|
||||
|
||||
Updates OpenSpec instructions to the latest version. This command is **team-friendly** and only updates files that already exist:
|
||||
> [!NOTE]
|
||||
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 25+ tools and growing.
|
||||
>
|
||||
> Also works with pnpm, yarn, bun, and nix. [See installation options](docs/installation.md).
|
||||
|
||||
- Always updates `openspec/README.md` with the latest OpenSpec instructions
|
||||
- **Only updates existing AI tool configuration files** (e.g., CLAUDE.md, CURSOR.md)
|
||||
- **Never creates new AI tool configuration files**
|
||||
- Preserves content outside of OpenSpec markers in AI tool files
|
||||
## Docs
|
||||
|
||||
This allows team members to use different AI tools without conflicts. Each developer can maintain their preferred AI tool configuration file, and `openspec update` will respect their choice.
|
||||
→ **[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
|
||||
|
||||
### `openspec spec`
|
||||
|
||||
Manage and view specifications.
|
||||
## Community schemas
|
||||
|
||||
Examples:
|
||||
- `openspec spec show <spec-id>`
|
||||
- Text mode: prints raw `spec.md` content
|
||||
- JSON mode (`--json`): returns minimal, stable shape
|
||||
- Filters are JSON-only: `--requirements`, `--no-scenarios`, `-r/--requirement <1-based>`
|
||||
- `openspec spec list`
|
||||
- Prints IDs only by default
|
||||
- Use `--long` to include `title` and `[requirements N]`
|
||||
- `openspec spec validate <spec-id>`
|
||||
- Text: human-readable summary to stdout/stderr
|
||||
- `--json` for structured report
|
||||
Third-party schema bundles distributed via standalone repositories — these provide opinionated workflows that integrate OpenSpec with other tools, similar to how [github/spec-kit's community extension catalog](https://github.com/github/spec-kit/tree/main/extensions) handles tool integrations.
|
||||
|
||||
### `openspec change`
|
||||
→ **[Browse the catalog](docs/customization.md#community-schemas)** in the customization docs.
|
||||
|
||||
Manage and view change proposals.
|
||||
|
||||
Examples:
|
||||
- `openspec change show <change-id>`
|
||||
- Text mode: prints raw `proposal.md` content
|
||||
- JSON mode (`--json`): `{ id, title, deltaCount, deltas }`
|
||||
- Filtering is JSON-only: `--deltas-only` (alias: `--requirements-only`, deprecated)
|
||||
- `openspec change list`
|
||||
- Prints IDs only by default
|
||||
- Use `--long` to include `title` and counts `[deltas N] [tasks x/y]`
|
||||
- `openspec change validate <change-id>`
|
||||
- Text: human-readable result
|
||||
- `--json` for structured report
|
||||
## Why OpenSpec?
|
||||
|
||||
### `openspec diff [change-name]`
|
||||
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.
|
||||
|
||||
Shows the differences between current specs and proposed changes:
|
||||
- Displays a unified diff format
|
||||
- Helps review what will change before implementation
|
||||
- Useful for pull request reviews
|
||||
- **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
|
||||
|
||||
### `openspec archive [change-name]`
|
||||
### How we compare
|
||||
|
||||
Archives a completed change:
|
||||
- Moves change from `openspec/changes/` to `openspec/changes/archive/`
|
||||
- Adds a date prefix to the archived change
|
||||
- Updates specs to reflect the new state
|
||||
- Use `--skip-specs` to archive without updating specs (for abandoned changes)
|
||||
**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.
|
||||
|
||||
## Team Collaboration
|
||||
**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.
|
||||
|
||||
OpenSpec is designed for team collaboration:
|
||||
**vs. nothing** — AI coding without specs means vague prompts and unpredictable results. OpenSpec brings predictability without the ceremony.
|
||||
|
||||
1. **AI Tool Flexibility**: Each team member can use their preferred AI assistant (Claude, Cursor, etc.)
|
||||
2. **Non-Invasive Updates**: The `update` command only modifies existing files, never forcing tools on team members
|
||||
3. **Specification Sharing**: The `openspec/` directory contains shared specifications that all team members work from
|
||||
4. **Change Tracking**: Proposed changes are visible to all team members for review before implementation
|
||||
## 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
|
||||
|
||||
See `openspec/specs/` for the current system specifications and `openspec/changes/` for pending improvements.
|
||||
**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>
|
||||
|
||||
## Notes
|
||||
|
||||
- The legacy `openspec list` command is deprecated. Use `openspec spec list` and `openspec change list`.
|
||||
- Text output is raw-first (no formatting or filtering). Prefer `--json` for tooling-friendly output.
|
||||
- Global `--no-color` disables ANSI colors and respects `NO_COLOR`.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
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
|
||||
@@ -0,0 +1,470 @@
|
||||
# Workspace Reimplementation Direction
|
||||
|
||||
Date: 2026-04-30
|
||||
|
||||
Fresh-agent entry point: read `WORKSPACE_REIMPLEMENTATION_START_HERE.md` first, then return to this document for the full product direction.
|
||||
|
||||
This document captures the intended direction for reimplementing OpenSpec workspace support from scratch, based on what we learned from the workspace POC.
|
||||
|
||||
The reimplementation should be ordered around the path a real user takes through OpenSpec:
|
||||
|
||||
```text
|
||||
set up workspace
|
||||
-> link repos or folders
|
||||
-> open workspace
|
||||
-> explore across repos or folders
|
||||
-> create proposal
|
||||
-> apply one repo slice
|
||||
-> verify
|
||||
-> archive
|
||||
```
|
||||
|
||||
The goal is not to rebuild every POC mechanism. The goal is to get one user-facing capability working at a time, in the same order a user would naturally create, implement, verify, and archive a change.
|
||||
|
||||
## North Star
|
||||
|
||||
A user should think:
|
||||
|
||||
```text
|
||||
I have a multi-repo product goal.
|
||||
I set up an OpenSpec workspace.
|
||||
I open it with my agent.
|
||||
The agent can see the linked repos or folders.
|
||||
We explore until the scope is clear.
|
||||
Then we create a proposal.
|
||||
Then we implement one repo slice at a time.
|
||||
```
|
||||
|
||||
They should not think:
|
||||
|
||||
```text
|
||||
I need to create a change so repos become visible.
|
||||
I need to materialize repo-local artifacts.
|
||||
I need to understand implementation-specific workspace machinery.
|
||||
I need to manage target metadata separately from proposal files.
|
||||
```
|
||||
|
||||
The core product rule is:
|
||||
|
||||
```text
|
||||
Workspace visibility is not change commitment.
|
||||
```
|
||||
|
||||
Linked repos or folders are planning context. Creating a change is a planning commitment. Applying a change is an implementation workflow.
|
||||
|
||||
## Build Order
|
||||
|
||||
### 1. Workspace Setup And Links
|
||||
|
||||
First make workspace setup boring and solid.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Create a planning home and link the repos or folders OpenSpec should know about.
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec workspace setup
|
||||
openspec workspace setup --no-interactive --name platform --link /path/to/api --link web=/path/to/web
|
||||
openspec workspace list
|
||||
openspec workspace ls
|
||||
openspec workspace link /path/to/api
|
||||
openspec workspace link api-service /path/to/api
|
||||
openspec workspace relink api /new/path/to/api
|
||||
openspec workspace doctor
|
||||
```
|
||||
|
||||
Expected outcome:
|
||||
|
||||
```text
|
||||
workspace-folder/
|
||||
changes/
|
||||
.openspec-workspace/
|
||||
workspace.yaml
|
||||
local.yaml
|
||||
```
|
||||
|
||||
Product decisions:
|
||||
|
||||
- Use `.openspec-workspace/`, not `.openspec/`, for workspace metadata.
|
||||
- Keep `changes/` visible in the workspace folder.
|
||||
- Keep setup as the only public creation path for the first release; do not expose `workspace create`.
|
||||
- Use `workspace link` and `workspace relink`, not POC-era `add-repo` or `update-repo`.
|
||||
- Allow linked repos or folders without repo-local `openspec/` state.
|
||||
- Keep stable link names in shared workspace state and local paths in machine-local state.
|
||||
- Make `doctor` show link names, resolved paths, repo-local specs paths when present, and suggested fixes.
|
||||
|
||||
Defer:
|
||||
|
||||
- Agent launch and workspace open behavior.
|
||||
- Preferred-agent prompts.
|
||||
- Owner or handoff metadata.
|
||||
- Workspace change creation or target selection.
|
||||
- Branches.
|
||||
- Worktrees.
|
||||
- Apply.
|
||||
- Archive.
|
||||
- Complex target lifecycle.
|
||||
|
||||
Done when a user can set up a workspace, link repos or folders, list known workspaces, relink local paths, and run `doctor` to see exactly what OpenSpec can resolve.
|
||||
|
||||
### 2. Workspace Open
|
||||
|
||||
Next make the workspace openable in the way users expect.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Open this multi-repo planning context with my coding agent.
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec workspace open
|
||||
openspec workspace open --agent codex
|
||||
openspec workspace open --agent github-copilot
|
||||
```
|
||||
|
||||
Product behavior:
|
||||
|
||||
- `workspace open` opens the coordination workspace plus linked repos or folders.
|
||||
- Repo visibility is default.
|
||||
- Change selection is optional focus, not the mechanism for repo access.
|
||||
- `--agent` should be a one-session override by default. Persisting the preferred agent should require an explicit preference-setting action.
|
||||
|
||||
For GitHub Copilot, generate or open a `.code-workspace` file with:
|
||||
|
||||
```text
|
||||
workspace folder
|
||||
linked repo or folder A
|
||||
linked repo or folder B
|
||||
```
|
||||
|
||||
For Claude and Codex, attach the linked repo or folder directories through the agent's supported mechanism.
|
||||
|
||||
Defer:
|
||||
|
||||
- `workspace open --change`.
|
||||
- In-session upgrade flows.
|
||||
- Per-change attachment restrictions.
|
||||
|
||||
Done when opening a workspace gives the agent visibility into the coordination root and all linked repos or folders.
|
||||
|
||||
### 3. Agent Guidance And Explore
|
||||
|
||||
Then make exploration work.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Tell the agent a rough product goal and have it inspect the repos before creating a proposal.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
Explore how we should make the OpenSpec docs available on the landing page.
|
||||
Look across the linked repos or folders, but do not implement yet.
|
||||
```
|
||||
|
||||
Agent behavior:
|
||||
|
||||
- Understand it is in workspace mode.
|
||||
- Inspect linked repos or folders.
|
||||
- Explain likely affected repos.
|
||||
- Ask for clarification only when needed.
|
||||
- Avoid implementation edits during explore.
|
||||
|
||||
Build:
|
||||
|
||||
- Workspace-level `AGENTS.md` guidance.
|
||||
- Normal OpenSpec skills and commands in workspace sessions.
|
||||
- Workspace-specific guidance layered on top of normal `/explore`, not replacing it.
|
||||
|
||||
Defer:
|
||||
|
||||
- Proposal artifact generation.
|
||||
- Target confirmation commands.
|
||||
- Apply context providers.
|
||||
|
||||
Done when a user can open a workspace and run a useful cross-repo exploration without creating a dummy change.
|
||||
|
||||
### 4. Proposal Creation
|
||||
|
||||
Only after explore works, build proposal creation.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Now that we understand the scope, capture the plan.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
Create a proposal for this change.
|
||||
Target the repos that are actually affected.
|
||||
```
|
||||
|
||||
Preferred artifact shape:
|
||||
|
||||
```text
|
||||
changes/integrate-docs/
|
||||
proposal.md
|
||||
design.md
|
||||
tasks.md
|
||||
specs/
|
||||
openspec/
|
||||
docs-conventions/spec.md
|
||||
landing/
|
||||
docs-routing/spec.md
|
||||
```
|
||||
|
||||
Key workflow rule:
|
||||
|
||||
```text
|
||||
/explore may leave targets unknown.
|
||||
/propose may discover targets.
|
||||
/propose must confirm targets before saying ready for apply.
|
||||
```
|
||||
|
||||
Targets should be represented by the proposal artifacts themselves where possible. If there is `specs/landing/...`, then `landing` is in scope. Avoid a separate required `targets: [...]` metadata list as the active source of truth.
|
||||
|
||||
Defer:
|
||||
|
||||
- Repo-local materialization.
|
||||
- Worktree selection.
|
||||
- Multi-repo implementation.
|
||||
- Archive.
|
||||
|
||||
Done when a user can explore, then create a workspace proposal with repo-scoped specs and tasks.
|
||||
|
||||
### 5. Status
|
||||
|
||||
Before implementation, make status excellent.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Where are we, what repos are involved, and is this ready to implement?
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec status
|
||||
openspec status --change integrate-docs
|
||||
```
|
||||
|
||||
Human output should answer:
|
||||
|
||||
```text
|
||||
Change: integrate-docs
|
||||
Scope: openspec, landing
|
||||
Proposal: present
|
||||
Design: present
|
||||
Tasks: present
|
||||
Ready for apply: yes/no
|
||||
```
|
||||
|
||||
Status should also catch structural mistakes:
|
||||
|
||||
- Unknown repo folder under `specs/`.
|
||||
- Missing tasks.
|
||||
- No confirmed affected repo.
|
||||
- Linked repo or folder path missing.
|
||||
|
||||
Done when the agent and user can trust status before applying.
|
||||
|
||||
### 6. Apply One Repo Slice
|
||||
|
||||
Only now build `/apply`.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Implement the planned slice for one repo.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
/apply integrate-docs for landing
|
||||
```
|
||||
|
||||
Product contract:
|
||||
|
||||
```text
|
||||
/apply means implement.
|
||||
```
|
||||
|
||||
It does not mean:
|
||||
|
||||
```text
|
||||
copy planning files
|
||||
materialize repo-local OpenSpec state
|
||||
create the proposal files for the first time
|
||||
```
|
||||
|
||||
Agent behavior:
|
||||
|
||||
1. Ask OpenSpec for apply context.
|
||||
2. Read proposal, design, tasks, and relevant specs.
|
||||
3. Confirm the target repo checkout.
|
||||
4. Edit only that repo.
|
||||
5. Update workspace tasks.
|
||||
6. Run relevant checks.
|
||||
|
||||
This likely wants a normalized context command internally, but that is supporting machinery:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "workspace",
|
||||
"change": "integrate-docs",
|
||||
"target": "landing",
|
||||
"implementationRoot": "/repos/openspec-landing",
|
||||
"contextFiles": [
|
||||
"changes/integrate-docs/proposal.md",
|
||||
"changes/integrate-docs/design.md",
|
||||
"changes/integrate-docs/tasks.md",
|
||||
"changes/integrate-docs/specs/landing/docs-routing/spec.md"
|
||||
],
|
||||
"allowedEditRoots": [
|
||||
"/repos/openspec-landing"
|
||||
],
|
||||
"tasksFile": "changes/integrate-docs/tasks.md"
|
||||
}
|
||||
```
|
||||
|
||||
Defer:
|
||||
|
||||
- Applying multiple repos at once.
|
||||
- Automatic branch creation.
|
||||
- Worktree management.
|
||||
- Repo-local OpenSpec mirroring.
|
||||
|
||||
Done when one repo slice can be implemented from the central workspace plan.
|
||||
|
||||
### 7. Verify
|
||||
|
||||
Then build verification.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Check whether the implemented repo slice satisfies the plan.
|
||||
```
|
||||
|
||||
Expected prompt:
|
||||
|
||||
```text
|
||||
/verify integrate-docs for landing
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
- Read the same normalized context as `/apply`.
|
||||
- Inspect the implementation checkout.
|
||||
- Check tasks and specs for that repo.
|
||||
- Run repo validation.
|
||||
- Report gaps clearly.
|
||||
|
||||
Default behavior should verify one repo slice. Whole-workspace verification can come later.
|
||||
|
||||
Done when a user can verify one implemented repo slice against the central workspace plan.
|
||||
|
||||
### 8. Archive
|
||||
|
||||
Archive comes last in the first complete loop.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
The change is done. Move it out of active planning.
|
||||
```
|
||||
|
||||
Expected prompt:
|
||||
|
||||
```text
|
||||
/archive integrate-docs
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
- Require all targeted repo slices to be complete or explicitly accepted.
|
||||
- Archive the workspace change.
|
||||
- Do not require repo-local planning copies unless OpenSpec later decides that repo-local archival matters.
|
||||
|
||||
Done when a user can complete the full lifecycle:
|
||||
|
||||
```text
|
||||
workspace setup
|
||||
-> link repos or folders
|
||||
-> open
|
||||
-> explore
|
||||
-> propose
|
||||
-> apply repo A
|
||||
-> apply repo B
|
||||
-> verify
|
||||
-> archive
|
||||
```
|
||||
|
||||
## Implementation Discipline
|
||||
|
||||
Build only the next user-visible step.
|
||||
|
||||
The sequence should stay grounded in these questions:
|
||||
|
||||
```text
|
||||
1. Can I set up the workspace?
|
||||
2. Can I see my linked repos or folders?
|
||||
3. Can my agent explore them?
|
||||
4. Can we capture a proposal?
|
||||
5. Can status tell us if it is ready?
|
||||
6. Can the agent implement one repo slice?
|
||||
7. Can we verify it?
|
||||
8. Can we archive it?
|
||||
```
|
||||
|
||||
Avoid starting with internal abstractions unless they are required for the next user-visible capability.
|
||||
|
||||
Do not start with:
|
||||
|
||||
- Target metadata machinery.
|
||||
- Materialization.
|
||||
- Adapter abstractions.
|
||||
- Branch orchestration.
|
||||
- Worktree orchestration.
|
||||
- Multi-repo apply.
|
||||
|
||||
Those may matter later, but they should not define the first reimplementation path.
|
||||
|
||||
## Product Shape
|
||||
|
||||
The workspace should feel like OpenSpec's normal workflow stretched across multiple repos, not a second product with its own lifecycle.
|
||||
|
||||
The durable product model is:
|
||||
|
||||
```text
|
||||
workspace = durable planning home
|
||||
links = repos or folders visible for planning
|
||||
proposal = scoped planning commitment
|
||||
repo slice = one affected repo or folder in the plan
|
||||
branch/worktree = implementation checkout
|
||||
/apply = implement one selected repo slice
|
||||
```
|
||||
|
||||
Keep the user journey simple:
|
||||
|
||||
```text
|
||||
Open the workspace.
|
||||
Ask the agent to explore.
|
||||
Create the proposal when scope is clear.
|
||||
Implement one repo slice at a time.
|
||||
Verify.
|
||||
Archive.
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
# Workspace Reimplementation Start Here
|
||||
|
||||
This is the grep-friendly entry point for agents working on the workspace reimplementation.
|
||||
|
||||
Useful search terms:
|
||||
|
||||
```text
|
||||
workspace reimplementation
|
||||
workspace poc
|
||||
workspace-poc
|
||||
workspace reference guide
|
||||
workspace roadmap
|
||||
fresh agent
|
||||
start here
|
||||
```
|
||||
|
||||
## Start Here
|
||||
|
||||
Read these files in order:
|
||||
|
||||
1. `WORKSPACE_REIMPLEMENTATION_DIRECTION.md`
|
||||
2. `openspec/changes/workspace-reimplementation-roadmap/README.md`
|
||||
3. `openspec/changes/workspace-reimplementation-roadmap/POC_REFERENCE_GUIDE.md`
|
||||
4. The proposal for the next implementation slice
|
||||
|
||||
The POC reference commit is:
|
||||
|
||||
```text
|
||||
workspace-poc @ 79a45ac043f414e63d13e08b9da83b135cb20a39
|
||||
```
|
||||
|
||||
Use the POC as research material. Do not merge it into an implementation branch. Do not preserve its architecture unless a slice proposal or design explicitly decides to do so.
|
||||
|
||||
## Implementation Order
|
||||
|
||||
Implement these flat OpenSpec changes in order:
|
||||
|
||||
1. `workspace-foundation`
|
||||
2. `workspace-create-and-register-repos`
|
||||
3. `workspace-open-agent-context`
|
||||
4. `workspace-change-planning`
|
||||
5. `workspace-apply-repo-slice`
|
||||
6. `workspace-verify-and-archive`
|
||||
|
||||
`workspace-reimplementation-roadmap` is the continuity and reference container for the plan.
|
||||
|
||||
## Before Editing
|
||||
|
||||
For the slice you are about to implement, inspect the pinned POC commit using `POC_REFERENCE_GUIDE.md`, then write down:
|
||||
|
||||
```text
|
||||
POC findings for <slice>:
|
||||
|
||||
User behavior to preserve:
|
||||
- ...
|
||||
|
||||
Tests or examples worth translating:
|
||||
- ...
|
||||
|
||||
Implementation shortcuts to avoid:
|
||||
- ...
|
||||
|
||||
Open design questions:
|
||||
- ...
|
||||
```
|
||||
|
||||
Capture durable findings in the relevant OpenSpec artifact so future sessions do not depend on chat history.
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
+1076
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,705 @@
|
||||
# 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
|
||||
|
||||
### Default Quick Path (`core` profile)
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
|
||||
| `/opsx:explore` | Think through ideas before committing to a change |
|
||||
| `/opsx:apply` | Implement tasks from the change |
|
||||
| `/opsx:sync` | Merge delta specs into main specs |
|
||||
| `/opsx:archive` | Archive a completed change |
|
||||
|
||||
### Expanded Workflow Commands (custom workflow selection)
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:new` | Start a new change scaffold |
|
||||
| `/opsx:continue` | Create the next artifact based on dependencies |
|
||||
| `/opsx:ff` | Fast-forward: create all planning artifacts at once |
|
||||
| `/opsx:verify` | Validate implementation matches artifacts |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes at once |
|
||||
| `/opsx:onboard` | Guided tutorial through the complete workflow |
|
||||
|
||||
The default global profile is `core`. To enable expanded workflow commands, run `openspec config profile`, select workflows, then run `openspec update` in your project.
|
||||
|
||||
---
|
||||
|
||||
## Command Reference
|
||||
|
||||
### `/opsx:propose`
|
||||
|
||||
Create a new change and generate planning artifacts in one step. This is the default start command in the `core` profile.
|
||||
|
||||
**Syntax:**
|
||||
```text
|
||||
/opsx:propose [change-name-or-description]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `change-name-or-description` | No | Kebab-case name or plain-language change description |
|
||||
|
||||
**What it does:**
|
||||
- Creates `openspec/changes/<change-name>/`
|
||||
- Generates artifacts needed before implementation (for `spec-driven`: proposal, specs, design, tasks)
|
||||
- Stops when the change is ready for `/opsx:apply`
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
You: /opsx:propose add-dark-mode
|
||||
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
✓ proposal.md
|
||||
✓ specs/ui/spec.md
|
||||
✓ design.md
|
||||
✓ tasks.md
|
||||
Ready for implementation. Run /opsx:apply.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Use this for the fastest end-to-end path
|
||||
- If you want step-by-step artifact control, enable expanded workflows and use `/opsx:new` + `/opsx:continue`
|
||||
|
||||
---
|
||||
|
||||
### `/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:propose` (default) or `/opsx:new` (expanded workflow) 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:propose 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 scaffold. Creates the change folder and waits for you to generate artifacts with `/opsx:continue` or `/opsx:ff`.
|
||||
|
||||
This command is part of the expanded workflow set (not included in the default `core` profile).
|
||||
|
||||
**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:propose`, `/opsx:apply` |
|
||||
| Cursor | `/opsx-propose`, `/opsx-apply` |
|
||||
| Windsurf | `/opsx-propose`, `/opsx-apply` |
|
||||
| Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
|
||||
| Kimi CLI | Skill-based invocations such as `/skill:openspec-propose`, `/skill:openspec-apply-change` (no generated `opsx-*` command files) |
|
||||
| Trae | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) |
|
||||
|
||||
The intent is the same across tools, but how commands are surfaced can differ by integration.
|
||||
|
||||
> **Note:** GitHub Copilot commands (`.github/prompts/*.prompt.md`) are only available in IDE extensions (VS Code, JetBrains, Visual Studio). GitHub Copilot CLI does not currently support custom prompt files — see [Supported Tools](supported-tools.md) for details and workarounds.
|
||||
|
||||
---
|
||||
|
||||
## 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,759 @@
|
||||
# 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.
|
||||
|
||||
## Coordination Workspaces
|
||||
|
||||
Workspace support is under active development and is not ready for use yet. Do not build external automation, integrations, or long-lived workflows on top of workspace behavior; the commands, state files, and JSON output can change at any point.
|
||||
|
||||
The commands below provide the first setup flow for planning across linked repos or folders.
|
||||
|
||||
Repo-local OpenSpec projects are the right default when one repo owns the planning, implementation, and archive flow. Some work spans several repos or folders. For that case, an OpenSpec coordination workspace is the durable planning home.
|
||||
|
||||
The workspace mental model is:
|
||||
|
||||
```text
|
||||
workspace = where related cross-repo changes live
|
||||
link = a stable name for a repo or folder the workspace can plan against
|
||||
change = one feature, fix, project, or other planned piece of work
|
||||
```
|
||||
|
||||
A workspace has a different shape from a repo-local project:
|
||||
|
||||
```text
|
||||
workspace-folder/
|
||||
├── changes/ # Workspace-level planning
|
||||
└── .openspec-workspace/
|
||||
├── workspace.yaml # Shared workspace identity and link names
|
||||
└── local.yaml # This machine's local paths
|
||||
```
|
||||
|
||||
Repo-local OpenSpec state keeps the existing shape:
|
||||
|
||||
```text
|
||||
repo-root/
|
||||
└── openspec/
|
||||
├── specs/
|
||||
└── changes/
|
||||
```
|
||||
|
||||
That distinction matters. The workspace folder is a coordination surface for planning across linked repos or folders. Each repo's `openspec/` directory remains the home for repo-owned specs, repo-local changes, and implementation planning. Users do not need to run repo-local `openspec init` inside a workspace folder.
|
||||
|
||||
Stable link names are how workspace planning refers to repos and folders. The shared workspace state keeps names such as `api`, `web`, or `checkout`; each machine maps those names to its own local paths in `.openspec-workspace/local.yaml`.
|
||||
|
||||
```yaml
|
||||
# .openspec-workspace/workspace.yaml
|
||||
version: 1
|
||||
name: platform
|
||||
links:
|
||||
api: {}
|
||||
web: {}
|
||||
```
|
||||
|
||||
```yaml
|
||||
# .openspec-workspace/local.yaml
|
||||
version: 1
|
||||
paths:
|
||||
api: /repos/api
|
||||
web: /repos/web
|
||||
```
|
||||
|
||||
OpenSpec-created workspaces exclude `.openspec-workspace/local.yaml` from portable collaboration state by default. `.openspec-workspace/workspace.yaml` remains portable because it stores the workspace name and stable link names, not one user's absolute checkout paths.
|
||||
|
||||
Linked paths can be full repos, folders inside a large monorepo, or other existing folders. They do not need repo-local `openspec/` state before they can participate in workspace planning. Later implementation, verify, or archive workflows may require more repo readiness, but planning visibility starts with the link.
|
||||
|
||||
```text
|
||||
multi-repo:
|
||||
api -> /repos/api
|
||||
web -> /repos/web
|
||||
|
||||
large monorepo:
|
||||
billing -> /repos/platform/services/billing
|
||||
checkout -> /repos/platform/apps/checkout
|
||||
```
|
||||
|
||||
Managed workspaces live under the standard OpenSpec data directory:
|
||||
|
||||
```text
|
||||
getGlobalDataDir()/workspaces
|
||||
```
|
||||
|
||||
That means `$XDG_DATA_HOME/openspec/workspaces` when `XDG_DATA_HOME` is set, `~/.local/share/openspec/workspaces` on Unix-style fallback, and `%LOCALAPPDATA%\openspec\workspaces` on native Windows fallback. Native Windows shells, PowerShell, and WSL2 each keep the path strings for the runtime running OpenSpec. This foundation does not translate between `D:\repo`, `/mnt/d/repo`, and UNC WSL paths.
|
||||
|
||||
OpenSpec also keeps a machine-local registry at:
|
||||
|
||||
```text
|
||||
getGlobalDataDir()/workspaces/registry.yaml
|
||||
```
|
||||
|
||||
The registry maps workspace names to workspace locations so later global commands can list or select known workspaces from anywhere. It is only an index. Each workspace folder remains authoritative for its own `.openspec-workspace/workspace.yaml` and `.openspec-workspace/local.yaml`, so stale registry records can be reported and repaired without redefining the workspace itself.
|
||||
|
||||
Workspace visibility is not change commitment. Set up a workspace when OpenSpec should know which repos or folders are relevant; create a change later when you are ready to plan a feature, fix, project, or other piece of work.
|
||||
|
||||
Useful commands:
|
||||
|
||||
```bash
|
||||
# Guided setup
|
||||
openspec workspace setup
|
||||
|
||||
# Automation-friendly setup
|
||||
openspec workspace setup --no-interactive --name platform --link /repos/api --link web=/repos/web
|
||||
openspec workspace setup --no-interactive --name platform --link /repos/api --opener codex
|
||||
|
||||
# See known workspaces from the local registry
|
||||
openspec workspace list
|
||||
openspec workspace ls
|
||||
|
||||
# Add or repair links for the selected workspace
|
||||
openspec workspace link /repos/api
|
||||
openspec workspace link api-service /repos/api
|
||||
openspec workspace relink api-service /new/path/to/api
|
||||
|
||||
# Check what this machine can resolve
|
||||
openspec workspace doctor
|
||||
openspec workspace doctor --workspace platform
|
||||
|
||||
# Open the linked working set
|
||||
openspec workspace open
|
||||
openspec workspace open platform --agent github-copilot
|
||||
openspec workspace open --editor
|
||||
```
|
||||
|
||||
`workspace setup` always creates the workspace in the standard workspace location, records it in the local registry, shows the workspace location, and requires at least one linked repo or folder. Interactive setup asks for a preferred opener. Non-interactive setup stores one only when `--opener codex`, `--opener claude`, `--opener github-copilot`, or `--opener editor` is provided.
|
||||
|
||||
OpenSpec also maintains root workspace open files: an OpenSpec-managed guidance block in `AGENTS.md`, a machine-local `<workspace-name>.code-workspace` file for VS Code and GitHub Copilot-in-VS-Code opens, and a specific ignore entry for that maintained `.code-workspace` file. User-authored `*.code-workspace` files remain trackable because the ignore rule targets only the maintained file.
|
||||
|
||||
The maintained VS Code workspace includes the coordination root as `.` plus valid linked repos or folders as additional roots. VS Code displays those entries as a multi-root workspace.
|
||||
|
||||
`workspace open` opens the linked working set with the stored preferred opener unless `--agent <tool>` or `--editor` is passed for that one session. Passing both opener overrides is an error. Root workspace open makes linked repos and folders visible for exploration and planning; implementation starts after the user explicitly asks for implementation work.
|
||||
|
||||
`workspace link` and `workspace relink` record existing folders only; they do not create, copy, move, initialize, or edit the linked repo or folder. After a successful link or relink, OpenSpec refreshes the managed guidance, VS Code workspace file, and ignore rule.
|
||||
|
||||
Workspace commands that need one workspace can run from anywhere with `--workspace <name>`. If you run them inside a workspace folder or subdirectory, OpenSpec uses that current workspace. If several known workspaces are available and you do not pass `--workspace <name>`, human commands show a picker; `--json` and `--no-interactive` fail with a structured status error instead of prompting.
|
||||
|
||||
Direct workspace commands support JSON output for scripts. JSON responses keep primary data in `workspace`, `workspaces`, or `link` objects and report warnings or errors in `status` arrays. Healthy objects use `status: []`.
|
||||
|
||||
## 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
|
||||
|
||||
### What a Spec Is (and Is Not)
|
||||
|
||||
A spec is a **behavior contract**, not an implementation plan.
|
||||
|
||||
Good spec content:
|
||||
- Observable behavior users or downstream systems rely on
|
||||
- Inputs, outputs, and error conditions
|
||||
- External constraints (security, privacy, reliability, compatibility)
|
||||
- Scenarios that can be tested or explicitly validated
|
||||
|
||||
Avoid in specs:
|
||||
- Internal class/function names
|
||||
- Library or framework choices
|
||||
- Step-by-step implementation details
|
||||
- Detailed execution plans (those belong in `design.md` or `tasks.md`)
|
||||
|
||||
Quick test:
|
||||
- If implementation can change without changing externally visible behavior, it likely does not belong in the spec.
|
||||
|
||||
### Keep It Lightweight: Progressive Rigor
|
||||
|
||||
OpenSpec aims to avoid bureaucracy. Use the lightest level that still makes the change verifiable.
|
||||
|
||||
**Lite spec (default):**
|
||||
- Short behavior-first requirements
|
||||
- Clear scope and non-goals
|
||||
- A few concrete acceptance checks
|
||||
|
||||
**Full spec (for higher risk):**
|
||||
- Cross-team or cross-repo changes
|
||||
- API/contract changes, migrations, security/privacy concerns
|
||||
- Changes where ambiguity is likely to cause expensive rework
|
||||
|
||||
Most changes should stay in Lite mode.
|
||||
|
||||
### Human + Agent Collaboration
|
||||
|
||||
In many teams, humans explore and agents draft artifacts. The intended loop is:
|
||||
|
||||
1. Human provides intent, context, and constraints.
|
||||
2. Agent converts this into behavior-first requirements and scenarios.
|
||||
3. Agent keeps implementation detail in `design.md` and `tasks.md`, not `spec.md`.
|
||||
4. Validation confirms structure and clarity before implementation.
|
||||
|
||||
This keeps specs readable for humans and consistent for agents.
|
||||
|
||||
## 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:propose (core) or /opsx:new (expanded) │
|
||||
│ │ CHANGE │ │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 2. CREATE │ /opsx:ff or /opsx:continue (expanded workflow) │
|
||||
│ │ 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,356 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Community Schemas
|
||||
|
||||
OpenSpec also supports community-maintained schemas distributed via standalone repositories. These provide opinionated workflows that integrate OpenSpec with other tools or systems, similar to how [github/spec-kit's community extension catalog](https://github.com/github/spec-kit/tree/main/extensions) works for spec-kit.
|
||||
|
||||
Community schemas are not vendored into OpenSpec core — they live in their own repositories with their own release cadence. To use one, copy the schema bundle into your project's `openspec/schemas/<schema-name>/` directory (each repo's README has install instructions).
|
||||
|
||||
| Schema | Maintainer | Repository | Description |
|
||||
|--------|-----------|-----------|-------------|
|
||||
| `superpowers-bridge` | @JiangWay | [JiangWay/openspec-schemas](https://github.com/JiangWay/openspec-schemas/tree/main/superpowers-bridge) | Integrates OpenSpec's artifact governance with [obra/superpowers](https://github.com/obra/superpowers) execution skills (brainstorming, writing-plans, TDD via subagents, code review, finishing). Adds an evidence-first `retrospective` artifact filling a gap Superpowers does not natively cover. |
|
||||
|
||||
> Want to contribute a community schema? Open an issue with a link to your repository, or submit a PR adding a row to this table.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [CLI Reference: Schema Commands](cli.md#schema-commands) - Full command documentation
|
||||
@@ -0,0 +1,253 @@
|
||||
# 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.
|
||||
|
||||
**Default quick path (core profile):**
|
||||
|
||||
```text
|
||||
/opsx:propose ──► /opsx:apply ──► /opsx:sync ──► /opsx:archive
|
||||
```
|
||||
|
||||
**Expanded path (custom workflow selection):**
|
||||
|
||||
```text
|
||||
/opsx:new ──► /opsx:ff or /opsx:continue ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
|
||||
```
|
||||
|
||||
The default global profile is `core`, which includes `propose`, `explore`, `apply`, `sync`, and `archive`. You can enable the expanded workflow commands with `openspec config profile` and then `openspec update`.
|
||||
|
||||
## 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 (Default)
|
||||
|
||||
```text
|
||||
You: /opsx:propose add-dark-mode
|
||||
|
||||
AI: Created openspec/changes/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!
|
||||
```
|
||||
|
||||
If you've enabled the expanded workflow profile, you can also do this as two steps: `/opsx:new` then `/opsx:ff` (or `/opsx:continue` incrementally).
|
||||
|
||||
### 2. 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
|
||||
```
|
||||
|
||||
### 3. 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.
|
||||
|
||||
### 4. 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,82 @@
|
||||
# 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
|
||||
|
||||
Bun can install OpenSpec globally, but OpenSpec currently runs on Node.js.
|
||||
You still need Node.js 20.19.0 or higher available on `PATH`.
|
||||
|
||||
```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,596 @@
|
||||
# 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` | Default: `/opsx:propose`, `/opsx:apply`, `/opsx:sync`, `/opsx:archive` (expanded workflow commands optional) |
|
||||
| **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` (IDE extensions only; not supported in Copilot CLI)
|
||||
- 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:
|
||||
|
||||
- New installs default to profile `core` (`propose`, `explore`, `apply`, `sync`, `archive`).
|
||||
- Migrated installs preserve your previously installed workflows by writing a `custom` profile when needed.
|
||||
|
||||
### 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 generated skills/commands to match your current profile and delivery settings.
|
||||
|
||||
### 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
|
||||
|
||||
Command availability is profile-dependent:
|
||||
|
||||
**Default (`core` profile):**
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
|
||||
| `/opsx:explore` | Think through ideas with no structure |
|
||||
| `/opsx:apply` | Implement tasks from tasks.md |
|
||||
| `/opsx:archive` | Finalize and archive the change |
|
||||
|
||||
**Expanded workflow (custom selection):**
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:new` | Start a new change scaffold |
|
||||
| `/opsx:continue` | Create the next artifact (one at a time) |
|
||||
| `/opsx:ff` | Fast-forward—create planning artifacts at once |
|
||||
| `/opsx:verify` | Validate implementation matches specs |
|
||||
| `/opsx:sync` | Preview/spec-merge without archiving |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes at once |
|
||||
| `/opsx:onboard` | Guided end-to-end onboarding workflow |
|
||||
|
||||
Enable expanded commands with `openspec config profile`, then run `openspec update`.
|
||||
|
||||
### Command Mapping from Legacy
|
||||
|
||||
| Legacy | OPSX Equivalent |
|
||||
|--------|-----------------|
|
||||
| `/openspec:proposal` | `/opsx:propose` (default) or `/opsx:new` then `/opsx:ff` (expanded) |
|
||||
| `/openspec:apply` | `/opsx:apply` |
|
||||
| `/openspec:archive` | `/opsx:archive` |
|
||||
|
||||
### New Capabilities
|
||||
|
||||
These capabilities are part of the expanded workflow command set.
|
||||
|
||||
**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-propose/ # default core profile
|
||||
│ ├── openspec-explore/
|
||||
│ ├── openspec-apply-change/
|
||||
│ ├── openspec-sync-specs/
|
||||
│ └── ... # expanded profile adds new/continue/ff/etc.
|
||||
├── 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
|
||||
|
||||
```text
|
||||
/opsx:propose Start quickly (default core profile)
|
||||
/opsx:apply Implement tasks
|
||||
/opsx:archive Finish and archive
|
||||
|
||||
# Expanded workflow (if enabled):
|
||||
/opsx:new Scaffold a change
|
||||
/opsx:continue Create next artifact
|
||||
/opsx:ff Create planning artifacts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
+659
@@ -0,0 +1,659 @@
|
||||
# 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.
|
||||
|
||||
By default, OpenSpec uses the `core` workflow profile (`propose`, `explore`, `apply`, `sync`, `archive`). If you want the expanded workflow commands (`new`, `continue`, `ff`, `verify`, `bulk-archive`, `onboard`), configure them with `openspec config profile` and apply with `openspec update`.
|
||||
|
||||
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:propose` | Create a change and generate planning artifacts in one step (default quick path) |
|
||||
| `/opsx:explore` | Think through ideas, investigate problems, clarify requirements |
|
||||
| `/opsx:new` | Start a new change scaffold (expanded workflow) |
|
||||
| `/opsx:continue` | Create the next artifact (expanded workflow) |
|
||||
| `/opsx:ff` | Fast-forward planning artifacts (expanded workflow) |
|
||||
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
|
||||
| `/opsx:verify` | Validate implementation against artifacts (expanded workflow) |
|
||||
| `/opsx:sync` | Sync delta specs to main (default workflow, optional) |
|
||||
| `/opsx:archive` | Archive when done |
|
||||
| `/opsx:bulk-archive` | Archive multiple completed changes (expanded workflow) |
|
||||
| `/opsx:onboard` | Guided walkthrough of an end-to-end change (expanded workflow) |
|
||||
|
||||
## 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:propose` (default) or `/opsx:new`/`/opsx:ff` (expanded).
|
||||
|
||||
### Start a new change
|
||||
```
|
||||
/opsx:propose
|
||||
```
|
||||
Creates the change and generates planning artifacts needed before implementation.
|
||||
|
||||
If you've enabled expanded workflows, you can instead use:
|
||||
|
||||
```text
|
||||
/opsx:new # scaffold only
|
||||
/opsx:continue # create one artifact at a time
|
||||
/opsx:ff # create all planning artifacts at once
|
||||
```
|
||||
|
||||
### 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.
|
||||
Examples in this section use the expanded command set (`new`, `continue`, etc.); default `core` users can map the same flow to `propose → apply → sync → archive`.
|
||||
|
||||
### 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) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Tool-specific configurators/adapters │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 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** | Tool-specific configurator/adapters | 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,111 @@
|
||||
# Supported Tools
|
||||
|
||||
OpenSpec works with many AI coding assistants. When you run `openspec init`, OpenSpec configures selected tools using your active profile/workflow selection and delivery mode.
|
||||
|
||||
## How It Works
|
||||
|
||||
For each selected tool, OpenSpec can install:
|
||||
|
||||
1. **Skills** (if delivery includes skills): `.../skills/openspec-*/SKILL.md`
|
||||
2. **Commands** (if delivery includes commands): tool-specific `opsx-*` command files
|
||||
|
||||
By default, OpenSpec uses the `core` profile, which includes:
|
||||
- `propose`
|
||||
- `explore`
|
||||
- `apply`
|
||||
- `sync`
|
||||
- `archive`
|
||||
|
||||
You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `bulk-archive`, `onboard`) via `openspec config profile`, then run `openspec update`.
|
||||
|
||||
## Tool Directory Reference
|
||||
|
||||
| Tool (ID) | Skills path pattern | Command path pattern |
|
||||
|-----------|---------------------|----------------------|
|
||||
| Amazon Q Developer (`amazon-q`) | `.amazonq/skills/openspec-*/SKILL.md` | `.amazonq/prompts/opsx-<id>.md` |
|
||||
| Antigravity (`antigravity`) | `.agent/skills/openspec-*/SKILL.md` | `.agent/workflows/opsx-<id>.md` |
|
||||
| Auggie (`auggie`) | `.augment/skills/openspec-*/SKILL.md` | `.augment/commands/opsx-<id>.md` |
|
||||
| IBM Bob Shell (`bob`) | `.bob/skills/openspec-*/SKILL.md` | `.bob/commands/opsx-<id>.md` |
|
||||
| Claude Code (`claude`) | `.claude/skills/openspec-*/SKILL.md` | `.claude/commands/opsx/<id>.md` |
|
||||
| Cline (`cline`) | `.cline/skills/openspec-*/SKILL.md` | `.clinerules/workflows/opsx-<id>.md` |
|
||||
| CodeBuddy (`codebuddy`) | `.codebuddy/skills/openspec-*/SKILL.md` | `.codebuddy/commands/opsx/<id>.md` |
|
||||
| Codex (`codex`) | `.codex/skills/openspec-*/SKILL.md` | `$CODEX_HOME/prompts/opsx-<id>.md`\* |
|
||||
| ForgeCode (`forgecode`) | `.forge/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
|
||||
| Continue (`continue`) | `.continue/skills/openspec-*/SKILL.md` | `.continue/prompts/opsx-<id>.prompt` |
|
||||
| CoStrict (`costrict`) | `.cospec/skills/openspec-*/SKILL.md` | `.cospec/openspec/commands/opsx-<id>.md` |
|
||||
| Crush (`crush`) | `.crush/skills/openspec-*/SKILL.md` | `.crush/commands/opsx/<id>.md` |
|
||||
| Cursor (`cursor`) | `.cursor/skills/openspec-*/SKILL.md` | `.cursor/commands/opsx-<id>.md` |
|
||||
| Factory Droid (`factory`) | `.factory/skills/openspec-*/SKILL.md` | `.factory/commands/opsx-<id>.md` |
|
||||
| Gemini CLI (`gemini`) | `.gemini/skills/openspec-*/SKILL.md` | `.gemini/commands/opsx/<id>.toml` |
|
||||
| GitHub Copilot (`github-copilot`) | `.github/skills/openspec-*/SKILL.md` | `.github/prompts/opsx-<id>.prompt.md`\*\* |
|
||||
| iFlow (`iflow`) | `.iflow/skills/openspec-*/SKILL.md` | `.iflow/commands/opsx-<id>.md` |
|
||||
| Junie (`junie`) | `.junie/skills/openspec-*/SKILL.md` | `.junie/commands/opsx-<id>.md` |
|
||||
| Kilo Code (`kilocode`) | `.kilocode/skills/openspec-*/SKILL.md` | `.kilocode/workflows/opsx-<id>.md` |
|
||||
| Kimi CLI (`kimi`) | `.kimi/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/skill:openspec-*` invocations) |
|
||||
| Kiro (`kiro`) | `.kiro/skills/openspec-*/SKILL.md` | `.kiro/prompts/opsx-<id>.prompt.md` |
|
||||
| Lingma (`lingma`) | `.lingma/skills/openspec-*/SKILL.md` | `.lingma/commands/opsx/<id>.md` |
|
||||
| OpenCode (`opencode`) | `.opencode/skills/openspec-*/SKILL.md` | `.opencode/commands/opsx-<id>.md` |
|
||||
| Pi (`pi`) | `.pi/skills/openspec-*/SKILL.md` | `.pi/prompts/opsx-<id>.md` |
|
||||
| Qoder (`qoder`) | `.qoder/skills/openspec-*/SKILL.md` | `.qoder/commands/opsx/<id>.md` |
|
||||
| Qwen Code (`qwen`) | `.qwen/skills/openspec-*/SKILL.md` | `.qwen/commands/opsx-<id>.toml` |
|
||||
| RooCode (`roocode`) | `.roo/skills/openspec-*/SKILL.md` | `.roo/commands/opsx-<id>.md` |
|
||||
| Trae (`trae`) | `.trae/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
|
||||
| Windsurf (`windsurf`) | `.windsurf/skills/openspec-*/SKILL.md` | `.windsurf/workflows/opsx-<id>.md` |
|
||||
|
||||
\* Codex commands are installed in the global Codex home (`$CODEX_HOME/prompts/` if set, otherwise `~/.codex/prompts/`), not your project directory.
|
||||
|
||||
\*\* GitHub Copilot prompt files are recognized as custom slash commands in IDE extensions (VS Code, JetBrains, Visual Studio). Copilot CLI does not currently consume `.github/prompts/*.prompt.md` directly.
|
||||
|
||||
## Non-Interactive Setup
|
||||
|
||||
For CI/CD or scripted setup, use `--tools` (and optionally `--profile`):
|
||||
|
||||
```bash
|
||||
# Configure specific tools
|
||||
openspec init --tools claude,cursor
|
||||
|
||||
# Configure all supported tools
|
||||
openspec init --tools all
|
||||
|
||||
# Skip tool configuration
|
||||
openspec init --tools none
|
||||
|
||||
# Override profile for this init run
|
||||
openspec init --profile core
|
||||
```
|
||||
|
||||
**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `forgecode`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `opencode`, `pi`, `qoder`, `lingma`, `qwen`, `roocode`, `trae`, `windsurf`
|
||||
|
||||
## Workflow-Dependent Installation
|
||||
|
||||
OpenSpec installs workflow artifacts based on selected workflows:
|
||||
|
||||
- **Core profile (default):** `propose`, `explore`, `apply`, `sync`, `archive`
|
||||
- **Custom selection:** any subset of all workflow IDs:
|
||||
`propose`, `explore`, `new`, `continue`, `apply`, `ff`, `sync`, `archive`, `bulk-archive`, `verify`, `onboard`
|
||||
|
||||
In other words, skill/command counts are profile-dependent and delivery-dependent, not fixed.
|
||||
|
||||
## Generated Skill Names
|
||||
|
||||
When selected by profile/workflow config, OpenSpec generates these skills:
|
||||
|
||||
- `openspec-propose`
|
||||
- `openspec-explore`
|
||||
- `openspec-new-change`
|
||||
- `openspec-continue-change`
|
||||
- `openspec-apply-change`
|
||||
- `openspec-ff-change`
|
||||
- `openspec-sync-specs`
|
||||
- `openspec-archive-change`
|
||||
- `openspec-bulk-archive-change`
|
||||
- `openspec-verify-change`
|
||||
- `openspec-onboard`
|
||||
|
||||
See [Commands](commands.md) for command behavior and [CLI](cli.md) for `init`/`update` options.
|
||||
|
||||
## 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,452 @@
|
||||
# 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.
|
||||
|
||||
## Two Modes
|
||||
|
||||
### Default Quick Path (`core` profile)
|
||||
|
||||
New installs default to `core`, which provides:
|
||||
- `/opsx:propose`
|
||||
- `/opsx:explore`
|
||||
- `/opsx:apply`
|
||||
- `/opsx:sync`
|
||||
- `/opsx:archive`
|
||||
|
||||
Typical flow:
|
||||
|
||||
```text
|
||||
/opsx:propose ──► /opsx:apply ──► /opsx:sync ──► /opsx:archive
|
||||
```
|
||||
|
||||
### Expanded/Full Workflow (custom selection)
|
||||
|
||||
If you want explicit scaffold-and-build commands (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:bulk-archive`, `/opsx:onboard`), enable them with:
|
||||
|
||||
```bash
|
||||
openspec config profile
|
||||
openspec update
|
||||
```
|
||||
|
||||
## Workflow Patterns (Expanded Mode)
|
||||
|
||||
### 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:propose` | Create change + planning artifacts | Fast default path (`core` profile) |
|
||||
| `/opsx:explore` | Think through ideas | Unclear requirements, investigation |
|
||||
| `/opsx:new` | Start a change scaffold | Expanded mode, explicit artifact control |
|
||||
| `/opsx:continue` | Create next artifact | Expanded mode, step-by-step artifact creation |
|
||||
| `/opsx:ff` | Create all planning artifacts | Expanded mode, clear scope |
|
||||
| `/opsx:apply` | Implement tasks | Ready to write code |
|
||||
| `/opsx:verify` | Validate implementation | Expanded mode, before archiving |
|
||||
| `/opsx:sync` | Merge delta specs | Expanded mode, optional |
|
||||
| `/opsx:archive` | Complete the change | All work finished |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes | Expanded mode, parallel work |
|
||||
|
||||
## 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,517 +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/ # Delta changes to specs
|
||||
│ │ └── [capability]/
|
||||
│ │ └── spec.md # Delta format (ADDED/MODIFIED/REMOVED/RENAMED)
|
||||
│ └── 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. Delta-Based Change Format
|
||||
|
||||
Changes use a delta format with clear sections:
|
||||
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: New Feature
|
||||
[Complete requirement content in structured format]
|
||||
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Existing Feature
|
||||
[Complete modified requirement (header must match current spec)]
|
||||
|
||||
## REMOVED Requirements
|
||||
### Requirement: Old Feature
|
||||
**Reason for removal**: [Why removing]
|
||||
**Migration path**: [How to handle existing usage]
|
||||
|
||||
## RENAMED Requirements
|
||||
- FROM: `### Requirement: Old Name`
|
||||
- TO: `### Requirement: New Name`
|
||||
```
|
||||
|
||||
Key rules:
|
||||
- Headers are matched using `normalize(header) = trim(header)`
|
||||
- Include complete requirements (not diffs)
|
||||
- Use standard symbols in CLI output: + (added), ~ (modified), - (removed), → (renamed)
|
||||
|
||||
### 4. 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 delta specs for ALL affected capabilities
|
||||
# - Store only the changes (not complete future state)
|
||||
# - Use sections: ## ADDED, ## MODIFIED, ## REMOVED, ## RENAMED
|
||||
# - Include complete requirements in their final form
|
||||
# Example spec.md content:
|
||||
# ## ADDED Requirements
|
||||
# ### Requirement: Password Reset
|
||||
# Users SHALL be able to reset passwords via email...
|
||||
#
|
||||
# ## MODIFIED Requirements
|
||||
# ### Requirement: User Authentication
|
||||
# [Complete modified requirement with new password reset hook]
|
||||
specs/
|
||||
└── [capability]/
|
||||
└── spec.md # Contains delta sections
|
||||
|
||||
# 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]
|
||||
```
|
||||
|
||||
### 5. The Change Lifecycle
|
||||
|
||||
1. **Propose** → Create change directory with delta-based 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** → Apply deltas to sync specs/ with new reality (IF the change affects system capabilities)
|
||||
6. **Archive** → Move to `changes/archive/YYYY-MM-DD-[name]/`
|
||||
|
||||
### 6. 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
|
||||
|
||||
### 7. 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.
|
||||
|
||||
### 8. 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.md describing the change
|
||||
- specs/user-auth/spec.md with:
|
||||
## ADDED Requirements
|
||||
### Requirement: Password Reset
|
||||
[Complete requirement for password reset]
|
||||
|
||||
## MODIFIED Requirements
|
||||
### Requirement: User Authentication
|
||||
[Updated to integrate with password reset]
|
||||
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,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,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-21
|
||||
@@ -0,0 +1,93 @@
|
||||
## Why
|
||||
|
||||
Parallel changes often touch the same capabilities and `cli-init`/`cli-update` behavior, but today there is no machine-readable way to express sequencing, dependencies, or expected merge order.
|
||||
|
||||
This creates three recurring problems:
|
||||
|
||||
- teams cannot tell which change should land first
|
||||
- large changes are hard to split into safe mergeable slices
|
||||
- parallel work can accidentally reintroduce assumptions already removed by another change
|
||||
|
||||
We need lightweight planning metadata and CLI guidance so contributors can safely stack plans on top of each other.
|
||||
|
||||
## What Changes
|
||||
|
||||
### 1. Add lightweight stack metadata for changes
|
||||
|
||||
Extend change metadata to support sequencing and decomposition context, for example:
|
||||
|
||||
- `dependsOn`: changes that must land first
|
||||
- `provides`: capability markers exposed by this change
|
||||
- `requires`: capability markers needed by this change
|
||||
- `touches`: capability/spec areas likely affected (advisory only; warning signal, not a hard dependency)
|
||||
- `parent`: optional parent change for split work
|
||||
|
||||
Metadata is optional and backward compatible for existing changes.
|
||||
|
||||
Ordering semantics:
|
||||
|
||||
- `dependsOn` is the source of truth for execution/archive ordering
|
||||
- `provides`/`requires` are capability contracts for validation and planning visibility
|
||||
- `provides`/`requires` do not create implicit dependency edges; authors must still declare required ordering via `dependsOn`
|
||||
|
||||
### 2. Add stack-aware validation
|
||||
|
||||
Enhance change validation to detect planning issues early:
|
||||
|
||||
- missing dependencies
|
||||
- dependency cycles
|
||||
- archive ordering violations (for example, attempting to archive a change before all `dependsOn` predecessors are archived)
|
||||
- unmatched capability markers (for example, `requires` marker with no provider in active history emits non-blocking warning)
|
||||
- overlap warnings when active changes touch the same capability
|
||||
|
||||
Validation should fail only for deterministic blockers (for example cycles or missing required dependencies), and keep overlap checks as actionable warnings.
|
||||
|
||||
### 3. Add sequencing visibility commands
|
||||
|
||||
Add lightweight CLI support to inspect and execute plan order:
|
||||
|
||||
- `openspec change graph` to show dependency DAG/order
|
||||
- `openspec change graph` validates for cycles first; when cycles are present it fails with the same deterministic cycle error as stack-aware validation
|
||||
- `openspec change next` to suggest unblocked changes ready to implement/archive
|
||||
|
||||
### 4. Add split scaffolding for large changes
|
||||
|
||||
Add helper workflow to decompose large proposals into stackable slices:
|
||||
|
||||
- `openspec change split <change-id>` scaffolds child changes with `parent` + `dependsOn`
|
||||
- generates minimal proposal/tasks stubs for each child slice
|
||||
- converts the source change into a parent planning container (no duplicate child implementation tasks)
|
||||
- re-running split for an already-split source change returns a deterministic actionable error unless `--overwrite` (alias `--force`) is passed
|
||||
- `--overwrite` / `--force` fully regenerates managed child scaffold stubs and metadata links for the split, replacing prior scaffold content
|
||||
|
||||
### 5. Document stack-first workflow
|
||||
|
||||
Update docs to describe:
|
||||
|
||||
- how to model dependencies and parent/child slices
|
||||
- when to split a large change
|
||||
- how to use graph/next validation signals during parallel development
|
||||
- migration guidance for `openspec/changes/IMPLEMENTATION_ORDER.md`:
|
||||
- machine-readable change metadata becomes the normative dependency source
|
||||
- `IMPLEMENTATION_ORDER.md` remains optional narrative context during transition
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `change-stacking-workflow`: Dependency-aware sequencing and split scaffolding for change planning
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `cli-change`: Adds graph/next/split planning commands and stack-aware validation messaging
|
||||
- `change-creation`: Supports parent/dependency metadata when creating or splitting changes
|
||||
- `openspec-conventions`: Defines optional stack metadata conventions for change proposals
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/project-config.ts` and related parsing/validation utilities for change metadata loading
|
||||
- `src/core/config-schema.ts` (or dedicated change schema) for stack metadata validation
|
||||
- `src/commands/change.ts` and/or `src/core/list.ts` for graph/next/split command behavior
|
||||
- `src/core/validation/*` for dependency cycle and overlap checks
|
||||
- `docs/cli.md`, `docs/concepts.md`, and contributor guidance for stack-aware workflows
|
||||
- tests for metadata parsing, graph ordering, next-item suggestions, and split scaffolding
|
||||
@@ -0,0 +1,15 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Stack Metadata Scaffolding
|
||||
Change creation workflows SHALL support optional dependency metadata for new or split changes.
|
||||
|
||||
#### Scenario: Create change with stack metadata
|
||||
- **WHEN** a change is created with stack metadata inputs
|
||||
- **THEN** creation SHALL persist metadata fields in change configuration
|
||||
- **AND** persisted metadata SHALL be validated against change metadata schema rules
|
||||
|
||||
#### Scenario: Split-generated child metadata
|
||||
- **WHEN** child changes are generated from a split workflow
|
||||
- **THEN** each child SHALL include a `parent` link to the source change
|
||||
- **AND** SHALL include dependency metadata needed for deterministic sequencing
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Stack Metadata Model
|
||||
The system SHALL support optional metadata on active changes to express sequencing and decomposition relationships.
|
||||
|
||||
#### Scenario: Optional stack metadata is present
|
||||
- **WHEN** a change includes stack metadata fields
|
||||
- **THEN** the system SHALL parse and expose `dependsOn`, `provides`, `requires`, `touches`, and `parent`
|
||||
- **AND** validation SHALL enforce normalized field shapes and value types (`dependsOn`/`provides`/`requires`/`touches` as string arrays, `parent` as string when present)
|
||||
|
||||
#### Scenario: Backward compatibility without stack metadata
|
||||
- **WHEN** a change does not include stack metadata
|
||||
- **THEN** existing behavior SHALL continue without migration steps
|
||||
- **AND** validation SHALL not fail solely because stack metadata is absent
|
||||
|
||||
### Requirement: Change Dependency Graph
|
||||
The system SHALL provide dependency-aware ordering for active changes.
|
||||
|
||||
#### Scenario: Build dependency order
|
||||
- **WHEN** users request stack planning output
|
||||
- **THEN** the system SHALL compute a dependency graph across active changes
|
||||
- **AND** SHALL return a deterministic topological order for unblocked changes
|
||||
|
||||
#### Scenario: Tie-breaking within the same dependency depth
|
||||
- **WHEN** multiple unblocked changes share the same topological dependency depth
|
||||
- **THEN** ordering SHALL break ties lexicographically by change ID
|
||||
- **AND** repeated runs over the same input SHALL return the same order
|
||||
|
||||
#### Scenario: Dependency cycle detection
|
||||
- **WHEN** active changes contain a dependency cycle
|
||||
- **THEN** validation SHALL fail with cycle details before archive or sequencing actions proceed
|
||||
- **AND** output SHALL include actionable guidance to break the cycle
|
||||
|
||||
### Requirement: Capability marker and overlap semantics
|
||||
The system SHALL treat capability markers as validation contracts and `touches` as advisory overlap signals.
|
||||
|
||||
#### Scenario: Required capability provided by an active change
|
||||
- **WHEN** change B declares `requires` marker `X`
|
||||
- **AND** active change A declares `provides` marker `X`
|
||||
- **THEN** validation SHALL require B to declare an explicit ordering edge in `dependsOn` to at least one active provider of `X`
|
||||
- **AND** validation SHALL fail if no explicit dependency is declared
|
||||
|
||||
#### Scenario: Requires marker without active provider
|
||||
- **WHEN** a change declares a `requires` marker
|
||||
- **AND** no active change declares the corresponding `provides` marker
|
||||
- **THEN** validation SHALL NOT infer an implicit dependency edge
|
||||
- **AND** ordering SHALL continue to be determined solely by explicit `dependsOn` relationships
|
||||
|
||||
#### Scenario: Requires marker satisfied by archived history
|
||||
- **WHEN** a change declares a `requires` marker
|
||||
- **AND** no active change provides that marker
|
||||
- **AND** at least one archived change in history provides that marker
|
||||
- **THEN** validation SHALL NOT warn solely about missing provider
|
||||
- **AND** SHALL continue to use explicit `dependsOn` for active ordering
|
||||
|
||||
#### Scenario: Requires marker missing in full history
|
||||
- **WHEN** a change declares a `requires` marker
|
||||
- **AND** no active or archived change in history provides that marker
|
||||
- **THEN** validation SHALL emit a non-blocking warning naming the change and missing marker
|
||||
- **AND** SHALL NOT infer an implicit dependency edge
|
||||
|
||||
#### Scenario: Overlap warning for shared touches
|
||||
- **WHEN** multiple active changes declare overlapping `touches` values
|
||||
- **THEN** validation SHALL emit a warning listing the overlapping changes and touched areas
|
||||
- **AND** validation SHALL NOT fail solely on overlap
|
||||
@@ -0,0 +1,27 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Stack Planning Commands
|
||||
The change CLI SHALL provide commands for dependency-aware sequencing of active changes.
|
||||
|
||||
#### Scenario: Show dependency graph
|
||||
- **WHEN** a user runs `openspec change graph`
|
||||
- **THEN** the CLI SHALL display dependency relationships for active changes
|
||||
- **AND** SHALL include a deterministic recommended order for execution
|
||||
|
||||
#### Scenario: Show next unblocked changes
|
||||
- **WHEN** a user runs `openspec change next`
|
||||
- **THEN** the CLI SHALL list changes that are not blocked by unresolved dependencies
|
||||
- **AND** SHALL use deterministic tie-breaking when multiple options are available
|
||||
|
||||
### Requirement: Split Large Change Scaffolding
|
||||
The change CLI SHALL support scaffolding child slices from an existing large change.
|
||||
|
||||
#### Scenario: Split command scaffolds child changes
|
||||
- **WHEN** a user runs `openspec change split <change-id>`
|
||||
- **THEN** the CLI SHALL create child change directories with proposal/tasks stubs
|
||||
- **AND** generated metadata SHALL include `parent` and dependency links back to the source change
|
||||
|
||||
#### Scenario: Re-running split on an already-split change
|
||||
- **WHEN** a user runs `openspec change split <change-id>` for a parent whose generated child directories already exist
|
||||
- **THEN** the CLI SHALL fail with a deterministic, actionable error
|
||||
- **AND** SHALL NOT mutate existing child change content unless an explicit overwrite mode is requested
|
||||
@@ -0,0 +1,29 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Stack-Aware Change Planning Conventions
|
||||
OpenSpec conventions SHALL define optional metadata fields for sequencing and decomposition across concurrent changes.
|
||||
|
||||
#### Scenario: Declaring change dependencies
|
||||
- **WHEN** authors need to sequence related changes
|
||||
- **THEN** conventions SHALL define how to declare dependencies and provided/required capability markers
|
||||
- **AND** validation guidance SHALL distinguish hard blockers from soft overlap warnings
|
||||
|
||||
#### Scenario: Dependency source of truth during migration
|
||||
- **WHEN** both stack metadata and `openspec/changes/IMPLEMENTATION_ORDER.md` are present
|
||||
- **THEN** conventions SHALL treat per-change stack metadata as the normative dependency source
|
||||
- **AND** `IMPLEMENTATION_ORDER.md` SHALL be treated as optional narrative guidance
|
||||
|
||||
#### Scenario: Explicit ordering remains required for capability markers
|
||||
- **WHEN** authors use `provides` and `requires` markers to describe capability contracts
|
||||
- **THEN** conventions SHALL require explicit `dependsOn` edges for ordering relationships
|
||||
- **AND** conventions SHALL prohibit treating `requires` as an implicit dependency edge
|
||||
|
||||
#### Scenario: Declaring advisory overlap via touches
|
||||
- **WHEN** a change may affect capability/spec areas shared by concurrent changes without requiring ordering
|
||||
- **THEN** conventions SHALL allow authors to declare `touches` with advisory area identifiers (for example capability IDs, spec area names, or paths)
|
||||
- **AND** tooling SHALL treat `touches` as informational only (no implicit dependency edge, non-blocking validation signal)
|
||||
|
||||
#### Scenario: Declaring parent-child split structure
|
||||
- **WHEN** a large change is decomposed into smaller slices
|
||||
- **THEN** conventions SHALL define parent-child metadata and expected ordering semantics
|
||||
- **AND** docs SHALL describe when to split versus keep a single change
|
||||
@@ -0,0 +1,39 @@
|
||||
## 1. Metadata Model
|
||||
|
||||
- [ ] 1.1 Add optional stack metadata fields (`dependsOn`, `provides`, `requires`, `touches`, `parent`) to change metadata schema
|
||||
- [ ] 1.2 Keep metadata backward compatible for existing changes without new fields
|
||||
- [ ] 1.3 Add tests for valid/invalid metadata and schema evolution behavior
|
||||
|
||||
## 2. Stack-Aware Validation
|
||||
|
||||
- [ ] 2.1 Detect dependency cycles and fail validation with deterministic errors
|
||||
- [ ] 2.2 Detect missing `dependsOn` targets (referenced change ID does not exist) and detect changes transitively blocked by unresolved/cyclic dependency paths
|
||||
- [ ] 2.3 Add overlap warnings for active changes that touch the same capability/spec areas
|
||||
- [ ] 2.4 Emit advisory warnings for unmatched `requires` markers when no provider exists in active history
|
||||
- [ ] 2.5 Add tests for cycle, missing dependency, overlap warning, and unmatched `requires` cases
|
||||
|
||||
## 3. Sequencing Commands
|
||||
|
||||
- [ ] 3.1 Add `openspec change graph` to display dependency order for active changes
|
||||
- [ ] 3.2 Add `openspec change next` to suggest unblocked changes in recommended order
|
||||
- [ ] 3.3 Add tests for topological ordering and deterministic tie-breaking (lexicographic by change ID at equal depth)
|
||||
|
||||
## 4. Split Scaffolding
|
||||
|
||||
- [ ] 4.1 Add `openspec change split <change-id>` to scaffold child slices
|
||||
- [ ] 4.2 Ensure generated children include parent/dependency metadata and stub proposal/tasks files
|
||||
- [ ] 4.3 Convert the source change into a parent planning container as part of split (no duplicate child implementation tasks)
|
||||
- [ ] 4.4 Add tests for split output structure, source-change parent conversion, and deterministic re-split error behavior when overwrite mode is not requested
|
||||
- [ ] 4.5 Implement and test explicit overwrite mode for `openspec change split` (`--overwrite` / `--force`) for controlled re-splitting
|
||||
|
||||
## 5. Documentation
|
||||
|
||||
- [ ] 5.1 Document stack metadata and sequencing workflow in `docs/concepts.md`
|
||||
- [ ] 5.2 Document new change commands and usage examples in `docs/cli.md`
|
||||
- [ ] 5.3 Add guidance for breaking large changes into independently mergeable slices
|
||||
- [ ] 5.4 Document migration guidance for `openspec/changes/IMPLEMENTATION_ORDER.md` as optional narrative, not dependency source of truth
|
||||
|
||||
## 6. Verification
|
||||
|
||||
- [ ] 6.1 Run targeted tests for change parsing, validation, and CLI commands
|
||||
- [ ] 6.2 Run full test suite (`pnpm test`) and resolve regressions
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-21
|
||||
@@ -0,0 +1,161 @@
|
||||
## Context
|
||||
|
||||
OpenSpec today assumes project-local installation for most generated artifacts, with Codex command prompts as the main global exception. This mixed model works, but it is implicit and not user-configurable.
|
||||
|
||||
The requested change is to support user-selectable install scope (`global` or `project`) for tool skills/commands, defaulting to `global` for new configurations while preserving legacy project-local behavior until explicit migration.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Provide a single scope preference that users can set globally and override per run
|
||||
- Default new users to `global` scope
|
||||
- Make install path resolution deterministic and explicit across tools/surfaces
|
||||
- Preserve current behavior for users with older config files that do not yet define `installScope`
|
||||
- Avoid silent partial installs; surface effective scope decisions in output
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Implementing project-local config file support for global settings
|
||||
- Defining global install paths for tools where upstream location conventions are unknown
|
||||
- Changing workflow/profile semantics (`core`, `custom`, `delivery`) in this change
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Scope model in global config
|
||||
|
||||
Add install scope preference to global config:
|
||||
|
||||
```ts
|
||||
type InstallScope = 'global' | 'project';
|
||||
|
||||
interface GlobalConfig {
|
||||
// existing fields...
|
||||
installScope?: InstallScope;
|
||||
}
|
||||
```
|
||||
|
||||
Defaults:
|
||||
|
||||
- New configs SHOULD write `installScope: global` explicitly.
|
||||
- Existing configs without this field continue to load safely through schema evolution and SHALL resolve effective default as `project` until users explicitly set `installScope`.
|
||||
|
||||
### 2. Explicit tool scope support metadata
|
||||
|
||||
Extend `AI_TOOLS` metadata with optional scope support declarations per surface:
|
||||
|
||||
```ts
|
||||
interface ToolInstallScopeSupport {
|
||||
skills?: InstallScope[];
|
||||
commands?: InstallScope[];
|
||||
}
|
||||
```
|
||||
|
||||
Resolution rules:
|
||||
|
||||
1. If scope support metadata is absent for a tool surface, treat it as project-only support for conservative backward compatibility.
|
||||
2. Try preferred scope.
|
||||
3. If unsupported, use alternate scope when supported.
|
||||
4. If neither is supported, fail with actionable error.
|
||||
|
||||
This enables default-global behavior while remaining safe for tools that only support project-local paths.
|
||||
|
||||
### 3. Scope-aware install target resolver
|
||||
|
||||
Introduce shared resolver utilities to compute effective target paths for:
|
||||
|
||||
- skills root directory
|
||||
- command output files
|
||||
|
||||
Resolver input:
|
||||
|
||||
- tool id
|
||||
- requested scope
|
||||
- project root
|
||||
- environment context (`CODEX_HOME`, etc.)
|
||||
|
||||
Resolver output:
|
||||
|
||||
- effective scope per surface
|
||||
- concrete target paths
|
||||
- optional fallback reasons for user-facing output
|
||||
|
||||
Platform behavior:
|
||||
|
||||
- Resolver outputs are OS-aware and normalized for the current platform.
|
||||
- Windows global targets MUST use Windows path conventions (for example `%USERPROFILE%\.codex\prompts` fallback for Codex when `CODEX_HOME` is unset), not POSIX defaults.
|
||||
|
||||
### 4. Context-aware command adapter paths
|
||||
|
||||
Update command generation contract so adapters receive install context for path resolution. This avoids hardcoded absolute/relative assumptions and centralizes scope decisions.
|
||||
|
||||
Example direction:
|
||||
|
||||
```ts
|
||||
getFilePath(commandId: string, context: InstallContext): string
|
||||
```
|
||||
|
||||
### 5. CLI behavior and UX
|
||||
|
||||
`init`:
|
||||
|
||||
- Uses configured install scope by default; if absent in a legacy config, uses migration-safe effective default (`project`).
|
||||
- Supports explicit override flag (`--scope global|project`).
|
||||
- In interactive mode, displays chosen scope and any per-tool fallback decisions before writing files.
|
||||
|
||||
`update`:
|
||||
|
||||
- Applies current scope preference (or override); if absent in a legacy config, uses migration-safe effective default (`project`).
|
||||
- Performs drift detection using effective scoped paths and last-applied scope state.
|
||||
- Reports effective scope decisions in summary output.
|
||||
|
||||
`config`:
|
||||
|
||||
- `openspec config profile` interactive flow includes install scope selection.
|
||||
- `openspec config list` shows `installScope` with source annotation (`explicit`, `new-default`, or `legacy-default`).
|
||||
|
||||
### 6. Cleanup safety during scope changes
|
||||
|
||||
When scope changes:
|
||||
|
||||
- Writes occur in the new effective targets.
|
||||
- Cleanup/removal is limited to OpenSpec-managed files for the relevant tool/workflow IDs.
|
||||
- Output explicitly states which scope locations were updated and which were cleaned.
|
||||
|
||||
### 7. Scope drift state tracking
|
||||
|
||||
Track last successful effective scope per tool/surface in project-managed state.
|
||||
|
||||
Rules:
|
||||
|
||||
1. Drift is detected when current resolved scope differs from last successful scope for a configured tool/surface.
|
||||
2. Scope support MUST be validated for all configured tools/surfaces before any write starts.
|
||||
3. Update writes to newly resolved targets first, verifies completeness, then removes managed files at previous targets.
|
||||
4. If new-target writes are partial or verification fails, command SHALL abort old-target cleanup and report actionable failure with incomplete/new and preserved/old paths.
|
||||
5. Cleanup failures do not rollback new writes; command returns actionable failure with leftover paths to resolve.
|
||||
|
||||
### 8. Coordination with command-surface capability changes
|
||||
|
||||
If `add-tool-command-surface-capabilities` lands, planning logic must evaluate scope resolution and delivery/capability behavior together (scope × delivery × command surface).
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
**Risk: Cross-project shared global state**
|
||||
Global installs are shared across projects. Updating global artifacts from one project affects all projects using that tool scope.
|
||||
→ Mitigation: make scope explicit in output; keep profile/delivery global and deterministic.
|
||||
|
||||
**Risk: Tool-specific unknown global conventions**
|
||||
Not all tools document a stable global install location.
|
||||
→ Mitigation: use explicit scope support metadata; fallback or fail instead of guessing.
|
||||
|
||||
**Risk: Adapter API churn**
|
||||
Changing adapter path contracts touches many files/tests.
|
||||
→ Mitigation: migrate in one pass with adapter contract tests and existing end-to-end generation tests.
|
||||
|
||||
## Rollout Plan
|
||||
|
||||
1. Add config schema + defaults for install scope.
|
||||
2. Add tool scope capability metadata and resolver utilities.
|
||||
3. Upgrade command adapter contract and generator path plumbing.
|
||||
4. Integrate scope-aware behavior into init/update.
|
||||
5. Add documentation and test coverage.
|
||||
@@ -0,0 +1,101 @@
|
||||
## Why
|
||||
|
||||
OpenSpec installation paths are currently inconsistent:
|
||||
|
||||
- Most skills and commands are written to project-local directories.
|
||||
- Codex commands are already global (`$CODEX_HOME/prompts` or `~/.codex/prompts`).
|
||||
- Users cannot choose a consistent install scope strategy across tools.
|
||||
|
||||
This creates friction for users who prefer user-level setup and expect tool artifacts to be managed globally by default.
|
||||
|
||||
## What Changes
|
||||
|
||||
### 1. Add install scope preference with legacy-safe defaults
|
||||
|
||||
Introduce a global install scope setting with two modes:
|
||||
|
||||
- `global` (default for newly created configs)
|
||||
- `project`
|
||||
|
||||
The setting is stored in global config and can be overridden per command run.
|
||||
For schema-evolved legacy configs where `installScope` is absent, effective default remains `project` until users opt in to global scope.
|
||||
|
||||
### 2. Add scope-aware path resolution for skills and commands
|
||||
|
||||
Refactor path resolution so both `init` and `update` compute install targets from:
|
||||
|
||||
- selected scope preference (`global` or `project`)
|
||||
- tool capability metadata (which scopes each tool/surface supports)
|
||||
- runtime context (project root, home directories, env overrides)
|
||||
|
||||
### 3. Add per-tool capability metadata for scope support
|
||||
|
||||
Extend tool metadata to explicitly declare scope support per surface:
|
||||
|
||||
- skills scope support
|
||||
- commands scope support
|
||||
|
||||
When preferred scope is unsupported for a tool/surface, the system uses deterministic fallback rules and reports the effective scope in output.
|
||||
|
||||
### 4. Make command generation context-aware
|
||||
|
||||
Extend command adapter path resolution so adapters receive install context (scope + environment context), instead of only command ID. This removes special-case handling and allows consistent scope behavior across tools.
|
||||
|
||||
### 5. Update init/update UX and behavior
|
||||
|
||||
- `openspec init`:
|
||||
- accepts scope override flag
|
||||
- uses configured scope or migration-aware default (new configs default global; legacy configs preserve project until migration)
|
||||
- applies scope-aware generation and cleanup planning
|
||||
- `openspec update`:
|
||||
- applies current scope preference
|
||||
- syncs artifacts in effective scope per tool/surface
|
||||
- tracks last successful effective scope per tool/surface for deterministic scope-drift detection
|
||||
- reports effective scope decisions clearly
|
||||
|
||||
### 6. Extend config UX and docs
|
||||
|
||||
- Add install scope control in `openspec config profile` interactive flow.
|
||||
- Extend `openspec config list` output with install scope source (`explicit`, `new-default`, `legacy-default`).
|
||||
- Add explicit migration guidance and prompt path so legacy users can opt into `global` scope.
|
||||
- Update supported tools and CLI docs to explain scope behavior and fallback rules.
|
||||
|
||||
### 7. Coordinate with command-surface capability delivery rules
|
||||
|
||||
`cli-init` and `cli-update` planning SHALL compose:
|
||||
|
||||
- install scope (`global | project`)
|
||||
- delivery mode (`both | skills | commands`)
|
||||
- command surface capability (`adapter | skills-invocable | none`)
|
||||
|
||||
This proposal remains focused on scope resolution, but implementation and test coverage should include mixed-tool cases to avoid regressions when combined with `add-tool-command-surface-capabilities`.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `installation-scope`: Scope preference model and effective scope resolution for tool artifact installation.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `global-config`: Persist install scope preference with schema evolution defaults.
|
||||
- `cli-config`: Configure and inspect install scope preferences.
|
||||
- `ai-tool-paths`: Add tool-level scope support metadata and path strategy.
|
||||
- `command-generation`: Scope-aware adapter path resolution via install context.
|
||||
- `cli-init`: Scope-aware initialization planning and output.
|
||||
- `cli-update`: Scope-aware update sync, drift detection, and output.
|
||||
- `migration`: Scope-aware migration scanning with install-scope-aware workflow lookup.
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/global-config.ts` - new install scope fields and defaults
|
||||
- `src/core/config-schema.ts` - validation support for install scope config keys
|
||||
- `src/commands/config.ts` - interactive profile/config UX additions for install scope
|
||||
- `src/core/config.ts` - tool scope capability metadata
|
||||
- `src/core/available-tools.ts` and `src/core/shared/tool-detection.ts` - scope-aware configured detection
|
||||
- `src/core/command-generation/types.ts` and adapter implementations - context-aware file path resolution
|
||||
- `src/core/init.ts` - scope-aware generation/removal planning
|
||||
- `src/core/update.ts` - scope-aware sync/removal/drift planning
|
||||
- `src/core/migration.ts` - scope-aware workflow scanning support
|
||||
- `docs/supported-tools.md` and `docs/cli.md` - install scope behavior documentation
|
||||
- `test/core/init.test.ts`, `test/core/update.test.ts`, adapter tests, config tests - scope coverage
|
||||
@@ -0,0 +1,35 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: AIToolOption skillsDir field
|
||||
The `AIToolOption` interface SHALL include scope support metadata in addition to path metadata.
|
||||
|
||||
#### Scenario: Scope support metadata present
|
||||
- **WHEN** a tool entry is defined in `AI_TOOLS`
|
||||
- **THEN** it MAY declare supported install scopes for skills and commands
|
||||
- **AND** this metadata SHALL be used for effective scope resolution
|
||||
|
||||
#### Scenario: Scope support metadata absent
|
||||
- **WHEN** a tool entry in `AI_TOOLS` omits scope support metadata for a surface
|
||||
- **THEN** resolver behavior SHALL default that surface to project-only support
|
||||
- **AND** effective scope resolution SHALL apply normal preferred/fallback rules against that default
|
||||
|
||||
### Requirement: Path configuration for supported tools
|
||||
Path metadata SHALL support both project and global install targets via resolver logic.
|
||||
|
||||
#### Scenario: Project scope path
|
||||
- **WHEN** effective scope is `project` for skills
|
||||
- **THEN** `skillsDir` SHALL be treated as a tool-specific container path under project root
|
||||
- **AND** managed skill artifacts SHALL be written under `<projectRoot>/<skillsDir>/skills/`
|
||||
- **AND** tool definitions SHALL set `skillsDir` accordingly (for example `.openspec` -> `.openspec/skills/`)
|
||||
|
||||
#### Scenario: Global scope path
|
||||
- **WHEN** effective scope is `global` for a supported tool/surface
|
||||
- **THEN** paths SHALL resolve to tool-specific global directories
|
||||
- **AND** environment overrides (for example `CODEX_HOME`) SHALL be respected where applicable
|
||||
|
||||
#### Scenario: Windows global path resolution for Codex commands
|
||||
- **WHEN** effective scope is `global`
|
||||
- **AND** tool is Codex
|
||||
- **AND** platform is Windows
|
||||
- **THEN** command targets SHALL resolve to `%CODEX_HOME%\prompts` when `CODEX_HOME` is set
|
||||
- **AND** SHALL otherwise resolve to `%USERPROFILE%\.codex\prompts`
|
||||
@@ -0,0 +1,21 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Install scope configuration via profile flow
|
||||
The config profile workflow SHALL allow users to configure install scope preference.
|
||||
|
||||
#### Scenario: Interactive profile includes install scope
|
||||
- **WHEN** user runs `openspec config profile`
|
||||
- **THEN** the interactive flow SHALL include install scope selection with values `global` and `project`
|
||||
- **AND** the currently configured value SHALL be pre-selected
|
||||
|
||||
#### Scenario: Save install scope
|
||||
- **WHEN** user confirms config profile changes
|
||||
- **THEN** selected install scope SHALL be saved to global config
|
||||
|
||||
### Requirement: Install scope visibility in config output
|
||||
The config command SHALL display install scope preference in human-readable output.
|
||||
|
||||
#### Scenario: Config list shows install scope
|
||||
- **WHEN** user runs `openspec config list`
|
||||
- **THEN** output SHALL include current install scope value
|
||||
- **AND** indicate whether value is default or explicit
|
||||
@@ -0,0 +1,28 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Init install scope selection
|
||||
The init command SHALL support install scope selection for generated artifacts.
|
||||
|
||||
#### Scenario: Scope defaults to global
|
||||
- **WHEN** user runs `openspec init` without explicit scope override
|
||||
- **THEN** init SHALL use global config install scope
|
||||
- **AND** if unset, SHALL resolve migration-aware default (`global` for newly created configs, `project` for legacy schema-evolved configs)
|
||||
|
||||
#### Scenario: Scope override via flag
|
||||
- **WHEN** user runs `openspec init --scope project`
|
||||
- **THEN** init SHALL use `project` as preferred scope for that run
|
||||
- **AND** SHALL NOT mutate persisted global config unless user explicitly changes config
|
||||
|
||||
### Requirement: Init uses effective scope resolution
|
||||
The init command SHALL resolve effective scope per tool surface before generating files.
|
||||
|
||||
#### Scenario: Effective scope with fallback
|
||||
- **WHEN** selected tool/surface does not support preferred scope
|
||||
- **AND** supports alternate scope
|
||||
- **THEN** init SHALL generate files at alternate effective scope
|
||||
- **AND** SHALL display fallback note in summary
|
||||
|
||||
#### Scenario: Unsupported scope selection
|
||||
- **WHEN** selected tool/surface supports neither preferred nor alternate scope
|
||||
- **THEN** init SHALL fail before writing files
|
||||
- **AND** SHALL provide clear error guidance
|
||||
@@ -0,0 +1,34 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Update install scope selection
|
||||
The update command SHALL support install scope selection for sync operations.
|
||||
|
||||
#### Scenario: Scope defaults to global config value
|
||||
- **WHEN** user runs `openspec update` without explicit scope override
|
||||
- **THEN** update SHALL use configured install scope
|
||||
- **AND** if unset, SHALL resolve migration-aware default (`global` for newly created configs, `project` for legacy schema-evolved configs)
|
||||
|
||||
#### Scenario: Scope override via flag
|
||||
- **WHEN** user runs `openspec update --scope project`
|
||||
- **THEN** update SHALL use `project` as preferred scope for that run
|
||||
|
||||
### Requirement: Scope-aware sync and drift detection
|
||||
The update command SHALL evaluate configured state and drift using effective scoped paths.
|
||||
|
||||
#### Scenario: Scoped drift detection
|
||||
- **WHEN** update evaluates whether tools are up-to-date
|
||||
- **THEN** it SHALL inspect files at effective scoped targets for each tool/surface
|
||||
- **AND** SHALL compare current resolved scope against last successful effective scope for each tool/surface
|
||||
- **AND** SHALL treat a difference as sync-required drift
|
||||
|
||||
#### Scenario: Scope fallback during update
|
||||
- **WHEN** preferred scope is unsupported for a configured tool/surface
|
||||
- **AND** alternate scope is supported
|
||||
- **THEN** update SHALL apply fallback scope resolution
|
||||
- **AND** SHALL report fallback in output
|
||||
|
||||
#### Scenario: Unsupported scope during update
|
||||
- **WHEN** configured tool/surface supports neither preferred nor alternate scope
|
||||
- **THEN** scope support SHALL be validated for all configured tools/surfaces before any write
|
||||
- **AND** update SHALL fail without performing file writes when incompatibilities are detected
|
||||
- **AND** SHALL report incompatible tools with remediation steps
|
||||
@@ -0,0 +1,22 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: ToolCommandAdapter interface
|
||||
The system SHALL provide install-context-aware command path resolution.
|
||||
|
||||
#### Scenario: Adapter interface structure
|
||||
- **WHEN** implementing a tool adapter
|
||||
- **THEN** command file path resolution SHALL receive install context (including effective scope and environment context)
|
||||
- **AND** SHALL return the effective command output path for that context
|
||||
|
||||
#### Scenario: Codex global path remains supported
|
||||
- **WHEN** resolving Codex command paths in global scope
|
||||
- **THEN** the adapter SHALL target `$CODEX_HOME/prompts` when `CODEX_HOME` is set
|
||||
- **AND** SHALL otherwise target `~/.codex/prompts`
|
||||
|
||||
### Requirement: Command generator function
|
||||
The command generator SHALL pass install context into adapter path resolution for all generated commands.
|
||||
|
||||
#### Scenario: Scoped command generation
|
||||
- **WHEN** generating commands for a tool with a resolved effective scope
|
||||
- **THEN** generated command paths SHALL match that effective scope
|
||||
- **AND** the formatted command body/frontmatter behavior SHALL remain tool-specific and unchanged
|
||||
@@ -0,0 +1,24 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Install scope field in global config
|
||||
The global config schema SHALL include install scope preference.
|
||||
|
||||
#### Scenario: Config shape supports install scope
|
||||
- **WHEN** reading or writing global config
|
||||
- **THEN** config SHALL support `installScope` with allowed values `global` and `project`
|
||||
|
||||
#### Scenario: Schema evolution default
|
||||
- **WHEN** loading legacy config without `installScope`
|
||||
- **THEN** the system SHALL preserve schema compatibility without mutating the file
|
||||
- **AND** effective install scope SHALL resolve to `project` until user explicitly sets `installScope`
|
||||
- **AND** preserve all other existing fields
|
||||
|
||||
#### Scenario: New config default
|
||||
- **WHEN** creating a new global config
|
||||
- **THEN** the system SHALL persist `installScope: global` by default
|
||||
- **AND** users MAY switch to `project` explicitly
|
||||
|
||||
#### Scenario: Invalid install scope value
|
||||
- **WHEN** config validation receives an invalid install scope value
|
||||
- **THEN** the value SHALL be rejected
|
||||
- **AND** the system SHALL preserve the existing valid configuration
|
||||
@@ -0,0 +1,71 @@
|
||||
## Purpose
|
||||
|
||||
Define the install scope model for OpenSpec-generated skills and commands, including scope preference, effective scope resolution, and fallback/error semantics.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Install scope preference model
|
||||
The system SHALL support a user-level install scope preference with values `global` and `project`.
|
||||
|
||||
#### Scenario: Default install scope
|
||||
- **WHEN** install scope is not explicitly configured
|
||||
- **THEN** the system SHALL resolve a migration-aware default:
|
||||
- **AND** use `global` for newly created configs
|
||||
- **AND** use `project` for legacy schema-evolved configs until explicit migration
|
||||
|
||||
#### Scenario: Explicit install scope
|
||||
- **WHEN** user configures install scope to `project`
|
||||
- **THEN** generation and update flows SHALL use `project` as the preferred scope
|
||||
|
||||
### Requirement: Effective scope resolution by tool surface
|
||||
The system SHALL compute effective scope per tool surface (skills, commands) based on preferred scope and tool capability support.
|
||||
|
||||
#### Scenario: Preferred scope is supported
|
||||
- **WHEN** preferred scope is supported for a tool surface
|
||||
- **THEN** the system SHALL use that scope as the effective scope
|
||||
|
||||
#### Scenario: Preferred scope is unsupported but alternate is supported
|
||||
- **WHEN** preferred scope is not supported for a tool surface
|
||||
- **AND** the alternate scope is supported
|
||||
- **THEN** the system SHALL use the alternate scope as effective scope
|
||||
- **AND** SHALL record a fallback note for user-facing output
|
||||
|
||||
#### Scenario: No supported scope
|
||||
- **WHEN** neither `global` nor `project` is supported for a tool surface
|
||||
- **THEN** the command SHALL fail before writing files
|
||||
- **AND** SHALL display actionable remediation
|
||||
|
||||
### Requirement: Effective scope reporting
|
||||
The system SHALL report effective scope decisions in command output when they differ from the preferred scope.
|
||||
|
||||
#### Scenario: Fallback reporting
|
||||
- **WHEN** fallback resolution occurs for any selected/configured tool surface
|
||||
- **THEN** init/update summaries SHALL include effective scope notes per affected tool
|
||||
|
||||
### Requirement: Cross-platform path behavior
|
||||
Install scope resolution SHALL produce platform-correct target paths.
|
||||
|
||||
#### Scenario: Global scope path on Windows
|
||||
- **WHEN** effective scope is `global`
|
||||
- **AND** the command runs on Windows
|
||||
- **THEN** resolved target paths SHALL use Windows path conventions and separators
|
||||
- **AND** SHALL NOT reuse POSIX-style home-relative defaults directly
|
||||
|
||||
### Requirement: Cleanup safety for scope transitions
|
||||
Scope transitions SHALL update new targets first and clean old managed targets safely.
|
||||
|
||||
#### Scenario: Automatic cleanup for managed files on scope change
|
||||
- **WHEN** update or init applies a scope transition for a configured tool/surface
|
||||
- **THEN** the system SHALL write new artifacts in the new effective scope before cleanup
|
||||
- **AND** SHALL automatically remove only OpenSpec-managed files in the previous effective scope
|
||||
|
||||
#### Scenario: Cleanup scope boundaries
|
||||
- **WHEN** cleanup runs after a scope transition
|
||||
- **THEN** the system SHALL leave non-managed files untouched
|
||||
- **AND** SHALL limit removal scope to the affected tool/workflow-managed paths
|
||||
|
||||
#### Scenario: Cleanup failure after successful writes
|
||||
- **WHEN** new artifacts were written successfully in the new scope
|
||||
- **AND** cleanup of old managed targets fails
|
||||
- **THEN** the command SHALL report failure with leftover cleanup paths
|
||||
- **AND** SHALL NOT rollback successfully written new-scope artifacts
|
||||
@@ -0,0 +1,61 @@
|
||||
## 1. Global Config + Validation
|
||||
|
||||
- [ ] 1.1 Add `installScope` (`global` | `project`) to `GlobalConfig` with explicit `global` default for newly created configs
|
||||
- [ ] 1.2 Update config schema validation and known-key checks to include install scope
|
||||
- [ ] 1.3 Add schema-evolution tests ensuring missing `installScope` in legacy configs resolves to effective `project` until explicit migration
|
||||
- [ ] 1.4 Extend `openspec config list` output to show install scope and source (`explicit`, `new-default`, `legacy-default`)
|
||||
|
||||
## 2. Tool Capability Metadata + Resolvers
|
||||
|
||||
- [ ] 2.1 Extend `AI_TOOLS` metadata to declare scope support per surface (skills/commands)
|
||||
- [ ] 2.2 Add shared install-target resolver for skills and commands using requested scope + tool support
|
||||
- [ ] 2.3 Implement deterministic fallback/error behavior when preferred scope is unsupported, including default behavior when scope support metadata is absent
|
||||
- [ ] 2.4 Add unit tests for scope resolution (preferred, fallback, and hard-fail paths)
|
||||
|
||||
## 3. Command Generation Contract
|
||||
|
||||
- [ ] 3.1 Update `ToolCommandAdapter` path contract to accept install context
|
||||
- [ ] 3.2 Update `generateCommand`/`generateCommands` to pass context through adapters
|
||||
- [ ] 3.3 Migrate all command adapters to the new path contract
|
||||
- [ ] 3.4 Update adapter tests for scoped path behavior (including Codex global path semantics)
|
||||
|
||||
## 4. Init Command Scope Support
|
||||
|
||||
- [ ] 4.1 Add scope override flag to `openspec init` (`--scope global|project`)
|
||||
- [ ] 4.2 Resolve effective scope per tool/surface before writing artifacts
|
||||
- [ ] 4.3 Apply scope-aware generation/removal planning for skills and commands
|
||||
- [ ] 4.4 Surface effective scope decisions and fallback notes in init summary output
|
||||
- [ ] 4.5 Add init tests for global default, project override, and fallback/error scenarios
|
||||
|
||||
## 5. Update Command Scope Support
|
||||
|
||||
- [ ] 5.1 Add scope override flag to `openspec update` (`--scope global|project`)
|
||||
- [ ] 5.2 Make configured-tool detection and drift checks scope-aware
|
||||
- [ ] 5.3 Persist and read last successful effective scope per tool/surface for deterministic scope-drift detection
|
||||
- [ ] 5.4 Apply scope-aware sync/removal with consistent fallback/error behavior
|
||||
- [ ] 5.5 Ensure scope changes update managed files in new targets and clean old managed targets safely
|
||||
- [ ] 5.6 Add update tests for global/project/fallback/error and repeat-run idempotency
|
||||
|
||||
## 6. Config UX
|
||||
|
||||
- [ ] 6.1 Extend `openspec config profile` interactive flow to select install scope
|
||||
- [ ] 6.2 Preserve install scope when using preset shortcuts unless explicitly changed
|
||||
- [ ] 6.3 Ensure non-interactive config behavior remains deterministic with clear errors
|
||||
- [ ] 6.4 Add/adjust config command tests for install scope flows
|
||||
- [ ] 6.5 Add migration UX for legacy users to opt into `global` scope explicitly
|
||||
|
||||
## 7. Documentation
|
||||
|
||||
- [ ] 7.1 Update `docs/supported-tools.md` with scope behavior and effective-scope fallback notes
|
||||
- [ ] 7.2 Update `docs/cli.md` examples for init/update scope options
|
||||
- [ ] 7.3 Document cross-project implications of global installs
|
||||
- [ ] 7.4 Add existing-user migration guide covering legacy-default behavior and explicit opt-in to `installScope: global`
|
||||
|
||||
## 8. Verification
|
||||
|
||||
- [ ] 8.1 Run targeted tests for config, adapters, init, and update
|
||||
- [ ] 8.2 Run full test suite (`pnpm test`) and resolve regressions
|
||||
- [ ] 8.3 Manual smoke test: init/update with `installScope=global`
|
||||
- [ ] 8.4 Manual smoke test: init/update with `--scope project`
|
||||
- [ ] 8.5 Verify path resolution behavior on Windows CI (or cross-platform unit tests with mocked Windows paths)
|
||||
- [ ] 8.6 Verify combined behavior matrix for mixed tools across scope × delivery × command-surface capability
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-20
|
||||
@@ -0,0 +1,45 @@
|
||||
## Why
|
||||
|
||||
We need a faster, more reliable way to manually validate CLI behavior changes like profile/delivery sync, migration behavior, and tool-detection UX.
|
||||
|
||||
Today, manual review is mostly ad hoc: each developer sets up state differently, runs a different command order, and checks outputs informally. This makes regressions easy to miss and slows iteration on CLI UX work.
|
||||
|
||||
An 80/20 solution is to add a lightweight smoke harness for deterministic non-interactive flows, plus a short manual checklist for interactive prompt behavior.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a lightweight QA smoke harness for OpenSpec CLI behavior with isolated per-run sandbox state
|
||||
- Use `Makefile` targets as the primary entrypoint:
|
||||
- `make qa` (default local QA entrypoint)
|
||||
- `make qa-smoke` (deterministic non-interactive suite)
|
||||
- `make qa-interactive` (prints/opens manual interactive checklist)
|
||||
- Implement smoke logic in a script (invoked by Make targets), not in Make itself
|
||||
- Ensure each scenario runs in an isolated sandbox with temporary `HOME`, `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, and `CODEX_HOME`
|
||||
- Capture scenario artifacts for inspection (command output, exit code, and before/after filesystem state)
|
||||
- Add a focused scenario set for high-risk behavior:
|
||||
- init core output generation
|
||||
- non-interactive detected-tool behavior
|
||||
- migration when profile is unset
|
||||
- delivery cleanup (`both -> skills`, `both -> commands`)
|
||||
- commands-only update detection
|
||||
- new tool directory detection messaging
|
||||
- invalid profile override validation
|
||||
- Add a short interactive checklist for keypress/prompt UX verification (Space toggle, Enter confirm, detected pre-selection)
|
||||
- Wire CI to run the smoke suite on Linux as a fast regression gate
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `qa-smoke-harness`: Deterministic, sandboxed CLI smoke validation with a single developer entrypoint
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `developer-qa-workflow`: Standardized local/CI QA flow for CLI behavior and migration-sensitive scenarios
|
||||
|
||||
## Impact
|
||||
|
||||
- `Makefile` - Add `qa`, `qa-smoke`, and `qa-interactive` targets
|
||||
- `scripts/qa-smoke.sh` (or equivalent) - Implement sandbox setup, scenario execution, and assertions
|
||||
- `docs/` - Add/update contributor-facing QA instructions and interactive checklist usage
|
||||
- CI workflow - Add smoke target execution as a lightweight regression gate
|
||||
@@ -0,0 +1,49 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Makefile QA Entry Point
|
||||
|
||||
The repository SHALL provide Makefile targets as the primary developer entrypoint for CLI QA flows.
|
||||
|
||||
#### Scenario: Default QA target runs smoke suite
|
||||
|
||||
- **WHEN** a developer runs `make qa`
|
||||
- **THEN** the command SHALL execute the non-interactive smoke suite
|
||||
- **AND** exit with status code 0 only when all smoke scenarios pass
|
||||
|
||||
#### Scenario: Smoke suite target is directly invokable
|
||||
|
||||
- **WHEN** a developer runs `make qa-smoke`
|
||||
- **THEN** the command SHALL execute the same smoke suite used by `make qa`
|
||||
- **AND** return a non-zero exit code on assertion failure
|
||||
|
||||
#### Scenario: Interactive checklist target exists
|
||||
|
||||
- **WHEN** a developer runs `make qa-interactive`
|
||||
- **THEN** the command SHALL provide the manual interactive verification checklist
|
||||
- **AND** SHALL NOT run interactive prompt automation by default
|
||||
|
||||
### Requirement: Sandboxed Smoke Scenario Runner
|
||||
|
||||
The smoke suite SHALL run CLI scenarios in isolated sandboxes so tests are repeatable and do not depend on machine-global state.
|
||||
|
||||
#### Scenario: Scenario execution is environment-isolated
|
||||
|
||||
- **WHEN** a smoke scenario runs
|
||||
- **THEN** it SHALL use temporary values for `HOME`, `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, and `CODEX_HOME`
|
||||
- **AND** global config from the host machine SHALL NOT affect scenario outcomes
|
||||
|
||||
#### Scenario: Scenario artifacts are captured for review
|
||||
|
||||
- **WHEN** a smoke scenario completes
|
||||
- **THEN** the runner SHALL capture command output and exit status
|
||||
- **AND** SHALL capture enough filesystem state to inspect before/after behavior
|
||||
|
||||
#### Scenario: High-risk workflow coverage exists
|
||||
|
||||
- **WHEN** the smoke suite executes
|
||||
- **THEN** it SHALL include scenarios covering profile/delivery behavior and migration-sensitive flows
|
||||
- **AND** include at least:
|
||||
- non-interactive tool detection
|
||||
- migration when profile is unset
|
||||
- delivery cleanup (`both -> skills`, `both -> commands`)
|
||||
- commands-only update detection
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-19
|
||||
@@ -0,0 +1,111 @@
|
||||
## Why
|
||||
|
||||
OpenSpec currently assumes command delivery maps directly to command adapters. That assumption does not hold for all tools.
|
||||
|
||||
Trae is a concrete example: it invokes OpenSpec workflows via skill entries (for example `/openspec-new-change`) rather than adapter-generated command files. In this model, skills are the command surface.
|
||||
|
||||
Today, this creates a behavior gap:
|
||||
|
||||
- `delivery=commands` can remove skills
|
||||
- tools without adapters skip command generation
|
||||
- result: selected tools like Trae can end up with no invocable workflow artifacts
|
||||
|
||||
This is more than a prompt UX issue because non-interactive and CI flows bypass interactive guidance. We need a capability-aware model in core generation logic.
|
||||
|
||||
## What Changes
|
||||
|
||||
### 1. Add explicit command-surface capability metadata
|
||||
|
||||
Add an optional field in tool metadata to describe how a tool exposes commands:
|
||||
|
||||
- `adapter`: command files are generated through a command adapter
|
||||
- `skills-invocable`: skills are directly invocable as commands
|
||||
- `none`: no OpenSpec command surface
|
||||
|
||||
Field should be optional. Default behavior is inferred from adapter registry presence: tools with a registered adapter resolve to `adapter`; tools with no adapter registration and no explicit annotation resolve to `none`.
|
||||
Capability values use kebab-case string tokens for consistency with serialized metadata conventions.
|
||||
|
||||
Initial explicit override:
|
||||
|
||||
- Trae -> `skills-invocable`
|
||||
|
||||
### 2. Make delivery behavior capability-aware
|
||||
|
||||
Update `init` and `update` to compute effective artifact actions per tool from:
|
||||
|
||||
- global delivery (`both | skills | commands`)
|
||||
- tool command surface capability
|
||||
|
||||
Behavior matrix:
|
||||
|
||||
- `both`:
|
||||
- generate skills for all tools with `skillsDir` (including `skills-invocable`)
|
||||
- generate command files only for `adapter` tools
|
||||
- `none`: no artifact action; MAY emit compatibility warning
|
||||
- `skills`:
|
||||
- generate skills for all tools with `skillsDir` (including `skills-invocable`)
|
||||
- remove adapter-generated command files
|
||||
- `none`: no artifact action; MAY emit compatibility warning
|
||||
- `commands`:
|
||||
- `adapter`: generate commands, remove skills
|
||||
- `skills-invocable`: generate (or keep if up-to-date) skills as command surface; do not remove them
|
||||
- `none`: fail fast with clear error
|
||||
|
||||
### 3. Add preflight validation and clearer output
|
||||
|
||||
Before writing/removing artifacts, validate selected/configured tools against delivery mode:
|
||||
|
||||
- interactive flow: show clear compatibility note before confirmation
|
||||
- non-interactive flow: fail with deterministic error listing incompatible tools and supported alternatives
|
||||
|
||||
Update summaries to show effective delivery outcomes per tool (for example, when commands mode still installs skills for skills-invocable tools).
|
||||
|
||||
### 4. Update docs and tests
|
||||
|
||||
- document capability model and Trae behavior under delivery modes
|
||||
- ensure CLI docs and supported-tools docs reflect effective behavior
|
||||
- add test coverage for:
|
||||
- `init --tools trae` with `delivery=commands`
|
||||
- `update` with Trae configured under `delivery=commands`
|
||||
- mixed selections (`claude + trae`) across all delivery modes
|
||||
- explicit error path for tools with no command surface under `delivery=commands`
|
||||
|
||||
### 5. Coordinate with install-scope behavior
|
||||
|
||||
When combined with `add-global-install-scope`, init/update planning must compose:
|
||||
|
||||
- install scope (`global | project`)
|
||||
- delivery mode (`both | skills | commands`)
|
||||
- command surface capability (`adapter | skills-invocable | none`)
|
||||
|
||||
Implementation tests should cover mixed-tool matrices to ensure deterministic behavior when both changes are active.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `tool-command-surface`: Capability model that classifies tools as `adapter`, `skills-invocable`, or `none` to drive delivery behavior
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `cli-init`: Delivery handling becomes tool-capability-aware with preflight compatibility validation
|
||||
- `cli-update`: Delivery sync becomes tool-capability-aware with consistent compatibility validation and messaging
|
||||
- `supported-tools-docs`: Documents command-surface semantics for non-adapter tools
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/config.ts` - add optional command-surface metadata and Trae override
|
||||
- `src/core/command-generation/registry.ts` (or shared helper) - capability inference from adapter presence
|
||||
- `src/core/init.ts` - capability-aware generation/removal planning + compatibility validation + summary messaging
|
||||
- `src/core/update.ts` - capability-aware sync/removal planning + compatibility validation + summary messaging
|
||||
- `src/core/shared/tool-detection.ts` - include capability-aware detection so `skills-invocable` tools remain detectable under `delivery=commands`, and `none` tools are excluded from command-surface artifact detection
|
||||
- `docs/supported-tools.md` and `docs/cli.md` - document delivery behavior and compatibility notes
|
||||
- `test/core/init.test.ts` and `test/core/update.test.ts` - add coverage for skills-invocable behavior and mixed-tool delivery scenarios
|
||||
|
||||
## Sequencing Notes
|
||||
|
||||
- This change is intended to stack safely with `simplify-skill-installation` by introducing additive, capability-specific requirements for init/update.
|
||||
- If `simplify-skill-installation` merges first, this change should be rebased and keep the capability-aware rule as the source of truth for `delivery=commands` behavior on `skills-invocable` tools.
|
||||
- If this change merges first, the `simplify-skill-installation` branch should be rebased to avoid re-introducing a global "commands-only means no skills for all tools" assumption.
|
||||
- If `add-global-install-scope` merges first, this change should be rebased to compose capability-aware behavior on top of scope-resolved path decisions from that change.
|
||||
- If this change merges first, `add-global-install-scope` should be rebased to preserve Section 5 composition rules (`install scope` + `delivery mode` + `command surface capability`) without overriding capability-aware command-surface outcomes.
|
||||
@@ -0,0 +1,121 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Command surface capability resolution
|
||||
The init command SHALL resolve each selected tool's command surface using explicit metadata first, then deterministic inference.
|
||||
|
||||
#### Scenario: Explicit command surface override
|
||||
- **WHEN** a tool declares an explicit command-surface capability
|
||||
- **THEN** init SHALL use that explicit capability
|
||||
- **AND** SHALL NOT override it based on adapter presence
|
||||
|
||||
#### Scenario: Inferred command surface from adapter presence
|
||||
- **WHEN** a tool does not declare an explicit command-surface capability
|
||||
- **AND** a command adapter is registered for the tool
|
||||
- **THEN** init SHALL infer `adapter` as the command surface
|
||||
|
||||
#### Scenario: Inferred command surface for skills-only tool
|
||||
- **WHEN** a tool does not declare an explicit command-surface capability
|
||||
- **AND** no command adapter is registered for the tool
|
||||
- **AND** the tool has a configured `skillsDir`
|
||||
- **THEN** init SHALL infer `skills-invocable` as the command surface
|
||||
|
||||
#### Scenario: Inferred command surface without adapter or skills
|
||||
- **WHEN** a tool does not declare an explicit command-surface capability
|
||||
- **AND** no command adapter is registered for the tool
|
||||
- **AND** the tool has no `skillsDir`
|
||||
- **THEN** init SHALL infer `none` as the command surface
|
||||
|
||||
### Requirement: Delivery compatibility by tool command surface
|
||||
The init command SHALL apply delivery settings using each tool's command surface capability, not adapter presence alone.
|
||||
|
||||
#### Scenario: Both delivery for adapter-backed tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool that has a command adapter
|
||||
- **AND** delivery is set to `both`
|
||||
- **THEN** the system SHALL generate command files for active workflows using that adapter
|
||||
- **AND** SHALL generate or refresh managed skills when the tool has `skillsDir`
|
||||
|
||||
#### Scenario: Both delivery for skills-invocable tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `skills-invocable`
|
||||
- **AND** delivery is set to `both`
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories when the tool has `skillsDir`
|
||||
- **AND** SHALL NOT require adapter-generated command files for that tool
|
||||
|
||||
#### Scenario: Both delivery for none command surface
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `none`
|
||||
- **AND** delivery is set to `both`
|
||||
- **THEN** the system SHALL perform no command-surface artifact action for that tool
|
||||
- **AND** MAY emit a compatibility note indicating no command surface is available
|
||||
|
||||
#### Scenario: Skills delivery for adapter-backed tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool that has a command adapter
|
||||
- **AND** delivery is set to `skills`
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories when the tool has `skillsDir`
|
||||
- **AND** SHALL remove managed adapter-generated command files for that tool
|
||||
|
||||
#### Scenario: Skills delivery for skills-invocable tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `skills-invocable`
|
||||
- **AND** delivery is set to `skills`
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories when the tool has `skillsDir`
|
||||
- **AND** SHALL NOT require adapter-generated command files for that tool
|
||||
|
||||
#### Scenario: Skills delivery for none command surface
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `none`
|
||||
- **AND** delivery is set to `skills`
|
||||
- **THEN** the system SHALL perform no command-surface artifact action for that tool
|
||||
- **AND** MAY emit a compatibility note indicating no command surface is available
|
||||
|
||||
#### Scenario: Commands delivery for adapter-backed tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool that has a command adapter
|
||||
- **AND** delivery is set to `commands`
|
||||
- **THEN** the system SHALL generate command files for active workflows using that adapter
|
||||
- **AND** the system SHALL remove managed skill directories for that tool
|
||||
|
||||
#### Scenario: Commands delivery for skills-invocable tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `skills-invocable`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories for active workflows
|
||||
- **AND** the system SHALL NOT remove those managed skill directories as part of commands-only cleanup
|
||||
- **AND** the system SHALL NOT require a command adapter for that tool
|
||||
|
||||
#### Scenario: Commands delivery for mixed tool selection
|
||||
- **WHEN** user runs `openspec init` with multiple tools
|
||||
- **AND** selected tools include both adapter-backed and skills-invocable command surfaces
|
||||
- **AND** delivery is set to `commands`
|
||||
- **THEN** the system SHALL apply commands-only behavior per tool capability
|
||||
- **AND** the resulting install SHALL include command files for adapter-backed tools and skills for skills-invocable tools
|
||||
|
||||
#### Scenario: Commands delivery for unsupported command surface
|
||||
- **WHEN** user runs `openspec init` with a selected tool that has no command surface capability
|
||||
- **AND** delivery is set to `commands`
|
||||
- **THEN** the system SHALL fail before generating or deleting artifacts
|
||||
- **AND** the error SHALL list incompatible tool IDs and explain supported alternatives (`both` or `skills`)
|
||||
|
||||
#### Scenario: Interactive handling for unsupported command surface
|
||||
- **WHEN** user runs `openspec init` interactively
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** selected tools include one or more tools with command surface `none`
|
||||
- **THEN** the CLI SHALL show a compatibility error and return to the interactive selection flow for correction
|
||||
- **AND** SHALL not perform artifact writes until a valid selection is confirmed
|
||||
|
||||
### Requirement: Init compatibility signaling
|
||||
The init command SHALL clearly signal command-surface compatibility outcomes in both interactive and non-interactive flows.
|
||||
|
||||
#### Scenario: Interactive compatibility note
|
||||
- **WHEN** init runs interactively
|
||||
- **AND** delivery is `commands`
|
||||
- **AND** selected tools include skills-invocable command surfaces
|
||||
- **THEN** the system SHALL display a compatibility note before the confirmation prompt indicating those tools will use skills as their command surface
|
||||
|
||||
#### Scenario: Non-interactive compatibility summary for skills-invocable tools
|
||||
- **WHEN** init runs non-interactively (including `--tools` usage)
|
||||
- **AND** delivery is `commands`
|
||||
- **AND** selected tools include one or more `skills-invocable` command surfaces
|
||||
- **THEN** the command SHALL proceed with exit code 0
|
||||
- **AND** the command SHALL write deterministic compatibility summary lines to stdout indicating those tools will use managed skills as their command surface
|
||||
|
||||
#### Scenario: Non-interactive compatibility failure
|
||||
- **WHEN** init runs non-interactively (including `--tools` usage)
|
||||
- **AND** delivery is `commands`
|
||||
- **AND** selected tools include any tool with no command surface capability
|
||||
- **THEN** the command SHALL exit with code 1
|
||||
- **AND** the command SHALL write deterministic, actionable guidance for resolving the selection to stderr
|
||||
@@ -0,0 +1,48 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Delivery sync by command surface capability
|
||||
The update command SHALL synchronize artifacts using each configured tool's command surface capability.
|
||||
|
||||
#### Scenario: Commands delivery for adapter-backed configured tool
|
||||
- **WHEN** user runs `openspec update`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** a configured tool has an adapter-backed command surface
|
||||
- **THEN** the system SHALL generate or refresh command files for active workflows
|
||||
- **AND** the system SHALL remove managed skill directories for that tool
|
||||
|
||||
#### Scenario: Commands delivery for skills-invocable configured tool
|
||||
- **WHEN** user runs `openspec update`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** a configured tool has `skills-invocable` command surface capability
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories for active workflows
|
||||
- **AND** the system SHALL NOT remove those managed skill directories as part of commands-only cleanup
|
||||
- **AND** the system SHALL NOT attempt to require adapter-generated command files for that tool
|
||||
|
||||
#### Scenario: Commands delivery with unsupported command surface
|
||||
- **WHEN** user runs `openspec update`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** a configured tool has no command surface capability
|
||||
- **THEN** the system SHALL fail with exit code 1 before applying partial updates
|
||||
- **AND** the output SHALL identify incompatible tools and recommended remediation
|
||||
|
||||
### Requirement: Configured-tool detection for skills-invocable command surfaces
|
||||
The update command SHALL treat tools with skills-invocable command surfaces as configured when managed skill artifacts are present, including under commands delivery.
|
||||
|
||||
#### Scenario: Skills-invocable tool under commands delivery
|
||||
- **WHEN** user runs `openspec update`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** a tool has no adapter-generated command files
|
||||
- **AND** that tool is marked `skills-invocable` and has managed skills installed
|
||||
- **THEN** the system SHALL include the tool in configured-tool detection
|
||||
- **AND** the system SHALL apply normal version/profile/delivery sync to that tool
|
||||
|
||||
### Requirement: Update summary reflects effective per-tool delivery
|
||||
The update command SHALL report effective artifact behavior when delivery intent and artifact type differ due to tool capability.
|
||||
|
||||
#### Scenario: Summary for skills-invocable tools in commands delivery
|
||||
- **WHEN** update completes successfully
|
||||
- **AND** delivery is `commands`
|
||||
- **AND** at least one updated tool is `skills-invocable`
|
||||
- **THEN** output SHALL include a clear note that those tools use skills as their command surface
|
||||
- **AND** output SHALL avoid implying that command generation was skipped due to an error
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
## 0. Stacking Coordination
|
||||
|
||||
- [ ] 0.1 Rebase this change on latest `main` before implementation
|
||||
- [ ] 0.2 If `simplify-skill-installation` is merged first, preserve its profile/delivery model and apply this change as a capability-aware refinement
|
||||
- [ ] 0.3 If this change merges first, ensure follow-up rebases do not reintroduce a blanket "commands = remove all skills" rule
|
||||
- [ ] 0.4 If `add-global-install-scope` is merged, verify combined scope × delivery × command-surface behavior remains deterministic
|
||||
|
||||
## 1. Tool Command-Surface Capability Model
|
||||
|
||||
- [ ] 1.1 Extend tool metadata in `src/core/config.ts` with an optional command-surface capability field
|
||||
- [ ] 1.2 Define supported capability values: `adapter`, `skills-invocable`, `none`
|
||||
- [ ] 1.3 Mark Trae as `skills-invocable`
|
||||
- [ ] 1.4 Add a shared capability resolver (explicit metadata override first, inferred fallback from adapter presence second)
|
||||
- [ ] 1.5 Add focused unit tests for capability resolution (explicit override, inferred adapter, inferred none)
|
||||
|
||||
## 2. Init: Capability-Aware Delivery Planning
|
||||
|
||||
- [ ] 2.1 Refactor init generation logic to compute per-tool effective actions (generate/remove skills and commands) instead of using only global booleans
|
||||
- [ ] 2.2 In `delivery=commands`, keep/generate skills for `skills-invocable` tools and do not remove those managed skill directories
|
||||
- [ ] 2.3 In `delivery=commands`, fail fast before writes when any selected tool resolves to `none`
|
||||
- [ ] 2.4 Update init output to clearly report effective behavior for `skills-invocable` tools (skills used as command surface)
|
||||
- [ ] 2.5 Ensure init no longer reports "no adapter" for tools intentionally using `skills-invocable`
|
||||
- [ ] 2.6 Add/adjust init tests for `delivery=commands` + `trae` (skills retained/generated, no adapter error), mixed tools (`claude,trae`) with per-tool expected outputs, and deterministic failure path for unsupported command surface (`none`)
|
||||
|
||||
## 3. Update: Capability-Aware Sync and Drift Detection
|
||||
|
||||
- [ ] 3.1 Refactor update sync logic to apply delivery behavior per tool capability (not globally per run)
|
||||
- [ ] 3.2 In `delivery=commands`, keep/generate managed skills for `skills-invocable` tools
|
||||
- [ ] 3.3 In `delivery=commands`, fail before partial updates when configured tools include a `none` command surface
|
||||
- [ ] 3.4 Update profile/delivery drift detection to avoid perpetual drift for `skills-invocable` tools under commands delivery
|
||||
- [ ] 3.5 Ensure configured-tool detection still includes `skills-invocable` tools under commands delivery when managed skills exist
|
||||
- [ ] 3.6 Update summary output so skills-invocable behavior is reported as expected behavior (not implicit skip/error)
|
||||
- [ ] 3.7 Add/adjust update tests for `delivery=commands` + configured Trae (skills retained/generated), idempotent second update (no false drift loop), mixed configured tools (`claude` + `trae`), and deterministic preflight failure for unsupported command surface (`none`)
|
||||
|
||||
## 4. UX and Error Messaging
|
||||
|
||||
- [ ] 4.1 Add interactive init compatibility note for `delivery=commands` when selected tools include `skills-invocable`
|
||||
- [ ] 4.2 Add deterministic non-interactive error text with incompatible tool IDs and suggested alternatives (`both` or `skills`)
|
||||
- [ ] 4.3 Align init and update wording so capability-related behavior/messages are consistent
|
||||
|
||||
## 5. Documentation Updates
|
||||
|
||||
- [ ] 5.1 Update `docs/supported-tools.md` to document command-surface semantics for Trae and clarify delivery interactions
|
||||
- [ ] 5.2 Update `docs/cli.md` delivery guidance to explain capability-aware behavior for `delivery=commands`
|
||||
- [ ] 5.3 Add a short troubleshooting note for "commands-only + unsupported tool" failures
|
||||
|
||||
## 6. Verification
|
||||
|
||||
- [ ] 6.1 Run targeted tests: `test/core/init.test.ts` and `test/core/update.test.ts`
|
||||
- [ ] 6.2 Run any new capability/unit test files added in this change
|
||||
- [ ] 6.3 Run full test suite (`pnpm test`) and resolve regressions
|
||||
- [ ] 6.4 Manual smoke check: `openspec init --tools trae` with `delivery=commands`
|
||||
- [ ] 6.5 Manual smoke check: mixed tools (`claude,trae`) with `delivery=commands`
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: List Command Behavior
|
||||
### Requirement: Command Execution
|
||||
|
||||
The current `list` command behavior SHALL be preserved but marked as deprecated.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
## MODIFIED Requirements
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Diff Command Enhancement
|
||||
|
||||
+2
@@ -24,6 +24,8 @@ Before moving the change to archive, the command SHALL apply delta changes to ma
|
||||
- **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.
|
||||
+2
@@ -31,6 +31,8 @@ The command SHALL show a requirement-level comparison displaying only changed re
|
||||
- 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.
|
||||
+2
-18
@@ -1,6 +1,6 @@
|
||||
# OpenSpec Conventions - Changes
|
||||
|
||||
## ADDED Requirements
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Header-Based Requirement Identification
|
||||
|
||||
@@ -31,8 +31,6 @@ Requirement headers SHALL serve as unique identifiers for programmatic matching
|
||||
- **THEN** ensure no duplicate headers exist within a spec
|
||||
- **AND** validation tools SHALL flag duplicate headers as errors
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Change Storage Convention
|
||||
|
||||
Change proposals SHALL store only the additions, modifications, and removals to specifications, not complete future states.
|
||||
@@ -100,18 +98,4 @@ The archive process SHALL programmatically apply delta changes to current specif
|
||||
- **AND** require manual resolution before proceeding
|
||||
- **AND** provide clear guidance on resolving conflicts
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Future State Storage
|
||||
|
||||
The system SHALL no longer store complete future-state specifications in change proposals.
|
||||
|
||||
**Reason for removal**: Replaced by delta-based change storage which provides better review experience and clearer change tracking.
|
||||
|
||||
**Migration path**: All new changes must use delta format.
|
||||
|
||||
#### Scenario: Deprecate future state storage
|
||||
|
||||
- **WHEN** creating a new change proposal
|
||||
- **THEN** do not include full future-state specs
|
||||
- **AND** include only ADDED/MODIFIED/REMOVED/RENAMED requirements under the change's `specs/` directory
|
||||
|
||||
@@ -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.)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user