mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-04 06:18:24 +08:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77cef014cf | ||
|
|
a32bb65d45 | ||
|
|
e6bfd30da3 |
@@ -1,11 +0,0 @@
|
||||
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
||||
# Minimal configuration for getting started
|
||||
language: "en-US"
|
||||
reviews:
|
||||
profile: "chill"
|
||||
high_level_summary: true
|
||||
auto_review:
|
||||
enabled: true
|
||||
drafts: false
|
||||
base_branches:
|
||||
- ".*"
|
||||
@@ -1,92 +0,0 @@
|
||||
# Dev Container Setup
|
||||
|
||||
This directory contains the VS Code dev container configuration for OpenSpec development.
|
||||
|
||||
## What's Included
|
||||
|
||||
- **Node.js 20 LTS** (>=20.19.0) - TypeScript/JavaScript runtime
|
||||
- **pnpm** - Fast, disk space efficient package manager
|
||||
- **Git + GitHub CLI** - Version control tools
|
||||
- **VS Code Extensions**:
|
||||
- ESLint & Prettier for code quality
|
||||
- Vitest Explorer for running tests
|
||||
- GitLens for enhanced git integration
|
||||
- Error Lens for inline error highlighting
|
||||
- Code Spell Checker
|
||||
- Path IntelliSense
|
||||
|
||||
## How to Use
|
||||
|
||||
### First Time Setup
|
||||
|
||||
1. **Install Prerequisites** (on your local machine):
|
||||
- [VS Code](https://code.visualstudio.com/)
|
||||
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
|
||||
- [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
|
||||
|
||||
2. **Open in Container**:
|
||||
- Open this project in VS Code
|
||||
- You'll see a notification: "Folder contains a Dev Container configuration file"
|
||||
- Click "Reopen in Container"
|
||||
|
||||
OR
|
||||
|
||||
- Open Command Palette (`Cmd/Ctrl+Shift+P`)
|
||||
- Type "Dev Containers: Reopen in Container"
|
||||
- Press Enter
|
||||
|
||||
3. **Wait for Setup**:
|
||||
- The container will build (first time takes a few minutes)
|
||||
- `pnpm install` runs automatically via `postCreateCommand`
|
||||
- All extensions install automatically
|
||||
|
||||
### Daily Development
|
||||
|
||||
Once set up, the container preserves your development environment:
|
||||
|
||||
```bash
|
||||
# Run development build
|
||||
pnpm run dev
|
||||
|
||||
# Run CLI in development
|
||||
pnpm run dev:cli
|
||||
|
||||
# Run tests
|
||||
pnpm test
|
||||
|
||||
# Run tests in watch mode
|
||||
pnpm test:watch
|
||||
|
||||
# Build the project
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
### SSH Keys
|
||||
|
||||
Your SSH keys are mounted read-only from `~/.ssh`, so git operations work seamlessly with GitHub/GitLab.
|
||||
|
||||
### Rebuilding the Container
|
||||
|
||||
If you modify `.devcontainer/devcontainer.json`:
|
||||
- Command Palette → "Dev Containers: Rebuild Container"
|
||||
|
||||
## Benefits
|
||||
|
||||
- No need to install Node.js or pnpm on your local machine
|
||||
- Consistent development environment across team members
|
||||
- Isolated from other Node.js projects on your machine
|
||||
- All dependencies and tools containerized
|
||||
- Easy onboarding for new developers
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Container won't build:**
|
||||
- Ensure Docker Desktop is running
|
||||
- Check Docker has enough memory allocated (recommend 4GB+)
|
||||
|
||||
**Extensions not appearing:**
|
||||
- Rebuild the container: "Dev Containers: Rebuild Container"
|
||||
|
||||
**Permission issues:**
|
||||
- The container runs as the `node` user (non-root)
|
||||
- Files created in the container are owned by this user
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"name": "OpenSpec Development",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm",
|
||||
|
||||
// Additional tools and features
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/git:1": {
|
||||
"version": "latest",
|
||||
"ppa": true
|
||||
},
|
||||
"ghcr.io/devcontainers/features/github-cli:1": {
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
|
||||
// Configure tool-specific properties
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
// Set default container specific settings
|
||||
"settings": {
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit"
|
||||
},
|
||||
"files.eol": "\n",
|
||||
"terminal.integrated.defaultProfile.linux": "bash"
|
||||
},
|
||||
|
||||
// Add extensions you want installed when the container is created
|
||||
"extensions": [
|
||||
// TypeScript/JavaScript essentials
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
|
||||
// Testing
|
||||
"vitest.explorer",
|
||||
|
||||
// Git
|
||||
"eamodio.gitlens",
|
||||
|
||||
// Utilities
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"usernamehw.errorlens",
|
||||
"christian-kohler.path-intellisense"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created
|
||||
"postCreateCommand": "corepack enable && corepack prepare pnpm@latest --activate && pnpm install",
|
||||
|
||||
// Configure mounts to preserve SSH keys for git operations
|
||||
"mounts": [
|
||||
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,readonly,type=bind,consistency=cached"
|
||||
],
|
||||
|
||||
// Set the default user to 'node' (non-root user)
|
||||
"remoteUser": "node",
|
||||
|
||||
// Ensure git is properly configured
|
||||
"initializeCommand": "echo 'Initializing dev container...'"
|
||||
}
|
||||
@@ -15,12 +15,10 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test_pr:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -50,68 +48,7 @@ jobs:
|
||||
- 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
|
||||
name: coverage-report
|
||||
path: coverage/
|
||||
retention-days: 7
|
||||
|
||||
@@ -185,15 +122,15 @@ jobs:
|
||||
echo "Changesets not configured, skipping validation"
|
||||
fi
|
||||
|
||||
required-checks-pr:
|
||||
required-checks:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_pr, lint]
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
needs: [test, lint]
|
||||
if: always()
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
if [[ "${{ needs.test_pr.result }}" != "success" ]]; then
|
||||
if [[ "${{ needs.test.result }}" != "success" ]]; then
|
||||
echo "Test job failed"
|
||||
exit 1
|
||||
fi
|
||||
@@ -201,22 +138,4 @@ jobs:
|
||||
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!"
|
||||
echo "All required checks passed!"
|
||||
@@ -8,13 +8,8 @@ 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
|
||||
@@ -29,22 +24,14 @@ jobs:
|
||||
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
|
||||
# Opens/updates the Version Packages PR; no publishing here
|
||||
- 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 }}
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
name: Publish to npm
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: publish-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
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
|
||||
|
||||
- name: Build project
|
||||
run: pnpm run build
|
||||
|
||||
- name: Ensure running from a tag
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != refs/tags/* ]]; then
|
||||
echo "This workflow must run from a tag (got: $GITHUB_REF)";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
- name: Verify release tag matches package.json
|
||||
run: |
|
||||
TAG="${GITHUB_REF_NAME#v}"
|
||||
PKG_VERSION=$(node -p "require('./package.json').version")
|
||||
if [ "$TAG" != "$PKG_VERSION" ]; then
|
||||
echo "Tag v$TAG does not match package.json $PKG_VERSION"; exit 1
|
||||
fi
|
||||
|
||||
- name: Debug npm auth and context
|
||||
run: |
|
||||
test -n "$NODE_AUTH_TOKEN" || (echo "NODE_AUTH_TOKEN is missing" && exit 1)
|
||||
echo "NODE_AUTH_TOKEN present"
|
||||
npm --version
|
||||
pnpm --version
|
||||
node --version
|
||||
npm config get registry
|
||||
npm whoami
|
||||
npm ping
|
||||
|
||||
- run: pnpm test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm publish --access public --provenance --no-git-checks
|
||||
@@ -147,6 +147,3 @@ docs/
|
||||
.claude/
|
||||
CLAUDE.md
|
||||
.DS_Store
|
||||
|
||||
# Pnpm
|
||||
.pnpm-store/
|
||||
|
||||
@@ -1,18 +1,40 @@
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Instructions
|
||||
# OpenSpec Project
|
||||
|
||||
These instructions are for AI assistants working in this 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.
|
||||
|
||||
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.
|
||||
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 -->
|
||||
|
||||
## Complexity Management
|
||||
|
||||
**Default to minimal solutions:**
|
||||
- Propose <100 lines of new code for features
|
||||
- Prefer single-file implementations until proven insufficient
|
||||
- Avoid frameworks, abstractions, and optimizations without clear justification
|
||||
- Choose boring, well-understood patterns over novel approaches
|
||||
|
||||
**Question requests for complexity:**
|
||||
- Caching? → Ask for performance data and targets
|
||||
- New framework? → Suggest plain code first
|
||||
- Extra layers? → Start with the thinnest viable design
|
||||
|
||||
**Justify complexity with data:**
|
||||
- Performance metrics showing current solution is too slow
|
||||
- Concrete scale requirements (e.g., >1000 users, >100MB data)
|
||||
- Multiple proven use cases requiring an abstraction
|
||||
|
||||
## Package Manager
|
||||
Always use pnpm (NOT npm or yarn) for all Node.js package management:
|
||||
- Install dependencies: `pnpm install`
|
||||
- Add packages: `pnpm add [package]`
|
||||
- Run scripts: `pnpm run [script]`
|
||||
|
||||
## Git Commits
|
||||
Use conventional commits with these rules:
|
||||
- Format: `type(scope): subject` (e.g., `fix: resolve auth error`, `feat(api): add user endpoint`)
|
||||
- Keep commit messages to ONE line only - no body or footer
|
||||
- Common types: feat, fix, docs, style, refactor, test, chore
|
||||
- Never add co-authorship lines or attribution
|
||||
-184
@@ -1,189 +1,5 @@
|
||||
# @fission-ai/openspec
|
||||
|
||||
## 0.16.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c08fbc1: Add new AI tool integrations and enhancements:
|
||||
|
||||
- **feat(iflow-cli)**: Add iFlow-cli integration with slash command support and documentation
|
||||
- **feat(init)**: Add IDE restart instruction after init to inform users about slash command availability
|
||||
**feat(antigravity)**: Add Antigravity slash command support
|
||||
- **fix**: Generate TOML commands for Qwen Code (fixes #293)
|
||||
- Clarify scaffold proposal documentation and enhance proposal guidelines
|
||||
- Update proposal guidelines to emphasize design-first approach before implementation
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add Antigravity slash command support so `openspec init` can generate `.agent/workflows/openspec-*.md` files with description-only frontmatter and `openspec update` refreshes existing workflows alongside Windsurf.
|
||||
|
||||
## 0.15.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 4758c5c: Add support for new AI tools with native slash command integration
|
||||
|
||||
- **Gemini CLI**: Add native TOML-based slash command support for Gemini CLI with `.gemini/commands/openspec/` integration
|
||||
- **RooCode**: Add RooCode integration with configurator, slash commands, and templates
|
||||
- **Cline**: Fix Cline to use workflows instead of rules for slash commands (`.clinerules/workflows/` paths)
|
||||
- **Documentation**: Update documentation to reflect new integrations and workflow changes
|
||||
|
||||
## 0.14.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 8386b91: Add support for new AI assistants and configuration improvements
|
||||
|
||||
- feat: add Qwen Code support with slash command integration
|
||||
- feat: add $ARGUMENTS support to apply slash command for dynamic variable passing
|
||||
- feat: add Qoder CLI support to configuration and documentation
|
||||
- feat: add CoStrict AI assistant support
|
||||
- fix: recreate missing openspec template files in extend mode
|
||||
- fix: prevent false 'already configured' detection for tools
|
||||
- fix: use change-id as fallback title instead of "Untitled Change"
|
||||
- docs: add guidance for populating project-level context
|
||||
- docs: add Crush to supported AI tools in README
|
||||
|
||||
## 0.13.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 668a125: Add support for multiple AI assistants and improve validation
|
||||
|
||||
This release adds support for several new AI coding assistants:
|
||||
|
||||
- CodeBuddy Code - AI-powered coding assistant
|
||||
- CodeRabbit - AI code review assistant
|
||||
- Cline - Claude-powered CLI assistant
|
||||
- Crush AI - AI assistant platform
|
||||
- Auggie (Augment CLI) - Code augmentation tool
|
||||
|
||||
New features:
|
||||
|
||||
- Archive slash command now supports arguments for more flexible workflows
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Delta spec validation now handles case-insensitive headers and properly detects empty sections
|
||||
- Archive validation now correctly honors --no-validate flag and ignores metadata
|
||||
|
||||
Documentation improvements:
|
||||
|
||||
- Added VS Code dev container configuration for easier development setup
|
||||
- Updated AGENTS.md with explicit change-id notation
|
||||
- Enhanced slash commands documentation with restart notes
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 082abb4: Add factory function support for slash commands and non-interactive init options
|
||||
|
||||
This release includes two new features:
|
||||
|
||||
- **Factory function support for slash commands**: Slash commands can now be defined as functions that return command objects, enabling dynamic command configuration
|
||||
- **Non-interactive init options**: Added `--tools`, `--all-tools`, and `--skip-tools` CLI flags to `openspec init` for automated initialization in CI/CD pipelines while maintaining backward compatibility with interactive mode
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 312e1d6: Add Amazon Q Developer CLI integration. OpenSpec now supports Amazon Q Developer with automatic prompt generation in `.amazonq/prompts/` directory, allowing you to use OpenSpec slash commands with Amazon Q's @-syntax.
|
||||
|
||||
## 0.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- d7e0ce8: Improve init wizard Enter key behavior to allow proceeding through prompts more naturally
|
||||
|
||||
## 0.9.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2ae0484: Fix cross-platform path handling issues. This release includes fixes for joinPath behavior and slash command path resolution to ensure OpenSpec works correctly across all platforms.
|
||||
|
||||
## 0.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 8210970: Fix OpenSpec not working on Windows when Codex integration is selected. This release includes fixes for cross-platform path handling and normalization to ensure OpenSpec works correctly on Windows systems.
|
||||
|
||||
## 0.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- efbbf3b: Add support for Codex and GitHub Copilot slash commands with YAML frontmatter and $ARGUMENTS
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add GitHub Copilot slash command support. OpenSpec now writes prompts to `.github/prompts/openspec-{proposal,apply,archive}.prompt.md` with YAML frontmatter and `$ARGUMENTS` placeholder, and refreshes them on `openspec update`.
|
||||
|
||||
## 0.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- d070d08: Fix CLI version mismatch and add a release guard that validates the packed tarball prints the same version as package.json via `openspec --version`.
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c29b06d: Add Windsurf support.
|
||||
- Add Codex slash command support. OpenSpec now writes prompts directly to Codex's global directory (`~/.codex/prompts` or `$CODEX_HOME/prompts`) and refreshes them on `openspec update`.
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add native Kilo Code workflow integration so `openspec init` and `openspec update` manage `.kilocode/workflows/openspec-*.md` files.
|
||||
- Always scaffold the managed root `AGENTS.md` hand-off stub and regroup the AI tool prompts during init/update to keep instructions consistent.
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Slim the generated root agent instructions down to a managed hand-off stub and update the init/update flows to refresh it safely.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- feat: implement Phase 1 E2E testing with cross-platform CI matrix
|
||||
|
||||
- Add shared runCLI helper in test/helpers/run-cli.ts for spawn testing
|
||||
- Create test/cli-e2e/basic.test.ts covering help, version, validate flows
|
||||
- Migrate existing CLI exec tests to use runCLI helper
|
||||
- Extend CI matrix to bash (Linux/macOS) and pwsh (Windows)
|
||||
- Split PR and main workflows for optimized feedback
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Make apply instructions more specific
|
||||
|
||||
Improve agent templates and slash command templates with more specific and actionable apply instructions.
|
||||
|
||||
- docs: improve documentation and cleanup
|
||||
|
||||
- Document non-interactive flag for archive command
|
||||
- Replace discord badge in README
|
||||
- Archive completed changes for better organization
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add OpenSpec change proposals for CLI improvements and enhanced user experience
|
||||
- Add Opencode slash commands support for AI-driven development workflows
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Add documentation improvements including --yes flag for archive command template and Discord badge
|
||||
- Fix normalize line endings in markdown parser to handle CRLF files properly
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<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>
|
||||
<a href="https://discord.gg/saTQQGQZ"><img alt="Discord" src="https://img.shields.io/discord/1411657095639601154?logo=discord&logoColor=white&style=flat-square" /></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -23,7 +23,7 @@
|
||||
</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.
|
||||
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/saTQQGQZ">OpenSpec Discord</a> for help and questions.
|
||||
</p>
|
||||
|
||||
# OpenSpec
|
||||
@@ -40,15 +40,6 @@ Key outcomes:
|
||||
- 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
|
||||
|
||||
```
|
||||
@@ -85,48 +76,20 @@ See the full comparison in [How OpenSpec Compares](#how-openspec-compares).
|
||||
|
||||
### Supported AI Tools
|
||||
|
||||
<details>
|
||||
<summary><strong>Native Slash Commands</strong> (click to expand)</summary>
|
||||
|
||||
#### Native Slash Commands
|
||||
These tools have built-in OpenSpec commands. Select the OpenSpec integration when prompted.
|
||||
|
||||
| Tool | Commands |
|
||||
|------|----------|
|
||||
| **Amazon Q Developer** | `@openspec-proposal`, `@openspec-apply`, `@openspec-archive` (`.amazonq/prompts/`) |
|
||||
| **Antigravity** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.agent/workflows/`) |
|
||||
| **Auggie (Augment CLI)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.augment/commands/`) |
|
||||
| **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` |
|
||||
| **Cline** | Workflows in `.clinerules/workflows/` directory (`.clinerules/workflows/openspec-*.md`) |
|
||||
| **CodeBuddy Code (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.codebuddy/commands/`) — see [docs](https://www.codebuddy.ai/cli) |
|
||||
| **Codex** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (global: `~/.codex/prompts`, auto-installed) |
|
||||
| **CoStrict** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.cospec/openspec/commands/`) — see [docs](https://costrict.ai)|
|
||||
| **Crush** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.crush/commands/openspec/`) |
|
||||
| **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
|
||||
| **Factory Droid** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.factory/commands/`) |
|
||||
| **Gemini CLI** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.gemini/commands/openspec/`) |
|
||||
| **GitHub Copilot** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.github/prompts/`) |
|
||||
| **iFlow (iflow-cli)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.iflow/commands/`) |
|
||||
| **Kilo Code** | `/openspec-proposal.md`, `/openspec-apply.md`, `/openspec-archive.md` (`.kilocode/workflows/`) |
|
||||
| **OpenCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
|
||||
| **Qoder (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.qoder/commands/openspec/`) — see [docs](https://qoder.com/cli) |
|
||||
| **Qwen Code** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.qwen/commands/`) |
|
||||
| **RooCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.roo/commands/`) |
|
||||
| **Windsurf** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.windsurf/workflows/`) |
|
||||
|
||||
Kilo Code discovers team workflows automatically. Save the generated files under `.kilocode/workflows/` and trigger them from the command palette with `/openspec-proposal.md`, `/openspec-apply.md`, or `/openspec-archive.md`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>AGENTS.md Compatible</strong> (click to expand)</summary>
|
||||
|
||||
#### 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 • Others |
|
||||
|
||||
</details>
|
||||
| Codex • Amp • Jules • OpenCode • Gemini CLI • GitHub Copilot • Others |
|
||||
|
||||
### Install & Initialize
|
||||
|
||||
@@ -157,26 +120,13 @@ openspec init
|
||||
```
|
||||
|
||||
**What happens during initialization:**
|
||||
- You'll be prompted to pick any natively supported AI tools (Claude Code, CodeBuddy, Cursor, OpenCode, Qoder,etc.); other assistants always rely on the shared `AGENTS.md` stub
|
||||
- OpenSpec automatically configures slash commands for the tools you choose and always writes a managed `AGENTS.md` hand-off at the project root
|
||||
- You'll be prompted to select your AI tool (Claude Code, Cursor, etc.)
|
||||
- OpenSpec automatically configures slash commands or `AGENTS.md` based on your selection
|
||||
- A new `openspec/` directory structure is created in your project
|
||||
|
||||
**After setup:**
|
||||
- Primary AI tools can trigger `/openspec` workflows without additional configuration
|
||||
- Run `openspec list` to verify the setup and view any active changes
|
||||
- If your coding assistant doesn't surface the new slash commands right away, restart it. Slash commands are loaded at startup,
|
||||
so a fresh launch ensures they appear
|
||||
|
||||
### Optional: Populate Project Context
|
||||
|
||||
After `openspec init` completes, you'll receive a suggested prompt to help populate your project context:
|
||||
|
||||
```text
|
||||
Populate your project context:
|
||||
"Please read openspec/project.md and help me fill it out with details about my project, tech stack, and conventions"
|
||||
```
|
||||
|
||||
Use `openspec/project.md` to define project-level conventions, standards, architectural patterns, and other guidelines that should be followed across all changes.
|
||||
|
||||
### Create Your First Change
|
||||
|
||||
@@ -234,16 +184,16 @@ You: Please archive the change
|
||||
(Shortcut for tools with slash commands: /openspec:archive add-profile-filters)
|
||||
|
||||
AI: I'll archive the add-profile-filters change.
|
||||
*Runs: openspec archive add-profile-filters --yes*
|
||||
*Runs: openspec archive add-profile-filters*
|
||||
✓ Change archived successfully. Specs updated. Ready for the next feature!
|
||||
```
|
||||
|
||||
Or run the command yourself in terminal:
|
||||
```bash
|
||||
$ openspec archive add-profile-filters --yes # Archive the completed change without prompts
|
||||
$ openspec archive add-profile-filters # Archive the completed change
|
||||
```
|
||||
|
||||
**Note:** Tools with native slash commands (Claude Code, CodeBuddy, Cursor, Codex, Qoder, RooCode) can use the shortcuts shown. All other tools work with natural language requests to "create an OpenSpec proposal", "apply the OpenSpec change", or "archive the change".
|
||||
**Note:** Tools with native slash commands (Claude Code, Cursor) 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
|
||||
|
||||
@@ -252,7 +202,7 @@ 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)
|
||||
openspec archive <change> # Move a completed change into archive/
|
||||
```
|
||||
|
||||
## Example: How AI Creates OpenSpec Files
|
||||
@@ -341,9 +291,6 @@ Deltas are "patches" that show how specs change:
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -355,7 +302,7 @@ Without specs, AI coding assistants generate code from vague prompts, often miss
|
||||
1. **Initialize OpenSpec** – Run `openspec init` in your repo.
|
||||
2. **Start with new features** – Ask your AI to capture upcoming work as change proposals.
|
||||
3. **Grow incrementally** – Each change archives into living specs that document your system.
|
||||
4. **Stay flexible** – Different teammates can use Claude Code, CodeBuddy, Cursor, or any AGENTS.md-compatible tool while sharing the same specs.
|
||||
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.
|
||||
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { execFileSync } from 'child_process';
|
||||
import { execSync } 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');
|
||||
|
||||
@@ -22,10 +14,10 @@ if (existsSync('dist')) {
|
||||
// Run TypeScript compiler (use local version explicitly)
|
||||
console.log('Compiling TypeScript...');
|
||||
try {
|
||||
runTsc(['--version']);
|
||||
runTsc();
|
||||
execSync('./node_modules/.bin/tsc -v', { stdio: 'inherit' });
|
||||
execSync('./node_modules/.bin/tsc', { stdio: 'inherit' });
|
||||
console.log('\n✅ Build completed successfully!');
|
||||
} catch (error) {
|
||||
console.error('\n❌ Build failed!');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
# OpenSpec Parallel Delta Remediation Plan
|
||||
|
||||
## Problem Summary
|
||||
- Active changes apply requirement-level replacements when archiving. When two changes touch the same requirement, the second archive overwrites the first and silently drops scenarios (e.g., Windsurf vs. Kilo Code slash command updates).
|
||||
- The archive workflow (`src/core/archive.ts:191` and `src/core/archive.ts:501`) rebuilds main specs by replacing entire requirement blocks with the content contained in the change delta. The delta format (`src/core/parsers/requirement-blocks.ts:113`) has no notion of base versions or scenario-level operations.
|
||||
- The tooling cannot detect divergence between the change author’s starting point and the live spec, so parallel development corrupts the source of truth without warning.
|
||||
|
||||
## Observed Failure Mode
|
||||
- Change A (`add-windsurf-workflows`) adds a Windsurf scenario under `Slash Command Configuration`.
|
||||
- Change B (`add-kilocode-workflows`) adds a Kilo Code scenario to the same requirement, starting from the pre-Windsurf spec.
|
||||
- After Change A archives, the main spec contains both scenarios.
|
||||
- When Change B archives, `buildUpdatedSpec` sees a `MODIFIED` block for `Slash Command Configuration` and replaces the requirement with the four-scenario variant shipped in that change. Because that file never learned about Windsurf, the Windsurf scenario disappears.
|
||||
- There is no warning, diff, or conflict indicator—the archive completes successfully, and the source-of-truth spec now omits a shipped scenario.
|
||||
|
||||
## Root Causes
|
||||
1. **Replace-only semantics.** `buildUpdatedSpec` performs hash-map substitution of requirement blocks and cannot merge or compare individual scenarios (`src/core/archive.ts:455`-`src/core/archive.ts:526`).
|
||||
2. **Missing base fingerprint.** Changes do not persist the requirement content they were authored against, so the archive step cannot tell if the live spec diverged.
|
||||
3. **Single-level granularity.** The delta language only understands requirements. Even if we introduced scenario-level parsing, we would still lose sibling edits without an accompanying merge strategy.
|
||||
4. **Lack of conflict UX.** The CLI never forces contributors to reconcile parallel updates. There is no equivalent of `git merge`, `git rebase`, or conflict markers.
|
||||
|
||||
## Design Objectives
|
||||
- Preserve every approved scenario regardless of archive order.
|
||||
- Detect and block speculative archives when the live spec diverges from the author’s base.
|
||||
- Provide a deterministic, reviewable conflict resolution flow that mirrors source-control best practices.
|
||||
- Keep the authoring experience ergonomic: deltas should remain human-editable markdown.
|
||||
- Support incremental adoption so existing repositories can roll forward without breaking active work.
|
||||
|
||||
## Proposed Fix: Layered Remediation
|
||||
|
||||
### Phase 0 – Stop the Bleeding (Detection & Guardrails)
|
||||
1. **Persist requirement fingerprints alongside each change.**
|
||||
- When scaffolding or validating a change, capture the current requirement body for every `MODIFIED`/`REMOVED`/`RENAMED` entry and write it to `changes/<id>/meta.json`.
|
||||
- Store a stable hash (e.g., SHA-256) of the base requirement content and the raw text itself for later merges.
|
||||
2. **Validate fingerprints during archive.**
|
||||
- Before `buildUpdatedSpec` mutates specs, recompute the requirement hash from the live spec.
|
||||
- If the hash differs from the stored base, abort and instruct the user to rebase. This makes the destructive path impossible.
|
||||
3. **Surface intent in CLI output.**
|
||||
- Show which requirements are stale, when they diverged, and which change last touched them.
|
||||
4. **Document interim manual mitigation.**
|
||||
- Update `openspec/AGENTS.md` and docs so contributors know to rerun `openspec change sync` (see Phase 1) whenever another change lands.
|
||||
|
||||
_Outcome:_ We prevent data loss immediately while we work on a richer merge story.
|
||||
|
||||
### Phase 1 – Add a Rebase Workflow (Author-Side Merge)
|
||||
1. **Introduce `openspec change sync <id>` (or `rebase`).**
|
||||
- Reads the stored base snapshot, the current spec, and the author’s delta.
|
||||
- Performs a 3-way merge per requirement. A naive diff3 on markdown lines is acceptable initially because we already operate on requirement-sized chunks.
|
||||
- If the merge is clean, rewrite the `MODIFIED` block with the merged text and refresh the stored fingerprint.
|
||||
- On conflict, write conflict markers inside the change delta (similar to Git) and require the author to hand-edit before re-running validation.
|
||||
2. **Enrich validator messages.**
|
||||
- `openspec validate` should flag unresolved conflict markers or fingerprint mismatches so errors appear early in the workflow.
|
||||
3. **Optional:** Offer a `--rewrite-scenarios` helper that merges bullet lists of scenarios to reduce manual editing noise.
|
||||
|
||||
_Outcome:_ Contributors can safely reconcile their work with the latest spec before archiving, restoring true parallel development.
|
||||
|
||||
### Phase 2 – Increase Delta Granularity
|
||||
1. **Extend the delta language with scenario-level directives.**
|
||||
- Allow `## MODIFIED Requirements` + `## ADDED Scenarios` / `## MODIFIED Scenarios` sections nested under the requirement header.
|
||||
- Backed by stable scenario identifiers (explicit IDs or generated hashes) stored in `meta.json`. This lets the system reason about individual scenarios.
|
||||
2. **Teach the parser to understand nested operations.**
|
||||
- Update `parseDeltaSpec` to emit scenario-level operations in addition to requirement blocks.
|
||||
- Update `buildUpdatedSpec` (or its replacement) to merge scenario lists, preserving order while inserting new entries in a deterministic fashion.
|
||||
3. **Automate migration.**
|
||||
- Provide a one-time command that inspects each existing spec, injects scenario IDs, and rewrites in-flight change deltas into the richer format.
|
||||
4. **Continue to rely on the Phase 1 rebase flow for conflicts when two changes edit the same scenario body or description.**
|
||||
|
||||
_Outcome:_ Most concurrent updates become commutative, drastically reducing the odds of human merges.
|
||||
|
||||
### Phase 3 – Structured Spec Graph (Long-Term)
|
||||
1. **Define stable requirement IDs.**
|
||||
- Embed `Requirement ID: <uuid>` markers in specs so renames and moves are trackable.
|
||||
- This enables future features like cross-capability references and better diff visualizations.
|
||||
2. **Model spec edits as operations over an AST.**
|
||||
- Build an intermediate representation (IR) for requirements/scenarios/metadata.
|
||||
- Use operational transforms or CRDT-like techniques to guarantee merge associativity.
|
||||
3. **Integrate with Git directly.**
|
||||
- Offer optional `openspec branch` scaffolding that aligns spec changes with Git branches, letting teams leverage Git’s conflict editor for the markdown IR.
|
||||
|
||||
_Outcome:_ OpenSpec graduates from replace-based updates to a resilient, intent-preserving spec management platform.
|
||||
|
||||
## Migration & Product Impacts
|
||||
- **Backfill metadata:** add hashes for all active changes and the current main specs during the initial rollout.
|
||||
- **CLI UX:** new commands (`change sync`, enhanced `archive`) require documentation, help text, and release notes.
|
||||
- **Docs & AGENTS updates:** reinforce the rebase workflow and explain conflict resolution to AI assistants.
|
||||
- **Testing:** introduce fixtures covering divergent requirement fingerprints and merge resolution logic.
|
||||
- **Telemetry (optional):** log fingerprint mismatches so we can see how often teams hit conflicts after the rollout.
|
||||
|
||||
## Open Questions / Risks
|
||||
- How should we order scenarios when multiple changes insert at different points? (Consider optional `position` metadata or deterministic alphabetical fallbacks.)
|
||||
- What is the graceful failure mode if contributors delete the `meta.json` file? (CLI should recreate fingerprints on demand.)
|
||||
- Do we need to support offline authors who cannot easily re-run the sync command before archiving? (Potential `--accept-outdated` escape hatch for emergencies.)
|
||||
- How will archived historical changes be handled? We may need a migration script to embed fingerprints retroactively so re-validation succeeds.
|
||||
|
||||
## Immediate Next Steps
|
||||
1. Prototype fingerprint capture during `openspec change validate` and block archive on mismatches.
|
||||
2. Ship `openspec change sync` with line-based diff3 merging and conflict markers.
|
||||
3. Update contributor docs and AI instructions to mandate running `sync` before archiving.
|
||||
4. Plan the scenario-level delta extension and migration path as a follow-up RFC.
|
||||
+7
-8
@@ -47,20 +47,18 @@ Skip proposal for:
|
||||
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
|
||||
5. **Mark complete immediately** - Update `- [x]` after each task
|
||||
6. **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-id> --skip-specs --yes` for tooling-only changes (always pass the change ID explicitly)
|
||||
- Use `openspec archive [change] --skip-specs` for tooling-only changes
|
||||
- Run `openspec validate --strict` to confirm the archived change passes checks
|
||||
|
||||
## Before Any Task
|
||||
@@ -95,8 +93,9 @@ After deployment, create separate PR to:
|
||||
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-id> [--yes|-y] # Archive after deployment (add --yes for non-interactive runs)
|
||||
openspec archive [change] # Archive after deployment
|
||||
|
||||
# Project management
|
||||
openspec init [path] # Initialize OpenSpec
|
||||
@@ -118,7 +117,6 @@ openspec validate [change] --strict
|
||||
- `--strict` - Comprehensive validation
|
||||
- `--no-interactive` - Disable prompts
|
||||
- `--skip-specs` - Archive without spec updates
|
||||
- `--yes`/`-y` - Skip confirmation prompts (non-interactive archive)
|
||||
|
||||
## Directory Structure
|
||||
|
||||
@@ -447,8 +445,9 @@ Only add complexity with:
|
||||
```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-id> [--yes|-y] # Mark complete (add --yes for automation)
|
||||
openspec archive [change] # Mark complete
|
||||
```
|
||||
|
||||
Remember: Specs are truth. Changes are proposals. Keep them in sync.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
## Why
|
||||
Google is rolling out Antigravity, a Windsurf-derived IDE that discovers workflows from `.agent/workflows/*.md`. Today OpenSpec can only scaffold slash commands for Windsurf directories, so Antigravity users cannot run the proposal/apply/archive flows from the IDE.
|
||||
|
||||
## What Changes
|
||||
- Add Antigravity as a selectable native tool in `openspec init` so it creates `.agent/workflows/openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md` with YAML frontmatter containing only a `description` field plus the standard OpenSpec-managed body.
|
||||
- Ensure `openspec update` refreshes the body of any existing Antigravity workflows inside `.agent/workflows/` without creating missing files, mirroring the Windsurf behavior.
|
||||
- Share e2e/template coverage confirming the generator writes the proper directory, filename casing, and frontmatter format so Antigravity picks up the workflows.
|
||||
|
||||
## Impact
|
||||
- Affected specs: `specs/cli-init`, `specs/cli-update`
|
||||
- Expected code: CLI init/update tool registries, slash-command templates, associated tests
|
||||
@@ -1,9 +0,0 @@
|
||||
## 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 Antigravity
|
||||
- **WHEN** the user selects Antigravity during initialization
|
||||
- **THEN** create `.agent/workflows/openspec-proposal.md`, `.agent/workflows/openspec-apply.md`, and `.agent/workflows/openspec-archive.md`
|
||||
- **AND** ensure each file begins with YAML frontmatter that contains only a `description: <stage summary>` field followed by the shared OpenSpec workflow instructions wrapped in managed markers
|
||||
- **AND** populate the workflow body with the same proposal/apply/archive guidance used for other tools so Antigravity behaves like Windsurf while pointing to the `.agent/workflows/` directory
|
||||
@@ -1,8 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Slash Command Updates
|
||||
The update command SHALL refresh existing slash command files for configured tools without creating new ones, and ensure the OpenCode archive command accepts change ID arguments.
|
||||
|
||||
#### Scenario: Updating slash commands for Antigravity
|
||||
- **WHEN** `.agent/workflows/` contains `openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`
|
||||
- **THEN** refresh the OpenSpec-managed portion of each file so the workflow copy matches other tools while preserving the existing single-field `description` frontmatter
|
||||
- **AND** skip creating any missing workflow files during update, mirroring the behavior for Windsurf and other IDEs
|
||||
@@ -1,12 +0,0 @@
|
||||
## 1. CLI init support
|
||||
- [x] 1.1 Surface Antigravity in the native-tool picker (interactive + `--tools`) so it toggles alongside other IDEs.
|
||||
- [x] 1.2 Generate `.agent/workflows/openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md` with YAML frontmatter restricted to a single `description` field for each stage and wrap the body in OpenSpec markers.
|
||||
- [x] 1.3 Confirm workspace scaffolding covers missing directory creation and re-run scenarios so repeated init refreshes the managed block.
|
||||
|
||||
## 2. CLI update support
|
||||
- [x] 2.1 Detect existing Antigravity workflow files during `openspec update` and refresh only the managed body, skipping creation when files are missing.
|
||||
- [x] 2.2 Ensure update logic preserves the `description` frontmatter block exactly as written by init, including case and spacing, and refreshes body templates alongside other tools.
|
||||
|
||||
## 3. Templates and tests
|
||||
- [x] 3.1 Add shared template entries for Antigravity that reuse the Windsurf copy but target `.agent/workflows` plus the description-only frontmatter requirement.
|
||||
- [x] 3.2 Expand automated coverage (unit or integration) verifying init and update produce the expected file paths and frontmatter + body markers for Antigravity.
|
||||
@@ -1,39 +0,0 @@
|
||||
## Why
|
||||
|
||||
Users need a way to view and modify their global OpenSpec settings without manually editing JSON files. The `add-global-config-dir` change provides the foundation, but there's no user-facing interface to interact with the config. A dedicated `openspec config` command provides discoverability and ease of use.
|
||||
|
||||
## What Changes
|
||||
|
||||
Add `openspec config` subcommand with the following operations:
|
||||
|
||||
```bash
|
||||
openspec config path # Show config file location
|
||||
openspec config list # Show all current settings
|
||||
openspec config get <key> # Get a specific value
|
||||
openspec config set <key> <value> # Set a value
|
||||
openspec config reset [key] # Reset to defaults (all or specific key)
|
||||
```
|
||||
|
||||
**Example usage:**
|
||||
```bash
|
||||
$ openspec config path
|
||||
/Users/me/.config/openspec/config.json
|
||||
|
||||
$ openspec config list
|
||||
enableTelemetry: true
|
||||
featureFlags: {}
|
||||
|
||||
$ openspec config set enableTelemetry false
|
||||
Set enableTelemetry = false
|
||||
|
||||
$ openspec config get enableTelemetry
|
||||
false
|
||||
```
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: New `cli-config` capability
|
||||
- Affected code:
|
||||
- New `src/commands/config.ts`
|
||||
- Update CLI entry point to register config command
|
||||
- Dependencies: Requires `add-global-config-dir` to be implemented first
|
||||
@@ -1,11 +0,0 @@
|
||||
## 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 (if it does not already exist) 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, including reminders on when to create spec deltas.
|
||||
- Add automated coverage (unit/integ tests) to ensure the command respects naming rules, copies templates correctly, fails for existing directories, and produces output that passes `openspec validate --strict` untouched.
|
||||
|
||||
## Impact
|
||||
- Affected specs: `specs/cli-scaffold`
|
||||
- Affected code: `src/cli/index.ts`, `src/commands`, `docs/`
|
||||
@@ -1,36 +0,0 @@
|
||||
## 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 (if it does not already exist) with proposal, tasks, optional design, and `specs/` 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/` if it does not exist
|
||||
- **AND** copy the default template bundle (proposal, tasks, design placeholders) into that directory in a single operation
|
||||
- **AND** create an empty `openspec/changes/add-user-notifications/specs/` directory ready for capability-specific deltas that will be authored later
|
||||
|
||||
### 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
|
||||
- **AND** include a short reminder inside `specs/README.md` (or similar) instructing authors to add deltas once they know the affected capability
|
||||
|
||||
### 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
|
||||
@@ -1,12 +0,0 @@
|
||||
## 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 copies the default change template bundle (`proposal.md`, `tasks.md`, optional `design.md`, `specs/README.md`) into `openspec/changes/<id>/`, creating the directory tree in a single pass.
|
||||
- [ ] 1.3 Detect when `openspec/changes/<id>/` already exists and exit with a clear error instead of overwriting user files.
|
||||
|
||||
## 2. Templates and documentation
|
||||
- [ ] 2.1 Update `openspec/AGENTS.md` quick reference so agents see `openspec scaffold` before drafting files manually.
|
||||
- [ ] 2.2 Refresh CLI docs/README/help text to mention the scaffold workflow, template bundle contents, and when to add spec deltas manually.
|
||||
|
||||
## 3. Test coverage
|
||||
- [ ] 3.1 Add unit tests covering name validation, template copying, and existing-directory failures.
|
||||
- [ ] 3.2 Add integration coverage ensuring a freshly scaffolded change (without deltas) passes `openspec validate --strict` until the author customizes it.
|
||||
-6
@@ -13,9 +13,3 @@ The init command SHALL generate slash command files for supported editors using
|
||||
- **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
|
||||
-5
@@ -12,11 +12,6 @@ The update command SHALL refresh existing slash command files for configured too
|
||||
- **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
|
||||
-4
@@ -14,7 +14,3 @@
|
||||
|
||||
## 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`.
|
||||
@@ -1,19 +0,0 @@
|
||||
## 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.
|
||||
@@ -1,9 +0,0 @@
|
||||
## 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.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
## 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)
|
||||
@@ -1,11 +0,0 @@
|
||||
## 1. Guard the regression
|
||||
- [x] 1.1 Add a unit test that feeds a CRLF change document into `MarkdownParser.parseChange` and asserts `Why`/`What Changes` are detected.
|
||||
- [x] 1.2 Add a CLI spawn/e2e test that writes a CRLF change, runs `openspec validate`, and expects success.
|
||||
|
||||
## 2. Normalize parsing
|
||||
- [x] 2.1 Normalize line endings when constructing `MarkdownParser` so headers and content comparisons ignore `\r`.
|
||||
- [x] 2.2 Ensure all CLI entry points (validate, view, spec conversion) reuse the normalized parser path.
|
||||
|
||||
## 3. Document and verify
|
||||
- [x] 3.1 Update the `cli-validate` spec with a scenario covering CRLF line endings.
|
||||
- [x] 3.2 Run the parser and CLI test suites (`pnpm test`, relevant spawn tests) to confirm the fix.
|
||||
@@ -1,25 +0,0 @@
|
||||
## Why
|
||||
- Codex (the VS Code extension formerly known as Codeium Chat) exposes "slash commands" by reading Markdown prompt files from `~/.codex/prompts/`. Each file name becomes the `/command` users can run, with YAML frontmatter for metadata (`description`, `argument-hint`) and `$ARGUMENTS` to capture user input. The workflow screenshot shared by Kevin Kern ("Codex problem analyzer") shows the format OpenSpec should target so teams can invoke curated workflows straight from the chat palette.
|
||||
- Teams already rely on OpenSpec to manage the slash-command surface area for Claude, Cursor, OpenCode, Kilo Code, and Windsurf. Leaving Codex out forces them to manually copy/paste OpenSpec guardrails into `~/.codex/prompts/*.md`, which drifts quickly and undermines the "single source of truth" promise of the CLI.
|
||||
- Codex commands live outside the repository (under the user's home directory), so shipping an automated configurator that both scaffolds the prompts and keeps them refreshed via `openspec update` eliminates error-prone manual steps and keeps OpenSpec instructions synchronized across assistants.
|
||||
|
||||
## What Changes
|
||||
- Add Codex to the `openspec init` tool picker with the same "already configured" detection we use for other editors, wiring an implementation that writes managed Markdown prompts directly to Codex's global directory (`~/.codex/prompts` or `$CODEX_HOME/prompts`) with OpenSpec marker blocks.
|
||||
- Produce three Codex prompt files—`openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md`—whose content mirrors the shared slash-command templates while using YAML frontmatter (`description` and `argument-hint` fields) and `$ARGUMENTS` to capture all arguments as a single string (matching the GitHub Copilot pattern and official Codex specification).
|
||||
- Document Codex's global-only discovery and that OpenSpec writes prompts directly to `~/.codex/prompts` (or `$CODEX_HOME/prompts`).
|
||||
- Teach `openspec update` to refresh existing Codex prompts in-place (and only when they already exist) in the global directory, updating both frontmatter and body.
|
||||
- Document Codex support alongside other slash-command integrations and add regression coverage that exercises init/update behaviour against a temporary global prompts directory via `CODEX_HOME`.
|
||||
|
||||
## Impact
|
||||
- Specs: `cli-init`, `cli-update`
|
||||
- Code: `src/core/config.ts`, `src/core/configurators/slash/*`, `src/core/templates/slash-command-templates.ts`, CLI tool summaries, docs
|
||||
- Tests: integration coverage for Codex prompt scaffolding and refresh logic
|
||||
- Docs: README and CHANGELOG entries announcing Codex slash-command support
|
||||
|
||||
## Current Spec Reference
|
||||
- `specs/cli-init/spec.md`
|
||||
- Requirements cover init UX, directory scaffolding, AI tool configuration, and the existing slash-command support for Claude Code, Cursor, and OpenCode.
|
||||
- Our `## MODIFIED` delta in `changes/.../specs/cli-init/spec.md` copies the full "Slash Command Configuration" requirement (header, description, and all scenarios) before appending the new Codex scenario so archiving will retain every prior scenario.
|
||||
- `specs/cli-update/spec.md`
|
||||
- Requirements define update preconditions, template refresh behavior, and slash-command refresh logic for Claude Code, Cursor, and OpenCode.
|
||||
- The corresponding delta preserves the entire "Slash Command Updates" requirement while adding the Codex refresh scenario, ensuring the archive workflow replaces the block without losing the existing scenarios or the "Missing slash command file" guardrail.
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: AI Tool Configuration
|
||||
The command SHALL configure AI coding assistants with OpenSpec instructions using a marker system.
|
||||
#### 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)
|
||||
- OpenCode (creates or refreshes `.opencode/command/openspec-*.md` slash commands)
|
||||
- Windsurf (creates or refreshes `.windsurf/workflows/openspec-*.md` workflows)
|
||||
- Kilo Code (creates or refreshes `.kilocode/workflows/openspec-*.md` workflows)
|
||||
- Codex (creates or refreshes global prompts at `~/.codex/prompts/openspec-*.md`)
|
||||
- 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: 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/command/openspec-proposal.md`, `.opencode/command/openspec-apply.md`, and `.opencode/command/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
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
## 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 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: Missing slash command file
|
||||
- **WHEN** a tool lacks a slash command file
|
||||
- **THEN** do not create a new file during update
|
||||
@@ -1,19 +0,0 @@
|
||||
## 1. CLI integration
|
||||
- [x] 1.1 Add Codex to the init tool picker with display text that clarifies prompts live in the global `.codex/prompts/` directory and implement "already configured" detection by checking for managed Codex prompt files.
|
||||
- [x] 1.2 Implement a `CodexSlashCommandConfigurator` that writes `.codex/prompts/openspec-{proposal,apply,archive}.md`, ensuring the prompt directory exists and wrapping content in OpenSpec markers.
|
||||
// (No helper command required)
|
||||
- [x] 1.3 Register the configurator with the slash-command registry and include Codex in init/update wiring so both commands invoke the new configurator when appropriate.
|
||||
|
||||
## 2. Prompt templates
|
||||
- [x] 2.1 Extend the shared slash-command templates (or add a Codex-specific wrapper) to inject numbered placeholders (`$1`, `$2`, …) where Codex expects user-supplied arguments.
|
||||
- [x] 2.2 Verify generated Markdown stays within Codex's formatting expectations (no front matter, heading-first layout) and matches the problem-analyzer style shown in the reference screenshot.
|
||||
|
||||
## 3. Update support & tests
|
||||
- [x] 3.1 Update the `openspec update` flow to refresh existing Codex prompts without creating new ones when files are missing.
|
||||
- [x] 3.2 Add integration coverage that exercises init/update against a temporary global Codex prompts directory by setting `CODEX_HOME`, asserting marker preservation and idempotent updates.
|
||||
- [x] 3.3 Document Codex's global-only discovery and automatic installation in README and CHANGELOG.
|
||||
- [x] 3.3 Confirm error handling surfaces clear paths when the CLI cannot write to the Codex prompt directory (permissions, missing home directory, etc.).
|
||||
|
||||
## 4. Documentation
|
||||
- [x] 4.1 Document Codex slash-command support in the README and changelog alongside other assistant integrations.
|
||||
- [x] 4.2 Add a release note snippet that points Codex users to the generated `/openspec-proposal`, `/openspec-apply`, and `/openspec-archive` commands.
|
||||
@@ -1,25 +0,0 @@
|
||||
## Why
|
||||
- GitHub Copilot supports custom slash commands through markdown files in `.github/prompts/<name>.prompt.md`. Each file includes YAML frontmatter with a `description` label and uses `$ARGUMENTS` to capture user input. This format allows teams to expose curated workflows directly in Copilot's chat interface.
|
||||
- Teams already rely on OpenSpec to manage slash-command configurations for Claude Code, Cursor, OpenCode, Codex, Kilo Code, and Windsurf. Excluding GitHub Copilot forces developers to manually maintain OpenSpec prompts in `.github/prompts/`, which leads to drift and undermines OpenSpec's "single source of truth" promise.
|
||||
- GitHub Copilot discovers prompts from the repository's `.github/prompts/` directory, making it straightforward to version control and share across the team. Adding automated generation and refresh through `openspec init` and `openspec update` eliminates manual synchronization and keeps OpenSpec instructions consistent across all AI assistants.
|
||||
|
||||
## What Changes
|
||||
- Add GitHub Copilot to the `openspec init` tool picker with "already configured" detection similar to other editors, wiring an implementation that writes managed Markdown prompt files to `.github/prompts/` with OpenSpec marker blocks.
|
||||
- Generate three GitHub Copilot prompt files—`openspec-proposal.prompt.md`, `openspec-apply.prompt.md`, and `openspec-archive.prompt.md`—whose content mirrors shared slash-command templates while conforming to Copilot's frontmatter and `$ARGUMENTS` placeholder convention.
|
||||
- Document GitHub Copilot's repository-based discovery and that OpenSpec writes prompts to `.github/prompts/` with managed blocks.
|
||||
- Teach `openspec update` to refresh existing GitHub Copilot prompts in-place (only when they already exist) in the repository's `.github/prompts/` directory.
|
||||
- Document GitHub Copilot support alongside other slash-command integrations and add test coverage that exercises init/update behavior for `.github/prompts/` files.
|
||||
|
||||
## Impact
|
||||
- Specs: `cli-init`, `cli-update`
|
||||
- Code: `src/core/configurators/slash/github-copilot.ts` (new), `src/core/configurators/slash/registry.ts`, `src/core/templates/slash-command-templates.ts`, CLI tool summaries, docs
|
||||
- Tests: integration coverage for GitHub Copilot prompt scaffolding and refresh logic
|
||||
- Docs: README and CHANGELOG entries announcing GitHub Copilot slash-command support
|
||||
|
||||
## Current Spec Reference
|
||||
- `specs/cli-init/spec.md`
|
||||
- Requirements cover init UX, directory scaffolding, AI tool configuration, and existing slash-command support for Claude Code, Cursor, OpenCode, Codex, Kilo Code, and Windsurf.
|
||||
- Our `## MODIFIED` delta in `changes/.../specs/cli-init/spec.md` will copy the full "Slash Command Configuration" requirement (header, description, and all scenarios) before appending the new GitHub Copilot scenario so archiving retains every prior scenario.
|
||||
- `specs/cli-update/spec.md`
|
||||
- Requirements define update preconditions, template refresh behavior, and slash-command refresh logic for existing tools.
|
||||
- The corresponding delta preserves the entire "Slash Command Updates" requirement while adding the GitHub Copilot refresh scenario, ensuring the archive workflow replaces the block without losing existing scenarios or the "Missing slash command file" guardrail.
|
||||
@@ -1,48 +0,0 @@
|
||||
## 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 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
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
## 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 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
|
||||
@@ -1,30 +0,0 @@
|
||||
## Implementation Tasks
|
||||
|
||||
- [x] Create `src/core/configurators/slash/github-copilot.ts` implementing `SlashCommandConfigurator` base class
|
||||
- Implement `getRelativePath()` to return `.github/prompts/openspec-{proposal,apply,archive}.prompt.md`
|
||||
- Implement `getFrontmatter()` to generate YAML frontmatter with `description` field and include `$ARGUMENTS` placeholder
|
||||
- Implement `generateAll()` to create `.github/prompts/` directory and write three prompt files with frontmatter, markers, and shared template bodies
|
||||
- Implement `updateExisting()` to refresh only the managed block between markers while preserving frontmatter
|
||||
- Set `toolId = "github-copilot"` and `isAvailable = true`
|
||||
|
||||
- [x] Register GitHub Copilot configurator in `src/core/configurators/slash/registry.ts`
|
||||
- Import `GitHubCopilotSlashCommandConfigurator`
|
||||
- Add to `SLASH_COMMAND_CONFIGURATORS` array
|
||||
- Update tool picker display name to "GitHub Copilot"
|
||||
|
||||
- [x] Update `src/core/init.ts` to include GitHub Copilot in the AI tool selection prompt
|
||||
- Add GitHub Copilot to the available tools list with detection for existing `.github/prompts/openspec-*.prompt.md` files
|
||||
- Display "(already configured)" when prompt files exist
|
||||
|
||||
- [x] Update `src/core/update.ts` to refresh GitHub Copilot prompts when they exist
|
||||
- Call `updateExisting()` for GitHub Copilot configurator when `.github/prompts/` contains OpenSpec prompt files
|
||||
|
||||
- [x] Add integration tests for GitHub Copilot slash command generation
|
||||
- Test `generateAll()` creates three prompt files with correct structure (frontmatter + markers + body)
|
||||
- Test `updateExisting()` preserves frontmatter and only updates managed blocks
|
||||
- Test that missing prompt files are not created during update
|
||||
|
||||
- [x] Update documentation
|
||||
- Add GitHub Copilot to README slash-command support table
|
||||
- Document `.github/prompts/` as the discovery location
|
||||
- Add CHANGELOG entry for GitHub Copilot support
|
||||
@@ -1,17 +0,0 @@
|
||||
## Why
|
||||
- Kilo Code executes \"slash commands\" by loading markdown workflows from `.kilocode/workflows/` (or the global `~/.kilocode/workflows/`) and running them when a user types `/workflow-name.md`, making project-local workflow files the analogue to the slash-command files we already ship for other tools.\\
|
||||
([Workflows | Kilo Code Docs](https://kilocode.ai/docs/features/slash-commands/workflows))
|
||||
- Those workflows are plain markdown with step-by-step instructions that can call built-in tools and MCP integrations, so reusing OpenSpec's shared proposal/apply/archive bodies keeps behaviour aligned across assistants without inventing new content.
|
||||
- OpenSpec already detects configured tools and refreshes marker-wrapped files during `init`/`update`; extending the same mechanism to `.kilocode/workflows/openspec-*.md` ensures Kilo Code stays in sync with one source of truth.
|
||||
|
||||
## What Changes
|
||||
- Add Kilo Code to the `openspec init` tool picker with \"already configured\" detection, including wiring for extend mode so teams can refresh Kilo Code assets.
|
||||
- Implement a `KiloCodeSlashCommandConfigurator` that creates `.kilocode/workflows/openspec-{proposal,apply,archive}.md`, ensuring the workflow directory exists and wrapping shared content in OpenSpec markers (no front matter required).
|
||||
- Teach `openspec update` to refresh existing Kilo Code workflows (and only those that already exist) using the shared slash-command templates.
|
||||
- Update documentation, release notes, and integration tests so the new workflow support is covered alongside Claude, Cursor, OpenCode, and Windsurf.
|
||||
|
||||
## Impact
|
||||
- Specs: `cli-init`, `cli-update`
|
||||
- Code: `src/core/config.ts`, `src/core/configurators/(registry|slash/*)`, `src/core/templates/slash-command-templates.ts`, CLI wiring for tool summaries
|
||||
- Tests: init/update workflow coverage, regression for marker preservation in `.kilocode/workflows/`
|
||||
- Docs: README / CHANGELOG updates advertising Kilo Code workflow support
|
||||
@@ -1,43 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: AI Tool Configuration
|
||||
The command SHALL configure AI coding assistants with OpenSpec instructions using a marker system.
|
||||
#### 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)
|
||||
- OpenCode (creates or refreshes `.opencode/command/openspec-*.md` slash commands)
|
||||
- Windsurf (creates or refreshes `.windsurf/workflows/openspec-*.md` workflows)
|
||||
- Kilo Code (creates or refreshes `.kilocode/workflows/openspec-*.md` workflows)
|
||||
- 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: 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
|
||||
|
||||
#### 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
|
||||
@@ -1,27 +0,0 @@
|
||||
## 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 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 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
|
||||
|
||||
#### Scenario: Missing slash command file
|
||||
- **WHEN** a tool lacks a slash command file
|
||||
- **THEN** do not create a new file during update
|
||||
@@ -1,15 +0,0 @@
|
||||
## 1. CLI wiring
|
||||
- [x] 1.1 Add Kilo Code to the selectable AI tools in `openspec init`, including "already configured" detection and success summaries.
|
||||
- [x] 1.2 Register a `KiloCodeSlashCommandConfigurator` alongside other slash-command tools.
|
||||
|
||||
## 2. Workflow generation
|
||||
- [x] 2.1 Implement the configurator so it creates `.kilocode/workflows/` (if needed) and writes `openspec-{proposal,apply,archive}.md` with OpenSpec markers.
|
||||
- [x] 2.2 Reuse the shared slash-command bodies without front matter; verify resulting files stay Markdown-only with no extra metadata.
|
||||
|
||||
## 3. Update support
|
||||
- [x] 3.1 Ensure `openspec update` refreshes existing Kilo Code workflows while skipping ones that are absent.
|
||||
- [x] 3.2 Add regression coverage confirming marker content is replaced (not duplicated) during updates.
|
||||
|
||||
## 4. Documentation
|
||||
- [x] 4.1 Update README / docs to note Kilo Code workflow support and path (`.kilocode/workflows/`).
|
||||
- [x] 4.2 Mention the integration in CHANGELOG or release notes if applicable.
|
||||
@@ -1,12 +0,0 @@
|
||||
## Why
|
||||
The current `openspec init` command requires interactive prompts, preventing automation in CI/CD pipelines and scripted setups. Adding non-interactive options will enable programmatic initialization for automated workflows while maintaining the existing interactive experience as the default.
|
||||
|
||||
## What Changes
|
||||
- Replace the multiple flag design with a single `--tools` option that accepts `all`, `none`, or a comma-separated list of tool IDs
|
||||
- Update InitCommand to bypass interactive prompts when `--tools` is supplied and apply single-flag validation rules
|
||||
- Document the non-interactive behavior via the CLI init spec delta (scenarios for `all`, `none`, list parsing, and invalid entries)
|
||||
- Generate CLI help text dynamically from `AI_TOOLS` so supported tools stay in sync
|
||||
|
||||
## Impact
|
||||
- Affected specs: `specs/cli-init/spec.md`
|
||||
- Affected code: `src/cli/index.ts`, `src/core/init.ts`
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
# Delta for CLI Init Specification
|
||||
|
||||
## ADDED Requirements
|
||||
### Requirement: Non-Interactive Mode
|
||||
The command SHALL support non-interactive operation through command-line options for automation and CI/CD use cases.
|
||||
|
||||
#### Scenario: Select all tools non-interactively
|
||||
- **WHEN** run with `--tools all`
|
||||
- **THEN** automatically select every available AI tool without prompting
|
||||
- **AND** proceed with initialization using the selected tools
|
||||
|
||||
#### Scenario: Select specific tools non-interactively
|
||||
- **WHEN** run with `--tools claude,cursor`
|
||||
- **THEN** parse the comma-separated tool IDs and validate against available tools
|
||||
- **AND** proceed with initialization using only the specified valid tools
|
||||
|
||||
#### Scenario: Skip tool configuration non-interactively
|
||||
- **WHEN** run with `--tools none`
|
||||
- **THEN** skip AI tool configuration entirely
|
||||
- **AND** only create the OpenSpec directory structure and template files
|
||||
|
||||
#### Scenario: Invalid tool specification
|
||||
- **WHEN** run with `--tools` containing any IDs not present in the AI tool registry
|
||||
- **THEN** exit with code 1 and display available values (`all`, `none`, or the supported tool IDs)
|
||||
|
||||
#### Scenario: Help text lists available tool IDs
|
||||
- **WHEN** displaying CLI help for `openspec init`
|
||||
- **THEN** show the `--tools` option description with the valid values derived from the AI tool registry
|
||||
|
||||
## MODIFIED Requirements
|
||||
### 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 without non-interactive options
|
||||
- **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
|
||||
@@ -1,17 +0,0 @@
|
||||
## 1. CLI Option Registration
|
||||
- [x] 1.1 Replace the multiple flag design with a single `--tools <value>` option supporting `all|none|a,b,c` and keep strict argument validation.
|
||||
- [x] 1.2 Populate the `--tools` help text dynamically from the `AI_TOOLS` registry.
|
||||
|
||||
## 2. InitCommand Modifications
|
||||
- [x] 2.1 Accept the single tools option in the InitCommand constructor and plumb it through existing flows.
|
||||
- [x] 2.2 Update tool selection logic to shortcut prompts for `all`, `none`, and explicit lists.
|
||||
- [x] 2.3 Fail fast with exit code 1 and a helpful message when the parsed list contains unsupported tool IDs.
|
||||
|
||||
## 3. Specification Updates
|
||||
- [x] 3.1 Capture the non-interactive scenarios (`all`, `none`, list, invalid) in the change delta without modifying `specs/cli-init/spec.md` directly.
|
||||
- [x] 3.2 Document that CLI help reflects the available tool IDs managed by `AI_TOOLS`.
|
||||
|
||||
## 4. Testing
|
||||
- [x] 4.1 Add unit coverage for parsing `--tools` values, including invalid entries.
|
||||
- [x] 4.2 Add integration coverage ensuring non-interactive runs generate the expected files and exit codes.
|
||||
- [x] 4.3 Verify the interactive flow remains unchanged when `--tools` is omitted.
|
||||
@@ -1,17 +0,0 @@
|
||||
## Why
|
||||
- Windsurf exposes "Workflows" as the vehicle for slash-like automation: saved Markdown files under `.windsurf/workflows/` that Cascade discovers across the workspace (including subdirectories and up to the git root), then executes when a user types `/workflow-name`. These files can be team-authored, must stay under 12k characters, and can call other workflows, making them the natural place to publish OpenSpec guidance for Windsurf users.\
|
||||
([Windsurf Workflows documentation](https://docs.windsurf.com/windsurf/cascade/workflows))
|
||||
- The Wave 12 changelog reiterates that workflows are invoked via slash commands and that Windsurf stores them in `.windsurf/workflows`, so the OpenSpec CLI just needs to generate Markdown there to participate in Windsurf's command palette.\
|
||||
("Custom Workflows" section, [Windsurf changelog](https://windsurf.com/changelog))
|
||||
- OpenSpec already ships shared command bodies for proposal/apply/archive and uses markers so commands stay up to date. Extending the same templates to Windsurf keeps behaviour consistent with Claude, Cursor, and OpenCode without inventing new content flows.
|
||||
|
||||
## What Changes
|
||||
- Add Windsurf to the CLI tool picker (`openspec init`) and the slash-command registry so selecting it scaffolds `.windsurf/workflows/openspec-proposal.md`, `openspec-apply.md`, and `openspec-archive.md` with marker-managed bodies.
|
||||
- Shape each Windsurf workflow with a short heading/description plus the existing OpenSpec guardrails/steps wrapped in markers, ensuring the total payload remains well below the 12,000 character limit.
|
||||
- Ensure `openspec update` refreshes existing Windsurf workflows (and only those that already exist) in-place, mirroring current behaviour for other editors.
|
||||
- Extend unit tests for init/update to cover Windsurf generation and updates, and update the README/tooling docs to advertise Windsurf support.
|
||||
|
||||
## Impact
|
||||
- Specs: `cli-init`, `cli-update`
|
||||
- Code: `src/core/configurators/slash/*`, `src/core/templates/slash-command-templates.ts`, CLI prompts, README
|
||||
- Tests: init/update integration coverage for Windsurf workflows
|
||||
@@ -1,42 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: AI Tool Configuration
|
||||
The command SHALL configure AI coding assistants with OpenSpec instructions using a marker system.
|
||||
#### 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)
|
||||
- OpenCode (creates or refreshes `.opencode/command/openspec-*.md` slash commands)
|
||||
- Windsurf (creates or refreshes `.windsurf/workflows/openspec-*.md` workflows)
|
||||
- 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: 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
|
||||
|
||||
#### 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
|
||||
@@ -1,27 +0,0 @@
|
||||
## 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 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
|
||||
|
||||
#### Scenario: Missing slash command file
|
||||
- **WHEN** a tool lacks a slash command file
|
||||
- **THEN** do not create a new file during update
|
||||
@@ -1,17 +0,0 @@
|
||||
## 1. CLI wiring
|
||||
- [x] 1.1 Add Windsurf to the selectable AI tools in `openspec init`, including "already configured" detection.
|
||||
- [x] 1.2 Register a `WindsurfSlashCommandConfigurator` that writes workflows to `.windsurf/workflows/` and ensures the directory exists.
|
||||
- [x] 1.3 Ensure `openspec update` pulls the Windsurf configurator when winds is selected and skips creation when files are absent.
|
||||
|
||||
## 2. Workflow templates
|
||||
- [x] 2.1 Reuse the shared proposal/apply/archive bodies, adding Windsurf-specific headings/description before the OpenSpec markers.
|
||||
- [x] 2.2 Confirm generated Markdown (per file) stays comfortably under the 12k character ceiling noted in the Windsurf docs.
|
||||
|
||||
## 3. Tests & safeguards
|
||||
- [x] 3.1 Extend init tests to assert creation of `.windsurf/workflows/openspec-*.md` when Windsurf is chosen.
|
||||
- [x] 3.2 Extend update tests to assert existing Windsurf workflows are refreshed and non-existent files are ignored.
|
||||
- [x] 3.3 Add regression coverage for marker preservation inside Windsurf workflow files.
|
||||
|
||||
## 4. Documentation
|
||||
- [x] 4.1 Update README (and any user-facing docs) to list Windsurf under native slash/workflow integrations.
|
||||
- [x] 4.2 Call out Windsurf workflow support in release notes or CHANGELOG if applicable.
|
||||
@@ -1,12 +0,0 @@
|
||||
## Why
|
||||
Validation errors like "no deltas found" or "missing requirement text" do not tell agents how to recover, leading to repeated failures. Making error output specific about headers, required text, and next actions will help assistants fix issues in a single pass.
|
||||
|
||||
## What Changes
|
||||
- Extend `openspec validate` error reporting so each failure names the exact header, file, and expected structure, including concrete examples of compliant Markdown.
|
||||
- Tailor messages for the most common mistakes (missing delta sections, absent descriptive requirement text, missing scenarios) with actionable fixes and suggested debug commands.
|
||||
- Update docs/help output so the improved messaging is discoverable (e.g., `--help`, troubleshooting section).
|
||||
- Add regression coverage to lock in the richer messaging for the top validation paths.
|
||||
|
||||
## Impact
|
||||
- Affected specs: `specs/cli-validate`
|
||||
- Affected code: `src/commands/validate.ts`, `src/core/validation`, `docs/`
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
## MODIFIED 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:
|
||||
- Explain that change specs must include `## ADDED Requirements`, `## MODIFIED Requirements`, `## REMOVED Requirements`, or `## RENAMED Requirements`
|
||||
- Remind authors that files must live under `openspec/changes/{id}/specs/<capability>/spec.md`
|
||||
- Include an explicit note: "Spec delta files cannot start with titles before the operation headers"
|
||||
- Suggest running `openspec change show {id} --json --deltas-only` for debugging
|
||||
|
||||
#### Scenario: Missing required sections
|
||||
- **WHEN** a required section is missing
|
||||
- **THEN** include expected header names and a minimal skeleton:
|
||||
- For Spec: `## Purpose`, `## Requirements`
|
||||
- For Change: `## Why`, `## What Changes`
|
||||
- Provide an example snippet of the missing section with placeholder prose ready to copy
|
||||
- Mention the quick-reference section in `openspec/AGENTS.md` as the authoritative template
|
||||
|
||||
#### Scenario: Missing requirement descriptive text
|
||||
- **WHEN** a requirement header lacks descriptive text before scenarios
|
||||
- **THEN** emit an error explaining that `### Requirement:` lines must be followed by narrative text before any `#### Scenario:` headers
|
||||
- Show compliant example: "### Requirement: Foo" followed by "The system SHALL ..."
|
||||
- Suggest adding 1-2 sentences describing the normative behavior prior to listing scenarios
|
||||
- Reference the pre-validation checklist in `openspec/AGENTS.md`
|
||||
|
||||
### 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** ...
|
||||
```
|
||||
@@ -1,12 +0,0 @@
|
||||
## 1. Messaging enhancements
|
||||
- [x] 1.1 Inventory current validation failures and map each to the desired message improvements.
|
||||
- [x] 1.2 Implement structured error builders that include file paths, normalized header names, and example fixes.
|
||||
- [x] 1.3 Ensure `openspec validate --help` and troubleshooting docs mention the richer messages and debug tips.
|
||||
|
||||
## 2. Tests
|
||||
- [x] 2.1 Add unit tests for representative errors (no deltas, missing requirement body, missing scenarios) asserting the new wording.
|
||||
- [x] 2.2 Add integration coverage verifying the Next steps footer reflects contextual guidance.
|
||||
|
||||
## 3. Documentation
|
||||
- [x] 3.1 Update troubleshooting sections and CLI docs with sample output from the enhanced errors.
|
||||
- [x] 3.2 Note the change in CHANGELOG or release notes if applicable.
|
||||
@@ -1,12 +0,0 @@
|
||||
## Why
|
||||
Agents fumble proposal formatting because the essential Markdown templates and formatting rules are buried mid-document. Reorganizing `openspec/AGENTS.md` with a prominent quick-reference and embedded examples will help assistants follow the process without guesswork.
|
||||
|
||||
## What Changes
|
||||
- Restructure `openspec/AGENTS.md` so file formats and scaffold templates appear in a top-level quick-reference section before workflow prose.
|
||||
- Embed copy/paste templates for `proposal.md`, `tasks.md`, `design.md`, and spec deltas alongside inline examples within the workflow steps.
|
||||
- Add a pre-validation checklist that highlights the most common formatting pitfalls before running `openspec validate`.
|
||||
- Split content into beginner vs. advanced sections to progressively disclose complexity while keeping advanced guidance accessible.
|
||||
|
||||
## Impact
|
||||
- Affected specs: `specs/docs-agent-instructions`
|
||||
- Affected code: `openspec/AGENTS.md`, `docs/`
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
## ADDED Requirements
|
||||
### Requirement: Quick Reference Placement
|
||||
The AI instructions SHALL begin with a quick-reference section that surfaces required file structures, templates, and formatting rules before any narrative guidance.
|
||||
|
||||
#### Scenario: Loading templates at the top
|
||||
- **WHEN** `openspec/AGENTS.md` is regenerated or updated
|
||||
- **THEN** the first substantive section after the title SHALL provide copy-ready headings for `proposal.md`, `tasks.md`, spec deltas, and scenario formatting
|
||||
- **AND** link each template to the corresponding workflow step for deeper reading
|
||||
|
||||
### Requirement: Embedded Templates and Examples
|
||||
`openspec/AGENTS.md` SHALL include complete copy/paste templates and inline examples exactly where agents make corresponding edits.
|
||||
|
||||
#### Scenario: Providing file templates
|
||||
- **WHEN** authors reach the workflow guidance for drafting proposals and deltas
|
||||
- **THEN** provide fenced Markdown templates that match the required structure (`## Why`, `## ADDED Requirements`, `#### Scenario:` etc.)
|
||||
- **AND** accompany each template with a brief example showing correct header usage and scenario bullets
|
||||
|
||||
### Requirement: Pre-validation Checklist
|
||||
`openspec/AGENTS.md` SHALL offer a concise pre-validation checklist that highlights common formatting mistakes before running `openspec validate`.
|
||||
|
||||
#### Scenario: Highlighting common validation failures
|
||||
- **WHEN** a reader reaches the validation guidance
|
||||
- **THEN** present a checklist reminding them to verify requirement headers, scenario formatting, and delta sections
|
||||
- **AND** include reminders about at least `#### Scenario:` usage and descriptive requirement text before scenarios
|
||||
|
||||
### Requirement: Progressive Disclosure of Workflow Guidance
|
||||
The documentation SHALL separate beginner essentials from advanced topics so newcomers can focus on core steps without losing access to advanced workflows.
|
||||
|
||||
#### Scenario: Organizing beginner and advanced sections
|
||||
- **WHEN** reorganizing `openspec/AGENTS.md`
|
||||
- **THEN** keep an introductory section limited to the minimum steps (scaffold, draft, validate, request review)
|
||||
- **AND** move advanced topics (multi-capability changes, archiving details, tooling deep dives) into clearly labeled later sections
|
||||
- **AND** provide anchor links from the quick-reference to those advanced sections
|
||||
@@ -1,11 +0,0 @@
|
||||
## 1. Instruction redesign
|
||||
- [x] 1.1 Draft a quick-reference section that surfaces file templates and formatting rules at the top of `openspec/AGENTS.md`.
|
||||
- [x] 1.2 Reorganize the workflow narrative with inline examples and progressive disclosure for advanced topics.
|
||||
|
||||
## 2. Templates and checklists
|
||||
- [x] 2.1 Add copy/paste templates for proposal, tasks, design, and spec delta files.
|
||||
- [x] 2.2 Insert a pre-validation checklist capturing common lint failures before running `openspec validate`.
|
||||
|
||||
## 3. Documentation updates
|
||||
- [x] 3.1 Update supporting docs or README pointers so contributors find the redesigned instructions.
|
||||
- [x] 3.2 Confirm examples and references stay in sync with the new scaffold command guidance.
|
||||
@@ -1,13 +0,0 @@
|
||||
## Why
|
||||
The project root currently receives a full copy of the OpenSpec agent instructions, duplicating the content that also lives in `openspec/AGENTS.md`. When teams edit one copy but not the other, the files drift and onboarding assistants see conflicting guidance.
|
||||
|
||||
## What Changes
|
||||
- Keep generating the complete template in `openspec/AGENTS.md` during `openspec init` and follow-up updates.
|
||||
- Replace the root-level file (`AGENTS.md` or `CLAUDE.md`, depending on tool selection) with a short hand-off that explains the project uses OpenSpec and points directly to `openspec/AGENTS.md`.
|
||||
- Add a dedicated stub template so both the init and update flows reuse the same minimal copy instructions.
|
||||
- Update CLI tests and documentation to reflect the new root-level messaging and ensure the OpenSpec marker block still protects future updates.
|
||||
|
||||
## Impact
|
||||
- Affected specs: `cli-init`, `cli-update`
|
||||
- Affected code: `src/core/init.ts`, `src/core/update.ts`, `src/core/templates/agents-template.ts`
|
||||
- Update assets/readmes that mention the root `AGENTS.md` contents to reference the new stub message.
|
||||
@@ -1,15 +0,0 @@
|
||||
## 1. Templates
|
||||
- [x] 1.1 Add a shared stub template that renders the root agent instructions hand-off message.
|
||||
- [x] 1.2 Ensure the stub covers both `AGENTS.md` and `CLAUDE.md` variants.
|
||||
|
||||
## 2. Init Flow
|
||||
- [x] 2.1 Update `createInitArtifacts` to write the stub to the project root instead of the full instructions.
|
||||
- [x] 2.2 Preserve the managed block markers so future updates can overwrite the stub safely.
|
||||
|
||||
## 3. Update Flow
|
||||
- [x] 3.1 Make the update command refresh the root stub rather than the full instructions.
|
||||
- [x] 3.2 Confirm the update log output still reflects the files that changed.
|
||||
|
||||
## 4. Tests & Docs
|
||||
- [x] 4.1 Adjust CLI/init tests to match the new root content.
|
||||
- [x] 4.2 Document the stub message in `openspec/specs/cli-init` and `openspec/specs/cli-update` (and any relevant README snippets).
|
||||
@@ -1,14 +0,0 @@
|
||||
## Why
|
||||
- Users frequently scroll to a tool and press Enter without toggling it, resulting in no configuration changes.
|
||||
- The current workflow deviates from common CLI expectations where Enter confirms the highlighted item.
|
||||
- Aligning behavior with user expectations reduces friction during onboarding.
|
||||
|
||||
## What Changes
|
||||
- Update the init wizard so pressing Enter on a highlighted tool selects it before moving to the review step.
|
||||
- Adjust interactive instructions to clarify Enter selects the current tool and Space still toggles selections.
|
||||
- Refresh specs to capture the clarified behavior for the interactive menu.
|
||||
|
||||
## Impact
|
||||
- Users who press Enter without toggling now configure the highlighted tool instead of exiting with no selections.
|
||||
- Spacebar multi-select support remains unchanged for power users.
|
||||
- Documentation better reflects how the wizard behaves.
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
### 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 Space and review selections with Enter
|
||||
- **AND** when Enter is pressed on a highlighted selectable tool that is not already selected, automatically add it to the selection before moving to review so the highlighted tool is configured
|
||||
- **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 Space toggles tools and Enter selects the highlighted tool before reviewing selections
|
||||
@@ -1,8 +0,0 @@
|
||||
## 1. Implementation
|
||||
- [x] Update the tool selection wizard to auto-select the highlighted tool when Enter is pressed without prior toggles.
|
||||
- [x] Refresh inline instructions copy so Enter behavior is clear.
|
||||
- [x] Adjust or add tests if needed to cover the new selection flow.
|
||||
|
||||
## 2. Validation
|
||||
- [x] Run `pnpm run build`.
|
||||
- [x] Run `pnpm test` (or targeted suite) if applicable.
|
||||
@@ -1,15 +0,0 @@
|
||||
## Why
|
||||
OpenSpec currently creates the root-level `AGENTS.md` stub only when teams explicitly select the "AGENTS.md standard" tool during `openspec init`. Projects that skip that checkbox never get a managed stub, so non-native assistants (Copilot, Codeium, etc.) have no entry point and later `openspec update` runs silently create the file without any context. We need to bake the stub into initialization, clarify the tool selection experience, and keep the update workflow aligned so every teammate lands on the right instructions from day one.
|
||||
|
||||
## What Changes
|
||||
- Update `openspec init` so the root `AGENTS.md` stub is always generated (first run and extend mode) and refreshed from a shared utility instead of being tied to a tool selection.
|
||||
- Redesign the AI tool selection wizard to split options into "Natively supported" (Claude, Cursor, OpenCode, …) and an informational "Other tools" section that explains the always-on `AGENTS.md` hand-off.
|
||||
- Adjust CLI specs, prompts, and success messaging to reflect the new categories while keeping extend-mode behaviour consistent.
|
||||
- Update automated tests and fixtures to cover the unconditional stub creation and the reworked prompt flow.
|
||||
- Refresh documentation and onboarding snippets so they no longer describe the stub as opt-in and instead call out the new grouping.
|
||||
- Ensure `openspec update` continues to reconcile both `openspec/AGENTS.md` and the root stub, documenting the expected behaviour so mismatched setups self-heal.
|
||||
|
||||
## Impact
|
||||
- Affected specs: `cli-init`, `cli-update`
|
||||
- Affected code: `src/core/init.ts`, `src/core/config.ts`, `src/core/configurators/agents.ts`, `src/core/templates/agents-root-stub.ts`, `src/core/update.ts`, related tests under `test/core/`
|
||||
- Docs & assets: README, CHANGELOG, any setup guides that reference choosing the "AGENTS.md standard" option
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: AI Tool Configuration
|
||||
The command SHALL configure AI coding assistants with OpenSpec instructions using a grouped selection experience so teams can enable native integrations while always provisioning guidance for other assistants.
|
||||
|
||||
#### Scenario: Prompting for AI tool selection
|
||||
- **WHEN** run interactively
|
||||
- **THEN** present a multi-select wizard that separates options into two headings:
|
||||
- **Natively supported providers** shows each available first-party integration (Claude Code, Cursor, OpenCode, …) with checkboxes
|
||||
- **Other tools** explains that the root-level `AGENTS.md` stub is always generated for AGENTS-compatible assistants and cannot be deselected
|
||||
- **AND** mark already configured native tools with "(already configured)" to signal that choosing them will refresh managed content
|
||||
- **AND** keep disabled or unavailable providers labelled as "coming soon" so users know they cannot opt in yet
|
||||
- **AND** allow confirming the selection even when no native provider is chosen because the root stub remains enabled by default
|
||||
- **AND** change the base prompt copy in extend mode to "Which natively supported AI tools would you like to add or refresh?"
|
||||
|
||||
### Requirement: Exit Code Adjustments
|
||||
`openspec init` SHALL treat extend mode without new native tool selections as a successful refresh.
|
||||
|
||||
#### Scenario: Allowing empty extend runs
|
||||
- **WHEN** OpenSpec is already initialized and the user selects no additional natively supported tools
|
||||
- **THEN** complete successfully while refreshing the root `AGENTS.md` stub
|
||||
- **AND** exit with code 0
|
||||
|
||||
## ADDED Requirements
|
||||
### Requirement: Root instruction stub
|
||||
`openspec init` SHALL always scaffold the root-level `AGENTS.md` hand-off so every teammate finds the primary OpenSpec instructions.
|
||||
|
||||
#### Scenario: Creating root `AGENTS.md`
|
||||
- **GIVEN** the project may or may not already contain an `AGENTS.md` file
|
||||
- **WHEN** initialization completes in fresh or extend mode
|
||||
- **THEN** create or refresh `AGENTS.md` at the repository root using the managed marker block from `TemplateManager.getAgentsStandardTemplate()`
|
||||
- **AND** preserve any existing content outside the managed markers while replacing the stub text inside them
|
||||
- **AND** create the stub regardless of which native AI tools are selected
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Tool-Agnostic Updates
|
||||
The update command SHALL refresh OpenSpec-managed files in a predictable manner while respecting each team's chosen tooling.
|
||||
|
||||
#### Scenario: Updating files
|
||||
- **WHEN** updating files
|
||||
- **THEN** completely replace `openspec/AGENTS.md` with the latest template
|
||||
- **AND** create or refresh the root-level `AGENTS.md` stub using the managed marker block, even if the file was previously absent
|
||||
- **AND** update only the OpenSpec-managed sections inside existing AI tool files, leaving user-authored content untouched
|
||||
- **AND** avoid creating new native-tool configuration files (slash commands, CLAUDE.md, etc.) unless they already exist
|
||||
@@ -1,11 +0,0 @@
|
||||
## 1. Implementation
|
||||
- [x] 1.1 Refactor `openspec init` to always generate the root `AGENTS.md` stub (initial run and extend mode) via shared helper logic.
|
||||
- [x] 1.2 Rework the AI tool selection wizard to surface "Natively supported" vs "Other tools" groupings and make the stub non-optional.
|
||||
- [x] 1.3 Update CLI messaging, templates, and configurators so the new flow stays in sync across init and update commands.
|
||||
- [x] 1.4 Refresh unit/integration tests to cover the unconditional stub and the regrouped prompt layout.
|
||||
- [x] 1.5 Update documentation, README snippets, and CHANGELOG entries that mention the opt-in `AGENTS.md` experience.
|
||||
|
||||
## 2. Validation
|
||||
- [x] 2.1 Run `pnpm test` targeting CLI init/update suites.
|
||||
- [x] 2.2 Execute `openspec validate update-cli-init-root-agents --strict`.
|
||||
- [x] 2.3 Perform a manual smoke test: run `openspec init` in a temp directory, confirm stub + grouped prompts, rerun in extend mode.
|
||||
@@ -1,49 +0,0 @@
|
||||
## Why
|
||||
Today’s process requires maintainers to merge the Changesets PR, cut a tag, and draft the GitHub release by hand. npm publish then runs from our existing workflow after the GitHub release is published. The human-in-the-loop steps (versioning, tagging, release notes) slow us down and risk drift between npm, tags, and changelog.
|
||||
|
||||
## What Changes
|
||||
- Use the single `changesets/action` on pushes to `main` to either open/update the version PR or, when the release PR is merged, run our publish command automatically using repository secrets.
|
||||
- Add a `release` script that builds and runs `changeset publish` so the action handles version bumps, changelog commits, npm publish, and GitHub releases end-to-end.
|
||||
- Enable `createGithubReleases: true` so GitHub releases are created from the changeset data right after publishing.
|
||||
- Document the automated flow, required secrets, guardrails, and recovery steps (rollback, hotfixes).
|
||||
|
||||
## Two-Phase Rollout (Two PRs)
|
||||
1) Phase 1 — Dry run (no publish)
|
||||
- Update the existing `release-prepare.yml` to wire up `changesets/action` with `createGithubReleases: true` and a no-op `publish` command (e.g., `echo 'dry run'`).
|
||||
- Keep `.github/workflows/release-publish.yml` intact. This avoids any publish path changes while we verify that the version PR behavior and permissions are correct.
|
||||
- Add a repository guard (`if: github.repository == 'Fission-AI/OpenSpec'`) and a concurrency group for safety.
|
||||
|
||||
2) Phase 2 — Enable publish and consolidate
|
||||
- Add `"release": "pnpm run build && pnpm exec changeset publish"` to `package.json`.
|
||||
- Change `release-prepare.yml` to use `with: publish: pnpm run release` and `env: NPM_TOKEN: \\${{ secrets.NPM_TOKEN }}` plus the default `GITHUB_TOKEN`.
|
||||
- Remove `.github/workflows/release-publish.yml` to avoid double-publish. Publishing now happens when the version PR is merged.
|
||||
|
||||
## Guardrails
|
||||
- Concurrency: `concurrency: { group: release-\\${{ github.ref }}, cancel-in-progress: false }` on the workflow to serialize releases.
|
||||
- Repository/branch guard: run publish logic only on upstream `main` (`if: github.repository == 'Fission-AI/OpenSpec' && github.ref == 'refs/heads/main'`).
|
||||
- Permissions: ensure `contents: write` and `pull-requests: write` for opening/updating the version PR; `packages: read` optional.
|
||||
|
||||
## Rollback and Hotfixes
|
||||
- Rollback: revert the release PR merge (which reverts version bumps/changelog); if a tag or GitHub release was created, delete the tag and release; deprecate the npm version if necessary (`npm deprecate @fission-ai/openspec@x.y.z 'reason'`).
|
||||
- Hotfix (urgent, no pending changesets): create a changeset for the fix and merge the release PR; in emergencies, run a manual bump/publish but reconcile with Changesets by adding a follow-up changeset to align versions.
|
||||
|
||||
## Required Secrets
|
||||
- `NPM_TOKEN` with publish rights for the `@fission-ai` scope.
|
||||
- Default `GITHUB_TOKEN` (provided by GitHub) for opening/updating the version PR and creating GitHub releases.
|
||||
|
||||
## How the Maintainer Flow Changes
|
||||
| Step | Current process | Future process |
|
||||
| --- | --- | --- |
|
||||
| Prepare release | Merge changeset PR, then manually draft release notes and tags | Merge release PR; action updates versions and handles changelog automatically |
|
||||
| Publish npm package | Happens automatically after GitHub release | Happens automatically via `changeset publish` invoked by the action |
|
||||
| GitHub release | Draft manually and sync with changelog | Action creates GitHub releases from changeset data |
|
||||
| Docs/process | Follow manual tagging/release steps | Docs describe automated flow + recovery and hotfix paths |
|
||||
|
||||
## Impact
|
||||
- Automation: reuse `.github/workflows/release-prepare.yml` (phase 1: dry-run, phase 2: publish) and remove `.github/workflows/release-publish.yml` in phase 2.
|
||||
- Package metadata: add `release` script to `package.json`.
|
||||
- Docs: update README or `/docs` to show the automated flow, secrets, guardrails, and recovery steps.
|
||||
|
||||
## Acceptance Criteria
|
||||
- Phase 1: merges to `main` open/update a version PR; on merge, the action’s `publish` step is a no-op; no npm publish occurs; logs confirm intended behavior; GitHub releases creation is wired but inert due to no publish.
|
||||
- Phase 2: merges to `main` run `pnpm run release` from the action; npm package publishes successfully; GitHub release is created automatically; `.github/workflows/release-publish.yml` is removed; no duplicate publishes occur.
|
||||
@@ -1,12 +0,0 @@
|
||||
## 1. Release workflow automation
|
||||
- [x] 1.1 Add a `.github/workflows/release.yml` that runs on pushes to `main`, sets up pnpm + Node 20, installs dependencies, and invokes `changesets/action@v1` with `publish: pnpm run release`.
|
||||
- [x] 1.2 Configure the action with `createGithubReleases: true` and document required secrets (`NPM_TOKEN`, default `GITHUB_TOKEN`) plus recommended concurrency safeguards.
|
||||
- [x] 1.3 Validate the workflow using `act` or a dry-run push to confirm the action opens release PRs when changesets exist and publishes when the release PR merge lands.
|
||||
|
||||
## 2. Package release script
|
||||
- [x] 2.1 Add a `release` script to `package.json` that builds the project and runs `changeset publish` using pnpm.
|
||||
- [x] 2.2 Ensure the script respects the existing `prepare`/`prepublishOnly` hooks to avoid duplicate builds and update documentation or scripts if adjustments are needed.
|
||||
|
||||
## 3. Documentation and recovery steps
|
||||
- [x] 3.1 Update maintainer docs (e.g., README or `/docs`) with the end-to-end automated release flow, explicitly removing the manual tag/release steps that are no longer required and explaining how changesets drive the release PR.
|
||||
- [x] 3.2 Document fallback steps for failed publishes (rerun workflow, manual publish) and the hotfix path when a release must be cut without pending changesets.
|
||||
@@ -1,17 +0,0 @@
|
||||
# Add Archive Command Arguments
|
||||
|
||||
## Why
|
||||
The `/openspec:archive` slash command currently lacks argument support, forcing the AI to infer which change to archive from conversation context or by listing all changes. This creates a safety risk where the wrong proposal could be archived if the context is ambiguous or multiple changes exist. Users expect to specify the change ID explicitly, matching the behavior of the CLI command `openspec archive <id>`.
|
||||
|
||||
## What Changes
|
||||
- Add `$ARGUMENTS` placeholder to the OpenCode archive slash command frontmatter (matching existing pattern for proposal command)
|
||||
- Update archive command template steps to validate the specific change ID argument when provided
|
||||
- Note: Codex, GitHub Copilot, and Amazon Q already have `$ARGUMENTS` for archive; Claude/Cursor/Windsurf/Kilocode don't support arguments
|
||||
|
||||
## Impact
|
||||
- Affected specs: `cli-update` (slash command generation logic)
|
||||
- Affected code:
|
||||
- `src/core/configurators/slash/opencode.ts` (add `$ARGUMENTS` to archive frontmatter)
|
||||
- `src/core/templates/slash-command-templates.ts` (archive template steps for argument validation)
|
||||
- Breaking: No - this is additive functionality that makes the command safer
|
||||
- User-facing: Yes - OpenCode users will be able to pass the change ID as an argument: `/openspec:archive <change-id>`
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
# CLI Update Specification Delta
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Slash Command Updates
|
||||
The update command SHALL refresh existing slash command files for configured tools without creating new ones, and ensure the OpenCode archive command accepts change ID arguments.
|
||||
|
||||
#### 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
|
||||
- **AND** ensure the archive command includes `$ARGUMENTS` placeholder in frontmatter for accepting change ID arguments
|
||||
|
||||
### Requirement: Archive Command Argument Support
|
||||
The archive slash command template SHALL support optional change ID arguments for tools that support `$ARGUMENTS` placeholder.
|
||||
|
||||
#### Scenario: Archive command with change ID argument
|
||||
- **WHEN** a user invokes `/openspec:archive <change-id>` with a change ID
|
||||
- **THEN** the template SHALL instruct the AI to validate the provided change ID against `openspec list`
|
||||
- **AND** use the provided change ID for archiving if valid
|
||||
- **AND** fail fast if the provided change ID doesn't match an archivable change
|
||||
|
||||
#### Scenario: Archive command without argument (backward compatibility)
|
||||
- **WHEN** a user invokes `/openspec:archive` without providing a change ID
|
||||
- **THEN** the template SHALL instruct the AI to identify the change ID from context or by running `openspec list`
|
||||
- **AND** proceed with the existing behavior (maintaining backward compatibility)
|
||||
|
||||
#### Scenario: OpenCode archive template generation
|
||||
- **WHEN** generating the OpenCode archive slash command file
|
||||
- **THEN** include the `$ARGUMENTS` placeholder in the frontmatter
|
||||
- **AND** wrap it in a clear structure like `<ChangeId>\n $ARGUMENTS\n</ChangeId>` to indicate the expected argument
|
||||
- **AND** include validation steps in the template body to check if the change ID is valid
|
||||
@@ -1,15 +0,0 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Update OpenCode Configurator
|
||||
- [x] 1.1 Add `$ARGUMENTS` placeholder to OpenCode archive frontmatter (matching the proposal pattern)
|
||||
- [x] 1.2 Format it as `<ChangeId>\n $ARGUMENTS\n</ChangeId>` or similar structure for clarity
|
||||
- [x] 1.3 Ensure `updateExisting` rewrites the archive frontmatter/body so `$ARGUMENTS` persists after `openspec update`
|
||||
|
||||
## 2. Update Slash Command Templates
|
||||
- [x] 2.1 Modify archive steps to validate change ID argument when provided via `$ARGUMENTS`
|
||||
- [x] 2.2 Keep backward compatibility - allow inferring from context if no argument provided
|
||||
- [x] 2.3 Add step to validate the change ID exists using `openspec list` before archiving
|
||||
|
||||
## 3. Update Documentation
|
||||
- [x] 3.1 Update AGENTS.md archive examples to show argument usage
|
||||
- [x] 3.2 Document that OpenCode now supports `/openspec:archive <change-id>`
|
||||
@@ -1,15 +0,0 @@
|
||||
## Why
|
||||
Add support for Cline (VS Code extension) in OpenSpec to enable developers to use Cline's AI-powered coding capabilities for spec-driven development workflows.
|
||||
|
||||
## What Changes
|
||||
- Add Cline slash command configurator for proposal, apply, and archive operations
|
||||
- Add Cline root CLINE.md configurator for project-level instructions
|
||||
- Add Cline template exports
|
||||
- Update tool and slash command registries to include Cline
|
||||
- Add comprehensive test coverage
|
||||
- **BREAKING**: None - this is additive functionality
|
||||
|
||||
## Impact
|
||||
- Affected specs: cli-init (new tool option)
|
||||
- Affected code: src/core/configurators/slash/cline.ts, src/core/configurators/cline.ts, registry files
|
||||
- New files: .clinerules/openspec-*.md, CLINE.md
|
||||
@@ -1,97 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
### 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/)
|
||||
- **AND** populate the managed block with a short stub that points teammates to `@/openspec/AGENTS.md`
|
||||
|
||||
#### Scenario: Configuring CodeBuddy Code
|
||||
|
||||
- **WHEN** CodeBuddy Code is selected
|
||||
- **THEN** create or update `CODEBUDDY.md` in the project root directory (not inside openspec/)
|
||||
- **AND** populate the managed block with a short stub that points teammates to `@/openspec/AGENTS.md`
|
||||
|
||||
#### Scenario: Configuring Cline
|
||||
|
||||
- **WHEN** Cline is selected
|
||||
- **THEN** create or update `CLINE.md` in the project root directory (not inside openspec/)
|
||||
- **AND** populate the managed block with a short stub that points teammates to `@/openspec/AGENTS.md`
|
||||
|
||||
#### Scenario: Creating new CLAUDE.md
|
||||
|
||||
- **WHEN** CLAUDE.md does not exist
|
||||
- **THEN** create new file with stub instructions wrapped in markers so the full workflow stays in `openspec/AGENTS.md`:
|
||||
```markdown
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Instructions
|
||||
|
||||
This project uses OpenSpec to manage AI assistant workflows.
|
||||
|
||||
- Full guidance lives in '@/openspec/AGENTS.md'.
|
||||
- Keep this managed block so 'openspec update' can refresh the instructions.
|
||||
<!-- OPENSPEC:END -->
|
||||
```
|
||||
|
||||
### 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 CodeBuddy Code
|
||||
- **WHEN** the user selects CodeBuddy Code during initialization
|
||||
- **THEN** create `.codebuddy/commands/openspec/proposal.md`, `.codebuddy/commands/openspec/apply.md`, and `.codebuddy/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 Cline
|
||||
- **WHEN** the user selects Cline during initialization
|
||||
- **THEN** create `.clinerules/openspec-proposal.md`, `.clinerules/openspec-apply.md`, and `.clinerules/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** include Cline-specific Markdown heading frontmatter
|
||||
- **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
|
||||
|
||||
#### 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
|
||||
@@ -1,19 +0,0 @@
|
||||
## 1. Implementation
|
||||
- [x] 1.1 Create ClineSlashCommandConfigurator class in src/core/configurators/slash/cline.ts
|
||||
- [x] 1.2 Create ClineConfigurator class in src/core/configurators/cline.ts
|
||||
- [x] 1.3 Create cline-template.ts for template exports
|
||||
- [x] 1.4 Define file paths for Cline rules (.clinerules/)
|
||||
- [x] 1.5 Create Cline-specific frontmatter (Markdown heading format)
|
||||
- [x] 1.6 Register Cline in slash/registry.ts
|
||||
- [x] 1.7 Register Cline in configurators/registry.ts
|
||||
- [x] 1.8 Add Cline to AI_TOOLS in config.ts
|
||||
- [x] 1.9 Add getClineTemplate() to templates/index.ts
|
||||
- [x] 1.10 Update README with Cline documentation
|
||||
|
||||
## 2. Testing
|
||||
- [x] 2.1 Add init tests for CLINE.md creation and updates
|
||||
- [x] 2.2 Add init tests for .clinerules/ file creation
|
||||
- [x] 2.3 Add update tests for CLINE.md updates
|
||||
- [x] 2.4 Add update tests for .clinerules/ file refreshes
|
||||
- [x] 2.5 Test integration with openspec init --tools cline
|
||||
- [x] 2.6 Verify all 225 tests pass
|
||||
@@ -1,13 +0,0 @@
|
||||
## Why
|
||||
Add support for Crush AI assistant in OpenSpec to enable developers to use Crush's enhanced capabilities for spec-driven development workflows.
|
||||
|
||||
## What Changes
|
||||
- Add Crush slash command configurator for proposal, apply, and archive operations
|
||||
- Add Crush-specific AGENTS.md configuration template
|
||||
- Update tool registry to include Crush configurator
|
||||
- **BREAKING**: None - this is additive functionality
|
||||
|
||||
## Impact
|
||||
- Affected specs: cli-init (new tool option)
|
||||
- Affected code: src/core/configurators/slash/crush.ts, registry.ts
|
||||
- New files: .crush/commands/openspec/ (proposal.md, apply.md, archive.md)
|
||||
@@ -1,67 +0,0 @@
|
||||
## 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 CodeBuddy Code
|
||||
- **WHEN** the user selects CodeBuddy Code during initialization
|
||||
- **THEN** create `.codebuddy/commands/openspec/proposal.md`, `.codebuddy/commands/openspec/apply.md`, and `.codebuddy/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 Cline
|
||||
- **WHEN** the user selects Cline during initialization
|
||||
- **THEN** create `.clinerules/openspec-proposal.md`, `.clinerules/openspec-apply.md`, and `.clinerules/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** include Cline-specific Markdown heading frontmatter
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
|
||||
#### Scenario: Generating slash commands for Crush
|
||||
- **WHEN** the user selects Crush during initialization
|
||||
- **THEN** create `.crush/commands/openspec/proposal.md`, `.crush/commands/openspec/apply.md`, and `.crush/commands/openspec/archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** include Crush-specific frontmatter with OpenSpec category and tags
|
||||
- **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
|
||||
|
||||
#### 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
|
||||
@@ -1,7 +0,0 @@
|
||||
## 1. Implementation
|
||||
- [x] 1.1 Create CrushSlashCommandConfigurator class in src/core/configurators/slash/crush.ts
|
||||
- [x] 1.2 Define file paths for Crush commands (.crush/commands/openspec/)
|
||||
- [x] 1.3 Create Crush-specific frontmatter for proposal, apply, archive commands
|
||||
- [x] 1.4 Register Crush configurator in slash/registry.ts
|
||||
- [x] 1.5 Add Crush to available tools in cli-init command
|
||||
- [x] 1.6 Test integration with openspec init --tool crush
|
||||
@@ -1,12 +0,0 @@
|
||||
## 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
|
||||
@@ -1,54 +0,0 @@
|
||||
## 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
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
## 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
|
||||
@@ -1,11 +0,0 @@
|
||||
## 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.
|
||||
@@ -1,525 +0,0 @@
|
||||
# Shell Completions Design
|
||||
|
||||
## Overview
|
||||
|
||||
This design establishes a plugin-based architecture for shell completions that prioritizes clean TypeScript patterns, scalability, and maintainability. The system separates concerns between shell-specific generation logic, dynamic completion data providers, and installation automation.
|
||||
|
||||
**Scope:** This proposal implements **Zsh completion only** (with Oh My Zsh priority). The architecture is designed to support bash, fish, and PowerShell in future proposals.
|
||||
|
||||
## Native Shell Completion Behaviors
|
||||
|
||||
**Design Philosophy:** We integrate with each shell's native completion system rather than attempting to customize or unify behaviors. This ensures familiar UX for users and reduces maintenance complexity.
|
||||
|
||||
**Note:** While all four shell behaviors are documented below for architectural reference, **only Zsh is implemented in this proposal**. Bash, Fish, and PowerShell are documented to guide future implementations.
|
||||
|
||||
### Bash Completion Behavior
|
||||
|
||||
**Interaction Pattern:**
|
||||
- **Single TAB:** Completes if only one match exists, otherwise does nothing
|
||||
- **Double TAB (TAB TAB):** Displays all possible completions as a list
|
||||
- **Type more characters + TAB:** Narrows matches and completes or shows refined list
|
||||
|
||||
**OpenSpec Integration:**
|
||||
```bash
|
||||
# After installing: openspec completion install bash
|
||||
openspec val<TAB> # Completes to "openspec validate"
|
||||
openspec validate <TAB><TAB> # Shows: --all --changes --specs --strict --json [change-ids] [spec-ids]
|
||||
openspec show add-<TAB><TAB> # Shows all changes starting with "add-"
|
||||
```
|
||||
|
||||
**Implementation:** Uses bash-completion framework with `_init_completion`, `compgen`, and `COMPREPLY` array.
|
||||
|
||||
### Zsh Completion Behavior (with Oh My Zsh)
|
||||
|
||||
**Interaction Pattern:**
|
||||
- **Single TAB:** Shows interactive menu with all matches immediately
|
||||
- **TAB / Arrow Keys:** Navigate through completion options
|
||||
- **Enter:** Selects highlighted option
|
||||
- **Ctrl+C / Esc:** Cancels completion menu
|
||||
|
||||
**OpenSpec Integration:**
|
||||
```zsh
|
||||
# After installing: openspec completion install zsh
|
||||
openspec val<TAB> # Shows menu with "validate" and "view" highlighted
|
||||
openspec show <TAB> # Shows menu with all change IDs and spec IDs, categorized
|
||||
```
|
||||
|
||||
**Implementation:** Uses Zsh completion system with `_arguments`, `_describe`, and `compadd` built-ins. Oh My Zsh provides enhanced menu styling automatically.
|
||||
|
||||
### Fish Completion Behavior
|
||||
|
||||
**Interaction Pattern:**
|
||||
- **As-you-type:** Gray suggestions appear automatically in real-time
|
||||
- **Right Arrow / Ctrl+F:** Accepts the suggestion
|
||||
- **TAB:** Shows menu with all matches if multiple exist
|
||||
- **TAB again:** Cycles through options or navigates menu
|
||||
- **Enter:** Accepts current selection
|
||||
|
||||
**OpenSpec Integration:**
|
||||
```fish
|
||||
# After installing: openspec completion install fish
|
||||
openspec val # Gray suggestion shows "validate" immediately
|
||||
openspec show a # Real-time suggestions for changes starting with "a"
|
||||
openspec <TAB> # Shows all commands with descriptions in paged menu
|
||||
```
|
||||
|
||||
**Implementation:** Uses Fish's declarative `complete -c` syntax. Completions are auto-loaded from `~/.config/fish/completions/`.
|
||||
|
||||
### PowerShell Completion Behavior
|
||||
|
||||
**Interaction Pattern:**
|
||||
- **TAB:** Cycles forward through completions one at a time (inline replacement)
|
||||
- **Shift+TAB:** Cycles backward through completions
|
||||
- **Ctrl+Space:** Shows IntelliSense-style menu (PSReadLine v2.2+)
|
||||
- **Arrow Keys:** Navigate menu if shown
|
||||
|
||||
**OpenSpec Integration:**
|
||||
```powershell
|
||||
# After installing: openspec completion install powershell
|
||||
openspec val<TAB> # Cycles: validate → view → validate
|
||||
openspec show <TAB> # Cycles through change IDs one by one
|
||||
openspec <Ctrl+Space> # Shows IntelliSense menu with all commands
|
||||
```
|
||||
|
||||
**Implementation:** Uses `Register-ArgumentCompleter` with custom script block that returns `[System.Management.Automation.CompletionResult]` objects.
|
||||
|
||||
### Comparison Table
|
||||
|
||||
| Shell | Trigger | Display Style | Navigation | Selection |
|
||||
|-------------|-----------------|------------------------|----------------------|----------------|
|
||||
| Bash | TAB TAB | List (printed once) | Type more + TAB | Auto-complete |
|
||||
| Zsh | TAB | Interactive menu | TAB/Arrows | Enter |
|
||||
| Fish | TAB/Auto | Real-time + menu | TAB/Arrows | Enter/Right |
|
||||
| PowerShell | TAB | Inline cycling | TAB/Shift+TAB | Stop cycling |
|
||||
|
||||
**Key Insight:** Each shell's completion UX reflects its design philosophy. We respect these conventions rather than forcing uniformity.
|
||||
|
||||
## Architectural Principles
|
||||
|
||||
### 1. Plugin-Based Generator System
|
||||
|
||||
Each shell has unique completion syntax and conventions. Rather than creating a monolithic generator with branching logic, we use a plugin pattern where each shell implements a common interface:
|
||||
|
||||
```typescript
|
||||
interface CompletionGenerator {
|
||||
generate(): string;
|
||||
getInstallPath(): string;
|
||||
getConfigFile(): string;
|
||||
}
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- New shells can be added without modifying existing generators
|
||||
- Shell-specific logic is isolated and testable
|
||||
- Type safety ensures all generators implement required methods
|
||||
- Easy to maintain and understand (single responsibility per generator)
|
||||
|
||||
**Implementation Classes:**
|
||||
- `ZshCompletionGenerator` - Uses Zsh's `_arguments` and `_describe` functions
|
||||
- `BashCompletionGenerator` - Uses `_init_completion` and `compgen` built-ins
|
||||
- `FishCompletionGenerator` - Uses `complete -c` declarative syntax
|
||||
- `PowerShellCompletionGenerator` - Uses `Register-ArgumentCompleter` cmdlet
|
||||
|
||||
### 2. Centralized Command Registry
|
||||
|
||||
Shell completions must stay synchronized with actual CLI commands. To avoid duplication and drift, we maintain a single source of truth:
|
||||
|
||||
```typescript
|
||||
type CommandDefinition = {
|
||||
name: string;
|
||||
description: string;
|
||||
flags: FlagDefinition[];
|
||||
acceptsChangeId: boolean;
|
||||
acceptsSpecId: boolean;
|
||||
subcommands?: CommandDefinition[];
|
||||
};
|
||||
|
||||
const COMMAND_REGISTRY: CommandDefinition[] = [
|
||||
{
|
||||
name: 'init',
|
||||
description: 'Initialize OpenSpec in your project',
|
||||
flags: [
|
||||
{ name: '--tools', description: 'Configure AI tools non-interactively', hasValue: true }
|
||||
],
|
||||
acceptsChangeId: false,
|
||||
acceptsSpecId: false
|
||||
},
|
||||
// ... all other commands
|
||||
];
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- All generators consume the same command definitions
|
||||
- Adding a new command automatically propagates to all shells
|
||||
- Flag changes only need to be made in one place
|
||||
- Type safety prevents typos and missing fields
|
||||
- Easier to test (mock the registry)
|
||||
|
||||
**TypeScript Sugar:**
|
||||
- Use `const` assertions for readonly registry
|
||||
- Leverage discriminated unions for command types
|
||||
- Use `satisfies` operator to ensure registry matches interface
|
||||
|
||||
### 3. Dynamic Completion Provider
|
||||
|
||||
Change and spec IDs are project-specific and discovered at runtime. A dedicated provider encapsulates this logic:
|
||||
|
||||
```typescript
|
||||
class CompletionProvider {
|
||||
private changeCache: { ids: string[]; timestamp: number } | null = null;
|
||||
private specCache: { ids: string[]; timestamp: number } | null = null;
|
||||
private readonly CACHE_TTL_MS = 2000;
|
||||
|
||||
async getChangeIds(): Promise<string[]> {
|
||||
if (this.changeCache && Date.now() - this.changeCache.timestamp < this.CACHE_TTL_MS) {
|
||||
return this.changeCache.ids;
|
||||
}
|
||||
|
||||
const ids = await discoverActiveChangeIds();
|
||||
this.changeCache = { ids, timestamp: Date.now() };
|
||||
return ids;
|
||||
}
|
||||
|
||||
async getSpecIds(): Promise<string[]> {
|
||||
// Similar caching logic
|
||||
}
|
||||
|
||||
isOpenSpecProject(): boolean {
|
||||
// Check for openspec/ directory
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Caching reduces file system overhead during rapid tab completion
|
||||
- Encapsulates project detection logic
|
||||
- Easy to test with mocked file system
|
||||
- Shared across all shell generators
|
||||
|
||||
**Design Decisions:**
|
||||
- 2-second cache TTL balances freshness with performance
|
||||
- Cache per-process (not persistent) to avoid stale data across sessions
|
||||
- Graceful degradation when outside OpenSpec projects
|
||||
|
||||
### 4. Separate Installation Logic
|
||||
|
||||
Installation involves shell configuration file manipulation, which differs from generation. We separate this concern:
|
||||
|
||||
```typescript
|
||||
interface CompletionInstaller {
|
||||
install(): Promise<InstallResult>;
|
||||
uninstall(): Promise<UninstallResult>;
|
||||
isInstalled(): Promise<boolean>;
|
||||
}
|
||||
```
|
||||
|
||||
**Shell-Specific Installers:**
|
||||
- `ZshInstaller` - Handles both Oh My Zsh (custom completions) and standard Zsh (fpath)
|
||||
- `BashInstaller` - Detects completion directories and sources from `.bashrc`
|
||||
- `FishInstaller` - Writes to `~/.config/fish/completions/` (auto-loaded)
|
||||
- `PowerShellInstaller` - Appends to PowerShell profile
|
||||
|
||||
**Benefits:**
|
||||
- Installation logic doesn't pollute generator code
|
||||
- Can test installation without generating completion scripts
|
||||
- Easier to handle edge cases (missing directories, permissions, already installed)
|
||||
|
||||
### 5. Type-Safe Shell Detection
|
||||
|
||||
We use TypeScript's literal types and type guards for shell detection:
|
||||
|
||||
```typescript
|
||||
type SupportedShell = 'bash' | 'zsh' | 'fish' | 'powershell';
|
||||
|
||||
function detectShell(): SupportedShell {
|
||||
const shellPath = process.env.SHELL || '';
|
||||
const shellName = path.basename(shellPath).toLowerCase();
|
||||
|
||||
// PowerShell normalization
|
||||
if (shellName === 'pwsh' || shellName === 'powershell') {
|
||||
return 'powershell';
|
||||
}
|
||||
|
||||
const supported: SupportedShell[] = ['bash', 'zsh', 'fish', 'powershell'];
|
||||
if (supported.includes(shellName as SupportedShell)) {
|
||||
return shellName as SupportedShell;
|
||||
}
|
||||
|
||||
throw new Error(`Shell '${shellName}' is not supported. Supported: ${supported.join(', ')}`);
|
||||
}
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Compile-time type checking prevents invalid shell names
|
||||
- Easy to add new shells (add to union type)
|
||||
- Type narrowing works in switch statements
|
||||
- Clear error messages for unsupported shells
|
||||
|
||||
### 6. Factory Pattern for Instantiation
|
||||
|
||||
A factory function selects the appropriate generator/installer based on shell type:
|
||||
|
||||
```typescript
|
||||
function createGenerator(shell: SupportedShell, provider: CompletionProvider): CompletionGenerator {
|
||||
switch (shell) {
|
||||
case 'bash': return new BashCompletionGenerator(COMMAND_REGISTRY, provider);
|
||||
case 'zsh': return new ZshCompletionGenerator(COMMAND_REGISTRY, provider);
|
||||
case 'fish': return new FishCompletionGenerator(COMMAND_REGISTRY, provider);
|
||||
case 'powershell': return new PowerShellCompletionGenerator(COMMAND_REGISTRY, provider);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Single point of instantiation
|
||||
- Type safety ensures exhaustive switch (TypeScript error if shell type missing)
|
||||
- Easy to inject dependencies (registry, provider)
|
||||
|
||||
## Command Structure
|
||||
|
||||
**This Proposal (Zsh-only):**
|
||||
```
|
||||
openspec completion
|
||||
├── zsh # Generate Zsh completion script
|
||||
├── install [shell] # Install Zsh completion (auto-detects or explicit zsh)
|
||||
└── uninstall [shell] # Remove Zsh completion (auto-detects or explicit zsh)
|
||||
```
|
||||
|
||||
**Future (after follow-up proposals):**
|
||||
```
|
||||
openspec completion
|
||||
├── bash # Generate Bash completion script (future)
|
||||
├── zsh # Generate Zsh completion script (this proposal)
|
||||
├── fish # Generate Fish completion script (future)
|
||||
├── powershell # Generate PowerShell completion script (future)
|
||||
├── install [shell] # Install completion (auto-detects or explicit shell)
|
||||
└── uninstall [shell] # Remove completion (auto-detects or explicit shell)
|
||||
```
|
||||
|
||||
## File Organization
|
||||
|
||||
**This Proposal (Zsh-only):**
|
||||
```
|
||||
src/
|
||||
├── commands/
|
||||
│ └── completion.ts # CLI command registration (zsh, install, uninstall)
|
||||
├── core/
|
||||
│ └── completions/
|
||||
│ ├── types.ts # Interfaces: CompletionGenerator, CommandDefinition, etc.
|
||||
│ ├── command-registry.ts # Single source of truth for OpenSpec commands
|
||||
│ ├── completion-provider.ts # Dynamic change/spec ID discovery with caching
|
||||
│ ├── factory.ts # Factory for instantiating Zsh generator/installer
|
||||
│ ├── generators/
|
||||
│ │ └── zsh-generator.ts # Zsh completion script generator
|
||||
│ └── installers/
|
||||
│ └── zsh-installer.ts # Handles Oh My Zsh + standard Zsh installation
|
||||
└── utils/
|
||||
└── shell-detection.ts # Shell detection (returns 'zsh' or throws)
|
||||
```
|
||||
|
||||
**Future additions (bash, fish, powershell):**
|
||||
- `generators/bash-generator.ts`, `fish-generator.ts`, `powershell-generator.ts`
|
||||
- `installers/bash-installer.ts`, `fish-installer.ts`, `powershell-installer.ts`
|
||||
- Update `shell-detection.ts` to support additional shell types
|
||||
|
||||
## Oh My Zsh Priority
|
||||
|
||||
Zsh implementation prioritizes Oh My Zsh because:
|
||||
1. **Popularity** - Oh My Zsh is the most popular Zsh configuration framework
|
||||
2. **Convention** - Has standard completion directory (`~/.oh-my-zsh/custom/completions/`)
|
||||
3. **Detection** - Easy to detect via `$ZSH` environment variable
|
||||
4. **Fallback** - Standard Zsh support provides compatibility when Oh My Zsh isn't installed
|
||||
|
||||
**Installation Strategy:**
|
||||
```typescript
|
||||
if (isOhMyZshInstalled()) {
|
||||
// Install to ~/.oh-my-zsh/custom/completions/_openspec
|
||||
// Automatically loaded by Oh My Zsh
|
||||
} else {
|
||||
// Install to ~/.zsh/completions/_openspec
|
||||
// Update ~/.zshrc with fpath and compinit if needed
|
||||
}
|
||||
```
|
||||
|
||||
## Caching Strategy
|
||||
|
||||
Dynamic completions cache results for 2 seconds to balance freshness with performance:
|
||||
|
||||
**Why 2 seconds?**
|
||||
- Typical tab completion sessions last < 2 seconds
|
||||
- Prevents repeated file system scans during rapid tabbing
|
||||
- Short enough to feel "live" when changes/specs are added
|
||||
- Automatic per-process expiration (no stale data across sessions)
|
||||
|
||||
**Implementation:**
|
||||
```typescript
|
||||
private changeCache: { ids: string[]; timestamp: number } | null = null;
|
||||
private readonly CACHE_TTL_MS = 2000;
|
||||
|
||||
if (this.changeCache && Date.now() - this.changeCache.timestamp < this.CACHE_TTL_MS) {
|
||||
return this.changeCache.ids; // Use cached
|
||||
}
|
||||
// Refresh cache
|
||||
```
|
||||
|
||||
## Error Handling Philosophy
|
||||
|
||||
Completions should degrade gracefully rather than break workflows:
|
||||
|
||||
1. **Unsupported shell** - Clear error with list of supported shells
|
||||
2. **Not in OpenSpec project** - Skip dynamic completions, only offer static commands
|
||||
3. **Permission errors** - Suggest alternative installation methods
|
||||
4. **Missing config directories** - Auto-create with user notification
|
||||
5. **Already installed** - Offer to reinstall/update
|
||||
6. **Not installed (during uninstall)** - Exit gracefully with informational message
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
Each component is independently testable:
|
||||
|
||||
1. **Unit Tests**
|
||||
- Shell detection with mocked `$SHELL` environment variable
|
||||
- Generator output verification (regex pattern matching)
|
||||
- Completion provider caching behavior
|
||||
- Command registry structure validation
|
||||
|
||||
2. **Integration Tests**
|
||||
- Installation to temporary test directories
|
||||
- Configuration file modifications
|
||||
- End-to-end command flow (generate → install → verify)
|
||||
|
||||
3. **Manual Testing**
|
||||
- Real shell environments (Oh My Zsh, Bash, Fish, PowerShell)
|
||||
- Tab completion behavior in OpenSpec projects
|
||||
- Dynamic change/spec ID suggestions
|
||||
- Installation/uninstallation workflows
|
||||
|
||||
## TypeScript Sugar Patterns
|
||||
|
||||
### 1. Const Assertions for Immutable Data
|
||||
```typescript
|
||||
const COMMAND_REGISTRY = [
|
||||
{ name: 'init', ... },
|
||||
{ name: 'list', ... }
|
||||
] as const;
|
||||
```
|
||||
|
||||
### 2. Discriminated Unions for Command Types
|
||||
```typescript
|
||||
type Command =
|
||||
| { type: 'simple'; name: string }
|
||||
| { type: 'with-subcommands'; name: string; subcommands: Command[] };
|
||||
```
|
||||
|
||||
### 3. Template Literal Types for Strings
|
||||
```typescript
|
||||
type ShellConfigFile = `~/.${SupportedShell}rc` | `~/.${SupportedShell}_profile`;
|
||||
```
|
||||
|
||||
### 4. Satisfies Operator for Type Validation
|
||||
```typescript
|
||||
const config = {
|
||||
shell: 'zsh',
|
||||
path: '~/.zshrc'
|
||||
} satisfies ShellConfig;
|
||||
```
|
||||
|
||||
### 5. Optional Chaining and Nullish Coalescing
|
||||
```typescript
|
||||
const path = process.env.ZSH ?? `${os.homedir()}/.oh-my-zsh`;
|
||||
```
|
||||
|
||||
### 6. Async/Await with Promise.all for Parallel Operations
|
||||
```typescript
|
||||
const [changes, specs] = await Promise.all([
|
||||
provider.getChangeIds(),
|
||||
provider.getSpecIds()
|
||||
]);
|
||||
```
|
||||
|
||||
## Scalability Considerations
|
||||
|
||||
### Adding a New Shell
|
||||
|
||||
1. Define shell in `SupportedShell` union type
|
||||
2. Create generator class implementing `CompletionGenerator`
|
||||
3. Create installer class implementing `CompletionInstaller`
|
||||
4. Add cases to factory functions
|
||||
5. Add command registration in CLI
|
||||
6. Write tests
|
||||
|
||||
**TypeScript will enforce** that all switch statements are updated (exhaustiveness checking).
|
||||
|
||||
### Adding a New Command
|
||||
|
||||
1. Add to `COMMAND_REGISTRY` with appropriate metadata
|
||||
2. All generators automatically include it
|
||||
3. Update tests to verify new command appears
|
||||
|
||||
### Changing Completion Behavior
|
||||
|
||||
Dynamic completion logic is centralized in `CompletionProvider`, making behavior changes trivial without touching shell-specific code.
|
||||
|
||||
## Trade-offs and Decisions
|
||||
|
||||
### Decision: Separate Generators vs. Template Engine
|
||||
|
||||
**Chosen:** Separate generator classes per shell
|
||||
|
||||
**Alternative:** Template engine with shell-specific templates
|
||||
|
||||
**Rationale:**
|
||||
- Shell completion syntax is fundamentally different (not just text substitution)
|
||||
- Type safety is better with classes than templates
|
||||
- Logic complexity (caching, dynamic completions) doesn't fit template paradigm
|
||||
- Easier to debug and test dedicated classes
|
||||
|
||||
### Decision: 2-Second Cache TTL
|
||||
|
||||
**Chosen:** 2-second cache
|
||||
|
||||
**Alternatives:** No cache (slow), longer cache (stale), persistent cache (complex)
|
||||
|
||||
**Rationale:**
|
||||
- Balances performance with freshness
|
||||
- Matches typical user interaction patterns
|
||||
- Simple implementation (no invalidation complexity)
|
||||
- Automatic cleanup on process exit
|
||||
|
||||
### Decision: Oh My Zsh Detection
|
||||
|
||||
**Chosen:** Check `$ZSH` env var first, then `~/.oh-my-zsh/` directory
|
||||
|
||||
**Rationale:**
|
||||
- `$ZSH` is set by Oh My Zsh initialization (reliable)
|
||||
- Directory check is fallback for non-interactive scenarios
|
||||
- Standard Zsh serves as ultimate fallback
|
||||
|
||||
### Decision: Installation Automation vs. Manual Instructions
|
||||
|
||||
**Chosen:** Automated installation with install/uninstall commands
|
||||
|
||||
**Alternative:** Generate script and provide manual installation instructions
|
||||
|
||||
**Rationale:**
|
||||
- Better user experience (one command vs. multiple manual steps)
|
||||
- Reduces errors from manual configuration
|
||||
- Aligns with user expectations for modern CLI tools
|
||||
- Still supports manual workflow via script generation to stdout
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. **Contextual Flag Completion** - Suggest only valid flags for current command
|
||||
2. **Fuzzy Matching** - Allow partial matching for change/spec IDs
|
||||
3. **Rich Descriptions** - Include "why" section in completion suggestions (shell-dependent)
|
||||
4. **Completion Stats** - Track completion usage for analytics
|
||||
5. **Custom Completion Hooks** - Allow projects to extend completions
|
||||
6. **MCP Integration** - Provide completions via Model Context Protocol
|
||||
|
||||
## References
|
||||
|
||||
- [Bash Programmable Completion](https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html)
|
||||
- [Zsh Completion System](https://zsh.sourceforge.io/Doc/Release/Completion-System.html)
|
||||
- [Fish Completions](https://fishshell.com/docs/current/completions.html)
|
||||
- [PowerShell Argument Completers](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/register-argumentcompleter)
|
||||
- [Oh My Zsh Custom Completions](https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#adding-custom-completions)
|
||||
@@ -1,29 +0,0 @@
|
||||
# Add Shell Completions
|
||||
|
||||
## Why
|
||||
|
||||
OpenSpec CLI commands lack shell completion, forcing users to remember all commands, subcommands, flags, and change/spec IDs manually. This creates friction during daily use and slows developer workflows. Shell completions are a standard expectation for modern CLI tools and significantly improve user experience through:
|
||||
- Faster command discovery via tab completion
|
||||
- Reduced cognitive load by removing memorization requirements
|
||||
- Fewer typos through validated suggestions
|
||||
- Professional polish expected of production-grade tools
|
||||
|
||||
## What Changes
|
||||
|
||||
This change adds shell completion support for the OpenSpec CLI, starting with **Zsh (including Oh My Zsh)** and establishing a scalable architecture for future shells (bash, fish, PowerShell). The implementation provides:
|
||||
|
||||
1. **New `openspec completion` command** with Zsh generation and installation/uninstallation capabilities
|
||||
2. **Native Zsh integration** that respects standard Zsh tab completion behavior (single-TAB menu navigation)
|
||||
3. **Dynamic completion providers** that discover active changes and specs from the current project
|
||||
4. **Plugin-based architecture** using TypeScript interfaces for easy extension to additional shells in future proposals
|
||||
5. **Installation automation** for Oh My Zsh (priority) and standard Zsh configurations
|
||||
6. **Context-aware suggestions** that only activate within OpenSpec-enabled projects
|
||||
|
||||
The architecture emphasizes clean TypeScript patterns, composable generators, separation of concerns between shell-specific logic and shared completion data providers, and integration with native shell completion systems. Other shells (bash, fish, PowerShell) are architecturally documented but not implemented in this proposal—they will be added in follow-up changes.
|
||||
|
||||
## Deltas
|
||||
|
||||
### Delta: New CLI completion specification
|
||||
- **Spec:** cli-completion
|
||||
- **Operation:** ADDED
|
||||
- **Description:** Defines requirements for the new `openspec completion` command including generation, installation, and shell-specific behaviors for Oh My Zsh, bash, fish, and PowerShell.
|
||||
-300
@@ -1,300 +0,0 @@
|
||||
# CLI Completion Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
The `openspec completion` command SHALL provide shell completion functionality for all OpenSpec CLI commands, flags, and dynamic values (change IDs, spec IDs), with support for Zsh (including Oh My Zsh) and a scalable architecture ready for future shells (bash, fish, PowerShell). The completion system SHALL integrate with Zsh's native completion behavior rather than attempting to customize the user experience.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Native Shell Behavior Integration
|
||||
|
||||
The completion system SHALL respect and integrate with Zsh's native completion patterns and user interaction model.
|
||||
|
||||
#### Scenario: Zsh native completion
|
||||
|
||||
- **WHEN** generating Zsh completion scripts
|
||||
- **THEN** use Zsh completion system with `_arguments`, `_describe`, and `compadd`
|
||||
- **AND** completions SHALL trigger on single TAB (standard Zsh behavior)
|
||||
- **AND** display as an interactive menu that users navigate with TAB/arrow keys
|
||||
- **AND** support Oh My Zsh's enhanced menu styling automatically
|
||||
|
||||
#### Scenario: No custom UX patterns
|
||||
|
||||
- **WHEN** implementing Zsh completion
|
||||
- **THEN** do NOT attempt to customize completion trigger behavior
|
||||
- **AND** do NOT override Zsh-specific navigation patterns
|
||||
- **AND** ensure completions feel native to experienced Zsh users
|
||||
|
||||
### Requirement: Command Structure
|
||||
|
||||
The completion command SHALL follow a subcommand pattern for generating and managing completion scripts.
|
||||
|
||||
#### Scenario: Available subcommands
|
||||
|
||||
- **WHEN** user executes `openspec completion --help`
|
||||
- **THEN** display available subcommands:
|
||||
- `zsh` - Generate Zsh completion script
|
||||
- `install [shell]` - Install completion for Zsh (auto-detects or requires explicit shell)
|
||||
- `uninstall [shell]` - Remove completion for Zsh (auto-detects or requires explicit shell)
|
||||
|
||||
### Requirement: Shell Detection
|
||||
|
||||
The completion system SHALL automatically detect the user's current shell environment.
|
||||
|
||||
#### Scenario: Detecting Zsh from environment
|
||||
|
||||
- **WHEN** no shell is explicitly specified
|
||||
- **THEN** read the `$SHELL` environment variable
|
||||
- **AND** extract the shell name from the path (e.g., `/bin/zsh` → `zsh`)
|
||||
- **AND** validate the shell is `zsh`
|
||||
- **AND** throw an error if the shell is not `zsh`, with message indicating only Zsh is currently supported
|
||||
|
||||
#### Scenario: Non-Zsh shell detection
|
||||
|
||||
- **WHEN** shell path indicates bash, fish, powershell, or other non-Zsh shell
|
||||
- **THEN** throw error: "Shell '<name>' is not supported yet. Currently supported: zsh"
|
||||
|
||||
### Requirement: Completion Generation
|
||||
|
||||
The completion command SHALL generate Zsh completion scripts on demand.
|
||||
|
||||
#### Scenario: Generating Zsh completion
|
||||
|
||||
- **WHEN** user executes `openspec completion zsh`
|
||||
- **THEN** output a complete Zsh completion script to stdout
|
||||
- **AND** include completions for all commands: init, list, show, validate, archive, view, update, change, spec, completion
|
||||
- **AND** include all command-specific flags and options
|
||||
- **AND** use Zsh's `_arguments` and `_describe` built-in functions
|
||||
- **AND** support dynamic completion for change and spec IDs
|
||||
|
||||
### Requirement: Dynamic Completions
|
||||
|
||||
The completion system SHALL provide context-aware dynamic completions for project-specific values.
|
||||
|
||||
#### Scenario: Completing change IDs
|
||||
|
||||
- **WHEN** completing arguments for commands that accept change names (show, validate, archive)
|
||||
- **THEN** discover active changes from `openspec/changes/` directory
|
||||
- **AND** exclude archived changes in `openspec/changes/archive/`
|
||||
- **AND** return change IDs as completion suggestions
|
||||
- **AND** only provide suggestions when inside an OpenSpec-enabled project
|
||||
|
||||
#### Scenario: Completing spec IDs
|
||||
|
||||
- **WHEN** completing arguments for commands that accept spec names (show, validate)
|
||||
- **THEN** discover specs from `openspec/specs/` directory
|
||||
- **AND** return spec IDs as completion suggestions
|
||||
- **AND** only provide suggestions when inside an OpenSpec-enabled project
|
||||
|
||||
#### Scenario: Completion caching
|
||||
|
||||
- **WHEN** dynamic completions are requested
|
||||
- **THEN** cache discovered change and spec IDs for 2 seconds
|
||||
- **AND** reuse cached values for subsequent requests within cache window
|
||||
- **AND** automatically refresh cache after expiration
|
||||
|
||||
#### Scenario: Project detection
|
||||
|
||||
- **WHEN** user requests completions outside an OpenSpec project
|
||||
- **THEN** skip dynamic change/spec ID completions
|
||||
- **AND** only suggest static commands and flags
|
||||
|
||||
### Requirement: Installation Automation
|
||||
|
||||
The completion command SHALL automatically install completion scripts into shell configuration files.
|
||||
|
||||
#### Scenario: Installing for Oh My Zsh
|
||||
|
||||
- **WHEN** user executes `openspec completion install zsh`
|
||||
- **THEN** detect if Oh My Zsh is installed by checking for `$ZSH` environment variable or `~/.oh-my-zsh/` directory
|
||||
- **AND** create custom completions directory at `~/.oh-my-zsh/custom/completions/` if it doesn't exist
|
||||
- **AND** write completion script to `~/.oh-my-zsh/custom/completions/_openspec`
|
||||
- **AND** ensure `~/.oh-my-zsh/custom/completions` is in `$fpath` by updating `~/.zshrc` if needed
|
||||
- **AND** display success message with instruction to run `exec zsh` or restart terminal
|
||||
|
||||
#### Scenario: Installing for standard Zsh
|
||||
|
||||
- **WHEN** user executes `openspec completion install zsh` and Oh My Zsh is not detected
|
||||
- **THEN** create completions directory at `~/.zsh/completions/` if it doesn't exist
|
||||
- **AND** write completion script to `~/.zsh/completions/_openspec`
|
||||
- **AND** add `fpath=(~/.zsh/completions $fpath)` to `~/.zshrc` if not already present
|
||||
- **AND** add `autoload -Uz compinit && compinit` to `~/.zshrc` if not already present
|
||||
- **AND** display success message with instruction to run `exec zsh` or restart terminal
|
||||
|
||||
#### Scenario: Auto-detecting Zsh for installation
|
||||
|
||||
- **WHEN** user executes `openspec completion install` without specifying a shell
|
||||
- **THEN** detect current shell using shell detection logic
|
||||
- **AND** install completion if detected shell is Zsh
|
||||
- **AND** throw error if detected shell is not Zsh
|
||||
- **AND** display which shell was detected
|
||||
|
||||
#### Scenario: Already installed
|
||||
|
||||
- **WHEN** completion is already installed for the target shell
|
||||
- **THEN** display message indicating completion is already installed
|
||||
- **AND** offer to reinstall/update by overwriting existing files
|
||||
- **AND** exit with code 0
|
||||
|
||||
### Requirement: Uninstallation
|
||||
|
||||
The completion command SHALL remove installed completion scripts and configuration.
|
||||
|
||||
#### Scenario: Uninstalling Oh My Zsh completion
|
||||
|
||||
- **WHEN** user executes `openspec completion uninstall zsh`
|
||||
- **THEN** remove `~/.oh-my-zsh/custom/completions/_openspec` if Oh My Zsh is detected
|
||||
- **AND** remove `~/.zsh/completions/_openspec` if standard Zsh setup is detected
|
||||
- **AND** optionally remove fpath modifications from `~/.zshrc` (with confirmation)
|
||||
- **AND** display success message
|
||||
|
||||
#### Scenario: Auto-detecting Zsh for uninstallation
|
||||
|
||||
- **WHEN** user executes `openspec completion uninstall` without specifying a shell
|
||||
- **THEN** detect current shell and uninstall completion if shell is Zsh
|
||||
- **AND** throw error if detected shell is not Zsh
|
||||
|
||||
#### Scenario: Not installed
|
||||
|
||||
- **WHEN** attempting to uninstall completion that isn't installed
|
||||
- **THEN** display message indicating completion is not installed
|
||||
- **AND** exit with code 0
|
||||
|
||||
### Requirement: Architecture Patterns
|
||||
|
||||
The completion implementation SHALL follow clean architecture principles with TypeScript best practices.
|
||||
|
||||
#### Scenario: Shell-specific generators
|
||||
|
||||
- **WHEN** implementing completion generators
|
||||
- **THEN** create `ZshCompletionGenerator` class for Zsh
|
||||
- **AND** implement a common `CompletionGenerator` interface with methods:
|
||||
- `generate(): string` - Returns complete shell script
|
||||
- `getInstallPath(): string` - Returns target installation path
|
||||
- `getConfigFile(): string` - Returns shell configuration file path
|
||||
- **AND** design interface to be extensible for future shells (bash, fish, powershell)
|
||||
|
||||
#### Scenario: Dynamic completion providers
|
||||
|
||||
- **WHEN** implementing dynamic completions
|
||||
- **THEN** create a `CompletionProvider` class that encapsulates project discovery logic
|
||||
- **AND** implement methods:
|
||||
- `getChangeIds(): Promise<string[]>` - Discovers active change IDs
|
||||
- `getSpecIds(): Promise<string[]>` - Discovers spec IDs
|
||||
- `isOpenSpecProject(): boolean` - Checks if current directory is OpenSpec-enabled
|
||||
- **AND** implement caching with 2-second TTL using class properties
|
||||
|
||||
#### Scenario: Command registry
|
||||
|
||||
- **WHEN** defining completable commands
|
||||
- **THEN** create a centralized `CommandDefinition` type with properties:
|
||||
- `name: string` - Command name
|
||||
- `description: string` - Help text
|
||||
- `flags: FlagDefinition[]` - Available flags
|
||||
- `acceptsChangeId: boolean` - Whether command takes change ID argument
|
||||
- `acceptsSpecId: boolean` - Whether command takes spec ID argument
|
||||
- `subcommands?: CommandDefinition[]` - Nested subcommands
|
||||
- **AND** export a `COMMAND_REGISTRY` constant with all command definitions
|
||||
- **AND** generators consume this registry to ensure consistency
|
||||
|
||||
#### Scenario: Type-safe shell detection
|
||||
|
||||
- **WHEN** implementing shell detection
|
||||
- **THEN** define a `SupportedShell` type as literal type: `'zsh'`
|
||||
- **AND** implement `detectShell()` function that returns 'zsh' or throws error
|
||||
- **AND** design type to be extensible (e.g., future: `'bash' | 'zsh' | 'fish' | 'powershell'`)
|
||||
|
||||
### Requirement: Error Handling
|
||||
|
||||
The completion command SHALL provide clear error messages for common failure scenarios.
|
||||
|
||||
#### Scenario: Unsupported shell
|
||||
|
||||
- **WHEN** user requests completion for unsupported shell (bash, fish, powershell, etc.)
|
||||
- **THEN** display error message: "Shell '<name>' is not supported yet. Currently supported: zsh"
|
||||
- **AND** exit with code 1
|
||||
|
||||
#### Scenario: Permission errors during installation
|
||||
|
||||
- **WHEN** installation fails due to file permission issues
|
||||
- **THEN** display clear error message indicating permission problem
|
||||
- **AND** suggest using appropriate permissions or alternative installation method
|
||||
- **AND** exit with code 1
|
||||
|
||||
#### Scenario: Missing shell configuration directory
|
||||
|
||||
- **WHEN** expected shell configuration directory doesn't exist
|
||||
- **THEN** create the directory automatically (with user notification)
|
||||
- **AND** proceed with installation
|
||||
|
||||
#### Scenario: Shell not detected
|
||||
|
||||
- **WHEN** `openspec completion install` cannot detect current shell or detects non-Zsh shell
|
||||
- **THEN** display error: "Could not detect Zsh. Please specify explicitly: openspec completion install zsh"
|
||||
- **AND** exit with code 1
|
||||
|
||||
### Requirement: Output Format
|
||||
|
||||
The completion command SHALL provide machine-parseable and human-readable output.
|
||||
|
||||
#### Scenario: Script generation output
|
||||
|
||||
- **WHEN** generating completion script to stdout
|
||||
- **THEN** output only the completion script content (no extra messages)
|
||||
- **AND** allow redirection to files: `openspec completion zsh > /path/to/_openspec`
|
||||
|
||||
#### Scenario: Installation success output
|
||||
|
||||
- **WHEN** installation completes successfully
|
||||
- **THEN** display formatted success message with:
|
||||
- Checkmark indicator
|
||||
- Installation location
|
||||
- Next steps (shell reload instructions)
|
||||
- **AND** use colors when terminal supports it (unless `--no-color` is set)
|
||||
|
||||
#### Scenario: Verbose installation output
|
||||
|
||||
- **WHEN** user provides `--verbose` flag during installation
|
||||
- **THEN** display detailed steps:
|
||||
- Shell detection result
|
||||
- Target file paths
|
||||
- Configuration modifications
|
||||
- File creation confirmations
|
||||
|
||||
### Requirement: Testing Support
|
||||
|
||||
The completion implementation SHALL be testable with unit and integration tests.
|
||||
|
||||
#### Scenario: Mock shell environment
|
||||
|
||||
- **WHEN** writing tests for shell detection
|
||||
- **THEN** allow overriding `$SHELL` environment variable
|
||||
- **AND** use dependency injection for file system operations
|
||||
|
||||
#### Scenario: Generator output verification
|
||||
|
||||
- **WHEN** testing completion generators
|
||||
- **THEN** verify generated scripts contain expected patterns
|
||||
- **AND** test that command registry is properly consumed
|
||||
- **AND** ensure dynamic completion placeholders are present
|
||||
|
||||
#### Scenario: Installation simulation
|
||||
|
||||
- **WHEN** testing installation logic
|
||||
- **THEN** use temporary test directories instead of actual home directories
|
||||
- **AND** verify file creation without modifying real shell configurations
|
||||
- **AND** test path resolution logic independently
|
||||
|
||||
## Not in Scope
|
||||
|
||||
The following shells are **architecturally documented but not implemented** in this proposal. They will be added in future proposals:
|
||||
|
||||
- **Bash completion** - Will use bash-completion framework with `_init_completion`, `compgen`, and `COMPREPLY`
|
||||
- **Fish completion** - Will use Fish's declarative `complete -c` syntax
|
||||
- **PowerShell completion** - Will use `Register-ArgumentCompleter` with completion result objects
|
||||
|
||||
The plugin-based architecture (CompletionGenerator interface, command registry, dynamic providers) is designed to make adding these shells straightforward in follow-up changes.
|
||||
|
||||
## Why
|
||||
|
||||
Shell completions are essential for professional CLI tools and significantly improve developer experience by reducing friction, errors, and cognitive load during daily workflows.
|
||||
@@ -1,81 +0,0 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## Phase 1: Foundation & Architecture
|
||||
|
||||
- [x] Create `src/utils/shell-detection.ts` with `SupportedShell` type and `detectShell()` function
|
||||
- [x] Create `src/core/completions/types.ts` with interfaces: `CompletionGenerator`, `CommandDefinition`, `FlagDefinition`
|
||||
- [x] Create `src/core/completions/command-registry.ts` with `COMMAND_REGISTRY` constant defining all OpenSpec commands, flags, and metadata
|
||||
- [x] Create `src/core/completions/completion-provider.ts` with `CompletionProvider` class for dynamic change/spec ID discovery with 2-second caching
|
||||
- [x] Write tests for shell detection (`test/utils/shell-detection.test.ts`)
|
||||
- [x] Write tests for completion provider (`test/core/completions/completion-provider.test.ts`)
|
||||
|
||||
## Phase 2: Zsh Completion (Oh My Zsh Priority)
|
||||
|
||||
- [x] Create `src/core/completions/generators/zsh-generator.ts` implementing `CompletionGenerator` interface
|
||||
- [x] Implement Zsh script generation using `_arguments` and `_describe` patterns
|
||||
- [x] Add dynamic completion logic for change/spec IDs using completion provider
|
||||
- [x] Test Zsh generator output (`test/core/completions/generators/zsh-generator.test.ts`)
|
||||
- [x] Create `src/core/completions/installers/zsh-installer.ts` with Oh My Zsh and standard Zsh support
|
||||
- [x] Implement Oh My Zsh detection (`$ZSH` env var or `~/.oh-my-zsh/` directory)
|
||||
- [x] Implement installation to `~/.oh-my-zsh/custom/completions/_openspec` for Oh My Zsh
|
||||
- [x] Implement fallback installation to `~/.zsh/completions/_openspec` with `fpath` updates
|
||||
- [x] Test Zsh installer logic with mocked file system (`test/core/completions/installers/zsh-installer.test.ts`)
|
||||
|
||||
## Phase 3: CLI Command Implementation
|
||||
|
||||
- [x] Create `src/commands/completion.ts` with `CompletionCommand` class
|
||||
- [x] Register `completion` command in `src/cli/index.ts` with subcommands: generate, install, uninstall
|
||||
- [x] Implement `generateSubcommand()` that outputs Zsh script to stdout
|
||||
- [x] Implement `installSubcommand(shell?: 'zsh')` with auto-detection for Zsh-only
|
||||
- [x] Implement `uninstallSubcommand(shell?: 'zsh')` for removing Zsh completions
|
||||
- [x] Add `--verbose` flag support for detailed installation output
|
||||
- [x] Add error handling with clear messages: "Shell '<name>' is not supported yet. Currently supported: zsh"
|
||||
- [x] Test completion command integration (`test/commands/completion.test.ts`)
|
||||
|
||||
## Phase 4: Integration & Polish
|
||||
|
||||
- [x] Create factory pattern in `src/core/completions/factory.ts` to instantiate Zsh generator/installer (extensible for future shells)
|
||||
- [x] Add `completion` command to command registry for self-referential completion
|
||||
- [x] Implement dynamic completion helper functions in Zsh generator (`_openspec_complete_changes`, `_openspec_complete_specs`, `_openspec_complete_items`)
|
||||
- [x] Add 'shell' positional type for completion command arguments
|
||||
- [x] Test completion generation with dynamic helpers
|
||||
- [x] Test completion install/uninstall flow
|
||||
- [x] Verify all tests pass (97 completion tests, 340 total tests)
|
||||
- [x] Implement auto-install via npm postinstall script
|
||||
- [x] Add safety checks (CI detection, opt-out flag)
|
||||
- [x] Handle Oh My Zsh vs standard Zsh installation paths
|
||||
- [x] Add test script for postinstall validation
|
||||
- [x] Document auto-install behavior and opt-out in README
|
||||
- [ ] Manually test Zsh completion in Oh My Zsh environment (install, test tab completion, uninstall)
|
||||
- [ ] Manually test Zsh completion in standard Zsh environment
|
||||
- [ ] Test dynamic change/spec ID completion in real OpenSpec projects
|
||||
- [ ] Verify completion cache behavior (2-second TTL)
|
||||
- [ ] Test behavior outside OpenSpec projects (should skip dynamic completions)
|
||||
- [x] Update `openspec --help` output to include completion command (automatically done via Commander)
|
||||
|
||||
## Phase 5: Edge Cases & Error Handling
|
||||
|
||||
- [ ] Test and handle permission errors during installation
|
||||
- [ ] Test and handle missing shell configuration directories (auto-create with notification)
|
||||
- [ ] Test "already installed" detection and reinstall flow
|
||||
- [ ] Test "not installed" detection during uninstall
|
||||
- [ ] Verify `--no-color` flag is respected in completion command output
|
||||
- [ ] Test shell detection failure scenarios with helpful error messages
|
||||
- [ ] Ensure graceful handling when `$SHELL` is unset or invalid
|
||||
- [ ] Test non-Zsh shells get clear "not supported yet" error messages
|
||||
- [ ] Test generator output can be redirected to files without corruption
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Phase 2 depends on Phase 1 (foundation must exist first)
|
||||
- Phase 3 depends on Phase 2 (CLI needs Zsh generator working)
|
||||
- Phase 4 depends on Phase 3 (integration requires CLI + Zsh implementation)
|
||||
- Phase 5 depends on Phase 4 (edge case testing after core functionality works)
|
||||
|
||||
## Future Work (Not in This Proposal)
|
||||
|
||||
- **Bash completions** - Create bash-generator.ts and bash-installer.ts in follow-up proposal
|
||||
- **Fish completions** - Create fish-generator.ts and fish-installer.ts in follow-up proposal
|
||||
- **PowerShell completions** - Create powershell-generator.ts and powershell-installer.ts in follow-up proposal
|
||||
|
||||
The architecture is designed to make adding these shells straightforward by implementing the `CompletionGenerator` interface.
|
||||
@@ -1,105 +0,0 @@
|
||||
## Context
|
||||
|
||||
OpenSpec needs a standard location for user-level configuration that works across platforms and follows established conventions. This will serve as the foundation for settings, feature flags, and future artifacts like workflows or templates.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Provide a single, well-defined location for global config
|
||||
- Follow XDG Base Directory Specification (widely adopted by CLI tools)
|
||||
- Support cross-platform usage (Unix, macOS, Windows)
|
||||
- Keep implementation minimal - just the foundation
|
||||
- Enable future expansion (cache, state, workflows)
|
||||
|
||||
**Non-Goals:**
|
||||
- Project-local config override (not in scope)
|
||||
- Config file migration tooling
|
||||
- Config validation CLI commands
|
||||
- Multiple config profiles
|
||||
|
||||
## Decisions
|
||||
|
||||
### Path Resolution Strategy
|
||||
|
||||
**Decision:** Use XDG Base Directory Specification with platform fallbacks.
|
||||
|
||||
```
|
||||
Unix/macOS: $XDG_CONFIG_HOME/openspec/ or ~/.config/openspec/
|
||||
Windows: %APPDATA%/openspec/
|
||||
```
|
||||
|
||||
**Rationale:**
|
||||
- XDG is the de facto standard for CLI tools (used by gh, bat, ripgrep, etc.)
|
||||
- Environment variable override allows user customization
|
||||
- Windows uses its native convention (%APPDATA%) for better integration
|
||||
|
||||
**Alternatives considered:**
|
||||
- `~/.openspec/` - Simple but clutters home directory
|
||||
- `~/Library/Application Support/` on macOS - Overkill for a CLI tool
|
||||
|
||||
### Config File Format
|
||||
|
||||
**Decision:** JSON (`config.json`)
|
||||
|
||||
**Rationale:**
|
||||
- Native Node.js support (no dependencies)
|
||||
- Human-readable and editable
|
||||
- Type-safe with TypeScript
|
||||
- Matches project.md's "minimal dependencies" principle
|
||||
|
||||
**Alternatives considered:**
|
||||
- YAML - Requires dependency, more error-prone to edit
|
||||
- TOML - Less common in Node.js ecosystem
|
||||
- Environment variables only - Too limited for structured settings
|
||||
|
||||
### Config Schema
|
||||
|
||||
**Decision:** Flat structure with typed fields, start minimal.
|
||||
|
||||
```typescript
|
||||
interface GlobalConfig {
|
||||
featureFlags?: Record<string, boolean>;
|
||||
}
|
||||
```
|
||||
|
||||
**Rationale:**
|
||||
- `featureFlags` enables controlled rollout of new features
|
||||
- Optional fields with defaults avoid breaking changes
|
||||
- Flat structure is easy to understand and extend
|
||||
|
||||
### Loading Strategy
|
||||
|
||||
**Decision:** Read from disk on each call, no caching.
|
||||
|
||||
```typescript
|
||||
export function getGlobalConfig(): GlobalConfig {
|
||||
return loadConfigFromDisk();
|
||||
}
|
||||
```
|
||||
|
||||
**Rationale:**
|
||||
- CLI commands are short-lived; caching adds complexity without benefit
|
||||
- Reading a small JSON file is ~1ms; negligible overhead
|
||||
- Always returns fresh data; no cache invalidation concerns
|
||||
- Simpler implementation
|
||||
|
||||
### Directory Creation
|
||||
|
||||
**Decision:** Create directory only when saving, not when reading.
|
||||
|
||||
**Rationale:**
|
||||
- Don't create empty directories on read operations
|
||||
- Users who never save config won't have unnecessary directories
|
||||
- Aligns with principle of least surprise
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| Config file corruption | Return defaults on parse error, log warning |
|
||||
| Permissions issues | Check write permissions before save, clear error message |
|
||||
| Future schema changes | Use optional fields, add version field if needed later |
|
||||
|
||||
## Open Questions
|
||||
|
||||
None - this proposal is intentionally minimal.
|
||||
@@ -1,20 +0,0 @@
|
||||
## Why
|
||||
|
||||
OpenSpec currently has no mechanism for user-level global settings or feature flags. As the CLI grows, we need a standard location to store user preferences, experimental features, and other configuration that persists across projects. Following XDG Base Directory Specification provides a well-understood, cross-platform approach.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add new `src/core/global-config.ts` module with:
|
||||
- Path resolution following XDG Base Directory spec (`$XDG_CONFIG_HOME/openspec/` or fallback)
|
||||
- Cross-platform support (Unix, macOS, Windows)
|
||||
- Lazy config loading with sensible defaults
|
||||
- TypeScript types for config shape
|
||||
- Export a global config directory path getter for future use (workflows, templates, cache)
|
||||
- Initial config schema supports 1-2 settings/feature flags only
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: New `global-config` capability (no existing specs modified)
|
||||
- Affected code:
|
||||
- New `src/core/global-config.ts`
|
||||
- Update `src/core/index.ts` to export new module
|
||||
@@ -1,76 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Global Config Directory Path
|
||||
|
||||
The system SHALL resolve the global configuration directory path following XDG Base Directory Specification with platform-specific fallbacks.
|
||||
|
||||
#### Scenario: Unix/macOS with XDG_CONFIG_HOME set
|
||||
- **WHEN** `$XDG_CONFIG_HOME` environment variable is set to `/custom/config`
|
||||
- **THEN** `getGlobalConfigDir()` returns `/custom/config/openspec`
|
||||
|
||||
#### Scenario: Unix/macOS without XDG_CONFIG_HOME
|
||||
- **WHEN** `$XDG_CONFIG_HOME` environment variable is not set
|
||||
- **AND** the platform is Unix or macOS
|
||||
- **THEN** `getGlobalConfigDir()` returns `~/.config/openspec` (expanded to absolute path)
|
||||
|
||||
#### Scenario: Windows platform
|
||||
- **WHEN** the platform is Windows
|
||||
- **AND** `%APPDATA%` is set to `C:\Users\User\AppData\Roaming`
|
||||
- **THEN** `getGlobalConfigDir()` returns `C:\Users\User\AppData\Roaming\openspec`
|
||||
|
||||
### Requirement: Global Config Loading
|
||||
|
||||
The system SHALL load global configuration from the config directory with sensible defaults when the config file does not exist or cannot be parsed.
|
||||
|
||||
#### Scenario: Config file exists and is valid
|
||||
- **WHEN** `config.json` exists in the global config directory
|
||||
- **AND** the file contains valid JSON matching the config schema
|
||||
- **THEN** `getGlobalConfig()` returns the parsed configuration
|
||||
|
||||
#### Scenario: Config file does not exist
|
||||
- **WHEN** `config.json` does not exist in the global config directory
|
||||
- **THEN** `getGlobalConfig()` returns the default configuration
|
||||
- **AND** no directory or file is created
|
||||
|
||||
#### Scenario: Config file is invalid JSON
|
||||
- **WHEN** `config.json` exists but contains invalid JSON
|
||||
- **THEN** `getGlobalConfig()` returns the default configuration
|
||||
- **AND** a warning is logged to stderr
|
||||
|
||||
### Requirement: Global Config Saving
|
||||
|
||||
The system SHALL save global configuration to the config directory, creating the directory if it does not exist.
|
||||
|
||||
#### Scenario: Save config to new directory
|
||||
- **WHEN** `saveGlobalConfig(config)` is called
|
||||
- **AND** the global config directory does not exist
|
||||
- **THEN** the directory is created
|
||||
- **AND** `config.json` is written with the provided configuration
|
||||
|
||||
#### Scenario: Save config to existing directory
|
||||
- **WHEN** `saveGlobalConfig(config)` is called
|
||||
- **AND** the global config directory already exists
|
||||
- **THEN** `config.json` is written (overwriting if exists)
|
||||
|
||||
### Requirement: Default Configuration
|
||||
|
||||
The system SHALL provide a default configuration that is used when no config file exists.
|
||||
|
||||
#### Scenario: Default config structure
|
||||
- **WHEN** no config file exists
|
||||
- **THEN** the default configuration includes an empty `featureFlags` object
|
||||
|
||||
### Requirement: Config Schema Evolution
|
||||
|
||||
The system SHALL merge loaded configuration with default values to ensure new config fields are available even when loading older config files.
|
||||
|
||||
#### Scenario: Config file missing new fields
|
||||
- **WHEN** `config.json` exists with `{ "featureFlags": {} }`
|
||||
- **AND** the current schema includes a new field `defaultAiTool`
|
||||
- **THEN** `getGlobalConfig()` returns `{ featureFlags: {}, defaultAiTool: <default> }`
|
||||
- **AND** the loaded values take precedence over defaults for fields that exist in both
|
||||
|
||||
#### Scenario: Config file has extra unknown fields
|
||||
- **WHEN** `config.json` contains fields not in the current schema
|
||||
- **THEN** the unknown fields are preserved in the returned configuration
|
||||
- **AND** no error or warning is raised
|
||||
@@ -1,26 +0,0 @@
|
||||
## 1. Core Implementation
|
||||
|
||||
- [x] 1.1 Create `src/core/global-config.ts` with path resolution
|
||||
- Implement `getGlobalConfigDir()` following XDG spec
|
||||
- Support `$XDG_CONFIG_HOME` environment variable override
|
||||
- Platform-specific fallbacks (Unix: `~/.config/`, Windows: `%APPDATA%`)
|
||||
- [x] 1.2 Define TypeScript interfaces for config shape
|
||||
- `GlobalConfig` interface with optional fields
|
||||
- Start minimal: just `featureFlags?: Record<string, boolean>`
|
||||
- [x] 1.3 Implement config loading with defaults
|
||||
- `getGlobalConfig()` - reads config.json if exists, merges with defaults
|
||||
- No directory/file creation on read (lazy initialization)
|
||||
- [x] 1.4 Implement config saving
|
||||
- `saveGlobalConfig(config)` - writes config.json, creates directory if needed
|
||||
|
||||
## 2. Integration
|
||||
|
||||
- [x] 2.1 Export new module from `src/core/index.ts`
|
||||
- [x] 2.2 Add constants for config file name and directory name
|
||||
|
||||
## 3. Testing
|
||||
|
||||
- [x] 3.1 Manual testing of path resolution on current platform
|
||||
- [x] 3.2 Test with/without `$XDG_CONFIG_HOME` set
|
||||
- [x] 3.3 Test config load when file doesn't exist (should return defaults)
|
||||
- [x] 3.4 Unit tests in `test/core/global-config.test.ts` (18 tests)
|
||||
@@ -1,13 +0,0 @@
|
||||
## Why
|
||||
The Cline implementation was architecturally incorrect. According to Cline's official documentation, Cline uses workflows for on-demand automation and rules for behavioral guidelines. The OpenSpec slash commands are procedural workflows (scaffold → implement → archive), not behavioral rules, so they should be placed in `.clinerules/workflows/` instead of `.clinerules/`.
|
||||
|
||||
## What Changes
|
||||
- Update ClineSlashCommandConfigurator to use `.clinerules/workflows/` paths instead of `.clinerules/` paths
|
||||
- Update all tests to expect the correct workflow file locations
|
||||
- Update README.md documentation to reflect workflows instead of rules
|
||||
- **BREAKING**: Existing Cline users will need to re-run `openspec init` to get the corrected workflow files
|
||||
|
||||
## Impact
|
||||
- Affected specs: cli-init (corrected Cline workflow paths)
|
||||
- Affected code: `src/core/configurators/slash/cline.ts`, test files, README.md
|
||||
- Modified files: `.clinerules/workflows/openspec-*.md` (moved from `.clinerules/openspec-*.md`)
|
||||
@@ -1,11 +0,0 @@
|
||||
# Delta for CLI Init
|
||||
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Slash Command Configuration
|
||||
|
||||
#### Scenario: Generating slash commands for Cline
|
||||
- **WHEN** the user selects Cline during initialization
|
||||
- **THEN** create `.clinerules/workflows/openspec-proposal.md`, `.clinerules/workflows/openspec-apply.md`, and `.clinerules/workflows/openspec-archive.md`
|
||||
- **AND** populate each file from shared templates so command text matches other tools
|
||||
- **AND** include Cline-specific Markdown heading frontmatter
|
||||
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
|
||||
@@ -1,13 +0,0 @@
|
||||
## 1. Update ClineSlashCommandConfigurator
|
||||
- [x] Change FILE_PATHS in `src/core/configurators/slash/cline.ts` from `.clinerules/openspec-*.md` to `.clinerules/workflows/openspec-*.md`
|
||||
|
||||
## 2. Update Tests
|
||||
- [x] Update "should refresh existing Cline rule files" test in `test/core/update.test.ts` to use workflow paths
|
||||
- [x] Update "should create Cline rule files with templates" test in `test/core/init.test.ts` to use workflow paths
|
||||
|
||||
## 3. Update Documentation
|
||||
- [x] Update README.md table to show "Workflows in `.clinerules/workflows/` directory" for Cline
|
||||
|
||||
## 4. Validate Changes
|
||||
- [x] Ensure all tests pass with the new paths
|
||||
- [x] Verify the change follows OpenSpec conventions
|
||||
@@ -0,0 +1,12 @@
|
||||
## 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 shared helpers.
|
||||
- Expand coverage to cross-shell/OS matrices once the spawn harness is stable, ensuring both the direct `node dist/cli/index.js` invocation and the bin shim are exercised 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.
|
||||
|
||||
## Impact
|
||||
- Tests: add `test/cli-e2e` spawn suite, helpers, and fixture usage updates; adjust `vitest.setup.ts` as needed.
|
||||
- Tooling: update GitHub Actions workflows to add shell/OS matrices and (optionally) a packaging install check where network is available.
|
||||
- Docs: keep `CROSS-SHELL-PLAN.md` aligned with the phased rollout and record any limitations called out during execution.
|
||||
@@ -0,0 +1,13 @@
|
||||
## 1. Phase 1 – Stabilize Local Spawn Coverage
|
||||
- [ ] 1.1 Update `vitest.setup.ts` and helpers so the CLI build runs once and `runCLI` executes `node dist/cli.js` with non-TTY defaults.
|
||||
- [ ] 1.2 Reuse the minimal fixture set (`tmp-init` or copy) to seed initial spawn tests for help/version, a happy-path `validate`, and a representative error flow.
|
||||
- [ ] 1.3 Document the Phase 1 coverage details in `CROSS-SHELL-PLAN.md`, noting any outstanding gaps.
|
||||
|
||||
## 2. Phase 2 – Expand Cross-Shell Validation
|
||||
- [ ] 2.1 Exercise both entry points (`node dist/cli.js`, `bin/openspec.js`) in the spawn suite and add diagnostics for shell/OS context.
|
||||
- [ ] 2.2 Extend GitHub Actions to run the spawn suite across a matrix of shells (bash, zsh, fish, pwsh, cmd) on macOS, Linux, and Windows runners.
|
||||
|
||||
## 3. Phase 3 – Package Validation (Optional)
|
||||
- [ ] 3.1 Add a simple CI job on runners with registry access that runs `pnpm pack`, installs the tarball into a temp workspace (e.g., `pnpm add --no-save`), and executes `pnpm exec openspec --version`.
|
||||
- [ ] 3.2 If network-restricted environments can’t exercise installs, document the limitation in `CROSS-SHELL-PLAN.md` and skip the job there.
|
||||
- [ ] 3.3 Close out remaining hardening items from the original cross-shell plan (e.g., `.gitattributes`, chmod enforcement, SIGINT follow-ups) and update the plan accordingly.
|
||||
+1
-1
@@ -21,5 +21,5 @@
|
||||
|
||||
## 5. Optional (Not Needed Now)
|
||||
- [x] 5.1 Add optional root param to discovery helpers (default process.cwd())
|
||||
|
||||
- [ ] 5.2 Consider threading root through command constructors if ever required
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user