mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-14 05:19:53 +08:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4772d71b4e | ||
|
|
d59a0b347a | ||
|
|
04dc6deb5d |
@@ -1,2 +0,0 @@
|
||||
---
|
||||
---
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
"@fission-ai/openspec": patch
|
||||
---
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **CLI path visibility**: OpenSpec now documents editor and agent PATH mismatches, warns during global installs when the detected CLI bin directory is not on PATH, and generates workflow skills with guidance for resolving `openspec` through `OPENSPEC_BIN` or an absolute path.
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
"@fission-ai/openspec": minor
|
||||
---
|
||||
|
||||
### New Features
|
||||
|
||||
- **Kimi CLI support** — OpenSpec can now initialize Kimi CLI as a supported skills-only tool using `.kimi/skills/`
|
||||
|
||||
### Other
|
||||
|
||||
- Added Kimi-specific docs and init coverage aligned with skill-based `/skill:openspec-*` usage
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
"@fission-ai/openspec": patch
|
||||
---
|
||||
|
||||
### 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,7 +0,0 @@
|
||||
---
|
||||
"@fission-ai/openspec": minor
|
||||
---
|
||||
|
||||
### New Features
|
||||
|
||||
- Include the sync workflow in the default core profile so new installs generate `/opsx:sync` skills and commands by default.
|
||||
@@ -3,8 +3,6 @@ name: CI
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
merge_group:
|
||||
branches: [main]
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
@@ -44,7 +42,7 @@ jobs:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -83,7 +81,7 @@ jobs:
|
||||
name: Test (${{ matrix.label }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 15
|
||||
if: github.event_name == 'push'
|
||||
if: github.event_name != 'pull_request'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -244,7 +242,7 @@ jobs:
|
||||
validate-changesets:
|
||||
name: Validate Changesets
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -277,7 +275,7 @@ jobs:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_pr, lint, nix-flake-validate]
|
||||
if: always() && (github.event_name == 'pull_request' || github.event_name == 'merge_group')
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
@@ -303,7 +301,7 @@ jobs:
|
||||
name: All checks passed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_matrix, lint, nix-flake-validate]
|
||||
if: always() && github.event_name == 'push'
|
||||
if: always() && github.event_name != 'pull_request'
|
||||
steps:
|
||||
- name: Verify all checks passed
|
||||
run: |
|
||||
|
||||
-10
@@ -149,13 +149,3 @@ CLAUDE.md
|
||||
# Pnpm
|
||||
.pnpm-store/
|
||||
result
|
||||
|
||||
# OpenCode
|
||||
.opencode/
|
||||
opencode.json
|
||||
|
||||
# Codex
|
||||
.codex/
|
||||
|
||||
# Bob
|
||||
.bob/
|
||||
|
||||
@@ -1,91 +1,5 @@
|
||||
# @fission-ai/openspec
|
||||
|
||||
## 1.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#995](https://github.com/Fission-AI/OpenSpec/pull/995) [`d1f3861`](https://github.com/Fission-AI/OpenSpec/commit/d1f3861d9ec694cc924b042b5da01963dcf93137) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- **Canonical artifact paths** — Workflow artifact paths are now resolved via the native `realpath`, so symlinks and case-insensitive filesystems no longer cause path mismatches during apply and archive.
|
||||
- **Glob apply instructions** — Apply instructions with glob artifact outputs now resolve correctly, and literal artifact outputs are enforced to be file paths.
|
||||
- **Hidden main spec requirements** — Requirements nested inside fenced code blocks or otherwise hidden in main specs are now detected during validation.
|
||||
- **Clean `--json` output** — Spinner progress text no longer leaks into stderr when `--json` is passed, so AI agents that combine stdout and stderr can parse the JSON reliably.
|
||||
- **Silent telemetry in firewalled environments** — PostHog network errors are now swallowed with a 1s timeout and retries/remote config disabled, so OpenSpec no longer surfaces `PostHogFetchNetworkError` in locked-down networks. Telemetry opt-out is documented earlier in the README, installation guide, and CLI reference.
|
||||
|
||||
## 1.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#952](https://github.com/Fission-AI/OpenSpec/pull/952) [`cce787e`](https://github.com/Fission-AI/OpenSpec/commit/cce787ec4083da2b27781f6786f5ce0002909a7b) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
|
||||
|
||||
- **Junie support** — Added tool and command generation for JetBrains Junie
|
||||
- **Lingma IDE support** — Added configuration support for Lingma IDE
|
||||
- **ForgeCode support** — Added tool support for ForgeCode
|
||||
- **IBM Bob support** — Added support for IBM Bob coding assistant
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **Shell completions opt-in** — Completion install is now opt-in, fixing PowerShell encoding corruption
|
||||
- **Copilot auto-detection** — Prevented false GitHub Copilot detection from a bare `.github/` directory
|
||||
- **pi.dev command generation** — Fixed command reference transforms and template argument passing
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#760](https://github.com/Fission-AI/OpenSpec/pull/760) [`61eb999`](https://github.com/Fission-AI/OpenSpec/commit/61eb999f7c6c0fc98d2e7f3678756fce6a3f4378) Thanks [@fsilvaortiz](https://github.com/fsilvaortiz)! - fix: OpenCode adapter now uses `.opencode/commands/` (plural) to match OpenCode's official directory convention. Fixes #748.
|
||||
|
||||
- [#759](https://github.com/Fission-AI/OpenSpec/pull/759) [`afdca0d`](https://github.com/Fission-AI/OpenSpec/commit/afdca0d5dab1aa109cfd8848b2512333ccad60c3) Thanks [@fsilvaortiz](https://github.com/fsilvaortiz)! - fix: `openspec status` now exits gracefully when no changes exist instead of throwing a fatal error. Fixes #714.
|
||||
|
||||
## 1.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#747](https://github.com/Fission-AI/OpenSpec/pull/747) [`1e94443`](https://github.com/Fission-AI/OpenSpec/commit/1e94443a3551b228eecbc89e95d96d3b9600a192) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
|
||||
|
||||
- **Profile system** — Choose between `core` (4 essential workflows) and `custom` (pick any subset) profiles to control which skills get installed. Manage profiles with the new `openspec config profile` command
|
||||
- **Propose workflow** — New one-step workflow creates a complete change proposal with design, specs, and tasks from a single request — no need to run `new` then `ff` separately
|
||||
- **AI tool auto-detection** — `openspec init` now scans your project for existing tool directories (`.claude/`, `.cursor/`, etc.) and pre-selects detected tools
|
||||
- **Pi (pi.dev) support** — Pi coding agent is now a supported tool with prompt and skill generation
|
||||
- **Kiro support** — AWS Kiro IDE is now a supported tool with prompt and skill generation
|
||||
- **Sync prunes deselected workflows** — `openspec update` now removes command files and skill directories for workflows you've deselected, keeping your project clean
|
||||
- **Config drift warning** — `openspec config list` warns when global config is out of sync with the current project
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed onboard preflight giving a false "not initialized" error on freshly initialized projects
|
||||
- Fixed archive workflow stopping mid-way when syncing — it now properly resumes after sync completes
|
||||
- Added Windows PowerShell alternatives for onboard shell commands
|
||||
|
||||
## 1.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#627](https://github.com/Fission-AI/OpenSpec/pull/627) [`afb73cf`](https://github.com/Fission-AI/OpenSpec/commit/afb73cf9ec59c6f8b26d0c538c0218c203ba3c56) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- **OpenCode command references** — Command references in generated files now use the correct `/opsx-` hyphen format instead of `/opsx:` colon format, ensuring commands work properly in OpenCode
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#625](https://github.com/Fission-AI/OpenSpec/pull/625) [`53081fb`](https://github.com/Fission-AI/OpenSpec/commit/53081fb2a26ec66d2950ae0474b9a56cbc5b5a76) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
|
||||
|
||||
- **Codex global path support** — Codex adapter now resolves global paths correctly, fixing workflow file generation when run outside the project directory (#622)
|
||||
- **Archive operations on cross-device or restricted paths** — Archive now falls back to copy+remove when rename fails with EPERM or EXDEV errors, fixing failures on networked/external drives (#605)
|
||||
- **Slash command hints in workflow messages** — Workflow completion messages now display helpful slash command hints for next steps (#603)
|
||||
- **Windsurf workflow file path** — Updated Windsurf adapter to use the correct `workflows` directory instead of the legacy `commands` path (#610)
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#550](https://github.com/Fission-AI/OpenSpec/pull/550) [`86d2e04`](https://github.com/Fission-AI/OpenSpec/commit/86d2e04cae76a999dbd1b4571f52fa720036be0c) Thanks [@jerome-benoit](https://github.com/jerome-benoit)! - ### Improvements
|
||||
|
||||
- **Nix flake maintenance** — Version now read dynamically from package.json, reducing manual sync issues
|
||||
- **Nix build optimization** — Source filtering excludes node_modules and artifacts, improving build times
|
||||
- **update-flake.sh script** — Detects when hash is already correct, skipping unnecessary rebuilds
|
||||
|
||||
### Other
|
||||
|
||||
- Updated Nix CI actions to latest versions (nix-installer v21, magic-nix-cache v13)
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -36,20 +36,27 @@ Our philosophy:
|
||||
> [!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)
|
||||
> Run `/opsx:onboard` to get started. → [Learn more here](docs/opsx.md)
|
||||
|
||||
<p align="center">
|
||||
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
|
||||
</p>
|
||||
|
||||
<!-- TODO: Add GIF demo of /opsx:propose → /opsx:archive workflow -->
|
||||
### Teams
|
||||
|
||||
Using OpenSpec in a team? [Email here](mailto:teams@openspec.dev) for access to our Slack channel.
|
||||
|
||||
<!-- TODO: Add GIF demo of /opsx:new → /opsx:archive workflow -->
|
||||
|
||||
## See it in action
|
||||
|
||||
```text
|
||||
You: /opsx:propose add-dark-mode
|
||||
You: /opsx:new add-dark-mode
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
✓ proposal.md — why we're doing this, what's changing
|
||||
Ready to create: proposal
|
||||
|
||||
You: /opsx:ff # "fast-forward" - generate all planning docs
|
||||
AI: ✓ proposal.md — why we're doing this, what's changing
|
||||
✓ specs/ — requirements and scenarios
|
||||
✓ design.md — technical approach
|
||||
✓ tasks.md — implementation checklist
|
||||
@@ -94,12 +101,10 @@ 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:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`.
|
||||
Now tell your AI: `/opsx:new <what-you-want-to-build>`
|
||||
|
||||
> [!NOTE]
|
||||
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 25+ tools and growing.
|
||||
> 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).
|
||||
|
||||
@@ -115,13 +120,6 @@ If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/
|
||||
→ **[Customization](docs/customization.md)**: make it yours
|
||||
|
||||
|
||||
## Community schemas
|
||||
|
||||
Third-party schema bundles distributed via standalone repositories — these provide opinionated workflows that integrate OpenSpec with other tools, similar to how [github/spec-kit's community extension catalog](https://github.com/github/spec-kit/tree/main/extensions) handles tool integrations.
|
||||
|
||||
→ **[Browse the catalog](docs/customization.md#community-schemas)** in the customization docs.
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -1,470 +0,0 @@
|
||||
# Workspace Reimplementation Direction
|
||||
|
||||
Date: 2026-04-30
|
||||
|
||||
Fresh-agent entry point: read `WORKSPACE_REIMPLEMENTATION_START_HERE.md` first, then return to this document for the full product direction.
|
||||
|
||||
This document captures the intended direction for reimplementing OpenSpec workspace support from scratch, based on what we learned from the workspace POC.
|
||||
|
||||
The reimplementation should be ordered around the path a real user takes through OpenSpec:
|
||||
|
||||
```text
|
||||
set up workspace
|
||||
-> link repos or folders
|
||||
-> open workspace
|
||||
-> explore across repos or folders
|
||||
-> create proposal
|
||||
-> apply one repo slice
|
||||
-> verify
|
||||
-> archive
|
||||
```
|
||||
|
||||
The goal is not to rebuild every POC mechanism. The goal is to get one user-facing capability working at a time, in the same order a user would naturally create, implement, verify, and archive a change.
|
||||
|
||||
## North Star
|
||||
|
||||
A user should think:
|
||||
|
||||
```text
|
||||
I have a multi-repo product goal.
|
||||
I set up an OpenSpec workspace.
|
||||
I open it with my agent.
|
||||
The agent can see the linked repos or folders.
|
||||
We explore until the scope is clear.
|
||||
Then we create a proposal.
|
||||
Then we implement one repo slice at a time.
|
||||
```
|
||||
|
||||
They should not think:
|
||||
|
||||
```text
|
||||
I need to create a change so repos become visible.
|
||||
I need to materialize repo-local artifacts.
|
||||
I need to understand implementation-specific workspace machinery.
|
||||
I need to manage target metadata separately from proposal files.
|
||||
```
|
||||
|
||||
The core product rule is:
|
||||
|
||||
```text
|
||||
Workspace visibility is not change commitment.
|
||||
```
|
||||
|
||||
Linked repos or folders are planning context. Creating a change is a planning commitment. Applying a change is an implementation workflow.
|
||||
|
||||
## Build Order
|
||||
|
||||
### 1. Workspace Setup And Links
|
||||
|
||||
First make workspace setup boring and solid.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Create a planning home and link the repos or folders OpenSpec should know about.
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec workspace setup
|
||||
openspec workspace setup --no-interactive --name platform --link /path/to/api --link web=/path/to/web
|
||||
openspec workspace list
|
||||
openspec workspace ls
|
||||
openspec workspace link /path/to/api
|
||||
openspec workspace link api-service /path/to/api
|
||||
openspec workspace relink api /new/path/to/api
|
||||
openspec workspace doctor
|
||||
```
|
||||
|
||||
Expected outcome:
|
||||
|
||||
```text
|
||||
workspace-folder/
|
||||
changes/
|
||||
.openspec-workspace/
|
||||
workspace.yaml
|
||||
local.yaml
|
||||
```
|
||||
|
||||
Product decisions:
|
||||
|
||||
- Use `.openspec-workspace/`, not `.openspec/`, for workspace metadata.
|
||||
- Keep `changes/` visible in the workspace folder.
|
||||
- Keep setup as the only public creation path for the first release; do not expose `workspace create`.
|
||||
- Use `workspace link` and `workspace relink`, not POC-era `add-repo` or `update-repo`.
|
||||
- Allow linked repos or folders without repo-local `openspec/` state.
|
||||
- Keep stable link names in shared workspace state and local paths in machine-local state.
|
||||
- Make `doctor` show link names, resolved paths, repo-local specs paths when present, and suggested fixes.
|
||||
|
||||
Defer:
|
||||
|
||||
- Agent launch and workspace open behavior.
|
||||
- Preferred-agent prompts.
|
||||
- Owner or handoff metadata.
|
||||
- Workspace change creation or target selection.
|
||||
- Branches.
|
||||
- Worktrees.
|
||||
- Apply.
|
||||
- Archive.
|
||||
- Complex target lifecycle.
|
||||
|
||||
Done when a user can set up a workspace, link repos or folders, list known workspaces, relink local paths, and run `doctor` to see exactly what OpenSpec can resolve.
|
||||
|
||||
### 2. Workspace Open
|
||||
|
||||
Next make the workspace openable in the way users expect.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Open this multi-repo planning context with my coding agent.
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec workspace open
|
||||
openspec workspace open --agent codex
|
||||
openspec workspace open --agent github-copilot
|
||||
```
|
||||
|
||||
Product behavior:
|
||||
|
||||
- `workspace open` opens the coordination workspace plus linked repos or folders.
|
||||
- Repo visibility is default.
|
||||
- Change selection is optional focus, not the mechanism for repo access.
|
||||
- `--agent` should be a one-session override by default. Persisting the preferred agent should require an explicit preference-setting action.
|
||||
|
||||
For GitHub Copilot, generate or open a `.code-workspace` file with:
|
||||
|
||||
```text
|
||||
workspace folder
|
||||
linked repo or folder A
|
||||
linked repo or folder B
|
||||
```
|
||||
|
||||
For Claude and Codex, attach the linked repo or folder directories through the agent's supported mechanism.
|
||||
|
||||
Defer:
|
||||
|
||||
- `workspace open --change`.
|
||||
- In-session upgrade flows.
|
||||
- Per-change attachment restrictions.
|
||||
|
||||
Done when opening a workspace gives the agent visibility into the coordination root and all linked repos or folders.
|
||||
|
||||
### 3. Agent Guidance And Explore
|
||||
|
||||
Then make exploration work.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Tell the agent a rough product goal and have it inspect the repos before creating a proposal.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
Explore how we should make the OpenSpec docs available on the landing page.
|
||||
Look across the linked repos or folders, but do not implement yet.
|
||||
```
|
||||
|
||||
Agent behavior:
|
||||
|
||||
- Understand it is in workspace mode.
|
||||
- Inspect linked repos or folders.
|
||||
- Explain likely affected repos.
|
||||
- Ask for clarification only when needed.
|
||||
- Avoid implementation edits during explore.
|
||||
|
||||
Build:
|
||||
|
||||
- Workspace-level `AGENTS.md` guidance.
|
||||
- Normal OpenSpec skills and commands in workspace sessions.
|
||||
- Workspace-specific guidance layered on top of normal `/explore`, not replacing it.
|
||||
|
||||
Defer:
|
||||
|
||||
- Proposal artifact generation.
|
||||
- Target confirmation commands.
|
||||
- Apply context providers.
|
||||
|
||||
Done when a user can open a workspace and run a useful cross-repo exploration without creating a dummy change.
|
||||
|
||||
### 4. Proposal Creation
|
||||
|
||||
Only after explore works, build proposal creation.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Now that we understand the scope, capture the plan.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
Create a proposal for this change.
|
||||
Target the repos that are actually affected.
|
||||
```
|
||||
|
||||
Preferred artifact shape:
|
||||
|
||||
```text
|
||||
changes/integrate-docs/
|
||||
proposal.md
|
||||
design.md
|
||||
tasks.md
|
||||
specs/
|
||||
openspec/
|
||||
docs-conventions/spec.md
|
||||
landing/
|
||||
docs-routing/spec.md
|
||||
```
|
||||
|
||||
Key workflow rule:
|
||||
|
||||
```text
|
||||
/explore may leave targets unknown.
|
||||
/propose may discover targets.
|
||||
/propose must confirm targets before saying ready for apply.
|
||||
```
|
||||
|
||||
Targets should be represented by the proposal artifacts themselves where possible. If there is `specs/landing/...`, then `landing` is in scope. Avoid a separate required `targets: [...]` metadata list as the active source of truth.
|
||||
|
||||
Defer:
|
||||
|
||||
- Repo-local materialization.
|
||||
- Worktree selection.
|
||||
- Multi-repo implementation.
|
||||
- Archive.
|
||||
|
||||
Done when a user can explore, then create a workspace proposal with repo-scoped specs and tasks.
|
||||
|
||||
### 5. Status
|
||||
|
||||
Before implementation, make status excellent.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Where are we, what repos are involved, and is this ready to implement?
|
||||
```
|
||||
|
||||
Expected surface:
|
||||
|
||||
```bash
|
||||
openspec status
|
||||
openspec status --change integrate-docs
|
||||
```
|
||||
|
||||
Human output should answer:
|
||||
|
||||
```text
|
||||
Change: integrate-docs
|
||||
Scope: openspec, landing
|
||||
Proposal: present
|
||||
Design: present
|
||||
Tasks: present
|
||||
Ready for apply: yes/no
|
||||
```
|
||||
|
||||
Status should also catch structural mistakes:
|
||||
|
||||
- Unknown repo folder under `specs/`.
|
||||
- Missing tasks.
|
||||
- No confirmed affected repo.
|
||||
- Linked repo or folder path missing.
|
||||
|
||||
Done when the agent and user can trust status before applying.
|
||||
|
||||
### 6. Apply One Repo Slice
|
||||
|
||||
Only now build `/apply`.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Implement the planned slice for one repo.
|
||||
```
|
||||
|
||||
Expected user prompt:
|
||||
|
||||
```text
|
||||
/apply integrate-docs for landing
|
||||
```
|
||||
|
||||
Product contract:
|
||||
|
||||
```text
|
||||
/apply means implement.
|
||||
```
|
||||
|
||||
It does not mean:
|
||||
|
||||
```text
|
||||
copy planning files
|
||||
materialize repo-local OpenSpec state
|
||||
create the proposal files for the first time
|
||||
```
|
||||
|
||||
Agent behavior:
|
||||
|
||||
1. Ask OpenSpec for apply context.
|
||||
2. Read proposal, design, tasks, and relevant specs.
|
||||
3. Confirm the target repo checkout.
|
||||
4. Edit only that repo.
|
||||
5. Update workspace tasks.
|
||||
6. Run relevant checks.
|
||||
|
||||
This likely wants a normalized context command internally, but that is supporting machinery:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "workspace",
|
||||
"change": "integrate-docs",
|
||||
"target": "landing",
|
||||
"implementationRoot": "/repos/openspec-landing",
|
||||
"contextFiles": [
|
||||
"changes/integrate-docs/proposal.md",
|
||||
"changes/integrate-docs/design.md",
|
||||
"changes/integrate-docs/tasks.md",
|
||||
"changes/integrate-docs/specs/landing/docs-routing/spec.md"
|
||||
],
|
||||
"allowedEditRoots": [
|
||||
"/repos/openspec-landing"
|
||||
],
|
||||
"tasksFile": "changes/integrate-docs/tasks.md"
|
||||
}
|
||||
```
|
||||
|
||||
Defer:
|
||||
|
||||
- Applying multiple repos at once.
|
||||
- Automatic branch creation.
|
||||
- Worktree management.
|
||||
- Repo-local OpenSpec mirroring.
|
||||
|
||||
Done when one repo slice can be implemented from the central workspace plan.
|
||||
|
||||
### 7. Verify
|
||||
|
||||
Then build verification.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
Check whether the implemented repo slice satisfies the plan.
|
||||
```
|
||||
|
||||
Expected prompt:
|
||||
|
||||
```text
|
||||
/verify integrate-docs for landing
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
- Read the same normalized context as `/apply`.
|
||||
- Inspect the implementation checkout.
|
||||
- Check tasks and specs for that repo.
|
||||
- Run repo validation.
|
||||
- Report gaps clearly.
|
||||
|
||||
Default behavior should verify one repo slice. Whole-workspace verification can come later.
|
||||
|
||||
Done when a user can verify one implemented repo slice against the central workspace plan.
|
||||
|
||||
### 8. Archive
|
||||
|
||||
Archive comes last in the first complete loop.
|
||||
|
||||
User goal:
|
||||
|
||||
```text
|
||||
The change is done. Move it out of active planning.
|
||||
```
|
||||
|
||||
Expected prompt:
|
||||
|
||||
```text
|
||||
/archive integrate-docs
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
- Require all targeted repo slices to be complete or explicitly accepted.
|
||||
- Archive the workspace change.
|
||||
- Do not require repo-local planning copies unless OpenSpec later decides that repo-local archival matters.
|
||||
|
||||
Done when a user can complete the full lifecycle:
|
||||
|
||||
```text
|
||||
workspace setup
|
||||
-> link repos or folders
|
||||
-> open
|
||||
-> explore
|
||||
-> propose
|
||||
-> apply repo A
|
||||
-> apply repo B
|
||||
-> verify
|
||||
-> archive
|
||||
```
|
||||
|
||||
## Implementation Discipline
|
||||
|
||||
Build only the next user-visible step.
|
||||
|
||||
The sequence should stay grounded in these questions:
|
||||
|
||||
```text
|
||||
1. Can I set up the workspace?
|
||||
2. Can I see my linked repos or folders?
|
||||
3. Can my agent explore them?
|
||||
4. Can we capture a proposal?
|
||||
5. Can status tell us if it is ready?
|
||||
6. Can the agent implement one repo slice?
|
||||
7. Can we verify it?
|
||||
8. Can we archive it?
|
||||
```
|
||||
|
||||
Avoid starting with internal abstractions unless they are required for the next user-visible capability.
|
||||
|
||||
Do not start with:
|
||||
|
||||
- Target metadata machinery.
|
||||
- Materialization.
|
||||
- Adapter abstractions.
|
||||
- Branch orchestration.
|
||||
- Worktree orchestration.
|
||||
- Multi-repo apply.
|
||||
|
||||
Those may matter later, but they should not define the first reimplementation path.
|
||||
|
||||
## Product Shape
|
||||
|
||||
The workspace should feel like OpenSpec's normal workflow stretched across multiple repos, not a second product with its own lifecycle.
|
||||
|
||||
The durable product model is:
|
||||
|
||||
```text
|
||||
workspace = durable planning home
|
||||
links = repos or folders visible for planning
|
||||
proposal = scoped planning commitment
|
||||
repo slice = one affected repo or folder in the plan
|
||||
branch/worktree = implementation checkout
|
||||
/apply = implement one selected repo slice
|
||||
```
|
||||
|
||||
Keep the user journey simple:
|
||||
|
||||
```text
|
||||
Open the workspace.
|
||||
Ask the agent to explore.
|
||||
Create the proposal when scope is clear.
|
||||
Implement one repo slice at a time.
|
||||
Verify.
|
||||
Archive.
|
||||
```
|
||||
@@ -1,67 +0,0 @@
|
||||
# Workspace Reimplementation Start Here
|
||||
|
||||
This is the grep-friendly entry point for agents working on the workspace reimplementation.
|
||||
|
||||
Useful search terms:
|
||||
|
||||
```text
|
||||
workspace reimplementation
|
||||
workspace poc
|
||||
workspace-poc
|
||||
workspace reference guide
|
||||
workspace roadmap
|
||||
fresh agent
|
||||
start here
|
||||
```
|
||||
|
||||
## Start Here
|
||||
|
||||
Read these files in order:
|
||||
|
||||
1. `WORKSPACE_REIMPLEMENTATION_DIRECTION.md`
|
||||
2. `openspec/changes/workspace-reimplementation-roadmap/README.md`
|
||||
3. `openspec/changes/workspace-reimplementation-roadmap/POC_REFERENCE_GUIDE.md`
|
||||
4. The proposal for the next implementation slice
|
||||
|
||||
The POC reference commit is:
|
||||
|
||||
```text
|
||||
workspace-poc @ 79a45ac043f414e63d13e08b9da83b135cb20a39
|
||||
```
|
||||
|
||||
Use the POC as research material. Do not merge it into an implementation branch. Do not preserve its architecture unless a slice proposal or design explicitly decides to do so.
|
||||
|
||||
## Implementation Order
|
||||
|
||||
Implement these flat OpenSpec changes in order:
|
||||
|
||||
1. `workspace-foundation`
|
||||
2. `workspace-create-and-register-repos`
|
||||
3. `workspace-open-agent-context`
|
||||
4. `workspace-change-planning`
|
||||
5. `workspace-apply-repo-slice`
|
||||
6. `workspace-verify-and-archive`
|
||||
|
||||
`workspace-reimplementation-roadmap` is the continuity and reference container for the plan.
|
||||
|
||||
## Before Editing
|
||||
|
||||
For the slice you are about to implement, inspect the pinned POC commit using `POC_REFERENCE_GUIDE.md`, then write down:
|
||||
|
||||
```text
|
||||
POC findings for <slice>:
|
||||
|
||||
User behavior to preserve:
|
||||
- ...
|
||||
|
||||
Tests or examples worth translating:
|
||||
- ...
|
||||
|
||||
Implementation shortcuts to avoid:
|
||||
- ...
|
||||
|
||||
Open design questions:
|
||||
- ...
|
||||
```
|
||||
|
||||
Capture durable findings in the relevant OpenSpec artifact so future sessions do not depend on chat history.
|
||||
+21
-166
@@ -1,13 +1,12 @@
|
||||
# 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).
|
||||
The OpenSpec CLI (`openspec`) provides terminal commands for project setup, validation, status inspection, and management. These commands complement the AI slash commands (like `/opsx:new`) documented in [Commands](commands.md).
|
||||
|
||||
## Summary
|
||||
|
||||
| Category | Commands | Purpose |
|
||||
|----------|----------|---------|
|
||||
| **Setup** | `init`, `update` | Initialize and update OpenSpec in your project |
|
||||
| **Workspaces (beta)** | `workspace setup`, `workspace list`, `workspace ls`, `workspace link`, `workspace relink`, `workspace doctor` | Set up planning across linked repos or folders |
|
||||
| **Browsing** | `list`, `view`, `show` | Explore changes and specs |
|
||||
| **Validation** | `validate` | Check changes and specs for issues |
|
||||
| **Lifecycle** | `archive` | Finalize completed changes |
|
||||
@@ -47,11 +46,6 @@ These commands support `--json` output for programmatic use by AI agents and scr
|
||||
| `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 |
|
||||
| `openspec workspace setup --no-interactive` | Create a workspace with explicit inputs | `--json` for structured setup output |
|
||||
| `openspec workspace list` | Browse known workspaces | `--json` for typed workspace objects |
|
||||
| `openspec workspace link` | Link a repo or folder | `--json` for structured link output |
|
||||
| `openspec workspace relink` | Repair a linked path | `--json` for structured link output |
|
||||
| `openspec workspace doctor` | Check one workspace | `--json` for structured status output |
|
||||
|
||||
---
|
||||
|
||||
@@ -73,8 +67,6 @@ These options work with all commands:
|
||||
|
||||
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, sync, archive`.
|
||||
|
||||
```
|
||||
openspec init [path] [options]
|
||||
```
|
||||
@@ -91,11 +83,8 @@ openspec init [path] [options]
|
||||
|--------|-------------|
|
||||
| `--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`, `bob`, `claude`, `cline`, `codex`, `forgecode`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `opencode`, `pi`, `qoder`, `lingma`, `qwen`, `roocode`, `trae`, `windsurf`
|
||||
**Supported tools:** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `opencode`, `qoder`, `qwen`, `roocode`, `windsurf`
|
||||
|
||||
**Examples:**
|
||||
|
||||
@@ -112,9 +101,6 @@ 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
|
||||
```
|
||||
@@ -127,9 +113,8 @@ openspec/
|
||||
├── 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)
|
||||
.claude/skills/ # Claude Code skill files (if claude selected)
|
||||
.cursor/rules/ # Cursor rules (if cursor selected)
|
||||
... (other tool configs)
|
||||
```
|
||||
|
||||
@@ -137,7 +122,7 @@ openspec/
|
||||
|
||||
### `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.
|
||||
Update OpenSpec instruction files after upgrading the CLI. Re-generates AI tool configuration files.
|
||||
|
||||
```
|
||||
openspec update [path] [options]
|
||||
@@ -165,103 +150,6 @@ openspec update
|
||||
|
||||
---
|
||||
|
||||
## Workspace Commands
|
||||
|
||||
Workspace commands are under active development and are not ready for use yet. Do not build external automation, integrations, or long-lived workflows on top of this command surface; command behavior, state files, and JSON output can change at any point.
|
||||
|
||||
Coordination workspaces are planning homes for work that spans multiple repos or folders. Workspace visibility is not change commitment: link the repos or folders OpenSpec should know about, then create changes when you are ready to plan specific work.
|
||||
|
||||
### `openspec workspace setup`
|
||||
|
||||
Create a workspace in the standard OpenSpec workspace location and link at least one existing repo or folder.
|
||||
|
||||
```bash
|
||||
openspec workspace setup [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--name <name>` | Workspace name. Names must be kebab-case |
|
||||
| `--link <path>` | Link an existing repo or folder and infer the link name from the folder name |
|
||||
| `--link <name>=<path>` | Link an existing repo or folder with an explicit link name |
|
||||
| `--no-interactive` | Disable prompts; requires `--name` and at least one `--link` |
|
||||
| `--json` | Output JSON; requires `--no-interactive` |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
openspec workspace setup
|
||||
openspec workspace setup --no-interactive --name platform --link /repos/api --link web=/repos/web
|
||||
openspec workspace setup --no-interactive --json --name checkout --link /repos/platform/apps/checkout
|
||||
```
|
||||
|
||||
Setup prints the workspace location, planning path, linked repos or folders, and a workspace check. It does not ask for a preferred agent or open the workspace.
|
||||
|
||||
### `openspec workspace list`
|
||||
|
||||
List known OpenSpec workspaces from the local registry.
|
||||
|
||||
```bash
|
||||
openspec workspace list [--json]
|
||||
openspec workspace ls [--json]
|
||||
```
|
||||
|
||||
The list shows each workspace location and linked repos or folders. Stale registry records are reported but not changed.
|
||||
|
||||
### `openspec workspace link`
|
||||
|
||||
Record an existing repo or folder for one workspace.
|
||||
|
||||
```bash
|
||||
openspec workspace link [name] <path> [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--workspace <name>` | Select a known workspace from the local registry |
|
||||
| `--json` | Output JSON |
|
||||
| `--no-interactive` | Disable workspace picker prompts |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
openspec workspace link /repos/api
|
||||
openspec workspace link api-service /repos/api
|
||||
openspec workspace link --workspace platform /repos/platform/apps/checkout
|
||||
```
|
||||
|
||||
The path must already exist. Relative paths are resolved against the command's current directory before OpenSpec stores the verified absolute path in machine-local workspace state. Linked paths can be full repos, packages, services, apps, or folders without repo-local `openspec/` state.
|
||||
|
||||
### `openspec workspace relink`
|
||||
|
||||
Repair or change the local path for an existing link.
|
||||
|
||||
```bash
|
||||
openspec workspace relink <name> <path> [options]
|
||||
```
|
||||
|
||||
The path must already exist. Relink updates only the machine-local path for the stable link name.
|
||||
|
||||
### `openspec workspace doctor`
|
||||
|
||||
Check what one workspace can resolve on the current machine.
|
||||
|
||||
```bash
|
||||
openspec workspace doctor [options]
|
||||
```
|
||||
|
||||
Doctor shows the workspace location, planning path, linked repos or folders, missing paths, repo-local specs paths when present, and suggested fixes. It reports issues only; it does not repair them automatically.
|
||||
|
||||
Commands that need one workspace use the current workspace when run from inside a workspace folder or subdirectory. From elsewhere, pass `--workspace <name>`, select from the picker in an interactive terminal, or rely on the only known workspace when exactly one exists. In `--json` or `--no-interactive` mode, ambiguous selection fails with a structured status error and suggests `--workspace <name>`.
|
||||
|
||||
JSON responses use typed objects plus `status` arrays. Primary data lives in `workspace`, `workspaces`, or `link`; warnings and errors live in `status`.
|
||||
|
||||
---
|
||||
|
||||
## Browsing Commands
|
||||
|
||||
### `openspec list`
|
||||
@@ -540,28 +428,29 @@ openspec status --change add-dark-mode --json
|
||||
```
|
||||
Change: add-dark-mode
|
||||
Schema: spec-driven
|
||||
Progress: 2/4 artifacts complete
|
||||
|
||||
[x] proposal
|
||||
[ ] design
|
||||
[x] specs
|
||||
[-] tasks (blocked by: design)
|
||||
Artifacts:
|
||||
✓ proposal proposal.md exists
|
||||
✓ specs specs/ exists
|
||||
◆ design ready (requires: specs)
|
||||
○ tasks blocked (requires: design)
|
||||
|
||||
Next: Create design using /opsx:continue
|
||||
```
|
||||
|
||||
**Output (JSON):**
|
||||
|
||||
```json
|
||||
{
|
||||
"changeName": "add-dark-mode",
|
||||
"schemaName": "spec-driven",
|
||||
"isComplete": false,
|
||||
"applyRequires": ["tasks"],
|
||||
"change": "add-dark-mode",
|
||||
"schema": "spec-driven",
|
||||
"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"]}
|
||||
]
|
||||
{"id": "proposal", "status": "complete", "path": "proposal.md"},
|
||||
{"id": "specs", "status": "complete", "path": "specs/"},
|
||||
{"id": "design", "status": "ready", "requires": ["specs"]},
|
||||
{"id": "tasks", "status": "blocked", "requires": ["design"]}
|
||||
],
|
||||
"next": "design"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -878,7 +767,6 @@ openspec config <subcommand> [options]
|
||||
| `unset <key>` | Remove a key |
|
||||
| `reset` | Reset to defaults |
|
||||
| `edit` | Open in `$EDITOR` |
|
||||
| `profile [preset]` | Configure workflow profile interactively or via preset |
|
||||
|
||||
**Examples:**
|
||||
|
||||
@@ -906,37 +794,6 @@ 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
|
||||
```
|
||||
|
||||
---
|
||||
@@ -1023,8 +880,6 @@ openspec completion uninstall
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `OPENSPEC_TELEMETRY` | Set to `0` to disable telemetry |
|
||||
| `DO_NOT_TRACK` | Set to `1` to disable telemetry (standard DNT signal) |
|
||||
| `OPENSPEC_CONCURRENCY` | Default concurrency for bulk validation (default: 6) |
|
||||
| `EDITOR` or `VISUAL` | Editor for `openspec config edit` |
|
||||
| `NO_COLOR` | Disable color output when set |
|
||||
@@ -1033,7 +888,7 @@ openspec completion uninstall
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Commands](commands.md) - AI slash commands (`/opsx:propose`, `/opsx:apply`, etc.)
|
||||
- [Commands](commands.md) - AI slash commands (`/opsx:new`, `/opsx:apply`, etc.)
|
||||
- [Workflows](workflows.md) - Common patterns and when to use each command
|
||||
- [Customization](customization.md) - Create custom schemas and templates
|
||||
- [Getting Started](getting-started.md) - First-time setup guide
|
||||
|
||||
+13
-65
@@ -6,70 +6,23 @@ For workflow patterns and when to use each command, see [Workflows](workflows.md
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Default Quick Path (`core` profile)
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
|
||||
| `/opsx:explore` | Think through ideas before committing to a change |
|
||||
| `/opsx:apply` | Implement tasks from the change |
|
||||
| `/opsx:sync` | Merge delta specs into main specs |
|
||||
| `/opsx:archive` | Archive a completed change |
|
||||
|
||||
### Expanded Workflow Commands (custom workflow selection)
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/opsx:new` | Start a new change scaffold |
|
||||
| `/opsx:new` | Start a new change |
|
||||
| `/opsx:continue` | Create the next artifact based on dependencies |
|
||||
| `/opsx:ff` | Fast-forward: create all planning artifacts at once |
|
||||
| `/opsx:apply` | Implement tasks from the change |
|
||||
| `/opsx:verify` | Validate implementation matches artifacts |
|
||||
| `/opsx:sync` | Merge delta specs into main specs |
|
||||
| `/opsx:archive` | Archive a completed change |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes at once |
|
||||
| `/opsx:onboard` | Guided tutorial through the complete workflow |
|
||||
|
||||
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.
|
||||
@@ -89,7 +42,7 @@ Think through ideas, investigate problems, and clarify requirements before commi
|
||||
- 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
|
||||
- Can transition to `/opsx:new` when insights crystallize
|
||||
|
||||
**Example:**
|
||||
```text
|
||||
@@ -113,7 +66,7 @@ AI: Let me investigate your current auth setup...
|
||||
|
||||
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.
|
||||
AI: Ready when you are. Run /opsx:new add-jwt-auth to begin.
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
@@ -126,9 +79,7 @@ AI: Ready when you are. Run /opsx:propose add-jwt-auth to begin.
|
||||
|
||||
### `/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).
|
||||
Start a new change. Creates the change folder structure and scaffolds it with the selected schema.
|
||||
|
||||
**Syntax:**
|
||||
```
|
||||
@@ -614,16 +565,13 @@ Different AI tools use slightly different command syntax. Use the format that ma
|
||||
|
||||
| Tool | Syntax Example |
|
||||
|------|----------------|
|
||||
| Claude Code | `/opsx:propose`, `/opsx:apply` |
|
||||
| Cursor | `/opsx-propose`, `/opsx-apply` |
|
||||
| Windsurf | `/opsx-propose`, `/opsx-apply` |
|
||||
| Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
|
||||
| Kimi CLI | Skill-based invocations such as `/skill:openspec-propose`, `/skill:openspec-apply-change` (no generated `opsx-*` command files) |
|
||||
| Trae | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) |
|
||||
| Claude Code | `/opsx:new`, `/opsx:apply` |
|
||||
| Cursor | `/opsx-new`, `/opsx-apply` |
|
||||
| Windsurf | `/opsx-new`, `/opsx-apply` |
|
||||
| Copilot | `/opsx-new`, `/opsx-apply` |
|
||||
| Trae | `/openspec-new-change`, `/openspec-apply-change` |
|
||||
|
||||
The 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.
|
||||
The functionality is identical regardless of syntax.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+27
-190
@@ -7,10 +7,10 @@ This guide explains the core ideas behind OpenSpec and how they fit together. Fo
|
||||
OpenSpec is built around four principles:
|
||||
|
||||
```
|
||||
fluid not rigid — no phase gates, work on what makes sense
|
||||
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
|
||||
easy not complex — lightweight setup, minimal ceremony
|
||||
brownfield-first — works with existing codebases, not just greenfield
|
||||
```
|
||||
|
||||
### Why These Principles Matter
|
||||
@@ -28,19 +28,19 @@ brownfield-first — works with existing codebases, not just greenfield
|
||||
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 │ │
|
||||
│ │ │ │ │ │
|
||||
│ └─────────────────────┘ └───────────────────────────────┘ │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────────────────┘
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 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.
|
||||
@@ -49,123 +49,6 @@ OpenSpec organizes your work into two main areas:
|
||||
|
||||
This separation is key. You can work on multiple changes in parallel without conflicts. You can review a change before it affects the main specs. And when you archive a change, its deltas merge cleanly into the source of truth.
|
||||
|
||||
## Coordination Workspaces
|
||||
|
||||
Workspace support is under active development and is not ready for use yet. Do not build external automation, integrations, or long-lived workflows on top of workspace behavior; the commands, state files, and JSON output can change at any point.
|
||||
|
||||
The commands below provide the first setup flow for planning across linked repos or folders.
|
||||
|
||||
Repo-local OpenSpec projects are the right default when one repo owns the planning, implementation, and archive flow. Some work spans several repos or folders. For that case, an OpenSpec coordination workspace is the durable planning home.
|
||||
|
||||
The workspace mental model is:
|
||||
|
||||
```text
|
||||
workspace = where related cross-repo changes live
|
||||
link = a stable name for a repo or folder the workspace can plan against
|
||||
change = one feature, fix, project, or other planned piece of work
|
||||
```
|
||||
|
||||
A workspace has a different shape from a repo-local project:
|
||||
|
||||
```text
|
||||
workspace-folder/
|
||||
├── changes/ # Workspace-level planning
|
||||
└── .openspec-workspace/
|
||||
├── workspace.yaml # Shared workspace identity and link names
|
||||
└── local.yaml # This machine's local paths
|
||||
```
|
||||
|
||||
Repo-local OpenSpec state keeps the existing shape:
|
||||
|
||||
```text
|
||||
repo-root/
|
||||
└── openspec/
|
||||
├── specs/
|
||||
└── changes/
|
||||
```
|
||||
|
||||
That distinction matters. The workspace folder is a coordination surface for planning across linked repos or folders. Each repo's `openspec/` directory remains the home for repo-owned specs, repo-local changes, and implementation planning. Users do not need to run repo-local `openspec init` inside a workspace folder.
|
||||
|
||||
Stable link names are how workspace planning refers to repos and folders. The shared workspace state keeps names such as `api`, `web`, or `checkout`; each machine maps those names to its own local paths in `.openspec-workspace/local.yaml`.
|
||||
|
||||
```yaml
|
||||
# .openspec-workspace/workspace.yaml
|
||||
version: 1
|
||||
name: platform
|
||||
links:
|
||||
api: {}
|
||||
web: {}
|
||||
```
|
||||
|
||||
```yaml
|
||||
# .openspec-workspace/local.yaml
|
||||
version: 1
|
||||
paths:
|
||||
api: /repos/api
|
||||
web: /repos/web
|
||||
```
|
||||
|
||||
OpenSpec-created workspaces exclude `.openspec-workspace/local.yaml` from portable collaboration state by default. `.openspec-workspace/workspace.yaml` remains portable because it stores the workspace name and stable link names, not one user's absolute checkout paths.
|
||||
|
||||
Linked paths can be full repos, folders inside a large monorepo, or other existing folders. They do not need repo-local `openspec/` state before they can participate in workspace planning. Later implementation, verify, or archive workflows may require more repo readiness, but planning visibility starts with the link.
|
||||
|
||||
```text
|
||||
multi-repo:
|
||||
api -> /repos/api
|
||||
web -> /repos/web
|
||||
|
||||
large monorepo:
|
||||
billing -> /repos/platform/services/billing
|
||||
checkout -> /repos/platform/apps/checkout
|
||||
```
|
||||
|
||||
Managed workspaces live under the standard OpenSpec data directory:
|
||||
|
||||
```text
|
||||
getGlobalDataDir()/workspaces
|
||||
```
|
||||
|
||||
That means `$XDG_DATA_HOME/openspec/workspaces` when `XDG_DATA_HOME` is set, `~/.local/share/openspec/workspaces` on Unix-style fallback, and `%LOCALAPPDATA%\openspec\workspaces` on native Windows fallback. Native Windows shells, PowerShell, and WSL2 each keep the path strings for the runtime running OpenSpec. This foundation does not translate between `D:\repo`, `/mnt/d/repo`, and UNC WSL paths.
|
||||
|
||||
OpenSpec also keeps a machine-local registry at:
|
||||
|
||||
```text
|
||||
getGlobalDataDir()/workspaces/registry.yaml
|
||||
```
|
||||
|
||||
The registry maps workspace names to workspace locations so later global commands can list or select known workspaces from anywhere. It is only an index. Each workspace folder remains authoritative for its own `.openspec-workspace/workspace.yaml` and `.openspec-workspace/local.yaml`, so stale registry records can be reported and repaired without redefining the workspace itself.
|
||||
|
||||
Workspace visibility is not change commitment. Set up a workspace when OpenSpec should know which repos or folders are relevant; create a change later when you are ready to plan a feature, fix, project, or other piece of work.
|
||||
|
||||
Useful commands:
|
||||
|
||||
```bash
|
||||
# Guided setup
|
||||
openspec workspace setup
|
||||
|
||||
# Automation-friendly setup
|
||||
openspec workspace setup --no-interactive --name platform --link /repos/api --link web=/repos/web
|
||||
|
||||
# See known workspaces from the local registry
|
||||
openspec workspace list
|
||||
openspec workspace ls
|
||||
|
||||
# Add or repair links for the selected workspace
|
||||
openspec workspace link /repos/api
|
||||
openspec workspace link api-service /repos/api
|
||||
openspec workspace relink api-service /new/path/to/api
|
||||
|
||||
# Check what this machine can resolve
|
||||
openspec workspace doctor
|
||||
openspec workspace doctor --workspace platform
|
||||
```
|
||||
|
||||
`workspace setup` always creates the workspace in the standard workspace location, records it in the local registry, shows the workspace location, and requires at least one linked repo or folder. `workspace link` and `workspace relink` record existing folders only; they do not create, copy, move, initialize, or edit the linked repo or folder.
|
||||
|
||||
Workspace commands that need one workspace can run from anywhere with `--workspace <name>`. If you run them inside a workspace folder or subdirectory, OpenSpec uses that current workspace. If several known workspaces are available and you do not pass `--workspace <name>`, human commands show a picker; `--json` and `--no-interactive` fail with a structured status error instead of prompting.
|
||||
|
||||
Direct workspace commands support JSON output for scripts. JSON responses keep primary data in `workspace`, `workspaces`, or `link` objects and report warnings or errors in `status` arrays. Healthy objects use `status: []`.
|
||||
|
||||
## Specs
|
||||
|
||||
Specs describe your system's behavior using structured requirements and scenarios.
|
||||
@@ -250,52 +133,6 @@ The system MUST expire sessions after 30 minutes of inactivity.
|
||||
- **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.
|
||||
@@ -387,7 +224,7 @@ Delta specs describe **what's changing** relative to the current specs. See [Del
|
||||
|
||||
The design captures **technical approach** and **architecture decisions**.
|
||||
|
||||
````markdown
|
||||
```markdown
|
||||
# Design: Add Dark Mode
|
||||
|
||||
## Technical Approach
|
||||
@@ -423,7 +260,7 @@ CSS Variables (applied to :root)
|
||||
- `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
|
||||
@@ -675,17 +512,17 @@ openspec/
|
||||
## How It All Fits Together
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────────┐
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ OPENSPEC FLOW │
|
||||
│ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 1. START │ /opsx:propose (core) or /opsx:new (expanded) │
|
||||
│ │ 1. START │ /opsx:new creates a change folder │
|
||||
│ │ CHANGE │ │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ 2. CREATE │ /opsx:ff or /opsx:continue (expanded workflow) │
|
||||
│ │ 2. CREATE │ /opsx:ff or /opsx:continue │
|
||||
│ │ ARTIFACTS │ Creates proposal → specs → design → tasks │
|
||||
│ │ │ (based on schema dependencies) │
|
||||
│ └───────┬────────┘ │
|
||||
@@ -704,13 +541,13 @@ openspec/
|
||||
│ └───────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ 5. ARCHIVE │────►│ Delta specs merge into main specs │ │
|
||||
│ │ CHANGE │ │ Change folder moves to archive/ │ │
|
||||
│ └────────────────┘ │ Specs are now the updated source of truth │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
│ ┌────────────────┐ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ 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:**
|
||||
|
||||
@@ -337,20 +337,6 @@ Then edit `schema.yaml` to add:
|
||||
|
||||
---
|
||||
|
||||
## Community Schemas
|
||||
|
||||
OpenSpec also supports community-maintained schemas distributed via standalone repositories. These provide opinionated workflows that integrate OpenSpec with other tools or systems, similar to how [github/spec-kit's community extension catalog](https://github.com/github/spec-kit/tree/main/extensions) works for spec-kit.
|
||||
|
||||
Community schemas are not vendored into OpenSpec core — they live in their own repositories with their own release cadence. To use one, copy the schema bundle into your project's `openspec/schemas/<schema-name>/` directory (each repo's README has install instructions).
|
||||
|
||||
| Schema | Maintainer | Repository | Description |
|
||||
|--------|-----------|-----------|-------------|
|
||||
| `superpowers-bridge` | @JiangWay | [JiangWay/openspec-schemas](https://github.com/JiangWay/openspec-schemas/tree/main/superpowers-bridge) | Integrates OpenSpec's artifact governance with [obra/superpowers](https://github.com/obra/superpowers) execution skills (brainstorming, writing-plans, TDD via subagents, code review, finishing). Adds an evidence-first `retrospective` artifact filling a gap Superpowers does not natively cover. |
|
||||
|
||||
> Want to contribute a community schema? Open an issue with a link to your repository, or submit a PR adding a row to this table.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [CLI Reference: Schema Commands](cli.md#schema-commands) - Full command documentation
|
||||
|
||||
+40
-20
@@ -4,22 +4,33 @@ This guide explains how OpenSpec works after you've installed and initialized it
|
||||
|
||||
## How It Works
|
||||
|
||||
OpenSpec helps you and your AI coding assistant agree on what to build before any code is written.
|
||||
OpenSpec helps you and your AI coding assistant agree on what to build before any code is written. The workflow follows a simple pattern:
|
||||
|
||||
**Default quick path (core profile):**
|
||||
|
||||
```text
|
||||
/opsx:propose ──► /opsx:apply ──► /opsx:sync ──► /opsx:archive
|
||||
```
|
||||
|
||||
**Expanded path (custom workflow selection):**
|
||||
|
||||
```text
|
||||
/opsx:new ──► /opsx:ff or /opsx:continue ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
|
||||
┌────────────────────┐
|
||||
│ Start a Change │ /opsx:new
|
||||
└────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Create Artifacts │ /opsx:ff or /opsx:continue
|
||||
│ (proposal, specs, │
|
||||
│ design, tasks) │
|
||||
└────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Implement Tasks │ /opsx:apply
|
||||
│ (AI writes code) │
|
||||
└────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Archive & Merge │ /opsx:archive
|
||||
│ Specs │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
The default global profile is `core`, which includes `propose`, `explore`, `apply`, `sync`, and `archive`. You can enable the expanded workflow commands with `openspec config profile` and then `openspec update`.
|
||||
|
||||
## What OpenSpec Creates
|
||||
|
||||
After running `openspec init`, your project has this structure:
|
||||
@@ -120,12 +131,23 @@ The change folder moves to `openspec/changes/archive/` for audit history.
|
||||
|
||||
Let's walk through adding dark mode to an application.
|
||||
|
||||
### 1. Start the Change (Default)
|
||||
### 1. Start the Change
|
||||
|
||||
```text
|
||||
You: /opsx:propose add-dark-mode
|
||||
```
|
||||
You: /opsx:new add-dark-mode
|
||||
|
||||
AI: Created openspec/changes/add-dark-mode/
|
||||
Ready to create: proposal
|
||||
```
|
||||
|
||||
### 2. Create Artifacts
|
||||
|
||||
Use `/opsx:ff` (fast-forward) to create all planning artifacts at once:
|
||||
|
||||
```
|
||||
You: /opsx:ff
|
||||
|
||||
AI: Creating artifacts for add-dark-mode...
|
||||
✓ proposal.md — why we're doing this, what's changing
|
||||
✓ specs/ — requirements and scenarios
|
||||
✓ design.md — technical approach
|
||||
@@ -133,9 +155,7 @@ AI: Created openspec/changes/add-dark-mode/
|
||||
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
|
||||
### 3. What Gets Created
|
||||
|
||||
**proposal.md** - Captures the intent:
|
||||
|
||||
@@ -198,7 +218,7 @@ The system SHALL allow users to choose between light and dark themes.
|
||||
- [ ] 3.2 Update components to use CSS variables
|
||||
```
|
||||
|
||||
### 3. Implement
|
||||
### 4. Implement
|
||||
|
||||
```
|
||||
You: /opsx:apply
|
||||
@@ -214,7 +234,7 @@ AI: Working through tasks...
|
||||
|
||||
During implementation, if you discover the design needs adjustment, just update the artifact and continue.
|
||||
|
||||
### 4. Archive
|
||||
### 5. Archive
|
||||
|
||||
```
|
||||
You: /opsx:archive
|
||||
|
||||
@@ -26,9 +26,6 @@ yarn global add @fission-ai/openspec@latest
|
||||
|
||||
### bun
|
||||
|
||||
Bun can install OpenSpec globally, but OpenSpec currently runs on Node.js.
|
||||
You still need Node.js 20.19.0 or higher available on `PATH`.
|
||||
|
||||
```bash
|
||||
bun add -g @fission-ai/openspec@latest
|
||||
```
|
||||
@@ -70,44 +67,6 @@ Or add to your development environment in `flake.nix`:
|
||||
openspec --version
|
||||
```
|
||||
|
||||
## Troubleshooting PATH Visibility
|
||||
|
||||
If `openspec --version` works in one terminal but fails in an editor, AI agent,
|
||||
GUI app, or automation, OpenSpec is usually installed correctly but that process
|
||||
started with a different `PATH`.
|
||||
|
||||
Global package managers create an executable shim in a bin directory, then your
|
||||
shell or launcher must put that directory on `PATH`. Common ways to inspect the
|
||||
directory are:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
printf '%s/bin\n' "$(npm prefix -g)"
|
||||
|
||||
# pnpm
|
||||
pnpm bin -g
|
||||
|
||||
# bun
|
||||
bun pm bin -g
|
||||
|
||||
# current shell
|
||||
command -v openspec
|
||||
```
|
||||
|
||||
Make sure the environment that launches your editor, agent, GUI app, or
|
||||
automation includes the package-manager bin directory. For shell startup files,
|
||||
keep this to a minimal `PATH` export in a file that the target environment
|
||||
actually reads. Do not move interactive setup such as prompts, themes,
|
||||
completions, or commands that can block into always-loaded startup files.
|
||||
|
||||
To bypass global bin discovery while debugging, run OpenSpec through a package
|
||||
manager:
|
||||
|
||||
```bash
|
||||
npx -y @fission-ai/openspec@latest --version
|
||||
pnpm dlx @fission-ai/openspec@latest --version
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
After installing, initialize OpenSpec in your project:
|
||||
|
||||
+23
-44
@@ -8,7 +8,7 @@ OPSX replaces the old phase-locked workflow with a fluid, action-based approach.
|
||||
|
||||
| Aspect | Legacy | OPSX |
|
||||
|--------|--------|------|
|
||||
| **Commands** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` | Default: `/opsx:propose`, `/opsx:apply`, `/opsx:sync`, `/opsx:archive` (expanded workflow commands optional) |
|
||||
| **Commands** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` | `/opsx:new`, `/opsx:continue`, `/opsx:apply`, and more |
|
||||
| **Workflow** | Create all artifacts at once | Create incrementally or all at once—your choice |
|
||||
| **Going back** | Awkward phase gates | Natural—update any artifact anytime |
|
||||
| **Customization** | Fixed structure | Schema-driven, fully hackable |
|
||||
@@ -46,7 +46,7 @@ Only OpenSpec-managed files that are being replaced:
|
||||
- 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)
|
||||
- GitHub Copilot: `.github/prompts/openspec-*.prompt.md`
|
||||
- And others (Augment, Continue, Amazon Q, etc.)
|
||||
|
||||
The migration detects whichever tools you have configured and cleans up their legacy files.
|
||||
@@ -84,9 +84,6 @@ Don't worry about getting it perfect. We're still learning what works best here,
|
||||
|
||||
Both `openspec init` and `openspec update` detect legacy files and guide you through the same cleanup process. Use whichever fits your situation:
|
||||
|
||||
- New installs default to profile `core` (`propose`, `explore`, `apply`, `sync`, `archive`).
|
||||
- Migrated installs preserve your previously installed workflows by writing a `custom` profile when needed.
|
||||
|
||||
### Using `openspec init`
|
||||
|
||||
Run this if you want to add new tools or reconfigure which tools are set up:
|
||||
@@ -144,7 +141,7 @@ Run this if you just want to migrate and refresh your existing tools to the late
|
||||
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.
|
||||
The update command also detects and cleans up legacy artifacts, then refreshes your skills to the latest version.
|
||||
|
||||
### Non-Interactive / CI Environments
|
||||
|
||||
@@ -278,43 +275,30 @@ 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):**
|
||||
After migration, you have 9 OPSX commands instead of 3:
|
||||
|
||||
| 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:new` | Start a new change |
|
||||
| `/opsx:continue` | Create the next artifact (one at a time) |
|
||||
| `/opsx:ff` | Fast-forward—create planning artifacts at once |
|
||||
| `/opsx:ff` | Fast-forward—create all planning artifacts at once |
|
||||
| `/opsx:apply` | Implement tasks from tasks.md |
|
||||
| `/opsx:verify` | Validate implementation matches specs |
|
||||
| `/opsx:sync` | Preview/spec-merge without archiving |
|
||||
| `/opsx:sync` | Preview spec merge (optional—archive prompts if needed) |
|
||||
| `/opsx:archive` | Finalize and archive the change |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes at once |
|
||||
| `/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:proposal` | `/opsx:new` then `/opsx:ff` |
|
||||
| `/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
|
||||
@@ -348,14 +332,14 @@ Too bad. Phase gates don't let you go back easily.
|
||||
OPSX uses actions, not phases:
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────┐
|
||||
│ ACTIONS (not phases) │
|
||||
│ │
|
||||
┌────────────────────────────────────────┐
|
||||
│ ACTIONS (not phases) │
|
||||
│ │
|
||||
│ new ◄──► continue ◄──► apply ◄──► archive │
|
||||
│ │ │ │ │ │
|
||||
│ └──────────┴───────────┴─────────────┘ │
|
||||
│ any order │
|
||||
└───────────────────────────────────────────────┘
|
||||
│ │ │ │ │ │
|
||||
│ └──────────┴───────────┴───────────┘ │
|
||||
│ any order │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Dependency Graph
|
||||
@@ -558,11 +542,9 @@ project/
|
||||
│ └── config.yaml # NEW: Project configuration
|
||||
├── .claude/
|
||||
│ └── skills/ # NEW: OPSX skills
|
||||
│ ├── openspec-propose/ # default core profile
|
||||
│ ├── openspec-explore/
|
||||
│ ├── openspec-apply-change/
|
||||
│ ├── openspec-sync-specs/
|
||||
│ └── ... # expanded profile adds new/continue/ff/etc.
|
||||
│ ├── openspec-new-change/
|
||||
│ └── ...
|
||||
├── CLAUDE.md # OpenSpec markers removed, your content preserved
|
||||
└── AGENTS.md # OpenSpec markers removed, your content preserved
|
||||
```
|
||||
@@ -576,15 +558,12 @@ project/
|
||||
|
||||
### Command Cheatsheet
|
||||
|
||||
```text
|
||||
/opsx:propose Start quickly (default core profile)
|
||||
```
|
||||
/opsx:new Start a change
|
||||
/opsx:continue Create next artifact
|
||||
/opsx:ff Create all planning artifacts
|
||||
/opsx:apply Implement tasks
|
||||
/opsx:archive Finish and archive
|
||||
|
||||
# Expanded workflow (if enabled):
|
||||
/opsx:new Scaffold a change
|
||||
/opsx:continue Create next artifact
|
||||
/opsx:ff Create planning artifacts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+9
-24
@@ -65,8 +65,6 @@ openspec init
|
||||
|
||||
This creates skills in `.claude/skills/` (or equivalent) that AI coding assistants auto-detect.
|
||||
|
||||
By default, OpenSpec uses the `core` workflow profile (`propose`, `explore`, `apply`, `sync`, `archive`). If you want the expanded workflow commands (`new`, `continue`, `ff`, `verify`, `bulk-archive`, `onboard`), configure them with `openspec config profile` and apply with `openspec update`.
|
||||
|
||||
During setup, you'll be prompted to create a **project config** (`openspec/config.yaml`). This is optional but recommended.
|
||||
|
||||
## Project Configuration
|
||||
@@ -157,17 +155,13 @@ rules:
|
||||
|
||||
| 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:new` | Start a new change |
|
||||
| `/opsx:continue` | Create the next artifact (based on what's ready) |
|
||||
| `/opsx:ff` | Fast-forward — create all planning artifacts at once |
|
||||
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
|
||||
| `/opsx:verify` | Validate implementation against artifacts (expanded workflow) |
|
||||
| `/opsx:sync` | Sync delta specs to main (default workflow, optional) |
|
||||
| `/opsx:sync` | Sync delta specs to main (optional—archive prompts if needed) |
|
||||
| `/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
|
||||
|
||||
@@ -175,21 +169,13 @@ rules:
|
||||
```
|
||||
/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).
|
||||
Think through ideas, investigate problems, compare options. No structure required - just a thinking partner. When insights crystallize, transition to `/opsx:new` or `/opsx:ff`.
|
||||
|
||||
### Start a new change
|
||||
```
|
||||
/opsx: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
|
||||
/opsx:new
|
||||
```
|
||||
You'll be asked what you want to build and which workflow schema to use.
|
||||
|
||||
### Create artifacts
|
||||
```
|
||||
@@ -313,7 +299,6 @@ Think of it like git branches:
|
||||
## Architecture Deep Dive
|
||||
|
||||
This section explains how OPSX works under the hood and how it compares to the legacy workflow.
|
||||
Examples in this section use the expanded command set (`new`, `continue`, etc.); default `core` users can map the same flow to `propose → apply → sync → archive`.
|
||||
|
||||
### Philosophy: Phases vs Actions
|
||||
|
||||
@@ -371,7 +356,7 @@ Examples in this section use the expanded command set (`new`, `continue`, etc.);
|
||||
│ Hardcoded Templates (TypeScript strings) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Tool-specific configurators/adapters │
|
||||
│ Configurators (18+ classes, one per editor) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Generated Command Files (.claude/commands/openspec/*.md) │
|
||||
@@ -619,7 +604,7 @@ artifacts:
|
||||
| **State** | Phase-based mental model | Filesystem existence |
|
||||
| **Customization** | Edit source, rebuild | Create schema.yaml |
|
||||
| **Iteration** | Phase-locked | Fluid, edit anything |
|
||||
| **Editor Support** | Tool-specific configurator/adapters | Single skills directory |
|
||||
| **Editor Support** | 18+ configurator classes | Single skills directory |
|
||||
|
||||
## Schemas
|
||||
|
||||
|
||||
+48
-74
@@ -1,64 +1,44 @@
|
||||
# Supported Tools
|
||||
|
||||
OpenSpec works with many AI coding assistants. When you run `openspec init`, OpenSpec configures selected tools using your active profile/workflow selection and delivery mode.
|
||||
OpenSpec works with 20+ AI coding assistants. When you run `openspec init`, you'll be prompted to select which tools you use, and OpenSpec will configure the appropriate integrations.
|
||||
|
||||
## How It Works
|
||||
|
||||
For each selected tool, OpenSpec can install:
|
||||
For each tool you select, OpenSpec installs:
|
||||
|
||||
1. **Skills** (if delivery includes skills): `.../skills/openspec-*/SKILL.md`
|
||||
2. **Commands** (if delivery includes commands): tool-specific `opsx-*` command files
|
||||
|
||||
By default, OpenSpec uses the `core` profile, which includes:
|
||||
- `propose`
|
||||
- `explore`
|
||||
- `apply`
|
||||
- `sync`
|
||||
- `archive`
|
||||
|
||||
You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `bulk-archive`, `onboard`) via `openspec config profile`, then run `openspec update`.
|
||||
1. **Skills** — Reusable instruction files that power the `/opsx:*` workflow commands
|
||||
2. **Commands** — Tool-specific slash command bindings
|
||||
|
||||
## Tool Directory Reference
|
||||
|
||||
| Tool (ID) | Skills path pattern | Command path pattern |
|
||||
|-----------|---------------------|----------------------|
|
||||
| Amazon Q Developer (`amazon-q`) | `.amazonq/skills/openspec-*/SKILL.md` | `.amazonq/prompts/opsx-<id>.md` |
|
||||
| Antigravity (`antigravity`) | `.agent/skills/openspec-*/SKILL.md` | `.agent/workflows/opsx-<id>.md` |
|
||||
| Auggie (`auggie`) | `.augment/skills/openspec-*/SKILL.md` | `.augment/commands/opsx-<id>.md` |
|
||||
| IBM Bob Shell (`bob`) | `.bob/skills/openspec-*/SKILL.md` | `.bob/commands/opsx-<id>.md` |
|
||||
| Claude Code (`claude`) | `.claude/skills/openspec-*/SKILL.md` | `.claude/commands/opsx/<id>.md` |
|
||||
| Cline (`cline`) | `.cline/skills/openspec-*/SKILL.md` | `.clinerules/workflows/opsx-<id>.md` |
|
||||
| CodeBuddy (`codebuddy`) | `.codebuddy/skills/openspec-*/SKILL.md` | `.codebuddy/commands/opsx/<id>.md` |
|
||||
| Codex (`codex`) | `.codex/skills/openspec-*/SKILL.md` | `$CODEX_HOME/prompts/opsx-<id>.md`\* |
|
||||
| ForgeCode (`forgecode`) | `.forge/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
|
||||
| Continue (`continue`) | `.continue/skills/openspec-*/SKILL.md` | `.continue/prompts/opsx-<id>.prompt` |
|
||||
| CoStrict (`costrict`) | `.cospec/skills/openspec-*/SKILL.md` | `.cospec/openspec/commands/opsx-<id>.md` |
|
||||
| Crush (`crush`) | `.crush/skills/openspec-*/SKILL.md` | `.crush/commands/opsx/<id>.md` |
|
||||
| Cursor (`cursor`) | `.cursor/skills/openspec-*/SKILL.md` | `.cursor/commands/opsx-<id>.md` |
|
||||
| Factory Droid (`factory`) | `.factory/skills/openspec-*/SKILL.md` | `.factory/commands/opsx-<id>.md` |
|
||||
| Gemini CLI (`gemini`) | `.gemini/skills/openspec-*/SKILL.md` | `.gemini/commands/opsx/<id>.toml` |
|
||||
| GitHub Copilot (`github-copilot`) | `.github/skills/openspec-*/SKILL.md` | `.github/prompts/opsx-<id>.prompt.md`\*\* |
|
||||
| iFlow (`iflow`) | `.iflow/skills/openspec-*/SKILL.md` | `.iflow/commands/opsx-<id>.md` |
|
||||
| Junie (`junie`) | `.junie/skills/openspec-*/SKILL.md` | `.junie/commands/opsx-<id>.md` |
|
||||
| Kilo Code (`kilocode`) | `.kilocode/skills/openspec-*/SKILL.md` | `.kilocode/workflows/opsx-<id>.md` |
|
||||
| Kimi CLI (`kimi`) | `.kimi/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/skill:openspec-*` invocations) |
|
||||
| Kiro (`kiro`) | `.kiro/skills/openspec-*/SKILL.md` | `.kiro/prompts/opsx-<id>.prompt.md` |
|
||||
| Lingma (`lingma`) | `.lingma/skills/openspec-*/SKILL.md` | `.lingma/commands/opsx/<id>.md` |
|
||||
| OpenCode (`opencode`) | `.opencode/skills/openspec-*/SKILL.md` | `.opencode/commands/opsx-<id>.md` |
|
||||
| Pi (`pi`) | `.pi/skills/openspec-*/SKILL.md` | `.pi/prompts/opsx-<id>.md` |
|
||||
| Qoder (`qoder`) | `.qoder/skills/openspec-*/SKILL.md` | `.qoder/commands/opsx/<id>.md` |
|
||||
| Qwen Code (`qwen`) | `.qwen/skills/openspec-*/SKILL.md` | `.qwen/commands/opsx-<id>.toml` |
|
||||
| RooCode (`roocode`) | `.roo/skills/openspec-*/SKILL.md` | `.roo/commands/opsx-<id>.md` |
|
||||
| Trae (`trae`) | `.trae/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
|
||||
| Windsurf (`windsurf`) | `.windsurf/skills/openspec-*/SKILL.md` | `.windsurf/workflows/opsx-<id>.md` |
|
||||
|
||||
\* Codex commands are installed in the global Codex home (`$CODEX_HOME/prompts/` if set, otherwise `~/.codex/prompts/`), not your project directory.
|
||||
|
||||
\*\* GitHub Copilot prompt files are recognized as custom slash commands in IDE extensions (VS Code, JetBrains, Visual Studio). Copilot CLI does not currently consume `.github/prompts/*.prompt.md` directly.
|
||||
| Tool | Skills Location | Commands Location |
|
||||
|------|-----------------|-------------------|
|
||||
| Amazon Q Developer | `.amazonq/skills/` | `.amazonq/prompts/` |
|
||||
| Antigravity | `.agent/skills/` | `.agent/workflows/` |
|
||||
| Auggie (Augment CLI) | `.augment/skills/` | `.augment/commands/` |
|
||||
| Claude Code | `.claude/skills/` | `.claude/commands/opsx/` |
|
||||
| Cline | `.cline/skills/` | `.clinerules/workflows/` |
|
||||
| CodeBuddy | `.codebuddy/skills/` | `.codebuddy/commands/opsx/` |
|
||||
| Codex | `.codex/skills/` | `.codex/prompts/` |
|
||||
| Continue | `.continue/skills/` | `.continue/prompts/` |
|
||||
| CoStrict | `.cospec/skills/` | `.cospec/openspec/commands/` |
|
||||
| Crush | `.crush/skills/` | `.crush/commands/opsx/` |
|
||||
| Cursor | `.cursor/skills/` | `.cursor/commands/` |
|
||||
| Factory Droid | `.factory/skills/` | `.factory/commands/` |
|
||||
| Gemini CLI | `.gemini/skills/` | `.gemini/commands/opsx/` |
|
||||
| GitHub Copilot | `.github/skills/` | `.github/prompts/` |
|
||||
| iFlow | `.iflow/skills/` | `.iflow/commands/` |
|
||||
| Kilo Code | `.kilocode/skills/` | `.kilocode/workflows/` |
|
||||
| OpenCode | `.opencode/skills/` | `.opencode/command/` |
|
||||
| Qoder | `.qoder/skills/` | `.qoder/commands/opsx/` |
|
||||
| Qwen Code | `.qwen/skills/` | `.qwen/commands/` |
|
||||
| RooCode | `.roo/skills/` | `.roo/commands/` |
|
||||
| Trae | `.trae/skills/` | `.trae/skills/` (via `/openspec-*`) |
|
||||
| Windsurf | `.windsurf/skills/` | `.windsurf/workflows/` |
|
||||
|
||||
## Non-Interactive Setup
|
||||
|
||||
For CI/CD or scripted setup, use `--tools` (and optionally `--profile`):
|
||||
For CI/CD or scripted setup, use the `--tools` flag:
|
||||
|
||||
```bash
|
||||
# Configure specific tools
|
||||
@@ -69,40 +49,34 @@ openspec init --tools all
|
||||
|
||||
# Skip tool configuration
|
||||
openspec init --tools none
|
||||
|
||||
# Override profile for this init run
|
||||
openspec init --profile core
|
||||
```
|
||||
|
||||
**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `forgecode`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `opencode`, `pi`, `qoder`, `lingma`, `qwen`, `roocode`, `trae`, `windsurf`
|
||||
**Available tool IDs:** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codebuddy`, `codex`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `opencode`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
|
||||
|
||||
## Workflow-Dependent Installation
|
||||
## What Gets Installed
|
||||
|
||||
OpenSpec installs workflow artifacts based on selected workflows:
|
||||
For each tool, OpenSpec generates 10 skill files that power the OPSX workflow:
|
||||
|
||||
- **Core profile (default):** `propose`, `explore`, `apply`, `sync`, `archive`
|
||||
- **Custom selection:** any subset of all workflow IDs:
|
||||
`propose`, `explore`, `new`, `continue`, `apply`, `ff`, `sync`, `archive`, `bulk-archive`, `verify`, `onboard`
|
||||
| Skill | Purpose |
|
||||
|-------|---------|
|
||||
| `openspec-explore` | Thinking partner for exploring ideas |
|
||||
| `openspec-new-change` | Start a new change |
|
||||
| `openspec-continue-change` | Create the next artifact |
|
||||
| `openspec-ff-change` | Fast-forward through all planning artifacts |
|
||||
| `openspec-apply-change` | Implement tasks |
|
||||
| `openspec-verify-change` | Verify implementation completeness |
|
||||
| `openspec-sync-specs` | Sync delta specs to main (optional—archive prompts if needed) |
|
||||
| `openspec-archive-change` | Archive a completed change |
|
||||
| `openspec-bulk-archive-change` | Archive multiple changes at once |
|
||||
| `openspec-onboard` | Guided onboarding through a complete workflow cycle |
|
||||
|
||||
In other words, skill/command counts are profile-dependent and delivery-dependent, not fixed.
|
||||
These skills are invoked via slash commands like `/opsx:new`, `/opsx:apply`, etc. See [Commands](commands.md) for the full list.
|
||||
|
||||
## Generated Skill Names
|
||||
## Adding a New Tool
|
||||
|
||||
When selected by profile/workflow config, OpenSpec generates these skills:
|
||||
Want to add support for another AI coding assistant? Check out the [command adapter pattern](../CONTRIBUTING.md) or open an issue on GitHub.
|
||||
|
||||
- `openspec-propose`
|
||||
- `openspec-explore`
|
||||
- `openspec-new-change`
|
||||
- `openspec-continue-change`
|
||||
- `openspec-apply-change`
|
||||
- `openspec-ff-change`
|
||||
- `openspec-sync-specs`
|
||||
- `openspec-archive-change`
|
||||
- `openspec-bulk-archive-change`
|
||||
- `openspec-verify-change`
|
||||
- `openspec-onboard`
|
||||
|
||||
See [Commands](commands.md) for command behavior and [CLI](cli.md) for `init`/`update` options.
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
|
||||
+7
-34
@@ -28,33 +28,7 @@ OPSX (fluid actions):
|
||||
|
||||
> **Customization:** OPSX workflows are driven by schemas that define artifact sequences. See [Customization](customization.md) for details on creating custom schemas.
|
||||
|
||||
## Two Modes
|
||||
|
||||
### Default Quick Path (`core` profile)
|
||||
|
||||
New installs default to `core`, which provides:
|
||||
- `/opsx:propose`
|
||||
- `/opsx:explore`
|
||||
- `/opsx:apply`
|
||||
- `/opsx:sync`
|
||||
- `/opsx:archive`
|
||||
|
||||
Typical flow:
|
||||
|
||||
```text
|
||||
/opsx:propose ──► /opsx:apply ──► /opsx:sync ──► /opsx:archive
|
||||
```
|
||||
|
||||
### Expanded/Full Workflow (custom selection)
|
||||
|
||||
If you want explicit scaffold-and-build commands (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:bulk-archive`, `/opsx:onboard`), enable them with:
|
||||
|
||||
```bash
|
||||
openspec config profile
|
||||
openspec update
|
||||
```
|
||||
|
||||
## Workflow Patterns (Expanded Mode)
|
||||
## Workflow Patterns
|
||||
|
||||
### Quick Feature
|
||||
|
||||
@@ -434,16 +408,15 @@ For full command details and options, see [Commands](commands.md).
|
||||
|
||||
| Command | Purpose | When to Use |
|
||||
|---------|---------|-------------|
|
||||
| `/opsx:propose` | Create change + planning artifacts | Fast default path (`core` profile) |
|
||||
| `/opsx:explore` | Think through ideas | Unclear requirements, investigation |
|
||||
| `/opsx:new` | Start a change scaffold | Expanded mode, explicit artifact control |
|
||||
| `/opsx:continue` | Create next artifact | Expanded mode, step-by-step artifact creation |
|
||||
| `/opsx:ff` | Create all planning artifacts | Expanded mode, clear scope |
|
||||
| `/opsx:new` | Start a change | Beginning any new work |
|
||||
| `/opsx:continue` | Create next artifact | Step-by-step artifact creation |
|
||||
| `/opsx:ff` | Create all planning artifacts | Clear scope, ready to build |
|
||||
| `/opsx:apply` | Implement tasks | Ready to write code |
|
||||
| `/opsx:verify` | Validate implementation | Expanded mode, before archiving |
|
||||
| `/opsx:sync` | Merge delta specs | Expanded mode, optional |
|
||||
| `/opsx:verify` | Validate implementation | Before archiving, catch mismatches |
|
||||
| `/opsx:sync` | Merge delta specs | Optional—archive prompts if needed |
|
||||
| `/opsx:archive` | Complete the change | All work finished |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes | Expanded mode, parallel work |
|
||||
| `/opsx:bulk-archive` | Archive multiple changes | Parallel work, batch completion |
|
||||
|
||||
## Next Steps
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-21
|
||||
@@ -1,93 +0,0 @@
|
||||
## Why
|
||||
|
||||
Parallel changes often touch the same capabilities and `cli-init`/`cli-update` behavior, but today there is no machine-readable way to express sequencing, dependencies, or expected merge order.
|
||||
|
||||
This creates three recurring problems:
|
||||
|
||||
- teams cannot tell which change should land first
|
||||
- large changes are hard to split into safe mergeable slices
|
||||
- parallel work can accidentally reintroduce assumptions already removed by another change
|
||||
|
||||
We need lightweight planning metadata and CLI guidance so contributors can safely stack plans on top of each other.
|
||||
|
||||
## What Changes
|
||||
|
||||
### 1. Add lightweight stack metadata for changes
|
||||
|
||||
Extend change metadata to support sequencing and decomposition context, for example:
|
||||
|
||||
- `dependsOn`: changes that must land first
|
||||
- `provides`: capability markers exposed by this change
|
||||
- `requires`: capability markers needed by this change
|
||||
- `touches`: capability/spec areas likely affected (advisory only; warning signal, not a hard dependency)
|
||||
- `parent`: optional parent change for split work
|
||||
|
||||
Metadata is optional and backward compatible for existing changes.
|
||||
|
||||
Ordering semantics:
|
||||
|
||||
- `dependsOn` is the source of truth for execution/archive ordering
|
||||
- `provides`/`requires` are capability contracts for validation and planning visibility
|
||||
- `provides`/`requires` do not create implicit dependency edges; authors must still declare required ordering via `dependsOn`
|
||||
|
||||
### 2. Add stack-aware validation
|
||||
|
||||
Enhance change validation to detect planning issues early:
|
||||
|
||||
- missing dependencies
|
||||
- dependency cycles
|
||||
- archive ordering violations (for example, attempting to archive a change before all `dependsOn` predecessors are archived)
|
||||
- unmatched capability markers (for example, `requires` marker with no provider in active history emits non-blocking warning)
|
||||
- overlap warnings when active changes touch the same capability
|
||||
|
||||
Validation should fail only for deterministic blockers (for example cycles or missing required dependencies), and keep overlap checks as actionable warnings.
|
||||
|
||||
### 3. Add sequencing visibility commands
|
||||
|
||||
Add lightweight CLI support to inspect and execute plan order:
|
||||
|
||||
- `openspec change graph` to show dependency DAG/order
|
||||
- `openspec change graph` validates for cycles first; when cycles are present it fails with the same deterministic cycle error as stack-aware validation
|
||||
- `openspec change next` to suggest unblocked changes ready to implement/archive
|
||||
|
||||
### 4. Add split scaffolding for large changes
|
||||
|
||||
Add helper workflow to decompose large proposals into stackable slices:
|
||||
|
||||
- `openspec change split <change-id>` scaffolds child changes with `parent` + `dependsOn`
|
||||
- generates minimal proposal/tasks stubs for each child slice
|
||||
- converts the source change into a parent planning container (no duplicate child implementation tasks)
|
||||
- re-running split for an already-split source change returns a deterministic actionable error unless `--overwrite` (alias `--force`) is passed
|
||||
- `--overwrite` / `--force` fully regenerates managed child scaffold stubs and metadata links for the split, replacing prior scaffold content
|
||||
|
||||
### 5. Document stack-first workflow
|
||||
|
||||
Update docs to describe:
|
||||
|
||||
- how to model dependencies and parent/child slices
|
||||
- when to split a large change
|
||||
- how to use graph/next validation signals during parallel development
|
||||
- migration guidance for `openspec/changes/IMPLEMENTATION_ORDER.md`:
|
||||
- machine-readable change metadata becomes the normative dependency source
|
||||
- `IMPLEMENTATION_ORDER.md` remains optional narrative context during transition
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `change-stacking-workflow`: Dependency-aware sequencing and split scaffolding for change planning
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `cli-change`: Adds graph/next/split planning commands and stack-aware validation messaging
|
||||
- `change-creation`: Supports parent/dependency metadata when creating or splitting changes
|
||||
- `openspec-conventions`: Defines optional stack metadata conventions for change proposals
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/project-config.ts` and related parsing/validation utilities for change metadata loading
|
||||
- `src/core/config-schema.ts` (or dedicated change schema) for stack metadata validation
|
||||
- `src/commands/change.ts` and/or `src/core/list.ts` for graph/next/split command behavior
|
||||
- `src/core/validation/*` for dependency cycle and overlap checks
|
||||
- `docs/cli.md`, `docs/concepts.md`, and contributor guidance for stack-aware workflows
|
||||
- tests for metadata parsing, graph ordering, next-item suggestions, and split scaffolding
|
||||
@@ -1,15 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Stack Metadata Scaffolding
|
||||
Change creation workflows SHALL support optional dependency metadata for new or split changes.
|
||||
|
||||
#### Scenario: Create change with stack metadata
|
||||
- **WHEN** a change is created with stack metadata inputs
|
||||
- **THEN** creation SHALL persist metadata fields in change configuration
|
||||
- **AND** persisted metadata SHALL be validated against change metadata schema rules
|
||||
|
||||
#### Scenario: Split-generated child metadata
|
||||
- **WHEN** child changes are generated from a split workflow
|
||||
- **THEN** each child SHALL include a `parent` link to the source change
|
||||
- **AND** SHALL include dependency metadata needed for deterministic sequencing
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Stack Metadata Model
|
||||
The system SHALL support optional metadata on active changes to express sequencing and decomposition relationships.
|
||||
|
||||
#### Scenario: Optional stack metadata is present
|
||||
- **WHEN** a change includes stack metadata fields
|
||||
- **THEN** the system SHALL parse and expose `dependsOn`, `provides`, `requires`, `touches`, and `parent`
|
||||
- **AND** validation SHALL enforce normalized field shapes and value types (`dependsOn`/`provides`/`requires`/`touches` as string arrays, `parent` as string when present)
|
||||
|
||||
#### Scenario: Backward compatibility without stack metadata
|
||||
- **WHEN** a change does not include stack metadata
|
||||
- **THEN** existing behavior SHALL continue without migration steps
|
||||
- **AND** validation SHALL not fail solely because stack metadata is absent
|
||||
|
||||
### Requirement: Change Dependency Graph
|
||||
The system SHALL provide dependency-aware ordering for active changes.
|
||||
|
||||
#### Scenario: Build dependency order
|
||||
- **WHEN** users request stack planning output
|
||||
- **THEN** the system SHALL compute a dependency graph across active changes
|
||||
- **AND** SHALL return a deterministic topological order for unblocked changes
|
||||
|
||||
#### Scenario: Tie-breaking within the same dependency depth
|
||||
- **WHEN** multiple unblocked changes share the same topological dependency depth
|
||||
- **THEN** ordering SHALL break ties lexicographically by change ID
|
||||
- **AND** repeated runs over the same input SHALL return the same order
|
||||
|
||||
#### Scenario: Dependency cycle detection
|
||||
- **WHEN** active changes contain a dependency cycle
|
||||
- **THEN** validation SHALL fail with cycle details before archive or sequencing actions proceed
|
||||
- **AND** output SHALL include actionable guidance to break the cycle
|
||||
|
||||
### Requirement: Capability marker and overlap semantics
|
||||
The system SHALL treat capability markers as validation contracts and `touches` as advisory overlap signals.
|
||||
|
||||
#### Scenario: Required capability provided by an active change
|
||||
- **WHEN** change B declares `requires` marker `X`
|
||||
- **AND** active change A declares `provides` marker `X`
|
||||
- **THEN** validation SHALL require B to declare an explicit ordering edge in `dependsOn` to at least one active provider of `X`
|
||||
- **AND** validation SHALL fail if no explicit dependency is declared
|
||||
|
||||
#### Scenario: Requires marker without active provider
|
||||
- **WHEN** a change declares a `requires` marker
|
||||
- **AND** no active change declares the corresponding `provides` marker
|
||||
- **THEN** validation SHALL NOT infer an implicit dependency edge
|
||||
- **AND** ordering SHALL continue to be determined solely by explicit `dependsOn` relationships
|
||||
|
||||
#### Scenario: Requires marker satisfied by archived history
|
||||
- **WHEN** a change declares a `requires` marker
|
||||
- **AND** no active change provides that marker
|
||||
- **AND** at least one archived change in history provides that marker
|
||||
- **THEN** validation SHALL NOT warn solely about missing provider
|
||||
- **AND** SHALL continue to use explicit `dependsOn` for active ordering
|
||||
|
||||
#### Scenario: Requires marker missing in full history
|
||||
- **WHEN** a change declares a `requires` marker
|
||||
- **AND** no active or archived change in history provides that marker
|
||||
- **THEN** validation SHALL emit a non-blocking warning naming the change and missing marker
|
||||
- **AND** SHALL NOT infer an implicit dependency edge
|
||||
|
||||
#### Scenario: Overlap warning for shared touches
|
||||
- **WHEN** multiple active changes declare overlapping `touches` values
|
||||
- **THEN** validation SHALL emit a warning listing the overlapping changes and touched areas
|
||||
- **AND** validation SHALL NOT fail solely on overlap
|
||||
@@ -1,27 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Stack Planning Commands
|
||||
The change CLI SHALL provide commands for dependency-aware sequencing of active changes.
|
||||
|
||||
#### Scenario: Show dependency graph
|
||||
- **WHEN** a user runs `openspec change graph`
|
||||
- **THEN** the CLI SHALL display dependency relationships for active changes
|
||||
- **AND** SHALL include a deterministic recommended order for execution
|
||||
|
||||
#### Scenario: Show next unblocked changes
|
||||
- **WHEN** a user runs `openspec change next`
|
||||
- **THEN** the CLI SHALL list changes that are not blocked by unresolved dependencies
|
||||
- **AND** SHALL use deterministic tie-breaking when multiple options are available
|
||||
|
||||
### Requirement: Split Large Change Scaffolding
|
||||
The change CLI SHALL support scaffolding child slices from an existing large change.
|
||||
|
||||
#### Scenario: Split command scaffolds child changes
|
||||
- **WHEN** a user runs `openspec change split <change-id>`
|
||||
- **THEN** the CLI SHALL create child change directories with proposal/tasks stubs
|
||||
- **AND** generated metadata SHALL include `parent` and dependency links back to the source change
|
||||
|
||||
#### Scenario: Re-running split on an already-split change
|
||||
- **WHEN** a user runs `openspec change split <change-id>` for a parent whose generated child directories already exist
|
||||
- **THEN** the CLI SHALL fail with a deterministic, actionable error
|
||||
- **AND** SHALL NOT mutate existing child change content unless an explicit overwrite mode is requested
|
||||
@@ -1,29 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Stack-Aware Change Planning Conventions
|
||||
OpenSpec conventions SHALL define optional metadata fields for sequencing and decomposition across concurrent changes.
|
||||
|
||||
#### Scenario: Declaring change dependencies
|
||||
- **WHEN** authors need to sequence related changes
|
||||
- **THEN** conventions SHALL define how to declare dependencies and provided/required capability markers
|
||||
- **AND** validation guidance SHALL distinguish hard blockers from soft overlap warnings
|
||||
|
||||
#### Scenario: Dependency source of truth during migration
|
||||
- **WHEN** both stack metadata and `openspec/changes/IMPLEMENTATION_ORDER.md` are present
|
||||
- **THEN** conventions SHALL treat per-change stack metadata as the normative dependency source
|
||||
- **AND** `IMPLEMENTATION_ORDER.md` SHALL be treated as optional narrative guidance
|
||||
|
||||
#### Scenario: Explicit ordering remains required for capability markers
|
||||
- **WHEN** authors use `provides` and `requires` markers to describe capability contracts
|
||||
- **THEN** conventions SHALL require explicit `dependsOn` edges for ordering relationships
|
||||
- **AND** conventions SHALL prohibit treating `requires` as an implicit dependency edge
|
||||
|
||||
#### Scenario: Declaring advisory overlap via touches
|
||||
- **WHEN** a change may affect capability/spec areas shared by concurrent changes without requiring ordering
|
||||
- **THEN** conventions SHALL allow authors to declare `touches` with advisory area identifiers (for example capability IDs, spec area names, or paths)
|
||||
- **AND** tooling SHALL treat `touches` as informational only (no implicit dependency edge, non-blocking validation signal)
|
||||
|
||||
#### Scenario: Declaring parent-child split structure
|
||||
- **WHEN** a large change is decomposed into smaller slices
|
||||
- **THEN** conventions SHALL define parent-child metadata and expected ordering semantics
|
||||
- **AND** docs SHALL describe when to split versus keep a single change
|
||||
@@ -1,39 +0,0 @@
|
||||
## 1. Metadata Model
|
||||
|
||||
- [ ] 1.1 Add optional stack metadata fields (`dependsOn`, `provides`, `requires`, `touches`, `parent`) to change metadata schema
|
||||
- [ ] 1.2 Keep metadata backward compatible for existing changes without new fields
|
||||
- [ ] 1.3 Add tests for valid/invalid metadata and schema evolution behavior
|
||||
|
||||
## 2. Stack-Aware Validation
|
||||
|
||||
- [ ] 2.1 Detect dependency cycles and fail validation with deterministic errors
|
||||
- [ ] 2.2 Detect missing `dependsOn` targets (referenced change ID does not exist) and detect changes transitively blocked by unresolved/cyclic dependency paths
|
||||
- [ ] 2.3 Add overlap warnings for active changes that touch the same capability/spec areas
|
||||
- [ ] 2.4 Emit advisory warnings for unmatched `requires` markers when no provider exists in active history
|
||||
- [ ] 2.5 Add tests for cycle, missing dependency, overlap warning, and unmatched `requires` cases
|
||||
|
||||
## 3. Sequencing Commands
|
||||
|
||||
- [ ] 3.1 Add `openspec change graph` to display dependency order for active changes
|
||||
- [ ] 3.2 Add `openspec change next` to suggest unblocked changes in recommended order
|
||||
- [ ] 3.3 Add tests for topological ordering and deterministic tie-breaking (lexicographic by change ID at equal depth)
|
||||
|
||||
## 4. Split Scaffolding
|
||||
|
||||
- [ ] 4.1 Add `openspec change split <change-id>` to scaffold child slices
|
||||
- [ ] 4.2 Ensure generated children include parent/dependency metadata and stub proposal/tasks files
|
||||
- [ ] 4.3 Convert the source change into a parent planning container as part of split (no duplicate child implementation tasks)
|
||||
- [ ] 4.4 Add tests for split output structure, source-change parent conversion, and deterministic re-split error behavior when overwrite mode is not requested
|
||||
- [ ] 4.5 Implement and test explicit overwrite mode for `openspec change split` (`--overwrite` / `--force`) for controlled re-splitting
|
||||
|
||||
## 5. Documentation
|
||||
|
||||
- [ ] 5.1 Document stack metadata and sequencing workflow in `docs/concepts.md`
|
||||
- [ ] 5.2 Document new change commands and usage examples in `docs/cli.md`
|
||||
- [ ] 5.3 Add guidance for breaking large changes into independently mergeable slices
|
||||
- [ ] 5.4 Document migration guidance for `openspec/changes/IMPLEMENTATION_ORDER.md` as optional narrative, not dependency source of truth
|
||||
|
||||
## 6. Verification
|
||||
|
||||
- [ ] 6.1 Run targeted tests for change parsing, validation, and CLI commands
|
||||
- [ ] 6.2 Run full test suite (`pnpm test`) and resolve regressions
|
||||
@@ -0,0 +1,60 @@
|
||||
## 1. Project Setup and Command Registration
|
||||
|
||||
- [x] 1.1 Create directory structure: `src/core/dashboard/` with `index.ts`, `server.ts`, `data.ts`, `markdown.ts`
|
||||
- [x] 1.2 Register `openspec dashboard` command in `src/cli/index.ts` with `--port` and `--no-open` options
|
||||
- [x] 1.3 Create `DashboardCommand` class in `src/core/dashboard/index.ts` that validates openspec directory exists
|
||||
|
||||
## 2. Data Gathering Module
|
||||
|
||||
- [x] 2.1 Implement `getChangesData()` in `data.ts` that returns draft/active/completed changes with artifact existence status (proposal.md, specs/, design.md, tasks.md)
|
||||
- [x] 2.2 Implement `getSpecsData()` in `data.ts` that returns specs grouped by domain prefix with requirement counts
|
||||
- [x] 2.3 Implement `getArchiveData()` in `data.ts` that returns archived changes with parsed dates, sorted reverse chronologically
|
||||
- [x] 2.4 Implement `getSummary()` in `data.ts` that aggregates counts for dashboard summary section
|
||||
- [x] 2.5 Implement `getArtifactContent()` in `data.ts` that reads a markdown file by relative path with path traversal protection
|
||||
|
||||
## 3. Markdown Renderer
|
||||
|
||||
- [x] 3.1 Implement markdown-to-HTML converter in `markdown.ts` handling headings, paragraphs, bold, italic, and line breaks
|
||||
- [x] 3.2 Add support for fenced code blocks and inline code
|
||||
- [x] 3.3 Add support for unordered lists, ordered lists, and checkboxes
|
||||
- [x] 3.4 Add support for blockquotes, horizontal rules, and links
|
||||
|
||||
## 4. HTTP Server and API
|
||||
|
||||
- [x] 4.1 Implement HTTP server in `server.ts` using Node.js built-in `http` module
|
||||
- [x] 4.2 Add route `GET /` that serves the embedded single-page HTML dashboard
|
||||
- [x] 4.3 Add route `GET /api/summary` returning aggregated project data
|
||||
- [x] 4.4 Add route `GET /api/changes` returning changes with artifact status
|
||||
- [x] 4.5 Add route `GET /api/specs` returning specs grouped by domain
|
||||
- [x] 4.6 Add route `GET /api/archive` returning archive entries with pagination (default 50)
|
||||
- [x] 4.7 Add route `GET /api/artifact?path=<relative>` returning rendered markdown HTML with path traversal guard
|
||||
- [x] 4.8 Implement port selection with auto-increment from default 3000 to 3010
|
||||
- [x] 4.9 Implement cross-platform browser opening (open/xdg-open/start)
|
||||
- [x] 4.10 Add graceful shutdown on SIGINT/SIGTERM
|
||||
|
||||
## 5. Dashboard HTML/CSS/JS
|
||||
|
||||
- [x] 5.1 Create embedded HTML template with navigation tabs for Changes, Specs, and Archive sections
|
||||
- [x] 5.2 Implement Changes view with status grouping (draft/active/completed), artifact indicators, and progress bars
|
||||
- [x] 5.3 Implement Specs view with domain-prefix grouping and requirement count display
|
||||
- [x] 5.4 Implement Archive view with date-based listing and "load more" pagination
|
||||
- [x] 5.5 Implement artifact detail panel that fetches and displays rendered markdown on click
|
||||
- [x] 5.6 Add basic responsive CSS styling with monospace fonts matching terminal aesthetic
|
||||
|
||||
## 6. Testing
|
||||
|
||||
- [x] 6.1 Add unit tests for markdown renderer in `test/core/dashboard/markdown.test.ts`
|
||||
- [x] 6.2 Add unit tests for data gathering functions in `test/core/dashboard/data.test.ts`
|
||||
- [x] 6.3 Add unit tests for path traversal prevention in artifact endpoint
|
||||
- [x] 6.4 Add unit tests for port selection logic
|
||||
- [x] 6.5 Add unit tests for domain grouping logic
|
||||
- [x] 6.6 Add unit tests for archive date parsing
|
||||
|
||||
## 7. Polish and Integration
|
||||
|
||||
- [x] 7.1 Add CLI help text for the dashboard command
|
||||
- [x] 7.2 Add shell completion entries for dashboard command and its options
|
||||
- [x] 7.3 Handle edge cases: empty project, missing directories, unparseable specs
|
||||
- [x] 7.4 Ensure cross-platform path handling with `path.join()` throughout
|
||||
- [x] 7.5 Run linting and fix any issues (`pnpm run lint`)
|
||||
- [x] 7.6 Run full test suite (`pnpm test`)
|
||||
@@ -1,2 +0,0 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-21
|
||||
@@ -1,161 +0,0 @@
|
||||
## Context
|
||||
|
||||
OpenSpec today assumes project-local installation for most generated artifacts, with Codex command prompts as the main global exception. This mixed model works, but it is implicit and not user-configurable.
|
||||
|
||||
The requested change is to support user-selectable install scope (`global` or `project`) for tool skills/commands, defaulting to `global` for new configurations while preserving legacy project-local behavior until explicit migration.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Provide a single scope preference that users can set globally and override per run
|
||||
- Default new users to `global` scope
|
||||
- Make install path resolution deterministic and explicit across tools/surfaces
|
||||
- Preserve current behavior for users with older config files that do not yet define `installScope`
|
||||
- Avoid silent partial installs; surface effective scope decisions in output
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Implementing project-local config file support for global settings
|
||||
- Defining global install paths for tools where upstream location conventions are unknown
|
||||
- Changing workflow/profile semantics (`core`, `custom`, `delivery`) in this change
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Scope model in global config
|
||||
|
||||
Add install scope preference to global config:
|
||||
|
||||
```ts
|
||||
type InstallScope = 'global' | 'project';
|
||||
|
||||
interface GlobalConfig {
|
||||
// existing fields...
|
||||
installScope?: InstallScope;
|
||||
}
|
||||
```
|
||||
|
||||
Defaults:
|
||||
|
||||
- New configs SHOULD write `installScope: global` explicitly.
|
||||
- Existing configs without this field continue to load safely through schema evolution and SHALL resolve effective default as `project` until users explicitly set `installScope`.
|
||||
|
||||
### 2. Explicit tool scope support metadata
|
||||
|
||||
Extend `AI_TOOLS` metadata with optional scope support declarations per surface:
|
||||
|
||||
```ts
|
||||
interface ToolInstallScopeSupport {
|
||||
skills?: InstallScope[];
|
||||
commands?: InstallScope[];
|
||||
}
|
||||
```
|
||||
|
||||
Resolution rules:
|
||||
|
||||
1. If scope support metadata is absent for a tool surface, treat it as project-only support for conservative backward compatibility.
|
||||
2. Try preferred scope.
|
||||
3. If unsupported, use alternate scope when supported.
|
||||
4. If neither is supported, fail with actionable error.
|
||||
|
||||
This enables default-global behavior while remaining safe for tools that only support project-local paths.
|
||||
|
||||
### 3. Scope-aware install target resolver
|
||||
|
||||
Introduce shared resolver utilities to compute effective target paths for:
|
||||
|
||||
- skills root directory
|
||||
- command output files
|
||||
|
||||
Resolver input:
|
||||
|
||||
- tool id
|
||||
- requested scope
|
||||
- project root
|
||||
- environment context (`CODEX_HOME`, etc.)
|
||||
|
||||
Resolver output:
|
||||
|
||||
- effective scope per surface
|
||||
- concrete target paths
|
||||
- optional fallback reasons for user-facing output
|
||||
|
||||
Platform behavior:
|
||||
|
||||
- Resolver outputs are OS-aware and normalized for the current platform.
|
||||
- Windows global targets MUST use Windows path conventions (for example `%USERPROFILE%\.codex\prompts` fallback for Codex when `CODEX_HOME` is unset), not POSIX defaults.
|
||||
|
||||
### 4. Context-aware command adapter paths
|
||||
|
||||
Update command generation contract so adapters receive install context for path resolution. This avoids hardcoded absolute/relative assumptions and centralizes scope decisions.
|
||||
|
||||
Example direction:
|
||||
|
||||
```ts
|
||||
getFilePath(commandId: string, context: InstallContext): string
|
||||
```
|
||||
|
||||
### 5. CLI behavior and UX
|
||||
|
||||
`init`:
|
||||
|
||||
- Uses configured install scope by default; if absent in a legacy config, uses migration-safe effective default (`project`).
|
||||
- Supports explicit override flag (`--scope global|project`).
|
||||
- In interactive mode, displays chosen scope and any per-tool fallback decisions before writing files.
|
||||
|
||||
`update`:
|
||||
|
||||
- Applies current scope preference (or override); if absent in a legacy config, uses migration-safe effective default (`project`).
|
||||
- Performs drift detection using effective scoped paths and last-applied scope state.
|
||||
- Reports effective scope decisions in summary output.
|
||||
|
||||
`config`:
|
||||
|
||||
- `openspec config profile` interactive flow includes install scope selection.
|
||||
- `openspec config list` shows `installScope` with source annotation (`explicit`, `new-default`, or `legacy-default`).
|
||||
|
||||
### 6. Cleanup safety during scope changes
|
||||
|
||||
When scope changes:
|
||||
|
||||
- Writes occur in the new effective targets.
|
||||
- Cleanup/removal is limited to OpenSpec-managed files for the relevant tool/workflow IDs.
|
||||
- Output explicitly states which scope locations were updated and which were cleaned.
|
||||
|
||||
### 7. Scope drift state tracking
|
||||
|
||||
Track last successful effective scope per tool/surface in project-managed state.
|
||||
|
||||
Rules:
|
||||
|
||||
1. Drift is detected when current resolved scope differs from last successful scope for a configured tool/surface.
|
||||
2. Scope support MUST be validated for all configured tools/surfaces before any write starts.
|
||||
3. Update writes to newly resolved targets first, verifies completeness, then removes managed files at previous targets.
|
||||
4. If new-target writes are partial or verification fails, command SHALL abort old-target cleanup and report actionable failure with incomplete/new and preserved/old paths.
|
||||
5. Cleanup failures do not rollback new writes; command returns actionable failure with leftover paths to resolve.
|
||||
|
||||
### 8. Coordination with command-surface capability changes
|
||||
|
||||
If `add-tool-command-surface-capabilities` lands, planning logic must evaluate scope resolution and delivery/capability behavior together (scope × delivery × command surface).
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
**Risk: Cross-project shared global state**
|
||||
Global installs are shared across projects. Updating global artifacts from one project affects all projects using that tool scope.
|
||||
→ Mitigation: make scope explicit in output; keep profile/delivery global and deterministic.
|
||||
|
||||
**Risk: Tool-specific unknown global conventions**
|
||||
Not all tools document a stable global install location.
|
||||
→ Mitigation: use explicit scope support metadata; fallback or fail instead of guessing.
|
||||
|
||||
**Risk: Adapter API churn**
|
||||
Changing adapter path contracts touches many files/tests.
|
||||
→ Mitigation: migrate in one pass with adapter contract tests and existing end-to-end generation tests.
|
||||
|
||||
## Rollout Plan
|
||||
|
||||
1. Add config schema + defaults for install scope.
|
||||
2. Add tool scope capability metadata and resolver utilities.
|
||||
3. Upgrade command adapter contract and generator path plumbing.
|
||||
4. Integrate scope-aware behavior into init/update.
|
||||
5. Add documentation and test coverage.
|
||||
@@ -1,101 +0,0 @@
|
||||
## Why
|
||||
|
||||
OpenSpec installation paths are currently inconsistent:
|
||||
|
||||
- Most skills and commands are written to project-local directories.
|
||||
- Codex commands are already global (`$CODEX_HOME/prompts` or `~/.codex/prompts`).
|
||||
- Users cannot choose a consistent install scope strategy across tools.
|
||||
|
||||
This creates friction for users who prefer user-level setup and expect tool artifacts to be managed globally by default.
|
||||
|
||||
## What Changes
|
||||
|
||||
### 1. Add install scope preference with legacy-safe defaults
|
||||
|
||||
Introduce a global install scope setting with two modes:
|
||||
|
||||
- `global` (default for newly created configs)
|
||||
- `project`
|
||||
|
||||
The setting is stored in global config and can be overridden per command run.
|
||||
For schema-evolved legacy configs where `installScope` is absent, effective default remains `project` until users opt in to global scope.
|
||||
|
||||
### 2. Add scope-aware path resolution for skills and commands
|
||||
|
||||
Refactor path resolution so both `init` and `update` compute install targets from:
|
||||
|
||||
- selected scope preference (`global` or `project`)
|
||||
- tool capability metadata (which scopes each tool/surface supports)
|
||||
- runtime context (project root, home directories, env overrides)
|
||||
|
||||
### 3. Add per-tool capability metadata for scope support
|
||||
|
||||
Extend tool metadata to explicitly declare scope support per surface:
|
||||
|
||||
- skills scope support
|
||||
- commands scope support
|
||||
|
||||
When preferred scope is unsupported for a tool/surface, the system uses deterministic fallback rules and reports the effective scope in output.
|
||||
|
||||
### 4. Make command generation context-aware
|
||||
|
||||
Extend command adapter path resolution so adapters receive install context (scope + environment context), instead of only command ID. This removes special-case handling and allows consistent scope behavior across tools.
|
||||
|
||||
### 5. Update init/update UX and behavior
|
||||
|
||||
- `openspec init`:
|
||||
- accepts scope override flag
|
||||
- uses configured scope or migration-aware default (new configs default global; legacy configs preserve project until migration)
|
||||
- applies scope-aware generation and cleanup planning
|
||||
- `openspec update`:
|
||||
- applies current scope preference
|
||||
- syncs artifacts in effective scope per tool/surface
|
||||
- tracks last successful effective scope per tool/surface for deterministic scope-drift detection
|
||||
- reports effective scope decisions clearly
|
||||
|
||||
### 6. Extend config UX and docs
|
||||
|
||||
- Add install scope control in `openspec config profile` interactive flow.
|
||||
- Extend `openspec config list` output with install scope source (`explicit`, `new-default`, `legacy-default`).
|
||||
- Add explicit migration guidance and prompt path so legacy users can opt into `global` scope.
|
||||
- Update supported tools and CLI docs to explain scope behavior and fallback rules.
|
||||
|
||||
### 7. Coordinate with command-surface capability delivery rules
|
||||
|
||||
`cli-init` and `cli-update` planning SHALL compose:
|
||||
|
||||
- install scope (`global | project`)
|
||||
- delivery mode (`both | skills | commands`)
|
||||
- command surface capability (`adapter | skills-invocable | none`)
|
||||
|
||||
This proposal remains focused on scope resolution, but implementation and test coverage should include mixed-tool cases to avoid regressions when combined with `add-tool-command-surface-capabilities`.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `installation-scope`: Scope preference model and effective scope resolution for tool artifact installation.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `global-config`: Persist install scope preference with schema evolution defaults.
|
||||
- `cli-config`: Configure and inspect install scope preferences.
|
||||
- `ai-tool-paths`: Add tool-level scope support metadata and path strategy.
|
||||
- `command-generation`: Scope-aware adapter path resolution via install context.
|
||||
- `cli-init`: Scope-aware initialization planning and output.
|
||||
- `cli-update`: Scope-aware update sync, drift detection, and output.
|
||||
- `migration`: Scope-aware migration scanning with install-scope-aware workflow lookup.
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/global-config.ts` - new install scope fields and defaults
|
||||
- `src/core/config-schema.ts` - validation support for install scope config keys
|
||||
- `src/commands/config.ts` - interactive profile/config UX additions for install scope
|
||||
- `src/core/config.ts` - tool scope capability metadata
|
||||
- `src/core/available-tools.ts` and `src/core/shared/tool-detection.ts` - scope-aware configured detection
|
||||
- `src/core/command-generation/types.ts` and adapter implementations - context-aware file path resolution
|
||||
- `src/core/init.ts` - scope-aware generation/removal planning
|
||||
- `src/core/update.ts` - scope-aware sync/removal/drift planning
|
||||
- `src/core/migration.ts` - scope-aware workflow scanning support
|
||||
- `docs/supported-tools.md` and `docs/cli.md` - install scope behavior documentation
|
||||
- `test/core/init.test.ts`, `test/core/update.test.ts`, adapter tests, config tests - scope coverage
|
||||
@@ -1,35 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: AIToolOption skillsDir field
|
||||
The `AIToolOption` interface SHALL include scope support metadata in addition to path metadata.
|
||||
|
||||
#### Scenario: Scope support metadata present
|
||||
- **WHEN** a tool entry is defined in `AI_TOOLS`
|
||||
- **THEN** it MAY declare supported install scopes for skills and commands
|
||||
- **AND** this metadata SHALL be used for effective scope resolution
|
||||
|
||||
#### Scenario: Scope support metadata absent
|
||||
- **WHEN** a tool entry in `AI_TOOLS` omits scope support metadata for a surface
|
||||
- **THEN** resolver behavior SHALL default that surface to project-only support
|
||||
- **AND** effective scope resolution SHALL apply normal preferred/fallback rules against that default
|
||||
|
||||
### Requirement: Path configuration for supported tools
|
||||
Path metadata SHALL support both project and global install targets via resolver logic.
|
||||
|
||||
#### Scenario: Project scope path
|
||||
- **WHEN** effective scope is `project` for skills
|
||||
- **THEN** `skillsDir` SHALL be treated as a tool-specific container path under project root
|
||||
- **AND** managed skill artifacts SHALL be written under `<projectRoot>/<skillsDir>/skills/`
|
||||
- **AND** tool definitions SHALL set `skillsDir` accordingly (for example `.openspec` -> `.openspec/skills/`)
|
||||
|
||||
#### Scenario: Global scope path
|
||||
- **WHEN** effective scope is `global` for a supported tool/surface
|
||||
- **THEN** paths SHALL resolve to tool-specific global directories
|
||||
- **AND** environment overrides (for example `CODEX_HOME`) SHALL be respected where applicable
|
||||
|
||||
#### Scenario: Windows global path resolution for Codex commands
|
||||
- **WHEN** effective scope is `global`
|
||||
- **AND** tool is Codex
|
||||
- **AND** platform is Windows
|
||||
- **THEN** command targets SHALL resolve to `%CODEX_HOME%\prompts` when `CODEX_HOME` is set
|
||||
- **AND** SHALL otherwise resolve to `%USERPROFILE%\.codex\prompts`
|
||||
@@ -1,21 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Install scope configuration via profile flow
|
||||
The config profile workflow SHALL allow users to configure install scope preference.
|
||||
|
||||
#### Scenario: Interactive profile includes install scope
|
||||
- **WHEN** user runs `openspec config profile`
|
||||
- **THEN** the interactive flow SHALL include install scope selection with values `global` and `project`
|
||||
- **AND** the currently configured value SHALL be pre-selected
|
||||
|
||||
#### Scenario: Save install scope
|
||||
- **WHEN** user confirms config profile changes
|
||||
- **THEN** selected install scope SHALL be saved to global config
|
||||
|
||||
### Requirement: Install scope visibility in config output
|
||||
The config command SHALL display install scope preference in human-readable output.
|
||||
|
||||
#### Scenario: Config list shows install scope
|
||||
- **WHEN** user runs `openspec config list`
|
||||
- **THEN** output SHALL include current install scope value
|
||||
- **AND** indicate whether value is default or explicit
|
||||
@@ -1,28 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Init install scope selection
|
||||
The init command SHALL support install scope selection for generated artifacts.
|
||||
|
||||
#### Scenario: Scope defaults to global
|
||||
- **WHEN** user runs `openspec init` without explicit scope override
|
||||
- **THEN** init SHALL use global config install scope
|
||||
- **AND** if unset, SHALL resolve migration-aware default (`global` for newly created configs, `project` for legacy schema-evolved configs)
|
||||
|
||||
#### Scenario: Scope override via flag
|
||||
- **WHEN** user runs `openspec init --scope project`
|
||||
- **THEN** init SHALL use `project` as preferred scope for that run
|
||||
- **AND** SHALL NOT mutate persisted global config unless user explicitly changes config
|
||||
|
||||
### Requirement: Init uses effective scope resolution
|
||||
The init command SHALL resolve effective scope per tool surface before generating files.
|
||||
|
||||
#### Scenario: Effective scope with fallback
|
||||
- **WHEN** selected tool/surface does not support preferred scope
|
||||
- **AND** supports alternate scope
|
||||
- **THEN** init SHALL generate files at alternate effective scope
|
||||
- **AND** SHALL display fallback note in summary
|
||||
|
||||
#### Scenario: Unsupported scope selection
|
||||
- **WHEN** selected tool/surface supports neither preferred nor alternate scope
|
||||
- **THEN** init SHALL fail before writing files
|
||||
- **AND** SHALL provide clear error guidance
|
||||
@@ -1,34 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Update install scope selection
|
||||
The update command SHALL support install scope selection for sync operations.
|
||||
|
||||
#### Scenario: Scope defaults to global config value
|
||||
- **WHEN** user runs `openspec update` without explicit scope override
|
||||
- **THEN** update SHALL use configured install scope
|
||||
- **AND** if unset, SHALL resolve migration-aware default (`global` for newly created configs, `project` for legacy schema-evolved configs)
|
||||
|
||||
#### Scenario: Scope override via flag
|
||||
- **WHEN** user runs `openspec update --scope project`
|
||||
- **THEN** update SHALL use `project` as preferred scope for that run
|
||||
|
||||
### Requirement: Scope-aware sync and drift detection
|
||||
The update command SHALL evaluate configured state and drift using effective scoped paths.
|
||||
|
||||
#### Scenario: Scoped drift detection
|
||||
- **WHEN** update evaluates whether tools are up-to-date
|
||||
- **THEN** it SHALL inspect files at effective scoped targets for each tool/surface
|
||||
- **AND** SHALL compare current resolved scope against last successful effective scope for each tool/surface
|
||||
- **AND** SHALL treat a difference as sync-required drift
|
||||
|
||||
#### Scenario: Scope fallback during update
|
||||
- **WHEN** preferred scope is unsupported for a configured tool/surface
|
||||
- **AND** alternate scope is supported
|
||||
- **THEN** update SHALL apply fallback scope resolution
|
||||
- **AND** SHALL report fallback in output
|
||||
|
||||
#### Scenario: Unsupported scope during update
|
||||
- **WHEN** configured tool/surface supports neither preferred nor alternate scope
|
||||
- **THEN** scope support SHALL be validated for all configured tools/surfaces before any write
|
||||
- **AND** update SHALL fail without performing file writes when incompatibilities are detected
|
||||
- **AND** SHALL report incompatible tools with remediation steps
|
||||
@@ -1,22 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: ToolCommandAdapter interface
|
||||
The system SHALL provide install-context-aware command path resolution.
|
||||
|
||||
#### Scenario: Adapter interface structure
|
||||
- **WHEN** implementing a tool adapter
|
||||
- **THEN** command file path resolution SHALL receive install context (including effective scope and environment context)
|
||||
- **AND** SHALL return the effective command output path for that context
|
||||
|
||||
#### Scenario: Codex global path remains supported
|
||||
- **WHEN** resolving Codex command paths in global scope
|
||||
- **THEN** the adapter SHALL target `$CODEX_HOME/prompts` when `CODEX_HOME` is set
|
||||
- **AND** SHALL otherwise target `~/.codex/prompts`
|
||||
|
||||
### Requirement: Command generator function
|
||||
The command generator SHALL pass install context into adapter path resolution for all generated commands.
|
||||
|
||||
#### Scenario: Scoped command generation
|
||||
- **WHEN** generating commands for a tool with a resolved effective scope
|
||||
- **THEN** generated command paths SHALL match that effective scope
|
||||
- **AND** the formatted command body/frontmatter behavior SHALL remain tool-specific and unchanged
|
||||
@@ -1,24 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Install scope field in global config
|
||||
The global config schema SHALL include install scope preference.
|
||||
|
||||
#### Scenario: Config shape supports install scope
|
||||
- **WHEN** reading or writing global config
|
||||
- **THEN** config SHALL support `installScope` with allowed values `global` and `project`
|
||||
|
||||
#### Scenario: Schema evolution default
|
||||
- **WHEN** loading legacy config without `installScope`
|
||||
- **THEN** the system SHALL preserve schema compatibility without mutating the file
|
||||
- **AND** effective install scope SHALL resolve to `project` until user explicitly sets `installScope`
|
||||
- **AND** preserve all other existing fields
|
||||
|
||||
#### Scenario: New config default
|
||||
- **WHEN** creating a new global config
|
||||
- **THEN** the system SHALL persist `installScope: global` by default
|
||||
- **AND** users MAY switch to `project` explicitly
|
||||
|
||||
#### Scenario: Invalid install scope value
|
||||
- **WHEN** config validation receives an invalid install scope value
|
||||
- **THEN** the value SHALL be rejected
|
||||
- **AND** the system SHALL preserve the existing valid configuration
|
||||
@@ -1,71 +0,0 @@
|
||||
## Purpose
|
||||
|
||||
Define the install scope model for OpenSpec-generated skills and commands, including scope preference, effective scope resolution, and fallback/error semantics.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Install scope preference model
|
||||
The system SHALL support a user-level install scope preference with values `global` and `project`.
|
||||
|
||||
#### Scenario: Default install scope
|
||||
- **WHEN** install scope is not explicitly configured
|
||||
- **THEN** the system SHALL resolve a migration-aware default:
|
||||
- **AND** use `global` for newly created configs
|
||||
- **AND** use `project` for legacy schema-evolved configs until explicit migration
|
||||
|
||||
#### Scenario: Explicit install scope
|
||||
- **WHEN** user configures install scope to `project`
|
||||
- **THEN** generation and update flows SHALL use `project` as the preferred scope
|
||||
|
||||
### Requirement: Effective scope resolution by tool surface
|
||||
The system SHALL compute effective scope per tool surface (skills, commands) based on preferred scope and tool capability support.
|
||||
|
||||
#### Scenario: Preferred scope is supported
|
||||
- **WHEN** preferred scope is supported for a tool surface
|
||||
- **THEN** the system SHALL use that scope as the effective scope
|
||||
|
||||
#### Scenario: Preferred scope is unsupported but alternate is supported
|
||||
- **WHEN** preferred scope is not supported for a tool surface
|
||||
- **AND** the alternate scope is supported
|
||||
- **THEN** the system SHALL use the alternate scope as effective scope
|
||||
- **AND** SHALL record a fallback note for user-facing output
|
||||
|
||||
#### Scenario: No supported scope
|
||||
- **WHEN** neither `global` nor `project` is supported for a tool surface
|
||||
- **THEN** the command SHALL fail before writing files
|
||||
- **AND** SHALL display actionable remediation
|
||||
|
||||
### Requirement: Effective scope reporting
|
||||
The system SHALL report effective scope decisions in command output when they differ from the preferred scope.
|
||||
|
||||
#### Scenario: Fallback reporting
|
||||
- **WHEN** fallback resolution occurs for any selected/configured tool surface
|
||||
- **THEN** init/update summaries SHALL include effective scope notes per affected tool
|
||||
|
||||
### Requirement: Cross-platform path behavior
|
||||
Install scope resolution SHALL produce platform-correct target paths.
|
||||
|
||||
#### Scenario: Global scope path on Windows
|
||||
- **WHEN** effective scope is `global`
|
||||
- **AND** the command runs on Windows
|
||||
- **THEN** resolved target paths SHALL use Windows path conventions and separators
|
||||
- **AND** SHALL NOT reuse POSIX-style home-relative defaults directly
|
||||
|
||||
### Requirement: Cleanup safety for scope transitions
|
||||
Scope transitions SHALL update new targets first and clean old managed targets safely.
|
||||
|
||||
#### Scenario: Automatic cleanup for managed files on scope change
|
||||
- **WHEN** update or init applies a scope transition for a configured tool/surface
|
||||
- **THEN** the system SHALL write new artifacts in the new effective scope before cleanup
|
||||
- **AND** SHALL automatically remove only OpenSpec-managed files in the previous effective scope
|
||||
|
||||
#### Scenario: Cleanup scope boundaries
|
||||
- **WHEN** cleanup runs after a scope transition
|
||||
- **THEN** the system SHALL leave non-managed files untouched
|
||||
- **AND** SHALL limit removal scope to the affected tool/workflow-managed paths
|
||||
|
||||
#### Scenario: Cleanup failure after successful writes
|
||||
- **WHEN** new artifacts were written successfully in the new scope
|
||||
- **AND** cleanup of old managed targets fails
|
||||
- **THEN** the command SHALL report failure with leftover cleanup paths
|
||||
- **AND** SHALL NOT rollback successfully written new-scope artifacts
|
||||
@@ -1,61 +0,0 @@
|
||||
## 1. Global Config + Validation
|
||||
|
||||
- [ ] 1.1 Add `installScope` (`global` | `project`) to `GlobalConfig` with explicit `global` default for newly created configs
|
||||
- [ ] 1.2 Update config schema validation and known-key checks to include install scope
|
||||
- [ ] 1.3 Add schema-evolution tests ensuring missing `installScope` in legacy configs resolves to effective `project` until explicit migration
|
||||
- [ ] 1.4 Extend `openspec config list` output to show install scope and source (`explicit`, `new-default`, `legacy-default`)
|
||||
|
||||
## 2. Tool Capability Metadata + Resolvers
|
||||
|
||||
- [ ] 2.1 Extend `AI_TOOLS` metadata to declare scope support per surface (skills/commands)
|
||||
- [ ] 2.2 Add shared install-target resolver for skills and commands using requested scope + tool support
|
||||
- [ ] 2.3 Implement deterministic fallback/error behavior when preferred scope is unsupported, including default behavior when scope support metadata is absent
|
||||
- [ ] 2.4 Add unit tests for scope resolution (preferred, fallback, and hard-fail paths)
|
||||
|
||||
## 3. Command Generation Contract
|
||||
|
||||
- [ ] 3.1 Update `ToolCommandAdapter` path contract to accept install context
|
||||
- [ ] 3.2 Update `generateCommand`/`generateCommands` to pass context through adapters
|
||||
- [ ] 3.3 Migrate all command adapters to the new path contract
|
||||
- [ ] 3.4 Update adapter tests for scoped path behavior (including Codex global path semantics)
|
||||
|
||||
## 4. Init Command Scope Support
|
||||
|
||||
- [ ] 4.1 Add scope override flag to `openspec init` (`--scope global|project`)
|
||||
- [ ] 4.2 Resolve effective scope per tool/surface before writing artifacts
|
||||
- [ ] 4.3 Apply scope-aware generation/removal planning for skills and commands
|
||||
- [ ] 4.4 Surface effective scope decisions and fallback notes in init summary output
|
||||
- [ ] 4.5 Add init tests for global default, project override, and fallback/error scenarios
|
||||
|
||||
## 5. Update Command Scope Support
|
||||
|
||||
- [ ] 5.1 Add scope override flag to `openspec update` (`--scope global|project`)
|
||||
- [ ] 5.2 Make configured-tool detection and drift checks scope-aware
|
||||
- [ ] 5.3 Persist and read last successful effective scope per tool/surface for deterministic scope-drift detection
|
||||
- [ ] 5.4 Apply scope-aware sync/removal with consistent fallback/error behavior
|
||||
- [ ] 5.5 Ensure scope changes update managed files in new targets and clean old managed targets safely
|
||||
- [ ] 5.6 Add update tests for global/project/fallback/error and repeat-run idempotency
|
||||
|
||||
## 6. Config UX
|
||||
|
||||
- [ ] 6.1 Extend `openspec config profile` interactive flow to select install scope
|
||||
- [ ] 6.2 Preserve install scope when using preset shortcuts unless explicitly changed
|
||||
- [ ] 6.3 Ensure non-interactive config behavior remains deterministic with clear errors
|
||||
- [ ] 6.4 Add/adjust config command tests for install scope flows
|
||||
- [ ] 6.5 Add migration UX for legacy users to opt into `global` scope explicitly
|
||||
|
||||
## 7. Documentation
|
||||
|
||||
- [ ] 7.1 Update `docs/supported-tools.md` with scope behavior and effective-scope fallback notes
|
||||
- [ ] 7.2 Update `docs/cli.md` examples for init/update scope options
|
||||
- [ ] 7.3 Document cross-project implications of global installs
|
||||
- [ ] 7.4 Add existing-user migration guide covering legacy-default behavior and explicit opt-in to `installScope: global`
|
||||
|
||||
## 8. Verification
|
||||
|
||||
- [ ] 8.1 Run targeted tests for config, adapters, init, and update
|
||||
- [ ] 8.2 Run full test suite (`pnpm test`) and resolve regressions
|
||||
- [ ] 8.3 Manual smoke test: init/update with `installScope=global`
|
||||
- [ ] 8.4 Manual smoke test: init/update with `--scope project`
|
||||
- [ ] 8.5 Verify path resolution behavior on Windows CI (or cross-platform unit tests with mocked Windows paths)
|
||||
- [ ] 8.6 Verify combined behavior matrix for mixed tools across scope × delivery × command-surface capability
|
||||
@@ -1,2 +0,0 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-20
|
||||
@@ -1,45 +0,0 @@
|
||||
## Why
|
||||
|
||||
We need a faster, more reliable way to manually validate CLI behavior changes like profile/delivery sync, migration behavior, and tool-detection UX.
|
||||
|
||||
Today, manual review is mostly ad hoc: each developer sets up state differently, runs a different command order, and checks outputs informally. This makes regressions easy to miss and slows iteration on CLI UX work.
|
||||
|
||||
An 80/20 solution is to add a lightweight smoke harness for deterministic non-interactive flows, plus a short manual checklist for interactive prompt behavior.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a lightweight QA smoke harness for OpenSpec CLI behavior with isolated per-run sandbox state
|
||||
- Use `Makefile` targets as the primary entrypoint:
|
||||
- `make qa` (default local QA entrypoint)
|
||||
- `make qa-smoke` (deterministic non-interactive suite)
|
||||
- `make qa-interactive` (prints/opens manual interactive checklist)
|
||||
- Implement smoke logic in a script (invoked by Make targets), not in Make itself
|
||||
- Ensure each scenario runs in an isolated sandbox with temporary `HOME`, `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, and `CODEX_HOME`
|
||||
- Capture scenario artifacts for inspection (command output, exit code, and before/after filesystem state)
|
||||
- Add a focused scenario set for high-risk behavior:
|
||||
- init core output generation
|
||||
- non-interactive detected-tool behavior
|
||||
- migration when profile is unset
|
||||
- delivery cleanup (`both -> skills`, `both -> commands`)
|
||||
- commands-only update detection
|
||||
- new tool directory detection messaging
|
||||
- invalid profile override validation
|
||||
- Add a short interactive checklist for keypress/prompt UX verification (Space toggle, Enter confirm, detected pre-selection)
|
||||
- Wire CI to run the smoke suite on Linux as a fast regression gate
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `qa-smoke-harness`: Deterministic, sandboxed CLI smoke validation with a single developer entrypoint
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `developer-qa-workflow`: Standardized local/CI QA flow for CLI behavior and migration-sensitive scenarios
|
||||
|
||||
## Impact
|
||||
|
||||
- `Makefile` - Add `qa`, `qa-smoke`, and `qa-interactive` targets
|
||||
- `scripts/qa-smoke.sh` (or equivalent) - Implement sandbox setup, scenario execution, and assertions
|
||||
- `docs/` - Add/update contributor-facing QA instructions and interactive checklist usage
|
||||
- CI workflow - Add smoke target execution as a lightweight regression gate
|
||||
@@ -1,49 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Makefile QA Entry Point
|
||||
|
||||
The repository SHALL provide Makefile targets as the primary developer entrypoint for CLI QA flows.
|
||||
|
||||
#### Scenario: Default QA target runs smoke suite
|
||||
|
||||
- **WHEN** a developer runs `make qa`
|
||||
- **THEN** the command SHALL execute the non-interactive smoke suite
|
||||
- **AND** exit with status code 0 only when all smoke scenarios pass
|
||||
|
||||
#### Scenario: Smoke suite target is directly invokable
|
||||
|
||||
- **WHEN** a developer runs `make qa-smoke`
|
||||
- **THEN** the command SHALL execute the same smoke suite used by `make qa`
|
||||
- **AND** return a non-zero exit code on assertion failure
|
||||
|
||||
#### Scenario: Interactive checklist target exists
|
||||
|
||||
- **WHEN** a developer runs `make qa-interactive`
|
||||
- **THEN** the command SHALL provide the manual interactive verification checklist
|
||||
- **AND** SHALL NOT run interactive prompt automation by default
|
||||
|
||||
### Requirement: Sandboxed Smoke Scenario Runner
|
||||
|
||||
The smoke suite SHALL run CLI scenarios in isolated sandboxes so tests are repeatable and do not depend on machine-global state.
|
||||
|
||||
#### Scenario: Scenario execution is environment-isolated
|
||||
|
||||
- **WHEN** a smoke scenario runs
|
||||
- **THEN** it SHALL use temporary values for `HOME`, `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, and `CODEX_HOME`
|
||||
- **AND** global config from the host machine SHALL NOT affect scenario outcomes
|
||||
|
||||
#### Scenario: Scenario artifacts are captured for review
|
||||
|
||||
- **WHEN** a smoke scenario completes
|
||||
- **THEN** the runner SHALL capture command output and exit status
|
||||
- **AND** SHALL capture enough filesystem state to inspect before/after behavior
|
||||
|
||||
#### Scenario: High-risk workflow coverage exists
|
||||
|
||||
- **WHEN** the smoke suite executes
|
||||
- **THEN** it SHALL include scenarios covering profile/delivery behavior and migration-sensitive flows
|
||||
- **AND** include at least:
|
||||
- non-interactive tool detection
|
||||
- migration when profile is unset
|
||||
- delivery cleanup (`both -> skills`, `both -> commands`)
|
||||
- commands-only update detection
|
||||
@@ -1,2 +0,0 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-19
|
||||
@@ -1,111 +0,0 @@
|
||||
## Why
|
||||
|
||||
OpenSpec currently assumes command delivery maps directly to command adapters. That assumption does not hold for all tools.
|
||||
|
||||
Trae is a concrete example: it invokes OpenSpec workflows via skill entries (for example `/openspec-new-change`) rather than adapter-generated command files. In this model, skills are the command surface.
|
||||
|
||||
Today, this creates a behavior gap:
|
||||
|
||||
- `delivery=commands` can remove skills
|
||||
- tools without adapters skip command generation
|
||||
- result: selected tools like Trae can end up with no invocable workflow artifacts
|
||||
|
||||
This is more than a prompt UX issue because non-interactive and CI flows bypass interactive guidance. We need a capability-aware model in core generation logic.
|
||||
|
||||
## What Changes
|
||||
|
||||
### 1. Add explicit command-surface capability metadata
|
||||
|
||||
Add an optional field in tool metadata to describe how a tool exposes commands:
|
||||
|
||||
- `adapter`: command files are generated through a command adapter
|
||||
- `skills-invocable`: skills are directly invocable as commands
|
||||
- `none`: no OpenSpec command surface
|
||||
|
||||
Field should be optional. Default behavior is inferred from adapter registry presence: tools with a registered adapter resolve to `adapter`; tools with no adapter registration and no explicit annotation resolve to `none`.
|
||||
Capability values use kebab-case string tokens for consistency with serialized metadata conventions.
|
||||
|
||||
Initial explicit override:
|
||||
|
||||
- Trae -> `skills-invocable`
|
||||
|
||||
### 2. Make delivery behavior capability-aware
|
||||
|
||||
Update `init` and `update` to compute effective artifact actions per tool from:
|
||||
|
||||
- global delivery (`both | skills | commands`)
|
||||
- tool command surface capability
|
||||
|
||||
Behavior matrix:
|
||||
|
||||
- `both`:
|
||||
- generate skills for all tools with `skillsDir` (including `skills-invocable`)
|
||||
- generate command files only for `adapter` tools
|
||||
- `none`: no artifact action; MAY emit compatibility warning
|
||||
- `skills`:
|
||||
- generate skills for all tools with `skillsDir` (including `skills-invocable`)
|
||||
- remove adapter-generated command files
|
||||
- `none`: no artifact action; MAY emit compatibility warning
|
||||
- `commands`:
|
||||
- `adapter`: generate commands, remove skills
|
||||
- `skills-invocable`: generate (or keep if up-to-date) skills as command surface; do not remove them
|
||||
- `none`: fail fast with clear error
|
||||
|
||||
### 3. Add preflight validation and clearer output
|
||||
|
||||
Before writing/removing artifacts, validate selected/configured tools against delivery mode:
|
||||
|
||||
- interactive flow: show clear compatibility note before confirmation
|
||||
- non-interactive flow: fail with deterministic error listing incompatible tools and supported alternatives
|
||||
|
||||
Update summaries to show effective delivery outcomes per tool (for example, when commands mode still installs skills for skills-invocable tools).
|
||||
|
||||
### 4. Update docs and tests
|
||||
|
||||
- document capability model and Trae behavior under delivery modes
|
||||
- ensure CLI docs and supported-tools docs reflect effective behavior
|
||||
- add test coverage for:
|
||||
- `init --tools trae` with `delivery=commands`
|
||||
- `update` with Trae configured under `delivery=commands`
|
||||
- mixed selections (`claude + trae`) across all delivery modes
|
||||
- explicit error path for tools with no command surface under `delivery=commands`
|
||||
|
||||
### 5. Coordinate with install-scope behavior
|
||||
|
||||
When combined with `add-global-install-scope`, init/update planning must compose:
|
||||
|
||||
- install scope (`global | project`)
|
||||
- delivery mode (`both | skills | commands`)
|
||||
- command surface capability (`adapter | skills-invocable | none`)
|
||||
|
||||
Implementation tests should cover mixed-tool matrices to ensure deterministic behavior when both changes are active.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `tool-command-surface`: Capability model that classifies tools as `adapter`, `skills-invocable`, or `none` to drive delivery behavior
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `cli-init`: Delivery handling becomes tool-capability-aware with preflight compatibility validation
|
||||
- `cli-update`: Delivery sync becomes tool-capability-aware with consistent compatibility validation and messaging
|
||||
- `supported-tools-docs`: Documents command-surface semantics for non-adapter tools
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/config.ts` - add optional command-surface metadata and Trae override
|
||||
- `src/core/command-generation/registry.ts` (or shared helper) - capability inference from adapter presence
|
||||
- `src/core/init.ts` - capability-aware generation/removal planning + compatibility validation + summary messaging
|
||||
- `src/core/update.ts` - capability-aware sync/removal planning + compatibility validation + summary messaging
|
||||
- `src/core/shared/tool-detection.ts` - include capability-aware detection so `skills-invocable` tools remain detectable under `delivery=commands`, and `none` tools are excluded from command-surface artifact detection
|
||||
- `docs/supported-tools.md` and `docs/cli.md` - document delivery behavior and compatibility notes
|
||||
- `test/core/init.test.ts` and `test/core/update.test.ts` - add coverage for skills-invocable behavior and mixed-tool delivery scenarios
|
||||
|
||||
## Sequencing Notes
|
||||
|
||||
- This change is intended to stack safely with `simplify-skill-installation` by introducing additive, capability-specific requirements for init/update.
|
||||
- If `simplify-skill-installation` merges first, this change should be rebased and keep the capability-aware rule as the source of truth for `delivery=commands` behavior on `skills-invocable` tools.
|
||||
- If this change merges first, the `simplify-skill-installation` branch should be rebased to avoid re-introducing a global "commands-only means no skills for all tools" assumption.
|
||||
- If `add-global-install-scope` merges first, this change should be rebased to compose capability-aware behavior on top of scope-resolved path decisions from that change.
|
||||
- If this change merges first, `add-global-install-scope` should be rebased to preserve Section 5 composition rules (`install scope` + `delivery mode` + `command surface capability`) without overriding capability-aware command-surface outcomes.
|
||||
@@ -1,121 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Command surface capability resolution
|
||||
The init command SHALL resolve each selected tool's command surface using explicit metadata first, then deterministic inference.
|
||||
|
||||
#### Scenario: Explicit command surface override
|
||||
- **WHEN** a tool declares an explicit command-surface capability
|
||||
- **THEN** init SHALL use that explicit capability
|
||||
- **AND** SHALL NOT override it based on adapter presence
|
||||
|
||||
#### Scenario: Inferred command surface from adapter presence
|
||||
- **WHEN** a tool does not declare an explicit command-surface capability
|
||||
- **AND** a command adapter is registered for the tool
|
||||
- **THEN** init SHALL infer `adapter` as the command surface
|
||||
|
||||
#### Scenario: Inferred command surface for skills-only tool
|
||||
- **WHEN** a tool does not declare an explicit command-surface capability
|
||||
- **AND** no command adapter is registered for the tool
|
||||
- **AND** the tool has a configured `skillsDir`
|
||||
- **THEN** init SHALL infer `skills-invocable` as the command surface
|
||||
|
||||
#### Scenario: Inferred command surface without adapter or skills
|
||||
- **WHEN** a tool does not declare an explicit command-surface capability
|
||||
- **AND** no command adapter is registered for the tool
|
||||
- **AND** the tool has no `skillsDir`
|
||||
- **THEN** init SHALL infer `none` as the command surface
|
||||
|
||||
### Requirement: Delivery compatibility by tool command surface
|
||||
The init command SHALL apply delivery settings using each tool's command surface capability, not adapter presence alone.
|
||||
|
||||
#### Scenario: Both delivery for adapter-backed tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool that has a command adapter
|
||||
- **AND** delivery is set to `both`
|
||||
- **THEN** the system SHALL generate command files for active workflows using that adapter
|
||||
- **AND** SHALL generate or refresh managed skills when the tool has `skillsDir`
|
||||
|
||||
#### Scenario: Both delivery for skills-invocable tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `skills-invocable`
|
||||
- **AND** delivery is set to `both`
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories when the tool has `skillsDir`
|
||||
- **AND** SHALL NOT require adapter-generated command files for that tool
|
||||
|
||||
#### Scenario: Both delivery for none command surface
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `none`
|
||||
- **AND** delivery is set to `both`
|
||||
- **THEN** the system SHALL perform no command-surface artifact action for that tool
|
||||
- **AND** MAY emit a compatibility note indicating no command surface is available
|
||||
|
||||
#### Scenario: Skills delivery for adapter-backed tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool that has a command adapter
|
||||
- **AND** delivery is set to `skills`
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories when the tool has `skillsDir`
|
||||
- **AND** SHALL remove managed adapter-generated command files for that tool
|
||||
|
||||
#### Scenario: Skills delivery for skills-invocable tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `skills-invocable`
|
||||
- **AND** delivery is set to `skills`
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories when the tool has `skillsDir`
|
||||
- **AND** SHALL NOT require adapter-generated command files for that tool
|
||||
|
||||
#### Scenario: Skills delivery for none command surface
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `none`
|
||||
- **AND** delivery is set to `skills`
|
||||
- **THEN** the system SHALL perform no command-surface artifact action for that tool
|
||||
- **AND** MAY emit a compatibility note indicating no command surface is available
|
||||
|
||||
#### Scenario: Commands delivery for adapter-backed tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool that has a command adapter
|
||||
- **AND** delivery is set to `commands`
|
||||
- **THEN** the system SHALL generate command files for active workflows using that adapter
|
||||
- **AND** the system SHALL remove managed skill directories for that tool
|
||||
|
||||
#### Scenario: Commands delivery for skills-invocable tool
|
||||
- **WHEN** user runs `openspec init` with a selected tool whose command surface is `skills-invocable`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories for active workflows
|
||||
- **AND** the system SHALL NOT remove those managed skill directories as part of commands-only cleanup
|
||||
- **AND** the system SHALL NOT require a command adapter for that tool
|
||||
|
||||
#### Scenario: Commands delivery for mixed tool selection
|
||||
- **WHEN** user runs `openspec init` with multiple tools
|
||||
- **AND** selected tools include both adapter-backed and skills-invocable command surfaces
|
||||
- **AND** delivery is set to `commands`
|
||||
- **THEN** the system SHALL apply commands-only behavior per tool capability
|
||||
- **AND** the resulting install SHALL include command files for adapter-backed tools and skills for skills-invocable tools
|
||||
|
||||
#### Scenario: Commands delivery for unsupported command surface
|
||||
- **WHEN** user runs `openspec init` with a selected tool that has no command surface capability
|
||||
- **AND** delivery is set to `commands`
|
||||
- **THEN** the system SHALL fail before generating or deleting artifacts
|
||||
- **AND** the error SHALL list incompatible tool IDs and explain supported alternatives (`both` or `skills`)
|
||||
|
||||
#### Scenario: Interactive handling for unsupported command surface
|
||||
- **WHEN** user runs `openspec init` interactively
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** selected tools include one or more tools with command surface `none`
|
||||
- **THEN** the CLI SHALL show a compatibility error and return to the interactive selection flow for correction
|
||||
- **AND** SHALL not perform artifact writes until a valid selection is confirmed
|
||||
|
||||
### Requirement: Init compatibility signaling
|
||||
The init command SHALL clearly signal command-surface compatibility outcomes in both interactive and non-interactive flows.
|
||||
|
||||
#### Scenario: Interactive compatibility note
|
||||
- **WHEN** init runs interactively
|
||||
- **AND** delivery is `commands`
|
||||
- **AND** selected tools include skills-invocable command surfaces
|
||||
- **THEN** the system SHALL display a compatibility note before the confirmation prompt indicating those tools will use skills as their command surface
|
||||
|
||||
#### Scenario: Non-interactive compatibility summary for skills-invocable tools
|
||||
- **WHEN** init runs non-interactively (including `--tools` usage)
|
||||
- **AND** delivery is `commands`
|
||||
- **AND** selected tools include one or more `skills-invocable` command surfaces
|
||||
- **THEN** the command SHALL proceed with exit code 0
|
||||
- **AND** the command SHALL write deterministic compatibility summary lines to stdout indicating those tools will use managed skills as their command surface
|
||||
|
||||
#### Scenario: Non-interactive compatibility failure
|
||||
- **WHEN** init runs non-interactively (including `--tools` usage)
|
||||
- **AND** delivery is `commands`
|
||||
- **AND** selected tools include any tool with no command surface capability
|
||||
- **THEN** the command SHALL exit with code 1
|
||||
- **AND** the command SHALL write deterministic, actionable guidance for resolving the selection to stderr
|
||||
@@ -1,48 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Delivery sync by command surface capability
|
||||
The update command SHALL synchronize artifacts using each configured tool's command surface capability.
|
||||
|
||||
#### Scenario: Commands delivery for adapter-backed configured tool
|
||||
- **WHEN** user runs `openspec update`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** a configured tool has an adapter-backed command surface
|
||||
- **THEN** the system SHALL generate or refresh command files for active workflows
|
||||
- **AND** the system SHALL remove managed skill directories for that tool
|
||||
|
||||
#### Scenario: Commands delivery for skills-invocable configured tool
|
||||
- **WHEN** user runs `openspec update`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** a configured tool has `skills-invocable` command surface capability
|
||||
- **THEN** the system SHALL generate or refresh managed skill directories for active workflows
|
||||
- **AND** the system SHALL NOT remove those managed skill directories as part of commands-only cleanup
|
||||
- **AND** the system SHALL NOT attempt to require adapter-generated command files for that tool
|
||||
|
||||
#### Scenario: Commands delivery with unsupported command surface
|
||||
- **WHEN** user runs `openspec update`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** a configured tool has no command surface capability
|
||||
- **THEN** the system SHALL fail with exit code 1 before applying partial updates
|
||||
- **AND** the output SHALL identify incompatible tools and recommended remediation
|
||||
|
||||
### Requirement: Configured-tool detection for skills-invocable command surfaces
|
||||
The update command SHALL treat tools with skills-invocable command surfaces as configured when managed skill artifacts are present, including under commands delivery.
|
||||
|
||||
#### Scenario: Skills-invocable tool under commands delivery
|
||||
- **WHEN** user runs `openspec update`
|
||||
- **AND** delivery is set to `commands`
|
||||
- **AND** a tool has no adapter-generated command files
|
||||
- **AND** that tool is marked `skills-invocable` and has managed skills installed
|
||||
- **THEN** the system SHALL include the tool in configured-tool detection
|
||||
- **AND** the system SHALL apply normal version/profile/delivery sync to that tool
|
||||
|
||||
### Requirement: Update summary reflects effective per-tool delivery
|
||||
The update command SHALL report effective artifact behavior when delivery intent and artifact type differ due to tool capability.
|
||||
|
||||
#### Scenario: Summary for skills-invocable tools in commands delivery
|
||||
- **WHEN** update completes successfully
|
||||
- **AND** delivery is `commands`
|
||||
- **AND** at least one updated tool is `skills-invocable`
|
||||
- **THEN** output SHALL include a clear note that those tools use skills as their command surface
|
||||
- **AND** output SHALL avoid implying that command generation was skipped due to an error
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
## 0. Stacking Coordination
|
||||
|
||||
- [ ] 0.1 Rebase this change on latest `main` before implementation
|
||||
- [ ] 0.2 If `simplify-skill-installation` is merged first, preserve its profile/delivery model and apply this change as a capability-aware refinement
|
||||
- [ ] 0.3 If this change merges first, ensure follow-up rebases do not reintroduce a blanket "commands = remove all skills" rule
|
||||
- [ ] 0.4 If `add-global-install-scope` is merged, verify combined scope × delivery × command-surface behavior remains deterministic
|
||||
|
||||
## 1. Tool Command-Surface Capability Model
|
||||
|
||||
- [ ] 1.1 Extend tool metadata in `src/core/config.ts` with an optional command-surface capability field
|
||||
- [ ] 1.2 Define supported capability values: `adapter`, `skills-invocable`, `none`
|
||||
- [ ] 1.3 Mark Trae as `skills-invocable`
|
||||
- [ ] 1.4 Add a shared capability resolver (explicit metadata override first, inferred fallback from adapter presence second)
|
||||
- [ ] 1.5 Add focused unit tests for capability resolution (explicit override, inferred adapter, inferred none)
|
||||
|
||||
## 2. Init: Capability-Aware Delivery Planning
|
||||
|
||||
- [ ] 2.1 Refactor init generation logic to compute per-tool effective actions (generate/remove skills and commands) instead of using only global booleans
|
||||
- [ ] 2.2 In `delivery=commands`, keep/generate skills for `skills-invocable` tools and do not remove those managed skill directories
|
||||
- [ ] 2.3 In `delivery=commands`, fail fast before writes when any selected tool resolves to `none`
|
||||
- [ ] 2.4 Update init output to clearly report effective behavior for `skills-invocable` tools (skills used as command surface)
|
||||
- [ ] 2.5 Ensure init no longer reports "no adapter" for tools intentionally using `skills-invocable`
|
||||
- [ ] 2.6 Add/adjust init tests for `delivery=commands` + `trae` (skills retained/generated, no adapter error), mixed tools (`claude,trae`) with per-tool expected outputs, and deterministic failure path for unsupported command surface (`none`)
|
||||
|
||||
## 3. Update: Capability-Aware Sync and Drift Detection
|
||||
|
||||
- [ ] 3.1 Refactor update sync logic to apply delivery behavior per tool capability (not globally per run)
|
||||
- [ ] 3.2 In `delivery=commands`, keep/generate managed skills for `skills-invocable` tools
|
||||
- [ ] 3.3 In `delivery=commands`, fail before partial updates when configured tools include a `none` command surface
|
||||
- [ ] 3.4 Update profile/delivery drift detection to avoid perpetual drift for `skills-invocable` tools under commands delivery
|
||||
- [ ] 3.5 Ensure configured-tool detection still includes `skills-invocable` tools under commands delivery when managed skills exist
|
||||
- [ ] 3.6 Update summary output so skills-invocable behavior is reported as expected behavior (not implicit skip/error)
|
||||
- [ ] 3.7 Add/adjust update tests for `delivery=commands` + configured Trae (skills retained/generated), idempotent second update (no false drift loop), mixed configured tools (`claude` + `trae`), and deterministic preflight failure for unsupported command surface (`none`)
|
||||
|
||||
## 4. UX and Error Messaging
|
||||
|
||||
- [ ] 4.1 Add interactive init compatibility note for `delivery=commands` when selected tools include `skills-invocable`
|
||||
- [ ] 4.2 Add deterministic non-interactive error text with incompatible tool IDs and suggested alternatives (`both` or `skills`)
|
||||
- [ ] 4.3 Align init and update wording so capability-related behavior/messages are consistent
|
||||
|
||||
## 5. Documentation Updates
|
||||
|
||||
- [ ] 5.1 Update `docs/supported-tools.md` to document command-surface semantics for Trae and clarify delivery interactions
|
||||
- [ ] 5.2 Update `docs/cli.md` delivery guidance to explain capability-aware behavior for `delivery=commands`
|
||||
- [ ] 5.3 Add a short troubleshooting note for "commands-only + unsupported tool" failures
|
||||
|
||||
## 6. Verification
|
||||
|
||||
- [ ] 6.1 Run targeted tests: `test/core/init.test.ts` and `test/core/update.test.ts`
|
||||
- [ ] 6.2 Run any new capability/unit test files added in this change
|
||||
- [ ] 6.3 Run full test suite (`pnpm test`) and resolve regressions
|
||||
- [ ] 6.4 Manual smoke check: `openspec init --tools trae` with `delivery=commands`
|
||||
- [ ] 6.5 Manual smoke check: mixed tools (`claude,trae`) with `delivery=commands`
|
||||
@@ -1,2 +0,0 @@
|
||||
schema: spec-driven
|
||||
created: 2026-01-30
|
||||
@@ -1,3 +0,0 @@
|
||||
# opencode-command-references
|
||||
|
||||
Transform /opsx: to /opsx- in both commands and skills for OpenCode
|
||||
@@ -1,70 +0,0 @@
|
||||
## Context
|
||||
|
||||
OpenCode is one of many supported AI tools. Each tool has:
|
||||
- A **command adapter** (in `src/core/command-generation/adapters/`) for generating tool-specific command files
|
||||
- **Skills** generated via `generateSkillContent()` in `src/core/shared/skill-generation.ts`
|
||||
|
||||
Currently:
|
||||
- Commands go through the adapter system which can transform content per-tool
|
||||
- Skills use a single shared function with no tool-specific transformation
|
||||
|
||||
The templates in `src/core/templates/skill-templates.ts` use Claude's colon-based format (`/opsx:new`) as the canonical format. Tools that use different formats need transformation at generation time.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Transform all `/opsx:` command references to `/opsx-` for OpenCode in both commands and skills
|
||||
- Create a shared, reusable transformation utility
|
||||
- Keep the transformation opt-in via a callback parameter (not hard-coded tool detection)
|
||||
|
||||
**Non-Goals:**
|
||||
- Modifying the canonical template format (templates stay with `/opsx:`)
|
||||
- Applying transformation to other tools (only OpenCode for now)
|
||||
- Creating a full adapter system for skills (overkill for current needs)
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Shared Utility Function
|
||||
|
||||
**Choice**: Create `transformToHyphenCommands()` in `src/utils/command-references.ts`
|
||||
|
||||
**Rationale**:
|
||||
- Single source of truth for the transformation logic
|
||||
- Can be used by both command adapter and skill generation
|
||||
- Easy to test in isolation
|
||||
- Follows existing utils pattern in the codebase
|
||||
|
||||
**Alternatives considered**:
|
||||
- Inline the transformation in each location - Duplicates logic, harder to maintain
|
||||
|
||||
### Decision 2: Callback Parameter for Skill Generation
|
||||
|
||||
**Choice**: Add optional `transformInstructions?: (instructions: string) => string` parameter to `generateSkillContent()`
|
||||
|
||||
**Rationale**:
|
||||
- Flexible - callers define the transformation, not the generation function
|
||||
- No coupling - `generateSkillContent()` doesn't need to know about tool formats
|
||||
- Extensible - could support other transformations in the future
|
||||
- Follows inversion of control principle
|
||||
|
||||
**Alternatives considered**:
|
||||
- Add tool ID parameter and switch on it - Creates coupling, harder to extend
|
||||
- Create skill adapter system parallel to commands - Over-engineering for current needs
|
||||
- Transform in templates directly - Breaks single-source-of-truth principle
|
||||
|
||||
### Decision 3: Apply at Generation Sites
|
||||
|
||||
**Choice**: Pass transformer in `init.ts` and `update.ts` when `tool.value === 'opencode'`
|
||||
|
||||
**Rationale**:
|
||||
- These are the only two places that generate skills
|
||||
- Simple conditional check, no new abstractions needed
|
||||
- Easy to extend to other tools if needed later
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| Other `/opsx:` patterns exist that shouldn't be transformed | All occurrences in templates are command invocations - verified by inspection |
|
||||
| Future tools may need same transformation | Utility is shared and easy to reuse; can add to other tools' generation |
|
||||
| Callback adds complexity to function signature | Optional parameter with sensible default (no transformation) |
|
||||
@@ -1,32 +0,0 @@
|
||||
## Why
|
||||
|
||||
OpenCode uses hyphen-based command syntax (`/opsx-new`) but our templates contain colon-based references (`/opsx:new`). This creates inconsistency where generated command files and skill files contain references that don't match the actual command invocation syntax, confusing both the AI and users.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Create a shared transformation utility (`transformToHyphenCommands`) for converting `/opsx:` to `/opsx-`
|
||||
- Update the OpenCode command adapter to transform body text using this utility
|
||||
- Add an optional `transformInstructions` callback parameter to `generateSkillContent()`
|
||||
- Update `init.ts` and `update.ts` to pass the transformer when generating skills for OpenCode
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
None - this is a bug fix, not a new capability.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
None - no spec-level behavior changes. This is an implementation fix in the OpenCode adapter and skill generation that doesn't change any external requirements or contracts.
|
||||
|
||||
## Impact
|
||||
|
||||
- **Code**:
|
||||
- `src/utils/command-references.ts` (new file)
|
||||
- `src/utils/index.ts` (export)
|
||||
- `src/core/shared/skill-generation.ts` (add callback parameter)
|
||||
- `src/core/command-generation/adapters/opencode.ts` (use transformer)
|
||||
- `src/core/init.ts` (pass transformer for OpenCode)
|
||||
- `src/core/update.ts` (pass transformer for OpenCode)
|
||||
- **Users**: OpenCode users will see correct `/opsx-` command references in both generated command files AND skill files
|
||||
- **Other tools**: No impact - transformation only applies to OpenCode
|
||||
@@ -1,9 +0,0 @@
|
||||
# No Spec Changes
|
||||
|
||||
This is a bug fix that doesn't modify any external requirements or contracts.
|
||||
|
||||
The proposal's Capabilities section indicates:
|
||||
- **New Capabilities**: None
|
||||
- **Modified Capabilities**: None
|
||||
|
||||
No spec files are needed for this implementation-only fix.
|
||||
@@ -1,22 +0,0 @@
|
||||
## 1. Implementation
|
||||
|
||||
- [x] 1.1 Create `src/utils/command-references.ts` with `transformToHyphenCommands()` function
|
||||
- [x] 1.2 Export `transformToHyphenCommands` from `src/utils/index.ts`
|
||||
- [x] 1.3 Update `generateSkillContent()` in `src/core/shared/skill-generation.ts` to accept optional `transformInstructions` callback
|
||||
- [x] 1.4 Update OpenCode adapter in `src/core/command-generation/adapters/opencode.ts` to use `transformToHyphenCommands()` for body text
|
||||
- [x] 1.5 Update `init.ts` to pass transformer when generating skills for OpenCode
|
||||
- [x] 1.6 Update `update.ts` to pass transformer when generating skills for OpenCode
|
||||
|
||||
## 2. Testing
|
||||
|
||||
- [x] 2.1 Create `test/utils/command-references.test.ts` with unit tests for `transformToHyphenCommands()`
|
||||
- [x] 2.2 Add test to `test/core/command-generation/adapters.test.ts` for OpenCode body transformation
|
||||
- [x] 2.3 Add test to `test/core/shared/skill-generation.test.ts` for transformer callback
|
||||
|
||||
## 3. Verification
|
||||
|
||||
- [x] 3.1 Run `npx vitest run test/utils/command-references.test.ts test/core/command-generation/adapters.test.ts test/core/shared/skill-generation.test.ts` to ensure tests pass
|
||||
- [x] 3.2 Run `pnpm run build` to ensure no TypeScript errors
|
||||
- [x] 3.3 Run `openspec init --tools opencode` in a temp directory and verify:
|
||||
- Command files in `.opencode/command/` contain `/opsx-` references (not `/opsx:`)
|
||||
- Skill files in `.opencode/skills/` contain `/opsx-` references (not `/opsx:`)
|
||||
@@ -1,2 +0,0 @@
|
||||
schema: spec-driven
|
||||
created: 2026-04-23
|
||||
@@ -1,3 +0,0 @@
|
||||
# add-kimi-cli-skills-only-support
|
||||
|
||||
Add Kimi CLI as a supported skills-only tool without a command adapter
|
||||
@@ -1,85 +0,0 @@
|
||||
## Context
|
||||
|
||||
Kimi CLI is not another Claude/Codex-style adapter target. Its extension model is built around discovered skills, not external command files:
|
||||
|
||||
- skills are discovered from `.kimi/skills/`
|
||||
- skills are exposed as `/skill:<name>`
|
||||
- no stable `.kimi/commands/` or prompt-file loading mechanism was found in the Kimi CLI codebase
|
||||
|
||||
OpenSpec's existing architecture can already represent that shape:
|
||||
|
||||
- `AI_TOOLS` can advertise a `skillsDir`
|
||||
- `init` can install skills for any selected tool with `skillsDir`
|
||||
- when command generation is attempted for a tool without an adapter, OpenSpec already records `commandsSkipped`
|
||||
|
||||
## Goals
|
||||
|
||||
- Add Kimi CLI using the same narrow `skills-only` pattern already used by Trae
|
||||
- Keep the implementation small: metadata, docs, and a focused regression test
|
||||
- Make the spec text match the current code path for adapterless tools
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- designing a Kimi-specific command adapter without upstream support
|
||||
- changing tool capability modeling across the whole generation pipeline
|
||||
- reworking `delivery=commands` behavior for all adapterless tools
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Represent Kimi CLI as an adapterless tool with `.kimi`
|
||||
|
||||
Add a new `AI_TOOLS` entry:
|
||||
|
||||
```ts
|
||||
{ name: 'Kimi CLI', value: 'kimi', available: true, successLabel: 'Kimi CLI', skillsDir: '.kimi' }
|
||||
```
|
||||
|
||||
This matches Kimi CLI's project-local skills root and lets existing init/update detection paths treat it as a supported tool.
|
||||
|
||||
### 2. Do not add a Kimi command adapter
|
||||
|
||||
No `src/core/command-generation/adapters/kimi.ts` file will be added, and the command adapter registry will remain unchanged.
|
||||
|
||||
Rationale:
|
||||
|
||||
- Kimi CLI exposes skills dynamically as `/skill:<name>`
|
||||
- the previous upstream PR stalled specifically because no legitimate adapter target was available
|
||||
- adding a fake `.kimi/commands/...` path would create behavior OpenSpec cannot justify against upstream Kimi CLI behavior
|
||||
|
||||
### 3. Document Kimi by its real invocation surface
|
||||
|
||||
Kimi documentation in OpenSpec must use Kimi's actual skill invocation form:
|
||||
|
||||
- supported-tools: no generated command files, use `/skill:openspec-*`
|
||||
- commands doc: examples such as `/skill:openspec-propose`
|
||||
|
||||
The docs must not claim generated `opsx-*` files or `/openspec-*` direct invocations for Kimi.
|
||||
|
||||
### 4. Keep the change compatible with existing Trae-style behavior
|
||||
|
||||
This change intentionally follows the current adapterless-tool behavior already present in the codebase:
|
||||
|
||||
- skills are created whenever delivery includes skills
|
||||
- command generation is skipped when no adapter exists
|
||||
- init output reports `Commands skipped for: kimi (no adapter)`
|
||||
|
||||
This keeps the Kimi change small and avoids overlapping implementation work already captured in `add-tool-command-surface-capabilities`.
|
||||
|
||||
## Test Strategy
|
||||
|
||||
Add one focused regression test in `test/core/init.test.ts`:
|
||||
|
||||
- configure `delivery=both`
|
||||
- run init with `--tools kimi`
|
||||
- verify Kimi skills are created under `.kimi/skills/...`
|
||||
- verify init reports the skipped command generation path for `kimi`
|
||||
|
||||
That test is enough for this narrow change because:
|
||||
|
||||
- adapterless update behavior already has generic coverage
|
||||
- CLI tool-id rendering is derived from `AI_TOOLS`
|
||||
- no command adapter or path formatting logic is being introduced
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
The main trade-off is scope: Kimi will inherit the current adapterless-tool behavior, including the broader limitation that `delivery=commands` is not yet capability-aware for skills-invocable tools. That is acceptable for this change because it matches the existing Trae/ForgeCode model and keeps the implementation aligned with verified Kimi CLI behavior.
|
||||
@@ -1,38 +0,0 @@
|
||||
## Why
|
||||
|
||||
OpenSpec already has user demand for Kimi CLI support, but the previous upstream attempt stalled because it assumed Kimi needed a command adapter. Local review of the Kimi CLI codebase shows a different integration surface: Kimi discovers `SKILL.md` files from `.kimi/skills/` and exposes them through `/skill:<name>`, but it does not provide a stable, file-based custom command directory like Claude Code or Codex.
|
||||
|
||||
OpenSpec already supports tools that install skills without a command adapter. Trae and ForgeCode are the existing examples. Kimi should follow the same pattern instead of introducing undocumented `.kimi/commands/...` behavior.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add Kimi CLI as a supported tool in `AI_TOOLS` with `skillsDir: '.kimi'`
|
||||
- Document Kimi CLI as a skills-only integration in supported tools and command usage docs
|
||||
- Align change specs so `cli-init` explicitly allows selected tools with `skillsDir` but no registered command adapter
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
_None._
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `ai-tool-paths`: define the `.kimi` skills root for Kimi CLI
|
||||
- `cli-init`: clarify that adapterless tools remain valid selections and skip command-file generation with an informational message
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/config.ts` - add Kimi CLI tool metadata
|
||||
- `docs/supported-tools.md` - add Kimi CLI row and tool id
|
||||
- `docs/commands.md` - document `/skill:openspec-*` usage for Kimi CLI
|
||||
- `docs/cli.md` - include `kimi` in the supported `--tools` list
|
||||
- `test/core/init.test.ts` - cover Kimi CLI as an adapterless tool during init
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Adding `src/core/command-generation/adapters/kimi.ts`
|
||||
- Defining a `.kimi/commands/...` output path
|
||||
- Changing the broader delivery model for adapterless tools under `delivery=commands`
|
||||
|
||||
That broader capability-aware delivery work is already being explored separately in `add-tool-command-surface-capabilities`. This change stays narrow and follows the existing Trae/ForgeCode pattern.
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
# ai-tool-paths Delta Specification
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Path configuration for supported tools
|
||||
|
||||
The `AI_TOOLS` array SHALL include `skillsDir` for tools that support the Agent Skills specification.
|
||||
|
||||
#### Scenario: Kimi CLI paths defined
|
||||
|
||||
- **WHEN** looking up the `kimi` tool
|
||||
- **THEN** `skillsDir` SHALL be `.kimi`
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
# cli-init Delta Specification
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Slash Command Generation
|
||||
|
||||
The command SHALL generate opsx slash commands only for selected tools that have a registered command adapter, while keeping adapterless tools valid for skill generation.
|
||||
|
||||
#### Scenario: Generating slash commands for a tool with a registered adapter
|
||||
|
||||
- **WHEN** a tool with a registered command adapter is selected during initialization
|
||||
- **THEN** create 9 slash command files using the tool's command adapter:
|
||||
- `/opsx:explore`
|
||||
- `/opsx:new`
|
||||
- `/opsx:continue`
|
||||
- `/opsx:apply`
|
||||
- `/opsx:ff`
|
||||
- `/opsx:verify`
|
||||
- `/opsx:sync`
|
||||
- `/opsx:archive`
|
||||
- `/opsx:bulk-archive`
|
||||
- **AND** use tool-specific path conventions (e.g., `.claude/commands/opsx/` for Claude)
|
||||
- **AND** include tool-specific frontmatter format
|
||||
|
||||
#### Scenario: Selected tool has no command adapter
|
||||
|
||||
- **GIVEN** a selected tool has `skillsDir` configured but no registered command adapter
|
||||
- **WHEN** initialization includes command generation
|
||||
- **THEN** skill generation for that tool SHALL still remain valid
|
||||
- **AND** command-file generation SHALL be skipped for that tool
|
||||
- **AND** the command output SHALL include `Commands skipped for: <tool-id> (no adapter)`
|
||||
|
||||
#### Scenario: Kimi CLI skips command-file generation
|
||||
|
||||
- **WHEN** the user selects Kimi CLI during initialization
|
||||
- **THEN** OpenSpec SHALL treat it as a supported tool with `skillsDir: '.kimi'`
|
||||
- **AND** command-file generation SHALL be skipped because no Kimi adapter is registered
|
||||
@@ -1,22 +0,0 @@
|
||||
## 1. Change Artifacts
|
||||
|
||||
- [x] 1.1 Write proposal, design, and spec deltas for Kimi CLI skills-only support
|
||||
|
||||
## 2. Tool Metadata
|
||||
|
||||
- [x] 2.1 Add `Kimi CLI` to `src/core/config.ts` with `value: 'kimi'` and `skillsDir: '.kimi'`
|
||||
|
||||
## 3. Documentation
|
||||
|
||||
- [x] 3.1 Update `docs/supported-tools.md` with a Kimi CLI row that clearly states there is no command adapter
|
||||
- [x] 3.2 Update `docs/commands.md` to document Kimi CLI usage via `/skill:openspec-*`
|
||||
- [x] 3.3 Update `docs/cli.md` so the supported `--tools` list includes `kimi`
|
||||
|
||||
## 4. Tests
|
||||
|
||||
- [x] 4.1 Add a targeted init regression test for `--tools kimi` under adapterless command generation
|
||||
|
||||
## 5. Validation
|
||||
|
||||
- [x] 5.1 Validate the change artifacts with `openspec validate`
|
||||
- [x] 5.2 Run targeted tests and fix any regressions
|
||||
@@ -1,208 +0,0 @@
|
||||
## Product Model
|
||||
|
||||
An OpenSpec workspace is the durable planning home for work that spans multiple repos or folders.
|
||||
|
||||
It should feel like this:
|
||||
|
||||
```text
|
||||
workspace = where related changes live
|
||||
link = a named repo or folder the workspace can plan against
|
||||
change = one feature, fix, project, or other planned piece of work
|
||||
```
|
||||
|
||||
The foundation intentionally avoids the rest of the workflow. It only defines how OpenSpec recognizes a workspace, where managed workspaces live, how linked paths are represented, and how shared state differs from local state.
|
||||
|
||||
A workspace is not a feature. It can hold many changes over time. The linked repos or folders provide planning context, while the code stays where it is.
|
||||
|
||||
## Workspace Shape
|
||||
|
||||
OpenSpec workspaces use this shape:
|
||||
|
||||
```text
|
||||
workspace-root/
|
||||
changes/ # workspace-level proposals, tasks, specs
|
||||
.openspec-workspace/
|
||||
workspace.yaml # shared workspace information
|
||||
local.yaml # this machine's paths and preferences
|
||||
```
|
||||
|
||||
The user-facing planning surface is `changes/`. The identity file that makes the directory a workspace is `.openspec-workspace/workspace.yaml`.
|
||||
|
||||
Repo-local projects keep the existing shape:
|
||||
|
||||
```text
|
||||
repo-root/
|
||||
openspec/
|
||||
specs/
|
||||
changes/
|
||||
```
|
||||
|
||||
That distinction lets a user or agent tell which surface they are working in:
|
||||
|
||||
```text
|
||||
coordination workspace -> shared cross-repo planning
|
||||
repo-local project -> repo-owned specs and implementation planning
|
||||
```
|
||||
|
||||
Users should not run repo-local `openspec init` inside the workspace root. A workspace is already an OpenSpec coordination surface; it is not a product repo adopting repo-local OpenSpec.
|
||||
|
||||
## Workspace Names
|
||||
|
||||
A workspace name is a simple folder-style identifier, not a display name.
|
||||
|
||||
The name must be usable as a folder name in the current runtime. It must not be empty, must not be `.` or `..`, and must not contain path separators.
|
||||
|
||||
OpenSpec should not maintain a cross-platform reserved-name list in this slice. Setup/create flows should let filesystem creation surface OS-specific invalid folder names, then report that failure clearly.
|
||||
|
||||
The same workspace name is stored in `.openspec-workspace/workspace.yaml`, used as the default managed workspace folder name, and used as the local registry name.
|
||||
|
||||
## Shared And Local State
|
||||
|
||||
Workspace state follows a simple sharing rule:
|
||||
|
||||
```text
|
||||
share stable link names and planning
|
||||
keep local checkout paths local
|
||||
```
|
||||
|
||||
Expected shared state:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
name: platform
|
||||
links:
|
||||
api: {}
|
||||
web: {}
|
||||
```
|
||||
|
||||
Expected local state:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
paths:
|
||||
api: /repos/api
|
||||
web: /repos/web
|
||||
```
|
||||
|
||||
Later slices can expand these shapes, but the product rule should stay stable: a shared workspace should not commit one user's absolute checkout paths.
|
||||
|
||||
OpenSpec-created workspaces should include an ignore rule for `.openspec-workspace/local.yaml` so local checkout paths are not accidentally shared. `.openspec-workspace/workspace.yaml` remains the portable workspace identity and link-name state.
|
||||
|
||||
## Workspace Location
|
||||
|
||||
OpenSpec should create managed workspaces in one standard place:
|
||||
|
||||
```text
|
||||
getGlobalDataDir()/workspaces
|
||||
```
|
||||
|
||||
That reuses existing OpenSpec data-directory behavior:
|
||||
|
||||
- `$XDG_DATA_HOME/openspec/workspaces` when `XDG_DATA_HOME` is set
|
||||
- `~/.local/share/openspec/workspaces` on Unix/macOS fallback
|
||||
- `%LOCALAPPDATA%\openspec\workspaces` on native Windows fallback
|
||||
|
||||
This slice intentionally does not define a workspace-specific environment-variable, command, or configuration override for managed workspace storage. Tests should rely on existing global data-directory controls and test helpers instead of a separate workspace-home override.
|
||||
|
||||
This is deliberately quiet. The product should not ask most users where workspaces should live.
|
||||
|
||||
OpenSpec should show the resolved workspace path after setup. Quiet defaults should avoid a prompt, not hide where planning files were created.
|
||||
|
||||
## Local Workspace Registry
|
||||
|
||||
OpenSpec should keep a lightweight local registry of known workspaces:
|
||||
|
||||
```text
|
||||
getGlobalDataDir()/workspaces/registry.yaml
|
||||
```
|
||||
|
||||
Expected registry state:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
workspaces:
|
||||
platform: /Users/tabish/.local/share/openspec/workspaces/platform
|
||||
checkout: /Users/tabish/.local/share/openspec/workspaces/checkout
|
||||
```
|
||||
|
||||
The registry is a local index, not the source of truth. It exists so workspace commands can work from anywhere, show a picker when multiple workspaces exist, and list known workspaces without scanning arbitrary folders.
|
||||
|
||||
Each workspace folder remains authoritative for its own `.openspec-workspace/workspace.yaml` and `.openspec-workspace/local.yaml`. If a registry entry points at a missing or invalid workspace, later check/list flows can report that and suggest a repair.
|
||||
|
||||
## Windows And WSL2
|
||||
|
||||
Path behavior is runtime-local:
|
||||
|
||||
- PowerShell/native Windows uses Windows paths and Windows data-directory fallback.
|
||||
- WSL2 uses Linux paths and Linux/XDG fallback inside WSL.
|
||||
- Local repo paths are stored as the user supplied them for the current runtime.
|
||||
|
||||
Examples:
|
||||
|
||||
```text
|
||||
PowerShell:
|
||||
default base -> %LOCALAPPDATA%\openspec\workspaces
|
||||
|
||||
WSL2:
|
||||
default base -> ~/.local/share/openspec/workspaces
|
||||
```
|
||||
|
||||
This slice should not translate between `D:\repo`, `/mnt/d/repo`, and `\\wsl$` paths. Cross-runtime translation can be reconsidered later if an agent-launch workflow requires it.
|
||||
|
||||
## Link Names
|
||||
|
||||
A link name is the stable way to refer to a repo or folder inside workspace planning.
|
||||
|
||||
The local path can vary by machine:
|
||||
|
||||
```text
|
||||
shared link name: landing
|
||||
Tabish path: /Users/tabish/repos/landing
|
||||
Windows path: D:\repos\landing
|
||||
WSL2 path: /mnt/d/repos/landing
|
||||
```
|
||||
|
||||
Later workflows should refer to `landing` in workspace planning, status, and apply context. The local path is only how the current machine finds that repo or folder.
|
||||
|
||||
Link names are intentionally minimal: they must be non-empty, must not be `.` or `..`, must not contain path separators, and must be unique within the workspace.
|
||||
|
||||
The owning repo or folder remains the home of canonical specs and implementation work. The workspace makes the cross-boundary plan legible; it does not take ownership away from the linked repos or folders.
|
||||
|
||||
Link names are normally inferred from the folder basename in guided flows. Direct flows can allow an explicit name when the default would conflict or be unclear.
|
||||
|
||||
## Linked Repos And Folders
|
||||
|
||||
Workspace planning visibility should not require repo-local OpenSpec state.
|
||||
|
||||
That matters for two common cases:
|
||||
|
||||
- a repo has not adopted OpenSpec yet, but still needs to be considered in planning
|
||||
- a large monorepo has folders such as packages, services, or apps that should be planned like separate areas, without each folder having its own `openspec/`
|
||||
|
||||
Foundation should allow the link model to describe both:
|
||||
|
||||
```text
|
||||
multi-repo:
|
||||
api -> /repos/api
|
||||
web -> /repos/web
|
||||
|
||||
large monorepo:
|
||||
billing -> /repos/platform/services/billing
|
||||
checkout -> /repos/platform/apps/checkout
|
||||
```
|
||||
|
||||
Later apply/verify/archive workflows can decide what extra readiness is needed for implementation. Planning should be able to start before that.
|
||||
|
||||
Linking only records the relationship between a workspace link name and a local path. It must not create, copy, move, initialize, or edit files inside the linked repo or folder.
|
||||
|
||||
Repo-local spec availability is computed when needed. For example, `repo_specs_path` can be reported by a later doctor command when a linked path contains `openspec/specs`, but that path should not be treated as required workspace state.
|
||||
|
||||
## Later Slices
|
||||
|
||||
This foundation stops before user-facing workspace workflows:
|
||||
|
||||
- `workspace-create-and-register-repos` owns setup, link, relink, list, and doctor behavior.
|
||||
- `workspace-open-agent-context` owns agent launch context.
|
||||
- `workspace-change-planning` owns workspace proposals and repo scope.
|
||||
- `workspace-apply-repo-slice` owns implementation of one repo slice.
|
||||
- `workspace-verify-and-archive` owns completion and archive behavior.
|
||||
@@ -1,142 +0,0 @@
|
||||
## Why
|
||||
|
||||
Users need a workspace to feel like the obvious home for planning across multiple repos or folders.
|
||||
|
||||
They should be able to think:
|
||||
|
||||
```text
|
||||
I have repos or folders that are often planned together.
|
||||
I create an OpenSpec workspace.
|
||||
That workspace is where changes live.
|
||||
My code stays where it is.
|
||||
OpenSpec links the workspace to those local paths.
|
||||
```
|
||||
|
||||
A workspace is not a feature. It is the durable planning home. Individual features, fixes, and projects are changes inside the workspace.
|
||||
|
||||
Users should not have to choose a storage location, create a change early, or understand internal workspace state before OpenSpec can orient itself.
|
||||
|
||||
The POC proved that workspace state is useful. This reimplementation should turn that into a simple product model that users and agents can explain without special-case vocabulary.
|
||||
|
||||
## What Changes
|
||||
|
||||
This change defines the user-facing foundation for OpenSpec workspaces.
|
||||
|
||||
An OpenSpec workspace has a recognizable planning home:
|
||||
|
||||
```text
|
||||
workspace-root/
|
||||
changes/
|
||||
.openspec-workspace/
|
||||
```
|
||||
|
||||
`changes/` is where workspace-level planning lives. `.openspec-workspace/` identifies the directory as an OpenSpec workspace and stores workspace state.
|
||||
|
||||
OpenSpec-managed workspaces live in one standard location:
|
||||
|
||||
```text
|
||||
<global-data-dir>/workspaces/
|
||||
```
|
||||
|
||||
Users should not need to choose that location. OpenSpec still shows the workspace path after setup so users know where planning files live. This foundation slice does not provide a workspace-specific environment-variable or configuration override for managed workspace storage.
|
||||
|
||||
OpenSpec also keeps a lightweight local registry of known workspaces on the current machine. The registry powers global commands, pickers, and listing, but each workspace folder remains the source of truth.
|
||||
|
||||
Workspace state is split by user expectation:
|
||||
|
||||
- shared workspace information can move between machines
|
||||
- local checkout paths stay local to each machine
|
||||
- linked repos and folders are referred to by stable link names, not by absolute paths
|
||||
|
||||
A linked path can be a full repo, a folder inside a monorepo, or another existing folder the workspace should plan against. A linked path does not need repo-local `openspec/` state before it can be included in workspace planning. Repo-local OpenSpec state may still matter later for implementation, verification, or archive workflows, but it is not a prerequisite for planning visibility.
|
||||
|
||||
Native Windows/PowerShell and WSL2 are both supported. Each runtime uses its own path conventions. OpenSpec does not translate paths between Windows and WSL in this foundation slice.
|
||||
|
||||
## Outcome
|
||||
|
||||
After this change, later workspace features can rely on one clear product contract:
|
||||
|
||||
- OpenSpec can tell when the user is inside a workspace.
|
||||
- OpenSpec knows where to create managed workspaces by default.
|
||||
- OpenSpec can keep a local registry of known workspaces.
|
||||
- A workspace has one visible planning area: `changes/`.
|
||||
- Workspace state is distinguishable from repo-local `openspec/` state.
|
||||
- Shared workspace state does not force one user's local paths onto another user.
|
||||
- Workspace planning can reference existing repos or folders by stable link names.
|
||||
- Linked repos or folders do not need repo-local OpenSpec state for workspace planning.
|
||||
- Multi-repo and large-monorepo work can use the same workspace planning model.
|
||||
- Repo-owned specs and implementation remain owned by their repos or source areas.
|
||||
- Windows, PowerShell, and WSL2 path behavior is predictable.
|
||||
|
||||
This change does not deliver the full workspace workflow. It gives `workspace-create-and-register-repos` the foundation it needs to add the first user-facing commands.
|
||||
|
||||
## POC Findings
|
||||
|
||||
Behavior to preserve:
|
||||
|
||||
- A workspace is a durable coordination home for cross-repo planning.
|
||||
- The workspace has a visible `changes/` directory at its root.
|
||||
- Linked repos and folders provide the context the workspace can plan against.
|
||||
- Stable link names matter more than local checkout paths.
|
||||
- Local machine paths should not become shared workspace state.
|
||||
- Canonical specs and implementation still belong to the owning repos.
|
||||
|
||||
Lessons to carry forward:
|
||||
|
||||
- The POC's hidden `.openspec/` workspace metadata shape made workspace state too easy to confuse with repo-local OpenSpec state.
|
||||
- Users should not need to run repo-local `openspec init` inside the workspace root.
|
||||
- The POC's requirement that registered repos already have `openspec/` is too strict for planning. Repos and folders should be linkable before they adopt repo-local OpenSpec state.
|
||||
- Repo or folder visibility should not depend on creating a change.
|
||||
- Workspace setup should not imply repo-local implementation, branch, worktree, apply, verify, or archive behavior.
|
||||
- `add-repo` is too narrow for the user-facing model. Linking an existing repo or folder is clearer.
|
||||
|
||||
## Decisions
|
||||
|
||||
- Workspace identity directory: `.openspec-workspace/`.
|
||||
- Workspace identity file: `.openspec-workspace/workspace.yaml`.
|
||||
- Workspace name: a valid folder name for the current OS, excluding empty names, `.`/`..`, and path separators.
|
||||
- Workspace name usage: stored in `workspace.yaml`, used as the default managed workspace folder name, and used as the local registry name.
|
||||
- Planning surface: top-level `changes/`.
|
||||
- Local machine state: `.openspec-workspace/local.yaml`.
|
||||
- Local machine state exclusion: OpenSpec-created workspaces exclude `.openspec-workspace/local.yaml` from portable collaboration state by default.
|
||||
- Local workspace registry: `<global-data-dir>/workspaces/registry.yaml`.
|
||||
- Default workspace base: `<global-data-dir>/workspaces/`.
|
||||
- Platform behavior: native Windows and WSL2 each use the path conventions of the runtime running OpenSpec.
|
||||
- Linked paths may be full repos, monorepo folders, or other existing folders.
|
||||
- Link names: non-empty stable names, unique within a workspace, excluding `.`/`..` and path separators.
|
||||
- Repo-local `openspec/` state is not required for workspace planning visibility.
|
||||
- Linking records the relationship only; it does not create, copy, move, initialize, or edit files in the linked repo or folder.
|
||||
|
||||
Planning dependency:
|
||||
|
||||
- None. This is the first implementation slice.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No complete `openspec workspace setup`, `openspec workspace link`, or `openspec workspace relink` flow yet.
|
||||
- No public `openspec workspace create` command in the first user-facing workspace flow.
|
||||
- No user-facing command, environment variable, or configuration setting for changing the standard workspace location.
|
||||
- No question that asks users where OpenSpec should store workspaces by default.
|
||||
- No automatic Windows-to-WSL or WSL-to-Windows path translation.
|
||||
- No workspace-open agent launch behavior.
|
||||
- No workspace-level proposal creation.
|
||||
- No repo-slice apply, verify, archive, branch, or worktree behavior.
|
||||
- No copying workspace planning files into linked repos or folders as a side effect of creating, detecting, or linking a workspace.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `workspace-foundation`: Defines the product foundation for OpenSpec workspaces.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `openspec-conventions`: Describes how coordination workspaces differ from repo-local OpenSpec projects.
|
||||
|
||||
## Impact
|
||||
|
||||
- Workspace recognition and path behavior.
|
||||
- Workspace state parsing.
|
||||
- Local workspace registry parsing.
|
||||
- Documentation and agent guidance for the workspace mental model.
|
||||
- Later workspace slices should build on this contract instead of redefining workspace storage, identity, registry, or path behavior.
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Workspace Product Language
|
||||
OpenSpec conventions SHALL describe coordination workspaces in user-facing product terms.
|
||||
|
||||
#### Scenario: Describing workspace structure
|
||||
- **WHEN** OpenSpec documentation describes workspace support
|
||||
- **THEN** it SHALL present a workspace as the planning home for work across linked repos or folders
|
||||
- **AND** it SHALL describe `changes/` as the workspace planning area
|
||||
|
||||
#### Scenario: Avoiding internal workspace vocabulary
|
||||
- **WHEN** OpenSpec documentation explains what a workspace includes
|
||||
- **THEN** it SHALL prefer plain product language such as "repos or folders"
|
||||
- **AND** it SHALL avoid user-facing reliance on terms such as "working set", "code area", "entry", "alias", or "local overlay"
|
||||
|
||||
#### Scenario: Distinguishing workspaces from changes
|
||||
- **WHEN** OpenSpec documentation explains workspace planning
|
||||
- **THEN** it SHALL describe a workspace as a durable planning home
|
||||
- **AND** it SHALL describe individual features, fixes, and projects as changes inside the workspace
|
||||
|
||||
#### Scenario: Distinguishing workspace and repo-local surfaces
|
||||
- **WHEN** OpenSpec documentation compares workspace and repo-local flows
|
||||
- **THEN** it SHALL explain that workspace planning lives in the workspace root
|
||||
- **AND** it SHALL explain that repo-local specs and changes continue to live under each repo's `openspec/` directory
|
||||
|
||||
#### Scenario: Sequencing the workspace roadmap
|
||||
- **WHEN** workspace reimplementation work is split across multiple active changes
|
||||
- **THEN** conventions SHALL allow those changes to remain flat siblings under `openspec/changes/`
|
||||
- **AND** dependency order MAY be documented in proposal prose until formal change stacking metadata is available
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Recognizable Workspace Home
|
||||
OpenSpec SHALL give users and agents a recognizable workspace home for cross-repo planning.
|
||||
|
||||
#### Scenario: Planning across linked repos or folders
|
||||
- **WHEN** a user creates an OpenSpec workspace for repos or folders they plan across
|
||||
- **THEN** the workspace SHALL provide a durable planning home
|
||||
- **AND** the workspace SHALL be able to hold multiple changes over time
|
||||
|
||||
#### Scenario: Working from inside a workspace
|
||||
- **GIVEN** a user runs OpenSpec from a workspace root or one of its subdirectories
|
||||
- **WHEN** OpenSpec resolves the current workspace
|
||||
- **THEN** it SHALL identify the workspace root
|
||||
- **AND** it SHALL use the workspace root's `changes/` directory as the workspace planning area
|
||||
|
||||
#### Scenario: Avoiding accidental workspace mode
|
||||
- **GIVEN** a directory has `changes/` but is not an OpenSpec workspace
|
||||
- **WHEN** OpenSpec resolves the current workspace
|
||||
- **THEN** it SHALL avoid treating that directory as a workspace
|
||||
- **AND** it SHALL enter workspace mode only when the workspace identity file is present
|
||||
|
||||
### Requirement: Stable Workspace Name
|
||||
OpenSpec SHALL use one folder-style workspace name across workspace identity, managed storage, and the local registry.
|
||||
|
||||
#### Scenario: Using one workspace name
|
||||
- **WHEN** OpenSpec creates or registers a managed workspace
|
||||
- **THEN** the workspace name SHALL be stored in `.openspec-workspace/workspace.yaml`
|
||||
- **AND** the same name SHALL be used as the default managed workspace folder name
|
||||
- **AND** the same name SHALL be used as the local registry name
|
||||
|
||||
#### Scenario: Rejecting invalid folder-style names
|
||||
- **WHEN** OpenSpec accepts a workspace name
|
||||
- **THEN** it SHALL reject empty names, `.` or `..`, and names containing path separators
|
||||
- **AND** setup or create flows SHALL report OS-level folder creation failures clearly
|
||||
|
||||
### Requirement: Dedicated Workspace Identity
|
||||
OpenSpec SHALL distinguish a coordination workspace from a repo-local OpenSpec project.
|
||||
|
||||
#### Scenario: Reading workspace identity
|
||||
- **WHEN** OpenSpec reads or writes workspace identity and workspace state
|
||||
- **THEN** it SHALL use `.openspec-workspace/`
|
||||
|
||||
#### Scenario: Preserving repo-local OpenSpec projects
|
||||
- **GIVEN** a repo-local OpenSpec project uses `openspec/`
|
||||
- **WHEN** that repo is linked to a workspace
|
||||
- **THEN** OpenSpec SHALL continue treating `openspec/` as that repo's local OpenSpec directory
|
||||
- **AND** workspace planning SHALL remain anchored in the workspace root
|
||||
|
||||
#### Scenario: Avoiding repo-local initialization in the workspace root
|
||||
- **WHEN** a user is working from an OpenSpec workspace root
|
||||
- **THEN** OpenSpec SHALL treat that root as a workspace coordination surface
|
||||
- **AND** users SHALL not need to initialize a repo-local `openspec/` project inside the workspace root
|
||||
|
||||
### Requirement: Safe Workspace Sharing
|
||||
OpenSpec SHALL keep shared workspace information separate from local machine paths.
|
||||
|
||||
#### Scenario: Sharing workspace planning
|
||||
- **WHEN** a workspace is shared with another user or machine
|
||||
- **THEN** shared workspace information SHALL include portable workspace identity and stable link names
|
||||
- **AND** it SHALL not require another user to reuse the original user's absolute checkout paths
|
||||
|
||||
#### Scenario: Keeping checkout paths local
|
||||
- **WHEN** OpenSpec stores local paths for a workspace
|
||||
- **THEN** those paths SHALL be treated as local to the current machine and runtime
|
||||
- **AND** another machine MAY map the same link names to different local paths
|
||||
|
||||
#### Scenario: Preserving runtime-local paths
|
||||
- **WHEN** OpenSpec reads or writes local workspace paths
|
||||
- **THEN** it SHALL preserve path strings valid for the current runtime
|
||||
- **AND** it SHALL support native Windows paths and WSL2/Linux paths as local state values
|
||||
|
||||
#### Scenario: Excluding local state from portable collaboration
|
||||
- **WHEN** OpenSpec creates a workspace
|
||||
- **THEN** it SHALL exclude `.openspec-workspace/local.yaml` from portable collaboration state by default
|
||||
- **AND** `.openspec-workspace/workspace.yaml` SHALL remain the portable workspace identity and link-name state
|
||||
|
||||
### Requirement: Standard Workspace Location
|
||||
OpenSpec SHALL use a standard location for OpenSpec-managed workspaces without asking most users to choose one.
|
||||
|
||||
#### Scenario: Using the standard workspace location
|
||||
- **WHEN** OpenSpec needs the location for OpenSpec-managed workspaces
|
||||
- **THEN** it SHALL use `<global-data-dir>/workspaces`
|
||||
- **AND** `<global-data-dir>` SHALL follow existing OpenSpec XDG and platform data directory behavior
|
||||
|
||||
#### Scenario: Avoiding workspace-specific storage overrides
|
||||
- **WHEN** OpenSpec resolves the location for OpenSpec-managed workspaces
|
||||
- **THEN** it SHALL not use a workspace-specific environment variable, command, or configuration setting in this slice
|
||||
- **AND** managed workspace storage SHALL remain under `<global-data-dir>/workspaces`
|
||||
|
||||
#### Scenario: Running from native Windows
|
||||
- **WHEN** OpenSpec runs from native Windows shells such as PowerShell
|
||||
- **AND** `XDG_DATA_HOME` is not set
|
||||
- **THEN** OpenSpec SHALL store managed workspaces under the Windows global data location
|
||||
- **AND** paths SHALL follow native Windows path behavior
|
||||
|
||||
#### Scenario: Running from WSL2
|
||||
- **WHEN** OpenSpec runs from WSL2
|
||||
- **THEN** OpenSpec SHALL store managed workspaces under the Linux/XDG data location inside WSL
|
||||
- **AND** paths SHALL follow Linux path behavior inside WSL
|
||||
|
||||
#### Scenario: Using the workspace location automatically
|
||||
- **WHEN** OpenSpec creates or resolves OpenSpec-managed workspaces in later workflows
|
||||
- **THEN** it SHALL use the resolved workspace location by default
|
||||
- **AND** users SHALL be able to follow the normal workspace flow without choosing a storage location
|
||||
|
||||
#### Scenario: Showing the workspace path
|
||||
- **WHEN** OpenSpec creates a workspace in the standard workspace location
|
||||
- **THEN** it SHALL report the workspace path to the user
|
||||
- **AND** it SHALL not hide where planning files were created
|
||||
|
||||
#### Scenario: Staying in the current runtime
|
||||
- **WHEN** OpenSpec resolves workspace paths or local repo paths
|
||||
- **THEN** it SHALL interpret paths for the runtime running OpenSpec
|
||||
- **AND** Windows, UNC WSL, and WSL mount paths SHALL remain explicit user-provided paths
|
||||
|
||||
### Requirement: Local Workspace Registry
|
||||
OpenSpec SHALL keep a lightweight local registry of known workspaces on the current machine.
|
||||
|
||||
#### Scenario: Recording known workspaces
|
||||
- **WHEN** OpenSpec creates or learns about a managed workspace
|
||||
- **THEN** it SHALL be able to record the workspace name and path in a local registry
|
||||
- **AND** the registry SHALL be machine-local state
|
||||
|
||||
#### Scenario: Keeping workspace folders authoritative
|
||||
- **WHEN** OpenSpec reads workspace details
|
||||
- **THEN** each workspace folder's `.openspec-workspace/workspace.yaml` SHALL remain the source of truth for that workspace
|
||||
- **AND** the local registry SHALL act only as an index of known workspace paths
|
||||
|
||||
#### Scenario: Finding workspaces from anywhere
|
||||
- **WHEN** a later workspace command runs outside a workspace directory
|
||||
- **THEN** OpenSpec MAY use the local registry to find known workspaces
|
||||
- **AND** commands that need one workspace MAY use the registry to support an interactive picker
|
||||
|
||||
### Requirement: Stable Link Names
|
||||
OpenSpec SHALL use stable link names to refer to repos and folders in workspace planning.
|
||||
|
||||
#### Scenario: Referring to a repo or folder in workspace planning
|
||||
- **WHEN** workspace state or later workspace planning artifacts refer to a linked repo or folder
|
||||
- **THEN** they SHALL use the stable link name
|
||||
- **AND** the same link name SHALL remain valid even when local checkout paths differ
|
||||
|
||||
#### Scenario: Reusing link names across machines
|
||||
- **WHEN** a workspace is used on another machine
|
||||
- **THEN** link names SHALL remain stable
|
||||
- **AND** local checkout paths MAY differ on that machine
|
||||
|
||||
#### Scenario: Rejecting invalid link names
|
||||
- **WHEN** OpenSpec accepts a workspace link name
|
||||
- **THEN** it SHALL reject empty names, `.` or `..`, and names containing path separators
|
||||
- **AND** link names SHALL be unique within the workspace
|
||||
|
||||
### Requirement: Linked Repos And Folders
|
||||
OpenSpec SHALL allow workspace planning to include linked repos and folders before they have repo-local OpenSpec state.
|
||||
|
||||
#### Scenario: Planning with a repo that has not adopted OpenSpec
|
||||
- **WHEN** a workspace links a repo path that does not yet contain repo-local `openspec/`
|
||||
- **THEN** the repo SHALL still be available for workspace-level planning
|
||||
- **AND** implementation readiness MAY be handled by a later workflow
|
||||
|
||||
#### Scenario: Planning across monorepo folders
|
||||
- **WHEN** planning spans multiple packages, services, apps, or directories inside one monorepo
|
||||
- **THEN** the workspace SHALL be able to link those folders separately
|
||||
- **AND** each folder SHALL not need its own repo-local `openspec/` directory to participate in workspace planning
|
||||
|
||||
#### Scenario: Treating repos and folders consistently
|
||||
- **WHEN** a workspace plan includes both separate repos and folders inside a monorepo
|
||||
- **THEN** OpenSpec SHALL use the same planning model for both
|
||||
- **AND** users SHALL not need to create different kinds of workspace plans for multi-repo and monorepo changes
|
||||
|
||||
#### Scenario: Recording links without changing targets
|
||||
- **WHEN** OpenSpec records a link between a workspace and a local repo or folder
|
||||
- **THEN** it SHALL store the link in workspace state
|
||||
- **AND** it SHALL not create, copy, move, initialize, or edit files inside the linked repo or folder
|
||||
|
||||
### Requirement: Planning Before Implementation
|
||||
OpenSpec SHALL treat workspace creation and detection as planning setup, not implementation.
|
||||
|
||||
#### Scenario: Creating or detecting a workspace
|
||||
- **WHEN** a workspace exists
|
||||
- **THEN** OpenSpec SHALL treat it as a place for workspace-level planning
|
||||
- **AND** repo implementation files SHALL remain unchanged until an explicit implementation workflow runs
|
||||
|
||||
#### Scenario: Deferring repo implementation
|
||||
- **WHEN** repo-local implementation, apply, verify, or archive behavior is needed
|
||||
- **THEN** that behavior SHALL require an explicit later workspace workflow
|
||||
|
||||
### Requirement: Repo Ownership Boundaries
|
||||
OpenSpec SHALL keep repo ownership legible when planning happens in a workspace.
|
||||
|
||||
#### Scenario: Planning across owned repos
|
||||
- **WHEN** a workspace plan refers to behavior owned by a repo or source area
|
||||
- **THEN** that owner SHALL remain the home for canonical specs and implementation work
|
||||
- **AND** the workspace SHALL make the cross-boundary plan visible without taking ownership away from that owner
|
||||
|
||||
#### Scenario: Drafting before ownership is clear
|
||||
- **WHEN** cross-repo behavior is still being explored and ownership is not clear
|
||||
- **THEN** the workspace MAY hold planning notes or draft behavior
|
||||
- **AND** those drafts SHALL remain distinguishable from canonical repo-owned specs
|
||||
@@ -1,56 +0,0 @@
|
||||
## 1. POC Findings And Model Decisions
|
||||
|
||||
- [x] 1.1 Capture the foundation POC findings in the proposal/design artifacts
|
||||
- [x] 1.2 Settle `.openspec-workspace/` as the workspace metadata directory
|
||||
- [x] 1.3 Define the minimal workspace root shape and root marker
|
||||
- [x] 1.4 Define committed workspace state versus machine-local workspace state
|
||||
- [x] 1.5 Capture that workspace setup is useful only after at least one repo or folder is linked
|
||||
- [x] 1.6 Capture that repo-owned specs and implementation remain owned by repos
|
||||
- [x] 1.7 Capture that planning can include repos or monorepo folders without repo-local OpenSpec state
|
||||
- [x] 1.8 Capture that workspaces hold many changes and are not feature containers
|
||||
- [x] 1.9 Capture `link`/`relink` as the user-facing model instead of `add-repo`/`update-repo`
|
||||
|
||||
## 2. Foundation Helpers
|
||||
|
||||
- [x] 2.1 Add workspace path constants and helpers for `.openspec-workspace/`, `workspace.yaml`, `local.yaml`, and root `changes/`
|
||||
- [x] 2.2 Add workspace root detection from an arbitrary starting directory
|
||||
- [x] 2.3 Add typed parsing and validation for minimal shared workspace state
|
||||
- [x] 2.4 Add typed parsing and validation for minimal machine-local workspace state
|
||||
- [x] 2.5 Ensure repo-local `openspec/` projects are not mistaken for coordination workspaces
|
||||
- [x] 2.6 Add a standard workspace location resolver using `getGlobalDataDir()/workspaces`
|
||||
- [x] 2.7 Ensure workspace path helpers use platform path APIs and avoid hardcoded POSIX separators
|
||||
- [x] 2.8 Add local workspace registry path constants and helpers
|
||||
|
||||
## 3. Metadata And Local State
|
||||
|
||||
- [x] 3.1 Define the versioned shared-state shape with workspace name and stable link map
|
||||
- [x] 3.2 Define the versioned local-state shape with stable link names mapped to local paths
|
||||
- [x] 3.3 Ensure local-state files are treated as machine-local and OpenSpec-created workspaces exclude `.openspec-workspace/local.yaml` from portable collaboration state
|
||||
- [x] 3.4 Add validation for invalid versions, invalid link names, malformed link maps, and malformed local path maps
|
||||
- [x] 3.5 Preserve native Windows and WSL2 path strings when reading and writing local path state
|
||||
- [x] 3.6 Define the versioned local registry shape with workspace names mapped to workspace roots
|
||||
- [x] 3.7 Ensure the local registry is treated as a convenience index, not the workspace source of truth
|
||||
|
||||
## 4. Documentation And Guidance
|
||||
|
||||
- [x] 4.1 Document the coordination workspace mental model
|
||||
- [x] 4.2 Document how `.openspec-workspace/` differs from repo-local `openspec/`
|
||||
- [x] 4.3 Document stable link names as the way to refer to linked repos and folders
|
||||
- [x] 4.4 Document which behavior is intentionally deferred to later workspace slices
|
||||
- [x] 4.5 Document native Windows/PowerShell and WSL2 path behavior for managed workspace storage
|
||||
- [x] 4.6 Document linked repos/folders without repo-local OpenSpec and large-monorepo planning behavior
|
||||
- [x] 4.7 Document the local workspace registry and global command model
|
||||
|
||||
## 5. Verification
|
||||
|
||||
- [x] 5.1 Add unit tests for root detection and non-detection cases
|
||||
- [x] 5.2 Add unit tests for shared-state and local-state parsing
|
||||
- [x] 5.3 Add unit tests for standard workspace location resolution with XDG/Linux fallback and native Windows fallback
|
||||
- [x] 5.4 Add unit tests that local-state parsing preserves native Windows and WSL2-style paths
|
||||
- [x] 5.5 Add unit tests for repo-local compatibility boundaries
|
||||
- [x] 5.6 Add tests or docs coverage that linked repos/folders do not require repo-local `openspec/`
|
||||
- [x] 5.7 Add tests or docs coverage for monorepo folder links under the same workspace model
|
||||
- [x] 5.8 Add tests for local registry parsing and stale registry entries
|
||||
- [x] 5.9 Add tests or docs coverage for `.openspec-workspace/local.yaml` exclusion in OpenSpec-created workspaces
|
||||
- [x] 5.10 Run `openspec validate workspace-foundation --strict`
|
||||
- [x] 5.11 Run targeted test coverage for the new workspace foundation helpers
|
||||
@@ -1,2 +0,0 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-25
|
||||
@@ -1,48 +0,0 @@
|
||||
## Context
|
||||
|
||||
The OpenCode adapter in `src/core/command-generation/adapters/opencode.ts` currently generates command files at `.opencode/command/opsx-<id>.md` (singular `command`). OpenCode's official documentation uses `.opencode/commands/` (plural), and every other adapter in the codebase follows the plural convention for commands directories. The legacy cleanup module in `src/core/legacy-cleanup.ts` also references the singular form for detecting old artifacts.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Align the OpenCode adapter path with OpenCode's official `.opencode/commands/` convention
|
||||
- Add the old singular path `.opencode/command/` to legacy cleanup so existing installations are properly cleaned
|
||||
- Update documentation to reflect the corrected path
|
||||
- Update test assertions to match the new path
|
||||
|
||||
**Non-Goals:**
|
||||
- Changing the OpenCode skill path (`.opencode/skills/`) — already correct
|
||||
- Modifying any other adapter's directory structure
|
||||
- Adding migration prompts or interactive upgrade flows
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Direct path rename in adapter
|
||||
|
||||
**Decision:** Change `path.join('.opencode', 'command', ...)` to `path.join('.opencode', 'commands', ...)` in the adapter's `getFilePath` method.
|
||||
|
||||
**Rationale:** This is a single-line change that aligns with the established pattern across all other adapters. No abstraction or indirection needed.
|
||||
|
||||
**Alternatives considered:**
|
||||
- Add a configuration option for the directory name — rejected as over-engineering for a bug fix
|
||||
- Keep singular and add plural as alias — rejected as it creates ambiguity about which is canonical
|
||||
|
||||
### 2. Legacy cleanup via existing constant map
|
||||
|
||||
**Decision:** Update the `LEGACY_SLASH_COMMAND_PATHS` entry for `'opencode'` from `'.opencode/command/openspec-*.md'` to `'.opencode/command/opsx-*.md'` (the old singular path becomes the legacy pattern) and ensure the new path is handled by the current command generation pipeline.
|
||||
|
||||
**Rationale:** The existing legacy cleanup infrastructure uses `LEGACY_SLASH_COMMAND_PATHS` as an explicit lookup. The old singular-path pattern already matches the legacy format (`openspec-*` prefix from the old SlashCommandRegistry era). The current command generation uses the `opsx-*` prefix, so we also need to add a legacy pattern for `opsx-*` files in the old singular directory.
|
||||
|
||||
**Alternatives considered:**
|
||||
- Add a separate migration script — rejected; the existing legacy cleanup mechanism handles this scenario
|
||||
|
||||
### 3. Documentation update
|
||||
|
||||
**Decision:** Update the `docs/supported-tools.md` table entry for OpenCode from `.opencode/command/opsx-<id>.md` to `.opencode/commands/opsx-<id>.md`.
|
||||
|
||||
**Rationale:** Documentation must match the actual generated paths.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- **[Existing installations have files at old path]** → Mitigated by legacy cleanup detecting `.opencode/command/` artifacts. On next `openspec init`, old files are cleaned up and new files written to `.opencode/commands/`.
|
||||
- **[Users referencing old path in custom scripts]** → Low risk. The old path was incorrect per OpenCode's specification, so custom references were already misaligned.
|
||||
@@ -1,26 +0,0 @@
|
||||
## Why
|
||||
|
||||
The OpenCode adapter uses `.opencode/command/` (singular) for its commands directory, but OpenCode's official documentation specifies `.opencode/commands/` (plural). Every other adapter in the codebase also uses plural directory names (`.claude/commands/`, `.cursor/commands/`, `.factory/commands/`, etc.). This inconsistency was introduced in Oct 2025 without documented rationale. Fixes [#748](https://github.com/Fission-AI/OpenSpec/issues/748).
|
||||
|
||||
## What Changes
|
||||
|
||||
- OpenCode adapter path changes from `.opencode/command/` to `.opencode/commands/`
|
||||
- Legacy cleanup adds `.opencode/command/` (old singular path) for backward compatibility
|
||||
- Documentation updated to reflect the new plural path
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
_None._
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `command-generation`: OpenCode adapter path changes from singular `command/` to plural `commands/` to match OpenCode's official directory convention
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/core/command-generation/adapters/opencode.ts` — adapter path
|
||||
- `src/core/legacy-cleanup.ts` — legacy cleanup pattern + add old singular path
|
||||
- `docs/supported-tools.md` — documentation table
|
||||
- `test/core/command-generation/adapters.test.ts` — test assertion
|
||||
@@ -1,63 +0,0 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: ToolCommandAdapter interface
|
||||
|
||||
The system SHALL define a `ToolCommandAdapter` interface for per-tool formatting.
|
||||
|
||||
#### Scenario: Adapter interface structure
|
||||
|
||||
- **WHEN** implementing a tool adapter
|
||||
- **THEN** `ToolCommandAdapter` SHALL require:
|
||||
- `toolId`: string identifier matching `AIToolOption.value`
|
||||
- `getFilePath(commandId: string)`: returns file path for command (relative from project root, or absolute for global-scoped tools like Codex)
|
||||
- `formatFile(content: CommandContent)`: returns complete file content with frontmatter
|
||||
|
||||
#### Scenario: Claude adapter formatting
|
||||
|
||||
- **WHEN** formatting a command for Claude Code
|
||||
- **THEN** the adapter SHALL output YAML frontmatter with `name`, `description`, `category`, `tags` fields
|
||||
- **AND** file path SHALL follow pattern `.claude/commands/opsx/<id>.md`
|
||||
|
||||
#### Scenario: Cursor adapter formatting
|
||||
|
||||
- **WHEN** formatting a command for Cursor
|
||||
- **THEN** the adapter SHALL output YAML frontmatter with `name` as `/opsx-<id>`, `id`, `category`, `description` fields
|
||||
- **AND** file path SHALL follow pattern `.cursor/commands/opsx-<id>.md`
|
||||
|
||||
#### Scenario: Windsurf adapter formatting
|
||||
|
||||
- **WHEN** formatting a command for Windsurf
|
||||
- **THEN** the adapter SHALL output YAML frontmatter with `name`, `description`, `category`, `tags` fields
|
||||
- **AND** file path SHALL follow pattern `.windsurf/workflows/opsx-<id>.md`
|
||||
|
||||
#### Scenario: OpenCode adapter formatting
|
||||
|
||||
- **WHEN** formatting a command for OpenCode
|
||||
- **THEN** the adapter SHALL output YAML frontmatter with `description` field
|
||||
- **AND** file path SHALL follow pattern `.opencode/commands/opsx-<id>.md` using `path.join('.opencode', 'commands', ...)` for cross-platform compatibility
|
||||
- **AND** the adapter SHALL transform colon-based command references (`/opsx:name`) to hyphen-based (`/opsx-name`) in the body
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Legacy cleanup for renamed OpenCode command directory
|
||||
|
||||
The legacy cleanup module SHALL detect and remove old OpenCode command files from the previous singular `.opencode/command/` directory path.
|
||||
|
||||
#### Scenario: Detect old singular-path OpenCode command files
|
||||
|
||||
- **WHEN** running legacy artifact detection on a project with files matching `.opencode/command/opsx-*.md` or `.opencode/command/openspec-*.md`
|
||||
- **THEN** the system SHALL include those files in the legacy slash command files list via `LEGACY_SLASH_COMMAND_PATHS`
|
||||
- **AND** `LegacySlashCommandPattern.pattern` SHALL accept `string | string[]` to support multiple glob patterns per tool
|
||||
|
||||
#### Scenario: Clean up old OpenCode command files on init
|
||||
|
||||
- **WHEN** a user runs `openspec init` in a project with old `.opencode/command/` artifacts
|
||||
- **THEN** the system SHALL remove the old files
|
||||
- **AND** generate new command files at `.opencode/commands/`
|
||||
|
||||
#### Scenario: Auto-cleanup legacy artifacts in non-interactive mode
|
||||
|
||||
- **WHEN** a user runs `openspec init` in non-interactive mode (e.g., CI) and legacy artifacts are detected
|
||||
- **THEN** the system SHALL auto-cleanup legacy artifacts without requiring `--force`
|
||||
- **AND** legacy slash command files (100% OpenSpec-managed) SHALL be removed
|
||||
- **AND** config file cleanup SHALL only remove OpenSpec markers (never delete user files)
|
||||
@@ -1,19 +0,0 @@
|
||||
## 1. Adapter Fix
|
||||
|
||||
- [x] 1.1 Update `src/core/command-generation/adapters/opencode.ts`: change `path.join('.opencode', 'command', ...)` to `path.join('.opencode', 'commands', ...)` and update the JSDoc comment
|
||||
|
||||
## 2. Legacy Cleanup
|
||||
|
||||
- [x] 2.1 Update `src/core/legacy-cleanup.ts`: update the `'opencode'` entry in `LEGACY_SLASH_COMMAND_PATHS` to detect both `opsx-*.md` and `openspec-*.md` patterns at `.opencode/command/` for backward compatibility
|
||||
|
||||
## 3. Documentation
|
||||
|
||||
- [x] 3.1 Update `docs/supported-tools.md`: change OpenCode command path from `.opencode/command/opsx-<id>.md` to `.opencode/commands/opsx-<id>.md`
|
||||
|
||||
## 4. Tests
|
||||
|
||||
- [x] 4.1 Update `test/core/command-generation/adapters.test.ts`: change the OpenCode file path assertion from `path.join('.opencode', 'command', 'opsx-explore.md')` to `path.join('.opencode', 'commands', 'opsx-explore.md')`
|
||||
|
||||
## 5. Changeset
|
||||
|
||||
- [x] 5.1 Create a changeset file (`.changeset/fix-opencode-commands-directory.md`) with a patch bump describing the path fix
|
||||
@@ -1,2 +0,0 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-25
|
||||
@@ -1,38 +0,0 @@
|
||||
## Context
|
||||
|
||||
`statusCommand` in `src/commands/workflow/status.ts` calls `validateChangeExists()` from `shared.ts` as its first operation. When no `--change` option is provided and no change directories exist, `validateChangeExists` throws: `No changes found. Create one with: openspec new change <name>`. This error propagates up as a fatal CLI error (non-zero exit code).
|
||||
|
||||
This is correct behavior for commands like `apply` and `show` that require a change to operate on. However, `status` is an informational command — it should report the current state, even when that state is "no changes exist."
|
||||
|
||||
The error surfaces during onboarding (issue #714) when AI agents call `openspec status` before any change has been created.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Make `openspec status` exit with code 0 and a friendly message when no changes exist
|
||||
- Support both text and JSON output modes for the no-changes case
|
||||
- Keep all other commands' validation behavior unchanged
|
||||
|
||||
**Non-Goals:**
|
||||
- Changing the behavior of `validateChangeExists` (keep it strict for all consumers; only extract its internal helper)
|
||||
- Changing the onboard template or skill instructions
|
||||
- Handling the case where `--change` is provided but the specific change doesn't exist (this should remain an error)
|
||||
|
||||
## Decisions
|
||||
|
||||
### Extract `getAvailableChanges` and check before validation
|
||||
|
||||
**Rationale**: Extract the private `getAvailableChanges` closure from `validateChangeExists` into a public exported function in `shared.ts`. Then, in `statusCommand`, call `getAvailableChanges` *before* `validateChangeExists` to detect the no-changes case early and handle it gracefully. This avoids using try/catch for control flow and eliminates any coupling to error message strings.
|
||||
|
||||
**Alternative considered**: Catching the error from `validateChangeExists` by matching `error.message.startsWith('No changes found')`. Rejected because string coupling is fragile — if the error message changes, the catch silently stops working.
|
||||
|
||||
**Alternative considered**: Adding a `throwOnEmpty` parameter to `validateChangeExists`. Rejected because it adds complexity to a shared function for a single consumer's needs and mixes UX concerns into a validation utility.
|
||||
|
||||
### Keep `validateChangeExists` strict
|
||||
|
||||
**Rationale**: `validateChangeExists` remains unchanged in behavior — it still throws for all error cases. The graceful handling lives entirely in `statusCommand`, which is the appropriate layer for UX decisions. Other commands (`apply`, `show`, `instructions`) are unaffected.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] Extra filesystem read when no `--change` is provided and changes *do* exist (`getAvailableChanges` is called first, then `validateChangeExists` performs its own read) → Mitigation: `statusCommand` returns early before reaching `validateChangeExists` when no changes exist, so the double-read only occurs when changes are present — minimal overhead.
|
||||
- [Risk] Other commands may also benefit from graceful no-changes handling in the future → Mitigation: `getAvailableChanges` is now public and reusable, making it easy to apply the same pattern elsewhere.
|
||||
@@ -1,25 +0,0 @@
|
||||
## Why
|
||||
|
||||
When `openspec status` is called without `--change` and no changes exist (e.g., during onboarding on a freshly initialized project), the CLI throws a fatal error: `No changes found. Create one with: openspec new change <name>`. This breaks the onboarding flow because AI agents may call `openspec status` before any change has been created, causing the agent to halt or report failure. Fixes [#714](https://github.com/Fission-AI/OpenSpec/issues/714).
|
||||
|
||||
## What Changes
|
||||
|
||||
- `openspec status` will exit gracefully (code 0) with a friendly message when no changes exist, instead of throwing a fatal error
|
||||
- `openspec status --json` will return a valid JSON object with an empty changes array when no changes exist
|
||||
- Other commands (`apply`, `show`, etc.) retain their current strict validation behavior
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `graceful-status-empty`: Graceful handling of `openspec status` when no changes exist, covering both text and JSON output modes
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
_None — `validateChangeExists` was internally refactored to delegate to the newly exported `getAvailableChanges`, but its behavior and public contract are unchanged. Other consumers are unaffected._
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/commands/workflow/shared.ts` — extract `getAvailableChanges` as a public function (validation behavior unchanged)
|
||||
- `src/commands/workflow/status.ts` — check for available changes before validation, handle empty case gracefully
|
||||
- Tests for the status command need to cover the new graceful behavior
|
||||
@@ -1,27 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Status command exits gracefully when no changes exist
|
||||
The `statusCommand` function SHALL check for available changes via `getAvailableChanges` before calling `validateChangeExists`. When no `--change` option is provided and no change directories exist, it SHALL print a friendly informational message and exit with code 0, instead of reaching `validateChangeExists` and propagating a fatal error.
|
||||
|
||||
#### Scenario: No changes exist, text mode
|
||||
- **WHEN** user runs `openspec status` without `--change` and no change directories exist under `openspec/changes/`
|
||||
- **THEN** the CLI prints `No active changes. Create one with: openspec new change <name>` to stdout and exits with code 0
|
||||
|
||||
#### Scenario: No changes exist, JSON mode
|
||||
- **WHEN** user runs `openspec status --json` without `--change` and no change directories exist
|
||||
- **THEN** the CLI outputs `{"changes":[],"message":"No active changes."}` as valid JSON to stdout and exits with code 0
|
||||
|
||||
### Requirement: Existing status validation behavior is preserved
|
||||
Other error paths in `validateChangeExists` that apply to the status command SHALL continue to throw errors as before. Commands other than `status` that use `validateChangeExists` SHALL NOT be affected.
|
||||
|
||||
#### Scenario: Changes exist but --change not specified
|
||||
- **WHEN** user runs `openspec status` without `--change` and one or more change directories exist
|
||||
- **THEN** the CLI throws an error listing available changes with the message `Missing required option --change. Available changes: ...`
|
||||
|
||||
#### Scenario: Specified change does not exist
|
||||
- **WHEN** user runs `openspec status --change non-existent`
|
||||
- **THEN** the CLI throws an error with message `Change 'non-existent' not found`
|
||||
|
||||
#### Scenario: Other commands unaffected
|
||||
- **WHEN** user runs `openspec show` or `openspec instructions` without `--change` and no changes exist
|
||||
- **THEN** the CLI throws the original `No changes found` error (no behavior change)
|
||||
@@ -1,16 +0,0 @@
|
||||
## 1. Implementation
|
||||
|
||||
- [x] 1.1 Extract `getAvailableChanges` in `shared.ts` and use it in `statusCommand` to check for changes before calling `validateChangeExists`
|
||||
- [x] 1.2 In text mode: print `No active changes. Create one with: openspec new change <name>` and return (exit 0)
|
||||
- [x] 1.3 In JSON mode: output `{"changes":[],"message":"No active changes."}` and return (exit 0)
|
||||
|
||||
## 2. Tests
|
||||
|
||||
- [x] 2.1 Add test: `openspec status` with no changes exits gracefully with friendly message (text mode)
|
||||
- [x] 2.2 Add test: `openspec status --json` with no changes returns valid JSON with empty changes array
|
||||
- [x] 2.3 Verify existing behavior: `openspec status` without `--change` when changes exist still throws missing option error
|
||||
- [x] 2.4 Verify cross-platform: tests use `path.join()` for any path assertions
|
||||
|
||||
## 3. Release
|
||||
|
||||
- [x] 3.1 Add changeset describing the fix
|
||||
+2
-2
@@ -18,7 +18,7 @@ Each AI tool has:
|
||||
- Create a generic, extensible command generation system
|
||||
|
||||
**Non-Goals:**
|
||||
- Global path installation for tools other than Codex (Codex uses absolute adapter paths today)
|
||||
- Global path installation (deferred to future work)
|
||||
- Multi-tool generation in single command (future enhancement)
|
||||
- Unifying with existing SlashCommandConfigurator (separate systems for now)
|
||||
|
||||
@@ -41,7 +41,7 @@ interface AIToolOption {
|
||||
**Rationale**:
|
||||
- Skills follow Agent Skills spec: `<toolDir>/skills/` - suffix is standard
|
||||
- Commands need per-tool formatting, handled by adapters (not a simple path)
|
||||
- Global paths supported — Codex adapter returns absolute paths via os.homedir()
|
||||
- Global paths deferred - can extend interface later
|
||||
|
||||
### 2. Strategy/Adapter pattern for command generation
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ The system SHALL define a `ToolCommandAdapter` interface for per-tool formatting
|
||||
- **WHEN** implementing a tool adapter
|
||||
- **THEN** `ToolCommandAdapter` SHALL require:
|
||||
- `toolId`: string identifier matching `AIToolOption.value`
|
||||
- `getFilePath(commandId: string)`: returns file path for command (relative from project root, or absolute for global-scoped tools like Codex)
|
||||
- `getFilePath(commandId: string)`: returns relative file path for command
|
||||
- `formatFile(content: CommandContent)`: returns complete file content with frontmatter
|
||||
|
||||
#### Scenario: Claude adapter formatting
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user