Compare commits

..
Author SHA1 Message Date
openspec-release-bot[bot]andgithub-actions[bot] bc7ab26650 Version Packages (#1023)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-01 21:23:33 +00:00
Tabish Bidiwale aa16080d16 Add changeset for Mistral Vibe support and validator/completion fixes (#1154) 2026-06-01 21:14:14 +00:00
Tabish Bidiwale 055957fbca clarify changeset release tracking (#1148) 2026-06-01 05:11:50 +00:00
Tabish BidiwaleandAlfred 9e78bcaa80 [codex] Document cross-platform path assertions (#1116)
* docs: document cross-platform path assertions

* docs: mention toPosixPath in path assertion guidance

* chore: remove changeset

---------

Co-authored-by: Alfred <alfred@Alfreds-Mac-mini.local>
2026-06-01 05:05:20 +00:00
e36463074d [codex] Add Mistral Vibe support with CI fix (#1144)
* feat: add mistral vibe support

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* feat: add mistral vibe support

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* chore: archive add-mistral-vibe-support change

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* chore: sync delta specs from add-mistral-vibe-support change

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* chore: fix archive directory date to match metadata

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* fix: correct vibe detection paths and alphabetical ordering

- Remove detectionPaths from Mistral Vibe to prevent double-nested skills dir
- Fix lingma alphabetical position in tool IDs list

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* chore: remove archived mistral vibe change files

Remove archive directory per PR review feedback to keep PR minimal

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* chore: remove mistral vibe spec files per PR feedback

Remove new spec corpus (vibe-tool-config + Mistral Vibe scenario in ai-tool-paths)

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* test: add Mistral Vibe detection regression test

Add focused regression test that proves Vibe initializes and detects
skills under .vibe/skills so the path semantics do not drift.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* test: tolerate workspace update help wrapping

---------

Co-authored-by: Thomas Betous <4435536+tbetous@users.noreply.github.com>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
Co-authored-by: tbetous <thomas.betous@doctolib.com>
2026-05-31 14:35:52 +00:00
9aded17af7 fix(validator): hint when SHALL/MUST appears only in requirement header (#1135)
When a change delta has a requirement whose body is missing SHALL/MUST but
whose header (the text after `### Requirement:`) already contains the
keyword, the validator emitted the generic error "must contain SHALL or
MUST". Authors then re-read the spec, see SHALL right there in the header,
and have no idea what the validator wants.

Per the OpenSpec conventions the keyword has to live on the requirement
body line (the line immediately after the header). When the keyword is
present in the header only, append guidance explaining exactly where to
move it. The fix is scoped to the two `validateChangeDeltaSpecs` call
sites (ADDED + MODIFIED) so behaviour for requirements that lack the
keyword everywhere stays unchanged.

Adds three vitest cases under `test/core/validation.test.ts`:
- ADDED block with header-only SHALL → enriched hint
- MODIFIED block with header-only MUST → enriched hint
- Neither header nor body contain SHALL/MUST → generic message preserved

Verified by reproducing the spec from #356, running
`openspec validate <change>` against the rebuilt CLI, and confirming the
new diagnostic guides the author to the fix. Reverting `validator.ts`
makes the two enriched-hint cases fail, so the tests guard the
regression.

Fixes #356

Co-authored-by: Pluviobyte <Pluviobyte@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-05-31 08:03:50 +00:00
Tabish Bidiwale 0c5f0c6c48 Improve context-store setup and cleanup UX (#1137)
* Improve context-store setup and cleanup UX

* Address CodeRabbit context-store feedback

* Canonicalize cleanup registry test assertion
2026-05-28 18:02:07 +00:00
Tabish Bidiwale 21c1805d80 [codex] Polish beta context workspace flow (#1136)
* Polish beta context workspace flow

* Allow context-only initiative workspace open

* Add workspace beta compatibility review item
2026-05-28 15:49:13 +00:00
Tabish Bidiwale 11b2690618 test: split slow workspace open CI case (#1134) 2026-05-28 06:54:51 +00:00
Tabish Bidiwale fd92ccca74 [codex] Add context stores and initiative views (#1127)
* Document initiative-led workspace direction

* Add context stores and initiative change links

* Let workspaces open initiative views

* Add workspace root bundle artifacts

* Support legacy workspace roots in planning resolution

* Remove accidental workspace root bundle artifacts

* Bundle workspace reimplementation docs into roadmap

* Preserve workspace context store bindings

* Address review feedback for context store initiatives

* test: canonicalize context store path assertions

* Refine context store and workspace core boundaries

* Avoid initiative diagnostic regex backtracking
2026-05-27 08:06:02 +00:00
Tabish Bidiwale e441287b1f test: normalize workspace change path assertion (#1117) 2026-05-23 05:45:18 +00:00
Tabish Bidiwale 7fdb177158 [codex] Fix Windows workspace path CI failure (#1111)
* fix: handle canonical workspace paths

* docs: document path canonicalization pitfalls

* docs: scope canonicalization notes to tests

* docs: improve test agent guidance

* docs: shorten test agent guidance
2026-05-23 01:38:30 +00:00
Tabish Bidiwale 79303b5210 Update recommended high-reasoning models (#1107) 2026-05-20 18:36:09 +00:00
Tabish Bidiwale 8498042fe8 [codex] Add workspace change planning workflow (#1089)
* Propose workspace change planning

* Implement workspace setup skills phase

* Implement workspace skill updates

* Handle config profile workspace apply

* Implement workspace change creation phase

* Enrich planning context for workspace changes

* Update workflow skills for planning context

* Add workspace planning verification coverage

* Fix workspace update review issues

* Fix workspace skill drift comparison

* Clean up workspace change planning artifacts

* Archive workspace change planning

* Fix archived workspace planning spec purpose

* Address workspace planning review comments
2026-05-14 16:00:56 +00:00
Howard 053d8a59d5 docs(migration-guide): fix inconsistent /opsx:sync description (#1059)
Changed description from 'Preview/spec-merge without archiving' to 'Merge delta specs into main specs' to match commands.md and workflows.md
2026-05-07 02:20:51 +00:00
Tabish Bidiwale b642398bf3 Fix Windows workspace launch arg expectation (#1057) 2026-05-06 04:33:20 +00:00
Tabish Bidiwale ff506c347a Fix Windows workspace CI tests (#1056) 2026-05-06 04:15:18 +00:00
Tabish Bidiwale 1cdf0410df [codex] Propose workspace open agent context (#1054)
* Propose workspace open agent context

* Implement workspace open surface

* Address workspace open review feedback

* Archive workspace open agent context

* Fix workspace open Windows launcher args
2026-05-06 03:53:55 +00:00
Tabish Bidiwale d5c824d4cd archive workspace create and register repos (#1052) 2026-05-06 02:30:11 +00:00
Tabish Bidiwale 849ae2a976 Fix Windows workspace path test expectations (#1055) 2026-05-06 01:54:12 +00:00
Tabish Bidiwale f510581b6c Fix Windows workspace path aliases (#1050) 2026-05-05 17:22:23 +00:00
Tabish Bidiwale 7c3acccaf7 [codex] Add workspace setup commands (#1046)
* add workspace setup commands

* Address workspace review comments

* Address completion review nitpicks

* Improve workspace command UX

* Address workspace review comments
2026-05-04 14:06:40 +00:00
Tabish Bidiwale 435458be56 archive workspace foundation (#1045) 2026-05-04 05:32:18 +00:00
JiangWayandClaude Opus 4.7 76c80f80f3 docs: add Community Schemas section + README entry (#1043)
Adds a "Community Schemas" section to docs/customization.md cataloging
community-maintained schema bundles distributed via standalone
repositories. Modeled after github/spec-kit's community extension
catalog (https://github.com/github/spec-kit/tree/main/extensions).

The first entry is `superpowers-bridge` from JiangWay/openspec-schemas
— born from the proposal in PR #970 and now maintained externally.

Also adds a brief 4-line "Community schemas" introductory section in
README.md (between Docs and Why OpenSpec) pointing readers to the
catalog. Documentation only; no code or schema changes.

Refs: #970

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 01:58:25 +00:00
Tabish Bidiwale 0ca74762dc fix windows workspace data dir paths (#1038) 2026-05-01 23:59:20 +00:00
Tabish Bidiwale e6d81ba0f6 [codex] Complete workspace foundation and setup specs (#1029)
* docs: define workspace foundation and setup specs

* Complete workspace foundation

* Document workspace beta status

* Address workspace PR review comments
2026-05-01 17:36:38 +00:00
davseby 2d189ce5e0 fix: make requirement header parsing case-insensitive (#1031)
* fix: make requirement header parsing case-insensitive

* fix: add tests and cover the rest of requirement header places
2026-05-01 15:55:09 +00:00
Tabish Bidiwale 44e4beeee8 fix omz completion compinit setup (#1033) 2026-05-01 15:30:14 +00:00
Tabish Bidiwale a974c67986 docs: clarify Bun install still requires Node (#1032) 2026-05-01 15:29:51 +00:00
Tabish Bidiwale 485c97e97d [codex] Include sync in core workflow defaults (#1030)
* Include sync in core workflow defaults

* Add old core custom profile sync hint

* Update workflows sync default docs
2026-05-01 14:20:28 +00:00
Yousa 347f0277e3 docs: sync tool ID lists with AI_TOOLS source of truth (#1027)
* docs: sync tool ID lists with AI_TOOLS source of truth

Fixes missing tool IDs in docs/cli.md and docs/supported-tools.md that
drifted from src/core/config.ts (AI_TOOLS).

- docs/cli.md: add bob, forgecode, junie, lingma (25 -> 29)
- docs/supported-tools.md: add lingma, align order with config.ts (28 -> 29)

Follow-up to #1003.

* docs: address AICR feedback on tool ID ordering and table entry

Address review comments from Copilot and CodeRabbit on PR #1027:

- docs/cli.md: reorder lingma to match AI_TOOLS position (between qoder and qwen)
- docs/supported-tools.md: same reordering in the --tools list
- docs/supported-tools.md: add missing Lingma row to Tool Directory Reference
  table (inserted alphabetically between Kiro and OpenCode, matching existing
  table convention)

Verified all three documentation surfaces against AI_TOOLS (29 tools):
- cli.md list: order matches src/core/config.ts
- supported-tools.md list: order matches src/core/config.ts
- supported-tools.md table: set equals AI_TOOLS (alphabetical-by-display-name
  order preserved per existing convention).
2026-04-30 13:49:59 +00:00
Tabish Bidiwale cb9641a450 docs: add workspace reimplementation proposal slices (#1025)
* docs: propose workspace reimplementation slices

* docs: add workspace reimplementation roadmap readme

* docs: add workspace poc reference guide

* docs: add workspace reimplementation entrypoint
2026-04-30 11:03:17 +00:00
Yousa 342ed43e69 feat: add Kimi CLI skills-only support (#1003)
* feat: add Kimi CLI skills-only support

* test: relax Kimi adapterless log assertion
2026-04-30 07:38:48 +00:00
openspec-release-bot[bot]andgithub-actions[bot] 3c7a05c5dc Version Packages (#996)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-21 16:14:12 +00:00
Tabish Bidiwale d1f3861d9e Add changeset for v1.3.1 patch fixes (#995) 2026-04-21 16:09:49 +00:00
7a39e887bb fix: escape glob-special characters in directory paths (#984)
* fix: escape glob-special chars in directory paths (#974)

Parentheses and square brackets in project directory paths broke
fast-glob matching, causing glob-based artifact outputs to silently
return empty results. Escape these characters in the directory portion
before passing to fast-glob, preserving glob semantics in the generates
pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use cwd for artifact output globs

---------

Co-authored-by: furao <furao@didiglobal.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
Co-authored-by: TabishB <tabishbidiwale@gmail.com>
2026-04-21 16:00:10 +00:00
swithekandTabishB 18c445a48d fix: handle XDG_CONFIG_HOME and %APPDATA% in telemetry config path (#990)
* fix: handle XDG_CONFIG_HOME and %APPDATA% in telemetry config path

* fix: migrate telemetry config to resolved path

* fix: address telemetry config review feedback

---------

Co-authored-by: TabishB <tabishbidiwale@gmail.com>
2026-04-21 15:31:23 +00:00
Tabish Bidiwale 900174000b docs: remove teams slack mention from readme (#991) 2026-04-20 02:22:12 +00:00
Tabish Bidiwale f529b25968 test: align path assertions with canonical helper (#975) 2026-04-15 10:32:03 +00:00
Tabish Bidiwale 93f7b797cf fix: prefer native realpath for canonical paths (#972) 2026-04-14 07:43:43 +00:00
Tabish Bidiwale 7d07101363 fix: canonicalize workflow artifact paths (#971) 2026-04-14 07:14:11 +00:00
Alfred c0f29044f9 docs: clarify initiative-first workspace model (#969)
* docs: split workspace initiatives from repo-local changes

* docs: align roadmap and explore ux with initiatives
2026-04-13 12:20:24 +00:00
Tabish Bidiwale 7fe45ca330 Fix apply instructions for glob artifact outputs (#967)
* Fix glob artifact resolution in apply instructions

* Enforce file-only literal artifact outputs
2026-04-12 14:35:11 +00:00
Tabish Bidiwale c8e2072e3a fix: detect hidden requirements in main specs (#966)
* fix: detect hidden main spec requirements

* fix: tighten fenced code parsing
2026-04-12 13:59:10 +00:00
Tabish Bidiwale cd5e49346f docs: expand workspace planning explorations (#965)
* docs: add workspace ux explorations

* docs: update workspace architecture direction
2026-04-12 13:17:17 +00:00
Tabish Bidiwale a18d992fa1 fix: suppress ora spinner output when --json flag is used (#960)
When --json is passed, ora spinners wrote progress text to stderr, which
broke JSON parsing for AI agents that combine stdout+stderr. Conditionally
skip spinner creation in status, instructions, and templates commands.

Closes #957
2026-04-12 03:27:55 +00:00
Tabish Bidiwale 4df6a4889b fix: silence telemetry network errors in firewalled environments (#959)
* fix: silence telemetry network errors in firewalled environments

Wrap PostHog fetch with safeTelemetryFetch that catches all network
errors and non-2xx responses, returning a synthetic 204 so PostHog
never throws PostHogFetchNetworkError. Disable retries, remote config,
surveys, and feature flag preloading to eliminate extra network calls.
Add 1s request timeout. Surface telemetry opt-out docs earlier in
README, installation, and CLI reference.

Closes #895

* fix: clear CI env var in telemetry fetch tests

GitHub Actions sets CI=true which disables telemetry, causing PostHog
to never be instantiated and the fetch wrapper tests to fail.

* docs: add telemetry env vars to Environment Variables table

Addresses CodeRabbit review comment.

* docs: remove unnecessary firewall telemetry warnings

Telemetry now fails silently, so users don't need to proactively
disable it. The env vars are still documented in the reference table.

* docs: restore original config get/set examples in cli.md

These examples document how config works, not telemetry opt-out.
2026-04-12 03:21:11 +00:00
openspec-release-bot[bot]andgithub-actions[bot] 9b5007dbc3 Version Packages (#953)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-11 15:43:55 +00:00
Tabish Bidiwale cce787ec40 chore: add changeset for v1.3.0 (#952)
* Add changeset for new tool integrations and bug fixes

* Update changeset with IBM Bob support and pi.dev fix
2026-04-11 15:39:42 +00:00
94d651de8c feat: add support for IBM Bob coding assistant (#886)
* test: add comprehensive tests for Bob Shell adapter

- Add 7 tests covering toolId, file paths, formatting, and edge cases
- Include Bob Shell adapter in cross-platform path handling tests
- All 89 adapter tests now passing
- Ensures Bob Shell adapter works correctly with all 11 workflows

* feat: add Bob Shell adapter support

- Implement Bob Shell command adapter with YAML frontmatter
- Register adapter in CommandAdapterRegistry
- Export adapter from adapters/index.ts
- Add Bob Shell to AI_TOOLS configuration
- Generates commands in .bob/commands/opsx-<id>.md format
- Supports all 11 workflows via custom profile system

* docs: add Bob Shell to supported tools documentation

- Add Bob Shell to README.md supported tools list
- Update docs/supported-tools.md with Bob Shell entry
- Document .bob/commands/opsx-<id>.md command path pattern
- Note that Bob Shell uses commands, not Agent Skills spec

* docs: add Bob Shell support proposal and design documentation

- Add comprehensive proposal for Bob Shell integration
- Document command structure and file format
- Include implementation plan and success criteria
- Preserve change documentation for future reference

* chore: update dependencies and gitignore

- Update package-lock.json with latest dependencies
- Add .bob/ to gitignore (test output directory)

* chore: update gitignore to exclude .bob directory

* openspec change not needed for project, should be kept local

* Update reference from Bob Shell to IBM Bob Shell

* fix: transform command references and add argument-hint for Bob adapter

Bob derives command names from filenames (opsx-apply.md → /opsx-apply),
so body text referencing /opsx:apply is incorrect. Apply the same
transformToHyphenCommands rewrite that opencode.ts uses. Also add
argument-hint frontmatter to match peer adapters (auggie, codebuddy, etc).

---------

Co-authored-by: TabishB <tabishbidiwale@gmail.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-04-11 15:31:45 +00:00
Tabish Bidiwale 040e382d64 test: fix windows powershell ci (#951) 2026-04-11 15:17:00 +00:00
Tabish Bidiwale caafd7c9bf fix: pi.dev command reference transforms and template args passing (#950)
* fix: pi.dev prompt naming and template args passing (#912)

Fix two pi.dev integration bugs:
- Use colon-based filenames (opsx:explore.md) so CLI commands render as
  /opsx:explore instead of /opsx-explore
- Inject $@ into template body so user arguments are passed through

Adds getLegacyFilePaths to ToolCommandAdapter for migration-safe cleanup
of old hyphenated files during init/update.

* fix: pi.dev command references and template args passing (#912)

- Transform /opsx: references to /opsx- in Pi command bodies and skills,
  matching the hyphenated filename convention (same approach as OpenCode)
- Inject $@ into template body so user arguments are passed through

Pi uses the filename (minus .md) as the slash command name, so
opsx-propose.md becomes /opsx-propose. This keeps filenames
cross-platform safe while ensuring command references in the body
match the actual command names.
2026-04-11 15:00:46 +00:00
Tabish Bidiwale 144528257d fix: make completion install opt-in, fix PowerShell encoding corruption (#949)
* fix: make shell completion install opt-in and fix PowerShell profile encoding corruption (#948)

The postinstall hook silently modified users' shell profiles and corrupted
UTF-16 LE PowerShell profiles by forcing all reads/writes through UTF-8.
Now postinstall only prints a tip, and the PowerShell installer preserves
file encoding via BOM detection on read/write.

* Address review: skip profile on any read error, log warnings, clean up UTF-16 BE handling

- configureProfile: skip profile on any non-ENOENT error instead of falling
  through with empty content (could overwrite real profile)
- removeProfileConfig: log warning on unexpected read errors instead of
  silently swallowing
- detectEncoding: throw directly for UTF-16 BE instead of using sentinel value
- Add test for UTF-16 BE profile rejection
2026-04-11 13:58:24 +00:00
Irina ChichikovaandTabishB af0b3418d0 Add support for Junie from JetBrains tool and command generation (#853)
* Add support for Junie from JetBrains tool and command generation

* Expand Junie support to include `opsx` file patterns and update documentation accordingly

---------

Co-authored-by: TabishB <tabishbidiwale@gmail.com>
2026-04-10 01:01:38 +00:00
7fd5417ed0 style: Fix formatting of user facing and agent facing diagrams and markdown tables (#892)
* style: Fix formatting of user facing and agent facing diagrams and markdown tables

* test: update template parity hashes for formatting changes

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
Co-authored-by: TabishB <tabishbidiwale@gmail.com>
2026-04-09 07:26:45 +00:00
mrack688andMarck 5ac1e12b83 feat: add Lingma IDE support to configuration (#864)
feat: add Lingma IDE support to configuration
feat: add Lingma IDE support to configuration

Co-authored-by: Marck <6992917@qq.com>
2026-04-09 06:25:27 +00:00
Gregor Albrecht fd7ad273c7 Fix formatting in concepts.md (#882) 2026-04-09 03:34:41 +00:00
Harry James Hall ea6f380fea feat: add ForgeCode tool support (#941) 2026-04-09 03:13:30 +00:00
XingxingandClaude Opus 4.6 765df47ad3 fix(init): prevent false GitHub Copilot auto-detection from bare .github/ directory (#917)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 03:13:04 +00:00
Alfred 64d476f8b9 ci: add merge_group support for merge queue (#918) 2026-04-05 06:56:59 +00:00
afdca0d5da fix(status): exit gracefully when no changes exist (#759)
* fix(status): exit gracefully when no changes exist (#714)

Extract `getAvailableChanges` as a public function from `validateChangeExists`
and use it in `statusCommand` to detect the no-changes case early. Returns a
friendly message (text and JSON modes) with exit code 0 instead of a fatal error.

Generated with Claude Code using claude-opus-4-6.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: fix design risk description and proposal accuracy

Address CodeRabbit review feedback:
- Fix contradictory risk description in design.md (double-read happens
  when changes exist, not when they don't)
- Clarify in proposal.md that validateChangeExists was internally
  refactored to delegate to getAvailableChanges

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(status): narrow catch in getAvailableChanges to ENOENT only

Return [] only when the changes directory doesn't exist (ENOENT).
Rethrow other errors (EACCES, etc.) so real filesystem issues
surface instead of being silently masked as "no changes".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-02-27 00:52:22 -08:00
61eb999f7c fix(opencode): use plural commands/ directory to match OpenCode convention (#760)
* fix(opencode): use plural `commands/` directory to match OpenCode convention

The OpenCode adapter was using `.opencode/command/` (singular) but OpenCode's
official documentation specifies `.opencode/commands/` (plural). This aligns
with every other adapter in the codebase. Legacy cleanup updated to detect
old singular-path artifacts. Fixes #748.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(legacy): detect both opsx-* and openspec-* patterns, auto-cleanup in CI

- Extend LegacySlashCommandPattern.pattern to accept string | string[]
- OpenCode legacy entry now detects both opsx-*.md and openspec-*.md
- Auto-cleanup legacy artifacts in non-interactive mode instead of
  aborting with exit 1 (safe: slash commands are OpenSpec-managed,
  config cleanup only removes markers)
- Add 7 tests (6 legacy detection + 1 non-interactive init)
- Update spec with array pattern support and auto-cleanup scenario

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: update task description to reflect dual-pattern support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-02-27 00:08:22 -08:00
3d3bf96061 docs: fix openspec status examples in cli.md (#761)
* docs: fix `openspec status` examples in cli.md to match actual CLI output

The text and JSON output examples for the status command used incorrect
field names, indicators, and structure. Updated to match real CLI output,
validated against a test project with partial artifacts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove spec change and changeset for docs-only fix

Per reviewer feedback — docs fixes don't need a spec change or
version bump.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-02-26 23:37:28 -08:00
JabinGP d199dfa407 docs: fix docs/concepts nested code-block format (#763) 2026-02-26 10:15:27 +00:00
Tabish Bidiwale d7d186088e docs: realign defaults, profile workflows, and tool references (#746)
* docs: realign defaults, workflows, and tool references

* docs: resolve Trae wording and opsx diagram alignment

* chore: ignore codex workspace directory
2026-02-23 18:27:23 -08:00
openspec-release-bot[bot]andgithub-actions[bot] 6a3a1263fe Version Packages (#751)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-23 15:43:08 -08:00
Tabish Bidiwale 1e94443a35 Add changeset for profiles, Pi, Kiro, and bug fixes (#747) 2026-02-23 15:37:30 -08:00
Tabish Bidiwale a0608d0bab Sync update to prune deselected workflows (#741) 2026-02-22 05:35:01 -08:00
329 changed files with 42722 additions and 1100 deletions
+13 -11
View File
@@ -12,11 +12,12 @@ Follow the prompts to select version bump type and describe your changes.
## Workflow
1. **Add a changeset** — Run `pnpm changeset` locally before or after your PR
2. **Version PR** — CI opens/updates a "Version Packages" PR when changesets merge to main
3. **Release** — Merging the Version PR triggers npm publish and GitHub Release
1. **Choose the release path**: Maintainers decide whether a PR follows the normal release cadence or gets dedicated release tracking.
2. **Add dedicated release tracking**: When a maintainer asks for a changeset, run `pnpm changeset` locally before or after your PR.
3. **Version PR**: CI opens/updates a "Version Packages" PR when changesets merge to main.
4. **Release**: Merging the Version PR triggers npm publish and GitHub Release.
> **Note:** Contributors only need to run `pnpm changeset`. Versioning (`changeset version`) and publishing happen automatically in CI.
> **Note:** The default path is the normal release cadence. Add a changeset when a maintainer or release owner wants dedicated release notes and version tracking for the PR. Versioning (`changeset version`) and publishing happen automatically in CI.
## Template
@@ -54,22 +55,23 @@ Include only the sections relevant to your change.
| Type | When to use | Example |
|------|-------------|---------|
| `patch` | Bug fixes, small improvements | Fixed crash when config missing |
| `patch` | Release-tracked bug fixes, small improvements | Fixed crash when config missing |
| `minor` | New features, non-breaking additions | Added `--verbose` flag |
| `major` | Breaking changes, removed features | Renamed `init` to `setup` |
## When to Create a Changeset
**Create one for:**
- New features or commands
- Bug fixes that affect users
**Use dedicated release tracking for:**
- New features or commands selected for release
- Notable bug fixes or hotfixes requested by a maintainer/release owner
- Breaking changes or deprecations
- Performance improvements users would notice
- Performance improvements users would notice and that are planned for release
**Skip for:**
**Use the normal release cadence for:**
- Routine bug fixes that fit the normal release cadence
- Documentation-only changes
- Test additions/fixes
- Internal refactoring with no user impact
- Internal refactoring that preserves user behavior
- CI/tooling changes
## Writing Good Descriptions
+34 -12
View File
@@ -3,6 +3,8 @@ name: CI
on:
pull_request:
branches: [main]
merge_group:
branches: [main]
push:
branches: [main]
workflow_dispatch:
@@ -42,7 +44,7 @@ jobs:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 10
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
steps:
- name: Checkout code
@@ -81,7 +83,7 @@ jobs:
name: Test (${{ matrix.label }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
if: github.event_name != 'pull_request'
if: github.event_name == 'push'
strategy:
fail-fast: false
matrix:
@@ -240,42 +242,62 @@ jobs:
run: git checkout -- flake.nix || true
validate-changesets:
name: Validate Changesets
name: Validate Release Tracking
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Determine release tracking
id: changed-changesets
run: |
changed_changesets="$(git diff --name-only --diff-filter=ACMRT origin/main...HEAD -- '.changeset/*.md' ':!.changeset/README.md')"
if [[ -n "$changed_changesets" ]]; then
echo "has_changesets=true" >> "$GITHUB_OUTPUT"
{
echo "files<<EOF"
echo "$changed_changesets"
echo "EOF"
} >> "$GITHUB_OUTPUT"
else
echo "has_changesets=false" >> "$GITHUB_OUTPUT"
echo "This PR follows the normal release cadence; continuing with standard validation"
fi
- name: Setup pnpm
if: steps.changed-changesets.outputs.has_changesets == 'true'
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
if: steps.changed-changesets.outputs.has_changesets == 'true'
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
if: steps.changed-changesets.outputs.has_changesets == 'true'
run: pnpm install --frozen-lockfile
- name: Validate changesets
- name: Validate release-tracked changesets
if: steps.changed-changesets.outputs.has_changesets == 'true'
env:
CHANGESET_FILES: ${{ steps.changed-changesets.outputs.files }}
run: |
if command -v changeset &> /dev/null; then
pnpm exec changeset status --since=origin/main
else
echo "Changesets not configured, skipping validation"
fi
echo "Validating changed changesets:"
printf '%s\n' "$CHANGESET_FILES"
pnpm exec changeset status --since=origin/main
required-checks-pr:
name: All checks passed
runs-on: ubuntu-latest
needs: [test_pr, lint, nix-flake-validate]
if: always() && github.event_name == 'pull_request'
if: always() && (github.event_name == 'pull_request' || github.event_name == 'merge_group')
steps:
- name: Verify all checks passed
run: |
@@ -301,7 +323,7 @@ jobs:
name: All checks passed
runs-on: ubuntu-latest
needs: [test_matrix, lint, nix-flake-validate]
if: always() && github.event_name != 'pull_request'
if: always() && github.event_name == 'push'
steps:
- name: Verify all checks passed
run: |
+6
View File
@@ -153,3 +153,9 @@ result
# OpenCode
.opencode/
opencode.json
# Codex
.codex/
# Bob
.bob/
+90
View File
@@ -1,5 +1,95 @@
# @fission-ai/openspec
## 1.4.0
### Minor Changes
- [#1003](https://github.com/Fission-AI/OpenSpec/pull/1003) [`342ed43`](https://github.com/Fission-AI/OpenSpec/commit/342ed43e694abba65a3ea275f94ba3b77df85da3) Thanks [@Miss-you](https://github.com/Miss-you)! - ### 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
- [#1154](https://github.com/Fission-AI/OpenSpec/pull/1154) [`aa16080`](https://github.com/Fission-AI/OpenSpec/commit/aa16080d16b70f7b26cebd465334b2e16c0e7a43) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
- **Mistral Vibe support** — OpenSpec can now initialize Mistral Vibe as a supported skills-only tool using `.vibe/skills/`
### Bug Fixes
- **Case-insensitive requirement headers** — Requirement headers are now parsed regardless of capitalization, so specs no longer fail to parse over header casing
- **Zsh completions on oh-my-zsh** — Fixed shell completion setup so tab completion installs correctly under oh-my-zsh's `compinit`
### Other
- **Clearer validation hints** — When a requirement has SHALL/MUST only in its header, `openspec validate` now points you to move the keyword onto the requirement body line instead of showing the generic error
- [#1030](https://github.com/Fission-AI/OpenSpec/pull/1030) [`485c97e`](https://github.com/Fission-AI/OpenSpec/commit/485c97e97d766e35dd16c02370baee2044abc4f4) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
- Include the sync workflow in the default core profile so new installs generate `/opsx:sync` skills and commands by default.
### Patch Changes
- [#1111](https://github.com/Fission-AI/OpenSpec/pull/1111) [`7fdb177`](https://github.com/Fission-AI/OpenSpec/commit/7fdb1771585b1688597d73dde5a8bc906084d0de) Thanks [@TabishB](https://github.com/TabishB)! - ### Fixed
- Preserve workspace planning detection when Windows short paths or symlink aliases resolve to a canonical workspace root.
## 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
+16 -14
View File
@@ -36,27 +36,20 @@ Our philosophy:
> [!TIP]
> **New workflow now available!** We've rebuilt OpenSpec with a new artifact-guided workflow.
>
> Run `/opsx:onboard` to get started. → [Learn more here](docs/opsx.md)
> Run `/opsx:propose "your idea"` to get started. → [Learn more here](docs/opsx.md)
<p align="center">
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
</p>
### Teams
Using OpenSpec in a team? [Email here](mailto:teams@openspec.dev) for access to our Slack channel.
<!-- TODO: Add GIF demo of /opsx:new → /opsx:archive workflow -->
<!-- TODO: Add GIF demo of /opsx:propose → /opsx:archive workflow -->
## See it in action
```text
You: /opsx:new add-dark-mode
You: /opsx:propose add-dark-mode
AI: Created openspec/changes/add-dark-mode/
Ready to create: proposal
You: /opsx:ff # "fast-forward" - generate all planning docs
AI: ✓ proposal.md — why we're doing this, what's changing
✓ proposal.md — why we're doing this, what's changing
✓ specs/ — requirements and scenarios
✓ design.md — technical approach
✓ tasks.md — implementation checklist
@@ -101,10 +94,12 @@ cd your-project
openspec init
```
Now tell your AI: `/opsx:new <what-you-want-to-build>`
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`.
> [!NOTE]
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 20+ tools and growing.
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 25+ tools and growing.
>
> Also works with pnpm, yarn, bun, and nix. [See installation options](docs/installation.md).
@@ -120,6 +115,13 @@ Now tell your AI: `/opsx:new <what-you-want-to-build>`
→ **[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.
@@ -155,7 +157,7 @@ openspec update
## Usage Notes
**Model selection**: OpenSpec works best with high-reasoning models. We recommend Opus 4.5 and GPT 5.2 for both planning and implementation.
**Model selection**: OpenSpec works best with high-reasoning models. We recommend Codex 5.5 and Opus 4.7 for both planning and implementation.
**Context hygiene**: OpenSpec benefits from a clean context window. Clear your context before starting implementation and maintain good context hygiene throughout your session.
+3 -1
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env node
import '../dist/cli/index.js';
import { runCli } from '../dist/cli/index.js';
runCli();
+414 -24
View File
@@ -1,16 +1,18 @@
# 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:new`) 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:propose`) 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`, `workspace update`, `workspace open` | Set up local views over linked repos or folders |
| **Shared context (beta)** | `context-store setup`, `context-store register`, `context-store unregister`, `context-store remove`, `context-store list`, `context-store doctor`, `initiative create`, `initiative show`, `initiative list` | Manage local context-store registrations and durable initiative context |
| **Browsing** | `list`, `view`, `show` | Explore changes and specs |
| **Validation** | `validate` | Check changes and specs for issues |
| **Lifecycle** | `archive` | Finalize completed changes |
| **Workflow** | `status`, `instructions`, `templates`, `schemas` | Artifact-driven workflow support |
| **Workflow** | `new change`, `set change`, `status`, `instructions`, `templates`, `schemas` | Artifact-driven workflow support |
| **Schemas** | `schema init`, `schema fork`, `schema validate`, `schema which` | Create and manage custom workflows |
| **Config** | `config` | View and modify settings |
| **Utility** | `feedback`, `completion` | Feedback and shell integration |
@@ -46,6 +48,22 @@ 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 |
| `openspec workspace update` | Refresh workspace-local guidance and agent skills | `--tools` selects agents; profile selects workflows |
| `openspec context-store setup <id>` | Create a local context store | `--json` with explicit inputs for structured setup output |
| `openspec context-store register <path>` | Register an existing context store | `--json` for structured registration output |
| `openspec context-store unregister <id>` | Forget a local context-store registration | `--json` for structured cleanup output |
| `openspec context-store remove <id>` | Delete a registered local context-store folder | `--yes --json` for non-interactive deletion |
| `openspec context-store list` | Browse registered context stores | `--json` for structured registrations |
| `openspec context-store doctor` | Check local store setup | `--json` for structured diagnostics |
| `openspec initiative list` | Browse shared initiatives | `--json` for structured initiative records |
| `openspec initiative show <id>` | Resolve an initiative | `--json` for canonical paths and metadata |
| `openspec new change <id>` | Create repo-local change scaffolding | `--json`, plus `--initiative` for shared coordination links |
| `openspec set change <id>` | Update checked-in change metadata | `--json`, plus `--initiative` for shared coordination links |
---
@@ -67,6 +85,8 @@ 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]
```
@@ -83,8 +103,11 @@ 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`) |
**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`
`--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`
**Examples:**
@@ -101,6 +124,9 @@ 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
```
@@ -113,8 +139,9 @@ openspec/
├── changes/ # Proposed changes
└── config.yaml # Project configuration
.claude/skills/ # Claude Code skill files (if claude selected)
.cursor/rules/ # Cursor rules (if cursor selected)
.claude/skills/ # Claude Code skills (if claude selected)
.cursor/skills/ # Cursor skills (if cursor selected)
.cursor/commands/ # Cursor OPSX commands (if delivery includes commands)
... (other tool configs)
```
@@ -122,7 +149,7 @@ openspec/
### `openspec update`
Update OpenSpec instruction files after upgrading the CLI. Re-generates AI tool configuration files.
Update OpenSpec instruction files after upgrading the CLI. Re-generates AI tool configuration files using your current global profile, selected workflows, and delivery mode.
```
openspec update [path] [options]
@@ -150,6 +177,321 @@ openspec update
---
## Workspace Commands
Workspace commands are in beta. The local-view model below is the current direction, but external automation, integrations, and long-lived workflows should still treat command behavior, state files, and JSON output as evolving.
Coordination workspaces are machine-local views over linked 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 |
| `--opener <id>` | Store a preferred opener during non-interactive setup: `codex-cli`, `claude`, `github-copilot`, or `editor` |
| `--tools <tools>` | Install workspace-local OpenSpec skills for agents. Use `all`, `none`, or comma-separated tool IDs |
| `--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 --name platform --link /repos/api --opener codex-cli
openspec workspace setup --no-interactive --name platform --link /repos/api --tools codex,claude
openspec workspace setup --no-interactive --json --name checkout --link /repos/platform/apps/checkout
```
Interactive setup asks for a preferred opener and can install workspace-local OpenSpec skills for selected agents. Non-interactive setup stores a preferred opener only when `--opener` is provided; otherwise `workspace open` prompts later in interactive terminals when a supported opener is available, or asks scripts to pass `--agent <tool>` or `--editor`.
Workspace skill installation is skills-only in this beta slice: even if global delivery is `commands` or `both`, workspace setup writes agent skill folders in the workspace root and does not create slash command files. The active global profile chooses which workflow skills are installed; `--tools` chooses which agents receive them. If `--tools` is omitted in non-interactive setup, no skills are installed and `workspace update --tools <ids>` can add them later.
### `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, linked repos or folders, missing paths, repo-local specs paths when present, and suggested fixes. JSON output also includes the workspace planning path for compatibility. 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`.
### `openspec workspace update`
Refresh workspace-local OpenSpec guidance and agent skills.
```bash
openspec workspace update [name] [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--workspace <name>` | Select a known workspace from the local registry |
| `--tools <tools>` | Select agents for workspace skills. Use `all`, `none`, or comma-separated tool IDs |
| `--json` | Output JSON |
| `--no-interactive` | Disable workspace picker prompts |
**Examples:**
```bash
openspec workspace update
openspec workspace update platform
openspec workspace update --workspace platform --tools codex,claude
openspec workspace update --workspace platform --tools none
```
`workspace update` refreshes the generated workspace guidance block and local open surface. For agent skills, it reuses the stored workspace skill agent selection when `--tools` is omitted. Passing `--tools` replaces that stored selection. It refreshes only OpenSpec-managed workflow skill directories in the workspace root, removes deselected managed workflow skills, and leaves linked repos and folders untouched.
Running `openspec update` from inside a workspace redirects to `openspec workspace update`; run `openspec update` inside repo-local projects when you want repo-owned tool files updated.
### `openspec workspace open`
Open a workspace working set through the stored preferred opener, a one-session agent override, or VS Code editor mode.
```bash
openspec workspace open [name] [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--workspace <name>` | Alias for the positional workspace name |
| `--initiative <id>` | Open an initiative as a local workspace view. Accepts `<id>` or `<store>/<id>` |
| `--store <id>` | Registered context store id for `--initiative` |
| `--store-path <path>` | Existing local context store root for `--initiative` |
| `--agent <tool>` | One-session agent override: `codex-cli`, `claude`, or `github-copilot` |
| `--editor` | Open the maintained VS Code workspace file as a normal editor workspace |
| `--no-interactive` | Disable workspace and opener picker prompts |
**Examples:**
```bash
openspec workspace open
openspec workspace open platform
openspec workspace open platform --agent github-copilot
openspec workspace open --agent codex-cli
openspec workspace open --editor
openspec workspace open --initiative billing-launch --store platform
openspec workspace open --initiative platform/billing-launch
```
`workspace open` uses the current workspace when run inside one, auto-selects the only known workspace when run elsewhere, and asks the user to choose when multiple workspaces are known. `--agent` and `--editor` do not change the stored preferred opener. Passing both opener overrides is an error; choose either `--agent <tool>` or `--editor`.
When `--initiative` is used, OpenSpec prepares or selects a private local workspace view for that initiative. Registry-selected stores are stored by id; `--store-path` stores a runtime-local path selector because workspace views are private local state.
OpenSpec maintains `<workspace-name>.code-workspace` at the workspace root for VS Code editor and GitHub Copilot-in-VS-Code opens. That file is machine-local workspace view state.
The maintained VS Code workspace lists valid linked repos or folders first, then initiative context when attached, then the OpenSpec workspace files. VS Code displays those entries as a multi-root workspace.
Root workspace open makes linked repos or folders visible for exploration and context. Implementation edits should start only after an explicit user request and a normal OpenSpec implementation workflow.
---
## Shared Context Commands
Context stores and initiatives are beta coordination surfaces. A context store is a local registration for durable shared context, usually a Git-backed folder or clone. An initiative is shared coordination context inside a context store; repo-local changes can link to it without copying the shared plan into every repo.
### `openspec context-store setup`
Create and register a local context store. With no arguments in a terminal,
OpenSpec guides the user through setup. Agents and scripts should pass explicit
inputs and use `--json`.
```bash
openspec context-store setup [id] [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--path <path>` | Context store folder path; defaults to OpenSpec's managed local data directory |
| `--init-git` | Initialize a Git repository in the context store |
| `--no-init-git` | Do not initialize a Git repository |
| `--json` | Output JSON |
When `--path` is omitted, setup creates the store under `getGlobalDataDir()/context-stores/<id>`: `$XDG_DATA_HOME/openspec/context-stores/<id>` when `XDG_DATA_HOME` is set, or `~/.local/share/openspec/context-stores/<id>` on Unix-style fallbacks. Pass `--path` when you want the store in a visible clone or team-specific folder.
Examples:
```bash
openspec context-store setup
openspec context-store setup team-context
openspec context-store setup team-context --path /repos/team-context --no-init-git
openspec context-store setup team-context --json --no-init-git
```
### `openspec context-store register`
Register an existing local context store folder.
```bash
openspec context-store register [path] [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--id <id>` | Context store id; defaults to store metadata or folder name |
| `--json` | Output JSON |
### `openspec context-store unregister`
Forget a local context-store registration without deleting files.
```bash
openspec context-store unregister <id> [--json]
```
Use this when a store was moved, cloned somewhere else, or should no longer be
shown by OpenSpec on this machine.
### `openspec context-store remove`
Forget a local context-store registration and delete its local folder.
```bash
openspec context-store remove <id> [--yes] [--json]
```
`remove` shows the exact folder before deleting in an interactive terminal.
Agents, scripts, and JSON callers must pass `--yes` to confirm deletion.
OpenSpec refuses to delete a folder that does not contain matching
context-store metadata.
### `openspec context-store list`
List locally registered context stores.
```bash
openspec context-store list [--json]
openspec context-store ls [--json]
```
### `openspec context-store doctor`
Check local context-store registration, metadata, and Git presence.
```bash
openspec context-store doctor [id] [--json]
```
Doctor is diagnostic-only; it reports missing roots, metadata mismatches, and invalid local registry state without modifying the store.
### `openspec initiative create`
Create an initiative in a context store.
```bash
openspec initiative create <id> --title <title> --summary <summary> [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--store <id>` | Context store id from the local registry |
| `--store-path <path>` | Existing local context store root |
| `--title <title>` | Initiative title |
| `--summary <summary>` | Initiative summary |
| `--json` | Output JSON |
### `openspec initiative list`
List initiatives. Without a selector, this searches all registered context stores and reports partial-read warnings in `status`.
```bash
openspec initiative list [options]
openspec initiative ls [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--store <id>` | List one registered context store |
| `--store-path <path>` | List one existing local context store root |
| `--json` | Output JSON |
### `openspec initiative show`
Resolve an initiative and print its canonical location.
```bash
openspec initiative show <id> [options]
openspec initiative show <store>/<id> [options]
```
Without `--store`, OpenSpec searches registered context stores. If the same initiative id exists in multiple stores, pass `--store <id>` or use the `<store>/<id>` form.
---
## Browsing Commands
### `openspec list`
@@ -394,6 +736,53 @@ openspec archive update-ci-config --skip-specs
These commands support the artifact-driven OPSX workflow. They're useful for both humans checking progress and agents determining next steps.
### `openspec new change`
Create a repo-local change directory and optional checked-in metadata.
```bash
openspec new change <name> [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--description <text>` | Description to add to `README.md` |
| `--goal <text>` | Workspace product goal to store with the change |
| `--areas <names>` | Comma-separated affected workspace link names |
| `--initiative <id>` | Link the repo-local change to an initiative |
| `--store <id>` | Context store id for `--initiative` |
| `--store-path <path>` | Existing local context store root for `--initiative` |
| `--schema <name>` | Workflow schema to use |
| `--json` | Output JSON |
Examples:
```bash
openspec new change add-billing-api --initiative billing-launch --store platform
openspec new change add-billing-api --initiative platform/billing-launch --json
```
### `openspec set change`
Update checked-in repo-local change metadata without recreating the change.
```bash
openspec set change <name> [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--initiative <id>` | Link the repo-local change to an initiative |
| `--store <id>` | Context store id for `--initiative` |
| `--store-path <path>` | Existing local context store root for `--initiative` |
| `--json` | Output JSON |
`set change --initiative` is idempotent when the requested link already exists and refuses to replace a different existing initiative link.
### `openspec status`
Display artifact completion status for a change.
@@ -428,29 +817,28 @@ openspec status --change add-dark-mode --json
```
Change: add-dark-mode
Schema: spec-driven
Progress: 2/4 artifacts complete
Artifacts:
✓ proposal proposal.md exists
✓ specs specs/ exists
◆ design ready (requires: specs)
○ tasks blocked (requires: design)
Next: Create design using /opsx:continue
[x] proposal
[ ] design
[x] specs
[-] tasks (blocked by: design)
```
**Output (JSON):**
```json
{
"change": "add-dark-mode",
"schema": "spec-driven",
"changeName": "add-dark-mode",
"schemaName": "spec-driven",
"isComplete": false,
"applyRequires": ["tasks"],
"artifacts": [
{"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"
{"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"]}
]
}
```
@@ -810,9 +1198,9 @@ openspec config profile core
- 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`.
If there are no config changes but the current project or workspace files are out of sync with your global profile/delivery, OpenSpec will show a warning and suggest `openspec update` for repo-local projects or `openspec workspace update` for workspace-local guidance and skills.
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).
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). From inside a workspace, use `openspec workspace update` to refresh workspace-local guidance and skills; this remains skills-only for generated agent workflow files and does not generate workspace slash commands.
**Interactive examples:**
@@ -912,6 +1300,8 @@ 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 |
@@ -920,7 +1310,7 @@ openspec completion uninstall
## Related Documentation
- [Commands](commands.md) - AI slash commands (`/opsx:new`, `/opsx:apply`, etc.)
- [Commands](commands.md) - AI slash commands (`/opsx:propose`, `/opsx:apply`, etc.)
- [Workflows](workflows.md) - Common patterns and when to use each command
- [Customization](customization.md) - Create custom schemas and templates
- [Getting Started](getting-started.md) - First-time setup guide
+63 -13
View File
@@ -6,23 +6,70 @@ 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: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 |
### Expanded Workflow Commands (custom workflow selection)
| Command | Purpose |
|---------|---------|
| `/opsx:new` | Start a new change scaffold |
| `/opsx:continue` | Create the next artifact based on dependencies |
| `/opsx:ff` | Fast-forward: create all planning artifacts at once |
| `/opsx:verify` | Validate implementation matches artifacts |
| `/opsx:bulk-archive` | Archive multiple changes at once |
| `/opsx:onboard` | Guided tutorial through the complete workflow |
The default global profile is `core`. To enable expanded workflow commands, run `openspec config profile`, select workflows, then run `openspec update` in your project.
---
## Command Reference
### `/opsx:propose`
Create a new change and generate planning artifacts in one step. This is the default start command in the `core` profile.
**Syntax:**
```text
/opsx:propose [change-name-or-description]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name-or-description` | No | Kebab-case name or plain-language change description |
**What it does:**
- Creates `openspec/changes/<change-name>/`
- Generates artifacts needed before implementation (for `spec-driven`: proposal, specs, design, tasks)
- Stops when the change is ready for `/opsx:apply`
**Example:**
```text
You: /opsx:propose add-dark-mode
AI: Created openspec/changes/add-dark-mode/
✓ proposal.md
✓ specs/ui/spec.md
✓ design.md
✓ tasks.md
Ready for implementation. Run /opsx:apply.
```
**Tips:**
- Use this for the fastest end-to-end path
- If you want step-by-step artifact control, enable expanded workflows and use `/opsx:new` + `/opsx:continue`
---
### `/opsx:explore`
Think through ideas, investigate problems, and clarify requirements before committing to a change.
@@ -42,7 +89,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:new` when insights crystallize
- Can transition to `/opsx:propose` (default) or `/opsx:new` (expanded workflow) when insights crystallize
**Example:**
```text
@@ -66,7 +113,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:new add-jwt-auth to begin.
AI: Ready when you are. Run /opsx:propose add-jwt-auth to begin.
```
**Tips:**
@@ -79,7 +126,9 @@ AI: Ready when you are. Run /opsx:new add-jwt-auth to begin.
### `/opsx:new`
Start a new change. Creates the change folder structure and scaffolds it with the selected schema.
Start a new change scaffold. Creates the change folder and waits for you to generate artifacts with `/opsx:continue` or `/opsx:ff`.
This command is part of the expanded workflow set (not included in the default `core` profile).
**Syntax:**
```
@@ -565,13 +614,14 @@ Different AI tools use slightly different command syntax. Use the format that ma
| Tool | Syntax Example |
|------|----------------|
| Claude Code | `/opsx:new`, `/opsx:apply` |
| Cursor | `/opsx-new`, `/opsx-apply` |
| Windsurf | `/opsx-new`, `/opsx-apply` |
| Copilot (IDE) | `/opsx-new`, `/opsx-apply` |
| Trae | `/openspec-new-change`, `/openspec-apply-change` |
| Claude Code | `/opsx:propose`, `/opsx:apply` |
| Cursor | `/opsx-propose`, `/opsx-apply` |
| Windsurf | `/opsx-propose`, `/opsx-apply` |
| Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
| Kimi CLI | Skill-based invocations such as `/skill:openspec-propose`, `/skill:openspec-apply-change` (no generated `opsx-*` command files) |
| Trae | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) |
The functionality is identical regardless of syntax.
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.
+168 -27
View File
@@ -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,6 +49,147 @@ 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 in beta. The local-view model below is the current direction, but external automation, integrations, and long-lived workflows should still treat command behavior, state files, and JSON output as evolving.
The commands below provide the first setup flow for opening local views over 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 a machine-local view that keeps linked paths, opener state, and agent setup together.
The workspace mental model is:
```text
workspace = private local view over context stores, initiatives, repos, and folders
context store = durable shared context container
initiative = durable coordination context inside a context store
link = a stable name for a repo or folder the workspace can resolve locally
change = one planned piece of work; implementation belongs in the owning repo
```
A workspace has a different shape from a repo-local project:
```text
getGlobalDataDir()/workspaces/<workspace-name>/
├── workspace.yaml # Private local view record
├── AGENTS.md # Generated runtime guidance
└── <workspace-name>.code-workspace # Generated editor workspace file
```
Repo-local OpenSpec state keeps the existing shape:
```text
repo-root/
└── openspec/
├── specs/
└── changes/
```
That distinction matters. The workspace folder is a local coordination surface for opening and inspecting 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 a workspace refers to repos and folders. The private workspace record keeps names such as `api`, `web`, or `checkout` and maps them to this runtime's local paths.
```yaml
# workspace.yaml
version: 1
name: platform
context: null
links:
api: /repos/api
web: /repos/web
```
When a workspace opens an initiative, `context` records the selected context-store binding and initiative id. Registry-selected stores stay portable by id; path-selected stores intentionally preserve the runtime-local path because `workspace.yaml` is private local state.
```yaml
context:
kind: initiative
store:
id: platform
selector:
kind: registry
id: platform
initiative:
id: billing-launch
```
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 can still read older beta workspace roots as compatibility inputs, but managed workspaces now use the root `workspace.yaml` record above. The workspace folder remains authoritative for its own private local view.
Workspace visibility is not change commitment. Set up a workspace when OpenSpec should know which repos or folders are relevant; create a change later when you are ready to plan a feature, fix, project, or other piece of work.
Useful commands:
```bash
# Guided setup
openspec workspace setup
# Automation-friendly setup
openspec workspace setup --no-interactive --name platform --link /repos/api --link web=/repos/web
openspec workspace setup --no-interactive --name platform --link /repos/api --opener codex-cli
# 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
# Refresh workspace-local guidance and agent skills
openspec workspace update
openspec workspace update --workspace platform --tools codex,claude
# Open the linked working set
openspec workspace open
openspec workspace open platform --agent github-copilot
openspec workspace open --editor
# Open an initiative as a local workspace view
openspec workspace open --initiative billing-launch --store platform
openspec workspace open --initiative billing-launch --store-path /repos/platform-context
```
`workspace setup` always creates the workspace in the standard workspace location, records it in the local registry, shows the workspace location, and requires at least one linked repo or folder. Interactive setup asks for a preferred opener and can install OpenSpec skills for selected agents. Non-interactive setup stores one only when `--opener codex-cli`, `--opener claude`, `--opener github-copilot`, or `--opener editor` is provided.
Workspace skills are installed only in the workspace root. The active global profile selects which workflow skills are generated; `--tools` selects which agents receive them. Workspace setup and update do not create slash command files even when global delivery includes commands. Run `openspec workspace update` to refresh workspace-local guidance and add, refresh, or remove managed workspace-local skill directories without editing linked repos or folders.
OpenSpec also maintains root workspace open files: an OpenSpec-managed guidance block in `AGENTS.md` and a machine-local `<workspace-name>.code-workspace` file for VS Code and GitHub Copilot-in-VS-Code opens. A managed workspace is not a repo, so OpenSpec does not create a default workspace `.gitignore` or a default workspace-level `changes/` directory.
The maintained VS Code workspace lists valid linked repos or folders first, then initiative context when attached, then the OpenSpec workspace files. VS Code displays those entries as a multi-root workspace.
`workspace open` opens the linked working set with the stored preferred opener unless `--agent <tool>` or `--editor` is passed for that one session. Passing both opener overrides is an error. Root workspace open makes linked repos and folders visible for exploration and context; implementation starts after the user explicitly asks for implementation work.
`workspace link` and `workspace relink` record existing folders only; they do not create, copy, move, initialize, or edit the linked repo or folder. After a successful link or relink, OpenSpec refreshes the managed guidance and VS Code workspace file.
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.
@@ -270,7 +411,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
@@ -306,7 +447,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
@@ -558,17 +699,17 @@ openspec/
## How It All Fits Together
```
┌─────────────────────────────────────────────────────────────────────────────┐
┌──────────────────────────────────────────────────────────────────────────────┐
│ OPENSPEC FLOW │
│ │
│ ┌────────────────┐ │
│ │ 1. START │ /opsx:new creates a change folder │
│ │ 1. START │ /opsx:propose (core) or /opsx:new (expanded) │
│ │ CHANGE │ │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 2. CREATE │ /opsx:ff or /opsx:continue │
│ │ 2. CREATE │ /opsx:ff or /opsx:continue (expanded workflow) │
│ │ ARTIFACTS │ Creates proposal → specs → design → tasks │
│ │ │ (based on schema dependencies) │
│ └───────┬────────┘ │
@@ -587,13 +728,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:**
+14
View File
@@ -337,6 +337,20 @@ 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
+20 -40
View File
@@ -4,33 +4,22 @@ 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. The workflow follows a simple pattern:
OpenSpec helps you and your AI coding assistant agree on what to build before any code is written.
**Default quick path (core profile):**
```text
/opsx:propose ──► /opsx:apply ──► /opsx:sync ──► /opsx:archive
```
┌────────────────────┐
│ 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 │
└────────────────────┘
**Expanded path (custom workflow selection):**
```text
/opsx:new ──► /opsx:ff or /opsx:continue ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
```
The default global profile is `core`, which includes `propose`, `explore`, `apply`, `sync`, and `archive`. You can enable the expanded workflow commands with `openspec config profile` and then `openspec update`.
## What OpenSpec Creates
After running `openspec init`, your project has this structure:
@@ -131,23 +120,12 @@ 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
### 1. Start the Change (Default)
```
You: /opsx:new add-dark-mode
```text
You: /opsx:propose 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
@@ -155,7 +133,9 @@ AI: Creating artifacts for add-dark-mode...
Ready for implementation!
```
### 3. What Gets Created
If you've enabled the expanded workflow profile, you can also do this as two steps: `/opsx:new` then `/opsx:ff` (or `/opsx:continue` incrementally).
### 2. What Gets Created
**proposal.md** - Captures the intent:
@@ -218,7 +198,7 @@ The system SHALL allow users to choose between light and dark themes.
- [ ] 3.2 Update components to use CSS variables
```
### 4. Implement
### 3. Implement
```
You: /opsx:apply
@@ -234,7 +214,7 @@ AI: Working through tasks...
During implementation, if you discover the design needs adjustment, just update the artifact and continue.
### 5. Archive
### 4. Archive
```
You: /opsx:archive
+3
View File
@@ -26,6 +26,9 @@ 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
```
+36 -15
View File
@@ -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` | `/opsx:new`, `/opsx:continue`, `/opsx:apply`, and more |
| **Commands** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` | Default: `/opsx:propose`, `/opsx:apply`, `/opsx:sync`, `/opsx:archive` (expanded workflow commands optional) |
| **Workflow** | Create all artifacts at once | Create incrementally or all at once—your choice |
| **Going back** | Awkward phase gates | Natural—update any artifact anytime |
| **Customization** | Fixed structure | Schema-driven, fully hackable |
@@ -84,6 +84,9 @@ 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:
@@ -141,7 +144,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 your skills to the latest version.
The update command also detects and cleans up legacy artifacts, then refreshes generated skills/commands to match your current profile and delivery settings.
### Non-Interactive / CI Environments
@@ -275,30 +278,43 @@ The AI will help you identify what's essential vs. what can be trimmed.
## The New Commands
After migration, you have 9 OPSX commands instead of 3:
Command availability is profile-dependent:
**Default (`core` profile):**
| Command | Purpose |
|---------|---------|
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
| `/opsx:explore` | Think through ideas with no structure |
| `/opsx:new` | Start a new change |
| `/opsx:continue` | Create the next artifact (one at a time) |
| `/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 (optional—archive prompts if needed) |
| `/opsx:archive` | Finalize and archive the change |
**Expanded workflow (custom selection):**
| Command | Purpose |
|---------|---------|
| `/opsx:new` | Start a new change scaffold |
| `/opsx:continue` | Create the next artifact (one at a time) |
| `/opsx:ff` | Fast-forward—create planning artifacts at once |
| `/opsx:verify` | Validate implementation matches specs |
| `/opsx:sync` | Merge delta specs into main specs |
| `/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:new` then `/opsx:ff` |
| `/openspec:proposal` | `/opsx:propose` (default) or `/opsx:new` then `/opsx:ff` (expanded) |
| `/openspec:apply` | `/opsx:apply` |
| `/openspec:archive` | `/opsx:archive` |
### New Capabilities
These capabilities are part of the expanded workflow command set.
**Granular artifact creation:**
```
/opsx:continue
@@ -542,9 +558,11 @@ project/
│ └── config.yaml # NEW: Project configuration
├── .claude/
│ └── skills/ # NEW: OPSX skills
│ ├── openspec-propose/ # default core profile
│ ├── openspec-explore/
│ ├── openspec-new-change/
│ └── ...
│ ├── openspec-apply-change/
│ ├── openspec-sync-specs/
│ └── ... # expanded profile adds new/continue/ff/etc.
├── CLAUDE.md # OpenSpec markers removed, your content preserved
└── AGENTS.md # OpenSpec markers removed, your content preserved
```
@@ -558,12 +576,15 @@ project/
### Command Cheatsheet
```
/opsx:new Start a change
/opsx:continue Create next artifact
/opsx:ff Create all planning artifacts
```text
/opsx:propose Start quickly (default core profile)
/opsx:apply Implement tasks
/opsx:archive Finish and archive
# Expanded workflow (if enabled):
/opsx:new Scaffold a change
/opsx:continue Create next artifact
/opsx:ff Create planning artifacts
```
---
+24 -9
View File
@@ -65,6 +65,8 @@ 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
@@ -155,13 +157,17 @@ 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 |
| `/opsx:continue` | Create the next artifact (based on what's ready) |
| `/opsx:ff` | Fast-forward — create all planning artifacts at once |
| `/opsx:new` | Start a new change scaffold (expanded workflow) |
| `/opsx:continue` | Create the next artifact (expanded workflow) |
| `/opsx:ff` | Fast-forward planning artifacts (expanded workflow) |
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
| `/opsx:sync` | Sync delta specs to main (optional—archive prompts if needed) |
| `/opsx:verify` | Validate implementation against artifacts (expanded workflow) |
| `/opsx:sync` | Sync delta specs to main (default workflow, optional) |
| `/opsx:archive` | Archive when done |
| `/opsx:bulk-archive` | Archive multiple completed changes (expanded workflow) |
| `/opsx:onboard` | Guided walkthrough of an end-to-end change (expanded workflow) |
## Usage
@@ -169,13 +175,21 @@ rules:
```
/opsx:explore
```
Think through ideas, investigate problems, compare options. No structure required - just a thinking partner. When insights crystallize, transition to `/opsx:new` or `/opsx:ff`.
Think through ideas, investigate problems, compare options. No structure required - just a thinking partner. When insights crystallize, transition to `/opsx:propose` (default) or `/opsx:new`/`/opsx:ff` (expanded).
### Start a new change
```
/opsx:new
/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
```
You'll be asked what you want to build and which workflow schema to use.
### Create artifacts
```
@@ -299,6 +313,7 @@ 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
@@ -356,7 +371,7 @@ This section explains how OPSX works under the hood and how it compares to the l
│ Hardcoded Templates (TypeScript strings) │
│ │ │
│ ▼ │
│ Configurators (18+ classes, one per editor) │
│ Tool-specific configurators/adapters │
│ │ │
│ ▼ │
│ Generated Command Files (.claude/commands/openspec/*.md) │
@@ -604,7 +619,7 @@ artifacts:
| **State** | Phase-based mental model | Filesystem existence |
| **Customization** | Edit source, rebuild | Create schema.yaml |
| **Iteration** | Phase-locked | Fluid, edit anything |
| **Editor Support** | 18+ configurator classes | Single skills directory |
| **Editor Support** | Tool-specific configurator/adapters | Single skills directory |
## Schemas
+73 -52
View File
@@ -1,50 +1,65 @@
# Supported Tools
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.
OpenSpec works with many AI coding assistants. When you run `openspec init`, OpenSpec configures selected tools using your active profile/workflow selection and delivery mode.
## How It Works
For each tool you select, OpenSpec installs:
For each selected tool, OpenSpec can install:
1. **Skills** — Reusable instruction files that power the `/opsx:*` workflow commands
2. **Commands** — Tool-specific slash command bindings
1. **Skills** (if delivery includes skills): `.../skills/openspec-*/SKILL.md`
2. **Commands** (if delivery includes commands): tool-specific `opsx-*` command files
By default, OpenSpec uses the `core` profile, which includes:
- `propose`
- `explore`
- `apply`
- `sync`
- `archive`
You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `bulk-archive`, `onboard`) via `openspec config profile`, then run `openspec update`.
## Tool Directory Reference
| Tool | 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/` |
| Kiro | `.kiro/skills/` | `.kiro/prompts/` |
| OpenCode | `.opencode/skills/` | `.opencode/command/` |
| Pi | `.pi/skills/` | `.pi/prompts/` |
| 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/` |
| 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` |
| Mistral Vibe (`vibe`) | `.vibe/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
| 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 to the global home directory (`~/.codex/prompts/` or `$CODEX_HOME/prompts/`), not the project directory.
\* Codex commands are installed in the global Codex home (`$CODEX_HOME/prompts/` if set, otherwise `~/.codex/prompts/`), not your project directory.
\*\* GitHub Copilot's `.github/prompts/*.prompt.md` files are recognized as custom slash commands in **IDE extensions only** (VS Code, JetBrains, Visual Studio). GitHub Copilot CLI does not currently support custom prompts from this directory — see [github/copilot-cli#618](https://github.com/github/copilot-cli/issues/618). If you use Copilot CLI, you may need to manually set up [custom agents](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-custom-agents) in `.github/agents/` as a workaround.
\*\* GitHub Copilot prompt files are recognized as custom slash commands in IDE extensions (VS Code, JetBrains, Visual Studio). Copilot CLI does not currently consume `.github/prompts/*.prompt.md` directly.
## Non-Interactive Setup
For CI/CD or scripted setup, use the `--tools` flag:
For CI/CD or scripted setup, use `--tools` (and optionally `--profile`):
```bash
# Configure specific tools
@@ -55,34 +70,40 @@ openspec init --tools all
# Skip tool configuration
openspec init --tools none
# Override profile for this init run
openspec init --profile core
```
**Available tool IDs:** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codebuddy`, `codex`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
**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`, `lingma`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `vibe`, `windsurf`
## What Gets Installed
## Workflow-Dependent Installation
For each tool, OpenSpec generates 10 skill files that power the OPSX workflow:
OpenSpec installs workflow artifacts based on selected workflows:
| 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 |
- **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`
These skills are invoked via slash commands like `/opsx:new`, `/opsx:apply`, etc. See [Commands](commands.md) for the full list.
In other words, skill/command counts are profile-dependent and delivery-dependent, not fixed.
## Adding a New Tool
## Generated Skill Names
Want to add support for another AI coding assistant? Check out the [command adapter pattern](../CONTRIBUTING.md) or open an issue on GitHub.
When selected by profile/workflow config, OpenSpec generates these skills:
---
- `openspec-propose`
- `openspec-explore`
- `openspec-new-change`
- `openspec-continue-change`
- `openspec-apply-change`
- `openspec-ff-change`
- `openspec-sync-specs`
- `openspec-archive-change`
- `openspec-bulk-archive-change`
- `openspec-verify-change`
- `openspec-onboard`
See [Commands](commands.md) for command behavior and [CLI](cli.md) for `init`/`update` options.
## Related
+34 -7
View File
@@ -28,7 +28,33 @@ OPSX (fluid actions):
> **Customization:** OPSX workflows are driven by schemas that define artifact sequences. See [Customization](customization.md) for details on creating custom schemas.
## Workflow Patterns
## Two Modes
### Default Quick Path (`core` profile)
New installs default to `core`, which provides:
- `/opsx:propose`
- `/opsx:explore`
- `/opsx:apply`
- `/opsx:sync`
- `/opsx:archive`
Typical flow:
```text
/opsx:propose ──► /opsx:apply ──► /opsx:sync ──► /opsx:archive
```
### Expanded/Full Workflow (custom selection)
If you want explicit scaffold-and-build commands (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:bulk-archive`, `/opsx:onboard`), enable them with:
```bash
openspec config profile
openspec update
```
## Workflow Patterns (Expanded Mode)
### Quick Feature
@@ -408,15 +434,16 @@ 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 | 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:new` | Start a change scaffold | Expanded mode, explicit artifact control |
| `/opsx:continue` | Create next artifact | Expanded mode, step-by-step artifact creation |
| `/opsx:ff` | Create all planning artifacts | Expanded mode, clear scope |
| `/opsx:apply` | Implement tasks | Ready to write code |
| `/opsx:verify` | Validate implementation | Before archiving, catch mismatches |
| `/opsx:sync` | Merge delta specs | Optional—archive prompts if needed |
| `/opsx:verify` | Validate implementation | Expanded mode, before archiving |
| `/opsx:sync` | Merge delta specs | Expanded mode, optional |
| `/opsx:archive` | Complete the change | All work finished |
| `/opsx:bulk-archive` | Archive multiple changes | Parallel work, batch completion |
| `/opsx:bulk-archive` | Archive multiple changes | Expanded mode, parallel work |
## Next Steps
@@ -0,0 +1,96 @@
# OpenSpec CLI Playbook For Agents
Beta note: workspace and initiative flows are usable, but still small. Prefer
plain commands, clear paths, and short status reports.
## Start By Resolving Context
Use JSON when you need exact paths.
```bash
openspec context-store list --json
openspec initiative list --json
openspec initiative show <store>/<initiative> --json
openspec workspace doctor --json
```
When the user is working from an opened workspace, treat the workspace as the
local view. Use `workspace doctor --json` to read linked repos/folders and the
selected initiative. Do not assume the current directory is the repo that should
own implementation artifacts.
## Set Up Context Stores Non-Interactively
Humans can run `openspec context-store setup` and answer prompts. Agents should
pass the setup inputs explicitly.
```bash
openspec context-store setup team-context --no-init-git --json
openspec context-store setup team-context --path /path/to/team-context --init-git --json
```
Use `context-store unregister <id> --json` to forget a local registration while
leaving files alone. Use `context-store remove <id> --yes --json` only when the
user explicitly asks to delete the local context-store folder.
## Create Initiatives In Context Stores
Create shared coordination context in a context store.
```bash
openspec initiative create billing-launch --store team-context --title "Billing Launch" --summary "Get billing live without losing the plot."
```
Then edit the initiative files in the context store:
- `requirements.md`
- `design.md`
- `decisions.md`
- `questions.md`
- `tasks.md`
## Explore Or Propose From A Workspace
When the user asks to explore or draft work from a workspace:
1. Resolve the workspace with `openspec workspace doctor --json`.
2. Resolve the initiative with `openspec initiative show <store>/<initiative> --json`.
3. Inspect linked repos or folders and identify the likely owning repo.
4. If ownership is ambiguous, ask the user which linked repo should own the
repo-local OpenSpec change.
5. Run explore/propose workflow commands from the owning repo, not from the
workspace root.
The workspace is the cockpit for the conversation. It is not the durable home
for implementation plans.
## Create Changes From The Owning Repo
Repo-local changes belong in the repo that owns the work.
```bash
openspec new change add-billing-api --initiative team-context/billing-launch
```
Run this command with the owning repo as the current working directory. Do not
ask the user to type it and do not run initiative-linked change creation from a
workspace root. If you only know the workspace, resolve linked repo paths first.
After creating a change, report the absolute paths of the created files and the
initiative link you used.
## Use Doctor Before Guessing
```bash
openspec workspace doctor --workspace billing-launch --json
openspec context-store doctor --json
```
## Do Not Promise Yet
- Automatic sync, pull, push, or conflict handling.
- Cloning repos.
- Creating branches, worktrees, or submodules.
- Workspace apply, verify, or archive.
- Progress dashboards.
- Enforced edit boundaries.
+76
View File
@@ -0,0 +1,76 @@
# Using OpenSpec With Your Coding Agent
Beta note: this is the smallest useful path. You do the local setup. Your agent
manages the OpenSpec work.
## 1. Create The Shared Place
```bash
openspec context-store setup
```
OpenSpec asks for the context store name, where to put it, and whether to
initialize Git. Press Enter for the managed local data directory unless you
want the store somewhere specific.
## 2. Ask Your Agent To Create The Initiative
> Create an OpenSpec initiative called `billing-launch` in `team-context`. Keep
> it short and useful.
## 3. Open Your Local Workbench
```bash
openspec workspace open
```
Select the initiative from the picker. OpenSpec creates a local workspace view
for it if you do not already have one. When creating a new view, it also asks
which local repos or folders to include.
The opened editor view shows linked repos and folders first, initiative context
when attached, and a small `OpenSpec workspace` folder last with `AGENTS.md`,
`workspace.yaml`, and the generated `.code-workspace` file.
Use `openspec workspace open --initiative team-context/billing-launch --editor`
when you want to skip the picker. Use `--agent codex-cli`, `--agent claude`, or
`--agent github-copilot` instead of `--editor` when you want to open an agent
directly.
## 4. Check The Local Context
Ask your agent to inspect the opened workspace before planning work:
> Check this OpenSpec workspace. Resolve the selected initiative, list the
> linked repos or folders, and tell me if anything important is missing before
> we explore the work.
If a repo or folder is missing, tell the agent which local path should be linked.
OpenSpec does not clone anything.
## 5. Explore Before Creating Artifacts
Use the workspace as the place where the conversation happens:
> Using initiative `team-context/billing-launch`, explore the work in this
> workspace. Read the initiative context and linked repo context first. Do not
> create a change yet; help me decide what should be proposed and where the
> OpenSpec artifacts should live.
## 6. Ask For A Draft When Ready
When exploration has converged, ask the agent to create the right artifact in
the right place:
> Create a draft repo-local OpenSpec proposal for the owning linked repo and
> link it to `team-context/billing-launch`. Resolve the workspace and initiative
> context yourself, run the needed OpenSpec commands from the correct repo, and
> report the files you created.
## Tiny Caveat Box
OpenSpec is not cloning, syncing, branching, or tracking progress dashboards in
this beta flow. It gives you shared initiative context, a local workspace view,
and repo-local plans tied back to the bigger mission. The workspace is where
you and the agent work together; durable plan artifacts should live in the
context store initiative or in the owning repo, not in the workspace root.
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-04-23
@@ -0,0 +1,3 @@
# add-kimi-cli-skills-only-support
Add Kimi CLI as a supported skills-only tool without a command adapter
@@ -0,0 +1,85 @@
## 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.
@@ -0,0 +1,38 @@
## 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.
@@ -0,0 +1,12 @@
# 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`
@@ -0,0 +1,37 @@
# 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
@@ -0,0 +1,22 @@
## 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
@@ -0,0 +1,208 @@
## 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.
@@ -0,0 +1,142 @@
## 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.
@@ -0,0 +1,29 @@
## 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
@@ -0,0 +1,199 @@
## 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
@@ -0,0 +1,56 @@
## 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
@@ -0,0 +1,356 @@
## Product Shape
This slice is the first user-facing step after `workspace-foundation`.
The user experience should be:
```text
I set up a workspace.
I link the repos or folders it should know about.
I can list my workspaces later.
I can ask OpenSpec what is broken and how to fix it.
```
No change proposal is required yet.
## Links
A workspace link is a stable name plus a local path on the current machine.
Examples:
```text
api -> /repos/api
web -> /repos/web
checkout -> /repos/platform/apps/checkout
billing -> /repos/platform/services/billing
```
The path may point at a full repo or a folder inside a large monorepo. It may point at a repo or folder that has not adopted repo-local OpenSpec yet.
The product language should say "repos or folders". It should avoid "working set", "code area", "entry", "alias", and "local overlay" in user-facing output.
Path handling should behave like a folder picker. The user may type a relative or absolute path, but OpenSpec should verify that it points to an existing folder, convert it to an absolute path relative to the command's current working directory when needed, and store that verified absolute path in local workspace state. OpenSpec should not store the raw string the user typed.
Path conversion stays in the current runtime. Native Windows paths, WSL2 paths, and Unix paths should not be translated across runtimes. Where duplicate-path detection needs canonical comparisons, OpenSpec may compare canonical existing paths internally, but it should store and display the verified absolute path for the current runtime.
## Names
Workspace names should be kebab-case:
```text
platform
checkout-web
api2
```
Invalid workspace names include uppercase letters, underscores, dots, spaces, leading hyphens, trailing hyphens, empty names, dot names, and path separators. Interactive setup should explain the expected form and let the user retry. Non-interactive setup should fail with the same expectation in the error message.
Link names should keep the folder-style validation from `workspace-foundation`: they must not be empty, must not be `.` or `..`, must not contain path separators, and must be unique inside the workspace. This lets inferred link names match existing folder basenames without forcing users to rename local folders for workspace planning.
Link names are normally inferred from the folder basename:
```text
/repos/api -> api
/repos/platform/apps/checkout -> checkout
```
If the inferred name conflicts, interactive setup should show the conflicting name and the existing path it maps to, then ask for a different name. Non-interactive setup and direct `workspace link` should fail with a clear message instead of silently overwriting.
Duplicate-name errors should be specific:
```text
Cannot use link name 'api' because another link already uses that name.
Existing link:
api -> /repos/api
Choose a different name:
openspec workspace link archived-api /archive/api
If you meant to change the existing link path:
openspec workspace relink api /archive/api
```
This slice does not add a separate link-rename command. Renaming a link can be considered later if users need it, but v1 should keep the command model crisp: `link` adds a new link, and `relink` changes the local path for an existing link.
## Commands
### `workspace setup`
Guided onboarding:
- create a workspace in the standard workspace location
- ask for a workspace name
- require at least one existing repo or folder path
- infer link names from folder names
- let the user add more repos or folders with a simple repeated prompt
- record the workspace in the local workspace registry
- run `workspace doctor`
- print the workspace location, planning path, linked repos or folders, and next useful commands
This slice should not ask for preferred agent or open the workspace with an agent. Those belong to `workspace-open-agent-context`.
Setup should support a non-interactive mode for automation:
```bash
openspec workspace setup --no-interactive --name platform --link /path/to/api --link web=/path/to/web
```
In non-interactive mode, setup should fail cleanly unless the user provides a valid workspace name and at least one valid link. `--link` should accept either a path, which infers the name from the folder basename, or `name=path`.
There is no public `workspace create` command in this slice. Setup is the creation flow.
### `workspace list`
Show known OpenSpec-managed workspaces from the local workspace registry.
`workspace ls` should behave the same way.
The output should answer what exists and what each workspace links to:
```yaml
workspaces:
- name: platform
location: /.../openspec/workspaces/platform
links:
- name: api
path: /repos/api
- name: web
path: /repos/web
- name: checkout
location: /.../openspec/workspaces/checkout
links:
- name: app
path: /repos/platform/apps/checkout
```
List should keep deep validation for `workspace doctor`. It can still report obviously stale workspace registry entries if a known workspace location no longer exists. Stale registry entries are report-only in this slice: `workspace list` should not delete, rewrite, or repair registry entries, and this slice should not add a `workspace forget` command.
For JSON output, list should use typed workspace objects with a structured `status` array for issues:
```json
{
"workspaces": [
{
"name": "platform",
"root": "/.../openspec/workspaces/platform",
"links": [
{
"name": "api",
"path": "/repos/api",
"status": []
}
],
"status": []
},
{
"name": "old-platform",
"root": "/.../openspec/workspaces/old-platform",
"links": [],
"status": [
{
"severity": "error",
"code": "workspace_root_missing",
"message": "Workspace location does not exist.",
"fix": "Remove or repair the local registry entry."
}
]
}
],
"status": []
}
```
### `workspace link [name] <path>`
Record an existing repo or folder path for the selected workspace.
Supported forms:
```bash
openspec workspace link /path/to/api
openspec workspace link api-service /path/to/api
```
The one-argument form infers the link name from the folder basename. The two-argument form lets the user choose the link name.
The path must exist. The command should accept:
- full repo roots
- monorepo folders such as packages, services, and apps
- repos or folders without repo-local `openspec/`
If the user passes a relative path, OpenSpec should resolve it against the command's current working directory before writing local state.
If the path has repo-local OpenSpec state, OpenSpec can report the repo specs path in doctor output. If it does not, OpenSpec should still allow workspace planning.
`workspace link` only records the link. It must not create, copy, move, initialize, or edit files in the linked repo or folder.
### `workspace relink <name> <path>`
Repair or change the local path for an existing link.
Relink should use the same path handling as link: require an existing folder, resolve relative inputs to absolute runtime-local paths, and store the verified path.
This slice should keep relink focused on path repair. It should not include owner or handoff metadata; that language was too process-heavy in the POC and can be revisited later if users need contact or notes fields.
### `workspace doctor`
Explain one selected workspace from the user's machine. If the command is run from a workspace folder or subdirectory and `--workspace <name>` is not provided, doctor should use that current workspace. Otherwise it should follow the normal workspace-selection rules.
Doctor should inspect:
- workspace location
- workspace planning path
- linked repos and folders
- whether each local path exists
- repo-local specs path when present
- missing local paths
- local names that are not in shared workspace state
- shared link names that are missing local paths
- suggested fixes for each issue
Doctor should not scan every known workspace in the local registry by default. Broad registry visibility belongs to `workspace list`. A future `workspace doctor --all` can be considered later if users need global workspace diagnostics.
Doctor should report issues and suggested fixes. It should not repair anything automatically.
Registry cleanup remains out of scope. If doctor cannot inspect the selected workspace because the registry points at a missing or invalid workspace location, it should report that selected-workspace issue through status entries and stop before inspecting links. Other stale registry entries should be surfaced by `workspace list`, not by selected-workspace doctor.
Human output should be readable by default: a short workspace summary, linked repo or folder rows, and a clear issues section when anything needs attention. It should not be raw JSON or a rigid YAML dump.
JSON output should follow the object/status pattern: primary data lives in typed objects, and diagnostics live in `status` arrays. A healthy object has `status: []`. Status entries should include `severity`, `code`, `message`, and optional `target` and `fix` fields.
```json
{
"workspace": {
"name": "platform",
"root": "/.../openspec/workspaces/platform",
"planning_path": "/.../openspec/workspaces/platform/changes",
"links": [
{
"name": "api",
"path": "/repos/api",
"repo_specs_path": "/repos/api/openspec/specs",
"status": []
},
{
"name": "web",
"path": "/old/path/web",
"repo_specs_path": null,
"status": [
{
"severity": "error",
"code": "linked_path_missing",
"message": "Linked path does not exist.",
"target": "links.web.path",
"fix": "openspec workspace relink web /path/to/web"
}
]
}
],
"status": []
},
"status": []
}
```
## Workspace Selection
Workspace commands should work from anywhere.
Commands that do not need one workspace:
- `workspace setup`
- `workspace list`
- `workspace ls`
Commands that need one workspace:
- `workspace link`
- `workspace relink`
- `workspace doctor`
If the current command needs one workspace and `--workspace <name>` is not provided:
- use the current workspace when running from inside a workspace
- otherwise show an interactive picker when multiple known workspaces exist
- otherwise select the only known workspace
- otherwise explain that no workspaces exist and suggest `openspec workspace setup`
The current workspace wins even if it is not in the local workspace registry. This supports manually created or shared workspace folders. In that case commands should continue and include a non-fatal warning status:
```json
{
"severity": "warning",
"code": "workspace_not_in_local_registry",
"message": "This workspace is not recorded in the local workspace registry.",
"target": "workspace.root",
"fix": "Run a mutating workspace command from this workspace, such as workspace link or workspace relink, to record it locally."
}
```
For human output, this should be a short warning rather than a blocking error. Successful mutating commands that use an unregistered current workspace, such as `workspace link` or `workspace relink`, should record the workspace name and location in the local registry after the mutation succeeds. Non-mutating commands such as `workspace doctor` should not write registry state; they should only report the warning. This slice should not add a standalone `workspace register` or `workspace join` command.
In non-interactive mode, commands that need one workspace should fail when selection is ambiguous and suggest `--workspace <name>`.
`--json` should also suppress prompting for commands that need one workspace. If a command would otherwise show a picker, JSON mode should fail with a structured status error and suggest `--workspace <name>`.
## Machine-Local Files
Workspace creation should make machine-local state safe by default.
The workspace should ignore:
```text
/.openspec-workspace/local.yaml
```
The local workspace registry should also be machine-local:
```text
<global-data-dir>/workspaces/registry.yaml
```
Generated agent launch surfaces can be ignored by `workspace-open-agent-context` when that slice creates them.
## JSON Output
Interactive setup does not need JSON output as its primary contract. Non-interactive setup and direct commands should support JSON output for scripting:
- `workspace setup --no-interactive --json`
- `workspace list --json`
- `workspace link --json`
- `workspace relink --json`
- `workspace doctor --json`
`workspace setup --json` should require `--no-interactive`. If a user runs `workspace setup --json` without `--no-interactive`, setup should fail clearly because an interactive wizard cannot produce clean JSON. Direct commands such as `workspace list --json`, `workspace link --json`, `workspace relink --json`, and `workspace doctor --json` do not require `--no-interactive`, but JSON mode should disable prompts and fail on ambiguous workspace selection.
JSON output should use object/status structure across commands:
- primary entities such as `workspace`, `workspaces`, or `link` carry the durable data
- `status` arrays carry warnings, errors, and suggested fixes
- status entries use stable `code` values plus human-readable `message` text
- command-level `status` describes the whole response
- object-level `status` describes that specific workspace or link
## POC Adjustments
Keep:
- guided setup as the default first run
- direct list/link/check commands
- shared state separate from local paths
- clean non-interactive failure when required setup inputs are missing
- JSON output for non-interactive/direct commands
Change:
- do not expose public `workspace create` in the first release
- do not require repo-local OpenSpec state to link a repo or folder
- use `workspace link` instead of `workspace add-repo`
- use `workspace relink` instead of `workspace update-repo`
- do not save a preferred agent during setup
- do not offer to open the workspace from setup
- require setup to link at least one existing repo or folder
- keep relink behavior focused on path repair rather than owner or handoff metadata
- do not use "working set", "code area", "entry", "alias", or "local overlay" in human-facing output
@@ -0,0 +1,128 @@
## Why
Note: the change id keeps the older "register repos" wording for continuity. User-facing product language in this slice is `workspace setup`, `workspace link`, `workspace relink`, and "linked repos or folders."
Users start workspace work by creating a planning home and linking the repos or folders OpenSpec should know about.
They should not have to create a change before OpenSpec can see the relevant repos, monorepo folders, packages, services, or apps.
The product rule is:
```text
Workspace visibility is not change commitment.
```
A workspace is the durable planning home. A change is a feature, fix, project, or other planned piece of work inside that workspace.
## What Changes
Add the first user-facing workspace setup flow:
```text
Set up a workspace.
Link existing repos or folders.
List known workspaces and what they link to.
Check what OpenSpec can resolve and how to fix problems.
```
Expected user 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
```
`workspace setup` is the creation path for users. It should ask for the workspace name first, create the workspace in the standard location, require at least one existing repo or folder path, infer link names from folder names, show the workspace location, and run a check at the end so the user knows what OpenSpec can see.
Workspace names should be kebab-case so they are clean managed-folder names and stable registry identifiers. Link names should keep the folder-style validation from `workspace-foundation` because they are often inferred directly from existing repo or folder basenames.
`workspace setup --no-interactive` is the automation path. It should require enough flags to create a useful workspace, including a workspace name and at least one link.
`workspace list` shows known OpenSpec-managed workspaces from the local workspace registry, including each workspace location and linked repos or folders.
`workspace link` records an existing local repo or folder path for the selected workspace. It should support a simple form that infers the link name from the folder name and an explicit-name form for conflicts or clarity. Linking does not create, copy, move, initialize, or edit files in the linked repo or folder.
Linking should behave like selecting a folder from a picker: OpenSpec verifies the folder exists, resolves relative inputs to an absolute path in the current runtime, and stores that verified path instead of the raw input string.
When a link name is already in use, OpenSpec should preserve the existing link and show the conflicting name with the existing path. The error should suggest choosing a different link name, or using `workspace relink <name> <path>` if the user intended to change the existing link's path.
`workspace relink` lets users repair or change the local path for an existing link without recreating the workspace. It should not introduce owner or handoff metadata in this slice.
`workspace doctor` explains what the current machine can resolve for one selected workspace: the workspace location, the workspace planning path, linked repos or folders, missing paths, repo-local specs paths when present, and suggested fixes. It should infer the current workspace when run from inside a workspace. It reports issues but does not repair them automatically.
Workspace commands should work globally. When a command needs one workspace and the user did not specify it, OpenSpec should use the local registry to show an interactive picker. In non-interactive mode, it should fail with a clear message and suggest `--workspace <name>`.
When a command runs from inside a valid workspace that is not in the local registry, OpenSpec should still use that current workspace. It should surface a non-fatal warning status that the workspace is not known locally, and successful mutating commands such as `workspace link` or `workspace relink` should record that workspace in the local registry after they update workspace state.
Machine-readable output should separate workspace or link objects from status entries. Status should be an array of structured issues instead of scattering fields such as `root_status`, `issue`, or `fix` through the primary object shape.
Interactive behavior should be disabled whenever output must be script-safe. `--no-interactive` means no prompts, and `--json` should fail instead of prompting when selection or setup inputs are ambiguous. `workspace setup --json` should require `--no-interactive` so JSON setup always uses the explicit automation path.
Planning dependency:
- Depends on `workspace-foundation`.
## POC Findings
Behavior to preserve:
- `workspace setup` was the friendly onboarding path.
- `workspace list` made managed workspaces discoverable.
- A direct automation path is still useful, but it should live under `workspace setup --no-interactive`.
- Link repair is useful, but owner or handoff metadata should not carry forward in this slice.
- `workspace doctor` was the right place to answer "what does OpenSpec know about this workspace?"
- Shared workspace state and local paths were stored separately.
- Setup failed cleanly when non-interactive inputs were incomplete.
- Created workspaces excluded machine-local path state from portable workspace state.
Behavior to change:
- The POC required linked repo paths to already contain repo-local `openspec/`. This should become an implementation-readiness signal, not a planning prerequisite.
- The POC used repo-only language. This slice should use "repos or folders" for user-facing text.
- The public command should be `workspace link`, not `workspace add-repo`.
- The repair command should be `workspace relink`, not `workspace update-repo`.
- Public `workspace create` should be removed for the first release. Setup should be the creation flow.
- The POC's `setup` flow stored preferred agent and open behavior. Agent launch preferences belong to `workspace-open-agent-context`, not this slice.
- Human output should avoid implementation terms such as working set, code area, entry, alias, or local overlay.
- `setup` should require at least one linked repo or folder so the created workspace is immediately useful.
## Non-Goals
- No public `openspec workspace create` command in this first release.
- No agent launch or workspace open behavior.
- No preferred agent prompts or saved agent preference.
- No owner or handoff metadata fields.
- No workspace change creation or target selection.
- No apply, verify, archive, branch, or worktree behavior.
- No requirement that linked repos or folders have repo-local OpenSpec state.
- No automatic repair behavior in `workspace doctor`.
- No registry cleanup command such as `workspace forget`; stale registry entries are report-only in this slice.
- No standalone `workspace register` or `workspace join` command; unregistered current workspaces are usable, and mutating workspace commands can record them locally.
## Capabilities
### New Capabilities
- `workspace-links`: Lets users set up a workspace, link repos or folders, list known workspaces, and check workspace resolution before change creation.
### Modified Capabilities
- `cli-artifact-workflow`: Introduces workspace setup commands that happen before change creation.
- `workspace-foundation`: Tightens workspace names to kebab-case while keeping folder-style link names.
## Impact
- `openspec workspace setup`
- `openspec workspace list`
- `openspec workspace ls`
- `openspec workspace link`
- `openspec workspace relink`
- `openspec workspace doctor`
- Local workspace registry usage from `workspace-foundation`.
- Docs and generated guidance that explain linked repos or folders as planning context, not implementation commitment.
@@ -0,0 +1,24 @@
## ADDED Requirements
### Requirement: Workspace Setup Commands
The CLI artifact workflow SHALL expose workspace setup commands before change creation.
#### Scenario: Preparing workspace planning before a change
- **WHEN** a user needs to prepare workspace planning across repos or folders
- **THEN** the CLI SHALL provide commands to set up, list, link, relink, and doctor workspaces
- **AND** those commands SHALL not require an active workspace change
#### Scenario: Listing workspaces with a short command
- **WHEN** a user wants a concise workspace list command
- **THEN** the CLI SHALL support `openspec workspace ls`
- **AND** it SHALL behave the same as `openspec workspace list`
#### Scenario: Keeping setup separate from agent launch
- **WHEN** a user completes workspace setup
- **THEN** the setup workflow SHALL leave agent launch and workspace open behavior to a later workflow
- **AND** setup SHALL not require a preferred agent choice
#### Scenario: Avoiding public direct creation
- **WHEN** users create a workspace in the first workspace setup flow
- **THEN** the CLI SHALL use `openspec workspace setup`
- **AND** it SHALL not expose `openspec workspace create` as the public creation path
@@ -0,0 +1,35 @@
## MODIFIED Requirements
### Requirement: Stable Workspace Name
OpenSpec SHALL use one kebab-case workspace name across workspace identity, managed storage, and the local registry.
#### Scenario: Using one workspace name
- **WHEN** OpenSpec creates or records 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 workspace names
- **WHEN** OpenSpec accepts a workspace name
- **THEN** it SHALL require kebab-case names using lowercase letters, numbers, and single hyphen separators
- **AND** it SHALL reject empty names, dot names, names with leading or trailing hyphens, names with repeated hyphens, uppercase letters, spaces, underscores, dots, and path separators
- **AND** setup flows SHALL report OS-level folder creation failures clearly
### Requirement: Stable Link Names
OpenSpec SHALL use stable folder-style 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
- **AND** link names SHALL not be required to use workspace-name kebab-case
@@ -0,0 +1,356 @@
## ADDED Requirements
### Requirement: Guided Workspace Setup
OpenSpec SHALL provide a guided setup flow for users starting workspace planning.
#### Scenario: Creating a workspace through setup
- **WHEN** a user runs `openspec workspace setup`
- **THEN** OpenSpec SHALL guide the user through creating an OpenSpec workspace
- **AND** the workspace SHALL use the standard workspace location from the workspace foundation
#### Scenario: Asking for the workspace name first
- **WHEN** interactive setup starts
- **THEN** OpenSpec SHALL ask for the workspace name before asking for repos or folders
- **AND** workspace names SHALL use kebab-case with lowercase letters, numbers, and hyphens
#### Scenario: Retrying an invalid workspace name during setup
- **WHEN** an interactive user enters an invalid workspace name
- **THEN** OpenSpec SHALL explain that workspace names must be kebab-case
- **AND** it SHALL let the user enter another workspace name before continuing setup
#### Scenario: Linking a required first repo or folder
- **WHEN** setup asks for repos or folders
- **THEN** the user SHALL provide at least one existing repo or folder path
- **AND** setup SHALL not finish successfully until at least one path is linked
#### Scenario: Inferring link names during setup
- **WHEN** the user provides a repo or folder path during setup
- **THEN** OpenSpec SHALL infer the link name from the folder basename
- **AND** it SHALL ask for a different name only when the inferred name conflicts
#### Scenario: Handling inferred link name conflicts during setup
- **GIVEN** setup infers a link name that already exists in the workspace
- **WHEN** setup is interactive
- **THEN** OpenSpec SHALL show the conflicting link name and the existing path for that link
- **AND** it SHALL ask the user for a different link name before continuing
#### Scenario: Preserving folder-style link names
- **WHEN** OpenSpec accepts a workspace link name
- **THEN** it SHALL allow folder-style names that are valid under the workspace foundation link-name rules
- **AND** it SHALL not require link names to use the stricter workspace-name kebab-case rule
#### Scenario: Adding multiple repos or folders during setup
- **WHEN** setup links a repo or folder
- **THEN** OpenSpec SHALL let the user add another repo or folder with a simple repeated prompt
- **AND** each linked path SHALL be recorded without editing the target repo or folder
#### Scenario: Storing verified absolute paths during setup
- **WHEN** setup links a repo or folder path
- **THEN** OpenSpec SHALL verify that the path resolves to an existing folder
- **AND** it SHALL store an absolute runtime-local path in machine-local state instead of the raw user input
- **AND** relative inputs SHALL be resolved against the command's current working directory
#### Scenario: Preserving equals signs in setup link paths
- **WHEN** non-interactive setup receives a `--link` value that resolves to an existing folder and contains `=`
- **THEN** OpenSpec SHALL treat the full value as the path
- **AND** it SHALL infer the link name from the folder basename
- **AND** explicit `--link <name>=<path>` inputs SHALL preserve `=` characters inside `<path>`
#### Scenario: Running setup with non-interactive inputs
- **WHEN** `openspec workspace setup --no-interactive` receives a workspace name and at least one valid link
- **THEN** OpenSpec SHALL create the workspace without prompts
- **AND** it SHALL support repeated `--link` values
#### Scenario: Non-interactive setup duplicate link names
- **WHEN** `openspec workspace setup --no-interactive` receives two links with the same inferred or explicit name
- **THEN** OpenSpec SHALL fail with a clear duplicate link-name error
- **AND** the error SHALL show the conflicting link name and the first path using that name
- **AND** it SHALL suggest using explicit `--link <name>=<path>` values with different names
#### Scenario: Missing non-interactive setup inputs
- **WHEN** `openspec workspace setup --no-interactive` is missing a workspace name or link
- **THEN** OpenSpec SHALL fail with a clear message
- **AND** it SHALL explain which flags are required
#### Scenario: Finishing setup
- **WHEN** setup finishes
- **THEN** OpenSpec SHALL show the workspace location, planning path, and linked repos or folders
- **AND** it SHALL check what the current machine can resolve
#### Scenario: Recording created workspaces locally
- **WHEN** setup creates a workspace
- **THEN** OpenSpec SHALL record it in the local workspace registry
- **AND** the workspace folder SHALL remain the source of truth for workspace state
#### Scenario: Reusing an existing workspace name during setup
- **GIVEN** a managed workspace already exists with the requested name
- **WHEN** a user runs setup with that workspace name
- **THEN** OpenSpec SHALL explain that the workspace already exists
- **AND** it SHALL not overwrite the existing workspace
### Requirement: Workspace Discovery
OpenSpec SHALL let users see the OpenSpec-managed workspaces available on the current machine.
#### Scenario: Listing workspaces
- **WHEN** a user runs `openspec workspace list`
- **THEN** OpenSpec SHALL list known managed workspaces
- **AND** each workspace SHALL include the workspace name, workspace location, and linked repos or folders
#### Scenario: Using the short list command
- **WHEN** a user runs `openspec workspace ls`
- **THEN** OpenSpec SHALL behave the same as `openspec workspace list`
#### Scenario: Listing when no workspaces exist
- **WHEN** a user runs `openspec workspace list`
- **AND** no managed workspaces exist
- **THEN** OpenSpec SHALL say that no workspaces were found
- **AND** it SHALL show the user how to create one
#### Scenario: Listing stale registry entries
- **WHEN** the local registry contains a workspace location that no longer exists
- **THEN** `workspace list` SHALL report the stale workspace entry
- **AND** it SHALL avoid silently deleting registry state
- **AND** it SHALL avoid rewriting or repairing registry state automatically
#### Scenario: Avoiding registry cleanup commands
- **WHEN** users inspect stale workspace registry entries in this slice
- **THEN** OpenSpec SHALL treat stale entries as report-only diagnostics
- **AND** it SHALL not expose a registry cleanup command such as `workspace forget`
### Requirement: Global Workspace Commands
OpenSpec SHALL let workspace commands run from outside workspace directories.
#### Scenario: Selecting a workspace by flag
- **WHEN** a command that needs one workspace receives `--workspace <name>`
- **THEN** OpenSpec SHALL use that workspace from the local registry
- **AND** it SHALL fail clearly if the workspace name is unknown
#### Scenario: Using the current workspace
- **GIVEN** the command runs from a workspace folder or subdirectory
- **WHEN** the command needs one workspace and no `--workspace` flag is provided
- **THEN** OpenSpec SHALL use the current workspace
#### Scenario: Using an unregistered current workspace
- **GIVEN** the command runs from a valid workspace folder or subdirectory
- **AND** that workspace is not recorded in the local workspace registry
- **WHEN** the command needs one workspace and no `--workspace <name>` flag is provided
- **THEN** OpenSpec SHALL use the current workspace
- **AND** it SHALL include a non-fatal warning status with code `workspace_not_in_local_registry`
- **AND** the warning SHALL explain how the user can get the workspace recorded locally
#### Scenario: Recording an unregistered current workspace after mutation
- **GIVEN** a mutating workspace command uses a valid current workspace that is not recorded in the local workspace registry
- **WHEN** `workspace link` or `workspace relink` succeeds
- **THEN** OpenSpec SHALL record the workspace name and location in the local workspace registry
#### Scenario: Doctor does not register current workspaces
- **GIVEN** `workspace doctor` uses a valid current workspace that is not recorded in the local workspace registry
- **WHEN** doctor finishes
- **THEN** OpenSpec SHALL report the non-fatal registry warning
- **AND** it SHALL not write registry state
#### Scenario: Picking from multiple workspaces
- **GIVEN** multiple known workspaces exist
- **WHEN** an interactive command needs one workspace and none is specified
- **THEN** OpenSpec SHALL show a workspace picker
- **AND** the picker SHALL include workspace names and paths
#### Scenario: Ambiguous non-interactive workspace selection
- **GIVEN** multiple known workspaces exist
- **WHEN** a non-interactive command needs one workspace and none is specified
- **THEN** OpenSpec SHALL fail with a clear message
- **AND** it SHALL suggest passing `--workspace <name>`
#### Scenario: Ambiguous JSON workspace selection
- **GIVEN** multiple known workspaces exist
- **WHEN** a command running with `--json` needs one workspace and none is specified
- **THEN** OpenSpec SHALL fail without showing a picker
- **AND** it SHALL emit a structured status error
- **AND** it SHALL suggest passing `--workspace <name>`
#### Scenario: No known workspaces for a command that needs one
- **GIVEN** no known workspaces exist in the local registry
- **AND** the command is not running from a workspace folder or subdirectory
- **WHEN** `workspace link`, `workspace relink`, `workspace doctor`, or another command that needs one workspace runs without `--workspace <name>`
- **THEN** OpenSpec SHALL fail without showing a picker regardless of interactive mode
- **AND** it SHALL print `No known OpenSpec workspaces. Run 'openspec workspace setup' first.`
- **AND** it SHALL explain that `--workspace <name>` can be used after at least one workspace is known locally
### Requirement: Workspace Links
OpenSpec SHALL let users link existing repos or folders to a workspace before creating a change.
#### Scenario: Linking with an inferred name
- **WHEN** a user runs `openspec workspace link <path>`
- **THEN** OpenSpec SHALL infer the link name from the folder basename
- **AND** it SHALL store the verified absolute local path as machine-local state
#### Scenario: Linking with an explicit name
- **WHEN** a user runs `openspec workspace link <name> <path>`
- **THEN** OpenSpec SHALL use the explicit link name for planning
- **AND** it SHALL store the verified absolute local path as machine-local state
#### Scenario: Requiring an existing path
- **WHEN** a user links a repo or folder path
- **THEN** the path SHALL exist on the current machine
- **AND** OpenSpec SHALL reject missing paths with a clear message
#### Scenario: Resolving linked paths before storage
- **WHEN** a user links a repo or folder path
- **THEN** OpenSpec SHALL store the verified absolute path for the current runtime
- **AND** relative inputs SHALL be resolved against the command's current working directory
- **AND** OpenSpec SHALL not translate paths between native Windows, WSL2, and Unix runtimes
#### Scenario: Linking a monorepo folder
- **WHEN** a user links a package, service, app, or directory inside a monorepo
- **THEN** OpenSpec SHALL store it as a workspace link
- **AND** it SHALL not require that folder to have its own repo-local `openspec/` directory
#### Scenario: Linking without repo-local OpenSpec
- **WHEN** a user links a path that does not contain repo-local OpenSpec state
- **THEN** OpenSpec SHALL keep that repo or folder available for workspace planning
- **AND** it SHALL not treat missing repo-local OpenSpec state as a link failure
#### Scenario: Link records only
- **WHEN** a user links a repo or folder
- **THEN** OpenSpec SHALL record workspace state and local path state
- **AND** it SHALL not create, copy, move, initialize, or edit files in the linked repo or folder
#### Scenario: Blocking link when local state is invalid
- **GIVEN** the workspace machine-local state file exists but cannot be parsed or validated
- **WHEN** a user runs `openspec workspace link`
- **THEN** OpenSpec SHALL fail with status code `workspace_local_state_invalid`
- **AND** it SHALL not rewrite shared workspace state or machine-local path state
#### Scenario: Reusing a link name
- **GIVEN** a workspace already has a link with a given name
- **WHEN** a user tries to link another path with the same name
- **THEN** OpenSpec SHALL explain that the link name is already in use by another link
- **AND** it SHALL show the existing link name and existing path
- **AND** it SHALL suggest choosing a different link name
- **AND** it SHALL suggest `workspace relink <name> <path>` when the user intended to change the existing link path
- **AND** it SHALL preserve the existing link unless the user explicitly relinks it
### Requirement: Workspace Relinks
OpenSpec SHALL let users update existing link paths without recreating the workspace.
#### Scenario: Updating a local path
- **GIVEN** a workspace has a link
- **WHEN** a user runs `openspec workspace relink <name> <path>`
- **THEN** OpenSpec SHALL keep the stable link name
- **AND** it SHALL update the machine-local path for the current machine to the verified absolute path
#### Scenario: Requiring an existing relink path
- **WHEN** a user relinks to a new path
- **THEN** the new path SHALL exist on the current machine
- **AND** OpenSpec SHALL reject missing paths with a clear message
#### Scenario: Resolving relink paths before storage
- **WHEN** a user relinks to a new path
- **THEN** OpenSpec SHALL store the verified absolute path for the current runtime
- **AND** relative inputs SHALL be resolved against the command's current working directory
#### Scenario: Blocking relink when local state is invalid
- **GIVEN** the workspace machine-local state file exists but cannot be parsed or validated
- **WHEN** a user runs `openspec workspace relink`
- **THEN** OpenSpec SHALL fail with status code `workspace_local_state_invalid`
- **AND** it SHALL not rewrite machine-local path state
#### Scenario: Updating an unknown link
- **WHEN** a user tries to relink a link that does not exist
- **THEN** OpenSpec SHALL explain that the link name is unknown
- **AND** it SHALL preserve existing workspace state
#### Scenario: Avoiding owner and handoff fields
- **WHEN** users link or relink repos or folders in this slice
- **THEN** OpenSpec SHALL not ask for owner or handoff metadata
- **AND** link maintenance SHALL focus on names and local paths
### Requirement: Workspace Health Check
OpenSpec SHALL explain what the current machine can resolve for a workspace.
#### Scenario: Doctor checks one selected workspace
- **WHEN** a user runs `openspec workspace doctor`
- **THEN** OpenSpec SHALL inspect one selected workspace
- **AND** it SHALL not scan every known workspace in the local registry by default
#### Scenario: Doctor infers the current workspace
- **GIVEN** the command runs from a workspace folder or subdirectory
- **WHEN** the user runs `openspec workspace doctor` without `--workspace <name>`
- **THEN** OpenSpec SHALL inspect the current workspace
#### Scenario: Checking a healthy workspace
- **WHEN** a user runs `openspec workspace doctor`
- **THEN** OpenSpec SHALL show the workspace location and workspace planning path
- **AND** it SHALL show linked repos or folders and which paths resolve on the current machine
#### Scenario: Selected workspace location is missing
- **GIVEN** the selected workspace comes from the local registry
- **AND** the registered workspace location is missing or invalid
- **WHEN** a user runs `openspec workspace doctor`
- **THEN** OpenSpec SHALL report a selected-workspace status error
- **AND** it SHALL not attempt to inspect links for that workspace
#### Scenario: Reporting repo-local specs paths
- **WHEN** a linked repo or folder resolves
- **THEN** doctor SHALL report `repo_specs_path` when repo-local `openspec/specs` exists
- **AND** it SHALL report `repo_specs_path: null` when repo-local specs are not present
#### Scenario: Checking missing paths
- **WHEN** a link points to a path that is missing on the current machine
- **THEN** doctor SHALL identify the affected link name
- **AND** it SHALL include a suggested `workspace relink` fix
#### Scenario: Checking shared and local state drift
- **WHEN** shared workspace state and machine-local path state do not agree
- **THEN** doctor SHALL explain which link names are affected
- **AND** it SHALL distinguish shared workspace links from local-only paths
#### Scenario: Reporting invalid local state
- **WHEN** list or doctor reads a workspace whose machine-local state file cannot be parsed or validated
- **THEN** OpenSpec SHALL report status code `workspace_local_state_invalid`
- **AND** it SHALL avoid treating the invalid local state as an empty path map for mutation or repair suggestions
- **AND** it SHALL not rewrite workspace registry state or machine-local path state
#### Scenario: Reporting without auto-repair
- **WHEN** doctor finds issues
- **THEN** it SHALL report all issues it can find
- **AND** it SHALL not automatically repair workspace state
#### Scenario: Using readable human output
- **WHEN** doctor prints human output
- **THEN** it SHALL show a readable workspace summary, linked repos or folders, and issues when present
- **AND** it SHALL avoid printing raw JSON or relying on a rigid YAML dump as the default human experience
### Requirement: Scriptable Workspace Setup Commands
OpenSpec SHALL provide JSON output for direct workspace setup commands.
#### Scenario: Requesting JSON output
- **WHEN** a user passes `--json` to direct workspace setup commands
- **THEN** OpenSpec SHALL print machine-readable output
- **AND** the output SHALL avoid extra human-readable text
- **AND** the output SHALL separate primary objects from structured `status` entries
#### Scenario: Setup JSON requires non-interactive setup
- **WHEN** a user runs `openspec workspace setup --json` without `--no-interactive`
- **THEN** OpenSpec SHALL fail clearly
- **AND** it SHALL explain that `workspace setup --json` requires `--no-interactive`
#### Scenario: JSON output disables prompts
- **WHEN** a direct workspace setup command runs with `--json`
- **THEN** OpenSpec SHALL avoid interactive prompts
- **AND** it SHALL fail with structured status output when required choices are ambiguous
#### Scenario: JSON status entry shape
- **WHEN** a direct workspace setup command reports warnings, errors, or suggested fixes in JSON output
- **THEN** each status entry SHALL include a stable `code`, a `severity`, and a human-readable `message`
- **AND** status entries MAY include `target` and `fix` fields when a specific object field or suggested command is useful
#### Scenario: JSON object status shape
- **WHEN** a direct workspace setup command emits JSON for workspace, link, or list objects
- **THEN** each object MAY include a `status` array for object-specific warnings or errors
- **AND** the top-level response SHALL include a `status` array for command-level warnings or errors
- **AND** healthy objects and healthy responses SHALL use an empty `status` array
#### Scenario: Commands with JSON output
- **WHEN** users run `workspace setup --no-interactive`, `workspace list`, `workspace link`, `workspace relink`, or `workspace doctor`
- **THEN** each command SHALL support JSON output
@@ -0,0 +1,121 @@
## 1. POC Findings And Scope
- [x] 1.1 Confirm `setup`, `list`, and `doctor` belong to this slice
- [x] 1.2 Capture that setup should not own preferred agent or workspace open behavior
- [x] 1.3 Capture that linked repos or folders and monorepo paths are allowed without repo-local OpenSpec state
- [x] 1.4 Capture decisions for JSON output, `ls`, `.gitignore`, non-interactive setup, required first link, and relink behavior
- [x] 1.5 Capture that public `workspace create` is out of scope for the first release
- [x] 1.6 Capture `link`/`relink` as the user-facing commands
## 2. Workspace Setup
- [x] 2.1 Implement `openspec workspace setup` as the only public creation path
- [x] 2.2 Prompt for workspace name first in interactive setup
- [x] 2.3 Validate workspace names as kebab-case and let interactive users retry invalid names
- [x] 2.4 Require at least one existing repo or folder path during setup
- [x] 2.5 Infer link names from folder basenames during setup
- [x] 2.6 Let users add more repos or folders with a simple repeated prompt
- [x] 2.7 Run `workspace doctor` after setup and show a readable summary
- [x] 2.8 Print the workspace location, planning path, linked repos or folders, and next useful commands
- [x] 2.9 Keep preferred agent prompts and workspace opening out of this slice
- [x] 2.10 Add `.gitignore` handling for machine-local workspace state
- [x] 2.11 Record created workspaces in the local workspace registry
- [x] 2.12 Add tests for native Windows/PowerShell and WSL2-compatible path construction where practical
## 3. Non-Interactive Setup
- [x] 3.1 Add `workspace setup --no-interactive --name <name> --link <path>` support
- [x] 3.2 Support repeated `--link` values
- [x] 3.3 Support `--link <path>` with inferred names
- [x] 3.4 Support `--link <name>=<path>` with explicit names
- [x] 3.5 Fail cleanly when non-interactive setup is missing a name or at least one link
- [x] 3.6 Resolve relative link paths to verified absolute runtime-local paths before storing local state
- [x] 3.7 Require `--no-interactive` when `workspace setup --json` is used
- [x] 3.8 Add `--json` output for non-interactive setup
- [x] 3.9 Preserve the interactive setup UX when `--no-interactive` is not passed
## 4. Workspace Listing
- [x] 4.1 Implement `openspec workspace list`
- [x] 4.2 Add `workspace ls` as an alias for `workspace list`
- [x] 4.3 List known OpenSpec-managed workspaces from the local workspace registry
- [x] 4.4 Handle the no-workspaces case with a clear next step
- [x] 4.5 Show each workspace location and linked repos or folders
- [x] 4.6 Report stale registry entries with status entries without deleting, rewriting, or repairing registry state
- [x] 4.7 Add JSON output with typed workspace objects and structured status arrays
## 5. Workspace Selection
- [x] 5.1 Make workspace commands work from outside workspace directories
- [x] 5.2 Add `--workspace <name>` to commands that need one workspace
- [x] 5.3 Use the current workspace when running from inside a workspace
- [x] 5.4 Use unregistered current workspaces with a non-fatal warning status
- [x] 5.5 Record unregistered current workspaces in the local registry after successful `workspace link` or `workspace relink`
- [x] 5.6 Keep `workspace doctor` diagnostic-only when the current workspace is unregistered
- [x] 5.7 Show an interactive picker when multiple known workspaces exist and no workspace is specified
- [x] 5.8 Select the only known workspace automatically when there is exactly one
- [x] 5.9 Fail clearly in non-interactive mode when workspace selection is ambiguous
- [x] 5.10 Fail with structured status output instead of prompting when `--json` workspace selection is ambiguous
- [x] 5.11 Use the local workspace registry for workspace lookup
## 6. Workspace Links
- [x] 6.1 Implement `openspec workspace link <path>` with inferred link names
- [x] 6.2 Implement `openspec workspace link <name> <path>` with explicit link names
- [x] 6.3 Accept full repo roots and monorepo package/service/app folder paths
- [x] 6.4 Require linked paths to exist
- [x] 6.5 Allow links without repo-local `openspec/`
- [x] 6.6 Store stable link names in shared state and local paths in machine-local state
- [x] 6.7 Keep link names folder-style, and detect duplicate link names with a specific error that shows the existing link path and suggests a different name or `workspace relink`
- [x] 6.8 Resolve relative linked paths to verified absolute runtime-local paths before storing local state
- [x] 6.9 Preserve native Windows and WSL2-style paths as local path values without cross-runtime translation
- [x] 6.10 Ensure link only records state and does not edit the linked repo/folder
- [x] 6.11 Add `--json` output for `workspace link`
## 7. Workspace Relinks
- [x] 7.1 Implement `openspec workspace relink <name> <path>`
- [x] 7.2 Let users repair or change the local path for an existing link
- [x] 7.3 Require relink paths to exist
- [x] 7.4 Resolve relative relink paths to verified absolute runtime-local paths before storing local state
- [x] 7.5 Keep owner or handoff metadata out of this slice
- [x] 7.6 Add `--json` output for `workspace relink`
- [x] 7.7 Return a clear error for unknown link names
## 8. Workspace Doctor
- [x] 8.1 Implement `openspec workspace doctor` for one selected workspace only
- [x] 8.2 Show the workspace location and workspace planning path
- [x] 8.3 Show linked repos or folders in readable human output with a clear issues section
- [x] 8.4 Report missing local paths, missing filesystem paths, local-only names, and selected-workspace location problems
- [x] 8.5 Report `repo_specs_path` when repo-local `openspec/specs` exists and `null` otherwise
- [x] 8.6 Include suggested fixes for each issue
- [x] 8.7 Avoid automatic repair behavior
- [x] 8.8 Add JSON output with typed workspace/link objects and structured status arrays
- [x] 8.9 Keep stale registry cleanup commands such as `workspace forget` out of this slice
## 9. Documentation And Guidance
- [x] 9.1 Document setup/list/link/relink/doctor in user-facing product language
- [x] 9.2 Document linked repos or folders and large-monorepo folder links
- [x] 9.3 Document that workspace visibility is not change commitment
- [x] 9.4 Avoid "working set", "code area", "entry", "alias", and "local overlay" in human-facing docs
- [x] 9.5 Document JSON output support and the object/status response pattern for non-interactive/direct commands
- [x] 9.6 Document global command behavior, workspace picker behavior, and `--workspace <name>`
- [x] 9.7 Document that setup controls workspace storage and always shows the workspace location
## 10. Verification
- [x] 10.1 Run `openspec validate workspace-create-and-register-repos --strict`
- [x] 10.2 Run targeted command tests for workspace setup/list/link/relink/doctor, including doctor inferring the current workspace
- [x] 10.3 Run targeted tests for links without repo-local OpenSpec and monorepo folder links
- [x] 10.4 Run targeted tests for JSON output, `ls`, `.gitignore`, non-interactive setup, required first link, verified absolute path storage, and JSON/no-interactive prompt suppression
- [x] 10.5 Run targeted tests for global command selection, unregistered current workspace handling, and local workspace registry behavior
## 11. Review Fixes
- [x] 11.1 Preserve `=` characters in inferred setup link paths while keeping explicit `--link <name>=<path>` support
- [x] 11.2 Add reusable core helpers for optional local state reads and setup link input parsing
- [x] 11.3 Fail `workspace link` and `workspace relink` before mutation when local state is invalid
- [x] 11.4 Report invalid local state distinctly in `workspace list` and `workspace doctor`
- [x] 11.5 Add regression tests for equals-sign setup paths and malformed local state behavior
@@ -0,0 +1,266 @@
## Product Shape
`workspace open` should feel like opening a multi-root working set.
The user model is:
```text
workspace setup = create the planning home and choose the default opener
workspace links = the repos or folders OpenSpec can plan across
workspace open = open that linked working set
--agent = use a different agent for this one session
--editor = open the working set as an editor workspace
```
Repo or folder visibility supports exploration and planning. Opening a workspace gives the agent or editor access to linked paths, and implementation starts through an explicit later workflow.
## Command Surface
Supported v1 forms:
```bash
openspec workspace open
openspec workspace open platform
openspec workspace open --agent codex
openspec workspace open platform --agent github-copilot
openspec workspace open --editor
```
The positional workspace name is the primary explicit selection surface for `open`. User-facing docs should prefer the positional form because a flag such as `--workspace <name>` repeats the noun.
For consistency with other workspace commands and scripts, `workspace open` may also support `--workspace <name>` as an alias for the positional name:
```bash
openspec workspace open platform
openspec workspace open --workspace platform
```
User-facing docs should prefer the positional form. If both are provided and they differ, OpenSpec should fail with a clear conflict error.
`--prepare-only` should not be included. The POC used it to build and print launch surfaces without starting the external tool, but that does not map cleanly to a user-facing intent.
`--json` should not be included in this slice. If a future integration needs a machine-readable resolved-open context, design that as a separate context/query surface instead of overloading the launching command.
`--change` should be deferred. Change-scoped open depends on workspace change planning and target semantics that this slice should not invent.
## Workspace Selection
Selection should follow this order:
1. If a positional workspace name is provided, open that known workspace.
2. Otherwise, if the command runs from inside a workspace, open the current workspace.
3. Otherwise, if exactly one workspace is known locally, open it.
4. Otherwise, if multiple workspaces are known and the terminal is interactive, present a picker.
5. Otherwise, fail with a clear message that names the known workspaces and asks the user to pass the workspace name.
This keeps the common cases direct while still supporting global use.
## Preferred Opener
Workspace setup should ask which opener the user wants by default. The answer is machine-local state because different machines may have different installed agents or editors.
`workspace open` uses the saved opener when no override is passed.
`--agent <tool>` is a one-session override that leaves the saved preference unchanged. Persisting a changed default should require an explicit preference/config action in a later slice if users need it.
This slice should not add global workspace opener config. OpenSpec already has a global config system, and workspace-level defaults can be added there later if repeated setup makes the local prompt feel noisy.
The local preference should be shaped so a future global default can fit underneath it with smooth migration. The intended precedence is:
```text
command override
-> workspace-local preferred opener
-> future global workspace default opener
-> interactive prompt or built-in fallback
```
In future config terms, that global default might look like `workspace.defaultOpener`; this slice documents the precedence for later implementation.
Store the preferred opener as a structured object in `.openspec-workspace/local.yaml`:
```yaml
preferred_opener:
kind: agent
id: codex
```
```yaml
preferred_opener:
kind: editor
id: vscode
```
Allowed initial values:
```text
kind: agent, id: codex
kind: agent, id: claude
kind: agent, id: github-copilot
kind: editor, id: vscode
```
The structure keeps the agent/editor distinction clear and leaves room for future opener variants without changing the local-state shape.
Interactive setup should show all supported opener choices, but it should order detected/available openers first. Unavailable choices should still be visible with a note such as `not found on PATH`.
Setup should prefer the plain editor option over an agent when a fallback default is needed for an interactive picker.
Non-interactive setup stores a preferred opener when the caller explicitly passes an opener option. Otherwise, it leaves opener selection for a later interactive `workspace open` prompt or a non-interactive error that explains how to choose an opener.
The setup-time flag should be:
```bash
openspec workspace setup --no-interactive --name platform --link /repo --opener codex
openspec workspace setup --no-interactive --name platform --link /repo --opener editor
```
`--opener <id>` sets the stored preference. It is different from `workspace open --agent <id>` and `workspace open --editor`, which are one-session runtime overrides.
Initial opener detection should stay simple and executable-based:
```text
VS Code editor: code
Codex: codex
Claude: claude
GitHub Copilot in VS Code: code
```
Keep initial detection scoped to executable availability in this slice.
Supported agent values for the initial open surface should be limited to tools with a real launch or attachment mechanism:
```text
claude
codex
github-copilot
```
Plain editor open should be represented by `--editor` with an explicit editor kind.
For this slice, `--editor` means VS Code editor. The `.code-workspace` format is VS Code-specific, so prompts and errors should call this `VS Code editor` rather than implying generic editor support.
`github-copilot` means the VS Code Copilot experience. It should open the maintained `.code-workspace` in VS Code because that is the product surface where this Copilot mode is available.
If OpenSpec later supports a Copilot CLI agent, it should use a distinct value such as `github-copilot-cli` and launch the CLI agent directly. VS Code Copilot and a CLI agent have different opener mechanics, so they should remain distinct opener values.
## Opener Availability
`workspace open` should fail with a clear error when the selected opener is unavailable on the current machine.
The selected opener remains required because it represents user intent, whether it came from local preference or a command-line override.
Errors should name the missing executable or unavailable opener and suggest a concrete next step. For editor-based open, the error should include the `.code-workspace` path so the user can open it manually if needed.
When no preferred opener is stored and no command-line override is provided, `workspace open` should prompt in interactive mode. In non-interactive mode, it should fail and tell the user to pass either an agent override or the editor option.
## Editor Open
`--editor` opens the workspace root plus every linked repo or folder with a valid local path.
For VS Code-style editor support, OpenSpec should create and maintain a `.code-workspace` file as part of the workspace setup/link/relink lifecycle. `workspace open` should launch against existing workspace state.
Expected local workspace shape:
```text
workspace-root/
changes/
<workspace-name>.code-workspace
.openspec-workspace/
workspace.yaml
local.yaml
```
The `.code-workspace` file should include the workspace root and each linked repo or folder with a valid local path. Because linked paths come from machine-local workspace state, OpenSpec-created workspaces should ignore the maintained `.code-workspace` file by default.
The ignore rule should target the specific maintained file and leave other `*.code-workspace` files available for user-authored tracking:
```text
<workspace-name>.code-workspace
```
This lets teams add a separate user-authored portable `.code-workspace` later if they have a shared relative-path layout.
`workspace setup`, `workspace link`, and `workspace relink` should all run the same open-surface sync after mutating workspace state. That sync owns:
- `AGENTS.md`
- `<workspace-name>.code-workspace`
- workspace ignore rules for machine-local files
Even when a command only changes local state, such as `workspace relink`, it should refresh the full openable workspace surface so user-facing files do not drift.
`--agent github-copilot` may use the same editor workspace mechanics, but it also needs Copilot prompt context. Plain `--editor` keeps a normal editor-workspace intent.
`--agent github-copilot` should still open VS Code. The distinction from `--editor` is intent: `--editor` opens the workspace as a normal editor workspace, while `--agent github-copilot` opens the same editor workspace for the user to work with the VS Code Copilot agent experience.
## Workspace Guidance
Workspace setup should install stable guidance in the workspace root, preferably `AGENTS.md`.
The guidance should explain durable workspace rules:
- the workspace root is the planning home
- `changes/` contains workspace-level planning
- linked repos and folders are available for exploration and planning
- visibility supports exploration and planning
- implementation edits start after the user explicitly asks for implementation work
The managed `AGENTS.md` text should stay short and durable, covering stable workspace guidance while runtime details remain discoverable from workspace state. A starting shape:
```markdown
# OpenSpec Workspace Guidance
This directory is an OpenSpec workspace for planning across linked repos or folders.
- Use `changes/` for workspace-level planning.
- Linked repos and folders are available for exploration and planning.
- Repo or folder visibility supports exploration and planning.
- Make implementation edits after the user explicitly asks for implementation work.
- Treat linked repos and folders as the implementation homes for their owned code.
- Use OpenSpec workspace commands instead of hand-editing `.openspec-workspace/*.yaml`.
```
`workspace open` is a launching feature. It should launch the selected opener against existing workspace files.
For Claude and Codex, `workspace open` may still need to pass workspace and linked directory arguments to the agent process at launch because those tools do not consume `.code-workspace` directly. If an opener requires an initial prompt argument, it should be minimal, such as `Open this OpenSpec workspace.`
Dynamic workspace facts should normally be discoverable from existing files:
- linked paths: `.openspec-workspace/local.yaml`
- stable link names: `.openspec-workspace/workspace.yaml`
- active workspace changes: `changes/`
- editor working set: `<workspace-name>.code-workspace`
Report a command file or prompt file path only when the file is actually written and used.
OpenSpec should own a marked workspace-guidance block inside `AGENTS.md`:
```markdown
<!-- OPENSPEC:WORKSPACE-GUIDANCE:START -->
# OpenSpec Workspace Guidance
...
<!-- OPENSPEC:WORKSPACE-GUIDANCE:END -->
```
`workspace setup`, `workspace link`, and `workspace relink` may rewrite that marked block during open-surface sync. Content outside the marked block should be preserved so users can keep their own workspace notes in the same file.
If `AGENTS.md` is missing, OpenSpec should recreate it. If `AGENTS.md` exists and the markers are absent, OpenSpec should append the managed block while preserving existing content.
## Linked Paths
Root workspace open should attach every linked repo or folder with a valid local path.
Broken links are skipped during workspace open. OpenSpec should surface clear status in human output, with `openspec workspace doctor` as the repair path.
Links with repo-local `openspec/` state absent remain valid for workspace open. Missing repo-local OpenSpec state can matter later for implementation readiness while still allowing visibility for exploration and planning.
## Safety Boundary
The opening prompt or editor guidance should say:
```text
Linked repos and folders are visible for exploration and planning.
Make implementation edits after the user explicitly asks for implementation work.
```
Prompt guidance is acceptable for this slice because apply/verify/archive sit outside the open surface. Later implementation workflows should enforce mode and scope through explicit context providers as well as prompt wording.
@@ -0,0 +1,65 @@
## Why
After a user creates a workspace and links repos or folders, they need to open that workspace with their preferred agent or editor and have the working set available immediately.
The workspace should provide repo and folder locations, link names, and the context that distinguishes planning from implementation.
## What Changes
Add the workspace-open experience:
```text
Open this workspace.
Use my preferred opener by default and honor explicit opener overrides.
The opener sees the workspace location, linked repos or folders, current changes, and relevant instructions.
```
Links are the planning context. The local registry serves as a workspace-discovery index for finding known workspaces on the current machine.
Expected user surface:
```bash
openspec workspace open
openspec workspace open platform
openspec workspace open --agent codex
openspec workspace open platform --agent github-copilot
openspec workspace open --editor
```
`workspace open` should open the current workspace when run from inside one, auto-select the only known workspace when run outside a workspace, and present an interactive picker when multiple known workspaces are available. Users can pass a workspace name as the positional argument when they want to choose explicitly.
Workspace setup should ask for and store a preferred opener in machine-local workspace state. `workspace open` uses that preference by default. `--agent <tool>` is a one-session override that leaves the saved preference unchanged.
`--editor` opens the workspace as an editor workspace. This is related to, but distinct from, `--agent github-copilot`: GitHub Copilot needs editor workspace support plus agent prompt context, while plain editor open should focus on opening the linked working set.
Workspace guidance should live in durable workspace files where possible:
- stable behavior belongs in workspace-level `AGENTS.md`
- opener-specific launch prompts stay minimal when required
- linked repos or folders are visible for exploration and planning before a change exists
This slice supports root workspace launching through the documented opener forms. Public preview (`--prepare-only`) and machine-readable context (`--json`) surfaces belong in a future context/query design if a clear user need appears.
This slice focuses on root workspace open behavior. Change-scoped sessions need the target model from workspace change planning before they can be specified cleanly.
Planning dependency:
- Depends on `workspace-create-and-register-repos`.
## Capabilities
### New Capabilities
- `workspace-open`: Opens a workspace through a preferred agent or VS Code editor with linked repos or folders available for exploration and planning.
### Modified Capabilities
- `workspace-foundation`: Extends machine-local workspace state and setup/link/relink behavior with a preferred opener and maintained openable workspace surface.
## Impact
- `openspec workspace open`
- Workspace setup preferred opener prompt and local preference storage.
- Workspace prompt, editor workspace, and agent-launch context.
- Generated or committed agent guidance for workspace mode.
- Tests for opening inside a workspace, auto-selecting one known workspace, picking among multiple known workspaces, opening by workspace name, one-session agent overrides, and editor open.
@@ -0,0 +1,76 @@
## ADDED Requirements
### Requirement: Workspace Preferred Opener State
OpenSpec SHALL store a workspace's preferred opener in machine-local workspace state when the user explicitly chooses one.
#### Scenario: Recording an interactive setup opener choice
- **WHEN** an interactive user chooses a preferred opener during `openspec workspace setup`
- **THEN** OpenSpec SHALL record the opener in `.openspec-workspace/local.yaml`
- **AND** the stored value SHALL use a structured `preferred_opener` object with `kind` and `id`
#### Scenario: Recording a non-interactive setup opener choice
- **WHEN** a non-interactive user runs `openspec workspace setup --no-interactive --opener codex`
- **THEN** OpenSpec SHALL record `preferred_opener.kind` as `agent`
- **AND** it SHALL record `preferred_opener.id` as `codex`
#### Scenario: Leaving opener unset during non-interactive setup
- **WHEN** a non-interactive user runs `openspec workspace setup --no-interactive` with opener selection omitted
- **THEN** OpenSpec SHALL leave the workspace preferred opener unset
- **AND** the unset state SHALL allow `workspace open` to prompt later
#### Scenario: Supported preferred opener values
- **WHEN** OpenSpec accepts a preferred opener value
- **THEN** it SHALL accept `codex`, `claude`, `github-copilot`, and `editor`
- **AND** it SHALL map `editor` to `kind: editor` and `id: vscode`
- **AND** it SHALL map agent values to `kind: agent` and the matching agent `id`
#### Scenario: Ordering setup opener choices
- **WHEN** interactive setup displays opener choices
- **THEN** OpenSpec SHALL show all supported openers
- **AND** it SHALL order openers with detected executables before unavailable openers
- **AND** unavailable openers SHALL remain visible with an availability note
### Requirement: Maintained Workspace Open Surface
OpenSpec SHALL maintain files that make a workspace directly openable after setup and link changes.
#### Scenario: Creating the open surface during setup
- **WHEN** `openspec workspace setup` creates a workspace
- **THEN** OpenSpec SHALL create or refresh `AGENTS.md`
- **AND** it SHALL create or refresh `<workspace-name>.code-workspace`
- **AND** it SHALL create or refresh workspace ignore rules for machine-local open files
#### Scenario: Refreshing the open surface after linking
- **WHEN** `openspec workspace link` succeeds
- **THEN** OpenSpec SHALL refresh `AGENTS.md`
- **AND** it SHALL refresh `<workspace-name>.code-workspace`
- **AND** it SHALL refresh workspace ignore rules for machine-local open files
#### Scenario: Refreshing the open surface after relinking
- **WHEN** `openspec workspace relink` succeeds
- **THEN** OpenSpec SHALL refresh `AGENTS.md`
- **AND** it SHALL refresh `<workspace-name>.code-workspace`
- **AND** it SHALL refresh workspace ignore rules for machine-local open files
#### Scenario: Building the VS Code workspace file
- **WHEN** OpenSpec refreshes `<workspace-name>.code-workspace`
- **THEN** the file SHALL include the workspace root
- **AND** the workspace root folder entry SHALL use the root path without a synthetic display name
- **AND** it SHALL include every linked repo or folder with a valid local path
- **AND** it SHALL omit linked repos or folders whose local paths are missing or invalid
#### Scenario: Ignoring the maintained VS Code workspace file
- **WHEN** OpenSpec refreshes workspace ignore rules
- **THEN** it SHALL ignore the specific maintained `<workspace-name>.code-workspace` file
- **AND** user-authored `*.code-workspace` files SHALL remain eligible for tracking
#### Scenario: Preserving user-authored AGENTS content
- **GIVEN** `AGENTS.md` contains content outside the OpenSpec workspace guidance markers
- **WHEN** OpenSpec refreshes workspace guidance
- **THEN** it SHALL replace only the marked OpenSpec workspace guidance block
- **AND** it SHALL preserve content outside the markers
#### Scenario: Appending AGENTS guidance when markers are missing
- **GIVEN** `AGENTS.md` exists and OpenSpec workspace guidance markers are absent
- **WHEN** OpenSpec refreshes workspace guidance
- **THEN** it SHALL append the marked OpenSpec workspace guidance block
- **AND** it SHALL preserve the existing file content
@@ -0,0 +1,199 @@
## ADDED Requirements
### Requirement: Workspace Open Command
OpenSpec SHALL provide a `workspace open` command that opens an OpenSpec workspace working set through an agent or VS Code editor.
#### Scenario: Opening the current workspace
- **GIVEN** the command runs from inside an OpenSpec workspace
- **WHEN** the user runs `openspec workspace open`
- **THEN** OpenSpec SHALL open that current workspace
- **AND** it SHALL use the selected opener for that workspace
#### Scenario: Opening a named workspace
- **GIVEN** a workspace named `platform` is known locally
- **WHEN** the user runs `openspec workspace open platform`
- **THEN** OpenSpec SHALL open the `platform` workspace
#### Scenario: Opening a named workspace with the selection flag
- **GIVEN** a workspace named `platform` is known locally
- **WHEN** the user runs `openspec workspace open --workspace platform`
- **THEN** OpenSpec SHALL open the `platform` workspace
#### Scenario: Conflicting workspace selectors
- **GIVEN** workspaces named `platform` and `checkout` are known locally
- **WHEN** the user runs `openspec workspace open platform --workspace checkout`
- **THEN** OpenSpec SHALL fail with a clear conflict error
- **AND** the error SHALL name both conflicting selectors
#### Scenario: Handling unsupported preview and JSON flags
- **WHEN** the user runs `openspec workspace open` with `--prepare-only` or `--json`
- **THEN** OpenSpec SHALL fail with a clear error that the root workspace open surface supports launching through a selected opener
- **AND** the error SHALL direct preview or machine-readable context needs to a future context/query surface
#### Scenario: Handling change-scoped open before workspace planning
- **WHEN** the user runs `openspec workspace open --change <id>`
- **THEN** OpenSpec SHALL fail with a clear error that this slice supports root workspace open
- **AND** the error SHALL direct change-scoped open behavior to future workspace change planning
### Requirement: Workspace Selection For Open
OpenSpec SHALL resolve the workspace to open using current workspace context, local registry state, and interactive selection.
#### Scenario: Current workspace wins
- **GIVEN** the command runs from a workspace folder or one of its subdirectories
- **AND** no workspace name is provided
- **WHEN** the user runs `openspec workspace open`
- **THEN** OpenSpec SHALL open the current workspace
#### Scenario: Auto-selecting the only known workspace
- **GIVEN** the command runs outside a workspace
- **AND** exactly one workspace is known locally
- **WHEN** the user runs `openspec workspace open`
- **THEN** OpenSpec SHALL open that known workspace directly
#### Scenario: Picking from multiple workspaces
- **GIVEN** the command runs outside a workspace
- **AND** multiple workspaces are known locally
- **AND** the terminal is interactive
- **WHEN** the user runs `openspec workspace open`
- **THEN** OpenSpec SHALL present a picker with workspace names and locations
- **AND** it SHALL open the workspace the user selects
#### Scenario: Non-interactive ambiguous selection
- **GIVEN** the command runs outside a workspace
- **AND** multiple workspaces are known locally
- **AND** the terminal is non-interactive
- **WHEN** the user runs `openspec workspace open`
- **THEN** OpenSpec SHALL fail with a clear message listing the known workspace names
- **AND** it SHALL ask the user to pass a workspace name
#### Scenario: No known workspace
- **GIVEN** the command runs outside a workspace
- **AND** no workspaces are known locally
- **WHEN** the user runs `openspec workspace open`
- **THEN** OpenSpec SHALL fail with a clear message
- **AND** it SHALL suggest running `openspec workspace setup`
### Requirement: Opener Resolution
OpenSpec SHALL resolve the opener from command overrides, workspace-local preference, or an interactive prompt.
#### Scenario: Conflicting opener overrides
- **WHEN** the user runs `openspec workspace open --agent codex --editor`
- **THEN** OpenSpec SHALL fail with a clear conflict error naming `--agent` and `--editor`
- **AND** it SHALL avoid launching any opener
- **AND** it SHALL leave the stored preferred opener unchanged
#### Scenario: Using the stored preferred opener
- **GIVEN** the workspace has a machine-local preferred opener
- **WHEN** the user runs `openspec workspace open` using default opener resolution
- **THEN** OpenSpec SHALL use the stored preferred opener
#### Scenario: Overriding with an agent for one session
- **GIVEN** the workspace has a stored preferred opener
- **WHEN** the user runs `openspec workspace open --agent codex`
- **THEN** OpenSpec SHALL use Codex for that open command
- **AND** it SHALL leave the stored preferred opener unchanged
#### Scenario: Overriding with VS Code editor for one session
- **GIVEN** the workspace has a stored preferred opener
- **WHEN** the user runs `openspec workspace open --editor`
- **THEN** OpenSpec SHALL open the workspace in VS Code editor mode
- **AND** it SHALL leave the stored preferred opener unchanged
#### Scenario: Prompting when no opener is stored
- **GIVEN** the workspace has no stored preferred opener
- **AND** the terminal is interactive
- **WHEN** the user runs `openspec workspace open` using default opener resolution
- **THEN** OpenSpec SHALL prompt the user to choose an opener
- **AND** it SHALL only offer openers with detected executables
#### Scenario: Failing when no opener can be prompted
- **GIVEN** the workspace has no stored preferred opener
- **AND** the terminal is interactive
- **AND** no supported opener executable is available on `PATH`
- **WHEN** the user runs `openspec workspace open` using default opener resolution
- **THEN** OpenSpec SHALL fail with a clear message that no supported opener is available
- **AND** it SHALL avoid prompting with unlaunchable choices
#### Scenario: Failing when no opener is stored in non-interactive mode
- **GIVEN** the workspace has no stored preferred opener
- **AND** the terminal is non-interactive
- **WHEN** the user runs `openspec workspace open` using default opener resolution
- **THEN** OpenSpec SHALL fail with a clear message
- **AND** it SHALL ask the user to pass `--agent <tool>` or `--editor`
### Requirement: Opener Launch Behavior
OpenSpec SHALL launch the selected opener using existing workspace files and linked path state.
#### Scenario: Opening VS Code editor
- **GIVEN** the user selected the VS Code editor opener
- **WHEN** `code` is available on `PATH`
- **THEN** OpenSpec SHALL open the workspace's maintained `.code-workspace` file with VS Code
#### Scenario: Opening GitHub Copilot in VS Code
- **GIVEN** the user selected `--agent github-copilot`
- **WHEN** `code` is available on `PATH`
- **THEN** OpenSpec SHALL open the workspace's maintained `.code-workspace` file with VS Code
- **AND** it SHALL treat this as the VS Code Copilot experience
#### Scenario: Opening Codex
- **GIVEN** the user selected `--agent codex`
- **WHEN** `codex` is available on `PATH`
- **THEN** OpenSpec SHALL launch Codex from the workspace root
- **AND** it SHALL attach every linked repo or folder with a valid local path using Codex's supported directory attachment mechanism
#### Scenario: Opening Claude
- **GIVEN** the user selected `--agent claude`
- **WHEN** `claude` is available on `PATH`
- **THEN** OpenSpec SHALL launch Claude from the workspace root
- **AND** it SHALL attach every linked repo or folder with a valid local path using Claude's supported directory attachment mechanism
#### Scenario: Missing opener executable
- **GIVEN** the selected opener requires an executable that is not available on `PATH`
- **WHEN** the user runs `openspec workspace open`
- **THEN** OpenSpec SHALL fail with a clear error naming the missing executable
- **AND** it SHALL keep the selected opener as the required opener
#### Scenario: Missing VS Code executable
- **GIVEN** the selected opener is VS Code editor or GitHub Copilot in VS Code
- **AND** `code` is not available on `PATH`
- **WHEN** the user runs `openspec workspace open`
- **THEN** OpenSpec SHALL fail with a clear error naming `code`
- **AND** it SHALL include the maintained `.code-workspace` path so the user can open it manually
### Requirement: Linked Working Set Visibility
OpenSpec SHALL make linked repos and folders visible for workspace exploration and planning before change creation.
#### Scenario: Attaching valid linked paths
- **GIVEN** a workspace has linked repos or folders with valid local paths
- **WHEN** the user opens the workspace through an opener that supports linked directory attachment
- **THEN** OpenSpec SHALL include every valid linked path in the opened working set
- **AND** it SHALL support opening before a workspace change exists
#### Scenario: Skipping broken linked paths
- **GIVEN** a workspace has at least one linked path that is missing or not recorded locally
- **WHEN** the user opens the workspace
- **THEN** OpenSpec SHALL skip the broken linked path
- **AND** it SHALL report that the path was skipped with `openspec workspace doctor` as the repair path
- **AND** it SHALL continue opening the workspace when the selected opener itself is available
#### Scenario: Opening links with repo-local OpenSpec state absent
- **GIVEN** a linked repo or folder has a valid local path and repo-local `openspec/` state is absent
- **WHEN** the user opens the workspace
- **THEN** OpenSpec SHALL include that link when its local path is valid
- **AND** it SHALL treat missing repo-local OpenSpec state as an implementation-readiness concern for later workflows while continuing open
### Requirement: Workspace Open Guidance
OpenSpec SHALL use durable workspace guidance as the primary context source for root workspace open.
#### Scenario: Launching with existing workspace guidance
- **GIVEN** the workspace has OpenSpec-managed guidance in `AGENTS.md`
- **WHEN** the user opens the workspace
- **THEN** OpenSpec SHALL refresh the maintained `.code-workspace` from current linked path state
- **AND** it SHALL launch the selected opener against refreshed workspace files
- **AND** it SHALL use durable workspace files as the primary workspace-open artifact
#### Scenario: Minimal required launch prompt
- **GIVEN** an opener requires an initial prompt argument
- **WHEN** OpenSpec launches that opener
- **THEN** OpenSpec SHALL use a minimal prompt such as `Open this OpenSpec workspace.`
- **AND** durable workspace rules SHALL remain in workspace files
@@ -0,0 +1,89 @@
## 1. Preferred Opener State
- [x] 1.1 Add structured `preferred_opener` support to workspace local state parsing and serialization
- [x] 1.2 Support backward-compatible parsing for existing local workspace files while adding `preferred_opener`
- [x] 1.3 Validate supported opener values: `codex`, `claude`, `github-copilot`, and `editor`
- [x] 1.4 Map `editor` to `kind: editor, id: vscode`
- [x] 1.5 Map agent opener values to `kind: agent` with the matching `id`
- [x] 1.6 Add simple executable detection for `code`, `codex`, and `claude`
- [x] 1.7 Add unit tests for preferred opener parsing, serialization, and invalid opener values
## 2. Setup Opener Selection
- [x] 2.1 Add interactive setup prompt for the preferred opener
- [x] 2.2 Show all supported opener choices with detected openers ordered first
- [x] 2.3 Mark unavailable opener choices with a clear availability note
- [x] 2.4 Prefer the plain editor option for setup fallback selection when a fallback is needed
- [x] 2.5 Add `workspace setup --opener <id>` for non-interactive setup
- [x] 2.6 Store a preferred opener during non-interactive setup when `--opener` is provided
- [x] 2.7 Add tests for interactive opener selection and non-interactive `--opener`
- [x] 2.8 Add tests that non-interactive setup with omitted `--opener` leaves opener unset
## 3. Open Surface Sync
- [x] 3.1 Add a shared open-surface sync helper used by setup, link, and relink
- [x] 3.2 Create or refresh root `AGENTS.md` with an OpenSpec-managed workspace guidance block
- [x] 3.3 Preserve user-authored `AGENTS.md` content outside the managed block
- [x] 3.4 Append the managed block to unmarked existing `AGENTS.md` files
- [x] 3.5 Create or refresh `<workspace-name>.code-workspace` at the workspace root
- [x] 3.6 Include the workspace root and every linked repo or folder with a valid local path in the `.code-workspace`
- [x] 3.7 Omit linked repos or folders with missing or invalid local paths from the `.code-workspace`
- [x] 3.8 Refresh `.gitignore` with the specific maintained `<workspace-name>.code-workspace` entry
- [x] 3.9 Scope ignore updates to the maintained `<workspace-name>.code-workspace` file
- [x] 3.10 Add cross-platform tests for `.code-workspace` path construction and Windows-style paths where practical
## 4. Workspace Open Selection
- [x] 4.1 Add `openspec workspace open [name]`
- [x] 4.2 Support `openspec workspace open --workspace <name>` as an alias for the positional name
- [x] 4.3 Fail clearly when positional name and `--workspace` are both provided with different values
- [x] 4.4 Open the current workspace when run from a workspace folder or subdirectory
- [x] 4.5 Auto-select the only known workspace when run outside a workspace
- [x] 4.6 Present an interactive picker when multiple workspaces are known
- [x] 4.7 Report ambiguous workspace selection in non-interactive mode and list known workspace names
- [x] 4.8 Report unresolved workspace selection clearly and suggest `openspec workspace setup`
- [x] 4.9 Handle unsupported `--prepare-only`, `--json`, and `--change` flags with clear errors
- [x] 4.10 Add command integration tests for selection, conflict, unsupported flags, and no-workspace cases
## 5. Opener Resolution
- [x] 5.1 Resolve command-line opener overrides before workspace-local preferences
- [x] 5.2 Implement `workspace open --agent codex`
- [x] 5.3 Implement `workspace open --agent claude`
- [x] 5.4 Implement `workspace open --agent github-copilot`
- [x] 5.5 Implement `workspace open --editor`
- [x] 5.6 Keep the stored preferred opener unchanged for `--agent` and `--editor` overrides
- [x] 5.7 Prompt interactively to choose an opener when the opener preference is unset
- [x] 5.8 Report unset opener preference in non-interactive mode with override guidance
- [x] 5.9 Add tests for opener precedence, prompting, non-interactive failure, and unchanged preference behavior
## 6. Opener Launchers
- [x] 6.1 Launch VS Code editor by opening the maintained `.code-workspace` file with `code`
- [x] 6.2 Launch GitHub Copilot by opening the maintained `.code-workspace` file with VS Code
- [x] 6.3 Launch Codex from the workspace root with valid linked paths attached
- [x] 6.4 Launch Claude from the workspace root with valid linked paths attached
- [x] 6.5 Use a minimal launch prompt when an agent CLI requires an initial prompt argument
- [x] 6.6 Report skipped broken links with `openspec workspace doctor` as the repair path
- [x] 6.7 Fail clearly when the selected opener executable is unavailable
- [x] 6.8 Include the `.code-workspace` path in VS Code opener availability errors
- [x] 6.9 Keep the selected opener as required when launching
- [x] 6.10 Add unit tests for launcher command construction using test doubles for external tools
## 7. Documentation And Command Metadata
- [x] 7.1 Update workspace command help for setup `--opener`, open positional name, `--workspace`, `--agent`, and `--editor`
- [x] 7.2 Update command registry and shell completion metadata for the new workspace open surface
- [x] 7.3 Update workspace documentation to describe preferred openers, editor open, agent open, and `.code-workspace` behavior
- [x] 7.4 Document that `.code-workspace` is machine-local and ignored by default
- [x] 7.5 Document that root workspace open supports exploration and planning, with implementation started by explicit user request
## 8. Verification
- [x] 8.1 Run `node bin/openspec.js validate workspace-open-agent-context --strict`
- [x] 8.2 Run targeted workspace command tests
- [x] 8.3 Run targeted workspace foundation tests
- [x] 8.4 Run command-generation or launcher tests that cover Codex, Claude, GitHub Copilot, and VS Code editor paths
- [x] 8.5 Run cross-platform path-focused tests for workspace open surfaces
- [x] 8.6 Run the relevant TypeScript test suite
- [x] 8.7 Run `pnpm run build`
@@ -0,0 +1,242 @@
## Context
Workspace setup already creates a planning home, records linked repos or folders, stores a preferred opener, and maintains the root open surface. For workspace change planning to work in practice, the opened agent also needs OpenSpec workflow skills available from that workspace root.
Repo-local `openspec init` and `openspec update` already provide the user model for choosing agent surfaces and generating skills. Workspace setup should feel similar, but the installation target is the workspace root rather than any linked repo or folder.
The existing artifact workflow assumes a change lives under a repo-local `openspec/changes/<id>` path. Workspace planning needs the same workflow vocabulary, but the planning home may be a workspace root and the implementation homes may be linked repos or folders.
## Goals / Non-Goals
**Goals:**
- Install OpenSpec agent skills into the workspace root during workspace setup.
- Use the active global profile to select which workflow skills are installed in the workspace.
- Let users choose which agents receive skills with familiar `--tools` semantics.
- Persist workspace-local agent skill selection so update can refresh the same agents later.
- Let users refresh, add, or remove workspace-local skills later through `workspace update`.
- Detect and report workspace-local skill drift from the active global profile.
- Let `openspec config profile` offer to apply changed profile settings to the current workspace when run from inside a workspace.
- Redirect workspace users from repo-local `openspec update` to `openspec workspace update`.
- Add a built-in workspace planning schema for workspace-scoped changes.
- Create workspace changes under the workspace planning path.
- Represent affected areas without forcing implementation artifacts into linked repos.
- Give agents machine-readable planning context through status/instructions output.
- Preserve the workspace boundary: linked repos and folders remain untouched during setup/update.
**Non-Goals:**
- Generating slash commands as part of workspace setup.
- Honoring global `delivery: commands` by generating workspace command files.
- Installing skills into linked repos or folders.
- Adding workspace-local workflow profiles separate from global config.
- Solving workspace-scoped artifact path discovery in the first setup-skill step.
- Adding a separate artifact-context CLI command in the first version.
- Implementing workspace apply, verify, or archive semantics end to end.
- Changing repo-local `openspec init` or `openspec update` behavior.
## Decisions
### Use agent-skill language in workspace UX
Workspace setup should ask, "Which agents should get OpenSpec skills in this workspace?" rather than using the broader "AI tools" wording. The user-visible action is installing skills for coding agents, and the target is the workspace planning home.
Alternative considered: reuse the exact `init` wording. That would be familiar, but it hides the important distinction between opening a workspace and installing skills into it.
### Reuse the existing tool id model
The CLI should use the existing `--tools all|none|<ids>` grammar for non-interactive setup and update. Reusing the existing tool IDs avoids inventing a second naming system for the same configured agents.
Alternative considered: add `--agents`. That reads better in isolation, but it creates unnecessary parallel vocabulary next to `openspec init --tools`.
### Let profile choose workflows and tools choose agents
Workspace setup/update should use the active global profile to decide which OpenSpec workflow skills are installed. The profile answers "which actions are available?" while `--tools` answers "which agents get those actions?" Keeping those concerns separate preserves the existing profile model and avoids adding workspace-local workflow selection in this slice.
If global profile is `core`, workspace skills should include the core workflow set. If global profile is `custom`, workspace skills should include only the configured custom workflows. `--tools none` should still mean no agent skills are installed, regardless of profile.
Alternative considered: add a workspace-local profile file. That might be useful later for team-shared workspace defaults, but this slice already stores machine-local agent paths and should avoid introducing another config authority before the global profile behavior works.
### Preselect the preferred opener when possible
Interactive setup should preselect the preferred opener when that opener maps to a skill-capable agent. The user can accept the default, add more agents, or deselect it.
Alternative considered: install skills only for the preferred opener. That is simpler, but opener choice means "how should I open this workspace" while skill selection means "which agents should understand OpenSpec here."
### Persist selected workspace skill agents locally
Workspace setup should store the selected skill-capable agents in `.openspec-workspace/local.yaml` because agent paths and installed tool surfaces are machine-local. Workspace update should use that stored selection when the user does not pass `--tools` or make a new interactive selection.
Explicit `--tools` on workspace setup/update should replace the stored selection. `--tools none` should store an empty selection and remove only known OpenSpec-managed workspace skill directories.
The local state should also record enough last-applied information to support drift detection, such as the workflow IDs installed for each selected agent and the effective global profile/delivery at the time of the last successful sync. This is diagnostic state, not a second source of truth.
Alternative considered: infer selected agents by scanning `.codex/skills/`, `.claude/skills/`, and similar directories. Scanning is useful as a fallback, but persisted selection gives predictable update behavior and avoids treating unrelated user-authored files as OpenSpec-managed state.
### Keep non-interactive setup backward-compatible
`openspec workspace setup --no-interactive` should not require `--tools`. If `--tools` is omitted, setup should create the workspace and skip skill installation, preserving existing scripted workspace setup behavior. Human and JSON output should say that no workspace skills were installed and that `openspec workspace update --tools <ids>` can add them later.
`openspec workspace update --no-interactive` without `--tools` should refresh the stored workspace skill agent selection. If no selection is stored, it should complete without installing skills and report a clear no-op with guidance to pass `--tools`.
Alternative considered: require `--tools` whenever workspace setup/update is non-interactive. That mirrors repo-local init, but it would break existing workspace setup scripts that predate workspace-local skill installation.
### Generate workspace-local skills only
Workspace setup/update should generate skills under the workspace root, such as `.codex/skills/` or `.claude/skills/`. It should not generate slash commands in this slice because some command adapters resolve to global locations, and workspace setup should remain local and predictable.
When global delivery is `commands` or `both`, workspace setup/update should still generate only skills and report that workspace command generation is not part of this slice. This keeps profile workflow selection useful without making workspace setup perform global or repo-local command writes.
Alternative considered: mirror `init` exactly and generate both skills and commands. That risks surprising global writes and makes the setup boundary harder to explain.
### Add `workspace update` for skill refresh
`openspec workspace update` should refresh, add, or remove workspace-local OpenSpec skills after setup. It should resolve the current workspace when run from inside a workspace, and also support named and non-interactive forms.
Workspace update should compare the active global profile's workflow selection with the last applied workspace skill state. If they differ, update should add/remove only OpenSpec-managed workflow skill directories for the selected agents. Workspace doctor/list/status surfaces may report the drift as a warning, and `openspec config profile` no-op inside a workspace should use the same drift check for guidance.
Alternative considered: reuse `openspec update` from inside the workspace. That command currently means repo/project update, while workspace update needs workspace selection, workspace JSON/status behavior, and linked-repo safety rules.
### Make `config profile` workspace-aware
`openspec config profile` should remain a global configuration command. When it runs inside a repo-local OpenSpec project and the user chooses to apply changes, it should continue to run `openspec update`.
When it runs inside an OpenSpec workspace and the profile or delivery settings actually change, it should prompt to apply changes to the current workspace. If confirmed, it should run `openspec workspace update` for that workspace. If declined, it should explain that the global config changed and the user can run `openspec workspace update` later.
The preset shortcut `openspec config profile core` should keep its non-interactive character and not launch an apply prompt. When run from inside a workspace, it should save global config and print workspace-specific follow-up guidance to run `openspec workspace update`. When run inside a repo-local project, it should keep the existing repo-local guidance.
For this slice, automatic workspace context should come from the workspace planning home and its own subdirectories. Running a command from inside a linked repo or folder should keep that location's repo-local behavior unless the user explicitly selects the workspace with a workspace command option. This avoids surprising repo-local commands merely because the repo is registered as a workspace link.
If a directory is both inside a workspace planning home and inside a repo-local OpenSpec project, the nearest planning home should determine the apply prompt. This avoids applying a workspace profile change to a linked repo when the user is intentionally operating from the workspace planning home.
Alternative considered: make `openspec config profile` update all known workspaces. That would be convenient in small setups, but global config changes should not fan out into multiple planning homes without an explicit per-workspace action.
### Resolve a planning home before acting
Workflow commands should resolve whether the current change belongs to a repo-local planning home or a workspace planning home before computing paths. The resolver should identify the planning root, change root, linked areas when present, and whether implementation edits are allowed. Linked repos are not implicitly treated as workspace planning homes just because they are registered in a workspace; workspace-scoped behavior is selected from the workspace planning home or through explicit workspace selection.
Alternative considered: add workspace-specific command branches wherever paths are used. That would make the workspace model leak into every workflow and make generated skills more fragile.
### Store workspace changes in the workspace planning path
Workspace changes should live under the workspace planning path, initially `changes/<id>` at the workspace root. Creating the workspace change should capture shared intent once and may record affected areas, but it should not create repo-local `openspec/changes/<id>` directories in linked repos.
Alternative considered: materialize a repo-local change in every affected repo during workspace change creation. That was easy to reason about in the POC, but it commits too early and makes exploration look like implementation.
### Add a workspace planning schema
Workspace-scoped changes should use a built-in `workspace-planning` schema by default. This keeps the workflow verbs familiar while letting workspace changes have a structure that fits cross-area planning.
Initial artifact shape:
```text
changes/<id>/
.openspec.yaml # schema: workspace-planning
proposal.md # shared goal and scope
design.md # cross-area decisions
tasks.md # coordination tasks, optionally grouped by affected area
specs/
<area-or-repo>/
<capability>/spec.md
```
The first schema should stay intentionally close to the normal OpenSpec artifact shape: proposal, specs, design, and tasks. Area-specific requirements live under `specs/` and area-specific work can be represented as sections in `tasks.md`. This slice does not introduce another area manifest beside those normal planning artifacts.
Alternative considered: reuse `spec-driven` unchanged and make all workspace differences implicit in status output. That hides the fact that workspace planning needs different instructions for organizing requirements and tasks by affected area.
Alternative considered: create separate workspace workflow skills instead of a schema. That would duplicate workflow guidance and make workspace mode feel like a different product.
### Support nested workspace spec paths in the schema
The `workspace-planning` schema should define its specs artifact so nested workspace paths are first-class, not accidental. The intended output pattern is `specs/**/*.md`, and the schema instructions should explicitly describe `specs/<area-or-repo>/<capability>/spec.md` as the default convention for area-specific requirements.
Status and instructions output should preserve the concrete nested paths it discovers. Repo-local spec sync, archive, and validation paths that assume `specs/<capability>/spec.md` should not treat workspace-scoped specs as repo-local capability specs until a later explicit implementation, sync, or archive workflow selects an affected area and defines the destination.
### Use affected areas, not targets or repo slices
The planning model should call ownership or implementation boundaries "affected areas." Affected areas can start with registered workspace link names, but the language should leave room for folders, packages, services, apps, or docs sites. Delivery breakdown remains a separate concept and should not be called an area.
Alternative considered: keep "targets" because it maps to the old POC flag. That term is implementation-first and encourages users to choose repos before the plan is clear.
### Make status JSON the agent context contract
`openspec status --change <id> --json` should become the primary source of machine-readable action context. It should include the planning home, change root, concrete artifact paths, affected areas, next steps, and constraints such as allowed edit roots when implementation is later in scope.
Alternative considered: create a separate context command immediately. Status is already used by generated workflow skills, so enriching it first gives agents a single place to look.
### Keep generated skills path-agnostic
Generated workflow skills should ask OpenSpec where artifacts live instead of embedding repo-local paths such as `openspec/changes/<name>`. The standard skill pattern should be:
```text
1. Run `openspec status --change "<name>" --json`.
2. Use the returned planning home, artifacts, next steps, and action context.
3. Run `openspec instructions <artifact> --change "<name>" --json` before writing an artifact.
4. Write to the resolved path returned by the CLI.
```
This keeps the same skill usable in repo-local and workspace-scoped changes. If status/instructions output later becomes too crowded, a separate context command can be introduced in a future change without changing the high-level skill rule.
Alternative considered: add a new `openspec context` command now. That may become useful, but it adds a new surface before we have proven that enriched status/instructions are insufficient.
### Guard unsupported workspace workflow actions
The global profile may select workflows whose workspace-scoped behavior is not implemented in this slice, such as full workspace apply, verify, or archive. Generated workspace-local skills for those workflows should be safe: they should inspect status/instructions, explain the unsupported workspace action, and avoid editing linked repos unless a later explicit implementation workflow supplies an allowed edit root.
This keeps the workspace skill set aligned with the user's profile while preventing repo-local fallbacks from pretending to implement workspace semantics.
Alternative considered: filter unsupported workflows out of workspace skill generation. That would avoid unsupported commands, but it would make the workspace skill set silently diverge from the user's profile and make drift harder to explain.
### Redirect repo update from workspace roots
`openspec update` should remain the repo/project update command. When it is run from an OpenSpec workspace planning home, it should not try to treat the workspace as a repo-local project. It should fail or redirect with clear guidance to run `openspec workspace update`.
Alternative considered: make `openspec update` polymorphic and perform workspace update inside workspaces. That would be convenient, but it blurs the repo/project versus workspace boundary this change is trying to make explicit.
### Update docs, help, and completions
The CLI help, command registry/completions, and user docs should include `openspec workspace update`, its `--tools` behavior, the global-profile relationship, and the skills-only workspace delivery rule.
Alternative considered: document this only after implementation. Because profile/update behavior is easy to confuse with repo-local update, the docs and help updates are part of the user-facing feature.
### Treat manual acceptance and UX review as phase gates
Each phase should produce a user-testable increment, even when most of the work is internal. The phase is not done until a user can exercise the named behavior through the CLI, inspect the resulting output or files, and understand what changed.
Each implementation phase should include a manual acceptance pass in addition to automated tests. The manual pass should exercise the real CLI flow, inspect the generated files or output, and confirm linked repos or folders stay untouched where that is part of the contract.
Each phase should also include a lightweight UX review of prompts, command forms, human output, JSON output, artifact paths, and next-step guidance. Any confusing UX found during review should be fixed in the same phase or recorded as an intentional follow-up before the phase is considered done.
Alternative considered: keep manual review only in the final verification phase. That would catch end-to-end issues late, but workspace planning is mostly workflow and agent-facing UX, so each phase needs its own human check while the behavior is still fresh.
### Reduce self-validation bias with evidence-based review
Implementation should define acceptance evidence before marking tasks done. For each phase, the implementer should capture the exact manual commands or interaction path, expected observations, and actual observations. A task is not complete merely because the implementer believes the code matches the design.
When practical, a separate reviewer or fresh agent context should run the manual acceptance checklist and UX review using only the change artifacts, CLI output, and observed filesystem state. If a separate reviewer is not available, the implementer should rerun the checklist from a clean temporary workspace and record the evidence in the change notes or final implementation summary.
Alternative considered: rely on automated tests plus the implementer's final review. Automated tests are necessary, but this change is workflow-heavy and agent-facing, so independent evidence is more useful than confidence alone.
## Deferred Direction
The earlier product notes pointed at a richer workspace model than this slice ships. Keep that direction as follow-up material, not competing current scope.
- Full workspace apply should select or confirm one work focus before implementation. The first work focus should be an affected area with an allowed edit root; later work may add an optional delivery phase when a large change needs sequencing. Until that model exists, workspace apply/verify/archive skills remain guarded.
- Workspace verify and archive should wait for a clear model of partial area completion, final whole-change completion, and how workspace-scoped specs become repo-local canonical specs.
- Scoped plan files may eventually attach at the change, phase, affected-area, or work-focus level. This slice intentionally keeps the first workspace schema close to normal OpenSpec artifacts: proposal, specs, design, and tasks.
- Affected areas can start as registered workspace link names, but future flows may refine or derive them from planning artifacts. That derivation should avoid reintroducing target-first or repo-slice language.
- Workflow skills may later separate generic OpenSpec workflow semantics from agent-specific affordances such as asking questions, tracking todos, or delegating work. This slice only makes generated workflow skills path-agnostic.
- OpenSpec may need a named exploratory-notes convention for preserving unsettled thinking before it is promoted into proposal, design, specs, or tasks. This cleanup keeps the current change folder focused on standard artifacts.
## Risks / Trade-offs
- Skill generation logic may drift from `init/update` → share the same template generation and tool validation helpers where practical.
- Removing unselected skills could remove user-modified files → remove only known OpenSpec-managed workflow skill directories by explicit workflow list.
- `--tools` is less precise than `--agents` in workspace UX → keep `--tools` for CLI consistency, but use "agents" in prompts and human output.
- Global delivery can say `commands` while workspace update remains skills-only → report this explicitly so users know command generation is deferred, not silently broken.
- `config profile` may run from a linked repo inside an opened workspace → resolve the current planning home carefully and apply only to that home.
- Stored workspace skill state can become stale or hand-edited → treat it as diagnostic machine-local state and always reconcile managed files from the active global profile during update.
- Profile-selected workflows may not yet have full workspace semantics → generated skills must guard unsupported actions and avoid repo-local fallbacks.
- Existing generated skills still contain repo-local path assumptions → handle that as a later artifact-context step after workspace-local skills can be installed.
- Status JSON may become too broad → keep fields plain and action-oriented, such as `planningHome`, `artifacts`, `affectedAreas`, `nextSteps`, and `actionContext`.
- Affected area discovery may be ambiguous → start with explicit registered workspace links and allow later refinement instead of parsing free-form Markdown headings as the only source of truth.
- A new schema can drift from repo-local workflow expectations → keep artifact IDs plain and make status/instructions carry the schema-specific paths.
- Skill instructions may lag behind CLI behavior → audit source workflow templates for hardcoded repo-local paths and replace them with the path-agnostic status/instructions pattern.
@@ -0,0 +1,78 @@
## Why
Once repos are visible and the agent has workspace context, the user should be able to plan a cross-repo change without creating repo-local artifacts before implementation starts.
The user goal is:
```text
Explore the product goal across repos.
Decide the scope.
Create one workspace-level proposal that identifies the affected areas.
```
Planning should be the commitment point. Repo visibility alone should remain lightweight.
## What Changes
Add workspace-level change planning:
- install and refresh OpenSpec agent skills from the workspace root so agents can operate from the planning home
- use the active global workflow profile to decide which workflow skills are installed in the workspace
- keep `--tools` focused on which agents receive those workspace-local skills
- add a workspace-specific planning schema for workspace changes
- create a workspace change from the coordination root
- capture the product goal once
- identify affected areas by registered workspace link name where applicable
- let the agent explore before committing to affected areas or delivery slices
- keep the workspace as the planning source of truth
- update workflow skill instructions to use CLI-reported artifact paths instead of hardcoded repo-local paths
This slice should avoid creating repo-local artifacts as a side effect of planning. Repo-local artifacts should not be created merely because a workspace change exists.
Workspace setup and update may write agent skill files into the workspace root, such as `.codex/skills/` or `.claude/skills/`, because those files make the workspace planning home usable by agents. That setup work must not write OpenSpec artifacts or agent skill files into linked repos or folders.
Interactive setup should ask which agents should get OpenSpec skills in the workspace, preselecting the preferred opener when that opener supports skills. Workspace update should let users refresh or change those installed agent skills later, including when run from inside the workspace.
Workspace setup and update should treat the global profile as the workflow selection source. For this slice, workspace setup and update are skills-only even when global delivery is `commands` or `both`; command generation for workspaces is deferred.
`openspec config profile` should remain global, but when it runs from inside an OpenSpec workspace and changes the global profile or delivery settings, it should offer to apply the new workflow selection to the current workspace by running `openspec workspace update`.
Workspace-local skill selection should be machine-local state: setup records which agents received skills, update refreshes that stored selection by default, and explicit `--tools` changes the stored selection. OpenSpec should detect when workspace-local skills drift from the current global profile and give clear update guidance.
Selected profile workflows that are not yet fully implemented for workspace-scoped changes should still be safe. Generated skills and CLI guidance must guard unsupported workspace actions instead of falling back to repo-local behavior or editing linked repos implicitly.
Workspace help, docs, and completions should make the distinction legible: `openspec update` remains repo/project sync, while `openspec workspace update` syncs workspace-local agent skills.
Planning dependency:
- Depends on `workspace-open-agent-context`.
## Capabilities
### New Capabilities
- `workspace-change-planning`: Creates and manages workspace-level proposals for cross-repo goals.
### Modified Capabilities
- `workspace-links`: Adds workspace setup/update behavior for workspace-local agent skill installation.
- `cli-config`: Makes `openspec config profile` aware of workspace roots and able to apply global profile changes to the current workspace.
- `change-creation`: Adds workspace-aware change creation semantics and affected area identification.
- `cli-artifact-workflow`: Enriches workflow status and instructions so agents can discover planning context and artifact paths without hardcoded repo-local assumptions.
- `artifact-graph`: Adds a built-in workspace planning schema for workspace-scoped changes.
- `schema-resolution`: Ensures workspace-scoped change creation and workflow commands can resolve the workspace planning schema.
- `openspec-conventions`: Defines the relationship between workspace-level planning and repo-local implementation work.
## Impact
- Workspace change creation.
- Workspace-specific planning schema and templates.
- Affected area metadata and validation.
- Workspace setup and update behavior for installing or refreshing agent skills in the workspace root.
- Global profile integration for workspace-local skill workflow selection.
- Workspace-aware `openspec config profile` apply prompt behavior.
- Workspace-local agent skill selection state and drift detection.
- Guarded workflow guidance for profile workflows whose workspace behavior is not implemented in this slice.
- Docs, help, and completions for workspace skill update behavior.
- Agent instructions for proposing cross-repo changes without hardcoded change paths.
- Tests that registered repos are visible before change creation and that creating a change does not imply repo-local artifact creation.
@@ -0,0 +1,36 @@
## ADDED Requirements
### Requirement: Workspace planning schema
The artifact graph SHALL provide a built-in workspace planning schema for workspace-scoped changes.
#### Scenario: Built-in workspace planning schema is available
- **WHEN** schemas are resolved from package built-ins
- **THEN** a schema named `workspace-planning` SHALL be available
- **AND** it SHALL describe the artifact structure for workspace-scoped planning
#### Scenario: Workspace planning schema artifacts
- **WHEN** the `workspace-planning` schema is loaded
- **THEN** it SHALL include the normal planning artifacts for a shared proposal, workspace-scoped specs, cross-area design, and coordination tasks
- **AND** it SHALL not require an additional area manifest outside those normal planning artifacts
#### Scenario: Workspace planning schema supports nested specs
- **WHEN** the `workspace-planning` schema defines its specs artifact
- **THEN** the specs artifact SHALL resolve workspace-scoped spec files under `specs/**/*.md`
- **AND** schema guidance SHALL describe `specs/<area-or-repo>/<capability>/spec.md` as the default convention for area-specific requirements
#### Scenario: Workspace planning schema templates
- **WHEN** artifact instructions are requested for the `workspace-planning` schema
- **THEN** the schema SHALL provide templates that guide agents to write workspace-level planning content
- **AND** those templates SHALL avoid instructing agents to create repo-local implementation artifacts
- **AND** specs instructions SHALL support organizing area-specific requirements under workspace-scoped `specs/` paths
#### Scenario: Workspace nested spec paths stay workspace-scoped
- **GIVEN** a workspace change has spec files under `specs/<area-or-repo>/<capability>/spec.md`
- **WHEN** OpenSpec reports status or artifact instructions for the workspace change
- **THEN** it SHALL preserve the concrete nested workspace spec paths
- **AND** it SHALL not treat those files as repo-local specs to sync or archive without an explicit affected-area implementation context
#### Scenario: Workspace planning apply readiness
- **WHEN** the `workspace-planning` schema defines apply readiness
- **THEN** it SHALL require coordination tasks before implementation begins
- **AND** the apply guidance SHALL direct agents to select an affected area before making implementation edits
@@ -0,0 +1,42 @@
## ADDED Requirements
### Requirement: Workspace-aware change creation
Change creation SHALL support both repo-local and workspace planning homes.
#### Scenario: Creating a change from a workspace root
- **GIVEN** the command runs from an OpenSpec workspace root
- **WHEN** the user creates a new change
- **THEN** OpenSpec SHALL create the change under the workspace planning path
- **AND** it SHALL not create the change under a linked repo's `openspec/changes/` directory
- **AND** it SHALL use the `workspace-planning` schema when no explicit schema is provided
#### Scenario: Creating a change from inside a workspace
- **GIVEN** the command runs from a subdirectory of an OpenSpec workspace planning home
- **WHEN** the user creates a new change
- **THEN** OpenSpec SHALL resolve the current workspace as the planning home
- **AND** it SHALL create the change under that workspace's planning path
- **AND** it SHALL use the `workspace-planning` schema when no explicit schema is provided
#### Scenario: Creating a change from inside a linked repo
- **GIVEN** a repo or folder is registered as a workspace link
- **AND** the command runs from inside that linked repo or folder rather than from the workspace planning home
- **WHEN** the user creates a new change without explicitly selecting a workspace
- **THEN** OpenSpec SHALL preserve repo-local change creation behavior for that location
- **AND** it SHALL not create a workspace-scoped change merely because the location is registered as a workspace link
#### Scenario: Preserving repo-local change creation
- **GIVEN** the command runs outside an OpenSpec workspace
- **WHEN** the user creates a new change in a repo-local OpenSpec project
- **THEN** OpenSpec SHALL continue to create the change under `openspec/changes/`
#### Scenario: Rejecting invalid workspace affected areas
- **GIVEN** a workspace change creation request includes affected area names
- **WHEN** one or more names are not registered workspace links
- **THEN** OpenSpec SHALL reject those invalid affected areas
- **AND** it SHALL list the valid workspace link names
#### Scenario: Creating without affected areas
- **GIVEN** the user is still exploring scope
- **WHEN** the user creates a workspace change without affected areas
- **THEN** OpenSpec SHALL create the workspace change
- **AND** it SHALL allow affected areas to be identified later
@@ -0,0 +1,100 @@
## ADDED Requirements
### Requirement: Status JSON provides planning context
The status command SHALL provide machine-readable planning context for repo-local and workspace changes.
#### Scenario: Reporting planning home
- **WHEN** a user runs `openspec status --change <id> --json`
- **THEN** the output SHALL identify whether the change is repo-local or workspace-scoped
- **AND** it SHALL include the planning home root and change root
#### Scenario: Reporting concrete artifact paths
- **WHEN** a user runs `openspec status --change <id> --json`
- **THEN** the output SHALL include concrete paths for existing artifacts
- **AND** agents SHALL be able to read those paths without assuming `openspec/changes/<id>/`
- **AND** workspace-scoped nested spec paths SHALL be reported without flattening the area or capability path
#### Scenario: Reporting workspace affected areas
- **GIVEN** the change is workspace-scoped
- **WHEN** a user runs `openspec status --change <id> --json`
- **THEN** the output SHALL include known affected areas
- **AND** it SHALL indicate when affected areas remain unresolved without requiring an additional area manifest artifact
#### Scenario: Reporting next steps
- **WHEN** a user runs `openspec status --change <id> --json`
- **THEN** the output SHALL include next step guidance for agents
- **AND** the guidance SHALL use plain action language
### Requirement: Status JSON action context
The status command SHALL expose action context that lets agents act without hardcoded filesystem assumptions.
#### Scenario: Planning action context
- **WHEN** a workspace change is still in planning
- **THEN** status JSON SHALL identify the planning artifacts agents may read or update
- **AND** it SHALL indicate that linked repos and folders are context for exploration
#### Scenario: Implementation action context
- **WHEN** a workspace change has a selected affected area for implementation
- **THEN** status JSON SHALL include the allowed edit root for that area
- **AND** it SHALL avoid authorizing edits outside that selected area
#### Scenario: Repo-local action context
- **GIVEN** the change is repo-local
- **WHEN** a user runs `openspec status --change <id> --json`
- **THEN** status JSON SHALL preserve existing artifact status behavior
- **AND** it SHALL report a repo-local planning home for agents that use action context
### Requirement: Instructions use resolved planning paths
Artifact and apply instructions SHALL use resolved planning paths rather than hardcoded repo-local change paths.
#### Scenario: Workspace artifact instructions
- **GIVEN** the change is workspace-scoped
- **WHEN** a user runs `openspec instructions <artifact> --change <id> --json`
- **THEN** instruction output SHALL point to the artifact path under the workspace change root
- **AND** it SHALL not instruct the agent to write under a linked repo unless an explicit implementation context allows it
#### Scenario: Repo-local artifact instructions
- **GIVEN** the change is repo-local
- **WHEN** a user runs `openspec instructions <artifact> --change <id> --json`
- **THEN** instruction output SHALL preserve existing repo-local paths
### Requirement: Workflow skills use CLI artifact context
Generated workflow skills SHALL use OpenSpec CLI output as the source of truth for artifact locations.
#### Scenario: Skills inspect status before artifact work
- **WHEN** a generated workflow skill needs to inspect or create artifacts for a change
- **THEN** it SHALL instruct the agent to run `openspec status --change <id> --json`
- **AND** it SHALL use returned planning context and artifact paths rather than assuming a repo-local change path
#### Scenario: Skills use instructions before writing artifacts
- **WHEN** a generated workflow skill is about to create or update an artifact
- **THEN** it SHALL instruct the agent to run `openspec instructions <artifact> --change <id> --json`
- **AND** it SHALL write to the resolved artifact path returned by the command
#### Scenario: Skills avoid hardcoded repo-local paths
- **WHEN** generated workflow skills describe artifact locations
- **THEN** they SHALL avoid hardcoded examples that require changes to live under `openspec/changes/<id>/`
- **AND** any examples SHALL defer to CLI-reported paths for repo-local and workspace-scoped changes
#### Scenario: Skills guard unsupported workspace workflows
- **GIVEN** a generated workflow skill is selected by the global profile
- **AND** the workflow does not yet have full workspace-scoped behavior in this slice
- **WHEN** the skill is used for a workspace-scoped change
- **THEN** it SHALL tell the agent that the workspace action is not supported yet
- **AND** it SHALL not instruct the agent to fall back to repo-local paths or edit linked repos without an explicit allowed edit root
### Requirement: Workspace schema instructions
Workflow commands SHALL use the workspace planning schema instructions for workspace-scoped changes that use that schema.
#### Scenario: Workspace planning artifact order
- **GIVEN** a workspace-scoped change uses schema `workspace-planning`
- **WHEN** a user runs `openspec status --change <id> --json`
- **THEN** the artifact list SHALL reflect the workspace planning schema
- **AND** it SHALL include the normal proposal, specs, design, and tasks artifacts
#### Scenario: Workspace specs instructions
- **GIVEN** a workspace-scoped change uses schema `workspace-planning`
- **WHEN** a user requests instructions for the specs artifact
- **THEN** instruction output SHALL guide the agent to organize area-specific requirements under workspace-scoped `specs/` paths
- **AND** it SHALL not require all affected areas to be finalized before planning can continue
- **AND** it SHALL not instruct the agent to create repo-local spec files while the change is still in workspace planning
@@ -0,0 +1,55 @@
## ADDED Requirements
### Requirement: Config profile applies to current workspace
The `openspec config profile` command SHALL remain global while offering an explicit workspace apply path when run from inside an OpenSpec workspace.
#### Scenario: Config profile run inside a workspace
- **GIVEN** the command runs from inside an OpenSpec workspace
- **WHEN** the user changes profile or delivery settings with interactive `openspec config profile`
- **THEN** OpenSpec SHALL save the global config changes
- **AND** it SHALL prompt: `Apply changes to this workspace now?`
#### Scenario: User confirms workspace apply
- **GIVEN** `openspec config profile` changed global profile or delivery settings inside a workspace
- **WHEN** the user confirms the workspace apply prompt
- **THEN** OpenSpec SHALL run `openspec workspace update` for the current workspace
- **AND** it SHALL not run repo-local `openspec update` unless the current planning home is repo-local
#### Scenario: User declines workspace apply
- **GIVEN** `openspec config profile` changed global profile or delivery settings inside a workspace
- **WHEN** the user declines the workspace apply prompt
- **THEN** OpenSpec SHALL explain that global config was updated
- **AND** it SHALL tell the user to run `openspec workspace update` later to apply the profile to workspace-local skills
- **AND** it SHALL not modify workspace skill files
#### Scenario: No-op inside workspace
- **GIVEN** the command runs from inside an OpenSpec workspace
- **WHEN** `openspec config profile` exits with no effective config changes
- **THEN** OpenSpec SHALL not prompt to apply changes
- **AND** it SHALL warn if workspace-local skills are out of sync with the current global profile
- **AND** the warning SHALL suggest `openspec workspace update`
#### Scenario: Core preset shortcut inside a workspace
- **GIVEN** the command runs from inside an OpenSpec workspace
- **WHEN** the user runs `openspec config profile core`
- **THEN** OpenSpec SHALL save the global config change without prompting to apply immediately
- **AND** it SHALL tell the user to run `openspec workspace update` to apply the profile to workspace-local skills
#### Scenario: Core preset shortcut inside a repo project
- **GIVEN** the command runs from inside a repo-local OpenSpec project
- **WHEN** the user runs `openspec config profile core`
- **THEN** OpenSpec SHALL preserve existing repo-local shortcut behavior
- **AND** it SHALL tell the user to run `openspec update` to apply the profile to project files
#### Scenario: Workspace planning home wins over linked repo project
- **GIVEN** the command runs in a path under a workspace planning home where a repo-local OpenSpec project could also be detected
- **WHEN** OpenSpec decides which apply prompt to show
- **THEN** the nearest current planning home SHALL determine whether to offer `openspec workspace update` or repo-local `openspec update`
- **AND** OpenSpec SHALL not apply profile changes to a linked repo when the current planning home is the workspace
#### Scenario: Linked repo keeps repo-local profile behavior
- **GIVEN** a repo-local OpenSpec project is registered as a workspace link
- **AND** the command runs from inside that linked repo rather than from the workspace planning home
- **WHEN** OpenSpec decides which apply prompt or guidance to show
- **THEN** OpenSpec SHALL preserve repo-local `openspec update` behavior for that repo
- **AND** it SHALL not offer `openspec workspace update` unless the workspace is explicitly selected
@@ -0,0 +1,21 @@
## ADDED Requirements
### Requirement: Repo update redirects from workspace planning homes
The repo-local `openspec update` command SHALL not silently treat a workspace planning home as a repo-local OpenSpec project.
#### Scenario: Running update from a workspace root
- **GIVEN** the command runs from an OpenSpec workspace root
- **WHEN** the user runs `openspec update`
- **THEN** OpenSpec SHALL not generate repo-local project files in the workspace root
- **AND** it SHALL tell the user to run `openspec workspace update`
#### Scenario: Running update from inside a workspace planning directory
- **GIVEN** the command runs from a subdirectory of an OpenSpec workspace planning home
- **WHEN** the user runs `openspec update`
- **THEN** OpenSpec SHALL not run repo-local update behavior
- **AND** it SHALL tell the user to run `openspec workspace update`
#### Scenario: Running update from a repo-local project
- **GIVEN** the command runs from inside a repo-local OpenSpec project
- **WHEN** the user runs `openspec update`
- **THEN** OpenSpec SHALL preserve existing repo-local update behavior
@@ -0,0 +1,32 @@
## ADDED Requirements
### Requirement: Workspace planning vocabulary
OpenSpec conventions SHALL distinguish workspace planning concepts using user-facing product language.
#### Scenario: Naming affected areas
- **WHEN** documentation or generated guidance refers to repos, folders, packages, services, apps, or docs sites touched by a workspace change
- **THEN** it SHALL call them affected areas
- **AND** it SHALL avoid using "target repo" or "repo slice" as the primary user-facing term
#### Scenario: Naming delivery slices
- **WHEN** documentation or generated guidance refers to delivery increments inside a larger change
- **THEN** it SHALL call them slices or phases only when delivery sequencing is the subject
- **AND** it SHALL not use slice as a synonym for repo, folder, or affected area
### Requirement: Workspace planning and implementation boundary
OpenSpec conventions SHALL distinguish workspace-level planning from repo-local implementation ownership.
#### Scenario: Workspace as shared planning home
- **WHEN** a change spans linked repos or folders
- **THEN** conventions SHALL describe the workspace as the shared planning home
- **AND** repo-local implementation homes SHALL retain ownership of their code and canonical behavior
#### Scenario: Avoiding materialization-first language
- **WHEN** documentation explains workspace change creation
- **THEN** it SHALL describe the user outcome in terms of shared planning and affected areas
- **AND** it SHALL avoid making users understand implementation terms such as materialization before they can plan
#### Scenario: Preserving familiar workflow verbs
- **WHEN** workspace guidance describes OpenSpec workflows
- **THEN** it SHALL keep the familiar verbs explore, propose, apply, verify, and archive
- **AND** it SHALL explain that workspace context changes paths, scope, and allowed edit roots rather than creating a separate workflow family
@@ -0,0 +1,25 @@
## ADDED Requirements
### Requirement: Workspace planning schema resolution
Schema resolution SHALL support the built-in workspace planning schema.
#### Scenario: Listing workspace planning schema
- **WHEN** a user runs `openspec schemas`
- **THEN** the output SHALL include `workspace-planning`
- **AND** it SHALL identify it as a package-provided schema unless overridden by a higher-precedence schema
#### Scenario: Resolving workspace planning schema by name
- **WHEN** a workflow command requests schema `workspace-planning`
- **THEN** schema resolution SHALL resolve it using the normal project, user, then package precedence order
#### Scenario: Workspace default schema for new changes
- **GIVEN** the command creates a change in a workspace planning home
- **AND** the user did not pass an explicit `--schema`
- **WHEN** OpenSpec resolves the schema for the new change
- **THEN** it SHALL use `workspace-planning` as the default schema
#### Scenario: Explicit schema override for workspace change
- **GIVEN** the command creates a change in a workspace planning home
- **WHEN** the user passes an explicit `--schema <name>`
- **THEN** OpenSpec SHALL use the explicitly requested schema
- **AND** it SHALL validate that schema using normal schema resolution
@@ -0,0 +1,67 @@
## ADDED Requirements
### Requirement: Workspace change planning home
OpenSpec SHALL support workspace-level changes whose shared plan lives in the workspace planning home.
#### Scenario: Creating a workspace change
- **GIVEN** the command runs from an OpenSpec workspace
- **WHEN** the user creates a change for workspace planning
- **THEN** OpenSpec SHALL create the change under the workspace planning path
- **AND** it SHALL treat the workspace as the planning home for that change
- **AND** it SHALL use the workspace planning schema when no explicit schema is provided
#### Scenario: Workspace planning artifact structure
- **GIVEN** a workspace change uses the workspace planning schema
- **WHEN** OpenSpec reports or creates planning artifacts for that change
- **THEN** it SHALL use workspace-level artifacts for proposal, specs, cross-area design, and coordination tasks
- **AND** those artifacts SHALL live under the workspace change root
- **AND** it SHALL not require an additional area manifest outside those normal planning artifacts
#### Scenario: Capturing the shared goal once
- **WHEN** a workspace change is proposed
- **THEN** OpenSpec SHALL capture the product goal at the workspace change level
- **AND** it SHALL avoid requiring separate repo-local proposals before the affected areas are understood
#### Scenario: Preserving linked repos during change creation
- **WHEN** OpenSpec creates a workspace-level change
- **THEN** it SHALL not create repo-local OpenSpec change directories inside linked repos or folders
- **AND** it SHALL not edit implementation files in linked repos or folders
### Requirement: Workspace affected areas
OpenSpec SHALL represent ownership or implementation boundaries in a workspace change as affected areas.
#### Scenario: Using registered workspace links as areas
- **GIVEN** a workspace has linked repos or folders
- **WHEN** a workspace change identifies affected areas by registered link name
- **THEN** OpenSpec SHALL validate those area names against the workspace links
- **AND** it SHALL report invalid area names clearly
#### Scenario: Planning before all areas are known
- **WHEN** a user is still exploring a workspace change
- **THEN** OpenSpec SHALL allow the shared plan to exist before all affected areas are finalized
- **AND** it SHALL keep unresolved affected area questions visible in the normal planning artifacts and status output
#### Scenario: Organizing requirements by area
- **GIVEN** a workspace change has requirements owned by one or more affected areas
- **WHEN** OpenSpec reports or creates workspace-scoped specs
- **THEN** it SHALL allow area-specific requirements to be organized under `specs/<area-or-repo>/<capability>/spec.md`
- **AND** it SHALL not require separate area folders outside the normal `specs/` artifact tree
- **AND** it SHALL preserve the area-or-repo path segment as workspace planning context rather than flattening it into a repo-local capability name
#### Scenario: Separating areas from delivery slices
- **WHEN** a workspace change reports affected areas
- **THEN** OpenSpec SHALL distinguish affected areas from delivery slices or phases
- **AND** it SHALL not require users to define delivery slices for a small cross-area change
### Requirement: Workspace planning source of truth
OpenSpec SHALL keep the workspace change plan as the source of truth until implementation begins for a selected affected area.
#### Scenario: Exploring before implementation
- **WHEN** an agent explores a workspace change
- **THEN** it SHALL use workspace-level planning artifacts as the shared planning source
- **AND** it SHALL treat linked repos and folders as available context rather than committed implementation targets
#### Scenario: Deferring repo-local implementation
- **WHEN** repo-local implementation work is needed for a workspace change
- **THEN** OpenSpec SHALL require an explicit implementation workflow with a selected affected area
- **AND** it SHALL expose the allowed edit root for that selected area before implementation edits begin
@@ -0,0 +1,163 @@
## ADDED Requirements
### Requirement: Workspace setup installs agent skills
OpenSpec SHALL let users install OpenSpec agent skills into a workspace during workspace setup.
#### Scenario: Prompting for workspace agent skills
- **WHEN** interactive workspace setup reaches agent skill installation
- **THEN** OpenSpec SHALL ask which agents should get OpenSpec skills in this workspace
- **AND** the prompt SHALL use agent-skill language rather than "AI tools" language
#### Scenario: Preselecting the preferred opener
- **GIVEN** the user selected a preferred opener that supports OpenSpec skill generation
- **WHEN** interactive workspace setup asks which agents should get skills
- **THEN** OpenSpec SHALL preselect the matching agent
- **AND** the user SHALL be able to select additional agents or deselect the preselected agent
#### Scenario: Installing selected workspace skills
- **WHEN** workspace setup completes with one or more selected agents
- **THEN** OpenSpec SHALL generate or refresh OpenSpec skill files under the workspace root for each selected agent
- **AND** it SHALL report which agents received skills
- **AND** it SHALL store the selected agents in workspace-local machine state
#### Scenario: Installing profile-selected workflows
- **GIVEN** global config resolves to a workflow profile
- **WHEN** workspace setup installs agent skills
- **THEN** OpenSpec SHALL install workspace-local skills for the workflows selected by that profile
- **AND** it SHALL treat `--tools` as agent selection, not workflow selection
- **AND** it SHALL record the last applied workflow IDs for drift detection
#### Scenario: Installing skills only during setup
- **WHEN** workspace setup installs agent skills
- **THEN** OpenSpec SHALL generate skill files only
- **AND** it SHALL not generate slash command files or global command files as part of workspace setup
#### Scenario: Ignoring command delivery for workspace setup
- **GIVEN** global config delivery is `commands` or `both`
- **WHEN** workspace setup installs agent skills
- **THEN** OpenSpec SHALL still generate workspace-local skills only
- **AND** it SHALL report that workspace command generation is not part of this slice
#### Scenario: Preserving linked repos during skill installation
- **WHEN** workspace setup installs agent skills
- **THEN** OpenSpec SHALL leave linked repos and folders unchanged
- **AND** generated skills SHALL be scoped to the workspace planning home
#### Scenario: Non-interactive setup tool selection
- **WHEN** non-interactive workspace setup receives `--tools all`, `--tools none`, or `--tools <ids>`
- **THEN** OpenSpec SHALL use the selected tool set for workspace agent skill installation
- **AND** it SHALL validate tool IDs using the same supported tool IDs as skill generation for repo initialization
#### Scenario: Non-interactive setup without tool selection
- **WHEN** non-interactive workspace setup omits `--tools`
- **THEN** OpenSpec SHALL create the workspace without installing agent skills
- **AND** it SHALL report that no workspace skills were installed
- **AND** it SHALL tell the user to run `openspec workspace update --tools <ids>` to install skills later
#### Scenario: Reporting setup skills in JSON output
- **WHEN** non-interactive workspace setup installs agent skills with JSON output enabled
- **THEN** OpenSpec SHALL include generated, refreshed, skipped, or failed skill installation results in machine-readable output
### Requirement: Workspace update manages agent skills
OpenSpec SHALL provide a workspace update flow for refreshing agent skills after setup.
#### Scenario: Updating the current workspace
- **GIVEN** the command runs from inside an OpenSpec workspace
- **WHEN** the user runs `openspec workspace update`
- **THEN** OpenSpec SHALL update that current workspace
#### Scenario: Updating a named workspace
- **GIVEN** a workspace named `platform` is known locally
- **WHEN** the user runs `openspec workspace update platform`
- **THEN** OpenSpec SHALL update the `platform` workspace
#### Scenario: Updating a workspace selected by flag
- **GIVEN** a workspace named `platform` is known locally
- **WHEN** the user runs `openspec workspace update --workspace platform`
- **THEN** OpenSpec SHALL update the `platform` workspace
#### Scenario: Updating selected workspace skills
- **WHEN** workspace update completes with selected agents
- **THEN** OpenSpec SHALL refresh OpenSpec skills for selected agents
- **AND** it SHALL add skills for newly selected agents
- **AND** it SHALL remove OpenSpec-managed workflow skill directories for agents that are no longer selected
- **AND** it SHALL update the stored workspace-local selected agent list
#### Scenario: Updating profile-selected workflows
- **GIVEN** global config resolves to a workflow profile
- **WHEN** workspace update refreshes workspace-local skills
- **THEN** OpenSpec SHALL sync the workspace-local skill workflow set to the workflows selected by that profile
- **AND** deselected workflow skill directories SHALL be removed only when they are known OpenSpec-managed workflow skill directories
- **AND** it SHALL update the last applied workflow IDs used for drift detection
#### Scenario: Ignoring command delivery for workspace update
- **GIVEN** global config delivery is `commands` or `both`
- **WHEN** workspace update refreshes workspace-local skills
- **THEN** OpenSpec SHALL still update workspace-local skills only
- **AND** it SHALL not generate slash command files or global command files
#### Scenario: Removing only managed skill directories
- **WHEN** workspace update removes skills for an unselected agent
- **THEN** OpenSpec SHALL remove only known OpenSpec-managed workflow skill directories
- **AND** it SHALL preserve unrelated files in the agent directory
#### Scenario: Updating stored agent selection by flag
- **WHEN** workspace update receives `--tools <ids>` or `--tools none`
- **THEN** OpenSpec SHALL replace the stored workspace-local selected agent list with that selection
- **AND** future workspace updates without `--tools` SHALL use the stored selection
#### Scenario: Non-interactive update tool selection
- **WHEN** workspace update receives `--tools all`, `--tools none`, or `--tools <ids>`
- **THEN** OpenSpec SHALL update workspace agent skills using that selected tool set
- **AND** it SHALL avoid prompting for agent selection
#### Scenario: Non-interactive update without tool selection
- **GIVEN** workspace-local selected agents are stored
- **WHEN** non-interactive workspace update omits `--tools`
- **THEN** OpenSpec SHALL refresh the stored selected agents using the active global profile
- **AND** it SHALL avoid prompting for agent selection
#### Scenario: Non-interactive update without stored selection
- **GIVEN** no workspace-local selected agents are stored
- **WHEN** non-interactive workspace update omits `--tools`
- **THEN** OpenSpec SHALL complete without installing agent skills
- **AND** it SHALL report a no-op with guidance to pass `--tools`
#### Scenario: Reporting workspace skill drift
- **GIVEN** workspace-local skill state records last applied workflow IDs
- **AND** the active global profile resolves to a different workflow set
- **WHEN** OpenSpec reports workspace skill state
- **THEN** it SHALL report that workspace-local skills are out of sync with the global profile
- **AND** it SHALL suggest `openspec workspace update`
#### Scenario: Reporting clean workspace skill sync
- **GIVEN** workspace-local skill state matches the active global profile and selected agents
- **WHEN** OpenSpec reports workspace skill state
- **THEN** it SHALL not report profile drift
#### Scenario: Reporting workspace skill update results
- **WHEN** workspace update changes agent skill state
- **THEN** OpenSpec SHALL report which agents were refreshed, added, removed, skipped, or failed
#### Scenario: Reporting workspace update results in JSON output
- **WHEN** workspace update runs with JSON output enabled
- **THEN** OpenSpec SHALL include refreshed, added, removed, skipped, or failed skill results in machine-readable output
### Requirement: Workspace skill update surface is documented
OpenSpec SHALL expose workspace skill setup/update behavior in user-facing command surfaces.
#### Scenario: Workspace update appears in help
- **WHEN** a user runs `openspec workspace --help`
- **THEN** OpenSpec SHALL list `workspace update`
- **AND** it SHALL describe it as refreshing workspace-local agent skills
#### Scenario: Workspace update options appear in help
- **WHEN** a user runs `openspec workspace update --help`
- **THEN** OpenSpec SHALL document workspace selection options
- **AND** it SHALL document `--tools all|none|<ids>`
- **AND** it SHALL state that global profile selects workflows and `--tools` selects agents
#### Scenario: Workspace update appears in completions
- **WHEN** shell completions are generated
- **THEN** the workspace command registry SHALL include `workspace update`
- **AND** it SHALL include relevant options such as `--workspace`, `--tools`, `--json`, and `--no-interactive`
@@ -0,0 +1,133 @@
## Phase 1: Workspace Setup Skills
User-testable outcome: A user can run workspace setup, choose which agents get the active profile's OpenSpec skills, and verify the selected skills are generated in the workspace root only.
- [x] 1.1 Add an interactive workspace setup step named "Install agent skills" that asks which agents should get OpenSpec skills in this workspace.
- [x] 1.2 Preselect the preferred opener when that opener supports skills, while allowing users to choose different or additional agents.
- [x] 1.3 Support non-interactive agent selection with the existing `--tools all|none|<ids>` style.
- [x] 1.4 Validate workspace setup tool IDs using the same supported skill-generation tool set as repo initialization.
- [x] 1.5 Resolve the active global profile and use it to choose which workflow skills workspace setup installs.
- [x] 1.6 Ensure `openspec workspace setup` generates or refreshes OpenSpec agent skills in the workspace root for the selected agents.
- [x] 1.7 Keep setup-time skill generation scoped to the workspace planning home; do not write skills or OpenSpec artifacts into linked repos or folders during workspace setup.
- [x] 1.8 Keep workspace setup skill generation skills-only for this slice; do not generate slash commands or global command files even when global delivery includes commands.
- [x] 1.9 Define how setup reports generated, refreshed, skipped, failed, and skills-only delivery work in human and JSON output.
- [x] 1.10 Store the selected workspace skill agents and last-applied workflow IDs in workspace-local machine state.
- [x] 1.11 Preserve non-interactive setup compatibility when `--tools` is omitted by skipping skill installation with clear guidance.
- [x] 1.12 Manually run workspace setup in interactive and non-interactive modes and verify the selected profile workflows land only in the workspace root.
- [x] 1.13 Review the setup UX: prompt wording, defaults, skip path, profile/delivery messaging, success output, and JSON output are clear before moving on.
## Phase 2: Workspace Skill Updates
User-testable outcome: A user can change the global profile, run workspace update in an existing workspace, and see workspace-local skills refresh to the selected workflows with clear human and JSON output.
- [x] 2.1 Add a workspace update flow that refreshes, adds, or removes OpenSpec agent skills in an existing workspace.
- [x] 2.2 Let `openspec workspace update` resolve the current workspace when run from inside a workspace.
- [x] 2.3 Support named and selected-workspace update forms such as `openspec workspace update platform` and `openspec workspace update --workspace platform`.
- [x] 2.4 Support non-interactive update forms such as `openspec workspace update platform --tools codex,claude`.
- [x] 2.5 Remove only known OpenSpec-managed workflow skill directories for agents that are no longer selected.
- [x] 2.6 Sync workspace-local workflow skill directories to the current global profile selection.
- [x] 2.7 Keep workspace update skills-only for this slice; do not generate slash commands or global command files even when global delivery includes commands.
- [x] 2.8 Define how update reports refreshed, added, removed, skipped, failed, and skills-only delivery work in human and JSON output.
- [x] 2.9 Use stored selected agents when workspace update runs without `--tools`, and update that stored selection when `--tools` is passed.
- [x] 2.10 Detect workspace-local skill drift from the active global profile and report `openspec workspace update` guidance.
- [x] 2.11 Manually run workspace update for refresh, add, remove, no-op, omitted-`--tools`, and profile-change cases and verify linked repos remain unchanged.
- [x] 2.12 Review the update UX: command forms, current-workspace detection, profile/delivery messaging, drift messaging, removal messaging, and JSON output are understandable.
## Phase 3: Config Profile Workspace Apply
User-testable outcome: A user can run `openspec config profile` inside a workspace and choose whether to apply the changed global profile to that workspace now.
- [x] 3.1 Detect when `openspec config profile` runs from inside an OpenSpec workspace.
- [x] 3.2 After an actual profile or delivery change inside a workspace, prompt to apply changes to the current workspace now.
- [x] 3.3 When confirmed, run `openspec workspace update` for the current workspace instead of repo-local `openspec update`.
- [x] 3.4 When declined, report that global config changed and that `openspec workspace update` applies it later.
- [x] 3.5 Preserve existing repo-local `openspec config profile` apply behavior outside workspaces.
- [x] 3.6 Keep `openspec config profile core` non-interactive, but print workspace-specific `openspec workspace update` guidance when run inside a workspace.
- [x] 3.7 Warn on no-op config profile inside a workspace when workspace-local skills drift from the active global profile.
- [x] 3.8 Manually run `openspec config profile` inside a workspace for confirm, decline, no-op, drift-warning, and `core` preset paths.
- [x] 3.9 Review the config-profile UX: prompt wording, project/workspace distinction, no-op behavior, preset guidance, and follow-up guidance are clear.
## Phase 4: Workspace Change Creation
User-testable outcome: A user can create a workspace-level change from the coordination root, inspect its workspace planning artifacts, and confirm linked repos were not edited.
- [x] 4.1 Add a built-in `workspace-planning` schema and templates that keep the normal proposal/specs/design/tasks artifact shape.
- [x] 4.2 Define the workspace-planning specs artifact with nested `specs/**/*.md` output support and instructions for `specs/<area-or-repo>/<capability>/spec.md`.
- [x] 4.3 Add workspace-aware change creation from the workspace coordination root.
- [x] 4.4 Default workspace-scoped change creation to the `workspace-planning` schema.
- [x] 4.5 Store workspace-level changes under the workspace planning path rather than under linked repos or folders.
- [x] 4.6 Capture the product goal once at the workspace change level.
- [x] 4.7 Record or validate affected area names through workspace-scoped specs or task sections using registered workspace link names where applicable.
- [x] 4.8 Ensure creating a workspace change does not create repo-local OpenSpec artifacts or edit linked repos.
- [x] 4.9 Preserve repo-local change creation behavior outside workspaces.
- [x] 4.10 Manually create a workspace change from a coordination root and verify the generated artifacts, workspace-scoped specs/tasks, affected areas, and untouched linked repos.
- [x] 4.11 Review the change creation UX: goal capture, affected-area identification, artifact paths, and next-step guidance feel clear.
## Phase 5: Planning Home And Agent Context
User-testable outcome: A user can run status and instructions for repo-local and workspace changes and see the resolved planning home, artifact paths, affected areas, constraints, and next steps.
- [x] 5.1 Introduce a shared planning-home resolver that identifies repo-local versus workspace planning homes.
- [x] 5.2 Enrich `openspec status --change <id> --json` with planning home, change root, relevant artifact paths, affected areas, next steps, and action context.
- [x] 5.3 Enrich `openspec instructions <artifact> --change <id> --json` with resolved artifact paths for repo-local and workspace-scoped changes.
- [x] 5.4 Keep workspace-level planning as the source of truth until an explicit implementation workflow selects an affected area.
- [x] 5.5 Preserve nested workspace spec paths in status and instructions output without flattening them into repo-local capability paths.
- [x] 5.6 Manually run status and instructions for both repo-local and workspace-scoped changes and verify paths and action context are correct.
- [x] 5.7 Review the planning-context UX: human output, JSON field names, and next-step guidance are easy for users and agents to follow.
## Phase 6: Workflow Skill Instructions
User-testable outcome: A user can inspect regenerated workflow skills and verify they are path-agnostic and tell agents to use CLI-reported artifact paths.
- [x] 6.1 Update generated workflow skill templates to run `openspec status --change <id> --json` before artifact work and trust returned planning context.
- [x] 6.2 Update generated workflow skill templates to run `openspec instructions <artifact> --change <id> --json` before writing artifacts and use the resolved output path.
- [x] 6.3 Audit source workflow templates for hardcoded `openspec/changes/<name>` assumptions and replace them with CLI-reported path guidance.
- [x] 6.4 Keep a separate artifact-context command out of this slice unless enriched status/instructions prove insufficient during implementation.
- [x] 6.5 Manually regenerate or inspect installed workflow skills and verify they follow CLI-reported artifact paths in a workspace change.
- [x] 6.6 Guard profile-selected workflow skills whose workspace behavior is not implemented yet so they do not fall back to repo-local paths or edit linked repos.
- [x] 6.7 Review the agent-instruction UX: instructions are concise, path-agnostic, safe for unsupported workspace workflows, and practical for both repo-local and workspace planning.
## Phase 7: Verification
User-testable outcome: A user or reviewer can run the full manual checklist from a clean workspace and compare expected versus actual evidence for every earlier phase.
- [x] 7.1 Add tests that workspace setup installs skills in the workspace root and leaves linked repos unchanged.
- [x] 7.2 Add tests that workspace update refreshes, adds, and removes only managed workspace skill directories.
- [x] 7.3 Add tests that workspace setup/update use the current global profile for workflow skill selection while keeping workspace delivery skills-only.
- [x] 7.4 Add tests that `openspec config profile` inside a workspace can apply changes through `openspec workspace update`.
- [x] 7.5 Add tests for stored workspace skill agent selection, omitted-`--tools` behavior, and profile drift reporting.
- [x] 7.6 Add tests that `openspec update` from a workspace planning home redirects to `openspec workspace update`.
- [x] 7.7 Add tests that unsupported workspace workflow skills are guarded and do not instruct repo-local fallback edits.
- [x] 7.8 Add tests that registered repos are visible before change creation.
- [x] 7.9 Add tests that workspace change creation does not imply repo-local artifact creation.
- [x] 7.10 Add tests that the workspace-planning schema resolves nested `specs/<area-or-repo>/<capability>/spec.md` files as workspace-scoped specs.
- [x] 7.11 Add cross-platform path tests for workspace-root skill paths and workspace change paths.
- [x] 7.12 Update CLI docs, command help, and shell completion coverage for `workspace update`, `--tools`, profile behavior, and workspace skills-only delivery.
- [x] 7.13 Run `openspec validate workspace-change-planning --strict`.
- [x] 7.14 Run the full manual acceptance checklist across setup, update, config profile, change creation, planning context, and workflow skills before marking the change complete.
- [x] 7.15 Complete a final UX review across the whole workflow and record any follow-up fixes or intentional deferrals.
- [x] 7.16 Before implementation sign-off, record the manual commands or interaction paths, expected observations, and actual observations for each phase.
- [x] 7.17 Have a separate reviewer or fresh agent context rerun the manual acceptance and UX checklist when available; otherwise rerun it from a clean temporary workspace and report the evidence.
## Verification Evidence
Completion evidence was recorded on 2026-05-14.
Automated checks:
```bash
pnpm run build
pnpm vitest run test/commands/workspace.test.ts test/commands/artifact-workflow.test.ts test/core/workspace/skills.test.ts test/core/planning-home.test.ts test/core/templates/skill-templates-parity.test.ts
node dist/cli/index.js validate workspace-change-planning --strict
git diff --check
```
Clean workspace rerun covered non-interactive workspace setup, workspace doctor, config profile update guidance, workspace update redirection, workspace change creation with `--areas api,web`, status/instructions JSON for nested workspace specs, linked repo cleanliness, and guarded unsupported workflow skills.
Observed results:
- Build, targeted tests, strict validation, and whitespace checks passed.
- Workspace setup/update generated skills only in the workspace root and left linked repos untouched.
- Workspace change creation used schema `workspace-planning`, reported affected areas `api` and `web`, preserved nested `specs/api/login/spec.md`, and kept `actionContext.allowedEditRoots` empty during planning.
- Generated workflow skills used CLI-reported paths and workspace guards rather than hardcoded `openspec/changes/<name>` paths.
- Fresh-agent rerun was not available; the clean temporary workspace rerun served as the fallback independent acceptance pass.
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-25
@@ -0,0 +1,48 @@
## 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.
@@ -0,0 +1,26 @@
## 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
@@ -0,0 +1,63 @@
## 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)
@@ -0,0 +1,19 @@
## 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
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-25
@@ -0,0 +1,38 @@
## 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.
@@ -0,0 +1,25 @@
## 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
@@ -0,0 +1,27 @@
## 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)
@@ -0,0 +1,16 @@
## 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
@@ -160,15 +160,14 @@ The update command SHALL only run inside an initialized OpenSpec project.
- **THEN** the system SHALL display: "No OpenSpec project found. Run 'openspec init' to set up."
- **THEN** the system SHALL exit with code 1
### Requirement: Extra workflows preserved
The update command SHALL NOT remove workflow files that aren't in the current profile.
### Requirement: Extra workflows synchronized to active profile
The update command SHALL remove workflow files that are no longer selected in the current profile.
#### Scenario: Extra workflows from previous profile
#### Scenario: Deselected workflows from previous profile
- **WHEN** user runs `openspec update`
- **AND** project has workflows not in current profile (e.g., user switched from custom to core)
- **THEN** the system SHALL NOT delete those extra workflow files
- **THEN** the system SHALL only add/update workflows in the current profile
- **THEN** the system SHALL display a note: "Note: <count> extra workflows not in profile (use `openspec config profile` to manage)"
- **AND** project has workflows not in current profile (e.g., user switched from custom to core or deselected workflows via `openspec config profile`)
- **THEN** the system SHALL delete skill and command workflow files for deselected workflows (respecting active delivery mode)
- **THEN** the system SHALL keep only workflows currently selected in profile
#### Scenario: Delivery change with extra workflows
- **WHEN** user runs `openspec update`
@@ -15,21 +15,19 @@ The design goal is to preserve current behavior while making extension points ex
- Define one canonical source for workflow content and metadata
- Make tool/agent-specific behavior explicit and centrally discoverable
- Keep command adapters as the formatting boundary for tool syntax differences
- Represent tool-specific command surfaces and terminology explicitly (not as scattered string rewrites)
- Consolidate artifact generation/write orchestration into one reusable engine
- Improve correctness with enforceable validation and parity tests
**Non-Goals:**
- Redesigning command semantics or workflow instruction content
- Changing user-facing CLI command names/flags in this proposal
- Guaranteeing fully accurate literal slash-command strings for every supported tool on day one
- Merging unrelated legacy cleanup behavior beyond artifact generation reuse
## Decisions
### 1. Canonical `WorkflowManifest`
**Decision**: Represent each workflow once in a manifest entry containing canonical skill and command definitions plus metadata defaults. Canonical text uses semantic tokens for tool-specific references.
**Decision**: Represent each workflow once in a manifest entry containing canonical skill and command definitions plus metadata defaults.
Suggested shape:
@@ -43,12 +41,6 @@ interface WorkflowManifestEntry {
tags: string[];
compatibility: string;
}
// Examples in canonical workflow text:
// - {{cmd.apply}}
// - {{cmd.continue.withArg}}
// - {{term.change}}
// - {{term.workflow}}
```
**Rationale**:
@@ -58,7 +50,7 @@ interface WorkflowManifestEntry {
### 2. `ToolProfileRegistry` for capability wiring
**Decision**: Add a tool profile layer that maps tool IDs to generation capabilities, command-surface rendering, and terminology.
**Decision**: Add a tool profile layer that maps tool IDs to generation capabilities and behavior.
Suggested shape:
@@ -67,16 +59,6 @@ interface ToolProfile {
toolId: string;
skillsDir?: string;
commandAdapterId?: string;
commandSurface: {
pattern: 'opsx-colon' | 'opsx-hyphen' | 'opsx-slash' | 'openspec-hyphen' | 'custom';
verified: boolean;
aliases?: string[];
};
terminology: {
change: string;
workflow: string;
command: string;
};
transforms: string[];
}
```
@@ -85,12 +67,10 @@ interface ToolProfile {
- Prevents capability drift between `AI_TOOLS`, adapter registry, and detection logic
- Allows intentional "skills-only" tools without implicit special casing
- Provides one place to answer "what does this tool support?"
- Makes command rendering decisions explicit and testable
- Supports future terminology tailoring without copy/paste template forks
### 3. First-class transform pipeline
**Decision**: Model transforms as ordered plugins with scope + phase + applicability. Include token rendering in the transform pipeline instead of hardcoding literal command strings in templates.
**Decision**: Model transforms as ordered plugins with scope + phase + applicability.
Suggested shape:
@@ -107,32 +87,17 @@ interface ArtifactTransform {
Execution order:
1. Render canonical content from manifest
2. Apply token-render transform (`{{cmd.*}}`, `{{term.*}}`) using tool profile
3. Apply matching `preAdapter` transforms
4. For commands, run adapter formatting
5. Apply matching `postAdapter` transforms
6. Validate and write
2. Apply matching `preAdapter` transforms
3. For commands, run adapter formatting
4. Apply matching `postAdapter` transforms
5. Validate and write
**Rationale**:
- Keeps adapters focused on tool formatting, not scattered behavioral rewrites
- Makes agent-specific modifications explicit and testable
- Replaces ad-hoc transform calls in `init`/`update`
- Enables neutral fallback rendering when a tool profile is not verified for literal command syntax
### 4. Fallback policy for unverified command surfaces
**Decision**: When a tool profile has `commandSurface.verified === false`, command tokens SHALL render to neutral workflow guidance instead of literal slash-command strings.
Examples:
- Literal (verified): `Run {{cmd.apply}}`
- Neutral (unverified): `Run the Apply workflow` or `use the apply skill`
**Rationale**:
- Prevents confidently wrong guidance in generated artifacts
- Allows incremental tool-surface verification without blocking rollout
- Keeps templates stable while rendering policy evolves
### 5. Shared `ArtifactSyncEngine`
### 4. Shared `ArtifactSyncEngine`
**Decision**: Introduce a single orchestration engine used by all generation entry points.
@@ -147,15 +112,13 @@ Responsibilities:
- Enables dry-run and future preview features without re-implementing logic
- Improves reliability of updates and legacy migrations
### 6. Validation + parity guardrails
### 5. Validation + parity guardrails
**Decision**: Add strict checks in tests (and optional runtime assertions in dev builds) for:
- Required skill metadata fields (`license`, `compatibility`, `metadata`) present for all manifest entries
- Projection consistency (skills, commands, detection names derived from manifest)
- Tool profile consistency (adapter existence, expected capabilities)
- Token coverage checks (no unresolved `{{...}}` tokens in rendered outputs)
- Tool command-surface verification matrix and fallback expectations
- Golden/parity output for key workflows/tools
**Rationale**:
@@ -180,8 +143,7 @@ Adding manifest/profile/transform registries increases conceptual surface area.
## Implementation Approach
1. Build manifest + profile + transform types and registries behind current public API
2. Tokenize command/terminology references in workflow templates
3. Rewire `getSkillTemplates`/`getCommandContents` to derive from manifest
4. Introduce `ArtifactSyncEngine` and switch `init` to use it with parity checks
5. Switch `update` and legacy upgrade flows to same engine
6. Remove duplicate/hardcoded lists after parity is green
2. Rewire `getSkillTemplates`/`getCommandContents` to derive from manifest
3. Introduce `ArtifactSyncEngine` and switch `init` to use it with parity checks
4. Switch `update` and legacy upgrade flows to same engine
5. Remove duplicate/hardcoded lists after parity is green
@@ -4,8 +4,7 @@ The recent split of `skill-templates.ts` into workflow modules improved readabil
- Workflow definitions are split from projection logic (`getSkillTemplates`, `getCommandTemplates`, `getCommandContents`)
- Tool capability and compatibility are spread across `AI_TOOLS`, `CommandAdapterRegistry`, and hardcoded lists like `SKILL_NAMES`
- Agent/tool-specific transformations are applied in different places (`init`, `update`, and adapter code)
- Command and terminology references are currently hardcoded in workflow text, but tool invocation surfaces vary (`/opsx:apply`, `/opsx-apply`, `/opsx/apply`, and tool-specific naming)
- Agent/tool-specific transformations (for example OpenCode command reference rewrites) are applied in different places (`init`, `update`, and adapter code)
- Artifact writing logic is duplicated across `init`, `update`, and legacy-upgrade flow
This fragmentation creates drift risk (missing exports, missing metadata parity, mismatched counts/support) and makes future workflow/tool additions slower and less predictable.
@@ -16,16 +15,13 @@ This fragmentation creates drift risk (missing exports, missing metadata parity,
- Introduce a `ToolProfileRegistry` to centralize tool capabilities (skills path, command adapter, transforms)
- Introduce a first-class transform pipeline with explicit phases (`preAdapter`, `postAdapter`) and scopes (`skill`, `command`, `both`)
- Introduce a shared `ArtifactSyncEngine` used by `init`, `update`, and legacy upgrade paths
- Add tokenized workflow text rendering so command references and tool terminology are resolved per tool profile at generation time
- Add explicit command-surface profiles per tool (pattern, namespace/path style, alias support, verification status)
- Add safe fallback behavior: when a tool command surface is not verified, render neutral workflow guidance (for example skill/workflow names) instead of potentially wrong literal command strings
- Add strict validation and test guardrails to preserve fidelity during migration and future changes
## Capabilities
### New Capabilities
- `template-artifact-pipeline`: Unified workflow manifest, tool profile registry, token-aware transform pipeline, and sync engine for skill/command generation
- `template-artifact-pipeline`: Unified workflow manifest, tool profile registry, transform pipeline, and sync engine for skill/command generation
### Modified Capabilities
@@ -45,9 +41,7 @@ This fragmentation creates drift risk (missing exports, missing metadata parity,
- **Testing additions**:
- Manifest completeness tests (workflows, required metadata, projection parity)
- Transform ordering and applicability tests
- Tool command-surface/terminology profile validation tests
- End-to-end parity tests for generated skill/command outputs across tools
- **User-facing behavior**:
- No new CLI surface area required
- Generated text may become more tool-accurate for verified tool profiles
- Generated text may intentionally use neutral workflow wording for unverified tools to avoid incorrect slash-command guidance
- Existing generated artifacts remain behaviorally equivalent unless explicitly changed in future deltas
@@ -10,18 +10,14 @@
- [ ] 2.1 Add `ToolProfile` types and `ToolProfileRegistry`
- [ ] 2.2 Map all currently supported tools to explicit profile entries
- [ ] 2.3 Wire profile lookups to command adapter resolution and skills path resolution
- [ ] 2.4 Add per-tool `commandSurface` metadata (pattern, aliases, `verified` flag)
- [ ] 2.5 Add per-tool terminology metadata (for example change/workflow/command labels)
- [ ] 2.6 Replace hardcoded detection arrays (for example `SKILL_NAMES`) with manifest-derived values
- [ ] 2.4 Replace hardcoded detection arrays (for example `SKILL_NAMES`) with manifest-derived values
## 3. Transform Pipeline
- [ ] 3.1 Introduce transform interfaces (`scope`, `phase`, `priority`, `applies`, `transform`)
- [ ] 3.2 Implement transform runner with deterministic ordering
- [ ] 3.3 Add token renderer transform for command + terminology tokens (`{{cmd.*}}`, `{{term.*}}`)
- [ ] 3.4 Implement neutral fallback rendering for tools with unverified command surfaces
- [ ] 3.5 Migrate OpenCode command reference rewrite to transform pipeline
- [ ] 3.6 Remove ad-hoc transform invocation from `init` and `update`
- [ ] 3.3 Migrate OpenCode command reference rewrite to transform pipeline
- [ ] 3.4 Remove ad-hoc transform invocation from `init` and `update`
## 4. Artifact Sync Engine
@@ -33,12 +29,10 @@
## 5. Validation and Tests
- [ ] 5.1 Add manifest completeness tests (metadata required fields, command IDs, dir names)
- [ ] 5.2 Add tool-profile consistency tests (skillsDir support, adapter/profile alignment, command-surface metadata)
- [ ] 5.3 Add token rendering tests (all tokens resolved, per-tool rendering correctness)
- [ ] 5.4 Add fallback tests for unverified tool command surfaces
- [ ] 5.5 Add transform applicability/order tests
- [ ] 5.6 Expand parity tests for representative workflow/tool matrix
- [ ] 5.7 Run full test suite and verify generated artifacts remain stable
- [ ] 5.2 Add tool-profile consistency tests (skillsDir support and adapter/profile alignment)
- [ ] 5.3 Add transform applicability/order tests
- [ ] 5.4 Expand parity tests for representative workflow/tool matrix
- [ ] 5.5 Run full test suite and verify generated artifacts remain stable
## 6. Cleanup and Documentation
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-05-14
@@ -0,0 +1,100 @@
## Why
Status: deferred by the context-store-and-initiatives direction. Generated
workspace guidance remains important, but the durable handoff should be designed
around initiatives linked to repo-local OpenSpec changes, not around a
workspace-owned cross-repo planning home.
The remaining sections preserve the original workspace-agent-guidance direction
for later reference. This work is still expected to matter after initiatives and
initiative-linked repo-local changes exist; it is not the immediate next focus.
OpenSpec workspaces let users create a planning home and link repos or folders
for cross-area exploration. After setup, the next user expectation is simple:
> I opened the workspace with my agent. The agent should understand where it is,
> what it can safely inspect, and how to help me turn a product goal into a
> workspace proposal.
Today that handoff is too thin. Workspace-local skills are installed, and the
CLI can create workspace-scoped changes, but agents still mostly behave like
they are in a normal repo-local OpenSpec project. They do not have a clear
workspace-native starting model before change creation.
That creates avoidable confusion:
- linked repos or folders may look like implementation targets instead of
read-only planning context
- agents may not know which registered link names are valid affected areas
- users may feel pressured to know every affected area before planning starts
- the product goal can be lost between workspace exploration and change
creation
- workspace planning can feel like a separate mode instead of normal OpenSpec
stretched across linked areas
The principle this change should reinforce is:
> Workspace visibility is not change commitment.
Linked repos and folders are available for exploration. Creating a workspace
change captures a planning commitment. Implementation edits still require an
explicit implementation workflow with an allowed edit root.
## Goal
Make workspace-local planning skills give agents a small, reliable operating
model for starting workspace proposals.
An agent opened in a workspace should be able to:
1. recognize that it is operating from a workspace planning home
2. inspect registered workspace links as planning context
3. keep linked repos and folders read-only during planning
4. derive a concise workspace change name and product goal from the user request
5. pass known affected areas only when they match registered workspace link names
6. continue even when affected areas are unresolved, keeping those questions
visible in the normal planning artifacts
This should feel to the user like the ordinary OpenSpec proposal flow, just with
workspace-aware context and safety.
## Starting Scope
Start with the smallest useful surface:
- workspace-local generated skill guidance
- change-starting workflows used from a workspace planning home
- the relationship between user product goals, registered link names, and
workspace change metadata
- guardrails that keep planning separate from implementation edits
The first implementation should prefer clear agent guidance over new workflow
machinery. If the existing CLI already exposes enough workspace context, the
skills should use it. If it does not, we should identify the missing context
explicitly before adding heavier behavior.
## Non-Goals
This change does not need to solve the full workspace lifecycle.
Out of scope for this slice:
- workspace apply semantics
- workspace verify or archive semantics
- branch or worktree orchestration
- creating repo-local changes for each affected area
- shared/team coordination repo behavior
- canonical shared-contract ownership flows
- forcing users to finalize all affected areas before creating a proposal
## Questions To Work Through
- What exact workspace context should an agent read before creating a change?
- Is the existing workspace/status/doctor output enough, or do we need a clearer
pre-change context command?
- How should generated skills decide when an affected area is confident enough
to pass as `--areas`?
- Should `--goal` be workspace-only metadata, or should repo-local behavior be
documented too?
- Where should unresolved affected-area questions appear so users and agents
continue from the same source of truth?
@@ -0,0 +1,58 @@
## Why
Status: deferred by the context-store-and-initiatives direction. The principle
that apply means implementation is still useful, but the durable handoff should
be designed around initiatives linked to repo-local OpenSpec changes, not around
a workspace-owned cross-repo plan. Do not implement this as a first-class
workspace lifecycle command until that linkage exists.
The remaining sections preserve the original workspace apply direction for
later reference. This work is still expected to matter after initiatives and
initiative-linked repo-local changes exist; it is not the immediate next focus.
After a workspace proposal exists, users need a practical way to implement one repo slice at a time.
In the proper workspace model, apply means implementation:
```text
Take the selected workspace change.
Take the selected repo slice.
Open or use the right checkout.
Implement that slice while preserving the workspace plan.
```
It should not mean copying or materializing planning files into every repo as a user-facing workflow.
## What Changes
Add the repo-slice apply workflow for workspace changes:
- select a workspace change
- select one target repo alias
- resolve the local checkout for that alias
- provide the agent with the workspace plan and repo-specific implementation context
- track progress without making the workspace lose ownership of the plan
The workflow should support implementation across separate branches or sessions while keeping the workspace proposal as the continuity layer.
Planning dependency:
- Depends on `workspace-change-planning`.
## Capabilities
### New Capabilities
- `workspace-repo-slice-apply`: Applies one repo slice of a workspace change as an implementation workflow.
### Modified Capabilities
- `cli-artifact-workflow`: Defines workspace apply as implementation rather than materialization.
- `context-injection`: Supplies repo-specific implementation context from a workspace change.
## Impact
- Workspace apply command behavior.
- Agent handoff text for repo-slice implementation.
- Local checkout resolution and branch/worktree assumptions.
- Tests that apply operates on one target repo slice and does not require copying workspace planning artifacts as the primary user contract.
@@ -0,0 +1,511 @@
# Workspace Reimplementation Direction
Date: 2026-04-30
## Status
This document is historical product direction from the workspace POC follow-up.
It remains useful for preserved workspace setup, link, open, update, doctor, and
agent-visibility decisions.
It no longer defines the durable coordination model. The current authority is
`openspec/initiatives/context-store-and-initiatives/direction.md`, which locks
this boundary:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
Superseded here: workspace as the durable planning home, workspace-level
planning artifacts as the canonical shared cross-repo plan, and workspace
apply/verify/archive as the next first-class lifecycle commands.
Deferred here: apply, verify, archive, branch/worktree orchestration,
cross-repo validation, dependency graph enforcement, and governance flows until
initiative-linked repo-local changes exist.
Fresh-agent entry point: read `openspec/changes/workspace-reimplementation-roadmap/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 sections below are historical POC follow-up direction. Use them for lessons
and preserved local-view behavior only. Do not treat later workspace lifecycle
sections as active implementation guidance.
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.
## Historical Product Shape
This was the older workspace product shape. It is preserved here so POC lessons
remain understandable, but it is superseded by the context-store-and-initiatives
direction for durable coordination.
The historical durable product model was:
```text
workspace = 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
```
The current durable product model is:
```text
context store = synced shared truth
initiative = durable coordination object
workspace = local opened view
repo change = repo-owned implementation plan
```
The historical user journey was:
```text
Open the workspace.
Ask the agent to explore.
Create the proposal when scope is clear.
Implement one repo slice at a time.
Verify.
Archive.
```
@@ -0,0 +1,266 @@
# Workspace POC Reference Guide
This guide is for a fresh agent starting a new session with no prior context about the workspace POC.
Root entry point: `START_HERE.md`.
The goal is not to continue the POC. The goal is to use it as research material
before preserving or replacing specific behavior from the current base.
Current product authority lives in
`openspec/initiatives/context-store-and-initiatives/`. Under that direction,
workspace setup/open/update/doctor behavior remains useful local-view
infrastructure. Workspace-level apply, verify, and archive research is deferred
until initiative-linked repo-local changes exist.
## Reference Point
Use this exact commit as the stable reference:
```text
workspace-poc @ 79a45ac043f414e63d13e08b9da83b135cb20a39
```
Do not rely only on the moving branch name. Do not merge this commit into the implementation branch. Do not cherry-pick from it unless a later proposal explicitly decides that a small piece should be preserved.
## What The POC Was Trying To Prove
Start from the user journey:
```text
create workspace
-> add repos
-> open workspace with an agent
-> explore across repos
-> create a proposal
-> apply one repo slice
-> verify
-> archive
```
The POC is useful if it helps answer:
- What did the user experience feel like when workspace mode worked?
- Which CLI surfaces made the workflow easier to understand?
- Which tests captured real product expectations?
- Which implementation choices were shortcuts that should not survive?
- Which terminology became misleading once the desired product shape was clearer?
## First Files To Read
Read these from the POC commit before implementation:
```text
WORKSPACE_REIMPLEMENTATION_DIRECTION.md
WORKSPACE_POC_FOLLOWUP_NOTES.md
docs/workspace.md
docs/workspace-demo.md
docs/cli.md
src/commands/workspace.ts
src/core/workspace/open.ts
test/commands/workspace/open.test.ts
test/core/workspace/open.test.ts
test/cli-e2e/workspace/workspace-open-cli.test.ts
```
Optional deeper context:
```text
workspace-poc-explorer.html
workspace-poc-phase-playground.html
copilot-session-d4e9c61e-readable.md
copilot-session-d4e9c61e-timeline.md
```
The optional files are historical research aids. Use them to understand how the POC evolved, not as implementation requirements.
## How To Inspect The POC Safely
Preferred approach: use a separate worktree or read files directly from the pinned commit.
Example direct reads:
```bash
git show 79a45ac043f414e63d13e08b9da83b135cb20a39:WORKSPACE_REIMPLEMENTATION_DIRECTION.md
git show 79a45ac043f414e63d13e08b9da83b135cb20a39:src/commands/workspace.ts
git diff origin/main...79a45ac043f414e63d13e08b9da83b135cb20a39 --stat
```
Example separate worktree:
```bash
git worktree add ../openspec-workspace-poc 79a45ac043f414e63d13e08b9da83b135cb20a39
```
Keep the implementation branch based on the current target branch. The POC worktree is for reading and running tests only.
## What To Bring Back
Before implementing a slice, come back with a short POC findings note:
```text
POC findings for <slice>:
User behavior to preserve:
- ...
Tests or examples worth translating:
- ...
Implementation shortcuts to avoid:
- ...
Open design questions:
- ...
```
Put durable findings in the relevant OpenSpec proposal or design artifact. Do not leave important decisions only in chat.
## Slice-Specific Reading
### `workspace-foundation`
Focus on:
- workspace folder shape
- metadata directory naming
- local versus committed state
- stable workspace name semantics
Read:
```text
WORKSPACE_REIMPLEMENTATION_DIRECTION.md
WORKSPACE_POC_FOLLOWUP_NOTES.md
docs/workspace.md
src/commands/workspace.ts
```
Bring back:
- the storage model worth keeping
- the metadata naming decision
- any compatibility risks with repo-local `openspec/`
### `workspace-create-and-register-repos`
Focus on:
- how a user creates a workspace
- how repos or folders are linked
- what `doctor` or equivalent status output should explain
- how POC `create`/`add-repo` behavior maps to the target `setup`/`link`/`relink`/`doctor` flow before change creation
- how planning-only repos and monorepo modules differ from implementation-ready repo-local OpenSpec projects
Read:
```text
docs/workspace.md
docs/workspace-demo.md
src/commands/workspace.ts
test/commands/workspace/setup.test.ts
```
Bring back:
- expected commands
- expected files
- validation behavior for bad paths, duplicate workspace names, missing paths, planning-only links, and duplicate link names
### `workspace-open-agent-context`
Focus on:
- what context the agent receives
- how linked repos or folders become visible
- how one-session agent selection should work
- what should be stable guidance versus dynamic launch context
Read:
```text
WORKSPACE_POC_FOLLOWUP_NOTES.md
src/commands/workspace.ts
src/core/workspace/open.ts
test/commands/workspace/open.test.ts
test/core/workspace/open.test.ts
test/cli-e2e/workspace/workspace-open-cli.test.ts
```
Bring back:
- launch-context requirements
- agent-specific behavior to preserve
- prompt or guidance text that should become stable instructions
### `workspace-change-planning`
Focus on:
- when repo scope becomes a planning commitment
- whether targets should be inferred from artifacts
- how proposal, design, tasks, and specs should be arranged
Read:
```text
WORKSPACE_REIMPLEMENTATION_DIRECTION.md
docs/workspace.md
docs/workspace-demo.md
```
Bring back:
- the artifact shape to use
- how targets should be confirmed
- which POC target metadata ideas should be avoided or deferred
### `workspace-apply-repo-slice`
Focus on:
- the terminology decision that apply means implementation
- what context the agent needs to implement one repo slice
- why materialization should not be the user-facing contract
Read:
```text
WORKSPACE_REIMPLEMENTATION_DIRECTION.md
WORKSPACE_POC_FOLLOWUP_NOTES.md
```
Bring back:
- the normalized apply context shape
- the user-facing apply contract
- any POC materialization behavior that should be explicitly rejected
### `workspace-verify-and-archive`
Focus on:
- partial repo completion versus full workspace completion
- how verification should report gaps
- how archive should avoid forcing repo-local planning copies
Read:
```text
WORKSPACE_REIMPLEMENTATION_DIRECTION.md
docs/workspace-demo.md
```
Bring back:
- the minimum useful verify behavior
- the archive preconditions
- the distinction between repo-slice completion and workspace hard-done state
## Ground Rules
- Treat the POC as evidence, not inheritance.
- Preserve user-visible lessons before preserving code.
- Prefer current repo patterns over POC-only abstractions.
- Implement one user-visible step at a time.
- Update this roadmap when a POC lesson changes a later slice.
@@ -0,0 +1,107 @@
# Workspace Reimplementation Roadmap
This change is the continuity layer for reimplementing workspace support across multiple sessions and branches.
## Current Status
This roadmap is historical and has been reframed by
`openspec/initiatives/context-store-and-initiatives/`. Fresh agents should use
the initiative direction as product authority and this roadmap as reference for
POC lessons and preserved local-view behavior.
Keep:
- workspace setup, link, relink, list, open, update, and doctor
- linked repos and folders as local planning context
- workspace-local skills as local agent guidance
- the POC as research material only
Supersede:
- workspace as the durable shared planning home
- workspace-level planning artifacts as the canonical cross-repo plan
- workspace change planning as the long-term source of truth
Defer:
- workspace apply, verify, and archive as first-class lifecycle commands
- branch/worktree orchestration, strong cross-repo validation, and dependency
graph enforcement
Do not pick up the next unfinished flat sibling change from this roadmap unless
a later initiative-linked repo-change design explicitly reactivates it.
Root entry point for fresh agents: `START_HERE.md`.
The user journey this historical roadmap was implementing is:
```text
create workspace
-> add repos
-> open workspace with agent context
-> plan a cross-repo change
-> implement one repo slice
-> verify and archive
```
The POC branch is reference material only:
```text
workspace-poc @ 79a45ac043f414e63d13e08b9da83b135cb20a39
```
Use it to understand behavior, tests, and lessons learned. Do not merge it or preserve its architecture by default. The full source direction document from that branch is captured in `HISTORICAL_DIRECTION.md`.
Fresh agents should read `POC_REFERENCE_GUIDE.md` before implementing any slice. That guide explains how to inspect the pinned POC commit, which files to read for each slice, and what findings to bring back into the OpenSpec artifacts.
## Historical Change Order
The original flat sibling changes were:
1. `workspace-foundation`
2. `workspace-create-and-register-repos`
3. `workspace-open-agent-context`
4. `workspace-change-planning`
5. `workspace-agent-guidance`
6. `workspace-apply-repo-slice`
7. `workspace-verify-and-archive`
OpenSpec currently discovers active changes as immediate directories under `openspec/changes/`, and change names are kebab-case identifiers. These changes remain useful reference artifacts, but they are no longer a direct implementation queue.
## Dependency Notes
`workspace-foundation` establishes the storage, root detection, and naming model. Every later slice should build on that model instead of redefining workspace metadata.
`workspace-create-and-register-repos` creates the workspace and makes linked repos or folders visible before a change exists. Linked items may be full repos, monorepo modules, or planning-only folders. This preserves the product rule that workspace visibility is not change commitment.
`workspace-open-agent-context` gives the agent the workspace location, linked repos or folders, active changes, and selected change scope.
`workspace-change-planning` created the beta workspace-level planning commitment and identified target repo slices. Under the initiative direction, this model is legacy or transitional rather than the durable shared plan.
`workspace-agent-guidance` makes workspace-local workflow skills use the planning model deliberately: inspect linked context, seed workspace changes with goal and known affected areas, and preserve linked repos as read-only planning context until apply selects an edit root.
`workspace-apply-repo-slice` is deferred until initiative-linked repo-local changes define the implementation handoff.
`workspace-verify-and-archive` is deferred until initiative status and linked repo-local change lifecycle exist.
## Session Handoff Prompt
Use this prompt at the start of future implementation sessions:
```text
Continue the context-store-and-initiatives direction. Read
openspec/initiatives/context-store-and-initiatives/direction.md and
openspec/initiatives/context-store-and-initiatives/roadmap.md first. Use
openspec/changes/workspace-reimplementation-roadmap/START_HERE.md,
openspec/changes/workspace-reimplementation-roadmap/README.md,
openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md,
openspec/changes/workspace-reimplementation-roadmap/POC_REFERENCE_GUIDE.md, and
workspace-poc at 79a45ac043f414e63d13e08b9da83b135cb20a39 as historical
reference material only. Preserve useful local-view workspace behavior, but do
not implement workspace apply, verify, or archive until initiative-linked
repo-local changes exist.
```
## Branching Guidance
Each sibling change may be implemented on its own branch or PR. Keep decisions that affect later slices in this README or in the relevant proposal so future sessions do not depend on chat history.
@@ -0,0 +1,105 @@
# Workspace Reimplementation Start Here
This is the grep-friendly historical entry point for agents working on the
workspace reimplementation.
## Current Status
The original workspace lifecycle roadmap has been reframed by the context store
and initiatives direction. Fresh agents should treat this document and the POC
materials as reference for preserved local-view infrastructure, not as the next
implementation queue.
Current product authority lives in:
1. `openspec/initiatives/context-store-and-initiatives/direction.md`
2. `openspec/initiatives/context-store-and-initiatives/roadmap.md`
The locked boundary is:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
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. `openspec/initiatives/context-store-and-initiatives/direction.md`
2. `openspec/initiatives/context-store-and-initiatives/roadmap.md`
3. `openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md`
4. `openspec/changes/workspace-reimplementation-roadmap/README.md`
5. `openspec/changes/workspace-reimplementation-roadmap/POC_REFERENCE_GUIDE.md`
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 later initiative or repo-local change
design explicitly decides to do so.
## Historical Implementation Order
The original flat OpenSpec order was:
1. `workspace-foundation`
2. `workspace-create-and-register-repos`
3. `workspace-open-agent-context`
4. `workspace-change-planning`
5. `workspace-agent-guidance`
6. `workspace-apply-repo-slice`
7. `workspace-verify-and-archive`
Current disposition:
- Keep setup, link, relink, list, open, update, and doctor as beta local-view
infrastructure.
- Treat workspace planning as legacy or transitional behavior, not the durable
cross-repo source of truth.
- Do not implement `workspace-apply-repo-slice` or
`workspace-verify-and-archive` as first-class workspace lifecycle commands
until initiative-linked repo-local changes exist.
- Use `workspace-reimplementation-roadmap` as continuity and reference, not as
the active shipping sequence.
## 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 initiative, context-store, or
repo-local OpenSpec artifact so future sessions do not depend on chat history.
@@ -0,0 +1,62 @@
## Why
Workspace support needs to be reimplemented as a user-facing workflow, not carried forward as a direct port of the proof of concept.
Status: this roadmap is now historical reference. The active product direction is
the context-store-and-initiatives initiative, where initiatives coordinate
durable cross-repo work, workspaces open local views, and repo-local changes own
implementation. Keep workspace setup/open/update/doctor infrastructure, but do
not treat workspace apply, verify, or archive as the next shipping sequence
until initiative-linked repo-local changes exist.
A user should be able to say they have a multi-repo product goal, create a workspace, add the relevant repos, open that workspace with an agent, plan the change, implement one repo slice at a time, verify it, and archive it. The POC branch captured useful behavior and discovery, but its implementation should remain reference material rather than the base architecture.
This roadmap also needs to survive multiple sessions and branches. Current OpenSpec change discovery treats active changes as flat immediate directories under `openspec/changes/`, and change names are kebab-case identifiers rather than nested paths. This change is therefore a flat planning container with sibling proposal changes instead of nested child changes.
Reference material:
- `workspace-poc` at `79a45ac043f414e63d13e08b9da83b135cb20a39`
- `WORKSPACE_REIMPLEMENTATION_DIRECTION.md` on that branch
- `WORKSPACE_POC_FOLLOWUP_NOTES.md` on that branch
## What Changes
Add a lightweight roadmap for reimplementing workspace support as a stack of flat sibling OpenSpec changes:
- `workspace-foundation`
- `workspace-create-and-register-repos`
- `workspace-open-agent-context`
- `workspace-change-planning`
- `workspace-agent-guidance`
- `workspace-apply-repo-slice`
- `workspace-verify-and-archive`
Each sibling change owns one step in the lived user journey. Dependencies are documented in proposal prose for now. When change stacking metadata lands, this roadmap can be migrated to explicit `parent` and `dependsOn` metadata.
The intended order is:
```text
workspace-foundation
-> workspace-create-and-register-repos
-> workspace-open-agent-context
-> workspace-change-planning
-> workspace-agent-guidance
-> workspace-apply-repo-slice
-> workspace-verify-and-archive
```
## Capabilities
### New Capabilities
- `workspace-reimplementation-roadmap`: Coordinates the workspace reimplementation plan across multiple flat OpenSpec changes.
### Modified Capabilities
- `openspec-conventions`: Clarifies that this workspace effort uses flat sibling changes until nested or stacked change metadata is supported.
## Impact
- Planning only in this PR.
- Future changes will affect workspace metadata, workspace CLI flows, agent context construction, workspace change planning, workspace-local agent guidance, repo-slice application, verification, and archive behavior.
- No runtime behavior changes are introduced by this roadmap proposal.
@@ -0,0 +1,57 @@
## Why
Status: deferred by the context-store-and-initiatives direction. Per-repo
progress visibility remains important, but verify/archive should be redesigned
around initiative status and linked repo-local OpenSpec changes, not around
workspace-owned final archive state. Do not implement this as a first-class
workspace lifecycle command until that linkage exists.
The remaining sections preserve the original workspace verify/archive direction
for later reference. This work is still expected to matter after initiatives and
initiative-linked repo-local changes exist; it is not the immediate next focus.
Users need to know whether a cross-repo workspace change is complete without flattening all repo progress into one ambiguous done state.
The desired lifecycle is:
```text
Verify each repo slice.
See which slices are complete or still open.
Archive repo-local results when appropriate.
Archive the workspace change when the cross-repo goal is done.
```
Verification and archive should make the user's cross-repo status clearer, not force them to reason about internal artifact placement.
## What Changes
Add workspace-aware verify and archive behavior:
- verify workspace-level change structure and target repo status
- show per-repo slice progress
- support repo-local archive work where needed
- support explicit workspace-level archive when the coordinated goal is complete
- avoid treating partial repo completion as full workspace completion
Planning dependency:
- Depends on `workspace-apply-repo-slice`.
## Capabilities
### New Capabilities
- `workspace-verify-archive`: Verifies and archives workspace changes with per-repo progress visibility.
### Modified Capabilities
- `cli-archive`: Adds workspace-aware archive semantics.
- `opsx-verify-skill`: Adds workspace verification guidance.
- `opsx-archive-skill`: Adds workspace archive guidance.
## Impact
- Workspace status, verify, and archive behavior.
- Per-repo slice completion reporting.
- Workspace-level hard-done marker or equivalent archive state.
- Tests for partial completion, final workspace archive, and compatibility with standalone repo-local archive flows.
+8 -1
View File
@@ -5,6 +5,12 @@ context: |
Package manager: pnpm
CLI framework: Commander.js
Product language:
- Write OpenSpec proposals and specs in user-facing product behavior language
- Requirements should describe the experience, observable behavior, and product contract
- Avoid implementation-negative SHALL statements when a positive user outcome can express the same rule
- Put internal mechanisms in design.md or tasks.md unless the mechanism is itself part of the user-facing contract
Cross-platform requirements:
- This tool runs on macOS, Linux, AND Windows
- Always use path.join() or path.resolve() for file paths - never hardcode slashes
@@ -16,7 +22,8 @@ rules:
specs:
- Include scenarios for Windows path handling when dealing with file paths
- Requirements involving paths must specify cross-platform behavior
- Be explicit about mechanisms, not just outcomes (say HOW, not just WHAT)
- Prefer user-facing product behavior and observable outcomes over internal implementation mechanics
- Include HOW details only when the mechanism is part of the product contract
- If we generate artifacts, specify deletion/modification by explicit list lookup, not pattern matching
tasks:
- Add Windows CI verification as a task when changes involve file paths
+15 -2
View File
@@ -6,6 +6,8 @@ The explore workflow is part of the core loop (`propose`, `explore`, `apply`, `a
Currently, explore references `/opsx:new` and `/opsx:ff` which are being replaced with `/opsx:propose`. But beyond just updating references, there are deeper UX questions about how explore should work.
This exploration is also affected by the emerging workspace direction: for larger cross-team or cross-repo work, OpenSpec may need to treat the **initiative** as the first-class planning object and repo-local changes as execution artifacts. That means explore may sometimes be seeding an initiative, not just a single change.
## Open Questions
### Exploration Artifacts
@@ -17,6 +19,7 @@ Currently, explore references `/opsx:new` and `/opsx:ff` which are being replace
2. **Where should exploration files live?**
- `openspec/explorations/<name>.md`?
- `openspec/changes/<change>/explorations/`?
- `.openspec-workspace/initiatives/<initiative>/explorations/` for coordinated work?
- Somewhere else?
3. **What should the format be?**
@@ -30,15 +33,17 @@ Currently, explore references `/opsx:new` and `/opsx:ff` which are being replace
- e.g., exploring auth approaches separately from UI approaches
- How would these relate to each other?
5. **How do explorations relate to changes?**
5. **How do explorations relate to changes or initiatives?**
- Before change exists: standalone exploration
- After change exists: exploration linked to change?
- After repo-local change exists: exploration linked to change?
- For coordinated work: exploration linked to initiative first, then optionally referenced by repo-local changes?
### Lifecycle & Transitions
6. **What happens before a change proposal exists?**
- Exploration is standalone
- When ready, user runs `/opsx:propose`
- For coordinated work, should exploration context seed an initiative first?
- Should exploration context automatically seed the proposal?
7. **What happens after a change proposal exists?**
@@ -90,11 +95,19 @@ Currently, explore references `/opsx:new` and `/opsx:ff` which are being replace
- **Pro:** Clear relationship to changes
- **Con:** Where do pre-change explorations go?
### Approach E: Initiative-First Explorations for Coordinated Work
- Local work can stay standalone or change-linked
- Coordinated work saves exploration notes under an initiative in the coordination workspace
- Repo-local changes can reference the shared exploration when execution starts
- **Pro:** Matches the emerging split between shared planning and repo-local execution
- **Con:** Adds another context where exploration artifacts may live
## Next Steps
- [ ] User research: How do people actually use explore today?
- [ ] Prototype: Try saving explorations and see if propose benefits
- [ ] Decide: Pick an approach based on findings
- [ ] Reconcile explore UX with initiative-first coordinated planning
- [ ] Implement: Update explore workflow accordingly
## Related
+182 -6
View File
@@ -77,7 +77,7 @@ We researched how similar tools handle config layering:
| **ESLint (flat)** | Single root config | *Deliberately killed cascading* - "complexity exploded exponentially" |
| **Turborepo** | Root + package extends | Per-package `turbo.json` with `extends: ["//"]` for overrides |
| **Nx** | Integrated vs Package-based | Two modes - shared root OR per-package. Hard to migrate from integrated. |
| **pnpm** | Workspace root defines scope | `pnpm-workspace.yaml` at root. Dependencies can be shared or per-package |
| **pnpm** | Workspace file defines package scope | `pnpm-workspace.yaml` at the package-set root. Dependencies can be shared or per-package |
| **Claude Code** | Global + Project | `~/.claude/` for global, `.claude/` per-project. No workspace tracking. |
| **Kiro** | Distributed per-root | Each folder has `.kiro/`. Aggregated display, no inheritance. |
@@ -645,23 +645,199 @@ To avoid losing this in exploration notes, codify it in:
---
## Part 10: Design Decisions (April 2026)
After evaluating the models above against real multi-repo use cases (see [#725](https://github.com/Fission-AI/OpenSpec/issues/725)), we converged on the following design direction.
### Core Insight
The workspace itself is not the durable thing. For large teams, the durable planning object is the **initiative** or **plan**, while repo-local specs and changes remain the execution artifacts owned by each repo. The set of repos involved in a feature is typically feature-scoped and changes over time, so a static workspace manifest that must be configured before work begins creates ceremony that doesn't match how teams actually work.
### Decision: Model D with Lazy Workspace
Choose Model D (Hybrid) from Part 4, but make the workspace manifest **optional and lazy, not prerequisite**.
- **Each repo keeps its own canonical `openspec/`** — no change to the fundamental storage model.
- **Cross-root work can be coordinated through an initiative in a coordination workspace** — this is where shared planning lives when the work stops being cleanly repo-scoped.
- **"Workspace" is a derived or explicit coordination view** over linked repos and linked changes, not something users must register up front.
- **Persist a workspace manifest only when someone explicitly wants a reusable cross-repo bundle** — this is an opt-in convenience, not a requirement.
### Decision: Initiative-First Planning with Linked Repo-Local Changes
For larger multi-team work, repo-centric planning is the wrong primary abstraction. Teams and repos are many-to-many facets over the same work. OpenSpec should treat the **initiative / plan** as the first-class planning object, then link repo-local changes to it.
This is especially important because a change today bundles:
- `proposal.md`
- `design.md`
- `tasks.md`
- delta specs
- `.openspec.yaml`
That bundled shape works well for repo-local work, but becomes awkward when one piece of work spans multiple repos or teams. In those cases, a single repo-local change is trying to act as both:
- the shared planning object
- the repo-specific execution artifact
Those should be split.
The preferred model is:
```text
coordination workspace /
.openspec-workspace/
workspace.yaml
initiatives/
add-3ds/
initiative.yaml
proposal.md
design.md
links.yaml
repo-A/
openspec/
changes/
add-3ds-api/
.openspec.yaml
tasks.md
specs/
repo-B/
openspec/
changes/
add-3ds-web/
.openspec.yaml
tasks.md
specs/
```
The initiative holds the shared planning layer:
- proposal / intent
- shared design and tradeoffs
- participating teams
- impacted repos
- milestones, risks, and dependencies
- links to repo-local changes
Each repo-local change holds the execution layer for that repo:
- repo-specific tasks
- delta specs
- local implementation status
- optional local notes that should archive with that repo's work
Cross-repo linking still matters, but it should hang off the initiative and the repo-local changes:
```yaml
# billing-service/openspec/changes/add-3ds/.openspec.yaml
schema: spec-driven
created: 2026-04-12
initiative: add-3ds
links:
- project: github.com/fission/web-client
change: add-3ds-checkout
- project: github.com/fission/ios-client
change: add-3ds-checkout
```
Each repo still holds its own change with its own deltas. A cross-repo effort is represented as one initiative plus N linked single-repo changes. This is preferable to a single mega-change because:
- Shared planning has one truthful home
- Each repo's change goes through its own archive cycle
- No need to resolve cross-repo file paths in delta specs
- Teams can move at different speeds (web ships before iOS)
For small single-repo work, a repo-local change may still be "good enough" as both plan and execution bundle. The initiative-first split matters once work becomes cross-team, cross-module, cross-repo, or otherwise coordination-heavy.
### Decision: Stable Project Identifiers, Not Paths
Cross-repo links must use **stable project identifiers**, not filesystem paths.
- **Canonical form:** A normalized `host/org/repo` tuple (e.g., `github.com/fission/web-client`).
- **Authoring shorthand:** The CLI accepts `org/repo` (e.g., `fission/web-client`) and infers the host from the current repo's remote.
- **Relative paths are never the durable identifier.** They may exist only as cached local resolution results.
### Decision: Offline-First Resolution
The CLI resolves project identifiers to local paths using an offline-first chain:
1. **Explicit paths** passed for the current run (e.g., CLI flags, ad-hoc multi-root).
2. **Local OpenSpec repo registry** — a persistent mapping in `~/.config/openspec/` or `~/.local/share/openspec/` (see `src/core/global-config.ts`).
3. **Parent directory scanning** — scan known parent directories for git checkouts whose remotes match the target identifier.
4. **Unresolved** — if no local path is found, leave the target unresolved and continue with a partial workspace. The CLI must not fail.
The registry is populated progressively: when the CLI discovers a clone (via scanning or user prompt), it persists the mapping for future resolution. The registry also stores "known scan roots" (e.g., `~/work/`) so scanning improves over time without upfront configuration.
### Decision: Informational References Only (v1)
Spec-level cross-repo references are **documentation-only pointers**:
```yaml
# web-client/openspec/specs/checkout/spec.md frontmatter
references:
- project: github.com/fission/contracts-service
spec: checkout-contract
```
- The CLI does **not** fail validation because a referenced cross-repo spec is missing or unresolved.
- The CLI **does** surface references to humans and agents when planning, viewing, or applying changes.
- Stronger guarantees (e.g., staleness warnings, cross-repo validation) are an opt-in layer added later — via `lint`, `doctor`, or a feature flag — not baseline behavior.
This avoids accidentally committing OpenSpec to a full dependency graph system before the use cases justify it.
### Decision: Explicit Owner Repo for Shared Contracts
When a spec cannot be mapped to a single implementation repo (e.g., a shared API contract):
- **One repo must be the explicit owner.** This can be a dedicated "contracts" repo, or whichever repo is the natural source of truth.
- **Other repos reference the owning repo's spec** via informational references (see above).
- **There is no default "pure spec repo" pattern.** Separating spec ownership from code ownership too aggressively makes agent execution awkward and diffuses responsibility.
### Monorepo vs. Multi-Repo Summary
| Concern | Monorepo | Multi-Repo |
|---------|----------|------------|
| **Spec organization** | Nested specs inside one `openspec/` (Model B) | Each repo has its own `openspec/` |
| **Cross-cutting specs** | Nested under a `contracts/` or `shared/` directory | Dedicated owner repo, others reference it |
| **Planning object** | Initiative optional for simple work, useful for large cross-team efforts | Initiative is the primary coordination object |
| **Changes** | One or more repo-local changes can implement one initiative | Linked per-repo changes implement one initiative |
| **Relationships** | References (no inheritance in v1) | Project identifier links, informational only |
| **Workspace** | Usually not needed, but can host initiative planning for complex work | Coordination workspace hosts initiative planning; optional manifest for reuse |
### Implementation Path
1. **Define initiative artifacts** — add an initiative format for shared planning in coordination workspaces.
2. **Extend change metadata** — let repo-local changes point at an initiative and linked sibling changes.
3. **Extend spec metadata** — add `references` field for cross-repo spec pointers.
4. **Build project resolution** — implement the offline-first resolution chain and local registry.
5. **Build initiative and link views** — commands that resolve and display the initiative graph plus linked repo-local changes.
6. **Support ad-hoc multi-root** — "add these dirs for this run" or "derive roots from this initiative's links."
7. **Optional workspace manifest** — add saved workspaces only if teams demonstrate reuse patterns.
Nested specs (Model B inside a single repo) are a prerequisite for clean monorepo support and should be tackled first, as outlined in #662.
---
## Summary
| Question | Status | Notes |
|----------|--------|-------|
| Profile UX | Decided | `openspec config profile` with presets |
| Config layering | Decided | Two layers: global + project (no workspace layer) |
| Spec organization | Open | Four models under consideration (including hybrid Model D) |
| Spec organization | **Direction set** | Nested specs per repo, explicit owner repos for shared contracts, references for cross-repo context |
| Spec philosophy | Direction set | Behavior-first contracts, progressive rigor, and agent-aligned authoring |
| Spec inheritance | Open | Inheritance vs references vs none |
| Multi-repo support | Open | Workspace concept TBD |
| Dependency tracking | Open | Probably out of scope initially |
| Spec inheritance | **Decided** | References only, no inheritance in v1 |
| Initiative / planning model | **Direction set** | Initiative-first planning for larger work, with repo-local changes as execution artifacts |
| Multi-repo support | **Direction set** | Linked per-repo changes under shared initiatives; workspace is coordination, not canonical execution storage |
| Dependency tracking | **Decided** | Out of scope for v1; references are informational only |
| Cross-repo resolution | **Decided** | Offline-first resolution chain with local registry |
| Shared contracts | **Decided** | Explicit owner repo required; no default pure-spec-repo pattern |
### Key Insight
The "workspace" question is really two separate questions:
1. **Config/profile scope** → Solved with global + project (no workspace needed)
2. **Spec/change organization** → Unsolved, needs deeper design work
2. **Plan vs. execution organization** → Direction set: initiatives coordinate, repo-local changes implement, workspace remains a coordination layer
These should be separate changes with separate explorations.
+367
View File
@@ -0,0 +1,367 @@
# Workspace Roadmap
## Purpose
This document proposes a lightweight roadmap for workspace, monorepo, and multi-repo support in OpenSpec.
It assumes:
- single-repo is the current default experience
- monorepo pain is already real
- multi-repo coordination is not hypothetical
- large engineering organizations already need this
This roadmap is intentionally staged.
The goal is not to build the full conceptual system at once.
The goal is to ship the smallest credible version of cross-boundary support while preserving a path to a stronger long-term model.
---
## Product Principle
> Prefer the smallest feature set that solves real cross-boundary work without blocking the likely long-term direction.
This means:
- do not overbuild governance before usage proves it
- do not underbuild coordination if real teams already need it
- do not add complexity to the single-repo path unless it clearly pays for itself
---
## What We Believe Now
Based on the current exploration work, several things look increasingly clear.
### 1. Nested spec organization is needed
OpenSpec needs a better way to organize:
- shared contracts
- local implementation specs
- multi-area behavior inside one root
### 2. Informational references are low-risk and useful
References help agents and humans navigate related specs without requiring OpenSpec to build a dependency graph system on day one.
### 3. Initiatives plus linked per-repo changes are the right primitive
For true multi-repo work, the likely durable primitive is:
- one initiative as the shared planning object
- one linked change per owning repo as the execution artifact
- stable identifiers connecting them
### 4. Cross-repo work needs a neutral planning location
For multi-repo work, a single repo is not an honest home for the whole planning artifact.
Some form of coordination workspace or coordination repo is needed for the initiative-level plan.
### 5. Team-shared coordination is a real requirement
This is not just a solo-user thought experiment.
Real teams and large engineering orgs already need a way to coordinate multi-repo work.
### 6. The risk is shipping too much at once
Even though the need is real, the full model has many moving parts:
- nested spec paths
- shared contracts
- linked changes
- cross-root planning
- partial repo resolution
- agent capability differences
- team-shared coordination state
The roadmap should sequence these carefully.
---
## Phase 1: Better Structure Inside One Root
### Goal
Reduce pain in single-repo and monorepo setups without introducing coordination machinery yet.
### Ship
1. Nested spec paths within one `openspec/` root
2. Informational `references` in specs
3. Better filtering of relevant spec paths during planning
4. Better handling of multi-area changes inside one root
### User value
- monorepo users can organize shared and local specs more naturally
- large roots become less noisy
- shared contracts inside one root become easier to model
### Do not ship yet
- coordination workspaces
- linked multi-repo changes
- team-shared coordination repos
- sponsor/owner workflow machinery
### Success criteria
- users can model large monorepos without flattening everything at the top level
- users can represent shared contracts inside one root
- planning context gets smaller and more relevant
---
## Phase 2: Thin Cross-Repo Coordination
### Goal
Support real multi-repo planning demand with the thinnest credible coordination layer.
### Ship
1. Initiative artifacts for shared planning in a neutral coordination workspace or coordination repo
2. Linked per-repo changes using stable project identifiers
3. Explicit repo linking via project IDs
4. Resolution through:
- explicit input
- git remote matching
5. Partial-resolution support
6. Basic agent handoff instructions for coordinated planning
### User value
- users have an honest place to stand for multi-repo work
- cross-repo plans are no longer buried in one repo
- shared planning and repo-local execution are clearly separated
- ownership stays with the real repos
- agents can be told what roots matter
### Key constraints
This phase should remain thin.
Avoid:
- dependency validation across repos
- rich governance flows
- too many new abstractions in the CLI
- heavyweight local/shared state semantics
### v1 shape
This phase should feel like:
- local planning by default
- upgrade to a coordinated initiative when needed
- initiative-level planning in the coordination workspace
- linked repo-local changes underneath
Not like:
- a whole second product mode with many admin concepts
### Success criteria
- teams can coordinate multi-repo changes without inventing ad hoc spreadsheets or naming conventions
- users understand where planning lives and where implementation lives
- agents can plan across roots in a way that is operationally usable
---
## Phase 3: Team-Shared Coordination Hardening
### Goal
Make coordinated planning work cleanly across teammates and teams.
### Ship
1. Shared coordination repo/workspace support as a first-class pattern
2. Clear split between:
- committed shared initiative state
- local machine-specific path resolution
3. Lightweight relinking / repair flows
4. Better onboarding for teammates joining an initiative
5. Better agent instruction generation for shared workspaces
### User value
- teams can share a stable cross-repo initiative
- each teammate can map project IDs to their own local clones
- new participants can join without reverse-engineering how the initiative is set up
### Important constraint
The local side of this model should stay as thin as possible.
The ideal local layer is:
- regenerable
- non-authoritative
- not semantically important beyond path resolution
### Success criteria
- team-shared coordination works without local path leakage into committed state
- joining an initiative feels lightweight
- maintenance cost stays acceptable
---
## Phase 4: Shared Contract and Governance Maturity
### Goal
Support organizations that need stronger contract ownership and more formal cross-boundary planning.
### Ship only if demand justifies it
1. Guided shared contract ownership flows
2. Promotion of initiative-only draft behavior into canonical shared contracts
3. Stronger role visibility:
- canonical shared contract owner
- initiative sponsor/driver
4. Optional linting or policy checks
5. Optional validation around missing owners or unresolved references
### User value
- larger orgs can create durable shared contracts cleanly
- governance becomes explicit where needed
- cross-team ownership becomes easier to understand
### Important constraint
This should not become mandatory for normal users.
These features should remain:
- opt-in
- advanced
- proportional to org complexity
### Success criteria
- shared-contract workflows solve real org-scale problems without making normal planning feel bureaucratic
---
## What Should Not Be Delayed
Because demand is already real, some things should not be treated as purely future work.
### Should happen soon
- nested spec paths
- references
- initiative artifact + linked change primitive
- stable project identifiers
- thin coordination layer for multi-repo planning
### Can wait
- rich ownership workflows
- strong dependency semantics
- broad policy and governance features
- too much agent-specific machinery
---
## UX Guardrails Across All Phases
No matter the phase, the UX should follow these rules.
### 1. Default local
Users should start where they already are.
### 2. Escalate only when necessary
Coordinated planning should appear as an upgrade path, not the default mode.
### 3. Keep advanced concepts mostly implicit
Only expose concepts like shared owners, sponsor roles, overlays, and manifests when the user truly needs to decide something.
### 4. Canonical storage follows ownership
Specs and repo-local changes stay with the owning root.
### 5. Shared coordination is not canonical spec storage
Coordination data helps planning, but does not replace the source of truth.
### 6. Hidden local state must stay thin
If OpenSpec uses local path caches or machine-specific mappings, they should be:
- repairable
- replaceable
- non-authoritative
---
## Likely Deliverable Sequence
If this roadmap were translated into actual change proposals, the sequence would likely be:
1. nested spec paths + references
2. monorepo scope filtering and multi-area planning improvements
3. initiative artifact for shared planning
4. linked change metadata across repos
5. thin coordination workspace / repo for multi-repo planning
6. team-shared coordination hardening
7. optional shared contract maturity features
---
## Open Risks
### 1. Coordination may still be too heavy in v1
Even a thin coordination layer may feel like too much if the handoff is clumsy.
### 2. Hidden local state may become more important than intended
If path resolution or local repo linking becomes semantically important, the system will become harder to trust and debug.
### 3. Monorepo and multi-repo may diverge unintentionally
The product should resist evolving two completely separate mental models.
### 4. Agent capability differences may distort the design
The UX should not assume every coding agent handles multi-root planning equally well.
### 5. Team-scale needs may pressure early governance
Large orgs may quickly ask for ownership, permissions, and review structures. That should not force all users into heavyweight flows.
---
## Summary
The roadmap should not be:
- "wait on multi-repo until later"
Because the demand is already real.
It also should not be:
- "build the full workspace model now"
Because the complexity surface is too large.
The right roadmap is:
1. improve structure inside one root
2. ship a thin but real coordination layer for multi-repo work
3. harden team-shared coordination
4. add more formal shared contract and governance support only as justified
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,491 @@
# Workspace UX Simplification
## Purpose
This document focuses on one UX goal:
> OpenSpec should have one default path, one escalation path, and fewer explicit concepts shown to the user unless the system actually needs a decision from them.
This is a follow-up to `workspace-user-journeys.md`. That document is useful for completeness, but it exposes too much of the conceptual model too early.
This document is about how the product should **feel**.
---
## The UX Problem
The current user-journey exploration is coherent, but it is too heavy at first contact.
The main issues are:
1. Too many concepts appear before the user has done anything:
- scope
- project
- owning root
- shared contract owner
- coordination workspace
- initiative sponsor
- shared manifest vs local overlay
2. Cross-root work feels like a workflow restart:
- user starts in one repo
- OpenSpec says this is multi-repo
- user creates a workspace
- user reopens the agent there
- user effectively starts again
3. Shared contract decisions are asked too explicitly and too early.
4. Team-scale coordination is conceptually right, but reads more like infra setup than a lightweight workflow.
The system is internally clean, but the product experience should be more progressive.
---
## Design Goal
The user should feel:
- "I just start where I am"
- "OpenSpec figures out whether this stays local or needs to expand"
- "If it expands, it carries me forward instead of making me restart"
- "I only see advanced concepts when OpenSpec needs a real decision from me"
---
## The Core UX Shape
### One default path
The default path should always be:
1. Enter a repo or monorepo root
2. Run `/opsx:explore` or `/opsx:propose`
3. OpenSpec plans locally unless it has a strong reason not to
This should work for:
- single repo
- normal monorepo work
- many users in many situations
The default assumption should be:
> This is a local change until proven otherwise.
### One escalation path
The only escalation path should be:
> This work spans multiple owned areas strongly enough that OpenSpec needs to upgrade it into a coordinated initiative.
That escalation may happen for:
- large monorepo cross-team work
- true multi-repo work
- creation of a shared cross-boundary contract
The important UX point is that these should all feel like the same escalation:
- "OpenSpec is upgrading this into a coordinated initiative"
Not:
- one flow for multi-repo
- another flow for large monorepos
- another flow for shared contracts
---
## Progressive Disclosure
Users should not have to understand the full data model up front.
### Concepts users should see by default
At the start, users should mostly see:
- change
- affected area
- maybe repo if relevant
That is enough for the first planning step.
### Concepts OpenSpec should keep implicit until needed
These should usually stay hidden until escalation:
- scope
- coordination workspace
- initiative
- shared contract owner
- sponsor/driver
- manifest vs local overlay
### Concepts OpenSpec should only show when a real decision is needed
Show these only at the point of action:
- "This spans multiple repos. Create a coordinated initiative?"
- "This looks like shared behavior. Where should the canonical contract live?"
- "This initiative is team-shared. Do you want to commit it in a shared coordination repo?"
The system should not front-load these concepts as theory.
---
## The Simplest User Story
This is the baseline story the UX should optimize for.
### Story
The user is in a repo and types:
```text
/opsx:propose add-3ds
```
OpenSpec should:
1. inspect local context
2. infer likely affected areas
3. ask for confirmation only if needed
4. continue immediately
The user should feel like they are doing one thing:
```text
I am proposing a change.
```
Not:
```text
I am selecting between multiple planning abstractions.
```
---
## The Escalation Story
If OpenSpec realizes the work is no longer local, it should escalate in one motion.
### Desired feel
```text
This change affects multiple owned areas.
I can upgrade it into a coordinated initiative and carry your current planning context forward.
```
That wording matters.
It should feel like:
- an upgrade
- a continuation
- a convenience
It should not feel like:
- an error
- a hard stop
- a separate setup workflow
### What should happen during escalation
If escalation is needed, OpenSpec should do as much as possible automatically:
1. carry forward the current change name / description
2. preserve the already inferred affected areas
3. create the coordination artifact
4. resolve any local roots it can
5. generate agent instructions
6. then tell the user the next step
### Example escalation UX
```text
This work spans multiple owned areas:
- contracts
- billing-service
- web-client
- ios-client
OpenSpec can upgrade this into a coordinated initiative.
Suggested next step:
- create a coordination workspace at ~/work/openspec-workspaces/add-3ds
I’ll carry forward:
- your current change description
- affected repos
- any planning notes already gathered
```
This is much better than making the user feel they must restart.
---
## The Minimum Decision Set
When OpenSpec has to ask questions, it should ask the smallest useful set.
### Decision 1: Is this local or coordinated?
Most important product question.
User-facing form:
```text
This appears to span multiple owned areas.
How should I proceed?
- Keep this as one local change
- Upgrade to a coordinated initiative
```
This should be used sparingly and only when ambiguity matters.
### Decision 2: What areas are affected?
User-facing form:
```text
Which areas are affected?
```
This is much more intuitive than asking users about "scopes" first.
Internally this is scope selection, but the user does not need that term unless advanced users want it.
### Decision 3: Is this shared behavior?
Only ask if OpenSpec has strong evidence of a cross-boundary contract.
User-facing form:
```text
This looks like behavior that multiple areas need to follow.
Should I treat this as:
- local changes only
- a shared contract
- draft coordination notes for now
```
### Decision 4: Where should shared ownership live?
Only ask if the user confirms shared contract behavior and no obvious existing owner exists.
User-facing form:
```text
Where should the canonical shared contract live?
```
This should appear late, not early.
---
## Recommended Terminology
The internal model may use many precise terms. The UI should use simpler terms.
### Prefer in user-facing UX
- "area" instead of "scope" by default
- "coordinated initiative" instead of "workspace model"
- "shared contract" instead of "cross-boundary canonical spec"
- "owner" instead of "owning root"
- "team-shared initiative" instead of "shared coordination manifest"
### Reserve for advanced UX or docs
- scope
- project root
- local overlay
- sponsor/driver
- coordination workspace
These terms are useful, but not ideal as the first thing users must absorb.
---
## Recommended Default Behavior
To keep the UX intuitive, OpenSpec should aggressively choose defaults.
### Default 1: Stay local
Unless there is strong evidence otherwise, planning stays in the current root.
### Default 2: Infer affected areas
OpenSpec should infer affected areas from:
- request wording
- current repo
- known spec layout
- recent initiative context
Ask the user only when there is meaningful ambiguity.
### Default 3: Reuse existing shared owners
If an existing shared contract owner already exists, OpenSpec should suggest it instead of asking an abstract ownership question.
### Default 4: Treat unresolved roots as partial, not fatal
For coordinated initiatives, unresolved repos should not block planning unless the user explicitly needs implementation there now.
### Default 5: Team-shared only when collaboration is real
Do not force team/shared setup for solo or exploratory work.
OpenSpec can start with a local coordination workspace and later offer:
```text
This now looks collaborative. Do you want to move it into a shared coordination repo?
```
---
## How To Make Team UX Feel Light
The team story should not feel like an admin ceremony.
### Desired team experience
1. One person starts planning normally
2. OpenSpec upgrades to a coordinated initiative if needed
3. When the work becomes collaborative, OpenSpec offers to make it team-shared
4. Teammates clone the initiative repo and run one linking command
5. Everyone starts from the same shared initiative context
### Team onboarding should feel like this
```text
Clone the initiative repo.
Run `openspec workspace doctor`.
Open your agent here.
```
Not like this:
```text
Learn a new planning model, understand manifests, configure overlays, and attach roots manually.
```
The implementation may require those concepts, but the UX should compress them into a few actions.
---
## UX Heuristics For Prompting
OpenSpec should avoid asking users to classify work in abstract ways if it can infer a reasonable default.
### Good prompt
```text
This affects:
- web checkout
- billing API
- shared checkout behavior
I think this should become a coordinated initiative.
Proceed?
```
Why this is good:
- concrete
- recommendation included
- low cognitive load
### Weaker prompt
```text
Would you like to create a coordination workspace with linked changes and shared ownership metadata?
```
Why this is weaker:
- too much internal machinery exposed
- user has to parse product architecture before saying yes
### Good ownership prompt
```text
I found an existing shared contracts area: `contracts/checkout`.
Use that as the canonical owner?
```
### Weaker ownership prompt
```text
Choose a canonical shared contract owner for this cross-boundary behavior.
```
The latter is precise, but too abstract unless the user is already deep in the workflow.
---
## The Experience We Should Aim For
By default, OpenSpec should feel like:
- "Start here"
- "Describe the work"
- "I’ll handle the shape unless I need your judgment"
When the system escalates, it should feel like:
- "This got bigger than one local change"
- "I’ve prepared the coordinated setup for you"
- "Here is the next obvious step"
When collaboration expands, it should feel like:
- "This is now team-shared"
- "Commit the stable plan"
- "Everyone links their own local clones"
The user should not feel like they are constantly switching conceptual frameworks.
---
## Recommended Follow-Up Changes To The Journeys
To make `workspace-user-journeys.md` simpler and more intuitive, the next revision should:
1. Move the simplest single-repo and monorepo journey to the top.
2. Move most terminology and internal model sections later or into an appendix.
3. Reframe "coordination workspace" as an escalation artifact, not a starting abstraction.
4. Replace many uses of "scope" with "area" in user-facing examples.
5. Convert abstract ownership questions into recommendation-first prompts.
6. Compress the team-scale setup into one simple story:
- shared initiative repo
- local link command
- open agent here
7. Make the escalation flow explicitly preserve user context so it reads as continuation, not restart.
---
## Summary
The current workspace thinking is directionally right, but the UX should become much more opinionated and much less explanatory up front.
The simplest product shape is:
- one default path: local planning from where the user already is
- one escalation path: upgrade into a coordinated initiative when needed
- progressive disclosure: only show advanced concepts when OpenSpec needs a real decision
If OpenSpec does this well, the same system can feel intuitive for:
- solo users
- small teams
- large monorepos
- multi-repo teams
- cross-team initiatives
@@ -0,0 +1,27 @@
version: 1
id: context-store-and-initiatives
title: Context Store And Initiatives Direction
status: exploring
summary: >
Define the direction for a synced context store, mounted collections,
initiatives, local workspaces, and repo-local changes.
owners: []
artifacts:
readme: README.md
direction: direction.md
roadmap: roadmap.md
tasks: tasks.md
decisions: decisions.md
questions: questions.md
work_items: work-items/
linked_changes:
- change: workspace-reimplementation-roadmap
relationship: informs
- change: workspace-agent-guidance
relationship: reframes
- change: workspace-apply-repo-slice
relationship: reframes
- change: workspace-verify-and-archive
relationship: reframes
links: []
metadata: {}
@@ -0,0 +1,33 @@
# Context Store And Initiatives
This initiative is the source of product intent for context stores,
collections, initiatives, workspaces, and repo-local changes.
Start here before continuing workspace or initiative work.
## Reading Order
1. `direction.md` explains the product model and principles.
2. `roadmap.md` lists the ordered roadmap.
3. `tasks.md` shows initiative-wide progress.
4. `decisions.md` records accepted decisions.
5. `questions.md` tracks unresolved questions.
6. `work-items/<id>/` contains execution notes for one roadmap item.
## Boundary
Initiative artifacts carry product intent and roadmap decisions. OpenSpec specs
describe the current behavioral contract behind the code.
Do not rewrite specs for future intent until behavior changes with an
implementation slice.
The current product boundary is:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
@@ -0,0 +1,204 @@
# Context Store And Initiatives Decisions
## 2026-05-20: Track Roadmap Execution Inside The Initiative
Decision: Track initiative roadmap implementation inside
`openspec/initiatives/context-store-and-initiatives/` rather than creating an
OpenSpec change for each roadmap item.
Why: The initiative is the durable coordination object for this work. Repo-local
OpenSpec changes should be reserved for implementation slices owned by a repo or
team. Roadmap-item tracking belongs with the initiative until a task needs a
repo-owned implementation plan.
Implications:
- Use `tasks.md` as the initiative-wide progress dashboard.
- Use `work-items/<nn-slug>/` for detailed execution notes on one roadmap item.
- Link repo-local OpenSpec changes back to the initiative later when
implementation moves into a repo-owned slice.
## 2026-05-20: Lock Workspace-To-Initiative Product Boundary
Decision: Workspaces are local working views, not durable shared planning
objects. Durable coordination belongs to context stores and initiatives. Repo
local changes own implementation.
Implications:
- Preserve workspace setup, link, relink, list, open, update, and doctor as
beta local-view infrastructure.
- Treat workspace-planning behavior as beta or transitional compatibility.
- Defer workspace apply, verify, and archive until initiative-linked repo-local
changes exist.
## 2026-05-21: Leave Specs Alone Until Behavior Changes
Decision: Do not use the initial direction lock to rewrite OpenSpec specs.
Specs should describe the current behavioral contract behind the code. The
initiative artifacts should carry product intent, roadmap decisions, and future
direction until a later implementation change deliberately updates behavior and
its specs together.
Implications:
- Initial Item 1 cleanup should focus on initiative docs, historical roadmap
artifacts, active proposal disposition, and user-facing docs.
- Existing workspace-planning specs and schemas may continue to describe current
implemented behavior.
- Future changes to specs should happen with the behavior they govern.
## 2026-05-21: Keep Deferred Workspace Changes As Reference Placeholders
Decision: Keep the active workspace changes for agent guidance, repo-slice
apply, verify/archive, and the reimplementation roadmap as deferred reference
placeholders.
Why: These areas are still expected to matter after context stores, initiatives,
and initiative-linked repo-local changes exist. Archiving or deleting them now
would lose useful research and continuity.
Implications:
- Do not pick them up as the immediate next implementation focus.
- Treat their current proposals as historical/deferred direction.
- Revisit and reframe them after initiative-linked repo-local changes define the
durable handoff model.
## 2026-05-21: Generated Workspace Guidance Routes Work By Ownership
Decision: Generated workspace guidance should describe workspaces as local
working views and route durable work to the owning artifact: initiatives own
cross-team or cross-repo intent, repo-local OpenSpec changes own implementation
plans, and linked repos or folders own their implementation.
Why: The initiative direction supersedes the older model where a workspace-level
`changes/` tree owned the canonical shared cross-repo plan. New agent guidance
should not reinforce that old model.
Implications:
- Remove guidance that tells agents to use workspace-level `changes/` as the
planning home for coordinated work.
- Keep legacy or beta workspace-planning files readable as compatibility
context when present.
- Update generated workspace guidance before broad user-facing docs or specs.
- Leave specs untouched until the corresponding behavior intentionally changes.
## 2026-05-21: Workspace Action Context Is Local Compatibility Context
Decision: Workspace-planning action context should no longer describe
workspace-level artifacts as the source of truth. It should report
`sourceOfTruth: "workspace-local"` and describe workspace-local planning
artifacts as compatibility context for the current local view.
Why: Workspace-planning artifacts can still exist in the beta workflow, but the
initiative direction assigns durable coordination to initiatives and
implementation planning to repo-local changes.
Implications:
- Keep `actionContext.mode: "workspace-planning"` for compatibility.
- Keep `allowedEditRoots: []` until an explicit edit root is selected.
- Keep linked repos and folders as context, not implicit edit roots.
- Route durable coordination to initiatives when initiative context exists.
## 2026-05-21: Reorder Roadmap Around Agent-First Initiative Handoff
Decision: Treat initiatives as an agent-first workflow. Users should be able to
prompt an agent with intent like "using initiative X, explore Y and create a
proposal"; OpenSpec should provide small CLI primitives the agent can compose.
Why: The practical UX is not a human manually typing every coordination command.
Agents need reliable structured answers about where canonical initiative context
lives and how repo-local changes reference it. Local paths come from workspace
state, not from an initiative command.
Implications:
- Promote minimal context-store setup, registration, listing, and doctoring
before workspace initiative opening.
- Add `initiative show --json` before broader progress/status concepts.
- Connect repo-local changes with checked-in initiative metadata, not checked-in
snapshots of initiative prose.
- Do not add `initiative resolve`; workspace local-view state owns local path
mapping.
- Teach workspace opening about initiatives after show and repo-change linkage
semantics exist.
## 2026-05-26: Workspace Initiative Opening Uses Generated Runtime Files
Decision: Treat workspace initiative opening as a private local view record plus
generated runtime files. The workspace does not contain the work. It remembers
how this runtime opens the work.
Why: Initiative context is shared truth in the context store, repo-local changes
own implementation, and agent/editor affordances need to exist in the runtime
where the agent actually runs. Persisting generated files as workspace truth
would blur local view state with shared coordination and create stale or
privacy-sensitive artifacts.
Implications:
- Persist only tiny private local view choices: selected store, selected
initiative, selected local links, opener, and selected tools.
- Preserve the selected context-store selector inside the private workspace
record, so a runtime-local `--store-path` open can be reopened without writing
machine-local paths into checked-in repo metadata.
- Generate agent guidance, skills, launch prompts, and editor workspace files as
runtime support when opening or preparing a view.
- Open existing local paths only; do not clone, branch, create worktrees, use
submodules, or infer local repos in Item 10.
- Treat generated runtime files as disposable and regenerable.
- Allow context-only initiative open; linked repos are optional local view
choices.
- Keep edit boundaries advisory in Item 10 until enforcement is designed.
## 2026-05-26: Workspace Storage Is Keyed By Workspace Name
Decision: Store private workspace views under
`getGlobalDataDir()/workspaces/<workspace-name>/`. The workspace name is the
local identity. The selected context store and initiative, if any, live inside
one durable private `workspace.yaml` record.
Why: Workspaces are generic local views, not initiative-owned directories. A
user may want a custom workspace with linked repos and folders but no initiative,
or multiple personal workspaces over the same initiative. Keying storage by
store and initiative would overfit the filesystem layout to one workflow.
Implications:
- Keep initiative references optional inside `workspace.yaml`.
- Store initiative context with an explicit context-store binding rather than a
flat store id, because workspace state may need to remember a registry selector
or a runtime-local path selector.
- Generate `AGENTS.md`, opener workspace files, and tool-specific skills at the
managed workspace root.
- Keep `workspace.yaml` as the only view file for Item 10; do not add a separate
machine-readable view file.
- Do not introduce a separate generated-output directory for Item 10.
- If the user opens an initiative without a workspace name, derive a friendly
default workspace name from the initiative id when that is unambiguous.
- On workspace-name collisions or multiple workspaces pointing at the same
initiative, ask the human to choose or require an explicit workspace name in
non-interactive mode.
## 2026-05-26: Item 10 Workspace Open UX Decisions
Decision: Close the remaining Item 10 product decisions around runtime identity,
JSON output, Codex Desktop, edit boundaries, and implementation scope.
Implications:
- Use `getGlobalDataDir()` as the cross-platform runtime-local boundary. Do not
add path translation or a separate runtime id in Item 10.
- Keep `workspace open --json` as a machine-facing receipt for the same open
operation. It should return useful generated paths, selected context, opened
roots, skipped roots, opener, launch status, and warnings.
- Do not add `--prepare-only` for Item 10.
- For Codex Desktop, open the generated workspace root as the project and expose
attached initiative and repo/folder paths through generated guidance and
`workspace open --json` output.
- Emit advisory edit boundaries only; do not enforce write restrictions.
- Continue to open known existing local paths only. Do not clone, branch, create
worktrees, use submodules, or infer local repos in Item 10.
@@ -0,0 +1,447 @@
# Context Store And Initiatives Direction
This document captures the suggested direction from the workspace/initiative
discussion. The main shift is that "workspace" should not be the durable shared
planning object. The durable shared object is a synced context store, and
initiatives are one opinionated collection inside it.
## Core Model
```text
Context Store
= synced shared content container
Collection
= mounted content system inside a store
Initiatives
= first major collection for cross-team implementation context
Workspace
= local working view over context stores and repos
Change
= repo/team-owned implementation plan
```
The clean rule:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
## Locked Product Boundary
The workspace-to-initiative pivot is now the product boundary for future
coordination work:
- A workspace is a regenerable, machine-local working view. It maps context
stores, initiatives, projects, repos, and folders to paths the current user can
open.
- A context store is the durable synced container for shared files.
- An initiative is the durable coordination object for cross-team or cross-repo
implementation context.
- A repo-local change remains the implementation plan owned by the repo or team
doing the work.
This supersedes the older model where a workspace-level `changes/` tree owned
the canonical shared plan for cross-repo work. Existing workspace-planning
behavior can remain as beta or legacy infrastructure, but it should not steer
new lifecycle design.
Workspace roadmap disposition:
- Keep setup, link, relink, list, open, update, and doctor.
- Keep linked repos and folders visible for exploration before a change exists.
- Keep workspace-local agent guidance as local view setup, refreshed by
`workspace update`.
- Defer workspace apply, verify, and archive until initiatives can link to
repo-owned OpenSpec changes.
- Defer branch/worktree orchestration, multi-repo apply, strong cross-repo
validation, and dependency graph enforcement.
## Agent-First UX
The primary user experience for initiatives is expected to be agent-driven:
```text
Using initiative billing-launch, explore the API work and create a proposal.
```
The user should not need to know every command. OpenSpec should expose small,
structured CLI primitives that an agent can use to:
- find the intended initiative across registered context stores
- read canonical initiative files from the context store
- create or link a repo-local OpenSpec change
- use workspace state for local repo and folder views
- respect edit boundaries instead of treating every opened folder as editable
The CLI is therefore the agent's tool surface, not the whole user workflow.
Prefer explicit, machine-readable commands such as `initiative show --json`,
`new change --initiative ...`, and workspace local-view commands over broad
interactive flows as the first slice.
Canonical initiative context should stay in the context store. Repo-local
changes should reference the initiative rather than checking in copied snapshots
of initiative prose. If an agent needs a compact context pack, OpenSpec can
generate that as command output from the live initiative context.
## Context Store
A context store is the shared/synced folder of files. It is content-agnostic.
It should not know what an initiative is.
Example:
```text
acme-context/
initiatives/
decisions/
api-catalog/
playbooks/
```
The first backend should be Git:
```text
create/update/delete files
-> commit
-> push
-> other users pull
-> local views update
```
But the application should talk to a store abstraction, not directly to Git, so
the backend can later become a cloud database.
## Backend
A backend provides persistence and sync for a context store.
Examples:
- `git` backend: local clone, pull, commit, push, watch
- `cloud` backend: database records, subscriptions, hosted sync
- `memory` backend: tests and local prototypes
The backend should expose generic file/object operations:
```text
read
write
delete
list
sync
watch
```
It should not contain initiative-specific behavior.
## Collections
A collection is a mounted content system inside a context store. It is
plugin-like, but "collection" is the user-facing term.
Each collection owns:
- a folder namespace
- a content model
- templates
- validation/rules
- optional agent guidance
- optional UI views
Example:
```text
context-store/
initiatives/ # Initiative collection
decisions/ # Decision collection
api-catalog/ # API catalog collection
```
Core should enforce that a collection only writes inside its mount.
## Initiative Collection
The initiative collection is the first enterprise-oriented collection.
An initiative is shared, agent-consumable implementation context for a
coordinated outcome. It can span teams, repos, services, APIs, contracts, and
capabilities.
Default shape:
```text
initiatives/
launch-billing-flow/
initiative.yaml
requirements.md
design.md
contracts/
decisions.md
questions.md
tasks.md
```
This describes the runtime initiative collection shape in context stores. This
roadmap folder may still contain legacy `.initiative.yaml` progress metadata
while the initiative itself is being used to manage the migration; that legacy
tracker is not the model new context-store initiatives should copy.
The default structure should be opinionated for the enterprise design
partnership, but the collection system should allow other structures later.
## Initiative Responsibilities
Initiatives should own implementation-relevant shared context:
- product/program intent
- accepted requirements
- high-level technical coordination
- capability and ownership maps
- API/event/schema contracts
- dependency assumptions
- decisions and open questions
- workspace-readable context for repo-local implementation work
Initiatives should not try to become all of Jira or Confluence. The focused
positioning is:
```text
OpenSpec stores agreed implementation context.
Jira tracks work.
Confluence stores broad prose.
GitHub/GitLab store code.
```
## Initiative And Change Scope
An initiative can span one or many OpenSpec changes.
Those changes may live:
- in the same repo as the initiative
- in different repos
- in multiple context stores or OpenSpec roots later
The initiative stores shared coordination context. Workspace views can associate
that context with local repos and repo-owned changes without making the
initiative store machine-local checkout links.
This keeps grouping separate from storage:
```text
Initiative = shared grouping/context
Change = execution artifact
Workspace = local opened view of initiative + repos
```
## Workspace
A workspace is a local working view, not the source of truth.
It can map context stores and project identifiers to local paths, configure an
opener, and launch coding agents with the right folders visible.
A workspace can open an initiative by resolving:
- the initiative's context store
- locally selected repo-local changes
- local checkout paths for participating repos
The durable workspace record should stay tiny and private. It records this
runtime's local view choices, not generated agent files or shared initiative
content.
```text
getGlobalDataDir()/workspaces/<workspace-name>/
workspace.yaml
```
The workspace name is the local identity. The workspace record can optionally
store a selected context store and initiative, plus stable link names to local
paths and opener preferences. Initiative references are data inside the record,
not path segments.
Opening a workspace materializes opener-specific runtime files at the managed
workspace root. Those files can contain generated agent guidance, skills,
and editor workspace files. Machine-readable context is returned by JSON command
output. These are regenerated local support, not source of truth.
```text
private local view record
-> generated runtime files
-> opener-specific launch
-> initiative context + selected local repos/folders
```
Workspaces should be regenerable and runtime-specific. They should not be the
canonical home for initiative content, checked-in collaboration state, branches,
worktrees, clones, or implementation progress.
## Repo Changes
Repo-local changes remain the team-owned implementation plan.
An engineering team should be able to pull relevant initiative context into a
repo and create a linked OpenSpec change.
Example:
```text
repo/
openspec/
changes/
add-billing-api/
.openspec.yaml
proposal.md
design.md
specs/
tasks.md
```
The local change should reference the initiative in metadata, for example:
```yaml
initiative:
store: platform
id: billing-launch
```
This metadata is durable repo context and should be checked in. It should not
contain machine-local paths. Agents should read the initiative's canonical files
from the registered context store when they need the shared context.
## Relationship Between Concepts
```text
Context Store
contains Collections
Collection
defines structure/rules for a mounted folder
Initiative Collection
defines initiatives/
Initiative
coordinates one shared outcome
Workspace
opens local views of context stores and repos
Repo Change
implements one team's/repo's part of an initiative
```
End-to-end flow:
```text
Product/program/architect creates initiative
-> initiative syncs through context store
-> engineers open local workspace
-> repo team pulls relevant initiative context
-> repo team creates linked OpenSpec change
-> repo team implements locally
-> workspace view surfaces local progress alongside initiative context
```
## Local API Direction
The app should use dependency injection:
```ts
const store = createStore({
id: "acme-context",
backend: gitBackend({
remote: "git@github.com:acme/context.git",
localPath: "~/.openspec/stores/acme-context",
autoSync: true,
}),
collections: [
initiativeCollection({ mount: "initiatives" }),
],
});
```
Usage:
```ts
const initiatives = store.collection("initiatives");
await initiatives.create({ id: "launch-billing-flow" });
await initiatives.update("launch-billing-flow", patch);
await store.sync();
```
Important separation:
```text
Git backend knows Git.
Store knows sync/lifecycle/events.
Collection knows content structure.
Initiative collection knows initiatives.
```
## UI Direction
The UI should be content-agnostic at the core:
- browse folders/files
- edit Markdown/YAML
- preview content
- search
- show diffs/history
- sync status
Collections can add richer views:
- initiative status view
- contract table
- owner/dependency graph
- linked repo-change view
The UI should work no matter which collections are mounted.
## Open Questions
- What is the first concrete context store command surface?
- Should stores be called `context`, `store`, or something more product-facing?
- Where should enterprise context stores live by default: customer GitHub,
OpenSpec-managed Git, or later hosted cloud?
- How do non-technical users edit Git-backed content without feeling Git?
- What is the minimum viable auto-sync behavior before conflict handling gets
painful?
- How does an initiative contract graduate into a canonical owner repo contract?
- How should linked repo changes report status back into an initiative without
becoming Jira?
- How should monorepos map capabilities, folders, and repo-local changes?
- What should the first repo-change linking command be called?
- Which initiative progress/status signals are useful after linked changes
exist?
## Suggested Next Direction
After the initial store, collection, and initiative create/list foundations,
build the next slices in this order:
1. Reconcile the Initiative MVP around create/list, validation, templates, and
explicit deferral of read/update/delete policy.
2. Add minimal context-store UX for setup, registration, listing, and doctoring.
3. Add agent-first initiative discovery with `initiative show --json` and
registered-store lookup.
4. Add repo-local change metadata and an agent-friendly create/link flow for
`--initiative`.
5. Reject standalone `initiative resolve`; local path mapping belongs to
workspaces, not initiative commands.
6. Let workspaces open initiative-aware local views once show/link semantics
exist.
7. Add local-to-initiative escalation UX.
8. Harden team-shared coordination, sync, conflict guidance, and progress
status after real usage shapes those needs.
@@ -0,0 +1,23 @@
# Context Store And Initiatives Questions
## Open
- Should the user-facing command vocabulary say `context`, `store`, or
something more product-facing?
- What migration or compatibility path should existing workspace-planning
changes get once initiatives exist?
- How should linked repo changes report progress back into an initiative without
becoming a Jira clone?
- How should monorepos map capabilities, folders, and repo-local changes?
- Should OpenSpec support configurable change homes across context stores and
local OpenSpec repos, and what ownership rules keep that model safe?
## Resolved
- Workspaces should not be the durable shared planning object.
- Initiative roadmap implementation should be tracked inside the initiative
until repo-owned implementation changes are needed.
- The first concrete context store command surface is `context-store setup`,
`context-store register`, `context-store list`/`ls`, and
`context-store doctor`. Sync, push/pull, remotes, and conflict handling are
future work.
@@ -0,0 +1,759 @@
# Context Store And Initiatives Roadmap
This roadmap turns the direction in `direction.md` into shippable chunks.
The product decision underneath every step is:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
## Current Beta Priority
The manual beta pass should pull first-run friction forward. Work in this order
before investing in deeper schema or lifecycle machinery:
1. Finish the manual beta reality pass enough to keep the next slices grounded.
2. Item 12, context-store first-run and cleanup UX: interactive no-argument setup,
target-path safety, and a supported unregister/remove path.
3. Item 13, agent handoff output and delivery polish: "Next for your agent" blocks,
direct JSON paths, and baseline OpenSpec guidance even when workflow
entrypoints are commands-oriented.
4. Item 14, workspaces beta guide split: make user docs match the interactive
setup path and keep exact flags in the agent playbook.
5. Item 15, context store project roots and schema-led initiatives: sparse initiative
creation and store-local schemas.
Escalation UX, team-sharing hardening, and initiative-hosted target-bound
changes remain important, but they should wait until the first-run path feels
boring in the good way.
Before workspaces become public/stable, run Item 19 as a late beta cleanup pass
so beta compatibility code is reviewed intentionally instead of treated as a
permanent contract.
## 1. Lock The Direction
Goal: make the workspace-to-initiative pivot explicit so future workspace work
does not keep implementing the older "workspace owns the plan" model.
Ship:
- Record that workspaces are local working views, not durable shared planning
objects.
- Record that initiatives are the durable coordination object for cross-team or
cross-repo work.
- Mark the current workspace apply, verify, and archive direction as deferred or
superseded until initiative-linked repo changes exist.
- Keep the already-built workspace setup, link, open, update, and doctor
behavior as useful beta infrastructure.
Done when:
- Fresh agents can tell which workspace ideas still apply and which ones should
not steer implementation.
Locked disposition:
- Keep workspace setup, link, relink, list, open, update, and doctor as beta
local-view infrastructure.
- Keep "workspace visibility is not change commitment" as a safety rule for
linked repos and folders.
- Supersede "workspace is the durable planning home" with "initiatives are the
durable coordination object."
- Supersede workspace-level planning artifacts as the canonical shared
cross-repo plan.
- Defer workspace apply, verify, and archive as first-class lifecycle commands
until initiative-linked repo-local changes exist.
- Defer branch/worktree orchestration, strong cross-repo validation, dependency
graph enforcement, and shared contract governance.
Fresh-agent rule:
- Start from `openspec/initiatives/context-store-and-initiatives/direction.md`
for product authority.
- Treat `openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md` and
`openspec/changes/workspace-reimplementation-roadmap/` as historical reference
material for preserved local-view behavior and POC lessons.
- Do not pick up `workspace-apply-repo-slice` or
`workspace-verify-and-archive` as the next implementation slice unless a later
initiative-linked repo-change design explicitly reactivates them.
## 2. Stabilize Workspace As Local View
Goal: keep workspaces useful without making them the source of truth.
Ship:
- Workspace guidance that routes durable coordination to initiatives,
implementation planning to repo-local changes, and linked repos or folders to
local context until an edit root is selected.
- Workspace-open behavior that launches the local planning view with linked
folders visible.
- Workspace doctor/status output that explains local path mappings, unresolved
links, installed agent skills, and repair steps.
- Clear docs that `workspace update` refreshes local agent guidance and does not
modify linked repos.
Done when:
- A user can set up a workspace, link repos, open an agent, and understand that
the workspace is a local view over context, not the canonical shared plan.
## 3. Add Context Store Foundation
Goal: create the generic local context-store foundation that can later hold
initiatives and other shared context collections. Sync/watch behavior remains a
future hardening slice.
Ship:
- A context store abstraction with generic local operations: read, write,
delete, and list.
- A first Git-shaped backend model that can point at a local store root.
- A test/memory backend for fast tests and prototypes.
- A store configuration model that does not contain initiative-specific logic.
Done when:
- OpenSpec can create and manipulate files inside a local context store without
the core store layer knowing what those files mean. Pull, push, watch,
remote creation, and conflict handling are tracked as future sync work.
## 4. Add Collection Foundation
Goal: let product-specific content systems live inside a context store without
hardcoding every future concept into the store layer.
Ship:
- A collection interface with a mounted folder namespace.
- Rules that keep a collection's writes inside its mount.
- Basic collection validation and template hooks.
- A way for collections to expose optional agent guidance or UI metadata later.
Done when:
- The context store can host a mounted `initiatives/` collection while staying
generic enough for future collections like decisions, API catalogs, or
playbooks.
## 5. Ship Initiative MVP
Goal: give coordinated work a durable, shared, agent-consumable home.
Ship:
- Initiative creation and listing.
- A default initiative file shape:
```text
initiatives/<id>/
initiative.yaml
requirements.md
design.md
decisions.md
questions.md
tasks.md
```
- Templates for product intent, accepted requirements, design decisions, open
questions, and coordination tasks.
- Validation for required initiative metadata.
- Explicit deferral of full read/show, update, and delete policy until the
agent-first discovery and lifecycle needs are clearer.
Done when:
- A user or agent can create and list initiatives as shared planning objects
before any repo has committed to implementation details.
## 6. Add Minimal Context Store UX
Goal: make shared initiative storage usable before repo handoff or workspace
opening depends on it.
Ship:
- `context-store setup <id>` for creating a local Git-backed store folder with
portable store metadata and local registration.
- `context-store register <path>` for registering an existing clone or folder,
defaulting the store id from the repo or folder name.
- `context-store list` and `context-store doctor` for local visibility and
non-mutating diagnostics.
- `initiative list` defaulting to all registered stores, with `--store` as a
filter and `--store-path` as an escape hatch.
- Minimal human output and JSON output suitable for agents.
Done when:
- A single developer or teammate can create or register a shared context store,
list initiatives across registered stores, and diagnose missing or broken
local store setup without learning the internal registry layout.
## 7. Add Agent-First Initiative Discovery
Goal: let an agent resolve the initiative the user named and read canonical
initiative context from the source of truth.
Ship:
- `initiative show <id>` that searches registered stores by default.
- Ambiguity handling when the same initiative id exists in multiple stores.
- JSON output with canonical initiative metadata, store identity, initiative
root path, and metadata path.
- Human output focused on identity and available files, not work progress.
Done when:
- An agent can answer, "Which initiative did the user mean, where is the
canonical context, and where is the initiative metadata?"
## 8. Connect Repo-Local Changes To Initiatives
Goal: split shared coordination from repo-owned implementation plans cleanly.
Discussion points to confirm before implementation:
- Should the create/link flow explicitly report where the change lives, which
initiative it references, and the next suggested command?
- Should `--initiative <id>` search registered stores by default, or should it
require `--store` when more than one store is registered?
- What should the command do when the initiative exists but the current repo has
no obvious ownership match?
Ship:
- Repo-local change metadata that can reference an initiative by store id and
initiative id.
- An agent-friendly create or link flow such as
`new change <id> --initiative <store>/<initiative>`.
- Guidance that repo-local changes remain responsible for implementation,
validation, and archive.
- No checked-in `initiative.md` snapshot by default; agents read canonical
initiative files live from the context store.
Done when:
- One initiative can coordinate several repo-local changes without copying the
shared plan into every repo, storing machine-local links in the initiative, or
making the initiative own implementation artifacts.
## 9. Reject Initiative Resolve
Decision: do not add `openspec initiative resolve`, now or later.
Rationale:
- `initiative show` already resolves canonical shared initiative context.
- A workspace is the local view over repos, folders, context stores, and
initiatives.
- Repo-local changes already carry durable initiative links in checked-in
`.openspec.yaml` metadata.
- Repo-local status already reports work progress.
- A standalone resolve command would either duplicate workspace local-view state
or produce weak output when no workspace is present.
Do not ship:
- `openspec initiative resolve <id>`
- all-workspace or all-repo scans for initiative availability
- explicit path scanning as an initiative command
- Git remote matching for initiative participation
- repo ownership inference
- cloning, branch creation, or worktree creation as part of initiative
resolution
- initiative backlinks
- local availability or progress dashboards under the initiative command
Done when:
- Future agents can see that "initiative resolve" is intentionally rejected and
should not be revived under another command name.
## Proposed Discussion Point: Add Initiative Next / Agent Handoff UX
Status: candidate work item, not locked into the numbered roadmap yet.
Question to confirm:
- Should this become a roadmap item before "Let Workspaces Open Initiatives"?
Goal: give agents and users a small "what now?" command after initiative
discovery from the current repo or workspace, without turning it into a
dashboard or progress/status surface.
Possible shape:
```bash
openspec initiative next billing-launch --json
```
Possible JSON answer:
```json
{
"initiative": "billing-launch",
"next_action": "create_repo_change",
"reason": "initiative found, no linked local change exists for this repo",
"suggested_command": "openspec new change add-billing-api --initiative billing-launch"
}
```
Discussion points to confirm before implementation:
- Is `initiative next` the right command name, or should this guidance belong
inside workspace initiative opening or repo-local status?
- Should it return exactly one suggested next action, or a ranked set of options?
- Should it ever inspect work progress, or stay limited to handoff/readiness?
- How should it behave when no stores are registered, the initiative is
ambiguous, or the local repo is unrelated?
Done when, if accepted:
- An agent can answer "what should I do next for this initiative from here?"
without guessing across `show`, workspace state, and repo-local
change metadata.
## 10. Let Workspaces Open Initiatives
Goal: connect durable initiative context to this runtime's local working view
after initiative show and repo-change linkage exist.
Locked direction:
- A workspace does not contain the work. It remembers how this runtime opens the
work.
- Persist only tiny private local view choices.
- Generate opener-specific runtime files on open.
- Attach initiative context and selected existing local repos or folders.
- Do not clone, branch, create worktrees, use submodules, or infer local repos in
this slice.
- Context-only open is valid.
Product decision status:
- No remaining Item 10 product decisions are open. Implementation may still
uncover mechanical details, but the intended UX shape is locked.
Command UX decision:
- Use `openspec workspace open --initiative <initiative>`.
- Support `<store>/<initiative>` and `<initiative> --store <store>`.
- Support `openspec workspace open <workspace-name> --initiative <initiative>`
when the user wants to choose the local workspace identity explicitly.
- If only `<initiative>` is provided, proceed when exactly one registered
context store has that initiative id.
- On ambiguity, list exact matches and require an explicit store selector.
- On no exact match, show likely matches when available and suggest `openspec
initiative list`; do not silently open a fuzzy match.
- If the user omits a workspace name, derive a friendly default from the
initiative id when that is unambiguous; otherwise require the user to pick an
explicit workspace name.
Open target decision:
- Open the initiative directory by default, not the whole context store.
- Generated guidance and JSON output should still report the context store root
and that broader context is available.
- A later explicit option may open the whole context store, but broad store
scope is not the Item 10 default.
Local view record decision:
- Use one private local view record for initiative-aware local views.
- Store initiative-view state in the root `workspace.yaml` file.
- The record stores selected context-store binding, initiative, local links,
opener, and selected tools. The binding may preserve a registry selector or a
runtime-local path selector.
- The context binding is optional, so a workspace can also be a custom local view
with linked folders and no initiative.
Workspace storage decision:
- Store each private workspace view under
`getGlobalDataDir()/workspaces/<workspace-name>/`.
- The workspace name is the local identity. Selected store and initiative, if
any, are data inside the private record rather than path segments.
- Use one durable `workspace.yaml` at the workspace root.
- Generate `AGENTS.md`, opener workspace files, and tool-specific skills at the
workspace root.
- Do not introduce a separate generated-output directory for Item 10.
Runtime identity decision:
- Use `getGlobalDataDir()` as the cross-platform runtime-local boundary.
- Local paths are valid only in the runtime that wrote the private
`workspace.yaml`.
- Do not add path translation or a separate `<runtime-id>` path segment in Item
10.
Prepare/JSON decision:
- Keep `workspace open --json` as a machine-facing receipt for the same open
operation.
- Do not add `--prepare-only` for Item 10.
- JSON should return useful generated paths, selected context, opened roots,
skipped roots, opener, launch status, and warnings rather than a bare success
response.
Codex Desktop decision:
- Open the generated workspace root as the Codex Desktop project.
- Expose attached initiative and linked repo/folder paths through generated
guidance and `workspace open --json` output.
- Defer Desktop multi-root automation until there is a clearer Desktop contract.
Edit-boundary decision:
- Emit advisory boundaries only.
- Label initiative/context-store files as shared coordination context and linked
repos/folders as local implementation context when selected.
- Do not enforce write restrictions in Item 10.
Ship:
- Private local view state that can remember the selected context store,
selected initiative, selected local links, opener, and selected tools for this
runtime.
- `workspace open` support for generating opener-specific runtime files and
opening initiative context plus locally resolved linked repos/folders.
- Agent guidance and machine-readable `workspace open --json` output that
explain the current initiative, opened roots, skipped roots, local paths, and
advisory edit boundaries.
- Workspace-name reuse behavior that avoids silently repointing an existing
workspace to a different initiative.
- Open-time warnings that skip missing linked repos/folders while failing when
the selected initiative or context store cannot be resolved.
- Continued support for custom non-initiative workspaces as first-class local
views.
- Doctor guidance for missing context stores, missing linked repos/folders, and
stale local view records.
Done when:
- A teammate can open the same initiative in their runtime while using their own
local paths and selected repo subset.
- Generated runtime files are clearly derived and can be regenerated without
losing the user's local view choices.
## 11. Manual Beta Reality Pass
Status: proposed immediate beta-learning item.
Goal: manually run what exists and use the friction to update initiative notes
before designing more surface area.
Ship:
- A fresh-user walkthrough of context-store setup, initiative creation,
workspace opening, repo linking, doctor output, and repo-local linked change
creation.
- Notes on what felt clear, what felt odd, where prompts were missing, and where
docs pushed too many flags onto the user.
- A short disposition that separates docs-only fixes from follow-on
implementation slices.
Done when:
- The initiative contains concrete notes from trying the current beta flow by
hand.
- The next implementation or docs slice is grounded in observed friction rather
than guessed workflow shape.
## 12. Context Store First-Run And Cleanup UX
Goal: make context-store setup and cleanup feel like a normal local workflow,
without adding sync, remote, or governance automation.
Work item:
`work-items/12-context-store-first-run-and-cleanup-ux/`
Ship:
- Interactive no-argument `context-store setup` for terminal users.
- Deterministic non-interactive and JSON behavior when required setup choices
are missing.
- Target-path safety output for managed defaults, explicit paths, existing Git
repos, and non-empty directories.
- A supported local cleanup path for unregistering or removing a context store
without hand-editing the registry.
- Setup output that explains local registry state and Git state, including
uncommitted shared-store files after `--init-git`.
Done when:
- A fresh user can set up or clean up a local context store without knowing
hidden registry paths, environment variables, or manual file edits.
## 13. Agent Handoff Output And Delivery Polish
Goal: make existing command output and delivery choices enough for a fresh
agent to continue safely, before adding any broader `initiative next` command.
Work item:
`work-items/13-agent-handoff-output-and-delivery-polish/`
Ship:
- "Next for your agent" handoff guidance in the command outputs where first-run
flow otherwise depends on pasted beta knowledge.
- JSON output with direct created artifact paths where agents need to write
files, while preserving existing relative fields for compatibility.
- Clear delivery wording that separates baseline OpenSpec guidance from
workflow entrypoints such as skills or slash commands.
- Warnings when a selected tool cannot receive workflow slash commands.
Done when:
- A coding agent can continue from setup or initiative creation output without
guessing command names, reconstructing writable paths, or losing baseline
OpenSpec guidance because the user chose commands-oriented delivery.
## 14. Workspaces Beta Guide Split
Status: proposed immediate beta-learning item.
Goal: make the beta docs reflect the intended division of labor:
```text
Users make local choices.
Agents run OpenSpec work commands.
```
Ship:
- A user-facing guide that prefers interactive terminal setup for local choices
such as context-store location, opener, and local repo paths.
- An agent-facing CLI playbook that keeps explicit commands, JSON output,
current-directory rules, and caveats.
- A clear rule for which flags are normal user-facing escape hatches and which
are mostly agent-facing precision.
Done when:
- A new user can get to a working beta setup without reading a flag-heavy CLI
tutorial.
- A coding agent can still find the exact commands needed to create initiatives,
link repo-local changes, and inspect state safely.
## 15. Context Store Project Roots And Schema-Led Initiatives
Goal: let context stores behave like OpenSpec roots for shared planning config
and schemas, while keeping implementation changes repo-owned by default.
Work item:
`work-items/15-context-store-project-roots-and-schema-led-initiatives/`
Product decision to confirm:
- A context store can have `openspec/config.yaml` and `openspec/schemas/` like a
repo after `openspec init`.
- That project-like shape is for shared context configuration and initiative
schemas. It must not silently make the context store an implementation repo.
- `initiative create` should create a sparse shell and let reviewed initiative
artifacts grow through schema-led status/instructions.
Ship:
- Context-store setup that creates or supports store-local OpenSpec config.
- A default initiative schema for high-level requirements and design artifacts.
- Sparse initiative creation: `initiative.yaml` plus a short `brief.md`, with no
`TBD` placeholders and no default `tasks.md`.
- Initiative artifact status and instructions output rooted in the initiative
directory.
- Guardrails so `openspec new change` does not accidentally create executable
repo-local changes inside a context store just because the store has an
`openspec/` directory.
- Compatibility for existing six-file MVP initiatives.
Done when:
- A context store can resolve store-local initiative schemas.
- Agents can iteratively create initiative requirements and design artifacts
from CLI instructions.
- Existing MVP initiatives continue to list and show.
- Docs stop presenting initiative creation as "fill every markdown file now."
## 16. Add Escalation UX
Goal: let users start locally and upgrade only when coordination is actually
needed.
Work item:
`work-items/16-add-escalation-ux/`
Ship:
- Explore/propose guidance that starts in the current repo by default.
- A recommendation path when work spans multiple owned areas:
```text
This appears to span multiple owned areas.
OpenSpec can upgrade it into a coordinated initiative and carry the current
planning context forward.
```
- Carry-forward behavior for the current change name, product goal, notes,
inferred areas, and relevant questions.
- Clear prompts that ask about concrete affected areas rather than abstract
storage models.
Done when:
- Coordinated planning feels like a continuation of local planning, not a
workflow restart.
## 17. Harden Team-Shared Coordination
Goal: make initiatives practical for teams without turning setup into an admin
ceremony.
Work item:
`work-items/17-harden-team-shared-coordination/`
Ship:
- A recommended Git-backed shared context store pattern.
- Lightweight teammate onboarding:
```text
Clone the context store.
Run openspec workspace doctor.
Open the initiative with your agent.
```
- Repair flows for local path mappings.
- Sync status and conflict guidance.
- Clear separation between committed initiative state and machine-local
workspace state.
Done when:
- Several teammates can share the same initiative while each keeps their own
local checkout layout.
## 18. Explore Initiative-Hosted Target-Bound Change Artifacts
Goal: decide whether shared initiative artifacts can graduate into executable
OpenSpec changes only after they are bound to a target repo or spec root,
without blurring initiative coordination, repo ownership, and workspace
local-view boundaries.
Work item:
`work-items/18-explore-initiative-hosted-target-bound-change-artifacts/`
Discussion points to confirm before exploration:
- Should "change home" stay internal resolver language, with user-facing
phrasing like "where should this plan live?" and "editable target"?
- What is the difference between initiative work items, briefs, target-bound
changes, and repo-local changes?
- What portable target metadata is required before an initiative-hosted artifact
can be considered implementation-ready?
- Should shared target-bound changes require explicit opt-in, or can
initiative/store policy select them?
- What user/team scenario would justify an initiative-hosted target-bound change
instead of a repo-local linked change?
Ship:
- Audit commands, templates, validation, archive, apply, completion, and docs
for repo-local `openspec/changes/` assumptions.
- Define the concepts of artifact home, implementation target, allowed edit
roots, and action context.
- Decide how initiative-hosted target-bound changes bind to repo specs,
implementation roots, branches, validation, archive, and sync/conflict
behavior.
- Define agent-readable JSON output for work target, artifact home,
implementation target, initiative link, edit boundaries, unsupported
lifecycle commands, and next commands.
- Record compatibility behavior for existing repo-local and workspace-local
changes.
- Recommend whether this should become an implementation slice, remain deferred,
start as initiative work items only, or be limited to specific schemas or
workflows first.
Done when:
- The initiative has a concrete recommendation, opt-in/config examples, affected
command list, and go/no-go criteria for implementation.
## 19. Review Workspace Beta Compatibility Before Public Release
Goal: decide which workspace beta compatibility behavior should survive into the
public workspace contract, and remove or migrate the rest while workspaces are
still unpublished.
Work item:
`work-items/19-review-workspace-beta-compatibility-before-public-release/`
Why this is late:
- Workspaces are still beta and not public/stable yet.
- We do not need to preserve every intermediate beta file shape forever.
- Early cleanup risks churn while first-run UX and initiative behavior are still
changing.
- The right compatibility contract is easier to define after manual beta usage
shows which local workspace artifacts real users have actually created.
Ship:
- Inventory workspace compatibility code, including legacy split state readers,
registry fallbacks, `codex` to `codex-cli` aliases, generated `.gitignore`
cleanup, and empty compatibility shims.
- Classify each path as public contract, beta migration, test-only shim, or
removable dead weight.
- Remove beta-only shims that only support unpublished intermediate workspace
shapes.
- Define any migration behavior worth keeping for people who tried the beta.
- Update docs, tests, generated guidance, and release notes so the public
workspace compatibility promise is explicit.
Done when:
- The workspace compatibility surface is intentionally small.
- Public docs do not imply support for beta-only workspace internals.
- Any remaining migration code has a clear owner, reason, and removal policy.
## Later, Not First
These are important, but should wait until the initiative model has real usage:
- Workspace apply, verify, and archive as first-class lifecycle commands.
- Branch or worktree orchestration.
- Strong cross-repo validation.
- Dependency graph enforcement.
- Shared contract ownership workflows.
- Sponsor/driver governance flows.
- Initiative progress/status dashboards.
- Cloud-hosted context stores.
## Suggested Shipping Sequence
1. Lock the direction and defer old workspace lifecycle slices.
2. Stabilize workspace as local view and agent launcher.
3. Add context store foundation.
4. Add collection foundation.
5. Ship initiative MVP.
6. Add minimal context-store UX.
7. Add agent-first initiative discovery.
8. Link repo-local changes to initiatives.
9. Keep initiative resolve rejected; use workspace local-view mapping instead.
10. Let workspaces open initiatives.
11. Manual beta reality pass.
12. Context store first-run and cleanup UX.
13. Agent handoff output and delivery polish.
14. Workspaces beta guide split.
15. Context store project roots and schema-led initiatives.
16. Add local-to-initiative escalation UX.
17. Harden team-shared coordination.
18. Explore initiative-hosted target-bound change artifacts.
19. Review workspace beta compatibility before public release.
Pending discussion: optionally add initiative next / agent handoff UX before or
alongside the handoff polish work.
@@ -0,0 +1,308 @@
# Context Store And Initiatives Tasks
This tracks roadmap execution for the initiative. Roadmap items live in
`roadmap.md`; detailed working notes live under `work-items/`.
## Current Beta Priority
After the manual beta pass, prioritize the things a fresh user hits while
getting started before deeper model work:
1. Finish Item 11 observations enough to keep implementation grounded.
2. Item 12: no-argument context-store setup, path safety, and
cleanup.
3. Item 13: "Next for your agent" output, direct JSON paths,
and baseline guidance/delivery polish.
4. Item 14: update the beta guide so it matches the improved first-run flow.
5. Item 15: context-store project roots and sparse schema-led
initiatives.
6. Items 16-18: leave escalation, team hardening, and initiative-hosted
target-bound changes until after the onboarding path feels sane.
7. Item 19: review beta workspace compatibility near the end, before workspace
behavior becomes public/stable.
## 1. Lock The Direction
Work item: `work-items/01-lock-the-direction/`
- [x] Record the workspace-to-initiative product boundary in initiative docs.
- [x] Mark the old workspace reimplementation roadmap as historical reference.
- [x] Defer workspace apply, verify, and archive until initiative-linked repo
changes exist.
- [x] Complete a non-spec direction pass so roadmap, work items, docs, and
active change artifacts point to the initiative as product intent.
- [x] Decide whether user-facing workspace docs need any change now; default to
no unless they misrepresent current behavior.
- [x] Decide how to handle active no-task workspace changes after the
disposition pass.
- [x] Record final evidence and remaining risks for Item 1.
## 2. Stabilize Workspace As Local View
Work item: `work-items/02-stabilize-workspace-as-local-view/`
- [x] Re-anchor generated workspace guidance in the initiative direction.
- [x] Decide that generated guidance should stop recommending workspace-level
`changes/` as the planning home for coordinated work.
- [x] Decide that `workspace update` should refresh generated workspace
guidance for existing workspaces.
- [x] Decide that workspace-planning action context should treat beta workspace
artifacts as local compatibility context.
- [x] Decide to defer doctor installed-skill summaries and only update stale
`workspace update` wording for now.
- [x] Define exact local-view behavior to preserve.
- [x] Review current workspace setup, link, relink, list, open, update, and
doctor behavior against that definition.
- [x] Identify any product wording or guidance gaps left after Item 1.
## 3. Add Context Store Foundation
Work item: `work-items/03-add-context-store-foundation/`
- [x] Define the initial store/backend data model.
- [x] Decide that the first slice is core API only, with no CLI surface yet.
- [x] Decide that the first backend is Git/local checkout config only.
- [x] Decide where context store roots, local registry YAML, and portable store
metadata YAML live.
- [x] Implement context-store foundation helpers and tests.
## 4. Add Collection Foundation
Work item: `work-items/04-add-collection-foundation/`
- [x] Define collection mount rules.
- [x] Decide validation/template hooks stay inert extension fields for this
slice.
- [x] Prove `initiatives/` can mount without store-specific logic.
## 5. Ship Initiative MVP
Work item: `work-items/05-ship-initiative-mvp/`
- [x] Define initiative file shape and validation.
- [x] Add templates for requirements, design, decisions, questions, and tasks.
- [x] Implement create/list mounted collection operations and CLI adapter.
- [x] Decide full read/show, update, and delete policy should move to later
agent-first discovery and lifecycle work.
## 6. Add Minimal Context Store UX
Work item: `work-items/06-add-minimal-context-store-ux/`
- [x] Create Item 6 work-item tracking notes.
- [x] Define high-level `context-store setup`, `register`, `list`, and `doctor`
UX direction.
- [x] Decide exact checked-in store metadata and machine-local registry
behavior.
- [x] Decide setup/register/list/doctor human behavior and responsibility split.
- [x] Decide `initiative list` partial-success behavior across registered
stores.
- [x] Decide final Item 6 edge cases: id inference, non-empty setup folders,
registry conflicts, empty states, JSON exit behavior, and static completions.
- [x] Update `initiative list` to default across registered stores, with
`--store` as a filter and `--store-path` as an escape hatch.
- [x] Add focused tests and verification for context-store CLI behavior.
## 7. Add Agent-First Initiative Discovery
- [x] Define `initiative show <id>` human and JSON output.
- [x] Search registered stores by default and handle ambiguous initiative ids.
- [x] Return canonical initiative metadata, store identity, root path, and
metadata path for agent reads.
- [x] Keep work-progress status out of this command.
## 8. Connect Repo-Local Changes To Initiatives
Work item: `work-items/08-connect-repo-local-changes-to-initiatives/`
- [x] Decide that the initiative link lives in repo-local `.openspec.yaml`.
- [x] Add repo-local initiative metadata.
- [x] Add an agent-friendly create or link flow for repo-local changes.
- [x] Decide command naming for `--initiative` linking on new change creation.
- [x] Confirm whether create/link output should report where the change lives,
which initiative it references, and the next suggested command.
- [x] Confirm whether `--initiative <id>` searches registered stores by default
or requires explicit store selection in multi-store setups.
- [x] Keep canonical initiative context in the context store; do not add a
checked-in `initiative.md` snapshot by default.
## 9. Reject Initiative Resolve
Work item: `work-items/09-add-initiative-resolve/`
- [x] Pressure-test whether a standalone `initiative resolve` command is needed.
- [x] Decide not to add `openspec initiative resolve`, now or later.
- [x] Keep canonical initiative discovery in `initiative show`.
- [x] Keep local path mapping in workspace behavior.
- [x] Keep implementation progress in repo-local status.
- [x] Reject all-repo scans, all-workspace scans, explicit path scanning as an
initiative command, Git remote matching, cloning, worktree creation, and
initiative backlinks.
## Proposed Discussion: Initiative Next / Agent Handoff UX
Work item draft:
`work-items/proposed-initiative-next-agent-handoff-ux/`
- [ ] Decide whether to add this as a numbered roadmap item between Item 9 and
Item 10.
- [ ] Decide whether the surface is `initiative next`, workspace initiative
opening, or repo-local status guidance.
- [ ] Decide whether it suggests one next action or multiple ranked options.
- [ ] Decide that progress/status stays out of scope, unless we explicitly want
this command to grow into a broader status surface.
## 10. Let Workspaces Open Initiatives
- [x] Create Item 10 work-item tracking notes.
- [x] Lock the command UX for opening an initiative as a local workspace view.
- [x] Define the private local view record for selected context store,
initiative, local links, opener, and selected tools.
- [x] Decide the private local view record storage namespace and keying.
- [x] Decide the default open target: initiative directory versus full context
store.
- [x] Decide where generated runtime files live and how they are regenerated.
- [x] Define runtime identity rules for macOS, Codespaces, WSL, SSH, and
containers without path translation.
- [x] Decide the prepare/JSON surface for agents and desktop integrations.
- [x] Decide the Codex Desktop behavior for generated workspace roots and attached
paths.
- [x] Define advisory edit-boundary output for Item 10.
- [x] Confirm this slice opens known local paths only and does not create
clones, branches, worktrees, or submodules.
## 11. Manual Beta Reality Pass
Work item: `work-items/11-manual-beta-reality-pass/`
- [ ] Manually run the current context-store, initiative, workspace, and
repo-local change flows from a fresh user's point of view.
- [ ] Capture notes on confusing commands, missing prompts, unclear output, and
places where the docs over-explain or under-explain.
- [ ] Update initiative notes as observations come in.
- [ ] Decide which findings should become implementation slices versus docs-only
fixes.
## 12. Context Store First-Run And Cleanup UX
Work item: `work-items/12-context-store-first-run-and-cleanup-ux/`
- [x] Decide and implement interactive no-argument `context-store setup`.
- [x] Define target-path safety behavior for managed defaults, explicit paths,
Git repos, and non-empty directories.
- [x] Add local cleanup support for unregistering or removing a context store.
- [x] Make setup and cleanup output report the agreed human-facing summary and
exact JSON state without workflow `next_commands`.
- [x] Update docs and tests for first-run setup and cleanup behavior.
## 13. Agent Handoff Output And Delivery Polish
Work item: `work-items/13-agent-handoff-output-and-delivery-polish/`
- [ ] Decide which commands should print "Next for your agent" handoff guidance.
- [ ] Add direct created-path JSON fields where agents currently have to
reconstruct artifact paths.
- [ ] Clarify commands-oriented delivery so workflow slash commands are separate
from baseline OpenSpec guidance.
- [ ] Warn when a selected tool cannot receive workflow slash commands.
- [ ] Update docs, generated agent guidance, and tests for the polished handoff
and delivery output.
## 14. Workspaces Beta Guide Split
Work item: `work-items/14-workspaces-beta-guide-split/`
- [ ] Update the user-facing guide to prefer interactive terminal setup for
local choices.
- [ ] Move initiative creation, initiative editing, and repo-local change
creation into "ask your coding agent" guidance.
- [ ] Keep explicit flags, JSON output, cwd rules, and caveats in the
agent-facing CLI playbook.
- [ ] Decide which flags remain useful in user docs as escape hatches for
ambiguity.
- [ ] Record any interactive prompt gaps found while writing the guide.
## 15. Context Store Project Roots And Schema-Led Initiatives
Work item:
`work-items/15-context-store-project-roots-and-schema-led-initiatives/`
- [x] Create Item 15 work-item tracking notes.
- [ ] Update initiative direction language so context stores are OpenSpec-aware
shared project roots, not only cross-team/cross-repo coordination folders.
- [ ] Decide the minimal context-store OpenSpec structure:
`.openspec-store/store.yaml`, `openspec/config.yaml`,
`openspec/schemas/`, and collection mounts.
- [ ] Decide the store-local config shape for initiative collection defaults,
including whether to use `collections.initiatives.schema`.
- [ ] Decide how context-store setup creates, preserves, or repairs
store-local `openspec/config.yaml`.
- [ ] Define the built-in high-level initiative schema and its initial
artifacts.
- [ ] Decide whether `initiative create` creates only `initiative.yaml`, or
`initiative.yaml` plus one schema-selected seed artifact such as `brief.md`.
- [ ] Replace eager six-file initiative scaffolding with sparse iterative
creation.
- [ ] Add initiative artifact status/instructions behavior rooted at the
initiative directory.
- [ ] Reuse project-local schema resolution with the context-store root as the
project root for initiative commands.
- [ ] Decide whether schema CLI commands need `--store` or `--store-path`
selectors.
- [ ] Guard planning-home resolution so context stores with `openspec/config.yaml`
do not accidentally make the store an implementation repo.
- [ ] Preserve existing six-file beta initiatives as readable valid
initiatives.
- [ ] Update docs, generated agent guidance, and tests for the project-like
context-store model.
## 16. Add Escalation UX
Work item: `work-items/16-add-escalation-ux/`
- [ ] Define local-to-initiative recommendation triggers.
- [ ] Carry current planning context into a new initiative.
- [ ] Keep prompts grounded in affected areas.
## 17. Harden Team-Shared Coordination
Work item: `work-items/17-harden-team-shared-coordination/`
- [ ] Document recommended Git-backed store setup.
- [ ] Define teammate onboarding and repair flows.
- [ ] Add sync status and conflict guidance.
## 18. Explore Initiative-Hosted Target-Bound Change Artifacts
Work item: `work-items/18-explore-initiative-hosted-target-bound-change-artifacts/`
- [ ] Confirm "change home" stays internal language and user-facing wording is
closer to "where should this plan live?"
- [ ] Define user-facing naming for initiative work items, briefs,
target-bound changes, artifact homes, and editable targets.
- [ ] Decide whether initiative-hosted artifacts can graduate into executable
changes, and which target metadata is required first.
- [ ] Decide the configuration or opt-in surface for repo-local versus
initiative-hosted artifacts.
- [ ] Define how `openspec new change` selects and reports the artifact home,
implementation target, initiative link, and action context.
- [ ] Decide how initiative-hosted target-bound changes bind to repo specs,
implementation roots, validation, archive, and sync behavior.
- [ ] Record compatibility behavior for existing repo-local and
workspace-local changes.
- [ ] Identify follow-on implementation slices and risks.
## 19. Review Workspace Beta Compatibility Before Public Release
Work item:
`work-items/19-review-workspace-beta-compatibility-before-public-release/`
- [ ] Inventory workspace beta compatibility code and tests.
- [ ] Decide which beta-only compatibility paths should be removed before
public release.
- [ ] Decide which compatibility paths need explicit migration behavior or
release notes.
- [ ] Remove low-value shims that only support unpublished beta workspace
shapes.
- [ ] Update docs, tests, and agent guidance to match the chosen public
workspace compatibility contract.
@@ -0,0 +1,154 @@
# Work Item 01 Evidence
## 2026-05-20 Initial Direction Lock
Completed before this work item folder was created:
- Added locked disposition to `roadmap.md`.
- Added locked product boundary to `direction.md`.
- Marked `openspec/changes/workspace-reimplementation-roadmap/START_HERE.md` as historical reference.
- Marked `openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md` as historical reference.
- Marked `openspec/changes/workspace-reimplementation-roadmap/` as historical
reference.
- Marked `workspace-apply-repo-slice` and `workspace-verify-and-archive` as
deferred until initiative-linked repo-local changes exist.
Research findings:
- Current workspace setup, link, relink, list, open, update, and doctor behavior
is useful beta local-view infrastructure and should be preserved.
- Live specs describe current workspace-planning behavior. They should not be
rewritten during the initial direction lock; initiative artifacts should carry
future product intent until behavior changes.
- Existing runtime behavior should remain intact until initiatives and linked
repo-local changes can replace workspace-level planning.
Verification:
- `git diff --check` passed after the initial direction-lock edits.
- `openspec validate workspace-reimplementation-roadmap --no-interactive`,
`openspec validate workspace-apply-repo-slice --no-interactive`, and
`openspec validate workspace-verify-and-archive --no-interactive` failed
because those existing active changes have no spec deltas. That predates the
disposition wording and is tracked as an active-change cleanup question.
## 2026-05-21 Initiative Entry Point
Added `README.md` as the initiative entry point and linked it from
`.initiative.yaml`.
The README explains:
- this initiative is the source of product intent
- the reading order for direction, roadmap, tasks, decisions, questions, and
work items
- specs remain the current behavioral contract behind the code
- specs should not be rewritten for future intent until behavior changes
Updated `work-items/01-lock-the-direction/tasks.md` to mark the initiative
source-of-intent review complete.
## 2026-05-21 Historical Workspace Roadmap Review
Reviewed the historical workspace reimplementation entry points:
- `openspec/changes/workspace-reimplementation-roadmap/START_HERE.md`
- `openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md`
- `openspec/changes/workspace-reimplementation-roadmap/README.md`
- `openspec/changes/workspace-reimplementation-roadmap/proposal.md`
- `openspec/changes/workspace-reimplementation-roadmap/POC_REFERENCE_GUIDE.md`
Added a guard near the top of
`openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md` stating
that the remaining sections are historical POC follow-up direction and should
not be treated as active implementation guidance.
The roadmap README and handoff prompt already direct agents to the initiative
direction first and warn not to continue the old flat sibling queue unless a
later initiative-linked repo-change design reactivates it.
## 2026-05-21 Active Workspace Proposal Review
Reviewed active workspace proposal artifacts:
- `workspace-reimplementation-roadmap`
- `workspace-agent-guidance`
- `workspace-apply-repo-slice`
- `workspace-verify-and-archive`
Added small notes to `workspace-apply-repo-slice` and
`workspace-verify-and-archive` clarifying that the remaining proposal sections
are preserved for later reference, not discarded, and should become relevant
again after initiatives and initiative-linked repo-local changes exist.
Left `workspace-agent-guidance` untouched because it already has unrelated
worktree edits and should be handled as a separate active-change disposition
decision.
## 2026-05-21 User-Facing Docs Decision
Decision: Do not update `docs/cli.md` as part of the initial direction lock
unless it misrepresents current user-facing behavior.
Reasoning:
- The direction lock is for contributors and agents deciding what to build next.
- User-facing docs should describe current CLI behavior, not future initiative
intent.
- Initiatives do not have a CLI surface yet, so announcing the pivot in user
docs would draw attention to an internal product direction before users can act
on it.
Revisit user-facing docs when initiative or context-store commands exist, or if
current docs promise unavailable workspace apply, verify, or archive behavior.
Verification:
- `git diff --check` passed.
- No files under `openspec/specs/` or `schemas/workspace-planning/` were
modified in this pass.
## 2026-05-21 Active Change Disposition
Decision: Keep the active workspace changes as deferred reference placeholders.
Rationale:
- Workspace agent guidance, apply, verify, and archive are still expected to
matter after initiative infrastructure exists.
- The immediate focus should be context stores, initiatives, and
initiative-linked repo-local changes.
- Keeping the proposals preserves research and continuity without making them
the next implementation queue.
Follow-up:
- Revisit the deferred workspace changes after initiative-linked repo-local
changes define the durable handoff model.
## Final Item 1 State
Item 1 is complete.
What is locked:
- Initiative artifacts are the source of product intent for context stores,
collections, initiatives, workspaces, and repo-local changes.
- Specs and schemas remain the current behavioral contract and were not edited
for future intent.
- Historical workspace roadmap artifacts remain available as reference, not as
the active shipping queue.
- Deferred workspace changes remain active reference placeholders because their
domains are expected to matter after initiative infrastructure exists.
- User-facing docs were intentionally left unchanged unless they misrepresent
current behavior.
Remaining risks:
- `openspec list` still shows deferred workspace changes as active no-task
changes. This is intentional for now but may remain visually noisy.
- `workspace-agent-guidance` has unrelated worktree edits and should be handled
carefully before any future commit or archive decision.
- Future agents still need to read the initiative README first; the historical
workspace docs are safer now, but still contain useful old lifecycle details
deeper in the file.
@@ -0,0 +1,90 @@
# Work Item 01: Lock The Direction
## Goal
Make the workspace-to-initiative pivot explicit enough that future agents and
contributors do not continue implementing the older "workspace owns the plan"
model.
The locked model is:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
## Direction
This work item is a non-spec direction pass, not a runtime removal.
Specs should continue to describe the current behavioral contract behind the
code. Product intent, roadmap decisions, and future direction should live in the
initiative artifacts until a later implementation change intentionally updates
behavior and its specs together.
Keep:
- workspace setup, link, relink, list, open, update, and doctor
- linked repos and folders as local planning context
- workspace-local skills as local agent guidance
- "workspace visibility is not change commitment"
Mark as transitional:
- workspace-level `changes/` planning
- `workspace-planning` schema
- workspace-scoped status/instructions compatibility
Defer:
- workspace apply, verify, and archive as first-class lifecycle commands
- branch/worktree orchestration
- strong cross-repo validation
- dependency graph enforcement
Supersede:
- workspace as the durable shared planning home
- workspace-level planning artifacts as the canonical cross-repo plan
- workspace change planning as the long-term source of truth
## Files To Review Now
- `openspec/initiatives/context-store-and-initiatives/*.md`
- `openspec/initiatives/context-store-and-initiatives/work-items/**/*.md`
- `openspec/changes/workspace-reimplementation-roadmap/START_HERE.md`
- `openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md`
- `openspec/changes/workspace-reimplementation-roadmap/*`
- active `openspec/changes/workspace-*` proposals
- `docs/cli.md`
## Files To Leave Alone For Now
- `openspec/specs/**/*.md`
- `schemas/workspace-planning/**`
Those files should change only when we intentionally change behavior or create a
repo-owned implementation change that updates the relevant behavioral contract.
## Non-Goals
- Do not remove current workspace-planning runtime behavior.
- Do not delete the `workspace-planning` schema.
- Do not add CLI deprecation warnings until the initiative replacement exists.
- Do not implement context stores in this work item.
- Do not edit OpenSpec specs as part of the initial direction lock.
## Done When
- Initiative artifacts clearly carry the product intent and roadmap decisions.
- Historical workspace roadmap artifacts no longer read as the active shipping
queue.
- User-facing docs describe current workspaces as local views where that does
not contradict current behavior.
- Existing workspace-planning behavior is clearly treated as current behavior,
not the future product model, in initiative and roadmap artifacts.
- Workspace apply, verify, and archive are clearly deferred.
- Fresh agents can identify the initiative direction as the source of truth.
@@ -0,0 +1,44 @@
# Work Item 01 Tasks
## Tracking Setup
- [x] Create initiative-level `tasks.md`, `decisions.md`, and `questions.md`.
- [x] Create `work-items/01-lock-the-direction/`.
- [x] Record why roadmap implementation is tracked inside the initiative instead
of creating a new OpenSpec change.
## Direction Lock Already Captured
- [x] Add locked disposition to `roadmap.md`.
- [x] Add locked product boundary to `direction.md`.
- [x] Mark `openspec/changes/workspace-reimplementation-roadmap/START_HERE.md` as historical reference.
- [x] Mark `openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md` as historical reference.
- [x] Mark `workspace-reimplementation-roadmap` as historical reference.
- [x] Mark `workspace-apply-repo-slice` as deferred.
- [x] Mark `workspace-verify-and-archive` as deferred.
## Non-Spec Direction Pass
- [x] Keep OpenSpec specs unchanged until behavior changes.
- [x] Review initiative artifacts for a clear source-of-intent story.
- [x] Review historical workspace roadmap artifacts for any remaining language
that tells agents to continue the old shipping queue.
- [x] Review active workspace proposal artifacts for any remaining language that
presents workspace apply, verify, or archive as next.
- [x] Decide whether user-facing docs need changes now; default to no unless
they misrepresent current behavior.
- [x] Record a decision that specs remain current behavioral contracts, while
initiative docs carry future product intent.
## Active Change Disposition
- [x] Decide whether `workspace-agent-guidance` should be reframed, closed, or
kept as a local-view guidance item.
- [x] Decide whether no-task deferred workspace changes should stay active,
move to archive, or be represented only by initiative work items.
## Verification
- [x] Run `git diff --check`.
- [x] Confirm no OpenSpec specs were modified in this pass.
- [x] Record evidence in `evidence.md`.
@@ -0,0 +1,68 @@
# Stabilize Workspace As Local View Evidence
## Direction Evidence
`direction.md` says the durable shared object is a synced context store, with
initiatives as the first major collection. It defines workspaces as local
working views over context stores and repos, and repo changes as repo/team-owned
implementation plans.
The locked product boundary supersedes the older model where a workspace-level
`changes/` tree owned the canonical shared cross-repo plan. Existing
workspace-planning behavior can remain as beta or legacy infrastructure, but it
should not steer new lifecycle design.
## Subagent Research
Implementation research found that workspace setup, link, relink, list, open,
update, and doctor already mostly behave like local-view infrastructure:
- shared link names live in workspace state
- machine-local paths and opener/skill state live in local state
- `workspace open` launches linked folders as a local working set
- linked repos are treated as context for workspace-planning commands
- `workspace update` refreshes workspace-local skills and leaves linked repos
untouched
Guidance research found that the generated `AGENTS.md` block is the most
important mismatch because it still frames the workspace as planning across
linked repos and says to use `changes/` for workspace-level planning.
Test research found strong current coverage for setup/list/doctor, link/relink,
open, update, artifact placement, and workspace-planning guards. The targeted
workspace/artifact test slice passed, as did the skill-template parity test.
## Main Risk
If generated workspace guidance continues to recommend workspace-level
`changes/`, agents may treat the workspace as the durable shared planning
object even though the initiative direction assigns durable coordination to
initiatives and implementation planning to repo-local changes.
## Implementation Evidence
The first implementation slice updates the generated workspace `AGENTS.md`
guidance and makes `workspace update` refresh the workspace-local open surface.
It also updates workspace-planning action context so beta workspace artifacts are
reported as `workspace-local` compatibility context instead of the source of
truth.
Doctor/status review found that local path mappings, unresolved links, repair
steps, malformed local state, missing local state, repo specs paths, and skill
drift warnings are already covered. Normal installed-skill summaries are
deferred for now; the current slice only updates stale `workspace update`
wording so it matches the guidance refresh behavior.
Verification:
- `pnpm run build`
- `pnpm exec vitest run test/commands/workspace.test.ts test/commands/artifact-workflow.test.ts test/core/workspace/foundation.test.ts`
- `pnpm run lint`
- `git diff --check`
## Closeout Evidence
Live docs no longer describe workspaces as durable planning homes or as the
canonical place for cross-repo planning. Historical and deferred workspace
artifacts remain as reference material, with active deferred proposals labeled
so they do not steer the next implementation slice.
@@ -0,0 +1,80 @@
# Stabilize Workspace As Local View
## Status
Complete for the current local-view stabilization slice. Remaining workspace
planning/apply/verify/archive behavior stays deferred until initiative-linked
repo-local changes exist.
## Source Of Truth
Start from `../direction.md`.
The relevant model is:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
## Goal
Keep workspace setup, link, relink, list, open, update, and doctor useful while
making it clear that a workspace is a regenerable machine-local view, not the
durable coordination object.
## Agreed Guidance Direction
Generated workspace guidance should route agents by ownership:
- Use the workspace to open the local view of coordinated work.
- Use initiatives for durable cross-team or cross-repo intent, decisions,
requirements, and coordination context.
- Use repo-local OpenSpec changes for implementation plans owned by a repo or
team.
- Use linked repos and folders to inspect context, understand ownership, and
make edits in the place that owns the work.
- Keep workspace-local files focused on local paths, opener state, agent setup,
and other machine-specific view state.
- Use OpenSpec workspace commands instead of hand-editing
`.openspec-workspace/*.yaml`.
- If a workspace contains legacy or beta workspace-level planning files, treat
them as compatibility context unless the user explicitly asks to use that beta
flow.
## Guidance To Stop Reinforcing
Do not tell agents to use workspace-level `changes/` as the planning home for
coordinated work. That reinforces the superseded model where a workspace-level
`changes/` tree owned the canonical shared cross-repo plan.
Existing workspace-planning behavior may remain as beta or legacy
infrastructure, but it should not steer new lifecycle design.
## Likely Repo Slice
- Reword generated workspace guidance in
`src/core/workspace/open-surface.ts`.
- Update focused guidance tests.
- Make `workspace update` refresh the guidance block for existing workspaces.
- Keep specs untouched until a behavior change intentionally updates them.
## Closeout
Implemented:
- generated workspace guidance now routes work by ownership
- `workspace update` refreshes workspace-local guidance/open-surface files and
managed agent skills
- workspace-planning action context treats beta workspace artifacts as
`workspace-local` compatibility context
- live docs describe workspaces as local views instead of durable planning homes
Deferred:
- normal doctor installed-skill inventory
- workspace apply, verify, and archive
- initiative-linked repo-local change orchestration
@@ -0,0 +1,23 @@
# Stabilize Workspace As Local View Tasks
- [x] Research current workspace runtime, guidance, and test coverage.
- [x] Re-anchor guidance direction in `direction.md`.
- [x] Decide that generated guidance should route durable coordination to
initiatives and implementation planning to repo-local changes.
- [x] Decide that generated guidance should stop recommending workspace-level
`changes/` as the planning home.
- [x] Decide that `workspace update` refreshes the generated guidance block
for existing workspaces.
- [x] Update workspace-planning action context so beta workspace artifacts are
compatibility context, not the source of truth.
- [x] Decide to defer normal doctor skill summaries until users need an
installed-skill inventory.
- [x] Update `workspace update` wording to include workspace-local guidance and
agent skills.
- [x] Define the minimal doctor/status improvement for local paths, unresolved
links, and installed agent skills.
- [x] Identify the focused code/test files for the implementation slice.
- [x] Run the targeted workspace and artifact workflow test slice before
landing implementation.
- [x] Close out live docs wording that still framed workspaces as durable
planning homes.
@@ -0,0 +1,43 @@
# Add Context Store Foundation Evidence
## Research Summary
Existing OpenSpec patterns point toward a small explicit foundation:
- Global data uses XDG/platform locations from `getGlobalDataDir()`.
- Workspace registries are machine-local convenience indexes under global data.
- Workspace portable state uses versioned YAML and strict Zod validation.
- Existing read/write helpers validate state before writing and use
`FileSystemUtils.writeFile()` to create parent directories.
- Schema/backend-style code favors small explicit adapters and registries over
heavy framework abstractions.
## Decisions
- The first context-store backend is Git/local checkout config only.
- OpenSpec records where the local checkout lives; it does not decide where real
team stores are cloned by default.
- The local registry is not source of truth. It is a machine-local index.
- Store-root metadata is portable source-of-identity for the synced store.
- Initiatives and collections are later consumers, not part of the store
foundation.
- A thin facade should hide raw registry/metadata writes before initiative CLI
wiring.
## Implementation Evidence
- `src/core/context-store/registry.ts` registers Git/local context stores,
lists local registry entries, and resolves registered stores with metadata id
validation.
- `src/core/context-store/index.ts` exports the facade.
- `test/core/context-store/registry.test.ts` covers registration, registry
merge/update, metadata mismatch rejection, listing, resolution, missing or
mismatched metadata, and initiative collection mounting from a resolved root.
## Verification
- `pnpm exec vitest run test/core/context-store/foundation.test.ts`
- `pnpm exec vitest run test/core/context-store/registry.test.ts`
- `pnpm run build`
- `pnpm run lint`
- `git diff --check`
@@ -0,0 +1,85 @@
# Add Context Store Foundation
## Status
Registration/resolution facade implemented.
## Source Of Truth
Start from `../direction.md`.
The relevant model is:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
## Goal
Add the smallest core foundation for context stores without making the store
layer know about initiatives, collections, workspaces, or repo-local changes.
## Locked Direction
- Support one backend for the first slice: a Git/local checkout backend.
- Treat the actual context store root as a user-chosen local Git checkout or
synced folder.
- Do not hide real team context stores under XDG data by default.
- Store the machine-local registry under global data:
`$XDG_DATA_HOME/openspec/context-stores/registry.yaml`.
- Store portable context-store identity inside the store root:
`<store-root>/.openspec-store/store.yaml`.
- Start with backend identity/config, strict validation, path helpers, and
registry/metadata read-write helpers.
- Add a thin registration/resolution facade before initiative CLI wiring so
callers do not manipulate raw registry and metadata YAML directly.
- Do not reimplement the TypeScript or Node filesystem APIs as the public store
interface.
- Do not add initiative, collection, workspace-open, sync, pull, push, or CLI
behavior in this slice.
## Initial Shape
Machine-local registry:
```yaml
version: 1
stores:
acme-context:
backend:
type: git
local_path: /Users/me/repos/acme-context
remote: git@github.com:acme/context.git
branch: main
```
Portable metadata in the store root:
```yaml
version: 1
id: acme-context
```
## Likely Repo Slice
- Add `src/core/context-store/foundation.ts`.
- Add `src/core/context-store/registry.ts`.
- Add `src/core/context-store/index.ts`.
- Export the core context-store foundation from `src/core/index.ts`.
- Add focused tests under `test/core/context-store/`.
- Keep specs untouched until a behavior/API contract is deliberately surfaced.
## Implemented Facade Slice
- Added `registerContextStore(...)`.
- Added `listRegisteredContextStores(...)`.
- Added `resolveRegisteredContextStore(...)`.
- Registration writes portable store metadata when missing, validates existing
metadata when present, and merges/updates the machine-local registry.
- Resolution validates that the registry id matches the store-root metadata id.
- No Git clone, pull, push, sync, workspace state, collection manifest, or CLI
behavior was added.
@@ -0,0 +1,17 @@
# Add Context Store Foundation Tasks
- [x] Research existing config, registry, file-system, and schema/backend
patterns.
- [x] Decide to start with Git/local backend identity only, not a generic file
API.
- [x] Decide that real context store roots are user-chosen Git checkouts or
synced folders.
- [x] Decide that the local registry lives under global data and portable store
metadata lives inside the store root.
- [x] Add context-store foundation types, path helpers, parse/serialize, and
read/write helpers.
- [x] Add focused tests for validation, paths, registry roundtrip, metadata
roundtrip, and Git/local backend path resolution.
- [x] Run targeted verification.
- [x] Decide registration/resolution facade should precede initiative CLI.
- [x] Add context-store registration/list/resolve facade and tests.
@@ -0,0 +1,77 @@
# Add Collection Foundation Evidence
## Research Summary
Subagent and local review converged on the same direction:
- Item 4 should define the boundary between store identity and product-specific
content meaning.
- The collection layer should own mounted namespaces and logical path fences.
- The context-store layer should stay content-agnostic.
- Initiative CRUD and initiative file shape belong to Item 5.
- A runtime injected registry is enough for now; persisted manifests and dynamic
plugins are premature.
- A thin registration facade should hide metadata and local registry writes, but
Item 4 should not depend on that facade.
## Clean-Code Notes
- Use module boundaries and mounted objects to carry context.
- Prefer `validateMount`, `parseCollectionPath`, `createCollectionRegistry`,
and `mountCollections` inside the collection module.
- Avoid public helper names that stack every concept together, such as
`validateContextStoreCollectionRelativePath`.
- Keep path resolution pure and lexical until a future write-capable layer
deliberately handles symlinks, canonical parent paths, and backend behavior.
- Keep persisted YAML shape below the public setup surface. Runtime/public
handles should use camelCase fields such as `storeRoot`; persisted backend
state can continue to use `local_path`.
## Chosen Pattern
Use a two-step pattern:
```ts
const store = await registerContextStore({
id: "acme-context",
backend: gitLocalBackend({
localPath: "/Users/me/repos/acme-context",
remote: "git@github.com:acme/context.git",
branch: "main",
}),
});
const collections = createCollectionRegistry([
{ id: "initiatives", mount: "initiatives" },
]);
const mounted = mountCollections({
storeRoot: store.storeRoot,
collections,
});
```
For Item 4 itself, `mountCollections({ storeRoot, collections })` is the
canonical API. One-call setup facades, store lifecycle objects, builder DSLs,
and initiative-specific setup presets are deferred.
## Implementation Evidence
- `src/core/collections/runtime.ts` defines runtime collection
definitions, registries, mounted collection contexts, logical path parsing,
and mount/path resolution.
- `src/core/collections/index.ts` exports the collection module, and
`src/core/index.ts` re-exports it for core consumers.
- `test/core/collections/runtime.test.ts` covers mount and id validation,
logical path parsing, duplicate id/mount rejection, Windows-style roots,
`createHandle(context)`, no filesystem creation, and generic `initiatives/`
mounting.
## Verification
- `pnpm exec vitest run test/core/collections/runtime.test.ts`
- `pnpm run build`
- `pnpm exec vitest run test/core/collections/runtime.test.ts test/core/context-store/foundation.test.ts test/core/planning-home.test.ts`
- `pnpm exec vitest run test/utils/file-system.test.ts`
- `pnpm run lint`
- `git diff --check`
@@ -0,0 +1,198 @@
# Add Collection Foundation
## Status
First implementation slice implemented.
## Source Of Truth
Start from `../../direction.md`.
The relevant model is:
```text
Context stores sync truth.
Collections shape truth.
Initiatives coordinate work.
Workspaces open local views.
Changes implement repo-owned slices.
```
## Goal
Add the smallest collection foundation that lets product-specific content
systems mount inside a context store without making the context-store layer know
what those systems mean.
## Locked Direction So Far
- Treat Item 4 as a mount/path foundation, not a collection runtime.
- Keep collection composition runtime-only and dependency-injected.
- Keep context-store registration separate from runtime collection mounting.
- Use a future thin registration facade for metadata/registry setup instead of
showing raw registry or metadata state writes in public examples.
- Do not add a persisted collection manifest yet.
- Do not add CLI behavior yet.
- Do not add generic `read`, `write`, `list`, or `delete` helpers.
- Do not add initiative file shape, initiative CRUD, or initiative validation
yet.
- Prove `initiatives/` can mount through generic collection definitions, not
through initiative-specific context-store logic.
## Naming Direction
Use the module/object boundary to carry context instead of growing helper names.
Use a focused generic module such as `src/core/collections/runtime.ts` with
short names:
```ts
validateCollectionId(id);
validateMount(mount);
parseCollectionPath(input);
createCollectionRegistry(...);
mountCollections(...);
```
Prefer mounted objects for context-aware operations:
```ts
const mounted = collections.require("initiatives");
mounted.resolvePath("launch-billing-flow/initiative.yaml");
mounted.toStorePath("launch-billing-flow/initiative.yaml");
```
Avoid names like `validateContextStoreCollectionRelativePath`. They indicate
that too much context has leaked into a standalone helper name.
## Minimal API Shape
The first slice should stay close to this:
```ts
interface CollectionDefinition<THandle = unknown> {
id: string;
mount: string;
metadata?: CollectionMetadata;
hooks?: CollectionHooks;
createHandle?: (context: MountedCollectionContext) => THandle;
}
interface MountedCollectionContext {
storeRoot: string;
collectionId: string;
mount: string;
mountRoot: string;
resolvePath(relativePath?: string): string;
toStorePath(relativePath?: string): string;
}
interface MountedCollection<THandle = unknown> {
collectionId: string;
mount: string;
mountRoot: string;
context: MountedCollectionContext;
handle: THandle | undefined;
}
```
Use `id` on definitions, but `collectionId` on mounted handles and contexts so
domain object IDs such as initiative IDs do not collide with collection type IDs.
## Setup And Mounting Pattern
Use two separate layers:
1. A context-store registration facade for setup.
2. A pure runtime collection mounting API for Item 4.
Registration should hide persisted YAML details:
```ts
const store = await registerContextStore({
id: "acme-context",
backend: gitLocalBackend({
localPath: "/Users/me/repos/acme-context",
remote: "git@github.com:acme/context.git",
branch: "main",
}),
});
```
The registration facade can call lower-level helpers such as backend config
normalization, metadata writes, and local registry writes internally. Public
examples should not call raw `writeContextStoreMetadataState(...)`,
`writeContextStoreRegistryState(...)`, or expose persisted snake_case backend
state such as `local_path`.
Item 4 mounting should stay independent of registration and accept only the
authority it needs:
```ts
const collections = createCollectionRegistry([
{ id: "initiatives", mount: "initiatives" },
]);
const mounted = mountCollections({
storeRoot: store.storeRoot,
collections,
});
mounted.require("initiatives").resolvePath(
"launch-billing-flow/initiative.yaml"
);
```
Prefer `mountCollections({ storeRoot, collections })` as the canonical first
API. Passing a whole store handle can wait until there is a real need.
## Path Direction
- Mount names are single-segment kebab-case folder names such as `initiatives`,
`decisions`, or `api-catalog`.
- Collection-relative paths are logical portable paths inside a mount.
- The path resolver is lexical only. It proves that a logical path belongs under
a collection mount; it does not claim to be a filesystem security sandbox.
- Future write-capable helpers must revisit symlink and canonical parent-path
handling before touching disk.
Reject:
- empty mounts
- `.`
- `..`
- hidden/reserved mounts such as `.openspec-store`
- absolute paths
- Windows drive paths
- UNC paths
- NUL bytes
- traversal segments
- sibling-prefix escapes
## Deferred
- Store-level collection config files.
- Dynamic plugin loading.
- One-call `setupContextStore({ id, backend, collections })` APIs.
- `createStore(...).setup()` lifecycle APIs.
- Builder-style setup DSLs.
- Initiative-specific setup presets in the generic context-store layer.
- Template override search paths.
- Rich validation execution.
- Agent guidance generation.
- Workspace integration.
- Git sync, commits, pull, push, watch, or conflict behavior.
## Implemented Slice
- Added a pure runtime collection module at
`src/core/collections/runtime.ts`.
- Exported the module through `src/core/collections/index.ts` and
`src/core/index.ts`.
- Added focused tests under `test/core/collections/runtime.test.ts`.
- Proved a generic `{ id: "initiatives", mount: "initiatives" }` definition can
mount and resolve paths without initiative-specific store logic.
- Kept validation/template hooks as inert extension fields for now; rich hook
execution remains deferred.

Some files were not shown because too many files have changed in this diff Show More