Full Code of Fission-AI/OpenSpec for AI

main afdca0d5dab1 cached
644 files
2.9 MB
788.0k tokens
737 symbols
1 requests
Download .txt
Showing preview only (3,128K chars total). Download the full file or copy to clipboard to get everything.
Repository: Fission-AI/OpenSpec
Branch: main
Commit: afdca0d5dab1
Files: 644
Total size: 2.9 MB

Directory structure:
gitextract_ovuhyth0/

├── .actrc
├── .changeset/
│   ├── README.md
│   ├── config.json
│   ├── fix-opencode-commands-directory.md
│   └── graceful-status-no-changes.md
├── .coderabbit.yaml
├── .devcontainer/
│   ├── README.md
│   └── devcontainer.json
├── .github/
│   ├── CODEOWNERS
│   └── workflows/
│       ├── README.md
│       ├── ci.yml
│       └── release-prepare.yml
├── .gitignore
├── AGENTS.md
├── CHANGELOG.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── README_OLD.md
├── bin/
│   └── openspec.js
├── build.js
├── docs/
│   ├── cli.md
│   ├── commands.md
│   ├── concepts.md
│   ├── customization.md
│   ├── getting-started.md
│   ├── installation.md
│   ├── migration-guide.md
│   ├── multi-language.md
│   ├── opsx.md
│   ├── supported-tools.md
│   └── workflows.md
├── eslint.config.js
├── flake.nix
├── openspec/
│   ├── changes/
│   │   ├── IMPLEMENTATION_ORDER.md
│   │   ├── add-artifact-regeneration-support/
│   │   │   └── proposal.md
│   │   ├── add-change-stacking-awareness/
│   │   │   ├── .openspec.yaml
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   ├── change-creation/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── change-stacking-workflow/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-change/
│   │   │   │   │   └── spec.md
│   │   │   │   └── openspec-conventions/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── add-global-install-scope/
│   │   │   ├── .openspec.yaml
│   │   │   ├── design.md
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   ├── ai-tool-paths/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-config/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-init/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-update/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── command-generation/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── global-config/
│   │   │   │   │   └── spec.md
│   │   │   │   └── installation-scope/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── add-qa-smoke-harness/
│   │   │   ├── .openspec.yaml
│   │   │   ├── proposal.md
│   │   │   └── specs/
│   │   │       └── developer-qa-workflow/
│   │   │           └── spec.md
│   │   ├── add-tool-command-surface-capabilities/
│   │   │   ├── .openspec.yaml
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   ├── cli-init/
│   │   │   │   │   └── spec.md
│   │   │   │   └── cli-update/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── archive/
│   │   │   ├── 2025-01-11-add-update-command/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-01-13-add-list-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-list/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-05-initialize-typescript-project/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-06-add-init-command/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-06-adopt-future-state-storage/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-11-add-complexity-guidelines/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── openspec-docs/
│   │   │   │   │       └── README.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-13-add-archive-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-archive/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-13-add-diff-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-diff/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-change-commands/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-change/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-list/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-interactive-show-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-change/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-show/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-spec/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-skip-specs-archive-option/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-archive/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-spec-commands/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-spec/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-zod-validation/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-archive/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-diff/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-adopt-delta-based-changes/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-archive/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-diff/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-adopt-verb-noun-cli-structure/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-list/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-bulk-validation-interactive-selection/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-change/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-spec/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-validate/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-fix-update-tool-selection/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-improve-validate-error-messages/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-validate/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-structured-spec-format/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-12-add-view-dashboard-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-view/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-add-agents-md-config/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-add-multi-agent-init/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-add-slash-command-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-improve-cli-e2e-plan/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-improve-deterministic-tests/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-improve-init-onboarding/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-remove-diff-command/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-sort-active-changes-by-progress/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-view/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-update-agent-file-name/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-update/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-update-agent-instructions/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-update-markdown-parser-crlf/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-validate/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-codex-slash-command-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-github-copilot-prompts/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-kilocode-workflows/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-non-interactive-init-options/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-windsurf-workflows/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-enhance-validation-error-messages/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-validate/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-improve-agent-instruction-usability/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── docs-agent-instructions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-slim-root-agents-file/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-update-cli-init-enter-selection/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-update-cli-init-root-agents/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-update-release-automation/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-22-add-archive-command-arguments/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-22-add-cline-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-22-add-crush-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-22-add-factory-slash-commands/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-11-06-add-shell-completions/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-completion/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-20-add-global-config-dir/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── global-config/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-21-add-config-command/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-config/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-23-extend-shell-completions/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-completion/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-24-add-artifact-graph-core/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── artifact-graph/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-25-add-change-manager/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── change-creation/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-28-add-artifact-workflow-cli/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-artifact-workflow/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-28-add-instruction-loader/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── instruction-loader/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-28-restructure-schema-directories/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── artifact-graph/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-29-unify-change-state-model/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-artifact-workflow/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-view/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-30-add-antigravity-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-30-fix-cline-workflows-implementation/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-add-agent-schema-selection/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-add-per-change-schema-metadata/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-artifact-workflow/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-add-specs-apply-command/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── specs-sync-skill/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-make-apply-instructions-schema-aware/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-artifact-workflow/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-opsx-archive-command/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── opsx-archive-skill/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-07-add-nix-flake-support/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── nix-flake-support/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-09-add-flake-update-script/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── flake-update-script/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-09-add-posthog-analytics/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── global-config/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── telemetry/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-09-fix-codebuddy-frontmatter-fields/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-15-add-nix-ci-validation/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── ci-nix-validation/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-30-opencode-command-references/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── README.md
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── no-changes.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-add-feedback-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-feedback/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-add-opsx-onboard-skill/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── opsx-onboard-skill/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-add-verify-skill/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── opsx-verify-skill/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-merge-init-experimental/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── legacy-cleanup/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-multi-provider-skill-generation/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── ai-tool-paths/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-artifact-workflow/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── command-generation/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-project-config/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── config-loading/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── context-injection/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── rules-injection/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── schema-resolution/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-project-local-schemas/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── schema-resolution/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   └── 2026-02-17-schema-management-cli/
│   │   │       ├── .openspec.yaml
│   │   │       ├── design.md
│   │   │       ├── proposal.md
│   │   │       ├── specs/
│   │   │       │   ├── schema-fork-command/
│   │   │       │   │   └── spec.md
│   │   │       │   ├── schema-init-command/
│   │   │       │   │   └── spec.md
│   │   │       │   ├── schema-validate-command/
│   │   │       │   │   └── spec.md
│   │   │       │   └── schema-which-command/
│   │   │       │       └── spec.md
│   │   │       └── tasks.md
│   │   ├── fix-opencode-commands-directory/
│   │   │   ├── .openspec.yaml
│   │   │   ├── design.md
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   └── command-generation/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── graceful-status-no-changes/
│   │   │   ├── .openspec.yaml
│   │   │   ├── design.md
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   └── graceful-status-empty/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── schema-alias-support/
│   │   │   ├── .openspec.yaml
│   │   │   └── proposal.md
│   │   ├── simplify-skill-installation/
│   │   │   ├── .openspec.yaml
│   │   │   ├── design.md
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   ├── cli-init/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-update/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── profiles/
│   │   │   │   │   └── spec.md
│   │   │   │   └── propose-workflow/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   └── unify-template-generation-pipeline/
│   │       ├── .openspec.yaml
│   │       ├── design.md
│   │       ├── proposal.md
│   │       ├── specs/
│   │       │   └── template-artifact-pipeline/
│   │       │       └── spec.md
│   │       └── tasks.md
│   ├── config.yaml
│   ├── explorations/
│   │   ├── explore-workflow-ux.md
│   │   └── workspace-architecture.md
│   └── specs/
│       ├── ai-tool-paths/
│       │   └── spec.md
│       ├── artifact-graph/
│       │   └── spec.md
│       ├── change-creation/
│       │   └── spec.md
│       ├── ci-nix-validation/
│       │   └── spec.md
│       ├── cli-archive/
│       │   └── spec.md
│       ├── cli-artifact-workflow/
│       │   └── spec.md
│       ├── cli-change/
│       │   └── spec.md
│       ├── cli-completion/
│       │   └── spec.md
│       ├── cli-config/
│       │   └── spec.md
│       ├── cli-feedback/
│       │   └── spec.md
│       ├── cli-init/
│       │   └── spec.md
│       ├── cli-list/
│       │   └── spec.md
│       ├── cli-show/
│       │   └── spec.md
│       ├── cli-spec/
│       │   └── spec.md
│       ├── cli-update/
│       │   └── spec.md
│       ├── cli-validate/
│       │   └── spec.md
│       ├── cli-view/
│       │   └── spec.md
│       ├── command-generation/
│       │   └── spec.md
│       ├── config-loading/
│       │   └── spec.md
│       ├── context-injection/
│       │   └── spec.md
│       ├── docs-agent-instructions/
│       │   └── spec.md
│       ├── global-config/
│       │   └── spec.md
│       ├── instruction-loader/
│       │   └── spec.md
│       ├── legacy-cleanup/
│       │   └── spec.md
│       ├── openspec-conventions/
│       │   └── spec.md
│       ├── opsx-archive-skill/
│       │   └── spec.md
│       ├── opsx-onboard-skill/
│       │   └── spec.md
│       ├── opsx-verify-skill/
│       │   └── spec.md
│       ├── rules-injection/
│       │   └── spec.md
│       ├── schema-fork-command/
│       │   └── spec.md
│       ├── schema-init-command/
│       │   └── spec.md
│       ├── schema-resolution/
│       │   └── spec.md
│       ├── schema-validate-command/
│       │   └── spec.md
│       ├── schema-which-command/
│       │   └── spec.md
│       ├── specs-sync-skill/
│       │   └── spec.md
│       └── telemetry/
│           └── spec.md
├── openspec-parallel-merge-plan.md
├── package.json
├── schemas/
│   └── spec-driven/
│       ├── schema.yaml
│       └── templates/
│           ├── design.md
│           ├── proposal.md
│           ├── spec.md
│           └── tasks.md
├── scripts/
│   ├── README.md
│   ├── pack-version-check.mjs
│   ├── postinstall.js
│   ├── test-postinstall.sh
│   └── update-flake.sh
├── src/
│   ├── cli/
│   │   └── index.ts
│   ├── commands/
│   │   ├── change.ts
│   │   ├── completion.ts
│   │   ├── config.ts
│   │   ├── feedback.ts
│   │   ├── schema.ts
│   │   ├── show.ts
│   │   ├── spec.ts
│   │   ├── validate.ts
│   │   └── workflow/
│   │       ├── index.ts
│   │       ├── instructions.ts
│   │       ├── new-change.ts
│   │       ├── schemas.ts
│   │       ├── shared.ts
│   │       ├── status.ts
│   │       └── templates.ts
│   ├── core/
│   │   ├── archive.ts
│   │   ├── artifact-graph/
│   │   │   ├── graph.ts
│   │   │   ├── index.ts
│   │   │   ├── instruction-loader.ts
│   │   │   ├── resolver.ts
│   │   │   ├── schema.ts
│   │   │   ├── state.ts
│   │   │   └── types.ts
│   │   ├── available-tools.ts
│   │   ├── command-generation/
│   │   │   ├── adapters/
│   │   │   │   ├── amazon-q.ts
│   │   │   │   ├── antigravity.ts
│   │   │   │   ├── auggie.ts
│   │   │   │   ├── claude.ts
│   │   │   │   ├── cline.ts
│   │   │   │   ├── codebuddy.ts
│   │   │   │   ├── codex.ts
│   │   │   │   ├── continue.ts
│   │   │   │   ├── costrict.ts
│   │   │   │   ├── crush.ts
│   │   │   │   ├── cursor.ts
│   │   │   │   ├── factory.ts
│   │   │   │   ├── gemini.ts
│   │   │   │   ├── github-copilot.ts
│   │   │   │   ├── iflow.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── kilocode.ts
│   │   │   │   ├── kiro.ts
│   │   │   │   ├── opencode.ts
│   │   │   │   ├── pi.ts
│   │   │   │   ├── qoder.ts
│   │   │   │   ├── qwen.ts
│   │   │   │   ├── roocode.ts
│   │   │   │   └── windsurf.ts
│   │   │   ├── generator.ts
│   │   │   ├── index.ts
│   │   │   ├── registry.ts
│   │   │   └── types.ts
│   │   ├── completions/
│   │   │   ├── command-registry.ts
│   │   │   ├── completion-provider.ts
│   │   │   ├── factory.ts
│   │   │   ├── generators/
│   │   │   │   ├── bash-generator.ts
│   │   │   │   ├── fish-generator.ts
│   │   │   │   ├── powershell-generator.ts
│   │   │   │   └── zsh-generator.ts
│   │   │   ├── installers/
│   │   │   │   ├── bash-installer.ts
│   │   │   │   ├── fish-installer.ts
│   │   │   │   ├── powershell-installer.ts
│   │   │   │   └── zsh-installer.ts
│   │   │   ├── templates/
│   │   │   │   ├── bash-templates.ts
│   │   │   │   ├── fish-templates.ts
│   │   │   │   ├── powershell-templates.ts
│   │   │   │   └── zsh-templates.ts
│   │   │   └── types.ts
│   │   ├── config-prompts.ts
│   │   ├── config-schema.ts
│   │   ├── config.ts
│   │   ├── converters/
│   │   │   └── json-converter.ts
│   │   ├── global-config.ts
│   │   ├── index.ts
│   │   ├── init.ts
│   │   ├── legacy-cleanup.ts
│   │   ├── list.ts
│   │   ├── migration.ts
│   │   ├── parsers/
│   │   │   ├── change-parser.ts
│   │   │   ├── markdown-parser.ts
│   │   │   └── requirement-blocks.ts
│   │   ├── profile-sync-drift.ts
│   │   ├── profiles.ts
│   │   ├── project-config.ts
│   │   ├── schemas/
│   │   │   ├── base.schema.ts
│   │   │   ├── change.schema.ts
│   │   │   ├── index.ts
│   │   │   └── spec.schema.ts
│   │   ├── shared/
│   │   │   ├── index.ts
│   │   │   ├── skill-generation.ts
│   │   │   └── tool-detection.ts
│   │   ├── specs-apply.ts
│   │   ├── styles/
│   │   │   └── palette.ts
│   │   ├── templates/
│   │   │   ├── index.ts
│   │   │   ├── skill-templates.ts
│   │   │   ├── types.ts
│   │   │   └── workflows/
│   │   │       ├── apply-change.ts
│   │   │       ├── archive-change.ts
│   │   │       ├── bulk-archive-change.ts
│   │   │       ├── continue-change.ts
│   │   │       ├── explore.ts
│   │   │       ├── feedback.ts
│   │   │       ├── ff-change.ts
│   │   │       ├── new-change.ts
│   │   │       ├── onboard.ts
│   │   │       ├── propose.ts
│   │   │       ├── sync-specs.ts
│   │   │       └── verify-change.ts
│   │   ├── update.ts
│   │   ├── validation/
│   │   │   ├── constants.ts
│   │   │   ├── types.ts
│   │   │   └── validator.ts
│   │   └── view.ts
│   ├── index.ts
│   ├── prompts/
│   │   └── searchable-multi-select.ts
│   ├── telemetry/
│   │   ├── config.ts
│   │   └── index.ts
│   ├── ui/
│   │   ├── ascii-patterns.ts
│   │   └── welcome-screen.ts
│   └── utils/
│       ├── change-metadata.ts
│       ├── change-utils.ts
│       ├── command-references.ts
│       ├── file-system.ts
│       ├── index.ts
│       ├── interactive.ts
│       ├── item-discovery.ts
│       ├── match.ts
│       ├── shell-detection.ts
│       └── task-progress.ts
├── test/
│   ├── cli-e2e/
│   │   └── basic.test.ts
│   ├── commands/
│   │   ├── artifact-workflow.test.ts
│   │   ├── change.interactive-show.test.ts
│   │   ├── change.interactive-validate.test.ts
│   │   ├── completion.test.ts
│   │   ├── config-profile.test.ts
│   │   ├── config.test.ts
│   │   ├── feedback.test.ts
│   │   ├── schema.test.ts
│   │   ├── show.test.ts
│   │   ├── spec.interactive-show.test.ts
│   │   ├── spec.interactive-validate.test.ts
│   │   ├── spec.test.ts
│   │   ├── validate.enriched-output.test.ts
│   │   └── validate.test.ts
│   ├── core/
│   │   ├── archive.test.ts
│   │   ├── artifact-graph/
│   │   │   ├── graph.test.ts
│   │   │   ├── instruction-loader.test.ts
│   │   │   ├── resolver.test.ts
│   │   │   ├── schema.test.ts
│   │   │   ├── state.test.ts
│   │   │   └── workflow.integration.test.ts
│   │   ├── available-tools.test.ts
│   │   ├── command-generation/
│   │   │   ├── adapters.test.ts
│   │   │   ├── generator.test.ts
│   │   │   ├── registry.test.ts
│   │   │   └── types.test.ts
│   │   ├── commands/
│   │   │   ├── change-command.list.test.ts
│   │   │   └── change-command.show-validate.test.ts
│   │   ├── completions/
│   │   │   ├── completion-provider.test.ts
│   │   │   ├── generators/
│   │   │   │   ├── bash-generator.test.ts
│   │   │   │   ├── fish-generator.test.ts
│   │   │   │   ├── powershell-generator.test.ts
│   │   │   │   └── zsh-generator.test.ts
│   │   │   └── installers/
│   │   │       ├── bash-installer.test.ts
│   │   │       ├── fish-installer.test.ts
│   │   │       ├── powershell-installer.test.ts
│   │   │       └── zsh-installer.test.ts
│   │   ├── config-schema.test.ts
│   │   ├── converters/
│   │   │   └── json-converter.test.ts
│   │   ├── global-config.test.ts
│   │   ├── init.test.ts
│   │   ├── legacy-cleanup.test.ts
│   │   ├── list.test.ts
│   │   ├── migration.test.ts
│   │   ├── parsers/
│   │   │   ├── change-parser.test.ts
│   │   │   └── markdown-parser.test.ts
│   │   ├── profile-sync-drift.test.ts
│   │   ├── profiles.test.ts
│   │   ├── project-config.test.ts
│   │   ├── shared/
│   │   │   ├── skill-generation.test.ts
│   │   │   └── tool-detection.test.ts
│   │   ├── templates/
│   │   │   └── skill-templates-parity.test.ts
│   │   ├── update.test.ts
│   │   ├── validation.enriched-messages.test.ts
│   │   ├── validation.test.ts
│   │   └── view.test.ts
│   ├── fixtures/
│   │   └── tmp-init/
│   │       └── openspec/
│   │           ├── changes/
│   │           │   └── c1/
│   │           │       ├── proposal.md
│   │           │       └── specs/
│   │           │           └── alpha/
│   │           │               └── spec.md
│   │           └── specs/
│   │               └── alpha/
│   │                   └── spec.md
│   ├── helpers/
│   │   └── run-cli.ts
│   ├── prompts/
│   │   └── searchable-multi-select.test.ts
│   ├── specs/
│   │   └── source-specs-normalization.test.ts
│   ├── telemetry/
│   │   ├── config.test.ts
│   │   └── index.test.ts
│   └── utils/
│       ├── change-metadata.test.ts
│       ├── change-utils.test.ts
│       ├── command-references.test.ts
│       ├── file-system.test.ts
│       ├── interactive.test.ts
│       ├── marker-updates.test.ts
│       └── shell-detection.test.ts
├── tsconfig.json
├── vitest.config.ts
└── vitest.setup.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .actrc
================================================
-P ubuntu-latest=catthehacker/ubuntu:act-latest


================================================
FILE: .changeset/README.md
================================================
# Changesets

This directory is managed by [Changesets](https://github.com/changesets/changesets).

## Quick Start

```bash
pnpm changeset
```

Follow the prompts to select version bump type and describe your changes.

## Workflow

1. **Add a changeset** — Run `pnpm changeset` locally before or after your PR
2. **Version PR** — CI opens/updates a "Version Packages" PR when changesets merge to main
3. **Release** — Merging the Version PR triggers npm publish and GitHub Release

> **Note:** Contributors only need to run `pnpm changeset`. Versioning (`changeset version`) and publishing happen automatically in CI.

## Template

Use this structure for your changeset content:

```markdown
---
"@fission-ai/openspec": patch
---

### New Features

- **Feature name** — What users can now do

### Bug Fixes

- Fixed issue where X happened when Y

### Breaking Changes

- `oldMethod()` has been removed, use `newMethod()` instead

### Deprecations

- `legacyOption` is deprecated and will be removed in v2.0

### Other

- Internal refactoring of X for better performance
```

Include only the sections relevant to your change.

## Version Bump Guide

| Type | When to use | Example |
|------|-------------|---------|
| `patch` | Bug fixes, small improvements | Fixed crash when config missing |
| `minor` | New features, non-breaking additions | Added `--verbose` flag |
| `major` | Breaking changes, removed features | Renamed `init` to `setup` |

## When to Create a Changeset

**Create one for:**
- New features or commands
- Bug fixes that affect users
- Breaking changes or deprecations
- Performance improvements users would notice

**Skip for:**
- Documentation-only changes
- Test additions/fixes
- Internal refactoring with no user impact
- CI/tooling changes

## Writing Good Descriptions

**Do:** Write for users, not developers
```markdown
- **Shell completions** — Tab completion now available for Bash, Fish, and PowerShell
```

**Don't:** Write implementation details
```markdown
- Added ShellCompletionGenerator class with Bash/Fish/PowerShell subclasses
```

**Do:** Explain the impact
```markdown
- Fixed config loading to respect `XDG_CONFIG_HOME` on Linux
```

**Don't:** Just reference the fix
```markdown
- Fixed #123
```


================================================
FILE: .changeset/config.json
================================================
{
  "$schema": "https://unpkg.com/@changesets/config/schema.json",
  "changelog": [
    "@changesets/changelog-github",
    { "repo": "Fission-AI/OpenSpec" }
  ],
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "public",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": []
}



================================================
FILE: .changeset/fix-opencode-commands-directory.md
================================================
---
"@fission-ai/openspec": patch
---

fix: OpenCode adapter now uses `.opencode/commands/` (plural) to match OpenCode's official directory convention. Fixes #748.


================================================
FILE: .changeset/graceful-status-no-changes.md
================================================
---
"@fission-ai/openspec": patch
---

fix: `openspec status` now exits gracefully when no changes exist instead of throwing a fatal error. Fixes #714.


================================================
FILE: .coderabbit.yaml
================================================
# 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:
      - ".*"

================================================
FILE: .devcontainer/README.md
================================================
# 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


================================================
FILE: .devcontainer/devcontainer.json
================================================
{
  "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...'"
}


================================================
FILE: .github/CODEOWNERS
================================================
# Default code ownership
* @TabishB


================================================
FILE: .github/workflows/README.md
================================================
# Github Workflows

## Testing CI Locally

Test GitHub Actions workflows locally using [act](https://nektosact.com/):

```bash
# Test all PR checks
act pull_request

# Test specific job
act pull_request -j nix-flake-validate

# Dry run to see what would execute
act pull_request --dryrun
```

The `.actrc` file configures act to use the appropriate Docker image.




================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

jobs:
  # Detect which files changed to enable path-based filtering
  changes:
    name: Detect changes
    runs-on: ubuntu-latest
    outputs:
      nix: ${{ steps.filter.outputs.nix }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Check for Nix-related changes
        uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            nix:
              - 'flake.nix'
              - 'flake.lock'
              - 'package.json'
              - 'pnpm-lock.yaml'
              - 'scripts/update-flake.sh'
              - '.github/workflows/ci.yml'

  test_pr:
    name: Test
    runs-on: ubuntu-latest
    timeout-minutes: 10
    if: github.event_name == 'pull_request'

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build project
        run: pnpm run build

      - name: Run tests
        run: pnpm test

      - name: Upload test coverage
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report-pr
          path: coverage/
          retention-days: 7

  test_matrix:
    name: Test (${{ matrix.label }})
    runs-on: ${{ matrix.os }}
    timeout-minutes: 15
    if: github.event_name != 'pull_request'
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            shell: bash
            label: linux-bash
          - os: macos-latest
            shell: bash
            label: macos-bash
          - os: windows-latest
            shell: pwsh
            label: windows-pwsh

    defaults:
      run:
        shell: ${{ matrix.shell }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'

      - name: Print environment diagnostics
        run: |
          node -p "JSON.stringify({ platform: process.platform, arch: process.arch, shell: process.env.SHELL || process.env.ComSpec || '' })"

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build project
        run: pnpm run build

      - name: Run tests
        run: pnpm test

      - name: Upload test coverage
        if: matrix.os == 'ubuntu-latest'
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report-main
          path: coverage/
          retention-days: 7

  lint:
    name: Lint & Type Check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build project
        run: pnpm run build

      - name: Type check
        run: pnpm exec tsc --noEmit

      - name: Lint
        run: pnpm lint

      - name: Check for build artifacts
        run: |
          if [ ! -d "dist" ]; then
            echo "Error: dist directory not found after build"
            exit 1
          fi
          if [ ! -f "dist/cli/index.js" ]; then
            echo "Error: CLI entry point not found"
            exit 1
          fi

  nix-flake-validate:
    name: Nix Flake Validation
    runs-on: ubuntu-latest
    timeout-minutes: 10
    needs: changes
    if: needs.changes.outputs.nix == 'true'
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Nix
        uses: DeterminateSystems/nix-installer-action@v21

      - name: Setup Nix cache
        uses: DeterminateSystems/magic-nix-cache-action@v13

      - name: Build with Nix
        run: nix build

      - name: Verify build output
        run: |
          if [ ! -e "result" ]; then
            echo "Error: Nix build output 'result' symlink not found"
            exit 1
          fi
          if [ ! -f "result/bin/openspec" ]; then
            echo "Error: openspec binary not found in build output"
            exit 1
          fi
          echo "✅ Build output verified"

      - name: Test binary execution
        run: |
          VERSION=$(nix run . -- --version)
          echo "OpenSpec version: $VERSION"
          if [ -z "$VERSION" ]; then
            echo "Error: Version command returned empty output"
            exit 1
          fi
          echo "✅ Binary execution successful"

      - name: Validate update script
        run: |
          echo "Testing update-flake.sh script..."
          bash scripts/update-flake.sh
          echo "✅ Update script executed successfully"

      - name: Check flake.nix modifications
        run: |
          if git diff --quiet flake.nix; then
            echo "ℹ️  flake.nix unchanged (hash already up-to-date)"
          else
            echo "✅ flake.nix was updated by script"
            git diff flake.nix
          fi

      - name: Restore flake.nix
        if: always()
        run: git checkout -- flake.nix || true

  validate-changesets:
    name: Validate Changesets
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Validate changesets
        run: |
          if command -v changeset &> /dev/null; then
            pnpm exec changeset status --since=origin/main
          else
            echo "Changesets not configured, skipping validation"
          fi

  required-checks-pr:
    name: All checks passed
    runs-on: ubuntu-latest
    needs: [test_pr, lint, nix-flake-validate]
    if: always() && github.event_name == 'pull_request'
    steps:
      - name: Verify all checks passed
        run: |
          if [[ "${{ needs.test_pr.result }}" != "success" ]]; then
            echo "Test job failed"
            exit 1
          fi
          if [[ "${{ needs.lint.result }}" != "success" ]]; then
            echo "Lint job failed"
            exit 1
          fi
          # Nix validation may be skipped if no Nix-related files changed
          if [[ "${{ needs.nix-flake-validate.result }}" != "success" && "${{ needs.nix-flake-validate.result }}" != "skipped" ]]; then
            echo "Nix flake validation job failed"
            exit 1
          fi
          if [[ "${{ needs.nix-flake-validate.result }}" == "skipped" ]]; then
            echo "Nix flake validation skipped (no Nix-related changes)"
          fi
          echo "All required checks passed!"

  required-checks-main:
    name: All checks passed
    runs-on: ubuntu-latest
    needs: [test_matrix, lint, nix-flake-validate]
    if: always() && github.event_name != 'pull_request'
    steps:
      - name: Verify all checks passed
        run: |
          if [[ "${{ needs.test_matrix.result }}" != "success" ]]; then
            echo "Matrix test job failed"
            exit 1
          fi
          if [[ "${{ needs.lint.result }}" != "success" ]]; then
            echo "Lint job failed"
            exit 1
          fi
          # Nix validation may be skipped if no Nix-related files changed
          if [[ "${{ needs.nix-flake-validate.result }}" != "success" && "${{ needs.nix-flake-validate.result }}" != "skipped" ]]; then
            echo "Nix flake validation job failed"
            exit 1
          fi
          if [[ "${{ needs.nix-flake-validate.result }}" == "skipped" ]]; then
            echo "Nix flake validation skipped (no Nix-related changes)"
          fi
          echo "All required checks passed!"


================================================
FILE: .github/workflows/release-prepare.yml
================================================
name: Release (prepare)

on:
  push:
    branches: [main]

permissions:
  contents: write
  pull-requests: write
  id-token: write # Required for npm OIDC trusted publishing

concurrency:
  group: release-${{ github.ref }}
  cancel-in-progress: false

jobs:
  prepare:
    if: github.repository == 'Fission-AI/OpenSpec'
    runs-on: ubuntu-latest
    steps:
      # Generate GitHub App token first - used for checkout and changesets
      # This allows git operations to trigger CI workflows on the version PR
      # (GITHUB_TOKEN cannot trigger workflows by design)
      - name: Generate GitHub App Token
        id: app-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ vars.APP_ID }}
          private-key: ${{ secrets.APP_PRIVATE_KEY }}

      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ steps.app-token.outputs.token }}

      - uses: pnpm/action-setup@v4
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: '24' # Node 24 includes npm 11.5.1+ required for OIDC
          cache: 'pnpm'
          registry-url: 'https://registry.npmjs.org'

      - run: pnpm install --frozen-lockfile

      # Opens/updates the Version Packages PR; publishes when the Version PR merges
      - name: Create/Update Version PR
        id: changesets
        uses: changesets/action@v1
        with:
          title: 'chore(release): version packages'
          createGithubReleases: true
          # Use CI-specific release script: relies on version PR having been merged
          # so package.json already contains the bumped version.
          publish: pnpm run release:ci
        env:
          GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
          # npm authentication handled via OIDC trusted publishing (no token needed)


================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.*
!.env.example

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt

# Build output
dist/

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Sveltekit cache directory
.svelte-kit/

# vitepress build output
**/.vitepress/dist

# vitepress cache directory
**/.vitepress/cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# Firebase cache directory
.firebase/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v3
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Vite logs files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*


# Claude
.claude/
CLAUDE.md
.DS_Store

# Pnpm
.pnpm-store/
result

# OpenCode
.opencode/
opencode.json

# Codex
.codex/


================================================
FILE: AGENTS.md
================================================


================================================
FILE: CHANGELOG.md
================================================
# @fission-ai/openspec

## 1.2.0

### Minor Changes

- [#747](https://github.com/Fission-AI/OpenSpec/pull/747) [`1e94443`](https://github.com/Fission-AI/OpenSpec/commit/1e94443a3551b228eecbc89e95d96d3b9600a192) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features

  - **Profile system** — Choose between `core` (4 essential workflows) and `custom` (pick any subset) profiles to control which skills get installed. Manage profiles with the new `openspec config profile` command
  - **Propose workflow** — New one-step workflow creates a complete change proposal with design, specs, and tasks from a single request — no need to run `new` then `ff` separately
  - **AI tool auto-detection** — `openspec init` now scans your project for existing tool directories (`.claude/`, `.cursor/`, etc.) and pre-selects detected tools
  - **Pi (pi.dev) support** — Pi coding agent is now a supported tool with prompt and skill generation
  - **Kiro support** — AWS Kiro IDE is now a supported tool with prompt and skill generation
  - **Sync prunes deselected workflows** — `openspec update` now removes command files and skill directories for workflows you've deselected, keeping your project clean
  - **Config drift warning** — `openspec config list` warns when global config is out of sync with the current project

  ### Bug Fixes

  - Fixed onboard preflight giving a false "not initialized" error on freshly initialized projects
  - Fixed archive workflow stopping mid-way when syncing — it now properly resumes after sync completes
  - Added Windows PowerShell alternatives for onboard shell commands

## 1.1.1

### Patch Changes

- [#627](https://github.com/Fission-AI/OpenSpec/pull/627) [`afb73cf`](https://github.com/Fission-AI/OpenSpec/commit/afb73cf9ec59c6f8b26d0c538c0218c203ba3c56) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes

  - **OpenCode command references** — Command references in generated files now use the correct `/opsx-` hyphen format instead of `/opsx:` colon format, ensuring commands work properly in OpenCode

## 1.1.0

### Minor Changes

- [#625](https://github.com/Fission-AI/OpenSpec/pull/625) [`53081fb`](https://github.com/Fission-AI/OpenSpec/commit/53081fb2a26ec66d2950ae0474b9a56cbc5b5a76) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes

  - **Codex global path support** — Codex adapter now resolves global paths correctly, fixing workflow file generation when run outside the project directory (#622)
  - **Archive operations on cross-device or restricted paths** — Archive now falls back to copy+remove when rename fails with EPERM or EXDEV errors, fixing failures on networked/external drives (#605)
  - **Slash command hints in workflow messages** — Workflow completion messages now display helpful slash command hints for next steps (#603)
  - **Windsurf workflow file path** — Updated Windsurf adapter to use the correct `workflows` directory instead of the legacy `commands` path (#610)

### Patch Changes

- [#550](https://github.com/Fission-AI/OpenSpec/pull/550) [`86d2e04`](https://github.com/Fission-AI/OpenSpec/commit/86d2e04cae76a999dbd1b4571f52fa720036be0c) Thanks [@jerome-benoit](https://github.com/jerome-benoit)! - ### Improvements

  - **Nix flake maintenance** — Version now read dynamically from package.json, reducing manual sync issues
  - **Nix build optimization** — Source filtering excludes node_modules and artifacts, improving build times
  - **update-flake.sh script** — Detects when hash is already correct, skipping unnecessary rebuilds

  ### Other

  - Updated Nix CI actions to latest versions (nix-installer v21, magic-nix-cache v13)

## 1.0.2

### Patch Changes

- [#596](https://github.com/Fission-AI/OpenSpec/pull/596) [`e91568d`](https://github.com/Fission-AI/OpenSpec/commit/e91568deb948073f3e9d9bb2d2ab5bf8080d6cf4) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes

  - Clarified spec naming convention — Specs should be named after capabilities (`specs/<capability>/spec.md`), not changes
  - Fixed task checkbox format guidance — Tasks now clearly require `- [ ]` checkbox format for apply phase tracking

## 1.0.1

### Patch Changes

- [#587](https://github.com/Fission-AI/OpenSpec/pull/587) [`943e0d4`](https://github.com/Fission-AI/OpenSpec/commit/943e0d41026d034de66b9442d1276c01b293eb2b) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes

  - Fixed incorrect archive path in onboarding documentation — the template now shows the correct path `openspec/changes/archive/YYYY-MM-DD-<name>/` instead of the incorrect `openspec/archive/YYYY-MM-DD--<name>/`

## 1.0.0

### Major Changes

- [#578](https://github.com/Fission-AI/OpenSpec/pull/578) [`0cc9d90`](https://github.com/Fission-AI/OpenSpec/commit/0cc9d9025af367faa1688a7b2606a2549053cd3f) Thanks [@TabishB](https://github.com/TabishB)! - ## OpenSpec 1.0 — The OPSX Release

  The workflow has been rebuilt from the ground up. OPSX replaces the old phase-locked `/openspec:*` commands with an action-based system where AI understands what artifacts exist, what's ready to create, and what each action unlocks.

  ### Breaking Changes

  - **Old commands removed** — `/openspec:proposal`, `/openspec:apply`, and `/openspec:archive` no longer exist
  - **Config files removed** — Tool-specific instruction files (`CLAUDE.md`, `.cursorrules`, `AGENTS.md`, `project.md`) are no longer generated
  - **Migration** — Run `openspec init` to upgrade. Legacy artifacts are detected and cleaned up with confirmation.

  ### From Static Prompts to Dynamic Instructions

  **Before:** AI received the same static instructions every time, regardless of project state.

  **Now:** Instructions are dynamically assembled from three layers:

  1. **Context** — Project background from `config.yaml` (tech stack, conventions)
  2. **Rules** — Artifact-specific constraints (e.g., "propose spike tasks for unknowns")
  3. **Template** — The actual structure for the output file

  AI queries the CLI for real-time state: which artifacts exist, what's ready to create, what dependencies are satisfied, and what each action unlocks.

  ### From Phase-Locked to Action-Based

  **Before:** Linear workflow — proposal → apply → archive. Couldn't easily go back or iterate.

  **Now:** Flexible actions on a change. Edit any artifact anytime. The artifact graph tracks state automatically.

  | Command              | What it does                                         |
  | -------------------- | ---------------------------------------------------- |
  | `/opsx:explore`      | Think through ideas before committing to a change    |
  | `/opsx:new`          | Start a new change                                   |
  | `/opsx:continue`     | Create one artifact at a time (step-through)         |
  | `/opsx:ff`           | Create all planning artifacts at once (fast-forward) |
  | `/opsx:apply`        | Implement tasks                                      |
  | `/opsx:verify`       | Validate implementation matches artifacts            |
  | `/opsx:sync`         | Sync delta specs to main specs                       |
  | `/opsx:archive`      | Archive completed change                             |
  | `/opsx:bulk-archive` | Archive multiple changes with conflict detection     |
  | `/opsx:onboard`      | Guided 15-minute walkthrough of complete workflow    |

  ### From Text Merging to Semantic Spec Syncing

  **Before:** Spec updates required manual merging or wholesale file replacement.

  **Now:** Delta specs use semantic markers that AI understands:

  - `## ADDED Requirements` — New requirements to add
  - `## MODIFIED Requirements` — Partial updates (add scenario without copying existing ones)
  - `## REMOVED Requirements` — Delete with reason and migration notes
  - `## RENAMED Requirements` — Rename preserving content

  Archive parses these at the requirement level, not brittle header matching.

  ### From Scattered Files to Agent Skills

  **Before:** 8+ config files at project root + slash commands scattered across 21 tool-specific locations with different formats.

  **Now:** Single `.claude/skills/` directory with YAML-fronted markdown files. Auto-detected by Claude Code, Cursor, Windsurf. Cross-editor compatible.

  ### New Features

  - **Onboarding skill** — `/opsx:onboard` walks new users through their first complete change with codebase-aware task suggestions and step-by-step narration (11 phases, ~15 minutes)

  - **21 AI tools supported** — Claude Code, Cursor, Windsurf, Continue, Gemini CLI, GitHub Copilot, Amazon Q, Cline, RooCode, Kilo Code, Auggie, CodeBuddy, Qoder, Qwen, CoStrict, Crush, Factory, OpenCode, Antigravity, iFlow, and Codex

  - **Interactive setup** — `openspec init` shows animated welcome screen and searchable multi-select for choosing tools. Pre-selects already-configured tools for easy refresh.

  - **Customizable schemas** — Define custom artifact workflows in `openspec/schemas/` without touching package code. Teams can share workflows via version control.

  ### Bug Fixes

  - Fixed Claude Code YAML parsing failure when command names contained colons
  - Fixed task file parsing to handle trailing whitespace on checkbox lines
  - Fixed JSON instruction output to separate context/rules from template — AI was copying constraint blocks into artifact files

  ### Documentation

  - New getting-started guide, CLI reference, concepts documentation
  - Removed misleading "edit mid-flight and continue" claims that weren't implemented
  - Added migration guide for upgrading from pre-OPSX versions

## 0.23.0

### Minor Changes

- [#540](https://github.com/Fission-AI/OpenSpec/pull/540) [`c4cfdc7`](https://github.com/Fission-AI/OpenSpec/commit/c4cfdc7c499daef30d8a218f5f59b8d9e5adb754) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features

  - **Bulk archive skill** — Archive multiple completed changes in a single operation with `/opsx:bulk-archive`. Includes batch validation, spec conflict detection, and consolidated confirmation

  ### Other

  - **Simplified setup** — Config creation now uses sensible defaults with helpful comments instead of interactive prompts

## 0.22.0

### Minor Changes

- [#530](https://github.com/Fission-AI/OpenSpec/pull/530) [`33466b1`](https://github.com/Fission-AI/OpenSpec/commit/33466b1e2a6798bdd6d0e19149173585b0612e6f) Thanks [@TabishB](https://github.com/TabishB)! - Add project-level configuration, project-local schemas, and schema management commands

  **New Features**

  - **Project-level configuration** — Configure OpenSpec behavior per-project via `openspec/config.yaml`, including custom rules injection, context files, and schema resolution settings
  - **Project-local schemas** — Define custom artifact schemas within your project's `openspec/schemas/` directory for project-specific workflows
  - **Schema management commands** — New `openspec schema` commands (`list`, `show`, `export`, `validate`) for inspecting and managing artifact schemas (experimental)

  **Bug Fixes**

  - Fixed config loading to handle null `rules` field in project configuration

## 0.21.0

### Minor Changes

- [#516](https://github.com/Fission-AI/OpenSpec/pull/516) [`b5a8847`](https://github.com/Fission-AI/OpenSpec/commit/b5a884748be6156a7bb140b4941cfec4f20a9fc8) Thanks [@TabishB](https://github.com/TabishB)! - Add feedback command and Nix flake support

  **New Features**

  - **Feedback command** — Submit feedback directly from the CLI with `openspec feedback`, which creates GitHub Issues with automatic metadata inclusion and graceful fallback for manual submission
  - **Nix flake support** — Install and develop openspec using Nix with the new `flake.nix`, including automated flake maintenance and CI validation

  **Bug Fixes**

  - **Explore mode guardrails** — Explore mode now explicitly prevents implementation, keeping the focus on thinking and discovery while still allowing artifact creation

  **Other**

  - Improved change inference in `opsx apply` — automatically detects the target change from conversation context or prompts when ambiguous
  - Streamlined archive sync assessment with clearer delta spec location guidance

## 0.20.0

### Minor Changes

- [#502](https://github.com/Fission-AI/OpenSpec/pull/502) [`9db74aa`](https://github.com/Fission-AI/OpenSpec/commit/9db74aa5ac6547efadaed795217cfa17444f2004) Thanks [@TabishB](https://github.com/TabishB)! - Add `/opsx:verify` command and fix vitest process storms

  **New Features**

  - **`/opsx:verify` command** — Validate that change implementations match their specifications

  **Bug Fixes**

  - Fixed vitest process storms by capping worker parallelism
  - Fixed agent workflows to use non-interactive mode for validation commands
  - Fixed PowerShell completions generator to remove trailing commas

## 0.19.0

### Minor Changes

- eb152eb: Add Continue IDE support, shell completions, and `/opsx:explore` command

  **New Features**

  - **Continue IDE support** – OpenSpec now generates slash commands for [Continue](https://continue.dev/), expanding editor integration options alongside Cursor, Windsurf, Claude Code, and others
  - **Shell completions for Bash, Fish, and PowerShell** – Run `openspec completion install` to set up tab completion in your preferred shell
  - **`/opsx:explore` command** – A new thinking partner mode for exploring ideas and investigating problems before committing to changes
  - **Codebuddy slash command improvements** – Updated frontmatter format for better compatibility

  **Bug Fixes**

  - Shell completions now correctly offer parent-level flags (like `--help`) when a command has subcommands
  - Fixed Windows compatibility issues in tests

  **Other**

  - Added optional anonymous usage statistics to help understand how OpenSpec is used. This is **opt-out** by default – set `OPENSPEC_TELEMETRY=0` or `DO_NOT_TRACK=1` to disable. Only command names and version are collected; no arguments, file paths, or content. Automatically disabled in CI environments.

## 0.18.0

### Minor Changes

- 8dfd824: Add OPSX experimental workflow commands and enhanced artifact system

  **New Commands:**

  - `/opsx:ff` - Fast-forward through artifact creation, generating all needed artifacts in one go
  - `/opsx:sync` - Sync delta specs from a change to main specs
  - `/opsx:archive` - Archive completed changes with smart sync check

  **Artifact Workflow Enhancements:**

  - Schema-aware apply instructions with inline guidance and XML output
  - Agent schema selection for experimental artifact workflow
  - Per-change schema metadata via `.openspec.yaml` files
  - Agent Skills for experimental artifact workflow
  - Instruction loader for template loading and change context
  - Restructured schemas as directories with templates

  **Improvements:**

  - Enhanced list command with last modified timestamps and sorting
  - Change creation utilities for better workflow support

  **Fixes:**

  - Normalize paths for cross-platform glob compatibility
  - Allow REMOVED requirements when creating new spec files

## 0.17.2

### Patch Changes

- 455c65f: Fix `--no-interactive` flag in validate command to properly disable spinner, preventing hangs in pre-commit hooks and CI environments

## 0.17.1

### Patch Changes

- a2757e7: Fix pre-commit hook hang issue in config command by using dynamic import for @inquirer/prompts

  The config command was causing pre-commit hooks to hang indefinitely due to stdin event listeners being registered at module load time. This fix converts the static import to a dynamic import that only loads inquirer when the `config reset` command is actually used interactively.

  Also adds ESLint with a rule to prevent static @inquirer imports, avoiding future regressions.

## 0.17.0

### Minor Changes

- 2e71835: Add `openspec config` command and Oh-my-zsh completions

  **New Features**

  - Add `openspec config` command for managing global configuration settings
  - Implement global config directory with XDG Base Directory specification support
  - Add Oh-my-zsh shell completions support for enhanced CLI experience

  **Bug Fixes**

  - Fix hang in pre-commit hooks by using dynamic imports
  - Respect XDG_CONFIG_HOME environment variable on all platforms
  - Resolve Windows compatibility issues in zsh-installer tests
  - Align cli-completion spec with implementation
  - Remove hardcoded agent field from slash commands

  **Documentation**

  - Alphabetize AI tools list in README and make it collapsible

## 0.16.0

### Minor Changes

- c08fbc1: Add new AI tool integrations and enhancements:

  - **feat(iflow-cli)**: Add iFlow-cli integration with slash command support and documentation
  - **feat(init)**: Add IDE restart instruction after init to inform users about slash command availability
    **feat(antigravity)**: Add Antigravity slash command support
  - **fix**: Generate TOML commands for Qwen Code (fixes #293)
  - Clarify scaffold proposal documentation and enhance proposal guidelines
  - Update proposal guidelines to emphasize design-first approach before implementation

## Unreleased

### Minor Changes

- Add Continue slash command support so `openspec init` can generate `.continue/prompts/openspec-*.prompt` files with MARKDOWN frontmatter and `$ARGUMENTS` placeholder, and refresh them on `openspec update`.

- Add Antigravity slash command support so `openspec init` can generate `.agent/workflows/openspec-*.md` files with description-only frontmatter and `openspec update` refreshes existing workflows alongside Windsurf.

## 0.15.0

### Minor Changes

- 4758c5c: Add support for new AI tools with native slash command integration

  - **Gemini CLI**: Add native TOML-based slash command support for Gemini CLI with `.gemini/commands/openspec/` integration
  - **RooCode**: Add RooCode integration with configurator, slash commands, and templates
  - **Cline**: Fix Cline to use workflows instead of rules for slash commands (`.clinerules/workflows/` paths)
  - **Documentation**: Update documentation to reflect new integrations and workflow changes

## 0.14.0

### Minor Changes

- 8386b91: Add support for new AI assistants and configuration improvements

  - feat: add Qwen Code support with slash command integration
  - feat: add $ARGUMENTS support to apply slash command for dynamic variable passing
  - feat: add Qoder CLI support to configuration and documentation
  - feat: add CoStrict AI assistant support
  - fix: recreate missing openspec template files in extend mode
  - fix: prevent false 'already configured' detection for tools
  - fix: use change-id as fallback title instead of "Untitled Change"
  - docs: add guidance for populating project-level context
  - docs: add Crush to supported AI tools in README

## 0.13.0

### Minor Changes

- 668a125: Add support for multiple AI assistants and improve validation

  This release adds support for several new AI coding assistants:

  - CodeBuddy Code - AI-powered coding assistant
  - CodeRabbit - AI code review assistant
  - Cline - Claude-powered CLI assistant
  - Crush AI - AI assistant platform
  - Auggie (Augment CLI) - Code augmentation tool

  New features:

  - Archive slash command now supports arguments for more flexible workflows

  Bug fixes:

  - Delta spec validation now handles case-insensitive headers and properly detects empty sections
  - Archive validation now correctly honors --no-validate flag and ignores metadata

  Documentation improvements:

  - Added VS Code dev container configuration for easier development setup
  - Updated AGENTS.md with explicit change-id notation
  - Enhanced slash commands documentation with restart notes

## 0.12.0

### Minor Changes

- 082abb4: Add factory function support for slash commands and non-interactive init options

  This release includes two new features:

  - **Factory function support for slash commands**: Slash commands can now be defined as functions that return command objects, enabling dynamic command configuration
  - **Non-interactive init options**: Added `--tools`, `--all-tools`, and `--skip-tools` CLI flags to `openspec init` for automated initialization in CI/CD pipelines while maintaining backward compatibility with interactive mode

## 0.11.0

### Minor Changes

- 312e1d6: Add Amazon Q Developer CLI integration. OpenSpec now supports Amazon Q Developer with automatic prompt generation in `.amazonq/prompts/` directory, allowing you to use OpenSpec slash commands with Amazon Q's @-syntax.

## 0.10.0

### Minor Changes

- d7e0ce8: Improve init wizard Enter key behavior to allow proceeding through prompts more naturally

## 0.9.2

### Patch Changes

- 2ae0484: Fix cross-platform path handling issues. This release includes fixes for joinPath behavior and slash command path resolution to ensure OpenSpec works correctly across all platforms.

## 0.9.1

### Patch Changes

- 8210970: Fix OpenSpec not working on Windows when Codex integration is selected. This release includes fixes for cross-platform path handling and normalization to ensure OpenSpec works correctly on Windows systems.

## 0.9.0

### Minor Changes

- efbbf3b: Add support for Codex and GitHub Copilot slash commands with YAML frontmatter and $ARGUMENTS

## Unreleased

### Minor Changes

- Add GitHub Copilot slash command support. OpenSpec now writes prompts to `.github/prompts/openspec-{proposal,apply,archive}.prompt.md` with YAML frontmatter and `$ARGUMENTS` placeholder, and refreshes them on `openspec update`.

## 0.8.1

### Patch Changes

- d070d08: Fix CLI version mismatch and add a release guard that validates the packed tarball prints the same version as package.json via `openspec --version`.

## 0.8.0

### Minor Changes

- c29b06d: Add Windsurf support.
- Add Codex slash command support. OpenSpec now writes prompts directly to Codex's global directory (`~/.codex/prompts` or `$CODEX_HOME/prompts`) and refreshes them on `openspec update`.

## 0.7.0

### Minor Changes

- Add native Kilo Code workflow integration so `openspec init` and `openspec update` manage `.kilocode/workflows/openspec-*.md` files.
- Always scaffold the managed root `AGENTS.md` hand-off stub and regroup the AI tool prompts during init/update to keep instructions consistent.

## 0.6.0

### Minor Changes

- Slim the generated root agent instructions down to a managed hand-off stub and update the init/update flows to refresh it safely.

## 0.5.0

### Minor Changes

- feat: implement Phase 1 E2E testing with cross-platform CI matrix

  - Add shared runCLI helper in test/helpers/run-cli.ts for spawn testing
  - Create test/cli-e2e/basic.test.ts covering help, version, validate flows
  - Migrate existing CLI exec tests to use runCLI helper
  - Extend CI matrix to bash (Linux/macOS) and pwsh (Windows)
  - Split PR and main workflows for optimized feedback

### Patch Changes

- Make apply instructions more specific

  Improve agent templates and slash command templates with more specific and actionable apply instructions.

- docs: improve documentation and cleanup

  - Document non-interactive flag for archive command
  - Replace discord badge in README
  - Archive completed changes for better organization

## 0.4.0

### Minor Changes

- Add OpenSpec change proposals for CLI improvements and enhanced user experience
- Add Opencode slash commands support for AI-driven development workflows

### Patch Changes

- Add documentation improvements including --yes flag for archive command template and Discord badge
- Fix normalize line endings in markdown parser to handle CRLF files properly

## 0.3.0

### Minor Changes

- Enhance `openspec init` with extend mode, multi-tool selection, and an interactive `AGENTS.md` configurator.

## 0.2.0

### Minor Changes

- ce5cead: - Add an `openspec view` dashboard that rolls up spec counts and change progress at a glance
  - Generate and update AI slash commands alongside the renamed `openspec/AGENTS.md` instructions file
  - Remove the deprecated `openspec diff` command and direct users to `openspec show`

## 0.1.0

### Minor Changes

- 24b4866: Initial release


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2024 OpenSpec Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: MAINTAINERS.md
================================================
# Maintainers

People who maintain and guide OpenSpec.

## Core Maintainers

| Name | GitHub | Role |
|------|--------|------|
| Tabish Bidiwale | [@TabishB](https://github.com/TabishB) | Lead maintainer |

## Advisors

Advisors help shape technical direction and provide guidance to the project.

| Name | GitHub | Focus |
|------|--------|-------|
| Hari Krishnan | [@harikrishnan83](https://github.com/harikrishnan83) | Technical direction |


================================================
FILE: README.md
================================================
<p align="center">
  <a href="https://github.com/Fission-AI/OpenSpec">
    <picture>
      <source srcset="assets/openspec_bg.png">
      <img src="assets/openspec_bg.png" alt="OpenSpec logo">
    </picture>
  </a>
</p>

<p align="center">
  <a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
  <a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
  <a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
  <a href="https://discord.gg/YctCnvvshC"><img alt="Discord" src="https://img.shields.io/discord/1411657095639601154?style=flat-square&logo=discord&logoColor=white&label=Discord&suffix=%20online" /></a>
</p>

<details>
<summary><strong>The most loved spec framework.</strong></summary>

[![Stars](https://img.shields.io/github/stars/Fission-AI/OpenSpec?style=flat-square&label=Stars)](https://github.com/Fission-AI/OpenSpec/stargazers)
[![Downloads](https://img.shields.io/npm/dm/@fission-ai/openspec?style=flat-square&label=Downloads/mo)](https://www.npmjs.com/package/@fission-ai/openspec)
[![Contributors](https://img.shields.io/github/contributors/Fission-AI/OpenSpec?style=flat-square&label=Contributors)](https://github.com/Fission-AI/OpenSpec/graphs/contributors)

</details>
<p></p>
Our philosophy:

```text
→ fluid not rigid
→ iterative not waterfall
→ easy not complex
→ built for brownfield not just greenfield
→ scalable from personal projects to enterprises
```

> [!TIP]
> **New workflow now available!** We've rebuilt OpenSpec with a new artifact-guided workflow.
>
> Run `/opsx:propose "your idea"` to get started. → [Learn more here](docs/opsx.md)

<p align="center">
  Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
</p>

### Teams

Using OpenSpec in a team? [Email here](mailto:teams@openspec.dev) for access to our Slack channel.

<!-- TODO: Add GIF demo of /opsx:propose → /opsx:archive workflow -->

## See it in action

```text
You: /opsx:propose add-dark-mode
AI:  Created openspec/changes/add-dark-mode/
     ✓ proposal.md — why we're doing this, what's changing
     ✓ specs/       — requirements and scenarios
     ✓ design.md    — technical approach
     ✓ tasks.md     — implementation checklist
     Ready for implementation!

You: /opsx:apply
AI:  Implementing tasks...
     ✓ 1.1 Add theme context provider
     ✓ 1.2 Create toggle component
     ✓ 2.1 Add CSS variables
     ✓ 2.2 Wire up localStorage
     All tasks complete!

You: /opsx:archive
AI:  Archived to openspec/changes/archive/2025-01-23-add-dark-mode/
     Specs updated. Ready for the next feature.
```

<details>
<summary><strong>OpenSpec Dashboard</strong></summary>

<p align="center">
  <img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
</p>

</details>

## Quick Start

**Requires Node.js 20.19.0 or higher.**

Install OpenSpec globally:

```bash
npm install -g @fission-ai/openspec@latest
```

Then navigate to your project directory and initialize:

```bash
cd your-project
openspec init
```

Now tell your AI: `/opsx:propose <what-you-want-to-build>`

If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:sync`, `/opsx:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`.

> [!NOTE]
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 20+ tools and growing.
>
> Also works with pnpm, yarn, bun, and nix. [See installation options](docs/installation.md).

## Docs

→ **[Getting Started](docs/getting-started.md)**: first steps<br>
→ **[Workflows](docs/workflows.md)**: combos and patterns<br>
→ **[Commands](docs/commands.md)**: slash commands & skills<br>
→ **[CLI](docs/cli.md)**: terminal reference<br>
→ **[Supported Tools](docs/supported-tools.md)**: tool integrations & install paths<br>
→ **[Concepts](docs/concepts.md)**: how it all fits<br>
→ **[Multi-Language](docs/multi-language.md)**: multi-language support<br>
→ **[Customization](docs/customization.md)**: make it yours


## Why OpenSpec?

AI coding assistants are powerful but unpredictable when requirements live only in chat history. OpenSpec adds a lightweight spec layer so you agree on what to build before any code is written.

- **Agree before you build** — human and AI align on specs before code gets written
- **Stay organized** — each change gets its own folder with proposal, specs, design, and tasks
- **Work fluidly** — update any artifact anytime, no rigid phase gates
- **Use your tools** — works with 20+ AI assistants via slash commands

### How we compare

**vs. [Spec Kit](https://github.com/github/spec-kit)** (GitHub) — Thorough but heavyweight. Rigid phase gates, lots of Markdown, Python setup. OpenSpec is lighter and lets you iterate freely.

**vs. [Kiro](https://kiro.dev)** (AWS) — Powerful but you're locked into their IDE and limited to Claude models. OpenSpec works with the tools you already use.

**vs. nothing** — AI coding without specs means vague prompts and unpredictable results. OpenSpec brings predictability without the ceremony.

## Updating OpenSpec

**Upgrade the package**

```bash
npm install -g @fission-ai/openspec@latest
```

**Refresh agent instructions**

Run this inside each project to regenerate AI guidance and ensure the latest slash commands are active:

```bash
openspec update
```

## Usage Notes

**Model selection**: OpenSpec works best with high-reasoning models. We recommend Opus 4.5 and GPT 5.2 for both planning and implementation.

**Context hygiene**: OpenSpec benefits from a clean context window. Clear your context before starting implementation and maintain good context hygiene throughout your session.

## Contributing

**Small fixes** — Bug fixes, typo corrections, and minor improvements can be submitted directly as PRs.

**Larger changes** — For new features, significant refactors, or architectural changes, please submit an OpenSpec change proposal first so we can align on intent and goals before implementation begins.

When writing proposals, keep the OpenSpec philosophy in mind: we serve a wide variety of users across different coding agents, models, and use cases. Changes should work well for everyone.

**AI-generated code is welcome** — as long as it's been tested and verified. PRs containing AI-generated code should mention the coding agent and model used (e.g., "Generated with Claude Code using claude-opus-4-5-20251101").

### Development

- Install dependencies: `pnpm install`
- Build: `pnpm run build`
- Test: `pnpm test`
- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
- Conventional commits (one-line): `type(scope): subject`

## Other

<details>
<summary><strong>Telemetry</strong></summary>

OpenSpec collects anonymous usage stats.

We collect only command names and version to understand usage patterns. No arguments, paths, content, or PII. Automatically disabled in CI.

**Opt-out:** `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`

</details>

<details>
<summary><strong>Maintainers & Advisors</strong></summary>

See [MAINTAINERS.md](MAINTAINERS.md) for the list of core maintainers and advisors who help guide the project.

</details>



## License

MIT


================================================
FILE: README_OLD.md
================================================
<p align="center">
  <a href="https://github.com/Fission-AI/OpenSpec">
    <picture>
      <source srcset="assets/openspec_pixel_dark.svg" media="(prefers-color-scheme: dark)">
      <source srcset="assets/openspec_pixel_light.svg" media="(prefers-color-scheme: light)">
      <img src="assets/openspec_pixel_light.svg" alt="OpenSpec logo" height="64">
    </picture>
  </a>
  
</p>
<p align="center">Spec-driven development for AI coding assistants.</p>
<p align="center">
  <a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
  <a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
  <a href="https://nodejs.org/"><img alt="node version" src="https://img.shields.io/node/v/@fission-ai/openspec?style=flat-square" /></a>
  <a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
  <a href="https://conventionalcommits.org"><img alt="Conventional Commits" src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square" /></a>
  <a href="https://discord.gg/YctCnvvshC"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join%20the%20community-5865F2?logo=discord&logoColor=white&style=flat-square" /></a>
</p>

<p align="center">
  <img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
</p>

<p align="center">
  Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
</p>

<p align="center">
  <sub>🧪 <strong>New:</strong> <a href="docs/opsx.md">OPSX Workflow</a> — schema-driven, hackable, fluid. Iterate on workflows without code changes.</sub>
</p>

# OpenSpec

OpenSpec aligns humans and AI coding assistants with spec-driven development so you agree on what to build before any code is written. **No API keys required.**

## Why OpenSpec?

AI coding assistants are powerful but unpredictable when requirements live in chat history. OpenSpec adds a lightweight specification workflow that locks intent before implementation, giving you deterministic, reviewable outputs.

Key outcomes:
- Human and AI stakeholders agree on specs before work begins.
- Structured change folders (proposals, tasks, and spec updates) keep scope explicit and auditable.
- Shared visibility into what's proposed, active, or archived.
- Works with the AI tools you already use: custom slash commands where supported, context rules everywhere else.

## How OpenSpec compares (at a glance)

- **Lightweight**: simple workflow, no API keys, minimal setup.
- **Brownfield-first**: works great beyond 0→1. OpenSpec separates the source of truth from proposals: `openspec/specs/` (current truth) and `openspec/changes/` (proposed updates). This keeps diffs explicit and manageable across features.
- **Change tracking**: proposals, tasks, and spec deltas live together; archiving merges the approved updates back into specs.
- **Compared to spec-kit & Kiro**: those shine for brand-new features (0→1). OpenSpec also excels when modifying existing behavior (1→n), especially when updates span multiple specs.

See the full comparison in [How OpenSpec Compares](#how-openspec-compares).

## How It Works

```
┌────────────────────┐
│ Draft Change       │
│ Proposal           │
└────────┬───────────┘
         │ share intent with your AI
         ▼
┌────────────────────┐
│ Review & Align     │
│ (edit specs/tasks) │◀──── feedback loop ──────┐
└────────┬───────────┘                          │
         │ approved plan                        │
         ▼                                      │
┌────────────────────┐                          │
│ Implement Tasks    │──────────────────────────┘
│ (AI writes code)   │
└────────┬───────────┘
         │ ship the change
         ▼
┌────────────────────┐
│ Archive & Update   │
│ Specs (source)     │
└────────────────────┘

1. Draft a change proposal that captures the spec updates you want.
2. Review the proposal with your AI assistant until everyone agrees.
3. Implement tasks that reference the agreed specs.
4. Archive the change to merge the approved updates back into the source-of-truth specs.
```

## Getting Started

### Supported AI Tools

<details>
<summary><strong>Native Slash Commands</strong> (click to expand)</summary>

These tools have built-in OpenSpec commands. Select the OpenSpec integration when prompted.

| Tool | Commands |
|------|----------|
| **Amazon Q Developer** | `@openspec-proposal`, `@openspec-apply`, `@openspec-archive` (`.amazonq/prompts/`) |
| **Antigravity** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.agent/workflows/`) |
| **Auggie (Augment CLI)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.augment/commands/`) |
| **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` |
| **Cline** | Workflows in `.clinerules/workflows/` directory (`.clinerules/workflows/openspec-*.md`) |
| **CodeBuddy Code (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.codebuddy/commands/`) — see [docs](https://www.codebuddy.ai/cli) |
| **Codex** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (global: `~/.codex/prompts`, auto-installed) |
| **Continue** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.continue/prompts/`) |
| **CoStrict** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.cospec/openspec/commands/`) — see [docs](https://costrict.ai)|
| **Crush** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.crush/commands/openspec/`) |
| **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
| **Factory Droid** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.factory/commands/`) |
| **Gemini CLI** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.gemini/commands/openspec/`) |
| **GitHub Copilot** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.github/prompts/`) |
| **iFlow (iflow-cli)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.iflow/commands/`) |
| **Kilo Code** | `/openspec-proposal.md`, `/openspec-apply.md`, `/openspec-archive.md` (`.kilocode/workflows/`) |
| **OpenCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
| **Qoder** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.qoder/commands/openspec/`) — see [docs](https://qoder.com) |
| **Qwen Code** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.qwen/commands/`) |
| **RooCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.roo/commands/`) |
| **Windsurf** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.windsurf/workflows/`) |

Kilo Code discovers team workflows automatically. Save the generated files under `.kilocode/workflows/` and trigger them from the command palette with `/openspec-proposal.md`, `/openspec-apply.md`, or `/openspec-archive.md`.

</details>

<details>
<summary><strong>AGENTS.md Compatible</strong> (click to expand)</summary>

These tools automatically read workflow instructions from `openspec/AGENTS.md`. Ask them to follow the OpenSpec workflow if they need a reminder. Learn more about the [AGENTS.md convention](https://agents.md/).

| Tools |
|-------|
| Amp • Jules • Others |

</details>

### Install & Initialize

#### Prerequisites
- **Node.js >= 20.19.0** - Check your version with `node --version`

#### Step 1: Install the CLI globally

**Option A: Using npm**

```bash
npm install -g @fission-ai/openspec@latest
```

Verify installation:
```bash
openspec --version
```

**Option B: Using Nix (NixOS and Nix package manager)**

Run OpenSpec directly without installation:
```bash
nix run github:Fission-AI/OpenSpec -- init
```

Or install to your profile:
```bash
nix profile install github:Fission-AI/OpenSpec
```

Or add to your development environment in `flake.nix`:
```nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    openspec.url = "github:Fission-AI/OpenSpec";
  };

  outputs = { nixpkgs, openspec, ... }: {
    devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
      buildInputs = [ openspec.packages.x86_64-linux.default ];
    };
  };
}
```

Verify installation:
```bash
openspec --version
```

#### Step 2: Initialize OpenSpec in your project

Navigate to your project directory:
```bash
cd my-project
```

Run the initialization:
```bash
openspec init
```

**What happens during initialization:**
- You'll be prompted to pick any natively supported AI tools (Claude Code, CodeBuddy, Cursor, OpenCode, Qoder,etc.); other assistants always rely on the shared `AGENTS.md` stub
- OpenSpec automatically configures slash commands for the tools you choose and always writes a managed `AGENTS.md` hand-off at the project root
- A new `openspec/` directory structure is created in your project

**After setup:**
- Primary AI tools can trigger `/openspec` workflows without additional configuration
- Run `openspec list` to verify the setup and view any active changes
- If your coding assistant doesn't surface the new slash commands right away, restart it. Slash commands are loaded at startup,
  so a fresh launch ensures they appear

### Optional: Populate Project Context

After `openspec init` completes, you'll receive a suggested prompt to help populate your project context:

```text
Populate your project context:
"Please read openspec/project.md and help me fill it out with details about my project, tech stack, and conventions"
```

Use `openspec/project.md` to define project-level conventions, standards, architectural patterns, and other guidelines that should be followed across all changes.

### Create Your First Change

Here's a real example showing the complete OpenSpec workflow. This works with any AI tool. Those with native slash commands will recognize the shortcuts automatically.

#### 1. Draft the Proposal
Start by asking your AI to create a change proposal:

```text
You: Create an OpenSpec change proposal for adding profile search filters by role and team
     (Shortcut for tools with slash commands: /openspec:proposal Add profile search filters)

AI:  I'll create an OpenSpec change proposal for profile filters.
     *Scaffolds openspec/changes/add-profile-filters/ with proposal.md, tasks.md, spec deltas.*
```

#### 2. Verify & Review
Check that the change was created correctly and review the proposal:

```bash
$ openspec list                             # Confirm the change folder exists
$ openspec validate add-profile-filters     # Validate spec formatting
$ openspec show add-profile-filters         # Review proposal, tasks, and spec delta
```

#### 3. Refine the Specs
Iterate on the specifications until they match your needs:

```text
You: Can you add acceptance criteria for the role and team filters?

AI:  I'll update the spec delta with scenarios for role and team filters.
     *Edits openspec/changes/add-profile-filters/specs/profile/spec.md and tasks.md.*
```

#### 4. Implement the Change
Once specs look good, start implementation:

```text
You: The specs look good. Let's implement this change.
     (Shortcut for tools with slash commands: /openspec:apply add-profile-filters)

AI:  I'll work through the tasks in the add-profile-filters change.
     *Implements tasks from openspec/changes/add-profile-filters/tasks.md*
     *Marks tasks complete: Task 1.1 ✓, Task 1.2 ✓, Task 2.1 ✓...*
```

#### 5. Archive the Completed Change
After implementation is complete, archive the change:

```text
AI:  All tasks are complete. The implementation is ready.

You: Please archive the change
     (Shortcut for tools with slash commands: /openspec:archive add-profile-filters)

AI:  I'll archive the add-profile-filters change.
    *Runs: openspec archive add-profile-filters --yes*
     ✓ Change archived successfully. Specs updated. Ready for the next feature!
```

Or run the command yourself in terminal:
```bash
$ openspec archive add-profile-filters --yes  # Archive the completed change without prompts
```

**Note:** Tools with native slash commands (Claude Code, CodeBuddy, Cursor, Codex, Qoder, RooCode) can use the shortcuts shown. All other tools work with natural language requests to "create an OpenSpec proposal", "apply the OpenSpec change", or "archive the change".

## Command Reference

```bash
openspec list               # View active change folders
openspec view               # Interactive dashboard of specs and changes
openspec show <change>      # Display change details (proposal, tasks, spec updates)
openspec validate <change>  # Check spec formatting and structure
openspec archive <change> [--yes|-y]   # Move a completed change into archive/ (non-interactive with --yes)
```

## Example: How AI Creates OpenSpec Files

When you ask your AI assistant to "add two-factor authentication", it creates:

```
openspec/
├── specs/
│   └── auth/
│       └── spec.md           # Current auth spec (if exists)
└── changes/
    └── add-2fa/              # AI creates this entire structure
        ├── proposal.md       # Why and what changes
        ├── tasks.md          # Implementation checklist
        ├── design.md         # Technical decisions (optional)
        └── specs/
            └── auth/
                └── spec.md   # Delta showing additions
```

### AI-Generated Spec (created in `openspec/specs/auth/spec.md`):

```markdown
# Auth Specification

## Purpose
Authentication and session management.

## Requirements
### Requirement: User Authentication
The system SHALL issue a JWT on successful login.

#### Scenario: Valid credentials
- WHEN a user submits valid credentials
- THEN a JWT is returned
```

### AI-Generated Change Delta (created in `openspec/changes/add-2fa/specs/auth/spec.md`):

```markdown
# Delta for Auth

## ADDED Requirements
### Requirement: Two-Factor Authentication
The system MUST require a second factor during login.

#### Scenario: OTP required
- WHEN a user submits valid credentials
- THEN an OTP challenge is required
```

### AI-Generated Tasks (created in `openspec/changes/add-2fa/tasks.md`):

```markdown
## 1. Database Setup
- [ ] 1.1 Add OTP secret column to users table
- [ ] 1.2 Create OTP verification logs table

## 2. Backend Implementation  
- [ ] 2.1 Add OTP generation endpoint
- [ ] 2.2 Modify login flow to require OTP
- [ ] 2.3 Add OTP verification endpoint

## 3. Frontend Updates
- [ ] 3.1 Create OTP input component
- [ ] 3.2 Update login flow UI
```

**Important:** You don't create these files manually. Your AI assistant generates them based on your requirements and the existing codebase.

## Understanding OpenSpec Files

### Delta Format

Deltas are "patches" that show how specs change:

- **`## ADDED Requirements`** - New capabilities
- **`## MODIFIED Requirements`** - Changed behavior (include complete updated text)
- **`## REMOVED Requirements`** - Deprecated features

**Format requirements:**
- Use `### Requirement: <name>` for headers
- Every requirement needs at least one `#### Scenario:` block
- Use SHALL/MUST in requirement text

## How OpenSpec Compares

### vs. spec-kit
OpenSpec’s two-folder model (`openspec/specs/` for the current truth, `openspec/changes/` for proposed updates) keeps state and diffs separate. This scales when you modify existing features or touch multiple specs. spec-kit is strong for greenfield/0→1 but provides less structure for cross-spec updates and evolving features.

### vs. Kiro.dev
OpenSpec groups every change for a feature in one folder (`openspec/changes/feature-name/`), making it easy to track related specs, tasks, and designs together. Kiro spreads updates across multiple spec folders, which can make feature tracking harder.

### vs. No Specs
Without specs, AI coding assistants generate code from vague prompts, often missing requirements or adding unwanted features. OpenSpec brings predictability by agreeing on the desired behavior before any code is written.

## Team Adoption

1. **Initialize OpenSpec** – Run `openspec init` in your repo.
2. **Start with new features** – Ask your AI to capture upcoming work as change proposals.
3. **Grow incrementally** – Each change archives into living specs that document your system.
4. **Stay flexible** – Different teammates can use Claude Code, CodeBuddy, Cursor, or any AGENTS.md-compatible tool while sharing the same specs.

Run `openspec update` whenever someone switches tools so your agents pick up the latest instructions and slash-command bindings.

## Updating OpenSpec

1. **Upgrade the package**
   ```bash
   npm install -g @fission-ai/openspec@latest
   ```
2. **Refresh agent instructions**
   - Run `openspec update` inside each project to regenerate AI guidance and ensure the latest slash commands are active.

## Experimental Features

<details>
<summary><strong>🧪 OPSX: Fluid, Iterative Workflow</strong> (Claude Code only)</summary>

**Why this exists:**
- Standard workflow is locked down — you can't tweak instructions or customize
- When AI output is bad, you can't improve the prompts yourself
- Same workflow for everyone, no way to match how your team works

**What's different:**
- **Hackable** — edit templates and schemas yourself, test immediately, no rebuild
- **Granular** — each artifact has its own instructions, test and tweak individually
- **Customizable** — define your own workflows, artifacts, and dependencies
- **Fluid** — no phase gates, update any artifact anytime

```
You can always go back:

  proposal ──→ specs ──→ design ──→ tasks ──→ implement
     ▲           ▲          ▲                    │
     └───────────┴──────────┴────────────────────┘
```

| Command | What it does |
|---------|--------------|
| `/opsx:new` | Start a new change |
| `/opsx:continue` | Create the next artifact (based on what's ready) |
| `/opsx:ff` | Fast-forward (all planning artifacts at once) |
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
| `/opsx:archive` | Archive when done |

**Setup:** `openspec experimental`

[Full documentation →](docs/opsx.md)

</details>

<details>
<summary><strong>Telemetry</strong> – OpenSpec collects anonymous usage stats (opt-out: <code>OPENSPEC_TELEMETRY=0</code>)</summary>

We collect only command names and version to understand usage patterns. No arguments, paths, content, or PII. Automatically disabled in CI.

**Opt-out:** `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`

</details>

## Contributing

- Install dependencies: `pnpm install`
- Build: `pnpm run build`
- Test: `pnpm test`
- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
- Conventional commits (one-line): `type(scope): subject`

<details>
<summary><strong>Maintainers & Advisors</strong></summary>

See [MAINTAINERS.md](MAINTAINERS.md) for the list of core maintainers and advisors who help guide the project.

</details>

## License

MIT


================================================
FILE: bin/openspec.js
================================================
#!/usr/bin/env node

import '../dist/cli/index.js';

================================================
FILE: build.js
================================================
#!/usr/bin/env node

import { execFileSync } from 'child_process';
import { existsSync, rmSync } from 'fs';
import { createRequire } from 'module';

const require = createRequire(import.meta.url);

const runTsc = (args = []) => {
  const tscPath = require.resolve('typescript/bin/tsc');
  execFileSync(process.execPath, [tscPath, ...args], { stdio: 'inherit' });
};

console.log('🔨 Building OpenSpec...\n');

// Clean dist directory
if (existsSync('dist')) {
  console.log('Cleaning dist directory...');
  rmSync('dist', { recursive: true, force: true });
}

// Run TypeScript compiler (use local version explicitly)
console.log('Compiling TypeScript...');
try {
  runTsc(['--version']);
  runTsc();
  console.log('\n✅ Build completed successfully!');
} catch (error) {
  console.error('\n❌ Build failed!');
  process.exit(1);
}


================================================
FILE: docs/cli.md
================================================
# CLI Reference

The OpenSpec CLI (`openspec`) provides terminal commands for project setup, validation, status inspection, and management. These commands complement the AI slash commands (like `/opsx:propose`) documented in [Commands](commands.md).

## Summary

| Category | Commands | Purpose |
|----------|----------|---------|
| **Setup** | `init`, `update` | Initialize and update OpenSpec in your project |
| **Browsing** | `list`, `view`, `show` | Explore changes and specs |
| **Validation** | `validate` | Check changes and specs for issues |
| **Lifecycle** | `archive` | Finalize completed changes |
| **Workflow** | `status`, `instructions`, `templates`, `schemas` | Artifact-driven workflow support |
| **Schemas** | `schema init`, `schema fork`, `schema validate`, `schema which` | Create and manage custom workflows |
| **Config** | `config` | View and modify settings |
| **Utility** | `feedback`, `completion` | Feedback and shell integration |

---

## Human vs Agent Commands

Most CLI commands are designed for **human use** in a terminal. Some commands also support **agent/script use** via JSON output.

### Human-Only Commands

These commands are interactive and designed for terminal use:

| Command | Purpose |
|---------|---------|
| `openspec init` | Initialize project (interactive prompts) |
| `openspec view` | Interactive dashboard |
| `openspec config edit` | Open config in editor |
| `openspec feedback` | Submit feedback via GitHub |
| `openspec completion install` | Install shell completions |

### Agent-Compatible Commands

These commands support `--json` output for programmatic use by AI agents and scripts:

| Command | Human Use | Agent Use |
|---------|-----------|-----------|
| `openspec list` | Browse changes/specs | `--json` for structured data |
| `openspec show <item>` | Read content | `--json` for parsing |
| `openspec validate` | Check for issues | `--all --json` for bulk validation |
| `openspec status` | See artifact progress | `--json` for structured status |
| `openspec instructions` | Get next steps | `--json` for agent instructions |
| `openspec templates` | Find template paths | `--json` for path resolution |
| `openspec schemas` | List available schemas | `--json` for schema discovery |

---

## Global Options

These options work with all commands:

| Option | Description |
|--------|-------------|
| `--version`, `-V` | Show version number |
| `--no-color` | Disable color output |
| `--help`, `-h` | Display help for command |

---

## Setup Commands

### `openspec init`

Initialize OpenSpec in your project. Creates the folder structure and configures AI tool integrations.

Default behavior uses global config defaults: profile `core`, delivery `both`, workflows `propose, explore, apply, archive`.

```
openspec init [path] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `path` | No | Target directory (default: current directory) |

**Options:**

| Option | Description |
|--------|-------------|
| `--tools <list>` | Configure AI tools non-interactively. Use `all`, `none`, or comma-separated list |
| `--force` | Auto-cleanup legacy files without prompting |
| `--profile <profile>` | Override global profile for this init run (`core` or `custom`) |

`--profile custom` uses whatever workflows are currently selected in global config (`openspec config profile`).

**Supported tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`

**Examples:**

```bash
# Interactive initialization
openspec init

# Initialize in a specific directory
openspec init ./my-project

# Non-interactive: configure for Claude and Cursor
openspec init --tools claude,cursor

# Configure for all supported tools
openspec init --tools all

# Override profile for this run
openspec init --profile core

# Skip prompts and auto-cleanup legacy files
openspec init --force
```

**What it creates:**

```
openspec/
├── specs/              # Your specifications (source of truth)
├── changes/            # Proposed changes
└── config.yaml         # Project configuration

.claude/skills/         # Claude Code skills (if claude selected)
.cursor/skills/         # Cursor skills (if cursor selected)
.cursor/commands/       # Cursor OPSX commands (if delivery includes commands)
... (other tool configs)
```

---

### `openspec update`

Update OpenSpec instruction files after upgrading the CLI. Re-generates AI tool configuration files using your current global profile, selected workflows, and delivery mode.

```
openspec update [path] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `path` | No | Target directory (default: current directory) |

**Options:**

| Option | Description |
|--------|-------------|
| `--force` | Force update even when files are up to date |

**Example:**

```bash
# Update instruction files after npm upgrade
npm update @fission-ai/openspec
openspec update
```

---

## Browsing Commands

### `openspec list`

List changes or specs in your project.

```
openspec list [options]
```

**Options:**

| Option | Description |
|--------|-------------|
| `--specs` | List specs instead of changes |
| `--changes` | List changes (default) |
| `--sort <order>` | Sort by `recent` (default) or `name` |
| `--json` | Output as JSON |

**Examples:**

```bash
# List all active changes
openspec list

# List all specs
openspec list --specs

# JSON output for scripts
openspec list --json
```

**Output (text):**

```
Active changes:
  add-dark-mode     UI theme switching support
  fix-login-bug     Session timeout handling
```

---

### `openspec view`

Display an interactive dashboard for exploring specs and changes.

```
openspec view
```

Opens a terminal-based interface for navigating your project's specifications and changes.

---

### `openspec show`

Display details of a change or spec.

```
openspec show [item-name] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `item-name` | No | Name of change or spec (prompts if omitted) |

**Options:**

| Option | Description |
|--------|-------------|
| `--type <type>` | Specify type: `change` or `spec` (auto-detected if unambiguous) |
| `--json` | Output as JSON |
| `--no-interactive` | Disable prompts |

**Change-specific options:**

| Option | Description |
|--------|-------------|
| `--deltas-only` | Show only delta specs (JSON mode) |

**Spec-specific options:**

| Option | Description |
|--------|-------------|
| `--requirements` | Show only requirements, exclude scenarios (JSON mode) |
| `--no-scenarios` | Exclude scenario content (JSON mode) |
| `-r, --requirement <id>` | Show specific requirement by 1-based index (JSON mode) |

**Examples:**

```bash
# Interactive selection
openspec show

# Show a specific change
openspec show add-dark-mode

# Show a specific spec
openspec show auth --type spec

# JSON output for parsing
openspec show add-dark-mode --json
```

---

## Validation Commands

### `openspec validate`

Validate changes and specs for structural issues.

```
openspec validate [item-name] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `item-name` | No | Specific item to validate (prompts if omitted) |

**Options:**

| Option | Description |
|--------|-------------|
| `--all` | Validate all changes and specs |
| `--changes` | Validate all changes |
| `--specs` | Validate all specs |
| `--type <type>` | Specify type when name is ambiguous: `change` or `spec` |
| `--strict` | Enable strict validation mode |
| `--json` | Output as JSON |
| `--concurrency <n>` | Max parallel validations (default: 6, or `OPENSPEC_CONCURRENCY` env) |
| `--no-interactive` | Disable prompts |

**Examples:**

```bash
# Interactive validation
openspec validate

# Validate a specific change
openspec validate add-dark-mode

# Validate all changes
openspec validate --changes

# Validate everything with JSON output (for CI/scripts)
openspec validate --all --json

# Strict validation with increased parallelism
openspec validate --all --strict --concurrency 12
```

**Output (text):**

```
Validating add-dark-mode...
  ✓ proposal.md valid
  ✓ specs/ui/spec.md valid
  ⚠ design.md: missing "Technical Approach" section

1 warning found
```

**Output (JSON):**

```json
{
  "version": "1.0.0",
  "results": {
    "changes": [
      {
        "name": "add-dark-mode",
        "valid": true,
        "warnings": ["design.md: missing 'Technical Approach' section"]
      }
    ]
  },
  "summary": {
    "total": 1,
    "valid": 1,
    "invalid": 0
  }
}
```

---

## Lifecycle Commands

### `openspec archive`

Archive a completed change and merge delta specs into main specs.

```
openspec archive [change-name] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Change to archive (prompts if omitted) |

**Options:**

| Option | Description |
|--------|-------------|
| `-y, --yes` | Skip confirmation prompts |
| `--skip-specs` | Skip spec updates (for infrastructure/tooling/doc-only changes) |
| `--no-validate` | Skip validation (requires confirmation) |

**Examples:**

```bash
# Interactive archive
openspec archive

# Archive specific change
openspec archive add-dark-mode

# Archive without prompts (CI/scripts)
openspec archive add-dark-mode --yes

# Archive a tooling change that doesn't affect specs
openspec archive update-ci-config --skip-specs
```

**What it does:**

1. Validates the change (unless `--no-validate`)
2. Prompts for confirmation (unless `--yes`)
3. Merges delta specs into `openspec/specs/`
4. Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`

---

## Workflow Commands

These commands support the artifact-driven OPSX workflow. They're useful for both humans checking progress and agents determining next steps.

### `openspec status`

Display artifact completion status for a change.

```
openspec status [options]
```

**Options:**

| Option | Description |
|--------|-------------|
| `--change <id>` | Change name (prompts if omitted) |
| `--schema <name>` | Schema override (auto-detected from change's config) |
| `--json` | Output as JSON |

**Examples:**

```bash
# Interactive status check
openspec status

# Status for specific change
openspec status --change add-dark-mode

# JSON for agent use
openspec status --change add-dark-mode --json
```

**Output (text):**

```
Change: add-dark-mode
Schema: spec-driven
Progress: 2/4 artifacts complete

[x] proposal
[ ] design
[x] specs
[-] tasks (blocked by: design)
```

**Output (JSON):**

```json
{
  "changeName": "add-dark-mode",
  "schemaName": "spec-driven",
  "isComplete": false,
  "applyRequires": ["tasks"],
  "artifacts": [
    {"id": "proposal", "outputPath": "proposal.md", "status": "done"},
    {"id": "design", "outputPath": "design.md", "status": "ready"},
    {"id": "specs", "outputPath": "specs/**/*.md", "status": "done"},
    {"id": "tasks", "outputPath": "tasks.md", "status": "blocked", "missingDeps": ["design"]}
  ]
}
```

---

### `openspec instructions`

Get enriched instructions for creating an artifact or applying tasks. Used by AI agents to understand what to create next.

```
openspec instructions [artifact] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `artifact` | No | Artifact ID: `proposal`, `specs`, `design`, `tasks`, or `apply` |

**Options:**

| Option | Description |
|--------|-------------|
| `--change <id>` | Change name (required in non-interactive mode) |
| `--schema <name>` | Schema override |
| `--json` | Output as JSON |

**Special case:** Use `apply` as the artifact to get task implementation instructions.

**Examples:**

```bash
# Get instructions for next artifact
openspec instructions --change add-dark-mode

# Get specific artifact instructions
openspec instructions design --change add-dark-mode

# Get apply/implementation instructions
openspec instructions apply --change add-dark-mode

# JSON for agent consumption
openspec instructions design --change add-dark-mode --json
```

**Output includes:**

- Template content for the artifact
- Project context from config
- Content from dependency artifacts
- Per-artifact rules from config

---

### `openspec templates`

Show resolved template paths for all artifacts in a schema.

```
openspec templates [options]
```

**Options:**

| Option | Description |
|--------|-------------|
| `--schema <name>` | Schema to inspect (default: `spec-driven`) |
| `--json` | Output as JSON |

**Examples:**

```bash
# Show template paths for default schema
openspec templates

# Show templates for custom schema
openspec templates --schema my-workflow

# JSON for programmatic use
openspec templates --json
```

**Output (text):**

```
Schema: spec-driven

Templates:
  proposal  → ~/.openspec/schemas/spec-driven/templates/proposal.md
  specs     → ~/.openspec/schemas/spec-driven/templates/specs.md
  design    → ~/.openspec/schemas/spec-driven/templates/design.md
  tasks     → ~/.openspec/schemas/spec-driven/templates/tasks.md
```

---

### `openspec schemas`

List available workflow schemas with their descriptions and artifact flows.

```
openspec schemas [options]
```

**Options:**

| Option | Description |
|--------|-------------|
| `--json` | Output as JSON |

**Example:**

```bash
openspec schemas
```

**Output:**

```
Available schemas:

  spec-driven (package)
    The default spec-driven development workflow
    Flow: proposal → specs → design → tasks

  my-custom (project)
    Custom workflow for this project
    Flow: research → proposal → tasks
```

---

## Schema Commands

Commands for creating and managing custom workflow schemas.

### `openspec schema init`

Create a new project-local schema.

```
openspec schema init <name> [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `name` | Yes | Schema name (kebab-case) |

**Options:**

| Option | Description |
|--------|-------------|
| `--description <text>` | Schema description |
| `--artifacts <list>` | Comma-separated artifact IDs (default: `proposal,specs,design,tasks`) |
| `--default` | Set as project default schema |
| `--no-default` | Don't prompt to set as default |
| `--force` | Overwrite existing schema |
| `--json` | Output as JSON |

**Examples:**

```bash
# Interactive schema creation
openspec schema init research-first

# Non-interactive with specific artifacts
openspec schema init rapid \
  --description "Rapid iteration workflow" \
  --artifacts "proposal,tasks" \
  --default
```

**What it creates:**

```
openspec/schemas/<name>/
├── schema.yaml           # Schema definition
└── templates/
    ├── proposal.md       # Template for each artifact
    ├── specs.md
    ├── design.md
    └── tasks.md
```

---

### `openspec schema fork`

Copy an existing schema to your project for customization.

```
openspec schema fork <source> [name] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `source` | Yes | Schema to copy |
| `name` | No | New schema name (default: `<source>-custom`) |

**Options:**

| Option | Description |
|--------|-------------|
| `--force` | Overwrite existing destination |
| `--json` | Output as JSON |

**Example:**

```bash
# Fork the built-in spec-driven schema
openspec schema fork spec-driven my-workflow
```

---

### `openspec schema validate`

Validate a schema's structure and templates.

```
openspec schema validate [name] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `name` | No | Schema to validate (validates all if omitted) |

**Options:**

| Option | Description |
|--------|-------------|
| `--verbose` | Show detailed validation steps |
| `--json` | Output as JSON |

**Example:**

```bash
# Validate a specific schema
openspec schema validate my-workflow

# Validate all schemas
openspec schema validate
```

---

### `openspec schema which`

Show where a schema resolves from (useful for debugging precedence).

```
openspec schema which [name] [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `name` | No | Schema name |

**Options:**

| Option | Description |
|--------|-------------|
| `--all` | List all schemas with their sources |
| `--json` | Output as JSON |

**Example:**

```bash
# Check where a schema comes from
openspec schema which spec-driven
```

**Output:**

```
spec-driven resolves from: package
  Source: /usr/local/lib/node_modules/@fission-ai/openspec/schemas/spec-driven
```

**Schema precedence:**

1. Project: `openspec/schemas/<name>/`
2. User: `~/.local/share/openspec/schemas/<name>/`
3. Package: Built-in schemas

---

## Configuration Commands

### `openspec config`

View and modify global OpenSpec configuration.

```
openspec config <subcommand> [options]
```

**Subcommands:**

| Subcommand | Description |
|------------|-------------|
| `path` | Show config file location |
| `list` | Show all current settings |
| `get <key>` | Get a specific value |
| `set <key> <value>` | Set a value |
| `unset <key>` | Remove a key |
| `reset` | Reset to defaults |
| `edit` | Open in `$EDITOR` |
| `profile [preset]` | Configure workflow profile interactively or via preset |

**Examples:**

```bash
# Show config file path
openspec config path

# List all settings
openspec config list

# Get a specific value
openspec config get telemetry.enabled

# Set a value
openspec config set telemetry.enabled false

# Set a string value explicitly
openspec config set user.name "My Name" --string

# Remove a custom setting
openspec config unset user.name

# Reset all configuration
openspec config reset --all --yes

# Edit config in your editor
openspec config edit

# Configure profile with action-based wizard
openspec config profile

# Fast preset: switch workflows to core (keeps delivery mode)
openspec config profile core
```

`openspec config profile` starts with a current-state summary, then lets you choose:
- Change delivery + workflows
- Change delivery only
- Change workflows only
- Keep current settings (exit)

If you keep current settings, no changes are written and no update prompt is shown.
If there are no config changes but the current project files are out of sync with your global profile/delivery, OpenSpec will show a warning and suggest running `openspec update`.
Pressing `Ctrl+C` also cancels the flow cleanly (no stack trace) and exits with code `130`.
In the workflow checklist, `[x]` means the workflow is selected in global config. To apply those selections to project files, run `openspec update` (or choose `Apply changes to this project now?` when prompted inside a project).

**Interactive examples:**

```bash
# Delivery-only update
openspec config profile
# choose: Change delivery only
# choose delivery: Skills only

# Workflows-only update
openspec config profile
# choose: Change workflows only
# toggle workflows in the checklist, then confirm
```

---

## Utility Commands

### `openspec feedback`

Submit feedback about OpenSpec. Creates a GitHub issue.

```
openspec feedback <message> [options]
```

**Arguments:**

| Argument | Required | Description |
|----------|----------|-------------|
| `message` | Yes | Feedback message |

**Options:**

| Option | Description |
|--------|-------------|
| `--body <text>` | Detailed description |

**Requirements:** GitHub CLI (`gh`) must be installed and authenticated.

**Example:**

```bash
openspec feedback "Add support for custom artifact types" \
  --body "I'd like to define my own artifact types beyond the built-in ones."
```

---

### `openspec completion`

Manage shell completions for the OpenSpec CLI.

```
openspec completion <subcommand> [shell]
```

**Subcommands:**

| Subcommand | Description |
|------------|-------------|
| `generate [shell]` | Output completion script to stdout |
| `install [shell]` | Install completion for your shell |
| `uninstall [shell]` | Remove installed completions |

**Supported shells:** `bash`, `zsh`, `fish`, `powershell`

**Examples:**

```bash
# Install completions (auto-detects shell)
openspec completion install

# Install for specific shell
openspec completion install zsh

# Generate script for manual installation
openspec completion generate bash > ~/.bash_completion.d/openspec

# Uninstall
openspec completion uninstall
```

---

## Exit Codes

| Code | Meaning |
|------|---------|
| `0` | Success |
| `1` | Error (validation failure, missing files, etc.) |

---

## Environment Variables

| Variable | Description |
|----------|-------------|
| `OPENSPEC_CONCURRENCY` | Default concurrency for bulk validation (default: 6) |
| `EDITOR` or `VISUAL` | Editor for `openspec config edit` |
| `NO_COLOR` | Disable color output when set |

---

## Related Documentation

- [Commands](commands.md) - AI slash commands (`/opsx:propose`, `/opsx:apply`, etc.)
- [Workflows](workflows.md) - Common patterns and when to use each command
- [Customization](customization.md) - Create custom schemas and templates
- [Getting Started](getting-started.md) - First-time setup guide


================================================
FILE: docs/commands.md
================================================
# Commands

This is the reference for OpenSpec's slash commands. These commands are invoked in your AI coding assistant's chat interface (e.g., Claude Code, Cursor, Windsurf).

For workflow patterns and when to use each command, see [Workflows](workflows.md). For CLI commands, see [CLI](cli.md).

## Quick Reference

### Default Quick Path (`core` profile)

| Command | Purpose |
|---------|---------|
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
| `/opsx:explore` | Think through ideas before committing to a change |
| `/opsx:apply` | Implement tasks from the change |
| `/opsx:archive` | Archive a completed change |

### Expanded Workflow Commands (custom workflow selection)

| Command | Purpose |
|---------|---------|
| `/opsx:new` | Start a new change scaffold |
| `/opsx:continue` | Create the next artifact based on dependencies |
| `/opsx:ff` | Fast-forward: create all planning artifacts at once |
| `/opsx:verify` | Validate implementation matches artifacts |
| `/opsx:sync` | Merge delta specs into main specs |
| `/opsx:bulk-archive` | Archive multiple changes at once |
| `/opsx:onboard` | Guided tutorial through the complete workflow |

The default global profile is `core`. To enable expanded workflow commands, run `openspec config profile`, select workflows, then run `openspec update` in your project.

---

## Command Reference

### `/opsx:propose`

Create a new change and generate planning artifacts in one step. This is the default start command in the `core` profile.

**Syntax:**
```text
/opsx:propose [change-name-or-description]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name-or-description` | No | Kebab-case name or plain-language change description |

**What it does:**
- Creates `openspec/changes/<change-name>/`
- Generates artifacts needed before implementation (for `spec-driven`: proposal, specs, design, tasks)
- Stops when the change is ready for `/opsx:apply`

**Example:**
```text
You: /opsx:propose add-dark-mode

AI:  Created openspec/changes/add-dark-mode/
     ✓ proposal.md
     ✓ specs/ui/spec.md
     ✓ design.md
     ✓ tasks.md
     Ready for implementation. Run /opsx:apply.
```

**Tips:**
- Use this for the fastest end-to-end path
- If you want step-by-step artifact control, enable expanded workflows and use `/opsx:new` + `/opsx:continue`

---

### `/opsx:explore`

Think through ideas, investigate problems, and clarify requirements before committing to a change.

**Syntax:**
```
/opsx:explore [topic]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `topic` | No | What you want to explore or investigate |

**What it does:**
- Opens an exploratory conversation with no structure required
- Investigates the codebase to answer questions
- Compares options and approaches
- Creates visual diagrams to clarify thinking
- Can transition to `/opsx:propose` (default) or `/opsx:new` (expanded workflow) when insights crystallize

**Example:**
```text
You: /opsx:explore

AI:  What would you like to explore?

You: How should we handle authentication for the mobile app?

AI:  Let me investigate your current auth setup...
     [Analyzes codebase]

     I see you're using session-based auth for the web app.
     For mobile, we have three main options:

     1. JWT tokens (stateless, works offline)
     2. OAuth2 (if you need third-party login)
     3. Extend current sessions (simpler, but requires connectivity)

     Your API already has CORS configured. Which direction interests you?

You: Let's go with JWT. Can we start a change for that?

AI:  Ready when you are. Run /opsx:propose add-jwt-auth to begin.
```

**Tips:**
- Use when requirements are unclear or you need to investigate
- No artifacts are created during exploration
- Good for comparing multiple approaches before deciding
- Can read files and search the codebase

---

### `/opsx:new`

Start a new change scaffold. Creates the change folder and waits for you to generate artifacts with `/opsx:continue` or `/opsx:ff`.

This command is part of the expanded workflow set (not included in the default `core` profile).

**Syntax:**
```
/opsx:new [change-name] [--schema <schema-name>]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Name for the change folder (prompted if not provided) |
| `--schema` | No | Workflow schema to use (default: from config or `spec-driven`) |

**What it does:**
- Creates `openspec/changes/<change-name>/` directory
- Creates `.openspec.yaml` metadata file in the change folder
- Shows the first artifact template ready for creation
- Prompts for change name and schema if not provided

**What it creates:**
```
openspec/changes/<change-name>/
└── .openspec.yaml    # Change metadata (schema, created date)
```

**Example:**
```
You: /opsx:new add-dark-mode

AI:  Created openspec/changes/add-dark-mode/
     Schema: spec-driven

     Ready to create: proposal
     Use /opsx:continue to create it, or /opsx:ff to create all artifacts.
```

**Tips:**
- Use descriptive names: `add-feature`, `fix-bug`, `refactor-module`
- Avoid generic names like `update`, `changes`, `wip`
- Schema can also be set in project config (`openspec/config.yaml`)

---

### `/opsx:continue`

Create the next artifact in the dependency chain. Creates one artifact at a time for incremental progress.

**Syntax:**
```
/opsx:continue [change-name]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to continue (inferred from context if not provided) |

**What it does:**
- Queries the artifact dependency graph
- Shows which artifacts are ready vs blocked
- Creates the first ready artifact
- Reads dependency files for context
- Shows what becomes available after creation

**Example:**
```
You: /opsx:continue

AI:  Change: add-dark-mode

     Artifact status:
     ✓ proposal    (done)
     ◆ specs       (ready)
     ◆ design      (ready)
     ○ tasks       (blocked - needs: specs)

     Creating specs...

     [Reads proposal.md, creates specs based on requirements]

     ✓ Created openspec/changes/add-dark-mode/specs/ui/spec.md

     Now available: tasks
     Run /opsx:continue to create the next artifact.
```

**Tips:**
- Use when you want to review each artifact before proceeding
- Good for complex changes where you want control
- Multiple artifacts may become ready simultaneously
- You can edit created artifacts before continuing

---

### `/opsx:ff`

Fast-forward through artifact creation. Creates all planning artifacts at once.

**Syntax:**
```
/opsx:ff [change-name]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to fast-forward (inferred from context if not provided) |

**What it does:**
- Creates all artifacts in dependency order
- Tracks progress via todo list
- Stops when all `apply-required` artifacts are complete
- Reads each dependency before creating the next artifact

**Example:**
```
You: /opsx:ff add-dark-mode

AI:  Fast-forwarding add-dark-mode...

     ✓ Creating proposal.md
     ✓ Creating specs/ui/spec.md
     ✓ Creating design.md
     ✓ Creating tasks.md

     All planning artifacts complete!
     Ready for implementation. Run /opsx:apply to begin.
```

**Tips:**
- Use when you have a clear picture of what you're building
- Faster than `/opsx:continue` for straightforward changes
- You can still edit artifacts afterward
- Good for small to medium features

---

### `/opsx:apply`

Implement tasks from the change. Works through the task list, writing code and checking off items.

**Syntax:**
```
/opsx:apply [change-name]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to implement (inferred from context if not provided) |

**What it does:**
- Reads `tasks.md` and identifies incomplete tasks
- Works through tasks one by one
- Writes code, creates files, runs tests as needed
- Marks tasks complete with checkboxes `[x]`

**Example:**
```
You: /opsx:apply

AI:  Implementing add-dark-mode...

     Reading tasks.md:
     - [ ] 1.1 Create ThemeContext
     - [ ] 1.2 Add CSS custom properties
     - [ ] 1.3 Implement localStorage persistence

     Working on 1.1: Create ThemeContext...
     [Creates src/context/ThemeContext.tsx]

     ✓ 1.1 Complete

     Working on 1.2: Add CSS custom properties...
     [Updates src/styles/globals.css]

     ✓ 1.2 Complete
     ...
```

**Tips:**
- Can resume where you left off if interrupted
- Use for parallel changes by specifying the change name
- Completion state is tracked in `tasks.md` checkboxes

---

### `/opsx:verify`

Validate that implementation matches your change artifacts. Checks completeness, correctness, and coherence.

**Syntax:**
```
/opsx:verify [change-name]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to verify (inferred from context if not provided) |

**What it does:**
- Checks three dimensions of implementation quality
- Searches codebase for implementation evidence
- Reports issues categorized as CRITICAL, WARNING, or SUGGESTION
- Does not block archive, but surfaces issues

**Verification dimensions:**

| Dimension | What it validates |
|-----------|-------------------|
| **Completeness** | All tasks done, all requirements implemented, scenarios covered |
| **Correctness** | Implementation matches spec intent, edge cases handled |
| **Coherence** | Design decisions reflected in code, patterns consistent |

**Example:**
```
You: /opsx:verify

AI:  Verifying add-dark-mode...

     COMPLETENESS
     ✓ All 8 tasks in tasks.md are checked
     ✓ All requirements in specs have corresponding code
     ⚠ Scenario "System preference detection" has no test coverage

     CORRECTNESS
     ✓ Implementation matches spec intent
     ✓ Edge cases from scenarios are handled
     ✓ Error states match spec definitions

     COHERENCE
     ✓ Design decisions reflected in code structure
     ✓ Naming conventions consistent with design.md
     ⚠ Design mentions "CSS variables" but implementation uses Tailwind classes

     SUMMARY
     ─────────────────────────────
     Critical issues: 0
     Warnings: 2
     Ready to archive: Yes (with warnings)

     Recommendations:
     1. Add test for system preference detection
     2. Update design.md to reflect Tailwind usage, or refactor to use CSS variables
```

**Tips:**
- Run before archiving to catch mismatches early
- Warnings don't block archive but indicate potential issues
- Good for reviewing AI's work before committing
- Can reveal drift between artifacts and implementation

---

### `/opsx:sync`

**Optional command.** Merge delta specs from a change into main specs. Archive will prompt to sync if needed, so you typically don't need to run this manually.

**Syntax:**
```
/opsx:sync [change-name]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to sync (inferred from context if not provided) |

**What it does:**
- Reads delta specs from change folder
- Parses ADDED/MODIFIED/REMOVED/RENAMED sections
- Merges changes into main `openspec/specs/` directory
- Preserves existing content not mentioned in delta
- Does not archive the change (remains active)

**Example:**
```text
You: /opsx:sync

AI:  Syncing add-dark-mode delta specs...

     Reading: openspec/changes/add-dark-mode/specs/ui/spec.md
     Target:  openspec/specs/ui/spec.md

     Changes to apply:
     ✓ ADDED: Theme Selection requirement (2 scenarios)
     ✓ ADDED: Accessibility requirement (1 scenario)

     Merging...
     ✓ openspec/specs/ui/spec.md updated

     Change remains active. Run /opsx:archive when ready to complete.
```

**When to use manually:**

| Scenario | Use sync? |
|----------|-----------|
| Long-running change, want specs in main before archiving | Yes |
| Multiple parallel changes need the updated base specs | Yes |
| Want to preview/review the merge separately | Yes |
| Quick change, going straight to archive | No (archive handles it) |

**Tips:**
- Sync is intelligent, not copy-paste
- Can add scenarios to existing requirements without duplicating
- Change stays active after sync (not archived)
- Most users will never need to call this directly—archive prompts if needed

---

### `/opsx:archive`

Archive a completed change. Finalizes the change and moves it to the archive folder.

**Syntax:**
```
/opsx:archive [change-name]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to archive (inferred from context if not provided) |

**What it does:**
- Checks artifact completion status
- Checks task completion (warns if incomplete)
- Offers to sync delta specs if not already synced
- Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`
- Preserves all artifacts for audit trail

**Example:**
```text
You: /opsx:archive

AI:  Archiving add-dark-mode...

     Artifact status:
     ✓ proposal.md exists
     ✓ specs/ exists
     ✓ design.md exists
     ✓ tasks.md exists (8/8 tasks complete)

     Delta specs: Not yet synced
     → Sync now? (recommended)

You: Yes

AI:  ✓ Synced specs to openspec/specs/ui/spec.md
     ✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/

     Change archived successfully.
```

**Tips:**
- Archive won't block on incomplete tasks, but will warn
- Delta specs can be synced during archive or beforehand
- Archived changes are preserved for history
- Use `/opsx:verify` first to catch issues

---

### `/opsx:bulk-archive`

Archive multiple completed changes at once. Handles spec conflicts between changes.

**Syntax:**
```
/opsx:bulk-archive [change-names...]
```

**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-names` | No | Specific changes to archive (prompts to select if not provided) |

**What it does:**
- Lists all completed changes
- Validates each change before archiving
- Detects spec conflicts across changes
- Resolves conflicts by checking what's actually implemented
- Archives in chronological order

**Example:**
```
You: /opsx:bulk-archive

AI:  Found 3 completed changes:
     - add-dark-mode (8/8 tasks complete)
     - fix-login-bug (3/3 tasks complete)
     - update-footer (2/2 tasks complete)

     Checking for spec conflicts...
     ⚠ add-dark-mode and update-footer both touch specs/ui/

     Inspecting codebase to resolve...
     Both changes are implemented. Will merge in chronological order:
     1. add-dark-mode (created Jan 20)
     2. update-footer (created Jan 22)

     Archive all 3 changes?

You: Yes

AI:  ✓ Archived add-dark-mode
     ✓ Archived fix-login-bug
     ✓ Archived update-footer
     Specs merged: add-dark-mode → update-footer
```

**Tips:**
- Good for parallel work streams
- Conflict resolution is agentic (checks codebase)
- Changes are archived in order of creation
- Prompts before overwriting spec content

---

### `/opsx:onboard`

Guided onboarding through the complete OpenSpec workflow. An interactive tutorial using your actual codebase.

**Syntax:**
```
/opsx:onboard
```

**What it does:**
- Walks through a complete workflow cycle with narration
- Scans your codebase for real improvement opportunities
- Creates an actual change with real artifacts
- Implements actual work (small, safe changes)
- Archives the completed change
- Explains each step as it happens

**Phases:**
1. Welcome and codebase analysis
2. Finding an improvement opportunity
3. Creating a change (`/opsx:new`)
4. Writing the proposal
5. Creating specs
6. Writing the design
7. Creating tasks
8. Implementing tasks (`/opsx:apply`)
9. Verifying implementation
10. Archiving the change
11. Summary and next steps

**Example:**
```
You: /opsx:onboard

AI:  Welcome to OpenSpec!

     I'll walk you through the complete workflow using your actual codebase.
     We'll find something small to improve, create a proper change for it,
     implement it, and archive it.

     Let me scan your codebase for opportunities...

     [Analyzes codebase]

     I found a few things we could work on:
     1. Add input validation to the contact form
     2. Improve error messages in the auth flow
     3. Add loading states to async buttons

     Which interests you? (or suggest something else)
```

**Tips:**
- Best for new users learning the workflow
- Uses real code, not toy examples
- Creates a real change you can keep or discard
- Takes 15-30 minutes to complete

---

## Command Syntax by AI Tool

Different AI tools use slightly different command syntax. Use the format that matches your tool:

| Tool | Syntax Example |
|------|----------------|
| Claude Code | `/opsx:propose`, `/opsx:apply` |
| Cursor | `/opsx-propose`, `/opsx-apply` |
| Windsurf | `/opsx-propose`, `/opsx-apply` |
| Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
| Trae | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) |

The intent is the same across tools, but how commands are surfaced can differ by integration.

> **Note:** GitHub Copilot commands (`.github/prompts/*.prompt.md`) are only available in IDE extensions (VS Code, JetBrains, Visual Studio). GitHub Copilot CLI does not currently support custom prompt files — see [Supported Tools](supported-tools.md) for details and workarounds.

---

## Legacy Commands

These commands use the older "all-at-once" workflow. They still work but OPSX commands are recommended.

| Command | What it does |
|---------|--------------|
| `/openspec:proposal` | Create all artifacts at once (proposal, specs, design, tasks) |
| `/openspec:apply` | Implement the change |
| `/openspec:archive` | Archive the change |

**When to use legacy commands:**
- Existing projects using the old workflow
- Simple changes where you don't need incremental artifact creation
- Preference for the all-or-nothing approach

**Migrating to OPSX:**
Legacy changes can be continued with OPSX commands. The artifact structure is compatible.

---

## Troubleshooting

### "Change not found"

The command couldn't identify which change to work on.

**Solutions:**
- Specify the change name explicitly: `/opsx:apply add-dark-mode`
- Check that the change folder exists: `openspec list`
- Verify you're in the right project directory

### "No artifacts ready"

All artifacts are either complete or blocked by missing dependencies.

**Solutions:**
- Run `openspec status --change <name>` to see what's blocking
- Check if required artifacts exist
- Create missing dependency artifacts first

### "Schema not found"

The specified schema doesn't exist.

**Solutions:**
- List available schemas: `openspec schemas`
- Check spelling of schema name
- Create the schema if it's custom: `openspec schema init <name>`

### Commands not recognized

The AI tool doesn't recognize OpenSpec commands.

**Solutions:**
- Ensure OpenSpec is initialized: `openspec init`
- Regenerate skills: `openspec update`
- Check that `.claude/skills/` directory exists (for Claude Code)
- Restart your AI tool to pick up new skills

### Artifacts not generating properly

The AI creates incomplete or incorrect artifacts.

**Solutions:**
- Add project context in `openspec/config.yaml`
- Add per-artifact rules for specific guidance
- Provide more detail in your change description
- Use `/opsx:continue` instead of `/opsx:ff` for more control

---

## Next Steps

- [Workflows](workflows.md) - Common patterns and when to use each command
- [CLI](cli.md) - Terminal commands for management and validation
- [Customization](customization.md) - Create custom schemas and workflows


================================================
FILE: docs/concepts.md
================================================
# Concepts

This guide explains the core ideas behind OpenSpec and how they fit together. For practical usage, see [Getting Started](getting-started.md) and [Workflows](workflows.md).

## Philosophy

OpenSpec is built around four principles:

```
fluid not rigid       — no phase gates, work on what makes sense
iterative not waterfall — learn as you build, refine as you go
easy not complex      — lightweight setup, minimal ceremony
brownfield-first      — works with existing codebases, not just greenfield
```

### Why These Principles Matter

**Fluid not rigid.** Traditional spec systems lock you into phases: first you plan, then you implement, then you're done. OpenSpec is more flexible — you can create artifacts in any order that makes sense for your work.

**Iterative not waterfall.** Requirements change. Understanding deepens. What seemed like a good approach at the start might not hold up after you see the codebase. OpenSpec embraces this reality.

**Easy not complex.** Some spec frameworks require extensive setup, rigid formats, or heavyweight processes. OpenSpec stays out of your way. Initialize in seconds, start working immediately, customize only if you need to.

**Brownfield-first.** Most software work isn't building from scratch — it's modifying existing systems. OpenSpec's delta-based approach makes it easy to specify changes to existing behavior, not just describe new systems.

## The Big Picture

OpenSpec organizes your work into two main areas:

```
┌─────────────────────────────────────────────────────────────────┐
│                        openspec/                                 │
│                                                                  │
│   ┌─────────────────────┐      ┌──────────────────────────────┐ │
│   │       specs/        │      │         changes/              │ │
│   │                     │      │                               │ │
│   │  Source of truth    │◄─────│  Proposed modifications       │ │
│   │  How your system    │ merge│  Each change = one folder     │ │
│   │  currently works    │      │  Contains artifacts + deltas  │ │
│   │                     │      │                               │ │
│   └─────────────────────┘      └──────────────────────────────┘ │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

**Specs** are the source of truth — they describe how your system currently behaves.

**Changes** are proposed modifications — they live in separate folders until you're ready to merge them.

This separation is key. You can work on multiple changes in parallel without conflicts. You can review a change before it affects the main specs. And when you archive a change, its deltas merge cleanly into the source of truth.

## Specs

Specs describe your system's behavior using structured requirements and scenarios.

### Structure

```
openspec/specs/
├── auth/
│   └── spec.md           # Authentication behavior
├── payments/
│   └── spec.md           # Payment processing
├── notifications/
│   └── spec.md           # Notification system
└── ui/
    └── spec.md           # UI behavior and themes
```

Organize specs by domain — logical groupings that make sense for your system. Common patterns:

- **By feature area**: `auth/`, `payments/`, `search/`
- **By component**: `api/`, `frontend/`, `workers/`
- **By bounded context**: `ordering/`, `fulfillment/`, `inventory/`

### Spec Format

A spec contains requirements, and each requirement has scenarios:

```markdown
# Auth Specification

## Purpose
Authentication and session management for the application.

## Requirements

### Requirement: User Authentication
The system SHALL issue a JWT token upon successful login.

#### Scenario: Valid credentials
- GIVEN a user with valid credentials
- WHEN the user submits login form
- THEN a JWT token is returned
- AND the user is redirected to dashboard

#### Scenario: Invalid credentials
- GIVEN invalid credentials
- WHEN the user submits login form
- THEN an error message is displayed
- AND no token is issued

### Requirement: Session Expiration
The system MUST expire sessions after 30 minutes of inactivity.

#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 30 minutes pass without activity
- THEN the session is invalidated
- AND the user must re-authenticate
```

**Key elements:**

| Element | Purpose |
|---------|---------|
| `## Purpose` | High-level description of this spec's domain |
| `### Requirement:` | A specific behavior the system must have |
| `#### Scenario:` | A concrete example of the requirement in action |
| SHALL/MUST/SHOULD | RFC 2119 keywords indicating requirement strength |

### Why Structure Specs This Way

**Requirements are the "what"** — they state what the system should do without specifying implementation.

**Scenarios are the "when"** — they provide concrete examples that can be verified. Good scenarios:
- Are testable (you could write an automated test for them)
- Cover both happy path and edge cases
- Use Given/When/Then or similar structured format

**RFC 2119 keywords** (SHALL, MUST, SHOULD, MAY) communicate intent:
- **MUST/SHALL** — absolute requirement
- **SHOULD** — recommended, but exceptions exist
- **MAY** — optional

### What a Spec Is (and Is Not)

A spec is a **behavior contract**, not an implementation plan.

Good spec content:
- Observable behavior users or downstream systems rely on
- Inputs, outputs, and error conditions
- External constraints (security, privacy, reliability, compatibility)
- Scenarios that can be tested or explicitly validated

Avoid in specs:
- Internal class/function names
- Library or framework choices
- Step-by-step implementation details
- Detailed execution plans (those belong in `design.md` or `tasks.md`)

Quick test:
- If implementation can change without changing externally visible behavior, it likely does not belong in the spec.

### Keep It Lightweight: Progressive Rigor

OpenSpec aims to avoid bureaucracy. Use the lightest level that still makes the change verifiable.

**Lite spec (default):**
- Short behavior-first requirements
- Clear scope and non-goals
- A few concrete acceptance checks

**Full spec (for higher risk):**
- Cross-team or cross-repo changes
- API/contract changes, migrations, security/privacy concerns
- Changes where ambiguity is likely to cause expensive rework

Most changes should stay in Lite mode.

### Human + Agent Collaboration

In many teams, humans explore and agents draft artifacts. The intended loop is:

1. Human provides intent, context, and constraints.
2. Agent converts this into behavior-first requirements and scenarios.
3. Agent keeps implementation detail in `design.md` and `tasks.md`, not `spec.md`.
4. Validation confirms structure and clarity before implementation.

This keeps specs readable for humans and consistent for agents.

## Changes

A change is a proposed modification to your system, packaged as a folder with everything needed to understand and implement it.

### Change Structure

```
openspec/changes/add-dark-mode/
├── proposal.md           # Why and what
├── design.md             # How (technical approach)
├── tasks.md              # Implementation checklist
├── .openspec.yaml        # Change metadata (optional)
└── specs/                # Delta specs
    └── ui/
        └── spec.md       # What's changing in ui/spec.md
```

Each change is self-contained. It has:
- **Artifacts** — documents that capture intent, design, and tasks
- **Delta specs** — specifications for what's being added, modified, or removed
- **Metadata** — optional configuration for this specific change

### Why Changes Are Folders

Packaging a change as a folder has several benefits:

1. **Everything together.** Proposal, design, tasks, and specs live in one place. No hunting through different locations.

2. **Parallel work.** Multiple changes can exist simultaneously without conflicting. Work on `add-dark-mode` while `fix-auth-bug` is also in progress.

3. **Clean history.** When archived, changes move to `changes/archive/` with their full context preserved. You can look back and understand not just what changed, but why.

4. **Review-friendly.** A change folder is easy to review — open it, read the proposal, check the design, see the spec deltas.

## Artifacts

Artifacts are the documents within a change that guide the work.

### The Artifact Flow

```
proposal ──────► specs ──────► design ──────► tasks ──────► implement
    │               │             │              │
   why            what           how          steps
 + scope        changes       approach      to take
```

Artifacts build on each other. Each artifact provides context for the next.

### Artifact Types

#### Proposal (`proposal.md`)

The proposal captures **intent**, **scope**, and **approach** at a high level.

```markdown
# Proposal: Add Dark Mode

## Intent
Users have requested a dark mode option to reduce eye strain
during nighttime usage and match system preferences.

## Scope
In scope:
- Theme toggle in settings
- System preference detection
- Persist preference in localStorage

Out of scope:
- Custom color themes (future work)
- Per-page theme overrides

## Approach
Use CSS custom properties for theming with a React context
for state management. Detect system preference on first load,
allow manual override.
```

**When to update the proposal:**
- Scope changes (narrowing or expanding)
- Intent clarifies (better understanding of the problem)
- Approach fundamentally shifts

#### Specs (delta specs in `specs/`)

Delta specs describe **what's changing** relative to the current specs. See [Delta Specs](#delta-specs) below.

#### Design (`design.md`)

The design captures **technical approach** and **architecture decisions**.

````markdown
# Design: Add Dark Mode

## Technical Approach
Theme state managed via React Context to avoid prop drilling.
CSS custom properties enable runtime switching without class toggling.

## Architecture Decisions

### Decision: Context over Redux
Using React Context for theme state because:
- Simple binary state (light/dark)
- No complex state transitions
- Avoids adding Redux dependency

### Decision: CSS Custom Properties
Using CSS variables instead of CSS-in-JS because:
- Works with existing stylesheet
- No runtime overhead
- Browser-native solution

## Data Flow
```
ThemeProvider (context)
       │
       ▼
ThemeToggle ◄──► localStorage
       │
       ▼
CSS Variables (applied to :root)
```

## File Changes
- `src/contexts/ThemeContext.tsx` (new)
- `src/components/ThemeToggle.tsx` (new)
- `src/styles/globals.css` (modified)
````

**When to update the design:**
- Implementation reveals the approach won't work
- Better solution discovered
- Dependencies or constraints change

#### Tasks (`tasks.md`)

Tasks are the **implementation checklist** — concrete steps with checkboxes.

```markdown
# Tasks

## 1. Theme Infrastructure
- [ ] 1.1 Create ThemeContext with light/dark state
- [ ] 1.2 Add CSS custom properties for colors
- [ ] 1.3 Implement localStorage persistence
- [ ] 1.4 Add system preference detection

## 2. UI Components
- [ ] 2.1 Create ThemeToggle component
- [ ] 2.2 Add toggle to settings page
- [ ] 2.3 Update Header to include quick toggle

## 3. Styling
- [ ] 3.1 Define dark theme color palette
- [ ] 3.2 Update components to use CSS variables
- [ ] 3.3 Test contrast ratios for accessibility
```

**Task best practices:**
- Group related tasks under headings
- Use hierarchical numbering (1.1, 1.2, etc.)
- Keep tasks small enough to complete in one session
- Check tasks off as you complete them

## Delta Specs

Delta specs are the key concept that makes OpenSpec work for brownfield development. They describe **what's changing** rather than restating the entire spec.

### The Format

```markdown
# Delta for Auth

## ADDED Requirements

### Requirement: Two-Factor Authentication
The system MUST support TOTP-based two-factor authentication.

#### Scenario: 2FA enrollment
- GIVEN a user without 2FA enabled
- WHEN the user enables 2FA in settings
- THEN a QR code is displayed for authenticator app setup
- AND the user must verify with a code before activation

#### Scenario: 2FA login
- GIVEN a user with 2FA enabled
- WHEN the user submits valid credentials
- THEN an OTP challenge is presented
- AND login completes only after valid OTP

## MODIFIED Requirements

### Requirement: Session Expiration
The system MUST expire sessions after 15 minutes of inactivity.
(Previously: 30 minutes)

#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 15 minutes pass without activity
- THEN the session is invalidated

## REMOVED Requirements

### Requirement: Remember Me
(Deprecated in favor of 2FA. Users should re-authenticate each session.)
```

### Delta Sections

| Section | Meaning | What Happens on Archive |
|---------|---------|------------------------|
| `## ADDED Requirements` | New behavior | Appended to main spec |
| `## MODIFIED Requirements` | Changed behavior | Replaces existing requirement |
| `## REMOVED Requirements` | Deprecated behavior | Deleted from main spec |

### Why Deltas Instead of Full Specs

**Clarity.** A delta shows exactly what's changing. Reading a full spec, you'd have to diff it mentally against the current version.

**Conflict avoidance.** Two changes can touch the same spec file without conflicting, as long as they modify different requirements.

**Review efficiency.** Reviewers see the change, not the unchanged context. Focus on what matters.

**Brownfield fit.** Most work modifies existing behavior. Deltas make modifications first-class, not an afterthought.

## Schemas

Schemas define the artifact types and their dependencies for a workflow.

### How Schemas Work

```yaml
# openspec/schemas/spec-driven/schema.yaml
name: spec-driven
artifacts:
  - id: proposal
    generates: proposal.md
    requires: []              # No dependencies, can create first

  - id: specs
    generates: specs/**/*.md
    requires: [proposal]      # Needs proposal before creating

  - id: design
    generates: design.md
    requires: [proposal]      # Can create in parallel with specs

  - id: tasks
    generates: tasks.md
    requires: [specs, design] # Needs both specs and design first
```

**Artifacts form a dependency graph:**

```
                    proposal
                   (root node)
                       │
         ┌─────────────┴─────────────┐
         │                           │
         ▼                           ▼
      specs                       design
   (requires:                  (requires:
    proposal)                   proposal)
         │                           │
         └─────────────┬─────────────┘
                       │
                       ▼
                    tasks
                (requires:
                specs, design)
```

**Dependencies are enablers, not gates.** They show what's possible to create, not what you must create next. You can skip design if you don't need it. You can create specs before or after design — both depend only on proposal.

### Built-in Schemas

**spec-driven** (default)

The standard workflow for spec-driven development:

```
proposal → specs → design → tasks → implement
```

Best for: Most feature work where you want to agree on specs before implementation.

### Custom Schemas

Create custom schemas for your team's workflow:

```bash
# Create from scratch
openspec schema init research-first

# Or fork an existing one
openspec schema fork spec-driven research-first
```

**Example custom schema:**

```yaml
# openspec/schemas/research-first/schema.yaml
name: research-first
artifacts:
  - id: research
    generates: research.md
    requires: []           # Do research first

  - id: proposal
    generates: proposal.md
    requires: [research]   # Proposal informed by research

  - id: tasks
    generates: tasks.md
    requires: [proposal]   # Skip specs/design, go straight to tasks
```

See [Customization](customization.md) for full details on creating and using custom schemas.

## Archive

Archiving completes a change by merging its delta specs into the main specs and preserving the change for history.

### What Happens When You Archive

```
Before archive:

openspec/
├── specs/
│   └── auth/
│       └── spec.md ◄────────────────┐
└── changes/                         │
    └── add-2fa/                     │
        ├── proposal.md              │
        ├── design.md                │ merge
        ├── tasks.md                 │
        └── specs/                   │
            └── auth/                │
                └── spec.md ─────────┘


After archive:

openspec/
├── specs/
│   └── auth/
│       └── spec.md        # Now includes 2FA requirements
└── changes/
    └── archive/
        └── 2025-01-24-add-2fa/    # Preserved for history
            ├── proposal.md
            ├── design.md
            ├── tasks.md
            └── specs/
                └── auth/
                    └── spec.md
```

### The Archive Process

1. **Merge deltas.** Each delta spec section (ADDED/MODIFIED/REMOVED) is applied to the corresponding main spec.

2. **Move to archive.** The change folder moves to `changes/archive/` with a date prefix for chronological ordering.

3. **Preserve context.** All artifacts remain intact in the archive. You can always look back to understand why a change was made.

### Why Archive Matters

**Clean state.** Active changes (`changes/`) shows only work in progress. Completed work moves out of the way.

**Audit trail.** The archive preserves the full context of every change — not just what changed, but the proposal explaining why, the design explaining how, and the tasks showing the work done.

**Spec evolution.** Specs grow organically as changes are archived. Each archive merges its deltas, building up a comprehensive specification over time.

## How It All Fits Together

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                              OPENSPEC FLOW                                   │
│                                                                              │
│   ┌────────────────┐                                                         │
│   │  1. START      │  /opsx:propose (core) or /opsx:new (expanded)          │
│   │     CHANGE     │                                                         │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  2. CREATE     │  /opsx:ff or /opsx:continue (expanded workflow)         │
│   │     ARTIFACTS  │  Creates proposal → specs → design → tasks              │
│   │                │  (based on schema dependencies)                         │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  3. IMPLEMENT  │  /opsx:apply                                            │
│   │     TASKS      │  Work through tasks, checking them off                  │
│   │                │◄──── Update artifacts as you learn                      │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  4. VERIFY     │  /opsx:verify (optional)                                │
│   │     WORK       │  Check implementation matches specs                     │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐     ┌──────────────────────────────────────────────┐   │
│   │  5. ARCHIVE    │────►│  Delta specs merge into main specs           │   │
│   │     CHANGE     │     │  Change folder moves to archive/             │   │
│   └────────────────┘     │  Specs are now the updated source of truth   │   │
│                          └──────────────────────────────────────────────┘   │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
```

**The virtuous cycle:**

1. Specs describe current behavior
2. Changes propose modifications (as deltas)
3. Implementation makes the changes real
4. Archive merges deltas into specs
5. Specs now describe the new behavior
6. Next change builds on updated specs

## Glossary

| Term | Definition |
|------|------------|
| **Artifact** | A document within a change (proposal, design, tasks, or delta specs) |
| **Archive** | The process of completing a change and merging its deltas into main specs |
| **Change** | A proposed modification to the system, packaged as a folder with artifacts |
| **Delta spec** | A spec that describes changes (ADDED/MODIFIED/REMOVED) relative to current specs |
| **Domain** | A logical grouping for specs (e.g., `auth/`, `payments/`) |
| **Requirement** | A specific behavior the system must have |
| **Scenario** | A concrete example of a requirement, typically in Given/When/Then format |
| **Schema** | A definition of artifact types and their dependencies |
| **Spec** | A specification describing system behavior, containing requirements and scenarios |
| **Source of truth** | The `openspec/specs/` directory, containing the current agreed-upon behavior |

## Next Steps

- [Getting Started](getting-started.md) - Practical first steps
- [Workflows](workflows.md) - Common patterns and when to use each
- [Commands](commands.md) - Full command reference
- [Customization](customization.md) - Create custom schemas and configure your project


================================================
FILE: docs/customization.md
================================================
# Customization

OpenSpec provides three levels of customization:

| Level | What it does | Best for |
|-------|--------------|----------|
| **Project Config** | Set defaults, inject context/rules | Most teams |
| **Custom Schemas** | Define your own workflow artifacts | Teams with unique processes |
| **Global Overrides** | Share schemas across all projects | Power users |

---

## Project Configuration

The `openspec/config.yaml` file is the easiest way to customize OpenSpec for your team. It lets you:

- **Set a default schema** - Skip `--schema` on every command
- **Inject project context** - AI sees your tech stack, conventions, etc.
- **Add per-artifact rules** - Custom rules for specific artifacts

### Quick Setup

```bash
openspec init
```

This walks you through creating a config interactively. Or create one manually:

```yaml
# openspec/config.yaml
schema: spec-driven

context: |
  Tech stack: TypeScript, React, Node.js, PostgreSQL
  API style: RESTful, documented in docs/api.md
  Testing: Jest + React Testing Library
  We value backwards compatibility for all public APIs

rules:
  proposal:
    - Include rollback plan
    - Identify affected teams
  specs:
    - Use Given/When/Then format
    - Reference existing patterns before inventing new ones
```

### How It Works

**Default schema:**

```bash
# Without config
openspec new change my-feature --schema spec-driven

# With config - schema is automatic
openspec new change my-feature
```

**Context and rules injection:**

When generating any artifact, your context and rules are injected into the AI prompt:

```xml
<context>
Tech stack: TypeScript, React, Node.js, PostgreSQL
...
</context>

<rules>
- Include rollback plan
- Identify affected teams
</rules>

<template>
[Schema's built-in template]
</template>
```

- **Context** appears in ALL artifacts
- **Rules** ONLY appear for the matching artifact

### Schema Resolution Order

When OpenSpec needs a schema, it checks in this order:

1. CLI flag: `--schema <name>`
2. Change metadata (`.openspec.yaml` in the change folder)
3. Project config (`openspec/config.yaml`)
4. Default (`spec-driven`)

---

## Custom Schemas

When project config isn't enough, create your own schema with a completely custom workflow. Custom schemas live in your project's `openspec/schemas/` directory and are version-controlled with your code.

```text
your-project/
├── openspec/
│   ├── config.yaml        # Project config
│   ├── schemas/           # Custom schemas live here
│   │   └── my-workflow/
│   │       ├── schema.yaml
│   │       └── templates/
│   └── changes/           # Your changes
└── src/
```

### Fork an Existing Schema

The fastest way to customize is to fork a built-in schema:

```bash
openspec schema fork spec-driven my-workflow
```

This copies the entire `spec-driven` schema to `openspec/schemas/my-workflow/` where you can edit it freely.

**What you get:**

```text
openspec/schemas/my-workflow/
├── schema.yaml           # Workflow definition
└── templates/
    ├── proposal.md       # Template for proposal artifact
    ├── spec.md           # Template for specs
    ├── design.md         # Template for design
    └── tasks.md          # Template for tasks
```

Now edit `schema.yaml` to change the workflow, or edit templates to change what AI generates.

### Create a Schema from Scratch

For a completely fresh workflow:

```bash
# Interactive
openspec schema init research-first

# Non-interactive
openspec schema init rapid \
  --description "Rapid iteration workflow" \
  --artifacts "proposal,tasks" \
  --default
```

### Schema Structure

A schema defines the artifacts in your workflow and how they depend on each other:

```yaml
# openspec/schemas/my-workflow/schema.yaml
name: my-workflow
version: 1
description: My team's custom workflow

artifacts:
  - id: proposal
    generates: proposal.md
    description: Initial proposal document
    template: proposal.md
    instruction: |
      Create a proposal that explains WHY this change is needed.
      Focus on the problem, not the solution.
    requires: []

  - id: design
    generates: design.md
    description: Technical design
    template: design.md
    instruction: |
      Create a design document explaining HOW to implement.
    requires:
      - proposal    # Can't create design until proposal exists

  - id: tasks
    generates: tasks.md
    description: Implementation checklist
    template: tasks.md
    requires:
      - design

apply:
  requires: [tasks]
  tracks: tasks.md
```

**Key fields:**

| Field | Purpose |
|-------|---------|
| `id` | Unique identifier, used in commands and rules |
| `generates` | Output filename (supports globs like `specs/**/*.md`) |
| `template` | Template file in `templates/` directory |
| `instruction` | AI instructions for creating this artifact |
| `requires` | Dependencies - which artifacts must exist first |

### Templates

Templates are markdown files that guide the AI. They're injected into the prompt when creating that artifact.

```markdown
<!-- templates/proposal.md -->
## Why

<!-- Explain the motivation for this change. What problem does this solve? -->

## What Changes

<!-- Describe what will change. Be specific about new capabilities or modifications. -->

## Impact

<!-- Affected code, APIs, dependencies, systems -->
```

Templates can include:
- Section headers the AI should fill in
- HTML comments with guidance for the AI
- Example formats showing expected structure

### Validate Your Schema

Before using a custom schema, validate it:

```bash
openspec schema validate my-workflow
```

This checks:
- `schema.yaml` syntax is correct
- All referenced templates exist
- No circular dependencies
- Artifact IDs are valid

### Use Your Custom Schema

Once created, use your schema with:

```bash
# Specify on command
openspec new change feature --schema my-workflow

# Or set as default in config.yaml
schema: my-workflow
```

### Debug Schema Resolution

Not sure which schema is being used? Check with:

```bash
# See where a specific schema resolves from
openspec schema which my-workflow

# List all available schemas
openspec schema which --all
```

Output shows whether it's from your project, user directory, or the package:

```text
Schema: my-workflow
Source: project
Path: /path/to/project/openspec/schemas/my-workflow
```

---

> **Note:** OpenSpec also supports user-level schemas at `~/.local/share/openspec/schemas/` for sharing across projects, but project-level schemas in `openspec/schemas/` are recommended since they're version-controlled with your code.

---

## Examples

### Rapid Iteration Workflow

A minimal workflow for quick iterations:

```yaml
# openspec/schemas/rapid/schema.yaml
name: rapid
version: 1
description: Fast iteration with minimal overhead

artifacts:
  - id: proposal
    generates: proposal.md
    description: Quick proposal
    template: proposal.md
    instruction: |
      Create a brief proposal for this change.
      Focus on what and why, skip detailed specs.
    requires: []

  - id: tasks
    generates: tasks.md
    description: Implementation checklist
    template: tasks.md
    requires: [proposal]

apply:
  requires: [tasks]
  tracks: tasks.md
```

### Adding a Review Artifact

Fork the default and add a review step:

```bash
openspec schema fork spec-driven with-review
```

Then edit `schema.yaml` to add:

```yaml
  - id: review
    generates: review.md
    description: Pre-implementation review checklist
    template: review.md
    instruction: |
      Create a review checklist based on the design.
      Include security, performance, and testing considerations.
    requires:
      - design

  - id: tasks
    # ... existing tasks config ...
    requires:
      - specs
      - design
      - review    # Now tasks require review too
```

---

## See Also

- [CLI Reference: Schema Commands](cli.md#schema-commands) - Full command documentation


================================================
FILE: docs/getting-started.md
================================================
# Getting Started

This guide explains how OpenSpec works after you've installed and initialized it. For installation instructions, see the [main README](../README.md#quick-start).

## How It Works

OpenSpec helps you and your AI coding assistant agree on what to build before any code is written.

**Default quick path (core profile):**

```text
/opsx:propose ──► /opsx:apply ──► /opsx:archive
```

**Expanded path (custom workflow selection):**

```text
/opsx:new ──► /opsx:ff or /opsx:continue ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
```

The default global profile is `core`, which includes `propose`, `explore`, `apply`, and `archive`. You can enable the expanded workflow commands with `openspec config profile` and then `openspec update`.

## What OpenSpec Creates

After running `openspec init`, your project has this structure:

```
openspec/
├── specs/              # Source of truth (your system's behavior)
│   └── <domain>/
│       └── spec.md
├── changes/            # Proposed updates (one folder per change)
│   └── <change-name>/
│       ├── proposal.md
│       ├── design.md
│       ├── tasks.md
│       └── specs/      # Delta specs (what's changing)
│           └── <domain>/
│               └── spec.md
└── config.yaml         # Project configuration (optional)
```

**Two key directories:**

- **`specs/`** - The source of truth. These specs describe how your system currently behaves. Organized by domain (e.g., `specs/auth/`, `specs/payments/`).

- **`changes/`** - Proposed modifications. Each change gets its own folder with all related artifacts. When a change is complete, its specs merge into the main `specs/` directory.

## Understanding Artifacts

Each change folder contains artifacts that guide the work:

| Artifact | Purpose |
|----------|---------|
| `proposal.md` | The "why" and "what" - captures intent, scope, and approach |
| `specs/` | Delta specs showing ADDED/MODIFIED/REMOVED requirements |
| `design.md` | The "how" - technical approach and architecture decisions |
| `tasks.md` | Implementation checklist with checkboxes |

**Artifacts build on each other:**

```
proposal ──► specs ──► design ──► tasks ──► implement
   ▲           ▲          ▲                    │
   └───────────┴──────────┴────────────────────┘
            update as you learn
```

You can always go back and refine earlier artifacts as you learn more during implementation.

## How Delta Specs Work

Delta specs are the key concept in OpenSpec. They show what's changing relative to your current specs.

### The Format

Delta specs use sections to indicate the type of change:

```markdown
# Delta for Auth

## ADDED Requirements

### Requirement: Two-Factor Authentication
The system MUST require a second factor during login.

#### Scenario: OTP required
- GIVEN a user with 2FA enabled
- WHEN the user submits valid credentials
- THEN an OTP challenge is presented

## MODIFIED Requirements

### Requirement: Session Timeout
The system SHALL expire sessions after 30 minutes of inactivity.
(Previously: 60 minutes)

#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 30 minutes pass without activity
- THEN the session is invalidated

## REMOVED Requirements

### Requirement: Remember Me
(Deprecated in favor of 2FA)
```

### What Happens on Archive

When you archive a change:

1. **ADDED** requirements are appended to the main spec
2. **MODIFIED** requirements replace the existing version
3. **REMOVED** requirements are deleted from the main spec

The change folder moves to `openspec/changes/archive/` for audit history.

## Example: Your First Change

Let's walk through adding dark mode to an application.

### 1. Start the Change (Default)

```text
You: /opsx:propose add-dark-mode

AI:  Created openspec/changes/add-dark-mode/
     ✓ proposal.md — why we're doing this, what's changing
     ✓ specs/       — requirements and scenarios
     ✓ design.md    — technical approach
     ✓ tasks.md     — implementation checklist
     Ready for implementation!
```

If you've enabled the expanded workflow profile, you can also do this as two steps: `/opsx:new` then `/opsx:ff` (or `/opsx:continue` incrementally).

### 2. What Gets Created

**proposal.md** - Captures the intent:

```markdown
# Proposal: Add Dark Mode

## Intent
Users have requested a dark mode option to reduce eye strain
during nighttime usage.

## Scope
- Add theme toggle in settings
- Support system preference detection
- Persist preference in localStorage

## Approach
Use CSS custom properties for theming with a React context
for state management.
```

**specs/ui/spec.md** - Delta showing new requirements:

```markdown
# Delta for UI

## ADDED Requirements

### Requirement: Theme Selection
The system SHALL allow users to choose between light and dark themes.

#### Scenario: Manual toggle
- GIVEN a user on any page
- WHEN the user clicks the theme toggle
- THEN the theme switches immediately
- AND the preference persists across sessions

#### Scenario: System preference
- GIVEN a user with no saved preference
- WHEN the application loads
- THEN the system's preferred color scheme is used
```

**tasks.md** - Implementation checklist:

```markdown
# Tasks

## 1. Theme Infrastructure
- [ ] 1.1 Create ThemeContext with light/dark state
- [ ] 1.2 Add CSS custom properties for colors
- [ ] 1.3 Implement localStorage persistence

## 2. UI Components
- [ ] 2.1 Create ThemeToggle component
- [ ] 2.2 Add toggle to settings page
- [ ] 2.3 Update Header to include quick toggle

## 3. Styling
- [ ] 3.1 Define dark theme color palette
- [ ] 3.2 Update components to use CSS variables
```

### 3. Implement

```
You: /opsx:apply

AI:  Working through tasks...
     ✓ 1.1 Created ThemeContext with light/dark state
     ✓ 1.2 Added CSS custom properties to globals.css
     ✓ 1.3 Implemented localStorage persistence
     ✓ 2.1 Created ThemeToggle component
     ...
     All tasks complete!
```

During implementation, if you discover the design needs adjustment, just update the artifact and continue.

### 4. Archive

```
You: /opsx:archive

AI:  Archiving add-dark-mode...
     ✓ Merged specs into openspec/specs/ui/spec.md
     ✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/
     Done! Ready for the next feature.
```

Your delta specs are now part of the main specs, documenting how your system works.

## Verifying and Reviewing

Use the CLI to check on your changes:

```bash
# List active changes
openspec list

# View change details
openspec show add-dark-mode

# Validate spec formatting
openspec validate add-dark-mode

# Interactive dashboard
openspec view
```

## Next Steps

- [Workflows](workflows.md) - Common patterns and when to use each command
- [Commands](commands.md) - Full reference for all slash commands
- [Concepts](concepts.md) - Deeper understanding of specs, changes, and schemas
- [Customization](customization.md) - Make OpenSpec work your way


================================================
FILE: docs/installation.md
================================================
# Installation

## Prerequisites

- **Node.js 20.19.0 or higher** — Check your version: `node --version`

## Package Managers

### npm

```bash
npm install -g @fission-ai/openspec@latest
```

### pnpm

```bash
pnpm add -g @fission-ai/openspec@latest
```

### yarn

```bash
yarn global add @fission-ai/openspec@latest
```

### bun

```bash
bun add -g @fission-ai/openspec@latest
```

## Nix

Run OpenSpec directly without installation:

```bash
nix run github:Fission-AI/OpenSpec -- init
```

Or install to your profile:

```bash
nix profile install github:Fission-AI/OpenSpec
```

Or add to your development environment in `flake.nix`:

```nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    openspec.url = "github:Fission-AI/OpenSpec";
  };

  outputs = { nixpkgs, openspec, ... }: {
    devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
      buildInputs = [ openspec.packages.x86_64-linux.default ];
    };
  };
}
```

## Verify Installation

```bash
openspec --version
```

## Next Steps

After installing, initialize OpenSpec in your project:

```bash
cd your-project
openspec init
```

See [Getting Started](getting-started.md) for a full walkthrough.


================================================
FILE: docs/migration-guide.md
================================================
# Migrating to OPSX

This guide helps you transition from the legacy OpenSpec workflow to OPSX. The migration is designed to be smooth—your existing work is preserved, and the new system offers more flexibility.

## What's Changing?

OPSX replaces the old phase-locked workflow with a fluid, action-based approach. Here's the key shift:

| Aspect | Legacy | OPSX |
|--------|--------|------|
| **Commands** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` | Default: `/opsx:propose`, `/opsx:apply`, `/opsx:archive` (expanded workflow commands optional) |
| **Workflow** | Create all artifacts at once | Create incrementally or all at once—your choice |
| **Going back** | Awkward phase gates | Natural—update any artifact anytime |
| **Customization** | Fixed structure | Schema-driven, fully hackable |
| **Configuration** | `CLAUDE.md` with markers + `project.md` | Clean config in `openspec/config.yaml` |

**The philosophy change:** Work isn't linear. OPSX stops pretending it is.

---

## Before You Begin

### Your Existing Work Is Safe

The migration process is designed with preservation in mind:

- **Active changes in `openspec/changes/`** — Completely preserved. You can continue them with OPSX commands.
- **Archived changes** — Untouched. Your history remains intact.
- **Main specs in `openspec/specs/`** — Untouched. These are your source of truth.
- **Your content in CLAUDE.md, AGENTS.md, etc.** — Preserved. Only the OpenSpec marker blocks are removed; everything you wrote stays.

### What Gets Removed

Only OpenSpec-managed files that are being replaced:

| What | Why |
|------|-----|
| Legacy slash command directories/files | Replaced by the new skills system |
| `openspec/AGENTS.md` | Obsolete workflow trigger |
| OpenSpec markers in `CLAUDE.md`, `AGENTS.md`, etc. | No longer needed |

**Legacy command locations by tool** (examples—your tool may vary):

- Claude Code: `.claude/commands/openspec/`
- Cursor: `.cursor/commands/openspec-*.md`
- Windsurf: `.windsurf/workflows/openspec-*.md`
- Cline: `.clinerules/workflows/openspec-*.md`
- Roo: `.roo/commands/openspec-*.md`
- GitHub Copilot: `.github/prompts/openspec-*.prompt.md` (IDE extensions only; not supported in Copilot CLI)
- And others (Augment, Continue, Amazon Q, etc.)

The migration detects whichever tools you have configured and cleans up their legacy files.

The removal list may seem long, but these are all files that OpenSpec originally created. Your own content is never deleted.

### What Needs Your Attention

One file requires manual migration:

**`openspec/project.md`** — This file isn't deleted automatically because it may contain project context you've written. You'll need to:

1. Review its contents
2. Move useful context to `openspec/config.yaml` (see guidance below)
3. Delete the file when ready

**Why we made this change:**

The old `project.md` was passive—agents might read it, might not, might forget what they read. We found reliability was inconsistent.

The new `config.yaml` context is **actively injected into every OpenSpec planning request**. This means your project conventions, tech stack, and rules are always present when the AI is creating artifacts. Higher reliability.

**The tradeoff:**

Because context is injected into every request, you'll want to be concise. Focus on what really matters:
- Tech stack and key conventions
- Non-obvious constraints the AI needs to know
- Rules that frequently got ignored before

Don't worry about getting it perfect. We're still learning what works best here, and we'll be improving how context injection works as we experiment.

---

## Running the Migration

Both `openspec init` and `openspec update` detect legacy files and guide you through the same cleanup process. Use whichever fits your situation:

- New installs default to profile `core` (`propose`, `explore`, `apply`, `archive`).
- Migrated installs preserve your previously installed workflows by writing a `custom` profile when needed.

### Using `openspec init`

Run this if you want to add new tools or reconfigure which tools are set up:

```bash
openspec init
```

The init command detects legacy files and guides you through cleanup:

```
Upgrading to the new OpenSpec

OpenSpec now uses agent skills, the emerging standard across coding
agents. This simplifies your setup while keeping everything working
as before.

Files to remove
No user content to preserve:
  • .claude/commands/openspec/
  • openspec/AGENTS.md

Files to update
OpenSpec markers will be removed, your content preserved:
  • CLAUDE.md
  • AGENTS.md

Needs your attention
  • openspec/project.md
    We won't delete this file. It may contain useful project context.

    The new openspec/config.yaml has a "context:" section for planning
    context. This is included in every OpenSpec request and works more
    reliably than the old project.md approach.

    Review project.md, move any useful content to config.yaml's context
    section, then delete the file when ready.

? Upgrade and clean up legacy files? (Y/n)
```

**What happens when you say yes:**

1. Legacy slash command directories are removed
2. OpenSpec markers are stripped from `CLAUDE.md`, `AGENTS.md`, etc. (your content stays)
3. `openspec/AGENTS.md` is deleted
4. New skills are installed in `.claude/skills/`
5. `openspec/config.yaml` is created with a default schema

### Using `openspec update`

Run this if you just want to migrate and refresh your existing tools to the latest version:

```bash
openspec update
```

The update command also detects and cleans up legacy artifacts, then refreshes generated skills/commands to match your current profile and delivery settings.

### Non-Interactive / CI Environments

For scripted migrations:

```bash
openspec init --force --tools claude
```

The `--force` flag skips prompts and auto-accepts cleanup.

---

## Migrating project.md to config.yaml

The old `openspec/project.md` was a freeform markdown file for project context. The new `openspec/config.yaml` is structured and—critically—**injected into every planning request** so your conventions are always present when the AI works.

### Before (project.md)

```markdown
# Project Context

This is a TypeScript monorepo using React and Node.js.
We use Jest for testing and follow strict ESLint rules.
Our API is RESTful and documented in docs/api.md.

## Conventions

- All public APIs must maintain backwards compatibility
- New features should include tests
- Use Given/When/Then format for specifications
```

### After (config.yaml)

```yaml
schema: spec-driven

context: |
  Tech stack: TypeScript, React, Node.js
  Testing: Jest with React Testing Library
  API: RESTful, documented in docs/api.md
  We maintain backwards compatibility for all public APIs

rules:
  proposal:
    - Include rollback plan for risky changes
  specs:
    - Use Given/When/Then format for scenarios
    - Reference existing patterns before inventing new ones
  design:
    - Include sequence diagrams for complex flows
```

### Key Differences

| project.md | config.yaml |
|------------|-------------|
| Freeform markdown | Structured YAML |
| One blob of text | Separate context and per-artifact rules |
| Unclear when it's used | Context appears in ALL artifacts; rules appear in matching artifacts only |
| No schema selection | Explicit `schema:` field sets default workflow |

### What to Keep, What to Drop

When migrating, be selective. Ask yourself: "Does the AI need this for *every* planning request?"

**Good candidates for `context:`**
- Tech stack (languages, frameworks, databases)
- Key architectural patterns (monorepo, microservices, etc.)
- Non-obvious constraints ("we can't use library X because...")
- Critical conventions that often get ignored

**Move to `rules:` instead**
- Artifact-specific formatting ("use Given/When/Then in specs")
- Review criteria ("proposals must include rollback plans")
- These only appear for the matching artifact, keeping other requests lighter

**Leave out entirely**
- General best practices the AI already knows
- Verbose explanations that could be summarized
- Historical context that doesn't affect current work

### Migration Steps

1. **Create config.yaml** (if not already created by init):
   ```yaml
   schema: spec-driven
   ```

2. **Add your context** (be concise—this goes into every request):
   ```yaml
   context: |
     Your project background goes here.
     Focus on what the AI genuinely needs to know.
   ```

3. **Add per-artifact rules** (optional):
   ```yaml
   rules:
     proposal:
       - Your proposal-specific guidance
     specs:
       - Your spec-writing rules
   ```

4. **Delete project.md** once you've moved everything useful.

**Don't overthink it.** Start with the essentials and iterate. If you notice the AI missing something important, add it. If context feels bloated, trim it. This is a living document.

### Need Help? Use This Prompt

If you're unsure how to distill your project.md, ask your AI assistant:

```
I'm migrating from OpenSpec's old project.md to the new config.yaml format.

Here's my current project.md:
[paste your project.md content]

Please help me create a config.yaml with:
1. A concise `context:` section (this gets injected into every planning request, so keep it tight—focus on tech stack, key constraints, and conventions that often get ignored)
2. `rules:` for specific artifacts if any content is artifact-specific (e.g., "use Given/When/Then" belongs in specs rules, not global context)

Leave out anything generic that AI models already know. Be ruthless about brevity.
```

The AI will help you identify what's essential vs. what can be trimmed.

---

## The New Commands

Command availability is profile-dependent:

**Default (`core` profile):**

| Command | Purpose |
|---------|---------|
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
| `/opsx:explore` | Think through ideas with no structure |
| `/opsx:apply` | Implement tasks from tasks.md |
| `/opsx:archive` | Finalize and archive the change |

**Expanded workflow (custom selection):**

| Command | Purpose |
|---------|---------|
| `/opsx:new` | Start a new change scaffold |
| `/opsx:continue` | Create the next artifact (one at a time) |
| `/opsx:ff` | Fast-forward—create planning artifacts at once |
| `/opsx:verify` | Validate implementation matches specs |
| `/opsx:sync` | Preview/spec-merge without archiving |
| `/opsx:bulk-archive` | Archive multiple changes at once |
| `/opsx:onboard` | Guided end-to-end onboarding workflow |

Enable expanded commands with `openspec config profile`, then run `openspec update`.

### Command Mapping from Legacy

| Legacy | OPSX Equivalent |
|--------|-----------------|
| `/openspec:proposal` | `/opsx:propose` (default) or `/opsx:new` then `/opsx:ff` (expanded) |
| `/openspec:apply` | `/opsx:apply` |
| `/openspec:archive` | `/opsx:archive` |

### New Capabilities

These capabilities are part of the expanded workflow command set.

**Granular artifact creation:**
```
/opsx:continue
```
Creates one artifact at a time based on dependencies. Use this when you want to review each step.

**Exploration mode:**
```
/opsx:explore
```
Think through ideas with a partner before committing to a change.

---

## Understanding the New Architecture

### From Phase-Locked to Fluid

The legacy workflow forced linear progression:

```
┌──────────────┐      ┌──────────────┐      ┌──────────────┐
│   PLANNING   │ ───► │ IMPLEMENTING │ ───► │   ARCHIVING  │
│    PHASE     │      │    PHASE     │      │    PHASE     │
└──────────────┘      └──────────────┘      └──────────────┘

If you're in implementation and realize the design is wrong?
Too bad. Phase gates don't let you go back easily.
```

OPSX uses actions, not phases:

```
         ┌───────────────────────────────────────────────┐
         │           ACTIONS (not phases)                │
         │                                               │
         │     new ◄──► continue ◄──► apply ◄──► archive │
         │      │          │           │             │   │
         │      └──────────┴───────────┴─────────────┘   │
         │                    any order                  │
         └───────────────────────────────────────────────┘
```

### Dependency Graph

Artifacts form a directed graph. Dependencies are enablers, not gates:

```
                        proposal
                       (root node)
                            │
              ┌─────────────┴─────────────┐
              │                           │
              ▼                           ▼
           specs                       design
        (requires:                  (requires:
         proposal)                   proposal)
              │                           │
              └─────────────┬─────────────┘
                            │
                            ▼
                         tasks
                     (requires:
                     specs, design)
```

When you run `/opsx:continue`, it checks what's ready and offers the next artifact. You can also create multiple ready artifacts in any order.

### Skills vs Commands

The legacy system used tool-specific command files:

```
.claude/commands/openspec/
├── proposal.md
├── apply.md
└── archive.md
```

OPSX uses the emerging **skills** standard:

```
.claude/skills/
├── openspec-explore/SKILL.md
├── openspec-new-change/SKILL.md
├── openspec-continue-change/SKILL.md
├── openspec-apply-change/SKILL.md
└── ...
```

Skills are recognized across multiple AI coding tools and provide richer metadata.

---

## Continuing Existing Changes

Your in-progress changes work seamlessly with OPSX commands.

**Have an active change from the legacy workflow?**

```
/opsx:apply add-my-feature
```

OPSX reads the existing artifacts and continues from where you left off.

**Want to add more artifacts to an existing change?**

```
/opsx:continue add-my-feature
```

Shows what's ready to create based on what already exists.

**Need to see status?**

```bash
openspec status --change add-my-feature
```

---

## The New Config System

### config.yaml Structure

```yaml
# Required: Default schema for new changes
schema: spec-driven

# Optional: Project context (max 50KB)
# Injected into ALL artifact instructions
context: |
  Your project background, tech stack,
  conventions, and constraints.

# Optional: Per-artifact rules
# Only injected into matching artifacts
rules:
  proposal:
    - Include rollback plan
  specs:
    - Use Given/When/Then format
  design:
    - Document fallback strategies
  tasks:
    - Break into 2-hour maximum chunks
```

### Schema Resolution

When determining which schema to use, OPSX checks in order:

1. **CLI flag**: `--schema <name>` (highest priority)
2. **Change metadata**: `.openspec.yaml` in the change directory
3. **Project config**: `openspec/config.yaml`
4. **Default**: `spec-driven`

### Available Schemas

| Schema | Artifacts | Best For |
|--------|-----------|----------|
| `spec-driven` | proposal → specs → design → tasks | Most projects |

List all available schemas:

```bash
openspec schemas
```

### Custom Schemas

Create your own workflow:

```bash
openspec schema init my-workflow
```

Or fork an existing one:

```bash
openspec schema fork spec-driven my-workflow
```

See [Customization](customization.md) for details.

---

## Troubleshooting

### "Legacy files detected in non-interactive mode"

You're running in a CI or non-interactive environment. Use:

```bash
openspec init --force
```

### Commands not appearing after migration

Restart your IDE. Skills are detected at startup.

### "Unknown artifact ID in rules"

Check that your `rules:` keys match your schema's artifact IDs:

- **spec-driven**: `proposal`, `specs`, `design`, `tasks`

Run this to see valid artifact IDs:

```bash
openspec schemas --json
```

### Config not being applied

1. Ensure the file is at `openspec/config.yaml` (not `.yml`)
2. Validate YAML syntax
3. Config changes take effect immediately—no restart needed

### project.md not migrated

The system intentionally preserves `project.md` because it may contain your custom content. Review it manually, move useful parts to `config.yaml`, then delete it.

### Want to see what would be cleaned up?

Run init and decline the cleanup prompt—you'll see the full detection summary without any changes being made.

---

## Quick Reference

### Files After Migration

```
project/
├── openspec/
│   ├── specs/                    # Unchanged
│   ├── changes/                  # Unchanged
│   │   └── archive/              # Unchanged
│   └── config.yaml               # NEW: Project configuration
├── .claude/
│   └── skills/                   # NEW: OPSX skills
│       ├── openspec-propose/     # default core profile
│       ├── openspec-explore/
│       ├── openspec-apply-change/
│       └── ...                   # expanded profile adds new/continue/ff/etc.
├── CLAUDE.md                     # OpenSpec markers removed, your content preserved
└── AGENTS.md                     # OpenSpec markers removed, your content preserved
```

### What's Gone

- `.claude/commands/openspec/` — replaced by `.claude/skills/`
- `openspec/AGENTS.md` — obsolete
- `openspec/project.md` — migrate to `config.yaml`, then delete
- OpenSpec marker blocks in `CLAUDE.md`, `AGENTS.md`, etc.

### Command Cheatsheet

```text
/opsx:propose      Start quickly (default core profile)
/opsx:apply        Implement tasks
/opsx:archive      Finish and archive

# Expanded workflow (if enabled):
/opsx:new          Scaffold a change
/opsx:continue     Create next artifact
/opsx:ff           Create planning artifacts
```

---

## Getting Help

- **Discord**: [discord.gg/YctCnvvshC](https://discord.gg/YctCnvvshC)
- **GitHub Issues**: [github.com/Fission-AI/OpenSpec/issues](https://github.com/Fission-AI/OpenSpec/issues)
- **Documentation**: [docs/opsx.md](opsx.md) for the full OPSX reference


================================================
FILE: docs/multi-language.md
================================================
# Multi-Language Guide

Configure OpenSpec to generate artifacts in languages other than English.

## Quick Setup

Add a language instruction to your `openspec/config.yaml`:

```yaml
schema: spec-driven

context: |
  Language: Portuguese (pt-BR)
  All artifacts must be written in Brazilian Portuguese.

  # Your other project context below...
  Tech stack: TypeScript, React, Node.js
```

That's it. All generated artifacts will now be in Portuguese.

## Language Examples

### Portuguese (Brazil)

```yaml
context: |
  Language: Portuguese (pt-BR)
  All artifacts must be written in Brazilian Portuguese.
```

### Spanish

```yaml
context: |
  Idioma: Español
  Todos los artefactos deben escribirse en español.
```

### Chinese (Simplified)

```yaml
context: |
  语言:中文(简体)
  所有产出物必须用简体中文撰写。
```

### Japanese

```yaml
context: |
  言語:日本語
  すべての成果物は日本語で作成してください。
```

### French

```yaml
context: |
  Langue : Français
  Tous les artefacts doivent être rédigés en français.
```

### German

```yaml
context: |
  Sprache: Deutsch
  Alle Artefakte müssen auf Deutsch verfasst werden.
```

## Tips

### Handle Technical Terms

Decide how to handle technical terminology:

```yaml
context: |
  Language: Japanese
  Write in Japanese, but:
  - Keep technical terms like "API", "REST", "GraphQL" in English
  - Code examples and file paths remain in English
```

### Combine with Other Context

Language settings work alongside your other project context:

```yaml
schema: spec-driven

context: |
  Language: Portuguese (pt-BR)
  All artifacts must be written in Brazilian Portuguese.

  Tech stack: TypeScript, React 18, Node.js 20
  Database: PostgreSQL with Prisma ORM
```

## Verification

To verify your language config is working:

```bash
# Check the instructions - should show your language context
openspec instructions proposal --change my-change

# Output will include your language context
```

## Related Documentation

- [Customization Guide](./customization.md) - Project configuration options
- [Workflows Guide](./workflows.md) - Full workflow documentation


================================================
FILE: docs/opsx.md
================================================
# OPSX Workflow

> Feedback welcome on [Discord](https://discord.gg/YctCnvvshC).

## What Is It?

OPSX is now the standard workflow for OpenSpec.

It's a **fluid, iterative workflow** for OpenSpec changes. No more rigid phases — just actions you can take anytime.

## Why This Exists

The legacy OpenSpec workflow works, but it's **locked down**:

- **Instructions are hardcoded** — buried in TypeScript, you can't change them
- **All-or-nothing** — one big command creates everything, can't test individual pieces
- **Fixed structure** — same workflow for everyone, no customization
- **Black box** — when AI output is bad, you can't tweak the prompts

**OPSX opens it up.** Now anyone can:

1. **Experiment with instructions** — edit a template, see if the AI does better
2. **Test granularly** — validate each artifact's instructions independently
3. **Customize workflows** — define your own artifacts and dependencies
4. **Iterate quickly** — change a template, test immediately, no rebuild

```
Legacy workflow:                      OPSX:
┌────────────────────────┐           ┌────────────────────────┐
│  Hardcoded in package  │           │  schema.yaml           │◄── You edit this
│  (can't change)        │           │  templates/*.md        │◄── Or this
│        ↓               │           │        ↓               │
│  Wait for new release  │           │  Instant effect        │
│        ↓               │           │        ↓               │
│  Hope it's better      │           │  Test it yourself      │
└────────────────────────┘           └────────────────────────┘
```

**This is for everyone:**
- **Teams** — create workflows that match how you actually work
- **Power users** — tweak prompts to get better AI outputs for your codebase
- **OpenSpec contributors** — experiment with new approaches without releases

We're all still learning what works best. OPSX lets us learn together.

## The User Experience

**The problem with linear workflows:**
You're "in planning phase", then "in implementation phase", then "done". But real work doesn't work that way. You implement something, realize your design was wrong, need to update specs, continue implementing. Linear phases fight against how work actually happens.

**OPSX approach:**
- **Actions, not phases** — create, implement, update, archive — do any of them anytime
- **Dependencies are enablers** — they show what's possible, not what's required next

```
  proposal ──→ specs ──→ design ──→ tasks ──→ implement
```

## Setup

```bash
# Make sure you have openspec installed — skills are automatically generated
openspec init
```

This creates skills in `.claude/skills/` (or equivalent) that AI coding assistants auto-detect.

By default, OpenSpec uses the `core` workflow profile (`propose`, `explore`, `apply`, `archive`). If you want the expanded workflow commands (`new`, `continue`, `ff`, `verify`, `sync`, `bulk-archive`, `onboard`), configure them with `openspec config profile` and apply with `openspec update`.

During setup, you'll be prompted to create a **project config** (`openspec/config.yaml`). This is optional but recommended.

## Project Configuration

Project config lets you set defaults and inject project-specific context into all artifacts.

### Creating Config

Config is created during `openspec init`, or manually:

```yaml
# openspec/config.yaml
schema: spec-driven

context: |
  Tech stack: TypeScript, React, Node.js
  API conventions: RESTful, JSON responses
  Testing: Vitest for unit tests, Playwright for e2e
  Style: ESLint with Prettier, strict TypeScript

rules:
  proposal:
    - Include rollback plan
    - Identify affected teams
  specs:
    - Use Given/When/Then format for scenarios
  design:
    - Include sequence diagrams for complex flows
```

### Config Fields

| Field | Type | Description |
|-------|------|-------------|
| `schema` | string | Default schema for new changes (e.g., `spec-driven`) |
| `context` | string | Project context injected into all artifact instructions |
| `rules` | object | Per-artifact rules, keyed by artifact ID |

### How It Works

**Schema precedence** (highest to lowest):
1. CLI flag (`--schema <name>`)
2. Change metadata (`.openspec.yaml` in change directory)
3. Project config (`openspec/config.yaml`)
4. Default (`spec-driven`)

**Context injection:**
- Context is prepended to every artifact's instructions
- Wrapped in `<context>...</context>` tags
- Helps AI understand your project's conventions

**Rules injection:**
- Rules are only injected for matching artifacts
- Wrapped in `<rules>...</rules>` tags
- Appear after context, before the template

### Artifact IDs by Schema

**spec-driven** (default):
- `proposal` — Change proposal
- `specs` — Specifications
- `design` — Technical design
- `tasks` — Implementation tasks

### Config Validation

- Unknown artifact IDs in `rules` generate warnings
- Schema names are validated against available schemas
- Context has a 50KB size limit
- Invalid YAML is reported with line numbers

### Troubleshooting

**"Unknown artifact ID in rules: X"**
- Check artifact IDs match your schema (see list above)
- Run `openspec schemas --json` to see artifact IDs for each schema

**Config not being applied:**
- Ensure file is at `openspec/config.yaml` (not `.yml`)
- Check YAML syntax with a validator
- Config changes take effect immediately (no restart needed)

**Context too large:**
- Context is limited to 50KB
- Summarize or link to external docs instead

## Commands

| Command | What it does |
|---------|--------------|
| `/opsx:propose` | Create a change and generate planning artifacts in one step (default quick path) |
| `/opsx:explore` | Think through ideas, investigate problems, clarify requirements |
| `/opsx:new` | Start a new change scaffold (expanded workflow) |
| `/opsx:continue` | Create the next artifact (expanded workflow) |
| `/opsx:ff` | Fast-forward planning artifacts (expanded workflow) |
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
| `/opsx:verify` | Validate implementation against artifacts (expanded workflow) |
| `/opsx:sync` | Sync delta specs to main (expanded workflow, optional) |
| `/opsx:archive` | Archive when done |
| `/opsx:bulk-archive` | Archive multiple completed changes (expanded workflow) |
| `/opsx:onboard` | Guided walkthrough of an end-to-end change (expanded workflow) |

## Usage

### Explore an idea
```
/opsx:explore
```
Think through ideas, investigate problems, compare options. No structure required - just a thinking partner. When insights crystallize, transition to `/opsx:propose` (default) or `/opsx:new`/`/opsx:ff` (expanded).

### Start a new change
```
/opsx:propose
```
Creates the change and generates planning artifacts needed before implementation.

If you've enabled expanded workflows, you can instead use:

```text
/opsx:new        # scaffold only
/opsx:continue   # create one artifact at a time
/opsx:ff         # create all planning artifacts at once
```

### Create artifacts
```
/opsx:continue
```
Shows what's ready to create based on dependencies, then creates one artifact. Use repeatedly to build up your change incrementally.

```
/opsx:ff add-dark-mode
```
Creates all planning artifacts at once. Use when you have a clear picture of what you're building.

### Implement (the fluid part)
```
/opsx:apply
```
Works through tasks, checking them off as you go. If you're juggling multiple changes, you can run `/opsx:apply <name>`; otherwise it should infer from the conversation and prompt you to choose if it can't tell.

### Finish up
```
/opsx:archive   # Move to archive when done (prompts to sync specs if needed)
```

## When to Update vs. Start Fresh

You can always edit your proposal or specs before implementation. But when does refining become "this is different work"?

### What a Proposal Captures

A proposal defines three things:
1. **Intent** — What problem are you solving?
2. **Scope** — What's in/out of bounds?
3. **Approach** — How will you solve it?

The question is: which changed, and by how much?

### Update the Existing Change When:

**Same intent, refined execution**
- You discover edge cases you didn't consider
- The approach needs tweaking but the goal is unchanged
- Implementation reveals the design was slightly off

**Scope narrows**
- You realize full scope is too big, want to ship MVP first
- "Add dark mode" → "Add dark mode toggle (system preference in v2)"

**Learning-driven corrections**
- Codebase isn't structured how you thought
- A dependency doesn't work as expected
- "Use CSS variables" → "Use Tailwind's dark: prefix instead"

### Start a New Change When:

**Intent fundamentally changed**
- The problem itself is different now
- "Add dark mode" → "Add comprehensive theme system with custom colors, fonts, spacing"

**Scope exploded**
- Change grew so much it's essentially different work
- Original proposal would be unrecognizable after updates
- "Fix login bug" → "Rewrite auth system"

**Original is completable**
- The original change can be marked "done"
- New work stands alone, not a refinement
- Complete "Add dark mode MVP" → Archive → New change "Enhance dark mode"

### The Heuristics

```
                        ┌─────────────────────────────────────┐
                        │     Is this the same work?          │
                        └──────────────┬──────────────────────┘
                                       │
                    ┌──────────────────┼──────────────────┐
                    │                  │                  │
                    ▼                  ▼                  ▼
             Same intent?      >50% overlap?      Can original
             Same problem?     Same scope?        be "done" without
                    │                  │          these changes?
                    │                  │                  │
          ┌────────┴────────┐  ┌──────┴──────┐   ┌───────┴───────┐
          │                 │  │             │   │               │
         YES               NO YES           NO  NO              YES
          │                 │  │             │   │               │
          ▼                 ▼  ▼             ▼   ▼               ▼
       UPDATE            NEW  UPDATE       NEW  UPDATE          NEW
```

| Test | Update | New Change |
|------|--------|------------|
| **Identity** | "Same thing, refined" | "Different work" |
| **Scope overlap** | >50% overlaps | <50% overlaps |
| **Completion** | Can't be "done" without changes | Can finish original, new work stands alone |
| **Story** | Update chain tells coherent story | Patches would confuse more than clarify |

### The Principle

> **Update preserves context. New change provides clarity.**
>
> Choose update when the history of your thinking is valuable.
> Choose new when starting fresh would be clearer than patching.

Think of it like git branches:
- Keep committing while working on the same feature
- Start a new branch when it's genuinely new work
- Sometimes merge a partial feature and start fresh for phase 2

## What's Different?

| | Legacy (`/openspec:proposal`) | OPSX (`/opsx:*`) |
|---|---|---|
| **Structure** | One big proposal document | Discrete artifacts with dependencies |
| **Workflow** | Linear phases: plan → implement → archive | Fluid actions — do anything anytime |
| **Iteration** | Awkward to go back | Update artifacts as you learn |
| **Customization** | Fixed structure | Schema-driven (define your own artifacts) |

**The key insight:** work isn't linear. OPSX stops pretending it is.

## Architecture Deep Dive

This section explains how OPSX works under the hood and how it compares to the legacy workflow.
Examples in this section use the expanded command set (`new`, `continue`, etc.); default `core` users can map the same flow to `propose → apply → archive`.

### Philosophy: Phases vs Actions

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                         LEGACY WORKFLOW                                      │
│                    (Phase-Locked, All-or-Nothing)                           │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   ┌──────────────┐      ┌──────────────┐      ┌──────────────┐             │
│   │   PLANNING   │ ───► │ IMPLEMENTING │ ───► │   ARCHIVING  │             │
│   │    PHASE     │      │    PHASE     │      │    PHASE     │             │
│   └──────────────┘      └──────────────┘      └──────────────┘             │
│         │                     │                     │                       │
│         ▼                     ▼                     ▼                       │
│   /openspec:proposal   /openspec:apply      /openspec:archive              │
│                                                                             │
│   • Creates ALL artifacts at once                                          │
│   • Can't go back to update specs during implementation                    │
│   • Phase gates enforce linear progression                                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────────┐
│                            OPSX WORKFLOW                                     │
│                      (Fluid Actions, Iterative)                             │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│              ┌────────────────────────────────────────────┐                 │
│              │           ACTIONS (not phases)             │                 │
│              │                                            │                 │
│              │   new ◄──► continue ◄──► apply ◄──► archive │                 │
│              │    │          │           │           │    │                 │
│              │    └──────────┴───────────┴───────────┘    │                 │
│              │              any order                     │                 │
│              └────────────────────────────────────────────┘                 │
│                                                                             │
│   • Create artifacts one at a time OR fast-forward                         │
│   • Update specs/design/tasks during implementation                        │
│   • Dependencies enable progress, phases don't exist                       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

### Component Architecture

**Legacy workflow** uses hardcoded templates in TypeScript:

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                      LEGACY WORKFLOW COMPONENTS                              │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   Hardcoded Templates (TypeScript strings)                                  │
│                    │                                                        │
│                    ▼                                                        │
│   Tool-specific configurators/adapters                                      │
│                    │                                                        │
│                    ▼                                                        │
│   Generated Command Files (.claude/commands/openspec/*.md)                  │
│                                                                             │
│   • Fixed structure, no artifact awareness                                  │
│   • Change requires code modification + rebuild                             │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

**OPSX** uses external schemas and a dependency graph engine:

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                         OPSX COMPONENTS                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   Schema Definitions (YAML)                                                 │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │  name: spec-driven                                                  │   │
│   │  artifacts:                                                         │   │
│   │    - id: proposal                                                   │   │
│   │      generates: proposal.md                                         │   │
│   │      requires: []              ◄── Dependencies                     │   │
│   │    - id: specs                                                      │   │
│   │      generates: specs/**/*.md  ◄── Glob patterns                    │   │
│   │      requires: [proposal]      ◄── Enables after proposal           │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                    │                                                        │
│                    ▼                                                        │
│   Artifact Graph Engine                                                     │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │  • Topological sort (dependency ordering)                           │   │
│   │  • State detection (filesystem existence)                           │   │
│   │  • Rich instruction generation (templates + context)                │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                    │                                                        │
│                    ▼                                                        │
│   Skill Files (.claude/skills/openspec-*/SKILL.md)                          │
│                                                                             │
│   • Cross-editor compatible (Claude Code, Cursor, Windsurf)                 │
│   • Skills query CLI for structured data                                    │
│   • Fully customizable via schema files                                     │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

### Dependency Graph Model

Artifacts form a directed acyclic graph (DAG). Dependencies are **enablers**, not gates:

```
                              proposal
                             (root node)
                                  │
                    ┌─────────────┴─────────────┐
                    │                           │
                    ▼                           ▼
                 specs                       design
              (requires:                  (requires:
               proposal)                   proposal)
                    │                           │
                    └─────────────┬─────────────┘
                                  │
                                  ▼
                               tasks
                           (requires:
                           specs, design)
                                  │
                                  ▼
                          ┌──────────────┐
                          │ APPLY PHASE  │
                          │ (requires:   │
                          │  tasks)      │
                          └──────────────┘
```

**State transitions:**

```
   BLOCKED ────────────────► READY ────────────────► DONE
      │                        │                       │
   Missing                  All deps               File exists
   dependencies             are DONE               on filesystem
```

### Information Flow

**Legacy workflow** — agent receives static instructions:

```
  User: "/openspec:proposal"
           │
           ▼
  ┌─────────────────────────────────────────┐
  │  Static instructions:                   │
  │  • Create proposal.md                   │
  │  • Create tasks.md                      │
  │  • Create design.md                     │
  │  • Create specs/<capability>/spec.md    │
  │                                         │
  │  No awareness of what exists or         │
  │  dependencies between artifacts         │
  └─────────────────────────────────────────┘
           │
           ▼
  Agent creates ALL artifacts in one go
```

**OPSX** — agent queries for rich context:

```
  User: "/opsx:continue"
           │
           ▼
  ┌──────────────────────────────────────────────────────────────────────────┐
  │  Step 1: Query current state                                             │
  │  ┌────────────────────────────────────────────────────────────────────┐  │
  │  │  $ openspec status --change "add-auth" --json                      │  │
  │  │                                                                    │  │
  │  │  {                                                                 │  │
  │  │    "artifacts": [                                                  │  │
  │  │      {"id": "proposal", "status": "done"},                         │  │
  │  │      {"id": "specs", "status": "ready"},      ◄── First ready      │  │
  │  │      {"id": "design", "status": "ready"},                          │  │
  │  │      {"id": "tasks", "status": "blocked", "missingDeps": ["specs"]}│  │
  │  │    ]                                                               │  │
  │  │  }                                                                 │  │
  │  └────────────────────────────────────────────────────────────────────┘  │
  │                                                          
Download .txt
gitextract_ovuhyth0/

├── .actrc
├── .changeset/
│   ├── README.md
│   ├── config.json
│   ├── fix-opencode-commands-directory.md
│   └── graceful-status-no-changes.md
├── .coderabbit.yaml
├── .devcontainer/
│   ├── README.md
│   └── devcontainer.json
├── .github/
│   ├── CODEOWNERS
│   └── workflows/
│       ├── README.md
│       ├── ci.yml
│       └── release-prepare.yml
├── .gitignore
├── AGENTS.md
├── CHANGELOG.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── README_OLD.md
├── bin/
│   └── openspec.js
├── build.js
├── docs/
│   ├── cli.md
│   ├── commands.md
│   ├── concepts.md
│   ├── customization.md
│   ├── getting-started.md
│   ├── installation.md
│   ├── migration-guide.md
│   ├── multi-language.md
│   ├── opsx.md
│   ├── supported-tools.md
│   └── workflows.md
├── eslint.config.js
├── flake.nix
├── openspec/
│   ├── changes/
│   │   ├── IMPLEMENTATION_ORDER.md
│   │   ├── add-artifact-regeneration-support/
│   │   │   └── proposal.md
│   │   ├── add-change-stacking-awareness/
│   │   │   ├── .openspec.yaml
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   ├── change-creation/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── change-stacking-workflow/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-change/
│   │   │   │   │   └── spec.md
│   │   │   │   └── openspec-conventions/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── add-global-install-scope/
│   │   │   ├── .openspec.yaml
│   │   │   ├── design.md
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   ├── ai-tool-paths/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-config/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-init/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-update/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── command-generation/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── global-config/
│   │   │   │   │   └── spec.md
│   │   │   │   └── installation-scope/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── add-qa-smoke-harness/
│   │   │   ├── .openspec.yaml
│   │   │   ├── proposal.md
│   │   │   └── specs/
│   │   │       └── developer-qa-workflow/
│   │   │           └── spec.md
│   │   ├── add-tool-command-surface-capabilities/
│   │   │   ├── .openspec.yaml
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   ├── cli-init/
│   │   │   │   │   └── spec.md
│   │   │   │   └── cli-update/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── archive/
│   │   │   ├── 2025-01-11-add-update-command/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-01-13-add-list-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-list/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-05-initialize-typescript-project/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-06-add-init-command/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-06-adopt-future-state-storage/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-11-add-complexity-guidelines/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── openspec-docs/
│   │   │   │   │       └── README.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-13-add-archive-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-archive/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-13-add-diff-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-diff/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-change-commands/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-change/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-list/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-interactive-show-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-change/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-show/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-spec/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-skip-specs-archive-option/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-archive/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-spec-commands/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-spec/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-add-zod-validation/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-archive/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-diff/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-adopt-delta-based-changes/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-archive/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-diff/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-adopt-verb-noun-cli-structure/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-list/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-bulk-validation-interactive-selection/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-change/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-spec/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-validate/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-fix-update-tool-selection/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-improve-validate-error-messages/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-validate/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-08-19-structured-spec-format/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-12-add-view-dashboard-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-view/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-add-agents-md-config/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-add-multi-agent-init/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-add-slash-command-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-improve-cli-e2e-plan/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-improve-deterministic-tests/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-improve-init-onboarding/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-remove-diff-command/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-sort-active-changes-by-progress/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-view/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-update-agent-file-name/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-update/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── openspec-conventions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-update-agent-instructions/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-09-29-update-markdown-parser-crlf/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-validate/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-codex-slash-command-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-github-copilot-prompts/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-kilocode-workflows/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-non-interactive-init-options/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-add-windsurf-workflows/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-enhance-validation-error-messages/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-validate/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-improve-agent-instruction-usability/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── docs-agent-instructions/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-slim-root-agents-file/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-update-cli-init-enter-selection/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-update-cli-init-root-agents/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-14-update-release-automation/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-22-add-archive-command-arguments/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-22-add-cline-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-22-add-crush-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-init/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-10-22-add-factory-slash-commands/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-11-06-add-shell-completions/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-completion/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-20-add-global-config-dir/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── global-config/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-21-add-config-command/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-config/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-23-extend-shell-completions/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-completion/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-24-add-artifact-graph-core/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── artifact-graph/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-25-add-change-manager/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── change-creation/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-28-add-artifact-workflow-cli/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-artifact-workflow/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-28-add-instruction-loader/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── instruction-loader/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-28-restructure-schema-directories/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── artifact-graph/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-29-unify-change-state-model/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-artifact-workflow/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-view/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-30-add-antigravity-support/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2025-12-30-fix-cline-workflows-implementation/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-add-agent-schema-selection/
│   │   │   │   ├── proposal.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-add-per-change-schema-metadata/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-artifact-workflow/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-add-specs-apply-command/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── specs-sync-skill/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-make-apply-instructions-schema-aware/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-artifact-workflow/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-06-opsx-archive-command/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── opsx-archive-skill/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-07-add-nix-flake-support/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── nix-flake-support/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-09-add-flake-update-script/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── flake-update-script/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-09-add-posthog-analytics/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── global-config/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── telemetry/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-09-fix-codebuddy-frontmatter-fields/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── cli-update/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-15-add-nix-ci-validation/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── ci-nix-validation/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-01-30-opencode-command-references/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── README.md
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── no-changes.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-add-feedback-command/
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── cli-feedback/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-add-opsx-onboard-skill/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── opsx-onboard-skill/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-add-verify-skill/
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── opsx-verify-skill/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-merge-init-experimental/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── cli-init/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── legacy-cleanup/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-multi-provider-skill-generation/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── ai-tool-paths/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── cli-artifact-workflow/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── command-generation/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-project-config/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   ├── config-loading/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── context-injection/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   ├── rules-injection/
│   │   │   │   │   │   └── spec.md
│   │   │   │   │   └── schema-resolution/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   ├── 2026-02-17-project-local-schemas/
│   │   │   │   ├── .openspec.yaml
│   │   │   │   ├── design.md
│   │   │   │   ├── proposal.md
│   │   │   │   ├── specs/
│   │   │   │   │   └── schema-resolution/
│   │   │   │   │       └── spec.md
│   │   │   │   └── tasks.md
│   │   │   └── 2026-02-17-schema-management-cli/
│   │   │       ├── .openspec.yaml
│   │   │       ├── design.md
│   │   │       ├── proposal.md
│   │   │       ├── specs/
│   │   │       │   ├── schema-fork-command/
│   │   │       │   │   └── spec.md
│   │   │       │   ├── schema-init-command/
│   │   │       │   │   └── spec.md
│   │   │       │   ├── schema-validate-command/
│   │   │       │   │   └── spec.md
│   │   │       │   └── schema-which-command/
│   │   │       │       └── spec.md
│   │   │       └── tasks.md
│   │   ├── fix-opencode-commands-directory/
│   │   │   ├── .openspec.yaml
│   │   │   ├── design.md
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   └── command-generation/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── graceful-status-no-changes/
│   │   │   ├── .openspec.yaml
│   │   │   ├── design.md
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   └── graceful-status-empty/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   ├── schema-alias-support/
│   │   │   ├── .openspec.yaml
│   │   │   └── proposal.md
│   │   ├── simplify-skill-installation/
│   │   │   ├── .openspec.yaml
│   │   │   ├── design.md
│   │   │   ├── proposal.md
│   │   │   ├── specs/
│   │   │   │   ├── cli-init/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── cli-update/
│   │   │   │   │   └── spec.md
│   │   │   │   ├── profiles/
│   │   │   │   │   └── spec.md
│   │   │   │   └── propose-workflow/
│   │   │   │       └── spec.md
│   │   │   └── tasks.md
│   │   └── unify-template-generation-pipeline/
│   │       ├── .openspec.yaml
│   │       ├── design.md
│   │       ├── proposal.md
│   │       ├── specs/
│   │       │   └── template-artifact-pipeline/
│   │       │       └── spec.md
│   │       └── tasks.md
│   ├── config.yaml
│   ├── explorations/
│   │   ├── explore-workflow-ux.md
│   │   └── workspace-architecture.md
│   └── specs/
│       ├── ai-tool-paths/
│       │   └── spec.md
│       ├── artifact-graph/
│       │   └── spec.md
│       ├── change-creation/
│       │   └── spec.md
│       ├── ci-nix-validation/
│       │   └── spec.md
│       ├── cli-archive/
│       │   └── spec.md
│       ├── cli-artifact-workflow/
│       │   └── spec.md
│       ├── cli-change/
│       │   └── spec.md
│       ├── cli-completion/
│       │   └── spec.md
│       ├── cli-config/
│       │   └── spec.md
│       ├── cli-feedback/
│       │   └── spec.md
│       ├── cli-init/
│       │   └── spec.md
│       ├── cli-list/
│       │   └── spec.md
│       ├── cli-show/
│       │   └── spec.md
│       ├── cli-spec/
│       │   └── spec.md
│       ├── cli-update/
│       │   └── spec.md
│       ├── cli-validate/
│       │   └── spec.md
│       ├── cli-view/
│       │   └── spec.md
│       ├── command-generation/
│       │   └── spec.md
│       ├── config-loading/
│       │   └── spec.md
│       ├── context-injection/
│       │   └── spec.md
│       ├── docs-agent-instructions/
│       │   └── spec.md
│       ├── global-config/
│       │   └── spec.md
│       ├── instruction-loader/
│       │   └── spec.md
│       ├── legacy-cleanup/
│       │   └── spec.md
│       ├── openspec-conventions/
│       │   └── spec.md
│       ├── opsx-archive-skill/
│       │   └── spec.md
│       ├── opsx-onboard-skill/
│       │   └── spec.md
│       ├── opsx-verify-skill/
│       │   └── spec.md
│       ├── rules-injection/
│       │   └── spec.md
│       ├── schema-fork-command/
│       │   └── spec.md
│       ├── schema-init-command/
│       │   └── spec.md
│       ├── schema-resolution/
│       │   └── spec.md
│       ├── schema-validate-command/
│       │   └── spec.md
│       ├── schema-which-command/
│       │   └── spec.md
│       ├── specs-sync-skill/
│       │   └── spec.md
│       └── telemetry/
│           └── spec.md
├── openspec-parallel-merge-plan.md
├── package.json
├── schemas/
│   └── spec-driven/
│       ├── schema.yaml
│       └── templates/
│           ├── design.md
│           ├── proposal.md
│           ├── spec.md
│           └── tasks.md
├── scripts/
│   ├── README.md
│   ├── pack-version-check.mjs
│   ├── postinstall.js
│   ├── test-postinstall.sh
│   └── update-flake.sh
├── src/
│   ├── cli/
│   │   └── index.ts
│   ├── commands/
│   │   ├── change.ts
│   │   ├── completion.ts
│   │   ├── config.ts
│   │   ├── feedback.ts
│   │   ├── schema.ts
│   │   ├── show.ts
│   │   ├── spec.ts
│   │   ├── validate.ts
│   │   └── workflow/
│   │       ├── index.ts
│   │       ├── instructions.ts
│   │       ├── new-change.ts
│   │       ├── schemas.ts
│   │       ├── shared.ts
│   │       ├── status.ts
│   │       └── templates.ts
│   ├── core/
│   │   ├── archive.ts
│   │   ├── artifact-graph/
│   │   │   ├── graph.ts
│   │   │   ├── index.ts
│   │   │   ├── instruction-loader.ts
│   │   │   ├── resolver.ts
│   │   │   ├── schema.ts
│   │   │   ├── state.ts
│   │   │   └── types.ts
│   │   ├── available-tools.ts
│   │   ├── command-generation/
│   │   │   ├── adapters/
│   │   │   │   ├── amazon-q.ts
│   │   │   │   ├── antigravity.ts
│   │   │   │   ├── auggie.ts
│   │   │   │   ├── claude.ts
│   │   │   │   ├── cline.ts
│   │   │   │   ├── codebuddy.ts
│   │   │   │   ├── codex.ts
│   │   │   │   ├── continue.ts
│   │   │   │   ├── costrict.ts
│   │   │   │   ├── crush.ts
│   │   │   │   ├── cursor.ts
│   │   │   │   ├── factory.ts
│   │   │   │   ├── gemini.ts
│   │   │   │   ├── github-copilot.ts
│   │   │   │   ├── iflow.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── kilocode.ts
│   │   │   │   ├── kiro.ts
│   │   │   │   ├── opencode.ts
│   │   │   │   ├── pi.ts
│   │   │   │   ├── qoder.ts
│   │   │   │   ├── qwen.ts
│   │   │   │   ├── roocode.ts
│   │   │   │   └── windsurf.ts
│   │   │   ├── generator.ts
│   │   │   ├── index.ts
│   │   │   ├── registry.ts
│   │   │   └── types.ts
│   │   ├── completions/
│   │   │   ├── command-registry.ts
│   │   │   ├── completion-provider.ts
│   │   │   ├── factory.ts
│   │   │   ├── generators/
│   │   │   │   ├── bash-generator.ts
│   │   │   │   ├── fish-generator.ts
│   │   │   │   ├── powershell-generator.ts
│   │   │   │   └── zsh-generator.ts
│   │   │   ├── installers/
│   │   │   │   ├── bash-installer.ts
│   │   │   │   ├── fish-installer.ts
│   │   │   │   ├── powershell-installer.ts
│   │   │   │   └── zsh-installer.ts
│   │   │   ├── templates/
│   │   │   │   ├── bash-templates.ts
│   │   │   │   ├── fish-templates.ts
│   │   │   │   ├── powershell-templates.ts
│   │   │   │   └── zsh-templates.ts
│   │   │   └── types.ts
│   │   ├── config-prompts.ts
│   │   ├── config-schema.ts
│   │   ├── config.ts
│   │   ├── converters/
│   │   │   └── json-converter.ts
│   │   ├── global-config.ts
│   │   ├── index.ts
│   │   ├── init.ts
│   │   ├── legacy-cleanup.ts
│   │   ├── list.ts
│   │   ├── migration.ts
│   │   ├── parsers/
│   │   │   ├── change-parser.ts
│   │   │   ├── markdown-parser.ts
│   │   │   └── requirement-blocks.ts
│   │   ├── profile-sync-drift.ts
│   │   ├── profiles.ts
│   │   ├── project-config.ts
│   │   ├── schemas/
│   │   │   ├── base.schema.ts
│   │   │   ├── change.schema.ts
│   │   │   ├── index.ts
│   │   │   └── spec.schema.ts
│   │   ├── shared/
│   │   │   ├── index.ts
│   │   │   ├── skill-generation.ts
│   │   │   └── tool-detection.ts
│   │   ├── specs-apply.ts
│   │   ├── styles/
│   │   │   └── palette.ts
│   │   ├── templates/
│   │   │   ├── index.ts
│   │   │   ├── skill-templates.ts
│   │   │   ├── types.ts
│   │   │   └── workflows/
│   │   │       ├── apply-change.ts
│   │   │       ├── archive-change.ts
│   │   │       ├── bulk-archive-change.ts
│   │   │       ├── continue-change.ts
│   │   │       ├── explore.ts
│   │   │       ├── feedback.ts
│   │   │       ├── ff-change.ts
│   │   │       ├── new-change.ts
│   │   │       ├── onboard.ts
│   │   │       ├── propose.ts
│   │   │       ├── sync-specs.ts
│   │   │       └── verify-change.ts
│   │   ├── update.ts
│   │   ├── validation/
│   │   │   ├── constants.ts
│   │   │   ├── types.ts
│   │   │   └── validator.ts
│   │   └── view.ts
│   ├── index.ts
│   ├── prompts/
│   │   └── searchable-multi-select.ts
│   ├── telemetry/
│   │   ├── config.ts
│   │   └── index.ts
│   ├── ui/
│   │   ├── ascii-patterns.ts
│   │   └── welcome-screen.ts
│   └── utils/
│       ├── change-metadata.ts
│       ├── change-utils.ts
│       ├── command-references.ts
│       ├── file-system.ts
│       ├── index.ts
│       ├── interactive.ts
│       ├── item-discovery.ts
│       ├── match.ts
│       ├── shell-detection.ts
│       └── task-progress.ts
├── test/
│   ├── cli-e2e/
│   │   └── basic.test.ts
│   ├── commands/
│   │   ├── artifact-workflow.test.ts
│   │   ├── change.interactive-show.test.ts
│   │   ├── change.interactive-validate.test.ts
│   │   ├── completion.test.ts
│   │   ├── config-profile.test.ts
│   │   ├── config.test.ts
│   │   ├── feedback.test.ts
│   │   ├── schema.test.ts
│   │   ├── show.test.ts
│   │   ├── spec.interactive-show.test.ts
│   │   ├── spec.interactive-validate.test.ts
│   │   ├── spec.test.ts
│   │   ├── validate.enriched-output.test.ts
│   │   └── validate.test.ts
│   ├── core/
│   │   ├── archive.test.ts
│   │   ├── artifact-graph/
│   │   │   ├── graph.test.ts
│   │   │   ├── instruction-loader.test.ts
│   │   │   ├── resolver.test.ts
│   │   │   ├── schema.test.ts
│   │   │   ├── state.test.ts
│   │   │   └── workflow.integration.test.ts
│   │   ├── available-tools.test.ts
│   │   ├── command-generation/
│   │   │   ├── adapters.test.ts
│   │   │   ├── generator.test.ts
│   │   │   ├── registry.test.ts
│   │   │   └── types.test.ts
│   │   ├── commands/
│   │   │   ├── change-command.list.test.ts
│   │   │   └── change-command.show-validate.test.ts
│   │   ├── completions/
│   │   │   ├── completion-provider.test.ts
│   │   │   ├── generators/
│   │   │   │   ├── bash-generator.test.ts
│   │   │   │   ├── fish-generator.test.ts
│   │   │   │   ├── powershell-generator.test.ts
│   │   │   │   └── zsh-generator.test.ts
│   │   │   └── installers/
│   │   │       ├── bash-installer.test.ts
│   │   │       ├── fish-installer.test.ts
│   │   │       ├── powershell-installer.test.ts
│   │   │       └── zsh-installer.test.ts
│   │   ├── config-schema.test.ts
│   │   ├── converters/
│   │   │   └── json-converter.test.ts
│   │   ├── global-config.test.ts
│   │   ├── init.test.ts
│   │   ├── legacy-cleanup.test.ts
│   │   ├── list.test.ts
│   │   ├── migration.test.ts
│   │   ├── parsers/
│   │   │   ├── change-parser.test.ts
│   │   │   └── markdown-parser.test.ts
│   │   ├── profile-sync-drift.test.ts
│   │   ├── profiles.test.ts
│   │   ├── project-config.test.ts
│   │   ├── shared/
│   │   │   ├── skill-generation.test.ts
│   │   │   └── tool-detection.test.ts
│   │   ├── templates/
│   │   │   └── skill-templates-parity.test.ts
│   │   ├── update.test.ts
│   │   ├── validation.enriched-messages.test.ts
│   │   ├── validation.test.ts
│   │   └── view.test.ts
│   ├── fixtures/
│   │   └── tmp-init/
│   │       └── openspec/
│   │           ├── changes/
│   │           │   └── c1/
│   │           │       ├── proposal.md
│   │           │       └── specs/
│   │           │           └── alpha/
│   │           │               └── spec.md
│   │           └── specs/
│   │               └── alpha/
│   │                   └── spec.md
│   ├── helpers/
│   │   └── run-cli.ts
│   ├── prompts/
│   │   └── searchable-multi-select.test.ts
│   ├── specs/
│   │   └── source-specs-normalization.test.ts
│   ├── telemetry/
│   │   ├── config.test.ts
│   │   └── index.test.ts
│   └── utils/
│       ├── change-metadata.test.ts
│       ├── change-utils.test.ts
│       ├── command-references.test.ts
│       ├── file-system.test.ts
│       ├── interactive.test.ts
│       ├── marker-updates.test.ts
│       └── shell-detection.test.ts
├── tsconfig.json
├── vitest.config.ts
└── vitest.setup.ts
Download .txt
SYMBOL INDEX (737 symbols across 137 files)

FILE: scripts/pack-version-check.mjs
  function log (line 18) | function log(msg) {
  function run (line 23) | function run(cmd, args, opts = {}) {
  function npmPack (line 27) | function npmPack() {
  function main (line 48) | function main() {

FILE: scripts/postinstall.js
  function shouldSkipInstallation (line 24) | function shouldSkipInstallation() {
  function distExists (line 41) | async function distExists() {
  function detectShell (line 54) | async function detectShell() {
  function installCompletions (line 68) | async function installCompletions(shell) {
  function main (line 113) | async function main() {

FILE: src/cli/index.ts
  function getCommandPath (line 43) | function getCommandPath(command: Command): string {

FILE: src/commands/change.ts
  constant ARCHIVE_DIR (line 11) | const ARCHIVE_DIR = 'archive';
  constant TASK_PATTERN (line 12) | const TASK_PATTERN = /^[-*]\s+\[[\sx]\]/i;
  constant COMPLETED_TASK_PATTERN (line 13) | const COMPLETED_TASK_PATTERN = /^[-*]\s+\[x\]/i;
  class ChangeCommand (line 15) | class ChangeCommand {
    method constructor (line 18) | constructor() {
    method show (line 28) | async show(changeName?: string, options?: { json?: boolean; requiremen...
    method list (line 97) | async list(options?: { json?: boolean; long?: boolean }): Promise<void> {
    method validate (line 185) | async validate(changeName?: string, options?: { strict?: boolean; json...
    method getActiveChanges (line 242) | private async getActiveChanges(changesPath: string): Promise<string[]> {
    method extractTitle (line 262) | private extractTitle(content: string, changeName: string): string {
    method countTasks (line 267) | private countTasks(content: string): { total: number; completed: numbe...
    method printNextSteps (line 284) | private printNextSteps(): void {

FILE: src/commands/completion.ts
  type GenerateOptions (line 8) | interface GenerateOptions {
  type InstallOptions (line 12) | interface InstallOptions {
  type UninstallOptions (line 17) | interface UninstallOptions {
  type CompleteOptions (line 22) | interface CompleteOptions {
  class CompletionCommand (line 29) | class CompletionCommand {
    method constructor (line 32) | constructor() {
    method resolveShellOrExit (line 42) | private resolveShellOrExit(shell: string | undefined, operationName: s...
    method generate (line 81) | async generate(options: GenerateOptions = {}): Promise<void> {
    method install (line 93) | async install(options: InstallOptions = {}): Promise<void> {
    method uninstall (line 105) | async uninstall(options: UninstallOptions = {}): Promise<void> {
    method generateForShell (line 115) | private async generateForShell(shell: SupportedShell): Promise<void> {
    method installForShell (line 124) | private async installForShell(shell: SupportedShell, verbose: boolean)...
    method uninstallForShell (line 210) | private async uninstallForShell(shell: SupportedShell, skipConfirmatio...
    method complete (line 263) | async complete(options: CompleteOptions): Promise<void> {
    method normalizeShell (line 303) | private normalizeShell(shell?: string): string | undefined {

FILE: src/commands/config.ts
  type ProfileAction (line 26) | type ProfileAction = 'both' | 'delivery' | 'workflows' | 'keep';
  type ProfileState (line 28) | interface ProfileState {
  type ProfileStateDiff (line 34) | interface ProfileStateDiff {
  type WorkflowPromptMeta (line 39) | interface WorkflowPromptMeta {
  constant WORKFLOW_PROMPT_META (line 44) | const WORKFLOW_PROMPT_META: Record<string, WorkflowPromptMeta> = {
  function isPromptCancellationError (line 91) | function isPromptCancellationError(error: unknown): boolean {
  function resolveCurrentProfileState (line 101) | function resolveCurrentProfileState(config: GlobalConfig): ProfileState {
  function deriveProfileFromWorkflowSelection (line 113) | function deriveProfileFromWorkflowSelection(selectedWorkflows: string[])...
  function formatWorkflowSummary (line 123) | function formatWorkflowSummary(workflows: readonly string[], profile: Pr...
  function stableWorkflowOrder (line 127) | function stableWorkflowOrder(workflows: readonly string[]): string[] {
  function diffProfileState (line 153) | function diffProfileState(before: ProfileState, after: ProfileState): Pr...
  function maybeWarnConfigDrift (line 189) | function maybeWarnConfigDrift(
  function registerConfigCommand (line 209) | function registerConfigCommand(program: Command): void {

FILE: src/commands/feedback.ts
  function isGhInstalled (line 11) | function isGhInstalled(): boolean {
  function isGhAuthenticated (line 24) | function isGhAuthenticated(): boolean {
  function getVersion (line 36) | function getVersion(): string {
  function getPlatform (line 48) | function getPlatform(): string {
  function getTimestamp (line 55) | function getTimestamp(): string {
  function generateMetadata (line 62) | function generateMetadata(): string {
  function formatTitle (line 77) | function formatTitle(message: string): string {
  function formatBody (line 84) | function formatBody(bodyText?: string): string {
  function generateManualSubmissionUrl (line 100) | function generateManualSubmissionUrl(title: string, body: string): string {
  function displayFormattedFeedback (line 112) | function displayFormattedFeedback(title: string, body: string): void {
  function submitViaGhCli (line 125) | function submitViaGhCli(title: string, body: string): void {
  function handleFallback (line 163) | function handleFallback(title: string, body: string, reason: 'missing' |...
  class FeedbackCommand (line 187) | class FeedbackCommand {
    method execute (line 188) | async execute(message: string, options?: { body?: string }): Promise<v...

FILE: src/commands/schema.ts
  type SchemaSource (line 19) | type SchemaSource = 'project' | 'user' | 'package';
  type SchemaLocation (line 24) | interface SchemaLocation {
  type SchemaResolution (line 33) | interface SchemaResolution {
  type ValidationIssue (line 43) | interface ValidationIssue {
  function checkAllLocations (line 52) | function checkAllLocations(
  function getSchemaResolution (line 91) | function getSchemaResolution(
  function getAllSchemasWithResolution (line 119) | function getAllSchemasWithResolution(
  function validateSchema (line 138) | function validateSchema(
  function isValidSchemaName (line 229) | function isValidSchemaName(name: string): boolean {
  function copyDirRecursive (line 236) | function copyDirRecursive(src: string, dest: string): void {
  constant DEFAULT_ARTIFACTS (line 255) | const DEFAULT_ARTIFACTS: Array<{
  function registerSchemaCommand (line 290) | function registerSchemaCommand(program: Command): void {
  function createDefaultTemplate (line 928) | function createDefaultTemplate(artifactId: string): string {

FILE: src/commands/show.ts
  type ItemType (line 8) | type ItemType = 'change' | 'spec';
  constant CHANGE_FLAG_KEYS (line 10) | const CHANGE_FLAG_KEYS = new Set(['deltasOnly', 'requirementsOnly']);
  constant SPEC_FLAG_KEYS (line 11) | const SPEC_FLAG_KEYS = new Set(['requirements', 'scenarios', 'requiremen...
  class ShowCommand (line 13) | class ShowCommand {
    method execute (line 14) | async execute(itemName?: string, options: { json?: boolean; type?: str...
    method normalizeType (line 39) | private normalizeType(value?: string): ItemType | undefined {
    method runInteractiveByType (line 46) | private async runInteractiveByType(type: ItemType, options: { json?: b...
    method showDirect (line 72) | private async showDirect(itemName: string, params: { typeOverride?: It...
    method printNonInteractiveHint (line 117) | private printNonInteractiveHint(): void {
    method warnIrrelevantFlags (line 125) | private warnIrrelevantFlags(type: ItemType, options: { [k: string]: an...

FILE: src/commands/spec.ts
  constant SPECS_DIR (line 10) | const SPECS_DIR = 'openspec/specs';
  type ShowOptions (line 12) | interface ShowOptions {
  function parseSpecFromFile (line 21) | function parseSpecFromFile(specPath: string, specId: string): Spec {
  function validateRequirementIndex (line 27) | function validateRequirementIndex(spec: Spec, requirementOpt?: string): ...
  function filterSpec (line 36) | function filterSpec(spec: Spec, options: ShowOptions): Spec {
  function printSpecTextRaw (line 62) | function printSpecTextRaw(specPath: string): void {
  class SpecCommand (line 67) | class SpecCommand {
    method show (line 70) | async show(specId?: string, options: ShowOptions = {}): Promise<void> {
  function registerSpecCommand (line 111) | function registerSpecCommand(rootProgram: typeof program) {

FILE: src/commands/validate.ts
  type ItemType (line 8) | type ItemType = 'change' | 'spec';
  type ExecuteOptions (line 10) | interface ExecuteOptions {
  type BulkItemResult (line 22) | interface BulkItemResult {
  class ValidateCommand (line 30) | class ValidateCommand {
    method execute (line 31) | async execute(itemName: string | undefined, options: ExecuteOptions = ...
    method normalizeType (line 59) | private normalizeType(value?: string): ItemType | undefined {
    method runInteractiveSelector (line 66) | private async runInteractiveSelector(opts: { strict: boolean; json: bo...
    method printNonInteractiveHint (line 96) | private printNonInteractiveHint(): void {
    method validateDirectItem (line 105) | private async validateDirectItem(itemName: string, opts: { typeOverrid...
    method validateByType (line 130) | private async validateByType(type: ItemType, id: string, opts: { stric...
    method printReport (line 150) | private printReport(type: ItemType, id: string, report: { valid: boole...
    method printNextSteps (line 169) | private printNextSteps(type: ItemType): void {
    method runBulkValidation (line 184) | private async runBulkValidation(scope: { changes: boolean; specs: bool...
  function summarizeType (line 298) | function summarizeType(results: BulkItemResult[], type: ItemType) {
  function normalizeConcurrency (line 306) | function normalizeConcurrency(value?: string): number | undefined {
  function getPlannedId (line 313) | function getPlannedId(index: number, changeIds: string[], specIds: strin...
  function getPlannedType (line 320) | function getPlannedType(index: number, changeIds: string[], specIds: str...

FILE: src/commands/workflow/instructions.ts
  type InstructionsOptions (line 28) | interface InstructionsOptions {
  type ApplyInstructionsOptions (line 34) | interface ApplyInstructionsOptions {
  function instructionsCommand (line 44) | async function instructionsCommand(
  function printInstructionsText (line 97) | function printInstructionsText(instructions: ArtifactInstructions, isBlo...
  function parseTasksFile (line 217) | function parseTasksFile(content: string): TaskItem[] {
  function artifactOutputExists (line 244) | function artifactOutputExists(changeDir: string, generates: string): boo...
  function generateApplyInstructions (line 307) | async function generateApplyInstructions(
  function applyInstructionsCommand (line 402) | async function applyInstructionsCommand(options: ApplyInstructionsOption...
  function printApplyInstructionsText (line 431) | function printApplyInstructionsText(instructions: ApplyInstructions): vo...

FILE: src/commands/workflow/new-change.ts
  type NewChangeOptions (line 16) | interface NewChangeOptions {
  function newChangeCommand (line 25) | async function newChangeCommand(name: string | undefined, options: NewCh...

FILE: src/commands/workflow/schemas.ts
  type SchemasOptions (line 14) | interface SchemasOptions {
  function schemasCommand (line 22) | async function schemasCommand(options: SchemasOptions): Promise<void> {

FILE: src/commands/workflow/shared.ts
  type TaskItem (line 18) | interface TaskItem {
  type ApplyInstructions (line 24) | interface ApplyInstructions {
  constant DEFAULT_SCHEMA (line 44) | const DEFAULT_SCHEMA = 'spec-driven';
  function isColorDisabled (line 53) | function isColorDisabled(): boolean {
  function getStatusColor (line 60) | function getStatusColor(status: 'done' | 'ready' | 'blocked'): (text: st...
  function getStatusIndicator (line 77) | function getStatusIndicator(status: 'done' | 'ready' | 'blocked'): string {
  function getAvailableChanges (line 93) | async function getAvailableChanges(projectRoot: string): Promise<string[...
  function validateChangeExists (line 110) | async function validateChangeExists(
  function validateSchemaExists (line 155) | function validateSchemaExists(schemaName: string, projectRoot?: string):...

FILE: src/commands/workflow/status.ts
  type StatusOptions (line 26) | interface StatusOptions {
  function statusCommand (line 36) | async function statusCommand(options: StatusOptions): Promise<void> {
  function printStatusText (line 87) | function printStatusText(status: ChangeStatus): void {

FILE: src/commands/workflow/templates.ts
  type TemplatesOptions (line 20) | interface TemplatesOptions {
  type TemplateInfo (line 25) | interface TemplateInfo {
  function templatesCommand (line 35) | async function templatesCommand(options: TemplatesOptions): Promise<void> {

FILE: src/core/archive.ts
  function copyDirRecursive (line 16) | async function copyDirRecursive(src: string, dest: string): Promise<void> {
  function moveDirectory (line 36) | async function moveDirectory(src: string, dest: string): Promise<void> {
  class ArchiveCommand (line 50) | class ArchiveCommand {
    method execute (line 51) | async execute(
    method selectChange (line 290) | private async selectChange(changesDir: string): Promise<string | null> {
    method getArchiveDate (line 335) | private getArchiveDate(): string {

FILE: src/core/artifact-graph/graph.ts
  class ArtifactGraph (line 8) | class ArtifactGraph {
    method constructor (line 12) | private constructor(schema: SchemaYaml) {
    method fromYaml (line 20) | static fromYaml(filePath: string): ArtifactGraph {
    method fromYamlContent (line 28) | static fromYamlContent(yamlContent: string): ArtifactGraph {
    method fromSchema (line 36) | static fromSchema(schema: SchemaYaml): ArtifactGraph {
    method getArtifact (line 43) | getArtifact(id: string): Artifact | undefined {
    method getAllArtifacts (line 50) | getAllArtifacts(): Artifact[] {
    method getName (line 57) | getName(): string {
    method getVersion (line 64) | getVersion(): number {
    method getBuildOrder (line 72) | getBuildOrder(): string[] {
    method getNextArtifacts (line 118) | getNextArtifacts(completed: CompletedSet): string[] {
    method isComplete (line 139) | isComplete(completed: CompletedSet): boolean {
    method getBlocked (line 151) | getBlocked(completed: CompletedSet): BlockedArtifacts {

FILE: src/core/artifact-graph/instruction-loader.ts
  class TemplateLoadError (line 16) | class TemplateLoadError extends Error {
    method constructor (line 17) | constructor(
  type ChangeContext (line 29) | interface ChangeContext {
  type ArtifactInstructions (line 47) | interface ArtifactInstructions {
  type DependencyInfo (line 77) | interface DependencyInfo {
  type ArtifactStatus (line 91) | interface ArtifactStatus {
  type ChangeStatus (line 105) | interface ChangeStatus {
  function loadTemplate (line 127) | function loadTemplate(
  function loadChangeContext (line 173) | function loadChangeContext(
  function generateInstructions (line 211) | function generateInstructions(
  function getDependencyInfo (line 280) | function getDependencyInfo(
  function getUnlockedArtifacts (line 299) | function getUnlockedArtifacts(graph: ArtifactGraph, artifactId: string):...
  function formatChangeStatus (line 317) | function formatChangeStatus(context: ChangeContext): ChangeStatus {

FILE: src/core/artifact-graph/resolver.ts
  class SchemaLoadError (line 11) | class SchemaLoadError extends Error {
    method constructor (line 12) | constructor(
  function getPackageSchemasDir (line 26) | function getPackageSchemasDir(): string {
  function getUserSchemasDir (line 35) | function getUserSchemasDir(): string {
  function getProjectSchemasDir (line 44) | function getProjectSchemasDir(projectRoot: string): string {
  function getSchemaDir (line 63) | function getSchemaDir(
  function resolveSchema (line 109) | function resolveSchema(name: string, projectRoot?: string): SchemaYaml {
  function listSchemas (line 161) | function listSchemas(projectRoot?: string): string[] {
  type SchemaInfo (line 211) | interface SchemaInfo {
  function listSchemasWithInfo (line 224) | function listSchemasWithInfo(projectRoot?: string): SchemaInfo[] {

FILE: src/core/artifact-graph/schema.ts
  class SchemaValidationError (line 5) | class SchemaValidationError extends Error {
    method constructor (line 6) | constructor(message: string) {
  function loadSchema (line 15) | function loadSchema(filePath: string): SchemaYaml {
  function parseSchema (line 23) | function parseSchema(yamlContent: string): SchemaYaml {
  function validateNoDuplicateIds (line 50) | function validateNoDuplicateIds(artifacts: Artifact[]): void {
  function validateRequiresReferences (line 63) | function validateRequiresReferences(artifacts: Artifact[]): void {
  function validateNoCycles (line 81) | function validateNoCycles(artifacts: Artifact[]): void {

FILE: src/core/artifact-graph/state.ts
  function detectCompleted (line 16) | function detectCompleted(graph: ArtifactGraph, changeDir: string): Compl...
  function isArtifactComplete (line 37) | function isArtifactComplete(generates: string, changeDir: string): boole...
  function isGlobPattern (line 52) | function isGlobPattern(pattern: string): boolean {
  function hasGlobMatches (line 60) | function hasGlobMatches(pattern: string): boolean {

FILE: src/core/artifact-graph/types.ts
  type Artifact (line 34) | type Artifact = z.infer<typeof ArtifactSchema>;
  type ApplyPhase (line 35) | type ApplyPhase = z.infer<typeof ApplyPhaseSchema>;
  type SchemaYaml (line 36) | type SchemaYaml = z.infer<typeof SchemaYamlSchema>;
  type ChangeMetadata (line 54) | type ChangeMetadata = z.infer<typeof ChangeMetadataSchema>;
  type CompletedSet (line 59) | type CompletedSet = Set<string>;
  type BlockedArtifacts (line 62) | interface BlockedArtifacts {

FILE: src/core/available-tools.ts
  function getAvailableTools (line 19) | function getAvailableTools(projectPath: string): AIToolOption[] {

FILE: src/core/command-generation/adapters/amazon-q.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/antigravity.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/auggie.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/claude.ts
  function escapeYamlValue (line 14) | function escapeYamlValue(value: string): string {
  function formatTagsArray (line 28) | function formatTagsArray(tags: string[]): string {
  method getFilePath (line 41) | getFilePath(commandId: string): string {
  method formatFile (line 45) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/cline.ts
  method getFilePath (line 19) | getFilePath(commandId: string): string {
  method formatFile (line 23) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/codebuddy.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/codex.ts
  function getCodexHome (line 18) | function getCodexHome(): string {
  method getFilePath (line 31) | getFilePath(commandId: string): string {
  method formatFile (line 35) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/continue.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/costrict.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/crush.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/cursor.ts
  function escapeYamlValue (line 15) | function escapeYamlValue(value: string): string {
  method getFilePath (line 34) | getFilePath(commandId: string): string {
  method formatFile (line 38) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/factory.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/gemini.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/github-copilot.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/iflow.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/kilocode.ts
  method getFilePath (line 19) | getFilePath(commandId: string): string {
  method formatFile (line 23) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/kiro.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/opencode.ts
  method getFilePath (line 19) | getFilePath(commandId: string): string {
  method formatFile (line 23) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/pi.ts
  function escapeYamlValue (line 15) | function escapeYamlValue(value: string): string {
  method getFilePath (line 34) | getFilePath(commandId: string): string {
  method formatFile (line 38) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/qoder.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/qwen.ts
  method getFilePath (line 18) | getFilePath(commandId: string): string {
  method formatFile (line 22) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/roocode.ts
  method getFilePath (line 19) | getFilePath(commandId: string): string {
  method formatFile (line 23) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/adapters/windsurf.ts
  function escapeYamlValue (line 15) | function escapeYamlValue(value: string): string {
  function formatTagsArray (line 29) | function formatTagsArray(tags: string[]): string {
  method getFilePath (line 42) | getFilePath(commandId: string): string {
  method formatFile (line 46) | formatFile(content: CommandContent): string {

FILE: src/core/command-generation/generator.ts
  function generateCommand (line 15) | function generateCommand(
  function generateCommands (line 31) | function generateCommands(

FILE: src/core/command-generation/registry.ts
  class CommandAdapterRegistry (line 36) | class CommandAdapterRegistry {
    method register (line 70) | static register(adapter: ToolCommandAdapter): void {
    method get (line 79) | static get(toolId: string): ToolCommandAdapter | undefined {
    method getAll (line 87) | static getAll(): ToolCommandAdapter[] {
    method has (line 96) | static has(toolId: string): boolean {

FILE: src/core/command-generation/types.ts
  type CommandContent (line 12) | interface CommandContent {
  type ToolCommandAdapter (line 32) | interface ToolCommandAdapter {
  type GeneratedCommand (line 53) | interface GeneratedCommand {

FILE: src/core/completions/command-registry.ts
  constant COMMON_FLAGS (line 6) | const COMMON_FLAGS = {
  constant COMMAND_REGISTRY (line 35) | const COMMAND_REGISTRY: CommandDefinition[] = [

FILE: src/core/completions/completion-provider.ts
  type CacheEntry (line 6) | interface CacheEntry<T> {
  class CompletionProvider (line 16) | class CompletionProvider {
    method constructor (line 27) | constructor(
    method getChangeIds (line 39) | async getChangeIds(): Promise<string[]> {
    method getSpecIds (line 64) | async getSpecIds(): Promise<string[]> {
    method getAllIds (line 89) | async getAllIds(): Promise<{ changeIds: string[]; specIds: string[] }> {
    method clearCache (line 101) | clearCache(): void {
    method getCacheStats (line 111) | getCacheStats(): {

FILE: src/core/completions/factory.ts
  type InstallationResult (line 15) | interface InstallationResult {
  type CompletionInstaller (line 32) | interface CompletionInstaller {
  class CompletionFactory (line 41) | class CompletionFactory {
    method createGenerator (line 51) | static createGenerator(shell: SupportedShell): CompletionGenerator {
    method createInstaller (line 73) | static createInstaller(shell: SupportedShell): CompletionInstaller {
    method isSupported (line 94) | static isSupported(shell: string): shell is SupportedShell {
    method getSupportedShells (line 103) | static getSupportedShells(): SupportedShell[] {

FILE: src/core/completions/generators/bash-generator.ts
  class BashGenerator (line 8) | class BashGenerator implements CompletionGenerator {
    method generate (line 17) | generate(commands: CommandDefinition[]): string {
    method generateCommandCase (line 81) | private generateCommandCase(cmd: CommandDefinition, indent: string): s...
    method generateArgumentCompletion (line 128) | private generateArgumentCompletion(cmd: CommandDefinition, indent: str...
    method generatePositionalCompletion (line 158) | private generatePositionalCompletion(positionalType: string | undefine...
    method escapeCommandName (line 187) | private escapeCommandName(name: string): string {

FILE: src/core/completions/generators/fish-generator.ts
  class FishGenerator (line 8) | class FishGenerator implements CompletionGenerator {
    method generate (line 17) | generate(commands: CommandDefinition[]): string {
    method generateCommandCompletions (line 56) | private generateCommandCompletions(cmd: CommandDefinition): string[] {
    method generateFlagCompletion (line 105) | private generateFlagCompletion(flag: FlagDefinition, condition: string...
    method generatePositionalCompletion (line 153) | private generatePositionalCompletion(positionalType: string | undefine...
    method escapeDescription (line 181) | private escapeDescription(description: string): string {

FILE: src/core/completions/generators/powershell-generator.ts
  class PowerShellGenerator (line 8) | class PowerShellGenerator implements CompletionGenerator {
    method stripTrailingCommaFromLastLine (line 11) | private stripTrailingCommaFromLastLine(lines: string[]): void {
    method generate (line 22) | generate(commands: CommandDefinition[]): string {
    method generateCommandCase (line 79) | private generateCommandCase(cmd: CommandDefinition, indent: string): s...
    method generateArgumentCompletion (line 142) | private generateArgumentCompletion(cmd: CommandDefinition, indent: str...
    method generatePositionalCompletion (line 180) | private generatePositionalCompletion(positionalType: string | undefine...
    method escapeDescription (line 217) | private escapeDescription(description: string): string {

FILE: src/core/completions/generators/zsh-generator.ts
  class ZshGenerator (line 8) | class ZshGenerator implements CompletionGenerator {
    method generate (line 17) | generate(commands: CommandDefinition[]): string {
    method generateCommandFunction (line 86) | private generateCommandFunction(cmd: CommandDefinition): string[] {
    method generateSubcommandFunction (line 170) | private generateSubcommandFunction(parentName: string, subcmd: Command...
    method generateFlagSpec (line 201) | private generateFlagSpec(flag: FlagDefinition): string {
    method generatePositionalSpec (line 236) | private generatePositionalSpec(positionalType?: string): string {
    method escapeDescription (line 256) | private escapeDescription(desc: string): string {
    method escapeValue (line 268) | private escapeValue(value: string): string {
    method sanitizeFunctionName (line 278) | private sanitizeFunctionName(name: string): string {

FILE: src/core/completions/installers/bash-installer.ts
  class BashInstaller (line 11) | class BashInstaller {
    method constructor (line 22) | constructor(homeDir: string = os.homedir()) {
    method isBashCompletionInstalled (line 31) | async isBashCompletionInstalled(): Promise<boolean> {
    method getInstallationPath (line 59) | async getInstallationPath(): Promise<string> {
    method backupExistingFile (line 73) | async backupExistingFile(targetPath: string): Promise<string | undefin...
    method getBashrcPath (line 92) | private getBashrcPath(): string {
    method generateBashrcConfig (line 102) | private generateBashrcConfig(completionsDir: string): string {
    method configureBashrc (line 119) | async configureBashrc(completionsDir: string): Promise<boolean> {
    method removeBashrcConfig (line 157) | async removeBashrcConfig(): Promise<boolean> {
    method install (line 213) | async install(completionScript: string): Promise<InstallationResult> {
    method generateInstructions (line 309) | private generateInstructions(installedPath: string): string[] {
    method uninstall (line 335) | async uninstall(options?: { yes?: boolean }): Promise<{ success: boole...

FILE: src/core/completions/installers/fish-installer.ts
  class FishInstaller (line 10) | class FishInstaller {
    method constructor (line 13) | constructor(homeDir: string = os.homedir()) {
    method getInstallationPath (line 22) | getInstallationPath(): string {
    method backupExistingFile (line 32) | async backupExistingFile(targetPath: string): Promise<string | undefin...
    method install (line 52) | async install(completionScript: string): Promise<InstallationResult> {
    method uninstall (line 124) | async uninstall(options?: { yes?: boolean }): Promise<{ success: boole...

FILE: src/core/completions/installers/powershell-installer.ts
  class PowerShellInstaller (line 11) | class PowerShellInstaller {
    method constructor (line 22) | constructor(homeDir: string = os.homedir()) {
    method getProfilePath (line 32) | getProfilePath(): string {
    method getAllProfilePaths (line 53) | private getAllProfilePaths(): string[] {
    method getInstallationPath (line 77) | getInstallationPath(): string {
    method backupExistingFile (line 89) | async backupExistingFile(targetPath: string): Promise<string | undefin...
    method generateProfileConfig (line 109) | private generateProfileConfig(scriptPath: string): string {
    method configureProfile (line 124) | async configureProfile(scriptPath: string): Promise<boolean> {
    method removeProfileConfig (line 174) | async removeProfileConfig(): Promise<boolean> {
    method install (line 226) | async install(completionScript: string): Promise<InstallationResult> {
    method generateInstructions (line 303) | private generateInstructions(installedPath: string): string[] {
    method uninstall (line 327) | async uninstall(options?: { yes?: boolean }): Promise<{ success: boole...

FILE: src/core/completions/installers/zsh-installer.ts
  class ZshInstaller (line 11) | class ZshInstaller {
    method constructor (line 22) | constructor(homeDir: string = os.homedir()) {
    method isOhMyZshInstalled (line 31) | async isOhMyZshInstalled(): Promise<boolean> {
    method getInstallationPath (line 53) | async getInstallationPath(): Promise<{ path: string; isOhMyZsh: boolea...
    method backupExistingFile (line 77) | async backupExistingFile(targetPath: string): Promise<string | undefin...
    method getZshrcPath (line 96) | private getZshrcPath(): string {
    method generateZshrcConfig (line 106) | private generateZshrcConfig(completionsDir: string): string {
    method configureZshrc (line 122) | async configureZshrc(completionsDir: string): Promise<boolean> {
    method hasZshrcConfig (line 159) | private async hasZshrcConfig(): Promise<boolean> {
    method needsFpathConfig (line 176) | private async needsFpathConfig(completionsDir: string): Promise<boolea...
    method removeZshrcConfig (line 196) | async removeZshrcConfig(): Promise<boolean> {
    method install (line 252) | async install(completionScript: string): Promise<InstallationResult> {
    method generateOhMyZshFpathGuidance (line 353) | private generateOhMyZshFpathGuidance(completionsDir: string): string[]...
    method generateInstructions (line 370) | private generateInstructions(isOhMyZsh: boolean, installedPath: string...
    method uninstall (line 405) | async uninstall(): Promise<{ success: boolean; message: string }> {
    method isInstalled (line 461) | async isInstalled(): Promise<boolean> {
    method getInstallationInfo (line 476) | async getInstallationInfo(): Promise<{

FILE: src/core/completions/templates/bash-templates.ts
  constant BASH_DYNAMIC_HELPERS (line 6) | const BASH_DYNAMIC_HELPERS = `# Dynamic completion helpers

FILE: src/core/completions/templates/fish-templates.ts
  constant FISH_STATIC_HELPERS (line 6) | const FISH_STATIC_HELPERS = `# Helper function to check if a subcommand ...
  constant FISH_DYNAMIC_HELPERS (line 23) | const FISH_DYNAMIC_HELPERS = `# Dynamic completion helpers

FILE: src/core/completions/templates/powershell-templates.ts
  constant POWERSHELL_DYNAMIC_HELPERS (line 6) | const POWERSHELL_DYNAMIC_HELPERS = `# Dynamic completion helpers

FILE: src/core/completions/templates/zsh-templates.ts
  constant ZSH_DYNAMIC_HELPERS (line 6) | const ZSH_DYNAMIC_HELPERS = `# Dynamic completion helpers

FILE: src/core/completions/types.ts
  type FlagDefinition (line 6) | interface FlagDefinition {
  type CommandDefinition (line 36) | interface CommandDefinition {
  type CompletionGenerator (line 78) | interface CompletionGenerator {

FILE: src/core/config-prompts.ts
  function serializeConfig (line 9) | function serializeConfig(config: Partial<ProjectConfig>): string {

FILE: src/core/config-schema.ts
  type GlobalConfigType (line 27) | type GlobalConfigType = z.infer<typeof GlobalConfigSchema>;
  constant DEFAULT_CONFIG (line 32) | const DEFAULT_CONFIG: GlobalConfigType = {
  constant KNOWN_TOP_LEVEL_KEYS (line 38) | const KNOWN_TOP_LEVEL_KEYS = new Set([...Object.keys(DEFAULT_CONFIG), 'w...
  function validateConfigKeyPath (line 44) | function validateConfigKeyPath(path: string): { valid: boolean; reason?:...
  function getNestedValue (line 77) | function getNestedValue(obj: Record<string, unknown>, path: string): unk...
  function setNestedValue (line 102) | function setNestedValue(obj: Record<string, unknown>, path: string, valu...
  function deleteNestedValue (line 125) | function deleteNestedValue(obj: Record<string, unknown>, path: string): ...
  function coerceValue (line 155) | function coerceValue(value: string, forceString: boolean = false): strin...
  function formatValueYaml (line 184) | function formatValueYaml(value: unknown, indent: number = 0): string {
  function validateConfig (line 231) | function validateConfig(config: unknown): { success: boolean; error?: st...

FILE: src/core/config.ts
  constant OPENSPEC_DIR_NAME (line 1) | const OPENSPEC_DIR_NAME = 'openspec';
  constant OPENSPEC_MARKERS (line 3) | const OPENSPEC_MARKERS = {
  type OpenSpecConfig (line 8) | interface OpenSpecConfig {
  type AIToolOption (line 12) | interface AIToolOption {
  constant AI_TOOLS (line 20) | const AI_TOOLS: AIToolOption[] = [

FILE: src/core/converters/json-converter.ts
  class JsonConverter (line 8) | class JsonConverter {
    method convertSpecToJson (line 9) | convertSpecToJson(filePath: string): string {
    method convertChangeToJson (line 27) | async convertChangeToJson(filePath: string): Promise<string> {
    method extractNameFromPath (line 46) | private extractNameFromPath(filePath: string): string {

FILE: src/core/global-config.ts
  constant GLOBAL_CONFIG_DIR_NAME (line 6) | const GLOBAL_CONFIG_DIR_NAME = 'openspec';
  constant GLOBAL_CONFIG_FILE_NAME (line 7) | const GLOBAL_CONFIG_FILE_NAME = 'config.json';
  constant GLOBAL_DATA_DIR_NAME (line 8) | const GLOBAL_DATA_DIR_NAME = 'openspec';
  type Profile (line 11) | type Profile = 'core' | 'custom';
  type Delivery (line 12) | type Delivery = 'both' | 'skills' | 'commands';
  type GlobalConfig (line 15) | interface GlobalConfig {
  constant DEFAULT_CONFIG (line 22) | const DEFAULT_CONFIG: GlobalConfig = {
  function getGlobalConfigDir (line 35) | function getGlobalConfigDir(): string {
  function getGlobalDataDir (line 66) | function getGlobalDataDir(): string {
  function getGlobalConfigPath (line 92) | function getGlobalConfigPath(): string {
  function getGlobalConfig (line 101) | function getGlobalConfig(): GlobalConfig {
  function saveGlobalConfig (line 145) | function saveGlobalConfig(config: GlobalConfig): void {

FILE: src/core/init.ts
  constant DEFAULT_SCHEMA (line 56) | const DEFAULT_SCHEMA = 'spec-driven';
  constant PROGRESS_SPINNER (line 58) | const PROGRESS_SPINNER = {
  constant WORKFLOW_TO_SKILL_DIR (line 63) | const WORKFLOW_TO_SKILL_DIR: Record<string, string> = {
  type InitCommandOptions (line 81) | type InitCommandOptions = {
  class InitCommand (line 92) | class InitCommand {
    method constructor (line 98) | constructor(options: InitCommandOptions = {}) {
    method execute (line 105) | async execute(targetPath: string): Promise<void> {
    method validate (line 161) | private async validate(
    method canPromptInteractively (line 174) | private canPromptInteractively(): boolean {
    method resolveProfileOverride (line 180) | private resolveProfileOverride(): Profile | undefined {
    method handleLegacyCleanup (line 196) | private async handleLegacyCleanup(projectPath: string, extendMode: boo...
    method performLegacyCleanup (line 235) | private async performLegacyCleanup(projectPath: string, detection: Leg...
    method getSelectedTools (line 255) | private async getSelectedTools(
    method resolveToolsArg (line 354) | private resolveToolsArg(): string[] | null {
    method validateTools (line 417) | private validateTools(
    method createDirectoryStructure (line 455) | private async createDirectoryStructure(openspecPath: string, extendMod...
    method generateSkillsAndCommands (line 494) | private async generateSkillsAndCommands(
    method createConfig (line 598) | private async createConfig(openspecPath: string, extendMode: boolean):...
    method displaySuccessMessage (line 626) | private displaySuccessMessage(
    method startSpinner (line 728) | private startSpinner(text: string) {
    method removeSkillDirs (line 737) | private async removeSkillDirs(skillsDir: string): Promise<number> {
    method removeCommandFiles (line 758) | private async removeCommandFiles(projectPath: string, toolId: string):...

FILE: src/core/legacy-cleanup.ts
  constant LEGACY_CONFIG_FILES (line 16) | const LEGACY_CONFIG_FILES = [
  constant LEGACY_SLASH_COMMAND_PATHS (line 32) | const LEGACY_SLASH_COMMAND_PATHS: Record<string, LegacySlashCommandPatte...
  type LegacySlashCommandPattern (line 63) | interface LegacySlashCommandPattern {
  type LegacyDetectionResult (line 72) | interface LegacyDetectionResult {
  function detectLegacyArtifacts (line 97) | async function detectLegacyArtifacts(
  function detectLegacyConfigFiles (line 147) | async function detectLegacyConfigFiles(
  function detectLegacySlashCommands (line 178) | async function detectLegacySlashCommands(
  function findLegacySlashCommandFiles (line 213) | async function findLegacySlashCommandFiles(
  function detectLegacyStructureFiles (line 265) | async function detectLegacyStructureFiles(
  function hasOpenSpecMarkers (line 300) | function hasOpenSpecMarkers(content: string): boolean {
  function isOnlyOpenSpecContent (line 312) | function isOnlyOpenSpecContent(content: string): boolean {
  function removeMarkerBlock (line 334) | function removeMarkerBlock(content: string): string {
  type CleanupResult (line 341) | interface CleanupResult {
  function cleanupLegacyArtifacts (line 362) | async function cleanupLegacyArtifacts(
  function formatCleanupSummary (line 437) | function formatCleanupSummary(result: CleanupResult): string {
  function buildRemovalsList (line 484) | function buildRemovalsList(detection: LegacyDetectionResult): Array<{ pa...
  function buildUpdatesList (line 517) | function buildUpdatesList(detection: LegacyDetectionResult): Array<{ pat...
  function formatDetectionSummary (line 535) | function formatDetectionSummary(detection: LegacyDetectionResult): string {
  function getToolsFromLegacyArtifacts (line 589) | function getToolsFromLegacyArtifacts(detection: LegacyDetectionResult): ...
  function formatProjectMdMigrationHint (line 637) | function formatProjectMdMigrationHint(): string {

FILE: src/core/list.ts
  type ChangeInfo (line 8) | interface ChangeInfo {
  type ListOptions (line 15) | interface ListOptions {
  function getLastModified (line 24) | async function getLastModified(dirPath: string): Promise<Date> {
  function formatRelativeTime (line 56) | function formatRelativeTime(date: Date): string {
  class ListCommand (line 77) | class ListCommand {
    method execute (line 78) | async execute(targetPath: string = '.', mode: 'changes' | 'specs' = 'c...

FILE: src/core/migration.ts
  type InstalledWorkflowArtifacts (line 16) | interface InstalledWorkflowArtifacts {
  function scanInstalledWorkflowArtifacts (line 22) | function scanInstalledWorkflowArtifacts(
  function scanInstalledWorkflows (line 69) | function scanInstalledWorkflows(projectPath: string, tools: AIToolOption...
  function inferDelivery (line 73) | function inferDelivery(artifacts: InstalledWorkflowArtifacts): Delivery {
  function migrateIfNeeded (line 92) | function migrateIfNeeded(projectPath: string, tools: AIToolOption[]): vo...

FILE: src/core/parsers/change-parser.ts
  type DeltaSection (line 6) | interface DeltaSection {
  class ChangeParser (line 12) | class ChangeParser extends MarkdownParser {
    method constructor (line 15) | constructor(content: string, changeDir: string) {
    method parseChangeWithDeltas (line 20) | async parseChangeWithDeltas(name: string): Promise<Change> {
    method parseDeltaSpecs (line 55) | private async parseDeltaSpecs(specsDir: string): Promise<Delta[]> {
    method parseSpecDeltas (line 84) | private parseSpecDeltas(specName: string, content: string): Delta[] {
    method parseRenames (line 151) | private parseRenames(content: string): Array<{ from: string; to: strin...
    method parseSectionsFromContent (line 179) | private parseSectionsFromContent(content: string): Section[] {
    method getContentUntilNextHeaderFromLines (line 218) | private getContentUntilNextHeaderFromLines(lines: string[], startLine:...

FILE: src/core/parsers/markdown-parser.ts
  type Section (line 3) | interface Section {
  class MarkdownParser (line 10) | class MarkdownParser {
    method constructor (line 14) | constructor(content: string) {
    method normalizeContent (line 20) | protected static normalizeContent(content: string): string {
    method parseSpec (line 24) | parseSpec(name: string): Spec {
    method parseChange (line 51) | parseChange(name: string): Change {
    method parseSections (line 78) | protected parseSections(): Section[] {
    method getContentUntilNextHeader (line 115) | protected getContentUntilNextHeader(startLine: number, currentLevel: n...
    method findSection (line 132) | protected findSection(sections: Section[], title: string): Section | u...
    method parseRequirements (line 145) | protected parseRequirements(section: Section): Requirement[] {
    method parseScenarios (line 187) | protected parseScenarios(requirementSection: Section): Scenario[] {
    method parseDeltas (line 203) | protected parseDeltas(content: string): Delta[] {

FILE: src/core/parsers/requirement-blocks.ts
  type RequirementBlock (line 1) | interface RequirementBlock {
  type RequirementsSectionParts (line 7) | interface RequirementsSectionParts {
  function normalizeRequirementName (line 15) | function normalizeRequirementName(name: string): string {
  constant REQUIREMENT_HEADER_REGEX (line 19) | const REQUIREMENT_HEADER_REGEX = /^###\s*Requirement:\s*(.+)\s*$/;
  function extractRequirementsSection (line 24) | function extractRequirementsSection(content: string): RequirementsSectio...
  type DeltaPlan (line 99) | interface DeltaPlan {
  function normalizeLineEndings (line 112) | function normalizeLineEndings(content: string): string {
  function parseDeltaSpec (line 119) | function parseDeltaSpec(content: string): DeltaPlan {
  function splitTopLevelSections (line 144) | function splitTopLevelSections(content: string): Record<string, string> {
  function getSectionCaseInsensitive (line 164) | function getSectionCaseInsensitive(sections: Record<string, string>, des...
  function parseRequirementBlocksFromSection (line 172) | function parseRequirementBlocksFromSection(sectionBody: string): Require...
  function parseRemovedNames (line 196) | function parseRemovedNames(sectionBody: string): string[] {
  function parseRenamedPairs (line 215) | function parseRenamedPairs(sectionBody: string): Array<{ from: string; t...

FILE: src/core/profile-sync-drift.ts
  type WorkflowId (line 9) | type WorkflowId = (typeof ALL_WORKFLOWS)[number];
  constant WORKFLOW_TO_SKILL_DIR (line 14) | const WORKFLOW_TO_SKILL_DIR: Record<WorkflowId, string> = {
  function toKnownWorkflows (line 28) | function toKnownWorkflows(workflows: readonly string[]): WorkflowId[] {
  function toolHasAnyConfiguredCommand (line 38) | function toolHasAnyConfiguredCommand(projectPath: string, toolId: string...
  function getCommandConfiguredTools (line 56) | function getCommandConfiguredTools(projectPath: string): string[] {
  function getConfiguredToolsForProfileSync (line 74) | function getConfiguredToolsForProfileSync(projectPath: string): string[] {
  function hasToolProfileOrDeliveryDrift (line 88) | function hasToolProfileOrDeliveryDrift(
  function getToolsNeedingProfileSync (line 166) | function getToolsNeedingProfileSync(
  function getInstalledWorkflowsForTool (line 178) | function getInstalledWorkflowsForTool(
  function hasProjectConfigDrift (line 218) | function hasProjectConfigDrift(

FILE: src/core/profiles.ts
  constant CORE_WORKFLOWS (line 14) | const CORE_WORKFLOWS = ['propose', 'explore', 'apply', 'archive'] as const;
  constant ALL_WORKFLOWS (line 19) | const ALL_WORKFLOWS = [
  type WorkflowId (line 33) | type WorkflowId = (typeof ALL_WORKFLOWS)[number];
  type CoreWorkflowId (line 34) | type CoreWorkflowId = (typeof CORE_WORKFLOWS)[number];
  function getProfileWorkflows (line 42) | function getProfileWorkflows(

FILE: src/core/project-config.ts
  type ProjectConfig (line 43) | type ProjectConfig = z.infer<typeof ProjectConfigSchema>;
  constant MAX_CONTEXT_SIZE (line 45) | const MAX_CONTEXT_SIZE = 50 * 1024;
  function readProjectConfig (line 66) | function readProjectConfig(projectRoot: string): ProjectConfig | null {
  function validateConfigRules (line 173) | function validateConfigRules(
  function suggestSchemas (line 201) | function suggestSchemas(

FILE: src/core/schemas/base.schema.ts
  type Scenario (line 19) | type Scenario = z.infer<typeof ScenarioSchema>;
  type Requirement (line 20) | type Requirement = z.infer<typeof RequirementSchema>;

FILE: src/core/schemas/change.schema.ts
  type DeltaOperation (line 40) | type DeltaOperation = z.infer<typeof DeltaOperationType>;
  type Delta (line 41) | type Delta = z.infer<typeof DeltaSchema>;
  type Change (line 42) | type Change = z.infer<typeof ChangeSchema>;

FILE: src/core/schemas/spec.schema.ts
  type Spec (line 17) | type Spec = z.infer<typeof SpecSchema>;

FILE: src/core/shared/skill-generation.ts
  type SkillTemplateEntry (line 37) | interface SkillTemplateEntry {
  type CommandTemplateEntry (line 46) | interface CommandTemplateEntry {
  function getSkillTemplates (line 56) | function getSkillTemplates(workflowFilter?: readonly string[]): SkillTem...
  function getCommandTemplates (line 82) | function getCommandTemplates(workflowFilter?: readonly string[]): Comman...
  function getCommandContents (line 108) | function getCommandContents(workflowFilter?: readonly string[]): Command...
  function generateSkillContent (line 127) | function generateSkillContent(

FILE: src/core/shared/tool-detection.ts
  constant SKILL_NAMES (line 14) | const SKILL_NAMES = [
  type SkillName (line 28) | type SkillName = (typeof SKILL_NAMES)[number];
  constant COMMAND_IDS (line 33) | const COMMAND_IDS = [
  type CommandId (line 47) | type CommandId = (typeof COMMAND_IDS)[number];
  type ToolSkillStatus (line 52) | interface ToolSkillStatus {
  type ToolVersionStatus (line 64) | interface ToolVersionStatus {
  function getToolsWithSkillsDir (line 80) | function getToolsWithSkillsDir(): string[] {
  function getToolSkillStatus (line 87) | function getToolSkillStatus(projectRoot: string, toolId: string): ToolSk...
  function getToolStates (line 113) | function getToolStates(projectRoot: string): Map<string, ToolSkillStatus> {
  function extractGeneratedByVersion (line 128) | function extractGeneratedByVersion(skillFilePath: string): string | null {
  function getToolVersionStatus (line 160) | function getToolVersionStatus(
  function getConfiguredTools (line 203) | function getConfiguredTools(projectRoot: string): string[] {
  function getAllToolVersionStatus (line 212) | function getAllToolVersionStatus(

FILE: src/core/specs-apply.ts
  type SpecUpdate (line 23) | interface SpecUpdate {
  type ApplyResult (line 29) | interface ApplyResult {
  type SpecsApplyOutput (line 37) | interface SpecsApplyOutput {
  function findSpecUpdates (line 56) | async function findSpecUpdates(changeDir: string, mainSpecsDir: string):...
  function buildUpdatedSpec (line 101) | async function buildUpdatedSpec(
  function writeUpdatedSpec (line 342) | async function writeUpdatedSpec(
  function buildSpecSkeleton (line 363) | function buildSpecSkeleton(specFolderName: string, changeName: string): ...
  function applySpecs (line 376) | async function applySpecs(

FILE: src/core/styles/palette.ts
  constant PALETTE (line 3) | const PALETTE = {

FILE: src/core/templates/types.ts
  type SkillTemplate (line 5) | interface SkillTemplate {
  type CommandTemplate (line 14) | interface CommandTemplate {

FILE: src/core/templates/workflows/apply-change.ts
  function getApplyChangeSkillTemplate (line 9) | function getApplyChangeSkillTemplate(): SkillTemplate {
  function getOpsxApplyCommandTemplate (line 164) | function getOpsxApplyCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/archive-change.ts
  function getArchiveChangeSkillTemplate (line 9) | function getArchiveChangeSkillTemplate(): SkillTemplate {
  function getOpsxArchiveCommandTemplate (line 122) | function getOpsxArchiveCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/bulk-archive-change.ts
  function getBulkArchiveChangeSkillTemplate (line 9) | function getBulkArchiveChangeSkillTemplate(): SkillTemplate {
  function getOpsxBulkArchiveCommandTemplate (line 254) | function getOpsxBulkArchiveCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/continue-change.ts
  function getContinueChangeSkillTemplate (line 9) | function getContinueChangeSkillTemplate(): SkillTemplate {
  function getOpsxContinueCommandTemplate (line 126) | function getOpsxContinueCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/explore.ts
  function getExploreSkillTemplate (line 9) | function getExploreSkillTemplate(): SkillTemplate {
  function getOpsxExploreCommandTemplate (line 296) | function getOpsxExploreCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/feedback.ts
  function getFeedbackSkillTemplate (line 9) | function getFeedbackSkillTemplate(): SkillTemplate {

FILE: src/core/templates/workflows/ff-change.ts
  function getFfChangeSkillTemplate (line 9) | function getFfChangeSkillTemplate(): SkillTemplate {
  function getOpsxFfCommandTemplate (line 109) | function getOpsxFfCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/new-change.ts
  function getNewChangeSkillTemplate (line 9) | function getNewChangeSkillTemplate(): SkillTemplate {
  function getOpsxNewCommandTemplate (line 82) | function getOpsxNewCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/onboard.ts
  function getOnboardSkillTemplate (line 9) | function getOnboardSkillTemplate(): SkillTemplate {
  function getOnboardInstructions (line 20) | function getOnboardInstructions(): string {
  function getOpsxOnboardCommandTemplate (line 566) | function getOpsxOnboardCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/propose.ts
  function getOpsxProposeSkillTemplate (line 9) | function getOpsxProposeSkillTemplate(): SkillTemplate {
  function getOpsxProposeCommandTemplate (line 118) | function getOpsxProposeCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/sync-specs.ts
  function getSyncSpecsSkillTemplate (line 9) | function getSyncSpecsSkillTemplate(): SkillTemplate {
  function getOpsxSyncCommandTemplate (line 146) | function getOpsxSyncCommandTemplate(): CommandTemplate {

FILE: src/core/templates/workflows/verify-change.ts
  function getVerifyChangeSkillTemplate (line 9) | function getVerifyChangeSkillTemplate(): SkillTemplate {
  function getOpsxVerifyCommandTemplate (line 176) | function getOpsxVerifyCommandTemplate(): CommandTemplate {

FILE: src/core/update.ts
  type UpdateCommandOptions (line 57) | interface UpdateCommandOptions {
  function scanInstalledWorkflows (line 68) | function scanInstalledWorkflows(projectPath: string, toolIds: string[]):...
  class UpdateCommand (line 75) | class UpdateCommand {
    method constructor (line 78) | constructor(options: UpdateCommandOptions = {}) {
    method execute (line 82) | async execute(projectPath: string): Promise<void> {
    method displayUpToDateMessage (line 299) | private displayUpToDateMessage(toolStatuses: ToolVersionStatus[]): void {
    method displayUpdatePlan (line 310) | private displayUpdatePlan(
    method detectNewTools (line 335) | private detectNewTools(projectPath: string, configuredTools: string[])...
    method displayExtraWorkflowsNote (line 358) | private displayExtraWorkflowsNote(
    method removeSkillDirs (line 376) | private async removeSkillDirs(skillsDir: string): Promise<number> {
    method removeUnselectedSkillDirs (line 401) | private async removeUnselectedSkillDirs(
    method removeCommandFiles (line 431) | private async removeCommandFiles(
    method removeUnselectedCommandFiles (line 461) | private async removeUnselectedCommandFiles(
    method handleLegacyCleanup (line 496) | private async handleLegacyCleanup(
    method performLegacyCleanup (line 551) | private async performLegacyCleanup(projectPath: string, detection: Leg...
    method upgradeLegacyTools (line 571) | private async upgradeLegacyTools(

FILE: src/core/validation/constants.ts
  constant MIN_WHY_SECTION_LENGTH (line 6) | const MIN_WHY_SECTION_LENGTH = 50;
  constant MIN_PURPOSE_LENGTH (line 7) | const MIN_PURPOSE_LENGTH = 50;
  constant MAX_WHY_SECTION_LENGTH (line 10) | const MAX_WHY_SECTION_LENGTH = 1000;
  constant MAX_REQUIREMENT_TEXT_LENGTH (line 11) | const MAX_REQUIREMENT_TEXT_LENGTH = 500;
  constant MAX_DELTAS_PER_CHANGE (line 12) | const MAX_DELTAS_PER_CHANGE = 10;
  constant VALIDATION_MESSAGES (line 15) | const VALIDATION_MESSAGES = {

FILE: src/core/validation/types.ts
  type ValidationLevel (line 1) | type ValidationLevel = 'ERROR' | 'WARNING' | 'INFO';
  type ValidationIssue (line 3) | interface ValidationIssue {
  type ValidationReport (line 11) | interface ValidationReport {

FILE: src/core/validation/validator.ts
  class Validator (line 16) | class Validator {
    method constructor (line 19) | constructor(strictMode: boolean = false) {
    method validateSpec (line 23) | async validateSpec(filePath: string): Promise<ValidationReport> {
    method validateSpecContent (line 56) | async validateSpecContent(specName: string, content: string): Promise<...
    method validateChange (line 74) | async validateChange(filePath: string): Promise<ValidationReport> {
    method validateChangeDeltaSpecs (line 114) | async validateChangeDeltaSpecs(changeDir: string): Promise<ValidationR...
    method convertZodErrors (line 275) | private convertZodErrors(error: ZodError): ValidationIssue[] {
    method applySpecRules (line 289) | private applySpecRules(spec: Spec, content: string): ValidationIssue[] {
    method applyChangeRules (line 321) | private applyChangeRules(change: Change, content: string): ValidationI...
    method enrichTopLevelError (line 348) | private enrichTopLevelError(itemId: string, baseMessage: string): stri...
    method extractNameFromPath (line 362) | private extractNameFromPath(filePath: string): string {
    method createReport (line 381) | private createReport(issues: ValidationIssue[]): ValidationReport {
    method isValid (line 401) | isValid(report: ValidationReport): boolean {
    method extractRequirementText (line 405) | private extractRequirementText(blockRaw: string): string | undefined {
    method containsShallOrMust (line 433) | private containsShallOrMust(text: string): boolean {
    method countScenarios (line 437) | private countScenarios(blockRaw: string): number {
    method formatSectionList (line 442) | private formatSectionList(sections: string[]): string {

FILE: src/core/view.ts
  class ViewCommand (line 7) | class ViewCommand {
    method execute (line 8) | async execute(targetPath: string = '.'): Promise<void> {
    method getChangesData (line 81) | private async getChangesData(openspecDir: string): Promise<{
    method getSpecsData (line 132) | private async getSpecsData(openspecDir: string): Promise<Array<{ name:...
    method displaySummary (line 164) | private displaySummary(
    method createProgressBar (line 207) | private createProgressBar(completed: number, total: number, width: num...

FILE: src/prompts/searchable-multi-select.ts
  type Choice (line 3) | interface Choice {
  type Config (line 13) | interface Config {
  function createSearchableMultiSelect (line 24) | async function createSearchableMultiSelect(): Promise<
  function searchableMultiSelect (line 215) | async function searchableMultiSelect(config: Config): Promise<string[]> {

FILE: src/telemetry/config.ts
  type TelemetryConfig (line 9) | interface TelemetryConfig {
  type GlobalConfig (line 14) | interface GlobalConfig {
  function getConfigPath (line 23) | function getConfigPath(): string {
  function readConfig (line 32) | async function readConfig(): Promise<GlobalConfig> {
  function writeConfig (line 50) | async function writeConfig(updates: Partial<GlobalConfig>): Promise<void> {
  function getTelemetryConfig (line 72) | async function getTelemetryConfig(): Promise<TelemetryConfig> {
  function updateTelemetryConfig (line 80) | async function updateTelemetryConfig(updates: Partial<TelemetryConfig>):...

FILE: src/telemetry/index.ts
  constant POSTHOG_API_KEY (line 17) | const POSTHOG_API_KEY = 'phc_Hthu8YvaIJ9QaFKyTG4TbVwkbd5ktcAFzVTKeMmoW2g';
  constant POSTHOG_HOST (line 19) | const POSTHOG_HOST = 'https://edge.openspec.dev';
  function isTelemetryEnabled (line 32) | function isTelemetryEnabled(): boolean {
  function getOrCreateAnonymousId (line 55) | async function getOrCreateAnonymousId(): Promise<string> {
  function getClient (line 78) | function getClient(): PostHog {
  function trackCommand (line 95) | async function trackCommand(commandName: string, version: string): Promi...
  function maybeShowTelemetryNotice (line 122) | async function maybeShowTelemetryNotice(): Promise<void> {
  function shutdown (line 149) | async function shutdown(): Promise<void> {

FILE: src/ui/ascii-patterns.ts
  constant CHARS (line 14) | const CHARS = supportsUnicode
  constant WELCOME_ANIMATION (line 29) | const WELCOME_ANIMATION = {

FILE: src/ui/welcome-screen.ts
  constant MIN_WIDTH (line 10) | const MIN_WIDTH = 60;
  constant ART_COLUMN_WIDTH (line 13) | const ART_COLUMN_WIDTH = 24;
  function getWelcomeText (line 18) | function getWelcomeText(): string[] {
  function renderFrame (line 39) | function renderFrame(artLines: string[], textLines: string[]): string {
  function canAnimate (line 63) | function canAnimate(): boolean {
  function waitForEnter (line 80) | function waitForEnter(): Promise<void> {
  function showWelcomeScreen (line 121) | async function showWelcomeScreen(): Promise<void> {

FILE: src/utils/change-metadata.ts
  constant METADATA_FILENAME (line 8) | const METADATA_FILENAME = '.openspec.yaml';
  class ChangeMetadataError (line 13) | class ChangeMetadataError extends Error {
    method constructor (line 14) | constructor(
  function validateSchemaName (line 32) | function validateSchemaName(
  function writeChangeMetadata (line 53) | function writeChangeMetadata(
  function readChangeMetadata (line 94) | function readChangeMetadata(
  function resolveSchemaForChange (line 162) | function resolveSchemaForChange(

FILE: src/utils/change-utils.ts
  constant DEFAULT_SCHEMA (line 6) | const DEFAULT_SCHEMA = 'spec-driven';
  type CreateChangeOptions (line 11) | interface CreateChangeOptions {
  type CreateChangeResult (line 19) | interface CreateChangeResult {
  type ValidationResult (line 27) | interface ValidationResult {
  function validateChangeName (line 48) | function validateChangeName(name: string): ValidationResult {
  function createChange (line 112) | async function createChange(

FILE: src/utils/command-references.ts
  function transformToHyphenCommands (line 18) | function transformToHyphenCommands(text: string): string {

FILE: src/utils/file-system.ts
  function isMarkerOnOwnLine (line 4) | function isMarkerOnOwnLine(content: string, markerIndex: number, markerL...
  function findMarkerIndex (line 26) | function findMarkerIndex(
  class FileSystemUtils (line 44) | class FileSystemUtils {
    method toPosixPath (line 49) | static toPosixPath(p: string): string {
    method isWindowsBasePath (line 53) | private static isWindowsBasePath(basePath: string): boolean {
    method normalizeSegments (line 57) | private static normalizeSegments(segments: string[]): string[] {
    method joinPath (line 63) | static joinPath(basePath: string, ...segments: string[]): string {
    method createDirectory (line 80) | static async createDirectory(dirPath: string): Promise<void> {
    method fileExists (line 84) | static async fileExists(filePath: string): Promise<boolean> {
    method findFirstExistingDirectory (line 101) | private static async findFirstExistingDirectory(dirPath: string): Prom...
    method canWriteFile (line 131) | static async canWriteFile(filePath: string): Promise<boolean> {
    method directoryExists (line 172) | static async directoryExists(dirPath: string): Promise<boolean> {
    method writeFile (line 184) | static async writeFile(filePath: string, content: string): Promise<voi...
    method readFile (line 190) | static async readFile(filePath: string): Promise<string> {
    method updateFileWithMarkers (line 194) | static async updateFileWithMarkers(
    method ensureWritePermissions (line 232) | static async ensureWritePermissions(dirPath: string): Promise<boolean> {
  function removeMarkerBlock (line 282) | function removeMarkerBlock(

FILE: src/utils/interactive.ts
  type InteractiveOptions (line 1) | type InteractiveOptions = {
  function resolveNoInteractive (line 17) | function resolveNoInteractive(value?: boolean | InteractiveOptions): boo...
  function isInteractive (line 22) | function isInteractive(value?: boolean | InteractiveOptions): boolean {

FILE: src/utils/item-discovery.ts
  function getActiveChangeIds (line 4) | async function getActiveChangeIds(root: string = process.cwd()): Promise...
  function getSpecIds (line 25) | async function getSpecIds(root: string = process.cwd()): Promise<string[...
  function getArchivedChangeIds (line 46) | async function getArchivedChangeIds(root: string = process.cwd()): Promi...

FILE: src/utils/match.ts
  function nearestMatches (line 1) | function nearestMatches(input: string, candidates: string[], max: number...
  function levenshtein (line 7) | function levenshtein(a: string, b: string): number {

FILE: src/utils/shell-detection.ts
  type SupportedShell (line 4) | type SupportedShell = 'zsh' | 'bash' | 'fish' | 'powershell';
  type ShellDetectionResult (line 9) | interface ShellDetectionResult {
  function detectShell (line 21) | function detectShell(): ShellDetectionResult {

FILE: src/utils/task-progress.ts
  constant TASK_PATTERN (line 4) | const TASK_PATTERN = /^[-*]\s+\[[\sx]\]/i;
  constant COMPLETED_TASK_PATTERN (line 5) | const COMPLETED_TASK_PATTERN = /^[-*]\s+\[x\]/i;
  type TaskProgress (line 7) | interface TaskProgress {
  function countTasksFromContent (line 12) | function countTasksFromContent(content: string): TaskProgress {
  function getTaskProgressForChange (line 27) | async function getTaskProgressForChange(changesDir: string, changeName: ...
  function formatTaskStatus (line 37) | function formatTaskStatus(progress: TaskProgress): string {

FILE: test/cli-e2e/basic.test.ts
  function fileExists (line 8) | async function fileExists(filePath: string): Promise<boolean> {
  function prepareFixture (line 19) | async function prepareFixture(fixtureName: string): Promise<string> {

FILE: test/commands/artifact-workflow.test.ts
  function getOutput (line 26) | function getOutput(result: { stdout: string; stderr: string }): string {
  function normalizePaths (line 33) | function normalizePaths(str: string): string {
  function createTestChange (line 42) | async function createTestChange(

FILE: test/commands/config-profile.test.ts
  function runConfigCommand (line 13) | async function runConfigCommand(args: string[]): Promise<void> {
  function getPromptMocks (line 20) | async function getPromptMocks(): Promise<{
  function setupDriftedProjectArtifacts (line 85) | function setupDriftedProjectArtifacts(projectDir: string): void {
  function setupSyncedCoreBothArtifacts (line 92) | function setupSyncedCoreBothArtifacts(projectDir: string): void {
  function addExtraSyncWorkflowArtifacts (line 114) | function addExtraSyncWorkflowArtifacts(projectDir: string): void {

FILE: test/core/artifact-graph/workflow.integration.test.ts
  function normalizeBlocked (line 14) | function normalizeBlocked(blocked: BlockedArtifacts): BlockedArtifacts {

FILE: test/core/command-generation/types.test.ts
  method getFilePath (line 42) | getFilePath(commandId: string): string {
  method formatFile (line 45) | formatFile(content: CommandContent): string {

FILE: test/core/init.test.ts
  function fileExists (line 744) | async function fileExists(filePath: string): Promise<boolean> {
  function directoryExists (line 753) | async function directoryExists(dirPath: string): Promise<boolean> {

FILE: test/core/migration.test.ts
  constant CLAUDE_TOOL (line 12) | const CLAUDE_TOOL = AI_TOOLS.find((tool) => tool.value === 'claude') as ...
  function ensureClaudeTool (line 14) | function ensureClaudeTool(): AIToolOption {
  function writeSkill (line 21) | async function writeSkill(projectPath: string, dirName: string): Promise...
  function writeManagedCommand (line 27) | async function writeManagedCommand(projectPath: string, workflowId: stri...
  function readRawConfig (line 40) | function readRawConfig(): Record<string, unknown> {

FILE: test/core/parsers/change-parser.test.ts
  function withTempDir (line 7) | async function withTempDir(run: (dir: string) => Promise<void>) {

FILE: test/core/profile-sync-drift.test.ts
  function writeSkill (line 12) | function writeSkill(projectDir: string, workflowId: string): void {
  function writeCommand (line 19) | function writeCommand(projectDir: string, workflowId: string): void {
  function setupCoreSkills (line 28) | function setupCoreSkills(projectDir: string): void {
  function setupCoreCommands (line 34) | function setupCoreCommands(projectDir: string): void {

FILE: test/core/templates/skill-templates-parity.test.ts
  constant EXPECTED_FUNCTION_HASHES (line 32) | const EXPECTED_FUNCTION_HASHES: Record<string, string> = {
  constant EXPECTED_GENERATED_SKILL_CONTENT_HASHES (line 58) | const EXPECTED_GENERATED_SKILL_CONTENT_HASHES: Record<string, string> = {
  function stableStringify (line 72) | function stableStringify(value: unknown): string {
  function hash (line 88) | function hash(value: string): string {

FILE: test/core/update.test.ts
  function setMockConfig (line 33) | function setMockConfig(config: GlobalConfig) {
  function resetMockConfig (line 37) | function resetMockConfig() {

FILE: test/helpers/run-cli.ts
  type RunCommandOptions (line 14) | interface RunCommandOptions {
  type RunCLIOptions (line 19) | interface RunCLIOptions {
  type RunCLIResult (line 26) | interface RunCLIResult {
  function runCommand (line 35) | function runCommand(command: string, args: string[], options: RunCommand...
  function ensureCliBuilt (line 56) | async function ensureCliBuilt() {
  function runCLI (line 75) | async function runCLI(args: string[] = [], options: RunCLIOptions = {}):...

FILE: test/prompts/searchable-multi-select.test.ts
  function resetState (line 20) | function resetState() {
  function rerender (line 35) | function rerender() {
  function pressKey (line 78) | function pressKey(name: string) {
  function getSelectedValues (line 83) | function getSelectedValues(): string[] {
  function getStatus (line 87) | function getStatus(): string {
  function getError (line 91) | function getError(): string | null {
  function setup (line 101) | async function setup(choices = testChoices, validate?: (selected: string...

FILE: test/specs/source-specs-normalization.test.ts
  constant DELTA_HEADER_PATTERN (line 11) | const DELTA_HEADER_PATTERN = /^## (ADDED|MODIFIED|REMOVED|RENAMED) Requi...
  constant PURPOSE_PLACEHOLDER_PATTERN (line 12) | const PURPOSE_PLACEHOLDER_PATTERN = /TBD - created by archiving change ....
  function getSpecFiles (line 14) | async function getSpecFiles(): Promise<string[]> {

FILE: vitest.config.ts
  function resolveMaxWorkers (line 4) | function resolveMaxWorkers(): number | undefined {

FILE: vitest.setup.ts
  function setup (line 4) | async function setup() {
  function teardown (line 9) | async function teardown() {
Condensed preview — 644 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,134K chars).
[
  {
    "path": ".actrc",
    "chars": 48,
    "preview": "-P ubuntu-latest=catthehacker/ubuntu:act-latest\n"
  },
  {
    "path": ".changeset/README.md",
    "chars": 2243,
    "preview": "# Changesets\n\nThis directory is managed by [Changesets](https://github.com/changesets/changesets).\n\n## Quick Start\n\n```b"
  },
  {
    "path": ".changeset/config.json",
    "chars": 318,
    "preview": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config/schema.json\",\n  \"changelog\": [\n    \"@changesets/changelog-github\",\n"
  },
  {
    "path": ".changeset/fix-opencode-commands-directory.md",
    "chars": 164,
    "preview": "---\n\"@fission-ai/openspec\": patch\n---\n\nfix: OpenCode adapter now uses `.opencode/commands/` (plural) to match OpenCode's"
  },
  {
    "path": ".changeset/graceful-status-no-changes.md",
    "chars": 152,
    "preview": "---\n\"@fission-ai/openspec\": patch\n---\n\nfix: `openspec status` now exits gracefully when no changes exist instead of thro"
  },
  {
    "path": ".coderabbit.yaml",
    "chars": 281,
    "preview": "# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json\n# Minimal configuration for getting st"
  },
  {
    "path": ".devcontainer/README.md",
    "chars": 2529,
    "preview": "# Dev Container Setup\n\nThis directory contains the VS Code dev container configuration for OpenSpec development.\n\n## Wha"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "chars": 2033,
    "preview": "{\n  \"name\": \"OpenSpec Development\",\n  \"image\": \"mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm\",\n\n  // Ad"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 36,
    "preview": "# Default code ownership\n* @TabishB\n"
  },
  {
    "path": ".github/workflows/README.md",
    "chars": 365,
    "preview": "# Github Workflows\n\n## Testing CI Locally\n\nTest GitHub Actions workflows locally using [act](https://nektosact.com/):\n\n`"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 8666,
    "preview": "name: CI\n\non:\n  pull_request:\n    branches: [main]\n  push:\n    branches: [main]\n  workflow_dispatch:\n\npermissions:\n  con"
  },
  {
    "path": ".github/workflows/release-prepare.yml",
    "chars": 1866,
    "preview": "name: Release (prepare)\n\non:\n  push:\n    branches: [main]\n\npermissions:\n  contents: write\n  pull-requests: write\n  id-to"
  },
  {
    "path": ".gitignore",
    "chars": 2291,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
  },
  {
    "path": "AGENTS.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "CHANGELOG.md",
    "chars": 24088,
    "preview": "# @fission-ai/openspec\n\n## 1.2.0\n\n### Minor Changes\n\n- [#747](https://github.com/Fission-AI/OpenSpec/pull/747) [`1e94443"
  },
  {
    "path": "LICENSE",
    "chars": 1079,
    "preview": "MIT License\n\nCopyright (c) 2024 OpenSpec Contributors\n\nPermission is hereby granted, free of charge, to any person obtai"
  },
  {
    "path": "MAINTAINERS.md",
    "chars": 445,
    "preview": "# Maintainers\n\nPeople who maintain and guide OpenSpec.\n\n## Core Maintainers\n\n| Name | GitHub | Role |\n|------|--------|-"
  },
  {
    "path": "README.md",
    "chars": 7566,
    "preview": "<p align=\"center\">\n  <a href=\"https://github.com/Fission-AI/OpenSpec\">\n    <picture>\n      <source srcset=\"assets/opensp"
  },
  {
    "path": "README_OLD.md",
    "chars": 19139,
    "preview": "<p align=\"center\">\n  <a href=\"https://github.com/Fission-AI/OpenSpec\">\n    <picture>\n      <source srcset=\"assets/opensp"
  },
  {
    "path": "bin/openspec.js",
    "chars": 51,
    "preview": "#!/usr/bin/env node\n\nimport '../dist/cli/index.js';"
  },
  {
    "path": "build.js",
    "chars": 829,
    "preview": "#!/usr/bin/env node\n\nimport { execFileSync } from 'child_process';\nimport { existsSync, rmSync } from 'fs';\nimport { cre"
  },
  {
    "path": "docs/cli.md",
    "chars": 21503,
    "preview": "# CLI Reference\n\nThe OpenSpec CLI (`openspec`) provides terminal commands for project setup, validation, status inspecti"
  },
  {
    "path": "docs/commands.md",
    "chars": 19936,
    "preview": "# Commands\n\nThis is the reference for OpenSpec's slash commands. These commands are invoked in your AI coding assistant'"
  },
  {
    "path": "docs/concepts.md",
    "chars": 22348,
    "preview": "# Concepts\n\nThis guide explains the core ideas behind OpenSpec and how they fit together. For practical usage, see [Gett"
  },
  {
    "path": "docs/customization.md",
    "chars": 7924,
    "preview": "# Customization\n\nOpenSpec provides three levels of customization:\n\n| Level | What it does | Best for |\n|-------|--------"
  },
  {
    "path": "docs/getting-started.md",
    "chars": 6928,
    "preview": "# Getting Started\n\nThis guide explains how OpenSpec works after you've installed and initialized it. For installation in"
  },
  {
    "path": "docs/installation.md",
    "chars": 1215,
    "preview": "# Installation\n\n## Prerequisites\n\n- **Node.js 20.19.0 or higher** — Check your version: `node --version`\n\n## Package Man"
  },
  {
    "path": "docs/migration-guide.md",
    "chars": 17944,
    "preview": "# Migrating to OPSX\n\nThis guide helps you transition from the legacy OpenSpec workflow to OPSX. The migration is designe"
  },
  {
    "path": "docs/multi-language.md",
    "chars": 2071,
    "preview": "# Multi-Language Guide\n\nConfigure OpenSpec to generate artifacts in languages other than English.\n\n## Quick Setup\n\nAdd a"
  },
  {
    "path": "docs/opsx.md",
    "chars": 27333,
    "preview": "# OPSX Workflow\n\n> Feedback welcome on [Discord](https://discord.gg/YctCnvvshC).\n\n## What Is It?\n\nOPSX is now the standa"
  },
  {
    "path": "docs/supported-tools.md",
    "chars": 5363,
    "preview": "# Supported Tools\n\nOpenSpec works with many AI coding assistants. When you run `openspec init`, OpenSpec configures sele"
  },
  {
    "path": "docs/workflows.md",
    "chars": 12729,
    "preview": "# Workflows\n\nThis guide covers common workflow patterns for OpenSpec and when to use each one. For basic setup, see [Get"
  },
  {
    "path": "eslint.config.js",
    "chars": 1339,
    "preview": "import tseslint from 'typescript-eslint';\n\nexport default tseslint.config(\n  {\n    files: ['src/**/*.ts'],\n    extends: "
  },
  {
    "path": "flake.nix",
    "chars": 2954,
    "preview": "{\n  description = \"OpenSpec - AI-native system for spec-driven development\";\n\n  inputs = {\n    nixpkgs.url = \"github:Nix"
  },
  {
    "path": "openspec/changes/IMPLEMENTATION_ORDER.md",
    "chars": 2636,
    "preview": "# Implementation Order and Dependencies\n\n## Required Implementation Sequence\n\nThe following changes must be implemented "
  },
  {
    "path": "openspec/changes/add-artifact-regeneration-support/proposal.md",
    "chars": 3607,
    "preview": "# Add Artifact Regeneration Support\n\n## Problem\n\nCurrently, there is **no way to regenerate artifacts** in the OPSX work"
  },
  {
    "path": "openspec/changes/add-change-stacking-awareness/.openspec.yaml",
    "chars": 40,
    "preview": "schema: spec-driven\ncreated: 2026-02-21\n"
  },
  {
    "path": "openspec/changes/add-change-stacking-awareness/proposal.md",
    "chars": 4505,
    "preview": "## Why\n\nParallel changes often touch the same capabilities and `cli-init`/`cli-update` behavior, but today there is no m"
  },
  {
    "path": "openspec/changes/add-change-stacking-awareness/specs/change-creation/spec.md",
    "chars": 691,
    "preview": "## ADDED Requirements\n\n### Requirement: Stack Metadata Scaffolding\nChange creation workflows SHALL support optional depe"
  },
  {
    "path": "openspec/changes/add-change-stacking-awareness/specs/change-stacking-workflow/spec.md",
    "chars": 3557,
    "preview": "## ADDED Requirements\n\n### Requirement: Stack Metadata Model\nThe system SHALL support optional metadata on active change"
  },
  {
    "path": "openspec/changes/add-change-stacking-awareness/specs/cli-change/spec.md",
    "chars": 1428,
    "preview": "## ADDED Requirements\n\n### Requirement: Stack Planning Commands\nThe change CLI SHALL provide commands for dependency-awa"
  },
  {
    "path": "openspec/changes/add-change-stacking-awareness/specs/openspec-conventions/spec.md",
    "chars": 1880,
    "preview": "## ADDED Requirements\n\n### Requirement: Stack-Aware Change Planning Conventions\nOpenSpec conventions SHALL define option"
  },
  {
    "path": "openspec/changes/add-change-stacking-awareness/tasks.md",
    "chars": 2401,
    "preview": "## 1. Metadata Model\n\n- [ ] 1.1 Add optional stack metadata fields (`dependsOn`, `provides`, `requires`, `touches`, `par"
  },
  {
    "path": "openspec/changes/add-global-install-scope/.openspec.yaml",
    "chars": 40,
    "preview": "schema: spec-driven\ncreated: 2026-02-21\n"
  },
  {
    "path": "openspec/changes/add-global-install-scope/design.md",
    "chars": 6284,
    "preview": "## Context\n\nOpenSpec today assumes project-local installation for most generated artifacts, with Codex command prompts a"
  },
  {
    "path": "openspec/changes/add-global-install-scope/proposal.md",
    "chars": 4770,
    "preview": "## Why\n\nOpenSpec installation paths are currently inconsistent:\n\n- Most skills and commands are written to project-local"
  },
  {
    "path": "openspec/changes/add-global-install-scope/specs/ai-tool-paths/spec.md",
    "chars": 1827,
    "preview": "## MODIFIED Requirements\n\n### Requirement: AIToolOption skillsDir field\nThe `AIToolOption` interface SHALL include scope"
  },
  {
    "path": "openspec/changes/add-global-install-scope/specs/cli-config/spec.md",
    "chars": 945,
    "preview": "## ADDED Requirements\n\n### Requirement: Install scope configuration via profile flow\nThe config profile workflow SHALL a"
  },
  {
    "path": "openspec/changes/add-global-install-scope/specs/cli-init/spec.md",
    "chars": 1326,
    "preview": "## ADDED Requirements\n\n### Requirement: Init install scope selection\nThe init command SHALL support install scope select"
  },
  {
    "path": "openspec/changes/add-global-install-scope/specs/cli-update/spec.md",
    "chars": 1764,
    "preview": "## ADDED Requirements\n\n### Requirement: Update install scope selection\nThe update command SHALL support install scope se"
  },
  {
    "path": "openspec/changes/add-global-install-scope/specs/command-generation/spec.md",
    "chars": 1101,
    "preview": "## MODIFIED Requirements\n\n### Requirement: ToolCommandAdapter interface\nThe system SHALL provide install-context-aware c"
  },
  {
    "path": "openspec/changes/add-global-install-scope/specs/global-config/spec.md",
    "chars": 1074,
    "preview": "## ADDED Requirements\n\n### Requirement: Install scope field in global config\nThe global config schema SHALL include inst"
  },
  {
    "path": "openspec/changes/add-global-install-scope/specs/installation-scope/spec.md",
    "chars": 3465,
    "preview": "## Purpose\n\nDefine the install scope model for OpenSpec-generated skills and commands, including scope preference, effec"
  },
  {
    "path": "openspec/changes/add-global-install-scope/tasks.md",
    "chars": 3716,
    "preview": "## 1. Global Config + Validation\n\n- [ ] 1.1 Add `installScope` (`global` | `project`) to `GlobalConfig` with explicit `g"
  },
  {
    "path": "openspec/changes/add-qa-smoke-harness/.openspec.yaml",
    "chars": 40,
    "preview": "schema: spec-driven\ncreated: 2026-02-20\n"
  },
  {
    "path": "openspec/changes/add-qa-smoke-harness/proposal.md",
    "chars": 2353,
    "preview": "## Why\n\nWe need a faster, more reliable way to manually validate CLI behavior changes like profile/delivery sync, migrat"
  },
  {
    "path": "openspec/changes/add-qa-smoke-harness/specs/developer-qa-workflow/spec.md",
    "chars": 1972,
    "preview": "## ADDED Requirements\n\n### Requirement: Makefile QA Entry Point\n\nThe repository SHALL provide Makefile targets as the pr"
  },
  {
    "path": "openspec/changes/add-tool-command-surface-capabilities/.openspec.yaml",
    "chars": 40,
    "preview": "schema: spec-driven\ncreated: 2026-02-19\n"
  },
  {
    "path": "openspec/changes/add-tool-command-surface-capabilities/proposal.md",
    "chars": 5935,
    "preview": "## Why\n\nOpenSpec currently assumes command delivery maps directly to command adapters. That assumption does not hold for"
  },
  {
    "path": "openspec/changes/add-tool-command-surface-capabilities/specs/cli-init/spec.md",
    "chars": 7077,
    "preview": "## ADDED Requirements\n\n### Requirement: Command surface capability resolution\nThe init command SHALL resolve each select"
  },
  {
    "path": "openspec/changes/add-tool-command-surface-capabilities/specs/cli-update/spec.md",
    "chars": 2732,
    "preview": "## ADDED Requirements\n\n### Requirement: Delivery sync by command surface capability\nThe update command SHALL synchronize"
  },
  {
    "path": "openspec/changes/add-tool-command-surface-capabilities/tasks.md",
    "chars": 4110,
    "preview": "## 0. Stacking Coordination\n\n- [ ] 0.1 Rebase this change on latest `main` before implementation\n- [ ] 0.2 If `simplify-"
  },
  {
    "path": "openspec/changes/archive/2025-01-11-add-update-command/design.md",
    "chars": 3057,
    "preview": "# Technical Design\n\n## Architecture Decisions\n\n### Simplicity First\n- No version tracking - always update when commanded"
  },
  {
    "path": "openspec/changes/archive/2025-01-11-add-update-command/proposal.md",
    "chars": 1223,
    "preview": "# Add Update Command\n\n## Why\n\nUsers need a way to update their local OpenSpec instructions (README.md and CLAUDE.md) whe"
  },
  {
    "path": "openspec/changes/archive/2025-01-11-add-update-command/specs/cli-update/spec.md",
    "chars": 1929,
    "preview": "# Update Command Specification\n\n## Purpose\n\nAs a developer using OpenSpec, I want to update the OpenSpec instructions in"
  },
  {
    "path": "openspec/changes/archive/2025-01-11-add-update-command/tasks.md",
    "chars": 1211,
    "preview": "# Implementation Tasks\n\n## 1. Update Command Implementation\n- [x] 1.1 Create `src/core/update.ts` with `UpdateCommand` c"
  },
  {
    "path": "openspec/changes/archive/2025-01-13-add-list-command/proposal.md",
    "chars": 746,
    "preview": "# Add List Command to OpenSpec CLI\n\n## Why\n\nDevelopers need visibility into available changes and their status to unders"
  },
  {
    "path": "openspec/changes/archive/2025-01-13-add-list-command/specs/cli-list/spec.md",
    "chars": 1968,
    "preview": "# List Command Specification\n\n## Purpose\n\nThe `openspec list` command SHALL provide developers with a quick overview of "
  },
  {
    "path": "openspec/changes/archive/2025-01-13-add-list-command/tasks.md",
    "chars": 913,
    "preview": "# Implementation Tasks\n\n## 1. Core Implementation\n- [x] 1.1 Create `src/core/list.ts` with list logic\n  - [x] 1.1.1 Impl"
  },
  {
    "path": "openspec/changes/archive/2025-08-05-initialize-typescript-project/design.md",
    "chars": 2414,
    "preview": "# Technical Design\n\n## Technology Choices\n\n### TypeScript Configuration\n- **Strict mode**: Enable all strict type checki"
  },
  {
    "path": "openspec/changes/archive/2025-08-05-initialize-typescript-project/proposal.md",
    "chars": 806,
    "preview": "# Initialize TypeScript Project\n\n## Why\nThe OpenSpec project needs a proper TypeScript foundation to build the minimal C"
  },
  {
    "path": "openspec/changes/archive/2025-08-05-initialize-typescript-project/tasks.md",
    "chars": 976,
    "preview": "# Tasks\n\n## 1. Project Configuration\n- [x] 1.1 Create package.json with project metadata, scripts, and ESM configuration"
  },
  {
    "path": "openspec/changes/archive/2025-08-06-add-init-command/design.md",
    "chars": 2658,
    "preview": "# Technical Design for Init Command\n\n## Architecture Overview\n\nThe init command follows a modular architecture with clea"
  },
  {
    "path": "openspec/changes/archive/2025-08-06-add-init-command/proposal.md",
    "chars": 1423,
    "preview": "# Add Init Command for OpenSpec\n\n## Why\n\nProjects need a simple way to adopt OpenSpec conventions. Currently, users must"
  },
  {
    "path": "openspec/changes/archive/2025-08-06-add-init-command/specs/cli-init/spec.md",
    "chars": 4777,
    "preview": "# CLI Init Specification\n\n## Purpose\n\nThe `openspec init` command SHALL create a complete OpenSpec directory structure i"
  },
  {
    "path": "openspec/changes/archive/2025-08-06-add-init-command/tasks.md",
    "chars": 1982,
    "preview": "# Implementation Tasks for Init Command\n\n## 1. Core Infrastructure\n- [x] 1.1 Create src/utils/file-system.ts with direct"
  },
  {
    "path": "openspec/changes/archive/2025-08-06-adopt-future-state-storage/proposal.md",
    "chars": 1024,
    "preview": "# Adopt Future State Storage for OpenSpec Changes\n\n## Why\n\nThe current approach of storing spec changes as diff files (`"
  },
  {
    "path": "openspec/changes/archive/2025-08-06-adopt-future-state-storage/specs/openspec-conventions/spec.md",
    "chars": 4273,
    "preview": "# OpenSpec Conventions Specification\n\n## Purpose\n\nOpenSpec conventions SHALL define how system capabilities are document"
  },
  {
    "path": "openspec/changes/archive/2025-08-06-adopt-future-state-storage/tasks.md",
    "chars": 1522,
    "preview": "# Implementation Tasks\n\n## 1. Update Core Documentation\n- [x] 1.1 Update openspec/README.md section on \"Creating a Chang"
  },
  {
    "path": "openspec/changes/archive/2025-08-11-add-complexity-guidelines/proposal.md",
    "chars": 514,
    "preview": "# Add Complexity Management Guidelines\n\n## Why\nOpenSpec currently lacks guidance on managing complexity, leading to over"
  },
  {
    "path": "openspec/changes/archive/2025-08-11-add-complexity-guidelines/specs/openspec-docs/README.md",
    "chars": 16006,
    "preview": "# OpenSpec Instructions\n\nThis document provides instructions for AI coding assistants on how to use OpenSpec conventions"
  },
  {
    "path": "openspec/changes/archive/2025-08-11-add-complexity-guidelines/tasks.md",
    "chars": 354,
    "preview": "# Implementation Tasks\n\n## 1. Update OpenSpec README\n- [x] 1.1 Add \"Start Simple\" section after Core Principle\n- [x] 1.2"
  },
  {
    "path": "openspec/changes/archive/2025-08-13-add-archive-command/proposal.md",
    "chars": 849,
    "preview": "## Why\nNeed a command to archive completed changes to the archive folder with proper date prefixing, following OpenSpec "
  },
  {
    "path": "openspec/changes/archive/2025-08-13-add-archive-command/specs/cli-archive/spec.md",
    "chars": 4373,
    "preview": "# CLI Archive Command Specification\n\n## Purpose\nThe archive command moves completed changes from the active changes dire"
  },
  {
    "path": "openspec/changes/archive/2025-08-13-add-archive-command/tasks.md",
    "chars": 1759,
    "preview": "# Implementation Tasks\n\n## 1. Core Implementation\n- [ ] 1.1 Create `src/core/archive.ts` with ArchiveCommand class\n  - ["
  },
  {
    "path": "openspec/changes/archive/2025-08-13-add-diff-command/proposal.md",
    "chars": 685,
    "preview": "# Add Diff Command to OpenSpec CLI\n\n## Why\n\nDevelopers need to easily view differences between proposed spec changes and"
  },
  {
    "path": "openspec/changes/archive/2025-08-13-add-diff-command/specs/cli-diff/spec.md",
    "chars": 2081,
    "preview": "# CLI Diff Command Specification\n\n## Purpose\n\nThe `openspec diff` command provides developers with a visual comparison b"
  },
  {
    "path": "openspec/changes/archive/2025-08-13-add-diff-command/tasks.md",
    "chars": 829,
    "preview": "# Implementation Tasks\n\n## 1. Core Implementation\n- [x] 1.1 Create `src/core/diff.ts` with diff logic\n- [x] 1.2 Implemen"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-change-commands/design.md",
    "chars": 1930,
    "preview": "# Design: Change Commands\n\n## Architecture Decisions\n\n### Command Structure\nSimilar to spec commands, we use subcommands"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-change-commands/proposal.md",
    "chars": 750,
    "preview": "# Change: Add Change Commands with JSON Output\n\n## Why\n\nOpenSpec change proposals currently can only be viewed as markdo"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-change-commands/specs/cli-change/spec.md",
    "chars": 1670,
    "preview": "## ADDED Requirements\n\n### Requirement: Change Command\n\nThe system SHALL provide a `change` command with subcommands for"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-change-commands/specs/cli-list/spec.md",
    "chars": 351,
    "preview": "## MODIFIED Requirements\n\n### Requirement: Command Execution\n\nThe current `list` command behavior SHALL be preserved but"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-change-commands/tasks.md",
    "chars": 1711,
    "preview": "# Implementation Tasks (Phase 2: Builds on add-zod-validation)\n\n## 1. Command Implementation\n- [x] 1.1 Create src/comman"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-interactive-show-command/proposal.md",
    "chars": 1091,
    "preview": "## Why\n\nUsers frequently need to view changes and specs but must know in advance whether they're looking at a change or "
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-change/spec.md",
    "chars": 918,
    "preview": "# CLI Change Command Spec\n\n## ADDED Requirements\n\n### Requirement: Interactive show selection\n\nThe change show command S"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-show/spec.md",
    "chars": 3440,
    "preview": "# CLI Show Command Spec\n\n## ADDED Requirements\n\n### Requirement: Top-level show command\n\nThe CLI SHALL provide a top-lev"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-spec/spec.md",
    "chars": 904,
    "preview": "# CLI Spec Command Spec\n\n## ADDED Requirements\n\n### Requirement: Interactive spec show\n\nThe spec show command SHALL supp"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-interactive-show-command/tasks.md",
    "chars": 6941,
    "preview": "# Implementation Tasks — Add Interactive Show Command\n\n## Goals\n- Add a top-level `show` command with intelligent select"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/proposal.md",
    "chars": 1013,
    "preview": "## Why\nThe archive command currently forces users to either accept spec updates or cancel the entire archive operation. "
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/specs/cli-archive/spec.md",
    "chars": 7644,
    "preview": "# CLI Archive Command Specification\n\n## Purpose\nThe archive command moves completed changes from the active changes dire"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/tasks.md",
    "chars": 2944,
    "preview": "## 1. Update Archive Command Implementation\n- [x] 1.1 Add `skipSpecs` option to the archive command options interface\n- "
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-spec-commands/design.md",
    "chars": 1649,
    "preview": "# Design: Spec Commands\n\n## Architecture Decisions\n\n### Command Hierarchy\nWe chose a subcommand pattern (`spec show`, `s"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-spec-commands/proposal.md",
    "chars": 727,
    "preview": "# Change: Add Spec Commands with JSON Output\n\n## Why\n\nCurrently, OpenSpec specs can only be viewed as markdown files. Th"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-spec-commands/specs/cli-spec/spec.md",
    "chars": 1388,
    "preview": "## ADDED Requirements\n\n### Requirement: Spec Command\n\nThe system SHALL provide a `spec` command with subcommands for dis"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-spec-commands/tasks.md",
    "chars": 1200,
    "preview": "# Implementation Tasks (Phase 3: Builds on add-zod-validation and add-change-commands)\n\n## 1. Command Implementation\n- ["
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-zod-validation/design.md",
    "chars": 2763,
    "preview": "# Design: Zod Validation Framework\n\n## Architecture Decisions\n\n### Validation Levels\nThree-tier validation system:\n1. **"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-zod-validation/proposal.md",
    "chars": 991,
    "preview": "# Change: Add Zod Runtime Validation\n\n## Why\n\nWhile the spec and change commands can output JSON, they currently don't p"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-zod-validation/specs/cli-archive/spec.md",
    "chars": 583,
    "preview": "## ADDED Requirements\n\n### Requirement: Archive Validation\n\nThe archive command SHALL validate changes before applying t"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-zod-validation/specs/cli-diff/spec.md",
    "chars": 352,
    "preview": "## ADDED Requirements\n\n### Requirement: Diff Command Enhancement\n\nThe diff command SHALL validate change structure befor"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-add-zod-validation/tasks.md",
    "chars": 2909,
    "preview": "# Implementation Tasks (Foundation Phase)\n\n## 1. Core Schemas\n- [x] 1.1 Add zod dependency to package.json\n- [x] 1.2 Cre"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-delta-based-changes/proposal.md",
    "chars": 4975,
    "preview": "# Adopt Delta-Based Changes for Specifications\n\n## Why\n\nThe current approach of storing complete future states in change"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/cli-archive/spec.md",
    "chars": 1422,
    "preview": "# CLI Archive Command - Changes\n\n## MODIFIED Requirements\n\n### Requirement: Spec Update Process\n\nBefore moving the chang"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/cli-diff/spec.md",
    "chars": 1530,
    "preview": "# CLI Diff Command - Changes\n\n## REMOVED Requirements\n\n### Requirement: Display Format\n\nThe diff command SHALL display u"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/openspec-conventions/spec.md",
    "chars": 4049,
    "preview": "# OpenSpec Conventions - Changes\n\n## MODIFIED Requirements\n\n### Requirement: Header-Based Requirement Identification\n\nRe"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-delta-based-changes/tasks.md",
    "chars": 3471,
    "preview": "# Implementation Tasks\n\n## 1. Update Conventions\n- [x] 1.1 Update openspec-conventions spec with delta-based approach\n- "
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/design.md",
    "chars": 903,
    "preview": "# Design: Verb–Noun CLI Structure Adoption\n\n## Overview\nWe will make verb commands (`list`, `show`, `validate`, `diff`, "
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/proposal.md",
    "chars": 3185,
    "preview": "# Change: Adopt Verb–Noun CLI Structure (Deprecate Noun-Based Commands)\n\n## Why\n\nMost widely used CLIs (git, docker, kub"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/specs/cli-list/spec.md",
    "chars": 2040,
    "preview": "# Delta: CLI List Command\n\n## MODIFIED Requirements\n\n### Requirement: Command Execution\nThe command SHALL scan and analy"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/specs/openspec-conventions/spec.md",
    "chars": 1022,
    "preview": "# Delta: OpenSpec Conventions — Verb–Noun CLI Design\n\n## ADDED Requirements\n\n### Requirement: Verb–Noun CLI Command Stru"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/tasks.md",
    "chars": 1570,
    "preview": "# Implementation Tasks\n\n## 1. CLI Behavior and Help\n- [x] 1.1 Un-deprecate top-level `openspec list`; mark `change list`"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/proposal.md",
    "chars": 1062,
    "preview": "## Why\n\nCurrently, users must validate changes and specs individually by specifying each ID. This creates friction when:"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-change/spec.md",
    "chars": 870,
    "preview": "# CLI Change Command Spec\n\n## ADDED Requirements\n\n### Requirement: Interactive validation selection\n\nThe change validate"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-spec/spec.md",
    "chars": 905,
    "preview": "# CLI Spec Command Spec\n\n## ADDED Requirements\n\n### Requirement: Interactive spec validation\n\nThe spec validate command "
  },
  {
    "path": "openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-validate/spec.md",
    "chars": 6245,
    "preview": "# CLI Validate Command Spec\n\n## ADDED Requirements\n\n### Requirement: Top-level validate command\n\nThe CLI SHALL provide a"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/tasks.md",
    "chars": 5426,
    "preview": "# Implementation Tasks\n\n## 1. Change Command: Interactive Validation Selection\n- [x] 1.1 Add `--no-interactive` flag to "
  },
  {
    "path": "openspec/changes/archive/2025-08-19-fix-update-tool-selection/proposal.md",
    "chars": 1841,
    "preview": "# Fix Update Command Tool Selection\n\n## Problem\n\nThe `openspec update` command currently forces the creation/update of C"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-fix-update-tool-selection/specs/cli-update/spec.md",
    "chars": 888,
    "preview": "## ADDED Requirements\n\n### Requirement: Tool-Agnostic Updates\n\nThe update command SHALL update only existing AI tool con"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-fix-update-tool-selection/tasks.md",
    "chars": 872,
    "preview": "# Implementation Tasks\n\n## 1. Update Update Command\n- [x] Remove hardcoded CLAUDE.md update from `src/core/update.ts`\n- "
  },
  {
    "path": "openspec/changes/archive/2025-08-19-improve-validate-error-messages/proposal.md",
    "chars": 1513,
    "preview": "# improve-validate-error-messages\n\n## Why\n\nDevelopers struggle to resolve validation failures because current errors lac"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-improve-validate-error-messages/specs/cli-validate/spec.md",
    "chars": 2711,
    "preview": "# Validate Command\n\n## ADDED Requirements\n\n### Requirement: Validation SHALL provide actionable remediation steps\nValida"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-improve-validate-error-messages/tasks.md",
    "chars": 898,
    "preview": "## 1. Enhance validation messages\n- [x] 1.1 Add remediation guidance for \"No deltas found\"\n- [x] 1.2 Include file path a"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-structured-spec-format/proposal.md",
    "chars": 1640,
    "preview": "## Why\n\nOpenSpec specifications lack a consistent structure that makes sections visually identifiable and programmatical"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-structured-spec-format/specs/openspec-conventions/spec.md",
    "chars": 7245,
    "preview": "# OpenSpec Conventions Specification\n\n## ADDED Requirements\n\n### Requirement: Structured Format Adoption\n\nBehavioral spe"
  },
  {
    "path": "openspec/changes/archive/2025-08-19-structured-spec-format/tasks.md",
    "chars": 909,
    "preview": "## 1. Update OpenSpec Conventions Spec\n\n- [x] 1.1 Add \"Specification Format\" section to openspec-conventions\n- [x] 1.2 D"
  },
  {
    "path": "openspec/changes/archive/2025-09-12-add-view-dashboard-command/proposal.md",
    "chars": 1476,
    "preview": "# Change: Add View Dashboard Command\n\n## Why\n\nUsers need a quick, at-a-glance overview of their OpenSpec project status "
  },
  {
    "path": "openspec/changes/archive/2025-09-12-add-view-dashboard-command/specs/cli-view/spec.md",
    "chars": 3455,
    "preview": "# CLI View Command - Changes\n\n## ADDED Requirements\n\n### Requirement: Dashboard Display\n\nThe system SHALL provide a `vie"
  },
  {
    "path": "openspec/changes/archive/2025-09-12-add-view-dashboard-command/tasks.md",
    "chars": 1866,
    "preview": "# Implementation Tasks\n\n## Design Phase\n- [x] Research existing list command implementation\n- [x] Design dashboard layou"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-agents-md-config/proposal.md",
    "chars": 2447,
    "preview": "# Add AGENTS.md Standard Support To Init/Update\n\n## Summary\n- Teach `openspec init` to manage a root-level `AGENTS.md` f"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-agents-md-config/specs/cli-init/spec.md",
    "chars": 2876,
    "preview": "## MODIFIED Requirements\n### Requirement: AI Tool Configuration\nThe command SHALL configure AI coding assistants with Op"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-agents-md-config/specs/cli-update/spec.md",
    "chars": 2058,
    "preview": "## MODIFIED Requirements\n### Requirement: Update Behavior\nThe update command SHALL update OpenSpec instruction files to "
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-agents-md-config/tasks.md",
    "chars": 1131,
    "preview": "# Implementation Tasks\n\n## 1. Extend Init Workflow\n- [x] 1.1 Add an \"AGENTS.md standard\" option to the `openspec init` t"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-multi-agent-init/proposal.md",
    "chars": 2683,
    "preview": "# Allow Additional AI Tool Initialization After Setup\n\n## Summary\n- Let `openspec init` configure new AI coding tools fo"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-multi-agent-init/specs/cli-init/spec.md",
    "chars": 2839,
    "preview": "## MODIFIED Requirements\n### Requirement: Safety Checks\nThe command SHALL perform safety checks to prevent overwriting e"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-multi-agent-init/tasks.md",
    "chars": 914,
    "preview": "# Implementation Tasks\n\n## 1. Extend Init Guard\n- [x] 1.1 Detect existing OpenSpec structures at the start of `openspec "
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-slash-command-support/proposal.md",
    "chars": 7277,
    "preview": "# Add Slash Command Support for Coding Agents\n\n## Summary\n- Enable OpenSpec to generate and update custom slash commands"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-slash-command-support/specs/cli-init/spec.md",
    "chars": 1457,
    "preview": "## ADDED Requirements\n### Requirement: Slash Command Configuration\nThe init command SHALL generate slash command files f"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-slash-command-support/specs/cli-update/spec.md",
    "chars": 1182,
    "preview": "## ADDED Requirements\n### Requirement: Slash Command Updates\nThe update command SHALL refresh existing slash command fil"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-add-slash-command-support/tasks.md",
    "chars": 1163,
    "preview": "# Implementation Tasks\n\n## 1. Templates and Configurators\n- [x] 1.1 Create shared templates for the Proposal, Apply, and"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-improve-cli-e2e-plan/proposal.md",
    "chars": 2337,
    "preview": "## Why\nRecent cross-shell regressions for `openspec` commands revealed that our existing unit/integration tests do not e"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-improve-cli-e2e-plan/tasks.md",
    "chars": 955,
    "preview": "## 1. Phase 1 – Stabilize Local Spawn Coverage\n- [x] 1.1 Add `test/helpers/run-cli.ts` that ensures the build runs once "
  },
  {
    "path": "openspec/changes/archive/2025-09-29-improve-deterministic-tests/proposal.md",
    "chars": 3128,
    "preview": "# Change: Improve Deterministic Tests (Isolate From Repo State)\n\n## Problem\n\nSome unit tests (e.g., ChangeCommand.show/v"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-improve-deterministic-tests/tasks.md",
    "chars": 1001,
    "preview": "# Implementation Tasks\n\n## 1. Test Isolation\n- [x] 1.1 Create temp fixture roots per suite (openspec/changes, openspec/s"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-improve-init-onboarding/proposal.md",
    "chars": 1047,
    "preview": "## Why\nThe current `openspec init` flow assumes a single assistant selection and stops once an OpenSpec structure alread"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-improve-init-onboarding/specs/cli-init/spec.md",
    "chars": 4120,
    "preview": "## MODIFIED Requirements\n### Requirement: AI Tool Configuration\n\nThe command SHALL configure AI coding assistants with O"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-improve-init-onboarding/tasks.md",
    "chars": 725,
    "preview": "## 1. Planning & Spec Updates\n- [x] 1.1 Confirm overlap with `add-multi-agent-init` and coordinate extend-mode flow\n- [x"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-remove-diff-command/proposal.md",
    "chars": 3157,
    "preview": "# Remove Diff Command\n\n## Problem\n\nThe `openspec diff` command adds unnecessary complexity to the OpenSpec CLI for sever"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-remove-diff-command/tasks.md",
    "chars": 1359,
    "preview": "# Remove Diff Command - Tasks\n\n## 1. Remove Core Implementation\n- [x] Delete `/src/core/diff.ts`\n- [x] Remove DiffComman"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/proposal.md",
    "chars": 1428,
    "preview": "# Change: Sort Active Changes by Progress\n\n## Problem\n- The dashboard currently lists active changes in filesystem disco"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/specs/cli-view/spec.md",
    "chars": 527,
    "preview": "## MODIFIED Requirements\n### Requirement: Active Changes Display\nThe dashboard SHALL show active changes with visual pro"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/tasks.md",
    "chars": 368,
    "preview": "# Implementation Tasks\n\n## 1. Dashboard Sorting Logic\n- [x] 1.1 Update the Active Changes rendering to sort by completio"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-agent-file-name/proposal.md",
    "chars": 1110,
    "preview": "# Update Agent Instruction File Name\n\n## Problem\nThe agent instructions live in `openspec/README.md`, which clashes with"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-agent-file-name/specs/cli-init/spec.md",
    "chars": 1453,
    "preview": "## MODIFIED Requirements\n\n### Requirement: Directory Creation\nThe command SHALL create the complete OpenSpec directory s"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-agent-file-name/specs/cli-update/spec.md",
    "chars": 852,
    "preview": "## MODIFIED Requirements\n\n### Requirement: Update Behavior\nThe update command SHALL update OpenSpec instruction files to"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-agent-file-name/specs/openspec-conventions/spec.md",
    "chars": 1153,
    "preview": "## MODIFIED Requirements\n\n### Requirement: Project Structure\nAn OpenSpec project SHALL maintain a consistent directory s"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-agent-file-name/tasks.md",
    "chars": 804,
    "preview": "# Update Agent Instruction File Name - Tasks\n\n## 1. Rename Instruction File\n- [x] Rename `openspec/README.md` to `opensp"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-agent-instructions/design.md",
    "chars": 5241,
    "preview": "# Design: Agent Instructions Update\n\n## Approach\n\n### Information Architecture\n- **Front-load critical information** - T"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-agent-instructions/proposal.md",
    "chars": 5870,
    "preview": "# Update OpenSpec Agent Instructions\n\n## Why\n\nThe current OpenSpec agent instructions need updates to follow best practi"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-agent-instructions/tasks.md",
    "chars": 3581,
    "preview": "# Implementation Tasks\n\n## 1. Restructure OpenSpec README.md\n- [x] 1.1 Front-load the three-stage workflow as primary co"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/proposal.md",
    "chars": 1711,
    "preview": "# Update Markdown Parser CRLF Handling\n\n## Problem\nWindows users report that `openspec validate` raises “Change must hav"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/specs/cli-validate/spec.md",
    "chars": 516,
    "preview": "## ADDED Requirements\n### Requirement: Parser SHALL handle cross-platform line endings\nThe markdown parser SHALL correct"
  },
  {
    "path": "openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/tasks.md",
    "chars": 737,
    "preview": "## 1. Guard the regression\n- [x] 1.1 Add a unit test that feeds a CRLF change document into `MarkdownParser.parseChange`"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-codex-slash-command-support/proposal.md",
    "chars": 3515,
    "preview": "## Why\n- Codex (the VS Code extension formerly known as Codeium Chat) exposes \"slash commands\" by reading Markdown promp"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-codex-slash-command-support/specs/cli-init/spec.md",
    "chars": 4198,
    "preview": "## MODIFIED Requirements\n### Requirement: AI Tool Configuration\nThe command SHALL configure AI coding assistants with Op"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-codex-slash-command-support/specs/cli-update/spec.md",
    "chars": 2482,
    "preview": "## MODIFIED Requirements\n### Requirement: Slash Command Updates\nThe update command SHALL refresh existing slash command "
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-codex-slash-command-support/tasks.md",
    "chars": 1939,
    "preview": "## 1. CLI integration\n- [x] 1.1 Add Codex to the init tool picker with display text that clarifies prompts live in the g"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-github-copilot-prompts/proposal.md",
    "chars": 3282,
    "preview": "## Why\n- GitHub Copilot supports custom slash commands through markdown files in `.github/prompts/<name>.prompt.md`. Eac"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-github-copilot-prompts/specs/cli-init/spec.md",
    "chars": 3683,
    "preview": "## MODIFIED Requirements\n\n### Requirement: Slash Command Configuration\nThe init command SHALL generate slash command fil"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-github-copilot-prompts/specs/cli-update/spec.md",
    "chars": 2908,
    "preview": "## MODIFIED Requirements\n\n### Requirement: Slash Command Updates\nThe update command SHALL refresh existing slash command"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-github-copilot-prompts/tasks.md",
    "chars": 1935,
    "preview": "## Implementation Tasks\n\n- [x] Create `src/core/configurators/slash/github-copilot.ts` implementing `SlashCommandConfigu"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-kilocode-workflows/proposal.md",
    "chars": 1970,
    "preview": "## Why\n- Kilo Code executes \\\"slash commands\\\" by loading markdown workflows from `.kilocode/workflows/` (or the global "
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-kilocode-workflows/specs/cli-init/spec.md",
    "chars": 3027,
    "preview": "## MODIFIED Requirements\n### Requirement: AI Tool Configuration\nThe command SHALL configure AI coding assistants with Op"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-kilocode-workflows/specs/cli-update/spec.md",
    "chars": 1512,
    "preview": "## MODIFIED Requirements\n### Requirement: Slash Command Updates\nThe update command SHALL refresh existing slash command "
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-kilocode-workflows/tasks.md",
    "chars": 1006,
    "preview": "## 1. CLI wiring\n- [x] 1.1 Add Kilo Code to the selectable AI tools in `openspec init`, including \"already configured\" d"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-non-interactive-init-options/proposal.md",
    "chars": 894,
    "preview": "## Why\nThe current `openspec init` command requires interactive prompts, preventing automation in CI/CD pipelines and sc"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-non-interactive-init-options/specs/cli-init/spec.md",
    "chars": 2070,
    "preview": "# Delta for CLI Init Specification\n\n## ADDED Requirements\n### Requirement: Non-Interactive Mode\nThe command SHALL suppor"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-non-interactive-init-options/tasks.md",
    "chars": 1173,
    "preview": "## 1. CLI Option Registration\n- [x] 1.1 Replace the multiple flag design with a single `--tools <value>` option supporti"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-windsurf-workflows/proposal.md",
    "chars": 2104,
    "preview": "## Why\n- Windsurf exposes \"Workflows\" as the vehicle for slash-like automation: saved Markdown files under `.windsurf/wo"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-windsurf-workflows/specs/cli-init/spec.md",
    "chars": 2942,
    "preview": "## MODIFIED Requirements\n### Requirement: AI Tool Configuration\nThe command SHALL configure AI coding assistants with Op"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-windsurf-workflows/specs/cli-update/spec.md",
    "chars": 1511,
    "preview": "## MODIFIED Requirements\n### Requirement: Slash Command Updates\nThe update command SHALL refresh existing slash command "
  },
  {
    "path": "openspec/changes/archive/2025-10-14-add-windsurf-workflows/tasks.md",
    "chars": 1250,
    "preview": "## 1. CLI wiring\n- [x] 1.1 Add Windsurf to the selectable AI tools in `openspec init`, including \"already configured\" de"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-enhance-validation-error-messages/proposal.md",
    "chars": 957,
    "preview": "## Why\nValidation errors like \"no deltas found\" or \"missing requirement text\" do not tell agents how to recover, leading"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-enhance-validation-error-messages/specs/cli-validate/spec.md",
    "chars": 2403,
    "preview": "## MODIFIED Requirements\n### Requirement: Validation SHALL provide actionable remediation steps\nValidation output SHALL "
  },
  {
    "path": "openspec/changes/archive/2025-10-14-enhance-validation-error-messages/tasks.md",
    "chars": 792,
    "preview": "## 1. Messaging enhancements\n- [x] 1.1 Inventory current validation failures and map each to the desired message improve"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/proposal.md",
    "chars": 940,
    "preview": "## Why\nAgents fumble proposal formatting because the essential Markdown templates and formatting rules are buried mid-do"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/specs/docs-agent-instructions/spec.md",
    "chars": 2304,
    "preview": "## ADDED Requirements\n### Requirement: Quick Reference Placement\nThe AI instructions SHALL begin with a quick-reference "
  },
  {
    "path": "openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/tasks.md",
    "chars": 723,
    "preview": "## 1. Instruction redesign\n- [x] 1.1 Draft a quick-reference section that surfaces file templates and formatting rules a"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-slim-root-agents-file/proposal.md",
    "chars": 1098,
    "preview": "## Why\nThe project root currently receives a full copy of the OpenSpec agent instructions, duplicating the content that "
  },
  {
    "path": "openspec/changes/archive/2025-10-14-slim-root-agents-file/tasks.md",
    "chars": 815,
    "preview": "## 1. Templates\n- [x] 1.1 Add a shared stub template that renders the root agent instructions hand-off message.\n- [x] 1."
  },
  {
    "path": "openspec/changes/archive/2025-10-14-update-cli-init-enter-selection/proposal.md",
    "chars": 866,
    "preview": "## Why\n- Users frequently scroll to a tool and press Enter without toggling it, resulting in no configuration changes.\n-"
  },
  {
    "path": "openspec/changes/archive/2025-10-14-update-cli-init-enter-selection/specs/cli-init/spec.md",
    "chars": 918,
    "preview": "## MODIFIED Requirements\n### Requirement: Interactive Mode\nThe command SHALL provide an interactive menu for AI tool sel"
  }
]

// ... and 444 more files (download for full content)

About this extraction

This page contains the full source code of the Fission-AI/OpenSpec GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 644 files (2.9 MB), approximately 788.0k tokens, and a symbol index with 737 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!