mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-04 06:18:24 +08:00
Compare commits
180
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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,6 @@
|
||||
This directory is managed by Changesets.
|
||||
|
||||
- Add a changeset locally with `pnpm changeset`.
|
||||
- The CI "Release (prepare)" workflow opens/updates a Version Packages PR.
|
||||
- Publishing happens from a GitHub Release via the "Publish to npm" workflow.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config/schema.json",
|
||||
"changelog": "@changesets/cli/changelog",
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": []
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Default code ownership
|
||||
* @TabishB
|
||||
@@ -0,0 +1,222 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test_pr:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm test
|
||||
|
||||
- name: Upload test coverage
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report-pr
|
||||
path: coverage/
|
||||
retention-days: 7
|
||||
|
||||
test_matrix:
|
||||
name: Test (${{ matrix.label }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 15
|
||||
if: github.event_name != 'pull_request'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
shell: bash
|
||||
label: linux-bash
|
||||
- os: macos-latest
|
||||
shell: bash
|
||||
label: macos-bash
|
||||
- os: windows-latest
|
||||
shell: pwsh
|
||||
label: windows-pwsh
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Print environment diagnostics
|
||||
run: |
|
||||
node -p "JSON.stringify({ platform: process.platform, arch: process.arch, shell: process.env.SHELL || process.env.ComSpec || '' })"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm test
|
||||
|
||||
- name: Upload test coverage
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report-main
|
||||
path: coverage/
|
||||
retention-days: 7
|
||||
|
||||
lint:
|
||||
name: Lint & Type Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Type check
|
||||
run: pnpm exec tsc --noEmit
|
||||
|
||||
- name: 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
|
||||
|
||||
validate-changesets:
|
||||
name: Validate Changesets
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Validate changesets
|
||||
run: |
|
||||
if command -v changeset &> /dev/null; then
|
||||
pnpm exec changeset status --since=origin/main
|
||||
else
|
||||
echo "Changesets not configured, skipping validation"
|
||||
fi
|
||||
|
||||
required-checks-pr:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_pr, lint]
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
if [[ "${{ needs.test_pr.result }}" != "success" ]]; then
|
||||
echo "Test job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.lint.result }}" != "success" ]]; then
|
||||
echo "Lint job failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "All required checks passed!"
|
||||
|
||||
required-checks-main:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_matrix, lint]
|
||||
if: always() && github.event_name != 'pull_request'
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
if [[ "${{ needs.test_matrix.result }}" != "success" ]]; then
|
||||
echo "Matrix test job failed"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.lint.result }}" != "success" ]]; then
|
||||
echo "Lint job failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "All required checks passed!"
|
||||
@@ -0,0 +1,50 @@
|
||||
name: Release (prepare)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
if: github.repository == 'Fission-AI/OpenSpec'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
scope: '@fission-ai'
|
||||
always-auth: true
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
# Opens/updates the Version Packages PR; publishes when the Version PR merges
|
||||
- name: Create/Update Version PR
|
||||
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: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
+2
-1
@@ -145,4 +145,5 @@ docs/
|
||||
|
||||
# Claude
|
||||
.claude/
|
||||
CLAUDE.md
|
||||
CLAUDE.md
|
||||
.DS_Store
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Instructions
|
||||
|
||||
These instructions are for AI assistants working in this project.
|
||||
|
||||
Always open `@/openspec/AGENTS.md` when the request:
|
||||
- Mentions planning or proposals (words like proposal, spec, change, plan)
|
||||
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
|
||||
- Sounds ambiguous and you need the authoritative spec before coding
|
||||
|
||||
Use `@/openspec/AGENTS.md` to learn:
|
||||
- How to create and apply change proposals
|
||||
- Spec format and conventions
|
||||
- Project structure and guidelines
|
||||
|
||||
Keep this managed block so 'openspec update' can refresh the instructions.
|
||||
|
||||
<!-- OPENSPEC:END -->
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
# @fission-ai/openspec
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -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,349 @@
|
||||
<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>
|
||||
|
||||
# OpenSpec
|
||||
|
||||
A specification-driven development system for maintaining living documentation alongside your code.
|
||||
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.**
|
||||
|
||||
## Installation
|
||||
## Why OpenSpec?
|
||||
|
||||
```bash
|
||||
npm install -g 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.
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
## Getting Started
|
||||
|
||||
### Supported AI Tools
|
||||
|
||||
#### Native Slash Commands
|
||||
These tools have built-in OpenSpec commands. Select the OpenSpec integration when prompted.
|
||||
|
||||
| Tool | Commands |
|
||||
|------|----------|
|
||||
| **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` |
|
||||
| **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
|
||||
| **Factory Droid** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.factory/commands/`) |
|
||||
| **OpenCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
|
||||
| **Kilo Code** | `/openspec-proposal.md`, `/openspec-apply.md`, `/openspec-archive.md` (`.kilocode/workflows/`) |
|
||||
| **Windsurf** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.windsurf/workflows/`) |
|
||||
| **Codex** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (global: `~/.codex/prompts`, auto-installed) |
|
||||
| **GitHub Copilot** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.github/prompts/`) |
|
||||
| **Amazon Q Developer** | `@openspec-proposal`, `@openspec-apply`, `@openspec-archive` (`.amazonq/prompts/`) |
|
||||
|
||||
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`.
|
||||
|
||||
#### AGENTS.md Compatible
|
||||
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 • Gemini CLI • Others |
|
||||
|
||||
### Install & Initialize
|
||||
|
||||
#### Prerequisites
|
||||
- **Node.js >= 20.19.0** - Check your version with `node --version`
|
||||
|
||||
#### Step 1: Install the CLI globally
|
||||
|
||||
```bash
|
||||
# Initialize OpenSpec in your project
|
||||
npm install -g @fission-ai/openspec@latest
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
# 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]
|
||||
```
|
||||
|
||||
## Commands
|
||||
**What happens during initialization:**
|
||||
- You'll be prompted to pick any natively supported AI tools (Claude Code, Cursor, OpenCode, 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
|
||||
|
||||
### `openspec init`
|
||||
**After setup:**
|
||||
- Primary AI tools can trigger `/openspec` workflows without additional configuration
|
||||
- Run `openspec list` to verify the setup and view any active changes
|
||||
|
||||
Initializes OpenSpec in your project by creating:
|
||||
- `openspec/` directory structure
|
||||
- `openspec/README.md` with OpenSpec instructions
|
||||
- AI tool configuration files (based on your selection)
|
||||
### Create Your First Change
|
||||
|
||||
### `openspec update`
|
||||
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.
|
||||
|
||||
Updates OpenSpec instructions to the latest version. This command is **team-friendly** and only updates files that already exist:
|
||||
#### 1. Draft the Proposal
|
||||
Start by asking your AI to create a change proposal:
|
||||
|
||||
- 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
|
||||
```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)
|
||||
|
||||
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.
|
||||
AI: I'll create an OpenSpec change proposal for profile filters.
|
||||
*Scaffolds openspec/changes/add-profile-filters/ with proposal.md, tasks.md, spec deltas.*
|
||||
```
|
||||
|
||||
### `openspec spec`
|
||||
#### 2. Verify & Review
|
||||
Check that the change was created correctly and review the proposal:
|
||||
|
||||
Manage and view specifications.
|
||||
```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
|
||||
```
|
||||
|
||||
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
|
||||
#### 3. Refine the Specs
|
||||
Iterate on the specifications until they match your needs:
|
||||
|
||||
### `openspec change`
|
||||
```text
|
||||
You: Can you add acceptance criteria for the role and team filters?
|
||||
|
||||
Manage and view change proposals.
|
||||
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.*
|
||||
```
|
||||
|
||||
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
|
||||
#### 4. Implement the Change
|
||||
Once specs look good, start implementation:
|
||||
|
||||
### `openspec diff [change-name]`
|
||||
```text
|
||||
You: The specs look good. Let's implement this change.
|
||||
(Shortcut for tools with slash commands: /openspec:apply add-profile-filters)
|
||||
|
||||
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
|
||||
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 ✓...*
|
||||
```
|
||||
|
||||
### `openspec archive [change-name]`
|
||||
#### 5. Archive the Completed Change
|
||||
After implementation is complete, archive the change:
|
||||
|
||||
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)
|
||||
```text
|
||||
AI: All tasks are complete. The implementation is ready.
|
||||
|
||||
## Team Collaboration
|
||||
You: Please archive the change
|
||||
(Shortcut for tools with slash commands: /openspec:archive add-profile-filters)
|
||||
|
||||
OpenSpec is designed for team collaboration:
|
||||
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!
|
||||
```
|
||||
|
||||
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
|
||||
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, Cursor, Codex) 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, 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.
|
||||
|
||||
## Contributing
|
||||
|
||||
See `openspec/specs/` for the current system specifications and `openspec/changes/` for pending improvements.
|
||||
|
||||
## 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`.
|
||||
- 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`
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
MIT
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# 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. **Improve diff tooling.**
|
||||
- Extend `openspec diff` to compare change deltas against the live spec and highlight pending merges.
|
||||
4. **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.
|
||||
@@ -0,0 +1,456 @@
|
||||
# OpenSpec Instructions
|
||||
|
||||
Instructions for AI coding assistants using OpenSpec for spec-driven development.
|
||||
|
||||
## TL;DR Quick Checklist
|
||||
|
||||
- Search existing work: `openspec spec list --long`, `openspec list` (use `rg` only for full-text search)
|
||||
- Decide scope: new capability vs modify existing capability
|
||||
- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`)
|
||||
- Scaffold: `proposal.md`, `tasks.md`, `design.md` (only if needed), and delta specs per affected capability
|
||||
- Write deltas: use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`; include at least one `#### Scenario:` per requirement
|
||||
- Validate: `openspec validate [change-id] --strict` and fix issues
|
||||
- Request approval: Do not start implementation until proposal is approved
|
||||
|
||||
## Three-Stage Workflow
|
||||
|
||||
### Stage 1: Creating Changes
|
||||
Create proposal when you need to:
|
||||
- Add features or functionality
|
||||
- Make breaking changes (API, schema)
|
||||
- Change architecture or patterns
|
||||
- Optimize performance (changes behavior)
|
||||
- Update security patterns
|
||||
|
||||
Triggers (examples):
|
||||
- "Help me create a change proposal"
|
||||
- "Help me plan a change"
|
||||
- "Help me create a proposal"
|
||||
- "I want to create a spec proposal"
|
||||
- "I want to create a spec"
|
||||
|
||||
Loose matching guidance:
|
||||
- Contains one of: `proposal`, `change`, `spec`
|
||||
- With one of: `create`, `plan`, `make`, `start`, `help`
|
||||
|
||||
Skip proposal for:
|
||||
- Bug fixes (restore intended behavior)
|
||||
- Typos, formatting, comments
|
||||
- Dependency updates (non-breaking)
|
||||
- Configuration changes
|
||||
- Tests for existing behavior
|
||||
|
||||
**Workflow**
|
||||
1. Review `openspec/project.md`, `openspec list`, and `openspec list --specs` to understand current context.
|
||||
2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas under `openspec/changes/<id>/`.
|
||||
3. Draft spec deltas using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement.
|
||||
4. Run `openspec validate <id> --strict` and resolve any issues before sharing the proposal.
|
||||
|
||||
### Stage 2: Implementing Changes
|
||||
Track these steps as TODOs and complete them one by one.
|
||||
1. **Read proposal.md** - Understand what's being built
|
||||
2. **Read design.md** (if exists) - Review technical decisions
|
||||
3. **Read tasks.md** - Get implementation checklist
|
||||
4. **Implement tasks sequentially** - Complete in order
|
||||
5. **Confirm completion** - Ensure every item in `tasks.md` is finished before updating statuses
|
||||
6. **Update checklist** - After all work is done, set every task to `- [x]` so the list reflects reality
|
||||
7. **Approval gate** - Do not start implementation until the proposal is reviewed and approved
|
||||
|
||||
### Stage 3: Archiving Changes
|
||||
After deployment, create separate PR to:
|
||||
- Move `changes/[name]/` → `changes/archive/YYYY-MM-DD-[name]/`
|
||||
- Update `specs/` if capabilities changed
|
||||
- Use `openspec archive [change] --skip-specs --yes` for tooling-only changes
|
||||
- Run `openspec validate --strict` to confirm the archived change passes checks
|
||||
|
||||
## Before Any Task
|
||||
|
||||
**Context Checklist:**
|
||||
- [ ] Read relevant specs in `specs/[capability]/spec.md`
|
||||
- [ ] Check pending changes in `changes/` for conflicts
|
||||
- [ ] Read `openspec/project.md` for conventions
|
||||
- [ ] Run `openspec list` to see active changes
|
||||
- [ ] Run `openspec list --specs` to see existing capabilities
|
||||
|
||||
**Before Creating Specs:**
|
||||
- Always check if capability already exists
|
||||
- Prefer modifying existing specs over creating duplicates
|
||||
- Use `openspec show [spec]` to review current state
|
||||
- If request is ambiguous, ask 1–2 clarifying questions before scaffolding
|
||||
|
||||
### Search Guidance
|
||||
- Enumerate specs: `openspec spec list --long` (or `--json` for scripts)
|
||||
- Enumerate changes: `openspec list` (or `openspec change list --json` - deprecated but available)
|
||||
- Show details:
|
||||
- Spec: `openspec show <spec-id> --type spec` (use `--json` for filters)
|
||||
- Change: `openspec show <change-id> --json --deltas-only`
|
||||
- Full-text search (use ripgrep): `rg -n "Requirement:|Scenario:" openspec/specs`
|
||||
|
||||
## Quick Start
|
||||
|
||||
### CLI Commands
|
||||
|
||||
```bash
|
||||
# Essential commands
|
||||
openspec list # List active changes
|
||||
openspec list --specs # List specifications
|
||||
openspec show [item] # Display change or spec
|
||||
openspec diff [change] # Show spec differences
|
||||
openspec validate [item] # Validate changes or specs
|
||||
openspec archive [change] [--yes|-y] # Archive after deployment (add --yes for non-interactive runs)
|
||||
|
||||
# Project management
|
||||
openspec init [path] # Initialize OpenSpec
|
||||
openspec update [path] # Update instruction files
|
||||
|
||||
# Interactive mode
|
||||
openspec show # Prompts for selection
|
||||
openspec validate # Bulk validation mode
|
||||
|
||||
# Debugging
|
||||
openspec show [change] --json --deltas-only
|
||||
openspec validate [change] --strict
|
||||
```
|
||||
|
||||
### Command Flags
|
||||
|
||||
- `--json` - Machine-readable output
|
||||
- `--type change|spec` - Disambiguate items
|
||||
- `--strict` - Comprehensive validation
|
||||
- `--no-interactive` - Disable prompts
|
||||
- `--skip-specs` - Archive without spec updates
|
||||
- `--yes`/`-y` - Skip confirmation prompts (non-interactive archive)
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── project.md # Project conventions
|
||||
├── specs/ # Current truth - what IS built
|
||||
│ └── [capability]/ # Single focused capability
|
||||
│ ├── spec.md # Requirements and scenarios
|
||||
│ └── design.md # Technical patterns
|
||||
├── changes/ # Proposals - what SHOULD change
|
||||
│ ├── [change-name]/
|
||||
│ │ ├── proposal.md # Why, what, impact
|
||||
│ │ ├── tasks.md # Implementation checklist
|
||||
│ │ ├── design.md # Technical decisions (optional; see criteria)
|
||||
│ │ └── specs/ # Delta changes
|
||||
│ │ └── [capability]/
|
||||
│ │ └── spec.md # ADDED/MODIFIED/REMOVED
|
||||
│ └── archive/ # Completed changes
|
||||
```
|
||||
|
||||
## Creating Change Proposals
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
New request?
|
||||
├─ Bug fix restoring spec behavior? → Fix directly
|
||||
├─ Typo/format/comment? → Fix directly
|
||||
├─ New feature/capability? → Create proposal
|
||||
├─ Breaking change? → Create proposal
|
||||
├─ Architecture change? → Create proposal
|
||||
└─ Unclear? → Create proposal (safer)
|
||||
```
|
||||
|
||||
### Proposal Structure
|
||||
|
||||
1. **Create directory:** `changes/[change-id]/` (kebab-case, verb-led, unique)
|
||||
|
||||
2. **Write proposal.md:**
|
||||
```markdown
|
||||
## Why
|
||||
[1-2 sentences on problem/opportunity]
|
||||
|
||||
## What Changes
|
||||
- [Bullet list of changes]
|
||||
- [Mark breaking changes with **BREAKING**]
|
||||
|
||||
## Impact
|
||||
- Affected specs: [list capabilities]
|
||||
- Affected code: [key files/systems]
|
||||
```
|
||||
|
||||
3. **Create spec deltas:** `specs/[capability]/spec.md`
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: New Feature
|
||||
The system SHALL provide...
|
||||
|
||||
#### Scenario: Success case
|
||||
- **WHEN** user performs action
|
||||
- **THEN** expected result
|
||||
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Existing Feature
|
||||
[Complete modified requirement]
|
||||
|
||||
## REMOVED Requirements
|
||||
### Requirement: Old Feature
|
||||
**Reason**: [Why removing]
|
||||
**Migration**: [How to handle]
|
||||
```
|
||||
If multiple capabilities are affected, create multiple delta files under `changes/[change-id]/specs/<capability>/spec.md`—one per capability.
|
||||
|
||||
4. **Create tasks.md:**
|
||||
```markdown
|
||||
## 1. Implementation
|
||||
- [ ] 1.1 Create database schema
|
||||
- [ ] 1.2 Implement API endpoint
|
||||
- [ ] 1.3 Add frontend component
|
||||
- [ ] 1.4 Write tests
|
||||
```
|
||||
|
||||
5. **Create design.md when needed:**
|
||||
Create `design.md` if any of the following apply; otherwise omit it:
|
||||
- Cross-cutting change (multiple services/modules) or a new architectural pattern
|
||||
- New external dependency or significant data model changes
|
||||
- Security, performance, or migration complexity
|
||||
- Ambiguity that benefits from technical decisions before coding
|
||||
|
||||
Minimal `design.md` skeleton:
|
||||
```markdown
|
||||
## Context
|
||||
[Background, constraints, stakeholders]
|
||||
|
||||
## Goals / Non-Goals
|
||||
- Goals: [...]
|
||||
- Non-Goals: [...]
|
||||
|
||||
## Decisions
|
||||
- Decision: [What and why]
|
||||
- Alternatives considered: [Options + rationale]
|
||||
|
||||
## Risks / Trade-offs
|
||||
- [Risk] → Mitigation
|
||||
|
||||
## Migration Plan
|
||||
[Steps, rollback]
|
||||
|
||||
## Open Questions
|
||||
- [...]
|
||||
```
|
||||
|
||||
## Spec File Format
|
||||
|
||||
### Critical: Scenario Formatting
|
||||
|
||||
**CORRECT** (use #### headers):
|
||||
```markdown
|
||||
#### Scenario: User login success
|
||||
- **WHEN** valid credentials provided
|
||||
- **THEN** return JWT token
|
||||
```
|
||||
|
||||
**WRONG** (don't use bullets or bold):
|
||||
```markdown
|
||||
- **Scenario: User login** ❌
|
||||
**Scenario**: User login ❌
|
||||
### Scenario: User login ❌
|
||||
```
|
||||
|
||||
Every requirement MUST have at least one scenario.
|
||||
|
||||
### Requirement Wording
|
||||
- Use SHALL/MUST for normative requirements (avoid should/may unless intentionally non-normative)
|
||||
|
||||
### Delta Operations
|
||||
|
||||
- `## ADDED Requirements` - New capabilities
|
||||
- `## MODIFIED Requirements` - Changed behavior
|
||||
- `## REMOVED Requirements` - Deprecated features
|
||||
- `## RENAMED Requirements` - Name changes
|
||||
|
||||
Headers matched with `trim(header)` - whitespace ignored.
|
||||
|
||||
#### When to use ADDED vs MODIFIED
|
||||
- ADDED: Introduces a new capability or sub-capability that can stand alone as a requirement. Prefer ADDED when the change is orthogonal (e.g., adding "Slash Command Configuration") rather than altering the semantics of an existing requirement.
|
||||
- MODIFIED: Changes the behavior, scope, or acceptance criteria of an existing requirement. Always paste the full, updated requirement content (header + all scenarios). The archiver will replace the entire requirement with what you provide here; partial deltas will drop previous details.
|
||||
- RENAMED: Use when only the name changes. If you also change behavior, use RENAMED (name) plus MODIFIED (content) referencing the new name.
|
||||
|
||||
Common pitfall: Using MODIFIED to add a new concern without including the previous text. This causes loss of detail at archive time. If you aren’t explicitly changing the existing requirement, add a new requirement under ADDED instead.
|
||||
|
||||
Authoring a MODIFIED requirement correctly:
|
||||
1) Locate the existing requirement in `openspec/specs/<capability>/spec.md`.
|
||||
2) Copy the entire requirement block (from `### Requirement: ...` through its scenarios).
|
||||
3) Paste it under `## MODIFIED Requirements` and edit to reflect the new behavior.
|
||||
4) Ensure the header text matches exactly (whitespace-insensitive) and keep at least one `#### Scenario:`.
|
||||
|
||||
Example for RENAMED:
|
||||
```markdown
|
||||
## RENAMED Requirements
|
||||
- FROM: `### Requirement: Login`
|
||||
- TO: `### Requirement: User Authentication`
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Errors
|
||||
|
||||
**"Change must have at least one delta"**
|
||||
- Check `changes/[name]/specs/` exists with .md files
|
||||
- Verify files have operation prefixes (## ADDED Requirements)
|
||||
|
||||
**"Requirement must have at least one scenario"**
|
||||
- Check scenarios use `#### Scenario:` format (4 hashtags)
|
||||
- Don't use bullet points or bold for scenario headers
|
||||
|
||||
**Silent scenario parsing failures**
|
||||
- Exact format required: `#### Scenario: Name`
|
||||
- Debug with: `openspec show [change] --json --deltas-only`
|
||||
|
||||
### Validation Tips
|
||||
|
||||
```bash
|
||||
# Always use strict mode for comprehensive checks
|
||||
openspec validate [change] --strict
|
||||
|
||||
# Debug delta parsing
|
||||
openspec show [change] --json | jq '.deltas'
|
||||
|
||||
# Check specific requirement
|
||||
openspec show [spec] --json -r 1
|
||||
```
|
||||
|
||||
## Happy Path Script
|
||||
|
||||
```bash
|
||||
# 1) Explore current state
|
||||
openspec spec list --long
|
||||
openspec list
|
||||
# Optional full-text search:
|
||||
# rg -n "Requirement:|Scenario:" openspec/specs
|
||||
# rg -n "^#|Requirement:" openspec/changes
|
||||
|
||||
# 2) Choose change id and scaffold
|
||||
CHANGE=add-two-factor-auth
|
||||
mkdir -p openspec/changes/$CHANGE/{specs/auth}
|
||||
printf "## Why\n...\n\n## What Changes\n- ...\n\n## Impact\n- ...\n" > openspec/changes/$CHANGE/proposal.md
|
||||
printf "## 1. Implementation\n- [ ] 1.1 ...\n" > openspec/changes/$CHANGE/tasks.md
|
||||
|
||||
# 3) Add deltas (example)
|
||||
cat > openspec/changes/$CHANGE/specs/auth/spec.md << 'EOF'
|
||||
## ADDED Requirements
|
||||
### Requirement: Two-Factor Authentication
|
||||
Users MUST provide a second factor during login.
|
||||
|
||||
#### Scenario: OTP required
|
||||
- **WHEN** valid credentials are provided
|
||||
- **THEN** an OTP challenge is required
|
||||
EOF
|
||||
|
||||
# 4) Validate
|
||||
openspec validate $CHANGE --strict
|
||||
```
|
||||
|
||||
## Multi-Capability Example
|
||||
|
||||
```
|
||||
openspec/changes/add-2fa-notify/
|
||||
├── proposal.md
|
||||
├── tasks.md
|
||||
└── specs/
|
||||
├── auth/
|
||||
│ └── spec.md # ADDED: Two-Factor Authentication
|
||||
└── notifications/
|
||||
└── spec.md # ADDED: OTP email notification
|
||||
```
|
||||
|
||||
auth/spec.md
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: Two-Factor Authentication
|
||||
...
|
||||
```
|
||||
|
||||
notifications/spec.md
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: OTP Email Notification
|
||||
...
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Simplicity First
|
||||
- Default to <100 lines of new code
|
||||
- Single-file implementations until proven insufficient
|
||||
- Avoid frameworks without clear justification
|
||||
- Choose boring, proven patterns
|
||||
|
||||
### Complexity Triggers
|
||||
Only add complexity with:
|
||||
- Performance data showing current solution too slow
|
||||
- Concrete scale requirements (>1000 users, >100MB data)
|
||||
- Multiple proven use cases requiring abstraction
|
||||
|
||||
### Clear References
|
||||
- Use `file.ts:42` format for code locations
|
||||
- Reference specs as `specs/auth/spec.md`
|
||||
- Link related changes and PRs
|
||||
|
||||
### Capability Naming
|
||||
- Use verb-noun: `user-auth`, `payment-capture`
|
||||
- Single purpose per capability
|
||||
- 10-minute understandability rule
|
||||
- Split if description needs "AND"
|
||||
|
||||
### Change ID Naming
|
||||
- Use kebab-case, short and descriptive: `add-two-factor-auth`
|
||||
- Prefer verb-led prefixes: `add-`, `update-`, `remove-`, `refactor-`
|
||||
- Ensure uniqueness; if taken, append `-2`, `-3`, etc.
|
||||
|
||||
## Tool Selection Guide
|
||||
|
||||
| Task | Tool | Why |
|
||||
|------|------|-----|
|
||||
| Find files by pattern | Glob | Fast pattern matching |
|
||||
| Search code content | Grep | Optimized regex search |
|
||||
| Read specific files | Read | Direct file access |
|
||||
| Explore unknown scope | Task | Multi-step investigation |
|
||||
|
||||
## Error Recovery
|
||||
|
||||
### Change Conflicts
|
||||
1. Run `openspec list` to see active changes
|
||||
2. Check for overlapping specs
|
||||
3. Coordinate with change owners
|
||||
4. Consider combining proposals
|
||||
|
||||
### Validation Failures
|
||||
1. Run with `--strict` flag
|
||||
2. Check JSON output for details
|
||||
3. Verify spec file format
|
||||
4. Ensure scenarios properly formatted
|
||||
|
||||
### Missing Context
|
||||
1. Read project.md first
|
||||
2. Check related specs
|
||||
3. Review recent archives
|
||||
4. Ask for clarification
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Stage Indicators
|
||||
- `changes/` - Proposed, not yet built
|
||||
- `specs/` - Built and deployed
|
||||
- `archive/` - Completed changes
|
||||
|
||||
### File Purposes
|
||||
- `proposal.md` - Why and what
|
||||
- `tasks.md` - Implementation steps
|
||||
- `design.md` - Technical decisions
|
||||
- `spec.md` - Requirements and behavior
|
||||
|
||||
### CLI Essentials
|
||||
```bash
|
||||
openspec list # What's in progress?
|
||||
openspec show [item] # View details
|
||||
openspec diff [change] # What's changing?
|
||||
openspec validate --strict # Is it correct?
|
||||
openspec archive [change] [--yes|-y] # Mark complete (add --yes for automation)
|
||||
```
|
||||
|
||||
Remember: Specs are truth. Changes are proposals. Keep them in sync.
|
||||
@@ -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,12 @@
|
||||
## Why
|
||||
Factory's Droid CLI recently shipped custom slash commands that mirror other native assistant integrations. Teams using OpenSpec want the same managed workflows they already get for Cursor, Windsurf, and others so init/update can provision and refresh Factory commands without manual setup.
|
||||
|
||||
## What Changes
|
||||
- Extend the native tool registry so Factory/Droid appears alongside other slash-command integrations during `openspec init`.
|
||||
- Add shared templates that generate the three Factory custom commands (proposal, apply, archive) and wrap them in OpenSpec markers for safe refreshes.
|
||||
- Update the init and update command flows so they create or refresh Factory command files when the tool is selected or already present.
|
||||
- Refresh CLI specs to document the Factory support and align validation expectations.
|
||||
|
||||
## Impact
|
||||
- Affected specs: `specs/cli-init`, `specs/cli-update`
|
||||
- Affected code (expected): tool registry, slash-command template manager, init/update command helpers, documentation snippets
|
||||
@@ -0,0 +1,54 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Slash Command Configuration
|
||||
The init command SHALL generate slash command files for supported editors using shared templates.
|
||||
|
||||
#### Scenario: Generating slash commands for Claude Code
|
||||
- **WHEN** the user selects Claude Code during initialization
|
||||
- **THEN** create `.claude/commands/openspec/proposal.md`, `.claude/commands/openspec/apply.md`, and `.claude/commands/openspec/archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
|
||||
#### Scenario: Generating slash commands for Cursor
|
||||
- **WHEN** the user selects Cursor during initialization
|
||||
- **THEN** create `.cursor/commands/openspec-proposal.md`, `.cursor/commands/openspec-apply.md`, and `.cursor/commands/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
|
||||
#### Scenario: Generating slash commands for Factory Droid
|
||||
- **WHEN** the user selects Factory Droid during initialization
|
||||
- **THEN** create `.factory/commands/openspec-proposal.md`, `.factory/commands/openspec-apply.md`, and `.factory/commands/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates that include Factory-compatible YAML frontmatter for the `description` and `argument-hint` fields
|
||||
- **AND** include the `$ARGUMENTS` placeholder in the template body so droid receives any user-supplied input
|
||||
- **AND** wrap the generated content in OpenSpec managed markers so `openspec update` can safely refresh the commands
|
||||
|
||||
#### Scenario: Generating slash commands for OpenCode
|
||||
- **WHEN** the user selects OpenCode during initialization
|
||||
- **THEN** create `.opencode/commands/openspec-proposal.md`, `.opencode/commands/openspec-apply.md`, and `.opencode/commands/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
|
||||
#### Scenario: Generating slash commands for Windsurf
|
||||
- **WHEN** the user selects Windsurf during initialization
|
||||
- **THEN** create `.windsurf/workflows/openspec-proposal.md`, `.windsurf/workflows/openspec-apply.md`, and `.windsurf/workflows/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates (wrapped in OpenSpec markers) so workflow text matches other tools
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
|
||||
#### Scenario: Generating slash commands for Kilo Code
|
||||
- **WHEN** the user selects Kilo Code during initialization
|
||||
- **THEN** create `.kilocode/workflows/openspec-proposal.md`, `.kilocode/workflows/openspec-apply.md`, and `.kilocode/workflows/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates (wrapped in OpenSpec markers) so workflow text matches other tools
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
|
||||
#### Scenario: Generating slash commands for Codex
|
||||
- **WHEN** the user selects Codex during initialization
|
||||
- **THEN** create global prompt files at `~/.codex/prompts/openspec-proposal.md`, `~/.codex/prompts/openspec-apply.md`, and `~/.codex/prompts/openspec-archive.md` (or under `$CODEX_HOME/prompts` if set)
|
||||
- **AND** populate each file from shared templates that map the first numbered placeholder (`$1`) to the primary user input (e.g., change identifier or question text)
|
||||
- **AND** wrap the generated content in OpenSpec markers so `openspec update` can refresh the prompts without touching surrounding custom notes
|
||||
|
||||
#### Scenario: Generating slash commands for GitHub Copilot
|
||||
- **WHEN** the user selects GitHub Copilot during initialization
|
||||
- **THEN** create `.github/prompts/openspec-proposal.prompt.md`, `.github/prompts/openspec-apply.prompt.md`, and `.github/prompts/openspec-archive.prompt.md`
|
||||
- **AND** populate each file with YAML frontmatter containing a `description` field that summarizes the workflow stage
|
||||
- **AND** include `$ARGUMENTS` placeholder to capture user input
|
||||
- **AND** wrap the shared template body with OpenSpec markers so `openspec update` can refresh the content
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
@@ -0,0 +1,54 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Slash Command Updates
|
||||
The update command SHALL refresh existing slash command files for configured tools without creating new ones.
|
||||
|
||||
#### Scenario: Updating slash commands for Claude Code
|
||||
- **WHEN** `.claude/commands/openspec/` contains `proposal.md`, `apply.md`, and `archive.md`
|
||||
- **THEN** refresh each file using shared templates
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
|
||||
#### Scenario: Updating slash commands for Cursor
|
||||
- **WHEN** `.cursor/commands/` contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **THEN** refresh each file using shared templates
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
|
||||
#### Scenario: Updating slash commands for Factory Droid
|
||||
- **WHEN** `.factory/commands/` contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **THEN** refresh each file using the shared Factory templates that include YAML frontmatter for the `description` and `argument-hint` fields
|
||||
- **AND** ensure the template body retains the `$ARGUMENTS` placeholder so user input keeps flowing into droid
|
||||
- **AND** update only the content inside the OpenSpec managed markers, leaving any unmanaged notes untouched
|
||||
- **AND** skip creating missing files during update
|
||||
|
||||
#### Scenario: Updating slash commands for OpenCode
|
||||
- **WHEN** `.opencode/command/` contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **THEN** refresh each file using shared templates
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
|
||||
#### Scenario: Updating slash commands for Windsurf
|
||||
- **WHEN** `.windsurf/workflows/` contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **THEN** refresh each file using shared templates wrapped in OpenSpec markers
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
- **AND** skip creating missing files (the update command only refreshes what already exists)
|
||||
|
||||
#### Scenario: Updating slash commands for Kilo Code
|
||||
- **WHEN** `.kilocode/workflows/` contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **THEN** refresh each file using shared templates wrapped in OpenSpec markers
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
- **AND** skip creating missing files (the update command only refreshes what already exists)
|
||||
|
||||
#### Scenario: Updating slash commands for Codex
|
||||
- **GIVEN** the global Codex prompt directory contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **WHEN** a user runs `openspec update`
|
||||
- **THEN** refresh each file using the shared slash-command templates (including placeholder guidance)
|
||||
- **AND** preserve any unmanaged content outside the OpenSpec marker block
|
||||
- **AND** skip creation when a Codex prompt file is missing
|
||||
|
||||
#### Scenario: Updating slash commands for GitHub Copilot
|
||||
- **WHEN** `.github/prompts/` contains `openspec-proposal.prompt.md`, `openspec-apply.prompt.md`, and `openspec-archive.prompt.md`
|
||||
- **THEN** refresh each file using shared templates while preserving the YAML frontmatter
|
||||
- **AND** update only the OpenSpec-managed block between markers
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
|
||||
#### Scenario: Missing slash command file
|
||||
- **WHEN** a tool lacks a slash command file
|
||||
- **THEN** do not create a new file during update
|
||||
@@ -0,0 +1,11 @@
|
||||
## 1. Factory tool registration
|
||||
- [x] 1.1 Add Factory/Droid metadata to the native tool registry used by init/update (ID, display name, command paths, availability flags).
|
||||
- [x] 1.2 Surface Factory in interactive prompts and non-interactive `--tools` parsing alongside existing slash-command integrations.
|
||||
|
||||
## 2. Slash command templates
|
||||
- [x] 2.1 Create shared templates for Factory's `openspec-proposal`, `openspec-apply`, and `openspec-archive` custom commands following Factory's CLI format.
|
||||
- [x] 2.2 Wire the templates into init/update so generation happens on create and refresh respects OpenSpec markers.
|
||||
|
||||
## 3. Verification
|
||||
- [x] 3.1 Update or add automated coverage that ensures Factory command files are scaffolded and refreshed correctly.
|
||||
- [x] 3.2 Document the new option in any user-facing copy (help text, README snippets) if required by spec.
|
||||
@@ -0,0 +1,11 @@
|
||||
## Why
|
||||
Manual setup for new changes leads to formatting mistakes in spec deltas and slows agents who must recreate the same file skeletons for every proposal. A built-in scaffold command will generate compliant templates so assistants can focus on the change content instead of structure.
|
||||
|
||||
## What Changes
|
||||
- Add an `openspec scaffold <change-id>` CLI command that creates a change directory with validated `proposal.md`, `tasks.md`, and spec delta templates.
|
||||
- Update CLI documentation and quick-reference guidance so agents discover the scaffold workflow before drafting files manually.
|
||||
- Add automated coverage (unit/integ tests) to ensure the command respects existing naming rules and generated Markdown passes validation.
|
||||
|
||||
## Impact
|
||||
- Affected specs: `specs/cli-scaffold`
|
||||
- Affected code: `src/cli/index.ts`, `src/commands`, `docs/`
|
||||
@@ -0,0 +1,44 @@
|
||||
## ADDED Requirements
|
||||
### Requirement: Scaffolding Command Registration
|
||||
The CLI SHALL expose an `openspec scaffold <change-id>` command that validates the change identifier before generating files.
|
||||
|
||||
#### Scenario: Registering scaffold command
|
||||
- **WHEN** a user runs `openspec scaffold add-user-notifications`
|
||||
- **THEN** the CLI SHALL reject invalid identifiers (non kebab-case) before proceeding
|
||||
- **AND** display usage documentation via `openspec scaffold --help`
|
||||
- **AND** exit with code 0 after successful scaffolding
|
||||
|
||||
### Requirement: Change Directory Structure
|
||||
The scaffold command SHALL create the standard change workspace with proposal, tasks, optional design, and delta directories laid out according to OpenSpec conventions.
|
||||
|
||||
#### Scenario: Generating change workspace
|
||||
- **WHEN** scaffolding a new change with id `add-user-notifications`
|
||||
- **THEN** create `openspec/changes/add-user-notifications/`
|
||||
- **AND** generate `proposal.md`, `tasks.md`, and `design.md` (commented placeholder content) in that directory when missing
|
||||
- **AND** create `openspec/changes/add-user-notifications/specs/` ready for capability-specific deltas
|
||||
|
||||
### Requirement: Template Content Guidance
|
||||
The scaffold command SHALL populate generated Markdown files with OpenSpec-compliant templates so authors can copy, edit, and pass validation without reformatting.
|
||||
|
||||
#### Scenario: Populating proposal and tasks templates
|
||||
- **WHEN** the scaffold command writes `proposal.md`
|
||||
- **THEN** include the `## Why`, `## What Changes`, and `## Impact` headings with placeholder guidance text
|
||||
- **AND** ensure `tasks.md` starts with `## 1. Implementation` and numbered checklist items using `- [ ]` syntax
|
||||
- **AND** annotate optional sections (like `design.md`) with inline TODO comments so users understand when to keep or delete them
|
||||
|
||||
### Requirement: Delta Spec Creation
|
||||
The scaffold command SHALL create at least one capability delta file with correctly formatted requirement and scenario placeholders that guide authors to enter the actual behavior.
|
||||
|
||||
#### Scenario: Creating spec delta skeleton
|
||||
- **WHEN** scaffolding a change and the capability `cli-scaffold` is provided interactively or via flags
|
||||
- **THEN** generate `openspec/changes/add-user-notifications/specs/cli-scaffold/spec.md`
|
||||
- **AND** include `## ADDED Requirements` with at least one `### Requirement:` block and matching `#### Scenario:` entries that remind the author to replace placeholder text
|
||||
- **AND** ensure the generated delta passes `openspec validate add-user-notifications --strict` until the author edits it
|
||||
|
||||
### Requirement: Idempotent Execution
|
||||
The scaffold command SHALL be safe to rerun, preserving user edits while filling in any missing managed sections.
|
||||
|
||||
#### Scenario: Rerunning scaffold on existing change
|
||||
- **WHEN** the command is executed again for an existing change directory containing user-edited files
|
||||
- **THEN** leave existing content untouched except for managed placeholder regions or missing files that need creation
|
||||
- **AND** update the filesystem summary to highlight which files were skipped, created, or refreshed
|
||||
@@ -0,0 +1,11 @@
|
||||
## 1. CLI scaffolding command
|
||||
- [ ] 1.1 Register an `openspec scaffold` command in the CLI entrypoint with `change-id` argument validation.
|
||||
- [ ] 1.2 Implement generator logic that creates the change directory structure plus default `proposal.md`, `tasks.md`, and delta spec skeletons without overwriting existing populated files.
|
||||
|
||||
## 2. Templates and documentation
|
||||
- [ ] 2.1 Surface copy/paste templates and scaffold usage in the top-level quick reference for `openspec/AGENTS.md`.
|
||||
- [ ] 2.2 Refresh other CLI docs (`docs/`, README) to mention the scaffold workflow and link to instructions.
|
||||
|
||||
## 3. Test coverage
|
||||
- [ ] 3.1 Add unit tests covering name validation, file generation, and idempotent reruns.
|
||||
- [ ] 3.2 Add integration coverage ensuring generated files pass `openspec validate --strict` without manual edits.
|
||||
+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.)
|
||||
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
# Delta: CLI List Command
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Command Execution
|
||||
The command SHALL scan and analyze either active changes or specs based on the selected mode.
|
||||
|
||||
#### Scenario: Scanning for changes (default)
|
||||
- **WHEN** `openspec list` is executed without flags
|
||||
- **THEN** scan the `openspec/changes/` directory for change directories
|
||||
- **AND** exclude the `archive/` subdirectory from results
|
||||
- **AND** parse each change's `tasks.md` file to count task completion
|
||||
|
||||
#### Scenario: Scanning for specs
|
||||
- **WHEN** `openspec list --specs` is executed
|
||||
- **THEN** scan the `openspec/specs/` directory for capabilities
|
||||
- **AND** read each capability's `spec.md`
|
||||
- **AND** parse requirements to compute requirement counts
|
||||
|
||||
### Requirement: Output Format
|
||||
The command SHALL display items in a clear, readable table format with mode-appropriate progress or counts.
|
||||
|
||||
#### Scenario: Displaying change list (default)
|
||||
- **WHEN** displaying the list of changes
|
||||
- **THEN** show a table with columns:
|
||||
- Change name (directory name)
|
||||
- Task progress (e.g., "3/5 tasks" or "✓ Complete")
|
||||
|
||||
#### Scenario: Displaying spec list
|
||||
- **WHEN** displaying the list of specs
|
||||
- **THEN** show a table with columns:
|
||||
- Spec id (directory name)
|
||||
- Requirement count (e.g., "requirements 12")
|
||||
|
||||
### Requirement: Empty State
|
||||
The command SHALL provide clear feedback when no items are present for the selected mode.
|
||||
|
||||
#### Scenario: Handling empty state (changes)
|
||||
- **WHEN** no active changes exist (only archive/ or empty changes/)
|
||||
- **THEN** display: "No active changes found."
|
||||
|
||||
#### Scenario: Handling empty state (specs)
|
||||
- **WHEN** no specs directory exists or contains no capabilities
|
||||
- **THEN** display: "No specs found."
|
||||
|
||||
### Requirement: Flags
|
||||
The command SHALL accept flags to select the noun being listed.
|
||||
|
||||
#### Scenario: Selecting specs
|
||||
- **WHEN** `--specs` is provided
|
||||
- **THEN** list specs instead of changes
|
||||
|
||||
#### Scenario: Selecting changes
|
||||
- **WHEN** `--changes` is provided
|
||||
- **THEN** list changes explicitly (same as default behavior)
|
||||
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# Delta: OpenSpec Conventions — Verb–Noun CLI Design
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Verb–Noun CLI Command Structure
|
||||
OpenSpec CLI design SHALL use verbs as top-level commands with nouns provided as arguments or flags for scoping.
|
||||
|
||||
#### Scenario: Verb-first command discovery
|
||||
- **WHEN** a user runs a command like `openspec list`
|
||||
- **THEN** the verb communicates the action clearly
|
||||
- **AND** nouns refine scope via flags or arguments (e.g., `--changes`, `--specs`)
|
||||
|
||||
#### Scenario: Backward compatibility for noun commands
|
||||
- **WHEN** users run noun-prefixed commands such as `openspec spec ...` or `openspec change ...`
|
||||
- **THEN** the CLI SHALL continue to support them for at least one release
|
||||
- **AND** display a deprecation warning that points to verb-first alternatives
|
||||
|
||||
#### Scenario: Disambiguation guidance
|
||||
- **WHEN** item names are ambiguous between changes and specs
|
||||
- **THEN** `openspec show` and `openspec validate` SHALL accept `--type spec|change`
|
||||
- **AND** the help text SHALL document this clearly
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. CLI Behavior and Help
|
||||
- [x] 1.1 Un-deprecate top-level `openspec list`; mark `change list` as deprecated with warning that points to `openspec list`
|
||||
- [x] 1.2 Add support to list specs via `openspec list --specs` and keep `--changes` as default
|
||||
- [x] 1.3 Update command descriptions and `--help` output to emphasize verb–noun pattern
|
||||
- [x] 1.4 Keep `openspec spec ...` and `openspec change ...` commands working but print deprecation notices
|
||||
|
||||
## 2. Core List Logic
|
||||
- [x] 2.1 Extend `src/core/list.ts` to accept a mode: `changes` (default) or `specs`
|
||||
- [x] 2.2 Implement `specs` listing: scan `openspec/specs/*/spec.md`, compute requirement count via parser, format output consistently
|
||||
- [x] 2.3 Share output structure for both modes; preserve current text table; ensure JSON parity in future change
|
||||
|
||||
## 3. Specs and Conventions
|
||||
- [x] 3.1 Update `openspec/specs/cli-list/spec.md` to document `--specs` (and default to changes)
|
||||
- [x] 3.2 Update `openspec/specs/openspec-conventions/spec.md` with a requirement for verb–noun CLI design and deprecation guidance
|
||||
|
||||
## 4. Tests and Docs
|
||||
- [x] 4.1 Update tests: ensure `openspec list` works for changes and specs; keep `change list` tests but assert warning
|
||||
- [ ] 4.2 Update README and any usage docs to show new primary commands
|
||||
- [ ] 4.3 Add migration notes in repo CHANGELOG or README
|
||||
|
||||
## 5. Follow-ups (Optional, not in this change)
|
||||
- [ ] 5.1 Consider `openspec show --specs/--changes` for discovery without ids
|
||||
- [ ] 5.2 Consider JSON output for `openspec list` with `--json` for both modes
|
||||
|
||||
|
||||
+9
-1
@@ -106,6 +106,8 @@ Where `Issue` follows the existing per-item validation report shape `{ level: "E
|
||||
|
||||
### Requirement: Item type detection and ambiguity handling
|
||||
|
||||
The validate command SHALL handle ambiguous names and explicit type overrides to ensure clear, deterministic behavior.
|
||||
|
||||
#### Scenario: Direct item validation with automatic type detection
|
||||
|
||||
- **WHEN** executing `openspec validate <item-name>`
|
||||
@@ -138,4 +140,10 @@ Where `Issue` follows the existing per-item validation report shape `{ level: "E
|
||||
|
||||
- The CLI SHALL respect `--no-interactive` to disable prompts.
|
||||
- The CLI SHALL respect `OPEN_SPEC_INTERACTIVE=0` to disable prompts globally.
|
||||
- Interactive prompts SHALL only be shown when stdin is a TTY and interactivity is not disabled.
|
||||
- Interactive prompts SHALL only be shown when stdin is a TTY and interactivity is not disabled.
|
||||
|
||||
#### Scenario: Disabling prompts via flags or environment
|
||||
|
||||
- **WHEN** `openspec validate` is executed with `--no-interactive` or with environment `OPEN_SPEC_INTERACTIVE=0`
|
||||
- **THEN** the CLI SHALL not display interactive prompts
|
||||
- **AND** SHALL print non-interactive hints or chosen outputs as appropriate
|
||||
@@ -0,0 +1,25 @@
|
||||
# improve-validate-error-messages
|
||||
|
||||
## Why
|
||||
|
||||
Developers struggle to resolve validation failures because current errors lack actionable guidance. Common issues include: missing deltas, missing required sections, and misformatted scenarios that are silently ignored. Without clear remediation steps, users cannot quickly correct structure or formatting, leading to frustration and rework. Improving error messages with concrete fixes, file/section hints, and suggested commands will significantly reduce time-to-green and make OpenSpec more approachable.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Validation errors SHALL include specific remediation steps (what to change and where).
|
||||
- "No deltas found" error SHALL guide users to create `specs/` with proper delta headers and suggest debug commands.
|
||||
- Missing required sections (Spec: Purpose/Requirements; Change: Why/What Changes) SHALL include expected header names and a minimal skeleton example.
|
||||
- Likely misformatted scenarios (bulleted WHEN/THEN/AND) SHALL emit a targeted warning explaining the `#### Scenario:` format and show a conversion template.
|
||||
- All reported issues SHALL include the source file path and structured location (e.g., `deltas[0].requirements[0]`).
|
||||
- Non-JSON output SHOULD end with a short "Next steps" footer when invalid.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected CLI: validate
|
||||
- Affected code:
|
||||
- `src/commands/validate.ts`
|
||||
- `src/core/validation/validator.ts`
|
||||
- `src/core/validation/constants.ts`
|
||||
- `src/core/parsers/*` (wrapping thrown errors with richer context)
|
||||
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
# Validate Command
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Validation SHALL provide actionable remediation steps
|
||||
Validation output SHALL include specific guidance to fix each error, including expected structure, example headers, and suggested commands to verify fixes.
|
||||
|
||||
#### Scenario: No deltas found in change
|
||||
- **WHEN** validating a change with zero parsed deltas
|
||||
- **THEN** show error "No deltas found" with guidance:
|
||||
- Ensure `openspec/changes/{id}/specs/` exists with `.md` files
|
||||
- Use delta headers: `## ADDED Requirements`, `## MODIFIED Requirements`, `## REMOVED Requirements`, `## RENAMED Requirements`
|
||||
- Each requirement must include at least one `#### Scenario:` block
|
||||
- Try: `openspec change show {id} --json --deltas-only` to inspect what was parsed
|
||||
|
||||
#### Scenario: Missing required sections
|
||||
- **WHEN** a required section is missing
|
||||
- **THEN** the validator SHALL include expected header names and a minimal skeleton:
|
||||
- For Spec: `## Purpose`, `## Requirements`
|
||||
- For Change: `## Why`, `## What Changes`
|
||||
- Show an example snippet of the missing section
|
||||
|
||||
### Requirement: Validator SHALL detect likely misformatted scenarios and warn with a fix
|
||||
The validator SHALL recognize bulleted lines that look like scenarios (e.g., lines beginning with WHEN/THEN/AND) and emit a targeted warning with a conversion example to `#### Scenario:`.
|
||||
|
||||
#### Scenario: Bulleted WHEN/THEN under a Requirement
|
||||
- **WHEN** bullets that start with WHEN/THEN/AND are found under a requirement without any `#### Scenario:` headers
|
||||
- **THEN** emit warning: "Scenarios must use '#### Scenario:' headers", and show a conversion template:
|
||||
```
|
||||
#### Scenario: Short name
|
||||
- **WHEN** ...
|
||||
- **THEN** ...
|
||||
- **AND** ...
|
||||
```
|
||||
|
||||
### Requirement: All issues SHALL include file paths and structured locations
|
||||
Error, warning, and info messages SHALL include:
|
||||
- Source file path (`openspec/changes/{id}/proposal.md`, `.../specs/{cap}/spec.md`)
|
||||
- Structured path (e.g., `deltas[0].requirements[0].scenarios`)
|
||||
|
||||
#### Scenario: Zod validation error
|
||||
- **WHEN** a schema validation fails
|
||||
- **THEN** the message SHALL include `file`, `path`, and a remediation hint if applicable
|
||||
|
||||
### Requirement: Invalid results SHALL include a Next steps footer in human-readable output
|
||||
The CLI SHALL append a Next steps footer when the item is invalid and not using `--json`, including:
|
||||
- Summary line with counts
|
||||
- Top-3 guidance bullets (contextual to the most frequent or blocking errors)
|
||||
- A suggestion to re-run with `--json` and/or the debug command
|
||||
|
||||
#### Scenario: Change invalid summary
|
||||
- **WHEN** a change validation fails
|
||||
- **THEN** print "Next steps" with 2-3 targeted bullets and suggest `openspec change show <id> --json --deltas-only`
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
## 1. Enhance validation messages
|
||||
- [x] 1.1 Add remediation guidance for "No deltas found"
|
||||
- [x] 1.2 Include file path and structured path in all issues
|
||||
- [x] 1.3 Improve messages for missing required sections (Spec, Change)
|
||||
- [x] 1.4 Detect likely misformatted scenarios and warn with conversion example
|
||||
- [x] 1.5 Add "Next steps" footer for non-JSON invalid output
|
||||
|
||||
## 2. Update constants and helpers
|
||||
- [x] 2.1 Centralize guidance snippets in `VALIDATION_MESSAGES`
|
||||
- [x] 2.2 Provide minimal skeleton examples for missing sections
|
||||
|
||||
## 3. Parser integration
|
||||
- [x] 3.1 Capture parser-thrown errors and wrap with richer context
|
||||
- [x] 3.2 Add file/section references to surfaced parser errors
|
||||
|
||||
## 4. Tests
|
||||
- [x] 4.1 Unit tests for validator message composition
|
||||
- [x] 4.2 CLI integration tests for human-readable output (with footer)
|
||||
- [x] 4.3 JSON mode tests (structure unchanged, content enriched)
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Change: Add View Dashboard Command
|
||||
|
||||
## Why
|
||||
|
||||
Users need a quick, at-a-glance overview of their OpenSpec project status without running multiple commands. Currently, users must run `openspec list --changes` and `openspec list --specs` separately to understand the project state. A unified dashboard view would improve developer experience and provide immediate insight into project progress.
|
||||
|
||||
## What Changes
|
||||
|
||||
### Added `openspec view` Command
|
||||
|
||||
The new command provides an interactive dashboard displaying:
|
||||
- Summary metrics (total specs, requirements, changes, task progress)
|
||||
- Active changes with visual progress bars
|
||||
- Completed changes
|
||||
- Specifications with requirement counts
|
||||
|
||||
### Specifications Affected
|
||||
|
||||
- **cli-view** (NEW): Complete specification for the view dashboard command
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### File Structure
|
||||
- Created `/src/core/view.ts` implementing the `ViewCommand` class
|
||||
- Registered command in `/src/cli/index.ts`
|
||||
- Reuses existing utilities from `task-progress.ts` and `MarkdownParser`
|
||||
|
||||
### Visual Design
|
||||
- Uses Unicode box drawing characters for borders
|
||||
- Color coding: cyan for specs, yellow for active, green for completed
|
||||
- Progress bars using filled (█) and empty (░) blocks
|
||||
- Clean alignment with proper padding
|
||||
|
||||
### Technical Approach
|
||||
- Async data fetching from changes and specs directories
|
||||
- Parallel processing of specs and changes
|
||||
- Error handling for missing or invalid data
|
||||
- Maintains consistency with existing list command output
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
# CLI View Command - Changes
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Dashboard Display
|
||||
|
||||
The system SHALL provide a `view` command that displays a dashboard overview of specs and changes.
|
||||
|
||||
#### Scenario: Basic dashboard display
|
||||
|
||||
- **WHEN** user runs `openspec view`
|
||||
- **THEN** system displays a formatted dashboard with sections for summary, active changes, completed changes, and specifications
|
||||
|
||||
#### Scenario: No OpenSpec directory
|
||||
|
||||
- **WHEN** user runs `openspec view` in a directory without OpenSpec
|
||||
- **THEN** system displays error message "✗ No openspec directory found"
|
||||
|
||||
### Requirement: Summary Section
|
||||
|
||||
The dashboard SHALL display a summary section with key project metrics.
|
||||
|
||||
#### Scenario: Complete summary display
|
||||
|
||||
- **WHEN** dashboard is rendered with specs and changes
|
||||
- **THEN** system shows total number of specifications and requirements
|
||||
- **AND** shows number of active changes in progress
|
||||
- **AND** shows number of completed changes
|
||||
- **AND** shows overall task progress percentage
|
||||
|
||||
#### Scenario: Empty project summary
|
||||
|
||||
- **WHEN** no specs or changes exist
|
||||
- **THEN** summary shows zero counts for all metrics
|
||||
|
||||
### Requirement: Active Changes Display
|
||||
|
||||
The dashboard SHALL show active changes with visual progress indicators.
|
||||
|
||||
#### Scenario: Active changes with progress bars
|
||||
|
||||
- **WHEN** there are in-progress changes with tasks
|
||||
- **THEN** system displays each change with change name left-aligned
|
||||
- **AND** visual progress bar using Unicode characters
|
||||
- **AND** percentage completion on the right
|
||||
|
||||
#### Scenario: No active changes
|
||||
|
||||
- **WHEN** all changes are completed or no changes exist
|
||||
- **THEN** active changes section is omitted from display
|
||||
|
||||
### Requirement: Completed Changes Display
|
||||
|
||||
The dashboard SHALL list completed changes in a separate section.
|
||||
|
||||
#### Scenario: Completed changes listing
|
||||
|
||||
- **WHEN** there are completed changes (all tasks done)
|
||||
- **THEN** system shows them with checkmark indicators in a dedicated section
|
||||
|
||||
#### Scenario: Mixed completion states
|
||||
|
||||
- **WHEN** some changes are complete and others active
|
||||
- **THEN** system separates them into appropriate sections
|
||||
|
||||
### Requirement: Specifications Display
|
||||
|
||||
The dashboard SHALL display specifications sorted by requirement count.
|
||||
|
||||
#### Scenario: Specs listing with counts
|
||||
|
||||
- **WHEN** specifications exist in the project
|
||||
- **THEN** system shows specs sorted by requirement count (descending) with count labels
|
||||
|
||||
#### Scenario: Specs with parsing errors
|
||||
|
||||
- **WHEN** a spec file cannot be parsed
|
||||
- **THEN** system includes it with 0 requirement count
|
||||
|
||||
### Requirement: Visual Formatting
|
||||
|
||||
The dashboard SHALL use consistent visual formatting with colors and symbols.
|
||||
|
||||
#### Scenario: Color coding
|
||||
|
||||
- **WHEN** dashboard elements are displayed
|
||||
- **THEN** system uses cyan for specification items
|
||||
- **AND** yellow for active changes
|
||||
- **AND** green for completed items
|
||||
- **AND** dim gray for supplementary text
|
||||
|
||||
#### Scenario: Progress bar rendering
|
||||
|
||||
- **WHEN** displaying progress bars
|
||||
- **THEN** system uses filled blocks (█) for completed portions and light blocks (░) for remaining
|
||||
|
||||
### Requirement: Error Handling
|
||||
|
||||
The view command SHALL handle errors gracefully.
|
||||
|
||||
#### Scenario: File system errors
|
||||
|
||||
- **WHEN** file system operations fail
|
||||
- **THEN** system continues with available data and omits inaccessible items
|
||||
|
||||
#### Scenario: Invalid data structures
|
||||
|
||||
- **WHEN** specs or changes have invalid format
|
||||
- **THEN** system skips invalid items and continues rendering
|
||||
@@ -0,0 +1,47 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## Design Phase
|
||||
- [x] Research existing list command implementation
|
||||
- [x] Design dashboard layout and information architecture
|
||||
- [x] Choose appropriate command verb (`view`)
|
||||
- [x] Define visual elements (progress bars, colors, layout)
|
||||
|
||||
## Core Implementation
|
||||
- [x] Create ViewCommand class in `/src/core/view.ts`
|
||||
- [x] Implement getChangesData method for fetching change information
|
||||
- [x] Implement getSpecsData method for fetching spec information
|
||||
- [x] Implement displaySummary method for summary metrics
|
||||
- [x] Add progress bar visualization with Unicode characters
|
||||
- [x] Implement color coding using chalk
|
||||
|
||||
## Integration
|
||||
- [x] Import ViewCommand in CLI index
|
||||
- [x] Register `openspec view` command with commander
|
||||
- [x] Add proper error handling and ora spinner integration
|
||||
- [x] Ensure command appears in help documentation
|
||||
|
||||
## Data Processing
|
||||
- [x] Reuse TaskProgress utilities for change progress
|
||||
- [x] Integrate MarkdownParser for spec requirement counting
|
||||
- [x] Handle async operations for file system access
|
||||
- [x] Sort specifications by requirement count
|
||||
|
||||
## Testing and Validation
|
||||
- [x] Build project successfully with new command
|
||||
- [x] Test command with sample data
|
||||
- [x] Verify correct requirement counts match list --specs
|
||||
- [x] Test progress bar display for various completion states
|
||||
- [x] Run existing test suite to ensure no regressions
|
||||
- [x] Verify TypeScript compilation with no errors
|
||||
|
||||
## Documentation
|
||||
- [x] Add command description in CLI help
|
||||
- [x] Create change proposal documentation
|
||||
- [x] Update README with view command example (if needed)
|
||||
- [x] Add view command to user documentation (if exists)
|
||||
|
||||
## Polish
|
||||
- [x] Ensure consistent formatting and alignment
|
||||
- [x] Add helpful footer text referencing list commands
|
||||
- [x] Optimize for terminal width considerations
|
||||
- [x] Review and refine color choices for accessibility
|
||||
@@ -0,0 +1,28 @@
|
||||
# Add AGENTS.md Standard Support To Init/Update
|
||||
|
||||
## Summary
|
||||
- Teach `openspec init` to manage a root-level `AGENTS.md` file using the same marker system as `CLAUDE.md`.
|
||||
- Allow `openspec update` to refresh or scaffold that root `AGENTS.md` so AGENTS-compatible tools always receive current instructions.
|
||||
- Keep the existing `openspec/AGENTS.md` template as the canonical source while ensuring assistants that read `AGENTS.md` opt-in instructions get the latest guidance automatically.
|
||||
|
||||
## Motivation
|
||||
The README now points teams to AGENTS.md-compatible assistants, but the CLI only manages `CLAUDE.md`. Projects must hand-roll a root `AGENTS.md` file to benefit from the standard, and updates will drift unless maintainers remember to copy content manually. Extending `init` and `update` closes that gap so OpenSpec actually delivers on the promise of first-class AGENTS support.
|
||||
|
||||
## Proposal
|
||||
1. Extend the `openspec init` selection flow with an "AGENTS.md standard" option that creates or refreshes a root `AGENTS.md` file wrapped in OpenSpec markers, mirroring the existing CLAUDE integration.
|
||||
2. When generating the file, pull the managed content from the same template used in `openspec/AGENTS.md`, ensuring both locations stay in sync.
|
||||
3. Update `openspec update` so it always refreshes the root `AGENTS.md` (creating it if missing) alongside `openspec/AGENTS.md` and any other configured assistants.
|
||||
4. Document the new behavior in CLI specs and verify marker handling (no duplicates, preserve user content outside the block) with tests for both commands.
|
||||
|
||||
## Out of Scope
|
||||
- Adding additional AGENTS-specific prompts or workflows beyond the shared instructions block.
|
||||
- Non-interactive flags or bulk configuration for multiple standards in one run.
|
||||
- Broader restructuring of how templates are stored or loaded.
|
||||
|
||||
## Risks & Mitigations
|
||||
- **Risk:** Accidentally overwriting user-edited content surrounding the managed block.
|
||||
- **Mitigation:** Reuse the existing marker-update helper shared with `CLAUDE.md`, and add tests that cover files containing custom text before and after the block.
|
||||
- **Risk:** Divergence between `openspec/AGENTS.md` and the root file.
|
||||
- **Mitigation:** Source the root file content from the canonical template rather than duplicating strings inline.
|
||||
- **Risk:** Confusion about when the file is created.
|
||||
- **Mitigation:** Log creation vs update, and ensure help text references the AGENTS option during `init`.
|
||||
@@ -0,0 +1,71 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: AI Tool Configuration
|
||||
The command SHALL configure AI coding assistants with OpenSpec instructions based on user selection.
|
||||
|
||||
#### Scenario: Prompting for AI tool selection
|
||||
|
||||
- **WHEN** run
|
||||
- **THEN** prompt user to select AI tools to configure:
|
||||
- Claude Code (✅ OpenSpec custom slash commands available)
|
||||
- Cursor (✅ OpenSpec custom slash commands available)
|
||||
- AGENTS.md (works with Codex, Amp, Copilot, …)
|
||||
|
||||
### Requirement: AI Tool Configuration Details
|
||||
The command SHALL properly configure selected AI tools with OpenSpec-specific instructions using a marker system.
|
||||
|
||||
#### Scenario: Configuring Claude Code
|
||||
|
||||
- **WHEN** Claude Code is selected
|
||||
- **THEN** create or update `CLAUDE.md` in the project root directory (not inside openspec/)
|
||||
|
||||
#### Scenario: Configuring AGENTS standard
|
||||
|
||||
- **WHEN** the AGENTS.md standard is selected
|
||||
- **THEN** create or update `AGENTS.md` in the project root directory (not inside openspec/)
|
||||
|
||||
#### Scenario: Creating new CLAUDE.md
|
||||
|
||||
- **WHEN** CLAUDE.md does not exist
|
||||
- **THEN** create new file with OpenSpec content wrapped in markers:
|
||||
```markdown
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Project
|
||||
|
||||
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.
|
||||
|
||||
This project uses OpenSpec for spec-driven development. Specifications are the source of truth.
|
||||
|
||||
See @openspec/AGENTS.md for detailed conventions and guidelines.
|
||||
<!-- OPENSPEC:END -->
|
||||
```
|
||||
|
||||
#### Scenario: Creating new AGENTS.md
|
||||
|
||||
- **WHEN** AGENTS.md does not exist in the project root
|
||||
- **THEN** create new file with OpenSpec content wrapped in markers using the same template as CLAUDE.md
|
||||
|
||||
#### Scenario: Updating existing CLAUDE.md
|
||||
|
||||
- **WHEN** CLAUDE.md already exists
|
||||
- **THEN** preserve all existing content
|
||||
- **AND** insert OpenSpec content at the beginning of the file using markers
|
||||
- **AND** ensure markers don't duplicate if they already exist
|
||||
|
||||
#### Scenario: Updating existing AGENTS.md
|
||||
|
||||
- **WHEN** AGENTS.md already exists in the project root
|
||||
- **THEN** preserve all existing content
|
||||
- **AND** ensure the OpenSpec-managed block at the beginning of the file is refreshed without duplicating markers
|
||||
|
||||
#### Scenario: Managing content with markers
|
||||
|
||||
- **WHEN** using the marker system
|
||||
- **THEN** use `<!-- OPENSPEC:START -->` to mark the beginning of managed content
|
||||
- **AND** use `<!-- OPENSPEC:END -->` to mark the end of managed content
|
||||
- **AND** allow OpenSpec to update its content without affecting user customizations
|
||||
- **AND** preserve all content outside the markers intact
|
||||
|
||||
WHY use markers:
|
||||
- Users may have existing CLAUDE.md or AGENTS.md instructions they want to keep
|
||||
- OpenSpec can update its instructions in future versions
|
||||
- Clear boundary between OpenSpec-managed and user-managed content
|
||||
@@ -0,0 +1,41 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Update Behavior
|
||||
The update command SHALL update OpenSpec instruction files to the latest templates in a team-friendly manner.
|
||||
|
||||
#### Scenario: Running update command
|
||||
|
||||
- **WHEN** a user runs `openspec update`
|
||||
- **THEN** the command SHALL:
|
||||
- Check if the `openspec` directory exists
|
||||
- Replace `openspec/AGENTS.md` with the latest template (complete replacement)
|
||||
- Create or refresh a root-level `AGENTS.md` file using the managed marker block (create if missing)
|
||||
- Update **only existing** AI tool configuration files (e.g., CLAUDE.md)
|
||||
- Check each registered AI tool configurator
|
||||
- For each configurator, check if its file exists
|
||||
- Update only files that already exist using their markers
|
||||
- Preserve user content outside markers
|
||||
- Display success message listing updated files
|
||||
|
||||
### Requirement: Tool-Agnostic Updates
|
||||
The update command SHALL handle file updates in a predictable and safe manner while respecting team tool choices.
|
||||
|
||||
#### Scenario: Updating files
|
||||
|
||||
- **WHEN** updating files
|
||||
- **THEN** completely replace `openspec/AGENTS.md` with the latest template
|
||||
- **AND** create or update the root-level `AGENTS.md` using the OpenSpec markers
|
||||
- **AND** update only the OpenSpec-managed blocks in **existing** AI tool files using markers
|
||||
- **AND** use the default directory name `openspec`
|
||||
- **AND** be idempotent (repeated runs have no additional effect)
|
||||
- **AND** respect team members' AI tool choices by not creating additional tool files beyond the root `AGENTS.md`
|
||||
|
||||
### Requirement: Core Files Always Updated
|
||||
The update command SHALL always update the core OpenSpec files and display an ASCII-safe success message.
|
||||
|
||||
#### Scenario: Successful update
|
||||
|
||||
- **WHEN** the update completes successfully
|
||||
- **THEN** replace `openspec/AGENTS.md` with the latest template
|
||||
- **AND** ensure the root-level `AGENTS.md` matches the latest template via the marker block
|
||||
- **AND** update existing AI tool configuration files within markers
|
||||
- **AND** display the message: "Updated OpenSpec instructions"
|
||||
@@ -0,0 +1,17 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Extend Init Workflow
|
||||
- [x] 1.1 Add an "AGENTS.md standard" option to the `openspec init` tool-selection prompt, respecting the existing UI conventions.
|
||||
- [x] 1.2 Generate or refresh a root-level `AGENTS.md` file using the OpenSpec markers when that option is selected, sourcing content from the canonical template.
|
||||
|
||||
## 2. Enhance Update Command
|
||||
- [x] 2.1 Ensure `openspec update` writes the root `AGENTS.md` from the latest template (creating it if missing) alongside `openspec/AGENTS.md`.
|
||||
- [x] 2.2 Update success messaging and logging to reflect creation vs refresh of the AGENTS standard file.
|
||||
|
||||
## 3. Shared Template Handling
|
||||
- [x] 3.1 Refactor template utilities if necessary so both commands reuse the same content without duplication.
|
||||
- [x] 3.2 Add automated tests covering init/update flows for projects with and without an existing `AGENTS.md`, ensuring markers behave correctly.
|
||||
|
||||
## 4. Documentation
|
||||
- [x] 4.1 Update CLI specs and user-facing docs to describe AGENTS standard support.
|
||||
- [x] 4.2 Run `openspec validate add-agents-md-config --strict` and document any notable behavior changes.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Allow Additional AI Tool Initialization After Setup
|
||||
|
||||
## Summary
|
||||
- Let `openspec init` configure new AI coding tools for projects that already contain an OpenSpec structure.
|
||||
- Keep the initialization flow safe by skipping structure creation and only generating files for tools the user explicitly selects.
|
||||
- Provide clear feedback so users know which tool files were added versus already present.
|
||||
|
||||
## Motivation
|
||||
Today `openspec init` exits with an error once an `openspec/` directory exists. That protects the directory layout, but it blocks
|
||||
teams that start with one assistant (for example, Claude Code) and later want to add another such as Cursor. They have to create
|
||||
those files by hand or rerun `init` in a clean clone, which undermines the "easy onboarding" promise. Letting the command extend
|
||||
an existing installation keeps the workflow consistent and avoids manual file management.
|
||||
|
||||
## Proposal
|
||||
1. Detect an existing OpenSpec structure at the start of `openspec init` and branch into an "extend" mode instead of exiting.
|
||||
- Announce that the base structure already exists and that the command will only manage AI tool configuration files.
|
||||
- Keep the existing guard for directories or files we must not overwrite.
|
||||
2. Present the usual AI tool selection prompt even in extend mode, showing which tools are already configured.
|
||||
- Skip disabled options that remain "coming soon".
|
||||
- Mark already configured tools as such so users know whether selecting them will refresh or add files.
|
||||
3. When the user selects additional tools, generate the same initialization files that a fresh run would create (e.g., Cursor
|
||||
workspace files) while leaving untouched tools intact apart from marker-managed sections.
|
||||
- Do nothing when the user selects no new tools and keep the previous error messaging to avoid silently succeeding.
|
||||
4. Summarize the outcome (created, refreshed, skipped) before exiting with code 0 when work was performed.
|
||||
- Include friendly guidance that future updates to shared content still come from `openspec update`.
|
||||
|
||||
## Out of Scope
|
||||
- Changing how `openspec update` discovers or updates AI tool files.
|
||||
- Supporting brand-new AI tools beyond those already wired into the CLI.
|
||||
- Adding non-interactive flags for selecting multiple tools in one run (follow-up if needed).
|
||||
|
||||
## Risks & Mitigations
|
||||
- **User confusion about extend mode** → Explicitly log what will happen before prompting and summarise results afterward.
|
||||
- **Accidental overwrites** → Continue using marker-based updates and skip files unless the user chooses that tool.
|
||||
- **Inconsistent state if init fails mid-run** → Reuse existing rollback/transaction logic so partial writes clean up.
|
||||
@@ -0,0 +1,45 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Safety Checks
|
||||
The command SHALL perform safety checks to prevent overwriting existing structures and ensure proper permissions.
|
||||
|
||||
#### Scenario: Detecting existing initialization
|
||||
- **WHEN** the `openspec/` directory already exists
|
||||
- **THEN** inform the user that OpenSpec is already initialized, skip recreating the base structure, and enter an extend mode
|
||||
- **AND** continue to the AI tool selection step so additional tools can be configured
|
||||
- **AND** display the existing-initialization error message only when the user declines to add any AI tools
|
||||
|
||||
### Requirement: Interactive Mode
|
||||
The command SHALL provide an interactive menu for AI tool selection with clear navigation instructions.
|
||||
|
||||
#### Scenario: Displaying interactive menu
|
||||
- **WHEN** run in fresh or extend mode
|
||||
- **THEN** present a looping select menu that lets users toggle tools with Enter and finish via a "Done" option
|
||||
- **AND** label already configured tools with "(already configured)" while keeping disabled options marked "coming soon"
|
||||
- **AND** change the prompt copy in extend mode to "Which AI tools would you like to add or refresh?"
|
||||
- **AND** display inline instructions clarifying that Enter toggles a tool and selecting "Done" confirms the list
|
||||
|
||||
## ADDED Requirements
|
||||
### Requirement: Additional AI Tool Initialization
|
||||
`openspec init` SHALL allow users to add configuration files for new AI coding assistants after the initial setup.
|
||||
|
||||
#### Scenario: Configuring an extra tool after initial setup
|
||||
- **GIVEN** an `openspec/` directory already exists and at least one AI tool file is present
|
||||
- **WHEN** the user runs `openspec init` and selects a different supported AI tool
|
||||
- **THEN** generate that tool's configuration files with OpenSpec markers the same way as during first-time initialization
|
||||
- **AND** leave existing tool configuration files unchanged except for managed sections that need refreshing
|
||||
- **AND** exit with code 0 and display a success summary highlighting the newly added tool files
|
||||
|
||||
### Requirement: Success Output Enhancements
|
||||
`openspec init` SHALL summarize tool actions when initialization or extend mode completes.
|
||||
|
||||
#### Scenario: Showing tool summary
|
||||
- **WHEN** the command completes successfully
|
||||
- **THEN** display a categorized summary of tools that were created, refreshed, or skipped (including already-configured skips)
|
||||
- **AND** personalize the "Next steps" header using the names of the selected tools, defaulting to a generic label when none remain
|
||||
|
||||
### Requirement: Exit Code Adjustments
|
||||
`openspec init` SHALL treat extend mode with no selected tools as a guarded error.
|
||||
|
||||
#### Scenario: Preventing empty extend runs
|
||||
- **WHEN** OpenSpec is already initialized and the user selects no additional tools
|
||||
- **THEN** exit with code 1 after showing the existing-initialization guidance message
|
||||
@@ -0,0 +1,16 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Extend Init Guard
|
||||
- [x] 1.1 Detect existing OpenSpec structures at the start of `openspec init` and enter an extend mode instead of failing.
|
||||
- [x] 1.2 Log that core scaffolding will be skipped while still protecting against missing write permissions.
|
||||
|
||||
## 2. Update AI Tool Selection
|
||||
- [x] 2.1 Present AI tool choices even in extend mode, indicating which tools are already configured.
|
||||
- [x] 2.2 Ensure disabled "coming soon" tools remain non-selectable.
|
||||
|
||||
## 3. Generate Additional Tool Files
|
||||
- [x] 3.1 Create configuration files for newly selected tools while leaving untouched tools unaffected apart from marker-managed sections.
|
||||
- [x] 3.2 Summarize created, refreshed, and skipped tools before exiting with the appropriate code.
|
||||
|
||||
## 4. Verification
|
||||
- [x] 4.1 Add tests covering rerunning `openspec init` to add another tool and the scenario where the user declines to add anything.
|
||||
@@ -0,0 +1,119 @@
|
||||
# Add Slash Command Support for Coding Agents
|
||||
|
||||
## Summary
|
||||
- Enable OpenSpec to generate and update custom slash commands for supported coding agents (Claude Code and Cursor).
|
||||
- Provide three slash commands aligned with OpenSpec's workflow: proposal (start a change proposal), apply (implement), and archive.
|
||||
- Share slash command templating between agents to make future extensions simple.
|
||||
|
||||
## Motivation
|
||||
Developers use different coding agents and editors. Having consistent slash commands across tools for the OpenSpec workflow reduces friction and ensures a standard way to trigger the workflow. Supporting both Claude Code and Cursor now lays a foundation for future agents that introduce slash command features.
|
||||
|
||||
## Proposal
|
||||
1. During `openspec init`, when a user selects a supported tool, generate slash command configuration for three OpenSpec workflow stages:
|
||||
- Claude (namespaced): `/openspec/proposal`, `/openspec/apply`, `/openspec/archive`.
|
||||
- Cursor (flat, prefixed): `/openspec-proposal`, `/openspec-apply`, `/openspec-archive`.
|
||||
- Semantics:
|
||||
- Create – scaffold a change (ID, `proposal.md`, `tasks.md`, delta specs); validate strictly.
|
||||
- Apply – implement an approved change; complete tasks; validate strictly.
|
||||
- Archive – archive after deployment; update specs if needed.
|
||||
- Each command file MUST embed concise, step-by-step instructions sourced from `openspec/README.md` (see Template Content section).
|
||||
2. Store slash command files per tool:
|
||||
- Claude Code: `.claude/commands/openspec/{proposal,apply,archive}.md`
|
||||
- Cursor: `.cursor/commands/{openspec-proposal,openspec-apply,openspec-archive}.md`
|
||||
- Ensure nested directories are created.
|
||||
3. Command file format and metadata:
|
||||
- Use Markdown with optional YAML frontmatter for tool metadata (name/title, description, category/tags) when supported by the tool.
|
||||
- Place OpenSpec markers around the body only, never inside frontmatter.
|
||||
- Keep the visible slash name, file name, and any frontmatter `name`/`id` consistently aligned (e.g., `proposal`, `openspec-proposal`).
|
||||
- Namespacing: categorize these under “OpenSpec” and prefer unique IDs (e.g., `openspec-proposal`) to avoid collisions.
|
||||
4. Centralize templates: define command bodies once and reuse across tools; apply minimal per-tool wrappers (frontmatter, categories, filenames).
|
||||
5. During `openspec update`, refresh only existing slash command files (per-file basis) within markers; do not create missing files or new tools.
|
||||
|
||||
## Design Ideas
|
||||
- Introduce `SlashCommandConfigurator` to manage multiple files per tool.
|
||||
- Expose targets rather than a single `configFileName` (e.g., `getTargets(): Array<{ path: string; kind: 'slash'; id: string }>`).
|
||||
- Provide `generateAll(projectPath, openspecDir)` for init and `updateExisting(projectPath, openspecDir)` for update.
|
||||
- Per-tool adapters add only frontmatter and pathing; bodies come from shared templates.
|
||||
- Templates live in `TemplateManager` with helpers that extract concise, authoritative snippets from `openspec/README.md`.
|
||||
- Update flow logs per-file results so users see exactly which slash files were refreshed.
|
||||
|
||||
### Marker Placement
|
||||
- Markers MUST wrap only the Markdown body contents:
|
||||
- Frontmatter (if present) goes first.
|
||||
- Then `<!-- OPENSPEC:START -->` … body … `<!-- OPENSPEC:END -->`.
|
||||
- Avoid inserting markers into the YAML block to prevent parse errors.
|
||||
|
||||
### Idempotency and Creation Rules
|
||||
- `init`: create all three files for the chosen tool(s) once; subsequent `init` runs are no-ops for existing files.
|
||||
- `update`: refresh only files that exist; skip missing ones without creating new files.
|
||||
- Directory creation for `.claude/commands/openspec/` and `.cursor/commands/` is the configurator’s responsibility.
|
||||
|
||||
### Command Naming & UX
|
||||
- Claude Code: use namespacing in the slash itself for readability and grouping: `/openspec/proposal`, `/openspec/apply`, `/openspec/archive`.
|
||||
- Cursor: use flat names with an `openspec-` prefix: `/openspec-proposal`, `/openspec-apply`, `/openspec-archive`. Group via `category: OpenSpec` when supported.
|
||||
- Consistency: align file names, visible slash names, and any frontmatter `id` (e.g., `id: openspec-apply`).
|
||||
- Migration: do not rename existing commands during `update`; apply new naming only on `init` (or via an explicit migrate step).
|
||||
|
||||
## Open Questions
|
||||
- Validate exact metadata/frontmatter supported by each tool version; if unsupported, omit frontmatter and ship Markdown body only.
|
||||
- Confirm the final Cursor command file location for the targeted versions; fall back to Markdown-only if Cursor does not parse frontmatter.
|
||||
- Evaluate additional commands beyond the initial three (e.g., `/show-change`, `/validate-all`) based on user demand.
|
||||
|
||||
## Alternatives
|
||||
- Hard-code slash command text per tool (rejected: duplicates content; increases maintenance).
|
||||
- Delay Cursor support until its config stabilizes (partial accept): gate Cursor behind a feature flag until verified in real environments.
|
||||
|
||||
## Risks
|
||||
- Tool configuration formats may change, requiring updates to wrappers/frontmatter.
|
||||
- Incorrect paths or categories can hide commands; add path existence checks and clear logging.
|
||||
- Marker misuse (inside frontmatter) can break parsing; enforce placement rules in tests.
|
||||
|
||||
## Future Work
|
||||
- Support additional editors/agents that expose slash command APIs.
|
||||
- Allow users to customize command names and categories during `openspec init`.
|
||||
- Provide a dedicated command to regenerate slash commands without running full `update`.
|
||||
|
||||
## File Format Examples
|
||||
The following examples illustrate expected structure. If a tool does not support frontmatter, omit the YAML block and keep only the markers + body.
|
||||
|
||||
### Claude Code: `.claude/commands/openspec/proposal.md`
|
||||
```markdown
|
||||
---
|
||||
name: OpenSpec: Proposal
|
||||
description: Scaffold a new OpenSpec change and validate strictly.
|
||||
category: OpenSpec
|
||||
tags: [openspec, change]
|
||||
---
|
||||
<!-- OPENSPEC:START -->
|
||||
...command body from shared template...
|
||||
<!-- OPENSPEC:END -->
|
||||
```
|
||||
|
||||
Slash invocation: `/openspec/proposal` (namespaced)
|
||||
|
||||
### Cursor: `.cursor/commands/openspec-proposal.md`
|
||||
```markdown
|
||||
---
|
||||
name: /openspec-proposal
|
||||
id: openspec-proposal
|
||||
category: OpenSpec
|
||||
description: Scaffold a new OpenSpec change and validate strictly.
|
||||
---
|
||||
<!-- OPENSPEC:START -->
|
||||
...command body from shared template...
|
||||
<!-- OPENSPEC:END -->
|
||||
```
|
||||
|
||||
Slash invocation: `/openspec-proposal` (flat, prefixed)
|
||||
|
||||
## Template Content
|
||||
Templates should be brief, actionable, and sourced from `openspec/README.md` to avoid duplication. Each command body includes:
|
||||
- Guardrails: ask 1–2 clarifying questions if needed; follow minimal-complexity rules; use `pnpm` for Node projects.
|
||||
- Step list tailored to the workflow stage (proposal, apply, archive), including strict validation commands.
|
||||
- Pointers to `openspec show`, `openspec list`, and troubleshooting tips when validation fails.
|
||||
|
||||
## Testing Strategy
|
||||
- Golden snapshots for generated files per tool (frontmatter + markers + body).
|
||||
- Partial presence tests: if 1–2 files exist, `update` only refreshes those and does not create missing ones.
|
||||
- Marker placement tests: ensure markers never appear inside frontmatter; cover missing/duplicated marker recovery behavior.
|
||||
- Logging tests: `update` reports per-file updates for slash commands.
|
||||
@@ -0,0 +1,21 @@
|
||||
## ADDED Requirements
|
||||
### Requirement: Slash Command Configuration
|
||||
The init command SHALL generate slash command files for supported editors using shared templates.
|
||||
|
||||
#### Scenario: Generating slash commands for Claude Code
|
||||
- **WHEN** the user selects Claude Code during initialization
|
||||
- **THEN** create `.claude/commands/openspec/proposal.md`, `.claude/commands/openspec/apply.md`, and `.claude/commands/openspec/archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
|
||||
#### Scenario: Generating slash commands for Cursor
|
||||
- **WHEN** the user selects Cursor during initialization
|
||||
- **THEN** create `.cursor/commands/openspec-proposal.md`, `.cursor/commands/openspec-apply.md`, and `.cursor/commands/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
|
||||
#### Scenario: Generating slash commands for OpenCode
|
||||
- **WHEN** the user selects OpenCode during initialization
|
||||
- **THEN** create `.opencode/commands/openspec-proposal.md`, `.opencode/commands/openspec-apply.md`, and `.opencode/commands/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
## ADDED Requirements
|
||||
### Requirement: Slash Command Updates
|
||||
The update command SHALL refresh existing slash command files for configured tools without creating new ones.
|
||||
|
||||
#### Scenario: Updating slash commands for Claude Code
|
||||
- **WHEN** `.claude/commands/openspec/` contains `proposal.md`, `apply.md`, and `archive.md`
|
||||
- **THEN** refresh each file using shared templates
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
|
||||
#### Scenario: Updating slash commands for Cursor
|
||||
- **WHEN** `.cursor/commands/` contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **THEN** refresh each file using shared templates
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
|
||||
#### Scenario: Updating slash commands for OpenCode
|
||||
- **WHEN** `.opencode/commands/` contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **THEN** refresh each file using shared templates
|
||||
- **AND** ensure templates include instructions for the relevant workflow stage
|
||||
|
||||
#### Scenario: Missing slash command file
|
||||
- **WHEN** a tool lacks a slash command file
|
||||
- **THEN** do not create a new file during update
|
||||
@@ -0,0 +1,20 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Templates and Configurators
|
||||
- [x] 1.1 Create shared templates for the Proposal, Apply, and Archive commands with instructions for each workflow stage from `openspec/README.md`.
|
||||
- [x] 1.2 Implement a `SlashCommandConfigurator` base and tool-specific configurators for Claude Code and Cursor.
|
||||
|
||||
## 2. Claude Code Integration
|
||||
- [x] 2.1 Generate `.claude/commands/openspec/{proposal,apply,archive}.md` during `openspec init` using shared templates.
|
||||
- [x] 2.2 Update existing `.claude/commands/openspec/*` files during `openspec update`.
|
||||
|
||||
## 3. Cursor Integration
|
||||
- [x] 3.1 Generate `.cursor/commands/{openspec-proposal,openspec-apply,openspec-archive}.md` during `openspec init` using shared templates.
|
||||
- [x] 3.2 Update existing `.cursor/commands/*` files during `openspec update`.
|
||||
|
||||
## 4. Verification
|
||||
- [x] 4.1 Add tests verifying slash command files are created and updated correctly.
|
||||
|
||||
## 5. OpenCode Integration
|
||||
- [x] 5.1 Generate `.opencode/commands/{openspec-proposal,openspec-apply,openspec-archive}.md` during `openspec init` using shared templates.
|
||||
- [x] 5.2 Update existing `.opencode/commands/*` files during `openspec update`.
|
||||
@@ -0,0 +1,19 @@
|
||||
## Why
|
||||
Recent cross-shell regressions for `openspec` commands revealed that our existing unit/integration tests do not exercise the packaged CLI or shell-specific behavior. The prior attempt at Vitest spawn tests stalled because it coupled e2e coverage with `pnpm pack` installs, which fail in network-restricted environments. With those findings incorporated, we now need an approved plan to realign the work.
|
||||
|
||||
## What Changes
|
||||
- Adopt a phased strategy that first stabilizes direct spawn testing of the built CLI (`node dist/cli/index.js`) using lightweight fixtures and a shared `runCLI` helper.
|
||||
- Expand coverage once the spawn harness is stable, keeping the initial matrix focused on bash jobs for Linux/macOS and `pwsh` on Windows while exercising both the direct `node dist/cli/index.js` invocation and the bin shim with non-TTY defaults and captured diagnostics.
|
||||
- Treat packaging/install validation as an optional CI safeguard: when a runner has registry access, run a simple pnpm-based pack→install→smoke-test flow; otherwise document it as out of scope while closing remaining hardening items.
|
||||
- Close out the remaining cross-shell hardening items: ensure `.gitattributes` covers packaged assets, enforce executable bits for CLI shims during CI, and finish the pending SIGINT handling improvements.
|
||||
|
||||
## Impact
|
||||
- Tests: add `test/cli-e2e` spawn suite, create the shared `runCLI` helper, and adjust `vitest.setup.ts` as needed.
|
||||
- Tooling: update GitHub Actions workflows with the lightweight matrix above and (optionally) a packaging install check where network is available.
|
||||
- Docs: note phase progress and any limitations inline in this proposal (or the relevant spec) so future phases have clear context.
|
||||
|
||||
### Phase 1 Status
|
||||
- Shared `test/helpers/run-cli.ts` guarantees the CLI bundle exists before spawning and enforces non-TTY defaults for every invocation.
|
||||
- New `test/cli-e2e/basic.test.ts` covers `--help`, `--version`, a successful `validate --all --json`, and an unknown-item error path against the `tmp-init` fixture copy.
|
||||
- Legacy top-level `validate` exec tests now rely on `runCLI`, avoiding manual `execSync` usage while keeping their fixture authoring intact.
|
||||
- CI matrix groundwork is in place (bash on Linux/macOS, pwsh on Windows) so the spawn suite runs the same way the helper does across supported shells.
|
||||
@@ -0,0 +1,9 @@
|
||||
## 1. Phase 1 – Stabilize Local Spawn Coverage
|
||||
- [x] 1.1 Add `test/helpers/run-cli.ts` that ensures the build runs once and executes `node dist/cli/index.js` with non-TTY defaults; update `vitest.setup.ts` to reuse the shared build step.
|
||||
- [x] 1.2 Seed `test/cli-e2e` using the minimal fixture set (`tmp-init` or copy) to cover help/version, a happy-path `validate`, and a representative error flow via the new helper.
|
||||
- [x] 1.3 Migrate the highest-value existing CLI exec tests (e.g., validate) onto `runCLI` and summarize Phase 1 coverage in this proposal for the next phase.
|
||||
|
||||
## 2. Phase 2 – Expand Cross-Shell Validation
|
||||
- [x] 2.1 Exercise both entry points (`node dist/cli/index.js`, `bin/openspec.js`) in the spawn suite and add diagnostics for shell/OS context.
|
||||
- [x] 2.2 Extend GitHub Actions to run the spawn suite on bash jobs for Linux/macOS and a `pwsh` job on Windows; capture shell/OS diagnostics and note follow-ups for additional shells.
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# Change: Improve Deterministic Tests (Isolate From Repo State)
|
||||
|
||||
## Problem
|
||||
|
||||
Some unit tests (e.g., ChangeCommand.show/validate) read the live repository
|
||||
state via `process.cwd()` and `openspec/changes`. This makes outcomes depend on
|
||||
whatever directories happen to exist and the order returned by `fs.readdir`,
|
||||
causing flaky success/failure across environments.
|
||||
|
||||
Symptoms observed:
|
||||
- Tests sometimes select a partial or unrelated change folder.
|
||||
- Failures like missing `proposal.md` when a stray change directory is picked.
|
||||
- Environment/sandbox differences alter `readdir` ordering and worker behavior.
|
||||
|
||||
## Goals
|
||||
|
||||
- Make tests deterministic and hermetic.
|
||||
- Remove dependence on real repo contents and directory ordering.
|
||||
- Keep runtime behavior unchanged for end users.
|
||||
|
||||
## Non‑Goals
|
||||
|
||||
- Introduce heavy frameworks or test harness complexity.
|
||||
- Redesign CLI behavior or change default paths for users.
|
||||
|
||||
## Approach
|
||||
|
||||
1) Test-local fixture root
|
||||
- Each suite that touches filesystem discovery creates a temporary directory:
|
||||
- `openspec/changes/sample-change/proposal.md`
|
||||
- `openspec/changes/sample-change/specs/sample/spec.md`
|
||||
- `beforeAll`: `process.chdir(tmpRoot)`; `afterAll`: restore original cwd.
|
||||
- Use a constant `changeName = 'sample-change'`; remove reliance on
|
||||
`readdir` order.
|
||||
|
||||
2) Optional thin DI for commands (minimal, if needed)
|
||||
- Allow `ChangeCommand` (and similar) to accept an optional `root` path
|
||||
(default `process.cwd()`), used for path resolution.
|
||||
- Tests pass the temp root explicitly; production code remains unchanged.
|
||||
|
||||
3) Harden discovery helpers (safe enhancement)
|
||||
- Update `getActiveChangeIds()`/`getActiveChanges()` to include only
|
||||
directories containing `proposal.md` (and optionally at least one
|
||||
`specs/*/spec.md`).
|
||||
- Prevents incomplete/stray change folders from being treated as active.
|
||||
|
||||
## Rationale
|
||||
|
||||
- Small, focused changes eliminate flakiness without altering user workflows.
|
||||
- Temporary fixtures are a well-understood testing pattern and keep tests fast.
|
||||
- Optional constructor root param is a minimal DI surface that avoids global
|
||||
stubbing and keeps code simple.
|
||||
|
||||
## Risks & Mitigations
|
||||
|
||||
- Risk: Tests forget to restore `process.cwd()`.
|
||||
- Mitigation: Add `afterAll` guard restoring cwd; reset `process.exitCode` in
|
||||
`afterEach` where modified.
|
||||
- Risk: Behavior divergence if DI root is misused.
|
||||
- Mitigation: Default to `process.cwd()`; only tests pass custom roots.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Tests that previously depended on repo state now:
|
||||
- Create and use a temp fixture root.
|
||||
- Do not read real `openspec/changes` during execution.
|
||||
- Pass consistently regardless of directory order or stray folders.
|
||||
- No change to CLI behavior for end users (paths still default to cwd).
|
||||
|
||||
## Rollout
|
||||
|
||||
- Phase 1: Convert the suites that hit `ChangeCommand.show/validate` to
|
||||
isolated fixtures; verify stability locally and in CI.
|
||||
- Phase 2: Apply the same pattern to any remaining suites that touch file
|
||||
discovery (`list`, `show`, `validate`, `diff`).
|
||||
- Phase 3 (optional): Introduce the constructor `root` param and discovery
|
||||
hardening, if Phase 1 alone isn’t sufficient.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Test Isolation
|
||||
- [x] 1.1 Create temp fixture roots per suite (openspec/changes, openspec/specs)
|
||||
- [x] 1.2 Use process.chdir to temp root within tests
|
||||
- [x] 1.3 Restore original cwd and clean temp dirs after each
|
||||
|
||||
## 2. Deterministic Discovery
|
||||
- [x] 2.1 Implement getActiveChangeIds(root?) to only include dirs with proposal.md
|
||||
- [x] 2.2 Implement getSpecIds(root?) to only include dirs with spec.md
|
||||
- [x] 2.3 Return sorted results to avoid fs.readdir ordering variance
|
||||
|
||||
## 3. Command Integration
|
||||
- [x] 3.1 Ensure change/show/validate rely on cwd and discovery helpers
|
||||
- [x] 3.2 Keep runtime behavior unchanged for end users
|
||||
|
||||
## 4. Validation
|
||||
- [x] 4.1 Convert affected command tests (show, spec, validate, change) to isolated fixtures
|
||||
- [x] 4.2 Verify tests pass consistently across environments
|
||||
- [x] 4.3 Confirm no reads from real repo state during tests
|
||||
|
||||
## 5. Optional (Not Needed Now)
|
||||
- [x] 5.1 Add optional root param to discovery helpers (default process.cwd())
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
## Why
|
||||
The current `openspec init` flow assumes a single assistant selection and stops once an OpenSpec structure already exists. That makes onboarding feel rigid: teams cannot configure multiple tools in one pass, they do not learn which files were refreshed, and the success copy always references Claude even when other assistants are involved.
|
||||
|
||||
## What Changes
|
||||
- Allow selecting multiple assistants during `openspec init`, including refreshing existing configurations in a single run.
|
||||
- Provide richer onboarding copy that summarizes which tool files were created or refreshed and guides users on next steps for each assistant.
|
||||
- Align generated AI-instruction content and specs so CLAUDE.md and AGENTS.md share the same OpenSpec guidance.
|
||||
- Update specs and tests to cover the multi-select prompt, improved summaries, and extend-mode coordination.
|
||||
|
||||
## Impact
|
||||
- Specs: `cli-init`
|
||||
- Code: `src/core/init.ts`, `src/core/config.ts`, `src/core/templates/*`, `src/core/configurators/*`
|
||||
- Tests: `test/core/init.test.ts`, `test/core/update.test.ts`
|
||||
@@ -0,0 +1,92 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: AI Tool Configuration
|
||||
|
||||
The command SHALL configure AI coding assistants with OpenSpec instructions based on user selection.
|
||||
|
||||
#### Scenario: Prompting for AI tool selection
|
||||
|
||||
- **WHEN** run interactively
|
||||
- **THEN** prompt the user with "Which AI tools do you use?" using a multi-select menu
|
||||
- **AND** list every available tool with a checkbox:
|
||||
- Claude Code (creates or refreshes CLAUDE.md and slash commands)
|
||||
- Cursor (creates or refreshes `.cursor/commands/*` slash commands)
|
||||
- AGENTS.md standard (creates or refreshes AGENTS.md with OpenSpec markers)
|
||||
- **AND** show "(already configured)" beside tools whose managed files exist so users understand selections will refresh content
|
||||
- **AND** treat disabled tools as "coming soon" and keep them unselectable
|
||||
- **AND** allow confirming with Enter after selecting one or more tools
|
||||
|
||||
### Requirement: AI Tool Configuration Details
|
||||
|
||||
The command SHALL properly configure selected AI tools with OpenSpec-specific instructions using a marker system.
|
||||
|
||||
#### Scenario: Configuring Claude Code
|
||||
|
||||
- **WHEN** Claude Code is selected
|
||||
- **THEN** create or update `CLAUDE.md` in the project root directory (not inside openspec/)
|
||||
|
||||
#### Scenario: Creating new CLAUDE.md
|
||||
|
||||
- **WHEN** CLAUDE.md does not exist
|
||||
- **THEN** create new file with OpenSpec content wrapped in markers:
|
||||
```markdown
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Instructions
|
||||
|
||||
Instructions for AI coding assistants using OpenSpec for spec-driven development.
|
||||
|
||||
## TL;DR Quick Checklist
|
||||
- Search existing work: `openspec spec list --long`, `openspec list`
|
||||
- Decide scope: new capability vs modify existing capability
|
||||
- Pick a unique `change-id`: verb-led kebab-case (`add-`, `update-`, `remove-`, `refactor-`)
|
||||
- Scaffold: `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas
|
||||
- Validate with `openspec validate [change-id] --strict`
|
||||
- Request approval before implementation
|
||||
<!-- OPENSPEC:END -->
|
||||
```
|
||||
|
||||
#### Scenario: Updating existing CLAUDE.md
|
||||
|
||||
- **WHEN** CLAUDE.md already exists
|
||||
- **THEN** preserve all existing content
|
||||
- **AND** insert OpenSpec content at the beginning of the file using markers
|
||||
- **AND** ensure markers don't duplicate if they already exist
|
||||
|
||||
#### Scenario: Managing content with markers
|
||||
|
||||
- **WHEN** using the marker system
|
||||
- **THEN** use `<!-- OPENSPEC:START -->` to mark the beginning of managed content
|
||||
- **AND** use `<!-- OPENSPEC:END -->` to mark the end of managed content
|
||||
- **AND** allow OpenSpec to update its content without affecting user customizations
|
||||
- **AND** preserve all content outside the markers intact
|
||||
|
||||
### Requirement: Interactive Mode
|
||||
|
||||
The command SHALL provide an interactive menu for AI tool selection with clear navigation instructions.
|
||||
|
||||
#### Scenario: Displaying interactive menu
|
||||
|
||||
- **WHEN** run
|
||||
- **THEN** prompt the user with: "Which AI tools do you use?"
|
||||
- **AND** show a checkbox-based multi-select menu with available tools (Claude Code, Cursor, AGENTS.md standard)
|
||||
- **AND** show disabled options as "coming soon" (not selectable)
|
||||
- **AND** display inline help indicating Space toggles selections and Enter confirms
|
||||
|
||||
#### Scenario: Navigating the menu
|
||||
|
||||
- **WHEN** the user is in the menu
|
||||
- **THEN** allow arrow keys to move between options
|
||||
- **AND** allow Spacebar to toggle the highlighted option
|
||||
- **AND** allow Enter key to confirm all current selections
|
||||
|
||||
### Requirement: Success Output
|
||||
|
||||
The command SHALL provide clear, actionable next steps upon successful initialization.
|
||||
|
||||
#### Scenario: Displaying success message
|
||||
|
||||
- **WHEN** initialization completes successfully
|
||||
- **THEN** display a success banner followed by actionable prompts tailored to the selected tools
|
||||
- **AND** summarize which assistant files were created versus refreshed (e.g., `CLAUDE.md (created)`, `.cursor/commands/openspec-apply.md (refreshed)`)
|
||||
- **AND** include copy-pasteable onboarding prompts for each configured assistant, replacing placeholder text ([YOUR FEATURE HERE]) with real guidance to customize
|
||||
- **AND** reference AGENTS.md-compatible assistants when no tool-specific file exists (e.g., when only AGENTS.md standard is selected)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
## 1. Planning & Spec Updates
|
||||
- [x] 1.1 Confirm overlap with `add-multi-agent-init` and coordinate extend-mode flow
|
||||
- [x] 1.2 Update `openspec/specs/cli-init/spec.md` to capture multi-select onboarding requirements
|
||||
|
||||
## 2. Implementation
|
||||
- [x] 2.1 Add multi-select support to the `openspec init` prompt, including indicators for existing tool configs
|
||||
- [x] 2.2 Enhance success messaging to summarize created/refreshed assets per tool
|
||||
- [x] 2.3 Ensure shared instruction template is applied consistently (CLAUDE.md, AGENTS.md, slash commands)
|
||||
|
||||
## 3. Quality
|
||||
- [x] 3.1 Expand unit tests for init/update flows covering multi-select and summaries
|
||||
- [x] 3.2 Perform `openspec init` smoke test in a temp directory (document output)
|
||||
@@ -0,0 +1,81 @@
|
||||
# Remove Diff Command
|
||||
|
||||
## Problem
|
||||
|
||||
The `openspec diff` command adds unnecessary complexity to the OpenSpec CLI for several reasons:
|
||||
|
||||
1. **Redundant functionality**: The `openspec show` command already provides comprehensive visualization of changes through structured JSON output and markdown rendering
|
||||
2. **Maintenance burden**: The diff command requires a separate dependency (jest-diff) and additional code complexity (~227 lines)
|
||||
3. **Limited value**: Developers can achieve better diff visualization using existing tools:
|
||||
- Git diff for actual file changes
|
||||
- The `show` command for structured change viewing
|
||||
- Standard diff utilities for comparing spec files directly
|
||||
4. **Inconsistent with verb-noun pattern**: The command doesn't follow the preferred verb-first command structure that other commands are migrating to
|
||||
|
||||
## Solution
|
||||
|
||||
Remove the `openspec diff` command entirely and guide users to more appropriate alternatives:
|
||||
|
||||
1. **For viewing change content**: Use `openspec show <change-name>` which provides:
|
||||
- Structured JSON output with `--json` flag
|
||||
- Markdown rendering for human-readable format
|
||||
- Delta-only views with `--deltas-only` flag
|
||||
- Full spec content visualization
|
||||
|
||||
2. **For comparing files**: Use standard tools:
|
||||
- `git diff` for version control comparisons
|
||||
- System diff utilities for file-by-file comparisons
|
||||
- IDE diff viewers for visual comparisons
|
||||
|
||||
## Benefits
|
||||
|
||||
- **Reduced complexity**: Removes ~227 lines of code and the jest-diff dependency
|
||||
- **Clearer user journey**: Directs users to the canonical `show` command for viewing changes
|
||||
- **Lower maintenance**: Fewer commands to maintain and test
|
||||
- **Better alignment**: Focuses on the core OpenSpec workflow without redundant features
|
||||
|
||||
## Implementation
|
||||
|
||||
### Files to Remove
|
||||
- `/src/core/diff.ts` - The entire diff command implementation
|
||||
- `/openspec/specs/cli-diff/spec.md` - The diff command specification
|
||||
|
||||
### Files to Update
|
||||
- `/src/cli/index.ts` - Remove diff command registration (lines 8, 84-96)
|
||||
- `/package.json` - Remove jest-diff dependency
|
||||
- `/README.md` - Remove diff command documentation
|
||||
- `/openspec/README.md` - Remove diff command references
|
||||
- Various documentation files mentioning `openspec diff`
|
||||
|
||||
### Migration Guide for Users
|
||||
|
||||
Users currently using `openspec diff` should transition to:
|
||||
|
||||
```bash
|
||||
# Before
|
||||
openspec diff add-feature
|
||||
|
||||
# After - view the change proposal
|
||||
openspec show add-feature
|
||||
|
||||
# After - view only the deltas
|
||||
openspec show add-feature --json --deltas-only
|
||||
|
||||
# After - use git for file comparisons
|
||||
git diff openspec/specs openspec/changes/add-feature/specs
|
||||
```
|
||||
|
||||
## Risks
|
||||
|
||||
- **User disruption**: Existing users may have workflows depending on the diff command
|
||||
- Mitigation: Provide clear migration guide and deprecation period
|
||||
|
||||
- **Loss of visual diff**: The colored, unified diff format will no longer be available
|
||||
- Mitigation: Users can use git diff or other tools for visual comparisons
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- Successful removal with no broken dependencies
|
||||
- Documentation updated to reflect the change
|
||||
- Tests passing without the diff command
|
||||
- Reduced package size from removing jest-diff dependency
|
||||
@@ -0,0 +1,37 @@
|
||||
# Remove Diff Command - Tasks
|
||||
|
||||
## 1. Remove Core Implementation
|
||||
- [x] Delete `/src/core/diff.ts`
|
||||
- [x] Remove DiffCommand import from `/src/cli/index.ts`
|
||||
- [x] Remove diff command registration from CLI
|
||||
|
||||
## 2. Remove Specifications
|
||||
- [x] Delete `/openspec/specs/cli-diff/spec.md`
|
||||
- [x] Archive the spec for historical reference if needed
|
||||
|
||||
## 3. Update Dependencies
|
||||
- [x] Remove jest-diff from package.json dependencies
|
||||
- [x] Run pnpm install to update lock file
|
||||
|
||||
## 4. Update Documentation
|
||||
- [x] Update main README.md to remove diff command references
|
||||
- [x] Update openspec/README.md to remove diff command from command list
|
||||
- [x] Update CLAUDE.md template if it mentions diff command
|
||||
- [x] Update any example workflows that use diff command
|
||||
|
||||
## 5. Update Related Files
|
||||
- [x] Search and update any remaining references to "openspec diff" in:
|
||||
- Template files
|
||||
- Test files (if any exist for diff command)
|
||||
- Archive documentation
|
||||
- Change proposals
|
||||
|
||||
## 7. Testing
|
||||
- [x] Ensure all tests pass after removal
|
||||
- [x] Verify CLI help text no longer shows diff command
|
||||
- [x] Test that show command provides adequate replacement functionality
|
||||
|
||||
## 8. Documentation of Alternative Workflows
|
||||
- [x] Document how to use `openspec show` for viewing changes
|
||||
- [x] Document how to use git diff for file comparisons
|
||||
- [x] Add migration guide to help text or documentation
|
||||
@@ -0,0 +1,25 @@
|
||||
# Change: Sort Active Changes by Progress
|
||||
|
||||
## Problem
|
||||
- The dashboard currently lists active changes in filesystem discovery order.
|
||||
- Users cannot quickly spot proposals that have not started or are nearly complete.
|
||||
- Inconsistent ordering between runs makes it harder to track progress when many changes exist.
|
||||
|
||||
## Proposal
|
||||
1. Update the Active Changes list in the dashboard to sort by percentage of completion in ascending order so 0% items show first.
|
||||
2. When two changes share the same completion percentage, break ties deterministically by change identifier (alphabetical).
|
||||
|
||||
## Benefits
|
||||
- Highlights work that has not started yet, enabling quicker prioritization.
|
||||
- Provides consistent ordering across machines and repeated runs.
|
||||
- Keeps the dashboard compact while communicating the most important status signal.
|
||||
|
||||
## Risks & Mitigations
|
||||
- **Risk:** Sorting logic could regress rendering when progress data is missing.
|
||||
- **Mitigation:** Treat missing progress as 0% so items still surface and document behavior in tests.
|
||||
- **Risk:** Additional sorting could impact performance for large change sets.
|
||||
- **Mitigation:** The number of active changes is typically small; sorting a few entries is negligible.
|
||||
|
||||
## Success Criteria
|
||||
- Dashboard output shows active changes ordered by ascending completion percentage with deterministic tie-breaking.
|
||||
- Unit coverage verifying the sort when percentages vary and when ties occur.
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Active Changes Display
|
||||
The dashboard SHALL show active changes with visual progress indicators.
|
||||
|
||||
#### Scenario: Active changes ordered by completion percentage
|
||||
- **WHEN** multiple active changes are displayed with progress information
|
||||
- **THEN** list them sorted by completion percentage ascending so 0% items appear first
|
||||
- **AND** treat missing progress values as 0% for ordering
|
||||
- **AND** break ties by change identifier in ascending alphabetical order to keep output deterministic
|
||||
@@ -0,0 +1,8 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Dashboard Sorting Logic
|
||||
- [x] 1.1 Update the Active Changes rendering to sort by completion percentage ascending.
|
||||
- [x] 1.2 Treat missing progress as 0% and break ties alphabetically by change identifier.
|
||||
|
||||
## 2. Verification
|
||||
- [x] 2.1 Add tests that cover different completion percentages and tie cases to confirm deterministic ordering.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Update Agent Instruction File Name
|
||||
|
||||
## Problem
|
||||
The agent instructions live in `openspec/README.md`, which clashes with conventional project README usage and creates confusion for tooling and contributors.
|
||||
|
||||
## Solution
|
||||
Rename the agent instruction file to `openspec/AGENTS.md` and update OpenSpec tooling to use the new filename:
|
||||
- `openspec init` generates `AGENTS.md` instead of `README.md`
|
||||
- Templates and code reference `AGENTS.md`
|
||||
- Specifications and documentation are updated accordingly
|
||||
|
||||
## Benefits
|
||||
- Clear separation from project documentation
|
||||
- Consistent naming with other agent instruction files
|
||||
- Simplifies tooling and project onboarding
|
||||
|
||||
## Implementation
|
||||
- Rename instruction file and template
|
||||
- Update CLI commands (`init`, `update`) to read/write `AGENTS.md`
|
||||
- Adjust specs and documentation to reference the new path
|
||||
|
||||
## Risks
|
||||
- Existing projects may still rely on `README.md`
|
||||
- Tooling may miss lingering references to the old filename
|
||||
|
||||
## Success Metrics
|
||||
- `openspec init` creates `openspec/AGENTS.md`
|
||||
- `openspec update` refreshes `AGENTS.md`
|
||||
- All specs reference `openspec/AGENTS.md`
|
||||
@@ -0,0 +1,40 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Directory Creation
|
||||
The command SHALL create the complete OpenSpec directory structure with all required directories and files.
|
||||
|
||||
#### Scenario: Creating OpenSpec structure
|
||||
- **WHEN** `openspec init` is executed
|
||||
- **THEN** create the following directory structure:
|
||||
```
|
||||
openspec/
|
||||
├── project.md
|
||||
├── AGENTS.md
|
||||
├── specs/
|
||||
└── changes/
|
||||
└── archive/
|
||||
```
|
||||
|
||||
### Requirement: File Generation
|
||||
The command SHALL generate required template files with appropriate content for immediate use.
|
||||
|
||||
#### Scenario: Generating template files
|
||||
- **WHEN** initializing OpenSpec
|
||||
- **THEN** generate `AGENTS.md` containing complete OpenSpec instructions for AI assistants
|
||||
- **AND** generate `project.md` with project context template
|
||||
|
||||
### Requirement: AI Tool Configuration Details
|
||||
|
||||
The command SHALL properly configure selected AI tools with OpenSpec-specific instructions using a marker system.
|
||||
|
||||
#### Scenario: Creating new CLAUDE.md
|
||||
- **WHEN** CLAUDE.md does not exist
|
||||
- **THEN** create new file with OpenSpec content wrapped in markers including reference to `@openspec/AGENTS.md`
|
||||
|
||||
### Requirement: Success Output
|
||||
|
||||
The command SHALL provide clear, actionable next steps upon successful initialization.
|
||||
|
||||
#### Scenario: Displaying success message
|
||||
- **WHEN** initialization completes successfully
|
||||
- **THEN** include prompt: "Please explain the OpenSpec workflow from openspec/AGENTS.md and how I should work with you on this project"
|
||||
@@ -0,0 +1,22 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Update Behavior
|
||||
The update command SHALL update OpenSpec instruction files to the latest templates in a team-friendly manner.
|
||||
|
||||
#### Scenario: Running update command
|
||||
- **WHEN** a user runs `openspec update`
|
||||
- **THEN** replace `openspec/AGENTS.md` with the latest template
|
||||
|
||||
### Requirement: File Handling
|
||||
The update command SHALL handle file updates in a predictable and safe manner.
|
||||
|
||||
#### Scenario: Updating files
|
||||
- **WHEN** updating files
|
||||
- **THEN** completely replace `openspec/AGENTS.md` with the latest template
|
||||
|
||||
### Requirement: Core Files Always Updated
|
||||
The update command SHALL always update the core OpenSpec files and display an ASCII-safe success message.
|
||||
|
||||
#### Scenario: Successful update
|
||||
- **WHEN** the update completes successfully
|
||||
- **THEN** replace `openspec/AGENTS.md` with the latest template
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user